bfd/
[deliverable/binutils-gdb.git] / ld / emultempl / elf32.em
index c1f5e31828e2da7ac38b41691e641808f40532b3..c6bc7c2ea4edbe68572f0d7d90dc8da38ec00464 100644 (file)
@@ -3,12 +3,17 @@
 # This file is now misnamed, because it supports both 32 bit and 64 bit
 # ELF emulations.
 test -z "${ELFSIZE}" && ELFSIZE=32
+if [ -z "$MACHINE" ]; then
+  OUTPUT_ARCH=${ARCH}
+else
+  OUTPUT_ARCH=${ARCH}:${MACHINE}
+fi
 cat >e${EMULATION_NAME}.c <<EOF
 /* This file is is generated by a shell script.  DO NOT EDIT! */
 
 /* ${ELFSIZE} bit ELF emulation code for ${EMULATION_NAME}
-   Copyright (C) 1991, 93, 94, 95, 96, 97, 98, 99, 2000
-   Free Software Foundation, Inc.
+   Copyright 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+   2002, 2003, 2004 Free Software Foundation, Inc.
    Written by Steve Chamberlain <sac@cygnus.com>
    ELF support by Ian Lance Taylor <ian@cygnus.com>
 
@@ -32,8 +37,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include "bfd.h"
 #include "sysdep.h"
-
-#include <ctype.h>
+#include "libiberty.h"
+#include "safe-ctype.h"
+#include "getopt.h"
 
 #include "bfdlink.h"
 
@@ -44,40 +50,36 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "ldlang.h"
 #include "ldfile.h"
 #include "ldemul.h"
-#include "ldgram.h"
+#include <ldgram.h>
 #include "elf/common.h"
 
-static void gld${EMULATION_NAME}_before_parse PARAMS ((void));
-static void gld${EMULATION_NAME}_vercheck
-  PARAMS ((lang_input_statement_type *));
-static void gld${EMULATION_NAME}_stat_needed
-  PARAMS ((lang_input_statement_type *));
-static boolean gld${EMULATION_NAME}_try_needed PARAMS ((const char *, int));
-static boolean gld${EMULATION_NAME}_search_needed
-  PARAMS ((const char *, const char *, int));
-static void gld${EMULATION_NAME}_check_needed
-  PARAMS ((lang_input_statement_type *));
-static void gld${EMULATION_NAME}_after_open PARAMS ((void));
-static void gld${EMULATION_NAME}_find_exp_assignment PARAMS ((etree_type *));
-static void gld${EMULATION_NAME}_find_statement_assignment
-  PARAMS ((lang_statement_union_type *));
-static void gld${EMULATION_NAME}_before_allocation PARAMS ((void));
-static boolean gld${EMULATION_NAME}_open_dynamic_archive
-  PARAMS ((const char *, search_dirs_type *, lang_input_statement_type *));
-static lang_output_section_statement_type *output_rel_find PARAMS ((void));
-static boolean gld${EMULATION_NAME}_place_orphan
-  PARAMS ((lang_input_statement_type *, asection *));
-static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
+/* Declare functions used by various EXTRA_EM_FILEs.  */
+static void gld${EMULATION_NAME}_before_parse (void);
+static void gld${EMULATION_NAME}_after_open (void);
+static void gld${EMULATION_NAME}_before_allocation (void);
+static bfd_boolean gld${EMULATION_NAME}_place_orphan
+  (lang_input_statement_type *file, asection *s);
+static void gld${EMULATION_NAME}_finish (void);
 
 EOF
 
+if [ "x${USE_LIBPATH}" = xyes ] ; then
+  case ${target} in
+    *-*-linux-gnu*)
+  cat >>e${EMULATION_NAME}.c <<EOF
+#include <glob.h>
+EOF
+    ;;
+  esac
+fi
+
 # Import any needed special functions and/or overrides.
 #
 if test -n "$EXTRA_EM_FILE" ; then
 . ${srcdir}/emultempl/${EXTRA_EM_FILE}.em
 fi
 
-# Functions in this file can be overriden by setting the LDEMUL_* shell
+# Functions in this file can be overridden by setting the LDEMUL_* shell
 # variables.  If the name of the overriding function is the same as is
 # defined in this file, then don't output this file's version.
 # If a different overriding name is given then output the standard function
@@ -87,16 +89,49 @@ if test x"$LDEMUL_BEFORE_PARSE" != xgld"$EMULATION_NAME"_before_parse; then
 cat >>e${EMULATION_NAME}.c <<EOF
 
 static void
-gld${EMULATION_NAME}_before_parse ()
+gld${EMULATION_NAME}_before_parse (void)
 {
-  ldfile_output_architecture = bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`;
-  config.dynamic_link = ${DYNAMIC_LINK-true};
-  config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo true ; else echo false ; fi`;
+  ldfile_set_output_arch ("${OUTPUT_ARCH}", bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`);
+  config.dynamic_link = ${DYNAMIC_LINK-TRUE};
+  config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo TRUE ; else echo FALSE ; fi`;
 }
 
 EOF
 fi
 
+if test x"$LDEMUL_RECOGNIZED_FILE" != xgld"${EMULATION_NAME}"_load_symbols; then
+cat >>e${EMULATION_NAME}.c <<EOF
+/* Handle as_needed DT_NEEDED.  */
+
+static bfd_boolean
+gld${EMULATION_NAME}_load_symbols (lang_input_statement_type *entry)
+{
+  int class = 0;
+
+  /* Tell the ELF linker that we don't want the output file to have a
+     DT_NEEDED entry for this file, unless it is used to resolve
+     references in a regular object.  */
+  if (entry->as_needed)
+    class = DYN_AS_NEEDED;
+
+  /* Tell the ELF linker that we don't want the output file to have a
+     DT_NEEDED entry for any dynamic library in DT_NEEDED tags from
+     this file at all.  */
+  if (!entry->add_needed)
+    class |= DYN_NO_ADD_NEEDED;
+
+  if (!class
+      || (bfd_get_file_flags (entry->the_bfd) & DYNAMIC) == 0)
+    return FALSE;
+
+  bfd_elf_set_dyn_lib_class (entry->the_bfd, class);
+
+  /* Continue on with normal load_symbols processing.  */
+  return FALSE;
+}
+EOF
+fi
+
 cat >>e${EMULATION_NAME}.c <<EOF
 
 /* These variables are required to pass information back and forth
@@ -104,9 +139,9 @@ cat >>e${EMULATION_NAME}.c <<EOF
 
 static struct bfd_link_needed_list *global_needed;
 static struct stat global_stat;
-static boolean global_found;
+static bfd_boolean global_found;
 static struct bfd_link_needed_list *global_vercheck_needed;
-static boolean global_vercheck_failed;
+static bfd_boolean global_vercheck_failed;
 
 
 /* On Linux, it's possible to have different versions of the same
@@ -123,14 +158,13 @@ static boolean global_vercheck_failed;
 
    This is called via lang_for_each_input_file.
    GLOBAL_VERCHECK_NEEDED is the list of objects needed by the object
-   which we ar checking.  This sets GLOBAL_VERCHECK_FAILED if we find
+   which we are checking.  This sets GLOBAL_VERCHECK_FAILED if we find
    a conflicting version.  */
 
 static void
-gld${EMULATION_NAME}_vercheck (s)
-     lang_input_statement_type *s;
+gld${EMULATION_NAME}_vercheck (lang_input_statement_type *s)
 {
-  const char *soname, *f;
+  const char *soname;
   struct bfd_link_needed_list *l;
 
   if (global_vercheck_failed)
@@ -141,19 +175,13 @@ gld${EMULATION_NAME}_vercheck (s)
 
   soname = bfd_elf_get_dt_soname (s->the_bfd);
   if (soname == NULL)
-    soname = bfd_get_filename (s->the_bfd);
-
-  f = strrchr (soname, '/');
-  if (f != NULL)
-    ++f;
-  else
-    f = soname;
+    soname = lbasename (bfd_get_filename (s->the_bfd));
 
   for (l = global_vercheck_needed; l != NULL; l = l->next)
     {
       const char *suffix;
 
-      if (strcmp (f, l->name) == 0)
+      if (strcmp (soname, l->name) == 0)
        {
          /* Probably can't happen, but it's an easy check.  */
          continue;
@@ -168,14 +196,14 @@ gld${EMULATION_NAME}_vercheck (s)
 
       suffix += sizeof ".so." - 1;
 
-      if (strncmp (f, l->name, suffix - l->name) == 0)
+      if (strncmp (soname, l->name, suffix - l->name) == 0)
        {
          /* Here we know that S is a dynamic object FOO.SO.VER1, and
-             the object we are considering needs a dynamic object
-             FOO.SO.VER2, and VER1 and VER2 are different.  This
-             appears to be a version mismatch, so we tell the caller
-             to try a different version of this library.  */
-         global_vercheck_failed = true;
+            the object we are considering needs a dynamic object
+            FOO.SO.VER2, and VER1 and VER2 are different.  This
+            appears to be a version mismatch, so we tell the caller
+            to try a different version of this library.  */
+         global_vercheck_failed = TRUE;
          return;
        }
     }
@@ -186,13 +214,11 @@ gld${EMULATION_NAME}_vercheck (s)
    the file.  */
 
 static void
-gld${EMULATION_NAME}_stat_needed (s)
-     lang_input_statement_type *s;
+gld${EMULATION_NAME}_stat_needed (lang_input_statement_type *s)
 {
   struct stat st;
   const char *suffix;
   const char *soname;
-  const char *f;
 
   if (global_found)
     return;
@@ -208,7 +234,7 @@ gld${EMULATION_NAME}_stat_needed (s)
   if (st.st_dev == global_stat.st_dev
       && st.st_ino == global_stat.st_ino)
     {
-      global_found = true;
+      global_found = TRUE;
       return;
     }
 
@@ -216,7 +242,7 @@ gld${EMULATION_NAME}_stat_needed (s)
      different versions of the same shared library.  For example,
      there may be a problem if -lc picks up libc.so.6 but some other
      shared library has a DT_NEEDED entry of libc.so.5.  This is a
-     hueristic test, and it will only work if the name looks like
+     heuristic test, and it will only work if the name looks like
      NAME.so.VERSION.  FIXME: Depending on file names is error-prone.
      If we really want to issue warnings about mixing version numbers
      of shared libraries, we need to find a better way.  */
@@ -230,43 +256,51 @@ gld${EMULATION_NAME}_stat_needed (s)
 
   soname = bfd_elf_get_dt_soname (s->the_bfd);
   if (soname == NULL)
-    soname = s->filename;
-
-  f = strrchr (soname, '/');
-  if (f != NULL)
-    ++f;
-  else
-    f = soname;
+    soname = lbasename (s->filename);
 
-  if (strncmp (f, global_needed->name, suffix - global_needed->name) == 0)
+  if (strncmp (soname, global_needed->name, suffix - global_needed->name) == 0)
     einfo ("%P: warning: %s, needed by %B, may conflict with %s\n",
-          global_needed->name, global_needed->by, f);
+          global_needed->name, global_needed->by, soname);
 }
 
+struct dt_needed
+{
+  bfd *by;
+  const char *name;
+};
 
 /* This function is called for each possible name for a dynamic object
    named by a DT_NEEDED entry.  The FORCE parameter indicates whether
    to skip the check for a conflicting version.  */
 
-static boolean
-gld${EMULATION_NAME}_try_needed (name, force)
-     const char *name;
-     int force;
+static bfd_boolean
+gld${EMULATION_NAME}_try_needed (struct dt_needed *needed,
+                                int force)
 {
   bfd *abfd;
+  const char *name = needed->name;
+  const char *soname;
+  int class;
 
   abfd = bfd_openr (name, bfd_get_target (output_bfd));
   if (abfd == NULL)
-    return false;
+    return FALSE;
   if (! bfd_check_format (abfd, bfd_object))
     {
-      (void) bfd_close (abfd);
-      return false;
+      bfd_close (abfd);
+      return FALSE;
     }
   if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0)
     {
-      (void) bfd_close (abfd);
-      return false;
+      bfd_close (abfd);
+      return FALSE;
+    }
+
+  /* For DT_NEEDED, they have to match.  */
+  if (abfd->xvec != output_bfd->xvec)
+    {
+      bfd_close (abfd);
+      return FALSE;
     }
 
   /* Check whether this object would include any conflicting library
@@ -284,22 +318,22 @@ gld${EMULATION_NAME}_try_needed (name, force)
       if (needed != NULL)
        {
          global_vercheck_needed = needed;
-         global_vercheck_failed = false;
+         global_vercheck_failed = FALSE;
          lang_for_each_input_file (gld${EMULATION_NAME}_vercheck);
          if (global_vercheck_failed)
            {
-             (void) bfd_close (abfd);
-             /* Return false to force the caller to move on to try
-                 another file on the search path.  */
-             return false;
+             bfd_close (abfd);
+             /* Return FALSE to force the caller to move on to try
+                another file on the search path.  */
+             return FALSE;
            }
 
          /* But wait!  It gets much worse.  On Linux, if a shared
-             library does not use libc at all, we are supposed to skip
-             it the first time around in case we encounter a shared
-             library later on with the same name which does use the
-             version of libc that we want.  This is much too horrible
-             to use on any system other than Linux.  */
+            library does not use libc at all, we are supposed to skip
+            it the first time around in case we encounter a shared
+            library later on with the same name which does use the
+            version of libc that we want.  This is much too horrible
+            to use on any system other than Linux.  */
 
 EOF
 case ${target} in
@@ -313,8 +347,8 @@ case ${target} in
                break;
            if (l == NULL)
              {
-               (void) bfd_close (abfd);
-               return false;
+               bfd_close (abfd);
+               return FALSE;
              }
          }
 
