Skip to content

Commit fed674c

Browse files
adpaco-awstedinski
authored andcommitted
Assume an x86_64 architecture for the machine model (rust-lang#1054)
* Assume an x86_64 architecture for the machine model * Add checks for arch spec/options * Check platform instead of architecture * Add debug statement * print platform * Use `starts_with` for apple platforms * minor comment change * Make code simpler
1 parent 4f7b5d4 commit fed674c

File tree

2 files changed

+63
-8
lines changed

2 files changed

+63
-8
lines changed

src/kani-compiler/src/codegen_cprover_gotoc/compiler_interface.rs

+41
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use rustc_middle::ty::{self, TyCtxt};
2121
use rustc_session::config::{OutputFilenames, OutputType};
2222
use rustc_session::cstore::MetadataLoaderDyn;
2323
use rustc_session::Session;
24+
use rustc_target::abi::Endian;
2425
use rustc_target::spec::PanicStrategy;
2526
use std::collections::BTreeMap;
2627
use std::io::BufWriter;
@@ -57,6 +58,7 @@ impl CodegenBackend for GotocCodegenBackend {
5758
) -> Box<dyn Any> {
5859
super::utils::init();
5960

61+
check_target(&tcx.sess);
6062
check_options(&tcx.sess, need_metadata_module);
6163

6264
let codegen_units: &'tcx [CodegenUnit<'_>] = tcx.collect_and_partition_mono_items(()).1;
@@ -184,7 +186,46 @@ impl CodegenBackend for GotocCodegenBackend {
184186
}
185187
}
186188

189+
fn check_target(session: &Session) {
190+
// The requirement below is needed to build a valid CBMC machine model
191+
// in function `machine_model_from_session` from
192+
// src/kani-compiler/src/codegen_cprover_gotoc/context/goto_ctx.rs
193+
let is_linux_target = session.target.llvm_target == "x86_64-unknown-linux-gnu";
194+
// Comparison with `x86_64-apple-darwin` does not work well because the LLVM
195+
// target may become `x86_64-apple-macosx10.7.0` (or similar) and fail
196+
let is_darwin_target = session.target.llvm_target.starts_with("x86_64-apple-");
197+
198+
if !is_linux_target && !is_darwin_target {
199+
let err_msg = format!(
200+
"Kani requires the target platform to be `x86_64-unknown-linux-gnu` or `x86_64-apple-darwin`, but it is {}",
201+
&session.target.llvm_target
202+
);
203+
session.err(&err_msg);
204+
}
205+
206+
session.abort_if_errors();
207+
}
208+
187209
fn check_options(session: &Session, need_metadata_module: bool) {
210+
// The requirements for `min_global_align` and `endian` are needed to build
211+
// a valid CBMC machine model in function `machine_model_from_session` from
212+
// src/kani-compiler/src/codegen_cprover_gotoc/context/goto_ctx.rs
213+
match session.target.options.min_global_align {
214+
Some(1) => (),
215+
Some(align) => {
216+
let err_msg = format!(
217+
"Kani requires the target architecture option `min_global_align` to be 1, but it is {}.",
218+
align
219+
);
220+
session.err(&err_msg);
221+
}
222+
_ => (),
223+
}
224+
225+
if session.target.options.endian != Endian::Little {
226+
session.err("Kani requires the target architecture option `endian` to be `little`.");
227+
}
228+
188229
if !session.overflow_checks() {
189230
session.err("Kani requires overflow checks in order to provide a sound analysis.");
190231
}

src/kani-compiler/src/codegen_cprover_gotoc/context/goto_ctx.rs

+22-8
Original file line numberDiff line numberDiff line change
@@ -345,27 +345,41 @@ impl MetadataLoader for GotocMetadataLoader {
345345
}
346346
}
347347

348+
/// Builds a machine model which is required by CBMC
348349
fn machine_model_from_session(sess: &Session) -> MachineModel {
349-
// TODO: Hardcoded values from from the ones currently used in env.rs
350-
// We may wish to get more of them from the session.
351-
let alignment = sess.target.options.min_global_align.unwrap_or(1);
350+
// The model assumes a `x86_64-unknown-linux-gnu` or `x86_64-apple-darwin`
351+
// platform. We check the target platform in function `check_target` from
352+
// src/kani-compiler/src/codegen_cprover_gotoc/compiler_interface.rs and
353+
// error if it is not any of the ones we expect.
352354
let architecture = &sess.target.arch;
355+
let pointer_width = sess.target.pointer_width.into();
356+
357+
// The model assumes the following values for session options:
358+
// * `min_global_align`: 1
359+
// * `endian`: `Endian::Little`
360+
//
361+
// We check these options in function `check_options` from
362+
// src/kani-compiler/src/codegen_cprover_gotoc/compiler_interface.rs
363+
// and error if their values are not the ones we expect.
364+
let alignment = sess.target.options.min_global_align.unwrap_or(1);
365+
let is_big_endian = match sess.target.options.endian {
366+
Endian::Little => false,
367+
Endian::Big => true,
368+
};
369+
370+
// The values below cannot be obtained from the session so they are
371+
// hardcoded using standard ones for the supported platforms
353372
let bool_width = 8;
354373
let char_is_unsigned = false;
355374
let char_width = 8;
356375
let double_width = 64;
357376
let float_width = 32;
358377
let int_width = 32;
359-
let is_big_endian = match sess.target.options.endian {
360-
Endian::Little => false,
361-
Endian::Big => true,
362-
};
363378
let long_double_width = 128;
364379
let long_int_width = 64;
365380
let long_long_int_width = 64;
366381
let memory_operand_size = 4;
367382
let null_is_zero = true;
368-
let pointer_width = sess.target.pointer_width.into();
369383
let short_int_width = 16;
370384
let single_width = 32;
371385
let wchar_t_is_unsigned = false;

0 commit comments

Comments
 (0)