Optimize x86 GOT32X/GOTPCRELX relocations
authorH.J. Lu <hjl.tools@gmail.com>
Fri, 26 Feb 2016 17:38:08 +0000 (09:38 -0800)
committerH.J. Lu <hjl.tools@gmail.com>
Fri, 26 Feb 2016 17:39:24 +0000 (09:39 -0800)
commitbae420ef26f4331415b0503141c5931318025906
tree997f55c531ebd08c7220d5fe523d3df00b709f87
parentfc5a9bd57cbb974b8fc3aeb9a15d644cd9103451
Optimize x86 GOT32X/GOTPCRELX relocations

R_386_GOT32X, R_X86_64_GOTPCRELX and R_X86_64_REX_GOTPCRELX relocations
retrieve the symbol address via its GOT slot.  If the symbol address is
known at the link-time, we can use it directly by changing instruction
encoding.  Indirect branch can only be converted to PC relative direct
branch.  MOV can be changed to LEA or encoded differently with signed
address.  The subset of binary operations can be encoded only with
signed address.

If undefined weak symbol is resolved to zero link-time, we can use it
as address.  Zero addresss can't used with PC relative direct branch
when PIC is true since the current PC is unknown.  In 64-bit, 32-bit
relocation for PC relatiave direct branch to zero may also overflow.

If this optimization causes relocation overflow, --no-relax can be used
to work around it.

bfd/

PR ld/19609
* elf32-i386.c (elf_i386_convert_load): Convert to R_386_32 for
load with locally bound symbols if PIC is false or there is no
base register.  Optimize branch to 0 if PIC is false.
(elf_i386_relocate_section): Don't generate dynamic relocations
against undefined weak symbols if PIC is false.
* elf64-x86-64.c (elf_x86_64_convert_load): Disable optimization
if we can't estimate relocation overflow with --no-relax.
Convert to R_X86_64_32S/R_X86_64_32 for load with locally bound
symbols if PIC is false.  Optimize branch to 0 if PIC is false.
(elf_x86_64_relocate_section): Don't generate dynamic relocations
against undefined weak symbols if PIC is false.

ld/

