Add R_X86_64_[REX_]GOTPCRELX support to gas and ld
authorH.J. Lu <hjl.tools@gmail.com>
Thu, 22 Oct 2015 11:49:20 +0000 (04:49 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Thu, 22 Oct 2015 11:49:38 +0000 (04:49 -0700)
commit56ceb5b5405af23eddd12e12d8ba849010120324
tree3404c0c3ed3df6a50bcb4bcf979e0bb276d84857
parent02a866936de7e63ad4962ccba56c8cd05c231275
Add R_X86_64_[REX_]GOTPCRELX support to gas and ld

This patch adds support for the R_X86_64_GOTPCRELX and
R_X86_64_REX_GOTPCRELX relocations proposed in

https://groups.google.com/forum/#!topic/x86-64-abi/n9AWHogmVY0

to gas and ld.  It updates gas to generate R_X86_64_GOTPCRELX,
R_X86_64_REX_GOTPCRELX if there is a REX prefix, relocation for memory
operand, foo@GOTPCREL(%rip).  With the locally defined symbol, foo, we
convert

  mov foo@GOTPCREL(%rip), %reg

to

   lea foo(%rip), %reg

and convert

   call/jmp *foo@GOTPCREL(%rip)
to

   nop call foo/jmp foo nop

When PIC is false, convert

   test %reg, foo@GOTPCREL(%rip)
to

test $foo, %reg

and convert

   binop foo@GOTPCREL(%rip), %reg

to

   binop $foo, %reg

where binop is one of adc, add, and, cmp, or, sbb, sub, xor instructions.

bfd/

* elf64-x86-64.c: Include opcode/i386.h.
(x86_64_elf_howto_table): Add R_X86_64_GOTPCRELX and
R_X86_64_REX_GOTPCRELX.
(R_X86_64_standard): Replace R_X86_64_PLT32_BND with
R_X86_64_REX_GOTPCRELX.
(x86_64_reloc_map): Add BFD_RELOC_X86_64_GOTPCRELX and
BFD_RELOC_X86_64_REX_GOTPCRELX.
(need_convert_mov_to_lea): Renamed to ...
(need_convert_load): This.
(elf_x86_64_check_relocs): Handle R_X86_64_GOTPCRELX and
R_X86_64_REX_GOTPCRELX.  Replace need_convert_mov_to_lea with
need_convert_load.
(elf_x86_64_gc_sweep_hook): Handle R_X86_64_GOTPCRELX and
R_X86_64_REX_GOTPCRELX.
(elf_x86_64_size_dynamic_sections): Likewise.
(elf_x86_64_relocate_section): Likewise.
(elf_x86_64_convert_mov_to_lea): Renamed to ...
(elf_x86_64_convert_load): This.  Replace need_convert_mov_to_lea
with need_convert_load.  Support R_X86_64_GOTPCRELX and
R_X86_64_REX_GOTPCRELX transformations.
* reloc.c (BFD_RELOC_X86_64_GOTPCRELX): New.
(BFD_RELOC_X86_64_REX_GOTPCRELX): Likewise.
* bfd-in2.h: Regenerated.
* libbfd.h: Likewise.

gas/

* config/tc-i386.c (tc_i386_fix_adjustable): Handle
BFD_RELOC_X86_64_GOTPCRELX and BFD_RELOC_X86_64_REX_GOTPCRELX.
(tc_gen_reloc): Likewise.
(i386_validate_fix): Generate BFD_RELOC_X86_64_GOTPCRELX or
BFD_RELOC_X86_64_REX_GOTPCRELX if fx_tcbit2 is set.
* config/tc-i386.h (TC_FORCE_RELOCATION_LOCAL): Also return
true for BFD_RELOC_X86_64_GOTPCRELX and
BFD_RELOC_X86_64_REX_GOTPCRELX.

gas/testsuite/

* gas/i386/i386.exp: Run x86-64-gotpcrel.
* gas/i386/x86-64-gotpcrel.d: New file.
* gas/i386/x86-64-gotpcrel.s: Likewise.
* gas/i386/ilp32/x86-64-gotpcrel.d: Likewise.
* gas/i386/x86-64-localpic.d: Replace R_X86_64_GOTPCREL with
R_X86_64_REX_GOTPCRELX.
* gas/i386/ilp32/x86-64-localpic.d: Likewise.

include/elf/

* x86-64.h (R_X86_64_GOTPCRELX): New.
(R_X86_64_REX_GOTPCRELX): Likewise.

ld/testsuite/

* ld-ifunc/ifunc-5r-local-x86-64.d: Replace R_X86_64_GOTPCREL
with R_X86_64_REX_GOTPCRELX.
* ld-x86-64/plt-main1.rd: Likewise.
* ld-x86-64/plt-main3.rd: Likewise.
* ld-x86-64/plt-main4.rd: Likewise.
* ld-x86-64/gotpcrel1.dd: New file.
* ld-x86-64/gotpcrel1.out: Likewise.
* ld-x86-64/gotpcrel1a.S: Likewise.
* ld-x86-64/gotpcrel1b.c: Likewise.
* ld-x86-64/gotpcrel1c.c: Likewise.
* ld-x86-64/gotpcrel1d.S: Likewise.
* ld-x86-64/load1.s: Likewise.
* ld-x86-64/load1a.d: Likewise.
* ld-x86-64/load1b.d: Likewise.
* ld-x86-64/load1c.d: Likewise.
* ld-x86-64/load1d.d: Likewise.
* ld-x86-64/x86-64.exp: Run load1a, load1b, load1c and load1d
tests.  Run gotpcrel1 test.
34 files changed:
bfd/ChangeLog
bfd/bfd-in2.h
bfd/elf64-x86-64.c
bfd/libbfd.h
bfd/reloc.c
gas/ChangeLog
gas/config/tc-i386.c
gas/config/tc-i386.h
gas/testsuite/ChangeLog
gas/testsuite/gas/i386/i386.exp
gas/testsuite/gas/i386/ilp32/x86-64-gotpcrel.d [new file with mode: 0644]
gas/testsuite/gas/i386/ilp32/x86-64-localpic.d
gas/testsuite/gas/i386/x86-64-gotpcrel.d [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-gotpcrel.s [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-localpic.d
include/elf/ChangeLog
include/elf/x86-64.h
ld/testsuite/ChangeLog
ld/testsuite/ld-ifunc/ifunc-5r-local-x86-64.d
ld/testsuite/ld-x86-64/gotpcrel1.dd [new file with mode: 0644]
ld/testsuite/ld-x86-64/gotpcrel1.out [new file with mode: 0644]
ld/testsuite/ld-x86-64/gotpcrel1a.S [new file with mode: 0644]
ld/testsuite/ld-x86-64/gotpcrel1b.c [new file with mode: 0644]
ld/testsuite/ld-x86-64/gotpcrel1c.c [new file with mode: 0644]
ld/testsuite/ld-x86-64/gotpcrel1d.S [new file with mode: 0644]
ld/testsuite/ld-x86-64/load1.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/load1a.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/load1b.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/load1c.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/load1d.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/plt-main1.rd
ld/testsuite/ld-x86-64/plt-main3.rd
ld/testsuite/ld-x86-64/plt-main4.rd
ld/testsuite/ld-x86-64/x86-64.exp