@@ -79,9 +79,11 @@ def add_selected_default_cbmc_flags(args):
79
79
if not args .no_unwinding_checks :
80
80
add_set_cbmc_flags (args , UNWINDING_CHECKS )
81
81
82
+ # Updates environment to use gotoc backend debugging
82
83
def add_rmc_rustc_debug_to_env (env ):
83
84
env ["RUSTC_LOG" ] = env .get ("RUSTC_LOG" , "rustc_codegen_llvm::gotoc" )
84
85
86
+ # Prints info about the RMC process
85
87
def print_rmc_step_status (step_name , completed_process , verbose = False ):
86
88
status = "PASS"
87
89
if completed_process .returncode != EXIT_CODE_SUCCESS :
@@ -90,6 +92,7 @@ def print_rmc_step_status(step_name, completed_process, verbose=False):
90
92
print (f"[RMC] stage: { step_name } ({ status } )" )
91
93
print (f"[RMC] cmd: { ' ' .join (completed_process .args )} " )
92
94
95
+ # Handler for running arbitrary command-line commands
93
96
def run_cmd (cmd , label = None , cwd = None , env = None , output_to = None , quiet = False , verbose = False , debug = False , scanners = [], dry_run = False ):
94
97
# If this a dry run, we emulate running a successful process whose output is the command itself
95
98
# We set `output_to` to `stdout` so that the output is not omitted below
@@ -123,6 +126,7 @@ def run_cmd(cmd, label=None, cwd=None, env=None, output_to=None, quiet=False, ve
123
126
124
127
return process .returncode
125
128
129
+ # Generates a symbol table from a rust file
126
130
def compile_single_rust_file (input_filename , output_filename , verbose = False , debug = False , keep_temps = False , mangler = "v0" , dry_run = False ):
127
131
if not keep_temps :
128
132
atexit .register (delete_file , output_filename )
@@ -134,7 +138,7 @@ def compile_single_rust_file(input_filename, output_filename, verbose=False, deb
134
138
135
139
return run_cmd (build_cmd , env = build_env , label = "compile" , verbose = verbose , debug = debug , dry_run = dry_run )
136
140
137
-
141
+ # Generates a symbol table (and some other artifacts) from a rust crate
138
142
def cargo_build (crate , target_dir = "target" , verbose = False , debug = False , mangler = "v0" , dry_run = False ):
139
143
rustflags = ["-Z" , "codegen-backend=gotoc" , "-Z" , f"symbol-mangling-version={ mangler } " , f"--cfg={ RMC_CFG } " ]
140
144
rustflags = " " .join (rustflags )
@@ -150,17 +154,25 @@ def cargo_build(crate, target_dir="target", verbose=False, debug=False, mangler=
150
154
add_rmc_rustc_debug_to_env (build_env )
151
155
return run_cmd (build_cmd , env = build_env , cwd = crate , label = "build" , verbose = verbose , debug = debug , dry_run = dry_run )
152
156
157
+ # Adds information about unwinding to the RMC output
153
158
def append_unwind_tip (text ):
154
159
unwind_tip = ("[RMC] info: Verification output shows one or more unwinding failures.\n "
155
160
"[RMC] tip: Consider increasing the unwinding value or disabling `--unwinding-assertions`.\n " )
156
161
return text + unwind_tip
157
162
163
+ # Generates a goto program from a symbol table
158
164
def symbol_table_to_gotoc (json_filename , cbmc_filename , verbose = False , keep_temps = False , dry_run = False ):
159
165
if not keep_temps :
160
166
atexit .register (delete_file , cbmc_filename )
161
167
cmd = ["symtab2gb" , json_filename , "--out" , cbmc_filename ]
162
168
return run_cmd (cmd , label = "to-gotoc" , verbose = verbose , dry_run = dry_run )
163
169
170
+ # Links in external C programs into a goto program
171
+ def link_c_lib (src , dst , c_lib , verbose = False , quiet = False , function = "main" , dry_run = False ):
172
+ cmd = ["goto-cc" ] + ["--function" , function ] + [src ] + c_lib + ["-o" , dst ]
173
+ return run_cmd (cmd , label = "goto-cc" , verbose = verbose , quiet = quiet , dry_run = dry_run )
174
+
175
+ # Runs CBMC on a goto program
164
176
def run_cbmc (cbmc_filename , cbmc_args , verbose = False , quiet = False , dry_run = False ):
165
177
cbmc_cmd = ["cbmc" ] + cbmc_args + [cbmc_filename ]
166
178
scanners = []
@@ -171,25 +183,22 @@ def run_cbmc(cbmc_filename, cbmc_args, verbose=False, quiet=False, dry_run=False
171
183
scanners .append (unwind_asserts_scanner )
172
184
return run_cmd (cbmc_cmd , label = "cbmc" , output_to = "stdout" , verbose = verbose , quiet = quiet , scanners = scanners , dry_run = dry_run )
173
185
186
+ # Generates a viewer report from a goto program
174
187
def run_visualize (cbmc_filename , prop_args , cover_args , verbose = False , quiet = False , keep_temps = False , function = "main" , srcdir = "." , wkdir = "." , outdir = "." , dry_run = False ):
175
188
results_filename = os .path .join (outdir , "results.xml" )
176
189
coverage_filename = os .path .join (outdir , "coverage.xml" )
177
190
property_filename = os .path .join (outdir , "property.xml" )
178
- temp_goto_filename = os .path .join (outdir , "temp.goto" )
179
191
if not keep_temps :
180
- for filename in [results_filename , coverage_filename , property_filename , temp_goto_filename ]:
192
+ for filename in [results_filename , coverage_filename , property_filename ]:
181
193
atexit .register (delete_file , filename )
182
194
183
- # 1) goto-cc --function main <cbmc_filename> -o temp.goto
184
- # 2) cbmc --xml-ui --trace ~/rmc/library/rmc/rmc_lib.c temp.goto > results.xml
185
- # 3) cbmc --xml-ui --cover location ~/rmc/library/rmc/rmc_lib.c temp.goto > coverage.xml
186
- # 4) cbmc --xml-ui --show-properties ~/rmc/library/rmc/rmc_lib.c temp.goto > property.xml
187
- # 5) cbmc-viewer --result results.xml --coverage coverage.xml --property property.xml --srcdir . --goto temp.goto --reportdir report
188
-
189
- run_goto_cc (cbmc_filename , temp_goto_filename , verbose , quiet , function = function , dry_run = dry_run )
195
+ # 1) cbmc --xml-ui --trace ~/rmc/library/rmc/rmc_lib.c <cbmc_filename> > results.xml
196
+ # 2) cbmc --xml-ui --cover location ~/rmc/library/rmc/rmc_lib.c <cbmc_filename> > coverage.xml
197
+ # 3) cbmc --xml-ui --show-properties ~/rmc/library/rmc/rmc_lib.c <cbmc_filename> > property.xml
198
+ # 4) cbmc-viewer --result results.xml --coverage coverage.xml --property property.xml --srcdir . --goto <cbmc_filename> --reportdir report
190
199
191
200
def run_cbmc_local (cbmc_args , output_to , dry_run = False ):
192
- cbmc_cmd = ["cbmc" ] + cbmc_args + [temp_goto_filename ]
201
+ cbmc_cmd = ["cbmc" ] + cbmc_args + [cbmc_filename ]
193
202
return run_cmd (cbmc_cmd , label = "cbmc" , output_to = output_to , verbose = verbose , quiet = quiet , dry_run = dry_run )
194
203
195
204
cbmc_prop_args = prop_args + ["--xml-ui" ]
@@ -199,15 +208,12 @@ def run_cbmc_local(cbmc_args, output_to, dry_run=False):
199
208
run_cbmc_local (cbmc_cover_args + ["--cover" , "location" ], coverage_filename , dry_run = dry_run )
200
209
run_cbmc_local (cbmc_prop_args + ["--show-properties" ], property_filename , dry_run = dry_run )
201
210
202
- run_cbmc_viewer (temp_goto_filename , results_filename , coverage_filename ,
211
+ run_cbmc_viewer (cbmc_filename , results_filename , coverage_filename ,
203
212
property_filename , verbose , quiet , srcdir , wkdir , os .path .join (outdir , "report" ), dry_run = dry_run )
204
213
205
214
return retcode
206
215
207
- def run_goto_cc (src , dst , verbose = False , quiet = False , function = "main" , dry_run = False ):
208
- cmd = ["goto-cc" ] + ["--function" , function ] + [src ] + ["-o" , dst ]
209
- return run_cmd (cmd , label = "goto-cc" , verbose = verbose , quiet = quiet , dry_run = dry_run )
210
-
216
+ # Handler for calling cbmc-viewer
211
217
def run_cbmc_viewer (goto_filename , results_filename , coverage_filename , property_filename , verbose = False , quiet = False , srcdir = "." , wkdir = "." , reportdir = "report" , dry_run = False ):
212
218
cmd = ["cbmc-viewer" ] + \
213
219
["--result" , results_filename ] + \
@@ -219,15 +225,15 @@ def run_cbmc_viewer(goto_filename, results_filename, coverage_filename, property
219
225
["--reportdir" , reportdir ]
220
226
return run_cmd (cmd , label = "cbmc-viewer" , verbose = verbose , quiet = quiet , dry_run = dry_run )
221
227
222
-
228
+ # Handler for calling goto-instrument
223
229
def run_goto_instrument (input_filename , output_filename , args , verbose = False , dry_run = False ):
224
230
cmd = ["goto-instrument" ] + args + [input_filename ]
225
231
return run_cmd (cmd , label = "goto-instrument" , verbose = verbose , output_to = output_filename , dry_run = dry_run )
226
232
227
-
233
+ # Generates a C program from a goto program
228
234
def goto_to_c (goto_filename , c_filename , verbose = False , dry_run = False ):
229
235
return run_goto_instrument (goto_filename , c_filename , ["--dump-c" ], verbose , dry_run = dry_run )
230
236
231
-
237
+ # Generates the CMBC symbol table from a goto program
232
238
def goto_to_symbols (goto_filename , symbols_filename , verbose = False , dry_run = False ):
233
239
return run_goto_instrument (goto_filename , symbols_filename , ["--show-symbol-table" ], verbose , dry_run = dry_run )
0 commit comments