skip to Main Content

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:

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

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

int not_main()
{
    printf("Entering %s:%sn", __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?

2

Answers


  1. Because of name mangling, the function is not not_main but _Z8not_mainv.

    how g++ can differ from gcc,

    What is the difference between g++ and gcc? why use g++ instead of gcc to compile *.cc files?

    Login or Signup to reply.
  2. 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:%sn", __FILE__, __func__);
        exit(0); // Necessary, otherwise it throws a segfault
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search