JavaScript is required to for searching.
ナビゲーションリンクをスキップ
印刷ビューの終了
リンカーとライブラリ     Oracle Solaris 10 8/11 Information Library (日本語)
search filter icon
search icon

ドキュメントの情報

はじめに

1.  Oracle Solaris リンカーの紹介

2.  リンカー

3.  実行時リンカー

4.  共有オブジェクト

5.  アプリケーションバイナリインタフェースとバージョン管理

6.  サポートインタフェース

7.  オブジェクトファイル形式

8.  スレッド固有領域 (TLS)

9.  mapfile

mapfile の構造と構文

mapfile のバージョン

条件付き入力

指令の構文

mapfile 指令

CAPABILITY 指令

HW 属性

HW_1/HW_2 属性

MACHINE 属性

PLATFORM 属性

SF 属性

SF_1 属性

DEPEND_VERSIONS 指令

ALLOW 属性

REQUIRE 属性

HDR_NOALLOC 指令

PHDR_ADD_NULL 指令

LOAD_SEGMENT/NOTE_SEGMENT/NULL_SEGMENT 指令

ALIGN 属性 (LOAD_SEGMENT のみ)

ASSIGN_SECTION 属性

DISABLE 属性

FLAGS 属性 (LOAD_SEGMENT のみ)

IS_ORDER 属性

MAX_SIZE 属性 (LOAD_SEGMENT のみ)

NOHDR 属性 (LOAD_SEGMENT のみ)

OS_ORDER 属性

PADDR 属性 (LOAD_SEGMENT のみ)

ROUND 属性 (LOAD_SEGMENT のみ)

SIZE_SYMBOL 属性 (LOAD_SEGMENT のみ)

VADDR (LOAD_SEGMENT のみ)

SEGMENT_ORDER 指令

STACK 指令

STUB_OBJECT 指令

SYMBOL_SCOPE/SYMBOL_VERSION 指令

ASSERT 属性

AUXILIARY 属性

FILTER 属性

FLAGS 属性

SIZE 属性

TYPE 属性

VALUE 属性

定義済みセグメント

マッピングの例

例: セクションからセグメントへの割り当て

例: 定義済みセクションの変更

リンカー内部情報: セクションおよびセグメント処理

セクションからセグメントへの割り当て

定義済みセグメントとエントランス基準のための mapfile 指令

A.  リンカーのクイックリファレンス

B.  バージョン管理の手引き

C.  動的ストリングトークンによる依存関係の確立

D.  直接結合

E.  System V Release 4 (バージョン 1) Mapfile

F.  リンカーとライブラリのアップデートおよび新機能

索引

mapfile 指令

mapfile 指令は、出力オブジェクトのさまざまな側面を指定するために存在します。これらの指令は共通の構文を共有しています。属性に名前と値のペアを使用し、階層およびグループを表すために {...} 構文を使用します。次の指令がリンカーで受け入れられます。

表 9-6 mapfile 指令

指令
目的
CAPABILITY
ハードウェア、ソフトウェア、およびプラットフォーム機能
DEPEND_VERSIONS
共有オブジェクトの依存関係から許可されるバージョンを指定します
HDR_NOALLOC
ELF ヘッダーおよびプログラムヘッダーは割り当て不可です
LOAD_SEGMENT
読み込み可能な新しいセグメントを作成するか、既存の読み込みセグメントを変更します
NOTE_SEGMENT
注釈セグメントを作成するか、既存の注釈セグメントを変更します
NULL_SEGMENT
ヌルセグメントを作成するか、既存のヌルセグメントを変更します
PHDR_ADD_NULL
ヌルプログラムヘッダーエントリを追加します
SEGMENT_ORDER
出力オブジェクトおよびプログラムヘッダー配列内のセグメントの順序を指定します
STACK
プロセススタック属性
STUB_OBJECT
オブジェクトがスタブオブジェクトとして構築できることを指定します
SYMBOL_SCOPE
命名されていない大域バージョン内でシンボルの属性およびスコープを設定します
SYMBOL_VERSION
明示的に命名されたバージョン内でシンボルの属性およびスコープを設定します

サポートされる各 mapfile 指令の具体的な構文については、後続の節で示します。

CAPABILITY 指令

再配置可能オブジェクトのハードウェア、ソフトウェア、マシン、およびプラットフォームの機能は通常、コンパイル時にオブジェクト内部に記録されます。リンカーは入力再配置可能オブジェクトの機能を組み合わせて、出力ファイルの最終機能セクションを作成します。mapfile 内で機能を定義して、入力再配置可能オブジェクトから指定される機能に追加したり、完全に置き換えたりすることができます。

        CAPABILITY [capid] {
                HW  = [hwcap_flag...];
                HW += [hwcap_flag...];
                HW -= [hwcap_flag...];
 
                HW_1  = [value...];
                HW_1 += [value...];
                HW_1 -= [value...];
 
                HW_2  = [value...];
                HW_2 += [value...];
                HW_2 -= [value...];
 
                MACHINE  = [machine_name...];
                MACHINE += [machine_name...];
                MACHINE -= [machine_name...];
 
                PLATFORM  = [platform_name...];
                PLATFORM += [platform_name...];
                PLATFORM -= [platform_name...];
 
                SF  = [sfcap_flag...];
                SF += [sfcap_flag...];
                SF -= [sfcap_flag...];
 
                SF_1  = [value...];
                SF_1 += [value...];
                SF_1 -= [value...];
        };    

オプションの capid の名前が存在する場合、この名前はオブジェクト機能のシンボリック名を提供し、結果として出力オブジェクト内に CA_SUNW_ID 機能エントリができます。複数の CAPABILITY 指令が存在する場合、最後の指令の capid が使用されます。

