# This shell script emits a C file. -*- C -*-
# It does some substitutions.
# 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
fragment <<EOF
/* This file is is generated by a shell script.  DO NOT EDIT! */

/* ${ELFSIZE} bit ELF emulation code for ${EMULATION_NAME}
   Copyright (C) 1991-2017 Free Software Foundation, Inc.
   Written by Steve Chamberlain <sac@cygnus.com>
   ELF support by Ian Lance Taylor <ian@cygnus.com>

   This file is part of the GNU Binutils.

   This program 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 3 of the License, or
   (at your option) any later version.

   This program 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 this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#define TARGET_IS_${EMULATION_NAME}

#include "sysdep.h"
#include "bfd.h"
#include "libiberty.h"
#include "safe-ctype.h"
#include "filenames.h"
#include "getopt.h"
#include <fcntl.h>

#include "bfdlink.h"

#include "ld.h"
#include "ldmain.h"
#include "ldmisc.h"
#include "ldexp.h"
#include "ldlang.h"
#include "ldfile.h"
#include "ldemul.h"
#include "ldbuildid.h"
#include <ldgram.h>
#include "elf/common.h"
#include "elf-bfd.h"
#include "filenames.h"

/* Declare functions used by various EXTRA_EM_FILEs.  */
static void gld${EMULATION_NAME}_before_parse (void);
static void gld${EMULATION_NAME}_after_parse (void);
static void gld${EMULATION_NAME}_after_open (void);
static void gld${EMULATION_NAME}_before_allocation (void);
static void gld${EMULATION_NAME}_after_allocation (void);
static lang_output_section_statement_type *gld${EMULATION_NAME}_place_orphan
  (asection *, const char *, int);
EOF

if [ "x${USE_LIBPATH}" = xyes ] ; then
  case ${target} in
    *-*-linux-* | *-*-k*bsd*-* | *-*-gnu*)
  fragment <<EOF
#ifdef HAVE_GLOB
#include <glob.h>
#endif
EOF
    ;;
  esac
fi

# Import any needed special functions and/or overrides.
#
source_em ${srcdir}/emultempl/elf-generic.em
if test -n "$EXTRA_EM_FILE" ; then
  source_em ${srcdir}/emultempl/${EXTRA_EM_FILE}.em
fi

# 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
# as presumably it is called from the overriding function.
#
if test x"$LDEMUL_BEFORE_PARSE" != xgld"$EMULATION_NAME"_before_parse; then
fragment <<EOF

static void
gld${EMULATION_NAME}_before_parse (void)
{
  ldfile_set_output_arch ("${OUTPUT_ARCH}", bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`);
  input_flags.dynamic = ${DYNAMIC_LINK-TRUE};
  config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo TRUE ; else echo FALSE ; fi`;
  config.separate_code = `if test "x${SEPARATE_CODE}" = xyes ; then echo TRUE ; else echo FALSE ; fi`;
  `if test -n "$CALL_NOP_BYTE" ; then echo link_info.call_nop_byte = $CALL_NOP_BYTE; fi`;
  link_info.check_relocs_after_open_input = `if test "x${CHECK_RELOCS_AFTER_OPEN_INPUT}" = xyes ; then echo TRUE ; else echo FALSE ; fi`;
  link_info.relro = DEFAULT_LD_Z_RELRO;
}

EOF
fi

if test x"$LDEMUL_AFTER_PARSE" != xgld"$EMULATION_NAME"_after_parse; then
fragment <<EOF

static void
gld${EMULATION_NAME}_after_parse (void)
{
  if (bfd_link_pie (&link_info))
    link_info.flags_1 |= (bfd_vma) DF_1_PIE;

  after_parse_default ();
}

EOF
fi

if test x"$LDEMUL_RECOGNIZED_FILE" != xgld"${EMULATION_NAME}"_load_symbols; then
fragment <<EOF
/* Handle the generation of DT_NEEDED tags.  */

static bfd_boolean
gld${EMULATION_NAME}_load_symbols (lang_input_statement_type *entry)
{
  int link_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->flags.add_DT_NEEDED_for_regular)
    link_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->flags.add_DT_NEEDED_for_dynamic)
    link_class |= DYN_NO_ADD_NEEDED;

  if (entry->flags.just_syms
      && (bfd_get_file_flags (entry->the_bfd) & DYNAMIC) != 0)
    einfo (_("%P%F: --just-symbols may not be used on DSO: %B\n"),
	   entry->the_bfd);

  if (link_class == 0
      || (bfd_get_file_flags (entry->the_bfd) & DYNAMIC) == 0)
    return FALSE;

  bfd_elf_set_dyn_lib_class (entry->the_bfd,
			     (enum dynamic_lib_link_class) link_class);

  /* Continue on with normal load_symbols processing.  */
  return FALSE;
}
EOF
fi

fragment <<EOF

/* These variables are required to pass information back and forth
   between after_open and check_needed and stat_needed and vercheck.  */

static struct bfd_link_needed_list *global_needed;
static struct stat global_stat;
static lang_input_statement_type *global_found;
static struct bfd_link_needed_list *global_vercheck_needed;
static bfd_boolean global_vercheck_failed;

/* These variables are used to implement target options */

static char *audit; /* colon (typically) separated list of libs */
static char *depaudit; /* colon (typically) separated list of libs */

/* Style of .note.gnu.build-id section.  */
static const char *emit_note_gnu_build_id;

/* On Linux, it's possible to have different versions of the same
   shared library linked against different versions of libc.  The
   dynamic linker somehow tags which libc version to use in
   /etc/ld.so.cache, and, based on the libc that it sees in the
   executable, chooses which version of the shared library to use.

   We try to do a similar check here by checking whether this shared
   library needs any other shared libraries which may conflict with
   libraries we have already included in the link.  If it does, we
   skip it, and try to find another shared library farther on down the
   link path.

   This is called via lang_for_each_input_file.
   GLOBAL_VERCHECK_NEEDED is the list of objects needed by the object
   which we are checking.  This sets GLOBAL_VERCHECK_FAILED if we find
   a conflicting version.  */

static void
gld${EMULATION_NAME}_vercheck (lang_input_statement_type *s)
{
  const char *soname;
  struct bfd_link_needed_list *l;

  if (global_vercheck_failed)
    return;
  if (s->the_bfd == NULL
      || (bfd_get_file_flags (s->the_bfd) & DYNAMIC) == 0)
    return;

  soname = bfd_elf_get_dt_soname (s->the_bfd);
  if (soname == NULL)
    soname = lbasename (bfd_get_filename (s->the_bfd));

  for (l = global_vercheck_needed; l != NULL; l = l->next)
    {
      const char *suffix;

      if (filename_cmp (soname, l->name) == 0)
	{
	  /* Probably can't happen, but it's an easy check.  */
	  continue;
	}

      if (strchr (l->name, '/') != NULL)
	continue;

      suffix = strstr (l->name, ".so.");
      if (suffix == NULL)
	continue;

      suffix += sizeof ".so." - 1;

      if (filename_ncmp (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;
	  return;
	}
    }
}


/* See if an input file matches a DT_NEEDED entry by running stat on
   the file.  */

static void
gld${EMULATION_NAME}_stat_needed (lang_input_statement_type *s)
{
  struct stat st;
  const char *suffix;
  const char *soname;

  if (global_found != NULL)
    return;
  if (s->the_bfd == NULL)
    return;

  /* If this input file was an as-needed entry, and wasn't found to be
     needed at the stage it was linked, then don't say we have loaded it.  */
  if ((bfd_elf_get_dyn_lib_class (s->the_bfd) & DYN_AS_NEEDED) != 0)
    return;

  if (bfd_stat (s->the_bfd, &st) != 0)
    {
      einfo ("%P:%B: bfd_stat failed: %E\n", s->the_bfd);
      return;
    }

  /* Some operating systems, e.g. Windows, do not provide a meaningful
     st_ino; they always set it to zero.  (Windows does provide a
     meaningful st_dev.)  Do not indicate a duplicate library in that
     case.  While there is no guarantee that a system that provides
     meaningful inode numbers will never set st_ino to zero, this is
     merely an optimization, so we do not need to worry about false
     negatives.  */
  if (st.st_dev == global_stat.st_dev
      && st.st_ino == global_stat.st_ino
      && st.st_ino != 0)
    {
      global_found = s;
      return;
    }

  /* We issue a warning if it looks like we are including two
     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
     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.  */

  if (strchr (global_needed->name, '/') != NULL)
    return;
  suffix = strstr (global_needed->name, ".so.");
  if (suffix == NULL)
    return;
  suffix += sizeof ".so." - 1;

  soname = bfd_elf_get_dt_soname (s->the_bfd);
  if (soname == NULL)
    soname = lbasename (s->filename);

  if (filename_ncmp (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, 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 bfd_boolean
gld${EMULATION_NAME}_try_needed (struct dt_needed *needed,
				 int force)
{
  bfd *abfd;
  const char *name = needed->name;
  const char *soname;
  int link_class;

  abfd = bfd_openr (name, bfd_get_target (link_info.output_bfd));
  if (abfd == NULL)
    {
      if (verbose)
	info_msg (_("attempt to open %s failed\n"), name);
      return FALSE;
    }

  /* Linker needs to decompress sections.  */
  abfd->flags |= BFD_DECOMPRESS;

  if (! bfd_check_format (abfd, bfd_object))
    {
      bfd_close (abfd);
      return FALSE;
    }
  if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0)
    {
      bfd_close (abfd);
      return FALSE;
    }

  /* For DT_NEEDED, they have to match.  */
  if (abfd->xvec != link_info.output_bfd->xvec)
    {
      bfd_close (abfd);
      return FALSE;
    }

  /* Check whether this object would include any conflicting library
     versions.  If FORCE is set, then we skip this check; we use this
     the second time around, if we couldn't find any compatible
     instance of the shared library.  */

  if (! force)
    {
      struct bfd_link_needed_list *needs;

      if (! bfd_elf_get_bfd_needed_list (abfd, &needs))
	einfo ("%F%P:%B: bfd_elf_get_bfd_needed_list failed: %E\n", abfd);

      if (needs != NULL)
	{
	  global_vercheck_needed = needs;
	  global_vercheck_failed = FALSE;
	  lang_for_each_input_file (gld${EMULATION_NAME}_vercheck);
	  if (global_vercheck_failed)
	    {
	      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.  */

EOF
case ${target} in
  *-*-linux-* | *-*-k*bsd*-* | *-*-gnu*)
    fragment <<EOF
	  {
	    struct bfd_link_needed_list *l;

	    for (l = needs; l != NULL; l = l->next)
	      if (CONST_STRNEQ (l->name, "libc.so"))
		break;
	    if (l == NULL)
	      {
		bfd_close (abfd);
		return FALSE;
	      }
	  }

EOF
    ;;
esac
fragment <<EOF
	}
    }

  /* We've found a dynamic object matching the DT_NEEDED entry.  */

  /* We have already checked that there is no other input file of the
     same name.  We must now check again that we are not including the
     same file twice.  We need to do this because on many systems
     libc.so is a symlink to, e.g., libc.so.1.  The SONAME entry will
     reference libc.so.1.  If we have already included libc.so, we
     don't want to include libc.so.1 if they are the same file, and we
     can only check that using stat.  */

  if (bfd_stat (abfd, &global_stat) != 0)
    einfo ("%F%P:%B: bfd_stat failed: %E\n", abfd);

  /* First strip off everything before the last '/'.  */
  soname = lbasename (abfd->filename);

  if (verbose)
    info_msg (_("found %s at %s\n"), soname, name);

  global_found = NULL;
  lang_for_each_input_file (gld${EMULATION_NAME}_stat_needed);
  if (global_found != NULL)
    {
      /* Return TRUE to indicate that we found the file, even though
	 we aren't going to do anything with it.  */
      return TRUE;
    }

  /* Specify the soname to use.  */
  bfd_elf_set_dt_needed_name (abfd, soname);

  /* 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.  */
  link_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 != NULL
      && (bfd_elf_get_dyn_lib_class (needed->by) & DYN_NO_ADD_NEEDED) != 0)
    link_class |= DYN_NO_NEEDED | DYN_NO_ADD_NEEDED;

  bfd_elf_set_dyn_lib_class (abfd, (enum dynamic_lib_link_class) link_class);

  /* Add this file into the symbol table.  */
  if (! bfd_link_add_symbols (abfd, &link_info))
    einfo ("%F%B: error adding symbols: %E\n", abfd);

  return TRUE;
}

/* Search for a needed file in a path.  */

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;

  needed.by = n->by;
  needed.name = n->name;

  len = strlen (name);
  while (1)
    {
      unsigned offset = 0;
      char * var;
      char *filename, *sset;

      s = strchr (path, config.rpath_separator);
      if (s == NULL)
	s = path + strlen (path);

#if HAVE_DOS_BASED_FILE_SYSTEM
      /* Assume a match on the second char is part of drive specifier.  */
      else if (config.rpath_separator == ':'
	       && s == path + 1
	       && ISALPHA (*path))
	{
	  s = strchr (s + 1, config.rpath_separator);
	  if (s == NULL)
	    s = path + strlen (path);
	}
#endif
      filename = (char *) xmalloc (s - path + len + 2);
      if (s == path)
	sset = filename;
      else
	{
	  memcpy (filename, path, s - path);
	  filename[s - path] = '/';
	  sset = filename + (s - path) + 1;
	}
      strcpy (sset, name);

      /* PR 20535: Support the same pseudo-environment variables that
	 are supported by ld.so.  Namely, $ORIGIN, $LIB and $PLATFORM.
         Since there can be more than one occurrence of these tokens in
	 the path we loop until no more are found.  Since we might not
	 be able to substitute some of the tokens we maintain an offset
	 into the filename for where we should begin our scan.  */
      while ((var = strchr (filename + offset, '$')) != NULL)
	{
	  /* The ld.so manual page does not say, but I am going to assume that
	     these tokens are terminated by a directory separator character
	     (/) or the end of the string.  There is also an implication that
	     $ORIGIN should only be used at the start of a path, but that is
	     not enforced here.

	     The ld.so manual page also states that it allows ${ORIGIN},
	     ${LIB} and ${PLATFORM}, so these are supported as well.

	     FIXME: The code could be a lot cleverer about allocating space
	     for the processed string.  */
	  char *    end = strchr (var, '/');
	  char *    replacement = NULL;
	  char *    v = var + 1;
	  char *    freeme = NULL;
	  unsigned  flen = strlen (filename);

	  if (end != NULL)
	    /* Temporarily terminate the filename at the end of the token.  */
	    * end = 0;

	  if (*v == '{')
	    ++ v;
	  switch (*v++)
	    {
	    case 'O':
	      if (strcmp (v, "RIGIN") == 0 || strcmp (v, "RIGIN}") == 0)
		{
		  /* ORIGIN - replace with the full path to the directory
		     containing the program or shared object.  */
		  if (needed.by == NULL)
		    {
		      if (link_info.output_bfd == NULL)
			{
			  break;
			}
		      else
			replacement = bfd_get_filename (link_info.output_bfd);
		    }
		  else
		    replacement = bfd_get_filename (needed.by);

		  if (replacement)
		    {
		      char * slash;

		      if (replacement[0] == '/')
			freeme = xstrdup (replacement);
		      else
			{
			  char * current_dir = getpwd ();

			  freeme = xmalloc (strlen (replacement) + strlen (current_dir) + 2);
			  sprintf (freeme, "%s/%s", current_dir, replacement);
			}

		      replacement = freeme;
		      if ((slash = strrchr (replacement, '/')) != NULL)
			* slash = 0;
		    }
		}
	      break;

	    case 'L':
	      if (strcmp (v, "IB") == 0 || strcmp (v, "IB}") == 0)
		{
		  /* LIB - replace with "lib" in 32-bit environments
		     and "lib64" in 64-bit environments.  */

		  /* Note - we could replace this switch statement by
		     conditional fragments of shell script, but that is messy.
		     Any compiler worth its salt is going to optimize away
		     all but one of these case statements anyway.  */
		  switch ($ELFSIZE)
		    {
		    case 32: replacement = "lib"; break;
		    case 64: replacement = "lib64"; break;
		    default:
		      /* $ELFSIZE is not 32 or 64 ...  */
		      abort ();
		    }
		}
	      break;

	    case 'P':
	      /* Supporting $PLATFORM in a cross-hosted environment is not
		 possible.  Supporting it in a native environment involves
		 loading the <sys/auxv.h> header file which loads the
		 system <elf.h> header file, which conflicts with the
		 "include/elf/mips.h" header file.  */
	      /* Fall through.  */
	    default:
	      break;
	    }

	  if (replacement)
	    {
	      char * filename2 = xmalloc (flen + strlen (replacement));

	      if (end)
		{
		  sprintf (filename2, "%.*s%s/%s",
			   (int)(var - filename), filename,
			   replacement, end + 1);
		  offset = (var - filename) + 1 + strlen (replacement);
		}
	      else
		{
		  sprintf (filename2, "%.*s%s",
			   (int)(var - filename), filename,
			   replacement);
		  offset = var - filename + strlen (replacement);
		}

	      free (filename);
	      filename = filename2;
	      /* There is no need to restore the path separator (when
		 end != NULL) as we have replaced the entire string.  */
	    }
	  else
	    {
	      if (verbose)
		/* We only issue an "unrecognised" message in verbose mode
		   as the $<foo> token might be a legitimate component of
		   a path name in the target's file system.  */
		info_msg (_("unrecognised or unsupported token '%s' in search path\n"), var);

	      if (end)
		/* Restore the path separator.  */
		* end = '/';

	      /* PR 20784: Make sure that we resume the scan
	         *after* the token that we could not replace.  */
	      offset = (var + 1) - filename;
	    }

	  free (freeme);
	}

      needed.name = filename;

      if (gld${EMULATION_NAME}_try_needed (&needed, force))
	return TRUE;

      free (filename);

      if (*s == '\0')
	break;
      path = s + 1;
    }

  return FALSE;
}

EOF
if [ "x${USE_LIBPATH}" = xyes ] ; then
  fragment <<EOF

/* Prefix the sysroot to absolute paths in PATH, a string containing
   paths separated by config.rpath_separator.  If running on a DOS
   file system, paths containing a drive spec won't have the sysroot
   prefix added, unless the sysroot also specifies the same drive.  */

static const char *
gld${EMULATION_NAME}_add_sysroot (const char *path)
{
  size_t len, extra;
  const char *p;
  char *ret, *q;
  int dos_drive_sysroot = HAS_DRIVE_SPEC (ld_sysroot);

  len = strlen (ld_sysroot);
  for (extra = 0, p = path; ; )
    {
      int dos_drive = HAS_DRIVE_SPEC (p);

      if (dos_drive)
	p += 2;
      if (IS_DIR_SEPARATOR (*p)
	  && (!dos_drive
	      || (dos_drive_sysroot
		  && ld_sysroot[0] == p[-2])))
	{
	  if (dos_drive && dos_drive_sysroot)
	    extra += len - 2;
	  else
	    extra += len;
	}
      p = strchr (p, config.rpath_separator);
      if (!p)
	break;
      ++p;
    }

  ret = xmalloc (strlen (path) + extra + 1);

  for (q = ret, p = path; ; )
    {
      const char *end;
      int dos_drive = HAS_DRIVE_SPEC (p);

      if (dos_drive)
	{
	  *q++ = *p++;
	  *q++ = *p++;
	}
      if (IS_DIR_SEPARATOR (*p)
	  && (!dos_drive
	      || (dos_drive_sysroot
		  && ld_sysroot[0] == p[-2])))
	{
	  if (dos_drive && dos_drive_sysroot)
	    {
	      strcpy (q, ld_sysroot + 2);
	      q += len - 2;
	    }
	  else
	    {
	      strcpy (q, ld_sysroot);
	      q += len;
	    }
	}
      end = strchr (p, config.rpath_separator);
      if (end)
	{
	  size_t n = end - p + 1;
	  strncpy (q, p, n);
	  q += n;
	  p += n;
	}
      else
	{
	  strcpy (q, p);
	  break;
	}
    }

  return ret;
}

EOF
  case ${target} in
    *-*-freebsd* | *-*-dragonfly*)
      fragment <<EOF
