skaht / Csu-85

Looking for crt0.o for Mac OSX?
51 stars 11 forks source link

Undefined symbols for architecture x86_64: "_exit", referenced from: start in crt0.o #2

Open zhangyubaka opened 7 years ago

zhangyubaka commented 7 years ago

System: 10.12.6 Xcode 8.3.3 After make ARCH_CFLAGS=-I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include,I tried a simple c program.

#include <stdio.h>
int main()
{
   printf("Hello, World!");
   return 0;
}

what I get is

Undefined symbols for architecture x86_64:
  "_exit", referenced from:
      start in crt0.o
  "_printf", referenced from:
      _main in test-c7a783.o
ld: symbol(s) not found for architecture x86_64
ylluminarious commented 6 years ago

@zhangyubaka @skaht

I had the same problem as well, but I managed to work around it by using gcc from Homebrew. The root issue with Csu-85 is that crt0.o cannot link with libc. This is explained in the original man gcc which used to be included with OS X (emphasis mine):

-static On systems that support dynamic linking, this prevents linking with the shared libraries. On other systems, this option has no effect.

This option will not work on Mac OS X unless all libraries (including libgcc.a) have also been compiled with -static. Since neither a static version of libSystem.dylib nor crt0.o are provided, this option is not useful to most people.

All that Csu-85 provides is a static version of crt0.o. This solves part of the problem, but not all of it. See, there is no official version of libc on OS X other than libc.dylib, which is just a symlink to libSystem.dylib. As mentioned above, there is no static version of libSystem.dylib. And that means there is no static version of libc for crt0.o to link with, which causes the errors about missing functions.

I guess that Csu is intended to be used for kernel development or something like that, especially given the explicit usage of -nostdlib in the Makefile. Maybe Apple uses it for XNU to bootstrap the kernel. And then they define all of the standard functions and libraries that they need inside the kernel so they never run into this issue. They really could be using Csu for kernel development since it's been around since 10.0, but take my word with a grain of salt since I'm not a kernel developer or an Apple employee.

Anyway, until Apple provides a static version of libSystem.dylib, it is not possible to have a purely static binary on OS X. However, someone on StackOverflow managed to get a partially static binary by using gcc from Macports. I.e., they were able to statically link the libgcc runtime to their object file. I was able to do the same thing by using gcc from Homebrew.

E.g.:

$ cat hello_world.c 
#include <stdio.h>
main() {
     printf("hello, world\n");
}

$ gcc-7 hello_world.c 
hello_world.c:2:1: warning: return type defaults to 'int' [-Wimplicit-int]
 main() {
 ^~~~

$ otool -L a.out        
a.out:
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.0.0)
    /usr/local/lib/gcc/7/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)

$ gcc-7 -static-libgcc hello_world.c
hello_world.c:2:1: warning: return type defaults to 'int' [-Wimplicit-int]
 main() {
 ^~~~

$ otool -L a.out                    
a.out:
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.0.0)

As you can see, -static-libgcc causes libgcc to be statically linked to my object file, although libSystem.B.dylib is still dynamically linked.

zhangyubaka commented 6 years ago

At last, I’ve managed to get a static libc and static libsystem_kernel(for syscall) from apple opensource ,but some symbols are still missing,like write nocancel

ylluminarious commented 6 years ago

@zhangyubaka Did you compile this libc and this libsystem? Just curious.

zhangyubaka commented 6 years ago

@ylluminatious Yes, in order to compile you need follow instructions for xnu kernel.

ylluminarious commented 6 years ago

@zhangyubaka Ok, I see.

ylluminarious commented 6 years ago

Well, I've got to hand it to Apple: they went totally out of their way to make it insanely difficult to statically link system binaries.

zhangyubaka commented 6 years ago

@ylluminarious Sorry didn’t see your edition :< The libsystem_kernel source is in xnu tree, https://opensource.apple.com/source/xnu/xnu-4570.1.46/libsyscall/

zhangyubaka commented 6 years ago

Yes, since most libs are missing their static version

ylluminarious commented 6 years ago

Sorry for the frequent editing... I'm somewhat scatterbrained right now and made some typos :P

Thanks for the link!

ylluminarious commented 6 years ago

@zhangyubaka I guess you made a blog post about this stuff at this link, right?

zhangyubaka commented 6 years ago

@ylluminarious Ah that post was just some notes for my self… I suggest you take a look at https://github.com/PureDarwin , they have a lot tutorials

ylluminarious commented 6 years ago

@zhangyubaka Yeah, it seems that all things lead to PureDarwin when it comes to poking around in Mac OS's insides :D

zhangyubaka commented 6 years ago

@ylluminarious And don’t forget to keep a copy of your original macosx.sdk :>

ylluminarious commented 6 years ago

Yes, I forgot about that.