]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
* gcc.c (print_multi_os_directory): New variable.
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 3 Oct 2002 20:35:14 +0000 (20:35 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 3 Oct 2002 20:35:14 +0000 (20:35 +0000)
(option_map): Support --print-multi-os-directory.
(struct prefix_list): Add os_multilib field.
(multilib_os_dir): New variable.
(static_specs): Add multilib_options.
(find_a_file): Add multilib argument.  Search in GCC or OS multilib
subdirs if non-zero.
(read_specs, execute): Update callers.
(find_file): Likewise.  Don't prefix name with multilib_dir, instead
pass 1 as multilib option.
(display_help): Include --print-multi-os-directory.
(add_prefix): Add os_multilib argument.  Initialize pl->os_multilib.
(process_command): Update callers.  Handle --print-multi-os-directory.
(do_spec_1) ['D']: Use multilib_os_directory if pl->os_multilib is
set.
(main): Update find_a_file and add_prefix callers.
Handle print_multi_os_directory.
(struct mdswitchstr): New.
(mdswitches, n_mdswitches): New variables.
(used_arg): Add MULTILIB_DEFAULT switches too if they are not
present on the command line nor their mutually incompatible
switches.
(default_arg): Optimize.
(set_multilib_dir): Compute multilib_os_dir.  Initialize mdswitches
array.
(print_multilib_info): Only print GCC multilib dir name, not OS
multilib dirname.
* genmultilib: Add osdirnames parameter.  Output multilib_options
variable.  If osdirnames is specified, output dirnames as
dirname:osdirname.
* mklibgcc.in: Use MULTILIB_OSDIRNAMES, --print-multi-directory
and --print-multi-os-directory instead of SHLIB_SLIBDIR_SUFFIXES
to compute libgcc_s soname and install path.
* Makefile.in (libgcc.mk): Pass MULTILIB_OSDIRNAMES instead of
SHLIB_SLIBDIR_SUFFIXES to mklibgcc.
(s_mlib): Pass MULTILIB_OSDIRNAMES or nothing as last genmultilib
argument.

* config/sparc/t-linux64 (MULTILIB_OSDIRNAMES): Set.
(SHLIB_SLIBDIR_SUFFIXES): Remove.
* config/sparc/linux64.h (STARTFILE_SPEC32, STARTFILE_SPEC64,
ENDFILE_SPEC32, ENDFILE_SPEC64, ENDFILE_COMMON): Remove.
(STARTFILE_SPEC, ENDFILE_SPEC): Don't distinguish between -m32
and -m64.
* config/sparc/t-sol2-64 (MULTILIB_OSDIRNAMES): Set.
(SHLIB_SLIBDIR_SUFFIXES): Remove.
* config/sparc/sol2-bi.h (STARTFILE_ARCH64_SPEC): Remove.
(STARTFILE_ARCH_SPEC): Remove.
* config/i386/t-linux64 (MULTILIB_OSDIRNAMES): Set.
(SHLIB_SLIBDIR_SUFFIXES): Remove.
* config/i386/linux64.h (STARTFILE_PREFIX_SPEC): Remove.
* config/mips/t-iris6 (MULTILIB_OSDIRNAMES): Set.
(SHLIB_SLIBDIR_SUFFIXES): Remove.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@57786 138bc75d-0d04-0410-961f-82ee72b054a4

12 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/config/i386/linux64.h
gcc/config/i386/t-linux64
gcc/config/mips/t-iris6
gcc/config/sparc/linux64.h
gcc/config/sparc/sol2-bi.h
gcc/config/sparc/t-linux64
gcc/config/sparc/t-sol2-64
gcc/gcc.c
gcc/genmultilib
gcc/mklibgcc.in

index 1ad35bd706271737a229ea93e6344c6a8f209fab..5e9e0737fa8af5ca2652e9d57ba24d76aff64232 100644 (file)
@@ -1,3 +1,59 @@
+2002-10-03  Jakub Jelinek  <jakub@redhat.com>
+
+       * gcc.c (print_multi_os_directory): New variable.
+       (option_map): Support --print-multi-os-directory.
+       (struct prefix_list): Add os_multilib field.
+       (multilib_os_dir): New variable.
+       (static_specs): Add multilib_options.
+       (find_a_file): Add multilib argument.  Search in GCC or OS multilib
+       subdirs if non-zero.
+       (read_specs, execute): Update callers.
+       (find_file): Likewise.  Don't prefix name with multilib_dir, instead
+       pass 1 as multilib option.
+       (display_help): Include --print-multi-os-directory.
+       (add_prefix): Add os_multilib argument.  Initialize pl->os_multilib.
+       (process_command): Update callers.  Handle --print-multi-os-directory.
+       (do_spec_1) ['D']: Use multilib_os_directory if pl->os_multilib is
+       set.
+       (main): Update find_a_file and add_prefix callers.
+       Handle print_multi_os_directory.
+       (struct mdswitchstr): New.
+       (mdswitches, n_mdswitches): New variables.
+       (used_arg): Add MULTILIB_DEFAULT switches too if they are not
+       present on the command line nor their mutually incompatible
+       switches.
+       (default_arg): Optimize.
+       (set_multilib_dir): Compute multilib_os_dir.  Initialize mdswitches
+       array.
+       (print_multilib_info): Only print GCC multilib dir name, not OS
+       multilib dirname.
+       * genmultilib: Add osdirnames parameter.  Output multilib_options
+       variable.  If osdirnames is specified, output dirnames as
+       dirname:osdirname.
+       * mklibgcc.in: Use MULTILIB_OSDIRNAMES, --print-multi-directory
+       and --print-multi-os-directory instead of SHLIB_SLIBDIR_SUFFIXES
+       to compute libgcc_s soname and install path.
+       * Makefile.in (libgcc.mk): Pass MULTILIB_OSDIRNAMES instead of
+       SHLIB_SLIBDIR_SUFFIXES to mklibgcc.
+       (s_mlib): Pass MULTILIB_OSDIRNAMES or nothing as last genmultilib
+       argument.
+
+       * config/sparc/t-linux64 (MULTILIB_OSDIRNAMES): Set.
+       (SHLIB_SLIBDIR_SUFFIXES): Remove.
+       * config/sparc/linux64.h (STARTFILE_SPEC32, STARTFILE_SPEC64,
+       ENDFILE_SPEC32, ENDFILE_SPEC64, ENDFILE_COMMON): Remove.
+       (STARTFILE_SPEC, ENDFILE_SPEC): Don't distinguish between -m32
+       and -m64.
+       * config/sparc/t-sol2-64 (MULTILIB_OSDIRNAMES): Set.
+       (SHLIB_SLIBDIR_SUFFIXES): Remove.
+       * config/sparc/sol2-bi.h (STARTFILE_ARCH64_SPEC): Remove.
+       (STARTFILE_ARCH_SPEC): Remove.
+       * config/i386/t-linux64 (MULTILIB_OSDIRNAMES): Set.
+       (SHLIB_SLIBDIR_SUFFIXES): Remove.
+       * config/i386/linux64.h (STARTFILE_PREFIX_SPEC): Remove.
+       * config/mips/t-iris6 (MULTILIB_OSDIRNAMES): Set.
+       (SHLIB_SLIBDIR_SUFFIXES): Remove.
+
 Thu Oct  3 21:42:20 CEST 2002  Jan Hubicka  <jh@suse.cz>
 
        * predict.c (choose_function_section): Avoid choice for linkonce functions.
index d7aad602c59ad13c0fcdb473edf01ff89fe80bf3..edf95572d608733510271cc4a16a9038f423c1ef 100644 (file)
@@ -1027,7 +1027,7 @@ libgcc.mk: config.status Makefile mklibgcc $(LIB2ADD) $(LIB2ADD_ST) xgcc$(exeext
        SHLIB_MKMAP_OPTS='$(SHLIB_MKMAP_OPTS)' \
        SHLIB_MAPFILES='$(SHLIB_MAPFILES)' \
        SHLIB_NM_FLAGS='$(SHLIB_NM_FLAGS)' \
-       SHLIB_SLIBDIR_SUFFIXES='$(SHLIB_SLIBDIR_SUFFIXES)' \
+       MULTILIB_OSDIRNAMES='$(MULTILIB_OSDIRNAMES)' \
        mkinstalldirs='$(SHELL) $(srcdir)/mkinstalldirs' \
          $(SHELL) mklibgcc > tmp-libgcc.mk
        mv tmp-libgcc.mk libgcc.mk
@@ -1069,9 +1069,10 @@ s-mlib: $(srcdir)/genmultilib Makefile
            "$(MULTILIB_EXCEPTIONS)" \
            "$(MULTILIB_EXTRA_OPTS)" \
            "$(MULTILIB_EXCLUSIONS)" \
+           "$(MULTILIB_OSDIRNAMES)" \
            > tmp-mlib.h; \
        else \
-         $(SHELL) $(srcdir)/genmultilib '' '' '' '' '' '' > tmp-mlib.h; \
+         $(SHELL) $(srcdir)/genmultilib '' '' '' '' '' '' '' > tmp-mlib.h; \
        fi
        $(SHELL) $(srcdir)/move-if-change tmp-mlib.h multilib.h
        $(STAMP) s-mlib
index d2113909ece3138de81a8a9fb93fbc0cf6393529..965120a1bb615ff4139a15d959679da4eeb95150 100644 (file)
@@ -60,10 +60,6 @@ Boston, MA 02111-1307, USA.  */
       %{!m32:%{!dynamic-linker:-dynamic-linker /lib64/ld-linux-x86-64.so.2}}} \
     %{static:-static}}"
 
