GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cómo se usan los registros fs/gs en Linux AMD64?

¿Cuál es entonces el uso de GS?

x86_64 El kernel de Linux usa el registro GS como una forma eficiente de adquirir la pila de espacio del kernel para las llamadas al sistema.

El registro GS almacena la dirección base para el área por CPU. Para adquirir la pila de espacio del kernel, en entry_SYSCALL_64

movq    PER_CPU_VAR(cpu_current_top_of_stack), %rsp

Después de expandir PER_CPU_VAR, obtenemos lo siguiente:

movq    %gs:cpu_current_top_of_stack, %rsp

Para responder realmente a su fs:0 pregunta:La ABI x86_64 requiere que fs:0 contiene la dirección "señalada" por fs sí mismo. Es decir, fs:-4 carga el valor almacenado en fs:0 - 4 . Esta función es necesaria porque no puede obtener fácilmente la dirección a la que apunta fs sin pasar por el código del kernel. Tener la dirección almacenada en fs:0 por lo tanto, hace que trabajar con el almacenamiento local de subprocesos sea mucho más eficiente.

Puede ver esto en acción cuando toma la dirección de una variable local de subproceso:

static __thread int test = 0;

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

int g(void) {
    return test;
}

compila a

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

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

i686 hace lo mismo pero con %gs . En aarch64 esto no es necesario porque la dirección se puede leer desde el propio registro tls.


En x86-64 hay 3 entradas TLS, dos de ellas accesibles vía FS y GS, FS es usado internamente por glibc (en IA32 aparentemente FS es usado por Wine y GS por glibc).

Glibc hace que su punto de entrada TLS sea un struct pthread que contiene algunas estructuras internas para roscar. Glibc generalmente se refiere a un struct pthread variable como pd , presumiblemente para pthread descriptor .

En x86-64, struct pthread comienza con un tcbhead_t (esto depende de la arquitectura, ver las macros TLS_DTV_AT_TP y TLS_TCB_AT_TP ). Este encabezado de bloque de control de subprocesos, AFAIU, contiene algunos campos que son necesarios incluso cuando hay un solo subproceso. El DTV es el vector de subproceso dinámico y contiene punteros a bloques TLS para DSO cargados a través de dlopen() . Antes o después de la TCB, hay un bloque TLS estático para el ejecutable y los DSO vinculados en el momento de la carga (del programa). TCB y DTV se explican bastante bien en el documento TLS de Ulrich Drepper (busque los diagramas en el capítulo 3).


Linux
  1. Cómo llegó Linux al mainframe

  2. Linux:¿Cómo encontrar el controlador de dispositivo utilizado para un dispositivo?

  3. Cómo cambiar permanentemente la dirección MAC en Linux

  4. En Linux, ¿cómo saber cuántos núcleos de la máquina están activos?

  5. ¿Qué fuentes de entropía utiliza el kernel de Linux?

Cómo encontrar la dirección IP en Kali Linux

Cómo encontrar la dirección IP en Linux

Cómo cambiar la dirección MAC en Linux

Cómo cambiar la dirección IP en Linux

Cómo obtener su dirección IP en Linux

cómo generar una dirección MAC aleatoria desde la línea de comandos de Linux