7

I want to write an LLVM pass that'll extract the arguments of function calls. If the argument is a constant one, my objective is to recover what that constant is.

The IR looks like

%2 = call noalias i8* @malloc(i64 512) #3

The LLVM pass looks like

bool runOnFunction(Function &F) override {
    for (auto& B : F) {
        for (auto& I : B) {
            if(CallInst* call_inst = dyn_cast<CallInst>(&I)) {
                Function* fn = call_inst->getCalledFunction();
                StringRef fn_name = fn->getName();
                errs() << fn_name << " : " << call_inst->getArgOperand(0) << "\n";
                for(auto arg = fn->arg_begin(); arg != fn->arg_end(); ++arg) {
                    errs() << *arg << "\n";
                }
            }
        }
    }

    return false;
} 

If I run the pass through opt, it produces the following

malloc : 0x3df3f40
i64 %0

What does 0x3df3f40 represent? Instead of i64 and 512, why does it produce i64 and %0?

sherlock
  • 2,397
  • 3
  • 27
  • 44

1 Answers1

9

It is a pointer to Value. Try cast<>ing it to ConstantInt and then calling getValue():

for(auto arg = fn->arg_begin(); arg != fn->arg_end(); ++arg) {
  if(auto* ci = dyn_cast<ConstantInt>(arg))
    errs() << ci->getValue() << "\n";
  errs() << *arg << "\n";
}
arrowd
  • 33,231
  • 8
  • 79
  • 110
  • Could you please clarify? (Expecting more details) – Jithin Pavithran Mar 16 '18 at 11:09
  • @JithinPavithran Updated the answer with example code. – arrowd Mar 16 '18 at 11:12
  • 1
    Thank you for the update. But for `call void @foo(i32** %4, i32** %5)`, it prints `i32** %arg1 i32** %arg2`. Why is it not `%4`? – Jithin Pavithran Mar 16 '18 at 11:20
  • 1
    Things starting with `%` are not constants, these are references to other expressions. Note the difference between `i32 %1` and `i32 1`. – arrowd Mar 16 '18 at 11:22
  • How do I find "to which named variable does `%1` refer to?" – Jithin Pavithran Mar 18 '18 at 10:57
  • If you are using LLVM API, then the reference already points to an instruction. In your case (`call void @foo(i32** %4, i32** %5)`) you need to iterate over its `operand_values()` to get references to instructions corresponding to `%4` and `%5`. – arrowd Mar 18 '18 at 12:40
  • If malloc is the called function, then the cast to ConstantInt can't really fail, and so the if statement in the answer is really redundant ... – OrenIshShalom May 07 '18 at 06:51