oat_file.h revision fbef44de596d298dc6430f482dffc933a046dd28
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 33namespace art { 34 35class BitVector; 36class ElfFile; 37class MemMap; 38class OatMethodOffsets; 39class OatHeader; 40 41class 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 uint8_t* 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 72 bool IsExecutable() const { 73 return is_executable_; 74 } 75 76 bool IsPic() const; 77 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 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 96 uint32_t GetCodeOffset() const { 97 return code_offset_; 98 } 99 100 const void* GetQuickCode() const { 101 return GetOatPointer<const void*>(code_offset_); 102 } 103 104 // Returns size of quick code. 105 uint32_t GetQuickCodeSize() const; 106 uint32_t GetQuickCodeSizeOffset() const; 107 108 // Returns OatQuickMethodHeader for debugging. Most callers should 109 // use more specific methods such as GetQuickCodeSize. 110 const OatQuickMethodHeader* GetOatQuickMethodHeader() const; 111 uint32_t GetOatQuickMethodHeaderOffset() const; 112 113 size_t GetFrameSizeInBytes() const; 114 uint32_t GetCoreSpillMask() const; 115 uint32_t GetFpSpillMask() const; 116 117 const uint8_t* GetMappingTable() const; 118 uint32_t GetMappingTableOffset() const; 119 uint32_t GetMappingTableOffsetOffset() const; 120 121 const uint8_t* GetVmapTable() const; 122 uint32_t GetVmapTableOffset() const; 123 uint32_t GetVmapTableOffsetOffset() const; 124 125 const uint8_t* GetGcMap() const; 126 uint32_t GetGcMapOffset() const; 127 uint32_t GetGcMapOffsetOffset() const; 128 129 // Create an OatMethod with offsets relative to the given base address 130 OatMethod(const uint8_t* base, const uint32_t code_offset) 131 : begin_(base), code_offset_(code_offset) { 132 } 133 ~OatMethod() {} 134 135 // A representation of an invalid OatMethod, used when an OatMethod or OatClass can't be found. 136 // See ClassLinker::FindOatMethodFor. 137 static const OatMethod Invalid() { 138 return OatMethod(nullptr, -1); 139 } 140 141 private: 142 template<class T> 143 T GetOatPointer(uint32_t offset) const { 144 if (offset == 0) { 145 return NULL; 146 } 147 return reinterpret_cast<T>(begin_ + offset); 148 } 149 150 const uint8_t* const begin_; 151 const uint32_t code_offset_; 152 153 friend class OatClass; 154 }; 155 156 class OatClass { 157 public: 158 mirror::Class::Status GetStatus() const { 159 return status_; 160 } 161 162 OatClassType GetType() const { 163 return type_; 164 } 165 166 // Get the OatMethod entry based on its index into the class 167 // defintion. Direct methods come first, followed by virtual 168 // methods. Note that runtime created methods such as miranda 169 // methods are not included. 170 const OatMethod GetOatMethod(uint32_t method_index) const; 171 172 // Return a pointer to the OatMethodOffsets for the requested 173 // method_index, or nullptr if none is present. Note that most 174 // callers should use GetOatMethod. 175 const OatMethodOffsets* GetOatMethodOffsets(uint32_t method_index) const; 176 177 // Return the offset from the start of the OatFile to the 178 // OatMethodOffsets for the requested method_index, or 0 if none 179 // is present. Note that most callers should use GetOatMethod. 180 uint32_t GetOatMethodOffsetsOffset(uint32_t method_index) const; 181 182 // A representation of an invalid OatClass, used when an OatClass can't be found. 183 // See ClassLinker::FindOatClass. 184 static OatClass Invalid() { 185 return OatClass(nullptr, mirror::Class::kStatusError, kOatClassNoneCompiled, 0, nullptr, 186 nullptr); 187 } 188 189 private: 190 OatClass(const OatFile* oat_file, 191 mirror::Class::Status status, 192 OatClassType type, 193 uint32_t bitmap_size, 194 const uint32_t* bitmap_pointer, 195 const OatMethodOffsets* methods_pointer); 196 197 const OatFile* const oat_file_; 198 199 const mirror::Class::Status status_; 200 201 const OatClassType type_; 202 203 const uint32_t* const bitmap_; 204 205 const OatMethodOffsets* const methods_pointer_; 206 207 friend class OatDexFile; 208 }; 209 210 class OatDexFile { 211 public: 212 // Opens the DexFile referred to by this OatDexFile from within the containing OatFile. 213 std::unique_ptr<const DexFile> OpenDexFile(std::string* error_msg) const; 214 215 const OatFile* GetOatFile() const { 216 return oat_file_; 217 } 218 219 // Returns the size of the DexFile refered to by this OatDexFile. 220 size_t FileSize() const; 221 222 // Returns original path of DexFile that was the source of this OatDexFile. 223 const std::string& GetDexFileLocation() const { 224 return dex_file_location_; 225 } 226 227 // Returns the canonical location of DexFile that was the source of this OatDexFile. 228 const std::string& GetCanonicalDexFileLocation() const { 229 return canonical_dex_file_location_; 230 } 231 232 // Returns checksum of original DexFile that was the source of this OatDexFile; 233 uint32_t GetDexFileLocationChecksum() const { 234 return dex_file_location_checksum_; 235 } 236 237 // Returns the OatClass for the class specified by the given DexFile class_def_index. 238 OatClass GetOatClass(uint16_t class_def_index) const; 239 240 // Returns the offset to the OatClass information. Most callers should use GetOatClass. 241 uint32_t GetOatClassOffset(uint16_t class_def_index) const; 242 243 ~OatDexFile(); 244 245 private: 246 OatDexFile(const OatFile* oat_file, 247 const std::string& dex_file_location, 248 const std::string& canonical_dex_file_location, 249 uint32_t dex_file_checksum, 250 const uint8_t* dex_file_pointer, 251 const uint32_t* oat_class_offsets_pointer); 252 253 const OatFile* const oat_file_; 254 const std::string dex_file_location_; 255 const std::string canonical_dex_file_location_; 256 const uint32_t dex_file_location_checksum_; 257 const uint8_t* const dex_file_pointer_; 258 const uint32_t* const oat_class_offsets_pointer_; 259 260 friend class OatFile; 261 DISALLOW_COPY_AND_ASSIGN(OatDexFile); 262 }; 263 264 const OatDexFile* GetOatDexFile(const char* dex_location, 265 const uint32_t* const dex_location_checksum, 266 bool exception_if_not_found = true) const 267 LOCKS_EXCLUDED(secondary_lookup_lock_); 268 269 const std::vector<const OatDexFile*>& GetOatDexFiles() const { 270 return oat_dex_files_storage_; 271 } 272 273 size_t Size() const { 274 return End() - Begin(); 275 } 276 277 const uint8_t* Begin() const; 278 const uint8_t* End() const; 279 280 private: 281 static void CheckLocation(const std::string& location); 282 283 static OatFile* OpenDlopen(const std::string& elf_filename, 284 const std::string& location, 285 uint8_t* requested_base, 286 std::string* error_msg); 287 288 static OatFile* OpenElfFile(File* file, 289 const std::string& location, 290 uint8_t* requested_base, 291 uint8_t* oat_file_begin, // Override base if not null 292 bool writable, 293 bool executable, 294 std::string* error_msg); 295 296 explicit OatFile(const std::string& filename, bool executable); 297 bool Dlopen(const std::string& elf_filename, uint8_t* requested_base, std::string* error_msg); 298 bool ElfFileOpen(File* file, uint8_t* requested_base, 299 uint8_t* oat_file_begin, // Override where the file is loaded to if not null 300 bool writable, bool executable, 301 std::string* error_msg); 302 bool Setup(std::string* error_msg); 303 304 // The oat file name. 305 // 306 // The image will embed this to link its associated oat file. 307 const std::string location_; 308 309 // Pointer to OatHeader. 310 const uint8_t* begin_; 311 312 // Pointer to end of oat region for bounds checking. 313 const uint8_t* end_; 314 315 // Was this oat_file loaded executable? 316 const bool is_executable_; 317 318 // Backing memory map for oat file during when opened by ElfWriter during initial compilation. 319 std::unique_ptr<MemMap> mem_map_; 320 321 // Backing memory map for oat file during cross compilation. 322 std::unique_ptr<ElfFile> elf_file_; 323 324 // dlopen handle during runtime. 325 void* dlopen_handle_; 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 nullptr 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 OatDexFile; 361 friend class OatDumper; // For GetBase and GetLimit 362 DISALLOW_COPY_AND_ASSIGN(OatFile); 363}; 364 365} // namespace art 366 367#endif // ART_RUNTIME_OAT_FILE_H_ 368