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

ドキュメントの情報

はじめに

パート I リンカーおよび実行時リンカーの使用

1.  Oracle Solaris リンカーの紹介

2.  リンカー

3.  実行時リンカー

4.  共有オブジェクト

5.  インタフェースおよびバージョン管理

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

パート II クイックリファレンス

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

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

パート III 詳細情報

9.  直接結合

10.  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 指令

11.  拡張性メカニズム

パート IV ELF アプリケーションバイナリインタフェース

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

13.  プログラムの読み込みと動的リンク

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

パート V 付録

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

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

索引

mapfile の構造と構文

mapfile 指令は複数の行に渡ることができ、改行を含む空白文字を任意の数だけ含めることができます。

すべての構文説明について、次の表記が適用されます。

表 10-1 二重引用符テキストのエスケープシーケンス

エスケープシーケンス
意味
\a
警告 (ベル)
\b
バックスペース
\f
用紙送り
\n
改行
\r
return
\t
水平タブ
\v
垂直タブ
\\
バックスラッシュ
\'
単一引用符
\”
二重引用符
\ooo
8 進数の定数で、ooo は 1 つから 3 つまでの 8 進数 (0...7) です

表 10-2 mapfile 内で一般的に使用される名前およびその他の文字列

名前
目的
segment_name
ELF セグメントの名前
section_name
ELF セクションの名前
symbol_name
ELF シンボルの名前
file_path
ELF オブジェクトまたは ELF オブジェクトを含むアーカイブを参照するために使用される、スラッシュ (/) で区切られた複数の名前から構成される UNIX のファイルパス
file_basename
file_path の最後のコンポーネント (basename(1))
objname
file_basename、またはアーカイブ内に含まれているオブジェクトの名前
soname
共有可能オブジェクトの SONAME に使用される共有可能オブジェクト名 (libc.so.1 など)
version_name
ELF バージョン管理セクション内で使用されるシンボルバージョンの名前
inherited_version_name
別のシンボルバージョンによって継承されたシンボルバージョンの名前

表 10-3 セグメントフラグ

フラグの値
意味
READ
セグメントは読み込み可能です
WRITE
セグメントは書き込み可能です
EXECUTE
セグメントは実行可能です
0
すべてのアクセス権フラグがクリアされます
DATA
ターゲットプラットフォーム上のデータセグメントに適した READ、WRITE、および EXECUTE フラグの組み合わせ
STACK
プラットフォーム ABI によって定義される、ターゲットプラットフォームに適した READ、WRITE、および EXECUTE フラグの組み合わせ

mapfile のバージョン

コメントまたは空白でない mapfile 内の先頭行には、mapfile のバージョン宣言が期待されます。この宣言によって、ファイルの残りの部分で使用される mapfile 言語のバージョンが確立されます。このマニュアルに記載されている mapfile 言語はバージョン 2 です。

        $mapfile_version 2

バージョン宣言で開始されない mapfile は、AT&T によって System V Release 4 Unix (SVR4) 用に定義されたオリジナルの mapfile 言語で記述されていると見なされます。リンカーはこのような mapfile を処理する能力を保持しています。この構文は、付録 B System V Release 4 (バージョン 1) Mapfileに記載されています。

条件付き入力

mapfile 内の行は、特定の ELFCLASS (32 ビットまたは 64 ビット) あるいは機械タイプにのみ適用されるように条件付けできます。

        $if expr
        ...
        [$elif expr]
        ...
        [$else]
        ...
        $endif

条件付き入力式は、論理的な true または false の値に評価されます。それぞれの指令 ($if$elif$else、および $endif) は 1 行に 1 つ記述します。$if 行と後続の $elif 行の中の式は、true と評価される式が見つかるまで順番に評価されます。false の値を持つ行に続くテキストは、破棄されます。true の指令の行に続くテキストは、通常どおり処理されます。この説明のテキストとは、条件文の一部でない任意の内容を表します。true となる $if または $elif が見つかり、そのテキストが処理されると、後続の $elif および $else 行に加え、それらのテキストも破棄されます。すべての式がゼロで、$else がある場合、$else に続くテキストが通常どおり処理されます。

$if 指令の範囲は、複数の mapfile を超えることはできません。$if 指令は、$if 指令を使用する mapfile 内で、対応する $endif によって終了する必要があり、終了しない場合はリンカーはエラーを生成します。

リンカーは、$if および $elif によって評価される論理式に使用できる名前の内部テーブルを保持します。このテーブルは起動時に、次の表内のそれぞれの名前で初期化され、作成中の出力オブジェクトに適用されます。

表 10-4 定義済みの条件式の名前

名前
意味
_ELF32
32 ビットオブジェクト
_ELF64
64 ビットオブジェクト
_ET_DYN
共有オブジェクトファイル
_ET_EXEC
実行可能オブジェクト
_ET_REL
再配置可能オブジェクト
_sparc
SPARC マシン (32 ビットまたは 64 ビット)
_x86
x86 マシン (32 ビットまたは 64 ビット)
true
常に定義済み

