blob: 39c35d3424e793a11cc537b41e59be80b85eb421 [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-Pal83a45bd2023-09-01 11:17:19 +020014
Mate Toth-Pal7b875ea2023-11-15 16:59:19 +010015find_package(Python3 REQUIRED)
16find_program(CHECK_CBMC_SUMMARY_EXECUTABLE "compare_summary.py"
17 PATHS ${CMAKE_SOURCE_DIR}
18 PATH_SUFFIXES tools/cbmc
19 DOC "Path to compare_summary.py"
20 )
21
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +020022#
23# Configure and execute CBMC
24#
25if(NOT (EXISTS "${RMM_CBMC_PATH}"))
26 message(FATAL_ERROR "cbmc executable not found. (${RMM_CBMC_PATH})")
27endif()
28
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +010029string(TOLOWER "${RMM_CBMC_CONFIGURATION}" CBMC_RESULT_FILE_SUFFIX)
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +020030
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +010031if(RMM_CBMC_VIEWER_OUTPUT)
32 set(CBMC_OUT_FILE_ENDING "xml")
33 set(CBMC_UI_OPTION "--xml-ui")
34else()
35 set(CBMC_OUT_FILE_ENDING "output")
36 set(CBMC_UI_OPTION "")
37endif()
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +020038
39set(RMM_TESTBENCH_RESULT_DIR "${BINARY_DIR}/cbmc_${CBMC_RESULT_FILE_SUFFIX}_results")
40set(SUMMARY_FILE "SUMMARY.${CBMC_RESULT_FILE_SUFFIX}")
41set(RMM_CBMC_SUMMARY_FIELD_WIDTH 38)
42
43# Configurations for the initial state.
44set(GRANULE_SHIFT "7")
45set(MAX_NUM_OF_GRANULE "8")
46set(HOST_MEM_SIZE "1024UL")
47
48set(MAX_RTT_UNWIND "6")
49set(MAX_AUX_REC "2")
50set(MAX_ROOT_RTT "3")
51set(MAX_UNWIND_FLAGS "")
52
53#
54# Set up cbmc command line
55#
56set(cbmc_unwinds_list
Mate Toth-Palc751c0d2023-11-14 16:56:41 +010057 "--unwindset;find_lock_granules.3:${MAX_ROOT_RTT}"
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +020058 "--unwindset;find_lock_rd_granules.0:${MAX_RTT_UNWIND}"
59 "--unwindset;find_lock_rd_granules.1:${MAX_RTT_UNWIND}"
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +020060 "--unwindset;free_rec_aux_granules.0:${MAX_AUX_REC}"
Mate Toth-Palc751c0d2023-11-14 16:56:41 +010061 "--unwindset;free_sl_rtts.0:${MAX_RTT_UNWIND}"
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +020062 "--unwindset;init_realm_descriptor_page.0:${MAX_ROOT_RTT}"
Mate Toth-Palc751c0d2023-11-14 16:56:41 +010063 "--unwindset;init_realm_descriptor_page.1:${MAX_ROOT_RTT}"
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +020064 "--unwindset;init_rec.0:${MAX_AUX_REC}"
Mate Toth-Palc751c0d2023-11-14 16:56:41 +010065 "--unwindset;init_rtt_root_page.0:${MAX_ROOT_RTT}"
66 "--unwindset;init_walk_path.0:${MAX_RTT_UNWIND}"
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +020067 "--unwindset;lock_order_invariable.0:21"
68 "--unwindset;lock_order_invariable.1:11"
69 "--unwindset;lock_order_invariable.2:"
Mate Toth-Palc751c0d2023-11-14 16:56:41 +010070 "--unwindset;RealmIsLive.0:${MAX_ROOT_RTT}"
71 "--unwindset;RealmIsLive.2:${MAX_ROOT_RTT}"
72 "--unwindset;rtt_walk_lock_unlock.0:${MAX_RTT_UNWIND}"
73 "--unwindset;RttWalk.0:${MAX_RTT_UNWIND}"
74 "--unwindset;smc_realm_create.0:${MAX_RTT_UNWIND}"
75 "--unwindset;smc_rec_create.0:${MAX_AUX_REC}"
76 "--unwindset;total_root_rtt_refcount.0:${MAX_RTT_UNWIND}"
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +020077)
78
79set(cbmc_defines_list
80 "-DCBMC"
81 "-DDISABLE_COMPILER_ASSERT"
82 "-DDISABLE_SET_MEMBER"
83 "-DGRANULE_SHIFT=${GRANULE_SHIFT}"
84 "-DXLAT_GRANULARITY_SIZE_SHIFT=${GRANULE_SHIFT}"
85 "-DRMM_MAX_GRANULES=${MAX_NUM_OF_GRANULE}"
86 "-DMAX_CPUS=1"
87 "-DMAX_RTT_LEVEL=${MAX_RTT_UNWIND}"
88 "-DHOST_MEM_SIZE=${HOST_MEM_SIZE}"
89 "-DNAME=\"RMM\""
90 "-DVERSION=\"CBMC\""
91 "-DCOMMIT_INFO=\"CBMC\""
AlexeiFedorov4c7d4852024-01-25 14:37:34 +000092 "-DRMM_NUM_PAGES_PER_STACK=1"
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +020093)
94
95# CBMC flags for memory safety analysis and undefined behaviour analysis.
96set(cbmc_analysis_flags_list
97 "--bounds-check"
98 "--pointer-check"
99 "--div-by-zero-check"
100 "--signed-overflow-check"
101 "--unsigned-overflow-check"
102 "--pointer-overflow-check"
103 "--conversion-check"
104 "--undefined-shift-check"
105 "--float-overflow-check"
106 "--nan-check"
107 "--enum-range-check"
108 "--pointer-primitive-check"
109 "--memory-leak-check")
110
111set(cbmc_flags_list
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200112 "--timestamp;wall"
113 "--verbosity;9"
114 # Optimisation flags:
115 "--drop-unused-functions"
116 "--reachability-slice"
117 )
118
119if("${RMM_CBMC_CONFIGURATION}" STREQUAL "COVERAGE")
120 list(APPEND cbmc_flags_list
121 "--cover;cover"
122 "--no-assertions")
123elseif("${RMM_CBMC_CONFIGURATION}" STREQUAL "ASSERT")
124 list(APPEND cbmc_flags_list
125 "--unwinding-assertions"
126 "--trace"
127 "--trace-show-function-calls")
128elseif("${RMM_CBMC_CONFIGURATION}" STREQUAL "ANALYSIS")
129 list(APPEND cbmc_flags_list
130 "--unwinding-assertions"
131 "${cbmc_analysis_flags_list}")
132else()
133 message(FATAL_ERROR "Invalid RMM_CBMC_CONFIGURATION '${RMM_CBMC_CONFIGURATION}'")
134endif()
135
Mate Toth-Palc492f482023-12-19 09:46:29 +0100136# Convert the space separated strings to a CMake list
137string(REPLACE " " ";" TESTBENCH_FILES "${TESTBENCH_FILES}")
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200138
139#
140# Create semi-colon separated list from white-space seperated ones.
141#
142separate_arguments(RMM_IMP_SRCS)
143separate_arguments(RMM_IMP_INCS)
144
145#
146# Execute CBMC on the testbench files
147#
148rmm_cbmc_write_summary_header(${RMM_CBMC_SUMMARY_FIELD_WIDTH}
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100149 ${RMM_TESTBENCH_RESULT_DIR} ${SUMMARY_FILE} ${RMM_CBMC_CONFIGURATION})
150
151function(rmm_cbmc_gen_file_names
152 testbench_file_path
153 filename_prefix
154 out_file_ending
155 cmd_file_var_name
156 out_file_var_name
157 err_file_var_name)
158 get_filename_component(testbench_file_name "${testbench_file_path}" NAME)
159 get_filename_component(parent "${testbench_file_path}" DIRECTORY)
160 set("${cmd_file_var_name}" "${parent}/${filename_prefix}_${testbench_file_name}.cmd" PARENT_SCOPE)
161 set("${out_file_var_name}" "${parent}/${filename_prefix}_${testbench_file_name}.${out_file_ending}" PARENT_SCOPE)
162 set("${err_file_var_name}" "${parent}/${filename_prefix}_${testbench_file_name}.error" PARENT_SCOPE)
163endfunction()
164
165function(normalise_cmd cmd_str out_var_name)
166 # replace the ; with space
167 string (REPLACE ";" " " cmd_str "${cmd_str}")
168 set("${out_var_name}" "${cmd_str}" PARENT_SCOPE)
169endfunction()
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200170
171foreach(testbench_file ${TESTBENCH_FILES})
172
173 string(REPLACE ${TESTBENCH_DIR}/ "" testbench_filename ${testbench_file})
174 string(REGEX REPLACE "\\.[^\\.]*$" "" entry_point "${testbench_filename}")
175
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100176 set(RMM_GOTO_PROG_NAME "${RMM_TESTBENCH_RESULT_DIR}/rmm_${entry_point}.goto")
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200177
178 # Set the names of output files
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100179 string(REPLACE ${TESTBENCH_DIR} ${RMM_TESTBENCH_RESULT_DIR} OUT_FILE_NAME_PREFIX "${testbench_file}")
180 rmm_cbmc_gen_file_names(${OUT_FILE_NAME_PREFIX} "cbmc" "${CBMC_OUT_FILE_ENDING}"
181 cbmc_cmd_file cbmc_output_file cbmc_error_file)
182 rmm_cbmc_gen_file_names(${OUT_FILE_NAME_PREFIX} "cbmc_prop" "xml"
183 cbmc_prop_cmd_file cbmc_prop_output_file cbmc_prop_error_file)
184 rmm_cbmc_gen_file_names(${OUT_FILE_NAME_PREFIX} "goto_cc" "output"
185 goto_cc_cmd_file goto_cc_output_file goto_cc_error_file)
186 rmm_cbmc_gen_file_names(${OUT_FILE_NAME_PREFIX} "cbmc_viewer" "output"
187 cbmc_viewer_cmd_file cbmc_viewer_output_file cbmc_viewer_error_file)
188 set(CBMC_VIEWER_REPORT_DIR "${RMM_TESTBENCH_RESULT_DIR}/report_${entry_point}")
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200189
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100190 set(goto_cc_cmd
191 ${RMM_GOTO_CC_PATH}
192 ${cbmc_compiler_options}
193 ${cbmc_defines_list}
194 "--function;${entry_point}"
195 "-o;${RMM_GOTO_PROG_NAME}"
196 ${RMM_IMP_INCS}
197 ${RMM_IMP_SRCS}
198 ${testbench_file}
199 )
200
201 set(cbmc_cmd
202 ${RMM_CBMC_PATH}
203 ${CBMC_UI_OPTION}
204 ${cbmc_flags_list}
205 ${cbmc_unwinds_list}
206 ${RMM_GOTO_PROG_NAME})
207
208 set(cbmc_prop_cmd
209 ${RMM_CBMC_PATH}
210 ${cbmc_flags_list}
211 "--xml-ui"
212 "--show-properties"
213 ${RMM_GOTO_PROG_NAME})
214
215 set(cbmc_viewer_cmd
216 "${RMM_CBMC_VIEWER_PATH}"
217 "--goto;${RMM_GOTO_PROG_NAME}"
218 "--result;${cbmc_output_file}"
219 "--property;${cbmc_prop_output_file}"
220 "--srcdir;${CMAKE_SOURCE_DIR}"
221 "--reportdir;${CBMC_VIEWER_REPORT_DIR}")
222
223 # remove the absolute path making it relative (shorten the command line)
224 string (REPLACE "${SOURCE_DIR}/" "" goto_cc_cmd "${goto_cc_cmd}")
225
226 normalise_cmd("${goto_cc_cmd}" GOTO_CC_CMD_STR)
227 normalise_cmd("${cbmc_cmd}" CBMC_CMD_STR)
228
229 file(WRITE ${goto_cc_cmd_file} "${GOTO_CC_CMD_STR}")
230 file(WRITE ${cbmc_cmd_file} "${CBMC_CMD_STR}")
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200231
232 execute_process(COMMAND ${CMAKE_COMMAND} -E echo_append "CBMC: ${testbench_file}... ")
233 execute_process(
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100234 COMMAND ${goto_cc_cmd}
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200235 RESULT_VARIABLE res_var
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100236 OUTPUT_FILE ${goto_cc_output_file}
237 ERROR_FILE ${goto_cc_error_file})
238 if (NOT ${res_var} EQUAL "0")
239 message(FATAL_ERROR "Compiling testbench with goto-cc failed. For details see: ${goto_cc_error_file}")
240 endif()
241
242 execute_process(
243 COMMAND ${cbmc_cmd}
244 RESULT_VARIABLE res_var
245 OUTPUT_FILE ${cbmc_output_file}
246 ERROR_FILE ${cbmc_error_file})
247
248 if(RMM_CBMC_VIEWER_OUTPUT)
249 normalise_cmd("${cbmc_prop_cmd}" CBMC_PROP_CMD_STR)
250 file(WRITE ${cbmc_prop_cmd_file} "${CBMC_PROP_CMD_STR}")
251 execute_process(
252 COMMAND ${cbmc_prop_cmd}
253 RESULT_VARIABLE res_var
254 OUTPUT_FILE ${cbmc_prop_output_file}
255 ERROR_FILE ${cbmc_prop_error_file})
256
257 normalise_cmd("${cbmc_viewer_cmd}" CBMC_VIEWER_CMD_STR)
258 file(WRITE ${cbmc_viewer_cmd_file} "${CBMC_VIEWER_CMD_STR}")
259 execute_process(
260 COMMAND ${cbmc_viewer_cmd}
261 RESULT_VARIABLE res_var
262 OUTPUT_FILE ${cbmc_viewer_output_file}
263 ERROR_FILE ${cbmc_viewer_error_file})
264 if (NOT ${res_var} EQUAL "0")
265 message(FATAL_ERROR "Failed to run cbmc-viewer. For details see: ${goto_cc_error_file}")
266 endif()
267 endif()
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200268
269 execute_process(COMMAND ${CMAKE_COMMAND} -E echo "DONE")
270
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100271 rmm_cbmc_append_summary("${testbench_filename}" "${cbmc_output_file}"
272 "${CBMC_RESULT_FILE_SUFFIX}-${CBMC_OUT_FILE_ENDING}"
273 ${RMM_CBMC_SUMMARY_FIELD_WIDTH} ${RMM_TESTBENCH_RESULT_DIR} ${SUMMARY_FILE})
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200274
275endforeach()
276message(STATUS "Result in ${RMM_TESTBENCH_RESULT_DIR}")
Mate Toth-Pal7b875ea2023-11-15 16:59:19 +0100277
Mate Toth-Palc492f482023-12-19 09:46:29 +0100278list(TRANSFORM TESTBENCH_FILES REPLACE "${TESTBENCH_DIR}/" "" OUTPUT_VARIABLE TESTBENCH_FILENAMES)
Mate Toth-Pal7b875ea2023-11-15 16:59:19 +0100279execute_process(
280 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
281 COMMAND ${CHECK_CBMC_SUMMARY_EXECUTABLE}
282 ${CMAKE_SOURCE_DIR}/tools/cbmc/testbenches_results/BASELINE.${CBMC_RESULT_FILE_SUFFIX}
Mate Toth-Palc492f482023-12-19 09:46:29 +0100283 --testbench-files "${TESTBENCH_FILENAMES}"
Mate Toth-Pal7b875ea2023-11-15 16:59:19 +0100284 ${RMM_TESTBENCH_RESULT_DIR}/${SUMMARY_FILE}
285 OUTPUT_VARIABLE CHECK_SUMMARY_OUTPUT
286 ERROR_VARIABLE CHECK_SUMMARY_ERROR
287 RESULT_VARIABLE CHECK_SUMMARY_RC
288 OUTPUT_STRIP_TRAILING_WHITESPACE
289 )
290
291if (NOT ${CHECK_SUMMARY_RC} EQUAL "0")
292 message(WARNING
293 "cbmc-${CBMC_RESULT_FILE_SUFFIX}: FAILED\n${CHECK_SUMMARY_ERROR}")
294else()
295 message(STATUS "cbmc-${CBMC_RESULT_FILE_SUFFIX}: PASSED")
296endif()