| ... | @@ -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. |
| 20 | shdrs: std.ArrayListUnmanaged(elf.Elf64_Shdr) = .{}, | 20 | shdrs: 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. |
| | 23 | atoms_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. |
| 22 | phdr_to_shdr_table: std.AutoHashMapUnmanaged(u16, u16) = .{}, | 25 | phdr_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) = .{}, |
| 159 | comdat_groups_owners: std.ArrayListUnmanaged(ComdatGroupOwner) = .{}, | 162 | comdat_groups_owners: std.ArrayListUnmanaged(ComdatGroupOwner) = .{}, |
| 160 | comdat_groups_table: std.AutoHashMapUnmanaged(u32, ComdatGroupOwner.Index) = .{}, | 163 | comdat_groups_table: std.AutoHashMapUnmanaged(u32, ComdatGroupOwner.Index) = .{}, |
| 161 | | 164 | |
| | 165 | const AtomList = std.ArrayListUnmanaged(Atom.Index); |
| 162 | const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Symbol.Index)); | 166 | const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Symbol.Index)); |
| 163 | const AnonDeclTable = std.AutoHashMapUnmanaged(InternPool.Index, Symbol.Index); | 167 | const AnonDeclTable = std.AutoHashMapUnmanaged(InternPool.Index, Symbol.Index); |
| 164 | const LazySymbolTable = std.AutoArrayHashMapUnmanaged(Module.Decl.OptionalIndex, LazySymbolMetadata); | 168 | const 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); |
| 316 | | 320 | |
| 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(); |
| 1247 | | 1258 | |
| 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 | } |
| 3562 | | 3573 | |
| 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 | } |
| 3589 | | 3600 | |
| | 3601 | fn 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 | |
| 3590 | fn updateSyntheticSectionSizes(self: *Elf) !void { | 3614 | fn 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) { |