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 }