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 <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 
     33 namespace art {
     34 
     35 class BitVector;
     36 class ElfFile;
     37 class MemMap;
     38 class OatMethodOffsets;
     39 class OatHeader;
     40 
     41 class 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                        uint8_t* oat_file_begin,
     53                        bool executable,
     54                        std::string* error_msg);
     55 
     56   // Open an oat file from an already opened File.
     57   // Does not use dlopen underneath so cannot be used for runtime use
     58   // where relocations may be required. Currently used from
     59   // ImageWriter which wants to open a writable version from an existing
     60   // file descriptor for patching.
     61   static OatFile* OpenWritable(File* file, const std::string& location, std::string* error_msg);
     62   // Opens an oat file from an already opened File. Maps it PROT_READ, MAP_PRIVATE.
     63   static OatFile* OpenReadable(File* file, const std::string& location, std::string* error_msg);
     64 
     65   // Open an oat file backed by a std::vector with the given location.
     66   static OatFile* OpenMemory(std::vector<uint8_t>& oat_contents,
     67                              const std::string& location,
     68                              std::string* error_msg);
     69 
     70   ~OatFile();
     71 
     72   bool IsExecutable() const {
     73     return is_executable_;
     74   }
     75 
     76   bool IsPic() const;
     77 
     78   ElfFile* GetElfFile() const {
     79     CHECK_NE(reinterpret_cast<uintptr_t>(elf_file_.get()), reinterpret_cast<uintptr_t>(nullptr))
     80         << "Cannot get an elf file from " << GetLocation();
     81     return elf_file_.get();
     82   }
     83 
     84   const std::string& GetLocation() const {
     85     return location_;
     86   }
     87 
     88   const OatHeader& GetOatHeader() const;
     89 
     90   class OatDexFile;
     91 
     92   class OatMethod {
     93    public:
     94     void LinkMethod(mirror::ArtMethod* method) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
     95 
     96     uint32_t GetCodeOffset() const {
     97       return code_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     // Returns 0.
    118     uint32_t GetPortableCodeSize() const {
    119       // TODO: With Quick, we store the size before the code. With Portable, the code is in a .o
    120       // file we don't manage ourselves. ELF symbols do have a concept of size, so we could capture
    121       // that and store it somewhere, such as the OatMethod.
    122       return 0;
    123     }
    124 
    125     // Returns size of quick code.
    126     uint32_t GetQuickCodeSize() const;
    127     uint32_t GetQuickCodeSizeOffset() const;
    128 
    129     // Returns OatQuickMethodHeader for debugging. Most callers should
    130     // use more specific methods such as GetQuickCodeSize.
    131     const OatQuickMethodHeader* GetOatQuickMethodHeader() const;
    132     uint32_t GetOatQuickMethodHeaderOffset() const;
    133 
    134     size_t GetFrameSizeInBytes() const;
    135     uint32_t GetCoreSpillMask() const;
    136     uint32_t GetFpSpillMask() const;
    137 
    138     const uint8_t* GetMappingTable() const;
    139     uint32_t GetMappingTableOffset() const;
    140     uint32_t GetMappingTableOffsetOffset() const;
    141 
    142     const uint8_t* GetVmapTable() const;
    143     uint32_t GetVmapTableOffset() const;
    144     uint32_t GetVmapTableOffsetOffset() const;
    145 
    146     const uint8_t* GetGcMap() const;
    147     uint32_t GetGcMapOffset() const;
    148     uint32_t GetGcMapOffsetOffset() const;
    149 
    150     ~OatMethod();
    151 
    152     // Create an OatMethod with offsets relative to the given base address
    153     OatMethod(const byte* base, const uint32_t code_offset);
    154 
    155     OatMethod() {}
    156 
    157    private:
    158     template<class T>
    159     T GetOatPointer(uint32_t offset) const {
    160       if (offset == 0) {
    161         return NULL;
    162       }
    163       return reinterpret_cast<T>(begin_ + offset);
    164     }
    165 
    166     const byte* begin_;
    167 
    168     uint32_t code_offset_;
    169 
    170     friend class OatClass;
    171   };
    172 
    173   class OatClass {
    174    public:
    175     mirror::Class::Status GetStatus() const {
    176       return status_;
    177     }
    178 
    179     OatClassType GetType() const {
    180       return type_;
    181     }
    182 
    183     // Get the OatMethod entry based on its index into the class
    184     // defintion. Direct methods come first, followed by virtual
    185     // methods. Note that runtime created methods such as miranda
    186     // methods are not included.
    187     const OatMethod GetOatMethod(uint32_t method_index) const;
    188 
    189     // Return a pointer to the OatMethodOffsets for the requested
    190     // method_index, or nullptr if none is present. Note that most
    191     // callers should use GetOatMethod.
    192     const OatMethodOffsets* GetOatMethodOffsets(uint32_t method_index) const;
    193 
    194     // Return the offset from the start of the OatFile to the
    195     // OatMethodOffsets for the requested method_index, or 0 if none
    196     // is present. Note that most callers should use GetOatMethod.
    197     uint32_t GetOatMethodOffsetsOffset(uint32_t method_index) const;
    198 
    199     OatClass() {}
    200 
    201    private:
    202     OatClass(const OatFile* oat_file,
    203              mirror::Class::Status status,
    204              OatClassType type,
    205              uint32_t bitmap_size,
    206              const uint32_t* bitmap_pointer,
    207              const OatMethodOffsets* methods_pointer);
    208 
    209     const OatFile* oat_file_;
    210 
    211     mirror::Class::Status status_;
    212 
    213     OatClassType type_;
    214 
    215     const uint32_t* bitmap_;
    216 
    217     const OatMethodOffsets* methods_pointer_;
    218 
    219     friend class OatDexFile;
    220   };
    221 
    222   class OatDexFile {
    223    public:
    224     // Opens the DexFile referred to by this OatDexFile from within the containing OatFile.
    225     const DexFile* OpenDexFile(std::string* error_msg) const;
    226 
    227     const OatFile* GetOatFile() const {
    228       return oat_file_;
    229     }
    230 
    231     // Returns the size of the DexFile refered to by this OatDexFile.
    232     size_t FileSize() const;
    233 
    234     // Returns original path of DexFile that was the source of this OatDexFile.
    235     const std::string& GetDexFileLocation() const {
    236       return dex_file_location_;
    237     }
    238 
    239     // Returns the canonical location of DexFile that was the source of this OatDexFile.
    240     const std::string& GetCanonicalDexFileLocation() const {
    241       return canonical_dex_file_location_;
    242     }
    243 
    244     // Returns checksum of original DexFile that was the source of this OatDexFile;
    245     uint32_t GetDexFileLocationChecksum() const {
    246       return dex_file_location_checksum_;
    247     }
    248 
    249     // Returns the OatClass for the class specified by the given DexFile class_def_index.
    250     OatClass GetOatClass(uint16_t class_def_index) const;
    251 
    252     // Returns the offset to the OatClass information. Most callers should use GetOatClass.
    253     uint32_t GetOatClassOffset(uint16_t class_def_index) const;
    254 
    255     ~OatDexFile();
    256 
    257    private:
    258     OatDexFile(const OatFile* oat_file,
    259                const std::string& dex_file_location,
    260                const std::string& canonical_dex_file_location,
    261                uint32_t dex_file_checksum,
    262                const byte* dex_file_pointer,
    263                const uint32_t* oat_class_offsets_pointer);
    264 
    265     const OatFile* const oat_file_;
    266     const std::string dex_file_location_;
    267     const std::string canonical_dex_file_location_;
    268     const uint32_t dex_file_location_checksum_;
    269     const byte* const dex_file_pointer_;
    270     const uint32_t* const oat_class_offsets_pointer_;
    271 
    272     friend class OatFile;
    273     DISALLOW_COPY_AND_ASSIGN(OatDexFile);
    274   };
    275 
    276   const OatDexFile* GetOatDexFile(const char* dex_location,
    277                                   const uint32_t* const dex_location_checksum,
    278                                   bool exception_if_not_found = true) const
    279       LOCKS_EXCLUDED(secondary_lookup_lock_);
    280 
    281   const std::vector<const OatDexFile*>& GetOatDexFiles() const {
    282     return oat_dex_files_storage_;
    283   }
    284 
    285   size_t Size() const {
    286     return End() - Begin();
    287   }
    288 
    289   const byte* Begin() const;
    290   const byte* End() const;
    291 
    292  private:
    293   static void CheckLocation(const std::string& location);
    294 
    295   static OatFile* OpenDlopen(const std::string& elf_filename,
    296                              const std::string& location,
    297                              byte* requested_base,
    298                              std::string* error_msg);
    299 
    300   static OatFile* OpenElfFile(File* file,
    301                               const std::string& location,
    302                               byte* requested_base,
    303                               uint8_t* oat_file_begin,  // Override base if not null
    304                               bool writable,
    305                               bool executable,
    306                               std::string* error_msg);
    307 
    308   explicit OatFile(const std::string& filename, bool executable);
    309   bool Dlopen(const std::string& elf_filename, byte* requested_base, std::string* error_msg);
    310   bool ElfFileOpen(File* file, byte* requested_base,
    311                    uint8_t* oat_file_begin,  // Override where the file is loaded to if not null
    312                    bool writable, bool executable,
    313                    std::string* error_msg);
    314   bool Setup(std::string* error_msg);
    315 
    316   // The oat file name.
    317   //
    318   // The image will embed this to link its associated oat file.
    319   const std::string location_;
    320 
    321   // Pointer to OatHeader.
    322   const byte* begin_;
    323 
    324   // Pointer to end of oat region for bounds checking.
    325   const byte* end_;
    326 
    327   // Was this oat_file loaded executable?
    328   const bool is_executable_;
    329 
    330   // Backing memory map for oat file during when opened by ElfWriter during initial compilation.
    331   std::unique_ptr<MemMap> mem_map_;
    332 
    333   // Backing memory map for oat file during cross compilation.
    334   std::unique_ptr<ElfFile> elf_file_;
    335 
    336   // dlopen handle during runtime.
    337   void* dlopen_handle_;
    338 
    339   // Owning storage for the OatDexFile objects.
    340   std::vector<const OatDexFile*> oat_dex_files_storage_;
    341 
    342   // NOTE: We use a StringPiece as the key type to avoid a memory allocation on every
    343   // lookup with a const char* key. The StringPiece doesn't own its backing storage,
    344   // therefore we're using the OatDexFile::dex_file_location_ as the backing storage
    345   // for keys in oat_dex_files_ and the string_cache_ entries for the backing storage
    346   // of keys in secondary_oat_dex_files_ and oat_dex_files_by_canonical_location_.
    347   typedef AllocationTrackingSafeMap<StringPiece, const OatDexFile*, kAllocatorTagOatFile> Table;
    348 
    349   // Map each location and canonical location (if different) retrieved from the
    350   // oat file to its OatDexFile. This map doesn't change after it's constructed in Setup()
    351   // and therefore doesn't need any locking and provides the cheapest dex file lookup
    352   // for GetOatDexFile() for a very frequent use case. Never contains a nullptr value.
    353   Table oat_dex_files_;
    354 
    355   // Lock guarding all members needed for secondary lookup in GetOatDexFile().
    356   mutable Mutex secondary_lookup_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
    357 
    358   // If the primary oat_dex_files_ lookup fails, use a secondary map. This map stores
    359   // the results of all previous secondary lookups, whether successful (non-null) or
    360   // failed (null). If it doesn't contain an entry we need to calculate the canonical
    361   // location and use oat_dex_files_by_canonical_location_.
    362   mutable Table secondary_oat_dex_files_ GUARDED_BY(secondary_lookup_lock_);
    363 
    364   // Cache of strings. Contains the backing storage for keys in the secondary_oat_dex_files_
    365   // and the lazily initialized oat_dex_files_by_canonical_location_.
    366   // NOTE: We're keeping references to contained strings in form of StringPiece and adding
    367   // new strings to the end. The adding of a new element must not touch any previously stored
    368   // elements. std::list<> and std::deque<> satisfy this requirement, std::vector<> doesn't.
    369   mutable std::list<std::string> string_cache_ GUARDED_BY(secondary_lookup_lock_);
    370 
    371   friend class OatClass;
    372   friend class OatDexFile;
    373   friend class OatDumper;  // For GetBase and GetLimit
    374   DISALLOW_COPY_AND_ASSIGN(OatFile);
    375 };
    376 
    377 }  // namespace art
    378 
    379 #endif  // ART_RUNTIME_OAT_FILE_H_
    380