В файле ELF как определяется адрес для _start? - PullRequest
4 голосов
/ 25 ноября 2010

Я читал спецификацию ELF и не могу понять, откуда берутся точка входа в программу и адрес _start.

Кажется, что они должны быть в довольно последовательном месте, но я сделал несколько тривиальных программ, а _start всегда в другом месте.

Может кто-нибудь уточнить?

Ответы [ 3 ]

3 голосов
/ 18 августа 2013

Символ _start может быть определен в любом объектном файле.Обычно он генерируется автоматически (соответствует main в C).Вы можете создать его самостоятельно, например, в исходном файле на ассемблере:

.globl _start
_start:
    // assembly here

Когда компоновщик обработал все объектные файлы, он ищет символ _start и помещает его значение в поле e_entry эльфийский заголовок .Загрузчик берет адрес из этого поля и вызывает его после завершения загрузки всех разделов в памяти и готовности выполнить файл.

1 голос

Посмотрите на скрипт компоновщика, который ld использует:

ld -verbose

Формат задокументирован по адресу: https://sourceware.org/binutils/docs-2.25/ld/Scripts.html

Он определяет в основном все о том, каким будет исполняемый файл.Генерируемый.

В 64-битной версии Binutils 2.24 Ubuntu 14.04 он содержит строку:

ENTRY(_start)

, которая устанавливает точку входа в символ _start (идет к заголовку ELF, как упоминалосьctn)

А затем:

. = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;

, который устанавливает адрес первых заголовков равным 0x400000 + SIZEOF_HEADERS.

Я изменил этот адрес на 0x800000, передал свой пользовательский скрипт с ld -T, и он заработал: readelf -s говорит, что _start находится по этому адресу.

Другой способизменить его - использовать опцию -Ttext-segment=0x800000.

Причина использования 0x400000 = 4Mb = getconf PAGE_SIZE состоит в том, чтобы начать в начале второй страницы, как указано по адресу: ПочемуВиртуальный адрес точки входа исполнения ELF в форме 0x80xxxxx, а не ноль 0x0?

Вопрос описывает, как установить _start из командной строки: Почему точка входа ELF 0x8048000 не изменяетсяс опцией "ld -e"?

SIZEOF_HEADERS - это размер заголовков программы ELF +, которые находятся в начале файла ELF.Эти данные загружаются в самое начало пространства виртуальной памяти Linux (почему TODO?). В минимальном мире приветствия Linux x86-64 с 2 заголовками программ это стоит 0xb0, так что символ _start имеет значение 0x4000b0.

0 голосов
/ 16 июля 2011

Я не уверен, но попробуйте эту ссылку http://www.docstoc.com/docs/23942105/UNIX-ELF-File-Format на странице 8 показано, где находится точка входа, если она исполняемая.В основном вам нужно рассчитать смещение, и вы его получили.Обязательно запомните немного порядковый номер x86 (я полагаю, вы используете его) и измените порядок, если вы читаете побайтное редактирование: или, возможно, нет, я не совсем уверен в этом, если честно.

...