In an C program, I need to re-initialize all global variables as they where when the program starts for tests purpose.
I want to reproduce the data copy from Load Memory Address, LMA to VMA (run-time address) done by GCC libraries with a reinitialization function.
For example, if foo variables are declared as global and initialized. And if my re-initialization function is re_init():
#include <stdio.h>
int foo1 = 42;
int foo2 = 777;
int main(){
foo1 = 0;
foo2 = 0;
re_init();
printf("foo1:%d and foo2:%d",foo1,foo2);
return 0;
}
then I want to have as an output :
foo1:42 and foo2:777
I believe that the right way to do this is to the default linker file and maybe the startup code that copy initiation values to RAM.
So, with GCC (cygwin), what should I do to achieve this?
Edit: This page seems o have more precision on it :
http://sources.redhat.com/binutils/docs-2.12/ld.info/Output-Section-LMA.html#Output%20Section%20LMA
I don’t know exactly how cygwin does this, but in general, the data section is not copied from its LMA to its VMA; rather, the relevant chunk of the executable file is memory-mapped into RAM at the desired VMA by the kernel, and then the dynamic linker executes any relocations that point at the data section.
To reinitialize the data section from the contents of the executable, therefore, you’re going to have to duplicate enough of the dynamic linker and kernel-side executable loader to: find the executable file (this is not necessarily argv[0]); parse its headers and locate the data section; destroy the old mapping and recreate it at the appropriate VMA; carry out all the relocations again; and then deal with all of the fallout caused by your having yanked the C library’s runtime state out from under it (it’s not only your own global variables in the data section, things like stdout and malloc’s master allocation tables are there as well).
Do some searches on “unexec” and “undump”, which are solving a similar (but not the same) problem, that might get you code you can recycle.