Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why does -Wl,–entry work with gcc, but not g++?

I am trying to compile a program so that it starts on a different entry point. I am running WSL1 with Ubuntu 20.04.5, and GCC and G++ 9.4.0

I found that adding the flag -Wl,--entry=foo to the compiler will link foo() as the entry function. Testing, this has worked with gcc, but not with g++.

Using the example file src/main.c:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

#include <stdlib.h>
#include <stdio.h>

int main()
{
    printf("Entering %s:%s\n", __FILE__, __func__);
    return 0;
}

int not_main()
{
    printf("Entering %s:%s\n", __FILE__, __func__);
    exit(0); // Necessary, otherwise it throws a segfault
}

When compiled with gcc -Wl,--entry=not_main -o entry.o src/main.c the output is what I want: Entering src/main.c:not_main.

However, when compiled with g++ -Wl,--entry=not_main -o entry.o src/main.c, the following warning appears: /usr/bin/ld: warning: cannot find entry symbol not_main; defaulting to 0000000000001080.

This defaults to the main() function, outputting Entering src/main.c:main. The function not_main() is not found by the linker, but it is present in the source code.

The documentation for g++ says:

g++ is a program that calls GCC and automatically specifies linking against the C++ library.

I don’t see how g++ can differ from gcc, if internally one calls the other. I understand that it is not the compiler but the linker which changes the entry point, and that g++ (unlike gcc) is linking against the C++ library, but I fail to understand how that is problematic.

What am I missing?

>Solution :

C++, unlike C, uses name mangling to distinguish different overloads of the same function name.

When compiled with gcc:

$ objdump -t entry.o | grep not_main
000000000000117c g     F .text  0000000000000036              not_main

When compiled with g++:

$ objdump -t entry.o | grep not_main
0000000000000000         *UND*  0000000000000000              not_main
000000000000117c g     F .text  0000000000000036              _Z8not_mainv

The *UND*efined reference to not_main was probably placed there by the linker since you requested this as the entry point. The actual not_main function has its name mangled to _Z8not_mainv.

To export not_main under its original name, use extern "C":

extern "C" int not_main()
{
    printf("Entering %s:%s\n", __FILE__, __func__);
    exit(0); // Necessary, otherwise it throws a segfault
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading