# 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-2018 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 = TRUE;
  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;

  if (bfd_link_executable (&link_info)
      && link_info.nointerp)
    {
      if (link_info.dynamic_undefined_weak > 0)
	einfo (_("%P: warning: -z dynamic-undefined-weak ignored\n"));
      link_info.dynamic_undefined_weak = 0;
    }
  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;
  asection *s;
  bfd *abfd;

  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)
    {
      /* 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
	    && !((lang_input_statement_type *) abfd->usrdata)->flags.just_syms)
	  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 *elfbfd = NULL;
      bfd_boolean warn_eh_frame = FALSE;
      int seen_type = 0;

      for (abfd = link_info.input_bfds; abfd; abfd = abfd->link.next)
	{
	  int type = 0;

	  if (((lang_input_statement_type *) abfd->usrdata)->flags.just_syms)
	    continue;

	  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 (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))
      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_table *htab = elf_hash_table (&link_info);
	  struct elf_link_hash_entry *h
	    = elf_link_hash_lookup (htab, "__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))
	    {
	      const struct elf_backend_data *bed;
	      bed = get_elf_backend_data (link_info.output_bfd);
	      (*bed->elf_backend_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;
}

/* Return whether IN is suitable to be part of OUT.  */

static bfd_boolean
elf_orphan_compatible (asection *in, asection *out)
{
  /* Non-zero sh_info implies a section with SHF_INFO_LINK with
     unknown semantics for the generic linker, or a SHT_REL/SHT_RELA
     section where sh_info specifies a symbol table.  (We won't see
     SHT_GROUP, SHT_SYMTAB or SHT_DYNSYM sections here.)  We clearly
     can't merge SHT_REL/SHT_RELA using differing symbol tables, and
     shouldn't merge sections with differing unknown semantics.  */
  if (elf_section_data (out)->this_hdr.sh_info
      != elf_section_data (in)->this_hdr.sh_info)
    return FALSE;
  /* We can't merge two sections with differing SHF_EXCLUDE when doing
     a relocatable link.  */
  if (bfd_link_relocatable (&link_info)
      && ((elf_section_flags (out) ^ elf_section_flags (in)) & SHF_EXCLUDE) != 0)
    return FALSE;
  return _bfd_elf_match_sections_by_type (link_info.output_bfd, out,
					  in->owner, in);
}

/* 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 elfinput = s->owner->xvec->flavour == bfd_target_elf_flavour;
  int elfoutput = link_info.output_bfd->xvec->flavour == bfd_target_elf_flavour;
  unsigned int sh_type = elfinput ? elf_section_type (s) : SHT_NULL;
  flagword flags;
  asection *nexts;

  if (!bfd_link_relocatable (&link_info)
      && link_info.combreloc
      && (s->flags & SEC_ALLOC))
    {
      if (elfinput)
	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)
      && elfinput
      && elfoutput
      && (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.  The
     script includes entries added by previous lang_insert_orphan
     calls, so this loop puts multiple compatible orphans of the same
     name into a single output 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;

	/* Check to see if 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, possibly as a
	   result of a --section-start command line switch.  */
	if (os->bfd_section != NULL
	    && (os->bfd_section->flags == 0
		|| (((s->flags ^ os->bfd_section->flags)
		     & (SEC_LOAD | SEC_ALLOC)) == 0
		    && (!elfinput
			|| !elfoutput
			|| elf_orphan_compatible (s, os->bfd_section)))))
	  {
	    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
	   && ((elfinput && sh_type == SHT_NOTE)
	       || (!elfinput && 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 (((elfinput && (sh_type == SHT_RELA || sh_type == SHT_REL))
	    || (!elfinput && 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)'		>> 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}.xsw			>> e${EMULATION_NAME}.c
echo '  ; else if (bfd_link_dll (&link_info)'		>> e${EMULATION_NAME}.c
echo '             && 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'			>> 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}.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;
	}
      else if (strcmp (optarg, "globalaudit") == 0)
	{
	  link_info.flags_1 |= DF_1_GLOBAUDIT;
	}
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_CHECK_RELOCS-after_check_relocs_default},
  ${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
