libc.so имеет четыре сегмента, отображенных в процессе, почему? - PullRequest
4 голосов
/ 20 января 2010

Чтобы увидеть, какие области карты памяти содержит работающая программа, я пишу простую программу на 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.

1 Ответ

5 голосов
/ 21 января 2010

Отображения r-xp, r--p и rw-p - это просто области, для которых требуются разные разрешения.

Отображение тайны ---p является следствием смещений виртуальной памяти в разделах, описываемых файлом ELF, которые необязательно совпадают с физическими смещениями в файле (для выравнивания может быть заполнение).

т.е. сам файл ELF может выглядеть так:

| .... sections .... | .... more sections .... |

... но опишите схему памяти, которая выглядит следующим образом:

| .... sections .... |     gap     | .... more sections .... |

(Вы можете увидеть это, используя objdump -h или readelf -e.)

Итак, общий принцип заключается в том, что ld.so необходимо выделить достаточно памяти для всего:

|                                                            |

... затем сделайте одно отображение для первой части:

| .... sections .... |                                       |

... а затем создайте второе отображение, чтобы получить вторую часть в нужном месте:

| .... sections .... |             | .... more sections .... |

Затем защищает «дыру», оставленную в виртуальном адресном пространстве. Это таинственное отображение, которое вы видите:

| .... sections .... |XXXXXXXXXXXXX| .... more sections .... |

Я считаю, что дыра защищена, а не освобождена для повторного использования, чтобы упростить задачу: она гарантирует, что каждая библиотека имеет только один диапазон виртуальных адресов, который принадлежит ей, и никому другому.

...