4

背景: 実行可能ファイルに、共有オブジェクトで定義された外部データ参照がある場合、コンパイラはコピーの再配置を使用して、.bss セクションにコピーを配置します。コピーの再配置については、次のサイトで詳しく説明しています: http://www.shrubbery.net/solaris9ab/SUNWdev/LLM/p22.html#CHAPTER4-84604

ただし、私の質問は次のとおりです。

共有オブジェクトの外部データ参照と同じように、GOT を介して実装することは可能ですか? 実行可能ファイルは、GOT エントリを介してこの外部コードに間接的にアクセスできます。この GOT エントリには、実行時にこのシンボルの実際のアドレスを詰め込むことができます。GCC がこのように実装しない理由がわかりません。コピーの再配置の利点は何ですか?

4

2 に答える 2

3

共有オブジェクトの外部データ参照と同じように、GOT を介して実装することは可能ですか?

はい。これを機能させるには、メインの実行可能ファイルにリンクされたコードをビルドする必要があります-fPIC。これはしばしば効率が悪く (余分な間接化)、通常は実行されないため、リンカーは代わりにコピーの再配置を行う必要があります。

詳細はこちら

于 2014-11-11T15:44:35.510 に答える
3

C や C++ などの言語では、静的ストレージ期間を持つオブジェクトのアドレスは、アドレス定数として修飾されます。概念的には、言語レベルでは、コンパイル時に値が「既知」であるかのように扱われることを意味します。

もちろん、問題になると、これは実際には当てはまりません。コンパイラ-リンカー-ローダーの組み合わせがアドレス定数の言語レベルの概念を完全にサポートする動的メカニズムを実装する必要があることに対抗するために。直観的には、完全なランタイム インダイレクションに基づく GOT ベースのメカニズムは、ロード時の再配置ベースのメカニズムよりも、その概念からはるかに離れています。

1 つには、C 言語は、静的記憶域期間を持つオブジェクトの動的初期化を必要としない言語として設計されました。つまり、概念的には、スタートアップ コードの初期化がなく、初期化の順序に関連する問題もありません。しかし、GOT ベースの実装では、このようなアドレス定数を使用してグローバル変数を初期化するには、起動コードで GOT から実際の値を抽出して変数に配置する必要があります。一方、再配置ベースのアプローチでは、そのようなグローバル変数が起動コードなしで適切な値でその寿命を始めるという完全な錯覚を生み出します。

再配置メカニズムによって提供される機能を見ると、アドレス定数の C 仕様と同期していることがわかります。たとえば、最終的な値には固定オフセットの追加が含まれる場合があります。これは、C アドレス定数式で許容される、C[]および演算子のローダー側の実装として機能することを目的としています。->

于 2014-11-11T16:05:43.863 に答える