Oracle® Solaris 11.2 リンカーとライブラリガイド

印刷ビューの終了

更新: 2014 年 7 月
 
 

シンボルソートセクション

並んで配置される .SUNW_ldynsym セクションと .dynsym セクションによって作成される動的なシンボルテーブルを使って、メモリーアドレスを対応するシンボルにマッピングできます。このマッピングを使って、特定のアドレスがどの関数または変数を表現するかを判断できます。ただし、シンボルテーブルを解析してマッピングを判断することは、シンボルがシンボルテーブルに書き込まれる順番が原因で、複雑な作業になります。シンボルテーブルのレイアウトと規則を参照してください。このレイアウトによって、アドレスをシンボル名に関連付ける作業は複雑になります。

  • シンボルがアドレスでソートされていないため、テーブル全体を地道に上から順番に検索する必要があります。

  • 特定のアドレスを複数のシンボルが参照していることがあります。これらのシンボルは有効で正しいのですが、それらの等価の名前のうち、デバッグツールがどれを使用するかを選択するかが明確でないことがあります。ツールごとに異なる名前が使用されることもあります。こうした問題によって、ユーザーが混乱する可能性があります。

  • 多くのシンボルがアドレス以外の情報を提供しています。それらのシンボルを検索に含めるべきではありません。

これらの問題を解決するために、シンボルソートセクションを使用します。シンボルソートセクションは、Elf32_Word または Elf64_Word オブジェクトの配列です。この配列の各要素は、.SUNW_ldynsym.dynsym の結合シンボルテーブルへのインデックスです。この配列の要素は、参照されるシンボルがソート順に提供されるようにソートされます。関数または変数を表現するシンボルのみが取り込まれます。ソート配列に関連付けられたシンボルは、–S オプション付きでelfdump(1)を使用することで表示できます。

通常のシンボルとスレッド固有ストレージシンボルを一緒にソートすることはできません。通常のシンボルの値は、そのシンボルが参照している関数または変数のアドレスです。スレッド固有ストレージシンボルの値は、変数のスレッドオフセットです。したがって、通常のシンボルとスレッド固有ストレージシンボルでは、異なる 2 つのソートセクションが使用されます。

.SUNW_dynsymsort

SHT_SUNW_SYMSORT タイプのセクション。.SUNW_ldynsym.dynsym の結合シンボルテーブル内の通常のシンボルへのインデックスが含まれます (アドレスでソート) 。変数または関数を表現しないシンボルは取り込まれません。

.SUNW_dyntlssort

SHT_SUNW_TLSSORT タイプのセクション。.SUNW_ldynsym.dynsym の結合シンボルテーブル内の TLS シンボルへのインデックスが含まれます (オフセットでソート) 。このセクションは、オブジェクトファイルに TLS シンボルが含まれる場合にだけ作成されます。

リンカーは、ソートセクションがどのシンボルを参照するかを選択するために、次の規則を記載順に使用します。

  • シンボルは関数タイプまたは変数タイプである必要がある: STT_FUNCSTT_OBJECTSTT_COMMON、または STT_TLS

  • 次のシンボルは常に取り込まれる (存在する場合): _DYNAMIC_end_fini_GLOBAL_OFFSET_TABLE_ _init_PROCEDURE_LINKAGE_TABLE_、および _start

  • 同じ項目を参照する大域シンボルとウィークシンボルが見つかった場合は、ウィークシンボルが取り込まれ、大域シンボルは除外される。

  • シンボルは未定義であってはいけない。

  • シンボルはゼロ以外のサイズである必要がある。

これらの規則によって、コンパイラとリンカーが自動的に生成するシンボルは除外されます。選択されるシンボルは、ユーザーに関係するものです。ただし、次の 2 つの場合には、選択処理を改善するために手動による介入が必要になる場合があります。

  • 規則によって、必要とする特殊シンボルが選択されなかった場合。たとえば、サイズがゼロの特殊シンボルなど。

  • 不要で余分なシンボルが選択される場合。たとえば、共有オブジェクトには、同じアドレスを参照し、同じサイズのシンボルを複数定義できます。これらの別名シンボルは同じ項目を参照することになります。ソートセクション内で、複数のシンボルファミリの 1 つだけを取り込みたい場合があります。

mapfile のキーワード DYNSORT および NODYNSORT により、シンボルをきめ細かく選択できます。SYMBOL_SCOPE/SYMBOL_VERSION 指令を参照してください。

DYNSORT

ソートセクションに含める必要があるシンボルを指定します。シンボルタイプは STT_FUNCSTT_OBJECTSTT_COMMON、または STT_TLS である必要があります。

NODYNSORT

ソートセクションに含める必要があるシンボルを指定します。

たとえば、あるオブジェクトのシンボルテーブル定義が次のようになっているとします。

$ elfdump -sN.symtab foo.so.1 | egrep "foo$|bar$"
    [37]    0x4b0   0x1c  FUNC GLOB  D   0 .text      bar
    [38]    0x4b0   0x1c  FUNC WEAK  D   0 .text      foo

シンボル foobar は別名ペアを表現しています。デフォルトでは、ソートされた配列を作成するときに、シンボル foo だけが表現されます。

$ cc -o foo.so.1 -G foo.c
$ elfdump -S foo.so.1 | egrep "foo$|bar$"
    [13]    0x4b0   0x1c  FUNC WEAK  D   0 .text      foo

リンカーによって同じ項目を参照する大域シンボルとウィークシンボルが検出された場合は、通常はウィークシンボルが選択されます。ウィークシンボル foo に関連付けられたので、シンボル bar はソートされた配列から除外されます。

次の mapfile を実行すると、シンボル bar がソートされた配列内で表現されています。シンボル foo は表示されません。

$ cat mapfile
{
        global:
                bar = DYNSORT;
                foo = NODYNSORT;
};
$ cc -M mapfile -o foo.so.2 -Kpic -G foo.c
$ elfdump -S foo.so.2 | egrep "foo$|bar$"
    [13]    0x4b0   0x1c  FUNC GLOB  D   0 .text      bar

.SUNW_dynsymsort セクションと .SUNW_dyntlssort セクションには、.SUNW_ldynsym セクションの存在が必要です。したがって、–z noldynsym オプションを使用すると、すべてのソートセクションが作成されなくなります。