相关疑难解决方法(0)

为什么ELF执行入口点虚拟地址为0x80xxxxx而不是0x0?

执行时,程序将从虚拟地址0x80482c0开始运行.此地址不指向我们的main()过程,而是指向_start由链接器创建的名为的过程.

到目前为止,我的谷歌研究只是让我得到了一些(含糊的)历史猜测:

有民间传说,0x08048000曾经是由加利福尼亚州圣克鲁斯市的一个团体颁布的*NIX到i386的端口上的STACK_TOP(也就是说,堆栈从接近0x08048000下降到0).这是因为128MB的RAM很昂贵,4GB的RAM是不可想象的.

任何人都可以确认/否认这个吗?

point elf virtual-address-space

19
推荐指数
2
解决办法
1万
查看次数

0x08048000用于32位机器之前的内存是多少?

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

但我不知道从那里开始的原因.在0x08048000用于之前的内存是多少?

更新:有些人认为它是为内核映射的.但据我所知,Linux内核使用在用户堆栈之后启动的高端内存.

linux memory operating-system process

19
推荐指数
2
解决办法
5065
查看次数

L2 TLB未命中后会发生什么?

我很难理解当翻译旁视缓冲区的前两个级别导致未命中时会发生什么?

我不确定特殊硬件电路中是否出现"页面行走",或者页表是否存储在L2/L3高速缓存中,或者它们是否只存在于主存储器中.

cpu performance x86 cpu-architecture tlb

19
推荐指数
1
解决办法
2135
查看次数

为什么Linux/gnu链接器选择地址0x400000?

我在Linux x86_64上试验ELF可执行文件和gnu工具链:

我已经链接并剥离(手工)"Hello World"测试.:

        .global _start
        .text
_start:
        mov     $1, %rax
        ...
Run Code Online (Sandbox Code Playgroud)

到一个267字节的ELF64可执行文件...

0000000: 7f45 4c46 0201 0100 0000 0000 0000 0000  .ELF............
0000010: 0200 3e00 0100 0000 d400 4000 0000 0000  ..>.......@.....
0000020: 4000 0000 0000 0000 0000 0000 0000 0000  @...............
0000030: 0000 0000 4000 3800 0100 4000 0000 0000  ....@.8...@.....
0000040: 0100 0000 0500 0000 0000 0000 0000 0000  ................
0000050: 0000 4000 0000 0000 0000 4000 0000 0000  ..@.......@.....
0000060: 0b01 0000 0000 0000 0b01 0000 …
Run Code Online (Sandbox Code Playgroud)

linux x86 x86-64 elf ld

16
推荐指数
2
解决办法
3347
查看次数

为什么在64位虚拟地址与物理地址(52位长)相比,4位短(48位长)?

在"低级编程:英特尔®64架构上的C,汇编和程序执行"一书中,我读到:

每个虚拟64位地址(例如,我们在程序中使用的地址)由几个字段组成.地址本身实际上只有48位宽; 它被符号扩展为64位规范地址.它的特点是它的17个左位是相等的.如果不满足条件,则在使用时立即拒绝该地址.然后借助特殊表将48位虚拟地址转换为52位物理地址.

为什么虚拟地址和物理地址之间的差异为4位?

assembly memory-management virtual-memory memory-address mmu

12
推荐指数
1
解决办法
2304
查看次数

在ELF文件中,如何确定_start的地址?

我一直在阅读ELF规范,无法确定程序入口点和_start地址从何而来。

似乎它们应该在一个相当一致的位置,但是我编写了一些琐碎的程序,而_start始终在另一个位置。

谁能澄清?

symbols elf

6
推荐指数
1
解决办法
2380
查看次数

为什么不能在64位内核的32位Linux进程中映射(MAP_FIXED)最高虚拟页面?

尝试测试时是否允许访问跨越x86中零边界的内存?在Linux的用户空间中,我编写了一个32位测试程序,该程序试图映射32位虚拟地址空间的低和高页。

之后echo 0 | sudo tee /proc/sys/vm/mmap_min_addr,我可以映射零页面,但是我不知道为什么不能映射-4096(即(void*)0xfffff000最高页面)。 为什么要mmap2((void*)-4096)退货-ENOMEM

strace ./a.out 
execve("./a.out", ["./a.out"], 0x7ffe08827c10 /* 65 vars */) = 0
strace: [ Process PID=1407 runs in 32 bit mode. ]
....
mmap2(0xfffff000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0
Run Code Online (Sandbox Code Playgroud)

另外,什么支票在中拒绝它linux/mm/mmap.c,为什么要这样设计?这是确保创建指向一个过去的对象的指针不会回绕并中断指针比较的部分吗,因为ISO C和C ++允许创建指向过去的一个指针,但不能在外部对象。


我在64位内核(Arch Linux上为4.12.8-2-ARCH)下运行,因此32位用户空间具有整个可用的4GiB。(与64位内核或32位内核(其中2:2或3:1用户/内核拆分会使高页成为内核地址)上的64位代码不同。)

我没有尝试使用最小的静态可执行文件(没有CRT启动程序或libc,只有asm),因为我认为这不会有所作为。没有一个CRT启动系统调用看起来可疑。


在断点处停下来时,我检查了一下/proc/PID/maps。主页尚未使用。堆栈包括第二高的页面,但未映射首页。

00000000-00001000 rw-p 00000000 …
Run Code Online (Sandbox Code Playgroud)

linux x86 assembly mmap linux-kernel

6
推荐指数
1
解决办法
501
查看次数