• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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  */
16 
17 #include "utils.h"
18 
19 #include <inttypes.h>
20 #include <pthread.h>
21 #include <sys/mman.h>  // For madvise
22 #include <sys/stat.h>
23 #include <sys/syscall.h>
24 #include <sys/types.h>
25 #include <sys/wait.h>
26 #include <unistd.h>
27 #include <memory>
28 
29 #include "android-base/stringprintf.h"
30 #include "android-base/strings.h"
31 
32 #include "base/stl_util.h"
33 #include "base/unix_file/fd_file.h"
34 #include "dex_file-inl.h"
35 #include "dex_instruction.h"
36 #include "oat_quick_method_header.h"
37 #include "os.h"
38 #include "scoped_thread_state_change-inl.h"
39 #include "utf-inl.h"
40 
41 #if defined(__APPLE__)
42 #include "AvailabilityMacros.h"  // For MAC_OS_X_VERSION_MAX_ALLOWED
43 #include <sys/syscall.h>
44 #include <crt_externs.h>
45 #endif
46 
47 #if defined(__linux__)
48 #include <linux/unistd.h>
49 #endif
50 
51 namespace art {
52 
53 using android::base::StringAppendF;
54 using android::base::StringPrintf;
55 
GetTid()56 pid_t GetTid() {
57 #if defined(__APPLE__)
58   uint64_t owner;
59   CHECK_PTHREAD_CALL(pthread_threadid_np, (nullptr, &owner), __FUNCTION__);  // Requires Mac OS 10.6
60   return owner;
61 #elif defined(__BIONIC__)
62   return gettid();
63 #else
64   return syscall(__NR_gettid);
65 #endif
66 }
67 
GetThreadName(pid_t tid)68 std::string GetThreadName(pid_t tid) {
69   std::string result;
70   if (ReadFileToString(StringPrintf("/proc/self/task/%d/comm", tid), &result)) {
71     result.resize(result.size() - 1);  // Lose the trailing '\n'.
72   } else {
73     result = "<unknown>";
74   }
75   return result;
76 }
77 
ReadFileToString(const std::string & file_name,std::string * result)78 bool ReadFileToString(const std::string& file_name, std::string* result) {
79   File file(file_name, O_RDONLY, false);
80   if (!file.IsOpened()) {
81     return false;
82   }
83 
84   std::vector<char> buf(8 * KB);
85   while (true) {
86     int64_t n = TEMP_FAILURE_RETRY(read(file.Fd(), &buf[0], buf.size()));
87     if (n == -1) {
88       return false;
89     }
90     if (n == 0) {
91       return true;
92     }
93     result->append(&buf[0], n);
94   }
95 }
96 
PrintFileToLog(const std::string & file_name,LogSeverity level)97 bool PrintFileToLog(const std::string& file_name, LogSeverity level) {
98   File file(file_name, O_RDONLY, false);
99   if (!file.IsOpened()) {
100     return false;
101   }
102 
103   constexpr size_t kBufSize = 256;  // Small buffer. Avoid stack overflow and stack size warnings.
104   char buf[kBufSize + 1];           // +1 for terminator.
105   size_t filled_to = 0;
106   while (true) {
107     DCHECK_LT(filled_to, kBufSize);
108     int64_t n = TEMP_FAILURE_RETRY(read(file.Fd(), &buf[filled_to], kBufSize - filled_to));
109     if (n <= 0) {
110       // Print the rest of the buffer, if it exists.
111       if (filled_to > 0) {
112         buf[filled_to] = 0;
113         LOG(level) << buf;
114       }
115       return n == 0;
116     }
117     // Scan for '\n'.
118     size_t i = filled_to;
119     bool found_newline = false;
120     for (; i < filled_to + n; ++i) {
121       if (buf[i] == '\n') {
122         // Found a line break, that's something to print now.
123         buf[i] = 0;
124         LOG(level) << buf;
125         // Copy the rest to the front.
126         if (i + 1 < filled_to + n) {
127           memmove(&buf[0], &buf[i + 1], filled_to + n - i - 1);
128           filled_to = filled_to + n - i - 1;
129         } else {
130           filled_to = 0;
131         }
132         found_newline = true;
133         break;
134       }
135     }
136     if (found_newline) {
137       continue;
138     } else {
139       filled_to += n;
140       // Check if we must flush now.
141       if (filled_to == kBufSize) {
142         buf[kBufSize] = 0;
143         LOG(level) << buf;
144         filled_to = 0;
145       }
146     }
147   }
148 }
149 
PrettyDescriptor(const char * descriptor)150 std::string PrettyDescriptor(const char* descriptor) {
151   // Count the number of '['s to get the dimensionality.
152   const char* c = descriptor;
153   size_t dim = 0;
154   while (*c == '[') {
155     dim++;
156     c++;
157   }
158 
159   // Reference or primitive?
160   if (*c == 'L') {
161     // "[[La/b/C;" -> "a.b.C[][]".
162     c++;  // Skip the 'L'.
163   } else {
164     // "[[B" -> "byte[][]".
165     // To make life easier, we make primitives look like unqualified
166     // reference types.
167     switch (*c) {
168     case 'B': c = "byte;"; break;
169     case 'C': c = "char;"; break;
170     case 'D': c = "double;"; break;
171     case 'F': c = "float;"; break;
172     case 'I': c = "int;"; break;
173     case 'J': c = "long;"; break;
174     case 'S': c = "short;"; break;
175     case 'Z': c = "boolean;"; break;
176     case 'V': c = "void;"; break;  // Used when decoding return types.
177     default: return descriptor;
178     }
179   }
180 
181   // At this point, 'c' is a string of the form "fully/qualified/Type;"
182   // or "primitive;". Rewrite the type with '.' instead of '/':
183   std::string result;
184   const char* p = c;
185   while (*p != ';') {
186     char ch = *p++;
187     if (ch == '/') {
188       ch = '.';
189     }
190     result.push_back(ch);
191   }
192   // ...and replace the semicolon with 'dim' "[]" pairs:
193   for (size_t i = 0; i < dim; ++i) {
194     result += "[]";
195   }
196   return result;
197 }
198 
PrettyArguments(const char * signature)199 std::string PrettyArguments(const char* signature) {
200   std::string result;
201   result += '(';
202   CHECK_EQ(*signature, '(');
203   ++signature;  // Skip the '('.
204   while (*signature != ')') {
205     size_t argument_length = 0;
206     while (signature[argument_length] == '[') {
207       ++argument_length;
208     }
209     if (signature[argument_length] == 'L') {
210       argument_length = (strchr(signature, ';') - signature + 1);
211     } else {
212       ++argument_length;
213     }
214     {
215       std::string argument_descriptor(signature, argument_length);
216       result += PrettyDescriptor(argument_descriptor.c_str());
217     }
218     if (signature[argument_length] != ')') {
219       result += ", ";
220     }
221     signature += argument_length;
222   }
223   CHECK_EQ(*signature, ')');
224   ++signature;  // Skip the ')'.
225   result += ')';
226   return result;
227 }
228 
PrettyReturnType(const char * signature)229 std::string PrettyReturnType(const char* signature) {
230   const char* return_type = strchr(signature, ')');
231   CHECK(return_type != nullptr);
232   ++return_type;  // Skip ')'.
233   return PrettyDescriptor(return_type);
234 }
235 
PrettyJavaAccessFlags(uint32_t access_flags)236 std::string PrettyJavaAccessFlags(uint32_t access_flags) {
237   std::string result;
238   if ((access_flags & kAccPublic) != 0) {
239     result += "public ";
240   }
241   if ((access_flags & kAccProtected) != 0) {
242     result += "protected ";
243   }
244   if ((access_flags & kAccPrivate) != 0) {
245     result += "private ";
246   }
247   if ((access_flags & kAccFinal) != 0) {
248     result += "final ";
249   }
250   if ((access_flags & kAccStatic) != 0) {
251     result += "static ";
252   }
253   if ((access_flags & kAccAbstract) != 0) {
254     result += "abstract ";
255   }
256   if ((access_flags & kAccInterface) != 0) {
257     result += "interface ";
258   }
259   if ((access_flags & kAccTransient) != 0) {
260     result += "transient ";
261   }
262   if ((access_flags & kAccVolatile) != 0) {
263     result += "volatile ";
264   }
265   if ((access_flags & kAccSynchronized) != 0) {
266     result += "synchronized ";
267   }
268   return result;
269 }
270 
PrettySize(int64_t byte_count)271 std::string PrettySize(int64_t byte_count) {
272   // The byte thresholds at which we display amounts.  A byte count is displayed
273   // in unit U when kUnitThresholds[U] <= bytes < kUnitThresholds[U+1].
274   static const int64_t kUnitThresholds[] = {
275     0,              // B up to...
276     3*1024,         // KB up to...
277     2*1024*1024,    // MB up to...
278     1024*1024*1024  // GB from here.
279   };
280   static const int64_t kBytesPerUnit[] = { 1, KB, MB, GB };
281   static const char* const kUnitStrings[] = { "B", "KB", "MB", "GB" };
282   const char* negative_str = "";
283   if (byte_count < 0) {
284     negative_str = "-";
285     byte_count = -byte_count;
286   }
287   int i = arraysize(kUnitThresholds);
288   while (--i > 0) {
289     if (byte_count >= kUnitThresholds[i]) {
290       break;
291     }
292   }
293   return StringPrintf("%s%" PRId64 "%s",
294                       negative_str, byte_count / kBytesPerUnit[i], kUnitStrings[i]);
295 }
296 
NeedsEscaping(uint16_t ch)297 static inline constexpr bool NeedsEscaping(uint16_t ch) {
298   return (ch < ' ' || ch > '~');
299 }
300 
PrintableChar(uint16_t ch)301 std::string PrintableChar(uint16_t ch) {
302   std::string result;
303   result += '\'';
304   if (NeedsEscaping(ch)) {
305     StringAppendF(&result, "\\u%04x", ch);
306   } else {
307     result += static_cast<std::string::value_type>(ch);
308   }
309   result += '\'';
310   return result;
311 }
312 
PrintableString(const char * utf)313 std::string PrintableString(const char* utf) {
314   std::string result;
315   result += '"';
316   const char* p = utf;
317   size_t char_count = CountModifiedUtf8Chars(p);
318   for (size_t i = 0; i < char_count; ++i) {
319     uint32_t ch = GetUtf16FromUtf8(&p);
320     if (ch == '\\') {
321       result += "\\\\";
322     } else if (ch == '\n') {
323       result += "\\n";
324     } else if (ch == '\r') {
325       result += "\\r";
326     } else if (ch == '\t') {
327       result += "\\t";
328     } else {
329       const uint16_t leading = GetLeadingUtf16Char(ch);
330 
331       if (NeedsEscaping(leading)) {
332         StringAppendF(&result, "\\u%04x", leading);
333       } else {
334         result += static_cast<std::string::value_type>(leading);
335       }
336 
337       const uint32_t trailing = GetTrailingUtf16Char(ch);
338       if (trailing != 0) {
339         // All high surrogates will need escaping.
340         StringAppendF(&result, "\\u%04x", trailing);
341       }
342     }
343   }
344   result += '"';
345   return result;
346 }
347 
GetJniShortName(const std::string & class_descriptor,const std::string & method)348 std::string GetJniShortName(const std::string& class_descriptor, const std::string& method) {
349   // Remove the leading 'L' and trailing ';'...
350   std::string class_name(class_descriptor);
351   CHECK_EQ(class_name[0], 'L') << class_name;
352   CHECK_EQ(class_name[class_name.size() - 1], ';') << class_name;
353   class_name.erase(0, 1);
354   class_name.erase(class_name.size() - 1, 1);
355 
356   std::string short_name;
357   short_name += "Java_";
358   short_name += MangleForJni(class_name);
359   short_name += "_";
360   short_name += MangleForJni(method);
361   return short_name;
362 }
363 
364 // See http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/design.html#wp615 for the full rules.
MangleForJni(const std::string & s)365 std::string MangleForJni(const std::string& s) {
366   std::string result;
367   size_t char_count = CountModifiedUtf8Chars(s.c_str());
368   const char* cp = &s[0];
369   for (size_t i = 0; i < char_count; ++i) {
370     uint32_t ch = GetUtf16FromUtf8(&cp);
371     if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')) {
372       result.push_back(ch);
373     } else if (ch == '.' || ch == '/') {
374       result += "_";
375     } else if (ch == '_') {
376       result += "_1";
377     } else if (ch == ';') {
378       result += "_2";
379     } else if (ch == '[') {
380       result += "_3";
381     } else {
382       const uint16_t leading = GetLeadingUtf16Char(ch);
383       const uint32_t trailing = GetTrailingUtf16Char(ch);
384 
385       StringAppendF(&result, "_0%04x", leading);
386       if (trailing != 0) {
387         StringAppendF(&result, "_0%04x", trailing);
388       }
389     }
390   }
391   return result;
392 }
393 
DotToDescriptor(const char * class_name)394 std::string DotToDescriptor(const char* class_name) {
395   std::string descriptor(class_name);
396   std::replace(descriptor.begin(), descriptor.end(), '.', '/');
397   if (descriptor.length() > 0 && descriptor[0] != '[') {
398     descriptor = "L" + descriptor + ";";
399   }
400   return descriptor;
401 }
402 
DescriptorToDot(const char * descriptor)403 std::string DescriptorToDot(const char* descriptor) {
404   size_t length = strlen(descriptor);
405   if (length > 1) {
406     if (descriptor[0] == 'L' && descriptor[length - 1] == ';') {
407       // Descriptors have the leading 'L' and trailing ';' stripped.
408       std::string result(descriptor + 1, length - 2);
409       std::replace(result.begin(), result.end(), '/', '.');
410       return result;
411     } else {
412       // For arrays the 'L' and ';' remain intact.
413       std::string result(descriptor);
414       std::replace(result.begin(), result.end(), '/', '.');
415       return result;
416     }
417   }
418   // Do nothing for non-class/array descriptors.
419   return descriptor;
420 }
421 
DescriptorToName(const char * descriptor)422 std::string DescriptorToName(const char* descriptor) {
423   size_t length = strlen(descriptor);
424   if (descriptor[0] == 'L' && descriptor[length - 1] == ';') {
425     std::string result(descriptor + 1, length - 2);
426     return result;
427   }
428   return descriptor;
429 }
430 
431 // Helper for IsValidPartOfMemberNameUtf8(), a bit vector indicating valid low ascii.
432 uint32_t DEX_MEMBER_VALID_LOW_ASCII[4] = {
433   0x00000000,  // 00..1f low control characters; nothing valid
434   0x03ff2010,  // 20..3f digits and symbols; valid: '0'..'9', '$', '-'
435   0x87fffffe,  // 40..5f uppercase etc.; valid: 'A'..'Z', '_'
436   0x07fffffe   // 60..7f lowercase etc.; valid: 'a'..'z'
437 };
438 
439 // Helper for IsValidPartOfMemberNameUtf8(); do not call directly.
IsValidPartOfMemberNameUtf8Slow(const char ** pUtf8Ptr)440 bool IsValidPartOfMemberNameUtf8Slow(const char** pUtf8Ptr) {
441   /*
442    * It's a multibyte encoded character. Decode it and analyze. We
443    * accept anything that isn't (a) an improperly encoded low value,
444    * (b) an improper surrogate pair, (c) an encoded '\0', (d) a high
445    * control character, or (e) a high space, layout, or special
446    * character (U+00a0, U+2000..U+200f, U+2028..U+202f,
447    * U+fff0..U+ffff). This is all specified in the dex format
448    * document.
449    */
450 
451   const uint32_t pair = GetUtf16FromUtf8(pUtf8Ptr);
452   const uint16_t leading = GetLeadingUtf16Char(pair);
453 
454   // We have a surrogate pair resulting from a valid 4 byte UTF sequence.
455   // No further checks are necessary because 4 byte sequences span code
456   // points [U+10000, U+1FFFFF], which are valid codepoints in a dex
457   // identifier. Furthermore, GetUtf16FromUtf8 guarantees that each of
458   // the surrogate halves are valid and well formed in this instance.
459   if (GetTrailingUtf16Char(pair) != 0) {
460     return true;
461   }
462 
463 
464   // We've encountered a one, two or three byte UTF-8 sequence. The
465   // three byte UTF-8 sequence could be one half of a surrogate pair.
466   switch (leading >> 8) {
467     case 0x00:
468       // It's only valid if it's above the ISO-8859-1 high space (0xa0).
469       return (leading > 0x00a0);
470     case 0xd8:
471     case 0xd9:
472     case 0xda:
473     case 0xdb:
474       {
475         // We found a three byte sequence encoding one half of a surrogate.
476         // Look for the other half.
477         const uint32_t pair2 = GetUtf16FromUtf8(pUtf8Ptr);
478         const uint16_t trailing = GetLeadingUtf16Char(pair2);
479 
480         return (GetTrailingUtf16Char(pair2) == 0) && (0xdc00 <= trailing && trailing <= 0xdfff);
481       }
482     case 0xdc:
483     case 0xdd:
484     case 0xde:
485     case 0xdf:
486       // It's a trailing surrogate, which is not valid at this point.
487       return false;
488     case 0x20:
489     case 0xff:
490       // It's in the range that has spaces, controls, and specials.
491       switch (leading & 0xfff8) {
492         case 0x2000:
493         case 0x2008:
494         case 0x2028:
495         case 0xfff0:
496         case 0xfff8:
497           return false;
498       }
499       return true;
500     default:
501       return true;
502   }
503 
504   UNREACHABLE();
505 }
506 
507 /* Return whether the pointed-at modified-UTF-8 encoded character is
508  * valid as part of a member name, updating the pointer to point past
509  * the consumed character. This will consume two encoded UTF-16 code
510  * points if the character is encoded as a surrogate pair. Also, if
511  * this function returns false, then the given pointer may only have
512  * been partially advanced.
513  */
IsValidPartOfMemberNameUtf8(const char ** pUtf8Ptr)514 static bool IsValidPartOfMemberNameUtf8(const char** pUtf8Ptr) {
515   uint8_t c = (uint8_t) **pUtf8Ptr;
516   if (LIKELY(c <= 0x7f)) {
517     // It's low-ascii, so check the table.
518     uint32_t wordIdx = c >> 5;
519     uint32_t bitIdx = c & 0x1f;
520     (*pUtf8Ptr)++;
521     return (DEX_MEMBER_VALID_LOW_ASCII[wordIdx] & (1 << bitIdx)) != 0;
522   }
523 
524   // It's a multibyte encoded character. Call a non-inline function
525   // for the heavy lifting.
526   return IsValidPartOfMemberNameUtf8Slow(pUtf8Ptr);
527 }
528 
IsValidMemberName(const char * s)529 bool IsValidMemberName(const char* s) {
530   bool angle_name = false;
531 
532   switch (*s) {
533     case '\0':
534       // The empty string is not a valid name.
535       return false;
536     case '<':
537       angle_name = true;
538       s++;
539       break;
540   }
541 
542   while (true) {
543     switch (*s) {
544       case '\0':
545         return !angle_name;
546       case '>':
547         return angle_name && s[1] == '\0';
548     }
549 
550     if (!IsValidPartOfMemberNameUtf8(&s)) {
551       return false;
552     }
553   }
554 }
555 
556 enum ClassNameType { kName, kDescriptor };
557 template<ClassNameType kType, char kSeparator>
IsValidClassName(const char * s)558 static bool IsValidClassName(const char* s) {
559   int arrayCount = 0;
560   while (*s == '[') {
561     arrayCount++;
562     s++;
563   }
564 
565   if (arrayCount > 255) {
566     // Arrays may have no more than 255 dimensions.
567     return false;
568   }
569 
570   ClassNameType type = kType;
571   if (type != kDescriptor && arrayCount != 0) {
572     /*
573      * If we're looking at an array of some sort, then it doesn't
574      * matter if what is being asked for is a class name; the
575      * format looks the same as a type descriptor in that case, so
576      * treat it as such.
577      */
578     type = kDescriptor;
579   }
580 
581   if (type == kDescriptor) {
582     /*
583      * We are looking for a descriptor. Either validate it as a
584      * single-character primitive type, or continue on to check the
585      * embedded class name (bracketed by "L" and ";").
586      */
587     switch (*(s++)) {
588     case 'B':
589     case 'C':
590     case 'D':
591     case 'F':
592     case 'I':
593     case 'J':
594     case 'S':
595     case 'Z':
596       // These are all single-character descriptors for primitive types.
597       return (*s == '\0');
598     case 'V':
599       // Non-array void is valid, but you can't have an array of void.
600       return (arrayCount == 0) && (*s == '\0');
601     case 'L':
602       // Class name: Break out and continue below.
603       break;
604     default:
605       // Oddball descriptor character.
606       return false;
607     }
608   }
609 
610   /*
611    * We just consumed the 'L' that introduces a class name as part
612    * of a type descriptor, or we are looking for an unadorned class
613    * name.
614    */
615 
616   bool sepOrFirst = true;  // first character or just encountered a separator.
617   for (;;) {
618     uint8_t c = (uint8_t) *s;
619     switch (c) {
620     case '\0':
621       /*
622        * Premature end for a type descriptor, but valid for
623        * a class name as long as we haven't encountered an
624        * empty component (including the degenerate case of
625        * the empty string "").
626        */
627       return (type == kName) && !sepOrFirst;
628     case ';':
629       /*
630        * Invalid character for a class name, but the
631        * legitimate end of a type descriptor. In the latter
632        * case, make sure that this is the end of the string
633        * and that it doesn't end with an empty component
634        * (including the degenerate case of "L;").
635        */
636       return (type == kDescriptor) && !sepOrFirst && (s[1] == '\0');
637     case '/':
638     case '.':
639       if (c != kSeparator) {
640         // The wrong separator character.
641         return false;
642       }
643       if (sepOrFirst) {
644         // Separator at start or two separators in a row.
645         return false;
646       }
647       sepOrFirst = true;
648       s++;
649       break;
650     default:
651       if (!IsValidPartOfMemberNameUtf8(&s)) {
652         return false;
653       }
654       sepOrFirst = false;
655       break;
656     }
657   }
658 }
659 
IsValidBinaryClassName(const char * s)660 bool IsValidBinaryClassName(const char* s) {
661   return IsValidClassName<kName, '.'>(s);
662 }
663 
IsValidJniClassName(const char * s)664 bool IsValidJniClassName(const char* s) {
665   return IsValidClassName<kName, '/'>(s);
666 }
667 
IsValidDescriptor(const char * s)668 bool IsValidDescriptor(const char* s) {
669   return IsValidClassName<kDescriptor, '/'>(s);
670 }
671 
Split(const std::string & s,char separator,std::vector<std::string> * result)672 void Split(const std::string& s, char separator, std::vector<std::string>* result) {
673   const char* p = s.data();
674   const char* end = p + s.size();
675   while (p != end) {
676     if (*p == separator) {
677       ++p;
678     } else {
679       const char* start = p;
680       while (++p != end && *p != separator) {
681         // Skip to the next occurrence of the separator.
682       }
683       result->push_back(std::string(start, p - start));
684     }
685   }
686 }
687 
SetThreadName(const char * thread_name)688 void SetThreadName(const char* thread_name) {
689   int hasAt = 0;
690   int hasDot = 0;
691   const char* s = thread_name;
692   while (*s) {
693     if (*s == '.') {
694       hasDot = 1;
695     } else if (*s == '@') {
696       hasAt = 1;
697     }
698     s++;
699   }
700   int len = s - thread_name;
701   if (len < 15 || hasAt || !hasDot) {
702     s = thread_name;
703   } else {
704     s = thread_name + len - 15;
705   }
706 #if defined(__linux__)
707   // pthread_setname_np fails rather than truncating long strings.
708   char buf[16];       // MAX_TASK_COMM_LEN=16 is hard-coded in the kernel.
709   strncpy(buf, s, sizeof(buf)-1);
710   buf[sizeof(buf)-1] = '\0';
711   errno = pthread_setname_np(pthread_self(), buf);
712   if (errno != 0) {
713     PLOG(WARNING) << "Unable to set the name of current thread to '" << buf << "'";
714   }
715 #else  // __APPLE__
716   pthread_setname_np(thread_name);
717 #endif
718 }
719 
GetTaskStats(pid_t tid,char * state,int * utime,int * stime,int * task_cpu)720 void GetTaskStats(pid_t tid, char* state, int* utime, int* stime, int* task_cpu) {
721   *utime = *stime = *task_cpu = 0;
722   std::string stats;
723   if (!ReadFileToString(StringPrintf("/proc/self/task/%d/stat", tid), &stats)) {
724     return;
725   }
726   // Skip the command, which may contain spaces.
727   stats = stats.substr(stats.find(')') + 2);
728   // Extract the three fields we care about.
729   std::vector<std::string> fields;
730   Split(stats, ' ', &fields);
731   *state = fields[0][0];
732   *utime = strtoull(fields[11].c_str(), nullptr, 10);
733   *stime = strtoull(fields[12].c_str(), nullptr, 10);
734   *task_cpu = strtoull(fields[36].c_str(), nullptr, 10);
735 }
736 
GetAndroidDirSafe(const char * env_var,const char * default_dir,std::string * error_msg)737 static const char* GetAndroidDirSafe(const char* env_var,
738                                      const char* default_dir,
739                                      std::string* error_msg) {
740   const char* android_dir = getenv(env_var);
741   if (android_dir == nullptr) {
742     if (OS::DirectoryExists(default_dir)) {
743       android_dir = default_dir;
744     } else {
745       *error_msg = StringPrintf("%s not set and %s does not exist", env_var, default_dir);
746       return nullptr;
747     }
748   }
749   if (!OS::DirectoryExists(android_dir)) {
750     *error_msg = StringPrintf("Failed to find %s directory %s", env_var, android_dir);
751     return nullptr;
752   }
753   return android_dir;
754 }
755 
GetAndroidDir(const char * env_var,const char * default_dir)756 const char* GetAndroidDir(const char* env_var, const char* default_dir) {
757   std::string error_msg;
758   const char* dir = GetAndroidDirSafe(env_var, default_dir, &error_msg);
759   if (dir != nullptr) {
760     return dir;
761   } else {
762     LOG(FATAL) << error_msg;
763     return nullptr;
764   }
765 }
766 
GetAndroidRoot()767 const char* GetAndroidRoot() {
768   return GetAndroidDir("ANDROID_ROOT", "/system");
769 }
770 
GetAndroidRootSafe(std::string * error_msg)771 const char* GetAndroidRootSafe(std::string* error_msg) {
772   return GetAndroidDirSafe("ANDROID_ROOT", "/system", error_msg);
773 }
774 
GetAndroidData()775 const char* GetAndroidData() {
776   return GetAndroidDir("ANDROID_DATA", "/data");
777 }
778 
GetAndroidDataSafe(std::string * error_msg)779 const char* GetAndroidDataSafe(std::string* error_msg) {
780   return GetAndroidDirSafe("ANDROID_DATA", "/data", error_msg);
781 }
782 
GetDefaultBootImageLocation(std::string * error_msg)783 std::string GetDefaultBootImageLocation(std::string* error_msg) {
784   const char* android_root = GetAndroidRootSafe(error_msg);
785   if (android_root == nullptr) {
786     return "";
787   }
788   return StringPrintf("%s/framework/boot.art", android_root);
789 }
790 
GetDalvikCache(const char * subdir,const bool create_if_absent,std::string * dalvik_cache,bool * have_android_data,bool * dalvik_cache_exists,bool * is_global_cache)791 void GetDalvikCache(const char* subdir, const bool create_if_absent, std::string* dalvik_cache,
792                     bool* have_android_data, bool* dalvik_cache_exists, bool* is_global_cache) {
793   CHECK(subdir != nullptr);
794   std::string error_msg;
795   const char* android_data = GetAndroidDataSafe(&error_msg);
796   if (android_data == nullptr) {
797     *have_android_data = false;
798     *dalvik_cache_exists = false;
799     *is_global_cache = false;
800     return;
801   } else {
802     *have_android_data = true;
803   }
804   const std::string dalvik_cache_root(StringPrintf("%s/dalvik-cache/", android_data));
805   *dalvik_cache = dalvik_cache_root + subdir;
806   *dalvik_cache_exists = OS::DirectoryExists(dalvik_cache->c_str());
807   *is_global_cache = strcmp(android_data, "/data") == 0;
808   if (create_if_absent && !*dalvik_cache_exists && !*is_global_cache) {
809     // Don't create the system's /data/dalvik-cache/... because it needs special permissions.
810     *dalvik_cache_exists = ((mkdir(dalvik_cache_root.c_str(), 0700) == 0 || errno == EEXIST) &&
811                             (mkdir(dalvik_cache->c_str(), 0700) == 0 || errno == EEXIST));
812   }
813 }
814 
GetDalvikCache(const char * subdir)815 std::string GetDalvikCache(const char* subdir) {
816   CHECK(subdir != nullptr);
817   const char* android_data = GetAndroidData();
818   const std::string dalvik_cache_root(StringPrintf("%s/dalvik-cache/", android_data));
819   const std::string dalvik_cache = dalvik_cache_root + subdir;
820   if (!OS::DirectoryExists(dalvik_cache.c_str())) {
821     // TODO: Check callers. Traditional behavior is to not abort.
822     return "";
823   }
824   return dalvik_cache;
825 }
826 
GetDalvikCacheFilename(const char * location,const char * cache_location,std::string * filename,std::string * error_msg)827 bool GetDalvikCacheFilename(const char* location, const char* cache_location,
828                             std::string* filename, std::string* error_msg) {
829   if (location[0] != '/') {
830     *error_msg = StringPrintf("Expected path in location to be absolute: %s", location);
831     return false;
832   }
833   std::string cache_file(&location[1]);  // skip leading slash
834   if (!android::base::EndsWith(location, ".dex") &&
835       !android::base::EndsWith(location, ".art") &&
836       !android::base::EndsWith(location, ".oat")) {
837     cache_file += "/";
838     cache_file += DexFile::kClassesDex;
839   }
840   std::replace(cache_file.begin(), cache_file.end(), '/', '@');
841   *filename = StringPrintf("%s/%s", cache_location, cache_file.c_str());
842   return true;
843 }
844 
GetVdexFilename(const std::string & oat_location)845 std::string GetVdexFilename(const std::string& oat_location) {
846   return ReplaceFileExtension(oat_location, "vdex");
847 }
848 
InsertIsaDirectory(const InstructionSet isa,std::string * filename)849 static void InsertIsaDirectory(const InstructionSet isa, std::string* filename) {
850   // in = /foo/bar/baz
851   // out = /foo/bar/<isa>/baz
852   size_t pos = filename->rfind('/');
853   CHECK_NE(pos, std::string::npos) << *filename << " " << isa;
854   filename->insert(pos, "/", 1);
855   filename->insert(pos + 1, GetInstructionSetString(isa));
856 }
857 
GetSystemImageFilename(const char * location,const InstructionSet isa)858 std::string GetSystemImageFilename(const char* location, const InstructionSet isa) {
859   // location = /system/framework/boot.art
860   // filename = /system/framework/<isa>/boot.art
861   std::string filename(location);
862   InsertIsaDirectory(isa, &filename);
863   return filename;
864 }
865 
FileExists(const std::string & filename)866 bool FileExists(const std::string& filename) {
867   struct stat buffer;
868   return stat(filename.c_str(), &buffer) == 0;
869 }
870 
FileExistsAndNotEmpty(const std::string & filename)871 bool FileExistsAndNotEmpty(const std::string& filename) {
872   struct stat buffer;
873   if (stat(filename.c_str(), &buffer) != 0) {
874     return false;
875   }
876   return buffer.st_size > 0;
877 }
878 
ReplaceFileExtension(const std::string & filename,const std::string & new_extension)879 std::string ReplaceFileExtension(const std::string& filename, const std::string& new_extension) {
880   const size_t last_ext = filename.find_last_of('.');
881   if (last_ext == std::string::npos) {
882     return filename + "." + new_extension;
883   } else {
884     return filename.substr(0, last_ext + 1) + new_extension;
885   }
886 }
887 
PrettyDescriptor(Primitive::Type type)888 std::string PrettyDescriptor(Primitive::Type type) {
889   return PrettyDescriptor(Primitive::Descriptor(type));
890 }
891 
ParseStringAfterChar(const std::string & s,char c,std::string * parsed_value,UsageFn Usage)892 static void ParseStringAfterChar(const std::string& s,
893                                  char c,
894                                  std::string* parsed_value,
895                                  UsageFn Usage) {
896   std::string::size_type colon = s.find(c);
897   if (colon == std::string::npos) {
898     Usage("Missing char %c in option %s\n", c, s.c_str());
899   }
900   // Add one to remove the char we were trimming until.
901   *parsed_value = s.substr(colon + 1);
902 }
903 
ParseDouble(const std::string & option,char after_char,double min,double max,double * parsed_value,UsageFn Usage)904 void ParseDouble(const std::string& option,
905                  char after_char,
906                  double min,
907                  double max,
908                  double* parsed_value,
909                  UsageFn Usage) {
910   std::string substring;
911   ParseStringAfterChar(option, after_char, &substring, Usage);
912   bool sane_val = true;
913   double value;
914   if ((false)) {
915     // TODO: this doesn't seem to work on the emulator.  b/15114595
916     std::stringstream iss(substring);
917     iss >> value;
918     // Ensure that we have a value, there was no cruft after it and it satisfies a sensible range.
919     sane_val = iss.eof() && (value >= min) && (value <= max);
920   } else {
921     char* end = nullptr;
922     value = strtod(substring.c_str(), &end);
923     sane_val = *end == '\0' && value >= min && value <= max;
924   }
925   if (!sane_val) {
926     Usage("Invalid double value %s for option %s\n", substring.c_str(), option.c_str());
927   }
928   *parsed_value = value;
929 }
930 
GetFileSizeBytes(const std::string & filename)931 int64_t GetFileSizeBytes(const std::string& filename) {
932   struct stat stat_buf;
933   int rc = stat(filename.c_str(), &stat_buf);
934   return rc == 0 ? stat_buf.st_size : -1;
935 }
936 
SleepForever()937 void SleepForever() {
938   while (true) {
939     usleep(1000000);
940   }
941 }
942 
MadviseLargestPageAlignedRegion(const uint8_t * begin,const uint8_t * end,int advice)943 int MadviseLargestPageAlignedRegion(const uint8_t* begin, const uint8_t* end, int advice) {
944   DCHECK_LE(begin, end);
945   begin = AlignUp(begin, kPageSize);
946   end = AlignDown(end, kPageSize);
947   if (begin < end) {
948     int result = madvise(const_cast<uint8_t*>(begin), end - begin, advice);
949     if (result != 0) {
950       PLOG(WARNING) << "madvise failed " << result;
951     }
952     return result;
953   }
954   return 0;
955 }
956 
957 }  // namespace art
958