* ld-mips-elf/elf-rel-got-n64-linux.d: New file.
[deliverable/binutils-gdb.git] / ld / ldlang.c
index 054ffc0fa91213305bd26568a932063018695297..56d65eb40ab17e4976c1f98400e445b6f53bba34 100644 (file)
@@ -1,24 +1,24 @@
 /* Linker command language support.
    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002
+   2001, 2002, 2003
    Free Software Foundation, Inc.
 
-This file is part of GLD, the Gnu Linker.
+   This file is part of GLD, the Gnu Linker.
 
-GLD is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
+   GLD is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
 
-GLD is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+   GLD is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License
-along with GLD; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+   You should have received a copy of the GNU General Public License
+   along with GLD; see the file COPYING.  If not, write to the Free
+   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.  */
 
 #include "bfd.h"
 #include "sysdep.h"
@@ -31,7 +31,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "ldmain.h"
 #include "ldexp.h"
 #include "ldlang.h"
-#include "ldgram.h"
+#include <ldgram.h>
 #include "ldlex.h"
 #include "ldmisc.h"
 #include "ldctor.h"
@@ -40,20 +40,20 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "fnmatch.h"
 #include "demangle.h"
 
-/* FORWARDS */
-static lang_statement_union_type *new_statement
-  PARAMS ((enum statement_enum, size_t, lang_statement_list_type *));
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) & (((TYPE*) 0)->MEMBER))
+#endif
 
-/* LOCALS */
+/* Locals variables.  */
 static struct obstack stat_obstack;
 
 #define obstack_chunk_alloc xmalloc
 #define obstack_chunk_free free
 static const char *startup_file;
 static lang_statement_list_type input_file_chain;
-static boolean placed_commons = false;
+static bfd_boolean placed_commons = FALSE;
 static lang_output_section_statement_type *default_common_section;
-static boolean map_option_f;
+static bfd_boolean map_option_f;
 static bfd_vma print_dot;
 static lang_input_statement_type *first_file;
 static const char *current_target;
@@ -61,148 +61,45 @@ static const char *output_target;
 static lang_statement_list_type statement_list;
 static struct lang_phdr *lang_phdr_list;
 
-static void lang_for_each_statement_worker
-  PARAMS ((void (*) (lang_statement_union_type *),
-          lang_statement_union_type *));
-static lang_input_statement_type *new_afile
-  PARAMS ((const char *, lang_input_file_enum_type, const char *, boolean));
-static lang_memory_region_type *lang_memory_default PARAMS ((asection *));
-static void lang_map_flags PARAMS ((flagword));
-static void init_os PARAMS ((lang_output_section_statement_type *));
-static void exp_init_os PARAMS ((etree_type *));
-static void section_already_linked PARAMS ((bfd *, asection *, PTR));
-static struct bfd_hash_entry *already_linked_newfunc
-  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
-static void already_linked_table_init PARAMS ((void));
-static void already_linked_table_free PARAMS ((void));
-static boolean wildcardp PARAMS ((const char *));
-static lang_statement_union_type *wild_sort
-  PARAMS ((lang_wild_statement_type *, struct wildcard_list *,
-          lang_input_statement_type *, asection *));
-static void output_section_callback
-  PARAMS ((lang_wild_statement_type *, struct wildcard_list *, asection *,
-          lang_input_statement_type *, PTR));
-static lang_input_statement_type *lookup_name PARAMS ((const char *));
-static boolean load_symbols
-  PARAMS ((lang_input_statement_type *, lang_statement_list_type *));
-static void wild
-  PARAMS ((lang_wild_statement_type *,
-          const char *, lang_output_section_statement_type *));
-static bfd *open_output PARAMS ((const char *));
-static void ldlang_open_output PARAMS ((lang_statement_union_type *));
-static void open_input_bfds PARAMS ((lang_statement_union_type *, boolean));
-static void lang_reasonable_defaults PARAMS ((void));
-static void insert_undefined PARAMS ((const char *));
-static void lang_place_undefineds PARAMS ((void));
-static void map_input_to_output_sections
-  PARAMS ((lang_statement_union_type *, const char *,
-          lang_output_section_statement_type *));
-static void print_output_section_statement
-  PARAMS ((lang_output_section_statement_type *));
-static void print_assignment
-  PARAMS ((lang_assignment_statement_type *,
-          lang_output_section_statement_type *));
-static void print_input_statement PARAMS ((lang_input_statement_type *));
-static boolean print_one_symbol PARAMS ((struct bfd_link_hash_entry *, PTR));
-static void print_input_section PARAMS ((lang_input_section_type *));
-static void print_fill_statement PARAMS ((lang_fill_statement_type *));
-static void print_data_statement PARAMS ((lang_data_statement_type *));
-static void print_address_statement PARAMS ((lang_address_statement_type *));
-static void print_reloc_statement PARAMS ((lang_reloc_statement_type *));
-static void print_padding_statement PARAMS ((lang_padding_statement_type *));
-static void print_wild_statement
-  PARAMS ((lang_wild_statement_type *, lang_output_section_statement_type *));
-static void print_group
-  PARAMS ((lang_group_statement_type *, lang_output_section_statement_type *));
-static void print_statement
-  PARAMS ((lang_statement_union_type *, lang_output_section_statement_type *));
-static void print_statement_list
-  PARAMS ((lang_statement_union_type *, lang_output_section_statement_type *));
-static void print_statements PARAMS ((void));
-static void insert_pad
-  PARAMS ((lang_statement_union_type **, fill_type *,
-          unsigned int, asection *, bfd_vma));
-static bfd_vma size_input_section
-  PARAMS ((lang_statement_union_type **, lang_output_section_statement_type *,
-          fill_type *, bfd_vma));
-static void lang_finish PARAMS ((void));
-static void ignore_bfd_errors PARAMS ((const char *, ...));
-static void lang_check PARAMS ((void));
-static void lang_common PARAMS ((void));
-static boolean lang_one_common PARAMS ((struct bfd_link_hash_entry *, PTR));
-static void lang_place_orphans PARAMS ((void));
-static int topower PARAMS ((int));
-static void lang_set_startof PARAMS ((void));
-static void gc_section_callback
-  PARAMS ((lang_wild_statement_type *, struct wildcard_list *, asection *,
-          lang_input_statement_type *, PTR));
-static void lang_record_phdrs PARAMS ((void));
-static void lang_gc_wild PARAMS ((lang_wild_statement_type *));
-static void lang_gc_sections_1 PARAMS ((lang_statement_union_type *));
-static void lang_gc_sections PARAMS ((void));
-static int lang_vers_match_lang_c
-  PARAMS ((struct bfd_elf_version_expr *, const char *));
-static int lang_vers_match_lang_cplusplus
-  PARAMS ((struct bfd_elf_version_expr *, const char *));
-static int lang_vers_match_lang_java
-  PARAMS ((struct bfd_elf_version_expr *, const char *));
-static void lang_do_version_exports_section PARAMS ((void));
-static void lang_check_section_addresses PARAMS ((void));
-static void os_region_check
-  PARAMS ((lang_output_section_statement_type *,
-          struct memory_region_struct *, etree_type *, bfd_vma));
-static bfd_vma lang_size_sections_1
-  PARAMS ((lang_statement_union_type *, lang_output_section_statement_type *,
-          lang_statement_union_type **, fill_type *, bfd_vma, boolean *));
-
-typedef void (*callback_t) PARAMS ((lang_wild_statement_type *,
-                                   struct wildcard_list *,
-                                   asection *,
-                                   lang_input_statement_type *,
-                                   PTR));
-static void walk_wild
-  PARAMS ((lang_wild_statement_type *, callback_t, PTR));
-static void walk_wild_section
-  PARAMS ((lang_wild_statement_type *, lang_input_statement_type *,
-          callback_t, PTR));
-static void walk_wild_file
-  PARAMS ((lang_wild_statement_type *, lang_input_statement_type *,
-          callback_t, PTR));
-
-static int    get_target PARAMS ((const bfd_target *, PTR));
-static void   stricpy PARAMS ((char *, char *));
-static void   strcut PARAMS ((char *, char *));
-static int    name_compare PARAMS ((char *, char *));
-static int    closest_target_match PARAMS ((const bfd_target *, PTR));
-static char * get_first_input_target PARAMS ((void));
-
-/* EXPORTS */
+/* Forward declarations.  */
+static void exp_init_os (etree_type *);
+static bfd_boolean wildcardp (const char *);
+static lang_input_statement_type *lookup_name (const char *);
+static bfd_boolean load_symbols (lang_input_statement_type *,
+                                lang_statement_list_type *);
+static void insert_undefined (const char *);
+static void print_statement (lang_statement_union_type *,
+                            lang_output_section_statement_type *);
+static void print_statement_list (lang_statement_union_type *,
+                                 lang_output_section_statement_type *);
+static void print_statements (void);
+static bfd_boolean lang_one_common (struct bfd_link_hash_entry *, void *);
+static void lang_record_phdrs (void);
+static void lang_do_version_exports_section (void);
+
+typedef void (*callback_t) (lang_wild_statement_type *, struct wildcard_list *,
+                           asection *, lang_input_statement_type *, void *);
+
+/* Exported variables.  */
 lang_output_section_statement_type *abs_output_section;
 lang_statement_list_type lang_output_section_statement;
 lang_statement_list_type *stat_ptr = &statement_list;
 lang_statement_list_type file_chain = { NULL, NULL };
-const char *entry_symbol = NULL;
+struct bfd_sym_chain entry_symbol = { NULL, NULL };
 const char *entry_section = ".text";
-boolean entry_from_cmdline;
-boolean lang_has_input_file = false;
-boolean had_output_filename = false;
-boolean lang_float_flag = false;
-boolean delete_output_file_on_failure = false;
+bfd_boolean entry_from_cmdline;
+bfd_boolean lang_has_input_file = FALSE;
+bfd_boolean had_output_filename = FALSE;
+bfd_boolean lang_float_flag = FALSE;
+bfd_boolean delete_output_file_on_failure = FALSE;
 struct lang_nocrossrefs *nocrossref_list;
 struct unique_sections *unique_section_list;
+static bfd_boolean ldlang_sysrooted_script = FALSE;
 
 etree_type *base; /* Relocation base - or null */
 
-#if defined (__STDC__) || defined (ALMOST_STDC)
-#define cat(a,b) a##b
-#else
-#define cat(a,b) a/**/b
-#endif
-
-/* Don't beautify the line below with "innocent" whitespace, it breaks
-   the K&R C preprocessor!  */
 #define new_stat(x, y) \
-  (cat (x,_type)*) new_statement (cat (x,_enum), sizeof (cat (x,_type)), y)
+  (x##_type *) new_statement (x##_enum, sizeof (x##_type), y)
 
 #define outside_section_address(q) \
   ((q)->output_offset + (q)->output_section->vma)
@@ -212,16 +109,14 @@ etree_type *base; /* Relocation base - or null */
 
 #define SECTION_NAME_MAP_LENGTH (16)
 
-PTR
-stat_alloc (size)
-     size_t size;
+void *
+stat_alloc (size_t size)
 {
   return obstack_alloc (&stat_obstack, size);
 }
 
-boolean
-unique_section_p (secnam)
-     const char *secnam;
+bfd_boolean
+unique_section_p (const char *secnam)
 {
   struct unique_sections *unam;
 
@@ -230,20 +125,19 @@ unique_section_p (secnam)
        ? fnmatch (unam->name, secnam, 0) == 0
        : strcmp (unam->name, secnam) == 0)
       {
-       return true;
+       return TRUE;
       }
 
-  return false;
+  return FALSE;
 }
 
 /* Generic traversal routines for finding matching sections.  */
 
 static void
