This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
ppc64 long branch stub error
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: binutils at sources dot redhat dot com
- Date: Mon, 19 Sep 2005 19:02:47 +0930
- Subject: ppc64 long branch stub error
An IBM bugzilla entry reported that the assert in ppc_build_one_stub was
being triggered, indicating that a long branch stub couldn't reach its
target. I don't have a testcase for it, but the likely cause is that
addition of stubs changed the layout sufficiently that some of the long
branch stubs need to be replaced with plt branch stubs. The change to
ppc64_elf_size_stubs below should fix this problem. I've also made the
linker warn when a single input section exceeds the stub group size,
since that may lead to later relocation overflows.
* elf64-ppc.c (ppc_build_one_stub): Replace assertion that long
branch offset is in range with an error. Print full stub name on
errors.
(ppc_size_one_stub): Print full stub name on errors.
(group_sections): Warn if section size exceeds group size.
(ppc64_elf_size_stubs): Continue relaxing when stub types change.
Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.220
diff -u -p -r1.220 elf64-ppc.c
--- bfd/elf64-ppc.c 18 Aug 2005 01:28:24 -0000 1.220
+++ bfd/elf64-ppc.c 19 Sep 2005 08:23:07 -0000
@@ -8015,7 +8015,13 @@ ppc_build_one_stub (struct bfd_hash_entr
}
bfd_put_32 (htab->stub_bfd, B_DOT | (off & 0x3fffffc), loc);
- BFD_ASSERT (off + (1 << 25) < (bfd_vma) (1 << 26));
+ if (off + (1 << 25) >= (bfd_vma) (1 << 26))
+ {
+ (*_bfd_error_handler) (_("long branch stub `%s' offset overflow"),
+ stub_entry->root.string);
+ htab->stub_error = TRUE;
+ return FALSE;
+ }
if (info->emitrelocations)
{
@@ -8087,7 +8093,7 @@ ppc_build_one_stub (struct bfd_hash_entr
if (br_entry == NULL)
{
(*_bfd_error_handler) (_("can't find branch stub `%s'"),
- stub_entry->root.string + 9);
+ stub_entry->root.string);
htab->stub_error = TRUE;
return FALSE;
}
@@ -8331,7 +8337,7 @@ ppc_size_one_stub (struct bfd_hash_entry
if (br_entry == NULL)
{
(*_bfd_error_handler) (_("can't build branch stub `%s'"),
- stub_entry->root.string + 9);
+ stub_entry->root.string);
htab->stub_error = TRUE;
return FALSE;
}
@@ -8752,7 +8758,10 @@ group_sections (struct ppc_link_hash_tab
curr = tail;
total = tail->size;
- big_sec = total >= stub_group_size;
+ big_sec = total > stub_group_size;
+ if (big_sec)
+ (*_bfd_error_handler) (_("%B section %A exceeds stub group size"),
+ tail->owner, tail);
curr_toc = htab->stub_group[tail->id].toc_off;
while ((prev = PREV_SEC (curr)) != NULL
@@ -8854,10 +8863,8 @@ ppc64_elf_size_stubs (bfd *output_bfd,
bfd *input_bfd;
unsigned int bfd_indx;
asection *stub_sec;
- bfd_boolean stub_changed;
htab->stub_iteration += 1;
- stub_changed = FALSE;
for (input_bfd = info->input_bfds, bfd_indx = 0;
input_bfd != NULL;
@@ -9106,8 +9113,6 @@ ppc64_elf_size_stubs (bfd *output_bfd,
if (stub_entry->h != NULL)
htab->stub_globals += 1;
-
- stub_changed = TRUE;
}
/* We're done with the internal relocs, free them. */
@@ -9125,16 +9130,14 @@ ppc64_elf_size_stubs (bfd *output_bfd,
}
}
- if (!stub_changed)
- break;
-
- /* OK, we've added some stubs. Find out the new size of the
+ /* We may have added some stubs. Find out the new size of the
stub sections. */
for (stub_sec = htab->stub_bfd->sections;
stub_sec != NULL;
stub_sec = stub_sec->next)
if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
{
+ stub_sec->rawsize = stub_sec->size;
stub_sec->size = 0;
stub_sec->reloc_count = 0;
}
@@ -9145,6 +9148,18 @@ ppc64_elf_size_stubs (bfd *output_bfd,
bfd_hash_traverse (&htab->stub_hash_table, ppc_size_one_stub, info);
+ for (stub_sec = htab->stub_bfd->sections;
+ stub_sec != NULL;
+ stub_sec = stub_sec->next)
+ if ((stub_sec->flags & SEC_LINKER_CREATED) == 0
+ && stub_sec->rawsize != stub_sec->size)
+ break;
+
+ /* Exit from this loop when no stubs have been added, and no stubs
+ have changed size. */
+ if (stub_sec == NULL)
+ break;
+
/* Ask the linker to do its stuff. */
(*htab->layout_sections_again) ();
}
--
Alan Modra
IBM OzLabs - Linux Technology Centre