Reputation: 450
I have a C programme which has one global and one local variable. My question is on the readelf. Following are my questions; 1. When i take the address dump using "readelf --symbols", i get an address for my global variable which is same as that of the address i print when i run the programme. How the readelf can know the absolute address before my programme is running or been loaded? 2. Why there are no informations on the local variables' symbols?. I can see only global variables' symbols.
Upvotes: 3
Views: 5040
Reputation: 61432
How readelf can know the absolute address before my programme is running or been loaded?
Because by the time the linker has done its work, the address computed for your global variable is the address at which the program loader will have to place that variable at runtime. The job of the linker is largely to put information into an executable that tells the program loader where symbols are to be mapped in memory.
Why there are no informations on the local variables' symbols
There may be three kinds of "local" variables in your program.
main.c
static int static_filescope_i = 1;
int f()
{
static int static_local_i = 2;
return static_local_i;
}
int g()
{
int automatic_i = 3;
return automatic_i;
}
int global_i = 4;
int main()
{
return global_i + f() + g() + static_filescope_i;
}
An automatic variable like automatic_local_i
is created on the stack at runtime
each time the program enters the block in which it is defined, and ceases to exist
then it leaves that block. Such a variable occupies no storage in the executable
so it is not represented in the symbol table.
A variable like static_filescope_i
would often be called a static global,
to distinguish it from one like static_local_i
. static_local_i
cannot
be seen outside the block in which it is defined. static_filescope_i
can
be seen in any function defined in the same object file (main.o
) but
not in any other object file: it is global within main.o
but
local to that object file within the program as a whole.
Both static_filescope_i
and static_local_i
must have its
initial value when the program first uses the variable and then keep
whatever value it has, or any new value assigned to it, until the next time
it is used - across function-calls, until the program ends. This means
that such variables need storage in the executable, not on the stack, and they may or may not be
represented in the symbol table.
global_i
, of course, is global to the whole program: it can be seen in
main.o
and any other other files we might link with main.o
.
If we compile main.c
with default options (no optimization):
$ gcc -c main.c
then we find:
$ readelf -s main.o | grep automatic_i
$
...no symbol for automatic_i
.
$ readelf -s main.o | grep global_i
12: 0000000000000004 4 OBJECT GLOBAL DEFAULT 3 global_i
...a global symbol for global_i
.
$ readelf -s main.o | grep static_filescope_i
5: 0000000000000000 4 OBJECT LOCAL DEFAULT 3 static_filescope_i
...a local symbol for static_filescope_i
$ readelf -s main.o | grep static_local_i
6: 0000000000000008 4 OBJECT LOCAL DEFAULT 3 static_local_i.1833
...and also a local symbol for static_local_i
, but with a scope-distinguishing
suffix appended.
Here, GLOBAL
means can be seen by the linker, and LOCAL
means cannot be seen
by the linker.
So for the purpose of linking main.o
with any other object files or libraries
to make an executable, static_filescope_i
and static_local_i
might as well
not exist.
That doesn't mean they are completely useless in the object file. They are useful for debugging. They are useful for the purpose of investigating what the static storage of the executable is made up of, as we are doing now.
But they're no use to the linker and so, if you compile main.c
with any optimization
level > 0 then the compiler will assume you want object code that is not for
purposes of debugging or investigation and it will not emit any local symbols:
$ gcc -O1 -c main.c
$ readelf -s main.o | grep static_local_i
$ readelf -s main.o | grep static_filescope_i
$ readelf -s main.o | grep global_i
11: 0000000000000000 4 OBJECT GLOBAL DEFAULT 3 global_i
...only global_i
remains.
That should explain why you're not seeing any of the "local" symbols. You r automatic variables are never in the symbol table. Your static variables are only in the symbol table if you have disabled all optimization.
Upvotes: 3