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