Speedup mmo and pe orphan placement for relocatable link
[binutils-gdb.git] / ld / emultempl / pe.em
index 04a7f5cd7f81b850404053a425beedc76ed4d0a7..2b78536df8996bc387c34c55c948b74224e7d8c9 100644 (file)
@@ -8,7 +8,7 @@ fi
 rm -f e${EMULATION_NAME}.c
 (echo;echo;echo;echo;echo)>e${EMULATION_NAME}.c # there, now line numbers match ;-)
 fragment <<EOF
-/* Copyright (C) 1995-2015 Free Software Foundation, Inc.
+/* Copyright (C) 1995-2016 Free Software Foundation, Inc.
 
    This file is part of the GNU Binutils.
 
@@ -2209,6 +2209,8 @@ gld_${EMULATION_NAME}_place_orphan (asection *s,
       struct orphan_save *place;
       lang_output_section_statement_type *after;
       etree_type *address;
+      flagword flags;
+      asection *nexts;
 
       if (!orphan_init_done)
        {
@@ -2223,17 +2225,35 @@ gld_${EMULATION_NAME}_place_orphan (asection *s,
          orphan_init_done = 1;
        }
 
+      flags = s->flags;
+      if (!bfd_link_relocatable (&link_info))
+       {
+         nexts = s;
+         while ((nexts = bfd_get_next_section_by_name (nexts->owner,
+                                                       nexts)))
+           if (nexts->output_section == NULL
+               && (nexts->flags & SEC_EXCLUDE) == 0
+               && ((nexts->flags ^ flags) & (SEC_LOAD | SEC_ALLOC)) == 0
+               && (nexts->owner->flags & DYNAMIC) == 0
+               && nexts->owner->usrdata != NULL
+               && !(((lang_input_statement_type *) nexts->owner->usrdata)
+                    ->flags.just_syms))
+             flags = (((flags ^ SEC_READONLY)
+                       | (nexts->flags ^ SEC_READONLY))
+                      ^ SEC_READONLY);
+       }
+
       /* Try to put the new output section in a reasonable place based
         on the section name and section flags.  */
 
       place = NULL;
-      if ((s->flags & SEC_ALLOC) == 0)
+      if ((flags & SEC_ALLOC) == 0)
        ;
-      else if ((s->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
+      else if ((flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
        place = &hold[orphan_bss];
-      else if ((s->flags & SEC_READONLY) == 0)
+      else if ((flags & SEC_READONLY) == 0)
        place = &hold[orphan_data];
-      else if ((s->flags & SEC_CODE) == 0)
+      else if ((flags & SEC_CODE) == 0)
        {
          place = (!strncmp (secname, ".idata\$", 7) ? &hold[orphan_idata]
                                                     : &hold[orphan_rodata]);
@@ -2248,7 +2268,8 @@ gld_${EMULATION_NAME}_place_orphan (asection *s,
            place->os = lang_output_section_find (place->name);
          after = place->os;
          if (after == NULL)
-           after = lang_output_section_find_by_flags (s, &place->os, NULL);
+           after = lang_output_section_find_by_flags (s, flags, &place->os,
+                                                      NULL);
          if (after == NULL)
            /* *ABS* is always the first output section statement.  */
            after = (&lang_output_section_statement.head