OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [ld/] [emultempl/] [aix.em] - Diff between revs 156 and 816

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 156 Rev 816
# This shell script emits a C file. -*- C -*-
# This shell script emits a C file. -*- C -*-
# It does some substitutions.
# It does some substitutions.
if [ -z "$MACHINE" ]; then
if [ -z "$MACHINE" ]; then
  OUTPUT_ARCH=${ARCH}
  OUTPUT_ARCH=${ARCH}
else
else
  OUTPUT_ARCH=${ARCH}:${MACHINE}
  OUTPUT_ARCH=${ARCH}:${MACHINE}
fi
fi
fragment <
fragment <
/* This file is is generated by a shell script.  DO NOT EDIT! */
/* This file is is generated by a shell script.  DO NOT EDIT! */
/* AIX emulation code for ${EMULATION_NAME}
/* AIX emulation code for ${EMULATION_NAME}
   Copyright 1991, 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
   Copyright 1991, 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
   2003, 2004, 2005, 2006, 2007, 2008
   2003, 2004, 2005, 2006, 2007, 2008
   Free Software Foundation, Inc.
   Free Software Foundation, Inc.
   Written by Steve Chamberlain 
   Written by Steve Chamberlain 
   AIX support by Ian Lance Taylor 
   AIX support by Ian Lance Taylor 
   AIX 64 bit support by Tom Rix 
   AIX 64 bit support by Tom Rix 
   This file is part of the GNU Binutils.
   This file is part of the GNU Binutils.
   This program is free software; you can redistribute it and/or modify
   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
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.
   (at your option) any later version.
   This program is distributed in the hope that it will be useful,
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   GNU General Public License for more details.
   You should have received a copy of the GNU General Public License
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */
   MA 02110-1301, USA.  */
#define TARGET_IS_${EMULATION_NAME}
#define TARGET_IS_${EMULATION_NAME}
#include "sysdep.h"
#include "sysdep.h"
#include "bfd.h"
#include "bfd.h"
#include "libiberty.h"
#include "libiberty.h"
#include "safe-ctype.h"
#include "safe-ctype.h"
#include "getopt.h"
#include "getopt.h"
#include "obstack.h"
#include "obstack.h"
#include "bfdlink.h"
#include "bfdlink.h"
#include "ld.h"
#include "ld.h"
#include "ldmain.h"
#include "ldmain.h"
#include "ldmisc.h"
#include "ldmisc.h"
#include "ldexp.h"
#include "ldexp.h"
#include "ldlang.h"
#include "ldlang.h"
#include "ldfile.h"
#include "ldfile.h"
#include "ldemul.h"
#include "ldemul.h"
#include "ldctor.h"
#include "ldctor.h"
#include 
#include 
#include "coff/internal.h"
#include "coff/internal.h"
#include "coff/xcoff.h"
#include "coff/xcoff.h"
#include "libcoff.h"
#include "libcoff.h"
#include "libxcoff.h"
#include "libxcoff.h"
static void gld${EMULATION_NAME}_read_file (const char *, bfd_boolean);
static void gld${EMULATION_NAME}_read_file (const char *, bfd_boolean);
static void gld${EMULATION_NAME}_free (void *);
static void gld${EMULATION_NAME}_free (void *);
static void gld${EMULATION_NAME}_find_relocs (lang_statement_union_type *);
static void gld${EMULATION_NAME}_find_relocs (lang_statement_union_type *);
static void gld${EMULATION_NAME}_find_exp_assignment (etree_type *);
static void gld${EMULATION_NAME}_find_exp_assignment (etree_type *);
/* The file alignment required for each section.  */
/* The file alignment required for each section.  */
static unsigned long file_align;
static unsigned long file_align;
/* The maximum size the stack is permitted to grow.  This is stored in
/* The maximum size the stack is permitted to grow.  This is stored in
   the a.out header.  */
   the a.out header.  */
static unsigned long maxstack;
static unsigned long maxstack;
/* The maximum data size.  This is stored in the a.out header.  */
/* The maximum data size.  This is stored in the a.out header.  */
static unsigned long maxdata;
static unsigned long maxdata;
/* Whether to perform garbage collection.  */
/* Whether to perform garbage collection.  */
static int gc = 1;
static int gc = 1;
/* The module type to use.  */
/* The module type to use.  */
static unsigned short modtype = ('1' << 8) | 'L';
static unsigned short modtype = ('1' << 8) | 'L';
/* Whether the .text section must be read-only (i.e., no relocs
/* Whether the .text section must be read-only (i.e., no relocs
   permitted).  */
   permitted).  */
static int textro;
static int textro;
/* Whether to implement Unix like linker semantics.  */
/* Whether to implement Unix like linker semantics.  */
static int unix_ld;
static int unix_ld;
/* Structure used to hold import file list.  */
/* Structure used to hold import file list.  */
struct filelist
struct filelist
{
{
  struct filelist *next;
  struct filelist *next;
  const char *name;
  const char *name;
};
};
/* List of import files.  */
/* List of import files.  */
static struct filelist *import_files;
static struct filelist *import_files;
/* List of export symbols read from the export files.  */
/* List of export symbols read from the export files.  */
struct export_symbol_list
struct export_symbol_list
{
{
  struct export_symbol_list *next;
  struct export_symbol_list *next;
  const char *name;
  const char *name;
};
};
static struct export_symbol_list *export_symbols;
static struct export_symbol_list *export_symbols;
/* Maintains the 32 or 64 bit mode state of import file */
/* Maintains the 32 or 64 bit mode state of import file */
static unsigned int symbol_mode = 0x04;
static unsigned int symbol_mode = 0x04;
/* Which symbol modes are valid */
/* Which symbol modes are valid */
static unsigned int symbol_mode_mask = 0x0d;
static unsigned int symbol_mode_mask = 0x0d;
/* Whether this is a 64 bit link */
/* Whether this is a 64 bit link */
static int is_64bit = 0;
static int is_64bit = 0;
/* Which syscalls from import file are valid */
/* Which syscalls from import file are valid */
static unsigned int syscall_mask = 0x77;
static unsigned int syscall_mask = 0x77;
/* fake file for -binitfini support */
/* fake file for -binitfini support */
static lang_input_statement_type *initfini_file;
static lang_input_statement_type *initfini_file;
/* Whether to do run time linking
/* Whether to do run time linking
   -brtl enables, -bnortl and -bnortllib disable. */
   -brtl enables, -bnortl and -bnortllib disable. */
static int rtld;
static int rtld;
/* Explicit command line library path, -blibpath */
/* Explicit command line library path, -blibpath */
static char *command_line_blibpath = NULL;
static char *command_line_blibpath = NULL;
/* This routine is called before anything else is done.  */
/* This routine is called before anything else is done.  */
static void
static void
gld${EMULATION_NAME}_before_parse (void)
gld${EMULATION_NAME}_before_parse (void)
{
{
  ldfile_set_output_arch ("${OUTPUT_ARCH}", bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`);
  ldfile_set_output_arch ("${OUTPUT_ARCH}", bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`);
  config.has_shared = TRUE;
  config.has_shared = TRUE;
  /* The link_info.[init|fini]_functions are initialized in ld/lexsup.c.
  /* The link_info.[init|fini]_functions are initialized in ld/lexsup.c.
     Override them here so we can use the link_info.init_function as a
     Override them here so we can use the link_info.init_function as a
     state flag that lets the backend know that -binitfini has been done.  */
     state flag that lets the backend know that -binitfini has been done.  */
  link_info.init_function = NULL;
  link_info.init_function = NULL;
  link_info.fini_function = NULL;
  link_info.fini_function = NULL;
}
}
/* Handle AIX specific options.  */
/* Handle AIX specific options.  */
enum
enum
  {
  {
    OPTION_IGNORE = 300,
    OPTION_IGNORE = 300,
    OPTION_AUTOIMP,
    OPTION_AUTOIMP,
    OPTION_ERNOTOK,
    OPTION_ERNOTOK,
    OPTION_EROK,
    OPTION_EROK,
    OPTION_EXPORT,
    OPTION_EXPORT,
    OPTION_IMPORT,
    OPTION_IMPORT,
    OPTION_INITFINI,
    OPTION_INITFINI,
    OPTION_LOADMAP,
    OPTION_LOADMAP,
    OPTION_MAXDATA,
    OPTION_MAXDATA,
    OPTION_MAXSTACK,
    OPTION_MAXSTACK,
    OPTION_MODTYPE,
    OPTION_MODTYPE,
    OPTION_NOAUTOIMP,
    OPTION_NOAUTOIMP,
    OPTION_NOSTRCMPCT,
    OPTION_NOSTRCMPCT,
    OPTION_PD,
    OPTION_PD,
    OPTION_PT,
    OPTION_PT,
    OPTION_STRCMPCT,
    OPTION_STRCMPCT,
    OPTION_UNIX,
    OPTION_UNIX,
    OPTION_32,
    OPTION_32,
    OPTION_64,
    OPTION_64,
    OPTION_LIBPATH,
    OPTION_LIBPATH,
    OPTION_NOLIBPATH,
    OPTION_NOLIBPATH,
  };
  };
