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