C 文本部分从哪个地址开始?
我在一本书中读到(记不起名字),32位系统的文本部分总是从0x0848000开始。但是当我执行C 文本部分从哪个地址开始?,c,C,我在一本书中读到(记不起名字),32位系统的文本部分总是从0x0848000开始。但是当我执行readelf-S example\u executable时,它并不反映相同的信息。为什么呢?其他部分(bss、数据、rodata等)是否也从固定地址开始?如何找到这些部分的对齐边界?对于文本部分或任何其他部分,操作系统和体系结构之间没有一致的地址。此外,位置无关的代码和地址空间布局随机性使得某些系统在同一台机器上的这些值甚至不一致。这里有一个很好的解释,说明了Linux虚拟内存在为特定程序分配存储时
readelf-S example\u executable
时,它并不反映相同的信息。为什么呢?其他部分(bss、数据、rodata等)是否也从固定地址开始?如何找到这些部分的对齐边界?对于文本部分或任何其他部分,操作系统和体系结构之间没有一致的地址。此外,位置无关的代码和地址空间布局随机性使得某些系统在同一台机器上的这些值甚至不一致。这里有一个很好的解释,说明了Linux虚拟内存在为特定程序分配存储时是如何工作的。
编译器/链接器工具链的设计者需要为特定内存块分配一个任意地址。为了使调试器和分析器等工具链的其他组件更容易使用,它们总是将相同的块分配给相同的地址。选择的实际地址完全是任意的
当程序加载时,虚拟地址将映射到某个随机的空闲内存块(这主要是在硬件中完成的)。此映射是在每个进程的基础上完成的,几个程序可以寻址虚拟地址x'0848000',但指向不同的“真实”内存地址。这一切都取决于特定计算机上的实现。对于linux计算机,其行为将不同于windows计算机。 然而,请注意,虚拟内存地址需要从某个固定地址开始,以使调试器的工作更轻松。然而,实际地址将根据RAM中可用的页面而有所不同。 如果您更仔细地查看readelf-S的输出,您会注意到从地址中减去偏移量确实会得到0x0848000。 正如我前面提到的,这个幻数0x0848000将取决于可执行文件格式的类型。 以下是我在ubuntu 32位机器上得到的输出:
readelf -S ~/a.out
There are 29 section headers, starting at offset 0x1130:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .interp PROGBITS 08048134 000134 000013 00 A 0 0 1
[ 2] .note.ABI-tag NOTE 08048148 000148 000020 00 A 0 0 4
[ 3] .note.gnu.build-i NOTE 08048168 000168 000024 00 A 0 0 4
[ 4] .gnu.hash GNU_HASH 0804818c 00018c 000020 04 A 5 0 4
[ 5] .dynsym DYNSYM 080481ac 0001ac 000050 10 A 6 1 4
[ 6] .dynstr STRTAB 080481fc 0001fc 00004c 00 A 0 0 1
[ 7] .gnu.version VERSYM 08048248 000248 00000a 02 A 5 0 2
[ 8] .gnu.version_r VERNEED 08048254 000254 000020 00 A 6 1 4
[ 9] .rel.dyn REL 08048274 000274 000008 08 A 5 0 4
[10] .rel.plt REL 0804827c 00027c 000018 08 A 5 12 4
[11] .init PROGBITS 08048294 000294 000030 00 AX 0 0 4
[12] .plt PROGBITS 080482c4 0002c4 000040 04 AX 0 0 4
[13] .text PROGBITS 08048310 000310 00018c 00 AX 0 0 16
[14] .fini PROGBITS 0804849c 00049c 00001c 00 AX 0 0 4
由于地址空间布局随机化(ASLR),在现代操作系统上,这些边界中的许多是随机化的。您可能指的是0x08048000,而不是0x0848000。地址的选择并非完全是任意的;有些选择比其他的好。特别是,将文本段设置为
0x60000000
左右将使应用程序可能使用的最大mmap
大小大约减半。。。