]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
PR 19264 looping in ppc64_elf_size_stubs
authorAlan Modra <amodra@gmail.com>
Tue, 28 Jun 2016 10:37:26 +0000 (20:07 +0930)
committerAlan Modra <amodra@gmail.com>
Tue, 28 Jun 2016 10:37:26 +0000 (20:07 +0930)
b399102 fixed the testcase in this PR but it may be possible to
trigger the problem in other ways.

PR ld/19264
* elf64-ppc.c (STUB_SHRINK_ITER): Define.
(ppc64_elf_size_stubs): Exit stub sizing loop past STUB_SHRINK_ITER
if shrinking stubs.
(ppc64_elf_size_stubs): Adjust to suit.

bfd/ChangeLog
bfd/elf64-ppc.c

index 36b10e98c7875478c8dfbb87edf3a324218d8197..f88580c5ea80c3fa701f1fab7851b7cd3929440f 100644 (file)
@@ -1,3 +1,11 @@
+2016-06-28  Alan Modra  <amodra@gmail.com>
+
+       PR ld/19264
+       * elf64-ppc.c (STUB_SHRINK_ITER): Define.
+       (ppc64_elf_size_stubs): Exit stub sizing loop past STUB_SHRINK_ITER
+       if shrinking stubs.
+       (ppc64_elf_size_stubs): Adjust to suit.
+
 2016-06-14  Senthil Kumar Selvaraj  <senthil_kumar.selvaraj@atmel.com>
 
        Backport from master
index d72b631d3d8652b2edf6fadf9878695ba12d3bb3..8c6a14b7308c390089ff2fc5b29ab1a4a1404de9 100644 (file)
@@ -12183,6 +12183,13 @@ ppc64_elf_size_stubs (struct bfd_link_info *info)
   if (!group_sections (info, stub_group_size, stubs_always_before_branch))
     return FALSE;
 
+#define STUB_SHRINK_ITER 20
+  /* Loop until no stubs added.  After iteration 20 of this loop we may
+     exit on a stub section shrinking.  This is to break out of a
+     pathological case where adding stubs on one iteration decreases
+     section gaps (perhaps due to alignment), which then requires
+     fewer or smaller stubs on the next iteration.  */
+
   while (1)
     {
       bfd *input_bfd;
@@ -12564,11 +12571,11 @@ ppc64_elf_size_stubs (struct bfd_link_info *info)
           stub_sec != NULL;
           stub_sec = stub_sec->next)
        if ((stub_sec->flags & SEC_LINKER_CREATED) == 0
-           && stub_sec->rawsize != stub_sec->size)
+           && stub_sec->rawsize != stub_sec->size
+           && (htab->stub_iteration <= STUB_SHRINK_ITER
+               || 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
          && (htab->glink_eh_frame == NULL
              || htab->glink_eh_frame->rawsize == htab->glink_eh_frame->size))
@@ -12899,9 +12906,6 @@ ppc64_elf_build_stubs (struct bfd_link_info *info,
        stub_sec->contents = bfd_zalloc (htab->params->stub_bfd, stub_sec->size);
        if (stub_sec->contents == NULL)
          return FALSE;
-       /* We want to check that built size is the same as calculated
-          size.  rawsize is a convenient location to use.  */
-       stub_sec->rawsize = stub_sec->size;
        stub_sec->size = 0;
       }
 
@@ -13090,7 +13094,9 @@ ppc64_elf_build_stubs (struct bfd_link_info *info,
     if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
       {
        stub_sec_count += 1;
-       if (stub_sec->rawsize != stub_sec->size)
+       if (stub_sec->rawsize != stub_sec->size
+           && (htab->stub_iteration <= STUB_SHRINK_ITER
+               || stub_sec->rawsize < stub_sec->size))
          break;
       }