diff --git a/src/link/Elf.zig b/src/link/Elf.zig index d62d786143..12ff4a76c9 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -112,7 +112,6 @@ zig_data_section_index: ?u16 = null, zig_data_rela_section_index: ?u16 = null, zig_bss_section_index: ?u16 = null, zig_got_section_index: ?u16 = null, -zig_got_rela_section_index: ?u16 = null, debug_info_section_index: ?u16 = null, debug_abbrev_section_index: ?u16 = null, @@ -612,8 +611,7 @@ pub fn initMetadata(self: *Elf) !void { try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_text_section_index.?, .{}); } - if (self.zig_got_section_index == null) { - // TODO we don't actually need this section in a relocatable object file + if (self.zig_got_section_index == null and !self.isObject()) { self.zig_got_section_index = try self.addSection(.{ .name = ".got.zig", .type = elf.SHT_PROGBITS, @@ -622,18 +620,11 @@ pub fn initMetadata(self: *Elf) !void { .offset = std.math.maxInt(u64), }); const shdr = &self.shdrs.items[self.zig_got_section_index.?]; - fillSection( - self, - shdr, - @as(u64, ptr_size) * self.base.options.symbol_count_hint, - self.phdr_zig_got_index, - ); - if (self.isObject()) { - self.zig_got_rela_section_index = try self.addRelaShdr( - ".rela.got.zig", - self.zig_got_section_index.?, - ); - } + const phndx = self.phdr_zig_got_index.?; + const phdr = self.phdrs.items[phndx]; + shdr.sh_addr = phdr.p_vaddr; + shdr.sh_offset = phdr.p_offset; + shdr.sh_size = phdr.p_memsz; } if (self.zig_data_rel_ro_section_index == null) { @@ -3701,7 +3692,6 @@ fn sortShdrs(self: *Elf) !void { &self.zig_text_section_index, &self.zig_text_rela_section_index, &self.zig_got_section_index, - &self.zig_got_rela_section_index, &self.zig_data_rel_ro_section_index, &self.zig_data_rel_ro_rela_section_index, &self.zig_data_section_index, @@ -3766,7 +3756,6 @@ fn sortShdrs(self: *Elf) !void { for (&[_]?u16{ self.zig_text_rela_section_index, - self.zig_got_rela_section_index, self.zig_data_rel_ro_rela_section_index, self.zig_data_rela_section_index, }) |maybe_index| { @@ -3776,6 +3765,20 @@ fn sortShdrs(self: *Elf) !void { shdr.sh_info = backlinks[shdr.sh_info]; } + { + var last_atom_and_free_list_table = try self.last_atom_and_free_list_table.clone(gpa); + defer last_atom_and_free_list_table.deinit(gpa); + + self.last_atom_and_free_list_table.clearRetainingCapacity(); + + var it = last_atom_and_free_list_table.iterator(); + while (it.next()) |entry| { + const shndx = entry.key_ptr.*; + const meta = entry.value_ptr.*; + self.last_atom_and_free_list_table.putAssumeCapacityNoClobber(backlinks[shndx], meta); + } + } + { var phdr_to_shdr_table = try self.phdr_to_shdr_table.clone(gpa); defer phdr_to_shdr_table.deinit(gpa); @@ -3832,6 +3835,10 @@ fn updateSectionSizes(self: *Elf) !void { } } + if (self.zigObjectPtr()) |zig_object| { + zig_object.updateRelaSectionSizes(self); + } + if (self.eh_frame_section_index) |index| { self.shdrs.items[index].sh_size = try eh_frame.calcEhFrameSize(self); } diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig index 82c3fe45f8..2b4872275c 100644 --- a/src/link/Elf/ZigObject.zig +++ b/src/link/Elf/ZigObject.zig @@ -398,6 +398,40 @@ pub fn markLive(self: *ZigObject, elf_file: *Elf) void { } } +pub fn updateRelaSectionSizes(self: ZigObject, elf_file: *Elf) void { + _ = self; + + for (&[_]?u16{ + elf_file.zig_text_rela_section_index, + elf_file.zig_data_rel_ro_rela_section_index, + elf_file.zig_data_rela_section_index, + }) |maybe_index| { + const index = maybe_index orelse continue; + const shdr = &elf_file.shdrs.items[index]; + const meta = elf_file.last_atom_and_free_list_table.get(@intCast(shdr.sh_info)).?; + const last_atom_index = meta.last_atom_index; + + var atom = elf_file.atom(last_atom_index) orelse continue; + while (true) { + const relocs = atom.relocs(elf_file); + shdr.sh_size += relocs.len * shdr.sh_entsize; + if (elf_file.atom(atom.prev_index)) |prev| { + atom = prev; + } else break; + } + } + + for (&[_]?u16{ + elf_file.zig_text_rela_section_index, + elf_file.zig_data_rel_ro_rela_section_index, + elf_file.zig_data_rela_section_index, + }) |maybe_index| { + const index = maybe_index orelse continue; + const shdr = &elf_file.shdrs.items[index]; + if (shdr.sh_size == 0) shdr.sh_offset = 0; + } +} + pub fn symbol(self: *ZigObject, index: Symbol.Index) Symbol.Index { const is_global = index & global_symbol_bit != 0; const actual_index = index & symbol_mask; @@ -689,10 +723,12 @@ fn updateDeclCode( sym.value = atom_ptr.value; esym.st_value = atom_ptr.value; - log.debug(" (writing new offset table entry)", .{}); - assert(sym.flags.has_zig_got); - const extra = sym.extra(elf_file).?; - try elf_file.zig_got.writeOne(elf_file, extra.zig_got); + if (!elf_file.isObject()) { + log.debug(" (writing new offset table entry)", .{}); + assert(sym.flags.has_zig_got); + const extra = sym.extra(elf_file).?; + try elf_file.zig_got.writeOne(elf_file, extra.zig_got); + } } } else if (code.len < old_size) { atom_ptr.shrink(elf_file); @@ -704,8 +740,10 @@ fn updateDeclCode( sym.value = atom_ptr.value; esym.st_value = atom_ptr.value; - const gop = try sym.getOrCreateZigGotEntry(sym_index, elf_file); - try elf_file.zig_got.writeOne(elf_file, gop.index); + if (!elf_file.isObject()) { + const gop = try sym.getOrCreateZigGotEntry(sym_index, elf_file); + try elf_file.zig_got.writeOne(elf_file, gop.index); + } } if (elf_file.base.child_pid) |pid| { @@ -957,8 +995,10 @@ fn updateLazySymbol( local_sym.value = atom_ptr.value; local_esym.st_value = atom_ptr.value; - const gop = try local_sym.getOrCreateZigGotEntry(symbol_index, elf_file); - try elf_file.zig_got.writeOne(elf_file, gop.index); + if (!elf_file.isObject()) { + const gop = try local_sym.getOrCreateZigGotEntry(symbol_index, elf_file); + try elf_file.zig_got.writeOne(elf_file, gop.index); + } const shdr = elf_file.shdrs.items[output_section_index]; const file_offset = shdr.sh_offset + atom_ptr.value - shdr.sh_addr;