Мне как раз нужно было выяснить, какие символы экспортировались какой библиотекой из простого списка экспортированных символов общей библиотеки. В списке было достаточно символов (около 20), так что я не собирался вручную делать перекрестные ссылки на каждый из них.
Я обнаружил, что это, nm -A -D -f sysv <library-name>
похоже, дает полезный вывод — я мог искать строки, содержащие FUNC
также указанный адрес во втором столбце. Поэтому я запустил эту команду для всего в /usr/lib
, перенаправив его в файл.
К моему удивлению, проверка работоспособности скрипта, который я сделал для разбора файла, показала, что там были дублирующиеся символы! После расследования было обнаружено, чтобиблиотеки, похоже, экспортируют дублирующиеся символы?!?
Я проверил это с помощью скриптов оболочки и смог превратить использованные мной команды в это (технически) один лайнер:
readlink -f /lib/* /usr/lib/* \
| grep -F .so. | sort | uniq \
| while read x; do nm -A -D -f sysv $x; done \
| grep FUNC | cut -d'|' -f1 | sort -g | uniq -c | sort -g \
| sed -n '/^ \+1/!{s/^ \+[0-9]\+ \+//p}' | sed 's/ //g' \
| tr '\n' '\v' \
| sed ':1;s/\([^ ]\+\):\([^\v$]\+\)\v\1:/\1:\2|/g;t1' \
| tr '\v' '\n' \
| while IFS=: read -a x; do \
nm -A -D -f sysv "${x[0]}" | grep ":\\(${x[1]//|/\\|}\\).*FUNC"; \
done
Команда выше заставит ваш диск искать в течение короткого периода времени. Вы можете разбить его на куски, которые перенаправят во временные файлы, если хотите. Такжевыход будет очень широким(~150 столбцов).
Первоначально я запустил оригинальный скрипт в chroot-окружении Debian Squeeze, в котором я работал, но из любопытства я запустил указанный выше сценарий на своей хост-системе, чтобы выяснить, не является ли chroot-окружение каким-либо ненормальным.
Ну... chroot сообщил о чуть более чем 90 дубликатах, но в моей хостовой системе (Arch) их, по-видимому, около 267.
Команда работает путем поиска nm
выходных данных, поэтому результаты немного зашумлены, но выглядят они примерно так:
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_access|00043700| T | FUNC|00000037| |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_access|000436c0| T | FUNC|0000003c| |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_access_mask|000458f0| T | FUNC|00000058| |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_buffer_size|000432a0| T | FUNC|00000037| |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_buffer_size|00043260| T | FUNC|0000003c| |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_buffer_size_max|00044ff0| T | FUNC|0000003c| |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_buffer_size_max|00045030| T | FUNC|00000037| |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_buffer_size_min|000453c0| T | FUNC|00000037| |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_buffer_size_min|00045380| T | FUNC|0000003c| |.text
Обратите внимание, что каждый символ представлен в двух экземплярах.Адрес другой., да, но... Я думал, что динамическое связывание работает по имени символа, и это было так. Мое замешательство усугубляется тем фактом, что (если вы прокрутите вправо в списке выше) все символы имеют тип FUNC
и из .text
раздела.
Я публикую это, чтобы узнать, какая интересная магия творится здесь под капотом. (Поскольку моя система работает...)
Если у кого-то есть хорошие идеи, куда можно сбросить около 600 строк текста (Pastebin, похоже, уже не в моде, а GitHub я не использую), я с радостью поделюсь полным выводом.
решение1
Символы кажутся дублированными, поскольку информация, предоставленная nm
неполная: рассматриваемые символы версионированы. Вы можете увидеть это с помощью objdump -T
:
0000000000059d00 g DF .text 0000000000000044 (ALSA_0.9) snd_pcm_hw_params_get_access
0000000000056040 g DF .text 000000000000004b ALSA_0.9.0rc4 snd_pcm_hw_params_get_access
или nm
вариант --with-symbol-versions
:
/usr/lib/x86_64-linux-gnu/libasound.so.2.0.0:snd_pcm_hw_params_get_access|0000000000059d00| T | FUNC|0000000000000044| |.text@ALSA_0.9
/usr/lib/x86_64-linux-gnu/libasound.so.2.0.0:snd_pcm_hw_params_get_access|0000000000056040| T | FUNC|000000000000004b| |.text@@ALSA_0.9.0rc4
Бинарные файлы связаны с определенной версией символа, и они получат нужную версию во время связывания. Это позволяет изменять API, сохраняя обратную совместимость.