X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=ld%2Flexsup.c;h=8f4785b1b2dc988fd177f4a3e71650bc4a07a95e;hb=feb129926a8d12656f1ca4b7a8bb10268d3af4fb;hp=72537a77cdc6fd074f9baa7ff429619a43dcdd7f;hpb=fc4826cf4d19eb3ed29a2e3a76e36c0f339ff3a3;p=deliverable%2Fbinutils-gdb.git diff --git a/ld/lexsup.c b/ld/lexsup.c index 72537a77cd..8f4785b1b2 100644 --- a/ld/lexsup.c +++ b/ld/lexsup.c @@ -1,5 +1,5 @@ /* Parse options for the GNU linker. - Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 1998 + Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. This file is part of GLD, the Gnu Linker. @@ -69,7 +69,8 @@ int parsing_defsym = 0; #define OPTION_CALL_SHARED (OPTION_ASSERT + 1) #define OPTION_CREF (OPTION_CALL_SHARED + 1) #define OPTION_DEFSYM (OPTION_CREF + 1) -#define OPTION_DYNAMIC_LINKER (OPTION_DEFSYM + 1) +#define OPTION_DEMANGLE (OPTION_DEFSYM + 1) +#define OPTION_DYNAMIC_LINKER (OPTION_DEMANGLE + 1) #define OPTION_EB (OPTION_DYNAMIC_LINKER + 1) #define OPTION_EL (OPTION_EB + 1) #define OPTION_EMBEDDED_RELOCS (OPTION_EL + 1) @@ -77,7 +78,8 @@ int parsing_defsym = 0; #define OPTION_HELP (OPTION_EXPORT_DYNAMIC + 1) #define OPTION_IGNORE (OPTION_HELP + 1) #define OPTION_MAP (OPTION_IGNORE + 1) -#define OPTION_NO_KEEP_MEMORY (OPTION_MAP + 1) +#define OPTION_NO_DEMANGLE (OPTION_MAP + 1) +#define OPTION_NO_KEEP_MEMORY (OPTION_NO_DEMANGLE + 1) #define OPTION_NO_WARN_MISMATCH (OPTION_NO_KEEP_MEMORY + 1) #define OPTION_NOINHIBIT_EXEC (OPTION_NO_WARN_MISMATCH + 1) #define OPTION_NON_SHARED (OPTION_NOINHIBIT_EXEC + 1) @@ -101,7 +103,8 @@ int parsing_defsym = 0; #define OPTION_VERBOSE (OPTION_UR + 1) #define OPTION_VERSION (OPTION_VERBOSE + 1) #define OPTION_VERSION_SCRIPT (OPTION_VERSION + 1) -#define OPTION_WARN_COMMON (OPTION_VERSION_SCRIPT + 1) +#define OPTION_VERSION_EXPORTS_SECTION (OPTION_VERSION_SCRIPT + 1) +#define OPTION_WARN_COMMON (OPTION_VERSION_EXPORTS_SECTION + 1) #define OPTION_WARN_CONSTRUCTORS (OPTION_WARN_COMMON + 1) #define OPTION_WARN_MULTIPLE_GP (OPTION_WARN_CONSTRUCTORS + 1) #define OPTION_WARN_ONCE (OPTION_WARN_MULTIPLE_GP + 1) @@ -111,6 +114,14 @@ int parsing_defsym = 0; #define OPTION_WHOLE_ARCHIVE (OPTION_SPLIT_BY_FILE + 1) #define OPTION_WRAP (OPTION_WHOLE_ARCHIVE + 1) #define OPTION_FORCE_EXE_SUFFIX (OPTION_WRAP + 1) +#define OPTION_GC_SECTIONS (OPTION_FORCE_EXE_SUFFIX + 1) +#define OPTION_NO_GC_SECTIONS (OPTION_GC_SECTIONS + 1) +#define OPTION_CHECK_SECTIONS (OPTION_NO_GC_SECTIONS + 1) +#define OPTION_NO_CHECK_SECTIONS (OPTION_CHECK_SECTIONS + 1) +#define OPTION_MPC860C0 (OPTION_NO_CHECK_SECTIONS + 1) +#define OPTION_NO_UNDEFINED (OPTION_MPC860C0 + 1) +#define OPTION_INIT (OPTION_NO_UNDEFINED + 1) +#define OPTION_FINI (OPTION_INIT + 1) /* The long options. This structure is used for both the option parsing and the help text. */ @@ -156,6 +167,10 @@ 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 }, + { {"EB", no_argument, NULL, OPTION_EB}, + '\0', NULL, N_("Link big-endian objects"), ONE_DASH }, + { {"EL", no_argument, NULL, OPTION_EL}, + '\0', NULL, N_("Link little-endian objects"), ONE_DASH }, { {"auxiliary", required_argument, NULL, 'f'}, 'f', N_("SHLIB"), N_("Auxiliary filter for shared object symbol table"), TWO_DASHES }, @@ -184,7 +199,9 @@ static const struct ld_option ld_options[] = { {"output", required_argument, NULL, 'o'}, 'o', N_("FILE"), N_("Set output file name"), TWO_DASHES }, { {NULL, required_argument, NULL, '\0'}, - 'O', NULL, N_("Ignored"), ONE_DASH }, + 'O', NULL, N_("Optimize output file"), ONE_DASH }, + { {"Qy", no_argument, NULL, OPTION_IGNORE}, + '\0', NULL, N_("Ignored for SVR4 compatibility"), ONE_DASH }, { {"relocateable", no_argument, NULL, 'r'}, 'r', NULL, N_("Generate relocateable output"), TWO_DASHES }, { {NULL, no_argument, NULL, '\0'}, @@ -202,6 +219,8 @@ static const struct ld_option ld_options[] = 'T', N_("FILE"), N_("Read linker script"), TWO_DASHES }, { {"undefined", required_argument, NULL, 'u'}, 'u', N_("SYMBOL"), N_("Start with undefined reference to SYMBOL"), TWO_DASHES }, + { {"Ur", no_argument, NULL, OPTION_UR}, + '\0', NULL, N_("Build global constructor/destructor tables"), ONE_DASH }, { {"version", no_argument, NULL, OPTION_VERSION}, 'v', NULL, N_("Print version information"), TWO_DASHES }, { {NULL, no_argument, NULL, '\0'}, @@ -238,26 +257,43 @@ static const struct ld_option ld_options[] = '\0', NULL, NULL, ONE_DASH }, { {"Bsymbolic", no_argument, NULL, OPTION_SYMBOLIC}, '\0', NULL, N_("Bind global references locally"), ONE_DASH }, + { {"check-sections", no_argument, NULL, OPTION_CHECK_SECTIONS}, + '\0', NULL, N_("Check section addresses for overlaps (default)"), TWO_DASHES }, + { {"no-check-sections", no_argument, NULL, OPTION_NO_CHECK_SECTIONS}, + '\0', NULL, N_("Do not check section addresses for overlaps"), + TWO_DASHES }, { {"cref", no_argument, NULL, OPTION_CREF}, '\0', NULL, N_("Output cross reference table"), TWO_DASHES }, { {"defsym", required_argument, NULL, OPTION_DEFSYM}, '\0', N_("SYMBOL=EXPRESSION"), N_("Define a symbol"), TWO_DASHES }, + { {"demangle", no_argument, NULL, OPTION_DEMANGLE}, + '\0', NULL, N_("Demangle symbol names"), TWO_DASHES }, { {"dynamic-linker", required_argument, NULL, OPTION_DYNAMIC_LINKER}, '\0', N_("PROGRAM"), N_("Set the dynamic linker to use"), TWO_DASHES }, - { {"EB", no_argument, NULL, OPTION_EB}, - '\0', NULL, N_("Link big-endian objects"), ONE_DASH }, - { {"EL", no_argument, NULL, OPTION_EL}, - '\0', NULL, N_("Link little-endian objects"), ONE_DASH }, { {"embedded-relocs", no_argument, NULL, OPTION_EMBEDDED_RELOCS}, '\0', NULL, N_("Generate embedded relocs"), 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}, '\0', NULL, N_("Force generation of file with .exe suffix"), TWO_DASHES}, + { {"gc-sections", no_argument, NULL, OPTION_GC_SECTIONS}, + '\0', NULL, N_("Remove unused sections (on some targets)"), + TWO_DASHES }, + { {"no-gc-sections", no_argument, NULL, OPTION_NO_GC_SECTIONS}, + '\0', NULL, N_("Don't remove unused sections (default)"), + TWO_DASHES }, { {"help", no_argument, NULL, OPTION_HELP}, '\0', NULL, N_("Print option help"), TWO_DASHES }, + { {"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 }, + { {"no-demangle", no_argument, NULL, OPTION_NO_DEMANGLE }, + '\0', NULL, N_("Do not demangle symbol names"), TWO_DASHES }, { {"no-keep-memory", no_argument, NULL, OPTION_NO_KEEP_MEMORY}, '\0', NULL, N_("Use less memory and more disk I/O"), TWO_DASHES }, + { {"no-undefined", no_argument, NULL, OPTION_NO_UNDEFINED}, + '\0', NULL, N_("Allow no undefined symbols"), TWO_DASHES }, { {"no-warn-mismatch", no_argument, NULL, OPTION_NO_WARN_MISMATCH}, '\0', NULL, N_("Don't warn about mismatched input files"), TWO_DASHES}, { {"no-whole-archive", no_argument, NULL, OPTION_NO_WHOLE_ARCHIVE}, @@ -270,8 +306,6 @@ static const struct ld_option ld_options[] = '\0', N_("TARGET"), N_("Specify target of output file"), TWO_DASHES }, { {"qmagic", no_argument, NULL, OPTION_IGNORE}, '\0', NULL, N_("Ignored for Linux compatibility"), ONE_DASH }, - { {"Qy", no_argument, NULL, OPTION_IGNORE}, - '\0', NULL, N_("Ignored for SVR4 compatibility"), ONE_DASH }, { {"relax", no_argument, NULL, OPTION_RELAX}, '\0', NULL, N_("Relax branches on certain targets"), TWO_DASHES }, { {"retain-symbols-file", required_argument, NULL, @@ -305,14 +339,16 @@ 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 }, - { {"Ur", no_argument, NULL, OPTION_UR}, - '\0', NULL, N_("Build global constructor/destructor tables"), ONE_DASH }, { {"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. */ '\0', NULL, NULL, NO_HELP }, { {"version-script", required_argument, NULL, OPTION_VERSION_SCRIPT }, '\0', N_("FILE"), N_("Read version information script"), TWO_DASHES }, + { {"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 }, { {"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}, @@ -328,11 +364,35 @@ static const struct ld_option ld_options[] = { {"whole-archive", no_argument, NULL, OPTION_WHOLE_ARCHIVE}, '\0', NULL, N_("Include all objects from following archives"), TWO_DASHES }, { {"wrap", required_argument, NULL, OPTION_WRAP}, - '\0', N_("SYMBOL"), N_("Use wrapper functions for SYMBOL"), TWO_DASHES } + '\0', N_("SYMBOL"), N_("Use wrapper functions for SYMBOL"), TWO_DASHES }, + { {"mpc860c0", optional_argument, NULL, OPTION_MPC860C0}, + '\0', N_("[=WORDS]"), N_("Modify problematic branches in last WORDS (1-10,\n\t\t\t\tdefault 5) words of a page"), TWO_DASHES } }; #define OPTION_COUNT ((int) (sizeof ld_options / sizeof ld_options[0])) +/* Test "string" for containing a string of digits that form a number +between "min" and "max". The return value is the number or "err". */ +static +int is_num( char *string, int min, int max, int err) +{ + int result = 0; + + for ( ; *string; ++string) + { + if (!isdigit(*string)) + { + result = err; + break; + } + result = result * 10 + (*string - '0'); + } + if (result < min || result > max) + result = err; + + return result; +} + void parse_args (argc, argv) int argc; @@ -399,7 +459,7 @@ parse_args (argc, argv) /* Because we permit long options to start with a single dash, and we have a --library option, and the -l option is conventionally used with an immediately following argument, we can have bad - results of somebody tries to use -l with a library whose name + results if somebody tries to use -l with a library whose name happens to start with "ibrary", as in -li. We avoid problems by simply turning -l into --library. This means that users will have to use two dashes in order to use --library, which is OK @@ -516,6 +576,9 @@ parse_args (argc, argv) parsing_defsym = 0; lex_string = NULL; break; + case OPTION_DEMANGLE: + demangling = true; + break; case OPTION_DYNAMIC_LINKER: command_line.interpreter = optarg; break; @@ -575,6 +638,9 @@ parse_args (argc, argv) case 'g': /* Ignore. */ break; + case OPTION_GC_SECTIONS: + command_line.gc_sections = true; + break; case OPTION_HELP: help (); xexit (0); @@ -604,9 +670,18 @@ parse_args (argc, argv) config.magic_demand_paged = false; config.dynamic_link = false; break; + case OPTION_NO_DEMANGLE: + demangling = false; + break; + case OPTION_NO_GC_SECTIONS: + command_line.gc_sections = false; + break; case OPTION_NO_KEEP_MEMORY: link_info.keep_memory = false; break; + case OPTION_NO_UNDEFINED: + link_info.no_undefined = true; + break; case OPTION_NO_WARN_MISMATCH: command_line.warn_mismatch = false; break; @@ -622,6 +697,9 @@ parse_args (argc, argv) something, or can we create a new option to do that (with a syntax similar to -defsym)? getopt can't handle two args to an option without kludges. */ + + /* Enable optimizations of output files. */ + link_info.optimize = strtoul (optarg, NULL, 0) ? true : false; break; case 'o': lang_add_output (optarg, 0); @@ -663,14 +741,36 @@ parse_args (argc, argv) command_line.rpath = buystring (optarg); else { + size_t rpath_len = strlen (command_line.rpath); + size_t optarg_len = strlen (optarg); char *buf; + char *cp = command_line.rpath; - buf = xmalloc (strlen (command_line.rpath) - + strlen (optarg) - + 2); - sprintf (buf, "%s:%s", command_line.rpath, optarg); - free (command_line.rpath); - command_line.rpath = buf; + /* First see whether OPTARG is already in the path. */ + do + { + size_t idx = 0; + while (optarg[idx] != '\0' && optarg[idx] == cp[idx]) + ++idx; + if (optarg[idx] == '\0' + && (cp[idx] == '\0' || cp[idx] == ':')) + /* We found it. */ + break; + + /* Not yet found. */ + cp = strchr (cp, ':'); + if (cp != NULL) + ++cp; + } + while (cp != NULL); + + if (cp == NULL) + { + buf = xmalloc (rpath_len + optarg_len + 2); + sprintf (buf, "%s:%s", command_line.rpath, optarg); + free (command_line.rpath); + command_line.rpath = buf; + } } break; case OPTION_RPATH_LINK: @@ -701,7 +801,10 @@ parse_args (argc, argv) link_info.strip = strip_all; break; case OPTION_SHARED: - link_info.shared = true; + if (config.has_shared) + link_info.shared = true; + else + einfo (_("%P%F: -shared not supported\n")); break; case 'h': /* Used on Solaris. */ case OPTION_SONAME: @@ -795,6 +898,12 @@ the GNU General Public License. This program has absolutely no warranty.\n")); yyparse (); } break; + case OPTION_VERSION_EXPORTS_SECTION: + /* This option records a version symbol to be applied to the + symbols listed for export to be found in the object files + .exports sections. */ + command_line.version_exports_section = optarg; + break; case OPTION_WARN_COMMON: config.warn_common = true; break; @@ -841,6 +950,12 @@ the GNU General Public License. This program has absolutely no warranty.\n")); case OPTION_SPLIT_BY_FILE: config.split_by_file = true; break; + case OPTION_CHECK_SECTIONS: + command_line.check_section_addresses = true; + break; + case OPTION_NO_CHECK_SECTIONS: + command_line.check_section_addresses = false; + break; case '(': if (ingroup) { @@ -863,7 +978,30 @@ the GNU General Public License. This program has absolutely no warranty.\n")); lang_leave_group (); ingroup = 0; break; + case OPTION_MPC860C0: + link_info.mpc860c0 = 20; /* default value (in bytes) */ + if (optarg) + { + unsigned words; + + words = is_num (optarg, 1, 10, 0); + if (words == 0) + { + fprintf (stderr, _("Invalid argument to option \"mpc860c0\"\n")); + xexit (1); + } + link_info.mpc860c0 = words * 4; /* convert words to bytes */ + } + command_line.relax = true; + break; + case OPTION_INIT: + link_info.init_function = optarg; + break; + + case OPTION_FINI: + link_info.fini_function = optarg; + break; } } @@ -994,6 +1132,9 @@ help () } } + /* Note: Various tools (such as libtool) depend upon the + format of the listings below - do not change them. */ + /* xgettext:c-format */ printf (_("%s: supported targets:"), program_name); targets = bfd_target_list (); for (pp = targets; *pp != NULL; pp++) @@ -1001,8 +1142,15 @@ help () free (targets); printf ("\n"); + /* xgettext:c-format */ printf (_("%s: supported emulations: "), program_name); ldemul_list_emulations (stdout); printf ("\n"); + + /* xgettext:c-format */ + printf (_("%s: emulation specific options:\n"), program_name); + ldemul_list_emulation_options (stdout); + printf ("\n"); + printf (_("\nReport bugs to bug-gnu-utils@gnu.org\n")); }