static void
static void
gld${EMULATION_NAME}_add_options
gld${EMULATION_NAME}_add_options
  (int ns, char **shortopts, int nl, struct option **longopts,
  (int ns, char **shortopts, int nl, struct option **longopts,
   int nrl ATTRIBUTE_UNUSED, struct option **really_longopts ATTRIBUTE_UNUSED)
   int nrl ATTRIBUTE_UNUSED, struct option **really_longopts ATTRIBUTE_UNUSED)
{
{
  static const char xtra_short[] = "D:H:KT:z";
  static const char xtra_short[] = "D:H:KT:z";
  static const struct option xtra_long[] = {
  static const struct option xtra_long[] = {
  /* -binitfini has special handling in the linker backend.  The native linker
  /* -binitfini has special handling in the linker backend.  The native linker
     uses the arguemnts to generate a table of init and fini functions for
     uses the arguemnts to generate a table of init and fini functions for
     the executable.  The important use for this option is to support aix 4.2+
     the executable.  The important use for this option is to support aix 4.2+
     c++ constructors and destructors.  This is tied into gcc via collect2.c.
     c++ constructors and destructors.  This is tied into gcc via collect2.c.
     The function table is accessed by the runtime linker/loader by checking if
     The function table is accessed by the runtime linker/loader by checking if
     the first symbol in the loader symbol table is __rtinit.  The gnu linker
     the first symbol in the loader symbol table is __rtinit.  The gnu linker
     generates this symbol and makes it the first loader symbol.  */
     generates this symbol and makes it the first loader symbol.  */
    {"basis", no_argument, NULL, OPTION_IGNORE},
    {"basis", no_argument, NULL, OPTION_IGNORE},
    {"bautoimp", no_argument, NULL, OPTION_AUTOIMP},
    {"bautoimp", no_argument, NULL, OPTION_AUTOIMP},
    {"bcomprld", no_argument, NULL, OPTION_IGNORE},
    {"bcomprld", no_argument, NULL, OPTION_IGNORE},
    {"bcrld", no_argument, NULL, OPTION_IGNORE},
    {"bcrld", no_argument, NULL, OPTION_IGNORE},
    {"bcror31", no_argument, NULL, OPTION_IGNORE},
    {"bcror31", no_argument, NULL, OPTION_IGNORE},
    {"bD", required_argument, NULL, OPTION_MAXDATA},
    {"bD", required_argument, NULL, OPTION_MAXDATA},
    {"bE", required_argument, NULL, OPTION_EXPORT},
    {"bE", required_argument, NULL, OPTION_EXPORT},
    {"bernotok", no_argument, NULL, OPTION_ERNOTOK},
    {"bernotok", no_argument, NULL, OPTION_ERNOTOK},
    {"berok", no_argument, NULL, OPTION_EROK},
    {"berok", no_argument, NULL, OPTION_EROK},
    {"berrmsg", no_argument, NULL, OPTION_IGNORE},
    {"berrmsg", no_argument, NULL, OPTION_IGNORE},
    {"bexport", required_argument, NULL, OPTION_EXPORT},
    {"bexport", required_argument, NULL, OPTION_EXPORT},
    {"bf", no_argument, NULL, OPTION_ERNOTOK},
    {"bf", no_argument, NULL, OPTION_ERNOTOK},
    {"bgc", no_argument, &gc, 1},
    {"bgc", no_argument, &gc, 1},
    {"bh", required_argument, NULL, OPTION_IGNORE},
    {"bh", required_argument, NULL, OPTION_IGNORE},
    {"bhalt", required_argument, NULL, OPTION_IGNORE},
    {"bhalt", required_argument, NULL, OPTION_IGNORE},
    {"bI", required_argument, NULL, OPTION_IMPORT},
    {"bI", required_argument, NULL, OPTION_IMPORT},
    {"bimport", required_argument, NULL, OPTION_IMPORT},
    {"bimport", required_argument, NULL, OPTION_IMPORT},
    {"binitfini", required_argument, NULL, OPTION_INITFINI},
    {"binitfini", required_argument, NULL, OPTION_INITFINI},
    {"bl", required_argument, NULL, OPTION_LOADMAP},
    {"bl", required_argument, NULL, OPTION_LOADMAP},
    {"bloadmap", required_argument, NULL, OPTION_LOADMAP},
    {"bloadmap", required_argument, NULL, OPTION_LOADMAP},
    {"bmaxdata", required_argument, NULL, OPTION_MAXDATA},
    {"bmaxdata", required_argument, NULL, OPTION_MAXDATA},
    {"bmaxstack", required_argument, NULL, OPTION_MAXSTACK},
    {"bmaxstack", required_argument, NULL, OPTION_MAXSTACK},
    {"bM", required_argument, NULL, OPTION_MODTYPE},
    {"bM", required_argument, NULL, OPTION_MODTYPE},
    {"bmodtype", required_argument, NULL, OPTION_MODTYPE},
    {"bmodtype", required_argument, NULL, OPTION_MODTYPE},
    {"bnoautoimp", no_argument, NULL, OPTION_NOAUTOIMP},
    {"bnoautoimp", no_argument, NULL, OPTION_NOAUTOIMP},
    {"bnodelcsect", no_argument, NULL, OPTION_IGNORE},
    {"bnodelcsect", no_argument, NULL, OPTION_IGNORE},
    {"bnoentry", no_argument, NULL, OPTION_IGNORE},
    {"bnoentry", no_argument, NULL, OPTION_IGNORE},
    {"bnogc", no_argument, &gc, 0},
    {"bnogc", no_argument, &gc, 0},
    {"bnso", no_argument, NULL, OPTION_NOAUTOIMP},
    {"bnso", no_argument, NULL, OPTION_NOAUTOIMP},
    {"bnostrcmpct", no_argument, NULL, OPTION_NOSTRCMPCT},
    {"bnostrcmpct", no_argument, NULL, OPTION_NOSTRCMPCT},
    {"bnotextro", no_argument, &textro, 0},
    {"bnotextro", no_argument, &textro, 0},
    {"bnro", no_argument, &textro, 0},
    {"bnro", no_argument, &textro, 0},
    {"bpD", required_argument, NULL, OPTION_PD},
    {"bpD", required_argument, NULL, OPTION_PD},
    {"bpT", required_argument, NULL, OPTION_PT},
    {"bpT", required_argument, NULL, OPTION_PT},
    {"bro", no_argument, &textro, 1},
    {"bro", no_argument, &textro, 1},
    {"brtl", no_argument, &rtld, 1},
    {"brtl", no_argument, &rtld, 1},
    {"bnortl", no_argument, &rtld, 0},
    {"bnortl", no_argument, &rtld, 0},
    {"bnortllib", no_argument, &rtld, 0},
    {"bnortllib", no_argument, &rtld, 0},
    {"bS", required_argument, NULL, OPTION_MAXSTACK},
    {"bS", required_argument, NULL, OPTION_MAXSTACK},
    {"bso", no_argument, NULL, OPTION_AUTOIMP},
    {"bso", no_argument, NULL, OPTION_AUTOIMP},
    {"bstrcmpct", no_argument, NULL, OPTION_STRCMPCT},
    {"bstrcmpct", no_argument, NULL, OPTION_STRCMPCT},
    {"btextro", no_argument, &textro, 1},
    {"btextro", no_argument, &textro, 1},
    {"b32", no_argument, NULL, OPTION_32},
    {"b32", no_argument, NULL, OPTION_32},
    {"b64", no_argument, NULL, OPTION_64},
    {"b64", no_argument, NULL, OPTION_64},
    {"static", no_argument, NULL, OPTION_NOAUTOIMP},
    {"static", no_argument, NULL, OPTION_NOAUTOIMP},
    {"unix", no_argument, NULL, OPTION_UNIX},
    {"unix", no_argument, NULL, OPTION_UNIX},
    {"blibpath", required_argument, NULL, OPTION_LIBPATH},
    {"blibpath", required_argument, NULL, OPTION_LIBPATH},
    {"bnolibpath", required_argument, NULL, OPTION_NOLIBPATH},
    {"bnolibpath", required_argument, NULL, OPTION_NOLIBPATH},
    {NULL, no_argument, NULL, 0}
    {NULL, no_argument, NULL, 0}
  };
  };
  /* Options supported by the AIX linker which we do not support: -f,
  /* Options supported by the AIX linker which we do not support: -f,
     -S, -v, -Z, -bbindcmds, -bbinder, -bbindopts, -bcalls, -bcaps,
     -S, -v, -Z, -bbindcmds, -bbinder, -bbindopts, -bcalls, -bcaps,
     -bcror15, -bdebugopt, -bdbg, -bdelcsect, -bex?, -bfilelist, -bfl,
     -bcror15, -bdebugopt, -bdbg, -bdelcsect, -bex?, -bfilelist, -bfl,
     -bgcbypass, -bglink, -binsert, -bi, -bloadmap, -bl, -bmap, -bnl,
     -bgcbypass, -bglink, -binsert, -bi, -bloadmap, -bl, -bmap, -bnl,
     -bnobind, -bnocomprld, -bnocrld, -bnoerrmsg, -bnoglink,
     -bnobind, -bnocomprld, -bnocrld, -bnoerrmsg, -bnoglink,
     -bnoloadmap, -bnl, -bnoobjreorder, -bnoquiet, -bnoreorder,
     -bnoloadmap, -bnl, -bnoobjreorder, -bnoquiet, -bnoreorder,
     -bnotypchk, -bnox, -bquiet, -bR, -brename, -breorder, -btypchk,
     -bnotypchk, -bnox, -bquiet, -bR, -brename, -breorder, -btypchk,
     -bx, -bX, -bxref.  */
     -bx, -bX, -bxref.  */
  *shortopts = (char *) xrealloc (*shortopts, ns + sizeof (xtra_short));
  *shortopts = (char *) xrealloc (*shortopts, ns + sizeof (xtra_short));
  memcpy (*shortopts + ns, &xtra_short, sizeof (xtra_short));
  memcpy (*shortopts + ns, &xtra_short, sizeof (xtra_short));
  *longopts = xrealloc (*longopts,
  *longopts = xrealloc (*longopts,
                        nl * sizeof (struct option) + sizeof (xtra_long));
                        nl * sizeof (struct option) + sizeof (xtra_long));
  memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long));
  memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long));
}
}
static bfd_boolean
static bfd_boolean
gld${EMULATION_NAME}_parse_args (int argc, char **argv)
gld${EMULATION_NAME}_parse_args (int argc, char **argv)
{
{
  int indx;
  int indx;
  /* If the current option starts with -b, change the first : to an =.
  /* If the current option starts with -b, change the first : to an =.
     The AIX linker uses : to separate the option from the argument;
     The AIX linker uses : to separate the option from the argument;
     changing it to = lets us treat it as a getopt option.  */
     changing it to = lets us treat it as a getopt option.  */
  indx = optind;
  indx = optind;
  if (indx == 0)
  if (indx == 0)
    indx = 1;
    indx = 1;
  if (indx < argc && CONST_STRNEQ (argv[indx], "-b"))
  if (indx < argc && CONST_STRNEQ (argv[indx], "-b"))
    {
    {
      char *s;
      char *s;
      for (s = argv[indx]; *s != '\0'; s++)
      for (s = argv[indx]; *s != '\0'; s++)
        {
        {
          if (*s == ':')
          if (*s == ':')
            {
            {
              *s = '=';
              *s = '=';
              break;
              break;
            }
            }
        }
        }
    }
    }
  return FALSE;
  return FALSE;
}
}
static bfd_boolean
static bfd_boolean
gld${EMULATION_NAME}_handle_option (int optc)
gld${EMULATION_NAME}_handle_option (int optc)
{
{
  bfd_signed_vma val;
  bfd_signed_vma val;
  const char *end;
  const char *end;
  switch (optc)
  switch (optc)
    {
    {
    default:
    default:
      return FALSE;
      return FALSE;
    case 0:
    case 0:
      /* Long option which just sets a flag.  */
      /* Long option which just sets a flag.  */
      break;
      break;
    case 'D':
    case 'D':
      val = bfd_scan_vma (optarg, &end, 0);
      val = bfd_scan_vma (optarg, &end, 0);
      if (*end != '\0')
      if (*end != '\0')
        einfo ("%P: warning: ignoring invalid -D number %s\n", optarg);
        einfo ("%P: warning: ignoring invalid -D number %s\n", optarg);
      else if (val != -1)
      else if (val != -1)
        lang_section_start (".data", exp_intop (val), NULL);
        lang_section_start (".data", exp_intop (val), NULL);
      break;
      break;
    case 'H':
    case 'H':
      val = bfd_scan_vma (optarg, &end, 0);
      val = bfd_scan_vma (optarg, &end, 0);
      if (*end != '\0' || (val & (val - 1)) != 0)
      if (*end != '\0' || (val & (val - 1)) != 0)
        einfo ("%P: warning: ignoring invalid -H number %s\n", optarg);
        einfo ("%P: warning: ignoring invalid -H number %s\n", optarg);
      else
      else
        file_align = val;
        file_align = val;
      break;
      break;
    case 'K':
    case 'K':
    case 'z':
    case 'z':
      /* FIXME: This should use the page size for the target system.  */
      /* FIXME: This should use the page size for the target system.  */
      file_align = 4096;
      file_align = 4096;
      break;
      break;
    case 'T':
    case 'T':
      /* On AIX this is the same as GNU ld -Ttext.  When we see -T
      /* On AIX this is the same as GNU ld -Ttext.  When we see -T
         number, we assume the AIX option is intended.  Otherwise, we
         number, we assume the AIX option is intended.  Otherwise, we
         assume the usual GNU ld -T option is intended.  We can't just
         assume the usual GNU ld -T option is intended.  We can't just
         ignore the AIX option, because gcc passes it to the linker.  */
         ignore the AIX option, because gcc passes it to the linker.  */
      val = bfd_scan_vma (optarg, &end, 0);
      val = bfd_scan_vma (optarg, &end, 0);
      if (*end != '\0')
      if (*end != '\0')
        return FALSE;
        return FALSE;
      lang_section_start (".text", exp_intop (val), NULL);
      lang_section_start (".text", exp_intop (val), NULL);
      break;
      break;
    case OPTION_IGNORE:
    case OPTION_IGNORE:
      break;
      break;
    case OPTION_INITFINI:
    case OPTION_INITFINI:
      {
      {
        /*
        /*
         * The aix linker init fini has the format :
         * The aix linker init fini has the format :
         *
         *
         * -binitfini:[ Initial][:Termination][:Priority]
         * -binitfini:[ Initial][:Termination][:Priority]
         *
         *
         * it allows the Termination and Priority to be optional.
         * it allows the Termination and Priority to be optional.
         *
         *
         * Since we support only one init/fini pair, we ignore the Priority.
         * Since we support only one init/fini pair, we ignore the Priority.
         *
         *
         * Define the special symbol __rtinit.
         * Define the special symbol __rtinit.
         *
         *
         * strtok does not correctly handle the case of -binitfini::fini: so
         * strtok does not correctly handle the case of -binitfini::fini: so
         * do it by hand
         * do it by hand
         */
         */
        char *t, *i, *f;
        char *t, *i, *f;
        i = t = optarg;
        i = t = optarg;
        while (*t && ':' != *t)
        while (*t && ':' != *t)
          t++;
          t++;
        if (*t)
        if (*t)
          *t++ = 0;
          *t++ = 0;
        if (0 != strlen (i))
        if (0 != strlen (i))
          link_info.init_function = i;
          link_info.init_function = i;
        f = t;
        f = t;
        while (*t && ':' != *t)
        while (*t && ':' != *t)
          t++;
          t++;
        *t = 0;
        *t = 0;
        if (0 != strlen (f))
        if (0 != strlen (f))
          link_info.fini_function = f;
          link_info.fini_function = f;
      }
      }
      break;
      break;
    case OPTION_AUTOIMP:
    case OPTION_AUTOIMP:
      link_info.static_link = FALSE;
      link_info.static_link = FALSE;
      break;
      break;
    case OPTION_ERNOTOK:
    case OPTION_ERNOTOK:
      force_make_executable = FALSE;
      force_make_executable = FALSE;
      break;
      break;
    case OPTION_EROK:
    case OPTION_EROK:
      force_make_executable = TRUE;
      force_make_executable = TRUE;
      break;
      break;
    case OPTION_EXPORT:
    case OPTION_EXPORT:
      gld${EMULATION_NAME}_read_file (optarg, FALSE);
      gld${EMULATION_NAME}_read_file (optarg, FALSE);
      break;
      break;
    case OPTION_IMPORT:
    case OPTION_IMPORT:
      {
      {
        struct filelist *n;
        struct filelist *n;
        struct filelist **flpp;
        struct filelist **flpp;
        n = (struct filelist *) xmalloc (sizeof (struct filelist));
        n = (struct filelist *) xmalloc (sizeof (struct filelist));
        n->next = NULL;
        n->next = NULL;
        n->name = optarg;
        n->name = optarg;
        flpp = &import_files;
        flpp = &import_files;
        while (*flpp != NULL)
        while (*flpp != NULL)
          flpp = &(*flpp)->next;
          flpp = &(*flpp)->next;
        *flpp = n;
        *flpp = n;
      }
      }
      break;
      break;
    case OPTION_LOADMAP:
    case OPTION_LOADMAP:
      config.map_filename = optarg;
      config.map_filename = optarg;
      break;
      break;
    case OPTION_MAXDATA:
    case OPTION_MAXDATA:
      val = bfd_scan_vma (optarg, &end, 0);
      val = bfd_scan_vma (optarg, &end, 0);
      if (*end != '\0')
      if (*end != '\0')
        einfo ("%P: warning: ignoring invalid -bmaxdata number %s\n", optarg);
        einfo ("%P: warning: ignoring invalid -bmaxdata number %s\n", optarg);
      else
      else
        maxdata = val;
        maxdata = val;
      break;
      break;
    case OPTION_MAXSTACK:
    case OPTION_MAXSTACK:
      val = bfd_scan_vma (optarg, &end, 0);
      val = bfd_scan_vma (optarg, &end, 0);
      if (*end != '\0')
      if (*end != '\0')
        einfo ("%P: warning: ignoring invalid -bmaxstack number %s\n",
        einfo ("%P: warning: ignoring invalid -bmaxstack number %s\n",
               optarg);
               optarg);
      else
      else
        maxstack = val;
        maxstack = val;
      break;
      break;
    case OPTION_MODTYPE:
    case OPTION_MODTYPE:
      if (*optarg == 'S')
      if (*optarg == 'S')
        {
        {
          link_info.shared = TRUE;
          link_info.shared = TRUE;
          ++optarg;
          ++optarg;
        }
        }
      if (*optarg == '\0' || optarg[1] == '\0')
      if (*optarg == '\0' || optarg[1] == '\0')
        einfo ("%P: warning: ignoring invalid module type %s\n", optarg);
        einfo ("%P: warning: ignoring invalid module type %s\n", optarg);
      else
      else
        modtype = (*optarg << 8) | optarg[1];
        modtype = (*optarg << 8) | optarg[1];
      break;
      break;
    case OPTION_NOAUTOIMP:
    case OPTION_NOAUTOIMP:
      link_info.static_link = TRUE;
      link_info.static_link = TRUE;
      break;
      break;
    case OPTION_NOSTRCMPCT:
    case OPTION_NOSTRCMPCT:
      link_info.traditional_format = TRUE;
      link_info.traditional_format = TRUE;
      break;
      break;
    case OPTION_PD:
    case OPTION_PD:
      /* This sets the page that the .data section is supposed to
      /* This sets the page that the .data section is supposed to
         start on.  The offset within the page should still be the
         start on.  The offset within the page should still be the
         offset within the file, so we need to build an appropriate
         offset within the file, so we need to build an appropriate
         expression.  */
         expression.  */
      val = bfd_scan_vma (optarg, &end, 0);
      val = bfd_scan_vma (optarg, &end, 0);
      if (*end != '\0')
      if (*end != '\0')
        einfo ("%P: warning: ignoring invalid -pD number %s\n", optarg);
        einfo ("%P: warning: ignoring invalid -pD number %s\n", optarg);
      else
      else
        {
        {
          etree_type *t;
          etree_type *t;
          t = exp_binop ('+',
          t = exp_binop ('+',
                         exp_intop (val),
                         exp_intop (val),
                         exp_binop ('&',
                         exp_binop ('&',
                                    exp_nameop (NAME, "."),
                                    exp_nameop (NAME, "."),
                                    exp_intop (0xfff)));
                                    exp_intop (0xfff)));
          t = exp_binop ('&',
          t = exp_binop ('&',
                         exp_binop ('+', t, exp_intop (31)),
                         exp_binop ('+', t, exp_intop (31)),
                         exp_intop (~(bfd_vma) 31));
                         exp_intop (~(bfd_vma) 31));
          lang_section_start (".data", t, NULL);
          lang_section_start (".data", t, NULL);
        }
        }
      break;
      break;
    case OPTION_PT:
    case OPTION_PT:
      /* This set the page that the .text section is supposed to start
      /* This set the page that the .text section is supposed to start
         on.  The offset within the page should still be the offset
         on.  The offset within the page should still be the offset
         within the file.  */
         within the file.  */
      val = bfd_scan_vma (optarg, &end, 0);
      val = bfd_scan_vma (optarg, &end, 0);
      if (*end != '\0')
      if (*end != '\0')
        einfo ("%P: warning: ignoring invalid -pT number %s\n", optarg);
        einfo ("%P: warning: ignoring invalid -pT number %s\n", optarg);
      else
      else
        {
        {
          etree_type *t;
          etree_type *t;
          t = exp_binop ('+',
          t = exp_binop ('+',
                         exp_intop (val),
                         exp_intop (val),
                         exp_nameop (SIZEOF_HEADERS, NULL));
                         exp_nameop (SIZEOF_HEADERS, NULL));
          t = exp_binop ('&',
          t = exp_binop ('&',
                         exp_binop ('+', t, exp_intop (31)),
                         exp_binop ('+', t, exp_intop (31)),
                         exp_intop (~(bfd_vma) 31));
                         exp_intop (~(bfd_vma) 31));
          lang_section_start (".text", t, NULL);
          lang_section_start (".text", t, NULL);
        }
        }
      break;
      break;
    case OPTION_STRCMPCT:
    case OPTION_STRCMPCT:
      link_info.traditional_format = FALSE;
      link_info.traditional_format = FALSE;
      break;
      break;
    case OPTION_UNIX:
    case OPTION_UNIX:
      unix_ld = TRUE;
      unix_ld = TRUE;
      break;
      break;
    case OPTION_32:
    case OPTION_32:
      is_64bit = 0;
      is_64bit = 0;
      syscall_mask = 0x77;
      syscall_mask = 0x77;
      symbol_mode_mask = 0x0d;
      symbol_mode_mask = 0x0d;
      break;
      break;
    case OPTION_64:
    case OPTION_64:
      is_64bit = 1;
      is_64bit = 1;
      syscall_mask = 0xcc;
      syscall_mask = 0xcc;
      symbol_mode_mask = 0x0e;
      symbol_mode_mask = 0x0e;
      break;
      break;
    case OPTION_LIBPATH:
    case OPTION_LIBPATH:
      command_line_blibpath = optarg;
      command_line_blibpath = optarg;
      break;
      break;
    case OPTION_NOLIBPATH:
    case OPTION_NOLIBPATH:
      command_line_blibpath = NULL;
      command_line_blibpath = NULL;
      break;
      break;
    }
    }
  return TRUE;
  return TRUE;
}
}
/* This is called when an input file can not be recognized as a BFD
/* This is called when an input file can not be recognized as a BFD
   object or an archive.  If the file starts with #!, we must treat it
   object or an archive.  If the file starts with #!, we must treat it
   as an import file.  This is for AIX compatibility.  */
   as an import file.  This is for AIX compatibility.  */