/* Read the system search path the FreeBSD way rather than the Linux way.  */
#ifdef HAVE_ELF_HINTS_H
#include <elf-hints.h>
#else
#include "elf-hints-local.h"
#endif

static bfd_boolean
gld${EMULATION_NAME}_check_ld_elf_hints (const struct bfd_link_needed_list *l,
					 int force)
{
  static bfd_boolean initialized;
  static const char *ld_elf_hints;
  struct dt_needed needed;

  if (!initialized)
    {
      FILE *f;
      char *tmppath;

      tmppath = concat (ld_sysroot, _PATH_ELF_HINTS, (const char *) NULL);
      f = fopen (tmppath, FOPEN_RB);
      free (tmppath);
      if (f != NULL)
	{
	  struct elfhints_hdr hdr;

	  if (fread (&hdr, 1, sizeof (hdr), f) == sizeof (hdr)
	      && hdr.magic == ELFHINTS_MAGIC
	      && hdr.version == 1)
	    {
	      if (fseek (f, hdr.strtab + hdr.dirlist, SEEK_SET) != -1)
		{
		  char *b;

		  b = xmalloc (hdr.dirlistlen + 1);
		  if (fread (b, 1, hdr.dirlistlen + 1, f) ==
		      hdr.dirlistlen + 1)
		    ld_elf_hints = gld${EMULATION_NAME}_add_sysroot (b);

		  free (b);
		}
	    }
	  fclose (f);
	}

      initialized = TRUE;
    }

  if (ld_elf_hints == NULL)
    return FALSE;

  needed.by = l->by;
  needed.name = l->name;
  return gld${EMULATION_NAME}_search_needed (ld_elf_hints, &needed, force);
}
EOF
    # FreeBSD
    ;;

    *-*-linux-* | *-*-k*bsd*-* | *-*-gnu*)
      fragment <<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.  */

struct gld${EMULATION_NAME}_ld_so_conf
{
  char *path;
  size_t len, alloc;
};

static bfd_boolean
gld${EMULATION_NAME}_parse_ld_so_conf
     (struct gld${EMULATION_NAME}_ld_so_conf *info, const char *filename);

static void
gld${EMULATION_NAME}_parse_ld_so_conf_include
     (struct gld${EMULATION_NAME}_ld_so_conf *info, const char *filename,
      const char *pattern)
{
  char *newp = NULL;
#ifdef HAVE_GLOB
  glob_t gl;
#endif

  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;
    }

#ifdef HAVE_GLOB
  if (glob (pattern, 0, NULL, &gl) == 0)
    {
      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);
    }
#else
  /* If we do not have glob, treat the pattern as a literal filename.  */
  gld${EMULATION_NAME}_parse_ld_so_conf (info, pattern);
#endif

  if (newp)
    free (newp);
}

static bfd_boolean
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 FALSE;

  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')
	{
	  line = xrealloc (line, 2 * linelen);
	  p = line + linelen - 1;
	  linelen += linelen;
	}

      if (q == NULL && p == line)
	break;

      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;

      if (CONST_STRNEQ (p, "include") && (p[7] == ' ' || p[7] == '\t'))
	{
	  char *dir, c;
	  p += 8;
	  do
	    {
	      while (*p == ' ' || *p == '\t')
		++p;

	      if (*p == '\0')
		break;

	      dir = p;

	      while (*p != ' ' && *p != '\t' && *p)
		++p;

	      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
	    {
	      if (info->len + 1 + (p - dir) >= info->alloc)
		{
		  info->alloc += p - dir + 256;
		  info->path = xrealloc (info->path, info->alloc);
		}
	      info->path[info->len++] = config.rpath_separator;
	    }
	  memcpy (info->path + info->len, dir, p - dir);
	  info->len += p - dir;
	  info->path[info->len] = '\0';
	}
    }
  while (! feof (f));
  free (line);
  fclose (f);
  return TRUE;
}

static bfd_boolean
gld${EMULATION_NAME}_check_ld_so_conf (const struct bfd_link_needed_list *l,
				       int force)
{
  static bfd_boolean initialized;
  static const char *ld_so_conf;
  struct dt_needed needed;

  if (! initialized)
    {
      char *tmppath;
      struct gld${EMULATION_NAME}_ld_so_conf info;

      info.path = NULL;
      info.len = info.alloc = 0;
      tmppath = concat (ld_sysroot, "${prefix}/etc/ld.so.conf",
			(const char *) NULL);
      if (!gld${EMULATION_NAME}_parse_ld_so_conf (&info, tmppath))
	{
	  free (tmppath);
	  tmppath = concat (ld_sysroot, "/etc/ld.so.conf",
			    (const char *) NULL);
	  gld${EMULATION_NAME}_parse_ld_so_conf (&info, tmppath);
	}
      free (tmppath);

      if (info.path)
	{
	  ld_so_conf = gld${EMULATION_NAME}_add_sysroot (info.path);
	  free (info.path);
	}
      initialized = TRUE;
    }

  if (ld_so_conf == NULL)
    return FALSE;


  needed.by = l->by;
  needed.name = l->name;
  return gld${EMULATION_NAME}_search_needed (ld_so_conf, &needed, force);
}

EOF
    # Linux
    ;;
  esac
fi
fragment <<EOF

/* See if an input file matches a DT_NEEDED entry by name.  */

static void
gld${EMULATION_NAME}_check_needed (lang_input_statement_type *s)
{
  const char *soname;

  /* Stop looking if we've found a loaded lib.  */
  if (global_found != NULL
      && (bfd_elf_get_dyn_lib_class (global_found->the_bfd)
	  & DYN_AS_NEEDED) == 0)
    return;

  if (s->filename == NULL || s->the_bfd == NULL)
    return;

  /* Don't look for a second non-loaded as-needed lib.  */
  if (global_found != NULL
      && (bfd_elf_get_dyn_lib_class (s->the_bfd) & DYN_AS_NEEDED) != 0)
    return;

  if (filename_cmp (s->filename, global_needed->name) == 0)
    {
      global_found = s;
      return;
    }

  if (s->flags.search_dirs)
    {
      const char *f = strrchr (s->filename, '/');
      if (f != NULL
	  && filename_cmp (f + 1, global_needed->name) == 0)
	{
	  global_found = s;
	  return;
	}
    }

  soname = bfd_elf_get_dt_soname (s->the_bfd);
  if (soname != NULL
      && filename_cmp (soname, global_needed->name) == 0)
    {
      global_found = s;
      return;
    }
}

EOF

if test x"$LDEMUL_AFTER_OPEN" != xgld"$EMULATION_NAME"_after_open; then
fragment <<EOF

static bfd_size_type
id_note_section_size (bfd *abfd ATTRIBUTE_UNUSED)
{
  const char *style = emit_note_gnu_build_id;
  bfd_size_type size;
  bfd_size_type build_id_size;

  size = offsetof (Elf_External_Note, name[sizeof "GNU"]);
  size = (size + 3) & -(bfd_size_type) 4;

  build_id_size = compute_build_id_size (style);
  if (build_id_size)
    size += build_id_size;
  else
    size = 0;

  return size;
}

static bfd_boolean
write_build_id (bfd *abfd)
{
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  struct elf_obj_tdata *t = elf_tdata (abfd);
  const char *style;
  asection *asec;
  Elf_Internal_Shdr *i_shdr;
  unsigned char *contents, *id_bits;
  bfd_size_type size;
  file_ptr position;
  Elf_External_Note *e_note;

  style = t->o->build_id.style;
  asec = t->o->build_id.sec;
  if (bfd_is_abs_section (asec->output_section))
    {
      einfo (_("%P: warning: .note.gnu.build-id section discarded,"
	       " --build-id ignored.\n"));
      return TRUE;
    }
  i_shdr = &elf_section_data (asec->output_section)->this_hdr;

  if (i_shdr->contents == NULL)
    {
      if (asec->contents == NULL)
	asec->contents = (unsigned char *) xmalloc (asec->size);
      contents = asec->contents;
    }
  else
    contents = i_shdr->contents + asec->output_offset;

  e_note = (Elf_External_Note *) contents;
  size = offsetof (Elf_External_Note, name[sizeof "GNU"]);
  size = (size + 3) & -(bfd_size_type) 4;
  id_bits = contents + size;
  size = asec->size - size;

  bfd_h_put_32 (abfd, sizeof "GNU", &e_note->namesz);
  bfd_h_put_32 (abfd, size, &e_note->descsz);
  bfd_h_put_32 (abfd, NT_GNU_BUILD_ID, &e_note->type);
  memcpy (e_note->name, "GNU", sizeof "GNU");

  generate_build_id (abfd, style, bed->s->checksum_contents, id_bits, size);

  position = i_shdr->sh_offset + asec->output_offset;
  size = asec->size;
  return (bfd_seek (abfd, position, SEEK_SET) == 0
	  && bfd_bwrite (contents, size, abfd) == size);
}

