Let's look at the LOAD
segments:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000000 0x08048000 0x08048000 0x0009d 0x0009d R E 0x1000
LOAD 0x00009d 0x0804909d 0x0804909d 0x00010 0x00010 RW 0x1000
The first one instructs the loader to mmap
0x9d
bytes from file offset 0
into virtual memory at address 0x08048000
.
The loader can't do exactly that, because memory mapping only works at one page (4096 bytes) granularity. So it mmap
s the .text
, and everything that follows it in the file, up to one page, at address 0x08048000
.
This means that whatever .data
followed .text
in the file after offset 0x9d
will appear at address 0x0804809d
and later, but with wrong permissions (R
ead and E
xecute).
The second LOAD
segment instructs the loader to mmap
file contents, starting at offset 0x9d
at virtual address 0x0804909d
.
The loader can't do exactly that either for the same "page granularity" reason.
Instead, it will round down the offset and the address, and mmap
file contents starting from offset 0
at address 0x08049000
.
That that means that whatever .text
preceded .data
in the file will appear at address before 0x0804909d
, again with the wrong permissions (R
ead and W
rite this time).
You can confirm that that's what's happening by using GDB x/10i 0x8049080
-- you will see exactly the same instructions as with x/10i 0x8048080
.
You can also observe the actual mmap
system calls the loader performed with strace
.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…