11#
2- # Copyright (C) 2018 by George Cave - gcave@stablecoder.ca
2+ # Copyright (C) 2018-2022 by George Cave - gcave@stablecoder.ca
33#
44# Licensed under the Apache License, Version 2.0 (the "License"); you may not
55# use this file except in compliance with the License. You may obtain a copy of
@@ -19,7 +19,7 @@ set(USE_SANITIZER
1919 ""
2020 CACHE
2121 STRING
22- "Compile with a sanitizer. Options are: Address, Memory, MemoryWithOrigins, Undefined, Thread, Leak, 'Address;Undefined'"
22+ "Compile with a sanitizer. Options are: Address, Memory, MemoryWithOrigins, Undefined, Thread, Leak, 'Address;Undefined', CFI "
2323)
2424
2525function (append value )
@@ -30,15 +30,23 @@ function(append value)
3030 endforeach (variable )
3131endfunction ()
3232
33+ function (append_quoteless value )
34+ foreach (variable ${ARGN} )
35+ set (${variable}
36+ ${${variable} } ${value}
37+ PARENT_SCOPE )
38+ endforeach (variable )
39+ endfunction ()
40+
3341function (test_san_flags return_var flags )
34- set (QUIET_BACKUP ${CMAKE_REQUIRED_QUIET} )
35- set (CMAKE_REQUIRED_QUIET TRUE )
36- unset (${return_var} CACHE )
37- set (FLAGS_BACKUP ${CMAKE_REQUIRED_FLAGS} )
38- set (CMAKE_REQUIRED_FLAGS "${flags} " )
39- check_cxx_source_compiles ("int main() { return 0; }" ${return_var} )
40- set (CMAKE_REQUIRED_FLAGS "${FLAGS_BACKUP} " )
41- set (CMAKE_REQUIRED_QUIET "${QUIET_BACKUP} " )
42+ set (QUIET_BACKUP ${CMAKE_REQUIRED_QUIET} )
43+ set (CMAKE_REQUIRED_QUIET TRUE )
44+ unset (${return_var} CACHE )
45+ set (FLAGS_BACKUP ${CMAKE_REQUIRED_FLAGS} )
46+ set (CMAKE_REQUIRED_FLAGS "${flags} " )
47+ check_cxx_source_compiles ("int main() { return 0; }" ${return_var} )
48+ set (CMAKE_REQUIRED_FLAGS "${FLAGS_BACKUP} " )
49+ set (CMAKE_REQUIRED_QUIET "${QUIET_BACKUP} " )
4250endfunction ()
4351
4452if (USE_SANITIZER)
@@ -57,11 +65,18 @@ if(USE_SANITIZER)
5765 message (STATUS "Testing with Address sanitizer" )
5866 set (SANITIZER_ADDR_FLAG "-fsanitize=address" )
5967 test_san_flags (SANITIZER_ADDR_AVAILABLE ${SANITIZER_ADDR_FLAG} )
60- if (SANITIZER_ADDR_AVAILABLE)
68+ if (SANITIZER_ADDR_AVAILABLE)
6169 message (STATUS " Building with Address sanitizer" )
6270 append ("${SANITIZER_ADDR_FLAG} " SANITIZER_SELECTED_FLAGS )
71+
72+ if (AFL)
73+ append_quoteless (AFL_USE_ASAN=1 CMAKE_C_COMPILER_LAUNCHER
74+ CMAKE_CXX_COMPILER_LAUNCHER )
75+ endif ()
6376 else ()
64- message (FATAL_ERROR "Address sanitizer not available for ${CMAKE_CXX_COMPILER} " )
77+ message (
78+ FATAL_ERROR
79+ "Address sanitizer not available for ${CMAKE_CXX_COMPILER} " )
6580 endif ()
6681 endif ()
6782
@@ -75,15 +90,23 @@ if(USE_SANITIZER)
7590 message (STATUS "Testing with Memory sanitizer" )
7691 endif ()
7792 test_san_flags (SANITIZER_MEM_AVAILABLE ${SANITIZER_MEM_FLAG} )
78- if (SANITIZER_MEM_AVAILABLE)
93+ if (SANITIZER_MEM_AVAILABLE)
7994 if (USE_SANITIZER MATCHES "([Mm]emory[Ww]ith[Oo]rigins)" )
80- message (STATUS " Building with MemoryWithOrigins sanitizer" )
95+ message (STATUS " Building with MemoryWithOrigins sanitizer" )
8196 else ()
82- message (STATUS " Building with Memory sanitizer" )
97+ message (STATUS " Building with Memory sanitizer" )
8398 endif ()
8499 append ("${SANITIZER_MEM_FLAG} " SANITIZER_SELECTED_FLAGS )
100+
101+ if (AFL)
102+ append_quoteless (AFL_USE_MSAN=1 CMAKE_C_COMPILER_LAUNCHER
103+ CMAKE_CXX_COMPILER_LAUNCHER )
104+ endif ()
85105 else ()
86- message (FATAL_ERROR "Memory [With Origins] sanitizer not available for ${CMAKE_CXX_COMPILER} " )
106+ message (
107+ FATAL_ERROR
108+ "Memory [With Origins] sanitizer not available for ${CMAKE_CXX_COMPILER} "
109+ )
87110 endif ()
88111 endif ()
89112
@@ -94,50 +117,99 @@ if(USE_SANITIZER)
94117 append ("-fsanitize-blacklist=${BLACKLIST_FILE} " SANITIZER_UB_FLAG )
95118 endif ()
96119 test_san_flags (SANITIZER_UB_AVAILABLE ${SANITIZER_UB_FLAG} )
97- if (SANITIZER_UB_AVAILABLE)
120+ if (SANITIZER_UB_AVAILABLE)
98121 message (STATUS " Building with Undefined Behaviour sanitizer" )
99122 append ("${SANITIZER_UB_FLAG} " SANITIZER_SELECTED_FLAGS )
123+
124+ if (AFL)
125+ append_quoteless (AFL_USE_UBSAN=1 CMAKE_C_COMPILER_LAUNCHER
126+ CMAKE_CXX_COMPILER_LAUNCHER )
127+ endif ()
100128 else ()
101- message (FATAL_ERROR "Undefined Behaviour sanitizer not available for ${CMAKE_CXX_COMPILER} " )
129+ message (
130+ FATAL_ERROR
131+ "Undefined Behaviour sanitizer not available for ${CMAKE_CXX_COMPILER} "
132+ )
102133 endif ()
103134 endif ()
104135
105136 if (USE_SANITIZER MATCHES "([Tt]hread)" )
106137 message (STATUS "Testing with Thread sanitizer" )
107138 set (SANITIZER_THREAD_FLAG "-fsanitize=thread" )
108139 test_san_flags (SANITIZER_THREAD_AVAILABLE ${SANITIZER_THREAD_FLAG} )
109- if (SANITIZER_THREAD_AVAILABLE)
140+ if (SANITIZER_THREAD_AVAILABLE)
110141 message (STATUS " Building with Thread sanitizer" )
111142 append ("${SANITIZER_THREAD_FLAG} " SANITIZER_SELECTED_FLAGS )
143+
144+ if (AFL)
145+ append_quoteless (AFL_USE_TSAN=1 CMAKE_C_COMPILER_LAUNCHER
146+ CMAKE_CXX_COMPILER_LAUNCHER )
147+ endif ()
112148 else ()
113- message (FATAL_ERROR "Thread sanitizer not available for ${CMAKE_CXX_COMPILER} " )
149+ message (
150+ FATAL_ERROR "Thread sanitizer not available for ${CMAKE_CXX_COMPILER} "
151+ )
114152 endif ()
115153 endif ()
116154
117155 if (USE_SANITIZER MATCHES "([Ll]eak)" )
118156 message (STATUS "Testing with Leak sanitizer" )
119157 set (SANITIZER_LEAK_FLAG "-fsanitize=leak" )
120158 test_san_flags (SANITIZER_LEAK_AVAILABLE ${SANITIZER_LEAK_FLAG} )
121- if (SANITIZER_LEAK_AVAILABLE)
159+ if (SANITIZER_LEAK_AVAILABLE)
122160 message (STATUS " Building with Leak sanitizer" )
123161 append ("${SANITIZER_LEAK_FLAG} " SANITIZER_SELECTED_FLAGS )
162+
163+ if (AFL)
164+ append_quoteless (AFL_USE_LSAN=1 CMAKE_C_COMPILER_LAUNCHER
165+ CMAKE_CXX_COMPILER_LAUNCHER )
166+ endif ()
124167 else ()
125- message (FATAL_ERROR "Thread sanitizer not available for ${CMAKE_CXX_COMPILER} " )
168+ message (
169+ FATAL_ERROR "Thread sanitizer not available for ${CMAKE_CXX_COMPILER} "
170+ )
171+ endif ()
172+ endif ()
173+
174+ if (USE_SANITIZER MATCHES "([Cc][Ff][Ii])" )
175+ message (STATUS "Testing with Control Flow Integrity(CFI) sanitizer" )
176+ set (SANITIZER_CFI_FLAG "-fsanitize=cfi" )
177+ test_san_flags (SANITIZER_CFI_AVAILABLE ${SANITIZER_CFI_FLAG} )
178+ if (SANITIZER_CFI_AVAILABLE)
179+ message (STATUS " Building with Control Flow Integrity(CFI) sanitizer" )
180+ append ("${SANITIZER_LEAK_FLAG} " SANITIZER_SELECTED_FLAGS )
181+
182+ if (AFL)
183+ append_quoteless (AFL_USE_CFISAN=1 CMAKE_C_COMPILER_LAUNCHER
184+ CMAKE_CXX_COMPILER_LAUNCHER )
185+ endif ()
186+ else ()
187+ message (
188+ FATAL_ERROR
189+ "Control Flow Integrity(CFI) sanitizer not available for ${CMAKE_CXX_COMPILER} "
190+ )
126191 endif ()
127192 endif ()
128193
129194 message (STATUS "Sanitizer flags: ${SANITIZER_SELECTED_FLAGS} " )
130195 test_san_flags (SANITIZER_SELECTED_COMPATIBLE ${SANITIZER_SELECTED_FLAGS} )
131- if (SANITIZER_SELECTED_COMPATIBLE)
196+ if (SANITIZER_SELECTED_COMPATIBLE)
132197 message (STATUS " Building with ${SANITIZER_SELECTED_FLAGS} " )
133198 append ("${SANITIZER_SELECTED_FLAGS} " CMAKE_C_FLAGS CMAKE_CXX_FLAGS )
134199 else ()
135- message (FATAL_ERROR " Sanitizer flags ${SANITIZER_SELECTED_FLAGS} are not compatible." )
200+ message (
201+ FATAL_ERROR
202+ " Sanitizer flags ${SANITIZER_SELECTED_FLAGS} are not compatible." )
136203 endif ()
137204 elseif (MSVC )
138205 if (USE_SANITIZER MATCHES "([Aa]ddress)" )
139206 message (STATUS "Building with Address sanitizer" )
140207 append ("-fsanitize=address" CMAKE_C_FLAGS CMAKE_CXX_FLAGS )
208+
209+ if (AFL)
210+ append_quoteless (AFL_USE_ASAN=1 CMAKE_C_COMPILER_LAUNCHER
211+ CMAKE_CXX_COMPILER_LAUNCHER )
212+ endif ()
141213 else ()
142214 message (
143215 FATAL_ERROR
0 commit comments