Я экспериментирую с форматом файлов ELF, и я еще не понял схему здесь.Вот минимальный файл ELF:
$ cat zero.asm
.text
.global _start
_start:
movl $0,%ebx # first argument: exit code.
movl $1,%eax # system call number (sys_exit).
int $0x80 # call kernel.
$ as zero.asm -o zero.o && ld zero.o -s && readelf -h -l a.out
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
...
Type: EXEC (Executable file)
...
Entry point address: 0x400078
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x0000000000000084 0x0000000000000084 R E 0x200000
Существует только одна область загрузки, которая загружается в LMA = VMA = 0x400000
с выравниванием 0x200000
.Я не уверен, почему 0x200000
является значением по умолчанию или как его изменить в ld, но с некоторым редактированием в шестнадцатеричном формате я могу уменьшить выравнивание до минимального значения 0x1000
(в соответствии со спецификацией ELF), а затем я также могууменьшить адрес загрузки страницы.Экспериментально, если я установил его на .text = 0x10000
или выше, он загружается и работает успешно, и если я пытаюсь загрузить его меньше, чем это, то программа segfaults.Откуда этот номер?Я проверил /proc/ID/maps
и не вижу никаких доказательств защищенной страницы в 0-0x10000, но я знаю, что здесь ядро хранит свои обработчики прерываний ... но весь процесс в любом случае находится в виртуальной памяти, так чтоне вижу память ядра ... что здесь происходит?Как ядро определяет, какие области адресов доступны для моего процесса?