Hi Everyone,
I'm quite new to LLVM and I want to update value of global variable in LLVM IR. I created new global variable in 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;
}Later in InstructionVisitor I try to update it like that:
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);
}I print that global variable during execution of instrumented code. I access it's value by key->getOperand(0), but it's unchanged. I'm using ORC JIT based on this tutorial: https://llvm.org/docs/tutorial/BuildingAJIT2.html and I run ModulePass from optimizeModule function from this tutorial.
In IR it looks like that:
%2 = load i64, i64* @globalKey
%3 = add i64 %2, 1
store i64 %3, i64* @globalKeyI tried updating value of global variable, which was present in source code that I'm instrumenting. It didn't work either.
I created corresponding stackoverflow topic: https://stackoverflow.com/questions/62142574/how-can-i-update-global-variable-value-in-llvm-ir-using-irbuilder?fbclid=IwAR2X7uGhUjm_SN2UcxWYqaRQW2-cs6iPbMx2_tbKubeyYUkZ_pS6rkFfY9I
I will be really grateful for help.
Regards,
Emma Luciano
Suppose I have the following program:
$ cat test.c
int a = 0;
int main() { a = 1; };
Then I compile and run it:
$ clang test.c
$ ./a.out
Then I print the contents of test.c again:
$ cat test.c
int a = 0;
int main() { a = 1; }
Why does it say “int a = 0;”? The program set it to 1, no?
As far as I can tell, this is equivalent to your question… except it’s less obvious because the “source code” is an LLVM IR module in memory.
Maybe you’re looking for ExecutionSession::lookup? The same way the tutorial computes the address of “main”, you can compute the runtime address of any other externally visible symbol.
See also https://llvm.org/docs/ORCv2.html , https://www.youtube.com/watch?v=hILdR8XRvdQ .
-Eli
> _______________________________________________
> LLVM Developers mailing list
> llvm...@lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
_______________________________________________
LLVM Developers mailing list
llvm...@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Right.
Maybe I can put this a bit
differently:
A `llvm::GlobalVariable` is *not* the source variable but a pointer to the storage location of the source variable.
This is the same for an `llvm::AllocaInst` that represents a local variable.
Using a source variable means reading the `llvm::GlobalVariable` (or `llvm::AllocaInst`) that models the memory allocated for the source variable.
Changing the variable corresponds to a write.
Hope this helps :)
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");
const char* message = "Allocated address: 0x%p, size: %d, key: %lld\n";
next = print(loadKey, message, allocatedAddress, allocatedSize, loadKey);
}
}
Thank you,
Emma Luciano