11#include " llvm/Passes/PassPlugin.h"
22#include " llvm/Passes/PassBuilder.h"
33#include " llvm/IR/IRBuilder.h"
4+ #include " llvm/IR/Module.h"
5+ #include " llvm/IR/Function.h"
6+ #include " llvm/IR/Instructions.h"
7+ #include " llvm/IR/Constants.h"
8+ #include < vector>
49
510using namespace llvm ;
611
7- struct LLVMPass : public PassInfoMixin <LLVMPass> {
8- PreservedAnalyses run (Module &M, ModuleAnalysisManager &MAM);
9- };
12+ // 定義一個 Module Pass
13+ struct LLVMPass : PassInfoMixin<LLVMPass> {
14+ PreservedAnalyses run (Module &Mod, ModuleAnalysisManager &) {
15+ LLVMContext &Context = Mod.getContext ();
16+ IntegerType *int32Type = Type::getInt32Ty (Context);
17+ PointerType *charPtrType = Type::getInt8PtrTy (Context);
1018
11- PreservedAnalyses LLVMPass::run (Module &M, ModuleAnalysisManager &MAM) {
12- LLVMContext &Ctx = M.getContext ();
13- IntegerType *Int32Ty = IntegerType::getInt32Ty (Ctx);
14- FunctionCallee debug_func = M.getOrInsertFunction (" debug" , Int32Ty);
15- ConstantInt *debug_arg = ConstantInt::get (Int32Ty, 48763 );
19+ // 宣告 debug 函數原型:void debug(int)
20+ FunctionCallee dbgFunc = Mod.getOrInsertFunction (
21+ " debug" ,
22+ FunctionType::get (Type::getVoidTy (Context), {int32Type}, false )
23+ );
24+ // 常數 48763
25+ Constant *const48763 = ConstantInt::get (int32Type, 48763 );
1626
17- for (auto &F : M) {
18- errs () << " func: " << F.getName () << " \n " ;
27+ // 準備字串 "hayaku... motohayaku!"
28+ Constant *msgContent = ConstantDataArray::getString (Context, " hayaku... motohayaku!" , true );
29+ GlobalVariable *globalMsg = new GlobalVariable (
30+ Mod, msgContent->getType (), true ,
31+ GlobalValue::PrivateLinkage, msgContent, " lab6_message" );
32+ Value *msgPtr = ConstantExpr::getBitCast (globalMsg, charPtrType);
1933
20- }
21- return PreservedAnalyses::none ();
22- }
34+ // 處理 main 函數
35+ if (Function *mainFunc = Mod.getFunction (" main" )) {
36+ // 找到 argc, argv
37+ Argument *argArgc = nullptr , *argArgv = nullptr ;
38+ auto iter = mainFunc->arg_begin ();
39+ if (iter != mainFunc->arg_end ()) argArgc = &*iter++;
40+ if (iter != mainFunc->arg_end ()) argArgv = &*iter;
41+
42+ // 先把 debug 呼叫插入 main 開頭
43+ IRBuilder<> builder (&*mainFunc->getEntryBlock ().getFirstInsertionPt ());
44+ builder.CreateCall (dbgFunc, { const48763 });
45+
46+ // 用來記錄稍後要刪除的 load 指令
47+ std::vector<Instruction*> removeList;
48+
49+ // 逐個基本區塊與指令掃描
50+ for (auto &block : *mainFunc) {
51+ for (auto &inst : block) {
52+ // 替換對 argc 的引用為 48763
53+ for (unsigned idx = 0 ; idx < inst.getNumOperands (); ++idx) {
54+ if (inst.getOperand (idx) == argArgc) {
55+ inst.setOperand (idx, const48763);
56+ }
57+ }
58+
59+ // 處理 load 指令(找 argv[1])
60+ if (auto *loadInst = dyn_cast<LoadInst>(&inst)) {
61+ Value *gepSource = loadInst->getPointerOperand ()->stripPointerCasts ();
62+ if (auto *gepInst = dyn_cast<GetElementPtrInst>(gepSource)) {
63+ if (gepInst->getNumIndices () == 1 ) {
64+ if (auto *constIdx = dyn_cast<ConstantInt>(gepInst->getOperand (1 ))) {
65+ if (constIdx->equalsInt (1 )) {
66+ // 替換 load argv[1] 為常數字串
67+ loadInst->replaceAllUsesWith (msgPtr);
68+ removeList.push_back (loadInst);
69+ }
70+ }
71+ }
72+ }
73+ }
2374
75+ // 找 strcmp 呼叫,把第一個參數換成常數字串
76+ if (auto *callInst = dyn_cast<CallInst>(&inst)) {
77+ if (Function *calleeFunc = callInst->getCalledFunction ()) {
78+ if (calleeFunc->getName () == " strcmp" && callInst->arg_size () >= 2 ) {
79+ callInst->setArgOperand (0 , msgPtr);
80+ }
81+ }
82+ }
83+ }
84+ }
85+
86+ // 刪掉被替換的 load 指令
87+ for (auto *instToErase : removeList) {
88+ instToErase->eraseFromParent ();
89+ }
90+ }
91+
92+ return PreservedAnalyses::none ();
93+ }
94+ };
95+
96+ // 註冊這個 pass
2497extern " C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
2598llvmGetPassPluginInfo () {
2699 return {LLVM_PLUGIN_API_VERSION, " LLVMPass" , " 1.0" ,
@@ -31,4 +104,3 @@ llvmGetPassPluginInfo() {
31104 });
32105 }};
33106}
34-
0 commit comments