elf: emit dynamic base relocs for .zig.got entries when required

This commit is contained in:
Jakub Konka 2023-10-14 01:33:25 +02:00
parent 315cd7623e
commit b3d98a4b88
2 changed files with 23 additions and 2 deletions

View File

@ -3747,7 +3747,7 @@ fn initSections(self: *Elf) !void {
const needs_rela_dyn = blk: {
if (self.got.flags.needs_rela or self.got.flags.needs_tlsld or
self.copy_rel.symbols.items.len > 0) break :blk true;
self.zig_got.flags.needs_rela or self.copy_rel.symbols.items.len > 0) break :blk true;
if (self.zig_module_index) |index| {
if (self.file(index).?.zig_module.num_dynrelocs > 0) break :blk true;
}
@ -4319,7 +4319,7 @@ fn updateSectionSizes(self: *Elf) !void {
}
if (self.rela_dyn_section_index) |shndx| {
var num = self.got.numRela(self) + self.copy_rel.numRela();
var num = self.got.numRela(self) + self.copy_rel.numRela() + self.zig_got.numRela();
if (self.zig_module_index) |index| {
num += self.file(index).?.zig_module.num_dynrelocs;
}
@ -4901,6 +4901,7 @@ fn writeSyntheticSections(self: *Elf) !void {
const shdr = self.shdrs.items[shndx];
try self.got.addRela(self);
try self.copy_rel.addRela(self);
try self.zig_got.addRela(self);
self.sortRelaDyn();
try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.rela_dyn.items), shdr.sh_offset);
}

View File

@ -251,6 +251,9 @@ pub const ZigGotSection = struct {
entry.* = sym_index;
const symbol = elf_file.symbol(sym_index);
symbol.flags.has_zig_got = true;
if (elf_file.base.options.pic) {
zig_got.flags.needs_rela = true;
}
if (symbol.extra(elf_file)) |extra| {
var new_extra = extra;
new_extra.zig_got = index;
@ -338,6 +341,23 @@ pub const ZigGotSection = struct {
}
}
pub fn numRela(zig_got: ZigGotSection) usize {
return zig_got.entries.items.len;
}
pub fn addRela(zig_got: ZigGotSection, elf_file: *Elf) !void {
try elf_file.rela_dyn.ensureUnusedCapacity(elf_file.base.allocator, zig_got.numRela());
for (zig_got.entries.items) |entry| {
const symbol = elf_file.symbol(entry);
const offset = symbol.zigGotAddress(elf_file);
elf_file.addRelaDynAssumeCapacity(.{
.offset = offset,
.type = elf.R_X86_64_RELATIVE,
.addend = @intCast(symbol.address(.{ .plt = false }, elf_file)),
});
}
}
pub fn updateSymtabSize(zig_got: *ZigGotSection, elf_file: *Elf) void {
_ = elf_file;
zig_got.output_symtab_size.nlocals = @as(u32, @intCast(zig_got.entries.items.len));