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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [binutils-2.20.1/] [ld/] [lexsup.c] - Diff between revs 816 and 818

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

Rev 816 Rev 818
/* Parse options for the GNU linker.
/* Parse options for the GNU linker.
   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
   Free Software Foundation, Inc.
   Free Software Foundation, Inc.
 
 
   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.  */
 
 
#include "sysdep.h"
#include "sysdep.h"
#include "bfd.h"
#include "bfd.h"
#include "bfdver.h"
#include "bfdver.h"
#include "libiberty.h"
#include "libiberty.h"
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <string.h>
#include "safe-ctype.h"
#include "safe-ctype.h"
#include "getopt.h"
#include "getopt.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 <ldgram.h>
#include <ldgram.h>
#include "ldlex.h"
#include "ldlex.h"
#include "ldfile.h"
#include "ldfile.h"
#include "ldver.h"
#include "ldver.h"
#include "ldemul.h"
#include "ldemul.h"
#include "demangle.h"
#include "demangle.h"
 
 
#ifndef PATH_SEPARATOR
#ifndef PATH_SEPARATOR
#if defined (__MSDOS__) || (defined (_WIN32) && ! defined (__CYGWIN32__))
#if defined (__MSDOS__) || (defined (_WIN32) && ! defined (__CYGWIN32__))
#define PATH_SEPARATOR ';'
#define PATH_SEPARATOR ';'
#else
#else
#define PATH_SEPARATOR ':'
#define PATH_SEPARATOR ':'
#endif
#endif
#endif
#endif
 
 
/* Somewhere above, sys/stat.h got included . . . .  */
/* Somewhere above, sys/stat.h got included . . . .  */
#if !defined(S_ISDIR) && defined(S_IFDIR)
#if !defined(S_ISDIR) && defined(S_IFDIR)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
#endif
 
 
static void set_default_dirlist (char *);
static void set_default_dirlist (char *);
static void set_section_start (char *, char *);
static void set_section_start (char *, char *);
static void set_segment_start (const char *, char *);
static void set_segment_start (const char *, char *);
static void help (void);
static void help (void);
 
 
/* Non-zero if we are processing a --defsym from the command line.  */
/* Non-zero if we are processing a --defsym from the command line.  */
int parsing_defsym = 0;
int parsing_defsym = 0;
 
 
/* Codes used for the long options with no short synonyms.  150 isn't
/* Codes used for the long options with no short synonyms.  150 isn't
   special; it's just an arbitrary non-ASCII char value.  */
   special; it's just an arbitrary non-ASCII char value.  */
enum option_values
enum option_values
{
{
  OPTION_ASSERT = 150,
  OPTION_ASSERT = 150,
  OPTION_CALL_SHARED,
  OPTION_CALL_SHARED,
  OPTION_CREF,
  OPTION_CREF,
  OPTION_DEFSYM,
  OPTION_DEFSYM,
  OPTION_DEMANGLE,
  OPTION_DEMANGLE,
  OPTION_DYNAMIC_LINKER,
  OPTION_DYNAMIC_LINKER,
  OPTION_SYSROOT,
  OPTION_SYSROOT,
  OPTION_EB,
  OPTION_EB,
  OPTION_EL,
  OPTION_EL,
  OPTION_EMBEDDED_RELOCS,
  OPTION_EMBEDDED_RELOCS,
  OPTION_EXPORT_DYNAMIC,
  OPTION_EXPORT_DYNAMIC,
  OPTION_NO_EXPORT_DYNAMIC,
  OPTION_NO_EXPORT_DYNAMIC,
  OPTION_HELP,
  OPTION_HELP,
  OPTION_IGNORE,
  OPTION_IGNORE,
  OPTION_MAP,
  OPTION_MAP,
  OPTION_NO_DEMANGLE,
  OPTION_NO_DEMANGLE,
  OPTION_NO_KEEP_MEMORY,
  OPTION_NO_KEEP_MEMORY,
  OPTION_NO_WARN_MISMATCH,
  OPTION_NO_WARN_MISMATCH,
  OPTION_NO_WARN_SEARCH_MISMATCH,
  OPTION_NO_WARN_SEARCH_MISMATCH,
  OPTION_NOINHIBIT_EXEC,
  OPTION_NOINHIBIT_EXEC,
  OPTION_NON_SHARED,
  OPTION_NON_SHARED,
  OPTION_NO_WHOLE_ARCHIVE,
  OPTION_NO_WHOLE_ARCHIVE,
  OPTION_OFORMAT,
  OPTION_OFORMAT,
  OPTION_RELAX,
  OPTION_RELAX,
  OPTION_RETAIN_SYMBOLS_FILE,
  OPTION_RETAIN_SYMBOLS_FILE,
  OPTION_RPATH,
  OPTION_RPATH,
  OPTION_RPATH_LINK,
  OPTION_RPATH_LINK,
  OPTION_SHARED,
  OPTION_SHARED,
  OPTION_SONAME,
  OPTION_SONAME,
  OPTION_SORT_COMMON,
  OPTION_SORT_COMMON,
  OPTION_SORT_SECTION,
  OPTION_SORT_SECTION,
  OPTION_STATS,
  OPTION_STATS,
  OPTION_SYMBOLIC,
  OPTION_SYMBOLIC,
  OPTION_SYMBOLIC_FUNCTIONS,
  OPTION_SYMBOLIC_FUNCTIONS,
  OPTION_TASK_LINK,
  OPTION_TASK_LINK,
  OPTION_TBSS,
  OPTION_TBSS,
  OPTION_TDATA,
  OPTION_TDATA,
  OPTION_TTEXT,
  OPTION_TTEXT,
  OPTION_TTEXT_SEGMENT,
  OPTION_TTEXT_SEGMENT,
  OPTION_TRADITIONAL_FORMAT,
  OPTION_TRADITIONAL_FORMAT,
  OPTION_UR,
  OPTION_UR,
  OPTION_VERBOSE,
  OPTION_VERBOSE,
  OPTION_VERSION,
  OPTION_VERSION,
  OPTION_VERSION_SCRIPT,
  OPTION_VERSION_SCRIPT,
  OPTION_VERSION_EXPORTS_SECTION,
  OPTION_VERSION_EXPORTS_SECTION,
  OPTION_DYNAMIC_LIST,
  OPTION_DYNAMIC_LIST,
  OPTION_DYNAMIC_LIST_CPP_NEW,
  OPTION_DYNAMIC_LIST_CPP_NEW,
  OPTION_DYNAMIC_LIST_CPP_TYPEINFO,
  OPTION_DYNAMIC_LIST_CPP_TYPEINFO,
  OPTION_DYNAMIC_LIST_DATA,
  OPTION_DYNAMIC_LIST_DATA,
  OPTION_WARN_COMMON,
  OPTION_WARN_COMMON,
  OPTION_WARN_CONSTRUCTORS,
  OPTION_WARN_CONSTRUCTORS,
  OPTION_WARN_FATAL,
  OPTION_WARN_FATAL,
  OPTION_NO_WARN_FATAL,
  OPTION_NO_WARN_FATAL,
  OPTION_WARN_MULTIPLE_GP,
  OPTION_WARN_MULTIPLE_GP,
  OPTION_WARN_ONCE,
  OPTION_WARN_ONCE,
  OPTION_WARN_SECTION_ALIGN,
  OPTION_WARN_SECTION_ALIGN,
  OPTION_SPLIT_BY_RELOC,
  OPTION_SPLIT_BY_RELOC,
  OPTION_SPLIT_BY_FILE ,
  OPTION_SPLIT_BY_FILE ,
  OPTION_WHOLE_ARCHIVE,
  OPTION_WHOLE_ARCHIVE,
  OPTION_ADD_NEEDED,
  OPTION_ADD_NEEDED,
  OPTION_NO_ADD_NEEDED,
  OPTION_NO_ADD_NEEDED,
  OPTION_AS_NEEDED,
  OPTION_AS_NEEDED,
  OPTION_NO_AS_NEEDED,
  OPTION_NO_AS_NEEDED,
  OPTION_WRAP,
  OPTION_WRAP,
  OPTION_FORCE_EXE_SUFFIX,
  OPTION_FORCE_EXE_SUFFIX,
  OPTION_GC_SECTIONS,
  OPTION_GC_SECTIONS,
  OPTION_NO_GC_SECTIONS,
  OPTION_NO_GC_SECTIONS,
  OPTION_PRINT_GC_SECTIONS,
  OPTION_PRINT_GC_SECTIONS,
  OPTION_NO_PRINT_GC_SECTIONS,
  OPTION_NO_PRINT_GC_SECTIONS,
  OPTION_HASH_SIZE,
  OPTION_HASH_SIZE,
  OPTION_CHECK_SECTIONS,
  OPTION_CHECK_SECTIONS,
  OPTION_NO_CHECK_SECTIONS,
  OPTION_NO_CHECK_SECTIONS,
  OPTION_NO_UNDEFINED,
  OPTION_NO_UNDEFINED,
  OPTION_INIT,
  OPTION_INIT,
  OPTION_FINI,
  OPTION_FINI,
  OPTION_SECTION_START,
  OPTION_SECTION_START,
  OPTION_UNIQUE,
  OPTION_UNIQUE,
  OPTION_TARGET_HELP,
  OPTION_TARGET_HELP,
  OPTION_ALLOW_SHLIB_UNDEFINED,
  OPTION_ALLOW_SHLIB_UNDEFINED,
  OPTION_NO_ALLOW_SHLIB_UNDEFINED,
  OPTION_NO_ALLOW_SHLIB_UNDEFINED,
  OPTION_ALLOW_MULTIPLE_DEFINITION,
  OPTION_ALLOW_MULTIPLE_DEFINITION,
  OPTION_NO_UNDEFINED_VERSION,
  OPTION_NO_UNDEFINED_VERSION,
  OPTION_DEFAULT_SYMVER,
  OPTION_DEFAULT_SYMVER,
  OPTION_DEFAULT_IMPORTED_SYMVER,
  OPTION_DEFAULT_IMPORTED_SYMVER,
  OPTION_DISCARD_NONE,
  OPTION_DISCARD_NONE,
  OPTION_SPARE_DYNAMIC_TAGS,
  OPTION_SPARE_DYNAMIC_TAGS,
  OPTION_NO_DEFINE_COMMON,
  OPTION_NO_DEFINE_COMMON,
  OPTION_NOSTDLIB,
  OPTION_NOSTDLIB,
  OPTION_NO_OMAGIC,
  OPTION_NO_OMAGIC,
  OPTION_STRIP_DISCARDED,
  OPTION_STRIP_DISCARDED,
  OPTION_NO_STRIP_DISCARDED,
  OPTION_NO_STRIP_DISCARDED,
  OPTION_ACCEPT_UNKNOWN_INPUT_ARCH,
  OPTION_ACCEPT_UNKNOWN_INPUT_ARCH,
  OPTION_NO_ACCEPT_UNKNOWN_INPUT_ARCH,
  OPTION_NO_ACCEPT_UNKNOWN_INPUT_ARCH,
  OPTION_PIE,
  OPTION_PIE,
  OPTION_UNRESOLVED_SYMBOLS,
  OPTION_UNRESOLVED_SYMBOLS,
  OPTION_WARN_UNRESOLVED_SYMBOLS,
  OPTION_WARN_UNRESOLVED_SYMBOLS,
  OPTION_ERROR_UNRESOLVED_SYMBOLS,
  OPTION_ERROR_UNRESOLVED_SYMBOLS,
  OPTION_WARN_SHARED_TEXTREL,
  OPTION_WARN_SHARED_TEXTREL,
  OPTION_WARN_ALTERNATE_EM,
  OPTION_WARN_ALTERNATE_EM,
  OPTION_REDUCE_MEMORY_OVERHEADS,
  OPTION_REDUCE_MEMORY_OVERHEADS,
  OPTION_DEFAULT_SCRIPT
  OPTION_DEFAULT_SCRIPT
};
};
 
 
/* The long options.  This structure is used for both the option
/* The long options.  This structure is used for both the option
   parsing and the help text.  */
   parsing and the help text.  */
 
 
