9

空でないコンストラクターを持つグローバル インスタンスの簡単な宣言がいくつかあります。これらのコンストラクターは、起動時に自動的に呼び出されます。Linux 上の C++ をさまざまなマイクロコントローラー ターゲットにクロスコンパイルしています。


はどうかと言うと

  • アーム-なし-eabi-gcc-4.8.4
  • rx-elf-gcc-4.8-GNURX_v14.03 (GCC 4.8.3)

コンストラクターへの呼び出しはセクションに入れられ.init_arrayます。マップ ファイルは次のようになります。

.init_array 0x00007cb8 0x4 libmotor.o

.init_array 0x00007cbc 0x4 libaudio.o


はどうかと言うと

  • mips-elf-gcc-4.8.2
  • avr-gcc-4.8.1
  • msp430-gcc-4.6.3

これらの呼び出しは.ctorsセクションに入ります:

.ctors 0x000000009d011508 0x4 libmotor.o

.ctors 0x000000009d01150c 0x4 libaudio.o


コンパイルは で行われ-ffunction-sections -fdata-sections、リンカは を取得し--gc-sectionsました。

すべてのバイナリが機能しますが、すべての呼び出しを同じセクションに入れたいと思います (リンカー スクリプトのメンテナンスを簡素化するため)。

  • ターゲット セクションが異なるのはなぜですか?
  • コマンド ライン オプションを使用してデフォルト セクションを変更することはできますか?
  • コマンド ライン オプションが終了しない場合: GCC コンパイル時にデフォルト セクションを定義することは可能ですか?
4

1 に答える 1

8

バグ 46770 - .ctors/.dtors をサポートしているターゲットで .init_array/.fini_array に置き換えるには、長い議論があります。

状況を説明するいくつかの項目を抽出しました。

なぜ現れ.init_arrayた?

  • 実際のコードを含む の SVR4 バージョンと、関数ポインターを含み、crt*.o ファイルから提供されるプロローグおよびエピローグ部分ではなく、動的配列のエントリを使用する HP-UX バージョンをブレンドするために、.init_array/を追加しました。HP-UX バージョンは改善されたと見なされていましたが、互換性がありませんでした。そのため、セクションと動的テーブル エントリの名前を変更して、2 つのバージョンが共存し、実装が一方から他方へゆっくりと移行できるようにしました。 ..fini_array.initDT_INIT_SZ

  • HP-UX では、静的コンストラクターに.init/を使用し、デストラクタをに追加するのではなく.init_array、対応する静的デストラクタを特別なリストに登録しました。環境)atexit.fini_arraydlclose()

.ctorsとでは実行順序が異なります。.init_array

.ctorsセクションの逆順

一部のプログラムは、後でリンクされたアーカイブ内のグローバル コンストラクターが、それらのアーカイブに対してリンクされたオブジェクト内のコンストラクターの前に実行されるという事実に暗黙的に依存している場合があります。つまり、

g++ foo.o -lbar

ここで、bar は共有ライブラリではなく静的アーカイブであり、現在、libbar.c から取り込まれたオブジェクトのグローバル コンストラクターは、foo.o のグローバル コンストラクターの前に実行されます。逆よりも正しい可能性が高いため、これは意図的な選択でした。ただし、C++ 標準はそれを保証していないため、この順序付けに依存するプログラムは技術的に無効です。

の逆順の問題.ctors

ldGNUとgold、コンストラクターを から に移動するため.ctorsに多くの作業が行われました。これら.init_arrayはすべて、Firefox の起動待ち時間を改善するためのものです。

.init_array/.fini_arrayの代わりに.ctors/を使用.dtorsすると、関連付けられた (相対的な) 再配置の必要がなくなり、起動時の後方ディスク シークが回避されます (while.ctorsは後方に.init_array処理され、前方に処理されるため)。

.ctorsからへの遷移.init_array

ldGNUとgoldnowの両方のメインライン バージョンは、.ctorsセクションを.init_arrayセクションに配置し、セクションをセクションに配置.dtors.fini_arrayます。

コメント: おそらく GCC 4.7 で導入されました。

ARM EABI は.init_array初日から使用しています。

コメント: それでも、デフォルトのリンカー スクリプトには.ctors出力セクションが含まれています。

GCC 構成

選択肢の 1 つは、gcc を --disable-initfini-array で構成することです。

mips-elf-gcc -vコメント: このオプションは、 ( -v"Configured with: ..." と表示されます) の出力には表示されません。

于 2015-03-11T08:42:01.177 に答える