static bfd_boolean
static bfd_boolean
gld${EMULATION_NAME}_unrecognized_file (lang_input_statement_type *entry)
gld${EMULATION_NAME}_unrecognized_file (lang_input_statement_type *entry)
{
{
  FILE *e;
  FILE *e;
  bfd_boolean ret;
  bfd_boolean ret;
  e = fopen (entry->filename, FOPEN_RT);
  e = fopen (entry->filename, FOPEN_RT);
  if (e == NULL)
  if (e == NULL)
    return FALSE;
    return FALSE;
  ret = FALSE;
  ret = FALSE;
  if (getc (e) == '#' && getc (e) == '!')
  if (getc (e) == '#' && getc (e) == '!')
    {
    {
      struct filelist *n;
      struct filelist *n;
      struct filelist **flpp;
      struct filelist **flpp;
      n = (struct filelist *) xmalloc (sizeof (struct filelist));
      n = (struct filelist *) xmalloc (sizeof (struct filelist));
      n->next = NULL;
      n->next = NULL;
      n->name = entry->filename;
      n->name = entry->filename;
      flpp = &import_files;
      flpp = &import_files;
      while (*flpp != NULL)
      while (*flpp != NULL)
        flpp = &(*flpp)->next;
        flpp = &(*flpp)->next;
      *flpp = n;
      *flpp = n;
      ret = TRUE;
      ret = TRUE;
      entry->loaded = TRUE;
      entry->loaded = TRUE;
    }
    }
  fclose (e);
  fclose (e);
  return ret;
  return ret;
}
}
/* This is called after the input files have been opened.  */
/* This is called after the input files have been opened.  */
static void
static void
gld${EMULATION_NAME}_after_open (void)
gld${EMULATION_NAME}_after_open (void)
{
{
  bfd_boolean r;
  bfd_boolean r;
  struct set_info *p;
  struct set_info *p;
  /* Call ldctor_build_sets, after pretending that this is a
  /* Call ldctor_build_sets, after pretending that this is a
     relocatable link.  We do this because AIX requires relocation
     relocatable link.  We do this because AIX requires relocation
     entries for all references to symbols, even in a final
     entries for all references to symbols, even in a final
     executable.  Of course, we only want to do this if we are
     executable.  Of course, we only want to do this if we are
     producing an XCOFF output file.  */
     producing an XCOFF output file.  */
  r = link_info.relocatable;
  r = link_info.relocatable;
  if (strstr (bfd_get_target (link_info.output_bfd), "xcoff") != NULL)
  if (strstr (bfd_get_target (link_info.output_bfd), "xcoff") != NULL)
    link_info.relocatable = TRUE;
    link_info.relocatable = TRUE;
  ldctor_build_sets ();
  ldctor_build_sets ();
  link_info.relocatable = r;
  link_info.relocatable = r;
  /* For each set, record the size, so that the XCOFF backend can
  /* For each set, record the size, so that the XCOFF backend can
     output the correct csect length.  */
     output the correct csect length.  */
  for (p = sets; p != (struct set_info *) NULL; p = p->next)
  for (p = sets; p != (struct set_info *) NULL; p = p->next)
    {
    {
      bfd_size_type size;
      bfd_size_type size;
      /* If the symbol is defined, we may have been invoked from
      /* If the symbol is defined, we may have been invoked from
         collect, and the sets may already have been built, so we do
         collect, and the sets may already have been built, so we do
         not do anything.  */
         not do anything.  */
      if (p->h->type == bfd_link_hash_defined
      if (p->h->type == bfd_link_hash_defined
          || p->h->type == bfd_link_hash_defweak)
          || p->h->type == bfd_link_hash_defweak)
        continue;
        continue;
      if (p->reloc != BFD_RELOC_CTOR)
      if (p->reloc != BFD_RELOC_CTOR)
        {
        {
          /* Handle this if we need to.  */
          /* Handle this if we need to.  */
          abort ();
          abort ();
        }
        }
      size = (p->count + 2) * 4;
      size = (p->count + 2) * 4;
      if (!bfd_xcoff_link_record_set (link_info.output_bfd, &link_info,
      if (!bfd_xcoff_link_record_set (link_info.output_bfd, &link_info,
                                      p->h, size))
                                      p->h, size))
        einfo ("%F%P: bfd_xcoff_link_record_set failed: %E\n");
        einfo ("%F%P: bfd_xcoff_link_record_set failed: %E\n");
    }
    }
}
}
/* This is called after the sections have been attached to output
/* This is called after the sections have been attached to output
   sections, but before any sizes or addresses have been set.  */
   sections, but before any sizes or addresses have been set.  */
