* ldemul.c (ldemul_place_orphan): Add "constraint" param.
authorAlan Modra <amodra@gmail.com>
Sat, 4 Oct 2008 06:08:59 +0000 (06:08 +0000)
committerAlan Modra <amodra@gmail.com>
Sat, 4 Oct 2008 06:08:59 +0000 (06:08 +0000)
* ldemul.h (ldemul_place_orphan): Update prototype.
(struct ld_emulation_xfer_struct <place_orphan>): Likewise add param.
* ldlang.c (unique_section_p): Make static.
(lang_output_section_statement_lookup): Optimise creation of SPECIAL
sections.
(lang_insert_orphan): Add "constraint" param.  Pass to
lang_enter_output_section_statement.
(init_os): Don't use an existing bfd section for SPECIAL sections.
(lang_place_orphans): Don't rename unique output sections, instead
mark their output section statements SPECIAL.
* ldlang.h (lang_insert_orphan): Update prototype.
(unique_section_p): Delete.
* emultempl/beos.em (place_orphan): Add "constraint" param.
* emultempl/elf32.em (place_orphan): Likewise.  Don't match existing
output sections if set.
* emultempl/pe.em (place_orphan): Likewise.
* emultempl/pep.em (place_orphan): Likewise.
* emultempl/mmo.em (mmo_place_orphan): Update.
* emultempl/spuelf.em (spu_place_special_section): Update.

ld/ChangeLog
ld/emultempl/beos.em
ld/emultempl/elf32.em
ld/emultempl/mmo.em
ld/emultempl/pe.em
ld/emultempl/pep.em
ld/emultempl/spuelf.em
ld/ldemul.c
ld/ldemul.h
ld/ldlang.c
ld/ldlang.h

index deeec540ba508f50d91c9432a0281fabde8c9215..fc8345f84a88e5bbaaa1c73d6f7b1e75b68ad763 100644 (file)
@@ -1,3 +1,27 @@
+2008-10-04  Alan Modra  <amodra@bigpond.net.au>
+
+       PR 6931
+       * ldemul.c (ldemul_place_orphan): Add "constraint" param.
+       * ldemul.h (ldemul_place_orphan): Update prototype.
+       (struct ld_emulation_xfer_struct <place_orphan>): Likewise add param.
+       * ldlang.c (unique_section_p): Make static.
+       (lang_output_section_statement_lookup): Optimise creation of SPECIAL
+       sections.
+       (lang_insert_orphan): Add "constraint" param.  Pass to
+       lang_enter_output_section_statement.
+       (init_os): Don't use an existing bfd section for SPECIAL sections.
+       (lang_place_orphans): Don't rename unique output sections, instead
+       mark their output section statements SPECIAL.
+       * ldlang.h (lang_insert_orphan): Update prototype.
+       (unique_section_p): Delete.
+       * emultempl/beos.em (place_orphan): Add "constraint" param.
+       * emultempl/elf32.em (place_orphan): Likewise.  Don't match existing
+       output sections if set.
+       * emultempl/pe.em (place_orphan): Likewise.
+       * emultempl/pep.em (place_orphan): Likewise.
+       * emultempl/mmo.em (mmo_place_orphan): Update.
+       * emultempl/spuelf.em (spu_place_special_section): Update.
+
 2008-10-03  Alan Modra  <amodra@bigpond.net.au>
 
        PR 6931
index 997f3a63cec719157cd0bf10fec086fe438b1897..2777be86ac9c4a2a55bd1e4d82d2ebfb7b90413b 100644 (file)
@@ -665,7 +665,9 @@ gld_${EMULATION_NAME}_before_allocation (void)
    which are not mentioned in the linker script.  */
 
 static bfd_boolean
