Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[nsan] Add shared runtime #98415

Merged
merged 4 commits into from
Jul 11, 2024
Merged

Conversation

MaskRay
Copy link
Member

@MaskRay MaskRay commented Jul 10, 2024

so that clang -fsanitize=numerical -shared-libsan will use
libclang_rt.nsan.so on Linux.

Shared runtime is preferred for some platforms (Android, Apple, Fuchsia;
though they are not supported yet) and helps plugin use cases (#98302).

  • Update ninja nsan to build libclang_rt.nsan.so
  • Fix nsan.syms.extra: nsan_* is unneeded. Add __ubsan_* so that
    -fsanitize=numerical,undefined -shared-libsan works.
  • Move allocation functions to nsan_malloc_linux.cpp. While Apple
    platforms aren't supported yet, this separation makes it easier to add
    Apple support.
  • Delete interceptors for very obsoleted pvalloc/valloc but retain
    memalign.
  • Replace HandleEarlyAlloc with DlsymAlloc.

Created using spr 1.3.5-bogner
@llvmbot llvmbot added clang Clang issues not falling into any other category compiler-rt clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' compiler-rt:sanitizer labels Jul 10, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Jul 10, 2024

@llvm/pr-subscribers-compiler-rt-sanitizer
@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-driver

Author: Fangrui Song (MaskRay)

Changes

so that clang -fsanitize=numerical -shared-libsan will use
libclang_rt.nsan.so on Linux.

Shared runtime is preferred for some platforms (Android, Apple, Fuchsia;
though they are not supported yet) and helps plugin use cases (#98302).

  • Update ninja nsan to build libclang_rt.nsan.so
  • Fix nsan.syms.extra: nsan_* is unneeded. Add __ubsan_* so that
    -fsanitize=numerical,undefined -shared-libsan works.
  • Move allocation functions to nsan_malloc_linux.cpp. While Apple
    platforms aren't supported yet, this separation makes it easier to add
    Apple support.

Note: The driver change will be pushed as a separate commit.


Full diff: https://github.com/llvm/llvm-project/pull/98415.diff

8 Files Affected:

  • (modified) clang/lib/Driver/SanitizerArgs.cpp (+2-2)
  • (modified) clang/lib/Driver/ToolChains/CommonArgs.cpp (+3-1)
  • (modified) clang/test/Driver/sanitizer-ld.c (+18)
  • (modified) compiler-rt/lib/nsan/CMakeLists.txt (+91-22)
  • (modified) compiler-rt/lib/nsan/nsan.h (+1)
  • (modified) compiler-rt/lib/nsan/nsan.syms.extra (+1-1)
  • (modified) compiler-rt/lib/nsan/nsan_interceptors.cpp (+2-113)
  • (added) compiler-rt/lib/nsan/nsan_malloc_linux.cpp (+137)
diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp
index 86825a6ccf7a1..1fd870b72286e 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -285,8 +285,8 @@ bool SanitizerArgs::needsFuzzerInterceptors() const {
 
 bool SanitizerArgs::needsUbsanRt() const {
   // All of these include ubsan.
-  if (needsAsanRt() || needsMsanRt() || needsHwasanRt() || needsTsanRt() ||
-      needsDfsanRt() || needsLsanRt() || needsCfiDiagRt() ||
+  if (needsAsanRt() || needsMsanRt() || needsNsanRt() || needsHwasanRt() ||
+      needsTsanRt() || needsDfsanRt() || needsLsanRt() || needsCfiDiagRt() ||
       (needsScudoRt() && !requiresMinimalRuntime()))
     return false;
 
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index ab1590104b790..80a2b2bf31183 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1409,6 +1409,8 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
       if (!Args.hasArg(options::OPT_shared) && !TC.getTriple().isAndroid())
         HelperStaticRuntimes.push_back("memprof-preinit");
     }
+    if (SanArgs.needsNsanRt())
+      SharedRuntimes.push_back("nsan");
     if (SanArgs.needsUbsanRt()) {
       if (SanArgs.requiresMinimalRuntime())
         SharedRuntimes.push_back("ubsan_minimal");
@@ -1479,7 +1481,7 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
     if (SanArgs.linkCXXRuntimes())
       StaticRuntimes.push_back("msan_cxx");
   }
-  if (SanArgs.needsNsanRt())
+  if (!SanArgs.needsSharedRt() && SanArgs.needsNsanRt())
     StaticRuntimes.push_back("nsan");
   if (!SanArgs.needsSharedRt() && SanArgs.needsTsanRt()) {
     StaticRuntimes.push_back("tsan");
diff --git a/clang/test/Driver/sanitizer-ld.c b/clang/test/Driver/sanitizer-ld.c
index e215c034070e0..48e4ea1f7dcb5 100644
--- a/clang/test/Driver/sanitizer-ld.c
+++ b/clang/test/Driver/sanitizer-ld.c
@@ -646,6 +646,24 @@
 // CHECK-NSAN-LINUX: libclang_rt.nsan.a"
 // CHECK-NSAN-LINUX: "-lpthread" "-lrt" "-lm" "-ldl" "-lresolv"
 
+// RUN: %clang -### %s 2>&1 --target=x86_64-unknown-linux -fuse-ld=ld -fsanitize=numerical -shared-libsan \
+// RUN:     -resource-dir=%S/Inputs/resource_dir \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-NSAN-SHARED-LINUX %s
+
+// CHECK-NSAN-SHARED-LINUX: libclang_rt.nsan.so"
+// CHECK-NSAN-SHARED-LINUX-NOT: "-lpthread"
+// CHECK-NSAN-SHARED-LINUX-NOT: "-ldl"
+// CHECK-NSAN-SHARED-LINUX-NOT: "--dynamic-list
+
+// RUN: %clang -### %s 2>&1 --target=x86_64-unknown-linux -fsanitize=numerical,undefined \
+// RUN:     -resource-dir=%S/Inputs/resource_dir \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-NSAN-UBSAN %s
+
+// CHECK-NSAN-UBSAN: "--whole-archive" "{{[^"]*}}libclang_rt.nsan.a" "--no-whole-archive"
+// CHECK-NSAN-UBSAN-NOT: libclang_rt.ubsan
+
 // CFI by itself does not link runtime libraries.
 // RUN: not %clang -fsanitize=cfi -### %s 2>&1 \
 // RUN:     --target=x86_64-unknown-linux -fuse-ld=ld -rtlib=platform \
diff --git a/compiler-rt/lib/nsan/CMakeLists.txt b/compiler-rt/lib/nsan/CMakeLists.txt
index aef9b651ab2ec..d67c3ac434d3a 100644
--- a/compiler-rt/lib/nsan/CMakeLists.txt
+++ b/compiler-rt/lib/nsan/CMakeLists.txt
@@ -6,6 +6,7 @@ set(NSAN_SOURCES
   nsan.cpp
   nsan_flags.cpp
   nsan_interceptors.cpp
+  nsan_malloc_linux.cpp
   nsan_stats.cpp
   nsan_suppressions.cpp
 )
@@ -24,30 +25,98 @@ append_list_if(COMPILER_RT_HAS_FPIC_FLAG -fPIC NSAN_CFLAGS)
 set(NSAN_DYNAMIC_LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS})
 
 set(NSAN_CFLAGS ${SANITIZER_COMMON_CFLAGS})
+set(NSAN_DYNAMIC_CFLAGS ${NSAN_CFLAGS})
 
-foreach(arch ${NSAN_SUPPORTED_ARCH})
-  add_compiler_rt_runtime(
-    clang_rt.nsan
-    STATIC
-    ARCHS ${arch}
-    SOURCES ${NSAN_SOURCES}
-            $<TARGET_OBJECTS:RTInterception.${arch}>
-            $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
-            $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
-            $<TARGET_OBJECTS:RTSanitizerCommonCoverage.${arch}>
-            $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>
-            $<TARGET_OBJECTS:RTUbsan.${arch}>
-    ADDITIONAL_HEADERS ${NSAN_HEADERS}
-    CFLAGS ${NSAN_CFLAGS}
-    PARENT_TARGET nsan
-  )
-endforeach()
-
-add_compiler_rt_object_libraries(RTNsan
+set(NSAN_COMMON_RUNTIME_OBJECT_LIBS
+  RTInterception
+  RTSanitizerCommon
+  RTSanitizerCommonLibc
+  RTSanitizerCommonCoverage
+  RTSanitizerCommonSymbolizer
+  RTSanitizerCommonSymbolizerInternal
+  RTUbsan)
+
+set(NSAN_DYNAMIC_LIBS
+  ${COMPILER_RT_UNWINDER_LINK_LIBS}
+  ${SANITIZER_CXX_ABI_LIBRARIES}
+  ${SANITIZER_COMMON_LINK_LIBS})
+
+append_list_if(COMPILER_RT_HAS_LIBDL dl NSAN_DYNAMIC_LIBS)
+append_list_if(COMPILER_RT_HAS_LIBRT rt NSAN_DYNAMIC_LIBS)
+append_list_if(COMPILER_RT_HAS_LIBM m NSAN_DYNAMIC_LIBS)
+append_list_if(COMPILER_RT_HAS_LIBPTHREAD pthread NSAN_DYNAMIC_LIBS)
+
+# Compile sources into an object library.
+
+add_compiler_rt_object_libraries(RTNsan_dynamic
+  ARCHS ${NSAN_SUPPORTED_ARCH}
+  SOURCES ${NSAN_SOURCES}
+  ADDITIONAL_HEADERS ${NSAN_HEADERS}
+  CFLAGS ${NSAN_CFLAGS})
+
+if(NOT APPLE)
+  add_compiler_rt_object_libraries(RTNsan
+      ARCHS ${NSAN_SUPPORTED_ARCH}
+      SOURCES ${NSAN_SOURCES}
+      ADDITIONAL_HEADERS ${NSAN_HEADERS}
+      CFLAGS ${NSAN_CFLAGS})
+
+  file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp "")
+  add_compiler_rt_object_libraries(RTNsan_dynamic_version_script_dummy
     ARCHS ${NSAN_SUPPORTED_ARCH}
-    SOURCES ${NSAN_SOURCES}
-    ADDITIONAL_HEADERS ${NSAN_HEADERS}
-    CFLAGS ${NSAN_CFLAGS})
+    SOURCES ${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp
+    CFLAGS ${NSAN_DYNAMIC_CFLAGS})
+endif()
+
+add_compiler_rt_runtime(
+  clang_rt.nsan
+  STATIC
+  ARCHS ${NSAN_SUPPORTED_ARCH}
+  OBJECT_LIBS RTNsan
+              ${NSAN_COMMON_RUNTIME_OBJECT_LIBS}
+  CFLAGS ${NSAN_CFLAGS}
+  PARENT_TARGET nsan)
+
+if(NOT APPLE)
+  foreach(arch ${NSAN_SUPPORTED_ARCH})
+    if (COMPILER_RT_HAS_VERSION_SCRIPT)
+      add_sanitizer_rt_version_list(clang_rt.nsan-dynamic-${arch}
+                                    LIBS clang_rt.nsan-${arch}
+                                    EXTRA nsan.syms.extra)
+      set(VERSION_SCRIPT_FLAG
+           -Wl,--version-script,${CMAKE_CURRENT_BINARY_DIR}/clang_rt.nsan-dynamic-${arch}.vers)
+      # The Solaris 11.4 linker supports a subset of GNU ld version scripts,
+      # but requires a special option to enable it.
+      if (COMPILER_RT_HAS_GNU_VERSION_SCRIPT_COMPAT)
+          list(APPEND VERSION_SCRIPT_FLAG -Wl,-z,gnu-version-script-compat)
+      endif()
+      set_property(SOURCE
+        ${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp
+        APPEND PROPERTY
+        OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/clang_rt.nsan-dynamic-${arch}.vers)
+    else()
+      set(VERSION_SCRIPT_FLAG)
+    endif()
+
+    add_compiler_rt_runtime(
+      clang_rt.nsan
+      SHARED
+      ARCHS ${arch}
+      OBJECT_LIBS ${NSAN_COMMON_RUNTIME_OBJECT_LIBS}
+        RTNsan_dynamic
+        # The only purpose of RTNsan_dynamic_version_script_dummy is to
+        # carry a dependency of the shared runtime on the version script.
+        # Replacing it with a straightforward
+        # add_dependencies(clang_rt.nsan-dynamic-${arch} clang_rt.nsan-dynamic-${arch}-version-list)
+        # generates an order-only dependency in ninja.
+        RTNsan_dynamic_version_script_dummy
+      CFLAGS ${NSAN_DYNAMIC_CFLAGS}
+      LINK_FLAGS ${NSAN_DYNAMIC_LINK_FLAGS}
+        ${VERSION_SCRIPT_FLAG}
+      LINK_LIBS ${NSAN_DYNAMIC_LIBS}
+      PARENT_TARGET nsan)
+  endforeach()
+endif()
 
 if(COMPILER_RT_INCLUDE_TESTS)
   add_subdirectory(tests)
diff --git a/compiler-rt/lib/nsan/nsan.h b/compiler-rt/lib/nsan/nsan.h
index 896e5379dfc37..0fb998b049854 100644
--- a/compiler-rt/lib/nsan/nsan.h
+++ b/compiler-rt/lib/nsan/nsan.h
@@ -55,6 +55,7 @@ extern bool nsan_initialized;
 extern bool nsan_init_is_running;
 
 void InitializeInterceptors();
+void InitializeMallocInterceptors();
 
 // See notes in nsan_platform.
 // printf-free (see comment in nsan_interceptors.cc).
diff --git a/compiler-rt/lib/nsan/nsan.syms.extra b/compiler-rt/lib/nsan/nsan.syms.extra
index f3be6d39736b7..53ce5833520b8 100644
--- a/compiler-rt/lib/nsan/nsan.syms.extra
+++ b/compiler-rt/lib/nsan/nsan.syms.extra
@@ -1,2 +1,2 @@
-nsan_*
 __nsan_*
+__ubsan_*
diff --git a/compiler-rt/lib/nsan/nsan_interceptors.cpp b/compiler-rt/lib/nsan/nsan_interceptors.cpp
index 68127f169ee46..544b44f53cc42 100644
--- a/compiler-rt/lib/nsan/nsan_interceptors.cpp
+++ b/compiler-rt/lib/nsan/nsan_interceptors.cpp
@@ -1,4 +1,4 @@
-//===-- nsan_interceptors.cc ----------------------------------------------===//
+//===- nsan_interceptors.cpp ----------------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -29,26 +29,8 @@ using namespace __sanitizer;
 using __nsan::nsan_init_is_running;
 using __nsan::nsan_initialized;
 
-constexpr uptr kEarlyAllocBufSize = 16384;
-static uptr allocated_bytes;
-static char early_alloc_buf[kEarlyAllocBufSize];
-
-static bool isInEarlyAllocBuf(const void *ptr) {
-  return ((uptr)ptr >= (uptr)early_alloc_buf &&
-          ((uptr)ptr - (uptr)early_alloc_buf) < sizeof(early_alloc_buf));
-}
-
 template <typename T> T min(T a, T b) { return a < b ? a : b; }
 
-// Handle allocation requests early (before all interceptors are setup). dlsym,
-// for example, calls calloc.
-static void *HandleEarlyAlloc(uptr size) {
-  void *Mem = (void *)&early_alloc_buf[allocated_bytes];
-  allocated_bytes += size;
-  CHECK_LT(allocated_bytes, kEarlyAllocBufSize);
-  return Mem;
-}
-
 INTERCEPTOR(void *, memset, void *dst, int v, uptr size) {
   // NOTE: This guard is needed because nsan's initialization code might call
   // memset.
@@ -105,90 +87,6 @@ INTERCEPTOR(wchar_t *, wmemcpy, wchar_t *dst, const wchar_t *src, uptr size) {
   return res;
 }
 
-INTERCEPTOR(void *, malloc, uptr size) {
-  // NOTE: This guard is needed because nsan's initialization code might call
-  // malloc.
-  if (nsan_init_is_running && REAL(malloc) == nullptr)
-    return HandleEarlyAlloc(size);
-
-  void *res = REAL(malloc)(size);
-  if (res)
-    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
-  return res;
-}
-
-INTERCEPTOR(void *, realloc, void *ptr, uptr size) {
-  void *res = REAL(realloc)(ptr, size);
-  // FIXME: We might want to copy the types from the original allocation
-  // (although that would require that we know its size).
-  if (res)
-    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
-  return res;
-}
-
-INTERCEPTOR(void *, calloc, uptr Nmemb, uptr size) {
-  // NOTE: This guard is needed because nsan's initialization code might call
-  // calloc.
-  if (nsan_init_is_running && REAL(calloc) == nullptr) {
-    // Note: EarlyAllocBuf is initialized with zeros.
-    return HandleEarlyAlloc(Nmemb * size);
-  }
-
-  void *res = REAL(calloc)(Nmemb, size);
-  if (res)
-    __nsan_set_value_unknown(static_cast<u8 *>(res), Nmemb * size);
-  return res;
-}
-
-INTERCEPTOR(void, free, void *P) {
-  // There are only a few early allocation requests, so we simply skip the free.
-  if (isInEarlyAllocBuf(P))
-    return;
-  REAL(free)(P);
-}
-
-INTERCEPTOR(void *, valloc, uptr size) {
-  void *const res = REAL(valloc)(size);
-  if (res)
-    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
-  return res;
-}
-
-INTERCEPTOR(void *, memalign, uptr align, uptr size) {
-  void *const res = REAL(memalign)(align, size);
-  if (res)
-    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
-  return res;
-}
-
-INTERCEPTOR(void *, __libc_memalign, uptr align, uptr size) {
-  void *const res = REAL(__libc_memalign)(align, size);
-  if (res)
-    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
-  return res;
-}
-
-INTERCEPTOR(void *, pvalloc, uptr size) {
-  void *const res = REAL(pvalloc)(size);
-  if (res)
-    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
-  return res;
-}
-
-INTERCEPTOR(void *, aligned_alloc, uptr align, uptr size) {
-  void *const res = REAL(aligned_alloc)(align, size);
-  if (res)
-    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
-  return res;
-}
-
-INTERCEPTOR(int, posix_memalign, void **memptr, uptr align, uptr size) {
-  int res = REAL(posix_memalign)(memptr, align, size);
-  if (res == 0 && *memptr)
-    __nsan_set_value_unknown(static_cast<u8 *>(*memptr), size);
-  return res;
-}
-
 INTERCEPTOR(char *, strfry, char *s) {
   const auto Len = internal_strlen(s);
   char *res = REAL(strfry)(s);
@@ -317,16 +215,7 @@ void __nsan::InitializeInterceptors() {
   mallopt(-3, 32 * 1024); // M_MMAP_THRESHOLD
 #endif
 
-  INTERCEPT_FUNCTION(malloc);
-  INTERCEPT_FUNCTION(calloc);
-  INTERCEPT_FUNCTION(free);
-  INTERCEPT_FUNCTION(realloc);
-  INTERCEPT_FUNCTION(valloc);
-  INTERCEPT_FUNCTION(memalign);
-  INTERCEPT_FUNCTION(__libc_memalign);
-  INTERCEPT_FUNCTION(pvalloc);
-  INTERCEPT_FUNCTION(aligned_alloc);
-  INTERCEPT_FUNCTION(posix_memalign);
+  InitializeMallocInterceptors();
 
   INTERCEPT_FUNCTION(memset);
   INTERCEPT_FUNCTION(wmemset);
diff --git a/compiler-rt/lib/nsan/nsan_malloc_linux.cpp b/compiler-rt/lib/nsan/nsan_malloc_linux.cpp
new file mode 100644
index 0000000000000..3bfc16f69b9be
--- /dev/null
+++ b/compiler-rt/lib/nsan/nsan_malloc_linux.cpp
@@ -0,0 +1,137 @@
+//===- nsan_malloc_linux.cpp ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Interceptors for memory allocation functions on ELF OSes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "interception/interception.h"
+#include "nsan/nsan.h"
+#include "sanitizer_common/sanitizer_allocator_dlsym.h"
+#include "sanitizer_common/sanitizer_common.h"
+#include "sanitizer_common/sanitizer_platform.h"
+#include "sanitizer_common/sanitizer_platform_interceptors.h"
+
+#if !SANITIZER_APPLE && !SANITIZER_WINDOWS
+using namespace __sanitizer;
+using __nsan::nsan_initialized;
+
+struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> {
+  static bool UseImpl() { return !nsan_initialized; }
+};
+
+INTERCEPTOR(void *, aligned_alloc, uptr align, uptr size) {
+  void *res = REAL(aligned_alloc)(align, size);
+  if (res)
+    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
+  return res;
+}
+
+INTERCEPTOR(void *, calloc, uptr nmemb, uptr size) {
+  if (DlsymAlloc::Use())
+    return DlsymAlloc::Callocate(nmemb, size);
+
+  void *res = REAL(calloc)(nmemb, size);
+  if (res)
+    __nsan_set_value_unknown(static_cast<u8 *>(res), nmemb * size);
+  return res;
+}
+
+INTERCEPTOR(void, free, void *ptr) {
+  if (DlsymAlloc::PointerIsMine(ptr))
+    return DlsymAlloc::Free(ptr);
+  REAL(free)(ptr);
+}
+
+INTERCEPTOR(void *, realloc, void *ptr, uptr size) {
+  if (DlsymAlloc::Use() || DlsymAlloc::PointerIsMine(ptr))
+    return DlsymAlloc::Realloc(ptr, size);
+  void *res = REAL(realloc)(ptr, size);
+  // TODO: We might want to copy the types from the original allocation
+  // (although that would require that we know its size).
+  if (res)
+    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
+  return res;
+}
+
+INTERCEPTOR(void *, malloc, uptr size) {
+  if (DlsymAlloc::Use())
+    return DlsymAlloc::Allocate(size);
+
+  void *res = REAL(malloc)(size);
+  if (res)
+    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
+  return res;
+}
+
+INTERCEPTOR(int, posix_memalign, void **memptr, uptr align, uptr size) {
+  int res = REAL(posix_memalign)(memptr, align, size);
+  if (res == 0 && *memptr)
+    __nsan_set_value_unknown(static_cast<u8 *>(*memptr), size);
+  return res;
+}
+
+#if SANITIZER_INTERCEPT_REALLOCARRAY
+INTERCEPTOR(void *, reallocarray, void *ptr, uptr nmemb, uptr size) {
+  void *res = REAL(reallocarray)(ptr, nmemb, size);
+  if (res)
+    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
+}
+#endif // SANITIZER_INTERCEPT_REALLOCARRAY
+
+// Deprecated allocation functions (memalign, pvalloc, valloc, etc).
+#if SANITIZER_INTERCEPT_MEMALIGN
+INTERCEPTOR(void *, memalign, uptr align, uptr size) {
+  void *const res = REAL(memalign)(align, size);
+  if (res)
+    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
+  return res;
+}
+
+INTERCEPTOR(void *, __libc_memalign, uptr align, uptr size) {
+  void *const res = REAL(__libc_memalign)(align, size);
+  if (res)
+    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
+  return res;
+}
+#endif
+
+#if SANITIZER_INTERCEPT_PVALLOC
+INTERCEPTOR(void *, pvalloc, uptr size) {
+  void *const res = REAL(pvalloc)(size);
+  if (res)
+    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
+  return res;
+}
+#endif
+
+INTERCEPTOR(void *, valloc, uptr size) {
+  void *const res = REAL(valloc)(size);
+  if (res)
+    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
+  return res;
+}
+
+void __nsan::InitializeMallocInterceptors() {
+  INTERCEPT_FUNCTION(aligned_alloc);
+  INTERCEPT_FUNCTION(calloc);
+  INTERCEPT_FUNCTION(free);
+  INTERCEPT_FUNCTION(malloc);
+  INTERCEPT_FUNCTION(posix_memalign);
+  INTERCEPT_FUNCTION(realloc);
+
+  INTERCEPT_FUNCTION(memalign);
+  INTERCEPT_FUNCTION(__libc_memalign);
+  INTERCEPT_FUNCTION(pvalloc);
+  INTERCEPT_FUNCTION(valloc);
+#if SANITIZER_INTERCEPT_REALLOCARRAY
+  INTERCEPT_FUNCTION(reallocarray);
+#endif
+}
+
+#endif

@vitalybuka
Copy link
Collaborator

vitalybuka commented Jul 10, 2024

@eugenis There is a inconsistency now with #98194

.
Created using spr 1.3.5-bogner
MaskRay added a commit that referenced this pull request Jul 11, 2024
…bsan

* `-fsanitize=numerical,undefined`: don't link in the ubsan standalone
  runtime.
* `-shared-libsan`: link against `libclang_rt.nsan.so`

The compiler-rt part will be properly fixed by #98415
.
Created using spr 1.3.5-bogner
Copy link
Collaborator

@alexander-shaposhnikov alexander-shaposhnikov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LG, thanks

.
Created using spr 1.3.5-bogner
@MaskRay MaskRay merged commit 80ff3ac into main Jul 11, 2024
3 of 5 checks passed
@MaskRay MaskRay deleted the users/MaskRay/spr/nsan-add-shared-runtime branch July 11, 2024 01:35
@yxsamliu
Copy link
Collaborator

It seems to cause a build failure:

https://lab.llvm.org/buildbot/#/builders/123/builds/1580

@yxsamliu
Copy link
Collaborator

It seems to cause a build failure:

https://lab.llvm.org/buildbot/#/builders/123/builds/1580

It seems the issue was due to old system linker. If I use lld to build compier-rt the build passes. I will fix the buildbot llvm/llvm-zorg#225

@MaskRay
Copy link
Member Author

MaskRay commented Jul 11, 2024

It seems to cause a build failure:
lab.llvm.org/buildbot

It seems the issue was due to old system linker. If I use lld to build compier-rt the build passes. I will fix the buildbot llvm/llvm-zorg#225

Thanks. This is a real issue that GNU ld doesn't like .preinit_array in DSO. I've fixed forward by adding nsan_preinit.cpp

@VinInn
Copy link

VinInn commented Jul 11, 2024

It still fails to build after a git pull

ninja -C build
ninja: Entering directory `build'
[1/1] Linking CXX shared library lib/clang/19/lib/x86_64-unknown-linux-gnu/libclang_rt.nsan.so
FAILED: lib/clang/19/lib/x86_64-unknown-linux-gnu/libclang_rt.nsan.so
: && /afs/cern.ch/user/i/innocent/w5/bin/g++ -fPIC -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -fno-lifetime-dse -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-maybe-uninitialized -Wno-nonnull -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wno-misleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -Wall -Wno-unused-parameter -O3 -DNDEBUG  -Wl,-z,defs -Wl,-z,nodelete   -m64 -nodefaultlibs -Wl,-z,text -nostdlib++ -Wl,--version-script,/data/user/innocent/llvm-project/build/projects/compiler-rt/lib/nsan/clang_rt.nsan-dynamic-x86_64.vers -shared -Wl,-soname,libclang_rt.nsan.so -o lib/clang/19/lib/x86_64-unknown-linux-gnu/libclang_rt.nsan.so projects/compiler-rt/lib/interception/CMakeFiles/RTInterception.x86_64.dir/interception_linux.cpp.o projects/compiler-rt/lib/interception/CMakeFiles/RTInterception.x86_64.dir/interception_mac.cpp.o projects/compiler-rt/lib/interception/CMakeFiles/RTInterception.x86_64.dir/interception_win.cpp.o projects/compiler-rt/lib/interception/CMakeFiles/RTInterception.x86_64.dir/interception_type_test.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_allocator.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_common.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_deadlock_detector1.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_deadlock_detector2.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_errno.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_file.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_flags.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_flag_parser.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_fuchsia.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_libc.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_libignore.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_linux.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_linux_s390.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_mac.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_mutex.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_netbsd.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_platform_limits_freebsd.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_platform_limits_linux.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_platform_limits_netbsd.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_platform_limits_posix.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_platform_limits_solaris.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_posix.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_printf.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_procmaps_common.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_procmaps_bsd.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_procmaps_fuchsia.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_procmaps_linux.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_procmaps_mac.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_procmaps_solaris.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_range.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_solaris.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_stoptheworld_fuchsia.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_stoptheworld_mac.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_stoptheworld_win.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_suppressions.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_tls_get_addr.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_thread_arg_retval.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_thread_registry.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_type_traits.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_win.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_termination.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonLibc.x86_64.dir/sanitizer_common_libcdep.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonLibc.x86_64.dir/sanitizer_allocator_checks.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonLibc.x86_64.dir/sanitizer_dl.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonLibc.x86_64.dir/sanitizer_linux_libcdep.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonLibc.x86_64.dir/sanitizer_mac_libcdep.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonLibc.x86_64.dir/sanitizer_posix_libcdep.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonLibc.x86_64.dir/sanitizer_stoptheworld_linux_libcdep.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonLibc.x86_64.dir/sanitizer_stoptheworld_netbsd_libcdep.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonCoverage.x86_64.dir/sancov_flags.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonCoverage.x86_64.dir/sanitizer_coverage_fuchsia.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonCoverage.x86_64.dir/sanitizer_coverage_libcdep_new.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonCoverage.x86_64.dir/sanitizer_coverage_win_sections.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_allocator_report.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_chained_origin_depot.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_stack_store.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_stackdepot.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_stacktrace.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_stacktrace_libcdep.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_stacktrace_printer.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_stacktrace_sparc.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_symbolizer.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_symbolizer_libbacktrace.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_symbolizer_libcdep.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_symbolizer_mac.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_symbolizer_markup.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_symbolizer_markup_fuchsia.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_symbolizer_posix_libcdep.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_symbolizer_report.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_symbolizer_report_fuchsia.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_symbolizer_win.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_unwind_linux_libcdep.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_unwind_fuchsia.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_unwind_win.cpp.o projects/compiler-rt/lib/ubsan/CMakeFiles/RTUbsan.x86_64.dir/ubsan_diag.cpp.o projects/compiler-rt/lib/ubsan/CMakeFiles/RTUbsan.x86_64.dir/ubsan_init.cpp.o projects/compiler-rt/lib/ubsan/CMakeFiles/RTUbsan.x86_64.dir/ubsan_flags.cpp.o projects/compiler-rt/lib/ubsan/CMakeFiles/RTUbsan.x86_64.dir/ubsan_handlers.cpp.o projects/compiler-rt/lib/ubsan/CMakeFiles/RTUbsan.x86_64.dir/ubsan_monitor.cpp.o projects/compiler-rt/lib/ubsan/CMakeFiles/RTUbsan.x86_64.dir/ubsan_value.cpp.o projects/compiler-rt/lib/nsan/CMakeFiles/RTNsan_dynamic.x86_64.dir/nsan.cpp.o projects/compiler-rt/lib/nsan/CMakeFiles/RTNsan_dynamic.x86_64.dir/nsan_flags.cpp.o projects/compiler-rt/lib/nsan/CMakeFiles/RTNsan_dynamic.x86_64.dir/nsan_interceptors.cpp.o projects/compiler-rt/lib/nsan/CMakeFiles/RTNsan_dynamic.x86_64.dir/nsan_malloc_linux.cpp.o projects/compiler-rt/lib/nsan/CMakeFiles/RTNsan_dynamic.x86_64.dir/nsan_stats.cpp.o projects/compiler-rt/lib/nsan/CMakeFiles/RTNsan_dynamic.x86_64.dir/nsan_suppressions.cpp.o projects/compiler-rt/lib/nsan/CMakeFiles/RTNsan_dynamic_version_script_dummy.x86_64.dir/dummy.cpp.o  -lstdc++  -lgcc_s  -lc  -ldl  -lrt  -lm  -lpthread && :
/usr/bin/ld: projects/compiler-rt/lib/nsan/CMakeFiles/RTNsan_dynamic.x86_64.dir/nsan.cpp.o: .preinit_array section is not allowed in DSO
/usr/bin/ld: failed to set dynamic section sizes: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

@dyung
Copy link
Collaborator

dyung commented Jul 12, 2024

It still fails to build after a git pull

ninja -C build
ninja: Entering directory `build'
[1/1] Linking CXX shared library lib/clang/19/lib/x86_64-unknown-linux-gnu/libclang_rt.nsan.so
FAILED: lib/clang/19/lib/x86_64-unknown-linux-gnu/libclang_rt.nsan.so
: && /afs/cern.ch/user/i/innocent/w5/bin/g++ -fPIC -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -fno-lifetime-dse -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-maybe-uninitialized -Wno-nonnull -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wno-misleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -Wall -Wno-unused-parameter -O3 -DNDEBUG  -Wl,-z,defs -Wl,-z,nodelete   -m64 -nodefaultlibs -Wl,-z,text -nostdlib++ -Wl,--version-script,/data/user/innocent/llvm-project/build/projects/compiler-rt/lib/nsan/clang_rt.nsan-dynamic-x86_64.vers -shared -Wl,-soname,libclang_rt.nsan.so -o lib/clang/19/lib/x86_64-unknown-linux-gnu/libclang_rt.nsan.so projects/compiler-rt/lib/interception/CMakeFiles/RTInterception.x86_64.dir/interception_linux.cpp.o projects/compiler-rt/lib/interception/CMakeFiles/RTInterception.x86_64.dir/interception_mac.cpp.o projects/compiler-rt/lib/interception/CMakeFiles/RTInterception.x86_64.dir/interception_win.cpp.o projects/compiler-rt/lib/interception/CMakeFiles/RTInterception.x86_64.dir/interception_type_test.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_allocator.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_common.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_deadlock_detector1.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_deadlock_detector2.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_errno.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_file.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_flags.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_flag_parser.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_fuchsia.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_libc.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_libignore.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_linux.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_linux_s390.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_mac.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_mutex.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_netbsd.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_platform_limits_freebsd.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_platform_limits_linux.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_platform_limits_netbsd.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_platform_limits_posix.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_platform_limits_solaris.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_posix.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_printf.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_procmaps_common.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_procmaps_bsd.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_procmaps_fuchsia.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_procmaps_linux.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_procmaps_mac.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_procmaps_solaris.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_range.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_solaris.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_stoptheworld_fuchsia.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_stoptheworld_mac.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_stoptheworld_win.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_suppressions.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_tls_get_addr.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_thread_arg_retval.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_thread_registry.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_type_traits.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_win.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.x86_64.dir/sanitizer_termination.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonLibc.x86_64.dir/sanitizer_common_libcdep.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonLibc.x86_64.dir/sanitizer_allocator_checks.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonLibc.x86_64.dir/sanitizer_dl.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonLibc.x86_64.dir/sanitizer_linux_libcdep.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonLibc.x86_64.dir/sanitizer_mac_libcdep.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonLibc.x86_64.dir/sanitizer_posix_libcdep.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonLibc.x86_64.dir/sanitizer_stoptheworld_linux_libcdep.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonLibc.x86_64.dir/sanitizer_stoptheworld_netbsd_libcdep.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonCoverage.x86_64.dir/sancov_flags.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonCoverage.x86_64.dir/sanitizer_coverage_fuchsia.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonCoverage.x86_64.dir/sanitizer_coverage_libcdep_new.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonCoverage.x86_64.dir/sanitizer_coverage_win_sections.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_allocator_report.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_chained_origin_depot.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_stack_store.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_stackdepot.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_stacktrace.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_stacktrace_libcdep.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_stacktrace_printer.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_stacktrace_sparc.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_symbolizer.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_symbolizer_libbacktrace.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_symbolizer_libcdep.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_symbolizer_mac.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_symbolizer_markup.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_symbolizer_markup_fuchsia.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_symbolizer_posix_libcdep.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_symbolizer_report.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_symbolizer_report_fuchsia.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_symbolizer_win.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_unwind_linux_libcdep.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_unwind_fuchsia.cpp.o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizer.x86_64.dir/sanitizer_unwind_win.cpp.o projects/compiler-rt/lib/ubsan/CMakeFiles/RTUbsan.x86_64.dir/ubsan_diag.cpp.o projects/compiler-rt/lib/ubsan/CMakeFiles/RTUbsan.x86_64.dir/ubsan_init.cpp.o projects/compiler-rt/lib/ubsan/CMakeFiles/RTUbsan.x86_64.dir/ubsan_flags.cpp.o projects/compiler-rt/lib/ubsan/CMakeFiles/RTUbsan.x86_64.dir/ubsan_handlers.cpp.o projects/compiler-rt/lib/ubsan/CMakeFiles/RTUbsan.x86_64.dir/ubsan_monitor.cpp.o projects/compiler-rt/lib/ubsan/CMakeFiles/RTUbsan.x86_64.dir/ubsan_value.cpp.o projects/compiler-rt/lib/nsan/CMakeFiles/RTNsan_dynamic.x86_64.dir/nsan.cpp.o projects/compiler-rt/lib/nsan/CMakeFiles/RTNsan_dynamic.x86_64.dir/nsan_flags.cpp.o projects/compiler-rt/lib/nsan/CMakeFiles/RTNsan_dynamic.x86_64.dir/nsan_interceptors.cpp.o projects/compiler-rt/lib/nsan/CMakeFiles/RTNsan_dynamic.x86_64.dir/nsan_malloc_linux.cpp.o projects/compiler-rt/lib/nsan/CMakeFiles/RTNsan_dynamic.x86_64.dir/nsan_stats.cpp.o projects/compiler-rt/lib/nsan/CMakeFiles/RTNsan_dynamic.x86_64.dir/nsan_suppressions.cpp.o projects/compiler-rt/lib/nsan/CMakeFiles/RTNsan_dynamic_version_script_dummy.x86_64.dir/dummy.cpp.o  -lstdc++  -lgcc_s  -lc  -ldl  -lrt  -lm  -lpthread && :
/usr/bin/ld: projects/compiler-rt/lib/nsan/CMakeFiles/RTNsan_dynamic.x86_64.dir/nsan.cpp.o: .preinit_array section is not allowed in DSO
/usr/bin/ld: failed to set dynamic section sizes: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

The fix was reverted in 0b15f89 because it broke the sanitizer bot.

MaskRay added a commit that referenced this pull request Jul 12, 2024
#94322 defines .preinit_array to initialize nsan early.
DT_PREINIT_ARRAY can only be used with the main executable. GNU ld would
complain when a DSO has .preinit_array. Therefore,
nsan_preinit.cpp cannot be linked into `libclang_rt.nsan.so` (#98415).

Working with @alexander-shaposhnikov, we noticed that `Nsan-x86_64-Test
--gtest_output=json` without `.preinit_array` will sigsegv. This is
because googletest with the JSON output calls `localtime_r` , which
calls `free(0)` and fails when `REAL(free)` remains uninitialized
(nullptr). This is benign with the default output because malloc/free
are all paired and `REAL(free)(ptr)` is not called.

To fix the unittest failure, `__nsan_init` needs to be called early
(.preinit_array).
`asan/tests/CMakeLists.txt:ASAN_UNITTEST_INSTRUMENTED_LINK_FLAGS` ues
`-fsanitize=address` to ensure `asan_preinit.cpp.o` is linked into the
unittest executable. Port the approach and remove
`NSAN_TEST_RUNTIME_OBJECTS`.

Fix #98523

Pull Request: #98564
aaryanshukla pushed a commit to aaryanshukla/llvm-project that referenced this pull request Jul 14, 2024
…bsan

* `-fsanitize=numerical,undefined`: don't link in the ubsan standalone
  runtime.
* `-shared-libsan`: link against `libclang_rt.nsan.so`

The compiler-rt part will be properly fixed by llvm#98415
aaryanshukla pushed a commit to aaryanshukla/llvm-project that referenced this pull request Jul 14, 2024
so that `clang -fsanitize=numerical -shared-libsan` will use
`libclang_rt.nsan.so` on Linux.

Shared runtime is preferred for some platforms (Android, Apple, Fuchsia;
though they are not supported yet) and helps plugin use cases (llvm#98302).

* Update `ninja nsan` to build `libclang_rt.nsan.so`
* Fix `nsan.syms.extra`: `nsan_*` is unneeded. Add `__ubsan_*` so that
  `-fsanitize=numerical,undefined -shared-libsan` works.
* Move allocation functions to `nsan_malloc_linux.cpp`. While Apple
  platforms aren't supported yet, this separation makes it easier to add
  Apple support.
* Delete interceptors for very obsoleted pvalloc/valloc but retain
  memalign.
* Replace `HandleEarlyAlloc` with `DlsymAlloc`.

Pull Request: llvm#98415
aaryanshukla pushed a commit to aaryanshukla/llvm-project that referenced this pull request Jul 14, 2024
llvm#94322 defines .preinit_array to initialize nsan early.
DT_PREINIT_ARRAY can only be used with the main executable. GNU ld would
complain when a DSO has .preinit_array. Therefore,
nsan_preinit.cpp cannot be linked into `libclang_rt.nsan.so` (llvm#98415).

Working with @alexander-shaposhnikov, we noticed that `Nsan-x86_64-Test
--gtest_output=json` without `.preinit_array` will sigsegv. This is
because googletest with the JSON output calls `localtime_r` , which
calls `free(0)` and fails when `REAL(free)` remains uninitialized
(nullptr). This is benign with the default output because malloc/free
are all paired and `REAL(free)(ptr)` is not called.

To fix the unittest failure, `__nsan_init` needs to be called early
(.preinit_array).
`asan/tests/CMakeLists.txt:ASAN_UNITTEST_INSTRUMENTED_LINK_FLAGS` ues
`-fsanitize=address` to ensure `asan_preinit.cpp.o` is linked into the
unittest executable. Port the approach and remove
`NSAN_TEST_RUNTIME_OBJECTS`.

Fix llvm#98523

Pull Request: llvm#98564
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang Clang issues not falling into any other category compiler-rt:sanitizer compiler-rt
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants