2014-11-11 7 views
5

ich gcc und eine Verknüpfung zu kompilieren verwendet rufen die grundlegendsten C-Programm, test.c:Wie funktioniert execve dynamische Linker/Lader (ld-linux.so.2)

int 
main() { 
} 

Wie erwartet, ist der Ausgang eine dynamisch verknüpfte ausführbare Datei:

$ 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 Laufen gibt die folgende Ausgabe:

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

ich erwartete "/lib64/ld-linux.so.2" s zu sehen omewhere im Strace Ausgang da nach dem execve Handbuch:

Wenn die ausführbare Datei ist ein dynamisch verknüpfte ausführbare ELF, der Interpreter genannt in> PT_INTERP das Segment wird verwendet, um die benötigten gemeinsam genutzte Bibliotheken zu laden. Dieser Interpreter> ist in der Regel /lib/ld-linux.so.2 für Binärdateien mit glibc verknüpft 2

Meine Vermutung ist, dass der Linker/Lader (/lib64/ld-linux.so.2) Aufruf ist Teil von Execve. Kann jemand bestätigen?

Antwort

9

Meine Vermutung ist, dass der Linker/Loader (/lib64/ld-linux.so.2) Aufruf Teil von Execve ist.

Dies ist etwas richtig.

Der Kernel betrachtet zuerst die ausführbaren Hauptsegmente und mmap s sie in die neue "Prozess-Shell".

Wenn es feststellt, dass die ausführbare PT_INTERP Segment hat, es mmap s das auch Segmente der Datei, und es Steuerelement gibt.

Bei "Rückkehr" von execve() in den Benutzermodus ist der Interpreter (normalerweise /lib64/ld-linux-x86-64.so.2 unter Linux/x86_64) bereits zugeordnet und wird ausgeführt. Es ist dann die Aufgabe dieses Interpreters, sich selbst zu verlagern, den Rest der benötigten gemeinsamen Bibliotheken zu mmap zu initialisieren, und schließlich die Kontrolle auf die Haupt-ausführbare Datei zu übertragen.

Wenn Sie weitere Details wünschen, starten Sie here.