In what segment (.BSS, .DATA, other) of an executable file are static variables stored so that they don\'t have name collision? For example:
foo.c:
How to find it yourself with objdump -Sr
To actually understand what is going on, you must understand linker relocation. If you've never touched that, consider reading this post first.
Let's analyze a Linux x86-64 ELF example to see it ourselves:
#include
int f() {
static int i = 1;
i++;
return i;
}
int main() {
printf("%d\n", f());
printf("%d\n", f());
return 0;
}
Compile with:
gcc -ggdb -c main.c
Decompile the code with:
objdump -Sr main.o
-S
decompiles the code with the original source intermingled-r
shows relocation informationInside the decompilation of f
we see:
static int i = 1;
i++;
4: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # a
6: R_X86_64_PC32 .data-0x4
and the .data-0x4
says that it will go to the first byte of the .data
segment.
The -0x4
is there because we are using RIP relative addressing, thus the %rip
in the instruction and R_X86_64_PC32
.
It is required because RIP points to the following instruction, which starts 4 bytes after 00 00 00 00
which is what will get relocated. I have explained this in more detail at: https://stackoverflow.com/a/30515926/895245
Then, if we modify the source to i = 1
and do the same analysis, we conclude that:
static int i = 0
goes on .bss
static int i = 1
goes on .data