authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-10-14 01:33:25+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-10-16 19:33:06+02:00
logb3d98a4b88514b1e8d2cc07ef05c218f50f5f5d8
tree986501178b8bcf292699a92720d774faa928a5c9
parent315cd7623eccdbce009845083b708f1c9bb6c672

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


2 files changed, 23 insertions(+), 2 deletions(-)

src/link/Elf.zig+3-2
...@@ -3747,7 +3747,7 @@ fn initSections(self: *Elf) !void {...@@ -3747,7 +3747,7 @@ fn initSections(self: *Elf) !void {
37473747
3748 const needs_rela_dyn = blk: {3748 const needs_rela_dyn = blk: {
3749 if (self.got.flags.needs_rela or self.got.flags.needs_tlsld or3749 if (self.got.flags.needs_rela or self.got.flags.needs_tlsld or
3750 self.copy_rel.symbols.items.len > 0) break :blk true;3750 self.zig_got.flags.needs_rela or self.copy_rel.symbols.items.len > 0) break :blk true;
3751 if (self.zig_module_index) |index| {3751 if (self.zig_module_index) |index| {
3752 if (self.file(index).?.zig_module.num_dynrelocs > 0) break :blk true;3752 if (self.file(index).?.zig_module.num_dynrelocs > 0) break :blk true;
3753 }3753 }
...@@ -4319,7 +4319,7 @@ fn updateSectionSizes(self: *Elf) !void {...@@ -4319,7 +4319,7 @@ fn updateSectionSizes(self: *Elf) !void {
4319 }4319 }
43204320
4321 if (self.rela_dyn_section_index) |shndx| {4321 if (self.rela_dyn_section_index) |shndx| {
4322 var num = self.got.numRela(self) + self.copy_rel.numRela();4322 var num = self.got.numRela(self) + self.copy_rel.numRela() + self.zig_got.numRela();
4323 if (self.zig_module_index) |index| {4323 if (self.zig_module_index) |index| {
4324 num += self.file(index).?.zig_module.num_dynrelocs;4324 num += self.file(index).?.zig_module.num_dynrelocs;
4325 }4325 }
...@@ -4901,6 +4901,7 @@ fn writeSyntheticSections(self: *Elf) !void {...@@ -4901,6 +4901,7 @@ fn writeSyntheticSections(self: *Elf) !void {
4901 const shdr = self.shdrs.items[shndx];4901 const shdr = self.shdrs.items[shndx];
4902 try self.got.addRela(self);4902 try self.got.addRela(self);
4903 try self.copy_rel.addRela(self);4903 try self.copy_rel.addRela(self);
4904 try self.zig_got.addRela(self);
4904 self.sortRelaDyn();4905 self.sortRelaDyn();
4905 try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.rela_dyn.items), shdr.sh_offset);4906 try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.rela_dyn.items), shdr.sh_offset);
4906 }4907 }
src/link/Elf/synthetic_sections.zig+20
...@@ -251,6 +251,9 @@ pub const ZigGotSection = struct {...@@ -251,6 +251,9 @@ pub const ZigGotSection = struct {
251 entry.* = sym_index;251 entry.* = sym_index;
252 const symbol = elf_file.symbol(sym_index);252 const symbol = elf_file.symbol(sym_index);
253 symbol.flags.has_zig_got = true;253 symbol.flags.has_zig_got = true;
254 if (elf_file.base.options.pic) {
255 zig_got.flags.needs_rela = true;
256 }
254 if (symbol.extra(elf_file)) |extra| {257 if (symbol.extra(elf_file)) |extra| {
255 var new_extra = extra;258 var new_extra = extra;
256 new_extra.zig_got = index;259 new_extra.zig_got = index;
...@@ -338,6 +341,23 @@ pub const ZigGotSection = struct {...@@ -338,6 +341,23 @@ pub const ZigGotSection = struct {
338 }341 }
339 }342 }
340343
344 pub fn numRela(zig_got: ZigGotSection) usize {
345 return zig_got.entries.items.len;
346 }
347
348 pub fn addRela(zig_got: ZigGotSection, elf_file: *Elf) !void {
349 try elf_file.rela_dyn.ensureUnusedCapacity(elf_file.base.allocator, zig_got.numRela());
350 for (zig_got.entries.items) |entry| {
351 const symbol = elf_file.symbol(entry);
352 const offset = symbol.zigGotAddress(elf_file);
353 elf_file.addRelaDynAssumeCapacity(.{
354 .offset = offset,
355 .type = elf.R_X86_64_RELATIVE,
356 .addend = @intCast(symbol.address(.{ .plt = false }, elf_file)),
357 });
358 }
359 }
360
341 pub fn updateSymtabSize(zig_got: *ZigGotSection, elf_file: *Elf) void {361 pub fn updateSymtabSize(zig_got: *ZigGotSection, elf_file: *Elf) void {
342 _ = elf_file;362 _ = elf_file;
343 zig_got.output_symtab_size.nlocals = @as(u32, @intCast(zig_got.entries.items.len));363 zig_got.output_symtab_size.nlocals = @as(u32, @intCast(zig_got.entries.items.len));