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