Skip to content

Commit a24e6fa

Browse files
celinvaltedinski
authored andcommitted
Fix cargo rmc to support multiple dependencies (rust-lang#451) (rust-lang#557)
When building multiple dependencies, rmc compilation generates multiple *json files which need to be merged before running CBMC. This remove the assumption that only json file is generated and use all the generated json files to generated the gotoc.
1 parent 6734e39 commit a24e6fa

File tree

5 files changed

+51
-60
lines changed

5 files changed

+51
-60
lines changed

scripts/cargo-rmc

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,15 @@ def main():
2727

2828
pattern = os.path.join(args.target_dir, "debug", "deps", "*.symtab.json")
2929
symbol_table_jsons = glob.glob(pattern)
30-
rmc.ensure(len(symbol_table_jsons) == 1, f"Unexpected number of json outputs: {len(symbol_table_jsons)}")
30+
rmc.ensure(len(symbol_table_jsons) > 0, f"Unexpected number of json outputs: {len(symbol_table_jsons)}")
3131

3232
cbmc_runnable_filename = os.path.join(args.target_dir, "cbmc_runnable.out")
3333
c_runnable_filename = os.path.join(args.target_dir, "cbmc_runnable.c")
3434

35-
if EXIT_CODE_SUCCESS != rmc.symbol_table_to_gotoc(symbol_table_jsons[0], cbmc_runnable_filename, args.verbose, args.keep_temps, args.dry_run):
36-
return 1
35+
out_files = rmc.symbol_table_to_gotoc(symbol_table_jsons, args.verbose, args.keep_temps, args.dry_run)
3736

38-
if EXIT_CODE_SUCCESS != rmc.link_c_lib(cbmc_runnable_filename, cbmc_runnable_filename, args.c_lib, args.verbose, args.quiet, args.function, args.dry_run):
39-
return 1
37+
rmc.link_c_lib(out_files, cbmc_runnable_filename, args.c_lib, args.verbose, args.quiet, args.function,
38+
args.dry_run)
4039

4140
if EXIT_CODE_SUCCESS != rmc.goto_to_c(cbmc_runnable_filename, c_runnable_filename, args.verbose, args.dry_run):
4241
return 1
@@ -50,21 +49,19 @@ def main():
5049
symbol_table_jsons = glob.glob(pattern)
5150

5251
if not args.dry_run:
53-
rmc.ensure(len(symbol_table_jsons) == 1, f"Unexpected number of json outputs: {len(symbol_table_jsons)}")
52+
rmc.ensure(len(symbol_table_jsons) > 0, f"Unexpected number of json outputs: {len(symbol_table_jsons)}")
5453
else:
5554
# Add a dummy value so dry-run works.
5655
symbol_table_jsons = ["dry-run.symtab.json"]
5756

5857
cbmc_filename = os.path.join(args.target_dir, "cbmc.out")
5958
c_filename = os.path.join(args.target_dir, "cbmc.c")
6059
symbols_filename = os.path.join(args.target_dir, "cbmc.symbols")
61-
if EXIT_CODE_SUCCESS != rmc.symbol_table_to_gotoc(symbol_table_jsons[0], cbmc_filename, args.verbose, args.keep_temps, args.dry_run):
62-
return 1
60+
out_files = rmc.symbol_table_to_gotoc(symbol_table_jsons, args.verbose, args.keep_temps, args.dry_run)
6361

6462
args.c_lib.append(str(RMC_C_LIB))
6563

66-
if EXIT_CODE_SUCCESS != rmc.link_c_lib(cbmc_filename, cbmc_filename, args.c_lib, args.verbose, args.quiet, args.function, args.dry_run):
67-
return 1
64+
rmc.link_c_lib(out_files, cbmc_filename, args.c_lib, args.verbose, args.quiet, args.function, args.dry_run)
6865

6966
if args.gen_c:
7067
if EXIT_CODE_SUCCESS != rmc.goto_to_c(cbmc_filename, c_filename, args.verbose, args.dry_run):

scripts/rmc

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,10 @@ def main():
3030
if EXIT_CODE_SUCCESS != rmc.compile_single_rust_file(args.input, base, json_runnable_filename, args.verbose, args.debug, args.keep_temps, args.mangler, args.dry_run, ["gen-c"]):
3131
return 1
3232

33-
if EXIT_CODE_SUCCESS != rmc.symbol_table_to_gotoc(json_runnable_filename, goto_runnable_filename, args.verbose, args.keep_temps, args.dry_run):
34-
return 1
33+
out_files = rmc.symbol_table_to_gotoc([json_runnable_filename], args.verbose, args.keep_temps, args.dry_run)
3534

36-
if EXIT_CODE_SUCCESS != rmc.link_c_lib(goto_runnable_filename, goto_runnable_filename, args.c_lib, args.verbose, args.quiet, args.function, args.dry_run):
37-
return 1
35+
rmc.link_c_lib(out_files, goto_runnable_filename, args.c_lib, args.verbose, args.quiet, args.function,
36+
args.dry_run)
3837

3938
if EXIT_CODE_SUCCESS != rmc.goto_to_c(goto_runnable_filename, c_runnable_filename, args.verbose, args.dry_run):
4039
return 1
@@ -49,8 +48,7 @@ def main():
4948
if EXIT_CODE_SUCCESS != rmc.compile_single_rust_file(args.input, base, symbol_table_json_filename, args.verbose, args.debug, args.keep_temps, args.mangler, args.dry_run, args.use_abs, args.abs_type, []):
5049
return 1
5150

52-
if EXIT_CODE_SUCCESS != rmc.symbol_table_to_gotoc(symbol_table_json_filename, goto_filename, args.verbose, args.keep_temps, args.dry_run):
53-
return 1
51+
out_files = rmc.symbol_table_to_gotoc([symbol_table_json_filename], args.verbose, args.keep_temps, args.dry_run)
5452

5553
args.c_lib.append(str(RMC_C_LIB))
5654

@@ -63,8 +61,7 @@ def main():
6361
RMC_C_HASHSET = RMC_C_STUB / "hashset" / "hashset.c"
6462
args.c_lib.append(str(RMC_C_HASHSET))
6563

66-
if EXIT_CODE_SUCCESS != rmc.link_c_lib(goto_filename, goto_filename, args.c_lib, args.verbose, args.quiet, args.function, args.dry_run):
67-
return 1
64+
rmc.link_c_lib(out_files, goto_filename, args.c_lib, args.verbose, args.quiet, args.function, args.dry_run)
6865

6966
if args.gen_c:
7067
if EXIT_CODE_SUCCESS != rmc.goto_to_c(goto_filename, c_filename, args.verbose, args.dry_run):

scripts/rmc.py

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -137,20 +137,25 @@ def run_cmd(cmd, label=None, cwd=None, env=None, output_to=None, quiet=False, ve
137137

138138
return process.returncode
139139

140+
def rustc_flags(mangler, symbol_table_passes):
141+
flags = [
142+
"-Z", "codegen-backend=gotoc",
143+
"-Z", "trim-diagnostic-paths=no",
144+
"-Z", f"symbol-mangling-version={mangler}",
145+
"-Z", f"symbol_table_passes={' '.join(symbol_table_passes)}",
146+
"-Z", "human_readable_cgu_names",
147+
f"--cfg={RMC_CFG}"]
148+
if "RUSTFLAGS" in os.environ:
149+
flags += os.environ["RUSTFLAGS"].split(" ")
150+
return flags
151+
140152
# Generates a symbol table from a rust file
141153
def compile_single_rust_file(input_filename, base, output_filename, verbose=False, debug=False, keep_temps=False, mangler="v0", dry_run=False, use_abs=False, abs_type="std", symbol_table_passes=[]):
142154
if not keep_temps:
143155
atexit.register(delete_file, output_filename)
144156
atexit.register(delete_file, base + ".type_map.json")
145157

146-
build_cmd = [RMC_RUSTC_EXE,
147-
"-Z", "codegen-backend=gotoc",
148-
"-Z", "trim-diagnostic-paths=no",
149-
"-Z", f"symbol-mangling-version={mangler}",
150-
"-Z", f"symbol_table_passes={' '.join(symbol_table_passes)}",
151-
"--crate-type=lib",
152-
"-Z", "human_readable_cgu_names",
153-
f"--cfg={RMC_CFG}"]
158+
build_cmd = [RMC_RUSTC_EXE, "--crate-type=lib"] + rustc_flags(mangler, symbol_table_passes)
154159

155160
if use_abs:
156161
build_cmd += ["-Z", "force-unstable-if-unmarked=yes",
@@ -159,8 +164,6 @@ def compile_single_rust_file(input_filename, base, output_filename, verbose=Fals
159164

160165
build_cmd += ["-o", base + ".o", input_filename]
161166

162-
if "RUSTFLAGS" in os.environ:
163-
build_cmd += os.environ["RUSTFLAGS"].split(" ")
164167
build_env = os.environ
165168
if debug:
166169
add_rmc_rustc_debug_to_env(build_env)
@@ -171,19 +174,9 @@ def compile_single_rust_file(input_filename, base, output_filename, verbose=Fals
171174
def cargo_build(crate, target_dir, verbose=False, debug=False, mangler="v0", dry_run=False, symbol_table_passes=[]):
172175
ensure(os.path.isdir(crate), f"Invalid path to crate: {crate}")
173176

174-
rustflags = [
175-
"-Z", "codegen-backend=gotoc",
176-
"-Z", "trim-diagnostic-paths=no",
177-
"-Z", f"symbol-mangling-version={mangler}",
178-
"-Z", f"symbol_table_passes={' '.join(symbol_table_passes)}",
179-
"-Z", "human_readable_cgu_names",
180-
f"--cfg={RMC_CFG}"]
181-
rustflags = " ".join(rustflags)
182-
if "RUSTFLAGS" in os.environ:
183-
rustflags = os.environ["RUSTFLAGS"] + " " + rustflags
184-
177+
rustflags = rustc_flags(mangler, symbol_table_passes)
185178
build_cmd = ["cargo", "build", "--lib", "--target-dir", str(target_dir)]
186-
build_env = {"RUSTFLAGS": rustflags,
179+
build_env = {"RUSTFLAGS": " ".join(rustflags),
187180
"RUSTC": RMC_RUSTC_EXE,
188181
"PATH": os.environ["PATH"],
189182
}
@@ -198,16 +191,25 @@ def append_unwind_tip(text):
198191
return text + unwind_tip
199192

200193
# Generates a goto program from a symbol table
201-
def symbol_table_to_gotoc(json_filename, cbmc_filename, verbose=False, keep_temps=False, dry_run=False):
202-
if not keep_temps:
203-
atexit.register(delete_file, cbmc_filename)
204-
cmd = ["symtab2gb", json_filename, "--out", cbmc_filename]
205-
return run_cmd(cmd, label="to-gotoc", verbose=verbose, dry_run=dry_run)
194+
def symbol_table_to_gotoc(json_files, verbose=False, keep_temps=False, dry_run=False):
195+
out_files = []
196+
for json in json_files:
197+
out_file = json + ".out"
198+
out_files.append(out_file)
199+
if not keep_temps:
200+
atexit.register(delete_file, out_file)
201+
202+
cmd = ["symtab2gb", json, "--out", out_file]
203+
if run_cmd(cmd, label="to-gotoc", verbose=verbose, dry_run=dry_run) != EXIT_CODE_SUCCESS:
204+
raise Exception("Failed to run command: {}".format(" ".join(cmd)))
205+
206+
return out_files
206207

207208
# Links in external C programs into a goto program
208-
def link_c_lib(src, dst, c_lib, verbose=False, quiet=False, function="main", dry_run=False):
209-
cmd = ["goto-cc"] + ["--function", function] + [src] + c_lib + ["-o", dst]
210-
return run_cmd(cmd, label="goto-cc", verbose=verbose, quiet=quiet, dry_run=dry_run)
209+
def link_c_lib(srcs, dst, c_lib, verbose=False, quiet=False, function="main", dry_run=False):
210+
cmd = ["goto-cc"] + ["--function", function] + srcs + c_lib + ["-o", dst]
211+
if run_cmd(cmd, label="goto-cc", verbose=verbose, quiet=quiet, dry_run=dry_run) != EXIT_CODE_SUCCESS:
212+
raise Exception("Failed to run command: {}".format(" ".join(cmd)))
211213

212214
# Runs CBMC on a goto program
213215
def run_cbmc(cbmc_filename, cbmc_args, verbose=False, quiet=False, dry_run=False):

src/test/expected/dry-run/expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
rmc-rustc -Z codegen-backend=gotoc -Z trim-diagnostic-paths=no -Z symbol-mangling-version=v0 -Z symbol_table_passes= --crate-type=lib -Z human_readable_cgu_names --cfg=rmc
1+
rmc-rustc --crate-type=lib -Z codegen-backend=gotoc -Z trim-diagnostic-paths=no -Z symbol-mangling-version=v0 -Z symbol_table_passes= -Z human_readable_cgu_names --cfg=rmc
22
symtab2gb
33
goto-cc --function main
44
cbmc --bounds-check --pointer-check --pointer-primitive-check --conversion-check --div-by-zero-check --float-overflow-check --nan-check --pointer-overflow-check --signed-overflow-check --undefined-shift-check --unsigned-overflow-check --unwinding-assertions --function main

src/test/rmc-multicrate/type-mismatch/run-mismatch-test.sh

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,15 @@ echo
1313
cd $(dirname $0)
1414
rm -rf /tmp/type_mismatch_test_build
1515
cd mismatch
16-
# Disable warnings until https://github.com/model-checking/rmc/issues/573 is fixed
17-
RUSTC_LOG=error CARGO_TARGET_DIR=/tmp/type_mismatch_test_build RUST_BACKTRACE=1 RUSTFLAGS="-Z codegen-backend=gotoc --cfg=rmc" RUSTC=rmc-rustc cargo build
18-
19-
# Convert from JSON to Gotoc
20-
cd /tmp/type_mismatch_test_build/debug/deps/
21-
ls *.symtab.json | xargs symtab2gb
16+
RESULT="/tmp/dependency_test_result.txt"
2217

23-
# Add the entry point and remove unused functions
24-
goto-cc --function main *.out -o a.out
25-
goto-instrument --drop-unused-functions a.out b.out
18+
# Disable warnings until https://github.com/model-checking/rmc/issues/573 is fixed
19+
export RUSTC_LOG=error
20+
export CARGO_TARGET_DIR=/tmp/type_mismatch_test_build
21+
export RUST_BACKTRACE=1
22+
cargo rmc &> $RESULT
2623

2724
# Run the solver
28-
RESULT="/tmp/dependency_test_result.txt"
29-
cbmc b.out &> $RESULT
3025
if ! grep -q "VERIFICATION SUCCESSFUL" $RESULT; then
3126
cat $RESULT
3227
echo

0 commit comments

Comments
 (0)