空の CAPABILITY 指令を使用すると、機能の値を何も指定せずにオブジェクト機能の capid を指定できます。

        CAPABILITY capid;

各タイプの機能について、リンカーは現在の値 (value) と、除外する一連の値 (exclude ) を保持します。ハードウェアおよびソフトウェア機能の場合、これらの値はビットマスクです。マシンおよびプラットフォームの機能の場合、これらは名前のリストです。mapfile を処理する前に、すべての機能の value および exclude の値がクリアされます。代入演算子の機能を次に示します。

入力オブジェクトは mapfile が読み込まれたあとに処理されます。入力オブジェクトによって指定された機能の値は、mapfile からの値とマージされます。ただし、「=」演算子が使用された場合は、入力オブジェクト内に見つかった機能は無視されます。つまり、「=」演算子は入力オブジェクトを上書きし、「+=」演算子は機能を追加します。

結果の機能の値を出力オブジェクトに書き込む前に、リンカーは「-=」演算子で指定されたすべての機能の値を削除します。

指定された機能を出力オブジェクトから完全に除去するには、「=」演算子と空の値リストを使用すれば十分です。たとえば次の例は、入力オブジェクトによって提供されるすべてのハードウェア機能を抑制します。

        $mapfile_version 2
        CAPABILITY {
                HW = ;
        };

ELF オブジェクト内では、ハードウェアとソフトウェアの機能は、オブジェクトの機能セクションから検出される 1 つ以上のビットマスク内でのビット割り当てとして表現されます。HW および SF mapfile 属性は、この実装の抽象的なビューを提供し、リンカーによって適切なマスクおよびビットに変換される、空白区切りのシンボリック機能名のリストを受け入れます。番号付き属性 (HW_1 HW_2SF_1) は、ベースとなる機能ビットマスクへの直接数値アクセスを可能にするために存在します。これらは正式に定義されていない機能ビットを指定するために使用できます。可能な場合、HW および SF 属性を使用することをお勧めします。

HW 属性

ハードウェア機能は、空白区切りのシンボリック機能名のリストとして指定されます。SPARC プラットフォームでは、ハードウェア機能は <sys/auxv_SPARC.h>AV_ の値として定義されます。x86 プラットフォームでは、ハードウェア機能は <sys/auxv_386.h>AV_ の値として定義されます。mapfile では同じ名前を使用し、AV_ 接頭辞を付けません。たとえば、x86 の AV_SSE ハードウェア機能は mapfile 内では SSE と呼ばれます。このリストには、CA_SUNW_HW_ 機能マスク用に定義されたすべての機能名を含めることができます。

HW_1/HW_2 属性

HW_1 および HW_2 属性には、CA_SUNW_HW_1 および CA_SUNW_HW_2 機能マスクを数値として直接指定したり、そのマスクに対応するシンボリックハードウェア機能名として指定したりできます。

MACHINE 属性

MACHINE 属性は、オブジェクトが実行可能なシステムのマシンハードウェア名を指定します。システムのマシンハードウェア名は、ユーティリティー uname(1)-m オプションを付けて実行すると表示できます。CAPABILITY 指令は複数のマシン名を指定できます。それぞれの名前は出力オブジェクト内の CA_SUNW_MACH 機能エントリになります。

PLATFORM 属性

PLATFORM 属性は、オブジェクトが実行可能なシステムのプラットフォーム名を指定します。システムのプラットフォーム名は、ユーティリティー uname(1)-i オプションを付けて実行すると表示できます。CAPABILITY 指令は複数のプラットフォーム名を指定できます。それぞれの名前は出力オブジェクト内の CA_SUNW_PLAT 機能エントリになります。

SF 属性

ソフトウェア機能は、空白区切りのシンボリック機能名のリストとして指定されます。ソフトウェア機能は、<sys/elf.h>SF1_SUNW_ の値として定義されます。mapfile では同じ名前を使用し、SF1_SUNW_ 接頭辞を付けません。たとえば、SF1_SUNW_ADDR32 ソフトウェア機能は mapfile 内では ADDR32 と呼ばれます。このリストには、CA_SUNW_SF_1 用に定義されたすべての機能名を含めることができます。

SF_1 属性

SF_1 属性には、CA_SUNW_SF_1 機能マスクを数値として直接指定したり、そのマスクに対応するシンボリックソフトウェア機能名として指定したりできます。

DEPEND_VERSIONS 指令

共有可能オブジェクトをリンクするとき、オブジェクトからエクスポートされるすべてのバージョンのシンボルが、通常はリンカーで使用可能になります。DEPEND_VERSIONS 指令は、指定したバージョンへのアクセスに限定するために使用されます。バージョンアクセスの制限は、古いバージョンのシステムで使用できない可能性がある新しい機能が出力オブジェクトで使用されないようにするために使用できます。

DEPEND_VERSIONS 指令には次の構文があります。

        DEPEND_VERSIONS objname {
                ALLOW = version_name;
                REQUIRE = version_name;
                ...
        };

objname は、コマンド行で指定された共有オブジェクトの名前です。-l コマンド行オプションを使用してオブジェクトを指定する一般的な場合、これは指定された名前に lib 接頭辞が付いたものになります。たとえば、libc はコマンド行で一般的に -lc と参照されるため、DEPEND_VERSIONS 指令内では libc.so と指定されます。

ALLOW 属性

ALLOW 属性は、指定されたバージョンと、そのバージョンによって継承されたバージョンが、出力オブジェクト内のシンボルを解決するためにリンカーによって使用可能であることを指定します。リンカーは、このバージョンを含む継承の連鎖内で使用されるもっとも高いバージョンの要件を、出力オブジェクトの要件に追加します。

REQUIRE 属性

REQUIRE は、リンク操作の要件を満たすために指定されたバージョンが実際に必要かどうかによらず、そのバージョンを出力オブジェクトの要件に追加します。

HDR_NOALLOC 指令

すべての ELF オブジェクトには、ファイル内のオフセット 0 に ELF ヘッダーがあります。実行可能ファイルおよび共有可能オブジェクトにはプログラムヘッダーもあり、これらは ELF ヘッダーを経由してアクセスされます。リンカーは通常、これらの項目が、読み込み可能な先頭セグメントの一部として組み込まれるように配置します。したがって、これらのヘッダーに含まれる情報は、マップされたイメージ内で可視となり、通常は実行時リンカーによって使用されます。HDR_NOALLOC 指令はこれを防ぎます。

        HDR_NOALLOC;

HDR_NOALLOC が指定されると、ELF ヘッダーおよびプログラムヘッダー配列は、結果として生じる出力オブジェクトファイルの先頭に引き続き示されますが、読み込み可能なセグメントには含まれず、イメージの仮想アドレス計算は、ELF ヘッダーのベースでなく先頭セグメントの先頭セクションから開始されます。

PHDR_ADD_NULL 指令

PHDR_ADD_NULL 指令によって、リンカーは、タイプが PT_NULL の指定された数のプログラムヘッダーエントリを、プログラムヘッダー配列の末尾に追加します。追加の PT_NULL エントリは、事後処理ユーティリティーで使用できます。

        PHDR_ADD_NULL = value;

value は正の整数値である必要があり、作成する追加の PT_NULL エントリの数を指定します。結果として生じるプログラムヘッダーエントリのすべてのフィールドは、0 に設定されます。

LOAD_SEGMENT/NOTE_SEGMENT/NULL_SEGMENT 指令

セグメントは出力オブジェクトの連続する部分で、セクションを含みます。mapfile セグメント指令では、3 つの異なるセグメントタイプの指定が可能です。

セグメント指令は、出力ファイルに新しいセグメントを作成したり、既存のセグメントの属性値を変更したりするために使用されます。既存のセグメントとは、以前に定義したものか、「定義済みセグメント」で説明されている組み込みセグメントのいずれかです。新しいセグメントはそれぞれオブジェクトに追加され、同じタイプの最後のセグメントの後に置かれます。読み込み可能なセグメントが最初に追加され、その次が注釈セグメントで、最後がヌルセグメントです。これらのセグメントに関連付けられたプログラムヘッダーは、セグメントと同じ相対順序でプログラムヘッダー配列に配置されます。デフォルトの配置は、読み込み可能なセグメントの場合は明示的にアドレスを設定するか、または SEGMENT_ORDER 指令を使用すると変更できます。

segment_name が事前に存在するセグメントの場合、指定された属性によって既存のセグメントが変更されます。それ以外の場合、新しいセグメントが作成され、指定された属性が新しいセグメントに適用されます。リンカーは、明示的に指定されていない属性にデフォルト値を設定します。


注 - セグメント名を選択するとき、リンカーの将来のバージョンで、新しい定義済みセグメントが追加される可能性があることに留意してください。ユーザーのセグメント指令に使用する名前がこの新しい名前と一致した場合、新しい定義済みセグメントによって、ユーザーの mapfile は、新規セグメントの作成から既存のセグメントの変更へと意味が変わります。この状況を回避するためのもっとも良い方法は、セグメントに一般的な名前を使用することを避け、すべてのセグメント名に対して企業識別子、プロジェクト識別子、プログラムの名前などの固有の接頭辞を追加することです。たとえば、hello_world という名前のプログラムの場合、hello_world_data_segment というセグメント名を使用できます。


3 つすべてのセグメント指令は、中核となる一連の共通属性を共有します。セグメント宣言は次のようになり、directiveLOAD_SEGMENTNOTE_SEGMENTNULL_SEGMENT のいずれかで置き換えます。

        directive segment_name {
                ASSIGN_SECTION [assign_name];
                ASSIGN_SECTION [assign_name] {
                        FILE_BASENAME = file_basename;
                        FILE_OBJNAME = objname;
                        FILE_PATH = file_path;
                        FLAGS = section_flags;
                        IS_NAME = section_name;
                        TYPE = section_type;
                };

                DISABLE;

                IS_ORDER  = assign_name...;
                IS_ORDER += assign_name...;

                OS_ORDER  = section_name...;
                OS_ORDER += section_name...;
};

LOAD_SEGMENT 指令は、読み込み可能セグメントに固有の一連の追加属性を受け入れます。これらの追加属性の構文は次のとおりです。

        LOAD_SEGMENT segment_name {
                ALIGN = value;

                FLAGS  = segment_flags;
                FLAGS += segment_flags;
                FLAGS -= segment_flags;

                MAX_SIZE = value;

                NOHDR;

                PADDR = value;
                ROUND = value;

                SIZE_SYMBOL  = symbol_name...;
                SIZE_SYMBOL += symbol_name...;

                VADDR = value;
};

どのセグメント指令も空の指令として指定できます。空のセグメント指令によって新しいセグメントが作成されると、すべてのセグメント属性にデフォルト値が設定されます。空のセグメントは次のように宣言されます。

        LOAD_SEGMENT segment_name;

        NOTE_SEGMENT segment_name;

        NULL_SEGMENT segment_name;

1 つ以上のセグメント指令によって受け入れられるすべての属性について、次に説明します。

ALIGN 属性 (LOAD_SEGMENT のみ)

ALIGN 属性は、読み込み可能セグメントの配置を指定するために使用されます。指定された値は、セグメントに対応するプログラムヘッダーの p_align フィールドに設定されます。セグメント配置は、セグメントの最初の仮想アドレスを計算する際に使用されます。

指定される配置は 2 のべき乗である必要があります。デフォルトでは、リンカーによって、セグメントの配置は組み込みのデフォルトに設定されます。デフォルトは CPU により異なり、ソフトウェアのバージョンによっても異なる場合があります。

ALIGN 属性は PADDR および VADDR 属性と相互に排他的で、これらと一緒に使用できません。PADDR または VADDR が指定されると、対応するプログラムヘッダーの p_align フィールドはデフォルト値に設定されます。

ASSIGN_SECTION 属性

ASSIGN_SECTION は、指定されたセグメントへの割り当て用にセクションを集合的に修飾する、セクション名、タイプ、およびフラグなどのセクション属性の組み合わせです。このような属性のセットは、エントランス基準と呼ばれます。セクションが一致するのは、セクション属性がこれらのエントランス基準と正確に一致するときです。ASSIGN_SECTION は、属性を何も指定しない場合、基準が比較される任意のセクションと一致します。

指定されたセグメントに対して複数の ASSIGN_SECTION 属性を指定できます。ASSIGN_SECTION 属性は、それぞれ互いに独立しています。セクションがセグメントに割り当てられるのは、そのセグメントに関連付けられているいずれかの ASSIGN_SECTION 定義とセクションが一致する場合です。セグメントに 1 つ以上の ASSIGN_SECTION 属性が存在しない場合、リンカーはセクションをセグメントに割り当てません。

リンカーはセクションをセグメントに割り当てるために、エントランス基準の内部リストを使用します。mapfile 内で見つかった ASSIGN_SECTION 宣言は、見つかった順序でこのリストに配置されます。「定義済みセグメント」で説明した組み込みセグメントのエントランス基準は、このリスト内で最後の mapfile 定義済みエントリの直後に配置されます。

エントランス基準には、オプションの名前 (assign_name) を指定できます。この名前は IS_ORDER 属性と一緒に使用すると、入力セクションが出力セクションに配置される順序を指定できます。

入力セクションを配置するには、リンカーはエントランス基準リストの先頭から開始し、セクションの属性を各エントランス基準と順番に比較します。セクションは、セクション属性に正確に一致した最初のエントランス基準に関連付けられているセグメントに割り当てられます。一致がない場合、一般的なすべての割り当て不可のセクションの場合と同じように、セクションはファイルの末尾に配置されます。

ASSIGN_SECTION は次を受け入れます。

表 9-7 セクションフラグの値

フラグの値
意味
ALLOC
セクションは割り当て可能です
WRITE
セクションは書き込み可能です
EXECUTE
セクションは実行可能です
AMD64_LARGE
セクションは 2G バイトより大きくすることができます

DISABLE 属性

DISABLE 属性を使用すると、リンカーはセグメントを無視します。無効にされたセグメントには、セクションが割り当てられません。セグメントは後続のセグメント指令によって参照されると、自動的にふたたび有効化されます。したがって、空の参照のみで、無効にされたセグメントをふたたび有効にできます。

segment segment_name;

FLAGS 属性 (LOAD_SEGMENT のみ)

FLAGS 属性は、表 9-3 のアクセス権の空白区切りのリストとして、セグメントのアクセス権を指定します。デフォルトでは、ユーザー定義のセグメントは READWRITE、および EXECUTE アクセス権を受け入れます。「定義済みセグメント」で説明されている定義済みセグメント用のデフォルトフラグがリンカーによって指定され、場合によってはプラットフォーム依存になります。

3 つの形式を使用できます。

        FLAGS  = segment_flags...;
        FLAGS += segment_flags...;
        FLAGS -= segment_flags...;

シンプルな「=」代入演算子は現在のフラグを新しいセットで置き換え、「+=」形式は既存のセットに新規フラグを追加し、「-=」形式は指定されたフラグを既存のセットから削除します。

IS_ORDER 属性

リンカーは通常、見つかった順序で出力セクションをセグメントに配置します。同様に、出力セクションを構成する入力セクションも、見つかった順序で配置されます。IS_ORDER 属性は、入力セクションのこのデフォルトの配置を変更するために使用できます。IS_ORDER は、エントランス基準名 (assign_name) の空白区切りのリストを指定します。これらのいずれかのエントランス基準に一致したセクションは、出力セクションの先頭に配置され、IS_ORDER で指定された順序で並べ替えられます。IS_ORDER リストに見つからないエントランス基準に一致したセクションは、並べ替えられたセクションの後方に、見つかった順序で配置されます。

=」形式の代入を使用すると、指定されたセグメントの IS_ORDER の以前の値は破棄され、新しいリストで置き換わります。「+=」形式の IS_ORDER の場合、既存のリストの末尾に新しいリストを連結します。

IS_ORDER 属性が特に注目されるのは、コンパイラの -xF オプションと合わせて使用する場合です。ファイルを -xF オプションを使ってコンパイルすると、そのファイル内の各関数が、.text セクションと同じ属性を持つ別個のセクションに置かれます。これらのセクションは、.text%function_name (function_name は関数名) という名前です。

たとえば、main()foo()、および bar() の 3 つの関数を持つファイルを -xF オプションを使ってコンパイルすると、再配置可能オブジェクトファイルが作成され、3 つの関数のテキストが .text%main.text%foo、および .text%bar という名前のセクションに配置されます。リンカーがこれらのセクションを出力に配置するとき、% と、% の後続のすべてが削除されます。したがって、これら 3 つの関数はすべて、.text 出力セクションに配置されます。IS_ORDER 属性は、.text 出力セクション内で特定の相対的な順序で配置することを強制するために使用できます。

