execve如何调用动态链接器/加载器(ld-linux.so.2) [英] How does execve call dynamic linker/loader (ld-linux.so.2)

查看:229
本文介绍了execve如何调用动态链接器/加载器(ld-linux.so.2)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用gcc编译和链接了最基本的C程序test.c:

I used gcc to compile and link the most basic C program, 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

运行strace会给出以下输出:

Running strace gives the following output:

$ 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)                  = ?

根据execve手册,我希望在strace输出中看到"/lib64/ld-linux.so.2":

I was expecting to see "/lib64/ld-linux.so.2" somewhere in the strace output since according to the execve manual:

如果可执行文件是动态链接的ELF可执行文件,则使用PT_INTERP段中命名的解释器来加载所需的共享库.该解释器通常是/lib/ld-linux.so.2,用于与glibc 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. This interpreter >is typically /lib/ld-linux.so.2 for binaries linked with glibc 2

我的猜测是链接器/加载器(/lib64/ld-linux.so.2)调用是execve的一部分.有人可以确认吗?

My guess is that the linker/loader (/lib64/ld-linux.so.2) call is part of execve. Can someone confirm?

推荐答案

我的猜测是链接器/加载器(/lib64/ld-linux.so.2)调用是execve的一部分.

My guess is that the linker/loader (/lib64/ld-linux.so.2) call is part of execve.

这是正确的.

内核首先查看主要的可执行段,然后将它们mmap放入新的进程外壳"中.

The kernel first looks at the main executable segments, and mmaps them into the new "process shell".

当发现可执行文件具有PT_INTERP段时,它也会mmap该文件的段,并将控制权传递给 it .

When it discovers that the executable has PT_INTERP segment, it mmaps that file's segments as well, and passes control to it.

因此,从execve()返回"到用户模式后,解释器(通常在Linux/x86_64上为/lib64/ld-linux-x86-64.so.2)已经映射并正在运行.然后,该解释器的工作就是将自己重新定位,到其余所需的共享库中,mmap,对其进行初始化,最后将控制权转移给主可执行文件.

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. 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.

如果您想了解更多详细信息,请在此处开始.

If you want more details, start here.

这篇关于execve如何调用动态链接器/加载器(ld-linux.so.2)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