stringtranslate.com

Переезд (вычисления)

Перемещение — это процесс назначения адресов загрузки для зависящего от положения кода и данных программы и корректировки кода и данных для отражения назначенных адресов. [1] [2] До появления многопроцессорных систем и до сих пор во многих встроенных системах адреса объектов были абсолютными , начиная с известного местоположения, часто с нуля. Поскольку многопроцессорные системы динамически связываются и переключаются между программами, возникла необходимость иметь возможность перемещать объекты с использованием независимого от позиции кода . Компоновщик обычно выполняет перемещение в сочетании с разрешением символов — процессом поиска файлов и библиотек для замены символических ссылок или имен библиотек фактическими пригодными для использования адресами в памяти перед запуском программы.

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

Сегментация

Объектные файлы сегментированы на различные сегменты или типы разделов памяти. Примеры типов сегментов включают сегмент кода (.text) , сегмент инициализированных данных (.data) , сегмент неинициализированных данных (.bss) или другие, установленные программистом, такие как общие сегменты или именованные статические сегменты.

Таблица перемещения

Таблица перемещения — это список указателей , созданный транслятором (компилятором или ассемблером ) и сохраненный в объекте или исполняемом файле. Каждая запись в таблице, или «исправление», представляет собой указатель на абсолютный адрес в объектном коде, который необходимо изменить, когда загрузчик перемещает программу, чтобы она ссылалась на правильное место. Исправления предназначены для поддержки перемещения программы как единого целого. В некоторых случаях каждое исправление в таблице само по себе связано с нулевым базовым адресом, поэтому сами исправления должны меняться по мере перемещения загрузчика по таблице. [2]

В некоторых архитектурах исправление, которое пересекает определенные границы (например, границу сегмента) или не выравнивается по границе слова, является незаконным и помечается компоновщиком как ошибка. [3]

DOS и 16-битная Windows

Дальние указатели ( 32-битные указатели с сегментом :offset, используемые для адресации 20-битного пространства памяти размером 640 КБ , доступного программам DOS ), которые указывают на код или данные в исполняемом файле DOS ( EXE ), не имеют абсолютных сегментов, поскольку Фактический адрес кода/данных зависит от того, где программа загружена в память, и это неизвестно, пока программа не загружена.

Вместо этого сегменты представляют собой относительные значения в файле DOS EXE. Эти сегменты необходимо исправить, когда исполняемый файл загрузится в память. Загрузчик EXE использует таблицу перемещения для поиска сегментов, которые необходимо настроить.

32-битная Windows

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

Как для DLL, так и для EXE-файлов, которые выбирают рандомизацию расположения адресного пространства (ASLR), метод предотвращения эксплойтов , представленный в Windows Vista , таблицы перемещения снова становятся обязательными из-за возможности того, что двоичный файл может быть динамически перемещен перед выполнением, даже если они по-прежнему являются первыми, что загружаются в виртуальное адресное пространство.

64-битная Windows

При запуске собственных 64-битных двоичных файлов в Windows Vista и более поздних версиях ASLR является обязательным , поэтому разделы перемещения не могут быть пропущены компилятором.

Unix-подобные системы

Формат исполняемых файлов и линкуемых файлов (ELF) и формат разделяемых библиотек, используемые большинством Unix-подобных систем, позволяют определить несколько типов перемещения. [4]

Процедура переезда

Компоновщик считывает информацию о сегментах и ​​таблицы перемещения в объектных файлах и выполняет перемещение следующим образом:

Пример

В следующем примере используется архитектура MIX Дональда Кнута и язык ассемблера MIXAL. Принципы одинаковы для любой архитектуры, хотя детали могут меняться.

Смотрите также

Рекомендации

  1. ^ «Типы объектного кода». Справочное руководство по загрузчику приложений iRMX 86 (PDF) . Интел . стр. 1-2–1-3. Архивировано (PDF) из оригинала 11 января 2020 г. Проверено 11 января 2020 г. […] Абсолютный код и абсолютный объектный модуль — это код, который был обработан LOC86 для запуска только в определенном месте памяти. Загрузчик загружает абсолютный объектный модуль только в определенное место , которое модуль должен занимать. Независимый от позиции код (обычно называемый PIC) отличается от абсолютного кода тем, что PIC можно загрузить в любую ячейку памяти. Преимущество PIC перед абсолютным кодом заключается в том, что PIC не требует резервирования определенного блока памяти. Когда загрузчик загружает PIC, он получает сегменты памяти iRMX 86 из пула задания вызывающей задачи и загружает PIC в эти сегменты. Ограничением, касающимся PIC, является то, что, как и в модели сегментации PL/M-86 COMPACT […], он может иметь только один сегмент кода и один сегмент данных, вместо того, чтобы позволять базовым адресам этих сегментов и, следовательно, самим сегментам , динамически изменяются. Это означает, что программы PIC обязательно имеют длину менее 64 КБ. Код PIC может быть создан с помощью элемента управления BIND LINK86. Код, размещаемый во время загрузки (обычно называемый LTL-кодом), является третьей формой объектного кода. Код LTL аналогичен PIC тем, что код LTL можно загрузить в любом месте памяти. Однако при загрузке LTL-кода загрузчик изменяет базовую часть указателей так, чтобы указатели не зависели от исходного содержимого регистров микропроцессора. Благодаря этому исправлению (корректировке базовых адресов) код LTL может использоваться задачами, имеющими более одного сегмента кода или более одного сегмента данных. Это означает, что программы LTL могут иметь длину более 64 КБ. FORTRAN 86 и Pascal 86 автоматически создают код LTL даже для коротких программ. Код LTL может быть создан с помощью элемента управления BIND LINK86. […]
  2. ^ аб Левин, Джон Р. (2000) [октябрь 1999 г.]. «Глава 1: Связывание и загрузка и Глава 3: Объектные файлы». Линкеры и загрузчики. Серия Моргана Кауфмана по разработке программного обеспечения и программированию (1-е изд.). Сан-Франциско, Калифорния, США: Морган Кауфманн . п. 5. ISBN 1-55860-496-0. OCLC  42413382. Архивировано из оригинала 5 декабря 2012 г. Проверено 12 января 2020 г.Код: [1][2] Ошибки: [3]
  3. ^ Борланд (1999-09-01) [1998-07-02]. «Статья Borland № 15961: Борьба с сообщениями о переполнении исправлений» . сообщество.borland.com . База данных технической информации — Продукт: Borland C++ 3.1. TI961C.txt #15961. Архивировано из оригинала 7 июля 2008 г. Проверено 15 января 2007 г.
  4. ^ «Исполняемый и связываемый формат (ELF)» (PDF) . сайт skyfree.org . Спецификация портативных форматов стандартов интерфейса инструментов (TIS), версия 1.1. Архивировано (PDF) из оригинала 24 декабря 2019 г. Проверено 1 октября 2018 г.

дальнейшее чтение