Commit 575c29e5c4

Jakub Konka <kubkon@jakubkonka.com>
2023-11-12 12:05:08
elf: set symbol flags such as needs_zig_got in ZigObject
1 parent 412519d
Changed files (6)
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, .{
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;
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() },
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 {
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;
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) {