我尝试调用 0x40010,但看起来 LLVM 正在用自己的计算修复该地址,是否可以在不创建内联汇编的情况下禁用它?我当前的任务代码是,但结果不是“call 0x40010”
uintptr_t imm = 0x40010;
const GlobalValue* GV = M->getNamedValue(MF->getName());
const MachineInstrBuilder& MIB = BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(X86::CALL64pcrel32));
MIB.addGlobalAddress(GV, imm, MCSymbolRefExpr::VK_None);
MIR 结果
CALL64pcrel32 @test + 262160, implicit $esp, implicit $ssp
当我使用该代码时:
const MachineInstrBuilder& MIB = BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(X86::CALL64pcrel32));
MIB.addImm(imm);
结果是:
CALL64pcrel32 262160, implicit $esp, implicit $ssp
但是当我执行编译时出现错误:断言失败:Target.getSymA() &&“重定位必须引用符号!”
您的代码没有执行
call 0x40010
。您正在发出对当前函数加上偏移量的调用,这就是您的原因:
CALL64pcrel32 @test + 262160, implicit $esp, implicit $ssp
(
addGlobalAddress
添加对当前全局值加上偏移量的引用)。
您不能使用任意立即地址发出
CALL64pcrel32
指令,因为无法确保 pc 相对偏移量适合正常 call
指令所期望的 32 位立即数字段。
最好的方法是在一些未使用的寄存器中具体化地址并使用该指令的调用寄存器变体(
CALL64r
)。