Resent with the patch expanded correctly (I guess, it wasn't because of UTF-8 encoding...).
Hi everyone, Since noone answered, I assume that MULTILIB_REUSE was indeed not the solution. Thus, I've implemented a solution using a new target macro MULTILIB_FALLBACK. It allows any target to return a new multilib suffix based on the current one being used by the algorithm. This solution is much simpler than adding a new Makefile option like MULTILIB_REUSE and it allows targets to fully control the new suffix, which can be an advantage. However, this solution is not perfect. Especially, MULTILIB_FALLBACK must take care of freeing "curr_multilib_dir" array, which might not be the best thing to do. But letting "for_each_path" doing it is created a much more complex code, which isn't better in my opinion. Anyway, is a patch like the following one seems possible to be integrated or should I search for a better solution ? Thanks, Clément ----------------------------------------------------------------- >From 73efb4cc50a221ed45a4d44c06157fcf9124e320 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Chigot?= <clement.chi...@atos.net> Date: Mon, 12 Oct 2020 11:37:13 +0200 Subject: [PATCH] gcc: implement multilib fallbacks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some targets needs to be able to fallback from multilib A to multilib B if multilib A isn't available at runtime. Currently, the searched paths generated by gcc only include a single multilib suffix and the default library. This patch adds MULTILIB_FALLBACK macro to allow targets to get extra multlib suffixes in these paths. gcc/ChangeLog: 2020-10-12 Clément Chigot <clement.chi...@atos.net> * config/rs6000/aix.h (MULTILIB_FALLBACK): New Define * gcc.c (for_each_path): Allow several multilib suffixes to be tried, based on MULTILIB_FALLBACK macro. --- gcc/config/rs6000/aix.h | 21 +++++++++++++++ gcc/gcc.c | 60 ++++++++++++++++++++++++++++++----------- 2 files changed, 66 insertions(+), 15 deletions(-) diff --git a/gcc/config/rs6000/aix.h b/gcc/config/rs6000/aix.h index edd6fdb0ec2..9cff6a67e1c 100644 --- a/gcc/config/rs6000/aix.h +++ b/gcc/config/rs6000/aix.h @@ -280,3 +280,24 @@ /* Use standard DWARF numbering for DWARF debugging information. */ #define RS6000_USE_DWARF_NUMBERING +/* Threaded programs must be able to fallback on pthread FAT library + if their architecture directory isn't present. This is happening + when a 32bit program built with a 64-bit gcc is running on a 32bit + runtime. */ +#define MULTILIB_FALLBACK(CURR_MULTILIB) \ + do \ + { \ + if (!strcmp (CURR_MULTILIB, "pthread/ppc64") \ + || !(strcmp (CURR_MULTILIB, "pthread/ppc32"))) \ + { \ + free (CONST_CAST (char *, CURR_MULTILIB)); \ + CURR_MULTILIB = XNEWVEC (char, strlen ("pthread") + 1); \ + strcpy (CURR_MULTILIB, "pthread"); \ + } \ + else \ + { \ + free (CONST_CAST (char *, CURR_MULTILIB)); \ + CURR_MULTILIB = NULL; \ + } \ + } \ + while (0) diff --git a/gcc/gcc.c b/gcc/gcc.c index ff7b6c4a320..6bee64dbec9 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -2683,11 +2683,12 @@ clear_failure_queue (void) /* Call CALLBACK for each path in PATHS, breaking out early if CALLBACK returns non-NULL. - If DO_MULTI is true iterate over the paths twice, first with multilib - suffix then without, otherwise iterate over the paths once without - adding a multilib suffix. When DO_MULTI is true, some attempt is made - to avoid visiting the same path twice, but we could do better. For - instance, /usr/lib/../lib is considered different from /usr/lib. + If DO_MULTI is true iterate over the paths at least twice, first with + multilib suffixes then without any, otherwise iterate over the paths + once without adding a multilib suffix. When DO_MULTI is true, some + attempt is made to avoid visiting the same path twice, but we could + do better. For instance, /usr/lib/../lib is considered different + from /usr/lib. At least EXTRA_SPACE chars past the end of the path passed to CALLBACK are available for use by the callback. CALLBACK_INFO allows extra parameters to be passed to CALLBACK. @@ -2712,11 +2713,18 @@ for_each_path (const struct path_prefix *paths, bool skip_multi_dir = false; bool skip_multi_os_dir = false; + char *curr_multilib_dir = NULL; + if (do_multi && multilib_dir) + { + curr_multilib_dir = XNEWVEC (char, strlen (multilib_dir)); + strcpy (curr_multilib_dir, multilib_dir); + } + multi_suffix = machine_suffix; just_multi_suffix = just_machine_suffix; - if (do_multi && multilib_dir && strcmp (multilib_dir, ".") != 0) + if (do_multi && curr_multilib_dir && strcmp (curr_multilib_dir, ".") != 0) { - multi_dir = concat (multilib_dir, dir_separator_str, NULL); + multi_dir = concat (curr_multilib_dir, dir_separator_str, NULL); multi_suffix = concat (multi_suffix, multi_dir, NULL); just_multi_suffix = concat (just_multi_suffix, multi_dir, NULL); } @@ -2819,17 +2827,39 @@ for_each_path (const struct path_prefix *paths, if (multi_dir == NULL && multi_os_dir == NULL) break; - /* Run through the paths again, this time without multilibs. + /* Run through the paths again, this time with a new + multilib suffix or without any. Don't repeat any we have already seen. */ if (multi_dir) { - free (CONST_CAST (char *, multi_dir)); - multi_dir = NULL; - free (CONST_CAST (char *, multi_suffix)); - multi_suffix = machine_suffix; - free (CONST_CAST (char *, just_multi_suffix)); - just_multi_suffix = just_machine_suffix; - } + +#ifdef MULTILIB_FALLBACK + /* Retrieve the next multilib to be tried. */ + if (curr_multilib_dir) + MULTILIB_FALLBACK (curr_multilib_dir); +#else + free (curr_multilib_dir); + curr_multilib_dir = NULL; +#endif + if (curr_multilib_dir) + { + free (CONST_CAST (char *, multi_dir)); + multi_dir = concat (curr_multilib_dir, dir_separator_str, NULL); + free (CONST_CAST (char *, multi_suffix)); + multi_suffix = concat (machine_suffix, multi_dir, NULL); + free (CONST_CAST (char *, just_multi_suffix)); + just_multi_suffix = concat (just_machine_suffix, multi_dir, NULL); + } + else + { + free (CONST_CAST (char *, multi_dir)); + multi_dir = NULL; + free (CONST_CAST (char *, multi_suffix)); + multi_suffix = machine_suffix; + free (CONST_CAST (char *, just_multi_suffix)); + just_multi_suffix = just_machine_suffix; + } + } else skip_multi_dir = true; if (multi_os_dir) -- 2.25.1