-#define STARTFILE_PREFIX_SPEC "\
-  %{m32: /usr/local/lib/ /lib/ /usr/lib/} \
-  %{!m32: /usr/local/lib64/ /lib64/ /usr/lib64/}"
-
 #undef  STARTFILE_SPEC
 #define STARTFILE_SPEC \
   "%{!shared: \
index 46a7caadf772e9ef2e0b423fcb98abec5394a400..8780321ca35e8c2c3f1b78940b80167f24e12ea3 100644 (file)
@@ -6,10 +6,9 @@ SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \
 
 MULTILIB_OPTIONS = m64/m32
 MULTILIB_DIRNAMES = 64 32 
+MULTILIB_OSDIRNAMES = ../lib64 ../lib32
 
 LIBGCC = stmp-multilib
 INSTALL_LIBGCC = install-multilib
 
 EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o
-
-SHLIB_SLIBDIR_SUFFIXES = 64:64 32:
index 582ec4c794906094bbd3008c5905f452512b9ac9..b55bc36aca8db76453487d79fe51dc1a10fd689f 100644 (file)
@@ -4,6 +4,7 @@
 MULTILIB_OPTIONS=mabi=n32/mabi=64
 MULTILIB_DIRNAMES=
 MULTILIB_MATCHES=
+MULTILIB_OSDIRNAMES=../lib32 ../lib64
 
 LIBGCC = stmp-multilib
 INSTALL_LIBGCC = install-multilib
