authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-11-08 11:51:11+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-11-08 11:51:11+01:00
logae08f9bfe9c2ab5488b375ffd949609016658450
tree697a3d39739a2704c538965c6ebcb462f1ea597f
parente87c751558ec1b81bab09f40959a58d250a35a41

elf: claim unresolved dangling symbols as undef externs in -r mode


4 files changed, 45 insertions(+), 7 deletions(-)

src/link/Elf.zig+8-2
......@@ -2041,8 +2041,7 @@ fn claimUnresolved(self: *Elf) void {
20412041 zig_object.claimUnresolved(self);
20422042 }
20432043 for (self.objects.items) |index| {
2044 const object = self.file(index).?.object;
2045 object.claimUnresolved(self);
2044 self.file(index).?.object.claimUnresolved(self);
20462045 }
20472046}
20482047
......@@ -2050,6 +2049,9 @@ fn claimUnresolvedObject(self: *Elf) void {
20502049 if (self.zigObjectPtr()) |zig_object| {
20512050 zig_object.claimUnresolvedObject(self);
20522051 }
2052 for (self.objects.items) |index| {
2053 self.file(index).?.object.claimUnresolvedObject(self);
2054 }
20532055}
20542056
20552057/// In scanRelocs we will go over all live atoms and scan their relocs.
......@@ -5083,6 +5085,10 @@ fn writeSectionSymbols(self: *Elf) void {
50835085 }
50845086}
50855087
5088pub fn sectionSymbolOutputSymtabIndex(self: Elf, shndx: u32) u32 {
5089 return @intCast(self.output_sections.getIndex(shndx).? + 1);
5090}
5091
50865092/// Always 4 or 8 depending on whether this is 32-bit ELF or 64-bit ELF.
50875093fn ptrWidthBytes(self: Elf) u8 {
50885094 return switch (self.ptr_width) {
src/link/Elf/Atom.zig+17-3
......@@ -294,6 +294,8 @@ pub fn relocs(self: Atom, elf_file: *Elf) []align(1) const elf.Elf64_Rela {
294294}
295295
296296pub fn writeRelocs(self: Atom, elf_file: *Elf, out_relocs: *std.ArrayList(elf.Elf64_Rela)) !void {
297 relocs_log.debug("0x{x}: {s}", .{ self.value, self.name(elf_file) });
298
297299 const file_ptr = self.file(elf_file).?;
298300 for (self.relocs(elf_file)) |rel| {
299301 const target_index = switch (file_ptr) {
......@@ -302,15 +304,27 @@ pub fn writeRelocs(self: Atom, elf_file: *Elf, out_relocs: *std.ArrayList(elf.El
302304 else => unreachable,
303305 };
304306 const target = elf_file.symbol(target_index);
305 const r_sym = target.outputSymtabIndex(elf_file);
306 const r_offset = self.value + rel.r_offset;
307 const r_addend = rel.r_addend;
308307 const r_type = switch (rel.r_type()) {
309308 Elf.R_X86_64_ZIG_GOT32,
310309 Elf.R_X86_64_ZIG_GOTPCREL,
311310 => unreachable, // Sanity check if we accidentally emitted those.
312311 else => |r_type| r_type,
313312 };
313 const r_offset = self.value + rel.r_offset;
314 const r_addend = rel.r_addend;
315 const r_sym = switch (target.type(elf_file)) {
316 elf.STT_SECTION => elf_file.sectionSymbolOutputSymtabIndex(target.outputShndx().?),
317 else => target.outputSymtabIndex(elf_file),
318 };
319
320 relocs_log.debug(" {s}: [{x} => {d}({s})] + {x}", .{
321 fmtRelocType(r_type),
322 r_offset,
323 r_sym,
324 target.name(elf_file),
325 r_addend,
326 });
327
314328 out_relocs.appendAssumeCapacity(.{
315329 .r_offset = r_offset,
316330 .r_addend = r_addend,
src/link/Elf/Object.zig+19
......@@ -491,6 +491,25 @@ pub fn claimUnresolved(self: *Object, elf_file: *Elf) void {
491491 }
492492}
493493
494pub fn claimUnresolvedObject(self: *Object, elf_file: *Elf) void {
495 const first_global = self.first_global orelse return;
496 for (self.globals(), 0..) |index, i| {
497 const esym_index = @as(u32, @intCast(first_global + i));
498 const esym = self.symtab.items[esym_index];
499 if (esym.st_shndx != elf.SHN_UNDEF) continue;
500
501 const global = elf_file.symbol(index);
502 if (global.file(elf_file)) |file| {
503 if (global.elfSym(elf_file).st_shndx != elf.SHN_UNDEF or file.index() <= self.index) continue;
504 }
505
506 global.value = 0;
507 global.atom_index = 0;
508 global.esym_index = esym_index;
509 global.file_index = self.index;
510 }
511}
512
494513pub fn markLive(self: *Object, elf_file: *Elf) void {
495514 const first_global = self.first_global orelse return;
496515 for (self.globals(), 0..) |index, i| {
src/link/Elf/ZigObject.zig+1-2
......@@ -377,8 +377,7 @@ pub fn claimUnresolvedObject(self: ZigObject, elf_file: *Elf) void {
377377
378378 const global = elf_file.symbol(index);
379379 if (global.file(elf_file)) |file| {
380 if (global.elfSym(elf_file).st_shndx != elf.SHN_UNDEF or
381 file.index() <= self.index) continue;
380 if (global.elfSym(elf_file).st_shndx != elf.SHN_UNDEF or file.index() <= self.index) continue;
382381 }
383382
384383 global.value = 0;