Для наблюдения, что содержат регионы карты распределения памяти под управлением программа я пишу простую программу C для чтения данных с/proc/self/maps:
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
int main() {
char buf[1024];
int fd;
ssize_t n;
fd = open("/proc/self/maps", O_RDONLY);
if (fd < 0) {
perror("");
}
while ((n = read(fd, buf, 1000)) > 0) {
buf[n] = 0;
printf("%s", buf);
}
close(fd);
return 0;
}
Вывод программы похож, это (маркировало):
1. 08048000-08049000 r-xp 00000000 08:01 2323014 /tmp/a.out
2. 08049000-0804a000 rw-p 00000000 08:01 2323014 /tmp/a.out
3. b7f69000-b7f6a000 rw-p b7f69000 00:00 0
4. b7f6a000-b80c6000 r-xp 00000000 08:01 1826975 /lib/tls/i686/cmov/libc-2.9.so
5. b80c6000-b80c7000 ---p 0015c000 08:01 1826975 /lib/tls/i686/cmov/libc-2.9.so
6. b80c7000-b80c9000 r--p 0015c000 08:01 1826975 /lib/tls/i686/cmov/libc-2.9.so
7. b80c9000-b80ca000 rw-p 0015e000 08:01 1826975 /lib/tls/i686/cmov/libc-2.9.so
8. b80ca000-b80cd000 rw-p b80ca000 00:00 0
9. b80dd000-b80df000 rw-p b80dd000 00:00 0
10.b80df000-b80e0000 r-xp b80df000 00:00 0 [vdso]
11.b80e0000-b80fc000 r-xp 00000000 08:01 1826830 /lib/ld-2.9.so
12.b80fc000-b80fd000 r--p 0001b000 08:01 1826830 /lib/ld-2.9.so
13.b80fd000-b80fe000 rw-p 0001c000 08:01 1826830 /lib/ld-2.9.so
14.bfee9000-bfefe000 rw-p bffeb000 00:00 0 [stack]
Поскольку мы можем вывести из разрядного выполнения и перезаписываемый бит, первые две строки связаны с сегментами кода и сегментами данных программы соответственно.
Но то, что смущает меня, является тем из libc.so, существует для регионов, которые отображаются от libc.so. У одного из них даже только есть частный бит, он не может быть записан, читать, или выполняемый. И другая интересная вещь состоит в том, что ld.so имеет только три сегмента. По сравнению с сегментами libc.so отсутствует тот только с частным битом на.
Таким образом, я хотел бы знать то, что эти четыре сегмента, делают на самом деле? Я использую Ubuntu SMP с ядром 2.6.28, gcc 3.4.6, и binutils 2.19.
R-XP
, R - P
и отображения RW-P
- это просто области, которые нуждаются в разных разрешениях.
Тайна --- P
сопоставление является следствием смещения виртуальной памяти сечений, описанных файлом ELF, не обязательно соответствует физическим смещениям в файле (может быть прокладка для выравнивания).
I.E. Сам файл эльфа может выглядеть так:
| .... sections .... | .... more sections .... |
... но опишите планировку памяти, который выглядит так:
| .... sections .... | gap | .... more sections .... |
(вы можете увидеть это, используя Objdump -h -h
или
.)
Итак, общий принцип - это то, что ld.so
необходимо выделить достаточно памяти для всего:
| |
... затем сделайте одно отображение для первой части:
| .... sections .... | |
... а затем сделайте второе сопоставление, чтобы получить вторую часть в нужном месте:
| .... sections .... | | .... more sections .... |
Затем он защищает «отверстие», которое осталось в виртуальном адресном пространстве. Это загадочное отображение, которое вы видите:
| .... sections .... |XXXXXXXXXXXXX| .... more sections .... |
Я считаю, что дыра защищена - вместо того, чтобы освободиться за повторное использование - для того, чтобы сохранить вещи простым: он гарантирует, что каждая библиотека имеет только один виртуальный диапазон адресов, который принадлежит Это и никто другой.