blob: 6ed54f748f2d9d896d02ddfaa601c4317c14df26 [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>
Ian Rogers700a4022014-05-19 16:49:03 -070026#include <memory>
Elliott Hughes42ee1422011-09-06 12:33:32 -070027
Brian Carlstrom6449c622014-02-10 23:48:36 -080028#include "base/stl_util.h"
Elliott Hughes76160052012-12-12 16:31:20 -080029#include "base/unix_file/fd_file.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070030#include "dex_file-inl.h"
Andreas Gampe5073fed2015-08-10 11:40:25 -070031#include "dex_instruction.h"
Nicolas Geoffray524e7ea2015-10-16 17:13:34 +010032#include "oat_quick_method_header.h"
buzbeec143c552011-08-20 17:38:58 -070033#include "os.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070034#include "scoped_thread_state_change-inl.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__)
Brian Carlstrom7934ac22013-07-26 10:54:15 -070038#include "AvailabilityMacros.h" // For MAC_OS_X_VERSION_MAX_ALLOWED
Elliott Hughesf1498432012-03-28 19:34:27 -070039#include <sys/syscall.h>
Elliott Hughes4ae722a2012-03-13 11:08:51 -070040#endif
41
Elliott Hughes058a6de2012-05-24 19:13:02 -070042#if defined(__linux__)
Elliott Hughese1aee692012-01-17 16:40:10 -080043#include <linux/unistd.h>
Elliott Hughese1aee692012-01-17 16:40:10 -080044#endif
45
Elliott Hughes11e45072011-08-16 17:40:46 -070046namespace art {
47
Alex Light9c20a142016-08-23 15:05:12 -070048static const uint8_t kBase64Map[256] = {
49 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
50 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
51 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
52 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
53 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
54 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
55 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, // NOLINT
56 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, // NOLINT
57 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
58 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, // NOLINT
59 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, // NOLINT
60 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
61 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
62 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
63 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
64 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
65 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
66 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
67 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
68 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
69 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
70 255, 255, 255, 255
71};
72
73uint8_t* DecodeBase64(const char* src, size_t* dst_size) {
74 std::vector<uint8_t> tmp;
75 uint32_t t = 0, y = 0;
76 int g = 3;
77 for (size_t i = 0; src[i] != '\0'; ++i) {
78 uint8_t c = kBase64Map[src[i] & 0xFF];
79 if (c == 255) continue;
80 // the final = symbols are read and used to trim the remaining bytes
81 if (c == 254) {
82 c = 0;
83 // prevent g < 0 which would potentially allow an overflow later
84 if (--g < 0) {
85 *dst_size = 0;
86 return nullptr;
87 }
88 } else if (g != 3) {
89 // we only allow = to be at the end
90 *dst_size = 0;
91 return nullptr;
92 }
93 t = (t << 6) | c;
94 if (++y == 4) {
95 tmp.push_back((t >> 16) & 255);
96 if (g > 1) {
97 tmp.push_back((t >> 8) & 255);
98 }
99 if (g > 2) {
100 tmp.push_back(t & 255);
101 }
102 y = t = 0;
103 }
104 }
105 if (y != 0) {
106 *dst_size = 0;
107 return nullptr;
108 }
109 std::unique_ptr<uint8_t[]> dst(new uint8_t[tmp.size()]);
110 if (dst_size != nullptr) {
111 *dst_size = tmp.size();
112 } else {
113 *dst_size = 0;
114 }
115 std::copy(tmp.begin(), tmp.end(), dst.get());
116 return dst.release();
117}
118
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800119pid_t GetTid() {
Brian Carlstromf3a26412012-08-24 11:06:02 -0700120#if defined(__APPLE__)
121 uint64_t owner;
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700122 CHECK_PTHREAD_CALL(pthread_threadid_np, (nullptr, &owner), __FUNCTION__); // Requires Mac OS 10.6
Brian Carlstromf3a26412012-08-24 11:06:02 -0700123 return owner;
Elliott Hughes323aa862014-08-20 15:00:04 -0700124#elif defined(__BIONIC__)
125 return gettid();
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800126#else
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800127 return syscall(__NR_gettid);
128#endif
129}
130
Elliott Hughes289be852012-06-12 13:57:20 -0700131std::string GetThreadName(pid_t tid) {
132 std::string result;
133 if (ReadFileToString(StringPrintf("/proc/self/task/%d/comm", tid), &result)) {
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700134 result.resize(result.size() - 1); // Lose the trailing '\n'.
Elliott Hughes289be852012-06-12 13:57:20 -0700135 } else {
136 result = "<unknown>";
137 }
138 return result;
139}
140
Elliott Hughes6d3fc562014-08-27 11:47:01 -0700141void GetThreadStack(pthread_t thread, void** stack_base, size_t* stack_size, size_t* guard_size) {
Elliott Hughese1884192012-04-23 12:38:15 -0700142#if defined(__APPLE__)
Brian Carlstrom29212012013-09-12 22:18:30 -0700143 *stack_size = pthread_get_stacksize_np(thread);
Ian Rogers120f1c72012-09-28 17:17:10 -0700144 void* stack_addr = pthread_get_stackaddr_np(thread);
Elliott Hughese1884192012-04-23 12:38:15 -0700145
146 // Check whether stack_addr is the base or end of the stack.
147 // (On Mac OS 10.7, it's the end.)
148 int stack_variable;
149 if (stack_addr > &stack_variable) {
Ian Rogers13735952014-10-08 12:43:28 -0700150 *stack_base = reinterpret_cast<uint8_t*>(stack_addr) - *stack_size;
Elliott Hughese1884192012-04-23 12:38:15 -0700151 } else {
Brian Carlstrom29212012013-09-12 22:18:30 -0700152 *stack_base = stack_addr;
Elliott Hughese1884192012-04-23 12:38:15 -0700153 }
Elliott Hughes6d3fc562014-08-27 11:47:01 -0700154
155 // This is wrong, but there doesn't seem to be a way to get the actual value on the Mac.
156 pthread_attr_t attributes;
157 CHECK_PTHREAD_CALL(pthread_attr_init, (&attributes), __FUNCTION__);
158 CHECK_PTHREAD_CALL(pthread_attr_getguardsize, (&attributes, guard_size), __FUNCTION__);
159 CHECK_PTHREAD_CALL(pthread_attr_destroy, (&attributes), __FUNCTION__);
Elliott Hughese1884192012-04-23 12:38:15 -0700160#else
161 pthread_attr_t attributes;
Ian Rogers120f1c72012-09-28 17:17:10 -0700162 CHECK_PTHREAD_CALL(pthread_getattr_np, (thread, &attributes), __FUNCTION__);
Brian Carlstrom29212012013-09-12 22:18:30 -0700163 CHECK_PTHREAD_CALL(pthread_attr_getstack, (&attributes, stack_base, stack_size), __FUNCTION__);
Elliott Hughes6d3fc562014-08-27 11:47:01 -0700164 CHECK_PTHREAD_CALL(pthread_attr_getguardsize, (&attributes, guard_size), __FUNCTION__);
Elliott Hughese1884192012-04-23 12:38:15 -0700165 CHECK_PTHREAD_CALL(pthread_attr_destroy, (&attributes), __FUNCTION__);
Elliott Hughes839cc302014-08-28 10:24:44 -0700166
167#if defined(__GLIBC__)
168 // If we're the main thread, check whether we were run with an unlimited stack. In that case,
169 // glibc will have reported a 2GB stack for our 32-bit process, and our stack overflow detection
170 // will be broken because we'll die long before we get close to 2GB.
171 bool is_main_thread = (::art::GetTid() == getpid());
172 if (is_main_thread) {
173 rlimit stack_limit;
174 if (getrlimit(RLIMIT_STACK, &stack_limit) == -1) {
175 PLOG(FATAL) << "getrlimit(RLIMIT_STACK) failed";
176 }
177 if (stack_limit.rlim_cur == RLIM_INFINITY) {
178 size_t old_stack_size = *stack_size;
179
180 // Use the kernel default limit as our size, and adjust the base to match.
181 *stack_size = 8 * MB;
182 *stack_base = reinterpret_cast<uint8_t*>(*stack_base) + (old_stack_size - *stack_size);
183
184 VLOG(threads) << "Limiting unlimited stack (reported as " << PrettySize(old_stack_size) << ")"
185 << " to " << PrettySize(*stack_size)
186 << " with base " << *stack_base;
187 }
188 }
189#endif
190
Elliott Hughese1884192012-04-23 12:38:15 -0700191#endif
192}
193
Elliott Hughesd92bec42011-09-02 17:04:36 -0700194bool ReadFileToString(const std::string& file_name, std::string* result) {
Andreas Gampedf878922015-08-13 16:44:54 -0700195 File file(file_name, O_RDONLY, false);
196 if (!file.IsOpened()) {
Elliott Hughesd92bec42011-09-02 17:04:36 -0700197 return false;
198 }
buzbeec143c552011-08-20 17:38:58 -0700199
Elliott Hughes3b6baaa2011-10-14 19:13:56 -0700200 std::vector<char> buf(8 * KB);
buzbeec143c552011-08-20 17:38:58 -0700201 while (true) {
Andreas Gampea6dfdae2015-02-24 15:50:19 -0800202 int64_t n = TEMP_FAILURE_RETRY(read(file.Fd(), &buf[0], buf.size()));
Elliott Hughesd92bec42011-09-02 17:04:36 -0700203 if (n == -1) {
204 return false;
buzbeec143c552011-08-20 17:38:58 -0700205 }
Elliott Hughesd92bec42011-09-02 17:04:36 -0700206 if (n == 0) {
207 return true;
208 }
Elliott Hughes3b6baaa2011-10-14 19:13:56 -0700209 result->append(&buf[0], n);
buzbeec143c552011-08-20 17:38:58 -0700210 }
buzbeec143c552011-08-20 17:38:58 -0700211}
212
Andreas Gampea6dfdae2015-02-24 15:50:19 -0800213bool PrintFileToLog(const std::string& file_name, LogSeverity level) {
Andreas Gampedf878922015-08-13 16:44:54 -0700214 File file(file_name, O_RDONLY, false);
215 if (!file.IsOpened()) {
Andreas Gampea6dfdae2015-02-24 15:50:19 -0800216 return false;
217 }
218
219 constexpr size_t kBufSize = 256; // Small buffer. Avoid stack overflow and stack size warnings.
220 char buf[kBufSize + 1]; // +1 for terminator.
221 size_t filled_to = 0;
222 while (true) {
223 DCHECK_LT(filled_to, kBufSize);
224 int64_t n = TEMP_FAILURE_RETRY(read(file.Fd(), &buf[filled_to], kBufSize - filled_to));
225 if (n <= 0) {
226 // Print the rest of the buffer, if it exists.
227 if (filled_to > 0) {
228 buf[filled_to] = 0;
229 LOG(level) << buf;
230 }
231 return n == 0;
232 }
233 // Scan for '\n'.
234 size_t i = filled_to;
235 bool found_newline = false;
236 for (; i < filled_to + n; ++i) {
237 if (buf[i] == '\n') {
238 // Found a line break, that's something to print now.
239 buf[i] = 0;
240 LOG(level) << buf;
241 // Copy the rest to the front.
242 if (i + 1 < filled_to + n) {
243 memmove(&buf[0], &buf[i + 1], filled_to + n - i - 1);
244 filled_to = filled_to + n - i - 1;
245 } else {
246 filled_to = 0;
247 }
248 found_newline = true;
249 break;
250 }
251 }
252 if (found_newline) {
253 continue;
254 } else {
255 filled_to += n;
256 // Check if we must flush now.
257 if (filled_to == kBufSize) {
258 buf[kBufSize] = 0;
259 LOG(level) << buf;
260 filled_to = 0;
261 }
262 }
263 }
264}
265
Ian Rogers1ff3c982014-08-12 02:30:58 -0700266std::string PrettyDescriptor(const char* descriptor) {
Elliott Hughes11e45072011-08-16 17:40:46 -0700267 // Count the number of '['s to get the dimensionality.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700268 const char* c = descriptor;
Elliott Hughes11e45072011-08-16 17:40:46 -0700269 size_t dim = 0;
270 while (*c == '[') {
271 dim++;
272 c++;
273 }
274
275 // Reference or primitive?
276 if (*c == 'L') {
277 // "[[La/b/C;" -> "a.b.C[][]".
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700278 c++; // Skip the 'L'.
Elliott Hughes11e45072011-08-16 17:40:46 -0700279 } else {
280 // "[[B" -> "byte[][]".
281 // To make life easier, we make primitives look like unqualified
282 // reference types.
283 switch (*c) {
284 case 'B': c = "byte;"; break;
285 case 'C': c = "char;"; break;
286 case 'D': c = "double;"; break;
287 case 'F': c = "float;"; break;
288 case 'I': c = "int;"; break;
289 case 'J': c = "long;"; break;
290 case 'S': c = "short;"; break;
291 case 'Z': c = "boolean;"; break;
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700292 case 'V': c = "void;"; break; // Used when decoding return types.
Elliott Hughes5174fe62011-08-23 15:12:35 -0700293 default: return descriptor;
Elliott Hughes11e45072011-08-16 17:40:46 -0700294 }
295 }
296
297 // At this point, 'c' is a string of the form "fully/qualified/Type;"
298 // or "primitive;". Rewrite the type with '.' instead of '/':
299 std::string result;
300 const char* p = c;
301 while (*p != ';') {
302 char ch = *p++;
303 if (ch == '/') {
304 ch = '.';
305 }
306 result.push_back(ch);
307 }
308 // ...and replace the semicolon with 'dim' "[]" pairs:
Ian Rogers1ff3c982014-08-12 02:30:58 -0700309 for (size_t i = 0; i < dim; ++i) {
Elliott Hughes11e45072011-08-16 17:40:46 -0700310 result += "[]";
311 }
312 return result;
313}
314
Elliott Hughes9058f2b2012-03-22 18:06:48 -0700315std::string PrettyArguments(const char* signature) {
316 std::string result;
317 result += '(';
318 CHECK_EQ(*signature, '(');
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700319 ++signature; // Skip the '('.
Elliott Hughes9058f2b2012-03-22 18:06:48 -0700320 while (*signature != ')') {
321 size_t argument_length = 0;
322 while (signature[argument_length] == '[') {
323 ++argument_length;
324 }
325 if (signature[argument_length] == 'L') {
326 argument_length = (strchr(signature, ';') - signature + 1);
327 } else {
328 ++argument_length;
329 }
Ian Rogers1ff3c982014-08-12 02:30:58 -0700330 {
331 std::string argument_descriptor(signature, argument_length);
332 result += PrettyDescriptor(argument_descriptor.c_str());
333 }
Elliott Hughes9058f2b2012-03-22 18:06:48 -0700334 if (signature[argument_length] != ')') {
335 result += ", ";
336 }
337 signature += argument_length;
338 }
339 CHECK_EQ(*signature, ')');
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700340 ++signature; // Skip the ')'.
Elliott Hughes9058f2b2012-03-22 18:06:48 -0700341 result += ')';
342 return result;
343}
344
345std::string PrettyReturnType(const char* signature) {
346 const char* return_type = strchr(signature, ')');
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700347 CHECK(return_type != nullptr);
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700348 ++return_type; // Skip ')'.
Elliott Hughes9058f2b2012-03-22 18:06:48 -0700349 return PrettyDescriptor(return_type);
350}
351
Andreas Gampec0d82292014-09-23 10:38:30 -0700352std::string PrettyJavaAccessFlags(uint32_t access_flags) {
353 std::string result;
354 if ((access_flags & kAccPublic) != 0) {
355 result += "public ";
356 }
357 if ((access_flags & kAccProtected) != 0) {
358 result += "protected ";
359 }
360 if ((access_flags & kAccPrivate) != 0) {
361 result += "private ";
362 }
363 if ((access_flags & kAccFinal) != 0) {
364 result += "final ";
365 }
366 if ((access_flags & kAccStatic) != 0) {
367 result += "static ";
368 }
David Brazdilca3c8c32016-09-06 14:04:48 +0100369 if ((access_flags & kAccAbstract) != 0) {
370 result += "abstract ";
371 }
372 if ((access_flags & kAccInterface) != 0) {
373 result += "interface ";
374 }
Andreas Gampec0d82292014-09-23 10:38:30 -0700375 if ((access_flags & kAccTransient) != 0) {
376 result += "transient ";
377 }
378 if ((access_flags & kAccVolatile) != 0) {
379 result += "volatile ";
380 }
381 if ((access_flags & kAccSynchronized) != 0) {
382 result += "synchronized ";
383 }
384 return result;
385}
386
Mathieu Chartiere6da9af2013-12-16 11:54:42 -0800387std::string PrettySize(int64_t byte_count) {
Elliott Hughesc967f782012-04-16 10:23:15 -0700388 // The byte thresholds at which we display amounts. A byte count is displayed
389 // in unit U when kUnitThresholds[U] <= bytes < kUnitThresholds[U+1].
Ian Rogersef7d42f2014-01-06 12:55:46 -0800390 static const int64_t kUnitThresholds[] = {
Elliott Hughesc967f782012-04-16 10:23:15 -0700391 0, // B up to...
392 3*1024, // KB up to...
393 2*1024*1024, // MB up to...
394 1024*1024*1024 // GB from here.
395 };
Mathieu Chartiere6da9af2013-12-16 11:54:42 -0800396 static const int64_t kBytesPerUnit[] = { 1, KB, MB, GB };
Elliott Hughesc967f782012-04-16 10:23:15 -0700397 static const char* const kUnitStrings[] = { "B", "KB", "MB", "GB" };
Mathieu Chartiere6da9af2013-12-16 11:54:42 -0800398 const char* negative_str = "";
399 if (byte_count < 0) {
400 negative_str = "-";
401 byte_count = -byte_count;
402 }
Elliott Hughesc967f782012-04-16 10:23:15 -0700403 int i = arraysize(kUnitThresholds);
404 while (--i > 0) {
405 if (byte_count >= kUnitThresholds[i]) {
406 break;
407 }
Ian Rogers3bb17a62012-01-27 23:56:44 -0800408 }
Brian Carlstrom474cc792014-03-07 14:18:15 -0800409 return StringPrintf("%s%" PRId64 "%s",
410 negative_str, byte_count / kBytesPerUnit[i], kUnitStrings[i]);
Ian Rogers3bb17a62012-01-27 23:56:44 -0800411}
412
Ian Rogers576ca0c2014-06-06 15:58:22 -0700413std::string PrintableChar(uint16_t ch) {
414 std::string result;
415 result += '\'';
416 if (NeedsEscaping(ch)) {
417 StringAppendF(&result, "\\u%04x", ch);
418 } else {
419 result += ch;
420 }
421 result += '\'';
422 return result;
423}
424
Ian Rogers68b56852014-08-29 20:19:11 -0700425std::string PrintableString(const char* utf) {
Elliott Hughes82914b62012-04-09 15:56:29 -0700426 std::string result;
427 result += '"';
Ian Rogers68b56852014-08-29 20:19:11 -0700428 const char* p = utf;
Elliott Hughes82914b62012-04-09 15:56:29 -0700429 size_t char_count = CountModifiedUtf8Chars(p);
430 for (size_t i = 0; i < char_count; ++i) {
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000431 uint32_t ch = GetUtf16FromUtf8(&p);
Elliott Hughes82914b62012-04-09 15:56:29 -0700432 if (ch == '\\') {
433 result += "\\\\";
434 } else if (ch == '\n') {
435 result += "\\n";
436 } else if (ch == '\r') {
437 result += "\\r";
438 } else if (ch == '\t') {
439 result += "\\t";
Elliott Hughes82914b62012-04-09 15:56:29 -0700440 } else {
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000441 const uint16_t leading = GetLeadingUtf16Char(ch);
442
443 if (NeedsEscaping(leading)) {
444 StringAppendF(&result, "\\u%04x", leading);
445 } else {
446 result += leading;
447 }
448
449 const uint32_t trailing = GetTrailingUtf16Char(ch);
450 if (trailing != 0) {
451 // All high surrogates will need escaping.
452 StringAppendF(&result, "\\u%04x", trailing);
453 }
Elliott Hughes82914b62012-04-09 15:56:29 -0700454 }
455 }
456 result += '"';
457 return result;
458}
459
Elliott Hughesd8c00d02012-01-30 14:08:31 -0800460// 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 -0700461std::string MangleForJni(const std::string& s) {
462 std::string result;
463 size_t char_count = CountModifiedUtf8Chars(s.c_str());
464 const char* cp = &s[0];
465 for (size_t i = 0; i < char_count; ++i) {
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000466 uint32_t ch = GetUtf16FromUtf8(&cp);
Elliott Hughesd8c00d02012-01-30 14:08:31 -0800467 if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')) {
468 result.push_back(ch);
469 } else if (ch == '.' || ch == '/') {
470 result += "_";
471 } else if (ch == '_') {
472 result += "_1";
473 } else if (ch == ';') {
474 result += "_2";
475 } else if (ch == '[') {
476 result += "_3";
Elliott Hughes79082e32011-08-25 12:07:32 -0700477 } else {
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000478 const uint16_t leading = GetLeadingUtf16Char(ch);
479 const uint32_t trailing = GetTrailingUtf16Char(ch);
480
481 StringAppendF(&result, "_0%04x", leading);
482 if (trailing != 0) {
483 StringAppendF(&result, "_0%04x", trailing);
484 }
Elliott Hughes79082e32011-08-25 12:07:32 -0700485 }
486 }
487 return result;
488}
489
Brian Carlstromf91c8c32011-09-21 17:30:34 -0700490std::string DotToDescriptor(const char* class_name) {
491 std::string descriptor(class_name);
492 std::replace(descriptor.begin(), descriptor.end(), '.', '/');
493 if (descriptor.length() > 0 && descriptor[0] != '[') {
494 descriptor = "L" + descriptor + ";";
495 }
496 return descriptor;
497}
498
Elliott Hughesf1a5adc2012-02-10 18:09:35 -0800499std::string DescriptorToDot(const char* descriptor) {
Elliott Hughes2435a572012-02-17 16:07:41 -0800500 size_t length = strlen(descriptor);
Ian Rogers1ff3c982014-08-12 02:30:58 -0700501 if (length > 1) {
502 if (descriptor[0] == 'L' && descriptor[length - 1] == ';') {
503 // Descriptors have the leading 'L' and trailing ';' stripped.
504 std::string result(descriptor + 1, length - 2);
505 std::replace(result.begin(), result.end(), '/', '.');
506 return result;
507 } else {
508 // For arrays the 'L' and ';' remain intact.
509 std::string result(descriptor);
510 std::replace(result.begin(), result.end(), '/', '.');
511 return result;
512 }
Elliott Hughes2435a572012-02-17 16:07:41 -0800513 }
Ian Rogers1ff3c982014-08-12 02:30:58 -0700514 // Do nothing for non-class/array descriptors.
Elliott Hughes2435a572012-02-17 16:07:41 -0800515 return descriptor;
Elliott Hughes91bf6cd2012-02-14 17:27:48 -0800516}
517
518std::string DescriptorToName(const char* descriptor) {
Elliott Hughesf1a5adc2012-02-10 18:09:35 -0800519 size_t length = strlen(descriptor);
Elliott Hughes2435a572012-02-17 16:07:41 -0800520 if (descriptor[0] == 'L' && descriptor[length - 1] == ';') {
521 std::string result(descriptor + 1, length - 2);
522 return result;
523 }
524 return descriptor;
Brian Carlstromaded5f72011-10-07 17:15:04 -0700525}
526
jeffhao10037c82012-01-23 15:06:23 -0800527// Helper for IsValidPartOfMemberNameUtf8(), a bit vector indicating valid low ascii.
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700528uint32_t DEX_MEMBER_VALID_LOW_ASCII[4] = {
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700529 0x00000000, // 00..1f low control characters; nothing valid
530 0x03ff2010, // 20..3f digits and symbols; valid: '0'..'9', '$', '-'
531 0x87fffffe, // 40..5f uppercase etc.; valid: 'A'..'Z', '_'
532 0x07fffffe // 60..7f lowercase etc.; valid: 'a'..'z'
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700533};
534
jeffhao10037c82012-01-23 15:06:23 -0800535// Helper for IsValidPartOfMemberNameUtf8(); do not call directly.
536bool IsValidPartOfMemberNameUtf8Slow(const char** pUtf8Ptr) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700537 /*
538 * It's a multibyte encoded character. Decode it and analyze. We
539 * accept anything that isn't (a) an improperly encoded low value,
540 * (b) an improper surrogate pair, (c) an encoded '\0', (d) a high
541 * control character, or (e) a high space, layout, or special
542 * character (U+00a0, U+2000..U+200f, U+2028..U+202f,
543 * U+fff0..U+ffff). This is all specified in the dex format
544 * document.
545 */
546
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000547 const uint32_t pair = GetUtf16FromUtf8(pUtf8Ptr);
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000548 const uint16_t leading = GetLeadingUtf16Char(pair);
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000549
Narayan Kamath8508e372015-05-06 14:55:43 +0100550 // We have a surrogate pair resulting from a valid 4 byte UTF sequence.
551 // No further checks are necessary because 4 byte sequences span code
552 // points [U+10000, U+1FFFFF], which are valid codepoints in a dex
553 // identifier. Furthermore, GetUtf16FromUtf8 guarantees that each of
554 // the surrogate halves are valid and well formed in this instance.
555 if (GetTrailingUtf16Char(pair) != 0) {
556 return true;
557 }
558
559
560 // We've encountered a one, two or three byte UTF-8 sequence. The
561 // three byte UTF-8 sequence could be one half of a surrogate pair.
562 switch (leading >> 8) {
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000563 case 0x00:
564 // It's only valid if it's above the ISO-8859-1 high space (0xa0).
565 return (leading > 0x00a0);
566 case 0xd8:
567 case 0xd9:
568 case 0xda:
569 case 0xdb:
Narayan Kamath8508e372015-05-06 14:55:43 +0100570 {
571 // We found a three byte sequence encoding one half of a surrogate.
572 // Look for the other half.
573 const uint32_t pair2 = GetUtf16FromUtf8(pUtf8Ptr);
574 const uint16_t trailing = GetLeadingUtf16Char(pair2);
575
576 return (GetTrailingUtf16Char(pair2) == 0) && (0xdc00 <= trailing && trailing <= 0xdfff);
577 }
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000578 case 0xdc:
579 case 0xdd:
580 case 0xde:
581 case 0xdf:
582 // It's a trailing surrogate, which is not valid at this point.
583 return false;
584 case 0x20:
585 case 0xff:
586 // It's in the range that has spaces, controls, and specials.
587 switch (leading & 0xfff8) {
Narayan Kamath8508e372015-05-06 14:55:43 +0100588 case 0x2000:
589 case 0x2008:
590 case 0x2028:
591 case 0xfff0:
592 case 0xfff8:
593 return false;
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000594 }
Narayan Kamath8508e372015-05-06 14:55:43 +0100595 return true;
596 default:
597 return true;
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700598 }
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000599
Narayan Kamath8508e372015-05-06 14:55:43 +0100600 UNREACHABLE();
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700601}
602
603/* Return whether the pointed-at modified-UTF-8 encoded character is
604 * valid as part of a member name, updating the pointer to point past
605 * the consumed character. This will consume two encoded UTF-16 code
606 * points if the character is encoded as a surrogate pair. Also, if
607 * this function returns false, then the given pointer may only have
608 * been partially advanced.
609 */
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700610static bool IsValidPartOfMemberNameUtf8(const char** pUtf8Ptr) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700611 uint8_t c = (uint8_t) **pUtf8Ptr;
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700612 if (LIKELY(c <= 0x7f)) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700613 // It's low-ascii, so check the table.
614 uint32_t wordIdx = c >> 5;
615 uint32_t bitIdx = c & 0x1f;
616 (*pUtf8Ptr)++;
617 return (DEX_MEMBER_VALID_LOW_ASCII[wordIdx] & (1 << bitIdx)) != 0;
618 }
619
620 // It's a multibyte encoded character. Call a non-inline function
621 // for the heavy lifting.
jeffhao10037c82012-01-23 15:06:23 -0800622 return IsValidPartOfMemberNameUtf8Slow(pUtf8Ptr);
623}
624
625bool IsValidMemberName(const char* s) {
626 bool angle_name = false;
627
Elliott Hughesb25c3f62012-03-26 16:35:06 -0700628 switch (*s) {
jeffhao10037c82012-01-23 15:06:23 -0800629 case '\0':
630 // The empty string is not a valid name.
631 return false;
632 case '<':
633 angle_name = true;
634 s++;
635 break;
636 }
637
638 while (true) {
639 switch (*s) {
640 case '\0':
641 return !angle_name;
642 case '>':
643 return angle_name && s[1] == '\0';
644 }
645
646 if (!IsValidPartOfMemberNameUtf8(&s)) {
647 return false;
648 }
649 }
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700650}
651
Elliott Hughes906e6852011-10-28 14:52:10 -0700652enum ClassNameType { kName, kDescriptor };
Ian Rogers7b078e82014-09-10 14:44:24 -0700653template<ClassNameType kType, char kSeparator>
654static bool IsValidClassName(const char* s) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700655 int arrayCount = 0;
656 while (*s == '[') {
657 arrayCount++;
658 s++;
659 }
660
661 if (arrayCount > 255) {
662 // Arrays may have no more than 255 dimensions.
663 return false;
664 }
665
Ian Rogers7b078e82014-09-10 14:44:24 -0700666 ClassNameType type = kType;
667 if (type != kDescriptor && arrayCount != 0) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700668 /*
669 * If we're looking at an array of some sort, then it doesn't
670 * matter if what is being asked for is a class name; the
671 * format looks the same as a type descriptor in that case, so
672 * treat it as such.
673 */
Elliott Hughes906e6852011-10-28 14:52:10 -0700674 type = kDescriptor;
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700675 }
676
Elliott Hughes906e6852011-10-28 14:52:10 -0700677 if (type == kDescriptor) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700678 /*
679 * We are looking for a descriptor. Either validate it as a
680 * single-character primitive type, or continue on to check the
681 * embedded class name (bracketed by "L" and ";").
682 */
683 switch (*(s++)) {
684 case 'B':
685 case 'C':
686 case 'D':
687 case 'F':
688 case 'I':
689 case 'J':
690 case 'S':
691 case 'Z':
692 // These are all single-character descriptors for primitive types.
693 return (*s == '\0');
694 case 'V':
695 // Non-array void is valid, but you can't have an array of void.
696 return (arrayCount == 0) && (*s == '\0');
697 case 'L':
698 // Class name: Break out and continue below.
699 break;
700 default:
701 // Oddball descriptor character.
702 return false;
703 }
704 }
705
706 /*
707 * We just consumed the 'L' that introduces a class name as part
708 * of a type descriptor, or we are looking for an unadorned class
709 * name.
710 */
711
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700712 bool sepOrFirst = true; // first character or just encountered a separator.
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700713 for (;;) {
714 uint8_t c = (uint8_t) *s;
715 switch (c) {
716 case '\0':
717 /*
718 * Premature end for a type descriptor, but valid for
719 * a class name as long as we haven't encountered an
720 * empty component (including the degenerate case of
721 * the empty string "").
722 */
Elliott Hughes906e6852011-10-28 14:52:10 -0700723 return (type == kName) && !sepOrFirst;
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700724 case ';':
725 /*
726 * Invalid character for a class name, but the
727 * legitimate end of a type descriptor. In the latter
728 * case, make sure that this is the end of the string
729 * and that it doesn't end with an empty component
730 * (including the degenerate case of "L;").
731 */
Elliott Hughes906e6852011-10-28 14:52:10 -0700732 return (type == kDescriptor) && !sepOrFirst && (s[1] == '\0');
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700733 case '/':
734 case '.':
Ian Rogers7b078e82014-09-10 14:44:24 -0700735 if (c != kSeparator) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700736 // The wrong separator character.
737 return false;
738 }
739 if (sepOrFirst) {
740 // Separator at start or two separators in a row.
741 return false;
742 }
743 sepOrFirst = true;
744 s++;
745 break;
746 default:
jeffhao10037c82012-01-23 15:06:23 -0800747 if (!IsValidPartOfMemberNameUtf8(&s)) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700748 return false;
749 }
750 sepOrFirst = false;
751 break;
752 }
753 }
754}
755
Elliott Hughes906e6852011-10-28 14:52:10 -0700756bool IsValidBinaryClassName(const char* s) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700757 return IsValidClassName<kName, '.'>(s);
Elliott Hughes906e6852011-10-28 14:52:10 -0700758}
759
760bool IsValidJniClassName(const char* s) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700761 return IsValidClassName<kName, '/'>(s);
Elliott Hughes906e6852011-10-28 14:52:10 -0700762}
763
764bool IsValidDescriptor(const char* s) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700765 return IsValidClassName<kDescriptor, '/'>(s);
Elliott Hughes906e6852011-10-28 14:52:10 -0700766}
767
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700768void Split(const std::string& s, char separator, std::vector<std::string>* result) {
Elliott Hughes34023802011-08-30 12:06:17 -0700769 const char* p = s.data();
770 const char* end = p + s.size();
771 while (p != end) {
Elliott Hughes48436bb2012-02-07 15:23:28 -0800772 if (*p == separator) {
Elliott Hughes34023802011-08-30 12:06:17 -0700773 ++p;
774 } else {
775 const char* start = p;
Elliott Hughes48436bb2012-02-07 15:23:28 -0800776 while (++p != end && *p != separator) {
777 // Skip to the next occurrence of the separator.
Elliott Hughes34023802011-08-30 12:06:17 -0700778 }
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700779 result->push_back(std::string(start, p - start));
Elliott Hughes34023802011-08-30 12:06:17 -0700780 }
781 }
782}
783
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700784std::string Trim(const std::string& s) {
Dave Allison70202782013-10-22 17:52:19 -0700785 std::string result;
786 unsigned int start_index = 0;
787 unsigned int end_index = s.size() - 1;
788
789 // Skip initial whitespace.
790 while (start_index < s.size()) {
791 if (!isspace(s[start_index])) {
792 break;
793 }
794 start_index++;
795 }
796
797 // Skip terminating whitespace.
798 while (end_index >= start_index) {
799 if (!isspace(s[end_index])) {
800 break;
801 }
802 end_index--;
803 }
804
805 // All spaces, no beef.
806 if (end_index < start_index) {
807 return "";
808 }
809 // Start_index is the first non-space, end_index is the last one.
810 return s.substr(start_index, end_index - start_index + 1);
811}
812
Elliott Hughes48436bb2012-02-07 15:23:28 -0800813template <typename StringT>
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700814std::string Join(const std::vector<StringT>& strings, char separator) {
Elliott Hughes48436bb2012-02-07 15:23:28 -0800815 if (strings.empty()) {
816 return "";
817 }
818
819 std::string result(strings[0]);
820 for (size_t i = 1; i < strings.size(); ++i) {
821 result += separator;
822 result += strings[i];
823 }
824 return result;
825}
826
827// Explicit instantiations.
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700828template std::string Join<std::string>(const std::vector<std::string>& strings, char separator);
829template std::string Join<const char*>(const std::vector<const char*>& strings, char separator);
Elliott Hughes48436bb2012-02-07 15:23:28 -0800830
Elliott Hughesf1a5adc2012-02-10 18:09:35 -0800831bool StartsWith(const std::string& s, const char* prefix) {
832 return s.compare(0, strlen(prefix), prefix) == 0;
833}
834
Brian Carlstrom7a967b32012-03-28 15:23:10 -0700835bool EndsWith(const std::string& s, const char* suffix) {
836 size_t suffix_length = strlen(suffix);
837 size_t string_length = s.size();
838 if (suffix_length > string_length) {
839 return false;
840 }
841 size_t offset = string_length - suffix_length;
842 return s.compare(offset, suffix_length, suffix) == 0;
843}
844
Elliott Hughes22869a92012-03-27 14:08:24 -0700845void SetThreadName(const char* thread_name) {
Elliott Hughesdcc24742011-09-07 14:02:44 -0700846 int hasAt = 0;
847 int hasDot = 0;
Elliott Hughes22869a92012-03-27 14:08:24 -0700848 const char* s = thread_name;
Elliott Hughesdcc24742011-09-07 14:02:44 -0700849 while (*s) {
850 if (*s == '.') {
851 hasDot = 1;
852 } else if (*s == '@') {
853 hasAt = 1;
854 }
855 s++;
856 }
Elliott Hughes22869a92012-03-27 14:08:24 -0700857 int len = s - thread_name;
Elliott Hughesdcc24742011-09-07 14:02:44 -0700858 if (len < 15 || hasAt || !hasDot) {
Elliott Hughes22869a92012-03-27 14:08:24 -0700859 s = thread_name;
Elliott Hughesdcc24742011-09-07 14:02:44 -0700860 } else {
Elliott Hughes22869a92012-03-27 14:08:24 -0700861 s = thread_name + len - 15;
Elliott Hughesdcc24742011-09-07 14:02:44 -0700862 }
Elliott Hughes0a18df82015-01-09 15:16:16 -0800863#if defined(__linux__)
Elliott Hughes7c6a61e2012-03-12 18:01:41 -0700864 // pthread_setname_np fails rather than truncating long strings.
Elliott Hughes0a18df82015-01-09 15:16:16 -0800865 char buf[16]; // MAX_TASK_COMM_LEN=16 is hard-coded in the kernel.
Elliott Hughesdcc24742011-09-07 14:02:44 -0700866 strncpy(buf, s, sizeof(buf)-1);
867 buf[sizeof(buf)-1] = '\0';
868 errno = pthread_setname_np(pthread_self(), buf);
869 if (errno != 0) {
870 PLOG(WARNING) << "Unable to set the name of current thread to '" << buf << "'";
871 }
Elliott Hughes0a18df82015-01-09 15:16:16 -0800872#else // __APPLE__
Elliott Hughes22869a92012-03-27 14:08:24 -0700873 pthread_setname_np(thread_name);
Elliott Hughesdcc24742011-09-07 14:02:44 -0700874#endif
875}
876
Brian Carlstrom29212012013-09-12 22:18:30 -0700877void GetTaskStats(pid_t tid, char* state, int* utime, int* stime, int* task_cpu) {
878 *utime = *stime = *task_cpu = 0;
Elliott Hughesbfe487b2011-10-26 15:48:55 -0700879 std::string stats;
Elliott Hughes8a31b502012-04-30 19:36:11 -0700880 if (!ReadFileToString(StringPrintf("/proc/self/task/%d/stat", tid), &stats)) {
Elliott Hughesbfe487b2011-10-26 15:48:55 -0700881 return;
882 }
883 // Skip the command, which may contain spaces.
884 stats = stats.substr(stats.find(')') + 2);
885 // Extract the three fields we care about.
886 std::vector<std::string> fields;
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700887 Split(stats, ' ', &fields);
Brian Carlstrom29212012013-09-12 22:18:30 -0700888 *state = fields[0][0];
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700889 *utime = strtoull(fields[11].c_str(), nullptr, 10);
890 *stime = strtoull(fields[12].c_str(), nullptr, 10);
891 *task_cpu = strtoull(fields[36].c_str(), nullptr, 10);
Elliott Hughesbfe487b2011-10-26 15:48:55 -0700892}
893
Elliott Hughes1bac54f2012-03-16 12:48:31 -0700894std::string GetSchedulerGroupName(pid_t tid) {
895 // /proc/<pid>/cgroup looks like this:
896 // 2:devices:/
897 // 1:cpuacct,cpu:/
898 // We want the third field from the line whose second field contains the "cpu" token.
899 std::string cgroup_file;
900 if (!ReadFileToString(StringPrintf("/proc/self/task/%d/cgroup", tid), &cgroup_file)) {
901 return "";
902 }
903 std::vector<std::string> cgroup_lines;
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700904 Split(cgroup_file, '\n', &cgroup_lines);
Elliott Hughes1bac54f2012-03-16 12:48:31 -0700905 for (size_t i = 0; i < cgroup_lines.size(); ++i) {
906 std::vector<std::string> cgroup_fields;
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700907 Split(cgroup_lines[i], ':', &cgroup_fields);
Elliott Hughes1bac54f2012-03-16 12:48:31 -0700908 std::vector<std::string> cgroups;
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700909 Split(cgroup_fields[1], ',', &cgroups);
Andreas Gampe277ccbd2014-11-03 21:36:10 -0800910 for (size_t j = 0; j < cgroups.size(); ++j) {
911 if (cgroups[j] == "cpu") {
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700912 return cgroup_fields[2].substr(1); // Skip the leading slash.
Elliott Hughes1bac54f2012-03-16 12:48:31 -0700913 }
914 }
915 }
916 return "";
917}
918
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800919const char* GetAndroidRoot() {
920 const char* android_root = getenv("ANDROID_ROOT");
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700921 if (android_root == nullptr) {
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800922 if (OS::DirectoryExists("/system")) {
923 android_root = "/system";
Brian Carlstroma9f19782011-10-13 00:14:47 -0700924 } else {
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800925 LOG(FATAL) << "ANDROID_ROOT not set and /system does not exist";
926 return "";
Brian Carlstroma9f19782011-10-13 00:14:47 -0700927 }
928 }
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800929 if (!OS::DirectoryExists(android_root)) {
930 LOG(FATAL) << "Failed to find ANDROID_ROOT directory " << android_root;
Brian Carlstroma9f19782011-10-13 00:14:47 -0700931 return "";
932 }
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800933 return android_root;
934}
Brian Carlstroma9f19782011-10-13 00:14:47 -0700935
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800936const char* GetAndroidData() {
Alex Lighta59dd802014-07-02 16:28:08 -0700937 std::string error_msg;
938 const char* dir = GetAndroidDataSafe(&error_msg);
939 if (dir != nullptr) {
940 return dir;
941 } else {
942 LOG(FATAL) << error_msg;
943 return "";
944 }
945}
946
947const char* GetAndroidDataSafe(std::string* error_msg) {
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800948 const char* android_data = getenv("ANDROID_DATA");
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700949 if (android_data == nullptr) {
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800950 if (OS::DirectoryExists("/data")) {
951 android_data = "/data";
952 } else {
Alex Lighta59dd802014-07-02 16:28:08 -0700953 *error_msg = "ANDROID_DATA not set and /data does not exist";
954 return nullptr;
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800955 }
956 }
957 if (!OS::DirectoryExists(android_data)) {
Alex Lighta59dd802014-07-02 16:28:08 -0700958 *error_msg = StringPrintf("Failed to find ANDROID_DATA directory %s", android_data);
959 return nullptr;
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800960 }
961 return android_data;
962}
963
Alex Lighta59dd802014-07-02 16:28:08 -0700964void GetDalvikCache(const char* subdir, const bool create_if_absent, std::string* dalvik_cache,
Andreas Gampe3c13a792014-09-18 20:56:04 -0700965 bool* have_android_data, bool* dalvik_cache_exists, bool* is_global_cache) {
Alex Lighta59dd802014-07-02 16:28:08 -0700966 CHECK(subdir != nullptr);
967 std::string error_msg;
968 const char* android_data = GetAndroidDataSafe(&error_msg);
969 if (android_data == nullptr) {
970 *have_android_data = false;
971 *dalvik_cache_exists = false;
Andreas Gampe3c13a792014-09-18 20:56:04 -0700972 *is_global_cache = false;
Alex Lighta59dd802014-07-02 16:28:08 -0700973 return;
974 } else {
975 *have_android_data = true;
976 }
977 const std::string dalvik_cache_root(StringPrintf("%s/dalvik-cache/", android_data));
978 *dalvik_cache = dalvik_cache_root + subdir;
979 *dalvik_cache_exists = OS::DirectoryExists(dalvik_cache->c_str());
Andreas Gampe3c13a792014-09-18 20:56:04 -0700980 *is_global_cache = strcmp(android_data, "/data") == 0;
981 if (create_if_absent && !*dalvik_cache_exists && !*is_global_cache) {
Alex Lighta59dd802014-07-02 16:28:08 -0700982 // Don't create the system's /data/dalvik-cache/... because it needs special permissions.
983 *dalvik_cache_exists = ((mkdir(dalvik_cache_root.c_str(), 0700) == 0 || errno == EEXIST) &&
984 (mkdir(dalvik_cache->c_str(), 0700) == 0 || errno == EEXIST));
985 }
986}
987
Richard Uhler55b58b62016-08-12 09:05:13 -0700988std::string GetDalvikCache(const char* subdir) {
Narayan Kamath11d9f062014-04-23 20:24:57 +0100989 CHECK(subdir != nullptr);
Brian Carlstrom41ccffd2014-05-06 10:37:30 -0700990 const char* android_data = GetAndroidData();
991 const std::string dalvik_cache_root(StringPrintf("%s/dalvik-cache/", android_data));
Narayan Kamath11d9f062014-04-23 20:24:57 +0100992 const std::string dalvik_cache = dalvik_cache_root + subdir;
Andreas Gampe40da2862015-02-27 12:49:04 -0800993 if (!OS::DirectoryExists(dalvik_cache.c_str())) {
Richard Uhler55b58b62016-08-12 09:05:13 -0700994 // TODO: Check callers. Traditional behavior is to not abort.
995 return "";
Brian Carlstroma9f19782011-10-13 00:14:47 -0700996 }
Brian Carlstrom7675e162013-06-10 16:18:04 -0700997 return dalvik_cache;
Brian Carlstroma9f19782011-10-13 00:14:47 -0700998}
999
Alex Lighta59dd802014-07-02 16:28:08 -07001000bool GetDalvikCacheFilename(const char* location, const char* cache_location,
1001 std::string* filename, std::string* error_msg) {
Ian Rogerse6060102013-05-16 12:01:04 -07001002 if (location[0] != '/') {
Alex Lighta59dd802014-07-02 16:28:08 -07001003 *error_msg = StringPrintf("Expected path in location to be absolute: %s", location);
1004 return false;
Ian Rogerse6060102013-05-16 12:01:04 -07001005 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001006 std::string cache_file(&location[1]); // skip leading slash
Alex Light6e183f22014-07-18 14:57:04 -07001007 if (!EndsWith(location, ".dex") && !EndsWith(location, ".art") && !EndsWith(location, ".oat")) {
Brian Carlstrom30e2ea42013-06-19 23:25:37 -07001008 cache_file += "/";
1009 cache_file += DexFile::kClassesDex;
1010 }
Brian Carlstromb7bbba42011-10-13 14:58:47 -07001011 std::replace(cache_file.begin(), cache_file.end(), '/', '@');
Alex Lighta59dd802014-07-02 16:28:08 -07001012 *filename = StringPrintf("%s/%s", cache_location, cache_file.c_str());
1013 return true;
1014}
1015
Brian Carlstrom2afe4942014-05-19 10:25:33 -07001016static void InsertIsaDirectory(const InstructionSet isa, std::string* filename) {
Brian Carlstrom0e12bdc2014-05-14 17:44:28 -07001017 // in = /foo/bar/baz
1018 // out = /foo/bar/<isa>/baz
1019 size_t pos = filename->rfind('/');
1020 CHECK_NE(pos, std::string::npos) << *filename << " " << isa;
1021 filename->insert(pos, "/", 1);
1022 filename->insert(pos + 1, GetInstructionSetString(isa));
1023}
1024
1025std::string GetSystemImageFilename(const char* location, const InstructionSet isa) {
1026 // location = /system/framework/boot.art
1027 // filename = /system/framework/<isa>/boot.art
1028 std::string filename(location);
Brian Carlstrom2afe4942014-05-19 10:25:33 -07001029 InsertIsaDirectory(isa, &filename);
Brian Carlstrom0e12bdc2014-05-14 17:44:28 -07001030 return filename;
1031}
1032
Calin Juravle2e2db782016-02-23 12:00:03 +00001033int ExecAndReturnCode(std::vector<std::string>& arg_vector, std::string* error_msg) {
Brian Carlstrom6449c622014-02-10 23:48:36 -08001034 const std::string command_line(Join(arg_vector, ' '));
Brian Carlstrom6449c622014-02-10 23:48:36 -08001035 CHECK_GE(arg_vector.size(), 1U) << command_line;
1036
1037 // Convert the args to char pointers.
1038 const char* program = arg_vector[0].c_str();
1039 std::vector<char*> args;
Brian Carlstrom35d8b8e2014-02-25 10:51:11 -08001040 for (size_t i = 0; i < arg_vector.size(); ++i) {
1041 const std::string& arg = arg_vector[i];
1042 char* arg_str = const_cast<char*>(arg.c_str());
1043 CHECK(arg_str != nullptr) << i;
1044 args.push_back(arg_str);
Brian Carlstrom6449c622014-02-10 23:48:36 -08001045 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001046 args.push_back(nullptr);
Brian Carlstrom6449c622014-02-10 23:48:36 -08001047
1048 // fork and exec
1049 pid_t pid = fork();
1050 if (pid == 0) {
1051 // no allocation allowed between fork and exec
1052
1053 // change process groups, so we don't get reaped by ProcessManager
1054 setpgid(0, 0);
1055
David Sehrd106d9f2016-08-16 19:22:57 -07001056 // (b/30160149): protect subprocesses from modifications to LD_LIBRARY_PATH, etc.
1057 // Use the snapshot of the environment from the time the runtime was created.
1058 char** envp = (Runtime::Current() == nullptr) ? nullptr : Runtime::Current()->GetEnvSnapshot();
1059 if (envp == nullptr) {
1060 execv(program, &args[0]);
1061 } else {
1062 execve(program, &args[0], envp);
1063 }
1064 PLOG(ERROR) << "Failed to execve(" << command_line << ")";
Tobias Lindskogae35c372015-11-04 19:41:21 +01001065 // _exit to avoid atexit handlers in child.
1066 _exit(1);
Brian Carlstrom6449c622014-02-10 23:48:36 -08001067 } else {
1068 if (pid == -1) {
1069 *error_msg = StringPrintf("Failed to execv(%s) because fork failed: %s",
1070 command_line.c_str(), strerror(errno));
Calin Juravle2e2db782016-02-23 12:00:03 +00001071 return -1;
Brian Carlstrom6449c622014-02-10 23:48:36 -08001072 }
1073
1074 // wait for subprocess to finish
Calin Juravle2e2db782016-02-23 12:00:03 +00001075 int status = -1;
Brian Carlstrom6449c622014-02-10 23:48:36 -08001076 pid_t got_pid = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0));
1077 if (got_pid != pid) {
1078 *error_msg = StringPrintf("Failed after fork for execv(%s) because waitpid failed: "
1079 "wanted %d, got %d: %s",
1080 command_line.c_str(), pid, got_pid, strerror(errno));
Calin Juravle2e2db782016-02-23 12:00:03 +00001081 return -1;
Brian Carlstrom6449c622014-02-10 23:48:36 -08001082 }
Calin Juravle2e2db782016-02-23 12:00:03 +00001083 if (WIFEXITED(status)) {
1084 return WEXITSTATUS(status);
Brian Carlstrom6449c622014-02-10 23:48:36 -08001085 }
Calin Juravle2e2db782016-02-23 12:00:03 +00001086 return -1;
1087 }
1088}
1089
1090bool Exec(std::vector<std::string>& arg_vector, std::string* error_msg) {
1091 int status = ExecAndReturnCode(arg_vector, error_msg);
1092 if (status != 0) {
1093 const std::string command_line(Join(arg_vector, ' '));
1094 *error_msg = StringPrintf("Failed execv(%s) because non-0 exit status",
1095 command_line.c_str());
1096 return false;
Brian Carlstrom6449c622014-02-10 23:48:36 -08001097 }
1098 return true;
1099}
1100
Calin Juravle5e2b9712015-12-18 14:10:00 +02001101bool FileExists(const std::string& filename) {
1102 struct stat buffer;
1103 return stat(filename.c_str(), &buffer) == 0;
1104}
1105
Calin Juravleb9c1b9b2016-03-17 17:07:52 +00001106bool FileExistsAndNotEmpty(const std::string& filename) {
1107 struct stat buffer;
1108 if (stat(filename.c_str(), &buffer) != 0) {
1109 return false;
1110 }
1111 return buffer.st_size > 0;
1112}
1113
David Brazdil7b49e6c2016-09-01 11:06:18 +01001114std::string ReplaceFileExtension(const std::string& filename, const std::string& new_extension) {
1115 const size_t last_ext = filename.find_last_of('.');
1116 if (last_ext == std::string::npos) {
1117 return filename + "." + new_extension;
1118 } else {
1119 return filename.substr(0, last_ext + 1) + new_extension;
1120 }
1121}
1122
Mathieu Chartier76433272014-09-26 14:32:37 -07001123std::string PrettyDescriptor(Primitive::Type type) {
1124 return PrettyDescriptor(Primitive::Descriptor(type));
1125}
1126
Nicolas Geoffrayabbb0f72015-10-29 18:55:58 +00001127static void ParseStringAfterChar(const std::string& s,
1128 char c,
1129 std::string* parsed_value,
1130 UsageFn Usage) {
1131 std::string::size_type colon = s.find(c);
1132 if (colon == std::string::npos) {
1133 Usage("Missing char %c in option %s\n", c, s.c_str());
1134 }
1135 // Add one to remove the char we were trimming until.
1136 *parsed_value = s.substr(colon + 1);
1137}
1138
1139void ParseDouble(const std::string& option,
1140 char after_char,
1141 double min,
1142 double max,
1143 double* parsed_value,
1144 UsageFn Usage) {
1145 std::string substring;
1146 ParseStringAfterChar(option, after_char, &substring, Usage);
1147 bool sane_val = true;
1148 double value;
1149 if ((false)) {
1150 // TODO: this doesn't seem to work on the emulator. b/15114595
1151 std::stringstream iss(substring);
1152 iss >> value;
1153 // Ensure that we have a value, there was no cruft after it and it satisfies a sensible range.
1154 sane_val = iss.eof() && (value >= min) && (value <= max);
1155 } else {
1156 char* end = nullptr;
1157 value = strtod(substring.c_str(), &end);
1158 sane_val = *end == '\0' && value >= min && value <= max;
1159 }
1160 if (!sane_val) {
1161 Usage("Invalid double value %s for option %s\n", substring.c_str(), option.c_str());
1162 }
1163 *parsed_value = value;
1164}
1165
Calin Juravle4d77b6a2015-12-01 18:38:09 +00001166int64_t GetFileSizeBytes(const std::string& filename) {
1167 struct stat stat_buf;
1168 int rc = stat(filename.c_str(), &stat_buf);
1169 return rc == 0 ? stat_buf.st_size : -1;
1170}
1171
Mathieu Chartier4d87df62016-01-07 15:14:19 -08001172void SleepForever() {
1173 while (true) {
1174 usleep(1000000);
1175 }
1176}
1177
Elliott Hughes42ee1422011-09-06 12:33:32 -07001178} // namespace art