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/array_ref.h" 25 #include "base/mutex.h" 26 #include "base/os.h" 27 #include "base/safe_map.h" 28 #include "base/stringpiece.h" 29 #include "base/tracking_safe_map.h" 30 #include "base/utils.h" 31 #include "class_status.h" 32 #include "compiler_filter.h" 33 #include "dex/dex_file.h" 34 #include "dex/dex_file_layout.h" 35 #include "dex/utf.h" 36 #include "index_bss_mapping.h" 37 #include "mirror/object.h" 38 #include "oat.h" 39 #include "type_lookup_table.h" 40 41 namespace art { 42 43 class BitVector; 44 class ElfFile; 45 class DexLayoutSections; 46 template <class MirrorType> class GcRoot; 47 class MemMap; 48 class OatDexFile; 49 class OatHeader; 50 class OatMethodOffsets; 51 class OatQuickMethodHeader; 52 class VdexFile; 53 54 namespace gc { 55 namespace collector { 56 class DummyOatFile; 57 } // namespace collector 58 } // namespace gc 59 60 // Runtime representation of the OAT file format which holds compiler output. 61 // The class opens an OAT file from storage and maps it to memory, typically with 62 // dlopen and provides access to its internal data structures (see OatWriter for 63 // for more details about the OAT format). 64 // In the process of loading OAT, the class also loads the associated VDEX file 65 // with the input DEX files (see VdexFile for details about the VDEX format). 66 // The raw DEX data are accessible transparently through the OatDexFile objects. 67 68 class OatFile { 69 public: 70 // Special classpath that skips shared library check. 71 static constexpr const char* kSpecialSharedLibrary = "&"; 72 73 typedef art::OatDexFile OatDexFile; 74 75 // Opens an oat file contained within the given elf file. This is always opened as 76 // non-executable at the moment. 77 static OatFile* OpenWithElfFile(int zip_fd, 78 ElfFile* elf_file, 79 VdexFile* vdex_file, 80 const std::string& location, 81 const char* abs_dex_location, 82 std::string* error_msg); 83 // Open an oat file. Returns null on failure. Requested base can 84 // optionally be used to request where the file should be loaded. 85 // See the ResolveRelativeEncodedDexLocation for a description of how the 86 // abs_dex_location argument is used. 87 static OatFile* Open(int zip_fd, 88 const std::string& filename, 89 const std::string& location, 90 uint8_t* requested_base, 91 uint8_t* oat_file_begin, 92 bool executable, 93 bool low_4gb, 94 const char* abs_dex_location, 95 std::string* error_msg); 96 97 // Similar to OatFile::Open(const std::string...), but accepts input vdex and 98 // odex files as file descriptors. We also take zip_fd in case the vdex does not 99 // contain the dex code, and we need to read it from the zip file. 100 static OatFile* Open(int zip_fd, 101 int vdex_fd, 102 int oat_fd, 103 const std::string& oat_location, 104 uint8_t* requested_base, 105 uint8_t* oat_file_begin, 106 bool executable, 107 bool low_4gb, 108 const char* abs_dex_location, 109 std::string* error_msg); 110 111 // Open an oat file from an already opened File. 112 // Does not use dlopen underneath so cannot be used for runtime use 113 // where relocations may be required. Currently used from 114 // ImageWriter which wants to open a writable version from an existing 115 // file descriptor for patching. 116 static OatFile* OpenWritable(int zip_fd, 117 File* file, 118 const std::string& location, 119 const char* abs_dex_location, 120 std::string* error_msg); 121 // Open an oat file from an already opened File. Maps it PROT_READ, MAP_PRIVATE. 122 static OatFile* OpenReadable(int zip_fd, 123 File* file, 124 const std::string& location, 125 const char* abs_dex_location, 126 std::string* error_msg); 127 128 virtual ~OatFile(); 129 IsExecutable()130 bool IsExecutable() const { 131 return is_executable_; 132 } 133 134 bool IsPic() const; 135 136 // Indicates whether the oat file was compiled with full debugging capability. 137 bool IsDebuggable() const; 138 139 CompilerFilter::Filter GetCompilerFilter() const; 140 141 std::string GetClassLoaderContext() const; 142 143 const char* GetCompilationReason() const; 144 GetLocation()145 const std::string& GetLocation() const { 146 return location_; 147 } 148 149 const OatHeader& GetOatHeader() const; 150 151 class OatMethod FINAL { 152 public: 153 void LinkMethod(ArtMethod* method) const; 154 155 uint32_t GetCodeOffset() const; 156 157 const void* GetQuickCode() const; 158 159 // Returns size of quick code. 160 uint32_t GetQuickCodeSize() const; 161 uint32_t GetQuickCodeSizeOffset() const; 162 163 // Returns OatQuickMethodHeader for debugging. Most callers should 164 // use more specific methods such as GetQuickCodeSize. 165 const OatQuickMethodHeader* GetOatQuickMethodHeader() const; 166 uint32_t GetOatQuickMethodHeaderOffset() const; 167 168 size_t GetFrameSizeInBytes() const; 169 uint32_t GetCoreSpillMask() const; 170 uint32_t GetFpSpillMask() const; 171 172 const uint8_t* GetVmapTable() const; 173 uint32_t GetVmapTableOffset() const; 174 uint32_t GetVmapTableOffsetOffset() const; 175 176 // Create an OatMethod with offsets relative to the given base address OatMethod(const uint8_t * base,const uint32_t code_offset)177 OatMethod(const uint8_t* base, const uint32_t code_offset) 178 : begin_(base), code_offset_(code_offset) { 179 } 180 OatMethod(const OatMethod&) = default; ~OatMethod()181 ~OatMethod() {} 182 183 OatMethod& operator=(const OatMethod&) = default; 184 185 // A representation of an invalid OatMethod, used when an OatMethod or OatClass can't be found. 186 // See ClassLinker::FindOatMethodFor. Invalid()187 static const OatMethod Invalid() { 188 return OatMethod(nullptr, -1); 189 } 190 191 private: 192 template<class T> GetOatPointer(uint32_t offset)193 T GetOatPointer(uint32_t offset) const { 194 if (offset == 0) { 195 return nullptr; 196 } 197 return reinterpret_cast<T>(begin_ + offset); 198 } 199 200 const uint8_t* begin_; 201 uint32_t code_offset_; 202 203 friend class OatClass; 204 }; 205 206 class OatClass FINAL { 207 public: GetStatus()208 ClassStatus GetStatus() const { 209 return status_; 210 } 211 GetType()212 OatClassType GetType() const { 213 return type_; 214 } 215 216 // Get the OatMethod entry based on its index into the class 217 // defintion. Direct methods come first, followed by virtual 218 // methods. Note that runtime created methods such as miranda 219 // methods are not included. 220 const OatMethod GetOatMethod(uint32_t method_index) const; 221 222 // Return a pointer to the OatMethodOffsets for the requested 223 // method_index, or null if none is present. Note that most 224 // callers should use GetOatMethod. 225 const OatMethodOffsets* GetOatMethodOffsets(uint32_t method_index) const; 226 227 // Return the offset from the start of the OatFile to the 228 // OatMethodOffsets for the requested method_index, or 0 if none 229 // is present. Note that most callers should use GetOatMethod. 230 uint32_t GetOatMethodOffsetsOffset(uint32_t method_index) const; 231 232 // A representation of an invalid OatClass, used when an OatClass can't be found. 233 // See FindOatClass(). Invalid()234 static OatClass Invalid() { 235 return OatClass(/* oat_file */ nullptr, 236 ClassStatus::kErrorUnresolved, 237 kOatClassNoneCompiled, 238 /* bitmap_size */ 0, 239 /* bitmap_pointer */ nullptr, 240 /* methods_pointer */ nullptr); 241 } 242 243 private: 244 OatClass(const OatFile* oat_file, 245 ClassStatus status, 246 OatClassType type, 247 uint32_t bitmap_size, 248 const uint32_t* bitmap_pointer, 249 const OatMethodOffsets* methods_pointer); 250 251 const OatFile* const oat_file_; 252 253 const ClassStatus status_; 254 255 const OatClassType type_; 256 257 const uint32_t* const bitmap_; 258 259 const OatMethodOffsets* const methods_pointer_; 260 261 friend class art::OatDexFile; 262 }; 263 264 // Get the OatDexFile for the given dex_location within this oat file. 265 // If dex_location_checksum is non-null, the OatDexFile will only be 266 // returned if it has a matching checksum. 267 // If error_msg is non-null and no OatDexFile is returned, error_msg will 268 // be updated with a description of why no OatDexFile was returned. 269 const OatDexFile* GetOatDexFile(const char* dex_location, 270 const uint32_t* const dex_location_checksum, 271 /*out*/std::string* error_msg = nullptr) const 272 REQUIRES(!secondary_lookup_lock_); 273 GetOatDexFiles()274 const std::vector<const OatDexFile*>& GetOatDexFiles() const { 275 return oat_dex_files_storage_; 276 } 277 Size()278 size_t Size() const { 279 return End() - Begin(); 280 } 281 Contains(const void * p)282 bool Contains(const void* p) const { 283 return p >= Begin() && p < End(); 284 } 285 BssSize()286 size_t BssSize() const { 287 return BssEnd() - BssBegin(); 288 } 289 VdexSize()290 size_t VdexSize() const { 291 return VdexEnd() - VdexBegin(); 292 } 293 BssMethodsOffset()294 size_t BssMethodsOffset() const { 295 // Note: This is used only for symbolizer and needs to return a valid .bss offset. 296 return (bss_methods_ != nullptr) ? bss_methods_ - BssBegin() : BssRootsOffset(); 297 } 298 BssRootsOffset()299 size_t BssRootsOffset() const { 300 // Note: This is used only for symbolizer and needs to return a valid .bss offset. 301 return (bss_roots_ != nullptr) ? bss_roots_ - BssBegin() : BssSize(); 302 } 303 DexSize()304 size_t DexSize() const { 305 return DexEnd() - DexBegin(); 306 } 307 308 const uint8_t* Begin() const; 309 const uint8_t* End() const; 310 311 const uint8_t* BssBegin() const; 312 const uint8_t* BssEnd() const; 313 314 const uint8_t* VdexBegin() const; 315 const uint8_t* VdexEnd() const; 316 317 const uint8_t* DexBegin() const; 318 const uint8_t* DexEnd() const; 319 320 ArrayRef<ArtMethod*> GetBssMethods() const; 321 ArrayRef<GcRoot<mirror::Object>> GetBssGcRoots() const; 322 323 // Returns the absolute dex location for the encoded relative dex location. 324 // 325 // If not null, abs_dex_location is used to resolve the absolute dex 326 // location of relative dex locations encoded in the oat file. 327 // For example, given absolute location "/data/app/foo/base.apk", encoded 328 // dex locations "base.apk", "base.apk!classes2.dex", etc. would be resolved 329 // to "/data/app/foo/base.apk", "/data/app/foo/base.apk!classes2.dex", etc. 330 // Relative encoded dex locations that don't match the given abs_dex_location 331 // are left unchanged. 332 static std::string ResolveRelativeEncodedDexLocation( 333 const char* abs_dex_location, const std::string& rel_dex_location); 334 335 // Finds the associated oat class for a dex_file and descriptor. Returns an invalid OatClass on 336 // error and sets found to false. 337 static OatClass FindOatClass(const DexFile& dex_file, uint16_t class_def_idx, bool* found); 338 GetVdexFile()339 VdexFile* GetVdexFile() const { 340 return vdex_.get(); 341 } 342 343 // Whether the OatFile embeds the Dex code. ContainsDexCode()344 bool ContainsDexCode() const { 345 return uncompressed_dex_files_ == nullptr; 346 } 347 348 protected: 349 OatFile(const std::string& filename, bool executable); 350 351 private: 352 // The oat file name. 353 // 354 // The image will embed this to link its associated oat file. 355 const std::string location_; 356 357 // Pointer to the Vdex file with the Dex files for this Oat file. 358 std::unique_ptr<VdexFile> vdex_; 359 360 // Pointer to OatHeader. 361 const uint8_t* begin_; 362 363 // Pointer to end of oat region for bounds checking. 364 const uint8_t* end_; 365 366 // Pointer to the .bss section, if present, otherwise null. 367 uint8_t* bss_begin_; 368 369 // Pointer to the end of the .bss section, if present, otherwise null. 370 uint8_t* bss_end_; 371 372 // Pointer to the beginning of the ArtMethod*s in .bss section, if present, otherwise null. 373 uint8_t* bss_methods_; 374 375 // Pointer to the beginning of the GC roots in .bss section, if present, otherwise null. 376 uint8_t* bss_roots_; 377 378 // Was this oat_file loaded executable? 379 const bool is_executable_; 380 381 // Pointer to the .vdex section, if present, otherwise null. 382 uint8_t* vdex_begin_; 383 384 // Pointer to the end of the .vdex section, if present, otherwise null. 385 uint8_t* vdex_end_; 386 387 // Owning storage for the OatDexFile objects. 388 std::vector<const OatDexFile*> oat_dex_files_storage_; 389 390 // NOTE: We use a StringPiece as the key type to avoid a memory allocation on every 391 // lookup with a const char* key. The StringPiece doesn't own its backing storage, 392 // therefore we're using the OatDexFile::dex_file_location_ as the backing storage 393 // for keys in oat_dex_files_ and the string_cache_ entries for the backing storage 394 // of keys in secondary_oat_dex_files_ and oat_dex_files_by_canonical_location_. 395 typedef AllocationTrackingSafeMap<StringPiece, const OatDexFile*, kAllocatorTagOatFile> Table; 396 397 // Map each location and canonical location (if different) retrieved from the 398 // oat file to its OatDexFile. This map doesn't change after it's constructed in Setup() 399 // and therefore doesn't need any locking and provides the cheapest dex file lookup 400 // for GetOatDexFile() for a very frequent use case. Never contains a null value. 401 Table oat_dex_files_; 402 403 // Lock guarding all members needed for secondary lookup in GetOatDexFile(). 404 mutable Mutex secondary_lookup_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; 405 406 // If the primary oat_dex_files_ lookup fails, use a secondary map. This map stores 407 // the results of all previous secondary lookups, whether successful (non-null) or 408 // failed (null). If it doesn't contain an entry we need to calculate the canonical 409 // location and use oat_dex_files_by_canonical_location_. 410 mutable Table secondary_oat_dex_files_ GUARDED_BY(secondary_lookup_lock_); 411 412 // Cache of strings. Contains the backing storage for keys in the secondary_oat_dex_files_ 413 // and the lazily initialized oat_dex_files_by_canonical_location_. 414 // NOTE: We're keeping references to contained strings in form of StringPiece and adding 415 // new strings to the end. The adding of a new element must not touch any previously stored 416 // elements. std::list<> and std::deque<> satisfy this requirement, std::vector<> doesn't. 417 mutable std::list<std::string> string_cache_ GUARDED_BY(secondary_lookup_lock_); 418 419 // Cache of dex files mapped directly from a location, in case the OatFile does 420 // not embed the dex code. 421 std::unique_ptr<std::vector<std::unique_ptr<const DexFile>>> uncompressed_dex_files_; 422 423 friend class gc::collector::DummyOatFile; // For modifying begin_ and end_. 424 friend class OatClass; 425 friend class art::OatDexFile; 426 friend class OatDumper; // For GetBase and GetLimit 427 friend class OatFileBase; 428 DISALLOW_COPY_AND_ASSIGN(OatFile); 429 }; 430 431 // OatDexFile should be an inner class of OatFile. Unfortunately, C++ doesn't 432 // support forward declarations of inner classes, and we want to 433 // forward-declare OatDexFile so that we can store an opaque pointer to an 434 // OatDexFile in DexFile. 435 class OatDexFile FINAL { 436 public: 437 // Opens the DexFile referred to by this OatDexFile from within the containing OatFile. 438 std::unique_ptr<const DexFile> OpenDexFile(std::string* error_msg) const; 439 440 // May return null if the OatDexFile only contains a type lookup table. This case only happens 441 // for the compiler to speed up compilation. GetOatFile()442 const OatFile* GetOatFile() const { 443 // Avoid pulling in runtime.h in the header file. 444 if (kIsDebugBuild && oat_file_ == nullptr) { 445 AssertAotCompiler(); 446 } 447 return oat_file_; 448 } 449 450 // Returns the size of the DexFile refered to by this OatDexFile. 451 size_t FileSize() const; 452 453 // Returns original path of DexFile that was the source of this OatDexFile. GetDexFileLocation()454 const std::string& GetDexFileLocation() const { 455 return dex_file_location_; 456 } 457 458 // Returns the canonical location of DexFile that was the source of this OatDexFile. GetCanonicalDexFileLocation()459 const std::string& GetCanonicalDexFileLocation() const { 460 return canonical_dex_file_location_; 461 } 462 463 // Returns checksum of original DexFile that was the source of this OatDexFile; GetDexFileLocationChecksum()464 uint32_t GetDexFileLocationChecksum() const { 465 return dex_file_location_checksum_; 466 } 467 468 // Returns the OatClass for the class specified by the given DexFile class_def_index. 469 OatFile::OatClass GetOatClass(uint16_t class_def_index) const; 470 471 // Returns the offset to the OatClass information. Most callers should use GetOatClass. 472 uint32_t GetOatClassOffset(uint16_t class_def_index) const; 473 GetLookupTableData()474 const uint8_t* GetLookupTableData() const { 475 return lookup_table_data_; 476 } 477 GetMethodBssMapping()478 const IndexBssMapping* GetMethodBssMapping() const { 479 return method_bss_mapping_; 480 } 481 GetTypeBssMapping()482 const IndexBssMapping* GetTypeBssMapping() const { 483 return type_bss_mapping_; 484 } 485 GetStringBssMapping()486 const IndexBssMapping* GetStringBssMapping() const { 487 return string_bss_mapping_; 488 } 489 GetDexFilePointer()490 const uint8_t* GetDexFilePointer() const { 491 return dex_file_pointer_; 492 } 493 494 // Looks up a class definition by its class descriptor. Hash must be 495 // ComputeModifiedUtf8Hash(descriptor). 496 static const DexFile::ClassDef* FindClassDef(const DexFile& dex_file, 497 const char* descriptor, 498 size_t hash); 499 500 // Madvise the dex file based on the state we are moving to. 501 static void MadviseDexFile(const DexFile& dex_file, MadviseState state); 502 GetTypeLookupTable()503 TypeLookupTable* GetTypeLookupTable() const { 504 return lookup_table_.get(); 505 } 506 507 ~OatDexFile(); 508 509 // Create only with a type lookup table, used by the compiler to speed up compilation. 510 explicit OatDexFile(std::unique_ptr<TypeLookupTable>&& lookup_table); 511 512 // Return the dex layout sections. GetDexLayoutSections()513 const DexLayoutSections* GetDexLayoutSections() const { 514 return dex_layout_sections_; 515 } 516 517 private: 518 OatDexFile(const OatFile* oat_file, 519 const std::string& dex_file_location, 520 const std::string& canonical_dex_file_location, 521 uint32_t dex_file_checksum, 522 const uint8_t* dex_file_pointer, 523 const uint8_t* lookup_table_data, 524 const IndexBssMapping* method_bss_mapping, 525 const IndexBssMapping* type_bss_mapping, 526 const IndexBssMapping* string_bss_mapping, 527 const uint32_t* oat_class_offsets_pointer, 528 const DexLayoutSections* dex_layout_sections); 529 530 static void AssertAotCompiler(); 531 532 const OatFile* const oat_file_ = nullptr; 533 const std::string dex_file_location_; 534 const std::string canonical_dex_file_location_; 535 const uint32_t dex_file_location_checksum_ = 0u; 536 const uint8_t* const dex_file_pointer_ = nullptr; 537 const uint8_t* const lookup_table_data_ = nullptr; 538 const IndexBssMapping* const method_bss_mapping_ = nullptr; 539 const IndexBssMapping* const type_bss_mapping_ = nullptr; 540 const IndexBssMapping* const string_bss_mapping_ = nullptr; 541 const uint32_t* const oat_class_offsets_pointer_ = 0u; 542 mutable std::unique_ptr<TypeLookupTable> lookup_table_; 543 const DexLayoutSections* const dex_layout_sections_ = nullptr; 544 545 friend class OatFile; 546 friend class OatFileBase; 547 DISALLOW_COPY_AND_ASSIGN(OatDexFile); 548 }; 549 550 } // namespace art 551 552 #endif // ART_RUNTIME_OAT_FILE_H_ 553