@@ -337,52 +371,68 @@ cat >>e${EMULATION_NAME}.c <<EOF
 
   if (bfd_stat (abfd, &global_stat) != 0)
     einfo ("%F%P:%B: bfd_stat failed: %E\n", abfd);
-  global_found = false;
+
+  /* First strip off everything before the last '/'.  */
+  soname = lbasename (abfd->filename);
+
+  if (trace_file_tries)
+    info_msg (_("found %s at %s\n"), soname, name);
+
+  global_found = FALSE;
   lang_for_each_input_file (gld${EMULATION_NAME}_stat_needed);
   if (global_found)
     {
-      /* Return true to indicate that we found the file, even though
-         we aren't going to do anything with it.  */
-      return true;
+      /* Return TRUE to indicate that we found the file, even though
+        we aren't going to do anything with it.  */
+      return TRUE;
     }
 
-  /* Tell the ELF backend that we don't want the output file to have a
-     DT_NEEDED entry for this file.  */
-  bfd_elf_set_dt_needed_name (abfd, "");
+  /* Specify the soname to use.  */
+  bfd_elf_set_dt_needed_name (abfd, soname);
 
-  /* First strip off everything before the last '/'.  */
-  name = strrchr (abfd->filename, '/');
-  if (name)
-    name++;
-  else
-    name = abfd->filename;
+  /* Tell the ELF linker that we don't want the output file to have a
+     DT_NEEDED entry for this file, unless it is used to resolve
+     references in a regular object.  */
+  class = DYN_DT_NEEDED;
+
+  /* Tell the ELF linker that we don't want the output file to have a
+     DT_NEEDED entry for this file at all if the entry is from a file
+     with DYN_NO_ADD_NEEDED.  */
+  if (needed->by
+      && (bfd_elf_get_dyn_lib_class (needed->by)
+         & DYN_NO_ADD_NEEDED) != 0)
+    class |= DYN_NO_NEEDED | DYN_NO_ADD_NEEDED;
 
-  /* Tell the ELF backend that the output file needs a DT_NEEDED
-     entry for this file if it is used to resolve the reference in
-     a regular object.  */
-  bfd_elf_set_dt_needed_soname (abfd, name);
+  bfd_elf_set_dyn_lib_class (abfd, class);
 
   /* Add this file into the symbol table.  */
   if (! bfd_link_add_symbols (abfd, &link_info))
     einfo ("%F%B: could not read symbols: %E\n", abfd);
 
-  return true;
+  return TRUE;
 }
 
 
 /* Search for a needed file in a path.  */
 
-static boolean
-gld${EMULATION_NAME}_search_needed (path, name, force)
-     const char *path;
-     const char *name;
-     int force;
+static bfd_boolean
+gld${EMULATION_NAME}_search_needed (const char *path,
+                                   struct dt_needed *n, int force)
 {
   const char *s;
+  const char *name = n->name;
   size_t len;
+  struct dt_needed needed;
+
+  if (name[0] == '/')
+    return gld${EMULATION_NAME}_try_needed (n, force);
 
   if (path == NULL || *path == '\0')
-    return false;
+    return FALSE;
+
+  needed.by = n->by;
+  needed.name = n->name;
+
   len = strlen (name);
   while (1)
     {
@@ -403,8 +453,9 @@ gld${EMULATION_NAME}_search_needed (path, name, force)
        }
       strcpy (sset, name);
 
-      if (gld${EMULATION_NAME}_try_needed (filename, force))
-       return true;
+      needed.name = filename;
+      if (gld${EMULATION_NAME}_try_needed (&needed, force))
+       return TRUE;
 
       free (filename);
 
@@ -413,98 +464,247 @@ gld${EMULATION_NAME}_search_needed (path, name, force)
       path = s + 1;
     }
 
-  return false;
+  return FALSE;
 }
 
 EOF
-if [ "x${host}" = "x${target}" ] ; then
-  case " ${EMULATION_LIBPATH} " in
-  *" ${EMULATION_NAME} "*)
-cat >>e${EMULATION_NAME}.c <<EOF
+if [ "x${USE_LIBPATH}" = xyes ] ; then
+  cat >>e${EMULATION_NAME}.c <<EOF
+
+/* Add the sysroot to every entry in a colon-separated path.  */
+
+static char *
+gld${EMULATION_NAME}_add_sysroot (const char *path)
+{
+  int len, colons, i;
+  char *ret, *p;
+
+  len = strlen (path);
+  colons = 0;
+  i = 0;
+  while (path[i])
+    if (path[i++] == ':')
+      colons++;
+
+  if (path[i])
+    colons++;
+
+  len = len + (colons + 1) * strlen (ld_sysroot);
+  ret = xmalloc (len + 1);
+  strcpy (ret, ld_sysroot);
+  p = ret + strlen (ret);
+  i = 0;
+  while (path[i])
+    if (path[i] == ':')
+      {
+       *p++ = path[i++];
+       strcpy (p, ld_sysroot);
+       p = p + strlen (p);
+      }
+    else
+      *p++ = path[i++];
 
+  *p = 0;
+  return ret;
+}
+
+EOF
+  case ${target} in
+    *-*-linux-gnu*)
+      cat >>e${EMULATION_NAME}.c <<EOF
 /* For a native linker, check the file /etc/ld.so.conf for directories
    in which we may find shared libraries.  /etc/ld.so.conf is really
-   only meaningful on Linux, but we check it on other systems anyhow.  */
+   only meaningful on Linux.  */
+
+struct gld${EMULATION_NAME}_ld_so_conf
+{
+  char *path;
+  size_t len, alloc;
+};
 