@@ -14,8 +15,6 @@ INSTALL_LIBGCC = install-multilib
 EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o
 CRTSTUFF_T_CFLAGS=-g1
 
-SHLIB_SLIBDIR_SUFFIXES = mabi=64:/mabi=64 mabi=n32:
-
 # This is only needed in the static libgcc as a band-aid until gcc correctly
 # implements the N32/N64 ABI structure passing conventions
 LIB2FUNCS_STATIC_EXTRA = $(srcdir)/config/mips/irix6-libc-compat.c
index 51eca1661ae38e6688c41488be12ecb250bf162e..eb81eb61401c3934908fa4b530429ecbc2b3bb9d 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions for 64-bit SPARC running Linux-based GNU systems with ELF.
-   Copyright 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
+   Copyright 1996, 1997, 1998, 2000, 2002 Free Software Foundation, Inc.
    Contributed by David S. Miller (davem@caip.rutgers.edu)
 
 This file is part of GNU CC.
@@ -55,38 +55,11 @@ Boston, MA 02111-1307, USA.  */
    
 #undef  STARTFILE_SPEC
 
-#define STARTFILE_SPEC32 \
-  "%{!shared: \
-     %{pg:/usr/lib/gcrt1.o%s} %{!pg:%{p:/usr/lib/gcrt1.o%s} %{!p:/usr/lib/crt1.o%s}}}\
-   /usr/lib/crti.o%s %{static:crtbeginT.o%s}\
+#define STARTFILE_SPEC \
+  "%{!shared:%{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}}\
+   crti.o%s %{static:crtbeginT.o%s}\
    %{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
 
-#define STARTFILE_SPEC64 \
-  "%{!shared: \
-     %{pg:/usr/lib64/gcrt1.o%s} %{!pg:%{p:/usr/lib64/gcrt1.o%s} %{!p:/usr/lib64/crt1.o%s}}}\
-   /usr/lib64/crti.o%s %{static:crtbeginT.o%s}\
-   %{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
-
-#ifdef SPARC_BI_ARCH
-
-#if DEFAULT_ARCH32_P
-#define STARTFILE_SPEC "\
-%{m32:" STARTFILE_SPEC32 "} \
-%{m64:" STARTFILE_SPEC64 "} \
-%{!m32:%{!m64:" STARTFILE_SPEC32 "}}"
-#else
-#define STARTFILE_SPEC "\
-%{m32:" STARTFILE_SPEC32 "} \
-%{m64:" STARTFILE_SPEC64 "} \
-%{!m32:%{!m64:" STARTFILE_SPEC64 "}}"
-#endif
-
-#else
-
-#define STARTFILE_SPEC STARTFILE_SPEC64
-
-#endif
-
 /* Provide a ENDFILE_SPEC appropriate for GNU/Linux.  Here we tack on
    the GNU/Linux magical crtend.o file (see crtstuff.c) which
    provides part of the support for getting C++ file-scope static
@@ -95,36 +68,9 @@ Boston, MA 02111-1307, USA.  */
 
 #undef  ENDFILE_SPEC
 
-#define ENDFILE_SPEC32 \
-  "%{!shared:crtend.o%s} %{shared:crtendS.o%s} /usr/lib/crtn.o%s"
-
-#define ENDFILE_SPEC64 \
-  "%{!shared:crtend.o%s} %{shared:crtendS.o%s} /usr/lib64/crtn.o%s"
-  
-#define ENDFILE_SPEC_COMMON \
-  "%{ffast-math|funsafe-math-optimizations:crtfastmath.o%s}"
-
-#ifdef SPARC_BI_ARCH
-
-#if DEFAULT_ARCH32_P
-#define ENDFILE_SPEC "\
-%{m32:" ENDFILE_SPEC32 "} \
-%{m64:" ENDFILE_SPEC64 "} \
-%{!m32:%{!m64:" ENDFILE_SPEC32 "}} " \
-ENDFILE_SPEC_COMMON
-#else
-#define ENDFILE_SPEC "\
-%{m32:" ENDFILE_SPEC32 "} \
-%{m64:" ENDFILE_SPEC64 "} \
-%{!m32:%{!m64:" ENDFILE_SPEC64 "}} " \
-ENDFILE_SPEC_COMMON
-#endif
-
-#else
-
-#define ENDFILE_SPEC ENDFILE_SPEC64 " " ENDFILE_SPEC_COMMON
-
-#endif
+#define ENDFILE_SPEC \
+  "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s\
+   %{ffast-math|funsafe-math-optimizations:crtfastmath.o%s}"
 
 /* The GNU C++ standard library requires that these macros be defined.  */
 #undef CPLUSPLUS_CPP_SPEC
index 1ba52606aa3bc1dbe23d63fe7f400f040d3571be..3f9416daaa0952d5d7e8b15b7a1e85acb85aff53 100644 (file)
 %{!mcpu*:%(asm_cpu_default)} \
 "
 
-#define STARTFILE_ARCH64_SPEC "\
-%{ansi:/usr/lib/sparcv9/values-Xc.o%s} \
-%{!ansi:/usr/lib/sparcv9/values-Xa.o%s}"
-#undef STARTFILE_ARCH_SPEC
-
-#if DEFAULT_ARCH32_P
-#define STARTFILE_ARCH_SPEC "\
-%{m32:" STARTFILE_ARCH32_SPEC "} \
-%{m64:" STARTFILE_ARCH64_SPEC "} \
-%{!m32:%{!m64:" STARTFILE_ARCH32_SPEC "}}"
-#else
-#define STARTFILE_ARCH_SPEC "\
-%{m32:" STARTFILE_ARCH32_SPEC "} \
-%{m64:" STARTFILE_ARCH64_SPEC "} \
-%{!m32:%{!m64:" STARTFILE_ARCH64_SPEC "}}"
-#endif
-
 #undef CPP_CPU_DEFAULT_SPEC
 #define CPP_CPU_DEFAULT_SPEC \
 (DEFAULT_ARCH32_P ? "\
index a64862638355ba6ce20d51b8997c9a6b0caf758e..5b6603334f0aa5b3a4c0d13cbdc426f5af1d1375 100644 (file)
@@ -3,6 +3,7 @@ MULTILIB_DIRNAMES = 64 32 alt
 MULTILIB_MATCHES = mcmodel?medany=mcmodel?medmid
 MULTILIB_EXCEPTIONS = m32/mno-app-regs* m32/mcmodel=*
 MULTILIB_EXCLUSIONS = m32/!m64/mno-app-regs m32/!m64/mcmodel=medany
+MULTILIB_OSDIRNAMES = ../lib64 ../lib alt
 
 LIBGCC = stmp-multilib
 INSTALL_LIBGCC = install-multilib
@@ -10,8 +11,6 @@ INSTALL_LIBGCC = install-multilib
 EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o \
        crtfastmath.o
 
-SHLIB_SLIBDIR_SUFFIXES = 64:64 32:
-
 # Override t-slibgcc-elf-ver to export some libgcc symbols with
 # the symbol versions that glibc used.
 # Avoid the t-linux version file.
index 39204d7368fe31c7bffb27101f1ff114c52c3246..3c15f0a712a10238179e21837997bdefbd89fac7 100644 (file)
@@ -1,11 +1,10 @@
 MULTILIB_OPTIONS = m32/m64
 MULTILIB_DIRNAMES = sparcv7 sparcv9
 MULTILIB_MATCHES =
+MULTILIB_OSDIRNAMES = . sparcv9
 
 LIBGCC = stmp-multilib
 INSTALL_LIBGCC = install-multilib
 
 EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o gmon.o crt1.o crti.o crtn.o gcrt1.o \
        crtfastmath.o
-
-SHLIB_SLIBDIR_SUFFIXES = sparcv9:/sparcv9 sparcv7:
index f14a29cdc3983ebfc827490bbab9f24913139ad2..b9794fe399844b635bc2bbeac8a888b0be983878 100644 (file)
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -162,6 +162,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.  */
 
@@ -275,9 +280,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 *));
@@ -961,6 +967,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},
@@ -1246,7 +1253,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
@@ -1335,6 +1344,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;
 \f
 /* Structure to keep track of the specs that have been defined so far.
    These are accessed using %(specname) or %[specname] in a compiler
@@ -1389,6 +1403,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),
@@ -1836,7 +1851,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;
            }
@@ -1855,7 +1870,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)
@@ -2490,16 +2505,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)
@@ -2514,6 +2530,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).  */
@@ -2529,6 +2561,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.
@@ -2537,7 +2572,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)
                  {
@@ -2547,10 +2582,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)
@@ -2569,7 +2604,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)
                  {
@@ -2581,7 +2616,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)
@@ -2599,7 +2634,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)
                  {
@@ -2610,7 +2645,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)
@@ -2648,13 +2683,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;
@@ -2676,6 +2713,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;
 
