Search code examples
llvmllvm-irrelocationllcposition-independent-code

llc: unsupported relocation on symbol


Problem

llc is giving me the following error:

LLVM ERROR: unsupported relocation on symbol

Detailed compilation flow

I am implementing an LLVM frontend for a middle-level IR (MIR) of a compiler, and after I convert various methods to many bitcode files, I link them (llvm-link), optimize them (opt), convert them to machine code (llc), make them a shared library (clang for it's linker wrapper), and dynamically load them. llc step fails for some of the methods that I am compiling!

Step 1: llvm-link: Merge many bitcode files

I may have many functions calling each other, so I llvm-link the different bitcode files that might interact with each other. This step has no issues. Example:

llvm-link function1.bc function2.bc -o lnk.bc

Step 2: opt: Run optimization passes

For now I am using the following:

opt -O3 lnk.bc -o opt.bc

This step proceeds with no issues, but that's the one that CAUSES the problem! Also, it's necessary because in the future I will need this step to pass extra passes, e.g. loop-unroll

Step 3: llc: Generate machine code (PIC)

I am using the following command:

llc -march=thumb -arm-reserve-r9 -mcpu=cortex-a9 -filetype=obj -relocation-model pic opt.bc -o obj.o

I have kept the arch specific flags I've set just in case they contribute to the issue. I am using Position Independent Code because on next step I will be building a shared object. This command fails with the error I've written on top of this answer.

Step 4: clang: Generate Shared Object

For the cases that Step 3 fails, this step isn't reached. If llc succeeds, this step will succeed too!

Additional information

Configuration

The following run on an llvm3.6, which runs on an arm device.

Things I've noticed

  • If I omit -O3 (or any other level) with the opt step, then llc would work.
  • If I don't, and instead I omit them from llc, llc would still fail. Which makes me think that opt -O<level> is causing the issue.
  • If I use llc directly it will work, but I won't be able to run specific passes that opt allows me, so this is not a option for me.
  • I've faced this issue ONLY with 2 functions that I've compiled so far (from their original MIR), which use loops. The others produce working code!
  • If I don't use pic model at llc, it can generate obj.o, but then I'll have problems creating an .so from it!

Questions

  1. Why is this happening??!!

  2. Why opt has -relocation-model option? Isn't that supposed to be just an llc thing? I've tried setting this both at opt and llc to pic, but still fails.

  3. I am using clang because it has a wrapper to a linker to get the the .so. Is there a way to do this step with an LLVM tool instead?


Solution

  • First of all, do not use neither llc nor opt. These are developer-side tools that should be never used in any production environment. Instead of this, implement your own proper optimization and codegeneration runtime via LLVM libraries.

    As for this particular bug - the thumb codegenerator might contain some bugs. Please reduce the problem and report it. Or don't use Thumb mode at all :)