]> oss.titaniummirror.com Git - msp430-binutils.git/blobdiff - ld/lexsup.c
Merge commit 'upstream/2.20'
[msp430-binutils.git] / ld / lexsup.c
index 2a31683b0e74a740acfc4967c9ae3c99e7e8745c..47c72dba6a21bb70f3e773256765874cfc3588e1 100644 (file)
@@ -1,6 +1,6 @@
 /* Parse options for the GNU linker.
    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005, 2006, 2007
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
    Free Software Foundation, Inc.
 
    This file is part of the GNU Binutils.
@@ -77,6 +77,7 @@ enum option_values
   OPTION_EL,
   OPTION_EMBEDDED_RELOCS,
   OPTION_EXPORT_DYNAMIC,
+  OPTION_NO_EXPORT_DYNAMIC,
   OPTION_HELP,
   OPTION_IGNORE,
   OPTION_MAP,
@@ -103,6 +104,7 @@ enum option_values
   OPTION_TBSS,
   OPTION_TDATA,
   OPTION_TTEXT,
+  OPTION_TTEXT_SEGMENT,
   OPTION_TRADITIONAL_FORMAT,
   OPTION_UR,
   OPTION_VERBOSE,
@@ -116,6 +118,7 @@ enum option_values
   OPTION_WARN_COMMON,
   OPTION_WARN_CONSTRUCTORS,
   OPTION_WARN_FATAL,
+  OPTION_NO_WARN_FATAL,
   OPTION_WARN_MULTIPLE_GP,
   OPTION_WARN_ONCE,
   OPTION_WARN_SECTION_ALIGN,
@@ -161,6 +164,7 @@ enum option_values
   OPTION_WARN_UNRESOLVED_SYMBOLS,
   OPTION_ERROR_UNRESOLVED_SYMBOLS,
   OPTION_WARN_SHARED_TEXTREL,
+  OPTION_WARN_ALTERNATE_EM,
   OPTION_REDUCE_MEMORY_OVERHEADS,
   OPTION_DEFAULT_SCRIPT
 };
@@ -168,6 +172,25 @@ enum option_values
 /* The long options.  This structure is used for both the option
    parsing and the help text.  */
 
+enum control_enum {
+  /* Use one dash before long option name.  */
+  ONE_DASH,
+  /* Use two dashes before long option name.  */
+  TWO_DASHES,
+  /* Only accept two dashes before the long option name.
+     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
+     the long option name.  This feature was added in order to resolve
+     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 ?  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
+     or --omagic.  */
+  EXACTLY_TWO_DASHES,
+  /* Don't mention this option in --help output.  */
+  NO_HELP
+};
+
 struct ld_option
 {
   /* The long option information.  */
@@ -179,24 +202,7 @@ struct ld_option
   /* The documentation string.  If this is NULL, this is a synonym for
      the previous option.  */
   const char *doc;
-  enum {
-    /* Use one dash before long option name.  */
-    ONE_DASH,
-    /* Use two dashes before long option name.  */
-    TWO_DASHES,
-    /* Only accept two dashes before the long option name.
-       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
-       the long option name.  This feature was added in order to resolve
-       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 ?  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
-       or --omagic.  */
-    EXACTLY_TWO_DASHES,
-    /* Don't mention this option in --help output.  */
-    NO_HELP
-  } control;
+  enum control_enum control;
 };
 
 static const struct ld_option ld_options[] =
@@ -219,6 +225,8 @@ static const struct ld_option ld_options[] =
     'e', N_("ADDRESS"), N_("Set start address"), TWO_DASHES },
   { {"export-dynamic", no_argument, NULL, OPTION_EXPORT_DYNAMIC},
     'E', NULL, N_("Export all dynamic symbols"), TWO_DASHES },
