blob: 66739a9d2ec3d6ec51b2b55c73469696b54aa075 [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>
David Sehrfa442002016-08-22 18:42:08 -070040#include <crt_externs.h>
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
Alex Light9c20a142016-08-23 15:05:12 -070049static const uint8_t kBase64Map[256] = {
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, 255, 255, 255, 255, 255,
53 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
54 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
55 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
56 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, // NOLINT
57 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, // NOLINT
58 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
59 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, // NOLINT
60 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, // NOLINT
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, 255, 255, 255, 255, 255, 255, 255, 255,
71 255, 255, 255, 255
72};
73
74uint8_t* DecodeBase64(const char* src, size_t* dst_size) {
75 std::vector<uint8_t> tmp;
76 uint32_t t = 0, y = 0;
77 int g = 3;
78 for (size_t i = 0; src[i] != '\0'; ++i) {
79 uint8_t c = kBase64Map[src[i] & 0xFF];
80 if (c == 255) continue;
81 // the final = symbols are read and used to trim the remaining bytes
82 if (c == 254) {
83 c = 0;
84 // prevent g < 0 which would potentially allow an overflow later
85 if (--g < 0) {
86 *dst_size = 0;
87 return nullptr;
88 }
89 } else if (g != 3) {
90 // we only allow = to be at the end
91 *dst_size = 0;
92 return nullptr;
93 }
94 t = (t << 6) | c;
95 if (++y == 4) {
96 tmp.push_back((t >> 16) & 255);
97 if (g > 1) {
98 tmp.push_back((t >> 8) & 255);
99 }
100 if (g > 2) {
101 tmp.push_back(t & 255);
102 }
103 y = t = 0;
104 }
105 }
106 if (y != 0) {
107 *dst_size = 0;
108 return nullptr;
109 }
110 std::unique_ptr<uint8_t[]> dst(new uint8_t[tmp.size()]);
111 if (dst_size != nullptr) {
112 *dst_size = tmp.size();
113 } else {
114 *dst_size = 0;
115 }
116 std::copy(tmp.begin(), tmp.end(), dst.get());
117 return dst.release();
118}
119
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800120pid_t GetTid() {
Brian Carlstromf3a26412012-08-24 11:06:02 -0700121#if defined(__APPLE__)
122 uint64_t owner;
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700123 CHECK_PTHREAD_CALL(pthread_threadid_np, (nullptr, &owner), __FUNCTION__); // Requires Mac OS 10.6
Brian Carlstromf3a26412012-08-24 11:06:02 -0700124 return owner;
Elliott Hughes323aa862014-08-20 15:00:04 -0700125#elif defined(__BIONIC__)
126 return gettid();
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800127#else
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800128 return syscall(__NR_gettid);
129#endif
130}
131
Elliott Hughes289be852012-06-12 13:57:20 -0700132std::string GetThreadName(pid_t tid) {
133 std::string result;
134 if (ReadFileToString(StringPrintf("/proc/self/task/%d/comm", tid), &result)) {
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700135 result.resize(result.size() - 1); // Lose the trailing '\n'.
Elliott Hughes289be852012-06-12 13:57:20 -0700136 } else {
137 result = "<unknown>";
138 }
139 return result;
140}
141
Elliott Hughes6d3fc562014-08-27 11:47:01 -0700142void GetThreadStack(pthread_t thread, void** stack_base, size_t* stack_size, size_t* guard_size) {
Elliott Hughese1884192012-04-23 12:38:15 -0700143#if defined(__APPLE__)
Brian Carlstrom29212012013-09-12 22:18:30 -0700144 *stack_size = pthread_get_stacksize_np(thread);
Ian Rogers120f1c72012-09-28 17:17:10 -0700145 void* stack_addr = pthread_get_stackaddr_np(thread);
Elliott Hughese1884192012-04-23 12:38:15 -0700146
147 // Check whether stack_addr is the base or end of the stack.
148 // (On Mac OS 10.7, it's the end.)
149 int stack_variable;
150 if (stack_addr > &stack_variable) {
Ian Rogers13735952014-10-08 12:43:28 -0700151 *stack_base = reinterpret_cast<uint8_t*>(stack_addr) - *stack_size;
Elliott Hughese1884192012-04-23 12:38:15 -0700152 } else {
Brian Carlstrom29212012013-09-12 22:18:30 -0700153 *stack_base = stack_addr;
Elliott Hughese1884192012-04-23 12:38:15 -0700154 }
Elliott Hughes6d3fc562014-08-27 11:47:01 -0700155
156 // This is wrong, but there doesn't seem to be a way to get the actual value on the Mac.
157 pthread_attr_t attributes;
158 CHECK_PTHREAD_CALL(pthread_attr_init, (&attributes), __FUNCTION__);
159 CHECK_PTHREAD_CALL(pthread_attr_getguardsize, (&attributes, guard_size), __FUNCTION__);
160 CHECK_PTHREAD_CALL(pthread_attr_destroy, (&attributes), __FUNCTION__);
Elliott Hughese1884192012-04-23 12:38:15 -0700161#else
162 pthread_attr_t attributes;
Ian Rogers120f1c72012-09-28 17:17:10 -0700163 CHECK_PTHREAD_CALL(pthread_getattr_np, (thread, &attributes), __FUNCTION__);
Brian Carlstrom29212012013-09-12 22:18:30 -0700164 CHECK_PTHREAD_CALL(pthread_attr_getstack, (&attributes, stack_base, stack_size), __FUNCTION__);
Elliott Hughes6d3fc562014-08-27 11:47:01 -0700165 CHECK_PTHREAD_CALL(pthread_attr_getguardsize, (&attributes, guard_size), __FUNCTION__);
Elliott Hughese1884192012-04-23 12:38:15 -0700166 CHECK_PTHREAD_CALL(pthread_attr_destroy, (&attributes), __FUNCTION__);
Elliott Hughes839cc302014-08-28 10:24:44 -0700167
168#if defined(__GLIBC__)
169 // If we're the main thread, check whether we were run with an unlimited stack. In that case,
170 // glibc will have reported a 2GB stack for our 32-bit process, and our stack overflow detection
171 // will be broken because we'll die long before we get close to 2GB.
172 bool is_main_thread = (::art::GetTid() == getpid());
173 if (is_main_thread) {
174 rlimit stack_limit;
175 if (getrlimit(RLIMIT_STACK, &stack_limit) == -1) {
176 PLOG(FATAL) << "getrlimit(RLIMIT_STACK) failed";
177 }
178 if (stack_limit.rlim_cur == RLIM_INFINITY) {
179 size_t old_stack_size = *stack_size;
180
181 // Use the kernel default limit as our size, and adjust the base to match.
182 *stack_size = 8 * MB;
183 *stack_base = reinterpret_cast<uint8_t*>(*stack_base) + (old_stack_size - *stack_size);
184
185 VLOG(threads) << "Limiting unlimited stack (reported as " << PrettySize(old_stack_size) << ")"
186 << " to " << PrettySize(*stack_size)
187 << " with base " << *stack_base;
188 }
189 }
190#endif
191
Elliott Hughese1884192012-04-23 12:38:15 -0700192#endif
193}
194
Elliott Hughesd92bec42011-09-02 17:04:36 -0700195bool ReadFileToString(const std::string& file_name, std::string* result) {
Andreas Gampedf878922015-08-13 16:44:54 -0700196 File file(file_name, O_RDONLY, false);
197 if (!file.IsOpened()) {
Elliott Hughesd92bec42011-09-02 17:04:36 -0700198 return false;
199 }
buzbeec143c552011-08-20 17:38:58 -0700200
Elliott Hughes3b6baaa2011-10-14 19:13:56 -0700201 std::vector<char> buf(8 * KB);
buzbeec143c552011-08-20 17:38:58 -0700202 while (true) {
Andreas Gampea6dfdae2015-02-24 15:50:19 -0800203 int64_t n = TEMP_FAILURE_RETRY(read(file.Fd(), &buf[0], buf.size()));
Elliott Hughesd92bec42011-09-02 17:04:36 -0700204 if (n == -1) {
205 return false;
buzbeec143c552011-08-20 17:38:58 -0700206 }
Elliott Hughesd92bec42011-09-02 17:04:36 -0700207 if (n == 0) {
208 return true;
209 }
Elliott Hughes3b6baaa2011-10-14 19:13:56 -0700210 result->append(&buf[0], n);
buzbeec143c552011-08-20 17:38:58 -0700211 }
buzbeec143c552011-08-20 17:38:58 -0700212}
213
Andreas Gampea6dfdae2015-02-24 15:50:19 -0800214bool PrintFileToLog(const std::string& file_name, LogSeverity level) {
Andreas Gampedf878922015-08-13 16:44:54 -0700215 File file(file_name, O_RDONLY, false);
216 if (!file.IsOpened()) {
Andreas Gampea6dfdae2015-02-24 15:50:19 -0800217 return false;
218 }
219
220 constexpr size_t kBufSize = 256; // Small buffer. Avoid stack overflow and stack size warnings.
221 char buf[kBufSize + 1]; // +1 for terminator.
222 size_t filled_to = 0;
223 while (true) {
224 DCHECK_LT(filled_to, kBufSize);
225 int64_t n = TEMP_FAILURE_RETRY(read(file.Fd(), &buf[filled_to], kBufSize - filled_to));
226 if (n <= 0) {
227 // Print the rest of the buffer, if it exists.
228 if (filled_to > 0) {
229 buf[filled_to] = 0;
230 LOG(level) << buf;
231 }
232 return n == 0;
233 }
234 // Scan for '\n'.
235 size_t i = filled_to;
236 bool found_newline = false;
237 for (; i < filled_to + n; ++i) {
238 if (buf[i] == '\n') {
239 // Found a line break, that's something to print now.
240 buf[i] = 0;
241 LOG(level) << buf;
242 // Copy the rest to the front.
243 if (i + 1 < filled_to + n) {
244 memmove(&buf[0], &buf[i + 1], filled_to + n - i - 1);
245 filled_to = filled_to + n - i - 1;
246 } else {
247 filled_to = 0;
248 }
249 found_newline = true;
250 break;
251 }
252 }
253 if (found_newline) {
254 continue;
255 } else {
256 filled_to += n;
257 // Check if we must flush now.
258 if (filled_to == kBufSize) {
259 buf[kBufSize] = 0;
260 LOG(level) << buf;
261 filled_to = 0;
262 }
263 }
264 }
265}
266
Ian Rogers1ff3c982014-08-12 02:30:58 -0700267std::string PrettyDescriptor(const char* descriptor) {
Elliott Hughes11e45072011-08-16 17:40:46 -0700268 // Count the number of '['s to get the dimensionality.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700269 const char* c = descriptor;
Elliott Hughes11e45072011-08-16 17:40:46 -0700270 size_t dim = 0;
271 while (*c == '[') {
272 dim++;
273 c++;
274 }
275
276 // Reference or primitive?
277 if (*c == 'L') {
278 // "[[La/b/C;" -> "a.b.C[][]".
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700279 c++; // Skip the 'L'.
Elliott Hughes11e45072011-08-16 17:40:46 -0700280 } else {
281 // "[[B" -> "byte[][]".
282 // To make life easier, we make primitives look like unqualified
283 // reference types.
284 switch (*c) {
285 case 'B': c = "byte;"; break;
286 case 'C': c = "char;"; break;
287 case 'D': c = "double;"; break;
288 case 'F': c = "float;"; break;
289 case 'I': c = "int;"; break;
290 case 'J': c = "long;"; break;
291 case 'S': c = "short;"; break;
292 case 'Z': c = "boolean;"; break;
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700293 case 'V': c = "void;"; break; // Used when decoding return types.
Elliott Hughes5174fe62011-08-23 15:12:35 -0700294 default: return descriptor;
Elliott Hughes11e45072011-08-16 17:40:46 -0700295 }
296 }
297
298 // At this point, 'c' is a string of the form "fully/qualified/Type;"
299 // or "primitive;". Rewrite the type with '.' instead of '/':
300 std::string result;
301 const char* p = c;
302 while (*p != ';') {
303 char ch = *p++;
304 if (ch == '/') {
305 ch = '.';
306 }
307 result.push_back(ch);
308 }
309 // ...and replace the semicolon with 'dim' "[]" pairs:
Ian Rogers1ff3c982014-08-12 02:30:58 -0700310 for (size_t i = 0; i < dim; ++i) {
Elliott Hughes11e45072011-08-16 17:40:46 -0700311 result += "[]";
312 }
313 return result;
314}
315
Elliott Hughes9058f2b2012-03-22 18:06:48 -0700316std::string PrettyArguments(const char* signature) {
317 std::string result;
318 result += '(';
319 CHECK_EQ(*signature, '(');
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700320 ++signature; // Skip the '('.
Elliott Hughes9058f2b2012-03-22 18:06:48 -0700321 while (*signature != ')') {
322 size_t argument_length = 0;
323 while (signature[argument_length] == '[') {
324 ++argument_length;
325 }
326 if (signature[argument_length] == 'L') {
327 argument_length = (strchr(signature, ';') - signature + 1);
328 } else {
329 ++argument_length;
330 }
Ian Rogers1ff3c982014-08-12 02:30:58 -0700331 {
332 std::string argument_descriptor(signature, argument_length);
333 result += PrettyDescriptor(argument_descriptor.c_str());
334 }
Elliott Hughes9058f2b2012-03-22 18:06:48 -0700335 if (signature[argument_length] != ')') {
336 result += ", ";
337 }
338 signature += argument_length;
339 }
340 CHECK_EQ(*signature, ')');
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700341 ++signature; // Skip the ')'.
Elliott Hughes9058f2b2012-03-22 18:06:48 -0700342 result += ')';
343 return result;
344}
345
346std::string PrettyReturnType(const char* signature) {
347 const char* return_type = strchr(signature, ')');
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700348 CHECK(return_type != nullptr);
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700349 ++return_type; // Skip ')'.
Elliott Hughes9058f2b2012-03-22 18:06:48 -0700350 return PrettyDescriptor(return_type);
351}
352
Andreas Gampec0d82292014-09-23 10:38:30 -0700353std::string PrettyJavaAccessFlags(uint32_t access_flags) {
354 std::string result;
355 if ((access_flags & kAccPublic) != 0) {
356 result += "public ";
357 }
358 if ((access_flags & kAccProtected) != 0) {
359 result += "protected ";
360 }
361 if ((access_flags & kAccPrivate) != 0) {
362 result += "private ";
363 }
364 if ((access_flags & kAccFinal) != 0) {
365 result += "final ";
366 }
367 if ((access_flags & kAccStatic) != 0) {
368 result += "static ";
369 }
David Brazdilca3c8c32016-09-06 14:04:48 +0100370 if ((access_flags & kAccAbstract) != 0) {
371 result += "abstract ";
372 }
373 if ((access_flags & kAccInterface) != 0) {
374 result += "interface ";
375 }
Andreas Gampec0d82292014-09-23 10:38:30 -0700376 if ((access_flags & kAccTransient) != 0) {
377 result += "transient ";
378 }
379 if ((access_flags & kAccVolatile) != 0) {
380 result += "volatile ";
381 }
382 if ((access_flags & kAccSynchronized) != 0) {
383 result += "synchronized ";
384 }
385 return result;
386}
387
Mathieu Chartiere6da9af2013-12-16 11:54:42 -0800388std::string PrettySize(int64_t byte_count) {
Elliott Hughesc967f782012-04-16 10:23:15 -0700389 // The byte thresholds at which we display amounts. A byte count is displayed
390 // in unit U when kUnitThresholds[U] <= bytes < kUnitThresholds[U+1].
Ian Rogersef7d42f2014-01-06 12:55:46 -0800391 static const int64_t kUnitThresholds[] = {
Elliott Hughesc967f782012-04-16 10:23:15 -0700392 0, // B up to...
393 3*1024, // KB up to...
394 2*1024*1024, // MB up to...
395 1024*1024*1024 // GB from here.
396 };
Mathieu Chartiere6da9af2013-12-16 11:54:42 -0800397 static const int64_t kBytesPerUnit[] = { 1, KB, MB, GB };
Elliott Hughesc967f782012-04-16 10:23:15 -0700398 static const char* const kUnitStrings[] = { "B", "KB", "MB", "GB" };
Mathieu Chartiere6da9af2013-12-16 11:54:42 -0800399 const char* negative_str = "";
400 if (byte_count < 0) {
401 negative_str = "-";
402 byte_count = -byte_count;
403 }
Elliott Hughesc967f782012-04-16 10:23:15 -0700404 int i = arraysize(kUnitThresholds);
405 while (--i > 0) {
406 if (byte_count >= kUnitThresholds[i]) {
407 break;
408 }
Ian Rogers3bb17a62012-01-27 23:56:44 -0800409 }
Brian Carlstrom474cc792014-03-07 14:18:15 -0800410 return StringPrintf("%s%" PRId64 "%s",
411 negative_str, byte_count / kBytesPerUnit[i], kUnitStrings[i]);
Ian Rogers3bb17a62012-01-27 23:56:44 -0800412}
413
Ian Rogers576ca0c2014-06-06 15:58:22 -0700414std::string PrintableChar(uint16_t ch) {
415 std::string result;
416 result += '\'';
417 if (NeedsEscaping(ch)) {
418 StringAppendF(&result, "\\u%04x", ch);
419 } else {
420 result += ch;
421 }
422 result += '\'';
423 return result;
424}
425
Ian Rogers68b56852014-08-29 20:19:11 -0700426std::string PrintableString(const char* utf) {
Elliott Hughes82914b62012-04-09 15:56:29 -0700427 std::string result;
428 result += '"';
Ian Rogers68b56852014-08-29 20:19:11 -0700429 const char* p = utf;
Elliott Hughes82914b62012-04-09 15:56:29 -0700430 size_t char_count = CountModifiedUtf8Chars(p);
431 for (size_t i = 0; i < char_count; ++i) {
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000432 uint32_t ch = GetUtf16FromUtf8(&p);
Elliott Hughes82914b62012-04-09 15:56:29 -0700433 if (ch == '\\') {
434 result += "\\\\";
435 } else if (ch == '\n') {
436 result += "\\n";
437 } else if (ch == '\r') {
438 result += "\\r";
439 } else if (ch == '\t') {
440 result += "\\t";
Elliott Hughes82914b62012-04-09 15:56:29 -0700441 } else {
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000442 const uint16_t leading = GetLeadingUtf16Char(ch);
443
444 if (NeedsEscaping(leading)) {
445 StringAppendF(&result, "\\u%04x", leading);
446 } else {
447 result += leading;
448 }
449
450 const uint32_t trailing = GetTrailingUtf16Char(ch);
451 if (trailing != 0) {
452 // All high surrogates will need escaping.
453 StringAppendF(&result, "\\u%04x", trailing);
454 }
Elliott Hughes82914b62012-04-09 15:56:29 -0700455 }
456 }
457 result += '"';
458 return result;
459}
460
Elliott Hughesd8c00d02012-01-30 14:08:31 -0800461// 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 -0700462std::string MangleForJni(const std::string& s) {
463 std::string result;
464 size_t char_count = CountModifiedUtf8Chars(s.c_str());
465 const char* cp = &s[0];
466 for (size_t i = 0; i < char_count; ++i) {
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000467 uint32_t ch = GetUtf16FromUtf8(&cp);
Elliott Hughesd8c00d02012-01-30 14:08:31 -0800468 if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')) {
469 result.push_back(ch);
470 } else if (ch == '.' || ch == '/') {
471 result += "_";
472 } else if (ch == '_') {
473 result += "_1";
474 } else if (ch == ';') {
475 result += "_2";
476 } else if (ch == '[') {
477 result += "_3";
Elliott Hughes79082e32011-08-25 12:07:32 -0700478 } else {
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000479 const uint16_t leading = GetLeadingUtf16Char(ch);
480 const uint32_t trailing = GetTrailingUtf16Char(ch);
481
482 StringAppendF(&result, "_0%04x", leading);
483 if (trailing != 0) {
484 StringAppendF(&result, "_0%04x", trailing);
485 }
Elliott Hughes79082e32011-08-25 12:07:32 -0700486 }
487 }
488 return result;
489}
490
Brian Carlstromf91c8c32011-09-21 17:30:34 -0700491std::string DotToDescriptor(const char* class_name) {
492 std::string descriptor(class_name);
493 std::replace(descriptor.begin(), descriptor.end(), '.', '/');
494 if (descriptor.length() > 0 && descriptor[0] != '[') {
495 descriptor = "L" + descriptor + ";";
496 }
497 return descriptor;
498}
499
Elliott Hughesf1a5adc2012-02-10 18:09:35 -0800500std::string DescriptorToDot(const char* descriptor) {
Elliott Hughes2435a572012-02-17 16:07:41 -0800501 size_t length = strlen(descriptor);
Ian Rogers1ff3c982014-08-12 02:30:58 -0700502 if (length > 1) {
503 if (descriptor[0] == 'L' && descriptor[length - 1] == ';') {
504 // Descriptors have the leading 'L' and trailing ';' stripped.
505 std::string result(descriptor + 1, length - 2);
506 std::replace(result.begin(), result.end(), '/', '.');
507 return result;
508 } else {
509 // For arrays the 'L' and ';' remain intact.
510 std::string result(descriptor);
511 std::replace(result.begin(), result.end(), '/', '.');
512 return result;
513 }
Elliott Hughes2435a572012-02-17 16:07:41 -0800514 }
Ian Rogers1ff3c982014-08-12 02:30:58 -0700515 // Do nothing for non-class/array descriptors.
Elliott Hughes2435a572012-02-17 16:07:41 -0800516 return descriptor;
Elliott Hughes91bf6cd2012-02-14 17:27:48 -0800517}
518
519std::string DescriptorToName(const char* descriptor) {
Elliott Hughesf1a5adc2012-02-10 18:09:35 -0800520 size_t length = strlen(descriptor);
Elliott Hughes2435a572012-02-17 16:07:41 -0800521 if (descriptor[0] == 'L' && descriptor[length - 1] == ';') {
522 std::string result(descriptor + 1, length - 2);
523 return result;
524 }
525 return descriptor;
Brian Carlstromaded5f72011-10-07 17:15:04 -0700526}
527
jeffhao10037c82012-01-23 15:06:23 -0800528// Helper for IsValidPartOfMemberNameUtf8(), a bit vector indicating valid low ascii.
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700529uint32_t DEX_MEMBER_VALID_LOW_ASCII[4] = {
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700530 0x00000000, // 00..1f low control characters; nothing valid
531 0x03ff2010, // 20..3f digits and symbols; valid: '0'..'9', '$', '-'
532 0x87fffffe, // 40..5f uppercase etc.; valid: 'A'..'Z', '_'
533 0x07fffffe // 60..7f lowercase etc.; valid: 'a'..'z'
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700534};
535
jeffhao10037c82012-01-23 15:06:23 -0800536// Helper for IsValidPartOfMemberNameUtf8(); do not call directly.
537bool IsValidPartOfMemberNameUtf8Slow(const char** pUtf8Ptr) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700538 /*
539 * It's a multibyte encoded character. Decode it and analyze. We
540 * accept anything that isn't (a) an improperly encoded low value,
541 * (b) an improper surrogate pair, (c) an encoded '\0', (d) a high
542 * control character, or (e) a high space, layout, or special
543 * character (U+00a0, U+2000..U+200f, U+2028..U+202f,
544 * U+fff0..U+ffff). This is all specified in the dex format
545 * document.
546 */
547
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000548 const uint32_t pair = GetUtf16FromUtf8(pUtf8Ptr);
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000549 const uint16_t leading = GetLeadingUtf16Char(pair);
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000550
Narayan Kamath8508e372015-05-06 14:55:43 +0100551 // We have a surrogate pair resulting from a valid 4 byte UTF sequence.
552 // No further checks are necessary because 4 byte sequences span code
553 // points [U+10000, U+1FFFFF], which are valid codepoints in a dex
554 // identifier. Furthermore, GetUtf16FromUtf8 guarantees that each of
555 // the surrogate halves are valid and well formed in this instance.
556 if (GetTrailingUtf16Char(pair) != 0) {
557 return true;
558 }
559
560
561 // We've encountered a one, two or three byte UTF-8 sequence. The
562 // three byte UTF-8 sequence could be one half of a surrogate pair.
563 switch (leading >> 8) {
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000564 case 0x00:
565 // It's only valid if it's above the ISO-8859-1 high space (0xa0).
566 return (leading > 0x00a0);
567 case 0xd8:
568 case 0xd9:
569 case 0xda:
570 case 0xdb:
Narayan Kamath8508e372015-05-06 14:55:43 +0100571 {
572 // We found a three byte sequence encoding one half of a surrogate.
573 // Look for the other half.
574 const uint32_t pair2 = GetUtf16FromUtf8(pUtf8Ptr);
575 const uint16_t trailing = GetLeadingUtf16Char(pair2);
576
577 return (GetTrailingUtf16Char(pair2) == 0) && (0xdc00 <= trailing && trailing <= 0xdfff);
578 }
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000579 case 0xdc:
580 case 0xdd:
581 case 0xde:
582 case 0xdf:
583 // It's a trailing surrogate, which is not valid at this point.
584 return false;
585 case 0x20:
586 case 0xff:
587 // It's in the range that has spaces, controls, and specials.
588 switch (leading & 0xfff8) {
Narayan Kamath8508e372015-05-06 14:55:43 +0100589 case 0x2000:
590 case 0x2008:
591 case 0x2028:
592 case 0xfff0:
593 case 0xfff8:
594 return false;
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000595 }
Narayan Kamath8508e372015-05-06 14:55:43 +0100596 return true;
597 default:
598 return true;
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700599 }
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000600
Narayan Kamath8508e372015-05-06 14:55:43 +0100601 UNREACHABLE();
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700602}
603
604/* Return whether the pointed-at modified-UTF-8 encoded character is
605 * valid as part of a member name, updating the pointer to point past
606 * the consumed character. This will consume two encoded UTF-16 code
607 * points if the character is encoded as a surrogate pair. Also, if
608 * this function returns false, then the given pointer may only have
609 * been partially advanced.
610 */
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700611static bool IsValidPartOfMemberNameUtf8(const char** pUtf8Ptr) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700612 uint8_t c = (uint8_t) **pUtf8Ptr;
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700613 if (LIKELY(c <= 0x7f)) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700614 // It's low-ascii, so check the table.
615 uint32_t wordIdx = c >> 5;
616 uint32_t bitIdx = c & 0x1f;
617 (*pUtf8Ptr)++;
618 return (DEX_MEMBER_VALID_LOW_ASCII[wordIdx] & (1 << bitIdx)) != 0;
619 }
620
621 // It's a multibyte encoded character. Call a non-inline function
622 // for the heavy lifting.
jeffhao10037c82012-01-23 15:06:23 -0800623 return IsValidPartOfMemberNameUtf8Slow(pUtf8Ptr);
624}
625
626bool IsValidMemberName(const char* s) {
627 bool angle_name = false;
628
Elliott Hughesb25c3f62012-03-26 16:35:06 -0700629 switch (*s) {
jeffhao10037c82012-01-23 15:06:23 -0800630 case '\0':
631 // The empty string is not a valid name.
632 return false;
633 case '<':
634 angle_name = true;
635 s++;
636 break;
637 }
638
639 while (true) {
640 switch (*s) {
641 case '\0':
642 return !angle_name;
643 case '>':
644 return angle_name && s[1] == '\0';
645 }
646
647 if (!IsValidPartOfMemberNameUtf8(&s)) {
648 return false;
649 }
650 }
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700651}
652
Elliott Hughes906e6852011-10-28 14:52:10 -0700653enum ClassNameType { kName, kDescriptor };
Ian Rogers7b078e82014-09-10 14:44:24 -0700654template<ClassNameType kType, char kSeparator>
655static bool IsValidClassName(const char* s) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700656 int arrayCount = 0;
657 while (*s == '[') {
658 arrayCount++;
659 s++;
660 }
661
662 if (arrayCount > 255) {
663 // Arrays may have no more than 255 dimensions.
664 return false;
665 }
666
Ian Rogers7b078e82014-09-10 14:44:24 -0700667 ClassNameType type = kType;
668 if (type != kDescriptor && arrayCount != 0) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700669 /*
670 * If we're looking at an array of some sort, then it doesn't
671 * matter if what is being asked for is a class name; the
672 * format looks the same as a type descriptor in that case, so
673 * treat it as such.
674 */
Elliott Hughes906e6852011-10-28 14:52:10 -0700675 type = kDescriptor;
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700676 }
677
Elliott Hughes906e6852011-10-28 14:52:10 -0700678 if (type == kDescriptor) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700679 /*
680 * We are looking for a descriptor. Either validate it as a
681 * single-character primitive type, or continue on to check the
682 * embedded class name (bracketed by "L" and ";").
683 */
684 switch (*(s++)) {
685 case 'B':
686 case 'C':
687 case 'D':
688 case 'F':
689 case 'I':
690 case 'J':
691 case 'S':
692 case 'Z':
693 // These are all single-character descriptors for primitive types.
694 return (*s == '\0');
695 case 'V':
696 // Non-array void is valid, but you can't have an array of void.
697 return (arrayCount == 0) && (*s == '\0');
698 case 'L':
699 // Class name: Break out and continue below.
700 break;
701 default:
702 // Oddball descriptor character.
703 return false;
704 }
705 }
706
707 /*
708 * We just consumed the 'L' that introduces a class name as part
709 * of a type descriptor, or we are looking for an unadorned class
710 * name.
711 */
712
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700713 bool sepOrFirst = true; // first character or just encountered a separator.
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700714 for (;;) {
715 uint8_t c = (uint8_t) *s;
716 switch (c) {
717 case '\0':
718 /*
719 * Premature end for a type descriptor, but valid for
720 * a class name as long as we haven't encountered an
721 * empty component (including the degenerate case of
722 * the empty string "").
723 */
Elliott Hughes906e6852011-10-28 14:52:10 -0700724 return (type == kName) && !sepOrFirst;
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700725 case ';':
726 /*
727 * Invalid character for a class name, but the
728 * legitimate end of a type descriptor. In the latter
729 * case, make sure that this is the end of the string
730 * and that it doesn't end with an empty component
731 * (including the degenerate case of "L;").
732 */
Elliott Hughes906e6852011-10-28 14:52:10 -0700733 return (type == kDescriptor) && !sepOrFirst && (s[1] == '\0');
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700734 case '/':
735 case '.':
Ian Rogers7b078e82014-09-10 14:44:24 -0700736 if (c != kSeparator) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700737 // The wrong separator character.
738 return false;
739 }
740 if (sepOrFirst) {
741 // Separator at start or two separators in a row.
742 return false;
743 }
744 sepOrFirst = true;
745 s++;
746 break;
747 default:
jeffhao10037c82012-01-23 15:06:23 -0800748 if (!IsValidPartOfMemberNameUtf8(&s)) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700749 return false;
750 }
751 sepOrFirst = false;
752 break;
753 }
754 }
755}
756
Elliott Hughes906e6852011-10-28 14:52:10 -0700757bool IsValidBinaryClassName(const char* s) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700758 return IsValidClassName<kName, '.'>(s);
Elliott Hughes906e6852011-10-28 14:52:10 -0700759}
760
761bool IsValidJniClassName(const char* s) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700762 return IsValidClassName<kName, '/'>(s);
Elliott Hughes906e6852011-10-28 14:52:10 -0700763}
764
765bool IsValidDescriptor(const char* s) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700766 return IsValidClassName<kDescriptor, '/'>(s);
Elliott Hughes906e6852011-10-28 14:52:10 -0700767}
768
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700769void Split(const std::string& s, char separator, std::vector<std::string>* result) {
Elliott Hughes34023802011-08-30 12:06:17 -0700770 const char* p = s.data();
771 const char* end = p + s.size();
772 while (p != end) {
Elliott Hughes48436bb2012-02-07 15:23:28 -0800773 if (*p == separator) {
Elliott Hughes34023802011-08-30 12:06:17 -0700774 ++p;
775 } else {
776 const char* start = p;
Elliott Hughes48436bb2012-02-07 15:23:28 -0800777 while (++p != end && *p != separator) {
778 // Skip to the next occurrence of the separator.
Elliott Hughes34023802011-08-30 12:06:17 -0700779 }
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700780 result->push_back(std::string(start, p - start));
Elliott Hughes34023802011-08-30 12:06:17 -0700781 }
782 }
783}
784
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700785std::string Trim(const std::string& s) {
Dave Allison70202782013-10-22 17:52:19 -0700786 std::string result;
787 unsigned int start_index = 0;
788 unsigned int end_index = s.size() - 1;
789
790 // Skip initial whitespace.
791 while (start_index < s.size()) {
792 if (!isspace(s[start_index])) {
793 break;
794 }
795 start_index++;
796 }
797
798 // Skip terminating whitespace.
799 while (end_index >= start_index) {
800 if (!isspace(s[end_index])) {
801 break;
802 }
803 end_index--;
804 }
805
806 // All spaces, no beef.
807 if (end_index < start_index) {
808 return "";
809 }
810 // Start_index is the first non-space, end_index is the last one.
811 return s.substr(start_index, end_index - start_index + 1);
812}
813
Elliott Hughes48436bb2012-02-07 15:23:28 -0800814template <typename StringT>
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700815std::string Join(const std::vector<StringT>& strings, char separator) {
Elliott Hughes48436bb2012-02-07 15:23:28 -0800816 if (strings.empty()) {
817 return "";
818 }
819
820 std::string result(strings[0]);
821 for (size_t i = 1; i < strings.size(); ++i) {
822 result += separator;
823 result += strings[i];
824 }
825 return result;
826}
827
828// Explicit instantiations.
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700829template std::string Join<std::string>(const std::vector<std::string>& strings, char separator);
830template std::string Join<const char*>(const std::vector<const char*>& strings, char separator);
Elliott Hughes48436bb2012-02-07 15:23:28 -0800831
Elliott Hughesf1a5adc2012-02-10 18:09:35 -0800832bool StartsWith(const std::string& s, const char* prefix) {
833 return s.compare(0, strlen(prefix), prefix) == 0;
834}
835
Brian Carlstrom7a967b32012-03-28 15:23:10 -0700836bool EndsWith(const std::string& s, const char* suffix) {
837 size_t suffix_length = strlen(suffix);
838 size_t string_length = s.size();
839 if (suffix_length > string_length) {
840 return false;
841 }
842 size_t offset = string_length - suffix_length;
843 return s.compare(offset, suffix_length, suffix) == 0;
844}
845
Elliott Hughes22869a92012-03-27 14:08:24 -0700846void SetThreadName(const char* thread_name) {
Elliott Hughesdcc24742011-09-07 14:02:44 -0700847 int hasAt = 0;
848 int hasDot = 0;
Elliott Hughes22869a92012-03-27 14:08:24 -0700849 const char* s = thread_name;
Elliott Hughesdcc24742011-09-07 14:02:44 -0700850 while (*s) {
851 if (*s == '.') {
852 hasDot = 1;
853 } else if (*s == '@') {
854 hasAt = 1;
855 }
856 s++;
857 }
Elliott Hughes22869a92012-03-27 14:08:24 -0700858 int len = s - thread_name;
Elliott Hughesdcc24742011-09-07 14:02:44 -0700859 if (len < 15 || hasAt || !hasDot) {
Elliott Hughes22869a92012-03-27 14:08:24 -0700860 s = thread_name;
Elliott Hughesdcc24742011-09-07 14:02:44 -0700861 } else {
Elliott Hughes22869a92012-03-27 14:08:24 -0700862 s = thread_name + len - 15;
Elliott Hughesdcc24742011-09-07 14:02:44 -0700863 }
Elliott Hughes0a18df82015-01-09 15:16:16 -0800864#if defined(__linux__)
Elliott Hughes7c6a61e2012-03-12 18:01:41 -0700865 // pthread_setname_np fails rather than truncating long strings.
Elliott Hughes0a18df82015-01-09 15:16:16 -0800866 char buf[16]; // MAX_TASK_COMM_LEN=16 is hard-coded in the kernel.
Elliott Hughesdcc24742011-09-07 14:02:44 -0700867 strncpy(buf, s, sizeof(buf)-1);
868 buf[sizeof(buf)-1] = '\0';
869 errno = pthread_setname_np(pthread_self(), buf);
870 if (errno != 0) {
871 PLOG(WARNING) << "Unable to set the name of current thread to '" << buf << "'";
872 }
Elliott Hughes0a18df82015-01-09 15:16:16 -0800873#else // __APPLE__
Elliott Hughes22869a92012-03-27 14:08:24 -0700874 pthread_setname_np(thread_name);
Elliott Hughesdcc24742011-09-07 14:02:44 -0700875#endif
876}
877
Brian Carlstrom29212012013-09-12 22:18:30 -0700878void GetTaskStats(pid_t tid, char* state, int* utime, int* stime, int* task_cpu) {
879 *utime = *stime = *task_cpu = 0;
Elliott Hughesbfe487b2011-10-26 15:48:55 -0700880 std::string stats;
Elliott Hughes8a31b502012-04-30 19:36:11 -0700881 if (!ReadFileToString(StringPrintf("/proc/self/task/%d/stat", tid), &stats)) {
Elliott Hughesbfe487b2011-10-26 15:48:55 -0700882 return;
883 }
884 // Skip the command, which may contain spaces.
885 stats = stats.substr(stats.find(')') + 2);
886 // Extract the three fields we care about.
887 std::vector<std::string> fields;
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700888 Split(stats, ' ', &fields);
Brian Carlstrom29212012013-09-12 22:18:30 -0700889 *state = fields[0][0];
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700890 *utime = strtoull(fields[11].c_str(), nullptr, 10);
891 *stime = strtoull(fields[12].c_str(), nullptr, 10);
892 *task_cpu = strtoull(fields[36].c_str(), nullptr, 10);
Elliott Hughesbfe487b2011-10-26 15:48:55 -0700893}
894
Elliott Hughes1bac54f2012-03-16 12:48:31 -0700895std::string GetSchedulerGroupName(pid_t tid) {
896 // /proc/<pid>/cgroup looks like this:
897 // 2:devices:/
898 // 1:cpuacct,cpu:/
899 // We want the third field from the line whose second field contains the "cpu" token.
900 std::string cgroup_file;
901 if (!ReadFileToString(StringPrintf("/proc/self/task/%d/cgroup", tid), &cgroup_file)) {
902 return "";
903 }
904 std::vector<std::string> cgroup_lines;
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700905 Split(cgroup_file, '\n', &cgroup_lines);
Elliott Hughes1bac54f2012-03-16 12:48:31 -0700906 for (size_t i = 0; i < cgroup_lines.size(); ++i) {
907 std::vector<std::string> cgroup_fields;
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700908 Split(cgroup_lines[i], ':', &cgroup_fields);
Elliott Hughes1bac54f2012-03-16 12:48:31 -0700909 std::vector<std::string> cgroups;
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700910 Split(cgroup_fields[1], ',', &cgroups);
Andreas Gampe277ccbd2014-11-03 21:36:10 -0800911 for (size_t j = 0; j < cgroups.size(); ++j) {
912 if (cgroups[j] == "cpu") {
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700913 return cgroup_fields[2].substr(1); // Skip the leading slash.
Elliott Hughes1bac54f2012-03-16 12:48:31 -0700914 }
915 }
916 }
917 return "";
918}
919
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800920const char* GetAndroidRoot() {
921 const char* android_root = getenv("ANDROID_ROOT");
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700922 if (android_root == nullptr) {
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800923 if (OS::DirectoryExists("/system")) {
924 android_root = "/system";
Brian Carlstroma9f19782011-10-13 00:14:47 -0700925 } else {
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800926 LOG(FATAL) << "ANDROID_ROOT not set and /system does not exist";
927 return "";
Brian Carlstroma9f19782011-10-13 00:14:47 -0700928 }
929 }
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800930 if (!OS::DirectoryExists(android_root)) {
931 LOG(FATAL) << "Failed to find ANDROID_ROOT directory " << android_root;
Brian Carlstroma9f19782011-10-13 00:14:47 -0700932 return "";
933 }
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800934 return android_root;
935}
Brian Carlstroma9f19782011-10-13 00:14:47 -0700936
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800937const char* GetAndroidData() {
Alex Lighta59dd802014-07-02 16:28:08 -0700938 std::string error_msg;
939 const char* dir = GetAndroidDataSafe(&error_msg);
940 if (dir != nullptr) {
941 return dir;
942 } else {
943 LOG(FATAL) << error_msg;
944 return "";
945 }
946}
947
948const char* GetAndroidDataSafe(std::string* error_msg) {
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800949 const char* android_data = getenv("ANDROID_DATA");
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700950 if (android_data == nullptr) {
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800951 if (OS::DirectoryExists("/data")) {
952 android_data = "/data";
953 } else {
Alex Lighta59dd802014-07-02 16:28:08 -0700954 *error_msg = "ANDROID_DATA not set and /data does not exist";
955 return nullptr;
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800956 }
957 }
958 if (!OS::DirectoryExists(android_data)) {
Alex Lighta59dd802014-07-02 16:28:08 -0700959 *error_msg = StringPrintf("Failed to find ANDROID_DATA directory %s", android_data);
960 return nullptr;
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800961 }
962 return android_data;
963}
964
Alex Lighta59dd802014-07-02 16:28:08 -0700965void GetDalvikCache(const char* subdir, const bool create_if_absent, std::string* dalvik_cache,
Andreas Gampe3c13a792014-09-18 20:56:04 -0700966 bool* have_android_data, bool* dalvik_cache_exists, bool* is_global_cache) {
Alex Lighta59dd802014-07-02 16:28:08 -0700967 CHECK(subdir != nullptr);
968 std::string error_msg;
969 const char* android_data = GetAndroidDataSafe(&error_msg);
970 if (android_data == nullptr) {
971 *have_android_data = false;
972 *dalvik_cache_exists = false;
Andreas Gampe3c13a792014-09-18 20:56:04 -0700973 *is_global_cache = false;
Alex Lighta59dd802014-07-02 16:28:08 -0700974 return;
975 } else {
976 *have_android_data = true;
977 }
978 const std::string dalvik_cache_root(StringPrintf("%s/dalvik-cache/", android_data));
979 *dalvik_cache = dalvik_cache_root + subdir;
980 *dalvik_cache_exists = OS::DirectoryExists(dalvik_cache->c_str());
Andreas Gampe3c13a792014-09-18 20:56:04 -0700981 *is_global_cache = strcmp(android_data, "/data") == 0;
982 if (create_if_absent && !*dalvik_cache_exists && !*is_global_cache) {
Alex Lighta59dd802014-07-02 16:28:08 -0700983 // Don't create the system's /data/dalvik-cache/... because it needs special permissions.
984 *dalvik_cache_exists = ((mkdir(dalvik_cache_root.c_str(), 0700) == 0 || errno == EEXIST) &&
985 (mkdir(dalvik_cache->c_str(), 0700) == 0 || errno == EEXIST));
986 }
987}
988
Richard Uhler55b58b62016-08-12 09:05:13 -0700989std::string GetDalvikCache(const char* subdir) {
Narayan Kamath11d9f062014-04-23 20:24:57 +0100990 CHECK(subdir != nullptr);
Brian Carlstrom41ccffd2014-05-06 10:37:30 -0700991 const char* android_data = GetAndroidData();
992 const std::string dalvik_cache_root(StringPrintf("%s/dalvik-cache/", android_data));
Narayan Kamath11d9f062014-04-23 20:24:57 +0100993 const std::string dalvik_cache = dalvik_cache_root + subdir;
Andreas Gampe40da2862015-02-27 12:49:04 -0800994 if (!OS::DirectoryExists(dalvik_cache.c_str())) {
Richard Uhler55b58b62016-08-12 09:05:13 -0700995 // TODO: Check callers. Traditional behavior is to not abort.
996 return "";
Brian Carlstroma9f19782011-10-13 00:14:47 -0700997 }
Brian Carlstrom7675e162013-06-10 16:18:04 -0700998 return dalvik_cache;
Brian Carlstroma9f19782011-10-13 00:14:47 -0700999}
1000
Alex Lighta59dd802014-07-02 16:28:08 -07001001bool GetDalvikCacheFilename(const char* location, const char* cache_location,
1002 std::string* filename, std::string* error_msg) {
Ian Rogerse6060102013-05-16 12:01:04 -07001003 if (location[0] != '/') {
Alex Lighta59dd802014-07-02 16:28:08 -07001004 *error_msg = StringPrintf("Expected path in location to be absolute: %s", location);
1005 return false;
Ian Rogerse6060102013-05-16 12:01:04 -07001006 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001007 std::string cache_file(&location[1]); // skip leading slash
Alex Light6e183f22014-07-18 14:57:04 -07001008 if (!EndsWith(location, ".dex") && !EndsWith(location, ".art") && !EndsWith(location, ".oat")) {
Brian Carlstrom30e2ea42013-06-19 23:25:37 -07001009 cache_file += "/";
1010 cache_file += DexFile::kClassesDex;
1011 }
Brian Carlstromb7bbba42011-10-13 14:58:47 -07001012 std::replace(cache_file.begin(), cache_file.end(), '/', '@');
Alex Lighta59dd802014-07-02 16:28:08 -07001013 *filename = StringPrintf("%s/%s", cache_location, cache_file.c_str());
1014 return true;
1015}
1016
Brian Carlstrom2afe4942014-05-19 10:25:33 -07001017static void InsertIsaDirectory(const InstructionSet isa, std::string* filename) {
Brian Carlstrom0e12bdc2014-05-14 17:44:28 -07001018 // in = /foo/bar/baz
1019 // out = /foo/bar/<isa>/baz
1020 size_t pos = filename->rfind('/');
1021 CHECK_NE(pos, std::string::npos) << *filename << " " << isa;
1022 filename->insert(pos, "/", 1);
1023 filename->insert(pos + 1, GetInstructionSetString(isa));
1024}
1025
1026std::string GetSystemImageFilename(const char* location, const InstructionSet isa) {
1027 // location = /system/framework/boot.art
1028 // filename = /system/framework/<isa>/boot.art
1029 std::string filename(location);
Brian Carlstrom2afe4942014-05-19 10:25:33 -07001030 InsertIsaDirectory(isa, &filename);
Brian Carlstrom0e12bdc2014-05-14 17:44:28 -07001031 return filename;
1032}
1033
Calin Juravle2e2db782016-02-23 12:00:03 +00001034int ExecAndReturnCode(std::vector<std::string>& arg_vector, std::string* error_msg) {
Brian Carlstrom6449c622014-02-10 23:48:36 -08001035 const std::string command_line(Join(arg_vector, ' '));
Brian Carlstrom6449c622014-02-10 23:48:36 -08001036 CHECK_GE(arg_vector.size(), 1U) << command_line;
1037
1038 // Convert the args to char pointers.
1039 const char* program = arg_vector[0].c_str();
1040 std::vector<char*> args;
Brian Carlstrom35d8b8e2014-02-25 10:51:11 -08001041 for (size_t i = 0; i < arg_vector.size(); ++i) {
1042 const std::string& arg = arg_vector[i];
1043 char* arg_str = const_cast<char*>(arg.c_str());
1044 CHECK(arg_str != nullptr) << i;
1045 args.push_back(arg_str);
Brian Carlstrom6449c622014-02-10 23:48:36 -08001046 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001047 args.push_back(nullptr);
Brian Carlstrom6449c622014-02-10 23:48:36 -08001048
1049 // fork and exec
1050 pid_t pid = fork();
1051 if (pid == 0) {
1052 // no allocation allowed between fork and exec
1053
1054 // change process groups, so we don't get reaped by ProcessManager
1055 setpgid(0, 0);
1056
David Sehrd106d9f2016-08-16 19:22:57 -07001057 // (b/30160149): protect subprocesses from modifications to LD_LIBRARY_PATH, etc.
1058 // Use the snapshot of the environment from the time the runtime was created.
1059 char** envp = (Runtime::Current() == nullptr) ? nullptr : Runtime::Current()->GetEnvSnapshot();
1060 if (envp == nullptr) {
1061 execv(program, &args[0]);
1062 } else {
1063 execve(program, &args[0], envp);
1064 }
1065 PLOG(ERROR) << "Failed to execve(" << command_line << ")";
Tobias Lindskogae35c372015-11-04 19:41:21 +01001066 // _exit to avoid atexit handlers in child.
1067 _exit(1);
Brian Carlstrom6449c622014-02-10 23:48:36 -08001068 } else {
1069 if (pid == -1) {
1070 *error_msg = StringPrintf("Failed to execv(%s) because fork failed: %s",
1071 command_line.c_str(), strerror(errno));
Calin Juravle2e2db782016-02-23 12:00:03 +00001072 return -1;
Brian Carlstrom6449c622014-02-10 23:48:36 -08001073 }
1074
1075 // wait for subprocess to finish
Calin Juravle2e2db782016-02-23 12:00:03 +00001076 int status = -1;
Brian Carlstrom6449c622014-02-10 23:48:36 -08001077 pid_t got_pid = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0));
1078 if (got_pid != pid) {
1079 *error_msg = StringPrintf("Failed after fork for execv(%s) because waitpid failed: "
1080 "wanted %d, got %d: %s",
1081 command_line.c_str(), pid, got_pid, strerror(errno));
Calin Juravle2e2db782016-02-23 12:00:03 +00001082 return -1;
Brian Carlstrom6449c622014-02-10 23:48:36 -08001083 }
Calin Juravle2e2db782016-02-23 12:00:03 +00001084 if (WIFEXITED(status)) {
1085 return WEXITSTATUS(status);
Brian Carlstrom6449c622014-02-10 23:48:36 -08001086 }
Calin Juravle2e2db782016-02-23 12:00:03 +00001087 return -1;
1088 }
1089}
1090
1091bool Exec(std::vector<std::string>& arg_vector, std::string* error_msg) {
1092 int status = ExecAndReturnCode(arg_vector, error_msg);
1093 if (status != 0) {
1094 const std::string command_line(Join(arg_vector, ' '));
1095 *error_msg = StringPrintf("Failed execv(%s) because non-0 exit status",
1096 command_line.c_str());
1097 return false;
Brian Carlstrom6449c622014-02-10 23:48:36 -08001098 }
1099 return true;
1100}
1101
Calin Juravle5e2b9712015-12-18 14:10:00 +02001102bool FileExists(const std::string& filename) {
1103 struct stat buffer;
1104 return stat(filename.c_str(), &buffer) == 0;
1105}
1106
Calin Juravleb9c1b9b2016-03-17 17:07:52 +00001107bool FileExistsAndNotEmpty(const std::string& filename) {
1108 struct stat buffer;
1109 if (stat(filename.c_str(), &buffer) != 0) {
1110 return false;
1111 }
1112 return buffer.st_size > 0;
1113}
1114
David Brazdil7b49e6c2016-09-01 11:06:18 +01001115std::string ReplaceFileExtension(const std::string& filename, const std::string& new_extension) {
1116 const size_t last_ext = filename.find_last_of('.');
1117 if (last_ext == std::string::npos) {
1118 return filename + "." + new_extension;
1119 } else {
1120 return filename.substr(0, last_ext + 1) + new_extension;
1121 }
1122}
1123
Mathieu Chartier76433272014-09-26 14:32:37 -07001124std::string PrettyDescriptor(Primitive::Type type) {
1125 return PrettyDescriptor(Primitive::Descriptor(type));
1126}
1127
Nicolas Geoffrayabbb0f72015-10-29 18:55:58 +00001128static void ParseStringAfterChar(const std::string& s,
1129 char c,
1130 std::string* parsed_value,
1131 UsageFn Usage) {
1132 std::string::size_type colon = s.find(c);
1133 if (colon == std::string::npos) {
1134 Usage("Missing char %c in option %s\n", c, s.c_str());
1135 }
1136 // Add one to remove the char we were trimming until.
1137 *parsed_value = s.substr(colon + 1);
1138}
1139
1140void ParseDouble(const std::string& option,
1141 char after_char,
1142 double min,
1143 double max,
1144 double* parsed_value,
1145 UsageFn Usage) {
1146 std::string substring;
1147 ParseStringAfterChar(option, after_char, &substring, Usage);
1148 bool sane_val = true;
1149 double value;
1150 if ((false)) {
1151 // TODO: this doesn't seem to work on the emulator. b/15114595
1152 std::stringstream iss(substring);
1153 iss >> value;
1154 // Ensure that we have a value, there was no cruft after it and it satisfies a sensible range.
1155 sane_val = iss.eof() && (value >= min) && (value <= max);
1156 } else {
1157 char* end = nullptr;
1158 value = strtod(substring.c_str(), &end);
1159 sane_val = *end == '\0' && value >= min && value <= max;
1160 }
1161 if (!sane_val) {
1162 Usage("Invalid double value %s for option %s\n", substring.c_str(), option.c_str());
1163 }
1164 *parsed_value = value;
1165}
1166
Calin Juravle4d77b6a2015-12-01 18:38:09 +00001167int64_t GetFileSizeBytes(const std::string& filename) {
1168 struct stat stat_buf;
1169 int rc = stat(filename.c_str(), &stat_buf);
1170 return rc == 0 ? stat_buf.st_size : -1;
1171}
1172
Mathieu Chartier4d87df62016-01-07 15:14:19 -08001173void SleepForever() {
1174 while (true) {
1175 usleep(1000000);
1176 }
1177}
1178
Elliott Hughes42ee1422011-09-06 12:33:32 -07001179} // namespace art