static void
static void
gld${EMULATION_NAME}_before_allocation (void)
gld${EMULATION_NAME}_before_allocation (void)
{
{
  struct filelist *fl;
  struct filelist *fl;
  struct export_symbol_list *el;
  struct export_symbol_list *el;
  char *libpath;
  char *libpath;
  asection *special_sections[XCOFF_NUMBER_OF_SPECIAL_SECTIONS];
  asection *special_sections[XCOFF_NUMBER_OF_SPECIAL_SECTIONS];
  int i;
  int i;
  /* Handle the import and export files, if any.  */
  /* Handle the import and export files, if any.  */
  for (fl = import_files; fl != NULL; fl = fl->next)
  for (fl = import_files; fl != NULL; fl = fl->next)
    gld${EMULATION_NAME}_read_file (fl->name, TRUE);
    gld${EMULATION_NAME}_read_file (fl->name, TRUE);
  for (el = export_symbols; el != NULL; el = el->next)
  for (el = export_symbols; el != NULL; el = el->next)
    {
    {
      struct bfd_link_hash_entry *h;
      struct bfd_link_hash_entry *h;
      h = bfd_link_hash_lookup (link_info.hash, el->name, FALSE, FALSE, FALSE);
      h = bfd_link_hash_lookup (link_info.hash, el->name, FALSE, FALSE, FALSE);
      if (h == NULL)
      if (h == NULL)
        einfo ("%P%F: bfd_link_hash_lookup of export symbol failed: %E\n");
        einfo ("%P%F: bfd_link_hash_lookup of export symbol failed: %E\n");
      if (!bfd_xcoff_export_symbol (link_info.output_bfd, &link_info, h))
      if (!bfd_xcoff_export_symbol (link_info.output_bfd, &link_info, h))
        einfo ("%P%F: bfd_xcoff_export_symbol failed: %E\n");
        einfo ("%P%F: bfd_xcoff_export_symbol failed: %E\n");
    }
    }
  /* Track down all relocations called for by the linker script (these
  /* Track down all relocations called for by the linker script (these
     are typically constructor/destructor entries created by
     are typically constructor/destructor entries created by
     CONSTRUCTORS) and let the backend know it will need to create
     CONSTRUCTORS) and let the backend know it will need to create
     .loader relocs for them.  */
     .loader relocs for them.  */
  lang_for_each_statement (gld${EMULATION_NAME}_find_relocs);
  lang_for_each_statement (gld${EMULATION_NAME}_find_relocs);
  /* Precedence of LIBPATH
  /* Precedence of LIBPATH
     -blibpath:  native support always first
     -blibpath:  native support always first
     -rpath:     gnu extension
     -rpath:     gnu extension
     -L          build from command line -L's */
     -L          build from command line -L's */
  if (command_line_blibpath != NULL)
  if (command_line_blibpath != NULL)
    libpath = command_line_blibpath;
    libpath = command_line_blibpath;
  else if (command_line.rpath != NULL)
  else if (command_line.rpath != NULL)
    libpath = command_line.rpath;
    libpath = command_line.rpath;
  else if (search_head == NULL)
  else if (search_head == NULL)
    libpath = (char *) "";
    libpath = (char *) "";
  else
  else
    {
    {
      size_t len;
      size_t len;
      search_dirs_type *search;
      search_dirs_type *search;
      /* PR ld/4023: Strip sysroot prefix from any paths
      /* PR ld/4023: Strip sysroot prefix from any paths
         being inserted into the output binary's DT_RPATH.  */
         being inserted into the output binary's DT_RPATH.  */
      if (ld_sysroot != NULL
      if (ld_sysroot != NULL
          && * ld_sysroot != 0)
          && * ld_sysroot != 0)
        {
        {
          const char * name = search_head->name;
          const char * name = search_head->name;
          size_t ld_sysroot_len = strlen (ld_sysroot);
          size_t ld_sysroot_len = strlen (ld_sysroot);
          if (strncmp (name, ld_sysroot, ld_sysroot_len) == 0)
          if (strncmp (name, ld_sysroot, ld_sysroot_len) == 0)
            name += ld_sysroot_len;
            name += ld_sysroot_len;
          len = strlen (name);
          len = strlen (name);
          libpath = xmalloc (len + 1);
          libpath = xmalloc (len + 1);
          strcpy (libpath, name);
          strcpy (libpath, name);
          for (search = search_head->next; search != NULL; search = search->next)
          for (search = search_head->next; search != NULL; search = search->next)
            {
            {
              size_t nlen;
              size_t nlen;
              name = search->name;
              name = search->name;
              if (strncmp (name, ld_sysroot, ld_sysroot_len) == 0)
              if (strncmp (name, ld_sysroot, ld_sysroot_len) == 0)
                name += ld_sysroot_len;
                name += ld_sysroot_len;
              nlen = strlen (name);
              nlen = strlen (name);
              libpath = xrealloc (libpath, len + nlen + 2);
              libpath = xrealloc (libpath, len + nlen + 2);
              libpath[len] = ':';
              libpath[len] = ':';
              strcpy (libpath + len + 1, name);
              strcpy (libpath + len + 1, name);
              len += nlen + 1;
              len += nlen + 1;
            }
            }
        }
        }
      else
      else
        {
        {
          len = strlen (search_head->name);
          len = strlen (search_head->name);
          libpath = xmalloc (len + 1);
          libpath = xmalloc (len + 1);
          strcpy (libpath, search_head->name);
          strcpy (libpath, search_head->name);
          for (search = search_head->next; search != NULL; search = search->next)
          for (search = search_head->next; search != NULL; search = search->next)
            {
            {
              size_t nlen;
              size_t nlen;
              nlen = strlen (search->name);
              nlen = strlen (search->name);
              libpath = xrealloc (libpath, len + nlen + 2);
              libpath = xrealloc (libpath, len + nlen + 2);
              libpath[len] = ':';
              libpath[len] = ':';
              strcpy (libpath + len + 1, search->name);
              strcpy (libpath + len + 1, search->name);
              len += nlen + 1;
              len += nlen + 1;
            }
            }
        }
        }
    }
    }
  /* Let the XCOFF backend set up the .loader section.  */
  /* Let the XCOFF backend set up the .loader section.  */
  if (!bfd_xcoff_size_dynamic_sections
  if (!bfd_xcoff_size_dynamic_sections
      (link_info.output_bfd, &link_info, libpath, entry_symbol.name, file_align,
      (link_info.output_bfd, &link_info, libpath, entry_symbol.name, file_align,
       maxstack, maxdata, gc && !unix_ld ? TRUE : FALSE,
       maxstack, maxdata, gc && !unix_ld ? TRUE : FALSE,
       modtype, textro ? TRUE : FALSE, unix_ld, special_sections,
       modtype, textro ? TRUE : FALSE, unix_ld, special_sections,
       rtld ? TRUE : FALSE))
       rtld ? TRUE : FALSE))
    einfo ("%P%F: failed to set dynamic section sizes: %E\n");
    einfo ("%P%F: failed to set dynamic section sizes: %E\n");
  /* Look through the special sections, and put them in the right
  /* Look through the special sections, and put them in the right
     place in the link ordering.  This is especially magic.  */
     place in the link ordering.  This is especially magic.  */
  for (i = 0; i < XCOFF_NUMBER_OF_SPECIAL_SECTIONS; i++)
  for (i = 0; i < XCOFF_NUMBER_OF_SPECIAL_SECTIONS; i++)
    {
    {
      asection *sec;
      asection *sec;
      lang_output_section_statement_type *os;
      lang_output_section_statement_type *os;
      lang_statement_union_type **pls;
      lang_statement_union_type **pls;
      lang_input_section_type *is;
      lang_input_section_type *is;
      const char *oname;
      const char *oname;
      bfd_boolean start;
      bfd_boolean start;
      sec = special_sections[i];
      sec = special_sections[i];
      if (sec == NULL)
      if (sec == NULL)
        continue;
        continue;
      /* Remove this section from the list of the output section.
      /* Remove this section from the list of the output section.
         This assumes we know what the script looks like.  */
         This assumes we know what the script looks like.  */
      is = NULL;
      is = NULL;
      os = lang_output_section_find (sec->output_section->name);
      os = lang_output_section_find (sec->output_section->name);
      if (os == NULL)
      if (os == NULL)
        einfo ("%P%F: can't find output section %s\n",
        einfo ("%P%F: can't find output section %s\n",
               sec->output_section->name);
               sec->output_section->name);
      for (pls = &os->children.head; *pls != NULL; pls = &(*pls)->header.next)
      for (pls = &os->children.head; *pls != NULL; pls = &(*pls)->header.next)
        {
        {
          if ((*pls)->header.type == lang_input_section_enum
          if ((*pls)->header.type == lang_input_section_enum
              && (*pls)->input_section.section == sec)
              && (*pls)->input_section.section == sec)
            {
            {
              is = (lang_input_section_type *) * pls;
              is = (lang_input_section_type *) * pls;
              *pls = (*pls)->header.next;
              *pls = (*pls)->header.next;
              break;
              break;
            }
            }
          if ((*pls)->header.type == lang_wild_statement_enum)
          if ((*pls)->header.type == lang_wild_statement_enum)
            {
            {
              lang_statement_union_type **pwls;
              lang_statement_union_type **pwls;
              for (pwls = &(*pls)->wild_statement.children.head;
              for (pwls = &(*pls)->wild_statement.children.head;
                   *pwls != NULL; pwls = &(*pwls)->header.next)
                   *pwls != NULL; pwls = &(*pwls)->header.next)
                {
                {
                  if ((*pwls)->header.type == lang_input_section_enum
                  if ((*pwls)->header.type == lang_input_section_enum
                      && (*pwls)->input_section.section == sec)
                      && (*pwls)->input_section.section == sec)
                    {
                    {
                      is = (lang_input_section_type *) * pwls;
                      is = (lang_input_section_type *) * pwls;
                      *pwls = (*pwls)->header.next;
                      *pwls = (*pwls)->header.next;
                      break;
                      break;
                    }
                    }
                }
                }
              if (is != NULL)
              if (is != NULL)
                break;
                break;
            }
            }
        }
        }
      if (is == NULL)
      if (is == NULL)
        {
        {
          einfo ("%P%F: can't find %s in output section\n",
          einfo ("%P%F: can't find %s in output section\n",
                 bfd_get_section_name (sec->owner, sec));
                 bfd_get_section_name (sec->owner, sec));
        }
        }
      /* Now figure out where the section should go.  */
      /* Now figure out where the section should go.  */
      switch (i)
      switch (i)
        {
        {
        default:                /* to avoid warnings */
        default:                /* to avoid warnings */
        case XCOFF_SPECIAL_SECTION_TEXT:
        case XCOFF_SPECIAL_SECTION_TEXT:
          /* _text */
          /* _text */
          oname = ".text";
          oname = ".text";
          start = TRUE;
          start = TRUE;
          break;
          break;
        case XCOFF_SPECIAL_SECTION_ETEXT:
        case XCOFF_SPECIAL_SECTION_ETEXT:
          /* _etext */
          /* _etext */
          oname = ".text";
          oname = ".text";
          start = FALSE;
          start = FALSE;
          break;
          break;
        case XCOFF_SPECIAL_SECTION_DATA:
        case XCOFF_SPECIAL_SECTION_DATA:
          /* _data */
          /* _data */
          oname = ".data";
          oname = ".data";
          start = TRUE;
          start = TRUE;
          break;
          break;
        case XCOFF_SPECIAL_SECTION_EDATA:
        case XCOFF_SPECIAL_SECTION_EDATA:
          /* _edata */
          /* _edata */
          oname = ".data";
          oname = ".data";
          start = FALSE;
          start = FALSE;
          break;
          break;
        case XCOFF_SPECIAL_SECTION_END:
        case XCOFF_SPECIAL_SECTION_END:
        case XCOFF_SPECIAL_SECTION_END2:
        case XCOFF_SPECIAL_SECTION_END2:
          /* _end and end */
          /* _end and end */
          oname = ".bss";
          oname = ".bss";
          start = FALSE;
          start = FALSE;
          break;
          break;
        }
        }
      os = lang_output_section_find (oname);
      os = lang_output_section_find (oname);
      if (start)
      if (start)
        {
        {
          is->header.next = os->children.head;
          is->header.next = os->children.head;
          os->children.head = (lang_statement_union_type *) is;
          os->children.head = (lang_statement_union_type *) is;
        }
        }
      else
      else
        {
        {
          is->header.next = NULL;
          is->header.next = NULL;
          lang_statement_append (&os->children,
          lang_statement_append (&os->children,
                                 (lang_statement_union_type *) is,
                                 (lang_statement_union_type *) is,
                                 &is->header.next);
                                 &is->header.next);
        }
        }
    }
    }
  before_allocation_default ();
  before_allocation_default ();
}
}
static char *
static char *
gld${EMULATION_NAME}_choose_target (int argc, char **argv)
gld${EMULATION_NAME}_choose_target (int argc, char **argv)
{
{
  int i, j, jmax;
  int i, j, jmax;
  static char *from_outside;
  static char *from_outside;
  static char *from_inside;
  static char *from_inside;
  static char *argv_to_target[][2] = {
  static char *argv_to_target[][2] = {
    {NULL,   "${OUTPUT_FORMAT}"},
    {NULL,   "${OUTPUT_FORMAT}"},
    {"-b32", "${OUTPUT_FORMAT_32BIT}"},
    {"-b32", "${OUTPUT_FORMAT_32BIT}"},
    {"-b64", "${OUTPUT_FORMAT_64BIT}"},
    {"-b64", "${OUTPUT_FORMAT_64BIT}"},
  };
  };
  jmax = 3;
  jmax = 3;
  from_outside = getenv (TARGET_ENVIRON);
  from_outside = getenv (TARGET_ENVIRON);
  if (from_outside != (char *) NULL)
  if (from_outside != (char *) NULL)
    return from_outside;
    return from_outside;
  /* Set to default. */
  /* Set to default. */
  from_inside = argv_to_target[0][1];
  from_inside = argv_to_target[0][1];
  for (i = 1; i < argc; i++)
  for (i = 1; i < argc; i++)
    {
    {
      for (j = 1; j < jmax; j++)
      for (j = 1; j < jmax; j++)
        {
        {
          if (0 == strcmp (argv[i], argv_to_target[j][0]))
          if (0 == strcmp (argv[i], argv_to_target[j][0]))
            from_inside = argv_to_target[j][1];
            from_inside = argv_to_target[j][1];
        }
        }
    }
    }
  return from_inside;
  return from_inside;
}
}
/* Returns
/* Returns
   1 : state changed
   1 : state changed
   0 : no change */
   0 : no change */
