-
Notifications
You must be signed in to change notification settings - Fork 346
/
miri_extern.rs
150 lines (134 loc) · 7.82 KB
/
miri_extern.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#[repr(C)]
/// Layout of the return value of `miri_resolve_frame`,
/// with fields in the exact same order.
pub struct MiriFrame {
// The size of the name of the function being executed, encoded in UTF-8
pub name_len: usize,
// The size of filename of the function being executed, encoded in UTF-8
pub filename_len: usize,
// The line number currently being executed in `filename`, starting from '1'.
pub lineno: u32,
// The column number currently being executed in `filename`, starting from '1'.
pub colno: u32,
// The function pointer to the function currently being executed.
// This can be compared against function pointers obtained by
// casting a function (e.g. `my_fn as *mut ()`)
pub fn_ptr: *mut (),
}
#[cfg(miri)]
extern "Rust" {
/// Miri-provided extern function to mark the block `ptr` points to as a "root"
/// for some static memory. This memory and everything reachable by it is not
/// considered leaking even if it still exists when the program terminates.
///
/// `ptr` has to point to the beginning of an allocated block.
pub fn miri_static_root(ptr: *const u8);
// Miri-provided extern function to get the amount of frames in the current backtrace.
// The `flags` argument must be `0`.
pub fn miri_backtrace_size(flags: u64) -> usize;
/// Miri-provided extern function to obtain a backtrace of the current call stack.
/// This writes a slice of pointers into `buf` - each pointer is an opaque value
/// that is only useful when passed to `miri_resolve_frame`.
/// `buf` must have `miri_backtrace_size(0) * pointer_size` bytes of space.
/// The `flags` argument must be `1`.
pub fn miri_get_backtrace(flags: u64, buf: *mut *mut ());
/// Miri-provided extern function to resolve a frame pointer obtained
/// from `miri_get_backtrace`. The `flags` argument must be `1`.
///
/// This function can be called on any thread (not just the one which obtained `frame`).
pub fn miri_resolve_frame(frame: *mut (), flags: u64) -> MiriFrame;
/// Miri-provided extern function to get the name and filename of the frame provided by `miri_resolve_frame`.
/// `name_buf` and `filename_buf` should be allocated with the `name_len` and `filename_len` fields of `MiriFrame`.
/// The flags argument must be `0`.
pub fn miri_resolve_frame_names(
ptr: *mut (),
flags: u64,
name_buf: *mut u8,
filename_buf: *mut u8,
);
/// Miri-provided extern function to begin unwinding with the given payload.
///
/// This is internal and unstable and should not be used; we give it here
/// just to be complete.
pub fn miri_start_unwind(payload: *mut u8) -> !;
/// Miri-provided extern function to get the internal unique identifier for the allocation that a pointer
/// points to. If this pointer is invalid (not pointing to an allocation), interpretation will abort.
///
/// This is only useful as an input to `miri_print_borrow_stacks`, and it is a separate call because
/// getting a pointer to an allocation at runtime can change the borrow stacks in the allocation.
/// This function should be considered unstable. It exists only to support `miri_print_borrow_state` and so
/// inherits all of its instability.
pub fn miri_get_alloc_id(ptr: *const ()) -> u64;
/// Miri-provided extern function to print (from the interpreter, not the program) the contents of all
/// borrows in an allocation.
///
/// If Stacked Borrows is running, this prints all the stacks. The leftmost tag is the bottom of the stack.
///
/// If Tree borrows is running, this prints on the left the permissions of each tag on each range,
/// an on the right the tree structure of the tags. If some tags were named via `miri_pointer_name`,
/// their names appear here.
///
/// If additionally `show_unnamed` is `false` then tags that did *not* receive a name will be hidden.
/// Ensure that either the important tags have been named, or `show_unnamed = true`.
/// Note: as Stacked Borrows does not have tag names at all, `show_unnamed` is ignored and all tags are shown.
/// In general, unless you strongly want some tags to be hidden (as is the case in `tree-borrows` tests),
/// `show_unnamed = true` should be the default.
///
/// The format of what this emits is unstable and may change at any time. In particular, users should be
/// aware that Miri will periodically attempt to garbage collect the contents of all stacks. Callers of
/// this function may wish to pass `-Zmiri-provenance-gc=0` to disable the GC.
///
/// This function is extremely unstable. At any time the format of its output may change, its signature may
/// change, or it may be removed entirely.
pub fn miri_print_borrow_state(alloc_id: u64, show_unnamed: bool);
/// Miri-provided extern function to associate a name to the nth parent of a tag.
/// Typically the name given would be the name of the program variable that holds the pointer.
/// Unreachable tags can still be named by using nonzero `nth_parent` and a child tag.
///
/// This function does nothing under Stacked Borrows, since Stacked Borrows's implementation
/// of `miri_print_borrow_state` does not show the names.
///
/// Under Tree Borrows, the names also appear in error messages.
pub fn miri_pointer_name(ptr: *const (), nth_parent: u8, name: &[u8]);
/// Miri-provided extern function to print (from the interpreter, not the
/// program) the contents of a section of program memory, as bytes. Bytes
/// written using this function will emerge from the interpreter's stdout.
pub fn miri_write_to_stdout(bytes: &[u8]);
/// Miri-provided extern function to print (from the interpreter, not the
/// program) the contents of a section of program memory, as bytes. Bytes
/// written using this function will emerge from the interpreter's stderr.
pub fn miri_write_to_stderr(bytes: &[u8]);
/// Miri-provided extern function to allocate memory from the interpreter.
///
/// This is useful when no fundamental way of allocating memory is
/// available, e.g. when using `no_std` + `alloc`.
pub fn miri_alloc(size: usize, align: usize) -> *mut u8;
/// Miri-provided extern function to deallocate memory.
pub fn miri_dealloc(ptr: *mut u8, size: usize, align: usize);
/// Convert a path from the host Miri runs on to the target Miri interprets.
/// Performs conversion of path separators as needed.
///
/// Usually Miri performs this kind of conversion automatically. However, manual conversion
/// might be necessary when reading an environment variable that was set on the host
/// (such as TMPDIR) and using it as a target path.
///
/// Only works with isolation disabled.
///
/// `in` must point to a null-terminated string, and will be read as the input host path.
/// `out` must point to at least `out_size` many bytes, and the result will be stored there
/// with a null terminator.
/// Returns 0 if the `out` buffer was large enough, and the required size otherwise.
pub fn miri_host_to_target_path(
path: *const core::ffi::c_char,
out: *mut core::ffi::c_char,
out_size: usize,
) -> usize;
/// Run the provenance GC. The GC will run automatically at some cadence,
/// but in tests we want to for sure run it at certain points to check
/// that it doesn't break anything.
pub fn miri_run_provenance_gc();
/// Miri-provided extern function to promise that a given pointer is properly aligned for
/// "symbolic" alignment checks. Will fail if the pointer is not actually aligned or `align` is
/// not a power of two. Has no effect when alignment checks are concrete (which is the default).
pub fn miri_promise_symbolic_alignment(ptr: *const (), align: usize);
}