This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] PR 19264 looping in ppc64_elf_size_stubs


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=c9301e31817019c38ab52da0e72fa1e3bf75332c

commit c9301e31817019c38ab52da0e72fa1e3bf75332c
Author: Alan Modra <amodra@gmail.com>
Date:   Mon Jun 27 20:00:09 2016 +0930

    PR 19264 looping in ppc64_elf_size_stubs
    
    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.

Diff:
---
 bfd/ChangeLog   |  8 ++++++++
 bfd/elf64-ppc.c | 20 +++++++++++++-------
 2 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 6fb242c..bf95751 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,11 @@
+2016-06-27  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-27  Trevor Saunders  <tbsaunde+binutils@tbsaunde.org>
 
 	* elf32-dlx.h: New file.
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 70fa5c3..e06b576 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -12185,6 +12185,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;
@@ -12566,11 +12573,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))
@@ -12901,9 +12908,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;
       }
 
@@ -13092,7 +13096,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;
       }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]