程序位址空間

2021-06-20 15:25:09 字數 3323 閱讀 9621

kernel筆記——程序位址空間

2013-09-03 09:53:49

分類: linux

下圖是x86_64下linux程序的預設記憶體布局形式:

下面逐一分析以上各個位址段的含義。

text **段

**段,從虛擬記憶體位址00400000開始,使用pmap $$可以檢視到,這個位址是固定的:

linux # pmap $$

27729: bash

00400000       552k  480k  260k     0k   0k r-xp /bin/bash

00689000         4k    4k    4k     4k   0k r--p /bin/bash

0068a000        20k   20k   20k    20k   0k rw-p /bin/bash

0068f000      1420k 1356k 1356k  1356k   0k rw-p [heap]

7f4f47b72000    64k    4k    4k     0k   0k r-xp /usr/lib64/gconv/libgb.so

…… 7f4f48c33000     4k    4k    4k     4k   0k rw-p [anon]

7fff0f0f1000    84k   20k   20k    20k   0k rw-p [stack]

7fff0f1ff000     4k    4k    0k     0k   0k r-xp [vdso]

ffffffffff600000 4k    0k    0k     0k   0k r-xp [vsyscall]

total:       18944k 3256k 2225k  1580k   0k

1652k writable-private, 17052k readonly-private, 240k shared, and 3256k referenced

00400000位址段用於存放程式的可執行檔案,fork乙個子程序,之後呼叫execve載入可執行檔案,execve即將檔案載入到該段位址中:

linux # strace ls

execve("/bin/ls", ["ls"], [/* 65 vars */]) = 0

brk(0) =0x618000

mmap(null, 4096, prot_read | prot_write, map_private | map_anonymous, -1, 0) = 0x7f0422e2a000 ……

data 資料段

資料段用於存放已初始化全域性變數。

bss段

該段用於存放全域性的、但未初始化的變數。bss段與data段的區別是,編譯時需為data段分配空間,而bss段不用。資料存放於bss段,減小了可執行程式的檔案大小。

heap

堆,c庫中的malloc呼叫就是從該段獲取記憶體空間。

memory map

mmap系統呼叫可將檔案對映入程序memory map位址空間。使用pmap $$檢視,[heap]下面部分就是mmap區域,對於以上"pmap $$"輸出:

7f4f47b72000  64k  4k  4k  0k  0k  r-xp        /usr/lib64/gconv/libgb.so

bash程序將/usr/lib64/gconv/libgb.so檔案對映到以7f4f47b72000開頭的位址段。

使用ldd命令,我們可以看到程序依賴的庫檔案,這些庫檔案編譯過程中都要關聯到程序的虛擬位址空間:

linux # ldd /bin/bash

linux-vdso.so.1 => (0x00007fffc73ff000)

libreadline.so.5 => /lib64/libreadline.so.5 (0x00007f7effe50000)

libdl.so.2 => /lib64/libdl.so.2 (0x00007f7effc4c000)

libc.so.6 => /lib64/libc.so.6 (0x00007f7eff8ee000)

libncurses.so.5 => /lib64/libncurses.so.5 (0x00007f7eff6a6000)

/lib64/ld-linux-x86-64.so.2 (0x00007f7f00092000)

stack

存放區域性變數,從高位址向低位址生長。

核心**中,mm_struct結構用於描述乙個程序的位址空間。

vm_area_struct用於描述一段位址,linux提供了/proc/pid/maps介面,我們可以通過該介面查詢某程序的虛擬位址段:

linux # cat /proc/$$/maps

00400000 - 00486000   r-xp 00000000 08:02 18104 /bin/bash

00586000 - 00586000   rw-p 00086000 08:02 18104 /bin/bash

0058b000 - 0073b000   rw-p 0058b000 00:00     0 [heap]

2b7c1ff67000 - 2b7c1ff82000 r-xp 00000000 08:02 12969 /lib64/ld-2.4.so

…… 7fff8ab2d000 - 7fff8ab43000 rw-p 7fff8ab2d000 00:00 0 [stack]

ffffffffff600000 - ffffffffffe00000 ---p 00000000 00:00 0 [vdso]

c庫中的malloc底層通過mmap或brk實現記憶體申請。mmap可用於關聯檔案到程序的虛擬位址空間,也可用於申請匿名位址空間。

void *mmap( void *addr, size_t length, int prot, int flags, int fd, off_t offset);

若指明fd就是關聯檔案到虛擬位址空間,沒有指明就是申請匿名位址空間。

brk呼叫只是增加heap這一段虛擬記憶體空間,sbrk用於實際的記憶體申請。

reference: chapter 15 - the process address space, linux kernel development.3rd.edition

程序位址空間

這篇文章應該不能說是原創的,這裡的記錄都是我通過閱讀整理來的,並沒有太多的自己的想法。資料 現代作業系統 之所以去了解位址空間也是因為在學習dll的時候看到要將dll對映到程式的位址空間,不甚明了所以去查詢相關的資料。位址空間其實很好理解 當然針對早期的機器 早期的機器是沒有ram,rom,cach...

程序位址空間

程序位址空間 1.可執行檔案 的記憶體對映,稱為 段 2.可執行檔案的已初始化全域性變數的記憶體對映,稱為資料段 3.包含未初始化的全域性變數,也就是bss段的零頁的記憶體對映 4.用於程序使用者控制項棧的零頁的記憶體對映 5.任何記憶體對映檔案 6.任何共享記憶體段 7.任何匿名的記憶體對映,比如...

程序位址空間

下圖是x86 64下linux程序的預設記憶體布局形式 下面逐一分析以上各個位址段的含義。text 段 段,從虛擬記憶體位址00400000開始,使用pmap 可以檢視到,這個位址是固定的 linux pmap 27729 bash 00400000 552k 480k 260k 0k 0k r x...