-static boolean gld${EMULATION_NAME}_check_ld_so_conf
-  PARAMS ((const char *, int));
+static void
+gld${EMULATION_NAME}_parse_ld_so_conf
+     (struct gld${EMULATION_NAME}_ld_so_conf *info, const char *filename);
 
-static boolean
-gld${EMULATION_NAME}_check_ld_so_conf (name, force)
-     const char *name;
-     int force;
+static void
+gld${EMULATION_NAME}_parse_ld_so_conf_include
+     (struct gld${EMULATION_NAME}_ld_so_conf *info, const char *filename,
+      const char *pattern)
 {
-  static boolean initialized;
-  static char *ld_so_conf;
+  char *newp = NULL;
+  glob_t gl;
 
-  if (! initialized)
+  if (pattern[0] != '/')
+    {
+      char *p = strrchr (filename, '/');
+      size_t patlen = strlen (pattern) + 1;
+
+      newp = xmalloc (p - filename + 1 + patlen);
+      memcpy (newp, filename, p - filename + 1);
+      memcpy (newp + (p - filename + 1), pattern, patlen);
+      pattern = newp;
+    }
+
+  if (glob (pattern, 0, NULL, &gl) == 0)
     {
-      FILE *f;
+      size_t i;
+
+      for (i = 0; i < gl.gl_pathc; ++i)
+       gld${EMULATION_NAME}_parse_ld_so_conf (info, gl.gl_pathv[i]);
+      globfree (&gl);
+    }
+
+  if (newp)
+    free (newp);
+}
+
+static void
+gld${EMULATION_NAME}_parse_ld_so_conf
+     (struct gld${EMULATION_NAME}_ld_so_conf *info, const char *filename)
+{
+  FILE *f = fopen (filename, FOPEN_RT);
+  char *line;
+  size_t linelen;
+
+  if (f == NULL)
+    return;
 
-      f = fopen ("/etc/ld.so.conf", FOPEN_RT);
-      if (f != NULL)
+  linelen = 256;
+  line = xmalloc (linelen);
+  do
+    {
+      char *p = line, *q;
+
+      /* Normally this would use getline(3), but we need to be portable.  */
+      while ((q = fgets (p, linelen - (p - line), f)) != NULL
+            && strlen (q) == linelen - (p - line) - 1
+            && line[linelen - 2] != '\n')
        {
-         char *b;
-         size_t len, alloc;
-         int c;
+         line = xrealloc (line, 2 * linelen);
+         p = line + linelen - 1;
+         linelen += linelen;
+       }
+
+      if (q == NULL && p == line)
+       break;
 
-         len = 0;
-         alloc = 100;
-         b = (char *) xmalloc (alloc);
+      p = strchr (line, '\n');
+      if (p)
+       *p = '\0';
+
+      /* Because the file format does not know any form of quoting we
+        can search forward for the next '#' character and if found
+        make it terminating the line.  */
+      p = strchr (line, '#');
+      if (p)
+       *p = '\0';
+
+      /* Remove leading whitespace.  NUL is no whitespace character.  */
+      p = line;
+      while (*p == ' ' || *p == '\f' || *p == '\r' || *p == '\t' || *p == '\v')
+       ++p;
+
+      /* If the line is blank it is ignored.  */
+      if (p[0] == '\0')
+       continue;
 
-         while ((c = getc (f)) != EOF)
+      if (!strncmp (p, "include", 7) && (p[7] == ' ' || p[7] == '\t'))
+       {
+         char *dir, c;
+         p += 8;
+         do
            {
-             if (len + 1 >= alloc)
-               {
-                 alloc *= 2;
-                 b = (char *) xrealloc (b, alloc);
-               }
-             if (c != ':'
-                 && c != ' '
-                 && c != '\t'
-                 && c != '\n'
-                 && c != ',')
-               {
-                 b[len] = c;
-                 ++len;
-               }
-             else
-               {
-                 if (len > 0 && b[len - 1] != ':')
-                   {
-                     b[len] = ':';
-                     ++len;
-                   }
-               }
-           }
+             while (*p == ' ' || *p == '\t')
+               ++p;
+
+             if (*p == '\0')
+               break;
+
+             dir = p;
 
-         if (len > 0 && b[len - 1] == ':')
-           --len;
+             while (*p != ' ' && *p != '\t' && *p)
+               ++p;
 
-         if (len > 0)
-           b[len] = '\0';
+             c = *p;
+             *p++ = '\0';
+             if (dir[0] != '\0')
+               gld${EMULATION_NAME}_parse_ld_so_conf_include (info, filename,
+                                                              dir);
+           }
+         while (c != '\0');
+       }
+      else
+       {
+         char *dir = p;
+         while (*p && *p != '=' && *p != ' ' && *p != '\t' && *p != '\f'
+                && *p != '\r' && *p != '\v')
+           ++p;
+
+         while (p != dir && p[-1] == '/')
+           --p;
+         if (info->path == NULL)
+           {
+             info->alloc = p - dir + 1 + 256;
+             info->path = xmalloc (info->alloc);
+             info->len = 0;
+           }
          else
            {
-             free (b);
-             b = NULL;
+             if (info->len + 1 + (p - dir) >= info->alloc)
+               {
+                 info->alloc += p - dir + 256;
+                 info->path = xrealloc (info->path, info->alloc);
+               }
+             info->path[info->len++] = ':';
            }
+         memcpy (info->path + info->len, dir, p - dir);
+         info->len += p - dir;
+         info->path[info->len] = '\0';
+       }
+    }
+  while (! feof (f));
+  free (line);
+  fclose (f);
+}
 
-         fclose (f);
+static bfd_boolean
+gld${EMULATION_NAME}_check_ld_so_conf (const char *name, int force)
+{
+  static bfd_boolean initialized;
+  static char *ld_so_conf;
+  struct dt_needed needed;
 
-         ld_so_conf = b;
+  if (! initialized)
+    {
+      char *tmppath;
+      struct gld${EMULATION_NAME}_ld_so_conf info;
+
+      tmppath = concat (ld_sysroot, "/etc/ld.so.conf", NULL);
+      info.path = NULL;
+      info.len = info.alloc = 0;
+      gld${EMULATION_NAME}_parse_ld_so_conf (&info, tmppath);
+      free (tmppath);
+      if (info.path)
+       {
+         char *d = gld${EMULATION_NAME}_add_sysroot (info.path);
+         free (info.path);
+         ld_so_conf = d;
        }
-
-      initialized = true;
+      initialized = TRUE;
     }
 
   if (ld_so_conf == NULL)
-    return false;
+    return FALSE;
+
 
-  return gld${EMULATION_NAME}_search_needed (ld_so_conf, name, force);
+  needed.by = NULL;
+  needed.name = name;
+  return gld${EMULATION_NAME}_search_needed (ld_so_conf, &needed, force);
 }
 
 EOF
-  ;;
+    # Linux
+    ;;
   esac
 fi
 cat >>e${EMULATION_NAME}.c <<EOF
@@ -512,17 +712,31 @@ cat >>e${EMULATION_NAME}.c <<EOF
 /* See if an input file matches a DT_NEEDED entry by name.  */
 
 static void
-gld${EMULATION_NAME}_check_needed (s)
-     lang_input_statement_type *s;
+gld${EMULATION_NAME}_check_needed (lang_input_statement_type *s)
 {
   if (global_found)
     return;
 
-  if (s->filename != NULL
-      && strcmp (s->filename, global_needed->name) == 0)
+  if (s->filename != NULL)
     {
-      global_found = true;
-      return;
+      const char *f;
+
+      if (strcmp (s->filename, global_needed->name) == 0)
+       {
+         global_found = TRUE;
+         return;
+       }
+
+      if (s->search_dirs_flag)
+       {
+         f = strrchr (s->filename, '/');
+         if (f != NULL
+             && strcmp (f + 1, global_needed->name) == 0)
+           {
+             global_found = TRUE;
+             return;
+           }
+       }
     }
 
   if (s->the_bfd != NULL)
@@ -533,22 +747,7 @@ gld${EMULATION_NAME}_check_needed (s)
       if (soname != NULL
          && strcmp (soname, global_needed->name) == 0)
        {
-         global_found = true;
-         return;
-       }
-    }
-         
-  if (s->search_dirs_flag
-      && s->filename != NULL
-      && strchr (global_needed->name, '/') == NULL)
-    {
-      const char *f;
-
-      f = strrchr (s->filename, '/');
-      if (f != NULL
-         && strcmp (f + 1, global_needed->name) == 0)
-       {
-         global_found = true;
+         global_found = TRUE;
          return;
        }
     }
@@ -562,12 +761,12 @@ cat >>e${EMULATION_NAME}.c <<EOF
 /* This is called after all the input files have been opened.  */
 
 static void
