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>
94
105using namespace llvm ;
116
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);
18-
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 );
26-
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);
33-
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- }
7+ struct LLVMPass : public PassInfoMixin <LLVMPass> {
8+ PreservedAnalyses run (Module &M, ModuleAnalysisManager &MAM);
9+ };
7410
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- }
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 );
8516
86- // 刪掉被替換的 load 指令
87- for (auto *instToErase : removeList) {
88- instToErase->eraseFromParent ();
89- }
90- }
17+ for (auto &F : M) {
18+ errs () << " func: " << F.getName () << " \n " ;
9119
92- return PreservedAnalyses::none ();
93- }
94- };
20+ }
21+ return PreservedAnalyses::none ();
22+ }
9523
96- // 註冊這個 pass
9724extern " C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
9825llvmGetPassPluginInfo () {
9926 return {LLVM_PLUGIN_API_VERSION, " LLVMPass" , " 1.0" ,
@@ -104,3 +31,4 @@ llvmGetPassPluginInfo() {
10431 });
10532 }};
10633}
34+
0 commit comments