static int
static int
change_symbol_mode (char *input)
change_symbol_mode (char *input)
{
{
  char *symbol_mode_string[] = {
  char *symbol_mode_string[] = {
    "# 32",                     /* 0x01 */
    "# 32",                     /* 0x01 */
    "# 64",                     /* 0x02 */
    "# 64",                     /* 0x02 */
    "# no32",                   /* 0x04 */
    "# no32",                   /* 0x04 */
    "# no64",                   /* 0x08 */
    "# no64",                   /* 0x08 */
    NULL,
    NULL,
  };
  };
  unsigned int bit;
  unsigned int bit;
  char *string;
  char *string;
  for (bit = 0;; bit++)
  for (bit = 0;; bit++)
    {
    {
      string = symbol_mode_string[bit];
      string = symbol_mode_string[bit];
      if (string == NULL)
      if (string == NULL)
        return 0;
        return 0;
      if (0 == strcmp (input, string))
      if (0 == strcmp (input, string))
        {
        {
          symbol_mode = (1 << bit);
          symbol_mode = (1 << bit);
          return 1;
          return 1;
        }
        }
    }
    }
  /* should not be here */
  /* should not be here */
  return 0;
  return 0;
}
}
/* Returns
/* Returns
   1 : yes
   1 : yes
   0 : ignore
   0 : ignore
   -1 : error, try something else */
   -1 : error, try something else */