-gld${EMULATION_NAME}_after_open ()
+gld${EMULATION_NAME}_after_open (void)
 {
   struct bfd_link_needed_list *needed, *l;
 
   /* We only need to worry about this when doing a final link.  */
-  if (link_info.relocateable || link_info.shared)
+  if (link_info.relocatable || !link_info.executable)
     return;
 
   /* Get the list of files which appear in DT_NEEDED entries in
@@ -583,6 +782,7 @@ gld${EMULATION_NAME}_after_open ()
   for (l = needed; l != NULL; l = l->next)
     {
       struct bfd_link_needed_list *ll;
+      struct dt_needed n, nn;
       int force;
 
       /* If we've already seen this file, skip it.  */
@@ -594,52 +794,85 @@ gld${EMULATION_NAME}_after_open ()
 
       /* See if this file was included in the link explicitly.  */
       global_needed = l;
-      global_found = false;
+      global_found = FALSE;
       lang_for_each_input_file (gld${EMULATION_NAME}_check_needed);
       if (global_found)
        continue;
 
+      n.by = l->by;
+      n.name = l->name;
+      nn.by = l->by;
+      if (trace_file_tries)
+       info_msg (_("%s needed by %B\n"), l->name, l->by);
+
       /* We need to find this file and include the symbol table.  We
         want to search for the file in the same way that the dynamic
         linker will search.  That means that we want to use
         rpath_link, rpath, then the environment variable
-        LD_LIBRARY_PATH (native only), then the linker script
-        LIB_SEARCH_DIRS.  We do not search using the -L arguments.
+        LD_LIBRARY_PATH (native only), then the DT_RPATH/DT_RUNPATH
+        entries (native only), then the linker script LIB_SEARCH_DIRS.
+        We do not search using the -L arguments.
 
         We search twice.  The first time, we skip objects which may
         introduce version mismatches.  The second time, we force
         their use.  See gld${EMULATION_NAME}_vercheck comment.  */
       for (force = 0; force < 2; force++)
        {
-         const char *lib_path;
          size_t len;
          search_dirs_type *search;
+EOF
+if [ "x${USE_LIBPATH}" = xyes ] ; then
+cat >>e${EMULATION_NAME}.c <<EOF
+         const char *lib_path;
+         struct bfd_link_needed_list *rp;
+         int found;
+EOF
+fi
+cat >>e${EMULATION_NAME}.c <<EOF
 
          if (gld${EMULATION_NAME}_search_needed (command_line.rpath_link,
-                                                 l->name, force))
+                                                 &n, force))
            break;
+EOF
+if [ "x${USE_LIBPATH}" = xyes ] ; then
+cat >>e${EMULATION_NAME}.c <<EOF
          if (gld${EMULATION_NAME}_search_needed (command_line.rpath,
-                                                 l->name, force))
+                                                 &n, force))
            break;
+EOF
+fi
+if [ "x${NATIVE}" = xyes ] ; then
+cat >>e${EMULATION_NAME}.c <<EOF
          if (command_line.rpath_link == NULL
              && command_line.rpath == NULL)
            {
              lib_path = (const char *) getenv ("LD_RUN_PATH");
-             if (gld${EMULATION_NAME}_search_needed (lib_path, l->name,
+             if (gld${EMULATION_NAME}_search_needed (lib_path, &n,
                                                      force))
                break;
            }
+         lib_path = (const char *) getenv ("LD_LIBRARY_PATH");
+         if (gld${EMULATION_NAME}_search_needed (lib_path, &n, force))
+           break;
 EOF
-if [ "x${host}" = "x${target}" ] ; then
-  case " ${EMULATION_LIBPATH} " in
-  *" ${EMULATION_NAME} "*)
+fi
+if [ "x${USE_LIBPATH}" = xyes ] ; then
 cat >>e${EMULATION_NAME}.c <<EOF
-         lib_path = (const char *) getenv ("LD_LIBRARY_PATH");
-         if (gld${EMULATION_NAME}_search_needed (lib_path, l->name, force))
+         found = 0;
+         rp = bfd_elf_get_runpath_list (output_bfd, &link_info);
+         for (; !found && rp != NULL; rp = rp->next)
+           {
+             char *tmpname = gld${EMULATION_NAME}_add_sysroot (rp->name);
+             found = (rp->by == l->by
+                      && gld${EMULATION_NAME}_search_needed (tmpname,
+                                                             &n,
+                                                             force));
+             free (tmpname);
+           }
+         if (found)
            break;
+
 EOF
-  ;;
-  esac
 fi
 cat >>e${EMULATION_NAME}.c <<EOF
          len = strlen (l->name);
@@ -651,21 +884,23 @@ cat >>e${EMULATION_NAME}.c <<EOF
                continue;
              filename = (char *) xmalloc (strlen (search->name) + len + 2);
              sprintf (filename, "%s/%s", search->name, l->name);
-             if (gld${EMULATION_NAME}_try_needed (filename, force))
+             nn.name = filename;
+             if (gld${EMULATION_NAME}_try_needed (&nn, force))
                break;
              free (filename);
            }
          if (search != NULL)
            break;
 EOF
-if [ "x${host}" = "x${target}" ] ; then
-  case " ${EMULATION_LIBPATH} " in
-  *" ${EMULATION_NAME} "*)
-cat >>e${EMULATION_NAME}.c <<EOF
+if [ "x${USE_LIBPATH}" = xyes ] ; then
+  case ${target} in
+    *-*-linux-gnu*)
+      cat >>e${EMULATION_NAME}.c <<EOF
          if (gld${EMULATION_NAME}_check_ld_so_conf (l->name, force))
            break;
 EOF
-  ;;
+    # Linux
+    ;;
   esac
 fi
 cat >>e${EMULATION_NAME}.c <<EOF
@@ -687,8 +922,7 @@ cat >>e${EMULATION_NAME}.c <<EOF
 /* Look through an expression for an assignment statement.  */
 
 static void
-gld${EMULATION_NAME}_find_exp_assignment (exp)
-     etree_type *exp;
+gld${EMULATION_NAME}_find_exp_assignment (etree_type *exp)
 {
   struct bfd_link_hash_entry *h;
 
@@ -696,7 +930,7 @@ gld${EMULATION_NAME}_find_exp_assignment (exp)
     {
     case etree_provide:
       h = bfd_link_hash_lookup (link_info.hash, exp->assign.dst,
-                               false, false, false);
+                               FALSE, FALSE, FALSE);
       if (h == NULL)
        break;
 
@@ -712,9 +946,9 @@ gld${EMULATION_NAME}_find_exp_assignment (exp)
     case etree_assign:
       if (strcmp (exp->assign.dst, ".") != 0)
        {
-         if (! (bfd_elf${ELFSIZE}_record_link_assignment
+         if (! (bfd_elf_record_link_assignment
                 (output_bfd, &link_info, exp->assign.dst,
-                 exp->type.node_class == etree_provide ? true : false)))
+                 exp->type.node_class == etree_provide ? TRUE : FALSE)))
            einfo ("%P%F: failed to record assignment to %s: %E\n",
                   exp->assign.dst);
        }
@@ -748,8 +982,7 @@ gld${EMULATION_NAME}_find_exp_assignment (exp)
    symbols which are referred to by dynamic objects.  */
 
 static void
-gld${EMULATION_NAME}_find_statement_assignment (s)
-     lang_statement_union_type *s;
+gld${EMULATION_NAME}_find_statement_assignment (lang_statement_union_type *s)
 {
   if (s->header.type == lang_assignment_statement_enum)
     gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp);
@@ -758,17 +991,32 @@ gld${EMULATION_NAME}_find_statement_assignment (s)
 EOF
 
 if test x"$LDEMUL_BEFORE_ALLOCATION" != xgld"$EMULATION_NAME"_before_allocation; then
+  if test x"${ELF_INTERPRETER_NAME+set}" = xset; then
+    ELF_INTERPRETER_SET_DEFAULT="
+  if (sinterp != NULL)
+    {
+      sinterp->contents = ${ELF_INTERPRETER_NAME};
+      sinterp->size = strlen (sinterp->contents) + 1;
+    }
+
+"
+  else
+    ELF_INTERPRETER_SET_DEFAULT=
+  fi
 cat >>e${EMULATION_NAME}.c <<EOF
 
 /* This is called after the sections have been attached to output
    sections, but before any sizes or addresses have been set.  */
 
 static void
