Home | History | Annotate | Download | only in runtime
      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