Wie kann ich mit Clang unter OS X Mavericks einen benutzerdefinierten C-Einstiegspunkt festlegen?

Wie kann ich mit Clang unter OS X Mavericks einen benutzerdefinierten C-Einstiegspunkt festlegen?


Ich habe folgendes Programm:


#include <stdio.h>
int bob() {
printf("bob\n");
return 0;
}
int main() {
printf("main\n");
return 0;
}

Unter Linux kann ich einen benutzerdefinierten Einstiegspunkt aktivieren über:


gcc test.c -Wl,-e,bob

Wenn ich das resultierende Programm ausführe, erhalte ich:


./a.out
bob

Unter OS X funktioniert dies jedoch nicht:


clang test.c -Wl,-e,bob
./a.out
main

Ich habe alles versucht, um dies zum Laufen zu bringen. Ich denke es könnte ein Bug sein. Hier ist die Ausgabe mit dem -v Möglichkeit:


clang test.c -Wl,-e,bob -v
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.3.0
Thread model: posix
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" -cc1 -triple x86_64-apple-macosx10.9.0 -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -main-file-name test.c -mrelocation-model pic -pic-level 2 -mdisable-fp-elim -masm-verbose -munwind-tables -target-cpu core2 -target-linker-version 236.3 -v -resource-dir /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/5.1 -fdebug-compilation-dir /Users/mfichman/jogo -ferror-limit 19 -fmessage-length 125 -stack-protector 1 -mstackrealign -fblocks -fobjc-runtime=macosx-10.9.0 -fencode-extended-block-signature -fdiagnostics-show-option -fcolor-diagnostics -vectorize-slp -o /var/folders/4z/q41by0256hjc7s6v8ljmfpw8lywh5g/T/test-9b80a6.o -x c test.c
clang -cc1 version 5.1 based upon LLVM 3.4svn default target x86_64-apple-darwin13.3.0
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/5.1/include
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
/usr/include
/System/Library/Frameworks (framework directory)
/Library/Frameworks (framework directory)
End of search list.
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld" -demangle -dynamic -arch x86_64 -macosx_version_min 10.9.0 -e bob -o a.out /var/folders/4z/q41by0256hjc7s6v8ljmfpw8lywh5g/T/test-9b80a6.o -lSystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/5.1/lib/darwin/libclang_rt.osx.a

Sie können diesen clang sehen -e korrekt übergibt bis ld , vielleicht ist dies ein Problem mit Apples ld . Wenn das der Fall ist, wäre ich an Workaround-Lösungen interessiert.


Antworten:


Der standardmäßige Einstiegspunkt, der durch -e überschrieben wird Argument ist nicht _main sondern start , der für das Einrichten und Aufrufen von _main verantwortlich ist , und dann den Rückgabewert von _main übergeben bis _exit . Wenn Sie Ihren eigenen Einstiegspunkt angeben, müssen Sie diese Schritte selbst ausführen. Es gibt derzeit keine Möglichkeit, diese Initialisierung für Sie durchführen zu lassen, sondern eine andere Hauptfunktion als die Verwendung von _main zu verwenden ist in den Tools fest codiert.


Der Grund, warum Ihr -e-Argument ignoriert wird, liegt an einer Änderung in 10.8. Vor dieser Version die Implementierung von start wurde in jede Anwendung über crt1.o eingebunden . In 10.8 der start Die Verarbeitung kann mit dyld durchgeführt werden, und der Ladebefehl LC_MAIN gibt den Offset zur Hauptfunktion innerhalb des Programms an. Das Ändern dieses Offsets scheint das zu sein, was Sie möchten, aber dies ist derzeit nicht möglich, da bei Verwendung der LC_MAIN-Startmethode ld immer _main verwendet und ignoriert den -e Streit. Um Ihren eigenen Einstiegspunkt festzulegen, müssen Sie ld anweisen, die alte Methode des Programmstarts zu verwenden, was Sie für eine Anwendung mit einem Bereitstellungsziel von 10.8 oder höher tun können, indem Sie -no_new_main übergeben zum Linker. Dies ist das Standardverhalten für Anwendungen mit einem Bereitstellungsziel vor 10.8.