-gld${EMULATION_NAME}_before_allocation ()
+gld${EMULATION_NAME}_before_allocation (void)
 {
   const char *rpath;
   asection *sinterp;
 
+  if (link_info.hash->type == bfd_link_elf_hash_table)
+    _bfd_elf_tls_setup (output_bfd, &link_info);
+
   /* If we are going to make any variable assignments, we need to let
      the ELF backend know about them in case the variables are
      referred to by dynamic objects.  */
@@ -779,19 +1027,19 @@ gld${EMULATION_NAME}_before_allocation ()
   rpath = command_line.rpath;
   if (rpath == NULL)
     rpath = (const char *) getenv ("LD_RUN_PATH");
-  if (! (bfd_elf${ELFSIZE}_size_dynamic_sections
-         (output_bfd, command_line.soname, rpath,
-         command_line.export_dynamic, command_line.filter_shlib,
+  if (! (bfd_elf_size_dynamic_sections
+        (output_bfd, command_line.soname, rpath,
+         command_line.filter_shlib,
          (const char * const *) command_line.auxiliary_filters,
          &link_info, &sinterp, lang_elf_version_info)))
     einfo ("%P%F: failed to set dynamic section sizes: %E\n");
-
+${ELF_INTERPRETER_SET_DEFAULT}
   /* Let the user override the dynamic linker we are using.  */
   if (command_line.interpreter != NULL
       && sinterp != NULL)
     {
       sinterp->contents = (bfd_byte *) command_line.interpreter;
-      sinterp->_raw_size = strlen (command_line.interpreter) + 1;
+      sinterp->size = strlen (command_line.interpreter) + 1;
     }
 
   /* Look for any sections named .gnu.warning.  As a GNU extensions,
@@ -804,8 +1052,10 @@ gld${EMULATION_NAME}_before_allocation ()
       {
        asection *s;
        bfd_size_type sz;
+       bfd_size_type prefix_len;
        char *msg;
-       boolean ret;
+       bfd_boolean ret;
+       const char * gnu_warning_prefix = _("warning: ");
 
        if (is->just_syms_flag)
          continue;
@@ -814,12 +1064,15 @@ gld${EMULATION_NAME}_before_allocation ()
        if (s == NULL)
          continue;
 
-       sz = bfd_section_size (is->the_bfd, s);
-       msg = xmalloc ((size_t) sz + 1);
-       if (! bfd_get_section_contents (is->the_bfd, s, msg, (file_ptr) 0, sz))
+       sz = s->size;
+       prefix_len = strlen (gnu_warning_prefix);
+       msg = xmalloc ((size_t) (prefix_len + sz + 1));
+       strcpy (msg, gnu_warning_prefix);
+       if (! bfd_get_section_contents (is->the_bfd, s, msg + prefix_len,
+                                       (file_ptr) 0, sz))
          einfo ("%F%B: Can't read contents of section .gnu.warning: %E\n",
                 is->the_bfd);
-       msg[sz] = '\0';
+       msg[prefix_len + sz] = '\0';
        ret = link_info.callbacks->warning (&link_info, msg,
                                            (const char *) NULL,
                                            is->the_bfd, (asection *) NULL,
@@ -829,7 +1082,7 @@ gld${EMULATION_NAME}_before_allocation ()
 
        /* Clobber the section size, so that we don't waste copying the
           warning into the output file.  */
-       s->_raw_size = 0;
+       s->size = 0;
       }
   }
 }
@@ -844,17 +1097,15 @@ cat >>e${EMULATION_NAME}.c <<EOF
    dynamic libraries have an extension of .so (or .sl on oddball systems
    like hpux).  */
 
-static boolean
-gld${EMULATION_NAME}_open_dynamic_archive (arch, search, entry)
-     const char *arch;
-     search_dirs_type *search;
-     lang_input_statement_type *entry;
+static bfd_boolean
+gld${EMULATION_NAME}_open_dynamic_archive
+  (const char *arch, search_dirs_type *search, lang_input_statement_type *entry)
 {
   const char *filename;
   char *string;
 
   if (! entry->is_archive)
-    return false;
+    return FALSE;
 
   filename = entry->filename;
 
@@ -882,7 +1133,7 @@ gld${EMULATION_NAME}_open_dynamic_archive (arch, search, entry)
   if (! ldfile_try_open_bfd (string, entry))
     {
       free (string);
-      return false;
+      return FALSE;
     }
 
   entry->filename = string;
@@ -903,111 +1154,186 @@ gld${EMULATION_NAME}_open_dynamic_archive (arch, search, entry)
   if (bfd_check_format (entry->the_bfd, bfd_object)
       && (entry->the_bfd->flags & DYNAMIC) != 0)
     {
-      char *needed_name;
-
       ASSERT (entry->is_archive && entry->search_dirs_flag);
 
       /* Rather than duplicating the logic above.  Just use the
-        filename we recorded earlier.
+        filename we recorded earlier.  */
 
-        First strip off everything before the last '/'.  */
-      filename = strrchr (entry->filename, '/');
-      filename++;
-
-      needed_name = (char *) xmalloc (strlen (filename) + 1);
-      strcpy (needed_name, filename);
-      bfd_elf_set_dt_needed_name (entry->the_bfd, needed_name);
+      filename = lbasename (entry->filename);
+      bfd_elf_set_dt_needed_name (entry->the_bfd, filename);
     }
 
-  return true;
+  return TRUE;
 }
 
 EOF
 fi
+
+if test x"$LDEMUL_PLACE_ORPHAN" != xgld"$EMULATION_NAME"_place_orphan; then
 cat >>e${EMULATION_NAME}.c <<EOF
 
-/* A variant of lang_output_section_find.  Used by place_orphan.  */
+/* A variant of lang_output_section_find used by place_orphan.  */
 
 static lang_output_section_statement_type *
-output_rel_find ()
+output_rel_find (asection *sec, int isdyn)
 {
-  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)
+  lang_output_section_statement_type *last = NULL;
+  lang_output_section_statement_type *last_alloc = NULL;
+  lang_output_section_statement_type *last_rel = NULL;
+  lang_output_section_statement_type *last_rel_alloc = NULL;
+  int rela = sec->name[4] == 'a';
+
+  for (lookup = &lang_output_section_statement.head->output_section_statement;
+       lookup != NULL;
+       lookup = lookup->next)
     {
-      lookup = &u->output_section_statement;
-      if (strncmp (".rel", lookup->name, 4) == 0
-         && lookup->bfd_section != NULL
-         && (lookup->bfd_section->flags & SEC_ALLOC) != 0)
+      if (lookup->constraint != -1
+         && strncmp (".rel", lookup->name, 4) == 0)
        {
-         return lookup;
+         int lookrela = lookup->name[4] == 'a';
+
+         /* .rel.dyn must come before all other reloc sections, to suit
+            GNU ld.so.  */
+         if (isdyn)
+           break;
+
+         /* Don't place after .rel.plt as doing so results in wrong
+            dynamic tags.  */
+         if (strcmp (".plt", lookup->name + 4 + lookrela) == 0)
+           break;
+
+         if (rela == lookrela || last_rel == NULL)
+           last_rel = lookup;
+         if ((rela == lookrela || last_rel_alloc == NULL)
+             && lookup->bfd_section != NULL
+             && (lookup->bfd_section->flags & SEC_ALLOC) != 0)
+           last_rel_alloc = lookup;
        }
+
+      last = lookup;
+      if (lookup->bfd_section != NULL
+         && (lookup->bfd_section->flags & SEC_ALLOC) != 0)
+       last_alloc = lookup;
     }
-  return (lang_output_section_statement_type *) NULL;
-}
 
-EOF
+  if (last_rel_alloc)
+    return last_rel_alloc;
 
-if test x"$LDEMUL_PLACE_ORPHAN" != xgld"$EMULATION_NAME"_place_orphan; then
-cat >>e${EMULATION_NAME}.c <<EOF
+  if (last_rel)
+    return last_rel;
+
+  if (last_alloc)
+    return last_alloc;
+
+  return last;
+}
 
 /* Place an orphan section.  We use this to put random SHF_ALLOC
    sections in the right segment.  */
 
