authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-11-02 00:20:56+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-11-04 09:10:23+01:00
log8055f687659de87ce0101cb3e459699b4541a8b7
tree19430e04b1d123a6f8946b8ea0fa88cd7452590b
parente8f522122ac83e94b2fe58aa369917f3686743c5

elf: make sure we never emit .got.zig relocs when linking object files


4 files changed, 28 insertions(+), 20 deletions(-)

src/arch/x86_64/CodeGen.zig+2-2
...@@ -10235,7 +10235,7 @@ fn genCall(self: *Self, info: union(enum) {...@@ -10235,7 +10235,7 @@ fn genCall(self: *Self, info: union(enum) {
10235 if (self.bin_file.cast(link.File.Elf)) |elf_file| {10235 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
10236 const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl);10236 const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl);
10237 const sym = elf_file.symbol(sym_index);10237 const sym = elf_file.symbol(sym_index);
10238 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);10238 try sym.createZigGotEntry(sym_index, elf_file);
10239 if (self.bin_file.options.pic) {10239 if (self.bin_file.options.pic) {
10240 const callee_reg: Register = switch (resolved_cc) {10240 const callee_reg: Register = switch (resolved_cc) {
10241 .SysV => callee: {10241 .SysV => callee: {
...@@ -13103,7 +13103,7 @@ fn genLazySymbolRef(...@@ -13103,7 +13103,7 @@ fn genLazySymbolRef(
13103 const sym_index = elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, lazy_sym) catch |err|13103 const sym_index = elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, lazy_sym) catch |err|
13104 return self.fail("{s} creating lazy symbol", .{@errorName(err)});13104 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
13105 const sym = elf_file.symbol(sym_index);13105 const sym = elf_file.symbol(sym_index);
13106 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);13106 try sym.createZigGotEntry(sym_index, elf_file);
1310713107
13108 if (self.bin_file.options.pic) {13108 if (self.bin_file.options.pic) {
13109 switch (tag) {13109 switch (tag) {
src/codegen.zig+1-1
...@@ -909,7 +909,7 @@ fn genDeclRef(...@@ -909,7 +909,7 @@ fn genDeclRef(
909 }909 }
910 const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, decl_index);910 const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, decl_index);
911 const sym = elf_file.symbol(sym_index);911 const sym = elf_file.symbol(sym_index);
912 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);912 try sym.createZigGotEntry(sym_index, elf_file);
913 return GenResult.mcv(.{ .load_symbol = sym.esym_index });913 return GenResult.mcv(.{ .load_symbol = sym.esym_index });
914 } else if (bin_file.cast(link.File.MachO)) |macho_file| {914 } else if (bin_file.cast(link.File.MachO)) |macho_file| {
915 if (is_extern) {915 if (is_extern) {
src/link/Elf/Symbol.zig+6
...@@ -168,11 +168,17 @@ const GetOrCreateZigGotEntryResult = struct {...@@ -168,11 +168,17 @@ const GetOrCreateZigGotEntryResult = struct {
168};168};
169169
170pub fn getOrCreateZigGotEntry(symbol: *Symbol, symbol_index: Index, elf_file: *Elf) !GetOrCreateZigGotEntryResult {170pub fn getOrCreateZigGotEntry(symbol: *Symbol, symbol_index: Index, elf_file: *Elf) !GetOrCreateZigGotEntryResult {
171 assert(!elf_file.isObject());
171 if (symbol.flags.has_zig_got) return .{ .found_existing = true, .index = symbol.extra(elf_file).?.zig_got };172 if (symbol.flags.has_zig_got) return .{ .found_existing = true, .index = symbol.extra(elf_file).?.zig_got };
172 const index = try elf_file.zig_got.addSymbol(symbol_index, elf_file);173 const index = try elf_file.zig_got.addSymbol(symbol_index, elf_file);
173 return .{ .found_existing = false, .index = index };174 return .{ .found_existing = false, .index = index };
174}175}
175176
177pub fn createZigGotEntry(symbol: *Symbol, symbol_index: Index, elf_file: *Elf) !void {
178 if (elf_file.isObject()) return;
179 _ = try symbol.getOrCreateZigGotEntry(symbol_index, elf_file);
180}
181
176pub fn zigGotAddress(symbol: Symbol, elf_file: *Elf) u64 {182pub fn zigGotAddress(symbol: Symbol, elf_file: *Elf) u64 {
177 if (!symbol.flags.has_zig_got) return 0;183 if (!symbol.flags.has_zig_got) return 0;
178 const extras = symbol.extra(elf_file).?;184 const extras = symbol.extra(elf_file).?;
src/link/Elf/ZigObject.zig+19-17
...@@ -433,7 +433,6 @@ pub fn updateRelaSectionSizes(self: ZigObject, elf_file: *Elf) void {...@@ -433,7 +433,6 @@ pub fn updateRelaSectionSizes(self: ZigObject, elf_file: *Elf) void {
433}433}
434434
435pub fn writeRelaSections(self: ZigObject, elf_file: *Elf) !void {435pub fn writeRelaSections(self: ZigObject, elf_file: *Elf) !void {
436 _ = self;
437 const gpa = elf_file.base.allocator;436 const gpa = elf_file.base.allocator;
438437
439 for (&[_]?u16{438 for (&[_]?u16{
...@@ -454,18 +453,18 @@ pub fn writeRelaSections(self: ZigObject, elf_file: *Elf) !void {...@@ -454,18 +453,18 @@ pub fn writeRelaSections(self: ZigObject, elf_file: *Elf) !void {
454453
455 while (true) {454 while (true) {
456 for (atom.relocs(elf_file)) |rel| {455 for (atom.relocs(elf_file)) |rel| {
457 relocs.appendAssumeCapacity(switch (rel.r_type()) {456 var r_sym = rel.r_sym() & symbol_mask;
458 Elf.R_X86_64_ZIG_GOT32 => .{457 if (self.isGlobal(rel.r_sym())) r_sym += @intCast(self.local_esyms.slice().len + 1);
459 .r_offset = rel.r_offset,458 const r_type = switch (rel.r_type()) {
460 .r_addend = rel.r_addend,459 Elf.R_X86_64_ZIG_GOT32,
461 .r_info = (@as(u64, @intCast(rel.r_sym())) << 32) | elf.R_X86_64_32,460 Elf.R_X86_64_ZIG_GOTPCREL,
462 },461 => unreachable, // Sanity check if we accidentally emitted those.
463 Elf.R_X86_64_ZIG_GOTPCREL => .{462 else => |r_type| r_type,
464 .r_offset = rel.r_offset,463 };
465 .r_addend = rel.r_addend,464 relocs.appendAssumeCapacity(.{
466 .r_info = (@as(u64, @intCast(rel.r_sym())) << 32) | elf.R_X86_64_PC32,465 .r_offset = rel.r_offset,
467 },466 .r_addend = rel.r_addend,
468 else => rel,467 .r_info = (@as(u64, @intCast(r_sym)) << 32) | r_type,
469 });468 });
470 }469 }
471 if (elf_file.atom(atom.prev_index)) |prev| {470 if (elf_file.atom(atom.prev_index)) |prev| {
...@@ -486,17 +485,20 @@ pub fn writeRelaSections(self: ZigObject, elf_file: *Elf) !void {...@@ -486,17 +485,20 @@ pub fn writeRelaSections(self: ZigObject, elf_file: *Elf) !void {
486 }485 }
487}486}
488487
488pub fn isGlobal(self: ZigObject, index: Symbol.Index) bool {
489 _ = self;
490 return index & global_symbol_bit != 0;
491}
492
489pub fn symbol(self: *ZigObject, index: Symbol.Index) Symbol.Index {493pub fn symbol(self: *ZigObject, index: Symbol.Index) Symbol.Index {
490 const is_global = index & global_symbol_bit != 0;
491 const actual_index = index & symbol_mask;494 const actual_index = index & symbol_mask;
492 if (is_global) return self.global_symbols.items[actual_index];495 if (self.isGlobal(index)) return self.global_symbols.items[actual_index];
493 return self.local_symbols.items[actual_index];496 return self.local_symbols.items[actual_index];
494}497}
495498
496pub fn elfSym(self: *ZigObject, index: Symbol.Index) *elf.Elf64_Sym {499pub fn elfSym(self: *ZigObject, index: Symbol.Index) *elf.Elf64_Sym {
497 const is_global = index & global_symbol_bit != 0;
498 const actual_index = index & symbol_mask;500 const actual_index = index & symbol_mask;
499 if (is_global) return &self.global_esyms.items(.elf_sym)[actual_index];501 if (self.isGlobal(index)) return &self.global_esyms.items(.elf_sym)[actual_index];
500 return &self.local_esyms.items(.elf_sym)[actual_index];502 return &self.local_esyms.items(.elf_sym)[actual_index];
501}503}
502504