名前は大文字と小文字を区別して、示されたとおりの名前を使用する必要があります。たとえば、true は定義されていますが、TRUE は定義されていません。これらのすべての名前は、それ自体を論理式として使用できます。次に例を示します。

        $if _ELF64
        ...
        $endif

出力オブジェクトが 64 ビットの場合、この例は true に評価され、リンカーは囲まれたテキストを処理します。これらの論理式では数値は許可されませんが、特殊な例外として、値 1true に評価され、0false に評価されます。

未定義のすべての名前は false に評価されます。一般的に、無条件にスキップする必要がある入力行を指定するために、未定義の名前 false を使用します。

        $if false
        ...
        $endif

次の表に示す演算子を使用すると、さらに複雑な論理式を記述できます。

表 10-5 条件式の演算子

演算子
意味
&&
論理積
||
論理和
( 式 )
式の一部
!
後続の式のブール値を否定します

式は左から右に評価されます。式の一部は、それを囲む式の前に評価されます。

たとえば、x86 プラットフォーム用の 64 ビットオブジェクトを構築するとき、次の構造構文が評価されます。

        $if _ELF64 && _x86
        ...
        $endif

$add 指令を使用すると、リンカーの既知の名前テーブルに新しい名前を追加できます。前の例を使用すると、$if 指令を簡素化するために、64 ビット x86 オブジェクトを表す amd64 という名前を定義すると便利な場合もあります。

        $if _ELF64 && _x86
        $add amd64
        $endif

これを使用すると、前の例を簡素化できます。

        $if amd64
        ...
        $endif

リンカーの -z mapfile-add オプションを使用することによって、リンカーの既知の名前のテーブルに新しい名前を追加することもできます。このオプションは、使用中のコンパイラなどの外部環境の属性に基づいて、mapfile 入力を条件的に有効にする必要がある場合に役立ちます。

$clear 指令は $add 指令の逆です。これは内部テーブルから名前を削除するために使用されます。

        $clear amd64

$add 指令の効果は、$add を使用する mapfile の終わりを超えて持続し、同じリンク操作内でリンカーによって処理される後続の mapfile でも使用できます。この動作を望まない場合は、$add が含まれる mapfile の最後で $clear を使用して定義を削除します。

最後に、$error 指令を使用すると、リンカーは行の残りのすべてのテキストを重大なエラーとして出力し、リンク操作を停止します。$error 指令は、プログラマがオブジェクトを新しい機械タイプに移植する際、必要な mapfile 定義が欠落した正しくないオブジェクトを暗黙のうちに構築できないようにするために使用できます。

        $if _sparc
        ...
        $elif _x86
        ...
        $else
        $error unknown machine type
        $endif

C 言語のプログラマであれば、mapfile の条件付き入力に使用される構文は、C プリプロセッサのマクロ言語の構文と似ていることがわかります。この類似性は意図的なものです。ただし、mapfile の条件付き入力の指令は、設計上、C プリプロセッサによって提供されるものよりも、ずっと機能が劣ります。クロスプラットフォーム環境でのリンク操作をサポートするために必要なもっとも基本的な機能のみが提供されます。

2 つの言語の大きな違いは次のとおりです。

高度なマクロ処理が必要な場合、m4(1) などの外部マクロプロセッサの使用を検討する必要があります。

指令の構文

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

mapfile 指令の構文は、次の一般的な形式に基づきます。

もっとも簡単な形式は、値を持たない指令の名前です。

        directive;

次の形式は、指令の名前に、値または空白区切りの値のリストが付いたものです。

        directive = value...;

示されている「=」代入演算子のほかに、「+=」および「-=」形式の代入も使用できます。「=」演算子は、指定された指令を、指定された値または値リストに設定します。「+=」演算子は、右側の値を現在の値に追加するために使用され、「-=」演算子は値を削除するために使用されます。

さらに複雑な指令では、複数の属性を {...} 括弧で囲んで、複数の属性を 1 つの単位としてグループ化して操作します。

        directive [name] {
                attribute [directive = value];
                ...
        } [name];

開き括弧 ({) の前に名前を置くことができ、指定されたステートメントの結果に名前を付けるために使用されます。同様に、閉じ括弧 (}) の後ろで終端のセミコロン (;) の前に、1 つ以上のオプションの名前を置くことができます。これらの名前は、定義される項目が、ほかの名前付き項目と関係があることを表すために使用されます。

グループ内の属性の形式は、上記で説明した同じ構文を使用します。つまり、単純な指令に、値が付いたものか、代入演算子 (=+=-=) の後に値が付いたものか、または空白区切りの値のリストが付いたもので、セミコロン (;) で終了します。

指令が持つ属性にはサブ属性を持たせることができます。そのような場合、サブ属性も階層を示すために、入れ子の {...} 括弧でグループ化されます。

        directive [name] {
                attribute {
                        subatribute [= value];
                        ...
                };
        } [name...];

mapfile 構文の文法では、入れ子が許可される深さに制限がありません。入れ子の深さは、指令の要件のみに依存します。