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 41 class OatFile { 42 public: 43 // Opens an oat file contained within the given elf file. This is always opened as 44 // non-executable at the moment. 45 static OatFile* OpenWithElfFile(ElfFile* elf_file, const std::string& location, 46 std::string* error_msg); 47 // Open an oat file. Returns NULL on failure. Requested base can 48 // optionally be used to request where the file should be loaded. 49 static OatFile* Open(const std::string& filename, 50 const std::string& location, 51 byte* requested_base, 52 uint8_t* oat_file_begin, 53 bool executable, 54 std::string* error_msg); 55 56 // Open an oat file from an already opened File. 57 // Does not use dlopen underneath so cannot be used for runtime use 58 // where relocations may be required. Currently used from 59 // ImageWriter which wants to open a writable version from an existing 60 // file descriptor for patching. 61 static OatFile* OpenWritable(File* file, const std::string& location, std::string* error_msg); 62 // Opens an oat file from an already opened File. Maps it PROT_READ, MAP_PRIVATE. 63 static OatFile* OpenReadable(File* file, const std::string& location, std::string* error_msg); 64 65 // Open an oat file backed by a std::vector with the given location. 66 static OatFile* OpenMemory(std::vector<uint8_t>& oat_contents, 67 const std::string& location, 68 std::string* error_msg); 69 70 ~OatFile(); 71 IsExecutable()72 bool IsExecutable() const { 73 return is_executable_; 74 } 75 76 bool IsPic() const; 77 GetElfFile()78 ElfFile* GetElfFile() const { 79 CHECK_NE(reinterpret_cast<uintptr_t>(elf_file_.get()), reinterpret_cast<uintptr_t>(nullptr)) 80 << "Cannot get an elf file from " << GetLocation(); 81 return elf_file_.get(); 82 } 83 GetLocation()84 const std::string& GetLocation() const { 85 return location_; 86 } 87 88 const OatHeader& GetOatHeader() const; 89 90 class OatDexFile; 91 92 class OatMethod { 93 public: 94 void LinkMethod(mirror::ArtMethod* method) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 95 GetCodeOffset()96 uint32_t GetCodeOffset() const { 97 return code_offset_; 98 } 99 GetPortableCode()100 const void* GetPortableCode() const { 101 // TODO: encode whether code is portable/quick in flags within OatMethod. 102 if (kUsePortableCompiler) { 103 return GetOatPointer<const void*>(code_offset_); 104 } else { 105 return nullptr; 106 } 107 } 108 GetQuickCode()109 const void* GetQuickCode() const { 110 if (kUsePortableCompiler) { 111 return nullptr; 112 } else { 113 return GetOatPointer<const void*>(code_offset_); 114 } 115 } 116 117 // Returns 0. GetPortableCodeSize()118 uint32_t GetPortableCodeSize() const { 119 // TODO: With Quick, we store the size before the code. With Portable, the code is in a .o 120 // file we don't manage ourselves. ELF symbols do have a concept of size, so we could capture 121 // that and store it somewhere, such as the OatMethod. 122 return 0; 123 } 124 125 // Returns size of quick code. 126 uint32_t GetQuickCodeSize() const; 127 uint32_t GetQuickCodeSizeOffset() const; 128 129 // Returns OatQuickMethodHeader for debugging. Most callers should 130 // use more specific methods such as GetQuickCodeSize. 131 const OatQuickMethodHeader* GetOatQuickMethodHeader() const; 132 uint32_t GetOatQuickMethodHeaderOffset() const; 133 134 size_t GetFrameSizeInBytes() const; 135 uint32_t GetCoreSpillMask() const; 136 uint32_t GetFpSpillMask() const; 137 138 const uint8_t* GetMappingTable() const; 139 uint32_t GetMappingTableOffset() const; 140 uint32_t GetMappingTableOffsetOffset() const; 141 142 const uint8_t* GetVmapTable() const; 143 uint32_t GetVmapTableOffset() const; 144 uint32_t GetVmapTableOffsetOffset() const; 145 146 const uint8_t* GetGcMap() const; 147 uint32_t GetGcMapOffset() const; 148 uint32_t GetGcMapOffsetOffset() const; 149 150 ~OatMethod(); 151 152 // Create an OatMethod with offsets relative to the given base address 153 OatMethod(const byte* base, const uint32_t code_offset); 154 OatMethod()155 OatMethod() {} 156 157 private: 158 template<class T> GetOatPointer(uint32_t offset)159 T GetOatPointer(uint32_t offset) const { 160 if (offset == 0) { 161 return NULL; 162 } 163 return reinterpret_cast<T>(begin_ + offset); 164 } 165 166 const byte* begin_; 167 168 uint32_t code_offset_; 169 170 friend class OatClass; 171 }; 172 173 class OatClass { 174 public: GetStatus()175 mirror::Class::Status GetStatus() const { 176 return status_; 177 } 178 GetType()179 OatClassType GetType() const { 180 return type_; 181 } 182 183 // Get the OatMethod entry based on its index into the class 184 // defintion. Direct methods come first, followed by virtual 185 // methods. Note that runtime created methods such as miranda 186 // methods are not included. 187 const OatMethod GetOatMethod(uint32_t method_index) const; 188 189 // Return a pointer to the OatMethodOffsets for the requested 190 // method_index, or nullptr if none is present. Note that most 191 // callers should use GetOatMethod. 192 const OatMethodOffsets* GetOatMethodOffsets(uint32_t method_index) const; 193 194 // Return the offset from the start of the OatFile to the 195 // OatMethodOffsets for the requested method_index, or 0 if none 196 // is present. Note that most callers should use GetOatMethod. 197 uint32_t GetOatMethodOffsetsOffset(uint32_t method_index) const; 198 OatClass()199 OatClass() {} 200 201 private: 202 OatClass(const OatFile* oat_file, 203 mirror::Class::Status status, 204 OatClassType type, 205 uint32_t bitmap_size, 206 const uint32_t* bitmap_pointer, 207 const OatMethodOffsets* methods_pointer); 208 209 const OatFile* oat_file_; 210 211 mirror::Class::Status status_; 212 213 OatClassType type_; 214 215 const uint32_t* bitmap_; 216 217 const OatMethodOffsets* methods_pointer_; 218 219 friend class OatDexFile; 220 }; 221 222 class OatDexFile { 223 public: 224 // Opens the DexFile referred to by this OatDexFile from within the containing OatFile. 225 const DexFile* OpenDexFile(std::string* error_msg) const; 226 GetOatFile()227 const OatFile* GetOatFile() const { 228 return oat_file_; 229 } 230 231 // Returns the size of the DexFile refered to by this OatDexFile. 232 size_t FileSize() const; 233 234 // Returns original path of DexFile that was the source of this OatDexFile. GetDexFileLocation()235 const std::string& GetDexFileLocation() const { 236 return dex_file_location_; 237 } 238 239 // Returns the canonical location of DexFile that was the source of this OatDexFile. GetCanonicalDexFileLocation()240 const std::string& GetCanonicalDexFileLocation() const { 241 return canonical_dex_file_location_; 242 } 243 244 // Returns checksum of original DexFile that was the source of this OatDexFile; GetDexFileLocationChecksum()245 uint32_t GetDexFileLocationChecksum() const { 246 return dex_file_location_checksum_; 247 } 248 249 // Returns the OatClass for the class specified by the given DexFile class_def_index. 250 OatClass GetOatClass(uint16_t class_def_index) const; 251 252 // Returns the offset to the OatClass information. Most callers should use GetOatClass. 253 uint32_t GetOatClassOffset(uint16_t class_def_index) const; 254 255 ~OatDexFile(); 256 257 private: 258 OatDexFile(const OatFile* oat_file, 259 const std::string& dex_file_location, 260 const std::string& canonical_dex_file_location, 261 uint32_t dex_file_checksum, 262 const byte* dex_file_pointer, 263 const uint32_t* oat_class_offsets_pointer); 264 265 const OatFile* const oat_file_; 266 const std::string dex_file_location_; 267 const std::string canonical_dex_file_location_; 268 const uint32_t dex_file_location_checksum_; 269 const byte* const dex_file_pointer_; 270 const uint32_t* const oat_class_offsets_pointer_; 271 272 friend class OatFile; 273 DISALLOW_COPY_AND_ASSIGN(OatDexFile); 274 }; 275 276 const OatDexFile* GetOatDexFile(const char* dex_location, 277 const uint32_t* const dex_location_checksum, 278 bool exception_if_not_found = true) const 279 LOCKS_EXCLUDED(secondary_lookup_lock_); 280 GetOatDexFiles()281 const std::vector<const OatDexFile*>& GetOatDexFiles() const { 282 return oat_dex_files_storage_; 283 } 284 Size()285 size_t Size() const { 286 return End() - Begin(); 287 } 288 289 const byte* Begin() const; 290 const byte* End() const; 291 292 private: 293 static void CheckLocation(const std::string& location); 294 295 static OatFile* OpenDlopen(const std::string& elf_filename, 296 const std::string& location, 297 byte* requested_base, 298 std::string* error_msg); 299 300 static OatFile* OpenElfFile(File* file, 301 const std::string& location, 302 byte* requested_base, 303 uint8_t* oat_file_begin, // Override base if not null 304 bool writable, 305 bool executable, 306 std::string* error_msg); 307 308 explicit OatFile(const std::string& filename, bool executable); 309 bool Dlopen(const std::string& elf_filename, byte* requested_base, std::string* error_msg); 310 bool ElfFileOpen(File* file, byte* requested_base, 311 uint8_t* oat_file_begin, // Override where the file is loaded to if not null 312 bool writable, bool executable, 313 std::string* error_msg); 314 bool Setup(std::string* error_msg); 315 316 // The oat file name. 317 // 318 // The image will embed this to link its associated oat file. 319 const std::string location_; 320 321 // Pointer to OatHeader. 322 const byte* begin_; 323 324 // Pointer to end of oat region for bounds checking. 325 const byte* end_; 326 327 // Was this oat_file loaded executable? 328 const bool is_executable_; 329 330 // Backing memory map for oat file during when opened by ElfWriter during initial compilation. 331 std::unique_ptr<MemMap> mem_map_; 332 333 // Backing memory map for oat file during cross compilation. 334 std::unique_ptr<ElfFile> elf_file_; 335 336 // dlopen handle during runtime. 337 void* dlopen_handle_; 338 339 // Owning storage for the OatDexFile objects. 340 std::vector<const OatDexFile*> oat_dex_files_storage_; 341 342 // NOTE: We use a StringPiece as the key type to avoid a memory allocation on every 343 // lookup with a const char* key. The StringPiece doesn't own its backing storage, 344 // therefore we're using the OatDexFile::dex_file_location_ as the backing storage 345 // for keys in oat_dex_files_ and the string_cache_ entries for the backing storage 346 // of keys in secondary_oat_dex_files_ and oat_dex_files_by_canonical_location_. 347 typedef AllocationTrackingSafeMap<StringPiece, const OatDexFile*, kAllocatorTagOatFile> Table; 348 349 // Map each location and canonical location (if different) retrieved from the 350 // oat file to its OatDexFile. This map doesn't change after it's constructed in Setup() 351 // and therefore doesn't need any locking and provides the cheapest dex file lookup 352 // for GetOatDexFile() for a very frequent use case. Never contains a nullptr value. 353 Table oat_dex_files_; 354 355 // Lock guarding all members needed for secondary lookup in GetOatDexFile(). 356 mutable Mutex secondary_lookup_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; 357 358 // If the primary oat_dex_files_ lookup fails, use a secondary map. This map stores 359 // the results of all previous secondary lookups, whether successful (non-null) or 360 // failed (null). If it doesn't contain an entry we need to calculate the canonical 361 // location and use oat_dex_files_by_canonical_location_. 362 mutable Table secondary_oat_dex_files_ GUARDED_BY(secondary_lookup_lock_); 363 364 // Cache of strings. Contains the backing storage for keys in the secondary_oat_dex_files_ 365 // and the lazily initialized oat_dex_files_by_canonical_location_. 366 // NOTE: We're keeping references to contained strings in form of StringPiece and adding 367 // new strings to the end. The adding of a new element must not touch any previously stored 368 // elements. std::list<> and std::deque<> satisfy this requirement, std::vector<> doesn't. 369 mutable std::list<std::string> string_cache_ GUARDED_BY(secondary_lookup_lock_); 370 371 friend class OatClass; 372 friend class OatDexFile; 373 friend class OatDumper; // For GetBase and GetLimit 374 DISALLOW_COPY_AND_ASSIGN(OatFile); 375 }; 376 377 } // namespace art 378 379 #endif // ART_RUNTIME_OAT_FILE_H_ 380