• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  
IsExecutable()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  
GetLocation()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
OatMethod(const uint8_t * base,const uint32_t code_offset)181      OatMethod(const uint8_t* base, const uint32_t code_offset)
182          : begin_(base), code_offset_(code_offset) {
183      }
184      OatMethod(const OatMethod&) = default;
~OatMethod()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.
Invalid()191      static const OatMethod Invalid() {
192        return OatMethod(nullptr, -1);
193      }
194  
195     private:
196      template<class T>
GetOatPointer(uint32_t offset)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:
GetStatus()212      ClassStatus GetStatus() const {
213        return status_;
214      }
215  
GetType()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().
Invalid()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  
GetOatDexFiles()278    const std::vector<const OatDexFile*>& GetOatDexFiles() const {
279      return oat_dex_files_storage_;
280    }
281  
Size()282    size_t Size() const {
283      return End() - Begin();
284    }
285  
Contains(const void * p)286    bool Contains(const void* p) const {
287      return p >= Begin() && p < End();
288    }
289  
DataBimgRelRoSize()290    size_t DataBimgRelRoSize() const {
291      return DataBimgRelRoEnd() - DataBimgRelRoBegin();
292    }
293  
BssSize()294    size_t BssSize() const {
295      return BssEnd() - BssBegin();
296    }
297  
VdexSize()298    size_t VdexSize() const {
299      return VdexEnd() - VdexBegin();
300    }
301  
BssMethodsOffset()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  
BssRootsOffset()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  
DexSize()312    size_t DexSize() const {
313      return DexEnd() - DexBegin();
314    }
315  
316    const uint8_t* Begin() const;
317    const uint8_t* End() const;
318  
DataBimgRelRoBegin()319    const uint8_t* DataBimgRelRoBegin() const { return data_bimg_rel_ro_begin_; }
DataBimgRelRoEnd()320    const uint8_t* DataBimgRelRoEnd() const { return data_bimg_rel_ro_end_; }
321  
BssBegin()322    const uint8_t* BssBegin() const { return bss_begin_; }
BssEnd()323    const uint8_t* BssEnd() const { return bss_end_; }
324  
VdexBegin()325    const uint8_t* VdexBegin() const { return vdex_begin_; }
VdexEnd()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  
GetVdexFile()364    VdexFile* GetVdexFile() const {
365      return vdex_.get();
366    }
367  
368    // Whether the OatFile embeds the Dex code.
ContainsDexCode()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.
GetOatFile()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.
GetDexFileLocation()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.
GetCanonicalDexFileLocation()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;
GetDexFileLocationChecksum()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  
GetLookupTableData()508    const uint8_t* GetLookupTableData() const {
509      return lookup_table_data_;
510    }
511  
GetMethodBssMapping()512    const IndexBssMapping* GetMethodBssMapping() const {
513      return method_bss_mapping_;
514    }
515  
GetTypeBssMapping()516    const IndexBssMapping* GetTypeBssMapping() const {
517      return type_bss_mapping_;
518    }
519  
GetStringBssMapping()520    const IndexBssMapping* GetStringBssMapping() const {
521      return string_bss_mapping_;
522    }
523  
GetDexFilePointer()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  
GetTypeLookupTable()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.
GetDexLayoutSections()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