mirror of
https://github.com/ziglang/zig.git
synced 2024-11-30 09:02:32 +00:00
elf: set symbol flags such as needs_zig_got in ZigObject
This commit is contained in:
parent
412519dd49
commit
575c29e5c4
@ -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, .{
|
||||
|
@ -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;
|
||||
|
@ -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() },
|
||||
|
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user