libsanitizer: Fix linkage errors for cross toolchains

Message ID AM0PR03MB48829C0D33B5B164343C782C82BD9@AM0PR03MB4882.eurprd03.prod.outlook.com
State New
Headers
Series libsanitizer: Fix linkage errors for cross toolchains |

Commit Message

Dimitrije Milošević July 1, 2022, 12:40 p.m. UTC
  When we use cross toolchains, in which the GCC libraries are not installed 
within a designated system root, the shared sanitizer libraries link against 
libstdc++.so* within the same libraries. This directory, however, is not in RPATH, 
so attempting to build a dynamically linked application with -fsanitize=... 
gives a linkage error.
More information can be found here: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69839.

GCC, even when configured with -with-sysroot, by default, doesn't install libstdc++.so*
within the sysroot, as GCC's installation process isn't designed to help construct sysroot trees.
This has to be done manually. 
Furthermore, if we are using a multiarch/multilib configuration (mips-mti*, for example), 
we may not even want to install them within the sysroot.
Would love to hear your thoughts on this, as I'm not sure myself that this is the best solution.

    gcc/ChangeLog:
    
            * gcc.cc (LIBSAN_RPATH): New macro.
            (LIBASAN_SPEC): Add LIBSAN_RPATH.
            (LIBTSAN_SPEC): Likewise.
            (LIBLSAN_SPEC): Likewise.
            (LIBUBSAN_SPEC): Likewise.
    
    libsanitizer/ChangeLog:
    
            * Makefile.in: New Makefile variable.
            * asan/Makefile.in: Likewise.
            * configure: Regenerate.
            * configure.ac: New config variable.
            * hwasan/Makefile.in: New Makefile variable.
            * interception/Makefile.in: Likewise.
            * libbacktrace/Makefile.in: Likewise.
            * libsanitizer.spec.in: New spec.
            * lsan/Makefile.in: New Makefile variable.
            * sanitizer_common/Makefile.in: Likewise.
            * tsan/Makefile.in: Likewise.
            * ubsan/Makefile.in: Likewise.

---

 gcc/gcc.cc                                | 20 ++++++++++++--------
 libsanitizer/Makefile.in                  |  1 +
 libsanitizer/asan/Makefile.in             |  1 +
 libsanitizer/configure                    | 10 ++++++++--
 libsanitizer/configure.ac                 |  7 +++++++
 libsanitizer/hwasan/Makefile.in           |  1 +
 libsanitizer/interception/Makefile.in     |  1 +
 libsanitizer/libbacktrace/Makefile.in     |  1 +
 libsanitizer/libsanitizer.spec.in         |  2 ++
 libsanitizer/lsan/Makefile.in             |  1 +
 libsanitizer/sanitizer_common/Makefile.in |  1 +
 libsanitizer/tsan/Makefile.in             |  1 +
 libsanitizer/ubsan/Makefile.in            |  1 +
 13 files changed, 38 insertions(+), 10 deletions(-)


---
  

Patch

diff --git a/gcc/gcc.cc b/gcc/gcc.cc
index 299e09c4f54..0d2d361b9a4 100644
--- a/gcc/gcc.cc
+++ b/gcc/gcc.cc
@@ -738,17 +738,21 @@  proper position among the other output files.  */
 #define STACK_SPLIT_SPEC " %{fsplit-stack: --wrap=pthread_create}"
 #endif
 
+#ifndef LIBSAN_RPATH
+#define LIBSAN_RPATH " %:include(libsanitizer.spec)%(link_libsan_rpath)"
+#endif
+
 #ifndef LIBASAN_SPEC
 #define STATIC_LIBASAN_LIBS \
   " %{static-libasan|static:%:include(libsanitizer.spec)%(link_libasan)}"
 #ifdef LIBASAN_EARLY_SPEC
