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 "dex_file.h" 24 #include "invoke_type.h" 25 #include "mem_map.h" 26 #include "mirror/art_method.h" 27 #include "oat.h" 28 #include "os.h" 29 30 namespace art { 31 32 class ElfFile; 33 class MemMap; 34 class OatMethodOffsets; 35 class OatHeader; 36 37 class OatFile { 38 public: 39 // Returns an .odex file name next adjacent to the dex location. 40 // For example, for "/foo/bar/baz.jar", return "/foo/bar/baz.odex". 41 static std::string DexFilenameToOdexFilename(const std::string& location); 42 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 50 // Open an oat file from an already opened File. 51 // Does not use dlopen underneath so cannot be used for runtime use 52 // where relocations may be required. Currently used from 53 // ImageWriter which wants to open a writable version from an existing 54 // file descriptor for patching. 55 static OatFile* OpenWritable(File* file, const std::string& location); 56 57 // Open an oat file backed by a std::vector with the given location. 58 static OatFile* OpenMemory(std::vector<uint8_t>& oat_contents, 59 const std::string& location); 60 61 ~OatFile(); 62 63 const std::string& GetLocation() const { 64 return location_; 65 } 66 67 const OatHeader& GetOatHeader() const; 68 69 class OatDexFile; 70 71 class OatMethod { 72 public: 73 void LinkMethod(mirror::ArtMethod* method) const; 74 75 uint32_t GetCodeOffset() const { 76 return code_offset_; 77 } 78 size_t GetFrameSizeInBytes() const { 79 return frame_size_in_bytes_; 80 } 81 uint32_t GetCoreSpillMask() const { 82 return core_spill_mask_; 83 } 84 uint32_t GetFpSpillMask() const { 85 return fp_spill_mask_; 86 } 87 uint32_t GetMappingTableOffset() const { 88 return mapping_table_offset_; 89 } 90 uint32_t GetVmapTableOffset() const { 91 return vmap_table_offset_; 92 } 93 uint32_t GetNativeGcMapOffset() const { 94 return native_gc_map_offset_; 95 } 96 97 const void* GetCode() const; 98 uint32_t GetCodeSize() const; 99 100 const uint8_t* GetMappingTable() const { 101 return GetOatPointer<const uint8_t*>(mapping_table_offset_); 102 } 103 const uint8_t* GetVmapTable() const { 104 return GetOatPointer<const uint8_t*>(vmap_table_offset_); 105 } 106 const uint8_t* GetNativeGcMap() const { 107 return GetOatPointer<const uint8_t*>(native_gc_map_offset_); 108 } 109 110 ~OatMethod(); 111 112 // Create an OatMethod with offsets relative to the given base address 113 OatMethod(const byte* base, 114 const uint32_t code_offset, 115 const size_t frame_size_in_bytes, 116 const uint32_t core_spill_mask, 117 const uint32_t fp_spill_mask, 118 const uint32_t mapping_table_offset, 119 const uint32_t vmap_table_offset, 120 const uint32_t gc_map_offset); 121 122 private: 123 template<class T> 124 T GetOatPointer(uint32_t offset) const { 125 if (offset == 0) { 126 return NULL; 127 } 128 return reinterpret_cast<T>(begin_ + offset); 129 } 130 131 const byte* begin_; 132 133 uint32_t code_offset_; 134 size_t frame_size_in_bytes_; 135 uint32_t core_spill_mask_; 136 uint32_t fp_spill_mask_; 137 uint32_t mapping_table_offset_; 138 uint32_t vmap_table_offset_; 139 uint32_t native_gc_map_offset_; 140 141 friend class OatClass; 142 }; 143 144 class OatClass { 145 public: 146 mirror::Class::Status GetStatus() const; 147 148 // get the OatMethod entry based on its index into the class 149 // defintion. direct methods come first, followed by virtual 150 // methods. note that runtime created methods such as miranda 151 // methods are not included. 152 const OatMethod GetOatMethod(uint32_t method_index) const; 153 ~OatClass(); 154 155 private: 156 OatClass(const OatFile* oat_file, 157 mirror::Class::Status status, 158 const OatMethodOffsets* methods_pointer); 159 160 const OatFile* oat_file_; 161 const mirror::Class::Status status_; 162 const OatMethodOffsets* methods_pointer_; 163 164 friend class OatDexFile; 165 }; 166 167 class OatDexFile { 168 public: 169 // Opens the DexFile referred to by this OatDexFile from within the containing OatFile. 170 const DexFile* OpenDexFile() const; 171 172 // Returns the size of the DexFile refered to by this OatDexFile. 173 size_t FileSize() const; 174 175 // Returns original path of DexFile that was the source of this OatDexFile. 176 const std::string& GetDexFileLocation() const { 177 return dex_file_location_; 178 } 179 180 // Returns checksum of original DexFile that was the source of this OatDexFile; 181 uint32_t GetDexFileLocationChecksum() const { 182 return dex_file_location_checksum_; 183 } 184 185 // Returns the OatClass for the class specified by the given DexFile class_def_index. 186 const OatClass* GetOatClass(uint16_t class_def_index) const; 187 188 ~OatDexFile(); 189 190 private: 191 OatDexFile(const OatFile* oat_file, 192 const std::string& dex_file_location, 193 uint32_t dex_file_checksum, 194 const byte* dex_file_pointer, 195 const uint32_t* oat_class_offsets_pointer); 196 197 const OatFile* oat_file_; 198 std::string dex_file_location_; 199 uint32_t dex_file_location_checksum_; 200 const byte* dex_file_pointer_; 201 const uint32_t* oat_class_offsets_pointer_; 202 203 friend class OatFile; 204 DISALLOW_COPY_AND_ASSIGN(OatDexFile); 205 }; 206 207 const OatDexFile* GetOatDexFile(const std::string& dex_location, 208 const uint32_t* const dex_location_checksum, 209 bool exception_if_not_found = true) const 210 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 211 std::vector<const OatDexFile*> GetOatDexFiles() const; 212 213 size_t Size() const { 214 return End() - Begin(); 215 } 216 217 private: 218 static void CheckLocation(const std::string& location); 219 220 static OatFile* OpenDlopen(const std::string& elf_filename, 221 const std::string& location, 222 byte* requested_base); 223 224 static OatFile* OpenElfFile(File* file, 225 const std::string& location, 226 byte* requested_base, 227 bool writable, 228 bool executable); 229 230 explicit OatFile(const std::string& filename); 231 bool Dlopen(const std::string& elf_filename, byte* requested_base); 232 bool ElfFileOpen(File* file, byte* requested_base, bool writable, bool executable); 233 bool Setup(); 234 235 const byte* Begin() const; 236 const byte* End() const; 237 238 // The oat file name. 239 // 240 // The image will embed this to link its associated oat file. 241 const std::string location_; 242 243 // Pointer to OatHeader. 244 const byte* begin_; 245 246 // Pointer to end of oat region for bounds checking. 247 const byte* end_; 248 249 // Backing memory map for oat file during when opened by ElfWriter during initial compilation. 250 UniquePtr<MemMap> mem_map_; 251 252 // Backing memory map for oat file during cross compilation. 253 UniquePtr<ElfFile> elf_file_; 254 255 // dlopen handle during runtime. 256 void* dlopen_handle_; 257 258 typedef SafeMap<std::string, const OatDexFile*> Table; 259 Table oat_dex_files_; 260 261 friend class OatClass; 262 friend class OatDexFile; 263 friend class OatDumper; // For GetBase and GetLimit 264 DISALLOW_COPY_AND_ASSIGN(OatFile); 265 }; 266 267 } // namespace art 268 269 #endif // ART_RUNTIME_OAT_FILE_H_ 270