Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor - Error handling #527

Merged
merged 3 commits into from
Sep 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 5 additions & 8 deletions benches/memory_mapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ macro_rules! bench_gapped_randomized_access_with_1024_entries {
AccessType::Load,
0x100000000 + (prng.gen::<u64>() % frame_count * (frame_size * 2)),
1,
0,
)
.is_ok());
});
Expand Down Expand Up @@ -119,7 +118,6 @@ macro_rules! bench_randomized_access_with_0001_entry {
AccessType::Load,
0x100000000 + (prng.gen::<u64>() % content.len() as u64),
1,
0,
);
});
}
Expand Down Expand Up @@ -153,7 +151,6 @@ macro_rules! bench_randomized_access_with_n_entries {
AccessType::Load,
0x100000000 + (prng.gen::<u64>() % end_address),
1,
0,
);
});
}
Expand Down Expand Up @@ -199,7 +196,7 @@ macro_rules! bench_randomized_mapping_with_n_entries {
let config = Config::default();
let memory_mapping = $mem::new(memory_regions, &config, &SBPFVersion::V2).unwrap();
bencher.iter(|| {
let _ = memory_mapping.map(AccessType::Load, 0x100000000, 1, 0);
let _ = memory_mapping.map(AccessType::Load, 0x100000000, 1);
});
}
};
Expand Down Expand Up @@ -248,7 +245,7 @@ macro_rules! bench_mapping_with_n_entries {
let config = Config::default();
let memory_mapping = $mem::new(memory_regions, &config, &SBPFVersion::V2).unwrap();
bencher.iter(|| {
let _ = memory_mapping.map(AccessType::Load, 0x100000000, 1, 0);
let _ = memory_mapping.map(AccessType::Load, 0x100000000, 1);
});
}
};
Expand Down Expand Up @@ -310,13 +307,13 @@ fn do_bench_mapping_operation(bencher: &mut Bencher, op: MemoryOperation, vm_add

match op {
MemoryOperation::Map => bencher.iter(|| {
let _ = memory_mapping.map(AccessType::Load, vm_addr, 8, 0).unwrap();
let _ = memory_mapping.map(AccessType::Load, vm_addr, 8).unwrap();
}),
MemoryOperation::Load => bencher.iter(|| {
let _ = memory_mapping.load::<u64>(vm_addr, 0).unwrap();
let _ = memory_mapping.load::<u64>(vm_addr).unwrap();
}),
MemoryOperation::Store(val) => bencher.iter(|| {
let _ = memory_mapping.store(val, vm_addr, 0).unwrap();
let _ = memory_mapping.store(val, vm_addr).unwrap();
}),
}
}
Expand Down
7 changes: 3 additions & 4 deletions src/debugger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use gdbstub::target::ext::section_offsets::Offsets;