-#define LIBASAN_SPEC STATIC_LIBASAN_LIBS
+#define LIBASAN_SPEC STATIC_LIBASAN_LIBS LIBSAN_RPATH
 #elif defined(HAVE_LD_STATIC_DYNAMIC)
 #define LIBASAN_SPEC "%{static-libasan:" LD_STATIC_OPTION \
                     "} -lasan %{static-libasan:" LD_DYNAMIC_OPTION "}" \
                     STATIC_LIBASAN_LIBS
 #else
-#define LIBASAN_SPEC "-lasan" STATIC_LIBASAN_LIBS
+#define LIBASAN_SPEC "-lasan" STATIC_LIBASAN_LIBS LIBSAN_RPATH
 #endif
 #endif
 
@@ -778,13 +782,13 @@  proper position among the other output files.  */
 #define STATIC_LIBTSAN_LIBS \
   " %{static-libtsan|static:%:include(libsanitizer.spec)%(link_libtsan)}"
 #ifdef LIBTSAN_EARLY_SPEC
-#define LIBTSAN_SPEC STATIC_LIBTSAN_LIBS
+#define LIBTSAN_SPEC STATIC_LIBTSAN_LIBS LIBSAN_RPATH
 #elif defined(HAVE_LD_STATIC_DYNAMIC)
 #define LIBTSAN_SPEC "%{static-libtsan:" LD_STATIC_OPTION \
                     "} -ltsan %{static-libtsan:" LD_DYNAMIC_OPTION "}" \
                     STATIC_LIBTSAN_LIBS
 #else
-#define LIBTSAN_SPEC "-ltsan" STATIC_LIBTSAN_LIBS
+#define LIBTSAN_SPEC "-ltsan" STATIC_LIBTSAN_LIBS LIBSAN_RPATH
 #endif
 #endif
 
@@ -796,13 +800,13 @@  proper position among the other output files.  */
 #define STATIC_LIBLSAN_LIBS \
   " %{static-liblsan|static:%:include(libsanitizer.spec)%(link_liblsan)}"
 #ifdef LIBLSAN_EARLY_SPEC
-#define LIBLSAN_SPEC STATIC_LIBLSAN_LIBS
+#define LIBLSAN_SPEC STATIC_LIBLSAN_LIBS LIBSAN_RPATH
 #elif defined(HAVE_LD_STATIC_DYNAMIC)
 #define LIBLSAN_SPEC "%{static-liblsan:" LD_STATIC_OPTION \
                     "} -llsan %{static-liblsan:" LD_DYNAMIC_OPTION "}" \
                     STATIC_LIBLSAN_LIBS
 #else
-#define LIBLSAN_SPEC "-llsan" STATIC_LIBLSAN_LIBS
+#define LIBLSAN_SPEC "-llsan" STATIC_LIBLSAN_LIBS LIBSAN_RPATH
 #endif
 #endif
 
@@ -816,9 +820,9 @@  proper position among the other output files.  */
 #ifdef HAVE_LD_STATIC_DYNAMIC
 #define LIBUBSAN_SPEC "%{static-libubsan:" LD_STATIC_OPTION \
                     "} -lubsan %{static-libubsan:" LD_DYNAMIC_OPTION "}" \
-                    STATIC_LIBUBSAN_LIBS
+                    STATIC_LIBUBSAN_LIBS LIBSAN_RPATH
 #else
-#define LIBUBSAN_SPEC "-lubsan" STATIC_LIBUBSAN_LIBS
+#define LIBUBSAN_SPEC "-lubsan" STATIC_LIBUBSAN_LIBS LIBSAN_RPATH
 #endif
 #endif
 
diff --git a/libsanitizer/Makefile.in b/libsanitizer/Makefile.in
index 65e7f2e9553..ef71407a512 100644
--- a/libsanitizer/Makefile.in
+++ b/libsanitizer/Makefile.in
@@ -333,6 +333,7 @@  libexecdir = @libexecdir@
 link_libasan = @link_libasan@
 link_libhwasan = @link_libhwasan@
 link_liblsan = @link_liblsan@
