2011-01-14 17 views
6

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

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

答えて

0

非難された関数のリンク時エラーを生成する最善の方法は、非難された関数がライブラリに存在しないことを確認することです。

おそらく、非難された関数を付属ライブラリに提供することができます。注意を払わない被告人は、補助ライブラリとリンクすることができますが、主流の人々は補助ライブラリを使用しないので、その機能を使用しません。しかし、それはまだ "廃止された"段階を超えてそれを取っています。

リンク時の警告を取得するのは難しいです。明らかに、GCCはある機能(mktemp()など)に対してそれを行い、Appleはgets()を使用するプログラムを実行するとGCCに警告します。私は彼らが何をするのか分からない。


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

GCC属性が(GCC 4.4.1マニュアルから)が挙げられる:

error ("message") 

この属性は、関数宣言に使用され、そのような関数の呼び出しが デッドコードを介して除去されていない場合メッセージを含むエラー が診断されます。これはコンパイル時に チェック、特に__builtin_constant_pとインライン関数 と一緒にチェックすると便利です。インライン関数の引数をチェックするのはexternでは不可能です char [(condition)? 1:-1];トリック。関数 を未定義にしてリンク障害を引き起こす可能性がありますが、 インライン関数が存在する場合でも、デバッグ情報を出力していない場合でも、この属性を使用すると問題が発生することがあります。

warning ("message") 

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

設定プログラムがエラーを無視すると、それらは単に壊れてしまいます。つまり、関数を使用して新しいコードをコンパイルすることはできませんでしたが、既存のコードではライブラリ内の廃止された関数を引き続き使用できます(再コンパイルが必要になるまで)。

+0

で警告が '.gnu.warning'ノートで行うことができますが、私はエラーを生成するための同等物を知らない。残念ながら、あなたのソリューションは最高ですが、廃止予定のABIと新しいアプリケーションのリンクの両方にマッチするニーズはありません。 –

+0

@R ..:十分に公正です。インストールされているライブラリの1つのコピーがほしいと言ってもいいですか?あらかじめコンパイルされたアプリケーション(非推奨のインタフェースを使用している可能性があります)を実行し続けたい場合廃止予定のインターフェイスを使用する新しくコンパイルされたアプリケーションをリンクできないようにしたいですか?もしそうなら、コンフィギュレーションディテクタが廃止された機能を発見するならば、人々が物事を修正するようにして、コードが近代的な(廃止されていない)インタフェースと結びつくようにする方法はありますか? –

+0

新しい置換インターフェイスはありません。これらの廃止されたインタフェースを使用しようとするのは有害であり、正しい動作はそれらをまったく使用しないことです。残念ながら、私はそれらを使用しようとしている壊れたソフトウェアを制御することはできませんし、新しいバージョンを修復するためのメンテナを手に入れることができるかもしれませんが、ユーザーは古いバージョンをコンパイルしようとしているかもしれません。 –

0

これらのシンボルを持つが予想外のプロパティを持つスタブライブラリを生成することが考えられます。

  • おそらく機能の名前を持つオブジェクトを作成し、その構成フェーズにおけるリンカーは、シンボルが
  • を解決されることはありません「 dont_use_symbol_XXX」依存関係を持つ関数を作成して互換性がないと文句を言うかもしれません
  • またはアーカイブ内の.oメンバーが間違った形式を持っている.Aのあなたの機能を持つことになり、グローバル索引を持つファイルが、
2

のFreeBSD 9.xのはttyslot()であなたが望むものに非常に近い何かを偽機能。この関数はutmpxでは無意味です。このシンボルのデフォルト以外のバージョンのみが存在するということです。したがって、ldはそれを見つけられませんが、古いバイナリが実行されると、rtldはバージョン化された定義を見つけます。古いバイナリにバージョン管理されていない参照がある場合はどうなるのか分かりませんが、定義が1つしかない場合はおそらく分かりやすいでしょう。例えば

__asm__(".symver hidden_badfunc, [email protected]_1.0"); 

通常は、また

__asm__(".symver new_badfunc, [email protected]@MYLIB_1.1"); 

またはSolarisと互換性のあるバージョンのスクリプトによる

のように、デフォルトのバージョンが存在することになるが、トリックは1を追加することではありません。

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

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

詳細情報:info gas.symverディレクティブ、ウルリック・ドレパーの「共有ライブラリを作成する方法」、その非推奨ttyslotをコミット()http://gitorious.org/freebsd/freebsd/commit/3f59ed0d571ac62355fc2bde3edbfe9a4e722845

+0

これがどのように機能するか、またはリンクを提供する方が良いでしょうか?それは私のニーズを満たすかもしれないように聞こえる。 –

+0

@R ..編集でさらに情報を追加しました。 – jilles

関連する問題