Действительно ли возможно настроить динамический загрузчик для исполняемого файла

На самом деле это - корректное поведение.

Ниже кавычка отсюда:

Ответ очень интересен. По умолчанию, gcc на Linux связывает программы с библиотеками времени выполнения C динамично. То, что это означает, - то, что одной из первых вещей, которая работает, когда любая программа выполнена, является динамический загрузчик библиотеки, который ищет необходимые общие библиотеки. Это - довольно много кода – и помните, что наш основной трассировщик здесь смотрит на каждую инструкцию, не просто основной функции, а целого процесса.

3
30.03.2016, 21:28
3 ответа

Можно использовать относительный rpath, используя $ORIGIN.

Связывание исполняемых файлов с помощью -Wl,-rpath,'$ORIGIN/... /lib' позволяет исполняемым файлам найти свои библиотеки, устанавливая :

  • исполняемые файлы в /bin/
  • разделяемые библиотеки в /lib/

Продолжая таким образом, можно настроить эту связь только для этих исполняемых файлов, а каталог может быть любым.

0
27.01.2020, 21:31

Нелегко. Файлы ld.so.conf имеют очень простой формат: это просто список путей.

Вы могли бы сделать что-нибудь, собрав свой исполняемый файл с другим интерпретатором ; обычным было бы что-нибудь вроде /lib64/ld-linux-x86-64.so.21 и это то, что на самом деле отвечает за выполнение динамического линковки. Так что ваш пользовательский динамический компоновщик может выглядеть в другом ld.so.conf, или делать что угодно. Но это звучит намного хуже, чем rpath!

Гораздо более простое решение - обертка. Установите бинарник как program.real, или, что еще лучше, где-нибудь в /usr/local/lib/ (то есть не в $PATH). Затем поместите простой скрипт оболочки в виде /usr/local/bin/program:

#!/bin/sh
export LD_LIBRARY_PATH=/path/to/libs
exec /usr/local/lib/program/program.real

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




1: Быстрый способ найти то, что обычно находится в вашей системе: читайте /bin/bash -p .interp. Попробуйте несколько разных исполняемых файлов; вы увидите, что как минимум 32- и 64-битные программы используют разные.

2
27.01.2020, 21:31

Аргумент filename для dlopen может быть абсолютным путем (начинается с ' / ').

Итак, сохраните «частный путь» в конфигурационном файле и создайте из него полное имя библиотеки. Или, если вы знаете, что частная библиотека будет в том же каталоге, что и исполняемый файл, выполните простые строковые операции на пути к исполняемому файлу, чтобы найти его ...

#include <dlfcn.h>
#include <unistd.h>
#include <string.h>

static int (*foo)();

/* ... */
char buf[BUFSIZ];
char *lastslash;
void *handle;

realpath(argv[0],buf);
lastslash = strrchr(buf,'/');
strcpy(lastslash,"foo." VERSION_BUILD ".so");
dlopen(buf,RTLD_LOCAL | RTLD_LAZY);
*(void **)(&foo) = dlsym(handle, "foo");

/* ... */
printf("%d\n",foo());
-1
27.01.2020, 21:31

Теги

Похожие вопросы