Подтвердить что ты не робот

Какая память до 0x08048000 используется в 32-битной машине?

В Linux я узнал, что каждый процесс хранит данные, начиная с 0x08048000 в 32-битной машине (и 0x00400000 на 64-битной машине).

Но я не знаю причины, почему оттуда. Какая память до 0x08048000 используется для?

Обновление: Некоторые люди считают, что это сопоставлено для ядра. Однако, насколько я знаю, ядро ​​Linux использует верхнюю память, начиная с пользовательского стека.

4b9b3361

Ответ 1

Ответ на самом деле: куча вещей. Магическое значение для адреса загрузки исполняемого файла не имеет, и почти все может быть сопоставлено с нижними адресами. Общие примеры, в том числе: библиотека C (например, библиотека C), динамический загрузчик ld.so и ядро ​​VDSO (ядро, преобразованное в динамическую библиотеку кодов, которая предоставляет некоторый интерфейс для ядра в x86 Linux). Но вы можете в значительной степени отобразить все, что хотите, используя системный вызов mmap().

Например, на моей конкретной машине карта выглядит следующим образом (приобретается, но "cat/proc/self/maps" ):

[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]

Ответ 2

Начальный адрес для загрузки исполняемого кода определяется заголовками ELF для исполняемого файла. Например:

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

Ничего не мешает исполняемому файлу указать другой адрес загрузки; по какой-либо причине настройки компоновщика компоновки по умолчанию. Вы можете переопределить с помощью специального компоновщика script.

По умолчанию на linux/x86 вы не увидите низких адресов ниже 0x08000000, используемых для многих; хотя ядро ​​может использовать его, если оно запрашивается при вызове mmap, или если у него не хватает места для mmaps. Кроме того, были предложены использовать адреса в диапазоне 0x00000000 - 0x01000000 для сопоставлений библиотек, чтобы затруднить переполнение буфера (путем вложения байта NUL для завершения строк).

Ответ 3

Типичная карта загрузки для x86 для 32 бит. Маленькое статическое приложение выглядит следующим образом:

 Address     Contents

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

Все это в обратном порядке - стек находится сверху и движется вниз, а данные движутся вверх. Я предполагаю, что адрес до 0x08048000 статически связан с чем-то похожим на MBR для каждой ОС.

Ответ 4

Адрес загрузки произвольный, но был стандартизован обратно с SYSV для x86. Он отличается для каждой архитектуры. То, что идет выше и ниже, также произвольно, и часто используется в библиотеках и областях mmap().