先获取模块中的每个函数,再获取每个函数中的每个BasicBlock,再获取每个BasicBlock中的每条instruction(最常用)
1 | for (Module::iterator FunIt = mod->begin() ; FunIt != mod->end() ; ++FunIt) |
获取Module中的每一个Function
1 | for (Module::iterator FunIt = mod->begin() ; FunIt != mod->end() ; ++FunIt) { |
直接获取Function中的instruction
1 | for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) |
获取Function中的每个BasicBlock,直接打印整个BasicBlock的内容
1 | for (Function::iterator i = FunIt->begin(), e = FunIt->end(); i != e; ++i) { //获取每个函数中的basic block |
声明一个函数
1 | //先创造函数的类型 |
调用一个函数
1 | //BasicBlock::iterator i i是BasicBlock迭代器,通过Instruction* inst = &(*i)获取指令 |
创建一个指向字符串的指针,若已存在则直接返回指针
1 | Constant *CreateWords(Module *mod, string str) |
itoa用sprintf替代
1 | int nValue = 80; |
llvm中调用printf
直接创建一个string类型的字串,然后获取它的地址Value*,调用printf的Function*即可。1
2
3
4
5
6
7
8
9
10
11
12
13Function *print = mod->getFunction("printf");
if(print)
{
CallInst *newcall;
std::vector<Value*> para;
Constant *content = CreateWords(mod, "output something\n");
para.push_back(content);
++i;
newcall = CallInst::Create(print, para, "printRand", i); //CallInst represents a function call,在i指令之前插入一条func_record
newcall->setCallingConv(CallingConv::C);
newcall->setTailCall(false);
--i;
}
从Value*得到int类型数据
1 | Value *oneInt = %add = add nsw i32 %call, %total.06 |
从Value得到string字符串
1 | 有getName方法时: |
从Value得到char* 字符串(由string转char*得到)
1 | string getString = MyIn->getName().str(); |
调用外部的C函数(生成静态库)
LLVM IR和C/C++函数相互调用时的注意事项1
2
3
4
5
6
7
8
9生成静态库.a:
gcc -c printInt.c #生成printInt.o
ar -cr libmyprint.a printInt.o #printInt.o生成静态库libmyprint.a
./RandSum ../../hello.bc #插桩生成.bc文件
llc update.bc -o update.s #将插桩后得到的.bc变为.s
gcc -c update.s -o update.o #将.s变为.o
gcc update.o ../../libmyprint.a -o update #将.o与静态库.a生成可执行文件
./update #运行可执行文件
获取指令的操作数和返回值
1 | int operand_num = inst->getNumOperands(); //获得所有的操作数 |
获取函数的参数的位置和类型
1 | if(myfunc->isVarArg()) |
replaceAllUsesWith
replaceUsesOfWith