2012-03-28 11 views
9

GCCを使用して、共有オブジェクトを作成した後に共有オブジェクトからシンボルを削除するにはどうすればよいですか?私はのようなシンボルfoo()を操作Cに3つのファイルがある場合:次に共有オブジェクトからシンボルを削除するにはどうしたらいいですか?

// a.c 
int foo() { return 0xdead; } 
int baz() { return 1; } 

// b.c 
int foo() { return 0xbeef; } 
int bar() { return 0; } 

// c.c 
#include "stdio.h" 
extern int foo(); 
extern int bar(); 
extern int baz(); 
int main() { printf("0x%x, 0x%x, 0x%x\n",foo(),bar(),baz()); return 0; } 

私はコンパイルして実行のような:

% gcc a.c --shared -fPIC -o a.so 
% gcc b.c --shared -fPIC -o b.so 
% setenv LD_LIBRARY_PATH . # export LD_LIBRARY_PATH=. for bash systems 
% gcc c.c a.so b.so -o c 
% ./c 
0xdead, 0x0, 0x1 

方法私はそれをそうすることができますか私がa.soを作成した後に、a.soのシンボルはfoo()になりましたか? a.soの代わりにb.soに定義されているfoo()a.soから削除するといいでしょう。 foo()a.soから削除された後、cを再実行することのプリントアウトを生成する必要があります。このおもちゃの例では

0xbeef, 0x0, 0x1 

を、私はa.sob.soc.cをコンパイルするときの順序再libary名前を私は単にすることができます知っているが、どのようにすることができます私は実際にa.soからシンボルを削除しますか?

nm -a a.so | grep foo 

今のに対し、それが返されます:私はa.soからfoo()を削除した後、nm出力のこのgrepのは何も得られないだろうと想像

000000000000063c T foo 
+0

なぜGCCにあなたのc.cでa.soとb.soをコンパイルするように指示しますか?共有ライブラリはあなたのバイナリにリンクされているとは思われません。これは 'LD_LIBRARY_PATH'のためのものです。 – Eregrith

+1

おそらく 'objcopy'には必要な機能がいくつかありますか? –

+0

'strip'をもっと見たことがありますか? '-R'でファイル内の特定のシンボルをターゲットにできると信じています... – timlukins

答えて

11

あなたは-N--strip-symbol)を使用することができるはずです希望するものを達成するためのobjcopyのオプション:

+0

完璧!フレデリックに感謝します。 –

2

Symbolの可視性は、ランタイムリンクのために機能するライブラリを選択する上で優れたソリューションのようですが、ライブラリを構成する他の.cファイル(http://gcc.gnu.org/wiki/Visibility)からの使用を許可すると宣言された "extern"はライブラリにローカルです。

関連する問題