简体   繁体   English

execve 如何调用动态链接器/加载器(ld-linux.so.2)

[英]How does execve call dynamic linker/loader (ld-linux.so.2)

I used gcc to compile and link the most basic C program, test.c:我使用 gcc 编译并链接了最基本的 C 程序 test.c:

int
main() {
}

As expected, the output is a dynamically linked executable:正如预期的那样,输出是一个动态链接的可执行文件:

$ file test
test: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses     shared libs), for GNU/Linux 2.6.26, BuildID[sha1]=0x0f806c099f74132a158d98aebde4639ae0998971, not stripped

Running strace gives the following output:运行 strace 给出以下输出:

$ strace -f ./test
execve("./test", ["./test"], [/* 31 vars */]) = 0
brk(0)                                  = 0x248d000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f77eeb27000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=109292, ...}) = 0
mmap(NULL, 109292, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f77eeb0c000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\300\357\1\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1595408, ...}) = 0
mmap(NULL, 3709016, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f77ee580000
mprotect(0x7f77ee700000, 2097152, PROT_NONE) = 0
mmap(0x7f77ee900000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x180000) = 0x7f77ee900000
mmap(0x7f77ee905000, 18520, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f77ee905000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f77eeb0b000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f77eeb0a000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f77eeb09000
arch_prctl(ARCH_SET_FS, 0x7f77eeb0a700) = 0
mprotect(0x7f77ee900000, 16384, PROT_READ) = 0
mprotect(0x7f77eeb29000, 4096, PROT_READ) = 0
munmap(0x7f77eeb0c000, 109292)          = 0
exit_group(-292524312)                  = ?

I was expecting to see "/lib64/ld-linux.so.2" somewhere in the strace output since according to the execve manual:根据 execve 手册,我希望在 strace 输出中的某处看到“/lib64/ld-linux.so.2”:

If the executable is a dynamically linked ELF executable, the interpreter named in >the PT_INTERP segment is used to load the needed shared libraries.如果可执行文件是动态链接的 ELF 可执行文件,则在 > PT_INTERP 段中命名的解释器用于加载所需的共享库。 This interpreter >is typically /lib/ld-linux.so.2 for binaries linked with glibc 2对于与 glibc 2 链接的二进制文件,此解释器通常是 /lib/ld-linux.so.2

My guess is that the linker/loader (/lib64/ld-linux.so.2) call is part of execve.我的猜测是链接器/加载器 (/lib64/ld-linux.so.2) 调用是 execve 的一部分。 Can someone confirm?有人可以确认吗?

My guess is that the linker/loader (/lib64/ld-linux.so.2) call is part of execve.我的猜测是链接器/加载器 (/lib64/ld-linux.so.2) 调用是 execve 的一部分。

This is somewhat correct.这有点正确。

The kernel first looks at the main executable segments, and mmap s them into the new "process shell".内核首先查看主要的可执行段,并将它们mmap到新的“进程外壳”中。

When it discovers that the executable has PT_INTERP segment, it mmap s that file's segments as well, and passes control to it .当它发现该可执行具有PT_INTERP段,它mmap s表示文件的片段,以及,并且将控制传递给

Thus, upon "return" from execve() into user-mode, the interpreter (usually /lib64/ld-linux-x86-64.so.2 on Linux/x86_64) is already mapped in and running.因此,在从execve() “返回”到用户模式时,解释器(在 Linux/x86_64 上通常为/lib64/ld-linux-x86-64.so.2 )已经映射并运行。 It is then the job of that interpreter to relocate itself, to mmap the rest of required shared libraries, initialize them, and finally transfer control to the main executable.然后解释器的工作是重新定位自身, mmap其余所需的共享库,初始化它们,最后将控制权转移到主可执行文件。

If you want more details, start here .如果您想了解更多详情,请从这里开始。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将elf解释器(ld-linux.so.2 / ld-2.17.so)构建为静态库? - How to build the elf interpreter (ld-linux.so.2/ld-2.17.so) as static library? 什么是ld-linux.so.2和linux-gate.so.1? - What are ld-linux.so.2 and linux-gate.so.1? 是否可以在Mono中用DllImport加载ld-linux.so.2? - Is it possible to load ld-linux.so.2 with DllImport in Mono? bash:./loopy:/lib/ld-linux.so.2:错误的ELF解释器:没有这样的文件或目录 - bash: ./loopy: /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory “ /usr/bin/javac:/lib/ld-linux.so.2:错误的ELF解释器:没有这样的文件或目录” - “/usr/bin/javac: /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory” 来自/lib/ld-linux.so.2的check_match.8629()中的核心哑巴 - core dumb in check_match.8629 () from /lib/ld-linux.so.2 /lib/ld-linux.so.2:错误的ELF解释器:没有这样的文件或目录没有可用的glibc.i386软件包 - /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory No package glibc.i386 available CentOS错误:/lib/ld-linux.so.2:错误的ELF解释器:没有这样的文件 - CentOS Error: /lib/ld-linux.so.2: bad ELF interpreter: No such file 为什么 ld 需要 /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 而它的默认动态链接器是 /lib64/ld-linux-x86-64.so.2? - Why does ld need /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 while its default dynamic linker is /lib64/ld-linux-x86-64.so.2? execve()是否设置寄存器以调用动态链接器或要执行的可执行文件? - Does `execve()` set up registers to invoke dynamic linker or the executable to be executed?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM