diff options
author | Alan Modra <amodra@gmail.com> | 2017-09-09 21:55:22 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2017-09-10 01:55:16 +0930 |
commit | 2420fff633eff03ec1f85eba82a926cd0ecf4229 (patch) | |
tree | ce52c69c7236e211580be3aa4da6692022bbe0bc /bfd | |
parent | c5bce5c69721af8dae5c607e085e545cdba33ab1 (diff) | |
download | gdb-2420fff633eff03ec1f85eba82a926cd0ecf4229.zip gdb-2420fff633eff03ec1f85eba82a926cd0ecf4229.tar.gz gdb-2420fff633eff03ec1f85eba82a926cd0ecf4229.tar.bz2 |
PowerPC64 --plt-align
This changes the PowerPC64 --plt-align option to perform the usual
alignment of code as suggested by its name, as well as the previous
behaviour of padding so as to reduce boundary crossing. The old
behaviour is had by using a negative parameter.
The default is also changed to align plt stub code by default to 32
byte boundaries, the point being to get better bctr branch prediction
on power8 and power9 hardware.
bfd/
* elf64-ppp.c (plt_stub_pad): Handle positive and negative
plt_stub_align.
ld/
* ld.texinfo (--plt-align): Describe new behaviour of option.
* emultempl/ppc64elf.em (params): Default plt_stub_align to 5.
* testsuite/ld-powerpc/powerpc.exp: Pass --no-plt-align for
selected tests.
* testsuite/ld-powerpc/relbrlt.d: Pass --no-plt-align.
* testsuite/ld-powerpc/elfv2so.d: Adjust expected output.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 5 | ||||
-rw-r--r-- | bfd/elf64-ppc.c | 19 |
2 files changed, 21 insertions, 3 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 06b9278..8521902 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,8 @@ +2017-09-09 Alan Modra <amodra@gmail.com> + + * elf64-ppp.c (plt_stub_pad): Handle positive and negative + plt_stub_align. + 2017-09-09 H.J. Lu <hongjiu.lu@intel.com> * elf32-i386.c (elf_i386_relocate_section): Update usage of diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index cf7c178..4821801 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -10610,17 +10610,30 @@ plt_stub_size (struct ppc_link_hash_table *htab, return size; } -/* If this stub would cross fewer 2**plt_stub_align boundaries if we align, - then return the padding needed to do so. */ +/* Depending on the sign of plt_stub_align: + If positive, return the padding to align to a 2**plt_stub_align + boundary. + If negative, if this stub would cross fewer 2**plt_stub_align + boundaries if we align, then return the padding needed to do so. */ + static inline unsigned int plt_stub_pad (struct ppc_link_hash_table *htab, struct ppc_stub_hash_entry *stub_entry, bfd_vma plt_off) { - int stub_align = 1 << htab->params->plt_stub_align; + int stub_align; unsigned stub_size = plt_stub_size (htab, stub_entry, plt_off); bfd_vma stub_off = stub_entry->group->stub_sec->size; + if (htab->params->plt_stub_align >= 0) + { + stub_align = 1 << htab->params->plt_stub_align; + if ((stub_off & (stub_align - 1)) != 0) + return stub_align - (stub_off & (stub_align - 1)); + return 0; + } + + stub_align = 1 << -htab->params->plt_stub_align; if (((stub_off + stub_size - 1) & -stub_align) - (stub_off & -stub_align) > ((stub_size - 1) & -stub_align)) return stub_align - (stub_off & (stub_align - 1)); |