The "Libc" library provides wrappers for most system calls and the "glue" code for the dynamic linker and userland process initialization. 1. Thread-local storage How thread-local variables are addressed and stored: http://www.technovelty.org/linux/debugging-__thead-variables-from-coredumps.html This post operates with core dumps for a reason: it is very hard to obtain the current values of segment descriptors (GDT) of a running process (see http://stackoverflow.com/questions/10354063/how-to-use-a-logical-address-in-gdb http://stackoverflow.com/questions/4006686/how-to-resolve-segmentoffset-adres-in-gdb). Note that this would be a great project. 2. Dynamic linking A very quick overview of structures involved in dynamic linking: http://thexploit.com/secdev/how-is-glibc-loaded-at-runtime/ A detailed analysis of dynamic linking: "Cheating the ELF" by the grugq, http://althing.cs.dartmouth.edu/local/subversiveld.pdf 3. Program startup An excellent step-by-step: "Linux x86 Program Start Up or - How the heck do we get to main()?" by Patrick Horgan http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html A old summary from a different angle: http://asm.sourceforge.net/articles/startup.html 4. Linker scripts and initial memory layout This example is from an embedded system with almost no kernel -- hence a very simple linker map (Listing 13): http://www.bravegnu.org/gnu-eprog/c-startup.html This is a chapter from http://www.bravegnu.org/gnu-eprog/index.html, a good book on programming tiny embedded computers (ARM-based "gumstix", literally the size of a pack of gum). Chapters 6 & 7 given very simple examples of linker operations: resolution, relocation.