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 {...@@ -2041,8 +2041,7 @@ fn claimUnresolved(self: *Elf) void {
2041 zig_object.claimUnresolved(self);2041 zig_object.claimUnresolved(self);
2042 }2042 }
2043 for (self.objects.items) |index| {2043 for (self.objects.items) |index| {
2044 const object = self.file(index).?.object;2044 self.file(index).?.object.claimUnresolved(self);
2045 object.claimUnresolved(self);
2046 }2045 }
2047}2046}
20482047
...@@ -2050,6 +2049,9 @@ fn claimUnresolvedObject(self: *Elf) void {...@@ -2050,6 +2049,9 @@ fn claimUnresolvedObject(self: *Elf) void {
2050 if (self.zigObjectPtr()) |zig_object| {2049 if (self.zigObjectPtr()) |zig_object| {
2051 zig_object.claimUnresolvedObject(self);2050 zig_object.claimUnresolvedObject(self);
2052 }2051 }
2052 for (self.objects.items) |index| {
2053 self.file(index).?.object.claimUnresolvedObject(self);
2054 }
2053}2055}
20542056
2055/// In scanRelocs we will go over all live atoms and scan their relocs.2057/// In scanRelocs we will go over all live atoms and scan their relocs.
...@@ -5083,6 +5085,10 @@ fn writeSectionSymbols(self: *Elf) void {...@@ -5083,6 +5085,10 @@ fn writeSectionSymbols(self: *Elf) void {
5083 }5085 }
5084}5086}
50855087
5088pub fn sectionSymbolOutputSymtabIndex(self: Elf, shndx: u32) u32 {
5089 return @intCast(self.output_sections.getIndex(shndx).? + 1);
5090}
5091
5086/// Always 4 or 8 depending on whether this is 32-bit ELF or 64-bit ELF.5092/// Always 4 or 8 depending on whether this is 32-bit ELF or 64-bit ELF.
5087fn ptrWidthBytes(self: Elf) u8 {5093fn ptrWidthBytes(self: Elf) u8 {
5088 return switch (self.ptr_width) {5094 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 {...@@ -294,6 +294,8 @@ pub fn relocs(self: Atom, elf_file: *Elf) []align(1) const elf.Elf64_Rela {
294}294}
295295
296pub fn writeRelocs(self: Atom, elf_file: *Elf, out_relocs: *std.ArrayList(elf.Elf64_Rela)) !void {296pub 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
297 const file_ptr = self.file(elf_file).?;299 const file_ptr = self.file(elf_file).?;
298 for (self.relocs(elf_file)) |rel| {300 for (self.relocs(elf_file)) |rel| {
299 const target_index = switch (file_ptr) {301 const target_index = switch (file_ptr) {
...@@ -302,15 +304,27 @@ pub fn writeRelocs(self: Atom, elf_file: *Elf, out_relocs: *std.ArrayList(elf.El...@@ -302,15 +304,27 @@ pub fn writeRelocs(self: Atom, elf_file: *Elf, out_relocs: *std.ArrayList(elf.El
302 else => unreachable,304 else => unreachable,
303 };305 };
304 const target = elf_file.symbol(target_index);306 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;
308 const r_type = switch (rel.r_type()) {307 const r_type = switch (rel.r_type()) {
309 Elf.R_X86_64_ZIG_GOT32,308 Elf.R_X86_64_ZIG_GOT32,
310 Elf.R_X86_64_ZIG_GOTPCREL,309 Elf.R_X86_64_ZIG_GOTPCREL,
311 => unreachable, // Sanity check if we accidentally emitted those.310 => unreachable, // Sanity check if we accidentally emitted those.
312 else => |r_type| r_type,311 else => |r_type| r_type,
313 };312 };
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
314 out_relocs.appendAssumeCapacity(.{328 out_relocs.appendAssumeCapacity(.{
315 .r_offset = r_offset,329 .r_offset = r_offset,
316 .r_addend = r_addend,330 .r_addend = r_addend,
src/link/Elf/Object.zig+19
...@@ -491,6 +491,25 @@ pub fn claimUnresolved(self: *Object, elf_file: *Elf) void {...@@ -491,6 +491,25 @@ pub fn claimUnresolved(self: *Object, elf_file: *Elf) void {
491 }491 }
492}492}
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
494pub fn markLive(self: *Object, elf_file: *Elf) void {513pub fn markLive(self: *Object, elf_file: *Elf) void {
495 const first_global = self.first_global orelse return;514 const first_global = self.first_global orelse return;
496 for (self.globals(), 0..) |index, i| {515 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 {...@@ -377,8 +377,7 @@ pub fn claimUnresolvedObject(self: ZigObject, elf_file: *Elf) void {
377377
378 const global = elf_file.symbol(index);378 const global = elf_file.symbol(index);
379 if (global.file(elf_file)) |file| {379 if (global.file(elf_file)) |file| {
380 if (global.elfSym(elf_file).st_shndx != elf.SHN_UNDEF or380 if (global.elfSym(elf_file).st_shndx != elf.SHN_UNDEF or file.index() <= self.index) continue;
381 file.index() <= self.index) continue;
382 }381 }
383382
384 global.value = 0;383 global.value = 0;