общая библиотека RPATH и двоичный приоритет RPATH

если разделяемая библиотека связана с двоичным файлом, и разделяемая библиотека также зависит от других библиотек, каковы приоритеты (порядок поиска компоновщика) для RPATH разделяемой библиотеки и RPATH для двоичного файла? Может ли RPATH двоичного файла переопределить значение в общей библиотеке? и $ ORIGIN, который я установил в общей библиотеке RPATH, относится к расположению lib или расположению двоичного файла?
Заранее спасибо.

3

Решение

По моим наблюдениям, если есть приложение main который динамически загружает библиотеку first.soа последний в свою очередь динамически загружает библиотеку second.soи оба main а также first.so содержит RPATH, тогда динамический компоновщик будет искать second.so сначала используя first.soRPATH, решая $ ORIGIN как first.soкаталог, и только в случае сбоя компоновщик перейдет к mainRPATH теперь разрешает $ ORIGIN как mainкаталог

Это не противоречит документ динамического компоновщика (ищите расширение токена Rpath):

$ ORIGIN (или эквивалентно $ {ORIGIN}): расширяется до каталога, содержащего программу или общий объект. …

Чтобы проверить это, я создал тестовое приложение и две библиотеки: main, liba а также libb соответственно. main связано с liba, а также liba связано с libb:

main -> liba.so -> libb.so

Встроенные двоичные файлы расположены так:

/cwd/main
/cwd/lib/liba.so
/cwd/lib/libb.so

И то и другое main а также liba построены с --rpath=\$ORIGIN/lib флаг компоновщика:

~$ readelf -a /cwd/main | grep ORIGIN
0x000000000000000f (RPATH)              Library rpath: [$ORIGIN/lib]
~$ readelf -a /cwd/lib/liba.so | grep ORIGIN
0x000000000000000f (RPATH)              Library rpath: [$ORIGIN/lib]

С помощью LD_DEBUG переменная окружения Я проверил, как динамический компоновщик обрабатывает RPATH:

~$ LD_DEBUG=libs /cwd/main
:     find library=liba.so [0]; searching
:      search path=/cwd/lib/tls/x86_64:/cwd/lib/tls:/cwd/lib/x86_64:/cwd/lib              (RPATH from file /cwd/main)
:       trying file=/cwd/lib/tls/x86_64/liba.so
:       trying file=/cwd/lib/tls/liba.so
:       trying file=/cwd/lib/x86_64/liba.so
:       trying file=/cwd/lib/liba.so
94313:
:     find library=libc.so.6 [0]; searching
:      search path=/cwd/lib                (RPATH from file /cwd/main)
:       trying file=/cwd/lib/libc.so.6
:      search cache=/etc/ld.so.cache
:       trying file=/lib/x86_64-linux-gnu/libc.so.6
94313:
:     find library=libb.so [0]; searching
:      search path=/cwd/lib/lib/tls/x86_64:/cwd/lib/lib/tls:/cwd/lib/lib/x86_64:/cwd/lib/lib              (RPATH from file /cwd/lib/liba.so)
:       trying file=/cwd/lib/lib/tls/x86_64/libb.so
:       trying file=/cwd/lib/lib/tls/libb.so
:       trying file=/cwd/lib/lib/x86_64/libb.so
:       trying file=/cwd/lib/lib/libb.so
:      search path=/cwd/lib                (RPATH from file /cwd/main)
:       trying file=/cwd/lib/libb.so

Из этого видно, что компоновщик первым сталкивается с необходимостью загрузки liba.so и использует main RPATH двоичного файла, чтобы решить эту проблему. Тогда он сталкивается с необходимостью загрузки libb.so и сначала он использует liba.so RPATH библиотеки, чтобы решить эту проблему. Но так как RPATH $ORIGIN/lib а также libb.so находится в том же каталоге, что и liba.soкомпоновщик не может найти libb.so с помощью liba.soRPATH. После этого он возвращается к mainRPATH и только используя последний, он может найти libb.so,

Тестовая среда: Linux Ubuntu 4.15.0-34-generic # 37 ~ 16.04.1-Ubuntu (64-разрядная версия), /lib/x86_64-linux-gnu/ld-2.23.so.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]