/* This file is is generated by a shell script.  DO NOT EDIT! */

/* 32 bit ELF emulation code for elf32ebmip
   Copyright 1991, 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2001
   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 GLD, the Gnu Linker.

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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */

#define TARGET_IS_elf32ebmip

#include "bfd.h"
#include "sysdep.h"

#include <ctype.h>

#include "bfdlink.h"

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

static void gldelf32ebmip_before_parse PARAMS ((void));
static boolean gldelf32ebmip_open_dynamic_archive
  PARAMS ((const char *, search_dirs_type *, lang_input_statement_type *));
static void gldelf32ebmip_after_open PARAMS ((void));
static void gldelf32ebmip_check_needed
  PARAMS ((lang_input_statement_type *));
static void gldelf32ebmip_stat_needed
  PARAMS ((lang_input_statement_type *));
static boolean gldelf32ebmip_search_needed
  PARAMS ((const char *, const char *));
static boolean gldelf32ebmip_try_needed PARAMS ((const char *));
static void gldelf32ebmip_before_allocation PARAMS ((void));
static void gldelf32ebmip_find_statement_assignment
  PARAMS ((lang_statement_union_type *));
static void gldelf32ebmip_find_exp_assignment PARAMS ((etree_type *));
static boolean gldelf32ebmip_place_orphan
  PARAMS ((lang_input_statement_type *, asection *));
static void gldelf32ebmip_place_section
  PARAMS ((lang_statement_union_type *));
static char *gldelf32ebmip_get_script PARAMS ((int *isfile));

static void
gldelf32ebmip_before_parse()
{
  ldfile_output_architecture = bfd_arch_mips;
  config.dynamic_link = true;
}

/* Try to open a dynamic archive.  This is where we know that ELF
   dynamic libraries have an extension of .so.  */

static boolean
gldelf32ebmip_open_dynamic_archive (arch, search, entry)
     const char *arch;
     search_dirs_type *search;
     lang_input_statement_type *entry;
{
  const char *filename;
  char *string;

  if (! entry->is_archive)
    return false;

  filename = entry->filename;

  string = (char *) xmalloc (strlen (search->name)
			     + strlen (filename)
			     + strlen (arch)
			     + sizeof "/lib.so");

  sprintf (string, "%s/lib%s%s.so", search->name, filename, arch);

  if (! 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)
    {
      char *needed_name;

      ASSERT (entry->is_archive && entry->search_dirs_flag);
      needed_name = (char *) xmalloc (strlen (filename)
				      + strlen (arch)
				      + sizeof "lib.so");
      sprintf (needed_name, "lib%s%s.so", filename, arch);
      bfd_elf_set_dt_needed_name (entry->the_bfd, needed_name);
    }

  return true;
}


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

static struct bfd_link_needed_list *global_needed;
static struct stat global_stat;
static boolean global_found;

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

static void
gldelf32ebmip_after_open ()
{
  struct bfd_link_needed_list *needed, *l;

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

  /* 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 (output_bfd, &link_info);
  for (l = needed; l != NULL; l = l->next)
    {
      struct bfd_link_needed_list *ll;
      const char *lib_path;
      size_t len;
      search_dirs_type *search;

      /* If we've already seen this file, skip it.  */
      for (ll = needed; ll != l; ll = ll->next)
	if (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 = false;
      lang_for_each_input_file (gldelf32ebmip_check_needed);
      if (global_found)
	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 linker script
	 LIB_SEARCH_DIRS.  We do not search using the -L arguments.  */
      if (gldelf32ebmip_search_needed (command_line.rpath_link,
					      l->name))
	continue;
      if (gldelf32ebmip_search_needed (command_line.rpath, l->name))
	continue;
      if (command_line.rpath_link == NULL
	  && command_line.rpath == NULL)
	{
	  lib_path = (const char *) getenv ("LD_RUN_PATH");
	  if (gldelf32ebmip_search_needed (lib_path, l->name))
	    continue;
	}
      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);
	  if (gldelf32ebmip_try_needed (filename))
	    break;
	  free (filename);
	}
      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 boolean
