how to get and modify a global variable inside a module

recently, i use LLVM API to write a program to read *.ll and excute it
automatically.
Further more, i want to change some global variables inside a module.
i tried some functions provided by Module.h and ExecutionEngine.h but none
were seemed to match my need.
did someone have the experience or some advices?
thank you :wink:

Hi Dong Chen,

You can write a ModulePass class and implement a runOnModule method.
Inside this method you can access Module::global_iterator and get a
reference to all global variables of a module. With this reference,
you can change this variable. But be careful, you may need to change
also the references to those variables. Have a look to the method
GlobalVariable::use_begin and use_end. They give you references to the
users of the global variable.

I hope this helps,
Regards,
Eduardo

You can get hold of the global variable by passing it's name to
Module::getNamedValue. For modification it depends on what kind of modification
you have in mind, so please clarify.

Ciao, Duncan.

hi Eduardo,
thanks for your attention, i checked the iterator, but i didn't see any
fucntion can return or modify the main memory address of a global variable
inside the module.
can you provide some reference code or program can achieve this?
thank you very much

hi Duncan Sands,
i have tried the functions:
GlobalValue * getNamedValue (StringRef Name) const
GlobalVariable * getGlobalVariable (StringRef Name, bool
AllowInternal=false) const
GlobalVariable * getNamedGlobal (StringRef Name) const
but i think these functions just return the ID or something else (not the
Global Variable's main memory address, i am not sure)
here is the thing. i want to know the exact main memory address of the
Global Varibale's address when ExecutionEngine execut the *.ll code. further
more, i want to change the address, is it possible?
do you have some good idea?
thank you very much

Hi Dong Chen,
I realized you are actually executing the IR, right? I am not sure if
the things I mentioned apply in that case. Actually, I wrote a
optimization pass that modify the IR. It modifies global variables and
the final IR is intended to be compiled.
A snippet of what I do looks like this:

class TestClass : public llvm::ModulePass {
public:
  TestClass() : llvm::ModulePass(TestClass::ID) { }
  virtual bool runOnModule(llvm::Module &m) {
    for (llvm::Module::global_iterator ii = m.global_begin();
        ii != m.global_end(); ++ii) {
      GlobalVariable* gv = ii;
// here you can modify the gv variable (actually I am creating new
globals and deleting the old ones)
        for (llvm::Value::use_iterator jj = gv->use_begin();
             jj != gv->use_end(); ++jj) {
// jj is a reference for the user of the global variable
        }
    }
  }
}

hi Eduardo,
i got what you did, but it seemed that you modified the Global Variable
list, deleted Global Variable and created new one and added it to the list.
I don't know whether i got it right and for more details, can you get the
main memory address of the Global Variable? or did the iterator provide
method to get this?

thank you very much

can you get the
main memory address of the Global Variable?

That is the point, at the stage I am working, there is no main memory
address. I am not executing the IR code. I am just transforming it for
later execution (actually, later compilation to the real machine and
then execution). Sorry.

Eduardo

I assume you want to adjust the value at that address, right?
Then you might want to check the ExecutionEngine::getPointerToGlobal method. You can just cast the void* to the appropriate pointer type, and write to it.

If you really want to change the address of the GlobalValue (i.e. the mapping from GlobalValue to main memory address), you can use the addGlobalMapping or updateGlobalMapping methods, but this should only be done before JITting any function which uses the GlobalValue. Otherwise you have to call recompileAndRelinkFunction for each function that uses the GlobalValue.

Cheers,
Clemens

well, that's good enough, i still learned something form you.
thank you for your replies.

haha~ you are right :slight_smile:
i have tried the function ExecutionEngine::getPointerToGlobal(), it is
returned a address, but i am not sure the address is the pointer to the main
memory. are you sure about that?

the 2nd suggestion seems working, but i am not at the lab now, so please
allow me to try it tomorrow. but i believe your suggestion will help me.
it's really late here

hi Clemens,
great news, I solved the problem using updateGlobalMapping and
recompileAndRelinkFunction.
that really helps.
thank you very very much

Dong Chen