Yet another set of fixes for orphan sections.
authorAlan Modra <amodra@gmail.com>
Tue, 18 Apr 2000 05:53:41 +0000 (05:53 +0000)
committerAlan Modra <amodra@gmail.com>
Tue, 18 Apr 2000 05:53:41 +0000 (05:53 +0000)
ld/ChangeLog
ld/emultempl/armelf.em
ld/emultempl/elf32.em
ld/emultempl/pe.em

index d24b36e..fc0c50e 100644 (file)
@@ -1,3 +1,14 @@
+2000-04-18  Alan Modra  <alan@linuxcare.com.au>
+
+       * emultempl/elf32.em (struct orphan_save): Add section field.
+       (gld${EMULATION_NAME}_place_orphan): Use above to keep sections in
+       better order, and place first orphan section as we did before the
+       2000-04-12 patch.  Ignore ~SEC_ALLOC sections when choosing place.
+       Don't call make_bfd_section here, let wild_doit do the job for us.
+       Don't build a statement list when we'll only throw it away.
+       * emultempl/armelf.em: Ditto.
+       * emultempl/pe.em: Similarly.
+
 2000-04-14  Geoff Keating  <geoffk@cygnus.com>
 
        * scripttempl/elfppc.sc: Remove.
 
 2000-04-14  Alan Modra  <alan@linuxcare.com.au>
 
-       * emultempl/elf32.em (gld${EMULATION_NAME}_place_section): Process
+       * emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): Process
        ~SEC_ALLOC sections too.  Init start address of debug sections.
-       * emultempl/armelf.em (gld${EMULATION_NAME}_place_section): Ditto.
-       * emultempl/pe.em (gld${EMULATION_NAME}_place_section): Ditto.
+       * emultempl/armelf.em (gld${EMULATION_NAME}_place_orphan): Ditto.
+       * emultempl/pe.em (gld${EMULATION_NAME}_place_orphan): Ditto.
        Also set all relocateable section start addresses.
 
 2000-04-13  Geoff Keating  <geoffk@cygnus.com>
index e5f1514..8632bd3 100644 (file)
@@ -789,6 +789,7 @@ static lang_output_section_statement_type *hold_use;
 struct orphan_save
 {
   lang_output_section_statement_type *os;
+  asection **section;
   lang_statement_union_type **stmt;
 };
 static struct orphan_save hold_text;
@@ -805,7 +806,6 @@ gld${EMULATION_NAME}_place_orphan (file, s)
      asection *s;
 {
   struct orphan_save *place;
-  asection *snew, **pps;
   lang_statement_list_type *old;
   lang_statement_list_type add;
   etree_type *address;
@@ -845,6 +845,8 @@ gld${EMULATION_NAME}_place_orphan (file, s)
      in the first page.  */
   if (s->flags & SEC_EXCLUDE)
     return false;
+  else if ((s->flags & SEC_ALLOC) == 0)
+    place = NULL;
   else if ((s->flags & SEC_LOAD) != 0
           && strncmp (secname, ".note", 4) == 0
           && hold_interp.os != NULL)
@@ -892,45 +894,29 @@ gld${EMULATION_NAME}_place_orphan (file, s)
       outsecname = newname;
     }
 
-  /* Create the section in the output file, and put it in the right
-     place.  This shuffling is to make the output file look neater.  */
-  snew = bfd_make_section (output_bfd, outsecname);
-  if (snew == NULL)
-      einfo ("%P%F: output format %s cannot represent section called %s\n",
-            output_bfd->xvec->name, outsecname);
-  if (place != NULL && place->os->bfd_section != NULL)
-    {
-      /* Unlink it first.  */
-      for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
-       ;
-      *pps = snew->next;
-      snew->next = NULL;
-      /* Now tack it on to the end of the "place->os" section list.  */
-      for (pps = &place->os->bfd_section; *pps; pps = &(*pps)->next)
-       ;
-      *pps = snew;
-    }
-
-  /* Start building a list of statements for this section.  */
-  old = stat_ptr;
-  stat_ptr = &add;
-  lang_list_init (stat_ptr);
-
-  /* If the name of the section is representable in C, then create
-     symbols to mark the start and the end of the section.  */
-  for (ps = outsecname; *ps != '\0'; ps++)
-    if (! isalnum ((unsigned char) *ps) && *ps != '_')
-      break;
-  if (*ps == '\0' && config.build_constructors)
+  if (place != NULL)
     {
-      char *symname;
-
-      symname = (char *) xmalloc (ps - outsecname + sizeof "__start_");
-      sprintf (symname, "__start_%s", outsecname);
-      lang_add_assignment (exp_assop ('=', symname,
-                                     exp_unop (ALIGN_K,
-                                               exp_intop ((bfd_vma) 1
-                                                          << s->alignment_power))));
+      /* Start building a list of statements for this section.  */
+      old = stat_ptr;
+      stat_ptr = &add;
+      lang_list_init (stat_ptr);
+
+      /* If the name of the section is representable in C, then create
+        symbols to mark the start and the end of the section.  */
+      for (ps = outsecname; *ps != '\0'; ps++)
+       if (! isalnum ((unsigned char) *ps) && *ps != '_')
+         break;
+      if (*ps == '\0' && config.build_constructors)
+       {
+         char *symname;
+         etree_type *e_align;
+
+         symname = (char *) xmalloc (ps - outsecname + sizeof "__start_");
+         sprintf (symname, "__start_%s", outsecname);
+         e_align = exp_unop (ALIGN_K,
+                             exp_intop ((bfd_vma) 1 << s->alignment_power));
+         lang_add_assignment (exp_assop ('=', symname, e_align));
+       }
     }
 
   if (link_info.relocateable || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0)
