エクスポートされた共有ライブラリシンボルのフラットリストから、どのシンボルがどのライブラリによってエクスポートされたかを調べる必要がありました。リストには十分な数のシンボル(20程度)が含まれていたため、それぞれを手動で相互参照することはしませんでした。
nm -A -D -f sysv <library-name>
が有用な出力を生成しているように見えることがわかりました。2番目の列にも住所がリストされている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列)
最初は、作業中のDebian Squeeze chrootで元のスクリプトを実行しましたが、好奇心から、ホストシステムで上記を実行して、chrootが何らかの理由で正常でないかどうかを確認しました。
ええと... chrootは90を少し超える重複を報告しましたが、私のホスト(Arch)システムには明らかに約267があります。
このコマンドはnm
の出力をgrepすることで機能するため、結果は少しうるさいですが、次のようになります。
/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
各シンボルが2つあることに注意してください。 アドレスが異なります、はい、しかし...動的リンクはシンボル名で機能すると思いました。それだけでした。私の混乱は、(上記のリストを右にスクロールした場合)シンボルがすべてタイプFUNC
であり、.text
セクションからのものであるという事実によって悪化します。
私はこれを投稿して、ここで内部でどのような興味深い魔法が起こっているかを学びます。 (私のシステムが機能しているので...)
誰かが私が約600行のテキストをダンプできる良いアイデアを持っているなら-Pastebinはもう流行していないようで、私はGitHubを使用していません-私は完全な出力を共有したいと思います。
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を変更できます。