diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 49e9b598c155ed1da6a7dd54534821db590a1d47..b2f65d646909ed889558e49f65e847a45e4b2618 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -10802,7 +10802,6 @@ 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); - sym.flags.needs_zig_got = true; if (self.bin_file.options.pic) { const callee_reg: Register = switch (resolved_cc) { .SysV => callee: { @@ -13690,7 +13689,6 @@ 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); - 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 baa438b0d1a9703516bf4c1a5242ba9b81bb9365..b3a5316104fbcdecf6228d02c64d4d06d7a38b99 100644 --- a/src/arch/x86_64/Emit.zig +++ b/src/arch/x86_64/Emit.zig @@ -138,7 +138,7 @@ pub fn emitMir(emit: *Emit) Error!void { link.File.Elf.R_X86_64_ZIG_GOT32 else if (sym.flags.needs_got) std.elf.R_X86_64_GOT32 - else if (sym.isTls(elf_file)) + else if (sym.flags.is_tls) std.elf.R_X86_64_TPOFF32 else std.elf.R_X86_64_32; diff --git a/src/arch/x86_64/Lower.zig b/src/arch/x86_64/Lower.zig index c63d1bf264d1b553630adcd376ff687531da0765..085b2932af1c07a2a2fdd2381b1ad996d42d5db0 100644 --- a/src/arch/x86_64/Lower.zig +++ b/src/arch/x86_64/Lower.zig @@ -332,7 +332,7 @@ fn needsZigGot(sym: bits.Symbol, ctx: *link.File) bool { fn isTls(sym: bits.Symbol, ctx: *link.File) bool { const elf_file = ctx.cast(link.File.Elf).?; const sym_index = elf_file.zigObjectPtr().?.symbol(sym.sym_index); - return elf_file.symbol(sym_index).isTls(elf_file); + return elf_file.symbol(sym_index).flags.is_tls; } fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) Error!void { @@ -380,10 +380,6 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) }); lower.result_insts_len += 1; _ = lower.reloc(.{ .linker_dtpoff = sym }); - if (lower.bin_file.cast(link.File.Elf)) |elf_file| { - const sym_index = elf_file.zigObjectPtr().?.symbol(sym.sym_index); - elf_file.symbol(sym_index).flags.needs_zig_got = false; - } emit_mnemonic = .lea; break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{ .base = .{ .reg = .rax }, @@ -398,10 +394,6 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) }); lower.result_insts_len += 1; _ = lower.reloc(.{ .linker_reloc = sym }); - if (lower.bin_file.cast(link.File.Elf)) |elf_file| { - const sym_index = elf_file.zigObjectPtr().?.symbol(sym.sym_index); - elf_file.symbol(sym_index).flags.needs_zig_got = false; - } emit_mnemonic = .lea; break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{ .base = .{ .reg = ops[0].reg.to64() }, diff --git a/src/codegen.zig b/src/codegen.zig index 1df993f78b66221ea50b80d23b49f664c405f170..9420e8ca14e1e65b60aa178994bcc17ba1f328e4 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -912,7 +912,6 @@ fn genDeclRef( } const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, decl_index); const sym = elf_file.symbol(sym_index); - 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 eced2880c6cba7ac6fa7777b0604a8a4ef81c6fc..3dd35dfe63a0a59e0ef534fb9f7ae1413d4bdbb8 100644 --- a/src/link/Elf/Symbol.zig +++ b/src/link/Elf/Symbol.zig @@ -51,13 +51,6 @@ pub fn isIFunc(symbol: Symbol, elf_file: *Elf) bool { return symbol.type(elf_file) == elf.STT_GNU_IFUNC; } -// TODO this check is enough for ZigObject emitted TLS vars but what about those emitted -// by different backends/compilers? -pub fn isTls(symbol: Symbol, elf_file: *Elf) bool { - if (symbol.file(elf_file) == null) return false; - return symbol.type(elf_file) == elf.STT_TLS; -} - pub fn @"type"(symbol: Symbol, elf_file: *Elf) u4 { const esym = symbol.elfSym(elf_file); const file_ptr = symbol.file(elf_file).?; @@ -406,6 +399,11 @@ pub const Flags = packed struct { /// Whether the symbol contains .zig.got indirection. needs_zig_got: bool = false, has_zig_got: bool = false, + + /// Whether the symbol is a TLS variable. + /// TODO this is really not needed if only we operated on esyms between + /// codegen and ZigObject. + is_tls: bool = false, }; pub const Extra = struct { diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig index 22af7f7309f18969fa85b5cf5e03cada877c87eb..28cc8895f7ceefb4b6d2be3820c30d881e73b175 100644 --- a/src/link/Elf/ZigObject.zig +++ b/src/link/Elf/ZigObject.zig @@ -668,7 +668,12 @@ pub fn getOrCreateMetadataForLazySymbol( }, }; switch (metadata.state.*) { - .unused => metadata.symbol_index.* = try self.addAtom(elf_file), + .unused => { + const symbol_index = try self.addAtom(elf_file); + const sym = elf_file.symbol(symbol_index); + sym.flags.needs_zig_got = true; + metadata.symbol_index.* = symbol_index; + }, .pending_flush => return metadata.symbol_index.*, .flushed => {}, } @@ -723,17 +728,19 @@ pub fn getOrCreateMetadataForDecl( ) !Symbol.Index { const gop = try self.decls.getOrPut(elf_file.base.allocator, decl_index); if (!gop.found_existing) { + const single_threaded = elf_file.base.options.single_threaded; const symbol_index = try self.addAtom(elf_file); const mod = elf_file.base.options.module.?; const decl = mod.declPtr(decl_index); - const single_threaded = elf_file.base.options.single_threaded; + const sym = elf_file.symbol(symbol_index); if (decl.getOwnedVariable(mod)) |variable| { if (variable.is_threadlocal and !single_threaded) { - const sym = elf_file.symbol(symbol_index); - self.elfSym(sym.esym_index).st_info = elf.STT_TLS; + sym.flags.is_tls = true; } } - + if (!sym.flags.is_tls) { + sym.flags.needs_zig_got = true; + } gop.value_ptr.* = .{ .symbol_index = symbol_index }; } return gop.value_ptr.symbol_index;