Я пытаюсь узнать больше о версиях библиотек в Linux и о том, как заставить все это работать. Вот контекст:
- У меня есть две версии динамической библиотеки, которые предоставляют один и тот же набор интерфейсов, скажем, libsome1.so
и libsome2.so
.
- Приложение связано с libsome1.so
.
- Это приложение использует libdl.so
для динамической загрузки, скажем, другой модуль libmagic.so
.
- Сейчас libmagic.so
связано против libsome2.so
. Очевидно, что без использования сценариев компоновщика для скрытия символов во libmagic.so
время выполнения все вызовы интерфейсов libsome2.so
разрешаются libsome1.so
. Это может быть подтверждено проверкой значения, возвращаемого libVersion()
значением макроса LIB_VERSION
.
- Поэтому я пытаюсь затем скомпилировать и связать libmagic.so
с помощью сценария компоновщика, который скрывает все символы, кроме 3, которые определены в libmagic.so
и экспортируются им. Это работает ... Или, по крайней мере, libVersion()
и LIB_VERSION
значения совпадают (и это сообщает версию 2, а не 1).
- Однако, когда некоторые структуры данных сериализуются на диск, я заметил некоторое повреждение. В каталоге приложения, если я удаляю libsome1.so
и создаю на его месте программную ссылку, чтобы все указывало libsome2.so
, все работает, как ожидалось, и такое же повреждение не происходит.
Я не могу не думать, что это может быть вызвано некоторым конфликтом в разрешении символов компоновщика во время выполнения. Я пробовал много вещей, например, пытался скомпоновать libsome2.so
так, чтобы все символы были разделены на symbol@@VER_2
(что я все еще запутался, потому что команда nm -CD libsome2.so
все еще перечисляет символы как symbol
и нет symbol@@VER_2
) ... Ничто, кажется, не работает !!! Помогите!!!!!!
источник
RTLD_LOCAL
иRTLD_DEEPBIND
установите флаги в вашем приложении. У меня нет времени, чтобы проверить это сейчас, но это должно работать на основе man-страницы.Ответы:
Это не совсем отвечает на ваш вопрос, но ...
Прежде всего, ELF - это спецификация, используемая Linux для исполняемых файлов (программ), разделяемых библиотек, а также объектных файлов, которые являются промежуточными файлами, обнаруживаемыми при компиляции программного обеспечения. Объектные файлы заканчиваются на .o, разделяемые библиотеки заканчиваются на .so, за которым следуют ноль или более цифр, разделенных точками, а исполняемые файлы обычно не имеют никакого расширения.
Обычно существует три формы для именования общей библиотеки, первая форма просто заканчивается на .so. Например, библиотека с именем readline хранится в файле с именем libreadline.so и обычно находится в одной из папок / lib, / usr / lib или / usr / local / lib. Этот файл находится при компиляции программного обеспечения с параметром, например -lreadline. -l говорит компилятору связать со следующей библиотекой. Поскольку библиотеки время от времени меняются, они могут устареть, поэтому библиотеки встраивают нечто, называемое SONAME. SONAME для readline может выглядеть как libreadline.so.2 для основной версии libreadline второй версии. Также может быть много минорных версий readline, которые совместимы и не требуют перекомпиляции программного обеспечения. Младшая версия readline может быть названа libreadline.so.2.14. Обычно libreadline. это просто символическая ссылка на самую последнюю основную версию readline, в данном случае libreadline.so.2. libreadline.so.2 также является символической ссылкой на libreadline.so.2.14, которая фактически является используемым файлом.
SONAME библиотеки встроен в сам файл библиотеки. Где-то внутри файла libreadline.so.2.14 находится строка libreadline.so.2. Когда программа компилируется и связывается с readline, она ищет файл libreadline.so и считывает встроенное в него SONAME. Позже, когда программа действительно выполняется, она загружает libreadline.so.2, а не только libreadline.so, поскольку это был SONAME, который был прочитан при первой ссылке. Это позволяет системе иметь несколько несовместимых версий readline, и каждая программа будет загружать соответствующую основную версию, с которой она связана. Кроме того, при обновлении readline, скажем, до 2.17, я могу просто установить libreadline.so.2.17 вместе с существующей библиотекой, и как только я переместу символическую ссылку libreadline.so.2 с libreadline.so.2.13 на libreadline.so.2.17,
источник