Skip to content

Commit

Permalink
disable mut pointer accesses, various test fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Strophox committed Aug 30, 2024
1 parent 6e23a4d commit d14235c
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 40 deletions.
13 changes: 9 additions & 4 deletions src/tools/miri/src/shims/native_lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,15 @@ fn imm_to_carg<'tcx>(v: ImmTy<'tcx>, cx: &impl HasDataLayout) -> InterpResult<'t
ty::Uint(UintTy::U64) => CArg::UInt64(v.to_scalar().to_u64()?),
ty::Uint(UintTy::Usize) =>
CArg::USize(v.to_scalar().to_target_usize(cx)?.try_into().unwrap()),
ty::RawPtr(..) => {
let s = v.to_scalar().to_pointer(cx)?.addr();
// This relies on the `expose_provenance` in `addr_from_alloc_id`.
CArg::RawPtr(std::ptr::with_exposed_provenance_mut(s.bytes_usize()))
ty::RawPtr(_, mutability) => {
// Arbitrary mutable pointer accesses are not currently supported in Miri.
if mutability.is_mut() {
throw_unsup_format!("unsupported mutable pointer type for native call: {}", v.layout.ty);
} else {
let s = v.to_scalar().to_pointer(cx)?.addr();
// This relies on the `expose_provenance` in `addr_from_alloc_id`.
CArg::RawPtr(std::ptr::with_exposed_provenance_mut(s.bytes_usize()))
}
},
_ => throw_unsup_format!("unsupported argument type for native call: {}", v.layout.ty),
})
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/tests/native-lib/native-lib.map
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ CODEABI_1.0 {

# The rest remains private.
local: *;
};
};
35 changes: 14 additions & 21 deletions src/tools/miri/tests/native-lib/pass/ptr_read_access.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,15 @@ fn main() {
test_static();
}

// Test function that dereferences a pointer and prints its contents from C.
// Test void function that dereferences a pointer and prints its contents from C.
fn test_pointer() {
extern "C" {
fn print_pointer(ptr: *mut i32);
fn print_pointer(ptr: *const i32);
}

let mut x = 42;
let ptr = &mut x as *mut i32;
let x = 42;

unsafe { print_pointer(ptr) };
unsafe { print_pointer(&x) };
}

// Test function that dereferences a simple struct pointer and accesses a field.
Expand All @@ -31,14 +30,12 @@ fn test_simple() {
}

extern "C" {
fn access_simple(s_ptr: *mut Simple) -> i32;
fn access_simple(s_ptr: *const Simple) -> i32;
}

let mut simple = Simple { field: -42 };
let s_ptr = &mut simple as *mut Simple;
let simple = Simple { field: -42 };

let result = unsafe { access_simple(s_ptr) };
assert_eq!(result, -42);
assert_eq!(unsafe { access_simple(&simple) }, -42);
}

// Test function that dereferences nested struct pointers and accesses fields.
Expand All @@ -53,17 +50,14 @@ fn test_nested() {
}

extern "C" {
fn access_nested(n_ptr: *mut Nested) -> i32;
fn access_nested(n_ptr: *const Nested) -> i32;
}

let mut nested_0 = Nested { value: 0, next: None };
let mut nested_1 = Nested { value: 1, next: NonNull::new(&mut nested_0) };
let mut nested_2 = Nested { value: 2, next: NonNull::new(&mut nested_1) };
let mut nested_3 = Nested { value: 3, next: NonNull::new(&mut nested_2) };
let n_ptr = &mut nested_3 as *mut Nested;
let mut nested_0 = Nested { value: 97, next: None };
let mut nested_1 = Nested { value: 98, next: NonNull::new(&mut nested_0) };
let nested_2 = Nested { value: 99, next: NonNull::new(&mut nested_1) };

let result = unsafe { access_nested(n_ptr) };
assert_eq!(result, 0);
assert_eq!(unsafe { access_nested(&nested_2) }, 97);
}

// Test function that dereferences static struct pointers and accesses fields.
Expand All @@ -84,6 +78,5 @@ fn test_static() {
recurse: &STATIC,
};

let result = unsafe { access_static(&STATIC) };
assert_eq!(result, 9001);
}
assert_eq!(unsafe { access_static(&STATIC) }, 9001);
}
2 changes: 1 addition & 1 deletion src/tools/miri/tests/native-lib/pass/scalar_arguments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,4 @@ fn main() {
// test void function that prints from C
printer();
}
}
}
20 changes: 10 additions & 10 deletions src/tools/miri/tests/native-lib/ptr_read_access.c
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
#include <stdio.h>

/* Test. */
/* Test: `test_pointer` */

void print_pointer(int *ptr) {
void print_pointer(const int *ptr) {
printf("printing pointer dereference from C: %d\n", *ptr);
}

/* Test. */
/* Test: `test_simple` */

typedef struct Simple {
int field;
} Simple;

int access_simple(Simple *s_ptr) {
int access_simple(const Simple *s_ptr) {
return s_ptr->field;
}

/* Test. */
/* Test: `test_nested` */

typedef struct Nested {
int value;
struct Nested *next;
} Nested;

// Returns the innermost/last `value` of the `Nested` pointer chain.
int access_nested(Nested *n_ptr) {
// Edge case: `n_ptr == NULL`, first Nested is None).
// Returns the innermost/last `value` of a `Nested` pointer chain.
int access_nested(const Nested *n_ptr) {
// Edge case: `n_ptr == NULL`, first `Nested` is None).
if (!n_ptr) { return 0; }

while (n_ptr->next) {
Expand All @@ -35,13 +35,13 @@ int access_nested(Nested *n_ptr) {
return n_ptr->value;
}

/* Test. */
/* Test: `test_static */

typedef struct Static {
int value;
struct Static *recurse;
} Static;

int access_static(Static *s_ptr) {
int access_static(const Static *s_ptr) {
return s_ptr->recurse->recurse->value;
}
2 changes: 1 addition & 1 deletion src/tools/miri/tests/native-lib/scalar_arguments.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ short add_int16(short x) {

long add_short_to_long(short x, long y) {
return x + y;
}
}
6 changes: 4 additions & 2 deletions src/tools/miri/tests/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,25 @@ fn build_native_lib() -> PathBuf {
// Create the directory if it does not already exist.
std::fs::create_dir_all(&so_target_dir)
.expect("Failed to create directory for shared object file");
/*let so_file_path = so_target_dir.join("scalar_arguments.so");*/
let so_file_path = so_target_dir.join("native-lib.so");
let cc_output = Command::new(cc)
.args([
"-shared",
"-o",
so_file_path.to_str().unwrap(),
// FIXME: Automate gathering of all relevant C source files in the directory.
"tests/native-lib/scalar_arguments.c",
"tests/native-lib/ptr_read_access.c",
// Only add the functions specified in libcode.version to the shared object file.
// This is to avoid automatically adding `malloc`, etc.
// Source: https://anadoxin.org/blog/control-over-symbol-exports-in-gcc.html/
"-fPIC",
"-Wl,--version-script=tests/native-lib/native-lib.map",
"-Werror",
// Ensure we notice serious problems in the C code.
"-Wall",
"-Wextra",
"-Wpedantic",
"-Werror",
])
.output()
.expect("failed to generate shared object file for testing native function calls");
Expand Down

0 comments on commit d14235c

Please sign in to comment.