diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2023-11-02 00:20:56 +0100 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2023-11-04 09:10:23 +0100 |
| commit | 8055f687659de87ce0101cb3e459699b4541a8b7 (patch) | |
| tree | 19430e04b1d123a6f8946b8ea0fa88cd7452590b /src | |
| parent | e8f522122ac83e94b2fe58aa369917f3686743c5 (diff) | |
| download | zig-8055f687659de87ce0101cb3e459699b4541a8b7.tar.gz zig-8055f687659de87ce0101cb3e459699b4541a8b7.zip | |
elf: make sure we never emit .got.zig relocs when linking object files
Diffstat (limited to 'src')
| -rw-r--r-- | src/arch/x86_64/CodeGen.zig | 4 | ||||
| -rw-r--r-- | src/codegen.zig | 2 | ||||
| -rw-r--r-- | src/link/Elf/Symbol.zig | 6 | ||||
| -rw-r--r-- | src/link/Elf/ZigObject.zig | 36 |
4 files changed, 28 insertions, 20 deletions
diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index d923f32bdd..b65a704351 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -10235,7 +10235,7 @@ fn genCall(self: *Self, info: union(enum) { if (self.bin_file.cast(link.File.Elf)) |elf_file| { const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl); const sym = elf_file.symbol(sym_index); - _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file); + try sym.createZigGotEntry(sym_index, elf_file); if (self.bin_file.options.pic) { const callee_reg: Register = switch (resolved_cc) { .SysV => callee: { @@ -13103,7 +13103,7 @@ fn genLazySymbolRef( const sym_index = elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, lazy_sym) catch |err| return self.fail("{s} creating lazy symbol", .{@errorName(err)}); const sym = elf_file.symbol(sym_index); - _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file); + try sym.createZigGotEntry(sym_index, elf_file); if (self.bin_file.options.pic) { switch (tag) { diff --git a/src/codegen.zig b/src/codegen.zig index bb2a9f9324..c5062228de 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -909,7 +909,7 @@ fn genDeclRef( } const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, decl_index); const sym = elf_file.symbol(sym_index); - _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file); + try sym.createZigGotEntry(sym_index, elf_file); return GenResult.mcv(.{ .load_symbol = sym.esym_index }); } else if (bin_file.cast(link.File.MachO)) |macho_file| { if (is_extern) { diff --git a/src/link/Elf/Symbol.zig b/src/link/Elf/Symbol.zig index 01a8129b32..113020e84e 100644 --- a/src/link/Elf/Symbol.zig +++ b/src/link/Elf/Symbol.zig @@ -168,11 +168,17 @@ const GetOrCreateZigGotEntryResult = struct { }; pub fn getOrCreateZigGotEntry(symbol: *Symbol, symbol_index: Index, elf_file: *Elf) !GetOrCreateZigGotEntryResult { + assert(!elf_file.isObject()); if (symbol.flags.has_zig_got) return .{ .found_existing = true, .index = symbol.extra(elf_file).?.zig_got }; const index = try elf_file.zig_got.addSymbol(symbol_index, elf_file); return .{ .found_existing = false, .index = index }; } +pub fn createZigGotEntry(symbol: *Symbol, symbol_index: Index, elf_file: *Elf) !void { + if (elf_file.isObject()) return; + _ = try symbol.getOrCreateZigGotEntry(symbol_index, elf_file); +} + pub fn zigGotAddress(symbol: Symbol, elf_file: *Elf) u64 { if (!symbol.flags.has_zig_got) return 0; const extras = symbol.extra(elf_file).?; diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig index bb4d37f9ee..2160e5a773 100644 --- a/src/link/Elf/ZigObject.zig +++ b/src/link/Elf/ZigObject.zig @@ -433,7 +433,6 @@ pub fn updateRelaSectionSizes(self: ZigObject, elf_file: *Elf) void { } pub fn writeRelaSections(self: ZigObject, elf_file: *Elf) !void { - _ = self; const gpa = elf_file.base.allocator; for (&[_]?u16{ @@ -454,18 +453,18 @@ pub fn writeRelaSections(self: ZigObject, elf_file: *Elf) !void { while (true) { for (atom.relocs(elf_file)) |rel| { - relocs.appendAssumeCapacity(switch (rel.r_type()) { - Elf.R_X86_64_ZIG_GOT32 => .{ - .r_offset = rel.r_offset, - .r_addend = rel.r_addend, - .r_info = (@as(u64, @intCast(rel.r_sym())) << 32) | elf.R_X86_64_32, - }, - Elf.R_X86_64_ZIG_GOTPCREL => .{ - .r_offset = rel.r_offset, - .r_addend = rel.r_addend, - .r_info = (@as(u64, @intCast(rel.r_sym())) << 32) | elf.R_X86_64_PC32, - }, - else => rel, + var r_sym = rel.r_sym() & symbol_mask; + if (self.isGlobal(rel.r_sym())) r_sym += @intCast(self.local_esyms.slice().len + 1); + 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, + }; + relocs.appendAssumeCapacity(.{ + .r_offset = rel.r_offset, + .r_addend = rel.r_addend, + .r_info = (@as(u64, @intCast(r_sym)) << 32) | r_type, }); } if (elf_file.atom(atom.prev_index)) |prev| { @@ -486,17 +485,20 @@ pub fn writeRelaSections(self: ZigObject, elf_file: *Elf) !void { } } +pub fn isGlobal(self: ZigObject, index: Symbol.Index) bool { + _ = self; + return index & global_symbol_bit != 0; +} + pub fn symbol(self: *ZigObject, index: Symbol.Index) Symbol.Index { - const is_global = index & global_symbol_bit != 0; const actual_index = index & symbol_mask; - if (is_global) return self.global_symbols.items[actual_index]; + if (self.isGlobal(index)) return self.global_symbols.items[actual_index]; return self.local_symbols.items[actual_index]; } pub fn elfSym(self: *ZigObject, index: Symbol.Index) *elf.Elf64_Sym { - const is_global = index & global_symbol_bit != 0; const actual_index = index & symbol_mask; - if (is_global) return &self.global_esyms.items(.elf_sym)[actual_index]; + if (self.isGlobal(index)) return &self.global_esyms.items(.elf_sym)[actual_index]; return &self.local_esyms.items(.elf_sym)[actual_index]; } |