@@ -947,24 +933,59 @@ gld${EMULATION_NAME}_place_orphan (file, s)
   os = lang_output_section_statement_lookup (outsecname);
   wild_doit (&os->children, s, os, file);
 
-  lang_leave_output_section_statement
-    ((bfd_vma) 0, "*default*", (struct lang_output_section_phdr_list *) NULL,
-     "*default*");
-  stat_ptr = &add;
-
-  if (*ps == '\0' && config.build_constructors)
+  if (place != NULL)
     {
-      char *symname;
+      asection *snew, **pps;
 
-      symname = (char *) xmalloc (ps - outsecname + sizeof "__stop_");
-      sprintf (symname, "__stop_%s", outsecname);
-      lang_add_assignment (exp_assop ('=', symname,
-                                     exp_nameop (NAME, ".")));
-    }
+      lang_leave_output_section_statement
+       ((bfd_vma) 0, "*default*",
+        (struct lang_output_section_phdr_list *) NULL, "*default*");
+      stat_ptr = &add;
 
-  if (place != NULL)
-    {
-      if (! place->stmt)
+      if (*ps == '\0' && config.build_constructors)
+       {
+         char *symname;
+
+         symname = (char *) xmalloc (ps - outsecname + sizeof "__stop_");
+         sprintf (symname, "__stop_%s", outsecname);
+         lang_add_assignment (exp_assop ('=', symname,
+                                         exp_nameop (NAME, ".")));
+       }
+      stat_ptr = old;
+
+      snew = os->bfd_section;
+      if (place->os->bfd_section != NULL || place->section != NULL)
+       {
+         /* Shuffle the section to make the output file look neater.  */
+         if (place->section == NULL)
+           {
+#if 0
+             /* Finding the end of the list is a little tricky.  We
+                make a wild stab at it by comparing section flags.  */
+             flagword first_flags = place->os->bfd_section->flags;
+             for (pps = &place->os->bfd_section->next;
+                  *pps != NULL && (*pps)->flags == first_flags;
+                  pps = &(*pps)->next)
+               ;
+             place->section = pps;
+#else
+             /* Put orphans after the first section on the list.  */
+             place->section = &place->os->bfd_section->next;
+#endif
+           }
+
+         /*  Unlink the section.  */
+         for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
+           ;
+         *pps = snew->next;
+
+         /* Now tack it on to the "place->os" section list.  */
+         snew->next = *place->section;
+         *place->section = snew;
+       }
+      place->section = &snew->next;    /* Save the end of this list.  */
+
+      if (place->stmt == NULL)
        {
          /* Put the new statement list right at the head.  */
          *add.tail = place->os->header.next;
@@ -976,9 +997,8 @@ gld${EMULATION_NAME}_place_orphan (file, s)
          *add.tail = *place->stmt;
          *place->stmt = add.head;
        }
-      place->stmt = add.tail;  /* Save the end of this list.  */
+      place->stmt = add.tail;          /* Save the end of this list.  */
     }
-  stat_ptr = old;
 
   return true;
 }
index 2489779..d5ee9af 100644 (file)
@@ -871,6 +871,7 @@ static lang_output_section_statement_type *hold_use;
 struct orphan_save
 {
   lang_output_section_statement_type *os;
+  asection **section;
   lang_statement_union_type **stmt;
 };
 static struct orphan_save hold_text;
