Ответ 1
Существует инструмент chrpath
, который может это сделать - он, вероятно, доступен в ваших дистрибутивных пакетах.
У меня есть старый исполняемый файл, который запланирован на кучу отходов, но он еще не существует. Он полагается на некоторые библиотеки, которые были удалены из моей среды, но у меня есть некоторые файлы-заглушки где-нибудь, где он работает нормально. Id нравится указывать этот исполняемый файл на эти файлы-заглушки. Да, я могу установить LD_LIBRARY_PATH, но этот исполняемый файл вызывается из многих сценариев, и многие пользователи, и я бы хотел его исправить в одном месте.
У меня нет источника для этого, и было бы трудно получить его. Я думал: могу ли я отредактировать этот файл, используя редактор ELF, и добавить простой PATH в rpath, чтобы он попал в новые библиотеки? Возможно ли это, или как только вы создадите двоичный файл ELF, вы исправляете вещи в местах и их нельзя перемещать?
Существует инструмент chrpath
, который может это сделать - он, вероятно, доступен в ваших дистрибутивных пакетах.
Существует более универсальный инструмент, чем chrpath
, называемый patchelf
. Он был первоначально создан для использования в создании пакетов для Nix и NixOS (система упаковки и дистрибутив GNU/Linux).
Если в двоичном коде отсутствует rpath (здесь называется rdsamp), chrpath
завершается сбой:
chrpath -r '$ORIGIN/../lib64' rdsamp
rdsamp: no rpath or runpath tag found.
С другой стороны,
patchelf --set-rpath '$ORIGIN/../lib64' rdsamp
преуспевает просто отлично.
Как сказал @user7610, правильный путь - это инструмент patchelf
.
Но я чувствую, что могу дать более полный ответ, охватывающий все команды, необходимые для выполнения именно этого.
Если вы хотите прочитать подробное объяснение по этому вопросу, вы можете найти больше информации здесь.
Прежде всего, многие разработчики говорят о RPATH
, но на самом деле они имеют в виду RUNPATH
. Это два разных необязательных динамических раздела, и загрузчик обрабатывает их совершенно по-разному. Вы можете прочитать больше о разнице между ними в ссылке, которую я упоминал ранее.
А пока просто помните:
RUNPATH
установлен, RPATH
игнорируетсяRPATH
устарела и ее следует избегатьRUNPATH
является предпочтительным, потому что он может быть переопределен LD_LIBRARY_PATH
Смотрите текущий R [UN] PATH
readelf -d <path-to-elf> | egrep "RPATH|RUNPATH"
Очистить путь R [UN]
patchelf --remove-rpath <path-to-elf>
Заметки:
RPATH
и RUNPATH
Добавить значения в R [UN] PATH
patchelf [--force-rpath] --set-rpath "<desired-rpath>" <path-to-elf>
Заметки:
<desired-path>
- это список каталогов, разделенный запятыми, например: /my/libs: /my/other/libs
--force-rpath
, устанавливает RPATH
, в противном случае устанавливает RUNPATH
Это сработало для меня, заменив XORIGIN на $ORIGIN.
chrpath -r '\$\ORIGIN/../lib64' httpd