1# Copyright (c) 2021-2022 Huawei Device Co., Ltd. 2# Licensed under the Apache License, Version 2.0 (the "License"); 3# you may not use this file except in compliance with the License. 4# You may obtain a copy of the License at 5# 6# http://www.apache.org/licenses/LICENSE-2.0 7# 8# Unless required by applicable law or agreed to in writing, software 9# distributed under the License is distributed on an "AS IS" BASIS, 10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11# See the License for the specific language governing permissions and 12# limitations under the License. 13 14option(PANDA_ENABLE_SANITIZE_TRAP "Enable sanitizer trap generation" false) 15if (CMAKE_BUILD_TYPE MATCHES Release) 16 set(PANDA_ENABLE_SANITIZE_TRAP true) 17endif () 18 19option(PANDA_ENABLE_ADDRESS_SANITIZER "Address sanitizer enable" false) 20option(PANDA_ENABLE_UNDEFINED_BEHAVIOR_SANITIZER "Undefined behavior sanitizer enable" false) 21option(PANDA_ENABLE_THREAD_SANITIZER "Thread sanitizer enable" false) 22 23set(PANDA_SANITIZERS_LIST) 24 25if (PANDA_ENABLE_ADDRESS_SANITIZER) 26 message(STATUS "Enabled ASAN") 27 list(APPEND PANDA_SANITIZERS_LIST "address") 28 add_definitions(-D__SANITIZE_ADDRESS__) 29endif() 30 31if (PANDA_ENABLE_UNDEFINED_BEHAVIOR_SANITIZER) 32 message(STATUS "Enabled UBSAN") 33 list(APPEND PANDA_SANITIZERS_LIST "undefined") 34 # GCC doesn't have built-in macro for UBSAN, bypass by making our own definition. 35 add_definitions(-D__SANITIZE_UNDEFINED__) 36endif() 37 38if (PANDA_ENABLE_THREAD_SANITIZER) 39 message(STATUS "Enabled TSAN") 40 list(APPEND PANDA_SANITIZERS_LIST "thread") 41 add_definitions(-D__SANITIZE_THREAD__) 42endif() 43 44# Workaround for http://rnd-gitlab-msc.huawei.com/rus-os-team/virtual-machines-and-tools/panda/-/issues/529 45# As of beginning of May 2020 we have checked: gcc 7.5.0, gcc 8.4.0, gcc 9.3.0 and 10.0-rc versions, all have 46# some false-positive or another issues when compiling with ASAN or UBSAN in release mode. So, cover this with early-bailout. 47if ((PANDA_ENABLE_ADDRESS_SANITIZER OR PANDA_ENABLE_UNDEFINED_BEHAVIOR_SANITIZER) AND 48 "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND (CMAKE_BUILD_TYPE MATCHES Release) AND 49 (NOT CROSS_VALUES_CONFIG)) 50 message(FATAL_ERROR "GCC gives false positives in release builds with ASAN or UBSAN, please use clang or another compiler.") 51 unset(build_type) 52endif() 53 54# Suppress warning for line `target_link_libraries(${ARG_TARGET} log)`: 55# Attempt to add link library "log" to target * which is not built in this directory. 56if(POLICY CMP0079) 57 cmake_policy(SET CMP0079 NEW) 58endif() 59 60# Add options to build with sanitizers to specified target 61# 62# Example usage: 63# panda_add_sanitizers(TARGET <name> SANITIZERS <sanitizer1>,<sanitizer2>) 64# 65# Adds options to build target <name> with <sanitizer1> and <sanitizer2> 66# 67# Available sanitizers: address, thread, undefined 68 69function(panda_add_sanitizers) 70 set(prefix ARG) 71 set(noValues) 72 set(singleValues TARGET) 73 set(multiValues SOURCES SANITIZERS) 74 75 cmake_parse_arguments(${prefix} 76 "${noValues}" 77 "${singleValues}" 78 "${multiValues}" 79 ${ARGN}) 80 81 if(ARG_SANITIZERS) 82 set(AVAILABLE_SANITIZERS "address" "undefined" "thread") 83 foreach(sanitizer ${ARG_SANITIZERS}) 84 if(NOT ${sanitizer} IN_LIST AVAILABLE_SANITIZERS) 85 message(FATAL_ERROR "Unknown sanitizer: ${sanitizer}") 86 endif() 87 endforeach() 88 string(REPLACE ";" "," ARG_SANITIZERS "${ARG_SANITIZERS}") 89 target_compile_options(${ARG_TARGET} PUBLIC "-fsanitize=${ARG_SANITIZERS}" -g) 90 if (PANDA_ENABLE_SANITIZE_TRAP) 91 target_compile_options(${ARG_TARGET} PUBLIC "-fsanitize-undefined-trap-on-error") 92 endif() 93 set_target_properties(${ARG_TARGET} PROPERTIES LINK_FLAGS "-fsanitize=${ARG_SANITIZERS}") 94 95 if (PANDA_TARGET_MOBILE) 96 target_link_libraries(${ARG_TARGET} log) 97 endif() 98 endif() 99endfunction() 100