| author | |
| committer | |
| log | ec2671d16b9363ad7f39312552456cf5e449e930 |
| tree | 2f0dd15f5a6f9fb140b90a6157dc1bd61049d5c7 |
| parent | 21853bc310fb6029f949bcf9aca59f69c768a664 |
2 files changed, 72 insertions(+), 25 deletions(-)
src/link/Elf.zig+24-17| ... | ... | @@ -112,7 +112,6 @@ zig_data_section_index: ?u16 = null, |
| 112 | 112 | zig_data_rela_section_index: ?u16 = null, |
| 113 | 113 | zig_bss_section_index: ?u16 = null, |
| 114 | 114 | zig_got_section_index: ?u16 = null, |
| 115 | zig_got_rela_section_index: ?u16 = null, | |
| 116 | 115 | |
| 117 | 116 | debug_info_section_index: ?u16 = null, |
| 118 | 117 | debug_abbrev_section_index: ?u16 = null, |
| ... | ... | @@ -612,8 +611,7 @@ pub fn initMetadata(self: *Elf) !void { |
| 612 | 611 | try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_text_section_index.?, .{}); |
| 613 | 612 | } |
| 614 | 613 | |
| 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()) { | |
| 617 | 615 | self.zig_got_section_index = try self.addSection(.{ |
| 618 | 616 | .name = ".got.zig", |
| 619 | 617 | .type = elf.SHT_PROGBITS, |
| ... | ... | @@ -622,18 +620,11 @@ pub fn initMetadata(self: *Elf) !void { |
| 622 | 620 | .offset = std.math.maxInt(u64), |
| 623 | 621 | }); |
| 624 | 622 | 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; | |
| 637 | 628 | } |
| 638 | 629 | |
| 639 | 630 | if (self.zig_data_rel_ro_section_index == null) { |
| ... | ... | @@ -3701,7 +3692,6 @@ fn sortShdrs(self: *Elf) !void { |
| 3701 | 3692 | &self.zig_text_section_index, |
| 3702 | 3693 | &self.zig_text_rela_section_index, |
| 3703 | 3694 | &self.zig_got_section_index, |
| 3704 | &self.zig_got_rela_section_index, | |
| 3705 | 3695 | &self.zig_data_rel_ro_section_index, |
| 3706 | 3696 | &self.zig_data_rel_ro_rela_section_index, |
| 3707 | 3697 | &self.zig_data_section_index, |
| ... | ... | @@ -3766,7 +3756,6 @@ fn sortShdrs(self: *Elf) !void { |
| 3766 | 3756 | |
| 3767 | 3757 | for (&[_]?u16{ |
| 3768 | 3758 | self.zig_text_rela_section_index, |
| 3769 | self.zig_got_rela_section_index, | |
| 3770 | 3759 | self.zig_data_rel_ro_rela_section_index, |
| 3771 | 3760 | self.zig_data_rela_section_index, |
| 3772 | 3761 | }) |maybe_index| { |
| ... | ... | @@ -3776,6 +3765,20 @@ fn sortShdrs(self: *Elf) !void { |
| 3776 | 3765 | shdr.sh_info = backlinks[shdr.sh_info]; |
| 3777 | 3766 | } |
| 3778 | 3767 | |
| 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 | 3783 | var phdr_to_shdr_table = try self.phdr_to_shdr_table.clone(gpa); |
| 3781 | 3784 | defer phdr_to_shdr_table.deinit(gpa); |
| ... | ... | @@ -3832,6 +3835,10 @@ fn updateSectionSizes(self: *Elf) !void { |
| 3832 | 3835 | } |
| 3833 | 3836 | } |
| 3834 | 3837 | |
| 3838 | if (self.zigObjectPtr()) |zig_object| { | |
| 3839 | zig_object.updateRelaSectionSizes(self); | |
| 3840 | } | |
| 3841 | ||
| 3835 | 3842 | if (self.eh_frame_section_index) |index| { |
| 3836 | 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 | 398 | } |
| 399 | 399 | } |
| 400 | 400 | |
| 401 | pub 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 | ||
| 401 | 435 | pub fn symbol(self: *ZigObject, index: Symbol.Index) Symbol.Index { |
| 402 | 436 | const is_global = index & global_symbol_bit != 0; |
| 403 | 437 | const actual_index = index & symbol_mask; |
| ... | ... | @@ -689,10 +723,12 @@ fn updateDeclCode( |
| 689 | 723 | sym.value = atom_ptr.value; |
| 690 | 724 | esym.st_value = atom_ptr.value; |
| 691 | 725 | |
| 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 | } | |
| 696 | 732 | } |
| 697 | 733 | } else if (code.len < old_size) { |
| 698 | 734 | atom_ptr.shrink(elf_file); |
| ... | ... | @@ -704,8 +740,10 @@ fn updateDeclCode( |
| 704 | 740 | sym.value = atom_ptr.value; |
| 705 | 741 | esym.st_value = atom_ptr.value; |
| 706 | 742 | |
| 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 | } | |
| 709 | 747 | } |
| 710 | 748 | |
| 711 | 749 | if (elf_file.base.child_pid) |pid| { |
| ... | ... | @@ -957,8 +995,10 @@ fn updateLazySymbol( |
| 957 | 995 | local_sym.value = atom_ptr.value; |
| 958 | 996 | local_esym.st_value = atom_ptr.value; |
| 959 | 997 | |
| 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 | } | |
| 962 | 1002 | |
| 963 | 1003 | const shdr = elf_file.shdrs.items[output_section_index]; |
| 964 | 1004 | const file_offset = shdr.sh_offset + atom_ptr.value - shdr.sh_addr; |