GNU/Linux >> Linux の 問題 >  >> Linux

Linux AMD64 で fs/gs レジスタはどのように使用されますか?

では、GS の用途は何ですか?

x86_64 Linux カーネルは、システム コール用のカーネル空間スタックを効率的に取得する方法として GS レジスタを使用します。

GS レジスタは、CPU ごとの領域のベース アドレスを格納します。カーネル空間スタックを取得するには、entry_SYSCALL_64 で

movq    PER_CPU_VAR(cpu_current_top_of_stack), %rsp

PER_CPU_VAR を展開すると、次のようになります:

movq    %gs:cpu_current_top_of_stack, %rsp

実際に fs:0 に答えるには 質問:x86_64 ABI では fs:0 が必要です fs が「指す」アドレスを含む 自体。つまり、fs:-4 fs:0 - 4 に保存されている値をロードします . fs が指すアドレスを簡単に取得できないため、この機能が必要です。 カーネルコードを介さずに。アドレスを fs:0 に格納する したがって、スレッド ローカル ストレージの操作がはるかに効率的になります。

スレッド ローカル変数のアドレスを取得すると、この動作を確認できます。

static __thread int test = 0;

int *f(void) {
    return &test;
}

int g(void) {
    return test;
}

にコンパイル

f:
    movq    %fs:0, %rax
    leaq    -4(%rax), %rax
    retq

g:
    movl    %fs:-4, %eax
    retq

i686 は同じことを行いますが、%gs を使用します . aarch64 では、アドレスは tls レジスタ自体から読み取ることができるため、これは必要ありません。


x86-64 には 3 つの TLS エントリがあり、そのうちの 2 つは FS と GS を介してアクセスできます。FS は glibc によって内部的に使用されます (IA32 では明らかに FS は Wine によって使用され、GS は glibc によって使用されます)。

glibc は TLS エントリ ポイントを struct pthread にします スレッド化のための内部構造が含まれています。 glibc は通常 struct pthread を参照します。 pd の変数 、おそらく pthread 記述子 .

x86-64 では、struct pthread tcbhead_t で始まる (これはアーキテクチャに依存します。マクロ TLS_DTV_AT_TP を参照してください) と TLS_TCB_AT_TP )。このスレッド制御ブロック ヘッダー、AFAIU には、スレッドが 1 つしかない場合でも必要なフィールドがいくつか含まれています。 DTV は動的スレッド ベクトルであり、dlopen() を介してロードされた DSO の TLS ブロックへのポインタが含まれています。 . TCB の前後には、(プログラムの) ロード時にリンクされた実行可能ファイルと DSO 用の静的 TLS ブロックがあります。 TCB と DTV については、Ulrich Drepper の TLS ドキュメントでかなり詳しく説明されています (第 3 章の図を参照してください)。


Linux
  1. Linux –システムに搭載されているハードディスクを確認する方法は?

  2. Linux:デバイスに使用されているデバイスドライバーを見つける方法は?

  3. Linux で MAC アドレスを恒久的に変更する方法

  1. 最もよく使用されている Linux コマンドを確認するにはどうすればよいですか?

  2. Linux カーネルで使用されるエントロピー ソースは何ですか?

  3. Linux でゲートウェイ IP アドレスを見つける方法

  1. Linuxがメインフレームに登場した経緯

  2. Linux – Linuxカーネルで使用されているエントロピーソースは何ですか?

  3. Linux カーネルが使用するキャッシュを消去する方法