PowerPC64, correct grouping of stubs for ld.bfd
authorAlan Modra <amodra@gmail.com>
Tue, 30 Aug 2016 11:32:58 +0000 (21:02 +0930)
committerAlan Modra <amodra@gmail.com>
Wed, 31 Aug 2016 09:52:31 +0000 (19:22 +0930)
Like 57f6d32d, this patch ensures that sections containing external
conditional branches limit the group size.

* elf64-ppc.c (group_sections): Delete stub14_group_size.  Instead,
track max group size with a new "group_size" var that is reduced
by a factor of 1024 from the 24-bit branch size whenever a 14-bit
branch is seen.

bfd/ChangeLog
bfd/elf64-ppc.c

index e1f5c873fe79b6a5c140bceadab5a2bf60dd09c0..59dfb2cb141153d408ff59005fad98ae5c4e4fe7 100644 (file)
@@ -1,3 +1,10 @@
+2016-08-31  Alan Modra  <amodra@gmail.com>
+
+       * elf64-ppc.c (group_sections): Delete stub14_group_size.  Instead,
+       track max group size with a new "group_size" var that is reduced
+       by a factor of 1024 from the 24-bit branch size whenever a 14-bit
+       branch is seen.
+
 2016-08-31  Alan Modra  <amodra@gmail.com>
 
        * elf32-ppc.c (ppc_elf_section_processing): Delete.
index a9cedb58e85b9c18391587cdda99374082b49f6d..3a9a1cb20f013ed8b4e1b10cd8ac7c9901d33e2e 100644 (file)
@@ -12049,7 +12049,6 @@ group_sections (struct bfd_link_info *info,
 {
   struct ppc_link_hash_table *htab;
   asection *osec;
-  bfd_size_type stub14_group_size;
   bfd_boolean suppress_size_errors;
 
   htab = ppc_hash_table (info);
@@ -12057,20 +12056,13 @@ group_sections (struct bfd_link_info *info,
     return FALSE;
 
   suppress_size_errors = FALSE;
-  stub14_group_size = stub_group_size >> 10;
   if (stub_group_size == 1)
     {
       /* Default values.  */
       if (stubs_always_before_branch)
-       {
-         stub_group_size = 0x1e00000;
-         stub14_group_size = 0x7800;
-       }
+       stub_group_size = 0x1e00000;
       else
-       {
-         stub_group_size = 0x1c00000;
-         stub14_group_size = 0x7000;
-       }
+       stub_group_size = 0x1c00000;
       suppress_size_errors = TRUE;
     }
 
@@ -12090,12 +12082,15 @@ group_sections (struct bfd_link_info *info,
          bfd_boolean big_sec;
          bfd_vma curr_toc;
          struct map_stub *group;
+         bfd_size_type group_size;
 
          curr = tail;
          total = tail->size;
-         big_sec = total > (ppc64_elf_section_data (tail) != NULL
-                            && ppc64_elf_section_data (tail)->has_14bit_branch
-                            ? stub14_group_size : stub_group_size);
+         group_size = (ppc64_elf_section_data (tail) != NULL
+                       && ppc64_elf_section_data (tail)->has_14bit_branch
+                       ? stub_group_size >> 10 : stub_group_size);
+
+         big_sec = total > group_size;
          if (big_sec && !suppress_size_errors)
            (*_bfd_error_handler) (_("%B section %A exceeds stub group size"),
                                     tail->owner, tail);
@@ -12105,20 +12100,20 @@ group_sections (struct bfd_link_info *info,
                 && ((total += curr->output_offset - prev->output_offset)
                     < (ppc64_elf_section_data (prev) != NULL
                        && ppc64_elf_section_data (prev)->has_14bit_branch
-                       ? stub14_group_size : stub_group_size))
+                       ? (group_size = stub_group_size >> 10) : group_size))
                 && htab->sec_info[prev->id].toc_off == curr_toc)
            curr = prev;
 
          /* OK, the size from the start of CURR to the end is less
-            than stub_group_size and thus can be handled by one stub
+            than group_size and thus can be handled by one stub
             section.  (or the tail section is itself larger than
-            stub_group_size, in which case we may be toast.)  We
-            should really be keeping track of the total size of stubs
-            added here, as stubs contribute to the final output
-            section size.  That's a little tricky, and this way will
-            only break if stubs added make the total size more than
-            2^25, ie. for the default stub_group_size, if stubs total
-            more than 2097152 bytes, or nearly 75000 plt call stubs.  */
+            group_size, in which case we may be toast.)  We should
+            really be keeping track of the total size of stubs added
+            here, as stubs contribute to the final output section
+            size.  That's a little tricky, and this way will only
+            break if stubs added make the total size more than 2^25,
+            ie. for the default stub_group_size, if stubs total more
+            than 2097152 bytes, or nearly 75000 plt call stubs.  */
          group = bfd_alloc (curr->owner, sizeof (*group));
          if (group == NULL)
            return FALSE;
@@ -12135,7 +12130,7 @@ group_sections (struct bfd_link_info *info,
            }
          while (tail != curr && (tail = prev) != NULL);
 
-         /* But wait, there's more!  Input sections up to stub_group_size
+         /* But wait, there's more!  Input sections up to group_size
             bytes before the stub section can be handled by it too.
             Don't do this if we have a really large section after the
             stubs, as adding more stubs increases the chance that
@@ -12147,7 +12142,7 @@ group_sections (struct bfd_link_info *info,
                     && ((total += tail->output_offset - prev->output_offset)
                         < (ppc64_elf_section_data (prev) != NULL
                            && ppc64_elf_section_data (prev)->has_14bit_branch
-                           ? stub14_group_size : stub_group_size))
+                           ? (group_size = stub_group_size >> 10) : group_size))
                     && htab->sec_info[prev->id].toc_off == curr_toc)
                {
                  tail = prev;