、ジャンプは直接になります。
今隠されたとしてtest1()
は、そのソースの翻訳単位で定義されていないかもしれないが、私は害はC言語を除いてその相違から来るべきではないと考えていますポインターの1つが非表示の参照で取得されたものとパブリック1つで取得されたものがある場合は、&test1 == &test1
が壊れている可能性があります(パブリックリファレンスは、プリロードまたは現在のルックアップスコープ、非表示の参照(直接ジャンプをもたらす)は効果的な介入を防止します)
これに対処するより適切な方法は、test1()
という2つの名前を定義することです。パブリック名とプライベート/非表示の名前です。
gccとclangでは、これはいくつかのエイリアスマジックで行うことができます。これは、シンボルを定義する翻訳単位でのみ行うことができます。
#define PRIVATE __attribute__((__visibility__("hidden")))
#define PUBLIC __attribute__((__visibility__("default")))
#define PRIVATE_ALIAS(Alias,OfWhat) \
extern __typeof(OfWhat) Alias __attribute((__alias__(#OfWhat), \
__visibility__("hidden")))
#if HERE
PUBLIC void test1(void) { }
PRIVATE_ALIAS(test1__,test1);
#else
PUBLIC void test1(void);
PRIVATE void test1__(void);
#endif
void call_test1(void) { test1(); }
void call_test1__(void) { test1__(); }
void call_ext0(void) { void ext0(void); ext0(); }
void call_ext1(void) { PRIVATE void ext1(void); ext1(); }
上記コンパイル(-O3、x86-64で):
マクロが、それはきれいにすることができ、それは小さいですので、ここで= 1を定義
call_test1:
jmp [email protected]
call_test1__:
jmp test1__
call_ext0:
jmp [email protected]
call_ext1:
jmp ext1
は(さらにTEST1呼び出しをインラインローカルおよび-O3はオン)。
ライブサンプルhttps://godbolt.org/g/eZvmp7です。
-fno-semantic-interposition
でも、それはC言語の保証を壊してしまいます。エイリアシングの細かさがない大きなハンマーです。
ライブラリ/実行ファイル内の呼び出しを意味しますか?それはどういうわけか、プライベートエイリアスなどを定義することによって可能になるはずです。しかし、あなたが動的にしかリンクしていないライブラリの関数を呼び出す場合、実行時リンカー*がそのような参照を解決できるかどうかはわかりません。 –
@PeterCordes '-fpic'を指定しないと、リンカは必要に応じてシンボルへの参照を自動的にPLT参照へ書き換えます。つまり、コンパイラがすべての関数に対して通常の呼び出しを生成し、リンカーが別の共有オブジェクトに行く呼び出しを書き直したいという動作です。 – fuz
['-fno-semantic-interposition'](http://stackoverflow.com/questions/35745543/new-option-in-gcc-5-3-fno-semantic-interposition)は何をしたいのですか? http://stackoverflow.com/questions/34102989/shared-object-in-linux-without-symbol-interposition-fno-semantic-interpositionも参照してください。この質問はそれらのいずれかと重複していますか? –