2012-02-15 Pedro Alves <palves@redhat.com>
[deliverable/binutils-gdb.git] / ld / lexsup.c
index 71b426a59f97a0e1e14050a301afb571adc4fcf6..20e0271e78fa3dbaa1dae2c65ee02a5bb221a676 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, 2008, 2009
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011
    Free Software Foundation, Inc.
 
    This file is part of the GNU Binutils.
@@ -40,6 +40,9 @@
 #include "ldver.h"
 #include "ldemul.h"
 #include "demangle.h"
+#ifdef ENABLE_PLUGINS
+#include "plugin.h"
+#endif /* ENABLE_PLUGINS */
 
 #ifndef PATH_SEPARATOR
 #if defined (__MSDOS__) || (defined (_WIN32) && ! defined (__CYGWIN32__))
@@ -90,6 +93,7 @@ enum option_values
   OPTION_NO_WHOLE_ARCHIVE,
   OPTION_OFORMAT,
   OPTION_RELAX,
+  OPTION_NO_RELAX,
   OPTION_RETAIN_SYMBOLS_FILE,
   OPTION_RPATH,
   OPTION_RPATH_LINK,
@@ -166,7 +170,12 @@ enum option_values
   OPTION_WARN_SHARED_TEXTREL,
   OPTION_WARN_ALTERNATE_EM,
   OPTION_REDUCE_MEMORY_OVERHEADS,
