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