@@ -887,7 +888,6 @@ gld${EMULATION_NAME}_place_orphan (file, s)
      asection *s;
 {
   struct orphan_save *place;
-  asection *snew, **pps;
   lang_statement_list_type *old;
   lang_statement_list_type add;
   etree_type *address;
@@ -927,6 +927,8 @@ gld${EMULATION_NAME}_place_orphan (file, s)
      in the first page.  */
   if (s->flags & SEC_EXCLUDE)
     return false;
+  else if ((s->flags & SEC_ALLOC) == 0)
+    place = NULL;
   else if ((s->flags & SEC_LOAD) != 0
           && strncmp (secname, ".note", 4) == 0
           && hold_interp.os != NULL)
@@ -974,45 +976,29 @@ gld${EMULATION_NAME}_place_orphan (file, s)
       outsecname = newname;
     }
 
-  /* Create the section in the output file, and put it in the right
-     place.  This shuffling is to make the output file look neater.  */
-  snew = bfd_make_section (output_bfd, outsecname);
-  if (snew == NULL)
-      einfo ("%P%F: output format %s cannot represent section called %s\n",
-            output_bfd->xvec->name, outsecname);
-  if (place != NULL && place->os->bfd_section != NULL)
-    {
-      /* Unlink it first.  */
-      for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
-       ;
-      *pps = snew->next;
-      snew->next = NULL;
-      /* Now tack it on to the end of the "place->os" section list.  */
-      for (pps = &place->os->bfd_section; *pps; pps = &(*pps)->next)
-       ;
-      *pps = snew;
-    }
-
-  /* Start building a list of statements for this section.  */
-  old = stat_ptr;
-  stat_ptr = &add;
-  lang_list_init (stat_ptr);
-
-  /* If the name of the section is representable in C, then create
-     symbols to mark the start and the end of the section.  */
-  for (ps = outsecname; *ps != '\0'; ps++)
-    if (! isalnum ((unsigned char) *ps) && *ps != '_')
-      break;
-  if (*ps == '\0' && config.build_constructors)
+  if (place != NULL)
     {
-      char *symname;
-
-      symname = (char *) xmalloc (ps - outsecname + sizeof "__start_");
-      sprintf (symname, "__start_%s", outsecname);
-      lang_add_assignment (exp_assop ('=', symname,
-                                     exp_unop (ALIGN_K,
-                                               exp_intop ((bfd_vma) 1
-                                                          << s->alignment_power))));
+      /* Start building a list of statements for this section.  */
+      old = stat_ptr;
+      stat_ptr = &add;
+      lang_list_init (stat_ptr);
+
+      /* If the name of the section is representable in C, then create
+        symbols to mark the start and the end of the section.  */
+      for (ps = outsecname; *ps != '\0'; ps++)
+       if (! isalnum ((unsigned char) *ps) && *ps != '_')
+         break;
+      if (*ps == '\0' && config.build_constructors)
+       {
+         char *symname;
+         etree_type *e_align;
+
+         symname = (char *) xmalloc (ps - outsecname + sizeof "__start_");
+         sprintf (symname, "__start_%s", outsecname);
+         e_align = exp_unop (ALIGN_K,
+                             exp_intop ((bfd_vma) 1 << s->alignment_power));
+         lang_add_assignment (exp_assop ('=', symname, e_align));
+       }
     }
 
   if (link_info.relocateable || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0)
@@ -1029,24 +1015,59 @@ gld${EMULATION_NAME}_place_orphan (file, s)
   os = lang_output_section_statement_lookup (outsecname);
   wild_doit (&os->children, s, os, file);
 
-  lang_leave_output_section_statement
-    ((bfd_vma) 0, "*default*", (struct lang_output_section_phdr_list *) NULL,
-     "*default*");
-  stat_ptr = &add;
-
-  if (*ps == '\0' && config.build_constructors)
+  if (place != NULL)
     {
-      char *symname;
+      asection *snew, **pps;
 
-      symname = (char *) xmalloc (ps - outsecname + sizeof "__stop_");
-      sprintf (symname, "__stop_%s", outsecname);
-      lang_add_assignment (exp_assop ('=', symname,
-                                     exp_nameop (NAME, ".")));
-    }
+      lang_leave_output_section_statement
+       ((bfd_vma) 0, "*default*",
+        (struct lang_output_section_phdr_list *) NULL, "*default*");
+      stat_ptr = &add;
 
