Linux64/x86_64 机器中进程的虚拟地址
Virtual Address of process in Linux64/x86_64 machine
我有两个与进程地址映射相关的问题;
- 我知道在32位的Linux机器上,一个进程的虚拟地址分为两部分,3GB给Userspace,1GB给Krnel。 x86_64/Linux64机也是一样吗?
- linux 可执行文件的 objdump 显示 _init 大约从地址 0x400000 开始。为什么exe地址从0x400000左右开始?
bash-4.2$ objdump -S a.out
a.out: file format elf64-x86-64
Disassembly of section .init:
0000000000400390 <_init>:
400390: 48 83 ec 08 sub [=11=]x8,%rsp
下面显示了相同 a.out 的 pmap 输出。这里的映射也从 0000000000400000
(即 4MB)开始。那么4MB之前的虚拟内存在哪里?
bash-4.2$ pmap 95297
95297: ./a.out
0000000000400000 4K r-x-- a.out
0000000000600000 4K r---- a.out
0000000000601000 4K rw--- a.out
00007fdfd0f37000 1800K r-x-- libc-2.17.so
00007fdfd10f9000 2048K ----- libc-2.17.so
00007fdfd12f9000 16K r---- libc-2.17.so
00007fdfd12fd000 8K rw--- libc-2.17.so
00007fdfd12ff000 20K rw--- [ anon ]
00007fdfd1304000 136K r-x-- ld-2.17.so
00007fdfd1506000 12K rw--- [ anon ]
00007fdfd1524000 4K rw--- [ anon ]
00007fdfd1525000 4K r---- ld-2.17.so
00007fdfd1526000 4K rw--- ld-2.17.so
00007fdfd1527000 4K rw--- [ anon ]
00007fff09042000 132K rw--- [ stack ]
00007fff091c3000 8K r-x-- [ anon ]
ffffffffff600000 4K r-x-- [ anon ]
total 4212K
在x86_64上,虚拟地址space是48位(只有64位地址,17位全0或全1有效),而在linux上被分成两半——用户 128TB,内核 128TB。
在那 128TB 的用户 space 中,堆栈被放置在随机选择的高地址(因此通常以 00007fff 开头)和低地址的可执行文件。然后共享库通常加载到堆栈下方的某个位置(也有些随机)选择的精确地址是随机的,以使其更难利用安全漏洞。
我有两个与进程地址映射相关的问题;
- 我知道在32位的Linux机器上,一个进程的虚拟地址分为两部分,3GB给Userspace,1GB给Krnel。 x86_64/Linux64机也是一样吗?
- linux 可执行文件的 objdump 显示 _init 大约从地址 0x400000 开始。为什么exe地址从0x400000左右开始?
bash-4.2$ objdump -S a.out
a.out: file format elf64-x86-64
Disassembly of section .init:
0000000000400390 <_init>:
400390: 48 83 ec 08 sub [=11=]x8,%rsp
下面显示了相同 a.out 的 pmap 输出。这里的映射也从 0000000000400000
(即 4MB)开始。那么4MB之前的虚拟内存在哪里?
bash-4.2$ pmap 95297
95297: ./a.out
0000000000400000 4K r-x-- a.out
0000000000600000 4K r---- a.out
0000000000601000 4K rw--- a.out
00007fdfd0f37000 1800K r-x-- libc-2.17.so
00007fdfd10f9000 2048K ----- libc-2.17.so
00007fdfd12f9000 16K r---- libc-2.17.so
00007fdfd12fd000 8K rw--- libc-2.17.so
00007fdfd12ff000 20K rw--- [ anon ]
00007fdfd1304000 136K r-x-- ld-2.17.so
00007fdfd1506000 12K rw--- [ anon ]
00007fdfd1524000 4K rw--- [ anon ]
00007fdfd1525000 4K r---- ld-2.17.so
00007fdfd1526000 4K rw--- ld-2.17.so
00007fdfd1527000 4K rw--- [ anon ]
00007fff09042000 132K rw--- [ stack ]
00007fff091c3000 8K r-x-- [ anon ]
ffffffffff600000 4K r-x-- [ anon ]
total 4212K
在x86_64上,虚拟地址space是48位(只有64位地址,17位全0或全1有效),而在linux上被分成两半——用户 128TB,内核 128TB。
在那 128TB 的用户 space 中,堆栈被放置在随机选择的高地址(因此通常以 00007fff 开头)和低地址的可执行文件。然后共享库通常加载到堆栈下方的某个位置(也有些随机)选择的精确地址是随机的,以使其更难利用安全漏洞。