1
votes

I am using clang assembly language output for a custom assembler and linker. I feel pretty comfortable with x86 mode, but not with x64 mode, where PC-relative addressing. Consider the following toy example.

C code:

void sum()
{
    static int a, b;
    static int c;
    c = a + b;
}

x86 output fragment:

sum:
    call    .L0$pb
.L0$pb:
    pop     EAX
.Ltmp0:
    add     EAX, _GLOBAL_OFFSET_TABLE_+(.Ltmp0-.L0$pb)
    mov     ECX, DWORD PTR [EAX + sum.a@GOTOFF]
    add     ECX, DWORD PTR [EAX + sum.b@GOTOFF]
    mov     DWORD PTR [EAX + sum.c@GOTOFF], ECX
    ret

x64 output fragment:

sum:
    mov     EAX, DWORD PTR [RIP + sum.a]
    add     EAX, DWORD PTR [RIP + sum.b]
    mov     DWORD PTR [RIP + sum.c], EAX
    ret

My question is: Is there any command line switch that would allow me to generate x64 code without using RIP-based addressing mode? If not, is it possible to modify the LLVM code to avoid RIP-based addressing mode generation for x64 mode and how?

1
Try compiling without position independent code (without -fPIC or similar flag - I got such code by default on Linux). I don't think use-case when relative addressing is used but you need a trick to get RIP as in first case (EAX in your example is just EIP at the beginning of call) is popular enough to get a flag - x86-64 code is simpler (no trick) and faster so from clang POV it's clear win (I understand that it's not from yours). Note that disabling address space randomization do disable some "defence in depth" you have.Maciej Piechotka
I am using the following command line: 'clang -cc1 -S -mllvm --x86-asm-syntax=intel -o - -triple x86_64-unknown-unknown xxx.c' What flag should I use to disable PIC?Dmitry K.
A final question: what is your problem with %rip-relative addressing? This is the kind of addressing the amd64-architecture was designed for.fuz
I need to feed instructions to an architectural simulator on the fly before everything has been generated. RIP-based addressing is very inconvenient for me.Dmitry K.

1 Answers

3
votes

You need to learn about x86-64 code model (see. e.g. X86-64 ABI doc or, e.g. http://eli.thegreenplace.net/2012/01/03/understanding-the-x64-code-models). By default the code model is small - everything is expected to be within 2Gb range and therefore rip-rel addressing should be used. If you won't want to use rip-rel addressing, then you need to use e.g. large code mode. Pass -mcmodel=large to clang and you're done.

PS: Intel asmprinter is of listing quality, the syntax is not expressive enough for the majority of apps, so, always use at&t.