getCalledValue 与 getCalledFunction LLVM 的地址

Address of getCalledValue vs getCalledFunction LLVM

我试图在直接函数调用中获取被调用操作数的地址。我找到了两种可行的方法,但令我惊讶的是,它们并不等同。

if (const auto call = dyn_cast<CallInst>(&inst)) {
    Addr calledAddr;
   
    const auto called = call->getCalledValue();
  
    // Get address of called value
    ss << called;
    ss >> std::hex >> calledAddr;
  
    // If it's a direct call
    if (const auto f = call->getCalledFunction()) {
        Addr funAddr;
 
        ss << cast<llvm::Value>(f);
        ss >> std::hex >> funAddr;
  
        // This assertion fails!
        assert (calledAddr == funAddr);
        ...

为什么调用值的地址与转换为值的函数的地址不同?我正在使用 llvm-10.0.0.

您恢复指针地址的方式似乎有问题(通过我假设的 std::stringstream)。

考虑这些例子:https://godbolt.org/z/h5cbzco93 vs https://godbolt.org/z/rh18PjrsM .

如果您直接比较地址,您的代码应该有效:

if (const CallInst* call = dyn_cast<CallInst>(&inst)) {
    const Value* called = call->getCalledValue();
  
    if (const Function* f = call->getCalledFunction()) {
        // compare direclty the address pointed by called and by f
        assert (called == f);
        ...

此外,如果您检查 CallBase::getCalledValueCallBase::getCalledFunction 的实现,您会发现它们 fall-back 调用了相同的方法。唯一的区别是 dyn_cast_or_null 将 return null 除非被调用的操作数是 Function.

Value *getCalledValue() const { return getCalledOperand(); }
...
Function *getCalledFunction() const {
  return dyn_cast_or_null<Function>(getCalledOperand());
}