Динамический компоновщик
В вычислениях динамический компоновщик — это часть операционной системы , которая загружает и связывает необходимые общие библиотеки, исполняемому файлу , когда он выполняется («во время выполнения »), путем копирования содержимого библиотек из постоянного хранилища в ОЗУ , заполнения перехода таблицы и перемещение указателей . Конкретная операционная система и формат исполняемого файла определяют, как функционирует динамический компоновщик и как он реализуется.
Связывание часто называют процессом, который выполняется при компиляции исполняемого файла , тогда как динамический компоновщик — это специальная часть операционной системы, которая загружает внешние общие библиотеки в работающий процесс , а затем динамически привязывает эти общие библиотеки к работающему процессу. Этот подход также называется динамическим связыванием или поздним связыванием .
Реализации
[ редактировать ]Microsoft Windows
[ редактировать ]Библиотека динамической компоновки , или DLL, — это Microsoft реализация концепции общей библиотеки в Microsoft Windows и OS/2 операционных системах . Эти библиотеки обычно имеют расширение файла DLL
, OCX
(для библиотек, содержащих элементы управления ActiveX ) или DRV
(для устаревших системных драйверов ). Форматы файлов DLL такие же, как и для файлов Windows EXE , то есть переносимый исполняемый файл (PE) для 32-битной и 64-битной Windows и новый исполняемый файл (NE) для 16-битной Windows. Как и EXE-файлы, библиотеки DLL могут содержать код , данные и ресурсы в любой комбинации.
данных Файлы того же формата , что и DLL, но с разными расширениями и, возможно, содержащие только разделы ресурсов, могут называться DLL ресурсов. Примеры таких DLL включают многоязычные библиотеки пользовательского интерфейса с расширением. MUI
, библиотеки значков , иногда имеющие расширение ICL
и файлы шрифтов , имеющие расширения FON
и FOT
. [1]
Unix-подобные системы, использующие ELF, и системы на основе Дарвина.
[ редактировать ]В большинстве Unix-подобных систем большая часть машинного кода, составляющего динамический компоновщик, на самом деле представляет собой внешний исполняемый файл, который ядро операционной системы загружает и выполняет сначала в адресном пространстве процесса, вновь созданном в результате вызова exec
или posix_spawn
функции. Во время компоновки путь к динамическому компоновщику, который следует использовать, внедряется в исполняемый образ.
Когда загружается исполняемый файл, ядро операционной системы считывает из него путь к динамическому компоновщику, а затем пытается загрузить и выполнить этот другой исполняемый двоичный файл; если эта попытка не удалась, например, из-за того, что по этому пути нет файла, попытка выполнить исходный исполняемый файл завершится неудачей. Затем динамический компоновщик загружает исходный исполняемый образ и все динамически подключаемые библиотеки, от которых он зависит, и запускает исполняемый файл. В результате путь к динамическому компоновщику является частью двоичного интерфейса приложения операционной системы .
Системы, использующие ELF
[ редактировать ]В Unix-подобных системах, использующих ELF для исполняемых образов и динамических библиотек, таких как Solaris , 64-битные версии HP-UX , Linux , FreeBSD , NetBSD , OpenBSD и DragonFly BSD , путь к динамическому компоновщику, который следует использовать. встраивается во время соединения в .interp
раздел исполняемого файла PT_INTERP
сегмент. В этих системах динамически загружаемые общие библиотеки можно идентифицировать по суффиксу имени файла. .so
(общий объект).
На динамический компоновщик можно повлиять, заставив его изменить свое поведение либо во время выполнения программы, либо во время компоновки программы, и примеры этого можно увидеть на страницах руководства компоновщика во время выполнения для различных Unix-подобных систем. [2] [3] [4] [5] [6] Типичной модификацией этого поведения является использование LD_LIBRARY_PATH
и LD_PRELOAD
переменные среды , которые корректируют процесс компоновки во время выполнения путем поиска общих библиотек в альтернативных местах и принудительной загрузки и связывания библиотек, которых в противном случае не было бы соответственно. Примером является zlibc, [7] также известный как uncompress.so
, [а] который облегчает прозрачную декомпрессию при использовании через LD_PRELOAD
взломать ; следовательно, можно читать предварительно сжатые (gzip) данные файла в системах BSD и Linux, как если бы файлы не были сжаты, что по сути позволяет пользователю добавлять прозрачное сжатие к базовой файловой системе, хотя и с некоторыми оговорками. Механизм является гибким, позволяя тривиально адаптировать один и тот же код для выполнения дополнительной или альтернативной обработки данных во время чтения файла до предоставления этих данных пользовательскому процессу, который их запросил. [8] [9]
macOS и iOS
[ редактировать ]В операционной системе Apple Darwin , а также в построенных на ее основе операционных системах macOS и iOS путь к динамическому компоновщику, который следует использовать, встроен во время компоновки в одну из команд загрузки Mach-O в исполняемом образе. В этих системах динамически загружаемые общие библиотеки можно идентифицировать либо по суффиксу имени файла, либо по суффиксу имени файла. .dylib
или путем их размещения внутри комплекта для каркаса.
Динамический компоновщик не только связывает целевой исполняемый файл с общими библиотеками, но также размещает функции машинного кода в определенных адресных точках памяти, о которых целевой исполняемый файл знает во время компоновки. Когда исполняемый файл хочет взаимодействовать с динамическим компоновщиком, он просто выполняет машинный вызов или инструкцию перехода к одной из этих хорошо известных адресных точек. Исполняемые файлы на платформах macOS и iOS часто взаимодействуют с динамическим компоновщиком во время выполнения процесса; известно даже, что исполняемый файл может взаимодействовать с динамическим компоновщиком, заставляя его загружать больше библиотек и обрабатывать больше символов через несколько часов после первоначального запуска. Причина, по которой программа macOS или iOS так часто взаимодействует с динамическим компоновщиком, связана как с Apple Cocoa и Cocoa Touch API , так и с Objective-C , языком, на котором они реализованы (дополнительную информацию см. в их основных статьях).
Динамический компоновщик можно заставить изменить некоторые части своего поведения; однако, в отличие от других Unix-подобных операционных систем, эти модификации представляют собой подсказки, которые могут (а иногда и игнорируются) динамическим компоновщиком. Примеры этого можно увидеть в dyld
справочная страница. [10] Типичной модификацией этого поведения является использование DYLD_FRAMEWORK_PATH
и DYLD_PRINT_LIBRARIES
переменные среды. Первая из ранее упомянутых переменных настраивает путь поиска исполняемых файлов для общих библиотек, а вторая отображает имена библиотек по мере их загрузки и связывания.
Динамический компоновщик Apple для macOS — это проект с открытым исходным кодом, выпущенный как часть Darwin , и его можно найти в документации Apple с открытым исходным кодом. dyld
проект. [11]
Unix-подобные системы на базе XCOFF
[ редактировать ]В Unix-подобных операционных системах, использующих XCOFF , таких как AIX , динамически загружаемые общие библиотеки используют суффикс имени файла. .a
.
На динамический компоновщик можно повлиять, чтобы он изменил свое поведение во время выполнения программы или во время компоновки программы.Типичной модификацией этого поведения является использование LIBPATH
переменная среды .Эта переменная регулирует процесс связывания во время выполнения, осуществляя поиск общих библиотек в альтернативных местах и принудительно загружая и связывая библиотеки, которых в противном случае не было бы соответственно.
OS/360 и его преемники
[ редактировать ]Динамическое связывание программ на языке ассемблера в IBM OS/360 и его преемниках обычно выполняется с использованием макрокоманды LINK, содержащей инструкцию вызова супервизора , которая активирует подпрограммы операционной системы, что делает связываемый библиотечный модуль доступным для программы. Модули библиотеки могут находиться в «STEPLIB» или «JOBLIB», указанных в картах управления и доступных только для конкретного выполнения программы, в библиотеке, включенной в список LINKLIST в PARMLIB (указанном во время запуска системы), или в « область пакета ссылок», куда загружаются определенные реентерабельные модули во время запуска системы.
Мультикс
[ редактировать ]В операционной системе Multics все файлы, включая исполняемые, являются сегментами . Вызов подпрограммы, не являющейся частью текущего сегмента, заставит систему найти указанный сегмент в памяти или на диске и добавить его в адресное пространство запущенного процесса. Динамическое связывание является обычным методом работы, а статическое связывание (с использованием связывателя ) является исключением.
Эффективность
[ редактировать ]Динамическое связывание обычно медленнее (требует больше циклов ЦП), чем связывание во время компиляции. [12] как и в случае большинства процессов, выполняемых во время выполнения. Однако динамическое связывание часто более эффективно использует пространство (на диске и в памяти во время выполнения). Когда библиотека связана статически, каждый запускаемый процесс связан со своей собственной копией вызываемых библиотечных функций. Поэтому, если библиотека вызывается много раз разными программами, одни и те же функции в этой библиотеке дублируются в нескольких местах системной памяти. Использование общих динамических библиотек означает, что вместо того, чтобы связывать каждый файл с его собственной копией библиотеки во время компиляции и потенциально тратить пространство памяти, в памяти одновременно хранится только одна копия библиотеки, освобождая пространство памяти для использования. используется в другом месте. [13] Кроме того, при динамическом связывании библиотека загружается только в том случае, если она действительно используется. [14]
См. также
[ редактировать ]- Прямая привязка
- DLL Ад
- Динамическая загрузка
- Позднее связывание
- предварительная ссылка
- Динамическое устранение мертвого кода
Примечания
[ редактировать ]- ^ Не путать с библиотекой сжатия zlib .
Ссылки
[ редактировать ]- ^ Корпорация Майкрософт. «Создание DLL, предназначенной только для ресурсов» . Сетевая библиотека разработчиков Microsoft .
- ^ Solaris 11.4 по пользовательским командам Справочное руководство : Динамический компоновщик/загрузчик Solaris –
- ^ Linux программиста Руководство – Администрирование и привилегированные команды –
- ^ FreeBSD по основным командам Руководство : Динамический компоновщик/загрузчик FreeBSD –
- ^ NetBSD по общим командам Руководство : Динамический компоновщик/загрузчик NetBSD –
- ^ OpenBSD по основным командам Руководство : Динамический компоновщик/загрузчик OpenBSD –
- ^ «ZLIBC — Прозрачный доступ к сжатым файлам» . Архивировано из оригинала 4 июня 2000 г.
- ^ "uncompress.so" . Делори.com . Проверено 4 июля 2014 г.
- ^ "zlibc.conf" . Делори.com . Проверено 4 июля 2014 г.
- ^ Darwin и macOS по общим командам Руководство : Динамический компоновщик/загрузчик Darwin/Mac OS X –
- ^ Apple Inc. «Открытый исходный код — Релизы» . apple.com . Проверено 4 июля 2014 г.
- ^ Сюсянь, Цзян (2009). «Принципы операционных систем: связывание и загрузка» (PDF) . Государственный университет Северной Каролины . Проверено 24 сентября 2020 г.
- ^ Джонс, М. (28 августа 2008 г.). «Анатомия динамических библиотек Linux» . ИБМ . Проверено 24 сентября 2020 г.
- ^ Сивилотти, Пол (август 2012 г.). «Динамическое связывание и загрузка» (PDF) . Университет штата Огайо . Проверено 24 сентября 2020 г.
Дальнейшее чтение
[ редактировать ]- Левин, Джон Р. (2000) [октябрь 1999 г.]. Линкеры и загрузчики . Серия Моргана Кауфмана по разработке программного обеспечения и программированию (1-е изд.). Сан-Франциско, США: Морган Кауфманн . ISBN 1-55860-496-0 . OCLC 42413382 . Архивировано из оригинала 5 декабря 2012 г. Проверено 12 января 2020 г. Код: [1] [2] Ошибки: [3]
Внешние ссылки
[ редактировать ]- Динамическое связывание и загрузка , IECC.com
- Динамическое связывание в Linux и Windows, часть первая , Symantec.com
- Анатомия динамических библиотек Linux , IBM.com