6

gcc と GNU binutils を使用して、使用するとリンク時にエラーが生成されるように一部の関数をマークする方法はありますか? 私の状況では、既存のバイナリとの互換性のために削除していないライブラリ関数がいくつかありますが、新しくコンパイルされたバイナリが関数を使用しようとしないようにしたいと考えています。configure問題のあるコードがヘッダーを無視し、スクリプトを使用して関数の存在を検出し、それら自体をプロトタイピングするため、コンパイル時の gcc 属性を使用することはできません。私の目標は、悪いスクリプトのリンク時エラーを生成してconfigure、関数の存在を検出しないようにすることです。

編集:アイデア..アセンブリを使用し.typeてエントリーポイントに間違ったものを指定すると、ダイナミックリンカーと互換性がありますが、新しいプログラムをリンクしようとするとリンクエラーが発生しますか?

4

3 に答える 3

2

FreeBSD 9.xは、関数で必要なものに非常に近いことを行いttyslot()ます。この関数はutmpxでは無意味です。秘訣は、このシンボルのデフォルト以外のバージョンしかないことです。したがって、ldそれは見つかりませんが、古いバイナリが実行されると、rtldはバージョン管理された定義を見つけます。古いバイナリにバージョン管理されていない参照がある場合はどうなるかわかりませんが、定義が1つしかない場合はおそらく賢明です。

例えば、

__asm__(".symver hidden_badfunc, badfunc@MYLIB_1.0");

通常、次のようなデフォルトバージョンもあります

__asm__(".symver new_badfunc, badfunc@@MYLIB_1.1");

またはSolaris互換バージョンのスクリプトを使用しますが、トリックはスクリプトを追加しないことです。

通常、asmディレクティブはマクロにラップされます。

このトリックは、アセンブラーディレクティブを使用してシンボルバージョンを定義するGNU拡張機能に依存している.symverため、おそらくLinuxとFreeBSDでのみ機能します。Solaris互換バージョンのスクリプトは、シンボルごとに1つの定義しか表現できません。

詳細:Ulrich Drepperの「共有ライブラリの書き方」の.symverディレクティブ、 http://gitorious.org/freebsd/freebsd/commit/3f59ed0d571ac62355fc2bde3edbfe9a4e722845でttyslot ()を非推奨にしたコミットinfo gas

于 2011-01-15T00:43:30.173 に答える
0

人々に使用してほしくない非推奨の関数のリンク時エラーを生成する最良の方法は、非推奨の関数がライブラリに存在しないことを確認することです。

おそらく、非推奨の関数を含む補助ライブラリを提供できます。注意を払わない嫌悪者は補助ライブラリとリンクできますが、主流の人々は補助ライブラリを使用しないため、関数を使用しません。ただし、まだ「非推奨」段階を超えています。

リンク時の警告を取得するのは難しいです。明らかに、GCC はいくつかの関数 (mktemp()など) に対してそれを行います。Apple は、を使用するプログラムを実行すると GCC に警告を発しますgets()。彼らがそれを実現するために何をしているのか、私にはわかりません。


コメントに照らして、リンク時または実行時まで待つのではなく、コンパイル時に問題を解決する必要があると思います。

GCC 属性には以下が含まれます (GCC 4.4.1 マニュアルより):

error ("message")

この属性が関数宣言で使用され、そのような関数の呼び出しがデッド コードの削除やその他の最適化によって削除されない場合、メッセージを含むエラーが診断されます。これは、extern char [(condition) ? 1 : -1]; トリック。関数を未定義のままにしてリンク障害を引き起こすことは可能ですが、この属性を使用すると、インライン関数が存在する場合やデバッグ情報を出力しない場合でも、問題が早期に診断され、呼び出しの正確な場所が示されます。

warning ("message")

この属性が関数宣言で使用され、そのような関数の呼び出しがデッド コードの削除またはその他の最適化によって削除されない場合、メッセージを含む警告が診断されます。これは、特に __builtin_constant_p およびインライン関数と一緒に、コンパイル時のチェックに役立ちます。.gnu.warning* セクションでメッセージを使用して関数を定義することは可能ですが、この属性を使用すると、インライン関数が存在する場合やデバッグ情報を出力しない場合でも、問題が早期に診断され、呼び出しの正確な場所が示されます。

構成プログラムがエラーを無視する場合、それらは単に壊れています。これは、関数を使用して新しいコードをコンパイルできなかったことを意味しますが、既存のコードは、ライブラリ内の非推奨の関数を (再コンパイルが必要になるまで) 引き続き使用できます。

于 2011-01-14T19:37:08.927 に答える
0

1 つのアイデアは、これらのシンボルを持ち、予期しないプロパティを持つスタブ ライブラリを生成することです。

  • おそらく、関数の名前を持つオブジェクトを作成するため、構成フェーズのリンカーは、シンボルに互換性がないことを訴える可能性があります
  • dont_use_symbol_XXX決して解決されない依存関係 " " を持つ関数を作成します
  • または、関数を含むグローバルインデックスを持つ .a ファイルを偽造しますが、アーカイブ内の .o メンバーの形式が間違っています
于 2011-01-14T20:17:20.777 に答える