blob: bfb6447607b9a820c9c84ea40e9a5c1742839c7b [file] [log] [blame]
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +02001#
2# SPDX-License-Identifier: BSD-3-Clause
3# SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4#
5
6include(FetchContent)
7include("${SOURCE_DIR}/tools/cbmc/SummaryHelpers.cmake")
8find_program(RMM_CBMC_PATH "cbmc"
9 DOC "Path to cbmc.")
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +010010find_program(RMM_GOTO_CC_PATH "goto-cc"
11 DOC "Path to goto-cc.")
12find_program(RMM_CBMC_VIEWER_PATH "cbmc-viewer"
13 DOC "Path to cbmc-viewer.")
Mate Toth-Pal0da58112024-01-10 11:49:58 +010014find_program(RMM_GCC_PATH "gcc"
15 DOC "Path to gcc.")
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +020016
Mate Toth-Pal7b875ea2023-11-15 16:59:19 +010017find_package(Python3 REQUIRED)
18find_program(CHECK_CBMC_SUMMARY_EXECUTABLE "compare_summary.py"
19 PATHS ${CMAKE_SOURCE_DIR}
20 PATH_SUFFIXES tools/cbmc
21 DOC "Path to compare_summary.py"
22 )
23
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +020024#
25# Configure and execute CBMC
26#
27if(NOT (EXISTS "${RMM_CBMC_PATH}"))
28 message(FATAL_ERROR "cbmc executable not found. (${RMM_CBMC_PATH})")
29endif()
30
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +010031string(TOLOWER "${RMM_CBMC_CONFIGURATION}" CBMC_RESULT_FILE_SUFFIX)
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +020032
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +010033if(RMM_CBMC_VIEWER_OUTPUT)
34 set(CBMC_OUT_FILE_ENDING "xml")
35 set(CBMC_UI_OPTION "--xml-ui")
36else()
37 set(CBMC_OUT_FILE_ENDING "output")
38 set(CBMC_UI_OPTION "")
39endif()
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +020040
Mate Toth-Pal0da58112024-01-10 11:49:58 +010041if(${RMM_CBMC_CONFIGURATION} STREQUAL "GCC")
42 set(COMPILED_FILE_PREFIX "gcc")
43 set(RMM_CBMC_COMPILER_PATH "${RMM_GCC_PATH}")
44 list(APPEND RMM_IMP_SRCS "${TESTBENCH_DIR}/../gcc/gcc_defs.c")
45else()
46 set(COMPILED_FILE_PREFIX "goto_cc")
47 set(RMM_CBMC_COMPILER_PATH "${RMM_GOTO_CC_PATH}")
48endif()
49
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +020050set(RMM_TESTBENCH_RESULT_DIR "${BINARY_DIR}/cbmc_${CBMC_RESULT_FILE_SUFFIX}_results")
51set(SUMMARY_FILE "SUMMARY.${CBMC_RESULT_FILE_SUFFIX}")
52set(RMM_CBMC_SUMMARY_FIELD_WIDTH 38)
53
54# Configurations for the initial state.
Mate Toth-Pal70ae89d2024-01-11 13:47:28 +010055set(GRANULE_SHIFT "9")
56set(MAX_NUM_OF_GRANULE "4")
57math(EXPR HOST_MEM_SIZE "(1 << ${GRANULE_SHIFT}) * ${MAX_NUM_OF_GRANULE}")
58set(HOST_MEM_SIZE "${HOST_MEM_SIZE}UL")
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +020059
60set(MAX_RTT_UNWIND "6")
61set(MAX_AUX_REC "2")
62set(MAX_ROOT_RTT "3")
63set(MAX_UNWIND_FLAGS "")
64
65#
66# Set up cbmc command line
67#
68set(cbmc_unwinds_list
Mate Toth-Palc751c0d2023-11-14 16:56:41 +010069 "--unwindset;find_lock_granules.3:${MAX_ROOT_RTT}"
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +020070 "--unwindset;find_lock_rd_granules.0:${MAX_RTT_UNWIND}"
71 "--unwindset;find_lock_rd_granules.1:${MAX_RTT_UNWIND}"
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +020072 "--unwindset;free_rec_aux_granules.0:${MAX_AUX_REC}"
Mate Toth-Palc751c0d2023-11-14 16:56:41 +010073 "--unwindset;free_sl_rtts.0:${MAX_RTT_UNWIND}"
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +020074 "--unwindset;init_realm_descriptor_page.0:${MAX_ROOT_RTT}"
Mate Toth-Palc751c0d2023-11-14 16:56:41 +010075 "--unwindset;init_realm_descriptor_page.1:${MAX_ROOT_RTT}"
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +020076 "--unwindset;init_rec.0:${MAX_AUX_REC}"
Mate Toth-Palc751c0d2023-11-14 16:56:41 +010077 "--unwindset;init_rtt_root_page.0:${MAX_ROOT_RTT}"
78 "--unwindset;init_walk_path.0:${MAX_RTT_UNWIND}"
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +020079 "--unwindset;lock_order_invariable.0:21"
80 "--unwindset;lock_order_invariable.1:11"
81 "--unwindset;lock_order_invariable.2:"
Mate Toth-Palc751c0d2023-11-14 16:56:41 +010082 "--unwindset;RealmIsLive.0:${MAX_ROOT_RTT}"
83 "--unwindset;RealmIsLive.2:${MAX_ROOT_RTT}"
84 "--unwindset;rtt_walk_lock_unlock.0:${MAX_RTT_UNWIND}"
85 "--unwindset;RttWalk.0:${MAX_RTT_UNWIND}"
86 "--unwindset;smc_realm_create.0:${MAX_RTT_UNWIND}"
87 "--unwindset;smc_rec_create.0:${MAX_AUX_REC}"
88 "--unwindset;total_root_rtt_refcount.0:${MAX_RTT_UNWIND}"
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +020089)
90
91set(cbmc_defines_list
92 "-DCBMC"
93 "-DDISABLE_COMPILER_ASSERT"
94 "-DDISABLE_SET_MEMBER"
95 "-DGRANULE_SHIFT=${GRANULE_SHIFT}"
96 "-DXLAT_GRANULARITY_SIZE_SHIFT=${GRANULE_SHIFT}"
97 "-DRMM_MAX_GRANULES=${MAX_NUM_OF_GRANULE}"
98 "-DMAX_CPUS=1"
99 "-DMAX_RTT_LEVEL=${MAX_RTT_UNWIND}"
100 "-DHOST_MEM_SIZE=${HOST_MEM_SIZE}"
101 "-DNAME=\"RMM\""
102 "-DVERSION=\"CBMC\""
103 "-DCOMMIT_INFO=\"CBMC\""
AlexeiFedorov4c7d4852024-01-25 14:37:34 +0000104 "-DRMM_NUM_PAGES_PER_STACK=1"
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200105)
106
107# CBMC flags for memory safety analysis and undefined behaviour analysis.
108set(cbmc_analysis_flags_list
109 "--bounds-check"
110 "--pointer-check"
111 "--div-by-zero-check"
112 "--signed-overflow-check"
113 "--unsigned-overflow-check"
114 "--pointer-overflow-check"
115 "--conversion-check"
116 "--undefined-shift-check"
117 "--float-overflow-check"
118 "--nan-check"
119 "--enum-range-check"
120 "--pointer-primitive-check"
121 "--memory-leak-check")
122
123set(cbmc_flags_list
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200124 "--timestamp;wall"
125 "--verbosity;9"
126 # Optimisation flags:
127 "--drop-unused-functions"
128 "--reachability-slice"
129 )
130
131if("${RMM_CBMC_CONFIGURATION}" STREQUAL "COVERAGE")
132 list(APPEND cbmc_flags_list
133 "--cover;cover"
134 "--no-assertions")
135elseif("${RMM_CBMC_CONFIGURATION}" STREQUAL "ASSERT")
136 list(APPEND cbmc_flags_list
137 "--unwinding-assertions"
138 "--trace"
139 "--trace-show-function-calls")
140elseif("${RMM_CBMC_CONFIGURATION}" STREQUAL "ANALYSIS")
141 list(APPEND cbmc_flags_list
142 "--unwinding-assertions"
143 "${cbmc_analysis_flags_list}")
Mate Toth-Pal0da58112024-01-10 11:49:58 +0100144elseif("${RMM_CBMC_CONFIGURATION}" STREQUAL "GCC")
145 list(APPEND cbmc_compiler_options
146 "-Wall"
147 "-Werror"
148 "-Wno-unused-function"
149 "-Wno-main" # Do not warning on the non-standard signature of main
150 "-Wno-error=unused-variable" # Some of the testbenches contain unused variables
151 "-include;${TESTBENCH_DIR}/../gcc/gcc_defs.h")
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200152else()
153 message(FATAL_ERROR "Invalid RMM_CBMC_CONFIGURATION '${RMM_CBMC_CONFIGURATION}'")
154endif()
155
Mate Toth-Palc492f482023-12-19 09:46:29 +0100156# Convert the space separated strings to a CMake list
157string(REPLACE " " ";" TESTBENCH_FILES "${TESTBENCH_FILES}")
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200158
159#
160# Create semi-colon separated list from white-space seperated ones.
161#
162separate_arguments(RMM_IMP_SRCS)
163separate_arguments(RMM_IMP_INCS)
164
165#
166# Execute CBMC on the testbench files
167#
168rmm_cbmc_write_summary_header(${RMM_CBMC_SUMMARY_FIELD_WIDTH}
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100169 ${RMM_TESTBENCH_RESULT_DIR} ${SUMMARY_FILE} ${RMM_CBMC_CONFIGURATION})
170
171function(rmm_cbmc_gen_file_names
172 testbench_file_path
173 filename_prefix
174 out_file_ending
175 cmd_file_var_name
176 out_file_var_name
177 err_file_var_name)
178 get_filename_component(testbench_file_name "${testbench_file_path}" NAME)
179 get_filename_component(parent "${testbench_file_path}" DIRECTORY)
180 set("${cmd_file_var_name}" "${parent}/${filename_prefix}_${testbench_file_name}.cmd" PARENT_SCOPE)
181 set("${out_file_var_name}" "${parent}/${filename_prefix}_${testbench_file_name}.${out_file_ending}" PARENT_SCOPE)
182 set("${err_file_var_name}" "${parent}/${filename_prefix}_${testbench_file_name}.error" PARENT_SCOPE)
183endfunction()
184
185function(normalise_cmd cmd_str out_var_name)
186 # replace the ; with space
187 string (REPLACE ";" " " cmd_str "${cmd_str}")
188 set("${out_var_name}" "${cmd_str}" PARENT_SCOPE)
189endfunction()
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200190
191foreach(testbench_file ${TESTBENCH_FILES})
192
193 string(REPLACE ${TESTBENCH_DIR}/ "" testbench_filename ${testbench_file})
194 string(REGEX REPLACE "\\.[^\\.]*$" "" entry_point "${testbench_filename}")
195
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100196 set(RMM_GOTO_PROG_NAME "${RMM_TESTBENCH_RESULT_DIR}/rmm_${entry_point}.goto")
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200197
198 # Set the names of output files
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100199 string(REPLACE ${TESTBENCH_DIR} ${RMM_TESTBENCH_RESULT_DIR} OUT_FILE_NAME_PREFIX "${testbench_file}")
200 rmm_cbmc_gen_file_names(${OUT_FILE_NAME_PREFIX} "cbmc" "${CBMC_OUT_FILE_ENDING}"
201 cbmc_cmd_file cbmc_output_file cbmc_error_file)
202 rmm_cbmc_gen_file_names(${OUT_FILE_NAME_PREFIX} "cbmc_prop" "xml"
203 cbmc_prop_cmd_file cbmc_prop_output_file cbmc_prop_error_file)
Mate Toth-Pal0da58112024-01-10 11:49:58 +0100204 rmm_cbmc_gen_file_names(${OUT_FILE_NAME_PREFIX} "${COMPILED_FILE_PREFIX}" "output"
205 compile_cmd_file compile_output_file compile_error_file)
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100206 rmm_cbmc_gen_file_names(${OUT_FILE_NAME_PREFIX} "cbmc_viewer" "output"
207 cbmc_viewer_cmd_file cbmc_viewer_output_file cbmc_viewer_error_file)
208 set(CBMC_VIEWER_REPORT_DIR "${RMM_TESTBENCH_RESULT_DIR}/report_${entry_point}")
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200209
Mate Toth-Pal0da58112024-01-10 11:49:58 +0100210 if(${RMM_CBMC_CONFIGURATION} STREQUAL "GCC")
211 set(CBMC_ENTRY_POINT "-D${entry_point}=main")
212 else()
213 set(CBMC_ENTRY_POINT "--function;${entry_point}")
214 endif()
215
216 set(compile_cmd
217 ${RMM_CBMC_COMPILER_PATH}
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100218 ${cbmc_compiler_options}
219 ${cbmc_defines_list}
Mate Toth-Pal0da58112024-01-10 11:49:58 +0100220 ${CBMC_ENTRY_POINT}
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100221 "-o;${RMM_GOTO_PROG_NAME}"
222 ${RMM_IMP_INCS}
223 ${RMM_IMP_SRCS}
224 ${testbench_file}
225 )
226
227 set(cbmc_cmd
228 ${RMM_CBMC_PATH}
229 ${CBMC_UI_OPTION}
230 ${cbmc_flags_list}
231 ${cbmc_unwinds_list}
232 ${RMM_GOTO_PROG_NAME})
233
234 set(cbmc_prop_cmd
235 ${RMM_CBMC_PATH}
236 ${cbmc_flags_list}
237 "--xml-ui"
238 "--show-properties"
239 ${RMM_GOTO_PROG_NAME})
240
241 set(cbmc_viewer_cmd
242 "${RMM_CBMC_VIEWER_PATH}"
243 "--goto;${RMM_GOTO_PROG_NAME}"
244 "--result;${cbmc_output_file}"
245 "--property;${cbmc_prop_output_file}"
246 "--srcdir;${CMAKE_SOURCE_DIR}"
247 "--reportdir;${CBMC_VIEWER_REPORT_DIR}")
248
249 # remove the absolute path making it relative (shorten the command line)
Mate Toth-Pal0da58112024-01-10 11:49:58 +0100250 string (REPLACE "${SOURCE_DIR}/" "" compile_cmd "${compile_cmd}")
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100251
Mate Toth-Pal0da58112024-01-10 11:49:58 +0100252 normalise_cmd("${compile_cmd}" COMPILE_CMD_STR)
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100253 normalise_cmd("${cbmc_cmd}" CBMC_CMD_STR)
254
Mate Toth-Pal0da58112024-01-10 11:49:58 +0100255 file(WRITE ${compile_cmd_file} "${COMPILE_CMD_STR}")
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100256 file(WRITE ${cbmc_cmd_file} "${CBMC_CMD_STR}")
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200257
258 execute_process(COMMAND ${CMAKE_COMMAND} -E echo_append "CBMC: ${testbench_file}... ")
259 execute_process(
Mate Toth-Pal0da58112024-01-10 11:49:58 +0100260 COMMAND ${compile_cmd}
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200261 RESULT_VARIABLE res_var
Mate Toth-Pal0da58112024-01-10 11:49:58 +0100262 OUTPUT_FILE ${compile_output_file}
263 ERROR_FILE ${compile_error_file})
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100264 if (NOT ${res_var} EQUAL "0")
Mate Toth-Pal0da58112024-01-10 11:49:58 +0100265 message(FATAL_ERROR "Compiling testbench with ${RMM_CBMC_COMPILER_PATH} failed. For details see: ${compile_error_file}")
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100266 endif()
267
Mate Toth-Pal0da58112024-01-10 11:49:58 +0100268 # Only run CBMC if not using compiler-only mode:
269 if(NOT ${RMM_CBMC_CONFIGURATION} STREQUAL "GCC")
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100270 execute_process(
Mate Toth-Pal0da58112024-01-10 11:49:58 +0100271 COMMAND ${cbmc_cmd}
272 RESULT_VARIABLE res_var
273 OUTPUT_FILE ${cbmc_output_file}
274 ERROR_FILE ${cbmc_error_file})
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100275
Mate Toth-Pal0da58112024-01-10 11:49:58 +0100276 if(RMM_CBMC_VIEWER_OUTPUT)
277 normalise_cmd("${cbmc_prop_cmd}" CBMC_PROP_CMD_STR)
278 file(WRITE ${cbmc_prop_cmd_file} "${CBMC_PROP_CMD_STR}")
279 execute_process(
280 COMMAND ${cbmc_prop_cmd}
281 RESULT_VARIABLE res_var
282 OUTPUT_FILE ${cbmc_prop_output_file}
283 ERROR_FILE ${cbmc_prop_error_file})
284
285 normalise_cmd("${cbmc_viewer_cmd}" CBMC_VIEWER_CMD_STR)
286 file(WRITE ${cbmc_viewer_cmd_file} "${CBMC_VIEWER_CMD_STR}")
287 execute_process(
288 COMMAND ${cbmc_viewer_cmd}
289 RESULT_VARIABLE res_var
290 OUTPUT_FILE ${cbmc_viewer_output_file}
291 ERROR_FILE ${cbmc_viewer_error_file})
292 if (NOT ${res_var} EQUAL "0")
293 message(FATAL_ERROR "Failed to run cbmc-viewer. For details see: ${cbmc_viewer_error_file}")
294 endif()
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100295 endif()
Mate Toth-Pal0da58112024-01-10 11:49:58 +0100296
297 rmm_cbmc_append_summary("${testbench_filename}" "${cbmc_output_file}"
298 "${CBMC_RESULT_FILE_SUFFIX}-${CBMC_OUT_FILE_ENDING}"
299 ${RMM_CBMC_SUMMARY_FIELD_WIDTH} ${RMM_TESTBENCH_RESULT_DIR} ${SUMMARY_FILE})
300
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100301 endif()
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200302
303 execute_process(COMMAND ${CMAKE_COMMAND} -E echo "DONE")
304
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200305endforeach()
306message(STATUS "Result in ${RMM_TESTBENCH_RESULT_DIR}")
Mate Toth-Pal7b875ea2023-11-15 16:59:19 +0100307
Mate Toth-Pal0da58112024-01-10 11:49:58 +0100308# Only run CBMC if not using compiler-only mode:
309if(NOT ${RMM_CBMC_CONFIGURATION} STREQUAL "GCC")
310 list(TRANSFORM TESTBENCH_FILES REPLACE "${TESTBENCH_DIR}/" "" OUTPUT_VARIABLE TESTBENCH_FILENAMES)
311 execute_process(
312 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
313 COMMAND ${CHECK_CBMC_SUMMARY_EXECUTABLE}
314 ${CMAKE_SOURCE_DIR}/tools/cbmc/testbenches_results/BASELINE.${CBMC_RESULT_FILE_SUFFIX}
315 --testbench-files "${TESTBENCH_FILENAMES}"
316 ${RMM_TESTBENCH_RESULT_DIR}/${SUMMARY_FILE}
317 OUTPUT_VARIABLE CHECK_SUMMARY_OUTPUT
318 ERROR_VARIABLE CHECK_SUMMARY_ERROR
319 RESULT_VARIABLE CHECK_SUMMARY_RC
320 OUTPUT_STRIP_TRAILING_WHITESPACE
321 )
Mate Toth-Pal7b875ea2023-11-15 16:59:19 +0100322
Mate Toth-Pal0da58112024-01-10 11:49:58 +0100323 if (NOT ${CHECK_SUMMARY_RC} EQUAL "0")
324 message(WARNING
325 "cbmc-${CBMC_RESULT_FILE_SUFFIX}: FAILED\n${CHECK_SUMMARY_ERROR}")
326 else()
327 message(STATUS "cbmc-${CBMC_RESULT_FILE_SUFFIX}: PASSED")
328 endif()
Mate Toth-Pal7b875ea2023-11-15 16:59:19 +0100329endif()