/* Make .note.gnu.build-id section, and set up elf_tdata->build_id.  */

static bfd_boolean
setup_build_id (bfd *ibfd)
{
  asection *s;
  bfd_size_type size;
  flagword flags;

  size = id_note_section_size (ibfd);
  if (size == 0)
    {
      einfo ("%P: warning: unrecognized --build-id style ignored.\n");
      return FALSE;
    }

  flags = (SEC_ALLOC | SEC_LOAD | SEC_IN_MEMORY
	   | SEC_LINKER_CREATED | SEC_READONLY | SEC_DATA);
  s = bfd_make_section_with_flags (ibfd, ".note.gnu.build-id", flags);
  if (s != NULL && bfd_set_section_alignment (ibfd, s, 2))
    {
      struct elf_obj_tdata *t = elf_tdata (link_info.output_bfd);
      t->o->build_id.after_write_object_contents = &write_build_id;
      t->o->build_id.style = emit_note_gnu_build_id;
      t->o->build_id.sec = s;
      elf_section_type (s) = SHT_NOTE;
      s->size = size;
      return TRUE;
    }

  einfo ("%P: warning: Cannot create .note.gnu.build-id section,"
	 " --build-id ignored.\n");
  return FALSE;
}

/* This is called after all the input files have been opened.  */

static void
gld${EMULATION_NAME}_after_open (void)
{
  struct bfd_link_needed_list *needed, *l;
  struct elf_link_hash_table *htab;

  after_open_default ();

  htab = elf_hash_table (&link_info);
  if (!is_elf_hash_table (htab))
    return;

  if (command_line.out_implib_filename)
    {
      unlink_if_ordinary (command_line.out_implib_filename);
      link_info.out_implib_bfd
	= bfd_openw (command_line.out_implib_filename,
		     bfd_get_target (link_info.output_bfd));

      if (link_info.out_implib_bfd == NULL)
	{
	  einfo ("%F%s: Can't open for writing: %E\n",
		 command_line.out_implib_filename);
	}
    }

  if (emit_note_gnu_build_id != NULL)
    {
      bfd *abfd;

      /* Find an ELF input.  */
      for (abfd = link_info.input_bfds;
	   abfd != (bfd *) NULL; abfd = abfd->link.next)
	if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
	    && bfd_count_sections (abfd) != 0)
	  break;

      /* PR 10555: If there are no ELF input files do not try to
	 create a .note.gnu-build-id section.  */
      if (abfd == NULL
	  || !setup_build_id (abfd))
	{
	  free ((char *) emit_note_gnu_build_id);
	  emit_note_gnu_build_id = NULL;
	}
    }

  get_elf_backend_data (link_info.output_bfd)->setup_gnu_properties (&link_info);

  if (bfd_link_relocatable (&link_info))
    {
      if (link_info.execstack == ! link_info.noexecstack)
	/* PR ld/16744: If "-z [no]execstack" has been specified on the
	   command line and we are perfoming a relocatable link then no
	   PT_GNU_STACK segment will be created and so the
	   linkinfo.[no]execstack values set in _handle_option() will have no
	   effect.  Instead we create a .note.GNU-stack section in much the
	   same way as the assembler does with its --[no]execstack option.  */
	(void) bfd_make_section_with_flags (link_info.input_bfds,
					    ".note.GNU-stack",
					    SEC_READONLY | (link_info.execstack ? SEC_CODE : 0));

      return;
    }

  if (!link_info.traditional_format)
    {
      bfd *abfd, *elfbfd = NULL;
      bfd_boolean warn_eh_frame = FALSE;
      asection *s;
      int seen_type = 0;

      for (abfd = link_info.input_bfds; abfd; abfd = abfd->link.next)
	{
	  int type = 0;
	  for (s = abfd->sections; s && type < COMPACT_EH_HDR; s = s->next)
	    {
	      const char *name = bfd_get_section_name (abfd, s);

	      if (bfd_is_abs_section (s->output_section))
		continue;
	      if (CONST_STRNEQ (name, ".eh_frame_entry"))
		type = COMPACT_EH_HDR;
	      else if (strcmp (name, ".eh_frame") == 0 && s->size > 8)
		type = DWARF2_EH_HDR;
	    }

	  if (type != 0)
	    {
	      if (seen_type == 0)
		{
		  seen_type = type;
		}
	      else if (seen_type != type)
		{
		  einfo (_("%P%F: compact frame descriptions incompatible with"
			 " DWARF2 .eh_frame from %B\n"),
			 type == DWARF2_EH_HDR ? abfd : elfbfd);
		  break;
		}

	      if (!elfbfd
		  && (type == COMPACT_EH_HDR || link_info.eh_frame_hdr_type != 0))
		{
		  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
		    elfbfd = abfd;

		  warn_eh_frame = TRUE;
		}
	    }

	  if (seen_type == COMPACT_EH_HDR)
	    link_info.eh_frame_hdr_type = COMPACT_EH_HDR;

	  if (bfd_count_sections (abfd) == 0)
	    continue;
	}
      if (elfbfd)
	{
	  const struct elf_backend_data *bed;

	  bed = get_elf_backend_data (elfbfd);
	  s = bfd_make_section_with_flags (elfbfd, ".eh_frame_hdr",
					   bed->dynamic_sec_flags
					   | SEC_READONLY);
	  if (s != NULL
	      && bfd_set_section_alignment (elfbfd, s, 2))
	    {
	      htab->eh_info.hdr_sec = s;
	      warn_eh_frame = FALSE;
	    }
	}
      if (warn_eh_frame)
	einfo ("%P: warning: Cannot create .eh_frame_hdr section,"
	       " --eh-frame-hdr ignored.\n");
    }

  /* Get the list of files which appear in DT_NEEDED entries in
     dynamic objects included in the link (often there will be none).
     For each such file, we want to track down the corresponding
     library, and include the symbol table in the link.  This is what
     the runtime dynamic linker will do.  Tracking the files down here
     permits one dynamic object to include another without requiring
     special action by the person doing the link.  Note that the
     needed list can actually grow while we are stepping through this
     loop.  */
  needed = bfd_elf_get_needed_list (link_info.output_bfd, &link_info);
  for (l = needed; l != NULL; l = l->next)
    {
      struct bfd_link_needed_list *ll;
      struct dt_needed n, nn;
      int force;

      /* If the lib that needs this one was --as-needed and wasn't
	 found to be needed, then this lib isn't needed either.  */
      if (l->by != NULL
	  && (bfd_elf_get_dyn_lib_class (l->by) & DYN_AS_NEEDED) != 0)
	continue;

      /* Skip the lib if --no-copy-dt-needed-entries and
	 --allow-shlib-undefined is in effect.  */
      if (l->by != NULL
	  && link_info.unresolved_syms_in_shared_libs == RM_IGNORE
	  && (bfd_elf_get_dyn_lib_class (l->by) & DYN_NO_ADD_NEEDED) != 0)
	continue;

      /* If we've already seen this file, skip it.  */
      for (ll = needed; ll != l; ll = ll->next)
	if ((ll->by == NULL
	     || (bfd_elf_get_dyn_lib_class (ll->by) & DYN_AS_NEEDED) == 0)
	    && strcmp (ll->name, l->name) == 0)
	  break;
      if (ll != l)
	continue;

      /* See if this file was included in the link explicitly.  */
      global_needed = l;
      global_found = NULL;
      lang_for_each_input_file (gld${EMULATION_NAME}_check_needed);
      if (global_found != NULL
	  && (bfd_elf_get_dyn_lib_class (global_found->the_bfd)
	      & DYN_AS_NEEDED) == 0)
	continue;

      n.by = l->by;
      n.name = l->name;
      nn.by = l->by;
      if (verbose)
	info_msg (_("%s needed by %B\n"), l->name, l->by);

      /* As-needed libs specified on the command line (or linker script)
	 take priority over libs found in search dirs.  */
      if (global_found != NULL)
	{
	  nn.name = global_found->filename;
	  if (gld${EMULATION_NAME}_try_needed (&nn, TRUE))
	    continue;
	}

      /* 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 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++)
	{
	  size_t len;
	  search_dirs_type *search;
EOF
if [ "x${NATIVE}" = xyes ] || [ "x${USE_LIBPATH}" = xyes ] ; then
fragment <<EOF
	  const char *path;
EOF
fi
if [ "x${USE_LIBPATH}" = xyes ] ; then
fragment <<EOF
	  struct bfd_link_needed_list *rp;
	  int found;
EOF
fi
fragment <<EOF

	  if (gld${EMULATION_NAME}_search_needed (command_line.rpath_link,
						  &n, force))
	    break;
EOF
if [ "x${USE_LIBPATH}" = xyes ] ; then
fragment <<EOF
	  path = command_line.rpath;
	  if (path)
	    {
	      path = gld${EMULATION_NAME}_add_sysroot (path);
	      found = gld${EMULATION_NAME}_search_needed (path, &n, force);
	      free ((char *) path);
	      if (found)
		break;
	    }
EOF
fi
if [ "x${NATIVE}" = xyes ] ; then
fragment <<EOF
	  if (command_line.rpath_link == NULL
	      && command_line.rpath == NULL)
	    {
	      path = (const char *) getenv ("LD_RUN_PATH");
	      if (path
		  && gld${EMULATION_NAME}_search_needed (path, &n, force))
		break;
	    }
	  path = (const char *) getenv ("LD_LIBRARY_PATH");
	  if (path
	      && gld${EMULATION_NAME}_search_needed (path, &n, force))
	    break;
EOF
fi
if [ "x${USE_LIBPATH}" = xyes ] ; then
fragment <<EOF
	  found = 0;
	  rp = bfd_elf_get_runpath_list (link_info.output_bfd, &link_info);
	  for (; !found && rp != NULL; rp = rp->next)
	    {
	      path = gld${EMULATION_NAME}_add_sysroot (rp->name);
	      found = (rp->by == l->by
		       && gld${EMULATION_NAME}_search_needed (path, &n,
							      force));
	      free ((char *) path);
	    }
	  if (found)
	    break;

EOF
fi
if [ "x${USE_LIBPATH}" = xyes ] ; then
  case ${target} in
    *-*-freebsd* | *-*-dragonfly*)
      fragment <<EOF
	  if (gld${EMULATION_NAME}_check_ld_elf_hints (l, force))
	    break;
EOF
    # FreeBSD
    ;;

    *-*-linux-* | *-*-k*bsd*-* | *-*-gnu*)
      fragment <<EOF
	  if (gld${EMULATION_NAME}_check_ld_so_conf (l, force))
	    break;

EOF
    # Linux
    ;;
  esac
fi
fragment <<EOF
	  len = strlen (l->name);
	  for (search = search_head; search != NULL; search = search->next)
	    {
	      char *filename;

	      if (search->cmdline)
		continue;
	      filename = (char *) xmalloc (strlen (search->name) + len + 2);
	      sprintf (filename, "%s/%s", search->name, l->name);
	      nn.name = filename;
	      if (gld${EMULATION_NAME}_try_needed (&nn, force))
		break;
	      free (filename);
	    }
	  if (search != NULL)
	    break;
EOF
fragment <<EOF
	}

      if (force < 2)
	continue;

      einfo ("%P: warning: %s, needed by %B, not found (try using -rpath or -rpath-link)\n",
	     l->name, l->by);
    }

  if (link_info.eh_frame_hdr_type == COMPACT_EH_HDR)
    if (bfd_elf_parse_eh_frame_entries (NULL, &link_info) == FALSE)
      einfo (_("%P%F: Failed to parse EH frame entries.\n"));
}

EOF
fi

fragment <<EOF

/* Look through an expression for an assignment statement.  */

static void
gld${EMULATION_NAME}_find_exp_assignment (etree_type *exp)
{
  bfd_boolean provide = FALSE;

  switch (exp->type.node_class)
    {
    case etree_provide:
    case etree_provided:
      provide = TRUE;
      /* Fallthru */
    case etree_assign:
      /* We call record_link_assignment even if the symbol is defined.
	 This is because if it is defined by a dynamic object, we
	 actually want to use the value defined by the linker script,
	 not the value from the dynamic object (because we are setting
	 symbols like etext).  If the symbol is defined by a regular
	 object, then, as it happens, calling record_link_assignment
	 will do no harm.  */
      if (strcmp (exp->assign.dst, ".") != 0)
	{
	  if (!bfd_elf_record_link_assignment (link_info.output_bfd,
					       &link_info,
					       exp->assign.dst, provide,
					       exp->assign.hidden))
	    einfo ("%P%F: failed to record assignment to %s: %E\n",
		   exp->assign.dst);
	}
      gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src);
      break;

    case etree_binary:
      gld${EMULATION_NAME}_find_exp_assignment (exp->binary.lhs);
      gld${EMULATION_NAME}_find_exp_assignment (exp->binary.rhs);
      break;

    case etree_trinary:
      gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.cond);
      gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs);
      gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs);
      break;

    case etree_unary:
      gld${EMULATION_NAME}_find_exp_assignment (exp->unary.child);
      break;

    default:
      break;
    }
}