-  if (place != NULL)
-    {
-      if (! place->stmt)
+      if (*ps == '\0' && config.build_constructors)
+       {
+         char *symname;
+
+         symname = (char *) xmalloc (ps - outsecname + sizeof "__stop_");
+         sprintf (symname, "__stop_%s", outsecname);
+         lang_add_assignment (exp_assop ('=', symname,
+                                         exp_nameop (NAME, ".")));
+       }
+      stat_ptr = old;
+
+      snew = os->bfd_section;
+      if (place->os->bfd_section != NULL || place->section != NULL)
+       {
+         /* Shuffle the section to make the output file look neater.  */
+         if (place->section == NULL)
+           {
+#if 0
+             /* Finding the end of the list is a little tricky.  We
+                make a wild stab at it by comparing section flags.  */
+             flagword first_flags = place->os->bfd_section->flags;
+             for (pps = &place->os->bfd_section->next;
+                  *pps != NULL && (*pps)->flags == first_flags;
+                  pps = &(*pps)->next)
+               ;
+             place->section = pps;
+#else
+             /* Put orphans after the first section on the list.  */
+             place->section = &place->os->bfd_section->next;
+#endif
+           }
+
+         /*  Unlink the section.  */
+         for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
+           ;
+         *pps = snew->next;
+
+         /* Now tack it on to the "place->os" section list.  */
+         snew->next = *place->section;
+         *place->section = snew;
+       }
+      place->section = &snew->next;    /* Save the end of this list.  */
+
+      if (place->stmt == NULL)
        {
          /* Put the new statement list right at the head.  */
          *add.tail = place->os->header.next;
@@ -1058,9 +1079,8 @@ gld${EMULATION_NAME}_place_orphan (file, s)
          *add.tail = *place->stmt;
          *place->stmt = add.head;
        }
-      place->stmt = add.tail;  /* Save the end of this list.  */
+      place->stmt = add.tail;          /* Save the end of this list.  */
     }
-  stat_ptr = old;
 
   return true;
 }
index 0a94f58..aeecb61 100644 (file)
@@ -1081,6 +1081,7 @@ static lang_output_section_statement_type *hold_use;
 struct orphan_save
 {
   lang_output_section_statement_type *os;
+  asection **section;
   lang_statement_union_type **stmt;
 };
 static struct orphan_save hold_text;
