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