title: Startup code of a statically-linked executable issues so many system calls?
body: <p>I am experimenting by statically compiling a minimal program and examining the system calls that are issued:</p>
  
  <pre><code>$ cat hello.c
  #include &lt;stdio.h&gt;
  
  int main (void) {
    write(1, "Hello world!", 12);
    return 0;
  }
  
  $ gcc hello.c -static
  
  $ objdump -f a.out
  a.out:     file format elf64-x86-64
  architecture: i386:x86-64, flags 0x00000112:
  EXEC_P, HAS_SYMS, D_PAGED
  start address 0x00000000004003c0
  
  $ strace ./a.out
  execve("./a.out", ["./a.out"], [/* 39 vars */]) = 0
  uname({sys="Linux", node="ubuntu", ...}) = 0
  brk(0)                                  = 0xa20000
  brk(0xa211a0)                           = 0xa211a0
  arch_prctl(ARCH_SET_FS, 0xa20880)       = 0
  brk(0xa421a0)                           = 0xa421a0
  brk(0xa43000)                           = 0xa43000
  write(1, "Hello world!", 12Hello world!)            = 12
  exit_group(0)                           = ?
  </code></pre>
  
  <p>I know that when linked non-statically, <code>ld</code> emits startup code to map <code>libc.so</code> and <code>ld.so</code> into the process's address space, and <code>ld.so</code> would continue loading any other shared libraries.</p>
  
  <p>But in this case, why are so many system calls issued, apart from <code>execve</code>, <code>write</code> and <code>exit_group</code>?</p>
  
  <p>Why the heck <code>uname(2)</code>? Why so many calls to <code>brk(2)</code> to get and set the program break, and a call to <code>arch_prctl(2)</code> to set the process state, when that seems like something that should have been done in kernel-space, at <code>execve</code> time?</p>