blob: f6533a7130b5f931b8996bbac8e1217b8c930e06 [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
2 * Copyright (C) 2011 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 */
Elliott Hughes11e45072011-08-16 17:40:46 -070016
Elliott Hughes42ee1422011-09-06 12:33:32 -070017#include "utils.h"
18
Christopher Ferris943af7d2014-01-16 12:41:46 -080019#include <inttypes.h>
Elliott Hughes92b3b562011-09-08 16:32:26 -070020#include <pthread.h>
Brian Carlstroma9f19782011-10-13 00:14:47 -070021#include <sys/stat.h>
Elliott Hughes42ee1422011-09-06 12:33:32 -070022#include <sys/syscall.h>
23#include <sys/types.h>
Brian Carlstrom4cf5e572014-02-25 11:47:48 -080024#include <sys/wait.h>
Elliott Hughes42ee1422011-09-06 12:33:32 -070025#include <unistd.h>
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070026
Ian Rogers700a4022014-05-19 16:49:03 -070027#include <memory>
Elliott Hughes42ee1422011-09-06 12:33:32 -070028
Andreas Gampe46ee31b2016-12-14 10:11:49 -080029#include "android-base/stringprintf.h"
Andreas Gampe9186ced2016-12-12 14:28:21 -080030#include "android-base/strings.h"
31
David Sehr891a50e2017-10-27 17:01:07 -070032#include "base/file_utils.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070033#include "dex_file-inl.h"
buzbeec143c552011-08-20 17:38:58 -070034#include "os.h"
Ian Rogersa6724902013-09-23 09:23:37 -070035#include "utf-inl.h"
Elliott Hughes11e45072011-08-16 17:40:46 -070036
Elliott Hughes4ae722a2012-03-13 11:08:51 -070037#if defined(__APPLE__)
David Sehrfa442002016-08-22 18:42:08 -070038#include <crt_externs.h>
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070039#include <sys/syscall.h>
40#include "AvailabilityMacros.h" // For MAC_OS_X_VERSION_MAX_ALLOWED
Elliott Hughes4ae722a2012-03-13 11:08:51 -070041#endif
42
Elliott Hughes058a6de2012-05-24 19:13:02 -070043#if defined(__linux__)
Elliott Hughese1aee692012-01-17 16:40:10 -080044#include <linux/unistd.h>
Elliott Hughese1aee692012-01-17 16:40:10 -080045#endif
46
Elliott Hughes11e45072011-08-16 17:40:46 -070047namespace art {
48
Andreas Gampe46ee31b2016-12-14 10:11:49 -080049using android::base::StringAppendF;
50using android::base::StringPrintf;
51
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080052pid_t GetTid() {
Brian Carlstromf3a26412012-08-24 11:06:02 -070053#if defined(__APPLE__)
54 uint64_t owner;
Mathieu Chartier2cebb242015-04-21 16:50:40 -070055 CHECK_PTHREAD_CALL(pthread_threadid_np, (nullptr, &owner), __FUNCTION__); // Requires Mac OS 10.6
Brian Carlstromf3a26412012-08-24 11:06:02 -070056 return owner;
Elliott Hughes323aa862014-08-20 15:00:04 -070057#elif defined(__BIONIC__)
58 return gettid();
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080059#else
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080060 return syscall(__NR_gettid);
61#endif
62}
63
Elliott Hughes289be852012-06-12 13:57:20 -070064std::string GetThreadName(pid_t tid) {
65 std::string result;
66 if (ReadFileToString(StringPrintf("/proc/self/task/%d/comm", tid), &result)) {
Brian Carlstrom7934ac22013-07-26 10:54:15 -070067 result.resize(result.size() - 1); // Lose the trailing '\n'.
Elliott Hughes289be852012-06-12 13:57:20 -070068 } else {
69 result = "<unknown>";
70 }
71 return result;
72}
73
Vladimir Markob8a55f82017-09-21 16:21:43 +010074void AppendPrettyDescriptor(const char* descriptor, std::string* result) {
Elliott Hughes11e45072011-08-16 17:40:46 -070075 // Count the number of '['s to get the dimensionality.
Ian Rogers1ff3c982014-08-12 02:30:58 -070076 const char* c = descriptor;
Elliott Hughes11e45072011-08-16 17:40:46 -070077 size_t dim = 0;
78 while (*c == '[') {
79 dim++;
80 c++;
81 }
82
83 // Reference or primitive?
84 if (*c == 'L') {
85 // "[[La/b/C;" -> "a.b.C[][]".
Brian Carlstrom7934ac22013-07-26 10:54:15 -070086 c++; // Skip the 'L'.
Elliott Hughes11e45072011-08-16 17:40:46 -070087 } else {
88 // "[[B" -> "byte[][]".
89 // To make life easier, we make primitives look like unqualified
90 // reference types.
91 switch (*c) {
Vladimir Markob8a55f82017-09-21 16:21:43 +010092 case 'B': c = "byte;"; break;
93 case 'C': c = "char;"; break;
94 case 'D': c = "double;"; break;
95 case 'F': c = "float;"; break;
96 case 'I': c = "int;"; break;
97 case 'J': c = "long;"; break;
98 case 'S': c = "short;"; break;
99 case 'Z': c = "boolean;"; break;
100 case 'V': c = "void;"; break; // Used when decoding return types.
101 default: result->append(descriptor); return;
Elliott Hughes11e45072011-08-16 17:40:46 -0700102 }
103 }
104
105 // At this point, 'c' is a string of the form "fully/qualified/Type;"
106 // or "primitive;". Rewrite the type with '.' instead of '/':
Elliott Hughes11e45072011-08-16 17:40:46 -0700107 const char* p = c;
108 while (*p != ';') {
109 char ch = *p++;
110 if (ch == '/') {
111 ch = '.';
112 }
Vladimir Markob8a55f82017-09-21 16:21:43 +0100113 result->push_back(ch);
Elliott Hughes11e45072011-08-16 17:40:46 -0700114 }
115 // ...and replace the semicolon with 'dim' "[]" pairs:
Ian Rogers1ff3c982014-08-12 02:30:58 -0700116 for (size_t i = 0; i < dim; ++i) {
Vladimir Markob8a55f82017-09-21 16:21:43 +0100117 result->append("[]");
Elliott Hughes11e45072011-08-16 17:40:46 -0700118 }
Elliott Hughes11e45072011-08-16 17:40:46 -0700119}
120
Vladimir Markob8a55f82017-09-21 16:21:43 +0100121std::string PrettyDescriptor(const char* descriptor) {
Elliott Hughes9058f2b2012-03-22 18:06:48 -0700122 std::string result;
Vladimir Markob8a55f82017-09-21 16:21:43 +0100123 AppendPrettyDescriptor(descriptor, &result);
Elliott Hughes9058f2b2012-03-22 18:06:48 -0700124 return result;
125}
126
Andreas Gampec0d82292014-09-23 10:38:30 -0700127std::string PrettyJavaAccessFlags(uint32_t access_flags) {
128 std::string result;
129 if ((access_flags & kAccPublic) != 0) {
130 result += "public ";
131 }
132 if ((access_flags & kAccProtected) != 0) {
133 result += "protected ";
134 }
135 if ((access_flags & kAccPrivate) != 0) {
136 result += "private ";
137 }
138 if ((access_flags & kAccFinal) != 0) {
139 result += "final ";
140 }
141 if ((access_flags & kAccStatic) != 0) {
142 result += "static ";
143 }
David Brazdilca3c8c32016-09-06 14:04:48 +0100144 if ((access_flags & kAccAbstract) != 0) {
145 result += "abstract ";
146 }
147 if ((access_flags & kAccInterface) != 0) {
148 result += "interface ";
149 }
Andreas Gampec0d82292014-09-23 10:38:30 -0700150 if ((access_flags & kAccTransient) != 0) {
151 result += "transient ";
152 }
153 if ((access_flags & kAccVolatile) != 0) {
154 result += "volatile ";
155 }
156 if ((access_flags & kAccSynchronized) != 0) {
157 result += "synchronized ";
158 }
159 return result;
160}
161
Mathieu Chartiere6da9af2013-12-16 11:54:42 -0800162std::string PrettySize(int64_t byte_count) {
Elliott Hughesc967f782012-04-16 10:23:15 -0700163 // The byte thresholds at which we display amounts. A byte count is displayed
164 // in unit U when kUnitThresholds[U] <= bytes < kUnitThresholds[U+1].
Ian Rogersef7d42f2014-01-06 12:55:46 -0800165 static const int64_t kUnitThresholds[] = {
Elliott Hughesc967f782012-04-16 10:23:15 -0700166 0, // B up to...
167 3*1024, // KB up to...
168 2*1024*1024, // MB up to...
169 1024*1024*1024 // GB from here.
170 };
Mathieu Chartiere6da9af2013-12-16 11:54:42 -0800171 static const int64_t kBytesPerUnit[] = { 1, KB, MB, GB };
Elliott Hughesc967f782012-04-16 10:23:15 -0700172 static const char* const kUnitStrings[] = { "B", "KB", "MB", "GB" };
Mathieu Chartiere6da9af2013-12-16 11:54:42 -0800173 const char* negative_str = "";
174 if (byte_count < 0) {
175 negative_str = "-";
176 byte_count = -byte_count;
177 }
Elliott Hughesc967f782012-04-16 10:23:15 -0700178 int i = arraysize(kUnitThresholds);
179 while (--i > 0) {
180 if (byte_count >= kUnitThresholds[i]) {
181 break;
182 }
Ian Rogers3bb17a62012-01-27 23:56:44 -0800183 }
Brian Carlstrom474cc792014-03-07 14:18:15 -0800184 return StringPrintf("%s%" PRId64 "%s",
185 negative_str, byte_count / kBytesPerUnit[i], kUnitStrings[i]);
Ian Rogers3bb17a62012-01-27 23:56:44 -0800186}
187
Andreas Gampe9186ced2016-12-12 14:28:21 -0800188static inline constexpr bool NeedsEscaping(uint16_t ch) {
189 return (ch < ' ' || ch > '~');
190}
191
Ian Rogers576ca0c2014-06-06 15:58:22 -0700192std::string PrintableChar(uint16_t ch) {
193 std::string result;
194 result += '\'';
195 if (NeedsEscaping(ch)) {
196 StringAppendF(&result, "\\u%04x", ch);
197 } else {
Andreas Gampef45d61c2017-06-07 10:29:33 -0700198 result += static_cast<std::string::value_type>(ch);
Ian Rogers576ca0c2014-06-06 15:58:22 -0700199 }
200 result += '\'';
201 return result;
202}
203
Ian Rogers68b56852014-08-29 20:19:11 -0700204std::string PrintableString(const char* utf) {
Elliott Hughes82914b62012-04-09 15:56:29 -0700205 std::string result;
206 result += '"';
Ian Rogers68b56852014-08-29 20:19:11 -0700207 const char* p = utf;
Elliott Hughes82914b62012-04-09 15:56:29 -0700208 size_t char_count = CountModifiedUtf8Chars(p);
209 for (size_t i = 0; i < char_count; ++i) {
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000210 uint32_t ch = GetUtf16FromUtf8(&p);
Elliott Hughes82914b62012-04-09 15:56:29 -0700211 if (ch == '\\') {
212 result += "\\\\";
213 } else if (ch == '\n') {
214 result += "\\n";
215 } else if (ch == '\r') {
216 result += "\\r";
217 } else if (ch == '\t') {
218 result += "\\t";
Elliott Hughes82914b62012-04-09 15:56:29 -0700219 } else {
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000220 const uint16_t leading = GetLeadingUtf16Char(ch);
221
222 if (NeedsEscaping(leading)) {
223 StringAppendF(&result, "\\u%04x", leading);
224 } else {
Andreas Gampef45d61c2017-06-07 10:29:33 -0700225 result += static_cast<std::string::value_type>(leading);
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000226 }
227
228 const uint32_t trailing = GetTrailingUtf16Char(ch);
229 if (trailing != 0) {
230 // All high surrogates will need escaping.
231 StringAppendF(&result, "\\u%04x", trailing);
232 }
Elliott Hughes82914b62012-04-09 15:56:29 -0700233 }
234 }
235 result += '"';
236 return result;
237}
238
Alex Light888a59e2017-01-25 11:41:41 -0800239std::string GetJniShortName(const std::string& class_descriptor, const std::string& method) {
240 // Remove the leading 'L' and trailing ';'...
241 std::string class_name(class_descriptor);
242 CHECK_EQ(class_name[0], 'L') << class_name;
243 CHECK_EQ(class_name[class_name.size() - 1], ';') << class_name;
244 class_name.erase(0, 1);
245 class_name.erase(class_name.size() - 1, 1);
246
247 std::string short_name;
248 short_name += "Java_";
249 short_name += MangleForJni(class_name);
250 short_name += "_";
251 short_name += MangleForJni(method);
252 return short_name;
253}
254
Elliott Hughesd8c00d02012-01-30 14:08:31 -0800255// See http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/design.html#wp615 for the full rules.
Elliott Hughes79082e32011-08-25 12:07:32 -0700256std::string MangleForJni(const std::string& s) {
257 std::string result;
258 size_t char_count = CountModifiedUtf8Chars(s.c_str());
259 const char* cp = &s[0];
260 for (size_t i = 0; i < char_count; ++i) {
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000261 uint32_t ch = GetUtf16FromUtf8(&cp);
Elliott Hughesd8c00d02012-01-30 14:08:31 -0800262 if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')) {
263 result.push_back(ch);
264 } else if (ch == '.' || ch == '/') {
265 result += "_";
266 } else if (ch == '_') {
267 result += "_1";
268 } else if (ch == ';') {
269 result += "_2";
270 } else if (ch == '[') {
271 result += "_3";
Elliott Hughes79082e32011-08-25 12:07:32 -0700272 } else {
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000273 const uint16_t leading = GetLeadingUtf16Char(ch);
274 const uint32_t trailing = GetTrailingUtf16Char(ch);
275
276 StringAppendF(&result, "_0%04x", leading);
277 if (trailing != 0) {
278 StringAppendF(&result, "_0%04x", trailing);
279 }
Elliott Hughes79082e32011-08-25 12:07:32 -0700280 }
281 }
282 return result;
283}
284
Brian Carlstromf91c8c32011-09-21 17:30:34 -0700285std::string DotToDescriptor(const char* class_name) {
286 std::string descriptor(class_name);
287 std::replace(descriptor.begin(), descriptor.end(), '.', '/');
288 if (descriptor.length() > 0 && descriptor[0] != '[') {
289 descriptor = "L" + descriptor + ";";
290 }
291 return descriptor;
292}
293
Elliott Hughesf1a5adc2012-02-10 18:09:35 -0800294std::string DescriptorToDot(const char* descriptor) {
Elliott Hughes2435a572012-02-17 16:07:41 -0800295 size_t length = strlen(descriptor);
Ian Rogers1ff3c982014-08-12 02:30:58 -0700296 if (length > 1) {
297 if (descriptor[0] == 'L' && descriptor[length - 1] == ';') {
298 // Descriptors have the leading 'L' and trailing ';' stripped.
299 std::string result(descriptor + 1, length - 2);
300 std::replace(result.begin(), result.end(), '/', '.');
301 return result;
302 } else {
303 // For arrays the 'L' and ';' remain intact.
304 std::string result(descriptor);
305 std::replace(result.begin(), result.end(), '/', '.');
306 return result;
307 }
Elliott Hughes2435a572012-02-17 16:07:41 -0800308 }
Ian Rogers1ff3c982014-08-12 02:30:58 -0700309 // Do nothing for non-class/array descriptors.
Elliott Hughes2435a572012-02-17 16:07:41 -0800310 return descriptor;
Elliott Hughes91bf6cd2012-02-14 17:27:48 -0800311}
312
313std::string DescriptorToName(const char* descriptor) {
Elliott Hughesf1a5adc2012-02-10 18:09:35 -0800314 size_t length = strlen(descriptor);
Elliott Hughes2435a572012-02-17 16:07:41 -0800315 if (descriptor[0] == 'L' && descriptor[length - 1] == ';') {
316 std::string result(descriptor + 1, length - 2);
317 return result;
318 }
319 return descriptor;
Brian Carlstromaded5f72011-10-07 17:15:04 -0700320}
321
jeffhao10037c82012-01-23 15:06:23 -0800322// Helper for IsValidPartOfMemberNameUtf8(), a bit vector indicating valid low ascii.
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700323uint32_t DEX_MEMBER_VALID_LOW_ASCII[4] = {
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700324 0x00000000, // 00..1f low control characters; nothing valid
325 0x03ff2010, // 20..3f digits and symbols; valid: '0'..'9', '$', '-'
326 0x87fffffe, // 40..5f uppercase etc.; valid: 'A'..'Z', '_'
327 0x07fffffe // 60..7f lowercase etc.; valid: 'a'..'z'
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700328};
329
jeffhao10037c82012-01-23 15:06:23 -0800330// Helper for IsValidPartOfMemberNameUtf8(); do not call directly.
331bool IsValidPartOfMemberNameUtf8Slow(const char** pUtf8Ptr) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700332 /*
333 * It's a multibyte encoded character. Decode it and analyze. We
334 * accept anything that isn't (a) an improperly encoded low value,
335 * (b) an improper surrogate pair, (c) an encoded '\0', (d) a high
336 * control character, or (e) a high space, layout, or special
337 * character (U+00a0, U+2000..U+200f, U+2028..U+202f,
338 * U+fff0..U+ffff). This is all specified in the dex format
339 * document.
340 */
341
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000342 const uint32_t pair = GetUtf16FromUtf8(pUtf8Ptr);
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000343 const uint16_t leading = GetLeadingUtf16Char(pair);
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000344
Narayan Kamath8508e372015-05-06 14:55:43 +0100345 // We have a surrogate pair resulting from a valid 4 byte UTF sequence.
346 // No further checks are necessary because 4 byte sequences span code
347 // points [U+10000, U+1FFFFF], which are valid codepoints in a dex
348 // identifier. Furthermore, GetUtf16FromUtf8 guarantees that each of
349 // the surrogate halves are valid and well formed in this instance.
350 if (GetTrailingUtf16Char(pair) != 0) {
351 return true;
352 }
353
354
355 // We've encountered a one, two or three byte UTF-8 sequence. The
356 // three byte UTF-8 sequence could be one half of a surrogate pair.
357 switch (leading >> 8) {
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000358 case 0x00:
359 // It's only valid if it's above the ISO-8859-1 high space (0xa0).
360 return (leading > 0x00a0);
361 case 0xd8:
362 case 0xd9:
363 case 0xda:
364 case 0xdb:
Narayan Kamath8508e372015-05-06 14:55:43 +0100365 {
366 // We found a three byte sequence encoding one half of a surrogate.
367 // Look for the other half.
368 const uint32_t pair2 = GetUtf16FromUtf8(pUtf8Ptr);
369 const uint16_t trailing = GetLeadingUtf16Char(pair2);
370
371 return (GetTrailingUtf16Char(pair2) == 0) && (0xdc00 <= trailing && trailing <= 0xdfff);
372 }
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000373 case 0xdc:
374 case 0xdd:
375 case 0xde:
376 case 0xdf:
377 // It's a trailing surrogate, which is not valid at this point.
378 return false;
379 case 0x20:
380 case 0xff:
381 // It's in the range that has spaces, controls, and specials.
382 switch (leading & 0xfff8) {
Narayan Kamath8508e372015-05-06 14:55:43 +0100383 case 0x2000:
384 case 0x2008:
385 case 0x2028:
386 case 0xfff0:
387 case 0xfff8:
388 return false;
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000389 }
Narayan Kamath8508e372015-05-06 14:55:43 +0100390 return true;
391 default:
392 return true;
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700393 }
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000394
Narayan Kamath8508e372015-05-06 14:55:43 +0100395 UNREACHABLE();
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700396}
397
398/* Return whether the pointed-at modified-UTF-8 encoded character is
399 * valid as part of a member name, updating the pointer to point past
400 * the consumed character. This will consume two encoded UTF-16 code
401 * points if the character is encoded as a surrogate pair. Also, if
402 * this function returns false, then the given pointer may only have
403 * been partially advanced.
404 */
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700405static bool IsValidPartOfMemberNameUtf8(const char** pUtf8Ptr) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700406 uint8_t c = (uint8_t) **pUtf8Ptr;
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700407 if (LIKELY(c <= 0x7f)) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700408 // It's low-ascii, so check the table.
409 uint32_t wordIdx = c >> 5;
410 uint32_t bitIdx = c & 0x1f;
411 (*pUtf8Ptr)++;
412 return (DEX_MEMBER_VALID_LOW_ASCII[wordIdx] & (1 << bitIdx)) != 0;
413 }
414
415 // It's a multibyte encoded character. Call a non-inline function
416 // for the heavy lifting.
jeffhao10037c82012-01-23 15:06:23 -0800417 return IsValidPartOfMemberNameUtf8Slow(pUtf8Ptr);
418}
419
420bool IsValidMemberName(const char* s) {
421 bool angle_name = false;
422
Elliott Hughesb25c3f62012-03-26 16:35:06 -0700423 switch (*s) {
jeffhao10037c82012-01-23 15:06:23 -0800424 case '\0':
425 // The empty string is not a valid name.
426 return false;
427 case '<':
428 angle_name = true;
429 s++;
430 break;
431 }
432
433 while (true) {
434 switch (*s) {
435 case '\0':
436 return !angle_name;
437 case '>':
438 return angle_name && s[1] == '\0';
439 }
440
441 if (!IsValidPartOfMemberNameUtf8(&s)) {
442 return false;
443 }
444 }
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700445}
446
Elliott Hughes906e6852011-10-28 14:52:10 -0700447enum ClassNameType { kName, kDescriptor };
Ian Rogers7b078e82014-09-10 14:44:24 -0700448template<ClassNameType kType, char kSeparator>
449static bool IsValidClassName(const char* s) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700450 int arrayCount = 0;
451 while (*s == '[') {
452 arrayCount++;
453 s++;
454 }
455
456 if (arrayCount > 255) {
457 // Arrays may have no more than 255 dimensions.
458 return false;
459 }
460
Ian Rogers7b078e82014-09-10 14:44:24 -0700461 ClassNameType type = kType;
462 if (type != kDescriptor && arrayCount != 0) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700463 /*
464 * If we're looking at an array of some sort, then it doesn't
465 * matter if what is being asked for is a class name; the
466 * format looks the same as a type descriptor in that case, so
467 * treat it as such.
468 */
Elliott Hughes906e6852011-10-28 14:52:10 -0700469 type = kDescriptor;
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700470 }
471
Elliott Hughes906e6852011-10-28 14:52:10 -0700472 if (type == kDescriptor) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700473 /*
474 * We are looking for a descriptor. Either validate it as a
475 * single-character primitive type, or continue on to check the
476 * embedded class name (bracketed by "L" and ";").
477 */
478 switch (*(s++)) {
479 case 'B':
480 case 'C':
481 case 'D':
482 case 'F':
483 case 'I':
484 case 'J':
485 case 'S':
486 case 'Z':
487 // These are all single-character descriptors for primitive types.
488 return (*s == '\0');
489 case 'V':
490 // Non-array void is valid, but you can't have an array of void.
491 return (arrayCount == 0) && (*s == '\0');
492 case 'L':
493 // Class name: Break out and continue below.
494 break;
495 default:
496 // Oddball descriptor character.
497 return false;
498 }
499 }
500
501 /*
502 * We just consumed the 'L' that introduces a class name as part
503 * of a type descriptor, or we are looking for an unadorned class
504 * name.
505 */
506
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700507 bool sepOrFirst = true; // first character or just encountered a separator.
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700508 for (;;) {
509 uint8_t c = (uint8_t) *s;
510 switch (c) {
511 case '\0':
512 /*
513 * Premature end for a type descriptor, but valid for
514 * a class name as long as we haven't encountered an
515 * empty component (including the degenerate case of
516 * the empty string "").
517 */
Elliott Hughes906e6852011-10-28 14:52:10 -0700518 return (type == kName) && !sepOrFirst;
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700519 case ';':
520 /*
521 * Invalid character for a class name, but the
522 * legitimate end of a type descriptor. In the latter
523 * case, make sure that this is the end of the string
524 * and that it doesn't end with an empty component
525 * (including the degenerate case of "L;").
526 */
Elliott Hughes906e6852011-10-28 14:52:10 -0700527 return (type == kDescriptor) && !sepOrFirst && (s[1] == '\0');
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700528 case '/':
529 case '.':
Ian Rogers7b078e82014-09-10 14:44:24 -0700530 if (c != kSeparator) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700531 // The wrong separator character.
532 return false;
533 }
534 if (sepOrFirst) {
535 // Separator at start or two separators in a row.
536 return false;
537 }
538 sepOrFirst = true;
539 s++;
540 break;
541 default:
jeffhao10037c82012-01-23 15:06:23 -0800542 if (!IsValidPartOfMemberNameUtf8(&s)) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700543 return false;
544 }
545 sepOrFirst = false;
546 break;
547 }
548 }
549}
550
Elliott Hughes906e6852011-10-28 14:52:10 -0700551bool IsValidBinaryClassName(const char* s) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700552 return IsValidClassName<kName, '.'>(s);
Elliott Hughes906e6852011-10-28 14:52:10 -0700553}
554
555bool IsValidJniClassName(const char* s) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700556 return IsValidClassName<kName, '/'>(s);
Elliott Hughes906e6852011-10-28 14:52:10 -0700557}
558
559bool IsValidDescriptor(const char* s) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700560 return IsValidClassName<kDescriptor, '/'>(s);
Elliott Hughes906e6852011-10-28 14:52:10 -0700561}
562
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700563void Split(const std::string& s, char separator, std::vector<std::string>* result) {
Elliott Hughes34023802011-08-30 12:06:17 -0700564 const char* p = s.data();
565 const char* end = p + s.size();
566 while (p != end) {
Elliott Hughes48436bb2012-02-07 15:23:28 -0800567 if (*p == separator) {
Elliott Hughes34023802011-08-30 12:06:17 -0700568 ++p;
569 } else {
570 const char* start = p;
Elliott Hughes48436bb2012-02-07 15:23:28 -0800571 while (++p != end && *p != separator) {
572 // Skip to the next occurrence of the separator.
Elliott Hughes34023802011-08-30 12:06:17 -0700573 }
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700574 result->push_back(std::string(start, p - start));
Elliott Hughes34023802011-08-30 12:06:17 -0700575 }
576 }
577}
578
Elliott Hughes22869a92012-03-27 14:08:24 -0700579void SetThreadName(const char* thread_name) {
Elliott Hughesdcc24742011-09-07 14:02:44 -0700580 int hasAt = 0;
581 int hasDot = 0;
Elliott Hughes22869a92012-03-27 14:08:24 -0700582 const char* s = thread_name;
Elliott Hughesdcc24742011-09-07 14:02:44 -0700583 while (*s) {
584 if (*s == '.') {
585 hasDot = 1;
586 } else if (*s == '@') {
587 hasAt = 1;
588 }
589 s++;
590 }
Elliott Hughes22869a92012-03-27 14:08:24 -0700591 int len = s - thread_name;
Elliott Hughesdcc24742011-09-07 14:02:44 -0700592 if (len < 15 || hasAt || !hasDot) {
Elliott Hughes22869a92012-03-27 14:08:24 -0700593 s = thread_name;
Elliott Hughesdcc24742011-09-07 14:02:44 -0700594 } else {
Elliott Hughes22869a92012-03-27 14:08:24 -0700595 s = thread_name + len - 15;
Elliott Hughesdcc24742011-09-07 14:02:44 -0700596 }
Elliott Hughes0a18df82015-01-09 15:16:16 -0800597#if defined(__linux__)
Elliott Hughes7c6a61e2012-03-12 18:01:41 -0700598 // pthread_setname_np fails rather than truncating long strings.
Elliott Hughes0a18df82015-01-09 15:16:16 -0800599 char buf[16]; // MAX_TASK_COMM_LEN=16 is hard-coded in the kernel.
Elliott Hughesdcc24742011-09-07 14:02:44 -0700600 strncpy(buf, s, sizeof(buf)-1);
601 buf[sizeof(buf)-1] = '\0';
602 errno = pthread_setname_np(pthread_self(), buf);
603 if (errno != 0) {
604 PLOG(WARNING) << "Unable to set the name of current thread to '" << buf << "'";
605 }
Elliott Hughes0a18df82015-01-09 15:16:16 -0800606#else // __APPLE__
Elliott Hughes22869a92012-03-27 14:08:24 -0700607 pthread_setname_np(thread_name);
Elliott Hughesdcc24742011-09-07 14:02:44 -0700608#endif
609}
610
Brian Carlstrom29212012013-09-12 22:18:30 -0700611void GetTaskStats(pid_t tid, char* state, int* utime, int* stime, int* task_cpu) {
612 *utime = *stime = *task_cpu = 0;
Elliott Hughesbfe487b2011-10-26 15:48:55 -0700613 std::string stats;
Elliott Hughes8a31b502012-04-30 19:36:11 -0700614 if (!ReadFileToString(StringPrintf("/proc/self/task/%d/stat", tid), &stats)) {
Elliott Hughesbfe487b2011-10-26 15:48:55 -0700615 return;
616 }
617 // Skip the command, which may contain spaces.
618 stats = stats.substr(stats.find(')') + 2);
619 // Extract the three fields we care about.
620 std::vector<std::string> fields;
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700621 Split(stats, ' ', &fields);
Brian Carlstrom29212012013-09-12 22:18:30 -0700622 *state = fields[0][0];
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700623 *utime = strtoull(fields[11].c_str(), nullptr, 10);
624 *stime = strtoull(fields[12].c_str(), nullptr, 10);
625 *task_cpu = strtoull(fields[36].c_str(), nullptr, 10);
Elliott Hughesbfe487b2011-10-26 15:48:55 -0700626}
627
Mathieu Chartier76433272014-09-26 14:32:37 -0700628std::string PrettyDescriptor(Primitive::Type type) {
629 return PrettyDescriptor(Primitive::Descriptor(type));
630}
631
Nicolas Geoffrayabbb0f72015-10-29 18:55:58 +0000632static void ParseStringAfterChar(const std::string& s,
633 char c,
634 std::string* parsed_value,
635 UsageFn Usage) {
636 std::string::size_type colon = s.find(c);
637 if (colon == std::string::npos) {
638 Usage("Missing char %c in option %s\n", c, s.c_str());
639 }
640 // Add one to remove the char we were trimming until.
641 *parsed_value = s.substr(colon + 1);
642}
643
644void ParseDouble(const std::string& option,
645 char after_char,
646 double min,
647 double max,
648 double* parsed_value,
649 UsageFn Usage) {
650 std::string substring;
651 ParseStringAfterChar(option, after_char, &substring, Usage);
652 bool sane_val = true;
653 double value;
654 if ((false)) {
655 // TODO: this doesn't seem to work on the emulator. b/15114595
656 std::stringstream iss(substring);
657 iss >> value;
658 // Ensure that we have a value, there was no cruft after it and it satisfies a sensible range.
659 sane_val = iss.eof() && (value >= min) && (value <= max);
660 } else {
661 char* end = nullptr;
662 value = strtod(substring.c_str(), &end);
663 sane_val = *end == '\0' && value >= min && value <= max;
664 }
665 if (!sane_val) {
666 Usage("Invalid double value %s for option %s\n", substring.c_str(), option.c_str());
667 }
668 *parsed_value = value;
669}
670
Mathieu Chartier4d87df62016-01-07 15:14:19 -0800671void SleepForever() {
672 while (true) {
673 usleep(1000000);
674 }
675}
676
Elliott Hughes42ee1422011-09-06 12:33:32 -0700677} // namespace art