Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I change entry point for a mach-o executable for a c++ file?

Tags:

c++

clang

mach-o

I am trying to write a c++ program without main. Is it possible to change the entry point of a mach-o executable to a custom function (other than main())?

If not, then, is it possible to wrap main to call my version of main before the actual C main is called?

Edit:

I want to my custom function to call the C main. If I gave it a constructor attribute or added it to ctor list then main will be called twice. I do not want that to happen.

P.S I'm building executables in Mac OS X High Sierra with clang version 9.1.0

like image 710
Rohit Avatar asked Sep 01 '25 01:09

Rohit


1 Answers

You can use the -e <symbol> option of ld, which you can invoke as -Wl,-e,_<symbol> from clang. Historically, the entry point of a program would be _start from crt0.o, however that has not been a thing on Darwin since Mac OS X 10.8 and iOS 6.0, where the LC_MAIN load command was introduced (replacing LC_UNIXTHREAD). The "old" way can still be used, but would have to be explicitly enabled with the -no_new_main linker flag (which has a counterpart -new_main, should you ever need it). The duty once carried by crt0.o has been shifted to the dynamic linker, /usr/lib/dyld, which can handle both LC_MAIN and LC_UNIXTHREAD as needed.

So given a C program with a main:

// t.c
#include <stdio.h>

int main(int argc, const char **argv)
{
    printf("test %i\n", argc);
    return 0;
}

You can easily create a C++ file like this:

// t.cpp

extern int main(int, const char**);

extern "C" int derp(int argc, const char **argv)
{
    return main(0, (const char*[]){ (const char*)0 });
}

And compile them with clang++ -o t t.cpp -xc t.c -Wl,-e,_derp.
Just be sure to either declare derp as extern "C", or specify the mangled symbol on the command line.

You can also inspect the resulting executable with otool to make sure it uses LC_MAIN rather than LC_UNIXTHREAD:

bash$ otool -l ./t | fgrep -B1 -A3 LC_MAIN
Load command 11
       cmd LC_MAIN
   cmdsize 24
  entryoff 3808
 stacksize 0
like image 95
Siguza Avatar answered Sep 02 '25 17:09

Siguza