[devel] rpmelfsym [2]

Alexey Tourbin =?iso-8859-1?q?at_=CE=C1_altlinux=2Eru?=
Вс Сен 18 00:45:20 MSD 2005


On Tue, Sep 13, 2005 at 07:49:49PM +0400, Alexey Tourbin wrote:
> $ find /bin /usr/bin /lib /usr/lib -type f -maxdepth 1 |file -f - |awk -F': +' '$2~/ELF.*(dynamic|shared)/{print$1}' |xargs nm -D |awk 'NF>1{print NF-1,$(NF-1)}' |sort |uniq -c |sort -n
>      25 2 a
>      54 1 v
>    5864 1 w
>    6488 2 R
>    9310 2 A
>   24821 2 D
>   27751 2 B
>   38616 2 V
>   65737 2 W
>  236795 1 U
>  359673 2 T
> $

> Зато "буквы" не "пересекаются" по наличию или отсутствию адреса.
> То есть отдельное поле в дампе для "есть адрес/нет адреса" не нужно.
> Наверное, это банальная истина, но вот я её с понтом проверил.

Итого, получен (почти) полный дамп всех ELF-символов сизифа, в следующем
виде:

$ pwd
/home/at/.qa-robot/rpmelfsym
$ du -hs dump.old
350M    dump.old
$ head dump.old
7colors /usr/bin/sevencolors    A       _DYNAMIC
7colors /usr/bin/sevencolors    A       _GLOBAL_OFFSET_TABLE_
7colors /usr/bin/sevencolors    A       __bss_start
7colors /usr/bin/sevencolors    A       _edata
7colors /usr/bin/sevencolors    A       _end
7colors /usr/bin/sevencolors    B       game
7colors /usr/bin/sevencolors    D       __data_start
7colors /usr/bin/sevencolors    D       options
7colors /usr/bin/sevencolors    D       rhomb_xpm_data
7colors /usr/bin/sevencolors    R       _IO_stdin_used
$

Как видно из списка выше, буковки [AaBDRTVW] имеют адрес, то есть в
принципе эти символы кем-то могут провайдиться.  Буковки [Uvw] не имеют
адреса, то есть эти символы "оживают" в процессе динамической линковки.

Теперь следите за моей логикой.  Буковки, которые имеют адрес,
складываем в кучку provides.  Остальные буковки по смыслу ложатся в
кучку requires.  Далее нужно сравнивнить эти две кучки: символы, которые
есть в кучке requires, но которые отсутствуют в кучке provides, ЗАВЕДОМО
не могут правильно резольвиться динамическим линкером.

Это правило -- СЛАБОЕ правило в том смысле, что позволяет обнаружить
только ЯВНЫЕ, ЗАВЕДОМО недопустимые, ошибочные символы в ELF'ах.  Оно
не учитывает связи между ELF'ами, попросту допуская, что при совпадении
символов в requires и provides нужная связь между ELF'ами имеется.

Для requires и provides буду использовать обозначения "ref" и "def"
соответственно (как в lorder из v7).

$ awk -F'\t' '$3~/[AaBDRTVW]/' dump.old >def
$ awk -F'\t' '$3~/[Uvw]/' dump.old >ref

Проверяем, не осталось ли за бортом других буковок.

$ wc -l dump.old def ref
  4897331 dump.old
  2793772 def
  2103559 ref
  9794662 total
$ echo $(( 2793772 + 2103559 ))
4897331
$

