• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (c) 2021-2024 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# 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
45# some false-positive or another issues when compiling with ASAN or UBSAN in release mode. So, cover this with early-bailout.
46if ((PANDA_ENABLE_ADDRESS_SANITIZER OR PANDA_ENABLE_UNDEFINED_BEHAVIOR_SANITIZER) AND
47    "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND (CMAKE_BUILD_TYPE MATCHES Release) AND
48    (NOT CROSS_VALUES_CONFIG))
49        message(FATAL_ERROR "GCC gives false positives in release builds with ASAN or UBSAN, please use clang or another compiler.")
50    unset(build_type)
51endif()
52
53# Add options to build with sanitizers to specified target
54#
55# Example usage:
56#   panda_add_sanitizers(TARGET <name> SANITIZERS <sanitizer1>,<sanitizer2>)
57#
58# Adds options to build target <name> with <sanitizer1> and <sanitizer2>
59#
60# Available sanitizers: address, thread, undefined
61
62function(panda_add_sanitizers)
63    set(prefix ARG)
64    set(noValues)
65    set(singleValues TARGET)
66    set(multiValues SOURCES SANITIZERS)
67
68    cmake_parse_arguments(${prefix}
69                          "${noValues}"
70                          "${singleValues}"
71                          "${multiValues}"
72                          ${ARGN})
73
74    get_target_property(target_is_imported ${ARG_TARGET} IMPORTED)
75    if(target_is_imported)
76        return()
77    endif()
78
79    if(ARG_SANITIZERS)
80        set(AVAILABLE_SANITIZERS "address" "undefined" "thread")
81        foreach(sanitizer ${ARG_SANITIZERS})
82            if(NOT ${sanitizer} IN_LIST AVAILABLE_SANITIZERS)
83                message(FATAL_ERROR "Unknown sanitizer: ${sanitizer}")
84            endif()
85        endforeach()
86        string(REPLACE ";" "," ARG_SANITIZERS "${ARG_SANITIZERS}")
87        target_compile_options(${ARG_TARGET} PUBLIC "-fsanitize=${ARG_SANITIZERS}" -g)
88        if (PANDA_ENABLE_SANITIZE_TRAP)
89            target_compile_options(${ARG_TARGET} PUBLIC "-fsanitize-undefined-trap-on-error")
90        endif()
91        set_target_properties(${ARG_TARGET} PROPERTIES LINK_FLAGS "-fsanitize=${ARG_SANITIZERS}")
92
93        if (PANDA_TARGET_MOBILE)
94            target_link_libraries(${ARG_TARGET} log)
95        endif()
96    endif()
97endfunction()
98