Franc
Franc

Reputation: 450

Readelf finding absolute address

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

Answers (1)

Mike Kinghan
Mike Kinghan

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

Related Questions