-  OPTION_DEFAULT_SCRIPT
+#ifdef ENABLE_PLUGINS
+  OPTION_PLUGIN,
+  OPTION_PLUGIN_OPT,
+#endif /* ENABLE_PLUGINS */
+  OPTION_DEFAULT_SCRIPT,
+  OPTION_PRINT_OUTPUT_FORMAT,
 };
 
 /* The long options.  This structure is used for both the option
@@ -270,6 +279,18 @@ static const struct ld_option ld_options[] =
     'o', N_("FILE"), N_("Set output file name"), EXACTLY_TWO_DASHES },
   { {NULL, required_argument, NULL, '\0'},
     'O', NULL, N_("Optimize output file"), ONE_DASH },
+#ifdef ENABLE_PLUGINS
+  { {"plugin", required_argument, NULL, OPTION_PLUGIN},
+    '\0', N_("PLUGIN"), N_("Load named plugin"), ONE_DASH },
+  { {"plugin-opt", required_argument, NULL, OPTION_PLUGIN_OPT},
+    '\0', N_("ARG"), N_("Send arg to last-loaded plugin"), ONE_DASH },
+  { {"flto", optional_argument, NULL, OPTION_IGNORE},
+    '\0', NULL, N_("Ignored for GCC LTO option compatibility"),
+    ONE_DASH },
+  { {"flto-partition=", required_argument, NULL, OPTION_IGNORE},
+    '\0', NULL, N_("Ignored for GCC LTO option compatibility"),
+    ONE_DASH },
+#endif /* ENABLE_PLUGINS */
   { {"Qy", no_argument, NULL, OPTION_IGNORE},
     '\0', NULL, N_("Ignored for SVR4 compatibility"), ONE_DASH },
   { {"emit-relocs", no_argument, NULL, 'q'},
@@ -336,8 +357,7 @@ static const struct ld_option ld_options[] =
 
   /* The next two options are deprecated because of their similarity to
      --as-needed and --no-as-needed.  They have been replaced by
-     --resolve-implicit-dynamic-symbols and
-     --no-resolve-implicit-dynamic-symbols.  */
+     --copy-dt-needed-entries and --no-copy-dt-needed-entries.  */
   { {"add-needed", no_argument, NULL, OPTION_ADD_DT_NEEDED_FOR_DYNAMIC},
     '\0', NULL, NULL, NO_HELP },
   { {"no-add-needed", no_argument, NULL, OPTION_NO_ADD_DT_NEEDED_FOR_DYNAMIC},
@@ -435,7 +455,7 @@ static const struct ld_option ld_options[] =
     '\0', NULL, N_("Do not allow unresolved references in object files"),
     TWO_DASHES },
   { {"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 libraries"),
     TWO_DASHES },
   { {"no-allow-shlib-undefined", no_argument, NULL,
      OPTION_NO_ALLOW_SHLIB_UNDEFINED},
@@ -472,6 +492,8 @@ static const struct ld_option ld_options[] =
   { {"oformat", required_argument, NULL, OPTION_OFORMAT},
     '\0', N_("TARGET"), N_("Specify target of output file"),
     EXACTLY_TWO_DASHES },
+  { {"print-output-format", no_argument, NULL, OPTION_PRINT_OUTPUT_FORMAT},
+    '\0', NULL, N_("Print default output format"), TWO_DASHES },
   { {"qmagic", no_argument, NULL, OPTION_IGNORE},
     '\0', NULL, N_("Ignored for Linux compatibility"), ONE_DASH },
   { {"reduce-memory-overheads", no_argument, NULL,
@@ -479,7 +501,9 @@ static const struct ld_option ld_options[] =
     '\0', NULL, N_("Reduce memory overheads, possibly taking much longer"),
     TWO_DASHES },
   { {"relax", no_argument, NULL, OPTION_RELAX},
-    '\0', NULL, N_("Relax branches on certain targets"), TWO_DASHES },
+    '\0', NULL, N_("Reduce code size by using target specific optimizations"), TWO_DASHES },
+  { {"no-relax", no_argument, NULL, OPTION_NO_RELAX},
+    '\0', NULL, N_("Do not use relaxation techniques to reduce code size"), TWO_DASHES },
   { {"retain-symbols-file", required_argument, NULL,
      OPTION_RETAIN_SYMBOLS_FILE},
     '\0', N_("FILE"), N_("Keep only symbols listed in FILE"), TWO_DASHES },
@@ -539,8 +563,9 @@ static const struct ld_option ld_options[] =
                   "                                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 },
+  { {"verbose", optional_argument, NULL, OPTION_VERBOSE},
+    '\0', N_("[=NUMBER]"),
+    N_("Output lots of information during link"), TWO_DASHES },
   { {"dll-verbose", no_argument, NULL, OPTION_VERBOSE}, /* Linux.  */
     '\0', NULL, NULL, NO_HELP },
   { {"version-script", required_argument, NULL, OPTION_VERSION_SCRIPT },
@@ -1037,6 +1062,20 @@ parse_args (unsigned argc, char **argv)
        case OPTION_OFORMAT:
          lang_add_output_format (optarg, NULL, NULL, 0);
          break;
+       case OPTION_PRINT_OUTPUT_FORMAT:
+         command_line.print_output_format = TRUE;
+         break;
+#ifdef ENABLE_PLUGINS
+       case OPTION_PLUGIN:
+         if (plugin_opt_plugin (optarg))
+           einfo (_("%P%F: %s: error loading plugin\n"),
+                  plugin_error_plugin ());
+         break;
+       case OPTION_PLUGIN_OPT:
+         if (plugin_opt_plugin_arg (optarg))
+           einfo(_("%P%F: bad -plugin-opt option\n"));
+         break;
+#endif /* ENABLE_PLUGINS */
        case 'q':
          link_info.emitrelocations = TRUE;
          break;
@@ -1132,8 +1171,11 @@ parse_args (unsigned argc, char **argv)
              command_line.rpath_link = buf;
            }
          break;
+       case OPTION_NO_RELAX:
+         DISABLE_RELAXATION;
+         break;
        case OPTION_RELAX:
-         command_line.relax = TRUE;
+         ENABLE_RELAXATION;
          break;
        case OPTION_RETAIN_SYMBOLS_FILE:
          add_keepsyms_file (optarg);
@@ -1278,7 +1320,7 @@ parse_args (unsigned argc, char **argv)
          config.dynamic_link = FALSE;
          break;
        case 'u':
-         ldlang_add_undef (optarg);
+         ldlang_add_undef (optarg, TRUE);
          break;
        case OPTION_UNIQUE:
          if (optarg != NULL)
@@ -1291,6 +1333,16 @@ parse_args (unsigned argc, char **argv)
          version_printed = TRUE;
          trace_file_tries = TRUE;
          overflow_cutoff_limit = -2;
+         if (optarg != NULL)
+           {
+             char *end;
+             int level ATTRIBUTE_UNUSED = strtoul (optarg, &end, 0);
+             if (*end)
+               einfo (_("%P%F: invalid number `%s'\n"), optarg);
+#ifdef ENABLE_PLUGINS
+             report_plugin_symbols = level > 1;
+#endif /* ENABLE_PLUGINS */
+           }
          break;
        case 'v':
          ldversion (0);
@@ -1453,18 +1505,15 @@ parse_args (unsigned argc, char **argv)
          command_line.accept_unknown_input_arch = FALSE;
          break;
        case '(':
-         if (ingroup)
-           einfo (_("%P%F: may not nest groups (--help for usage)\n"));
-
          lang_enter_group ();
-         ingroup = 1;
+         ingroup++;
          break;
        case ')':
          if (! ingroup)
            einfo (_("%P%F: group ended before it began (--help for usage)\n"));
 
          lang_leave_group ();
-         ingroup = 0;
+         ingroup--;
          break;
 
        case OPTION_INIT:
@@ -1495,8 +1544,11 @@ parse_args (unsigned argc, char **argv)
        }
     }
 
