Видимость символа ELF
Допустим, я определяю API (sym1) в файле spec_a.h. Реализация этого API в lib_imp1.so. У меня может быть приложение, которое добавляет эту общую библиотеку, dlsym() sym1, и вызывает ее. Возможно ли для приложения dlopen() какой-то другой разделяемой библиотеки с sym1 как неопределенной, и она преобразуется в sym1 в lib_imp1.so? Если так, как мы это делаем?
Если это возможно, то у нас может быть две реализации, lib_imp1.so и lib_imp2.so, причем обе имеют два разных адреса для одного и того же символа sym1. Если приложение загружает другую разделяемую библиотеку с неразрешенным sym1, можем ли мы иметь какой-либо контроль, к которому разрешается sym1 (lib_imp1.so или lib_imp2.so)?
При генерации lib_imp1.so, можем ли мы сказать, что, хотя мы хотим, чтобы sym1 экспортировался, мы не хотим, чтобы какой-либо неразрешенный символ был разрешен в него? (вид контролируемого экспорта??)
Спасибо
1 ответ
У меня может быть приложение, которое добавляет эту общую библиотеку, dlsym() sym1, и вызывает ее. Возможно ли для приложения dlopen() какой-либо другой разделяемой библиотеки с sym1 как неопределенной, и она преобразуется в sym1 в lib_imp1.so?
Да: если первый dlopen
использования RTLD_GLOBAL
тогда все символы экспортируются из lib_imp1.so
(в том числе sym1
) вводятся в глобальную область и становятся видимыми для других библиотек, загруженных позже.
Если это возможно, то мы можем иметь две реализации, lib_imp1.so и lib_imp2.so, причем обе имеют два разных адреса для одного и того же символа sym1.
Да. Это опрометчиво.
Если приложение загружает другую разделяемую библиотеку с неразрешенным sym1, можем ли мы иметь какой-либо контроль, к которому разрешается sym1 (lib_imp1.so или lib_imp2.so)?
Нет, при условии, что вы dlopen
Эд оба lib_imp1.so
а также lib_imp2.so
с RTLD_GLOBAL
любая последующая библиотека всегда будет привязана к sym1
от первой dlopen
библиотека, которая обеспечивает это (то есть, это разрешит к lib_imp1.so
определение).
Далее, если lib_imp1.so
также экспорт sym2
и что-нибудь в lib_imp2.so
звонки sym2
этот символ также разрешил бы определение внутри lib_imp1.so
(если вы не принимаете особый уход и не используете -Bsymbolic
).
Конечным результатом является то, что UNIX .so
библиотеки ведут себя так же, как архивные библиотеки, а не как окна DLL
s. Это делает невозможным использование двух отдельных реализаций, экспортирующих один и тот же интерфейс, в одном процессе.
При генерации lib_imp1.so, можем ли мы сказать, что, хотя мы хотим, чтобы sym1 экспортировался, мы не хотим, чтобы какой-либо неразрешенный символ был разрешен в него?
dlsym
использует точно такой же процесс разрешения. Если вы сделаете символ недоступным для чего-либо, чтобы разрешить его, dlsym
тоже не найду. И наоборот, экспорт символа означает в точности "сделать его доступным для разрешения" (либо dlopen
или просто обычное неразрешенное разрешение зависимостей).