diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2023-11-08 11:51:11 +0100 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2023-11-08 11:51:11 +0100 |
| commit | ae08f9bfe9c2ab5488b375ffd949609016658450 (patch) | |
| tree | 697a3d39739a2704c538965c6ebcb462f1ea597f /src/link/Elf | |
| parent | e87c751558ec1b81bab09f40959a58d250a35a41 (diff) | |
| download | zig-ae08f9bfe9c2ab5488b375ffd949609016658450.tar.gz zig-ae08f9bfe9c2ab5488b375ffd949609016658450.zip | |
elf: claim unresolved dangling symbols as undef externs in -r mode
Diffstat (limited to 'src/link/Elf')
| -rw-r--r-- | src/link/Elf/Atom.zig | 20 | ||||
| -rw-r--r-- | src/link/Elf/Object.zig | 19 | ||||
| -rw-r--r-- | src/link/Elf/ZigObject.zig | 3 |
3 files changed, 37 insertions, 5 deletions
diff --git a/src/link/Elf/Atom.zig b/src/link/Elf/Atom.zig index 95202a3d4c..09a16e4240 100644 --- a/src/link/Elf/Atom.zig +++ b/src/link/Elf/Atom.zig @@ -294,6 +294,8 @@ pub fn relocs(self: Atom, elf_file: *Elf) []align(1) const elf.Elf64_Rela { } pub fn writeRelocs(self: Atom, elf_file: *Elf, out_relocs: *std.ArrayList(elf.Elf64_Rela)) !void { + relocs_log.debug("0x{x}: {s}", .{ self.value, self.name(elf_file) }); + const file_ptr = self.file(elf_file).?; for (self.relocs(elf_file)) |rel| { const target_index = switch (file_ptr) { @@ -302,15 +304,27 @@ pub fn writeRelocs(self: Atom, elf_file: *Elf, out_relocs: *std.ArrayList(elf.El else => unreachable, }; const target = elf_file.symbol(target_index); - const r_sym = target.outputSymtabIndex(elf_file); - const r_offset = self.value + rel.r_offset; - const r_addend = rel.r_addend; const r_type = switch (rel.r_type()) { Elf.R_X86_64_ZIG_GOT32, Elf.R_X86_64_ZIG_GOTPCREL, => unreachable, // Sanity check if we accidentally emitted those. else => |r_type| r_type, }; + const r_offset = self.value + rel.r_offset; + const r_addend = rel.r_addend; + const r_sym = switch (target.type(elf_file)) { + elf.STT_SECTION => elf_file.sectionSymbolOutputSymtabIndex(target.outputShndx().?), + else => target.outputSymtabIndex(elf_file), + }; + + relocs_log.debug(" {s}: [{x} => {d}({s})] + {x}", .{ + fmtRelocType(r_type), + r_offset, + r_sym, + target.name(elf_file), + r_addend, + }); + out_relocs.appendAssumeCapacity(.{ .r_offset = r_offset, .r_addend = r_addend, diff --git a/src/link/Elf/Object.zig b/src/link/Elf/Object.zig index 8a402ad7d2..0a4232d3b1 100644 --- a/src/link/Elf/Object.zig +++ b/src/link/Elf/Object.zig @@ -491,6 +491,25 @@ pub fn claimUnresolved(self: *Object, elf_file: *Elf) void { } } +pub fn claimUnresolvedObject(self: *Object, elf_file: *Elf) void { + const first_global = self.first_global orelse return; + for (self.globals(), 0..) |index, i| { + const esym_index = @as(u32, @intCast(first_global + i)); + const esym = self.symtab.items[esym_index]; + if (esym.st_shndx != elf.SHN_UNDEF) continue; + + const global = elf_file.symbol(index); + if (global.file(elf_file)) |file| { + if (global.elfSym(elf_file).st_shndx != elf.SHN_UNDEF or file.index() <= self.index) continue; + } + + global.value = 0; + global.atom_index = 0; + global.esym_index = esym_index; + global.file_index = self.index; + } +} + pub fn markLive(self: *Object, elf_file: *Elf) void { const first_global = self.first_global orelse return; for (self.globals(), 0..) |index, i| { diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig index 07c492431c..798ced73a5 100644 --- a/src/link/Elf/ZigObject.zig +++ b/src/link/Elf/ZigObject.zig @@ -377,8 +377,7 @@ pub fn claimUnresolvedObject(self: ZigObject, elf_file: *Elf) void { const global = elf_file.symbol(index); if (global.file(elf_file)) |file| { - if (global.elfSym(elf_file).st_shndx != elf.SHN_UNDEF or - file.index() <= self.index) continue; + if (global.elfSym(elf_file).st_shndx != elf.SHN_UNDEF or file.index() <= self.index) continue; } global.value = 0; |