/* This is called by the before_allocation routine via
   lang_for_each_statement.  It locates any assignment statements, and
   tells the ELF backend about them, in case they are assignments to
   symbols which are referred to by dynamic objects.  */

static void
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);
}

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 = (unsigned char *) ${ELF_INTERPRETER_NAME};
      sinterp->size = strlen ((char *) sinterp->contents) + 1;
    }

"
  else
    ELF_INTERPRETER_SET_DEFAULT=
  fi
fragment <<EOF

/* used by before_allocation and handle_option. */
static void
gld${EMULATION_NAME}_append_to_separated_string (char **to, char *op_arg)
{
  if (*to == NULL)
    *to = xstrdup (op_arg);
  else
    {
      size_t to_len = strlen (*to);
      size_t op_arg_len = strlen (op_arg);
      char *buf;
      char *cp = *to;

      /* First see whether OPTARG is already in the path.  */
      do
	{
	  if (strncmp (op_arg, cp, op_arg_len) == 0
	      && (cp[op_arg_len] == 0
		  || cp[op_arg_len] == config.rpath_separator))
	    /* We found it.  */
	    break;

	  /* Not yet found.  */
	  cp = strchr (cp, config.rpath_separator);
	  if (cp != NULL)
	    ++cp;
	}
      while (cp != NULL);

      if (cp == NULL)
	{
	  buf = xmalloc (to_len + op_arg_len + 2);
	  sprintf (buf, "%s%c%s", *to,
		   config.rpath_separator, op_arg);
	  free (*to);
	  *to = buf;
	}
    }
}

#if defined(__GNUC__) && GCC_VERSION < 4006
  /* Work around a GCC uninitialized warning bug fixed in GCC 4.6.  */
static struct bfd_link_hash_entry ehdr_start_empty;
#endif

/* 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 (void)
{
  const char *rpath;
  asection *sinterp;
  bfd *abfd;
  struct elf_link_hash_entry *ehdr_start = NULL;
#if defined(__GNUC__) && GCC_VERSION < 4006
  /* Work around a GCC uninitialized warning bug fixed in GCC 4.6.  */
  struct bfd_link_hash_entry ehdr_start_save = ehdr_start_empty;
#else
  struct bfd_link_hash_entry ehdr_start_save;
#endif

  if (is_elf_hash_table (link_info.hash))
    {
      _bfd_elf_tls_setup (link_info.output_bfd, &link_info);

      /* Make __ehdr_start hidden if it has been referenced, to
	 prevent the symbol from being dynamic.  */
      if (!bfd_link_relocatable (&link_info))
       {
         struct elf_link_hash_entry *h
           = elf_link_hash_lookup (elf_hash_table (&link_info), "__ehdr_start",
                                   FALSE, FALSE, TRUE);

         /* Only adjust the export class if the symbol was referenced
            and not defined, otherwise leave it alone.  */
         if (h != NULL
             && (h->root.type == bfd_link_hash_new
                 || h->root.type == bfd_link_hash_undefined
                 || h->root.type == bfd_link_hash_undefweak
                 || h->root.type == bfd_link_hash_common))
           {
             _bfd_elf_link_hash_hide_symbol (&link_info, h, TRUE);
             if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL)
               h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN;
	     /* Don't leave the symbol undefined.  Undefined hidden
		symbols typically won't have dynamic relocations, but
		we most likely will need dynamic relocations for
		__ehdr_start if we are building a PIE or shared
		library.  */
	     ehdr_start = h;
	     ehdr_start_save = h->root;
	     h->root.type = bfd_link_hash_defined;
	     h->root.u.def.section = bfd_abs_section_ptr;
	     h->root.u.def.value = 0;
           }
       }

      /* 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.  */
      lang_for_each_statement (gld${EMULATION_NAME}_find_statement_assignment);
    }

  /* Let the ELF backend work out the sizes of any sections required
     by dynamic linking.  */
  rpath = command_line.rpath;
  if (rpath == NULL)
    rpath = (const char *) getenv ("LD_RUN_PATH");

  for (abfd = link_info.input_bfds; abfd; abfd = abfd->link.next)
    if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
      {
	const char *audit_libs = elf_dt_audit (abfd);

	/* If the input bfd contains an audit entry, we need to add it as
	   a dep audit entry.  */
	if (audit_libs && *audit_libs != '\0')
	  {
	    char *cp = xstrdup (audit_libs);
	    do
	      {
		int more = 0;
		char *cp2 = strchr (cp, config.rpath_separator);

		if (cp2)
		  {
		    *cp2 = '\0';
		    more = 1;
		  }

		if (cp != NULL && *cp != '\0')
		  gld${EMULATION_NAME}_append_to_separated_string (&depaudit, cp);

		cp = more ? ++cp2 : NULL;
	      }
	    while (cp != NULL);
	  }
      }

  if (! (bfd_elf_size_dynamic_sections
	 (link_info.output_bfd, command_line.soname, rpath,
	  command_line.filter_shlib, audit, depaudit,
	  (const char * const *) command_line.auxiliary_filters,
	  &link_info, &sinterp)))
    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->size = strlen (command_line.interpreter) + 1;
    }

  /* Look for any sections named .gnu.warning.  As a GNU extensions,
     we treat such sections as containing warning messages.  We print
     out the warning message, and then zero out the section size so
     that it does not get copied into the output file.  */

  {
    LANG_FOR_EACH_INPUT_STATEMENT (is)
      {
	asection *s;
	bfd_size_type sz;
	char *msg;

	if (is->flags.just_syms)
	  continue;

	s = bfd_get_section_by_name (is->the_bfd, ".gnu.warning");
	if (s == NULL)
	  continue;

	sz = s->size;
	msg = (char *) xmalloc ((size_t) (sz + 1));
	if (! bfd_get_section_contents (is->the_bfd, s,	msg,
					(file_ptr) 0, sz))
	  einfo ("%F%B: Can't read contents of section .gnu.warning: %E\n",
		 is->the_bfd);
	msg[sz] = '\0';
	(*link_info.callbacks->warning) (&link_info, msg,
					 (const char *) NULL, is->the_bfd,
					 (asection *) NULL, (bfd_vma) 0);
	free (msg);

	/* Clobber the section size, so that we don't waste space
	   copying the warning into the output file.  If we've already
	   sized the output section, adjust its size.  The adjustment
	   is on rawsize because targets that size sections early will
	   have called lang_reset_memory_regions after sizing.  */
	if (s->output_section != NULL
	    && s->output_section->rawsize >= s->size)
	  s->output_section->rawsize -= s->size;

	s->size = 0;

	/* Also set SEC_EXCLUDE, so that local symbols defined in the
	   warning section don't get copied to the output.  */
	s->flags |= SEC_EXCLUDE | SEC_KEEP;
      }
  }

  before_allocation_default ();

  if (!bfd_elf_size_dynsym_hash_dynstr (link_info.output_bfd, &link_info))
    einfo ("%P%F: failed to set dynamic section sizes: %E\n");

  if (ehdr_start != NULL)
    {
      /* If we twiddled __ehdr_start to defined earlier, put it back
	 as it was.  */
      ehdr_start->root.type = ehdr_start_save.type;
      ehdr_start->root.u = ehdr_start_save.u;
    }
}

