3

On x86-64, how do I load an address from the .data section in a position independent manner (PIC and PIE compatible) when using the GNU assembler with intel syntax.

For example, using AT&T syntax, you can do this:

leaq mystring(%rip), %rdi

Is there an equivalent for Intel syntax? I can't seem to find the answer using search engines...

I am actually using the noprefix version of intel syntax, in case that makes a difference.

Thanks

nrz
  • 10,435
  • 4
  • 39
  • 71
Edd Barrett
  • 3,425
  • 2
  • 29
  • 48
  • Related, see [How to force NASM to address variables position-independent?](https://stackoverflow.com/q/34288482/608639) – jww Mar 18 '18 at 04:07

1 Answers1

2

An easy way to answer this is to assemble the instruction into an object file and disassemble it in Intel syntax. You might use a command something like objdump -d -Mintel test.o.

Doing it that way gives us:

Disassembly of section .text:

0000000000000000 <test>:
   0:   48 8d 3d 00 00 00 00    lea    rdi,[rip+0x0]        # 7 <test+0x7>

And that should be pretty clear. Note that mystring has turned into 0x0: those zeros are placeholder bytes which will be adjusted at link time using the relocation of mystring. In your assembly source, you would use an identifier there.

Edit: to make it more clear, here is an example source file:

    .intel_syntax noprefix
    .globl test
test:
    lea rdi, [rip+mystring]

And here is the disassembly (from objdump -rd -Mintel test.o). Note the PC-relative relocation:

0000000000000000 <test>:
   0:   48 8d 3d 00 00 00 00    lea    rdi,[rip+0x0]        # 7 <test+0x7>
                        3: R_X86_64_PC32    mystring+0xfffffffffffffffc
gsg
  • 9,167
  • 1
  • 21
  • 23
  • I'm not sure if I am missing something, but that does not help if I want to use an assembler to write x86-64 code (by hand). I can't just load [rip+0x0] every time I want to load something from .data -- the instruction does not encode which piece of data I want to load. – Edd Barrett Nov 14 '13 at 18:48
  • Of course you don't write `0x0`, you write the symbol that you want. The purpose is just to see what the syntax of the instruction is. – gsg Nov 14 '13 at 18:51
  • You can't just specify the symbol though, right? Without PIE/PIC I would have written (for example) `mov rdi, offset fmt`, but if you build that on a PIE setup (`-fpie -Wl,-pic`) then the assembler will complain that the code isn't position independent: `relocation R_X86_64_32S can not be used when making a shared object; recompile with -fPIC`. I'm not building a shared object, but that is the error you will get. On the other hand, `leaq mystring(%rip), %rdi` (in AT&T) generates PIC code and computes the offset for you. – Edd Barrett Nov 14 '13 at 18:56
  • I see. But those are the _exact same instruction_, just printed in different syntaxes: so something else is going on. – gsg Nov 14 '13 at 19:06
  • Hmm, perhaps I misunderstood your comment. `leaq symbol(%rip), %rdi` should be fine in PIC: it generates a `R_X86_64_PC32` relocation, and as far as I know, that should work ok in a `.so`. The syntax is more or less irrelevant. – gsg Nov 14 '13 at 19:21
  • It's useful to add `-r` to the objdump options when doing `-d` on a `.o` file. That shows you the relocations along with the instructions, so you will have an obvious indicator in examples like this when a `0x0` is really a symbol reference. –  Nov 15 '13 at 17:39
  • @gsg so the "offset" keyword in intel syntax should generate position independent code? – Edd Barrett Nov 21 '13 at 11:23
  • @vext01 no, the `offset` keyword indicates that an operand should refer to the address of a label and not the contents of memory at that label. This is same difference as between `movq foo, %rax` and `movq $foo, %rax`: note that neither instruction is position independent. – gsg Nov 21 '13 at 13:18
  • 1
    So, unless I am mistaken, we still have not answered the question and I'm not really sure what to make of the above. Could you perhaps post a hello world program in Intel noprefix gas syntax that (for example) loads the string "hello world" from the data section in a PIC/PIE compatible manner. This would greatly clarify. – Edd Barrett Nov 21 '13 at 16:46
  • 1
    I really don't understand how this is not clear. `leaq mystring(%rip), %rdi` in Intel syntax is `lea rdi, [rip+mystring]`. Both of them will generate a PC-relative relocation. There's nothing else to it. – gsg Nov 21 '13 at 16:54