#include "libiberty.h"
#include <stdio.h>
#include <string.h>
-#include <ctype.h>
+#include "safe-ctype.h"
#include "getopt.h"
#include "bfdlink.h"
#include "ld.h"
#define OPTION_VERSION_EXPORTS_SECTION (OPTION_VERSION_SCRIPT + 1)
#define OPTION_WARN_COMMON (OPTION_VERSION_EXPORTS_SECTION + 1)
#define OPTION_WARN_CONSTRUCTORS (OPTION_WARN_COMMON + 1)
-#define OPTION_WARN_MULTIPLE_GP (OPTION_WARN_CONSTRUCTORS + 1)
+#define OPTION_WARN_FATAL (OPTION_WARN_CONSTRUCTORS + 1)
+#define OPTION_WARN_MULTIPLE_GP (OPTION_WARN_FATAL + 1)
#define OPTION_WARN_ONCE (OPTION_WARN_MULTIPLE_GP + 1)
#define OPTION_WARN_SECTION_ALIGN (OPTION_WARN_ONCE + 1)
#define OPTION_SPLIT_BY_RELOC (OPTION_WARN_SECTION_ALIGN + 1)
#define OPTION_TARGET_HELP (OPTION_UNIQUE + 1)
#define OPTION_ALLOW_SHLIB_UNDEFINED (OPTION_TARGET_HELP + 1)
#define OPTION_DISCARD_NONE (OPTION_ALLOW_SHLIB_UNDEFINED + 1)
+#define OPTION_SPARE_DYNAMIC_TAGS (OPTION_DISCARD_NONE + 1)
+#define OPTION_NO_DEFINE_COMMON (OPTION_SPARE_DYNAMIC_TAGS + 1)
+#define OPTION_NOSTDLIB (OPTION_NO_DEFINE_COMMON + 1)
/* The long options. This structure is used for both the option
parsing and the help text. */
TWO_DASHES },
{ {"soname", required_argument, NULL, OPTION_SONAME},
'h', N_("FILENAME"), N_("Set internal name of shared library"), ONE_DASH },
+ { {"dynamic-linker", required_argument, NULL, OPTION_DYNAMIC_LINKER},
+ 'I', N_("PROGRAM"), N_("Set PROGRAM as the dynamic linker to use"), TWO_DASHES },
{ {"library", required_argument, NULL, 'l'},
'l', N_("LIBNAME"), N_("Search for library LIBNAME"), TWO_DASHES },
{ {"library-path", required_argument, NULL, 'L'},
'\0', N_("SYMBOL=EXPRESSION"), N_("Define a symbol"), TWO_DASHES },
{ {"demangle", optional_argument, NULL, OPTION_DEMANGLE},
'\0', N_("[=STYLE]"), N_("Demangle symbol names [using STYLE]"), TWO_DASHES },
- { {"dynamic-linker", required_argument, NULL, OPTION_DYNAMIC_LINKER},
- '\0', N_("PROGRAM"), N_("Set the dynamic linker to use"), TWO_DASHES },
{ {"embedded-relocs", no_argument, NULL, OPTION_EMBEDDED_RELOCS},
'\0', NULL, N_("Generate embedded relocs"), TWO_DASHES},
{ {"fini", required_argument, NULL, OPTION_FINI},
'\0', N_("SYMBOL"), N_("Call SYMBOL at load-time"), ONE_DASH },
{ {"Map", required_argument, NULL, OPTION_MAP},
'\0', N_("FILE"), N_("Write a map file"), ONE_DASH },
+ { {"no-define-common", no_argument, NULL, OPTION_NO_DEFINE_COMMON},
+ '\0', NULL, N_("Do not define Common storage"), TWO_DASHES },
{ {"no-demangle", no_argument, NULL, OPTION_NO_DEMANGLE },
'\0', NULL, N_("Do not demangle symbol names"), TWO_DASHES },
{ {"no-keep-memory", no_argument, NULL, OPTION_NO_KEEP_MEMORY},
'\0', NULL, N_("Create an output file even if errors occur"), TWO_DASHES },
{ {"noinhibit_exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC},
'\0', NULL, NULL, NO_HELP },
+ { {"nostdlib", no_argument, NULL, OPTION_NOSTDLIB},
+ '\0', NULL, N_("Only use library directories specified on\n\t\t\t\tthe command line"), ONE_DASH },
{ {"oformat", required_argument, NULL, OPTION_OFORMAT},
'\0', N_("TARGET"), N_("Specify target of output file"), EXACTLY_TWO_DASHES },
{ {"qmagic", no_argument, NULL, OPTION_IGNORE},
'\0', NULL, N_("Sort common symbols by size"), TWO_DASHES },
{ {"sort_common", no_argument, NULL, OPTION_SORT_COMMON},
'\0', NULL, NULL, NO_HELP },
+ { {"spare-dynamic-tags", required_argument, NULL, OPTION_SPARE_DYNAMIC_TAGS},
+ '\0', N_("COUNT"), N_("How many tags to reserve in .dynamic section"), TWO_DASHES },
{ {"split-by-file", optional_argument, NULL, OPTION_SPLIT_BY_FILE},
'\0', N_("[=SIZE]"), N_("Split output sections every SIZE octets"), TWO_DASHES },
{ {"split-by-reloc", optional_argument, NULL, OPTION_SPLIT_BY_RELOC},
{ {"warn-section-align", no_argument, NULL, OPTION_WARN_SECTION_ALIGN},
'\0', NULL, N_("Warn if start of section changes due to alignment"),
TWO_DASHES },
+ { {"fatal-warnings", no_argument, NULL, OPTION_WARN_FATAL},
+ '\0', NULL, N_("Treat warnings as errors"),
+ TWO_DASHES },
{ {"whole-archive", no_argument, NULL, OPTION_WHOLE_ARCHIVE},
'\0', NULL, N_("Include all objects from following archives"), TWO_DASHES },
{ {"wrap", required_argument, NULL, OPTION_WRAP},
for (; *string; ++string)
{
- if (! isdigit (*string))
+ if (! ISDIGIT (*string))
{
result = err;
break;
for (i = 1; i < argc; i++)
if (strcmp (argv[i], "-G") == 0
&& (i + 1 >= argc
- || ! isdigit ((unsigned char) argv[i + 1][0])))
+ || ! ISDIGIT (argv[i + 1][0])))
argv[i] = (char *) "--shared";
/* Because we permit long options to start with a single dash, and
-nx, in which the -n is parsed as a single option, and we
loop around to pick up the -x. */
if (optind != last_optind)
- {
- if (ldemul_parse_args (argc, argv))
- continue;
- last_optind = optind;
- }
+ if (ldemul_parse_args (argc, argv))
+ continue;
/* getopt_long_only is like getopt_long, but '-' as well as '--'
can indicate a long option. */
opterr = 0;
+ last_optind = optind;
optc = getopt_long_only (argc, argv, shortopts, longopts, &longind);
if (optc == '?')
{
- --optind;
- optc = getopt_long (argc, argv, shortopts, really_longopts, &longind);
+ optind = last_optind;
+ optc = getopt_long (argc, argv, "-", really_longopts, &longind);
}
if (optc == -1)
switch (optc)
{
case '?':
- fprintf (stderr, _("%s: unrecognized option '%s'\n"),
- program_name, argv[optind - 1]);
+ einfo (_("%P: unrecognized option '%s'\n"), argv[last_optind]);
default:
- fprintf (stderr,
- _("%s: use the --help option for usage information\n"),
- program_name);
- xexit (1);
+ einfo (_("%P%F: use the --help option for usage information\n"));
+
case 1: /* File name. */
lang_add_input_file (optarg, lang_input_file_is_file_enum,
(char *) NULL);
cplus_demangle_set_style (style);
}
break;
+ case 'I': /* Used on Solaris. */
case OPTION_DYNAMIC_LINKER:
command_line.interpreter = optarg;
break;
break;
case OPTION_EXPORT_DYNAMIC:
case 'E': /* HP/UX compatibility. */
- command_line.export_dynamic = true;
+ link_info.export_dynamic = true;
break;
case 'e':
lang_add_entry (optarg, true);
config.magic_demand_paged = false;
config.dynamic_link = false;
break;
+ case OPTION_NO_DEFINE_COMMON:
+ command_line.inhibit_common_definition = true;
+ break;
case OPTION_NO_DEMANGLE:
demangling = false;
break;
case OPTION_NOINHIBIT_EXEC:
force_make_executable = true;
break;
+ case OPTION_NOSTDLIB:
+ config.only_cmd_line_lib_dirs = true;
+ break;
case OPTION_NO_WHOLE_ARCHIVE:
whole_archive = false;
break;
break;
case 'i':
case 'r':
+ if (optind == last_optind)
+ /* This can happen if the user put "-rpath,a" on the command
+ line. (Or something similar. The comma is important).
+ Getopt becomes confused and thinks that this is a -r option
+ but it cannot parse the text after the -r so it refuses to
+ increment the optind counter. Detect this case and issue
+ an error message here. We cannot just make this a warning,
+ increment optind, and continue because getopt is too confused
+ and will seg-fault the next time around. */
+ einfo(_("%P%F: bad -rpath option\n"));
+
link_info.relocateable = true;
config.build_constructors = false;
config.magic_demand_paged = false;
/* Fall through. */
case OPTION_RPATH:
if (command_line.rpath == NULL)
- command_line.rpath = buystring (optarg);
+ command_line.rpath = xstrdup (optarg);
else
{
size_t rpath_len = strlen (command_line.rpath);
do
{
size_t idx = 0;
+
while (optarg[idx] != '\0' && optarg[idx] == cp[idx])
++idx;
if (optarg[idx] == '\0'
break;
case OPTION_RPATH_LINK:
if (command_line.rpath_link == NULL)
- command_line.rpath_link = buystring (optarg);
+ command_line.rpath_link = xstrdup (optarg);
else
{
char *buf;
/* Check for <something>=<somthing>... */
optarg2 = strchr (optarg, '=');
if (optarg2 == NULL)
- {
- fprintf (stderr,
- _("%s: Invalid argument to option \"--section-start\"\n"),
- program_name);
- xexit (1);
- }
+ einfo (_("%P%F: invalid argument to option \"--section-start\"\n"));
optarg2++;
/* So far so good. Are all the args present? */
if ((*optarg == '\0') || (*optarg2 == '\0'))
- {
- fprintf (stderr,
- _("%s: Missing argument(s) to option \"--section-start\"\n"),
- program_name);
- xexit (1);
- }
+ einfo (_("%P%F: missing argument(s) to option \"--section-start\"\n"));
/* We must copy the section name as set_section_start
doesn't do it for us. */
version_printed = true;
break;
case OPTION_VERSION:
- /* This output is intended to follow the GNU standards document. */
- printf ("GNU ld %s\n", ld_program_version);
- printf (_("Copyright 2001 Free Software Foundation, Inc.\n"));
- printf (_("\
-This program is free software; you may redistribute it under the terms of\n\
-the GNU General Public License. This program has absolutely no warranty.\n"));
- {
- ld_emulation_xfer_type **ptr = ld_emulations;
-
- printf (_(" Supported emulations:\n"));
- while (*ptr)
- {
- printf (" %s\n", (*ptr)->emulation_name);
- ptr++;
- }
- }
+ ldversion (2);
xexit (0);
break;
case OPTION_VERSION_SCRIPT:
version information. Read it, but don't assume that
we've seen a linker script. */
{
- boolean hold_had_script;
+ FILE * hold_script_handle;
- hold_had_script = had_script;
+ hold_script_handle = saved_script_handle;
ldfile_open_command_file (optarg);
- had_script = hold_had_script;
+ saved_script_handle = hold_script_handle;
parser_input = input_version_script;
yyparse ();
}
case OPTION_WARN_CONSTRUCTORS:
config.warn_constructors = true;
break;
+ case OPTION_WARN_FATAL:
+ config.fatal_warnings = true;
+ break;
case OPTION_WARN_MULTIPLE_GP:
config.warn_multiple_gp = true;
break;
case 'y':
add_ysym (optarg);
break;
+ case OPTION_SPARE_DYNAMIC_TAGS:
+ link_info.spare_dynamic_tags = strtoul (optarg, NULL, 0);
+ break;
case OPTION_SPLIT_BY_RELOC:
if (optarg != NULL)
config.split_by_reloc = strtoul (optarg, NULL, 0);
break;
case '(':
if (ingroup)
- {
- fprintf (stderr,
- _("%s: may not nest groups (--help for usage)\n"),
- program_name);
- xexit (1);
- }
+ einfo (_("%P%F: may not nest groups (--help for usage)\n"));
+
lang_enter_group ();
ingroup = 1;
break;
case ')':
if (! ingroup)
- {
- fprintf (stderr,
- _("%s: group ended before it began (--help for usage)\n"),
- program_name);
- xexit (1);
- }
+ einfo (_("%P%F: group ended before it began (--help for usage)\n"));
+
lang_leave_group ();
ingroup = 0;
break;
case OPTION_MPC860C0:
- link_info.mpc860c0 = 20; /* default value (in bytes) */
+ /* Default value (in bytes). */
+ link_info.mpc860c0 = 20;
if (optarg)
{
unsigned words;
words = is_num (optarg, 1, 10, 0);
if (words == 0)
- {
- fprintf (stderr,
- _("%s: Invalid argument to option \"mpc860c0\"\n"),
- program_name);
- xexit (1);
- }
- link_info.mpc860c0 = words * 4; /* convert words to bytes */
+ einfo (_("%P%F: invalid argument to option \"mpc860c0\"\n"));
+
+ /* Convert words to bytes. */
+ link_info.mpc860c0 = words * 4;
}
command_line.relax = true;
break;