# 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-2016 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

/* Add the sysroot to every entry in a path separated by
   config.rpath_separator.  */

static char *
gld${EMULATION_NAME}_add_sysroot (const char *path)
{
  int len, colons, i;
  char *ret, *p;

  len = strlen (path);
  colons = 0;
  i = 0;
  while (path[i])
    if (path[i++] == config.rpath_separator)
      colons++;

  if (path[i])
    colons++;

  len = len + (colons + 1) * strlen (ld_sysroot);
  ret = xmalloc (len + 1);
  strcpy (ret, ld_sysroot);
  p = ret + strlen (ret);
  i = 0;
  while (path[i])
    if (path[i] == config.rpath_separator)
      {
	*p++ = path[i++];
	strcpy (p, ld_sysroot);
	p = p + strlen (p);
      }
    else
      *p++ = path[i++];

  *p = 0;
  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 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 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)
	{
	  char *d = gld${EMULATION_NAME}_add_sysroot (info.path);
	  free (info.path);
	  ld_so_conf = d;
	}
      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;
	}
    }

  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 ] ; then
fragment <<EOF
	  const char *lib_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
	  if (gld${EMULATION_NAME}_search_needed (command_line.rpath,
						  &n, force))
	    break;
EOF
fi
if [ "x${NATIVE}" = xyes ] ; then
fragment <<EOF
	  if (command_line.rpath_link == NULL
	      && command_line.rpath == NULL)
	    {
	      lib_path = (const char *) getenv ("LD_RUN_PATH");
	      if (gld${EMULATION_NAME}_search_needed (lib_path, &n,
						      force))
		break;
	    }
	  lib_path = (const char *) getenv ("LD_LIBRARY_PATH");
	  if (gld${EMULATION_NAME}_search_needed (lib_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)
	    {
	      const char *tmpname = rp->name;

	      if (IS_ABSOLUTE_PATH (tmpname))
		tmpname = gld${EMULATION_NAME}_add_sysroot (tmpname);
	      found = (rp->by == l->by
		       && gld${EMULATION_NAME}_search_needed (tmpname,
							      &n,
							      force));
	      if (tmpname != rp->name)
		free ((char *) tmpname);
	    }
	  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;
	}
    }

  /* 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.  */
	if (os->bfd_section != NULL
	    && (os->bfd_section->flags == 0
		|| ((!bfd_link_relocatable (&link_info)
		     || (((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
