如何使用 IRBuilder 更新 LLVM IR 中的全局变量值?
How can I update global variable value in LLVM IR using IRBuilder?
我想在 LLVM IR 中更新全局变量的值。
我在 ModulePass 中创建了新的全局变量:
bool runOnModule(llvm::Module &M) {
IRBuilder<> Builder(M.getContext());
Instruction *I = &*inst_begin(M.getFunction("main"));
Builder.SetInsertPoint(I);
M.getOrInsertGlobal("globalKey", Builder.getInt64Ty());
GlobalVariable* gVar = M.getNamedGlobal("globalKey");
gVar->setLinkage(GlobalValue::InternalLinkage);
gVar->setAlignment(Align(8));
gVar->setInitializer(Builder.getInt64(0));
gVar->setConstant(false);
for (Function &F : M.functions()) {
InstructionVisitor visitor(DL, getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F));
for (Instruction &I : instructions(F)) {
visitor.visit(I);
}
}
return true;
}
稍后在 InstructionVisitor 中,我尝试在每次分配时增加 globalKey 并使用 printf 函数打印它:
Instruction* InstructionVisitor::print(Instruction* I, const char* text, Value* arg1, Value* arg2, Value* arg3, Value* arg4) {
Function* printfFn = I->getModule()->getFunction("printf");
if (printfFn) {
IRBuilder<> Builder(I->getContext());
Builder.SetInsertPoint(I->getNextNode());
Value* convertedText = Builder.CreateGlobalStringPtr(text);
std::vector <Value *> params;
params.push_back(convertedText);
if (arg1)
params.push_back(arg1);
if (arg2)
params.push_back(arg2);
if (arg3)
params.push_back(arg3);
if (arg4)
params.push_back(arg4);
return Builder.CreateCall(printfFn, params);
}
return I;
}
Instruction* InstructionVisitor::incrementGlobalKey(Instruction* I) {
IRBuilder<> Builder(I->getContext());
Builder.SetInsertPoint(I->getNextNode());
GlobalVariable* key = I->getModule()->getNamedGlobal("globalKey");
if (key) {
LoadInst* load = Builder.CreateLoad(key);
Value* inc = Builder.CreateAdd(load, Builder.getInt64(1));
StoreInst* store = Builder.CreateStore(inc, key);
return store;
}
return I;
}
void InstructionVisitor::visitCallInst(CallInst &CI) {
if (isAllocationFn(&CI, &TLI)) {
Value* allocatedAddress = &CI;
Instruction* I = &CI;
Value* allocatedSize = I->getOperand(0);
Instruction* next = incrementGlobalKey(I);
GlobalVariable* key = I->getModule()->getNamedGlobal("globalKey");
const char* message = "Allocated address: 0x%p, size: %d, key: 0x%x\n";
print(next, message, allocatedAddress, allocatedSize, key->getOperand(0));
}
}
我在执行检测代码期间打印该全局变量(使用注入的 printf 调用)。我通过 key->getOperand(0) 访问它的值(如上所示),但它没有改变。我正在根据本教程使用 ORC JIT:https://llvm.org/docs/tutorial/BuildingAJIT2.html 并且我 运行 来自本教程的 optimizeModule 函数的 ModulePass。
IR,我正在检测的源代码和程序输出可以在这里找到:
https://pastebin.com/JbDR2Wug
有谁知道如何让它工作?我将不胜感激!
在@droptop 有用的评论之后,我更改了我的代码以使用加载指令实际加载全局变量的值。它现在工作正常。如果有人需要,更新后的代码如下所示:
Instruction* InstructionVisitor::getGlobalValue(Instruction* I, StringRef Name) {
IRBuilder<> Builder(I->getContext());
Builder.SetInsertPoint(I->getNextNode());
GlobalVariable* key = I->getModule()->getNamedGlobal(Name);
if (key) {
LoadInst* load = Builder.CreateLoad(key);
return load;
}
return nullptr;
}
void InstructionVisitor::visitCallInst(CallInst &CI) {
if (isAllocationFn(&CI, &TLI)) {
Value* allocatedAddress = &CI;
Instruction* I = &CI;
Value* allocatedSize = I->getOperand(0);
Instruction* next = incrementGlobalKey(I, allocatedAddress, allocatedSize);
Instruction* loadKey = getGlobalValue(next, "globalKey"); //here
const char* message = "Allocated address: 0x%p, size: %d, key: %lld\n";
next = print(loadKey, message, allocatedAddress, allocatedSize, loadKey);
}
}
我想在 LLVM IR 中更新全局变量的值。 我在 ModulePass 中创建了新的全局变量:
bool runOnModule(llvm::Module &M) {
IRBuilder<> Builder(M.getContext());
Instruction *I = &*inst_begin(M.getFunction("main"));
Builder.SetInsertPoint(I);
M.getOrInsertGlobal("globalKey", Builder.getInt64Ty());
GlobalVariable* gVar = M.getNamedGlobal("globalKey");
gVar->setLinkage(GlobalValue::InternalLinkage);
gVar->setAlignment(Align(8));
gVar->setInitializer(Builder.getInt64(0));
gVar->setConstant(false);
for (Function &F : M.functions()) {
InstructionVisitor visitor(DL, getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F));
for (Instruction &I : instructions(F)) {
visitor.visit(I);
}
}
return true;
}
稍后在 InstructionVisitor 中,我尝试在每次分配时增加 globalKey 并使用 printf 函数打印它:
Instruction* InstructionVisitor::print(Instruction* I, const char* text, Value* arg1, Value* arg2, Value* arg3, Value* arg4) {
Function* printfFn = I->getModule()->getFunction("printf");
if (printfFn) {
IRBuilder<> Builder(I->getContext());
Builder.SetInsertPoint(I->getNextNode());
Value* convertedText = Builder.CreateGlobalStringPtr(text);
std::vector <Value *> params;
params.push_back(convertedText);
if (arg1)
params.push_back(arg1);
if (arg2)
params.push_back(arg2);
if (arg3)
params.push_back(arg3);
if (arg4)
params.push_back(arg4);
return Builder.CreateCall(printfFn, params);
}
return I;
}
Instruction* InstructionVisitor::incrementGlobalKey(Instruction* I) {
IRBuilder<> Builder(I->getContext());
Builder.SetInsertPoint(I->getNextNode());
GlobalVariable* key = I->getModule()->getNamedGlobal("globalKey");
if (key) {
LoadInst* load = Builder.CreateLoad(key);
Value* inc = Builder.CreateAdd(load, Builder.getInt64(1));
StoreInst* store = Builder.CreateStore(inc, key);
return store;
}
return I;
}
void InstructionVisitor::visitCallInst(CallInst &CI) {
if (isAllocationFn(&CI, &TLI)) {
Value* allocatedAddress = &CI;
Instruction* I = &CI;
Value* allocatedSize = I->getOperand(0);
Instruction* next = incrementGlobalKey(I);
GlobalVariable* key = I->getModule()->getNamedGlobal("globalKey");
const char* message = "Allocated address: 0x%p, size: %d, key: 0x%x\n";
print(next, message, allocatedAddress, allocatedSize, key->getOperand(0));
}
}
我在执行检测代码期间打印该全局变量(使用注入的 printf 调用)。我通过 key->getOperand(0) 访问它的值(如上所示),但它没有改变。我正在根据本教程使用 ORC JIT:https://llvm.org/docs/tutorial/BuildingAJIT2.html 并且我 运行 来自本教程的 optimizeModule 函数的 ModulePass。
IR,我正在检测的源代码和程序输出可以在这里找到: https://pastebin.com/JbDR2Wug
有谁知道如何让它工作?我将不胜感激!
在@droptop 有用的评论之后,我更改了我的代码以使用加载指令实际加载全局变量的值。它现在工作正常。如果有人需要,更新后的代码如下所示:
Instruction* InstructionVisitor::getGlobalValue(Instruction* I, StringRef Name) {
IRBuilder<> Builder(I->getContext());
Builder.SetInsertPoint(I->getNextNode());
GlobalVariable* key = I->getModule()->getNamedGlobal(Name);
if (key) {
LoadInst* load = Builder.CreateLoad(key);
return load;
}
return nullptr;
}
void InstructionVisitor::visitCallInst(CallInst &CI) {
if (isAllocationFn(&CI, &TLI)) {
Value* allocatedAddress = &CI;
Instruction* I = &CI;
Value* allocatedSize = I->getOperand(0);
Instruction* next = incrementGlobalKey(I, allocatedAddress, allocatedSize);
Instruction* loadKey = getGlobalValue(next, "globalKey"); //here
const char* message = "Allocated address: 0x%p, size: %d, key: %lld\n";
next = print(loadKey, message, allocatedAddress, allocatedSize, loadKey);
}
}