C Runtime
Mixing content from:
- Understanding the C Runtime: crt0, crt1, crti, and crtn
https://www.inferara.com/en/blog/c-runtime/ - Documentation from ulibc
https://github.com/kraj/uClibc/blob/master/docs/crt.txt - gcc docs
http://gcc.gnu.org/onlinedocs/gccint/Initialization.html
crt0.o / crt*.o the startup objects
Historically crt0.o (C Runtime Zero). Modern toolchains split crt0 and use
crt1.o (the primary startup object).
crt1.o: entry point; provides_startsymbolcrti.o: initialization; prologues of.initand.finitsectionscrtn.o: termination; epilogue of.initand.finitsections
crt1 Variants
Scrt1.o: used in place ofcrt1.oto generate PIEsgcrt1.o: used in place ofcrt1.oto generate profiling info. (seegprof)Mcrt1.o: likegcrt1.o; forprof; useless on Linuxgrcrt1.o,rcrt1.o: wtf
C++ constructor stuffs, I guess
crtbegin{,S,T}.oto find start of constructors (gcc);Sfor shared objects/PIEs. T for static executables.crtend{,S}.o: find start of destructors (gcc);
Instead of function calls, the startup objects are concatenated at link time.
General linking order:
crt1.o crti.o crtbegin.o [-L paths] [user objects] [gcc libs] [C libs] [gcc libs] crtend.o crtn.o
typical file locations
/usr/lib/{Scrt1, crt1, crti, crtn, gcrt1}.o/lib64/gcc/<m>/<v>/:crtbegin,crtend, etc.
notes
entry point + crt1.o / crt0.o- The
crt0/crt1provides the entry point_startfor the binary loader.
initialization + crti.o
- stack initialization, if not done by the kernel
- set up memory (data, BSS)
- prepare
argc,argvfor main - invoking constructors for global/static objects (C++)
- library initialization
- then calls
main(argc, argv, envp)
cleanup + crtn.o
- when
mainreturns, calls OS exit routines (e.g._exit)
$ readelf -s /usr/lib/crt1.o
Num: Value Size Type Bind Vis Ndx Name
0: [...] 0 NOTYPE LOCAL DEFAULT UND
1: [...] 0 SECTION LOCAL DEFAULT 1 .text
2: [...] 5 FUNC GLOBAL HIDDEN 1 _dl_relocate_sta[...]
3: [...] 38 FUNC GLOBAL DEFAULT 1 _start
4: [...] 0 NOTYPE GLOBAL DEFAULT UND main
5: [...] 0 NOTYPE WEAK DEFAULT 11 data_start
6: [...] 4 OBJECT GLOBAL DEFAULT 3 _IO_stdin_used
7: [...] 0 NOTYPE GLOBAL DEFAULT UND __libc_start_main
8: [...] 0 NOTYPE GLOBAL DEFAULT 11 __data_start
$ readelf -s /usr/lib/crti.o
Symbol table '.symtab' contains 4 entries:
Num: Value Size Type Bind Vis Ndx Name
0: [...] 0 NOTYPE LOCAL DEFAULT UND
1: [...] 0 NOTYPE WEAK DEFAULT UND __gmon_start__
2: [...] 0 FUNC GLOBAL HIDDEN 5 _init
3: [...] 0 FUNC GLOBAL HIDDEN 7 _fini