I'm trying to understand how printf works in C for a simple case. I wrote the following program:
#include "stdio.h"
int main(int argc, char const *argv[])
{
printf("Test %s\n", argv[1]);
return 0;
}
Running objdump on the binary I noticed the Test %s\n resides in .rodata
objdump -sj .rodata bin
bin: file format elf64-x86-64
Contents of section .rodata:
08e0 01000200 54657374 2025730a 00 ....Test %s..
So formatted print seems to perform additional pattern copying from rodata to somewhere else.
After compiling and running it with stare ./bin rr I noticed a brk syscall before the actual write. So running it with
gdb catch syscall brk
gdb catch syscall write
shows that in my case the current break equals to 0x555555756000, but it then sets to 0x555555777000. When the write occurs the formatted string
x/s $rsi
0x555555756260: "Test rr\n"
Resides between the "old" and "new" break. After the write occurs the programs exits.
QUESTION: Why do we allocate so many pages and why didn't the break returns to the previous one after write syscall occurs? Is there any reason to use brk instead of mmap for such formatting?