web-dev-qa-db-ja.com

オブジェクトファイルが-fPICを使用してビルドされているかどうか、objdumpなどを使用してどのように確認できますか?

objdumpのようなものを使用して、オブジェクトファイルが-fPIC

52
Crazy Chenz

答えはプラットフォームによって異なります。ほとんどのプラットフォームでは、

readelf --relocs foo.o | egrep '(GOT|PLT|JU?MP_SLOT)'

が空の場合、foo.o-fPICでコンパイルされていないか、foo.o-fPICが重要なコードが含まれていません。

60

PowerPCターゲットでこれを実行するだけで、-fPICなしでビルドされている共有オブジェクト(.so)を見つけることができました。私がしたことはreadelf -d libMyLib1.soを実行してTEXTRELを探しました。 TEXTRELが表示される場合は、.soを構成する1つ以上のソースファイルが-fPICでビルドされていません。必要に応じて、readelfelfdumpに置き換えることができます。

例えば。、

[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

この情報がすべてのアーキテクチャに適用されるかどうかはわかりません。

出典: blogs.Oracle.com/rie

12
indiv

私が本当に知りたいのは、共有ライブラリが-fPICでコンパイルされたオブジェクトファイルから構成されるかどうかです。

すでに述べたように、TEXTRELがある場合、-fPICは使用されませんでした。

.textの再配置を引き起こしたシンボルを表示できるscanelfと呼ばれる優れたツールがあります。

詳細は HOWTO Locate and Fix .text Relocations TEXTRELs にあります。

2
Vanuan
 readelf -a * .so | grepフラグ
フラグ:0x50001007、noreorder、pic、cpic、o32、mips32 

ほとんどの場合、これでうまくいくはずです。

2
Ternvein

-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}
2
CodeWizard

プログラムが-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の事前要求があるため、私はほとんど使用されていません。

0
zhaorufei