movl x@GOTPCREL+4(%rip), %eax

Fangrui Song i@maskray.me
Tue Nov 24 17:42:50 GMT 2020


Clang emits movl x@GOTPCREL+4(%rip), %eax for the following code:

   void x();
   int foo() { return (long)x >> 32; }

3 questions:

* Is movl x@GOTPCREL+4(%rip) valid?
* If no, should GNU as reject the expression?
* If yes, should GNU as emit an R_X86_64_GOTPCRELX instead of R_X86_64_GOTPCREL? (If yes, ideally x86-64 psABI should document that this case cannot be optimized)
* If yes, gold should be fixed to not relax R_X86_64_GOTPCRELX if the
   addend is not -4


Let's compare the -no-pie linked output of `movl foo@GOTPCREL(%rip), %eax; movl foo@GOTPCREL+4(%rip), %eax`:

GNU ld (the second instruction loads the high 32-bit address):

0000000000401000 <foo-0xd>:
   401000:       48 c7 c0 0d 10 40 00    mov    rax,0x40100d
   401007:       8b 05 ef 1f 00 00       mov    eax,DWORD PTR [rip+0x1fef]        # 402ffc <.got+0x4>

gold (the second instruction loads the address of foo plus 4):

00000000004000e8 <foo-0xd>:
   4000e8:       48 8d 05 06 00 00 00    lea    rax,[rip+0x6]        # 4000f5 <foo>
   4000ef:       8d 05 04 00 00 00       lea    eax,[rip+0x4]        # 4000f9 <foo+0x4>


More information about the Binutils mailing list