+  { {"no-export-dynamic", no_argument, NULL, OPTION_NO_EXPORT_DYNAMIC},
+    '\0', NULL, N_("Undo the effect of --export-dynamic"), TWO_DASHES },
   { {"EB", no_argument, NULL, OPTION_EB},
     '\0', NULL, N_("Link big-endian objects"), ONE_DASH },
   { {"EL", no_argument, NULL, OPTION_EL},
@@ -327,10 +335,12 @@ static const struct ld_option ld_options[] =
     TWO_DASHES },
   { {"add-needed", no_argument, NULL, OPTION_ADD_NEEDED},
     '\0', NULL, N_("Set DT_NEEDED tags for DT_NEEDED entries in\n"
-                  "\t\t\t\tfollowing dynamic libs"), TWO_DASHES },
+                  "                                following dynamic libs"),
+    TWO_DASHES },
   { {"no-add-needed", no_argument, NULL, OPTION_NO_ADD_NEEDED},
     '\0', NULL, N_("Do not set DT_NEEDED tags for DT_NEEDED entries\n"
-                  "\t\t\t\tin following dynamic libs"), TWO_DASHES },
+                  "                                in following dynamic libs"),
+    TWO_DASHES },
   { {"as-needed", no_argument, NULL, OPTION_AS_NEEDED},
     '\0', NULL, N_("Only set DT_NEEDED for following dynamic libs if used"),
     TWO_DASHES },
@@ -375,6 +385,9 @@ static const struct ld_option ld_options[] =
   { {"fatal-warnings", no_argument, NULL, OPTION_WARN_FATAL},
     '\0', NULL, N_("Treat warnings as errors"),
     TWO_DASHES },
+  { {"no-fatal-warnings", no_argument, NULL, OPTION_NO_WARN_FATAL},
+    '\0', NULL, N_("Do not treat warnings as errors (default)"),
+    TWO_DASHES },
   { {"fini", required_argument, NULL, OPTION_FINI},
     '\0', N_("SYMBOL"), N_("Call SYMBOL at unload-time"), ONE_DASH },
   { {"force-exe-suffix", no_argument, NULL, OPTION_FORCE_EXE_SUFFIX},
@@ -442,7 +455,8 @@ static const struct ld_option ld_options[] =
     '\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 },
+                  "                                the command line"),
+    ONE_DASH },
   { {"oformat", required_argument, NULL, OPTION_OFORMAT},
     '\0', N_("TARGET"), N_("Specify target of output file"),
     EXACTLY_TWO_DASHES },
@@ -470,8 +484,10 @@ static const struct ld_option ld_options[] =
     '\0', NULL, N_("Create a position independent executable"), ONE_DASH },
   { {"pic-executable", no_argument, NULL, OPTION_PIE},
     '\0', NULL, NULL, TWO_DASHES },
-  { {"sort-common", no_argument, NULL, OPTION_SORT_COMMON},
-    '\0', NULL, N_("Sort common symbols by size"), TWO_DASHES },
+  { {"sort-common", optional_argument, NULL, OPTION_SORT_COMMON},
+    '\0', N_("[=ascending|descending]"), 
+    N_("Sort common symbols by alignment [in specified order]"), 
+    TWO_DASHES },
   { {"sort_common", no_argument, NULL, OPTION_SORT_COMMON},
     '\0', NULL, NULL, NO_HELP },
   { {"sort-section", required_argument, NULL, OPTION_SORT_SECTION},
@@ -503,11 +519,14 @@ static const struct ld_option ld_options[] =
     '\0', N_("ADDRESS"), N_("Set address of .data section"), ONE_DASH },
   { {"Ttext", required_argument, NULL, OPTION_TTEXT},
     '\0', N_("ADDRESS"), N_("Set address of .text section"), ONE_DASH },
