From 8020fe26f5f666906f4010ff38aa4e57718bd9c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Mon, 21 Aug 2023 16:54:38 +0200 Subject: [PATCH] Removes the generic parameter "V: Verifier" from Executable. --- benches/elf_loader.rs | 9 ++---- benches/jit_compile.rs | 22 ++++++--------- benches/vm_execution.rs | 24 +++++++--------- cli/src/main.rs | 6 ++-- examples/disassemble.rs | 3 +- examples/to_json.rs | 3 +- fuzz/fuzz_targets/dumb.rs | 4 +-- fuzz/fuzz_targets/smart.rs | 4 +-- fuzz/fuzz_targets/smart_jit_diff.rs | 4 +-- fuzz/fuzz_targets/smarter_jit_diff.rs | 6 ++-- src/assembler.rs | 12 ++------ src/debugger.rs | 38 +++++++++++-------------- src/elf.rs | 27 +++++++----------- src/interpreter.rs | 9 +++--- src/jit.rs | 22 ++++++--------- src/static_analysis.rs | 7 ++--- src/vm.rs | 13 ++++----- src/x86.rs | 3 +- test_utils/src/lib.rs | 5 ++-- tests/execution.rs | 14 +++++----- tests/verifier.rs | 40 +++++++++++++-------------- 21 files changed, 115 insertions(+), 160 deletions(-) diff --git a/benches/elf_loader.rs b/benches/elf_loader.rs index deecd307e..0ff3c84f0 100644 --- a/benches/elf_loader.rs +++ b/benches/elf_loader.rs @@ -13,7 +13,6 @@ extern crate test_utils; use solana_rbpf::{ elf::{Executable, FunctionRegistry}, syscalls, - verifier::TautologyVerifier, vm::{BuiltinFunction, BuiltinProgram, Config, TestContextObject}, }; use std::{fs::File, io::Read, sync::Arc}; @@ -36,9 +35,7 @@ fn bench_load_sbpfv1(bencher: &mut Bencher) { let mut elf = Vec::new(); file.read_to_end(&mut elf).unwrap(); let loader = loader(); - bencher.iter(|| { - Executable::::from_elf(&elf, loader.clone()).unwrap() - }); + bencher.iter(|| Executable::::from_elf(&elf, loader.clone()).unwrap()); } #[bench] @@ -47,7 +44,5 @@ fn bench_load_sbpfv2(bencher: &mut Bencher) { let mut elf = Vec::new(); file.read_to_end(&mut elf).unwrap(); let loader = loader(); - bencher.iter(|| { - Executable::::from_elf(&elf, loader.clone()).unwrap() - }); + bencher.iter(|| Executable::::from_elf(&elf, loader.clone()).unwrap()); } diff --git a/benches/jit_compile.rs b/benches/jit_compile.rs index ccdb4be9f..08f8c89bb 100644 --- a/benches/jit_compile.rs +++ b/benches/jit_compile.rs @@ -11,7 +11,7 @@ extern crate test; use solana_rbpf::{ elf::Executable, - verifier::{RequisiteVerifier, TautologyVerifier}, + verifier::RequisiteVerifier, vm::{BuiltinProgram, TestContextObject}, }; use std::{fs::File, io::Read, sync::Arc}; @@ -23,13 +23,11 @@ fn bench_init_vm(bencher: &mut Bencher) { let mut file = File::open("tests/elfs/relative_call.so").unwrap(); let mut elf = Vec::new(); file.read_to_end(&mut elf).unwrap(); - let executable = Executable::::from_elf( - &elf, - Arc::new(BuiltinProgram::new_mock()), - ) - .unwrap(); + let executable = + Executable::::from_elf(&elf, Arc::new(BuiltinProgram::new_mock())) + .unwrap(); let verified_executable = - Executable::::verified(executable).unwrap(); + Executable::::verified::(executable).unwrap(); bencher.iter(|| { let mut context_object = TestContextObject::default(); create_vm!( @@ -50,12 +48,10 @@ fn bench_jit_compile(bencher: &mut Bencher) { let mut file = File::open("tests/elfs/relative_call.so").unwrap(); let mut elf = Vec::new(); file.read_to_end(&mut elf).unwrap(); - let executable = Executable::::from_elf( - &elf, - Arc::new(BuiltinProgram::new_mock()), - ) - .unwrap(); + let executable = + Executable::::from_elf(&elf, Arc::new(BuiltinProgram::new_mock())) + .unwrap(); let mut verified_executable = - Executable::::verified(executable).unwrap(); + Executable::::verified::(executable).unwrap(); bencher.iter(|| verified_executable.jit_compile().unwrap()); } diff --git a/benches/vm_execution.rs b/benches/vm_execution.rs index 505f927f7..93c82ad22 100644 --- a/benches/vm_execution.rs +++ b/benches/vm_execution.rs @@ -13,7 +13,7 @@ use solana_rbpf::{ ebpf, elf::{Executable, FunctionRegistry}, memory_region::MemoryRegion, - verifier::{RequisiteVerifier, TautologyVerifier}, + verifier::RequisiteVerifier, vm::{BuiltinProgram, Config, TestContextObject}, }; use std::{fs::File, io::Read, sync::Arc}; @@ -25,13 +25,11 @@ fn bench_init_interpreter_start(bencher: &mut Bencher) { let mut file = File::open("tests/elfs/rodata_section.so").unwrap(); let mut elf = Vec::new(); file.read_to_end(&mut elf).unwrap(); - let executable = Executable::::from_elf( - &elf, - Arc::new(BuiltinProgram::new_mock()), - ) - .unwrap(); + let executable = + Executable::::from_elf(&elf, Arc::new(BuiltinProgram::new_mock())) + .unwrap(); let verified_executable = - Executable::::verified(executable).unwrap(); + Executable::::verified::(executable).unwrap(); let mut context_object = TestContextObject::default(); create_vm!( vm, @@ -54,13 +52,11 @@ fn bench_init_jit_start(bencher: &mut Bencher) { let mut file = File::open("tests/elfs/rodata_section.so").unwrap(); let mut elf = Vec::new(); file.read_to_end(&mut elf).unwrap(); - let executable = Executable::::from_elf( - &elf, - Arc::new(BuiltinProgram::new_mock()), - ) - .unwrap(); + let executable = + Executable::::from_elf(&elf, Arc::new(BuiltinProgram::new_mock())) + .unwrap(); let mut verified_executable = - Executable::::verified(executable).unwrap(); + Executable::::verified::(executable).unwrap(); verified_executable.jit_compile().unwrap(); let mut context_object = TestContextObject::default(); create_vm!( @@ -95,7 +91,7 @@ fn bench_jit_vs_interpreter( ) .unwrap(); let mut verified_executable = - Executable::::verified(executable).unwrap(); + Executable::::verified::(executable).unwrap(); verified_executable.jit_compile().unwrap(); let mut context_object = TestContextObject::default(); let mem_region = MemoryRegion::new_writable(mem, ebpf::MM_INPUT_START); diff --git a/cli/src/main.rs b/cli/src/main.rs index c11521c72..4829490dd 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -6,7 +6,7 @@ use solana_rbpf::{ elf::{Executable, FunctionRegistry}, memory_region::{MemoryMapping, MemoryRegion}, static_analysis::Analysis, - verifier::{RequisiteVerifier, TautologyVerifier}, + verifier::{RequisiteVerifier}, vm::{BuiltinProgram, Config, DynamicAnalysis, EbpfVm, TestContextObject}, }; use std::{fs::File, io::Read, path::Path, sync::Arc}; @@ -112,7 +112,7 @@ fn main() { let mut file = File::open(Path::new(matches.value_of("elf").unwrap())).unwrap(); let mut elf = Vec::new(); file.read_to_end(&mut elf).unwrap(); - Executable::::from_elf(&elf, loader) + Executable::::from_elf(&elf, loader) .map_err(|err| format!("Executable constructor failed: {err:?}")) } } @@ -120,7 +120,7 @@ fn main() { #[allow(unused_mut)] let verified_executable = - Executable::::verified(executable).unwrap(); + Executable::::verified::(executable).unwrap(); let mut mem = match matches.value_of("input").unwrap().parse::() { Ok(allocate) => vec![0u8; allocate], diff --git a/examples/disassemble.rs b/examples/disassemble.rs index eab69b941..4417af4a2 100644 --- a/examples/disassemble.rs +++ b/examples/disassemble.rs @@ -8,7 +8,6 @@ extern crate solana_rbpf; use solana_rbpf::{ elf::{Executable, FunctionRegistry, SBPFVersion}, static_analysis::Analysis, - verifier::TautologyVerifier, vm::{BuiltinProgram, TestContextObject}, }; use std::sync::Arc; @@ -32,7 +31,7 @@ fn main() { 0x00, 0x00, 0x00, 0x00, 0x00, ]; let loader = Arc::new(BuiltinProgram::new_mock()); - let executable = Executable::::from_text_bytes( + let executable = Executable::::from_text_bytes( program, loader, SBPFVersion::V2, diff --git a/examples/to_json.rs b/examples/to_json.rs index dc3974bf6..89e9ec9d7 100644 --- a/examples/to_json.rs +++ b/examples/to_json.rs @@ -14,7 +14,6 @@ extern crate solana_rbpf; use solana_rbpf::{ elf::{Executable, FunctionRegistry, SBPFVersion}, static_analysis::Analysis, - verifier::TautologyVerifier, vm::{BuiltinProgram, TestContextObject}, }; use std::sync::Arc; @@ -28,7 +27,7 @@ use std::sync::Arc; // * Print integers as integers, and not as strings containing their hexadecimal representation // (just replace the relevant `format!()` calls by the commented values. fn to_json(program: &[u8]) -> String { - let executable = Executable::::from_text_bytes( + let executable = Executable::::from_text_bytes( program, Arc::new(BuiltinProgram::new_mock()), SBPFVersion::V2, diff --git a/fuzz/fuzz_targets/dumb.rs b/fuzz/fuzz_targets/dumb.rs index ab8ace341..b0dab4e98 100644 --- a/fuzz/fuzz_targets/dumb.rs +++ b/fuzz/fuzz_targets/dumb.rs @@ -8,7 +8,7 @@ use solana_rbpf::{ ebpf, elf::{Executable, FunctionRegistry, SBPFVersion}, memory_region::MemoryRegion, - verifier::{RequisiteVerifier, TautologyVerifier, Verifier}, + verifier::{RequisiteVerifier, Verifier}, vm::{BuiltinProgram, TestContextObject}, }; use test_utils::create_vm; @@ -33,7 +33,7 @@ fuzz_target!(|data: DumbFuzzData| { return; } let mut mem = data.mem; - let executable = Executable::::from_text_bytes( + let executable = Executable::::from_text_bytes( &prog, std::sync::Arc::new(BuiltinProgram::new_loader(config, FunctionRegistry::default())), SBPFVersion::V2, diff --git a/fuzz/fuzz_targets/smart.rs b/fuzz/fuzz_targets/smart.rs index 92d82889f..d1a91a989 100644 --- a/fuzz/fuzz_targets/smart.rs +++ b/fuzz/fuzz_targets/smart.rs @@ -10,7 +10,7 @@ use solana_rbpf::{ elf::{Executable, FunctionRegistry, SBPFVersion}, insn_builder::{Arch, IntoBytes}, memory_region::MemoryRegion, - verifier::{RequisiteVerifier, TautologyVerifier, Verifier}, + verifier::{RequisiteVerifier, Verifier}, vm::{BuiltinProgram, TestContextObject}, }; use test_utils::create_vm; @@ -37,7 +37,7 @@ fuzz_target!(|data: FuzzData| { return; } let mut mem = data.mem; - let executable = Executable::::from_text_bytes( + let executable = Executable::::from_text_bytes( prog.into_bytes(), std::sync::Arc::new(BuiltinProgram::new_loader(config, FunctionRegistry::default())), SBPFVersion::V2, diff --git a/fuzz/fuzz_targets/smart_jit_diff.rs b/fuzz/fuzz_targets/smart_jit_diff.rs index a6c2e99e3..a6fc1e797 100644 --- a/fuzz/fuzz_targets/smart_jit_diff.rs +++ b/fuzz/fuzz_targets/smart_jit_diff.rs @@ -8,7 +8,7 @@ use solana_rbpf::{ elf::{Executable, FunctionRegistry, SBPFVersion}, insn_builder::{Arch, Instruction, IntoBytes}, memory_region::MemoryRegion, - verifier::{RequisiteVerifier, TautologyVerifier, Verifier}, + verifier::{RequisiteVerifier, Verifier}, vm::{BuiltinProgram, TestContextObject}, }; use test_utils::create_vm; @@ -45,7 +45,7 @@ fuzz_target!(|data: FuzzData| { } let mut interp_mem = data.mem.clone(); let mut jit_mem = data.mem; - let mut executable = Executable::::from_text_bytes( + let mut executable = Executable::::from_text_bytes( prog.into_bytes(), std::sync::Arc::new(BuiltinProgram::new_loader(config, FunctionRegistry::default())), SBPFVersion::V2, diff --git a/fuzz/fuzz_targets/smarter_jit_diff.rs b/fuzz/fuzz_targets/smarter_jit_diff.rs index d2639f9e8..15837b9b0 100644 --- a/fuzz/fuzz_targets/smarter_jit_diff.rs +++ b/fuzz/fuzz_targets/smarter_jit_diff.rs @@ -9,7 +9,7 @@ use solana_rbpf::{ insn_builder::IntoBytes, memory_region::MemoryRegion, static_analysis::Analysis, - verifier::{RequisiteVerifier, TautologyVerifier, Verifier}, + verifier::{RequisiteVerifier, Verifier}, vm::{ BuiltinProgram, ContextObject, TestContextObject, }, @@ -28,7 +28,7 @@ struct FuzzData { mem: Vec, } -fn dump_insns(verified_executable: &Executable) { +fn dump_insns(verified_executable: &Executable) { let analysis = Analysis::from_executable(verified_executable).unwrap(); eprint!("Using the following disassembly"); analysis.disassemble(&mut std::io::stderr().lock()).unwrap(); @@ -44,7 +44,7 @@ fuzz_target!(|data: FuzzData| { } let mut interp_mem = data.mem.clone(); let mut jit_mem = data.mem; - let mut executable = Executable::::from_text_bytes( + let mut executable = Executable::::from_text_bytes( prog.into_bytes(), std::sync::Arc::new(BuiltinProgram::new_loader(config, FunctionRegistry::default())), SBPFVersion::V2, diff --git a/src/assembler.rs b/src/assembler.rs index 998870a8c..5208ab087 100644 --- a/src/assembler.rs +++ b/src/assembler.rs @@ -19,7 +19,6 @@ use crate::{ }, ebpf::{self, Insn}, elf::{Executable, FunctionRegistry, SBPFVersion}, - verifier::TautologyVerifier, vm::{BuiltinProgram, ContextObject}, }; use std::{collections::HashMap, sync::Arc}; @@ -218,7 +217,7 @@ fn insn(opc: u8, dst: i64, src: i64, off: i64, imm: i64) -> Result pub fn assemble( src: &str, loader: Arc>, -) -> Result, String> { +) -> Result, String> { let sbpf_version = if loader.get_config().enable_sbpf_v2 { SBPFVersion::V2 } else { @@ -366,11 +365,6 @@ pub fn assemble( .iter() .flat_map(|insn| insn.to_vec()) .collect::>(); - Executable::::from_text_bytes( - &program, - loader, - sbpf_version, - function_registry, - ) - .map_err(|err| format!("Executable constructor {err:?}")) + Executable::::from_text_bytes(&program, loader, sbpf_version, function_registry) + .map_err(|err| format!("Executable constructor {err:?}")) } diff --git a/src/debugger.rs b/src/debugger.rs index db0634121..79bf4d5dc 100644 --- a/src/debugger.rs +++ b/src/debugger.rs @@ -43,7 +43,7 @@ fn wait_for_tcp(port: u16) -> DynResult { } /// Connect to the debugger and hand over the control of the interpreter -pub fn execute(interpreter: &mut Interpreter, port: u16) { +pub fn execute(interpreter: &mut Interpreter, port: u16) { let connection: Box> = Box::new(wait_for_tcp(port).expect("Cannot connect to Debugger")); let mut dbg = GdbStub::new(connection) @@ -117,7 +117,7 @@ pub fn execute(interpreter: &mut Interpreter Target for Interpreter<'a, 'b, V, C> { +impl<'a, 'b, C: ContextObject> Target for Interpreter<'a, 'b, C> { type Arch = Bpf; type Error = &'static str; @@ -149,8 +149,8 @@ impl<'a, 'b, V: Verifier, C: ContextObject> Target for Interpreter<'a, 'b, V, C> } } -fn get_host_ptr( - interpreter: &mut Interpreter, +fn get_host_ptr( + interpreter: &mut Interpreter, mut vm_addr: u64, pc: usize, ) -> Result<*mut u8, Box> { @@ -168,7 +168,7 @@ fn get_host_ptr( } } -impl<'a, 'b, V: Verifier, C: ContextObject> SingleThreadBase for Interpreter<'a, 'b, V, C> { +impl<'a, 'b, C: ContextObject> SingleThreadBase for Interpreter<'a, 'b, C> { fn read_registers(&mut self, regs: &mut BpfRegs) -> TargetResult<(), Self> { for i in 0..10 { regs.r[i] = self.reg[i]; @@ -222,9 +222,8 @@ impl<'a, 'b, V: Verifier, C: ContextObject> SingleThreadBase for Interpreter<'a, } } -impl<'a, 'b, V: Verifier, C: ContextObject> - target::ext::base::single_register_access::SingleRegisterAccess<()> - for Interpreter<'a, 'b, V, C> +impl<'a, 'b, C: ContextObject> target::ext::base::single_register_access::SingleRegisterAccess<()> + for Interpreter<'a, 'b, C> { fn read_register( &mut self, @@ -262,7 +261,7 @@ impl<'a, 'b, V: Verifier, C: ContextObject> } } -impl<'a, 'b, V: Verifier, C: ContextObject> SingleThreadResume for Interpreter<'a, 'b, V, C> { +impl<'a, 'b, C: ContextObject> SingleThreadResume for Interpreter<'a, 'b, C> { fn resume(&mut self, signal: Option) -> Result<(), Self::Error> { if signal.is_some() { return Err("no support for continuing with signal"); @@ -281,8 +280,8 @@ impl<'a, 'b, V: Verifier, C: ContextObject> SingleThreadResume for Interpreter<' } } -impl<'a, 'b, V: Verifier, C: ContextObject> target::ext::base::singlethread::SingleThreadSingleStep - for Interpreter<'a, 'b, V, C> +impl<'a, 'b, C: ContextObject> target::ext::base::singlethread::SingleThreadSingleStep + for Interpreter<'a, 'b, C> { fn step(&mut self, signal: Option) -> Result<(), Self::Error> { if signal.is_some() { @@ -295,8 +294,8 @@ impl<'a, 'b, V: Verifier, C: ContextObject> target::ext::base::singlethread::Sin } } -impl<'a, 'b, V: Verifier, C: ContextObject> target::ext::section_offsets::SectionOffsets - for Interpreter<'a, 'b, V, C> +impl<'a, 'b, C: ContextObject> target::ext::section_offsets::SectionOffsets + for Interpreter<'a, 'b, C> { fn get_section_offsets(&mut self) -> Result, Self::Error> { Ok(Offsets::Sections { @@ -307,9 +306,7 @@ impl<'a, 'b, V: Verifier, C: ContextObject> target::ext::section_offsets::Sectio } } -impl<'a, 'b, V: Verifier, C: ContextObject> target::ext::breakpoints::Breakpoints - for Interpreter<'a, 'b, V, C> -{ +impl<'a, 'b, C: ContextObject> target::ext::breakpoints::Breakpoints for Interpreter<'a, 'b, C> { #[inline(always)] fn support_sw_breakpoint( &mut self, @@ -318,9 +315,7 @@ impl<'a, 'b, V: Verifier, C: ContextObject> target::ext::breakpoints::Breakpoint } } -impl<'a, 'b, V: Verifier, C: ContextObject> target::ext::breakpoints::SwBreakpoint - for Interpreter<'a, 'b, V, C> -{ +impl<'a, 'b, C: ContextObject> target::ext::breakpoints::SwBreakpoint for Interpreter<'a, 'b, C> { fn add_sw_breakpoint( &mut self, addr: u64, @@ -345,9 +340,8 @@ impl<'a, 'b, V: Verifier, C: ContextObject> target::ext::breakpoints::SwBreakpoi } } -impl<'a, 'b, V: Verifier, C: ContextObject> - target::ext::lldb_register_info_override::LldbRegisterInfoOverride - for Interpreter<'a, 'b, V, C> +impl<'a, 'b, C: ContextObject> target::ext::lldb_register_info_override::LldbRegisterInfoOverride + for Interpreter<'a, 'b, C> { fn lldb_register_info<'c>( &mut self, diff --git a/src/elf.rs b/src/elf.rs index ce1218b0c..beac98a46 100644 --- a/src/elf.rs +++ b/src/elf.rs @@ -22,7 +22,7 @@ use crate::{ }, error::EbpfError, memory_region::MemoryRegion, - verifier::{TautologyVerifier, Verifier}, + verifier::Verifier, vm::{BuiltinProgram, Config, ContextObject}, }; @@ -32,7 +32,6 @@ use byteorder::{ByteOrder, LittleEndian}; use std::{ collections::{btree_map::Entry, BTreeMap}, fmt::Debug, - marker::PhantomData, mem, ops::Range, str, @@ -409,9 +408,7 @@ impl FunctionRegistry { /// Elf loader/relocator #[derive(Debug, PartialEq)] -pub struct Executable { - /// Verifier that verified this program - _verifier: PhantomData, +pub struct Executable { /// Loaded and executable elf elf_bytes: AlignedMemory<{ HOST_ALIGN }>, /// Required SBPF capabilities @@ -431,7 +428,7 @@ pub struct Executable { compiled_program: Option, } -impl Executable { +impl Executable { /// Get the configuration settings pub fn get_config(&self) -> &Config { self.loader.get_config() @@ -500,22 +497,20 @@ impl Executable { } /// Verify the executable - pub fn verified(executable: Executable) -> Result { + pub fn verified(executable: Executable) -> Result { ::verify( executable.get_text_bytes().1, executable.get_config(), executable.get_sbpf_version(), executable.get_function_registry(), )?; - Ok(unsafe { - std::mem::transmute::, Executable>(executable) - }) + Ok(unsafe { std::mem::transmute::, Executable>(executable) }) } /// JIT compile the executable #[cfg(all(feature = "jit", not(target_os = "windows"), target_arch = "x86_64"))] pub fn jit_compile(&mut self) -> Result<(), crate::error::EbpfError> { - let jit = JitCompiler::::new(self)?; + let jit = JitCompiler::::new(self)?; self.compiled_program = Some(jit.compile()?); Ok(()) } @@ -547,7 +542,6 @@ impl Executable { 0 }; Ok(Self { - _verifier: PhantomData, elf_bytes, sbpf_version, ro_section: Section::Borrowed(0, 0..text_bytes.len()), @@ -678,7 +672,6 @@ impl Executable { )?; Ok(Self { - _verifier: PhantomData, elf_bytes, sbpf_version, ro_section, @@ -1408,7 +1401,7 @@ mod test { use rand::{distributions::Uniform, Rng}; use std::{fs::File, io::Read}; use test_utils::assert_error; - type ElfExecutable = Executable; + type ElfExecutable = Executable; fn loader() -> Arc> { let mut function_registry = @@ -1533,7 +1526,7 @@ mod test { .expect("failed to read elf file"); let elf = ElfExecutable::load(&elf_bytes, loader.clone()).expect("validation failed"); let parsed_elf = NewParser::parse(&elf_bytes).unwrap(); - let executable: &Executable = &elf; + let executable: &Executable = &elf; assert_eq!(0, executable.get_entrypoint_instruction_offset()); let write_header = |header: Elf64Ehdr| unsafe { @@ -1548,7 +1541,7 @@ mod test { header.e_entry += 8; let elf_bytes = write_header(header.clone()); let elf = ElfExecutable::load(&elf_bytes, loader.clone()).expect("validation failed"); - let executable: &Executable = &elf; + let executable: &Executable = &elf; assert_eq!(1, executable.get_entrypoint_instruction_offset()); header.e_entry = 1; @@ -1575,7 +1568,7 @@ mod test { header.e_entry = initial_e_entry; let elf_bytes = write_header(header); let elf = ElfExecutable::load(&elf_bytes, loader).expect("validation failed"); - let executable: &Executable = &elf; + let executable: &Executable = &elf; assert_eq!(0, executable.get_entrypoint_instruction_offset()); } diff --git a/src/interpreter.rs b/src/interpreter.rs index 518d85ca3..0ab0854c4 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -16,7 +16,6 @@ use crate::{ ebpf::{self, STACK_PTR_REG}, elf::Executable, error::EbpfError, - verifier::Verifier, vm::{Config, ContextObject, EbpfVm, ProgramResult}, }; use std::convert::TryInto; @@ -65,9 +64,9 @@ pub enum DebugState { } /// State of an interpreter -pub struct Interpreter<'a, 'b, V: Verifier, C: ContextObject> { +pub struct Interpreter<'a, 'b, C: ContextObject> { pub(crate) vm: &'a mut EbpfVm<'b, C>, - pub(crate) executable: &'a Executable, + pub(crate) executable: &'a Executable, pub(crate) program: &'a [u8], pub(crate) program_vm_addr: u64, pub(crate) due_insn_count: u64, @@ -83,11 +82,11 @@ pub struct Interpreter<'a, 'b, V: Verifier, C: ContextObject> { pub(crate) breakpoints: Vec, } -impl<'a, 'b, V: Verifier, C: ContextObject> Interpreter<'a, 'b, V, C> { +impl<'a, 'b, C: ContextObject> Interpreter<'a, 'b, C> { /// Creates a new interpreter state pub fn new( vm: &'a mut EbpfVm<'b, C>, - executable: &'a Executable, + executable: &'a Executable, registers: [u64; 12], ) -> Self { let (program_vm_addr, program) = executable.get_text_bytes(); diff --git a/src/jit.rs b/src/jit.rs index d84a7a4c2..122881630 100644 --- a/src/jit.rs +++ b/src/jit.rs @@ -21,7 +21,6 @@ use crate::{ allocate_pages, free_pages, get_system_page_size, protect_pages, round_to_page_size, }, memory_region::{AccessType, MemoryMapping}, - verifier::Verifier, vm::{Config, ContextObject, EbpfVm, ProgramResult}, x86::*, }; @@ -310,12 +309,12 @@ enum RuntimeEnvironmentSlot { and undo again can be anything, so we just set it to zero. */ -pub struct JitCompiler<'a, V: Verifier, C: ContextObject> { +pub struct JitCompiler<'a, C: ContextObject> { result: JitProgram, text_section_jumps: Vec, anchors: [*const u8; ANCHOR_COUNT], offset_in_text_section: usize, - executable: &'a Executable, + executable: &'a Executable, program: &'a [u8], program_vm_addr: u64, config: &'a Config, @@ -328,9 +327,9 @@ pub struct JitCompiler<'a, V: Verifier, C: ContextObject> { } #[rustfmt::skip] -impl<'a, V: Verifier, C: ContextObject> JitCompiler<'a, V, C> { +impl<'a, C: ContextObject> JitCompiler<'a, C> { /// Constructs a new compiler and allocates memory for the compilation output - pub fn new(executable: &'a Executable) -> Result { + pub fn new(executable: &'a Executable) -> Result { let config = executable.get_config(); let (program_vm_addr, program) = executable.get_text_bytes(); @@ -1603,7 +1602,6 @@ mod tests { use crate::{ elf::{FunctionRegistry, SBPFVersion}, syscalls, - verifier::TautologyVerifier, vm::{BuiltinFunction, BuiltinProgram, TestContextObject}, }; use byteorder::{ByteOrder, LittleEndian}; @@ -1644,9 +1642,7 @@ mod tests { check_slot!(env, memory_mapping, MemoryMapping); } - fn create_mockup_executable( - program: &[u8], - ) -> Executable { + fn create_mockup_executable(program: &[u8]) -> Executable { let mut function_registry = FunctionRegistry::>::default(); function_registry @@ -1663,7 +1659,7 @@ mod tests { function_registry .register_function(8, *b"function_foo", 8) .unwrap(); - Executable::::from_text_bytes( + Executable::::from_text_bytes( program, Arc::new(loader), SBPFVersion::V2, @@ -1680,8 +1676,7 @@ mod tests { let empty_program_machine_code_length = { prog[0] = ebpf::EXIT; let mut executable = create_mockup_executable(&prog[0..ebpf::INSN_SIZE]); - Executable::::jit_compile(&mut executable) - .unwrap(); + Executable::::jit_compile(&mut executable).unwrap(); executable .get_compiled_program() .unwrap() @@ -1708,8 +1703,7 @@ mod tests { LittleEndian::write_u32(&mut prog[pc * ebpf::INSN_SIZE + 4..], immediate); } let mut executable = create_mockup_executable(&prog); - let result = - Executable::::jit_compile(&mut executable); + let result = Executable::::jit_compile(&mut executable); if result.is_err() { assert!(matches!( result.unwrap_err(), diff --git a/src/static_analysis.rs b/src/static_analysis.rs index 07c7b09c7..67fe9c99c 100644 --- a/src/static_analysis.rs +++ b/src/static_analysis.rs @@ -6,7 +6,6 @@ use crate::{ ebpf, elf::Executable, error::EbpfError, - verifier::{TautologyVerifier, Verifier}, vm::{ContextObject, DynamicAnalysis, TestContextObject}, }; use rustc_demangle::demangle; @@ -127,7 +126,7 @@ impl Default for CfgNode { /// Result of the executable analysis pub struct Analysis<'a> { /// The program which is analyzed - executable: &'a Executable, + executable: &'a Executable, /// Plain list of instructions as they occur in the executable pub instructions: Vec, /// Functions in the executable @@ -148,8 +147,8 @@ pub struct Analysis<'a> { impl<'a> Analysis<'a> { /// Analyze an executable statically - pub fn from_executable( - executable: &'a Executable, + pub fn from_executable( + executable: &'a Executable, ) -> Result { let (_program_vm_addr, program) = executable.get_text_bytes(); let mut functions = BTreeMap::new(); diff --git a/src/vm.rs b/src/vm.rs index bd1dc94a0..5ba70a272 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -19,7 +19,6 @@ use crate::{ interpreter::Interpreter, memory_region::MemoryMapping, static_analysis::{Analysis, TraceLogEntry}, - verifier::{TautologyVerifier, Verifier}, }; use std::{collections::BTreeMap, fmt::Debug, mem, sync::Arc}; @@ -234,7 +233,7 @@ impl Default for Config { } /// Static constructors for Executable -impl Executable { +impl Executable { /// Creates an executable from an ELF file pub fn from_elf(elf_bytes: &[u8], loader: Arc>) -> Result { let executable = Executable::load(elf_bytes, loader)?; @@ -362,7 +361,7 @@ pub struct CallFrame { /// ebpf, /// elf::{Executable, FunctionRegistry, SBPFVersion}, /// memory_region::{MemoryMapping, MemoryRegion}, -/// verifier::{TautologyVerifier, RequisiteVerifier}, +/// verifier::{RequisiteVerifier}, /// vm::{BuiltinProgram, Config, EbpfVm, TestContextObject}, /// }; /// @@ -375,8 +374,8 @@ pub struct CallFrame { /// /// let loader = std::sync::Arc::new(BuiltinProgram::new_mock()); /// let function_registry = FunctionRegistry::default(); -/// let mut executable = Executable::::from_text_bytes(prog, loader, SBPFVersion::V2, function_registry).unwrap(); -/// let verified_executable = Executable::::verified(executable).unwrap(); +/// let mut executable = Executable::::from_text_bytes(prog, loader, SBPFVersion::V2, function_registry).unwrap(); +/// let verified_executable = Executable::::verified::(executable).unwrap(); /// let mut context_object = TestContextObject::new(1); /// let config = verified_executable.get_config(); /// let sbpf_version = verified_executable.get_sbpf_version(); @@ -477,9 +476,9 @@ impl<'a, C: ContextObject> EbpfVm<'a, C> { /// Execute the program /// /// If interpreted = `false` then the JIT compiled executable is used. - pub fn execute_program( + pub fn execute_program( &mut self, - executable: &Executable, + executable: &Executable, interpreted: bool, ) -> (u64, ProgramResult) { let mut registers = [0u64; 12]; diff --git a/src/x86.rs b/src/x86.rs index a191a34a9..9d33ba7fd 100644 --- a/src/x86.rs +++ b/src/x86.rs @@ -1,7 +1,6 @@ #![allow(clippy::arithmetic_side_effects)] use crate::{ jit::{JitCompiler, OperandSize}, - verifier::Verifier, vm::ContextObject, }; @@ -103,7 +102,7 @@ impl X86Instruction { }; #[inline] - pub fn emit(&self, jit: &mut JitCompiler) { + pub fn emit(&self, jit: &mut JitCompiler) { debug_assert!(!matches!(self.size, OperandSize::S0)); let mut rex = X86Rex { w: matches!(self.size, OperandSize::S64), diff --git a/test_utils/src/lib.rs b/test_utils/src/lib.rs index b26bb0c6c..d173dd943 100644 --- a/test_utils/src/lib.rs +++ b/test_utils/src/lib.rs @@ -14,7 +14,6 @@ use solana_rbpf::{ elf::Executable, error::EbpfError, memory_region::{MemoryCowCallback, MemoryMapping, MemoryRegion}, - verifier::Verifier, vm::ContextObject, }; @@ -159,8 +158,8 @@ pub const TCP_SACK_NOMATCH: [u8; 66] = [ 0x9e, 0x27, // ]; -pub fn create_memory_mapping<'a, V: Verifier, C: ContextObject>( - executable: &'a Executable, +pub fn create_memory_mapping<'a, C: ContextObject>( + executable: &'a Executable, stack: &'a mut AlignedMemory<{ HOST_ALIGN }>, heap: &'a mut AlignedMemory<{ HOST_ALIGN }>, additional_regions: Vec, diff --git a/tests/execution.rs b/tests/execution.rs index 88a8293f7..b9a346362 100644 --- a/tests/execution.rs +++ b/tests/execution.rs @@ -23,7 +23,7 @@ use solana_rbpf::{ memory_region::{AccessType, MemoryMapping, MemoryRegion}, static_analysis::Analysis, syscalls, - verifier::{RequisiteVerifier, TautologyVerifier}, + verifier::RequisiteVerifier, vm::{ BuiltinFunction, BuiltinProgram, Config, ContextObject, ProgramResult, TestContextObject, }, @@ -51,7 +51,7 @@ macro_rules! test_interpreter_and_jit { } #[allow(unused_mut)] let mut verified_executable = - Executable::::verified($executable).unwrap(); + Executable::<_>::verified::($executable).unwrap(); let (instruction_count_interpreter, _tracer_interpreter) = { let mut mem = $mem; let mem_region = MemoryRegion::new_writable(&mut mem, ebpf::MM_INPUT_START); @@ -161,7 +161,7 @@ macro_rules! test_interpreter_and_jit_elf { let mut function_registry = FunctionRegistry::>::default(); $(test_interpreter_and_jit!(register, function_registry, $location => $syscall_function);)* let loader = Arc::new(BuiltinProgram::new_loader($config, function_registry)); - let mut executable = Executable::::from_elf(&elf, loader).unwrap(); + let mut executable = Executable::::from_elf(&elf, loader).unwrap(); test_interpreter_and_jit!(executable, $mem, $context_object, $expected_result); } }; @@ -2733,7 +2733,7 @@ fn test_err_mem_access_out_of_bound() { LittleEndian::write_u32(&mut prog[4..], address as u32); LittleEndian::write_u32(&mut prog[12..], (address >> 32) as u32); #[allow(unused_mut)] - let mut executable = Executable::::from_text_bytes( + let mut executable = Executable::::from_text_bytes( &prog, loader.clone(), SBPFVersion::V2, @@ -3457,7 +3457,7 @@ fn test_err_unresolved_syscall_reloc_64_32() { let mut elf = Vec::new(); file.read_to_end(&mut elf).unwrap(); assert_error!( - Executable::::from_elf(&elf, Arc::new(loader)), + Executable::::from_elf(&elf, Arc::new(loader)), "UnresolvedSymbol(\"log\", 68, 312)" ); } @@ -3851,7 +3851,7 @@ fn test_struct_func_pointer() { fn execute_generated_program(prog: &[u8]) -> bool { let max_instruction_count = 1024; let mem_size = 1024 * 1024; - let executable = Executable::::from_text_bytes( + let executable = Executable::::from_text_bytes( prog, Arc::new(BuiltinProgram::new_loader( Config { @@ -3869,7 +3869,7 @@ fn execute_generated_program(prog: &[u8]) -> bool { return false; }; let verified_executable = - Executable::::verified(executable); + Executable::::verified::(executable); let mut verified_executable = if let Ok(verified_executable) = verified_executable { verified_executable } else { diff --git a/tests/verifier.rs b/tests/verifier.rs index e3be968b2..57a5679b3 100644 --- a/tests/verifier.rs +++ b/tests/verifier.rs @@ -62,7 +62,7 @@ fn test_verifier_success() { ) .unwrap(); let verified_executable = - Executable::::verified(executable).unwrap(); + Executable::::verified::(executable).unwrap(); create_vm!( _vm, &verified_executable, @@ -85,7 +85,7 @@ fn test_verifier_fail() { ) .unwrap(); let _verified_executable = - Executable::::verified(executable).unwrap(); + Executable::::verified::(executable).unwrap(); } #[test] @@ -100,7 +100,7 @@ fn test_verifier_err_div_by_zero_imm() { ) .unwrap(); let _verified_executable = - Executable::::verified(executable).unwrap(); + Executable::::verified::(executable).unwrap(); } #[test] @@ -111,7 +111,7 @@ fn test_verifier_err_endian_size() { 0xb7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ]; - let executable = Executable::::from_text_bytes( + let executable = Executable::::from_text_bytes( prog, Arc::new(BuiltinProgram::new_mock()), SBPFVersion::V2, @@ -119,7 +119,7 @@ fn test_verifier_err_endian_size() { ) .unwrap(); let _verified_executable = - Executable::::verified(executable).unwrap(); + Executable::::verified::(executable).unwrap(); } #[test] @@ -130,7 +130,7 @@ fn test_verifier_err_incomplete_lddw() { 0x18, 0x00, 0x00, 0x00, 0x88, 0x77, 0x66, 0x55, // 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ]; - let executable = Executable::::from_text_bytes( + let executable = Executable::::from_text_bytes( prog, Arc::new(BuiltinProgram::new_mock()), SBPFVersion::V1, @@ -138,7 +138,7 @@ fn test_verifier_err_incomplete_lddw() { ) .unwrap(); let _verified_executable = - Executable::::verified(executable).unwrap(); + Executable::::verified::(executable).unwrap(); } #[test] @@ -159,7 +159,7 @@ fn test_verifier_err_invalid_reg_dst() { )), ) .unwrap(); - let result = Executable::::verified(executable) + let result = Executable::::verified::(executable) .map_err(|err| format!("Executable constructor {err:?}")); assert_eq!( @@ -187,7 +187,7 @@ fn test_verifier_err_invalid_reg_src() { )), ) .unwrap(); - let result = Executable::::verified(executable) + let result = Executable::::verified::(executable) .map_err(|err| format!("Executable constructor {err:?}")); assert_eq!( @@ -214,7 +214,7 @@ fn test_verifier_resize_stack_ptr_success() { ) .unwrap(); let _verified_executable = - Executable::::verified(executable).unwrap(); + Executable::::verified::(executable).unwrap(); } #[test] @@ -229,7 +229,7 @@ fn test_verifier_err_jmp_lddw() { ) .unwrap(); let _verified_executable = - Executable::::verified(executable).unwrap(); + Executable::::verified::(executable).unwrap(); } #[test] @@ -244,7 +244,7 @@ fn test_verifier_err_call_lddw() { ) .unwrap(); let _verified_executable = - Executable::::verified(executable).unwrap(); + Executable::::verified::(executable).unwrap(); } #[test] @@ -259,7 +259,7 @@ fn test_verifier_err_function_fallthrough() { ) .unwrap(); let _verified_executable = - Executable::::verified(executable).unwrap(); + Executable::::verified::(executable).unwrap(); } #[test] @@ -273,7 +273,7 @@ fn test_verifier_err_jmp_out() { ) .unwrap(); let _verified_executable = - Executable::::verified(executable).unwrap(); + Executable::::verified::(executable).unwrap(); } #[test] @@ -287,7 +287,7 @@ fn test_verifier_err_jmp_out_start() { ) .unwrap(); let _verified_executable = - Executable::::verified(executable).unwrap(); + Executable::::verified::(executable).unwrap(); } #[test] @@ -297,7 +297,7 @@ fn test_verifier_err_unknown_opcode() { 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ]; - let executable = Executable::::from_text_bytes( + let executable = Executable::::from_text_bytes( prog, Arc::new(BuiltinProgram::new_mock()), SBPFVersion::V2, @@ -305,7 +305,7 @@ fn test_verifier_err_unknown_opcode() { ) .unwrap(); let _verified_executable = - Executable::::verified(executable).unwrap(); + Executable::::verified::(executable).unwrap(); } #[test] @@ -319,7 +319,7 @@ fn test_verifier_err_write_r10() { ) .unwrap(); let _verified_executable = - Executable::::verified(executable).unwrap(); + Executable::::verified::(executable).unwrap(); } #[test] @@ -352,7 +352,7 @@ fn test_verifier_err_all_shift_overflows() { let assembly = format!("\n{overflowing_instruction}\nexit"); let executable = assemble::(&assembly, Arc::new(BuiltinProgram::new_mock())).unwrap(); - let result = Executable::::verified(executable) + let result = Executable::::verified::(executable) .map_err(|err| format!("Executable constructor {err:?}")); match expected { Ok(()) => assert!(result.is_ok()), @@ -390,7 +390,7 @@ fn test_sdiv_disabled() { )), ) .unwrap(); - let result = Executable::::verified(executable) + let result = Executable::::verified::(executable) .map_err(|err| format!("Executable constructor {err:?}")); if enable_sbpf_v2 { assert!(result.is_ok());