@@ -2719,7 +2757,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;
@@ -2733,7 +2771,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++;
@@ -3048,6 +3087,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,<options>            Pass comma-separated <options> on to the assembler\n"), stdout);
   fputs (_("  -Wp,<options>            Pass comma-separated <options> on to the preprocessor\n"), stdout);
   fputs (_("  -Wl,<options>            Pass comma-separated <options> on to the linker\n"), stdout);
@@ -3264,9 +3304,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
@@ -3294,10 +3334,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;
@@ -3329,7 +3369,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;
@@ -3362,7 +3402,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;
@@ -3462,6 +3502,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;
@@ -3624,7 +3666,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);
@@ -3632,16 +3674,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;
@@ -3771,17 +3813,17 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
      as well as trying the machine and the version.  */
 #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);
   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
 
   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);
 
   tooldir_prefix = concat (tooldir_base_prefix, spec_machine,
                           dir_separator_str, NULL);
@@ -3804,11 +3846,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,
@@ -3818,10 +3860,10 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
 
   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);
 
   /* More prefixes are enabled in main, after we read the specs file
      and determine whether this is cross-compilation or not.  */
@@ -3871,6 +3913,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"))
@@ -4381,9 +4425,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)
@@ -4406,14 +4455,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);
                            }
@@ -5634,11 +5683,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.  */
@@ -5646,7 +5693,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;
 }
 
