From a6a10d9c2b096e1c5cb7bf29273d64e7285b5f94 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 25 Oct 2023 16:49:56 +0200 Subject: x86_64: do not hardcode memory passed by Elf linker --- src/codegen.zig | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) (limited to 'src/codegen.zig') diff --git a/src/codegen.zig b/src/codegen.zig index 051c2b33b3..d60e820dda 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -791,13 +791,11 @@ fn lowerDeclRef( /// Helper struct to denote that the value is in memory but requires a linker relocation fixup: /// * got - the value is referenced indirectly via GOT entry index (the linker emits a got-type reloc) -/// * extern_got - pointer to extern variable referenced via GOT /// * direct - the value is referenced directly via symbol index index (the linker emits a displacement reloc) /// * import - the value is referenced indirectly via import entry index (the linker emits an import-type reloc) pub const LinkerLoad = struct { type: enum { got, - extern_got, direct, import, }, @@ -827,8 +825,10 @@ pub const GenResult = union(enum) { load_got: u32, /// Direct by-address reference to memory location. memory: u64, - /// Pointer to extern variable via GOT. - load_extern_got: u32, + /// Reference to memory location but deferred until linker allocated the Decl in memory. + /// Traditionally, this corresponds to emitting a relocation in a relocatable object file. + load_memory: u32, + lea_memory: u32, }; fn mcv(val: MCValue) GenResult { @@ -903,16 +903,13 @@ fn genDeclRef( mod.intern_pool.stringToSliceUnwrap(ov.lib_name) else null; - return GenResult.mcv(.{ .load_extern_got = try elf_file.getGlobalSymbol(name, lib_name) }); + const sym_index = try elf_file.getGlobalSymbol(name, lib_name); + return GenResult.mcv(.{ .lea_memory = sym_index }); } const sym_index = try elf_file.getOrCreateMetadataForDecl(decl_index); const sym = elf_file.symbol(sym_index); _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file); - if (bin_file.options.pic) { - return GenResult.mcv(.{ .load_got = sym.esym_index }); - } else { - return GenResult.mcv(.{ .memory = sym.zigGotAddress(elf_file) }); - } + return GenResult.mcv(.{ .lea_memory = sym.esym_index }); } else if (bin_file.cast(link.File.MachO)) |macho_file| { const atom_index = try macho_file.getOrCreateAtomForDecl(decl_index); const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?; @@ -948,11 +945,7 @@ fn genUnnamedConst( }; if (bin_file.cast(link.File.Elf)) |elf_file| { const local = elf_file.symbol(local_sym_index); - if (bin_file.options.pic) { - return GenResult.mcv(.{ .load_direct = local.esym_index }); - } else { - return GenResult.mcv(.{ .memory = local.value }); - } + return GenResult.mcv(.{ .load_memory = local.esym_index }); } else if (bin_file.cast(link.File.MachO)) |_| { return GenResult.mcv(.{ .load_direct = local_sym_index }); } else if (bin_file.cast(link.File.Coff)) |_| { -- cgit v1.2.3 From 9a1fbb27059ec59b2e6f61c713b9c3120125a3da Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 26 Oct 2023 22:57:14 +0200 Subject: x86_64: rename load/lea_memory to load/lea_symbol --- src/arch/aarch64/CodeGen.zig | 2 +- src/arch/arm/CodeGen.zig | 2 +- src/arch/riscv64/CodeGen.zig | 2 +- src/arch/sparc64/CodeGen.zig | 2 +- src/arch/x86_64/CodeGen.zig | 148 +++++++++++++++++++++---------------------- src/codegen.zig | 10 +-- 6 files changed, 83 insertions(+), 83 deletions(-) (limited to 'src/codegen.zig') diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index 4f7545da32..0b1ac0752f 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/src/arch/aarch64/CodeGen.zig @@ -6176,7 +6176,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue { .memory => |addr| .{ .memory = addr }, .load_got => |sym_index| .{ .linker_load = .{ .type = .got, .sym_index = sym_index } }, .load_direct => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } }, - .load_memory, .lea_memory, .load_tlv => unreachable, // TODO + .load_symbol, .lea_symbol, .load_tlv => unreachable, // TODO }, .fail => |msg| { self.err_msg = msg; diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig index 576afd5fed..2146f92de1 100644 --- a/src/arch/arm/CodeGen.zig +++ b/src/arch/arm/CodeGen.zig @@ -6135,7 +6135,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue { .mcv => |mcv| switch (mcv) { .none => .none, .undef => .undef, - .load_got, .load_memory, .lea_memory, .load_direct, .load_tlv => unreachable, // TODO + .load_got, .load_symbol, .lea_symbol, .load_direct, .load_tlv => unreachable, // TODO .immediate => |imm| .{ .immediate = @as(u32, @truncate(imm)) }, .memory => |addr| .{ .memory = addr }, }, diff --git a/src/arch/riscv64/CodeGen.zig b/src/arch/riscv64/CodeGen.zig index 701b0fdf8a..9b61166d6e 100644 --- a/src/arch/riscv64/CodeGen.zig +++ b/src/arch/riscv64/CodeGen.zig @@ -2591,7 +2591,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { .mcv => |mcv| switch (mcv) { .none => .none, .undef => .undef, - .load_got, .load_memory, .lea_memory, .load_direct, .load_tlv => unreachable, // TODO + .load_got, .load_symbol, .lea_symbol, .load_direct, .load_tlv => unreachable, // TODO .immediate => |imm| .{ .immediate = imm }, .memory => |addr| .{ .memory = addr }, }, diff --git a/src/arch/sparc64/CodeGen.zig b/src/arch/sparc64/CodeGen.zig index fc901210c3..2e20fbf5cf 100644 --- a/src/arch/sparc64/CodeGen.zig +++ b/src/arch/sparc64/CodeGen.zig @@ -4137,7 +4137,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { .mcv => |mcv| switch (mcv) { .none => .none, .undef => .undef, - .load_got, .load_memory, .lea_memory, .load_direct, .load_tlv => unreachable, // TODO + .load_got, .load_symbol, .lea_symbol, .load_direct, .load_tlv => unreachable, // TODO .immediate => |imm| .{ .immediate = imm }, .memory => |addr| .{ .memory = addr }, }, diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 19bfef70bb..edf8af098e 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -195,9 +195,9 @@ pub const MCValue = union(enum) { memory: u64, /// The value is in memory at an address not-yet-allocated by the linker. /// This traditionally corresponds to a relocation emitted in a relocatable object file. - load_memory: u32, + load_symbol: u32, /// The address of the memory location not-yet-allocated by the linker. - lea_memory: u32, + lea_symbol: u32, /// The value is in memory at a constant offset from the address in a register. indirect: RegisterOffset, /// The value is in memory. @@ -298,7 +298,7 @@ pub const MCValue = union(enum) { .register_pair, .register_offset, .register_overflow, - .lea_memory, + .lea_symbol, .lea_direct, .lea_got, .lea_tlv, @@ -315,7 +315,7 @@ pub const MCValue = union(enum) { .load_got => |sym_index| .{ .lea_got = sym_index }, .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, .load_frame => |frame_addr| .{ .lea_frame = frame_addr }, - .load_memory => |sym_index| .{ .lea_memory = sym_index }, + .load_symbol => |sym_index| .{ .lea_symbol = sym_index }, }; } @@ -334,7 +334,7 @@ pub const MCValue = union(enum) { .load_got, .load_tlv, .load_frame, - .load_memory, + .load_symbol, .reserved_frame, .air_ref, => unreachable, // not dereferenceable @@ -345,7 +345,7 @@ pub const MCValue = union(enum) { .lea_got => |sym_index| .{ .load_got = sym_index }, .lea_tlv => |sym_index| .{ .load_tlv = sym_index }, .lea_frame => |frame_addr| .{ .load_frame = frame_addr }, - .lea_memory => |sym_index| .{ .load_memory = sym_index }, + .lea_symbol => |sym_index| .{ .load_symbol = sym_index }, }; } @@ -370,8 +370,8 @@ pub const MCValue = union(enum) { .load_tlv, .lea_tlv, .load_frame, - .load_memory, - .lea_memory, + .load_symbol, + .lea_symbol, => switch (off) { 0 => mcv, else => unreachable, // not offsettable @@ -408,8 +408,8 @@ pub const MCValue = union(enum) { .lea_frame, .reserved_frame, .air_ref, - .load_memory, - .lea_memory, + .load_symbol, + .lea_symbol, => unreachable, .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr| Memory.sib(ptr_size, .{ .base = .{ .reg = .ds }, .disp = small_addr }) @@ -453,8 +453,8 @@ pub const MCValue = union(enum) { .lea_frame => |pl| try writer.print("{} + 0x{x}", .{ pl.index, pl.off }), .reserved_frame => |pl| try writer.print("(dead:{})", .{pl}), .air_ref => |pl| try writer.print("(air:0x{x})", .{@intFromEnum(pl)}), - .load_memory => |pl| try writer.print("[mem:{d}]", .{pl}), - .lea_memory => |pl| try writer.print("mem:{d}", .{pl}), + .load_symbol => |pl| try writer.print("[mem:{d}]", .{pl}), + .lea_symbol => |pl| try writer.print("mem:{d}", .{pl}), } } }; @@ -480,8 +480,8 @@ const InstTracking = struct { .lea_tlv, .load_frame, .lea_frame, - .load_memory, - .lea_memory, + .load_symbol, + .lea_symbol, => result, .dead, .reserved_frame, @@ -541,8 +541,8 @@ const InstTracking = struct { .lea_tlv, .load_frame, .lea_frame, - .load_memory, - .lea_memory, + .load_symbol, + .lea_symbol, => self.long, .dead, .eflags, @@ -577,8 +577,8 @@ const InstTracking = struct { .load_tlv, .lea_tlv, .lea_frame, - .load_memory, - .lea_memory, + .load_symbol, + .lea_symbol, => assert(std.meta.eql(self.long, target.long)), .load_frame, .reserved_frame, @@ -4731,12 +4731,12 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { Memory.sib(.qword, .{ .base = .{ .frame = frame_addr.index }, .disp = frame_addr.off }), ), .memory, - .load_memory, + .load_symbol, .load_direct, .load_got, .load_tlv, => try self.genSetReg(addr_reg, Type.usize, array.address()), - .lea_memory, .lea_direct, .lea_tlv => unreachable, + .lea_symbol, .lea_direct, .lea_tlv => unreachable, else => return self.fail("TODO implement array_elem_val when array is {}", .{array}), } @@ -6329,7 +6329,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro .immediate, .register, .register_offset, - .lea_memory, + .lea_symbol, .lea_direct, .lea_got, .lea_tlv, @@ -6337,7 +6337,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro => try self.genCopy(dst_ty, dst_mcv, ptr_mcv.deref()), .memory, .indirect, - .load_memory, + .load_symbol, .load_direct, .load_got, .load_tlv, @@ -6478,7 +6478,7 @@ fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerErr .immediate, .register, .register_offset, - .lea_memory, + .lea_symbol, .lea_direct, .lea_got, .lea_tlv, @@ -6486,7 +6486,7 @@ fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerErr => try self.genCopy(src_ty, ptr_mcv.deref(), src_mcv), .memory, .indirect, - .load_memory, + .load_symbol, .load_direct, .load_got, .load_tlv, @@ -6919,11 +6919,11 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MC .lea_frame, .reserved_frame, .air_ref, - .lea_memory, + .lea_symbol, => unreachable, // unmodifiable destination .register => |dst_reg| try self.asmRegister(mir_tag, registerAlias(dst_reg, abi_size)), .register_pair => unreachable, // unimplemented - .memory, .load_memory, .load_got, .load_direct, .load_tlv => { + .memory, .load_symbol, .load_got, .load_direct, .load_tlv => { const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); defer self.register_manager.unlockReg(addr_reg_lock); @@ -7975,8 +7975,8 @@ fn genBinOp( .immediate, .eflags, .register_offset, - .load_memory, - .lea_memory, + .load_symbol, + .lea_symbol, .load_direct, .lea_direct, .load_got, @@ -8033,8 +8033,8 @@ fn genBinOp( .register_pair, .register_offset, .register_overflow, - .load_memory, - .lea_memory, + .load_symbol, + .lea_symbol, .load_direct, .lea_direct, .load_got, @@ -9168,7 +9168,7 @@ fn genBinOpMir( .lea_got, .lea_tlv, .lea_frame, - .lea_memory, + .lea_symbol, .reserved_frame, .air_ref, => unreachable, // unmodifiable destination @@ -9251,8 +9251,8 @@ fn genBinOpMir( .register_offset, .memory, .indirect, - .load_memory, - .lea_memory, + .load_symbol, + .lea_symbol, .load_direct, .lea_direct, .load_got, @@ -9287,7 +9287,7 @@ fn genBinOpMir( switch (src_mcv) { .eflags, .register_offset, - .lea_memory, + .lea_symbol, .lea_direct, .lea_got, .lea_tlv, @@ -9303,7 +9303,7 @@ fn genBinOpMir( ); }, .memory, - .load_memory, + .load_symbol, .load_direct, .load_got, .load_tlv, @@ -9326,13 +9326,13 @@ fn genBinOpMir( } } }, - .memory, .indirect, .load_memory, .load_got, .load_direct, .load_tlv, .load_frame => { + .memory, .indirect, .load_symbol, .load_got, .load_direct, .load_tlv, .load_frame => { const OpInfo = ?struct { addr_reg: Register, addr_lock: RegisterLock }; const limb_abi_size: u32 = @min(abi_size, 8); const dst_info: OpInfo = switch (dst_mcv) { else => unreachable, - .memory, .load_memory, .load_got, .load_direct, .load_tlv => dst: { + .memory, .load_symbol, .load_got, .load_direct, .load_tlv => dst: { const dst_addr_reg = (try self.register_manager.allocReg(null, abi.RegisterClass.gp)).to64(); const dst_addr_lock = self.register_manager.lockRegAssumeUnused(dst_addr_reg); @@ -9369,14 +9369,14 @@ fn genBinOpMir( .lea_tlv, .load_frame, .lea_frame, - .lea_memory, + .lea_symbol, => null, - .memory, .load_memory, .load_got, .load_direct, .load_tlv => src: { + .memory, .load_symbol, .load_got, .load_direct, .load_tlv => src: { switch (resolved_src_mcv) { .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr))) != null and math.cast(i32, @as(i64, @bitCast(addr)) + abi_size - limb_abi_size) != null) break :src null, - .load_memory, .load_got, .load_direct, .load_tlv => {}, + .load_symbol, .load_got, .load_direct, .load_tlv => {}, else => unreachable, } @@ -9418,7 +9418,7 @@ fn genBinOpMir( Memory.PtrSize.fromSize(limb_abi_size), switch (dst_mcv) { .memory, - .load_memory, + .load_symbol, .load_got, .load_direct, .load_tlv, @@ -9500,8 +9500,8 @@ fn genBinOpMir( .eflags, .memory, .indirect, - .load_memory, - .lea_memory, + .load_symbol, + .lea_symbol, .load_direct, .lea_direct, .load_got, @@ -9519,7 +9519,7 @@ fn genBinOpMir( }, .eflags, .register_offset, - .lea_memory, + .lea_symbol, .lea_direct, .lea_got, .lea_tlv, @@ -9570,7 +9570,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M .eflags, .register_offset, .register_overflow, - .lea_memory, + .lea_symbol, .lea_direct, .lea_got, .lea_tlv, @@ -9617,8 +9617,8 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M }, .register_offset, .eflags, - .load_memory, - .lea_memory, + .load_symbol, + .lea_symbol, .load_direct, .lea_direct, .load_got, @@ -9661,7 +9661,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M } }, .register_pair => unreachable, // unimplemented - .memory, .indirect, .load_memory, .load_direct, .load_got, .load_tlv, .load_frame => { + .memory, .indirect, .load_symbol, .load_direct, .load_got, .load_tlv, .load_frame => { const tmp_reg = try self.copyToTmpRegister(dst_ty, dst_mcv); const tmp_mcv = MCValue{ .register = tmp_reg }; const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); @@ -9761,7 +9761,7 @@ fn genVarDbgInfo( // .offset = -off, //} }, .memory => |address| .{ .memory = address }, - .load_memory => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } }, // TODO + .load_symbol => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } }, // TODO .load_got => |sym_index| .{ .linker_load = .{ .type = .got, .sym_index = sym_index } }, .load_direct => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } }, .immediate => |x| .{ .immediate = x }, @@ -10013,7 +10013,7 @@ fn genCall(self: *Self, info: union(enum) { const sym = elf_file.symbol(sym_index); _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file); if (self.bin_file.options.pic) { - try self.genSetReg(.rax, Type.usize, .{ .lea_memory = sym.esym_index }); + try self.genSetReg(.rax, Type.usize, .{ .lea_symbol = sym.esym_index }); try self.asmRegister(.{ ._, .call }, .rax); } else { _ = try self.addInst(.{ @@ -10245,12 +10245,12 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { .lea_got, .lea_tlv, .lea_frame, - .lea_memory, + .lea_symbol, .reserved_frame, .air_ref, => unreachable, .register_pair, .load_frame => null, - .memory, .load_memory, .load_got, .load_direct, .load_tlv => dst: { + .memory, .load_symbol, .load_got, .load_direct, .load_tlv => dst: { switch (resolved_dst_mcv) { .memory => |addr| if (math.cast( i32, @@ -10259,7 +10259,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { i32, @as(i64, @bitCast(addr)) + abi_size - 8, ) != null) break :dst null, - .load_memory, .load_got, .load_direct, .load_tlv => {}, + .load_symbol, .load_got, .load_direct, .load_tlv => {}, else => unreachable, } @@ -10300,7 +10300,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { .register_offset, .register_overflow, .indirect, - .lea_memory, + .lea_symbol, .lea_direct, .lea_got, .lea_tlv, @@ -10309,7 +10309,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { .air_ref, => unreachable, .register_pair, .load_frame => null, - .memory, .load_memory, .load_got, .load_direct, .load_tlv => src: { + .memory, .load_symbol, .load_got, .load_direct, .load_tlv => src: { switch (resolved_src_mcv) { .memory => |addr| if (math.cast( i32, @@ -10318,7 +10318,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { i32, @as(i64, @bitCast(addr)) + abi_size - 8, ) != null) break :src null, - .load_memory, .load_got, .load_direct, .load_tlv => {}, + .load_symbol, .load_got, .load_direct, .load_tlv => {}, else => unreachable, } @@ -10743,7 +10743,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC .lea_got, .lea_tlv, .lea_frame, - .lea_memory, + .lea_symbol, .reserved_frame, .air_ref, => unreachable, @@ -10767,7 +10767,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC }, .memory, - .load_memory, + .load_symbol, .load_got, .load_direct, .load_tlv, @@ -11365,7 +11365,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |_| break :arg input_mcv, .indirect, .load_frame => break :arg input_mcv, - .load_memory, .load_direct, .load_got, .load_tlv => {}, + .load_symbol, .load_direct, .load_got, .load_tlv => {}, else => { const temp_mcv = try self.allocTempRegOrMem(ty, false); try self.genCopy(ty, temp_mcv, input_mcv); @@ -11627,8 +11627,8 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { .{ .reg = try self.copyToTmpRegister(Type.usize, .{ .lea_got = sym_index }) } else return self.fail("invalid modifier: '{s}'", .{modifier}), - .lea_memory => |sym_index| if (mem.eql(u8, modifier, "P")) - .{ .reg = try self.copyToTmpRegister(Type.usize, .{ .lea_memory = sym_index }) } + .lea_symbol => |sym_index| if (mem.eql(u8, modifier, "P")) + .{ .reg = try self.copyToTmpRegister(Type.usize, .{ .lea_symbol = sym_index }) } else return self.fail("invalid modifier: '{s}'", .{modifier}), else => return self.fail("invalid constraint: '{s}'", .{op_str}), @@ -12186,7 +12186,7 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError .lea_got, .lea_tlv, .lea_frame, - .lea_memory, + .lea_symbol, .reserved_frame, .air_ref, => unreachable, // unmodifiable destination @@ -12242,7 +12242,7 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError class_ty, .{ .register = src_regs[dst_reg_i] }, ), - .load_memory => { + .load_symbol => { const addr_reg = try self.copyToTmpRegister(Type.usize, src_mcv.address()); const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); defer self.register_manager.unlockReg(addr_lock); @@ -12263,11 +12263,11 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError } }, .indirect => |reg_off| try self.genSetMem(.{ .reg = reg_off.reg }, reg_off.off, ty, src_mcv), - .memory, .load_memory, .load_direct, .load_got, .load_tlv => { + .memory, .load_symbol, .load_direct, .load_got, .load_tlv => { switch (dst_mcv) { .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr| return self.genSetMem(.{ .reg = .ds }, small_addr, ty, src_mcv), - .load_memory, .load_direct, .load_got, .load_tlv => {}, + .load_symbol, .load_direct, .load_got, .load_tlv => {}, else => unreachable, } @@ -12443,7 +12443,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr else => unreachable, }, )), - .memory, .load_memory, .load_direct, .load_got, .load_tlv => { + .memory, .load_symbol, .load_direct, .load_got, .load_tlv => { switch (src_mcv) { .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr| return (try self.moveStrategy( @@ -12473,7 +12473,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr .segment, .mmx => unreachable, .x87, .sse => {}, }, - .load_memory, .load_got, .load_tlv => {}, + .load_symbol, .load_got, .load_tlv => {}, else => unreachable, } @@ -12487,7 +12487,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .{ .reg = addr_reg } }), ); }, - .lea_memory, .lea_direct, .lea_got => |sym_index| { + .lea_symbol, .lea_direct, .lea_got => |sym_index| { const atom_index = try self.owner.getSymbolIndex(self); if (self.bin_file.cast(link.File.Elf)) |elf_file| { const sym = elf_file.symbol(elf_file.zigModulePtr().symbol(sym_index)); @@ -12675,8 +12675,8 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal .lea_tlv, .load_frame, .lea_frame, - .load_memory, - .lea_memory, + .load_symbol, + .lea_symbol, => switch (abi_size) { 0 => {}, 1, 2, 4, 8 => { @@ -12767,8 +12767,8 @@ fn genLazySymbolRef( if (self.bin_file.options.pic) { switch (tag) { - .lea, .call => try self.genSetReg(reg, Type.usize, .{ .lea_memory = sym.esym_index }), - .mov => try self.genSetReg(reg, Type.usize, .{ .load_memory = sym.esym_index }), + .lea, .call => try self.genSetReg(reg, Type.usize, .{ .lea_symbol = sym.esym_index }), + .mov => try self.genSetReg(reg, Type.usize, .{ .load_symbol = sym.esym_index }), else => unreachable, } switch (tag) { @@ -14742,8 +14742,8 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue { .undef => .undef, .immediate => |imm| .{ .immediate = imm }, .memory => |addr| .{ .memory = addr }, - .load_memory => |sym_index| .{ .load_memory = sym_index }, - .lea_memory => |sym_index| .{ .lea_memory = sym_index }, + .load_symbol => |sym_index| .{ .load_symbol = sym_index }, + .lea_symbol => |sym_index| .{ .lea_symbol = sym_index }, .load_direct => |sym_index| .{ .load_direct = sym_index }, .load_got => |sym_index| .{ .lea_got = sym_index }, .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, diff --git a/src/codegen.zig b/src/codegen.zig index d60e820dda..e6ac1ee2e1 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -827,8 +827,8 @@ pub const GenResult = union(enum) { memory: u64, /// Reference to memory location but deferred until linker allocated the Decl in memory. /// Traditionally, this corresponds to emitting a relocation in a relocatable object file. - load_memory: u32, - lea_memory: u32, + load_symbol: u32, + lea_symbol: u32, }; fn mcv(val: MCValue) GenResult { @@ -904,12 +904,12 @@ fn genDeclRef( else null; const sym_index = try elf_file.getGlobalSymbol(name, lib_name); - return GenResult.mcv(.{ .lea_memory = sym_index }); + return GenResult.mcv(.{ .lea_symbol = sym_index }); } const sym_index = try elf_file.getOrCreateMetadataForDecl(decl_index); const sym = elf_file.symbol(sym_index); _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file); - return GenResult.mcv(.{ .lea_memory = sym.esym_index }); + return GenResult.mcv(.{ .lea_symbol = sym.esym_index }); } else if (bin_file.cast(link.File.MachO)) |macho_file| { const atom_index = try macho_file.getOrCreateAtomForDecl(decl_index); const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?; @@ -945,7 +945,7 @@ fn genUnnamedConst( }; if (bin_file.cast(link.File.Elf)) |elf_file| { const local = elf_file.symbol(local_sym_index); - return GenResult.mcv(.{ .load_memory = local.esym_index }); + return GenResult.mcv(.{ .load_symbol = local.esym_index }); } else if (bin_file.cast(link.File.MachO)) |_| { return GenResult.mcv(.{ .load_direct = local_sym_index }); } else if (bin_file.cast(link.File.Coff)) |_| { -- cgit v1.2.3 From 0d00b7c585f0e3a20ace71105f562bd7bdd14489 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 27 Oct 2023 00:08:31 +0200 Subject: elf: set needs_got on generated extern vars --- src/arch/x86_64/Emit.zig | 2 +- src/codegen.zig | 1 + src/link/Elf.zig | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src/codegen.zig') diff --git a/src/arch/x86_64/Emit.zig b/src/arch/x86_64/Emit.zig index c6671b82d5..4b49c51977 100644 --- a/src/arch/x86_64/Emit.zig +++ b/src/arch/x86_64/Emit.zig @@ -84,7 +84,7 @@ pub fn emitMir(emit: *Emit) Error!void { if (emit.bin_file.options.pic) { const r_type: u32 = if (sym.flags.has_zig_got) link.File.Elf.R_X86_64_ZIG_GOTPCREL - else if (sym.flags.has_got) + else if (sym.flags.needs_got) std.elf.R_X86_64_GOTPCREL else std.elf.R_X86_64_PC32; diff --git a/src/codegen.zig b/src/codegen.zig index e6ac1ee2e1..3f2863ed7d 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -904,6 +904,7 @@ fn genDeclRef( else null; const sym_index = try elf_file.getGlobalSymbol(name, lib_name); + elf_file.symbol(elf_file.zigModulePtr().symbol(sym_index)).flags.needs_got = true; return GenResult.mcv(.{ .lea_symbol = sym_index }); } const sym_index = try elf_file.getOrCreateMetadataForDecl(decl_index); diff --git a/src/link/Elf.zig b/src/link/Elf.zig index b03bdfbc7e..f5d6a78298 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -3333,7 +3333,8 @@ pub fn updateDecl( const variable = decl.getOwnedVariable(mod).?; const name = mod.intern_pool.stringToSlice(decl.name); const lib_name = mod.intern_pool.stringToSliceUnwrap(variable.lib_name); - _ = try self.getGlobalSymbol(name, lib_name); + const esym_index = try self.getGlobalSymbol(name, lib_name); + self.symbol(self.zigModulePtr().symbol(esym_index)).flags.needs_got = true; return; } -- cgit v1.2.3 From 2be1250f244a362b832cfc3d519a27363495f130 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 27 Oct 2023 19:43:38 +0200 Subject: x86_64: no more load/lea_symbol weirdness --- src/arch/aarch64/CodeGen.zig | 2 +- src/arch/arm/CodeGen.zig | 2 +- src/arch/riscv64/CodeGen.zig | 2 +- src/arch/sparc64/CodeGen.zig | 2 +- src/arch/x86_64/CodeGen.zig | 31 ++++++---------- src/arch/x86_64/Emit.zig | 2 +- src/arch/x86_64/Lower.zig | 84 +++++++++++++++++++++++--------------------- src/codegen.zig | 5 ++- 8 files changed, 62 insertions(+), 68 deletions(-) (limited to 'src/codegen.zig') diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index 0b1ac0752f..b3ca885ef8 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/src/arch/aarch64/CodeGen.zig @@ -6176,7 +6176,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue { .memory => |addr| .{ .memory = addr }, .load_got => |sym_index| .{ .linker_load = .{ .type = .got, .sym_index = sym_index } }, .load_direct => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } }, - .load_symbol, .lea_symbol, .load_tlv => unreachable, // TODO + .load_symbol, .load_tlv => unreachable, // TODO }, .fail => |msg| { self.err_msg = msg; diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig index 2146f92de1..18121a04ac 100644 --- a/src/arch/arm/CodeGen.zig +++ b/src/arch/arm/CodeGen.zig @@ -6135,7 +6135,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue { .mcv => |mcv| switch (mcv) { .none => .none, .undef => .undef, - .load_got, .load_symbol, .lea_symbol, .load_direct, .load_tlv => unreachable, // TODO + .load_got, .load_symbol, .load_direct, .load_tlv => unreachable, // TODO .immediate => |imm| .{ .immediate = @as(u32, @truncate(imm)) }, .memory => |addr| .{ .memory = addr }, }, diff --git a/src/arch/riscv64/CodeGen.zig b/src/arch/riscv64/CodeGen.zig index 9b61166d6e..f66be65d1c 100644 --- a/src/arch/riscv64/CodeGen.zig +++ b/src/arch/riscv64/CodeGen.zig @@ -2591,7 +2591,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { .mcv => |mcv| switch (mcv) { .none => .none, .undef => .undef, - .load_got, .load_symbol, .lea_symbol, .load_direct, .load_tlv => unreachable, // TODO + .load_got, .load_symbol, .load_direct, .load_tlv => unreachable, // TODO .immediate => |imm| .{ .immediate = imm }, .memory => |addr| .{ .memory = addr }, }, diff --git a/src/arch/sparc64/CodeGen.zig b/src/arch/sparc64/CodeGen.zig index 2e20fbf5cf..cc9630320f 100644 --- a/src/arch/sparc64/CodeGen.zig +++ b/src/arch/sparc64/CodeGen.zig @@ -4137,7 +4137,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { .mcv => |mcv| switch (mcv) { .none => .none, .undef => .undef, - .load_got, .load_symbol, .lea_symbol, .load_direct, .load_tlv => unreachable, // TODO + .load_got, .load_symbol, .load_direct, .load_tlv => unreachable, // TODO .immediate => |imm| .{ .immediate = imm }, .memory => |addr| .{ .memory = addr }, }, diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index edf8af098e..9db0f0a1dc 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -453,8 +453,8 @@ pub const MCValue = union(enum) { .lea_frame => |pl| try writer.print("{} + 0x{x}", .{ pl.index, pl.off }), .reserved_frame => |pl| try writer.print("(dead:{})", .{pl}), .air_ref => |pl| try writer.print("(air:0x{x})", .{@intFromEnum(pl)}), - .load_symbol => |pl| try writer.print("[mem:{d}]", .{pl}), - .lea_symbol => |pl| try writer.print("mem:{d}", .{pl}), + .load_symbol => |pl| try writer.print("[symbol:{d}]", .{pl}), + .lea_symbol => |pl| try writer.print("symbol:{d}", .{pl}), } } }; @@ -11627,8 +11627,8 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { .{ .reg = try self.copyToTmpRegister(Type.usize, .{ .lea_got = sym_index }) } else return self.fail("invalid modifier: '{s}'", .{modifier}), - .lea_symbol => |sym_index| if (mem.eql(u8, modifier, "P")) - .{ .reg = try self.copyToTmpRegister(Type.usize, .{ .lea_symbol = sym_index }) } + .load_symbol => |sym_index| if (mem.eql(u8, modifier, "P")) + .{ .reg = try self.copyToTmpRegister(Type.usize, .{ .load_symbol = sym_index }) } else return self.fail("invalid modifier: '{s}'", .{modifier}), else => return self.fail("invalid constraint: '{s}'", .{op_str}), @@ -12489,10 +12489,9 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr }, .lea_symbol, .lea_direct, .lea_got => |sym_index| { const atom_index = try self.owner.getSymbolIndex(self); - if (self.bin_file.cast(link.File.Elf)) |elf_file| { - const sym = elf_file.symbol(elf_file.zigModulePtr().symbol(sym_index)); + if (self.bin_file.cast(link.File.Elf)) |_| { _ = try self.addInst(.{ - .tag = if (sym.flags.has_zig_got) .mov else .lea, + .tag = .lea, .ops = .linker_reloc, .data = .{ .rx = .{ .r1 = dst_reg.to64(), @@ -12783,7 +12782,7 @@ fn genLazySymbolRef( }; switch (tag) { .lea, .mov => _ = try self.addInst(.{ - .tag = .mov, + .tag = tag, .ops = .linker_reloc, .data = .{ .rx = .{ .r1 = reg.to64(), @@ -12797,15 +12796,6 @@ fn genLazySymbolRef( }), else => unreachable, } - switch (tag) { - .lea, .call => {}, - .mov => try self.asmRegisterMemory( - .{ ._, tag }, - reg.to64(), - Memory.sib(.qword, .{ .base = .{ .reg = reg.to64() } }), - ), - else => unreachable, - } } } else if (self.bin_file.cast(link.File.Plan9)) |p9_file| { const atom_index = p9_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err| @@ -14692,10 +14682,12 @@ 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); - if (!gop.found_existing) gop.value_ptr.* = InstTracking.init(try self.genTypedValue(.{ + const mcv = try self.genTypedValue(.{ .ty = ty, .val = ip_index.toValue(), - })); + }); + std.debug.print("genTypedValue: {any}\n", .{mcv}); + if (!gop.found_existing) gop.value_ptr.* = InstTracking.init(mcv); break :mcv gop.value_ptr.short; }; @@ -14743,7 +14735,6 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue { .immediate => |imm| .{ .immediate = imm }, .memory => |addr| .{ .memory = addr }, .load_symbol => |sym_index| .{ .load_symbol = sym_index }, - .lea_symbol => |sym_index| .{ .lea_symbol = sym_index }, .load_direct => |sym_index| .{ .load_direct = sym_index }, .load_got => |sym_index| .{ .lea_got = sym_index }, .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, diff --git a/src/arch/x86_64/Emit.zig b/src/arch/x86_64/Emit.zig index 4b49c51977..e599e7c2a7 100644 --- a/src/arch/x86_64/Emit.zig +++ b/src/arch/x86_64/Emit.zig @@ -96,7 +96,7 @@ pub fn emitMir(emit: *Emit) Error!void { } else { const r_type: u32 = if (sym.flags.has_zig_got) link.File.Elf.R_X86_64_ZIG_GOT32 - else if (sym.flags.has_got) + else if (sym.flags.needs_got) std.elf.R_X86_64_GOT32 else std.elf.R_X86_64_32; diff --git a/src/arch/x86_64/Lower.zig b/src/arch/x86_64/Lower.zig index c59ee5e671..31121b991b 100644 --- a/src/arch/x86_64/Lower.zig +++ b/src/arch/x86_64/Lower.zig @@ -415,7 +415,49 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void { => ._, else => return lower.fail("TODO lower .{s}", .{@tagName(inst.ops)}), }; - try lower.emit(switch (fixes) { + if (inst.ops == .linker_reloc) { + if (lower.bin_file.options.pic) { + const reg = inst.data.rx.r1; + const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data; + _ = lower.reloc(.{ .linker_reloc = extra }); + const mnemonic: Mnemonic = switch (inst.tag) { + .mov => .mov, + .lea => .lea, + else => unreachable, + }; + try lower.emit(.none, mnemonic, &.{ + .{ .reg = reg }, + .{ .mem = Memory.rip(Memory.PtrSize.fromBitSize(reg.bitSize()), 0) }, + }); + } else { + switch (inst.tag) { + .call => { + _ = lower.reloc(.{ .linker_reloc = inst.data.reloc }); + try lower.emit(.none, .call, &.{ + .{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = 0 }) }, + }); + }, + .lea => { + const reg = inst.data.rx.r1; + const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data; + try lower.emit(.none, .mov, &.{ + .{ .reg = reg }, + .{ .imm = lower.reloc(.{ .linker_reloc = extra }) }, + }); + }, + .mov => { + const reg = inst.data.rx.r1; + const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data; + _ = lower.reloc(.{ .linker_reloc = extra }); + try lower.emit(.none, .mov, &.{ + .{ .reg = reg }, + .{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = 0 }) }, + }); + }, + else => return lower.fail("TODO lower {s} {s}", .{ @tagName(inst.tag), @tagName(inst.ops) }), + } + } + } else try lower.emit(switch (fixes) { inline else => |tag| comptime if (std.mem.indexOfScalar(u8, @tagName(tag), ' ')) |space| @field(Prefix, @tagName(tag)[0..space]) else @@ -544,45 +586,7 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void { .extern_fn_reloc => &.{ .{ .imm = lower.reloc(.{ .linker_extern_fn = inst.data.reloc }) }, }, - .linker_reloc => ops: { - if (lower.bin_file.options.pic) { - const reg = inst.data.rx.r1; - const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data; - _ = lower.reloc(.{ .linker_reloc = extra }); - break :ops &.{ - .{ .reg = reg }, - .{ .mem = Memory.rip(Memory.PtrSize.fromBitSize(reg.bitSize()), 0) }, - }; - } else { - switch (inst.tag) { - .call => { - _ = lower.reloc(.{ .linker_reloc = inst.data.reloc }); - break :ops &.{ - .{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = 0 }) }, - }; - }, - .mov => { - const reg = inst.data.rx.r1; - const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data; - _ = lower.reloc(.{ .linker_reloc = extra }); - break :ops &.{ - .{ .reg = reg }, - .{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = 0 }) }, - }; - }, - .lea => { - const reg = inst.data.rx.r1; - const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data; - _ = lower.reloc(.{ .linker_reloc = extra }); - break :ops &.{ - .{ .reg = reg }, - .{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = 0 }) }, - }; - }, - else => return lower.fail("TODO lower {s} {s}", .{ @tagName(inst.tag), @tagName(inst.ops) }), - } - } - }, + .linker_reloc => unreachable, .got_reloc, .direct_reloc, .import_reloc, .tlv_reloc => ops: { const reg = inst.data.rx.r1; const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data; diff --git a/src/codegen.zig b/src/codegen.zig index 3f2863ed7d..4db32df16f 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -828,7 +828,6 @@ pub const GenResult = union(enum) { /// Reference to memory location but deferred until linker allocated the Decl in memory. /// Traditionally, this corresponds to emitting a relocation in a relocatable object file. load_symbol: u32, - lea_symbol: u32, }; fn mcv(val: MCValue) GenResult { @@ -905,12 +904,12 @@ fn genDeclRef( null; const sym_index = try elf_file.getGlobalSymbol(name, lib_name); elf_file.symbol(elf_file.zigModulePtr().symbol(sym_index)).flags.needs_got = true; - return GenResult.mcv(.{ .lea_symbol = sym_index }); + return GenResult.mcv(.{ .load_symbol = sym_index }); } const sym_index = try elf_file.getOrCreateMetadataForDecl(decl_index); const sym = elf_file.symbol(sym_index); _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file); - return GenResult.mcv(.{ .lea_symbol = sym.esym_index }); + return GenResult.mcv(.{ .load_symbol = sym.esym_index }); } else if (bin_file.cast(link.File.MachO)) |macho_file| { const atom_index = try macho_file.getOrCreateAtomForDecl(decl_index); const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?; -- cgit v1.2.3