How to run linker after emitting LLVM object file

Viewed 165

I wrote a simple toy language compiler frontend that generates LLVM IR using llvm-sys (Rust bindings for LLVM's C library). I then generated an object file by creating a LLVMTargetMachine based on the machine's target triple then calling LLVMTargetMachineEmitToFile, which successfully generates an executable. However, running the executable produces zsh: exec format error: ./a.out.

I figured out that I had to run ld -lSystem ./a.out after generating the executable to make it work. How should I automatically call the linker in code?

Currently using LLVM 9.0 on macOS Catalina.

1 Answers

Indeed, LLVMTargetMachineEmitToFile produces an object file that still needs to be linked - either into an executable or shared library.

You need a linker for this, which is not, strictly speaking, a part of LLVM. LLVM's integrated linker operates on LLVM IR, not native machine code.

However, just like there is a LLVM-related C compiler, Clang, there also is a LLVM-related native linker called LLD. AFAIK, it can be used as a library, so you can imbue your compiler with integrated linked.

It worth noting that native compilers follow "pipeline" architecture, where the compiler itself and linker (and sometimes assembler too) are completely decoupled one from other. In such architecture, the compiler executable (like clang or g++) is actually a driver program that invokes other programs (cc1, the real compiler and ld, the linker) to produce the final binary.

Related