@@ -5881,7 +5928,7 @@ main (argc, argv)
                           spec_version, dir_separator_str, NULL);
   just_machine_suffix = concat (spec_machine, dir_separator_str, NULL);
 
-  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);
@@ -5908,18 +5955,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
@@ -5927,28 +5974,28 @@ 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);
        }
 
       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);
 #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
@@ -5958,7 +6005,7 @@ 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);
     }
 
   if (*startfile_prefix_spec != 0
@@ -5968,14 +6015,15 @@ main (argc, argv)
       int ndx;
       for (ndx = 0; ndx < argbuf_index; ndx++)
        add_prefix (&startfile_prefixes, argbuf[ndx], "BINUTILS",
-                   PREFIX_PRIORITY_LAST, 0, NULL);
+                   PREFIX_PRIORITY_LAST, 0, NULL, 1);
     }
 
   /* Process any user specified specs in the order given on the command
      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);
     }
 
@@ -6017,7 +6065,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);
     }
@@ -6037,6 +6085,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.  */
@@ -6196,7 +6253,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";
        }
@@ -6490,6 +6547,15 @@ next_member:
     goto next_member;
 }
 \f
+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.  */
 
@@ -6555,8 +6621,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);
@@ -6572,6 +6639,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++)
@@ -6586,25 +6704,11 @@ default_arg (p, len)
      const char *p;
      int len;
 {
-  const char *start, *end;
-
-  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;
+  int i;
 
-      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;
 }
