From 80b73e3e8fd5ef8b46152e929153ad45fc6220fd Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sun, 12 Nov 2023 18:10:06 -0500 Subject: [PATCH] x86_64: resolve tlv references on first use and spill to the stack This avoids any arbitrary memory operand possibly clobbering rax and sometime rdi with no warning. --- src/arch/x86_64/CodeGen.zig | 34 +++++++++++++++++++++++++++++----- src/codegen.zig | 3 +++ 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 1faeeced957b..2e3209f64ac3 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -1107,6 +1107,7 @@ fn formatWipMir( .cc = .Unspecified, .src_loc = data.self.src_loc, }; + var first = true; for ((lower.lowerMir(data.inst) catch |err| switch (err) { error.LowerFail => { defer { @@ -1125,7 +1126,11 @@ fn formatWipMir( return; }, else => |e| return e, - }).insts) |lowered_inst| try writer.print(" | {}", .{lowered_inst}); + }).insts) |lowered_inst| { + if (!first) try writer.writeAll("\ndebug(wip_mir): "); + try writer.print(" | {}", .{lowered_inst}); + first = false; + } } fn fmtWipMir(self: *Self, inst: Mir.Inst.Index) std.fmt.Formatter(formatWipMir) { return .{ .data = .{ .self = self, .inst = inst } }; @@ -15798,11 +15803,30 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue { } else mcv: { const ip_index = Air.refToInterned(ref).?; const gop = try self.const_tracking.getOrPut(self.gpa, ip_index); - const mcv = try self.genTypedValue(.{ - .ty = ty, - .val = ip_index.toValue(), + if (!gop.found_existing) gop.value_ptr.* = InstTracking.init(init: { + const const_mcv = try self.genTypedValue(.{ .ty = ty, .val = ip_index.toValue() }); + switch (const_mcv) { + .lea_tlv => |tlv_sym| if (self.bin_file.cast(link.File.Elf)) |_| { + if (self.bin_file.options.pic) { + try self.spillRegisters(&.{ .rdi, .rax }); + } else { + try self.spillRegisters(&.{.rax}); + } + const frame_index = try self.allocFrameIndex(FrameAlloc.init(.{ + .size = 8, + .alignment = .@"8", + })); + try self.genSetMem( + .{ .frame = frame_index }, + 0, + Type.usize, + .{ .lea_symbol = .{ .sym = tlv_sym } }, + ); + break :init .{ .load_frame = .{ .index = frame_index } }; + } else break :init const_mcv, + else => break :init const_mcv, + } }); - if (!gop.found_existing) gop.value_ptr.* = InstTracking.init(mcv); break :mcv gop.value_ptr.short; }; diff --git a/src/codegen.zig b/src/codegen.zig index 9420e8ca14e1..94f1f6ea0eba 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -912,6 +912,9 @@ fn genDeclRef( } const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, decl_index); const sym = elf_file.symbol(sym_index); + if (is_threadlocal) { + return GenResult.mcv(.{ .load_tlv = sym.esym_index }); + } return GenResult.mcv(.{ .load_symbol = sym.esym_index }); } else if (bin_file.cast(link.File.MachO)) |macho_file| { if (is_extern) {