diff options
Diffstat (limited to 'drivers/android/binder/error.rs')
| -rw-r--r-- | drivers/android/binder/error.rs | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/drivers/android/binder/error.rs b/drivers/android/binder/error.rs index 1296072c35d9..41b07d687b30 100644 --- a/drivers/android/binder/error.rs +++ b/drivers/android/binder/error.rs @@ -2,6 +2,7 @@ // Copyright (C) 2025 Google LLC. +use core::panic::Location; use kernel::fmt; use kernel::prelude::*; @@ -9,32 +10,65 @@ use crate::defs::*; pub(crate) type BinderResult<T = ()> = core::result::Result<T, BinderError>; +/// Wraps a `&'static Location` to format it as `filename.rs:line` without the directory prefix. +#[derive(Copy, Clone)] +#[repr(transparent)] +pub(crate) struct ErrorLocation(&'static Location<'static>); + +// SAFETY: `ErrorLocation` is `repr(transparent)` over a shared reference, which is part of the +// option layout optimization guarantee, so all zeroes is a valid representation for `None`. +unsafe impl pin_init::ZeroableOption for ErrorLocation {} + +impl ErrorLocation { + #[track_caller] + pub(crate) const fn caller() -> Self { + Self(Location::caller()) + } +} + +impl fmt::Display for ErrorLocation { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let file = match self.0.file().rsplit_once('/') { + Some((_, file)) => file, + None => self.0.file(), + }; + write!(f, "{}:{}", file, self.0.line()) + } +} + /// An error that will be returned to userspace via the `BINDER_WRITE_READ` ioctl rather than via /// errno. pub(crate) struct BinderError { pub(crate) reply: u32, pub(crate) source: Option<Error>, + pub(crate) line: ErrorLocation, } impl BinderError { + #[track_caller] pub(crate) fn new_dead() -> Self { Self { reply: BR_DEAD_REPLY, source: None, + line: ErrorLocation::caller(), } } + #[track_caller] pub(crate) fn new_frozen() -> Self { Self { reply: BR_FROZEN_REPLY, source: None, + line: ErrorLocation::caller(), } } + #[track_caller] pub(crate) fn new_frozen_oneway() -> Self { Self { reply: BR_TRANSACTION_PENDING_FROZEN, source: None, + line: ErrorLocation::caller(), } } @@ -46,25 +80,30 @@ impl BinderError { /// Convert an errno into a `BinderError` and store the errno used to construct it. The errno /// should be stored as the thread's extended error when given to userspace. impl From<Error> for BinderError { + #[track_caller] fn from(source: Error) -> Self { Self { reply: BR_FAILED_REPLY, source: Some(source), + line: ErrorLocation::caller(), } } } impl From<kernel::fs::file::BadFdError> for BinderError { + #[track_caller] fn from(source: kernel::fs::file::BadFdError) -> Self { BinderError::from(Error::from(source)) } } impl From<kernel::alloc::AllocError> for BinderError { + #[track_caller] fn from(_: kernel::alloc::AllocError) -> Self { Self { reply: BR_FAILED_REPLY, source: Some(ENOMEM), + line: ErrorLocation::caller(), } } } |
