Remove path name from test case
[binutils-gdb.git] / ld / ldlang.c
index 2852a4222d36300af513f361adec040af115a6a5..566c2b8326ffe56e30048e5e9eb764ffe6ff1b08 100644 (file)
@@ -27,7 +27,6 @@
 #include "obstack.h"
 #include "bfdlink.h"
 #include "ctf-api.h"
-
 #include "ld.h"
 #include "ldmain.h"
 #include "ldexp.h"
 #include "demangle.h"
 #include "hashtab.h"
 #include "elf-bfd.h"
+#include "bfdver.h"
+
 #if BFD_SUPPORTS_PLUGINS
 #include "plugin.h"
-#endif /* BFD_SUPPORTS_PLUGINS */
+#endif
 
 #ifndef offsetof
 #define offsetof(TYPE, MEMBER) ((size_t) & (((TYPE*) 0)->MEMBER))
@@ -79,6 +80,8 @@ static unsigned int opb_shift = 0;
 /* Forward declarations.  */
 static void exp_init_os (etree_type *);
 static lang_input_statement_type *lookup_name (const char *);
+static bool wont_add_section_p (asection *,
+                               lang_output_section_statement_type *);
 static void insert_undefined (const char *);
 static bool sort_def_symbol (struct bfd_link_hash_entry *, void *);
 static lang_statement_union_type *new_statement (enum statement_enum type,
@@ -131,6 +134,7 @@ bool lang_has_input_file = false;
 bool had_output_filename = false;
 bool lang_float_flag = false;
 bool delete_output_file_on_failure = false;
+bool enable_linker_version = false;
 struct lang_phdr *lang_phdr_list;
 struct lang_nocrossrefs *nocrossref_list;
 struct asneeded_minfo **asneeded_list_tail;
@@ -431,10 +435,29 @@ walk_wild_section_match (lang_wild_statement_type *ptr,
     }
   else
     {
-      lang_input_statement_type *f;
-      /* Perform the iteration over a single file.  */
-      f = lookup_name (file_spec);
-      if (f != file)
+      /* XXX Matching against non-wildcard filename in wild statements
+        was done by going through lookup_name, which uses
+        ->local_sym_name to compare against, not ->filename.  We retain
+        this behaviour even though the above code paths use filename.
+        It would be more logical to use it here as well, in which
+        case the above wildcard() arm could be folded into this by using
+        name_match.  This would also solve the worry of what to do
+        about unset local_sym_name (in which case lookup_name simply adds
+        the input file again).  */
+      const char *filename = file->local_sym_name;
+      lang_input_statement_type *arch_is;
+      if (filename && filename_cmp (filename, file_spec) == 0)
+       ;
+      /* FIXME: see also walk_wild_file_in_exclude_list for why we
+        also check parents BFD (local_sym_)name to match input statements
+        with unadorned archive names.  */
+      else if (file->the_bfd
+              && file->the_bfd->my_archive
+              && (arch_is = bfd_usrdata (file->the_bfd->my_archive))
+              && arch_is->local_sym_name
+              && filename_cmp (arch_is->local_sym_name, file_spec) == 0)
+       ;
+      else
        return;
     }
 
@@ -516,7 +539,7 @@ get_init_priority (const asection *sec)
 /* Compare sections ASEC and BSEC according to SORT.  */
 
 static int
-compare_section (sort_type sort, asection *asec, asection *bsec)
+compare_section (sort_type sort, asection *asec, asection *bsec, bool reversed)
 {
   int ret;
   int a_priority, b_priority;
@@ -531,7 +554,10 @@ compare_section (sort_type sort, asection *asec, asection *bsec)
       b_priority = get_init_priority (bsec);
       if (a_priority < 0 || b_priority < 0)
        goto sort_by_name;
-      ret = a_priority - b_priority;
+      if (reversed)
+       ret = b_priority - a_priority;
+      else
+       ret = a_priority - b_priority;
       if (ret)
        break;
       else
@@ -545,11 +571,17 @@ compare_section (sort_type sort, asection *asec, asection *bsec)
 
     case by_name:
     sort_by_name:
-      ret = strcmp (bfd_section_name (asec), bfd_section_name (bsec));
+      if (reversed)
+       ret = strcmp (bfd_section_name (bsec), bfd_section_name (asec));
+      else
+       ret = strcmp (bfd_section_name (asec), bfd_section_name (bsec));
       break;
 
     case by_name_alignment:
-      ret = strcmp (bfd_section_name (asec), bfd_section_name (bsec));
+      if (reversed)
+       ret = strcmp (bfd_section_name (bsec), bfd_section_name (asec));
+      else
+       ret = strcmp (bfd_section_name (asec), bfd_section_name (bsec));
       if (ret)
        break;
       /* Fall through.  */
@@ -624,7 +656,11 @@ wild_sort (lang_wild_statement_type *wild,
          else
            ln = sort_filename (lsec->owner);
 
-         i = filename_cmp (fn, ln);
+         if (wild->filenames_reversed)
+           i = filename_cmp (ln, fn);
+         else
+           i = filename_cmp (fn, ln);
+
          if (i > 0)
            { tree = &((*tree)->right); continue; }
          else if (i < 0)
@@ -637,7 +673,11 @@ wild_sort (lang_wild_statement_type *wild,
              if (la)
                ln = sort_filename (lsec->owner);
 
-             i = filename_cmp (fn, ln);
+             if (wild->filenames_reversed)
+               i = filename_cmp (ln, fn);
+             else
+               i = filename_cmp (fn, ln);
+             
              if (i > 0)
                { tree = &((*tree)->right); continue; }
              else if (i < 0)
@@ -650,7 +690,7 @@ wild_sort (lang_wild_statement_type *wild,
 
       /* Find the correct node to append this section.  */
       if (sec && sec->spec.sorted != none && sec->spec.sorted != by_none
-         && compare_section (sec->spec.sorted, section, (*tree)->section) < 0)
+         && compare_section (sec->spec.sorted, section, (*tree)->section, sec->spec.reversed) < 0)
        tree = &((*tree)->left);
       else
        tree = &((*tree)->right);
@@ -677,6 +717,11 @@ output_section_callback_sort (lang_wild_statement_type *ptr,
   if (unique_section_p (section, os))
     return;
 
+  /* Don't add sections to the tree when we already know that
+     lang_add_section won't do anything with it.  */
+  if (wont_add_section_p (section, os))
+    return;
+
   node = (lang_section_bst_type *) xmalloc (sizeof (lang_section_bst_type));
   node->left = 0;
   node->right = 0;
@@ -1108,6 +1153,16 @@ new_afile (const char *name,
 
   lang_has_input_file = true;
 
+  /* PR 30632: It is OK for name to be NULL.  For example
+     see the initialization of first_file in lang_init().  */
+  if (name != NULL)
+    {
+      name = ldfile_possibly_remap_input (name);
+      /* But if a name is remapped to NULL, it should be ignored.  */
+      if (name == NULL)
+       return NULL;
+    }
+
   p = new_stat (lang_input_statement, stat_ptr);
   memset (&p->the_bfd, 0,
          sizeof (*p) - offsetof (lang_input_statement_type, the_bfd));
@@ -1311,6 +1366,7 @@ void
 lang_finish (void)
 {
   output_section_statement_table_free ();
+  ldfile_remap_input_free ();
 }
 
 /*----------------------------------------------------------------------
@@ -1774,7 +1830,7 @@ output_prev_sec_find (lang_output_section_statement_type *os)
       if (lookup->constraint < 0)
        continue;
 
-      if (lookup->bfd_section != NULL && lookup->bfd_section->owner != NULL)
+      if (lookup->bfd_section != NULL)
        return lookup->bfd_section;
     }
 
@@ -1793,13 +1849,13 @@ output_prev_sec_find (lang_output_section_statement_type *os)
    image symbols.  */
 
 static lang_statement_union_type **
-insert_os_after (lang_output_section_statement_type *after)
+insert_os_after (lang_statement_union_type *after)
 {
   lang_statement_union_type **where;
   lang_statement_union_type **assign = NULL;
   bool ignore_first;
 
-  ignore_first = after == (void *) lang_os_list.head;
+  ignore_first = after == lang_os_list.head;
 
   for (where = &after->header.next;
        *where != NULL;
@@ -1936,7 +1992,9 @@ lang_insert_orphan (asection *s,
          if (bfd_section == NULL)
            bfd_section = output_prev_sec_find (after);
 
-         if (bfd_section != NULL && bfd_section != snew)
+         if (bfd_section != NULL
+             && bfd_section->owner != NULL
+             && bfd_section != snew)
            place->section = &bfd_section->next;
        }
 
@@ -2159,8 +2217,9 @@ lang_insert_orphan (asection *s,
          /* Place OS after AFTER if AFTER_NOTE is TRUE.  */
          if (place_after)
            {
-             lang_statement_union_type **where = insert_os_after (after);
+             lang_statement_union_type **where;
 
+             where = insert_os_after ((lang_statement_union_type *) after);
              *add.tail = *where;
              *where = add.head;
 
@@ -2260,6 +2319,8 @@ lang_map (void)
   lang_memory_region_type *m;
   bool dis_header_printed = false;
 
+  ldfile_print_input_remaps ();
+
   LANG_FOR_EACH_INPUT_STATEMENT (file)
     {
       asection *s;
@@ -2276,13 +2337,15 @@ lang_map (void)
            {
              if (! dis_header_printed)
                {
-                 fprintf (config.map_file, _("\nDiscarded input sections\n\n"));
+                 minfo (_("\nDiscarded input sections\n\n"));
                  dis_header_printed = true;
                }
 
              print_input_section (s, true);
            }
     }
+  if (config.print_map_discarded && ! dis_header_printed)
+    minfo (_("\nThere are no discarded input sections\n"));
 
   minfo (_("\nMemory Configuration\n\n"));
   fprintf (config.map_file, "%-16s %-18s %-18s %s\n",
@@ -2310,7 +2373,7 @@ lang_map (void)
       print_nl ();
     }
 
-  fprintf (config.map_file, _("\nLinker script and memory map\n\n"));
+  minfo (_("\nLinker script and memory map\n\n"));
 
   if (!link_info.reduce_memory_overheads)
     {
@@ -2393,10 +2456,24 @@ init_os (lang_output_section_statement_type *s, flagword flags)
 
   /* If supplied an alignment, set it.  */
   if (s->section_alignment != NULL)
-    s->bfd_section->alignment_power = exp_get_power (s->section_alignment,
+    s->bfd_section->alignment_power = exp_get_power (s->section_alignment, s,
                                                     "section alignment");
 }
 
+static flagword
+get_os_init_flag (lang_output_section_statement_type * os)
+{
+  if (os != NULL)
+    switch (os->sectype)
+      {
+      case readonly_section: return SEC_READONLY;
+      case noload_section:   return SEC_NEVER_LOAD;
+      default: break;
+      }
+
+  return 0;
+}
+
 /* Make sure that all output sections mentioned in an expression are
    initialized.  */
 
@@ -2440,7 +2517,7 @@ exp_init_os (etree_type *exp)
 
            os = lang_output_section_find (exp->name.name);
            if (os != NULL && os->bfd_section == NULL)
-             init_os (os, 0);
+             init_os (os, get_os_init_flag (os));
          }
        }
       break;
@@ -2498,30 +2575,27 @@ lang_discard_section_p (asection *section)
       && (flags & SEC_DEBUGGING) != 0)
     discard = true;
 
+  /* Discard non-alloc sections if we are stripping section headers.  */
+  else if (config.no_section_header && (flags & SEC_ALLOC) == 0)
+    discard = true;
+
   return discard;
 }
 
-/* The wild routines.
-
-   These expand statements like *(.text) and foo.o to a list of
-   explicit actions, like foo.o(.text), bar.o(.text) and
-   foo.o(.text, .data).  */
+/* Return TRUE if SECTION is never going to be added to output statement
+   OUTPUT.  lang_add_section() definitely won't do anything with SECTION
+   if this returns TRUE.  It may do something (or not) if this returns FALSE.
 
-/* Add SECTION to the output section OUTPUT.  Do this by creating a
-   lang_input_section statement which is placed at PTR.  */
+   Can be used as early-out to filter matches.  This may set
+   output_section of SECTION, if it was unset, to the abs section in case
+   we discover SECTION to be always discarded.  This may also give
+   warning messages.  */
 
-void
-lang_add_section (lang_statement_list_type *ptr,
-                 asection *section,
-                 struct wildcard_list *pattern,
-                 struct flag_info *sflag_info,
-                 lang_output_section_statement_type *output)
+static bool
+wont_add_section_p (asection *section,
+                   lang_output_section_statement_type *output)
 {
-  flagword flags = section->flags;
-
   bool discard;
-  lang_input_section_type *new_section;
-  bfd *abfd = link_info.output_bfd;
 
   /* Is this section one we know should be discarded?  */
   discard = lang_discard_section_p (section);
@@ -2535,41 +2609,35 @@ lang_add_section (lang_statement_list_type *ptr,
     {
       if (section->output_section == NULL)
        {
-         /* This prevents future calls from assigning this section.  */
+         /* This prevents future calls from assigning this section or
+            warning about it again.  */
          section->output_section = bfd_abs_section_ptr;
        }
+      else if (bfd_is_abs_section (section->output_section))
+       ;
       else if (link_info.non_contiguous_regions_warnings)
        einfo (_("%P:%pS: warning: --enable-non-contiguous-regions makes "
                 "section `%pA' from `%pB' match /DISCARD/ clause.\n"),
               NULL, section, section->owner);
 
-      return;
-    }
-
-  if (sflag_info)
-    {
-      bool keep;
-
-      keep = bfd_lookup_section_flags (&link_info, sflag_info, section);
-      if (!keep)
-       return;
+      return true;
     }
 
   if (section->output_section != NULL)
     {
       if (!link_info.non_contiguous_regions)
-       return;
+       return true;
 
       /* SECTION has already been handled in a special way
         (eg. LINK_ONCE): skip it.  */
       if (bfd_is_abs_section (section->output_section))
-       return;
+       return true;
 
       /* Already assigned to the same output section, do not process
         it again, to avoid creating loops between duplicate sections
         later.  */
       if (section->output_section == output->bfd_section)
-       return;
+       return true;
 
       if (link_info.non_contiguous_regions_warnings && output->bfd_section)
        einfo (_("%P:%pS: warning: --enable-non-contiguous-regions may "
@@ -2584,6 +2652,42 @@ lang_add_section (lang_statement_list_type *ptr,
         size_input_section as appropriate.  */
     }
 
+  return false;
+}
+
+/* The wild routines.
+
+   These expand statements like *(.text) and foo.o to a list of
+   explicit actions, like foo.o(.text), bar.o(.text) and
+   foo.o(.text, .data).  */
+
+/* Add SECTION to the output section OUTPUT.  Do this by creating a
+   lang_input_section statement which is placed at PTR.  */
+
+void
+lang_add_section (lang_statement_list_type *ptr,
+                 asection *section,
+                 struct wildcard_list *pattern,
+                 struct flag_info *sflag_info,
+                 lang_output_section_statement_type *output)
+{
+  flagword flags = section->flags;
+
+  lang_input_section_type *new_section;
+  bfd *abfd = link_info.output_bfd;
+
+  if (wont_add_section_p (section, output))
+    return;
+
+  if (sflag_info)
+    {
+      bool keep;
+
+      keep = bfd_lookup_section_flags (&link_info, sflag_info, section);
+      if (!keep)
+       return;
+    }
+
   /* We don't copy the SEC_NEVER_LOAD flag from an input section
      to an output section, because we want to be able to include a
      SEC_NEVER_LOAD section in the middle of an otherwise loaded
@@ -3371,6 +3475,10 @@ ldlang_open_output (lang_statement_union_type *statement)
        link_info.output_bfd->flags |= BFD_TRADITIONAL_FORMAT;
       else
        link_info.output_bfd->flags &= ~BFD_TRADITIONAL_FORMAT;
+      if (config.no_section_header)
+       link_info.output_bfd->flags |= BFD_NO_SECTION_HEADER;
+      else
+       link_info.output_bfd->flags &= ~BFD_NO_SECTION_HEADER;
       break;
 
     case lang_target_statement_enum:
@@ -3417,17 +3525,20 @@ static struct bfd_link_hash_entry *plugin_undefs = NULL;
 #endif
 
 static void
-open_input_bfds (lang_statement_union_type *s, enum open_bfd_mode mode)
+open_input_bfds (lang_statement_union_type *s,
+                lang_output_section_statement_type *os,
+                enum open_bfd_mode mode)
 {
   for (; s != NULL; s = s->header.next)
     {
       switch (s->header.type)
        {
        case lang_constructors_statement_enum:
-         open_input_bfds (constructor_list.head, mode);
+         open_input_bfds (constructor_list.head, os, mode);
          break;
        case lang_output_section_statement_enum:
-         open_input_bfds (s->output_section_statement.children.head, mode);
+         os = &s->output_section_statement;
+         open_input_bfds (os->children.head, os, mode);
          break;
        case lang_wild_statement_enum:
          /* Maybe we should load the file's symbols.  */
@@ -3436,7 +3547,7 @@ open_input_bfds (lang_statement_union_type *s, enum open_bfd_mode mode)
              && !wildcardp (s->wild_statement.filename)
              && !archive_path (s->wild_statement.filename))
            lookup_name (s->wild_statement.filename);
-         open_input_bfds (s->wild_statement.children.head, mode);
+         open_input_bfds (s->wild_statement.children.head, os, mode);
          break;
        case lang_group_statement_enum:
          {
@@ -3455,7 +3566,7 @@ open_input_bfds (lang_statement_union_type *s, enum open_bfd_mode mode)
                plugin_insert_save = plugin_insert;
 #endif
                undefs = link_info.hash->undefs_tail;
-               open_input_bfds (s->group_statement.children.head,
+               open_input_bfds (s->group_statement.children.head, os,
                                 mode | OPEN_BFD_FORCE);
              }
            while (undefs != link_info.hash->undefs_tail
@@ -3542,7 +3653,7 @@ open_input_bfds (lang_statement_union_type *s, enum open_bfd_mode mode)
          break;
        case lang_assignment_statement_enum:
          if (s->assignment_statement.exp->type.node_class != etree_assert)
-           exp_fold_tree_no_dot (s->assignment_statement.exp);
+           exp_fold_tree_no_dot (s->assignment_statement.exp, os);
          break;
        default:
          break;
@@ -4104,6 +4215,9 @@ map_input_to_output_sections
                                        os);
          break;
        case lang_data_statement_enum:
+         if (os == NULL)
+           /* This should never happen.  */
+           FAIL ();
          /* Make sure that any sections mentioned in the expression
             are initialized.  */
          exp_init_os (s->data_statement.exp);
@@ -4150,7 +4264,7 @@ map_input_to_output_sections
                }
             else
               {
-                exp_fold_tree_no_dot (os->sectype_value);
+                exp_fold_tree_no_dot (os->sectype_value, os);
                 if (expld.result.valid_p)
                   type = expld.result.value;
                 else
@@ -4182,14 +4296,16 @@ map_input_to_output_sections
          if (os != NULL && os->bfd_section == NULL)
            init_os (os, 0);
          break;
+
        case lang_assignment_statement_enum:
          if (os != NULL && os->bfd_section == NULL)
-           init_os (os, 0);
+           init_os (os, get_os_init_flag (os));
 
          /* Make sure that any sections mentioned in the assignment
             are initialized.  */
          exp_init_os (s->assignment_statement.exp);
          break;
+
        case lang_address_statement_enum:
          /* Mark the specified section with the supplied address.
             If this section was actually a segment marker, then the
@@ -4370,21 +4486,55 @@ process_insert_statements (lang_statement_union_type **start)
                      else
                        link_info.output_bfd->section_last = first_sec->prev;
                      /* Add back.  */
-                     last_sec->next = sec->next;
-                     if (sec->next != NULL)
-                       sec->next->prev = last_sec;
+                     if (sec->owner == NULL)
+                       /* SEC is the absolute section, from the
+                          first dummy output section statement.  Add
+                          back the sections we trimmed off to the
+                          start of the bfd sections.  */
+                       sec = NULL;
+                     if (sec != NULL)
+                       last_sec->next = sec->next;
+                     else
+                       last_sec->next = link_info.output_bfd->sections;
+                     if (last_sec->next != NULL)
+                       last_sec->next->prev = last_sec;
                      else
                        link_info.output_bfd->section_last = last_sec;
                      first_sec->prev = sec;
-                     sec->next = first_sec;
+                     if (first_sec->prev != NULL)
+                       first_sec->prev->next = first_sec;
+                     else
+                       link_info.output_bfd->sections = first_sec;
                    }
                }
-
-             first_os = NULL;
-             last_os = NULL;
            }
 
-         ptr = insert_os_after (where);
+         lang_statement_union_type *after = (void *) where;
+         if (where == &lang_os_list.head->output_section_statement
+             && where->next == first_os)
+           {
+             /* PR30155.  Handle a corner case where the statement
+                list is something like the following:
+                . LOAD t.o
+                . .data           0x0000000000000000        0x0
+                .                 [0x0000000000000000]              b = .
+                .  *(.data)
+                .  .data          0x0000000000000000        0x0 t.o
+                .                 0x0000000000000000        0x4 LONG 0x0
+                . INSERT BEFORE .text.start
+                .                 [0x0000000000000004]              a = .
+                . .text.start     0x0000000000000000        0x0
+                .                 [0x0000000000000000]              c = .
+                . OUTPUT(a.out elf64-x86-64)
+                Here we do not want to allow insert_os_after to
+                choose a point inside the list we are moving.
+                That would lose the list.  Instead, let
+                insert_os_after work from the INSERT, which in this
+                particular example will result in inserting after
+                the assignment "a = .".  */
+             after = *s;
+           }
+         ptr = insert_os_after (after);
          /* Snip everything from the start of the list, up to and
             including the insert statement we are currently processing.  */
          first = *start;
@@ -4395,6 +4545,8 @@ process_insert_statements (lang_statement_union_type **start)
            statement_list.tail = s;
          *ptr = first;
          s = start;
+         first_os = NULL;
+         last_os = NULL;
          continue;
        }
       s = &(*s)->header.next;
@@ -4541,6 +4693,7 @@ print_output_section_statement
 
          if (output_section_statement->update_dot_tree != NULL)
            exp_fold_tree (output_section_statement->update_dot_tree,
+                          output_section_statement,
                           bfd_abs_section_ptr, &print_dot);
        }
 
@@ -4579,7 +4732,7 @@ print_assignment (lang_assignment_statement_type *assignment,
     osec = bfd_abs_section_ptr;
 
   if (assignment->exp->type.node_class != etree_provide)
-    exp_fold_tree (tree, osec, &print_dot);
+    exp_fold_tree (tree, output_section, osec, &print_dot);
   else
     expld.result.valid_p = false;
 
@@ -4718,6 +4871,50 @@ print_all_symbols (asection *sec)
   obstack_free (&map_obstack, entries);
 }
 
+/* Returns TRUE if SYM is a symbol suitable for printing
+   in a linker map as a local symbol.  */
+
+static bool
+ld_is_local_symbol (asymbol * sym)
+{
+  const char * name = bfd_asymbol_name (sym);
+
+  if (name == NULL || *name == 0)
+    return false;
+
+  if (strcmp (name, "(null)") == 0)
+    return false;
+
+  /* Skip .Lxxx and such like.  */
+  if (bfd_is_local_label (link_info.output_bfd, sym))
+    return false;
+
+  /* FIXME: This is intended to skip ARM mapping symbols,
+     which for some reason are not excluded by bfd_is_local_label,
+     but maybe it is wrong for other architectures.
+     It would be better to fix bfd_is_local_label.  */  
+  if (*name == '$')
+    return false;
+
+  /* Some local symbols, eg _GLOBAL_OFFSET_TABLE_, are present
+     in the hash table, so do not print duplicates here.  */
+  struct bfd_link_hash_entry * h;
+  h = bfd_link_hash_lookup (link_info.hash, name, false /* create */, 
+                           false /* copy */, true /* follow */);
+  if (h == NULL)
+    return true;
+  
+  /* Symbols from the plugin owned BFD will not get their own
+     iteration of this function, but can be on the link_info
+     list.  So include them here.  */
+  if (h->u.def.section->owner != NULL
+      && ((bfd_get_file_flags (h->u.def.section->owner) & (BFD_LINKER_CREATED | BFD_PLUGIN))
+         == (BFD_LINKER_CREATED | BFD_PLUGIN)))
+    return true;
+
+  return false;
+}
+
 /* Print information about an input section to the map file.  */
 
 static void
@@ -4773,6 +4970,44 @@ print_input_section (asection *i, bool is_discarded)
         later overlay is shorter than an earier one.  */
       if (addr + TO_ADDR (size) > print_dot)
        print_dot = addr + TO_ADDR (size);
+
+      if (config.print_map_locals)
+       {
+         long  storage_needed;
+
+         /* FIXME: It would be better to cache this table, rather
+            than recreating it for each output section.  */
+         /* FIXME: This call is not working for non-ELF based targets.
+            Find out why.  */
+         storage_needed = bfd_get_symtab_upper_bound (link_info.output_bfd);
+         if (storage_needed > 0)
+           {
+             asymbol **  symbol_table;
+             long        number_of_symbols;
+             long        j;
+
+             symbol_table = xmalloc (storage_needed);
+             number_of_symbols = bfd_canonicalize_symtab (link_info.output_bfd, symbol_table);
+
+             for (j = 0; j < number_of_symbols; j++)
+               {
+                 asymbol *     sym = symbol_table[j];
+                 bfd_vma       sym_addr = sym->value + i->output_section->vma;
+                 
+                 if (sym->section == i->output_section
+                     && (sym->flags & BSF_LOCAL) != 0
+                     && sym_addr >= addr
+                     && sym_addr < print_dot
+                     && ld_is_local_symbol (sym))
+                   {
+                     print_spaces (SECTION_NAME_MAP_LENGTH);
+                     minfo ("0x%V        (local) %s\n", sym_addr, bfd_asymbol_name (sym));
+                   }
+               }
+
+             free (symbol_table);
+           }
+       }
     }
 }
 
@@ -4933,10 +5168,14 @@ print_wild_statement (lang_wild_statement_type *w,
 
   if (w->filenames_sorted)
     minfo ("SORT_BY_NAME(");
+  if (w->filenames_reversed)
+    minfo ("REVERSE(");
   if (w->filename != NULL)
     minfo ("%s", w->filename);
   else
     minfo ("*");
+  if (w->filenames_reversed)
+    minfo (")");
   if (w->filenames_sorted)
     minfo (")");
 
@@ -4981,6 +5220,12 @@ print_wild_statement (lang_wild_statement_type *w,
          break;
        }
 
+      if (sec->spec.reversed)
+       {
+         minfo ("REVERSE(");
+         closing_paren++;
+       }
+
       if (sec->spec.exclude_name_list != NULL)
        {
          name_list *tmp;
@@ -5228,6 +5473,7 @@ size_input_section
       if (output_section_statement->subsection_alignment != NULL)
        i->alignment_power
          = exp_get_power (output_section_statement->subsection_alignment,
+                          output_section_statement,
                           "subsection alignment");
 
       if (o->alignment_power < i->alignment_power)
@@ -5566,7 +5812,7 @@ ldlang_check_relro_region (lang_statement_union_type *s)
 static bfd_vma
 lang_size_sections_1
   (lang_statement_union_type **prev,
-   lang_output_section_statement_type *output_section_statement,
+   lang_output_section_statement_type *current_os,
    fill_type *fill,
    bfd_vma dot,
    bool *relax,
@@ -5575,6 +5821,7 @@ lang_size_sections_1
   lang_statement_union_type *s;
   lang_statement_union_type *prev_s = NULL;
   bool removed_prev_s = false;
+  lang_output_section_statement_type *os = current_os;
 
   /* Size up the sections from their constituent parts.  */
   for (s = *prev; s != NULL; prev_s = s, s = s->header.next)
@@ -5586,7 +5833,6 @@ lang_size_sections_1
        case lang_output_section_statement_enum:
          {
            bfd_vma newdot, after, dotdelta;
-           lang_output_section_statement_type *os;
            lang_memory_region_type *r;
            int section_alignment = 0;
 
@@ -5605,7 +5851,7 @@ lang_size_sections_1
              os->addr_tree = exp_intop (0);
            if (os->addr_tree != NULL)
              {
-               exp_fold_tree (os->addr_tree, bfd_abs_section_ptr, &dot);
+               exp_fold_tree (os->addr_tree, os, bfd_abs_section_ptr, &dot);
 
                if (expld.result.valid_p)
                  {
@@ -5710,7 +5956,7 @@ lang_size_sections_1
                    section_alignment = os->bfd_section->alignment_power;
                  }
                else
-                 section_alignment = exp_get_power (os->section_alignment,
+                 section_alignment = exp_get_power (os->section_alignment, os,
                                                     "section alignment");
 
                /* Align to what the section needs.  */
@@ -5798,6 +6044,7 @@ lang_size_sections_1
                       statement.  */
                    if (os->lma_region != os->region)
                      section_alignment = exp_get_power (os->section_alignment,
+                                                        os,
                                                         "section alignment");
                    if (section_alignment > 0)
                      lma = align_power (lma, section_alignment);
@@ -5887,7 +6134,7 @@ lang_size_sections_1
            dot += dotdelta;
 
            if (os->update_dot_tree != 0)
-             exp_fold_tree (os->update_dot_tree, bfd_abs_section_ptr, &dot);
+             exp_fold_tree (os->update_dot_tree, os, bfd_abs_section_ptr, &dot);
 
            /* Update dot in the region ?
               We only do this if the section is going to be allocated,
@@ -5918,8 +6165,7 @@ lang_size_sections_1
          break;
 
        case lang_constructors_statement_enum:
-         dot = lang_size_sections_1 (&constructor_list.head,
-                                     output_section_statement,
+         dot = lang_size_sections_1 (&constructor_list.head, current_os,
                                      fill, dot, relax, check_regions);
          break;
 
@@ -5927,14 +6173,13 @@ lang_size_sections_1
          {
            unsigned int size = 0;
 
-           s->data_statement.output_offset =
-             dot - output_section_statement->bfd_section->vma;
-           s->data_statement.output_section =
-             output_section_statement->bfd_section;
+           s->data_statement.output_offset = dot - current_os->bfd_section->vma;
+           s->data_statement.output_section = current_os->bfd_section;
 
            /* We might refer to provided symbols in the expression, and
               need to mark them as needed.  */
-           exp_fold_tree (s->data_statement.exp, bfd_abs_section_ptr, &dot);
+           exp_fold_tree (s->data_statement.exp, os,
+                          bfd_abs_section_ptr, &dot);
 
            switch (s->data_statement.type)
              {
@@ -5957,10 +6202,9 @@ lang_size_sections_1
            if (size < TO_SIZE ((unsigned) 1))
              size = TO_SIZE ((unsigned) 1);
            dot += TO_ADDR (size);
-           if (!(output_section_statement->bfd_section->flags
-                 & SEC_FIXED_SIZE))
-             output_section_statement->bfd_section->size
-               = TO_SIZE (dot - output_section_statement->bfd_section->vma);
+           if (!(current_os->bfd_section->flags & SEC_FIXED_SIZE))
+             current_os->bfd_section->size
+               = TO_SIZE (dot - current_os->bfd_section->vma);
 
          }
          break;
@@ -5969,29 +6213,27 @@ lang_size_sections_1
          {
            int size;
 
-           s->reloc_statement.output_offset =
-             dot - output_section_statement->bfd_section->vma;
-           s->reloc_statement.output_section =
-             output_section_statement->bfd_section;
+           s->reloc_statement.output_offset
+             = dot - current_os->bfd_section->vma;
+           s->reloc_statement.output_section
+             = current_os->bfd_section;
            size = bfd_get_reloc_size (s->reloc_statement.howto);
            dot += TO_ADDR (size);
-           if (!(output_section_statement->bfd_section->flags
-                 & SEC_FIXED_SIZE))
-             output_section_statement->bfd_section->size
-               = TO_SIZE (dot - output_section_statement->bfd_section->vma);
+           if (!(current_os->bfd_section->flags & SEC_FIXED_SIZE))
+             current_os->bfd_section->size
+               = TO_SIZE (dot - current_os->bfd_section->vma);
          }
          break;
 
        case lang_wild_statement_enum:
          dot = lang_size_sections_1 (&s->wild_statement.children.head,
-                                     output_section_statement,
-                                     fill, dot, relax, check_regions);
+                                     current_os, fill, dot, relax,
+                                     check_regions);
          break;
 
        case lang_object_symbols_statement_enum:
-         link_info.create_object_symbols_section
-           = output_section_statement->bfd_section;
-         output_section_statement->bfd_section->flags |= SEC_KEEP;
+         link_info.create_object_symbols_section = current_os->bfd_section;
+         current_os->bfd_section->flags |= SEC_KEEP;
          break;
 
        case lang_output_statement_enum:
@@ -6012,8 +6254,7 @@ lang_size_sections_1
                if (again)
                  *relax = true;
              }
-           dot = size_input_section (prev, output_section_statement,
-                                     fill, &removed, dot);
+           dot = size_input_section (prev, current_os, fill, &removed, dot);
          }
          break;
 
@@ -6021,8 +6262,7 @@ lang_size_sections_1
          break;
 
        case lang_fill_statement_enum:
-         s->fill_statement.output_section =
-           output_section_statement->bfd_section;
+         s->fill_statement.output_section = current_os->bfd_section;
 
          fill = s->fill_statement.fill;
          break;
@@ -6034,9 +6274,7 @@ lang_size_sections_1
 
            expld.dataseg.relro = exp_seg_relro_none;
 
-           exp_fold_tree (tree,
-                          output_section_statement->bfd_section,
-                          &newdot);
+           exp_fold_tree (tree, os, current_os->bfd_section, &newdot);
 
            ldlang_check_relro_region (s);
 
@@ -6047,11 +6285,11 @@ lang_size_sections_1
                 || tree->type.node_class == etree_assign)
                && (tree->assign.dst [0] != '.'
                    || tree->assign.dst [1] != '\0'))
-             output_section_statement->update_dot = 1;
+             current_os->update_dot = 1;
 
-           if (!output_section_statement->ignored)
+           if (!current_os->ignored)
              {
-               if (output_section_statement == abs_output_section)
+               if (current_os == abs_output_section)
                  {
                    /* If we don't have an output section, then just adjust
                       the default memory address.  */
@@ -6064,7 +6302,7 @@ lang_size_sections_1
                       put the pad before when relaxing, in case the
                       assignment references dot.  */
                    insert_pad (&s->header.next, fill, TO_SIZE (newdot - dot),
-                               output_section_statement->bfd_section, dot);
+                               current_os->bfd_section, dot);
 
                    /* Don't neuter the pad below when relaxing.  */
                    s = s->header.next;
@@ -6073,11 +6311,11 @@ lang_size_sections_1
                       should have space allocated to it, unless the
                       user has explicitly stated that the section
                       should not be allocated.  */
-                   if (output_section_statement->sectype != noalloc_section
-                       && (output_section_statement->sectype != noload_section
+                   if (current_os->sectype != noalloc_section
+                       && (current_os->sectype != noload_section
                            || (bfd_get_flavour (link_info.output_bfd)
                                == bfd_target_elf_flavour)))
-                     output_section_statement->bfd_section->flags |= SEC_ALLOC;
+                     current_os->bfd_section->flags |= SEC_ALLOC;
                  }
                dot = newdot;
              }
@@ -6098,13 +6336,13 @@ lang_size_sections_1
             section.  bfd_set_section_contents will complain even for
             a pad size of zero.  */
          s->padding_statement.output_offset
-           = dot - output_section_statement->bfd_section->vma;
+           = dot - current_os->bfd_section->vma;
          break;
 
        case lang_group_statement_enum:
          dot = lang_size_sections_1 (&s->group_statement.children.head,
-                                     output_section_statement,
-                                     fill, dot, relax, check_regions);
+                                     current_os, fill, dot, relax,
+                                     check_regions);
          break;
 
        case lang_insert_statement_enum:
@@ -6351,6 +6589,8 @@ lang_do_assignments_1 (lang_statement_union_type *s,
                       bfd_vma dot,
                       bool *found_end)
 {
+  lang_output_section_statement_type *os = current_os;
+
   for (; s != NULL; s = s->header.next)
     {
       switch (s->header.type)
@@ -6362,10 +6602,9 @@ lang_do_assignments_1 (lang_statement_union_type *s,
 
        case lang_output_section_statement_enum:
          {
-           lang_output_section_statement_type *os;
            bfd_vma newdot;
 
-           os = &(s->output_section_statement);
+           os = &s->output_section_statement;
            os->after_end = *found_end;
            init_opb (os->bfd_section);
            newdot = dot;
@@ -6392,7 +6631,7 @@ lang_do_assignments_1 (lang_statement_union_type *s,
                      newdot += TO_ADDR (os->bfd_section->size);
 
                    if (os->update_dot_tree != NULL)
-                     exp_fold_tree (os->update_dot_tree,
+                     exp_fold_tree (os->update_dot_tree, os,
                                     bfd_abs_section_ptr, &newdot);
                  }
                dot = newdot;
@@ -6412,7 +6651,7 @@ lang_do_assignments_1 (lang_statement_union_type *s,
          break;
 
        case lang_data_statement_enum:
-         exp_fold_tree (s->data_statement.exp, bfd_abs_section_ptr, &dot);
+         exp_fold_tree (s->data_statement.exp, os, bfd_abs_section_ptr, &dot);
          if (expld.result.valid_p)
            {
              s->data_statement.value = expld.result.value;
@@ -6448,7 +6687,7 @@ lang_do_assignments_1 (lang_statement_union_type *s,
          break;
 
        case lang_reloc_statement_enum:
-         exp_fold_tree (s->reloc_statement.addend_exp,
+         exp_fold_tree (s->reloc_statement.addend_exp, os,
                         bfd_abs_section_ptr, &dot);
          if (expld.result.valid_p)
            s->reloc_statement.addend_value = expld.result.value;
@@ -6487,7 +6726,7 @@ lang_do_assignments_1 (lang_statement_union_type *s,
              if (strcmp (p, "end") == 0)
                *found_end = true;
            }
-         exp_fold_tree (s->assignment_statement.exp,
+         exp_fold_tree (s->assignment_statement.exp, os,
                         (current_os->bfd_section != NULL
                          ? current_os->bfd_section : bfd_und_section_ptr),
                         &dot);
@@ -7917,20 +8156,20 @@ lang_process (void)
   /* Create a bfd for each input file.  */
   current_target = default_target;
   lang_statement_iteration++;
-  open_input_bfds (statement_list.head, OPEN_BFD_NORMAL);
+  open_input_bfds (statement_list.head, NULL, OPEN_BFD_NORMAL);
 
   /* Now that open_input_bfds has processed assignments and provide
      statements we can give values to symbolic origin/length now.  */
   lang_do_memory_regions (true);
 
+  ldemul_before_plugin_all_symbols_read ();
+
 #if BFD_SUPPORTS_PLUGINS
   if (link_info.lto_plugin_active)
     {
       lang_statement_list_type added;
       lang_statement_list_type files, inputfiles;
 
-      ldemul_before_plugin_all_symbols_read ();
-
       /* Now all files are read, let the plugin(s) decide if there
         are any more to be added to the link before we call the
         emulation's after_open hook.  We create a private list of
@@ -7947,7 +8186,12 @@ lang_process (void)
       link_info.lto_all_symbols_read = true;
       /* Open any newly added files, updating the file chains.  */
       plugin_undefs = link_info.hash->undefs_tail;
-      open_input_bfds (*added.tail, OPEN_BFD_NORMAL);
+      lang_output_section_statement_type *last_os = NULL;
+      if (lang_os_list.head != NULL)
+       last_os = ((lang_output_section_statement_type *)
+                  ((char *) lang_os_list.tail
+                   - offsetof (lang_output_section_statement_type, next)));
+      open_input_bfds (*added.tail, last_os, OPEN_BFD_NORMAL);
       if (plugin_undefs == link_info.hash->undefs_tail)
        plugin_undefs = NULL;
       /* Restore the global list pointer now they have all been added.  */
@@ -7998,7 +8242,7 @@ lang_process (void)
          /* Rescan archives in case new undefined symbols have appeared.  */
          files = file_chain;
          lang_statement_iteration++;
-         open_input_bfds (statement_list.head, OPEN_BFD_RESCAN);
+         open_input_bfds (statement_list.head, NULL, OPEN_BFD_RESCAN);
          lang_list_remove_tail (&file_chain, &files);
          while (files.head != NULL)
            {
@@ -8033,17 +8277,17 @@ lang_process (void)
     }
 #endif /* BFD_SUPPORTS_PLUGINS */
 
-  /* Make sure that nobody has tried to add a symbol to this list
-     before now.  */
-  ASSERT (link_info.gc_sym_list == NULL);
+  struct bfd_sym_chain **sym = &link_info.gc_sym_list;
+  while (*sym)
+    sym = &(*sym)->next;
 
-  link_info.gc_sym_list = &entry_symbol;
+  *sym = &entry_symbol;
 
   if (entry_symbol.name == NULL)
     {
-      link_info.gc_sym_list = ldlang_undef_chain_list_head;
+      *sym = ldlang_undef_chain_list_head;
 
-      /* entry_symbol is normally initialied by a ENTRY definition in the
+      /* entry_symbol is normally initialised by an ENTRY definition in the
         linker script or the -e command line option.  But if neither of
         these have been used, the target specific backend may still have
         provided an entry symbol via a call to lang_default_entry().
@@ -8222,6 +8466,28 @@ lang_process (void)
   lang_end ();
 }
 
+void
+lang_add_version_string (void)
+{
+  if (! enable_linker_version)
+    return;
+
+  const char * str = "GNU ld ";
+  int len = strlen (str);
+  int i;
+
+  for (i = 0 ; i < len ; i++)
+    lang_add_data (BYTE, exp_intop (str[i]));
+
+  str = BFD_VERSION_STRING;
+  len = strlen (str);
+
+  for (i = 0 ; i < len ; i++)
+    lang_add_data (BYTE, exp_intop (str[i]));
+
+  lang_add_data (BYTE, exp_intop ('\0'));
+}
+
 /* EXPORTED TO YACC */
 
 void
@@ -8261,9 +8527,10 @@ lang_add_wild (struct wildcard_spec *filespec,
   if (filespec != NULL)
     {
       new_stmt->filename = filespec->name;
-      new_stmt->filenames_sorted = filespec->sorted == by_name;
+      new_stmt->filenames_sorted = (filespec->sorted == by_name || filespec->reversed);
       new_stmt->section_flag_list = filespec->section_flag_list;
       new_stmt->exclude_name_list = filespec->exclude_name_list;
+      new_stmt->filenames_reversed = filespec->reversed;
     }
   new_stmt->section_list = section_list;
   new_stmt->keep_sections = keep_sections;
@@ -8361,20 +8628,15 @@ lang_add_data (int type, union etree_union *exp)
   new_stmt->type = type;
 }
 
-/* Convert escape codes in S.
-   Supports \n, \r, \t and \NNN octals.
-   Returns a copy of S in a malloc'ed buffer.  */
-
-static char *
-convert_string (const char * s)
+void
+lang_add_string (const char *s)
 {
-  size_t  len = strlen (s);
-  size_t  i;
-  bool    escape = false;
-  char *  buffer = malloc (len + 1);
-  char *  b;
+  bfd_vma  len = strlen (s);
+  bfd_vma  i;
+  bool     escape = false;
 
-  for (i = 0, b = buffer; i < len; i++)
+  /* Add byte expressions until end of string.  */
+  for (i = 0 ; i < len; i++)
     {
       char c = *s++;
 
@@ -8409,7 +8671,7 @@ convert_string (const char * s)
                    value += (c - '0');
                    i++;
                    s++;
+
                    c = *s;
                    if ((c >= '0') && (c <= '7'))
                      {
@@ -8427,58 +8689,26 @@ convert_string (const char * s)
                    i--;
                    s--;
                  }
-               
+
                c = value;
              }
              break;
            }
+
+         lang_add_data (BYTE, exp_intop (c));
          escape = false;
        }
       else
        {
          if (c == '\\')
-           {
-             escape = true;
-             continue;
-           }
+           escape = true;
+         else
+           lang_add_data (BYTE, exp_intop (c));
        }
-
-      * b ++ = c;
-    }
-
-  * b = 0;
-  return buffer;
-}
-
-void
-lang_add_string (size_t size, const char *s)
-{
-  size_t  len;
-  size_t  i;
-  char *  string;
-
-  string = convert_string (s);
-  len = strlen (string);
-
-  /* Check if it is ASCIZ command (len == 0) */
-  if (size == 0)
-    /* Make sure that we include the terminating nul byte.  */
-    size = len + 1;
-  else if (len >= size)
-    {
-      len = size - 1;
-
-      einfo (_("%P:%pS: warning: ASCII string does not fit in allocated space,"
-               " truncated\n"), NULL);
     }
 
-  for (i = 0 ; i < len ; i++)
-    lang_add_data (BYTE, exp_intop (string[i]));
-
-  while (i++ < size)
-    lang_add_data (BYTE, exp_intop ('\0'));
-
-  free (string);
+  /* Remeber to terminate the string.  */
+  lang_add_data (BYTE, exp_intop (0));
 }
 
 /* Create a new reloc statement.  RELOC is the BFD relocation type to
@@ -8668,7 +8898,7 @@ lang_new_phdr (const char *name,
   n = stat_alloc (sizeof (struct lang_phdr));
   n->next = NULL;
   n->name = name;
-  n->type = exp_get_vma (type, 0, "program header type");
+  n->type = exp_get_vma (type, NULL, 0, "program header type");
   n->filehdr = filehdr;
   n->phdrs = phdrs;
   n->at = at;
@@ -8782,12 +9012,12 @@ lang_record_phdrs (void)
       if (l->flags == NULL)
        flags = 0;
       else
-       flags = exp_get_vma (l->flags, 0, "phdr flags");
+       flags = exp_get_vma (l->flags, NULL, 0, "phdr flags");
 
       if (l->at == NULL)
        at = 0;
       else
-       at = exp_get_vma (l->at, 0, "phdr load address");
+       at = exp_get_vma (l->at, NULL, 0, "phdr load address");
 
       if (!bfd_record_phdr (link_info.output_bfd, l->type,
                            l->flags != NULL, flags, l->at != NULL,
@@ -9547,7 +9777,7 @@ lang_do_memory_regions (bool update_regions_p)
     {
       if (r->origin_exp)
        {
-         exp_fold_tree_no_dot (r->origin_exp);
+         exp_fold_tree_no_dot (r->origin_exp, NULL);
           if (update_regions_p)
             {
               if (expld.result.valid_p)
@@ -9562,7 +9792,7 @@ lang_do_memory_regions (bool update_regions_p)
        }
       if (r->length_exp)
        {
-         exp_fold_tree_no_dot (r->length_exp);
+         exp_fold_tree_no_dot (r->length_exp, NULL);
           if (update_regions_p)
             {
               if (expld.result.valid_p)