GNU/Linux >> Tutoriels Linux >  >> Linux

Comment les registres fs/gs sont-ils utilisés dans Linux AMD64 ?

A quoi sert alors GS ?

x86_64 Le noyau Linux utilise le registre GS comme moyen efficace d'acquérir la pile d'espace du noyau pour les appels système.

Le registre GS stocke l'adresse de base pour la zone par processeur. Pour acquérir la pile d'espace du noyau, dans entry_SYSCALL_64

movq    PER_CPU_VAR(cpu_current_top_of_stack), %rsp

Après avoir développé PER_CPU_VAR, nous obtenons ce qui suit :

movq    %gs:cpu_current_top_of_stack, %rsp

Pour répondre réellement à votre fs:0 question :L'ABI x86_64 nécessite que fs:0 contient l'adresse "pointée" par fs lui-même. C'est-à-dire fs:-4 charge la valeur stockée à fs:0 - 4 . Cette fonctionnalité est nécessaire car vous ne pouvez pas facilement obtenir l'adresse pointée par fs sans passer par le code du noyau. Avoir l'adresse stockée à fs:0 rend ainsi le travail avec le stockage local des threads beaucoup plus efficace.

Vous pouvez le voir en action lorsque vous prenez l'adresse d'une variable locale de thread :

static __thread int test = 0;

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

int g(void) {
    return test;
}

compile vers

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

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

i686 fait la même chose mais avec %gs . Sur aarch64, ce n'est pas nécessaire car l'adresse peut être lue à partir du registre tls lui-même.


Dans x86-64, il y a 3 entrées TLS, dont deux accessibles via FS et GS, FS est utilisé en interne par la glibc (dans IA32, apparemment FS est utilisé par Wine et GS par la glibc).

Glibc fait de son point d'entrée TLS un struct pthread qui contient des structures internes pour le filetage. Glibc fait généralement référence à un struct pthread variable comme pd , vraisemblablement pour descripteur pthread .

Sur x86-64, struct pthread commence par un tcbhead_t (cela dépend de l'architecture, voir les macros TLS_DTV_AT_TP et TLS_TCB_AT_TP ). Cet en-tête de bloc de contrôle de thread, AFAIU, contient certains champs qui sont nécessaires même lorsqu'il n'y a qu'un seul thread. Le DTV est le vecteur de thread dynamique et contient des pointeurs vers des blocs TLS pour les DSO chargés via dlopen() . Avant ou après le TCB, il y a un bloc TLS statique pour l'exécutable et les DSO liés au moment du chargement (du programme). Le TCB et le DTV sont assez bien expliqués dans le document TLS d'Ulrich Drepper (recherchez les schémas au chapitre 3).


Linux
  1. Comment Linux est arrivé sur le mainframe

  2. Linux - Quelles sources d'entropie sont utilisées par le noyau Linux ?

  3. Sous Linux, comment savoir combien de cœurs de la machine sont actifs ?

  4. Quelles sources d'entropie sont utilisées par le noyau Linux ?

  5. Comment trouver l'adresse IP de la passerelle sous Linux

Comment trouver une adresse IP dans Kali Linux

Comment trouver une adresse IP sous Linux

Comment changer l'adresse MAC sous Linux

Comment changer l'adresse IP sous Linux

Comment obtenir votre adresse IP sous Linux

comment générer une adresse MAC aléatoire à partir de la ligne de commande Linux