I'm understanding ELF and its program headers. When I read an ELF using readelf
with file type as DYN. I see virtual address value in Program Headers is actually from kernel Virtual address space.
Elf file type is DYN (Shared object file)
Entry point 0x1060
There are 13 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000000040 0x0000000000000040
0x00000000000002d8 0x00000000000002d8 R 0x8
INTERP 0x0000000000000318 0x0000000000000318 0x0000000000000318
0x000000000000001c 0x000000000000001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000600 0x0000000000000600 R 0x1000
LOAD 0x0000000000001000 0x0000000000001000 0x0000000000001000
0x00000000000001f5 0x00000000000001f5 R E 0x1000
LOAD 0x0000000000002000 0x0000000000002000 0x0000000000002000
0x0000000000000168 0x0000000000000168 R 0x1000
LOAD 0x0000000000002db8 0x0000000000003db8 0x0000000000003db8
0x0000000000000258 0x0000000000000260 RW 0x1000
DYNAMIC 0x0000000000002dc8 0x0000000000003dc8 0x0000000000003dc8
0x00000000000001f0 0x00000000000001f0 RW 0x8
NOTE 0x0000000000000338 0x0000000000000338 0x0000000000000338
0x0000000000000020 0x0000000000000020 R 0x8
NOTE 0x0000000000000358 0x0000000000000358 0x0000000000000358
0x0000000000000044 0x0000000000000044 R 0x4
GNU_PROPERTY 0x0000000000000338 0x0000000000000338 0x0000000000000338
0x0000000000000020 0x0000000000000020 R 0x8
GNU_EH_FRAME 0x0000000000002018 0x0000000000002018 0x0000000000002018
0x0000000000000044 0x0000000000000044 R 0x4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 0x10
GNU_RELRO 0x0000000000002db8 0x0000000000003db8 0x0000000000003db8
0x0000000000000248 0x0000000000000248 R 0x1
I'm able to deduce the actual VirtAddr at the time of loading the binary should be = Base Address + VirtAddr. But I'm not able to find out how loader calculates the Base Address Value?
Also, I know .text and .data are two PT_LOAD segments for loading the binary. But I see 4 PT_LOAD program headers in my example. What are two PT_LOAD program headers used for?
I see virtual address value in Program Headers is actually from kernel Virtual address space.
No, you do not see that. None of the addresses in your output have anything to do with the kernel.
What you are looking at is a Position Independent executable, which can be loaded anywhere in memory.
I'm not able to find out how loader calculates the Base Address Value?
The loader doesn't load the main executable (the kernel does), and doesn't decide the load address.
Given that the file type is ET_DYN
, the kernel performs an equivalent of
mmap(0, ...)
(without MAP_FIXED
flag), and selects a suitable virtual address, which is then communicated to the loader in the aux
vector.
But I see 4 PT_LOAD program headers in my example. What are two PT_LOAD program headers used for?
See this answer.