diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2024-08-15 14:23:36 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2024-08-15 14:23:36 +0200 |
| commit | 4d5bf0f09a29eeb0eb7f3602825f1a0095b8427e (patch) | |
| tree | 540c55e59e6e6c78e0b0824b20f5a009e943aa71 /src | |
| parent | 79418fa0abe4b19a2fd2fb10cf3c1144b927d10f (diff) | |
| download | zig-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.zig | 16 |
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, .{ |
