Professional Documents
Culture Documents
html
1 de 21 06/04/2021 0:05
Tearing apart printf() – MaiZure's Projects http://www.maizure.org/projects/printf/index.html
2 de 21 06/04/2021 0:05
Tearing apart printf() – MaiZure's Projects http://www.maizure.org/projects/printf/index.html
3 de 21 06/04/2021 0:05
Tearing apart printf() – MaiZure's Projects http://www.maizure.org/projects/printf/index.html
$uname -a
Linux localhost.localdomain 3.10.0-693.el7.x86_64 #1 SMP Tue Aug 22 21:09:27 UTC 20
17 x86_64 x86_64 x86_64 GNU/Linux
$gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-16)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ldd --version
ldd (GNU libc) 2.17
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.
4 de 21 06/04/2021 0:05
Tearing apart printf() – MaiZure's Projects http://www.maizure.org/projects/printf/index.html
#include <stdio.h>
5 de 21 06/04/2021 0:05
Tearing apart printf() – MaiZure's Projects http://www.maizure.org/projects/printf/index.html
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
printf("Hello World\n"); printf("Hello World %d\n",1);
return 0; return 0;
} }
6 de 21 06/04/2021 0:05
Tearing apart printf() – MaiZure's Projects http://www.maizure.org/projects/printf/index.html
7 de 21 06/04/2021 0:05
Tearing apart printf() – MaiZure's Projects http://www.maizure.org/projects/printf/index.html
$ ls -l printf1*
total 1696
-rwxrwxr-x. 1 maiz maiz 8520 Mar 31 13:38 printf1 # Dynamic
-rw-rw-r--. 1 maiz maiz 101 Mar 31 12:57 printf1.c
-rw-rw-r--. 1 maiz maiz 1520 Mar 31 13:37 printf1.o
-rwxrwxr-x. 1 maiz maiz 844000 Mar 31 13:40 printf1_s # Static
$ nm printf1.o | wc -l
2 # Object file symbol count (main, printf)
$ nm printf1 | wc -l
34 # Dynamic-linked binary symbol count
$ nm printf1_s | wc -l
1873 # Static-linked binary symbol count
strace
8 de 21 06/04/2021 0:05
Tearing apart printf() – MaiZure's Projects http://www.maizure.org/projects/printf/index.html
$ strace ./printf1
execve("./printf1", ["./printf1"], [/* 47 vars */]) = 0
brk(NULL) = 0x1dde000
mmap(NULL, 4096, ..., -1, 0) = 0x7f59bce82000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=83694, ...}) = 0
mmap(NULL, 83694, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f59bce6d000
close(3) = 0
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2127336, ...}) = 0
mmap(NULL, 3940800, ..., 3, 0) = 0x7f59bc89f000
mprotect(0x7f59bca57000, 2097152, PROT_NONE) = 0
mmap(0x7f59bcc57000, 24576, ..., 3, 0x1b8000) = 0x7f59bcc57000
mmap(0x7f59bcc5d000, 16832, ..., -1, 0) = 0x7f59bcc5d000
close(3) = 0
mmap(NULL, 4096, ..., -1, 0) = 0x7f59bce6c000
mmap(NULL, 8192, ..., -1, 0) = 0x7f59bce6a000
arch_prctl(ARCH_SET_FS, 0x7f59bce6a740) = 0
mprotect(0x7f59bcc57000, 16384, PROT_READ) = 0
mprotect(0x600000, 4096, PROT_READ) = 0
mprotect(0x7f59bce83000, 4096, PROT_READ) = 0
munmap(0x7f59bce6d000, 83694) = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap(NULL, 4096, ..., -1, 0) = 0x7f59bce81000
write(1, "Hello World 1\n", 14Hello World 1) = 14
exit_group(0) = ?
+++ exited with 0 +++
brk fstat
9 de 21 06/04/2021 0:05
Tearing apart printf() – MaiZure's Projects http://www.maizure.org/projects/printf/index.html
$ cat /proc/3177/maps
00400000-00401000 r-xp 00000000 ./printf1
00600000-00601000 r--p 00000000 ./printf1
00601000-00602000 rw-p 00001000 ./printf1
7f59bc89f000-7f59bca57000 r-xp 00000000 /usr/lib64/libc-2.17.so
7f59bca57000-7f59bcc57000 ---p 001b8000 /usr/lib64/libc-2.17.so
7f59bcc57000-7f59bcc5b000 r--p 001b8000 /usr/lib64/libc-2.17.so
7f59bcc5b000-7f59bcc5d000 rw-p 001bc000 /usr/lib64/libc-2.17.so
7f59bcc5d000-7f59bcc62000 rw-p 00000000
7f59bcc62000-7f59bcc83000 r-xp 00000000 /usr/lib64/ld-2.17.so
7f59bce6a000-7f59bce6d000 rw-p 00000000
7f59bce81000-7f59bce83000 rw-p 00000000
7f59bce83000-7f59bce84000 r--p 00021000 /usr/lib64/ld-2.17.so
7f59bce84000-7f59bce85000 rw-p 00022000 /usr/lib64/ld-2.17.so
7f59bce85000-7f59bce86000 rw-p 00000000
7fff89031000-7fff89052000 rw-p 00000000 [stack]
7fff8914e000-7fff89150000 r-xp 00000000 [vdso]
ffffffffff600000-ffffffffff601000 r-xp [vsyscall]
$ strace ./printf1_s
execve("./printf1_s", ["./printf1_s"],[/*47 vars*/]) = 0
uname({sysname="Linux", nodename="...", ...}) = 0
brk(NULL) = 0x1d4a000
brk(0x1d4b1c0) = 0x1d4b1c0
arch_prctl(ARCH_SET_FS, 0x1d4a880) = 0
brk(0x1d6c1c0) = 0x1d6c1c0
brk(0x1d6d000) = 0x1d6d000
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap(NULL, 4096, ..., -1, 0) = 0x7faad3151000
write(1, "Hello World 1\n", 14Hello World 1) = 14
exit_group(0) = ?
+++ exited with 0 +++
10 de 21 06/04/2021 0:05
Tearing apart printf() – MaiZure's Projects http://www.maizure.org/projects/printf/index.html
$ cat /proc/3237/printf1_s
00400000-004b8000 r-xp 00000000 ./printf1_s
006b7000-006ba000 rw-p 000b7000 ./printf1_s
006ba000-006df000 rw-p 00000000 [heap]
7ffff7ffc000-7ffff7ffd000 rw-p 00000000
7ffff7ffd000-7ffff7fff000 r-xp 00000000 [vdso]
7ffffffde000-7ffffffff000 rw-p 00000000 [stack]
ffffffffff600000-ffffffffff601000 r-xp [vsyscall]
11 de 21 06/04/2021 0:05
Tearing apart printf() – MaiZure's Projects http://www.maizure.org/projects/printf/index.html
12 de 21 06/04/2021 0:05
Tearing apart printf() – MaiZure's Projects http://www.maizure.org/projects/printf/index.html
_IO_*
_fxstat
13 de 21 06/04/2021 0:05
Tearing apart printf() – MaiZure's Projects http://www.maizure.org/projects/printf/index.html
from glibc/stdio-common/printf-parse.h:
/* Find the next spec in FORMAT, or the end of the string. Returns
a pointer into FORMAT, to a '%' or a '\0'. */
__extern_always_inline const unsigned char *
__find_specmb (const unsigned char *format)
{
return (const unsigned char *) __strchrnul ((const char *) format, '%');
}
in vfprintf:
0x414668 <+104>: mov esi,0x25 # Setting ESI to the '%' symbol
0x41466d <+109>: mov rdi,r12 # Pointing RDI to the format string
...saving arguments...
0x41468d <+141>: call 0x40c110 <strchrnul> # Search for next % or end
in strchrnul:
0x40c110 <+0>: movd xmm1,esi # Loading up an SSE register with '%'
0x40c114 <+4>: mov rcx,rdi # Moving the format string pointer
0x40c117 <+7>: punpcklbw xmm1,xmm1 # Vector-izing '%' for a fast compare
...eventual return of a pointer to the next token...
14 de 21 06/04/2021 0:05
Tearing apart printf() – MaiZure's Projects http://www.maizure.org/projects/printf/index.html
15 de 21 06/04/2021 0:05
Tearing apart printf() – MaiZure's Projects http://www.maizure.org/projects/printf/index.html
000000000040f9c0 <__libc_write>:
40f9c0: 83 3d c5 bb 2a 00 00 cmpl $0x0,0x2abbc5(%rip) # 6bb58c <__libc_mult
iple_threads>
40f9c7: 75 14 jne 40f9dd <__write_nocancel+0x14>
000000000040f9c9 <__write_nocancel>:
40f9c9: b8 01 00 00 00 mov $0x1,%eax
40f9ce: 0f 05 syscall
...cut...
16 de 21 06/04/2021 0:05
Tearing apart printf() – MaiZure's Projects http://www.maizure.org/projects/printf/index.html
#!/bin/sh
echo function_graph > /sys/kernel/debug/tracing/current_tracer
echo 1 > /sys/kernel/debug/tracing/tracing_on
./printf1_s
echo 0 > /sys/kernel/debug/tracing/tracing_on
cat /sys/kernel/debug/tracing/trace > output
7) | SyS_write() {
7) | vfs_write() {
7) | tty_write() {
7) 0.053 us | tty_paranoia_check();
7) | n_tty_write() {
7) 0.091 us | process_echoes();
7) | add_wait_queue()
7) 0.026 us | tty_hung_up_p();
7) | tty_write_room()
7) | pty_write() {
7) | tty_insert_flip_string_fixed_flag()
7) | tty_flip_buffer_push() {
7) | queue_work_on()
7)+10.288 us | } /* tty_flip_buffer_push */
7) | tty_wakeup()
7)+14.687 us | } /* pty_write */
7)+57.252 us | } /* n_tty_write */
7)+61.647 us | } /* tty_write */
7)+64.106 us | } /* vfs_write */
7)+64.611 us | } /* SyS_write */
17 de 21 06/04/2021 0:05
Tearing apart printf() – MaiZure's Projects http://www.maizure.org/projects/printf/index.html
$ ./printf1_s
Hello World 1
^Z
[1]+ Stopped ./printf1_s
$ top -o TTY
$ ls -l /dev/pts/0
crw--w----. 1 maizure tty 136, 0 Apr 1 09:55 /dev/pts/0
include/uapi/linux/major.h
...
#define UNIX98_PTY_MASTER_MAJOR 128
#define UNIX98_PTY_MAJOR_COUNT 8
#define UNIX98_PTY_SLAVE_MAJOR (UNIX98_PTY_MASTER_MAJOR+UNIX98_PTY_MAJOR_COUNT)
...
18 de 21 06/04/2021 0:05
Tearing apart printf() – MaiZure's Projects http://www.maizure.org/projects/printf/index.html
tty_insert_flip_string_fixed_flag()
(https://elixir.bootlin.com/linux/v3.10/source/drivers/tty/tty_buffer.c#L256)
if (port->low_latency)
flush_to_ldisc(&buf->work);
else
schedule_work(&buf->work);
19 de 21 06/04/2021 0:05
Tearing apart printf() – MaiZure's Projects http://www.maizure.org/projects/printf/index.html
tty_wakeup()
$ ./printf1_s
Hello World 1
20 de 21 06/04/2021 0:05
Tearing apart printf() – MaiZure's Projects http://www.maizure.org/projects/printf/index.html
$cat gdbcmds
start
stepi
stepi
stepi
stepi
...about 1000 more stepi...
21 de 21 06/04/2021 0:05