authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-10-02 23:45:14+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-10-16 19:33:04+02:00
log14cff77d87c1580e10fce60b6e07022ea9456948
tree63b2d8d109c8a86d183e505f2ee9c972885f3cd6
parent540ef3e010ea00d9bfb3ba8c2e43ebf8fa226084

elf: create atom lists indexed by section index


1 files changed, 25 insertions(+), 1 deletions(-)

src/link/Elf.zig+25-1
...@@ -18,6 +18,9 @@ objects: std.ArrayListUnmanaged(File.Index) = .{},...@@ -18,6 +18,9 @@ objects: std.ArrayListUnmanaged(File.Index) = .{},
18/// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write.18/// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write.
19/// Same order as in the file.19/// Same order as in the file.
20shdrs: std.ArrayListUnmanaged(elf.Elf64_Shdr) = .{},20shdrs: std.ArrayListUnmanaged(elf.Elf64_Shdr) = .{},
21/// Given index to a section, returns a list of atoms allocated within it.
22/// Excludes incrementally allocated atoms - for those, use linked-list approach.
23atoms_by_shdr_table: std.AutoArrayHashMapUnmanaged(u16, AtomList) = .{},
21/// Given index to a section, pulls index of containing phdr if any.24/// Given index to a section, pulls index of containing phdr if any.
22phdr_to_shdr_table: std.AutoHashMapUnmanaged(u16, u16) = .{},25phdr_to_shdr_table: std.AutoHashMapUnmanaged(u16, u16) = .{},
23/// File offset into the shdr table.26/// File offset into the shdr table.
...@@ -159,6 +162,7 @@ comdat_groups: std.ArrayListUnmanaged(ComdatGroup) = .{},...@@ -159,6 +162,7 @@ comdat_groups: std.ArrayListUnmanaged(ComdatGroup) = .{},
159comdat_groups_owners: std.ArrayListUnmanaged(ComdatGroupOwner) = .{},162comdat_groups_owners: std.ArrayListUnmanaged(ComdatGroupOwner) = .{},
160comdat_groups_table: std.AutoHashMapUnmanaged(u32, ComdatGroupOwner.Index) = .{},163comdat_groups_table: std.AutoHashMapUnmanaged(u32, ComdatGroupOwner.Index) = .{},
161164
165const AtomList = std.ArrayListUnmanaged(Atom.Index);
162const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Symbol.Index));166const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Symbol.Index));
163const AnonDeclTable = std.AutoHashMapUnmanaged(InternPool.Index, Symbol.Index);167const AnonDeclTable = std.AutoHashMapUnmanaged(InternPool.Index, Symbol.Index);
164const LazySymbolTable = std.AutoArrayHashMapUnmanaged(Module.Decl.OptionalIndex, LazySymbolMetadata);168const LazySymbolTable = std.AutoArrayHashMapUnmanaged(Module.Decl.OptionalIndex, LazySymbolMetadata);
...@@ -315,6 +319,12 @@ pub fn deinit(self: *Elf) void {...@@ -315,6 +319,12 @@ pub fn deinit(self: *Elf) void {
315 self.objects.deinit(gpa);319 self.objects.deinit(gpa);
316320
317 self.shdrs.deinit(gpa);321 self.shdrs.deinit(gpa);
322
323 for (self.atoms_by_shdr_table.values()) |*list| {
324 list.deinit(gpa);
325 }
326 self.atoms_by_shdr_table.deinit(gpa);
327
318 self.phdr_to_shdr_table.deinit(gpa);328 self.phdr_to_shdr_table.deinit(gpa);
319 self.phdrs.deinit(gpa);329 self.phdrs.deinit(gpa);
320 self.shstrtab.deinit(gpa);330 self.shstrtab.deinit(gpa);
...@@ -1244,6 +1254,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node...@@ -1244,6 +1254,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
1244 // Generate and emit non-incremental sections.1254 // Generate and emit non-incremental sections.
1245 try self.initSections();1255 try self.initSections();
1246 try self.sortSections();1256 try self.sortSections();
1257 try self.addAtomsToSections();
12471258
1248 // Dump the state for easy debugging.1259 // Dump the state for easy debugging.
1249 // State can be dumped via `--debug-log link_state`.1260 // State can be dumped via `--debug-log link_state`.
...@@ -3561,7 +3572,7 @@ fn sortSections(self: *Elf) !void {...@@ -3561,7 +3572,7 @@ fn sortSections(self: *Elf) !void {
3561 }3572 }
35623573
3563 for (self.objects.items) |index| {3574 for (self.objects.items) |index| {
3564 for (self.file(index).?.object.atoms.items) |atom_index| {3575 for (self.file(index).?.atoms()) |atom_index| {
3565 const atom_ptr = self.atom(atom_index) orelse continue;3576 const atom_ptr = self.atom(atom_index) orelse continue;
3566 if (!atom_ptr.flags.alive) continue;3577 if (!atom_ptr.flags.alive) continue;
3567 atom_ptr.output_section_index = backlinks[atom_ptr.output_section_index];3578 atom_ptr.output_section_index = backlinks[atom_ptr.output_section_index];
...@@ -3587,6 +3598,19 @@ fn sortSections(self: *Elf) !void {...@@ -3587,6 +3598,19 @@ fn sortSections(self: *Elf) !void {
3587 }3598 }
3588}3599}
35893600
3601fn addAtomsToSections(self: *Elf) !void {
3602 const gpa = self.base.allocator;
3603 for (self.objects.items) |index| {
3604 for (self.file(index).?.atoms()) |atom_index| {
3605 const atom_ptr = self.atom(atom_index) orelse continue;
3606 if (!atom_ptr.flags.alive) continue;
3607 const gop = try self.atoms_by_shdr_table.getOrPut(gpa, atom_ptr.output_section_index);
3608 if (!gop.found_existing) gop.value_ptr.* = .{};
3609 try gop.value_ptr.append(gpa, atom_index);
3610 }
3611 }
3612}
3613
3590fn updateSyntheticSectionSizes(self: *Elf) !void {3614fn updateSyntheticSectionSizes(self: *Elf) !void {
3591 if (self.got_section_index) |index| {3615 if (self.got_section_index) |index| {
3592 if (self.got.dirty) {3616 if (self.got.dirty) {