blob: 86769551d7406059be77065b9f94112cdf382252 [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"
18
Colin Cross9d45ccc2017-06-20 17:48:33 -070019#include <binder/ProcessState.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080020
21#include <utils/misc.h>
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <ctype.h>
26
27namespace android {
28
Steven Moreland5553ac42020-11-11 02:14:45 +000029std::string hexString(const void* bytes, size_t len) {
30 if (bytes == nullptr) return "<null>";
31
32 const uint8_t* bytes8 = static_cast<const uint8_t*>(bytes);
33 const char chars[] = "0123456789abcdef";
34 std::string result;
35 result.resize(len * 2);
36
37 for (size_t i = 0; i < len; i++) {
38 result[2 * i] = chars[bytes8[i] >> 4];
39 result[2 * i + 1] = chars[bytes8[i] & 0xf];
40 }
41
42 return result;
43}
44
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080045// ---------------------------------------------------------------------
46
47static const char indentStr[] =
48" "
49" ";
50
51const char* stringForIndent(int32_t indentLevel)
52{
53 ssize_t off = sizeof(indentStr)-1-(indentLevel*2);
54 return indentStr + (off < 0 ? 0 : off);
55}
56
57// ---------------------------------------------------------------------
58
Colin Cross6f4f3ab2014-02-05 17:42:44 -080059static void defaultPrintFunc(void* /*cookie*/, const char* txt)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080060{
61 printf("%s", txt);
62}
63
64// ---------------------------------------------------------------------
65
66static inline int isident(int c)
67{
68 return isalnum(c) || c == '_';
69}
70
71static inline bool isasciitype(char c)
72{
73 if( c >= ' ' && c < 127 && c != '\'' && c != '\\' ) return true;
74 return false;
75}
76
77static inline char makehexdigit(uint32_t val)
78{
79 return "0123456789abcdef"[val&0xF];
80}
81
82static char* appendhexnum(uint32_t val, char* out)
83{
84 for( int32_t i=28; i>=0; i-=4 ) {
85 *out++ = makehexdigit( val>>i );
86 }
87 *out = 0;
88 return out;
89}
90
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080091static char* appendcharornum(char c, char* out, bool skipzero = true)
92{
93 if (skipzero && c == 0) return out;
94
95 if (isasciitype(c)) {
96 *out++ = c;
97 return out;
98 }
99
100 *out++ = '\\';
101 *out++ = 'x';
102 *out++ = makehexdigit(c>>4);
103 *out++ = makehexdigit(c);
104 return out;
105}
106
107static char* typetostring(uint32_t type, char* out,
108 bool fullContext = true,
109 bool strict = false)
110{
111 char* pos = out;
112 char c[4];
113 c[0] = (char)((type>>24)&0xFF);
114 c[1] = (char)((type>>16)&0xFF);
115 c[2] = (char)((type>>8)&0xFF);
116 c[3] = (char)(type&0xFF);
117 bool valid;
118 if( !strict ) {
119 // now even less strict!
120 // valid = isasciitype(c[3]);
121 valid = true;
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 (!isasciitype(c[i])) valid = false;
130 }
131 i++;
132 }
133 // if all zeros, not a valid type code.
134 if (zero) valid = false;
135 } else {
136 valid = isident(c[3]) ? true : false;
137 int32_t i = 0;
138 bool zero = true;
139 while (valid && i<3) {
140 if (c[i] == 0) {
141 if (!zero) valid = false;
142 } else {
143 zero = false;
144 if (!isident(c[i])) valid = false;
145 }
146 i++;
147 }
148 }
149 if( valid && (!fullContext || c[0] != '0' || c[1] != 'x') ) {
150 if( fullContext ) *pos++ = '\'';
151 pos = appendcharornum(c[0], pos);
152 pos = appendcharornum(c[1], pos);
153 pos = appendcharornum(c[2], pos);
154 pos = appendcharornum(c[3], pos);
155 if( fullContext ) *pos++ = '\'';
156 *pos = 0;
157 return pos;
158 }
Dan Austinc2bf8e82015-10-21 11:28:59 -0700159
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800160 if( fullContext ) {
161 *pos++ = '0';
162 *pos++ = 'x';
163 }
164 return appendhexnum(type, pos);
165}
166
167void printTypeCode(uint32_t typeCode, debugPrintFunc func, void* cookie)
168{
169 char buffer[32];
170 char* end = typetostring(typeCode, buffer);
171 *end = 0;
172 func ? (*func)(cookie, buffer) : defaultPrintFunc(cookie, buffer);
173}
174
175void printHexData(int32_t indent, const void *buf, size_t length,
176 size_t bytesPerLine, int32_t singleLineBytesCutoff,
177 size_t alignment, bool cStyle,
178 debugPrintFunc func, void* cookie)
179{
180 if (alignment == 0) {
181 if (bytesPerLine >= 16) alignment = 4;
182 else if (bytesPerLine >= 8) alignment = 2;
183 else alignment = 1;
184 }
Yi Kongfdd8da92018-06-07 17:52:27 -0700185 if (func == nullptr) func = defaultPrintFunc;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800186
187 size_t offset;
Dan Austinc2bf8e82015-10-21 11:28:59 -0700188
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800189 unsigned char *pos = (unsigned char *)buf;
Dan Austinc2bf8e82015-10-21 11:28:59 -0700190
Yi Kongfdd8da92018-06-07 17:52:27 -0700191 if (pos == nullptr) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800192 if (singleLineBytesCutoff < 0) func(cookie, "\n");
193 func(cookie, "(NULL)");
194 return;
195 }
Dan Austinc2bf8e82015-10-21 11:28:59 -0700196
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800197 if (length == 0) {
198 if (singleLineBytesCutoff < 0) func(cookie, "\n");
199 func(cookie, "(empty)");
200 return;
201 }
Dan Austinc2bf8e82015-10-21 11:28:59 -0700202
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800203 if ((int32_t)length < 0) {
204 if (singleLineBytesCutoff < 0) func(cookie, "\n");
205 char buf[64];
Andrew Hsieh0ae8c142012-02-27 18:50:55 -0800206 sprintf(buf, "(bad length: %zu)", length);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800207 func(cookie, buf);
208 return;
209 }
Dan Austinc2bf8e82015-10-21 11:28:59 -0700210
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800211 char buffer[256];
212 static const size_t maxBytesPerLine = (sizeof(buffer)-1-11-4)/(3+1);
Dan Austinc2bf8e82015-10-21 11:28:59 -0700213
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800214 if (bytesPerLine > maxBytesPerLine) bytesPerLine = maxBytesPerLine;
Dan Austinc2bf8e82015-10-21 11:28:59 -0700215
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800216 const bool oneLine = (int32_t)length <= singleLineBytesCutoff;
217 bool newLine = false;
218 if (cStyle) {
219 indent++;
220 func(cookie, "{\n");
221 newLine = true;
222 } else if (!oneLine) {
223 func(cookie, "\n");
224 newLine = true;
225 }
Dan Austinc2bf8e82015-10-21 11:28:59 -0700226
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800227 for (offset = 0; ; offset += bytesPerLine, pos += bytesPerLine) {
Vishnu Naircda5a2b2020-11-18 17:11:49 -0800228 ssize_t remain = length;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800229
230 char* c = buffer;
231 if (!oneLine && !cStyle) {
232 sprintf(c, "0x%08x: ", (int)offset);
233 c += 12;
234 }
235
236 size_t index;
237 size_t word;
Dan Austinc2bf8e82015-10-21 11:28:59 -0700238
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800239 for (word = 0; word < bytesPerLine; ) {
240
Martijn Coenend40633b2017-05-08 09:24:15 -0700241 size_t align_offset = alignment-(alignment?1:0);
242 if (remain > 0 && (size_t)remain <= align_offset) {
243 align_offset = remain - 1;
244 }
245 const size_t startIndex = word+align_offset;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800246
247 for (index = 0; index < alignment || (alignment == 0 && index < bytesPerLine); index++) {
Dan Austinc2bf8e82015-10-21 11:28:59 -0700248
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800249 if (!cStyle) {
250 if (index == 0 && word > 0 && alignment > 0) {
251 *c++ = ' ';
252 }
Dan Austinc2bf8e82015-10-21 11:28:59 -0700253
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800254 if (remain-- > 0) {
Dan Austinc2bf8e82015-10-21 11:28:59 -0700255 const unsigned char val = *(pos+startIndex-index);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800256 *c++ = makehexdigit(val>>4);
257 *c++ = makehexdigit(val);
258 } else if (!oneLine) {
259 *c++ = ' ';
260 *c++ = ' ';
261 }
262 } else {
263 if (remain > 0) {
264 if (index == 0 && word > 0) {
265 *c++ = ',';
266 *c++ = ' ';
267 }
268 if (index == 0) {
269 *c++ = '0';
270 *c++ = 'x';
271 }
Dan Austinc2bf8e82015-10-21 11:28:59 -0700272 const unsigned char val = *(pos+startIndex-index);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800273 *c++ = makehexdigit(val>>4);
274 *c++ = makehexdigit(val);
275 remain--;
276 }
277 }
278 }
Dan Austinc2bf8e82015-10-21 11:28:59 -0700279
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800280 word += index;
281 }
282
283 if (!cStyle) {
284 remain = length;
285 *c++ = ' ';
286 *c++ = '\'';
287 for (index = 0; index < bytesPerLine; index++) {
288
289 if (remain-- > 0) {
290 const unsigned char val = pos[index];
291 *c++ = (val >= ' ' && val < 127) ? val : '.';
292 } else if (!oneLine) {
293 *c++ = ' ';
294 }
295 }
Dan Austinc2bf8e82015-10-21 11:28:59 -0700296
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800297 *c++ = '\'';
298 if (length > bytesPerLine) *c++ = '\n';
299 } else {
300 if (remain > 0) *c++ = ',';
301 *c++ = '\n';
302 }
303
304 if (newLine && indent) func(cookie, stringForIndent(indent));
305 *c = 0;
306 func(cookie, buffer);
307 newLine = true;
Dan Austinc2bf8e82015-10-21 11:28:59 -0700308
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800309 if (length <= bytesPerLine) break;
310 length -= bytesPerLine;
311 }
312
313 if (cStyle) {
314 if (indent > 0) func(cookie, stringForIndent(indent-1));
315 func(cookie, "};");
316 }
317}
318
Colin Cross9d45ccc2017-06-20 17:48:33 -0700319ssize_t getBinderKernelReferences(size_t count, uintptr_t* buf) {
320 sp<ProcessState> proc = ProcessState::selfOrNull();
Yi Kongfdd8da92018-06-07 17:52:27 -0700321 if (proc.get() == nullptr) {
Colin Cross9d45ccc2017-06-20 17:48:33 -0700322 return 0;
323 }
324
325 return proc->getKernelReferences(count, buf);
326}
327
Steven Moreland61ff8492019-09-26 16:05:45 -0700328} // namespace android
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800329