From c862ae0c4233c6a8da94c364d0411aebfe8577b8 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 15 Dec 2020 22:59:07 +0300 Subject: [PATCH] Explicitly link with -llib$SANITIZER for gcc gcc with -nodefaultlibs does not add sanitizers library during linkage with -static-libasan and similar, fix this, by add them explicitly. From the gcc(1) about -nodefaultlibs: Do not use the standard system libraries when linking. Only the libraries you specify are passed to the linker, and options specifying linkage of the system libraries, such as -static-libgcc or -shared-libgcc, are ignored. The standard startup files are used normally, unless -nostartfiles is used. Plus checked it manually, w/o -nodefaultlibs everything works without this explicit linkage. After this patch UBSAN under gcc compiled successfully. v2: freebsd and darwin --- CMakeLists.txt | 6 ++++++ cmake/darwin/default_libs.cmake | 4 ---- cmake/freebsd/default_libs.cmake | 4 ---- cmake/linux/default_libs.cmake | 4 ---- cmake/sanitize.cmake | 15 +++++++++++++++ 5 files changed, 21 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 56faf4ca2b1..406ef76ddae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -112,6 +112,12 @@ if (ENABLE_FUZZING) set (FUZZER "libfuzzer") endif() +# Global libraries +# See: +# - default_libs.cmake +# - sanitize.cmake +add_library(global-libs INTERFACE) + include (cmake/fuzzer.cmake) include (cmake/sanitize.cmake) diff --git a/cmake/darwin/default_libs.cmake b/cmake/darwin/default_libs.cmake index 4ee1bcdcfbf..79ac675f234 100644 --- a/cmake/darwin/default_libs.cmake +++ b/cmake/darwin/default_libs.cmake @@ -14,10 +14,6 @@ set(CMAKE_C_STANDARD_LIBRARIES ${DEFAULT_LIBS}) # Minimal supported SDK version set(CMAKE_OSX_DEPLOYMENT_TARGET 10.15) -# Global libraries - -add_library(global-libs INTERFACE) - # Unfortunately '-pthread' doesn't work with '-nodefaultlibs'. # Just make sure we have pthreads at all. set(THREADS_PREFER_PTHREAD_FLAG ON) diff --git a/cmake/freebsd/default_libs.cmake b/cmake/freebsd/default_libs.cmake index d60df52bc6d..a5847c95387 100644 --- a/cmake/freebsd/default_libs.cmake +++ b/cmake/freebsd/default_libs.cmake @@ -17,10 +17,6 @@ message(STATUS "Default libraries: ${DEFAULT_LIBS}") set(CMAKE_CXX_STANDARD_LIBRARIES ${DEFAULT_LIBS}) set(CMAKE_C_STANDARD_LIBRARIES ${DEFAULT_LIBS}) -# Global libraries - -add_library(global-libs INTERFACE) - # Unfortunately '-pthread' doesn't work with '-nodefaultlibs'. # Just make sure we have pthreads at all. set(THREADS_PREFER_PTHREAD_FLAG ON) diff --git a/cmake/linux/default_libs.cmake b/cmake/linux/default_libs.cmake index 6c93e197e86..b610a32759f 100644 --- a/cmake/linux/default_libs.cmake +++ b/cmake/linux/default_libs.cmake @@ -31,10 +31,6 @@ if (ARCH_AMD64 AND NOT_UNBUNDLED) set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES ${ClickHouse_SOURCE_DIR}/contrib/libc-headers/x86_64-linux-gnu ${ClickHouse_SOURCE_DIR}/contrib/libc-headers) endif () -# Global libraries - -add_library(global-libs INTERFACE) - # Unfortunately '-pthread' doesn't work with '-nodefaultlibs'. # Just make sure we have pthreads at all. set(THREADS_PREFER_PTHREAD_FLAG ON) diff --git a/cmake/sanitize.cmake b/cmake/sanitize.cmake index 169dac3b6be..6c23ce8bc91 100644 --- a/cmake/sanitize.cmake +++ b/cmake/sanitize.cmake @@ -8,6 +8,12 @@ option (SANITIZE "Enable one of the code sanitizers" "") set (SAN_FLAGS "${SAN_FLAGS} -g -fno-omit-frame-pointer -DSANITIZER") +# gcc with -nodefaultlibs does not add sanitizer libraries +# with -static-libasan and similar +macro(add_explicit_sanitizer_library lib) + target_link_libraries(global-libs INTERFACE "-Wl,-static -l${lib} -Wl,-Bdynamic") +endmacro() + if (SANITIZE) if (SANITIZE STREQUAL "address") set (ASAN_FLAGS "-fsanitize=address -fsanitize-address-use-after-scope") @@ -20,6 +26,9 @@ if (SANITIZE) if (MAKE_STATIC_LIBRARIES AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libasan") endif () + if (COMPILER_GCC) + add_explicit_sanitizer_library(asan) + endif() elseif (SANITIZE STREQUAL "memory") # MemorySanitizer flags are set according to the official documentation: @@ -63,6 +72,9 @@ if (SANITIZE) if (MAKE_STATIC_LIBRARIES AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libtsan") endif () + if (COMPILER_GCC) + add_explicit_sanitizer_library(tsan) + endif() elseif (SANITIZE STREQUAL "undefined") set (UBSAN_FLAGS "-fsanitize=undefined -fno-sanitize-recover=all -fno-sanitize=float-divide-by-zero") @@ -83,6 +95,9 @@ if (SANITIZE) if (MAKE_STATIC_LIBRARIES AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libubsan") endif () + if (COMPILER_GCC) + add_explicit_sanitizer_library(ubsan) + endif() # llvm-tblgen, that is used during LLVM build, doesn't work with UBSan. set (ENABLE_EMBEDDED_COMPILER 0 CACHE BOOL "")