-  if (ingroup)
-    lang_leave_group ();
+  while (ingroup)
+    {
+      lang_leave_group ();
+      ingroup--;
+    }
 
   if (default_dirlist != NULL)
     {
@@ -1511,6 +1563,72 @@ parse_args (unsigned argc, char **argv)
   if (link_info.unresolved_syms_in_shared_libs == RM_NOT_YET_SET)
     /* FIXME: Should we allow emulations a chance to set this ?  */
     link_info.unresolved_syms_in_shared_libs = how_to_report_unresolved_symbols;
+
+  if (link_info.relocatable)
+    {
+      if (command_line.check_section_addresses < 0)
+       command_line.check_section_addresses = 0;
+      if (link_info.shared)
+       einfo (_("%P%F: -r and -shared may not be used together\n"));
+    }
+
+  /* We may have -Bsymbolic, -Bsymbolic-functions, --dynamic-list-data,
+     --dynamic-list-cpp-new, --dynamic-list-cpp-typeinfo and
+     --dynamic-list FILE.  -Bsymbolic and -Bsymbolic-functions are
+     for shared libraries.  -Bsymbolic overrides all others and vice
+     versa.  */
+  switch (command_line.symbolic)
+    {
+    case symbolic_unset:
+      break;
+    case symbolic:
+      /* -Bsymbolic is for shared library only.  */
+      if (link_info.shared)
+       {
+         link_info.symbolic = TRUE;
+         /* Should we free the unused memory?  */
+         link_info.dynamic_list = NULL;
+         command_line.dynamic_list = dynamic_list_unset;
+       }
+      break;
+    case symbolic_functions:
+      /* -Bsymbolic-functions is for shared library only.  */
+      if (link_info.shared)
+       command_line.dynamic_list = dynamic_list_data;
+      break;
+    }
+
+  switch (command_line.dynamic_list)
+    {
+    case dynamic_list_unset:
+      break;
+    case dynamic_list_data:
+      link_info.dynamic_data = TRUE;
+    case dynamic_list:
+      link_info.dynamic = TRUE;
+      break;
+    }
+
+  if (! link_info.shared)
+    {
+      if (command_line.filter_shlib)
+       einfo (_("%P%F: -F may not be used without -shared\n"));
+      if (command_line.auxiliary_filters)
+       einfo (_("%P%F: -f may not be used without -shared\n"));
+    }
+
+  if (! link_info.shared || link_info.pie)
+    link_info.executable = TRUE;
+
+  /* Treat ld -r -s as ld -r -S -x (i.e., strip all local symbols).  I
+     don't see how else this can be handled, since in this case we
+     must preserve all externally visible symbols.  */
+  if (link_info.relocatable && link_info.strip == strip_all)
+    {
+      link_info.strip = strip_debugger;
+      if (link_info.discard == discard_sec_merge)
+       link_info.discard = discard_all;
+    }
 }
 
 /* Add the (colon-separated) elements of DIRLIST_PTR to the
This page took 0.027277 seconds and 4 git commands to generate.