lib/tldr/src/formats/elf/liveness/roots.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

 1 const std = @import("std");
 2 const root = @import("../../../root.zig");
 3 const elf = @import("../root.zig");
 4 const state = @import("state.zig");
 5 
 6 const model = root.model;
 7 const ObjectFile = elf.parser.ObjectFile;
 8 const SectionHeader = elf.format.SectionHeader;
 9 const State = state.State;
10 const foldedSection = elf.section_state.foldedSection;
11 const sectionDiscarded = elf.section_state.sectionDiscarded;
12 const sectionIsAllocated = elf.format.sectionIsAllocated;
13 const sectionNameOrEmpty = elf.parser.sectionNameOrEmpty;
14 
15 pub fn markReserved(
16     objects: []const ObjectFile,
17     live: *State,
18 ) model.Error!void {
19     for (objects, 0..) |object, object_index| {
20         for (object.sections, 0..) |section, section_index| {
21             if (!sectionIsReservedRoot(object, section_index, section)) continue;
22             if (sectionDiscarded(object, section_index)) continue;
23             if (foldedSection(object, section_index) != null) continue;
24             try state.markSection(
25                 live,
26                 objects,
27                 .{
28                     .object_index = object_index,
29                     .section_index = @intCast(section_index),
30                 },
31             );
32         }
33     }
34 }
35 
36 pub fn markRetained(
37     objects: []const ObjectFile,
38     live: *State,
39 ) model.Error!void {
40     for (objects, 0..) |object, object_index| {
41         for (object.sections, 0..) |section, section_index| {
42             if (!sectionIsAllocated(section)) continue;
43             if (sectionDiscarded(object, section_index)) continue;
44             if (foldedSection(object, section_index) != null) continue;
45             if ((section.flags & std.elf.SHF_GNU_RETAIN) == 0) continue;
46             try state.markSection(
47                 live,
48                 objects,
49                 .{
50                     .object_index = object_index,
51                     .section_index = @intCast(section_index),
52                 },
53             );
54         }
55     }
56 }
57 
58 fn sectionIsReservedRoot(object: ObjectFile, section_index: usize, section: SectionHeader) bool {
59     if (!sectionIsAllocated(section)) return false;
60     switch (section.section_type) {
61         std.elf.SHT_PREINIT_ARRAY,
62         std.elf.SHT_INIT_ARRAY,
63         std.elf.SHT_FINI_ARRAY,
64         => return true,
65         std.elf.SHT_NOTE => return (section.flags & std.elf.SHF_GROUP) == 0,
66         else => {},
67     }
68 
69     const name = sectionNameOrEmpty(object, section_index);
70     return std.mem.eql(u8, name, ".init") or
71         std.mem.eql(u8, name, ".fini") or
72         std.mem.eql(u8, name, ".jcr") or
73         std.mem.startsWith(u8, name, ".init_array") or
74         std.mem.startsWith(u8, name, ".ctors") or
75         std.mem.startsWith(u8, name, ".dtors");
76 }