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