summaryrefslogtreecommitdiff
path: root/drivers/android/binder/error.rs
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/android/binder/error.rs')
-rw-r--r--drivers/android/binder/error.rs39
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(),
}
}
}