# This shell script emits a C file. -*- C -*-
# It does some substitutions.
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! */

/* SunOS emulation code for ${EMULATION_NAME}
   Copyright 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
   2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
   Written by Steve Chamberlain <sac@cygnus.com>
   SunOS shared library 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 "bfdlink.h"
#include "libiberty.h"
#include "safe-ctype.h"

#include "ld.h"
#include "ldmain.h"
#include "ldmisc.h"
#include "ldexp.h"
#include "ldlang.h"
#include "ldfile.h"
#include "ldemul.h"

#ifdef HAVE_DIRENT_H
# include <dirent.h>
#else
# define dirent direct
# ifdef HAVE_SYS_NDIR_H
#  include <sys/ndir.h>
# endif
# ifdef HAVE_SYS_DIR_H
#  include <sys/dir.h>
# endif
# ifdef HAVE_NDIR_H
#  include <ndir.h>
# endif
#endif

static void gld${EMULATION_NAME}_find_so
  (lang_input_statement_type *);
static char *gld${EMULATION_NAME}_search_dir
  (const char *, const char *, bfd_boolean *);
static void gld${EMULATION_NAME}_check_needed
  (lang_input_statement_type *);
static bfd_boolean gld${EMULATION_NAME}_search_needed
  (const char *, const char *);
static bfd_boolean gld${EMULATION_NAME}_try_needed
  (const char *, const char *);
static void gld${EMULATION_NAME}_find_assignment
  (lang_statement_union_type *);
static void gld${EMULATION_NAME}_find_exp_assignment
  (etree_type *);
static void gld${EMULATION_NAME}_count_need
  (lang_input_statement_type *);
static void gld${EMULATION_NAME}_set_need
  (lang_input_statement_type *);

static void
gld${EMULATION_NAME}_before_parse (void)
{
  ldfile_set_output_arch ("${OUTPUT_ARCH}", bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`);
  config.dynamic_link = TRUE;
  config.has_shared = TRUE;
}

/* This is called after the command line arguments have been parsed,
   but before the linker script has been read.  If this is a native
   linker, we add the directories in LD_LIBRARY_PATH to the search
   list.  */

static void
gld${EMULATION_NAME}_set_symbols (void)
{
EOF
if [ "x${host}" = "x${target}" ] ; then
  case " ${EMULATION_LIBPATH} " in
  *" ${EMULATION_NAME} "*)
fragment <<EOF
  const char *env;

  env = (const char *) getenv ("LD_LIBRARY_PATH");
  if (env != NULL)
    {
      char *l;

      l = xstrdup (env);
      while (1)
	{
	  char *c;

	  c = strchr (l, ':');
	  if (c != NULL)
	    *c++ = '\0';
	  if (*l != '\0')
	    ldfile_add_library_path (l, FALSE);
	  if (c == NULL)
	    break;
	  l = c;
	}
    }
EOF
  ;;
  esac
fi
fragment <<EOF
}

/* Despite the name, we use this routine to search for dynamic
   libraries.  On SunOS this requires a directory search.  We need to
   find the .so file with the highest version number.  The user may
   restrict the major version by saying, e.g., -lc.1.  Also, if we
   find a .so file, we need to look for a the same file after
   replacing .so with .sa; if it exists, it will be an archive which
   provide some initializations for data symbols, and we need to
   search it after including the .so file.  */

static void
gld${EMULATION_NAME}_create_output_section_statements (void)
{
  lang_for_each_input_file (gld${EMULATION_NAME}_find_so);
}

/* Search the directory for a .so file for each library search.  */

