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