私がやること
Linux 用の共有ライブラリを作成するときは、再配置、シンボルの可視性、GOT/PLT などに注意を払う傾向があります。
該当する場合は、同じライブラリの関数が相互に呼び出すときに PLT スタブを呼び出さないようにしています。たとえば、共有オブジェクトが 2 つのパブリック関数を提供するfoo()
とbar()
します。(どちらもユーザーが呼び出すことができます)。bar()
ただし、この関数は も呼び出しますfoo()
。したがって、この場合に私が行うことは次のとおりです。
- プライベートな可視性を持つ関数を定義
_foo()
します。_bar()
foo()
と のbar()
弱いエイリアスを_foo()
それぞれ定義し_bar()
ます。
そうすれば、共有オブジェクトのコードで弱いシンボルが使用されることはありません。ローカル関数のみを直接呼び出します。たとえば、_bar()
が呼び出されると、_foo()
直接呼び出します。
しかし、ユーザーは_*
関数を認識しておらず、対応する弱いエイリアスを常に使用しています。
やり方
Linux では、これは次の構成を使用して実現されます。
extern __typeof (_NAME) NAME __attribute__(weak, alias("_NAME"));
問題
残念ながら、これは OS X では機能しません。私は OS X やそのバイナリ形式について深い知識を持っていないので、少し調べてみると、弱い関数の例がいくつか見つかりました (このようなもの)。ウィーク シンボルを使用できるのと同じですが、DSO のローカル関数のエイリアスであるウィーク シンボルは使用できません。
可能な解決策...
今のところ、すべてのシンボルがグローバルでデフォルトの可視性を持つように、この機能 (マクロを使用して実装) を無効にしました。今のところ同じことを達成するために私が考えることができる唯一の方法は、すべての_foo
関数をプライベートな可視性で持ち、対応するfoo
関数をデフォルトの可視性で持ち、対応する「非表示」を呼び出すことです。
より良い方法は?
ただし、そのためにはかなりの量のコードを変更する必要があります。したがって、他に方法がない限り、そこには行かないほうがいいと思います。
では、OS X の代替手段、または同じセマンティクス/動作を取得する最も簡単な方法は何ですか?