aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2023-11-03 11:55:43 +0100
committerJakub Konka <kubkon@jakubkonka.com>2023-11-04 09:12:35 +0100
commit912a774a1519756dd68e514e5b5ac3e4e6f4e511 (patch)
treecdb9be32b5eff80c1cc475a6cce5280f7baebbaf
parent33a0a72e87bd01ce6dbd10fa327c74168a0166db (diff)
downloadzig-912a774a1519756dd68e514e5b5ac3e4e6f4e511.tar.gz
zig-912a774a1519756dd68e514e5b5ac3e4e6f4e511.zip
x86_64: rewrite call r/m64 to call rel32 for .got.zig refs when object
-rw-r--r--src/arch/x86_64/Emit.zig30
-rw-r--r--src/arch/x86_64/Lower.zig4
2 files changed, 22 insertions, 12 deletions
diff --git a/src/arch/x86_64/Emit.zig b/src/arch/x86_64/Emit.zig
index a1a2e2cb1c..db951a71a2 100644
--- a/src/arch/x86_64/Emit.zig
+++ b/src/arch/x86_64/Emit.zig
@@ -109,17 +109,25 @@ pub fn emitMir(emit: *Emit) Error!void {
.r_addend = -4,
});
} else {
- const r_type: u32 = if (sym.flags.needs_zig_got and !is_obj_or_static_lib)
- link.File.Elf.R_X86_64_ZIG_GOT32
- else if (sym.flags.needs_got)
- std.elf.R_X86_64_GOT32
- else
- std.elf.R_X86_64_32;
- try atom.addReloc(elf_file, .{
- .r_offset = end_offset - 4,
- .r_info = (@as(u64, @intCast(data.sym_index)) << 32) | r_type,
- .r_addend = 0,
- });
+ if (lowered_inst.encoding.mnemonic == .call and sym.flags.needs_zig_got and is_obj_or_static_lib) {
+ try atom.addReloc(elf_file, .{
+ .r_offset = end_offset - 4,
+ .r_info = (@as(u64, @intCast(data.sym_index)) << 32) | std.elf.R_X86_64_PC32,
+ .r_addend = -4,
+ });
+ } else {
+ const r_type: u32 = if (sym.flags.needs_zig_got and !is_obj_or_static_lib)
+ link.File.Elf.R_X86_64_ZIG_GOT32
+ else if (sym.flags.needs_got)
+ std.elf.R_X86_64_GOT32
+ else
+ std.elf.R_X86_64_32;
+ try atom.addReloc(elf_file, .{
+ .r_offset = end_offset - 4,
+ .r_info = (@as(u64, @intCast(data.sym_index)) << 32) | r_type,
+ .r_addend = 0,
+ });
+ }
}
} else unreachable,
.linker_got,
diff --git a/src/arch/x86_64/Lower.zig b/src/arch/x86_64/Lower.zig
index 913e55f00a..621d61d7f8 100644
--- a/src/arch/x86_64/Lower.zig
+++ b/src/arch/x86_64/Lower.zig
@@ -356,7 +356,9 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
},
else => unreachable,
} else switch (mnemonic) {
- .call => .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
+ .call => break :op if (is_obj_or_static_lib and needsZigGot(sym, lower.bin_file)) .{
+ .imm = Immediate.s(0),
+ } else .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
.base = .{ .reg = .ds },
}) },
.lea => {