-struct orphan_save {
-  lang_output_section_statement_type *os;
-  asection **section;
-  lang_statement_union_type **stmt;
-};
-
-static boolean
-gld${EMULATION_NAME}_place_orphan (file, s)
-     lang_input_statement_type *file;
-     asection *s;
+static bfd_boolean
+gld${EMULATION_NAME}_place_orphan (lang_input_statement_type *file, asection *s)
 {
-  static struct orphan_save hold_text;
-  static struct orphan_save hold_rodata;
-  static struct orphan_save hold_data;
-  static struct orphan_save hold_bss;
-  static struct orphan_save hold_rel;
-  static struct orphan_save hold_interp;
+  static struct orphan_save hold[] =
+    {
+      { ".text",
+       SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE,
+       0, 0, 0, 0 },
+      { ".rodata",
+       SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA,
+       0, 0, 0, 0 },
+      { ".data",
+       SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_DATA,
+       0, 0, 0, 0 },
+      { ".bss",
+       SEC_ALLOC,
+       0, 0, 0, 0 },
+      { 0,
+       SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA,
+       0, 0, 0, 0 },
+      { ".interp",
+       SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA,
+       0, 0, 0, 0 },
+      { ".sdata",
+       SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_SMALL_DATA,
+       0, 0, 0, 0 }
+    };
+  enum orphan_save_index
+    {
+      orphan_text = 0,
+      orphan_rodata,
+      orphan_data,
+      orphan_bss,
+      orphan_rel,
+      orphan_interp,
+      orphan_sdata
+    };
+  static int orphan_init_done = 0;
   struct orphan_save *place;
-  lang_statement_list_type *old = NULL;
-  lang_statement_list_type add;
-  etree_type *address;
-  const char *secname, *ps = NULL;
-  const char *outsecname;
+  const char *secname;
+  lang_output_section_statement_type *after;
   lang_output_section_statement_type *os;
+  int isdyn = 0;
 
   secname = bfd_get_section_name (s->owner, s);
 
-  /* Look through the script to see where to place this section.  */
-  os = lang_output_section_find (secname);
+  if (! link_info.relocatable
+      && link_info.combreloc
+      && (s->flags & SEC_ALLOC)
+      && strncmp (secname, ".rel", 4) == 0)
+    {
+      if (secname[4] == 'a')
+       secname = ".rela.dyn";
+      else
+       secname = ".rel.dyn";
+      isdyn = 1;
+    }
 
-  if (os != NULL
-      && os->bfd_section != NULL
-      && ((s->flags ^ os->bfd_section->flags) & (SEC_LOAD | SEC_ALLOC)) == 0)
+  if (isdyn || (!config.unique_orphan_sections && !unique_section_p (s)))
     {
-      /* We have already placed a section with this name.  */
-      wild_doit (&os->children, s, os, file);
-      return true;
+      /* Look through the script to see where to place this section.  */
+      os = lang_output_section_find (secname);
+
+      if (os != NULL
+         && (os->bfd_section == NULL
+             || os->bfd_section->flags == 0
+             || ((s->flags ^ os->bfd_section->flags)
+                 & (SEC_LOAD | SEC_ALLOC)) == 0))
+       {
+         /* We already have an output section statement with this
+            name, and its bfd section, if any, has compatible flags.
+            If the section already exists but does not have any flags
+            set, then it has been created by the linker, probably as a
+            result of a --section-start command line switch.  */
+         lang_add_section (&os->children, s, os, file);
+         return TRUE;
+       }
     }
 
-  if (hold_text.os == NULL)
-    hold_text.os = lang_output_section_find (".text");
+  if (!orphan_init_done)
+    {
+      struct orphan_save *ho;
+      for (ho = hold; ho < hold + sizeof (hold) / sizeof (hold[0]); ++ho)
+       if (ho->name != NULL)
+         {
+           ho->os = lang_output_section_find (ho->name);
+           if (ho->os != NULL && ho->os->flags == 0)
+             ho->os->flags = ho->flags;
+         }
+      orphan_init_done = 1;
+    }
 
   /* If this is a final link, then always put .gnu.warning.SYMBOL
      sections into the .text section to get them out of the way.  */
-  if (! link_info.shared
-      && ! link_info.relocateable
+  if (link_info.executable
+      && ! link_info.relocatable
       && strncmp (secname, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0
-      && hold_text.os != NULL)
+      && hold[orphan_text].os != NULL)
     {
-      wild_doit (&hold_text.os->children, s, hold_text.os, file);
-      return true;
+      lang_add_section (&hold[orphan_text].os->children, s,
+                       hold[orphan_text].os, file);
+      return TRUE;
     }
 
   /* Decide which segment the section should go in based on the
@@ -1015,172 +1341,85 @@ gld${EMULATION_NAME}_place_orphan (file, s)
      right after the .interp section, so that the PT_NOTE segment is
      stored right after the program headers where the OS can read it
      in the first page.  */
-#define HAVE_SECTION(hold, name) \
-(hold.os != NULL || (hold.os = lang_output_section_find (name)) != NULL)
 
-  if (s->flags & SEC_EXCLUDE)
-    return false;
-  else if ((s->flags & SEC_ALLOC) == 0)
-    place = NULL;
+  place = NULL;
+  if ((s->flags & SEC_ALLOC) == 0)
+    ;
   else if ((s->flags & SEC_LOAD) != 0
-          && strncmp (secname, ".note", 4) == 0
-          && HAVE_SECTION (hold_interp, ".interp"))
-    place = &hold_interp;
-  else if ((s->flags & SEC_HAS_CONTENTS) == 0
-          && HAVE_SECTION (hold_bss, ".bss"))
-    place = &hold_bss;
-  else if ((s->flags & SEC_READONLY) == 0
-          && HAVE_SECTION (hold_data, ".data"))
-    place = &hold_data;
+          && strncmp (secname, ".note", 5) == 0)
+    place = &hold[orphan_interp];
+  else if ((s->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
+    place = &hold[orphan_bss];
+  else if ((s->flags & SEC_SMALL_DATA) != 0)
+    place = &hold[orphan_sdata];
+  else if ((s->flags & SEC_READONLY) == 0)
+    place = &hold[orphan_data];
   else if (strncmp (secname, ".rel", 4) == 0
-          && (hold_rel.os != NULL
-              || (hold_rel.os = output_rel_find ()) != NULL))
-    place = &hold_rel;
-  else if ((s->flags & SEC_CODE) == 0
-          && (s->flags & SEC_READONLY) != 0
-          && HAVE_SECTION (hold_rodata, ".rodata"))
-    place = &hold_rodata;
-  else if ((s->flags & SEC_READONLY) != 0
-          && hold_text.os != NULL)
-    place = &hold_text;
+          && (s->flags & SEC_LOAD) != 0)
+    place = &hold[orphan_rel];
+  else if ((s->flags & SEC_CODE) == 0)
+    place = &hold[orphan_rodata];
   else
-    place = NULL;
-
-#undef HAVE_SECTION
+    place = &hold[orphan_text];
 
-  /* Choose a unique name for the section.  This will be needed if the
-     same section name appears in the input file with different
-     loadable or allocateable characteristics.  */
-  outsecname = secname;
-  if (bfd_get_section_by_name (output_bfd, outsecname) != NULL)
+  after = NULL;
+  if (place != NULL)
     {
-      unsigned int len;
-      char *newname;
-      unsigned int i;
-
-      len = strlen (outsecname);
-      newname = xmalloc (len + 5);
-      strcpy (newname, outsecname);
-      i = 0;
-      do
+      if (place->os == NULL)
        {
-         sprintf (newname + len, "%d", i);
-         ++i;
+         if (place->name != NULL)
+           place->os = lang_output_section_find (place->name);
+         else
+           place->os = output_rel_find (s, isdyn);
        }
-      while (bfd_get_section_by_name (output_bfd, newname) != NULL);
-
-      outsecname = newname;
+      after = place->os;
+      if (after == NULL)
+       after = lang_output_section_find_by_flags (s, &place->os);
+      if (after == NULL)
+       /* *ABS* is always the first output section statement.  */
+       after = &lang_output_section_statement.head->output_section_statement;
     }
 
-  if (place != NULL)
+  /* Choose a unique name for the section.  This will be needed if the
+     same section name appears in the input file with different
+     loadable or allocatable characteristics.  */
+  if (bfd_get_section_by_name (output_bfd, secname) != NULL)
     {
-      /* Start building a list of statements for this section.  */
-      old = stat_ptr;
-      stat_ptr = &add;
-      lang_list_init (stat_ptr);
-
-      /* If the name of the section is representable in C, then create
-        symbols to mark the start and the end of the section.  */
-      for (ps = outsecname; *ps != '\0'; ps++)
-       if (! isalnum ((unsigned char) *ps) && *ps != '_')
-         break;
-      if (*ps == '\0' && config.build_constructors)
-       {
-         char *symname;
-         etree_type *e_align;
-
-         symname = (char *) xmalloc (ps - outsecname + sizeof "__start_");
-         sprintf (symname, "__start_%s", outsecname);
-         e_align = exp_unop (ALIGN_K,
-                             exp_intop ((bfd_vma) 1 << s->alignment_power));
-         lang_add_assignment (exp_assop ('=', symname, e_align));
-       }
+      static int count = 1;
+      secname = bfd_get_unique_section_name (output_bfd, secname, &count);
+      if (secname == NULL)
+       einfo ("%F%P: place_orphan failed: %E\n");
     }
 
-  if (link_info.relocateable || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0)
-    address = exp_intop ((bfd_vma) 0);
-  else
-    address = NULL;
-
-  os = lang_enter_output_section_statement (outsecname, address, 0,
-                                           (bfd_vma) 0,
-                                           (etree_type *) NULL,
-                                           (etree_type *) NULL,
-                                           (etree_type *) NULL);
+  lang_insert_orphan (file, s, secname, after, place, NULL, NULL);
 
-  wild_doit (&os->children, s, os, file);
+  return TRUE;
+}
+EOF
+fi
 
-  lang_leave_output_section_statement
-    ((bfd_vma) 0, "*default*",
-     (struct lang_output_section_phdr_list *) NULL, "*default*");
+if test x"$LDEMUL_FINISH" != xgld"$EMULATION_NAME"_finish; then
+cat >>e${EMULATION_NAME}.c <<EOF
 
-  if (place != NULL)
+static void
+gld${EMULATION_NAME}_finish (void)
+{
+  if (bfd_elf_discard_info (output_bfd, &link_info))
     {
-      asection *snew, **pps;
+      lang_reset_memory_regions ();
 
-      stat_ptr = &add;
+      /* Resize the sections.  */
+      lang_size_sections (stat_ptr->head, abs_output_section,
+                         &stat_ptr->head, 0, (bfd_vma) 0, NULL, TRUE);
 
-      if (*ps == '\0' && config.build_constructors)
-       {
-         char *symname;
+      /* Redo special stuff.  */
+      ldemul_after_allocation ();
 
-         symname = (char *) xmalloc (ps - outsecname + sizeof "__stop_");
-         sprintf (symname, "__stop_%s", outsecname);
-         lang_add_assignment (exp_assop ('=', symname,
-                                         exp_nameop (NAME, ".")));
-       }
-      stat_ptr = old;
-
-      snew = os->bfd_section;
-      if (place->os->bfd_section != NULL || place->section != NULL)
-       {
-         /* Shuffle the section to make the output file look neater.  */
-         if (place->section == NULL)
-           {
-#if 0
-             /* Finding the end of the list is a little tricky.  We
-                make a wild stab at it by comparing section flags.  */
-             flagword first_flags = place->os->bfd_section->flags;
-             for (pps = &place->os->bfd_section->next;
-                  *pps != NULL && (*pps)->flags == first_flags;
-                  pps = &(*pps)->next)
-               ;
-             place->section = pps;
-#else
-             /* Put orphans after the first section on the list.  */
-             place->section = &place->os->bfd_section->next;
-#endif
-           }
-
-         /*  Unlink the section.  */
-         for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
-           ;
-         *pps = snew->next;
-
-         /* Now tack it on to the "place->os" section list.  */
-         snew->next = *place->section;
-         *place->section = snew;
-       }
-      place->section = &snew->next;    /* Save the end of this list.  */
-
-      if (place->stmt == NULL)
-       {
-         /* Put the new statement list right at the head.  */
-         *add.tail = place->os->header.next;
-         place->os->header.next = add.head;
-       }
-      else
-       {
-         /* Put it after the last orphan statement we added.  */
-         *add.tail = *place->stmt;
-         *place->stmt = add.head;
-       }
-      place->stmt = add.tail;          /* Save the end of this list.  */
+      /* Do the assignments again.  */
+      lang_do_assignments (stat_ptr->head, abs_output_section,
+                          (fill_type *) 0, (bfd_vma) 0);
     }
-
-  return true;
 }
-
 EOF
 fi
 
@@ -1188,8 +1427,7 @@ if test x"$LDEMUL_GET_SCRIPT" != xgld"$EMULATION_NAME"_get_script; then
 cat >>e${EMULATION_NAME}.c <<EOF
 
 static char *
-gld${EMULATION_NAME}_get_script (isfile)
-     int *isfile;
+gld${EMULATION_NAME}_get_script (int *isfile)
 EOF
 
 if test -n "$COMPILE_IN"
@@ -1203,25 +1441,52 @@ cat >>e${EMULATION_NAME}.c <<EOF
 {
   *isfile = 0;
 
-  if (link_info.relocateable == true && config.build_constructors == true)
+  if (link_info.relocatable && config.build_constructors)
     return
 EOF
-sed $sc ldscripts/${EMULATION_NAME}.xu                     >> e${EMULATION_NAME}.c
-echo '  ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c
-sed $sc ldscripts/${EMULATION_NAME}.xr                     >> e${EMULATION_NAME}.c
-echo '  ; else if (!config.text_read_only) return'         >> e${EMULATION_NAME}.c
-sed $sc ldscripts/${EMULATION_NAME}.xbn                    >> e${EMULATION_NAME}.c
-echo '  ; else if (!config.magic_demand_paged) return'     >> e${EMULATION_NAME}.c
-sed $sc ldscripts/${EMULATION_NAME}.xn                     >> e${EMULATION_NAME}.c
-
+sed $sc ldscripts/${EMULATION_NAME}.xu                 >> e${EMULATION_NAME}.c
+echo '  ; else if (link_info.relocatable) return'      >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xr                 >> e${EMULATION_NAME}.c
+echo '  ; else if (!config.text_read_only) return'     >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xbn                        >> e${EMULATION_NAME}.c
+if cmp -s ldscripts/${EMULATION_NAME}.x ldscripts/${EMULATION_NAME}.xn; then : ; else
+echo '  ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xn                 >> e${EMULATION_NAME}.c
+fi
+if test -n "$GENERATE_PIE_SCRIPT" ; then
+if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
+echo '  ; else if (link_info.pie && link_info.combreloc' >> e${EMULATION_NAME}.c
+echo '             && link_info.relro' >> e${EMULATION_NAME}.c
+echo '             && (link_info.flags & DT_BIND_NOW)) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xdw                        >> e${EMULATION_NAME}.c
+echo '  ; else if (link_info.pie && link_info.combreloc) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xdc                        >> e${EMULATION_NAME}.c
+fi
+echo '  ; else if (link_info.pie) return'              >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xd                 >> e${EMULATION_NAME}.c
+fi
 if test -n "$GENERATE_SHLIB_SCRIPT" ; then
-echo '  ; else if (link_info.shared) return'              >> e${EMULATION_NAME}.c
-sed $sc ldscripts/${EMULATION_NAME}.xs                     >> e${EMULATION_NAME}.c
+if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
+echo '  ; else if (link_info.shared && link_info.combreloc' >> e${EMULATION_NAME}.c
+echo '             && link_info.relro' >> e${EMULATION_NAME}.c
+echo '             && (link_info.flags & DT_BIND_NOW)) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xsw                        >> e${EMULATION_NAME}.c
+echo '  ; else if (link_info.shared && link_info.combreloc) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xsc                        >> e${EMULATION_NAME}.c
 fi
-
-echo '  ; else return'                                     >> e${EMULATION_NAME}.c
-sed $sc ldscripts/${EMULATION_NAME}.x                      >> e${EMULATION_NAME}.c
-echo '; }'                                                 >> e${EMULATION_NAME}.c
+echo '  ; else if (link_info.shared) return'           >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xs                 >> e${EMULATION_NAME}.c
+fi
+if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
+echo '  ; else if (link_info.combreloc && link_info.relro' >> e${EMULATION_NAME}.c
+echo '             && (link_info.flags & DT_BIND_NOW)) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xw                 >> e${EMULATION_NAME}.c
+echo '  ; else if (link_info.combreloc) return'                >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xc                 >> e${EMULATION_NAME}.c
+fi
+echo '  ; else return'                                 >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.x                  >> e${EMULATION_NAME}.c
+echo '; }'                                             >> e${EMULATION_NAME}.c
 
 else
 # Scripts read from the filesystem.
@@ -1230,16 +1495,60 @@ cat >>e${EMULATION_NAME}.c <<EOF
 {
   *isfile = 1;
 
-  if (link_info.relocateable == true && config.build_constructors == true)
+  if (link_info.relocatable && config.build_constructors)
     return "ldscripts/${EMULATION_NAME}.xu";
-  else if (link_info.relocateable == true)
+  else if (link_info.relocatable)
     return "ldscripts/${EMULATION_NAME}.xr";
   else if (!config.text_read_only)
     return "ldscripts/${EMULATION_NAME}.xbn";
+EOF
+if cmp -s ldscripts/${EMULATION_NAME}.x ldscripts/${EMULATION_NAME}.xn; then :
+else
+cat >>e${EMULATION_NAME}.c <<EOF
   else if (!config.magic_demand_paged)
     return "ldscripts/${EMULATION_NAME}.xn";
+EOF
+fi
+if test -n "$GENERATE_PIE_SCRIPT" ; then
+if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
+cat >>e${EMULATION_NAME}.c <<EOF
+  else if (link_info.pie && link_info.combreloc
+          && link_info.relro && (link_info.flags & DT_BIND_NOW))
+    return "ldscripts/${EMULATION_NAME}.xdw";
+  else if (link_info.pie && link_info.combreloc)
+    return "ldscripts/${EMULATION_NAME}.xdc";
+EOF
+fi
+cat >>e${EMULATION_NAME}.c <<EOF
+  else if (link_info.pie)
+    return "ldscripts/${EMULATION_NAME}.xd";
+EOF
+fi
+if test -n "$GENERATE_SHLIB_SCRIPT" ; then
+if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
+cat >>e${EMULATION_NAME}.c <<EOF
+  else if (link_info.shared && link_info.combreloc
+          && link_info.relro && (link_info.flags & DT_BIND_NOW))
+    return "ldscripts/${EMULATION_NAME}.xsw";
+  else if (link_info.shared && link_info.combreloc)
+    return "ldscripts/${EMULATION_NAME}.xsc";
+EOF
+fi
+cat >>e${EMULATION_NAME}.c <<EOF
   else if (link_info.shared)
     return "ldscripts/${EMULATION_NAME}.xs";
+EOF
+fi
+if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
+cat >>e${EMULATION_NAME}.c <<EOF
+  else if (link_info.combreloc && link_info.relro
+          && (link_info.flags & DT_BIND_NOW))
+    return "ldscripts/${EMULATION_NAME}.xw";
+  else if (link_info.combreloc)
+    return "ldscripts/${EMULATION_NAME}.xc";
+EOF
+fi
+cat >>e${EMULATION_NAME}.c <<EOF
   else
     return "ldscripts/${EMULATION_NAME}.x";
 }
@@ -1250,8 +1559,6 @@ fi
 
 if test -n "$PARSE_AND_LIST_ARGS_CASES" -o x"$GENERATE_SHLIB_SCRIPT" = xyes; then
 
-if test x"$LDEMUL_PARSE_ARGS" != xgld"$EMULATION_NAME"_parse_args; then
-
 if test -n "$PARSE_AND_LIST_PROLOGUE" ; then
 cat >>e${EMULATION_NAME}.c <<EOF
  $PARSE_AND_LIST_PROLOGUE
@@ -1260,79 +1567,81 @@ fi
 
 cat >>e${EMULATION_NAME}.c <<EOF
 
-#include "getopt.h"
-
 #define OPTION_DISABLE_NEW_DTAGS       (400)
 #define OPTION_ENABLE_NEW_DTAGS                (OPTION_DISABLE_NEW_DTAGS + 1)
-
-static struct option longopts[] =
+#define OPTION_GROUP                   (OPTION_ENABLE_NEW_DTAGS + 1)
+#define OPTION_EH_FRAME_HDR            (OPTION_GROUP + 1)
+#define OPTION_EXCLUDE_LIBS            (OPTION_EH_FRAME_HDR + 1)
+  
+static void
+gld${EMULATION_NAME}_add_options
+  (int ns, char **shortopts, int nl, struct option **longopts,
+   int nrl ATTRIBUTE_UNUSED, struct option **really_longopts ATTRIBUTE_UNUSED)
 {
+  static const char xtra_short[] = "${PARSE_AND_LIST_SHORTOPTS}z:";
+  static const struct option xtra_long[] = {
 EOF
 
 if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
 cat >>e${EMULATION_NAME}.c <<EOF
-  /* getopt allows abbreviations, so we do this to stop it from
-     treating -d/-e as abbreviations for these options. */
-  {"disable-new-dtags", no_argument, NULL, OPTION_DISABLE_NEW_DTAGS},
-  {"disable-new-dtags", no_argument, NULL, OPTION_DISABLE_NEW_DTAGS},
-  {"enable-new-dtags", no_argument, NULL, OPTION_ENABLE_NEW_DTAGS},
-  {"enable-new-dtags", no_argument, NULL, OPTION_ENABLE_NEW_DTAGS},
+    {"disable-new-dtags", no_argument, NULL, OPTION_DISABLE_NEW_DTAGS},
+    {"enable-new-dtags", no_argument, NULL, OPTION_ENABLE_NEW_DTAGS},
+    {"eh-frame-hdr", no_argument, NULL, OPTION_EH_FRAME_HDR},
+    {"exclude-libs", required_argument, NULL, OPTION_EXCLUDE_LIBS},
+    {"Bgroup", no_argument, NULL, OPTION_GROUP},
 EOF
 fi
 
 if test -n "$PARSE_AND_LIST_LONGOPTS" ; then
 cat >>e${EMULATION_NAME}.c <<EOF
- $PARSE_AND_LIST_LONGOPTS
   $PARSE_AND_LIST_LONGOPTS
 EOF
 fi
 
 cat >>e${EMULATION_NAME}.c <<EOF
-  {NULL, no_argument, NULL, 0}
-};
-
-
-static int gld${EMULATION_NAME}_parse_args PARAMS ((int, char **));
+    {NULL, no_argument, NULL, 0}
+  };
+
+  *shortopts = (char *) xrealloc (*shortopts, ns + sizeof (xtra_short));
+  memcpy (*shortopts + ns, &xtra_short, sizeof (xtra_short));
+  *longopts = (struct option *)
+    xrealloc (*longopts, nl * sizeof (struct option) + sizeof (xtra_long));
+  memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long));
+}
 
