* emultempl/ppc32elf.em (ppc_before_allocation): Turn on
authorAlan Modra <amodra@gmail.com>
Fri, 10 Jul 2009 12:29:40 +0000 (12:29 +0000)
committerAlan Modra <amodra@gmail.com>
Fri, 10 Jul 2009 12:29:40 +0000 (12:29 +0000)
linker relaxation if it might be necessary.

ld/ChangeLog
ld/emultempl/ppc32elf.em

index 5836c86..8ffee59 100644 (file)
@@ -1,5 +1,10 @@
 2009-07-10  Alan Modra  <amodra@bigpond.net.au>
 
+       * emultempl/ppc32elf.em (ppc_before_allocation): Turn on
+       linker relaxation if it might be necessary.
+
+2009-07-10  Alan Modra  <amodra@bigpond.net.au>
+
        * emulparams/elf32ppc.sh (GOTPLT, PLT): Handle .iplt.
 
 2009-07-06  Matthias Klose <doko@ubuntu.com>
index 1a93ed4..b801df8 100644 (file)
@@ -112,7 +112,40 @@ ppc_before_allocation (void)
            }
        }
     }
+
   gld${EMULATION_NAME}_before_allocation ();
+
+  /* Turn on relaxation if executable sections have addresses that
+     might make branches overflow.  */
+  if (!command_line.relax)
+    {
+      bfd_vma low = (bfd_vma) -1;
+      bfd_vma high = 0;
+      asection *o;
+
+      /* Run lang_size_sections (if not already done).  */
+      if (expld.phase != lang_mark_phase_enum)
+       {
+         expld.phase = lang_mark_phase_enum;
+         expld.dataseg.phase = exp_dataseg_none;
+         one_lang_size_sections_pass (NULL, FALSE);
+         lang_reset_memory_regions ();
+       }
+
+      for (o = link_info.output_bfd->sections; o != NULL; o = o->next)
+       {
+         if ((o->flags & (SEC_ALLOC | SEC_CODE)) != (SEC_ALLOC | SEC_CODE))
+           continue;
+         if (o->size == 0)
+           continue;
+         if (low > o->vma)
+           low = o->vma;
+         if (high < o->vma + o->size - 1)
+           high = o->vma + o->size - 1;
+       }
+      if (high > low && high - low > (1 << 25) - 1)
+       command_line.relax = TRUE;
+    }
 }
 
 EOF