Cross compiling an empty program results in a segfault

Hello,

I’m trying to cross compile an empty program on macOS for Linux:

cat test.c

int main() {
int a = 2+3;
return 0;
}

clang -o -c -target x86_64-linux-gnu test.c

If I copy the resulting test.o to the Linux machine and run clang test.o, it works fine.

However if I try to link it on macOS, I get a segfault when I launch ./a.out

ld.lld --entry main test.o

[copy a.out to Linux]

./a.out
segmentation fault 0x00000000001 in ?? ()

Would really appreciate your help here!

Thanks

“–entry main” is not going to do what you want; the entry point for a Linux program is not equivalent to the C “main”. http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html has a description of how a C program normally starts on Linux.

Generally, to build a C program, you don’t want to invoke the linker directly; instead, use clang to invoke the linker correctly. This will pass the appropriate flags and link against the appropriate libraries. When you’re cross compiling, to make this work, you have to actually have the appropriate libraries, so you’ll have to build or download them separately. Then you tell clang the path to those libraries using –sysroot. https://clang.llvm.org/docs/CrossCompilation.html has a general description of various issues with cross-compiling.

-Eli

Sorry for the late reply.

Thanks, Eli. That was really helpful.

The reason I was trying to link it myself is because clang failed:

ld: unknown option: --eh-frame-hdr

My host is macOS, trying to compile for Linux:

clang -target x86_64-pc-linux-gnu -o main_linux main.c

main.c is an empty program with 0 dependencies.

I managed to do it with

ld.lld -v -o hi -m elf_x86_64 -dynamic-linker
/lib64/ld-linux-x86-64.so.2
/usr/lib/x86_64-linux-gnu/crt1.o
/usr/lib/x86_64-linux-gnu/crti.o
hi_lin.o
/usr/lib/x86_64-linux-gnu/libc.so
/usr/lib/x86_64-linux-gnu/crtn.o

I had to create /usr/lib/x86_64-linux-gnu/ directory on my Mac and copy about 8 libc files. This felt like a hack, but it worked.

You'll want to use a sysroot to accomplish this as Eli mentioned above :slight_smile:

-eric