LLVM 如何检测和忽略库(内置)函数?
LLVM how to detect and ignore library(built-in) functions?
我正在尝试编写一个简单的 LLVM pass,目标如下:
- 找到所有
call
指令。
- 在被调用函数中插入一个我写的外部函数。
例如,假设我有以下示例程序:
#include <stdio.h>
#include <stdlib.h>
int times_two(int val);
int main(int argc, char** argv) {
int arg_1 = atoi(argv[1]);
char test_str[] = "Test String";
int res = times_two(arg_1);
printf("%d", res);
return 0;
}
int times_two(int val) {
// ----> INSERT SOME EXTERNAL FUNCTION HERE <----
return val * 2;
}
这是我的 LLVM 工具的一部分:
/* Begin instrumentation
--------------------- */
for (auto &F : M)
{
for (auto &B : F)
{
for (auto &I : B)
{
IRBuilder<> builder(&I);
// Now we have reached a 'call' instruction
if (auto *CallInstr = dyn_cast<CallInst>(&I))
{
// Cast into Function pointer
Function *called_func = CallInstr->getCalledFunction();
errs() << called_func->getName() << "\n";
// loop into the function, getFirstInstruction, do stuff and break.
for (auto &bb_in_func : *called_func)
{
// Set an Insert point at the first
// line of the external function
BasicBlock::iterator insert_point = bb_in_func.getFirstInsertionPt();
builder.SetInsertPoint(&bb_in_func, insert_point);
// Make an external call
builder.CreateCall(extern1);
break;
}
}
}
}
}
但是,当我遍历模块中的所有函数时,这个函数列表似乎也包含内置函数。在上述情况下,我得到以下信息:
atoi
llvm.memcpy.p0i8.p0i8.i64
times_two
printf
如何忽略这些内置函数,只考虑times_two?
我想我已经弄明白了。我们想用 getLibFunc()
. This 例子做一些非常相似的事情。
就我而言,我必须按如下方式更新 LLVM 工具:
/* Include this:
#include "llvm/Analysis/TargetLibraryInfo.h"
#include <bits/stdc++.h>
*/
bool Example::runOnModule(Module &M)
{
const TargetLibraryInfo *TLI;
LibFunc inbuilt_func;
std::set<StringRef> builtins;
/* Gather all built-in functions
--------------------- */
for (auto &F : M)
{
if (TLI->getLibFunc(F, inbuilt_func))
builtins.insert(F.getFunction().getName());
}
/* Begin instrumentation
--------------------- */
for (auto &F : M)
{
for (auto &B : F)
{
for (auto &I : B)
{
IRBuilder<> builder(&I);
// Now we have reached a 'call' instruction
if (auto *CallInstr = dyn_cast<CallInst>(&I))
{
// Cast into Function pointer
Function *called_func = CallInstr->getCalledFunction();
StringRef func_name = called_func->getName();
// This line checks to see if the function is not a builtin-function
if (builtins.count(func_name)==0)
{
// loop into the function, getFirstInstruction, do stuff and break.
for (auto &bb_in_func : *called_func)
{
// Set an Insert point at the first
// line of the external function
BasicBlock::iterator insert_point = bb_in_func.getFirstInsertionPt();
builder.SetInsertPoint(&bb_in_func, insert_point);
// Make an external call
builder.CreateCall(extern1);
break;
}
}
}
}
}
}
}
我正在尝试编写一个简单的 LLVM pass,目标如下:
- 找到所有
call
指令。 - 在被调用函数中插入一个我写的外部函数。
例如,假设我有以下示例程序:
#include <stdio.h>
#include <stdlib.h>
int times_two(int val);
int main(int argc, char** argv) {
int arg_1 = atoi(argv[1]);
char test_str[] = "Test String";
int res = times_two(arg_1);
printf("%d", res);
return 0;
}
int times_two(int val) {
// ----> INSERT SOME EXTERNAL FUNCTION HERE <----
return val * 2;
}
这是我的 LLVM 工具的一部分:
/* Begin instrumentation
--------------------- */
for (auto &F : M)
{
for (auto &B : F)
{
for (auto &I : B)
{
IRBuilder<> builder(&I);
// Now we have reached a 'call' instruction
if (auto *CallInstr = dyn_cast<CallInst>(&I))
{
// Cast into Function pointer
Function *called_func = CallInstr->getCalledFunction();
errs() << called_func->getName() << "\n";
// loop into the function, getFirstInstruction, do stuff and break.
for (auto &bb_in_func : *called_func)
{
// Set an Insert point at the first
// line of the external function
BasicBlock::iterator insert_point = bb_in_func.getFirstInsertionPt();
builder.SetInsertPoint(&bb_in_func, insert_point);
// Make an external call
builder.CreateCall(extern1);
break;
}
}
}
}
}
但是,当我遍历模块中的所有函数时,这个函数列表似乎也包含内置函数。在上述情况下,我得到以下信息:
atoi
llvm.memcpy.p0i8.p0i8.i64
times_two
printf
如何忽略这些内置函数,只考虑times_two?
我想我已经弄明白了。我们想用 getLibFunc()
. This 例子做一些非常相似的事情。
就我而言,我必须按如下方式更新 LLVM 工具:
/* Include this:
#include "llvm/Analysis/TargetLibraryInfo.h"
#include <bits/stdc++.h>
*/
bool Example::runOnModule(Module &M)
{
const TargetLibraryInfo *TLI;
LibFunc inbuilt_func;
std::set<StringRef> builtins;
/* Gather all built-in functions
--------------------- */
for (auto &F : M)
{
if (TLI->getLibFunc(F, inbuilt_func))
builtins.insert(F.getFunction().getName());
}
/* Begin instrumentation
--------------------- */
for (auto &F : M)
{
for (auto &B : F)
{
for (auto &I : B)
{
IRBuilder<> builder(&I);
// Now we have reached a 'call' instruction
if (auto *CallInstr = dyn_cast<CallInst>(&I))
{
// Cast into Function pointer
Function *called_func = CallInstr->getCalledFunction();
StringRef func_name = called_func->getName();
// This line checks to see if the function is not a builtin-function
if (builtins.count(func_name)==0)
{
// loop into the function, getFirstInstruction, do stuff and break.
for (auto &bb_in_func : *called_func)
{
// Set an Insert point at the first
// line of the external function
BasicBlock::iterator insert_point = bb_in_func.getFirstInsertionPt();
builder.SetInsertPoint(&bb_in_func, insert_point);
// Make an external call
builder.CreateCall(extern1);
break;
}
}
}
}
}
}
}