1
1
#include " llvm/Passes/PassPlugin.h"
2
2
#include " llvm/Passes/PassBuilder.h"
3
3
#include " llvm/IR/IRBuilder.h"
4
-
5
4
using namespace llvm ;
6
5
7
6
struct LLVMPass : public PassInfoMixin <LLVMPass> {
@@ -11,37 +10,53 @@ struct LLVMPass : public PassInfoMixin<LLVMPass> {
11
10
PreservedAnalyses LLVMPass::run (Module &M, ModuleAnalysisManager &MAM) {
12
11
LLVMContext &Ctx = M.getContext ();
13
12
IntegerType *Int32Ty = IntegerType::getInt32Ty (Ctx);
14
- FunctionCallee debug_func = M.getOrInsertFunction (" debug" , Int32Ty);
15
- ConstantInt *debug_arg = ConstantInt::get (Int32Ty, 48763 );
13
+
14
+ // Get or insert debug function declaration
15
+ FunctionType *debugTy = FunctionType::get (Type::getVoidTy (Ctx), {Int32Ty}, false );
16
+ FunctionCallee debugFunc = M.getOrInsertFunction (" debug" , debugTy);
17
+ ConstantInt *debugArg = ConstantInt::get (Int32Ty, 48763 );
16
18
17
19
for (auto &F : M) {
18
- if (F.getName () == " main" ) {
19
- IRBuilder<> Builder (&*F.getEntryBlock ().getFirstInsertionPt ());
20
-
21
- // 1. 插入 debug(48763);
22
- Builder.CreateCall (debug_func, debug_arg);
23
-
24
- // 2. 將 argv[1] = "hayaku... motohayaku!"
25
- // 建立常數字串
26
- Constant *StrConstant = Builder.CreateGlobalStringPtr (" hayaku... motohayaku!" , " hayaku_str" );
27
-
28
- // 取得參數 argc 和 argv
29
- Function::arg_iterator args = F.arg_begin ();
30
- Value *argcArg = &*args++;
31
- Value *argvArg = &*args;
32
-
33
- // argv[1] = "hayaku... motohayaku!"
34
- Value *idxs[] = {
35
- ConstantInt::get (Int32Ty, 1 )
36
- };
37
- Value *argv1Ptr = Builder.CreateInBoundsGEP (argvArg, idxs, " argv1_ptr" );
38
- Builder.CreateStore (StrConstant, argv1Ptr);
39
-
40
- // 3. 將 argc 改為 48763
41
- argcArg->replaceAllUsesWith (debug_arg); // 把 argc 的所有使用都替換成 48763
20
+ if (F.getName () != " main" || F.isDeclaration ())
21
+ continue ;
22
+
23
+ errs () << " instrumenting main\n " ;
24
+
25
+ IRBuilder<> Builder (&*F.getEntryBlock ().getFirstInsertionPt ());
26
+
27
+ // Call debug(48763)
28
+ Builder.CreateCall (debugFunc, {debugArg});
29
+
30
+ // Get arguments
31
+ auto ArgIter = F.arg_begin ();
32
+ Argument *argcArg = &*ArgIter++;
33
+ Argument *argvArg = &*ArgIter;
34
+
35
+ // Allocate space and store 48763 to replace argc
36
+ AllocaInst *argcAlloca = Builder.CreateAlloca (Int32Ty, nullptr , " argcVar" );
37
+ Builder.CreateStore (debugArg, argcAlloca);
38
+
39
+ // Replace uses of argcArg with loaded value
40
+ for (auto &BB : F) {
41
+ for (auto &I : BB) {
42
+ for (unsigned i = 0 ; i < I.getNumOperands (); ++i) {
43
+ if (I.getOperand (i) == argcArg) {
44
+ // Load from new variable instead of using original argc
45
+ IRBuilder<> B (&I);
46
+ Value *loadedArgc = B.CreateLoad (Int32Ty, argcAlloca);
47
+ I.setOperand (i, loadedArgc);
48
+ }
49
+ }
50
+ }
42
51
}
43
52
53
+ // Replace argv[1] = "hayaku... motohayaku!"
54
+ Value *index1 = ConstantInt::get (Int32Ty, 1 );
55
+ Value *argv1Ptr = Builder.CreateInBoundsGEP (argvArg->getType ()->getPointerElementType (), argvArg, index1);
56
+ Value *hayakuStr = Builder.CreateGlobalStringPtr (" hayaku... motohayaku!" );
57
+ Builder.CreateStore (hayakuStr, argv1Ptr);
44
58
}
59
+
45
60
return PreservedAnalyses::none ();
46
61
}
47
62
@@ -55,4 +70,3 @@ llvmGetPassPluginInfo() {
55
70
});
56
71
}};
57
72
}
58
-
0 commit comments