@@ -6626,8 +6730,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')
@@ -6682,6 +6829,7 @@ set_multilib_dir ()
       ++p;
     }
 
+  first = 1;
   p = multilib_select;
   while (*p != '\0')
     {
@@ -6704,6 +6852,7 @@ set_multilib_dir ()
 
       /* Check the arguments.  */
       ok = 1;
+      ndfltok = 1;
       ++p;
       while (*p != ';')
        {
@@ -6739,32 +6888,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 == ':')
+           {
+             char *new_multilib_os_dir = xmalloc (end - q);
+             strncpy (new_multilib_os_dir, q + 1, end - q - 1);
+             new_multilib_os_dir[end - q] = '\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
@@ -6945,7 +7127,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 (';');
        }
index 3cbfaa1ebab263d6a52b4212401ce14270c3166d..c687537d70046e7d094e3281c85a87c127d3be2c 100644 (file)
 # for the rule to exclude a set. Options can be preceded with a '!' to
 # match a logical NOT.
 
+# The optional sevenths argument is a list of OS subdirectory names.
+# The format is the same as of the second argument.
+# The difference is that second argument describes multilib directories
+# in GCC conventions, while this one the OS multilib convention.
+
 # The output looks like
 #   #define MULTILIB_MATCHES "\
 #   SUBDIRECTORY OPTIONS;\
 # Here is an example (this is from the actual sparc64 case):
 #   genmultilib 'm64/m32 mno-app-regs|mcmodel=medany' '64 32 alt'
 #              'mcmodel?medany=mcmodel?medmid' 'm32/mno-app-regs* m32/mcmodel=*'
-#              'm32/!m64/mno-app-regs m32/!m64/mcmodel=medany'
+#              '' 'm32/!m64/mno-app-regs m32/!m64/mcmodel=medany'
+#              '../lib64 ../lib32 alt'
 # This produces:
 #   ". !m64 !m32 !mno-app-regs !mcmodel=medany;",
-#   "64 m64 !m32 !mno-app-regs !mcmodel=medany;",
-#   "32 !m64 m32 !mno-app-regs !mcmodel=medany;",
+#   "64:../lib64 m64 !m32 !mno-app-regs !mcmodel=medany;",
+#   "32:../lib32 !m64 m32 !mno-app-regs !mcmodel=medany;",
 #   "alt !m64 !m32 mno-app-regs mcmodel=medany;",
 #   "alt !m64 !m32 mno-app-regs !mcmodel=medany;",
 #   "alt !m64 !m32 !mno-app-regs mcmodel=medany;",
-#   "64/alt m64 !m32 mno-app-regs mcmodel=medany;",
-#   "64/alt m64 !m32 mno-app-regs !mcmodel=medany;",
-#   "64/alt m64 !m32 !mno-app-regs mcmodel=medany;",
+#   "64/alt:../lib64/alt m64 !m32 mno-app-regs mcmodel=medany;",
+#   "64/alt:../lib64/alt m64 !m32 mno-app-regs !mcmodel=medany;",
+#   "64/alt:../lib64/alt m64 !m32 !mno-app-regs mcmodel=medany;",
 #
 # The effect is that `gcc -mno-app-regs' (for example) will append "alt"
 # to the directory name when searching for libraries or startup files and
@@ -106,6 +112,7 @@ matches=$3
 exceptions=$4
 extra=$5
 exclusions=$6
+osdirnames=$7
 
 echo "static const char *const multilib_raw[] = {"
 
@@ -202,6 +209,29 @@ if [ -n "${dirnames}" ]; then
   done
 fi
 
+# Construct a sed pattern which will convert option names to OS directory
+# names.
+toosdirnames=
+if [ -n "${osdirnames}" ]; then
+  set x ${osdirnames}
+  shift
+  for set in ${options}; do
+    for opts in `echo ${set} | sed -e 's|/| |'g`; do
+      patt="/"
+      for opt in `echo ${opts} | sed -e 's_|_ _'g`; do
+        if [ "$1" != "${opt}" ]; then
+          toosdirnames="${toosdirnames} -e s|/${opt}/|/${1}/|g"
+         patt="${patt}${1}/"
+         if [ "${patt}" != "/${1}/" ]; then
+           toosdirnames="${toosdirnames} -e s|${patt}|/${1}/|g"
+          fi
+        fi
+      done
+      shift
+    done
+  done
+fi
+
 # We need another recursive shell script to correctly handle positive
 # matches.  If we are invoked as
 #   genmultilib "opt1 opt2" "" "opt1=nopt1 opt2=nopt2"
@@ -257,6 +287,16 @@ for combo in ${combinations}; do
   # Remove the leading and trailing slashes.
   dirout=`echo ${dirout} | sed -e 's|^/||' -e 's|/$||g'`
 
+  # Use the OS directory names rather than the option names.
+  if [ -n "${toosdirnames}" ]; then
+    osdirout=`echo ${combo} | sed ${toosdirnames}`
+    # Remove the leading and trailing slashes.
+    osdirout=`echo ${osdirout} | sed -e 's|^/||' -e 's|/$||g'`
+    if [ "x${dirout}" != "x${osdirout}" ]; then
+      dirout="${dirout}:${osdirout}"
+    fi
+  fi
+
   # Look through the options.  We must output each option that is
   # present, and negate each option that is not present.
   optout=
@@ -313,6 +353,11 @@ done
 echo "NULL"
 echo "};"
 
+# Output the options now
+moptions=`echo ${options} | sed -e 's,[        ][      ]*, ,g'`
+echo ""
+echo "static const char *multilib_options = \"${moptions}\";"
+
 rm -f tmpmultilib2
 
 exit 0
index 12f54460a6f0f840017080289cb83fd5ea01ee16..81d2e47f52b8f8cf32ac5a1a4406cb0f6aae692a 100644 (file)
@@ -32,7 +32,7 @@
 # SHLIB_MAPFILES
 # SHLIB_NM_FLAGS
 # SHLIB_INSTALL
-# SHLIB_SLIBDIR_SUFFIXES
+# MULTILIB_OSDIRNAMES
 
 # Make needs VPATH to be literal.
 echo 'srcdir = @srcdir@'
@@ -317,22 +317,18 @@ for ml in $MULTILIBS; do
       fi
       shlib_so_name="$shlib_base_name"
       shlib_dir=
-      if [ -n "$SHLIB_SLIBDIR_SUFFIXES" ]; then
+      if [ -n "$MULTILIB_OSDIRNAMES" ]; then
        if [ "$dir" != . ]; then
+         gcc_multilib_dir=`./xgcc -B./ $flags --print-multi-directory`
+         os_multilib_dir=`./xgcc -B./ $flags --print-multi-os-directory`
          shlib_dir="$dir"/
-         for suffix_pair in $SHLIB_SLIBDIR_SUFFIXES ; do
-           base_ml_dir=`echo ${suffix_pair} | sed -e 's/:.*$//' -e 's/=/$(EQ)/g'`
-           if [ "$dir" = "$base_ml_dir" ]; then
-             shlib_so_name=libgcc_s
-             break
-           else
-             canon_dir=`echo $dir | sed -n -e "s:$base_ml_dir/::p"`
-             if [ -n "$canon_dir" ]; then
-               shlib_so_name=libgcc_s_`echo $canon_dir | sed s,/,_,g`
-               break
-             fi
-           fi
-         done
+         gcc_multilib_sup=`echo $gcc_multilib_dir | sed 's~^[^/]*/~~'`
+         os_multilib_base=`echo $os_multilib_dir | sed -n "s~/${gcc_multilib_sup}\$~~p"`
+         if [ -z "$os_multilib_base" ]; then
+           shlib_so_name=libgcc_s
+         else
+           shlib_so_name=libgcc_s_`echo $gcc_multilib_sup | sed s,/,_,g`
+         fi
        fi
       fi
       echo ""
@@ -438,6 +434,7 @@ echo ""
 echo "install: $all"
 for ml in $MULTILIBS; do
   dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'`
+  flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`;
   if [ $dir != . ]; then
     ldir='$(libsubdir)'/$dir
     echo "     if [ -d $ldir ]; then true; else mkdir $ldir; chmod a+rx $ldir; fi;"
@@ -460,39 +457,22 @@ for ml in $MULTILIBS; do
       shlib_so_name="$shlib_base_name"
       shlib_dir=
       shlib_slibdir_qual=
-      if [ -n "$SHLIB_SLIBDIR_SUFFIXES" ]; then
-       shlib_slibdir_qual=none
+      if [ -n "$MULTILIB_OSDIRNAMES" ]; then
+       gcc_multilib_dir=`./xgcc -B./ $flags --print-multi-directory`
+       os_multilib_dir=`./xgcc -B./ $flags --print-multi-os-directory`
        if [ "$dir" != . ]; then
          shlib_dir="$dir"/
-         for suffix_pair in $SHLIB_SLIBDIR_SUFFIXES ; do
-           base_ml_dir=`echo ${suffix_pair} | sed -e 's/:.*$//' -e 's/=/$(EQ)/g'`
-           if [ "$dir" = "$base_ml_dir" ]; then
-             shlib_so_name=libgcc_s
-             shlib_slibdir_qual=`echo ${suffix_pair} | sed -e 's/^[^:]*://'`
-             break
-           else
-             canon_dir=`echo $dir | sed -n -e "s:$base_ml_dir/::p"`
-             if [ -n "$canon_dir" ]; then
-               shlib_so_name=libgcc_s_`echo $canon_dir | sed s,/,_,g`
-               shlib_slibdir_qual=`echo ${suffix_pair} | sed -e 's/^[^:]*://'`
-               break
-             fi
-           fi
-         done
        fi
-       if [ "$shlib_slibdir_qual" = none ]; then
-         for suffix_pair in $SHLIB_SLIBDIR_SUFFIXES ; do
-           base_ml_dir=`echo ${suffix_pair} | sed -e 's/:.*$//' -e 's/=/$(EQ)/g'`
-           shlib_slibdir_qual=`echo ${suffix_pair} | sed -e 's/^[^:]*://'`
-           for ml2 in $MULTILIBS; do
-             dir2=`echo ${ml2} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'`
-             if [ "$base_ml_dir" = "$dir2" ]; then
-               shlib_slibdir_qual=
-               break
-             fi
-           done
-           if [ -n "$shlib_slibdir_qual" ]; then break; fi
-         done
+       gcc_multilib_sup=`echo $gcc_multilib_dir | sed 's~^[^/]*/~~'`
+       os_multilib_base=`echo $os_multilib_dir | sed -n "s~/${gcc_multilib_sup}\$~~p"`
+       if [ -z "$os_multilib_base" ]; then
+         shlib_so_name=libgcc_s
+         if [ "$os_multilib_dir" != "." ]; then
+           shlib_slibdir_qual="/$os_multilib_dir"
+         fi
+       else
+         shlib_so_name=libgcc_s_`echo $gcc_multilib_sup | sed s,/,_,g`
+         shlib_slibdir_qual="/$os_multilib_base"
        fi
       fi
       echo "   $SHLIB_INSTALL" \