このコードシーケンスはもっとも一般的であり、共有オブジェクトと動的実行可能ファイルのどちらでも使用できます。このコードシーケンスは、共有オブジェクト内および動的実行可能ファイル内の外部 TLS 変数を参照できます。
表 8–8 x86: General Dynamic スレッド固有変数のアクセスコード
コードシーケンス |
初期の再配置 |
シンボル |
---|---|---|
0x00 leal x@tlsgd(,%ebx,1),%eax 0x07 call x@tlsgdplt # %eax - TLS 変数のアドレスが含まれる |
R_386_TLS_GD R_386_TLS_GD_PLT |
x x |
未処理の再配置 |
シンボル |
|
---|---|---|
GOT[n] GOT[n + 1] |
R_386_TLS_DTPMOD32 R_386_TLS_DTPOFF32 |
x |
leal 命令は R_386_TLS_GD 再配置を生成します。この再配置は、変数 x の TLS_index 構造体を保持する領域を大域オフセットテーブル内に割り当てるよう、リンカーに指示します。リンカーは、この新しい GOT エントリに、GOT からの相対オフセットを代入することによって、この再配置を処理します。
読み込みオブジェクトインデックスと x の TLS ブロックインデックスは実行時まで不明なため、リンカーは、実行時リンカーによって処理されるように、GOT に対して R_386_TLS_DTPMOD32 再配置と R_386_TLS_DTPOFF32 再配置を設定します。生成された GOT エントリのアドレスは、___tls_get_addr() 呼び出しのためにレジスタ %eax に読み込まれます。
call 命令は、R_386_TLS_GD_PLT 再配置を生成します。この再配置は、___tls_get_addr () 関数の呼び出しを結合するようリンカーに指示し、call 命令を GD コードシーケンスに関連付けます。
call 命令は、leal 命令の直後に配置する必要があります。これは、コード変換を可能にするために必要です。