aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2024-08-15 14:23:36 +0200
committerJakub Konka <kubkon@jakubkonka.com>2024-08-15 14:23:36 +0200
commit4d5bf0f09a29eeb0eb7f3602825f1a0095b8427e (patch)
tree540c55e59e6e6c78e0b0824b20f5a009e943aa71 /src
parent79418fa0abe4b19a2fd2fb10cf3c1144b927d10f (diff)
downloadzig-4d5bf0f09a29eeb0eb7f3602825f1a0095b8427e.tar.gz
zig-4d5bf0f09a29eeb0eb7f3602825f1a0095b8427e.zip
x86_64: deref GOT pointer when requesting var value
Diffstat (limited to 'src')
-rw-r--r--src/arch/x86_64/Lower.zig16
1 files changed, 15 insertions, 1 deletions
diff --git a/src/arch/x86_64/Lower.zig b/src/arch/x86_64/Lower.zig
index 4fab1b806d..15322ce4f6 100644
--- a/src/arch/x86_64/Lower.zig
+++ b/src/arch/x86_64/Lower.zig
@@ -402,7 +402,21 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
if (elf_sym.flags.is_extern_ptr) emit_mnemonic = .mov;
break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) };
},
- .mov => break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) },
+ .mov => {
+ if (elf_sym.flags.is_extern_ptr) {
+ const reg = ops[0].reg;
+ lower.result_insts[lower.result_insts_len] =
+ try Instruction.new(.none, .mov, &[_]Operand{
+ .{ .reg = reg.to64() },
+ .{ .mem = Memory.rip(.qword, 0) },
+ });
+ lower.result_insts_len += 1;
+ break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{ .base = .{
+ .reg = reg.to64(),
+ } }) };
+ }
+ break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) };
+ },
else => unreachable,
} else switch (mnemonic) {
.call => break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{