| author | |
| committer | |
| log | ae08f9bfe9c2ab5488b375ffd949609016658450 |
| tree | 697a3d39739a2704c538965c6ebcb462f1ea597f |
| parent | e87c751558ec1b81bab09f40959a58d250a35a41 |
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 | } |
| 2048 | 2047 | ||
| ... | @@ -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 | } |
| 2054 | 2056 | ||
| 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 | } |
| 5085 | 5087 | ||
| 5088 | pub 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. |
| 5087 | fn ptrWidthBytes(self: Elf) u8 { | 5093 | fn 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 | } |
| 295 | 295 | ||
| 296 | pub fn writeRelocs(self: Atom, elf_file: *Elf, out_relocs: *std.ArrayList(elf.Elf64_Rela)) !void { | 296 | pub 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 | } |
| 493 | 493 | ||
| 494 | pub 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 | |||
| 494 | pub fn markLive(self: *Object, elf_file: *Elf) void { | 513 | pub 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 { |
| 377 | 377 | ||
| 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 or | 380 | if (global.elfSym(elf_file).st_shndx != elf.SHN_UNDEF or file.index() <= self.index) continue; |
| 381 | file.index() <= self.index) continue; | ||
| 382 | } | 381 | } |
| 383 | 382 | ||
| 384 | global.value = 0; | 383 | global.value = 0; |