| /* |
| * Copyright (C) 2011 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef ART_SRC_OAT_FILE_H_ |
| #define ART_SRC_OAT_FILE_H_ |
| |
| #include <vector> |
| |
| #include "dex_file.h" |
| #include "mem_map.h" |
| #include "oat.h" |
| #include "object.h" |
| |
| namespace art { |
| |
| class OatFile { |
| public: |
| |
| // Returns an OatFile name based on a DexFile location |
| static std::string DexFilenameToOatFilename(const std::string& location); |
| |
| // Open an oat file. Returns NULL on failure. Requested base can |
| // optionally be used to request where the file should be loaded. |
| static OatFile* Open(const std::string& filename, |
| const std::string& location, |
| byte* requested_base, |
| bool writable = false); |
| |
| // Open an oat file from an already opened File with the given location. |
| static OatFile* Open(File& file, |
| const std::string& location, |
| byte* requested_base, |
| bool writable = false); |
| |
| ~OatFile(); |
| |
| const std::string& GetLocation() const { |
| return location_; |
| } |
| |
| const OatHeader& GetOatHeader() const; |
| |
| class OatDexFile; |
| |
| class OatMethod { |
| public: |
| // Link Method for execution using the contents of this OatMethod |
| void LinkMethodPointers(Method* method) const; |
| |
| // Link Method for image writing using the contents of this OatMethod |
| void LinkMethodOffsets(Method* method) const; |
| |
| uint32_t GetCodeOffset() const { |
| return code_offset_; |
| } |
| size_t GetFrameSizeInBytes() const { |
| return frame_size_in_bytes_; |
| } |
| uint32_t GetCoreSpillMask() const { |
| return core_spill_mask_; |
| } |
| uint32_t GetFpSpillMask() const { |
| return fp_spill_mask_; |
| } |
| uint32_t GetMappingTableOffset() const { |
| return mapping_table_offset_; |
| } |
| uint32_t GetVmapTableOffset() const { |
| return vmap_table_offset_; |
| } |
| uint32_t GetGcMapOffset() const { |
| return gc_map_offset_; |
| } |
| uint32_t GetInvokeStubOffset() const { |
| return invoke_stub_offset_; |
| } |
| |
| const void* GetCode() const { |
| return GetOatPointer<const void*>(code_offset_); |
| } |
| uint32_t GetCodeSize() const { |
| uintptr_t code = reinterpret_cast<uint32_t>(GetCode()); |
| if (code == 0) { |
| return 0; |
| } |
| // TODO: make this Thumb2 specific |
| code &= ~0x1; |
| return reinterpret_cast<uint32_t*>(code)[-1]; |
| } |
| const uint32_t* GetMappingTable() const { |
| return GetOatPointer<const uint32_t*>(mapping_table_offset_); |
| } |
| const uint16_t* GetVmapTable() const { |
| return GetOatPointer<const uint16_t*>(vmap_table_offset_); |
| } |
| const uint8_t* GetGcMap() const { |
| return GetOatPointer<const uint8_t*>(gc_map_offset_); |
| } |
| const Method::InvokeStub* GetInvokeStub() const { |
| return GetOatPointer<const Method::InvokeStub*>(invoke_stub_offset_); |
| } |
| uint32_t GetInvokeStubSize() const { |
| uintptr_t code = reinterpret_cast<uint32_t>(GetInvokeStub()); |
| if (code == 0) { |
| return 0; |
| } |
| return reinterpret_cast<uint32_t*>(code)[-1]; |
| } |
| |
| ~OatMethod(); |
| |
| // Create an OatMethod with offsets relative to the given base address |
| OatMethod(const byte* base, |
| const uint32_t code_offset, |
| const size_t frame_size_in_bytes, |
| const uint32_t core_spill_mask, |
| const uint32_t fp_spill_mask, |
| const uint32_t mapping_table_offset, |
| const uint32_t vmap_table_offset, |
| const uint32_t gc_map_offset, |
| const uint32_t invoke_stub_offset); |
| |
| private: |
| template<class T> |
| T GetOatPointer(uint32_t offset) const { |
| if (offset == 0) { |
| return NULL; |
| } |
| return reinterpret_cast<T>(begin_ + offset); |
| } |
| |
| const byte* begin_; |
| |
| uint32_t code_offset_; |
| size_t frame_size_in_bytes_; |
| uint32_t core_spill_mask_; |
| uint32_t fp_spill_mask_; |
| uint32_t mapping_table_offset_; |
| uint32_t vmap_table_offset_; |
| uint32_t gc_map_offset_; |
| uint32_t invoke_stub_offset_; |
| |
| friend class OatClass; |
| }; |
| |
| class OatClass { |
| public: |
| Class::Status GetStatus() const; |
| |
| // get the OatMethod entry based on its index into the class |
| // defintion. direct methods come first, followed by virtual |
| // methods. note that runtime created methods such as miranda |
| // methods are not included. |
| const OatMethod GetOatMethod(uint32_t method_index) const; |
| ~OatClass(); |
| |
| private: |
| OatClass(const OatFile* oat_file, |
| Class::Status status, |
| const OatMethodOffsets* methods_pointer); |
| |
| const OatFile* oat_file_; |
| const Class::Status status_; |
| const OatMethodOffsets* methods_pointer_; |
| |
| friend class OatDexFile; |
| }; |
| |
| class OatDexFile { |
| public: |
| const DexFile* OpenDexFile() const; |
| const OatClass* GetOatClass(uint32_t class_def_index) const; |
| |
| const std::string& GetDexFileLocation() const { |
| return dex_file_location_; |
| } |
| |
| uint32_t GetDexFileLocationChecksum() const { |
| return dex_file_location_checksum_; |
| } |
| |
| ~OatDexFile(); |
| private: |
| OatDexFile(const OatFile* oat_file, |
| const std::string& dex_file_location, |
| uint32_t dex_file_checksum, |
| byte* dex_file_pointer, |
| const uint32_t* oat_class_offsets_pointer); |
| |
| const OatFile* oat_file_; |
| std::string dex_file_location_; |
| uint32_t dex_file_location_checksum_; |
| const byte* dex_file_pointer_; |
| const uint32_t* oat_class_offsets_pointer_; |
| |
| friend class OatFile; |
| DISALLOW_COPY_AND_ASSIGN(OatDexFile); |
| }; |
| |
| class OatElfImage { |
| public: |
| const byte* begin() const { |
| return elf_addr_; |
| } |
| |
| const byte* end() const { |
| return (elf_addr_ + elf_size_); |
| } |
| |
| size_t size() const { |
| return elf_size_; |
| } |
| |
| private: |
| OatElfImage(const OatFile* oat_file, const byte* addr, uint32_t size); |
| |
| const OatFile* oat_file_; |
| const byte* elf_addr_; |
| uint32_t elf_size_; |
| |
| friend class OatFile; |
| DISALLOW_COPY_AND_ASSIGN(OatElfImage); |
| }; |
| |
| const OatDexFile* GetOatDexFile(const std::string& dex_file_location, |
| bool warn_if_not_found = true) const; |
| std::vector<const OatDexFile*> GetOatDexFiles() const; |
| |
| const OatElfImage* GetOatElfImage(size_t i) const { |
| return oat_elf_images_[i]; |
| } |
| |
| size_t Size() const { |
| return End() - Begin(); |
| } |
| |
| private: |
| explicit OatFile(const std::string& filename); |
| bool Map(File& file, byte* requested_base, bool writable); |
| |
| const byte* Begin() const; |
| const byte* End() const; |
| |
| // The oat file name. |
| // |
| // The image will embed this to link its associated oat file. |
| const std::string location_; |
| |
| // backing memory map for oat file |
| UniquePtr<MemMap> mem_map_; |
| |
| typedef std::map<std::string, const OatDexFile*> Table; |
| Table oat_dex_files_; |
| |
| std::vector<OatElfImage*> oat_elf_images_; |
| |
| friend class OatClass; |
| friend class OatDexFile; |
| friend class OatDumper; // For GetBase and GetLimit |
| DISALLOW_COPY_AND_ASSIGN(OatFile); |
| }; |
| |
| } // namespace art |
| |
| #endif // ART_SRC_OAT_WRITER_H_ |