use crate::{
ebpf,
error::EbpfError,
interpreter::{DebugState, Interpreter},
memory_region::AccessType,
vm::{ContextObject, ProgramResult},
Expand Down Expand Up @@ -151,16 +152,14 @@ impl<'a, 'b, C: ContextObject> Target for Interpreter<'a, 'b, C> {
fn get_host_ptr<C: ContextObject>(
interpreter: &mut Interpreter<C>,
mut vm_addr: u64,
pc: usize,
) -> Result<*mut u8, Box<dyn std::error::Error>> {
) -> Result<*mut u8, EbpfError> {
if vm_addr < ebpf::MM_PROGRAM_START {
vm_addr += ebpf::MM_PROGRAM_START;
}
match interpreter.vm.memory_mapping.map(
AccessType::Load,
vm_addr,
std::mem::size_of::<u8>() as u64,
pc + ebpf::ELF_INSN_DUMP_OFFSET,
) {
ProgramResult::Ok(host_addr) => Ok(host_addr as *mut u8),
ProgramResult::Err(err) => Err(err),
Expand Down Expand Up @@ -196,7 +195,7 @@ impl<'a, 'b, C: ContextObject> SingleThreadBase for Interpreter<'a, 'b, C> {

fn read_addrs(&mut self, start_addr: u64, data: &mut [u8]) -> TargetResult<(), Self> {
for (vm_addr, val) in (start_addr..).zip(data.iter_mut()) {
let host_ptr = match get_host_ptr(self, vm_addr, self.pc) {
let host_ptr = match get_host_ptr(self, vm_addr) {
Ok(host_ptr) => host_ptr,
// The debugger is sometimes requesting more data than we have access to, just skip these
_ => continue,
Expand Down
54 changes: 27 additions & 27 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
//! <https://www.kernel.org/doc/Documentation/networking/filter.txt>, or for a shorter version of
//! the list of the operation codes: <https://github.com/iovisor/bpf-docs/blob/master/eBPF.md>

use crate::{elf::ElfError, memory_region::AccessType, verifier::VerifierError};
use {
crate::{elf::ElfError, memory_region::AccessType, verifier::VerifierError},
std::error::Error,
};

/// Error definitions
#[derive(Debug, thiserror::Error)]
Expand All @@ -30,28 +33,26 @@ pub enum EbpfError {
#[error("function #{0} was already registered")]
FunctionAlreadyRegistered(usize),
/// Exceeded max BPF to BPF call depth
#[error("exceeded max BPF to BPF call depth of {1} at BPF instruction #{0}")]
CallDepthExceeded(usize, usize),
#[error("exceeded max BPF to BPF call depth")]
CallDepthExceeded,
/// Attempt to exit from root call frame
#[error("attempted to exit root call frame")]
ExitRootCallFrame,
/// Divide by zero"
#[error("divide by zero at BPF instruction {0}")]
DivideByZero(usize),
#[error("divide by zero at BPF instruction")]
DivideByZero,
/// Divide overflow
#[error("division overflow at BPF instruction {0}")]
DivideOverflow(usize),
#[error("division overflow at BPF instruction")]
DivideOverflow,
/// Exceeded max instructions allowed
#[error("attempted to execute past the end of the text segment at BPF instruction #{0}")]
ExecutionOverrun(usize),
#[error("attempted to execute past the end of the text segment at BPF instruction")]
ExecutionOverrun,
/// Attempt to call to an address outside the text segment
#[error(
"callx at BPF instruction {0} attempted to call outside of the text segment to addr 0x{1:x}"
)]
CallOutsideTextSegment(usize, u64),
#[error("callx attempted to call outside of the text segment")]
CallOutsideTextSegment,
/// Exceeded max instructions allowed
#[error("exceeded CUs meter at BPF instruction #{0}")]
ExceededMaxInstructions(usize),
#[error("exceeded CUs meter at BPF instruction")]
ExceededMaxInstructions,
/// Program has not been JIT-compiled
#[error("program has not been JIT-compiled")]
JitNotCompiled,
Expand All @@ -62,21 +63,17 @@ pub enum EbpfError {
#[error("Invalid memory region at index {0}")]
InvalidMemoryRegion(usize),
/// Access violation (general)
#[error(
"Access violation in {4} section at address {2:#x} of size {3:?} at BPF instruction #{0}"
)]
AccessViolation(usize, AccessType, u64, u64, &'static str),
#[error("Access violation in {3} section at address {1:#x} of size {2:?}")]
AccessViolation(AccessType, u64, u64, &'static str),
/// Access violation (stack specific)
#[error(
"Access violation in stack frame {4} at address {2:#x} of size {3:?} at BPF instruction #{0}"
)]
StackAccessViolation(usize, AccessType, u64, u64, i64),
#[error("Access violation in stack frame {3} at address {1:#x} of size {2:?}")]
StackAccessViolation(AccessType, u64, u64, i64),
/// Invalid instruction
#[error("invalid BPF instruction at {0}")]
InvalidInstruction(usize),
#[error("invalid BPF instruction")]
InvalidInstruction,
/// Unsupported instruction
#[error("unsupported BPF instruction at {0}")]
UnsupportedInstruction(usize),
#[error("unsupported BPF instruction")]
UnsupportedInstruction,
/// Compilation is too big to fit
#[error("Compilation exhausted text segment at BPF instruction {0}")]
ExhaustedTextSegment(usize),
Expand All @@ -86,4 +83,7 @@ pub enum EbpfError {
/// Verifier error
#[error("Verifier error: {0}")]
VerifierError(#[from] VerifierError),
/// Syscall error
#[error("Syscall error: {0}")]
SyscallError(Box<dyn Error>),
}
Loading