Давайте посмотрим на сегменты LOAD
:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000000 0x08048000 0x08048000 0x0009d 0x0009d R E 0x1000
LOAD 0x00009d 0x0804909d 0x0804909d 0x00010 0x00010 RW 0x1000
Первый инструктирует загрузчик в mmap
0x9d
байтов от смещения файла 0
в виртуальную память по адресу 0x08048000
.
Загрузчик не может сделать точно это , потому что отображение памяти работает только с детализацией на одной странице (4096 байт). Таким образом, это mmap
s .text
и все, что следует за ним в файле , до одной страницы, по адресу 0x08048000
.
Это означает, что все, что .data
после .text
в файле после смещения 0x9d
появится по адресу 0x0804809d
и позже, но с неправильными разрешениями (R
ead и E
xecute).
Второй сегмент LOAD
указывает загрузчику содержимое файла mmap
, начиная со смещения 0x9d
по виртуальному адресу 0x0804909d
.
Загрузчик не может делать это либо по той же причине "гранулярности страницы".
Вместо этого будет округлено смещение и адрес, а также mmap
содержимое файла, начиная со смещения 0
по адресу 0x08049000
.
Это означает, что все, что .text
предшествует .data
в файле, будет отображаться по адресу до 0x0804909d
, опять же с неправильными разрешениями (R
ead и W
на этот раз ритуал).
Вы можете подтвердить, что именно это происходит, используя GDB x/10i 0x8049080
- вы получите ee точно те же инструкции, что и с x/10i 0x8048080
.
Вы также можете наблюдать фактические mmap
системные вызовы, выполняемые загрузчиком с strace
.