
私はLinuxプラットフォーム(redhat)で大規模なC ++プロジェクト、特にここで使用されている共有ライブラリを分析しています。特定の共有ライブラリで、このプロジェクトで使用されているシンボル(関数/変数)をどのように見つけることができますか?
まず、バイナリで次のコマンドを実行します。
readelf -d binaryName | grep -i "Shared library"
私のプロジェクトで使用されている共有ライブラリのリストを入手しました。 (これらの共有ライブラリにも独自の依存関係があるため、lddはより長いリストを表示します。)
0x0000000000000001 (NEEDED) Shared library: [librt.so.1]
0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
0x0000000000000001 (NEEDED) Shared library: [libuv.so.1]
0x0000000000000001 (NEEDED) Shared library: [libssl.so.1.1]
0x0000000000000001 (NEEDED) Shared library: [libcrypto.so.1.1]
0x0000000000000001 (NEEDED) Shared library: [libz.so.1]
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
libuv.so.1
これで、プロジェクトのコードベースで使用されているシンボルを見つける方法があります。誰でもロードマップを提案できますか?
答え1
nm -uD /path/to/your/binary
バイナリの未定義のすべての動的シンボルがリストされます。その後、出力と一致させる必要があります。
nm -gD /path/to/a/library
リストされた各ライブラリーに対して、コマンドはreadelf
各シンボルを提供するライブラリーを決定します。
これが必ずしも完全な写真を提供するわけではありません。特に、を通じてアクセスされるライブラリとシンボルはlibdl
考慮されません。やる意思があれば走るこれはバイナリであり、GNU Cライブラリの動的ローダ(ld.so
またはLinuxでは)を使用しているため、ld-linux.so
環境でsetを使用してバイナリを実行してすべてのシンボルバインディングを詳細に表示できます。詳細よりLD_DEBUG=bindings
。man ld.so
答え2
許可された回答に記載されている情報を使用してください。そしてここ、現在バイナリ(共有ライブラリから取得)で使用されているすべてのシンボルを見つけるために、次のスクリプトを作成しました。スクリプトは、バイナリ名(またはバイナリがスクリプトとは異なるディレクトリにある場合はパス)である1つのパラメータを使用します。
このスクリプトは、入力に提供されたバイナリに必要な共有ライブラリを表示します。すべてのシンボルは出力ファイル(result.txt)にダンプされます。
#!/bin/bash
if [ "$#" -ne 1 ]
then
echo "1 argument needed in the script"
echo "e.g. $0 [binary name(complete path)]"
exit
fi
if [ -f $1 ]
then
echo "Going to find the unresolved symbols found in \"$1\""
else
echo "Binary file \"$1\" not found. Check name/path."
fi
binaryFile=$1
lddOutput=(`ldd $binaryFile | awk '{print $3}' | grep -v "0x" | awk 'NF >0'`)
#echo "$lddOutput"
sharedDependencies=()
echo "Given below are the shared libraries used in $1"
for lib in "${lddOutput[@]}"
do
sharedDependencies+=($lib)
ls -lrta $lib
done
rm -f allSymbols.temp
rm -f result.txt
# Iterate the loop to read and print each array element
#echo -e "\nGiven below are the dependencies found for $binaryFile\n"
#echo "SharedDependencies: ${sharedDependencies}"
for lib in "${sharedDependencies[@]}"
do
#echo "Will search below lib in sharedDependencies"
#echo $lib
#Create list of all text symbols from all the libraries
#for symbol in `nm -gD $lib | awk '{$1=""}1' | grep " T \| W \| V \| w \| v \| t " | awk '{print $2}'`;
#for symbol in `nm -gD $lib | grep -i " T \| W \| V "`;
nm -gD $lib | grep -i " T \| W \| V \| I " | while read symbol;
do
string=
sym=
#echo -e "\nsymbol->$symbol" >> debug.txt
n=`echo $symbol | awk "{print NF}"`
#echo -e "n->$n\n" >> debug.txt
if [ $n -eq 2 ]
then
sym=`echo $symbol | awk '{print $2}'`
else
sym=`echo $symbol | awk '{print $3}'`
fi
string="$lib contains $sym"
echo $string >> allSymbols.temp
#echo $string >> debug.txt
done
done
undefinedDynamicSymbols=`nm -uD $binaryFile | awk '{print $2}'`
#echo -e "\n\nUndefinedDynamicSymbols\n$undefinedDynamicSymbols\n"
for undefinedSymbol in $undefinedDynamicSymbols;
do
echo $undefinedSymbol >> result.txt
grep -w $undefinedSymbol allSymbols.temp >> result.txt
echo -e "\n" >> result.txt
done
echo "symbols dumped in result.txt"
rm -f allSymbols.temp