summaryrefslogtreecommitdiff
path: root/bfd/elf64-ppc.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2022-06-27 18:17:18 +0930
committerAlan Modra <amodra@gmail.com>2022-06-28 13:02:26 +0930
commitf40bb390bbf2c4a7a4ff0a042ac9ab9168ab6956 (patch)
tree37b9756be8a00ddfe472ed9ab64d48ad18a13749 /bfd/elf64-ppc.c
parent0f0d9373a3697ea2e464584dcea5cb7242b7208e (diff)
PowerPC64: align plt_branch stubs
plt_branch stubs are similar to plt_call stubs in that they branch via bctr. Align them too. bfd/ * elf64-ppc.c (ppc_size_one_stub): Align plt_branch stubs as for plt_call stubs. ld/ * testsuite/ld-powerpc/elfv2exe.d: Adjust for plt_branch changes. * testsuite/ld-powerpc/notoc.d: Likewise. * testsuite/ld-powerpc/notoc.wf: Likewise. * testsuite/ld-powerpc/notoc3.d: Likewise. * testsuite/ld-powerpc/pr23937.d: Likewise.
Diffstat (limited to 'bfd/elf64-ppc.c')
-rw-r--r--bfd/elf64-ppc.c54
1 files changed, 34 insertions, 20 deletions
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 202c941515..77e8f596d1 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -12393,6 +12393,8 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
if (PPC_LO (r2off) != 0)
size += 4;
}
+ pad = plt_stub_pad (htab->params->plt_stub_align, stub_offset, size);
+ stub_offset += pad;
}
else if (info->emitrelocations)
{
@@ -12415,6 +12417,38 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
odd = off & 4;
off = targ - off;
+ if (stub_entry->type.sub == ppc_stub_notoc)
+ extra = size_power10_offset (off, odd);
+ else
+ extra = size_offset (off - 8);
+ /* Include branch insn plus those in the offset sequence. */
+ size += 4 + extra;
+
+ /* If the branch can't reach, use a plt_branch.
+ The branch insn is at the end, or "extra" bytes along. So
+ its offset will be "extra" bytes less that that already
+ calculated. */
+ if (off - extra + (1 << 25) >= (bfd_vma) (1 << 26))
+ {
+ stub_entry->type.main = ppc_stub_plt_branch;
+ size += 4;
+ pad = plt_stub_pad (htab->params->plt_stub_align, stub_offset, size);
+ if (pad != 0)
+ {
+ stub_offset += pad;
+ off -= pad;
+ odd ^= pad & 4;
+ size -= extra;
+ if (stub_entry->type.sub == ppc_stub_notoc)
+ extra = size_power10_offset (off, odd);
+ else
+ extra = size_offset (off - 8);
+ size += extra;
+ }
+ }
+ else if (info->emitrelocations)
+ stub_entry->group->stub_sec->reloc_count +=1;
+
if (info->emitrelocations)
{
unsigned int num_rel;
@@ -12426,17 +12460,6 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
stub_entry->group->stub_sec->flags |= SEC_RELOC;
}
- if (stub_entry->type.sub == ppc_stub_notoc)
- extra = size_power10_offset (off, odd);
- else
- extra = size_offset (off - 8);
- /* Include branch insn plus those in the offset sequence. */
- size += 4 + extra;
- /* The branch insn is at the end, or "extra" bytes along. So
- its offset will be "extra" bytes less that that already
- calculated. */
- off -= extra;
-
if (stub_entry->type.sub != ppc_stub_notoc)
{
/* After the bcl, lr has been modified so we need to emit
@@ -12451,15 +12474,6 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
stub_entry->group->eh_size += eh_advance_size (delta) + 6;
stub_entry->group->lr_restore = lr_used + 8;
}
-
- /* If the branch can't reach, use a plt_branch. */
- if (off + (1 << 25) >= (bfd_vma) (1 << 26))
- {
- stub_entry->type.main = ppc_stub_plt_branch;
- size += 4;
- }
- else if (info->emitrelocations)
- stub_entry->group->stub_sec->reloc_count +=1;
}
else if (stub_entry->type.sub >= ppc_stub_notoc)
{