blob: 1f9d0304795214bf46a3d1e2f687e4b92d2c9e2a [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
135file(GLOB_RECURSE TESTBENCH_FILES "${TESTBENCH_DIR}/*.c")
136
137#
138# Create semi-colon separated list from white-space seperated ones.
139#
140separate_arguments(RMM_IMP_SRCS)
141separate_arguments(RMM_IMP_INCS)
142
143#
144# Execute CBMC on the testbench files
145#
146rmm_cbmc_write_summary_header(${RMM_CBMC_SUMMARY_FIELD_WIDTH}
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100147 ${RMM_TESTBENCH_RESULT_DIR} ${SUMMARY_FILE} ${RMM_CBMC_CONFIGURATION})
148
149function(rmm_cbmc_gen_file_names
150 testbench_file_path
151 filename_prefix
152 out_file_ending
153 cmd_file_var_name
154 out_file_var_name
155 err_file_var_name)
156 get_filename_component(testbench_file_name "${testbench_file_path}" NAME)
157 get_filename_component(parent "${testbench_file_path}" DIRECTORY)
158 set("${cmd_file_var_name}" "${parent}/${filename_prefix}_${testbench_file_name}.cmd" PARENT_SCOPE)
159 set("${out_file_var_name}" "${parent}/${filename_prefix}_${testbench_file_name}.${out_file_ending}" PARENT_SCOPE)
160 set("${err_file_var_name}" "${parent}/${filename_prefix}_${testbench_file_name}.error" PARENT_SCOPE)
161endfunction()
162
163function(normalise_cmd cmd_str out_var_name)
164 # replace the ; with space
165 string (REPLACE ";" " " cmd_str "${cmd_str}")
166 set("${out_var_name}" "${cmd_str}" PARENT_SCOPE)
167endfunction()
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200168
169foreach(testbench_file ${TESTBENCH_FILES})
170
171 string(REPLACE ${TESTBENCH_DIR}/ "" testbench_filename ${testbench_file})
172 string(REGEX REPLACE "\\.[^\\.]*$" "" entry_point "${testbench_filename}")
173
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100174 set(RMM_GOTO_PROG_NAME "${RMM_TESTBENCH_RESULT_DIR}/rmm_${entry_point}.goto")
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200175
176 # Set the names of output files
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100177 string(REPLACE ${TESTBENCH_DIR} ${RMM_TESTBENCH_RESULT_DIR} OUT_FILE_NAME_PREFIX "${testbench_file}")
178 rmm_cbmc_gen_file_names(${OUT_FILE_NAME_PREFIX} "cbmc" "${CBMC_OUT_FILE_ENDING}"
179 cbmc_cmd_file cbmc_output_file cbmc_error_file)
180 rmm_cbmc_gen_file_names(${OUT_FILE_NAME_PREFIX} "cbmc_prop" "xml"
181 cbmc_prop_cmd_file cbmc_prop_output_file cbmc_prop_error_file)
182 rmm_cbmc_gen_file_names(${OUT_FILE_NAME_PREFIX} "goto_cc" "output"
183 goto_cc_cmd_file goto_cc_output_file goto_cc_error_file)
184 rmm_cbmc_gen_file_names(${OUT_FILE_NAME_PREFIX} "cbmc_viewer" "output"
185 cbmc_viewer_cmd_file cbmc_viewer_output_file cbmc_viewer_error_file)
186 set(CBMC_VIEWER_REPORT_DIR "${RMM_TESTBENCH_RESULT_DIR}/report_${entry_point}")
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200187
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100188 set(goto_cc_cmd
189 ${RMM_GOTO_CC_PATH}
190 ${cbmc_compiler_options}
191 ${cbmc_defines_list}
192 "--function;${entry_point}"
193 "-o;${RMM_GOTO_PROG_NAME}"
194 ${RMM_IMP_INCS}
195 ${RMM_IMP_SRCS}
196 ${testbench_file}
197 )
198
199 set(cbmc_cmd
200 ${RMM_CBMC_PATH}
201 ${CBMC_UI_OPTION}
202 ${cbmc_flags_list}
203 ${cbmc_unwinds_list}
204 ${RMM_GOTO_PROG_NAME})
205
206 set(cbmc_prop_cmd
207 ${RMM_CBMC_PATH}
208 ${cbmc_flags_list}
209 "--xml-ui"
210 "--show-properties"
211 ${RMM_GOTO_PROG_NAME})
212
213 set(cbmc_viewer_cmd
214 "${RMM_CBMC_VIEWER_PATH}"
215 "--goto;${RMM_GOTO_PROG_NAME}"
216 "--result;${cbmc_output_file}"
217 "--property;${cbmc_prop_output_file}"
218 "--srcdir;${CMAKE_SOURCE_DIR}"
219 "--reportdir;${CBMC_VIEWER_REPORT_DIR}")
220
221 # remove the absolute path making it relative (shorten the command line)
222 string (REPLACE "${SOURCE_DIR}/" "" goto_cc_cmd "${goto_cc_cmd}")
223
224 normalise_cmd("${goto_cc_cmd}" GOTO_CC_CMD_STR)
225 normalise_cmd("${cbmc_cmd}" CBMC_CMD_STR)
226
227 file(WRITE ${goto_cc_cmd_file} "${GOTO_CC_CMD_STR}")
228 file(WRITE ${cbmc_cmd_file} "${CBMC_CMD_STR}")
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200229
230 execute_process(COMMAND ${CMAKE_COMMAND} -E echo_append "CBMC: ${testbench_file}... ")
231 execute_process(
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100232 COMMAND ${goto_cc_cmd}
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200233 RESULT_VARIABLE res_var
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100234 OUTPUT_FILE ${goto_cc_output_file}
235 ERROR_FILE ${goto_cc_error_file})
236 if (NOT ${res_var} EQUAL "0")
237 message(FATAL_ERROR "Compiling testbench with goto-cc failed. For details see: ${goto_cc_error_file}")
238 endif()
239
240 execute_process(
241 COMMAND ${cbmc_cmd}
242 RESULT_VARIABLE res_var
243 OUTPUT_FILE ${cbmc_output_file}
244 ERROR_FILE ${cbmc_error_file})
245
246 if(RMM_CBMC_VIEWER_OUTPUT)
247 normalise_cmd("${cbmc_prop_cmd}" CBMC_PROP_CMD_STR)
248 file(WRITE ${cbmc_prop_cmd_file} "${CBMC_PROP_CMD_STR}")
249 execute_process(
250 COMMAND ${cbmc_prop_cmd}
251 RESULT_VARIABLE res_var
252 OUTPUT_FILE ${cbmc_prop_output_file}
253 ERROR_FILE ${cbmc_prop_error_file})
254
255 normalise_cmd("${cbmc_viewer_cmd}" CBMC_VIEWER_CMD_STR)
256 file(WRITE ${cbmc_viewer_cmd_file} "${CBMC_VIEWER_CMD_STR}")
257 execute_process(
258 COMMAND ${cbmc_viewer_cmd}
259 RESULT_VARIABLE res_var
260 OUTPUT_FILE ${cbmc_viewer_output_file}
261 ERROR_FILE ${cbmc_viewer_error_file})
262 if (NOT ${res_var} EQUAL "0")
263 message(FATAL_ERROR "Failed to run cbmc-viewer. For details see: ${goto_cc_error_file}")
264 endif()
265 endif()
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200266
267 execute_process(COMMAND ${CMAKE_COMMAND} -E echo "DONE")
268
Mate Toth-Pal0361dcb2023-11-29 10:20:12 +0100269 rmm_cbmc_append_summary("${testbench_filename}" "${cbmc_output_file}"
270 "${CBMC_RESULT_FILE_SUFFIX}-${CBMC_OUT_FILE_ENDING}"
271 ${RMM_CBMC_SUMMARY_FIELD_WIDTH} ${RMM_TESTBENCH_RESULT_DIR} ${SUMMARY_FILE})
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +0200272
273endforeach()
274message(STATUS "Result in ${RMM_TESTBENCH_RESULT_DIR}")
Mate Toth-Pal7b875ea2023-11-15 16:59:19 +0100275
276execute_process(
277 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
278 COMMAND ${CHECK_CBMC_SUMMARY_EXECUTABLE}
279 ${CMAKE_SOURCE_DIR}/tools/cbmc/testbenches_results/BASELINE.${CBMC_RESULT_FILE_SUFFIX}
280 ${RMM_TESTBENCH_RESULT_DIR}/${SUMMARY_FILE}
281 OUTPUT_VARIABLE CHECK_SUMMARY_OUTPUT
282 ERROR_VARIABLE CHECK_SUMMARY_ERROR
283 RESULT_VARIABLE CHECK_SUMMARY_RC
284 OUTPUT_STRIP_TRAILING_WHITESPACE
285 )
286
287if (NOT ${CHECK_SUMMARY_RC} EQUAL "0")
288 message(WARNING
289 "cbmc-${CBMC_RESULT_FILE_SUFFIX}: FAILED\n${CHECK_SUMMARY_ERROR}")
290else()
291 message(STATUS "cbmc-${CBMC_RESULT_FILE_SUFFIX}: PASSED")
292endif()