利用llvm 源码提供的API,获取IR中函数调用实际参数的名字并打印

在LLVM Pass开发中,由于需要我们可能需要获取IR中函数调用的的实际参数名字,在C语言中函数调用是这样的func1("hello",3),如果在编译器的前端clang中我们想要获取第一个参数"hello",还是比较容易的,但是在当程序被转成IR就类似这样了:

@.str = private unnamed_addr constant [6 x i8] c"hello\00", align 1
//这里还有很多IR指令...
call void @func1(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0), i32 %0)

这样给我们的感觉并不是一目了然,发现第一个参数“hello”变成了i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0),我们只能往上捋一下才能找到hello.但是怎么样在llvm pass中让程序找到呢?下面我们首先来分析一下这两行IR。

   对于第二行IR我们发现func1函数的第一个参数位置变成了i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0),函数调用在llvm中是CallInst,然后我们去llvm源码提供的文档中找这个类如下图所示:

根据该类提供的getArgOperand(0)方法获得第一个参数,Value *op0 = CInst->getArgOperand(0);然后将op0转成ConstantExpr,

auto constExpr = dyn_cast<ConstantExpr>(op0);

这些转换和调用的方法在llvm源码文档中都能查到。然后再次利用getOperand方法该方法的底层实现如下:

   Value *getOperand(unsigned i) const {
     assert(i < NumUserOperands && "getOperand() out of range!");
     return getOperandList()[i];
   }

auto var = dyn_cast<GlobalVariable>(constExpr->getOperand(0));

最后我们转换成ConstantDataArray

auto a5 = dyn_cast<ConstantDataArray>(var->getInitializer());

然后获取String:

auto a6 = a5->getAsString();

完整的函数如下:

  std::string getCallArgName(CallInst *CInst){
    Value *op0 = CInst->getArgOperand(0);
                  if (isa<ConstantExpr>(op0)) {
                 auto constExpr = dyn_cast<ConstantExpr>(op0);
                 if (constExpr->isGEPWithNoNotionalOverIndexing() ){
                        if (constExpr->getOpcode() == Instruction::GetElementPtr){
                                if (isa<GlobalVariable>(constExpr->getOperand(0))){
                                        auto var = dyn_cast<GlobalVariable>(constExpr->getOperand(0));
                                        auto a5 = dyn_cast<ConstantDataArray>(var->getInitializer());
                                        if (a5) {
                                                auto a6 = a5->getAsString();
                                                 return a6;
                                               // errs() << "String: " << a6 << "\n";
                                        }
                                }
                        }
                }
              }
     return NULL;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值