Process creation

Main source: "How programs get run", on lwn 1, 2. READ THIS FIRST

There are a few details that are crucial for sizecoding stuff. On program entry:

  • PT_LOAD phdrs allocate memory, or map data or code from the executable into memory.
  • PT_INTERP makes the kernel load a second program and execute that one, after mapping the first one into memory.
  • The kernel doesn't care about other phdrs.
  • There is a minimum address for memory mapping, addresses lower than this value cannot be mapped into userspace memory. This config is available at /proc/sys/vm/mmap_min_addr, but can only be written to by root.
  • The kernel maps pages, not bytes, so the size fields in a phdr are always aligned to the next page. Bytes that are not mapped from a file, or are "loaded" after the end of the file, are set to zero.
  • Pretty much all registers that aren't a stack pointer or program counter are set to zero. This is NOT true when doing dynamic linking!
  • On x86_64 (and maybe i386?), the stack is aligned to 16 bytes . The x86_64 calling convention says that the stac pointer mod 16 must be 8 when calling a function. SIMD instructions sometimes require 16-byte alignment . Data on which SIMD instructions are working is sometimes stored on the stack. This means that, if you do not manually realign the stack, crashes will happen when doing SIMD. This code may be in libraries you're depending on, and depending on the distro, libraries may or may not be compiled with SIMD instructions! This can be fixed with one byte: push rax.
  • Lots of interesting data is placed on the stack at program entry. See the second lwn article for details.
  • For dynamic linking-related stuff on program entry, see this page