objdump
のようなものを使用して、オブジェクトファイルが-fPIC
?
答えはプラットフォームによって異なります。ほとんどのプラットフォームでは、
readelf --relocs foo.o | egrep '(GOT|PLT|JU?MP_SLOT)'
が空の場合、foo.o
が-fPIC
でコンパイルされていないか、foo.o
に-fPIC
が重要なコードが含まれていません。
PowerPCターゲットでこれを実行するだけで、-fPICなしでビルドされている共有オブジェクト(.so)を見つけることができました。私がしたことはreadelf -d libMyLib1.soを実行してTEXTRELを探しました。 TEXTRELが表示される場合は、.soを構成する1つ以上のソースファイルが-fPICでビルドされていません。必要に応じて、readelfをelfdumpに置き換えることができます。
例えば。、
[user@Host lib]$ readelf -d libMyLib1.so | grep TEXT # Bad, not -fPIC
0x00000016 (TEXTREL)
[user@Host lib]$ readelf -d libMyLib2.so | grep TEXT # Good, -fPIC
[user@Host lib]$
ソリューションの検索を支援するために、実行可能ファイルを実行したときに発生したエラーは次のとおりです。
root@target:/# ./program: error while loading shared libraries: /usr/lib/libMyLi
b1.so: R_PPC_REL24 relocation at 0x0fc5987c for symbol 'memcpy' out of range
この情報がすべてのアーキテクチャに適用されるかどうかはわかりません。
私が本当に知りたいのは、共有ライブラリが-fPICでコンパイルされたオブジェクトファイルから構成されるかどうかです。
すでに述べたように、TEXTRELがある場合、-fPICは使用されませんでした。
.textの再配置を引き起こしたシンボルを表示できるscanelfと呼ばれる優れたツールがあります。
readelf -a * .so | grepフラグ フラグ:0x50001007、noreorder、pic、cpic、o32、mips32
ほとんどの場合、これでうまくいくはずです。
-fPICは、コードがコンパイルされたアドレスとは異なるアドレスで実行できることを意味します。
それを行うには、disasamblerは次のようになります。
call get_offset_from_compilation_address
get_offset_from_compilation_address: pop ax
sub ax, ax , &get_offset_from_compilation_address
これで、axにはオフセットがあり、メモリへのアクセスに追加する必要があります。
load bx, [ax + var_address}
プログラムが-fPICオプションで生成されているかどうかを区別する別のオプション:
コードのコンパイル時に-g3 -gdwarf-2オプションが有効になっている場合。
他のgccデバッグ形式にもマクロ情報が含まれている場合があります。
次の$ '..'構文はbashを想定していることに注意してください
echo $' main() { printf("%d\\n", \n#ifdef __PIC__\n__PIC__\n#else\n0\n#endif\n); }' | gcc -fPIC -g3
-gdwarf-2 -o test -x c -
readelf --debug-dump=macro ./test | grep __PIC__
このような方法が機能するのは、gccマニュアルで-fpicを使用すると[〜#〜] pic [〜#〜]が1に定義され、-fPICを使用すると[〜 #〜] pic [〜#〜]は2です。
GOTをチェックすることによる上記の答えは、より良い方法です。 -g3 -gdwarf-2の事前要求があるため、私はほとんど使用されていません。