+  { {"Ttext-segment", required_argument, NULL, OPTION_TTEXT_SEGMENT},
+    '\0', N_("ADDRESS"), N_("Set address of text segment"), ONE_DASH },
   { {"unresolved-symbols=<method>", required_argument, NULL,
      OPTION_UNRESOLVED_SYMBOLS},
     '\0', NULL, N_("How to handle unresolved symbols.  <method> is:\n"
-                  "\t\t\t\tignore-all, report-all, ignore-in-object-files,\n"
-                  "\t\t\t\tignore-in-shared-libs"), TWO_DASHES },
+                  "                                ignore-all, report-all, ignore-in-object-files,\n"
+                  "                                ignore-in-shared-libs"),
+    TWO_DASHES },
   { {"verbose", no_argument, NULL, OPTION_VERBOSE},
     '\0', NULL, N_("Output lots of information during link"), TWO_DASHES },
   { {"dll-verbose", no_argument, NULL, OPTION_VERBOSE}, /* Linux.  */
@@ -517,7 +536,8 @@ static const struct ld_option ld_options[] =
   { {"version-exports-section", required_argument, NULL,
      OPTION_VERSION_EXPORTS_SECTION },
     '\0', N_("SYMBOL"), N_("Take export symbols list from .exports, using\n"
-                          "\t\t\t\tSYMBOL as the version."), TWO_DASHES },
+                          "                                SYMBOL as the version."),
+    TWO_DASHES },
   { {"dynamic-list-data", no_argument, NULL, OPTION_DYNAMIC_LIST_DATA},
     '\0', NULL, N_("Add data symbols to dynamic list"), TWO_DASHES },
   { {"dynamic-list-cpp-new", no_argument, NULL, OPTION_DYNAMIC_LIST_CPP_NEW},
@@ -541,6 +561,9 @@ static const struct ld_option ld_options[] =
   { {"warn-shared-textrel", no_argument, NULL, OPTION_WARN_SHARED_TEXTREL},
     '\0', NULL, N_("Warn if shared object has DT_TEXTREL"),
     TWO_DASHES },
+  { {"warn-alternate-em", no_argument, NULL, OPTION_WARN_ALTERNATE_EM},
+    '\0', NULL, N_("Warn if an object has alternate ELF machine code"),
+    TWO_DASHES },
   { {"warn-unresolved-symbols", no_argument, NULL,
      OPTION_WARN_UNRESOLVED_SYMBOLS},
     '\0', NULL, N_("Report unresolved symbols as warnings"), TWO_DASHES },
@@ -569,9 +592,11 @@ parse_args (unsigned argc, char **argv)
   int last_optind;
   enum report_method how_to_report_unresolved_symbols = RM_GENERATE_ERROR;
 
-  shortopts = xmalloc (OPTION_COUNT * 3 + 2);
-  longopts = xmalloc (sizeof (*longopts) * (OPTION_COUNT + 1));
-  really_longopts = xmalloc (sizeof (*really_longopts) * (OPTION_COUNT + 1));
+  shortopts = (char *) xmalloc (OPTION_COUNT * 3 + 2);
+  longopts = (struct option *)
+      xmalloc (sizeof (*longopts) * (OPTION_COUNT + 1));
+  really_longopts = (struct option *)
+      malloc (sizeof (*really_longopts) * (OPTION_COUNT + 1));
 
   /* Starting the short option string with '-' is for programs that
      expect options and other ARGV-elements in any order and that care about
@@ -656,7 +681,7 @@ parse_args (unsigned argc, char **argv)
        {
          char *n;
 
-         n = xmalloc (strlen (argv[i]) + 20);
+         n = (char *) xmalloc (strlen (argv[i]) + 20);
          sprintf (n, "--library=%s", argv[i] + 2);
          argv[i] = n;
        }
@@ -802,13 +827,17 @@ parse_args (unsigned argc, char **argv)
        case 'E': /* HP/UX compatibility.  */
          link_info.export_dynamic = TRUE;
          break;
+       case OPTION_NO_EXPORT_DYNAMIC:
+         link_info.export_dynamic = FALSE;
+         break;
        case 'e':
          lang_add_entry (optarg, TRUE);
          break;
        case 'f':
          if (command_line.auxiliary_filters == NULL)
            {
-             command_line.auxiliary_filters = xmalloc (2 * sizeof (char *));
+             command_line.auxiliary_filters = (char **)
+                  xmalloc (2 * sizeof (char *));
              command_line.auxiliary_filters[0] = optarg;
              command_line.auxiliary_filters[1] = NULL;
            }
@@ -820,8 +849,8 @@ parse_args (unsigned argc, char **argv)
              c = 0;
              for (p = command_line.auxiliary_filters; *p != NULL; p++)
                ++c;
-             command_line.auxiliary_filters
-               = xrealloc (command_line.auxiliary_filters,
+             command_line.auxiliary_filters = (char **)
+                  xrealloc (command_line.auxiliary_filters,
                            (c + 2) * sizeof (char *));
              command_line.auxiliary_filters[c] = optarg;
              command_line.auxiliary_filters[c + 1] = NULL;
@@ -1067,7 +1096,7 @@ parse_args (unsigned argc, char **argv)
 
              if (cp == NULL)
                {
-                 buf = xmalloc (rpath_len + optarg_len + 2);
+                 buf = (char *) xmalloc (rpath_len + optarg_len + 2);
                  sprintf (buf, "%s%c%s", command_line.rpath,
                           config.rpath_separator, optarg);
                  free (command_line.rpath);
@@ -1082,9 +1111,9 @@ parse_args (unsigned argc, char **argv)
            {
              char *buf;
 
-             buf = xmalloc (strlen (command_line.rpath_link)
-                            + strlen (optarg)
-                            + 2);
+             buf = (char *) xmalloc (strlen (command_line.rpath_link)
+                                      + strlen (optarg)
+                                      + 2);
              sprintf (buf, "%s%c%s", command_line.rpath_link,
                       config.rpath_separator, optarg);
              free (command_line.rpath_link);
@@ -1137,7 +1166,14 @@ parse_args (unsigned argc, char **argv)
          command_line.soname = optarg;
          break;
        case OPTION_SORT_COMMON:
-         config.sort_common = TRUE;
+         if (optarg == NULL
+             || strcmp (optarg, N_("descending")) == 0)
+            config.sort_common = sort_descending;
+          else if (strcmp (optarg, N_("ascending")) == 0)
+           config.sort_common = sort_ascending;
+         else
+           einfo (_("%P%F: invalid common section sorting option: %s\n"),
+                  optarg);
          break;
        case OPTION_SORT_SECTION:
          if (strcmp (optarg, N_("name")) == 0)
@@ -1161,9 +1197,11 @@ parse_args (unsigned argc, char **argv)
          trace_files = TRUE;
          break;
        case 'T':
+         previous_script_handle = saved_script_handle;
          ldfile_open_command_file (optarg);
          parser_input = input_script;
          yyparse ();
+         previous_script_handle = NULL;
          break;
        case OPTION_DEFAULT_SCRIPT:
          command_line.default_script = optarg;
@@ -1190,7 +1228,7 @@ parse_args (unsigned argc, char **argv)
            /* We must copy the section name as set_section_start
               doesn't do it for us.  */
            len = optarg2 - optarg;
-           sec_name = xmalloc (len);
+           sec_name = (char *) xmalloc (len);
            memcpy (sec_name, optarg, len - 1);
            sec_name[len - 1] = 0;
 
@@ -1211,6 +1249,9 @@ parse_args (unsigned argc, char **argv)
        case OPTION_TTEXT:
          set_segment_start (".text", optarg);
          break;
+       case OPTION_TTEXT_SEGMENT:
+         set_segment_start (".text-segment", optarg);
+         break;
        case OPTION_TRADITIONAL_FORMAT:
          link_info.traditional_format = TRUE;
          break;
@@ -1317,6 +1358,9 @@ parse_args (unsigned argc, char **argv)
        case OPTION_WARN_FATAL:
          config.fatal_warnings = TRUE;
          break;
+       case OPTION_NO_WARN_FATAL:
+         config.fatal_warnings = FALSE;
+         break;
        case OPTION_WARN_MULTIPLE_GP:
          config.warn_multiple_gp = TRUE;
          break;
@@ -1329,6 +1373,9 @@ parse_args (unsigned argc, char **argv)
        case OPTION_WARN_SHARED_TEXTREL:
          link_info.warn_shared_textrel = TRUE;
          break;
+       case OPTION_WARN_ALTERNATE_EM:
+         link_info.warn_alternate_em = TRUE;
+         break;
        case OPTION_WHOLE_ARCHIVE:
          whole_archive = TRUE;
          break;
@@ -1382,10 +1429,10 @@ parse_args (unsigned argc, char **argv)
            config.split_by_file = 1;
          break;
        case OPTION_CHECK_SECTIONS:
-         command_line.check_section_addresses = TRUE;
+         command_line.check_section_addresses = 1;
          break;
        case OPTION_NO_CHECK_SECTIONS:
-         command_line.check_section_addresses = FALSE;
+         command_line.check_section_addresses = 0;
          break;
        case OPTION_ACCEPT_UNKNOWN_INPUT_ARCH:
          command_line.accept_unknown_input_arch = TRUE;
@@ -1506,7 +1553,7 @@ set_segment_start (const char *section, char *valstr)
       }
   /* There was no existing value so we must create a new segment
      entry.  */
-  seg = stat_alloc (sizeof (*seg));
+  seg = (segment_type *) stat_alloc (sizeof (*seg));
   seg->name = name;
   seg->value = val;
   seg->used = FALSE;