static int
static int
is_syscall (char *input, unsigned int *flag)
is_syscall (char *input, unsigned int *flag)
{
{
  unsigned int bit;
  unsigned int bit;
  char *string;
  char *string;
  struct sc {
  struct sc {
    char *syscall_string;
    char *syscall_string;
    unsigned int flag;
    unsigned int flag;
  } s [] = {
  } s [] = {
    { "svc"         /* 0x01 */, XCOFF_SYSCALL32 },
    { "svc"         /* 0x01 */, XCOFF_SYSCALL32 },
    { "svc32"       /* 0x02 */, XCOFF_SYSCALL32 },
    { "svc32"       /* 0x02 */, XCOFF_SYSCALL32 },
    { "svc3264"     /* 0x04 */, XCOFF_SYSCALL32 | XCOFF_SYSCALL64 },
    { "svc3264"     /* 0x04 */, XCOFF_SYSCALL32 | XCOFF_SYSCALL64 },
    { "svc64"       /* 0x08 */, XCOFF_SYSCALL64 },
    { "svc64"       /* 0x08 */, XCOFF_SYSCALL64 },
    { "syscall"     /* 0x10 */, XCOFF_SYSCALL32 },
    { "syscall"     /* 0x10 */, XCOFF_SYSCALL32 },
    { "syscall32"   /* 0x20 */, XCOFF_SYSCALL32 },
    { "syscall32"   /* 0x20 */, XCOFF_SYSCALL32 },
    { "syscall3264" /* 0x40 */, XCOFF_SYSCALL32 | XCOFF_SYSCALL64 },
    { "syscall3264" /* 0x40 */, XCOFF_SYSCALL32 | XCOFF_SYSCALL64 },
    { "syscall64"   /* 0x80 */, XCOFF_SYSCALL64 },
    { "syscall64"   /* 0x80 */, XCOFF_SYSCALL64 },
    { NULL, 0 },
    { NULL, 0 },
  };
  };
  *flag = 0;
  *flag = 0;
  for (bit = 0;; bit++)
  for (bit = 0;; bit++)
    {
    {
      string = s[bit].syscall_string;
      string = s[bit].syscall_string;
      if (string == NULL)
      if (string == NULL)
        return -1;
        return -1;
      if (0 == strcmp (input, string))
      if (0 == strcmp (input, string))
        {
        {
          if (1 << bit & syscall_mask)
          if (1 << bit & syscall_mask)
            {
            {
              *flag = s[bit].flag;
              *flag = s[bit].flag;
              return 1;
              return 1;
            }
            }
          else
          else
            {
            {
              return 0;
              return 0;
            }
            }
        }
        }
    }
    }
  /* should not be here */
  /* should not be here */
  return -1;
  return -1;
}
}
/* Read an import or export file.  For an import file, this is called
/* Read an import or export file.  For an import file, this is called
   by the before_allocation emulation routine.  For an export file,
   by the before_allocation emulation routine.  For an export file,
   this is called by the handle_option emulation routine.  */
   this is called by the handle_option emulation routine.  */
