Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: GPL-2.0
2
3// Copyright (C) 2025 Google LLC.
4
5use core::mem::MaybeUninit;
6use core::ops::{Deref, DerefMut};
7use kernel::{
8 transmute::{AsBytes, FromBytes},
9 uapi::{self, *},
10};
11
12macro_rules! pub_no_prefix {
13 ($prefix:ident, $($newname:ident),+ $(,)?) => {
14 $(pub(crate) const $newname: u32 = kernel::macros::concat_idents!($prefix, $newname);)+
15 };
16}
17
18pub_no_prefix!(
19 binder_driver_return_protocol_,
20 BR_TRANSACTION,
21 BR_TRANSACTION_SEC_CTX,
22 BR_REPLY,
23 BR_DEAD_REPLY,
24 BR_FAILED_REPLY,
25 BR_FROZEN_REPLY,
26 BR_NOOP,
27 BR_SPAWN_LOOPER,
28 BR_TRANSACTION_COMPLETE,
29 BR_TRANSACTION_PENDING_FROZEN,
30 BR_ONEWAY_SPAM_SUSPECT,
31 BR_OK,
32 BR_ERROR,
33 BR_INCREFS,
34 BR_ACQUIRE,
35 BR_RELEASE,
36 BR_DECREFS,
37 BR_DEAD_BINDER,
38 BR_CLEAR_DEATH_NOTIFICATION_DONE,
39 BR_FROZEN_BINDER,
40 BR_CLEAR_FREEZE_NOTIFICATION_DONE,
41);
42
43pub_no_prefix!(
44 binder_driver_command_protocol_,
45 BC_TRANSACTION,
46 BC_TRANSACTION_SG,
47 BC_REPLY,
48 BC_REPLY_SG,
49 BC_FREE_BUFFER,
50 BC_ENTER_LOOPER,
51 BC_EXIT_LOOPER,
52 BC_REGISTER_LOOPER,
53 BC_INCREFS,
54 BC_ACQUIRE,
55 BC_RELEASE,
56 BC_DECREFS,
57 BC_INCREFS_DONE,
58 BC_ACQUIRE_DONE,
59 BC_REQUEST_DEATH_NOTIFICATION,
60 BC_CLEAR_DEATH_NOTIFICATION,
61 BC_DEAD_BINDER_DONE,
62 BC_REQUEST_FREEZE_NOTIFICATION,
63 BC_CLEAR_FREEZE_NOTIFICATION,
64 BC_FREEZE_NOTIFICATION_DONE,
65);
66
67pub_no_prefix!(
68 flat_binder_object_flags_,
69 FLAT_BINDER_FLAG_ACCEPTS_FDS,
70 FLAT_BINDER_FLAG_TXN_SECURITY_CTX
71);
72
73pub_no_prefix!(
74 transaction_flags_,
75 TF_ONE_WAY,
76 TF_ACCEPT_FDS,
77 TF_CLEAR_BUF,
78 TF_UPDATE_TXN
79);
80
81pub(crate) use uapi::{
82 BINDER_TYPE_BINDER, BINDER_TYPE_FD, BINDER_TYPE_FDA, BINDER_TYPE_HANDLE, BINDER_TYPE_PTR,
83 BINDER_TYPE_WEAK_BINDER, BINDER_TYPE_WEAK_HANDLE,
84};
85
86macro_rules! decl_wrapper {
87 ($newname:ident, $wrapped:ty) => {
88 // Define a wrapper around the C type. Use `MaybeUninit` to enforce that the value of
89 // padding bytes must be preserved.
90 #[derive(Copy, Clone)]
91 #[repr(transparent)]
92 pub(crate) struct $newname(MaybeUninit<$wrapped>);
93
94 // SAFETY: This macro is only used with types where this is ok.
95 unsafe impl FromBytes for $newname {}
96 // SAFETY: This macro is only used with types where this is ok.
97 unsafe impl AsBytes for $newname {}
98
99 impl Deref for $newname {
100 type Target = $wrapped;
101 fn deref(&self) -> &Self::Target {
102 // SAFETY: We use `MaybeUninit` only to preserve padding. The value must still
103 // always be valid.
104 unsafe { self.0.assume_init_ref() }
105 }
106 }
107
108 impl DerefMut for $newname {
109 fn deref_mut(&mut self) -> &mut Self::Target {
110 // SAFETY: We use `MaybeUninit` only to preserve padding. The value must still
111 // always be valid.
112 unsafe { self.0.assume_init_mut() }
113 }
114 }
115
116 impl Default for $newname {
117 fn default() -> Self {
118 // Create a new value of this type where all bytes (including padding) are zeroed.
119 Self(MaybeUninit::zeroed())
120 }
121 }
122 };
123}
124
125decl_wrapper!(BinderNodeDebugInfo, uapi::binder_node_debug_info);
126decl_wrapper!(BinderNodeInfoForRef, uapi::binder_node_info_for_ref);
127decl_wrapper!(FlatBinderObject, uapi::flat_binder_object);
128decl_wrapper!(BinderFdObject, uapi::binder_fd_object);
129decl_wrapper!(BinderFdArrayObject, uapi::binder_fd_array_object);
130decl_wrapper!(BinderObjectHeader, uapi::binder_object_header);
131decl_wrapper!(BinderBufferObject, uapi::binder_buffer_object);
132decl_wrapper!(BinderTransactionData, uapi::binder_transaction_data);
133decl_wrapper!(
134 BinderTransactionDataSecctx,
135 uapi::binder_transaction_data_secctx
136);
137decl_wrapper!(BinderTransactionDataSg, uapi::binder_transaction_data_sg);
138decl_wrapper!(BinderWriteRead, uapi::binder_write_read);
139decl_wrapper!(BinderVersion, uapi::binder_version);
140decl_wrapper!(BinderFrozenStatusInfo, uapi::binder_frozen_status_info);
141decl_wrapper!(BinderFreezeInfo, uapi::binder_freeze_info);
142decl_wrapper!(BinderFrozenStateInfo, uapi::binder_frozen_state_info);
143decl_wrapper!(BinderHandleCookie, uapi::binder_handle_cookie);
144decl_wrapper!(ExtendedError, uapi::binder_extended_error);
145
146impl BinderVersion {
147 pub(crate) fn current() -> Self {
148 Self(MaybeUninit::new(uapi::binder_version {
149 protocol_version: BINDER_CURRENT_PROTOCOL_VERSION as _,
150 }))
151 }
152}
153
154impl BinderTransactionData {
155 pub(crate) fn with_buffers_size(self, buffers_size: u64) -> BinderTransactionDataSg {
156 BinderTransactionDataSg(MaybeUninit::new(uapi::binder_transaction_data_sg {
157 transaction_data: *self,
158 buffers_size,
159 }))
160 }
161}
162
163impl BinderTransactionDataSecctx {
164 /// View the inner data as wrapped in `BinderTransactionData`.
165 pub(crate) fn tr_data(&mut self) -> &mut BinderTransactionData {
166 // SAFETY: Transparent wrapper is safe to transmute.
167 unsafe {
168 &mut *(&mut self.transaction_data as *mut uapi::binder_transaction_data
169 as *mut BinderTransactionData)
170 }
171 }
172}
173
174impl ExtendedError {
175 pub(crate) fn new(id: u32, command: u32, param: i32) -> Self {
176 Self(MaybeUninit::new(uapi::binder_extended_error {
177 id,
178 command,
179 param,
180 }))
181 }
182}