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_OAT_FILE_H_ 18 #define ART_RUNTIME_OAT_FILE_H_ 19 20 #include <list> 21 #include <string> 22 #include <vector> 23 24 #include "base/mutex.h" 25 #include "base/stringpiece.h" 26 #include "dex_file.h" 27 #include "invoke_type.h" 28 #include "mem_map.h" 29 #include "mirror/class.h" 30 #include "oat.h" 31 #include "os.h" 32 #include "utils.h" 33 34 namespace art { 35 36 class BitVector; 37 class ElfFile; 38 class MemMap; 39 class OatMethodOffsets; 40 class OatHeader; 41 class OatDexFile; 42 43 namespace gc { 44 namespace collector { 45 class DummyOatFile; 46 } // namespace collector 47 } // namespace gc 48 49 class OatFile { 50 public: 51 // Special classpath that skips shared library check. 52 static constexpr const char* kSpecialSharedLibrary = "&"; 53 54 typedef art::OatDexFile OatDexFile; 55 56 // Opens an oat file contained within the given elf file. This is always opened as 57 // non-executable at the moment. 58 static OatFile* OpenWithElfFile(ElfFile* elf_file, const std::string& location, 59 const char* abs_dex_location, 60 std::string* error_msg); 61 // Open an oat file. Returns null on failure. Requested base can 62 // optionally be used to request where the file should be loaded. 63 // See the ResolveRelativeEncodedDexLocation for a description of how the 64 // abs_dex_location argument is used. 65 static OatFile* Open(const std::string& filename, 66 const std::string& location, 67 uint8_t* requested_base, 68 uint8_t* oat_file_begin, 69 bool executable, 70 bool low_4gb, 71 const char* abs_dex_location, 72 std::string* error_msg); 73 74 // Open an oat file from an already opened File. 75 // Does not use dlopen underneath so cannot be used for runtime use 76 // where relocations may be required. Currently used from 77 // ImageWriter which wants to open a writable version from an existing 78 // file descriptor for patching. 79 static OatFile* OpenWritable(File* file, const std::string& location, 80 const char* abs_dex_location, 81 std::string* error_msg); 82 // Opens an oat file from an already opened File. Maps it PROT_READ, MAP_PRIVATE. 83 static OatFile* OpenReadable(File* file, const std::string& location, 84 const char* abs_dex_location, 85 std::string* error_msg); 86 87 virtual ~OatFile(); 88 IsExecutable()89 bool IsExecutable() const { 90 return is_executable_; 91 } 92 93 bool HasPatchInfo() const; 94 95 bool IsPic() const; 96 97 // Indicates whether the oat file was compiled with full debugging capability. 98 bool IsDebuggable() const; 99 100 CompilerFilter::Filter GetCompilerFilter() const; 101 GetLocation()102 const std::string& GetLocation() const { 103 return location_; 104 } 105 106 const OatHeader& GetOatHeader() const; 107 108 class OatMethod FINAL { 109 public: 110 void LinkMethod(ArtMethod* method) const; 111 112 uint32_t GetCodeOffset() const; 113 114 const void* GetQuickCode() const; 115 116 // Returns size of quick code. 117 uint32_t GetQuickCodeSize() const; 118 uint32_t GetQuickCodeSizeOffset() const; 119 120 // Returns OatQuickMethodHeader for debugging. Most callers should 121 // use more specific methods such as GetQuickCodeSize. 122 const OatQuickMethodHeader* GetOatQuickMethodHeader() const; 123 uint32_t GetOatQuickMethodHeaderOffset() const; 124 125 size_t GetFrameSizeInBytes() const; 126 uint32_t GetCoreSpillMask() const; 127 uint32_t GetFpSpillMask() const; 128 129 const uint8_t* GetVmapTable() const; 130 uint32_t GetVmapTableOffset() const; 131 uint32_t GetVmapTableOffsetOffset() const; 132 133 // Create an OatMethod with offsets relative to the given base address OatMethod(const uint8_t * base,const uint32_t code_offset)134 OatMethod(const uint8_t* base, const uint32_t code_offset) 135 : begin_(base), code_offset_(code_offset) { 136 } 137 OatMethod(const OatMethod&) = default; ~OatMethod()138 ~OatMethod() {} 139 140 OatMethod& operator=(const OatMethod&) = default; 141 142 // A representation of an invalid OatMethod, used when an OatMethod or OatClass can't be found. 143 // See ClassLinker::FindOatMethodFor. Invalid()144 static const OatMethod Invalid() { 145 return OatMethod(nullptr, -1); 146 } 147 148 private: 149 template<class T> GetOatPointer(uint32_t offset)150 T GetOatPointer(uint32_t offset) const { 151 if (offset == 0) { 152 return nullptr; 153 } 154 return reinterpret_cast<T>(begin_ + offset); 155 } 156 157 const uint8_t* begin_; 158 uint32_t code_offset_; 159 160 friend class OatClass; 161 }; 162 163 class OatClass FINAL { 164 public: GetStatus()165 mirror::Class::Status GetStatus() const { 166 return status_; 167 } 168 GetType()169 OatClassType GetType() const { 170 return type_; 171 } 172 173 // Get the OatMethod entry based on its index into the class 174 // defintion. Direct methods come first, followed by virtual 175 // methods. Note that runtime created methods such as miranda 176 // methods are not included. 177 const OatMethod GetOatMethod(uint32_t method_index) const; 178 179 // Return a pointer to the OatMethodOffsets for the requested 180 // method_index, or null if none is present. Note that most 181 // callers should use GetOatMethod. 182 const OatMethodOffsets* GetOatMethodOffsets(uint32_t method_index) const; 183 184 // Return the offset from the start of the OatFile to the 185 // OatMethodOffsets for the requested method_index, or 0 if none 186 // is present. Note that most callers should use GetOatMethod. 187 uint32_t GetOatMethodOffsetsOffset(uint32_t method_index) const; 188 189 // A representation of an invalid OatClass, used when an OatClass can't be found. 190 // See ClassLinker::FindOatClass. Invalid()191 static OatClass Invalid() { 192 return OatClass(nullptr, mirror::Class::kStatusError, kOatClassNoneCompiled, 0, nullptr, 193 nullptr); 194 } 195 196 private: 197 OatClass(const OatFile* oat_file, 198 mirror::Class::Status status, 199 OatClassType type, 200 uint32_t bitmap_size, 201 const uint32_t* bitmap_pointer, 202 const OatMethodOffsets* methods_pointer); 203 204 const OatFile* const oat_file_; 205 206 const mirror::Class::Status status_; 207 208 const OatClassType type_; 209 210 const uint32_t* const bitmap_; 211 212 const OatMethodOffsets* const methods_pointer_; 213 214 friend class art::OatDexFile; 215 }; 216 const OatDexFile* GetOatDexFile(const char* dex_location, 217 const uint32_t* const dex_location_checksum, 218 bool exception_if_not_found = true) const 219 REQUIRES(!secondary_lookup_lock_); 220 GetOatDexFiles()221 const std::vector<const OatDexFile*>& GetOatDexFiles() const { 222 return oat_dex_files_storage_; 223 } 224 Size()225 size_t Size() const { 226 return End() - Begin(); 227 } 228 Contains(const void * p)229 bool Contains(const void* p) const { 230 return p >= Begin() && p < End(); 231 } 232 BssSize()233 size_t BssSize() const { 234 return BssEnd() - BssBegin(); 235 } 236 237 const uint8_t* Begin() const; 238 const uint8_t* End() const; 239 240 const uint8_t* BssBegin() const; 241 const uint8_t* BssEnd() const; 242 243 // Returns the absolute dex location for the encoded relative dex location. 244 // 245 // If not null, abs_dex_location is used to resolve the absolute dex 246 // location of relative dex locations encoded in the oat file. 247 // For example, given absolute location "/data/app/foo/base.apk", encoded 248 // dex locations "base.apk", "base.apk:classes2.dex", etc. would be resolved 249 // to "/data/app/foo/base.apk", "/data/app/foo/base.apk:classes2.dex", etc. 250 // Relative encoded dex locations that don't match the given abs_dex_location 251 // are left unchanged. 252 static std::string ResolveRelativeEncodedDexLocation( 253 const char* abs_dex_location, const std::string& rel_dex_location); 254 255 // Create a dependency list (dex locations and checksums) for the given dex files. 256 static std::string EncodeDexFileDependencies(const std::vector<const DexFile*>& dex_files); 257 258 // Check the given dependency list against their dex files - thus the name "Static," this does 259 // not check the class-loader environment, only whether there have been file updates. 260 static bool CheckStaticDexFileDependencies(const char* dex_dependencies, std::string* msg); 261 262 // Get the dex locations of a dependency list. Note: this is *not* cleaned for synthetic 263 // locations of multidex files. 264 static bool GetDexLocationsFromDependencies(const char* dex_dependencies, 265 std::vector<std::string>* locations); 266 267 protected: 268 OatFile(const std::string& filename, bool executable); 269 270 private: 271 // The oat file name. 272 // 273 // The image will embed this to link its associated oat file. 274 const std::string location_; 275 276 // Pointer to OatHeader. 277 const uint8_t* begin_; 278 279 // Pointer to end of oat region for bounds checking. 280 const uint8_t* end_; 281 282 // Pointer to the .bss section, if present, otherwise null. 283 uint8_t* bss_begin_; 284 285 // Pointer to the end of the .bss section, if present, otherwise null. 286 uint8_t* bss_end_; 287 288 // Was this oat_file loaded executable? 289 const bool is_executable_; 290 291 // Owning storage for the OatDexFile objects. 292 std::vector<const OatDexFile*> oat_dex_files_storage_; 293 294 // NOTE: We use a StringPiece as the key type to avoid a memory allocation on every 295 // lookup with a const char* key. The StringPiece doesn't own its backing storage, 296 // therefore we're using the OatDexFile::dex_file_location_ as the backing storage 297 // for keys in oat_dex_files_ and the string_cache_ entries for the backing storage 298 // of keys in secondary_oat_dex_files_ and oat_dex_files_by_canonical_location_. 299 typedef AllocationTrackingSafeMap<StringPiece, const OatDexFile*, kAllocatorTagOatFile> Table; 300 301 // Map each location and canonical location (if different) retrieved from the 302 // oat file to its OatDexFile. This map doesn't change after it's constructed in Setup() 303 // and therefore doesn't need any locking and provides the cheapest dex file lookup 304 // for GetOatDexFile() for a very frequent use case. Never contains a null value. 305 Table oat_dex_files_; 306 307 // Lock guarding all members needed for secondary lookup in GetOatDexFile(). 308 mutable Mutex secondary_lookup_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; 309 310 // If the primary oat_dex_files_ lookup fails, use a secondary map. This map stores 311 // the results of all previous secondary lookups, whether successful (non-null) or 312 // failed (null). If it doesn't contain an entry we need to calculate the canonical 313 // location and use oat_dex_files_by_canonical_location_. 314 mutable Table secondary_oat_dex_files_ GUARDED_BY(secondary_lookup_lock_); 315 316 // Cache of strings. Contains the backing storage for keys in the secondary_oat_dex_files_ 317 // and the lazily initialized oat_dex_files_by_canonical_location_. 318 // NOTE: We're keeping references to contained strings in form of StringPiece and adding 319 // new strings to the end. The adding of a new element must not touch any previously stored 320 // elements. std::list<> and std::deque<> satisfy this requirement, std::vector<> doesn't. 321 mutable std::list<std::string> string_cache_ GUARDED_BY(secondary_lookup_lock_); 322 323 friend class gc::collector::DummyOatFile; // For modifying begin_ and end_. 324 friend class OatClass; 325 friend class art::OatDexFile; 326 friend class OatDumper; // For GetBase and GetLimit 327 friend class OatFileBase; 328 DISALLOW_COPY_AND_ASSIGN(OatFile); 329 }; 330 331 // OatDexFile should be an inner class of OatFile. Unfortunately, C++ doesn't 332 // support forward declarations of inner classes, and we want to 333 // forward-declare OatDexFile so that we can store an opaque pointer to an 334 // OatDexFile in DexFile. 335 class OatDexFile FINAL { 336 public: 337 // Opens the DexFile referred to by this OatDexFile from within the containing OatFile. 338 std::unique_ptr<const DexFile> OpenDexFile(std::string* error_msg) const; 339 GetOatFile()340 const OatFile* GetOatFile() const { 341 return oat_file_; 342 } 343 344 // Returns the size of the DexFile refered to by this OatDexFile. 345 size_t FileSize() const; 346 347 // Returns original path of DexFile that was the source of this OatDexFile. GetDexFileLocation()348 const std::string& GetDexFileLocation() const { 349 return dex_file_location_; 350 } 351 352 // Returns the canonical location of DexFile that was the source of this OatDexFile. GetCanonicalDexFileLocation()353 const std::string& GetCanonicalDexFileLocation() const { 354 return canonical_dex_file_location_; 355 } 356 357 // Returns checksum of original DexFile that was the source of this OatDexFile; GetDexFileLocationChecksum()358 uint32_t GetDexFileLocationChecksum() const { 359 return dex_file_location_checksum_; 360 } 361 362 // Returns the OatClass for the class specified by the given DexFile class_def_index. 363 OatFile::OatClass GetOatClass(uint16_t class_def_index) const; 364 365 // Returns the offset to the OatClass information. Most callers should use GetOatClass. 366 uint32_t GetOatClassOffset(uint16_t class_def_index) const; 367 GetDexCacheArrays()368 uint8_t* GetDexCacheArrays() const { 369 return dex_cache_arrays_; 370 } 371 GetLookupTableData()372 const uint8_t* GetLookupTableData() const { 373 return lookup_table_data_; 374 } 375 GetDexFilePointer()376 const uint8_t* GetDexFilePointer() const { 377 return dex_file_pointer_; 378 } 379 380 ~OatDexFile(); 381 382 private: 383 OatDexFile(const OatFile* oat_file, 384 const std::string& dex_file_location, 385 const std::string& canonical_dex_file_location, 386 uint32_t dex_file_checksum, 387 const uint8_t* dex_file_pointer, 388 const uint8_t* lookup_table_data, 389 const uint32_t* oat_class_offsets_pointer, 390 uint8_t* dex_cache_arrays); 391 392 const OatFile* const oat_file_; 393 const std::string dex_file_location_; 394 const std::string canonical_dex_file_location_; 395 const uint32_t dex_file_location_checksum_; 396 const uint8_t* const dex_file_pointer_; 397 const uint8_t* lookup_table_data_; 398 const uint32_t* const oat_class_offsets_pointer_; 399 uint8_t* const dex_cache_arrays_; 400 401 friend class OatFile; 402 friend class OatFileBase; 403 DISALLOW_COPY_AND_ASSIGN(OatDexFile); 404 }; 405 406 } // namespace art 407 408 #endif // ART_RUNTIME_OAT_FILE_H_ 409