commit 56a8fd4062e5dfad2402c59acf210cb64eec4991 from: Sergey Bronnikov date: Wed Jul 10 15:18:15 2024 UTC cmake: fix searching Clang RT luzer module requires linking with a library `clang_rt.fuzzer_no_main-x86_64` that is a part of a Clang runtime. Without linking with it Lua runtime will report an error right on loading `luzer.so`: lua5.1: error loading module 'luzer' from file './luzer.so': ./luzer.so: undefined symbol: __sanitizer_cov_8bit_counters_init The patch adds a module that composes a path to Clang runtime libraries and adds this path to a library search paths. I suppose in some cases introduced CMake function may fail. One can pass a path to a directory with Clang RT manually using environment variable CLANG_RT_LIB_DIR. In a usual case symbol __sanitizer_cov_8bit_counters_init is added by compiler on instrumentation when compiler option -fsanitize-coverage=inline-8bit-counters is specified [1]. 1. https://clang.llvm.org/docs/SanitizerCoverage.html commit - e0ad4cdfda579f7d61ea90428257e0f5d82d86ce commit + 56a8fd4062e5dfad2402c59acf210cb64eec4991 blob - b2cb78a09071a5d4150c0f266d41669e9757419f blob + 10ff09c348f161a16e7f4dff1c97729455c93ce8 --- CHANGELOG.md +++ CHANGELOG.md @@ -18,3 +18,7 @@ and this project adheres to [Semantic Versioning](http ### Changed - Disable coverage instrumentation of internal functions (#11). + +### Fixed + +- Fix searching Clang RT. blob - da1edbdfd954ac1e81a5bc16f705f967cc0ba8bb blob + 3401739b4c4dfdc78897e54621e6870afb4a6b25 --- CMakeLists.txt +++ CMakeLists.txt @@ -5,9 +5,11 @@ project(luzer VERSION "1.0.0" ) +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") +include(SetClangRTLib) + find_package(Lua 5.1 REQUIRED) find_package(LLVM REQUIRED CONFIG) -find_library(LIBRT rt) set(LUA_NAME "lua${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}") find_program(LUA_EXECUTABLE "${LUA_NAME}") blob - /dev/null blob + 56debc50de1bd9fde9a63336f9b41df12863109a (mode 644) --- /dev/null +++ cmake/SetClangRTLib.cmake @@ -0,0 +1,40 @@ +# The function sets the given variable in a parent scope to a +# value in FUZZER_NO_MAIN_LIBRARY environment variable if it +# is set. Otherwise the value with path to a directory with +# libclang_rt.fuzzer_no_main library is composed manually. +# Function raises a fatal message if C compiler is not Clang. +# +# $ clang-15 -print-file-name=libclang_rt.fuzzer_no_main-x86_64.a +# $ /usr/lib/llvm-15/lib/clang/15.0.7/lib/linux/libclang_rt.fuzzer_no_main-x86_64.a +# +# On Linux installations libFuzzer library is typically located at: +# +# /usr/lib//lib/clang//lib/linux/libclang_rt.fuzzer_no_main-.a +# +# 1. https://llvm.org/docs/LibFuzzer.html#using-libfuzzer-as-a-library + +function(SetFuzzerNoMainLibPath outvar) + if (NOT CMAKE_C_COMPILER_ID STREQUAL "Clang") + message(FATAL_ERROR "C compiler is not a Clang") + endif () + + if (CMAKE_SIZEOF_VOID_P EQUAL 4) + set(ARCH "i386") + elseif (CMAKE_SIZEOF_VOID_P EQUAL 8) + set(ARCH "x86_64") + else () + message(FATAL_ERROR "Unsupported architecture.") + endif () + + set(LIB_FUZZER_NO_MAIN "libclang_rt.fuzzer_no_main-${ARCH}.a") + execute_process(COMMAND ${CMAKE_C_COMPILER} "-print-file-name=${LIB_FUZZER_NO_MAIN}" + RESULT_VARIABLE CMD_ERROR + OUTPUT_VARIABLE CMD_OUTPUT + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if (CMD_ERROR) + message(FATAL_ERROR "${CMD_ERROR}") + endif () + set(${outvar} ${CMD_OUTPUT} PARENT_SCOPE) + message(STATUS "[SetClangRTLib] ${outvar} is ${CMD_OUTPUT}") +endfunction() blob - 785a9e297fabab0f521d678b5d673a9840829a24 blob + 4f76421a49c64be403566d3f75ae3e1a88932534 --- luzer/CMakeLists.txt +++ luzer/CMakeLists.txt @@ -1,18 +1,5 @@ -# Locate compiler-rt libraries. -# Location is LLVM_LIBRARY_DIRS/clang//lib//, -# for example LLVM_LIBRARY_DIRS/clang/4.0.0/lib/darwin/. -# -# See https://llvm.org/docs/LibFuzzer.html#using-libfuzzer-as-a-library +SetFuzzerNoMainLibPath(FUZZER_NO_MAIN_LIBRARY) -set(LLVM_BASE ${LLVM_LIBRARY_DIRS}/clang/${LLVM_PACKAGE_VERSION}) -string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} OS_NAME) -set(LIBCLANG_RT ${LLVM_BASE}/lib/${OS_NAME}/libclang_rt.fuzzer_no_main-x86_64.a) -if(EXISTS ${LIBCLANG_RT}) - message(STATUS "Found libclang_rt ${LIBCLANG_RT}") -else() - message(FATAL_ERROR "libclang_rt is not found") -endif() - configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/version.c ${CMAKE_CURRENT_BINARY_DIR}/version.c @@ -31,9 +18,8 @@ target_include_directories(${CMAKE_PROJECT_NAME} PRIVA ) target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE ${LUA_LIBRARIES} - ${LIBRT} - ${LIBCLANG_RT} -fsanitize=fuzzer-no-link + ${FUZZER_NO_MAIN_LIBRARY} ) target_compile_options(${CMAKE_PROJECT_NAME} PRIVATE -D_FORTIFY_SOURCE=2