From ccb2afacc00264897cc474befc13f36239c91b03 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 2 Nov 2023 12:46:37 +0100 Subject: [PATCH] elf: postpone creation of .got.zig entry until code emit --- src/arch/x86_64/CodeGen.zig | 5 ++--- src/arch/x86_64/Emit.zig | 10 +++++++--- src/codegen.zig | 2 +- src/link/Elf/Symbol.zig | 7 ++----- src/link/Elf/ZigObject.zig | 2 ++ 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index b65a704351..f842033484 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.createZigGotEntry(sym_index, elf_file); + sym.flags.needs_zig_got = true; if (self.bin_file.options.pic) { const callee_reg: Register = switch (resolved_cc) { .SysV => callee: { @@ -13103,8 +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.createZigGotEntry(sym_index, elf_file); - + sym.flags.needs_zig_got = true; if (self.bin_file.options.pic) { switch (tag) { .lea, .call => try self.genSetReg(reg, Type.usize, .{ diff --git a/src/arch/x86_64/Emit.zig b/src/arch/x86_64/Emit.zig index 36f4b05a6e..c2f7d8c436 100644 --- a/src/arch/x86_64/Emit.zig +++ b/src/arch/x86_64/Emit.zig @@ -86,9 +86,13 @@ pub fn emitMir(emit: *Emit) Error!void { }), .linker_reloc => |data| if (emit.lower.bin_file.cast(link.File.Elf)) |elf_file| { const atom = elf_file.symbol(data.atom_index).atom(elf_file).?; - const sym = elf_file.symbol(elf_file.zigObjectPtr().?.symbol(data.sym_index)); + const sym_index = elf_file.zigObjectPtr().?.symbol(data.sym_index); + const sym = elf_file.symbol(sym_index); + if (sym.flags.needs_zig_got and emit.lower.bin_file.options.effectiveOutputMode() != .Obj) { + _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file); + } if (emit.lower.bin_file.options.pic) { - const r_type: u32 = if (sym.flags.has_zig_got) + const r_type: u32 = if (sym.flags.needs_zig_got) link.File.Elf.R_X86_64_ZIG_GOTPCREL else if (sym.flags.needs_got) std.elf.R_X86_64_GOTPCREL @@ -100,7 +104,7 @@ pub fn emitMir(emit: *Emit) Error!void { .r_addend = -4, }); } else { - const r_type: u32 = if (sym.flags.has_zig_got) + const r_type: u32 = if (sym.flags.needs_zig_got) link.File.Elf.R_X86_64_ZIG_GOT32 else if (sym.flags.needs_got) std.elf.R_X86_64_GOT32 diff --git a/src/codegen.zig b/src/codegen.zig index c5062228de..d2a84ba800 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.createZigGotEntry(sym_index, elf_file); + sym.flags.needs_zig_got = true; 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 957be0d069..b792725df7 100644 --- a/src/link/Elf/Symbol.zig +++ b/src/link/Elf/Symbol.zig @@ -169,16 +169,12 @@ const GetOrCreateZigGotEntryResult = struct { pub fn getOrCreateZigGotEntry(symbol: *Symbol, symbol_index: Index, elf_file: *Elf) !GetOrCreateZigGotEntryResult { assert(!elf_file.isObject()); + assert(symbol.flags.needs_zig_got); 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).?; @@ -385,6 +381,7 @@ pub const Flags = packed struct { has_tlsdesc: bool = false, /// Whether the symbol contains .zig.got indirection. + needs_zig_got: bool = false, has_zig_got: bool = false, }; diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig index 920af93cb2..d65a39d6d2 100644 --- a/src/link/Elf/ZigObject.zig +++ b/src/link/Elf/ZigObject.zig @@ -901,6 +901,7 @@ fn updateDeclCode( errdefer self.freeDeclMetadata(elf_file, sym_index); sym.value = atom_ptr.value; + sym.flags.needs_zig_got = true; esym.st_value = atom_ptr.value; if (!elf_file.isObject()) { @@ -1156,6 +1157,7 @@ fn updateLazySymbol( errdefer self.freeDeclMetadata(elf_file, symbol_index); local_sym.value = atom_ptr.value; + local_sym.flags.needs_zig_got = true; local_esym.st_value = atom_ptr.value; if (!elf_file.isObject()) {