Commit ec2671d16b
Changed files (2)
src
link
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;
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);
}