[SOLVED] Address of getCalledValue vs getCalledFunction LLVM

Issue

I’m trying to get the address of the called operand in a direct function call. I found two plausible ways of doing so, but to my surprise, they’re not equivalent.

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);
        ...

Why does the address of the called value differ from the address of the function cast to a value? I’m using llvm-10.0.0.

Solution

There seems to be a problem in the way you’re recovering the address of your pointers (through what I assume is a std::stringstream).

Consider these examples: https://godbolt.org/z/h5cbzco93 vs https://godbolt.org/z/rh18PjrsM .

If you compare the addresses direclty your code should have worked:

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);
        ...

Furthermore, if you check the implementation of CallBase::getCalledValue and CallBase::getCalledFunction you’ll see that they fall-back to the same method call. The only difference is dyn_cast_or_null that will return null unless the called operand is a Function.

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

Answered By – jmmartinez

Answer Checked By – Jay B. (BugsFixing Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *