Какая память до 0x08048000 используется в 32-битной машине?
В Linux я узнал, что каждый процесс хранит данные, начиная с 0x08048000 в 32-битной машине (и 0x00400000 на 64-битной машине).
Но я не знаю причины, почему оттуда. Какая память до 0x08048000 используется для?
Обновление:
Некоторые люди считают, что это сопоставлено для ядра. Однако, насколько я знаю, ядро Linux использует верхнюю память, начиная с пользовательского стека.
Ответы
Ответ 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().