static void
static void
gld${EMULATION_NAME}_read_file (const char *filename, bfd_boolean import)
gld${EMULATION_NAME}_read_file (const char *filename, bfd_boolean import)
{
{
  struct obstack *o;
  struct obstack *o;
  FILE *f;
  FILE *f;
  int lineno;
  int lineno;
  int c;
  int c;
  bfd_boolean keep;
  bfd_boolean keep;
  const char *imppath;
  const char *imppath;
  const char *impfile;
  const char *impfile;
  const char *impmember;
  const char *impmember;
  o = (struct obstack *) xmalloc (sizeof (struct obstack));
  o = (struct obstack *) xmalloc (sizeof (struct obstack));
  obstack_specify_allocation (o, 0, 0, xmalloc, gld${EMULATION_NAME}_free);
  obstack_specify_allocation (o, 0, 0, xmalloc, gld${EMULATION_NAME}_free);
  f = fopen (filename, FOPEN_RT);
  f = fopen (filename, FOPEN_RT);
  if (f == NULL)
  if (f == NULL)
    {
    {
      bfd_set_error (bfd_error_system_call);
      bfd_set_error (bfd_error_system_call);
      einfo ("%F%s: %E\n", filename);
      einfo ("%F%s: %E\n", filename);
    }
    }
  keep = FALSE;
  keep = FALSE;
  imppath = NULL;
  imppath = NULL;
  impfile = NULL;
  impfile = NULL;
  impmember = NULL;
  impmember = NULL;
  lineno = 0;
  lineno = 0;
  /* Default to 32 and 64 bit mode
  /* Default to 32 and 64 bit mode
     symbols at top of /lib/syscalls.exp do not have a mode modifier and they
     symbols at top of /lib/syscalls.exp do not have a mode modifier and they
     are not repeated, assume 64 bit routines also want to use them.
     are not repeated, assume 64 bit routines also want to use them.
     See the routine change_symbol_mode for more information.  */
     See the routine change_symbol_mode for more information.  */
  symbol_mode = 0x04;
  symbol_mode = 0x04;
  while ((c = getc (f)) != EOF)
  while ((c = getc (f)) != EOF)
    {
    {
      char *s;
      char *s;
      char *symname;
      char *symname;
      unsigned int syscall_flag = 0;
      unsigned int syscall_flag = 0;
      bfd_vma address;
      bfd_vma address;
      struct bfd_link_hash_entry *h;
      struct bfd_link_hash_entry *h;
      if (c != '\n')
      if (c != '\n')
        {
        {
          obstack_1grow (o, c);
          obstack_1grow (o, c);
          continue;
          continue;
        }
        }
      obstack_1grow (o, '\0');
      obstack_1grow (o, '\0');
      ++lineno;
      ++lineno;
      s = (char *) obstack_base (o);
      s = (char *) obstack_base (o);
      while (ISSPACE (*s))
      while (ISSPACE (*s))
        ++s;
        ++s;
      if (*s == '\0'
      if (*s == '\0'
          || *s == '*'
          || *s == '*'
          || change_symbol_mode (s)
          || change_symbol_mode (s)
          || (*s == '#' && s[1] == ' ')
          || (*s == '#' && s[1] == ' ')
          || (!import && *s == '#' && s[1] == '!'))
          || (!import && *s == '#' && s[1] == '!'))
        {
        {
          obstack_free (o, obstack_base (o));
          obstack_free (o, obstack_base (o));
          continue;
          continue;
        }
        }
      if (*s == '#' && s[1] == '!')
      if (*s == '#' && s[1] == '!')
        {
        {
          s += 2;
          s += 2;
          while (ISSPACE (*s))
          while (ISSPACE (*s))
            ++s;
            ++s;
          if (*s == '\0')
          if (*s == '\0')
            {
            {
              imppath = NULL;
              imppath = NULL;
              impfile = NULL;
              impfile = NULL;
              impmember = NULL;
              impmember = NULL;
              obstack_free (o, obstack_base (o));
              obstack_free (o, obstack_base (o));
            }
            }
          else if (*s == '(')
          else if (*s == '(')
            einfo ("%F%s%d: #! ([member]) is not supported in import files\n",
            einfo ("%F%s%d: #! ([member]) is not supported in import files\n",
                   filename, lineno);
                   filename, lineno);
          else
          else
            {
            {
              char cs;
              char cs;
              char *file;
              char *file;
              (void) obstack_finish (o);
              (void) obstack_finish (o);
              keep = TRUE;
              keep = TRUE;
              imppath = s;
              imppath = s;
              file = NULL;
              file = NULL;
              while (!ISSPACE (*s) && *s != '(' && *s != '\0')
              while (!ISSPACE (*s) && *s != '(' && *s != '\0')
                {
                {
                  if (*s == '/')
                  if (*s == '/')
                    file = s + 1;
                    file = s + 1;
                  ++s;
                  ++s;
                }
                }
              if (file != NULL)
              if (file != NULL)
                {
                {
                  file[-1] = '\0';
                  file[-1] = '\0';
                  impfile = file;
                  impfile = file;
                  if (imppath == file - 1)
                  if (imppath == file - 1)
                    imppath = "/";
                    imppath = "/";
                }
                }
              else
              else
                {
                {
                  impfile = imppath;
                  impfile = imppath;
                  imppath = "";
                  imppath = "";
                }
                }
              cs = *s;
              cs = *s;
              *s = '\0';
              *s = '\0';
              while (ISSPACE (cs))
              while (ISSPACE (cs))
                {
                {
                  ++s;
                  ++s;
                  cs = *s;
                  cs = *s;
                }
                }
              if (cs != '(')
              if (cs != '(')
                {
                {
                  impmember = "";
                  impmember = "";
                  if (cs != '\0')
                  if (cs != '\0')
                    einfo ("%s:%d: warning: syntax error in import file\n",
                    einfo ("%s:%d: warning: syntax error in import file\n",
                           filename, lineno);
                           filename, lineno);
                }
                }
              else
              else
                {
                {
                  ++s;
                  ++s;
                  impmember = s;
                  impmember = s;
                  while (*s != ')' && *s != '\0')
                  while (*s != ')' && *s != '\0')
                    ++s;
                    ++s;
                  if (*s == ')')
                  if (*s == ')')
                    *s = '\0';
                    *s = '\0';
                  else
                  else
                    einfo ("%s:%d: warning: syntax error in import file\n",
                    einfo ("%s:%d: warning: syntax error in import file\n",
                           filename, lineno);
                           filename, lineno);
                }
                }
            }
            }
          continue;
          continue;
        }
        }
      if (symbol_mode & symbol_mode_mask)
      if (symbol_mode & symbol_mode_mask)
        {
        {
          /* This is a symbol to be imported or exported.  */
          /* This is a symbol to be imported or exported.  */
          symname = s;
          symname = s;
          syscall_flag = 0;
          syscall_flag = 0;
          address = (bfd_vma) -1;
          address = (bfd_vma) -1;
          while (!ISSPACE (*s) && *s != '\0')
          while (!ISSPACE (*s) && *s != '\0')
            ++s;
            ++s;
          if (*s != '\0')
          if (*s != '\0')
            {
            {
              char *se;
              char *se;
              *s++ = '\0';
              *s++ = '\0';
              while (ISSPACE (*s))
              while (ISSPACE (*s))
                ++s;
                ++s;
              se = s;
              se = s;
              while (!ISSPACE (*se) && *se != '\0')
              while (!ISSPACE (*se) && *se != '\0')
                ++se;
                ++se;
              if (*se != '\0')
              if (*se != '\0')
                {
                {
                  *se++ = '\0';
                  *se++ = '\0';
                  while (ISSPACE (*se))
                  while (ISSPACE (*se))
                    ++se;
                    ++se;
                  if (*se != '\0')
                  if (*se != '\0')
                    einfo ("%s%d: warning: syntax error in import/export file\n",
                    einfo ("%s%d: warning: syntax error in import/export file\n",
                           filename, lineno);
                           filename, lineno);
                }
                }
              if (s != se)
              if (s != se)
                {
                {
                  int status;
                  int status;
                  const char *end;
                  const char *end;
                  status = is_syscall (s, &syscall_flag);
                  status = is_syscall (s, &syscall_flag);
                  if (0 > status)
                  if (0 > status)
                    {
                    {
                      /* not a system call, check for address */
                      /* not a system call, check for address */
                      address = bfd_scan_vma (s, &end, 0);
                      address = bfd_scan_vma (s, &end, 0);
                      if (*end != '\0')
                      if (*end != '\0')
                        {
                        {
                          einfo ("%s:%d: warning: syntax error in import/export file\n",
                          einfo ("%s:%d: warning: syntax error in import/export file\n",
                                 filename, lineno);
                                 filename, lineno);
                        }
                        }
                    }
                    }
                }
                }
            }
            }
          if (!import)
          if (!import)
            {
            {
              struct export_symbol_list *n;
              struct export_symbol_list *n;
              ldlang_add_undef (symname);
              ldlang_add_undef (symname);
              n = ((struct export_symbol_list *)
              n = ((struct export_symbol_list *)
                   xmalloc (sizeof (struct export_symbol_list)));
                   xmalloc (sizeof (struct export_symbol_list)));
              n->next = export_symbols;
              n->next = export_symbols;
              n->name = xstrdup (symname);
              n->name = xstrdup (symname);
              export_symbols = n;
              export_symbols = n;
            }
            }
          else
          else
            {
            {
              h = bfd_link_hash_lookup (link_info.hash, symname, FALSE, FALSE,
              h = bfd_link_hash_lookup (link_info.hash, symname, FALSE, FALSE,
                                        TRUE);
                                        TRUE);
              if (h == NULL || h->type == bfd_link_hash_new)
              if (h == NULL || h->type == bfd_link_hash_new)
                {
                {
                  /* We can just ignore attempts to import an unreferenced
                  /* We can just ignore attempts to import an unreferenced
                     symbol.  */
                     symbol.  */
                }
                }
              else
              else
                {
                {
                  if (!bfd_xcoff_import_symbol (link_info.output_bfd,
                  if (!bfd_xcoff_import_symbol (link_info.output_bfd,
                                                &link_info, h,
                                                &link_info, h,
                                                address, imppath, impfile,
                                                address, imppath, impfile,
                                                impmember, syscall_flag))
                                                impmember, syscall_flag))
                    einfo ("%X%s:%d: failed to import symbol %s: %E\n",
                    einfo ("%X%s:%d: failed to import symbol %s: %E\n",
                           filename, lineno, symname);
                           filename, lineno, symname);
                }
                }
            }
            }
        }
        }
      obstack_free (o, obstack_base (o));
      obstack_free (o, obstack_base (o));
    }
    }
  if (obstack_object_size (o) > 0)
  if (obstack_object_size (o) > 0)
    {
    {
      einfo ("%s:%d: warning: ignoring unterminated last line\n",
      einfo ("%s:%d: warning: ignoring unterminated last line\n",
             filename, lineno);
             filename, lineno);
      obstack_free (o, obstack_base (o));
      obstack_free (o, obstack_base (o));
    }
    }
  if (!keep)
  if (!keep)
    {
    {
      obstack_free (o, NULL);
      obstack_free (o, NULL);
      free (o);
      free (o);
    }
    }
}
}
/* This routine saves us from worrying about declaring free.  */
/* This routine saves us from worrying about declaring free.  */
static void
static void
gld${EMULATION_NAME}_free (void *p)
gld${EMULATION_NAME}_free (void *p)
{
{
  free (p);
  free (p);
}
}
/* This is called by the before_allocation routine via
/* This is called by the before_allocation routine via
   lang_for_each_statement.  It looks for relocations and assignments
   lang_for_each_statement.  It looks for relocations and assignments
   to symbols.  */
   to symbols.  */