-walk_wild_section (ptr, file, callback, data)
-     lang_wild_statement_type *ptr;
-     lang_input_statement_type *file;
-     callback_t callback;
-     PTR data;
+walk_wild_section (lang_wild_statement_type *ptr,
+                  lang_input_statement_type *file,
+                  callback_t callback,
+                  void *data)
 {
   asection *s;
 
@@ -260,7 +154,7 @@ walk_wild_section (ptr, file, callback, data)
 
       while (sec != NULL)
        {
-         boolean skip = false;
+         bfd_boolean skip = FALSE;
          struct name_list *list_tmp;
 
          /* Don't process sections from files which were
@@ -314,11 +208,10 @@ walk_wild_section (ptr, file, callback, data)
 /* Handle a wild statement for a single file F.  */
 
 static void
-walk_wild_file (s, f, callback, data)
-     lang_wild_statement_type *s;
-     lang_input_statement_type *f;
-     callback_t callback;
-     PTR data;
+walk_wild_file (lang_wild_statement_type *s,
+               lang_input_statement_type *f,
+               callback_t callback,
+               void *data)
 {
   if (f->the_bfd == NULL
       || ! bfd_check_format (f->the_bfd, bfd_archive))
@@ -329,7 +222,7 @@ walk_wild_file (s, f, callback, data)
 
       /* This is an archive file.  We must map each member of the
         archive separately.  */
-      member = bfd_openr_next_archived_file (f->the_bfd, (bfd *) NULL);
+      member = bfd_openr_next_archived_file (f->the_bfd, NULL);
       while (member != NULL)
        {
          /* When lookup_name is called, it will call the add_symbols
@@ -339,9 +232,7 @@ walk_wild_file (s, f, callback, data)
             lang_input_statement.  */
          if (member->usrdata != NULL)
            {
-             walk_wild_section (s,
-                                (lang_input_statement_type *) member->usrdata,
-                                callback, data);
+             walk_wild_section (s, member->usrdata, callback, data);
            }
 
          member = bfd_openr_next_archived_file (f->the_bfd, member);
@@ -350,10 +241,7 @@ walk_wild_file (s, f, callback, data)
 }
 
 static void
-walk_wild (s, callback, data)
-     lang_wild_statement_type *s;
-     callback_t callback;
-     PTR data;
+walk_wild (lang_wild_statement_type *s, callback_t callback, void *data)
 {
   const char *file_spec = s->filename;
 
@@ -388,11 +276,10 @@ walk_wild (s, callback, data)
    function for each node.  */
 
 static void
-lang_for_each_statement_worker (func, s)
-     void (*func) PARAMS ((lang_statement_union_type *));
-     lang_statement_union_type *s;
+lang_for_each_statement_worker (void (*func) (lang_statement_union_type *),
+                               lang_statement_union_type *s)
 {
-  for (; s != (lang_statement_union_type *) NULL; s = s->header.next)
+  for (; s != NULL; s = s->header.next)
     {
       func (s);
 
@@ -435,8 +322,7 @@ lang_for_each_statement_worker (func, s)
 }
 
 void
-lang_for_each_statement (func)
-     void (*func) PARAMS ((lang_statement_union_type *));
+lang_for_each_statement (void (*func) (lang_statement_union_type *))
 {
   lang_for_each_statement_worker (func, statement_list.head);
 }
@@ -444,26 +330,24 @@ lang_for_each_statement (func)
 /*----------------------------------------------------------------------*/
 
 void
-lang_list_init (list)
-     lang_statement_list_type *list;
+lang_list_init (lang_statement_list_type *list)
 {
-  list->head = (lang_statement_union_type *) NULL;
+  list->head = NULL;
   list->tail = &list->head;
 }
 
 /* Build a new statement node for the parse tree.  */
 
 static lang_statement_union_type *
-new_statement (type, size, list)
-     enum statement_enum type;
-     size_t size;
-     lang_statement_list_type *list;
+new_statement (enum statement_enum type,
+              size_t size,
+              lang_statement_list_type *list)
 {
-  lang_statement_union_type *new = (lang_statement_union_type *)
-  stat_alloc (size);
+  lang_statement_union_type *new;
 
+  new = stat_alloc (size);
   new->header.type = type;
-  new->header.next = (lang_statement_union_type *) NULL;
+  new->header.next = NULL;
   lang_statement_append (list, new, &new->header.next);
   return new;
 }
@@ -473,16 +357,15 @@ new_statement (type, size, list)
    or prefix it with a -l etc.
 
    We can be supplied with requests for input files more than once;
-   they may, for example be split over serveral lines like foo.o(.text)
+   they may, for example be split over several lines like foo.o(.text)
    foo.o(.data) etc, so when asked for a file we check that we haven't
    got it already so we don't duplicate the bfd.  */
 
 static lang_input_statement_type *
-new_afile (name, file_type, target, add_to_list)
-     const char *name;
-     lang_input_file_enum_type file_type;
-     const char *target;
-     boolean add_to_list;
+new_afile (const char *name,
+          lang_input_file_enum_type file_type,
+          const char *target,
+          bfd_boolean add_to_list)
 {
   lang_input_statement_type *p;
 
@@ -490,74 +373,75 @@ new_afile (name, file_type, target, add_to_list)
     p = new_stat (lang_input_statement, stat_ptr);
   else
     {
-      p = ((lang_input_statement_type *)
-          stat_alloc (sizeof (lang_input_statement_type)));
+      p = stat_alloc (sizeof (lang_input_statement_type));
       p->header.next = NULL;
     }
 
-  lang_has_input_file = true;
+  lang_has_input_file = TRUE;
   p->target = target;
+  p->sysrooted = FALSE;
   switch (file_type)
     {
     case lang_input_file_is_symbols_only_enum:
       p->filename = name;
-      p->is_archive = false;
-      p->real = true;
+      p->is_archive = FALSE;
+      p->real = TRUE;
       p->local_sym_name = name;
-      p->just_syms_flag = true;
-      p->search_dirs_flag = false;
+      p->just_syms_flag = TRUE;
+      p->search_dirs_flag = FALSE;
       break;
     case lang_input_file_is_fake_enum:
       p->filename = name;
-      p->is_archive = false;
-      p->real = false;
+      p->is_archive = FALSE;
+      p->real = FALSE;
       p->local_sym_name = name;
-      p->just_syms_flag = false;
-      p->search_dirs_flag = false;
+      p->just_syms_flag = FALSE;
+      p->search_dirs_flag = FALSE;
       break;
     case lang_input_file_is_l_enum:
-      p->is_archive = true;
+      p->is_archive = TRUE;
       p->filename = name;
-      p->real = true;
-      p->local_sym_name = concat ("-l", name, (const char *) NULL);
-      p->just_syms_flag = false;
-      p->search_dirs_flag = true;
+      p->real = TRUE;
+      p->local_sym_name = concat ("-l", name, NULL);
+      p->just_syms_flag = FALSE;
+      p->search_dirs_flag = TRUE;
       break;
     case lang_input_file_is_marker_enum:
       p->filename = name;
-      p->is_archive = false;
-      p->real = false;
+      p->is_archive = FALSE;
+      p->real = FALSE;
       p->local_sym_name = name;
-      p->just_syms_flag = false;
-      p->search_dirs_flag = true;
+      p->just_syms_flag = FALSE;
+      p->search_dirs_flag = TRUE;
       break;
     case lang_input_file_is_search_file_enum:
+      p->sysrooted = ldlang_sysrooted_script;
       p->filename = name;
-      p->is_archive = false;
-      p->real = true;
+      p->is_archive = FALSE;
+      p->real = TRUE;
       p->local_sym_name = name;
-      p->just_syms_flag = false;
-      p->search_dirs_flag = true;
+      p->just_syms_flag = FALSE;
+      p->search_dirs_flag = TRUE;
       break;
     case lang_input_file_is_file_enum:
       p->filename = name;
-      p->is_archive = false;
-      p->real = true;
+      p->is_archive = FALSE;
+      p->real = TRUE;
       p->local_sym_name = name;
-      p->just_syms_flag = false;
-      p->search_dirs_flag = false;
+      p->just_syms_flag = FALSE;
+      p->search_dirs_flag = FALSE;
       break;
     default:
       FAIL ();
     }
-  p->the_bfd = (bfd *) NULL;
-  p->asymbols = (asymbol **) NULL;
-  p->next_real_file = (lang_statement_union_type *) NULL;
-  p->next = (lang_statement_union_type *) NULL;
+  p->the_bfd = NULL;
+  p->asymbols = NULL;
+  p->next_real_file = NULL;
+  p->next = NULL;
   p->symbol_count = 0;
   p->dynamic = config.dynamic_link;
   p->whole_archive = whole_archive;
-  p->loaded = false;
+  p->loaded = FALSE;
   lang_statement_append (&input_file_chain,
                         (lang_statement_union_type *) p,
                         &p->next_real_file);
@@ -565,19 +449,18 @@ new_afile (name, file_type, target, add_to_list)
 }
 
 lang_input_statement_type *
-lang_add_input_file (name, file_type, target)
-     const char *name;
-     lang_input_file_enum_type file_type;
-     const char *target;
+lang_add_input_file (const char *name,
+                    lang_input_file_enum_type file_type,
+                    const char *target)
 {
-  lang_has_input_file = true;
-  return new_afile (name, file_type, target, true);
+  lang_has_input_file = TRUE;
+  return new_afile (name, file_type, target, TRUE);
 }
 
 /* Build enough state so that the parser can build its tree.  */
 
 void
-lang_init ()
+lang_init (void)
 {
   obstack_begin (&stat_obstack, 1000);
 
@@ -588,14 +471,12 @@ lang_init ()
   lang_list_init (&input_file_chain);
   lang_list_init (&lang_output_section_statement);
   lang_list_init (&file_chain);
-  first_file = lang_add_input_file ((char *) NULL,
-                                   lang_input_file_is_marker_enum,
-                                   (char *) NULL);
+  first_file = lang_add_input_file (NULL, lang_input_file_is_marker_enum,
+                                   NULL);
   abs_output_section =
     lang_output_section_statement_lookup (BFD_ABS_SECTION_NAME);
 
   abs_output_section->bfd_section = bfd_abs_section_ptr;
-
 }
 
 /*----------------------------------------------------------------------
@@ -612,23 +493,19 @@ static lang_memory_region_type *lang_memory_region_list;
 static lang_memory_region_type **lang_memory_region_list_tail = &lang_memory_region_list;
 
 lang_memory_region_type *
-lang_memory_region_lookup (name)
-     const char *const name;
+lang_memory_region_lookup (const char *const name)
 {
   lang_memory_region_type *p;
+  lang_memory_region_type *new;
 
   /* NAME is NULL for LMA memspecs if no region was specified.  */
   if (name == NULL)
     return NULL;
 
-  for (p = lang_memory_region_list;
-       p != (lang_memory_region_type *) NULL;
-       p = p->next)
+  for (p = lang_memory_region_list; p != NULL; p = p->next)
     {
       if (strcmp (p->name, name) == 0)
-       {
-         return p;
-       }
+       return p;
     }
 
 #if 0
@@ -640,36 +517,30 @@ lang_memory_region_lookup (name)
      a region.  */
   if (strcmp (name, "*default*") == 0)
     {
-      if (lang_memory_region_list != (lang_memory_region_type *) NULL)
-       {
-         return lang_memory_region_list;
-       }
+      if (lang_memory_region_list != NULL)
+       return lang_memory_region_list;
     }
 #endif
 
-  {
-    lang_memory_region_type *new =
-    (lang_memory_region_type *) stat_alloc (sizeof (lang_memory_region_type));
+  new = stat_alloc (sizeof (lang_memory_region_type));
 
-    new->name = xstrdup (name);
-    new->next = (lang_memory_region_type *) NULL;
+  new->name = xstrdup (name);
+  new->next = NULL;
 
-    *lang_memory_region_list_tail = new;
-    lang_memory_region_list_tail = &new->next;
-    new->origin = 0;
-    new->flags = 0;
-    new->not_flags = 0;
-    new->length = ~(bfd_size_type) 0;
-    new->current = 0;
-    new->had_full_message = false;
+  *lang_memory_region_list_tail = new;
+  lang_memory_region_list_tail = &new->next;
+  new->origin = 0;
+  new->flags = 0;
+  new->not_flags = 0;
+  new->length = ~(bfd_size_type) 0;
+  new->current = 0;
+  new->had_full_message = FALSE;
 
-    return new;
-  }
+  return new;
 }
 
 static lang_memory_region_type *
-lang_memory_default (section)
-     asection *section;
+lang_memory_default (asection *section)
 {
   lang_memory_region_type *p;
 
@@ -679,9 +550,7 @@ lang_memory_default (section)
   if ((sec_flags & (SEC_ALLOC | SEC_READONLY | SEC_CODE)) == SEC_ALLOC)
     sec_flags |= SEC_DATA;
 
-  for (p = lang_memory_region_list;
-       p != (lang_memory_region_type *) NULL;
-       p = p->next)
+  for (p = lang_memory_region_list; p != NULL; p = p->next)
     {
       if ((p->flags & sec_flags) != 0
          && (p->not_flags & sec_flags) == 0)
@@ -693,55 +562,47 @@ lang_memory_default (section)
 }
 
 lang_output_section_statement_type *
-lang_output_section_find (name)
-     const char *const name;
+lang_output_section_find (const char *const name)
 {
   lang_statement_union_type *u;
   lang_output_section_statement_type *lookup;
 
-  for (u = lang_output_section_statement.head;
-       u != (lang_statement_union_type *) NULL;
-       u = lookup->next)
+  for (u = lang_output_section_statement.head; u != NULL; u = lookup->next)
     {
       lookup = &u->output_section_statement;
       if (strcmp (name, lookup->name) == 0)
-       {
-         return lookup;
-       }
+       return lookup;
     }
-  return (lang_output_section_statement_type *) NULL;
+  return NULL;
 }
 
 lang_output_section_statement_type *
-lang_output_section_statement_lookup (name)
-     const char *const name;
+lang_output_section_statement_lookup (const char *const name)
 {
   lang_output_section_statement_type *lookup;
 
   lookup = lang_output_section_find (name);
-  if (lookup == (lang_output_section_statement_type *) NULL)
+  if (lookup == NULL)
     {
-
-      lookup = (lang_output_section_statement_type *)
-       new_stat (lang_output_section_statement, stat_ptr);
-      lookup->region = (lang_memory_region_type *) NULL;
-      lookup->lma_region = (lang_memory_region_type *) NULL;
-      lookup->fill = (fill_type *) 0;
+      lookup = new_stat (lang_output_section_statement, stat_ptr);
+      lookup->region = NULL;
+      lookup->lma_region = NULL;
+      lookup->fill = 0;
       lookup->block_value = 1;
       lookup->name = name;
 
-      lookup->next = (lang_statement_union_type *) NULL;
-      lookup->bfd_section = (asection *) NULL;
-      lookup->processed = false;
+      lookup->next = NULL;
+      lookup->bfd_section = NULL;
+      lookup->processed = FALSE;
       lookup->sectype = normal_section;
-      lookup->addr_tree = (etree_type *) NULL;
+      lookup->addr_tree = NULL;
       lang_list_init (&lookup->children);
 
-      lookup->memspec = (const char *) NULL;
+      lookup->memspec = NULL;
       lookup->flags = 0;
       lookup->subsection_alignment = -1;
       lookup->section_alignment = -1;
-      lookup->load_base = (union etree_union *) NULL;
+      lookup->load_base = NULL;
       lookup->update_dot_tree = NULL;
       lookup->phdrs = NULL;
 
@@ -753,8 +614,7 @@ lang_output_section_statement_lookup (name)
 }
 
 static void
-lang_map_flags (flag)
-     flagword flag;
+lang_map_flags (flagword flag)
 {
   if (flag & SEC_ALLOC)
     minfo ("a");
@@ -773,7 +633,7 @@ lang_map_flags (flag)
 }
 
 void
-lang_map ()
+lang_map (void)
 {
   lang_memory_region_type *m;
 
@@ -781,9 +641,7 @@ lang_map ()
   fprintf (config.map_file, "%-16s %-18s %-18s %s\n",
           _("Name"), _("Origin"), _("Length"), _("Attributes"));
 
-  for (m = lang_memory_region_list;
-       m != (lang_memory_region_type *) NULL;
-       m = m->next)
+  for (m = lang_memory_region_list; m != NULL; m = m->next)
     {
       char buf[100];
       int len;
@@ -829,8 +687,7 @@ lang_map ()
 /* Initialize an output section.  */
 
 static void
-init_os (s)
-     lang_output_section_statement_type *s;
+init_os (lang_output_section_statement_type *s)
 {
   section_userdata_type *new;
 
@@ -840,13 +697,12 @@ init_os (s)
   if (strcmp (s->name, DISCARD_SECTION_NAME) == 0)
     einfo (_("%P%F: Illegal use of `%s' section\n"), DISCARD_SECTION_NAME);
 
-  new = ((section_userdata_type *)
-        stat_alloc (sizeof (section_userdata_type)));
+  new = stat_alloc (sizeof (section_userdata_type));
 
   s->bfd_section = bfd_get_section_by_name (output_bfd, s->name);
-  if (s->bfd_section == (asection *) NULL)
+  if (s->bfd_section == NULL)
     s->bfd_section = bfd_make_section (output_bfd, s->name);
-  if (s->bfd_section == (asection *) NULL)
+  if (s->bfd_section == NULL)
     {
       einfo (_("%P%F: output format %s cannot represent section called %s\n"),
             output_bfd->xvec->name, s->name);
@@ -856,20 +712,22 @@ init_os (s)
   /* We initialize an output sections output offset to minus its own
      vma to allow us to output a section through itself.  */
   s->bfd_section->output_offset = 0;
-  get_userdata (s->bfd_section) = (PTR) new;
+  get_userdata (s->bfd_section) = new;
 
   /* If there is a base address, make sure that any sections it might
      mention are initialized.  */
   if (s->addr_tree != NULL)
     exp_init_os (s->addr_tree);
+
+  if (s->load_base != NULL)
+    exp_init_os (s->load_base);
 }
 
 /* Make sure that all output sections mentioned in an expression are
    initialized.  */
 
 static void
-exp_init_os (exp)
-     etree_type *exp;
+exp_init_os (etree_type *exp)
 {
   switch (exp->type.node_class)
     {
@@ -944,12 +802,9 @@ struct already_linked
 static struct bfd_hash_table already_linked_table;
 
 static void
-section_already_linked (abfd, sec, data)
-     bfd *abfd;
-     asection *sec;
-     PTR data;
+section_already_linked (bfd *abfd, asection *sec, void *data)
 {
-  lang_input_statement_type *entry = (lang_input_statement_type *) data;
+  lang_input_statement_type *entry = data;
   flagword flags;
   const char *name;
   struct already_linked *l;
@@ -959,8 +814,7 @@ section_already_linked (abfd, sec, data)
      discard all sections.  */
   if (entry->just_syms_flag)
     {
-      sec->output_section = bfd_abs_section_ptr;
-      sec->output_offset = sec->vma;
+      bfd_link_just_syms (sec, &link_info);
       return;
     }
 
@@ -983,14 +837,14 @@ section_already_linked (abfd, sec, data)
      of having link once sections in the first place.
 
      Also, not merging link once sections in a relocatable link
-     causes trouble for MIPS ELF, which relies in link once semantics
+     causes trouble for MIPS ELF, which relies on link once semantics
      to handle the .reginfo section correctly.  */
 
   name = bfd_get_section_name (abfd, sec);
 
   already_linked_list =
     ((struct already_linked_hash_entry *)
-     bfd_hash_lookup (&already_linked_table, name, true, false));
+     bfd_hash_lookup (&already_linked_table, name, TRUE, FALSE));
 
   for (l = already_linked_list->entry; l != NULL; l = l->next)
     {
@@ -1034,8 +888,14 @@ section_already_linked (abfd, sec, data)
 
          /* Set the output_section field so that lang_add_section
             does not create a lang_input_section structure for this
-            section.  */
+            section.  Since there might be a symbol in the section
+            being discarded, we must retain a pointer to the section
+            which we are really going to use.  */
          sec->output_section = bfd_abs_section_ptr;
+         sec->kept_section = l->sec;
+
+         if (flags & SEC_GROUP)
+           bfd_discard_group (abfd, sec);
 
          return;
        }
@@ -1044,8 +904,7 @@ section_already_linked (abfd, sec, data)
   /* This is the first section with this name.  Record it.  Allocate
      the memory from the same obstack as the hash table is kept in.  */
 
-  l = ((struct already_linked *)
-       bfd_hash_allocate (&already_linked_table, sizeof *l));
+  l = bfd_hash_allocate (&already_linked_table, sizeof *l);
 
   l->sec = sec;
   l->next = already_linked_list->entry;
@@ -1056,21 +915,20 @@ section_already_linked (abfd, sec, data)
    initialize the table, fill in an entry and remove the table.  */
 
 static struct bfd_hash_entry *
-already_linked_newfunc (entry, table, string)
-     struct bfd_hash_entry *entry ATTRIBUTE_UNUSED;
-     struct bfd_hash_table *table;
-     const char *string ATTRIBUTE_UNUSED;
+already_linked_newfunc (struct bfd_hash_entry *entry ATTRIBUTE_UNUSED,
+                       struct bfd_hash_table *table,
+                       const char *string ATTRIBUTE_UNUSED)
 {
   struct already_linked_hash_entry *ret =
     bfd_hash_allocate (table, sizeof (struct already_linked_hash_entry));
 
   ret->entry = NULL;
 
-  return (struct bfd_hash_entry *) ret;
+  return &ret->root;
 }
 
 static void
-already_linked_table_init ()
+already_linked_table_init (void)
 {
   if (! bfd_hash_table_init_n (&already_linked_table,
                               already_linked_newfunc,
@@ -1079,7 +937,7 @@ already_linked_table_init ()
 }
 
 static void
-already_linked_table_free ()
+already_linked_table_free (void)
 {
   bfd_hash_table_free (&already_linked_table);
 }
@@ -1090,15 +948,14 @@ already_linked_table_free ()
    explicit actions, like foo.o(.text), bar.o(.text) and
    foo.o(.text, .data).  */
 
-/* Return true if the PATTERN argument is a wildcard pattern.
+/* Return TRUE if the PATTERN argument is a wildcard pattern.
    Although backslashes are treated specially if a pattern contains
    wildcards, we do not consider the mere presence of a backslash to
    be enough to cause the pattern to be treated as a wildcard.
    That lets us handle DOS filenames more naturally.  */
 
-static boolean
-wildcardp (pattern)
-     const char *pattern;
+static bfd_boolean
+wildcardp (const char *pattern)
 {
   const char *s;
 
@@ -1106,8 +963,8 @@ wildcardp (pattern)
     if (*s == '?'
        || *s == '*'
        || *s == '[')
-      return true;
-  return false;
+      return TRUE;
+  return FALSE;
 }
 
 /* Add SECTION to the output section OUTPUT.  Do this by creating a
@@ -1115,35 +972,35 @@ wildcardp (pattern)
    input file which holds SECTION.  */
 
 void
-lang_add_section (ptr, section, output, file)
-     lang_statement_list_type *ptr;
-     asection *section;
-     lang_output_section_statement_type *output;
-     lang_input_statement_type *file;
+lang_add_section (lang_statement_list_type *ptr,
+                 asection *section,
+                 lang_output_section_statement_type *output,
+                 lang_input_statement_type *file)
 {
   flagword flags;
-  boolean discard;
+  bfd_boolean discard;
 
   flags = bfd_get_section_flags (section->owner, section);
 
-  discard = false;
+  discard = FALSE;
 
-  /* If we are doing a final link, discard sections marked with
-     SEC_EXCLUDE.  */
-  if (! link_info.relocateable
-      && (flags & SEC_EXCLUDE) != 0)
-    discard = true;
+  /* Discard sections marked with SEC_EXCLUDE if we are doing a final
+     link.  Discard debugging sections marked with SEC_EXCLUDE on a
+     relocatable link too.  */
+  if ((flags & SEC_EXCLUDE) != 0
+      && ((flags & SEC_DEBUGGING) != 0 || !link_info.relocatable))
+    discard = TRUE;
 
   /* Discard input sections which are assigned to a section named
      DISCARD_SECTION_NAME.  */
   if (strcmp (output->name, DISCARD_SECTION_NAME) == 0)
-    discard = true;
+    discard = TRUE;
 
   /* Discard debugging sections if we are stripping debugging
      information.  */
   if ((link_info.strip == strip_debugger || link_info.strip == strip_all)
       && (flags & SEC_DEBUGGING) != 0)
-    discard = true;
+    discard = TRUE;
 
   if (discard)
     {
@@ -1157,7 +1014,7 @@ lang_add_section (ptr, section, output, file)
 
   if (section->output_section == NULL)
     {
-      boolean first;
+      bfd_boolean first;
       lang_input_section_type *new;
       flagword flags;
 
@@ -1190,7 +1047,7 @@ lang_add_section (ptr, section, output, file)
         format targets, .text$foo sections go into .text and it's odd
         to see .text with SEC_LINK_ONCE set.  */
 
-      if (! link_info.relocateable)
+      if (! link_info.relocatable)
        flags &= ~ (SEC_LINK_ONCE | SEC_LINK_DUPLICATES);
 
       /* If this is not the first input section, and the SEC_READONLY
@@ -1211,6 +1068,10 @@ lang_add_section (ptr, section, output, file)
          flags &= ~ (SEC_MERGE | SEC_STRINGS);
        }
 
+      /* For now make .tbss normal section.  */
+      if ((flags & SEC_THREAD_LOCAL) && ! link_info.relocatable)
+       flags |= SEC_LOAD;
+
       section->output_section->flags |= flags;
 
       if (flags & SEC_MERGE)
@@ -1244,7 +1105,7 @@ lang_add_section (ptr, section, output, file)
       if (section->alignment_power > output->bfd_section->alignment_power)
        output->bfd_section->alignment_power = section->alignment_power;
 
-      /* If supplied an aligment, then force it.  */
+      /* If supplied an alignment, then force it.  */
       if (output->section_alignment != -1)
        output->bfd_section->alignment_power = output->section_alignment;
 
@@ -1263,11 +1124,10 @@ lang_add_section (ptr, section, output, file)
    new section should just go at the end of the current list.  */
 
 static lang_statement_union_type *
-wild_sort (wild, sec, file, section)
-     lang_wild_statement_type *wild;
-     struct wildcard_list *sec;
-     lang_input_statement_type *file;
-     asection *section;
+wild_sort (lang_wild_statement_type *wild,
+          struct wildcard_list *sec,
+          lang_input_statement_type *file,
+          asection *section)
 {
   const char *section_name;
   lang_statement_union_type *l;
@@ -1290,7 +1150,7 @@ wild_sort (wild, sec, file, section)
       if (wild->filenames_sorted)
        {
          const char *fn, *ln;
-         boolean fa, la;
+         bfd_boolean fa, la;
          int i;
 
          /* The PE support for the .idata section as generated by
@@ -1302,24 +1162,24 @@ wild_sort (wild, sec, file, section)
              && bfd_my_archive (file->the_bfd) != NULL)
            {
              fn = bfd_get_filename (bfd_my_archive (file->the_bfd));
-             fa = true;
+             fa = TRUE;
            }
          else
            {
              fn = file->filename;
-             fa = false;
+             fa = FALSE;
            }
 
          if (ls->ifile->the_bfd != NULL
              && bfd_my_archive (ls->ifile->the_bfd) != NULL)
            {
              ln = bfd_get_filename (bfd_my_archive (ls->ifile->the_bfd));
-             la = true;
+             la = TRUE;
            }
          else
            {
              ln = ls->ifile->filename;
-             la = false;
+             la = FALSE;
            }
 
          i = strcmp (fn, ln);
@@ -1363,12 +1223,11 @@ wild_sort (wild, sec, file, section)
    NULL, in which case it is a wild card.  */
 
 static void
-output_section_callback (ptr, sec, section, file, output)
-     lang_wild_statement_type *ptr;
-     struct wildcard_list *sec;
-     asection *section;
-     lang_input_statement_type *file;
-     PTR output;
+output_section_callback (lang_wild_statement_type *ptr,
+                        struct wildcard_list *sec,
+                        asection *section,
+                        lang_input_statement_type *file,
+                        void *output)
 {
   lang_statement_union_type *before;
 
@@ -1424,36 +1283,35 @@ output_section_callback (ptr, sec, section, file, output)
    already and had its symbols read.  If not then we'll read it.  */
 
 static lang_input_statement_type *
-lookup_name (name)
-     const char *name;
+lookup_name (const char *name)
 {
   lang_input_statement_type *search;
 
   for (search = (lang_input_statement_type *) input_file_chain.head;
-       search != (lang_input_statement_type *) NULL;
+       search != NULL;
        search = (lang_input_statement_type *) search->next_real_file)
     {
-      if (search->filename == (char *) NULL && name == (char *) NULL)
+      if (search->filename == NULL && name == NULL)
        return search;
-      if (search->filename != (char *) NULL
-         && name != (char *) NULL
+      if (search->filename != NULL
+         && name != NULL
          && strcmp (search->filename, name) == 0)
        break;
     }
 
-  if (search == (lang_input_statement_type *) NULL)
+  if (search == NULL)
     search = new_afile (name, lang_input_file_is_file_enum, default_target,
-                       false);
+                       FALSE);
 
   /* If we have already added this file, or this file is not real
      (FIXME: can that ever actually happen?) or the name is NULL
      (FIXME: can that ever actually happen?) don't add this file.  */
   if (search->loaded
       || ! search->real
-      || search->filename == (const char *) NULL)
+      || search->filename == NULL)
     return search;
 
-  if (! load_symbols (search, (lang_statement_list_type *) NULL))
+  if (! load_symbols (search, NULL))
     return NULL;
 
   return search;
@@ -1461,15 +1319,14 @@ lookup_name (name)
 
 /* Get the symbols for an input file.  */
 
-static boolean
-load_symbols (entry, place)
-     lang_input_statement_type *entry;
-     lang_statement_list_type *place;
+static bfd_boolean
+load_symbols (lang_input_statement_type *entry,
+             lang_statement_list_type *place)
 {
   char **matching;
 
   if (entry->loaded)
-    return true;
+    return TRUE;
 
   ldfile_open_file (entry);
 
@@ -1478,13 +1335,14 @@ load_symbols (entry, place)
     {
       bfd_error_type err;
       lang_statement_list_type *hold;
-      boolean bad_load = true;
+      bfd_boolean bad_load = TRUE;
+      bfd_boolean save_ldlang_sysrooted_script;
 
       err = bfd_get_error ();
 
       /* See if the emulation has some special knowledge.  */
       if (ldemul_unrecognized_file (entry))
-       return true;
+       return TRUE;
 
       if (err == bfd_error_file_ambiguously_recognized)
        {
@@ -1500,7 +1358,7 @@ load_symbols (entry, place)
               || place == NULL)
          einfo (_("%F%B: file not recognized: %E\n"), entry->the_bfd);
       else
-       bad_load = false;
+       bad_load = FALSE;
 
       bfd_close (entry->the_bfd);
       entry->the_bfd = NULL;
@@ -1510,19 +1368,22 @@ load_symbols (entry, place)
 
       hold = stat_ptr;
       stat_ptr = place;
+      save_ldlang_sysrooted_script = ldlang_sysrooted_script;
+      ldlang_sysrooted_script = entry->sysrooted;
 
-      ldfile_assumed_script = true;
+      ldfile_assumed_script = TRUE;
       parser_input = input_script;
       yyparse ();
-      ldfile_assumed_script = false;
+      ldfile_assumed_script = FALSE;
 
+      ldlang_sysrooted_script = save_ldlang_sysrooted_script;
       stat_ptr = hold;
 
       return ! bad_load;
     }
 
   if (ldemul_recognized_file (entry))
-    return true;
+    return TRUE;
 
   /* We don't call ldlang_add_file for an archive.  Instead, the
      add_symbols entry point will call ldlang_add_file, via the
@@ -1543,7 +1404,7 @@ load_symbols (entry, place)
       if (entry->whole_archive)
        {
          bfd *member = NULL;
-         boolean loaded = true;
+         bfd_boolean loaded = TRUE;
 
          for (;;)
            {
@@ -1556,7 +1417,7 @@ load_symbols (entry, place)
                {
                  einfo (_("%F%B: member %B in archive is not an object\n"),
                         entry->the_bfd, member);
-                 loaded = false;
+                 loaded = FALSE;
                }
 
              if (! ((*link_info.callbacks->add_archive_element)
@@ -1566,7 +1427,7 @@ load_symbols (entry, place)
              if (! bfd_link_add_symbols (member, &link_info))
                {
                  einfo (_("%F%B: could not read symbols: %E\n"), member);
-                 loaded = false;
+                 loaded = FALSE;
                }
            }
 
@@ -1577,7 +1438,7 @@ load_symbols (entry, place)
     }
 
   if (bfd_link_add_symbols (entry->the_bfd, &link_info))
-    entry->loaded = true;
+    entry->loaded = TRUE;
   else
     einfo (_("%F%B: could not read symbols: %E\n"), entry->the_bfd);
 
@@ -1591,14 +1452,13 @@ load_symbols (entry, place)
    the output section.  */
 
 static void
-wild (s, target, output)
-     lang_wild_statement_type *s;
-     const char *target ATTRIBUTE_UNUSED;
-     lang_output_section_statement_type *output;
+wild (lang_wild_statement_type *s,
+      const char *target ATTRIBUTE_UNUSED,
+      lang_output_section_statement_type *output)
 {
   struct wildcard_list *sec;
 
-  walk_wild (s, output_section_callback, (PTR) output);
+  walk_wild (s, output_section_callback, output);
 
   for (sec = s->section_list; sec != NULL; sec = sec->next)
     {
@@ -1613,14 +1473,12 @@ wild (s, target, output)
     }
 }
 
-/* Return true iff target is the sought target.  */
+/* Return TRUE iff target is the sought target.  */
 
 static int
-get_target (target, data)
-     const bfd_target *target;
-     PTR data;
+get_target (const bfd_target *target, void *data)
 {
-  const char *sought = (const char *) data;
+  const char *sought = data;
 
   return strcmp (target->name, sought) == 0;
 }
@@ -1628,9 +1486,7 @@ get_target (target, data)
 /* Like strcpy() but convert to lower case as well.  */
 
 static void
-stricpy (dest, src)
-     char *dest;
-     char *src;
+stricpy (char *dest, char *src)
 {
   char c;
 
@@ -1640,13 +1496,11 @@ stricpy (dest, src)
   *dest = 0;
 }
 
-/* Remove the first occurance of needle (if any) in haystack
+/* Remove the first occurrence of needle (if any) in haystack
    from haystack.  */
 
 static void
-strcut (haystack, needle)
-     char *haystack;
-     char *needle;
+strcut (char *haystack, char *needle)
 {
   haystack = strstr (haystack, needle);
 
@@ -1665,9 +1519,7 @@ strcut (haystack, needle)
    Return a value indicating how "similar" they are.  */
 
 static int
-name_compare (first, second)
-     char *first;
-     char *second;
+name_compare (char *first, char *second)
 {
   char *copy1;
   char *copy2;
@@ -1680,7 +1532,7 @@ name_compare (first, second)
   stricpy (copy1, first);
   stricpy (copy2, second);
 
-  /* Remove and endian strings from the name.  */
+  /* Remove size and endian strings from the name.  */
   strcut (copy1, "big");
   strcut (copy1, "little");
   strcut (copy2, "big");
@@ -1710,11 +1562,9 @@ static const bfd_target *winner;
    match to the original output target.  */
 
 static int
-closest_target_match (target, data)
-     const bfd_target *target;
-     PTR data;
+closest_target_match (const bfd_target *target, void *data)
 {
-  const bfd_target *original = (const bfd_target *) data;
+  const bfd_target *original = data;
 
   if (command_line.endian == ENDIAN_BIG
       && target->byteorder != BFD_ENDIAN_BIG)
@@ -1748,7 +1598,7 @@ closest_target_match (target, data)
 /* Return the BFD target format of the first input file.  */
 
 static char *
-get_first_input_target ()
+get_first_input_target (void)
 {
   char *target = NULL;
 
@@ -1773,32 +1623,37 @@ get_first_input_target ()
   return target;
 }
 
+const char *
+lang_get_output_target (void)
+{
+  const char *target;
+
+  /* Has the user told us which output format to use?  */
+  if (output_target != NULL)
+    return output_target;
+
+  /* No - has the current target been set to something other than
+     the default?  */
+  if (current_target != default_target)
+    return current_target;
+
+  /* No - can we determine the format of the first input file?  */
+  target = get_first_input_target ();
+  if (target != NULL)
+    return target;
+
+  /* Failed - use the default output target.  */
+  return default_target;
+}
+
 /* Open the output file.  */
 
 static bfd *
-open_output (name)
-     const char *name;
+open_output (const char *name)
 {
   bfd *output;
 
-  /* Has the user told us which output format to use?  */
-  if (output_target == (char *) NULL)
-    {
-      /* No - has the current target been set to something other than
-         the default?  */
-      if (current_target != default_target)
-       output_target = current_target;
-
-      /* No - can we determine the format of the first input file?  */
-      else
-       {
-         output_target = get_first_input_target ();
-
-         /* Failed - use the default output target.  */
-         if (output_target == NULL)
-           output_target = default_target;
-       }
-    }
+  output_target = lang_get_output_target ();
 
   /* Has the user requested a particular endianness on the command
      line?  */
@@ -1808,7 +1663,7 @@ open_output (name)
       enum bfd_endian desired_endian;
 
       /* Get the chosen target.  */
-      target = bfd_search_for_target (get_target, (PTR) output_target);
+      target = bfd_search_for_target (get_target, (void *) output_target);
 
       /* If the target is not supported, we cannot do anything.  */
       if (target != NULL)
@@ -1834,8 +1689,8 @@ open_output (name)
                  /* Try to find a target as similar as possible to
                     the default target, but which has the desired
                     endian characteristic.  */
-                 (void) bfd_search_for_target (closest_target_match,
-                                               (PTR) target);
+                 bfd_search_for_target (closest_target_match,
+                                        (void *) target);
 
                  /* Oh dear - we could not find any targets that
                     satisfy our requirements.  */
@@ -1850,7 +1705,7 @@ open_output (name)
 
   output = bfd_openw (name, output_target);
 
-  if (output == (bfd *) NULL)
+  if (output == NULL)
     {
       if (bfd_get_error () == bfd_error_invalid_target)
        einfo (_("%P%F: target %s not found\n"), output_target);
@@ -1858,7 +1713,7 @@ open_output (name)
       einfo (_("%P%F: cannot open output file %s: %E\n"), name);
     }
 
-  delete_output_file_on_failure = true;
+  delete_output_file_on_failure = TRUE;
 
 #if 0
   output->flags |= D_PAGED;
@@ -1872,7 +1727,7 @@ open_output (name)
     einfo (_("%P%F:%s: can not set architecture: %E\n"), name);
 
   link_info.hash = bfd_link_hash_table_create (output);
-  if (link_info.hash == (struct bfd_link_hash_table *) NULL)
+  if (link_info.hash == NULL)
     einfo (_("%P%F: can not create link hash table: %E\n"));
 
   bfd_set_gp_size (output, g_switch_value);
@@ -1880,16 +1735,15 @@ open_output (name)
 }
 
 static void
-ldlang_open_output (statement)
-     lang_statement_union_type *statement;
+ldlang_open_output (lang_statement_union_type *statement)
 {
   switch (statement->header.type)
     {
     case lang_output_statement_enum:
-      ASSERT (output_bfd == (bfd *) NULL);
+      ASSERT (output_bfd == NULL);
       output_bfd = open_output (statement->output_statement.name);
       ldemul_set_output_arch ();
-      if (config.magic_demand_paged && !link_info.relocateable)
+      if (config.magic_demand_paged && !link_info.relocatable)
        output_bfd->flags |= D_PAGED;
       else
        output_bfd->flags &= ~D_PAGED;
@@ -1914,11 +1768,9 @@ ldlang_open_output (statement)
 /* Open all the input files.  */
 
 static void
-open_input_bfds (s, force)
-     lang_statement_union_type *s;
-     boolean force;
+open_input_bfds (lang_statement_union_type *s, bfd_boolean force)
 {
-  for (; s != (lang_statement_union_type *) NULL; s = s->header.next)
+  for (; s != NULL; s = s->header.next)
     {
       switch (s->header.type)
        {
@@ -1946,7 +1798,7 @@ open_input_bfds (s, force)
            do
              {
                undefs = link_info.hash->undefs_tail;
-               open_input_bfds (s->group_statement.children.head, true);
+               open_input_bfds (s->group_statement.children.head, TRUE);
              }
            while (undefs != link_info.hash->undefs_tail);
          }
@@ -1970,12 +1822,12 @@ open_input_bfds (s, force)
                  && s->input_statement.loaded
                  && bfd_check_format (s->input_statement.the_bfd,
                                       bfd_archive))
-               s->input_statement.loaded = false;
+               s->input_statement.loaded = FALSE;
 
              lang_list_init (&add);
 
              if (! load_symbols (&s->input_statement, &add))
-               config.make_executable = false;
+               config.make_executable = FALSE;
 
              if (add.head != NULL)
                {
@@ -1994,7 +1846,7 @@ open_input_bfds (s, force)
    section.  */
 
 static void
-lang_reasonable_defaults ()
+lang_reasonable_defaults (void)
 {
 #if 0
   lang_output_section_statement_lookup (".text");
@@ -2002,14 +1854,14 @@ lang_reasonable_defaults ()
 
   default_common_section = lang_output_section_statement_lookup (".bss");
 
-  if (placed_commons == false)
+  if (!placed_commons)
     {
       lang_wild_statement_type *new =
       new_stat (lang_wild_statement,
                &default_common_section->children);
 
       new->section_name = "COMMON";
-      new->filename = (char *) NULL;
+      new->filename = NULL;
       lang_list_init (&new->children);
     }
 #endif
@@ -2021,21 +1873,15 @@ lang_reasonable_defaults ()
    on a list, then, once the output file has been opened, transfer the
    name to the symbol table.  */
 
-typedef struct ldlang_undef_chain_list
-{
-  struct ldlang_undef_chain_list *next;
-  char *name;
-}                       ldlang_undef_chain_list_type;
+typedef struct bfd_sym_chain ldlang_undef_chain_list_type;
 
-static ldlang_undef_chain_list_type *ldlang_undef_chain_list_head;
+#define ldlang_undef_chain_list_head entry_symbol.next
 
 void
-ldlang_add_undef (name)
-     const char *const name;
+ldlang_add_undef (const char *const name)
 {
   ldlang_undef_chain_list_type *new =
-    ((ldlang_undef_chain_list_type *)
-     stat_alloc (sizeof (ldlang_undef_chain_list_type)));
+    stat_alloc (sizeof (ldlang_undef_chain_list_type));
 
   new->next = ldlang_undef_chain_list_head;
   ldlang_undef_chain_list_head = new;
@@ -2049,13 +1895,12 @@ ldlang_add_undef (name)
 /* Insert NAME as undefined in the symbol table.  */
 
 static void
-insert_undefined (name)
-     const char *name;
+insert_undefined (const char *name)
 {
   struct bfd_link_hash_entry *h;
 
-  h = bfd_link_hash_lookup (link_info.hash, name, true, false, true);
-  if (h == (struct bfd_link_hash_entry *) NULL)
+  h = bfd_link_hash_lookup (link_info.hash, name, TRUE, FALSE, TRUE);
+  if (h == NULL)
     einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));
   if (h->type == bfd_link_hash_new)
     {
@@ -2070,27 +1915,22 @@ insert_undefined (name)
    script file.  */
 
 static void
-lang_place_undefineds ()
+lang_place_undefineds (void)
 {
   ldlang_undef_chain_list_type *ptr;
 
-  for (ptr = ldlang_undef_chain_list_head;
-       ptr != (ldlang_undef_chain_list_type *) NULL;
-       ptr = ptr->next)
-    {
-      insert_undefined (ptr->name);
-    }
+  for (ptr = ldlang_undef_chain_list_head; ptr != NULL; ptr = ptr->next)
+    insert_undefined (ptr->name);
 }
 
-/* Open input files and attatch to output sections.  */
+/* Open input files and attach to output sections.  */
 
 static void
-map_input_to_output_sections (s, target, output_section_statement)
-     lang_statement_union_type *s;
-     const char *target;
-     lang_output_section_statement_type *output_section_statement;
+map_input_to_output_sections
+  (lang_statement_union_type *s, const char *target,
+   lang_output_section_statement_type *output_section_statement)
 {
-  for (; s != (lang_statement_union_type *) NULL; s = s->header.next)
+  for (; s != NULL; s = s->header.next)
     {
       switch (s->header.type)
        {
@@ -2156,9 +1996,44 @@ map_input_to_output_sections (s, target, output_section_statement)
     }
 }
 
+/* An output section might have been removed after its statement was
+   added.  For example, ldemul_before_allocation can remove dynamic
+   sections if they turn out to be not needed.  Clean them up here.  */
+
 static void
-print_output_section_statement (output_section_statement)
-     lang_output_section_statement_type *output_section_statement;
+strip_excluded_output_sections (void)
+{
+  lang_statement_union_type *u;
+
+  for (u = lang_output_section_statement.head;
+       u != NULL;
+       u = u->output_section_statement.next)
+    {
+      lang_output_section_statement_type *os;
+      asection *s;
+
+      os = &u->output_section_statement;
+      s = os->bfd_section;
+      if (s != NULL && (s->flags & SEC_EXCLUDE) != 0)
+       {
+         asection **p;
+
+         os->bfd_section = NULL;
+
+         for (p = &output_bfd->sections; *p; p = &(*p)->next)
+           if (*p == s)
+             {
+               bfd_section_list_remove (output_bfd, p);
+               output_bfd->section_count--;
+               break;
+             }
+       }
+    }
+}
+
+static void
+print_output_section_statement
+  (lang_output_section_statement_type *output_section_statement)
 {
   asection *section = output_section_statement->bfd_section;
   int len;
@@ -2203,9 +2078,8 @@ print_output_section_statement (output_section_statement)
 }
 
 static void
-print_assignment (assignment, output_section)
-     lang_assignment_statement_type *assignment;
-     lang_output_section_statement_type *output_section;
+print_assignment (lang_assignment_statement_type *assignment,
+                 lang_output_section_statement_type *output_section)
 {
   int i;
   etree_value_type result;
@@ -2243,10 +2117,9 @@ print_assignment (assignment, output_section)
 }
 
 static void
-print_input_statement (statm)
-     lang_input_statement_type *statm;
+print_input_statement (lang_input_statement_type *statm)
 {
-  if (statm->filename != (char *) NULL)
+  if (statm->filename != NULL)
     {
       fprintf (config.map_file, "LOAD %s\n", statm->filename);
     }
@@ -2255,12 +2128,10 @@ print_input_statement (statm)
 /* Print all symbols defined in a particular section.  This is called
    via bfd_link_hash_traverse.  */
 
-static boolean
-print_one_symbol (hash_entry, ptr)
-     struct bfd_link_hash_entry *hash_entry;
-     PTR ptr;
+static bfd_boolean
+print_one_symbol (struct bfd_link_hash_entry *hash_entry, void *ptr)
 {
-  asection *sec = (asection *) ptr;
+  asection *sec = ptr;
 
   if ((hash_entry->type == bfd_link_hash_defined
        || hash_entry->type == bfd_link_hash_defweak)
@@ -2278,14 +2149,13 @@ print_one_symbol (hash_entry, ptr)
       minfo ("             %T\n", hash_entry->root.string);
     }
 
-  return true;
+  return TRUE;
 }
 
 /* Print information about an input section to the map file.  */
 
 static void
-print_input_section (in)
-     lang_input_section_type *in;
+print_input_section (lang_input_section_type *in)
 {
   asection *i = in->section;
   bfd_size_type size = i->_cooked_size != 0 ? i->_cooked_size : i->_raw_size;
@@ -2334,7 +2204,7 @@ print_input_section (in)
              minfo (_("%W (size before relaxing)\n"), i->_raw_size);
            }
 
-         bfd_link_hash_traverse (link_info.hash, print_one_symbol, (PTR) i);
+         bfd_link_hash_traverse (link_info.hash, print_one_symbol, i);
 
          print_dot = i->output_section->vma + i->output_offset + size / opb;
        }
@@ -2342,8 +2212,7 @@ print_input_section (in)
 }
 
 static void
-print_fill_statement (fill)
-     lang_fill_statement_type *fill;
+print_fill_statement (lang_fill_statement_type *fill)
 {
   size_t size;
   unsigned char *p;
@@ -2354,8 +2223,7 @@ print_fill_statement (fill)
 }
 
 static void
-print_data_statement (data)
-     lang_data_statement_type *data;
+print_data_statement (lang_data_statement_type *data)
 {
   int i;
   bfd_vma addr;
@@ -2415,8 +2283,7 @@ print_data_statement (data)
    -Ttext.  */
 
 static void
-print_address_statement (address)
-     lang_address_statement_type *address;
+print_address_statement (lang_address_statement_type *address)
 {
   minfo (_("Address of section %s set to "), address->section_name);
   exp_print_tree (address->address);
@@ -2426,8 +2293,7 @@ print_address_statement (address)
 /* Print a reloc statement.  */
 
 static void
-print_reloc_statement (reloc)
-     lang_reloc_statement_type *reloc;
+print_reloc_statement (lang_reloc_statement_type *reloc)
 {
   int i;
   bfd_vma addr;
@@ -2459,8 +2325,7 @@ print_reloc_statement (reloc)
 }
 
 static void
-print_padding_statement (s)
-     lang_padding_statement_type *s;
+print_padding_statement (lang_padding_statement_type *s)
 {
   int len;
   bfd_vma addr;
@@ -2495,9 +2360,8 @@ print_padding_statement (s)
 }
 
 static void
-print_wild_statement (w, os)
-     lang_wild_statement_type *w;
-     lang_output_section_statement_type *os;
+print_wild_statement (lang_wild_statement_type *w,
+                     lang_output_section_statement_type *os)
 {
   struct wildcard_list *sec;
 
@@ -2520,10 +2384,10 @@ print_wild_statement (w, os)
       if (sec->spec.exclude_name_list != NULL)
        {
          name_list *tmp;
-         minfo ("EXCLUDE_FILE ( %s", sec->spec.exclude_name_list->name);
+         minfo ("EXCLUDE_FILE(%s", sec->spec.exclude_name_list->name);
          for (tmp = sec->spec.exclude_name_list->next; tmp; tmp = tmp->next)
-           minfo (", %s", tmp->name);
-         minfo (")");
+           minfo (" %s", tmp->name);
+         minfo (") ");
        }
       if (sec->spec.name != NULL)
        minfo ("%s", sec->spec.name);
@@ -2531,6 +2395,8 @@ print_wild_statement (w, os)
        minfo ("*");
       if (sec->spec.sorted)
        minfo (")");
+      if (sec->next)
+       minfo (" ");
     }
   minfo (")");
 
@@ -2542,9 +2408,8 @@ print_wild_statement (w, os)
 /* Print a group statement.  */
 
 static void
-print_group (s, os)
-     lang_group_statement_type *s;
-     lang_output_section_statement_type *os;
+print_group (lang_group_statement_type *s,
+            lang_output_section_statement_type *os)
 {
   fprintf (config.map_file, "START GROUP\n");
   print_statement_list (s->children.head, os);
@@ -2555,9 +2420,8 @@ print_group (s, os)
    This can be called for any statement type.  */
 
 static void
-print_statement_list (s, os)
-     lang_statement_union_type *s;
-     lang_output_section_statement_type *os;
+print_statement_list (lang_statement_union_type *s,
+                     lang_output_section_statement_type *os)
 {
   while (s != NULL)
     {
@@ -2570,9 +2434,8 @@ print_statement_list (s, os)
    This can be called for any statement type.  */
 
 static void
-print_statement (s, os)
-     lang_statement_union_type *s;
-     lang_output_section_statement_type *os;
+print_statement (lang_statement_union_type *s,
+                lang_output_section_statement_type *os)
 {
   switch (s->header.type)
     {
@@ -2642,7 +2505,7 @@ print_statement (s, os)
 }
 
 static void
-print_statements ()
+print_statements (void)
 {
   print_statement_list (statement_list.head, abs_output_section);
 }
@@ -2653,9 +2516,7 @@ print_statements ()
    Intended to be called from GDB.  */
 
 void
-dprint_statement (s, n)
-     lang_statement_union_type *s;
-     int n;
+dprint_statement (lang_statement_union_type *s, int n)
 {
   FILE *map_save = config.map_file;
 
@@ -2676,12 +2537,11 @@ dprint_statement (s, n)
 }
 
 static void
-insert_pad (ptr, fill, alignment_needed, output_section, dot)
-     lang_statement_union_type **ptr;
-     fill_type *fill;
-     unsigned int alignment_needed;
-     asection *output_section;
-     bfd_vma dot;
+insert_pad (lang_statement_union_type **ptr,
+           fill_type *fill,
+           unsigned int alignment_needed,
+           asection *output_section,
+           bfd_vma dot)
 {
   static fill_type zero_fill = { 1, { 0 } };
   lang_statement_union_type *pad;
@@ -2698,13 +2558,12 @@ insert_pad (ptr, fill, alignment_needed, output_section, dot)
   else
     {
       /* Make a new padding statement, linked into existing chain.  */
-      pad = ((lang_statement_union_type *)
-            stat_alloc (sizeof (lang_padding_statement_type)));
+      pad = stat_alloc (sizeof (lang_padding_statement_type));
       pad->header.next = *ptr;
       *ptr = pad;
       pad->header.type = lang_padding_statement_enum;
       pad->padding_statement.output_section = output_section;
-      if (fill == (fill_type *) 0)
+      if (fill == NULL)
        fill = &zero_fill;
       pad->padding_statement.fill = fill;
     }
@@ -2716,16 +2575,15 @@ insert_pad (ptr, fill, alignment_needed, output_section, dot)
 /* Work out how much this section will move the dot point.  */
 
 static bfd_vma
-size_input_section (this_ptr, output_section_statement, fill, dot)
-     lang_statement_union_type **this_ptr;
-     lang_output_section_statement_type *output_section_statement;
-     fill_type *fill;
-     bfd_vma dot;
+size_input_section (lang_statement_union_type **this_ptr,
+                   lang_output_section_statement_type *output_section_statement,
+                   fill_type *fill,
+                   bfd_vma dot)
 {
   lang_input_section_type *is = &((*this_ptr)->input_section);
   asection *i = is->section;
 
-  if (is->ifile->just_syms_flag == false)
+  if (!is->ifile->just_syms_flag)
     {
       unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
                                                    ldfile_output_machine);
@@ -2781,7 +2639,7 @@ size_input_section (this_ptr, output_section_statement, fill, dot)
    the output section addresses of the two sections.  */
 
 static void
-lang_check_section_addresses ()
+lang_check_section_addresses (void)
 {
   asection *s;
   unsigned opb = bfd_octets_per_byte (output_bfd);
@@ -2838,18 +2696,17 @@ _("%X%P: section %s [%V -> %V] overlaps section %s [%V -> %V]\n"),
    calculation wraps around.  */
 
 static void
-os_region_check (os, region, tree, base)
-     lang_output_section_statement_type *os;
-     struct memory_region_struct *region;
-     etree_type *tree;
-     bfd_vma base;
+os_region_check (lang_output_section_statement_type *os,
+                struct memory_region_struct *region,
+                etree_type *tree,
+                bfd_vma base)
 {
   if ((region->current < region->origin
        || (region->current - region->origin > region->length))
       && ((region->current != region->origin + region->length)
          || base == 0))
     {
-      if (tree != (etree_type *) NULL)
+      if (tree != NULL)
        {
          einfo (_("%X%P: address 0x%v of %B section %s is not within region %s\n"),
                 region->current,
@@ -2872,19 +2729,20 @@ os_region_check (os, region, tree, base)
 /* Set the sizes for all the output sections.  */
 
 static bfd_vma
-lang_size_sections_1 (s, output_section_statement, prev, fill, dot, relax)
-     lang_statement_union_type *s;
-     lang_output_section_statement_type *output_section_statement;
-     lang_statement_union_type **prev;
-     fill_type *fill;
-     bfd_vma dot;
-     boolean *relax;
+lang_size_sections_1
+  (lang_statement_union_type *s,
+   lang_output_section_statement_type *output_section_statement,
+   lang_statement_union_type **prev,
+   fill_type *fill,
+   bfd_vma dot,
+   bfd_boolean *relax,
+   bfd_boolean check_regions)
 {
   unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
                                                ldfile_output_machine);
 
   /* Size up the sections from their constituent parts.  */
-  for (; s != (lang_statement_union_type *) NULL; s = s->header.next)
+  for (; s != NULL; s = s->header.next)
     {
       switch (s->header.type)
        {
@@ -2927,11 +2785,11 @@ lang_size_sections_1 (s, output_section_statement, prev, fill, dot, relax)
              }
            else
              {
-               if (os->addr_tree == (etree_type *) NULL)
+               if (os->addr_tree == NULL)
                  {
                    /* No address specified for this section, get one
                       from the region specification.  */
-                   if (os->region == (lang_memory_region_type *) NULL
+                   if (os->region == NULL
                        || (((bfd_get_section_flags (output_bfd, os->bfd_section)
                              & (SEC_ALLOC | SEC_LOAD)) != 0)
                            && os->region->name[0] == '*'
@@ -2942,20 +2800,37 @@ lang_size_sections_1 (s, output_section_statement, prev, fill, dot, relax)
 
                    /* If a loadable section is using the default memory
                       region, and some non default memory regions were
-                      defined, issue a warning.  */
+                      defined, issue an error message.  */
                    if ((bfd_get_section_flags (output_bfd, os->bfd_section)
                         & (SEC_ALLOC | SEC_LOAD)) != 0
                        && (bfd_get_section_flags (output_bfd, os->bfd_section)
                            & SEC_NEVER_LOAD) == 0
-                       && ! link_info.relocateable
+                       && ! link_info.relocatable
+                       && check_regions
                        && strcmp (os->region->name, "*default*") == 0
                        && lang_memory_region_list != NULL
                        && (strcmp (lang_memory_region_list->name,
                                    "*default*") != 0
                            || lang_memory_region_list->next != NULL))
-                     einfo (_("%P: warning: no memory region specified for section `%s'\n"),
-                            bfd_get_section_name (output_bfd,
-                                                  os->bfd_section));
+                     {
+                       /* By default this is an error rather than just a
+                          warning because if we allocate the section to the
+                          default memory region we can end up creating an
+                          excessivly large binary, or even seg faulting when
+                          attmepting to perform a negative seek.  See
+                            http://sources.redhat.com/ml/binutils/2003-04/msg00423.html
+                          for an example of this.  This behaviour can be
+                          overridden by the using the --no-check-sections
+                          switch.  */
+                       if (command_line.check_section_addresses)
+                         einfo (_("%P%F: error: no memory region specified for loadable section `%s'\n"),
+                                bfd_get_section_name (output_bfd,
+                                                      os->bfd_section));
+                       else
+                         einfo (_("%P: warning: no memory region specified for loadable section `%s'\n"),
+                                bfd_get_section_name (output_bfd,
+                                                      os->bfd_section));
+                     }
 
                    dot = os->region->current;
 
@@ -2980,11 +2855,10 @@ lang_size_sections_1 (s, output_section_statement, prev, fill, dot, relax)
                                       abs_output_section,
                                       lang_allocating_phase_enum,
                                       dot, &dot);
-                   if (r.valid_p == false)
-                     {
-                       einfo (_("%F%S: non constant address expression for section %s\n"),
-                              os->name);
-                     }
+                   if (!r.valid_p)
+                     einfo (_("%F%S: non constant address expression for section %s\n"),
+                            os->name);
+
                    dot = r.value + r.section->bfd_section->vma;
                  }
 
@@ -3000,23 +2874,26 @@ lang_size_sections_1 (s, output_section_statement, prev, fill, dot, relax)
              }
 
            lang_size_sections_1 (os->children.head, os, &os->children.head,
-                                 os->fill, dot, relax);
+                                 os->fill, dot, relax, check_regions);
 
            /* Put the section within the requested block size, or
               align at the block boundary.  */
-           after = ALIGN_N (os->bfd_section->vma
+           after = align_n (os->bfd_section->vma
                             + os->bfd_section->_raw_size / opb,
-                            /* The coercion here is important, see ld.h.  */
                             (bfd_vma) os->block_value);
 
            if (bfd_is_abs_section (os->bfd_section))
              ASSERT (after == os->bfd_section->vma);
+           else if ((os->bfd_section->flags & SEC_HAS_CONTENTS) == 0
+                    && (os->bfd_section->flags & SEC_THREAD_LOCAL)
+                    && ! link_info.relocatable)
+             os->bfd_section->_raw_size = 0;
            else
              os->bfd_section->_raw_size =
                (after - os->bfd_section->vma) * opb;
 
            dot = os->bfd_section->vma + os->bfd_section->_raw_size / opb;
-           os->processed = true;
+           os->processed = TRUE;
 
            if (os->update_dot_tree != 0)
              exp_fold_tree (os->update_dot_tree, abs_output_section,
@@ -3030,7 +2907,7 @@ lang_size_sections_1 (s, output_section_statement, prev, fill, dot, relax)
               If the SEC_NEVER_LOAD bit is not set, it will affect the
               addresses of sections after it. We have to update
               dot.  */
-           if (os->region != (lang_memory_region_type *) NULL
+           if (os->region != NULL
                && ((bfd_get_section_flags (output_bfd, os->bfd_section)
                     & SEC_NEVER_LOAD) == 0
                    || (bfd_get_section_flags (output_bfd, os->bfd_section)
@@ -3038,35 +2915,25 @@ lang_size_sections_1 (s, output_section_statement, prev, fill, dot, relax)
              {
                os->region->current = dot;
 
-               /* Make sure the new address is within the region.  */
-               os_region_check (os, os->region, os->addr_tree,
-                                os->bfd_section->vma);
+               if (check_regions)
+                 /* Make sure the new address is within the region.  */
+                 os_region_check (os, os->region, os->addr_tree,
+                                  os->bfd_section->vma);
 
                /* If there's no load address specified, use the run
                   region as the load region.  */
                if (os->lma_region == NULL && os->load_base == NULL)
                  os->lma_region = os->region;
 
-               if (os->lma_region != NULL)
+               if (os->lma_region != NULL && os->lma_region != os->region)
                  {
-                   if (os->load_base != NULL)
-                     {
-                       einfo (_("%X%P: use an absolute load address or a load memory region, not both\n"));
-                     }
-                   else
-                     {
-                       /* Don't allocate twice.  */
-                       if (os->lma_region != os->region)
-                         {
-                           /* Set load_base, which will be handled later.  */
-                           os->load_base =
-                             exp_intop (os->lma_region->current);
-                           os->lma_region->current +=
-                             os->bfd_section->_raw_size / opb;
-                           os_region_check (os, os->lma_region, NULL,
-                                            os->bfd_section->lma);
-                         }
-                     }
+                   /* Set load_base, which will be handled later.  */
+                   os->load_base = exp_intop (os->lma_region->current);
+                   os->lma_region->current +=
+                     os->bfd_section->_raw_size / opb;
+                   if (check_regions)
+                     os_region_check (os, os->lma_region, NULL,
+                                      os->bfd_section->lma);
                  }
              }
          }
@@ -3076,7 +2943,7 @@ lang_size_sections_1 (s, output_section_statement, prev, fill, dot, relax)
          dot = lang_size_sections_1 (constructor_list.head,
                                      output_section_statement,
                                      &s->wild_statement.children.head,
-                                     fill, dot, relax);
+                                     fill, dot, relax, check_regions);
          break;
 
        case lang_data_statement_enum:
@@ -3140,7 +3007,7 @@ lang_size_sections_1 (s, output_section_statement, prev, fill, dot, relax)
          dot = lang_size_sections_1 (s->wild_statement.children.head,
                                      output_section_statement,
                                      &s->wild_statement.children.head,
-                                     fill, dot, relax);
+                                     fill, dot, relax, check_regions);
 
          break;
 
@@ -3163,12 +3030,12 @@ lang_size_sections_1 (s, output_section_statement, prev, fill, dot, relax)
              }
            else
              {
-               boolean again;
+               bfd_boolean again;
 
                if (! bfd_relax_section (i->owner, i, &link_info, &again))
                  einfo (_("%P%F: can't relax section: %E\n"));
                if (again)
-                 *relax = true;
+                 *relax = TRUE;
              }
            dot = size_input_section (prev, output_section_statement,
                                      output_section_statement->fill, dot);
@@ -3238,7 +3105,7 @@ lang_size_sections_1 (s, output_section_statement, prev, fill, dot, relax)
          dot = lang_size_sections_1 (s->group_statement.children.head,
                                      output_section_statement,
                                      &s->group_statement.children.head,
-                                     fill, dot, relax);
+                                     fill, dot, relax, check_regions);
          break;
 
        default:
@@ -3255,19 +3122,20 @@ lang_size_sections_1 (s, output_section_statement, prev, fill, dot, relax)
 }
 
 bfd_vma
-lang_size_sections (s, output_section_statement, prev, fill, dot, relax)
-     lang_statement_union_type *s;
-     lang_output_section_statement_type *output_section_statement;
-     lang_statement_union_type **prev;
-     fill_type *fill;
-     bfd_vma dot;
-     boolean *relax;
+lang_size_sections
+  (lang_statement_union_type *s,
+   lang_output_section_statement_type *output_section_statement,
+   lang_statement_union_type **prev,
+   fill_type *fill,
+   bfd_vma dot,
+   bfd_boolean *relax,
+   bfd_boolean check_regions)
 {
   bfd_vma result;
 
   exp_data_seg.phase = exp_dataseg_none;
   result = lang_size_sections_1 (s, output_section_statement, prev, fill,
-                                dot, relax);
+                                dot, relax, check_regions);
   if (exp_data_seg.phase == exp_dataseg_end_seen)
     {
       /* If DATA_SEGMENT_ALIGN DATA_SEGMENT_END pair was seen, check whether
@@ -3283,7 +3151,7 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax)
        {
          exp_data_seg.phase = exp_dataseg_adjust;
          result = lang_size_sections_1 (s, output_section_statement, prev,
-                                        fill, dot, relax);
+                                        fill, dot, relax, check_regions);
        }
     }
 
@@ -3291,16 +3159,16 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax)
 }
 
 bfd_vma
-lang_do_assignments (s, output_section_statement, fill, dot)
-     lang_statement_union_type *s;
-     lang_output_section_statement_type *output_section_statement;
-     fill_type *fill;
-     bfd_vma dot;
+lang_do_assignments
+  (lang_statement_union_type *s,
+   lang_output_section_statement_type *output_section_statement,
+   fill_type *fill,
+   bfd_vma dot)
 {
   unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
                                                ldfile_output_machine);
 
-  for (; s != (lang_statement_union_type *) NULL; s = s->header.next)
+  for (; s != NULL; s = s->header.next)
     {
       switch (s->header.type)
        {
@@ -3360,7 +3228,7 @@ lang_do_assignments (s, output_section_statement, fill, dot)
                                   abs_output_section,
                                   lang_final_phase_enum, dot, &dot);
            s->data_statement.value = value.value;
-           if (value.valid_p == false)
+           if (!value.valid_p)
              einfo (_("%F%P: invalid data statement\n"));
          }
          {
@@ -3397,7 +3265,7 @@ lang_do_assignments (s, output_section_statement, fill, dot)
                                   abs_output_section,
                                   lang_final_phase_enum, dot, &dot);
            s->reloc_statement.addend_value = value.value;
-           if (value.valid_p == false)
+           if (!value.valid_p)
              einfo (_("%F%P: invalid reloc statement\n"));
          }
          dot += bfd_get_reloc_size (s->reloc_statement.howto) / opb;
@@ -3459,11 +3327,11 @@ lang_do_assignments (s, output_section_statement, fill, dot)
    such symbols, and set them to the correct value.  */
 
 static void
-lang_set_startof ()
+lang_set_startof (void)
 {
   asection *s;
 
-  if (link_info.relocateable)
+  if (link_info.relocatable)
     return;
 
   for (s = output_bfd->sections; s != NULL; s = s->next)
@@ -3476,7 +3344,7 @@ lang_set_startof ()
       buf = xmalloc (10 + strlen (secname));
 
       sprintf (buf, ".startof.%s", secname);
-      h = bfd_link_hash_lookup (link_info.hash, buf, false, false, true);
+      h = bfd_link_hash_lookup (link_info.hash, buf, FALSE, FALSE, TRUE);
       if (h != NULL && h->type == bfd_link_hash_undefined)
        {
          h->type = bfd_link_hash_defined;
@@ -3485,7 +3353,7 @@ lang_set_startof ()
        }
 
       sprintf (buf, ".sizeof.%s", secname);
-      h = bfd_link_hash_lookup (link_info.hash, buf, false, false, true);
+      h = bfd_link_hash_lookup (link_info.hash, buf, FALSE, FALSE, TRUE);
       if (h != NULL && h->type == bfd_link_hash_undefined)
        {
          unsigned opb;
@@ -3505,26 +3373,27 @@ lang_set_startof ()
 }
 
 static void
-lang_finish ()
+lang_finish (void)
 {
   struct bfd_link_hash_entry *h;
-  boolean warn;
+  bfd_boolean warn;
 
-  if (link_info.relocateable || link_info.shared)
-    warn = false;
+  if (link_info.relocatable || link_info.shared)
+    warn = FALSE;
   else
-    warn = true;
+    warn = TRUE;
 
-  if (entry_symbol == (char *) NULL)
+  if (entry_symbol.name == NULL)
     {
       /* No entry has been specified.  Look for start, but don't warn
         if we don't find it.  */
-      entry_symbol = "start";
-      warn = false;
+      entry_symbol.name = "start";
+      warn = FALSE;
     }
 
-  h = bfd_link_hash_lookup (link_info.hash, entry_symbol, false, false, true);
-  if (h != (struct bfd_link_hash_entry *) NULL
+  h = bfd_link_hash_lookup (link_info.hash, entry_symbol.name,
+                           FALSE, FALSE, TRUE);
+  if (h != NULL
       && (h->type == bfd_link_hash_defined
          || h->type == bfd_link_hash_defweak)
       && h->u.def.section->output_section != NULL)
@@ -3536,7 +3405,7 @@ lang_finish ()
                                    h->u.def.section->output_section)
             + h->u.def.section->output_offset);
       if (! bfd_set_start_address (output_bfd, val))
-       einfo (_("%P%F:%s: can't set start address\n"), entry_symbol);
+       einfo (_("%P%F:%s: can't set start address\n"), entry_symbol.name);
     }
   else
     {
@@ -3545,7 +3414,7 @@ lang_finish ()
 
       /* We couldn't find the entry symbol.  Try parsing it as a
          number.  */
-      val = bfd_scan_vma (entry_symbol, &send, 0);
+      val = bfd_scan_vma (entry_symbol.name, &send, 0);
       if (*send == '\0')
        {
          if (! bfd_set_start_address (output_bfd, val))
@@ -3558,11 +3427,12 @@ lang_finish ()
          /* Can't find the entry symbol, and it's not a number.  Use
             the first address in the text section.  */
          ts = bfd_get_section_by_name (output_bfd, entry_section);
-         if (ts != (asection *) NULL)
+         if (ts != NULL)
            {
              if (warn)
                einfo (_("%P: warning: cannot find entry symbol %s; defaulting to %V\n"),
-                      entry_symbol, bfd_get_section_vma (output_bfd, ts));
+                      entry_symbol.name,
+                      bfd_get_section_vma (output_bfd, ts));
              if (! bfd_set_start_address (output_bfd,
                                           bfd_get_section_vma (output_bfd,
                                                                ts)))
@@ -3572,7 +3442,7 @@ lang_finish ()
            {
              if (warn)
                einfo (_("%P: warning: cannot find entry symbol %s; not setting start address\n"),
-                      entry_symbol);
+                      entry_symbol.name);
            }
        }
     }
@@ -3582,12 +3452,7 @@ lang_finish ()
    BFD.  */
 
 static void
-#ifdef ANSI_PROTOTYPES
 ignore_bfd_errors (const char *s ATTRIBUTE_UNUSED, ...)
-#else
-ignore_bfd_errors (s)
-     const char *s ATTRIBUTE_UNUSED;
-#endif
 {
   /* Don't do anything.  */
 }
@@ -3597,18 +3462,17 @@ ignore_bfd_errors (s)
    other checking that is needed.  */
 
 static void
-lang_check ()
+lang_check (void)
 {
   lang_statement_union_type *file;
   bfd *input_bfd;
   const bfd_arch_info_type *compatible;
 
-  for (file = file_chain.head;
-       file != (lang_statement_union_type *) NULL;
-       file = file->input_statement.next)
+  for (file = file_chain.head; file != NULL; file = file->input_statement.next)
     {
       input_bfd = file->input_statement.the_bfd;
-      compatible = bfd_arch_get_compatible (input_bfd, output_bfd);
+      compatible = bfd_arch_get_compatible (input_bfd, output_bfd,
+                                           command_line.accept_unknown_input_arch);
 
       /* In general it is not possible to perform a relocatable
         link between differing object formats when the input
@@ -3616,7 +3480,7 @@ lang_check ()
         input format may not have equivalent representations in
         the output format (and besides BFD does not translate
         relocs for other link purposes than a final link).  */
-      if ((link_info.relocateable || link_info.emitrelocations)
+      if ((link_info.relocatable || link_info.emitrelocations)
          && (compatible == NULL
              || bfd_get_flavour (input_bfd) != bfd_get_flavour (output_bfd))
          && (bfd_get_file_flags (input_bfd) & HAS_RELOC) != 0)
@@ -3665,32 +3529,29 @@ lang_check ()
    to roughly sort the entries by size.  */
 
 static void
-lang_common ()
+lang_common (void)
 {
   if (command_line.inhibit_common_definition)
     return;
-  if (link_info.relocateable
+  if (link_info.relocatable
       && ! command_line.force_common_definition)
     return;
 
   if (! config.sort_common)
-    bfd_link_hash_traverse (link_info.hash, lang_one_common, (PTR) NULL);
+    bfd_link_hash_traverse (link_info.hash, lang_one_common, NULL);
   else
     {
       int power;
 
       for (power = 4; power >= 0; power--)
-       bfd_link_hash_traverse (link_info.hash, lang_one_common,
-                               (PTR) &power);
+       bfd_link_hash_traverse (link_info.hash, lang_one_common, &power);
     }
 }
 
 /* Place one common symbol in the correct section.  */
 
-static boolean
-lang_one_common (h, info)
-     struct bfd_link_hash_entry *h;
-     PTR info;
+static bfd_boolean
+lang_one_common (struct bfd_link_hash_entry *h, void *info)
 {
   unsigned int power_of_two;
   bfd_vma size;
@@ -3699,20 +3560,20 @@ lang_one_common (h, info)
                                                ldfile_output_machine);
 
   if (h->type != bfd_link_hash_common)
-    return true;
+    return TRUE;
 
   size = h->u.c.size;
   power_of_two = h->u.c.p->alignment_power;
 
   if (config.sort_common
       && power_of_two < (unsigned int) *(int *) info)
-    return true;
+    return TRUE;
 
   section = h->u.c.p->section;
 
   /* Increase the size of the section.  */
-  section->_cooked_size = ALIGN_N ((section->_cooked_size + opb - 1) / opb,
-                                  (bfd_size_type) (1 << power_of_two)) * opb;
+  section->_cooked_size = align_n ((section->_cooked_size + opb - 1) / opb,
+                                  (bfd_vma) 1 << power_of_two) * opb;
 
   /* Adjust the alignment if necessary.  */
   if (power_of_two > section->alignment_power)
@@ -3733,7 +3594,7 @@ lang_one_common (h, info)
 
   if (config.map_file != NULL)
     {
-      static boolean header_printed;
+      static bfd_boolean header_printed;
       int len;
       char *name;
       char buf[50];
@@ -3742,7 +3603,7 @@ lang_one_common (h, info)
        {
          minfo (_("\nAllocating common symbols\n"));
          minfo (_("Common symbol       size              file\n\n"));
-         header_printed = true;
+         header_printed = TRUE;
        }
 
       name = demangle (h->root.string);
@@ -3778,7 +3639,7 @@ lang_one_common (h, info)
       minfo ("%B\n", section->owner);
     }
 
-  return true;
+  return TRUE;
 }
 
 /* Run through the input files and ensure that every input section has
@@ -3786,35 +3647,29 @@ lang_one_common (h, info)
    an input request and place it into the statement tree.  */
 
 static void
-lang_place_orphans ()
+lang_place_orphans (void)
 {
   LANG_FOR_EACH_INPUT_STATEMENT (file)
     {
       asection *s;
 
-      for (s = file->the_bfd->sections;
-          s != (asection *) NULL;
-          s = s->next)
+      for (s = file->the_bfd->sections; s != NULL; s = s->next)
        {
-         if (s->output_section == (asection *) NULL)
+         if (s->output_section == NULL)
            {
-             /* This section of the file is not attatched, root
+             /* This section of the file is not attached, root
                 around for a sensible place for it to go.  */
 
              if (file->just_syms_flag)
                {
-                 /* We are only retrieving symbol values from this
-                     file.  We want the symbols to act as though the
-                     values in the file are absolute.  */
-                 s->output_section = bfd_abs_section_ptr;
-                 s->output_offset = s->vma;
+                 abort ();
                }
              else if (strcmp (s->name, "COMMON") == 0)
                {
                  /* This is a lonely common section which must have
                     come from an archive.  We attach to the section
                     with the wildcard.  */
-                 if (! link_info.relocateable
+                 if (! link_info.relocatable
                      || command_line.force_common_definition)
                    {
                      if (default_common_section == NULL)
@@ -3848,10 +3703,7 @@ lang_place_orphans ()
 }
 
 void
-lang_set_flags (ptr, flags, invert)
-     lang_memory_region_type *ptr;
-     const char *flags;
-     int invert;
+lang_set_flags (lang_memory_region_type *ptr, const char *flags, int invert)
 {
   flagword *ptr_flags;
 
@@ -3893,8 +3745,7 @@ lang_set_flags (ptr, flags, invert)
    on an archive, but not on the elements.  */
 
 void
-lang_for_each_input_file (func)
-     void (*func) PARAMS ((lang_input_statement_type *));
+lang_for_each_input_file (void (*func) (lang_input_statement_type *))
 {
   lang_input_statement_type *f;
 
@@ -3909,8 +3760,7 @@ lang_for_each_input_file (func)
    not be called on the archive file itself.  */
 
 void
-lang_for_each_file (func)
-     void (*func) PARAMS ((lang_input_statement_type *));
+lang_for_each_file (void (*func) (lang_input_statement_type *))
 {
   LANG_FOR_EACH_INPUT_STATEMENT (f)
     {
@@ -3923,27 +3773,21 @@ lang_for_each_file (func)
 /* Not used.  */
 
 void
-lang_for_each_input_section (func)
-     void (*func) PARAMS ((bfd *ab, asection *as));
+lang_for_each_input_section (void (*func) (bfd *ab, asection *as))
 {
   LANG_FOR_EACH_INPUT_STATEMENT (f)
     {
       asection *s;
 
-      for (s = f->the_bfd->sections;
-          s != (asection *) NULL;
-          s = s->next)
-       {
-         func (f->the_bfd, s);
-       }
+      for (s = f->the_bfd->sections; s != NULL; s = s->next)
+       func (f->the_bfd, s);
     }
 }
 
 #endif
 
 void
-ldlang_add_file (entry)
-     lang_input_statement_type *entry;
+ldlang_add_file (lang_input_statement_type *entry)
 {
   bfd **pp;
 
@@ -3953,14 +3797,12 @@ ldlang_add_file (entry)
 
   /* The BFD linker needs to have a list of all input BFDs involved in
      a link.  */
-  ASSERT (entry->the_bfd->link_next == (bfd *) NULL);
+  ASSERT (entry->the_bfd->link_next == NULL);
   ASSERT (entry->the_bfd != output_bfd);
-  for (pp = &link_info.input_bfds;
-       *pp != (bfd *) NULL;
-       pp = &(*pp)->link_next)
+  for (pp = &link_info.input_bfds; *pp != NULL; pp = &(*pp)->link_next)
     ;
   *pp = entry->the_bfd;
-  entry->the_bfd->usrdata = (PTR) entry;
+  entry->the_bfd->usrdata = entry;
   bfd_set_gp_size (entry->the_bfd, g_switch_value);
 
   /* Look through the sections and check for any which should not be
@@ -3973,27 +3815,24 @@ ldlang_add_file (entry)
      each backend which might set the SEC_LINK_ONCE flag.  If we do
      this, we should probably handle SEC_EXCLUDE in the same way.  */
 
-  bfd_map_over_sections (entry->the_bfd, section_already_linked, (PTR) entry);
+  bfd_map_over_sections (entry->the_bfd, section_already_linked, entry);
 }
 
 void
-lang_add_output (name, from_script)
-     const char *name;
-     int from_script;
+lang_add_output (const char *name, int from_script)
 {
   /* Make -o on command line override OUTPUT in script.  */
-  if (had_output_filename == false || !from_script)
+  if (!had_output_filename || !from_script)
     {
       output_filename = name;
-      had_output_filename = true;
+      had_output_filename = TRUE;
     }
 }
 
 static lang_output_section_statement_type *current_section;
 
 static int
-topower (x)
-     int x;
+topower (int x)
 {
   unsigned int i = 1;
   int l;
@@ -4012,16 +3851,13 @@ topower (x)
 }
 
 lang_output_section_statement_type *
-lang_enter_output_section_statement (output_section_statement_name,
-                                    address_exp, sectype, block_value,
-                                    align, subalign, ebase)
-     const char *output_section_statement_name;
-     etree_type *address_exp;
-     enum section_type sectype;
-     bfd_vma block_value;
-     etree_type *align;
-     etree_type *subalign;
-     etree_type *ebase;
+lang_enter_output_section_statement (const char *output_section_statement_name,
+                                    etree_type *address_exp,
+                                    enum section_type sectype,
+                                    bfd_vma block_value,
+                                    etree_type *align,
+                                    etree_type *subalign,
+                                    etree_type *ebase)
 {
   lang_output_section_statement_type *os;
 
@@ -4036,7 +3872,7 @@ lang_enter_output_section_statement (output_section_statement_name,
 #endif
   /* Make next things chain into subchain of this.  */
 
-  if (os->addr_tree == (etree_type *) NULL)
+  if (os->addr_tree == NULL)
     {
       os->addr_tree = address_exp;
     }
@@ -4058,7 +3894,7 @@ lang_enter_output_section_statement (output_section_statement_name,
 }
 
 void
-lang_final ()
+lang_final (void)
 {
   lang_output_statement_type *new =
     new_stat (lang_output_statement, stat_ptr);
@@ -4069,14 +3905,12 @@ lang_final ()
 /* Reset the current counters in the regions.  */
 
 void
-lang_reset_memory_regions ()
+lang_reset_memory_regions (void)
 {
   lang_memory_region_type *p = lang_memory_region_list;
   asection *o;
 
-  for (p = lang_memory_region_list;
-       p != (lang_memory_region_type *) NULL;
-       p = p->next)
+  for (p = lang_memory_region_list; p != NULL; p = p->next)
     {
       p->old_length = (bfd_size_type) (p->current - p->origin);
       p->current = p->origin;
@@ -4090,12 +3924,11 @@ lang_reset_memory_regions ()
    should be as well.  */
 
 static void
-gc_section_callback (ptr, sec, section, file, data)
-     lang_wild_statement_type *ptr;
-     struct wildcard_list *sec ATTRIBUTE_UNUSED;
-     asection *section;
-     lang_input_statement_type *file ATTRIBUTE_UNUSED;
-     PTR data ATTRIBUTE_UNUSED;
+gc_section_callback (lang_wild_statement_type *ptr,
+                    struct wildcard_list *sec ATTRIBUTE_UNUSED,
+                    asection *section,
+                    lang_input_statement_type *file ATTRIBUTE_UNUSED,
+                    void *data ATTRIBUTE_UNUSED)
 {
   if (ptr->keep_sections)
     section->flags |= SEC_KEEP;
@@ -4104,8 +3937,7 @@ gc_section_callback (ptr, sec, section, file, data)
 /* Handle a wild statement, marking it against GC.  */
 
 static void
-lang_gc_wild (s)
-     lang_wild_statement_type *s;
+lang_gc_wild (lang_wild_statement_type *s)
 {
   walk_wild (s, gc_section_callback, NULL);
 }
@@ -4113,10 +3945,9 @@ lang_gc_wild (s)
 /* Iterate over sections marking them against GC.  */
 
 static void
-lang_gc_sections_1 (s)
-     lang_statement_union_type *s;
+lang_gc_sections_1 (lang_statement_union_type *s)
 {
-  for (; s != (lang_statement_union_type *) NULL; s = s->header.next)
+  for (; s != NULL; s = s->header.next)
     {
       switch (s->header.type)
        {
@@ -4139,33 +3970,24 @@ lang_gc_sections_1 (s)
 }
 
 static void
-lang_gc_sections ()
+lang_gc_sections (void)
 {
   struct bfd_link_hash_entry *h;
-  ldlang_undef_chain_list_type *ulist, fake_list_start;
+  ldlang_undef_chain_list_type *ulist;
 
   /* Keep all sections so marked in the link script.  */
 
   lang_gc_sections_1 (statement_list.head);
 
-  /* Keep all sections containing symbols undefined on the command-line.
-     Handle the entry symbol at the same time.  */
-
-  if (entry_symbol != NULL)
-    {
-      fake_list_start.next = ldlang_undef_chain_list_head;
-      fake_list_start.name = (char *) entry_symbol;
-      ulist = &fake_list_start;
-    }
-  else
-    ulist = ldlang_undef_chain_list_head;
+  /* Keep all sections containing symbols undefined on the command-line,
+     and the section containing the entry symbol.  */
 
-  for (; ulist; ulist = ulist->next)
+  for (ulist = link_info.gc_sym_list; ulist; ulist = ulist->next)
     {
       h = bfd_link_hash_lookup (link_info.hash, ulist->name,
-                               false, false, false);
+                               FALSE, FALSE, FALSE);
 
-      if (h != (struct bfd_link_hash_entry *) NULL
+      if (h != NULL
          && (h->type == bfd_link_hash_defined
              || h->type == bfd_link_hash_defweak)
          && ! bfd_is_abs_section (h->u.def.section))
@@ -4178,7 +4000,7 @@ lang_gc_sections ()
 }
 
 void
-lang_process ()
+lang_process (void)
 {
   lang_reasonable_defaults ();
   current_target = default_target;
@@ -4195,7 +4017,11 @@ lang_process ()
 
   /* Create a bfd for each input file.  */
   current_target = default_target;
-  open_input_bfds (statement_list.head, false);
+  open_input_bfds (statement_list.head, FALSE);
+
+  link_info.gc_sym_list = &entry_symbol;
+  if (entry_symbol.name == NULL)
+    link_info.gc_sym_list = ldlang_undef_chain_list_head;
 
   ldemul_after_open ();
 
@@ -4231,18 +4057,17 @@ lang_process ()
 
   /* Run through the contours of the script and attach input sections
      to the correct output sections.  */
-  map_input_to_output_sections (statement_list.head, (char *) NULL,
-                               (lang_output_section_statement_type *) NULL);
+  map_input_to_output_sections (statement_list.head, NULL, NULL);
 
   /* Find any sections not attached explicitly and handle them.  */
   lang_place_orphans ();
 
-  if (! link_info.relocateable)
+  if (! link_info.relocatable)
     {
       /* Look for a text section and set the readonly attribute in it.  */
       asection *found = bfd_get_section_by_name (output_bfd, ".text");
 
-      if (found != (asection *) NULL)
+      if (found != NULL)
        {
          if (config.text_read_only)
            found->flags |= SEC_READONLY;
@@ -4255,26 +4080,29 @@ lang_process ()
      and other back-ends size dynamic sections.  */
   ldemul_before_allocation ();
 
+  if (!link_info.relocatable)
+    strip_excluded_output_sections ();
+
   /* We must record the program headers before we try to fix the
      section positions, since they will affect SIZEOF_HEADERS.  */
   lang_record_phdrs ();
 
   /* Size up the sections.  */
-  lang_size_sections (statement_list.head,
-                     abs_output_section,
-                     &statement_list.head, 0, (bfd_vma) 0, NULL);
+  lang_size_sections (statement_list.head, abs_output_section,
+                     &statement_list.head, 0, 0, NULL,
+                     command_line.relax ? FALSE : TRUE);
 
   /* Now run around and relax if we can.  */
   if (command_line.relax)
     {
       /* Keep relaxing until bfd_relax_section gives up.  */
-      boolean relax_again;
+      bfd_boolean relax_again;
 
       do
        {
          lang_reset_memory_regions ();
 
-         relax_again = false;
+         relax_again = FALSE;
 
          /* Note: pe-dll.c does something like this also.  If you find
             you need to change this code, you probably need to change
@@ -4282,18 +4110,29 @@ lang_process ()
 
          /* Do all the assignments with our current guesses as to
             section sizes.  */
-         lang_do_assignments (statement_list.head,
-                              abs_output_section,
-                              (fill_type *) 0, (bfd_vma) 0);
+         lang_do_assignments (statement_list.head, abs_output_section,
+                              NULL, 0);
 
          /* Perform another relax pass - this time we know where the
-            globals are, so can make better guess.  */
-         lang_size_sections (statement_list.head,
-                             abs_output_section,
-                             &(statement_list.head), 0, (bfd_vma) 0,
-                             &relax_again);
+            globals are, so can make a better guess.  */
+         lang_size_sections (statement_list.head, abs_output_section,
+                             &statement_list.head, 0, 0, &relax_again, FALSE);
+
+         /* If the normal relax is done and the relax finalize pass
+            is not performed yet, we perform another relax pass.  */
+         if (!relax_again && !link_info.relax_finalizing)
+           {
+             link_info.relax_finalizing = TRUE;
+             relax_again = TRUE;
+           }
        }
       while (relax_again);
+
+      /* Final extra sizing to report errors.  */
+      lang_reset_memory_regions ();
+      lang_do_assignments (statement_list.head, abs_output_section, NULL, 0);
+      lang_size_sections (statement_list.head, abs_output_section,
+                         &statement_list.head, 0, 0, NULL, TRUE);
     }
 
   /* See if anything special should be done now we know how big
@@ -4306,12 +4145,10 @@ lang_process ()
   /* Do all the assignments, now that we know the final resting places
      of all the symbols.  */
 
-  lang_do_assignments (statement_list.head,
-                      abs_output_section,
-                      (fill_type *) 0, (bfd_vma) 0);
+  lang_do_assignments (statement_list.head, abs_output_section, NULL, 0);
 
   /* Make sure that the section addresses make sense.  */
-  if (! link_info.relocateable
+  if (! link_info.relocatable
       && command_line.check_section_addresses)
     lang_check_section_addresses ();
 
@@ -4324,10 +4161,9 @@ lang_process ()
 /* EXPORTED TO YACC */
 
 void
-lang_add_wild (filespec, section_list, keep_sections)
-     struct wildcard_spec *filespec;
-     struct wildcard_list *section_list;
-     boolean keep_sections;
+lang_add_wild (struct wildcard_spec *filespec,
+              struct wildcard_list *section_list,
+              bfd_boolean keep_sections)
 {
   struct wildcard_list *curr, *next;
   lang_wild_statement_type *new;
@@ -4338,7 +4174,7 @@ lang_add_wild (filespec, section_list, keep_sections)
        section_list = curr, curr = next)
     {
       if (curr->spec.name != NULL && strcmp (curr->spec.name, "COMMON") == 0)
-       placed_commons = true;
+       placed_commons = TRUE;
 
       next = curr->next;
       curr->next = section_list;
@@ -4349,12 +4185,12 @@ lang_add_wild (filespec, section_list, keep_sections)
       if (strcmp (filespec->name, "*") == 0)
        filespec->name = NULL;
       else if (! wildcardp (filespec->name))
-       lang_has_input_file = true;
+       lang_has_input_file = TRUE;
     }
 
   new = new_stat (lang_wild_statement, stat_ptr);
   new->filename = NULL;
-  new->filenames_sorted = false;
+  new->filenames_sorted = FALSE;
   if (filespec != NULL)
     {
       new->filename = filespec->name;
@@ -4366,9 +4202,7 @@ lang_add_wild (filespec, section_list, keep_sections)
 }
 
 void
-lang_section_start (name, address)
-     const char *name;
-     etree_type *address;
+lang_section_start (const char *name, etree_type *address)
 {
   lang_address_statement_type *ad;
 
@@ -4383,22 +4217,19 @@ lang_section_start (name, address)
    precedence.  */
 
 void
-lang_add_entry (name, cmdline)
-     const char *name;
-     boolean cmdline;
+lang_add_entry (const char *name, bfd_boolean cmdline)
 {
-  if (entry_symbol == NULL
+  if (entry_symbol.name == NULL
       || cmdline
       || ! entry_from_cmdline)
     {
-      entry_symbol = name;
+      entry_symbol.name = name;
       entry_from_cmdline = cmdline;
     }
 }
 
 void
-lang_add_target (name)
-     const char *name;
+lang_add_target (const char *name)
 {
   lang_target_statement_type *new = new_stat (lang_target_statement,
                                              stat_ptr);
@@ -4408,15 +4239,14 @@ lang_add_target (name)
 }
 
 void
-lang_add_map (name)
-     const char *name;
+lang_add_map (const char *name)
 {
   while (*name)
     {
       switch (*name)
        {
        case 'F':
-         map_option_f = true;
+         map_option_f = TRUE;
          break;
        }
       name++;
@@ -4424,8 +4254,7 @@ lang_add_map (name)
 }
 
 void
-lang_add_fill (fill)
-     fill_type *fill;
+lang_add_fill (fill_type *fill)
 {
   lang_fill_statement_type *new = new_stat (lang_fill_statement,
                                            stat_ptr);
@@ -4434,9 +4263,7 @@ lang_add_fill (fill)
 }
 
 void
-lang_add_data (type, exp)
-     int type;
-     union etree_union *exp;
+lang_add_data (int type, union etree_union *exp)
 {
 
   lang_data_statement_type *new = new_stat (lang_data_statement,
@@ -4455,12 +4282,11 @@ lang_add_data (type, exp)
    NAME must be NULL.  ADDEND is an expression for the addend.  */
 
 void
-lang_add_reloc (reloc, howto, section, name, addend)
-     bfd_reloc_code_real_type reloc;
-     reloc_howto_type *howto;
-     asection *section;
-     const char *name;
-     union etree_union *addend;
+lang_add_reloc (bfd_reloc_code_real_type reloc,
+               reloc_howto_type *howto,
+               asection *section,
+               const char *name,
+               union etree_union *addend)
 {
   lang_reloc_statement_type *p = new_stat (lang_reloc_statement, stat_ptr);
 
@@ -4476,8 +4302,7 @@ lang_add_reloc (reloc, howto, section, name, addend)
 }
 
 lang_assignment_statement_type *
-lang_add_assignment (exp)
-     etree_type *exp;
+lang_add_assignment (etree_type *exp)
 {
   lang_assignment_statement_type *new = new_stat (lang_assignment_statement,
                                                  stat_ptr);
@@ -4487,50 +4312,72 @@ lang_add_assignment (exp)
 }
 
 void
-lang_add_attribute (attribute)
-     enum statement_enum attribute;
+lang_add_attribute (enum statement_enum attribute)
 {
   new_statement (attribute, sizeof (lang_statement_union_type), stat_ptr);
 }
 
 void
-lang_startup (name)
-     const char *name;
+lang_startup (const char *name)
 {
-  if (startup_file != (char *) NULL)
+  if (startup_file != NULL)
     {
       einfo (_("%P%Fmultiple STARTUP files\n"));
     }
   first_file->filename = name;
   first_file->local_sym_name = name;
-  first_file->real = true;
+  first_file->real = TRUE;
 
   startup_file = name;
 }
 
 void
-lang_float (maybe)
-     boolean maybe;
+lang_float (bfd_boolean maybe)
 {
   lang_float_flag = maybe;
 }
 
-void
-lang_leave_output_section_statement (fill, memspec, phdrs, lma_memspec)
-     fill_type *fill;
-     const char *memspec;
-     struct lang_output_section_phdr_list *phdrs;
-     const char *lma_memspec;
+
+/* Work out the load- and run-time regions from a script statement, and
+   store them in *LMA_REGION and *REGION respectively.
+
+   MEMSPEC is the name of the run-time region, or "*default*" if the
+   statement didn't specify one.  LMA_MEMSPEC is the name of the
+   load-time region, or null if the statement didn't specify one.
+   HAVE_LMA_P is TRUE if the statement had an explicit load address.
+
+   It is an error to specify both a load region and a load address.  */
+
+static void
+lang_get_regions (struct memory_region_struct **region,
+                 struct memory_region_struct **lma_region,
+                 const char *memspec,
+                 const char *lma_memspec,
+                 int have_lma_p)
 {
-  current_section->fill = fill;
-  current_section->region = lang_memory_region_lookup (memspec);
-  current_section->lma_region = lang_memory_region_lookup (lma_memspec);
+  *lma_region = lang_memory_region_lookup (lma_memspec);
 
   /* If no runtime region has been given, but the load region has
      been, use the load region.  */
-  if (current_section->lma_region != 0 && strcmp (memspec, "*default*") == 0)
-    current_section->region = current_section->lma_region;
+  if (lma_memspec != 0 && strcmp (memspec, "*default*") == 0)
+    *region = *lma_region;
+  else
+    *region = lang_memory_region_lookup (memspec);
+
+  if (have_lma_p && lma_memspec != 0)
+    einfo (_("%X%P:%S: section has both a load address and a load region\n"));
+}
 
+void
+lang_leave_output_section_statement
+  (fill_type *fill, const char *memspec,
+   struct lang_output_section_phdr_list *phdrs, const char *lma_memspec)
+{
+  lang_get_regions (&current_section->region,
+                   &current_section->lma_region,
+                   memspec, lma_memspec,
+                   current_section->load_base != 0);
+  current_section->fill = fill;
   current_section->phdrs = phdrs;
   stat_ptr = &statement_list;
 }
@@ -4541,14 +4388,12 @@ lang_leave_output_section_statement (fill, memspec, phdrs, lma_memspec)
    If the symbol already exists, then do nothing.  */
 
 void
-lang_abs_symbol_at_beginning_of (secname, name)
-     const char *secname;
-     const char *name;
+lang_abs_symbol_at_beginning_of (const char *secname, const char *name)
 {
   struct bfd_link_hash_entry *h;
 
-  h = bfd_link_hash_lookup (link_info.hash, name, true, true, true);
-  if (h == (struct bfd_link_hash_entry *) NULL)
+  h = bfd_link_hash_lookup (link_info.hash, name, TRUE, TRUE, TRUE);
+  if (h == NULL)
     einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));
 
   if (h->type == bfd_link_hash_new
@@ -4559,7 +4404,7 @@ lang_abs_symbol_at_beginning_of (secname, name)
       h->type = bfd_link_hash_defined;
 
       sec = bfd_get_section_by_name (output_bfd, secname);
-      if (sec == (asection *) NULL)
+      if (sec == NULL)
        h->u.def.value = 0;
       else
        h->u.def.value = bfd_get_section_vma (output_bfd, sec);
@@ -4574,14 +4419,12 @@ lang_abs_symbol_at_beginning_of (secname, name)
    If the symbol already exists, then do nothing.  */
 
 void
-lang_abs_symbol_at_end_of (secname, name)
-     const char *secname;
-     const char *name;
+lang_abs_symbol_at_end_of (const char *secname, const char *name)
 {
   struct bfd_link_hash_entry *h;
 
-  h = bfd_link_hash_lookup (link_info.hash, name, true, true, true);
-  if (h == (struct bfd_link_hash_entry *) NULL)
+  h = bfd_link_hash_lookup (link_info.hash, name, TRUE, TRUE, TRUE);
+  if (h == NULL)
     einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));
 
   if (h->type == bfd_link_hash_new
@@ -4592,7 +4435,7 @@ lang_abs_symbol_at_end_of (secname, name)
       h->type = bfd_link_hash_defined;
 
       sec = bfd_get_section_by_name (output_bfd, secname);
-      if (sec == (asection *) NULL)
+      if (sec == NULL)
        h->u.def.value = 0;
       else
        h->u.def.value = (bfd_get_section_vma (output_bfd, sec)
@@ -4604,10 +4447,9 @@ lang_abs_symbol_at_end_of (secname, name)
 }
 
 void
-lang_statement_append (list, element, field)
-     lang_statement_list_type *list;
-     lang_statement_union_type *element;
-     lang_statement_union_type **field;
+lang_statement_append (lang_statement_list_type *list,
+                      lang_statement_union_type *element,
+                      lang_statement_union_type **field)
 {
   *(list->tail) = element;
   list->tail = field;
@@ -4616,11 +4458,10 @@ lang_statement_append (list, element, field)
 /* Set the output format type.  -oformat overrides scripts.  */
 
 void
-lang_add_output_format (format, big, little, from_script)
-     const char *format;
-     const char *big;
-     const char *little;
-     int from_script;
+lang_add_output_format (const char *format,
+                       const char *big,
+                       const char *little,
+                       int from_script)
 {
   if (output_target == NULL || !from_script)
     {
@@ -4639,7 +4480,7 @@ lang_add_output_format (format, big, little, from_script)
    stat_ptr to build new statements within the group.  */
 
 void
-lang_enter_group ()
+lang_enter_group (void)
 {
   lang_group_statement_type *g;
 
@@ -4654,7 +4495,7 @@ lang_enter_group ()
    but currently they can't.  */
 
 void
-lang_leave_group ()
+lang_leave_group (void)
 {
   stat_ptr = &statement_list;
 }
@@ -4663,17 +4504,16 @@ lang_leave_group ()
    command in a linker script.  */
 
 void
-lang_new_phdr (name, type, filehdr, phdrs, at, flags)
-     const char *name;
-     etree_type *type;
-     boolean filehdr;
-     boolean phdrs;
-     etree_type *at;
-     etree_type *flags;
+lang_new_phdr (const char *name,
+              etree_type *type,
+              bfd_boolean filehdr,
+              bfd_boolean phdrs,
+              etree_type *at,
+              etree_type *flags)
 {
   struct lang_phdr *n, **pp;
 
-  n = (struct lang_phdr *) stat_alloc (sizeof (struct lang_phdr));
+  n = stat_alloc (sizeof (struct lang_phdr));
   n->next = NULL;
   n->name = name;
   n->type = exp_get_value_int (type, 0, "program header type",
@@ -4692,7 +4532,7 @@ lang_new_phdr (name, type, filehdr, phdrs, at, flags)
    should not be calling an ELF specific function here.  */
 
 static void
-lang_record_phdrs ()
+lang_record_phdrs (void)
 {
   unsigned int alc;
   asection **secs;
@@ -4701,7 +4541,7 @@ lang_record_phdrs ()
   lang_statement_union_type *u;
 
   alc = 10;
-  secs = (asection **) xmalloc (alc * sizeof (asection *));
+  secs = xmalloc (alc * sizeof (asection *));
   last = NULL;
   for (l = lang_phdr_list; l != NULL; l = l->next)
     {
@@ -4741,12 +4581,11 @@ lang_record_phdrs ()
                  if (c >= alc)
                    {
                      alc *= 2;
-                     secs = ((asection **)
-                             xrealloc (secs, alc * sizeof (asection *)));
+                     secs = xrealloc (secs, alc * sizeof (asection *));
                    }
                  secs[c] = os->bfd_section;
                  ++c;
-                 pl->used = true;
+                 pl->used = TRUE;
                }
            }
        }
@@ -4793,18 +4632,17 @@ lang_record_phdrs ()
 /* Record a list of sections which may not be cross referenced.  */
 
 void
-lang_add_nocrossref (l)
-     struct lang_nocrossref *l;
+lang_add_nocrossref (struct lang_nocrossref *l)
 {
   struct lang_nocrossrefs *n;
 
-  n = (struct lang_nocrossrefs *) xmalloc (sizeof *n);
+  n = xmalloc (sizeof *n);
   n->next = nocrossref_list;
   n->list = l;
   nocrossref_list = n;
 
   /* Set notice_all so that we get informed about all symbols.  */
-  link_info.notice_all = true;
+  link_info.notice_all = TRUE;
 }
 \f
 /* Overlay handling.  We handle overlays with some static variables.  */
@@ -4827,8 +4665,7 @@ static struct overlay_list *overlay_list;
 /* Start handling an overlay.  */
 
 void
-lang_enter_overlay (vma_expr)
-     etree_type *vma_expr;
+lang_enter_overlay (etree_type *vma_expr)
 {
   /* The grammar should prevent nested overlays from occurring.  */
   ASSERT (overlay_vma == NULL && overlay_max == NULL);
@@ -4841,8 +4678,7 @@ lang_enter_overlay (vma_expr)
    lang_leave_overlay sets up the LMA and memory regions.  */
 
 void
-lang_enter_overlay_section (name)
-     const char *name;
+lang_enter_overlay_section (const char *name)
 {
   struct overlay_list *n;
   etree_type *size;
@@ -4857,7 +4693,7 @@ lang_enter_overlay_section (name)
     overlay_vma = exp_nameop (ADDR, name);
 
   /* Remember the section.  */
-  n = (struct overlay_list *) xmalloc (sizeof *n);
+  n = xmalloc (sizeof *n);
   n->os = current_section;
   n->next = overlay_list;
   overlay_list = n;
@@ -4875,9 +4711,8 @@ lang_enter_overlay_section (name)
    here.  */
 
 void
-lang_leave_overlay_section (fill, phdrs)
-     fill_type *fill;
-     struct lang_output_section_phdr_list *phdrs;
+lang_leave_overlay_section (fill_type *fill,
+                           struct lang_output_section_phdr_list *phdrs)
 {
   const char *name;
   char *clean, *s2;
@@ -4919,21 +4754,21 @@ lang_leave_overlay_section (fill, phdrs)
    looks through all the sections in the overlay and sets them.  */
 
 void
-lang_leave_overlay (lma_expr, nocrossrefs, fill, memspec, phdrs, lma_memspec)
-     etree_type *lma_expr;
-     int nocrossrefs;
-     fill_type *fill;
-     const char *memspec;
-     struct lang_output_section_phdr_list *phdrs;
-     const char *lma_memspec;
+lang_leave_overlay (etree_type *lma_expr,
+                   int nocrossrefs,
+                   fill_type *fill,
+                   const char *memspec,
+                   struct lang_output_section_phdr_list *phdrs,
+                   const char *lma_memspec)
 {
   lang_memory_region_type *region;
   lang_memory_region_type *lma_region;
   struct overlay_list *l;
   struct lang_nocrossref *nocrossref;
 
-  region = lang_memory_region_lookup (memspec);
-  lma_region = lang_memory_region_lookup (lma_memspec);
+  lang_get_regions (&region, &lma_region,
+                   memspec, lma_memspec,
+                   lma_expr != 0);
 
   nocrossref = NULL;
 
@@ -4948,7 +4783,7 @@ lang_leave_overlay (lma_expr, nocrossrefs, fill, memspec, phdrs, lma_memspec)
     {
       struct overlay_list *next;
 
-      if (fill != (fill_type *) 0 && l->os->fill == (fill_type *) 0)
+      if (fill != NULL && l->os->fill == NULL)
        l->os->fill = fill;
 
       l->os->region = region;
@@ -4972,7 +4807,7 @@ lang_leave_overlay (lma_expr, nocrossrefs, fill, memspec, phdrs, lma_memspec)
        {
          struct lang_nocrossref *nc;
 
-         nc = (struct lang_nocrossref *) xmalloc (sizeof *nc);
+         nc = xmalloc (sizeof *nc);
          nc->name = l->os->name;
          nc->next = nocrossref;
          nocrossref = nc;
@@ -4998,9 +4833,8 @@ lang_leave_overlay (lma_expr, nocrossrefs, fill, memspec, phdrs, lma_memspec)
 struct bfd_elf_version_tree *lang_elf_version_info;
 
 static int
-lang_vers_match_lang_c (expr, sym)
-     struct bfd_elf_version_expr *expr;
-     const char *sym;
+lang_vers_match_lang_c (struct bfd_elf_version_expr *expr,
+                       const char *sym)
 {
   if (expr->pattern[0] == '*' && expr->pattern[1] == '\0')
     return 1;
@@ -5008,9 +4842,8 @@ lang_vers_match_lang_c (expr, sym)
 }
 
 static int
-lang_vers_match_lang_cplusplus (expr, sym)
-     struct bfd_elf_version_expr *expr;
-     const char *sym;
+lang_vers_match_lang_cplusplus (struct bfd_elf_version_expr *expr,
+                               const char *sym)
 {
   char *alt_sym;
   int result;
@@ -5022,7 +4855,7 @@ lang_vers_match_lang_cplusplus (expr, sym)
   if (!alt_sym)
     {
       /* cplus_demangle (also) returns NULL when it is not a C++ symbol.
-        Should we early out false in this case?  */
+        Should we early out FALSE in this case?  */
       result = fnmatch (expr->pattern, sym, 0) == 0;
     }
   else
@@ -5035,9 +4868,8 @@ lang_vers_match_lang_cplusplus (expr, sym)
 }
 
 static int
-lang_vers_match_lang_java (expr, sym)
-     struct bfd_elf_version_expr *expr;
-     const char *sym;
+lang_vers_match_lang_java (struct bfd_elf_version_expr *expr,
+                          const char *sym)
 {
   char *alt_sym;
   int result;
@@ -5049,7 +4881,7 @@ lang_vers_match_lang_java (expr, sym)
   if (!alt_sym)
     {
       /* cplus_demangle (also) returns NULL when it is not a Java symbol.
-        Should we early out false in this case?  */
+        Should we early out FALSE in this case?  */
       result = fnmatch (expr->pattern, sym, 0) == 0;
     }
   else
@@ -5064,16 +4896,17 @@ lang_vers_match_lang_java (expr, sym)
 /* This is called for each variable name or match expression.  */
 
 struct bfd_elf_version_expr *
-lang_new_vers_pattern (orig, new, lang)
-     struct bfd_elf_version_expr *orig;
-     const char *new;
-     const char *lang;
+lang_new_vers_pattern (struct bfd_elf_version_expr *orig,
+                      const char *new,
+                      const char *lang)
 {
   struct bfd_elf_version_expr *ret;
 
-  ret = (struct bfd_elf_version_expr *) xmalloc (sizeof *ret);
+  ret = xmalloc (sizeof *ret);
   ret->next = orig;
   ret->pattern = new;
+  ret->symver = 0;
+  ret->script = 0;
 
   if (lang == NULL || strcasecmp (lang, "C") == 0)
     ret->match = lang_vers_match_lang_c;
@@ -5088,20 +4921,19 @@ lang_new_vers_pattern (orig, new, lang)
       ret->match = lang_vers_match_lang_c;
     }
 
-  return ret;
+  return ldemul_new_vers_pattern (ret);
 }
 
 /* This is called for each set of variable names and match
    expressions.  */
 
 struct bfd_elf_version_tree *
-lang_new_vers_node (globals, locals)
-     struct bfd_elf_version_expr *globals;
-     struct bfd_elf_version_expr *locals;
+lang_new_vers_node (struct bfd_elf_version_expr *globals,
+                   struct bfd_elf_version_expr *locals)
 {
   struct bfd_elf_version_tree *ret;
 
-  ret = (struct bfd_elf_version_tree *) xmalloc (sizeof *ret);
+  ret = xmalloc (sizeof *ret);
   ret->next = NULL;
   ret->name = NULL;
   ret->vernum = 0;
@@ -5121,10 +4953,9 @@ static int version_index;
    version.  */
 
 void
-lang_register_vers_node (name, version, deps)
-     const char *name;
-     struct bfd_elf_version_tree *version;
-     struct bfd_elf_version_deps *deps;
+lang_register_vers_node (const char *name,
+                        struct bfd_elf_version_tree *version,
+                        struct bfd_elf_version_deps *deps)
 {
   struct bfd_elf_version_tree *t, **pp;
   struct bfd_elf_version_expr *e1;
@@ -5136,6 +4967,7 @@ lang_register_vers_node (name, version, deps)
       || (lang_elf_version_info && lang_elf_version_info->name[0] == '\0'))
     {
       einfo (_("%X%P: anonymous version tag cannot be combined with other version tags\n"));
+      free (version);
       return;
     }
 
@@ -5191,14 +5023,12 @@ lang_register_vers_node (name, version, deps)
 /* This is called when we see a version dependency.  */
 
 struct bfd_elf_version_deps *
-lang_add_vers_depend (list, name)
-     struct bfd_elf_version_deps *list;
-     const char *name;
+lang_add_vers_depend (struct bfd_elf_version_deps *list, const char *name)
 {
   struct bfd_elf_version_deps *ret;
   struct bfd_elf_version_tree *t;
 
-  ret = (struct bfd_elf_version_deps *) xmalloc (sizeof *ret);
+  ret = xmalloc (sizeof *ret);
   ret->next = list;
 
   for (t = lang_elf_version_info; t != NULL; t = t->next)
@@ -5216,7 +5046,7 @@ lang_add_vers_depend (list, name)
 }
 
 static void
-lang_do_version_exports_section ()
+lang_do_version_exports_section (void)
 {
   struct bfd_elf_version_expr *greg = NULL, *lreg;
 
@@ -5254,8 +5084,7 @@ lang_do_version_exports_section ()
 }
 
 void
-lang_add_unique (name)
-     const char *name;
+lang_add_unique (const char *name)
 {
   struct unique_sections *ent;
 
@@ -5263,7 +5092,7 @@ lang_add_unique (name)
     if (strcmp (ent->name, name) == 0)
       return;
 
-  ent = (struct unique_sections *) xmalloc (sizeof *ent);
+  ent = xmalloc (sizeof *ent);
   ent->name = xstrdup (name);
   ent->next = unique_section_list;
   unique_section_list = ent;
This page took 0.069739 seconds and 4 git commands to generate.