enum control_enum {
enum control_enum {
  /* Use one dash before long option name.  */
  /* Use one dash before long option name.  */
  ONE_DASH,
  ONE_DASH,
  /* Use two dashes before long option name.  */
  /* Use two dashes before long option name.  */
  TWO_DASHES,
  TWO_DASHES,
  /* Only accept two dashes before the long option name.
  /* Only accept two dashes before the long option name.
     This is an overloading of the use of this enum, since originally it
     This is an overloading of the use of this enum, since originally it
     was only intended to tell the --help display function how to display
     was only intended to tell the --help display function how to display
     the long option name.  This feature was added in order to resolve
     the long option name.  This feature was added in order to resolve
     the confusion about the -omagic command line switch.  Is it setting
     the confusion about the -omagic command line switch.  Is it setting
     the output file name to "magic" or is it setting the NMAGIC flag on
     the output file name to "magic" or is it setting the NMAGIC flag on
     the output ?  It has been decided that it is setting the output file
     the output ?  It has been decided that it is setting the output file
     name, and that if you want to set the NMAGIC flag you should use -N
     name, and that if you want to set the NMAGIC flag you should use -N
     or --omagic.  */
     or --omagic.  */
  EXACTLY_TWO_DASHES,
  EXACTLY_TWO_DASHES,
  /* Don't mention this option in --help output.  */
  /* Don't mention this option in --help output.  */
  NO_HELP
  NO_HELP
};
};
 
 
struct ld_option
struct ld_option
{
{
  /* The long option information.  */
  /* The long option information.  */
  struct option opt;
  struct option opt;
  /* The short option with the same meaning ('\0' if none).  */
  /* The short option with the same meaning ('\0' if none).  */
  char shortopt;
  char shortopt;
  /* The name of the argument (NULL if none).  */
  /* The name of the argument (NULL if none).  */
  const char *arg;
  const char *arg;
  /* The documentation string.  If this is NULL, this is a synonym for
  /* The documentation string.  If this is NULL, this is a synonym for
     the previous option.  */
     the previous option.  */
  const char *doc;
  const char *doc;
  enum control_enum control;
  enum control_enum control;
};
};
 
 
static const struct ld_option ld_options[] =
static const struct ld_option ld_options[] =
{
{
  { {NULL, required_argument, NULL, '\0'},
  { {NULL, required_argument, NULL, '\0'},
    'a', N_("KEYWORD"), N_("Shared library control for HP/UX compatibility"),
    'a', N_("KEYWORD"), N_("Shared library control for HP/UX compatibility"),
    ONE_DASH },
    ONE_DASH },
  { {"architecture", required_argument, NULL, 'A'},
  { {"architecture", required_argument, NULL, 'A'},
    'A', N_("ARCH"), N_("Set architecture") , TWO_DASHES },
    'A', N_("ARCH"), N_("Set architecture") , TWO_DASHES },
  { {"format", required_argument, NULL, 'b'},
  { {"format", required_argument, NULL, 'b'},
    'b', N_("TARGET"), N_("Specify target for following input files"),
    'b', N_("TARGET"), N_("Specify target for following input files"),
    TWO_DASHES },
    TWO_DASHES },
  { {"mri-script", required_argument, NULL, 'c'},
  { {"mri-script", required_argument, NULL, 'c'},
    'c', N_("FILE"), N_("Read MRI format linker script"), TWO_DASHES },
    'c', N_("FILE"), N_("Read MRI format linker script"), TWO_DASHES },
  { {"dc", no_argument, NULL, 'd'},
  { {"dc", no_argument, NULL, 'd'},
    'd', NULL, N_("Force common symbols to be defined"), ONE_DASH },
    'd', NULL, N_("Force common symbols to be defined"), ONE_DASH },
  { {"dp", no_argument, NULL, 'd'},
  { {"dp", no_argument, NULL, 'd'},
    '\0', NULL, NULL, ONE_DASH },
    '\0', NULL, NULL, ONE_DASH },
  { {"entry", required_argument, NULL, 'e'},
  { {"entry", required_argument, NULL, 'e'},
    'e', N_("ADDRESS"), N_("Set start address"), TWO_DASHES },
    'e', N_("ADDRESS"), N_("Set start address"), TWO_DASHES },
  { {"export-dynamic", no_argument, NULL, OPTION_EXPORT_DYNAMIC},
  { {"export-dynamic", no_argument, NULL, OPTION_EXPORT_DYNAMIC},
    'E', NULL, N_("Export all dynamic symbols"), TWO_DASHES },
    'E', NULL, N_("Export all dynamic symbols"), TWO_DASHES },
  { {"no-export-dynamic", no_argument, NULL, OPTION_NO_EXPORT_DYNAMIC},
  { {"no-export-dynamic", no_argument, NULL, OPTION_NO_EXPORT_DYNAMIC},
    '\0', NULL, N_("Undo the effect of --export-dynamic"), TWO_DASHES },
    '\0', NULL, N_("Undo the effect of --export-dynamic"), TWO_DASHES },
  { {"EB", no_argument, NULL, OPTION_EB},
  { {"EB", no_argument, NULL, OPTION_EB},
    '\0', NULL, N_("Link big-endian objects"), ONE_DASH },
    '\0', NULL, N_("Link big-endian objects"), ONE_DASH },
  { {"EL", no_argument, NULL, OPTION_EL},
  { {"EL", no_argument, NULL, OPTION_EL},
    '\0', NULL, N_("Link little-endian objects"), ONE_DASH },
    '\0', NULL, N_("Link little-endian objects"), ONE_DASH },
  { {"auxiliary", required_argument, NULL, 'f'},
  { {"auxiliary", required_argument, NULL, 'f'},
    'f', N_("SHLIB"), N_("Auxiliary filter for shared object symbol table"),
    'f', N_("SHLIB"), N_("Auxiliary filter for shared object symbol table"),
    TWO_DASHES },
    TWO_DASHES },
  { {"filter", required_argument, NULL, 'F'},
  { {"filter", required_argument, NULL, 'F'},
    'F', N_("SHLIB"), N_("Filter for shared object symbol table"),
    'F', N_("SHLIB"), N_("Filter for shared object symbol table"),
    TWO_DASHES },
    TWO_DASHES },
  { {NULL, no_argument, NULL, '\0'},
  { {NULL, no_argument, NULL, '\0'},
    'g', NULL, N_("Ignored"), ONE_DASH },
    'g', NULL, N_("Ignored"), ONE_DASH },
  { {"gpsize", required_argument, NULL, 'G'},
  { {"gpsize", required_argument, NULL, 'G'},
    'G', N_("SIZE"), N_("Small data size (if no size, same as --shared)"),
    'G', N_("SIZE"), N_("Small data size (if no size, same as --shared)"),
    TWO_DASHES },
    TWO_DASHES },
  { {"soname", required_argument, NULL, OPTION_SONAME},
  { {"soname", required_argument, NULL, OPTION_SONAME},
    'h', N_("FILENAME"), N_("Set internal name of shared library"), ONE_DASH },
    'h', N_("FILENAME"), N_("Set internal name of shared library"), ONE_DASH },
  { {"dynamic-linker", required_argument, NULL, OPTION_DYNAMIC_LINKER},
  { {"dynamic-linker", required_argument, NULL, OPTION_DYNAMIC_LINKER},
    'I', N_("PROGRAM"), N_("Set PROGRAM as the dynamic linker to use"),
    'I', N_("PROGRAM"), N_("Set PROGRAM as the dynamic linker to use"),
    TWO_DASHES },
    TWO_DASHES },
  { {"library", required_argument, NULL, 'l'},
  { {"library", required_argument, NULL, 'l'},
    'l', N_("LIBNAME"), N_("Search for library LIBNAME"), TWO_DASHES },
    'l', N_("LIBNAME"), N_("Search for library LIBNAME"), TWO_DASHES },
  { {"library-path", required_argument, NULL, 'L'},
  { {"library-path", required_argument, NULL, 'L'},
    'L', N_("DIRECTORY"), N_("Add DIRECTORY to library search path"),
    'L', N_("DIRECTORY"), N_("Add DIRECTORY to library search path"),
    TWO_DASHES },
    TWO_DASHES },
  { {"sysroot=<DIRECTORY>", required_argument, NULL, OPTION_SYSROOT},
  { {"sysroot=<DIRECTORY>", required_argument, NULL, OPTION_SYSROOT},
    '\0', NULL, N_("Override the default sysroot location"), TWO_DASHES },
    '\0', NULL, N_("Override the default sysroot location"), TWO_DASHES },
  { {NULL, required_argument, NULL, '\0'},
  { {NULL, required_argument, NULL, '\0'},
    'm', N_("EMULATION"), N_("Set emulation"), ONE_DASH },
    'm', N_("EMULATION"), N_("Set emulation"), ONE_DASH },
  { {"print-map", no_argument, NULL, 'M'},
  { {"print-map", no_argument, NULL, 'M'},
    'M', NULL, N_("Print map file on standard output"), TWO_DASHES },
    'M', NULL, N_("Print map file on standard output"), TWO_DASHES },
  { {"nmagic", no_argument, NULL, 'n'},
  { {"nmagic", no_argument, NULL, 'n'},
    'n', NULL, N_("Do not page align data"), TWO_DASHES },
    'n', NULL, N_("Do not page align data"), TWO_DASHES },
  { {"omagic", no_argument, NULL, 'N'},
  { {"omagic", no_argument, NULL, 'N'},
    'N', NULL, N_("Do not page align data, do not make text readonly"),
    'N', NULL, N_("Do not page align data, do not make text readonly"),
    EXACTLY_TWO_DASHES },
    EXACTLY_TWO_DASHES },
  { {"no-omagic", no_argument, NULL, OPTION_NO_OMAGIC},
  { {"no-omagic", no_argument, NULL, OPTION_NO_OMAGIC},
    '\0', NULL, N_("Page align data, make text readonly"),
    '\0', NULL, N_("Page align data, make text readonly"),
    EXACTLY_TWO_DASHES },
    EXACTLY_TWO_DASHES },
  { {"output", required_argument, NULL, 'o'},
  { {"output", required_argument, NULL, 'o'},
    'o', N_("FILE"), N_("Set output file name"), EXACTLY_TWO_DASHES },
    'o', N_("FILE"), N_("Set output file name"), EXACTLY_TWO_DASHES },
  { {NULL, required_argument, NULL, '\0'},
  { {NULL, required_argument, NULL, '\0'},
    'O', NULL, N_("Optimize output file"), ONE_DASH },
    'O', NULL, N_("Optimize output file"), ONE_DASH },
  { {"Qy", no_argument, NULL, OPTION_IGNORE},
  { {"Qy", no_argument, NULL, OPTION_IGNORE},
    '\0', NULL, N_("Ignored for SVR4 compatibility"), ONE_DASH },
    '\0', NULL, N_("Ignored for SVR4 compatibility"), ONE_DASH },
  { {"emit-relocs", no_argument, NULL, 'q'},
  { {"emit-relocs", no_argument, NULL, 'q'},
    'q', NULL, "Generate relocations in final output", TWO_DASHES },
    'q', NULL, "Generate relocations in final output", TWO_DASHES },
  { {"relocatable", no_argument, NULL, 'r'},
  { {"relocatable", no_argument, NULL, 'r'},
    'r', NULL, N_("Generate relocatable output"), TWO_DASHES },
    'r', NULL, N_("Generate relocatable output"), TWO_DASHES },
  { {NULL, no_argument, NULL, '\0'},
  { {NULL, no_argument, NULL, '\0'},
    'i', NULL, NULL, ONE_DASH },
    'i', NULL, NULL, ONE_DASH },
  { {"just-symbols", required_argument, NULL, 'R'},
  { {"just-symbols", required_argument, NULL, 'R'},
    'R', N_("FILE"), N_("Just link symbols (if directory, same as --rpath)"),
    'R', N_("FILE"), N_("Just link symbols (if directory, same as --rpath)"),
    TWO_DASHES },
    TWO_DASHES },
  { {"strip-all", no_argument, NULL, 's'},
  { {"strip-all", no_argument, NULL, 's'},
    's', NULL, N_("Strip all symbols"), TWO_DASHES },
    's', NULL, N_("Strip all symbols"), TWO_DASHES },
  { {"strip-debug", no_argument, NULL, 'S'},
  { {"strip-debug", no_argument, NULL, 'S'},
    'S', NULL, N_("Strip debugging symbols"), TWO_DASHES },
    'S', NULL, N_("Strip debugging symbols"), TWO_DASHES },
  { {"strip-discarded", no_argument, NULL, OPTION_STRIP_DISCARDED},
  { {"strip-discarded", no_argument, NULL, OPTION_STRIP_DISCARDED},
    '\0', NULL, N_("Strip symbols in discarded sections"), TWO_DASHES },
    '\0', NULL, N_("Strip symbols in discarded sections"), TWO_DASHES },
  { {"no-strip-discarded", no_argument, NULL, OPTION_NO_STRIP_DISCARDED},
  { {"no-strip-discarded", no_argument, NULL, OPTION_NO_STRIP_DISCARDED},
    '\0', NULL, N_("Do not strip symbols in discarded sections"), TWO_DASHES },
    '\0', NULL, N_("Do not strip symbols in discarded sections"), TWO_DASHES },
  { {"trace", no_argument, NULL, 't'},
  { {"trace", no_argument, NULL, 't'},
    't', NULL, N_("Trace file opens"), TWO_DASHES },
    't', NULL, N_("Trace file opens"), TWO_DASHES },
  { {"script", required_argument, NULL, 'T'},
  { {"script", required_argument, NULL, 'T'},
    'T', N_("FILE"), N_("Read linker script"), TWO_DASHES },
    'T', N_("FILE"), N_("Read linker script"), TWO_DASHES },
  { {"default-script", required_argument, NULL, OPTION_DEFAULT_SCRIPT},
  { {"default-script", required_argument, NULL, OPTION_DEFAULT_SCRIPT},
    '\0', N_("FILE"), N_("Read default linker script"), TWO_DASHES },
    '\0', N_("FILE"), N_("Read default linker script"), TWO_DASHES },
  { {"dT", required_argument, NULL, OPTION_DEFAULT_SCRIPT},
  { {"dT", required_argument, NULL, OPTION_DEFAULT_SCRIPT},
    '\0', NULL, NULL, ONE_DASH },
    '\0', NULL, NULL, ONE_DASH },
  { {"undefined", required_argument, NULL, 'u'},
  { {"undefined", required_argument, NULL, 'u'},
    'u', N_("SYMBOL"), N_("Start with undefined reference to SYMBOL"),
    'u', N_("SYMBOL"), N_("Start with undefined reference to SYMBOL"),
    TWO_DASHES },
    TWO_DASHES },
  { {"unique", optional_argument, NULL, OPTION_UNIQUE},
  { {"unique", optional_argument, NULL, OPTION_UNIQUE},
    '\0', N_("[=SECTION]"),
    '\0', N_("[=SECTION]"),
    N_("Don't merge input [SECTION | orphan] sections"), TWO_DASHES },
    N_("Don't merge input [SECTION | orphan] sections"), TWO_DASHES },
  { {"Ur", no_argument, NULL, OPTION_UR},
  { {"Ur", no_argument, NULL, OPTION_UR},
    '\0', NULL, N_("Build global constructor/destructor tables"), ONE_DASH },
    '\0', NULL, N_("Build global constructor/destructor tables"), ONE_DASH },
  { {"version", no_argument, NULL, OPTION_VERSION},
  { {"version", no_argument, NULL, OPTION_VERSION},
    'v', NULL, N_("Print version information"), TWO_DASHES },
    'v', NULL, N_("Print version information"), TWO_DASHES },
  { {NULL, no_argument, NULL, '\0'},
  { {NULL, no_argument, NULL, '\0'},
    'V', NULL, N_("Print version and emulation information"), ONE_DASH },
    'V', NULL, N_("Print version and emulation information"), ONE_DASH },
  { {"discard-all", no_argument, NULL, 'x'},
  { {"discard-all", no_argument, NULL, 'x'},
    'x', NULL, N_("Discard all local symbols"), TWO_DASHES },
    'x', NULL, N_("Discard all local symbols"), TWO_DASHES },
  { {"discard-locals", no_argument, NULL, 'X'},
  { {"discard-locals", no_argument, NULL, 'X'},
    'X', NULL, N_("Discard temporary local symbols (default)"), TWO_DASHES },
    'X', NULL, N_("Discard temporary local symbols (default)"), TWO_DASHES },
  { {"discard-none", no_argument, NULL, OPTION_DISCARD_NONE},
  { {"discard-none", no_argument, NULL, OPTION_DISCARD_NONE},
    '\0', NULL, N_("Don't discard any local symbols"), TWO_DASHES },
    '\0', NULL, N_("Don't discard any local symbols"), TWO_DASHES },
  { {"trace-symbol", required_argument, NULL, 'y'},
  { {"trace-symbol", required_argument, NULL, 'y'},
    'y', N_("SYMBOL"), N_("Trace mentions of SYMBOL"), TWO_DASHES },
    'y', N_("SYMBOL"), N_("Trace mentions of SYMBOL"), TWO_DASHES },
  { {NULL, required_argument, NULL, '\0'},
  { {NULL, required_argument, NULL, '\0'},
    'Y', N_("PATH"), N_("Default search path for Solaris compatibility"),
    'Y', N_("PATH"), N_("Default search path for Solaris compatibility"),
    ONE_DASH },
    ONE_DASH },
  { {"start-group", no_argument, NULL, '('},
  { {"start-group", no_argument, NULL, '('},
    '(', NULL, N_("Start a group"), TWO_DASHES },
    '(', NULL, N_("Start a group"), TWO_DASHES },
  { {"end-group", no_argument, NULL, ')'},
  { {"end-group", no_argument, NULL, ')'},
    ')', NULL, N_("End a group"), TWO_DASHES },
    ')', NULL, N_("End a group"), TWO_DASHES },
  { {"accept-unknown-input-arch", no_argument, NULL,
  { {"accept-unknown-input-arch", no_argument, NULL,
     OPTION_ACCEPT_UNKNOWN_INPUT_ARCH},
     OPTION_ACCEPT_UNKNOWN_INPUT_ARCH},
    '\0', NULL,
    '\0', NULL,
    N_("Accept input files whose architecture cannot be determined"),
    N_("Accept input files whose architecture cannot be determined"),
    TWO_DASHES },
    TWO_DASHES },
  { {"no-accept-unknown-input-arch", no_argument, NULL,
  { {"no-accept-unknown-input-arch", no_argument, NULL,
     OPTION_NO_ACCEPT_UNKNOWN_INPUT_ARCH},
     OPTION_NO_ACCEPT_UNKNOWN_INPUT_ARCH},
    '\0', NULL, N_("Reject input files whose architecture is unknown"),
    '\0', NULL, N_("Reject input files whose architecture is unknown"),
    TWO_DASHES },
    TWO_DASHES },
  { {"add-needed", no_argument, NULL, OPTION_ADD_NEEDED},
  { {"add-needed", no_argument, NULL, OPTION_ADD_NEEDED},
    '\0', NULL, N_("Set DT_NEEDED tags for DT_NEEDED entries in\n"
    '\0', NULL, N_("Set DT_NEEDED tags for DT_NEEDED entries in\n"
                   "                                following dynamic libs"),
                   "                                following dynamic libs"),
    TWO_DASHES },
    TWO_DASHES },
  { {"no-add-needed", no_argument, NULL, OPTION_NO_ADD_NEEDED},
  { {"no-add-needed", no_argument, NULL, OPTION_NO_ADD_NEEDED},
    '\0', NULL, N_("Do not set DT_NEEDED tags for DT_NEEDED entries\n"
    '\0', NULL, N_("Do not set DT_NEEDED tags for DT_NEEDED entries\n"
                   "                                in following dynamic libs"),
                   "                                in following dynamic libs"),
    TWO_DASHES },
    TWO_DASHES },
  { {"as-needed", no_argument, NULL, OPTION_AS_NEEDED},
  { {"as-needed", no_argument, NULL, OPTION_AS_NEEDED},
    '\0', NULL, N_("Only set DT_NEEDED for following dynamic libs if used"),
    '\0', NULL, N_("Only set DT_NEEDED for following dynamic libs if used"),
    TWO_DASHES },
    TWO_DASHES },
  { {"no-as-needed", no_argument, NULL, OPTION_NO_AS_NEEDED},
  { {"no-as-needed", no_argument, NULL, OPTION_NO_AS_NEEDED},
    '\0', NULL, N_("Always set DT_NEEDED for following dynamic libs"),
    '\0', NULL, N_("Always set DT_NEEDED for following dynamic libs"),
    TWO_DASHES },
    TWO_DASHES },
  { {"assert", required_argument, NULL, OPTION_ASSERT},
  { {"assert", required_argument, NULL, OPTION_ASSERT},
    '\0', N_("KEYWORD"), N_("Ignored for SunOS compatibility"), ONE_DASH },
    '\0', N_("KEYWORD"), N_("Ignored for SunOS compatibility"), ONE_DASH },
  { {"Bdynamic", no_argument, NULL, OPTION_CALL_SHARED},
  { {"Bdynamic", no_argument, NULL, OPTION_CALL_SHARED},
    '\0', NULL, N_("Link against shared libraries"), ONE_DASH },
    '\0', NULL, N_("Link against shared libraries"), ONE_DASH },
  { {"dy", no_argument, NULL, OPTION_CALL_SHARED},
  { {"dy", no_argument, NULL, OPTION_CALL_SHARED},
    '\0', NULL, NULL, ONE_DASH },
    '\0', NULL, NULL, ONE_DASH },
  { {"call_shared", no_argument, NULL, OPTION_CALL_SHARED},
  { {"call_shared", no_argument, NULL, OPTION_CALL_SHARED},
    '\0', NULL, NULL, ONE_DASH },
    '\0', NULL, NULL, ONE_DASH },
  { {"Bstatic", no_argument, NULL, OPTION_NON_SHARED},
  { {"Bstatic", no_argument, NULL, OPTION_NON_SHARED},
    '\0', NULL, N_("Do not link against shared libraries"), ONE_DASH },
    '\0', NULL, N_("Do not link against shared libraries"), ONE_DASH },
  { {"dn", no_argument, NULL, OPTION_NON_SHARED},
  { {"dn", no_argument, NULL, OPTION_NON_SHARED},
    '\0', NULL, NULL, ONE_DASH },
    '\0', NULL, NULL, ONE_DASH },
  { {"non_shared", no_argument, NULL, OPTION_NON_SHARED},
  { {"non_shared", no_argument, NULL, OPTION_NON_SHARED},
    '\0', NULL, NULL, ONE_DASH },
    '\0', NULL, NULL, ONE_DASH },
  { {"static", no_argument, NULL, OPTION_NON_SHARED},
  { {"static", no_argument, NULL, OPTION_NON_SHARED},
    '\0', NULL, NULL, ONE_DASH },
    '\0', NULL, NULL, ONE_DASH },
  { {"Bsymbolic", no_argument, NULL, OPTION_SYMBOLIC},
  { {"Bsymbolic", no_argument, NULL, OPTION_SYMBOLIC},
    '\0', NULL, N_("Bind global references locally"), ONE_DASH },
    '\0', NULL, N_("Bind global references locally"), ONE_DASH },
  { {"Bsymbolic-functions", no_argument, NULL, OPTION_SYMBOLIC_FUNCTIONS},
  { {"Bsymbolic-functions", no_argument, NULL, OPTION_SYMBOLIC_FUNCTIONS},
    '\0', NULL, N_("Bind global function references locally"), ONE_DASH },
    '\0', NULL, N_("Bind global function references locally"), ONE_DASH },
  { {"check-sections", no_argument, NULL, OPTION_CHECK_SECTIONS},
  { {"check-sections", no_argument, NULL, OPTION_CHECK_SECTIONS},
    '\0', NULL, N_("Check section addresses for overlaps (default)"),
    '\0', NULL, N_("Check section addresses for overlaps (default)"),
    TWO_DASHES },
    TWO_DASHES },
  { {"no-check-sections", no_argument, NULL, OPTION_NO_CHECK_SECTIONS},
  { {"no-check-sections", no_argument, NULL, OPTION_NO_CHECK_SECTIONS},
    '\0', NULL, N_("Do not check section addresses for overlaps"),
    '\0', NULL, N_("Do not check section addresses for overlaps"),
    TWO_DASHES },
    TWO_DASHES },
  { {"cref", no_argument, NULL, OPTION_CREF},
  { {"cref", no_argument, NULL, OPTION_CREF},
    '\0', NULL, N_("Output cross reference table"), TWO_DASHES },
    '\0', NULL, N_("Output cross reference table"), TWO_DASHES },
  { {"defsym", required_argument, NULL, OPTION_DEFSYM},
  { {"defsym", required_argument, NULL, OPTION_DEFSYM},
    '\0', N_("SYMBOL=EXPRESSION"), N_("Define a symbol"), TWO_DASHES },
    '\0', N_("SYMBOL=EXPRESSION"), N_("Define a symbol"), TWO_DASHES },
  { {"demangle", optional_argument, NULL, OPTION_DEMANGLE},
  { {"demangle", optional_argument, NULL, OPTION_DEMANGLE},
    '\0', N_("[=STYLE]"), N_("Demangle symbol names [using STYLE]"),
    '\0', N_("[=STYLE]"), N_("Demangle symbol names [using STYLE]"),
    TWO_DASHES },
    TWO_DASHES },
  { {"embedded-relocs", no_argument, NULL, OPTION_EMBEDDED_RELOCS},
  { {"embedded-relocs", no_argument, NULL, OPTION_EMBEDDED_RELOCS},
    '\0', NULL, N_("Generate embedded relocs"), TWO_DASHES},
    '\0', NULL, N_("Generate embedded relocs"), TWO_DASHES},
  { {"fatal-warnings", no_argument, NULL, OPTION_WARN_FATAL},
  { {"fatal-warnings", no_argument, NULL, OPTION_WARN_FATAL},
    '\0', NULL, N_("Treat warnings as errors"),
    '\0', NULL, N_("Treat warnings as errors"),
    TWO_DASHES },
    TWO_DASHES },
  { {"no-fatal-warnings", no_argument, NULL, OPTION_NO_WARN_FATAL},
  { {"no-fatal-warnings", no_argument, NULL, OPTION_NO_WARN_FATAL},
    '\0', NULL, N_("Do not treat warnings as errors (default)"),
    '\0', NULL, N_("Do not treat warnings as errors (default)"),
    TWO_DASHES },
    TWO_DASHES },
  { {"fini", required_argument, NULL, OPTION_FINI},
  { {"fini", required_argument, NULL, OPTION_FINI},
    '\0', N_("SYMBOL"), N_("Call SYMBOL at unload-time"), ONE_DASH },
    '\0', N_("SYMBOL"), N_("Call SYMBOL at unload-time"), ONE_DASH },
  { {"force-exe-suffix", no_argument, NULL, OPTION_FORCE_EXE_SUFFIX},
  { {"force-exe-suffix", no_argument, NULL, OPTION_FORCE_EXE_SUFFIX},
    '\0', NULL, N_("Force generation of file with .exe suffix"), TWO_DASHES},
    '\0', NULL, N_("Force generation of file with .exe suffix"), TWO_DASHES},
  { {"gc-sections", no_argument, NULL, OPTION_GC_SECTIONS},
  { {"gc-sections", no_argument, NULL, OPTION_GC_SECTIONS},
    '\0', NULL, N_("Remove unused sections (on some targets)"),
    '\0', NULL, N_("Remove unused sections (on some targets)"),
    TWO_DASHES },
    TWO_DASHES },
  { {"no-gc-sections", no_argument, NULL, OPTION_NO_GC_SECTIONS},
  { {"no-gc-sections", no_argument, NULL, OPTION_NO_GC_SECTIONS},
    '\0', NULL, N_("Don't remove unused sections (default)"),
    '\0', NULL, N_("Don't remove unused sections (default)"),
    TWO_DASHES },
    TWO_DASHES },
  { {"print-gc-sections", no_argument, NULL, OPTION_PRINT_GC_SECTIONS},
  { {"print-gc-sections", no_argument, NULL, OPTION_PRINT_GC_SECTIONS},
    '\0', NULL, N_("List removed unused sections on stderr"),
    '\0', NULL, N_("List removed unused sections on stderr"),
    TWO_DASHES },
    TWO_DASHES },
  { {"no-print-gc-sections", no_argument, NULL, OPTION_NO_PRINT_GC_SECTIONS},
  { {"no-print-gc-sections", no_argument, NULL, OPTION_NO_PRINT_GC_SECTIONS},
    '\0', NULL, N_("Do not list removed unused sections"),
    '\0', NULL, N_("Do not list removed unused sections"),
    TWO_DASHES },
    TWO_DASHES },
  { {"hash-size=<NUMBER>", required_argument, NULL, OPTION_HASH_SIZE},
  { {"hash-size=<NUMBER>", required_argument, NULL, OPTION_HASH_SIZE},
    '\0', NULL, N_("Set default hash table size close to <NUMBER>"),
    '\0', NULL, N_("Set default hash table size close to <NUMBER>"),
    TWO_DASHES },
    TWO_DASHES },
  { {"help", no_argument, NULL, OPTION_HELP},
  { {"help", no_argument, NULL, OPTION_HELP},
    '\0', NULL, N_("Print option help"), TWO_DASHES },
    '\0', NULL, N_("Print option help"), TWO_DASHES },
  { {"init", required_argument, NULL, OPTION_INIT},
  { {"init", required_argument, NULL, OPTION_INIT},
    '\0', N_("SYMBOL"), N_("Call SYMBOL at load-time"), ONE_DASH },
    '\0', N_("SYMBOL"), N_("Call SYMBOL at load-time"), ONE_DASH },
  { {"Map", required_argument, NULL, OPTION_MAP},
  { {"Map", required_argument, NULL, OPTION_MAP},
    '\0', N_("FILE"), N_("Write a map file"), ONE_DASH },
    '\0', N_("FILE"), N_("Write a map file"), ONE_DASH },
  { {"no-define-common", no_argument, NULL, OPTION_NO_DEFINE_COMMON},
  { {"no-define-common", no_argument, NULL, OPTION_NO_DEFINE_COMMON},
    '\0', NULL, N_("Do not define Common storage"), TWO_DASHES },
    '\0', NULL, N_("Do not define Common storage"), TWO_DASHES },
  { {"no-demangle", no_argument, NULL, OPTION_NO_DEMANGLE },
  { {"no-demangle", no_argument, NULL, OPTION_NO_DEMANGLE },
    '\0', NULL, N_("Do not demangle symbol names"), TWO_DASHES },
    '\0', NULL, N_("Do not demangle symbol names"), TWO_DASHES },
  { {"no-keep-memory", no_argument, NULL, OPTION_NO_KEEP_MEMORY},
  { {"no-keep-memory", no_argument, NULL, OPTION_NO_KEEP_MEMORY},
    '\0', NULL, N_("Use less memory and more disk I/O"), TWO_DASHES },
    '\0', NULL, N_("Use less memory and more disk I/O"), TWO_DASHES },
  { {"no-undefined", no_argument, NULL, OPTION_NO_UNDEFINED},
  { {"no-undefined", no_argument, NULL, OPTION_NO_UNDEFINED},
    '\0', NULL, N_("Do not allow unresolved references in object files"),
    '\0', NULL, N_("Do not allow unresolved references in object files"),
    TWO_DASHES },
    TWO_DASHES },
  { {"allow-shlib-undefined", no_argument, NULL, OPTION_ALLOW_SHLIB_UNDEFINED},
  { {"allow-shlib-undefined", no_argument, NULL, OPTION_ALLOW_SHLIB_UNDEFINED},
    '\0', NULL, N_("Allow unresolved references in shared libaries"),
    '\0', NULL, N_("Allow unresolved references in shared libaries"),
    TWO_DASHES },
    TWO_DASHES },
  { {"no-allow-shlib-undefined", no_argument, NULL,
  { {"no-allow-shlib-undefined", no_argument, NULL,
     OPTION_NO_ALLOW_SHLIB_UNDEFINED},
     OPTION_NO_ALLOW_SHLIB_UNDEFINED},
    '\0', NULL, N_("Do not allow unresolved references in shared libs"),
    '\0', NULL, N_("Do not allow unresolved references in shared libs"),
    TWO_DASHES },
    TWO_DASHES },
  { {"allow-multiple-definition", no_argument, NULL,
  { {"allow-multiple-definition", no_argument, NULL,
     OPTION_ALLOW_MULTIPLE_DEFINITION},
     OPTION_ALLOW_MULTIPLE_DEFINITION},
    '\0', NULL, N_("Allow multiple definitions"), TWO_DASHES },
    '\0', NULL, N_("Allow multiple definitions"), TWO_DASHES },
  { {"no-undefined-version", no_argument, NULL, OPTION_NO_UNDEFINED_VERSION},
  { {"no-undefined-version", no_argument, NULL, OPTION_NO_UNDEFINED_VERSION},
    '\0', NULL, N_("Disallow undefined version"), TWO_DASHES },
    '\0', NULL, N_("Disallow undefined version"), TWO_DASHES },
  { {"default-symver", no_argument, NULL, OPTION_DEFAULT_SYMVER},
  { {"default-symver", no_argument, NULL, OPTION_DEFAULT_SYMVER},
    '\0', NULL, N_("Create default symbol version"), TWO_DASHES },
    '\0', NULL, N_("Create default symbol version"), TWO_DASHES },
  { {"default-imported-symver", no_argument, NULL,
  { {"default-imported-symver", no_argument, NULL,
      OPTION_DEFAULT_IMPORTED_SYMVER},
      OPTION_DEFAULT_IMPORTED_SYMVER},
    '\0', NULL, N_("Create default symbol version for imported symbols"),
    '\0', NULL, N_("Create default symbol version for imported symbols"),
    TWO_DASHES },
    TWO_DASHES },
  { {"no-warn-mismatch", no_argument, NULL, OPTION_NO_WARN_MISMATCH},
  { {"no-warn-mismatch", no_argument, NULL, OPTION_NO_WARN_MISMATCH},
    '\0', NULL, N_("Don't warn about mismatched input files"), TWO_DASHES},
    '\0', NULL, N_("Don't warn about mismatched input files"), TWO_DASHES},
  { {"no-warn-search-mismatch", no_argument, NULL,
  { {"no-warn-search-mismatch", no_argument, NULL,
     OPTION_NO_WARN_SEARCH_MISMATCH},
     OPTION_NO_WARN_SEARCH_MISMATCH},
    '\0', NULL, N_("Don't warn on finding an incompatible library"),
    '\0', NULL, N_("Don't warn on finding an incompatible library"),
    TWO_DASHES},
    TWO_DASHES},
  { {"no-whole-archive", no_argument, NULL, OPTION_NO_WHOLE_ARCHIVE},
  { {"no-whole-archive", no_argument, NULL, OPTION_NO_WHOLE_ARCHIVE},
    '\0', NULL, N_("Turn off --whole-archive"), TWO_DASHES },
    '\0', NULL, N_("Turn off --whole-archive"), TWO_DASHES },
  { {"noinhibit-exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC},
  { {"noinhibit-exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC},
    '\0', NULL, N_("Create an output file even if errors occur"),
    '\0', NULL, N_("Create an output file even if errors occur"),
    TWO_DASHES },
    TWO_DASHES },
  { {"noinhibit_exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC},
  { {"noinhibit_exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC},
    '\0', NULL, NULL, NO_HELP },
    '\0', NULL, NULL, NO_HELP },
  { {"nostdlib", no_argument, NULL, OPTION_NOSTDLIB},
  { {"nostdlib", no_argument, NULL, OPTION_NOSTDLIB},
    '\0', NULL, N_("Only use library directories specified on\n"
    '\0', NULL, N_("Only use library directories specified on\n"
                   "                                the command line"),
                   "                                the command line"),
    ONE_DASH },
    ONE_DASH },
  { {"oformat", required_argument, NULL, OPTION_OFORMAT},
  { {"oformat", required_argument, NULL, OPTION_OFORMAT},
    '\0', N_("TARGET"), N_("Specify target of output file"),
    '\0', N_("TARGET"), N_("Specify target of output file"),
    EXACTLY_TWO_DASHES },
    EXACTLY_TWO_DASHES },
  { {"qmagic", no_argument, NULL, OPTION_IGNORE},
  { {"qmagic", no_argument, NULL, OPTION_IGNORE},
    '\0', NULL, N_("Ignored for Linux compatibility"), ONE_DASH },
    '\0', NULL, N_("Ignored for Linux compatibility"), ONE_DASH },
  { {"reduce-memory-overheads", no_argument, NULL,
  { {"reduce-memory-overheads", no_argument, NULL,
     OPTION_REDUCE_MEMORY_OVERHEADS},
     OPTION_REDUCE_MEMORY_OVERHEADS},
    '\0', NULL, N_("Reduce memory overheads, possibly taking much longer"),
    '\0', NULL, N_("Reduce memory overheads, possibly taking much longer"),
    TWO_DASHES },
    TWO_DASHES },
  { {"relax", no_argument, NULL, OPTION_RELAX},
  { {"relax", no_argument, NULL, OPTION_RELAX},
    '\0', NULL, N_("Relax branches on certain targets"), TWO_DASHES },
    '\0', NULL, N_("Relax branches on certain targets"), TWO_DASHES },
  { {"retain-symbols-file", required_argument, NULL,
  { {"retain-symbols-file", required_argument, NULL,
     OPTION_RETAIN_SYMBOLS_FILE},
     OPTION_RETAIN_SYMBOLS_FILE},
    '\0', N_("FILE"), N_("Keep only symbols listed in FILE"), TWO_DASHES },
    '\0', N_("FILE"), N_("Keep only symbols listed in FILE"), TWO_DASHES },
  { {"rpath", required_argument, NULL, OPTION_RPATH},
  { {"rpath", required_argument, NULL, OPTION_RPATH},
    '\0', N_("PATH"), N_("Set runtime shared library search path"), ONE_DASH },
    '\0', N_("PATH"), N_("Set runtime shared library search path"), ONE_DASH },
  { {"rpath-link", required_argument, NULL, OPTION_RPATH_LINK},
  { {"rpath-link", required_argument, NULL, OPTION_RPATH_LINK},
    '\0', N_("PATH"), N_("Set link time shared library search path"),
    '\0', N_("PATH"), N_("Set link time shared library search path"),
    ONE_DASH },
    ONE_DASH },
  { {"shared", no_argument, NULL, OPTION_SHARED},
  { {"shared", no_argument, NULL, OPTION_SHARED},
    '\0', NULL, N_("Create a shared library"), ONE_DASH },
    '\0', NULL, N_("Create a shared library"), ONE_DASH },
  { {"Bshareable", no_argument, NULL, OPTION_SHARED }, /* FreeBSD.  */
  { {"Bshareable", no_argument, NULL, OPTION_SHARED }, /* FreeBSD.  */
    '\0', NULL, NULL, ONE_DASH },
    '\0', NULL, NULL, ONE_DASH },
  { {"pie", no_argument, NULL, OPTION_PIE},
  { {"pie", no_argument, NULL, OPTION_PIE},
    '\0', NULL, N_("Create a position independent executable"), ONE_DASH },
    '\0', NULL, N_("Create a position independent executable"), ONE_DASH },
  { {"pic-executable", no_argument, NULL, OPTION_PIE},
  { {"pic-executable", no_argument, NULL, OPTION_PIE},
    '\0', NULL, NULL, TWO_DASHES },
    '\0', NULL, NULL, TWO_DASHES },
  { {"sort-common", optional_argument, NULL, OPTION_SORT_COMMON},
  { {"sort-common", optional_argument, NULL, OPTION_SORT_COMMON},
    '\0', N_("[=ascending|descending]"),
    '\0', N_("[=ascending|descending]"),
    N_("Sort common symbols by alignment [in specified order]"),
    N_("Sort common symbols by alignment [in specified order]"),
    TWO_DASHES },
    TWO_DASHES },
  { {"sort_common", no_argument, NULL, OPTION_SORT_COMMON},
  { {"sort_common", no_argument, NULL, OPTION_SORT_COMMON},
    '\0', NULL, NULL, NO_HELP },
    '\0', NULL, NULL, NO_HELP },
  { {"sort-section", required_argument, NULL, OPTION_SORT_SECTION},
  { {"sort-section", required_argument, NULL, OPTION_SORT_SECTION},
    '\0', N_("name|alignment"),
    '\0', N_("name|alignment"),
    N_("Sort sections by name or maximum alignment"), TWO_DASHES },
    N_("Sort sections by name or maximum alignment"), TWO_DASHES },
  { {"spare-dynamic-tags", required_argument, NULL, OPTION_SPARE_DYNAMIC_TAGS},
  { {"spare-dynamic-tags", required_argument, NULL, OPTION_SPARE_DYNAMIC_TAGS},
    '\0', N_("COUNT"), N_("How many tags to reserve in .dynamic section"),
    '\0', N_("COUNT"), N_("How many tags to reserve in .dynamic section"),
    TWO_DASHES },
    TWO_DASHES },
  { {"split-by-file", optional_argument, NULL, OPTION_SPLIT_BY_FILE},
  { {"split-by-file", optional_argument, NULL, OPTION_SPLIT_BY_FILE},
    '\0', N_("[=SIZE]"), N_("Split output sections every SIZE octets"),
    '\0', N_("[=SIZE]"), N_("Split output sections every SIZE octets"),
    TWO_DASHES },
    TWO_DASHES },
  { {"split-by-reloc", optional_argument, NULL, OPTION_SPLIT_BY_RELOC},
  { {"split-by-reloc", optional_argument, NULL, OPTION_SPLIT_BY_RELOC},
    '\0', N_("[=COUNT]"), N_("Split output sections every COUNT relocs"),
    '\0', N_("[=COUNT]"), N_("Split output sections every COUNT relocs"),
    TWO_DASHES },
    TWO_DASHES },
  { {"stats", no_argument, NULL, OPTION_STATS},
  { {"stats", no_argument, NULL, OPTION_STATS},
    '\0', NULL, N_("Print memory usage statistics"), TWO_DASHES },
    '\0', NULL, N_("Print memory usage statistics"), TWO_DASHES },
  { {"target-help", no_argument, NULL, OPTION_TARGET_HELP},
  { {"target-help", no_argument, NULL, OPTION_TARGET_HELP},
    '\0', NULL, N_("Display target specific options"), TWO_DASHES },
    '\0', NULL, N_("Display target specific options"), TWO_DASHES },
  { {"task-link", required_argument, NULL, OPTION_TASK_LINK},
  { {"task-link", required_argument, NULL, OPTION_TASK_LINK},
    '\0', N_("SYMBOL"), N_("Do task level linking"), TWO_DASHES },
    '\0', N_("SYMBOL"), N_("Do task level linking"), TWO_DASHES },
  { {"traditional-format", no_argument, NULL, OPTION_TRADITIONAL_FORMAT},
  { {"traditional-format", no_argument, NULL, OPTION_TRADITIONAL_FORMAT},
    '\0', NULL, N_("Use same format as native linker"), TWO_DASHES },
    '\0', NULL, N_("Use same format as native linker"), TWO_DASHES },
  { {"section-start", required_argument, NULL, OPTION_SECTION_START},
  { {"section-start", required_argument, NULL, OPTION_SECTION_START},
    '\0', N_("SECTION=ADDRESS"), N_("Set address of named section"),
    '\0', N_("SECTION=ADDRESS"), N_("Set address of named section"),
    TWO_DASHES },
    TWO_DASHES },
  { {"Tbss", required_argument, NULL, OPTION_TBSS},
  { {"Tbss", required_argument, NULL, OPTION_TBSS},
    '\0', N_("ADDRESS"), N_("Set address of .bss section"), ONE_DASH },
    '\0', N_("ADDRESS"), N_("Set address of .bss section"), ONE_DASH },
  { {"Tdata", required_argument, NULL, OPTION_TDATA},
  { {"Tdata", required_argument, NULL, OPTION_TDATA},
    '\0', N_("ADDRESS"), N_("Set address of .data section"), ONE_DASH },
    '\0', N_("ADDRESS"), N_("Set address of .data section"), ONE_DASH },
  { {"Ttext", required_argument, NULL, OPTION_TTEXT},
  { {"Ttext", required_argument, NULL, OPTION_TTEXT},
    '\0', N_("ADDRESS"), N_("Set address of .text section"), ONE_DASH },
    '\0', N_("ADDRESS"), N_("Set address of .text section"), ONE_DASH },
  { {"Ttext-segment", required_argument, NULL, OPTION_TTEXT_SEGMENT},
  { {"Ttext-segment", required_argument, NULL, OPTION_TTEXT_SEGMENT},
    '\0', N_("ADDRESS"), N_("Set address of text segment"), ONE_DASH },
    '\0', N_("ADDRESS"), N_("Set address of text segment"), ONE_DASH },
  { {"unresolved-symbols=<method>", required_argument, NULL,
  { {"unresolved-symbols=<method>", required_argument, NULL,
     OPTION_UNRESOLVED_SYMBOLS},
     OPTION_UNRESOLVED_SYMBOLS},
    '\0', NULL, N_("How to handle unresolved symbols.  <method> is:\n"
    '\0', NULL, N_("How to handle unresolved symbols.  <method> is:\n"
                   "                                ignore-all, report-all, ignore-in-object-files,\n"
                   "                                ignore-all, report-all, ignore-in-object-files,\n"
                   "                                ignore-in-shared-libs"),
                   "                                ignore-in-shared-libs"),
    TWO_DASHES },
    TWO_DASHES },
  { {"verbose", no_argument, NULL, OPTION_VERBOSE},
  { {"verbose", no_argument, NULL, OPTION_VERBOSE},
    '\0', NULL, N_("Output lots of information during link"), TWO_DASHES },
    '\0', NULL, N_("Output lots of information during link"), TWO_DASHES },
  { {"dll-verbose", no_argument, NULL, OPTION_VERBOSE}, /* Linux.  */
  { {"dll-verbose", no_argument, NULL, OPTION_VERBOSE}, /* Linux.  */
    '\0', NULL, NULL, NO_HELP },
    '\0', NULL, NULL, NO_HELP },
  { {"version-script", required_argument, NULL, OPTION_VERSION_SCRIPT },
  { {"version-script", required_argument, NULL, OPTION_VERSION_SCRIPT },
    '\0', N_("FILE"), N_("Read version information script"), TWO_DASHES },
    '\0', N_("FILE"), N_("Read version information script"), TWO_DASHES },
  { {"version-exports-section", required_argument, NULL,
  { {"version-exports-section", required_argument, NULL,
     OPTION_VERSION_EXPORTS_SECTION },
     OPTION_VERSION_EXPORTS_SECTION },
    '\0', N_("SYMBOL"), N_("Take export symbols list from .exports, using\n"
    '\0', N_("SYMBOL"), N_("Take export symbols list from .exports, using\n"
                           "                                SYMBOL as the version."),
                           "                                SYMBOL as the version."),
    TWO_DASHES },
    TWO_DASHES },
  { {"dynamic-list-data", no_argument, NULL, OPTION_DYNAMIC_LIST_DATA},
  { {"dynamic-list-data", no_argument, NULL, OPTION_DYNAMIC_LIST_DATA},
    '\0', NULL, N_("Add data symbols to dynamic list"), TWO_DASHES },
    '\0', NULL, N_("Add data symbols to dynamic list"), TWO_DASHES },
  { {"dynamic-list-cpp-new", no_argument, NULL, OPTION_DYNAMIC_LIST_CPP_NEW},
  { {"dynamic-list-cpp-new", no_argument, NULL, OPTION_DYNAMIC_LIST_CPP_NEW},
    '\0', NULL, N_("Use C++ operator new/delete dynamic list"), TWO_DASHES },
    '\0', NULL, N_("Use C++ operator new/delete dynamic list"), TWO_DASHES },
  { {"dynamic-list-cpp-typeinfo", no_argument, NULL, OPTION_DYNAMIC_LIST_CPP_TYPEINFO},
  { {"dynamic-list-cpp-typeinfo", no_argument, NULL, OPTION_DYNAMIC_LIST_CPP_TYPEINFO},
    '\0', NULL, N_("Use C++ typeinfo dynamic list"), TWO_DASHES },
    '\0', NULL, N_("Use C++ typeinfo dynamic list"), TWO_DASHES },
  { {"dynamic-list", required_argument, NULL, OPTION_DYNAMIC_LIST},
  { {"dynamic-list", required_argument, NULL, OPTION_DYNAMIC_LIST},
    '\0', N_("FILE"), N_("Read dynamic list"), TWO_DASHES },
    '\0', N_("FILE"), N_("Read dynamic list"), TWO_DASHES },
  { {"warn-common", no_argument, NULL, OPTION_WARN_COMMON},
  { {"warn-common", no_argument, NULL, OPTION_WARN_COMMON},
    '\0', NULL, N_("Warn about duplicate common symbols"), TWO_DASHES },
    '\0', NULL, N_("Warn about duplicate common symbols"), TWO_DASHES },
  { {"warn-constructors", no_argument, NULL, OPTION_WARN_CONSTRUCTORS},
  { {"warn-constructors", no_argument, NULL, OPTION_WARN_CONSTRUCTORS},
    '\0', NULL, N_("Warn if global constructors/destructors are seen"),
    '\0', NULL, N_("Warn if global constructors/destructors are seen"),
    TWO_DASHES },
    TWO_DASHES },
  { {"warn-multiple-gp", no_argument, NULL, OPTION_WARN_MULTIPLE_GP},
  { {"warn-multiple-gp", no_argument, NULL, OPTION_WARN_MULTIPLE_GP},
    '\0', NULL, N_("Warn if the multiple GP values are used"), TWO_DASHES },
    '\0', NULL, N_("Warn if the multiple GP values are used"), TWO_DASHES },
  { {"warn-once", no_argument, NULL, OPTION_WARN_ONCE},
  { {"warn-once", no_argument, NULL, OPTION_WARN_ONCE},
    '\0', NULL, N_("Warn only once per undefined symbol"), TWO_DASHES },
    '\0', NULL, N_("Warn only once per undefined symbol"), TWO_DASHES },
  { {"warn-section-align", no_argument, NULL, OPTION_WARN_SECTION_ALIGN},
  { {"warn-section-align", no_argument, NULL, OPTION_WARN_SECTION_ALIGN},
    '\0', NULL, N_("Warn if start of section changes due to alignment"),
    '\0', NULL, N_("Warn if start of section changes due to alignment"),
    TWO_DASHES },
    TWO_DASHES },
  { {"warn-shared-textrel", no_argument, NULL, OPTION_WARN_SHARED_TEXTREL},
  { {"warn-shared-textrel", no_argument, NULL, OPTION_WARN_SHARED_TEXTREL},
    '\0', NULL, N_("Warn if shared object has DT_TEXTREL"),
    '\0', NULL, N_("Warn if shared object has DT_TEXTREL"),
    TWO_DASHES },
    TWO_DASHES },
  { {"warn-alternate-em", no_argument, NULL, OPTION_WARN_ALTERNATE_EM},
  { {"warn-alternate-em", no_argument, NULL, OPTION_WARN_ALTERNATE_EM},
    '\0', NULL, N_("Warn if an object has alternate ELF machine code"),
    '\0', NULL, N_("Warn if an object has alternate ELF machine code"),
    TWO_DASHES },
    TWO_DASHES },
  { {"warn-unresolved-symbols", no_argument, NULL,
  { {"warn-unresolved-symbols", no_argument, NULL,
     OPTION_WARN_UNRESOLVED_SYMBOLS},
     OPTION_WARN_UNRESOLVED_SYMBOLS},
    '\0', NULL, N_("Report unresolved symbols as warnings"), TWO_DASHES },
    '\0', NULL, N_("Report unresolved symbols as warnings"), TWO_DASHES },
  { {"error-unresolved-symbols", no_argument, NULL,
  { {"error-unresolved-symbols", no_argument, NULL,
     OPTION_ERROR_UNRESOLVED_SYMBOLS},
     OPTION_ERROR_UNRESOLVED_SYMBOLS},
    '\0', NULL, N_("Report unresolved symbols as errors"), TWO_DASHES },
    '\0', NULL, N_("Report unresolved symbols as errors"), TWO_DASHES },
  { {"whole-archive", no_argument, NULL, OPTION_WHOLE_ARCHIVE},
  { {"whole-archive", no_argument, NULL, OPTION_WHOLE_ARCHIVE},
    '\0', NULL, N_("Include all objects from following archives"),
    '\0', NULL, N_("Include all objects from following archives"),
    TWO_DASHES },
    TWO_DASHES },
  { {"wrap", required_argument, NULL, OPTION_WRAP},
  { {"wrap", required_argument, NULL, OPTION_WRAP},
    '\0', N_("SYMBOL"), N_("Use wrapper functions for SYMBOL"), TWO_DASHES },
    '\0', N_("SYMBOL"), N_("Use wrapper functions for SYMBOL"), TWO_DASHES },
};
};
 
 
#define OPTION_COUNT ARRAY_SIZE (ld_options)
#define OPTION_COUNT ARRAY_SIZE (ld_options)
 
 
void
void
parse_args (unsigned argc, char **argv)
parse_args (unsigned argc, char **argv)
{
{
  unsigned i;
  unsigned i;
  int is, il, irl;
  int is, il, irl;
  int ingroup = 0;
  int ingroup = 0;
  char *default_dirlist = NULL;
  char *default_dirlist = NULL;
  char *shortopts;
  char *shortopts;
  struct option *longopts;
  struct option *longopts;
  struct option *really_longopts;
  struct option *really_longopts;
  int last_optind;
  int last_optind;
  enum report_method how_to_report_unresolved_symbols = RM_GENERATE_ERROR;
  enum report_method how_to_report_unresolved_symbols = RM_GENERATE_ERROR;
 
 
  shortopts = (char *) xmalloc (OPTION_COUNT * 3 + 2);
  shortopts = (char *) xmalloc (OPTION_COUNT * 3 + 2);
  longopts = (struct option *)
  longopts = (struct option *)
      xmalloc (sizeof (*longopts) * (OPTION_COUNT + 1));
      xmalloc (sizeof (*longopts) * (OPTION_COUNT + 1));
  really_longopts = (struct option *)
  really_longopts = (struct option *)
      malloc (sizeof (*really_longopts) * (OPTION_COUNT + 1));
      malloc (sizeof (*really_longopts) * (OPTION_COUNT + 1));
 
 
  /* Starting the short option string with '-' is for programs that
  /* Starting the short option string with '-' is for programs that
     expect options and other ARGV-elements in any order and that care about
     expect options and other ARGV-elements in any order and that care about
     the ordering of the two.  We describe each non-option ARGV-element
     the ordering of the two.  We describe each non-option ARGV-element
     as if it were the argument of an option with character code 1.  */
     as if it were the argument of an option with character code 1.  */
  shortopts[0] = '-';
  shortopts[0] = '-';
  is = 1;
  is = 1;
  il = 0;
  il = 0;
  irl = 0;
  irl = 0;
  for (i = 0; i < OPTION_COUNT; i++)
  for (i = 0; i < OPTION_COUNT; i++)
    {
    {
      if (ld_options[i].shortopt != '\0')
      if (ld_options[i].shortopt != '\0')
        {
        {
          shortopts[is] = ld_options[i].shortopt;
          shortopts[is] = ld_options[i].shortopt;
          ++is;
          ++is;
          if (ld_options[i].opt.has_arg == required_argument
          if (ld_options[i].opt.has_arg == required_argument
              || ld_options[i].opt.has_arg == optional_argument)
              || ld_options[i].opt.has_arg == optional_argument)
            {
            {
              shortopts[is] = ':';
              shortopts[is] = ':';
              ++is;
              ++is;
              if (ld_options[i].opt.has_arg == optional_argument)
              if (ld_options[i].opt.has_arg == optional_argument)
                {
                {
                  shortopts[is] = ':';
                  shortopts[is] = ':';
                  ++is;
                  ++is;
                }
                }
            }
            }
        }
        }
      if (ld_options[i].opt.name != NULL)
      if (ld_options[i].opt.name != NULL)
        {
        {
          if (ld_options[i].control == EXACTLY_TWO_DASHES)
          if (ld_options[i].control == EXACTLY_TWO_DASHES)
            {
            {
              really_longopts[irl] = ld_options[i].opt;
              really_longopts[irl] = ld_options[i].opt;
              ++irl;
              ++irl;
            }
            }
          else
          else
            {
            {
              longopts[il] = ld_options[i].opt;
              longopts[il] = ld_options[i].opt;
              ++il;
              ++il;
            }
            }
        }
        }
    }
    }
  shortopts[is] = '\0';
  shortopts[is] = '\0';
  longopts[il].name = NULL;
  longopts[il].name = NULL;
  really_longopts[irl].name = NULL;
  really_longopts[irl].name = NULL;
 
 
  ldemul_add_options (is, &shortopts, il, &longopts, irl, &really_longopts);
  ldemul_add_options (is, &shortopts, il, &longopts, irl, &really_longopts);
 
 
  /* The -G option is ambiguous on different platforms.  Sometimes it
  /* The -G option is ambiguous on different platforms.  Sometimes it
     specifies the largest data size to put into the small data
     specifies the largest data size to put into the small data
     section.  Sometimes it is equivalent to --shared.  Unfortunately,
     section.  Sometimes it is equivalent to --shared.  Unfortunately,
     the first form takes an argument, while the second does not.
     the first form takes an argument, while the second does not.
 
 
     We need to permit the --shared form because on some platforms,
     We need to permit the --shared form because on some platforms,
     such as Solaris, gcc -shared will pass -G to the linker.
     such as Solaris, gcc -shared will pass -G to the linker.
 
 
     To permit either usage, we look through the argument list.  If we
     To permit either usage, we look through the argument list.  If we
     find -G not followed by a number, we change it into --shared.
     find -G not followed by a number, we change it into --shared.
     This will work for most normal cases.  */
     This will work for most normal cases.  */
  for (i = 1; i < argc; i++)
  for (i = 1; i < argc; i++)
    if (strcmp (argv[i], "-G") == 0
    if (strcmp (argv[i], "-G") == 0
        && (i + 1 >= argc
        && (i + 1 >= argc
            || ! ISDIGIT (argv[i + 1][0])))
            || ! ISDIGIT (argv[i + 1][0])))
      argv[i] = (char *) "--shared";
      argv[i] = (char *) "--shared";
 
 
  /* Because we permit long options to start with a single dash, and
  /* Because we permit long options to start with a single dash, and
     we have a --library option, and the -l option is conventionally
     we have a --library option, and the -l option is conventionally
     used with an immediately following argument, we can have bad
     used with an immediately following argument, we can have bad
     results if somebody tries to use -l with a library whose name
     results if somebody tries to use -l with a library whose name
     happens to start with "ibrary", as in -li.  We avoid problems by
     happens to start with "ibrary", as in -li.  We avoid problems by
     simply turning -l into --library.  This means that users will
     simply turning -l into --library.  This means that users will
     have to use two dashes in order to use --library, which is OK
     have to use two dashes in order to use --library, which is OK
     since that's how it is documented.
     since that's how it is documented.
 
 
     FIXME: It's possible that this problem can arise for other short
     FIXME: It's possible that this problem can arise for other short
     options as well, although the user does always have the recourse
     options as well, although the user does always have the recourse
     of adding a space between the option and the argument.  */
     of adding a space between the option and the argument.  */
  for (i = 1; i < argc; i++)
  for (i = 1; i < argc; i++)
    {
    {
      if (argv[i][0] == '-'
      if (argv[i][0] == '-'
          && argv[i][1] == 'l'
          && argv[i][1] == 'l'
          && argv[i][2] != '\0')
          && argv[i][2] != '\0')
        {
        {
          char *n;
          char *n;
 
 
          n = (char *) xmalloc (strlen (argv[i]) + 20);
          n = (char *) xmalloc (strlen (argv[i]) + 20);
          sprintf (n, "--library=%s", argv[i] + 2);
          sprintf (n, "--library=%s", argv[i] + 2);
          argv[i] = n;
          argv[i] = n;
        }
        }
    }
    }
 
 
  last_optind = -1;
  last_optind = -1;
  while (1)
  while (1)
    {
    {
      int longind;
      int longind;
      int optc;
      int optc;
 
 
      /* Using last_optind lets us avoid calling ldemul_parse_args
      /* Using last_optind lets us avoid calling ldemul_parse_args
         multiple times on a single option, which would lead to
         multiple times on a single option, which would lead to
         confusion in the internal static variables maintained by
         confusion in the internal static variables maintained by
         getopt.  This could otherwise happen for an argument like
         getopt.  This could otherwise happen for an argument like
         -nx, in which the -n is parsed as a single option, and we
         -nx, in which the -n is parsed as a single option, and we
         loop around to pick up the -x.  */
         loop around to pick up the -x.  */
      if (optind != last_optind)
      if (optind != last_optind)
        if (ldemul_parse_args (argc, argv))
        if (ldemul_parse_args (argc, argv))
          continue;
          continue;
 
 
      /* getopt_long_only is like getopt_long, but '-' as well as '--'
      /* getopt_long_only is like getopt_long, but '-' as well as '--'
         can indicate a long option.  */
         can indicate a long option.  */
      opterr = 0;
      opterr = 0;
      last_optind = optind;
      last_optind = optind;
      optc = getopt_long_only (argc, argv, shortopts, longopts, &longind);
      optc = getopt_long_only (argc, argv, shortopts, longopts, &longind);
      if (optc == '?')
      if (optc == '?')
        {
        {
          optind = last_optind;
          optind = last_optind;
          optc = getopt_long (argc, argv, "-", really_longopts, &longind);
          optc = getopt_long (argc, argv, "-", really_longopts, &longind);
        }
        }
 
 
      if (ldemul_handle_option (optc))
      if (ldemul_handle_option (optc))
        continue;
        continue;
 
 
      if (optc == -1)
      if (optc == -1)
        break;
        break;
 
 
      switch (optc)
      switch (optc)
        {
        {
        case '?':
        case '?':
          einfo (_("%P: unrecognized option '%s'\n"), argv[last_optind]);
          einfo (_("%P: unrecognized option '%s'\n"), argv[last_optind]);
          /* Fall through.  */
          /* Fall through.  */
 
 
        default:
        default:
          einfo (_("%P%F: use the --help option for usage information\n"));
          einfo (_("%P%F: use the --help option for usage information\n"));
 
 
        case 1:                 /* File name.  */
        case 1:                 /* File name.  */
          lang_add_input_file (optarg, lang_input_file_is_file_enum, NULL);
          lang_add_input_file (optarg, lang_input_file_is_file_enum, NULL);
          break;
          break;
 
 
        case OPTION_IGNORE:
        case OPTION_IGNORE:
          break;
          break;
        case 'a':
        case 'a':
          /* For HP/UX compatibility.  Actually -a shared should mean
          /* For HP/UX compatibility.  Actually -a shared should mean
             ``use only shared libraries'' but, then, we don't
             ``use only shared libraries'' but, then, we don't
             currently support shared libraries on HP/UX anyhow.  */
             currently support shared libraries on HP/UX anyhow.  */
          if (strcmp (optarg, "archive") == 0)
          if (strcmp (optarg, "archive") == 0)
            config.dynamic_link = FALSE;
            config.dynamic_link = FALSE;
          else if (strcmp (optarg, "shared") == 0
          else if (strcmp (optarg, "shared") == 0
                   || strcmp (optarg, "default") == 0)
                   || strcmp (optarg, "default") == 0)
            config.dynamic_link = TRUE;
            config.dynamic_link = TRUE;
          else
          else
            einfo (_("%P%F: unrecognized -a option `%s'\n"), optarg);
            einfo (_("%P%F: unrecognized -a option `%s'\n"), optarg);
          break;
          break;
        case OPTION_ASSERT:
        case OPTION_ASSERT:
          /* FIXME: We just ignore these, but we should handle them.  */
          /* FIXME: We just ignore these, but we should handle them.  */
          if (strcmp (optarg, "definitions") == 0)
          if (strcmp (optarg, "definitions") == 0)
            ;
            ;
          else if (strcmp (optarg, "nodefinitions") == 0)
          else if (strcmp (optarg, "nodefinitions") == 0)
            ;
            ;
          else if (strcmp (optarg, "nosymbolic") == 0)
          else if (strcmp (optarg, "nosymbolic") == 0)
            ;
            ;
          else if (strcmp (optarg, "pure-text") == 0)
          else if (strcmp (optarg, "pure-text") == 0)
            ;
            ;
          else
          else
            einfo (_("%P%F: unrecognized -assert option `%s'\n"), optarg);
            einfo (_("%P%F: unrecognized -assert option `%s'\n"), optarg);
          break;
          break;
        case 'A':
        case 'A':
          ldfile_add_arch (optarg);
          ldfile_add_arch (optarg);
          break;
          break;
        case 'b':
        case 'b':
          lang_add_target (optarg);
          lang_add_target (optarg);
          break;
          break;
        case 'c':
        case 'c':
          ldfile_open_command_file (optarg);
          ldfile_open_command_file (optarg);
          parser_input = input_mri_script;
          parser_input = input_mri_script;
          yyparse ();
          yyparse ();
          break;
          break;
        case OPTION_CALL_SHARED:
        case OPTION_CALL_SHARED:
          config.dynamic_link = TRUE;
          config.dynamic_link = TRUE;
          break;
          break;
        case OPTION_NON_SHARED:
        case OPTION_NON_SHARED:
          config.dynamic_link = FALSE;
          config.dynamic_link = FALSE;
          break;
          break;
        case OPTION_CREF:
        case OPTION_CREF:
          command_line.cref = TRUE;
          command_line.cref = TRUE;
          link_info.notice_all = TRUE;
          link_info.notice_all = TRUE;
          break;
          break;
        case 'd':
        case 'd':
          command_line.force_common_definition = TRUE;
          command_line.force_common_definition = TRUE;
          break;
          break;
        case OPTION_DEFSYM:
        case OPTION_DEFSYM:
          lex_string = optarg;
          lex_string = optarg;
          lex_redirect (optarg);
          lex_redirect (optarg);
          parser_input = input_defsym;
          parser_input = input_defsym;
          parsing_defsym = 1;
          parsing_defsym = 1;
          yyparse ();
          yyparse ();
          parsing_defsym = 0;
          parsing_defsym = 0;
          lex_string = NULL;
          lex_string = NULL;
          break;
          break;
        case OPTION_DEMANGLE:
        case OPTION_DEMANGLE:
          demangling = TRUE;
          demangling = TRUE;
          if (optarg != NULL)
          if (optarg != NULL)
            {
            {
              enum demangling_styles style;
              enum demangling_styles style;
 
 
              style = cplus_demangle_name_to_style (optarg);
              style = cplus_demangle_name_to_style (optarg);
              if (style == unknown_demangling)
              if (style == unknown_demangling)
                einfo (_("%F%P: unknown demangling style `%s'"),
                einfo (_("%F%P: unknown demangling style `%s'"),
                       optarg);
                       optarg);
 
 
              cplus_demangle_set_style (style);
              cplus_demangle_set_style (style);
            }
            }
          break;
          break;
        case 'I':               /* Used on Solaris.  */
        case 'I':               /* Used on Solaris.  */
        case OPTION_DYNAMIC_LINKER:
        case OPTION_DYNAMIC_LINKER:
          command_line.interpreter = optarg;
          command_line.interpreter = optarg;
          break;
          break;
        case OPTION_SYSROOT:
        case OPTION_SYSROOT:
          /* Already handled in ldmain.c.  */
          /* Already handled in ldmain.c.  */
          break;
          break;
        case OPTION_EB:
        case OPTION_EB:
          command_line.endian = ENDIAN_BIG;
          command_line.endian = ENDIAN_BIG;
          break;
          break;
        case OPTION_EL:
        case OPTION_EL:
          command_line.endian = ENDIAN_LITTLE;
          command_line.endian = ENDIAN_LITTLE;
          break;
          break;
        case OPTION_EMBEDDED_RELOCS:
        case OPTION_EMBEDDED_RELOCS:
          command_line.embedded_relocs = TRUE;
          command_line.embedded_relocs = TRUE;
          break;
          break;
        case OPTION_EXPORT_DYNAMIC:
        case OPTION_EXPORT_DYNAMIC:
        case 'E': /* HP/UX compatibility.  */
        case 'E': /* HP/UX compatibility.  */
          link_info.export_dynamic = TRUE;
          link_info.export_dynamic = TRUE;
          break;
          break;
        case OPTION_NO_EXPORT_DYNAMIC:
        case OPTION_NO_EXPORT_DYNAMIC:
          link_info.export_dynamic = FALSE;
          link_info.export_dynamic = FALSE;
          break;
          break;
        case 'e':
        case 'e':
          lang_add_entry (optarg, TRUE);
          lang_add_entry (optarg, TRUE);
          break;
          break;
        case 'f':
        case 'f':
          if (command_line.auxiliary_filters == NULL)
          if (command_line.auxiliary_filters == NULL)
            {
            {
              command_line.auxiliary_filters = (char **)
              command_line.auxiliary_filters = (char **)
                  xmalloc (2 * sizeof (char *));
                  xmalloc (2 * sizeof (char *));
              command_line.auxiliary_filters[0] = optarg;
              command_line.auxiliary_filters[0] = optarg;
              command_line.auxiliary_filters[1] = NULL;
              command_line.auxiliary_filters[1] = NULL;
            }
            }
          else
          else
            {
            {
              int c;
              int c;
              char **p;
              char **p;
 
 
              c = 0;
              c = 0;
              for (p = command_line.auxiliary_filters; *p != NULL; p++)
              for (p = command_line.auxiliary_filters; *p != NULL; p++)
                ++c;
                ++c;
              command_line.auxiliary_filters = (char **)
              command_line.auxiliary_filters = (char **)
                  xrealloc (command_line.auxiliary_filters,
                  xrealloc (command_line.auxiliary_filters,
                            (c + 2) * sizeof (char *));
                            (c + 2) * sizeof (char *));
              command_line.auxiliary_filters[c] = optarg;
              command_line.auxiliary_filters[c] = optarg;
              command_line.auxiliary_filters[c + 1] = NULL;
              command_line.auxiliary_filters[c + 1] = NULL;
            }
            }
          break;
          break;
        case 'F':
        case 'F':
          command_line.filter_shlib = optarg;
          command_line.filter_shlib = optarg;
          break;
          break;
        case OPTION_FORCE_EXE_SUFFIX:
        case OPTION_FORCE_EXE_SUFFIX:
          command_line.force_exe_suffix = TRUE;
          command_line.force_exe_suffix = TRUE;
          break;
          break;
        case 'G':
        case 'G':
          {
          {
            char *end;
            char *end;
            g_switch_value = strtoul (optarg, &end, 0);
            g_switch_value = strtoul (optarg, &end, 0);
            if (*end)
            if (*end)
              einfo (_("%P%F: invalid number `%s'\n"), optarg);
              einfo (_("%P%F: invalid number `%s'\n"), optarg);
          }
          }
          break;
          break;
        case 'g':
        case 'g':
          /* Ignore.  */
          /* Ignore.  */
          break;
          break;
        case OPTION_GC_SECTIONS:
        case OPTION_GC_SECTIONS:
          link_info.gc_sections = TRUE;
          link_info.gc_sections = TRUE;
          break;
          break;
        case OPTION_PRINT_GC_SECTIONS:
        case OPTION_PRINT_GC_SECTIONS:
          link_info.print_gc_sections = TRUE;
          link_info.print_gc_sections = TRUE;
          break;
          break;
        case OPTION_HELP:
        case OPTION_HELP:
          help ();
          help ();
          xexit (0);
          xexit (0);
          break;
          break;
        case 'L':
        case 'L':
          ldfile_add_library_path (optarg, TRUE);
          ldfile_add_library_path (optarg, TRUE);
          break;
          break;
        case 'l':
        case 'l':
          lang_add_input_file (optarg, lang_input_file_is_l_enum, NULL);
          lang_add_input_file (optarg, lang_input_file_is_l_enum, NULL);
          break;
          break;
        case 'M':
        case 'M':
          config.map_filename = "-";
          config.map_filename = "-";
          break;
          break;
        case 'm':
        case 'm':
          /* Ignore.  Was handled in a pre-parse.   */
          /* Ignore.  Was handled in a pre-parse.   */
          break;
          break;
        case OPTION_MAP:
        case OPTION_MAP:
          config.map_filename = optarg;
          config.map_filename = optarg;
          break;
          break;
        case 'N':
        case 'N':
          config.text_read_only = FALSE;
          config.text_read_only = FALSE;
          config.magic_demand_paged = FALSE;
          config.magic_demand_paged = FALSE;
          config.dynamic_link = FALSE;
          config.dynamic_link = FALSE;
          break;
          break;
        case OPTION_NO_OMAGIC:
        case OPTION_NO_OMAGIC:
          config.text_read_only = TRUE;
          config.text_read_only = TRUE;
          config.magic_demand_paged = TRUE;
          config.magic_demand_paged = TRUE;
          /* NB/ Does not set dynamic_link to TRUE.
          /* NB/ Does not set dynamic_link to TRUE.
             Use --call-shared or -Bdynamic for this.  */
             Use --call-shared or -Bdynamic for this.  */
          break;
          break;
        case 'n':
        case 'n':
          config.magic_demand_paged = FALSE;
          config.magic_demand_paged = FALSE;
          config.dynamic_link = FALSE;
          config.dynamic_link = FALSE;
          break;
          break;
        case OPTION_NO_DEFINE_COMMON:
        case OPTION_NO_DEFINE_COMMON:
          command_line.inhibit_common_definition = TRUE;
          command_line.inhibit_common_definition = TRUE;
          break;
          break;
        case OPTION_NO_DEMANGLE:
        case OPTION_NO_DEMANGLE:
          demangling = FALSE;
          demangling = FALSE;
          break;
          break;
        case OPTION_NO_GC_SECTIONS:
        case OPTION_NO_GC_SECTIONS:
          link_info.gc_sections = FALSE;
          link_info.gc_sections = FALSE;
          break;
          break;
        case OPTION_NO_PRINT_GC_SECTIONS:
        case OPTION_NO_PRINT_GC_SECTIONS:
          link_info.print_gc_sections = FALSE;
          link_info.print_gc_sections = FALSE;
          break;
          break;
        case OPTION_NO_KEEP_MEMORY:
        case OPTION_NO_KEEP_MEMORY:
          link_info.keep_memory = FALSE;
          link_info.keep_memory = FALSE;
          break;
          break;
        case OPTION_NO_UNDEFINED:
        case OPTION_NO_UNDEFINED:
          link_info.unresolved_syms_in_objects
          link_info.unresolved_syms_in_objects
            = how_to_report_unresolved_symbols;
            = how_to_report_unresolved_symbols;
          break;
          break;
        case OPTION_ALLOW_SHLIB_UNDEFINED:
        case OPTION_ALLOW_SHLIB_UNDEFINED:
          link_info.unresolved_syms_in_shared_libs = RM_IGNORE;
          link_info.unresolved_syms_in_shared_libs = RM_IGNORE;
          break;
          break;
        case OPTION_NO_ALLOW_SHLIB_UNDEFINED:
        case OPTION_NO_ALLOW_SHLIB_UNDEFINED:
          link_info.unresolved_syms_in_shared_libs
          link_info.unresolved_syms_in_shared_libs
            = how_to_report_unresolved_symbols;
            = how_to_report_unresolved_symbols;
          break;
          break;
        case OPTION_UNRESOLVED_SYMBOLS:
        case OPTION_UNRESOLVED_SYMBOLS:
          if (strcmp (optarg, "ignore-all") == 0)
          if (strcmp (optarg, "ignore-all") == 0)
            {
            {
              link_info.unresolved_syms_in_objects = RM_IGNORE;
              link_info.unresolved_syms_in_objects = RM_IGNORE;
              link_info.unresolved_syms_in_shared_libs = RM_IGNORE;
              link_info.unresolved_syms_in_shared_libs = RM_IGNORE;
            }
            }
          else if (strcmp (optarg, "report-all") == 0)
          else if (strcmp (optarg, "report-all") == 0)
            {
            {
              link_info.unresolved_syms_in_objects
              link_info.unresolved_syms_in_objects
                = how_to_report_unresolved_symbols;
                = how_to_report_unresolved_symbols;
              link_info.unresolved_syms_in_shared_libs
              link_info.unresolved_syms_in_shared_libs
                = how_to_report_unresolved_symbols;
                = how_to_report_unresolved_symbols;
            }
            }
          else if (strcmp (optarg, "ignore-in-object-files") == 0)
          else if (strcmp (optarg, "ignore-in-object-files") == 0)
            {
            {
              link_info.unresolved_syms_in_objects = RM_IGNORE;
              link_info.unresolved_syms_in_objects = RM_IGNORE;
              link_info.unresolved_syms_in_shared_libs
              link_info.unresolved_syms_in_shared_libs
                = how_to_report_unresolved_symbols;
                = how_to_report_unresolved_symbols;
            }
            }
          else if (strcmp (optarg, "ignore-in-shared-libs") == 0)
          else if (strcmp (optarg, "ignore-in-shared-libs") == 0)
            {
            {
              link_info.unresolved_syms_in_objects
              link_info.unresolved_syms_in_objects
                = how_to_report_unresolved_symbols;
                = how_to_report_unresolved_symbols;
              link_info.unresolved_syms_in_shared_libs = RM_IGNORE;
              link_info.unresolved_syms_in_shared_libs = RM_IGNORE;
            }
            }
          else
          else
            einfo (_("%P%F: bad --unresolved-symbols option: %s\n"), optarg);
            einfo (_("%P%F: bad --unresolved-symbols option: %s\n"), optarg);
          break;
          break;
        case OPTION_WARN_UNRESOLVED_SYMBOLS:
        case OPTION_WARN_UNRESOLVED_SYMBOLS:
          how_to_report_unresolved_symbols = RM_GENERATE_WARNING;
          how_to_report_unresolved_symbols = RM_GENERATE_WARNING;
          if (link_info.unresolved_syms_in_objects == RM_GENERATE_ERROR)
          if (link_info.unresolved_syms_in_objects == RM_GENERATE_ERROR)
            link_info.unresolved_syms_in_objects = RM_GENERATE_WARNING;
            link_info.unresolved_syms_in_objects = RM_GENERATE_WARNING;
          if (link_info.unresolved_syms_in_shared_libs == RM_GENERATE_ERROR)
          if (link_info.unresolved_syms_in_shared_libs == RM_GENERATE_ERROR)
            link_info.unresolved_syms_in_shared_libs = RM_GENERATE_WARNING;
            link_info.unresolved_syms_in_shared_libs = RM_GENERATE_WARNING;
          break;
          break;
 
 
        case OPTION_ERROR_UNRESOLVED_SYMBOLS:
        case OPTION_ERROR_UNRESOLVED_SYMBOLS:
          how_to_report_unresolved_symbols = RM_GENERATE_ERROR;
          how_to_report_unresolved_symbols = RM_GENERATE_ERROR;
          if (link_info.unresolved_syms_in_objects == RM_GENERATE_WARNING)
          if (link_info.unresolved_syms_in_objects == RM_GENERATE_WARNING)
            link_info.unresolved_syms_in_objects = RM_GENERATE_ERROR;
            link_info.unresolved_syms_in_objects = RM_GENERATE_ERROR;
          if (link_info.unresolved_syms_in_shared_libs == RM_GENERATE_WARNING)
          if (link_info.unresolved_syms_in_shared_libs == RM_GENERATE_WARNING)
            link_info.unresolved_syms_in_shared_libs = RM_GENERATE_ERROR;
            link_info.unresolved_syms_in_shared_libs = RM_GENERATE_ERROR;
          break;
          break;
        case OPTION_ALLOW_MULTIPLE_DEFINITION:
        case OPTION_ALLOW_MULTIPLE_DEFINITION:
          link_info.allow_multiple_definition = TRUE;
          link_info.allow_multiple_definition = TRUE;
          break;
          break;
        case OPTION_NO_UNDEFINED_VERSION:
        case OPTION_NO_UNDEFINED_VERSION:
          link_info.allow_undefined_version = FALSE;
          link_info.allow_undefined_version = FALSE;
          break;
          break;
        case OPTION_DEFAULT_SYMVER:
        case OPTION_DEFAULT_SYMVER:
          link_info.create_default_symver = TRUE;
          link_info.create_default_symver = TRUE;
          break;
          break;
        case OPTION_DEFAULT_IMPORTED_SYMVER:
        case OPTION_DEFAULT_IMPORTED_SYMVER:
          link_info.default_imported_symver = TRUE;
          link_info.default_imported_symver = TRUE;
          break;
          break;
        case OPTION_NO_WARN_MISMATCH:
        case OPTION_NO_WARN_MISMATCH:
          command_line.warn_mismatch = FALSE;
          command_line.warn_mismatch = FALSE;
          break;
          break;
        case OPTION_NO_WARN_SEARCH_MISMATCH:
        case OPTION_NO_WARN_SEARCH_MISMATCH:
          command_line.warn_search_mismatch = FALSE;
          command_line.warn_search_mismatch = FALSE;
          break;
          break;
        case OPTION_NOINHIBIT_EXEC:
        case OPTION_NOINHIBIT_EXEC:
          force_make_executable = TRUE;
          force_make_executable = TRUE;
          break;
          break;
        case OPTION_NOSTDLIB:
        case OPTION_NOSTDLIB:
          config.only_cmd_line_lib_dirs = TRUE;
          config.only_cmd_line_lib_dirs = TRUE;
          break;
          break;
        case OPTION_NO_WHOLE_ARCHIVE:
        case OPTION_NO_WHOLE_ARCHIVE:
          whole_archive = FALSE;
          whole_archive = FALSE;
          break;
          break;
        case 'O':
        case 'O':
          /* FIXME "-O<non-digits> <value>" used to set the address of
          /* FIXME "-O<non-digits> <value>" used to set the address of
             section <non-digits>.  Was this for compatibility with
             section <non-digits>.  Was this for compatibility with
             something, or can we create a new option to do that
             something, or can we create a new option to do that
             (with a syntax similar to -defsym)?
             (with a syntax similar to -defsym)?
             getopt can't handle two args to an option without kludges.  */
             getopt can't handle two args to an option without kludges.  */
 
 
          /* Enable optimizations of output files.  */
          /* Enable optimizations of output files.  */
          link_info.optimize = strtoul (optarg, NULL, 0) ? TRUE : FALSE;
          link_info.optimize = strtoul (optarg, NULL, 0) ? TRUE : FALSE;
          break;
          break;
        case 'o':
        case 'o':
          lang_add_output (optarg, 0);
          lang_add_output (optarg, 0);
          break;
          break;
        case OPTION_OFORMAT:
        case OPTION_OFORMAT:
          lang_add_output_format (optarg, NULL, NULL, 0);
          lang_add_output_format (optarg, NULL, NULL, 0);
          break;
          break;
        case 'q':
        case 'q':
          link_info.emitrelocations = TRUE;
          link_info.emitrelocations = TRUE;
          break;
          break;
        case 'i':
        case 'i':
        case 'r':
        case 'r':
          if (optind == last_optind)
          if (optind == last_optind)
            /* This can happen if the user put "-rpath,a" on the command
            /* This can happen if the user put "-rpath,a" on the command
               line.  (Or something similar.  The comma is important).
               line.  (Or something similar.  The comma is important).
               Getopt becomes confused and thinks that this is a -r option
               Getopt becomes confused and thinks that this is a -r option
               but it cannot parse the text after the -r so it refuses to
               but it cannot parse the text after the -r so it refuses to
               increment the optind counter.  Detect this case and issue
               increment the optind counter.  Detect this case and issue
               an error message here.  We cannot just make this a warning,
               an error message here.  We cannot just make this a warning,
               increment optind, and continue because getopt is too confused
               increment optind, and continue because getopt is too confused
               and will seg-fault the next time around.  */
               and will seg-fault the next time around.  */
            einfo(_("%P%F: bad -rpath option\n"));
            einfo(_("%P%F: bad -rpath option\n"));
 
 
          link_info.relocatable = TRUE;
          link_info.relocatable = TRUE;
          config.build_constructors = FALSE;
          config.build_constructors = FALSE;
          config.magic_demand_paged = FALSE;
          config.magic_demand_paged = FALSE;
          config.text_read_only = FALSE;
          config.text_read_only = FALSE;
          config.dynamic_link = FALSE;
          config.dynamic_link = FALSE;
          break;
          break;
        case 'R':
        case 'R':
          /* The GNU linker traditionally uses -R to mean to include
          /* The GNU linker traditionally uses -R to mean to include
             only the symbols from a file.  The Solaris linker uses -R
             only the symbols from a file.  The Solaris linker uses -R
             to set the path used by the runtime linker to find
             to set the path used by the runtime linker to find
             libraries.  This is the GNU linker -rpath argument.  We
             libraries.  This is the GNU linker -rpath argument.  We
             try to support both simultaneously by checking the file
             try to support both simultaneously by checking the file
             named.  If it is a directory, rather than a regular file,
             named.  If it is a directory, rather than a regular file,
             we assume -rpath was meant.  */
             we assume -rpath was meant.  */
          {
          {
            struct stat s;
            struct stat s;
 
 
            if (stat (optarg, &s) >= 0
            if (stat (optarg, &s) >= 0
                && ! S_ISDIR (s.st_mode))
                && ! S_ISDIR (s.st_mode))
              {
              {
                lang_add_input_file (optarg,
                lang_add_input_file (optarg,
                                     lang_input_file_is_symbols_only_enum,
                                     lang_input_file_is_symbols_only_enum,
                                     NULL);
                                     NULL);
                break;
                break;
              }
              }
          }
          }
          /* Fall through.  */
          /* Fall through.  */
        case OPTION_RPATH:
        case OPTION_RPATH:
          if (command_line.rpath == NULL)
          if (command_line.rpath == NULL)
            command_line.rpath = xstrdup (optarg);
            command_line.rpath = xstrdup (optarg);
          else
          else
            {
            {
              size_t rpath_len = strlen (command_line.rpath);
              size_t rpath_len = strlen (command_line.rpath);
              size_t optarg_len = strlen (optarg);
              size_t optarg_len = strlen (optarg);
              char *buf;
              char *buf;
              char *cp = command_line.rpath;
              char *cp = command_line.rpath;
 
 
              /* First see whether OPTARG is already in the path.  */
              /* First see whether OPTARG is already in the path.  */
              do
              do
                {
                {
                  if (strncmp (optarg, cp, optarg_len) == 0
                  if (strncmp (optarg, cp, optarg_len) == 0
                      && (cp[optarg_len] == 0
                      && (cp[optarg_len] == 0
                          || cp[optarg_len] == config.rpath_separator))
                          || cp[optarg_len] == config.rpath_separator))
                    /* We found it.  */
                    /* We found it.  */
                    break;
                    break;
 
 
                  /* Not yet found.  */
                  /* Not yet found.  */
                  cp = strchr (cp, config.rpath_separator);
                  cp = strchr (cp, config.rpath_separator);
                  if (cp != NULL)
                  if (cp != NULL)
                    ++cp;
                    ++cp;
                }
                }
              while (cp != NULL);
              while (cp != NULL);
 
 
              if (cp == NULL)
              if (cp == NULL)
                {
                {
                  buf = (char *) xmalloc (rpath_len + optarg_len + 2);
                  buf = (char *) xmalloc (rpath_len + optarg_len + 2);
                  sprintf (buf, "%s%c%s", command_line.rpath,
                  sprintf (buf, "%s%c%s", command_line.rpath,
                           config.rpath_separator, optarg);
                           config.rpath_separator, optarg);
                  free (command_line.rpath);
                  free (command_line.rpath);
                  command_line.rpath = buf;
                  command_line.rpath = buf;
                }
                }
            }
            }
          break;
          break;
        case OPTION_RPATH_LINK:
        case OPTION_RPATH_LINK:
          if (command_line.rpath_link == NULL)
          if (command_line.rpath_link == NULL)
            command_line.rpath_link = xstrdup (optarg);
            command_line.rpath_link = xstrdup (optarg);
          else
          else
            {
            {
              char *buf;
              char *buf;
 
 
              buf = (char *) xmalloc (strlen (command_line.rpath_link)
              buf = (char *) xmalloc (strlen (command_line.rpath_link)
                                      + strlen (optarg)
                                      + strlen (optarg)
                                      + 2);
                                      + 2);
              sprintf (buf, "%s%c%s", command_line.rpath_link,
              sprintf (buf, "%s%c%s", command_line.rpath_link,
                       config.rpath_separator, optarg);
                       config.rpath_separator, optarg);
              free (command_line.rpath_link);
              free (command_line.rpath_link);
              command_line.rpath_link = buf;
              command_line.rpath_link = buf;
            }
            }
          break;
          break;
        case OPTION_RELAX:
        case OPTION_RELAX:
          command_line.relax = TRUE;
          command_line.relax = TRUE;
          break;
          break;
        case OPTION_RETAIN_SYMBOLS_FILE:
        case OPTION_RETAIN_SYMBOLS_FILE:
          add_keepsyms_file (optarg);
          add_keepsyms_file (optarg);
          break;
          break;
        case 'S':
        case 'S':
          link_info.strip = strip_debugger;
          link_info.strip = strip_debugger;
          break;
          break;
        case 's':
        case 's':
          link_info.strip = strip_all;
          link_info.strip = strip_all;
          break;
          break;
        case OPTION_STRIP_DISCARDED:
        case OPTION_STRIP_DISCARDED:
          link_info.strip_discarded = TRUE;
          link_info.strip_discarded = TRUE;
          break;
          break;
        case OPTION_NO_STRIP_DISCARDED:
        case OPTION_NO_STRIP_DISCARDED:
          link_info.strip_discarded = FALSE;
          link_info.strip_discarded = FALSE;
          break;
          break;
        case OPTION_SHARED:
        case OPTION_SHARED:
          if (config.has_shared)
          if (config.has_shared)
            {
            {
              link_info.shared = TRUE;
              link_info.shared = TRUE;
              /* When creating a shared library, the default
              /* When creating a shared library, the default
                 behaviour is to ignore any unresolved references.  */
                 behaviour is to ignore any unresolved references.  */
              if (link_info.unresolved_syms_in_objects == RM_NOT_YET_SET)
              if (link_info.unresolved_syms_in_objects == RM_NOT_YET_SET)
                link_info.unresolved_syms_in_objects = RM_IGNORE;
                link_info.unresolved_syms_in_objects = RM_IGNORE;
              if (link_info.unresolved_syms_in_shared_libs == RM_NOT_YET_SET)
              if (link_info.unresolved_syms_in_shared_libs == RM_NOT_YET_SET)
                link_info.unresolved_syms_in_shared_libs = RM_IGNORE;
                link_info.unresolved_syms_in_shared_libs = RM_IGNORE;
            }
            }
          else
          else
            einfo (_("%P%F: -shared not supported\n"));
            einfo (_("%P%F: -shared not supported\n"));
          break;
          break;
        case OPTION_PIE:
        case OPTION_PIE:
          if (config.has_shared)
          if (config.has_shared)
            {
            {
              link_info.shared = TRUE;
              link_info.shared = TRUE;
              link_info.pie = TRUE;
              link_info.pie = TRUE;
            }
            }
          else
          else
            einfo (_("%P%F: -pie not supported\n"));
            einfo (_("%P%F: -pie not supported\n"));
          break;
          break;
        case 'h':               /* Used on Solaris.  */
        case 'h':               /* Used on Solaris.  */
        case OPTION_SONAME:
        case OPTION_SONAME:
          command_line.soname = optarg;
          command_line.soname = optarg;
          break;
          break;
        case OPTION_SORT_COMMON:
        case OPTION_SORT_COMMON:
          if (optarg == NULL
          if (optarg == NULL
              || strcmp (optarg, N_("descending")) == 0)
              || strcmp (optarg, N_("descending")) == 0)
            config.sort_common = sort_descending;
            config.sort_common = sort_descending;
          else if (strcmp (optarg, N_("ascending")) == 0)
          else if (strcmp (optarg, N_("ascending")) == 0)
            config.sort_common = sort_ascending;
            config.sort_common = sort_ascending;
          else
          else
            einfo (_("%P%F: invalid common section sorting option: %s\n"),
            einfo (_("%P%F: invalid common section sorting option: %s\n"),
                   optarg);
                   optarg);
          break;
          break;
        case OPTION_SORT_SECTION:
        case OPTION_SORT_SECTION:
          if (strcmp (optarg, N_("name")) == 0)
          if (strcmp (optarg, N_("name")) == 0)
            sort_section = by_name;
            sort_section = by_name;
          else if (strcmp (optarg, N_("alignment")) == 0)
          else if (strcmp (optarg, N_("alignment")) == 0)
            sort_section = by_alignment;
            sort_section = by_alignment;
          else
          else
            einfo (_("%P%F: invalid section sorting option: %s\n"),
            einfo (_("%P%F: invalid section sorting option: %s\n"),
                   optarg);
                   optarg);
          break;
          break;
        case OPTION_STATS:
        case OPTION_STATS:
          config.stats = TRUE;
          config.stats = TRUE;
          break;
          break;
        case OPTION_SYMBOLIC:
        case OPTION_SYMBOLIC:
          command_line.symbolic = symbolic;
          command_line.symbolic = symbolic;
          break;
          break;
        case OPTION_SYMBOLIC_FUNCTIONS:
        case OPTION_SYMBOLIC_FUNCTIONS:
          command_line.symbolic = symbolic_functions;
          command_line.symbolic = symbolic_functions;
          break;
          break;
        case 't':
        case 't':
          trace_files = TRUE;
          trace_files = TRUE;
          break;
          break;
        case 'T':
        case 'T':
          previous_script_handle = saved_script_handle;
          previous_script_handle = saved_script_handle;
          ldfile_open_command_file (optarg);
          ldfile_open_command_file (optarg);
          parser_input = input_script;
          parser_input = input_script;
          yyparse ();
          yyparse ();
          previous_script_handle = NULL;
          previous_script_handle = NULL;
          break;
          break;
        case OPTION_DEFAULT_SCRIPT:
        case OPTION_DEFAULT_SCRIPT:
          command_line.default_script = optarg;
          command_line.default_script = optarg;
          break;
          break;
        case OPTION_SECTION_START:
        case OPTION_SECTION_START:
          {
          {
            char *optarg2;
            char *optarg2;
            char *sec_name;
            char *sec_name;
            int len;
            int len;
 
 
            /* Check for <something>=<somthing>...  */
            /* Check for <something>=<somthing>...  */
            optarg2 = strchr (optarg, '=');
            optarg2 = strchr (optarg, '=');
            if (optarg2 == NULL)
            if (optarg2 == NULL)
              einfo (_("%P%F: invalid argument to option"
              einfo (_("%P%F: invalid argument to option"
                       " \"--section-start\"\n"));
                       " \"--section-start\"\n"));
 
 
            optarg2++;
            optarg2++;
 
 
            /* So far so good.  Are all the args present?  */
            /* So far so good.  Are all the args present?  */
            if ((*optarg == '\0') || (*optarg2 == '\0'))
            if ((*optarg == '\0') || (*optarg2 == '\0'))
              einfo (_("%P%F: missing argument(s) to option"
              einfo (_("%P%F: missing argument(s) to option"
                       " \"--section-start\"\n"));
                       " \"--section-start\"\n"));
 
 
            /* We must copy the section name as set_section_start
            /* We must copy the section name as set_section_start
               doesn't do it for us.  */
               doesn't do it for us.  */
            len = optarg2 - optarg;
            len = optarg2 - optarg;
            sec_name = (char *) xmalloc (len);
            sec_name = (char *) xmalloc (len);
            memcpy (sec_name, optarg, len - 1);
            memcpy (sec_name, optarg, len - 1);
            sec_name[len - 1] = 0;
            sec_name[len - 1] = 0;
 
 
            /* Then set it...  */
            /* Then set it...  */
            set_section_start (sec_name, optarg2);
            set_section_start (sec_name, optarg2);
          }
          }
          break;
          break;
        case OPTION_TARGET_HELP:
        case OPTION_TARGET_HELP:
          /* Mention any target specific options.  */
          /* Mention any target specific options.  */
          ldemul_list_emulation_options (stdout);
          ldemul_list_emulation_options (stdout);
          exit (0);
          exit (0);
        case OPTION_TBSS:
        case OPTION_TBSS:
          set_segment_start (".bss", optarg);
          set_segment_start (".bss", optarg);
          break;
          break;
        case OPTION_TDATA:
        case OPTION_TDATA:
          set_segment_start (".data", optarg);
          set_segment_start (".data", optarg);
          break;
          break;
        case OPTION_TTEXT:
        case OPTION_TTEXT:
          set_segment_start (".text", optarg);
          set_segment_start (".text", optarg);
          break;
          break;
        case OPTION_TTEXT_SEGMENT:
        case OPTION_TTEXT_SEGMENT:
          set_segment_start (".text-segment", optarg);
          set_segment_start (".text-segment", optarg);
          break;
          break;
        case OPTION_TRADITIONAL_FORMAT:
        case OPTION_TRADITIONAL_FORMAT:
          link_info.traditional_format = TRUE;
          link_info.traditional_format = TRUE;
          break;
          break;
        case OPTION_TASK_LINK:
        case OPTION_TASK_LINK:
          link_info.task_link = TRUE;
          link_info.task_link = TRUE;
          /* Fall through - do an implied -r option.  */
          /* Fall through - do an implied -r option.  */
        case OPTION_UR:
        case OPTION_UR:
          link_info.relocatable = TRUE;
          link_info.relocatable = TRUE;
          config.build_constructors = TRUE;
          config.build_constructors = TRUE;
          config.magic_demand_paged = FALSE;
          config.magic_demand_paged = FALSE;
          config.text_read_only = FALSE;
          config.text_read_only = FALSE;
          config.dynamic_link = FALSE;
          config.dynamic_link = FALSE;
          break;
          break;
        case 'u':
        case 'u':
          ldlang_add_undef (optarg);
          ldlang_add_undef (optarg);
          break;
          break;
        case OPTION_UNIQUE:
        case OPTION_UNIQUE:
          if (optarg != NULL)
          if (optarg != NULL)
            lang_add_unique (optarg);
            lang_add_unique (optarg);
          else
          else
            config.unique_orphan_sections = TRUE;
            config.unique_orphan_sections = TRUE;
          break;
          break;
        case OPTION_VERBOSE:
        case OPTION_VERBOSE:
          ldversion (1);
          ldversion (1);
          version_printed = TRUE;
          version_printed = TRUE;
          trace_file_tries = TRUE;
          trace_file_tries = TRUE;
          overflow_cutoff_limit = -2;
          overflow_cutoff_limit = -2;
          break;
          break;
        case 'v':
        case 'v':
          ldversion (0);
          ldversion (0);
          version_printed = TRUE;
          version_printed = TRUE;
          break;
          break;
        case 'V':
        case 'V':
          ldversion (1);
          ldversion (1);
          version_printed = TRUE;
          version_printed = TRUE;
          break;
          break;
        case OPTION_VERSION:
        case OPTION_VERSION:
          ldversion (2);
          ldversion (2);
          xexit (0);
          xexit (0);
          break;
          break;
        case OPTION_VERSION_SCRIPT:
        case OPTION_VERSION_SCRIPT:
          /* This option indicates a small script that only specifies
          /* This option indicates a small script that only specifies
             version information.  Read it, but don't assume that
             version information.  Read it, but don't assume that
             we've seen a linker script.  */
             we've seen a linker script.  */
          {
          {
            FILE *hold_script_handle;
            FILE *hold_script_handle;
 
 
            hold_script_handle = saved_script_handle;
            hold_script_handle = saved_script_handle;
            ldfile_open_command_file (optarg);
            ldfile_open_command_file (optarg);
            saved_script_handle = hold_script_handle;
            saved_script_handle = hold_script_handle;
            parser_input = input_version_script;
            parser_input = input_version_script;
            yyparse ();
            yyparse ();
          }
          }
          break;
          break;
        case OPTION_VERSION_EXPORTS_SECTION:
        case OPTION_VERSION_EXPORTS_SECTION:
          /* This option records a version symbol to be applied to the
          /* This option records a version symbol to be applied to the
             symbols listed for export to be found in the object files
             symbols listed for export to be found in the object files
             .exports sections.  */
             .exports sections.  */
          command_line.version_exports_section = optarg;
          command_line.version_exports_section = optarg;
          break;
          break;
        case OPTION_DYNAMIC_LIST_DATA:
        case OPTION_DYNAMIC_LIST_DATA:
          command_line.dynamic_list = dynamic_list_data;
          command_line.dynamic_list = dynamic_list_data;
          if (command_line.symbolic == symbolic)
          if (command_line.symbolic == symbolic)
            command_line.symbolic = symbolic_unset;
            command_line.symbolic = symbolic_unset;
          break;
          break;
        case OPTION_DYNAMIC_LIST_CPP_TYPEINFO:
        case OPTION_DYNAMIC_LIST_CPP_TYPEINFO:
          lang_append_dynamic_list_cpp_typeinfo ();
          lang_append_dynamic_list_cpp_typeinfo ();
          if (command_line.dynamic_list != dynamic_list_data)
          if (command_line.dynamic_list != dynamic_list_data)
            command_line.dynamic_list = dynamic_list;
            command_line.dynamic_list = dynamic_list;
          if (command_line.symbolic == symbolic)
          if (command_line.symbolic == symbolic)
            command_line.symbolic = symbolic_unset;
            command_line.symbolic = symbolic_unset;
          break;
          break;
        case OPTION_DYNAMIC_LIST_CPP_NEW:
        case OPTION_DYNAMIC_LIST_CPP_NEW:
          lang_append_dynamic_list_cpp_new ();
          lang_append_dynamic_list_cpp_new ();
          if (command_line.dynamic_list != dynamic_list_data)
          if (command_line.dynamic_list != dynamic_list_data)
            command_line.dynamic_list = dynamic_list;
            command_line.dynamic_list = dynamic_list;
          if (command_line.symbolic == symbolic)
          if (command_line.symbolic == symbolic)
            command_line.symbolic = symbolic_unset;
            command_line.symbolic = symbolic_unset;
          break;
          break;
        case OPTION_DYNAMIC_LIST:
        case OPTION_DYNAMIC_LIST:
          /* This option indicates a small script that only specifies
          /* This option indicates a small script that only specifies
             a dynamic list.  Read it, but don't assume that we've
             a dynamic list.  Read it, but don't assume that we've
             seen a linker script.  */
             seen a linker script.  */
          {
          {
            FILE *hold_script_handle;
            FILE *hold_script_handle;
 
 
            hold_script_handle = saved_script_handle;
            hold_script_handle = saved_script_handle;
            ldfile_open_command_file (optarg);
            ldfile_open_command_file (optarg);
            saved_script_handle = hold_script_handle;
            saved_script_handle = hold_script_handle;
            parser_input = input_dynamic_list;
            parser_input = input_dynamic_list;
            yyparse ();
            yyparse ();
          }
          }
          if (command_line.dynamic_list != dynamic_list_data)
          if (command_line.dynamic_list != dynamic_list_data)
            command_line.dynamic_list = dynamic_list;
            command_line.dynamic_list = dynamic_list;
          if (command_line.symbolic == symbolic)
          if (command_line.symbolic == symbolic)
            command_line.symbolic = symbolic_unset;
            command_line.symbolic = symbolic_unset;
          break;
          break;
        case OPTION_WARN_COMMON:
        case OPTION_WARN_COMMON:
          config.warn_common = TRUE;
          config.warn_common = TRUE;
          break;
          break;
        case OPTION_WARN_CONSTRUCTORS:
        case OPTION_WARN_CONSTRUCTORS:
          config.warn_constructors = TRUE;
          config.warn_constructors = TRUE;
          break;
          break;
        case OPTION_WARN_FATAL:
        case OPTION_WARN_FATAL:
          config.fatal_warnings = TRUE;
          config.fatal_warnings = TRUE;
          break;
          break;
        case OPTION_NO_WARN_FATAL:
        case OPTION_NO_WARN_FATAL:
          config.fatal_warnings = FALSE;
          config.fatal_warnings = FALSE;
          break;
          break;
        case OPTION_WARN_MULTIPLE_GP:
        case OPTION_WARN_MULTIPLE_GP:
          config.warn_multiple_gp = TRUE;
          config.warn_multiple_gp = TRUE;
          break;
          break;
        case OPTION_WARN_ONCE:
        case OPTION_WARN_ONCE:
          config.warn_once = TRUE;
          config.warn_once = TRUE;
          break;
          break;
        case OPTION_WARN_SECTION_ALIGN:
        case OPTION_WARN_SECTION_ALIGN:
          config.warn_section_align = TRUE;
          config.warn_section_align = TRUE;
          break;
          break;
        case OPTION_WARN_SHARED_TEXTREL:
        case OPTION_WARN_SHARED_TEXTREL:
          link_info.warn_shared_textrel = TRUE;
          link_info.warn_shared_textrel = TRUE;
          break;
          break;
        case OPTION_WARN_ALTERNATE_EM:
        case OPTION_WARN_ALTERNATE_EM:
          link_info.warn_alternate_em = TRUE;
          link_info.warn_alternate_em = TRUE;
          break;
          break;
        case OPTION_WHOLE_ARCHIVE:
        case OPTION_WHOLE_ARCHIVE:
          whole_archive = TRUE;
          whole_archive = TRUE;
          break;
          break;
        case OPTION_ADD_NEEDED:
        case OPTION_ADD_NEEDED:
          add_needed = TRUE;
          add_needed = TRUE;
          break;
          break;
        case OPTION_NO_ADD_NEEDED:
        case OPTION_NO_ADD_NEEDED:
          add_needed = FALSE;
          add_needed = FALSE;
          break;
          break;
        case OPTION_AS_NEEDED:
        case OPTION_AS_NEEDED:
          as_needed = TRUE;
          as_needed = TRUE;
          break;
          break;
        case OPTION_NO_AS_NEEDED:
        case OPTION_NO_AS_NEEDED:
          as_needed = FALSE;
          as_needed = FALSE;
          break;
          break;
        case OPTION_WRAP:
        case OPTION_WRAP:
          add_wrap (optarg);
          add_wrap (optarg);
          break;
          break;
        case OPTION_DISCARD_NONE:
        case OPTION_DISCARD_NONE:
          link_info.discard = discard_none;
          link_info.discard = discard_none;
          break;
          break;
        case 'X':
        case 'X':
          link_info.discard = discard_l;
          link_info.discard = discard_l;
          break;
          break;
        case 'x':
        case 'x':
          link_info.discard = discard_all;
          link_info.discard = discard_all;
          break;
          break;
        case 'Y':
        case 'Y':
          if (CONST_STRNEQ (optarg, "P,"))
          if (CONST_STRNEQ (optarg, "P,"))
            optarg += 2;
            optarg += 2;
          if (default_dirlist != NULL)
          if (default_dirlist != NULL)
            free (default_dirlist);
            free (default_dirlist);
          default_dirlist = xstrdup (optarg);
          default_dirlist = xstrdup (optarg);
          break;
          break;
        case 'y':
        case 'y':
          add_ysym (optarg);
          add_ysym (optarg);
          break;
          break;
        case OPTION_SPARE_DYNAMIC_TAGS:
        case OPTION_SPARE_DYNAMIC_TAGS:
          link_info.spare_dynamic_tags = strtoul (optarg, NULL, 0);
          link_info.spare_dynamic_tags = strtoul (optarg, NULL, 0);
          break;
          break;
        case OPTION_SPLIT_BY_RELOC:
        case OPTION_SPLIT_BY_RELOC:
          if (optarg != NULL)
          if (optarg != NULL)
            config.split_by_reloc = strtoul (optarg, NULL, 0);
            config.split_by_reloc = strtoul (optarg, NULL, 0);
          else
          else
            config.split_by_reloc = 32768;
            config.split_by_reloc = 32768;
          break;
          break;
        case OPTION_SPLIT_BY_FILE:
        case OPTION_SPLIT_BY_FILE:
          if (optarg != NULL)
          if (optarg != NULL)
            config.split_by_file = bfd_scan_vma (optarg, NULL, 0);
            config.split_by_file = bfd_scan_vma (optarg, NULL, 0);
          else
          else
            config.split_by_file = 1;
            config.split_by_file = 1;
          break;
          break;
        case OPTION_CHECK_SECTIONS:
        case OPTION_CHECK_SECTIONS:
          command_line.check_section_addresses = 1;
          command_line.check_section_addresses = 1;
          break;
          break;
        case OPTION_NO_CHECK_SECTIONS:
        case OPTION_NO_CHECK_SECTIONS:
          command_line.check_section_addresses = 0;
          command_line.check_section_addresses = 0;
          break;
          break;
        case OPTION_ACCEPT_UNKNOWN_INPUT_ARCH:
        case OPTION_ACCEPT_UNKNOWN_INPUT_ARCH:
          command_line.accept_unknown_input_arch = TRUE;
          command_line.accept_unknown_input_arch = TRUE;
          break;
          break;
        case OPTION_NO_ACCEPT_UNKNOWN_INPUT_ARCH:
        case OPTION_NO_ACCEPT_UNKNOWN_INPUT_ARCH:
          command_line.accept_unknown_input_arch = FALSE;
          command_line.accept_unknown_input_arch = FALSE;
          break;
          break;
        case '(':
        case '(':
          if (ingroup)
          if (ingroup)
            einfo (_("%P%F: may not nest groups (--help for usage)\n"));
            einfo (_("%P%F: may not nest groups (--help for usage)\n"));
 
 
          lang_enter_group ();
          lang_enter_group ();
          ingroup = 1;
          ingroup = 1;
          break;
          break;
        case ')':
        case ')':
          if (! ingroup)
          if (! ingroup)
            einfo (_("%P%F: group ended before it began (--help for usage)\n"));
            einfo (_("%P%F: group ended before it began (--help for usage)\n"));
 
 
          lang_leave_group ();
          lang_leave_group ();
          ingroup = 0;
          ingroup = 0;
          break;
          break;
 
 
        case OPTION_INIT:
        case OPTION_INIT:
          link_info.init_function = optarg;
          link_info.init_function = optarg;
          break;
          break;
 
 
        case OPTION_FINI:
        case OPTION_FINI:
          link_info.fini_function = optarg;
          link_info.fini_function = optarg;
          break;
          break;
 
 
        case OPTION_REDUCE_MEMORY_OVERHEADS:
        case OPTION_REDUCE_MEMORY_OVERHEADS:
          link_info.reduce_memory_overheads = TRUE;
          link_info.reduce_memory_overheads = TRUE;
          if (config.hash_table_size == 0)
          if (config.hash_table_size == 0)
            config.hash_table_size = 1021;
            config.hash_table_size = 1021;
          break;
          break;
 
 
        case OPTION_HASH_SIZE:
        case OPTION_HASH_SIZE:
          {
          {
            bfd_size_type new_size;
            bfd_size_type new_size;
 
 
            new_size = strtoul (optarg, NULL, 0);
            new_size = strtoul (optarg, NULL, 0);
            if (new_size)
            if (new_size)
              config.hash_table_size = new_size;
              config.hash_table_size = new_size;
            else
            else
              einfo (_("%P%X: --hash-size needs a numeric argument\n"));
              einfo (_("%P%X: --hash-size needs a numeric argument\n"));
          }
          }
          break;
          break;
        }
        }
    }
    }
 
 
  if (ingroup)
  if (ingroup)
    lang_leave_group ();
    lang_leave_group ();
 
 
  if (default_dirlist != NULL)
  if (default_dirlist != NULL)
    {
    {
      set_default_dirlist (default_dirlist);
      set_default_dirlist (default_dirlist);
      free (default_dirlist);
      free (default_dirlist);
    }
    }
 
 
  if (link_info.unresolved_syms_in_objects == RM_NOT_YET_SET)
  if (link_info.unresolved_syms_in_objects == RM_NOT_YET_SET)
    /* FIXME: Should we allow emulations a chance to set this ?  */
    /* FIXME: Should we allow emulations a chance to set this ?  */
    link_info.unresolved_syms_in_objects = how_to_report_unresolved_symbols;
    link_info.unresolved_syms_in_objects = how_to_report_unresolved_symbols;
 
 
  if (link_info.unresolved_syms_in_shared_libs == RM_NOT_YET_SET)
  if (link_info.unresolved_syms_in_shared_libs == RM_NOT_YET_SET)
    /* FIXME: Should we allow emulations a chance to set this ?  */
    /* FIXME: Should we allow emulations a chance to set this ?  */
    link_info.unresolved_syms_in_shared_libs = how_to_report_unresolved_symbols;
    link_info.unresolved_syms_in_shared_libs = how_to_report_unresolved_symbols;
}
}
 
 
/* Add the (colon-separated) elements of DIRLIST_PTR to the
/* Add the (colon-separated) elements of DIRLIST_PTR to the
   library search path.  */
   library search path.  */
 
 
static void
static void
set_default_dirlist (char *dirlist_ptr)
set_default_dirlist (char *dirlist_ptr)
{
{
  char *p;
  char *p;
 
 
  while (1)
  while (1)
    {
    {
      p = strchr (dirlist_ptr, PATH_SEPARATOR);
      p = strchr (dirlist_ptr, PATH_SEPARATOR);
      if (p != NULL)
      if (p != NULL)
        *p = '\0';
        *p = '\0';
      if (*dirlist_ptr != '\0')
      if (*dirlist_ptr != '\0')
        ldfile_add_library_path (dirlist_ptr, TRUE);
        ldfile_add_library_path (dirlist_ptr, TRUE);
      if (p == NULL)
      if (p == NULL)
        break;
        break;
      dirlist_ptr = p + 1;
      dirlist_ptr = p + 1;
    }
    }
}
}
 
 
static void
static void
set_section_start (char *sect, char *valstr)
set_section_start (char *sect, char *valstr)
{
{
  const char *end;
  const char *end;
  bfd_vma val = bfd_scan_vma (valstr, &end, 16);
  bfd_vma val = bfd_scan_vma (valstr, &end, 16);
  if (*end)
  if (*end)
    einfo (_("%P%F: invalid hex number `%s'\n"), valstr);
    einfo (_("%P%F: invalid hex number `%s'\n"), valstr);
  lang_section_start (sect, exp_intop (val), NULL);
  lang_section_start (sect, exp_intop (val), NULL);
}
}
 
 
static void
static void
set_segment_start (const char *section, char *valstr)
set_segment_start (const char *section, char *valstr)
{
{
  const char *name;
  const char *name;
  const char *end;
  const char *end;
  segment_type *seg;
  segment_type *seg;
 
 
  bfd_vma val = bfd_scan_vma (valstr, &end, 16);
  bfd_vma val = bfd_scan_vma (valstr, &end, 16);
  if (*end)
  if (*end)
    einfo (_("%P%F: invalid hex number `%s'\n"), valstr);
    einfo (_("%P%F: invalid hex number `%s'\n"), valstr);
  /* If we already have an entry for this segment, update the existing
  /* If we already have an entry for this segment, update the existing
     value.  */
     value.  */
  name = section + 1;
  name = section + 1;
  for (seg = segments; seg; seg = seg->next)
  for (seg = segments; seg; seg = seg->next)
    if (strcmp (seg->name, name) == 0)
    if (strcmp (seg->name, name) == 0)
      {
      {
        seg->value = val;
        seg->value = val;
        return;
        return;
      }
      }
  /* There was no existing value so we must create a new segment
  /* There was no existing value so we must create a new segment
     entry.  */
     entry.  */
  seg = (segment_type *) stat_alloc (sizeof (*seg));
  seg = (segment_type *) stat_alloc (sizeof (*seg));
  seg->name = name;
  seg->name = name;
  seg->value = val;
  seg->value = val;
  seg->used = FALSE;
  seg->used = FALSE;
  /* Add it to the linked list of segments.  */
  /* Add it to the linked list of segments.  */
  seg->next = segments;
  seg->next = segments;
  segments = seg;
  segments = seg;
  /* Historically, -Ttext and friends set the base address of a
  /* Historically, -Ttext and friends set the base address of a
     particular section.  For backwards compatibility, we still do
     particular section.  For backwards compatibility, we still do
     that.  If a SEGMENT_START directive is seen, the section address
     that.  If a SEGMENT_START directive is seen, the section address
     assignment will be disabled.  */
     assignment will be disabled.  */
  lang_section_start (section, exp_intop (val), seg);
  lang_section_start (section, exp_intop (val), seg);
}
}
 
 


/* Print help messages for the options.  */
/* Print help messages for the options.  */
 
 
static void
static void
help (void)
help (void)
{
{
  unsigned i;
  unsigned i;
  const char **targets, **pp;
  const char **targets, **pp;
  int len;
  int len;
 
 
  printf (_("Usage: %s [options] file...\n"), program_name);
  printf (_("Usage: %s [options] file...\n"), program_name);
 
 
  printf (_("Options:\n"));
  printf (_("Options:\n"));
  for (i = 0; i < OPTION_COUNT; i++)
  for (i = 0; i < OPTION_COUNT; i++)
    {
    {
      if (ld_options[i].doc != NULL)
      if (ld_options[i].doc != NULL)
        {
        {
          bfd_boolean comma;
          bfd_boolean comma;
          unsigned j;
          unsigned j;
 
 
          printf ("  ");
          printf ("  ");
 
 
          comma = FALSE;
          comma = FALSE;
          len = 2;
          len = 2;
 
 
          j = i;
          j = i;
          do
          do
            {
            {
              if (ld_options[j].shortopt != '\0'
              if (ld_options[j].shortopt != '\0'
                  && ld_options[j].control != NO_HELP)
                  && ld_options[j].control != NO_HELP)
                {
                {
                  printf ("%s-%c", comma ? ", " : "", ld_options[j].shortopt);
                  printf ("%s-%c", comma ? ", " : "", ld_options[j].shortopt);
                  len += (comma ? 2 : 0) + 2;
                  len += (comma ? 2 : 0) + 2;
                  if (ld_options[j].arg != NULL)
                  if (ld_options[j].arg != NULL)
                    {
                    {
                      if (ld_options[j].opt.has_arg != optional_argument)
                      if (ld_options[j].opt.has_arg != optional_argument)
                        {
                        {
                          printf (" ");
                          printf (" ");
                          ++len;
                          ++len;
                        }
                        }
                      printf ("%s", _(ld_options[j].arg));
                      printf ("%s", _(ld_options[j].arg));
                      len += strlen (_(ld_options[j].arg));
                      len += strlen (_(ld_options[j].arg));
                    }
                    }
                  comma = TRUE;
                  comma = TRUE;
                }
                }
              ++j;
              ++j;
            }
            }
          while (j < OPTION_COUNT && ld_options[j].doc == NULL);
          while (j < OPTION_COUNT && ld_options[j].doc == NULL);
 
 
          j = i;
          j = i;
          do
          do
            {
            {
              if (ld_options[j].opt.name != NULL
              if (ld_options[j].opt.name != NULL
                  && ld_options[j].control != NO_HELP)
                  && ld_options[j].control != NO_HELP)
                {
                {
                  int two_dashes =
                  int two_dashes =
                    (ld_options[j].control == TWO_DASHES
                    (ld_options[j].control == TWO_DASHES
                     || ld_options[j].control == EXACTLY_TWO_DASHES);
                     || ld_options[j].control == EXACTLY_TWO_DASHES);
 
 
                  printf ("%s-%s%s",
                  printf ("%s-%s%s",
                          comma ? ", " : "",
                          comma ? ", " : "",
                          two_dashes ? "-" : "",
                          two_dashes ? "-" : "",
                          ld_options[j].opt.name);
                          ld_options[j].opt.name);
                  len += ((comma ? 2 : 0)
                  len += ((comma ? 2 : 0)
                          + 1
                          + 1
                          + (two_dashes ? 1 : 0)
                          + (two_dashes ? 1 : 0)
                          + strlen (ld_options[j].opt.name));
                          + strlen (ld_options[j].opt.name));
                  if (ld_options[j].arg != NULL)
                  if (ld_options[j].arg != NULL)
                    {
                    {
                      printf (" %s", _(ld_options[j].arg));
                      printf (" %s", _(ld_options[j].arg));
                      len += 1 + strlen (_(ld_options[j].arg));
                      len += 1 + strlen (_(ld_options[j].arg));
                    }
                    }
                  comma = TRUE;
                  comma = TRUE;
                }
                }
              ++j;
              ++j;
            }
            }
          while (j < OPTION_COUNT && ld_options[j].doc == NULL);
          while (j < OPTION_COUNT && ld_options[j].doc == NULL);
 
 
          if (len >= 30)
          if (len >= 30)
            {
            {
              printf ("\n");
              printf ("\n");
              len = 0;
              len = 0;
            }
            }
 
 
          for (; len < 30; len++)
          for (; len < 30; len++)
            putchar (' ');
            putchar (' ');
 
 
          printf ("%s\n", _(ld_options[i].doc));
          printf ("%s\n", _(ld_options[i].doc));
        }
        }
    }
    }
  printf (_("  @FILE"));
  printf (_("  @FILE"));
  for (len = strlen ("  @FILE"); len < 30; len++)
  for (len = strlen ("  @FILE"); len < 30; len++)
    putchar (' ');
    putchar (' ');
  printf (_("Read options from FILE\n"));
  printf (_("Read options from FILE\n"));
 
 
  /* Note: Various tools (such as libtool) depend upon the
  /* Note: Various tools (such as libtool) depend upon the
     format of the listings below - do not change them.  */
     format of the listings below - do not change them.  */
  /* xgettext:c-format */
  /* xgettext:c-format */
  printf (_("%s: supported targets:"), program_name);
  printf (_("%s: supported targets:"), program_name);
  targets = bfd_target_list ();
  targets = bfd_target_list ();
  for (pp = targets; *pp != NULL; pp++)
  for (pp = targets; *pp != NULL; pp++)
    printf (" %s", *pp);
    printf (" %s", *pp);
  free (targets);
  free (targets);
  printf ("\n");
  printf ("\n");
 
 
  /* xgettext:c-format */
  /* xgettext:c-format */
  printf (_("%s: supported emulations: "), program_name);
  printf (_("%s: supported emulations: "), program_name);
  ldemul_list_emulations (stdout);
  ldemul_list_emulations (stdout);
  printf ("\n");
  printf ("\n");
 
 
  /* xgettext:c-format */
  /* xgettext:c-format */
  printf (_("%s: emulation specific options:\n"), program_name);
  printf (_("%s: emulation specific options:\n"), program_name);
  ldemul_list_emulation_options (stdout);
  ldemul_list_emulation_options (stdout);
  printf ("\n");
  printf ("\n");
 
 
  if (REPORT_BUGS_TO[0])
  if (REPORT_BUGS_TO[0])
    printf (_("Report bugs to %s\n"), REPORT_BUGS_TO);
    printf (_("Report bugs to %s\n"), REPORT_BUGS_TO);
}
}
 
 

powered by: WebSVN 2.1.0

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