X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=ld%2Flexsup.c;h=eae64932dfcbeaeec4391fc613bfa459eda56bcb;hb=23ae20f5e3afeeab9aa616c63ab3b357668476d5;hp=412e2e60267119192073359c87ec904371130011;hpb=b32632c49968cd03e952f9b63b32d9e9f1ddaf53;p=deliverable%2Fbinutils-gdb.git diff --git a/ld/lexsup.c b/ld/lexsup.c index 412e2e6026..eae64932df 100644 --- a/ld/lexsup.c +++ b/ld/lexsup.c @@ -39,9 +39,9 @@ #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__)) @@ -113,6 +113,8 @@ 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 }, + { {"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 }, @@ -174,7 +176,7 @@ static const struct ld_option ld_options[] = '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}, @@ -185,7 +187,12 @@ static const struct ld_option ld_options[] = { {"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 }, @@ -379,6 +386,11 @@ static const struct ld_option ld_options[] = { {"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}, @@ -504,6 +516,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}, @@ -519,9 +535,9 @@ static const struct ld_option ld_options[] = { {"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}, @@ -561,6 +577,18 @@ static const struct ld_option ld_options[] = { {"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=", required_argument, NULL, + OPTION_CTF_SHARE_TYPES}, + '\0', NULL, N_("How to share CTF types between translation units.\n" + " is: share-unconflicted (default),\n" + " share-duplicated"), + TWO_DASHES }, }; #define OPTION_COUNT ARRAY_SIZE (ld_options) @@ -588,12 +616,13 @@ parse_args (unsigned argc, char **argv) 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 @@ -711,6 +740,20 @@ parse_args (unsigned argc, char **argv) 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; @@ -1005,6 +1048,15 @@ parse_args (unsigned argc, char **argv) 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; @@ -1056,7 +1108,7 @@ parse_args (unsigned argc, char **argv) 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; @@ -1064,7 +1116,7 @@ parse_args (unsigned argc, char **argv) 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; @@ -1358,9 +1410,9 @@ parse_args (unsigned argc, char **argv) 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': @@ -1419,11 +1471,35 @@ 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 (); + } + break; case OPTION_WARN_COMMON: config.warn_common = TRUE; break; @@ -1597,6 +1673,27 @@ parse_args (unsigned argc, char **argv) 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; } } @@ -1666,6 +1763,49 @@ parse_args (unsigned argc, char **argv) && 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: @@ -1836,7 +1976,7 @@ elf_shlib_list_options (FILE *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")); + loaded objects\n")); fprintf (file, _("\ -z initfirst Mark DSO to be initialized first at runtime\n")); fprintf (file, _("\ @@ -1920,10 +2060,10 @@ elf_static_list_options (FILE *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")); @@ -1938,6 +2078,10 @@ elf_static_list_options (FILE *file) 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")); }