-static int
-gld${EMULATION_NAME}_parse_args (argc, argv)
-     int argc;
-     char ** argv;
+static bfd_boolean
+gld${EMULATION_NAME}_handle_option (int optc)
 {
-  int longind;
-  int optc;
-  static int prevoptind = -1;
-  int prevopterr = opterr;
-  int wanterror;
-
-  if (prevoptind != optind)
-    opterr = 0;
-
-  wanterror = opterr;
-  prevoptind = optind;
-
-  optc = getopt_long_only (argc, argv,
-                          "-${PARSE_AND_LIST_SHORTOPTS}z:", longopts,
-                          &longind);
-  opterr = prevopterr;
-
   switch (optc)
     {
     default:
-      if (wanterror)
-       xexit (1);
-      optind = prevoptind;
-      return 0;
+      return FALSE;
 
 EOF
 
 if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
 cat >>e${EMULATION_NAME}.c <<EOF
     case OPTION_DISABLE_NEW_DTAGS:
-      link_info.new_dtags = false;
+      link_info.new_dtags = FALSE;
       break;
 
     case OPTION_ENABLE_NEW_DTAGS:
-      link_info.new_dtags = true;
+      link_info.new_dtags = TRUE;
+      break;
+
+    case OPTION_EH_FRAME_HDR:
+      link_info.eh_frame_hdr = TRUE;
+      break;
+
+    case OPTION_GROUP:
+      link_info.flags_1 |= (bfd_vma) DF_1_GROUP;
+      /* Groups must be self-contained.  */
+      link_info.unresolved_syms_in_objects = RM_GENERATE_ERROR;
+      link_info.unresolved_syms_in_shared_libs = RM_GENERATE_ERROR;
+      break;
+
+    case OPTION_EXCLUDE_LIBS:
+      add_excluded_libs (optarg);
       break;
 
     case 'z':
@@ -1360,6 +1669,30 @@ cat >>e${EMULATION_NAME}.c <<EOF
          link_info.flags |= (bfd_vma) DF_ORIGIN;
          link_info.flags_1 |= (bfd_vma) DF_1_ORIGIN;
        }
+      else if (strcmp (optarg, "defs") == 0)
+       link_info.unresolved_syms_in_objects = RM_GENERATE_ERROR;
+      else if (strcmp (optarg, "muldefs") == 0)
+       link_info.allow_multiple_definition = TRUE;
+      else if (strcmp (optarg, "combreloc") == 0)
+       link_info.combreloc = TRUE;
+      else if (strcmp (optarg, "nocombreloc") == 0)
+       link_info.combreloc = FALSE;
+      else if (strcmp (optarg, "nocopyreloc") == 0)
+       link_info.nocopyreloc = TRUE;
+      else if (strcmp (optarg, "execstack") == 0)
+       {
+         link_info.execstack = TRUE;
+         link_info.noexecstack = FALSE;
+       }
+      else if (strcmp (optarg, "noexecstack") == 0)
+       {
+         link_info.noexecstack = TRUE;
+         link_info.execstack = FALSE;
+       }
+      else if (strcmp (optarg, "relro") == 0)
+       link_info.relro = TRUE;
+      else if (strcmp (optarg, "norelro") == 0)
+       link_info.relro = FALSE;
       /* What about the other Solaris -z options? FIXME.  */
       break;
 EOF
@@ -1374,37 +1707,43 @@ fi
 cat >>e${EMULATION_NAME}.c <<EOF
     }
 
