Для чего используется память до 0x08048000 на 32-битной машине? - PullRequest
19 голосов
/ 25 августа 2011

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

Но я не знаю причину, почему начинать с этого.Для чего использовалась память до 0x08048000 ?

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

Ответы [ 4 ]

8 голосов
/ 28 августа 2011

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

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

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

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

7 голосов
/ 28 августа 2011

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

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

gby@watson:~$ 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 голосов
/ 30 августа 2011

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

1 голос
/ 26 августа 2011

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

 Address     Contents

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

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

...