I'm back with C/C++ and ASM and I want to play a little bit with fire. I found out that when you compile and link code into an executable for Windows it is dynamically linked to some libraries that must exists on any computer where that application is expected to run. You can specify the compiler to not link against them and create your own libraries for that.
Apart from that (and please, correct me if I'm wrong in everything I say here) there's an object file that is always complied and linked along the main code of our app. It is the crt0.o (the C runtime) file and, as I know, it prepares the stack, get argc and argv and call the main function (and maybe other things). I also believe it is the first piece of code called by the system when executing the application.
So, I am trying to create a simple crt0.obj and link it against a simple C++ object file
int main(int argc, char** argv) {
return 0;
}
I use GCC and I want to make use of no standard library, so my command looks like:
g++ -s -nostartfiles -nodefaultlibs -nostdlib testapp.cpp -o test.exe crt0.o
I suppose that the -nostartfiles directive is what tells the linker to not embed the default crt0.o, so it expects me to give every definition for any function and handle the start-up of the application. I am a little confused here.
Anyway, I want to create a very basic crt0 object file, that will be enough for GCC to create my executable, and for the system to start it. I know there are many code files (C and ASM) on the Internet but I want to write my own in order to learn how it works. More than code what I need is a little help on what must it do and how to compile/link in order to achieve it. If you know any helpful link that is also very appreciated.
My doubts are:
1. How does the compiler/link create the final file from my code and the C runtime? Do I have to call the main function from crt0.o (using an extern directive)? When I execute g++ -s -nostartfiles -nodefaultlibs -nostdlib testapp.cpp -o test.exe
I get "*undefined reference to __main*" error. Is the main function defined in the crt0.o file? It's strange that if I change int main
by int start
I don't get any error. What does that mean?
2. Which are the essential operations that a crt0 must contain (like getting command-line arguments, calling main)?
3. My code file is CPP and the crt0 is a piece of assembly inside a C file (compiled with GCC). I will post some "frankencode" I managed to create from pieces I found and partially understood:
// crt0.c
__asm(".section .text\n"
".global _start\n"
"_start:\n"
"mov $0, %ebp\n"
"push %ebp\n"
"mov %esp, %ebp\n"
"push %esi\n"
"push %edi\n"
"call _init\n"
"pop %edi\n"
"pop %esi\n"
"call main\n"
"movl %eax, %edi\n"
"call exit\n"
".section .init\n"
".global _init\n"
"_init:\n"
"push %ebp\n"
"mov %esp, %ebp\n"
".section .fini\n"
".global _fini\n"
"_fini:\n"
"push %ebp\n"
"mov %esp, %ebp\n");
4.) So, in this file, I made some calls to initialization functions. The init and fini functions are already created (they look like simple constructors and destructors, I don't know) There's also the main function, which I don't know how is related to the .cpp main function. I mean, am I supposed to import it? I get undefined reference
errors for both main and exit functions.
5.) Must the c0 have a specific format or contain a specific function so the system find its start?
Well, I don't see it difficult to make a small crt0 and make the compiler attach it to the executable, but there are some things I am not able to see correctly. I hope somebody can help me fit all this together. Thanks