From: Jakub Jelinek Date: Sat, 5 Oct 2002 21:32:10 +0000 (+0200) Subject: gcc.c (set_multilib_dir): Don't access *end. X-Git-Tag: releases/gcc-3.2.1~206 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=85f52bb4dd84ab835531a5169c06c7a9de91276d;p=thirdparty%2Fgcc.git gcc.c (set_multilib_dir): Don't access *end. * gcc.c (set_multilib_dir): Don't access *end. Use memcpy instead of strncpy. Don't write beyond malloced buffer. (print_multilib_info): Don't show paths starting with ".:". * genmultilib: Add new option, "yes" if multilibs are enabled. Update comments. If multilibs not enabled, print .:${osdirout} for each directory. If multilibs are enabled, always print ${dirout}:${osdirout}, even if the two are the same. * Makefile.in (s-mlib): Pass @enable_multilib@ to genmultilib. Pass all MULTILIB_* variables to genmultilib even if --disable-multilib but MULTILIB_OSDIRNAMES is not empty. * 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_SPEC32, STARTFILE_SPEC64): Remove. (STARTFILE_ARCH_SPEC): Remove. (STARTFILE_SPEC): Add values-X*.o here. * config/i386/t-linux64 (MULTILIB_OSDIRNAMES): Set. (SHLIB_SLIBDIR_SUFFIXES): Remove. * config/i386/linux64.h (STARTFILE_PREFIX_SPEC): Remove. (STARTFILE_SPEC, ENDFILE_SPEC): Don't distinguish between m32 and !m32. * config/mips/t-iris6 (MULTILIB_OSDIRNAMES): Set. (SHLIB_SLIBDIR_SUFFIXES): Remove. From-SVN: r57853 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bb6bcf22626e..70cd9af4e1db 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,73 @@ +2002-10-05 Jakub Jelinek + + * gcc.c (set_multilib_dir): Don't access *end. + Use memcpy instead of strncpy. Don't write beyond malloced buffer. + (print_multilib_info): Don't show paths starting with ".:". + * genmultilib: Add new option, "yes" if multilibs are enabled. + Update comments. If multilibs not enabled, print .:${osdirout} + for each directory. If multilibs are enabled, always print + ${dirout}:${osdirout}, even if the two are the same. + * Makefile.in (s-mlib): Pass @enable_multilib@ to genmultilib. + Pass all MULTILIB_* variables to genmultilib even if + --disable-multilib but MULTILIB_OSDIRNAMES is not empty. + + * 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_SPEC32, STARTFILE_SPEC64): Remove. + (STARTFILE_ARCH_SPEC): Remove. + (STARTFILE_SPEC): Add values-X*.o here. + * config/i386/t-linux64 (MULTILIB_OSDIRNAMES): Set. + (SHLIB_SLIBDIR_SUFFIXES): Remove. + * config/i386/linux64.h (STARTFILE_PREFIX_SPEC): Remove. + (STARTFILE_SPEC, ENDFILE_SPEC): Don't distinguish between m32 and + !m32. + * config/mips/t-iris6 (MULTILIB_OSDIRNAMES): Set. + (SHLIB_SLIBDIR_SUFFIXES): Remove. + 2002-10-05 Neil Booth PR preprocessor/8120 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index ebcbbc2b6af5..5afd30ef0467 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1003,7 +1003,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 @@ -1037,7 +1037,8 @@ libgcc.a: $(LIBGCC_DEPS) # switches. multilib.h: s-mlib; @true s-mlib: $(srcdir)/genmultilib Makefile - if test @enable_multilib@ = yes; then \ + if test @enable_multilib@ = yes \ + || test -n "$(MULTILIB_OSDIRNAMES)"; then \ $(SHELL) $(srcdir)/genmultilib \ "$(MULTILIB_OPTIONS)" \ "$(MULTILIB_DIRNAMES)" \ @@ -1045,9 +1046,12 @@ s-mlib: $(srcdir)/genmultilib Makefile "$(MULTILIB_EXCEPTIONS)" \ "$(MULTILIB_EXTRA_OPTS)" \ "$(MULTILIB_EXCLUSIONS)" \ + "$(MULTILIB_OSDIRNAMES)" \ + "@enable_multilib@" \ > tmp-mlib.h; \ else \ - $(SHELL) $(srcdir)/genmultilib '' '' '' '' '' '' > tmp-mlib.h; \ + $(SHELL) $(srcdir)/genmultilib '' '' '' '' '' '' '' no \ + > tmp-mlib.h; \ fi $(SHELL) $(srcdir)/move-if-change tmp-mlib.h multilib.h $(STAMP) s-mlib diff --git a/gcc/config/i386/linux64.h b/gcc/config/i386/linux64.h index 7ffbd0d07ea5..8a0bfbe925ad 100644 --- a/gcc/config/i386/linux64.h +++ b/gcc/config/i386/linux64.h @@ -48,29 +48,16 @@ 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 \ - "%{m32:%{!shared: \ - %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} \ - %{!p:%{profile:gcrt1.o%s} %{!profile:crt1.o%s}}}} \ - crti.o%s %{static:crtbeginT.o%s}\ - %{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}} \ - %{!m32:%{!shared: \ - %{pg:/usr/lib64/gcrt1.o%s} %{!pg:%{p:/usr/lib64/gcrt1.o%s} \ - %{!p:%{profile:/usr/lib64/gcrt1.o%s} %{!profile:/usr/lib64/crt1.o%s}}}}\ - /usr/lib64/crti.o%s %{static:crtbeginT.o%s} \ - %{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}}" + "%{!shared: \ + %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} \ + %{!p:%{profile:gcrt1.o%s} %{!profile:crt1.o%s}}}} \ + crti.o%s %{static:crtbeginT.o%s} \ + %{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}" #undef ENDFILE_SPEC -#define ENDFILE_SPEC "\ - %{m32:%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s} \ - %{!m32:%{!shared:crtend.o%s} %{shared:crtendS.o%s} /usr/lib64/crtn.o%s}" +#define ENDFILE_SPEC "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s" #define MULTILIB_DEFAULTS { "m64" } diff --git a/gcc/config/i386/t-linux64 b/gcc/config/i386/t-linux64 index 46a7caadf772..31b6ad463862 100644 --- a/gcc/config/i386/t-linux64 +++ b/gcc/config/i386/t-linux64 @@ -6,10 +6,9 @@ SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \ MULTILIB_OPTIONS = m64/m32 MULTILIB_DIRNAMES = 64 32 +MULTILIB_OSDIRNAMES = ../lib64 ../lib 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: diff --git a/gcc/config/mips/t-iris6 b/gcc/config/mips/t-iris6 index 4a8d6be3cd1b..f0bee5a2be79 100644 --- a/gcc/config/mips/t-iris6 +++ b/gcc/config/mips/t-iris6 @@ -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 @@ -22,7 +23,6 @@ SHLIB_NAME = @shlib_dir@@shlib_so_name@.so.1 SHLIB_MAP = @shlib_map_file@ SHLIB_OBJS = @shlib_objs@ SHLIB_SLIBDIR_QUAL = @shlib_slibdir_qual@ -SHLIB_SLIBDIR_SUFFIXES = mabi=64:/mabi=64 mabi=n32: SHLIB_LINK = $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -shared -nodefaultlibs \ -Wl,-soname,$(SHLIB_SONAME) \ diff --git a/gcc/config/sparc/linux64.h b/gcc/config/sparc/linux64.h index 4e929162c426..c7d8f491166b 100644 --- a/gcc/config/sparc/linux64.h +++ b/gcc/config/sparc/linux64.h @@ -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. @@ -56,38 +56,12 @@ Boston, MA 02111-1307, USA. */ #undef STARTFILE_SPEC -#define STARTFILE_SPEC32 \ +#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 @@ -96,36 +70,9 @@ Boston, MA 02111-1307, USA. */ #undef ENDFILE_SPEC -#define ENDFILE_SPEC32 \ - "%{!shared:crtend.o%s} %{shared:crtendS.o%s} 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 diff --git a/gcc/config/sparc/sol2-bi.h b/gcc/config/sparc/sol2-bi.h index 9828d634c915..e19e88810736 100644 --- a/gcc/config/sparc/sol2-bi.h +++ b/gcc/config/sparc/sol2-bi.h @@ -72,30 +72,6 @@ %{!mcpu*:%(asm_cpu_default)} \ " -#define STARTFILE_SPEC32 "\ -%{ansi:values-Xc.o%s} \ -%{!ansi: \ - %{traditional:values-Xt.o%s} \ - %{!traditional:values-Xa.o%s}}" - -#define STARTFILE_SPEC64 "\ -%{ansi:/usr/lib/sparcv9/values-Xc.o%s} \ -%{!ansi: \ - %{traditional:/usr/lib/sparcv9/values-Xt.o%s} \ - %{!traditional:/usr/lib/sparcv9/values-Xa.o%s}}" - -#if DEFAULT_ARCH32_P -#define STARTFILE_ARCH_SPEC "\ -%{m32:" STARTFILE_SPEC32 "} \ -%{m64:" STARTFILE_SPEC64 "} \ -%{!m32:%{!m64:" STARTFILE_SPEC32 "}}" -#else -#define STARTFILE_ARCH_SPEC "\ -%{m32:" STARTFILE_SPEC32 "} \ -%{m64:" STARTFILE_SPEC64 "} \ -%{!m32:%{!m64:" STARTFILE_SPEC64 "}}" -#endif - #undef STARTFILE_SPEC #define STARTFILE_SPEC "%{!shared: \ %{!symbolic: \ @@ -103,7 +79,10 @@ %{!p: \ %{pg:gcrt1.o%s gmon.o%s} \ %{!pg:crt1.o%s}}}} \ - crti.o%s " STARTFILE_ARCH_SPEC " \ + crti.o%s \ + %{ansi:values-Xc.o%s} \ + %{!ansi: %{traditional:values-Xt.o%s} \ + %{!traditional:values-Xa.o%s}} \ crtbegin.o%s" #undef CPP_CPU_DEFAULT_SPEC diff --git a/gcc/config/sparc/t-linux64 b/gcc/config/sparc/t-linux64 index a64862638355..5b6603334f0a 100644 --- a/gcc/config/sparc/t-linux64 +++ b/gcc/config/sparc/t-linux64 @@ -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. diff --git a/gcc/config/sparc/t-sol2-64 b/gcc/config/sparc/t-sol2-64 index 39204d7368fe..3c15f0a712a1 100644 --- a/gcc/config/sparc/t-sol2-64 +++ b/gcc/config/sparc/t-sol2-64 @@ -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: diff --git a/gcc/gcc.c b/gcc/gcc.c index 96045167492e..cf86f9bc2f22 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -172,6 +172,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. */ @@ -285,9 +290,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 *)); @@ -963,6 +969,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}, @@ -1248,7 +1255,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 @@ -1337,6 +1346,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 @@ -1390,6 +1404,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), @@ -1832,7 +1847,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; } @@ -1851,7 +1866,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) @@ -2480,16 +2495,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) @@ -2504,6 +2520,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). */ @@ -2519,6 +2551,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. @@ -2527,7 +2562,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) { @@ -2537,10 +2572,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) @@ -2559,7 +2594,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) { @@ -2571,7 +2606,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) @@ -2589,7 +2624,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) { @@ -2600,7 +2635,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) @@ -2638,13 +2673,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; @@ -2666,6 +2703,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; @@ -2709,7 +2747,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; @@ -2723,7 +2761,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++; @@ -3041,6 +3080,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); @@ -3202,9 +3242,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 @@ -3232,10 +3272,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; @@ -3267,7 +3307,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; @@ -3300,7 +3340,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; @@ -3401,6 +3441,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; @@ -3570,7 +3612,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); @@ -3578,16 +3620,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; @@ -3760,17 +3802,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); @@ -3793,11 +3835,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, @@ -3807,10 +3849,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. */ @@ -3860,6 +3902,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")) @@ -4363,9 +4407,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) @@ -4388,14 +4437,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); } @@ -5616,11 +5665,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. */ @@ -5628,7 +5675,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; } @@ -5863,7 +5910,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); @@ -5888,18 +5935,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 @@ -5907,28 +5954,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 @@ -5938,14 +5985,15 @@ 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); } /* 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); } @@ -5987,7 +6035,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); } @@ -6007,6 +6055,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. */ @@ -6166,7 +6223,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"; } @@ -6460,6 +6517,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. */ @@ -6525,8 +6591,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); @@ -6542,6 +6609,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++) @@ -6556,25 +6674,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; } @@ -6596,8 +6700,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') @@ -6652,6 +6799,7 @@ set_multilib_dir () ++p; } + first = 1; p = multilib_select; while (*p != '\0') { @@ -6674,6 +6822,7 @@ set_multilib_dir () /* Check the arguments. */ ok = 1; + ndfltok = 1; ++p; while (*p != ';') { @@ -6709,32 +6858,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 @@ -6774,6 +6956,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. */ @@ -6915,7 +7103,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 (';'); } diff --git a/gcc/genmultilib b/gcc/genmultilib index 3cbfaa1ebab2..ca3b71bdfa3d 100644 --- a/gcc/genmultilib +++ b/gcc/genmultilib @@ -63,6 +63,14 @@ # 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 last option should be "yes" if multilibs are enabled. If it is not +# "yes", all GCC multilib dir names will be ".". + # The output looks like # #define MULTILIB_MATCHES "\ # SUBDIRECTORY OPTIONS;\ @@ -79,17 +87,18 @@ # 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' yes # 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 +115,8 @@ matches=$3 exceptions=$4 extra=$5 exclusions=$6 +osdirnames=$7 +enable_multilib=$8 echo "static const char *const multilib_raw[] = {" @@ -202,6 +213,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 +291,25 @@ 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${enable_multilib}" != xyes ]; then + dirout=".:${osdirout}" + else + dirout="${dirout}:${osdirout}" + fi + else + if [ "x${enable_multilib}" != xyes ]; then + # genmultilib with --disable-multilib should be + # called with '' '' '' '' '' '' '' no + # if MULTILIB_OSDIRNAMES is empty. + exit 1 + 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 +366,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 diff --git a/gcc/mklibgcc.in b/gcc/mklibgcc.in index c5db6f0a0393..30f660c4be1a 100644 --- a/gcc/mklibgcc.in +++ b/gcc/mklibgcc.in @@ -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" \