static void
gld${EMULATION_NAME}_find_so (lang_input_statement_type *inp)
{
  search_dirs_type *search;
  char *found = NULL;
  char *alc;
  struct stat st;

  if (! inp->search_dirs_flag
      || ! inp->is_archive
      || ! inp->dynamic)
    return;

  ASSERT (CONST_STRNEQ (inp->local_sym_name, "-l"));

  for (search = search_head; search != NULL; search = search->next)
    {
      bfd_boolean found_static;

      found = gld${EMULATION_NAME}_search_dir (search->name, inp->filename,
					       &found_static);
      if (found != NULL || found_static)
	break;
    }

  if (found == NULL)
    {
      /* We did not find a matching .so file.  This isn't an error,
	 since there might still be a matching .a file, which will be
	 found by the usual search.  */
      return;
    }

  /* Replace the filename with the one we have found.  */
  alc = (char *) xmalloc (strlen (search->name) + strlen (found) + 2);
  sprintf (alc, "%s/%s", search->name, found);
  inp->filename = alc;

  /* Turn off the search_dirs_flag to prevent ldfile_open_file from
     searching for this file again.  */
  inp->search_dirs_flag = FALSE;

  free (found);

  /* Now look for the same file name, but with .sa instead of .so.  If
     found, add it to the list of input files.  */
  alc = (char *) xmalloc (strlen (inp->filename) + 1);
  strcpy (alc, inp->filename);
  strstr (alc + strlen (search->name), ".so")[2] = 'a';
  if (stat (alc, &st) != 0)
    free (alc);
  else
    {
      lang_input_statement_type *sa;

      /* Add the .sa file to the statement list just before the .so
	 file.  This is really a hack.  */
      sa = ((lang_input_statement_type *)
	    xmalloc (sizeof (lang_input_statement_type)));
      *sa = *inp;

      inp->filename = alc;
      inp->local_sym_name = alc;

      inp->header.next = (lang_statement_union_type *) sa;
      inp->next_real_file = (lang_statement_union_type *) sa;
    }
}

/* Search a directory for a .so file.  */

static char *
gld${EMULATION_NAME}_search_dir
  (const char *dirname, const char *filename, bfd_boolean *found_static)
{
  int force_maj, force_min;
  const char *dot;
  unsigned int len;
  char *alc;
  char *found;
  int max_maj, max_min;
  DIR *dir;
  struct dirent *entry;
  unsigned int dirnamelen;
  char *full_path;
  int statval;
  struct stat st;

  *found_static = FALSE;

  force_maj = -1;
  force_min = -1;
  dot = strchr (filename, '.');
  if (dot == NULL)
    {
      len = strlen (filename);
      alc = NULL;
    }
  else
    {
      force_maj = atoi (dot + 1);

      len = dot - filename;
      alc = (char *) xmalloc (len + 1);
      strncpy (alc, filename, len);
      alc[len] = '\0';
      filename = alc;

      dot = strchr (dot + 1, '.');
      if (dot != NULL)
	force_min = atoi (dot + 1);
    }

  found = NULL;
  max_maj = max_min = 0;

  dir = opendir (dirname);
  if (dir == NULL)
    return NULL;
  dirnamelen = strlen (dirname);

  while ((entry = readdir (dir)) != NULL)
    {
      const char *s;
      int found_maj, found_min;

      if (! CONST_STRNEQ (entry->d_name, "lib")
	  || strncmp (entry->d_name + 3, filename, len) != 0)
	continue;

      if (dot == NULL
	  && strcmp (entry->d_name + 3 + len, ".a") == 0)
	{
	  *found_static = TRUE;
	  continue;
	}

      /* We accept libfoo.so without a version number, even though the
	 native linker does not.  This is more convenient for packages
	 which just generate .so files for shared libraries, as on ELF
	 systems.  */
      if (! CONST_STRNEQ (entry->d_name + 3 + len, ".so"))
	continue;
      if (entry->d_name[6 + len] == '\0')
	;
      else if (entry->d_name[6 + len] == '.'
	       && ISDIGIT (entry->d_name[7 + len]))
	;
      else
	continue;

      for (s = entry->d_name + 6 + len; *s != '\0'; s++)
	if (*s != '.' && ! ISDIGIT (*s))
	  break;
      if (*s != '\0')
	continue;

      /* We've found a .so file.  Work out the major and minor
	 version numbers.  */
      found_maj = 0;
      found_min = 0;
      sscanf (entry->d_name + 3 + len, ".so.%d.%d",
	      &found_maj, &found_min);

      if ((force_maj != -1 && force_maj != found_maj)
	  || (force_min != -1 && force_min != found_min))
	continue;

      /* Make sure the file really exists (ignore broken symlinks).  */
      full_path = xmalloc (dirnamelen + 1 + strlen (entry->d_name) + 1);
      sprintf (full_path, "%s/%s", dirname, entry->d_name);
      statval = stat (full_path, &st);
      free (full_path);
      if (statval != 0)
	continue;

      /* We've found a match for the name we are searching for.  See
	 if this is the version we should use.  If the major and minor
	 versions match, we use the last entry in alphabetical order;
	 I don't know if this is how SunOS distinguishes libc.so.1.8
	 from libc.so.1.8.1, but it ought to suffice.  */
      if (found == NULL
	  || (found_maj > max_maj)
	  || (found_maj == max_maj
	      && (found_min > max_min
		  || (found_min == max_min
		      && strcmp (entry->d_name, found) > 0))))
	{
	  if (found != NULL)
	    free (found);
	  found = (char *) xmalloc (strlen (entry->d_name) + 1);
	  strcpy (found, entry->d_name);
	  max_maj = found_maj;
	  max_min = found_min;
	}
    }

  closedir (dir);

  if (alc != NULL)
    free (alc);

  return found;
}

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

