The run-time environment calls the
mainfunction to begin program execution.
On Linux operating system, C runtime file can be found in either /usr/lib directory or /lib directory.
crt0 (or crt0.o, gcrt0.o, mcrt0.o) is a set of execution startup routines that are platform-dependent, and is required in order to compile using the GCC and other GNU tools.
crt stands for 'C runtime'.
Let me explain you the life cycle of c program:
1. Create a C program
2. Compile C program to generate object file.
3. Link object files (s)
4. execute the program
During compilation, compiler generates the object code for the program and for standard C library functions used in program such as printf(), scanf (), etc, it puts the entry in object file saying that "unresolved reference".
Linking can be static or dynamic. During static linking,
the static linker (ld) sees the unresolved reference to printf(), scanf(), and searches the available libraries for an implementation for printf(), scanf(), etc. In general this will be found in the C library (for example, libC ). Now, the linker has two options:
Linker can take the printf(), scanf(), implementation from the library and copy it into the final executable accordingly. The linker then searches the printf(), scanf() implementation for other unresolved references, and again consult the libraries for resolution. This process will be performed iteratively until all references to the symbols were resolved. This is known as static linking.
If the C library is realized as a `shared library', the linker can simply put a reference to the C library into the final executable. This is known as dynamic linking.
A statically linked executable is self contained. It is loaded into memory. The entry point, whose designation is system dependent (for eg, the `__main' symbol) is found and called. In a dynamically linked executable, after loading the executable binary into memory, the dynamic linker (ld.so.1) takes control first. It reads the library references to dynamic libraries produced by the static linker, and loads them into memory. It then performs symbol resolution and updates all references to symbols in the shared library to point to their actual location, which can only be determined at runtime, because the shared libraries might be loaded to different memory locations each time the executable binary gets executed.