Skip to content

Commit dd30cbb

Browse files
authored
Merge pull request #429 from nanlioniya/lab6
[LAB6] 313553005
2 parents 41c7445 + 1739af6 commit dd30cbb

1 file changed

Lines changed: 98 additions & 18 deletions

File tree

lab6/llvm-pass.so.cc

Lines changed: 98 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,114 @@
11
#include "llvm/Passes/PassPlugin.h"
22
#include "llvm/Passes/PassBuilder.h"
33
#include "llvm/IR/IRBuilder.h"
4+
#include "llvm/IR/Instructions.h"
5+
#include "llvm/Support/raw_ostream.h"
6+
#include "llvm/IR/Constants.h"
7+
#include "llvm/IR/Function.h"
8+
#include "llvm/IR/BasicBlock.h"
9+
#include "llvm/IR/Value.h"
410

511
using namespace llvm;
612

13+
namespace {
714
struct LLVMPass : public PassInfoMixin<LLVMPass> {
8-
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
9-
};
10-
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);
16-
17-
for (auto &F : M) {
18-
errs() << "func: " << F.getName() << "\n";
15+
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM) {
16+
// 尋找 main 函數
17+
Function *MainFunc = M.getFunction("main");
18+
if (!MainFunc) {
19+
return PreservedAnalyses::all();
20+
}
1921

22+
LLVMContext &Ctx = M.getContext();
23+
24+
// 創建全局字符串常量 "deubg mode"
25+
Constant *DebugStr = ConstantDataArray::getString(Ctx, "deubg mode", true);
26+
GlobalVariable *DebugGV = new GlobalVariable(
27+
M, DebugStr->getType(), true, GlobalValue::PrivateLinkage, DebugStr, "debug_str");
28+
29+
// 創建全局字符串常量 "hayaku... motohayaku!"
30+
Constant *HayakuStr = ConstantDataArray::getString(Ctx, "hayaku... motohayaku!", true);
31+
GlobalVariable *HayakuGV = new GlobalVariable(
32+
M, HayakuStr->getType(), true, GlobalValue::PrivateLinkage, HayakuStr, "hayaku_str");
33+
34+
// 獲取 printf 函數
35+
FunctionType *PrintfTy = FunctionType::get(
36+
Type::getInt32Ty(Ctx), Type::getInt8PtrTy(Ctx), true);
37+
FunctionCallee PrintfFunc = M.getOrInsertFunction("printf", PrintfTy);
38+
39+
// 在 main 函數入口處插入代碼
40+
BasicBlock &EntryBB = MainFunc->getEntryBlock();
41+
IRBuilder<> Builder(&EntryBB, EntryBB.getFirstInsertionPt());
42+
43+
// 打印 "deubg mode"
44+
Value *FormatStr = Builder.CreateGlobalStringPtr("%s\n", "format");
45+
Value *GEPIndices[] = {
46+
ConstantInt::get(Type::getInt32Ty(Ctx), 0),
47+
ConstantInt::get(Type::getInt32Ty(Ctx), 0)
48+
};
49+
Value *DebugPtr = Builder.CreateInBoundsGEP(DebugGV->getValueType(), DebugGV, GEPIndices, "debug_str_ptr");
50+
Builder.CreateCall(PrintfFunc, {FormatStr, DebugPtr});
51+
52+
// 創建常量 48763 (替換 argc)
53+
ConstantInt *MagicNum = ConstantInt::get(Type::getInt32Ty(Ctx), 48763);
54+
55+
// 獲取 main 函數參數
56+
auto ArgIt = MainFunc->arg_begin();
57+
Argument *ArgC = &*ArgIt; // 第一個參數是 argc
58+
++ArgIt;
59+
Argument *ArgV = &*ArgIt; // 第二個參數是 argv
60+
61+
// 創建臨時變量存儲 48763
62+
AllocaInst *TempArgC = Builder.CreateAlloca(Type::getInt32Ty(Ctx), nullptr, "temp_argc");
63+
Builder.CreateStore(MagicNum, TempArgC);
64+
65+
// 替換所有 argc 的使用
66+
for (auto UI = ArgC->use_begin(), UE = ArgC->use_end(); UI != UE;) {
67+
Use &U = *UI++;
68+
User *User = U.getUser();
69+
70+
// 替換為從臨時變量加載的值
71+
Value *LoadedArgC = Builder.CreateLoad(Type::getInt32Ty(Ctx), TempArgC, "loaded_argc");
72+
U.set(LoadedArgC);
73+
}
74+
75+
// 修改 argv[1]
76+
// 創建指向 "hayaku... motohayaku!" 的指針
77+
Value *HayakuPtr = Builder.CreateInBoundsGEP(HayakuGV->getValueType(), HayakuGV, GEPIndices, "hayaku_str_ptr");
78+
79+
// 計算 argv[1] 的地址
80+
Value *IndexOne = ConstantInt::get(Type::getInt32Ty(Ctx), 1);
81+
Value *ArgVPtr = Builder.CreateGEP(ArgV->getType()->getPointerElementType(), ArgV, IndexOne, "argv_1_ptr");
82+
83+
// 將 "hayaku... motohayaku!" 存入 argv[1]
84+
Builder.CreateStore(HayakuPtr, ArgVPtr);
85+
86+
return PreservedAnalyses::none();
2087
}
21-
return PreservedAnalyses::none();
88+
};
2289
}
2390

24-
extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
91+
// 註冊 Pass
92+
extern "C" LLVM_ATTRIBUTE_WEAK ::llvm::PassPluginLibraryInfo
2593
llvmGetPassPluginInfo() {
26-
return {LLVM_PLUGIN_API_VERSION, "LLVMPass", "1.0",
94+
return {
95+
LLVM_PLUGIN_API_VERSION, "LLVMPass", LLVM_VERSION_STRING,
2796
[](PassBuilder &PB) {
28-
PB.registerOptimizerLastEPCallback(
29-
[](ModulePassManager &MPM, OptimizationLevel OL) {
97+
PB.registerPipelineParsingCallback(
98+
[](StringRef Name, ModulePassManager &MPM,
99+
ArrayRef<PassBuilder::PipelineElement>) {
100+
if (Name == "llvm-pass") {
101+
MPM.addPass(LLVMPass());
102+
return true;
103+
}
104+
return false;
105+
});
106+
107+
// 註冊為優化器的開始步驟
108+
PB.registerPipelineStartEPCallback(
109+
[](ModulePassManager &MPM, OptimizationLevel) {
30110
MPM.addPass(LLVMPass());
31111
});
32-
}};
112+
}
113+
};
33114
}
34-

0 commit comments

Comments
 (0)