static void
static void
gld${EMULATION_NAME}_find_relocs (lang_statement_union_type *s)
gld${EMULATION_NAME}_find_relocs (lang_statement_union_type *s)
{
{
  if (s->header.type == lang_reloc_statement_enum)
  if (s->header.type == lang_reloc_statement_enum)
    {
    {
      lang_reloc_statement_type *rs;
      lang_reloc_statement_type *rs;
      rs = &s->reloc_statement;
      rs = &s->reloc_statement;
      if (rs->name == NULL)
      if (rs->name == NULL)
        einfo ("%F%P: only relocations against symbols are permitted\n");
        einfo ("%F%P: only relocations against symbols are permitted\n");
      if (!bfd_xcoff_link_count_reloc (link_info.output_bfd, &link_info,
      if (!bfd_xcoff_link_count_reloc (link_info.output_bfd, &link_info,
                                       rs->name))
                                       rs->name))
        einfo ("%F%P: bfd_xcoff_link_count_reloc failed: %E\n");
        einfo ("%F%P: bfd_xcoff_link_count_reloc failed: %E\n");
    }
    }
  if (s->header.type == lang_assignment_statement_enum)
  if (s->header.type == lang_assignment_statement_enum)
    gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp);
    gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp);
}
}
/* Look through an expression for an assignment statement.  */
/* Look through an expression for an assignment statement.  */
static void
static void
gld${EMULATION_NAME}_find_exp_assignment (etree_type *exp)
gld${EMULATION_NAME}_find_exp_assignment (etree_type *exp)
{
{
  struct bfd_link_hash_entry *h;
  struct bfd_link_hash_entry *h;
  switch (exp->type.node_class)
  switch (exp->type.node_class)
    {
    {
    case etree_provide:
    case etree_provide:
      h = bfd_link_hash_lookup (link_info.hash, exp->assign.dst,
      h = bfd_link_hash_lookup (link_info.hash, exp->assign.dst,
                                FALSE, FALSE, FALSE);
                                FALSE, FALSE, FALSE);
      if (h == NULL)
      if (h == NULL)
        break;
        break;
      /* Fall through.  */
      /* Fall through.  */
    case etree_assign:
    case etree_assign:
      if (strcmp (exp->assign.dst, ".") != 0)
      if (strcmp (exp->assign.dst, ".") != 0)
        {
        {
          if (!bfd_xcoff_record_link_assignment (link_info.output_bfd,
          if (!bfd_xcoff_record_link_assignment (link_info.output_bfd,
                                                 &link_info,
                                                 &link_info,
                                                 exp->assign.dst))
                                                 exp->assign.dst))
            einfo ("%P%F: failed to record assignment to %s: %E\n",
            einfo ("%P%F: failed to record assignment to %s: %E\n",
                   exp->assign.dst);
                   exp->assign.dst);
        }
        }
      gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src);
      gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src);
      break;
      break;
    case etree_binary:
    case etree_binary:
      gld${EMULATION_NAME}_find_exp_assignment (exp->binary.lhs);
      gld${EMULATION_NAME}_find_exp_assignment (exp->binary.lhs);
      gld${EMULATION_NAME}_find_exp_assignment (exp->binary.rhs);
      gld${EMULATION_NAME}_find_exp_assignment (exp->binary.rhs);
      break;
      break;
    case etree_trinary:
    case etree_trinary:
      gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.cond);
      gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.cond);
      gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs);
      gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs);
      gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs);
      gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs);
      break;
      break;
    case etree_unary:
    case etree_unary:
      gld${EMULATION_NAME}_find_exp_assignment (exp->unary.child);
      gld${EMULATION_NAME}_find_exp_assignment (exp->unary.child);
      break;
      break;
    default:
    default:
      break;
      break;
    }
    }
}
}
static char *
static char *
gld${EMULATION_NAME}_get_script (int *isfile)
gld${EMULATION_NAME}_get_script (int *isfile)
EOF
EOF
if test -n "$COMPILE_IN"
if test -n "$COMPILE_IN"
then
then
# Scripts compiled in.
# Scripts compiled in.
# sed commands to quote an ld script as a C string.
# sed commands to quote an ld script as a C string.
sc="-f ${srcdir}/emultempl/ostring.sed"
sc="-f ${srcdir}/emultempl/ostring.sed"
fragment <
fragment <
{
{
  *isfile = 0;
  *isfile = 0;
  if (link_info.relocatable && config.build_constructors)
  if (link_info.relocatable && config.build_constructors)
    return
    return
EOF
EOF
sed $sc ldscripts/${EMULATION_NAME}.xu                 >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xu                 >> e${EMULATION_NAME}.c
echo '  ; else if (link_info.relocatable) return'     >> e${EMULATION_NAME}.c
echo '  ; else if (link_info.relocatable) return'     >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xr                 >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xr                 >> e${EMULATION_NAME}.c
echo '  ; else if (!config.text_read_only) return'     >> e${EMULATION_NAME}.c
echo '  ; else if (!config.text_read_only) return'     >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xbn                >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xbn                >> e${EMULATION_NAME}.c
echo '  ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
echo '  ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xn                 >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xn                 >> e${EMULATION_NAME}.c
echo '  ; else return'                                 >> e${EMULATION_NAME}.c
echo '  ; else return'                                 >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.x                  >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.x                  >> e${EMULATION_NAME}.c
echo '; }'                                             >> e${EMULATION_NAME}.c
echo '; }'                                             >> e${EMULATION_NAME}.c
else
else
# Scripts read from the filesystem.
# Scripts read from the filesystem.
fragment <
fragment <
{
{
  *isfile = 1;
  *isfile = 1;
  if (link_info.relocatable && config.build_constructors)
  if (link_info.relocatable && config.build_constructors)
    return "ldscripts/${EMULATION_NAME}.xu";
    return "ldscripts/${EMULATION_NAME}.xu";
  else if (link_info.relocatable)
  else if (link_info.relocatable)
    return "ldscripts/${EMULATION_NAME}.xr";
    return "ldscripts/${EMULATION_NAME}.xr";
  else if (!config.text_read_only)
  else if (!config.text_read_only)
    return "ldscripts/${EMULATION_NAME}.xbn";
    return "ldscripts/${EMULATION_NAME}.xbn";
  else if (!config.magic_demand_paged)
  else if (!config.magic_demand_paged)
    return "ldscripts/${EMULATION_NAME}.xn";
    return "ldscripts/${EMULATION_NAME}.xn";
  else
  else
    return "ldscripts/${EMULATION_NAME}.x";
    return "ldscripts/${EMULATION_NAME}.x";
}
}
EOF
EOF
fi
fi
fragment <
fragment <
static void
static void
gld${EMULATION_NAME}_create_output_section_statements (void)
gld${EMULATION_NAME}_create_output_section_statements (void)
{
{
  /* __rtinit */
  /* __rtinit */
  if ((bfd_get_flavour (link_info.output_bfd) == bfd_target_xcoff_flavour)
  if ((bfd_get_flavour (link_info.output_bfd) == bfd_target_xcoff_flavour)
      && (link_info.init_function != NULL
      && (link_info.init_function != NULL
          || link_info.fini_function != NULL
          || link_info.fini_function != NULL
          || rtld))
          || rtld))
    {
    {
      initfini_file = lang_add_input_file ("initfini",
      initfini_file = lang_add_input_file ("initfini",
                                           lang_input_file_is_file_enum,
                                           lang_input_file_is_file_enum,
                                           NULL);
                                           NULL);
      initfini_file->the_bfd = bfd_create ("initfini", link_info.output_bfd);
      initfini_file->the_bfd = bfd_create ("initfini", link_info.output_bfd);
      if (initfini_file->the_bfd == NULL
      if (initfini_file->the_bfd == NULL
          || ! bfd_set_arch_mach (initfini_file->the_bfd,
          || ! bfd_set_arch_mach (initfini_file->the_bfd,
                                  bfd_get_arch (link_info.output_bfd),
                                  bfd_get_arch (link_info.output_bfd),
                                  bfd_get_mach (link_info.output_bfd)))
                                  bfd_get_mach (link_info.output_bfd)))
        {
        {
          einfo ("%X%P: can not create BFD %E\n");
          einfo ("%X%P: can not create BFD %E\n");
          return;
          return;
        }
        }
      /* Call backend to fill in the rest */
      /* Call backend to fill in the rest */
      if (! bfd_xcoff_link_generate_rtinit (initfini_file->the_bfd,
      if (! bfd_xcoff_link_generate_rtinit (initfini_file->the_bfd,
                                            link_info.init_function,
                                            link_info.init_function,
                                            link_info.fini_function,
                                            link_info.fini_function,
                                            rtld))
                                            rtld))
        {
        {
          einfo ("%X%P: can not create BFD %E\n");
          einfo ("%X%P: can not create BFD %E\n");
          return;
          return;
        }
        }
      /* __rtld defined in /lib/librtl.a */
      /* __rtld defined in /lib/librtl.a */
      if (rtld)
      if (rtld)
        lang_add_input_file ("rtl", lang_input_file_is_l_enum, NULL);
        lang_add_input_file ("rtl", lang_input_file_is_l_enum, NULL);
    }
    }
}
}
static void
static void
gld${EMULATION_NAME}_set_output_arch (void)
gld${EMULATION_NAME}_set_output_arch (void)
{
{
  bfd_set_arch_mach (link_info.output_bfd,
  bfd_set_arch_mach (link_info.output_bfd,
                     bfd_xcoff_architecture (link_info.output_bfd),
                     bfd_xcoff_architecture (link_info.output_bfd),
                     bfd_xcoff_machine (link_info.output_bfd));
                     bfd_xcoff_machine (link_info.output_bfd));
  ldfile_output_architecture = bfd_get_arch (link_info.output_bfd);
  ldfile_output_architecture = bfd_get_arch (link_info.output_bfd);
  ldfile_output_machine = bfd_get_mach (link_info.output_bfd);
  ldfile_output_machine = bfd_get_mach (link_info.output_bfd);
  ldfile_output_machine_name = bfd_printable_name (link_info.output_bfd);
  ldfile_output_machine_name = bfd_printable_name (link_info.output_bfd);
}
}
struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = {
struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = {
  gld${EMULATION_NAME}_before_parse,
  gld${EMULATION_NAME}_before_parse,
  syslib_default,
  syslib_default,
  hll_default,
  hll_default,
  after_parse_default,
  after_parse_default,
  gld${EMULATION_NAME}_after_open,
  gld${EMULATION_NAME}_after_open,
  after_allocation_default,
  after_allocation_default,
  gld${EMULATION_NAME}_set_output_arch,
  gld${EMULATION_NAME}_set_output_arch,
  gld${EMULATION_NAME}_choose_target,
  gld${EMULATION_NAME}_choose_target,
  gld${EMULATION_NAME}_before_allocation,
  gld${EMULATION_NAME}_before_allocation,
  gld${EMULATION_NAME}_get_script,
  gld${EMULATION_NAME}_get_script,
  "${EMULATION_NAME}",
  "${EMULATION_NAME}",
  "${OUTPUT_FORMAT}",
  "${OUTPUT_FORMAT}",
  finish_default,
  finish_default,
  gld${EMULATION_NAME}_create_output_section_statements,
  gld${EMULATION_NAME}_create_output_section_statements,
  0,                            /* open_dynamic_archive */
  0,                            /* open_dynamic_archive */
  0,                            /* place_orphan */
  0,                            /* place_orphan */
  0,                            /* set_symbols */
  0,                            /* set_symbols */
  gld${EMULATION_NAME}_parse_args,
  gld${EMULATION_NAME}_parse_args,
  gld${EMULATION_NAME}_add_options,
  gld${EMULATION_NAME}_add_options,
  gld${EMULATION_NAME}_handle_option,
  gld${EMULATION_NAME}_handle_option,
  gld${EMULATION_NAME}_unrecognized_file,
  gld${EMULATION_NAME}_unrecognized_file,
  NULL,                         /* list_options */
  NULL,                         /* list_options */
  NULL,                         /* recognized_file */
  NULL,                         /* recognized_file */
  NULL,                         /* find potential_libraries */
  NULL,                         /* find potential_libraries */
  NULL                          /* new_vers_pattern */
  NULL                          /* new_vers_pattern */
};
};
EOF
EOF
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.