From 7be983ac9217a596b7f35e7ef4c49fda0270e10b Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 13 Oct 2023 14:54:52 +0200 Subject: elf: create new synthetic section ZigGotSection --- src/arch/arm/CodeGen.zig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/arch/arm/CodeGen.zig') diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig index 5afb944474..aefac7bdd4 100644 --- a/src/arch/arm/CodeGen.zig +++ b/src/arch/arm/CodeGen.zig @@ -4304,8 +4304,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier if (self.bin_file.cast(link.File.Elf)) |elf_file| { const sym_index = try elf_file.getOrCreateMetadataForDecl(func.owner_decl); const sym = elf_file.symbol(sym_index); - _ = try sym.getOrCreateGotEntry(sym_index, elf_file); - const got_addr = @as(u32, @intCast(sym.gotAddress(elf_file))); + _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file); + const got_addr = @as(u32, @intCast(sym.zigGotAddress(elf_file))); try self.genSetReg(Type.usize, .lr, .{ .memory = got_addr }); } else if (self.bin_file.cast(link.File.MachO)) |_| { unreachable; // unsupported architecture for MachO -- cgit v1.2.3 From 45197ea7adfa34806b549263c06b988b5e35d48c Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sun, 15 Oct 2023 09:10:46 +0200 Subject: codegen+elf: lower imported data refs --- src/arch/aarch64/CodeGen.zig | 6 ++- src/arch/arm/CodeGen.zig | 2 +- src/arch/riscv64/CodeGen.zig | 2 +- src/arch/sparc64/CodeGen.zig | 2 +- src/arch/x86_64/CodeGen.zig | 87 +++++++++++++++++++++++++++++++++++--------- src/arch/x86_64/Emit.zig | 4 +- src/arch/x86_64/Lower.zig | 6 ++- src/arch/x86_64/Mir.zig | 2 + src/codegen.zig | 10 +++++ src/link/Dwarf.zig | 1 + src/link/Elf.zig | 14 ++++--- 11 files changed, 107 insertions(+), 29 deletions(-) (limited to 'src/arch/arm/CodeGen.zig') diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index 5a114459d8..154e2ea129 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/src/arch/aarch64/CodeGen.zig @@ -4012,6 +4012,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type .got => .load_memory_ptr_got, .direct => .load_memory_ptr_direct, .import => unreachable, + .actual_got => unreachable, }; const atom_index = switch (self.bin_file.tag) { .macho => blk: { @@ -5531,6 +5532,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro .got => .load_memory_ptr_got, .direct => .load_memory_ptr_direct, .import => unreachable, + .actual_got => unreachable, }; const atom_index = switch (self.bin_file.tag) { .macho => blk: { @@ -5652,6 +5654,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void .got => .load_memory_got, .direct => .load_memory_direct, .import => .load_memory_import, + .actual_got => unreachable, }; const atom_index = switch (self.bin_file.tag) { .macho => blk: { @@ -5849,6 +5852,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I .got => .load_memory_ptr_got, .direct => .load_memory_ptr_direct, .import => unreachable, + .actual_got => unreachable, }; const atom_index = switch (self.bin_file.tag) { .macho => blk: { @@ -6176,7 +6180,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_tlv => unreachable, // TODO + .load_actual_got, .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 aefac7bdd4..7a505de659 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_direct, .load_tlv => unreachable, // TODO + .load_got, .load_actual_got, .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 eb7d7187eb..0191e8a302 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_direct, .load_tlv => unreachable, // TODO + .load_got, .load_actual_got, .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 b5fd40ed95..504f9b4c43 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_direct, .load_tlv => unreachable, // TODO + .load_got, .load_actual_got, .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 c488209366..0d50f03d95 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -207,6 +207,10 @@ pub const MCValue = union(enum) { /// The value is a pointer to a value referenced indirectly via GOT. /// Payload is a symbol index. lea_got: u32, + /// TODO indirection via actual .got table + /// LOL Jakub, the king of naming... + load_actual_got: u32, + lea_actual_got: u32, /// The value is a threadlocal variable. /// Payload is a symbol index. load_tlv: u32, @@ -295,6 +299,7 @@ pub const MCValue = union(enum) { .register_overflow, .lea_direct, .lea_got, + .lea_actual_got, .lea_tlv, .lea_frame, .reserved_frame, @@ -308,6 +313,7 @@ pub const MCValue = union(enum) { .load_direct => |sym_index| .{ .lea_direct = sym_index }, .load_got => |sym_index| .{ .lea_got = sym_index }, .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, + .load_actual_got => |sym_index| .{ .lea_actual_got = sym_index }, .load_frame => |frame_addr| .{ .lea_frame = frame_addr }, }; } @@ -325,6 +331,7 @@ pub const MCValue = union(enum) { .indirect, .load_direct, .load_got, + .load_actual_got, .load_tlv, .load_frame, .reserved_frame, @@ -335,6 +342,7 @@ pub const MCValue = union(enum) { .register_offset => |reg_off| .{ .indirect = reg_off }, .lea_direct => |sym_index| .{ .load_direct = sym_index }, .lea_got => |sym_index| .{ .load_got = sym_index }, + .lea_actual_got => |sym_index| .{ .load_actual_got = sym_index }, .lea_tlv => |sym_index| .{ .load_tlv = sym_index }, .lea_frame => |frame_addr| .{ .load_frame = frame_addr }, }; @@ -358,6 +366,8 @@ pub const MCValue = union(enum) { .lea_direct, .load_got, .lea_got, + .load_actual_got, + .lea_actual_got, .load_tlv, .lea_tlv, .load_frame, @@ -392,6 +402,8 @@ pub const MCValue = union(enum) { .lea_direct, .load_got, .lea_got, + .load_actual_got, + .lea_actual_got, .load_tlv, .lea_tlv, .lea_frame, @@ -434,6 +446,8 @@ pub const MCValue = union(enum) { .lea_direct => |pl| try writer.print("direct:{d}", .{pl}), .load_got => |pl| try writer.print("[got:{d}]", .{pl}), .lea_got => |pl| try writer.print("got:{d}", .{pl}), + .load_actual_got => |pl| try writer.print("[actual_got:{d}]", .{pl}), + .lea_actual_got => |pl| try writer.print("actual_got:{d}", .{pl}), .load_tlv => |pl| try writer.print("[tlv:{d}]", .{pl}), .lea_tlv => |pl| try writer.print("tlv:{d}", .{pl}), .load_frame => |pl| try writer.print("[{} + 0x{x}]", .{ pl.index, pl.off }), @@ -461,6 +475,8 @@ const InstTracking = struct { .lea_direct, .load_got, .lea_got, + .load_actual_got, + .lea_actual_got, .load_tlv, .lea_tlv, .load_frame, @@ -520,6 +536,8 @@ const InstTracking = struct { .lea_direct, .load_got, .lea_got, + .load_actual_got, + .lea_actual_got, .load_tlv, .lea_tlv, .load_frame, @@ -555,6 +573,8 @@ const InstTracking = struct { .lea_direct, .load_got, .lea_got, + .load_actual_got, + .lea_actual_got, .load_tlv, .lea_tlv, .lea_frame, @@ -4371,6 +4391,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { .memory, .load_direct, .load_got, + .load_actual_got, .load_tlv, => try self.genSetReg(addr_reg, Type.usize, array.address()), .lea_direct, .lea_tlv => unreachable, @@ -5851,6 +5872,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro .register_offset, .lea_direct, .lea_got, + .lea_actual_got, .lea_tlv, .lea_frame, => try self.genCopy(dst_ty, dst_mcv, ptr_mcv.deref()), @@ -5858,6 +5880,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro .indirect, .load_direct, .load_got, + .load_actual_got, .load_tlv, .load_frame, => { @@ -5996,6 +6019,7 @@ fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerErr .register_offset, .lea_direct, .lea_got, + .lea_actual_got, .lea_tlv, .lea_frame, => try self.genCopy(src_ty, ptr_mcv.deref(), src_mcv), @@ -6003,6 +6027,7 @@ fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerErr .indirect, .load_direct, .load_got, + .load_actual_got, .load_tlv, .load_frame, => { @@ -6424,6 +6449,7 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MC .register_overflow, .lea_direct, .lea_got, + .lea_actual_got, .lea_tlv, .lea_frame, .reserved_frame, @@ -6431,7 +6457,7 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MC => unreachable, // unmodifiable destination .register => |dst_reg| try self.asmRegister(mir_tag, registerAlias(dst_reg, abi_size)), .register_pair => unreachable, // unimplemented - .memory, .load_got, .load_direct, .load_tlv => { + .memory, .load_got, .load_actual_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); @@ -7389,6 +7415,8 @@ fn genBinOp( .lea_direct, .load_got, .lea_got, + .load_actual_got, + .lea_actual_got, .load_tlv, .lea_tlv, .lea_frame, @@ -7445,6 +7473,8 @@ fn genBinOp( .lea_direct, .load_got, .lea_got, + .load_actual_got, + .lea_actual_got, .load_tlv, .lea_tlv, .lea_frame, @@ -8397,6 +8427,7 @@ fn genBinOpMir( .register_overflow, .lea_direct, .lea_got, + .lea_actual_got, .lea_tlv, .lea_frame, .reserved_frame, @@ -8485,6 +8516,8 @@ fn genBinOpMir( .lea_direct, .load_got, .lea_got, + .load_actual_got, + .lea_actual_got, .load_tlv, .lea_tlv, .load_frame, @@ -8517,6 +8550,7 @@ fn genBinOpMir( .register_offset, .lea_direct, .lea_got, + .lea_actual_got, .lea_tlv, .lea_frame, => { @@ -8532,6 +8566,7 @@ fn genBinOpMir( .memory, .load_direct, .load_got, + .load_actual_got, .load_tlv, => { const ptr_ty = try mod.singleConstPtrType(ty); @@ -8552,13 +8587,13 @@ fn genBinOpMir( } } }, - .memory, .indirect, .load_got, .load_direct, .load_tlv, .load_frame => { + .memory, .indirect, .load_got, .load_actual_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_got, .load_direct, .load_tlv => dst: { + .memory, .load_got, .load_actual_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); @@ -8592,16 +8627,17 @@ fn genBinOpMir( .indirect, .lea_direct, .lea_got, + .lea_actual_got, .lea_tlv, .load_frame, .lea_frame, => null, - .memory, .load_got, .load_direct, .load_tlv => src: { + .memory, .load_got, .load_actual_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_got, .load_direct, .load_tlv => {}, + .load_got, .load_actual_got, .load_direct, .load_tlv => {}, else => unreachable, } @@ -8644,6 +8680,7 @@ fn genBinOpMir( switch (dst_mcv) { .memory, .load_got, + .load_actual_got, .load_direct, .load_tlv, => .{ .base = .{ .reg = dst_info.?.addr_reg }, .disp = off }, @@ -8728,6 +8765,8 @@ fn genBinOpMir( .lea_direct, .load_got, .lea_got, + .load_actual_got, + .lea_actual_got, .load_tlv, .lea_tlv, .load_frame, @@ -8743,6 +8782,7 @@ fn genBinOpMir( .register_offset, .lea_direct, .lea_got, + .lea_actual_got, .lea_tlv, .lea_frame, => switch (limb_i) { @@ -8792,6 +8832,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M .register_overflow, .lea_direct, .lea_got, + .lea_actual_got, .lea_tlv, .lea_frame, .reserved_frame, @@ -8840,6 +8881,8 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M .lea_direct, .load_got, .lea_got, + .load_actual_got, + .lea_actual_got, .load_tlv, .lea_tlv, .lea_frame, @@ -8878,7 +8921,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M } }, .register_pair => unreachable, // unimplemented - .memory, .indirect, .load_direct, .load_got, .load_tlv, .load_frame => { + .memory, .indirect, .load_direct, .load_got, .load_actual_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); @@ -8971,6 +9014,7 @@ fn genVarDbgInfo( //} }, .memory => |address| .{ .memory = address }, .load_got => |sym_index| .{ .linker_load = .{ .type = .got, .sym_index = sym_index } }, + .load_actual_got => |sym_index| .{ .linker_load = .{ .type = .actual_got, .sym_index = sym_index } }, .load_direct => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } }, .immediate => |x| .{ .immediate = x }, .undef => .undef, @@ -9410,13 +9454,14 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { .indirect, .lea_direct, .lea_got, + .lea_actual_got, .lea_tlv, .lea_frame, .reserved_frame, .air_ref, => unreachable, .register_pair, .load_frame => null, - .memory, .load_got, .load_direct, .load_tlv => dst: { + .memory, .load_got, .load_actual_got, .load_direct, .load_tlv => dst: { switch (resolved_dst_mcv) { .memory => |addr| if (math.cast( i32, @@ -9425,7 +9470,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_got, .load_direct, .load_tlv => {}, + .load_got, .load_actual_got, .load_direct, .load_tlv => {}, else => unreachable, } @@ -9468,13 +9513,14 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { .indirect, .lea_direct, .lea_got, + .lea_actual_got, .lea_tlv, .lea_frame, .reserved_frame, .air_ref, => unreachable, .register_pair, .load_frame => null, - .memory, .load_got, .load_direct, .load_tlv => src: { + .memory, .load_got, .load_actual_got, .load_direct, .load_tlv => src: { switch (resolved_src_mcv) { .memory => |addr| if (math.cast( i32, @@ -9483,7 +9529,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_got, .load_direct, .load_tlv => {}, + .load_got, .load_actual_got, .load_direct, .load_tlv => {}, else => unreachable, } @@ -9902,6 +9948,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC .register_overflow, .lea_direct, .lea_got, + .lea_actual_got, .lea_tlv, .lea_frame, .reserved_frame, @@ -9928,6 +9975,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC .memory, .load_got, + .load_actual_got, .load_direct, .load_tlv, => { @@ -10485,7 +10533,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_direct, .load_got, .load_tlv => {}, + .load_direct, .load_got, .load_actual_got, .load_tlv => {}, else => { const temp_mcv = try self.allocTempRegOrMem(ty, false); try self.genCopy(ty, temp_mcv, input_mcv); @@ -11146,6 +11194,7 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError .register_overflow, .lea_direct, .lea_got, + .lea_actual_got, .lea_tlv, .lea_frame, .reserved_frame, @@ -11197,11 +11246,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_direct, .load_got, .load_tlv => { + .memory, .load_direct, .load_got, .load_actual_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_direct, .load_got, .load_tlv => {}, + .load_direct, .load_got, .load_actual_got, .load_tlv => {}, else => unreachable, } @@ -11363,7 +11412,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr else => unreachable, }, )), - .memory, .load_direct, .load_got, .load_tlv => { + .memory, .load_direct, .load_got, .load_actual_got, .load_tlv => { switch (src_mcv) { .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr| return (try self.moveStrategy( @@ -11391,7 +11440,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr }, .Float, .Vector => {}, }, - .load_got, .load_tlv => {}, + .load_got, .load_actual_got, .load_tlv => {}, else => unreachable, } @@ -11405,17 +11454,18 @@ 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_direct, .lea_got => |sym_index| { + .lea_direct, .lea_got, .lea_actual_got => |sym_index| { const atom_index = try self.owner.getSymbolIndex(self); _ = try self.addInst(.{ .tag = switch (src_mcv) { .lea_direct => .lea, - .lea_got => .mov, + .lea_got, .lea_actual_got => .mov, else => unreachable, }, .ops = switch (src_mcv) { .lea_direct => .direct_reloc, .lea_got => .got_reloc, + .lea_actual_got => .actual_got_reloc, else => unreachable, }, .data = .{ .rx = .{ @@ -11551,6 +11601,8 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal .lea_direct, .load_got, .lea_got, + .load_actual_got, + .lea_actual_got, .load_tlv, .lea_tlv, .load_frame, @@ -13556,6 +13608,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue { .memory => |addr| .{ .memory = addr }, .load_direct => |sym_index| .{ .load_direct = sym_index }, .load_got => |sym_index| .{ .lea_got = sym_index }, + .load_actual_got => |sym_index| .{ .lea_actual_got = sym_index }, .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, }, .fail => |msg| { diff --git a/src/arch/x86_64/Emit.zig b/src/arch/x86_64/Emit.zig index 3347460eb8..9c0c48121f 100644 --- a/src/arch/x86_64/Emit.zig +++ b/src/arch/x86_64/Emit.zig @@ -79,6 +79,7 @@ pub fn emitMir(emit: *Emit) Error!void { @tagName(emit.bin_file.tag), }), .linker_got, + .linker_actual_got, .linker_direct, .linker_direct_got, .linker_import, @@ -87,12 +88,13 @@ pub fn emitMir(emit: *Emit) Error!void { const r_type: u32 = switch (lowered_relocs[0].target) { .linker_direct_got => link.File.Elf.R_X86_64_ZIG_GOT32, .linker_got => link.File.Elf.R_X86_64_ZIG_GOTPCREL, + .linker_actual_got => std.elf.R_X86_64_GOTPCREL, .linker_direct => std.elf.R_X86_64_PC32, else => unreachable, }; const r_addend: i64 = switch (lowered_relocs[0].target) { .linker_direct_got => 0, - .linker_got, .linker_direct => -4, + .linker_got, .linker_actual_got, .linker_direct => -4, else => unreachable, }; const atom_ptr = elf_file.symbol(symbol.atom_index).atom(elf_file).?; diff --git a/src/arch/x86_64/Lower.zig b/src/arch/x86_64/Lower.zig index 71f411bdaf..f8091e5476 100644 --- a/src/arch/x86_64/Lower.zig +++ b/src/arch/x86_64/Lower.zig @@ -51,6 +51,7 @@ pub const Reloc = struct { inst: Mir.Inst.Index, linker_extern_fn: Mir.Reloc, linker_got: Mir.Reloc, + linker_actual_got: Mir.Reloc, linker_direct: Mir.Reloc, linker_direct_got: Mir.Reloc, linker_import: Mir.Reloc, @@ -388,7 +389,7 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void { .rrmi_sib, .rrmi_rip => inst.data.rrix.fixes, .mi_sib_u, .mi_rip_u, .mi_sib_s, .mi_rip_s => inst.data.x.fixes, .m_sib, .m_rip, .rax_moffs, .moffs_rax => inst.data.x.fixes, - .extern_fn_reloc, .got_reloc, .direct_reloc, .direct_got_reloc, .import_reloc, .tlv_reloc => ._, + .extern_fn_reloc, .got_reloc, .actual_got_reloc, .direct_reloc, .direct_got_reloc, .import_reloc, .tlv_reloc => ._, else => return lower.fail("TODO lower .{s}", .{@tagName(inst.ops)}), }; try lower.emit(switch (fixes) { @@ -532,11 +533,12 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void { else => unreachable, } }, - .got_reloc, .direct_reloc, .import_reloc, .tlv_reloc => ops: { + .got_reloc, .actual_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; _ = lower.reloc(switch (inst.ops) { .got_reloc => .{ .linker_got = extra }, + .actual_got_reloc => .{ .linker_actual_got = extra }, .direct_reloc => .{ .linker_direct = extra }, .import_reloc => .{ .linker_import = extra }, .tlv_reloc => .{ .linker_tlv = extra }, diff --git a/src/arch/x86_64/Mir.zig b/src/arch/x86_64/Mir.zig index b17da20862..1e159d5a16 100644 --- a/src/arch/x86_64/Mir.zig +++ b/src/arch/x86_64/Mir.zig @@ -783,6 +783,8 @@ pub const Inst = struct { /// Linker relocation - GOT indirection. /// Uses `rx` payload with extra data of type `Reloc`. got_reloc, + /// TODO + actual_got_reloc, /// Linker relocation - direct reference. /// Uses `rx` payload with extra data of type `Reloc`. direct_reloc, diff --git a/src/codegen.zig b/src/codegen.zig index b5f7f3885e..de5ff9651a 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -798,6 +798,7 @@ fn lowerDeclRef( pub const LinkerLoad = struct { type: enum { got, + actual_got, direct, import, }, @@ -827,6 +828,8 @@ pub const GenResult = union(enum) { load_got: u32, /// Direct by-address reference to memory location. memory: u64, + /// TODO LOL Jakub, the king of naming... + load_actual_got: u32, }; fn mcv(val: MCValue) GenResult { @@ -885,8 +888,15 @@ fn genDeclRef( try mod.markDeclAlive(decl); const is_threadlocal = tv.val.isPtrToThreadLocal(mod) and !bin_file.options.single_threaded; + const is_extern = decl.isExtern(mod); if (bin_file.cast(link.File.Elf)) |elf_file| { + if (is_extern) { + const variable = decl.getOwnedVariable(mod).?; + const name = mod.intern_pool.stringToSlice(decl.name); + const lib_name = mod.intern_pool.stringToSliceUnwrap(variable.lib_name); + return GenResult.mcv(.{ .load_actual_got = try elf_file.getGlobalSymbol(name, lib_name) }); + } const sym_index = try elf_file.getOrCreateMetadataForDecl(decl_index); const sym = elf_file.symbol(sym_index); _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file); diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index e271a7d399..ffe078f831 100644 --- a/src/link/Dwarf.zig +++ b/src/link/Dwarf.zig @@ -1389,6 +1389,7 @@ pub fn commitDeclState( .prev_vaddr = 0, }); }, + .elf => {}, // TODO else => unreachable, } } diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 9fe2f6b7ed..d27e3c7f3b 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -3196,12 +3196,16 @@ pub fn updateDecl( const decl = mod.declPtr(decl_index); if (decl.val.getExternFunc(mod)) |_| { - return; // TODO Should we do more when front-end analyzed extern decl? + return; } - if (decl.val.getVariable(mod)) |variable| { - if (variable.is_extern) { - return; // TODO Should we do more when front-end analyzed extern decl? - } + + if (decl.isExtern(mod)) { + // Extern variable gets a .got entry only. + 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); + return; } const sym_index = try self.getOrCreateMetadataForDecl(decl_index); -- cgit v1.2.3 From 6993b3e23e3b8f45f66902ebe23980aa155b343c Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sun, 15 Oct 2023 22:06:18 +0200 Subject: codegen: refactor .actual_got into .extern_got --- src/arch/aarch64/CodeGen.zig | 10 +-- src/arch/arm/CodeGen.zig | 2 +- src/arch/riscv64/CodeGen.zig | 2 +- src/arch/sparc64/CodeGen.zig | 2 +- src/arch/x86_64/CodeGen.zig | 142 ++++++++++++++++++++++--------------------- src/arch/x86_64/Emit.zig | 6 +- src/arch/x86_64/Lower.zig | 8 +-- src/arch/x86_64/Mir.zig | 5 +- src/codegen.zig | 9 +-- 9 files changed, 95 insertions(+), 91 deletions(-) (limited to 'src/arch/arm/CodeGen.zig') diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index 154e2ea129..d0e068da73 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/src/arch/aarch64/CodeGen.zig @@ -4012,7 +4012,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type .got => .load_memory_ptr_got, .direct => .load_memory_ptr_direct, .import => unreachable, - .actual_got => unreachable, + .extern_got => unreachable, }; const atom_index = switch (self.bin_file.tag) { .macho => blk: { @@ -5532,7 +5532,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro .got => .load_memory_ptr_got, .direct => .load_memory_ptr_direct, .import => unreachable, - .actual_got => unreachable, + .extern_got => unreachable, }; const atom_index = switch (self.bin_file.tag) { .macho => blk: { @@ -5654,7 +5654,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void .got => .load_memory_got, .direct => .load_memory_direct, .import => .load_memory_import, - .actual_got => unreachable, + .extern_got => unreachable, }; const atom_index = switch (self.bin_file.tag) { .macho => blk: { @@ -5852,7 +5852,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I .got => .load_memory_ptr_got, .direct => .load_memory_ptr_direct, .import => unreachable, - .actual_got => unreachable, + .extern_got => unreachable, }; const atom_index = switch (self.bin_file.tag) { .macho => blk: { @@ -6180,7 +6180,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_actual_got, .load_tlv => unreachable, // TODO + .load_extern_got, .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 7a505de659..a7c437bb59 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_actual_got, .load_direct, .load_tlv => unreachable, // TODO + .load_got, .load_extern_got, .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 0191e8a302..e4c4266531 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_actual_got, .load_direct, .load_tlv => unreachable, // TODO + .load_got, .load_extern_got, .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 504f9b4c43..ae4fc29e8a 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_actual_got, .load_direct, .load_tlv => unreachable, // TODO + .load_got, .load_extern_got, .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 0d50f03d95..980b96c0ed 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -207,10 +207,12 @@ pub const MCValue = union(enum) { /// The value is a pointer to a value referenced indirectly via GOT. /// Payload is a symbol index. lea_got: u32, - /// TODO indirection via actual .got table - /// LOL Jakub, the king of naming... - load_actual_got: u32, - lea_actual_got: u32, + /// The value is an extern variable referenced via GOT. + /// Payload is a symbol index. + load_extern_got: u32, + /// The value is a pointer to an extern variable referenced via GOT. + /// Payload is a symbol index. + lea_extern_got: u32, /// The value is a threadlocal variable. /// Payload is a symbol index. load_tlv: u32, @@ -299,7 +301,7 @@ pub const MCValue = union(enum) { .register_overflow, .lea_direct, .lea_got, - .lea_actual_got, + .lea_extern_got, .lea_tlv, .lea_frame, .reserved_frame, @@ -313,7 +315,7 @@ pub const MCValue = union(enum) { .load_direct => |sym_index| .{ .lea_direct = sym_index }, .load_got => |sym_index| .{ .lea_got = sym_index }, .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, - .load_actual_got => |sym_index| .{ .lea_actual_got = sym_index }, + .load_extern_got => |sym_index| .{ .lea_extern_got = sym_index }, .load_frame => |frame_addr| .{ .lea_frame = frame_addr }, }; } @@ -331,7 +333,7 @@ pub const MCValue = union(enum) { .indirect, .load_direct, .load_got, - .load_actual_got, + .load_extern_got, .load_tlv, .load_frame, .reserved_frame, @@ -342,7 +344,7 @@ pub const MCValue = union(enum) { .register_offset => |reg_off| .{ .indirect = reg_off }, .lea_direct => |sym_index| .{ .load_direct = sym_index }, .lea_got => |sym_index| .{ .load_got = sym_index }, - .lea_actual_got => |sym_index| .{ .load_actual_got = sym_index }, + .lea_extern_got => |sym_index| .{ .load_extern_got = sym_index }, .lea_tlv => |sym_index| .{ .load_tlv = sym_index }, .lea_frame => |frame_addr| .{ .load_frame = frame_addr }, }; @@ -366,8 +368,8 @@ pub const MCValue = union(enum) { .lea_direct, .load_got, .lea_got, - .load_actual_got, - .lea_actual_got, + .load_extern_got, + .lea_extern_got, .load_tlv, .lea_tlv, .load_frame, @@ -402,8 +404,8 @@ pub const MCValue = union(enum) { .lea_direct, .load_got, .lea_got, - .load_actual_got, - .lea_actual_got, + .load_extern_got, + .lea_extern_got, .load_tlv, .lea_tlv, .lea_frame, @@ -446,8 +448,8 @@ pub const MCValue = union(enum) { .lea_direct => |pl| try writer.print("direct:{d}", .{pl}), .load_got => |pl| try writer.print("[got:{d}]", .{pl}), .lea_got => |pl| try writer.print("got:{d}", .{pl}), - .load_actual_got => |pl| try writer.print("[actual_got:{d}]", .{pl}), - .lea_actual_got => |pl| try writer.print("actual_got:{d}", .{pl}), + .load_extern_got => |pl| try writer.print("[extern_got:{d}]", .{pl}), + .lea_extern_got => |pl| try writer.print("extern_got:{d}", .{pl}), .load_tlv => |pl| try writer.print("[tlv:{d}]", .{pl}), .lea_tlv => |pl| try writer.print("tlv:{d}", .{pl}), .load_frame => |pl| try writer.print("[{} + 0x{x}]", .{ pl.index, pl.off }), @@ -475,8 +477,8 @@ const InstTracking = struct { .lea_direct, .load_got, .lea_got, - .load_actual_got, - .lea_actual_got, + .load_extern_got, + .lea_extern_got, .load_tlv, .lea_tlv, .load_frame, @@ -536,8 +538,8 @@ const InstTracking = struct { .lea_direct, .load_got, .lea_got, - .load_actual_got, - .lea_actual_got, + .load_extern_got, + .lea_extern_got, .load_tlv, .lea_tlv, .load_frame, @@ -573,8 +575,8 @@ const InstTracking = struct { .lea_direct, .load_got, .lea_got, - .load_actual_got, - .lea_actual_got, + .load_extern_got, + .lea_extern_got, .load_tlv, .lea_tlv, .lea_frame, @@ -4391,7 +4393,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { .memory, .load_direct, .load_got, - .load_actual_got, + .load_extern_got, .load_tlv, => try self.genSetReg(addr_reg, Type.usize, array.address()), .lea_direct, .lea_tlv => unreachable, @@ -5872,7 +5874,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro .register_offset, .lea_direct, .lea_got, - .lea_actual_got, + .lea_extern_got, .lea_tlv, .lea_frame, => try self.genCopy(dst_ty, dst_mcv, ptr_mcv.deref()), @@ -5880,7 +5882,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro .indirect, .load_direct, .load_got, - .load_actual_got, + .load_extern_got, .load_tlv, .load_frame, => { @@ -6019,7 +6021,7 @@ fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerErr .register_offset, .lea_direct, .lea_got, - .lea_actual_got, + .lea_extern_got, .lea_tlv, .lea_frame, => try self.genCopy(src_ty, ptr_mcv.deref(), src_mcv), @@ -6027,7 +6029,7 @@ fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerErr .indirect, .load_direct, .load_got, - .load_actual_got, + .load_extern_got, .load_tlv, .load_frame, => { @@ -6449,7 +6451,7 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MC .register_overflow, .lea_direct, .lea_got, - .lea_actual_got, + .lea_extern_got, .lea_tlv, .lea_frame, .reserved_frame, @@ -6457,7 +6459,7 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MC => unreachable, // unmodifiable destination .register => |dst_reg| try self.asmRegister(mir_tag, registerAlias(dst_reg, abi_size)), .register_pair => unreachable, // unimplemented - .memory, .load_got, .load_actual_got, .load_direct, .load_tlv => { + .memory, .load_got, .load_extern_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); @@ -7415,8 +7417,8 @@ fn genBinOp( .lea_direct, .load_got, .lea_got, - .load_actual_got, - .lea_actual_got, + .load_extern_got, + .lea_extern_got, .load_tlv, .lea_tlv, .lea_frame, @@ -7473,8 +7475,8 @@ fn genBinOp( .lea_direct, .load_got, .lea_got, - .load_actual_got, - .lea_actual_got, + .load_extern_got, + .lea_extern_got, .load_tlv, .lea_tlv, .lea_frame, @@ -8427,7 +8429,7 @@ fn genBinOpMir( .register_overflow, .lea_direct, .lea_got, - .lea_actual_got, + .lea_extern_got, .lea_tlv, .lea_frame, .reserved_frame, @@ -8516,8 +8518,8 @@ fn genBinOpMir( .lea_direct, .load_got, .lea_got, - .load_actual_got, - .lea_actual_got, + .load_extern_got, + .lea_extern_got, .load_tlv, .lea_tlv, .load_frame, @@ -8550,7 +8552,7 @@ fn genBinOpMir( .register_offset, .lea_direct, .lea_got, - .lea_actual_got, + .lea_extern_got, .lea_tlv, .lea_frame, => { @@ -8566,7 +8568,7 @@ fn genBinOpMir( .memory, .load_direct, .load_got, - .load_actual_got, + .load_extern_got, .load_tlv, => { const ptr_ty = try mod.singleConstPtrType(ty); @@ -8587,13 +8589,13 @@ fn genBinOpMir( } } }, - .memory, .indirect, .load_got, .load_actual_got, .load_direct, .load_tlv, .load_frame => { + .memory, .indirect, .load_got, .load_extern_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_got, .load_actual_got, .load_direct, .load_tlv => dst: { + .memory, .load_got, .load_extern_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); @@ -8627,17 +8629,17 @@ fn genBinOpMir( .indirect, .lea_direct, .lea_got, - .lea_actual_got, + .lea_extern_got, .lea_tlv, .load_frame, .lea_frame, => null, - .memory, .load_got, .load_actual_got, .load_direct, .load_tlv => src: { + .memory, .load_got, .load_extern_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_got, .load_actual_got, .load_direct, .load_tlv => {}, + .load_got, .load_extern_got, .load_direct, .load_tlv => {}, else => unreachable, } @@ -8680,7 +8682,7 @@ fn genBinOpMir( switch (dst_mcv) { .memory, .load_got, - .load_actual_got, + .load_extern_got, .load_direct, .load_tlv, => .{ .base = .{ .reg = dst_info.?.addr_reg }, .disp = off }, @@ -8765,8 +8767,8 @@ fn genBinOpMir( .lea_direct, .load_got, .lea_got, - .load_actual_got, - .lea_actual_got, + .load_extern_got, + .lea_extern_got, .load_tlv, .lea_tlv, .load_frame, @@ -8782,7 +8784,7 @@ fn genBinOpMir( .register_offset, .lea_direct, .lea_got, - .lea_actual_got, + .lea_extern_got, .lea_tlv, .lea_frame, => switch (limb_i) { @@ -8832,7 +8834,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M .register_overflow, .lea_direct, .lea_got, - .lea_actual_got, + .lea_extern_got, .lea_tlv, .lea_frame, .reserved_frame, @@ -8881,8 +8883,8 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M .lea_direct, .load_got, .lea_got, - .load_actual_got, - .lea_actual_got, + .load_extern_got, + .lea_extern_got, .load_tlv, .lea_tlv, .lea_frame, @@ -8921,7 +8923,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M } }, .register_pair => unreachable, // unimplemented - .memory, .indirect, .load_direct, .load_got, .load_actual_got, .load_tlv, .load_frame => { + .memory, .indirect, .load_direct, .load_got, .load_extern_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); @@ -9014,7 +9016,7 @@ fn genVarDbgInfo( //} }, .memory => |address| .{ .memory = address }, .load_got => |sym_index| .{ .linker_load = .{ .type = .got, .sym_index = sym_index } }, - .load_actual_got => |sym_index| .{ .linker_load = .{ .type = .actual_got, .sym_index = sym_index } }, + .load_extern_got => |sym_index| .{ .linker_load = .{ .type = .extern_got, .sym_index = sym_index } }, .load_direct => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } }, .immediate => |x| .{ .immediate = x }, .undef => .undef, @@ -9454,14 +9456,14 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { .indirect, .lea_direct, .lea_got, - .lea_actual_got, + .lea_extern_got, .lea_tlv, .lea_frame, .reserved_frame, .air_ref, => unreachable, .register_pair, .load_frame => null, - .memory, .load_got, .load_actual_got, .load_direct, .load_tlv => dst: { + .memory, .load_got, .load_extern_got, .load_direct, .load_tlv => dst: { switch (resolved_dst_mcv) { .memory => |addr| if (math.cast( i32, @@ -9470,7 +9472,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_got, .load_actual_got, .load_direct, .load_tlv => {}, + .load_got, .load_extern_got, .load_direct, .load_tlv => {}, else => unreachable, } @@ -9513,14 +9515,14 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { .indirect, .lea_direct, .lea_got, - .lea_actual_got, + .lea_extern_got, .lea_tlv, .lea_frame, .reserved_frame, .air_ref, => unreachable, .register_pair, .load_frame => null, - .memory, .load_got, .load_actual_got, .load_direct, .load_tlv => src: { + .memory, .load_got, .load_extern_got, .load_direct, .load_tlv => src: { switch (resolved_src_mcv) { .memory => |addr| if (math.cast( i32, @@ -9529,7 +9531,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_got, .load_actual_got, .load_direct, .load_tlv => {}, + .load_got, .load_extern_got, .load_direct, .load_tlv => {}, else => unreachable, } @@ -9948,7 +9950,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC .register_overflow, .lea_direct, .lea_got, - .lea_actual_got, + .lea_extern_got, .lea_tlv, .lea_frame, .reserved_frame, @@ -9975,7 +9977,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC .memory, .load_got, - .load_actual_got, + .load_extern_got, .load_direct, .load_tlv, => { @@ -10533,7 +10535,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_direct, .load_got, .load_actual_got, .load_tlv => {}, + .load_direct, .load_got, .load_extern_got, .load_tlv => {}, else => { const temp_mcv = try self.allocTempRegOrMem(ty, false); try self.genCopy(ty, temp_mcv, input_mcv); @@ -11194,7 +11196,7 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError .register_overflow, .lea_direct, .lea_got, - .lea_actual_got, + .lea_extern_got, .lea_tlv, .lea_frame, .reserved_frame, @@ -11246,11 +11248,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_direct, .load_got, .load_actual_got, .load_tlv => { + .memory, .load_direct, .load_got, .load_extern_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_direct, .load_got, .load_actual_got, .load_tlv => {}, + .load_direct, .load_got, .load_extern_got, .load_tlv => {}, else => unreachable, } @@ -11412,7 +11414,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr else => unreachable, }, )), - .memory, .load_direct, .load_got, .load_actual_got, .load_tlv => { + .memory, .load_direct, .load_got, .load_extern_got, .load_tlv => { switch (src_mcv) { .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr| return (try self.moveStrategy( @@ -11440,7 +11442,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr }, .Float, .Vector => {}, }, - .load_got, .load_actual_got, .load_tlv => {}, + .load_got, .load_extern_got, .load_tlv => {}, else => unreachable, } @@ -11454,18 +11456,18 @@ 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_direct, .lea_got, .lea_actual_got => |sym_index| { + .lea_direct, .lea_got, .lea_extern_got => |sym_index| { const atom_index = try self.owner.getSymbolIndex(self); _ = try self.addInst(.{ .tag = switch (src_mcv) { .lea_direct => .lea, - .lea_got, .lea_actual_got => .mov, + .lea_got, .lea_extern_got => .mov, else => unreachable, }, .ops = switch (src_mcv) { .lea_direct => .direct_reloc, .lea_got => .got_reloc, - .lea_actual_got => .actual_got_reloc, + .lea_extern_got => .extern_got_reloc, else => unreachable, }, .data = .{ .rx = .{ @@ -11601,8 +11603,8 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal .lea_direct, .load_got, .lea_got, - .load_actual_got, - .lea_actual_got, + .load_extern_got, + .lea_extern_got, .load_tlv, .lea_tlv, .load_frame, @@ -13608,7 +13610,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue { .memory => |addr| .{ .memory = addr }, .load_direct => |sym_index| .{ .load_direct = sym_index }, .load_got => |sym_index| .{ .lea_got = sym_index }, - .load_actual_got => |sym_index| .{ .lea_actual_got = sym_index }, + .load_extern_got => |sym_index| .{ .lea_extern_got = sym_index }, .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, }, .fail => |msg| { diff --git a/src/arch/x86_64/Emit.zig b/src/arch/x86_64/Emit.zig index 9c0c48121f..e03b0f01b5 100644 --- a/src/arch/x86_64/Emit.zig +++ b/src/arch/x86_64/Emit.zig @@ -79,7 +79,7 @@ pub fn emitMir(emit: *Emit) Error!void { @tagName(emit.bin_file.tag), }), .linker_got, - .linker_actual_got, + .linker_extern_got, .linker_direct, .linker_direct_got, .linker_import, @@ -88,13 +88,13 @@ pub fn emitMir(emit: *Emit) Error!void { const r_type: u32 = switch (lowered_relocs[0].target) { .linker_direct_got => link.File.Elf.R_X86_64_ZIG_GOT32, .linker_got => link.File.Elf.R_X86_64_ZIG_GOTPCREL, - .linker_actual_got => std.elf.R_X86_64_GOTPCREL, + .linker_extern_got => std.elf.R_X86_64_GOTPCREL, .linker_direct => std.elf.R_X86_64_PC32, else => unreachable, }; const r_addend: i64 = switch (lowered_relocs[0].target) { .linker_direct_got => 0, - .linker_got, .linker_actual_got, .linker_direct => -4, + .linker_got, .linker_extern_got, .linker_direct => -4, else => unreachable, }; const atom_ptr = elf_file.symbol(symbol.atom_index).atom(elf_file).?; diff --git a/src/arch/x86_64/Lower.zig b/src/arch/x86_64/Lower.zig index f8091e5476..ae5f86d6b0 100644 --- a/src/arch/x86_64/Lower.zig +++ b/src/arch/x86_64/Lower.zig @@ -51,7 +51,7 @@ pub const Reloc = struct { inst: Mir.Inst.Index, linker_extern_fn: Mir.Reloc, linker_got: Mir.Reloc, - linker_actual_got: Mir.Reloc, + linker_extern_got: Mir.Reloc, linker_direct: Mir.Reloc, linker_direct_got: Mir.Reloc, linker_import: Mir.Reloc, @@ -389,7 +389,7 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void { .rrmi_sib, .rrmi_rip => inst.data.rrix.fixes, .mi_sib_u, .mi_rip_u, .mi_sib_s, .mi_rip_s => inst.data.x.fixes, .m_sib, .m_rip, .rax_moffs, .moffs_rax => inst.data.x.fixes, - .extern_fn_reloc, .got_reloc, .actual_got_reloc, .direct_reloc, .direct_got_reloc, .import_reloc, .tlv_reloc => ._, + .extern_fn_reloc, .got_reloc, .extern_got_reloc, .direct_reloc, .direct_got_reloc, .import_reloc, .tlv_reloc => ._, else => return lower.fail("TODO lower .{s}", .{@tagName(inst.ops)}), }; try lower.emit(switch (fixes) { @@ -533,12 +533,12 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void { else => unreachable, } }, - .got_reloc, .actual_got_reloc, .direct_reloc, .import_reloc, .tlv_reloc => ops: { + .got_reloc, .extern_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; _ = lower.reloc(switch (inst.ops) { .got_reloc => .{ .linker_got = extra }, - .actual_got_reloc => .{ .linker_actual_got = extra }, + .extern_got_reloc => .{ .linker_extern_got = extra }, .direct_reloc => .{ .linker_direct = extra }, .import_reloc => .{ .linker_import = extra }, .tlv_reloc => .{ .linker_tlv = extra }, diff --git a/src/arch/x86_64/Mir.zig b/src/arch/x86_64/Mir.zig index 1e159d5a16..0e2a4cca6d 100644 --- a/src/arch/x86_64/Mir.zig +++ b/src/arch/x86_64/Mir.zig @@ -783,8 +783,9 @@ pub const Inst = struct { /// Linker relocation - GOT indirection. /// Uses `rx` payload with extra data of type `Reloc`. got_reloc, - /// TODO - actual_got_reloc, + /// Linker relocation - reference to an extern variable via GOT. + /// Uses `rx` payload with extra data of type `Reloc`. + extern_got_reloc, /// Linker relocation - direct reference. /// Uses `rx` payload with extra data of type `Reloc`. direct_reloc, diff --git a/src/codegen.zig b/src/codegen.zig index 54ed9c0cf5..24269f38ba 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -793,12 +793,13 @@ 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, - actual_got, + extern_got, direct, import, }, @@ -828,8 +829,8 @@ pub const GenResult = union(enum) { load_got: u32, /// Direct by-address reference to memory location. memory: u64, - /// TODO LOL Jakub, the king of naming... - load_actual_got: u32, + /// Pointer to extern variable via GOT. + load_extern_got: u32, }; fn mcv(val: MCValue) GenResult { @@ -898,7 +899,7 @@ fn genDeclRef( mod.intern_pool.stringToSliceUnwrap(ov.lib_name) else null; - return GenResult.mcv(.{ .load_actual_got = try elf_file.getGlobalSymbol(name, lib_name) }); + return GenResult.mcv(.{ .load_extern_got = try elf_file.getGlobalSymbol(name, lib_name) }); } const sym_index = try elf_file.getOrCreateMetadataForDecl(decl_index); const sym = elf_file.symbol(sym_index); -- cgit v1.2.3