GNU/Linux >> Linux Esercitazione >  >> Linux

Come vengono utilizzati i registri fs/gs in Linux AMD64?

A cosa serve allora GS?

x86_64 Il kernel Linux utilizza il registro GS come un modo efficiente per acquisire lo stack dello spazio del kernel per le chiamate di sistema.

Il registro GS memorizza l'indirizzo di base per l'area per CPU. Per acquisire lo stack dello spazio del kernel, in entry_SYSCALL_64

movq    PER_CPU_VAR(cpu_current_top_of_stack), %rsp

Dopo aver espanso PER_CPU_VAR, otteniamo quanto segue:

movq    %gs:cpu_current_top_of_stack, %rsp

Per rispondere effettivamente al tuo fs:0 domanda:l'ABI x86_64 richiede che fs:0 contiene l'indirizzo "indicato" da fs si. Ovvero, fs:-4 carica il valore memorizzato in fs:0 - 4 . Questa funzione è necessaria perché non è possibile ottenere facilmente l'indirizzo indicato da fs senza passare attraverso il codice del kernel. Avere l'indirizzo memorizzato in fs:0 quindi rende il lavoro con l'archiviazione locale dei thread molto più efficiente.

Puoi vederlo in azione quando prendi l'indirizzo di una variabile locale del thread:

static __thread int test = 0;

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

int g(void) {
    return test;
}

compila in

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

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

i686 fa lo stesso ma con %gs . Su aarch64 questo non è necessario perché l'indirizzo può essere letto dal registro tls stesso.


In x86-64 ci sono 3 voci TLS, due delle quali accessibili tramite FS e GS, FS è usato internamente da glibc (in IA32 apparentemente FS è usato da Wine e GS da glibc).

Glibc imposta il suo punto di ingresso TLS su un struct pthread che contiene alcune strutture interne per la filettatura. Glibc di solito si riferisce a un struct pthread variabile come pd , presumibilmente per pthread descriptor .

Su x86-64, struct pthread inizia con un tcbhead_t (questo dipende dall'architettura, vedi le macro TLS_DTV_AT_TP e TLS_TCB_AT_TP ). Questa intestazione del blocco di controllo del thread, AFAIU, contiene alcuni campi necessari anche quando è presente un singolo thread. Il DTV è il Dynamic Thread Vector e contiene puntatori a blocchi TLS per DSO caricati tramite dlopen() . Prima o dopo il TCB c'è un blocco TLS statico per l'eseguibile e i DSO collegati al momento del caricamento (del programma). Il TCB e il DTV sono spiegati abbastanza bene nel documento TLS di Ulrich Drepper (cerca i diagrammi nel capitolo 3).


Linux
  1. Linux:come scoprire quali dischi rigidi ci sono nel sistema?

  2. Linux:come trovare il driver di dispositivo utilizzato per un dispositivo?

  3. Linux:quali sorgenti di entropia vengono utilizzate dal kernel Linux?

  4. Come modificare in modo permanente l'indirizzo MAC su Linux

  5. Come posso vedere quali sono i miei comandi Linux più usati?

Come trovare l'indirizzo IP in Kali Linux

Come trovare l'indirizzo IP in Linux

Come modificare l'indirizzo MAC in Linux

Come modificare l'indirizzo IP su Linux

Come ottenere il tuo indirizzo IP su Linux

come generare un indirizzo MAC casuale dalla riga di comando di Linux