次のユーザー定義の mapfile を検討します。

        $mapfile_version 2
                LOAD_SEGMENT text {
                ASSIGN_SECTION text_bar  { IS_NAME = .text%bar };
                ASSIGN_SECTION text_main { IS_NAME = .text%main };
                ASSIGN_SECTION text_foo  { IS_NAME = .text%foo };
                IS_ORDER = text_foo text_bar text_main;
        };

これら 3 つの関数がソースコード内で検出された順序や、リンカーによって見つけられた順序に関係なく、出力オブジェクトの text セグメント内での順序は foo()bar()main() となります。

MAX_SIZE 属性 (LOAD_SEGMENT のみ)

リンカーはデフォルトで、セグメントの内容が必要とするサイズにまで、セグメントが大きくなることを許可します。セグメントの最大サイズを指定するために、MAX_SIZE 属性を使用できます。MAX_SIZE が設定されると、セグメントが指定されたサイズを超えて大きくなった場合にリンカーはエラーを生成します。

NOHDR 属性 (LOAD_SEGMENT のみ)

NOHDR 属性が設定されたセグメントが、出力オブジェクトの最初の読み込み可能セグメントになった場合、ELF およびプログラムヘッダーはセグメントに含まれません。

NOHDR 属性が最上位の HDR_NOALLOC 指令と異なる点は、HDR_NOALLOC はセグメントごとの値であり、セグメントが最初の読み込み可能セグメントになった場合にのみ有効だということです。この機能は主に、古い mapfile との互換性を確保するために存在します。詳細は、付録 E System V Release 4 (バージョン 1) Mapfileを参照してください。

セグメントの NOHDR 属性よりも HDR_NOALLOC 指令を優先させることをお勧めします。

OS_ORDER 属性

リンカーは通常、見つかった順序で出力セクションをセグメントに配置します。OS_ORDER 属性は、出力セクションのこのデフォルトの配置を変更するために使用できます。OS_ORDER は、出力セクション名 ( section_name) の空白区切りのリストを指定します。リストされたセクションは、セグメントの先頭に配置され、OS_ORDER で指定された順序で並べ替えられます。OS_ORDER にリストされていないセクションは、並べ替えられたセクションの後方に、見つかった順序で配置されます。

=」形式の代入を使用すると、指定されたセグメントの OS_ORDER の以前の値は破棄され、新しいリストで置き換わります。「+=」形式の OS_ORDER の場合、既存のリストの末尾に新しいリストを連結します。

PADDR 属性 (LOAD_SEGMENT のみ)

PADDR 属性は、セグメントの物理アドレスを明示するために使用されます。指定された値は、セグメントに対応するプログラムヘッダーの p_addr フィールドに設定されます。デフォルトでは、リンカーはセグメントの物理アドレスを 0 に設定します。この理由は、このフィールドはユーザーモードオブジェクトについては意味がなく、主にオペレーティングシステムのカーネルなど「ユーザーランド以外」のオブジェクトに関係があるためです。

ROUND 属性 (LOAD_SEGMENT のみ)

ROUND 属性は、セグメントのサイズを指定された値に丸める必要があることを指定するために使用されます。丸める値の指定は 2 のべき乗である必要があります。デフォルトでは、リンカーはセグメントの丸め係数を 1 に設定し、これはセグメントサイズが丸められないことを意味します。

SIZE_SYMBOL 属性 (LOAD_SEGMENT のみ)

SIZE_SYMBOL 属性は、リンカーによって作成される、セクションのサイズシンボル名の空白区切りのリストを定義します。サイズシンボルは、セグメントのサイズをバイト数で示す大域絶対シンボルです。これらのシンボルは、オブジェクトファイル内で参照できます。コード内でシンボルにアクセスするには、symbol_name が言語内で正当な識別子であることを確認する必要があります。シンボルをほかの言語からアクセスできる可能性が高くするため、C プログラミング言語のシンボル命名規則が推奨されます。

=」形式の代入は初期値を設定するために使用でき、リンカーのセッションにつき 1 回のみ使用できます。「+=」形式の SIZE_SYMBOL の場合、既存のリストの末尾に新しいリストを連結し、必要な回数だけ使用できます。

VADDR (LOAD_SEGMENT のみ)

VADDR 属性は、セグメントの仮想アドレスを明示するために使用されます。指定された値は、セグメントに対応するプログラムヘッダーの p_vaddr フィールドに設定されます。デフォルトでは、リンカーは出力ファイルが作成されるとき、仮想アドレスをセグメントに割り当てます。

SEGMENT_ORDER 指令

SEGMENT_ORDER 指令は、出力オブジェクト内のセグメントのデフォルト以外の順序付けを指定するために使用されます。

SEGMENT_ORDER は、セグメント名の空白区切りのリストを受け入れます。

        SEGMENT_ORDER  = segment_name...;
        SEGMENT_ORDER += segment_name...;

=」形式の代入を使用すると、以前のセグメント順序リストは破棄され、新しいリストで置き換わります。「+=」形式の代入の場合、既存のリストの末尾に新しいリストを連結します。

デフォルトでは、リンカーは次の順序でセグメントを順序付けします。

  1. アドレスによって並べ替えられた、LOAD_SEGMENT 指令の VADDR 属性を使用してアドレスを明示した読み込み可能セグメント。

  2. SEGMENT_ORDER 指令を使用して、指定された順序で並べ替えられたセグメント。

  3. アドレスが明示されていない読み込み可能セグメントで、SEGMENT_ORDER リストに見つからないもの。

  4. アドレスが明示されていない注釈セグメントで、SEGMENT_ORDER リストに見つからないもの。

  5. アドレスが明示されていないヌルセグメントで、SEGMENT_ORDER リストに見つからないもの。


