Scroll to navigation

LD.SO(8) Руководство программиста Linux LD.SO(8)

ИМЯ

ld.so, ld-linux.so* - динамический компоновщик/загрузчик

ОБЗОР

Динамический компоновщик может запускаться неявно из динамически скомпонованной программы или библиотеки (в этом случае динамическому компоновщику невозможно передать параметры командной строки, как и в случае с ELF, когда динамический компоновщик хранится в разделе .interp исполняемой программы) или явно с помощью вызова:

/lib/ld-linux.so.* [ПАРАМЕТРЫ] [ПРОГРАММА [АРГУМЕНТЫ]]

ОПИСАНИЕ

Программы ld.so и ld-linux.so* ищут и загружают динамические библиотеки, необходимые программе, а также подготавливают программу к запуску и запускают её.

Для двоичных файлов Linux требуется динамическая компоновка (компоновка во время выполнения), если при сборке программе ld(1) не был передан параметр -static.

Программа ld.so предназначена для обработки двоичных файлов в формате a.out (старый формат); ld-linux.so* предназначена для обработки файлов в формате ELF (/lib/ld-linux.so.1, если используется libc5 и /lib/ld-linux.so.2, если glibc2), который используется последние несколько лет. Обе программы ведут себя одинаково и используют те же самые файлы поддержки и программы ldd(1), ldconfig(8) и /etc/ld.so.conf.

Динамические библиотеки, необходимые программе, ищутся в следующем порядке:

(только для ELF) В каталогах, указанных в атрибуте DT_RPATH динамического раздела двоичного файла, если он есть и если атрибут DT_RUNPATH не существует. Использование DT_RPATH не рекомендуется.
В переменной окружения LD_LIBRARY_PATH. Если исполняется двоичный файл с установленным set-user-ID/set-group-ID битом, то в этом случае она игнорируется.
(только для ELF) В каталогах, указанных в атрибуте DT_RUNPATH динамического раздела двоичного файла, если он есть.
В кэш-файле /etc/ld.so.cache, содержащем скомпилированный список библиотек-кандидатов, которые ранее были найдены по указанным путям расположения библиотек. Однако, если при сборке двоичного файла компоновщику был указан параметр -z nodeflib, то библиотеки в путях по умолчанию будут пропущены. Библиотеки, установленные в каталоги для аппаратных возможностей (см. далее) имеют больший приоритет, чем остальные библиотеки.
В каталоге по умолчанию /lib и затем в /usr/lib. Если при сборке двоичного файла компоновщику был указан параметр -z nodeflib, то этот шаг пропускается.

$ORIGIN и rpath

ld.so обрабатывает строку $ORIGIN (то же самое, что ${ORIGIN}) согласно спецификации rpath (DT_RPATH или DT_RUNPATH) для поиска каталога, в котором содержится исполняемый файл приложения. Таким образом, приложение, расположенное в somedir/app может компилироваться с gcc -Wl,-rpath,'$ORIGIN/../lib' для того, чтобы оно могло найти связанную динамическую библиотеку в somedir/lib и не важно где в иерархии каталогов будет находиться somedir. Это облегчает создание приложений "под ключ", которые вместо установки в специальные каталоги, можно просто распаковать в любой каталог, и они всё равно найдут свои динамические библиотеки.

ПАРАМЕТРЫ

Выдать список всех зависимостей и как они удовлетворяются.
Проверить, что программа является динамически скомпонованной и что компоновщик понимает её формат.
Использовать PATH вместо значения переменной окружения LD_LIBRARY_PATH (см. далее).
Игнорировать информацию в RPATH и RUNPATH об именах объектов из СПИСКА. Этот параметр игнорируется, если на ld.so установлен бит is set-user-ID или set-group-ID.
Использовать объекты из СПИСКА в качестве аудиторов.

АППАРАТНЫЕ ВОЗМОЖНОСТИ

Некоторые библиотеки скомпилированы с использованием специальных аппаратных инструкций, которые существуют не в каждом ЦП. Такие библиотеки должны быть установлены в каталоги, чью имена (например, /usr/lib/sse2/) определяют требования к аппаратным возможностям. Динамический компоновщик проверяет эти каталоги учитывая аппаратуру машины и выбирает наиболее подходящую версию требуемой библиотеки. Каталоги аппаратных возможностей могут каскадироваться для объединения свойств ЦП. Список имён поддерживаемых аппаратных возможностей зависит от ЦП. В настоящее время распознаются следующие имена:

