#include "ldver.h"
#include "ldemul.h"
#include "demangle.h"
-#ifdef ENABLE_PLUGINS
+#if BFD_SUPPORTS_PLUGINS
#include "plugin.h"
-#endif /* ENABLE_PLUGINS */
+#endif /* BFD_SUPPORTS_PLUGINS */
#ifndef PATH_SEPARATOR
#if defined (__MSDOS__) || (defined (_WIN32) && ! defined (__CYGWIN32__))
'd', NULL, N_("Force common symbols to be defined"), ONE_DASH },
{ {"dp", no_argument, NULL, 'd'},
'\0', NULL, NULL, ONE_DASH },
+ { {"dependency-file", required_argument, NULL, OPTION_DEPENDENCY_FILE},
+ '\0', N_("FILE"), N_("Write dependency file"), TWO_DASHES },
{ {"force-group-allocation", no_argument, NULL,
OPTION_FORCE_GROUP_ALLOCATION},
'\0', NULL, N_("Force group members out of groups"), TWO_DASHES },
'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
+#if BFD_SUPPORTS_PLUGINS
{ {"plugin", required_argument, NULL, OPTION_PLUGIN},
'\0', N_("PLUGIN"), N_("Load named plugin"), ONE_DASH },
{ {"plugin-opt", required_argument, NULL, OPTION_PLUGIN_OPT},
{ {"flto-partition=", required_argument, NULL, OPTION_IGNORE},
'\0', NULL, N_("Ignored for GCC LTO option compatibility"),
ONE_DASH },
-#endif /* ENABLE_PLUGINS */
+#else
+ { {"plugin", required_argument, NULL, OPTION_IGNORE},
+ '\0', N_("PLUGIN"), N_("Load named plugin (ignored)"), ONE_DASH },
+ { {"plugin-opt", required_argument, NULL, OPTION_IGNORE},
+ '\0', N_("ARG"), N_("Send arg to last-loaded plugin (ignored)"), ONE_DASH },
+#endif /* BFD_SUPPORTS_PLUGINS */
{ {"fuse-ld=", required_argument, NULL, OPTION_IGNORE},
'\0', NULL, N_("Ignored for GCC linker option compatibility"),
ONE_DASH },
{ {"allow-multiple-definition", no_argument, NULL,
OPTION_ALLOW_MULTIPLE_DEFINITION},
'\0', NULL, N_("Allow multiple definitions"), TWO_DASHES },
+#if SUPPORT_ERROR_HANDLING_SCRIPT
+ { {"error-handling-script", required_argument, NULL,
+ OPTION_ERROR_HANDLING_SCRIPT},
+ '\0', N_("SCRIPT"), N_("Provide a script to help with undefined symbol errors"), TWO_DASHES},
+#endif
{ {"no-undefined-version", no_argument, NULL, OPTION_NO_UNDEFINED_VERSION},
'\0', NULL, N_("Disallow undefined version"), TWO_DASHES },
{ {"default-symver", no_argument, NULL, OPTION_DEFAULT_SYMVER},
'\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},
{ {"warn-textrel", no_argument, NULL, OPTION_WARN_TEXTREL},
'\0', NULL,
#if DEFAULT_LD_TEXTREL_CHECK_WARNING
- N_("Warn if outpout has DT_TEXTREL (default)"),
+ N_("Warn if output has DT_TEXTREL (default)"),
#else
- N_("Warn if outpout has DT_TEXTREL"),
+ N_("Warn if output has DT_TEXTREL"),
#endif
TWO_DASHES },
{ {"warn-shared-textrel", no_argument, NULL, OPTION_WARN_TEXTREL},
{ {"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 },
+ { {"ctf-variables", no_argument, NULL, OPTION_CTF_VARIABLES},
+ '\0', NULL, N_("Emit names and types of static variables in CTF"),
+ TWO_DASHES },
+ { {"no-ctf-variables", no_argument, NULL, OPTION_NO_CTF_VARIABLES},
+ '\0', NULL, N_("Do not emit names and types of static variables in CTF"),
+ TWO_DASHES },
+ { {"ctf-share-types=<method>", required_argument, NULL,
+ OPTION_CTF_SHARE_TYPES},
+ '\0', NULL, N_("How to share CTF types between translation units.\n"
+ " <method> is: share-unconflicted (default),\n"
+ " share-duplicated"),
+ TWO_DASHES },
};
#define OPTION_COUNT ARRAY_SIZE (ld_options)
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 *)
xmalloc (sizeof (*longopts) * (OPTION_COUNT + 1));
really_longopts = (struct option *)
- malloc (sizeof (*really_longopts) * (OPTION_COUNT + 1));
+ xmalloc (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
optind = last_optind;
optc = getopt_long (argc, argv, "-", really_longopts, &longind);
}
+ /* Attempt to detect grouped short options, eg: "-non-start".
+ Accepting such options is error prone as it is not clear if the user
+ intended "-n -o n-start" or "--non-start". */
+ else if (longind == 0 /* This is a short option. */
+ && optc > 32 /* It is a valid option. */
+ /* The character is not the second character of argv[last_optind]. */
+ && optc != argv[last_optind][1])
+ {
+ if (optarg)
+ einfo (_("%F%P: Error: unable to disambiguate: %s (did you mean -%s ?)\n"),
+ argv[last_optind], argv[last_optind]);
+ else
+ einfo (_("%P: Warning: grouped short command line options are deprecated: %s\n"), argv[last_optind]);
+ }
if (ldemul_handle_option (optc))
continue;
case OPTION_ALLOW_MULTIPLE_DEFINITION:
link_info.allow_multiple_definition = TRUE;
break;
+
+#if SUPPORT_ERROR_HANDLING_SCRIPT
+ case OPTION_ERROR_HANDLING_SCRIPT:
+ /* FIXME: Should we warn if the script is being overridden by another ?
+ Or maybe they should be chained together ? */
+ error_handling_script = optarg;
+ break;
+#endif
+
case OPTION_NO_UNDEFINED_VERSION:
link_info.allow_undefined_version = FALSE;
break;
case OPTION_PRINT_OUTPUT_FORMAT:
command_line.print_output_format = TRUE;
break;
-#ifdef ENABLE_PLUGINS
+#if BFD_SUPPORTS_PLUGINS
case OPTION_PLUGIN:
plugin_opt_plugin (optarg);
break;
if (plugin_opt_plugin_arg (optarg))
einfo (_("%F%P: bad -plugin-opt option\n"));
break;
-#endif /* ENABLE_PLUGINS */
+#endif /* BFD_SUPPORTS_PLUGINS */
case 'q':
link_info.emitrelocations = TRUE;
break;
int level ATTRIBUTE_UNUSED = strtoul (optarg, &end, 0);
if (*end)
einfo (_("%F%P: invalid number `%s'\n"), optarg);
-#ifdef ENABLE_PLUGINS
+#if BFD_SUPPORTS_PLUGINS
report_plugin_symbols = level > 1;
-#endif /* ENABLE_PLUGINS */
+#endif /* BFD_SUPPORTS_PLUGINS */
}
break;
case 'v':
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 ();
+ }
+ break;
case OPTION_WARN_COMMON:
config.warn_common = TRUE;
break;
case OPTION_PRINT_MAP_DISCARDED:
config.print_map_discarded = TRUE;
break;
+
+ case OPTION_DEPENDENCY_FILE:
+ config.dependency_file = optarg;
+ break;
+
+ case OPTION_CTF_VARIABLES:
+ config.ctf_variables = TRUE;
+ break;
+
+ case OPTION_NO_CTF_VARIABLES:
+ config.ctf_variables = FALSE;
+ break;
+
+ case OPTION_CTF_SHARE_TYPES:
+ if (strcmp (optarg, "share-unconflicted") == 0)
+ config.ctf_share_duplicated = FALSE;
+ else if (strcmp (optarg, "share-duplicated") == 0)
+ config.ctf_share_duplicated = TRUE;
+ else
+ einfo (_("%F%P: bad --ctf-share-types option: %s\n"), optarg);
+ break;
}
}
&& command_line.check_section_addresses < 0)
command_line.check_section_addresses = 0;
+ if (export_list)
+ {
+ 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))
+ {
+ /* 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);
+ }
+ }
+
switch (opt_dynamic_list)
{
case dynamic_list_unset:
-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"));
+ loaded objects\n"));
fprintf (file, _("\
-z initfirst Mark DSO to be initialized first at runtime\n"));
fprintf (file, _("\
Compress DWARF debug sections using zlib\n"));
#ifdef DEFAULT_FLAG_COMPRESS_DEBUG
fprintf (file, _("\
- Default: zlib-gabi\n"));
+ Default: zlib-gabi\n"));
#else
fprintf (file, _("\
- Default: none\n"));
+ Default: none\n"));
#endif
fprintf (file, _("\
-z common-page-size=SIZE Set common page size to SIZE\n"));
fprintf (file, _("\
-z noexecstack Mark executable as not requiring executable stack\n"));
fprintf (file, _("\
+ -z unique-symbol Avoid duplicated local symbol names\n"));
+ fprintf (file, _("\
+ -z nounique-symbol Keep duplicated local symbol names (default)\n"));
+ fprintf (file, _("\
-z globalaudit Mark executable requiring global auditing\n"));
}