再配置エントリには、次の図に示す命令およびデータフィールドの変更方法が記述されます。ビット番号は、下隅に示されています。
SPARC プラットフォームの場合、再配置エントリはバイト (byte8)、ハーフワード (half16) またはワードに適用されます。
64 ビット SPARC と x64 では、再配置は拡張ワード (xword64) にも適用されます。
x86 の場合、再配置エントリはワード (word32) に適用されます。
word32 は、任意バイト整列が存在する 4 バイトを占める 32 ビットフィールドを指定します。これらの値は、x86 アーキテクチャーにおけるほかのワード値と同じバイト順序を使用します。
いずれの場合でも r_offset 値は、影響が与えられる領域の先頭バイトのオフセットまたは仮想アドレスを指定します。再配置タイプは、変更されるビットと、これらのビットの値の計算方法を指定します。
次の再配置型の計算では、操作により、再配置可能ファイルが実行可能ファイルまたは共有オブジェクトファイルに変換されることが仮定されています。概念上、リンカーは 1 つまたは複数の再配置可能ファイルを併合して出力します。リンカーは、まず入力ファイルの結合/配置方法を決めます。次に、シンボルの値を更新し、再配置を実行します。実行可能オブジェクトファイルと共有オブジェクトファイルに適用される再配置は類似しており、同じ結果を実現します。このセクションの表では、次の表記が使用されています。
再配置可能フィールドの値を計算するために使用される加数。
実行時に共有オブジェクトがメモリーに読み込まれるベースアドレス。一般的に、共有オブジェクトファイルは、ベース仮想アドレス 0 で作成されます。ただし、共有オブジェクトの実行アドレスは異なります。「プログラムヘッダー」を参照してください。
実行時に再配置エントリのシンボルのアドレスが存在する大域オフセットテーブルへのオフセット。「大域オフセットテーブル (プロセッサ固有)」を参照してください。
大域オフセットテーブルのアドレス。「大域オフセットテーブル (プロセッサ固有)」を参照してください。
シンボルに対するプロシージャーのリンクテーブルエントリのセクションオフセットまたはアドレス。「プロシージャーのリンクテーブル (プロセッサ固有)」を参照してください。
再配置される領域のセクションオフセットまたはアドレス (r_offset を使用して計算)。
インデックスが再配置エントリ内に存在するシンボルの値。
インデックスが再配置エントリ内に存在するシンボルのサイズ。
次の表に示すフィールド名は、再配置型がオーバーフローを検査するかどうかを通知します。計算される再配置値は意図したフィールドより大きい場合があり、再配置型によっては値の適合を検証 (V) したり結果を切り捨てたり (T) することがあります。たとえば、V-simm13 は、計算された値が simm13 フィールドの外部に 0 以外の有意ビットを持つことがないことを意味します。
表 7–13 SPARC: ELF 再配置型
名前 |
値 |
フィールド |
計算 |
---|---|---|---|
R_SPARC_NONE |
0 |
None |
None |
R_SPARC_8 |
1 |
V-byte8 |
S + A |
R_SPARC_16 |
2 |
V-half16 |
S + A |
R_SPARC_32 |
3 |
V-word32 |
S + A |
R_SPARC_DISP8 |
4 |
V-byte8 |
S + A - P |
R_SPARC_DISP16 |
5 |
V-half16 |
S + A - P |
R_SPARC_DISP32 |
6 |
V-disp32 |
S + A - P |
R_SPARC_WDISP30 |
7 |
V-disp30 |
(S + A - P) >> 2 |
R_SPARC_WDISP22 |
8 |
V-disp22 |
(S + A - P) >> 2 |
R_SPARC_HI22 |
9 |
T-imm22 |
(S + A) >> 10 |
R_SPARC_22 |
10 |
V-imm22 |
S + A |
R_SPARC_13 |
11 |
V-simm13 |
S + A |
R_SPARC_LO10 |
12 |
T-simm13 |
(S + A) & 0x3ff |
R_SPARC_GOT10 |
13 |
T-simm13 |
G & 0x3ff |
R_SPARC_GOT13 |
14 |
V-simm13 |
G |
R_SPARC_GOT22 |
15 |
T-simm22 |
G >> 10 |
R_SPARC_PC10 |
16 |
T-simm13 |
(S + A - P) & 0x3ff |
R_SPARC_PC22 |
17 |
V-disp22 |
(S + A - P) >> 10 |
R_SPARC_WPLT30 |
18 |
V-disp30 |
(L + A - P) >> 2 |
R_SPARC_COPY |
19 |
None |
この表のあとの説明を参照してください。 |
R_SPARC_GLOB_DAT |
20 |
V-word32 |
S + A |
R_SPARC_JMP_SLOT |
21 |
None |
この表のあとの説明を参照してください。 |
R_SPARC_RELATIVE |
22 |
V-word32 |
B + A |
R_SPARC_UA32 |
23 |
V-word32 |
S + A |
R_SPARC_PLT32 |
24 |
V-word32 |
L + A |
R_SPARC_HIPLT22 |
25 |
T-imm22 |
(L + A) >> 10 |
R_SPARC_LOPLT10 |
26 |
T-simm13 |
(L + A) & 0x3ff |
R_SPARC_PCPLT32 |
27 |
V-word32 |
L + A - P |
R_SPARC_PCPLT22 |
28 |
V-disp22 |
(L + A - P) >> 10 |
R_SPARC_PCPLT10 |
29 |
V-simm13 |
(L + A - P) & 0x3ff |
R_SPARC_10 |
30 |
V-simm10 |
S + A |
R_SPARC_11 |
31 |
V-simm11 |
S + A |
R_SPARC_HH22 |
34 |
V-imm22 |
(S + A) >> 42 |
R_SPARC_HM10 |
35 |
T-simm13 |
((S + A) >> 32) & 0x3ff |
R_SPARC_LM22 |
36 |
T-imm22 |
(S + A) >> 10 |
R_SPARC_PC_HH22 |
37 |
V-imm22 |
(S + A - P) >> 42 |
R_SPARC_PC_HM10 |
38 |
T-simm13 |
((S + A - P) >> 32) & 0x3ff |
R_SPARC_PC_LM22 |
39 |
T-imm22 |
(S + A - P) >> 10 |
R_SPARC_WDISP16 |
40 |
V-d2/disp14 |
(S + A - P) >> 2 |
R_SPARC_WDISP19 |
41 |
V-disp19 |
(S + A - P) >> 2 |
.R_SPARC_7 |
43 |
V-imm7 |
S + A |
R_SPARC_5 |
44 |
V-imm5 |
S + A |
R_SPARC_6 |
45 |
V-imm6 |
S + A |
R_SPARC_HIX22 |
48 |
V-imm22 |
((S + A) ^ 0xffffffffffffffff) >> 10 |
R_SPARC_LOX10 |
49 |
T-simm13 |
((S + A) & 0x3ff) | 0x1c00 |
R_SPARC_H44 |
50 |
V-imm22 |
(S + A) >> 22 |
R_SPARC_M44 |
51 |
T-imm10 |
((S + A) >> 12) & 0x3ff |
R_SPARC_L44 |
52 |
T-imm13 |
(S + A) & 0xfff |
R_SPARC_REGISTER |
53 |
V-word32 |
S + A |
R_SPARC_UA16 |
55 |
V-half16 |
S + A |
R_SPARC_GOTDATA_HIX22 |
80 |
T-imm22 |
((S + A - GOT) >> 10) ^ ((S + A - GOT) >> 31) |
R_SPARC_GOTDATA_LOX10 |
81 |
T-imm13 |
((S + A - GOT) & 0x3ff) | (((S + A - GOT) >> 31) & 0x1c00) |
R_SPARC_GOTDATA_OP_HIX22 |
82 |
T-imm22 |
(G >> 10) ^ (G >> 31) |
R_SPARC_GOTDATA_OP_LOX10 |
83 |
T-imm13 |
(G & 0x3ff) | ((G >> 31) & 0x1c00) |
R_SPARC_GOTDATA_OP |
84 |
Word32 |
この表のあとの説明を参照してください。 |
スレッド固有領域の参照に使用できる再配置はほかにも存在します。これらの再配置については、第 8 章スレッド固有領域 (TLS)で説明しています。
いくつかの再配置型には、単純な計算を超えたセマンティクスが存在します。
R_SPARC_LO10 に似ていますが、シンボルの GOT エントリのアドレスを参照する点が異なります。また、 R_SPARC_GOT10 は、大域オフセットテーブルの作成をリンカーに指示します。
R_SPARC_13 に似ていますが、シンボルの GOT エントリのアドレスを参照する点が異なります。また、 R_SPARC_GOT13 は、大域オフセットテーブルの作成をリンカーに指示します。
R_SPARC_22 に似ていますが、シンボルの GOT エントリのアドレスを参照する点が異なります。また、 R_SPARC_GOT22 は、大域オフセットテーブルの作成をリンカーに指示します。
R_SPARC_WDISP30 に似ていますが、シンボルのプロシージャーリンクテーブルエントリのアドレスを参照する点が異なります。また、R_SPARC_WPLT30 は、プロシージャーのリンクテーブル作成をリンカーに指示します。
リンカーは、この再配置型を作成して、動的実行可能ファイルが読み取り専用のテキストセグメントを保持できるようにします。この再配置型のオフセットメンバーは、書き込み可能セグメントの位置を参照します。シンボルテーブルインデックスは、現オブジェクトファイルと共有オブジェクトの両方に存在する必要があるシンボルを指定します。実行時、実行時リンカーは共有オブジェクトのシンボルに関連付けられているデータを、オフセットで指定されている位置にコピーします。「コピー再配置」を参照してください。
R_SPARC_32 に似ていますが、再配置は GOT エントリを指定されたシンボルのアドレスに設定する点が異なります。この特殊な再配置型を使うと、シンボルと GOT エントリの対応付けを判定できます。
リンカーは、動的オブジェクトが遅延結合を提供できるようにするため、この再配置型を作成します。この再配置型のオフセットメンバーは、プロシージャーのリンクテーブルエントリの位置を与えます。実行時リンカーは、プロシージャーのリンクテーブルエントリを変更して指定シンボルアドレスに制御を渡します。
リンカーは、動的オブジェクト用にこの再配置型を作成します。この再配置型のオフセットメンバーは、相対アドレスを表す値が存在する、共有オブジェクト内の位置を与えます。実行時リンカーは共有オブジェクトが読み込まれる仮想アドレスに相対アドレスを加算することで、対応する仮想アドレスを計算します。この型に対する再配置エントリは、シンボルテーブルインデックスに対して値 0 を指定する必要があります。
R_SPARC_32 に似ていますが、整列されていないワードを参照する点が異なります。再配置されるワードは、任意整列が存在する 4 つの別個のバイトとして処理されなければなりません (アーキテクチャーの要求に従って整列されるワードとしては処理されません)。
R_SPARC_HI22 に似ていますが、妥当性検査ではなく切り捨てを行う点が異なります。
R_SPARC_PC22に似ていますが、妥当性検査ではなく切り捨てを行う点が異なります。
64 ビットアドレス空間の最上位 4G バイトに限定される実行可能ファイルに対して R_SPARC_LOX10 とともに使用されます。R_SPARC_HI22 に似ていますが、リンク値の 1 の補数を与えます。
R_SPARC_HIX22 とともに使用されます。R_SPARC_LO10 に似ていますが、必ずリンク値のビット 10 からビット 12 までを設定します。
再配置型 R_SPARC_H44 および R_SPARC_M44 とともに使用され、44 ビット絶対アドレス指定モデルを生成します。
レジスタシンボルの初期化に使用されます。この再配置型のオフセットメンバーには、初期化されるレジスタ番号が存在します。このレジスタに対応するレジスタシンボルが必要です。このシンボルの種類は SHN_ABS です。
これらの再配置はコード変換に対応したものです。
再配置計算に使用される次の表記は、64 ビット SPARC 固有のものです。
再配置可能フィールドの値を計算するために使用される二次的な加数。この加数は、ELF64_R_TYPE_DATA マクロを適用することにより r_info フィールドから抽出されます。
次の表に示す再配置型は、32 ビット SPARC 用に定義された再配置型を拡張または変 更します。「SPARC: 再配置型」を参照してください。
表 7–14 64 ビット SPARC: ELF 再配置型
名前 |
値 |
フィールド |
計算 |
---|---|---|---|
R_SPARC_HI22 |
9 |
V-imm22 |
(S + A) >> 10 |
R_SPARC_GLOB_DAT |
20 |
V-xword64 |
S + A |
R_SPARC_RELATIVE |
22 |
V-xword64 |
B + A |
R_SPARC_64 |
32 |
V-xword64 |
S + A |
R_SPARC_OLO10 |
33 |
V-simm13 |
((S + A) & 0x3ff) + O |
R_SPARC_DISP64 |
46 |
V-xword64 |
S + A - P |
R_SPARC_PLT64 |
47 |
V-xword64 |
L + A |
R_SPARC_REGISTER |
53 |
V-xword64 |
S + A |
R_SPARC_UA64 |
54 |
V-xword64 |
S + A |
R_SPARC_H34 |
85 |
V-imm22 |
(S + A) >> 12 |
次の再配置型には、単純な計算を超えたセマンティクスが存在します。
R_SPARC_LO10 に似ていますが、符号付き13 ビット即値フィールドを十分に使用するために余分なオフセットが追加される点が異なります。
次の表に、32 ビット x86 用に定義された再配置を示します。
表 7–15 32 ビット x86: ELF 再配置型
名前 |
値 |
フィールド |
計算 |
---|---|---|---|
R_386_NONE |
0 |
None |
None |
R_386_32 |
1 |
word32 |
S + A |
R_386_PC32 |
2 |
word32 |
S + A - P |
R_386_GOT32 |
3 |
word32 |
G + A |
R_386_PLT32 |
4 |
word32 |
L + A - P |
R_386_COPY |
5 |
None |
この表のあとの説明を参照してください。 |
R_386_GLOB_DAT |
6 |
word32 |
S |
R_386_JMP_SLOT |
7 |
word32 |
S |
R_386_RELATIVE |
8 |
word32 |
B + A |
R_386_GOTOFF |
9 |
word32 |
S + A - GOT |
R_386_GOTPC |
10 |
word32 |
GOT + A - P |
R_386_32PLT |
11 |
word32 |
L + A |
R_386_16 |
20 |
word16 |
S + A |
R_386_PC16 |
21 |
word16 |
S + A - P |
R_386_8 |
22 |
word8 |
S + A |
R_386_PC8 |
23 |
word8 |
S + A - P |
スレッド固有領域の参照に使用できる再配置はほかにも存在します。これらの再配置については、第 8 章スレッド固有領域 (TLS)で説明しています。
いくつかの再配置型には、単純な計算を超えたセマンティクスが存在します。
GOT のベースからシンボルの GOT エントリまでの距離を計算します。この再配置型はまた、大域オフセットテーブルを作成するようにリンカーに指示します。
シンボルのプロシージャーのリンクテーブルエントリのアドレスを計算し、かつプロシージャーのリンクテーブルを作成するようにリンカーに指示します。
リンカーは、この再配置型を作成して、動的実行可能ファイルが読み取り専用のテキストセグメントを保持できるようにします。この再配置型のオフセットメンバーは、書き込み可能セグメントの位置を参照します。シンボルテーブルインデックスは、現オブジェクトファイルと共有オブジェクトの両方に存在する必要があるシンボルを指定します。実行時、実行時リンカーは共有オブジェクトのシンボルに関連付けられているデータを、オフセットで指定されている位置にコピーします。「コピー再配置」を参照してください。
GOT エントリを、指定されたシンボルのアドレスに設定します。この特殊な再配置型を使うと、シンボルと GOT エントリの対応付けを判定できます。
リンカーは、動的オブジェクトが遅延結合を提供できるようにするため、この再配置型を作成します。この再配置型のオフセットメンバーは、プロシージャーのリンクテーブルエントリの位置を与えます。実行時リンカーは、プロシージャーのリンクテーブルエントリを変更して指定シンボルアドレスに制御を渡します。
リンカーは、動的オブジェクト用にこの再配置型を作成します。この再配置型のオフセットメンバーは、相対アドレスを表す値が存在する、共有オブジェクト内の位置を与えます。実行時リンカーは共有オブジェクトが読み込まれる仮想アドレスに相対アドレスを加算することで、対応する仮想アドレスを計算します。この型に対する再配置エントリは、シンボルテーブルインデックスに対して値 0 を指定する必要があります。
シンボルの値と GOT のアドレスの差を計算します。この再配置型はまた、大域オフセットテーブルを作成するようにリンカーに指示します。
R_386_PC32 に似ていますが、計算を行う際に GOT のアドレスを使用する点が異なります。この再配置で参照されるシンボルは、通常 _GLOBAL_OFFSET_TABLE_ です。 この再配置型はまた、大域オフセットテーブルを作成するようにリンカーに指示します。
次の表に、x64 用に定義された再配置を示します。
表 7–16 x64: ELF 再配置型
名前 |
値 |
フィールド |
計算 |
---|---|---|---|
R_AMD64_NONE |
0 |
None |
None |
R_AMD64_64 |
1 |
word64 |
S + A |
R_AMD64_PC32 |
2 |
word32 |
S + A - P |
R_AMD64_GOT32 |
3 |
word32 |
G + A |
R_AMD64_PLT32 |
4 |
word32 |
L + A - P |
R_AMD64_COPY |
5 |
None |
この表のあとの説明を参照してください。 |
R_AMD64_GLOB_DAT |
6 |
word64 |
S |
R_AMD64_JUMP_SLOT |
7 |
word64 |
S |
R_AMD64_RELATIVE |
8 |
word64 |
B + A |
R_AMD64_GOTPCREL |
9 |
word32 |
G + GOT + A - P |
R_AMD64_32 |
10 |
word32 |
S + A |
R_AMD64_32S |
11 |
word32 |
S + A |
R_AMD64_16 |
12 |
word16 |
S + A |
R_AMD64_PC16 |
13 |
word16 |
S + A - P |
R_AMD64_8 |
14 |
word8 |
S + A |
R_AMD64_PC8 |
15 |
word8 |
S + A - P |
R_AMD64_PC64 |
24 |
word64 |
S + A - P |
R_AMD64_GOTOFF64 |
25 |
word64 |
S + A - GOT |
R_AMD64_GOTPC32 |
26 |
word32 |
GOT + A + P |
スレッド固有領域の参照に使用できる再配置はほかにも存在します。これらの再配置については、第 8 章スレッド固有領域 (TLS)で説明しています。
これらの再配置型のほとんどの特別なセマンティクスは、x86 で使用されているものと同じです。いくつかの再配置型には、単純な計算を超えたセマンティクスが存在します。
この再配置のセマンティクスは R_AMD64_GOT32 または等しい R_386_GOTPC 再配置と異なります。x64 アーキテクチャーは、命令ポインタに対して相対的なアドレス指定モードを提供します。したがって、アドレスは 1 つの命令で GOT から読み込むことができます。
R_AMD64_GOTPCREL 再配置の計算は、シンボルのアドレスを指定した GOT 内の位置と再配置を適用する位置の間の差を提供します。
計算値は 32 ビットに切り捨てられます。リンカーは、再配置のために生成された値が元の 64 ビット値にゼロ拡張されていることを確認します。
計算値は 32 ビットに切り捨てられます。リンカーは、再配置のために生成された値が元の 64 ビット値に符号拡張されていることを確認します。
これらの再配置は x64 ABI には準拠していませんが、文書化するためにここに追加しておきます。R_AMD64_8 再配置は、計算値を 8 ビットに切り詰めます。R_AMD64_16 再配置は、計算値を 16 ビットに切り詰めます。