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