Skip to content

Commit 7fae134

Browse files
authored
Merge pull request #440 from sss28072637/lab6
[LAB6] 313560007
2 parents 2f88cd5 + f578fdc commit 7fae134

File tree

1 file changed

+75
-21
lines changed

1 file changed

+75
-21
lines changed

lab6/llvm-pass.so.cc

Lines changed: 75 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,88 @@
11
#include "llvm/Passes/PassPlugin.h"
22
#include "llvm/Passes/PassBuilder.h"
33
#include "llvm/IR/IRBuilder.h"
4-
4+
#include "llvm/IR/Module.h"
5+
#include "llvm/IR/Function.h"
6+
#include "llvm/IR/Instructions.h"
7+
#include "llvm/IR/Constants.h"
58
using namespace llvm;
69

7-
struct LLVMPass : public PassInfoMixin<LLVMPass> {
8-
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
9-
};
10+
namespace {
11+
12+
struct Lab6FinalPass : PassInfoMixin<Lab6FinalPass> {
13+
PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
14+
LLVMContext &C = M.getContext();
15+
auto *i32 = Type::getInt32Ty(C);
16+
auto *i8ptr = Type::getInt8PtrTy(C);
17+
18+
// 宣告 debug 函數與 48763 常數
19+
auto debugTy = FunctionType::get(Type::getVoidTy(C), {i32}, false);
20+
auto debugFn = M.getOrInsertFunction("debug", debugTy);
21+
auto const48763 = ConstantInt::get(i32, 48763);
22+
23+
// 建立常數字串 "hayaku... motohayaku!"
24+
auto strConst = ConstantDataArray::getString(C, "hayaku... motohayaku!", true);
25+
auto *gstr = new GlobalVariable(M, strConst->getType(), true,
26+
GlobalValue::PrivateLinkage, strConst, "haya_str");
27+
auto strPtr = ConstantExpr::getBitCast(gstr, i8ptr);
28+
29+
// 找到 main 函式
30+
Function *main = M.getFunction("main");
31+
if (!main) return PreservedAnalyses::all();
32+
33+
// IRBuilder 插入點設在 entry block 開頭
34+
IRBuilder<> B(&*main->getEntryBlock().getFirstInsertionPt());
1035

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);
36+
// 呼叫 debug(48763)
37+
B.CreateCall(debugFn, const48763);
1638

17-
for (auto &F : M) {
18-
errs() << "func: " << F.getName() << "\n";
39+
// 抓取 main 的參數
40+
Argument *argc = nullptr, *argv = nullptr;
41+
auto it = main->arg_begin();
42+
if (it != main->arg_end()) argc = it++;
43+
if (it != main->arg_end()) argv = it;
1944

45+
// 覆寫 argv[1] 的記憶體:argv[1] = strPtr
46+
Value *idx[] = { ConstantInt::get(i32, 1) };
47+
Value *argv1Ptr = B.CreateInBoundsGEP(i8ptr, argv, idx);
48+
B.CreateStore(strPtr, argv1Ptr);
49+
50+
// 遍歷整個函數,修改 argc 為常數,並處理 strcmp
51+
for (auto &BB : *main) {
52+
for (auto &I : BB) {
53+
// 修改使用 argc 的地方
54+
for (unsigned i = 0; i < I.getNumOperands(); ++i) {
55+
if (I.getOperand(i) == argc) {
56+
I.setOperand(i, const48763);
57+
}
58+
}
59+
60+
// 如果遇到 strcmp(argv[1], ...) 則強制修改 argv[1] 為我們的字串
61+
if (auto *call = dyn_cast<CallInst>(&I)) {
62+
if (Function *callee = call->getCalledFunction()) {
63+
if (callee->getName() == "strcmp" && call->arg_size() >= 2) {
64+
call->setArgOperand(0, strPtr);
65+
}
66+
}
67+
}
68+
}
69+
}
70+
71+
return PreservedAnalyses::none();
2072
}
21-
return PreservedAnalyses::none();
22-
}
73+
};
74+
75+
} // namespace
2376

24-
extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
25-
llvmGetPassPluginInfo() {
26-
return {LLVM_PLUGIN_API_VERSION, "LLVMPass", "1.0",
77+
// 註冊 Pass 到 New Pass Manager
78+
extern "C" LLVM_ATTRIBUTE_WEAK ::llvm::PassPluginLibraryInfo llvmGetPassPluginInfo() {
79+
return {
80+
LLVM_PLUGIN_API_VERSION, "Lab6FinalPass", "v1.0",
2781
[](PassBuilder &PB) {
28-
PB.registerOptimizerLastEPCallback(
29-
[](ModulePassManager &MPM, OptimizationLevel OL) {
30-
MPM.addPass(LLVMPass());
82+
PB.registerPipelineStartEPCallback(
83+
[](ModulePassManager &MPM, OptimizationLevel) {
84+
MPM.addPass(Lab6FinalPass());
3185
});
32-
}};
86+
}
87+
};
3388
}
34-

0 commit comments

Comments
 (0)