OSDN Git Service

* ldlang.c (lang_output_section_find_by_flags): Handle non-alloc
authoramodra <amodra>
Tue, 21 Oct 2008 22:55:04 +0000 (22:55 +0000)
committeramodra <amodra>
Tue, 21 Oct 2008 22:55:04 +0000 (22:55 +0000)
sections.
* emultempl/elf32.em (enum orphan_save_index): Add orphan_nonalloc.
(hold): Likewise.
(gld${EMULATION_NAME}_place_orphan): Handle non-alloc orphans.

ld/ChangeLog
ld/emultempl/elf32.em
ld/ldlang.c

index 59fa810..7677999 100644 (file)
@@ -1,3 +1,11 @@
+2008-10-22  Alan Modra  <amodra@bigpond.net.au>
+
+       * ldlang.c (lang_output_section_find_by_flags): Handle non-alloc
+       sections.
+       * emultempl/elf32.em (enum orphan_save_index): Add orphan_nonalloc.
+       (hold): Likewise.
+       (gld${EMULATION_NAME}_place_orphan): Handle non-alloc orphans.
+
 2008-10-22  Bernhard Reutner-Fischer  <aldot@gcc.gnu.org>
 
        * emultempl/armelf.em (PARSE_AND_LIST_OPTIONS): Correct typo in
index e1e7420..bb299d9 100644 (file)
@@ -1662,7 +1662,10 @@ gld${EMULATION_NAME}_place_orphan (asection *s,
        0, 0, 0, 0 },
       { ".sdata",
        SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_SMALL_DATA,
-       0, 0, 0, 0 }
+       0, 0, 0, 0 },
+      { 0,
+       SEC_HAS_CONTENTS,
+       0, 0, 0, 0 },
     };
   enum orphan_save_index
     {
@@ -1672,7 +1675,8 @@ gld${EMULATION_NAME}_place_orphan (asection *s,
       orphan_bss,
       orphan_rel,
       orphan_interp,
-      orphan_sdata
+      orphan_sdata,
+      orphan_nonalloc
     };
   static int orphan_init_done = 0;
   struct orphan_save *place;
@@ -1728,7 +1732,9 @@ gld${EMULATION_NAME}_place_orphan (asection *s,
 
   if (!orphan_init_done)
     {
+      lang_output_section_statement_type *lookup;
       struct orphan_save *ho;
+
       for (ho = hold; ho < hold + sizeof (hold) / sizeof (hold[0]); ++ho)
        if (ho->name != NULL)
          {
@@ -1736,6 +1742,16 @@ gld${EMULATION_NAME}_place_orphan (asection *s,
            if (ho->os != NULL && ho->os->flags == 0)
              ho->os->flags = ho->flags;
          }
+      lookup = hold[orphan_bss].os;
+      if (lookup == NULL)
+       lookup = &lang_output_section_statement.head->output_section_statement;
+      for (; lookup != NULL; lookup = lookup->next)
+       if ((lookup->bfd_section != NULL
+            && (lookup->bfd_section->flags & SEC_DEBUGGING) != 0)
+           || strcmp (lookup->name, ".comment") == 0)
+         break;
+      hold[orphan_nonalloc].os = lookup ? lookup->prev : NULL;
+      hold[orphan_nonalloc].name = ".comment";
       orphan_init_done = 1;
     }
 
@@ -1758,7 +1774,9 @@ gld${EMULATION_NAME}_place_orphan (asection *s,
      in the first page.  */
 
   place = NULL;
-  if ((s->flags & SEC_ALLOC) == 0)
+  if ((s->flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0)
+    place = &hold[orphan_nonalloc];
+  else if ((s->flags & SEC_ALLOC) == 0)
     ;
   else if ((s->flags & SEC_LOAD) != 0
           && ((iself && sh_type == SHT_NOTE)
index 2908449..322ce5b 100644 (file)
@@ -1363,7 +1363,8 @@ lang_output_section_find_by_flags (const asection *sec,
       return found;
     }
 
-  if (sec->flags & SEC_CODE)
+  if ((sec->flags & SEC_CODE) != 0
+      && (sec->flags & SEC_ALLOC) != 0)
     {
       /* Try for a rw code section.  */
       for (look = first; look; look = look->next)
@@ -1383,7 +1384,8 @@ lang_output_section_find_by_flags (const asection *sec,
            found = look;
        }
     }
-  else if (sec->flags & (SEC_READONLY | SEC_THREAD_LOCAL))
+  else if ((sec->flags & (SEC_READONLY | SEC_THREAD_LOCAL)) != 0
+          && (sec->flags & SEC_ALLOC) != 0)
     {
       /* .rodata can go after .text, .sdata2 after .rodata.  */
       for (look = first; look; look = look->next)
@@ -1404,7 +1406,8 @@ lang_output_section_find_by_flags (const asection *sec,
            found = look;
        }
     }
-  else if (sec->flags & SEC_SMALL_DATA)
+  else if ((sec->flags & SEC_SMALL_DATA) != 0
+          && (sec->flags & SEC_ALLOC) != 0)
     {
       /* .sdata goes after .data, .sbss after .sdata.  */
       for (look = first; look; look = look->next)
@@ -1426,7 +1429,8 @@ lang_output_section_find_by_flags (const asection *sec,
            found = look;
        }
     }
-  else if (sec->flags & SEC_HAS_CONTENTS)
+  else if ((sec->flags & SEC_HAS_CONTENTS) != 0
+          && (sec->flags & SEC_ALLOC) != 0)
     {
       /* .data goes after .rodata.  */
       for (look = first; look; look = look->next)
@@ -1446,9 +1450,9 @@ lang_output_section_find_by_flags (const asection *sec,
            found = look;
        }
     }
-  else
+  else if ((sec->flags & SEC_ALLOC) != 0)
     {
-      /* .bss goes last.  */
+      /* .bss goes after any other alloc section.  */
       for (look = first; look; look = look->next)
        {
          flags = look->flags;
@@ -1465,6 +1469,20 @@ lang_output_section_find_by_flags (const asection *sec,
            found = look;
        }
     }
+  else
+    {
+      /* non-alloc go last.  */
+      for (look = first; look; look = look->next)
+       {
+         flags = look->flags;
+         if (look->bfd_section != NULL)
+           flags = look->bfd_section->flags;
+         flags ^= sec->flags;
+         if (!(flags & SEC_DEBUGGING))
+           found = look;
+       }
+      return found;
+    }
 
   if (found || !match_type)
     return found;