Возьмите взгляд на сценарии компоновки ld
использует:
ld -verbose
Формат документированы: https://sourceware.org/binutils/docs-2.25/ld/Scripts.html
Он определяет, в основном все о том, как будет создан исполняемый файл.
На Binutils 2.24 Ubuntu 14.04 64-бит, он содержит строку:
ENTRY(_start)
который устанавливает точку входа в _start
символ (идет в заголовок ELF, как указано с помощью КТС)
И затем:
. = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
, который задает адрес первых заголовков к 0x400000
+ SIZEOF_HEADERS
.
Я изменил этот адрес 0x800000
, прошел мой собственный сценарий с ld -T
, и она работала: readelf -s
говорит, что _start
находится по этому адресу.
Другой способ изменить это - использовать опцию -Ttext-segment=0x800000
.
Причина использования 0x400000
= 4Mb = getconf PAGE_SIZE
начнется в начале второй страницы, как спросил у: Why is the ELF execution entry point virtual address of the form 0x80xxxxx and not zero 0x0?
в вопросе описывается, как установить _start
из командной строки: Why is the ELF entry point 0x8048000 not changeable with the "ld -e" option?
SIZEOF_HEADERS
представляет собой размер заголовков программ ELF +, которые находятся в начале файла ELF. Эти данные загружаются в самом начале виртуального пространства памяти Linux (TODO, почему?). В минимальном мире приветствия x86-64 с двумя заголовками программ стоит 0xb0
, так что символ _start
приходит на 0x4000b0.
Как правило, `_start` на самом деле не является` главным ', по крайней мере, с помощью функций GCC/glibc: `_start` вызывает инициализацию, затем` main`, затем `exit() `со значением, возвращаемым` main`. – ysdx 2016-02-12 00:35:38