EOF
fi

if test x"$LDEMUL_OPEN_DYNAMIC_ARCHIVE" != xgld"$EMULATION_NAME"_open_dynamic_archive; then
fragment <<EOF

/* Try to open a dynamic archive.  This is where we know that ELF
   dynamic libraries have an extension of .so (or .sl on oddball systems
   like hpux).  */

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;
  size_t len;
  bfd_boolean opened = FALSE;

  if (! entry->flags.maybe_archive)
    return FALSE;

  filename = entry->filename;
  len = strlen (search->name) + strlen (filename);
  if (entry->flags.full_name_provided)
    {
      len += sizeof "/";
      string = (char *) xmalloc (len);
      sprintf (string, "%s/%s", search->name, filename);
    }
  else
    {
      size_t xlen = 0;

      len += strlen (arch) + sizeof "/lib.so";
#ifdef EXTRA_SHLIB_EXTENSION
      xlen = (strlen (EXTRA_SHLIB_EXTENSION) > 3
	      ? strlen (EXTRA_SHLIB_EXTENSION) - 3
	      : 0);
#endif
      string = (char *) xmalloc (len + xlen);
      sprintf (string, "%s/lib%s%s.so", search->name, filename, arch);
#ifdef EXTRA_SHLIB_EXTENSION
      /* Try the .so extension first.  If that fails build a new filename
	 using EXTRA_SHLIB_EXTENSION.  */
      opened = ldfile_try_open_bfd (string, entry);
      if (!opened)
	strcpy (string + len - 4, EXTRA_SHLIB_EXTENSION);
#endif
    }

  if (!opened && !ldfile_try_open_bfd (string, entry))
    {
      free (string);
      return FALSE;
    }

  entry->filename = string;

  /* We have found a dynamic object to include in the link.  The ELF
     backend linker will create a DT_NEEDED entry in the .dynamic
     section naming this file.  If this file includes a DT_SONAME
     entry, it will be used.  Otherwise, the ELF linker will just use
     the name of the file.  For an archive found by searching, like
     this one, the DT_NEEDED entry should consist of just the name of
     the file, without the path information used to find it.  Note
     that we only need to do this if we have a dynamic object; an
     archive will never be referenced by a DT_NEEDED entry.

     FIXME: This approach--using bfd_elf_set_dt_needed_name--is not
     very pretty.  I haven't been able to think of anything that is
     pretty, though.  */
  if (bfd_check_format (entry->the_bfd, bfd_object)
      && (entry->the_bfd->flags & DYNAMIC) != 0)
    {
      ASSERT (entry->flags.maybe_archive && entry->flags.search_dirs);

      /* Rather than duplicating the logic above.  Just use the
	 filename we recorded earlier.  */

      if (!entry->flags.full_name_provided)
        filename = lbasename (entry->filename);
      bfd_elf_set_dt_needed_name (entry->the_bfd, filename);
    }

  return TRUE;
}

EOF
fi

if test x"$LDEMUL_PLACE_ORPHAN" != xgld"$EMULATION_NAME"_place_orphan; then
fragment <<EOF

/* A variant of lang_output_section_find used by place_orphan.  */

static lang_output_section_statement_type *
output_rel_find (asection *sec, int isdyn)
{
  lang_output_section_statement_type *lookup;
  lang_output_section_statement_type *last = NULL;
  lang_output_section_statement_type *last_alloc = NULL;
  lang_output_section_statement_type *last_ro_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)
    {
      if (lookup->constraint >= 0
	  && CONST_STRNEQ (lookup->name, ".rel"))
	{
	  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;
	  if ((lookup->bfd_section->flags & SEC_READONLY) != 0)
	    last_ro_alloc = lookup;
	}
    }

  if (last_rel_alloc)
    return last_rel_alloc;

  if (last_rel)
    return last_rel;

  if (last_ro_alloc)
    return last_ro_alloc;

  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.  */