static struct bfd_link_needed_list *global_needed;
static bfd_boolean global_found;

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

  /* We only need to worry about this when doing a final link.  */
  if (link_info.relocatable || link_info.shared)
    return;

  /* Get the list of files which appear in ld_need entries in dynamic
     objects included in the link.  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_sunos_get_needed_list (link_info.output_bfd, &link_info);
  for (l = needed; l != NULL; l = l->next)
    {
      struct bfd_link_needed_list *ll;
      const char *lname;
      search_dirs_type *search;

      lname = l->name;

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

      /* See if this file was included in the link explicitly.  */
      global_needed = l;
      global_found = FALSE;
      lang_for_each_input_file (gld${EMULATION_NAME}_check_needed);
      if (global_found)
	continue;

      if (! CONST_STRNEQ (lname, "-l"))
	{
	  bfd *abfd;

	  abfd = bfd_openr (lname, bfd_get_target (link_info.output_bfd));
	  if (abfd != NULL)
	    {
	      if (! bfd_check_format (abfd, bfd_object))
		{
		  (void) bfd_close (abfd);
		  abfd = NULL;
		}
	    }
	  if (abfd != NULL)
	    {
	      if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0)
		{
		  (void) bfd_close (abfd);
		  abfd = NULL;
		}
	    }
	  if (abfd != NULL)
	    {
	      /* We've found the needed dynamic object.  */
	      if (! bfd_link_add_symbols (abfd, &link_info))
		einfo ("%F%B: could not read symbols: %E\n", abfd);
	    }
	  else
	    {
	      einfo ("%P: warning: %s, needed by %B, not found\n",
		     lname, l->by);
	    }

	  continue;
	}

      lname += 2;

      /* 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 or -L, then the environment variable
	 LD_LIBRARY_PATH (native only), then (if rpath was used) the
	 linker script LIB_SEARCH_DIRS.  */
      if (gld${EMULATION_NAME}_search_needed (command_line.rpath_link,
					      lname))
	continue;
      if (command_line.rpath != NULL)
	{
	  if (gld${EMULATION_NAME}_search_needed (command_line.rpath, lname))
	    continue;
	}
      else
	{
	  for (search = search_head; search != NULL; search = search->next)
	    if (gld${EMULATION_NAME}_try_needed (search->name, lname))
	      break;
	  if (search != NULL)
	    continue;
	}
EOF
if [ "x${host}" = "x${target}" ] ; then
  case " ${EMULATION_LIBPATH} " in
  *" ${EMULATION_NAME} "*)
