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 <hwbinder/Debug.h> 18 #include <hwbinder/ProcessState.h> 19 20 #include <utils/misc.h> 21 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <ctype.h> 25 26 namespace android { 27 namespace hardware { 28 29 // --------------------------------------------------------------------- 30 31 static const char indentStr[] = 32 " " 33 " "; 34 35 const char* stringForIndent(int32_t indentLevel) 36 { 37 ssize_t off = sizeof(indentStr)-1-(indentLevel*2); 38 return indentStr + (off < 0 ? 0 : off); 39 } 40 41 // --------------------------------------------------------------------- 42 43 static void defaultPrintFunc(void* /*cookie*/, const char* txt) 44 { 45 printf("%s", txt); 46 } 47 48 // --------------------------------------------------------------------- 49 50 static inline int isident(int c) 51 { 52 return isalnum(c) || c == '_'; 53 } 54 55 static inline bool isasciitype(char c) 56 { 57 if( c >= ' ' && c < 127 && c != '\'' && c != '\\' ) return true; 58 return false; 59 } 60 61 static inline char makehexdigit(uint32_t val) 62 { 63 return "0123456789abcdef"[val&0xF]; 64 } 65 66 static char* appendhexnum(uint32_t val, char* out) 67 { 68 for( int32_t i=28; i>=0; i-=4 ) { 69 *out++ = makehexdigit( val>>i ); 70 } 71 *out = 0; 72 return out; 73 } 74 75 static char* appendcharornum(char c, char* out, bool skipzero = true) 76 { 77 if (skipzero && c == 0) return out; 78 79 if (isasciitype(c)) { 80 *out++ = c; 81 return out; 82 } 83 84 *out++ = '\\'; 85 *out++ = 'x'; 86 *out++ = makehexdigit(c>>4); 87 *out++ = makehexdigit(c); 88 return out; 89 } 90 91 static char* typetostring(uint32_t type, char* out, 92 bool fullContext = true, 93 bool strict = false) 94 { 95 char* pos = out; 96 char c[4]; 97 c[0] = (char)((type>>24)&0xFF); 98 c[1] = (char)((type>>16)&0xFF); 99 c[2] = (char)((type>>8)&0xFF); 100 c[3] = (char)(type&0xFF); 101 bool valid; 102 if( !strict ) { 103 // now even less strict! 104 // valid = isasciitype(c[3]); 105 valid = true; 106 int32_t i = 0; 107 bool zero = true; 108 while (valid && i<3) { 109 if (c[i] == 0) { 110 if (!zero) valid = false; 111 } else { 112 zero = false; 113 //if (!isasciitype(c[i])) valid = false; 114 } 115 i++; 116 } 117 // if all zeros, not a valid type code. 118 if (zero) valid = false; 119 } else { 120 valid = isident(c[3]) ? true : false; 121 int32_t i = 0; 122 bool zero = true; 123 while (valid && i<3) { 124 if (c[i] == 0) { 125 if (!zero) valid = false; 126 } else { 127 zero = false; 128 if (!isident(c[i])) valid = false; 129 } 130 i++; 131 } 132 } 133 if( valid && (!fullContext || c[0] != '0' || c[1] != 'x') ) { 134 if( fullContext ) *pos++ = '\''; 135 pos = appendcharornum(c[0], pos); 136 pos = appendcharornum(c[1], pos); 137 pos = appendcharornum(c[2], pos); 138 pos = appendcharornum(c[3], pos); 139 if( fullContext ) *pos++ = '\''; 140 *pos = 0; 141 return pos; 142 } 143 144 if( fullContext ) { 145 *pos++ = '0'; 146 *pos++ = 'x'; 147 } 148 return appendhexnum(type, pos); 149 } 150 151 void printTypeCode(uint32_t typeCode, debugPrintFunc func, void* cookie) 152 { 153 char buffer[32]; 154 char* end = typetostring(typeCode, buffer); 155 *end = 0; 156 func ? (*func)(cookie, buffer) : defaultPrintFunc(cookie, buffer); 157 } 158 159 void printHexData(int32_t indent, const void *buf, size_t length, 160 size_t bytesPerLine, int32_t singleLineBytesCutoff, 161 size_t alignment, bool cStyle, 162 debugPrintFunc func, void* cookie) 163 { 164 if (alignment == 0) { 165 if (bytesPerLine >= 16) alignment = 4; 166 else if (bytesPerLine >= 8) alignment = 2; 167 else alignment = 1; 168 } 169 if (func == nullptr) func = defaultPrintFunc; 170 171 size_t offset; 172 173 unsigned char *pos = (unsigned char *)buf; 174 175 if (pos == nullptr) { 176 if (singleLineBytesCutoff < 0) func(cookie, "\n"); 177 func(cookie, "(NULL)"); 178 return; 179 } 180 181 if (length == 0) { 182 if (singleLineBytesCutoff < 0) func(cookie, "\n"); 183 func(cookie, "(empty)"); 184 return; 185 } 186 187 if ((int32_t)length < 0) { 188 if (singleLineBytesCutoff < 0) func(cookie, "\n"); 189 char buf[64]; 190 sprintf(buf, "(bad length: %zu)", length); 191 func(cookie, buf); 192 return; 193 } 194 195 char buffer[256]; 196 static const size_t maxBytesPerLine = (sizeof(buffer)-1-11-4)/(3+1); 197 198 if (bytesPerLine > maxBytesPerLine) bytesPerLine = maxBytesPerLine; 199 200 const bool oneLine = (int32_t)length <= singleLineBytesCutoff; 201 bool newLine = false; 202 if (cStyle) { 203 indent++; 204 func(cookie, "{\n"); 205 newLine = true; 206 } else if (!oneLine) { 207 func(cookie, "\n"); 208 newLine = true; 209 } 210 211 for (offset = 0; ; offset += bytesPerLine, pos += bytesPerLine) { 212 long remain = length; 213 214 char* c = buffer; 215 if (!oneLine && !cStyle) { 216 sprintf(c, "0x%08x: ", (int)offset); 217 c += 12; 218 } 219 220 size_t index; 221 size_t word; 222 223 for (word = 0; word < bytesPerLine; ) { 224 225 size_t align_offset = alignment-(alignment?1:0); 226 if (remain > 0 && (size_t)remain <= align_offset) { 227 align_offset = remain - 1; 228 } 229 const size_t startIndex = word+align_offset; 230 231 for (index = 0; index < alignment || (alignment == 0 && index < bytesPerLine); index++) { 232 233 if (!cStyle) { 234 if (index == 0 && word > 0 && alignment > 0) { 235 *c++ = ' '; 236 } 237 238 if (remain-- > 0) { 239 const unsigned char val = *(pos+startIndex-index); 240 *c++ = makehexdigit(val>>4); 241 *c++ = makehexdigit(val); 242 } else if (!oneLine) { 243 *c++ = ' '; 244 *c++ = ' '; 245 } 246 } else { 247 if (remain > 0) { 248 if (index == 0 && word > 0) { 249 *c++ = ','; 250 *c++ = ' '; 251 } 252 if (index == 0) { 253 *c++ = '0'; 254 *c++ = 'x'; 255 } 256 const unsigned char val = *(pos+startIndex-index); 257 *c++ = makehexdigit(val>>4); 258 *c++ = makehexdigit(val); 259 remain--; 260 } 261 } 262 } 263 264 word += index; 265 } 266 267 if (!cStyle) { 268 remain = length; 269 *c++ = ' '; 270 *c++ = '\''; 271 for (index = 0; index < bytesPerLine; index++) { 272 273 if (remain-- > 0) { 274 const unsigned char val = pos[index]; 275 *c++ = (val >= ' ' && val < 127) ? val : '.'; 276 } else if (!oneLine) { 277 *c++ = ' '; 278 } 279 } 280 281 *c++ = '\''; 282 if (length > bytesPerLine) *c++ = '\n'; 283 } else { 284 if (remain > 0) *c++ = ','; 285 *c++ = '\n'; 286 } 287 288 if (newLine && indent) func(cookie, stringForIndent(indent)); 289 *c = 0; 290 func(cookie, buffer); 291 newLine = true; 292 293 if (length <= bytesPerLine) break; 294 length -= bytesPerLine; 295 } 296 297 if (cStyle) { 298 if (indent > 0) func(cookie, stringForIndent(indent-1)); 299 func(cookie, "};"); 300 } 301 } 302 303 ssize_t getHWBinderKernelReferences(size_t count, uintptr_t* buf) { 304 sp<ProcessState> proc = ProcessState::selfOrNull(); 305 if (proc.get() == nullptr) { 306 return 0; 307 } 308 309 return proc->getKernelReferences(count, buf); 310 } 311 312 } // namespace hardware 313 } // namespace android 314 315