注 - ELF には、整形オブジェクトが従う必要がある暗黙の規約があります。

mapfile を使用すると、これらの要件に違反するオブジェクトを作成できます。そのようなオブジェクトの実行結果は定義されていないため、この操作は回避する必要があります。


HDR_NOALLOC 指令が指定されないかぎり、リンカーは、最初のセグメントが注釈セグメントやヌルセグメントでなく、読み込み可能セグメントであるという要件を強制します。HDR_NOALLOC は 「ユーザーランド」のオブジェクト用に使用できないため、あまり実用的ではありません。この機能はオペレーティングシステムのカーネルを構築するときに使用されます。

STACK 指令

STACK 指令はプロセススタックの属性を指定します。

        STACK {
                FLAGS  = segment_flags...;
                FLAGS += segment_flags...;
                FLAGS -= segment_flags...;
};

FLAGS 属性は、表 9-3 に記載されている任意の値で構成される空白区切りのリストで、セグメントのアクセス権を指定します。

3 つの形式を使用できます。シンプルな「=」代入演算子は現在のフラグを新しいセットで置き換え、「+=」形式は既存のセットに新規フラグを追加し、「-=」形式は指定されたフラグを既存のセットから削除します。

デフォルトのスタックアクセス権はプラットフォーム ABI によって定義され、プラットフォームによって異なります。ターゲットプラットフォームの値はセグメントフラグ名 STACK を使用して指定します。

一部のプラットフォームでは、デフォルトのアクセス権に EXECUTE を含めることが ABI によって要求されます。EXECUTE が必要とされることはほとんどなく、一般的には潜在的なセキュリティーリスクと見なされます。EXECUTE アクセス権をスタックから削除することをお勧めします。

        STACK {
                FLAGS -= EXECUTE;
        };

STACK 指令は出力 ELF オブジェクト内の PT_SUNWSTACK プログラムヘッダーエントリに反映されます。

STUB_OBJECT 指令

STUB_OBJECT 指令は、mapfile によって記述されたオブジェクトがスタブオブジェクトとして作成できることをリンカーに通知します。

        STUB_OBJECT;

スタブ共有オブジェクトは、コマンド行で指定された mapfile 内の情報から完全に作成されます。スタブオブジェクトを作成するために -z stub オプションを指定する場合、STUB_OBJECT 指令が mapfile に存在することが必須で、リンカーはシンボルの ASSERT 属性内の情報を使用して、実オブジェクトのシンボルと一致する大域シンボルを作成します。

SYMBOL_SCOPE/SYMBOL_VERSION 指令

SYMBOL_SCOPE および SYMBOL_VERSION 指令は、大域シンボルのスコープと属性を指定するために使用されます。SYMBOL_SCOPE は、命名されていないベースシンボルバージョンのコンテキストで動作し、SYMBOL_VERSION は、明示的に命名された大域バージョンにシンボルを収集するために使用されます。SYMBOL_VERSION 指令を使用すると、下位互換性を保ちながらオブジェクトの進化をサポートできる安定したインタフェースを作成できます。

SYMBOL_VERSION の構文は次のとおりです。

        SYMBOL_VERSION version_name {
            symbol_scope:
                *;

                symbol_name;
                symbol_name {
                        ASSERT = {
                                ALIAS = symbol_name;
                                BINDING = symbol_binding;
                                TYPE = symbol_type;
 
                                SIZE = size_value;
                                SIZE = size_value[count];
                        };
                        AUXILIARY = soname;
                        FILTER = soname;
                        FLAGS = symbol_flags...;
 
                        SIZE = size_value;
                        SIZE = size_value[count];
 
                        TYPE = symbol_type;
                        VALUE = value;
                };
        } [inherited_version_name...];

SYMBOL_SCOPE はバージョン名を受け入れませんが、それ以外は同一です。

        SYMBOL_SCOPE {
                ...
        };

SYMBOL_VERSION 指令では、version_name がこの一連のシンボル定義のラベルを提供します。このラベルは、出力オブジェクト内のバージョン定義を指定します。1 つ以上の継承されたバージョン (inherited_version_name) を空白区切りで指定できます。この場合、新しく定義されたバージョンは、指定されたバージョンを継承します。第 5 章アプリケーションバイナリインタフェースとバージョン管理を参照してください。

symbol_scopeSYMBOL_SCOPE または SYMBOL_VERSION 指令内でシンボルのスコープを定義します。デフォルトでは、シンボルは大域スコープを持つものと想定されます。これは symbol_scope の後ろにコロン (:) を付けて指定することによって変更できます。これらの行は、後続のスコープ宣言によって変更されるまで、後に続くすべてのシンボルのシンボルスコープを決定します。可能性のあるスコープ値と意味を、次の表に示します。

表 9-8 シンボルのスコープのタイプ

