[SOLVED] Address of getCalledValue vs getCalledFunction LLVM


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.


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 *