authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-11-01 22:51:18+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-11-04 09:09:46+01:00
logec2671d16b9363ad7f39312552456cf5e449e930
tree2f0dd15f5a6f9fb140b90a6157dc1bd61049d5c7
parent21853bc310fb6029f949bcf9aca59f69c768a664

elf: update .rela section sizes; skip .got.zig when emitting object


2 files changed, 72 insertions(+), 25 deletions(-)

src/link/Elf.zig+24-17
......@@ -112,7 +112,6 @@ zig_data_section_index: ?u16 = null,
112112zig_data_rela_section_index: ?u16 = null,
113113zig_bss_section_index: ?u16 = null,
114114zig_got_section_index: ?u16 = null,
115zig_got_rela_section_index: ?u16 = null,
116115
117116debug_info_section_index: ?u16 = null,
118117debug_abbrev_section_index: ?u16 = null,
......@@ -612,8 +611,7 @@ pub fn initMetadata(self: *Elf) !void {
612611 try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_text_section_index.?, .{});
613612 }
614613
615 if (self.zig_got_section_index == null) {
616 // TODO we don't actually need this section in a relocatable object file
614 if (self.zig_got_section_index == null and !self.isObject()) {
617615 self.zig_got_section_index = try self.addSection(.{
618616 .name = ".got.zig",
619617 .type = elf.SHT_PROGBITS,
......@@ -622,18 +620,11 @@ pub fn initMetadata(self: *Elf) !void {
622620 .offset = std.math.maxInt(u64),
623621 });
624622 const shdr = &self.shdrs.items[self.zig_got_section_index.?];
625 fillSection(
626 self,
627 shdr,
628 @as(u64, ptr_size) * self.base.options.symbol_count_hint,
629 self.phdr_zig_got_index,
630 );
631 if (self.isObject()) {
632 self.zig_got_rela_section_index = try self.addRelaShdr(
633 ".rela.got.zig",
634 self.zig_got_section_index.?,
635 );
636 }
623 const phndx = self.phdr_zig_got_index.?;
624 const phdr = self.phdrs.items[phndx];
625 shdr.sh_addr = phdr.p_vaddr;
626 shdr.sh_offset = phdr.p_offset;
627 shdr.sh_size = phdr.p_memsz;
637628 }
638629
639630 if (self.zig_data_rel_ro_section_index == null) {
......@@ -3701,7 +3692,6 @@ fn sortShdrs(self: *Elf) !void {
37013692 &self.zig_text_section_index,
37023693 &self.zig_text_rela_section_index,
37033694 &self.zig_got_section_index,
3704 &self.zig_got_rela_section_index,
37053695 &self.zig_data_rel_ro_section_index,
37063696 &self.zig_data_rel_ro_rela_section_index,
37073697 &self.zig_data_section_index,
......@@ -3766,7 +3756,6 @@ fn sortShdrs(self: *Elf) !void {
37663756
37673757 for (&[_]?u16{
37683758 self.zig_text_rela_section_index,
3769 self.zig_got_rela_section_index,
37703759 self.zig_data_rel_ro_rela_section_index,
37713760 self.zig_data_rela_section_index,
37723761 }) |maybe_index| {
......@@ -3776,6 +3765,20 @@ fn sortShdrs(self: *Elf) !void {
37763765 shdr.sh_info = backlinks[shdr.sh_info];
37773766 }
37783767
3768 {
3769 var last_atom_and_free_list_table = try self.last_atom_and_free_list_table.clone(gpa);
3770 defer last_atom_and_free_list_table.deinit(gpa);
3771
3772 self.last_atom_and_free_list_table.clearRetainingCapacity();
3773
3774 var it = last_atom_and_free_list_table.iterator();
3775 while (it.next()) |entry| {
3776 const shndx = entry.key_ptr.*;
3777 const meta = entry.value_ptr.*;
3778 self.last_atom_and_free_list_table.putAssumeCapacityNoClobber(backlinks[shndx], meta);
3779 }
3780 }
3781
37793782 {
37803783 var phdr_to_shdr_table = try self.phdr_to_shdr_table.clone(gpa);
37813784 defer phdr_to_shdr_table.deinit(gpa);
......@@ -3832,6 +3835,10 @@ fn updateSectionSizes(self: *Elf) !void {
38323835 }
38333836 }
38343837
3838 if (self.zigObjectPtr()) |zig_object| {
3839 zig_object.updateRelaSectionSizes(self);
3840 }
3841
38353842 if (self.eh_frame_section_index) |index| {
38363843 self.shdrs.items[index].sh_size = try eh_frame.calcEhFrameSize(self);
38373844 }
src/link/Elf/ZigObject.zig+48-8
......@@ -398,6 +398,40 @@ pub fn markLive(self: *ZigObject, elf_file: *Elf) void {
398398 }
399399}
400400
401pub fn updateRelaSectionSizes(self: ZigObject, elf_file: *Elf) void {
402 _ = self;
403
404 for (&[_]?u16{
405 elf_file.zig_text_rela_section_index,
406 elf_file.zig_data_rel_ro_rela_section_index,
407 elf_file.zig_data_rela_section_index,
408 }) |maybe_index| {
409 const index = maybe_index orelse continue;
410 const shdr = &elf_file.shdrs.items[index];
411 const meta = elf_file.last_atom_and_free_list_table.get(@intCast(shdr.sh_info)).?;
412 const last_atom_index = meta.last_atom_index;
413
414 var atom = elf_file.atom(last_atom_index) orelse continue;
415 while (true) {
416 const relocs = atom.relocs(elf_file);
417 shdr.sh_size += relocs.len * shdr.sh_entsize;
418 if (elf_file.atom(atom.prev_index)) |prev| {
419 atom = prev;
420 } else break;
421 }
422 }
423
424 for (&[_]?u16{
425 elf_file.zig_text_rela_section_index,
426 elf_file.zig_data_rel_ro_rela_section_index,
427 elf_file.zig_data_rela_section_index,
428 }) |maybe_index| {
429 const index = maybe_index orelse continue;
430 const shdr = &elf_file.shdrs.items[index];
431 if (shdr.sh_size == 0) shdr.sh_offset = 0;
432 }
433}
434
401435pub fn symbol(self: *ZigObject, index: Symbol.Index) Symbol.Index {
402436 const is_global = index & global_symbol_bit != 0;
403437 const actual_index = index & symbol_mask;
......@@ -689,10 +723,12 @@ fn updateDeclCode(
689723 sym.value = atom_ptr.value;
690724 esym.st_value = atom_ptr.value;
691725
692 log.debug(" (writing new offset table entry)", .{});
693 assert(sym.flags.has_zig_got);
694 const extra = sym.extra(elf_file).?;
695 try elf_file.zig_got.writeOne(elf_file, extra.zig_got);
726 if (!elf_file.isObject()) {
727 log.debug(" (writing new offset table entry)", .{});
728 assert(sym.flags.has_zig_got);
729 const extra = sym.extra(elf_file).?;
730 try elf_file.zig_got.writeOne(elf_file, extra.zig_got);
731 }
696732 }
697733 } else if (code.len < old_size) {
698734 atom_ptr.shrink(elf_file);
......@@ -704,8 +740,10 @@ fn updateDeclCode(
704740 sym.value = atom_ptr.value;
705741 esym.st_value = atom_ptr.value;
706742
707 const gop = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
708 try elf_file.zig_got.writeOne(elf_file, gop.index);
743 if (!elf_file.isObject()) {
744 const gop = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
745 try elf_file.zig_got.writeOne(elf_file, gop.index);
746 }
709747 }
710748
711749 if (elf_file.base.child_pid) |pid| {
......@@ -957,8 +995,10 @@ fn updateLazySymbol(
957995 local_sym.value = atom_ptr.value;
958996 local_esym.st_value = atom_ptr.value;
959997
960 const gop = try local_sym.getOrCreateZigGotEntry(symbol_index, elf_file);
961 try elf_file.zig_got.writeOne(elf_file, gop.index);
998 if (!elf_file.isObject()) {
999 const gop = try local_sym.getOrCreateZigGotEntry(symbol_index, elf_file);
1000 try elf_file.zig_got.writeOne(elf_file, gop.index);
1001 }
9621002
9631003 const shdr = elf_file.shdrs.items[output_section_index];
9641004 const file_offset = shdr.sh_offset + atom_ptr.value - shdr.sh_addr;