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

/* 32 bit ELF emulation code for elf32ebmip
   Copyright (C) 1991, 93, 94, 95, 1996, 1998 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 "ldemul.h"
#include "ldfile.h"
#include "ldmisc.h"
#include "ldexp.h"
#include "ldlang.h"
#include "ldgram.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,
						 &link_info,
						 &sinterp))
    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:
      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_provide ? 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*");
  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
};
