【问题标题】:Is there any way to get function-name of indirect call from CallInst in LLVM IR有什么方法可以从 LLVM IR 中的 CallInst 获取间接调用的函数名
【发布时间】:2022-11-14 16:20:21
【问题描述】:

我正在解决一个问题,以从 LLVM IR 中的 CallInst 中提取间接调用的函数名称。有没有办法获得间接调用的函数名?基本上,我需要找到所有被调用的函数,包括通过函数指针调用的函数。

C代码:

#include<stdio.h>

void (*fun_ptr)(int);

void fun(int a)
{
     printf("Value of a: %d\n", a);
}

int func_3(int a, int b)
{
    (*fun_ptr)(a+b);
}

int main ()
{
    fun_ptr = fun;
    func_3(4, 5);
}

LLVM 红外:

 30   %retval = alloca i32, align 4
 31   %a.addr = alloca i32, align 4
 32   %b.addr = alloca i32, align 4
 33   store i32 %a, i32* %a.addr, align 4
 34   store i32 %b, i32* %b.addr, align 4
 35   %3 = load void (i32)*, void (i32)** @fun_ptr, align 8 ;Can we retrieve the value of @fun_ptr
 36   %4 = load i32, i32* %a.addr, align 4
 37   %5 = load i32, i32* %b.addr, align 4
 38   %add = add nsw i32 %4, %5
 39   call void %3(i32 %add) ;Indirect Call
 40   %6 = load i32, i32* %retval, align 4
 41   ret i32 %6

LLVM 通行证:

for(Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
{
    for(BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE; ++BI){
        if (CallInst *CI = dyn_cast<CallInst>(BI)) {
          CF = CI->getCalledFunction();
          if (CF) {
            // Direct function call
            std::string fName = CF->getName().str(); //Name of callsite function
          } else {
            //Indirect function call (Via Function pointer)
            //Can we get the function name? or Get the address of function pointer and resolve it using symbol table offline?
          }
        }
    }
}

我能够找到直接调用的函数名称并检测到间接函数调用。

【问题讨论】:

    标签: llvm


    【解决方案1】:

    不。

    根据生成 LLVM IR 的内容,您可能很幸运,并且拥有 !callees 元数据,它告诉您来自调用站点的一组可能的调用函数。 https://llvm.org/docs/LangRef.html#callees-metadata

    如果您能证明它们的地址未被占用,或者如果您分析它是如何被占用并通过一些复杂的自定义过程间数据流分析表明函数地址不可能流入此调用站点,则您可以消除一些函数。

    此外,如果您认为“调用函数将是未定义的行为”与不调用函数相同,那么您可以将可能的被调用者集限制为不存在 ABI 不匹配的被调用者集。

    执行此操作时,请考虑您可以 dlopen() 和 dlsym() 大多数程序并直接使用它们的功能而无需通过它们的 main()。就此而言,正在编译的目标文件是主程序还是共享对象的一部分?如果用户正在使用 ELF 符号插入(将程序中的一个函数替换为另一个函数)怎么办?还是 JIT?任何其链接允许从另一个目标文件访问的函数都应被视为“获取地址并传播给所有人”,否则我可以设计一个程序和情况,而您的分析将不正确。

    一般来说,没有办法知道。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-21
      • 1970-01-01
      • 1970-01-01
      • 2017-03-14
      • 2019-04-01
      • 1970-01-01
      相关资源
      最近更新 更多