Commit 6faed6269f

Jakub Konka <kubkon@jakubkonka.com>
2023-10-03 00:22:11
elf: update section sizes accumulated from objects
1 parent 14cff77
Changed files (2)
src
src/link/Elf/Object.zig
@@ -179,7 +179,6 @@ fn addAtom(
     atom.name_offset = try elf_file.strtab.insert(elf_file.base.allocator, name);
     atom.file_index = self.index;
     atom.input_section_index = shndx;
-    atom.output_section_index = try self.getOutputSectionIndex(elf_file, shdr);
     atom.flags.alive = true;
     self.atoms.items[shndx] = atom_index;
 
@@ -279,10 +278,6 @@ fn initSymtab(self: *Object, elf_file: *Elf) !void {
         sym_ptr.esym_index = @as(u32, @intCast(i));
         sym_ptr.atom_index = if (sym.st_shndx == elf.SHN_ABS) 0 else self.atoms.items[sym.st_shndx];
         sym_ptr.file_index = self.index;
-        sym_ptr.output_section_index = if (sym_ptr.atom(elf_file)) |atom_ptr|
-            atom_ptr.outputShndx().?
-        else
-            elf.SHN_UNDEF;
     }
 
     for (self.symtab[first_global..]) |sym| {
@@ -453,15 +448,10 @@ pub fn resolveSymbols(self: *Object, elf_file: *Elf) void {
                 elf.SHN_ABS, elf.SHN_COMMON => 0,
                 else => self.atoms.items[esym.st_shndx],
             };
-            const output_section_index = if (elf_file.atom(atom_index)) |atom|
-                atom.outputShndx().?
-            else
-                elf.SHN_UNDEF;
             global.value = esym.st_value;
             global.atom_index = atom_index;
             global.esym_index = esym_index;
             global.file_index = self.index;
-            global.output_section_index = output_section_index;
             global.version_index = elf_file.default_sym_version;
             if (esym.st_bind() == elf.STB_WEAK) global.flags.weak = true;
         }
@@ -611,6 +601,19 @@ pub fn convertCommonSymbols(self: *Object, elf_file: *Elf) !void {
     }
 }
 
+pub fn updateSectionSizes(self: Object, elf_file: *Elf) void {
+    for (self.atoms.items) |atom_index| {
+        const atom = elf_file.atom(atom_index) orelse continue;
+        if (!atom.flags.alive) continue;
+        const shdr = &elf_file.shdrs.items[atom.output_section_index];
+        const offset = atom.alignment.forward(shdr.sh_size);
+        const padding = offset - shdr.sh_size;
+        atom.value = offset;
+        shdr.sh_size += padding + atom.size;
+        shdr.sh_addralign = @max(shdr.sh_addralign, atom.alignment.toByteUnits(1));
+    }
+}
+
 pub fn updateSymtabSize(self: *Object, elf_file: *Elf) void {
     for (self.locals()) |local_index| {
         const local = elf_file.symbol(local_index);
src/link/Elf.zig
@@ -18,9 +18,6 @@ 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.
@@ -319,12 +316,6 @@ 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);
@@ -1254,7 +1245,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();
+    try self.updateSectionSizes();
 
     // Dump the state for easy debugging.
     // State can be dumped via `--debug-log link_state`.
@@ -1266,7 +1257,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
     // linker-defined synthetic symbols.
     try self.allocateObjects();
     self.allocateLinkerDefinedSymbols();
-    try self.updateSyntheticSectionSizes();
 
     // Look for entry address in objects if not set by the incremental compiler.
     if (self.entry_addr == null) {
@@ -3598,26 +3588,13 @@ fn sortSections(self: *Elf) !void {
     }
 }
 
-fn addAtomsToSections(self: *Elf) !void {
-    const gpa = self.base.allocator;
+fn updateSectionSizes(self: *Elf) !void {
     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);
-        }
+        self.file(index).?.object.updateSectionSizes(self);
     }
-}
 
-fn updateSyntheticSectionSizes(self: *Elf) !void {
     if (self.got_section_index) |index| {
-        if (self.got.dirty) {
-            try self.growAllocSection(index, self.got.size(self));
-            self.got.dirty = false;
-            self.got_addresses_dirty = true;
-        }
+        self.shdrs.items[index].sh_size = self.got.size(self);
     }
 
     if (self.symtab_section_index != null) {