Skip to content

Commit fdbdb26

Browse files
authored
Merge pull request #437 from wei020789/lab6
[LAB6] 313553053
2 parents 2fb1743 + 0002ced commit fdbdb26

File tree

1 file changed

+86
-14
lines changed

1 file changed

+86
-14
lines changed

lab6/llvm-pass.so.cc

Lines changed: 86 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,99 @@
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

510
using 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
2497
extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
2598
llvmGetPassPluginInfo() {
2699
return {LLVM_PLUGIN_API_VERSION, "LLVMPass", "1.0",
@@ -31,4 +104,3 @@ llvmGetPassPluginInfo() {
31104
});
32105
}};
33106
}
34-

0 commit comments

Comments
 (0)