blob: e31e82fa5e307718a14bf54d403d7e72de3f3187 [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\""
92)
93
94# CBMC flags for memory safety analysis and undefined behaviour analysis.
95set(cbmc_analysis_flags_list
96 "--bounds-check"
97 "--pointer-check"
98 "--div-by-zero-check"
99 "--signed-overflow-check"
100 "--unsigned-overflow-check"
101 "--pointer-overflow-check"
102 "--conversion-check"
103 "--undefined-shift-check"
104 "--float-overflow-check"
105 "--nan-check"
106 "--enum-range-check"
107 "--pointer-primitive-check"
108 "--memory-leak-check")
109
110set(cbmc_flags_list
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200111 "--timestamp;wall"
112 "--verbosity;9"
113 # Optimisation flags:
114 "--drop-unused-functions"
115 "--reachability-slice"
116 )
117
118if("${RMM_CBMC_CONFIGURATION}" STREQUAL "COVERAGE")
119 list(APPEND cbmc_flags_list
120 "--cover;cover"
121 "--no-assertions")
122elseif("${RMM_CBMC_CONFIGURATION}" STREQUAL "ASSERT")
123 list(APPEND cbmc_flags_list
124 "--unwinding-assertions"
125 "--trace"
126 "--trace-show-function-calls")
127elseif("${RMM_CBMC_CONFIGURATION}" STREQUAL "ANALYSIS")
128 list(APPEND cbmc_flags_list
129 "--unwinding-assertions"
130 "${cbmc_analysis_flags_list}")
131else()
132 message(FATAL_ERROR "Invalid RMM_CBMC_CONFIGURATION '${RMM_CBMC_CONFIGURATION}'")
133endif()
134
Mate Toth-Palc492f482023-12-19 09:46:29 +0100135# Convert the space separated strings to a CMake list
136string(REPLACE " " ";" TESTBENCH_FILES "${TESTBENCH_FILES}")
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200137
138#
139# Create semi-colon separated list from white-space seperated ones.
140#
141separate_arguments(RMM_IMP_SRCS)
142separate_arguments(RMM_IMP_INCS)
143
144#
145# Execute CBMC on the testbench files
146#
147rmm_cbmc_write_summary_header(${RMM_CBMC_SUMMARY_FIELD_WIDTH}
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100148 ${RMM_TESTBENCH_RESULT_DIR} ${SUMMARY_FILE} ${RMM_CBMC_CONFIGURATION})
149
150function(rmm_cbmc_gen_file_names
151 testbench_file_path
152 filename_prefix
153 out_file_ending
154 cmd_file_var_name
155 out_file_var_name
156 err_file_var_name)
157 get_filename_component(testbench_file_name "${testbench_file_path}" NAME)
158 get_filename_component(parent "${testbench_file_path}" DIRECTORY)
159 set("${cmd_file_var_name}" "${parent}/${filename_prefix}_${testbench_file_name}.cmd" PARENT_SCOPE)
160 set("${out_file_var_name}" "${parent}/${filename_prefix}_${testbench_file_name}.${out_file_ending}" PARENT_SCOPE)
161 set("${err_file_var_name}" "${parent}/${filename_prefix}_${testbench_file_name}.error" PARENT_SCOPE)
162endfunction()
163
164function(normalise_cmd cmd_str out_var_name)
165 # replace the ; with space
166 string (REPLACE ";" " " cmd_str "${cmd_str}")
167 set("${out_var_name}" "${cmd_str}" PARENT_SCOPE)
168endfunction()
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200169
170foreach(testbench_file ${TESTBENCH_FILES})
171
172 string(REPLACE ${TESTBENCH_DIR}/ "" testbench_filename ${testbench_file})
173 string(REGEX REPLACE "\\.[^\\.]*$" "" entry_point "${testbench_filename}")
174
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100175 set(RMM_GOTO_PROG_NAME "${RMM_TESTBENCH_RESULT_DIR}/rmm_${entry_point}.goto")
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200176
177 # Set the names of output files
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100178 string(REPLACE ${TESTBENCH_DIR} ${RMM_TESTBENCH_RESULT_DIR} OUT_FILE_NAME_PREFIX "${testbench_file}")
179 rmm_cbmc_gen_file_names(${OUT_FILE_NAME_PREFIX} "cbmc" "${CBMC_OUT_FILE_ENDING}"
180 cbmc_cmd_file cbmc_output_file cbmc_error_file)
181 rmm_cbmc_gen_file_names(${OUT_FILE_NAME_PREFIX} "cbmc_prop" "xml"
182 cbmc_prop_cmd_file cbmc_prop_output_file cbmc_prop_error_file)
183 rmm_cbmc_gen_file_names(${OUT_FILE_NAME_PREFIX} "goto_cc" "output"
184 goto_cc_cmd_file goto_cc_output_file goto_cc_error_file)
185 rmm_cbmc_gen_file_names(${OUT_FILE_NAME_PREFIX} "cbmc_viewer" "output"
186 cbmc_viewer_cmd_file cbmc_viewer_output_file cbmc_viewer_error_file)
187 set(CBMC_VIEWER_REPORT_DIR "${RMM_TESTBENCH_RESULT_DIR}/report_${entry_point}")
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200188
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100189 set(goto_cc_cmd
190 ${RMM_GOTO_CC_PATH}
191 ${cbmc_compiler_options}
192 ${cbmc_defines_list}
193 "--function;${entry_point}"
194 "-o;${RMM_GOTO_PROG_NAME}"
195 ${RMM_IMP_INCS}
196 ${RMM_IMP_SRCS}
197 ${testbench_file}
198 )
199
200 set(cbmc_cmd
201 ${RMM_CBMC_PATH}
202 ${CBMC_UI_OPTION}
203 ${cbmc_flags_list}
204 ${cbmc_unwinds_list}
205 ${RMM_GOTO_PROG_NAME})
206
207 set(cbmc_prop_cmd
208 ${RMM_CBMC_PATH}
209 ${cbmc_flags_list}
210 "--xml-ui"
211 "--show-properties"
212 ${RMM_GOTO_PROG_NAME})
213
214 set(cbmc_viewer_cmd
215 "${RMM_CBMC_VIEWER_PATH}"
216 "--goto;${RMM_GOTO_PROG_NAME}"
217 "--result;${cbmc_output_file}"
218 "--property;${cbmc_prop_output_file}"
219 "--srcdir;${CMAKE_SOURCE_DIR}"
220 "--reportdir;${CBMC_VIEWER_REPORT_DIR}")
221
222 # remove the absolute path making it relative (shorten the command line)
223 string (REPLACE "${SOURCE_DIR}/" "" goto_cc_cmd "${goto_cc_cmd}")
224
225 normalise_cmd("${goto_cc_cmd}" GOTO_CC_CMD_STR)
226 normalise_cmd("${cbmc_cmd}" CBMC_CMD_STR)
227
228 file(WRITE ${goto_cc_cmd_file} "${GOTO_CC_CMD_STR}")
229 file(WRITE ${cbmc_cmd_file} "${CBMC_CMD_STR}")
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200230
231 execute_process(COMMAND ${CMAKE_COMMAND} -E echo_append "CBMC: ${testbench_file}... ")
232 execute_process(
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100233 COMMAND ${goto_cc_cmd}
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200234 RESULT_VARIABLE res_var
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100235 OUTPUT_FILE ${goto_cc_output_file}
236 ERROR_FILE ${goto_cc_error_file})
237 if (NOT ${res_var} EQUAL "0")
238 message(FATAL_ERROR "Compiling testbench with goto-cc failed. For details see: ${goto_cc_error_file}")
239 endif()
240
241 execute_process(
242 COMMAND ${cbmc_cmd}
243 RESULT_VARIABLE res_var
244 OUTPUT_FILE ${cbmc_output_file}
245 ERROR_FILE ${cbmc_error_file})
246
247 if(RMM_CBMC_VIEWER_OUTPUT)
248 normalise_cmd("${cbmc_prop_cmd}" CBMC_PROP_CMD_STR)
249 file(WRITE ${cbmc_prop_cmd_file} "${CBMC_PROP_CMD_STR}")
250 execute_process(
251 COMMAND ${cbmc_prop_cmd}
252 RESULT_VARIABLE res_var
253 OUTPUT_FILE ${cbmc_prop_output_file}
254 ERROR_FILE ${cbmc_prop_error_file})
255
256 normalise_cmd("${cbmc_viewer_cmd}" CBMC_VIEWER_CMD_STR)
257 file(WRITE ${cbmc_viewer_cmd_file} "${CBMC_VIEWER_CMD_STR}")
258 execute_process(
259 COMMAND ${cbmc_viewer_cmd}
260 RESULT_VARIABLE res_var
261 OUTPUT_FILE ${cbmc_viewer_output_file}
262 ERROR_FILE ${cbmc_viewer_error_file})
263 if (NOT ${res_var} EQUAL "0")
264 message(FATAL_ERROR "Failed to run cbmc-viewer. For details see: ${goto_cc_error_file}")
265 endif()
266 endif()
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200267
268 execute_process(COMMAND ${CMAKE_COMMAND} -E echo "DONE")
269
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100270 rmm_cbmc_append_summary("${testbench_filename}" "${cbmc_output_file}"
271 "${CBMC_RESULT_FILE_SUFFIX}-${CBMC_OUT_FILE_ENDING}"
272 ${RMM_CBMC_SUMMARY_FIELD_WIDTH} ${RMM_TESTBENCH_RESULT_DIR} ${SUMMARY_FILE})
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200273
274endforeach()
275message(STATUS "Result in ${RMM_TESTBENCH_RESULT_DIR}")
Mate Toth-Pal7b875ea2023-11-15 16:59:19 +0100276
Mate Toth-Palc492f482023-12-19 09:46:29 +0100277list(TRANSFORM TESTBENCH_FILES REPLACE "${TESTBENCH_DIR}/" "" OUTPUT_VARIABLE TESTBENCH_FILENAMES)
Mate Toth-Pal7b875ea2023-11-15 16:59:19 +0100278execute_process(
279 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
280 COMMAND ${CHECK_CBMC_SUMMARY_EXECUTABLE}
281 ${CMAKE_SOURCE_DIR}/tools/cbmc/testbenches_results/BASELINE.${CBMC_RESULT_FILE_SUFFIX}
Mate Toth-Palc492f482023-12-19 09:46:29 +0100282 --testbench-files "${TESTBENCH_FILENAMES}"
Mate Toth-Pal7b875ea2023-11-15 16:59:19 +0100283 ${RMM_TESTBENCH_RESULT_DIR}/${SUMMARY_FILE}
284 OUTPUT_VARIABLE CHECK_SUMMARY_OUTPUT
285 ERROR_VARIABLE CHECK_SUMMARY_ERROR
286 RESULT_VARIABLE CHECK_SUMMARY_RC
287 OUTPUT_STRIP_TRAILING_WHITESPACE
288 )
289
290if (NOT ${CHECK_SUMMARY_RC} EQUAL "0")
291 message(WARNING
292 "cbmc-${CBMC_RESULT_FILE_SUFFIX}: FAILED\n${CHECK_SUMMARY_ERROR}")
293else()
294 message(STATUS "cbmc-${CBMC_RESULT_FILE_SUFFIX}: PASSED")
295endif()