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