+link_libsan_rpath = @link_libsan_rpath@
 link_libtsan = @link_libtsan@
 link_libubsan = @link_libubsan@
 localedir = @localedir@
diff --git a/libsanitizer/asan/Makefile.in b/libsanitizer/asan/Makefile.in
index 7833a9a4c3f..143dafa450d 100644
--- a/libsanitizer/asan/Makefile.in
+++ b/libsanitizer/asan/Makefile.in
@@ -387,6 +387,7 @@  libexecdir = @libexecdir@
 link_libasan = @link_libasan@
 link_libhwasan = @link_libhwasan@
 link_liblsan = @link_liblsan@
+link_libsan_rpath = @link_libsan_rpath@
 link_libtsan = @link_libtsan@
 link_libubsan = @link_libubsan@
 localedir = @localedir@
diff --git a/libsanitizer/configure b/libsanitizer/configure
index 771b135573a..4408167929f 100755
--- a/libsanitizer/configure
+++ b/libsanitizer/configure
@@ -660,6 +660,7 @@  link_libubsan
 link_libtsan
 link_libhwasan
 link_libasan
+link_libsan_rpath
 HWASAN_SUPPORTED_FALSE
 HWASAN_SUPPORTED_TRUE
 LSAN_SUPPORTED_FALSE
@@ -12359,7 +12360,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 12362 "configure"
+#line 12363 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12465,7 +12466,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 12468 "configure"
+#line 12469 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -15935,6 +15936,11 @@  if test "x$ac_cv_lib_dl_dlsym" = xyes; then :
   link_sanitizer_common="-ldl $link_sanitizer_common"
 fi
 
+lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+if test -n "$with_cross_host" &&
+       test x"$with_cross_host" != x"no"; then
+    link_libsan_rpath="-rpath-link=%R/../${target_alias}/lib/$lt_multi_os_dir"
+fi
 
 # Set up the set of additional libraries that we need to link against for libasan.
 link_libasan=$link_sanitizer_common
