Commit 14cff77d87

Jakub Konka <kubkon@jakubkonka.com>
2023-10-02 23:45:14
elf: create atom lists indexed by section index
1 parent 540ef3e
Changed files (1)
src
link
src/link/Elf.zig
@@ -18,6 +18,9 @@ objects: std.ArrayListUnmanaged(File.Index) = .{},
 /// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write.
 /// Same order as in the file.
 shdrs: std.ArrayListUnmanaged(elf.Elf64_Shdr) = .{},
+/// Given index to a section, returns a list of atoms allocated within it.
+/// Excludes incrementally allocated atoms - for those, use linked-list approach.
+atoms_by_shdr_table: std.AutoArrayHashMapUnmanaged(u16, AtomList) = .{},
 /// Given index to a section, pulls index of containing phdr if any.
 phdr_to_shdr_table: std.AutoHashMapUnmanaged(u16, u16) = .{},
 /// File offset into the shdr table.
@@ -159,6 +162,7 @@ comdat_groups: std.ArrayListUnmanaged(ComdatGroup) = .{},
 comdat_groups_owners: std.ArrayListUnmanaged(ComdatGroupOwner) = .{},
 comdat_groups_table: std.AutoHashMapUnmanaged(u32, ComdatGroupOwner.Index) = .{},
 
+const AtomList = std.ArrayListUnmanaged(Atom.Index);
 const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Symbol.Index));
 const AnonDeclTable = std.AutoHashMapUnmanaged(InternPool.Index, Symbol.Index);
 const LazySymbolTable = std.AutoArrayHashMapUnmanaged(Module.Decl.OptionalIndex, LazySymbolMetadata);
@@ -315,6 +319,12 @@ pub fn deinit(self: *Elf) void {
     self.objects.deinit(gpa);
 
     self.shdrs.deinit(gpa);
+
+    for (self.atoms_by_shdr_table.values()) |*list| {
+        list.deinit(gpa);
+    }
+    self.atoms_by_shdr_table.deinit(gpa);
+
     self.phdr_to_shdr_table.deinit(gpa);
     self.phdrs.deinit(gpa);
     self.shstrtab.deinit(gpa);
@@ -1244,6 +1254,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
     // Generate and emit non-incremental sections.
     try self.initSections();
     try self.sortSections();
+    try self.addAtomsToSections();
 
     // Dump the state for easy debugging.
     // State can be dumped via `--debug-log link_state`.
@@ -3561,7 +3572,7 @@ fn sortSections(self: *Elf) !void {
     }
 
     for (self.objects.items) |index| {
-        for (self.file(index).?.object.atoms.items) |atom_index| {
+        for (self.file(index).?.atoms()) |atom_index| {
             const atom_ptr = self.atom(atom_index) orelse continue;
             if (!atom_ptr.flags.alive) continue;
             atom_ptr.output_section_index = backlinks[atom_ptr.output_section_index];
@@ -3587,6 +3598,19 @@ fn sortSections(self: *Elf) !void {
     }
 }
 
+fn addAtomsToSections(self: *Elf) !void {
+    const gpa = self.base.allocator;
+    for (self.objects.items) |index| {
+        for (self.file(index).?.atoms()) |atom_index| {
+            const atom_ptr = self.atom(atom_index) orelse continue;
+            if (!atom_ptr.flags.alive) continue;
+            const gop = try self.atoms_by_shdr_table.getOrPut(gpa, atom_ptr.output_section_index);
+            if (!gop.found_existing) gop.value_ptr.* = .{};
+            try gop.value_ptr.append(gpa, atom_index);
+        }
+    }
+}
+
 fn updateSyntheticSectionSizes(self: *Elf) !void {
     if (self.got_section_index) |index| {
         if (self.got.dirty) {