static lang_output_section_statement_type *
gld${EMULATION_NAME}_place_orphan (asection *s,
				   const char *secname,
				   int constraint)
{
  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 },
      { ".tdata",
	SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_THREAD_LOCAL,
	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 },
      { ".comment",
	SEC_HAS_CONTENTS,
	0, 0, 0, 0 },
    };
  enum orphan_save_index
    {
      orphan_text = 0,
      orphan_rodata,
      orphan_tdata,
      orphan_data,
      orphan_bss,
      orphan_rel,
      orphan_interp,
      orphan_sdata,
      orphan_nonalloc
    };
  static int orphan_init_done = 0;
  struct orphan_save *place;
  lang_output_section_statement_type *after;
  lang_output_section_statement_type *os;
  lang_output_section_statement_type *match_by_name = NULL;
  int isdyn = 0;
  int iself = s->owner->xvec->flavour == bfd_target_elf_flavour;
  unsigned int sh_type = iself ? elf_section_type (s) : SHT_NULL;
  flagword flags;
  asection *nexts;

  if (!bfd_link_relocatable (&link_info)
      && link_info.combreloc
      && (s->flags & SEC_ALLOC))
    {
      if (iself)
	switch (sh_type)
	  {
	  case SHT_RELA:
	    secname = ".rela.dyn";
	    isdyn = 1;
	    break;
	  case SHT_REL:
	    secname = ".rel.dyn";
	    isdyn = 1;
	    break;
	  default:
	    break;
	  }
      else if (CONST_STRNEQ (secname, ".rel"))
	{
	  secname = secname[4] == 'a' ? ".rela.dyn" : ".rel.dyn";
	  isdyn = 1;
	}
    }

  if (!bfd_link_relocatable (&link_info)
      && (s->flags & SEC_ALLOC) != 0
      && (elf_section_flags (s) & SHF_GNU_MBIND) != 0)
    {
      /* Find the output mbind section with the same type, attributes
	 and sh_info field.  */
      for (os = &lang_output_section_statement.head->output_section_statement;
	   os != NULL;
	   os = os->next)
	if (os->bfd_section != NULL
	    && !bfd_is_abs_section (os->bfd_section)
	    && (elf_section_flags (os->bfd_section) & SHF_GNU_MBIND) != 0
	    && ((s->flags & (SEC_ALLOC
			     | SEC_LOAD
			     | SEC_HAS_CONTENTS
			     | SEC_READONLY
			     | SEC_CODE))
		== (os->bfd_section->flags & (SEC_ALLOC
					      | SEC_LOAD
					      | SEC_HAS_CONTENTS
					      | SEC_READONLY
					      | SEC_CODE)))
	    && (elf_section_data (os->bfd_section)->this_hdr.sh_info
		== elf_section_data (s)->this_hdr.sh_info))
	    {
	      lang_add_section (&os->children, s, NULL, os);
	      return os;
	    }

      /* Create the output mbind section with the ".mbind." prefix
	 in section name.  */
      if ((s->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
	secname = ".mbind.bss";
      else if ((s->flags & SEC_READONLY) == 0)
	secname = ".mbind.data";
      else if ((s->flags & SEC_CODE) == 0)
	secname = ".mbind.rodata";
      else
	secname = ".mbind.text";
    }

  /* Look through the script to see where to place this section.  */
  if (constraint == 0)
    for (os = lang_output_section_find (secname);
	 os != NULL;
	 os = next_matching_output_section_statement (os, 0))
      {
	/* If we don't match an existing output section, tell
	   lang_insert_orphan to create a new output section.  */
	constraint = SPECIAL;

	/* SEC_EXCLUDE is cleared when doing a relocatable link.  But
	   we can't merge 2 input sections with the same name when only
	   one of them has SHF_EXCLUDE.  Don't merge 2 sections with
	   different sh_info.  */
	if (os->bfd_section != NULL
	    && (elf_section_data (os->bfd_section)->this_hdr.sh_info
		== elf_section_data (s)->this_hdr.sh_info)
	    && (os->bfd_section->flags == 0
		|| ((!bfd_link_relocatable (&link_info)
		     || (iself && (((elf_section_flags (s)
				     ^ elf_section_flags (os->bfd_section))
				    & SHF_EXCLUDE) == 0)))
		    && ((s->flags ^ os->bfd_section->flags)
		     & (SEC_LOAD | SEC_ALLOC)) == 0
		    && _bfd_elf_match_sections_by_type (link_info.output_bfd,
							os->bfd_section,
							s->owner, s))))
	  {
	    /* We already have an output section statement with this
	       name, and its bfd section 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, NULL, os);
	    return os;
	  }

	/* Save unused output sections in case we can match them
	   against orphans later.  */
	if (os->bfd_section == NULL)
	  match_by_name = os;
      }

  /* If we didn't match an active output section, see if we matched an
     unused one and use that.  */
  if (match_by_name)
    {
      lang_add_section (&match_by_name->children, s, NULL, match_by_name);
      return match_by_name;
    }

  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 (bfd_link_executable (&link_info)
      && CONST_STRNEQ (s->name, ".gnu.warning.")
      && hold[orphan_text].os != NULL)
    {
      os = hold[orphan_text].os;
      lang_add_section (&os->children, s, NULL, os);
      return os;
    }

  flags = s->flags;
  if (!bfd_link_relocatable (&link_info))
    {
      nexts = s;
      while ((nexts = bfd_get_next_section_by_name (nexts->owner, nexts))
	     != NULL)
	if (nexts->output_section == NULL
	    && (nexts->flags & SEC_EXCLUDE) == 0
	    && ((nexts->flags ^ flags) & (SEC_LOAD | SEC_ALLOC)) == 0
	    && (nexts->owner->flags & DYNAMIC) == 0
	    && nexts->owner->usrdata != NULL
	    && !(((lang_input_statement_type *) nexts->owner->usrdata)
		 ->flags.just_syms)
	    && _bfd_elf_match_sections_by_type (nexts->owner, nexts,
						s->owner, s))
	  flags = (((flags ^ SEC_READONLY)
		    | (nexts->flags ^ SEC_READONLY))
		   ^ SEC_READONLY);
    }

  /* Decide which segment the section should go in based on the
     section name and section flags.  We put loadable .note sections
     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.  */

  place = NULL;
  if ((flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0)
    place = &hold[orphan_nonalloc];
  else if ((flags & SEC_ALLOC) == 0)
    ;
  else if ((flags & SEC_LOAD) != 0
	   && ((iself && sh_type == SHT_NOTE)
	       || (!iself && CONST_STRNEQ (secname, ".note"))))
    place = &hold[orphan_interp];
  else if ((flags & (SEC_LOAD | SEC_HAS_CONTENTS | SEC_THREAD_LOCAL)) == 0)
    place = &hold[orphan_bss];
  else if ((flags & SEC_SMALL_DATA) != 0)
    place = &hold[orphan_sdata];
  else if ((flags & SEC_THREAD_LOCAL) != 0)
    place = &hold[orphan_tdata];
  else if ((flags & SEC_READONLY) == 0)
    place = &hold[orphan_data];
  else if (((iself && (sh_type == SHT_RELA || sh_type == SHT_REL))
	    || (!iself && CONST_STRNEQ (secname, ".rel")))
	   && (flags & SEC_LOAD) != 0)
    place = &hold[orphan_rel];
  else if ((flags & SEC_CODE) == 0)
    place = &hold[orphan_rodata];
  else
    place = &hold[orphan_text];

  after = NULL;
  if (place != NULL)
    {
      if (place->os == NULL)
	{
	  if (place->name != NULL)
	    place->os = lang_output_section_find (place->name);
	  else
	    place->os = output_rel_find (s, isdyn);
	}
      after = place->os;
      if (after == NULL)
	after
	  = lang_output_section_find_by_flags (s, flags, &place->os,
					       _bfd_elf_match_sections_by_type);
      if (after == NULL)
	/* *ABS* is always the first output section statement.  */
	after = &lang_output_section_statement.head->output_section_statement;
    }

  return lang_insert_orphan (s, secname, constraint, after, place, NULL, NULL);
}
EOF
fi

if test x"$LDEMUL_AFTER_ALLOCATION" != xgld"$EMULATION_NAME"_after_allocation; then
fragment <<EOF

static void
gld${EMULATION_NAME}_after_allocation (void)
{
  int need_layout = bfd_elf_discard_info (link_info.output_bfd, &link_info);

  if (need_layout < 0)
    einfo ("%X%P: .eh_frame/.stab edit: %E\n");
  else
    gld${EMULATION_NAME}_map_segments (need_layout);
}
EOF
fi

if test x"$LDEMUL_GET_SCRIPT" != xgld"$EMULATION_NAME"_get_script; then
fragment <<EOF

static char *
gld${EMULATION_NAME}_get_script (int *isfile)
EOF

if test x"$COMPILE_IN" = xyes
then
# Scripts compiled in.

# sed commands to quote an ld script as a C string.
sc="-f stringify.sed"

fragment <<EOF
{
  *isfile = 0;

  if (bfd_link_relocatable (&link_info) && config.build_constructors)
    return
EOF
sed $sc ldscripts/${EMULATION_NAME}.xu			>> e${EMULATION_NAME}.c
echo '  ; else if (bfd_link_relocatable (&link_info)) 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 (bfd_link_pie (&link_info)'		>> e${EMULATION_NAME}.c
echo '             && link_info.combreloc'		>> e${EMULATION_NAME}.c
echo '             && link_info.relro'			>> e${EMULATION_NAME}.c
echo '             && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xdw			>> e${EMULATION_NAME}.c
echo '  ; else if (bfd_link_pie (&link_info)'		>> e${EMULATION_NAME}.c
echo '             && link_info.combreloc) return'	>> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xdc			>> e${EMULATION_NAME}.c
fi
echo '  ; else if (bfd_link_pie (&link_info)) return'	>> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xd			>> e${EMULATION_NAME}.c
fi
if test -n "$GENERATE_SHLIB_SCRIPT" ; then
if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
echo '  ; else if (bfd_link_dll (&link_info) && link_info.combreloc' >> e${EMULATION_NAME}.c
echo '             && link_info.relro' >> e${EMULATION_NAME}.c
echo '             && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xsw			>> e${EMULATION_NAME}.c
echo '  ; else if (bfd_link_dll (&link_info) && link_info.combreloc) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xsc			>> e${EMULATION_NAME}.c
fi
echo '  ; else if (bfd_link_dll (&link_info)) 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 & DF_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.

fragment <<EOF
{
  *isfile = 1;

  if (bfd_link_relocatable (&link_info) && config.build_constructors)
    return "ldscripts/${EMULATION_NAME}.xu";
  else if (bfd_link_relocatable (&link_info))
    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
fragment <<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
fragment <<EOF
  else if (bfd_link_pie (&link_info)
	   && link_info.combreloc
	   && link_info.relro
	   && (link_info.flags & DF_BIND_NOW))
    return "ldscripts/${EMULATION_NAME}.xdw";
  else if (bfd_link_pie (&link_info)
	   && link_info.combreloc)
    return "ldscripts/${EMULATION_NAME}.xdc";
EOF
fi
fragment <<EOF
  else if (bfd_link_pie (&link_info))
    return "ldscripts/${EMULATION_NAME}.xd";
EOF
fi
if test -n "$GENERATE_SHLIB_SCRIPT" ; then
if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
fragment <<EOF
  else if (bfd_link_dll (&link_info) && link_info.combreloc
	   && link_info.relro && (link_info.flags & DF_BIND_NOW))
    return "ldscripts/${EMULATION_NAME}.xsw";
  else if (bfd_link_dll (&link_info) && link_info.combreloc)
    return "ldscripts/${EMULATION_NAME}.xsc";
EOF
fi
fragment <<EOF
  else if (bfd_link_dll (&link_info))
    return "ldscripts/${EMULATION_NAME}.xs";
EOF
fi
if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
fragment <<EOF
  else if (link_info.combreloc && link_info.relro
	   && (link_info.flags & DF_BIND_NOW))
    return "ldscripts/${EMULATION_NAME}.xw";
  else if (link_info.combreloc)
    return "ldscripts/${EMULATION_NAME}.xc";
EOF
fi
fragment <<EOF
  else
    return "ldscripts/${EMULATION_NAME}.x";
}

EOF
fi
fi

if test -n "$PARSE_AND_LIST_PROLOGUE" ; then
fragment <<EOF
 $PARSE_AND_LIST_PROLOGUE
EOF
fi

fragment <<EOF

enum elf_options
{
  OPTION_DISABLE_NEW_DTAGS = 400,
  OPTION_ENABLE_NEW_DTAGS,
  OPTION_GROUP,
  OPTION_EH_FRAME_HDR,
  OPTION_NO_EH_FRAME_HDR,
  OPTION_EXCLUDE_LIBS,
  OPTION_HASH_STYLE,
  OPTION_BUILD_ID,
  OPTION_AUDIT,
  OPTION_COMPRESS_DEBUG
};

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)
{
EOF
if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
fragment <<EOF
  static const char xtra_short[] = "${PARSE_AND_LIST_SHORTOPTS}z:P:";
EOF
else
fragment <<EOF
  static const char xtra_short[] = "${PARSE_AND_LIST_SHORTOPTS}z:";
EOF
fi
fragment <<EOF
  static const struct option xtra_long[] = {
EOF
if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
fragment <<EOF
    {"audit", required_argument, NULL, OPTION_AUDIT},
    {"Bgroup", no_argument, NULL, OPTION_GROUP},
EOF
fi
fragment <<EOF
    {"build-id", optional_argument, NULL, OPTION_BUILD_ID},
    {"compress-debug-sections", required_argument, NULL, OPTION_COMPRESS_DEBUG},
EOF
if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
fragment <<EOF
    {"depaudit", required_argument, NULL, 'P'},
    {"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},
    {"no-eh-frame-hdr", no_argument, NULL, OPTION_NO_EH_FRAME_HDR},
    {"exclude-libs", required_argument, NULL, OPTION_EXCLUDE_LIBS},
    {"hash-style", required_argument, NULL, OPTION_HASH_STYLE},
EOF
fi
if test -n "$PARSE_AND_LIST_LONGOPTS" ; then
fragment <<EOF
    $PARSE_AND_LIST_LONGOPTS
EOF
fi
fragment <<EOF
    {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));
}

#define DEFAULT_BUILD_ID_STYLE	"sha1"

static bfd_boolean
gld${EMULATION_NAME}_handle_option (int optc)
{
  switch (optc)
    {
    default:
      return FALSE;

    case OPTION_BUILD_ID:
      if (emit_note_gnu_build_id != NULL)
	{
	  free ((char *) emit_note_gnu_build_id);
	  emit_note_gnu_build_id = NULL;
	}
      if (optarg == NULL)
	optarg = DEFAULT_BUILD_ID_STYLE;
      if (strcmp (optarg, "none"))
	emit_note_gnu_build_id = xstrdup (optarg);
      break;

    case OPTION_COMPRESS_DEBUG:
      if (strcasecmp (optarg, "none") == 0)
	link_info.compress_debug = COMPRESS_DEBUG_NONE;
      else if (strcasecmp (optarg, "zlib") == 0)
	link_info.compress_debug = COMPRESS_DEBUG_GABI_ZLIB;
      else if (strcasecmp (optarg, "zlib-gnu") == 0)
	link_info.compress_debug = COMPRESS_DEBUG_GNU_ZLIB;
      else if (strcasecmp (optarg, "zlib-gabi") == 0)
	link_info.compress_debug = COMPRESS_DEBUG_GABI_ZLIB;
      else
	einfo (_("%P%F: invalid --compress-debug-sections option: \`%s'\n"),
	       optarg);
      break;
EOF

if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
fragment <<EOF
    case OPTION_AUDIT:
	gld${EMULATION_NAME}_append_to_separated_string (&audit, optarg);
	break;

    case 'P':
	gld${EMULATION_NAME}_append_to_separated_string (&depaudit, optarg);
	break;

    case OPTION_DISABLE_NEW_DTAGS:
      link_info.new_dtags = FALSE;
      break;

    case OPTION_ENABLE_NEW_DTAGS:
      link_info.new_dtags = TRUE;
      break;

    case OPTION_EH_FRAME_HDR:
      link_info.eh_frame_hdr_type = DWARF2_EH_HDR;
      break;

    case OPTION_NO_EH_FRAME_HDR:
      link_info.eh_frame_hdr_type = 0;
      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 OPTION_HASH_STYLE:
      link_info.emit_hash = FALSE;
      link_info.emit_gnu_hash = FALSE;
      if (strcmp (optarg, "sysv") == 0)
	link_info.emit_hash = TRUE;
      else if (strcmp (optarg, "gnu") == 0)
	link_info.emit_gnu_hash = TRUE;
      else if (strcmp (optarg, "both") == 0)
	{
	  link_info.emit_hash = TRUE;
	  link_info.emit_gnu_hash = TRUE;
	}
      else
	einfo (_("%P%F: invalid hash style \`%s'\n"), optarg);
      break;

EOF
fi
fragment <<EOF
    case 'z':
      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 (CONST_STRNEQ (optarg, "max-page-size="))
	{
	  char *end;

	  config.maxpagesize = strtoul (optarg + 14, &end, 0);
	  if (*end || (config.maxpagesize & (config.maxpagesize - 1)) != 0)
	    einfo (_("%P%F: invalid maxium page size \`%s'\n"),
		   optarg + 14);
	}
      else if (CONST_STRNEQ (optarg, "common-page-size="))
	{
	  char *end;
	  config.commonpagesize = strtoul (optarg + 17, &end, 0);
	  if (*end
	      || (config.commonpagesize & (config.commonpagesize - 1)) != 0)
	    einfo (_("%P%F: invalid common page size \`%s'\n"),
		   optarg + 17);
	}
      else if (CONST_STRNEQ (optarg, "stack-size="))
	{
	  char *end;
	  link_info.stacksize = strtoul (optarg + 11, &end, 0);
	  if (*end || link_info.stacksize < 0)
	    einfo (_("%P%F: invalid stack size \`%s'\n"), optarg + 11);
	  if (!link_info.stacksize)
	    /* Use -1 for explicit no-stack, because zero means
	       'default'.   */
	    link_info.stacksize = -1;
	}
      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;
	}
EOF

if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
fragment <<EOF
      else if (strcmp (optarg, "global") == 0)
	link_info.flags_1 |= (bfd_vma) DF_1_GLOBAL;
      else if (strcmp (optarg, "initfirst") == 0)
	link_info.flags_1 |= (bfd_vma) DF_1_INITFIRST;
      else if (strcmp (optarg, "interpose") == 0)
	link_info.flags_1 |= (bfd_vma) DF_1_INTERPOSE;
      else if (strcmp (optarg, "loadfltr") == 0)
	link_info.flags_1 |= (bfd_vma) DF_1_LOADFLTR;
      else if (strcmp (optarg, "nodefaultlib") == 0)
	link_info.flags_1 |= (bfd_vma) DF_1_NODEFLIB;
      else if (strcmp (optarg, "nodelete") == 0)
	link_info.flags_1 |= (bfd_vma) DF_1_NODELETE;
      else if (strcmp (optarg, "nodlopen") == 0)
	link_info.flags_1 |= (bfd_vma) DF_1_NOOPEN;
      else if (strcmp (optarg, "nodump") == 0)
	link_info.flags_1 |= (bfd_vma) DF_1_NODUMP;
      else if (strcmp (optarg, "now") == 0)
	{
	  link_info.flags |= (bfd_vma) DF_BIND_NOW;
	  link_info.flags_1 |= (bfd_vma) DF_1_NOW;
	}
      else if (strcmp (optarg, "lazy") == 0)
	{
	  link_info.flags &= ~(bfd_vma) DF_BIND_NOW;
	  link_info.flags_1 &= ~(bfd_vma) DF_1_NOW;
	}
      else if (strcmp (optarg, "origin") == 0)
	{
	  link_info.flags |= (bfd_vma) DF_ORIGIN;
	  link_info.flags_1 |= (bfd_vma) DF_1_ORIGIN;
	}
      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, "relro") == 0)
	link_info.relro = TRUE;
      else if (strcmp (optarg, "norelro") == 0)
	link_info.relro = FALSE;
      else if (strcmp (optarg, "common") == 0)
	link_info.elf_stt_common = elf_stt_common;
      else if (strcmp (optarg, "nocommon") == 0)
	link_info.elf_stt_common = no_elf_stt_common;
      else if (strcmp (optarg, "text") == 0)
	link_info.error_textrel = TRUE;
      else if (strcmp (optarg, "notext") == 0)
	link_info.error_textrel = FALSE;
      else if (strcmp (optarg, "textoff") == 0)
	link_info.error_textrel = FALSE;
EOF
fi

if test -n "$PARSE_AND_LIST_ARGS_CASE_Z" ; then
fragment <<EOF
 $PARSE_AND_LIST_ARGS_CASE_Z
EOF
fi

fragment <<EOF
      else
	einfo (_("%P: warning: -z %s ignored.\n"), optarg);
      break;
EOF

if test -n "$PARSE_AND_LIST_ARGS_CASES" ; then
fragment <<EOF
 $PARSE_AND_LIST_ARGS_CASES
EOF
fi

fragment <<EOF
    }

  return TRUE;
}

EOF

if test x"$LDEMUL_LIST_OPTIONS" != xgld"$EMULATION_NAME"_list_options; then
gld_list_options="gld${EMULATION_NAME}_list_options"
if test -n "$PARSE_AND_LIST_OPTIONS"; then
fragment <<EOF

static void
gld${EMULATION_NAME}_list_options (FILE * file)
{
EOF

if test -n "$PARSE_AND_LIST_OPTIONS" ; then
fragment <<EOF
 $PARSE_AND_LIST_OPTIONS
EOF
fi

fragment <<EOF
}
EOF
else
  gld_list_options="NULL"
fi

if test -n "$PARSE_AND_LIST_EPILOGUE" ; then
fragment <<EOF
 $PARSE_AND_LIST_EPILOGUE
EOF
fi
fi

fragment <<EOF

struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
{
  ${LDEMUL_BEFORE_PARSE-gld${EMULATION_NAME}_before_parse},
  ${LDEMUL_SYSLIB-syslib_default},
  ${LDEMUL_HLL-hll_default},
  ${LDEMUL_AFTER_PARSE-gld${EMULATION_NAME}_after_parse},
  ${LDEMUL_AFTER_OPEN-gld${EMULATION_NAME}_after_open},
  ${LDEMUL_AFTER_ALLOCATION-gld${EMULATION_NAME}_after_allocation},
  ${LDEMUL_SET_OUTPUT_ARCH-set_output_arch_default},
  ${LDEMUL_CHOOSE_TARGET-ldemul_default_target},
  ${LDEMUL_BEFORE_ALLOCATION-gld${EMULATION_NAME}_before_allocation},
  ${LDEMUL_GET_SCRIPT-gld${EMULATION_NAME}_get_script},
  "${EMULATION_NAME}",
  "${OUTPUT_FORMAT}",
  ${LDEMUL_FINISH-finish_default},
  ${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-NULL},
  gld${EMULATION_NAME}_add_options,
  gld${EMULATION_NAME}_handle_option,
  ${LDEMUL_UNRECOGNIZED_FILE-NULL},
  ${LDEMUL_LIST_OPTIONS-${gld_list_options}},
  ${LDEMUL_RECOGNIZED_FILE-gld${EMULATION_NAME}_load_symbols},
  ${LDEMUL_FIND_POTENTIAL_LIBRARIES-NULL},
  ${LDEMUL_NEW_VERS_PATTERN-NULL},
  ${LDEMUL_EXTRA_MAP_FILE_TEXT-NULL}
};
EOF
