Видимость символа 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 библиотеки ведут себя так же, как архивные библиотеки, а не как окна DLLs. Это делает невозможным использование двух отдельных реализаций, экспортирующих один и тот же интерфейс, в одном процессе.

При генерации lib_imp1.so, можем ли мы сказать, что, хотя мы хотим, чтобы sym1 экспортировался, мы не хотим, чтобы какой-либо неразрешенный символ был разрешен в него?

dlsym использует точно такой же процесс разрешения. Если вы сделаете символ недоступным для чего-либо, чтобы разрешить его, dlsym тоже не найду. И наоборот, экспорт символа означает в точности "сделать его доступным для разрешения" (либо dlopen или просто обычное неразрешенное разрешение зависимостей).

Другие вопросы по тегам