17

http://newlib.sourcearchive.com/documentation/1.18.0/init_8c-source.htmlから__libc_init_arrayのソースコードを表示しました。
しかし、私はこの関数が何をするのかよくわかりません。

私はこれらのシンボルが

/* These magic symbols are provided by the linker.  */
extern void (*__preinit_array_start []) (void) __attribute__((weak));
extern void (*__preinit_array_end []) (void) __attribute__((weak));
extern void (*__init_array_start []) (void) __attribute__((weak));
extern void (*__init_array_end []) (void) __attribute__((weak));
extern void (*__fini_array_start []) (void) __attribute__((weak));
extern void (*__fini_array_end []) (void) __attribute__((weak));

リンカスクリプトで定義されています。
リンカスクリプトの一部は次のようになります。

  .preinit_array     :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  } >FLASH
  .init_array :
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
  } >FLASH
  ...

次に、ELF-v1.1、gcc 4.7.2、ld、およびcodesourcery(codesourcery g ++ liteを使用しています)のドキュメントでキー「init_array」を使用して検索したところ、何も得られませんでした。

これらの記号の仕様はどこにありますか?

4

4 に答える 4

19

これらのシンボルは、C/C++ のコンストラクタとデストラクタの起動に関連し、前後に呼び出されるコードを分解しますmain().init.ctors.preinit_array、およびという名前のセクションは.init_array、C/C++ オブジェクトの初期化に関係し、セクション.fini.fini_array、および.dtorsは破棄に関係します。開始記号と終了記号は、そのような操作に関連するコード セクションの開始と終了を定義し、ランタイム サポート コードの他の部分から参照される場合があります。

.preinit_arrayand.init_arrayセクションには、初期化時に呼び出される関数へのポインタの配列が含まれています。は.fini_array、破棄時に呼び出される関数の配列です。おそらく、開始ラベルと終了ラベルは、これらのリストをたどるために使用されます。

これらのシンボルを使用するコードの良い例は、ここのlibc source for にありinitfini.cます。起動時に__libc_init_array()が呼び出され、これが最初.preinit_arrayに開始ラベルと終了ラベルを参照して、セクション内のすべての関数ポインターを呼び出すことがわかります。_init()次に、セクション内の関数を呼び出します.init。最後に、セクション内のすべての関数ポインタを呼び出します.init_arraymain()の分解呼び出しが完了した後、最終的に を呼び出す前に、__libc_fini_array()のすべての関数が呼び出されます。このコードには、ティアダウン時に呼び出す関数の数を計算する際に、カット アンド ペーストのバグがあるように見えることに注意してください。おそらく、彼らはリアルタイム マイクロ コントローラ OS を扱っていて、このセクションに遭遇したことはありません。.fini_array_fini()

于 2015-06-22T05:10:06.510 に答える
4

これらの特殊なシンボルはPT_DYNAMIC、生成されたライブラリのセクションによって参照されることになります。PT_DYNAMIC動的リンクを成功させるために必要なさまざまなリソースを定義します (ライブラリの依存関係、エクスポートされたシンボル、シンボル ハッシュ テーブル、init/fini 配列など)。

したがって、これらのリスト内の関数は最終的にPT_DYNAMICセクションにリンクされ、動的リンク プロセスの適切なタイミングで呼び出されます。詳細については、ソースを参照してlddください。

于 2013-03-07T07:27:38.570 に答える