diff --git a/libsanitizer/configure.ac b/libsanitizer/configure.ac
index 7f1ef3979c4..4c7c3814cf1 100644
--- a/libsanitizer/configure.ac
+++ b/libsanitizer/configure.ac
@@ -118,6 +118,13 @@  AC_CHECK_LIB(rt, shm_open,
 AC_CHECK_LIB(dl, dlsym,
   [link_sanitizer_common="-ldl $link_sanitizer_common"])
 
+lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+if test -n "$with_cross_host" &&
+       test x"$with_cross_host" != x"no"; then
+    link_libsan_rpath="-rpath-link=%R/../../${target_alias}/lib/$lt_multi_os_dir"
+fi
+AC_SUBST(link_libsan_rpath)
+
 # Set up the set of additional libraries that we need to link against for libasan.
 link_libasan=$link_sanitizer_common
 AC_SUBST(link_libasan)
diff --git a/libsanitizer/hwasan/Makefile.in b/libsanitizer/hwasan/Makefile.in
index b9b942003a3..cda1c944542 100644
--- a/libsanitizer/hwasan/Makefile.in
+++ b/libsanitizer/hwasan/Makefile.in
@@ -376,6 +376,7 @@  libexecdir = @libexecdir@
 link_libasan = @link_libasan@
 link_libhwasan = @link_libhwasan@
 link_liblsan = @link_liblsan@
+link_libsan_rpath = @link_libsan_rpath@
 link_libtsan = @link_libtsan@
 link_libubsan = @link_libubsan@
 localedir = @localedir@
diff --git a/libsanitizer/interception/Makefile.in b/libsanitizer/interception/Makefile.in
index 85dd386de47..a10851cd157 100644
--- a/libsanitizer/interception/Makefile.in
+++ b/libsanitizer/interception/Makefile.in
@@ -305,6 +305,7 @@  libexecdir = @libexecdir@
 link_libasan = @link_libasan@
 link_libhwasan = @link_libhwasan@
 link_liblsan = @link_liblsan@
+link_libsan_rpath = @link_libsan_rpath@
 link_libtsan = @link_libtsan@
 link_libubsan = @link_libubsan@
 localedir = @localedir@
diff --git a/libsanitizer/libbacktrace/Makefile.in b/libsanitizer/libbacktrace/Makefile.in
index c0243fa4aab..4c75070a6e3 100644
--- a/libsanitizer/libbacktrace/Makefile.in
+++ b/libsanitizer/libbacktrace/Makefile.in
@@ -355,6 +355,7 @@  libexecdir = @libexecdir@
 link_libasan = @link_libasan@
 link_libhwasan = @link_libhwasan@
 link_liblsan = @link_liblsan@
+link_libsan_rpath = @link_libsan_rpath@
 link_libtsan = @link_libtsan@
 link_libubsan = @link_libubsan@
 localedir = @localedir@
diff --git a/libsanitizer/libsanitizer.spec.in b/libsanitizer/libsanitizer.spec.in
index 70a33574d7b..1df604335d5 100644
--- a/libsanitizer/libsanitizer.spec.in
+++ b/libsanitizer/libsanitizer.spec.in
@@ -11,3 +11,5 @@ 
 
 *link_liblsan: @link_liblsan@
 
+*link_libsan_rpath: @link_libsan_rpath@
+
diff --git a/libsanitizer/lsan/Makefile.in b/libsanitizer/lsan/Makefile.in
index d8fd4ee9557..8f459b255d7 100644
--- a/libsanitizer/lsan/Makefile.in
+++ b/libsanitizer/lsan/Makefile.in
@@ -350,6 +350,7 @@  libexecdir = @libexecdir@
 link_libasan = @link_libasan@
 link_libhwasan = @link_libhwasan@
 link_liblsan = @link_liblsan@
+link_libsan_rpath = @link_libsan_rpath@
 link_libtsan = @link_libtsan@
 link_libubsan = @link_libubsan@
 localedir = @localedir@
diff --git a/libsanitizer/sanitizer_common/Makefile.in b/libsanitizer/sanitizer_common/Makefile.in
index 07047bd4b17..e916a803786 100644
--- a/libsanitizer/sanitizer_common/Makefile.in
+++ b/libsanitizer/sanitizer_common/Makefile.in
@@ -342,6 +342,7 @@  libexecdir = @libexecdir@
 link_libasan = @link_libasan@
 link_libhwasan = @link_libhwasan@
 link_liblsan = @link_liblsan@
+link_libsan_rpath = @link_libsan_rpath@
 link_libtsan = @link_libtsan@
 link_libubsan = @link_libubsan@
 localedir = @localedir@
diff --git a/libsanitizer/tsan/Makefile.in b/libsanitizer/tsan/Makefile.in
index 36498832bb8..ab8db13a268 100644
--- a/libsanitizer/tsan/Makefile.in
+++ b/libsanitizer/tsan/Makefile.in
@@ -379,6 +379,7 @@  libexecdir = @libexecdir@
 link_libasan = @link_libasan@
 link_libhwasan = @link_libhwasan@
 link_liblsan = @link_liblsan@
+link_libsan_rpath = @link_libsan_rpath@
 link_libtsan = @link_libtsan@
 link_libubsan = @link_libubsan@
 localedir = @localedir@
diff --git a/libsanitizer/ubsan/Makefile.in b/libsanitizer/ubsan/Makefile.in
index 92a8e387fd7..5fc063fe9ee 100644
--- a/libsanitizer/ubsan/Makefile.in
+++ b/libsanitizer/ubsan/Makefile.in
@@ -344,6 +344,7 @@  libexecdir = @libexecdir@
 link_libasan = @link_libasan@
 link_libhwasan = @link_libhwasan@
 link_liblsan = @link_liblsan@
+link_libsan_rpath = @link_libsan_rpath@
 link_libtsan = @link_libtsan@
 link_libubsan = @link_libubsan@
 localedir = @localedir@