Nios II Gen2 プロセッサー・リファレンス・ガイド

ID 683836
日付 10/28/2016
Public
ドキュメント目次

7.9.1.3. スレッドローカル・ストレージ

Nios II プロセッサーはスレッドローカル・ストレージに Variant I モデルを使用します。

スレッド・コントロール・ブロック (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