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