Commit d312dfc1f2
Changed files (5)
src
src/arch/x86_64/CodeGen.zig
@@ -163354,7 +163354,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
},
.runtime_nav_ptr => {
const ty_nav = air_datas[@intFromEnum(inst)].ty_nav;
- const is_threadlocal = ip.getNav(ty_nav.nav).isThreadlocal(ip);
+ const nav = ip.getNav(ty_nav.nav);
+ const is_threadlocal = zcu.comp.config.any_non_single_threaded and nav.isThreadlocal(ip);
if (is_threadlocal) if (cg.mod.pic) {
try cg.spillRegisters(&.{ .rdi, .rax });
} else {
src/arch/x86_64/Emit.zig
@@ -21,7 +21,8 @@ pub const Error = Lower.Error || error{
} || link.File.UpdateDebugInfoError;
pub fn emitMir(emit: *Emit) Error!void {
- const gpa = emit.bin_file.comp.gpa;
+ const comp = emit.bin_file.comp;
+ const gpa = comp.gpa;
try emit.code_offset_mapping.resize(gpa, emit.lower.mir.instructions.len);
emit.relocs.clearRetainingCapacity();
emit.table_relocs.clearRetainingCapacity();
@@ -99,12 +100,10 @@ pub fn emitMir(emit: *Emit) Error!void {
.inst => |inst| .{ .index = inst, .is_extern = false, .type = .inst },
.table => .{ .index = undefined, .is_extern = false, .type = .table },
.nav => |nav| {
- const ip = &emit.pt.zcu.intern_pool;
const sym_index = switch (try codegen.genNavRef(
emit.bin_file,
emit.pt,
emit.lower.src_loc,
- .fromInterned(ip.getNav(nav).typeOf(ip)),
nav,
emit.lower.target.*,
)) {
@@ -118,12 +117,13 @@ pub fn emitMir(emit: *Emit) Error!void {
return error.EmitFail;
},
};
+ const ip = &emit.pt.zcu.intern_pool;
break :target switch (ip.getNav(nav).status) {
.unresolved => unreachable,
.type_resolved => |type_resolved| .{
.index = sym_index,
.is_extern = false,
- .type = if (type_resolved.is_threadlocal) .tlv else .symbol,
+ .type = if (type_resolved.is_threadlocal and comp.config.any_non_single_threaded) .tlv else .symbol,
},
.fully_resolved => |fully_resolved| switch (ip.indexToKey(fully_resolved.val)) {
.@"extern" => |@"extern"| .{
@@ -132,7 +132,7 @@ pub fn emitMir(emit: *Emit) Error!void {
.default => true,
.hidden, .protected => false,
},
- .type = if (@"extern".is_threadlocal) .tlv else .symbol,
+ .type = if (@"extern".is_threadlocal and comp.config.any_non_single_threaded) .tlv else .symbol,
.force_pcrel_direct = switch (@"extern".relocation) {
.any => false,
.pcrel => true,
@@ -141,7 +141,7 @@ pub fn emitMir(emit: *Emit) Error!void {
.variable => |variable| .{
.index = sym_index,
.is_extern = false,
- .type = if (variable.is_threadlocal) .tlv else .symbol,
+ .type = if (variable.is_threadlocal and comp.config.any_non_single_threaded) .tlv else .symbol,
},
else => .{ .index = sym_index, .is_extern = false, .type = .symbol },
},
@@ -292,12 +292,8 @@ pub fn emitMir(emit: *Emit) Error!void {
.branch, .tls => unreachable,
.tlv => {
if (emit.bin_file.cast(.elf)) |elf_file| {
- if (reloc.target.is_extern) {
- // TODO handle extern TLS vars, i.e., emit GD model
- return emit.fail("TODO implement extern {s} reloc for {s}", .{
- @tagName(reloc.target.type), @tagName(emit.bin_file.tag),
- });
- } else if (emit.pic) switch (lowered_inst.encoding.mnemonic) {
+ // TODO handle extern TLS vars, i.e., emit GD model
+ if (emit.pic) switch (lowered_inst.encoding.mnemonic) {
.lea, .mov => {
// Here, we currently assume local dynamic TLS vars, and so
// we emit LD model.
@@ -507,7 +503,6 @@ pub fn emitMir(emit: *Emit) Error!void {
} };
},
.pseudo_dbg_arg_m, .pseudo_dbg_var_m => {
- const ip = &emit.pt.zcu.intern_pool;
const mem = emit.lower.mir.resolveMemoryExtra(mir_inst.data.x.payload).decode();
break :loc .{ .plus = .{
base: {
@@ -519,7 +514,6 @@ pub fn emitMir(emit: *Emit) Error!void {
emit.bin_file,
emit.pt,
emit.lower.src_loc,
- .fromInterned(ip.getNav(nav).typeOf(ip)),
nav,
emit.lower.target.*,
) catch |err| switch (err) {
@@ -803,9 +797,6 @@ fn encodeInst(emit: *Emit, lowered_inst: Instruction, reloc_info: []const RelocI
@tagName(reloc.target.type), @tagName(emit.bin_file.tag),
}),
.tls => if (emit.bin_file.cast(.elf)) |elf_file| {
- if (reloc.target.is_extern) return emit.fail("TODO implement extern {s} reloc for {s}", .{
- @tagName(reloc.target.type), @tagName(emit.bin_file.tag),
- });
const zo = elf_file.zigObjectPtr().?;
const atom = zo.symbol(emit.atom_index).atom(elf_file).?;
const r_type: std.elf.R_X86_64 = if (emit.pic) .TLSLD else unreachable;
@@ -818,9 +809,6 @@ fn encodeInst(emit: *Emit, lowered_inst: Instruction, reloc_info: []const RelocI
@tagName(reloc.target.type), @tagName(emit.bin_file.tag),
}),
.tlv => if (emit.bin_file.cast(.elf)) |elf_file| {
- if (reloc.target.is_extern) return emit.fail("TODO implement extern {s} reloc for {s}", .{
- @tagName(reloc.target.type), @tagName(emit.bin_file.tag),
- });
const zo = elf_file.zigObjectPtr().?;
const atom = zo.symbol(emit.atom_index).atom(elf_file).?;
const r_type: std.elf.R_X86_64 = if (emit.pic) .DTPOFF32 else .TPOFF32;
src/link/Elf/ZigObject.zig
@@ -1142,7 +1142,6 @@ fn getNavShdrIndex(
const gpa = elf_file.base.comp.gpa;
const ptr_size = elf_file.ptrWidthBytes();
const ip = &zcu.intern_pool;
- const any_non_single_threaded = elf_file.base.comp.config.any_non_single_threaded;
const nav_val = zcu.navValue(nav_index);
if (ip.isFunctionType(nav_val.typeOf(zcu).toIntern())) {
if (self.text_index) |symbol_index|
@@ -1162,7 +1161,7 @@ fn getNavShdrIndex(
else => .{ true, false, nav_val.toIntern() },
};
const has_relocs = self.symbol(sym_index).atom(elf_file).?.relocs(elf_file).len > 0;
- if (any_non_single_threaded and is_threadlocal) {
+ if (is_threadlocal and elf_file.base.comp.config.any_non_single_threaded) {
const is_bss = !has_relocs and for (code) |byte| {
if (byte != 0) break false;
} else true;
@@ -1542,7 +1541,7 @@ pub fn updateNav(
nav.name.toSlice(ip),
@"extern".lib_name.toSlice(ip),
);
- if (@"extern".is_threadlocal) self.symbol(sym_index).flags.is_tls = true;
+ if (@"extern".is_threadlocal and elf_file.base.comp.config.any_non_single_threaded) self.symbol(sym_index).flags.is_tls = true;
if (self.dwarf) |*dwarf| dwarf: {
var debug_wip_nav = try dwarf.initWipNav(pt, nav_index, sym_index) orelse break :dwarf;
defer debug_wip_nav.deinit();
src/link/MachO/ZigObject.zig
@@ -881,7 +881,7 @@ pub fn updateNav(
const name = @"extern".name.toSlice(ip);
const lib_name = @"extern".lib_name.toSlice(ip);
const sym_index = try self.getGlobalSymbol(macho_file, name, lib_name);
- if (@"extern".is_threadlocal) self.symbols.items[sym_index].flags.tlv = true;
+ if (@"extern".is_threadlocal and macho_file.base.comp.config.any_non_single_threaded) self.symbols.items[sym_index].flags.tlv = true;
if (self.dwarf) |*dwarf| dwarf: {
var debug_wip_nav = try dwarf.initWipNav(pt, nav_index, sym_index) orelse break :dwarf;
defer debug_wip_nav.deinit();
@@ -1154,7 +1154,6 @@ fn getNavOutputSection(
) error{OutOfMemory}!u8 {
_ = self;
const ip = &zcu.intern_pool;
- const any_non_single_threaded = macho_file.base.comp.config.any_non_single_threaded;
const nav_val = zcu.navValue(nav_index);
if (ip.isFunctionType(nav_val.typeOf(zcu).toIntern())) return macho_file.zig_text_sect_index.?;
const is_const, const is_threadlocal, const nav_init = switch (ip.indexToKey(nav_val.toIntern())) {
@@ -1162,7 +1161,7 @@ fn getNavOutputSection(
.@"extern" => |@"extern"| .{ @"extern".is_const, @"extern".is_threadlocal, .none },
else => .{ true, false, nav_val.toIntern() },
};
- if (any_non_single_threaded and is_threadlocal) {
+ if (is_threadlocal and macho_file.base.comp.config.any_non_single_threaded) {
for (code) |byte| {
if (byte != 0) break;
} else return macho_file.getSectionByName("__DATA", "__thread_bss") orelse try macho_file.addSection(
src/codegen.zig
@@ -955,47 +955,18 @@ pub fn genNavRef(
lf: *link.File,
pt: Zcu.PerThread,
src_loc: Zcu.LazySrcLoc,
- ty: Type,
nav_index: InternPool.Nav.Index,
target: std.Target,
) CodeGenError!GenResult {
const zcu = pt.zcu;
const ip = &zcu.intern_pool;
- log.debug("genNavRef: ty = {}", .{ty.fmt(pt)});
-
- if (!ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) {
- const imm: u64 = switch (@divExact(target.ptrBitWidth(), 8)) {
- 1 => 0xaa,
- 2 => 0xaaaa,
- 4 => 0xaaaaaaaa,
- 8 => 0xaaaaaaaaaaaaaaaa,
- else => unreachable,
- };
- return .{ .mcv = .{ .immediate = imm } };
- }
-
- const comp = lf.comp;
- const gpa = comp.gpa;
-
- // TODO this feels clunky. Perhaps we should check for it in `genTypedValue`?
- if (ty.castPtrToFn(zcu)) |fn_ty| {
- if (zcu.typeToFunc(fn_ty).?.is_generic) {
- return .{ .mcv = .{ .immediate = fn_ty.abiAlignment(zcu).toByteUnits().? } };
- }
- } else if (ty.zigTypeTag(zcu) == .pointer) {
- const elem_ty = ty.elemType2(zcu);
- if (!elem_ty.hasRuntimeBits(zcu)) {
- return .{ .mcv = .{ .immediate = elem_ty.abiAlignment(zcu).toByteUnits().? } };
- }
- }
-
const nav = ip.getNav(nav_index);
+ log.debug("genNavRef({})", .{nav.fqn.fmt(ip)});
+
const lib_name, const linkage, const is_threadlocal = if (nav.getExtern(ip)) |e|
- .{ e.lib_name, e.linkage, e.is_threadlocal and !zcu.navFileScope(nav_index).mod.?.single_threaded }
+ .{ e.lib_name, e.linkage, e.is_threadlocal and zcu.comp.config.any_non_single_threaded }
else
.{ .none, .internal, false };
-
- const name = nav.name;
if (lf.cast(.elf)) |elf_file| {
const zo = elf_file.zigObjectPtr().?;
switch (linkage) {
@@ -1005,7 +976,7 @@ pub fn genNavRef(
return .{ .mcv = .{ .lea_symbol = sym_index } };
},
.strong, .weak => {
- const sym_index = try elf_file.getGlobalSymbol(name.toSlice(ip), lib_name.toSlice(ip));
+ const sym_index = try elf_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip));
switch (linkage) {
.internal => unreachable,
.strong => {},
@@ -1026,7 +997,7 @@ pub fn genNavRef(
return .{ .mcv = .{ .lea_symbol = sym_index } };
},
.strong, .weak => {
- const sym_index = try macho_file.getGlobalSymbol(name.toSlice(ip), lib_name.toSlice(ip));
+ const sym_index = try macho_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip));
switch (linkage) {
.internal => unreachable,
.strong => {},
@@ -1047,8 +1018,8 @@ pub fn genNavRef(
return .{ .mcv = .{ .load_got = sym_index } };
},
.strong, .weak => {
- const global_index = try coff_file.getGlobalSymbol(name.toSlice(ip), lib_name.toSlice(ip));
- try coff_file.need_got_table.put(gpa, global_index, {}); // needs GOT
+ const global_index = try coff_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip));
+ try coff_file.need_got_table.put(zcu.gpa, global_index, {}); // needs GOT
return .{ .mcv = .{ .load_got = link.File.Coff.global_symbol_bit | global_index } };
},
.link_once => unreachable,
@@ -1058,7 +1029,7 @@ pub fn genNavRef(
const atom = p9.getAtom(atom_index);
return .{ .mcv = .{ .memory = atom.getOffsetTableAddress(p9) } };
} else {
- const msg = try ErrorMsg.create(gpa, src_loc, "TODO genNavRef for target {}", .{target});
+ const msg = try ErrorMsg.create(zcu.gpa, src_loc, "TODO genNavRef for target {}", .{target});
return .{ .fail = msg };
}
}
@@ -1071,12 +1042,11 @@ pub fn genTypedValue(
val: Value,
target: std.Target,
) CodeGenError!GenResult {
- const ip = &pt.zcu.intern_pool;
return switch (try lowerValue(pt, val, &target)) {
.none => .{ .mcv = .none },
.undef => .{ .mcv = .undef },
.immediate => |imm| .{ .mcv = .{ .immediate = imm } },
- .lea_nav => |nav| genNavRef(lf, pt, src_loc, .fromInterned(ip.getNav(nav).typeOf(ip)), nav, target),
+ .lea_nav => |nav| genNavRef(lf, pt, src_loc, nav, target),
.lea_uav => |uav| switch (try lf.lowerUav(
pt,
uav.val,