Page 1 of 1

ELF segments vs. link_map's l_addr

Posted: Tue Jul 20, 2021 11:02 am
by kai12345
Hi,

I'm wondering how ELF segments are loaded into memory. ELF Wiki sounds like each segment is mapped individually to its preferred address (p_vaddr).

But this SO answer sounds like the opposite: https://stackoverflow.com/questions/623 ... 1#62505821
For this reason, the dynamic linker (I'll use rtld contraction for it) must perform the mmap of both segments as a single mmap
Individually mapped segments would also explain /proc/maps traces like this, where some libs are interleaved:

Code: Select all

 00:00:802    test_bla-23606/23606           7ffff7ddc000-7ffff7dfd000 r-xp 00000000 fe:01 436934                     /lib64/ld-2.19.so
 00:00:802    test_bla-23606/23606           7ffff7e6b000-7ffff7e82000 r--p 00000000 fe:01 163598                     /etc/ld.so.cache
 00:00:802    test_bla-23606/23606           7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0                          [vdso]
 00:00:802    test_bla-23606/23606           7ffff7ffc000-7ffff7ffd000 r--p 00020000 fe:01 436934                     /lib64/ld-2.19.so
 00:00:802    test_bla-23606/23606           7ffff7ffd000-7ffff7ffe000 rw-p 00021000 fe:01 436934                     /lib64/ld-2.19.so
But, assuming each segment is mapped individually, how does link_map's l_addr work then?
https://code.woboq.org/userspace/glibc/ ... ap::l_addr

Code: Select all

    ElfW(Addr) l_addr;                /* Difference between the address in the ELF
                                   file and the addresses in memory.  */
Assuming each segment is mapped individually, wouldn't each segment need its own load-offset?

Re: ELF segments vs. link_map's l_addr

Posted: Wed Jul 21, 2021 9:48 am
by Octocontrabass
The offset between the preferred address and the actual address has to be the same for all segments in the file.

Re: ELF segments vs. link_map's l_addr

Posted: Wed Jul 21, 2021 12:21 pm
by Korona
The SO answer is wrong, you can use MAP_FIXED to map segments individually. For example, you could first reserve a range of virtual memory by mapping MAP_ANONYMOUS memory with PROT_NONE, and then overwrite the appropriate parts of that reservation using MAP_FIXED.