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)