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/array_ref.h"
     25 #include "base/mutex.h"
     26 #include "base/os.h"
     27 #include "base/safe_map.h"
     28 #include "base/stringpiece.h"
     29 #include "base/tracking_safe_map.h"
     30 #include "base/utils.h"
     31 #include "class_status.h"
     32 #include "compiler_filter.h"
     33 #include "dex/dex_file.h"
     34 #include "dex/dex_file_layout.h"
     35 #include "dex/utf.h"
     36 #include "index_bss_mapping.h"
     37 #include "mirror/object.h"
     38 #include "oat.h"
     39 #include "type_lookup_table.h"
     40 
     41 namespace art {
     42 
     43 class BitVector;
     44 class ElfFile;
     45 class DexLayoutSections;
     46 template <class MirrorType> class GcRoot;
     47 class MemMap;
     48 class OatDexFile;
     49 class OatHeader;
     50 class OatMethodOffsets;
     51 class OatQuickMethodHeader;
     52 class VdexFile;
     53 
     54 namespace gc {
     55 namespace collector {
     56 class DummyOatFile;
     57 }  // namespace collector
     58 }  // namespace gc
     59 
     60 // Runtime representation of the OAT file format which holds compiler output.
     61 // The class opens an OAT file from storage and maps it to memory, typically with
     62 // dlopen and provides access to its internal data structures (see OatWriter for
     63 // for more details about the OAT format).
     64 // In the process of loading OAT, the class also loads the associated VDEX file
     65 // with the input DEX files (see VdexFile for details about the VDEX format).
     66 // The raw DEX data are accessible transparently through the OatDexFile objects.
     67 
     68 class OatFile {
     69  public:
     70   // Special classpath that skips shared library check.
     71   static constexpr const char* kSpecialSharedLibrary = "&";
     72 
     73   typedef art::OatDexFile OatDexFile;
     74 
     75   // Opens an oat file contained within the given elf file. This is always opened as
     76   // non-executable at the moment.
     77   static OatFile* OpenWithElfFile(int zip_fd,
     78                                   ElfFile* elf_file,
     79                                   VdexFile* vdex_file,
     80                                   const std::string& location,
     81                                   const char* abs_dex_location,
     82                                   std::string* error_msg);
     83   // Open an oat file. Returns null on failure.  Requested base can
     84   // optionally be used to request where the file should be loaded.
     85   // See the ResolveRelativeEncodedDexLocation for a description of how the
     86   // abs_dex_location argument is used.
     87   static OatFile* Open(int zip_fd,
     88                        const std::string& filename,
     89                        const std::string& location,
     90                        uint8_t* requested_base,
     91                        uint8_t* oat_file_begin,
     92                        bool executable,
     93                        bool low_4gb,
     94                        const char* abs_dex_location,
     95                        std::string* error_msg);
     96 
     97   // Similar to OatFile::Open(const std::string...), but accepts input vdex and
     98   // odex files as file descriptors. We also take zip_fd in case the vdex does not
     99   // contain the dex code, and we need to read it from the zip file.
    100   static OatFile* Open(int zip_fd,
    101                        int vdex_fd,
    102                        int oat_fd,
    103                        const std::string& oat_location,
    104                        uint8_t* requested_base,
    105                        uint8_t* oat_file_begin,
    106                        bool executable,
    107                        bool low_4gb,
    108                        const char* abs_dex_location,
    109                        std::string* error_msg);
    110 
    111   // Open an oat file from an already opened File.
    112   // Does not use dlopen underneath so cannot be used for runtime use
    113   // where relocations may be required. Currently used from
    114   // ImageWriter which wants to open a writable version from an existing
    115   // file descriptor for patching.
    116   static OatFile* OpenWritable(int zip_fd,
    117                                File* file,
    118                                const std::string& location,
    119                                const char* abs_dex_location,
    120                                std::string* error_msg);
    121   // Open an oat file from an already opened File. Maps it PROT_READ, MAP_PRIVATE.
    122   static OatFile* OpenReadable(int zip_fd,
    123                                File* file,
    124                                const std::string& location,
    125                                const char* abs_dex_location,
    126                                std::string* error_msg);
    127 
    128   virtual ~OatFile();
    129 
    130   bool IsExecutable() const {
    131     return is_executable_;
    132   }
    133 
    134   bool IsPic() const;
    135 
    136   // Indicates whether the oat file was compiled with full debugging capability.
    137   bool IsDebuggable() const;
    138 
    139   CompilerFilter::Filter GetCompilerFilter() const;
    140 
    141   std::string GetClassLoaderContext() const;
    142 
    143   const char* GetCompilationReason() const;
    144 
    145   const std::string& GetLocation() const {
    146     return location_;
    147   }
    148 
    149   const OatHeader& GetOatHeader() const;
    150 
    151   class OatMethod FINAL {
    152    public:
    153     void LinkMethod(ArtMethod* method) const;
    154 
    155     uint32_t GetCodeOffset() const;
    156 
    157     const void* GetQuickCode() const;
    158 
    159     // Returns size of quick code.
    160     uint32_t GetQuickCodeSize() const;
    161     uint32_t GetQuickCodeSizeOffset() const;
    162 
    163     // Returns OatQuickMethodHeader for debugging. Most callers should
    164     // use more specific methods such as GetQuickCodeSize.
    165     const OatQuickMethodHeader* GetOatQuickMethodHeader() const;
    166     uint32_t GetOatQuickMethodHeaderOffset() const;
    167 
    168     size_t GetFrameSizeInBytes() const;
    169     uint32_t GetCoreSpillMask() const;
    170     uint32_t GetFpSpillMask() const;
    171 
    172     const uint8_t* GetVmapTable() const;
    173     uint32_t GetVmapTableOffset() const;
    174     uint32_t GetVmapTableOffsetOffset() const;
    175 
    176     // Create an OatMethod with offsets relative to the given base address
    177     OatMethod(const uint8_t* base, const uint32_t code_offset)
    178         : begin_(base), code_offset_(code_offset) {
    179     }
    180     OatMethod(const OatMethod&) = default;
    181     ~OatMethod() {}
    182 
    183     OatMethod& operator=(const OatMethod&) = default;
    184 
    185     // A representation of an invalid OatMethod, used when an OatMethod or OatClass can't be found.
    186     // See ClassLinker::FindOatMethodFor.
    187     static const OatMethod Invalid() {
    188       return OatMethod(nullptr, -1);
    189     }
    190 
    191    private:
    192     template<class T>
    193     T GetOatPointer(uint32_t offset) const {
    194       if (offset == 0) {
    195         return nullptr;
    196       }
    197       return reinterpret_cast<T>(begin_ + offset);
    198     }
    199 
    200     const uint8_t* begin_;
    201     uint32_t code_offset_;
    202 
    203     friend class OatClass;
    204   };
    205 
    206   class OatClass FINAL {
    207    public:
    208     ClassStatus GetStatus() const {
    209       return status_;
    210     }
    211 
    212     OatClassType GetType() const {
    213       return type_;
    214     }
    215 
    216     // Get the OatMethod entry based on its index into the class
    217     // defintion. Direct methods come first, followed by virtual
    218     // methods. Note that runtime created methods such as miranda
    219     // methods are not included.
    220     const OatMethod GetOatMethod(uint32_t method_index) const;
    221 
    222     // Return a pointer to the OatMethodOffsets for the requested
    223     // method_index, or null if none is present. Note that most
    224     // callers should use GetOatMethod.
    225     const OatMethodOffsets* GetOatMethodOffsets(uint32_t method_index) const;
    226 
    227     // Return the offset from the start of the OatFile to the
    228     // OatMethodOffsets for the requested method_index, or 0 if none
    229     // is present. Note that most callers should use GetOatMethod.
    230     uint32_t GetOatMethodOffsetsOffset(uint32_t method_index) const;
    231 
    232     // A representation of an invalid OatClass, used when an OatClass can't be found.
    233     // See FindOatClass().
    234     static OatClass Invalid() {
    235       return OatClass(/* oat_file */ nullptr,
    236                       ClassStatus::kErrorUnresolved,
    237                       kOatClassNoneCompiled,
    238                       /* bitmap_size */ 0,
    239                       /* bitmap_pointer */ nullptr,
    240                       /* methods_pointer */ nullptr);
    241     }
    242 
    243    private:
    244     OatClass(const OatFile* oat_file,
    245              ClassStatus status,
    246              OatClassType type,
    247              uint32_t bitmap_size,
    248              const uint32_t* bitmap_pointer,
    249              const OatMethodOffsets* methods_pointer);
    250 
    251     const OatFile* const oat_file_;
    252 
    253     const ClassStatus status_;
    254 
    255     const OatClassType type_;
    256 
    257     const uint32_t* const bitmap_;
    258 
    259     const OatMethodOffsets* const methods_pointer_;
    260 
    261     friend class art::OatDexFile;
    262   };
    263 
    264   // Get the OatDexFile for the given dex_location within this oat file.
    265   // If dex_location_checksum is non-null, the OatDexFile will only be
    266   // returned if it has a matching checksum.
    267   // If error_msg is non-null and no OatDexFile is returned, error_msg will
    268   // be updated with a description of why no OatDexFile was returned.
    269   const OatDexFile* GetOatDexFile(const char* dex_location,
    270                                   const uint32_t* const dex_location_checksum,
    271                                   /*out*/std::string* error_msg = nullptr) const
    272       REQUIRES(!secondary_lookup_lock_);
    273 
    274   const std::vector<const OatDexFile*>& GetOatDexFiles() const {
    275     return oat_dex_files_storage_;
    276   }
    277 
    278   size_t Size() const {
    279     return End() - Begin();
    280   }
    281 
    282   bool Contains(const void* p) const {
    283     return p >= Begin() && p < End();
    284   }
    285 
    286   size_t BssSize() const {
    287     return BssEnd() - BssBegin();
    288   }
    289 
    290   size_t VdexSize() const {
    291     return VdexEnd() - VdexBegin();
    292   }
    293 
    294   size_t BssMethodsOffset() const {
    295     // Note: This is used only for symbolizer and needs to return a valid .bss offset.
    296     return (bss_methods_ != nullptr) ? bss_methods_ - BssBegin() : BssRootsOffset();
    297   }
    298 
    299   size_t BssRootsOffset() const {
    300     // Note: This is used only for symbolizer and needs to return a valid .bss offset.
    301     return (bss_roots_ != nullptr) ? bss_roots_ - BssBegin() : BssSize();
    302   }
    303 
    304   size_t DexSize() const {
    305     return DexEnd() - DexBegin();
    306   }
    307 
    308   const uint8_t* Begin() const;
    309   const uint8_t* End() const;
    310 
    311   const uint8_t* BssBegin() const;
    312   const uint8_t* BssEnd() const;
    313 
    314   const uint8_t* VdexBegin() const;
    315   const uint8_t* VdexEnd() const;
    316 
    317   const uint8_t* DexBegin() const;
    318   const uint8_t* DexEnd() const;
    319 
    320   ArrayRef<ArtMethod*> GetBssMethods() const;
    321   ArrayRef<GcRoot<mirror::Object>> GetBssGcRoots() const;
    322 
    323   // Returns the absolute dex location for the encoded relative dex location.
    324   //
    325   // If not null, abs_dex_location is used to resolve the absolute dex
    326   // location of relative dex locations encoded in the oat file.
    327   // For example, given absolute location "/data/app/foo/base.apk", encoded
    328   // dex locations "base.apk", "base.apk!classes2.dex", etc. would be resolved
    329   // to "/data/app/foo/base.apk", "/data/app/foo/base.apk!classes2.dex", etc.
    330   // Relative encoded dex locations that don't match the given abs_dex_location
    331   // are left unchanged.
    332   static std::string ResolveRelativeEncodedDexLocation(
    333       const char* abs_dex_location, const std::string& rel_dex_location);
    334 
    335   // Finds the associated oat class for a dex_file and descriptor. Returns an invalid OatClass on
    336   // error and sets found to false.
    337   static OatClass FindOatClass(const DexFile& dex_file, uint16_t class_def_idx, bool* found);
    338 
    339   VdexFile* GetVdexFile() const {
    340     return vdex_.get();
    341   }
    342 
    343   // Whether the OatFile embeds the Dex code.
    344   bool ContainsDexCode() const {
    345     return uncompressed_dex_files_ == nullptr;
    346   }
    347 
    348  protected:
    349   OatFile(const std::string& filename, bool executable);
    350 
    351  private:
    352   // The oat file name.
    353   //
    354   // The image will embed this to link its associated oat file.
    355   const std::string location_;
    356 
    357   // Pointer to the Vdex file with the Dex files for this Oat file.
    358   std::unique_ptr<VdexFile> vdex_;
    359 
    360   // Pointer to OatHeader.
    361   const uint8_t* begin_;
    362 
    363   // Pointer to end of oat region for bounds checking.
    364   const uint8_t* end_;
    365 
    366   // Pointer to the .bss section, if present, otherwise null.
    367   uint8_t* bss_begin_;
    368 
    369   // Pointer to the end of the .bss section, if present, otherwise null.
    370   uint8_t* bss_end_;
    371 
    372   // Pointer to the beginning of the ArtMethod*s in .bss section, if present, otherwise null.
    373   uint8_t* bss_methods_;
    374 
    375   // Pointer to the beginning of the GC roots in .bss section, if present, otherwise null.
    376   uint8_t* bss_roots_;
    377 
    378   // Was this oat_file loaded executable?
    379   const bool is_executable_;
    380 
    381   // Pointer to the .vdex section, if present, otherwise null.
    382   uint8_t* vdex_begin_;
    383 
    384   // Pointer to the end of the .vdex section, if present, otherwise null.
    385   uint8_t* vdex_end_;
    386 
    387   // Owning storage for the OatDexFile objects.
    388   std::vector<const OatDexFile*> oat_dex_files_storage_;
    389 
    390   // NOTE: We use a StringPiece as the key type to avoid a memory allocation on every
    391   // lookup with a const char* key. The StringPiece doesn't own its backing storage,
    392   // therefore we're using the OatDexFile::dex_file_location_ as the backing storage
    393   // for keys in oat_dex_files_ and the string_cache_ entries for the backing storage
    394   // of keys in secondary_oat_dex_files_ and oat_dex_files_by_canonical_location_.
    395   typedef AllocationTrackingSafeMap<StringPiece, const OatDexFile*, kAllocatorTagOatFile> Table;
    396 
    397   // Map each location and canonical location (if different) retrieved from the
    398   // oat file to its OatDexFile. This map doesn't change after it's constructed in Setup()
    399   // and therefore doesn't need any locking and provides the cheapest dex file lookup
    400   // for GetOatDexFile() for a very frequent use case. Never contains a null value.
    401   Table oat_dex_files_;
    402 
    403   // Lock guarding all members needed for secondary lookup in GetOatDexFile().
    404   mutable Mutex secondary_lookup_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
    405 
    406   // If the primary oat_dex_files_ lookup fails, use a secondary map. This map stores
    407   // the results of all previous secondary lookups, whether successful (non-null) or
    408   // failed (null). If it doesn't contain an entry we need to calculate the canonical
    409   // location and use oat_dex_files_by_canonical_location_.
    410   mutable Table secondary_oat_dex_files_ GUARDED_BY(secondary_lookup_lock_);
    411 
    412   // Cache of strings. Contains the backing storage for keys in the secondary_oat_dex_files_
    413   // and the lazily initialized oat_dex_files_by_canonical_location_.
    414   // NOTE: We're keeping references to contained strings in form of StringPiece and adding
    415   // new strings to the end. The adding of a new element must not touch any previously stored
    416   // elements. std::list<> and std::deque<> satisfy this requirement, std::vector<> doesn't.
    417   mutable std::list<std::string> string_cache_ GUARDED_BY(secondary_lookup_lock_);
    418 
    419   // Cache of dex files mapped directly from a location, in case the OatFile does
    420   // not embed the dex code.
    421   std::unique_ptr<std::vector<std::unique_ptr<const DexFile>>> uncompressed_dex_files_;
    422 
    423   friend class gc::collector::DummyOatFile;  // For modifying begin_ and end_.
    424   friend class OatClass;
    425   friend class art::OatDexFile;
    426   friend class OatDumper;  // For GetBase and GetLimit
    427   friend class OatFileBase;
    428   DISALLOW_COPY_AND_ASSIGN(OatFile);
    429 };
    430 
    431 // OatDexFile should be an inner class of OatFile. Unfortunately, C++ doesn't
    432 // support forward declarations of inner classes, and we want to
    433 // forward-declare OatDexFile so that we can store an opaque pointer to an
    434 // OatDexFile in DexFile.
    435 class OatDexFile FINAL {
    436  public:
    437   // Opens the DexFile referred to by this OatDexFile from within the containing OatFile.
    438   std::unique_ptr<const DexFile> OpenDexFile(std::string* error_msg) const;
    439 
    440   // May return null if the OatDexFile only contains a type lookup table. This case only happens
    441   // for the compiler to speed up compilation.
    442   const OatFile* GetOatFile() const {
    443     // Avoid pulling in runtime.h in the header file.
    444     if (kIsDebugBuild && oat_file_ == nullptr) {
    445       AssertAotCompiler();
    446     }
    447     return oat_file_;
    448   }
    449 
    450   // Returns the size of the DexFile refered to by this OatDexFile.
    451   size_t FileSize() const;
    452 
    453   // Returns original path of DexFile that was the source of this OatDexFile.
    454   const std::string& GetDexFileLocation() const {
    455     return dex_file_location_;
    456   }
    457 
    458   // Returns the canonical location of DexFile that was the source of this OatDexFile.
    459   const std::string& GetCanonicalDexFileLocation() const {
    460     return canonical_dex_file_location_;
    461   }
    462 
    463   // Returns checksum of original DexFile that was the source of this OatDexFile;
    464   uint32_t GetDexFileLocationChecksum() const {
    465     return dex_file_location_checksum_;
    466   }
    467 
    468   // Returns the OatClass for the class specified by the given DexFile class_def_index.
    469   OatFile::OatClass GetOatClass(uint16_t class_def_index) const;
    470 
    471   // Returns the offset to the OatClass information. Most callers should use GetOatClass.
    472   uint32_t GetOatClassOffset(uint16_t class_def_index) const;
    473 
    474   const uint8_t* GetLookupTableData() const {
    475     return lookup_table_data_;
    476   }
    477 
    478   const IndexBssMapping* GetMethodBssMapping() const {
    479     return method_bss_mapping_;
    480   }
    481 
    482   const IndexBssMapping* GetTypeBssMapping() const {
    483     return type_bss_mapping_;
    484   }
    485 
    486   const IndexBssMapping* GetStringBssMapping() const {
    487     return string_bss_mapping_;
    488   }
    489 
    490   const uint8_t* GetDexFilePointer() const {
    491     return dex_file_pointer_;
    492   }
    493 
    494   // Looks up a class definition by its class descriptor. Hash must be
    495   // ComputeModifiedUtf8Hash(descriptor).
    496   static const DexFile::ClassDef* FindClassDef(const DexFile& dex_file,
    497                                                const char* descriptor,
    498                                                size_t hash);
    499 
    500   // Madvise the dex file based on the state we are moving to.
    501   static void MadviseDexFile(const DexFile& dex_file, MadviseState state);
    502 
    503   TypeLookupTable* GetTypeLookupTable() const {
    504     return lookup_table_.get();
    505   }
    506 
    507   ~OatDexFile();
    508 
    509   // Create only with a type lookup table, used by the compiler to speed up compilation.
    510   explicit OatDexFile(std::unique_ptr<TypeLookupTable>&& lookup_table);
    511 
    512   // Return the dex layout sections.
    513   const DexLayoutSections* GetDexLayoutSections() const {
    514     return dex_layout_sections_;
    515   }
    516 
    517  private:
    518   OatDexFile(const OatFile* oat_file,
    519              const std::string& dex_file_location,
    520              const std::string& canonical_dex_file_location,
    521              uint32_t dex_file_checksum,
    522              const uint8_t* dex_file_pointer,
    523              const uint8_t* lookup_table_data,
    524              const IndexBssMapping* method_bss_mapping,
    525              const IndexBssMapping* type_bss_mapping,
    526              const IndexBssMapping* string_bss_mapping,
    527              const uint32_t* oat_class_offsets_pointer,
    528              const DexLayoutSections* dex_layout_sections);
    529 
    530   static void AssertAotCompiler();
    531 
    532   const OatFile* const oat_file_ = nullptr;
    533   const std::string dex_file_location_;
    534   const std::string canonical_dex_file_location_;
    535   const uint32_t dex_file_location_checksum_ = 0u;
    536   const uint8_t* const dex_file_pointer_ = nullptr;
    537   const uint8_t* const lookup_table_data_ = nullptr;
    538   const IndexBssMapping* const method_bss_mapping_ = nullptr;
    539   const IndexBssMapping* const type_bss_mapping_ = nullptr;
    540   const IndexBssMapping* const string_bss_mapping_ = nullptr;
    541   const uint32_t* const oat_class_offsets_pointer_ = 0u;
    542   mutable std::unique_ptr<TypeLookupTable> lookup_table_;
    543   const DexLayoutSections* const dex_layout_sections_ = nullptr;
    544 
    545   friend class OatFile;
    546   friend class OatFileBase;
    547   DISALLOW_COPY_AND_ASSIGN(OatDexFile);
    548 };
    549 
    550 }  // namespace art
    551 
    552 #endif  // ART_RUNTIME_OAT_FILE_H_
    553