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,...@@ -112,7 +112,6 @@ zig_data_section_index: ?u16 = null,
112zig_data_rela_section_index: ?u16 = null,112zig_data_rela_section_index: ?u16 = null,
113zig_bss_section_index: ?u16 = null,113zig_bss_section_index: ?u16 = null,
114zig_got_section_index: ?u16 = null,114zig_got_section_index: ?u16 = null,
115zig_got_rela_section_index: ?u16 = null,
116115
117debug_info_section_index: ?u16 = null,116debug_info_section_index: ?u16 = null,
118debug_abbrev_section_index: ?u16 = null,117debug_abbrev_section_index: ?u16 = null,
...@@ -612,8 +611,7 @@ pub fn initMetadata(self: *Elf) !void {...@@ -612,8 +611,7 @@ pub fn initMetadata(self: *Elf) !void {
612 try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_text_section_index.?, .{});611 try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_text_section_index.?, .{});
613 }612 }
614613
615 if (self.zig_got_section_index == null) {614 if (self.zig_got_section_index == null and !self.isObject()) {
616 // TODO we don't actually need this section in a relocatable object file
617 self.zig_got_section_index = try self.addSection(.{615 self.zig_got_section_index = try self.addSection(.{
618 .name = ".got.zig",616 .name = ".got.zig",
619 .type = elf.SHT_PROGBITS,617 .type = elf.SHT_PROGBITS,
...@@ -622,18 +620,11 @@ pub fn initMetadata(self: *Elf) !void {...@@ -622,18 +620,11 @@ pub fn initMetadata(self: *Elf) !void {
622 .offset = std.math.maxInt(u64),620 .offset = std.math.maxInt(u64),
623 });621 });
624 const shdr = &self.shdrs.items[self.zig_got_section_index.?];622 const shdr = &self.shdrs.items[self.zig_got_section_index.?];
625 fillSection(623 const phndx = self.phdr_zig_got_index.?;
626 self,624 const phdr = self.phdrs.items[phndx];
627 shdr,625 shdr.sh_addr = phdr.p_vaddr;
628 @as(u64, ptr_size) * self.base.options.symbol_count_hint,626 shdr.sh_offset = phdr.p_offset;
629 self.phdr_zig_got_index,627 shdr.sh_size = phdr.p_memsz;
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 }
637 }628 }
638629
639 if (self.zig_data_rel_ro_section_index == null) {630 if (self.zig_data_rel_ro_section_index == null) {
...@@ -3701,7 +3692,6 @@ fn sortShdrs(self: *Elf) !void {...@@ -3701,7 +3692,6 @@ fn sortShdrs(self: *Elf) !void {
3701 &self.zig_text_section_index,3692 &self.zig_text_section_index,
3702 &self.zig_text_rela_section_index,3693 &self.zig_text_rela_section_index,
3703 &self.zig_got_section_index,3694 &self.zig_got_section_index,
3704 &self.zig_got_rela_section_index,
3705 &self.zig_data_rel_ro_section_index,3695 &self.zig_data_rel_ro_section_index,
3706 &self.zig_data_rel_ro_rela_section_index,3696 &self.zig_data_rel_ro_rela_section_index,
3707 &self.zig_data_section_index,3697 &self.zig_data_section_index,
...@@ -3766,7 +3756,6 @@ fn sortShdrs(self: *Elf) !void {...@@ -3766,7 +3756,6 @@ fn sortShdrs(self: *Elf) !void {
37663756
3767 for (&[_]?u16{3757 for (&[_]?u16{
3768 self.zig_text_rela_section_index,3758 self.zig_text_rela_section_index,
3769 self.zig_got_rela_section_index,
3770 self.zig_data_rel_ro_rela_section_index,3759 self.zig_data_rel_ro_rela_section_index,
3771 self.zig_data_rela_section_index,3760 self.zig_data_rela_section_index,
3772 }) |maybe_index| {3761 }) |maybe_index| {
...@@ -3776,6 +3765,20 @@ fn sortShdrs(self: *Elf) !void {...@@ -3776,6 +3765,20 @@ fn sortShdrs(self: *Elf) !void {
3776 shdr.sh_info = backlinks[shdr.sh_info];3765 shdr.sh_info = backlinks[shdr.sh_info];
3777 }3766 }
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
3779 {3782 {
3780 var phdr_to_shdr_table = try self.phdr_to_shdr_table.clone(gpa);3783 var phdr_to_shdr_table = try self.phdr_to_shdr_table.clone(gpa);
3781 defer phdr_to_shdr_table.deinit(gpa);3784 defer phdr_to_shdr_table.deinit(gpa);
...@@ -3832,6 +3835,10 @@ fn updateSectionSizes(self: *Elf) !void {...@@ -3832,6 +3835,10 @@ fn updateSectionSizes(self: *Elf) !void {
3832 }3835 }
3833 }3836 }
38343837
3838 if (self.zigObjectPtr()) |zig_object| {
3839 zig_object.updateRelaSectionSizes(self);
3840 }
3841
3835 if (self.eh_frame_section_index) |index| {3842 if (self.eh_frame_section_index) |index| {
3836 self.shdrs.items[index].sh_size = try eh_frame.calcEhFrameSize(self);3843 self.shdrs.items[index].sh_size = try eh_frame.calcEhFrameSize(self);
3837 }3844 }
src/link/Elf/ZigObject.zig+48-8
...@@ -398,6 +398,40 @@ pub fn markLive(self: *ZigObject, elf_file: *Elf) void {...@@ -398,6 +398,40 @@ pub fn markLive(self: *ZigObject, elf_file: *Elf) void {
398 }398 }
399}399}
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
401pub fn symbol(self: *ZigObject, index: Symbol.Index) Symbol.Index {435pub fn symbol(self: *ZigObject, index: Symbol.Index) Symbol.Index {
402 const is_global = index & global_symbol_bit != 0;436 const is_global = index & global_symbol_bit != 0;
403 const actual_index = index & symbol_mask;437 const actual_index = index & symbol_mask;
...@@ -689,10 +723,12 @@ fn updateDeclCode(...@@ -689,10 +723,12 @@ fn updateDeclCode(
689 sym.value = atom_ptr.value;723 sym.value = atom_ptr.value;
690 esym.st_value = atom_ptr.value;724 esym.st_value = atom_ptr.value;
691725
692 log.debug(" (writing new offset table entry)", .{});726 if (!elf_file.isObject()) {
693 assert(sym.flags.has_zig_got);727 log.debug(" (writing new offset table entry)", .{});
694 const extra = sym.extra(elf_file).?;728 assert(sym.flags.has_zig_got);
695 try elf_file.zig_got.writeOne(elf_file, extra.zig_got);729 const extra = sym.extra(elf_file).?;
730 try elf_file.zig_got.writeOne(elf_file, extra.zig_got);
731 }
696 }732 }
697 } else if (code.len < old_size) {733 } else if (code.len < old_size) {
698 atom_ptr.shrink(elf_file);734 atom_ptr.shrink(elf_file);
...@@ -704,8 +740,10 @@ fn updateDeclCode(...@@ -704,8 +740,10 @@ fn updateDeclCode(
704 sym.value = atom_ptr.value;740 sym.value = atom_ptr.value;
705 esym.st_value = atom_ptr.value;741 esym.st_value = atom_ptr.value;
706742
707 const gop = try sym.getOrCreateZigGotEntry(sym_index, elf_file);743 if (!elf_file.isObject()) {
708 try elf_file.zig_got.writeOne(elf_file, gop.index);744 const gop = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
745 try elf_file.zig_got.writeOne(elf_file, gop.index);
746 }
709 }747 }
710748
711 if (elf_file.base.child_pid) |pid| {749 if (elf_file.base.child_pid) |pid| {
...@@ -957,8 +995,10 @@ fn updateLazySymbol(...@@ -957,8 +995,10 @@ fn updateLazySymbol(
957 local_sym.value = atom_ptr.value;995 local_sym.value = atom_ptr.value;
958 local_esym.st_value = atom_ptr.value;996 local_esym.st_value = atom_ptr.value;
959997
960 const gop = try local_sym.getOrCreateZigGotEntry(symbol_index, elf_file);998 if (!elf_file.isObject()) {
961 try elf_file.zig_got.writeOne(elf_file, gop.index);999 const gop = try local_sym.getOrCreateZigGotEntry(symbol_index, elf_file);
1000 try elf_file.zig_got.writeOne(elf_file, gop.index);
1001 }
9621002
963 const shdr = elf_file.shdrs.items[output_section_index];1003 const shdr = elf_file.shdrs.items[output_section_index];
964 const file_offset = shdr.sh_offset + atom_ptr.value - shdr.sh_addr;1004 const file_offset = shdr.sh_offset + atom_ptr.value - shdr.sh_addr;