diff --git a/20220425/bs-20220425.txt b/20220425/bs-20220425.txt new file mode 100644 index 0000000000000000000000000000000000000000..ba7537fce07fd14c553030fdd850ea464a8276a0 --- /dev/null +++ b/20220425/bs-20220425.txt @@ -0,0 +1,64 @@ +Von der Anwendung bis zum Kernel: libc, 14.05.2021, 14:17:04 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +$ gcc -Wall -O -g3 hello-1.c -o hello-1 +$ gdb -tui ./hello-1 +(gdb) b 5 # setze Breakpoint vor printf()-Aufruf +(gdb) run +(gdb) step # springe in die aufgerufene Funktion hinein +(gdb) directory libc/glibc-2.28/libio # Verzeichnis für Quelltext mitteilen +--> _IO_puts() +(gdb) next # 1 Zeile ausführen +--> _IO_sputn() # springe in die aufgerufene Funktion hinein +--> IO_validate_vtable() # In dieser Funktion landen wir stattdessen. +--> return vtable; +--> "Hello, world!\n" erscheint auf dem Bildschirm. +--> ??? + +_IO_sputn() ist keine Funktion, sondern ein Präprozessor-Makro, +der _IO_XSPUTN() aufruft. + +_IO_XSPUTN() ist keine Funktion, sondern ein Präprozessor-Makro, +der JUMP2() aufruft und zusätzlich __xsputn +als ersten Parameter übergibt. + +JUMP2() ist keine Funktion, sondern ein Präprozessor-Makro, +der die Funktion _IO_JUMPS_FUNC(THIS)->FUNC() aufruft +und zusätzlich THIS als ersten Parameter übergibt. +FUNC hat hierbei den Wert __xsputn, und +THIS hat den Wert FP, also die Datei, hier also stdout. + +_IO_JUMPS_FUNC() ist keine Funktion, sondern ein Präprozessor-Makro, +der ... + +# define _IO_JUMPS_FUNC(THIS) \ + (IO_validate_vtable \ + (*(struct _IO_jump_t **) ((void *) &_IO_JUMPS_FILE_plus (THIS) \ + + (THIS)->_vtable_offset))) + +... prüft, ob die virtuelle Methodentabelle (vtable) in Ordnung ist +und einen Zeiger darauf zurückliefert. +Anschließend kann JUMP2() die tatsächliche Funktion __xsputn() aufrufen. + +Gesamtergebnis: + +_IO_sputn() ist eine virtuelle Methode der Datei. +THIS hat den Wert der Datei, hier also stdout. + +... +--> return vtable; +--> _IO_new_file_xsputn() + +_IO_default_xsputn (f, ...) +--> _IO_OVERFLOW (f, EOF) +--> IO_valudate_vtable() # Aufruf einer virtuellen Methode +--> _IO_new_file_overflow() +--> _IO_do_write (f, ...) # Präprozessor-Makro für ... +--> _IO_new_do_write (f, ...) +... Schleife ... +Datei fileops.c, Zeile 791 +--> _IO_new_do_write (f, ...) +--> new_do_write (f, ...) +--> _IO_SYSWRITE (fp, ...) +--> __libc_write() +Datei sysdeeps/unix/sysv/linux/write.c, Zeile 26 +--> return SYSCALL_CANCEL (write, fd, buf, nbytes);