インテルのみ表示可能 — GUID: iga1409352735142
Ixiasoft
インテルのみ表示可能 — GUID: iga1409352735142
Ixiasoft
7.9.1.3. スレッドローカル・ストレージ
スレッド・コントロール・ブロック (TCB) の終わりは、スレッドポインターの前に 0x7000 バイトにあります。TCB は 8 バイト長です。最初のワードはダイナミック・スレッド・ポインター (DTV) および 2 番目のワードは予約されています。各モジュールのダイナミック・スレッド・ポインターは 0x8000 ( when retrieved using __tls_get_addrを使用して取得した場合 ) でバイアスされます。スレッド・ライブラリーは TBC の前に追加のプライベート情報を格納することができます。
GNU Linux ツールチェーンでは、GOT ポインター (_gp_got) は常にr22に保持され、スレッドポインターは常にr23に保持されます。
次の例では、__tls_get_addrの引数が常にr4に渡され、その戻り値は常にr2に返されることを除き、どのレジスターも使用できます。__tls_get_addrへの呼び出しは、PIC コードで通常の位置に依存しないコード (PIC) 呼び出し規約を使用する必要があり、つまり、これらのシーケンスは単なる例であり、コンパイラーは異なるシーケンスを生成する可能性があります。リンカー緩和は定義されていません。
一般的な動的モデル
addi r4, r22, %tls_gd(x) # R_NIOS2_TLS_GD16 x
call __tls_get_addr # R_NIOS2_CALL26 __tls_get_addr
# Address of x in r2
一般的な動的モデルでは、「一般的な動的モデルでの GOT スロット」の例で示すように、x に対して 2 ワードの GOT スロットが割り当てられます。
一般的な動的モデルでの GOT スロット
GOT[n] R_NIOS2_TLS_DTPMOD x
GOT[n+1] R_NIOS2_TLS_DTPREL x
ローカル動的モデル
addi r4, r22, %tls_ldm(x) # R_NIOS2_TLS_LDM16 x
call __tls_get_addr # R_NIOS2_CALL26 __tls_get_addr
addi r5, r2, %tls_ldo(x) # R_NIOS2_TLS_LDO16 x
# Address of x in r5
ldw r6, %tls_ldo(x2)(r2) # R_NIOS2_TLS_LDO16 x2
# Value of x2 in r6
リンクされたオブジェクト内のすべての R_NIOS2_TLS_LDM16 演算に 1 つの 2 ワード GOT スロットが割り当てられます。このオブジェクトのスレッドローカル・シンボルは、「スレッドローカル・ストレージを持つ GOT スロット」の例に示すように使用できます。
スレッドローカル・ストレージを持つ GOT スロット
GOT[n] R_NIOS2_TLS_DTPMOD x
GOT[n+1] 0
初期実行モデル
ldw r4, %tls_ie(x)(r22) # R_NIOS2_TLS_IE16 x
add r4, r23, r4
# Address of x in r4
単一 GOT スロットは、「初期実行モデルでの GOT スロット」の例で示すように、スレッドポインターからの x のオフセットを保持するために割り当てられます。
初期実行モデルでの GOT スロット
GOT[n] R_NIOS2_TLS_TPREL x
ローカル実行モデル
addi r4, r23, %tls_le(x) # R_NIOS2_TLS_LE16 x
# Address of x in r4
ローカル実行モデルに関連する GOT スロットはありません。
デバッグ情報は GNU 拡張子 DW_OP_GNU_push_tls_address を使用します。
デバッグ情報
.byte 0x03 # DW_OP_addr
.word %tls_ldo(x) # R_NIOS2_TLS_DTPREL x
.byte 0xe0 # DW_OP_GNU_push_tls_address