ich die syscall Aufruf im letzten libc seziert:Linux syscall, libc, VDSO und Implementierung Dissektion
git clone git://sourceware.org/git/glibc.git
Und ich habe diesen Code in sysdeps/Unix/sysv/linux/i386/sysdep.h:
# define INTERNAL_SYSCALL_MAIN_INLINE(name, err, nr, args...) \
LOADREGS_##nr(args) \
asm volatile ( \
"call *%%gs:%P2" \
: "=a" (resultvar) \
: "a" (__NR_##name), "i" (offsetof (tcbhead_t, sysinfo)) \
ASMARGS_##nr(args) : "memory", "cc")
Wenn ich auch diesen Code zu verstehen, die LOADREGS _ ## nr (args) Makro lädt das Argument in der EBX-Register, ECX, EDX, esi, EDX und EBP.
sysdeps/Unix/sysv/linux/i386/sysdep.h
# define LOADREGS_0()
# define ASMARGS_0()
# define LOADREGS_1(arg1) \
LOADREGS_0()
# define ASMARGS_1(arg1) \
ASMARGS_0(), "b" ((unsigned int) (arg1))
# define LOADREGS_2(arg1, arg2) \
LOADREGS_1 (arg1)
# define ASMARGS_2(arg1, arg2) \
ASMARGS_1 (arg1), "c" ((unsigned int) (arg2))
# define LOADREGS_3(arg1, arg2, arg3) \
LOADREGS_2 (arg1, arg2)
# define ASMARGS_3(arg1, arg2, arg3) \
ASMARGS_2 (arg1, arg2), "d" ((unsigned int) (arg3))
# define LOADREGS_4(arg1, arg2, arg3, arg4) \
LOADREGS_3 (arg1, arg2, arg3)
# define ASMARGS_4(arg1, arg2, arg3, arg4) \
ASMARGS_3 (arg1, arg2, arg3), "S" ((unsigned int) (arg4))
# define LOADREGS_5(arg1, arg2, arg3, arg4, arg5) \
LOADREGS_4 (arg1, arg2, arg3, arg4)
# define ASMARGS_5(arg1, arg2, arg3, arg4, arg5) \
ASMARGS_4 (arg1, arg2, arg3, arg4), "D" ((unsigned int) (arg5))
# define LOADREGS_6(arg1, arg2, arg3, arg4, arg5, arg6) \
register unsigned int _a6 asm ("ebp") = (unsigned int) (arg6); \
LOADREGS_5 (arg1, arg2, arg3, arg4, arg5)
# define ASMARGS_6(arg1, arg2, arg3, arg4, arg5, arg6) \
ASMARGS_5 (arg1, arg2, arg3, arg4, arg5), "r" (_a6)
#endif /* GCC 5 */
enter code here
Wo ist der Code, der das Argument in den Registern ebx laden, ECX, EDX, esi, EDX und EBP? es ist dieser Code oben? Ich verstehe die Implementierung nicht. der folgende Code lädt das 6. Argument im ebx-Register?
register unsigned int _a6 asm ("ebp") = (unsigned int) (arg6);
Was diesen Code tut:
ASMARGS_0(), "b" ((unsigned int) (arg1))
Es lädt das erste Argument in der EBX registrieren?
Dann springt der "Aufruf * %% gs:% P2" zum VDSO-Code? dieser Code entspricht "call * gs: 0x10"?
so, das folgende Diagramm für den Schreib syscall, ist es gut ?:
write(1, "A", 1) -----> LIBC -----> VDSO -----> KERNEL
load reg ?
jump to vdso
|---------------------------------------------------|--------------|
user land kernel land
ich nicht das VDSO Dienstprogramm nicht verstehe! vdso wählt die Methode syscall (sysenter oder int 0x80).
Vielen Dank im Voraus für Ihre Hilfe. Und tut mir leid, mein Englisch ist sehr schlecht.
Die Glibc ist aufgrund ihrer verschachtelten Abstraktionsschicht extrem kompliziert. Ich empfehle Ihnen, zuerst eine einfachere libc zu betrachten. – fuz
ist sehr einfach zu verstehen, eine einfache libc, die syscall Argumente sind in den Registern gespeichert und die Int 0x80 oder sysenter Anweisung wird ausgeführt, um im Kernel-Modus zu drehen. – tutuen
@tuutuen suchst du jemanden, der das VDSO oder die Methode erklärt, mit der glibc damit interagiert? Wenn Sie nur eine Erklärung des VDSO wünschen, wäre das einfacher bereitzustellen. –