I know that the dynamic linker uses mmap()
to load libraries. I guess it is the kernel who loads both the executable and its .interp
reter into the same address space, but how does it determine where? I noticed that ld.so
's load address with ASLR disabled is 0x555555554000
(on x86_64) — where does this address come from? I tried following do_execve()
's code path, but it is too ramified for me not to be confused as hell.
相关问题
- Is shmid returned by shmget() unique across proces
- how to get running process information in java?
- Kernel oops Oops: 80000005 on arm embedded system
- Error building gcc 4.8.3 from source: libstdc++.so
- Why should we check WIFEXITED after wait in order
Read more about ELF, in particular elf(5), and about the execve(2) syscall.
An ELF file may contain an interpreter. elf(5) mentions:
That interpreter is practically almost always ld-linux(8) (e.g. with GNU glibc), more precisely (on my Debian/Sid)
/lib64/ld-linux-x86-64.so.2
. If you compile musl-libc then build some software with it you'll get a different interpreter,/lib/ld-musl-x86_64.so.1
. That ELF interpreter is the dynamic linker.The execve(2) syscall is using that interpreter:
See also Levine's book on Linkers and loaders, and Drepper's paper: How To Write Shared Libraries
Notice that
execve
is also handling the shebang (i.e. first line starting with#!
); see the Interpreter scripts section of execve(2). BTW, for ELF binaries,execve
is doing the equivalent of mmap(2) on some segments.Read also about vdso(7), proc(5) & ASLR. Type
cat /proc/self/maps
in your shell.(I guess, but I am not sure, that the 0x555555554000 address is in the ELF program header of your executable, or perhaps of
ld-linux.so
; it might also come from the kernel, since 0x55555555 seems to appear in the kernel source code)