Точкой входа является рядом с адресом секции .text
.
Точкой входа, которую вы видите с помощью $ readelf -h a.out
, является номинальный адрес, статически назначенный компоновщиком допрограмма загружена и перемещена.
Адрес раздела .text
не является адресом main
, как предполагает ваша программа, это адрес символа __executable_start
, и более тогоПрограмма печатает во время выполнения не номинальный адрес, назначенный компоновщиком, а виртуальный адрес после загрузки и перемещения программы.См .:
$ cat main.c
#include <stdio.h>
extern char __executable_start;
extern char _start;
int main(void)
{
printf("%p: address of `.text` section\n", &__executable_start);
printf("%p: address of `_start` \n", &_start);
printf("%p: address of `main` \n", &main);
return 0;
}
$ gcc -Wall main.c
$ readelf -s a.out | egrep -w '(main|_start|__executable_start)'
34: 0000000000000000 0 FILE LOCAL DEFAULT ABS main.c
49: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS __executable_start
57: 0000000000000540 43 FUNC GLOBAL DEFAULT 14 _start
59: 000000000000064a 83 FUNC GLOBAL DEFAULT 14 main
Номинальный адрес секции .text
- 0000000000000000. Точкой входа является адрес _start
, со смещением 0x540 байтов в секции .text
, а main
- по адресусмещение 0x64a.Точка входа, о которой сообщают:
$ readelf -h a.out | grep 'Entry point'
Entry point address: 0x540
, совпадает.И работает программа:
$ ./a.out
0x564c5d350000: address of `.text` section
0x564c5d350540: address of `_start`
0x564c5d35064a: address of `main`
показывает символы с одинаковыми смещениями от виртуального базового адреса 0x564c5d350000.