xref: /linux/drivers/android/binder/trace.rs (revision cb4eb6771c0f8fd1c52a8f6fdec7762fb087380a)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 // Copyright (C) 2025 Google LLC.
4 
5 use crate::transaction::Transaction;
6 
7 use kernel::bindings::{rust_binder_transaction, task_struct};
8 use kernel::error::Result;
9 use kernel::ffi::{c_int, c_uint, c_ulong};
10 use kernel::task::Task;
11 use kernel::tracepoint::declare_trace;
12 
13 declare_trace! {
14     unsafe fn binder_ioctl(cmd: c_uint, arg: c_ulong);
15     unsafe fn binder_ioctl_done(ret: c_int);
16     unsafe fn binder_read_done(ret: c_int);
17     unsafe fn binder_write_done(ret: c_int);
18     unsafe fn binder_wait_for_work(proc_work: bool, transaction_stack: bool, thread_todo: bool);
19     unsafe fn binder_transaction(reply: bool, t: rust_binder_transaction, thread: *mut task_struct);
20     unsafe fn binder_transaction_received(t: rust_binder_transaction);
21     unsafe fn binder_transaction_fd_send(t_debug_id: c_int, fd: c_int, offset: usize);
22     unsafe fn binder_transaction_fd_recv(t_debug_id: c_int, fd: c_int, offset: usize);
23     unsafe fn binder_command(cmd: u32);
24     unsafe fn binder_return(ret: u32);
25 }
26 
27 #[inline]
raw_transaction(t: &Transaction) -> rust_binder_transaction28 fn raw_transaction(t: &Transaction) -> rust_binder_transaction {
29     t as *const Transaction as rust_binder_transaction
30 }
31 
32 #[inline]
to_errno(ret: Result) -> i3233 fn to_errno(ret: Result) -> i32 {
34     match ret {
35         Ok(()) => 0,
36         Err(err) => err.to_errno(),
37     }
38 }
39 
40 #[inline]
trace_ioctl(cmd: u32, arg: usize)41 pub(crate) fn trace_ioctl(cmd: u32, arg: usize) {
42     // SAFETY: Always safe to call.
43     unsafe { binder_ioctl(cmd, arg as c_ulong) }
44 }
45 
46 #[inline]
trace_ioctl_done(ret: Result)47 pub(crate) fn trace_ioctl_done(ret: Result) {
48     // SAFETY: Always safe to call.
49     unsafe { binder_ioctl_done(to_errno(ret)) }
50 }
51 #[inline]
trace_read_done(ret: Result)52 pub(crate) fn trace_read_done(ret: Result) {
53     // SAFETY: Always safe to call.
54     unsafe { binder_read_done(to_errno(ret)) }
55 }
56 #[inline]
trace_write_done(ret: Result)57 pub(crate) fn trace_write_done(ret: Result) {
58     // SAFETY: Always safe to call.
59     unsafe { binder_write_done(to_errno(ret)) }
60 }
61 
62 #[inline]
trace_wait_for_work(proc_work: bool, transaction_stack: bool, thread_todo: bool)63 pub(crate) fn trace_wait_for_work(proc_work: bool, transaction_stack: bool, thread_todo: bool) {
64     // SAFETY: Always safe to call.
65     unsafe { binder_wait_for_work(proc_work, transaction_stack, thread_todo) }
66 }
67 
68 #[inline]
trace_transaction(reply: bool, t: &Transaction, thread: Option<&Task>)69 pub(crate) fn trace_transaction(reply: bool, t: &Transaction, thread: Option<&Task>) {
70     let thread = match thread {
71         Some(thread) => thread.as_ptr(),
72         None => core::ptr::null_mut(),
73     };
74     // SAFETY: The raw transaction is valid for the duration of this call. The thread pointer is
75     // valid or null.
76     unsafe { binder_transaction(reply, raw_transaction(t), thread) }
77 }
78 
79 #[inline]
trace_transaction_received(t: &Transaction)80 pub(crate) fn trace_transaction_received(t: &Transaction) {
81     // SAFETY: The raw transaction is valid for the duration of this call.
82     unsafe { binder_transaction_received(raw_transaction(t)) }
83 }
84 
85 #[inline]
trace_transaction_fd_send(t_debug_id: usize, fd: u32, offset: usize)86 pub(crate) fn trace_transaction_fd_send(t_debug_id: usize, fd: u32, offset: usize) {
87     // SAFETY: This function is always safe to call.
88     unsafe { binder_transaction_fd_send(t_debug_id as c_int, fd as c_int, offset) }
89 }
90 #[inline]
trace_transaction_fd_recv(t_debug_id: usize, fd: u32, offset: usize)91 pub(crate) fn trace_transaction_fd_recv(t_debug_id: usize, fd: u32, offset: usize) {
92     // SAFETY: This function is always safe to call.
93     unsafe { binder_transaction_fd_recv(t_debug_id as c_int, fd as c_int, offset) }
94 }
95 
96 #[inline]
trace_command(cmd: u32)97 pub(crate) fn trace_command(cmd: u32) {
98     // SAFETY: This function is always safe to call.
99     unsafe { binder_command(cmd) }
100 }
101 #[inline]
trace_return(ret: u32)102 pub(crate) fn trace_return(ret: u32) {
103     // SAFETY: This function is always safe to call.
104     unsafe { binder_return(ret) }
105 }
106