fragment <<EOF
      {
	const char *lib_path;

	lib_path = (const char *) getenv ("LD_LIBRARY_PATH");
	if (gld${EMULATION_NAME}_search_needed (lib_path, lname))
	  continue;
      }
EOF
  ;;
  esac
fi
fragment <<EOF
      if (command_line.rpath != NULL)
	{
	  for (search = search_head; search != NULL; search = search->next)
	    {
	      if (search->cmdline)
		continue;
	      if (gld${EMULATION_NAME}_try_needed (search->name, lname))
		break;
	    }
	  if (search != NULL)
	    continue;
	}

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

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

static bfd_boolean
gld${EMULATION_NAME}_search_needed (const char *path, const char *name)
{
  const char *s;

  if (path == NULL || *path == '\0')
    return FALSE;
  while (1)
    {
      const char *dir;
      char *dircopy;

      s = strchr (path, ':');
      if (s == NULL)
	{
	  dircopy = NULL;
	  dir = path;
	}
      else
	{
	  dircopy = (char *) xmalloc (s - path + 1);
	  memcpy (dircopy, path, s - path);
	  dircopy[s - path] = '\0';
	  dir = dircopy;
	}

      if (gld${EMULATION_NAME}_try_needed (dir, name))
	return TRUE;

      if (dircopy != NULL)
	free (dircopy);

      if (s == NULL)
	break;
      path = s + 1;
    }

  return FALSE;
}

/* This function is called for each possible directory for a needed
   dynamic object.  */

static bfd_boolean
gld${EMULATION_NAME}_try_needed (const char *dir, const char *name)
{
  char *file;
  char *alc;
  bfd_boolean ignore;
  bfd *abfd;

  file = gld${EMULATION_NAME}_search_dir (dir, name, &ignore);
  if (file == NULL)
    return FALSE;

  alc = (char *) xmalloc (strlen (dir) + strlen (file) + 2);
  sprintf (alc, "%s/%s", dir, file);
  free (file);
  abfd = bfd_openr (alc, bfd_get_target (link_info.output_bfd));
  if (abfd == NULL)
    return FALSE;
  if (! bfd_check_format (abfd, bfd_object))
    {
      (void) bfd_close (abfd);
      return FALSE;
    }
  if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0)
    {
      (void) bfd_close (abfd);
      return FALSE;
    }

  /* We've found the needed dynamic object.  */

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

  return TRUE;
}

/* See if we have already included a needed object in the link.  This
   does not have to be precise, as it does no harm to include a
   dynamic object more than once.  */

static void
gld${EMULATION_NAME}_check_needed (lang_input_statement_type *s)
{
  if (s->filename == NULL)
    return;
  if (! CONST_STRNEQ (global_needed->name, "-l"))
    {
      if (strcmp (s->filename, global_needed->name) == 0)
	global_found = TRUE;
    }
  else
    {
      const char *sname, *lname;
      const char *sdot, *ldot;
      int lmaj, lmin, smaj, smin;

      lname = global_needed->name + 2;

      sname = strrchr (s->filename, '/');
      if (sname == NULL)
	sname = s->filename;
      else
	++sname;

      if (! CONST_STRNEQ (sname, "lib"))
	return;
      sname += 3;

      ldot = strchr (lname, '.');
      if (ldot == NULL)
	ldot = lname + strlen (lname);

      sdot = strstr (sname, ".so.");
      if (sdot == NULL)
	return;

      if (sdot - sname != ldot - lname
	  || strncmp (lname, sname, sdot - sname) != 0)
	return;

      lmaj = lmin = -1;
      sscanf (ldot, ".%d.%d", &lmaj, &lmin);
      smaj = smin = -1;
      sscanf (sdot, ".so.%d.%d", &smaj, &smin);
      if ((smaj != lmaj && smaj != -1 && lmaj != -1)
	  || (smin != lmin && smin != -1 && lmin != -1))
	return;

      global_found = TRUE;
    }
}

/* We need to use static variables to pass information around the call
   to lang_for_each_statement.  Ick.  */