-  return 1;
+  return TRUE;
 }
 
 EOF
-fi
 
 if test x"$LDEMUL_LIST_OPTIONS" != xgld"$EMULATION_NAME"_list_options; then
 cat >>e${EMULATION_NAME}.c <<EOF
 
-static void gld${EMULATION_NAME}_list_options PARAMS ((FILE * file));
-
 static void
-gld${EMULATION_NAME}_list_options (file)
-     FILE * file;
+gld${EMULATION_NAME}_list_options (FILE * file)
 {
 EOF
 
 if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
 cat >>e${EMULATION_NAME}.c <<EOF
+  fprintf (file, _("  -Bgroup\t\tSelects group name lookup rules for DSO\n"));
   fprintf (file, _("  --disable-new-dtags\tDisable new dynamic tags\n"));
   fprintf (file, _("  --enable-new-dtags\tEnable new dynamic tags\n"));
-  fprintf (file, _("  -z initfirst\t\tMark DSO to be initialized first at rutime\n"));
-  fprintf (file, _("  -z interpose\t\tMark object to interpose all DSOs but execuable\n"));
+  fprintf (file, _("  --eh-frame-hdr\tCreate .eh_frame_hdr section\n"));
+  fprintf (file, _("  -z combreloc\t\tMerge dynamic relocs into one section and sort\n"));
+  fprintf (file, _("  -z defs\t\tReport unresolved symbols in object files.\n"));
+  fprintf (file, _("  -z execstack\t\tMark executable as requiring executable stack\n"));
+  fprintf (file, _("  -z initfirst\t\tMark DSO to be initialized first at runtime\n"));
+  fprintf (file, _("  -z interpose\t\tMark object to interpose all DSOs but executable\n"));
   fprintf (file, _("  -z loadfltr\t\tMark object requiring immediate process\n"));
+  fprintf (file, _("  -z muldefs\t\tAllow multiple definitions\n"));
+  fprintf (file, _("  -z nocombreloc\tDon't merge dynamic relocs into one section\n"));
+  fprintf (file, _("  -z nocopyreloc\tDon't create copy relocs\n"));
   fprintf (file, _("  -z nodefaultlib\tMark object not to use default search paths\n"));
   fprintf (file, _("  -z nodelete\t\tMark DSO non-deletable at runtime\n"));
-  fprintf (file, _("  -z nodlopen\t\tMark DSO not availale to dlopen\n"));
-  fprintf (file, _("  -z nodump\t\tMark DSO not availale to dldump\n"));
+  fprintf (file, _("  -z nodlopen\t\tMark DSO not available to dlopen\n"));
+  fprintf (file, _("  -z nodump\t\tMark DSO not available to dldump\n"));
+  fprintf (file, _("  -z noexecstack\tMark executable as not requiring executable stack\n"));
+  fprintf (file, _("  -z norelro\t\tDon't create RELRO program header\n"));
   fprintf (file, _("  -z now\t\tMark object non-lazy runtime binding\n"));
-  fprintf (file, _("  -z origin\t\tMark object requiring immediate \$ORIGIN processing\n"));
-  fprintf (file, _("\t\t\t  at runtime\n"));
+  fprintf (file, _("  -z origin\t\tMark object requiring immediate \$ORIGIN processing\n\t\t\t  at runtime\n"));
+  fprintf (file, _("  -z relro\t\tCreate RELRO program header\n"));
   fprintf (file, _("  -z KEYWORD\t\tIgnored for Solaris compatibility\n"));
 EOF
 fi
@@ -1426,11 +1765,10 @@ EOF
 fi
 fi
 else
-if test x"$LDEMUL_PARSE_ARGS" != xgld"$EMULATION_NAME"_parse_args; then
 cat >>e${EMULATION_NAME}.c <<EOF
-#define gld${EMULATION_NAME}_parse_args   NULL
+#define gld${EMULATION_NAME}_add_options NULL
+#define gld${EMULATION_NAME}_handle_option NULL
 EOF
-fi
 if test x"$LDEMUL_LIST_OPTIONS" != xgld"$EMULATION_NAME"_list_options; then
 cat >>e${EMULATION_NAME}.c <<EOF
 #define gld${EMULATION_NAME}_list_options NULL
@@ -1454,15 +1792,18 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
   ${LDEMUL_GET_SCRIPT-gld${EMULATION_NAME}_get_script},
   "${EMULATION_NAME}",
   "${OUTPUT_FORMAT}",
-  ${LDEMUL_FINISH-NULL},
+  ${LDEMUL_FINISH-gld${EMULATION_NAME}_finish},
   ${LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS-NULL},
   ${LDEMUL_OPEN_DYNAMIC_ARCHIVE-gld${EMULATION_NAME}_open_dynamic_archive},
   ${LDEMUL_PLACE_ORPHAN-gld${EMULATION_NAME}_place_orphan},
   ${LDEMUL_SET_SYMBOLS-NULL},
-  ${LDEMUL_PARSE_ARGS-gld${EMULATION_NAME}_parse_args},
+  ${LDEMUL_PARSE_ARGS-NULL},
+  gld${EMULATION_NAME}_add_options,
+  gld${EMULATION_NAME}_handle_option,
   ${LDEMUL_UNRECOGNIZED_FILE-NULL},
   ${LDEMUL_LIST_OPTIONS-gld${EMULATION_NAME}_list_options},
-  ${LDEMUL_RECOGNIZED_FILE-NULL},
+  ${LDEMUL_RECOGNIZED_FILE-gld${EMULATION_NAME}_load_symbols},
   ${LDEMUL_FIND_POTENTIAL_LIBRARIES-NULL},
+  ${LDEMUL_NEW_VERS_PATTERN-NULL}
 };
 EOF
This page took 0.047124 seconds and 4 git commands to generate.