32位机器使用0x08048000之前的内存是多less?

在Linux中,我了解到每个进程都在32位机器上存储从0x08048000开始的数据(而在64位机器中存储0x00400000)。

但我不知道从那里出发的原因。 0x08048000之前内存是多less?

更新 :有些人认为它是为内核映射的。 不过据我所知,Linux内核使用用户堆栈之后开始的高端内存。

答案是:一堆东西。 可执行文件的加载地址没有任何神奇的含义,几乎任何东西都可以映射到较低的地址。 常见的例子包括:C库(如C库),动态加载程序ld.so和内核VDSO(内核映射的动态代码库,提供了x86 Linux内核的一些接口)。 但是使用mmap()系统调用,你几乎可以映射任何你想要的东西。

例如,在我的特定机器上,地图如下(获得但是“cat / proc / self / maps”):

gby@watson:~$ cat /proc/self/maps 001c0000-00317000 r-xp 00000000 08:01 245836 /lib/libc-2.12.1.so 00317000-00318000 ---p 00157000 08:01 245836 /lib/libc-2.12.1.so 00318000-0031a000 r--p 00157000 08:01 245836 /lib/libc-2.12.1.so 0031a000-0031b000 rw-p 00159000 08:01 245836 /lib/libc-2.12.1.so 0031b000-0031e000 rw-p 00000000 00:00 0 00376000-00377000 r-xp 00000000 00:00 0 [vdso] 00852000-0086e000 r-xp 00000000 08:01 245783 /lib/ld-2.12.1.so 0086e000-0086f000 r--p 0001b000 08:01 245783 /lib/ld-2.12.1.so 0086f000-00870000 rw-p 0001c000 08:01 245783 /lib/ld-2.12.1.so 08048000-08051000 r-xp 00000000 08:01 2244617 /bin/cat 08051000-08052000 r--p 00008000 08:01 2244617 /bin/cat 08052000-08053000 rw-p 00009000 08:01 2244617 /bin/cat 09ab5000-09ad6000 rw-p 00000000 00:00 0 [heap] b7502000-b7702000 r--p 00000000 08:01 4456455 /usr/lib/locale/locale-archive b7702000-b7703000 rw-p 00000000 00:00 0 b771b000-b771c000 r--p 002a1000 08:01 4456455 /usr/lib/locale/locale-archive b771c000-b771e000 rw-p 00000000 00:00 0 bfbd9000-bfbfa000 rw-p 00000000 00:00 0 [stack] 

加载可执行代码的起始地址由可执行文件的ELF头文件决定。 例如:

 /bin/ls architecture: i386, flags 0x00000112: EXEC_P, HAS_SYMS, D_PAGED start address 0x08049bb0 

没有什么能阻止可执行文件指定不同的加载地址; 无论出于何种原因, 默认的链接器设置将其放在那里。 您可以使用自定义链接程序脚本进行覆盖。

默认情况下,在linux / x86上,你不会看到低于0x08000000低地址; 尽管内核可能会在mmap调用中使用它,或者如果它在mmap空间不足的话。 此外,还有建议使用0x00000000 - 0x01000000范围内的地址作为库映射,使缓冲区溢出变得更加困难(通过嵌入NUL字节来终止字符串)。

适用于x86的32位典型加载映射小型静态应用程序如下所示:

  Address Contents 0x08048000 code 0x08052000 data 0x0805A000 bss (zero data) 0x08072000 end of data (brk marker) 0xBFFFE000 stack 

所有这些都是反向堆栈,在数据向上移动的同时向下移动。 我的猜测是0x08048000之前的地址静态链接的东西类似于每个操作系统的MBR。

加载地址是任意的,但用SYSV for x86标准化。 每个架构都不一样 上面和下面的内容也是任意的,而且经常被链接到库和mmap()区域中。