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 bool executable, 53 std::string* error_msg); 54 55 // Open an oat file from an already opened File. 56 // Does not use dlopen underneath so cannot be used for runtime use 57 // where relocations may be required. Currently used from 58 // ImageWriter which wants to open a writable version from an existing 59 // file descriptor for patching. 60 static OatFile* OpenWritable(File* file, const std::string& location, std::string* error_msg); 61 // Opens an oat file from an already opened File. Maps it PROT_READ, MAP_PRIVATE. 62 static OatFile* OpenReadable(File* file, const std::string& location, std::string* error_msg); 63 64 // Open an oat file backed by a std::vector with the given location. 65 static OatFile* OpenMemory(std::vector<uint8_t>& oat_contents, 66 const std::string& location, 67 std::string* error_msg); 68 69 ~OatFile(); 70 71 bool IsExecutable() const { 72 return is_executable_; 73 } 74 75 ElfFile* GetElfFile() const { 76 CHECK_NE(reinterpret_cast<uintptr_t>(elf_file_.get()), reinterpret_cast<uintptr_t>(nullptr)) 77 << "Cannot get an elf file from " << GetLocation(); 78 return elf_file_.get(); 79 } 80 81 const std::string& GetLocation() const { 82 return location_; 83 } 84 85 const OatHeader& GetOatHeader() const; 86 87 class OatDexFile; 88 89 class OatMethod { 90 public: 91 void LinkMethod(mirror::ArtMethod* method) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 92 93 uint32_t GetCodeOffset() const { 94 return code_offset_; 95 } 96 uint32_t GetNativeGcMapOffset() const { 97 return native_gc_map_offset_; 98 } 99 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 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. 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 const uint8_t* GetNativeGcMap() const { 135 return GetOatPointer<const uint8_t*>(native_gc_map_offset_); 136 } 137 138 size_t GetFrameSizeInBytes() const; 139 uint32_t GetCoreSpillMask() const; 140 uint32_t GetFpSpillMask() const; 141 142 const uint8_t* GetMappingTable() const; 143 uint32_t GetMappingTableOffset() const; 144 uint32_t GetMappingTableOffsetOffset() const; 145 146 const uint8_t* GetVmapTable() const; 147 uint32_t GetVmapTableOffset() const; 148 uint32_t GetVmapTableOffsetOffset() const; 149 150 ~OatMethod(); 151 152 // Create an OatMethod with offsets relative to the given base address 153 OatMethod(const byte* base, 154 const uint32_t code_offset, 155 const uint32_t gc_map_offset); 156 157 OatMethod() {} 158 159 private: 160 template<class T> 161 T GetOatPointer(uint32_t offset) const { 162 if (offset == 0) { 163 return NULL; 164 } 165 return reinterpret_cast<T>(begin_ + offset); 166 } 167 168 const byte* begin_; 169 170 uint32_t code_offset_; 171 uint32_t native_gc_map_offset_; 172 173 friend class OatClass; 174 }; 175 176 class OatClass { 177 public: 178 mirror::Class::Status GetStatus() const { 179 return status_; 180 } 181 182 OatClassType GetType() const { 183 return type_; 184 } 185 186 // Get the OatMethod entry based on its index into the class 187 // defintion. Direct methods come first, followed by virtual 188 // methods. Note that runtime created methods such as miranda 189 // methods are not included. 190 const OatMethod GetOatMethod(uint32_t method_index) const; 191 192 // Return a pointer to the OatMethodOffsets for the requested 193 // method_index, or nullptr if none is present. Note that most 194 // callers should use GetOatMethod. 195 const OatMethodOffsets* GetOatMethodOffsets(uint32_t method_index) const; 196 197 // Return the offset from the start of the OatFile to the 198 // OatMethodOffsets for the requested method_index, or 0 if none 199 // is present. Note that most callers should use GetOatMethod. 200 uint32_t GetOatMethodOffsetsOffset(uint32_t method_index) const; 201 202 OatClass() {} 203 204 private: 205 OatClass(const OatFile* oat_file, 206 mirror::Class::Status status, 207 OatClassType type, 208 uint32_t bitmap_size, 209 const uint32_t* bitmap_pointer, 210 const OatMethodOffsets* methods_pointer); 211 212 const OatFile* oat_file_; 213 214 mirror::Class::Status status_; 215 216 OatClassType type_; 217 218 const uint32_t* bitmap_; 219 220 const OatMethodOffsets* methods_pointer_; 221 222 friend class OatDexFile; 223 }; 224 225 class OatDexFile { 226 public: 227 // Opens the DexFile referred to by this OatDexFile from within the containing OatFile. 228 const DexFile* OpenDexFile(std::string* error_msg) const; 229 230 const OatFile* GetOatFile() const { 231 return oat_file_; 232 } 233 234 // Returns the size of the DexFile refered to by this OatDexFile. 235 size_t FileSize() const; 236 237 // Returns original path of DexFile that was the source of this OatDexFile. 238 const std::string& GetDexFileLocation() const { 239 return dex_file_location_; 240 } 241 242 // Returns the canonical location of DexFile that was the source of this OatDexFile. 243 const std::string& GetCanonicalDexFileLocation() const { 244 return canonical_dex_file_location_; 245 } 246 247 // Returns checksum of original DexFile that was the source of this OatDexFile; 248 uint32_t GetDexFileLocationChecksum() const { 249 return dex_file_location_checksum_; 250 } 251 252 // Returns the OatClass for the class specified by the given DexFile class_def_index. 253 OatClass GetOatClass(uint16_t class_def_index) const; 254 255 // Returns the offset to the OatClass information. Most callers should use GetOatClass. 256 uint32_t GetOatClassOffset(uint16_t class_def_index) const; 257 258 ~OatDexFile(); 259 260 private: 261 OatDexFile(const OatFile* oat_file, 262 const std::string& dex_file_location, 263 const std::string& canonical_dex_file_location, 264 uint32_t dex_file_checksum, 265 const byte* dex_file_pointer, 266 const uint32_t* oat_class_offsets_pointer); 267 268 const OatFile* const oat_file_; 269 const std::string dex_file_location_; 270 const std::string canonical_dex_file_location_; 271 const uint32_t dex_file_location_checksum_; 272 const byte* const dex_file_pointer_; 273 const uint32_t* const oat_class_offsets_pointer_; 274 275 friend class OatFile; 276 DISALLOW_COPY_AND_ASSIGN(OatDexFile); 277 }; 278 279 const OatDexFile* GetOatDexFile(const char* dex_location, 280 const uint32_t* const dex_location_checksum, 281 bool exception_if_not_found = true) const 282 LOCKS_EXCLUDED(secondary_lookup_lock_); 283 284 const std::vector<const OatDexFile*>& GetOatDexFiles() const { 285 return oat_dex_files_storage_; 286 } 287 288 size_t Size() const { 289 return End() - Begin(); 290 } 291 292 const byte* Begin() const; 293 const byte* End() const; 294 295 private: 296 static void CheckLocation(const std::string& location); 297 298 static OatFile* OpenDlopen(const std::string& elf_filename, 299 const std::string& location, 300 byte* requested_base, 301 std::string* error_msg); 302 303 static OatFile* OpenElfFile(File* file, 304 const std::string& location, 305 byte* requested_base, 306 bool writable, 307 bool executable, 308 std::string* error_msg); 309 310 explicit OatFile(const std::string& filename, bool executable); 311 bool Dlopen(const std::string& elf_filename, byte* requested_base, std::string* error_msg); 312 bool ElfFileOpen(File* file, byte* requested_base, 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