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