1 /*
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 */
16
17 #ifndef ART_RUNTIME_UTILS_H_
18 #define ART_RUNTIME_UTILS_H_
19
20 #include <pthread.h>
21 #include <stdlib.h>
22
23 #include <limits>
24 #include <memory>
25 #include <random>
26 #include <string>
27 #include <type_traits>
28 #include <vector>
29
30 #include "arch/instruction_set.h"
31 #include "base/casts.h"
32 #include "base/logging.h"
33 #include "base/stringpiece.h"
34 #include "globals.h"
35 #include "primitive.h"
36
37 namespace art {
38
39 template <typename T>
ParseUint(const char * in,T * out)40 bool ParseUint(const char *in, T* out) {
41 char* end;
42 unsigned long long int result = strtoull(in, &end, 0); // NOLINT(runtime/int)
43 if (in == end || *end != '\0') {
44 return false;
45 }
46 if (std::numeric_limits<T>::max() < result) {
47 return false;
48 }
49 *out = static_cast<T>(result);
50 return true;
51 }
52
53 template <typename T>
ParseInt(const char * in,T * out)54 bool ParseInt(const char* in, T* out) {
55 char* end;
56 long long int result = strtoll(in, &end, 0); // NOLINT(runtime/int)
57 if (in == end || *end != '\0') {
58 return false;
59 }
60 if (result < std::numeric_limits<T>::min() || std::numeric_limits<T>::max() < result) {
61 return false;
62 }
63 *out = static_cast<T>(result);
64 return true;
65 }
66
PointerToLowMemUInt32(const void * p)67 static inline uint32_t PointerToLowMemUInt32(const void* p) {
68 uintptr_t intp = reinterpret_cast<uintptr_t>(p);
69 DCHECK_LE(intp, 0xFFFFFFFFU);
70 return intp & 0xFFFFFFFFU;
71 }
72
73 std::string PrintableChar(uint16_t ch);
74
75 // Returns an ASCII string corresponding to the given UTF-8 string.
76 // Java escapes are used for non-ASCII characters.
77 std::string PrintableString(const char* utf8);
78
79 // Used to implement PrettyClass, PrettyField, PrettyMethod, and PrettyTypeOf,
80 // one of which is probably more useful to you.
81 // Returns a human-readable equivalent of 'descriptor'. So "I" would be "int",
82 // "[[I" would be "int[][]", "[Ljava/lang/String;" would be
83 // "java.lang.String[]", and so forth.
84 std::string PrettyDescriptor(const char* descriptor);
85 std::string PrettyDescriptor(Primitive::Type type);
86
87 // Utilities for printing the types for method signatures.
88 std::string PrettyArguments(const char* signature);
89 std::string PrettyReturnType(const char* signature);
90
91 // Returns a human-readable version of the Java part of the access flags, e.g., "private static "
92 // (note the trailing whitespace).
93 std::string PrettyJavaAccessFlags(uint32_t access_flags);
94
95 // Returns a human-readable size string such as "1MB".
96 std::string PrettySize(int64_t size_in_bytes);
97
98 // Performs JNI name mangling as described in section 11.3 "Linking Native Methods"
99 // of the JNI spec.
100 std::string MangleForJni(const std::string& s);
101
102 std::string GetJniShortName(const std::string& class_name, const std::string& method_name);
103
104 // Turn "java.lang.String" into "Ljava/lang/String;".
105 std::string DotToDescriptor(const char* class_name);
106
107 // Turn "Ljava/lang/String;" into "java.lang.String" using the conventions of
108 // java.lang.Class.getName().
109 std::string DescriptorToDot(const char* descriptor);
110
111 // Turn "Ljava/lang/String;" into "java/lang/String" using the opposite conventions of
112 // java.lang.Class.getName().
113 std::string DescriptorToName(const char* descriptor);
114
115 // Tests for whether 's' is a valid class name in the three common forms:
116 bool IsValidBinaryClassName(const char* s); // "java.lang.String"
117 bool IsValidJniClassName(const char* s); // "java/lang/String"
118 bool IsValidDescriptor(const char* s); // "Ljava/lang/String;"
119
120 // Returns whether the given string is a valid field or method name,
121 // additionally allowing names that begin with '<' and end with '>'.
122 bool IsValidMemberName(const char* s);
123
124 bool ReadFileToString(const std::string& file_name, std::string* result);
125 bool PrintFileToLog(const std::string& file_name, LogSeverity level);
126
127 // Splits a string using the given separator character into a vector of
128 // strings. Empty strings will be omitted.
129 void Split(const std::string& s, char separator, std::vector<std::string>* result);
130
131 // Returns the calling thread's tid. (The C libraries don't expose this.)
132 pid_t GetTid();
133
134 // Returns the given thread's name.
135 std::string GetThreadName(pid_t tid);
136
137 // Reads data from "/proc/self/task/${tid}/stat".
138 void GetTaskStats(pid_t tid, char* state, int* utime, int* stime, int* task_cpu);
139
140 // Sets the name of the current thread. The name may be truncated to an
141 // implementation-defined limit.
142 void SetThreadName(const char* thread_name);
143
144 // Find $ANDROID_ROOT, /system, or abort.
145 const char* GetAndroidRoot();
146 // Find $ANDROID_ROOT, /system, or return null.
147 const char* GetAndroidRootSafe(std::string* error_msg);
148
149 // Find $ANDROID_DATA, /data, or abort.
150 const char* GetAndroidData();
151 // Find $ANDROID_DATA, /data, or return null.
152 const char* GetAndroidDataSafe(std::string* error_msg);
153
154 // Returns the default boot image location (ANDROID_ROOT/framework/boot.art).
155 // Returns an empty string if ANDROID_ROOT is not set.
156 std::string GetDefaultBootImageLocation(std::string* error_msg);
157
158 // Returns the dalvik-cache location, with subdir appended. Returns the empty string if the cache
159 // could not be found.
160 std::string GetDalvikCache(const char* subdir);
161 // Return true if we found the dalvik cache and stored it in the dalvik_cache argument.
162 // have_android_data will be set to true if we have an ANDROID_DATA that exists,
163 // dalvik_cache_exists will be true if there is a dalvik-cache directory that is present.
164 // The flag is_global_cache tells whether this cache is /data/dalvik-cache.
165 void GetDalvikCache(const char* subdir, bool create_if_absent, std::string* dalvik_cache,
166 bool* have_android_data, bool* dalvik_cache_exists, bool* is_global_cache);
167
168 // Returns the absolute dalvik-cache path for a DexFile or OatFile. The path returned will be
169 // rooted at cache_location.
170 bool GetDalvikCacheFilename(const char* file_location, const char* cache_location,
171 std::string* filename, std::string* error_msg);
172
173 // Returns the system location for an image
174 std::string GetSystemImageFilename(const char* location, InstructionSet isa);
175
176 // Returns the vdex filename for the given oat filename.
177 std::string GetVdexFilename(const std::string& oat_filename);
178
179 // Returns true if the file exists.
180 bool FileExists(const std::string& filename);
181 bool FileExistsAndNotEmpty(const std::string& filename);
182
183 // Returns `filename` with the text after the last occurrence of '.' replaced with
184 // `extension`. If `filename` does not contain a period, returns a string containing `filename`,
185 // a period, and `new_extension`.
186 // Example: ReplaceFileExtension("foo.bar", "abc") == "foo.abc"
187 // ReplaceFileExtension("foo", "abc") == "foo.abc"
188 std::string ReplaceFileExtension(const std::string& filename, const std::string& new_extension);
189
190 class VoidFunctor {
191 public:
192 template <typename A>
operator()193 inline void operator() (A a ATTRIBUTE_UNUSED) const {
194 }
195
196 template <typename A, typename B>
operator()197 inline void operator() (A a ATTRIBUTE_UNUSED, B b ATTRIBUTE_UNUSED) const {
198 }
199
200 template <typename A, typename B, typename C>
operator()201 inline void operator() (A a ATTRIBUTE_UNUSED, B b ATTRIBUTE_UNUSED, C c ATTRIBUTE_UNUSED) const {
202 }
203 };
204
TestBitmap(size_t idx,const uint8_t * bitmap)205 inline bool TestBitmap(size_t idx, const uint8_t* bitmap) {
206 return ((bitmap[idx / kBitsPerByte] >> (idx % kBitsPerByte)) & 0x01) != 0;
207 }
208
ValidPointerSize(size_t pointer_size)209 static inline constexpr bool ValidPointerSize(size_t pointer_size) {
210 return pointer_size == 4 || pointer_size == 8;
211 }
212
EntryPointToCodePointer(const void * entry_point)213 static inline const void* EntryPointToCodePointer(const void* entry_point) {
214 uintptr_t code = reinterpret_cast<uintptr_t>(entry_point);
215 // TODO: Make this Thumb2 specific. It is benign on other architectures as code is always at
216 // least 2 byte aligned.
217 code &= ~0x1;
218 return reinterpret_cast<const void*>(code);
219 }
220
221 using UsageFn = void (*)(const char*, ...);
222
223 template <typename T>
224 static void ParseIntOption(const StringPiece& option,
225 const std::string& option_name,
226 T* out,
227 UsageFn usage,
228 bool is_long_option = true) {
229 std::string option_prefix = option_name + (is_long_option ? "=" : "");
230 DCHECK(option.starts_with(option_prefix)) << option << " " << option_prefix;
231 const char* value_string = option.substr(option_prefix.size()).data();
232 int64_t parsed_integer_value = 0;
233 if (!ParseInt(value_string, &parsed_integer_value)) {
234 usage("Failed to parse %s '%s' as an integer", option_name.c_str(), value_string);
235 }
236 *out = dchecked_integral_cast<T>(parsed_integer_value);
237 }
238
239 template <typename T>
240 static void ParseUintOption(const StringPiece& option,
241 const std::string& option_name,
242 T* out,
243 UsageFn usage,
244 bool is_long_option = true) {
245 ParseIntOption(option, option_name, out, usage, is_long_option);
246 if (*out < 0) {
247 usage("%s passed a negative value %d", option_name.c_str(), *out);
248 *out = 0;
249 }
250 }
251
252 void ParseDouble(const std::string& option,
253 char after_char,
254 double min,
255 double max,
256 double* parsed_value,
257 UsageFn Usage);
258
259 #if defined(__BIONIC__)
260 struct Arc4RandomGenerator {
261 typedef uint32_t result_type;
minArc4RandomGenerator262 static constexpr uint32_t min() { return std::numeric_limits<uint32_t>::min(); }
maxArc4RandomGenerator263 static constexpr uint32_t max() { return std::numeric_limits<uint32_t>::max(); }
operatorArc4RandomGenerator264 uint32_t operator() () { return arc4random(); }
265 };
266 using RNG = Arc4RandomGenerator;
267 #else
268 using RNG = std::random_device;
269 #endif
270
271 template <typename T>
GetRandomNumber(T min,T max)272 static T GetRandomNumber(T min, T max) {
273 CHECK_LT(min, max);
274 std::uniform_int_distribution<T> dist(min, max);
275 RNG rng;
276 return dist(rng);
277 }
278
279 // Return the file size in bytes or -1 if the file does not exists.
280 int64_t GetFileSizeBytes(const std::string& filename);
281
282 // Sleep forever and never come back.
283 NO_RETURN void SleepForever();
284
FlushInstructionCache(char * begin,char * end)285 inline void FlushInstructionCache(char* begin, char* end) {
286 __builtin___clear_cache(begin, end);
287 }
288
FlushDataCache(char * begin,char * end)289 inline void FlushDataCache(char* begin, char* end) {
290 // Same as FlushInstructionCache for lack of other builtin. __builtin___clear_cache
291 // flushes both caches.
292 __builtin___clear_cache(begin, end);
293 }
294
295 template <typename T>
ConvertToPointerSize(T any)296 constexpr PointerSize ConvertToPointerSize(T any) {
297 if (any == 4 || any == 8) {
298 return static_cast<PointerSize>(any);
299 } else {
300 LOG(FATAL);
301 UNREACHABLE();
302 }
303 }
304
305 // Returns a type cast pointer if object pointed to is within the provided bounds.
306 // Otherwise returns nullptr.
307 template <typename T>
BoundsCheckedCast(const void * pointer,const void * lower,const void * upper)308 inline static T BoundsCheckedCast(const void* pointer,
309 const void* lower,
310 const void* upper) {
311 const uint8_t* bound_begin = static_cast<const uint8_t*>(lower);
312 const uint8_t* bound_end = static_cast<const uint8_t*>(upper);
313 DCHECK(bound_begin <= bound_end);
314
315 T result = reinterpret_cast<T>(pointer);
316 const uint8_t* begin = static_cast<const uint8_t*>(pointer);
317 const uint8_t* end = begin + sizeof(*result);
318 if (begin < bound_begin || end > bound_end || begin > end) {
319 return nullptr;
320 }
321 return result;
322 }
323
324 template <typename T, size_t size>
ArrayCount(const T (&)[size])325 constexpr size_t ArrayCount(const T (&)[size]) {
326 return size;
327 }
328
329 // Return -1 if <, 0 if ==, 1 if >.
330 template <typename T>
Compare(T lhs,T rhs)331 inline static int32_t Compare(T lhs, T rhs) {
332 return (lhs < rhs) ? -1 : ((lhs == rhs) ? 0 : 1);
333 }
334
335 // Return -1 if < 0, 0 if == 0, 1 if > 0.
336 template <typename T>
Signum(T opnd)337 inline static int32_t Signum(T opnd) {
338 return (opnd < 0) ? -1 : ((opnd == 0) ? 0 : 1);
339 }
340
341 } // namespace art
342
343 #endif // ART_RUNTIME_UTILS_H_
344