projects/linux·blob master · refs

184 lines · 5.4 KiB

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