From 2a4b2c4b2ecc54e7fac47efd0393edba86997434 Mon Sep 17 00:00:00 2001 From: Alexander Kabaev Date: Thu, 10 Oct 2002 04:49:03 +0000 Subject: [PATCH] Merge FreeBSD modifications into gcc 3.2.1-prerelease: 1.\\{2,15\\} FREEBSD_NATIVE 1.\\{5,13\\} ELF, and objformat support 1.\\{16,23,25\\} Better cross building control 1.21 'GCC_OPTIONS' 1.27 cross-arch MD_EXEC_PREFIX fixes cc -print-search-dir fixes 1.28 Read specs from /usr/libdata/gcc/specs, if available Approved by: obrien --- contrib/gcc/gcc.c | 376 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 282 insertions(+), 94 deletions(-) diff --git a/contrib/gcc/gcc.c b/contrib/gcc/gcc.c index be4a666c093b..bded641e029f 100644 --- a/contrib/gcc/gcc.c +++ b/contrib/gcc/gcc.c @@ -174,6 +174,11 @@ static const char *print_prog_name = NULL; static int print_multi_directory; +/* Flag saying to print the relative path we'd use to + find OS libraries given the current compiler flags. */ + +static int print_multi_os_directory; + /* Flag saying to print the list of subdirectories and compiler flags used to select them in a standard form. */ @@ -287,9 +292,10 @@ static struct compiler *lookup_compiler PARAMS ((const char *, size_t, const cha static char *build_search_list PARAMS ((struct path_prefix *, const char *, int)); static void putenv_from_prefixes PARAMS ((struct path_prefix *, const char *)); static int access_check PARAMS ((const char *, int)); -static char *find_a_file PARAMS ((struct path_prefix *, const char *, int)); +static char *find_a_file PARAMS ((struct path_prefix *, const char *, + int, int)); static void add_prefix PARAMS ((struct path_prefix *, const char *, - const char *, int, int, int *)); + const char *, int, int, int *, int)); static void translate_options PARAMS ((int *, const char *const **)); static char *skip_whitespace PARAMS ((char *)); static void delete_if_ordinary PARAMS ((const char *)); @@ -965,6 +971,7 @@ static const struct option_map option_map[] = {"--print-missing-file-dependencies", "-MG", 0}, {"--print-multi-lib", "-print-multi-lib", 0}, {"--print-multi-directory", "-print-multi-directory", 0}, + {"--print-multi-os-directory", "-print-multi-os-directory", 0}, {"--print-prog-name", "-print-prog-name=", "aj"}, {"--profile", "-p", 0}, {"--profile-blocks", "-a", 0}, @@ -1250,7 +1257,9 @@ struct prefix_list int require_machine_suffix; /* Don't use without machine_suffix. */ /* 2 means try both machine_suffix and just_machine_suffix. */ int *used_flag_ptr; /* 1 if a file was found with this prefix. */ - int priority; /* Sort key - priority within list */ + int priority; /* Sort key - priority within list. */ + int os_multilib; /* 1 if OS multilib scheme should be used, + 0 for GCC multilib scheme. */ }; struct path_prefix @@ -1343,6 +1352,11 @@ static const char *const standard_bindir_prefix = STANDARD_BINDIR_PREFIX; set_multilib_dir based on the compilation options. */ static const char *multilib_dir; + +/* Subdirectory to use for locating libraries in OS conventions. Set by + set_multilib_dir based on the compilation options. */ + +static const char *multilib_os_dir; /* Structure to keep track of the specs that have been defined so far. These are accessed using %(specname) or %[specname] in a compiler @@ -1396,6 +1410,7 @@ static struct spec_list static_specs[] = INIT_STATIC_SPEC ("multilib_extra", &multilib_extra), INIT_STATIC_SPEC ("multilib_matches", &multilib_matches), INIT_STATIC_SPEC ("multilib_exclusions", &multilib_exclusions), + INIT_STATIC_SPEC ("multilib_options", &multilib_options), INIT_STATIC_SPEC ("linker", &linker_name_spec), INIT_STATIC_SPEC ("link_libgcc", &link_libgcc_spec), INIT_STATIC_SPEC ("md_exec_prefix", &md_exec_prefix), @@ -1838,7 +1853,7 @@ read_specs (filename, main_p) (long) (p1 - buffer + 1)); p[-2] = '\0'; - new_filename = find_a_file (&startfile_prefixes, p1, R_OK); + new_filename = find_a_file (&startfile_prefixes, p1, R_OK, 0); read_specs (new_filename ? new_filename : p1, FALSE); continue; } @@ -1857,7 +1872,7 @@ read_specs (filename, main_p) (long) (p1 - buffer + 1)); p[-2] = '\0'; - new_filename = find_a_file (&startfile_prefixes, p1, R_OK); + new_filename = find_a_file (&startfile_prefixes, p1, R_OK, 0); if (new_filename) read_specs (new_filename, FALSE); else if (verbose_flag) @@ -2486,16 +2501,17 @@ access_check (name, mode) Return 0 if not found, otherwise return its name, allocated with malloc. */ static char * -find_a_file (pprefix, name, mode) +find_a_file (pprefix, name, mode, multilib) struct path_prefix *pprefix; const char *name; - int mode; + int mode, multilib; { char *temp; const char *const file_suffix = ((mode & X_OK) != 0 ? HOST_EXECUTABLE_SUFFIX : ""); struct prefix_list *pl; int len = pprefix->max_len + strlen (name) + strlen (file_suffix) + 1; + const char *multilib_name, *multilib_os_name; #ifdef DEFAULT_ASSEMBLER if (! strcmp (name, "as") && access (DEFAULT_ASSEMBLER, mode) == 0) @@ -2510,6 +2526,22 @@ find_a_file (pprefix, name, mode) if (machine_suffix) len += strlen (machine_suffix); + multilib_name = name; + multilib_os_name = name; + if (multilib && multilib_os_dir) + { + int len1 = multilib_dir ? strlen (multilib_dir) + 1 : 0; + int len2 = strlen (multilib_os_dir) + 1; + + len += len1 > len2 ? len1 : len2; + if (multilib_dir) + multilib_name = ACONCAT ((multilib_dir, dir_separator_str, name, + NULL)); + if (strcmp (multilib_os_dir, ".") != 0) + multilib_os_name = ACONCAT ((multilib_os_dir, dir_separator_str, name, + NULL)); + } + temp = xmalloc (len); /* Determine the filename to execute (special case for absolute paths). */ @@ -2525,6 +2557,9 @@ find_a_file (pprefix, name, mode) else for (pl = pprefix->plist; pl; pl = pl->next) { + const char *this_name + = pl->os_multilib ? multilib_os_name : multilib_name; + if (machine_suffix) { /* Some systems have a suffix for executable files. @@ -2533,7 +2568,7 @@ find_a_file (pprefix, name, mode) { strcpy (temp, pl->prefix); strcat (temp, machine_suffix); - strcat (temp, name); + strcat (temp, multilib_name); strcat (temp, file_suffix); if (access_check (temp, mode) == 0) { @@ -2543,10 +2578,10 @@ find_a_file (pprefix, name, mode) } } - /* Now try just the name. */ + /* Now try just the multilib_name. */ strcpy (temp, pl->prefix); strcat (temp, machine_suffix); - strcat (temp, name); + strcat (temp, multilib_name); if (access_check (temp, mode) == 0) { if (pl->used_flag_ptr != 0) @@ -2565,7 +2600,7 @@ find_a_file (pprefix, name, mode) { strcpy (temp, pl->prefix); strcat (temp, just_machine_suffix); - strcat (temp, name); + strcat (temp, multilib_name); strcat (temp, file_suffix); if (access_check (temp, mode) == 0) { @@ -2577,7 +2612,7 @@ find_a_file (pprefix, name, mode) strcpy (temp, pl->prefix); strcat (temp, just_machine_suffix); - strcat (temp, name); + strcat (temp, multilib_name); if (access_check (temp, mode) == 0) { if (pl->used_flag_ptr != 0) @@ -2595,7 +2630,7 @@ find_a_file (pprefix, name, mode) if (file_suffix[0] != 0) { strcpy (temp, pl->prefix); - strcat (temp, name); + strcat (temp, this_name); strcat (temp, file_suffix); if (access_check (temp, mode) == 0) { @@ -2606,7 +2641,7 @@ find_a_file (pprefix, name, mode) } strcpy (temp, pl->prefix); - strcat (temp, name); + strcat (temp, this_name); if (access_check (temp, mode) == 0) { if (pl->used_flag_ptr != 0) @@ -2644,13 +2679,15 @@ enum path_prefix_priority 2 means try both machine_suffix and just_machine_suffix. */ static void -add_prefix (pprefix, prefix, component, priority, require_machine_suffix, warn) +add_prefix (pprefix, prefix, component, priority, require_machine_suffix, + warn, os_multilib) struct path_prefix *pprefix; const char *prefix; const char *component; /* enum prefix_priority */ int priority; int require_machine_suffix; int *warn; + int os_multilib; { struct prefix_list *pl, **prev; int len; @@ -2672,6 +2709,7 @@ add_prefix (pprefix, prefix, component, priority, require_machine_suffix, warn) pl->require_machine_suffix = require_machine_suffix; pl->used_flag_ptr = warn; pl->priority = priority; + pl->os_multilib = os_multilib; if (warn) *warn = 0; @@ -2715,7 +2753,7 @@ execute () commands[0].prog = argbuf[0]; /* first command. */ commands[0].argv = &argbuf[0]; - string = find_a_file (&exec_prefixes, commands[0].prog, X_OK); + string = find_a_file (&exec_prefixes, commands[0].prog, X_OK, 0); if (string) commands[0].argv[0] = string; @@ -2729,7 +2767,8 @@ execute () argbuf[i] = 0; /* termination of command args. */ commands[n_commands].prog = argbuf[i + 1]; commands[n_commands].argv = &argbuf[i + 1]; - string = find_a_file (&exec_prefixes, commands[n_commands].prog, X_OK); + string = find_a_file (&exec_prefixes, commands[n_commands].prog, + X_OK, 0); if (string) commands[n_commands].argv[0] = string; n_commands++; @@ -3058,6 +3097,7 @@ display_help () fputs (_("\ -print-multi-lib Display the mapping between command line options and\n\ multiple library search directories\n"), stdout); + fputs (_(" -print-multi-os-directory Display the relative path to OS libraries\n"), stdout); fputs (_(" -Wa, Pass comma-separated on to the assembler\n"), stdout); fputs (_(" -Wp, Pass comma-separated on to the preprocessor\n"), stdout); fputs (_(" -Wl, Pass comma-separated on to the linker\n"), stdout); @@ -3221,9 +3261,9 @@ process_command (argc, argv) set_std_prefix (gcc_exec_prefix, len); add_prefix (&exec_prefixes, gcc_exec_prefix, "GCC", - PREFIX_PRIORITY_LAST, 0, NULL); + PREFIX_PRIORITY_LAST, 0, NULL, 0); add_prefix (&startfile_prefixes, gcc_exec_prefix, "GCC", - PREFIX_PRIORITY_LAST, 0, NULL); + PREFIX_PRIORITY_LAST, 0, NULL, 0); } /* COMPILER_PATH and LIBRARY_PATH have values @@ -3251,10 +3291,10 @@ process_command (argc, argv) else nstore[endp - startp] = 0; add_prefix (&exec_prefixes, nstore, 0, - PREFIX_PRIORITY_LAST, 0, NULL); + PREFIX_PRIORITY_LAST, 0, NULL, 0); add_prefix (&include_prefixes, concat (nstore, "include", NULL), - 0, PREFIX_PRIORITY_LAST, 0, NULL); + 0, PREFIX_PRIORITY_LAST, 0, NULL, 0); if (*endp == 0) break; endp = startp = endp + 1; @@ -3286,7 +3326,7 @@ process_command (argc, argv) else nstore[endp - startp] = 0; add_prefix (&startfile_prefixes, nstore, NULL, - PREFIX_PRIORITY_LAST, 0, NULL); + PREFIX_PRIORITY_LAST, 0, NULL, 1); if (*endp == 0) break; endp = startp = endp + 1; @@ -3319,7 +3359,7 @@ process_command (argc, argv) else nstore[endp - startp] = 0; add_prefix (&startfile_prefixes, nstore, NULL, - PREFIX_PRIORITY_LAST, 0, NULL); + PREFIX_PRIORITY_LAST, 0, NULL, 1); if (*endp == 0) break; endp = startp = endp + 1; @@ -3471,6 +3511,8 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" print_multi_lib = 1; else if (! strcmp (argv[i], "-print-multi-directory")) print_multi_directory = 1; + else if (! strcmp (argv[i], "-print-multi-os-directory")) + print_multi_os_directory = 1; else if (! strncmp (argv[i], "-Wa,", 4)) { int prev, j; @@ -3640,7 +3682,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" { if (len == 7) add_prefix (&include_prefixes, "include", NULL, - PREFIX_PRIORITY_B_OPT, 0, NULL); + PREFIX_PRIORITY_B_OPT, 0, NULL, 0); else { char * string = xmalloc (len + 1); @@ -3648,16 +3690,16 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" strncpy (string, value, len - 7); strcpy (string + len - 7, "include"); add_prefix (&include_prefixes, string, NULL, - PREFIX_PRIORITY_B_OPT, 0, NULL); + PREFIX_PRIORITY_B_OPT, 0, NULL, 0); } } add_prefix (&exec_prefixes, value, NULL, - PREFIX_PRIORITY_B_OPT, 0, &warn_B); + PREFIX_PRIORITY_B_OPT, 0, &warn_B, 0); add_prefix (&startfile_prefixes, value, NULL, - PREFIX_PRIORITY_B_OPT, 0, &warn_B); + PREFIX_PRIORITY_B_OPT, 0, &warn_B, 0); add_prefix (&include_prefixes, concat (value, "include", NULL), - NULL, PREFIX_PRIORITY_B_OPT, 0, NULL); + NULL, PREFIX_PRIORITY_B_OPT, 0, NULL, 0); n_switches++; } break; @@ -3834,11 +3876,11 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" case OBJFMT_AOUT: n_switches++; /* add implied -maout */ add_prefix (&exec_prefixes, PREFIX"/libexec/aout/", "BINUTILS", - 0, 0, warn_std_ptr); + 0, 0, warn_std_ptr, 0); break; case OBJFMT_ELF: add_prefix (&exec_prefixes, PREFIX"/libexec/elf/", "BINUTILS", - 0, 0, warn_std_ptr); + 0, 0, warn_std_ptr, 0); break; case OBJFMT_UNKNOWN: fatal ("object format unknown"); @@ -3846,20 +3888,20 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" #endif /* FREEBSD_NATIVE */ #ifndef OS2 add_prefix (&exec_prefixes, standard_exec_prefix, "GCC", - PREFIX_PRIORITY_LAST, 1, warn_std_ptr); + PREFIX_PRIORITY_LAST, 1, warn_std_ptr, 0); add_prefix (&exec_prefixes, standard_exec_prefix, "BINUTILS", - PREFIX_PRIORITY_LAST, 2, warn_std_ptr); + PREFIX_PRIORITY_LAST, 2, warn_std_ptr, 0); #ifndef FREEBSD_NATIVE add_prefix (&exec_prefixes, standard_exec_prefix_1, "BINUTILS", - PREFIX_PRIORITY_LAST, 2, warn_std_ptr); + PREFIX_PRIORITY_LAST, 2, warn_std_ptr, 0); #endif /* not FREEBSD_NATIVE */ #endif #ifndef FREEBSD_NATIVE add_prefix (&startfile_prefixes, standard_exec_prefix, "BINUTILS", - PREFIX_PRIORITY_LAST, 1, warn_std_ptr); + PREFIX_PRIORITY_LAST, 1, warn_std_ptr, 0); add_prefix (&startfile_prefixes, standard_exec_prefix_1, "BINUTILS", - PREFIX_PRIORITY_LAST, 1, warn_std_ptr); + PREFIX_PRIORITY_LAST, 1, warn_std_ptr, 0); #endif /* not FREEBSD_NATIVE */ tooldir_prefix = concat (tooldir_base_prefix, spec_machine, @@ -3883,11 +3925,11 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" add_prefix (&exec_prefixes, concat (gcc_exec_tooldir_prefix, "bin", dir_separator_str, NULL), - NULL, PREFIX_PRIORITY_LAST, 0, NULL); + NULL, PREFIX_PRIORITY_LAST, 0, NULL, 0); add_prefix (&startfile_prefixes, concat (gcc_exec_tooldir_prefix, "lib", dir_separator_str, NULL), - NULL, PREFIX_PRIORITY_LAST, 0, NULL); + NULL, PREFIX_PRIORITY_LAST, 0, NULL, 1); } tooldir_prefix = concat (standard_exec_prefix, spec_machine, @@ -3898,10 +3940,10 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" #ifndef FREEBSD_NATIVE add_prefix (&exec_prefixes, concat (tooldir_prefix, "bin", dir_separator_str, NULL), - "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL); + "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 0); add_prefix (&startfile_prefixes, concat (tooldir_prefix, "lib", dir_separator_str, NULL), - "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL); + "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1); #endif /* FREEBSD_NATIVE */ /* More prefixes are enabled in main, after we read the specs file @@ -3971,6 +4013,8 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" ; else if (! strcmp (argv[i], "-print-multi-directory")) ; + else if (! strcmp (argv[i], "-print-multi-os-directory")) + ; else if (! strcmp (argv[i], "-ftarget-help")) ; else if (! strcmp (argv[i], "-fhelp")) @@ -4474,9 +4518,14 @@ do_spec_1 (spec, inswitch, soft_matched_part) continue; #endif /* Try subdirectory if there is one. */ - if (multilib_dir != NULL) + if (multilib_dir != NULL + || (pl->os_multilib && multilib_os_dir != NULL)) { - if (machine_suffix) + const char *multi_dir; + + multi_dir = pl->os_multilib ? multilib_os_dir + : multilib_dir; + if (machine_suffix && multilib_dir) { if (strlen (pl->prefix) + strlen (machine_suffix) >= bufsize) @@ -4499,14 +4548,14 @@ do_spec_1 (spec, inswitch, soft_matched_part) } if (!pl->require_machine_suffix) { - if (is_directory (pl->prefix, multilib_dir, 1)) + if (is_directory (pl->prefix, multi_dir, 1)) { do_spec_1 ("-L", 0, NULL); #ifdef SPACE_AFTER_L_OPTION do_spec_1 (" ", 0, NULL); #endif do_spec_1 (pl->prefix, 1, NULL); - do_spec_1 (multilib_dir, 1, NULL); + do_spec_1 (multi_dir, 1, NULL); /* Make this a separate argument. */ do_spec_1 (" ", 0, NULL); } @@ -5727,11 +5776,9 @@ find_file (name) char *newname; /* Try multilib_dir if it is defined. */ - if (multilib_dir != NULL) + if (multilib_os_dir != NULL) { - const char *const try = ACONCAT ((multilib_dir, dir_separator_str, name, NULL)); - - newname = find_a_file (&startfile_prefixes, try, R_OK); + newname = find_a_file (&startfile_prefixes, name, R_OK, 1); /* If we don't find it in the multi library dir, then fall through and look for it in the normal places. */ @@ -5739,7 +5786,7 @@ find_file (name) return newname; } - newname = find_a_file (&startfile_prefixes, name, R_OK); + newname = find_a_file (&startfile_prefixes, name, R_OK, 0); return newname ? newname : name; } @@ -5980,7 +6027,7 @@ main (argc, argv) just_machine_suffix = concat (spec_machine, dir_separator_str, NULL); #endif /* FREEBSD_NATIVE */ - specs_file = find_a_file (&startfile_prefixes, "specs", R_OK); + specs_file = find_a_file (&startfile_prefixes, "specs", R_OK, 0); /* Read the specs file unless it is a default one. */ if (specs_file != 0 && strcmp (specs_file, "specs")) read_specs (specs_file, TRUE); @@ -6005,18 +6052,18 @@ main (argc, argv) if (*md_exec_prefix) { add_prefix (&exec_prefixes, md_exec_prefix, "GCC", - PREFIX_PRIORITY_LAST, 0, NULL); + PREFIX_PRIORITY_LAST, 0, NULL, 0); add_prefix (&startfile_prefixes, md_exec_prefix, "GCC", - PREFIX_PRIORITY_LAST, 0, NULL); + PREFIX_PRIORITY_LAST, 0, NULL, 0); } if (*md_startfile_prefix) add_prefix (&startfile_prefixes, md_startfile_prefix, "GCC", - PREFIX_PRIORITY_LAST, 0, NULL); + PREFIX_PRIORITY_LAST, 0, NULL, 1); if (*md_startfile_prefix_1) add_prefix (&startfile_prefixes, md_startfile_prefix_1, "GCC", - PREFIX_PRIORITY_LAST, 0, NULL); + PREFIX_PRIORITY_LAST, 0, NULL, 1); /* If standard_startfile_prefix is relative, base it on standard_exec_prefix. This lets us move the installed tree @@ -6024,30 +6071,30 @@ main (argc, argv) standard_startfile_prefix on that as well. */ if (IS_ABSOLUTE_PATHNAME (standard_startfile_prefix)) add_prefix (&startfile_prefixes, standard_startfile_prefix, "BINUTILS", - PREFIX_PRIORITY_LAST, 0, NULL); + PREFIX_PRIORITY_LAST, 0, NULL, 1); else { if (gcc_exec_prefix) add_prefix (&startfile_prefixes, concat (gcc_exec_prefix, machine_suffix, standard_startfile_prefix, NULL), - NULL, PREFIX_PRIORITY_LAST, 0, NULL); + NULL, PREFIX_PRIORITY_LAST, 0, NULL, 1); add_prefix (&startfile_prefixes, concat (standard_exec_prefix, machine_suffix, standard_startfile_prefix, NULL), - NULL, PREFIX_PRIORITY_LAST, 0, NULL); + NULL, PREFIX_PRIORITY_LAST, 0, NULL, 1); } #ifndef FREEBSD_NATIVE add_prefix (&startfile_prefixes, standard_startfile_prefix_1, - "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL); + "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1); add_prefix (&startfile_prefixes, standard_startfile_prefix_2, - "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL); + "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1); #endif /* not FREEBSD_NATIVE */ #if 0 /* Can cause surprises, and one can use -B./ instead. */ add_prefix (&startfile_prefixes, "./", NULL, - PREFIX_PRIORITY_LAST, 1, NULL); + PREFIX_PRIORITY_LAST, 1, NULL, 0); #endif } else @@ -6057,10 +6104,10 @@ main (argc, argv) add_prefix (&startfile_prefixes, concat (gcc_exec_prefix, machine_suffix, standard_startfile_prefix, NULL), - "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL); + "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1); #ifdef CROSS_STARTFILE_PREFIX add_prefix (&startfile_prefixes, CROSS_STARTFILE_PREFIX, "BINUTILS", - PREFIX_PRIORITY_LAST, 0, NULL); + PREFIX_PRIORITY_LAST, 0, NULL, 1); #endif } @@ -6068,7 +6115,8 @@ main (argc, argv) line. */ for (uptr = user_specs_head; uptr; uptr = uptr->next) { - char *filename = find_a_file (&startfile_prefixes, uptr->filename, R_OK); + char *filename = find_a_file (&startfile_prefixes, uptr->filename, + R_OK, 0); read_specs (filename ? filename : uptr->filename, FALSE); } @@ -6110,7 +6158,7 @@ main (argc, argv) if (print_prog_name) { - char *newname = find_a_file (&exec_prefixes, print_prog_name, X_OK); + char *newname = find_a_file (&exec_prefixes, print_prog_name, X_OK, 0); printf ("%s\n", (newname ? newname : print_prog_name)); return (0); } @@ -6130,6 +6178,15 @@ main (argc, argv) return (0); } + if (print_multi_os_directory) + { + if (multilib_os_dir == NULL) + printf (".\n"); + else + printf ("%s\n", multilib_os_dir); + return (0); + } + if (target_help_flag) { /* Print if any target specific options. */ @@ -6289,7 +6346,7 @@ main (argc, argv) /* We'll use ld if we can't find collect2. */ if (! strcmp (linker_name_spec, "collect2")) { - char *s = find_a_file (&exec_prefixes, "collect2", X_OK); + char *s = find_a_file (&exec_prefixes, "collect2", X_OK, 0); if (s == NULL) linker_name_spec = "ld"; } @@ -6583,6 +6640,15 @@ next_member: goto next_member; } +struct mdswitchstr +{ + const char *str; + int len; +}; + +static struct mdswitchstr *mdswitches; +static int n_mdswitches; + /* Check whether a particular argument was used. The first time we canonicalize the switches to keep only the ones we care about. */ @@ -6648,8 +6714,9 @@ used_arg (p, len) xmalloc from calling fatal, and prevents us from re-executing this block of code. */ mswitches - = (struct mswitchstr *) xmalloc ((sizeof (struct mswitchstr)) - * (n_switches ? n_switches : 1)); + = (struct mswitchstr *) + xmalloc (sizeof (struct mswitchstr) + * (n_mdswitches + (n_switches ? n_switches : 1))); for (i = 0; i < n_switches; i++) { int xlen = strlen (switches[i].part1); @@ -6665,6 +6732,57 @@ used_arg (p, len) break; } } + + /* Add MULTILIB_DEFAULTS switches too, as long as they were not present + on the command line nor any options mutually incompatible with + them. */ + for (i = 0; i < n_mdswitches; i++) + { + const char *r; + + for (q = multilib_options; *q != '\0'; q++) + { + while (*q == ' ') + q++; + + r = q; + while (strncmp (q, mdswitches[i].str, mdswitches[i].len) != 0 + || strchr (" /", q[mdswitches[i].len]) == NULL) + { + while (*q != ' ' && *q != '/' && *q != '\0') + q++; + if (*q != '/') + break; + q++; + } + + if (*q != ' ' && *q != '\0') + { + while (*r != ' ' && *r != '\0') + { + q = r; + while (*q != ' ' && *q != '/' && *q != '\0') + q++; + + if (used_arg (r, q - r)) + break; + + if (*q != '/') + { + mswitches[n_mswitches].str = mdswitches[i].str; + mswitches[n_mswitches].len = mdswitches[i].len; + mswitches[n_mswitches].replace = (char *) 0; + mswitches[n_mswitches].rep_len = 0; + n_mswitches++; + break; + } + + r = q + 1; + } + break; + } + } + } } for (i = 0; i < n_mswitches; i++) @@ -6679,25 +6797,11 @@ default_arg (p, len) const char *p; int len; { - const char *start, *end; + int i; - for (start = multilib_defaults; *start != '\0'; start = end + 1) - { - while (*start == ' ' || *start == '\t') - start++; - - if (*start == '\0') - break; - - for (end = start + 1; *end != ' ' && *end != '\t' && *end != '\0'; end++) - ; - - if ((end - start) == len && strncmp (p, start, len) == 0) - return 1; - - if (*end == '\0') - break; - } + for (i = 0; i < n_mdswitches; i++) + if (len == mdswitches[i].len && ! strncmp (p, mdswitches[i].str, len)) + return 1; return 0; } @@ -6719,8 +6823,51 @@ set_multilib_dir () const char *p; unsigned int this_path_len; const char *this_path, *this_arg; + const char *start, *end; int not_arg; - int ok; + int ok, ndfltok, first; + + n_mdswitches = 0; + start = multilib_defaults; + while (*start == ' ' || *start == '\t') + start++; + while (*start != '\0') + { + n_mdswitches++; + while (*start != ' ' && *start != '\t' && *start != '\0') + start++; + while (*start == ' ' || *start == '\t') + start++; + } + + if (n_mdswitches) + { + int i = 0; + + mdswitches + = (struct mdswitchstr *) xmalloc (sizeof (struct mdswitchstr) + * n_mdswitches); + for (start = multilib_defaults; *start != '\0'; start = end + 1) + { + while (*start == ' ' || *start == '\t') + start++; + + if (*start == '\0') + break; + + for (end = start + 1; + *end != ' ' && *end != '\t' && *end != '\0'; end++) + ; + + obstack_grow (&multilib_obstack, start, end - start); + obstack_1grow (&multilib_obstack, 0); + mdswitches[i].str = obstack_finish (&multilib_obstack); + mdswitches[i++].len = end - start; + + if (*end == '\0') + break; + } + } p = multilib_exclusions; while (*p != '\0') @@ -6775,6 +6922,7 @@ set_multilib_dir () ++p; } + first = 1; p = multilib_select; while (*p != '\0') { @@ -6797,6 +6945,7 @@ set_multilib_dir () /* Check the arguments. */ ok = 1; + ndfltok = 1; ++p; while (*p != ';') { @@ -6832,32 +6981,65 @@ set_multilib_dir () there is a more specific library which uses this argument. If this argument is a default, we need not consider that more specific library. */ - if (! default_arg (this_arg, p - this_arg)) - { - ok = used_arg (this_arg, p - this_arg); - if (not_arg) - ok = ! ok; - } + ok = used_arg (this_arg, p - this_arg); + if (not_arg) + ok = ! ok; + + if (! ok) + ndfltok = 0; + + if (default_arg (this_arg, p - this_arg)) + ok = 1; if (*p == ' ') ++p; } - if (ok) + if (ok && first) { if (this_path_len != 1 || this_path[0] != '.') { char *new_multilib_dir = xmalloc (this_path_len + 1); + char *q; + strncpy (new_multilib_dir, this_path, this_path_len); new_multilib_dir[this_path_len] = '\0'; + q = strchr (new_multilib_dir, ':'); + if (q != NULL) + *q = '\0'; multilib_dir = new_multilib_dir; } - break; + first = 0; + } + + if (ndfltok) + { + const char *q = this_path, *end = this_path + this_path_len; + + while (q < end && *q != ':') + q++; + if (q < end) + { + char *new_multilib_os_dir = xmalloc (end - q); + memcpy (new_multilib_os_dir, q + 1, end - q - 1); + new_multilib_os_dir[end - q - 1] = '\0'; + multilib_os_dir = new_multilib_os_dir; + break; + } } ++p; } + + if (multilib_dir == NULL && multilib_os_dir != NULL + && strcmp (multilib_os_dir, ".") == 0) + { + free ((char *) multilib_os_dir); + multilib_os_dir = NULL; + } + else if (multilib_dir != NULL && multilib_os_dir == NULL) + multilib_os_dir = multilib_dir; } /* Print out the multiple library subdirectory selection @@ -6897,6 +7079,12 @@ print_multilib_info () ++p; } + /* When --disable-multilib was used but target defines + MULTILIB_OSDIRNAMES, entries starting with .: are there just + to find multilib_os_dir, so skip them from output. */ + if (this_path[0] == '.' && this_path[1] == ':') + skip = 1; + /* Check for matches with the multilib_exclusions. We don't bother with the '!' in either list. If any of the exclusion rules match all of its options with the select rule, we skip it. */ @@ -7038,7 +7226,7 @@ print_multilib_info () { const char *p1; - for (p1 = last_path; p1 < p; p1++) + for (p1 = last_path; p1 < p && *p1 != ':'; p1++) putchar (*p1); putchar (';'); }