blob: 4732f59ae10c87e0e83ef97086efd6dfafe959e3 [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
Andreas Gampe9186ced2016-12-12 14:28:21 -080028#include "android-base/strings.h"
29
Brian Carlstrom6449c622014-02-10 23:48:36 -080030#include "base/stl_util.h"
Elliott Hughes76160052012-12-12 16:31:20 -080031#include "base/unix_file/fd_file.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070032#include "dex_file-inl.h"
Andreas Gampe5073fed2015-08-10 11:40:25 -070033#include "dex_instruction.h"
Nicolas Geoffray524e7ea2015-10-16 17:13:34 +010034#include "oat_quick_method_header.h"
buzbeec143c552011-08-20 17:38:58 -070035#include "os.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070036#include "scoped_thread_state_change-inl.h"
Ian Rogersa6724902013-09-23 09:23:37 -070037#include "utf-inl.h"
Elliott Hughes11e45072011-08-16 17:40:46 -070038
Elliott Hughes4ae722a2012-03-13 11:08:51 -070039#if defined(__APPLE__)
Brian Carlstrom7934ac22013-07-26 10:54:15 -070040#include "AvailabilityMacros.h" // For MAC_OS_X_VERSION_MAX_ALLOWED
Elliott Hughesf1498432012-03-28 19:34:27 -070041#include <sys/syscall.h>
David Sehrfa442002016-08-22 18:42:08 -070042#include <crt_externs.h>
Elliott Hughes4ae722a2012-03-13 11:08:51 -070043#endif
44
Elliott Hughes058a6de2012-05-24 19:13:02 -070045#if defined(__linux__)
Elliott Hughese1aee692012-01-17 16:40:10 -080046#include <linux/unistd.h>
Elliott Hughese1aee692012-01-17 16:40:10 -080047#endif
48
Elliott Hughes11e45072011-08-16 17:40:46 -070049namespace art {
50
Alex Light9c20a142016-08-23 15:05:12 -070051static const uint8_t kBase64Map[256] = {
52 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
53 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
54 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
55 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
56 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
57 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
58 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, // NOLINT
59 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, // NOLINT
60 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
61 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, // NOLINT
62 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, // NOLINT
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, 255, 255, 255, 255, 255, 255, 255, 255,
72 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
73 255, 255, 255, 255
74};
75
76uint8_t* DecodeBase64(const char* src, size_t* dst_size) {
77 std::vector<uint8_t> tmp;
78 uint32_t t = 0, y = 0;
79 int g = 3;
80 for (size_t i = 0; src[i] != '\0'; ++i) {
81 uint8_t c = kBase64Map[src[i] & 0xFF];
82 if (c == 255) continue;
83 // the final = symbols are read and used to trim the remaining bytes
84 if (c == 254) {
85 c = 0;
86 // prevent g < 0 which would potentially allow an overflow later
87 if (--g < 0) {
88 *dst_size = 0;
89 return nullptr;
90 }
91 } else if (g != 3) {
92 // we only allow = to be at the end
93 *dst_size = 0;
94 return nullptr;
95 }
96 t = (t << 6) | c;
97 if (++y == 4) {
98 tmp.push_back((t >> 16) & 255);
99 if (g > 1) {
100 tmp.push_back((t >> 8) & 255);
101 }
102 if (g > 2) {
103 tmp.push_back(t & 255);
104 }
105 y = t = 0;
106 }
107 }
108 if (y != 0) {
109 *dst_size = 0;
110 return nullptr;
111 }
112 std::unique_ptr<uint8_t[]> dst(new uint8_t[tmp.size()]);
113 if (dst_size != nullptr) {
114 *dst_size = tmp.size();
115 } else {
116 *dst_size = 0;
117 }
118 std::copy(tmp.begin(), tmp.end(), dst.get());
119 return dst.release();
120}
121
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800122pid_t GetTid() {
Brian Carlstromf3a26412012-08-24 11:06:02 -0700123#if defined(__APPLE__)
124 uint64_t owner;
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700125 CHECK_PTHREAD_CALL(pthread_threadid_np, (nullptr, &owner), __FUNCTION__); // Requires Mac OS 10.6
Brian Carlstromf3a26412012-08-24 11:06:02 -0700126 return owner;
Elliott Hughes323aa862014-08-20 15:00:04 -0700127#elif defined(__BIONIC__)
128 return gettid();
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800129#else
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800130 return syscall(__NR_gettid);
131#endif
132}
133
Elliott Hughes289be852012-06-12 13:57:20 -0700134std::string GetThreadName(pid_t tid) {
135 std::string result;
136 if (ReadFileToString(StringPrintf("/proc/self/task/%d/comm", tid), &result)) {
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700137 result.resize(result.size() - 1); // Lose the trailing '\n'.
Elliott Hughes289be852012-06-12 13:57:20 -0700138 } else {
139 result = "<unknown>";
140 }
141 return result;
142}
143
Elliott Hughesd92bec42011-09-02 17:04:36 -0700144bool ReadFileToString(const std::string& file_name, std::string* result) {
Andreas Gampedf878922015-08-13 16:44:54 -0700145 File file(file_name, O_RDONLY, false);
146 if (!file.IsOpened()) {
Elliott Hughesd92bec42011-09-02 17:04:36 -0700147 return false;
148 }
buzbeec143c552011-08-20 17:38:58 -0700149
Elliott Hughes3b6baaa2011-10-14 19:13:56 -0700150 std::vector<char> buf(8 * KB);
buzbeec143c552011-08-20 17:38:58 -0700151 while (true) {
Andreas Gampea6dfdae2015-02-24 15:50:19 -0800152 int64_t n = TEMP_FAILURE_RETRY(read(file.Fd(), &buf[0], buf.size()));
Elliott Hughesd92bec42011-09-02 17:04:36 -0700153 if (n == -1) {
154 return false;
buzbeec143c552011-08-20 17:38:58 -0700155 }
Elliott Hughesd92bec42011-09-02 17:04:36 -0700156 if (n == 0) {
157 return true;
158 }
Elliott Hughes3b6baaa2011-10-14 19:13:56 -0700159 result->append(&buf[0], n);
buzbeec143c552011-08-20 17:38:58 -0700160 }
buzbeec143c552011-08-20 17:38:58 -0700161}
162
Andreas Gampea6dfdae2015-02-24 15:50:19 -0800163bool PrintFileToLog(const std::string& file_name, LogSeverity level) {
Andreas Gampedf878922015-08-13 16:44:54 -0700164 File file(file_name, O_RDONLY, false);
165 if (!file.IsOpened()) {
Andreas Gampea6dfdae2015-02-24 15:50:19 -0800166 return false;
167 }
168
169 constexpr size_t kBufSize = 256; // Small buffer. Avoid stack overflow and stack size warnings.
170 char buf[kBufSize + 1]; // +1 for terminator.
171 size_t filled_to = 0;
172 while (true) {
173 DCHECK_LT(filled_to, kBufSize);
174 int64_t n = TEMP_FAILURE_RETRY(read(file.Fd(), &buf[filled_to], kBufSize - filled_to));
175 if (n <= 0) {
176 // Print the rest of the buffer, if it exists.
177 if (filled_to > 0) {
178 buf[filled_to] = 0;
179 LOG(level) << buf;
180 }
181 return n == 0;
182 }
183 // Scan for '\n'.
184 size_t i = filled_to;
185 bool found_newline = false;
186 for (; i < filled_to + n; ++i) {
187 if (buf[i] == '\n') {
188 // Found a line break, that's something to print now.
189 buf[i] = 0;
190 LOG(level) << buf;
191 // Copy the rest to the front.
192 if (i + 1 < filled_to + n) {
193 memmove(&buf[0], &buf[i + 1], filled_to + n - i - 1);
194 filled_to = filled_to + n - i - 1;
195 } else {
196 filled_to = 0;
197 }
198 found_newline = true;
199 break;
200 }
201 }
202 if (found_newline) {
203 continue;
204 } else {
205 filled_to += n;
206 // Check if we must flush now.
207 if (filled_to == kBufSize) {
208 buf[kBufSize] = 0;
209 LOG(level) << buf;
210 filled_to = 0;
211 }
212 }
213 }
214}
215
Ian Rogers1ff3c982014-08-12 02:30:58 -0700216std::string PrettyDescriptor(const char* descriptor) {
Elliott Hughes11e45072011-08-16 17:40:46 -0700217 // Count the number of '['s to get the dimensionality.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700218 const char* c = descriptor;
Elliott Hughes11e45072011-08-16 17:40:46 -0700219 size_t dim = 0;
220 while (*c == '[') {
221 dim++;
222 c++;
223 }
224
225 // Reference or primitive?
226 if (*c == 'L') {
227 // "[[La/b/C;" -> "a.b.C[][]".
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700228 c++; // Skip the 'L'.
Elliott Hughes11e45072011-08-16 17:40:46 -0700229 } else {
230 // "[[B" -> "byte[][]".
231 // To make life easier, we make primitives look like unqualified
232 // reference types.
233 switch (*c) {
234 case 'B': c = "byte;"; break;
235 case 'C': c = "char;"; break;
236 case 'D': c = "double;"; break;
237 case 'F': c = "float;"; break;
238 case 'I': c = "int;"; break;
239 case 'J': c = "long;"; break;
240 case 'S': c = "short;"; break;
241 case 'Z': c = "boolean;"; break;
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700242 case 'V': c = "void;"; break; // Used when decoding return types.
Elliott Hughes5174fe62011-08-23 15:12:35 -0700243 default: return descriptor;
Elliott Hughes11e45072011-08-16 17:40:46 -0700244 }
245 }
246
247 // At this point, 'c' is a string of the form "fully/qualified/Type;"
248 // or "primitive;". Rewrite the type with '.' instead of '/':
249 std::string result;
250 const char* p = c;
251 while (*p != ';') {
252 char ch = *p++;
253 if (ch == '/') {
254 ch = '.';
255 }
256 result.push_back(ch);
257 }
258 // ...and replace the semicolon with 'dim' "[]" pairs:
Ian Rogers1ff3c982014-08-12 02:30:58 -0700259 for (size_t i = 0; i < dim; ++i) {
Elliott Hughes11e45072011-08-16 17:40:46 -0700260 result += "[]";
261 }
262 return result;
263}
264
Elliott Hughes9058f2b2012-03-22 18:06:48 -0700265std::string PrettyArguments(const char* signature) {
266 std::string result;
267 result += '(';
268 CHECK_EQ(*signature, '(');
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700269 ++signature; // Skip the '('.
Elliott Hughes9058f2b2012-03-22 18:06:48 -0700270 while (*signature != ')') {
271 size_t argument_length = 0;
272 while (signature[argument_length] == '[') {
273 ++argument_length;
274 }
275 if (signature[argument_length] == 'L') {
276 argument_length = (strchr(signature, ';') - signature + 1);
277 } else {
278 ++argument_length;
279 }
Ian Rogers1ff3c982014-08-12 02:30:58 -0700280 {
281 std::string argument_descriptor(signature, argument_length);
282 result += PrettyDescriptor(argument_descriptor.c_str());
283 }
Elliott Hughes9058f2b2012-03-22 18:06:48 -0700284 if (signature[argument_length] != ')') {
285 result += ", ";
286 }
287 signature += argument_length;
288 }
289 CHECK_EQ(*signature, ')');
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700290 ++signature; // Skip the ')'.
Elliott Hughes9058f2b2012-03-22 18:06:48 -0700291 result += ')';
292 return result;
293}
294
295std::string PrettyReturnType(const char* signature) {
296 const char* return_type = strchr(signature, ')');
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700297 CHECK(return_type != nullptr);
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700298 ++return_type; // Skip ')'.
Elliott Hughes9058f2b2012-03-22 18:06:48 -0700299 return PrettyDescriptor(return_type);
300}
301
Andreas Gampec0d82292014-09-23 10:38:30 -0700302std::string PrettyJavaAccessFlags(uint32_t access_flags) {
303 std::string result;
304 if ((access_flags & kAccPublic) != 0) {
305 result += "public ";
306 }
307 if ((access_flags & kAccProtected) != 0) {
308 result += "protected ";
309 }
310 if ((access_flags & kAccPrivate) != 0) {
311 result += "private ";
312 }
313 if ((access_flags & kAccFinal) != 0) {
314 result += "final ";
315 }
316 if ((access_flags & kAccStatic) != 0) {
317 result += "static ";
318 }
David Brazdilca3c8c32016-09-06 14:04:48 +0100319 if ((access_flags & kAccAbstract) != 0) {
320 result += "abstract ";
321 }
322 if ((access_flags & kAccInterface) != 0) {
323 result += "interface ";
324 }
Andreas Gampec0d82292014-09-23 10:38:30 -0700325 if ((access_flags & kAccTransient) != 0) {
326 result += "transient ";
327 }
328 if ((access_flags & kAccVolatile) != 0) {
329 result += "volatile ";
330 }
331 if ((access_flags & kAccSynchronized) != 0) {
332 result += "synchronized ";
333 }
334 return result;
335}
336
Mathieu Chartiere6da9af2013-12-16 11:54:42 -0800337std::string PrettySize(int64_t byte_count) {
Elliott Hughesc967f782012-04-16 10:23:15 -0700338 // The byte thresholds at which we display amounts. A byte count is displayed
339 // in unit U when kUnitThresholds[U] <= bytes < kUnitThresholds[U+1].
Ian Rogersef7d42f2014-01-06 12:55:46 -0800340 static const int64_t kUnitThresholds[] = {
Elliott Hughesc967f782012-04-16 10:23:15 -0700341 0, // B up to...
342 3*1024, // KB up to...
343 2*1024*1024, // MB up to...
344 1024*1024*1024 // GB from here.
345 };
Mathieu Chartiere6da9af2013-12-16 11:54:42 -0800346 static const int64_t kBytesPerUnit[] = { 1, KB, MB, GB };
Elliott Hughesc967f782012-04-16 10:23:15 -0700347 static const char* const kUnitStrings[] = { "B", "KB", "MB", "GB" };
Mathieu Chartiere6da9af2013-12-16 11:54:42 -0800348 const char* negative_str = "";
349 if (byte_count < 0) {
350 negative_str = "-";
351 byte_count = -byte_count;
352 }
Elliott Hughesc967f782012-04-16 10:23:15 -0700353 int i = arraysize(kUnitThresholds);
354 while (--i > 0) {
355 if (byte_count >= kUnitThresholds[i]) {
356 break;
357 }
Ian Rogers3bb17a62012-01-27 23:56:44 -0800358 }
Brian Carlstrom474cc792014-03-07 14:18:15 -0800359 return StringPrintf("%s%" PRId64 "%s",
360 negative_str, byte_count / kBytesPerUnit[i], kUnitStrings[i]);
Ian Rogers3bb17a62012-01-27 23:56:44 -0800361}
362
Andreas Gampe9186ced2016-12-12 14:28:21 -0800363static inline constexpr bool NeedsEscaping(uint16_t ch) {
364 return (ch < ' ' || ch > '~');
365}
366
Ian Rogers576ca0c2014-06-06 15:58:22 -0700367std::string PrintableChar(uint16_t ch) {
368 std::string result;
369 result += '\'';
370 if (NeedsEscaping(ch)) {
371 StringAppendF(&result, "\\u%04x", ch);
372 } else {
373 result += ch;
374 }
375 result += '\'';
376 return result;
377}
378
Ian Rogers68b56852014-08-29 20:19:11 -0700379std::string PrintableString(const char* utf) {
Elliott Hughes82914b62012-04-09 15:56:29 -0700380 std::string result;
381 result += '"';
Ian Rogers68b56852014-08-29 20:19:11 -0700382 const char* p = utf;
Elliott Hughes82914b62012-04-09 15:56:29 -0700383 size_t char_count = CountModifiedUtf8Chars(p);
384 for (size_t i = 0; i < char_count; ++i) {
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000385 uint32_t ch = GetUtf16FromUtf8(&p);
Elliott Hughes82914b62012-04-09 15:56:29 -0700386 if (ch == '\\') {
387 result += "\\\\";
388 } else if (ch == '\n') {
389 result += "\\n";
390 } else if (ch == '\r') {
391 result += "\\r";
392 } else if (ch == '\t') {
393 result += "\\t";
Elliott Hughes82914b62012-04-09 15:56:29 -0700394 } else {
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000395 const uint16_t leading = GetLeadingUtf16Char(ch);
396
397 if (NeedsEscaping(leading)) {
398 StringAppendF(&result, "\\u%04x", leading);
399 } else {
400 result += leading;
401 }
402
403 const uint32_t trailing = GetTrailingUtf16Char(ch);
404 if (trailing != 0) {
405 // All high surrogates will need escaping.
406 StringAppendF(&result, "\\u%04x", trailing);
407 }
Elliott Hughes82914b62012-04-09 15:56:29 -0700408 }
409 }
410 result += '"';
411 return result;
412}
413
Elliott Hughesd8c00d02012-01-30 14:08:31 -0800414// 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 -0700415std::string MangleForJni(const std::string& s) {
416 std::string result;
417 size_t char_count = CountModifiedUtf8Chars(s.c_str());
418 const char* cp = &s[0];
419 for (size_t i = 0; i < char_count; ++i) {
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000420 uint32_t ch = GetUtf16FromUtf8(&cp);
Elliott Hughesd8c00d02012-01-30 14:08:31 -0800421 if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')) {
422 result.push_back(ch);
423 } else if (ch == '.' || ch == '/') {
424 result += "_";
425 } else if (ch == '_') {
426 result += "_1";
427 } else if (ch == ';') {
428 result += "_2";
429 } else if (ch == '[') {
430 result += "_3";
Elliott Hughes79082e32011-08-25 12:07:32 -0700431 } else {
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000432 const uint16_t leading = GetLeadingUtf16Char(ch);
433 const uint32_t trailing = GetTrailingUtf16Char(ch);
434
435 StringAppendF(&result, "_0%04x", leading);
436 if (trailing != 0) {
437 StringAppendF(&result, "_0%04x", trailing);
438 }
Elliott Hughes79082e32011-08-25 12:07:32 -0700439 }
440 }
441 return result;
442}
443
Brian Carlstromf91c8c32011-09-21 17:30:34 -0700444std::string DotToDescriptor(const char* class_name) {
445 std::string descriptor(class_name);
446 std::replace(descriptor.begin(), descriptor.end(), '.', '/');
447 if (descriptor.length() > 0 && descriptor[0] != '[') {
448 descriptor = "L" + descriptor + ";";
449 }
450 return descriptor;
451}
452
Elliott Hughesf1a5adc2012-02-10 18:09:35 -0800453std::string DescriptorToDot(const char* descriptor) {
Elliott Hughes2435a572012-02-17 16:07:41 -0800454 size_t length = strlen(descriptor);
Ian Rogers1ff3c982014-08-12 02:30:58 -0700455 if (length > 1) {
456 if (descriptor[0] == 'L' && descriptor[length - 1] == ';') {
457 // Descriptors have the leading 'L' and trailing ';' stripped.
458 std::string result(descriptor + 1, length - 2);
459 std::replace(result.begin(), result.end(), '/', '.');
460 return result;
461 } else {
462 // For arrays the 'L' and ';' remain intact.
463 std::string result(descriptor);
464 std::replace(result.begin(), result.end(), '/', '.');
465 return result;
466 }
Elliott Hughes2435a572012-02-17 16:07:41 -0800467 }
Ian Rogers1ff3c982014-08-12 02:30:58 -0700468 // Do nothing for non-class/array descriptors.
Elliott Hughes2435a572012-02-17 16:07:41 -0800469 return descriptor;
Elliott Hughes91bf6cd2012-02-14 17:27:48 -0800470}
471
472std::string DescriptorToName(const char* descriptor) {
Elliott Hughesf1a5adc2012-02-10 18:09:35 -0800473 size_t length = strlen(descriptor);
Elliott Hughes2435a572012-02-17 16:07:41 -0800474 if (descriptor[0] == 'L' && descriptor[length - 1] == ';') {
475 std::string result(descriptor + 1, length - 2);
476 return result;
477 }
478 return descriptor;
Brian Carlstromaded5f72011-10-07 17:15:04 -0700479}
480
jeffhao10037c82012-01-23 15:06:23 -0800481// Helper for IsValidPartOfMemberNameUtf8(), a bit vector indicating valid low ascii.
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700482uint32_t DEX_MEMBER_VALID_LOW_ASCII[4] = {
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700483 0x00000000, // 00..1f low control characters; nothing valid
484 0x03ff2010, // 20..3f digits and symbols; valid: '0'..'9', '$', '-'
485 0x87fffffe, // 40..5f uppercase etc.; valid: 'A'..'Z', '_'
486 0x07fffffe // 60..7f lowercase etc.; valid: 'a'..'z'
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700487};
488
jeffhao10037c82012-01-23 15:06:23 -0800489// Helper for IsValidPartOfMemberNameUtf8(); do not call directly.
490bool IsValidPartOfMemberNameUtf8Slow(const char** pUtf8Ptr) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700491 /*
492 * It's a multibyte encoded character. Decode it and analyze. We
493 * accept anything that isn't (a) an improperly encoded low value,
494 * (b) an improper surrogate pair, (c) an encoded '\0', (d) a high
495 * control character, or (e) a high space, layout, or special
496 * character (U+00a0, U+2000..U+200f, U+2028..U+202f,
497 * U+fff0..U+ffff). This is all specified in the dex format
498 * document.
499 */
500
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000501 const uint32_t pair = GetUtf16FromUtf8(pUtf8Ptr);
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000502 const uint16_t leading = GetLeadingUtf16Char(pair);
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000503
Narayan Kamath8508e372015-05-06 14:55:43 +0100504 // We have a surrogate pair resulting from a valid 4 byte UTF sequence.
505 // No further checks are necessary because 4 byte sequences span code
506 // points [U+10000, U+1FFFFF], which are valid codepoints in a dex
507 // identifier. Furthermore, GetUtf16FromUtf8 guarantees that each of
508 // the surrogate halves are valid and well formed in this instance.
509 if (GetTrailingUtf16Char(pair) != 0) {
510 return true;
511 }
512
513
514 // We've encountered a one, two or three byte UTF-8 sequence. The
515 // three byte UTF-8 sequence could be one half of a surrogate pair.
516 switch (leading >> 8) {
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000517 case 0x00:
518 // It's only valid if it's above the ISO-8859-1 high space (0xa0).
519 return (leading > 0x00a0);
520 case 0xd8:
521 case 0xd9:
522 case 0xda:
523 case 0xdb:
Narayan Kamath8508e372015-05-06 14:55:43 +0100524 {
525 // We found a three byte sequence encoding one half of a surrogate.
526 // Look for the other half.
527 const uint32_t pair2 = GetUtf16FromUtf8(pUtf8Ptr);
528 const uint16_t trailing = GetLeadingUtf16Char(pair2);
529
530 return (GetTrailingUtf16Char(pair2) == 0) && (0xdc00 <= trailing && trailing <= 0xdfff);
531 }
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000532 case 0xdc:
533 case 0xdd:
534 case 0xde:
535 case 0xdf:
536 // It's a trailing surrogate, which is not valid at this point.
537 return false;
538 case 0x20:
539 case 0xff:
540 // It's in the range that has spaces, controls, and specials.
541 switch (leading & 0xfff8) {
Narayan Kamath8508e372015-05-06 14:55:43 +0100542 case 0x2000:
543 case 0x2008:
544 case 0x2028:
545 case 0xfff0:
546 case 0xfff8:
547 return false;
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000548 }
Narayan Kamath8508e372015-05-06 14:55:43 +0100549 return true;
550 default:
551 return true;
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700552 }
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000553
Narayan Kamath8508e372015-05-06 14:55:43 +0100554 UNREACHABLE();
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700555}
556
557/* Return whether the pointed-at modified-UTF-8 encoded character is
558 * valid as part of a member name, updating the pointer to point past
559 * the consumed character. This will consume two encoded UTF-16 code
560 * points if the character is encoded as a surrogate pair. Also, if
561 * this function returns false, then the given pointer may only have
562 * been partially advanced.
563 */
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700564static bool IsValidPartOfMemberNameUtf8(const char** pUtf8Ptr) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700565 uint8_t c = (uint8_t) **pUtf8Ptr;
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700566 if (LIKELY(c <= 0x7f)) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700567 // It's low-ascii, so check the table.
568 uint32_t wordIdx = c >> 5;
569 uint32_t bitIdx = c & 0x1f;
570 (*pUtf8Ptr)++;
571 return (DEX_MEMBER_VALID_LOW_ASCII[wordIdx] & (1 << bitIdx)) != 0;
572 }
573
574 // It's a multibyte encoded character. Call a non-inline function
575 // for the heavy lifting.
jeffhao10037c82012-01-23 15:06:23 -0800576 return IsValidPartOfMemberNameUtf8Slow(pUtf8Ptr);
577}
578
579bool IsValidMemberName(const char* s) {
580 bool angle_name = false;
581
Elliott Hughesb25c3f62012-03-26 16:35:06 -0700582 switch (*s) {
jeffhao10037c82012-01-23 15:06:23 -0800583 case '\0':
584 // The empty string is not a valid name.
585 return false;
586 case '<':
587 angle_name = true;
588 s++;
589 break;
590 }
591
592 while (true) {
593 switch (*s) {
594 case '\0':
595 return !angle_name;
596 case '>':
597 return angle_name && s[1] == '\0';
598 }
599
600 if (!IsValidPartOfMemberNameUtf8(&s)) {
601 return false;
602 }
603 }
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700604}
605
Elliott Hughes906e6852011-10-28 14:52:10 -0700606enum ClassNameType { kName, kDescriptor };
Ian Rogers7b078e82014-09-10 14:44:24 -0700607template<ClassNameType kType, char kSeparator>
608static bool IsValidClassName(const char* s) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700609 int arrayCount = 0;
610 while (*s == '[') {
611 arrayCount++;
612 s++;
613 }
614
615 if (arrayCount > 255) {
616 // Arrays may have no more than 255 dimensions.
617 return false;
618 }
619
Ian Rogers7b078e82014-09-10 14:44:24 -0700620 ClassNameType type = kType;
621 if (type != kDescriptor && arrayCount != 0) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700622 /*
623 * If we're looking at an array of some sort, then it doesn't
624 * matter if what is being asked for is a class name; the
625 * format looks the same as a type descriptor in that case, so
626 * treat it as such.
627 */
Elliott Hughes906e6852011-10-28 14:52:10 -0700628 type = kDescriptor;
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700629 }
630
Elliott Hughes906e6852011-10-28 14:52:10 -0700631 if (type == kDescriptor) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700632 /*
633 * We are looking for a descriptor. Either validate it as a
634 * single-character primitive type, or continue on to check the
635 * embedded class name (bracketed by "L" and ";").
636 */
637 switch (*(s++)) {
638 case 'B':
639 case 'C':
640 case 'D':
641 case 'F':
642 case 'I':
643 case 'J':
644 case 'S':
645 case 'Z':
646 // These are all single-character descriptors for primitive types.
647 return (*s == '\0');
648 case 'V':
649 // Non-array void is valid, but you can't have an array of void.
650 return (arrayCount == 0) && (*s == '\0');
651 case 'L':
652 // Class name: Break out and continue below.
653 break;
654 default:
655 // Oddball descriptor character.
656 return false;
657 }
658 }
659
660 /*
661 * We just consumed the 'L' that introduces a class name as part
662 * of a type descriptor, or we are looking for an unadorned class
663 * name.
664 */
665
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700666 bool sepOrFirst = true; // first character or just encountered a separator.
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700667 for (;;) {
668 uint8_t c = (uint8_t) *s;
669 switch (c) {
670 case '\0':
671 /*
672 * Premature end for a type descriptor, but valid for
673 * a class name as long as we haven't encountered an
674 * empty component (including the degenerate case of
675 * the empty string "").
676 */
Elliott Hughes906e6852011-10-28 14:52:10 -0700677 return (type == kName) && !sepOrFirst;
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700678 case ';':
679 /*
680 * Invalid character for a class name, but the
681 * legitimate end of a type descriptor. In the latter
682 * case, make sure that this is the end of the string
683 * and that it doesn't end with an empty component
684 * (including the degenerate case of "L;").
685 */
Elliott Hughes906e6852011-10-28 14:52:10 -0700686 return (type == kDescriptor) && !sepOrFirst && (s[1] == '\0');
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700687 case '/':
688 case '.':
Ian Rogers7b078e82014-09-10 14:44:24 -0700689 if (c != kSeparator) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700690 // The wrong separator character.
691 return false;
692 }
693 if (sepOrFirst) {
694 // Separator at start or two separators in a row.
695 return false;
696 }
697 sepOrFirst = true;
698 s++;
699 break;
700 default:
jeffhao10037c82012-01-23 15:06:23 -0800701 if (!IsValidPartOfMemberNameUtf8(&s)) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700702 return false;
703 }
704 sepOrFirst = false;
705 break;
706 }
707 }
708}
709
Elliott Hughes906e6852011-10-28 14:52:10 -0700710bool IsValidBinaryClassName(const char* s) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700711 return IsValidClassName<kName, '.'>(s);
Elliott Hughes906e6852011-10-28 14:52:10 -0700712}
713
714bool IsValidJniClassName(const char* s) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700715 return IsValidClassName<kName, '/'>(s);
Elliott Hughes906e6852011-10-28 14:52:10 -0700716}
717
718bool IsValidDescriptor(const char* s) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700719 return IsValidClassName<kDescriptor, '/'>(s);
Elliott Hughes906e6852011-10-28 14:52:10 -0700720}
721
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700722void Split(const std::string& s, char separator, std::vector<std::string>* result) {
Elliott Hughes34023802011-08-30 12:06:17 -0700723 const char* p = s.data();
724 const char* end = p + s.size();
725 while (p != end) {
Elliott Hughes48436bb2012-02-07 15:23:28 -0800726 if (*p == separator) {
Elliott Hughes34023802011-08-30 12:06:17 -0700727 ++p;
728 } else {
729 const char* start = p;
Elliott Hughes48436bb2012-02-07 15:23:28 -0800730 while (++p != end && *p != separator) {
731 // Skip to the next occurrence of the separator.
Elliott Hughes34023802011-08-30 12:06:17 -0700732 }
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700733 result->push_back(std::string(start, p - start));
Elliott Hughes34023802011-08-30 12:06:17 -0700734 }
735 }
736}
737
Elliott Hughes22869a92012-03-27 14:08:24 -0700738void SetThreadName(const char* thread_name) {
Elliott Hughesdcc24742011-09-07 14:02:44 -0700739 int hasAt = 0;
740 int hasDot = 0;
Elliott Hughes22869a92012-03-27 14:08:24 -0700741 const char* s = thread_name;
Elliott Hughesdcc24742011-09-07 14:02:44 -0700742 while (*s) {
743 if (*s == '.') {
744 hasDot = 1;
745 } else if (*s == '@') {
746 hasAt = 1;
747 }
748 s++;
749 }
Elliott Hughes22869a92012-03-27 14:08:24 -0700750 int len = s - thread_name;
Elliott Hughesdcc24742011-09-07 14:02:44 -0700751 if (len < 15 || hasAt || !hasDot) {
Elliott Hughes22869a92012-03-27 14:08:24 -0700752 s = thread_name;
Elliott Hughesdcc24742011-09-07 14:02:44 -0700753 } else {
Elliott Hughes22869a92012-03-27 14:08:24 -0700754 s = thread_name + len - 15;
Elliott Hughesdcc24742011-09-07 14:02:44 -0700755 }
Elliott Hughes0a18df82015-01-09 15:16:16 -0800756#if defined(__linux__)
Elliott Hughes7c6a61e2012-03-12 18:01:41 -0700757 // pthread_setname_np fails rather than truncating long strings.
Elliott Hughes0a18df82015-01-09 15:16:16 -0800758 char buf[16]; // MAX_TASK_COMM_LEN=16 is hard-coded in the kernel.
Elliott Hughesdcc24742011-09-07 14:02:44 -0700759 strncpy(buf, s, sizeof(buf)-1);
760 buf[sizeof(buf)-1] = '\0';
761 errno = pthread_setname_np(pthread_self(), buf);
762 if (errno != 0) {
763 PLOG(WARNING) << "Unable to set the name of current thread to '" << buf << "'";
764 }
Elliott Hughes0a18df82015-01-09 15:16:16 -0800765#else // __APPLE__
Elliott Hughes22869a92012-03-27 14:08:24 -0700766 pthread_setname_np(thread_name);
Elliott Hughesdcc24742011-09-07 14:02:44 -0700767#endif
768}
769
Brian Carlstrom29212012013-09-12 22:18:30 -0700770void GetTaskStats(pid_t tid, char* state, int* utime, int* stime, int* task_cpu) {
771 *utime = *stime = *task_cpu = 0;
Elliott Hughesbfe487b2011-10-26 15:48:55 -0700772 std::string stats;
Elliott Hughes8a31b502012-04-30 19:36:11 -0700773 if (!ReadFileToString(StringPrintf("/proc/self/task/%d/stat", tid), &stats)) {
Elliott Hughesbfe487b2011-10-26 15:48:55 -0700774 return;
775 }
776 // Skip the command, which may contain spaces.
777 stats = stats.substr(stats.find(')') + 2);
778 // Extract the three fields we care about.
779 std::vector<std::string> fields;
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700780 Split(stats, ' ', &fields);
Brian Carlstrom29212012013-09-12 22:18:30 -0700781 *state = fields[0][0];
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700782 *utime = strtoull(fields[11].c_str(), nullptr, 10);
783 *stime = strtoull(fields[12].c_str(), nullptr, 10);
784 *task_cpu = strtoull(fields[36].c_str(), nullptr, 10);
Elliott Hughesbfe487b2011-10-26 15:48:55 -0700785}
786
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800787const char* GetAndroidRoot() {
788 const char* android_root = getenv("ANDROID_ROOT");
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700789 if (android_root == nullptr) {
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800790 if (OS::DirectoryExists("/system")) {
791 android_root = "/system";
Brian Carlstroma9f19782011-10-13 00:14:47 -0700792 } else {
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800793 LOG(FATAL) << "ANDROID_ROOT not set and /system does not exist";
794 return "";
Brian Carlstroma9f19782011-10-13 00:14:47 -0700795 }
796 }
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800797 if (!OS::DirectoryExists(android_root)) {
798 LOG(FATAL) << "Failed to find ANDROID_ROOT directory " << android_root;
Brian Carlstroma9f19782011-10-13 00:14:47 -0700799 return "";
800 }
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800801 return android_root;
802}
Brian Carlstroma9f19782011-10-13 00:14:47 -0700803
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800804const char* GetAndroidData() {
Alex Lighta59dd802014-07-02 16:28:08 -0700805 std::string error_msg;
806 const char* dir = GetAndroidDataSafe(&error_msg);
807 if (dir != nullptr) {
808 return dir;
809 } else {
810 LOG(FATAL) << error_msg;
811 return "";
812 }
813}
814
815const char* GetAndroidDataSafe(std::string* error_msg) {
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800816 const char* android_data = getenv("ANDROID_DATA");
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700817 if (android_data == nullptr) {
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800818 if (OS::DirectoryExists("/data")) {
819 android_data = "/data";
820 } else {
Alex Lighta59dd802014-07-02 16:28:08 -0700821 *error_msg = "ANDROID_DATA not set and /data does not exist";
822 return nullptr;
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800823 }
824 }
825 if (!OS::DirectoryExists(android_data)) {
Alex Lighta59dd802014-07-02 16:28:08 -0700826 *error_msg = StringPrintf("Failed to find ANDROID_DATA directory %s", android_data);
827 return nullptr;
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800828 }
829 return android_data;
830}
831
Alex Lighta59dd802014-07-02 16:28:08 -0700832void GetDalvikCache(const char* subdir, const bool create_if_absent, std::string* dalvik_cache,
Andreas Gampe3c13a792014-09-18 20:56:04 -0700833 bool* have_android_data, bool* dalvik_cache_exists, bool* is_global_cache) {
Alex Lighta59dd802014-07-02 16:28:08 -0700834 CHECK(subdir != nullptr);
835 std::string error_msg;
836 const char* android_data = GetAndroidDataSafe(&error_msg);
837 if (android_data == nullptr) {
838 *have_android_data = false;
839 *dalvik_cache_exists = false;
Andreas Gampe3c13a792014-09-18 20:56:04 -0700840 *is_global_cache = false;
Alex Lighta59dd802014-07-02 16:28:08 -0700841 return;
842 } else {
843 *have_android_data = true;
844 }
845 const std::string dalvik_cache_root(StringPrintf("%s/dalvik-cache/", android_data));
846 *dalvik_cache = dalvik_cache_root + subdir;
847 *dalvik_cache_exists = OS::DirectoryExists(dalvik_cache->c_str());
Andreas Gampe3c13a792014-09-18 20:56:04 -0700848 *is_global_cache = strcmp(android_data, "/data") == 0;
849 if (create_if_absent && !*dalvik_cache_exists && !*is_global_cache) {
Alex Lighta59dd802014-07-02 16:28:08 -0700850 // Don't create the system's /data/dalvik-cache/... because it needs special permissions.
851 *dalvik_cache_exists = ((mkdir(dalvik_cache_root.c_str(), 0700) == 0 || errno == EEXIST) &&
852 (mkdir(dalvik_cache->c_str(), 0700) == 0 || errno == EEXIST));
853 }
854}
855
Richard Uhler55b58b62016-08-12 09:05:13 -0700856std::string GetDalvikCache(const char* subdir) {
Narayan Kamath11d9f062014-04-23 20:24:57 +0100857 CHECK(subdir != nullptr);
Brian Carlstrom41ccffd2014-05-06 10:37:30 -0700858 const char* android_data = GetAndroidData();
859 const std::string dalvik_cache_root(StringPrintf("%s/dalvik-cache/", android_data));
Narayan Kamath11d9f062014-04-23 20:24:57 +0100860 const std::string dalvik_cache = dalvik_cache_root + subdir;
Andreas Gampe40da2862015-02-27 12:49:04 -0800861 if (!OS::DirectoryExists(dalvik_cache.c_str())) {
Richard Uhler55b58b62016-08-12 09:05:13 -0700862 // TODO: Check callers. Traditional behavior is to not abort.
863 return "";
Brian Carlstroma9f19782011-10-13 00:14:47 -0700864 }
Brian Carlstrom7675e162013-06-10 16:18:04 -0700865 return dalvik_cache;
Brian Carlstroma9f19782011-10-13 00:14:47 -0700866}
867
Alex Lighta59dd802014-07-02 16:28:08 -0700868bool GetDalvikCacheFilename(const char* location, const char* cache_location,
869 std::string* filename, std::string* error_msg) {
Ian Rogerse6060102013-05-16 12:01:04 -0700870 if (location[0] != '/') {
Alex Lighta59dd802014-07-02 16:28:08 -0700871 *error_msg = StringPrintf("Expected path in location to be absolute: %s", location);
872 return false;
Ian Rogerse6060102013-05-16 12:01:04 -0700873 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700874 std::string cache_file(&location[1]); // skip leading slash
Andreas Gampe9186ced2016-12-12 14:28:21 -0800875 if (!android::base::EndsWith(location, ".dex") &&
876 !android::base::EndsWith(location, ".art") &&
877 !android::base::EndsWith(location, ".oat")) {
Brian Carlstrom30e2ea42013-06-19 23:25:37 -0700878 cache_file += "/";
879 cache_file += DexFile::kClassesDex;
880 }
Brian Carlstromb7bbba42011-10-13 14:58:47 -0700881 std::replace(cache_file.begin(), cache_file.end(), '/', '@');
Alex Lighta59dd802014-07-02 16:28:08 -0700882 *filename = StringPrintf("%s/%s", cache_location, cache_file.c_str());
883 return true;
884}
885
Brian Carlstrom2afe4942014-05-19 10:25:33 -0700886static void InsertIsaDirectory(const InstructionSet isa, std::string* filename) {
Brian Carlstrom0e12bdc2014-05-14 17:44:28 -0700887 // in = /foo/bar/baz
888 // out = /foo/bar/<isa>/baz
889 size_t pos = filename->rfind('/');
890 CHECK_NE(pos, std::string::npos) << *filename << " " << isa;
891 filename->insert(pos, "/", 1);
892 filename->insert(pos + 1, GetInstructionSetString(isa));
893}
894
895std::string GetSystemImageFilename(const char* location, const InstructionSet isa) {
896 // location = /system/framework/boot.art
897 // filename = /system/framework/<isa>/boot.art
898 std::string filename(location);
Brian Carlstrom2afe4942014-05-19 10:25:33 -0700899 InsertIsaDirectory(isa, &filename);
Brian Carlstrom0e12bdc2014-05-14 17:44:28 -0700900 return filename;
901}
902
Calin Juravle2e2db782016-02-23 12:00:03 +0000903int ExecAndReturnCode(std::vector<std::string>& arg_vector, std::string* error_msg) {
Andreas Gampe9186ced2016-12-12 14:28:21 -0800904 const std::string command_line(android::base::Join(arg_vector, ' '));
Brian Carlstrom6449c622014-02-10 23:48:36 -0800905 CHECK_GE(arg_vector.size(), 1U) << command_line;
906
907 // Convert the args to char pointers.
908 const char* program = arg_vector[0].c_str();
909 std::vector<char*> args;
Brian Carlstrom35d8b8e2014-02-25 10:51:11 -0800910 for (size_t i = 0; i < arg_vector.size(); ++i) {
911 const std::string& arg = arg_vector[i];
912 char* arg_str = const_cast<char*>(arg.c_str());
913 CHECK(arg_str != nullptr) << i;
914 args.push_back(arg_str);
Brian Carlstrom6449c622014-02-10 23:48:36 -0800915 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700916 args.push_back(nullptr);
Brian Carlstrom6449c622014-02-10 23:48:36 -0800917
918 // fork and exec
919 pid_t pid = fork();
920 if (pid == 0) {
921 // no allocation allowed between fork and exec
922
923 // change process groups, so we don't get reaped by ProcessManager
924 setpgid(0, 0);
925
David Sehrd106d9f2016-08-16 19:22:57 -0700926 // (b/30160149): protect subprocesses from modifications to LD_LIBRARY_PATH, etc.
927 // Use the snapshot of the environment from the time the runtime was created.
928 char** envp = (Runtime::Current() == nullptr) ? nullptr : Runtime::Current()->GetEnvSnapshot();
929 if (envp == nullptr) {
930 execv(program, &args[0]);
931 } else {
932 execve(program, &args[0], envp);
933 }
934 PLOG(ERROR) << "Failed to execve(" << command_line << ")";
Tobias Lindskogae35c372015-11-04 19:41:21 +0100935 // _exit to avoid atexit handlers in child.
936 _exit(1);
Brian Carlstrom6449c622014-02-10 23:48:36 -0800937 } else {
938 if (pid == -1) {
939 *error_msg = StringPrintf("Failed to execv(%s) because fork failed: %s",
940 command_line.c_str(), strerror(errno));
Calin Juravle2e2db782016-02-23 12:00:03 +0000941 return -1;
Brian Carlstrom6449c622014-02-10 23:48:36 -0800942 }
943
944 // wait for subprocess to finish
Calin Juravle2e2db782016-02-23 12:00:03 +0000945 int status = -1;
Brian Carlstrom6449c622014-02-10 23:48:36 -0800946 pid_t got_pid = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0));
947 if (got_pid != pid) {
948 *error_msg = StringPrintf("Failed after fork for execv(%s) because waitpid failed: "
949 "wanted %d, got %d: %s",
950 command_line.c_str(), pid, got_pid, strerror(errno));
Calin Juravle2e2db782016-02-23 12:00:03 +0000951 return -1;
Brian Carlstrom6449c622014-02-10 23:48:36 -0800952 }
Calin Juravle2e2db782016-02-23 12:00:03 +0000953 if (WIFEXITED(status)) {
954 return WEXITSTATUS(status);
Brian Carlstrom6449c622014-02-10 23:48:36 -0800955 }
Calin Juravle2e2db782016-02-23 12:00:03 +0000956 return -1;
957 }
958}
959
960bool Exec(std::vector<std::string>& arg_vector, std::string* error_msg) {
961 int status = ExecAndReturnCode(arg_vector, error_msg);
962 if (status != 0) {
Andreas Gampe9186ced2016-12-12 14:28:21 -0800963 const std::string command_line(android::base::Join(arg_vector, ' '));
Calin Juravle2e2db782016-02-23 12:00:03 +0000964 *error_msg = StringPrintf("Failed execv(%s) because non-0 exit status",
965 command_line.c_str());
966 return false;
Brian Carlstrom6449c622014-02-10 23:48:36 -0800967 }
968 return true;
969}
970
Calin Juravle5e2b9712015-12-18 14:10:00 +0200971bool FileExists(const std::string& filename) {
972 struct stat buffer;
973 return stat(filename.c_str(), &buffer) == 0;
974}
975
Calin Juravleb9c1b9b2016-03-17 17:07:52 +0000976bool FileExistsAndNotEmpty(const std::string& filename) {
977 struct stat buffer;
978 if (stat(filename.c_str(), &buffer) != 0) {
979 return false;
980 }
981 return buffer.st_size > 0;
982}
983
David Brazdil7b49e6c2016-09-01 11:06:18 +0100984std::string ReplaceFileExtension(const std::string& filename, const std::string& new_extension) {
985 const size_t last_ext = filename.find_last_of('.');
986 if (last_ext == std::string::npos) {
987 return filename + "." + new_extension;
988 } else {
989 return filename.substr(0, last_ext + 1) + new_extension;
990 }
991}
992
Mathieu Chartier76433272014-09-26 14:32:37 -0700993std::string PrettyDescriptor(Primitive::Type type) {
994 return PrettyDescriptor(Primitive::Descriptor(type));
995}
996
Nicolas Geoffrayabbb0f72015-10-29 18:55:58 +0000997static void ParseStringAfterChar(const std::string& s,
998 char c,
999 std::string* parsed_value,
1000 UsageFn Usage) {
1001 std::string::size_type colon = s.find(c);
1002 if (colon == std::string::npos) {
1003 Usage("Missing char %c in option %s\n", c, s.c_str());
1004 }
1005 // Add one to remove the char we were trimming until.
1006 *parsed_value = s.substr(colon + 1);
1007}
1008
1009void ParseDouble(const std::string& option,
1010 char after_char,
1011 double min,
1012 double max,
1013 double* parsed_value,
1014 UsageFn Usage) {
1015 std::string substring;
1016 ParseStringAfterChar(option, after_char, &substring, Usage);
1017 bool sane_val = true;
1018 double value;
1019 if ((false)) {
1020 // TODO: this doesn't seem to work on the emulator. b/15114595
1021 std::stringstream iss(substring);
1022 iss >> value;
1023 // Ensure that we have a value, there was no cruft after it and it satisfies a sensible range.
1024 sane_val = iss.eof() && (value >= min) && (value <= max);
1025 } else {
1026 char* end = nullptr;
1027 value = strtod(substring.c_str(), &end);
1028 sane_val = *end == '\0' && value >= min && value <= max;
1029 }
1030 if (!sane_val) {
1031 Usage("Invalid double value %s for option %s\n", substring.c_str(), option.c_str());
1032 }
1033 *parsed_value = value;
1034}
1035
Calin Juravle4d77b6a2015-12-01 18:38:09 +00001036int64_t GetFileSizeBytes(const std::string& filename) {
1037 struct stat stat_buf;
1038 int rc = stat(filename.c_str(), &stat_buf);
1039 return rc == 0 ? stat_buf.st_size : -1;
1040}
1041
Mathieu Chartier4d87df62016-01-07 15:14:19 -08001042void SleepForever() {
1043 while (true) {
1044 usleep(1000000);
1045 }
1046}
1047
Elliott Hughes42ee1422011-09-06 12:33:32 -07001048} // namespace art