diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2024-08-12 22:51:33 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2024-08-13 13:30:24 +0200 |
| commit | e3f6ebaea94bb11c2e990e1fa17b48e51e598b5c (patch) | |
| tree | b8114bfb6d2eef489674bcc3108480583d85ef29 /src/arch/x86_64/CodeGen.zig | |
| parent | 16abf51ceef2ba2ebb38f27270af676387435f05 (diff) | |
| download | zig-e3f6ebaea94bb11c2e990e1fa17b48e51e598b5c.tar.gz zig-e3f6ebaea94bb11c2e990e1fa17b48e51e598b5c.zip | |
x86_64+elf: fix jump table indirection for functions
Diffstat (limited to 'src/arch/x86_64/CodeGen.zig')
| -rw-r--r-- | src/arch/x86_64/CodeGen.zig | 46 |
1 files changed, 19 insertions, 27 deletions
diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index dede09fc71..f6fbc67ff1 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -12311,33 +12311,25 @@ fn genCall(self: *Self, info: union(enum) { const zo = elf_file.zigObjectPtr().?; const sym_index = try zo.getOrCreateMetadataForNav(elf_file, func.owner_nav); if (self.mod.pic) { - // const callee_reg: Register = switch (resolved_cc) { - // .SysV => callee: { - // if (!fn_info.is_var_args) break :callee .rax; - // const param_regs = abi.getCAbiIntParamRegs(resolved_cc); - // break :callee if (call_info.gp_count < param_regs.len) - // param_regs[call_info.gp_count] - // else - // .r10; - // }, - // .Win64 => .rax, - // else => unreachable, - // }; - // TODO convert to near jump - try self.asmMemory(.{ ._, .call }, .{ - .base = .{ .reloc = .{ - .atom_index = try self.owner.getSymbolIndex(self), - .sym_index = sym_index, - } }, - .mod = .{ .rm = .{ .size = .qword } }, - }); - // try self.genSetReg( - // callee_reg, - // Type.usize, - // .{ .load_symbol = .{ .sym = sym_index } }, - // .{}, - // ); - // try self.asmRegister(.{ ._, .call }, callee_reg); + const callee_reg: Register = switch (resolved_cc) { + .SysV => callee: { + if (!fn_info.is_var_args) break :callee .rax; + const param_regs = abi.getCAbiIntParamRegs(resolved_cc); + break :callee if (call_info.gp_count < param_regs.len) + param_regs[call_info.gp_count] + else + .r10; + }, + .Win64 => .rax, + else => unreachable, + }; + try self.genSetReg( + callee_reg, + Type.usize, + .{ .lea_symbol = .{ .sym = sym_index } }, + .{}, + ); + try self.asmRegister(.{ ._, .call }, callee_reg); } else try self.asmMemory(.{ ._, .call }, .{ .base = .{ .reloc = .{ .atom_index = try self.owner.getSymbolIndex(self), |