PR ld/19609
* testsuite/ld-i386/got1.dd: Updated.
* testsuite/ld-i386/lea1c.d: Likewise.
* testsuite/ld-i386/load1-nacl.d: Likewise.
* testsuite/ld-i386/load1.d: Likewise.
* testsuite/ld-i386/load4b.d: Likewise.
* testsuite/ld-i386/load5b.d: Likewise.
* testsuite/ld-i386/mov1b.d: Likewise.
* testsuite/ld-x86-64/mov1b.d: Likewise.
* testsuite/ld-x86-64/mov1d.d: Likewise.
* testsuite/ld-ifunc/ifunc-21-i386.d: Likewise.
* testsuite/ld-ifunc/ifunc-21-x86-64.d: Likewise.
* testsuite/ld-ifunc/ifunc-22-i386.d: Likewise.
* testsuite/ld-ifunc/ifunc-22-x86-64.d: Likewise.
* testsuite/ld-x86-64/gotpcrel1.dd: Likewise.
* testsuite/ld-x86-64/lea1a.d: Likewise.
* testsuite/ld-x86-64/lea1b.d: Likewise.
* testsuite/ld-x86-64/lea1c.d: Likewise.
* testsuite/ld-x86-64/lea1d.d: Likewise.
* testsuite/ld-x86-64/lea1e.d: Likewise.
* testsuite/ld-x86-64/lea1f.d: Likewise.
* testsuite/ld-x86-64/mov1b.d: Likewise.
* testsuite/ld-x86-64/mov1d.d: Likewise.
* testsuite/ld-x86-64/pr13082-3b.d: Likewise.
* testsuite/ld-x86-64/pr13082-4b.d: Likewise.
* testsuite/ld-x86-64/lea1.s: Add tests for 32-bit registers.
* testsuite/ld-i386/pr19609-1.s: New file.
* testsuite/ld-i386/pr19609-1a.d: Likewise.
* testsuite/ld-i386/pr19609-1b.d: Likewise.
* testsuite/ld-i386/pr19609-1c.d: Likewise.
* testsuite/ld-i386/pr19609-1d.d: Likewise.
* testsuite/ld-i386/pr19609-1e.d: Likewise.
* testsuite/ld-i386/pr19609-1f.d: Likewise.
* testsuite/ld-i386/pr19609-1g.d: Likewise.
* testsuite/ld-i386/pr19609-1h.d: Likewise.
* testsuite/ld-i386/pr19609-1i.d: Likewise.
* testsuite/ld-i386/pr19609-2.s: Likewise.
* testsuite/ld-i386/pr19609-2a.d: Likewise.
* testsuite/ld-i386/pr19609-2b.d: Likewise.
* testsuite/ld-i386/pr19609-2c.d: Likewise.
* testsuite/ld-i386/undefweak.s: Likewise.
* testsuite/ld-i386/undefweaka.d: Likewise.
* testsuite/ld-i386/undefweakb.d: Likewise.
* testsuite/ld-x86-64/pr13082-3c.d: Likewise.
* testsuite/ld-x86-64/pr13082-3d.d: Likewise.
* testsuite/ld-x86-64/pr19609-1.s: Likewise.
* testsuite/ld-x86-64/pr19609-1a.d: Likewise.
* testsuite/ld-x86-64/pr19609-1b.d: Likewise.
* testsuite/ld-x86-64/pr19609-1c.d: Likewise.
* testsuite/ld-x86-64/pr19609-1d.d: Likewise.
* testsuite/ld-x86-64/pr19609-1e.d: Likewise.
* testsuite/ld-x86-64/pr19609-1f.d: Likewise.
* testsuite/ld-x86-64/pr19609-1g.d: Likewise.
* testsuite/ld-x86-64/pr19609-1h.d: Likewise.
* testsuite/ld-x86-64/pr19609-1i.d: Likewise.
* testsuite/ld-x86-64/pr19609-1j.d: Likewise.
* testsuite/ld-x86-64/pr19609-1k.d: Likewise.
* testsuite/ld-x86-64/pr19609-1l.d: Likewise.
* testsuite/ld-x86-64/pr19609-1m.d: Likewise.
* testsuite/ld-x86-64/pr19609-2.s: Likewise.
* testsuite/ld-x86-64/pr19609-2a.d: Likewise.
* testsuite/ld-x86-64/pr19609-2b.d: Likewise.
* testsuite/ld-x86-64/pr19609-2c.d: Likewise.
* testsuite/ld-x86-64/pr19609-2d.d: Likewise.
* testsuite/ld-x86-64/pr19609-3.s: Likewise.
* testsuite/ld-x86-64/pr19609-3a.d: Likewise.
* testsuite/ld-x86-64/pr19609-3b.d: Likewise.
* testsuite/ld-x86-64/pr19609-4.s: Likewise.
* testsuite/ld-x86-64/pr19609-4a.d: Likewise.
* testsuite/ld-x86-64/pr19609-4b.d: Likewise.
* testsuite/ld-x86-64/pr19609-4c.d: Likewise.
* testsuite/ld-x86-64/pr19609-4d.d: Likewise.
* testsuite/ld-x86-64/pr19609-4e.d: Likewise.
* testsuite/ld-x86-64/pr19609-5.s: Likewise.
* testsuite/ld-x86-64/pr19609-5a.d: Likewise.
* testsuite/ld-x86-64/pr19609-5b.d: Likewise.
* testsuite/ld-x86-64/pr19609-5c.d: Likewise.
* testsuite/ld-x86-64/pr19609-5d.d: Likewise.
* testsuite/ld-x86-64/pr19609-5e.d: Likewise.
* testsuite/ld-x86-64/pr19609-6.s: Likewise.
* testsuite/ld-x86-64/pr19609-6a.d: Likewise.
* testsuite/ld-x86-64/pr19609-6b.d: Likewise.
* testsuite/ld-x86-64/pr19609-6c.d: Likewise.
* testsuite/ld-x86-64/pr19609-6d.d: Likewise.
* testsuite/ld-x86-64/pr19609-7.s: Likewise.
* testsuite/ld-x86-64/pr19609-7a.d: Likewise.
* testsuite/ld-x86-64/pr19609-7b.d: Likewise.
* testsuite/ld-x86-64/pr19609-7c.d: Likewise.
* testsuite/ld-x86-64/pr19609-7d.d: Likewise.
* testsuite/ld-i386/i386.exp: Run undefweak tests and tests for
PR ld/19609.
* testsuite/ld-x86-64/x86-64.exp: Run pr13082-3c, pr13082-3d
and tests for PR ld/19609.
92 files changed:
bfd/ChangeLog
bfd/elf32-i386.c
bfd/elf64-x86-64.c
ld/ChangeLog
ld/testsuite/ld-i386/got1.dd
ld/testsuite/ld-i386/i386.exp
ld/testsuite/ld-i386/lea1c.d
ld/testsuite/ld-i386/load1-nacl.d
ld/testsuite/ld-i386/load1.d
ld/testsuite/ld-i386/load4b.d
ld/testsuite/ld-i386/load5b.d
ld/testsuite/ld-i386/mov1b.d
ld/testsuite/ld-i386/pr19609-1.s [new file with mode: 0644]
ld/testsuite/ld-i386/pr19609-1a.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19609-1b.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19609-1c.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19609-1d.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19609-1e.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19609-1f.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19609-1g.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19609-1h.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19609-1i.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19609-2.s [new file with mode: 0644]
ld/testsuite/ld-i386/pr19609-2a.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19609-2b.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19609-2c.d [new file with mode: 0644]
ld/testsuite/ld-i386/undefweak.s [new file with mode: 0644]
ld/testsuite/ld-i386/undefweaka.d [new file with mode: 0644]
ld/testsuite/ld-i386/undefweakb.d [new file with mode: 0644]
ld/testsuite/ld-ifunc/ifunc-21-i386.d
ld/testsuite/ld-ifunc/ifunc-21-x86-64.d
ld/testsuite/ld-ifunc/ifunc-22-i386.d
ld/testsuite/ld-ifunc/ifunc-22-x86-64.d
ld/testsuite/ld-x86-64/gotpcrel1.dd
ld/testsuite/ld-x86-64/lea1.s
ld/testsuite/ld-x86-64/lea1a.d
ld/testsuite/ld-x86-64/lea1b.d
ld/testsuite/ld-x86-64/lea1c.d
ld/testsuite/ld-x86-64/lea1d.d
ld/testsuite/ld-x86-64/lea1e.d
ld/testsuite/ld-x86-64/lea1f.d
ld/testsuite/ld-x86-64/mov1b.d
ld/testsuite/ld-x86-64/mov1d.d
ld/testsuite/ld-x86-64/pr13082-3b.d
ld/testsuite/ld-x86-64/pr13082-3c.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr13082-3d.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr13082-4b.d
ld/testsuite/ld-x86-64/pr19609-1.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-1a.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-1b.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-1c.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-1d.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-1e.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-1f.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-1g.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-1h.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-1i.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-1j.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-1k.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-1l.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-1m.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-2.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-2a.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-2b.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-2c.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-2d.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-3.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-3a.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-3b.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-4.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-4a.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-4b.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-4c.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-4d.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-4e.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-5.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-5a.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-5b.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-5c.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-5d.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-5e.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-6.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-6a.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-6b.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-6c.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-6d.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-7.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-7a.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-7b.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-7c.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19609-7d.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/x86-64.exp