# 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->maybe_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;

  after_open_default ();

  /* 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", 0, TRUE);
      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->maybe_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->maybe_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
