oat_file.h revision 4bb932773e47b1ce04602d81ffa5a8a7d863eb10
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 private: 137 template<class T> 138 T GetOatPointer(uint32_t offset) const { 139 if (offset == 0) { 140 return NULL; 141 } 142 return reinterpret_cast<T>(begin_ + offset); 143 } 144 145 const byte* begin_; 146 147 uint32_t code_offset_; 148 uint32_t native_gc_map_offset_; 149 150 friend class OatClass; 151 }; 152 153 class OatClass { 154 public: 155 mirror::Class::Status GetStatus() const { 156 return status_; 157 } 158 159 OatClassType GetType() const { 160 return type_; 161 } 162 163 // Get the OatMethod entry based on its index into the class 164 // defintion. direct methods come first, followed by virtual 165 // methods. note that runtime created methods such as miranda 166 // methods are not included. 167 const OatMethod GetOatMethod(uint32_t method_index) const; 168 169 private: 170 OatClass(const OatFile* oat_file, 171 mirror::Class::Status status, 172 OatClassType type, 173 uint32_t bitmap_size, 174 const uint32_t* bitmap_pointer, 175 const OatMethodOffsets* methods_pointer); 176 177 const OatFile* const oat_file_; 178 179 const mirror::Class::Status status_; 180 181 const OatClassType type_; 182 183 const uint32_t* const bitmap_; 184 185 const OatMethodOffsets* methods_pointer_; 186 187 friend class OatDexFile; 188 }; 189 190 class OatDexFile { 191 public: 192 // Opens the DexFile referred to by this OatDexFile from within the containing OatFile. 193 const DexFile* OpenDexFile(std::string* error_msg) const; 194 195 // Returns the size of the DexFile refered to by this OatDexFile. 196 size_t FileSize() const; 197 198 // Returns original path of DexFile that was the source of this OatDexFile. 199 const std::string& GetDexFileLocation() const { 200 return dex_file_location_; 201 } 202 203 // Returns checksum of original DexFile that was the source of this OatDexFile; 204 uint32_t GetDexFileLocationChecksum() const { 205 return dex_file_location_checksum_; 206 } 207 208 // Returns the OatClass for the class specified by the given DexFile class_def_index. 209 OatClass GetOatClass(uint16_t class_def_index) const; 210 211 ~OatDexFile(); 212 213 private: 214 OatDexFile(const OatFile* oat_file, 215 const std::string& dex_file_location, 216 uint32_t dex_file_checksum, 217 const byte* dex_file_pointer, 218 const uint32_t* oat_class_offsets_pointer); 219 220 const OatFile* const oat_file_; 221 const std::string dex_file_location_; 222 const uint32_t dex_file_location_checksum_; 223 const byte* const dex_file_pointer_; 224 const uint32_t* const oat_class_offsets_pointer_; 225 226 friend class OatFile; 227 DISALLOW_COPY_AND_ASSIGN(OatDexFile); 228 }; 229 230 const OatDexFile* GetOatDexFile(const char* dex_location, 231 const uint32_t* const dex_location_checksum, 232 bool exception_if_not_found = true) const 233 LOCKS_EXCLUDED(secondary_lookup_lock_); 234 235 std::vector<const OatDexFile*> GetOatDexFiles() const; 236 237 size_t Size() const { 238 return End() - Begin(); 239 } 240 241 const byte* Begin() const; 242 const byte* End() const; 243 244 private: 245 static void CheckLocation(const std::string& location); 246 247 static OatFile* OpenDlopen(const std::string& elf_filename, 248 const std::string& location, 249 byte* requested_base, 250 std::string* error_msg); 251 252 static OatFile* OpenElfFile(File* file, 253 const std::string& location, 254 byte* requested_base, 255 bool writable, 256 bool executable, 257 std::string* error_msg); 258 259 explicit OatFile(const std::string& filename); 260 bool Dlopen(const std::string& elf_filename, byte* requested_base, std::string* error_msg); 261 bool ElfFileOpen(File* file, byte* requested_base, bool writable, bool executable, 262 std::string* error_msg); 263 bool Setup(std::string* error_msg); 264 265 // The oat file name. 266 // 267 // The image will embed this to link its associated oat file. 268 const std::string location_; 269 270 // Pointer to OatHeader. 271 const byte* begin_; 272 273 // Pointer to end of oat region for bounds checking. 274 const byte* end_; 275 276 // Backing memory map for oat file during when opened by ElfWriter during initial compilation. 277 std::unique_ptr<MemMap> mem_map_; 278 279 // Backing memory map for oat file during cross compilation. 280 std::unique_ptr<ElfFile> elf_file_; 281 282 // dlopen handle during runtime. 283 void* dlopen_handle_; 284 285 // NOTE: We use a StringPiece as the key type to avoid a memory allocation on every 286 // lookup with a const char* key. The StringPiece doesn't own its backing storage, 287 // therefore we're using the OatDexFile::dex_file_location_ as the backing storage 288 // for keys in oat_dex_files_ and the string_cache_ entries for the backing storage 289 // of keys in secondary_oat_dex_files_ and oat_dex_files_by_canonical_location_. 290 typedef SafeMap<StringPiece, const OatDexFile*> Table; 291 292 // Map each plain dex file location retrieved from the oat file to its OatDexFile. 293 // This map doesn't change after it's constructed in Setup() and therefore doesn't 294 // need any locking and provides the cheapest dex file lookup for GetOatDexFile() 295 // for a very frequent use case. Never contains a nullptr value. 296 Table oat_dex_files_; // Owns the OatDexFile* values. 297 298 // Lock guarding all members needed for secondary lookup in GetOatDexFile(). 299 mutable Mutex secondary_lookup_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; 300 301 // If the primary oat_dex_files_ lookup fails, use a secondary map. This map stores 302 // the results of all previous secondary lookups, whether successful (non-null) or 303 // failed (null). If it doesn't contain an entry we need to calculate the canonical 304 // location and use oat_dex_files_by_canonical_location_. 305 mutable Table secondary_oat_dex_files_ GUARDED_BY(secondary_lookup_lock_); 306 307 // Map the canonical location to an OatDexFile. This lazily constructed map is used 308 // when we're doing the secondary lookup for a given location for the first time. 309 mutable Table oat_dex_files_by_canonical_location_ GUARDED_BY(secondary_lookup_lock_); 310 311 // Cache of strings. Contains the backing storage for keys in the secondary_oat_dex_files_ 312 // and the lazily initialized oat_dex_files_by_canonical_location_. 313 // NOTE: We're keeping references to contained strings in form of StringPiece and adding 314 // new strings to the end. The adding of a new element must not touch any previously stored 315 // elements. std::list<> and std::deque<> satisfy this requirement, std::vector<> doesn't. 316 mutable std::list<std::string> string_cache_ GUARDED_BY(secondary_lookup_lock_); 317 318 friend class OatClass; 319 friend class OatDexFile; 320 friend class OatDumper; // For GetBase and GetLimit 321 DISALLOW_COPY_AND_ASSIGN(OatFile); 322}; 323 324} // namespace art 325 326#endif // ART_RUNTIME_OAT_FILE_H_ 327