スコープ
意味
default/global
このスコープの大域シンボルは、すべての外部オブジェクトに対して可視となります。このタイプのシンボルに対するオブジェクト内からの参照は実行時に結合されるため、介入が可能となります。この可視性スコープがデフォルトになりますが、これは、ほかのシンボル可視性テクニックを使って降格または削除することができます。このスコープ定義には、シンボルに STV_DEFAULT 可視性が指定された場合と同じ効果があります。表 7-20 を参照してください。
hidden/local
このスコープの大域シンボルは、ローカル結合を持つシンボルに縮小されます。このスコープのシンボルは、ほかの外部オブジェクトから見えません。このスコープ定義には、シンボルに STV_HIDDEN 可視性が指定された場合と同じ効果があります。表 7-20 を参照してください。
protected/symbolic
このスコープの大域シンボルは、すべての外部オブジェクトに対して可視となります。これらのシンボルに対するオブジェクト内からの参照はリンク編集時に結合されるため、実行時の介入は防止されます。この可視性スコープは、ほかのシンボル可視性テクニックを使って降格または削除することができます。このスコープ定義には、シンボルに STV_PROTECTED 可視性が指定された場合と同じ効果があります。表 7-20 を参照してください。
exported
このスコープの大域シンボルは、すべての外部オブジェクトに対して可視となります。このタイプのシンボルに対するオブジェクト内からの参照は実行時に結合されるため、介入が可能となります。ほかのどのようなシンボル可視性テクニックを使っても、このシンボル可視性を降格または削除することはできません。このスコープ定義には、シンボルに STV_EXPORTED 可視性が指定された場合と同じ効果があります。表 7-20 を参照してください。
singleton
このスコープの大域シンボルは、すべての外部オブジェクトに対して可視となります。オブジェクト内からそのようなシンボルへの参照は実行時にバインドされるので、シンボルの 1 つのインスタンスだけがプロセス内のすべての参照にバインドされます。ほかのどのようなシンボル可視性テクニックを使っても、このシンボル可視性を降格または削除することはできません。このスコープ定義には、シンボルに STV_SINGLETON 可視性が指定された場合と同じ効果があります。表 7-20 を参照してください。
eliminate
このスコープの大域シンボルは不可視です。これらのシンボルテーブルのエントリは削除されます。このスコープ定義には、シンボルに STV_ELIMINATE 可視性が指定された場合と同じ効果があります。表 7-20 を参照してください。リンカーの -z redlocsym オプションを使用して、ローカルシンボルを削除することもできます。

symbol_name はシンボルの名前です。この名前により、修飾属性に応じて、シンボル定義またはシンボル参照が生成されます。修飾属性のないもっとも簡潔な形式で、シンボル参照が作成されます。この参照は、-u オプションを使用した追加シンボルの定義」で説明した -u オプションを使用して生成する参照とまったく同じものです。 通常、このシンボル名に修飾属性が付いている場合には、シンボル定義は、関連する属性を使用して生成されます。

local スコープが定義された場合、シンボル名を特別な「*」自動縮小 (auto-reduction) 指令として定義できます。可視性が明示的に定義されていないシンボルは、生成される動的オブジェクト内のローカル結合に降格されます。明示的な可視性の定義は、mapfile 定義、再配置可能オブジェクト内にカプセル化された可視性定義のいずれかに起因します。同様に、eliminate スコープが定義された場合、シンボル名を特別な「*」自動削除 (auto-elimination) 指令として定義できます。可視性が明示的に定義されていないシンボルは、生成される動的オブジェクトから削除されます。

SYMBOL_VERSION 指令が指定されるか、SYMBOL_VERSION または SYMBOL_SCOPE のいずれかで自動縮小が指定された場合、作成されるイメージにバージョン情報が記録されます。このイメージが実行可能プログラムまたは共有オブジェクトである場合には、シンボル縮小も適用されます。

作成されるイメージが再配置可能オブジェクトである場合は、デフォルトにより、シンボル縮小は適用されません。この場合、シンボル縮小はバージョン情報の一部として記録されます。これらの縮小は、再配置可能オブジェクトが最終的に実行可能ファイルまたは共有オブジェクトの生成に使用されるときに適用されます。リンカーの -B reduce オプションを使用すると、再配置可能オブジェクトを生成するときに、強制的にシンボル縮小を実行できます。

バージョン情報の詳細については、第 5 章アプリケーションバイナリインタフェースとバージョン管理に記載されています。


注 - インタフェース定義を確実に安定させるためには、シンボル名の定義に対しワイルドカードによる拡張を行わないようにします。


シンボルをバージョンに割り当てたり、そのスコープを指定したり、またはその両方を行うには、symbol_name 自体をリストすると簡単です。オプションのシンボル属性は {} 括弧内で指定できます。有効な属性を次に示します。

ASSERT 属性

ASSERT 属性は、シンボルの予期される特性を指定するために使用されます。リンカーは、リンク編集で得られたシンボル特性と、ASSERT 属性によって指定されたシンボル特性を比較します。表明された属性と実際の属性が一致しない場合、重大なエラーが発生し、出力オブジェクトは作成されません。

ASSERT 属性の解釈は、STUB_OBJECT 指令または -z stub コマンド行オプションが使用されるかどうかによって異なります。次の 3 つの場合が考えられます。

  1. STUB_OBJECT 指令を使用しない場合、ASSERT 属性は不要です。ただし、ASSERT 属性が存在する場合、属性はリンク編集で収集された実際の値に対して検証されます。いずれかの ASSERT 属性が、関連付けられている実際の値と一致しない場合、リンク編集はエラーで終了します。

  2. STUB_OBJECT 指令が使用され、-z stub コマンド行オプションが指定された場合、リンカーは ASSERT 指令を使用して、オブジェクトによって提供される大域シンボルの属性を定義します。「スタブオブジェクト」を参照してください。

  3. STUB_OBJECT 指令が使用され、-z stub コマンド行オプションが指定されない場合、リンカーは、結果として生成されるオブジェクト内のすべての大域データが、対応する ASSERT 指令を持つことを要求します。この指令では、大域データをデータとして宣言し、サイズを指定する必要があります。このモードで、TYPE ASSERT 属性が指定されない場合、GLOBAL が想定されます。同様に、SH_ATTR が指定されない場合、デフォルト値 BITS が想定されます。これらのデフォルト値によって、スタブと実オブジェクトのデータ属性が互換性を持つことが保証されます。結果の ASSERT ステートメントは、上記の最初の場合と同じ方法で評価されます。「STUB_OBJECT 指令」を参照してください。