gldelf32ebmip_search_needed (path, name)
     const char *path;
     const char *name;
{
  const char *s;
  size_t len;

  if (path == NULL || *path == '\0')
    return false;
  len = strlen (name);
  while (1)
    {
      char *filename, *sset;

      s = strchr (path, ':');
      if (s == NULL)
	s = path + strlen (path);

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

      if (gldelf32ebmip_try_needed (filename))
	return true;

      free (filename);

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

  return false;	  
}

/* This function is called for each possible name for a dynamic object
   named by a DT_NEEDED entry.  */

static boolean
gldelf32ebmip_try_needed (name)
     const char *name;
{
  bfd *abfd;

  abfd = bfd_openr (name, bfd_get_target (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 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);
  global_found = false;
  lang_for_each_input_file (gldelf32ebmip_stat_needed);
  if (global_found)
    {
      /* Return true to indicate that we found the file, even though
         we aren't going to do anything with it.  */
      return true;
    }

  /* Tell the ELF backend that don't want the output file to have a
     DT_NEEDED entry for this file.  */
  bfd_elf_set_dt_needed_name (abfd, "");

  /* 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 an input file matches a DT_NEEDED entry by name.  */

static void
gldelf32ebmip_check_needed (s)
     lang_input_statement_type *s;
{
  if (global_found)
    return;

  if (s->filename != NULL
      && strcmp (s->filename, global_needed->name) == 0)
    {
      global_found = true;
      return;
    }

  if (s->the_bfd != NULL)
    {
      const char *soname;

      soname = bfd_elf_get_dt_soname (s->the_bfd);
      if (soname != NULL
	  && strcmp (soname, global_needed->name) == 0)
	{
	  global_found = true;
	  return;
	}
    }
	  
  if (s->search_dirs_flag
      && s->filename != NULL
      && strchr (global_needed->name, '/') == NULL)
    {
      const char *f;

      f = strrchr (s->filename, '/');
      if (f != NULL
	  && strcmp (f + 1, global_needed->name) == 0)
	{
	  global_found = true;
	  return;
	}
    }
}

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

static void
gldelf32ebmip_stat_needed (s)
     lang_input_statement_type *s;
{
  struct stat st;
  const char *suffix;
  const char *soname;
  const char *f;

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

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

  if (st.st_dev == global_stat.st_dev
      && st.st_ino == global_stat.st_ino)
    {
      global_found = true;
      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
     hueristic 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 = s->filename;

  f = strrchr (soname, '/');
  if (f != NULL)
    ++f;
  else
    f = soname;

  if (strncmp (f, 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, f);
}

/* This is called after the sections have been attached to output
   sections, but before any sizes or addresses have been set.  */

static void
gldelf32ebmip_before_allocation ()
{
  const char *rpath;
  asection *sinterp;

  /* 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 (gldelf32ebmip_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");
  if (! (bfd_elf32_size_dynamic_sections
	 (output_bfd, command_line.soname, rpath,
	  command_line.export_dynamic, command_line.filter_shlib,
	  (const char * const *) command_line.auxiliary_filters,
	  &link_info, &sinterp, lang_elf_version_info)))
    einfo (_("%P%F: failed to set dynamic section sizes: %E\n"));

  /* 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->_raw_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;
	boolean ret;

	if (is->just_syms_flag)
	  continue;

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

	sz = bfd_section_size (is->the_bfd, s);
	msg = 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';
	ret = link_info.callbacks->warning (&link_info, msg,
					    (const char *) NULL,
					    is->the_bfd, (asection *) NULL,
					    (bfd_vma) 0);
	ASSERT (ret);
	free (msg);

	/* Clobber the section size, so that we don't waste copying the
	   warning into the output file.  */
	s->_raw_size = 0;
      }
  }
}

/* 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
gldelf32ebmip_find_statement_assignment (s)
     lang_statement_union_type *s;
{
  if (s->header.type == lang_assignment_statement_enum)
    gldelf32ebmip_find_exp_assignment (s->assignment_statement.exp);
}

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

static void
gldelf32ebmip_find_exp_assignment (exp)
     etree_type *exp;
{
  struct bfd_link_hash_entry *h;

  switch (exp->type.node_class)
    {
    case etree_provide:
    case etree_provided:
      h = bfd_link_hash_lookup (link_info.hash, exp->assign.dst,
				false, false, false);
      if (h == NULL)
	break;

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

      /* Fall through.  */
    case etree_assign:
      if (strcmp (exp->assign.dst, ".") != 0)
	{
	  if (! (bfd_elf32_record_link_assignment
		 (output_bfd, &link_info, exp->assign.dst,
		  exp->type.node_class != etree_assign ? true : false)))
	    einfo (_("%P%F: failed to record assignment to %s: %E\n"),
		   exp->assign.dst);
	}
      gldelf32ebmip_find_exp_assignment (exp->assign.src);
      break;

    case etree_binary:
      gldelf32ebmip_find_exp_assignment (exp->binary.lhs);
      gldelf32ebmip_find_exp_assignment (exp->binary.rhs);
      break;

    case etree_trinary:
      gldelf32ebmip_find_exp_assignment (exp->trinary.cond);
      gldelf32ebmip_find_exp_assignment (exp->trinary.lhs);
      gldelf32ebmip_find_exp_assignment (exp->trinary.rhs);
      break;

    case etree_unary:
      gldelf32ebmip_find_exp_assignment (exp->unary.child);
      break;

    default:
      break;
    }
}

/* Place an orphan section.  We use this to put random SHF_ALLOC
   sections in the right segment.  */

static asection *hold_section;
static lang_output_section_statement_type *hold_use;
static lang_output_section_statement_type *hold_text;
static lang_output_section_statement_type *hold_rodata;
static lang_output_section_statement_type *hold_data;
static lang_output_section_statement_type *hold_bss;
static lang_output_section_statement_type *hold_rel;

/*ARGSUSED*/
static boolean
gldelf32ebmip_place_orphan (file, s)
     lang_input_statement_type *file;
     asection *s;
{
  lang_output_section_statement_type *place;
  asection *snew, **pps;
  lang_statement_list_type *old;
  lang_statement_list_type add;
  etree_type *address;
  const char *secname, *ps;
  lang_output_section_statement_type *os;

  if ((s->flags & SEC_ALLOC) == 0)
    return false;

  /* Look through the script to see where to place this section.  */
  hold_section = s;
  hold_use = NULL;
  lang_for_each_statement (gldelf32ebmip_place_section);

  if (hold_use != NULL)
    {
      /* We have already placed a section with this name.  */
      wild_doit (&hold_use->children, s, hold_use, file);
      return true;
    }

  secname = bfd_get_section_name (s->owner, s);

  /* 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 (! link_info.shared
      && ! link_info.relocateable
      && strncmp (secname, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0
      && hold_text != NULL)
    {
      wild_doit (&hold_text->children, s, hold_text, file);
      return true;
    }

  /* Decide which segment the section should go in based on the
     section name and section flags.  */
  place = NULL;
  if ((s->flags & SEC_HAS_CONTENTS) == 0
      && hold_bss != NULL)
    place = hold_bss;
  else if ((s->flags & SEC_READONLY) == 0
	   && hold_data != NULL)
    place = hold_data;
  else if (strncmp (secname, ".rel", 4) == 0
	   && hold_rel != NULL)
    place = hold_rel;
  else if ((s->flags & SEC_CODE) == 0
	   && (s->flags & SEC_READONLY) != 0
	   && hold_rodata != NULL)
    place = hold_rodata;
  else if ((s->flags & SEC_READONLY) != 0
	   && hold_text != NULL)
    place = hold_text;
  if (place == NULL)
    return false;

  /* Create the section in the output file, and put it in the right
     place.  This shuffling is to make the output file look neater.  */
  snew = bfd_make_section (output_bfd, secname);
  if (snew == NULL)
      einfo (_("%P%F: output format %s cannot represent section called %s\n"),
	     output_bfd->xvec->name, secname);
  if (place->bfd_section != NULL)
    {
      for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
	;
      *pps = snew->next;
      snew->next = place->bfd_section->next;
      place->bfd_section->next = snew;
    }

  /* Start building a list of statements for this section.  */
  old = stat_ptr;
  stat_ptr = &add;
  lang_list_init (stat_ptr);

  /* If the name of the section is representable in C, then create
     symbols to mark the start and the end of the section.  */
  for (ps = secname; *ps != '\0'; ps++)
    if (! isalnum (*ps) && *ps != '_')
      break;
  if (*ps == '\0' && config.build_constructors)
    {
      char *symname;

      symname = (char *) xmalloc (ps - secname + sizeof "__start_");
      sprintf (symname, "__start_%s", secname);
      lang_add_assignment (exp_assop ('=', symname,
				      exp_unop (ALIGN_K,
						exp_intop ((bfd_vma) 1
							   << s->alignment_power))));
    }

  if (! link_info.relocateable)
    address = NULL;
  else
    address = exp_intop ((bfd_vma) 0);

  lang_enter_output_section_statement (secname, address, 0,
				       (bfd_vma) 0,
				       (etree_type *) NULL,
				       (etree_type *) NULL,
				       (etree_type *) NULL);

  os = lang_output_section_statement_lookup (secname);
  wild_doit (&os->children, s, os, file);

  lang_leave_output_section_statement
    ((bfd_vma) 0, "*default*",
     (struct lang_output_section_phdr_list *) NULL, "*default*");
  stat_ptr = &add;

  if (*ps == '\0' && config.build_constructors)
    {
      char *symname;

      symname = (char *) xmalloc (ps - secname + sizeof "__stop_");
      sprintf (symname, "__stop_%s", secname);
      lang_add_assignment (exp_assop ('=', symname,
				      exp_nameop (NAME, ".")));
    }

  /* Now stick the new statement list right after PLACE.  */
  *add.tail = place->header.next;
  place->header.next = add.head;

  stat_ptr = old;

  return true;
}

static void
gldelf32ebmip_place_section (s)
     lang_statement_union_type *s;
{
  lang_output_section_statement_type *os;

  if (s->header.type != lang_output_section_statement_enum)
    return;

  os = &s->output_section_statement;

  if (strcmp (os->name, hold_section->name) == 0)
    hold_use = os;

  if (strcmp (os->name, ".text") == 0)
    hold_text = os;
  else if (strcmp (os->name, ".rodata") == 0)
    hold_rodata = os;
  else if (strcmp (os->name, ".data") == 0)
    hold_data = os;
  else if (strcmp (os->name, ".bss") == 0)
    hold_bss = os;
  else if (hold_rel == NULL
	   && os->bfd_section != NULL
	   && strncmp (os->name, ".rel", 4) == 0)
    hold_rel = os;
}

static char *
gldelf32ebmip_get_script(isfile)
     int *isfile;
{			     
  *isfile = 0;

  if (link_info.relocateable == true && config.build_constructors == true)
    return "OUTPUT_FORMAT(\"elf32-bigmips\", \"elf32-bigmips\",\n\
	      \"elf32-littlemips\")\n\
OUTPUT_ARCH(mips)\n\
ENTRY(_start)\n\
 /* For some reason, the Solaris linker makes bad executables\n\
  if gld -r is used and the intermediate file has sections starting\n\
  at non-zero addresses.  Could be a Solaris ld bug, could be a GNU ld\n\
  bug.  But for now assigning the zero vmas works.  */\n\
SECTIONS\n\
{\n\
  /* Read-only sections, merged into text segment: */\n\
  .interp   0 : { *(.interp) 	}\n\
  .reginfo     0 : { *(.reginfo) }\n\
  .dynamic     0 : { *(.dynamic) }\n\
  .dynstr      0 : { *(.dynstr)		}\n\
  .dynsym      0 : { *(.dynsym)		}\n\
  .hash        0 : { *(.hash)		}\n\
  .rel.text    0 : { *(.rel.text)		}\n\
  .rela.text   0 : { *(.rela.text) 	}\n\
  .rel.data    0 : { *(.rel.data)		}\n\
  .rela.data   0 : { *(.rela.data) 	}\n\
  .rel.rodata  0 : { *(.rel.rodata) 	}\n\
  .rela.rodata 0 : { *(.rela.rodata) 	}\n\
  .rel.got     0 : { *(.rel.got)		}\n\
  .rela.got    0 : { *(.rela.got)		}\n\
  .rel.ctors   0 : { *(.rel.ctors)	}\n\
  .rela.ctors  0 : { *(.rela.ctors)	}\n\
  .rel.dtors   0 : { *(.rel.dtors)	}\n\
  .rela.dtors  0 : { *(.rela.dtors)	}\n\
  .rel.init    0 : { *(.rel.init)	}\n\
  .rela.init   0 : { *(.rela.init)	}\n\
  .rel.fini    0 : { *(.rel.fini)	}\n\
  .rela.fini   0 : { *(.rela.fini)	}\n\
  .rel.bss     0 : { *(.rel.bss)		}\n\
  .rela.bss    0 : { *(.rela.bss)		}\n\
  .rel.plt     0 : { *(.rel.plt)		}\n\
  .rela.plt    0 : { *(.rela.plt)		}\n\
  .rodata  0 : { *(.rodata)  }\n\
  .rodata1 0 : { *(.rodata1) }\n\
  .init        0 : { *(.init)	} =0\n\
  .text    0 :\n\
  {\n\
    *(.text)\n\
    *(.stub)\n\
    /* .gnu.warning sections are handled specially by elf32.em.  */\n\
    *(.gnu.warning)\n\
  } =0\n\
  .fini    0 : { *(.fini)    } =0\n\
  /* Adjust the address for the data segment.  We want to adjust up to\n\
     the same address within the page on the next page up.  It would\n\
     be more correct to do this:\n\
     The current expression does not correctly handle the case of a\n\
     text segment ending precisely at the end of a page; it causes the\n\
     data segment to skip a page.  The above expression does not have\n\
     this problem, but it will currently (2/95) cause BFD to allocate\n\
     a single segment, combining both text and data, for this case.\n\
     This will prevent the text segment from being shared among\n\
     multiple executions of the program; I think that is more\n\
     important than losing a page of the virtual address space (note\n\
     that no actual memory is lost; the page which is skipped can not\n\
     be referenced).  */\n\
  .data  0 :\n\
  {\n\
    *(.data)\n\
    CONSTRUCTORS\n\
  }\n\
  .data1 0 : { *(.data1) }\n\
  .ctors       0 : { *(.ctors)   }\n\
  .dtors       0 : { *(.dtors)   }\n\
  .got         0 :\n\
  {\n\
    *(.got.plt) *(.got)\n\
   }\n\
  /* We want the small data sections together, so single-instruction offsets\n\
     can access them all, and initialized data all before uninitialized, so\n\
     we can shorten the on-disk segment size.  */\n\
  .sdata   0 : { *(.sdata) }\n\
  .sbss    0 : { *(.sbss) *(.scommon) }\n\
  .bss     0 :\n\
  {\n\
   *(.dynbss)\n\
   *(.bss)\n\
   *(COMMON)\n\
  }\n\
  /* These are needed for ELF backends which have not yet been\n\
     converted to the new style linker.  */\n\
  .stab 0 : { *(.stab) }\n\
  .stabstr 0 : { *(.stabstr) }\n\
  /* DWARF debug sections.\n\
     Symbols in the .debug DWARF section are relative to the beginning of the\n\
     section so we begin .debug at 0.  It's not clear yet what needs to happen\n\
     for the others.   */\n\
  .debug          0 : { *(.debug) }\n\
  .debug_srcinfo  0 : { *(.debug_srcinfo) }\n\
  .debug_aranges  0 : { *(.debug_aranges) }\n\
  .debug_pubnames 0 : { *(.debug_pubnames) }\n\
  .debug_sfnames  0 : { *(.debug_sfnames) }\n\
  .line           0 : { *(.line) }\n\
  /* These must appear regardless of .  */\n\
  .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }\n\
  .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }\n\
}\n\n";
  else if (link_info.relocateable == true)
    return "OUTPUT_FORMAT(\"elf32-bigmips\", \"elf32-bigmips\",\n\
	      \"elf32-littlemips\")\n\
OUTPUT_ARCH(mips)\n\
ENTRY(_start)\n\
 /* For some reason, the Solaris linker makes bad executables\n\
  if gld -r is used and the intermediate file has sections starting\n\
  at non-zero addresses.  Could be a Solaris ld bug, could be a GNU ld\n\
  bug.  But for now assigning the zero vmas works.  */\n\
SECTIONS\n\
{\n\
  /* Read-only sections, merged into text segment: */\n\
  .interp   0 : { *(.interp) 	}\n\
  .reginfo     0 : { *(.reginfo) }\n\
  .dynamic     0 : { *(.dynamic) }\n\
  .dynstr      0 : { *(.dynstr)		}\n\
  .dynsym      0 : { *(.dynsym)		}\n\
  .hash        0 : { *(.hash)		}\n\
  .rel.text    0 : { *(.rel.text)		}\n\
  .rela.text   0 : { *(.rela.text) 	}\n\
  .rel.data    0 : { *(.rel.data)		}\n\
  .rela.data   0 : { *(.rela.data) 	}\n\
  .rel.rodata  0 : { *(.rel.rodata) 	}\n\
  .rela.rodata 0 : { *(.rela.rodata) 	}\n\
  .rel.got     0 : { *(.rel.got)		}\n\
  .rela.got    0 : { *(.rela.got)		}\n\
  .rel.ctors   0 : { *(.rel.ctors)	}\n\
  .rela.ctors  0 : { *(.rela.ctors)	}\n\
  .rel.dtors   0 : { *(.rel.dtors)	}\n\
  .rela.dtors  0 : { *(.rela.dtors)	}\n\
  .rel.init    0 : { *(.rel.init)	}\n\
  .rela.init   0 : { *(.rela.init)	}\n\
  .rel.fini    0 : { *(.rel.fini)	}\n\
  .rela.fini   0 : { *(.rela.fini)	}\n\
  .rel.bss     0 : { *(.rel.bss)		}\n\
  .rela.bss    0 : { *(.rela.bss)		}\n\
  .rel.plt     0 : { *(.rel.plt)		}\n\
  .rela.plt    0 : { *(.rela.plt)		}\n\
  .rodata  0 : { *(.rodata)  }\n\
  .rodata1 0 : { *(.rodata1) }\n\
  .init        0 : { *(.init)	} =0\n\
  .text    0 :\n\
  {\n\
    *(.text)\n\
    *(.stub)\n\
    /* .gnu.warning sections are handled specially by elf32.em.  */\n\
    *(.gnu.warning)\n\
  } =0\n\
  .fini    0 : { *(.fini)    } =0\n\
  /* Adjust the address for the data segment.  We want to adjust up to\n\
     the same address within the page on the next page up.  It would\n\
     be more correct to do this:\n\
     The current expression does not correctly handle the case of a\n\
     text segment ending precisely at the end of a page; it causes the\n\
     data segment to skip a page.  The above expression does not have\n\
     this problem, but it will currently (2/95) cause BFD to allocate\n\
     a single segment, combining both text and data, for this case.\n\
     This will prevent the text segment from being shared among\n\
     multiple executions of the program; I think that is more\n\
     important than losing a page of the virtual address space (note\n\
     that no actual memory is lost; the page which is skipped can not\n\
     be referenced).  */\n\
  .data  0 :\n\
  {\n\
    *(.data)\n\
  }\n\
  .data1 0 : { *(.data1) }\n\
  .ctors       0 : { *(.ctors)   }\n\
  .dtors       0 : { *(.dtors)   }\n\
  .got         0 :\n\
  {\n\
    *(.got.plt) *(.got)\n\
   }\n\
  /* We want the small data sections together, so single-instruction offsets\n\
     can access them all, and initialized data all before uninitialized, so\n\
     we can shorten the on-disk segment size.  */\n\
  .sdata   0 : { *(.sdata) }\n\
  .sbss    0 : { *(.sbss) *(.scommon) }\n\
  .bss     0 :\n\
  {\n\
   *(.dynbss)\n\
   *(.bss)\n\
   *(COMMON)\n\
  }\n\
  /* These are needed for ELF backends which have not yet been\n\
     converted to the new style linker.  */\n\
  .stab 0 : { *(.stab) }\n\
  .stabstr 0 : { *(.stabstr) }\n\
  /* DWARF debug sections.\n\
     Symbols in the .debug DWARF section are relative to the beginning of the\n\
     section so we begin .debug at 0.  It's not clear yet what needs to happen\n\
     for the others.   */\n\
  .debug          0 : { *(.debug) }\n\
  .debug_srcinfo  0 : { *(.debug_srcinfo) }\n\
  .debug_aranges  0 : { *(.debug_aranges) }\n\
  .debug_pubnames 0 : { *(.debug_pubnames) }\n\
  .debug_sfnames  0 : { *(.debug_sfnames) }\n\
  .line           0 : { *(.line) }\n\
  /* These must appear regardless of .  */\n\
  .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }\n\
  .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }\n\
}\n\n";
  else if (!config.text_read_only)
    return "OUTPUT_FORMAT(\"elf32-bigmips\", \"elf32-bigmips\",\n\
	      \"elf32-littlemips\")\n\
OUTPUT_ARCH(mips)\n\
ENTRY(_start)\n\
 SEARCH_DIR(/usr/local/mips-elf/lib);\n\
/* Do we need any of these for elf?\n\
   __DYNAMIC = 0;    */\n\
SECTIONS\n\
{\n\
  /* Read-only sections, merged into text segment: */\n\
  . = 0x0400000;\n\
  .interp     : { *(.interp) 	}\n\
  .reginfo       : { *(.reginfo) }\n\
  .dynamic       : { *(.dynamic) }\n\
  .dynstr        : { *(.dynstr)		}\n\
  .dynsym        : { *(.dynsym)		}\n\
  .hash          : { *(.hash)		}\n\
  .rel.text      : { *(.rel.text)		}\n\
  .rela.text     : { *(.rela.text) 	}\n\
  .rel.data      : { *(.rel.data)		}\n\
  .rela.data     : { *(.rela.data) 	}\n\
  .rel.rodata    : { *(.rel.rodata) 	}\n\
  .rela.rodata   : { *(.rela.rodata) 	}\n\
  .rel.got       : { *(.rel.got)		}\n\
  .rela.got      : { *(.rela.got)		}\n\
  .rel.ctors     : { *(.rel.ctors)	}\n\
  .rela.ctors    : { *(.rela.ctors)	}\n\
  .rel.dtors     : { *(.rel.dtors)	}\n\
  .rela.dtors    : { *(.rela.dtors)	}\n\
  .rel.init      : { *(.rel.init)	}\n\
  .rela.init     : { *(.rela.init)	}\n\
  .rel.fini      : { *(.rel.fini)	}\n\
  .rela.fini     : { *(.rela.fini)	}\n\
  .rel.bss       : { *(.rel.bss)		}\n\
  .rela.bss      : { *(.rela.bss)		}\n\
  .rel.plt       : { *(.rel.plt)		}\n\
  .rela.plt      : { *(.rela.plt)		}\n\
  .rodata    : { *(.rodata)  }\n\
  .rodata1   : { *(.rodata1) }\n\
  .init          : { *(.init)	} =0\n\
  .text      :\n\
  {\n\
    _ftext = . ;\n\
    *(.text)\n\
    *(.stub)\n\
    /* .gnu.warning sections are handled specially by elf32.em.  */\n\
    *(.gnu.warning)\n\
  } =0\n\
  _etext = .;\n\
  PROVIDE (etext = .);\n\
  .fini      : { *(.fini)    } =0\n\
  /* Adjust the address for the data segment.  We want to adjust up to\n\
     the same address within the page on the next page up.  It would\n\
     be more correct to do this:\n\
       . = .;\n\
     The current expression does not correctly handle the case of a\n\
     text segment ending precisely at the end of a page; it causes the\n\
     data segment to skip a page.  The above expression does not have\n\
     this problem, but it will currently (2/95) cause BFD to allocate\n\
     a single segment, combining both text and data, for this case.\n\
     This will prevent the text segment from being shared among\n\
     multiple executions of the program; I think that is more\n\
     important than losing a page of the virtual address space (note\n\
     that no actual memory is lost; the page which is skipped can not\n\
     be referenced).  */\n\
  . += . - 0x0400000;\n\
  .data    :\n\
  {\n\
    _fdata = . ;\n\
    *(.data)\n\
    CONSTRUCTORS\n\
  }\n\
  .data1   : { *(.data1) }\n\
  .ctors         : { *(.ctors)   }\n\
  .dtors         : { *(.dtors)   }\n\
  _gp = ALIGN(16) + 0x7ff0;\n\
  .got           :\n\
  {\n\
    *(.got.plt) *(.got)\n\
   }\n\
  /* We want the small data sections together, so single-instruction offsets\n\
     can access them all, and initialized data all before uninitialized, so\n\
     we can shorten the on-disk segment size.  */\n\
  .sdata     : { *(.sdata) }\n\
  .lit8 : { *(.lit8) }\n\
  .lit4 : { *(.lit4) }\n\
  _edata  =  .;\n\
  PROVIDE (edata = .);\n\
  __bss_start = .;\n\
  _fbss = .;\n\
  .sbss      : { *(.sbss) *(.scommon) }\n\
  .bss       :\n\
  {\n\
   *(.dynbss)\n\
   *(.bss)\n\
   *(COMMON)\n\
  }\n\
  _end = . ;\n\
  PROVIDE (end = .);\n\
  /* These are needed for ELF backends which have not yet been\n\
     converted to the new style linker.  */\n\
  .stab 0 : { *(.stab) }\n\
  .stabstr 0 : { *(.stabstr) }\n\
  /* DWARF debug sections.\n\
     Symbols in the .debug DWARF section are relative to the beginning of the\n\
     section so we begin .debug at 0.  It's not clear yet what needs to happen\n\
     for the others.   */\n\
  .debug          0 : { *(.debug) }\n\
  .debug_srcinfo  0 : { *(.debug_srcinfo) }\n\
  .debug_aranges  0 : { *(.debug_aranges) }\n\
  .debug_pubnames 0 : { *(.debug_pubnames) }\n\
  .debug_sfnames  0 : { *(.debug_sfnames) }\n\
  .line           0 : { *(.line) }\n\
  /* These must appear regardless of  .  */\n\
  .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }\n\
  .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }\n\
}\n\n";
  else if (!config.magic_demand_paged)
    return "OUTPUT_FORMAT(\"elf32-bigmips\", \"elf32-bigmips\",\n\
	      \"elf32-littlemips\")\n\
OUTPUT_ARCH(mips)\n\
ENTRY(_start)\n\
 SEARCH_DIR(/usr/local/mips-elf/lib);\n\
/* Do we need any of these for elf?\n\
   __DYNAMIC = 0;    */\n\
SECTIONS\n\
{\n\
  /* Read-only sections, merged into text segment: */\n\
  . = 0x0400000;\n\
  .interp     : { *(.interp) 	}\n\
  .reginfo       : { *(.reginfo) }\n\
  .dynamic       : { *(.dynamic) }\n\
  .dynstr        : { *(.dynstr)		}\n\
  .dynsym        : { *(.dynsym)		}\n\
  .hash          : { *(.hash)		}\n\
  .rel.text      : { *(.rel.text)		}\n\
  .rela.text     : { *(.rela.text) 	}\n\
  .rel.data      : { *(.rel.data)		}\n\
  .rela.data     : { *(.rela.data) 	}\n\
  .rel.rodata    : { *(.rel.rodata) 	}\n\
  .rela.rodata   : { *(.rela.rodata) 	}\n\
  .rel.got       : { *(.rel.got)		}\n\
  .rela.got      : { *(.rela.got)		}\n\
  .rel.ctors     : { *(.rel.ctors)	}\n\
  .rela.ctors    : { *(.rela.ctors)	}\n\
  .rel.dtors     : { *(.rel.dtors)	}\n\
  .rela.dtors    : { *(.rela.dtors)	}\n\
  .rel.init      : { *(.rel.init)	}\n\
  .rela.init     : { *(.rela.init)	}\n\
  .rel.fini      : { *(.rel.fini)	}\n\
  .rela.fini     : { *(.rela.fini)	}\n\
  .rel.bss       : { *(.rel.bss)		}\n\
  .rela.bss      : { *(.rela.bss)		}\n\
  .rel.plt       : { *(.rel.plt)		}\n\
  .rela.plt      : { *(.rela.plt)		}\n\
  .rodata    : { *(.rodata)  }\n\
  .rodata1   : { *(.rodata1) }\n\
  .init          : { *(.init)	} =0\n\
  .text      :\n\
  {\n\
    _ftext = . ;\n\
    *(.text)\n\
    *(.stub)\n\
    /* .gnu.warning sections are handled specially by elf32.em.  */\n\
    *(.gnu.warning)\n\
  } =0\n\
  _etext = .;\n\
  PROVIDE (etext = .);\n\
  .fini      : { *(.fini)    } =0\n\
  /* Adjust the address for the data segment.  We want to adjust up to\n\
     the same address within the page on the next page up.  It would\n\
     be more correct to do this:\n\
       . = 0x10000000;\n\
     The current expression does not correctly handle the case of a\n\
     text segment ending precisely at the end of a page; it causes the\n\
     data segment to skip a page.  The above expression does not have\n\
     this problem, but it will currently (2/95) cause BFD to allocate\n\
     a single segment, combining both text and data, for this case.\n\
     This will prevent the text segment from being shared among\n\
     multiple executions of the program; I think that is more\n\
     important than losing a page of the virtual address space (note\n\
     that no actual memory is lost; the page which is skipped can not\n\
     be referenced).  */\n\
  . += 0x10000000 - 0x0400000;\n\
  .data    :\n\
  {\n\
    _fdata = . ;\n\
    *(.data)\n\
    CONSTRUCTORS\n\
  }\n\
  .data1   : { *(.data1) }\n\
  .ctors         : { *(.ctors)   }\n\
  .dtors         : { *(.dtors)   }\n\
  _gp = ALIGN(16) + 0x7ff0;\n\
  .got           :\n\
  {\n\
    *(.got.plt) *(.got)\n\
   }\n\
  /* We want the small data sections together, so single-instruction offsets\n\
     can access them all, and initialized data all before uninitialized, so\n\
     we can shorten the on-disk segment size.  */\n\
  .sdata     : { *(.sdata) }\n\
  .lit8 : { *(.lit8) }\n\
  .lit4 : { *(.lit4) }\n\
  _edata  =  .;\n\
  PROVIDE (edata = .);\n\
  __bss_start = .;\n\
  _fbss = .;\n\
  .sbss      : { *(.sbss) *(.scommon) }\n\
  .bss       :\n\
  {\n\
   *(.dynbss)\n\
   *(.bss)\n\
   *(COMMON)\n\
  }\n\
  _end = . ;\n\
  PROVIDE (end = .);\n\
  /* These are needed for ELF backends which have not yet been\n\
     converted to the new style linker.  */\n\
  .stab 0 : { *(.stab) }\n\
  .stabstr 0 : { *(.stabstr) }\n\
  /* DWARF debug sections.\n\
     Symbols in the .debug DWARF section are relative to the beginning of the\n\
     section so we begin .debug at 0.  It's not clear yet what needs to happen\n\
     for the others.   */\n\
  .debug          0 : { *(.debug) }\n\
  .debug_srcinfo  0 : { *(.debug_srcinfo) }\n\
  .debug_aranges  0 : { *(.debug_aranges) }\n\
  .debug_pubnames 0 : { *(.debug_pubnames) }\n\
  .debug_sfnames  0 : { *(.debug_sfnames) }\n\
  .line           0 : { *(.line) }\n\
  /* These must appear regardless of  .  */\n\
  .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }\n\
  .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }\n\
}\n\n";
  else if (link_info.shared)
    return "OUTPUT_FORMAT(\"elf32-bigmips\", \"elf32-bigmips\",\n\
	      \"elf32-littlemips\")\n\
OUTPUT_ARCH(mips)\n\
ENTRY(_start)\n\
 SEARCH_DIR(/usr/local/mips-elf/lib);\n\
/* Do we need any of these for elf?\n\
   __DYNAMIC = 0;    */\n\
SECTIONS\n\
{\n\
  /* Read-only sections, merged into text segment: */\n\
  . = 0x5ffe0000 + SIZEOF_HEADERS;\n\
  .reginfo       : { *(.reginfo) }\n\
  .dynamic       : { *(.dynamic) }\n\
  .dynstr        : { *(.dynstr)		}\n\
  .dynsym        : { *(.dynsym)		}\n\
  .hash          : { *(.hash)		}\n\
  .rel.text      : { *(.rel.text)		}\n\
  .rela.text     : { *(.rela.text) 	}\n\
  .rel.data      : { *(.rel.data)		}\n\
  .rela.data     : { *(.rela.data) 	}\n\
  .rel.rodata    : { *(.rel.rodata) 	}\n\
  .rela.rodata   : { *(.rela.rodata) 	}\n\
  .rel.got       : { *(.rel.got)		}\n\
  .rela.got      : { *(.rela.got)		}\n\
  .rel.ctors     : { *(.rel.ctors)	}\n\
  .rela.ctors    : { *(.rela.ctors)	}\n\
  .rel.dtors     : { *(.rel.dtors)	}\n\
  .rela.dtors    : { *(.rela.dtors)	}\n\
  .rel.init      : { *(.rel.init)	}\n\
  .rela.init     : { *(.rela.init)	}\n\
  .rel.fini      : { *(.rel.fini)	}\n\
  .rela.fini     : { *(.rela.fini)	}\n\
  .rel.bss       : { *(.rel.bss)		}\n\
  .rela.bss      : { *(.rela.bss)		}\n\
  .rel.plt       : { *(.rel.plt)		}\n\
  .rela.plt      : { *(.rela.plt)		}\n\
  .rodata    : { *(.rodata)  }\n\
  .rodata1   : { *(.rodata1) }\n\
  .init          : { *(.init)	} =0\n\
  .text      :\n\
  {\n\
    *(.text)\n\
    *(.stub)\n\
    /* .gnu.warning sections are handled specially by elf32.em.  */\n\
    *(.gnu.warning)\n\
  } =0\n\
  .fini      : { *(.fini)    } =0\n\
  /* Adjust the address for the data segment.  We want to adjust up to\n\
     the same address within the page on the next page up.  It would\n\
     be more correct to do this:\n\
       . = 0x10000000;\n\
     The current expression does not correctly handle the case of a\n\
     text segment ending precisely at the end of a page; it causes the\n\
     data segment to skip a page.  The above expression does not have\n\
     this problem, but it will currently (2/95) cause BFD to allocate\n\
     a single segment, combining both text and data, for this case.\n\
     This will prevent the text segment from being shared among\n\
     multiple executions of the program; I think that is more\n\
     important than losing a page of the virtual address space (note\n\
     that no actual memory is lost; the page which is skipped can not\n\
     be referenced).  */\n\
  . += 0x10000;\n\
  .data    :\n\
  {\n\
    *(.data)\n\
    CONSTRUCTORS\n\
  }\n\
  .data1   : { *(.data1) }\n\
  .ctors         : { *(.ctors)   }\n\
  .dtors         : { *(.dtors)   }\n\
  _gp = ALIGN(16) + 0x7ff0;\n\
  .got           :\n\
  {\n\
    *(.got.plt) *(.got)\n\
   }\n\
  /* We want the small data sections together, so single-instruction offsets\n\
     can access them all, and initialized data all before uninitialized, so\n\
     we can shorten the on-disk segment size.  */\n\
  .sdata     : { *(.sdata) }\n\
  .lit8 : { *(.lit8) }\n\
  .lit4 : { *(.lit4) }\n\
  .sbss      : { *(.sbss) *(.scommon) }\n\
  .bss       :\n\
  {\n\
   *(.dynbss)\n\
   *(.bss)\n\
   *(COMMON)\n\
  }\n\
  /* These are needed for ELF backends which have not yet been\n\
     converted to the new style linker.  */\n\
  .stab 0 : { *(.stab) }\n\
  .stabstr 0 : { *(.stabstr) }\n\
  /* DWARF debug sections.\n\
     Symbols in the .debug DWARF section are relative to the beginning of the\n\
     section so we begin .debug at 0.  It's not clear yet what needs to happen\n\
     for the others.   */\n\
  .debug          0 : { *(.debug) }\n\
  .debug_srcinfo  0 : { *(.debug_srcinfo) }\n\
  .debug_aranges  0 : { *(.debug_aranges) }\n\
  .debug_pubnames 0 : { *(.debug_pubnames) }\n\
  .debug_sfnames  0 : { *(.debug_sfnames) }\n\
  .line           0 : { *(.line) }\n\
  /* These must appear regardless of  .  */\n\
  .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }\n\
  .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }\n\
}\n\n";
  else
    return "OUTPUT_FORMAT(\"elf32-bigmips\", \"elf32-bigmips\",\n\
	      \"elf32-littlemips\")\n\
OUTPUT_ARCH(mips)\n\
ENTRY(_start)\n\
 SEARCH_DIR(/usr/local/mips-elf/lib);\n\
/* Do we need any of these for elf?\n\
   __DYNAMIC = 0;    */\n\
SECTIONS\n\
{\n\
  /* Read-only sections, merged into text segment: */\n\
  . = 0x0400000;\n\
  .interp     : { *(.interp) 	}\n\
  .reginfo       : { *(.reginfo) }\n\
  .dynamic       : { *(.dynamic) }\n\
  .dynstr        : { *(.dynstr)		}\n\
  .dynsym        : { *(.dynsym)		}\n\
  .hash          : { *(.hash)		}\n\
  .rel.text      : { *(.rel.text)		}\n\
  .rela.text     : { *(.rela.text) 	}\n\
  .rel.data      : { *(.rel.data)		}\n\
  .rela.data     : { *(.rela.data) 	}\n\
  .rel.rodata    : { *(.rel.rodata) 	}\n\
  .rela.rodata   : { *(.rela.rodata) 	}\n\
  .rel.got       : { *(.rel.got)		}\n\
  .rela.got      : { *(.rela.got)		}\n\
  .rel.ctors     : { *(.rel.ctors)	}\n\
  .rela.ctors    : { *(.rela.ctors)	}\n\
  .rel.dtors     : { *(.rel.dtors)	}\n\
  .rela.dtors    : { *(.rela.dtors)	}\n\
  .rel.init      : { *(.rel.init)	}\n\
  .rela.init     : { *(.rela.init)	}\n\
  .rel.fini      : { *(.rel.fini)	}\n\
  .rela.fini     : { *(.rela.fini)	}\n\
  .rel.bss       : { *(.rel.bss)		}\n\
  .rela.bss      : { *(.rela.bss)		}\n\
  .rel.plt       : { *(.rel.plt)		}\n\
  .rela.plt      : { *(.rela.plt)		}\n\
  .rodata    : { *(.rodata)  }\n\
  .rodata1   : { *(.rodata1) }\n\
  .init          : { *(.init)	} =0\n\
  .text      :\n\
  {\n\
    _ftext = . ;\n\
    *(.text)\n\
    *(.stub)\n\
    /* .gnu.warning sections are handled specially by elf32.em.  */\n\
    *(.gnu.warning)\n\
  } =0\n\
  _etext = .;\n\
  PROVIDE (etext = .);\n\
  .fini      : { *(.fini)    } =0\n\
  /* Adjust the address for the data segment.  We want to adjust up to\n\
     the same address within the page on the next page up.  It would\n\
     be more correct to do this:\n\
       . = 0x10000000;\n\
     The current expression does not correctly handle the case of a\n\
     text segment ending precisely at the end of a page; it causes the\n\
     data segment to skip a page.  The above expression does not have\n\
     this problem, but it will currently (2/95) cause BFD to allocate\n\
     a single segment, combining both text and data, for this case.\n\
     This will prevent the text segment from being shared among\n\
     multiple executions of the program; I think that is more\n\
     important than losing a page of the virtual address space (note\n\
     that no actual memory is lost; the page which is skipped can not\n\
     be referenced).  */\n\
  . += 0x10000000 - 0x0400000;\n\
  .data    :\n\
  {\n\
    _fdata = . ;\n\
    *(.data)\n\
    CONSTRUCTORS\n\
  }\n\
  .data1   : { *(.data1) }\n\
  .ctors         : { *(.ctors)   }\n\
  .dtors         : { *(.dtors)   }\n\
  _gp = ALIGN(16) + 0x7ff0;\n\
  .got           :\n\
  {\n\
    *(.got.plt) *(.got)\n\
   }\n\
  /* We want the small data sections together, so single-instruction offsets\n\
     can access them all, and initialized data all before uninitialized, so\n\
     we can shorten the on-disk segment size.  */\n\
  .sdata     : { *(.sdata) }\n\
  .lit8 : { *(.lit8) }\n\
  .lit4 : { *(.lit4) }\n\
  _edata  =  .;\n\
  PROVIDE (edata = .);\n\
  __bss_start = .;\n\
  _fbss = .;\n\
  .sbss      : { *(.sbss) *(.scommon) }\n\
  .bss       :\n\
  {\n\
   *(.dynbss)\n\
   *(.bss)\n\
   *(COMMON)\n\
  }\n\
  _end = . ;\n\
  PROVIDE (end = .);\n\
  /* These are needed for ELF backends which have not yet been\n\
     converted to the new style linker.  */\n\
  .stab 0 : { *(.stab) }\n\
  .stabstr 0 : { *(.stabstr) }\n\
  /* DWARF debug sections.\n\
     Symbols in the .debug DWARF section are relative to the beginning of the\n\
     section so we begin .debug at 0.  It's not clear yet what needs to happen\n\
     for the others.   */\n\
  .debug          0 : { *(.debug) }\n\
  .debug_srcinfo  0 : { *(.debug_srcinfo) }\n\
  .debug_aranges  0 : { *(.debug_aranges) }\n\
  .debug_pubnames 0 : { *(.debug_pubnames) }\n\
  .debug_sfnames  0 : { *(.debug_sfnames) }\n\
  .line           0 : { *(.line) }\n\
  /* These must appear regardless of  .  */\n\
  .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }\n\
  .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }\n\
}\n\n";
}

struct ld_emulation_xfer_struct ld_elf32ebmip_emulation = 
{
  gldelf32ebmip_before_parse,
  syslib_default,
  hll_default,
  after_parse_default,
  gldelf32ebmip_after_open,
  after_allocation_default,
  set_output_arch_default,
  ldemul_default_target,
  gldelf32ebmip_before_allocation,
  gldelf32ebmip_get_script,
  "elf32ebmip",
  "elf32-bigmips",
  NULL,
  NULL,
  gldelf32ebmip_open_dynamic_archive,
  gldelf32ebmip_place_orphan
};