@@ -1099,6 +1100,7 @@ gld_${EMULATION_NAME}_place_orphan (file, s)
 {
   const char *secname;
   char *dollar = NULL;
+  lang_statement_list_type add_child;
 
   secname = bfd_get_section_name (s->owner, s);
 
@@ -1117,11 +1119,16 @@ gld_${EMULATION_NAME}_place_orphan (file, s)
   hold_use = NULL;
   lang_for_each_statement (gld${EMULATION_NAME}_place_section);
 
-  if (hold_use == NULL)
+  lang_list_init (&add_child);
+
+  if (hold_use != NULL)
+    {
+      wild_doit (&add_child, s, hold_use, file);
+    }
+  else
     {
       struct orphan_save *place;
       char *outsecname;
-      asection *snew, **pps;
       lang_statement_list_type *old;
       lang_statement_list_type add;
       etree_type *address;
@@ -1129,8 +1136,10 @@ gld_${EMULATION_NAME}_place_orphan (file, s)
       /* 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_HAS_CONTENTS) == 0
-         && hold_bss.os != NULL)
+      if ((s->flags & SEC_ALLOC) == 0)
+       ;
+      else if ((s->flags & SEC_HAS_CONTENTS) == 0
+              && hold_bss.os != NULL)
        place = &hold_bss;
       else if ((s->flags & SEC_READONLY) == 0
               && hold_data.os != NULL)
@@ -1168,29 +1177,6 @@ gld_${EMULATION_NAME}_place_orphan (file, s)
          outsecname = newname;
        }
 
-      /* We don't want to free OUTSECNAME, as it may get attached to
-        the output section statement.  */
-
-      /* Create the section in the output file, and put it in the
-        right place.  This shuffling is to make the output file look
-        neater.  */
-      snew = bfd_make_section (output_bfd, outsecname);
-      if (snew == NULL)
-       einfo ("%P%F: output format %s cannot represent section called %s\n",
-              output_bfd->xvec->name, outsecname);
-      if (place != NULL && place->os->bfd_section != NULL)
-       {
-         /* Unlink it first.  */
-         for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
-           ;
-         *pps = snew->next;
-         snew->next = NULL;
-         /* Now tack it on to the end of the "place->os" section list.  */
-         for (pps = &place->os->bfd_section; *pps; pps = &(*pps)->next)
-           ;
-         *pps = snew;
-       }
-
       /* Start building a list of statements for this section.  */
       old = stat_ptr;
       stat_ptr = &add;
@@ -1213,15 +1199,52 @@ gld_${EMULATION_NAME}_place_orphan (file, s)
                                           (etree_type *) NULL);
 
       hold_use = lang_output_section_statement_lookup (outsecname);
+      wild_doit (&add_child, s, hold_use, file);
 
       lang_leave_output_section_statement
        ((bfd_vma) 0, "*default*",
         (struct lang_output_section_phdr_list *) NULL,
        "*default*");
 
+      stat_ptr = old;
+
       if (place != NULL)
        {
-         if (! place->stmt)
+         asection *snew, **pps;
+
+         snew = hold_use->bfd_section;
+         if (place->os->bfd_section != NULL || place->section != NULL)
+           {
+             /* Shuffle the section to make the output file look neater.  */
+             if (place->section == NULL)
+               {
+#if 0
+                 /* Finding the end of the list is a little tricky.  We
+                    make a wild stab at it by comparing section flags.  */
+                 flagword first_flags = place->os->bfd_section->flags;
+                 for (pps = &place->os->bfd_section->next;
+                      *pps != NULL && (*pps)->flags == first_flags;
+                      pps = &(*pps)->next)
+                   ;
+                 place->section = pps;
+#else
+                 /* Put orphans after the first section on the list.  */
+                 place->section = &place->os->bfd_section->next;
+#endif
+               }
+
+             /*  Unlink the section.  */
+             for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
+               ;
+             *pps = snew->next;
+
+             /* Now tack it on to the "place->os" section list.  */
+             snew->next = *place->section;
+             *place->section = snew;
+           }
+         place->section = &snew->next; /* Save the end of this list.  */
+
+         if (place->stmt == NULL)
            {
              /* Put the new statement list right at the head.  */
              *add.tail = place->os->header.next;
@@ -1235,55 +1258,50 @@ gld_${EMULATION_NAME}_place_orphan (file, s)
            }
          place->stmt = add.tail;       /* Save the end of this list.  */
        }
-
-      stat_ptr = old;
     }
 
-  if (dollar == NULL)
-    wild_doit (&hold_use->children, s, hold_use, file);
-  else
-    {
-      lang_statement_union_type **pl;
-      boolean found_dollar;
-      lang_statement_list_type list;
+  {
+    lang_statement_union_type **pl = &hold_use->children.head;
 
-      /* The section name has a '$'.  Sort it with the other '$'
-         sections.  */
+    if (dollar != NULL)
+      {
+       boolean found_dollar;
 
-      found_dollar = false;
-      for (pl = &hold_use->children.head; *pl != NULL; pl = &(*pl)->next)
-       {
-         lang_input_section_type *ls;
-         const char *lname;
+       /* The section name has a '$'.  Sort it with the other '$'
+          sections.  */
 
-         if ((*pl)->header.type != lang_input_section_enum)
-           continue;
+       found_dollar = false;
+       for ( ; *pl != NULL; pl = &(*pl)->next)
+         {
+           lang_input_section_type *ls;
+           const char *lname;
 
-         ls = &(*pl)->input_section;
+           if ((*pl)->header.type != lang_input_section_enum)
+             continue;
 
-         lname = bfd_get_section_name (ls->ifile->the_bfd, ls->section);
-         if (strchr (lname, '$') == NULL)
-           {
-             if (found_dollar)
-               break;
-           }
-         else
-           {
-             found_dollar = true;
-             if (strcmp (secname, lname) < 0)
-               break;
-           }
-       }
+           ls = &(*pl)->input_section;
 
-      lang_list_init (&list);
-      wild_doit (&list, s, hold_use, file);
-      if (list.head != NULL)
-       {
-         ASSERT (list.head->next == NULL);
-         list.head->next = *pl;
-         *pl = list.head;
-       }
-    }
+           lname = bfd_get_section_name (ls->ifile->the_bfd, ls->section);
+           if (strchr (lname, '$') == NULL)
+             {
+               if (found_dollar)
+                 break;
+             }
+           else
+             {
+               found_dollar = true;
+               if (strcmp (secname, lname) < 0)
+                 break;
+             }
+         }
+      }
+
+    if (add_child.head != NULL)
+      {
+       add_child.head->next = *pl;
+       *pl = add_child.head;
+      }
+  }
 
   free (hold_section_name);