Как найти себя с помощью objdump -Sr
Чтобы действительно понять, что происходит, вы должны понимать перемещение компоновщика. Если вы никогда не касались этого, подумайте сначала прочитав это сообщение .
Давайте проанализируем пример Linux x86-64 ELF, чтобы увидеть его сами:
#include <stdio.h>
int f() {
static int i = 1;
i++;
return i;
}
int main() {
printf("%d\n", f());
printf("%d\n", f());
return 0;
}
Компилировать с:
gcc -ggdb -c main.c
Декомпилируйте код с помощью:
objdump -Sr main.o
-S
декомпилирует код с исходным кодом, смешанным
-r
показывает информацию о переезде
Внутри декомпиляции f
мы видим:
static int i = 1;
i++;
4: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # a <f+0xa>
6: R_X86_64_PC32 .data-0x4
и .data-0x4
говорит, что он перейдет к первому байту сегмента .data
.
-0x4
есть, потому что мы используем относительную адресацию RIP, то есть %rip
в инструкции и R_X86_64_PC32
.
Требуется, потому что RIP указывает на следующую инструкцию, которая начинается через 4 байта после 00 00 00 00
, что и будет перемещено. Я объяснил это более подробно по адресу: https://stackoverflow.com/a/30515926/895245
Затем, если мы изменим источник на i = 1
и проведем тот же анализ, мы заключим, что:
static int i = 0
продолжается .bss
static int i = 1
продолжается .data