From f40bb390bbf2c4a7a4ff0a042ac9ab9168ab6956 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 27 Jun 2022 18:17:18 +0930 Subject: 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. --- bfd/elf64-ppc.c | 54 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 20 deletions(-) (limited to 'bfd/elf64-ppc.c') 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) { -- cgit v1.2.3