заголовки программ и заголовки разделов в файлах ELF

Это повторение вопроса, но я не смог быстро найти ответ на свой вопрос. Вот почему спрашиваю об этом.

Некоторые файлы ELF содержат (исполняемые файлы или общие библиотеки) заголовки программ, которые объясняют сегменты. Они содержат поле, называемое виртуальным адресом и смещением файла, а также некоторые другие поля.

Также есть соответствующие разделы, объясняющие «адрес в памяти» и смещение файла.

Теперь меня немного смущает, как связаны разделы и сегменты. (Для статически скомпилированных исполняемых файлов и для нестатически скомпилированных исполняемых файлов.) Чем различаются смещения файлов для статически скомпилированных двоичных файлов? Есть ли связь между виртуальным адресом в заголовках программ и адресом памяти в заголовках разделов.

Спасибо


person agent.smith    schedule 14.08.2014    source источник
comment
Я сам нашел хорошую статью, которая устраняет большую часть моей путаницы: mylinuxbook.com/readelf-command   -  person agent.smith    schedule 14.08.2014
comment
Не могли бы вы обобщить то, что вы узнали, в форме ответа на свой вопрос?   -  person Ross Ridge    schedule 15.08.2014


Ответы (1)


Раздел - это самая маленькая непрерывная область файла. Итак, файлы ELF подразделяются на разделы. Разделы не могут перекрываться, то есть ни один байт не может быть частью более чем одного раздела. Но могут быть байты, не принадлежащие ни к какому разделу («мусор»).

Разделы обычно используются для целей ссылки. Они содержат разные части файла, которые компоновщик может переупорядочивать, объединять и т. Д.

Но исполняемые файлы также могут содержать разделы - для описания содержимого файла и того, где начинается каждый фрагмент кода или данных. Общие объекты тоже используют разделы. Они содержат таблицы символов для динамического связывания и тому подобное.

Все разделы, содержащиеся в файле ELF, описаны в таблице заголовков разделов, в каждом разделе есть запись.

Но для того, чтобы создать исполняемый файл, вам нужно кое-что еще: сегменты. Они сообщают загрузчику, какие части файла он должен загрузить в память и по каким адресам. Таким образом, сегменты отображаются в пространстве памяти исполняемого процесса. Они могут содержать как код, так и данные, поэтому для этого сегменты можно разделить на разделы. Думаю, это ответ на ваш вопрос.

Загружаемые сегменты описаны в таблице заголовков программ.

Короче говоря:
В исполняемых файлах у вас есть сегменты, которые можно подразделить на разделы. Сегменты загружаются в память процесса. Разделы необязательны, но могут помочь разделить сегменты дальше или описать их содержимое. В перемещаемых модулях (выходные данные компилятора, файлы .o) все наоборот: необходимы разделы, потому что они описывают содержимое файла и позволяют связывать.


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

Физические адреса не используются, поэтому их можно оставить нулевыми, но на всякий случай можно установить те же адреса.

person BarbaraKwarc    schedule 04.07.2018