authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-11-12 12:05:08+01:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-11-12 18:12:41-05:00
log575c29e5c4fe3aac955be407155750b92c0f6ea3
treea1a595273c8833b97ea6fff59bc74d8ef4c58936
parent412519dd49ec2a42d0feb9842545dadaf1c6b68d

elf: set symbol flags such as needs_zig_got in ZigObject


6 files changed, 19 insertions(+), 25 deletions(-)

src/arch/x86_64/CodeGen.zig-2
...@@ -10802,7 +10802,6 @@ fn genCall(self: *Self, info: union(enum) {...@@ -10802,7 +10802,6 @@ fn genCall(self: *Self, info: union(enum) {
10802 if (self.bin_file.cast(link.File.Elf)) |elf_file| {10802 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
10803 const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl);10803 const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl);
10804 const sym = elf_file.symbol(sym_index);10804 const sym = elf_file.symbol(sym_index);
10805 sym.flags.needs_zig_got = true;
10806 if (self.bin_file.options.pic) {10805 if (self.bin_file.options.pic) {
10807 const callee_reg: Register = switch (resolved_cc) {10806 const callee_reg: Register = switch (resolved_cc) {
10808 .SysV => callee: {10807 .SysV => callee: {
...@@ -13690,7 +13689,6 @@ fn genLazySymbolRef(...@@ -13690,7 +13689,6 @@ fn genLazySymbolRef(
13690 const sym_index = elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, lazy_sym) catch |err|13689 const sym_index = elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, lazy_sym) catch |err|
13691 return self.fail("{s} creating lazy symbol", .{@errorName(err)});13690 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
13692 const sym = elf_file.symbol(sym_index);13691 const sym = elf_file.symbol(sym_index);
13693 sym.flags.needs_zig_got = true;
13694 if (self.bin_file.options.pic) {13692 if (self.bin_file.options.pic) {
13695 switch (tag) {13693 switch (tag) {
13696 .lea, .call => try self.genSetReg(reg, Type.usize, .{13694 .lea, .call => try self.genSetReg(reg, Type.usize, .{
src/arch/x86_64/Emit.zig+1-1
...@@ -138,7 +138,7 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -138,7 +138,7 @@ pub fn emitMir(emit: *Emit) Error!void {
138 link.File.Elf.R_X86_64_ZIG_GOT32138 link.File.Elf.R_X86_64_ZIG_GOT32
139 else if (sym.flags.needs_got)139 else if (sym.flags.needs_got)
140 std.elf.R_X86_64_GOT32140 std.elf.R_X86_64_GOT32
141 else if (sym.isTls(elf_file))141 else if (sym.flags.is_tls)
142 std.elf.R_X86_64_TPOFF32142 std.elf.R_X86_64_TPOFF32
143 else143 else
144 std.elf.R_X86_64_32;144 std.elf.R_X86_64_32;
src/arch/x86_64/Lower.zig+1-9
...@@ -332,7 +332,7 @@ fn needsZigGot(sym: bits.Symbol, ctx: *link.File) bool {...@@ -332,7 +332,7 @@ fn needsZigGot(sym: bits.Symbol, ctx: *link.File) bool {
332fn isTls(sym: bits.Symbol, ctx: *link.File) bool {332fn isTls(sym: bits.Symbol, ctx: *link.File) bool {
333 const elf_file = ctx.cast(link.File.Elf).?;333 const elf_file = ctx.cast(link.File.Elf).?;
334 const sym_index = elf_file.zigObjectPtr().?.symbol(sym.sym_index);334 const sym_index = elf_file.zigObjectPtr().?.symbol(sym.sym_index);
335 return elf_file.symbol(sym_index).isTls(elf_file);335 return elf_file.symbol(sym_index).flags.is_tls;
336}336}
337337
338fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) Error!void {338fn 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)...@@ -380,10 +380,6 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
380 });380 });
381 lower.result_insts_len += 1;381 lower.result_insts_len += 1;
382 _ = lower.reloc(.{ .linker_dtpoff = sym });382 _ = lower.reloc(.{ .linker_dtpoff = sym });
383 if (lower.bin_file.cast(link.File.Elf)) |elf_file| {
384 const sym_index = elf_file.zigObjectPtr().?.symbol(sym.sym_index);
385 elf_file.symbol(sym_index).flags.needs_zig_got = false;
386 }
387 emit_mnemonic = .lea;383 emit_mnemonic = .lea;
388 break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{384 break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
389 .base = .{ .reg = .rax },385 .base = .{ .reg = .rax },
...@@ -398,10 +394,6 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)...@@ -398,10 +394,6 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
398 });394 });
399 lower.result_insts_len += 1;395 lower.result_insts_len += 1;
400 _ = lower.reloc(.{ .linker_reloc = sym });396 _ = lower.reloc(.{ .linker_reloc = sym });
401 if (lower.bin_file.cast(link.File.Elf)) |elf_file| {
402 const sym_index = elf_file.zigObjectPtr().?.symbol(sym.sym_index);
403 elf_file.symbol(sym_index).flags.needs_zig_got = false;
404 }
405 emit_mnemonic = .lea;397 emit_mnemonic = .lea;
406 break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{398 break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
407 .base = .{ .reg = ops[0].reg.to64() },399 .base = .{ .reg = ops[0].reg.to64() },
src/codegen.zig-1
...@@ -912,7 +912,6 @@ fn genDeclRef(...@@ -912,7 +912,6 @@ fn genDeclRef(
912 }912 }
913 const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, decl_index);913 const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, decl_index);
914 const sym = elf_file.symbol(sym_index);914 const sym = elf_file.symbol(sym_index);
915 sym.flags.needs_zig_got = true;
916 return GenResult.mcv(.{ .load_symbol = sym.esym_index });915 return GenResult.mcv(.{ .load_symbol = sym.esym_index });
917 } else if (bin_file.cast(link.File.MachO)) |macho_file| {916 } else if (bin_file.cast(link.File.MachO)) |macho_file| {
918 if (is_extern) {917 if (is_extern) {
src/link/Elf/Symbol.zig+5-7
...@@ -51,13 +51,6 @@ pub fn isIFunc(symbol: Symbol, elf_file: *Elf) bool {...@@ -51,13 +51,6 @@ pub fn isIFunc(symbol: Symbol, elf_file: *Elf) bool {
51 return symbol.type(elf_file) == elf.STT_GNU_IFUNC;51 return symbol.type(elf_file) == elf.STT_GNU_IFUNC;
52}52}
5353
54// TODO this check is enough for ZigObject emitted TLS vars but what about those emitted
55// by different backends/compilers?
56pub fn isTls(symbol: Symbol, elf_file: *Elf) bool {
57 if (symbol.file(elf_file) == null) return false;
58 return symbol.type(elf_file) == elf.STT_TLS;
59}
60
61pub fn @"type"(symbol: Symbol, elf_file: *Elf) u4 {54pub fn @"type"(symbol: Symbol, elf_file: *Elf) u4 {
62 const esym = symbol.elfSym(elf_file);55 const esym = symbol.elfSym(elf_file);
63 const file_ptr = symbol.file(elf_file).?;56 const file_ptr = symbol.file(elf_file).?;
...@@ -406,6 +399,11 @@ pub const Flags = packed struct {...@@ -406,6 +399,11 @@ pub const Flags = packed struct {
406 /// Whether the symbol contains .zig.got indirection.399 /// Whether the symbol contains .zig.got indirection.
407 needs_zig_got: bool = false,400 needs_zig_got: bool = false,
408 has_zig_got: bool = false,401 has_zig_got: bool = false,
402
403 /// Whether the symbol is a TLS variable.
404 /// TODO this is really not needed if only we operated on esyms between
405 /// codegen and ZigObject.
406 is_tls: bool = false,
409};407};
410408
411pub const Extra = struct {409pub const Extra = struct {
src/link/Elf/ZigObject.zig+12-5
...@@ -668,7 +668,12 @@ pub fn getOrCreateMetadataForLazySymbol(...@@ -668,7 +668,12 @@ pub fn getOrCreateMetadataForLazySymbol(
668 },668 },
669 };669 };
670 switch (metadata.state.*) {670 switch (metadata.state.*) {
671 .unused => metadata.symbol_index.* = try self.addAtom(elf_file),671 .unused => {
672 const symbol_index = try self.addAtom(elf_file);
673 const sym = elf_file.symbol(symbol_index);
674 sym.flags.needs_zig_got = true;
675 metadata.symbol_index.* = symbol_index;
676 },
672 .pending_flush => return metadata.symbol_index.*,677 .pending_flush => return metadata.symbol_index.*,
673 .flushed => {},678 .flushed => {},
674 }679 }
...@@ -723,17 +728,19 @@ pub fn getOrCreateMetadataForDecl(...@@ -723,17 +728,19 @@ pub fn getOrCreateMetadataForDecl(
723) !Symbol.Index {728) !Symbol.Index {
724 const gop = try self.decls.getOrPut(elf_file.base.allocator, decl_index);729 const gop = try self.decls.getOrPut(elf_file.base.allocator, decl_index);
725 if (!gop.found_existing) {730 if (!gop.found_existing) {
731 const single_threaded = elf_file.base.options.single_threaded;
726 const symbol_index = try self.addAtom(elf_file);732 const symbol_index = try self.addAtom(elf_file);
727 const mod = elf_file.base.options.module.?;733 const mod = elf_file.base.options.module.?;
728 const decl = mod.declPtr(decl_index);734 const decl = mod.declPtr(decl_index);
729 const single_threaded = elf_file.base.options.single_threaded;735 const sym = elf_file.symbol(symbol_index);
730 if (decl.getOwnedVariable(mod)) |variable| {736 if (decl.getOwnedVariable(mod)) |variable| {
731 if (variable.is_threadlocal and !single_threaded) {737 if (variable.is_threadlocal and !single_threaded) {
732 const sym = elf_file.symbol(symbol_index);738 sym.flags.is_tls = true;
733 self.elfSym(sym.esym_index).st_info = elf.STT_TLS;
734 }739 }
735 }740 }
736741 if (!sym.flags.is_tls) {
742 sym.flags.needs_zig_got = true;
743 }
737 gop.value_ptr.* = .{ .symbol_index = symbol_index };744 gop.value_ptr.* = .{ .symbol_index = symbol_index };
738 }745 }
739 return gop.value_ptr.symbol_index;746 return gop.value_ptr.symbol_index;