Подтвердить что ты не робот

Как изменить имя файла в общей библиотеке после создания программы, которая зависит от нее?

У меня есть программа, которая зависит от общей библиотеки, которую она ожидает найти внутри структуры каталогов. Я бы хотел переместить эту общую библиотеку и стать лучше. В OS X это можно сделать с помощью install_name_tool. Я не могу найти эквивалент для Linux.

Для справки, readelf -d myprogram выплевывает следующий перефразируемый вывод:

Dynamic section at offset 0x1e9ed4 contains 30 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [this/is/terrible/library.so]
 0x00000001 (NEEDED)                     Shared library: [libGL.so.1]
 0x00000001 (NEEDED)                     Shared library: [libGLU.so.1]
 0x00000001 (NEEDED)                     Shared library: [libstdc++.so.6]
(continues in an uninteresting fashion)

(и по запросу ldd myprogram:)

    linux-gate.so.1 =>  (0x0056a000)
    this/is/terrible/library.so => not found
    libGL.so.1 => /usr/lib/mesa/libGL.so.1 (0x0017d000)
    libGLU.so.1 => /usr/lib/libGLU.so.1 (0x00a9c000)
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00710000)
   (etc, etc)

и мне бы хотелось, чтобы этот файл /this/is/terrible/library.so был "shared/library.so". Обратите внимание, что если программа остается в своем "построенном" месте, где фактический путь//ужас/library.so существует, то ldd может найти его, как и следовало ожидать.

Я знаю о RPATH, и это не то, что я ищу, мне не нужно менять пути поиска по всему миру.

4b9b3361

Ответ 1

HT - это может быть полезно.

HT - это редактор файлов/просмотрщик/анализатор для исполняемых файлов. Цель состоит в том, чтобы объединить низкоуровневые функции отладчика и удобство использования IDE. Мы планируем реализовать все (шестнадцатеричные) функции редактирования и поддержку наиболее важных форматов файлов.

Я не мог найти что-то сильно отличающееся от решения ZorbaTHut, но, возможно, возможно поместить имя с разной длиной и все равно сохранить двоичный файл.

gelf - это тоже может быть полезно.

GElf - это общий API-интерфейс, не зависящий от ELF для манипулирования,      объектных файлов ELF. GElf обеспечивает единую,      face для обработки 32-битных и 64-разрядных объектных файлов формата ELF.

Ответ 2

Публикация пробного, ужасного, хакерского решения.

Библиотечные зависимости хранятся в блоке ELF, известном как блок .depends. Формат этого блока представляет собой большой массив пар идентификаторов/строк строк, причем указатель строки указывает на стандартную строку с нулевым символом, расположенную где-то в двоичном формате.

Вы видите, где это происходит, правильно?

Да, если новый путь вам не больше старого пути, вы можете просто дойти до двоичного кода и просто заменить строку. Убедитесь, что вы не добавляете или не удаляете байты, или вы разбиваете весь двоичный файл. Если вы хотите быть более уверенным в этом, вы могли бы пройти через структуру ELF, чтобы убедиться, что у вас есть правильное местоположение. Сейчас я просто проверяю, чтобы строка источника отображалась ровно один раз.

ELF включает контрольную сумму, но, видимо, нет загрузчика, который на самом деле проверяет его, поэтому он "безопасен" - хотя и беспорядочный - игнорировать.

"Реальное решение" было бы полезностью, которая позволяла бы обобщенные манипуляции низкоуровневого управления структурой ELF. Насколько я могу судить, никакой такой утилиты не существует ни для чего, кроме нескольких специализированных случаев (RPATH, в основном.) Я не претендую на то, чтобы знать, насколько сложно будет написать такую ​​утилиту.

Мне бы очень понравилось лучшее решение этого, но пока это работает.

Ответ 3

Мы можем использовать patchelf:

patchelf --replace-needed liboriginal.so.1 libreplacement.so.1 my-program

Мы также можем удалить зависимость:

patchelf --remove-needed libfoo.so.1 my-program

Добавить зависимость:

patchelf --add-needed libfoo.so.1 my-program

Или измените путь поиска библиотек (rpath):

patchelf --set-rpath /path/to/lib:/other/path my-program

Ответ 4

Вы можете использовать LD_LIBRARY_PATH для изменения пути поиска для разделяемых библиотек. Если ваша программа зависит от определенного относительного пути, как показывает ваш пример, вам все равно придется иметь эту структуру каталогов. Другими словами, вы можете переместить lib с /home/user/dev/project/this/is/terrible/library.so на /usr/local/lib/this/is/terrible/library.so, но не на /usr/local/lib/library.so

Если вы можете перестроить свою программу, вы можете изменить относительный путь, который он использует для lib.

Там есть дополнительная информация об общих libs в Linux на http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html