Не осталось.  Теперь нужно отыскать символы в кучке "ref", которые не
"спариваются" с символами в кучке "def".  Это умеет делать join.  Для
этого нужно предварительно отсортировать def и ref по ключевому полю,
т.е. по символам (последнее поле, #4).

$ sort -t$'\t' -k4,4 -o def def & sort -t$'\t' -k4,4 -o ref ref &
[1] 15993
[2] 15994
$ man join

(sort тормознуто сортирует, читаю man join)

[2]  + done       sort -t$'\t' -k4,4 -o ref ref
[1]  + done       sort -t$'\t' -k4,4 -o def def
$ join -t$'\t' -j 4 -v 1 ref def -o '1.1 1.2 1.3 1.4' >join.out
$ wc -l join.out
18243 join.out
$

Есть такие символы!

$ head -20 join.out
tomboy	/usr/lib/tomboy/libtomboy.so	U	GTK_IS_SOURCE_VIEW
directfb	/usr/lib/directfb-0.9.21/gfxdrivers/libdirectfb_nsc.so	U	Gal_set_source_transparency
libcdf	/usr/lib/libcdf_idl.so.0.0.0	U	IDL_MakeTempArray
libcdf	/usr/lib/libcdf_idl.so.0.0.0	U	IDL_StoreScalar
libcdf	/usr/lib/libcdf_idl.so.0.0.0	U	IDL_StrDelete
libcdf	/usr/lib/libcdf_idl.so.0.0.0	U	IDL_StrStore
libcdf	/usr/lib/libcdf_idl.so.0.0.0	U	IDL_VarCopy
libgcj3.4	/usr/lib/lib-gnu-java-awt-peer-gtk.so.5.0.0	U	LINK_ReallyLinkClass
libgcj3.4-debug	/usr/lib/debug/lib-gnu-java-awt-peer-gtk.so.5.0.0	U	LINK_ReallyLinkClass
libgcj3.4	/usr/lib/lib-gnu-java-awt-peer-gtk.so.5.0.0	U	LINK_ReallyLinkKnownClass
libgcj3.4-debug	/usr/lib/debug/lib-gnu-java-awt-peer-gtk.so.5.0.0	U	LINK_ReallyLinkKnownClass
mod_ssl-sxnet	/usr/lib/apache/mod_sxnet.so	U	Malloc
mnogosearch-ruby	/usr/lib/ruby/vendor_ruby/1.8/i586-linux-gnu/mnogo.so	U	UdmEnvErrCode
abiword	/usr/lib/AbiWord-2.4/plugins/libAbiGimp.so	U	_Z10progExistsPKc
python-module-PyKDE	/usr/lib/python2.4/site-packages/kdeprint.so	U	_Z11rangeToSizeRK7QString
TORCS	/usr/lib/torcs/modules/graphic/ssggraph.so	U	_Z14ssgCullAndDrawP7ssgRoot
TORCS	/usr/lib/torcs/texmapper-bin	U	_Z14ssgCullAndDrawP7ssgRoot
boost-test	/usr/lib/libboost_unit_test_framework-gcc-1_32.so.1.32.0	U	_Z20init_unit_test_suiteiPPc
boost-test	/usr/lib/libboost_unit_test_framework-gcc-mt-1_32.so.1.32.0	U	_Z20init_unit_test_suiteiPPc
boost-test-devel	/usr/lib/libboost_unit_test_framework-gcc-d-1_32.so.1.32.0	U	_Z20init_unit_test_suiteiPPc
$

Похоже на правду.  По поводу GTK_IS_SOURCE_VIEW всё ясно -- это
нераскрытый макрос (в смысле препроцессора cpp).  По поводу
Gal_set_source_transparency -- проверяем:

$ grep -wi Gal_set_source_transparency dump.old
directfb        /usr/lib/directfb-0.9.21/gfxdrivers/libdirectfb_nsc.so	U       Gal_set_source_transparency
$

Нет такого символа в дампе.  Кто предоставляет символы Gal_*?

$ awk -F'\t' '$3=="T"&&$4~/^Gal_/' dump.old
directfb        /usr/lib/directfb-0.9.21/gfxdrivers/libdirectfb_nsc.so	T       Gal_bresenham_line
directfb        /usr/lib/directfb-0.9.21/gfxdrivers/libdirectfb_nsc.so	T       Gal_cleanup_interface
...
$

Ага, сам же directfb их и предоставляет.  Что-то в нём не стыкуется.

$ awk -F'\t' '$4~/^Gal_.*transp/' dump.old
directfb        /usr/lib/directfb-0.9.21/gfxdrivers/libdirectfb_nsc.so	U       Gal_set_source_transparency
$

Странно.  Ладно, едем дальше.  libcdf_idl, символы IDL_*.

$ awk -F'\t' '$3=="T"&&$4~/^IDL_/' dump.old
ORBit-devel     /usr/bin/orbit-idl      T	IDL_tree_traverse_parents
ORBit2-devel    /usr/bin/orbit-idl-2    T	IDL_tree_traverse_parents
ORBit2-devel    /usr/bin/orbit-idl-2    T	IDL_tree_traverse_parents_full
libIDL  /usr/lib/libIDL-2.so.0.0.0      T       IDL_attr_dcl_new
libIDL  /usr/lib/libIDL-2.so.0.0.0      T       IDL_binop_new
...
libORBit        /usr/lib/libIDL-0.6.so.0.4.4    T       IDL_attr_dcl_new
libORBit        /usr/lib/libIDL-0.6.so.0.4.4    T       IDL_binop_new
libORBit        /usr/lib/libIDL-0.6.so.0.4.4    T       IDL_boolean_new
libORBit        /usr/lib/libIDL-0.6.so.0.4.4    T	IDL_case_stmt_new
...
$

Ясно, это всякие ORBit'ы и IDL'и, но таких символов в них нету.  Странно.
Попробуем на всякий случай `ldd -r'.

$ ldd -r /usr/lib/libcdf_idl.so.0.0.0
        libc.so.6 => /lib/i686/libc.so.6 (0x4005d000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x80000000)
undefined symbol: IDL_StoreScalar       (/usr/lib/libcdf_idl.so.0.0.0)
undefined symbol: IDL_VarCopy   (/usr/lib/libcdf_idl.so.0.0.0)
undefined symbol: IDL_StrStore  (/usr/lib/libcdf_idl.so.0.0.0)
undefined symbol: IDL_StrDelete (/usr/lib/libcdf_idl.so.0.0.0)
undefined symbol: IDL_MakeTempArray     (/usr/lib/libcdf_idl.so.0.0.0)
$

Круто!  Эта библиотека по части IDL_ ни с кем не слинкована, а вывод
`ldd -r' подтвержает то, что мы только что увидели в join.out.

По поводу libgcj3.4 я судить не берусь.
Дальше идет mod_ssl-sxnet Malloc.

$ grep -w Malloc dump.old
mod_ssl-sxnet   /usr/lib/apache/mod_sxnet.so    U       Malloc
$

Нет такого символа нигде!  Далее идёт boost -- опять же не берусь
судить.  Потом всякое приплюснутое.  И так далее.

...

Что делать будем?

PS: там дальше много всяких __gmon_start__ символов идёт, так что всё
не слишком плохо.
----------- следующая часть -----------
Было удалено вложение не в текстовом формате...
Имя     : =?iso-8859-1?q?=CF=D4=D3=D5=D4=D3=D4=D7=D5=C5=D4?=
Тип     : application/pgp-signature
Размер  : 189 байтов
Описание: =?iso-8859-1?q?=CF=D4=D3=D5=D4=D3=D4=D7=D5=C5=D4?=
Url     : <http://lists.altlinux.org/pipermail/devel/attachments/20050918/84f6faf1/attachment-0001.bin>


Подробная информация о списке рассылки Devel