[llvm-dev] Quick question: How to BuildMI mov64mi32 arbitrary MMB address to memory

Tim Northover via llvm-dev llvm-dev at lists.llvm.org
Sat Sep 22 11:46:04 PDT 2018


Hi,

On Sat, 22 Sep 2018 at 19:25, K Jelesnianski via llvm-dev
<llvm-dev at lists.llvm.org> wrote:
> /usr/bin/ld: /tmp/foo-d523b6.o: relocation R_X86_64_32S against `.text' can not be used when making a shared object; recompile with -fPIC
> /usr/bin/ld: final link failed: Nonrepresentable section on output

The issue is that you're presumably building in position-independent
mode (PIC). Shared libraries are almost always built like this, and a
lot of executables these days to aid ASLR.

Anyway, because of that you can't directly reference the absolute
address of a basic block from the .text section because that's
supposed to be read-only and so couldn't be fixed up by ld-linux or
dyld.

The solution is to instead calculate the address of the block relative
to %rip, which can't be stored in the same instruction (it'd have two
addressing-mode operands, which no x86 instruction does). So instead
it'd be a lea/mov pair (and you'll need a scratch register).

To get the exact form, it's useful to compile a simple .ll file:

    define void @foo(i8** %addr) {
      br label %next
    next:
      store i8* blockaddress(@foo, %next), i8** %addr
      ret void
    }

$ bin/llc -relocation-model=pic simple.ll -o -
[...]
        leaq    .Ltmp0(%rip), %rax
        movq    %rax, (%rdi)

You seem to be reasonably OK with BuildMI so I'm not going to try and
translate that to C++. And yes, addMBB is the one you want for that
operand.

> The BuildMI looks like:
>
> BuildMI(MBB, MBIt, DL, TII->get(X86::MOV64mi32))
> .addImm(0x1) // Scale
> .addReg(X86::RSP) // Base
> .addImm(0x8) // Disp
> .addMBB(my_target_mbb); // Source

This looks like some operands might be wrong to me. Aren't the x86
addressing-mode operands [base, scale, index,disp, segment]?

Cheers.

Tim.


More information about the llvm-dev mailing list