static const char *find_assign;
static bfd_boolean found_assign;

/* We need to use static variables to pass information around the call
   to lang_for_each_input_file.  Ick.  */

static bfd_size_type need_size;
static bfd_size_type need_entries;
static bfd_byte *need_contents;
static bfd_byte *need_pinfo;
static bfd_byte *need_pnames;

/* The size of one entry in the .need section, not including the file
   name.  */

#define NEED_ENTRY_SIZE (16)

/* 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)
{
  struct bfd_link_hash_entry *hdyn = NULL;
  asection *sneed;
  asection *srules;
  asection *sdyn;

  /* The SunOS native linker creates a shared library whenever there
     are any undefined symbols in a link, unless -e is used.  This is
     pretty weird, but we are compatible.  */
  if (! link_info.shared && ! link_info.relocatable && ! entry_from_cmdline)
    {
      struct bfd_link_hash_entry *h;

      for (h = link_info.hash->undefs; h != NULL; h = h->u.undef.next)
	{
	  if (h->type == bfd_link_hash_undefined
	      && h->u.undef.abfd != NULL
	      && (h->u.undef.abfd->flags & DYNAMIC) == 0
	      && strcmp (h->root.string, "__DYNAMIC") != 0
	      && strcmp (h->root.string, "__GLOBAL_OFFSET_TABLE_") != 0)
	    {
	      find_assign = h->root.string;
	      found_assign = FALSE;
	      lang_for_each_statement (gld${EMULATION_NAME}_find_assignment);
	      if (! found_assign)
		{
		  link_info.shared = TRUE;
		  break;
		}
	    }
	}
    }

  if (link_info.shared)
    {
      lang_output_section_statement_type *os;

      /* Set the .text section to start at 0x20, not 0x2020.  FIXME:
	 This is too magical.  */
      os = lang_output_section_statement_lookup (".text");
      if (os->addr_tree == NULL)
	os->addr_tree = exp_intop (0x20);
    }

  /* We need to create a __DYNAMIC symbol.  We don't do this in the
     linker script because we want to set the value to the start of
     the dynamic section if there is one, or to zero if there isn't
     one.  We need to create the symbol before calling
     size_dynamic_sections, although we can't set the value until
     afterward.  */
  if (! link_info.relocatable)
    {
      hdyn = bfd_link_hash_lookup (link_info.hash, "__DYNAMIC", TRUE, FALSE,
				   FALSE);
      if (hdyn == NULL)
	einfo ("%P%F: bfd_link_hash_lookup: %E\n");
      if (! bfd_sunos_record_link_assignment (link_info.output_bfd, &link_info,
					      "__DYNAMIC"))
	einfo ("%P%F: failed to record assignment to __DYNAMIC: %E\n");
    }

  /* If we are going to make any variable assignments, we need to let
     the backend linker know about them in case the variables are
     referred to by dynamic objects.  */
  lang_for_each_statement (gld${EMULATION_NAME}_find_assignment);

  /* Let the backend linker work out the sizes of any sections
     required by dynamic linking.  */
  if (! bfd_sunos_size_dynamic_sections (link_info.output_bfd, &link_info,
					 &sdyn, &sneed, &srules))
    einfo ("%P%F: failed to set dynamic section sizes: %E\n");

  if (sneed != NULL)
    {
      /* Set up the .need section.  See the description of the ld_need
	 field in include/aout/sun4.h.  */

      need_entries = 0;
      need_size = 0;

      lang_for_each_input_file (gld${EMULATION_NAME}_count_need);

      /* We should only have a .need section if we have at least one
	 dynamic object.  */
      ASSERT (need_entries != 0);

      sneed->size = need_size;
      sneed->contents = (bfd_byte *) xmalloc (need_size);

      need_contents = sneed->contents;
      need_pinfo = sneed->contents;
      need_pnames = sneed->contents + need_entries * 16;

      lang_for_each_input_file (gld${EMULATION_NAME}_set_need);

      ASSERT ((bfd_size_type) (need_pnames - sneed->contents) == need_size);
    }

  if (srules != NULL)
    {
      /* Set up the .rules section.  This is just a PATH like string
	 of the -L arguments given on the command line.  We permit the
	 user to specify the directories using the -rpath command line
	 option.  */
      if (command_line.rpath)
	{
	  srules->size = strlen (command_line.rpath);
	  srules->contents = (bfd_byte *) command_line.rpath;
	}
      else
	{
	  unsigned int size;
	  search_dirs_type *search;

	  size = 0;
	  for (search = search_head; search != NULL; search = search->next)
	    if (search->cmdline)
	      size += strlen (search->name) + 1;
	  srules->size = size;
	  if (size > 0)
	    {
	      char *p;

	      srules->contents = (bfd_byte *) xmalloc (size);
	      p = (char *) srules->contents;
	      *p = '\0';
	      for (search = search_head; search != NULL; search = search->next)
		{
		  if (search->cmdline)
		    {
		      if (p != (char *) srules->contents)
			*p++ = ':';
		      strcpy (p, search->name);
		      p += strlen (p);
		    }
		}
	    }
	}
    }

  /* We must assign a value to __DYNAMIC.  It should be zero if we are
     not doing a dynamic link, or the start of the .dynamic section if
     we are doing one.  */
  if (! link_info.relocatable)
    {
      hdyn->type = bfd_link_hash_defined;
      hdyn->u.def.value = 0;
      if (sdyn != NULL)
	hdyn->u.def.section = sdyn;
      else
	hdyn->u.def.section = bfd_abs_section_ptr;
    }

  before_allocation_default ();
}

