I'm developing an OS kernel as a hobby and I already have a library that replaces the standard library in both hosted and freestanding environments. Naturally it provides the entry point that does the necessary set up and calls main()
.
In hosted environment it seems that it doesn't matter if the signatures of the main()
declaration and in the actual main()
definition doesn't exactly match. However, once I add the -ffreestanding
compilation flag, the linker can no longer resolve such reference. See the minimal example below:
start.cpp
int main(int argc, char *argv[], char *envp[]);
extern "C" void _start()
{
main(0, nullptr, nullptr);
}
main.cpp
int main()
{
return 0;
}
Command line:
clang++-6.0 -nostdlib -ffreestanding start.cpp main.cpp
It seems that this behavior is specific to Clang since GCC 7.3.0 compiles this example successfully.
My question is how the above example is allowed and working in general and whether the issue I'm experiencing is a Clang bug.
Update 1:
Turned out that the solution to this is to add __attribute__((weak))
to the declaration of main()
. However, it would be nice if someone could explain in more detail how does this usually work with main()
.
Update 2:
Apparently marking main()
as a weak symbol makes it possible to link without main()
at all which is obviously not how it normally works (given all the other "undefined reference to main" questions on SO). So if main()
is not usually a weak symbol how does it really work?
Update 3:
Turns out that a weak symbol is not a solution at all, because when used with -ffreestanding
it only hides the fact that the int main(int argc, char *argv[], char *envp[])
is never resolved and the actual int main()
is not called from _start()
at all. In hosted environment, however it's still called as usual. This seems more and more like a Clang bug.