gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / ld / lexsup.c
index fc410c9e301be9fb545a1210f075d687e1c6927f..4808f7443d146b5409aa8fb2374f016b7408fef1 100644 (file)
@@ -1,7 +1,5 @@
 /* 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, 2011, 2012
-   Free Software Foundation, Inc.
+   Copyright (C) 1991-2020 Free Software Foundation, Inc.
 
    This file is part of the GNU Binutils.
 
@@ -29,6 +27,7 @@
 #include "safe-ctype.h"
 #include "getopt.h"
 #include "bfdlink.h"
+#include "ctf-api.h"
 #include "ld.h"
 #include "ldmain.h"
 #include "ldmisc.h"
@@ -67,9 +66,9 @@ static void help (void);
 
 enum control_enum {
   /* Use one dash before long option name.  */
-  ONE_DASH,
+  ONE_DASH = 1,
   /* Use two dashes before long option name.  */
-  TWO_DASHES,
+  TWO_DASHES = 2,
   /* 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
@@ -114,12 +113,19 @@ static const struct ld_option ld_options[] =
     'd', NULL, N_("Force common symbols to be defined"), ONE_DASH },
   { {"dp", no_argument, NULL, 'd'},
     '\0', NULL, NULL, ONE_DASH },
+  { {"force-group-allocation", no_argument, NULL,
+     OPTION_FORCE_GROUP_ALLOCATION},
+    '\0', NULL, N_("Force group members out of groups"), TWO_DASHES },
   { {"entry", required_argument, NULL, 'e'},
     '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 },
+  { {"enable-non-contiguous-regions", no_argument, NULL, OPTION_NON_CONTIGUOUS_REGIONS},
+    '\0', NULL, N_("Enable support of non-contiguous memory regions"), TWO_DASHES },
+  { {"enable-non-contiguous-regions-warnings", no_argument, NULL, OPTION_NON_CONTIGUOUS_REGIONS_WARNINGS},
+    '\0', NULL, N_("Enable warnings when --enable-non-contiguous-regions may cause unexpected behaviour"), TWO_DASHES },
   { {"EB", no_argument, NULL, OPTION_EB},
     '\0', NULL, N_("Link big-endian objects"), ONE_DASH },
   { {"EL", no_argument, NULL, OPTION_EL},
@@ -140,6 +146,9 @@ static const struct ld_option ld_options[] =
   { {"dynamic-linker", required_argument, NULL, OPTION_DYNAMIC_LINKER},
     'I', N_("PROGRAM"), N_("Set PROGRAM as the dynamic linker to use"),
     TWO_DASHES },
+  { {"no-dynamic-linker", no_argument, NULL, OPTION_NO_DYNAMIC_LINKER},
+    '\0', NULL, N_("Produce an executable with no program interpreter header"),
+    TWO_DASHES },
   { {"library", required_argument, NULL, 'l'},
     'l', N_("LIBNAME"), N_("Search for library LIBNAME"), TWO_DASHES },
   { {"library-path", required_argument, NULL, 'L'},
@@ -163,6 +172,8 @@ 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 },
+  { {"out-implib", required_argument, NULL, OPTION_OUT_IMPLIB},
+    '\0', N_("FILE"), N_("Generate import library"), TWO_DASHES },
 #ifdef ENABLE_PLUGINS
   { {"plugin", required_argument, NULL, OPTION_PLUGIN},
     '\0', N_("PLUGIN"), N_("Load named plugin"), ONE_DASH },
@@ -175,6 +186,15 @@ static const struct ld_option ld_options[] =
     '\0', NULL, N_("Ignored for GCC LTO option compatibility"),
     ONE_DASH },
 #endif /* ENABLE_PLUGINS */