ev4, ev5, ev56, ev6, ev67
loongson2e, loongson2f, octeon, octeon2
4xxmac, altivec, arch_2_05, arch_2_06, booke, cellbe, dfp, efpdouble, efpsingle, fpu, ic_snoop, mmu, notb, pa6t, power4, power5, power5+, power6x, ppc32, ppc601, ppc64, smt, spe, ucache, vsx
flush, muldiv, stbar, swap, ultra3, v9, v9v, v9v2
dfp, eimm, esan3, etf3enh, g5, highgprs, hpage, ldisp, msa, stfle, z900, z990, z9-109, z10, zarch
acpi, apic, clflush, cmov, cx8, dts, fxsr, ht, i386, i486, i586, i686, mca, mmx, mtrr, pat, pbe, pge, pn, pse36, sep, ss, sse, sse2, tm

ОКРУЖЕНИЕ

Существует четыре важные переменные окружения.

(libc5; в glibc начиная с версии 2.1.1) Если переменная содержит непустую строку, то динамический компоновщик будет искать все символы при запуске программы вместо того, чтобы отложить поиск вызовов функций до момента, когда они встретятся в первый раз. Это полезно при отладке.
Содержит список разделённых двоеточием каталогов, в которых будет производиться поиск ELF библиотек в момент выполнения. Похожа на переменную окружения PATH.
Содержит заданный пользователем список дополнительных динамических ELF библиотек разделённых пробелами, которые будут загружены перед всеми другими. Это можно использовать для выборочной замены функций в других динамических библиотеках. Для двоичных файлов ELF с установленным битом set-user-ID/set-group-ID будут загружены только библиотеки в стандартных каталогах поиска и которые также имеют установленный set-user-ID.
(только для ELF) Если переменная содержит непустую строку, то вместо нормального запуска программы будут выданы её зависимости от динамических библиотек, как если бы она была запущена через ldd(1).

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

(libc5) Тоже что и LD_LIBRARY_PATH, но только для двоичных файлов в формате a.out. Старые версии ld-linux.so.1 также поддерживают LD_ELF_LIBRARY_PATH.
(libc5) Тоже что и LD_PRELOAD, но только для двоичных файлов в формате a.out. Старые версии ld-linux.so.1 также поддерживают LD_ELF_PRELOAD.
(в glibc начиная с 2.4) Определяемый пользователем список динамических объектов ELF разделяемых двоеточиями, которые будут загружены раньше всех остальных в отдельном пространстве имён компоновщика (т.е., они не внедряются вместо обычных привязываемых символов, которые могли бы быть в этом процессе). Эти библиотеки можно использовать для контрольной проверки операций динамического компоновщика. LD_AUDIT игнорируется, если на двоичном файле установлены биты set-user-ID/set-group-ID.

Динамический компоновщик будет уведомлять библиотеки контроля в так называемых точках контроля — например, при загрузке новой библиотеки, поиске символа или при вызове символа из другого динамического объекта — вызывая соответствующую функцию библиотеки контроля. Подробности смотрите в rtld-audit(7). Интерфейс контроля в значительной степени совместим с предоставляемым Solaris, описан в его Руководстве по компоновщику и библиотекам (Linker and Libraries Guide) в главе Интерфейс контроля компоновщика во время выполнения (Runtime Linker Auditing Interface).

