oat_file.h revision a59dd80f9f48cb750d329d4d4af2d99d72b484d1
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 <string> 21#include <vector> 22 23#include "base/stringpiece.h" 24#include "dex_file.h" 25#include "invoke_type.h" 26#include "mem_map.h" 27#include "mirror/class.h" 28#include "oat.h" 29#include "os.h" 30 31namespace art { 32 33class BitVector; 34class ElfFile; 35class MemMap; 36class OatMethodOffsets; 37class OatHeader; 38 39class OatFile { 40 public: 41 // Open an oat file. Returns NULL on failure. Requested base can 42 // optionally be used to request where the file should be loaded. 43 static OatFile* Open(const std::string& filename, 44 const std::string& location, 45 byte* requested_base, 46 bool executable, 47 std::string* error_msg); 48 49 // Open an oat file from an already opened File. 50 // Does not use dlopen underneath so cannot be used for runtime use 51 // where relocations may be required. Currently used from 52 // ImageWriter which wants to open a writable version from an existing 53 // file descriptor for patching. 54 static OatFile* OpenWritable(File* file, const std::string& location, std::string* error_msg); 55 // Opens an oat file from an already opened File. Maps it PROT_READ, MAP_PRIVATE. 56 static OatFile* OpenReadable(File* file, const std::string& location, std::string* error_msg); 57 58 // Open an oat file backed by a std::vector with the given location. 59 static OatFile* OpenMemory(std::vector<uint8_t>& oat_contents, 60 const std::string& location, 61 std::string* error_msg); 62 63 ~OatFile(); 64 65 ElfFile* GetElfFile() const { 66 CHECK_NE(reinterpret_cast<uintptr_t>(elf_file_.get()), reinterpret_cast<uintptr_t>(nullptr)) 67 << "Cannot get an elf file from " << GetLocation(); 68 return elf_file_.get(); 69 } 70 71 const std::string& GetLocation() const { 72 return location_; 73 } 74 75 const OatHeader& GetOatHeader() const; 76 77 class OatDexFile; 78 79 class OatMethod { 80 public: 81 void LinkMethod(mirror::ArtMethod* method) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 82 83 uint32_t GetCodeOffset() const { 84 return code_offset_; 85 } 86 uint32_t GetNativeGcMapOffset() const { 87 return native_gc_map_offset_; 88 } 89 90 const void* GetPortableCode() const { 91 // TODO: encode whether code is portable/quick in flags within OatMethod. 92 if (kUsePortableCompiler) { 93 return GetOatPointer<const void*>(code_offset_); 94 } else { 95 return nullptr; 96 } 97 } 98 99 const void* GetQuickCode() const { 100 if (kUsePortableCompiler) { 101 return nullptr; 102 } else { 103 return GetOatPointer<const void*>(code_offset_); 104 } 105 } 106 107 uint32_t GetPortableCodeSize() const { 108 // TODO: With Quick, we store the size before the code. With Portable, the code is in a .o 109 // file we don't manage ourselves. ELF symbols do have a concept of size, so we could capture 110 // that and store it somewhere, such as the OatMethod. 111 return 0; 112 } 113 uint32_t GetQuickCodeSize() const; 114 115 const uint8_t* GetNativeGcMap() const { 116 return GetOatPointer<const uint8_t*>(native_gc_map_offset_); 117 } 118 119 size_t GetFrameSizeInBytes() const; 120 uint32_t GetCoreSpillMask() const; 121 uint32_t GetFpSpillMask() const; 122 uint32_t GetMappingTableOffset() const; 123 uint32_t GetVmapTableOffset() const; 124 const uint8_t* GetMappingTable() const; 125 const uint8_t* GetVmapTable() const; 126 127 ~OatMethod(); 128 129 // Create an OatMethod with offsets relative to the given base address 130 OatMethod(const byte* base, 131 const uint32_t code_offset, 132 const uint32_t gc_map_offset); 133 134 private: 135 template<class T> 136 T GetOatPointer(uint32_t offset) const { 137 if (offset == 0) { 138 return NULL; 139 } 140 return reinterpret_cast<T>(begin_ + offset); 141 } 142 143 const byte* begin_; 144 145 uint32_t code_offset_; 146 uint32_t native_gc_map_offset_; 147 148 friend class OatClass; 149 }; 150 151 class OatClass { 152 public: 153 mirror::Class::Status GetStatus() const { 154 return status_; 155 } 156 157 OatClassType GetType() const { 158 return type_; 159 } 160 161 // Get the OatMethod entry based on its index into the class 162 // defintion. direct methods come first, followed by virtual 163 // methods. note that runtime created methods such as miranda 164 // methods are not included. 165 const OatMethod GetOatMethod(uint32_t method_index) const; 166 167 private: 168 OatClass(const OatFile* oat_file, 169 mirror::Class::Status status, 170 OatClassType type, 171 uint32_t bitmap_size, 172 const uint32_t* bitmap_pointer, 173 const OatMethodOffsets* methods_pointer); 174 175 const OatFile* const oat_file_; 176 177 const mirror::Class::Status status_; 178 179 const OatClassType type_; 180 181 const uint32_t* const bitmap_; 182 183 const OatMethodOffsets* methods_pointer_; 184 185 friend class OatDexFile; 186 }; 187 188 class OatDexFile { 189 public: 190 // Opens the DexFile referred to by this OatDexFile from within the containing OatFile. 191 const DexFile* OpenDexFile(std::string* error_msg) const; 192 193 // Returns the size of the DexFile refered to by this OatDexFile. 194 size_t FileSize() const; 195 196 // Returns original path of DexFile that was the source of this OatDexFile. 197 const std::string& GetDexFileLocation() const { 198 return dex_file_location_; 199 } 200 201 // Returns checksum of original DexFile that was the source of this OatDexFile; 202 uint32_t GetDexFileLocationChecksum() const { 203 return dex_file_location_checksum_; 204 } 205 206 // Returns the OatClass for the class specified by the given DexFile class_def_index. 207 OatClass GetOatClass(uint16_t class_def_index) const; 208 209 ~OatDexFile(); 210 211 private: 212 OatDexFile(const OatFile* oat_file, 213 const std::string& dex_file_location, 214 uint32_t dex_file_checksum, 215 const byte* dex_file_pointer, 216 const uint32_t* oat_class_offsets_pointer); 217 218 const OatFile* const oat_file_; 219 const std::string dex_file_location_; 220 const uint32_t dex_file_location_checksum_; 221 const byte* const dex_file_pointer_; 222 const uint32_t* const oat_class_offsets_pointer_; 223 224 friend class OatFile; 225 DISALLOW_COPY_AND_ASSIGN(OatDexFile); 226 }; 227 228 const OatDexFile* GetOatDexFile(const char* dex_location, 229 const uint32_t* const dex_location_checksum, 230 bool exception_if_not_found = true) const; 231 232 std::vector<const OatDexFile*> GetOatDexFiles() const; 233 234 size_t Size() const { 235 return End() - Begin(); 236 } 237 238 const byte* Begin() const; 239 const byte* End() const; 240 241 private: 242 static void CheckLocation(const std::string& location); 243 244 static OatFile* OpenDlopen(const std::string& elf_filename, 245 const std::string& location, 246 byte* requested_base, 247 std::string* error_msg); 248 249 static OatFile* OpenElfFile(File* file, 250 const std::string& location, 251 byte* requested_base, 252 bool writable, 253 bool executable, 254 std::string* error_msg); 255 256 explicit OatFile(const std::string& filename); 257 bool Dlopen(const std::string& elf_filename, byte* requested_base, std::string* error_msg); 258 bool ElfFileOpen(File* file, byte* requested_base, bool writable, bool executable, 259 std::string* error_msg); 260 bool Setup(std::string* error_msg); 261 262 // The oat file name. 263 // 264 // The image will embed this to link its associated oat file. 265 const std::string location_; 266 267 // Pointer to OatHeader. 268 const byte* begin_; 269 270 // Pointer to end of oat region for bounds checking. 271 const byte* end_; 272 273 // Backing memory map for oat file during when opened by ElfWriter during initial compilation. 274 std::unique_ptr<MemMap> mem_map_; 275 276 // Backing memory map for oat file during cross compilation. 277 std::unique_ptr<ElfFile> elf_file_; 278 279 // dlopen handle during runtime. 280 void* dlopen_handle_; 281 282 // NOTE: We use a StringPiece as the key type to avoid a memory allocation on every lookup 283 // with a const char* key. 284 typedef SafeMap<StringPiece, const OatDexFile*> Table; 285 Table oat_dex_files_; 286 287 friend class OatClass; 288 friend class OatDexFile; 289 friend class OatDumper; // For GetBase and GetLimit 290 DISALLOW_COPY_AND_ASSIGN(OatFile); 291}; 292 293} // namespace art 294 295#endif // ART_RUNTIME_OAT_FILE_H_ 296