/* This is called by the before_allocation routine via
   lang_for_each_statement.  It does one of two things: if the
   variable find_assign is set, it sets found_assign if it finds an
   assignment to that variable; otherwise it tells the backend linker
   about all assignment statements, in case they are assignments to
   symbols which are referred to by dynamic objects.  */

static void
gld${EMULATION_NAME}_find_assignment (lang_statement_union_type *s)
{
  if (s->header.type == lang_assignment_statement_enum
      && (find_assign == NULL || ! found_assign))
    gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp);
}

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

static void
gld${EMULATION_NAME}_find_exp_assignment (etree_type *exp)
{
  switch (exp->type.node_class)
    {
    case etree_assign:
      if (find_assign != NULL)
	{
	  if (strcmp (find_assign, exp->assign.dst) == 0)
	    found_assign = TRUE;
	  return;
	}

      if (strcmp (exp->assign.dst, ".") != 0)
	{
	  if (! bfd_sunos_record_link_assignment (link_info.output_bfd,
						  &link_info,
						  exp->assign.dst))
	    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;
    }
}

/* Work out the size of the .need section, and the number of entries.
   The backend will set the ld_need field of the dynamic linking
   information to point to the .need section.  See include/aout/sun4.h
   for more information.  */

static void
gld${EMULATION_NAME}_count_need (lang_input_statement_type *inp)
{
  if (inp->the_bfd != NULL
      && (inp->the_bfd->flags & DYNAMIC) != 0)
    {
      ++need_entries;
      need_size += NEED_ENTRY_SIZE;
      if (! inp->is_archive)
	need_size += strlen (inp->filename) + 1;
      else
	{
	  ASSERT (inp->local_sym_name[0] == '-'
		  && inp->local_sym_name[1] == 'l');
	  need_size += strlen (inp->local_sym_name + 2) + 1;
	}
    }
}

/* Fill in the contents of the .need section.  */

static void
gld${EMULATION_NAME}_set_need (lang_input_statement_type *inp)
{
  if (inp->the_bfd != NULL
      && (inp->the_bfd->flags & DYNAMIC) != 0)
    {
      bfd_size_type c;

      /* To really fill in the .need section contents, we need to know
	 the final file position of the section, but we don't.
	 Instead, we use offsets, and rely on the BFD backend to
	 finish the section up correctly.  FIXME: Talk about lack of
	 referential locality.  */
      bfd_put_32 (link_info.output_bfd, need_pnames - need_contents,
		  need_pinfo);
      if (! inp->is_archive)
	{
	  bfd_put_32 (link_info.output_bfd, (bfd_vma) 0, need_pinfo + 4);
	  bfd_put_16 (link_info.output_bfd, (bfd_vma) 0, need_pinfo + 8);
	  bfd_put_16 (link_info.output_bfd, (bfd_vma) 0, need_pinfo + 10);
	  strcpy ((char *) need_pnames, inp->filename);
	}
      else
	{
	  char *verstr;
	  int maj, min;

	  bfd_put_32 (link_info.output_bfd, (bfd_vma) 0x80000000,
		      need_pinfo + 4);
	  maj = 0;
	  min = 0;
	  verstr = strstr (inp->filename, ".so.");
	  if (verstr != NULL)
	    sscanf (verstr, ".so.%d.%d", &maj, &min);
	  bfd_put_16 (link_info.output_bfd, (bfd_vma) maj, need_pinfo + 8);
	  bfd_put_16 (link_info.output_bfd, (bfd_vma) min, need_pinfo + 10);
	  strcpy ((char *) need_pnames, inp->local_sym_name + 2);
	}

      c = (need_pinfo - need_contents) / NEED_ENTRY_SIZE;
      if (c + 1 >= need_entries)
	bfd_put_32 (link_info.output_bfd, (bfd_vma) 0, need_pinfo + 12);
      else
	bfd_put_32 (link_info.output_bfd, (bfd_vma) (c + 1) * NEED_ENTRY_SIZE,
		    need_pinfo + 12);

      need_pinfo += NEED_ENTRY_SIZE;
      need_pnames += strlen ((char *) need_pnames) + 1;
    }
}

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

if test -n "$COMPILE_IN"
then
# Scripts compiled in.

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

fragment <<EOF
{
  *isfile = 0;

  if (link_info.relocatable && config.build_constructors)
    return
EOF
sed $sc ldscripts/${EMULATION_NAME}.xu                     >> e${EMULATION_NAME}.c
echo '  ; else if (link_info.relocatable) return'         >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xr                     >> e${EMULATION_NAME}.c
echo '  ; else if (!config.text_read_only) return'         >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xbn                    >> e${EMULATION_NAME}.c
echo '  ; else if (!config.magic_demand_paged) return'     >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xn                     >> e${EMULATION_NAME}.c
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 (link_info.relocatable && config.build_constructors)
    return "ldscripts/${EMULATION_NAME}.xu";
  else if (link_info.relocatable)
    return "ldscripts/${EMULATION_NAME}.xr";
  else if (!config.text_read_only)
    return "ldscripts/${EMULATION_NAME}.xbn";
  else if (!config.magic_demand_paged)
    return "ldscripts/${EMULATION_NAME}.xn";
  else
    return "ldscripts/${EMULATION_NAME}.x";
}
EOF

fi

fragment <<EOF

struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
{
  gld${EMULATION_NAME}_before_parse,
  syslib_default,
  hll_default,
  after_parse_default,
  gld${EMULATION_NAME}_after_open,
  after_allocation_default,
  set_output_arch_default,
  ldemul_default_target,
  gld${EMULATION_NAME}_before_allocation,
  gld${EMULATION_NAME}_get_script,
  "${EMULATION_NAME}",
  "${OUTPUT_FORMAT}",
  finish_default,
  gld${EMULATION_NAME}_create_output_section_statements,
  NULL,	/* open dynamic archive */
  NULL,	/* place orphan */
  gld${EMULATION_NAME}_set_symbols,
  NULL,	/* parse args */
  NULL,	/* add_options */
  NULL,	/* handle_option */
  NULL,	/* unrecognized file */
  NULL,	/* list options */
  NULL,	/* recognized file */
  NULL,	/* find_potential_libraries */
  NULL	/* new_vers_pattern */
};
EOF
