2015-08-31 Alan Modra <amodra@gmail.com>
+ * elf64-ppc.c (get_r2off): Return -1 on error.
+ (ppc_build_one_stub): Adjust for get_r2off change. Don't emit
+ addi r2,r2,0 on r2off stubs when the low 16-bit delta is zero.
+ (ppc_size_one_stub): Corresponding size changes for r2off stubs.
+ Add condition in test for -R objects.
+
+2015-08-31 Alan Modra <amodra@gmail.com>
+
* section.c (section_id): Make file scope.
(bfd_get_next_section_id): New function.
* elf64-ppc.c (struct map_stub): Remove toc_off field. Move decl.
info->callbacks->einfo (_("%P: cannot find opd entry toc for `%T'\n"),
stub_entry->h->elf.root.root.string);
bfd_set_error (bfd_error_bad_value);
- return 0;
+ return (bfd_vma) -1;
}
if (!bfd_get_section_contents (opd->owner, opd, buf, opd_off + 8, 8))
- return 0;
+ return (bfd_vma) -1;
r2off = bfd_get_64 (opd->owner, buf);
r2off -= elf_gp (info->output_bfd);
}
{
bfd_vma r2off = get_r2off (info, stub_entry);
- if (r2off == 0)
+ if (r2off == (bfd_vma) -1)
{
htab->stub_error = TRUE;
return FALSE;
}
bfd_put_32 (htab->params->stub_bfd, STD_R2_0R1 + STK_TOC (htab), loc);
loc += 4;
- size = 12;
+ size = 8;
if (PPC_HA (r2off) != 0)
{
- size = 16;
bfd_put_32 (htab->params->stub_bfd,
ADDIS_R2_R2 | PPC_HA (r2off), loc);
loc += 4;
+ size += 4;
+ }
+ if (PPC_LO (r2off) != 0)
+ {
+ bfd_put_32 (htab->params->stub_bfd,
+ ADDI_R2_R2 | PPC_LO (r2off), loc);
+ loc += 4;
+ size += 4;
}
- bfd_put_32 (htab->params->stub_bfd, ADDI_R2_R2 | PPC_LO (r2off), loc);
- loc += 4;
off -= size - 4;
}
bfd_put_32 (htab->params->stub_bfd, B_DOT | (off & 0x3fffffc), loc);
{
bfd_vma r2off = get_r2off (info, stub_entry);
- if (r2off == 0 && htab->opd_abi)
+ if (r2off == (bfd_vma) -1)
{
htab->stub_error = TRUE;
return FALSE;
if (stub_entry->stub_type == ppc_stub_long_branch_r2off)
{
r2off = get_r2off (info, stub_entry);
- if (r2off == 0 && htab->opd_abi)
+ if (r2off == (bfd_vma) -1)
{
htab->stub_error = TRUE;
return FALSE;
}
- size = 12;
+ size = 8;
if (PPC_HA (r2off) != 0)
- size = 16;
+ size += 4;
+ if (PPC_LO (r2off) != 0)
+ size += 4;
off -= size - 4;
}
Do the same for -R objects without function descriptors. */
if (off + (1 << 25) >= (bfd_vma) (1 << 26) - local_off
|| (stub_entry->stub_type == ppc_stub_long_branch_r2off
- && r2off == 0))
+ && r2off == 0
+ && htab->sec_info[stub_entry->target_section->id].toc_off == 0))
{
struct ppc_branch_hash_entry *br_entry;