соединить с двумя общими библиотеками, экспортируя символы - PullRequest
8 голосов
/ 29 июля 2010

У меня есть общая библиотека linux, foo.so, которая загружается из исполняемого файла с использованием dlopen("foo.so", RTLD_NOW | RTLD_LOCAL).Из foo.so я хотел бы добавить другую библиотеку, bar.so, которая ссылается на символы, определенные в foo.so, но компоновщик не может их найти.Я не могу изменить RTLD_LOCAL на RTLD_GLOBAL, потому что у меня нет исходного кода для исполняемого файла, выполняющего загрузку.Я подумал -Wl,--export-dynamic, когда ссылка foo.so может помочь, но она не переопределяет локальный флаг на dlopen.Новая функция видимости атрибута GCC также не дает ответа.

Есть ли способ, которым я могу дать указание компоновщику разрешить ссылки на неопределенные символы в bar.so на эти определения в foo.so, безсвязать bar с -lfoo или сходство, переместить символы в 3-ю библиотеку и связать foo и bar с ней?Единственное, что приходит мне в голову, это добавить foo.so с RTLD_GLOBAL из самого foo.so, а затем dlopen bar.so, но это кажется мне беспорядочным.Спасибо.

1 Ответ

6 голосов
/ 31 июля 2010

Ссылка foo.so против bar.so.

Когда исполняемый файл dlopen() s foo.so, bar.so также будет загружен.

Кроме того, можно выполнить двоичное исправление исполняемого файла, добавив RTLD_GLOBAL к флажкам для вызова dlopen(). Код будет выглядеть примерно так:

    movl    $2, 4(%esp)       # $2 == RTLD_NOW; RTLD_LOCAL is 0
    movl    $0xNNNNN, (%esp)  # $0xNNNNN == &"foo.so"
    call    dlopen

Вместо этого укажите movl $0x102, 4(%esp) (RTLD_GLOBAL == 0x100) и вуаля.

EDIT:
Если вам известно имя bar.so, то вы можете связать foo.so с "заглушкой" bar.so. Неважно, что у вас нет «настоящего» * ​​1023 *; все, что имеет значение, это то, что foo.so зависит от него. Во время выполнения эта зависимость приведет к загрузке bar.so при загрузке foo.so.

...