+  { {"fuse-ld=", required_argument, NULL, OPTION_IGNORE},
+    '\0', NULL, N_("Ignored for GCC linker option compatibility"),
+    ONE_DASH },
+  { {"map-whole-files", optional_argument, NULL, OPTION_IGNORE},
+    '\0', NULL, N_("Ignored for gold option compatibility"),
+    TWO_DASHES },
+  { {"no-map-whole-files", optional_argument, NULL, OPTION_IGNORE},
+    '\0', NULL, N_("Ignored for gold option compatibility"),
+    TWO_DASHES },
   { {"Qy", no_argument, NULL, OPTION_IGNORE},
     '\0', NULL, N_("Ignored for SVR4 compatibility"), ONE_DASH },
   { {"emit-relocs", no_argument, NULL, 'q'},
@@ -205,6 +225,9 @@ static const struct ld_option ld_options[] =
   { {"undefined", required_argument, NULL, 'u'},
     'u', N_("SYMBOL"), N_("Start with undefined reference to SYMBOL"),
     TWO_DASHES },
+  { {"require-defined", required_argument, NULL, OPTION_REQUIRE_DEFINED_SYMBOL},
+    '\0', N_("SYMBOL"), N_("Require SYMBOL be defined in the final output"),
+    TWO_DASHES },
   { {"unique", optional_argument, NULL, OPTION_UNIQUE},
     '\0', N_("[=SECTION]"),
     N_("Don't merge input [SECTION | orphan] sections"), TWO_DASHES },
@@ -296,6 +319,11 @@ static const struct ld_option ld_options[] =
   { {"demangle", optional_argument, NULL, OPTION_DEMANGLE},
     '\0', N_("[=STYLE]"), N_("Demangle symbol names [using STYLE]"),
     TWO_DASHES },
+  { {"disable-multiple-abs-defs", no_argument, NULL,
+     OPTION_DISABLE_MULTIPLE_DEFS_ABS},
+    '\0', NULL, N_("Do not allow multiple definitions with symbols included\n"
+                  "           in filename invoked by -R or --just-symbols"),
+    TWO_DASHES},
   { {"embedded-relocs", no_argument, NULL, OPTION_EMBEDDED_RELOCS},
     '\0', NULL, N_("Generate embedded relocs"), TWO_DASHES},
   { {"fatal-warnings", no_argument, NULL, OPTION_WARN_FATAL},
@@ -320,6 +348,9 @@ static const struct ld_option ld_options[] =
   { {"no-print-gc-sections", no_argument, NULL, OPTION_NO_PRINT_GC_SECTIONS},
     '\0', NULL, N_("Do not list removed unused sections"),
     TWO_DASHES },
+  { {"gc-keep-exported", no_argument, NULL, OPTION_GC_KEEP_EXPORTED},
+    '\0', NULL, N_("Keep exported symbols when removing unused sections"),
+    TWO_DASHES },
   { {"hash-size=<NUMBER>", required_argument, NULL, OPTION_HASH_SIZE},
     '\0', NULL, N_("Set default hash table size close to <NUMBER>"),
     TWO_DASHES },
@@ -328,7 +359,7 @@ static const struct ld_option ld_options[] =
   { {"init", required_argument, NULL, OPTION_INIT},
     '\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 },
+    '\0', N_("FILE/DIR"), N_("Write a linker map to FILE or DIR/<outputname>.map"), 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 },
@@ -378,6 +409,8 @@ static const struct ld_option ld_options[] =
     EXACTLY_TWO_DASHES },
   { {"print-output-format", no_argument, NULL, OPTION_PRINT_OUTPUT_FORMAT},
     '\0', NULL, N_("Print default output format"), TWO_DASHES },
+  { {"print-sysroot", no_argument, NULL, OPTION_PRINT_SYSROOT},
+    '\0', NULL, N_("Print current sysroot"), TWO_DASHES },
   { {"qmagic", no_argument, NULL, OPTION_IGNORE},
     '\0', NULL, N_("Ignored for Linux compatibility"), ONE_DASH },
   { {"reduce-memory-overheads", no_argument, NULL,
@@ -405,13 +438,13 @@ static const struct ld_option ld_options[] =
   { {"pic-executable", no_argument, NULL, OPTION_PIE},
     '\0', NULL, NULL, TWO_DASHES },
   { {"sort-common", optional_argument, NULL, OPTION_SORT_COMMON},
-    '\0', N_("[=ascending|descending]"), 
-    N_("Sort common symbols by alignment [in specified order]"), 
+    '\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},
-    '\0', N_("name|alignment"), 
+    '\0', N_("name|alignment"),
     N_("Sort sections by name or maximum alignment"), TWO_DASHES },
   { {"spare-dynamic-tags", required_argument, NULL, OPTION_SPARE_DYNAMIC_TAGS},
     '\0', N_("COUNT"), N_("How many tags to reserve in .dynamic section"),
@@ -441,6 +474,10 @@ static const struct ld_option ld_options[] =
     '\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 },
+  { {"Trodata-segment", required_argument, NULL, OPTION_TRODATA_SEGMENT},
+    '\0', N_("ADDRESS"), N_("Set address of rodata segment"), ONE_DASH },
+  { {"Tldata-segment", required_argument, NULL, OPTION_TLDATA_SEGMENT},
+    '\0', N_("ADDRESS"), N_("Set address of ldata segment"), ONE_DASH },
   { {"unresolved-symbols=<method>", required_argument, NULL,
      OPTION_UNRESOLVED_SYMBOLS},
     '\0', NULL, N_("How to handle unresolved symbols.  <method> is:\n"
@@ -467,6 +504,10 @@ static const struct ld_option ld_options[] =
     '\0', NULL, N_("Use C++ typeinfo dynamic list"), TWO_DASHES },
   { {"dynamic-list", required_argument, NULL, OPTION_DYNAMIC_LIST},
     '\0', N_("FILE"), N_("Read dynamic list"), TWO_DASHES },
+  { {"export-dynamic-symbol", required_argument, NULL, OPTION_EXPORT_DYNAMIC_SYMBOL},
+    '\0', N_("SYMBOL"), N_("Export the specified symbol"), EXACTLY_TWO_DASHES },
+  { {"export-dynamic-symbol-list", required_argument, NULL, OPTION_EXPORT_DYNAMIC_SYMBOL_LIST},
+    '\0', N_("FILE"), N_("Read export dynamic symbol list"), EXACTLY_TWO_DASHES },
   { {"warn-common", no_argument, NULL, OPTION_WARN_COMMON},
     '\0', NULL, N_("Warn about duplicate common symbols"), TWO_DASHES },
   { {"warn-constructors", no_argument, NULL, OPTION_WARN_CONSTRUCTORS},
@@ -479,9 +520,16 @@ static const struct ld_option ld_options[] =
   { {"warn-section-align", no_argument, NULL, OPTION_WARN_SECTION_ALIGN},
     '\0', NULL, N_("Warn if start of section changes due to alignment"),
     TWO_DASHES },
-  { {"warn-shared-textrel", no_argument, NULL, OPTION_WARN_SHARED_TEXTREL},
-    '\0', NULL, N_("Warn if shared object has DT_TEXTREL"),
+  { {"warn-textrel", no_argument, NULL, OPTION_WARN_TEXTREL},
+    '\0', NULL,
+#if DEFAULT_LD_TEXTREL_CHECK_WARNING
+    N_("Warn if outpout has DT_TEXTREL (default)"),
+#else
+    N_("Warn if outpout has DT_TEXTREL"),
+#endif
     TWO_DASHES },
+  { {"warn-shared-textrel", no_argument, NULL, OPTION_WARN_TEXTREL},
+    '\0', NULL, NULL, NO_HELP },
   { {"warn-alternate-em", no_argument, NULL, OPTION_WARN_ALTERNATE_EM},
     '\0', NULL, N_("Warn if an object has alternate ELF machine code"),
     TWO_DASHES },
@@ -496,6 +544,27 @@ static const struct ld_option ld_options[] =
     TWO_DASHES },
   { {"wrap", required_argument, NULL, OPTION_WRAP},
     '\0', N_("SYMBOL"), N_("Use wrapper functions for SYMBOL"), TWO_DASHES },
+  { {"ignore-unresolved-symbol", required_argument, NULL,
+    OPTION_IGNORE_UNRESOLVED_SYMBOL},
+    '\0', N_("SYMBOL"),
+    N_("Unresolved SYMBOL will not cause an error or warning"), TWO_DASHES },
+  { {"push-state", no_argument, NULL, OPTION_PUSH_STATE},
+    '\0', NULL, N_("Push state of flags governing input file handling"),
+    TWO_DASHES },
+  { {"pop-state", no_argument, NULL, OPTION_POP_STATE},
+    '\0', NULL, N_("Pop state of flags governing input file handling"),
+    TWO_DASHES },
+  { {"print-memory-usage", no_argument, NULL, OPTION_PRINT_MEMORY_USAGE},
+    '\0', NULL, N_("Report target memory usage"), TWO_DASHES },
+  { {"orphan-handling", required_argument, NULL, OPTION_ORPHAN_HANDLING},
+    '\0', N_("=MODE"), N_("Control how orphan sections are handled."),
+    TWO_DASHES },
+  { {"print-map-discarded", no_argument, NULL, OPTION_PRINT_MAP_DISCARDED},
+    '\0', NULL, N_("Show discarded sections in map file output (default)"),
+    TWO_DASHES },
+  { {"no-print-map-discarded", no_argument, NULL, OPTION_NO_PRINT_MAP_DISCARDED},
+    '\0', NULL, N_("Do not show discarded sections in map file output"),
+    TWO_DASHES },
 };
 
 #define OPTION_COUNT ARRAY_SIZE (ld_options)
@@ -511,7 +580,19 @@ parse_args (unsigned argc, char **argv)
   struct option *longopts;
   struct option *really_longopts;
   int last_optind;
-  enum report_method how_to_report_unresolved_symbols = RM_GENERATE_ERROR;
+  enum symbolic_enum
+  {
+    symbolic_unset = 0,
+    symbolic,
+    symbolic_functions,
+  } opt_symbolic = symbolic_unset;
+  enum dynamic_list_enum
+  {
+    dynamic_list_unset = 0,
+    dynamic_list_data,
+    dynamic_list
+  } opt_dynamic_list = dynamic_list_unset;
+  struct bfd_elf_dynamic_list *export_list = NULL;
 
   shortopts = (char *) xmalloc (OPTION_COUNT * 3 + 2);
   longopts = (struct option *)
@@ -645,11 +726,33 @@ parse_args (unsigned argc, char **argv)
       switch (optc)
        {
        case '?':
-         einfo (_("%P: unrecognized option '%s'\n"), argv[last_optind]);
+         {
+           /* If the last word on the command line is an option that
+              requires an argument, getopt will refuse to recognise it.
+              Try to catch such options here and issue a more helpful
+              error message than just "unrecognized option".  */
+           int opt;
+
+           for (opt = ARRAY_SIZE (ld_options); opt--;)
+             if (ld_options[opt].opt.has_arg == required_argument
+                 /* FIXME: There are a few short options that do not
+                    have long equivalents, but which require arguments.
+                    We should handle them too.  */
+                 && ld_options[opt].opt.name != NULL
+                 && strcmp (argv[last_optind] + ld_options[opt].control, ld_options[opt].opt.name) == 0)
+               {
+                 einfo (_("%P: %s: missing argument\n"), argv[last_optind]);
+                 break;
+               }
+
+           if (opt == -1)
+             einfo (_("%P: unrecognized option '%s'\n"), argv[last_optind]);
+         }
          /* Fall through.  */
 
        default:
-         einfo (_("%P%F: use the --help option for usage information\n"));
+         einfo (_("%F%P: use the --help option for usage information\n"));
+         break;
 
        case 1:                 /* File name.  */
          lang_add_input_file (optarg, lang_input_file_is_file_enum, NULL);
@@ -667,7 +770,7 @@ parse_args (unsigned argc, char **argv)
                   || strcmp (optarg, "default") == 0)
            input_flags.dynamic = TRUE;
          else
-           einfo (_("%P%F: unrecognized -a option `%s'\n"), optarg);
+           einfo (_("%F%P: unrecognized -a option `%s'\n"), optarg);
          break;
        case OPTION_ASSERT:
          /* FIXME: We just ignore these, but we should handle them.  */
@@ -680,7 +783,7 @@ parse_args (unsigned argc, char **argv)
          else if (strcmp (optarg, "pure-text") == 0)
            ;
          else
-           einfo (_("%P%F: unrecognized -assert option `%s'\n"), optarg);
+           einfo (_("%F%P: unrecognized -assert option `%s'\n"), optarg);
          break;
        case 'A':
          ldfile_add_arch (optarg);
@@ -706,6 +809,9 @@ parse_args (unsigned argc, char **argv)
        case 'd':
          command_line.force_common_definition = TRUE;
          break;
+       case OPTION_FORCE_GROUP_ALLOCATION:
+         command_line.force_group_allocation = TRUE;
+         break;
        case OPTION_DEFSYM:
          lex_string = optarg;
          lex_redirect (optarg, "--defsym", ++defsym_count);
@@ -730,6 +836,10 @@ parse_args (unsigned argc, char **argv)
        case 'I':               /* Used on Solaris.  */
        case OPTION_DYNAMIC_LINKER:
          command_line.interpreter = optarg;
+         link_info.nointerp = 0;
+         break;
+       case OPTION_NO_DYNAMIC_LINKER:
+         link_info.nointerp = 1;
          break;
        case OPTION_SYSROOT:
          /* Already handled in ldmain.c.  */
@@ -750,6 +860,12 @@ parse_args (unsigned argc, char **argv)
        case OPTION_NO_EXPORT_DYNAMIC:
          link_info.export_dynamic = FALSE;
          break;
+       case OPTION_NON_CONTIGUOUS_REGIONS:
+         link_info.non_contiguous_regions = TRUE;
+         break;
+       case OPTION_NON_CONTIGUOUS_REGIONS_WARNINGS:
+         link_info.non_contiguous_regions_warnings = TRUE;
+         break;
        case 'e':
          lang_add_entry (optarg, TRUE);
          break;
@@ -757,7 +873,7 @@ parse_args (unsigned argc, char **argv)
          if (command_line.auxiliary_filters == NULL)
            {
              command_line.auxiliary_filters = (char **)
-                  xmalloc (2 * sizeof (char *));
+               xmalloc (2 * sizeof (char *));
              command_line.auxiliary_filters[0] = optarg;
              command_line.auxiliary_filters[1] = NULL;
            }
@@ -770,8 +886,8 @@ parse_args (unsigned argc, char **argv)
              for (p = command_line.auxiliary_filters; *p != NULL; p++)
                ++c;
              command_line.auxiliary_filters = (char **)
-                  xrealloc (command_line.auxiliary_filters,
-                           (c + 2) * sizeof (char *));
+               xrealloc (command_line.auxiliary_filters,
+                         (c + 2) * sizeof (char *));
              command_line.auxiliary_filters[c] = optarg;
              command_line.auxiliary_filters[c + 1] = NULL;
            }
@@ -787,7 +903,7 @@ parse_args (unsigned argc, char **argv)
            char *end;
            g_switch_value = strtoul (optarg, &end, 0);
            if (*end)
-             einfo (_("%P%F: invalid number `%s'\n"), optarg);
+             einfo (_("%F%P: invalid number `%s'\n"), optarg);
          }
          break;
        case 'g':
@@ -799,6 +915,9 @@ parse_args (unsigned argc, char **argv)
        case OPTION_PRINT_GC_SECTIONS:
          link_info.print_gc_sections = TRUE;
          break;
+       case OPTION_GC_KEEP_EXPORTED:
+         link_info.gc_keep_exported = TRUE;
+         break;
        case OPTION_HELP:
          help ();
          xexit (0);
@@ -830,11 +949,12 @@ parse_args (unsigned argc, char **argv)
             Use --call-shared or -Bdynamic for this.  */
          break;
        case 'n':
+         config.text_read_only = TRUE;
          config.magic_demand_paged = FALSE;
          input_flags.dynamic = FALSE;
          break;
        case OPTION_NO_DEFINE_COMMON:
-         command_line.inhibit_common_definition = TRUE;
+         link_info.inhibit_common_definition = TRUE;
          break;
        case OPTION_NO_DEMANGLE:
          demangling = FALSE;
@@ -849,15 +969,13 @@ parse_args (unsigned argc, char **argv)
          link_info.keep_memory = FALSE;
          break;
        case OPTION_NO_UNDEFINED:
-         link_info.unresolved_syms_in_objects
-           = how_to_report_unresolved_symbols;
+         link_info.unresolved_syms_in_objects = RM_DIAGNOSE;
          break;
        case OPTION_ALLOW_SHLIB_UNDEFINED:
          link_info.unresolved_syms_in_shared_libs = RM_IGNORE;
          break;
        case OPTION_NO_ALLOW_SHLIB_UNDEFINED:
-         link_info.unresolved_syms_in_shared_libs
-           = how_to_report_unresolved_symbols;
+         link_info.unresolved_syms_in_shared_libs = RM_DIAGNOSE;
          break;
        case OPTION_UNRESOLVED_SYMBOLS:
          if (strcmp (optarg, "ignore-all") == 0)
@@ -867,40 +985,27 @@ parse_args (unsigned argc, char **argv)
            }
          else if (strcmp (optarg, "report-all") == 0)
            {
-             link_info.unresolved_syms_in_objects
-               = how_to_report_unresolved_symbols;
-             link_info.unresolved_syms_in_shared_libs
-               = how_to_report_unresolved_symbols;
+             link_info.unresolved_syms_in_objects = RM_DIAGNOSE;
+             link_info.unresolved_syms_in_shared_libs = RM_DIAGNOSE;
            }
          else if (strcmp (optarg, "ignore-in-object-files") == 0)
            {
              link_info.unresolved_syms_in_objects = RM_IGNORE;
-             link_info.unresolved_syms_in_shared_libs
-               = how_to_report_unresolved_symbols;
+             link_info.unresolved_syms_in_shared_libs = RM_DIAGNOSE;
            }
-         else if (strcmp (optarg, "ignore-in-shared-libs") == 0)
+         else if (strcmp (optarg, "ignore-in-shared-libs") == 0)
            {
-             link_info.unresolved_syms_in_objects
-               = how_to_report_unresolved_symbols;
+             link_info.unresolved_syms_in_objects = RM_DIAGNOSE;
              link_info.unresolved_syms_in_shared_libs = RM_IGNORE;
            }
          else
-           einfo (_("%P%F: bad --unresolved-symbols option: %s\n"), optarg);
+           einfo (_("%F%P: bad --unresolved-symbols option: %s\n"), optarg);
          break;
        case OPTION_WARN_UNRESOLVED_SYMBOLS:
-         how_to_report_unresolved_symbols = RM_GENERATE_WARNING;
-         if (link_info.unresolved_syms_in_objects == RM_GENERATE_ERROR)
-           link_info.unresolved_syms_in_objects = RM_GENERATE_WARNING;
-         if (link_info.unresolved_syms_in_shared_libs == RM_GENERATE_ERROR)
-           link_info.unresolved_syms_in_shared_libs = RM_GENERATE_WARNING;
+         link_info.warn_unresolved_syms = TRUE;
          break;
-
        case OPTION_ERROR_UNRESOLVED_SYMBOLS:
-         how_to_report_unresolved_symbols = RM_GENERATE_ERROR;
-         if (link_info.unresolved_syms_in_objects == RM_GENERATE_WARNING)
-           link_info.unresolved_syms_in_objects = RM_GENERATE_ERROR;
-         if (link_info.unresolved_syms_in_shared_libs == RM_GENERATE_WARNING)
-           link_info.unresolved_syms_in_shared_libs = RM_GENERATE_ERROR;
+         link_info.warn_unresolved_syms = FALSE;
          break;
        case OPTION_ALLOW_MULTIPLE_DEFINITION:
          link_info.allow_multiple_definition = TRUE;
@@ -945,18 +1050,24 @@ parse_args (unsigned argc, char **argv)
        case OPTION_OFORMAT:
          lang_add_output_format (optarg, NULL, NULL, 0);
          break;
+       case OPTION_OUT_IMPLIB:
+         command_line.out_implib_filename = xstrdup (optarg);
+         break;
+       case OPTION_PRINT_SYSROOT:
+         if (*ld_sysroot)
+           puts (ld_sysroot);
+         xexit (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 ());
+         plugin_opt_plugin (optarg);
          break;
        case OPTION_PLUGIN_OPT:
          if (plugin_opt_plugin_arg (optarg))
-           einfo(_("%P%F: bad -plugin-opt option\n"));
+           einfo (_("%F%P: bad -plugin-opt option\n"));
          break;
 #endif /* ENABLE_PLUGINS */
        case 'q':
@@ -973,9 +1084,13 @@ parse_args (unsigned argc, char **argv)
               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"));
+           einfo(_("%F%P: unrecognised option: %s\n"), argv[optind]);
 
-         link_info.relocatable = TRUE;
+         if (bfd_link_pic (&link_info))
+           einfo (_("%F%P: -r and %s may not be used together\n"),
+                    bfd_link_dll (&link_info) ? "-shared" : "-pie");
+
+         link_info.type = type_relocatable;
          config.build_constructors = FALSE;
          config.magic_demand_paged = FALSE;
          config.text_read_only = FALSE;
@@ -1046,8 +1161,8 @@ parse_args (unsigned argc, char **argv)
              char *buf;
 
              buf = (char *) xmalloc (strlen (command_line.rpath_link)
-                                      + strlen (optarg)
-                                      + 2);
+                                     + strlen (optarg)
+                                     + 2);
              sprintf (buf, "%s%c%s", command_line.rpath_link,
                       config.rpath_separator, optarg);
              free (command_line.rpath_link);
@@ -1075,10 +1190,17 @@ parse_args (unsigned argc, char **argv)
        case OPTION_NO_STRIP_DISCARDED:
          link_info.strip_discarded = FALSE;
          break;
+       case OPTION_DISABLE_MULTIPLE_DEFS_ABS:
+         link_info.prohibit_multiple_definition_absolute = TRUE;
+         break;
        case OPTION_SHARED:
          if (config.has_shared)
            {
-             link_info.shared = TRUE;
+             if (bfd_link_relocatable (&link_info))
+               einfo (_("%F%P: -r and %s may not be used together\n"),
+                      "-shared");
+
+             link_info.type = type_dll;
              /* When creating a shared library, the default
                 behaviour is to ignore any unresolved references.  */
              if (link_info.unresolved_syms_in_objects == RM_NOT_YET_SET)
@@ -1087,29 +1209,35 @@ parse_args (unsigned argc, char **argv)
                link_info.unresolved_syms_in_shared_libs = RM_IGNORE;
            }
          else
-           einfo (_("%P%F: -shared not supported\n"));
+           einfo (_("%F%P: -shared not supported\n"));
          break;
        case OPTION_PIE:
          if (config.has_shared)
            {
-             link_info.shared = TRUE;
-             link_info.pie = TRUE;
+             if (bfd_link_relocatable (&link_info))
+               einfo (_("%F%P: -r and %s may not be used together\n"), "-pie");
+
+             link_info.type = type_pie;
            }
          else
-           einfo (_("%P%F: -pie not supported\n"));
+           einfo (_("%F%P: -pie not supported\n"));
          break;
        case 'h':               /* Used on Solaris.  */
        case OPTION_SONAME:
-         command_line.soname = optarg;
+         if (optarg[0] == '\0' && command_line.soname
+             && command_line.soname[0])
+           einfo (_("%P: SONAME must not be empty string; keeping previous one\n"));
+         else
+           command_line.soname = optarg;
          break;
        case OPTION_SORT_COMMON:
          if (optarg == NULL
              || strcmp (optarg, N_("descending")) == 0)
-            config.sort_common = sort_descending;
-          else if (strcmp (optarg, N_("ascending")) == 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"),
+           einfo (_("%F%P: invalid common section sorting option: %s\n"),
                   optarg);
          break;
        case OPTION_SORT_SECTION:
@@ -1118,24 +1246,24 @@ parse_args (unsigned argc, char **argv)
          else if (strcmp (optarg, N_("alignment")) == 0)
            sort_section = by_alignment;
          else
-           einfo (_("%P%F: invalid section sorting option: %s\n"),
+           einfo (_("%F%P: invalid section sorting option: %s\n"),
                   optarg);
          break;
        case OPTION_STATS:
          config.stats = TRUE;
          break;
        case OPTION_SYMBOLIC:
-         command_line.symbolic = symbolic;
+         opt_symbolic = symbolic;
          break;
        case OPTION_SYMBOLIC_FUNCTIONS:
-         command_line.symbolic = symbolic_functions;
+         opt_symbolic = symbolic_functions;
          break;
        case 't':
-         trace_files = TRUE;
+         ++trace_files;
          break;
        case 'T':
          previous_script_handle = saved_script_handle;
-         ldfile_open_command_file (optarg);
+         ldfile_open_script_file (optarg);
          parser_input = input_script;
          yyparse ();
          previous_script_handle = NULL;
@@ -1152,14 +1280,14 @@ parse_args (unsigned argc, char **argv)
            /* Check for <something>=<somthing>...  */
            optarg2 = strchr (optarg, '=');
            if (optarg2 == NULL)
-             einfo (_("%P%F: invalid argument to option"
+             einfo (_("%F%P: invalid argument to option"
                       " \"--section-start\"\n"));
 
            optarg2++;
 
            /* So far so good.  Are all the args present?  */
            if ((*optarg == '\0') || (*optarg2 == '\0'))
-             einfo (_("%P%F: missing argument(s) to option"
+             einfo (_("%F%P: missing argument(s) to option"
                       " \"--section-start\"\n"));
 
            /* We must copy the section name as set_section_start
@@ -1189,14 +1317,24 @@ parse_args (unsigned argc, char **argv)
        case OPTION_TTEXT_SEGMENT:
          set_segment_start (".text-segment", optarg);
          break;
+       case OPTION_TRODATA_SEGMENT:
+         set_segment_start (".rodata-segment", optarg);
+         break;
+       case OPTION_TLDATA_SEGMENT:
+         set_segment_start (".ldata-segment", optarg);
+         break;
        case OPTION_TRADITIONAL_FORMAT:
          link_info.traditional_format = TRUE;
          break;
        case OPTION_TASK_LINK:
          link_info.task_link = TRUE;
-         /* Fall through - do an implied -r option.  */
+         /* Fall through.  */
        case OPTION_UR:
-         link_info.relocatable = TRUE;
+         if (bfd_link_pic (&link_info))
+           einfo (_("%F%P: -r and %s may not be used together\n"),
+                    bfd_link_dll (&link_info) ? "-shared" : "-pie");
+
+         link_info.type = type_relocatable;
          config.build_constructors = TRUE;
          config.magic_demand_paged = FALSE;
          config.text_read_only = FALSE;
@@ -1205,6 +1343,9 @@ parse_args (unsigned argc, char **argv)
        case 'u':
          ldlang_add_undef (optarg, TRUE);
          break;
+       case OPTION_REQUIRE_DEFINED_SYMBOL:
+         ldlang_add_require_defined (optarg);
+         break;
        case OPTION_UNIQUE:
          if (optarg != NULL)
            lang_add_unique (optarg);
@@ -1221,7 +1362,7 @@ parse_args (unsigned argc, char **argv)
              char *end;
              int level ATTRIBUTE_UNUSED = strtoul (optarg, &end, 0);
              if (*end)
-               einfo (_("%P%F: invalid number `%s'\n"), optarg);
+               einfo (_("%F%P: invalid number `%s'\n"), optarg);
 #ifdef ENABLE_PLUGINS
              report_plugin_symbols = level > 1;
 #endif /* ENABLE_PLUGINS */
@@ -1260,23 +1401,17 @@ parse_args (unsigned argc, char **argv)
          command_line.version_exports_section = optarg;
          break;
        case OPTION_DYNAMIC_LIST_DATA:
-         command_line.dynamic_list = dynamic_list_data;
-         if (command_line.symbolic == symbolic)
-           command_line.symbolic = symbolic_unset;
+         opt_dynamic_list = dynamic_list_data;
          break;
        case OPTION_DYNAMIC_LIST_CPP_TYPEINFO:
          lang_append_dynamic_list_cpp_typeinfo ();
-         if (command_line.dynamic_list != dynamic_list_data)
-           command_line.dynamic_list = dynamic_list;
-         if (command_line.symbolic == symbolic)
-           command_line.symbolic = symbolic_unset;
+         if (opt_dynamic_list != dynamic_list_data)
+           opt_dynamic_list = dynamic_list;
          break;
        case OPTION_DYNAMIC_LIST_CPP_NEW:
          lang_append_dynamic_list_cpp_new ();
-         if (command_line.dynamic_list != dynamic_list_data)
-           command_line.dynamic_list = dynamic_list;
-         if (command_line.symbolic == symbolic)
-           command_line.symbolic = symbolic_unset;
+         if (opt_dynamic_list != dynamic_list_data)
+           opt_dynamic_list = dynamic_list;
          break;
        case OPTION_DYNAMIC_LIST:
          /* This option indicates a small script that only specifies
@@ -1289,12 +1424,34 @@ parse_args (unsigned argc, char **argv)
            ldfile_open_command_file (optarg);
            saved_script_handle = hold_script_handle;
            parser_input = input_dynamic_list;
+           current_dynamic_list_p = &link_info.dynamic_list;
+           yyparse ();
+         }
+         if (opt_dynamic_list != dynamic_list_data)
+           opt_dynamic_list = dynamic_list;
+         break;
+       case OPTION_EXPORT_DYNAMIC_SYMBOL:
+         {
+           struct bfd_elf_version_expr *expr
+             = lang_new_vers_pattern (NULL, xstrdup (optarg), NULL,
+                                      FALSE);
+           lang_append_dynamic_list (&export_list, expr);
+          }
+         break;
+       case OPTION_EXPORT_DYNAMIC_SYMBOL_LIST:
+         /* This option indicates a small script that only specifies
+            an export list.  Read it, but don't assume that we've
+            seen a linker script.  */
+         {
+           FILE *hold_script_handle;
+
+           hold_script_handle = saved_script_handle;
+           ldfile_open_command_file (optarg);
+           saved_script_handle = hold_script_handle;
+           parser_input = input_dynamic_list;
+           current_dynamic_list_p = &export_list;
            yyparse ();
          }
-         if (command_line.dynamic_list != dynamic_list_data)
-           command_line.dynamic_list = dynamic_list;
-         if (command_line.symbolic == symbolic)
-           command_line.symbolic = symbolic_unset;
          break;
        case OPTION_WARN_COMMON:
          config.warn_common = TRUE;
@@ -1317,8 +1474,8 @@ parse_args (unsigned argc, char **argv)
        case OPTION_WARN_SECTION_ALIGN:
          config.warn_section_align = TRUE;
          break;
-       case OPTION_WARN_SHARED_TEXTREL:
-         link_info.warn_shared_textrel = TRUE;
+       case OPTION_WARN_TEXTREL:
+         link_info.textrel_check = textrel_check_warning;
          break;
        case OPTION_WARN_ALTERNATE_EM:
          link_info.warn_alternate_em = TRUE;
@@ -1341,6 +1498,9 @@ parse_args (unsigned argc, char **argv)
        case OPTION_WRAP:
          add_wrap (optarg);
          break;
+       case OPTION_IGNORE_UNRESOLVED_SYMBOL:
+         add_ignoresym (&link_info, optarg);
+         break;
        case OPTION_DISCARD_NONE:
          link_info.discard = discard_none;
          break;
@@ -1353,8 +1513,7 @@ parse_args (unsigned argc, char **argv)
        case 'Y':
          if (CONST_STRNEQ (optarg, "P,"))
            optarg += 2;
-         if (default_dirlist != NULL)
-           free (default_dirlist);
+         free (default_dirlist);
          default_dirlist = xstrdup (optarg);
          break;
        case 'y':
@@ -1393,7 +1552,7 @@ parse_args (unsigned argc, char **argv)
          break;
        case ')':
          if (! ingroup)
-           einfo (_("%P%F: group ended before it began (--help for usage)\n"));
+           einfo (_("%F%P: group ended before it began (--help for usage)\n"));
 
          lang_leave_group ();
          ingroup--;
@@ -1413,22 +1572,107 @@ parse_args (unsigned argc, char **argv)
            config.hash_table_size = 1021;
          break;
 
-        case OPTION_HASH_SIZE:
+       case OPTION_HASH_SIZE:
          {
            bfd_size_type new_size;
 
-            new_size = strtoul (optarg, NULL, 0);
-            if (new_size)
-              config.hash_table_size = new_size;
-            else
-              einfo (_("%P%X: --hash-size needs a numeric argument\n"));
-          }
-          break;
+           new_size = strtoul (optarg, NULL, 0);
+           if (new_size)
+             config.hash_table_size = new_size;
+           else
+             einfo (_("%X%P: --hash-size needs a numeric argument\n"));
+         }
+         break;
+
+       case OPTION_PUSH_STATE:
+         input_flags.pushed = xmemdup (&input_flags,
+                                       sizeof (input_flags),
+                                       sizeof (input_flags));
+         break;
+
+       case OPTION_POP_STATE:
+         if (input_flags.pushed == NULL)
+           einfo (_("%F%P: no state pushed before popping\n"));
+         else
+           {
+             struct lang_input_statement_flags *oldp = input_flags.pushed;
+             memcpy (&input_flags, oldp, sizeof (input_flags));
+             free (oldp);
+           }
+         break;
+
+       case OPTION_PRINT_MEMORY_USAGE:
+         command_line.print_memory_usage = TRUE;
+         break;
+
+       case OPTION_ORPHAN_HANDLING:
+         if (strcasecmp (optarg, "place") == 0)
+           config.orphan_handling = orphan_handling_place;
+         else if (strcasecmp (optarg, "warn") == 0)
+           config.orphan_handling = orphan_handling_warn;
+         else if (strcasecmp (optarg, "error") == 0)
+           config.orphan_handling = orphan_handling_error;
+         else if (strcasecmp (optarg, "discard") == 0)
+           config.orphan_handling = orphan_handling_discard;
+         else
+           einfo (_("%F%P: invalid argument to option"
+                    " \"--orphan-handling\"\n"));
+         break;
+
+       case OPTION_NO_PRINT_MAP_DISCARDED:
+         config.print_map_discarded = FALSE;
+         break;
+
+       case OPTION_PRINT_MAP_DISCARDED:
+         config.print_map_discarded = TRUE;
+         break;
        }
     }
 
+  /* Run a couple of checks on the map filename.  */
+  if (config.map_filename)
+    {
+      if (config.map_filename[0] == 0)
+       {
+         einfo (_("%P: no file/directory name provided for map output; ignored\n"));
+         config.map_filename = NULL;
+       }
+      else
+       {
+         struct stat s;
+
+         /* If the map filename is actually a directory then create
+            a file inside it, based upon the output filename.  */
+         if (stat (config.map_filename, &s) >= 0
+             && S_ISDIR (s.st_mode))
+           {
+             char * new_name;
+
+             /* FIXME: This is a (trivial) memory leak.  */
+             if (asprintf (&new_name, "%s/%s.map",
+                           config.map_filename, output_filename) < 0)
+               {
+                 /* If this alloc fails then something is probably very
+                    wrong.  Better to halt now rather than continue on
+                    into more problems.  */
+                 einfo (_("%P%F: cannot create name for linker map file: %E\n"));
+                 new_name = NULL;
+               }
+
+             config.map_filename = new_name;
+           }
+       }
+    }
+
+  if (command_line.soname && command_line.soname[0] == '\0')
+    {
+      einfo (_("%P: SONAME must not be empty string; ignored\n"));
+      command_line.soname = NULL;
+    }
+
   while (ingroup)
     {
+      einfo (_("%P: missing --end-group; added as last command line option\n"));
       lang_leave_group ();
       ingroup--;
     }
@@ -1441,72 +1685,110 @@ parse_args (unsigned argc, char **argv)
 
   if (link_info.unresolved_syms_in_objects == RM_NOT_YET_SET)
     /* 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 = RM_DIAGNOSE;
 
   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;
+    link_info.unresolved_syms_in_shared_libs = RM_DIAGNOSE;
 
-  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"));
-    }
+  if (bfd_link_relocatable (&link_info)
+      && command_line.check_section_addresses < 0)
+    command_line.check_section_addresses = 0;
 
-  /* 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)
+  if (export_list)
     {
-    case symbolic_unset:
-      break;
-    case symbolic:
-      /* -Bsymbolic is for shared library only.  */
-      if (link_info.shared)
+      struct bfd_elf_version_expr *head = export_list->head.list;
+      struct bfd_elf_version_expr *next;
+
+      /* For --export-dynamic-symbol[-list]:
+        1. When building executable, treat like --dynamic-list.
+        2. When building shared object:
+           a. If -Bsymbolic or --dynamic-list are used, treat like
+              --dynamic-list.
+           b. Otherwise, ignored.
+       */
+      if (!bfd_link_relocatable (&link_info)
+         && (bfd_link_executable (&link_info)
+             || opt_symbolic != symbolic_unset
+             || opt_dynamic_list != dynamic_list_unset))
        {
-         link_info.symbolic = TRUE;
-         /* Should we free the unused memory?  */
-         link_info.dynamic_list = NULL;
-         command_line.dynamic_list = dynamic_list_unset;
+         /* Append the export list to link_info.dynamic_list.  */
+         if (link_info.dynamic_list)
+           {
+             for (next = head; next->next != NULL; next = next->next)
+               ;
+             next->next = link_info.dynamic_list->head.list;
+             link_info.dynamic_list->head.list = head;
+           }
+         else
+           link_info.dynamic_list = export_list;
+
+         if (opt_dynamic_list != dynamic_list_data)
+           opt_dynamic_list = dynamic_list;
+       }
+      else
+       {
+         /* Free the export list.  */
+         for (; head->next != NULL; head = next)
+           {
+             next = head->next;
+             free (head);
+           }
+         free (export_list);
        }
-      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)
+  switch (opt_dynamic_list)
     {
     case dynamic_list_unset:
       break;
     case dynamic_list_data:
       link_info.dynamic_data = TRUE;
+      /* Fall through.  */
     case dynamic_list:
       link_info.dynamic = TRUE;
+      opt_symbolic = symbolic_unset;
       break;
     }
 
-  if (! link_info.shared)
+  /* -Bsymbolic and -Bsymbols-functions are for shared library output.  */
+  if (bfd_link_dll (&link_info))
+    switch (opt_symbolic)
+      {
+      case symbolic_unset:
+       break;
+      case symbolic:
+       link_info.symbolic = TRUE;
+       if (link_info.dynamic_list)
+         {
+           struct bfd_elf_version_expr *ent, *next;
+           for (ent = link_info.dynamic_list->head.list; ent; ent = next)
+             {
+               next = ent->next;
+               free (ent);
+             }
+           free (link_info.dynamic_list);
+           link_info.dynamic_list = NULL;
+         }
+       break;
+      case symbolic_functions:
+       link_info.dynamic = TRUE;
+       link_info.dynamic_data = TRUE;
+       break;
+      }
+
+  if (!bfd_link_dll (&link_info))
     {
       if (command_line.filter_shlib)
-       einfo (_("%P%F: -F may not be used without -shared\n"));
+       einfo (_("%F%P: -F may not be used without -shared\n"));
       if (command_line.auxiliary_filters)
-       einfo (_("%P%F: -f may not be used without -shared\n"));
+       einfo (_("%F%P: -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)
+  if (bfd_link_relocatable (&link_info) && link_info.strip == strip_all)
     {
       link_info.strip = strip_debugger;
       if (link_info.discard == discard_sec_merge)
@@ -1541,7 +1823,7 @@ set_section_start (char *sect, char *valstr)
   const char *end;
   bfd_vma val = bfd_scan_vma (valstr, &end, 16);
   if (*end)
-    einfo (_("%P%F: invalid hex number `%s'\n"), valstr);
+    einfo (_("%F%P: invalid hex number `%s'\n"), valstr);
   lang_section_start (sect, exp_intop (val), NULL);
 }
 
@@ -1554,7 +1836,7 @@ set_segment_start (const char *section, char *valstr)
 
   bfd_vma val = bfd_scan_vma (valstr, &end, 16);
   if (*end)
-    einfo (_("%P%F: invalid hex number `%s'\n"), valstr);
+    einfo (_("%F%P: invalid hex number `%s'\n"), valstr);
   /* If we already have an entry for this segment, update the existing
      value.  */
   name = section + 1;
@@ -1562,11 +1844,12 @@ set_segment_start (const char *section, char *valstr)
     if (strcmp (seg->name, name) == 0)
       {
        seg->value = val;
+       lang_section_start (section, exp_intop (val), seg);
        return;
       }
   /* There was no existing value so we must create a new segment
      entry.  */
-  seg = (segment_type *) stat_alloc (sizeof (*seg));
+  seg = stat_alloc (sizeof (*seg));
   seg->name = name;
   seg->value = val;
   seg->used = FALSE;
@@ -1580,6 +1863,180 @@ set_segment_start (const char *section, char *valstr)
   lang_section_start (section, exp_intop (val), seg);
 }
 
+static void
+elf_shlib_list_options (FILE *file)
+{
+  fprintf (file, _("\
+  --audit=AUDITLIB            Specify a library to use for auditing\n"));
+  fprintf (file, _("\
+  -Bgroup                     Selects group name lookup rules for DSO\n"));
+  fprintf (file, _("\
+  --disable-new-dtags         Disable new dynamic tags\n"));
+  fprintf (file, _("\
+  --enable-new-dtags          Enable new dynamic tags\n"));
+  fprintf (file, _("\
+  --eh-frame-hdr              Create .eh_frame_hdr section\n"));
+  fprintf (file, _("\
+  --no-eh-frame-hdr           Do not create .eh_frame_hdr section\n"));
+  fprintf (file, _("\
+  --exclude-libs=LIBS         Make all symbols in LIBS hidden\n"));
+  fprintf (file, _("\
+  --hash-style=STYLE          Set hash style to sysv/gnu/both.  Default: "));
+  if (DEFAULT_EMIT_SYSV_HASH)
+    {
+      /* Note - these strings are not translated as
+        they are keywords not descriptive text.  */
+      if (DEFAULT_EMIT_GNU_HASH)
+       fprintf (file, "both\n");
+      else
+       fprintf (file, "sysv\n");
+    }
+  else
+    {
+      if (DEFAULT_EMIT_GNU_HASH)
+       fprintf (file, "gnu\n");
+      else
+       /* FIXME: Can this happen ?  */
+       fprintf (file, "none\n");
+    }
+  fprintf (file, _("\
+  -P AUDITLIB, --depaudit=AUDITLIB\n" "\
+                              Specify a library to use for auditing dependencies\n"));
+  fprintf (file, _("\
+  -z combreloc                Merge dynamic relocs into one section and sort\n"));
+  fprintf (file, _("\
+  -z nocombreloc              Don't merge dynamic relocs into one section\n"));
+  fprintf (file, _("\
+  -z global                   Make symbols in DSO available for subsequently\n\
+                               loaded objects\n"));
+  fprintf (file, _("\
+  -z initfirst                Mark DSO to be initialized first at runtime\n"));
+  fprintf (file, _("\
+  -z interpose                Mark object to interpose all DSOs but executable\n"));
+  fprintf (file, _("\
+  -z lazy                     Mark object lazy runtime binding (default)\n"));
+  fprintf (file, _("\
+  -z loadfltr                 Mark object requiring immediate process\n"));
+  fprintf (file, _("\
+  -z nocopyreloc              Don't create copy relocs\n"));
+  fprintf (file, _("\
+  -z nodefaultlib             Mark object not to use default search paths\n"));
+  fprintf (file, _("\
+  -z nodelete                 Mark DSO non-deletable at runtime\n"));
+  fprintf (file, _("\
+  -z nodlopen                 Mark DSO not available to dlopen\n"));
+  fprintf (file, _("\
+  -z nodump                   Mark DSO not available to dldump\n"));
+  fprintf (file, _("\
+  -z now                      Mark object non-lazy runtime binding\n"));
+  fprintf (file, _("\
+  -z origin                   Mark object requiring immediate $ORIGIN\n\
+                                processing at runtime\n"));
+#if DEFAULT_LD_Z_RELRO
+  fprintf (file, _("\
+  -z relro                    Create RELRO program header (default)\n"));
+  fprintf (file, _("\
+  -z norelro                  Don't create RELRO program header\n"));
+#else
+  fprintf (file, _("\
+  -z relro                    Create RELRO program header\n"));
+  fprintf (file, _("\
+  -z norelro                  Don't create RELRO program header (default)\n"));
+#endif
+#if DEFAULT_LD_Z_SEPARATE_CODE
+  fprintf (file, _("\
+  -z separate-code            Create separate code program header (default)\n"));
+  fprintf (file, _("\
+  -z noseparate-code          Don't create separate code program header\n"));
+#else
+  fprintf (file, _("\
+  -z separate-code            Create separate code program header\n"));
+  fprintf (file, _("\
+  -z noseparate-code          Don't create separate code program header (default)\n"));
+#endif
+  fprintf (file, _("\
+  -z common                   Generate common symbols with STT_COMMON type\n"));
+  fprintf (file, _("\
+  -z nocommon                 Generate common symbols with STT_OBJECT type\n"));
+  fprintf (file, _("\
+  -z stack-size=SIZE          Set size of stack segment\n"));
+  if (link_info.textrel_check == textrel_check_error)
+    fprintf (file, _("\
+  -z text                     Treat DT_TEXTREL in output as error (default)\n"));
+  else
+    fprintf (file, _("\
+  -z text                     Treat DT_TEXTREL in output as error\n"));
+  if (link_info.textrel_check == textrel_check_none)
+    {
+      fprintf (file, _("\
+  -z notext                   Don't treat DT_TEXTREL in output as error (default)\n"));
+      fprintf (file, _("\
+  -z textoff                  Don't treat DT_TEXTREL in output as error (default)\n"));
+    }
+  else
+    {
+      fprintf (file, _("\
+  -z notext                   Don't treat DT_TEXTREL in output as error\n"));
+      fprintf (file, _("\
+  -z textoff                  Don't treat DT_TEXTREL in output as error\n"));
+    }
+}
+
+static void
+elf_static_list_options (FILE *file)
+{
+  fprintf (file, _("\
+  --build-id[=STYLE]          Generate build ID note\n"));
+  fprintf (file, _("\
+  --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi]\n\
+                              Compress DWARF debug sections using zlib\n"));
+#ifdef DEFAULT_FLAG_COMPRESS_DEBUG
+  fprintf (file, _("\
+                               Default: zlib-gabi\n"));
+#else
+  fprintf (file, _("\
+                               Default: none\n"));
+#endif
+  fprintf (file, _("\
+  -z common-page-size=SIZE    Set common page size to SIZE\n"));
+  fprintf (file, _("\
+  -z max-page-size=SIZE       Set maximum page size to SIZE\n"));
+  fprintf (file, _("\
+  -z defs                     Report unresolved symbols in object files\n"));
+  fprintf (file, _("\
+  -z muldefs                  Allow multiple definitions\n"));
+  fprintf (file, _("\
+  -z execstack                Mark executable as requiring executable stack\n"));
+  fprintf (file, _("\
+  -z noexecstack              Mark executable as not requiring executable stack\n"));
+  fprintf (file, _("\
+  -z globalaudit              Mark executable requiring global auditing\n"));
+}
+
+static void
+elf_plt_unwind_list_options (FILE *file)
+{
+  fprintf (file, _("\
+  --ld-generated-unwind-info  Generate exception handling info for PLT\n"));
+  fprintf (file, _("\
+  --no-ld-generated-unwind-info\n\
+                              Don't generate exception handling info for PLT\n"));
+}
+
+static void
+ld_list_options (FILE *file, bfd_boolean elf, bfd_boolean shlib,
+                bfd_boolean plt_unwind)
+{
+  if (!elf)
+    return;
+  printf (_("ELF emulations:\n"));
+  if (plt_unwind)
+    elf_plt_unwind_list_options (file);
+  elf_static_list_options (file);
+  if (shlib)
+    elf_shlib_list_options (file);
+}
+
 \f
 /* Print help messages for the options.  */
 
@@ -1692,6 +2149,8 @@ help (void)
 
   /* xgettext:c-format */
   printf (_("%s: emulation specific options:\n"), program_name);
+  ld_list_options (stdout, ELF_LIST_OPTIONS, ELF_SHLIB_LIST_OPTIONS,
+                  ELF_PLT_UNWIND_LIST_OPTIONS);
   ldemul_list_emulation_options (stdout);
   printf ("\n");
 
This page took 0.038122 seconds and 4 git commands to generate.