2011-08-25 1842 views
17

En Linux, aprendí que cada proceso almacena datos comenzando en 0x08048000 en máquina de 32 bits (y 0x00400000 en máquina de 64 bits).¿Cuál es la memoria anterior a 0x08048000 utilizada en una máquina de 32 bits?

Pero no sé la razón por la cual comenzar desde allí. ¿Para qué se utiliza la memoria antes de 0x08048000?

Actualización: Algunas personas piensan que está mapeado para el kernel. Sin embargo, que yo sepa, Linux Kernel usa la memoria de gama alta comenzando después de la pila del usuario.

Respuesta

6

La respuesta es realmente: un montón de cosas. No hay un significado mágico para la dirección de carga del ejecutable y casi cualquier cosa puede asignarse a las direcciones inferiores. Ejemplos comunes incluyen: biblioteca C (como la biblioteca C), el cargador dinámico ld.so y el kernel VDSO (biblioteca de códigos dinámicos asignados al kernel que proporciona parte de la interfaz al kernel en x86 Linux). Pero puede mapear prácticamente cualquier cosa que desee allí, utilizando la llamada al sistema mmap().

Por ejemplo en mi máquina específica el mapa es el siguiente (adquirida, pero "cat/proc/self/mapas"):

[email protected]:~$ cat /proc/self/maps 
001c0000-00317000 r-xp 00000000 08:01 245836  /lib/libc-2.12.1.so 
00317000-00318000 ---p 00157000 08:01 245836  /lib/libc-2.12.1.so 
00318000-0031a000 r--p 00157000 08:01 245836  /lib/libc-2.12.1.so 
0031a000-0031b000 rw-p 00159000 08:01 245836  /lib/libc-2.12.1.so 
0031b000-0031e000 rw-p 00000000 00:00 0 
00376000-00377000 r-xp 00000000 00:00 0   [vdso] 
00852000-0086e000 r-xp 00000000 08:01 245783  /lib/ld-2.12.1.so 
0086e000-0086f000 r--p 0001b000 08:01 245783  /lib/ld-2.12.1.so 
0086f000-00870000 rw-p 0001c000 08:01 245783  /lib/ld-2.12.1.so 
08048000-08051000 r-xp 00000000 08:01 2244617 /bin/cat 
08051000-08052000 r--p 00008000 08:01 2244617 /bin/cat 
08052000-08053000 rw-p 00009000 08:01 2244617 /bin/cat 
09ab5000-09ad6000 rw-p 00000000 00:00 0   [heap] 
b7502000-b7702000 r--p 00000000 08:01 4456455 /usr/lib/locale/locale-archive 
b7702000-b7703000 rw-p 00000000 00:00 0 
b771b000-b771c000 r--p 002a1000 08:01 4456455 /usr/lib/locale/locale-archive 
b771c000-b771e000 rw-p 00000000 00:00 0 
bfbd9000-bfbfa000 rw-p 00000000 00:00 0   [stack] 
+1

Algunas distribuciones (por ejemplo, RHEL6) incluso han abandonado por completo la cosa '0x08048000' vinculando programas con la bandera [' DYNAMIC'] (http://stackoverflow.com/questions/5235844/objdump-head-elf-meaning-of-flags), haciendo que sus segmentos sean asignados junto con '.so''s. –

1

típica de carga mapa para x86 de 32 bits pequeña aplicación estática se ve así:

Address  Contents 

0x08048000 code 
0x08052000 data 
0x0805A000 bss (zero data) 
0x08072000 end of data (brk marker) 
0xBFFFE000 stack 

Todo este ser a la inversa - pila de estar en la cima y se extiende hacia arriba mientras que los datos en movimiento. Mi suposición es que la dirección anterior a 0x08048000 está vinculada de forma estática a algo similar al MBR por sistema operativo.

+0

Si la imagen de su programa está cargada en 0x0848000, no verá nada debajo de eso, ni "MBR" ni nada. – bdonlan

8

La dirección de inicio para cargar el código ejecutable está determinada por los encabezados ELF para el ejecutable. Por ejemplo:

/bin/ls 
architecture: i386, flags 0x00000112: 
EXEC_P, HAS_SYMS, D_PAGED 
start address 0x08049bb0 

No hay nada que impida que un ejecutable especifique una dirección de carga diferente; por alguna razón, el default linker settings lo puso allí. Puede anular con un script de enlazador personalizado.

De forma predeterminada, en linux/x86, no verá direcciones bajas por debajo de 0x08000000 utilizadas por mucho; aunque el kernel puede usarlo si se solicita en una llamada mmap, o si se queda sin espacio para mmaps. Además, ha habido propuestas para utilizar direcciones en el rango de 0x00000000 - 0x01000000 para mapeos de bibliotecas, para hacer que los desbordamientos de búfer sean más difíciles (al incrustar un byte NUL para terminar cadenas).

+0

Todos los procesos tienen tablas de traducción de direcciones virtuales separadas. Muchos de ellos podrían tener la misma dirección de inicio, traduciendo a diferentes direcciones físicas. –

1

La dirección de carga es arbitrario, pero se estandarizó atrás con SYSV para x86 . Es diferente para cada arquitectura. Lo que pasa arriba y abajo también es arbitrario y, a menudo, lo utilizan los enlaces en las bibliotecas y las regiones de mmap().

Cuestiones relacionadas