Вопрос по dynamic-loading, linker, dynamic-linking, loader –  на диске.

2

нтересно, что на самом деле означает перемещение во время загрузки в системе с поддержкой виртуальной памяти. Я думал, что в системе с виртуальной памятью каждый исполняемый файл будет иметь адреса, начиная с нуля, и во время выполнения адреса будут преобразованы в физические адреса с использованием Таблицы страниц. Поэтому исполняемый файл может быть загружен в любом месте памяти без необходимости перемещения. Однако в этой статье об общих библиотеках упоминается, что компоновщик указывает адрес в исполняемом файле, куда должен быть загружен исполняемый файл (адрес точки входа).

http://eli.thegreenplace.net/2011/08/25/load-time-relocation-of-shared-libraries/

Также есть много статей о динамическом связывании, которые говорят об абсолютных адресах. Мое понимание неверно?

Перемещение не связано с виртуальным адресным пространством (по крайней мере, не на уровне загрузки библиотеки; мы не говорим о реализации диспетчера памяти ОС здесь). Вы должны знать некоторый ассемблер, чтобы знать, как исполняемый файл выглядит внутри. Теперь вы заметили, что там есть адреса памяти. Теперь рассмотрим, что происходит, когда эти адреса на самом деле не являются фиксированными, а зависят отгде библиотека загружается внутри адресного пространства. Kerrek SB
Хм, не из головы, но, возможно, вы можете сканировать Википедию, начинаяВот а такжеВот. Kerrek SB
Спасибо за ссылки, но они не объясняют, что это означает под перемещением в виртуальном адресном пространстве. Мне нужно понять, если и как виртуальная память и перемещение работают вместе. Кроме того, не могли бы вы рассказать о значении адреса точки входа? vjain27
Перемещение во время загрузки и виртуальная память - это две независимые, ортогональные концепции. Перемещение времени загрузки обычно относится к загрузке кода по переменным адресамвнутри данное (виртуальное) адресное пространство. Kerrek SB
Можете ли вы указать мне на статью, которая объясняет это подробно? Я не могу понять эту «перестановку в виртуальном адресном пространстве». vjain27

Ваш Ответ

1   ответ
9

разные концепции. Почти все процессоры и операционные системы в наши дни поддерживают виртуальную память. Единственный действительно важный момент для понимания виртуальной памяти: забыть физические адреса. Теперь это ответственность за аппаратное обеспечение и ОС, и, если вы не пишете систему подкачки, вы можете забыть о физических адресах. Все адреса, которые использует программа, являются виртуальными. Это огромное преимущество и значительно упрощает модель программирования. В 32-разрядных системах это просто означает, что каждый процесс получает свое собственное пространство памяти 4 ГБ, начиная от0x00000000 в0xffffffff.

.exe представляет процесс. Линкер производит.exe из.obj файлы. Хотя оба являются двоичными файлами,.obj файлы не являются исполняемыми, потому что они не содержат адреса всех переменных и функций. Работа линкера заключается в предоставлении этих адресов, которые он определяет, помещая эти.obj файлы в конец, а затем вычисление точных адресов всех символов (функций и переменных). Таким образом.exe то, что создано, имеет каждый адрес функций и переменных, «жестко запрограммированных» в нем. Но есть еще одна важная информация, необходимая до.exe может быть создан. Линкер должен иметь инсайдерские знания о том, где в памяти.exe будет загружен. Это будет по адресу0x00000000, или на0xffff0000или где-то еще? Например, в Windows все.exes всегда загружаются по абсолютному начальному адресу0x00400000, Это называется базовым адресом. Когда компоновщик генерирует окончательные адреса символов (функций и переменных), он вычисляет их с этого адреса и далее.

В настоящее время,.exes редко нужно загружать по любому другому адресу. Но то же самое не верно для.dlls..ddls такие же, как.exes (оба формата отформатированы в формате переносимого исполняемого файла (PE), который описывает структуру памяти, например, куда идет текст, куда идут данные и как найти какой)..dllУ них тоже есть предпочтительный адрес. Это просто означает, что компоновщик использует это значение, когда вычисляет адреса для символов внутри.dll, Если.dll загружается по этому адресу, то у нас все настроено.

Но если.dll не может быть загружен по этому адресу (скажем, это было0x10000000) потому что некоторые другие.dll уже был загружен по этому адресу, тогда загрузчик найдет другое место в памяти и загрузит.dll там. Однако глобальные адреса функций и символов в.dll сейчас неверны. Таким образом, загрузчик должен сделатьперемещение (также называемый «fixup»), в котором он корректирует адреса всех глобальных символов и функций, чтобы отразить их фактические адреса.

Чтобы выполнить эту настройку, загрузчик должен быть в состоянии найти все такие символы в.dll, Файл PE имеет.reloc раздел, который содержит внутреннее смещение всех таких символов.

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

Наконец, суть заключается в следующем: вам нужно переместить (в некотором роде), чтобы настроить адреса в вызове и переходе, а также инструкции по доступу к переменной, когда код не загружается в той позиции (в пределах адресного пространства 4 ГиБ), которую он ожидал нагрузки. Когда ОС загружает.exe, он должен выбрать подходящее место в этом 4 ГБ адресном пространстве, куда он будет копировать код и порции данных из этого.exe на диске.

Похожие вопросы