blob: c6e4fb378d118fbbf72c7e5bfb794dbd8f9b7e34 [file] [log] [blame]
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2005 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Steven Morelandaaff3252021-03-06 00:26:09 +000017#include "Debug.h"
Steven Moreland32150282021-11-12 22:54:53 +000018#include "BuildFlags.h"
Steven Morelandaaff3252021-03-06 00:26:09 +000019
Colin Cross9d45ccc2017-06-20 17:48:33 -070020#include <binder/ProcessState.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080021
22#include <utils/misc.h>
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <ctype.h>
27
28namespace android {
29
30// ---------------------------------------------------------------------
31
32static const char indentStr[] =
33" "
34" ";
35
36const char* stringForIndent(int32_t indentLevel)
37{
38 ssize_t off = sizeof(indentStr)-1-(indentLevel*2);
39 return indentStr + (off < 0 ? 0 : off);
40}
41
42// ---------------------------------------------------------------------
43
Colin Cross6f4f3ab2014-02-05 17:42:44 -080044static void defaultPrintFunc(void* /*cookie*/, const char* txt)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080045{
46 printf("%s", txt);
47}
48
49// ---------------------------------------------------------------------
50
51static inline int isident(int c)
52{
53 return isalnum(c) || c == '_';
54}
55
56static inline bool isasciitype(char c)
57{
58 if( c >= ' ' && c < 127 && c != '\'' && c != '\\' ) return true;
59 return false;
60}
61
62static inline char makehexdigit(uint32_t val)
63{
64 return "0123456789abcdef"[val&0xF];
65}
66
67static char* appendhexnum(uint32_t val, char* out)
68{
69 for( int32_t i=28; i>=0; i-=4 ) {
70 *out++ = makehexdigit( val>>i );
71 }
72 *out = 0;
73 return out;
74}
75
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080076static char* appendcharornum(char c, char* out, bool skipzero = true)
77{
78 if (skipzero && c == 0) return out;
79
80 if (isasciitype(c)) {
81 *out++ = c;
82 return out;
83 }
84
85 *out++ = '\\';
86 *out++ = 'x';
87 *out++ = makehexdigit(c>>4);
88 *out++ = makehexdigit(c);
89 return out;
90}
91
92static char* typetostring(uint32_t type, char* out,
93 bool fullContext = true,
94 bool strict = false)
95{
96 char* pos = out;
97 char c[4];
98 c[0] = (char)((type>>24)&0xFF);
99 c[1] = (char)((type>>16)&0xFF);
100 c[2] = (char)((type>>8)&0xFF);
101 c[3] = (char)(type&0xFF);
102 bool valid;
103 if( !strict ) {
104 // now even less strict!
105 // valid = isasciitype(c[3]);
106 valid = true;
107 int32_t i = 0;
108 bool zero = true;
109 while (valid && i<3) {
110 if (c[i] == 0) {
111 if (!zero) valid = false;
112 } else {
113 zero = false;
114 //if (!isasciitype(c[i])) valid = false;
115 }
116 i++;
117 }
118 // if all zeros, not a valid type code.
119 if (zero) valid = false;
120 } else {
121 valid = isident(c[3]) ? true : false;
122 int32_t i = 0;
123 bool zero = true;
124 while (valid && i<3) {
125 if (c[i] == 0) {
126 if (!zero) valid = false;
127 } else {
128 zero = false;
129 if (!isident(c[i])) valid = false;
130 }
131 i++;
132 }
133 }
134 if( valid && (!fullContext || c[0] != '0' || c[1] != 'x') ) {
135 if( fullContext ) *pos++ = '\'';
136 pos = appendcharornum(c[0], pos);
137 pos = appendcharornum(c[1], pos);
138 pos = appendcharornum(c[2], pos);
139 pos = appendcharornum(c[3], pos);
140 if( fullContext ) *pos++ = '\'';
141 *pos = 0;
142 return pos;
143 }
Dan Austinc2bf8e82015-10-21 11:28:59 -0700144
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800145 if( fullContext ) {
146 *pos++ = '0';
147 *pos++ = 'x';
148 }
149 return appendhexnum(type, pos);
150}
151
152void printTypeCode(uint32_t typeCode, debugPrintFunc func, void* cookie)
153{
154 char buffer[32];
155 char* end = typetostring(typeCode, buffer);
156 *end = 0;
157 func ? (*func)(cookie, buffer) : defaultPrintFunc(cookie, buffer);
158}
159
160void printHexData(int32_t indent, const void *buf, size_t length,
161 size_t bytesPerLine, int32_t singleLineBytesCutoff,
162 size_t alignment, bool cStyle,
163 debugPrintFunc func, void* cookie)
164{
165 if (alignment == 0) {
166 if (bytesPerLine >= 16) alignment = 4;
167 else if (bytesPerLine >= 8) alignment = 2;
168 else alignment = 1;
169 }
Yi Kongfdd8da92018-06-07 17:52:27 -0700170 if (func == nullptr) func = defaultPrintFunc;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800171
172 size_t offset;
Dan Austinc2bf8e82015-10-21 11:28:59 -0700173
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800174 unsigned char *pos = (unsigned char *)buf;
Dan Austinc2bf8e82015-10-21 11:28:59 -0700175
Yi Kongfdd8da92018-06-07 17:52:27 -0700176 if (pos == nullptr) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800177 if (singleLineBytesCutoff < 0) func(cookie, "\n");
178 func(cookie, "(NULL)");
179 return;
180 }
Dan Austinc2bf8e82015-10-21 11:28:59 -0700181
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800182 if (length == 0) {
183 if (singleLineBytesCutoff < 0) func(cookie, "\n");
184 func(cookie, "(empty)");
185 return;
186 }
Dan Austinc2bf8e82015-10-21 11:28:59 -0700187
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800188 if ((int32_t)length < 0) {
189 if (singleLineBytesCutoff < 0) func(cookie, "\n");
190 char buf[64];
Andrew Hsieh0ae8c142012-02-27 18:50:55 -0800191 sprintf(buf, "(bad length: %zu)", length);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800192 func(cookie, buf);
193 return;
194 }
Dan Austinc2bf8e82015-10-21 11:28:59 -0700195
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800196 char buffer[256];
197 static const size_t maxBytesPerLine = (sizeof(buffer)-1-11-4)/(3+1);
Dan Austinc2bf8e82015-10-21 11:28:59 -0700198
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800199 if (bytesPerLine > maxBytesPerLine) bytesPerLine = maxBytesPerLine;
Dan Austinc2bf8e82015-10-21 11:28:59 -0700200
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800201 const bool oneLine = (int32_t)length <= singleLineBytesCutoff;
202 bool newLine = false;
203 if (cStyle) {
204 indent++;
205 func(cookie, "{\n");
206 newLine = true;
207 } else if (!oneLine) {
208 func(cookie, "\n");
209 newLine = true;
210 }
Dan Austinc2bf8e82015-10-21 11:28:59 -0700211
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800212 for (offset = 0; ; offset += bytesPerLine, pos += bytesPerLine) {
Vishnu Naircda5a2b2020-11-18 17:11:49 -0800213 ssize_t remain = length;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800214
215 char* c = buffer;
216 if (!oneLine && !cStyle) {
217 sprintf(c, "0x%08x: ", (int)offset);
218 c += 12;
219 }
220
221 size_t index;
222 size_t word;
Dan Austinc2bf8e82015-10-21 11:28:59 -0700223
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800224 for (word = 0; word < bytesPerLine; ) {
225
Martijn Coenend40633b2017-05-08 09:24:15 -0700226 size_t align_offset = alignment-(alignment?1:0);
227 if (remain > 0 && (size_t)remain <= align_offset) {
228 align_offset = remain - 1;
229 }
230 const size_t startIndex = word+align_offset;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800231
232 for (index = 0; index < alignment || (alignment == 0 && index < bytesPerLine); index++) {
Dan Austinc2bf8e82015-10-21 11:28:59 -0700233
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800234 if (!cStyle) {
235 if (index == 0 && word > 0 && alignment > 0) {
236 *c++ = ' ';
237 }
Dan Austinc2bf8e82015-10-21 11:28:59 -0700238
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800239 if (remain-- > 0) {
Dan Austinc2bf8e82015-10-21 11:28:59 -0700240 const unsigned char val = *(pos+startIndex-index);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800241 *c++ = makehexdigit(val>>4);
242 *c++ = makehexdigit(val);
243 } else if (!oneLine) {
244 *c++ = ' ';
245 *c++ = ' ';
246 }
247 } else {
248 if (remain > 0) {
249 if (index == 0 && word > 0) {
250 *c++ = ',';
251 *c++ = ' ';
252 }
253 if (index == 0) {
254 *c++ = '0';
255 *c++ = 'x';
256 }
Dan Austinc2bf8e82015-10-21 11:28:59 -0700257 const unsigned char val = *(pos+startIndex-index);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800258 *c++ = makehexdigit(val>>4);
259 *c++ = makehexdigit(val);
260 remain--;
261 }
262 }
263 }
Dan Austinc2bf8e82015-10-21 11:28:59 -0700264
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800265 word += index;
266 }
267
268 if (!cStyle) {
269 remain = length;
270 *c++ = ' ';
271 *c++ = '\'';
272 for (index = 0; index < bytesPerLine; index++) {
273
274 if (remain-- > 0) {
275 const unsigned char val = pos[index];
276 *c++ = (val >= ' ' && val < 127) ? val : '.';
277 } else if (!oneLine) {
278 *c++ = ' ';
279 }
280 }
Dan Austinc2bf8e82015-10-21 11:28:59 -0700281
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800282 *c++ = '\'';
283 if (length > bytesPerLine) *c++ = '\n';
284 } else {
285 if (remain > 0) *c++ = ',';
286 *c++ = '\n';
287 }
288
289 if (newLine && indent) func(cookie, stringForIndent(indent));
290 *c = 0;
291 func(cookie, buffer);
292 newLine = true;
Dan Austinc2bf8e82015-10-21 11:28:59 -0700293
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800294 if (length <= bytesPerLine) break;
295 length -= bytesPerLine;
296 }
297
298 if (cStyle) {
299 if (indent > 0) func(cookie, stringForIndent(indent-1));
300 func(cookie, "};");
301 }
302}
303
Colin Cross9d45ccc2017-06-20 17:48:33 -0700304ssize_t getBinderKernelReferences(size_t count, uintptr_t* buf) {
Steven Moreland32150282021-11-12 22:54:53 +0000305 if constexpr (!kEnableKernelIpc) {
306 LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time");
307 return 0;
308 }
309
Colin Cross9d45ccc2017-06-20 17:48:33 -0700310 sp<ProcessState> proc = ProcessState::selfOrNull();
Yi Kongfdd8da92018-06-07 17:52:27 -0700311 if (proc.get() == nullptr) {
Colin Cross9d45ccc2017-06-20 17:48:33 -0700312 return 0;
313 }
314
315 return proc->getKernelReferences(count, buf);
316}
317
Steven Moreland61ff8492019-09-26 16:05:45 -0700318} // namespace android
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800319