summaryrefslogtreecommitdiff
path: root/gbl/libgbl/src/error.rs
diff options
context:
space:
mode:
Diffstat (limited to 'gbl/libgbl/src/error.rs')
-rw-r--r--gbl/libgbl/src/error.rs144
1 files changed, 95 insertions, 49 deletions
diff --git a/gbl/libgbl/src/error.rs b/gbl/libgbl/src/error.rs
index 5855d50..b4aa1f6 100644
--- a/gbl/libgbl/src/error.rs
+++ b/gbl/libgbl/src/error.rs
@@ -14,16 +14,21 @@
//! Error types used in libgbl.
+use crate::GblOpsError;
use avb::{DescriptorError, SlotVerifyError};
use core::ffi::{FromBytesUntilNulError, FromBytesWithNulError};
use core::fmt::{Debug, Display, Formatter};
+use gbl_storage::StorageError;
/// Helper type GBL functions will return.
-pub type Result<T> = core::result::Result<T, Error>;
+pub type Result<T> = core::result::Result<T, IntegrationError>;
#[derive(Debug, PartialEq)]
-/// Error values that can be returned by function in this library
+/// Errors originating from GBL native logic.
pub enum Error {
+ ArithmeticOverflow,
+ /// Fail to hand off to kernel.
+ BootFailed,
/// Generic error
Error,
/// Missing all images required to boot system
@@ -37,73 +42,114 @@ pub enum Error {
/// AvbOps were already borrowed. This would happen on second `load_and_verify_image()` call
/// unless `reuse()` is called before.
AvbOpsBusy,
- /// Failed to get descriptor from AvbMeta
- AvbDescriptorError(DescriptorError),
- /// Avb slot verification failed.
- /// SlotVerifyError is used without verify data.
- AvbSlotVerifyError(SlotVerifyError<'static>),
}
-// Unfortunately thiserror is not available in `no_std` world.
-// Thus `Display` implementation is required.
impl Display for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
match self {
+ Error::ArithmeticOverflow => write!(f, "Arithmetic Overflow"),
+ Error::BootFailed => write!(f, "Failed to boot"),
Error::Error => write!(f, "Generic error"),
Error::MissingImage => write!(f, "Missing image required to boot system"),
Error::NotImplemented => write!(f, "Functionality is not implemented"),
Error::OperationProhibited => write!(f, "Operation is prohibited"),
Error::Internal => write!(f, "Internal error"),
Error::AvbOpsBusy => write!(f, "AvbOps were already borrowed"),
- Error::AvbDescriptorError(error) => {
- write!(f, "Failed to get descriptor from AvbMeta: {:?}", error)
- }
- Error::AvbSlotVerifyError(error) => {
- write!(f, "Avb slot verification failed: {}", error)
- }
}
}
}
-impl From<DescriptorError> for Error {
- fn from(value: DescriptorError) -> Self {
- Error::AvbDescriptorError(value)
- }
-}
-
-impl<'a> From<SlotVerifyError<'a>> for Error {
- fn from(value: SlotVerifyError<'a>) -> Self {
- Error::AvbSlotVerifyError(value.without_verify_data())
- }
-}
+/// A helper macro for declaring a composite enum type that simply wraps other types as entries.
+/// It auto-generate `From<...>` implementation for each entry type. The type for each entry must
+/// be different from each other. i.e.:
+///
+/// ```rust
+/// composite_enum! {
+/// pub enum MyEnum {
+/// Usize(usize),
+/// I64(i64),
+/// }
+/// }
+/// ```
+///
+/// expands to
+///
+/// ```rust
+/// pub enum MyEnum {
+/// Usize(usize),
+/// I64(i64),
+/// }
+///
+/// impl From<usize> for MyEnum {
+/// fn from(ent: usize) -> MyEnum {
+/// MyEnum::Usize(ent)
+/// }
+/// }
+///
+/// impl From<i64> for MyEnum {
+/// fn from(ent: i64) -> MyEnum {
+/// MyEnum::I64(ent)
+/// }
+/// }
+/// ```
+#[macro_export]
+macro_rules! composite_enum {
+ (
+ $(#[$outer:meta])*
+ $vis:vis enum $name:ident {
+ $(
+ $(#[$inner:ident $($args:tt)*])*
+ $ent:ident($ent_t:ty)
+ ),*
+ $(,)*
+ }
+ ) => {
+ // Copy over enum declaration as it is.
+ $(#[$outer])*
+ $vis enum $name {
+ $(
+ $(#[$inner $($args)*])*
+ $ent($ent_t)
+ ),*
+ }
-impl From<FromBytesUntilNulError> for Error {
- fn from(e: FromBytesUntilNulError) -> Self {
- Error::Internal
- }
+ // Generate `From<...>` implementation.
+ composite_enum!{$name, $($ent($ent_t)),*}
+ };
+ // `From<>` implementation generation. Base case.
+ ($name:ident, $ent:ident($ent_t:ty)) => {
+ impl From<$ent_t> for $name {
+ fn from(ent: $ent_t) -> $name {
+ $name::$ent(ent)
+ }
+ }
+ };
+ // `From<>` implementation generation. Recursive case.
+ ($name:ident, $ent:ident($ent_t:ty), $($next:ident($next_t:ty)),+) => {
+ composite_enum!{$name, $ent($ent_t)}
+ composite_enum!{$name, $($next($next_t)),*}
+ };
}
-impl From<FromBytesWithNulError> for Error {
- fn from(e: FromBytesWithNulError) -> Self {
- Error::Internal
+composite_enum! {
+ /// Top level error type that integrates errors from various dependency libraries.
+ #[derive(Debug)]
+ pub enum IntegrationError {
+ /// Failed to get descriptor from AvbMeta
+ AvbDescriptorError(DescriptorError),
+ /// Avb slot verification failed.
+ /// SlotVerifyError is used without verify data.
+ AvbSlotVerifyError(SlotVerifyError<'static>),
+ GblNativeError(Error),
+ GblOpsError(GblOpsError),
+ FromBytesUntilNulError(FromBytesUntilNulError),
+ FromBytesWithNulError(FromBytesWithNulError),
+ StorageError(StorageError),
}
}
-#[cfg(test)]
-mod tests {
- use crate::*;
- use avb::{DescriptorError, SlotVerifyError};
-
- #[test]
- fn test_error_output_formats() {
- assert_eq!("Generic error", format!("{}", Error::Error));
- assert_eq!(
- format!("Avb slot verification failed: {}", SlotVerifyError::Io),
- format!("{}", Error::AvbSlotVerifyError(SlotVerifyError::Io))
- );
- assert_eq!(
- format!("Failed to get descriptor from AvbMeta: {:?}", DescriptorError::InvalidValue),
- format!("{}", Error::AvbDescriptorError(DescriptorError::InvalidValue))
- );
+impl Display for IntegrationError {
+ fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
+ write!(f, "{:?}", self)
}
}