1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ART_RUNTIME_OAT_FILE_H_
18 #define ART_RUNTIME_OAT_FILE_H_
19 
20 #include <list>
21 #include <string>
22 #include <vector>
23 
24 #include "base/mutex.h"
25 #include "base/stringpiece.h"
26 #include "dex_file.h"
27 #include "invoke_type.h"
28 #include "mem_map.h"
29 #include "mirror/class.h"
30 #include "oat.h"
31 #include "os.h"
32 
33 namespace art {
34 
35 class BitVector;
36 class ElfFile;
37 class MemMap;
38 class OatMethodOffsets;
39 class OatHeader;
40 class OatDexFile;
41 
42 class OatFile FINAL {
43  public:
44   typedef art::OatDexFile OatDexFile;
45 
46   // Opens an oat file contained within the given elf file. This is always opened as
47   // non-executable at the moment.
48   static OatFile* OpenWithElfFile(ElfFile* elf_file, const std::string& location,
49                                   const char* abs_dex_location,
50                                   std::string* error_msg);
51   // Open an oat file. Returns null on failure.  Requested base can
52   // optionally be used to request where the file should be loaded.
53   // See the ResolveRelativeEncodedDexLocation for a description of how the
54   // abs_dex_location argument is used.
55   static OatFile* Open(const std::string& filename,
56                        const std::string& location,
57                        uint8_t* requested_base,
58                        uint8_t* oat_file_begin,
59                        bool executable,
60                        const char* abs_dex_location,
61                        std::string* error_msg);
62 
63   // Open an oat file from an already opened File.
64   // Does not use dlopen underneath so cannot be used for runtime use
65   // where relocations may be required. Currently used from
66   // ImageWriter which wants to open a writable version from an existing
67   // file descriptor for patching.
68   static OatFile* OpenWritable(File* file, const std::string& location,
69                                const char* abs_dex_location,
70                                std::string* error_msg);
71   // Opens an oat file from an already opened File. Maps it PROT_READ, MAP_PRIVATE.
72   static OatFile* OpenReadable(File* file, const std::string& location,
73                                const char* abs_dex_location,
74                                std::string* error_msg);
75 
76   ~OatFile();
77 
IsExecutable()78   bool IsExecutable() const {
79     return is_executable_;
80   }
81 
82   bool IsPic() const;
83 
84   // Indicates whether the oat file was compiled with full debugging capability.
85   bool IsDebuggable() const;
86 
GetElfFile()87   ElfFile* GetElfFile() const {
88     CHECK_NE(reinterpret_cast<uintptr_t>(elf_file_.get()), reinterpret_cast<uintptr_t>(nullptr))
89         << "Cannot get an elf file from " << GetLocation();
90     return elf_file_.get();
91   }
92 
GetLocation()93   const std::string& GetLocation() const {
94     return location_;
95   }
96 
97   const OatHeader& GetOatHeader() const;
98 
99   class OatMethod FINAL {
100    public:
101     void LinkMethod(ArtMethod* method) const;
102 
GetCodeOffset()103     uint32_t GetCodeOffset() const {
104       return code_offset_;
105     }
106 
GetQuickCode()107     const void* GetQuickCode() const {
108       return GetOatPointer<const void*>(code_offset_);
109     }
110 
111     // Returns size of quick code.
112     uint32_t GetQuickCodeSize() const;
113     uint32_t GetQuickCodeSizeOffset() const;
114 
115     // Returns OatQuickMethodHeader for debugging. Most callers should
116     // use more specific methods such as GetQuickCodeSize.
117     const OatQuickMethodHeader* GetOatQuickMethodHeader() const;
118     uint32_t GetOatQuickMethodHeaderOffset() const;
119 
120     size_t GetFrameSizeInBytes() const;
121     uint32_t GetCoreSpillMask() const;
122     uint32_t GetFpSpillMask() const;
123 
124     const uint8_t* GetMappingTable() const;
125     uint32_t GetMappingTableOffset() const;
126     uint32_t GetMappingTableOffsetOffset() const;
127 
128     const uint8_t* GetVmapTable() const;
129     uint32_t GetVmapTableOffset() const;
130     uint32_t GetVmapTableOffsetOffset() const;
131 
132     const uint8_t* GetGcMap() const;
133     uint32_t GetGcMapOffset() const;
134     uint32_t GetGcMapOffsetOffset() const;
135 
136     // Create an OatMethod with offsets relative to the given base address
OatMethod(const uint8_t * base,const uint32_t code_offset)137     OatMethod(const uint8_t* base, const uint32_t code_offset)
138         : begin_(base), code_offset_(code_offset) {
139     }
140     OatMethod(const OatMethod&) = default;
~OatMethod()141     ~OatMethod() {}
142 
143     OatMethod& operator=(const OatMethod&) = default;
144 
145     // A representation of an invalid OatMethod, used when an OatMethod or OatClass can't be found.
146     // See ClassLinker::FindOatMethodFor.
Invalid()147     static const OatMethod Invalid() {
148       return OatMethod(nullptr, -1);
149     }
150 
151    private:
152     template<class T>
GetOatPointer(uint32_t offset)153     T GetOatPointer(uint32_t offset) const {
154       if (offset == 0) {
155         return nullptr;
156       }
157       return reinterpret_cast<T>(begin_ + offset);
158     }
159 
160     const uint8_t* begin_;
161     uint32_t code_offset_;
162 
163     friend class OatClass;
164   };
165 
166   class OatClass FINAL {
167    public:
GetStatus()168     mirror::Class::Status GetStatus() const {
169       return status_;
170     }
171 
GetType()172     OatClassType GetType() const {
173       return type_;
174     }
175 
176     // Get the OatMethod entry based on its index into the class
177     // defintion. Direct methods come first, followed by virtual
178     // methods. Note that runtime created methods such as miranda
179     // methods are not included.
180     const OatMethod GetOatMethod(uint32_t method_index) const;
181 
182     // Return a pointer to the OatMethodOffsets for the requested
183     // method_index, or null if none is present. Note that most
184     // callers should use GetOatMethod.
185     const OatMethodOffsets* GetOatMethodOffsets(uint32_t method_index) const;
186 
187     // Return the offset from the start of the OatFile to the
188     // OatMethodOffsets for the requested method_index, or 0 if none
189     // is present. Note that most callers should use GetOatMethod.
190     uint32_t GetOatMethodOffsetsOffset(uint32_t method_index) const;
191 
192     // A representation of an invalid OatClass, used when an OatClass can't be found.
193     // See ClassLinker::FindOatClass.
Invalid()194     static OatClass Invalid() {
195       return OatClass(nullptr, mirror::Class::kStatusError, kOatClassNoneCompiled, 0, nullptr,
196                       nullptr);
197     }
198 
199    private:
200     OatClass(const OatFile* oat_file,
201              mirror::Class::Status status,
202              OatClassType type,
203              uint32_t bitmap_size,
204              const uint32_t* bitmap_pointer,
205              const OatMethodOffsets* methods_pointer);
206 
207     const OatFile* const oat_file_;
208 
209     const mirror::Class::Status status_;
210 
211     const OatClassType type_;
212 
213     const uint32_t* const bitmap_;
214 
215     const OatMethodOffsets* const methods_pointer_;
216 
217     friend class art::OatDexFile;
218   };
219   const OatDexFile* GetOatDexFile(const char* dex_location,
220                                   const uint32_t* const dex_location_checksum,
221                                   bool exception_if_not_found = true) const
222       LOCKS_EXCLUDED(secondary_lookup_lock_);
223 
GetOatDexFiles()224   const std::vector<const OatDexFile*>& GetOatDexFiles() const {
225     return oat_dex_files_storage_;
226   }
227 
Size()228   size_t Size() const {
229     return End() - Begin();
230   }
231 
BssSize()232   size_t BssSize() const {
233     return BssEnd() - BssBegin();
234   }
235 
236   const uint8_t* Begin() const;
237   const uint8_t* End() const;
238 
239   const uint8_t* BssBegin() const;
240   const uint8_t* BssEnd() const;
241 
242   // Returns the absolute dex location for the encoded relative dex location.
243   //
244   // If not null, abs_dex_location is used to resolve the absolute dex
245   // location of relative dex locations encoded in the oat file.
246   // For example, given absolute location "/data/app/foo/base.apk", encoded
247   // dex locations "base.apk", "base.apk:classes2.dex", etc. would be resolved
248   // to "/data/app/foo/base.apk", "/data/app/foo/base.apk:classes2.dex", etc.
249   // Relative encoded dex locations that don't match the given abs_dex_location
250   // are left unchanged.
251   static std::string ResolveRelativeEncodedDexLocation(
252       const char* abs_dex_location, const std::string& rel_dex_location);
253 
254   // Create a dependency list (dex locations and checksums) for the given dex files.
255   static std::string EncodeDexFileDependencies(const std::vector<const DexFile*>& dex_files);
256 
257   // Check the given dependency list against their dex files - thus the name "Static," this does
258   // not check the class-loader environment, only whether there have been file updates.
259   static bool CheckStaticDexFileDependencies(const char* dex_dependencies, std::string* msg);
260 
261   // Get the dex locations of a dependency list. Note: this is *not* cleaned for synthetic
262   // locations of multidex files.
263   static bool GetDexLocationsFromDependencies(const char* dex_dependencies,
264                                               std::vector<std::string>* locations);
265 
266  private:
267   static void CheckLocation(const std::string& location);
268 
269   static OatFile* OpenDlopen(const std::string& elf_filename,
270                              const std::string& location,
271                              uint8_t* requested_base,
272                              const char* abs_dex_location,
273                              std::string* error_msg);
274 
275   static OatFile* OpenElfFile(File* file,
276                               const std::string& location,
277                               uint8_t* requested_base,
278                               uint8_t* oat_file_begin,  // Override base if not null
279                               bool writable,
280                               bool executable,
281                               const char* abs_dex_location,
282                               std::string* error_msg);
283 
284   explicit OatFile(const std::string& filename, bool executable);
285   bool Dlopen(const std::string& elf_filename, uint8_t* requested_base,
286               const char* abs_dex_location, std::string* error_msg);
287   bool ElfFileOpen(File* file, uint8_t* requested_base,
288                    uint8_t* oat_file_begin,  // Override where the file is loaded to if not null
289                    bool writable, bool executable,
290                    const char* abs_dex_location,
291                    std::string* error_msg);
292 
293   bool Setup(const char* abs_dex_location, std::string* error_msg);
294 
295   // The oat file name.
296   //
297   // The image will embed this to link its associated oat file.
298   const std::string location_;
299 
300   // Pointer to OatHeader.
301   const uint8_t* begin_;
302 
303   // Pointer to end of oat region for bounds checking.
304   const uint8_t* end_;
305 
306   // Pointer to the .bss section, if present, otherwise null.
307   const uint8_t* bss_begin_;
308 
309   // Pointer to the end of the .bss section, if present, otherwise null.
310   const uint8_t* bss_end_;
311 
312   // Was this oat_file loaded executable?
313   const bool is_executable_;
314 
315   // Backing memory map for oat file during when opened by ElfWriter during initial compilation.
316   std::unique_ptr<MemMap> mem_map_;
317 
318   // Backing memory map for oat file during cross compilation.
319   std::unique_ptr<ElfFile> elf_file_;
320 
321   // dlopen handle during runtime.
322   void* dlopen_handle_;
323 
324   // Dummy memory map objects corresponding to the regions mapped by dlopen.
325   std::vector<std::unique_ptr<MemMap>> dlopen_mmaps_;
326 
327   // Owning storage for the OatDexFile objects.
328   std::vector<const OatDexFile*> oat_dex_files_storage_;
329 
330   // NOTE: We use a StringPiece as the key type to avoid a memory allocation on every
331   // lookup with a const char* key. The StringPiece doesn't own its backing storage,
332   // therefore we're using the OatDexFile::dex_file_location_ as the backing storage
333   // for keys in oat_dex_files_ and the string_cache_ entries for the backing storage
334   // of keys in secondary_oat_dex_files_ and oat_dex_files_by_canonical_location_.
335   typedef AllocationTrackingSafeMap<StringPiece, const OatDexFile*, kAllocatorTagOatFile> Table;
336 
337   // Map each location and canonical location (if different) retrieved from the
338   // oat file to its OatDexFile. This map doesn't change after it's constructed in Setup()
339   // and therefore doesn't need any locking and provides the cheapest dex file lookup
340   // for GetOatDexFile() for a very frequent use case. Never contains a null value.
341   Table oat_dex_files_;
342 
343   // Lock guarding all members needed for secondary lookup in GetOatDexFile().
344   mutable Mutex secondary_lookup_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
345 
346   // If the primary oat_dex_files_ lookup fails, use a secondary map. This map stores
347   // the results of all previous secondary lookups, whether successful (non-null) or
348   // failed (null). If it doesn't contain an entry we need to calculate the canonical
349   // location and use oat_dex_files_by_canonical_location_.
350   mutable Table secondary_oat_dex_files_ GUARDED_BY(secondary_lookup_lock_);
351 
352   // Cache of strings. Contains the backing storage for keys in the secondary_oat_dex_files_
353   // and the lazily initialized oat_dex_files_by_canonical_location_.
354   // NOTE: We're keeping references to contained strings in form of StringPiece and adding
355   // new strings to the end. The adding of a new element must not touch any previously stored
356   // elements. std::list<> and std::deque<> satisfy this requirement, std::vector<> doesn't.
357   mutable std::list<std::string> string_cache_ GUARDED_BY(secondary_lookup_lock_);
358 
359   friend class OatClass;
360   friend class art::OatDexFile;
361   friend class OatDumper;  // For GetBase and GetLimit
362   DISALLOW_COPY_AND_ASSIGN(OatFile);
363 };
364 
365 // OatDexFile should be an inner class of OatFile. Unfortunately, C++ doesn't
366 // support forward declarations of inner classes, and we want to
367 // forward-declare OatDexFile so that we can store an opaque pointer to an
368 // OatDexFile in DexFile.
369 class OatDexFile FINAL {
370  public:
371   // Opens the DexFile referred to by this OatDexFile from within the containing OatFile.
372   std::unique_ptr<const DexFile> OpenDexFile(std::string* error_msg) const;
373 
GetOatFile()374   const OatFile* GetOatFile() const {
375     return oat_file_;
376   }
377 
378   // Returns the size of the DexFile refered to by this OatDexFile.
379   size_t FileSize() const;
380 
381   // Returns original path of DexFile that was the source of this OatDexFile.
GetDexFileLocation()382   const std::string& GetDexFileLocation() const {
383     return dex_file_location_;
384   }
385 
386   // Returns the canonical location of DexFile that was the source of this OatDexFile.
GetCanonicalDexFileLocation()387   const std::string& GetCanonicalDexFileLocation() const {
388     return canonical_dex_file_location_;
389   }
390 
391   // Returns checksum of original DexFile that was the source of this OatDexFile;
GetDexFileLocationChecksum()392   uint32_t GetDexFileLocationChecksum() const {
393     return dex_file_location_checksum_;
394   }
395 
396   // Returns the OatClass for the class specified by the given DexFile class_def_index.
397   OatFile::OatClass GetOatClass(uint16_t class_def_index) const;
398 
399   // Returns the offset to the OatClass information. Most callers should use GetOatClass.
400   uint32_t GetOatClassOffset(uint16_t class_def_index) const;
401 
402   ~OatDexFile();
403 
404  private:
405   OatDexFile(const OatFile* oat_file,
406              const std::string& dex_file_location,
407              const std::string& canonical_dex_file_location,
408              uint32_t dex_file_checksum,
409              const uint8_t* dex_file_pointer,
410              const uint32_t* oat_class_offsets_pointer);
411 
412   const OatFile* const oat_file_;
413   const std::string dex_file_location_;
414   const std::string canonical_dex_file_location_;
415   const uint32_t dex_file_location_checksum_;
416   const uint8_t* const dex_file_pointer_;
417   const uint32_t* const oat_class_offsets_pointer_;
418 
419   friend class OatFile;
420   DISALLOW_COPY_AND_ASSIGN(OatDexFile);
421 };
422 
423 }  // namespace art
424 
425 #endif  // ART_RUNTIME_OAT_FILE_H_
426