linux - mac - musicbrainz picard español
Dominio virtual del encabezado del programa ELF y compensación de archivos (1)
¿Por qué comienza en 0x1000 bytes DESPUÉS DEL FINAL del primer segmento de CARGA?
Si no fuera así, debería comenzar en 0x08048154
, pero no puede: los dos segmentos LOAD
tienen banderas diferentes especificadas para su mapeo (la primera está mapeada con PROT_READ|PROT_EXEC
, la segunda con PROT_READ|PROTO_WRITE
. Protecciones ( ser parte de la tabla de páginas) solo se puede aplicar a páginas enteras , no a partes de una página. Por lo tanto, las asignaciones con diferentes protecciones deben pertenecer a diferentes páginas.
Alineación de página de mod de dirección virtual = Alineación de página de mod de desplazamiento de archivo
Pero no sé por qué esta relación debe ser satisfecha.
Los segmentos LOAD
son directamente mmap
ed desde el archivo. El mapeo real del segundo segmento de LOAD
realizado para su ejemplo se verá algo así (puede ejecutar su programa bajo strace
y ver que sí lo hace):
mmap(0x08049000, 0x158, PROT_READ|PROT_WRITE, MAP_PRIVATE, $fd, 0)
Si intenta hacer que la dirección virtual o el desplazamiento no mmap
alineados con la página, mmap
fallará con EINVAL
. La única forma de hacer que los datos de archivos aparezcan en la memoria virtual en la dirección deseada para hacer que VirtAddr
congruente con el módulo de Offset
Align
, y eso es exactamente lo que hace el enlazador estático.
Tenga en cuenta que para un primer segmento LOAD
tan pequeño, todo el primer segmento también aparece al comienzo de la segunda asignación (con las protecciones incorrectas). Pero el programa no debe acceder a nada en el rango [0x08049000,0x08049154)
. En general, casi siempre sucede que hay algo de "basura" antes del inicio de los datos reales en el segundo segmento de LOAD
(a menos que tenga mucha suerte y el primer segmento de LOAD
termine en un límite de página).
Ver también la página man de mmap .
Sé la relación entre los dos:
Alineación de página de mod de dirección virtual = Alineación de página de mod de desplazamiento de archivo
¿Pero alguien puede decirme en qué dirección se calculan estos dos números?
¿La dirección virtual se calcula a partir de la compensación de archivos de acuerdo con la relación anterior, o viceversa?
Actualizar
Aquí hay algunos detalles más: cuando el enlazador escribe el encabezado del archivo ELF, establece la dirección virtual y el desplazamiento del archivo de los encabezados del programa. (Segmentos)
Por ejemplo, está el resultado de readelf -l someELFfile
:
Elf file type is EXEC (Executable file)
Entry point 0x8048094
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000000 0x08048000 0x08048000 0x00154 0x00154 R E 0x1000
LOAD 0x000154 0x08049154 0x08049154 0x00004 0x00004 RW 0x1000
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x10
Podemos ver 2 segmentos de carga.
La dirección virtual de la primera CARGA finaliza en 0x8048154, mientras que la segunda CARGA comienza en 0x8049154.
En el archivo ELF, la segunda CARGA está justo detrás de la primera CARGA con desplazamiento de archivo 0x00154, sin embargo, cuando esta ELF se carga en la memoria, comienza en 0x1000 bytes después del final del primer segmento CARGAR.
¿Pero por qué? Si tenemos que considerar la alineación de la página de memoria, ¿por qué el segundo segmento LOAD no comienza en 0x80489000? ¿Por qué comienza en 0x1000 bytes DESPUÉS DEL FINAL del primer segmento de CARGA?
Sé que la dirección virtual de la segunda CARGA satisface la relación:
Alineación de página de mod de dirección virtual = Alineación de página de mod de desplazamiento de archivo
Pero no sé por qué esta relación debe ser satisfecha.