2

グローバルシンボルテーブルへのシンボルのエクスポートを制限する方法を誰か提案してもらえますか?

前もって感謝します


やあ、

返信ありがとうございます...

実際には、「ver1.a」というサードパーティのライブラリに静的にリンクされている実行可能ファイルがあり、同じライブラリにリンクされているサードパーティの「.so」ファイルも使用していますが、バージョンは「ver2.a」と呼ばれています。問題は、これらの両方のバージョンの実装が異なることです。最初に、実行可能ファイルが読み込まれると、「ver1.a」のシンボルがグローバル シンボル テーブルにエクスポートされます。「.so」がロードされるたびに、ver2.a からのシンボルを参照しようとし、以前にロードされた「ver1.a」からのシンボルを参照することになります。したがって、バイナリがクラッシュします。

実行可能ファイルのシンボルをグローバル シンボル テーブルにエクスポートしないという解決策を考えました。そのため、「.so」がロードされて ver2.a のシンボルを使用しようとすると、グローバル シンボル テーブルで見つからず、そのシンボルを使用します。独自のシンボル、つまり ver2.a のシンボル

シンボルのグローバル シンボル テーブルへのエクスポートを制限する方法が見つかりません。--version-scriptとretain-symbol-fileで試してみましたが、うまくいきませんでした。-fvisibility=hidden オプションの場合、「 -f オプションは -shared でのみ使用できる」というエラーが表示されます。したがって、これも「--version-script」のように、実行可能バイナリではなく共有ライブラリに対してのみ機能すると思います。

コードは c++、OS-Linux、gcc バージョン 3.2 です。サードパーティのライブラリと「.so」を再コンパイルできない場合があります。したがって、「so」ファイルを bsymbolic フラグで再コンパイルするオプションは除外されます。

どんな助けでも大歓迎です。

4

3 に答える 3

2

dlopen でサードパーティのライブラリを取り込みます。

サードパーティのシンボルをすべて非表示にし、独自の API のみを公開する独自の共有ライブラリを作成することで、これを回避できる場合がありますが、他のすべてが失敗した場合は、dlopen を使用して完全に制御できます。

于 2009-11-26T16:33:41.990 に答える
0

最も簡単な解決策は、そもそも共有ライブラリと競合しないように、実行可能ファイル内のシンボルの名前を (ソース コードを変更して) 変更することです。

次の最も簡単な方法は、「問題」の記号を で局所化することです'objcopy -L problem_symbol'

最後に、サード パーティのライブラリに直接リンクせず (ただし、 bmargulies が示唆するように、代わりに dlopen します)、他の共有ライブラリで "問題" シンボルの定義を使用ておらず、-rdynamic を使用してリンクしていない場合またはそれに相当するものの1つである場合、シンボルは実行可能ファイルの動的シンボルテーブルにエクスポートされるべきではないため、競合が発生することはありません.

注:シンボルはグローバルに定義されたものとして表示され'nm a.out'ます、動的リンクでは問題ありません。withの動的シンボル テーブルを見たいとします。a.out'nm -D a.out'

于 2009-11-27T04:52:47.580 に答える