blob: 64c1ff68c0dc14299862aa1f5405c8074bb0dc92 [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
Mathias Agopian002e1e52013-05-06 20:20:50 -070017#include <binder/Debug.h>
Colin Cross9d45ccc2017-06-20 17:48:33 -070018#include <binder/ProcessState.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080019
20#include <utils/misc.h>
21
22#include <stdio.h>
23#include <stdlib.h>
24#include <ctype.h>
25
26namespace android {
27
28// ---------------------------------------------------------------------
29
30static const char indentStr[] =
31" "
32" ";
33
34const char* stringForIndent(int32_t indentLevel)
35{
36 ssize_t off = sizeof(indentStr)-1-(indentLevel*2);
37 return indentStr + (off < 0 ? 0 : off);
38}
39
40// ---------------------------------------------------------------------
41
Colin Cross6f4f3ab2014-02-05 17:42:44 -080042static void defaultPrintFunc(void* /*cookie*/, const char* txt)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080043{
44 printf("%s", txt);
45}
46
47// ---------------------------------------------------------------------
48
49static inline int isident(int c)
50{
51 return isalnum(c) || c == '_';
52}
53
54static inline bool isasciitype(char c)
55{
56 if( c >= ' ' && c < 127 && c != '\'' && c != '\\' ) return true;
57 return false;
58}
59
60static inline char makehexdigit(uint32_t val)
61{
62 return "0123456789abcdef"[val&0xF];
63}
64
65static char* appendhexnum(uint32_t val, char* out)
66{
67 for( int32_t i=28; i>=0; i-=4 ) {
68 *out++ = makehexdigit( val>>i );
69 }
70 *out = 0;
71 return out;
72}
73
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080074static char* appendcharornum(char c, char* out, bool skipzero = true)
75{
76 if (skipzero && c == 0) return out;
77
78 if (isasciitype(c)) {
79 *out++ = c;
80 return out;
81 }
82
83 *out++ = '\\';
84 *out++ = 'x';
85 *out++ = makehexdigit(c>>4);
86 *out++ = makehexdigit(c);
87 return out;
88}
89
90static char* typetostring(uint32_t type, char* out,
91 bool fullContext = true,
92 bool strict = false)
93{
94 char* pos = out;
95 char c[4];
96 c[0] = (char)((type>>24)&0xFF);
97 c[1] = (char)((type>>16)&0xFF);
98 c[2] = (char)((type>>8)&0xFF);
99 c[3] = (char)(type&0xFF);
100 bool valid;
101 if( !strict ) {
102 // now even less strict!
103 // valid = isasciitype(c[3]);
104 valid = true;
105 int32_t i = 0;
106 bool zero = true;
107 while (valid && i<3) {
108 if (c[i] == 0) {
109 if (!zero) valid = false;
110 } else {
111 zero = false;
112 //if (!isasciitype(c[i])) valid = false;
113 }
114 i++;
115 }
116 // if all zeros, not a valid type code.
117 if (zero) valid = false;
118 } else {
119 valid = isident(c[3]) ? true : false;
120 int32_t i = 0;
121 bool zero = true;
122 while (valid && i<3) {
123 if (c[i] == 0) {
124 if (!zero) valid = false;
125 } else {
126 zero = false;
127 if (!isident(c[i])) valid = false;
128 }
129 i++;
130 }
131 }
132 if( valid && (!fullContext || c[0] != '0' || c[1] != 'x') ) {
133 if( fullContext ) *pos++ = '\'';
134 pos = appendcharornum(c[0], pos);
135 pos = appendcharornum(c[1], pos);
136 pos = appendcharornum(c[2], pos);
137 pos = appendcharornum(c[3], pos);
138 if( fullContext ) *pos++ = '\'';
139 *pos = 0;
140 return pos;
141 }
Dan Austinc2bf8e82015-10-21 11:28:59 -0700142
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800143 if( fullContext ) {
144 *pos++ = '0';
145 *pos++ = 'x';
146 }
147 return appendhexnum(type, pos);
148}
149
150void printTypeCode(uint32_t typeCode, debugPrintFunc func, void* cookie)
151{
152 char buffer[32];
153 char* end = typetostring(typeCode, buffer);
154 *end = 0;
155 func ? (*func)(cookie, buffer) : defaultPrintFunc(cookie, buffer);
156}
157
158void printHexData(int32_t indent, const void *buf, size_t length,
159 size_t bytesPerLine, int32_t singleLineBytesCutoff,
160 size_t alignment, bool cStyle,
161 debugPrintFunc func, void* cookie)
162{
163 if (alignment == 0) {
164 if (bytesPerLine >= 16) alignment = 4;
165 else if (bytesPerLine >= 8) alignment = 2;
166 else alignment = 1;
167 }
Yi Kongfdd8da92018-06-07 17:52:27 -0700168 if (func == nullptr) func = defaultPrintFunc;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800169
170 size_t offset;
Dan Austinc2bf8e82015-10-21 11:28:59 -0700171
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800172 unsigned char *pos = (unsigned char *)buf;
Dan Austinc2bf8e82015-10-21 11:28:59 -0700173
Yi Kongfdd8da92018-06-07 17:52:27 -0700174 if (pos == nullptr) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800175 if (singleLineBytesCutoff < 0) func(cookie, "\n");
176 func(cookie, "(NULL)");
177 return;
178 }
Dan Austinc2bf8e82015-10-21 11:28:59 -0700179
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800180 if (length == 0) {
181 if (singleLineBytesCutoff < 0) func(cookie, "\n");
182 func(cookie, "(empty)");
183 return;
184 }
Dan Austinc2bf8e82015-10-21 11:28:59 -0700185
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800186 if ((int32_t)length < 0) {
187 if (singleLineBytesCutoff < 0) func(cookie, "\n");
188 char buf[64];
Andrew Hsieh0ae8c142012-02-27 18:50:55 -0800189 sprintf(buf, "(bad length: %zu)", length);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800190 func(cookie, buf);
191 return;
192 }
Dan Austinc2bf8e82015-10-21 11:28:59 -0700193
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800194 char buffer[256];
195 static const size_t maxBytesPerLine = (sizeof(buffer)-1-11-4)/(3+1);
Dan Austinc2bf8e82015-10-21 11:28:59 -0700196
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800197 if (bytesPerLine > maxBytesPerLine) bytesPerLine = maxBytesPerLine;
Dan Austinc2bf8e82015-10-21 11:28:59 -0700198
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800199 const bool oneLine = (int32_t)length <= singleLineBytesCutoff;
200 bool newLine = false;
201 if (cStyle) {
202 indent++;
203 func(cookie, "{\n");
204 newLine = true;
205 } else if (!oneLine) {
206 func(cookie, "\n");
207 newLine = true;
208 }
Dan Austinc2bf8e82015-10-21 11:28:59 -0700209
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800210 for (offset = 0; ; offset += bytesPerLine, pos += bytesPerLine) {
211 long remain = length;
212
213 char* c = buffer;
214 if (!oneLine && !cStyle) {
215 sprintf(c, "0x%08x: ", (int)offset);
216 c += 12;
217 }
218
219 size_t index;
220 size_t word;
Dan Austinc2bf8e82015-10-21 11:28:59 -0700221
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800222 for (word = 0; word < bytesPerLine; ) {
223
Martijn Coenend40633b2017-05-08 09:24:15 -0700224 size_t align_offset = alignment-(alignment?1:0);
225 if (remain > 0 && (size_t)remain <= align_offset) {
226 align_offset = remain - 1;
227 }
228 const size_t startIndex = word+align_offset;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800229
230 for (index = 0; index < alignment || (alignment == 0 && index < bytesPerLine); index++) {
Dan Austinc2bf8e82015-10-21 11:28:59 -0700231
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800232 if (!cStyle) {
233 if (index == 0 && word > 0 && alignment > 0) {
234 *c++ = ' ';
235 }
Dan Austinc2bf8e82015-10-21 11:28:59 -0700236
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800237 if (remain-- > 0) {
Dan Austinc2bf8e82015-10-21 11:28:59 -0700238 const unsigned char val = *(pos+startIndex-index);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800239 *c++ = makehexdigit(val>>4);
240 *c++ = makehexdigit(val);
241 } else if (!oneLine) {
242 *c++ = ' ';
243 *c++ = ' ';
244 }
245 } else {
246 if (remain > 0) {
247 if (index == 0 && word > 0) {
248 *c++ = ',';
249 *c++ = ' ';
250 }
251 if (index == 0) {
252 *c++ = '0';
253 *c++ = 'x';
254 }
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 remain--;
259 }
260 }
261 }
Dan Austinc2bf8e82015-10-21 11:28:59 -0700262
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800263 word += index;
264 }
265
266 if (!cStyle) {
267 remain = length;
268 *c++ = ' ';
269 *c++ = '\'';
270 for (index = 0; index < bytesPerLine; index++) {
271
272 if (remain-- > 0) {
273 const unsigned char val = pos[index];
274 *c++ = (val >= ' ' && val < 127) ? val : '.';
275 } else if (!oneLine) {
276 *c++ = ' ';
277 }
278 }
Dan Austinc2bf8e82015-10-21 11:28:59 -0700279
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800280 *c++ = '\'';
281 if (length > bytesPerLine) *c++ = '\n';
282 } else {
283 if (remain > 0) *c++ = ',';
284 *c++ = '\n';
285 }
286
287 if (newLine && indent) func(cookie, stringForIndent(indent));
288 *c = 0;
289 func(cookie, buffer);
290 newLine = true;
Dan Austinc2bf8e82015-10-21 11:28:59 -0700291
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800292 if (length <= bytesPerLine) break;
293 length -= bytesPerLine;
294 }
295
296 if (cStyle) {
297 if (indent > 0) func(cookie, stringForIndent(indent-1));
298 func(cookie, "};");
299 }
300}
301
Colin Cross9d45ccc2017-06-20 17:48:33 -0700302ssize_t getBinderKernelReferences(size_t count, uintptr_t* buf) {
303 sp<ProcessState> proc = ProcessState::selfOrNull();
Yi Kongfdd8da92018-06-07 17:52:27 -0700304 if (proc.get() == nullptr) {
Colin Cross9d45ccc2017-06-20 17:48:33 -0700305 return 0;
306 }
307
308 return proc->getKernelReferences(count, buf);
309}
310
Steven Moreland61ff8492019-09-26 16:05:45 -0700311} // namespace android
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800312