Problem: Generate binary file with llc

Hi,

I’m trying to generate an executable file for the code obtained with llc. The steps I follow are:

1 Generate a IR file (.ll)
$ clang -emit-llvm hello.c -S -o hello.ll

2 Generate an object file (.o)
$ llc hello.ll -filetype=obj -o hello.o

3 Execute hello.o (this produces an error)
$ ./hello.o
cannot execute binary file: Wrong executable format

However, if I see the executable format, it is the correct type:
$ objdump -f hello.o
hello.o: file format elf64-x86-64
architecture: i386:x86-64, options 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x0000000000000000

For example, if I generated an executable file with gcc:
$ gcc hello.c -o hello

$ objdump -f hello
hello: file format elf64-x86-64
architecture: i386:x86-64, options 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x0000000000000540

In addition, I also tried this step:
1 Generate an assembly code (.s)
$ llc hello.ll -o hello.s

2 Generate an executable file with gcc
$ gcc hello.s -o hello-gcc.o

But when I executed it, I had:
$ ./hello-gcc.o
./hello-gcc.o: Symbol printf' causes overflow in R_X86_64_PC32 relocation Segmentation fault (core’ generated)

I need obtained the execute file after using llc because I want to apply some pass availables with llc.

Anybody can help me?

This is the difference between an executable and an object file. The latter must be linked into the former.

After running llc you get a .o, which would be the equivalent of running clang/gcc with -c:

$ clang hello.c -c -o hello.o

Your step going through an assembly file is not far, I don’t know what is the problem with the incorrect relocation though.

At this point you couldn’t run hello.o either.

When you invoke clang (or gcc) without the -c option you are asking it to perform multiple steps: 1) compiler to an object file and then linking it.
You can see these individual steps by invoking clang with -v:

$ clang -v hello.c -o hello

You should see clang invoking clang -cc1 to produce a temporary .o object file, and then clang will invoke ld to produce the hello executable.

So after getting hello.o out of llc, you can get an executable by using clang to invoke the linker:

$ clang -v hello.o -o hello

Thank you so much!

Your explanation has been very useful for me.