Как я могу увидеть, какие модули существуют в файлах .so?
Я пытаюсь понять Linux и файлы. Это сложно.
Я пытаюсь выяснить, как мне найти, какие модули доступны в файле, например:
В моем файле конфигурации httpd я нашел следующую строку:LoadModule wsgi_module modules/mod_wsgi.so
Я предполагаюwsgi_module
это модуль «внутри»mod_wsgi.so
.
Вопрос: Как я могу перечислить или найти все модули*.so
файл?
2 ответа
В общем, все файлы (будь то библиотеки или модули) работают путем экспорта именованных символов , которые обычно представляют функции или иногда «внешние» переменные, которые программа импортирует по имени с помощью «динамического компоновщика». Для модулей это в основном то же самое, что и для библиотек.
В случае модулей Apache httpd «имя модуля»wsgi_module
буквально это просто имя символа, который экспортирует файл .so (скорее всего, указывающий на структурную переменную с указателями на все необходимые функции, чтобы Apache мог начать использовать ее в качестве модуля). Основная программа загрузит .so, используяdlopen()
и найдите указанный символ, используяdlsym()
.
(Для других программ, использующих модули .so, это может быть по-другому, поскольку каждая программа в основном использует свои собственные; например, многие программы ожидают, что все модули каждый раз будут предоставлять символ с одним и тем же именем.)
Чтобы узнать, какие имена экспортируются файлом .so, вы можете использовать команду binutils:
$ nm -D -Ux /usr/lib/httpd/modules/mod_rewrite.so
0000000000012020 D rewrite_module
Здесь-D
заставляет nm показывать «динамические» символы и сокращает список только до «определенных» символов (т. е. экспортированных — полный список также содержит символы, импортированные из других библиотек).
(По всему должно быть просто-U
, нет-Ux
, но, видимо, версия nm/binutils, которая у меня есть, по ошибке требует, чтобы параметр был задан для короткой опции, поэтому мне приходится использовать-Usomething
. Длинный вариант--defined-only
работает как ожидалось.)
Вы можете сравнить это с.so
файл, который представляет собой обычную библиотеку C, которая работает более или менее одинаково (символы обычно разрешаются во время компиляции, когдаgcc hello.c -lcrypt
готово, но его также можно загрузить с помощью dlsym):
$ nm -D -Ux /usr/lib/libcrypt.so
0000000000000000 A XCRYPT_2.0
0000000000000000 A XCRYPT_4.3
0000000000000000 A XCRYPT_4.4
0000000000010e30 T crypt@@XCRYPT_2.0
0000000000011090 T crypt_checksalt@@XCRYPT_4.3
000000000000f4d0 T crypt_gensalt@@XCRYPT_2.0
0000000000011000 T crypt_gensalt_ra@@XCRYPT_2.0
0000000000010e50 T crypt_gensalt_rn@@XCRYPT_2.0
0000000000011120 T crypt_preferred_method@@XCRYPT_4.4
0000000000010de0 T crypt_r@@XCRYPT_2.0
0000000000010d20 T crypt_ra@@XCRYPT_2.0
0000000000010c90 T crypt_rn@@XCRYPT_2.0
Альтернативыnm
, из комментария Дэвида:
Ваши предположения неверны: файл — это просто общая библиотека, созданная путем связывания одного или нескольких объектных файлов.
В частности, директива LoadModule имеет синтаксис:
LoadModule module filename
В описании директивы сказано:
Директива LoadModule связывает объектный файл или имя файла библиотеки и добавляет структуру модуля с именем модуль в список активных модулей. Модуль — это имя внешней переменной типа модуль в файле, которое указано как идентификатор модуля в документации модуля.
Это значит, чтоmodule
— это особое имя, используемое в Apache. Не все библиотеки являются модулями Apache, и уж точно не состоят из модулей Apache.
библиотеки создаются компоновщиком из объектных файлов. Иногда эти файлы еще называют «модулями». После связывания их нельзя снова распаковать в исходные объектные файлы, поскольку эта информация больше не доступна.
Все, что осталось в.so
Библиотека — это точки входа, предоставляемые исходными объектными файлами и именем объектного файла, которому они изначально принадлежали. Однако вы не сможете догадаться, не разбирая библиотеку, где в ней начинается или заканчивается код из каждого объектного файла.