forked from solana-labs/rbpf
-
Notifications
You must be signed in to change notification settings - Fork 64
Expand file tree
/
Copy pathsmart_jit_diff.rs
More file actions
116 lines (107 loc) · 3.41 KB
/
Copy pathsmart_jit_diff.rs
File metadata and controls
116 lines (107 loc) · 3.41 KB
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
#![no_main]
use libfuzzer_sys::fuzz_target;
use grammar_aware::*;
use solana_sbpf::{
ebpf,
elf::Executable,
insn_builder::{Arch, Instruction, IntoBytes},
memory_region::MemoryRegion,
program::{BuiltinFunction, BuiltinProgram, FunctionRegistry, SBPFVersion},
verifier::{RequisiteVerifier, Verifier},
};
use test_utils::{create_vm, TestContextObject};
use crate::common::ConfigTemplate;
mod common;
mod grammar_aware;
#[derive(arbitrary::Arbitrary, Debug)]
struct FuzzData {
template: ConfigTemplate,
exit_dst: u8,
exit_src: u8,
exit_off: i16,
exit_imm: i64,
prog: FuzzProgram,
mem: Vec<u8>,
}
fuzz_target!(|data: FuzzData| {
let mut prog = make_program(&data.prog, Arch::X64);
prog.exit()
.set_dst(data.exit_dst)
.set_src(data.exit_src)
.set_off(data.exit_off)
.set_imm(data.exit_imm)
.push();
let config = data.template.into();
let function_registry = FunctionRegistry::default();
let syscall_registry = FunctionRegistry::<BuiltinFunction<TestContextObject>>::default();
if RequisiteVerifier::verify(
prog.into_bytes(),
&config,
SBPFVersion::V3,
&function_registry,
&syscall_registry,
)
.is_err()
{
// verify please
return;
}
#[allow(unused_mut)]
let mut executable = Executable::<TestContextObject>::from_text_bytes(
prog.into_bytes(),
std::sync::Arc::new(BuiltinProgram::new_loader(
config,
)),
SBPFVersion::V3,
function_registry,
)
.unwrap();
let mut interp_mem = data.mem.clone();
let mut interp_context_object = TestContextObject::new(1 << 16);
let interp_mem_region = MemoryRegion::new_writable(&mut interp_mem, ebpf::MM_TX_AREA);
create_vm!(
interp_vm,
&executable,
&mut interp_context_object,
interp_stack,
interp_heap,
vec![interp_mem_region],
None
);
#[allow(unused)]
let (_interp_ins_count, interp_res) = interp_vm.execute_program(&executable, true);
#[cfg(all(not(target_os = "windows"), target_arch = "x86_64"))]
if executable.jit_compile().is_ok() {
let mut jit_mem = data.mem;
let mut jit_context_object = TestContextObject::new(1 << 16);
let jit_mem_region = MemoryRegion::new_writable(&mut jit_mem, ebpf::MM_TX_AREA);
create_vm!(
jit_vm,
&executable,
&mut jit_context_object,
jit_stack,
jit_heap,
vec![jit_mem_region],
None
);
let (_jit_ins_count, jit_res) = jit_vm.execute_program(&executable, false);
if format!("{:?}", interp_res) != format!("{:?}", jit_res) {
panic!("Expected {:?}, but got {:?}", interp_res, jit_res);
}
if interp_res.is_ok() {
// we know jit res must be ok if interp res is by this point
if interp_context_object.remaining != jit_context_object.remaining {
panic!(
"Expected {} insts remaining, but got {}",
interp_context_object.remaining, jit_context_object.remaining
);
}
if interp_mem != jit_mem {
panic!(
"Expected different memory. From interpreter: {:?}\nFrom JIT: {:?}",
interp_mem, jit_mem
);
}
}
}
});