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