2011-08-27 12 views
25

は、私が最近受け取っ:共有オブジェクトを作るときなぜFPICは64にしていない32ビットプラットフォーム上で絶対に必要なのですか?

...ローカルシンボル」 `に対する移転R_X86_64_32を使用することはできません。 -fPICで再コンパイルします。

共有ライブラリとしてプログラムをコンパイルしようとしているときにエラーが発生しました。

今、これを解決するには、(-fPICを持つすべての依存関係を再コンパイル)それほど難しくありませんが、いくつかの研究の後に、この問題は、x86-64のプラットフォーム上でのみ存在することが判明しました。 32ビットでは、位置依存コードは動的ローダによって再配置されます。

私は見つけることができる最高のanswerは次のとおりです。

のx86は、.textの再配置のためのサポート(あなたは 位置dependendコードを持っているときに何が起こるかである)があります。このサポートは、このような再配置を含むすべての ページがそれ が、それによって共有 LIBSの概念そのものを損なう、共有ライブラリに座っていても、基本的には非共有になっつまりこと、コストがかかります。

しかし、私はこの非常に十分なを見つけることができません。そこで私たちはAMD64でこれを禁止することを決定した(値が32ビット以上を必要とする場合、すべての.text再配置情報のみ サイズ「word32」を持っているので、それに加えて、 問題を作成します) 。再配置によって共有ライブラリの概念が損なわれる場合は、なぜ32ビットプラットフォームで実行できるのでしょうか? 64ビットをサポートするために、ELF形式に行うことが必要な変更があった場合は、すべてのフィールドのサイズは増加しなかった理由も、その後に対応するには?

これはマイナーポイントかもしれませんが、問題のコードは科学的なコードであり、パフォーマンスヒットをするのがうれしくありません。b)この情報は不可能でした最初に見つけてください!

[編集: '回答'

@awoodlands answeraddedいくつかの良い情報@servn、おそらく最高の 'リテラルの答え' です。私はthis、最終的にx86_64 ABI referenceを発見した再配置のさまざまなタイプについての詳細を見つけるための検索で

(68ページを参照してください) ]

+1

私はあなたの質問への答えを知らないが、あなたはそれを認識する必要があり ' x86-64(x86-32と比較して)では、より多くのレジスタ、PC相対アドレッシング、およびPICを考慮して設計されたABIを備えているため、-fPICのパフォーマンスが低下します。私はそれが*行ったと言うつもりはないが、それを測定すると、あなたはうれしく驚くかもしれない。 – zwol

+0

それはコンセンサス、確かに大きな利便性のためにパフォーマンスの小さなペナルティと思われる。私はそれを自分で試してみる必要があります。 –

+0

主な質問はもちろん、なぜコンパイラに「必須オプション」があるのか​​です。 「あなたは魔法の言葉を言っていませんでした」とは、むしろ幼稚なゲームです。 – MSalters

答えて

10

私はそれを理解したような問題は、より速く、新しいを導入するx86-64のようです命令ポインタに関連するデータを参照する方法。これはx86-32では存在しませんでした。

This articleはそれの素敵な詳細な分析を持っており、以下のエグゼクティブ・サマリーを提供します:

データアドレスへ がいいの最適化で相殺相対命令ポインタを使用するx86-64での能力は、しかし、共有ライブラリ内のデータの相対的な位置に関する 状況の仮定は 無効であり、使用することはできません。この場合、グローバルデータへのアクセス(あなたに周りに変更される場合がありますすなわち もの)は抽象化層 、すなわちグローバルオフセットテーブルを通過する必要があります。

e.e.e. -fPICアドレッシングはアドレッシングに抽象レイヤーを追加して、従来のアドレッシングスタイルでこれまで可能であった(そして望ましいフィーチャー)ものが新しいアーキテクチャでも機能するようにします。

+0

これは素晴らしい記事です、ありがとう! –

7

しかし、これはかなり適切ではありません。再配置によって共有ライブラリの概念が損なわれる場合は、なぜ32ビットプラットフォームで実行できるのでしょうか?

再配置の計算にはランタイムコストがあり、再配置された実行可能ファイルには追加のメモリが必要であり、そのメカニズムによって実行可能なローダーに多くの複雑さがもたらされます。また、Linuxディストリビューションは、実行可能ファイルのベースアドレスを変更することがセキュリティ脆弱性の悪用を難しくする緩和戦略であるため、実際にすべてのコードを-fPICでコンパイルすることを推奨したいと考えています。

特に、-fvisibility = hiddenまたは同等のものを使用する場合、-fPICは一般的に大きなパフォーマンスコストではありません。

なぜ、すべてのフィールドのサイズが拡大されたわけではありませんか?

問題の「フィールド」は、ELF開発者の管理下にないx86-64アドレッシングモードの直接のフィールドです。

+0

あなたの答えをありがとう、それは本当に@awoodlandによって提供されるリンクに多くを追加します - 特にそれが完了することができますが、ある時点では愚かになるという認識。 明確にする:fvisibility = hiddenは、明示的にエクスポートされない関数はすべてPLTから呼び出されないため、間接参照のレベルが削除されることを意味しますか? –

+0

はい、fvisibility = hiddenはPLT間接を削除します。 – servn

関連する問題