blob: 410416ea6419bcf9f2587331bd2982188eab90e3 [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 Gampe46ee31b2016-12-14 10:11:49 -080028#include "android-base/stringprintf.h"
Andreas Gampe9186ced2016-12-12 14:28:21 -080029#include "android-base/strings.h"
30
Brian Carlstrom6449c622014-02-10 23:48:36 -080031#include "base/stl_util.h"
Elliott Hughes76160052012-12-12 16:31:20 -080032#include "base/unix_file/fd_file.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070033#include "dex_file-inl.h"
Andreas Gampe5073fed2015-08-10 11:40:25 -070034#include "dex_instruction.h"
Nicolas Geoffray524e7ea2015-10-16 17:13:34 +010035#include "oat_quick_method_header.h"
buzbeec143c552011-08-20 17:38:58 -070036#include "os.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070037#include "scoped_thread_state_change-inl.h"
Ian Rogersa6724902013-09-23 09:23:37 -070038#include "utf-inl.h"
Elliott Hughes11e45072011-08-16 17:40:46 -070039
Elliott Hughes4ae722a2012-03-13 11:08:51 -070040#if defined(__APPLE__)
Brian Carlstrom7934ac22013-07-26 10:54:15 -070041#include "AvailabilityMacros.h" // For MAC_OS_X_VERSION_MAX_ALLOWED
Elliott Hughesf1498432012-03-28 19:34:27 -070042#include <sys/syscall.h>
David Sehrfa442002016-08-22 18:42:08 -070043#include <crt_externs.h>
Elliott Hughes4ae722a2012-03-13 11:08:51 -070044#endif
45
Elliott Hughes058a6de2012-05-24 19:13:02 -070046#if defined(__linux__)
Elliott Hughese1aee692012-01-17 16:40:10 -080047#include <linux/unistd.h>
Elliott Hughese1aee692012-01-17 16:40:10 -080048#endif
49
Elliott Hughes11e45072011-08-16 17:40:46 -070050namespace art {
51
Andreas Gampe46ee31b2016-12-14 10:11:49 -080052using android::base::StringAppendF;
53using android::base::StringPrintf;
54
Alex Light9c20a142016-08-23 15:05:12 -070055static const uint8_t kBase64Map[256] = {
56 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
57 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
58 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
59 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
60 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
61 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
62 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, // NOLINT
63 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, // NOLINT
64 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
65 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, // NOLINT
66 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, // NOLINT
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, 255, 255, 255, 255, 255, 255, 255, 255,
74 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
75 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
76 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
77 255, 255, 255, 255
78};
79
80uint8_t* DecodeBase64(const char* src, size_t* dst_size) {
81 std::vector<uint8_t> tmp;
82 uint32_t t = 0, y = 0;
83 int g = 3;
84 for (size_t i = 0; src[i] != '\0'; ++i) {
85 uint8_t c = kBase64Map[src[i] & 0xFF];
86 if (c == 255) continue;
87 // the final = symbols are read and used to trim the remaining bytes
88 if (c == 254) {
89 c = 0;
90 // prevent g < 0 which would potentially allow an overflow later
91 if (--g < 0) {
92 *dst_size = 0;
93 return nullptr;
94 }
95 } else if (g != 3) {
96 // we only allow = to be at the end
97 *dst_size = 0;
98 return nullptr;
99 }
100 t = (t << 6) | c;
101 if (++y == 4) {
102 tmp.push_back((t >> 16) & 255);
103 if (g > 1) {
104 tmp.push_back((t >> 8) & 255);
105 }
106 if (g > 2) {
107 tmp.push_back(t & 255);
108 }
109 y = t = 0;
110 }
111 }
112 if (y != 0) {
113 *dst_size = 0;
114 return nullptr;
115 }
116 std::unique_ptr<uint8_t[]> dst(new uint8_t[tmp.size()]);
117 if (dst_size != nullptr) {
118 *dst_size = tmp.size();
119 } else {
120 *dst_size = 0;
121 }
122 std::copy(tmp.begin(), tmp.end(), dst.get());
123 return dst.release();
124}
125
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800126pid_t GetTid() {
Brian Carlstromf3a26412012-08-24 11:06:02 -0700127#if defined(__APPLE__)
128 uint64_t owner;
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700129 CHECK_PTHREAD_CALL(pthread_threadid_np, (nullptr, &owner), __FUNCTION__); // Requires Mac OS 10.6
Brian Carlstromf3a26412012-08-24 11:06:02 -0700130 return owner;
Elliott Hughes323aa862014-08-20 15:00:04 -0700131#elif defined(__BIONIC__)
132 return gettid();
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800133#else
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800134 return syscall(__NR_gettid);
135#endif
136}
137
Elliott Hughes289be852012-06-12 13:57:20 -0700138std::string GetThreadName(pid_t tid) {
139 std::string result;
140 if (ReadFileToString(StringPrintf("/proc/self/task/%d/comm", tid), &result)) {
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700141 result.resize(result.size() - 1); // Lose the trailing '\n'.
Elliott Hughes289be852012-06-12 13:57:20 -0700142 } else {
143 result = "<unknown>";
144 }
145 return result;
146}
147
Elliott Hughesd92bec42011-09-02 17:04:36 -0700148bool ReadFileToString(const std::string& file_name, std::string* result) {
Andreas Gampedf878922015-08-13 16:44:54 -0700149 File file(file_name, O_RDONLY, false);
150 if (!file.IsOpened()) {
Elliott Hughesd92bec42011-09-02 17:04:36 -0700151 return false;
152 }
buzbeec143c552011-08-20 17:38:58 -0700153
Elliott Hughes3b6baaa2011-10-14 19:13:56 -0700154 std::vector<char> buf(8 * KB);
buzbeec143c552011-08-20 17:38:58 -0700155 while (true) {
Andreas Gampea6dfdae2015-02-24 15:50:19 -0800156 int64_t n = TEMP_FAILURE_RETRY(read(file.Fd(), &buf[0], buf.size()));
Elliott Hughesd92bec42011-09-02 17:04:36 -0700157 if (n == -1) {
158 return false;
buzbeec143c552011-08-20 17:38:58 -0700159 }
Elliott Hughesd92bec42011-09-02 17:04:36 -0700160 if (n == 0) {
161 return true;
162 }
Elliott Hughes3b6baaa2011-10-14 19:13:56 -0700163 result->append(&buf[0], n);
buzbeec143c552011-08-20 17:38:58 -0700164 }
buzbeec143c552011-08-20 17:38:58 -0700165}
166
Andreas Gampea6dfdae2015-02-24 15:50:19 -0800167bool PrintFileToLog(const std::string& file_name, LogSeverity level) {
Andreas Gampedf878922015-08-13 16:44:54 -0700168 File file(file_name, O_RDONLY, false);
169 if (!file.IsOpened()) {
Andreas Gampea6dfdae2015-02-24 15:50:19 -0800170 return false;
171 }
172
173 constexpr size_t kBufSize = 256; // Small buffer. Avoid stack overflow and stack size warnings.
174 char buf[kBufSize + 1]; // +1 for terminator.
175 size_t filled_to = 0;
176 while (true) {
177 DCHECK_LT(filled_to, kBufSize);
178 int64_t n = TEMP_FAILURE_RETRY(read(file.Fd(), &buf[filled_to], kBufSize - filled_to));
179 if (n <= 0) {
180 // Print the rest of the buffer, if it exists.
181 if (filled_to > 0) {
182 buf[filled_to] = 0;
183 LOG(level) << buf;
184 }
185 return n == 0;
186 }
187 // Scan for '\n'.
188 size_t i = filled_to;
189 bool found_newline = false;
190 for (; i < filled_to + n; ++i) {
191 if (buf[i] == '\n') {
192 // Found a line break, that's something to print now.
193 buf[i] = 0;
194 LOG(level) << buf;
195 // Copy the rest to the front.
196 if (i + 1 < filled_to + n) {
197 memmove(&buf[0], &buf[i + 1], filled_to + n - i - 1);
198 filled_to = filled_to + n - i - 1;
199 } else {
200 filled_to = 0;
201 }
202 found_newline = true;
203 break;
204 }
205 }
206 if (found_newline) {
207 continue;
208 } else {
209 filled_to += n;
210 // Check if we must flush now.
211 if (filled_to == kBufSize) {
212 buf[kBufSize] = 0;
213 LOG(level) << buf;
214 filled_to = 0;
215 }
216 }
217 }
218}
219
Ian Rogers1ff3c982014-08-12 02:30:58 -0700220std::string PrettyDescriptor(const char* descriptor) {
Elliott Hughes11e45072011-08-16 17:40:46 -0700221 // Count the number of '['s to get the dimensionality.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700222 const char* c = descriptor;
Elliott Hughes11e45072011-08-16 17:40:46 -0700223 size_t dim = 0;
224 while (*c == '[') {
225 dim++;
226 c++;
227 }
228
229 // Reference or primitive?
230 if (*c == 'L') {
231 // "[[La/b/C;" -> "a.b.C[][]".
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700232 c++; // Skip the 'L'.
Elliott Hughes11e45072011-08-16 17:40:46 -0700233 } else {
234 // "[[B" -> "byte[][]".
235 // To make life easier, we make primitives look like unqualified
236 // reference types.
237 switch (*c) {
238 case 'B': c = "byte;"; break;
239 case 'C': c = "char;"; break;
240 case 'D': c = "double;"; break;
241 case 'F': c = "float;"; break;
242 case 'I': c = "int;"; break;
243 case 'J': c = "long;"; break;
244 case 'S': c = "short;"; break;
245 case 'Z': c = "boolean;"; break;
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700246 case 'V': c = "void;"; break; // Used when decoding return types.
Elliott Hughes5174fe62011-08-23 15:12:35 -0700247 default: return descriptor;
Elliott Hughes11e45072011-08-16 17:40:46 -0700248 }
249 }
250
251 // At this point, 'c' is a string of the form "fully/qualified/Type;"
252 // or "primitive;". Rewrite the type with '.' instead of '/':
253 std::string result;
254 const char* p = c;
255 while (*p != ';') {
256 char ch = *p++;
257 if (ch == '/') {
258 ch = '.';
259 }
260 result.push_back(ch);
261 }
262 // ...and replace the semicolon with 'dim' "[]" pairs:
Ian Rogers1ff3c982014-08-12 02:30:58 -0700263 for (size_t i = 0; i < dim; ++i) {
Elliott Hughes11e45072011-08-16 17:40:46 -0700264 result += "[]";
265 }
266 return result;
267}
268
Elliott Hughes9058f2b2012-03-22 18:06:48 -0700269std::string PrettyArguments(const char* signature) {
270 std::string result;
271 result += '(';
272 CHECK_EQ(*signature, '(');
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700273 ++signature; // Skip the '('.
Elliott Hughes9058f2b2012-03-22 18:06:48 -0700274 while (*signature != ')') {
275 size_t argument_length = 0;
276 while (signature[argument_length] == '[') {
277 ++argument_length;
278 }
279 if (signature[argument_length] == 'L') {
280 argument_length = (strchr(signature, ';') - signature + 1);
281 } else {
282 ++argument_length;
283 }
Ian Rogers1ff3c982014-08-12 02:30:58 -0700284 {
285 std::string argument_descriptor(signature, argument_length);
286 result += PrettyDescriptor(argument_descriptor.c_str());
287 }
Elliott Hughes9058f2b2012-03-22 18:06:48 -0700288 if (signature[argument_length] != ')') {
289 result += ", ";
290 }
291 signature += argument_length;
292 }
293 CHECK_EQ(*signature, ')');
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700294 ++signature; // Skip the ')'.
Elliott Hughes9058f2b2012-03-22 18:06:48 -0700295 result += ')';
296 return result;
297}
298
299std::string PrettyReturnType(const char* signature) {
300 const char* return_type = strchr(signature, ')');
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700301 CHECK(return_type != nullptr);
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700302 ++return_type; // Skip ')'.
Elliott Hughes9058f2b2012-03-22 18:06:48 -0700303 return PrettyDescriptor(return_type);
304}
305
Andreas Gampec0d82292014-09-23 10:38:30 -0700306std::string PrettyJavaAccessFlags(uint32_t access_flags) {
307 std::string result;
308 if ((access_flags & kAccPublic) != 0) {
309 result += "public ";
310 }
311 if ((access_flags & kAccProtected) != 0) {
312 result += "protected ";
313 }
314 if ((access_flags & kAccPrivate) != 0) {
315 result += "private ";
316 }
317 if ((access_flags & kAccFinal) != 0) {
318 result += "final ";
319 }
320 if ((access_flags & kAccStatic) != 0) {
321 result += "static ";
322 }
David Brazdilca3c8c32016-09-06 14:04:48 +0100323 if ((access_flags & kAccAbstract) != 0) {
324 result += "abstract ";
325 }
326 if ((access_flags & kAccInterface) != 0) {
327 result += "interface ";
328 }
Andreas Gampec0d82292014-09-23 10:38:30 -0700329 if ((access_flags & kAccTransient) != 0) {
330 result += "transient ";
331 }
332 if ((access_flags & kAccVolatile) != 0) {
333 result += "volatile ";
334 }
335 if ((access_flags & kAccSynchronized) != 0) {
336 result += "synchronized ";
337 }
338 return result;
339}
340
Mathieu Chartiere6da9af2013-12-16 11:54:42 -0800341std::string PrettySize(int64_t byte_count) {
Elliott Hughesc967f782012-04-16 10:23:15 -0700342 // The byte thresholds at which we display amounts. A byte count is displayed
343 // in unit U when kUnitThresholds[U] <= bytes < kUnitThresholds[U+1].
Ian Rogersef7d42f2014-01-06 12:55:46 -0800344 static const int64_t kUnitThresholds[] = {
Elliott Hughesc967f782012-04-16 10:23:15 -0700345 0, // B up to...
346 3*1024, // KB up to...
347 2*1024*1024, // MB up to...
348 1024*1024*1024 // GB from here.
349 };
Mathieu Chartiere6da9af2013-12-16 11:54:42 -0800350 static const int64_t kBytesPerUnit[] = { 1, KB, MB, GB };
Elliott Hughesc967f782012-04-16 10:23:15 -0700351 static const char* const kUnitStrings[] = { "B", "KB", "MB", "GB" };
Mathieu Chartiere6da9af2013-12-16 11:54:42 -0800352 const char* negative_str = "";
353 if (byte_count < 0) {
354 negative_str = "-";
355 byte_count = -byte_count;
356 }
Elliott Hughesc967f782012-04-16 10:23:15 -0700357 int i = arraysize(kUnitThresholds);
358 while (--i > 0) {
359 if (byte_count >= kUnitThresholds[i]) {
360 break;
361 }
Ian Rogers3bb17a62012-01-27 23:56:44 -0800362 }
Brian Carlstrom474cc792014-03-07 14:18:15 -0800363 return StringPrintf("%s%" PRId64 "%s",
364 negative_str, byte_count / kBytesPerUnit[i], kUnitStrings[i]);
Ian Rogers3bb17a62012-01-27 23:56:44 -0800365}
366
Andreas Gampe9186ced2016-12-12 14:28:21 -0800367static inline constexpr bool NeedsEscaping(uint16_t ch) {
368 return (ch < ' ' || ch > '~');
369}
370
Ian Rogers576ca0c2014-06-06 15:58:22 -0700371std::string PrintableChar(uint16_t ch) {
372 std::string result;
373 result += '\'';
374 if (NeedsEscaping(ch)) {
375 StringAppendF(&result, "\\u%04x", ch);
376 } else {
377 result += ch;
378 }
379 result += '\'';
380 return result;
381}
382
Ian Rogers68b56852014-08-29 20:19:11 -0700383std::string PrintableString(const char* utf) {
Elliott Hughes82914b62012-04-09 15:56:29 -0700384 std::string result;
385 result += '"';
Ian Rogers68b56852014-08-29 20:19:11 -0700386 const char* p = utf;
Elliott Hughes82914b62012-04-09 15:56:29 -0700387 size_t char_count = CountModifiedUtf8Chars(p);
388 for (size_t i = 0; i < char_count; ++i) {
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000389 uint32_t ch = GetUtf16FromUtf8(&p);
Elliott Hughes82914b62012-04-09 15:56:29 -0700390 if (ch == '\\') {
391 result += "\\\\";
392 } else if (ch == '\n') {
393 result += "\\n";
394 } else if (ch == '\r') {
395 result += "\\r";
396 } else if (ch == '\t') {
397 result += "\\t";
Elliott Hughes82914b62012-04-09 15:56:29 -0700398 } else {
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000399 const uint16_t leading = GetLeadingUtf16Char(ch);
400
401 if (NeedsEscaping(leading)) {
402 StringAppendF(&result, "\\u%04x", leading);
403 } else {
404 result += leading;
405 }
406
407 const uint32_t trailing = GetTrailingUtf16Char(ch);
408 if (trailing != 0) {
409 // All high surrogates will need escaping.
410 StringAppendF(&result, "\\u%04x", trailing);
411 }
Elliott Hughes82914b62012-04-09 15:56:29 -0700412 }
413 }
414 result += '"';
415 return result;
416}
417
Elliott Hughesd8c00d02012-01-30 14:08:31 -0800418// 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 -0700419std::string MangleForJni(const std::string& s) {
420 std::string result;
421 size_t char_count = CountModifiedUtf8Chars(s.c_str());
422 const char* cp = &s[0];
423 for (size_t i = 0; i < char_count; ++i) {
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000424 uint32_t ch = GetUtf16FromUtf8(&cp);
Elliott Hughesd8c00d02012-01-30 14:08:31 -0800425 if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')) {
426 result.push_back(ch);
427 } else if (ch == '.' || ch == '/') {
428 result += "_";
429 } else if (ch == '_') {
430 result += "_1";
431 } else if (ch == ';') {
432 result += "_2";
433 } else if (ch == '[') {
434 result += "_3";
Elliott Hughes79082e32011-08-25 12:07:32 -0700435 } else {
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000436 const uint16_t leading = GetLeadingUtf16Char(ch);
437 const uint32_t trailing = GetTrailingUtf16Char(ch);
438
439 StringAppendF(&result, "_0%04x", leading);
440 if (trailing != 0) {
441 StringAppendF(&result, "_0%04x", trailing);
442 }
Elliott Hughes79082e32011-08-25 12:07:32 -0700443 }
444 }
445 return result;
446}
447
Brian Carlstromf91c8c32011-09-21 17:30:34 -0700448std::string DotToDescriptor(const char* class_name) {
449 std::string descriptor(class_name);
450 std::replace(descriptor.begin(), descriptor.end(), '.', '/');
451 if (descriptor.length() > 0 && descriptor[0] != '[') {
452 descriptor = "L" + descriptor + ";";
453 }
454 return descriptor;
455}
456
Elliott Hughesf1a5adc2012-02-10 18:09:35 -0800457std::string DescriptorToDot(const char* descriptor) {
Elliott Hughes2435a572012-02-17 16:07:41 -0800458 size_t length = strlen(descriptor);
Ian Rogers1ff3c982014-08-12 02:30:58 -0700459 if (length > 1) {
460 if (descriptor[0] == 'L' && descriptor[length - 1] == ';') {
461 // Descriptors have the leading 'L' and trailing ';' stripped.
462 std::string result(descriptor + 1, length - 2);
463 std::replace(result.begin(), result.end(), '/', '.');
464 return result;
465 } else {
466 // For arrays the 'L' and ';' remain intact.
467 std::string result(descriptor);
468 std::replace(result.begin(), result.end(), '/', '.');
469 return result;
470 }
Elliott Hughes2435a572012-02-17 16:07:41 -0800471 }
Ian Rogers1ff3c982014-08-12 02:30:58 -0700472 // Do nothing for non-class/array descriptors.
Elliott Hughes2435a572012-02-17 16:07:41 -0800473 return descriptor;
Elliott Hughes91bf6cd2012-02-14 17:27:48 -0800474}
475
476std::string DescriptorToName(const char* descriptor) {
Elliott Hughesf1a5adc2012-02-10 18:09:35 -0800477 size_t length = strlen(descriptor);
Elliott Hughes2435a572012-02-17 16:07:41 -0800478 if (descriptor[0] == 'L' && descriptor[length - 1] == ';') {
479 std::string result(descriptor + 1, length - 2);
480 return result;
481 }
482 return descriptor;
Brian Carlstromaded5f72011-10-07 17:15:04 -0700483}
484
jeffhao10037c82012-01-23 15:06:23 -0800485// Helper for IsValidPartOfMemberNameUtf8(), a bit vector indicating valid low ascii.
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700486uint32_t DEX_MEMBER_VALID_LOW_ASCII[4] = {
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700487 0x00000000, // 00..1f low control characters; nothing valid
488 0x03ff2010, // 20..3f digits and symbols; valid: '0'..'9', '$', '-'
489 0x87fffffe, // 40..5f uppercase etc.; valid: 'A'..'Z', '_'
490 0x07fffffe // 60..7f lowercase etc.; valid: 'a'..'z'
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700491};
492
jeffhao10037c82012-01-23 15:06:23 -0800493// Helper for IsValidPartOfMemberNameUtf8(); do not call directly.
494bool IsValidPartOfMemberNameUtf8Slow(const char** pUtf8Ptr) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700495 /*
496 * It's a multibyte encoded character. Decode it and analyze. We
497 * accept anything that isn't (a) an improperly encoded low value,
498 * (b) an improper surrogate pair, (c) an encoded '\0', (d) a high
499 * control character, or (e) a high space, layout, or special
500 * character (U+00a0, U+2000..U+200f, U+2028..U+202f,
501 * U+fff0..U+ffff). This is all specified in the dex format
502 * document.
503 */
504
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000505 const uint32_t pair = GetUtf16FromUtf8(pUtf8Ptr);
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000506 const uint16_t leading = GetLeadingUtf16Char(pair);
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000507
Narayan Kamath8508e372015-05-06 14:55:43 +0100508 // We have a surrogate pair resulting from a valid 4 byte UTF sequence.
509 // No further checks are necessary because 4 byte sequences span code
510 // points [U+10000, U+1FFFFF], which are valid codepoints in a dex
511 // identifier. Furthermore, GetUtf16FromUtf8 guarantees that each of
512 // the surrogate halves are valid and well formed in this instance.
513 if (GetTrailingUtf16Char(pair) != 0) {
514 return true;
515 }
516
517
518 // We've encountered a one, two or three byte UTF-8 sequence. The
519 // three byte UTF-8 sequence could be one half of a surrogate pair.
520 switch (leading >> 8) {
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000521 case 0x00:
522 // It's only valid if it's above the ISO-8859-1 high space (0xa0).
523 return (leading > 0x00a0);
524 case 0xd8:
525 case 0xd9:
526 case 0xda:
527 case 0xdb:
Narayan Kamath8508e372015-05-06 14:55:43 +0100528 {
529 // We found a three byte sequence encoding one half of a surrogate.
530 // Look for the other half.
531 const uint32_t pair2 = GetUtf16FromUtf8(pUtf8Ptr);
532 const uint16_t trailing = GetLeadingUtf16Char(pair2);
533
534 return (GetTrailingUtf16Char(pair2) == 0) && (0xdc00 <= trailing && trailing <= 0xdfff);
535 }
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000536 case 0xdc:
537 case 0xdd:
538 case 0xde:
539 case 0xdf:
540 // It's a trailing surrogate, which is not valid at this point.
541 return false;
542 case 0x20:
543 case 0xff:
544 // It's in the range that has spaces, controls, and specials.
545 switch (leading & 0xfff8) {
Narayan Kamath8508e372015-05-06 14:55:43 +0100546 case 0x2000:
547 case 0x2008:
548 case 0x2028:
549 case 0xfff0:
550 case 0xfff8:
551 return false;
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000552 }
Narayan Kamath8508e372015-05-06 14:55:43 +0100553 return true;
554 default:
555 return true;
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700556 }
Narayan Kamatha5afcfc2015-01-29 20:06:46 +0000557
Narayan Kamath8508e372015-05-06 14:55:43 +0100558 UNREACHABLE();
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700559}
560
561/* Return whether the pointed-at modified-UTF-8 encoded character is
562 * valid as part of a member name, updating the pointer to point past
563 * the consumed character. This will consume two encoded UTF-16 code
564 * points if the character is encoded as a surrogate pair. Also, if
565 * this function returns false, then the given pointer may only have
566 * been partially advanced.
567 */
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700568static bool IsValidPartOfMemberNameUtf8(const char** pUtf8Ptr) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700569 uint8_t c = (uint8_t) **pUtf8Ptr;
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700570 if (LIKELY(c <= 0x7f)) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700571 // It's low-ascii, so check the table.
572 uint32_t wordIdx = c >> 5;
573 uint32_t bitIdx = c & 0x1f;
574 (*pUtf8Ptr)++;
575 return (DEX_MEMBER_VALID_LOW_ASCII[wordIdx] & (1 << bitIdx)) != 0;
576 }
577
578 // It's a multibyte encoded character. Call a non-inline function
579 // for the heavy lifting.
jeffhao10037c82012-01-23 15:06:23 -0800580 return IsValidPartOfMemberNameUtf8Slow(pUtf8Ptr);
581}
582
583bool IsValidMemberName(const char* s) {
584 bool angle_name = false;
585
Elliott Hughesb25c3f62012-03-26 16:35:06 -0700586 switch (*s) {
jeffhao10037c82012-01-23 15:06:23 -0800587 case '\0':
588 // The empty string is not a valid name.
589 return false;
590 case '<':
591 angle_name = true;
592 s++;
593 break;
594 }
595
596 while (true) {
597 switch (*s) {
598 case '\0':
599 return !angle_name;
600 case '>':
601 return angle_name && s[1] == '\0';
602 }
603
604 if (!IsValidPartOfMemberNameUtf8(&s)) {
605 return false;
606 }
607 }
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700608}
609
Elliott Hughes906e6852011-10-28 14:52:10 -0700610enum ClassNameType { kName, kDescriptor };
Ian Rogers7b078e82014-09-10 14:44:24 -0700611template<ClassNameType kType, char kSeparator>
612static bool IsValidClassName(const char* s) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700613 int arrayCount = 0;
614 while (*s == '[') {
615 arrayCount++;
616 s++;
617 }
618
619 if (arrayCount > 255) {
620 // Arrays may have no more than 255 dimensions.
621 return false;
622 }
623
Ian Rogers7b078e82014-09-10 14:44:24 -0700624 ClassNameType type = kType;
625 if (type != kDescriptor && arrayCount != 0) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700626 /*
627 * If we're looking at an array of some sort, then it doesn't
628 * matter if what is being asked for is a class name; the
629 * format looks the same as a type descriptor in that case, so
630 * treat it as such.
631 */
Elliott Hughes906e6852011-10-28 14:52:10 -0700632 type = kDescriptor;
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700633 }
634
Elliott Hughes906e6852011-10-28 14:52:10 -0700635 if (type == kDescriptor) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700636 /*
637 * We are looking for a descriptor. Either validate it as a
638 * single-character primitive type, or continue on to check the
639 * embedded class name (bracketed by "L" and ";").
640 */
641 switch (*(s++)) {
642 case 'B':
643 case 'C':
644 case 'D':
645 case 'F':
646 case 'I':
647 case 'J':
648 case 'S':
649 case 'Z':
650 // These are all single-character descriptors for primitive types.
651 return (*s == '\0');
652 case 'V':
653 // Non-array void is valid, but you can't have an array of void.
654 return (arrayCount == 0) && (*s == '\0');
655 case 'L':
656 // Class name: Break out and continue below.
657 break;
658 default:
659 // Oddball descriptor character.
660 return false;
661 }
662 }
663
664 /*
665 * We just consumed the 'L' that introduces a class name as part
666 * of a type descriptor, or we are looking for an unadorned class
667 * name.
668 */
669
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700670 bool sepOrFirst = true; // first character or just encountered a separator.
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700671 for (;;) {
672 uint8_t c = (uint8_t) *s;
673 switch (c) {
674 case '\0':
675 /*
676 * Premature end for a type descriptor, but valid for
677 * a class name as long as we haven't encountered an
678 * empty component (including the degenerate case of
679 * the empty string "").
680 */
Elliott Hughes906e6852011-10-28 14:52:10 -0700681 return (type == kName) && !sepOrFirst;
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700682 case ';':
683 /*
684 * Invalid character for a class name, but the
685 * legitimate end of a type descriptor. In the latter
686 * case, make sure that this is the end of the string
687 * and that it doesn't end with an empty component
688 * (including the degenerate case of "L;").
689 */
Elliott Hughes906e6852011-10-28 14:52:10 -0700690 return (type == kDescriptor) && !sepOrFirst && (s[1] == '\0');
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700691 case '/':
692 case '.':
Ian Rogers7b078e82014-09-10 14:44:24 -0700693 if (c != kSeparator) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700694 // The wrong separator character.
695 return false;
696 }
697 if (sepOrFirst) {
698 // Separator at start or two separators in a row.
699 return false;
700 }
701 sepOrFirst = true;
702 s++;
703 break;
704 default:
jeffhao10037c82012-01-23 15:06:23 -0800705 if (!IsValidPartOfMemberNameUtf8(&s)) {
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700706 return false;
707 }
708 sepOrFirst = false;
709 break;
710 }
711 }
712}
713
Elliott Hughes906e6852011-10-28 14:52:10 -0700714bool IsValidBinaryClassName(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 IsValidJniClassName(const char* s) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700719 return IsValidClassName<kName, '/'>(s);
Elliott Hughes906e6852011-10-28 14:52:10 -0700720}
721
722bool IsValidDescriptor(const char* s) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700723 return IsValidClassName<kDescriptor, '/'>(s);
Elliott Hughes906e6852011-10-28 14:52:10 -0700724}
725
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700726void Split(const std::string& s, char separator, std::vector<std::string>* result) {
Elliott Hughes34023802011-08-30 12:06:17 -0700727 const char* p = s.data();
728 const char* end = p + s.size();
729 while (p != end) {
Elliott Hughes48436bb2012-02-07 15:23:28 -0800730 if (*p == separator) {
Elliott Hughes34023802011-08-30 12:06:17 -0700731 ++p;
732 } else {
733 const char* start = p;
Elliott Hughes48436bb2012-02-07 15:23:28 -0800734 while (++p != end && *p != separator) {
735 // Skip to the next occurrence of the separator.
Elliott Hughes34023802011-08-30 12:06:17 -0700736 }
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700737 result->push_back(std::string(start, p - start));
Elliott Hughes34023802011-08-30 12:06:17 -0700738 }
739 }
740}
741
Elliott Hughes22869a92012-03-27 14:08:24 -0700742void SetThreadName(const char* thread_name) {
Elliott Hughesdcc24742011-09-07 14:02:44 -0700743 int hasAt = 0;
744 int hasDot = 0;
Elliott Hughes22869a92012-03-27 14:08:24 -0700745 const char* s = thread_name;
Elliott Hughesdcc24742011-09-07 14:02:44 -0700746 while (*s) {
747 if (*s == '.') {
748 hasDot = 1;
749 } else if (*s == '@') {
750 hasAt = 1;
751 }
752 s++;
753 }
Elliott Hughes22869a92012-03-27 14:08:24 -0700754 int len = s - thread_name;
Elliott Hughesdcc24742011-09-07 14:02:44 -0700755 if (len < 15 || hasAt || !hasDot) {
Elliott Hughes22869a92012-03-27 14:08:24 -0700756 s = thread_name;
Elliott Hughesdcc24742011-09-07 14:02:44 -0700757 } else {
Elliott Hughes22869a92012-03-27 14:08:24 -0700758 s = thread_name + len - 15;
Elliott Hughesdcc24742011-09-07 14:02:44 -0700759 }
Elliott Hughes0a18df82015-01-09 15:16:16 -0800760#if defined(__linux__)
Elliott Hughes7c6a61e2012-03-12 18:01:41 -0700761 // pthread_setname_np fails rather than truncating long strings.
Elliott Hughes0a18df82015-01-09 15:16:16 -0800762 char buf[16]; // MAX_TASK_COMM_LEN=16 is hard-coded in the kernel.
Elliott Hughesdcc24742011-09-07 14:02:44 -0700763 strncpy(buf, s, sizeof(buf)-1);
764 buf[sizeof(buf)-1] = '\0';
765 errno = pthread_setname_np(pthread_self(), buf);
766 if (errno != 0) {
767 PLOG(WARNING) << "Unable to set the name of current thread to '" << buf << "'";
768 }
Elliott Hughes0a18df82015-01-09 15:16:16 -0800769#else // __APPLE__
Elliott Hughes22869a92012-03-27 14:08:24 -0700770 pthread_setname_np(thread_name);
Elliott Hughesdcc24742011-09-07 14:02:44 -0700771#endif
772}
773
Brian Carlstrom29212012013-09-12 22:18:30 -0700774void GetTaskStats(pid_t tid, char* state, int* utime, int* stime, int* task_cpu) {
775 *utime = *stime = *task_cpu = 0;
Elliott Hughesbfe487b2011-10-26 15:48:55 -0700776 std::string stats;
Elliott Hughes8a31b502012-04-30 19:36:11 -0700777 if (!ReadFileToString(StringPrintf("/proc/self/task/%d/stat", tid), &stats)) {
Elliott Hughesbfe487b2011-10-26 15:48:55 -0700778 return;
779 }
780 // Skip the command, which may contain spaces.
781 stats = stats.substr(stats.find(')') + 2);
782 // Extract the three fields we care about.
783 std::vector<std::string> fields;
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700784 Split(stats, ' ', &fields);
Brian Carlstrom29212012013-09-12 22:18:30 -0700785 *state = fields[0][0];
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700786 *utime = strtoull(fields[11].c_str(), nullptr, 10);
787 *stime = strtoull(fields[12].c_str(), nullptr, 10);
788 *task_cpu = strtoull(fields[36].c_str(), nullptr, 10);
Elliott Hughesbfe487b2011-10-26 15:48:55 -0700789}
790
Calin Juravle36eb3132017-01-13 16:32:38 -0800791static const char* GetAndroidDirSafe(const char* env_var,
792 const char* default_dir,
793 std::string* error_msg) {
794 const char* android_dir = getenv(env_var);
795 if (android_dir == nullptr) {
796 if (OS::DirectoryExists(default_dir)) {
797 android_dir = default_dir;
Brian Carlstroma9f19782011-10-13 00:14:47 -0700798 } else {
Calin Juravle36eb3132017-01-13 16:32:38 -0800799 *error_msg = StringPrintf("%s not set and %s does not exist", env_var, default_dir);
800 return nullptr;
Brian Carlstroma9f19782011-10-13 00:14:47 -0700801 }
802 }
Calin Juravle36eb3132017-01-13 16:32:38 -0800803 if (!OS::DirectoryExists(android_dir)) {
804 *error_msg = StringPrintf("Failed to find %s directory %s", env_var, android_dir);
805 return nullptr;
Brian Carlstroma9f19782011-10-13 00:14:47 -0700806 }
Calin Juravle36eb3132017-01-13 16:32:38 -0800807 return android_dir;
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800808}
Brian Carlstroma9f19782011-10-13 00:14:47 -0700809
Calin Juravle36eb3132017-01-13 16:32:38 -0800810const char* GetAndroidDir(const char* env_var, const char* default_dir) {
Alex Lighta59dd802014-07-02 16:28:08 -0700811 std::string error_msg;
Calin Juravle36eb3132017-01-13 16:32:38 -0800812 const char* dir = GetAndroidDirSafe(env_var, default_dir, &error_msg);
Alex Lighta59dd802014-07-02 16:28:08 -0700813 if (dir != nullptr) {
814 return dir;
815 } else {
816 LOG(FATAL) << error_msg;
Calin Juravle36eb3132017-01-13 16:32:38 -0800817 return nullptr;
Alex Lighta59dd802014-07-02 16:28:08 -0700818 }
819}
820
Calin Juravle36eb3132017-01-13 16:32:38 -0800821const char* GetAndroidRoot() {
822 return GetAndroidDir("ANDROID_ROOT", "/system");
823}
824
825const char* GetAndroidRootSafe(std::string* error_msg) {
826 return GetAndroidDirSafe("ANDROID_ROOT", "/system", error_msg);
827}
828
829const char* GetAndroidData() {
830 return GetAndroidDir("ANDROID_DATA", "/data");
831}
832
Alex Lighta59dd802014-07-02 16:28:08 -0700833const char* GetAndroidDataSafe(std::string* error_msg) {
Calin Juravle36eb3132017-01-13 16:32:38 -0800834 return GetAndroidDirSafe("ANDROID_DATA", "/data", error_msg);
835}
836
837std::string GetDefaultBootImageLocation(std::string* error_msg) {
838 const char* android_root = GetAndroidRootSafe(error_msg);
839 if (android_root == nullptr) {
840 return "";
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800841 }
Calin Juravle36eb3132017-01-13 16:32:38 -0800842 return StringPrintf("%s/framework/boot.art", android_root);
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800843}
844
Alex Lighta59dd802014-07-02 16:28:08 -0700845void GetDalvikCache(const char* subdir, const bool create_if_absent, std::string* dalvik_cache,
Andreas Gampe3c13a792014-09-18 20:56:04 -0700846 bool* have_android_data, bool* dalvik_cache_exists, bool* is_global_cache) {
Alex Lighta59dd802014-07-02 16:28:08 -0700847 CHECK(subdir != nullptr);
848 std::string error_msg;
849 const char* android_data = GetAndroidDataSafe(&error_msg);
850 if (android_data == nullptr) {
851 *have_android_data = false;
852 *dalvik_cache_exists = false;
Andreas Gampe3c13a792014-09-18 20:56:04 -0700853 *is_global_cache = false;
Alex Lighta59dd802014-07-02 16:28:08 -0700854 return;
855 } else {
856 *have_android_data = true;
857 }
858 const std::string dalvik_cache_root(StringPrintf("%s/dalvik-cache/", android_data));
859 *dalvik_cache = dalvik_cache_root + subdir;
860 *dalvik_cache_exists = OS::DirectoryExists(dalvik_cache->c_str());
Andreas Gampe3c13a792014-09-18 20:56:04 -0700861 *is_global_cache = strcmp(android_data, "/data") == 0;
862 if (create_if_absent && !*dalvik_cache_exists && !*is_global_cache) {
Alex Lighta59dd802014-07-02 16:28:08 -0700863 // Don't create the system's /data/dalvik-cache/... because it needs special permissions.
864 *dalvik_cache_exists = ((mkdir(dalvik_cache_root.c_str(), 0700) == 0 || errno == EEXIST) &&
865 (mkdir(dalvik_cache->c_str(), 0700) == 0 || errno == EEXIST));
866 }
867}
868
Richard Uhler55b58b62016-08-12 09:05:13 -0700869std::string GetDalvikCache(const char* subdir) {
Narayan Kamath11d9f062014-04-23 20:24:57 +0100870 CHECK(subdir != nullptr);
Brian Carlstrom41ccffd2014-05-06 10:37:30 -0700871 const char* android_data = GetAndroidData();
872 const std::string dalvik_cache_root(StringPrintf("%s/dalvik-cache/", android_data));
Narayan Kamath11d9f062014-04-23 20:24:57 +0100873 const std::string dalvik_cache = dalvik_cache_root + subdir;
Andreas Gampe40da2862015-02-27 12:49:04 -0800874 if (!OS::DirectoryExists(dalvik_cache.c_str())) {
Richard Uhler55b58b62016-08-12 09:05:13 -0700875 // TODO: Check callers. Traditional behavior is to not abort.
876 return "";
Brian Carlstroma9f19782011-10-13 00:14:47 -0700877 }
Brian Carlstrom7675e162013-06-10 16:18:04 -0700878 return dalvik_cache;
Brian Carlstroma9f19782011-10-13 00:14:47 -0700879}
880
Alex Lighta59dd802014-07-02 16:28:08 -0700881bool GetDalvikCacheFilename(const char* location, const char* cache_location,
882 std::string* filename, std::string* error_msg) {
Ian Rogerse6060102013-05-16 12:01:04 -0700883 if (location[0] != '/') {
Alex Lighta59dd802014-07-02 16:28:08 -0700884 *error_msg = StringPrintf("Expected path in location to be absolute: %s", location);
885 return false;
Ian Rogerse6060102013-05-16 12:01:04 -0700886 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700887 std::string cache_file(&location[1]); // skip leading slash
Andreas Gampe9186ced2016-12-12 14:28:21 -0800888 if (!android::base::EndsWith(location, ".dex") &&
889 !android::base::EndsWith(location, ".art") &&
890 !android::base::EndsWith(location, ".oat")) {
Brian Carlstrom30e2ea42013-06-19 23:25:37 -0700891 cache_file += "/";
892 cache_file += DexFile::kClassesDex;
893 }
Brian Carlstromb7bbba42011-10-13 14:58:47 -0700894 std::replace(cache_file.begin(), cache_file.end(), '/', '@');
Alex Lighta59dd802014-07-02 16:28:08 -0700895 *filename = StringPrintf("%s/%s", cache_location, cache_file.c_str());
896 return true;
897}
898
Brian Carlstrom2afe4942014-05-19 10:25:33 -0700899static void InsertIsaDirectory(const InstructionSet isa, std::string* filename) {
Brian Carlstrom0e12bdc2014-05-14 17:44:28 -0700900 // in = /foo/bar/baz
901 // out = /foo/bar/<isa>/baz
902 size_t pos = filename->rfind('/');
903 CHECK_NE(pos, std::string::npos) << *filename << " " << isa;
904 filename->insert(pos, "/", 1);
905 filename->insert(pos + 1, GetInstructionSetString(isa));
906}
907
908std::string GetSystemImageFilename(const char* location, const InstructionSet isa) {
909 // location = /system/framework/boot.art
910 // filename = /system/framework/<isa>/boot.art
911 std::string filename(location);
Brian Carlstrom2afe4942014-05-19 10:25:33 -0700912 InsertIsaDirectory(isa, &filename);
Brian Carlstrom0e12bdc2014-05-14 17:44:28 -0700913 return filename;
914}
915
Calin Juravle2e2db782016-02-23 12:00:03 +0000916int ExecAndReturnCode(std::vector<std::string>& arg_vector, std::string* error_msg) {
Andreas Gampe9186ced2016-12-12 14:28:21 -0800917 const std::string command_line(android::base::Join(arg_vector, ' '));
Brian Carlstrom6449c622014-02-10 23:48:36 -0800918 CHECK_GE(arg_vector.size(), 1U) << command_line;
919
920 // Convert the args to char pointers.
921 const char* program = arg_vector[0].c_str();
922 std::vector<char*> args;
Brian Carlstrom35d8b8e2014-02-25 10:51:11 -0800923 for (size_t i = 0; i < arg_vector.size(); ++i) {
924 const std::string& arg = arg_vector[i];
925 char* arg_str = const_cast<char*>(arg.c_str());
926 CHECK(arg_str != nullptr) << i;
927 args.push_back(arg_str);
Brian Carlstrom6449c622014-02-10 23:48:36 -0800928 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700929 args.push_back(nullptr);
Brian Carlstrom6449c622014-02-10 23:48:36 -0800930
931 // fork and exec
932 pid_t pid = fork();
933 if (pid == 0) {
934 // no allocation allowed between fork and exec
935
936 // change process groups, so we don't get reaped by ProcessManager
937 setpgid(0, 0);
938
David Sehrd106d9f2016-08-16 19:22:57 -0700939 // (b/30160149): protect subprocesses from modifications to LD_LIBRARY_PATH, etc.
940 // Use the snapshot of the environment from the time the runtime was created.
941 char** envp = (Runtime::Current() == nullptr) ? nullptr : Runtime::Current()->GetEnvSnapshot();
942 if (envp == nullptr) {
943 execv(program, &args[0]);
944 } else {
945 execve(program, &args[0], envp);
946 }
947 PLOG(ERROR) << "Failed to execve(" << command_line << ")";
Tobias Lindskogae35c372015-11-04 19:41:21 +0100948 // _exit to avoid atexit handlers in child.
949 _exit(1);
Brian Carlstrom6449c622014-02-10 23:48:36 -0800950 } else {
951 if (pid == -1) {
952 *error_msg = StringPrintf("Failed to execv(%s) because fork failed: %s",
953 command_line.c_str(), strerror(errno));
Calin Juravle2e2db782016-02-23 12:00:03 +0000954 return -1;
Brian Carlstrom6449c622014-02-10 23:48:36 -0800955 }
956
957 // wait for subprocess to finish
Calin Juravle2e2db782016-02-23 12:00:03 +0000958 int status = -1;
Brian Carlstrom6449c622014-02-10 23:48:36 -0800959 pid_t got_pid = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0));
960 if (got_pid != pid) {
961 *error_msg = StringPrintf("Failed after fork for execv(%s) because waitpid failed: "
962 "wanted %d, got %d: %s",
963 command_line.c_str(), pid, got_pid, strerror(errno));
Calin Juravle2e2db782016-02-23 12:00:03 +0000964 return -1;
Brian Carlstrom6449c622014-02-10 23:48:36 -0800965 }
Calin Juravle2e2db782016-02-23 12:00:03 +0000966 if (WIFEXITED(status)) {
967 return WEXITSTATUS(status);
Brian Carlstrom6449c622014-02-10 23:48:36 -0800968 }
Calin Juravle2e2db782016-02-23 12:00:03 +0000969 return -1;
970 }
971}
972
973bool Exec(std::vector<std::string>& arg_vector, std::string* error_msg) {
974 int status = ExecAndReturnCode(arg_vector, error_msg);
975 if (status != 0) {
Andreas Gampe9186ced2016-12-12 14:28:21 -0800976 const std::string command_line(android::base::Join(arg_vector, ' '));
Calin Juravle2e2db782016-02-23 12:00:03 +0000977 *error_msg = StringPrintf("Failed execv(%s) because non-0 exit status",
978 command_line.c_str());
979 return false;
Brian Carlstrom6449c622014-02-10 23:48:36 -0800980 }
981 return true;
982}
983
Calin Juravle5e2b9712015-12-18 14:10:00 +0200984bool FileExists(const std::string& filename) {
985 struct stat buffer;
986 return stat(filename.c_str(), &buffer) == 0;
987}
988
Calin Juravleb9c1b9b2016-03-17 17:07:52 +0000989bool FileExistsAndNotEmpty(const std::string& filename) {
990 struct stat buffer;
991 if (stat(filename.c_str(), &buffer) != 0) {
992 return false;
993 }
994 return buffer.st_size > 0;
995}
996
David Brazdil7b49e6c2016-09-01 11:06:18 +0100997std::string ReplaceFileExtension(const std::string& filename, const std::string& new_extension) {
998 const size_t last_ext = filename.find_last_of('.');
999 if (last_ext == std::string::npos) {
1000 return filename + "." + new_extension;
1001 } else {
1002 return filename.substr(0, last_ext + 1) + new_extension;
1003 }
1004}
1005
Mathieu Chartier76433272014-09-26 14:32:37 -07001006std::string PrettyDescriptor(Primitive::Type type) {
1007 return PrettyDescriptor(Primitive::Descriptor(type));
1008}
1009
Nicolas Geoffrayabbb0f72015-10-29 18:55:58 +00001010static void ParseStringAfterChar(const std::string& s,
1011 char c,
1012 std::string* parsed_value,
1013 UsageFn Usage) {
1014 std::string::size_type colon = s.find(c);
1015 if (colon == std::string::npos) {
1016 Usage("Missing char %c in option %s\n", c, s.c_str());
1017 }
1018 // Add one to remove the char we were trimming until.
1019 *parsed_value = s.substr(colon + 1);
1020}
1021
1022void ParseDouble(const std::string& option,
1023 char after_char,
1024 double min,
1025 double max,
1026 double* parsed_value,
1027 UsageFn Usage) {
1028 std::string substring;
1029 ParseStringAfterChar(option, after_char, &substring, Usage);
1030 bool sane_val = true;
1031 double value;
1032 if ((false)) {
1033 // TODO: this doesn't seem to work on the emulator. b/15114595
1034 std::stringstream iss(substring);
1035 iss >> value;
1036 // Ensure that we have a value, there was no cruft after it and it satisfies a sensible range.
1037 sane_val = iss.eof() && (value >= min) && (value <= max);
1038 } else {
1039 char* end = nullptr;
1040 value = strtod(substring.c_str(), &end);
1041 sane_val = *end == '\0' && value >= min && value <= max;
1042 }
1043 if (!sane_val) {
1044 Usage("Invalid double value %s for option %s\n", substring.c_str(), option.c_str());
1045 }
1046 *parsed_value = value;
1047}
1048
Calin Juravle4d77b6a2015-12-01 18:38:09 +00001049int64_t GetFileSizeBytes(const std::string& filename) {
1050 struct stat stat_buf;
1051 int rc = stat(filename.c_str(), &stat_buf);
1052 return rc == 0 ? stat_buf.st_size : -1;
1053}
1054
Mathieu Chartier4d87df62016-01-07 15:14:19 -08001055void SleepForever() {
1056 while (true) {
1057 usleep(1000000);
1058 }
1059}
1060
Elliott Hughes42ee1422011-09-06 12:33:32 -07001061} // namespace art