• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 #include "Debug.h"
18 #include "BuildFlags.h"
19 
20 #include <binder/ProcessState.h>
21 
22 #include <utils/misc.h>
23 
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <ctype.h>
27 
28 namespace android {
29 
30 // ---------------------------------------------------------------------
31 
32 static const char indentStr[] =
33 "                                                                            "
34 "                                                                            ";
35 
stringForIndent(int32_t indentLevel)36 const 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 
defaultPrintFunc(void *,const char * txt)44 static void defaultPrintFunc(void* /*cookie*/, const char* txt)
45 {
46     printf("%s", txt);
47 }
48 
49 // ---------------------------------------------------------------------
50 
isident(int c)51 static inline int isident(int c)
52 {
53     return isalnum(c) || c == '_';
54 }
55 
isasciitype(char c)56 static inline bool isasciitype(char c)
57 {
58     if( c >= ' ' && c < 127 && c != '\'' && c != '\\' ) return true;
59     return false;
60 }
61 
makehexdigit(uint32_t val)62 static inline char makehexdigit(uint32_t val)
63 {
64     return "0123456789abcdef"[val&0xF];
65 }
66 
appendhexnum(uint32_t val,char * out)67 static 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 
appendcharornum(char c,char * out,bool skipzero=true)76 static 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 
typetostring(uint32_t type,char * out,bool fullContext=true,bool strict=false)92 static 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     }
144 
145     if( fullContext ) {
146         *pos++ = '0';
147         *pos++ = 'x';
148     }
149     return appendhexnum(type, pos);
150 }
151 
printTypeCode(uint32_t typeCode,debugPrintFunc func,void * cookie)152 void 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 
printHexData(int32_t indent,const void * buf,size_t length,size_t bytesPerLine,int32_t singleLineBytesCutoff,size_t alignment,bool cStyle,debugPrintFunc func,void * cookie)160 void 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     }
170     if (func == nullptr) func = defaultPrintFunc;
171 
172     size_t offset;
173 
174     unsigned char *pos = (unsigned char *)buf;
175 
176     if (pos == nullptr) {
177         if (singleLineBytesCutoff < 0) func(cookie, "\n");
178         func(cookie, "(NULL)");
179         return;
180     }
181 
182     if (length == 0) {
183         if (singleLineBytesCutoff < 0) func(cookie, "\n");
184         func(cookie, "(empty)");
185         return;
186     }
187 
188     if ((int32_t)length < 0) {
189         if (singleLineBytesCutoff < 0) func(cookie, "\n");
190         char buf[64];
191         sprintf(buf, "(bad length: %zu)", length);
192         func(cookie, buf);
193         return;
194     }
195 
196     char buffer[256];
197     static const size_t maxBytesPerLine = (sizeof(buffer)-1-11-4)/(3+1);
198 
199     if (bytesPerLine > maxBytesPerLine) bytesPerLine = maxBytesPerLine;
200 
201     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     }
211 
212     for (offset = 0; ; offset += bytesPerLine, pos += bytesPerLine) {
213         ssize_t remain = length;
214 
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;
223 
224         for (word = 0; word < bytesPerLine; ) {
225 
226             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;
231 
232             for (index = 0; index < alignment || (alignment == 0 && index < bytesPerLine); index++) {
233 
234                 if (!cStyle) {
235                     if (index == 0 && word > 0 && alignment > 0) {
236                         *c++ = ' ';
237                     }
238 
239                     if (remain-- > 0) {
240                         const unsigned char val = *(pos+startIndex-index);
241                         *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                         }
257                         const unsigned char val = *(pos+startIndex-index);
258                         *c++ = makehexdigit(val>>4);
259                         *c++ = makehexdigit(val);
260                         remain--;
261                     }
262                 }
263             }
264 
265             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             }
281 
282             *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;
293 
294         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 
getBinderKernelReferences(size_t count,uintptr_t * buf)304 ssize_t getBinderKernelReferences(size_t count, uintptr_t* buf) {
305     if constexpr (!kEnableKernelIpc) {
306         LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time");
307         return 0;
308     }
309 
310     sp<ProcessState> proc = ProcessState::selfOrNull();
311     if (proc.get() == nullptr) {
312         return 0;
313     }
314 
315     return proc->getKernelReferences(count, buf);
316 }
317 
318 } // namespace android
319 
320