authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-10-03 00:22:11+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-10-16 19:33:04+02:00
log6faed6269fca56d583d2bc5bf35f55a51eb54cdf
tree4a05d233aff0aad4fe2ed85c9ec18257ddaea786
parent14cff77d87c1580e10fce60b6e07022ea9456948

elf: update section sizes accumulated from objects


2 files changed, 17 insertions(+), 37 deletions(-)

src/link/Elf.zig+4-27
...@@ -18,9 +18,6 @@ objects: std.ArrayListUnmanaged(File.Index) = .{},...@@ -18,9 +18,6 @@ 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) = .{},
24/// Given index to a section, pulls index of containing phdr if any.21/// Given index to a section, pulls index of containing phdr if any.
25phdr_to_shdr_table: std.AutoHashMapUnmanaged(u16, u16) = .{},22phdr_to_shdr_table: std.AutoHashMapUnmanaged(u16, u16) = .{},
26/// File offset into the shdr table.23/// File offset into the shdr table.
...@@ -319,12 +316,6 @@ pub fn deinit(self: *Elf) void {...@@ -319,12 +316,6 @@ pub fn deinit(self: *Elf) void {
319 self.objects.deinit(gpa);316 self.objects.deinit(gpa);
320317
321 self.shdrs.deinit(gpa);318 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
328 self.phdr_to_shdr_table.deinit(gpa);319 self.phdr_to_shdr_table.deinit(gpa);
329 self.phdrs.deinit(gpa);320 self.phdrs.deinit(gpa);
330 self.shstrtab.deinit(gpa);321 self.shstrtab.deinit(gpa);
...@@ -1254,7 +1245,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node...@@ -1254,7 +1245,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
1254 // Generate and emit non-incremental sections.1245 // Generate and emit non-incremental sections.
1255 try self.initSections();1246 try self.initSections();
1256 try self.sortSections();1247 try self.sortSections();
1257 try self.addAtomsToSections();1248 try self.updateSectionSizes();
12581249
1259 // Dump the state for easy debugging.1250 // Dump the state for easy debugging.
1260 // State can be dumped via `--debug-log link_state`.1251 // 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...@@ -1266,7 +1257,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
1266 // linker-defined synthetic symbols.1257 // linker-defined synthetic symbols.
1267 try self.allocateObjects();1258 try self.allocateObjects();
1268 self.allocateLinkerDefinedSymbols();1259 self.allocateLinkerDefinedSymbols();
1269 try self.updateSyntheticSectionSizes();
12701260
1271 // Look for entry address in objects if not set by the incremental compiler.1261 // Look for entry address in objects if not set by the incremental compiler.
1272 if (self.entry_addr == null) {1262 if (self.entry_addr == null) {
...@@ -3598,26 +3588,13 @@ fn sortSections(self: *Elf) !void {...@@ -3598,26 +3588,13 @@ fn sortSections(self: *Elf) !void {
3598 }3588 }
3599}3589}
36003590
3601fn addAtomsToSections(self: *Elf) !void {3591fn updateSectionSizes(self: *Elf) !void {
3602 const gpa = self.base.allocator;
3603 for (self.objects.items) |index| {3592 for (self.objects.items) |index| {
3604 for (self.file(index).?.atoms()) |atom_index| {3593 self.file(index).?.object.updateSectionSizes(self);
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 }3594 }
3612}
36133595
3614fn updateSyntheticSectionSizes(self: *Elf) !void {
3615 if (self.got_section_index) |index| {3596 if (self.got_section_index) |index| {
3616 if (self.got.dirty) {3597 self.shdrs.items[index].sh_size = self.got.size(self);
3617 try self.growAllocSection(index, self.got.size(self));
3618 self.got.dirty = false;
3619 self.got_addresses_dirty = true;
3620 }
3621 }3598 }
36223599
3623 if (self.symtab_section_index != null) {3600 if (self.symtab_section_index != null) {
src/link/Elf/Object.zig+13-10
...@@ -179,7 +179,6 @@ fn addAtom(...@@ -179,7 +179,6 @@ fn addAtom(
179 atom.name_offset = try elf_file.strtab.insert(elf_file.base.allocator, name);179 atom.name_offset = try elf_file.strtab.insert(elf_file.base.allocator, name);
180 atom.file_index = self.index;180 atom.file_index = self.index;
181 atom.input_section_index = shndx;181 atom.input_section_index = shndx;
182 atom.output_section_index = try self.getOutputSectionIndex(elf_file, shdr);
183 atom.flags.alive = true;182 atom.flags.alive = true;
184 self.atoms.items[shndx] = atom_index;183 self.atoms.items[shndx] = atom_index;
185184
...@@ -279,10 +278,6 @@ fn initSymtab(self: *Object, elf_file: *Elf) !void {...@@ -279,10 +278,6 @@ fn initSymtab(self: *Object, elf_file: *Elf) !void {
279 sym_ptr.esym_index = @as(u32, @intCast(i));278 sym_ptr.esym_index = @as(u32, @intCast(i));
280 sym_ptr.atom_index = if (sym.st_shndx == elf.SHN_ABS) 0 else self.atoms.items[sym.st_shndx];279 sym_ptr.atom_index = if (sym.st_shndx == elf.SHN_ABS) 0 else self.atoms.items[sym.st_shndx];
281 sym_ptr.file_index = self.index;280 sym_ptr.file_index = self.index;
282 sym_ptr.output_section_index = if (sym_ptr.atom(elf_file)) |atom_ptr|
283 atom_ptr.outputShndx().?
284 else
285 elf.SHN_UNDEF;
286 }281 }
287282
288 for (self.symtab[first_global..]) |sym| {283 for (self.symtab[first_global..]) |sym| {
...@@ -453,15 +448,10 @@ pub fn resolveSymbols(self: *Object, elf_file: *Elf) void {...@@ -453,15 +448,10 @@ pub fn resolveSymbols(self: *Object, elf_file: *Elf) void {
453 elf.SHN_ABS, elf.SHN_COMMON => 0,448 elf.SHN_ABS, elf.SHN_COMMON => 0,
454 else => self.atoms.items[esym.st_shndx],449 else => self.atoms.items[esym.st_shndx],
455 };450 };
456 const output_section_index = if (elf_file.atom(atom_index)) |atom|
457 atom.outputShndx().?
458 else
459 elf.SHN_UNDEF;
460 global.value = esym.st_value;451 global.value = esym.st_value;
461 global.atom_index = atom_index;452 global.atom_index = atom_index;
462 global.esym_index = esym_index;453 global.esym_index = esym_index;
463 global.file_index = self.index;454 global.file_index = self.index;
464 global.output_section_index = output_section_index;
465 global.version_index = elf_file.default_sym_version;455 global.version_index = elf_file.default_sym_version;
466 if (esym.st_bind() == elf.STB_WEAK) global.flags.weak = true;456 if (esym.st_bind() == elf.STB_WEAK) global.flags.weak = true;
467 }457 }
...@@ -611,6 +601,19 @@ pub fn convertCommonSymbols(self: *Object, elf_file: *Elf) !void {...@@ -611,6 +601,19 @@ pub fn convertCommonSymbols(self: *Object, elf_file: *Elf) !void {
611 }601 }
612}602}
613603
604pub fn updateSectionSizes(self: Object, elf_file: *Elf) void {
605 for (self.atoms.items) |atom_index| {
606 const atom = elf_file.atom(atom_index) orelse continue;
607 if (!atom.flags.alive) continue;
608 const shdr = &elf_file.shdrs.items[atom.output_section_index];
609 const offset = atom.alignment.forward(shdr.sh_size);
610 const padding = offset - shdr.sh_size;
611 atom.value = offset;
612 shdr.sh_size += padding + atom.size;
613 shdr.sh_addralign = @max(shdr.sh_addralign, atom.alignment.toByteUnits(1));
614 }
615}
616
614pub fn updateSymtabSize(self: *Object, elf_file: *Elf) void {617pub fn updateSymtabSize(self: *Object, elf_file: *Elf) void {
615 for (self.locals()) |local_index| {618 for (self.locals()) |local_index| {
616 const local = elf_file.symbol(local_index);619 const local = elf_file.symbol(local_index);