|
1 | 1 | #include "llvm/Passes/PassPlugin.h"
|
2 | 2 | #include "llvm/Passes/PassBuilder.h"
|
3 | 3 | #include "llvm/IR/IRBuilder.h"
|
| 4 | +#include "llvm/IR/Constants.h" |
| 5 | +#include "llvm/IR/GlobalVariable.h" |
| 6 | + |
4 | 7 | using namespace llvm;
|
| 8 | + |
5 | 9 | struct LLVMPass : public PassInfoMixin<LLVMPass> {
|
6 | 10 | PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
|
7 | 11 | };
|
8 | 12 | PreservedAnalyses LLVMPass::run(Module &M, ModuleAnalysisManager &MAM) {
|
9 | 13 | LLVMContext &Ctx = M.getContext();
|
10 | 14 | IntegerType *Int32Ty = IntegerType::getInt32Ty(Ctx);
|
| 15 | + PointerType *Int8PtrTy = Type::getInt8PtrTy(Ctx); |
11 | 16 |
|
12 |
| - FunctionType *debugTy = FunctionType::get(Type::getVoidTy(Ctx), {Int32Ty}, false); |
13 |
| - FunctionCallee debug_func = M.getOrInsertFunction("debug", debugTy); |
| 17 | + FunctionType *DebugTy = FunctionType::get(Type::getVoidTy(Ctx), {Int32Ty}, false); |
| 18 | + FunctionCallee debug_func = M.getOrInsertFunction("debug", DebugTy); |
14 | 19 | ConstantInt *debug_arg = ConstantInt::get(Int32Ty, 48763);
|
15 | 20 |
|
16 |
| - for (auto &F : M) { |
17 |
| - //errs() << "func: " << F.getName() << "\n"; |
18 |
| - if(F.getName() != "main" || F.isDeclaration()) |
19 |
| - continue; |
| 21 | + Constant *StrConstant = ConstantDataArray::getString(Ctx, "hayaku... motohayaku!", true); |
| 22 | + GlobalVariable *StrVar = new GlobalVariable(M, StrConstant->getType(), true, |
| 23 | + GlobalValue::PrivateLinkage, StrConstant, ".str.hayaku"); |
| 24 | + Constant *Zero = ConstantInt::get(Int32Ty, 0); |
| 25 | + Constant *Indices[] = {Zero, Zero}; |
| 26 | + Constant *StrPtr = ConstantExpr::getGetElementPtr(StrConstant->getType(), StrVar, Indices); |
20 | 27 |
|
21 |
| - errs() << "func: " << F.getName() << "\n"; |
22 |
| - |
23 |
| - auto ArgIter = F.arg_begin(); |
24 |
| - Argument *argcArg = &*ArgIter++; |
25 |
| - Argument *argvArg = &*ArgIter; |
| 28 | + for (auto &F : M) { |
| 29 | + if (F.getName() != "main") |
| 30 | + continue; |
26 | 31 |
|
27 |
| - Instruction *InsertPt = &*F.getEntryBlock().getFirstInsertionPt(); |
28 |
| - IRBuilder<> Builder(InsertPt); |
| 32 | + errs() << "Instrumenting function: " << F.getName() << "\n"; |
| 33 | + IRBuilder<> Builder(&*F.getEntryBlock().getFirstInsertionPt()); |
29 | 34 |
|
30 | 35 | Builder.CreateCall(debug_func, {debug_arg});
|
31 | 36 |
|
32 |
| - for(auto &BB : F){ |
33 |
| - for(auto &I : BB){ |
34 |
| - for(unsigned i = 0; i < I.getNumOperands(); ++i){ |
35 |
| - if(I.getOperand(i) == argcArg){ |
36 |
| - I.setOperand(i, debug_arg); |
37 |
| - } |
38 |
| - } |
39 |
| - } |
40 |
| - } |
41 |
| - |
42 |
| - Value *idx1 = ConstantInt::get(Int32Ty, 1); |
43 |
| - Value *argv1Ptr = Builder.CreateInBoundsGEP(argvArg->getType()->getPointerElementType(), argvArg, idx1); |
44 |
| - Value *strPtr = Builder.CreateGlobalStringPtr("hayaku... motohayaku!"); |
45 |
| - Builder.CreateStore(strPtr, argv1Ptr); |
| 37 | + auto ArgIter = F.arg_begin(); |
| 38 | + Argument *argcArg = ArgIter++; |
| 39 | + Argument *argvArg = ArgIter; |
46 | 40 |
|
47 |
| - //Builder.CreateStore(debug_arg, argcArg); |
| 41 | + Value *Argv1Ptr = Builder.CreateGEP(Int8PtrTy, argvArg, ConstantInt::get(Int32Ty, 1)); |
| 42 | + Builder.CreateStore(StrPtr, Argv1Ptr); |
48 | 43 |
|
| 44 | + argcArg->replaceAllUsesWith(debug_arg); |
49 | 45 | }
|
| 46 | + |
50 | 47 | return PreservedAnalyses::none();
|
51 | 48 | }
|
| 49 | + |
52 | 50 | extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
|
53 | 51 | llvmGetPassPluginInfo() {
|
54 | 52 | return {LLVM_PLUGIN_API_VERSION, "LLVMPass", "1.0",
|
|
0 commit comments