blob: 8867743ec193f71acbd516023b9a8297db024f2a [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
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800791const char* GetAndroidRoot() {
792 const char* android_root = getenv("ANDROID_ROOT");
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700793 if (android_root == nullptr) {
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800794 if (OS::DirectoryExists("/system")) {
795 android_root = "/system";
Brian Carlstroma9f19782011-10-13 00:14:47 -0700796 } else {
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800797 LOG(FATAL) << "ANDROID_ROOT not set and /system does not exist";
798 return "";
Brian Carlstroma9f19782011-10-13 00:14:47 -0700799 }
800 }
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800801 if (!OS::DirectoryExists(android_root)) {
802 LOG(FATAL) << "Failed to find ANDROID_ROOT directory " << android_root;
Brian Carlstroma9f19782011-10-13 00:14:47 -0700803 return "";
804 }
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800805 return android_root;
806}
Brian Carlstroma9f19782011-10-13 00:14:47 -0700807
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800808const char* GetAndroidData() {
Alex Lighta59dd802014-07-02 16:28:08 -0700809 std::string error_msg;
810 const char* dir = GetAndroidDataSafe(&error_msg);
811 if (dir != nullptr) {
812 return dir;
813 } else {
814 LOG(FATAL) << error_msg;
815 return "";
816 }
817}
818
819const char* GetAndroidDataSafe(std::string* error_msg) {
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800820 const char* android_data = getenv("ANDROID_DATA");
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700821 if (android_data == nullptr) {
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800822 if (OS::DirectoryExists("/data")) {
823 android_data = "/data";
824 } else {
Alex Lighta59dd802014-07-02 16:28:08 -0700825 *error_msg = "ANDROID_DATA not set and /data does not exist";
826 return nullptr;
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800827 }
828 }
829 if (!OS::DirectoryExists(android_data)) {
Alex Lighta59dd802014-07-02 16:28:08 -0700830 *error_msg = StringPrintf("Failed to find ANDROID_DATA directory %s", android_data);
831 return nullptr;
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800832 }
833 return android_data;
834}
835
Alex Lighta59dd802014-07-02 16:28:08 -0700836void GetDalvikCache(const char* subdir, const bool create_if_absent, std::string* dalvik_cache,
Andreas Gampe3c13a792014-09-18 20:56:04 -0700837 bool* have_android_data, bool* dalvik_cache_exists, bool* is_global_cache) {
Alex Lighta59dd802014-07-02 16:28:08 -0700838 CHECK(subdir != nullptr);
839 std::string error_msg;
840 const char* android_data = GetAndroidDataSafe(&error_msg);
841 if (android_data == nullptr) {
842 *have_android_data = false;
843 *dalvik_cache_exists = false;
Andreas Gampe3c13a792014-09-18 20:56:04 -0700844 *is_global_cache = false;
Alex Lighta59dd802014-07-02 16:28:08 -0700845 return;
846 } else {
847 *have_android_data = true;
848 }
849 const std::string dalvik_cache_root(StringPrintf("%s/dalvik-cache/", android_data));
850 *dalvik_cache = dalvik_cache_root + subdir;
851 *dalvik_cache_exists = OS::DirectoryExists(dalvik_cache->c_str());
Andreas Gampe3c13a792014-09-18 20:56:04 -0700852 *is_global_cache = strcmp(android_data, "/data") == 0;
853 if (create_if_absent && !*dalvik_cache_exists && !*is_global_cache) {
Alex Lighta59dd802014-07-02 16:28:08 -0700854 // Don't create the system's /data/dalvik-cache/... because it needs special permissions.
855 *dalvik_cache_exists = ((mkdir(dalvik_cache_root.c_str(), 0700) == 0 || errno == EEXIST) &&
856 (mkdir(dalvik_cache->c_str(), 0700) == 0 || errno == EEXIST));
857 }
858}
859
Richard Uhler55b58b62016-08-12 09:05:13 -0700860std::string GetDalvikCache(const char* subdir) {
Narayan Kamath11d9f062014-04-23 20:24:57 +0100861 CHECK(subdir != nullptr);
Brian Carlstrom41ccffd2014-05-06 10:37:30 -0700862 const char* android_data = GetAndroidData();
863 const std::string dalvik_cache_root(StringPrintf("%s/dalvik-cache/", android_data));
Narayan Kamath11d9f062014-04-23 20:24:57 +0100864 const std::string dalvik_cache = dalvik_cache_root + subdir;
Andreas Gampe40da2862015-02-27 12:49:04 -0800865 if (!OS::DirectoryExists(dalvik_cache.c_str())) {
Richard Uhler55b58b62016-08-12 09:05:13 -0700866 // TODO: Check callers. Traditional behavior is to not abort.
867 return "";
Brian Carlstroma9f19782011-10-13 00:14:47 -0700868 }
Brian Carlstrom7675e162013-06-10 16:18:04 -0700869 return dalvik_cache;
Brian Carlstroma9f19782011-10-13 00:14:47 -0700870}
871
Alex Lighta59dd802014-07-02 16:28:08 -0700872bool GetDalvikCacheFilename(const char* location, const char* cache_location,
873 std::string* filename, std::string* error_msg) {
Ian Rogerse6060102013-05-16 12:01:04 -0700874 if (location[0] != '/') {
Alex Lighta59dd802014-07-02 16:28:08 -0700875 *error_msg = StringPrintf("Expected path in location to be absolute: %s", location);
876 return false;
Ian Rogerse6060102013-05-16 12:01:04 -0700877 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700878 std::string cache_file(&location[1]); // skip leading slash
Andreas Gampe9186ced2016-12-12 14:28:21 -0800879 if (!android::base::EndsWith(location, ".dex") &&
880 !android::base::EndsWith(location, ".art") &&
881 !android::base::EndsWith(location, ".oat")) {
Brian Carlstrom30e2ea42013-06-19 23:25:37 -0700882 cache_file += "/";
883 cache_file += DexFile::kClassesDex;
884 }
Brian Carlstromb7bbba42011-10-13 14:58:47 -0700885 std::replace(cache_file.begin(), cache_file.end(), '/', '@');
Alex Lighta59dd802014-07-02 16:28:08 -0700886 *filename = StringPrintf("%s/%s", cache_location, cache_file.c_str());
887 return true;
888}
889
Brian Carlstrom2afe4942014-05-19 10:25:33 -0700890static void InsertIsaDirectory(const InstructionSet isa, std::string* filename) {
Brian Carlstrom0e12bdc2014-05-14 17:44:28 -0700891 // in = /foo/bar/baz
892 // out = /foo/bar/<isa>/baz
893 size_t pos = filename->rfind('/');
894 CHECK_NE(pos, std::string::npos) << *filename << " " << isa;
895 filename->insert(pos, "/", 1);
896 filename->insert(pos + 1, GetInstructionSetString(isa));
897}
898
899std::string GetSystemImageFilename(const char* location, const InstructionSet isa) {
900 // location = /system/framework/boot.art
901 // filename = /system/framework/<isa>/boot.art
902 std::string filename(location);
Brian Carlstrom2afe4942014-05-19 10:25:33 -0700903 InsertIsaDirectory(isa, &filename);
Brian Carlstrom0e12bdc2014-05-14 17:44:28 -0700904 return filename;
905}
906
Calin Juravle2e2db782016-02-23 12:00:03 +0000907int ExecAndReturnCode(std::vector<std::string>& arg_vector, std::string* error_msg) {
Andreas Gampe9186ced2016-12-12 14:28:21 -0800908 const std::string command_line(android::base::Join(arg_vector, ' '));
Brian Carlstrom6449c622014-02-10 23:48:36 -0800909 CHECK_GE(arg_vector.size(), 1U) << command_line;
910
911 // Convert the args to char pointers.
912 const char* program = arg_vector[0].c_str();
913 std::vector<char*> args;
Brian Carlstrom35d8b8e2014-02-25 10:51:11 -0800914 for (size_t i = 0; i < arg_vector.size(); ++i) {
915 const std::string& arg = arg_vector[i];
916 char* arg_str = const_cast<char*>(arg.c_str());
917 CHECK(arg_str != nullptr) << i;
918 args.push_back(arg_str);
Brian Carlstrom6449c622014-02-10 23:48:36 -0800919 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700920 args.push_back(nullptr);
Brian Carlstrom6449c622014-02-10 23:48:36 -0800921
922 // fork and exec
923 pid_t pid = fork();
924 if (pid == 0) {
925 // no allocation allowed between fork and exec
926
927 // change process groups, so we don't get reaped by ProcessManager
928 setpgid(0, 0);
929
David Sehrd106d9f2016-08-16 19:22:57 -0700930 // (b/30160149): protect subprocesses from modifications to LD_LIBRARY_PATH, etc.
931 // Use the snapshot of the environment from the time the runtime was created.
932 char** envp = (Runtime::Current() == nullptr) ? nullptr : Runtime::Current()->GetEnvSnapshot();
933 if (envp == nullptr) {
934 execv(program, &args[0]);
935 } else {
936 execve(program, &args[0], envp);
937 }
938 PLOG(ERROR) << "Failed to execve(" << command_line << ")";
Tobias Lindskogae35c372015-11-04 19:41:21 +0100939 // _exit to avoid atexit handlers in child.
940 _exit(1);
Brian Carlstrom6449c622014-02-10 23:48:36 -0800941 } else {
942 if (pid == -1) {
943 *error_msg = StringPrintf("Failed to execv(%s) because fork failed: %s",
944 command_line.c_str(), strerror(errno));
Calin Juravle2e2db782016-02-23 12:00:03 +0000945 return -1;
Brian Carlstrom6449c622014-02-10 23:48:36 -0800946 }
947
948 // wait for subprocess to finish
Calin Juravle2e2db782016-02-23 12:00:03 +0000949 int status = -1;
Brian Carlstrom6449c622014-02-10 23:48:36 -0800950 pid_t got_pid = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0));
951 if (got_pid != pid) {
952 *error_msg = StringPrintf("Failed after fork for execv(%s) because waitpid failed: "
953 "wanted %d, got %d: %s",
954 command_line.c_str(), pid, got_pid, strerror(errno));
Calin Juravle2e2db782016-02-23 12:00:03 +0000955 return -1;
Brian Carlstrom6449c622014-02-10 23:48:36 -0800956 }
Calin Juravle2e2db782016-02-23 12:00:03 +0000957 if (WIFEXITED(status)) {
958 return WEXITSTATUS(status);
Brian Carlstrom6449c622014-02-10 23:48:36 -0800959 }
Calin Juravle2e2db782016-02-23 12:00:03 +0000960 return -1;
961 }
962}
963
964bool Exec(std::vector<std::string>& arg_vector, std::string* error_msg) {
965 int status = ExecAndReturnCode(arg_vector, error_msg);
966 if (status != 0) {
Andreas Gampe9186ced2016-12-12 14:28:21 -0800967 const std::string command_line(android::base::Join(arg_vector, ' '));
Calin Juravle2e2db782016-02-23 12:00:03 +0000968 *error_msg = StringPrintf("Failed execv(%s) because non-0 exit status",
969 command_line.c_str());
970 return false;
Brian Carlstrom6449c622014-02-10 23:48:36 -0800971 }
972 return true;
973}
974
Calin Juravle5e2b9712015-12-18 14:10:00 +0200975bool FileExists(const std::string& filename) {
976 struct stat buffer;
977 return stat(filename.c_str(), &buffer) == 0;
978}
979
Calin Juravleb9c1b9b2016-03-17 17:07:52 +0000980bool FileExistsAndNotEmpty(const std::string& filename) {
981 struct stat buffer;
982 if (stat(filename.c_str(), &buffer) != 0) {
983 return false;
984 }
985 return buffer.st_size > 0;
986}
987
David Brazdil7b49e6c2016-09-01 11:06:18 +0100988std::string ReplaceFileExtension(const std::string& filename, const std::string& new_extension) {
989 const size_t last_ext = filename.find_last_of('.');
990 if (last_ext == std::string::npos) {
991 return filename + "." + new_extension;
992 } else {
993 return filename.substr(0, last_ext + 1) + new_extension;
994 }
995}
996
Mathieu Chartier76433272014-09-26 14:32:37 -0700997std::string PrettyDescriptor(Primitive::Type type) {
998 return PrettyDescriptor(Primitive::Descriptor(type));
999}
1000
Nicolas Geoffrayabbb0f72015-10-29 18:55:58 +00001001static void ParseStringAfterChar(const std::string& s,
1002 char c,
1003 std::string* parsed_value,
1004 UsageFn Usage) {
1005 std::string::size_type colon = s.find(c);
1006 if (colon == std::string::npos) {
1007 Usage("Missing char %c in option %s\n", c, s.c_str());
1008 }
1009 // Add one to remove the char we were trimming until.
1010 *parsed_value = s.substr(colon + 1);
1011}
1012
1013void ParseDouble(const std::string& option,
1014 char after_char,
1015 double min,
1016 double max,
1017 double* parsed_value,
1018 UsageFn Usage) {
1019 std::string substring;
1020 ParseStringAfterChar(option, after_char, &substring, Usage);
1021 bool sane_val = true;
1022 double value;
1023 if ((false)) {
1024 // TODO: this doesn't seem to work on the emulator. b/15114595
1025 std::stringstream iss(substring);
1026 iss >> value;
1027 // Ensure that we have a value, there was no cruft after it and it satisfies a sensible range.
1028 sane_val = iss.eof() && (value >= min) && (value <= max);
1029 } else {
1030 char* end = nullptr;
1031 value = strtod(substring.c_str(), &end);
1032 sane_val = *end == '\0' && value >= min && value <= max;
1033 }
1034 if (!sane_val) {
1035 Usage("Invalid double value %s for option %s\n", substring.c_str(), option.c_str());
1036 }
1037 *parsed_value = value;
1038}
1039
Calin Juravle4d77b6a2015-12-01 18:38:09 +00001040int64_t GetFileSizeBytes(const std::string& filename) {
1041 struct stat stat_buf;
1042 int rc = stat(filename.c_str(), &stat_buf);
1043 return rc == 0 ? stat_buf.st_size : -1;
1044}
1045
Mathieu Chartier4d87df62016-01-07 15:14:19 -08001046void SleepForever() {
1047 while (true) {
1048 usleep(1000000);
1049 }
1050}
1051
Elliott Hughes42ee1422011-09-06 12:33:32 -07001052} // namespace art