-gld${EMULATION_NAME}_place_orphan (asection *s, const char *secname)
+gld${EMULATION_NAME}_place_orphan (asection *s,
+                                  const char *secname,
+                                  int constraint)
 {
   char *output_secname, *ps;
   lang_output_section_statement_type *os;
@@ -694,7 +696,7 @@ gld${EMULATION_NAME}_place_orphan (asection *s, const char *secname)
   output_secname = xstrdup (secname);
   ps = strchr (output_secname + 1, '\$');
   *ps = 0;
-  os = lang_output_section_statement_lookup (output_secname, 0, TRUE);
+  os = lang_output_section_statement_lookup (output_secname, constraint, TRUE);
 
   /* Find the '\$' wild statement for this section.  We currently require the
      linker script to explicitly mention "*(.foo\$)".
index 65ad4f134616b798143244ce579d82200ab04f61..7eb4e28a46788e55317537960d9e4b2ab52fccf8 100644 (file)
@@ -62,7 +62,8 @@ fragment <<EOF
 static void gld${EMULATION_NAME}_before_parse (void);
 static void gld${EMULATION_NAME}_after_open (void);
 static void gld${EMULATION_NAME}_before_allocation (void);
-static bfd_boolean gld${EMULATION_NAME}_place_orphan (asection *, const char *);
+static bfd_boolean gld${EMULATION_NAME}_place_orphan
+  (asection *, const char *, int);
 static void gld${EMULATION_NAME}_finish (void);
 
 EOF
@@ -1635,7 +1636,9 @@ output_rel_find (asection *sec, int isdyn)
    sections in the right segment.  */
 
 static bfd_boolean
-gld${EMULATION_NAME}_place_orphan (asection *s, const char *secname)
+gld${EMULATION_NAME}_place_orphan (asection *s,
+                                  const char *secname,
+                                  int constraint)
 {
   static struct orphan_save hold[] =
     {
@@ -1705,9 +1708,8 @@ gld${EMULATION_NAME}_place_orphan (asection *s, const char *secname)
     }
 
   /* Look through the script to see where to place this section.  */
-  os = lang_output_section_find (secname);
-
-  if (os != NULL
+  if (constraint == 0
+      && (os = lang_output_section_find (secname)) != NULL
       && os->bfd_section != NULL
       && (os->bfd_section->flags == 0
          || (_bfd_elf_match_sections_by_type (link_info.output_bfd,
@@ -1796,7 +1798,7 @@ gld${EMULATION_NAME}_place_orphan (asection *s, const char *secname)
        after = &lang_output_section_statement.head->output_section_statement;
     }
 
-  lang_insert_orphan (s, secname, after, place, NULL, NULL);
+  lang_insert_orphan (s, secname, constraint, after, place, NULL, NULL);
 
   return TRUE;
 }
index 8b02fd64228e2b08657d9a7114cc2b74b0c676a1..4ff9846ed123ffc39534f8cffa0e03b831a92030 100644 (file)
@@ -47,7 +47,9 @@ fragment <<EOF
    from elf32.em.  */
 
 static bfd_boolean
-mmo_place_orphan (asection *s)
+mmo_place_orphan (asection *s,
+                 const char *secname,
+                 int constraint ATTRIBUTE_UNUSED)
 {
   static struct orphan_save hold_text =
     {
@@ -56,7 +58,6 @@ mmo_place_orphan (asection *s)
       0, 0, 0, 0
     };
   struct orphan_save *place;
-  const char *secname;
   lang_output_section_statement_type *after;
   lang_output_section_statement_type *os;
 
@@ -66,7 +67,6 @@ mmo_place_orphan (asection *s)
     return FALSE;
 
   /* Only care for sections we're going to load.  */
-  secname = s->name;
   os = lang_output_section_find (secname);
 
   /* We have an output section by this name.  Place the section inside it
@@ -93,7 +93,7 @@ mmo_place_orphan (asection *s)
 
   /* If there's an output section by this name, we'll use it, regardless
      of section flags, in contrast to what's done in elf32.em.  */
-  os = lang_insert_orphan (s, secname, after, place, NULL, NULL);
+  os = lang_insert_orphan (s, secname, 0, after, place, NULL, NULL);
 
   /* We need an output section for .text as a root, so if there was none
      (might happen with a peculiar linker script such as in "map
index 89c521d9e9e5a73a1959ebc0f5869ce38f6a9ef5..b01425704f17bf528885812a773f92deca3fcb0f 100644 (file)
@@ -1613,7 +1613,9 @@ gld_${EMULATION_NAME}_finish (void)
    sort_sections.  */
 
 static bfd_boolean
-gld_${EMULATION_NAME}_place_orphan (asection *s, const char *secname)
+gld_${EMULATION_NAME}_place_orphan (asection *s,
+                                   const char *secname,
+                                   int constraint)
 {
   const char *orig_secname = secname;
   char *dollar = NULL;
@@ -1631,11 +1633,10 @@ gld_${EMULATION_NAME}_place_orphan (asection *s, const char *secname)
       secname = newname;
     }
 
-  os = lang_output_section_find (secname);
-
   lang_list_init (&add_child);
 
-  if (os != NULL
+  if (constraint == 0
+      && (os = lang_output_section_find (secname)) != NULL
       && os->bfd_section != NULL
       && (os->bfd_section->flags == 0
          || ((s->flags ^ os->bfd_section->flags)
@@ -1721,7 +1722,8 @@ gld_${EMULATION_NAME}_place_orphan (asection *s, const char *secname)
 
       /* All sections in an executable must be aligned to a page boundary.  */
       address = exp_unop (ALIGN_K, exp_nameop (NAME, "__section_alignment__"));
-      os = lang_insert_orphan (s, secname, after, place, address, &add_child);
+      os = lang_insert_orphan (s, secname, constraint, after, place, address,
+                              &add_child);
     }
 
   {
index 4afac022b6dd58b47b35678e4556fb5f947945f8..386c98f99aaaf95b937e440a6e52b2c21f229f3a 100644 (file)
@@ -1372,7 +1372,9 @@ gld_${EMULATION_NAME}_finish (void)
    sort_sections.  */
 
 static bfd_boolean
-gld_${EMULATION_NAME}_place_orphan (asection *s, const char *secname)
+gld_${EMULATION_NAME}_place_orphan (asection *s,
+                                   const char *secname,
+                                   int constraint)
 {
   const char *orig_secname = secname;
   char *dollar = NULL;
@@ -1390,11 +1392,10 @@ gld_${EMULATION_NAME}_place_orphan (asection *s, const char *secname)
       secname = newname;
     }
 
-  os = lang_output_section_find (secname);
-
   lang_list_init (&add_child);
 
-  if (os != NULL
+  if (constraint == 0
+      && (os = lang_output_section_find (secname)) != NULL
       && os->bfd_section != NULL
       && (os->bfd_section->flags == 0
          || ((s->flags ^ os->bfd_section->flags)
@@ -1480,7 +1481,8 @@ gld_${EMULATION_NAME}_place_orphan (asection *s, const char *secname)
 
       /* All sections in an executable must be aligned to a page boundary.  */
       address = exp_unop (ALIGN_K, exp_nameop (NAME, "__section_alignment__"));
-      os = lang_insert_orphan (s, secname, after, place, address, &add_child);
+      os = lang_insert_orphan (s, secname, constraint, after, place, address,
+                              &add_child);
     }
 
   {
index bc2f6b548fc1efbf23892e1f42c8c337a16e2341..fe248af6a46b86bc2e6b1de90274bf0586932186 100644 (file)
@@ -114,7 +114,7 @@ spu_place_special_section (asection *s, asection *o, const char *output_name)
 
   os = lang_output_section_find (o != NULL ? o->name : output_name);
   if (os == NULL)
-    gld${EMULATION_NAME}_place_orphan (s, output_name);
+    gld${EMULATION_NAME}_place_orphan (s, output_name, 0);
   else if (o != NULL && os->children.head != NULL)
     {
       lang_statement_list_type add;
index 68e1de26210a1e76ec9014e4bdef69f345fe799e..567e8ac2cd40711b850f0cf58f238c3731843935 100644 (file)
@@ -120,10 +120,10 @@ ldemul_open_dynamic_archive (const char *arch, search_dirs_type *search,
 }
 
 bfd_boolean
-ldemul_place_orphan (asection *s, const char *name)
+ldemul_place_orphan (asection *s, const char *name, int constraint)
 {
   if (ld_emulation->place_orphan)
-    return (*ld_emulation->place_orphan) (s, name);
+    return (*ld_emulation->place_orphan) (s, name, constraint);
   return FALSE;
 }
 
index 6c95a9d9a16b644030fd51e513b7c04ef47703bf..65612583a78ab476274ef2c40031eccc50037f2a 100644 (file)
@@ -59,7 +59,7 @@ extern void ldemul_set_symbols
 extern void ldemul_create_output_section_statements
   (void);
 extern bfd_boolean ldemul_place_orphan
-  (asection *, const char *);
+  (asection *, const char *, int);
 extern bfd_boolean ldemul_parse_args
   (int, char **);
 extern void ldemul_add_options
@@ -152,7 +152,7 @@ typedef struct ld_emulation_xfer_struct {
      the default action should be taken.  This field may be NULL, in
      which case the default action will always be taken.  */
   bfd_boolean (*place_orphan)
-    (asection *, const char *);
+    (asection *, const char *, int);
 
   /* Run after assigning parsing with the args, but before
      reading the script.  Used to initialize symbols used in the script.  */
index 44fb136d84b3b51bdd9fc134be7b6ac8c01663de..29084490e7be6ffad779e8d12d35c2483026e867 100644 (file)
@@ -193,7 +193,7 @@ input_statement_is_archive_path (const char *file_spec, char *sep,
   return match;
 }
 
-bfd_boolean
+static bfd_boolean
 unique_section_p (const asection *sec)
 {
   struct unique_sections *unam;
@@ -1278,19 +1278,25 @@ lang_output_section_statement_lookup (const char *const name,
       struct out_section_hash_entry *last_ent;
       unsigned long hash = entry->root.hash;
 
-      do
-       {
-         if (entry->s.output_section_statement.constraint >= 0
-             && (constraint == 0
-                 || (constraint == entry->s.output_section_statement.constraint
-                     && constraint != SPECIAL)))
-           return &entry->s.output_section_statement;
-         last_ent = entry;
-         entry = (struct out_section_hash_entry *) entry->root.next;
-       }
-      while (entry != NULL
-            && entry->root.hash == hash
-            && strcmp (name, entry->s.output_section_statement.name) == 0);
+      if (create && constraint == SPECIAL)
+       /* Not traversing to the end reverses the order of the second
+          and subsequent SPECIAL sections in the hash table chain,
+          but that shouldn't matter.  */
+       last_ent = entry;
+      else
+       do
+         {
+           if (entry->s.output_section_statement.constraint >= 0
+               && (constraint == 0
+                   || (constraint
+                       == entry->s.output_section_statement.constraint)))
+             return &entry->s.output_section_statement;
+           last_ent = entry;
+           entry = (struct out_section_hash_entry *) entry->root.next;
+         }
+       while (entry != NULL
+              && entry->root.hash == hash
+              && strcmp (name, entry->s.output_section_statement.name) == 0);
 
       if (!create)
        return NULL;
@@ -1556,6 +1562,7 @@ insert_os_after (lang_output_section_statement_type *after)
 lang_output_section_statement_type *
 lang_insert_orphan (asection *s,
                    const char *secname,
+                   int constraint,
                    lang_output_section_statement_type *after,
                    struct orphan_save *place,
                    etree_type *address,
@@ -1611,7 +1618,7 @@ lang_insert_orphan (asection *s,
   os_tail = ((lang_output_section_statement_type **)
             lang_output_section_statement.tail);
   os = lang_enter_output_section_statement (secname, address, 0, NULL, NULL,
-                                           NULL, 0);
+                                           NULL, constraint);
 
   if (add_child == NULL)
     add_child = &os->children;
@@ -1914,10 +1921,11 @@ init_os (lang_output_section_statement_type *s, asection *isec,
   if (strcmp (s->name, DISCARD_SECTION_NAME) == 0)
     einfo (_("%P%F: Illegal use of `%s' section\n"), DISCARD_SECTION_NAME);
 
-  s->bfd_section = bfd_get_section_by_name (link_info.output_bfd, s->name);
+  if (s->constraint != SPECIAL)
+    s->bfd_section = bfd_get_section_by_name (link_info.output_bfd, s->name);
   if (s->bfd_section == NULL)
-    s->bfd_section = bfd_make_section_with_flags (link_info.output_bfd,
-                                                 s->name, flags);
+    s->bfd_section = bfd_make_section_anyway_with_flags (link_info.output_bfd,
+                                                        s->name, flags);
   if (s->bfd_section == NULL)
     {
       einfo (_("%P%F: output format %s cannot represent section called %s\n"),
@@ -5655,23 +5663,16 @@ lang_place_orphans (void)
              else
                {
                  const char *name = s->name;
+                 int constraint = 0;
 
-                 if ((config.unique_orphan_sections
-                      || unique_section_p (s))
-                     && bfd_get_section_by_name (link_info.output_bfd,
-                                                 name) != NULL)
-                   {
-                     static int count = 1;
-                     name = bfd_get_unique_section_name (link_info.output_bfd,
-                                                         name, &count);
-                     if (name == NULL)
-                       einfo ("%F%P: place_orphan failed: %E\n");
-                   }
+                 if (config.unique_orphan_sections || unique_section_p (s))
+                   constraint = SPECIAL;
 
-                 if (!ldemul_place_orphan (s, name))
+                 if (!ldemul_place_orphan (s, name, constraint))
                    {
                      lang_output_section_statement_type *os;
-                     os = lang_output_section_statement_lookup (name, 0,
+                     os = lang_output_section_statement_lookup (name,
+                                                                constraint,
                                                                 TRUE);
                      lang_add_section (&os->children, s, os);
                    }
index 8b652a8d7854544f1d4881365d0f8bc121e46c46..fd0465ea1ab7c81abe6c2b9ef5965579c537e0fb 100644 (file)
@@ -536,7 +536,7 @@ extern lang_output_section_statement_type *lang_output_section_find_by_flags
   (const asection *, lang_output_section_statement_type **,
    lang_match_sec_type_func);
 extern lang_output_section_statement_type *lang_insert_orphan
-  (asection *, const char *, lang_output_section_statement_type *,
+  (asection *, const char *, int, lang_output_section_statement_type *,
    struct orphan_save *, etree_type *, lang_statement_list_type *);
 extern lang_input_statement_type *lang_add_input_file
   (const char *, lang_input_file_enum_type, const char *);
@@ -604,8 +604,6 @@ extern void lang_register_vers_node
 extern void lang_append_dynamic_list (struct bfd_elf_version_expr *);
 extern void lang_append_dynamic_list_cpp_typeinfo (void);
 extern void lang_append_dynamic_list_cpp_new (void);
-bfd_boolean unique_section_p
-  (const asection *);
 extern void lang_add_unique
   (const char *);
 extern const char *lang_get_output_target