blob: 4eecfdb98956f5980a6ed0307ea5fdd3d5c774c2 [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.")
10
Mate Toth-Pal7b875ea2023-11-15 16:59:19 +010011find_package(Python3 REQUIRED)
12find_program(CHECK_CBMC_SUMMARY_EXECUTABLE "compare_summary.py"
13 PATHS ${CMAKE_SOURCE_DIR}
14 PATH_SUFFIXES tools/cbmc
15 DOC "Path to compare_summary.py"
16 )
17
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +020018#
19# Configure and execute CBMC
20#
21if(NOT (EXISTS "${RMM_CBMC_PATH}"))
22 message(FATAL_ERROR "cbmc executable not found. (${RMM_CBMC_PATH})")
23endif()
24
25if("${RMM_CBMC_CONFIGURATION}" STREQUAL "COVERAGE")
26 set(CBMC_RESULT_FILE_SUFFIX "coverage")
27 set(CBMC_SUMMARY_HEADER "COVERAGE")
28 set(CBMC_SUMMARY_PATTERN "covered")
29elseif("${RMM_CBMC_CONFIGURATION}" STREQUAL "ASSERT")
30 set(CBMC_RESULT_FILE_SUFFIX "assert")
31 set(CBMC_SUMMARY_HEADER "ASSERT")
32 set(CBMC_SUMMARY_PATTERN "failed")
33elseif("${RMM_CBMC_CONFIGURATION}" STREQUAL "ANALYSIS")
34 set(CBMC_RESULT_FILE_SUFFIX "analysis")
35 set(CBMC_SUMMARY_HEADER "ANALYSIS")
36 set(CBMC_SUMMARY_PATTERN "failed")
37else()
38 message(FATAL_ERROR "Invalid RMM_CBMC_CONFIGURATION '${RMM_CBMC_CONFIGURATION}'")
39endif()
40
41
42set(RMM_TESTBENCH_RESULT_DIR "${BINARY_DIR}/cbmc_${CBMC_RESULT_FILE_SUFFIX}_results")
43set(SUMMARY_FILE "SUMMARY.${CBMC_RESULT_FILE_SUFFIX}")
44set(RMM_CBMC_SUMMARY_FIELD_WIDTH 38)
45
46# Configurations for the initial state.
47set(GRANULE_SHIFT "7")
48set(MAX_NUM_OF_GRANULE "8")
49set(HOST_MEM_SIZE "1024UL")
50
51set(MAX_RTT_UNWIND "6")
52set(MAX_AUX_REC "2")
53set(MAX_ROOT_RTT "3")
54set(MAX_UNWIND_FLAGS "")
55
56#
57# Set up cbmc command line
58#
59set(cbmc_unwinds_list
60 "--unwindset;find_lock_rd_granules.0:${MAX_RTT_UNWIND}"
61 "--unwindset;find_lock_rd_granules.1:${MAX_RTT_UNWIND}"
62 "--unwindset;smc_realm_create.0:${MAX_RTT_UNWIND}"
63 "--unwindset;total_root_rtt_refcount.0:${MAX_RTT_UNWIND}"
64 "--unwindset;free_sl_rtts.0:${MAX_RTT_UNWIND}"
65 "--unwindset;rtt_walk_lock_unlock.0:${MAX_RTT_UNWIND}"
66 "--unwindset;RttWalk.0:${MAX_RTT_UNWIND}"
67 "--unwindset;init_walk_path.0:${MAX_RTT_UNWIND}"
68 "--unwindset;smc_rec_create.0:${MAX_AUX_REC}"
69 "--unwindset;free_rec_aux_granules.0:${MAX_AUX_REC}"
70 "--unwindset;find_lock_granules.3:${MAX_ROOT_RTT}"
71 "--unwindset;RealmIsLive.0:${MAX_ROOT_RTT}"
72 "--unwindset;init_rtt_root_page.0:${MAX_ROOT_RTT}"
73 "--unwindset;init_rec.0:${MAX_AUX_REC}"
74 "--unwindset;RealmIsLive.2:${MAX_ROOT_RTT}"
75 "--unwindset;init_realm_descriptor_page.0:${MAX_ROOT_RTT}"
76 "--unwindset;init_rec.0:${MAX_AUX_REC}"
77 "--unwindset;lock_order_invariable.0:21"
78 "--unwindset;lock_order_invariable.1:11"
79 "--unwindset;lock_order_invariable.2:"
80)
81
82set(cbmc_defines_list
83 "-DCBMC"
84 "-DDISABLE_COMPILER_ASSERT"
85 "-DDISABLE_SET_MEMBER"
86 "-DGRANULE_SHIFT=${GRANULE_SHIFT}"
87 "-DXLAT_GRANULARITY_SIZE_SHIFT=${GRANULE_SHIFT}"
88 "-DRMM_MAX_GRANULES=${MAX_NUM_OF_GRANULE}"
89 "-DMAX_CPUS=1"
90 "-DMAX_RTT_LEVEL=${MAX_RTT_UNWIND}"
91 "-DHOST_MEM_SIZE=${HOST_MEM_SIZE}"
92 "-DNAME=\"RMM\""
93 "-DVERSION=\"CBMC\""
94 "-DCOMMIT_INFO=\"CBMC\""
95)
96
97# CBMC flags for memory safety analysis and undefined behaviour analysis.
98set(cbmc_analysis_flags_list
99 "--bounds-check"
100 "--pointer-check"
101 "--div-by-zero-check"
102 "--signed-overflow-check"
103 "--unsigned-overflow-check"
104 "--pointer-overflow-check"
105 "--conversion-check"
106 "--undefined-shift-check"
107 "--float-overflow-check"
108 "--nan-check"
109 "--enum-range-check"
110 "--pointer-primitive-check"
111 "--memory-leak-check")
112
113set(cbmc_flags_list
114 "--c11"
115 "--timestamp;wall"
116 "--verbosity;9"
117 # Optimisation flags:
118 "--drop-unused-functions"
119 "--reachability-slice"
120 )
121
122if("${RMM_CBMC_CONFIGURATION}" STREQUAL "COVERAGE")
123 list(APPEND cbmc_flags_list
124 "--cover;cover"
125 "--no-assertions")
126elseif("${RMM_CBMC_CONFIGURATION}" STREQUAL "ASSERT")
127 list(APPEND cbmc_flags_list
128 "--unwinding-assertions"
129 "--trace"
130 "--trace-show-function-calls")
131elseif("${RMM_CBMC_CONFIGURATION}" STREQUAL "ANALYSIS")
132 list(APPEND cbmc_flags_list
133 "--unwinding-assertions"
134 "${cbmc_analysis_flags_list}")
135else()
136 message(FATAL_ERROR "Invalid RMM_CBMC_CONFIGURATION '${RMM_CBMC_CONFIGURATION}'")
137endif()
138
139file(GLOB_RECURSE TESTBENCH_FILES "${TESTBENCH_DIR}/*.c")
140
141#
142# Create semi-colon separated list from white-space seperated ones.
143#
144separate_arguments(RMM_IMP_SRCS)
145separate_arguments(RMM_IMP_INCS)
146
147#
148# Execute CBMC on the testbench files
149#
150rmm_cbmc_write_summary_header(${RMM_CBMC_SUMMARY_FIELD_WIDTH}
151 ${RMM_TESTBENCH_RESULT_DIR} ${SUMMARY_FILE} ${CBMC_SUMMARY_HEADER})
152
153foreach(testbench_file ${TESTBENCH_FILES})
154
155 string(REPLACE ${TESTBENCH_DIR}/ "" testbench_filename ${testbench_file})
156 string(REGEX REPLACE "\\.[^\\.]*$" "" entry_point "${testbench_filename}")
157
158 set(cmd
159 ${RMM_CBMC_PATH}
160 ${cbmc_flags_list}
161 "--function;${entry_point}"
162 ${RMM_IMP_INCS}
163 ${cbmc_unwinds_list}
164 ${cbmc_defines_list}
165 ${RMM_IMP_SRCS}
166 ${testbench_file})
167
168 # Set the names of output files
169 string(REPLACE ${TESTBENCH_DIR} ${RMM_TESTBENCH_RESULT_DIR} output_file ${testbench_file})
170 set(error_file ${output_file})
171 set(cmd_file ${output_file})
172 string(APPEND output_file ".${CBMC_RESULT_FILE_SUFFIX}" ".output")
173 string(APPEND error_file ".${CBMC_RESULT_FILE_SUFFIX}" ".error")
174 string(APPEND cmd_file ".${CBMC_RESULT_FILE_SUFFIX}" ".cmd")
175
176 # remove the absolute path making it relative
177 string (REPLACE "${SOURCE_DIR}/" "" cmd "${cmd}")
178 # replace the ; with space
179 string (REPLACE ";" " " CMD_STR "${cmd}")
180 # add double quotes
181 string (REPLACE "\"" "\\\"" CMD_STR "${CMD_STR}")
182 # escape parentheses
183 string (REPLACE "(" "\"(" CMD_STR "${CMD_STR}")
184 string (REPLACE ")" ")\"" CMD_STR "${CMD_STR}")
185 file(WRITE ${cmd_file} "${CMD_STR}")
186
187 execute_process(COMMAND ${CMAKE_COMMAND} -E echo_append "CBMC: ${testbench_file}... ")
188 execute_process(
189 COMMAND ${cmd}
190 RESULT_VARIABLE res_var
191 OUTPUT_FILE ${output_file}
192 ERROR_FILE ${error_file}
193 )
194
195 execute_process(COMMAND ${CMAKE_COMMAND} -E echo "DONE")
196
197 rmm_cbmc_append_summary("${testbench_filename}" "${output_file}"
198 ${RMM_CBMC_SUMMARY_FIELD_WIDTH} ${RMM_TESTBENCH_RESULT_DIR} ${SUMMARY_FILE}
199 ${CBMC_SUMMARY_PATTERN})
200
201endforeach()
202message(STATUS "Result in ${RMM_TESTBENCH_RESULT_DIR}")
Mate Toth-Pal7b875ea2023-11-15 16:59:19 +0100203
204execute_process(
205 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
206 COMMAND ${CHECK_CBMC_SUMMARY_EXECUTABLE}
207 ${CMAKE_SOURCE_DIR}/tools/cbmc/testbenches_results/BASELINE.${CBMC_RESULT_FILE_SUFFIX}
208 ${RMM_TESTBENCH_RESULT_DIR}/${SUMMARY_FILE}
209 OUTPUT_VARIABLE CHECK_SUMMARY_OUTPUT
210 ERROR_VARIABLE CHECK_SUMMARY_ERROR
211 RESULT_VARIABLE CHECK_SUMMARY_RC
212 OUTPUT_STRIP_TRAILING_WHITESPACE
213 )
214
215if (NOT ${CHECK_SUMMARY_RC} EQUAL "0")
216 message(WARNING
217 "cbmc-${CBMC_RESULT_FILE_SUFFIX}: FAILED\n${CHECK_SUMMARY_ERROR}")
218else()
219 message(STATUS "cbmc-${CBMC_RESULT_FILE_SUFFIX}: PASSED")
220endif()