ASSERT は次を受け入れます。

表 9-9 SH_ATTR の値

セクション属性
意味
BITS
セクションのタイプは SHT_NOBITS ではありません
NOBITS
セクションのタイプは SHT_NOBITS です

AUXILIARY 属性

このシンボルが共有オブジェクト名 (soname) の補助フィルタであることを示します。「補助フィルタの生成」を参照してください。

FILTER 属性

このシンボルが共有オブジェクト名 (name) のフィルタであることを示します。「標準フィルタの生成」を参照してください。フィルタシンボルは、入力再配置可能オブジェクトから提供される補助実装を必要としません。したがって、シンボルの種類を定義してこの指令を使用し、絶対シンボルテーブルエントリを作成します。

FLAGS 属性

symbol_flags は、次の値が 1 つ以上含まれる空白区切りリストとしてシンボル属性を指定します。

表 9-10 シンボルフラグの値

フラグ
意味
DIRECT
このシンボルを直接結合する必要があることを示します。このキーワードをシンボル定義で使用すると、参照が、構築中のオブジェクト内から定義に直接結合されます。このフラグをシンボル参照で使用すると、定義を提供する依存関係に直接結合されます。付録 D 直接結合を参照してください。このフラグを PARENT フラグとともに使用すると、実行時に任意の親への直接結合を確立することもできます。
DYNSORT
このシンボルをソートセクションに取り込むべきであることを示します。「シンボルソートセクション」を参照してください。シンボルタイプは STT_FUNCSTT_OBJECTSTT_COMMONSTT_TLS のいずれかである必要があります。
EXTERN
シンボルが、作成されるオブジェクトの外部で定義されていることを示します。通常、このキーワードは、コールバックルーチンへのラベル付けで定義されます。このフラグによって、-z defs オプションで示される未定義シンボルが抑制されます。このフラグは、シンボル参照を生成する場合にのみ有効です。このシンボルの定義が、リンク編集時に結合されるオブジェクト内部で生成された場合には、暗黙的に無視されます。
INTERPOSE
このシンボルは割り込み処理として機能することを示します。このフラグは、動的実行可能ファイルを生成するときにだけ使用できます。このフラグは、割り込みシンボルを定義する際に、-z interpose オプションを使用したときよりも詳細な制御を提供します。
NODIRECT
このシンボルを直接結合してはならないことを示します。この状態は、作成されるオブジェクト内からの参照と外部参照に適用されます。付録 D 直接結合を参照してください。このフラグを PARENT フラグとともに使用すると、実行時に任意の親への直接結合を回避することもできます。
NODYNSORT
このシンボルをソートセクションに含めてはならないことを示します。「シンボルソートセクション」を参照してください。
PARENT
シンボルが、作成中のオブジェクトの親で定義されていることを示します。親とは、実行時にこのオブジェクトを明示的な依存関係として参照するオブジェクトです。親は、dlopen(3C) を使用して、このオブジェクトを実行時に参照することもできます。このフラグは通常、コールバックルーチンへのラベル付けで定義されます。このフラグを DIRECT または NODIRECT フラグとともに使用すると、親への直接的または間接的な参照を個別に確立することもできます。このフラグによって、-z defs オプションで示される未定義シンボルが抑制されます。このフラグは、シンボル参照を生成する場合にのみ有効です。このシンボルの定義が、リンク編集時に結合されるオブジェクト内部で生成された場合には、暗黙的に無視されます。

SIZE 属性

サイズ属性を設定します。この属性により、シンボル定義が作成されます。

size_value 引数には、数値またはシンボリック名 addrsize を指定できます。addrsize はメモリーアドレスを保持できるマシンワードのサイズを表します。リンカーは addrsize に対し、32 ビットオブジェクトを作成するときは値 4 を、64 ビットオブジェクトを構築するときは値 8 を代入します。addrsize は、条件付き入力の使用を必要としないで 32 ビットおよび 64 ビットオブジェクトに合わせて自動的に調節されるため、ポインタ変数および C 変数の long 型のサイズを表す際に使用すると便利です。

size_value 引数にはオプションで count 値を角括弧で囲んで接尾辞として追加できます。count が存在する場合、size_valuecount が掛け合わされて最終的なサイズの値が取得されます。

TYPE 属性

シンボルのタイプ属性です。この属性は、COMMON DATA、または FUNCTION のいずれかです。COMMON を指定すると、一時的なシンボル定義になります。DATA および FUNCTION を指定すると、セクションシンボル定義または絶対的なシンボル定義になります。「シンボルテーブルセクション」を参照してください。

データ属性を指定すると、OBJT シンボルが作成されます。サイズを指定し値を指定しないデータ属性を指定すると、セクションシンボルが ELF セクションに関連付けられて作成されます。このセクションは、ゼロで埋められます。関数属性を指定すると、FUNC シンボルが作成されます。

サイズを指定し値を指定しない関数属性を指定すると、セクションシンボルが ELF セクションに関連付けられて作成されます。このセクションには、リンカーによって生成される void 関数が、次のシグニチャーを使用して割り当てられます。

        void (*)(void)

値が指定されたデータまたは関数属性を指定すると、絶対値を表す ABS セクションインデックスを伴う適切なシンボルタイプが生成されます。

セクションデータシンボルの作成は、フィルタの作成時に役立ちます。実行可能ファイルからフィルタのセクションデータシンボルへの外部参照により、生成中のコピーが適切に再配置されます。「コピー再配置」を参照してください。

VALUE 属性

値の属性を示します。この属性により、シンボル定義が作成されます。