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