use crate::{elf::ElfError, memory_region::AccessType};
pub trait UserDefinedError: 'static + std::error::Error {}
#[derive(Debug, thiserror::Error, PartialEq, Eq)]
pub enum EbpfError<E: UserDefinedError> {
#[error("{0}")]
UserError(#[from] E),
#[error("ELF error: {0}")]
ElfError(#[from] ElfError),
#[error("syscall #{0} was already registered before")]
SycallAlreadyRegistered(usize),
#[error("syscall #{0} was not registered before bind")]
SyscallNotRegistered(usize),
#[error("syscall #{0} already has a bound context object")]
SyscallAlreadyBound(usize),
#[error("exceeded max BPF to BPF call depth of {1} at instruction #{0}")]
CallDepthExceeded(usize, usize),
#[error("attempted to exit root call frame")]
ExitRootCallFrame,
#[error("divide by zero at instruction {0}")]
DivideByZero(usize),
#[error("attempted to execute past the end of the text segment at instruction #{0}")]
ExecutionOverrun(usize),
#[error(
"callx at instruction {0} attempted to call outside of the text segment to addr 0x{1:x}"
)]
CallOutsideTextSegment(usize, u64),
#[error("exceeded maximum number of instructions allowed ({1}) at instruction #{0}")]
ExceededMaxInstructions(usize, u64),
#[error("program has not been JIT-compiled")]
JitNotCompiled,
#[error("invalid virtual address {0:x?}")]
InvalidVirtualAddress(u64),
#[error("virtual address overlap {0:x?}")]
VirtualAddressOverlap(u64),
#[error("Access violation in {4} section at address {2:#x} of size {3:?} by instruction #{0}")]
AccessViolation(usize, AccessType, u64, u64, &'static str),
#[error(
"Access violation in stack frame {4} at address {2:#x} of size {3:?} by instruction #{0}"
)]
StackAccessViolation(usize, AccessType, u64, u64, i64),
#[error("invalid instruction at {0}")]
InvalidInstruction(usize),
#[error("unsupported instruction at instruction {0}")]
UnsupportedInstruction(usize),
#[error("Compilation exhaused text segment at instruction {0}")]
ExhausedTextSegment(usize),
}