[llvm-dev] Fwd: I cannot change value of global variable in LLVM IR using IRBuilder

Johannes Doerfert via llvm-dev llvm-dev at lists.llvm.org
Wed Jun 3 13:17:18 PDT 2020


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 :)



On 6/3/20 1:56 PM, David Blaikie via llvm-dev wrote:
> I'm with Eli on this "GlobalVariable" is not the actual global
> variable in memory - it's the IR representation of the global variable
> before it is compiled to machine code & allocated in the running
> process - it always has the same value/isn't affected by the execution
> of loads and stores at runtime.
>
> On Wed, Jun 3, 2020 at 2:53 AM Emma Luciano via llvm-dev
> <llvm-dev at lists.llvm.org> wrote:
>> I don't think it's the same problem as you described. By printing I meant calling printf function and passing my global variable as one of the arguments.
>>
>> My code:
>>
>> 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;
>> }
>>
>> 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;
>> }
>>
>> 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: %lld\n";
>> print(next, message, allocatedAddress, allocatedSize, key->getOperand(0));
>> }
>> }
>>
>> Code that I'm executing (source code) is:
>> int main()
>> {
>> char* buffer;
>> int size = 101;
>> buffer = new char[size];
>> printf("CHECK address: 0x%p, size: %d\n", buffer, size);
>> TestClass* test = new TestClass(1, 2);
>> printf("(CHECK address: 0x%p, size: %llu\n", test, sizeof(TestClass));
>>
>> delete buffer;
>> delete test;
>> }
>>
>> And program output after instrumentation:
>>
>> Allocated address: 0x000001CD326C1B20, size: 101, key: 0
>> CHECK address: 0x000001CD326C1B20, size: 101
>> Allocated address: 0x000001CD326C1B90, size: 8, key: 0
>> CHECK address: 0x000001CD326C1B90, size: 8
>>
>> Regards,
>> Emma Luciano
>>
>> śr., 3 cze 2020 o 11:21 Eli Friedman <efriedma at quicinc.com> napisał(a):
>>> 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
>>>
>>>
>>>
>>> From: llvm-dev <llvm-dev-bounces at lists.llvm.org> On Behalf Of Emma Luciano via llvm-dev
>>> Sent: Wednesday, June 3, 2020 1:35 AM
>>> To: llvm-dev at lists.llvm.org
>>> Subject: [EXT] [llvm-dev] Fwd: I cannot change value of global variable in LLVM IR using IRBuilder
>>>
>>>
>>>
>>> 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* @globalKey
>>>
>>> I 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
>> _______________________________________________
>> LLVM Developers mailing list
>> llvm-dev at lists.llvm.org
>> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200603/86a3d83c/attachment.html>


More information about the llvm-dev mailing list