2010-01-20 37 views
4

要查看正在運行的程序包含哪些存儲器映射區域,我寫了一個簡單的C程序來讀取從/ proc /自/地圖數據:libc.so在一個進程中映射了四個段,爲什麼?

#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的段相比,缺少只有私有位的段。

所以我想知道什麼是四段實際上呢?我正在使用內核2.6.28的Ubuntu SMP,gcc 3.4.6和binutils 2.19。

回答

5

r-xp,r--prw-p映射只是需要不同權限的區域。

神祕---p映射是由ELF文件描述的部分的虛擬內存偏移量不一定與文件內的物理偏移量匹配(可能因爲對齊原因而存在填充)的結果。

即ELF文件本身可能是這樣的:

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

...但描述了內存佈局,看起來像這樣:

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

(你可以看到這個使用objdump -hreadelf -e 。)

所以,總的原則是,ld.so需要的一切分配足夠的內存:

|               | 

...然後做一個映射第一部分:

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

...然後進行第二次的映射來得到在正確的地方第二部分:

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

然後,它保護了在虛擬地址空間留下了「洞」。這就是神祕的映射,你看到:

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

我相信孔被保護 - 而不是釋放再利用 - 爲了讓事情簡單:確保每個庫只有一個單一的虛擬地址範圍,屬於它而不是其他人。

+0

很好的答案。但它確實提出了後續問題,您提到的「差距」是什麼原因? – 2015-07-10 20:32:01

相關問題