(в glibc начиная с 2.1.95) Не обновлять GOT (global offset table — таблицу глобальных перемещений) и PLT (procedure linkage table — таблицу компоновки процедур) после нахождения символа.
(в glibc начиная с 2.1) Выводить подробную отладочную информацию о динамическом компоновщике. Если значение равно all, то выдаётся вся имеющаяся отладочная информация, если значение равно help, то выдаётся справка о некоторых категориях, которые могут быть указаны в этой переменной окружения. Начиная с glibc 2.3.4, LD_DEBUG игнорируется, если на двоичном файле установлены биты set-user-ID/set-group-ID.
(в glibc начиная с 2.1) Файл куда будет записываться вывод LD_DEBUG — по умолчанию это стандартный вывод. LD_DEBUG_OUTPUT игнорируется, если на двоичном файле установлены биты set-user-ID/set-group-ID.
(в glibc начиная с 2.1.91) Разрешить перекрытие слабых символов (возврат к поведению старой glibc). В целях безопасности начиная с glibc 2.3.4 LD_DYNAMIC_WEAK игнорируется, если на двоичном файле установлены биты set-user-ID/set-group-ID.
(в glibc начиная с 2.1) Маска для совместимости с аппаратными возможностями.
(только для a.out)(libc5) Не игнорировать каталог для загрузки в именах a.out библиотек. Настоятельно не рекомендуется использовать этот параметр.
(только a.out)(libc5) Подавлять предупреждения о библиотеках a.out с несовместимыми младшими номерами версий.
(в glibc начиная с 2.1) Путь, где находится двоичный файл (для не set-user-ID программ). В целях безопасности начиная с glibc 2.4 LD_ORIGIN_PATH игнорируется, если на двоичном файле установлены биты set-user-ID/set-group-ID.
(в glibc начиная с 2.4) Значение 0 отключает защиту указателя. Любое другое значение включает защиту указателя, что является действием по умолчанию. Защита указателя — это механизм безопасности, в результате которого некоторые указатели на код, хранящийся в перезаписываемой памяти программы (адреса возврата, сохраняемые setjmp(3) или указатели на функцию, используемые различными внутренними функциями glibc), искажаются полупроизвольным образом, что затрудняет атакующему подбор указателей для проведения атак переполнения буфера или срыва стека.
(в glibc начиная с 2.1) В переменной задаётся динамический объект для профилирования, в виде пути или имени so. Результат профилирования записывается в файл с именем: "$LD_PROFILE_OUTPUT/$LD_PROFILE".
(в glibc начиная с 2.1) Каталог, куда будет сохраняться результат работы с LD_PROFILE. Если эта переменная не определена или её значение равно пустой строке, то по умолчанию результат будет сохранён в каталог /var/tmp. Переменная LD_PROFILE_OUTPUT игнорируется для программ с установленными флагами set-user-ID и set-group-ID, для которых всегда используется /var/profile.
(в glibc начиная с 2.1) Показать вспомогательный массив, передаваемый из ядра. В целях безопасности начиная с glibc 2.3.5 LD_SHOW_AUXV игнорируется, если на двоичном файле установлены биты set-user-ID/set-group-ID.
По умолчанию (т.е., если переменная не определена) исполняемые и предварительно скомпонованные объекты учитывают базовые адреса библиотек, от которых они зависят, а (предварительно не скомпонованные) перемещаемые исполняемые (PIE) и другие динамические объекты не учитывают их. Если переменной LD_USE_LOAD_BIAS присвоено значение, то и исполняемые файлы и PIE учитывают базовые адреса. Если значение переменной LD_USE_LOAD_BIAS равно 0, то ни исполняемые файлы ни PIE не учитывают базовые адреса. Эта переменная игнорируется программами с флагами set-user-ID и set-group-ID.
(в glibc начиная с 2.1) Если значение равно непустой строке, то выводится информация о символах программы, если запрашивается информация о программе (т.е., установлена переменная LD_TRACE_LOADED_OBJECTS или динамическому компоновщику переданы параметры --list или --verify).
(только для ELF)(в glibc начиная с 2.1.3) Если значение равно непустой строке, то выдаются предупреждения о ненайденных символах.
(libc5) Значение argv[0] будет использоваться ldd(1), если другого нет.

ФАЙЛЫ

/lib/ld.so
динамический компоновщик/загрузчик a.out
/lib/ld-linux.so.{1,2}
динамический компоновщик/загрузчик ELF
/etc/ld.so.cache
Файл с скомпилированным списком каталогов, в которых производится поиск библиотек и сортированный список библиотек-кандидатов.
/etc/ld.so.preload
Файл со списком динамических ELF библиотек (через пробел), которые будут загружены перед программой.
динамические библиотеки

ЗАМЕЧАНИЯ

Функциональность ld.so доступна для исполняемых программ, скомпилированных с использованием libc версии 4.4.3 или выше. Функциональность ELF доступна начиная с Linux 1.1.52 и libc5.

СМОТРИТЕ ТАКЖЕ

ldd(1), rtld-audit(7), ldconfig(8)

2012-04-17 GNU