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 
41 class OatFile {
42  public:
43   // Opens an oat file contained within the given elf file. This is always opened as
44   // non-executable at the moment.
45   static OatFile* OpenWithElfFile(ElfFile* elf_file, const std::string& location,
46                                   std::string* error_msg);
47   // Open an oat file. Returns NULL on failure.  Requested base can
48   // optionally be used to request where the file should be loaded.
49   static OatFile* Open(const std::string& filename,
50                        const std::string& location,
51                        byte* requested_base,
52                        uint8_t* oat_file_begin,
53                        bool executable,
54                        std::string* error_msg);
55 
56   // Open an oat file from an already opened File.
57   // Does not use dlopen underneath so cannot be used for runtime use
58   // where relocations may be required. Currently used from
59   // ImageWriter which wants to open a writable version from an existing
60   // file descriptor for patching.
61   static OatFile* OpenWritable(File* file, const std::string& location, std::string* error_msg);
62   // Opens an oat file from an already opened File. Maps it PROT_READ, MAP_PRIVATE.
63   static OatFile* OpenReadable(File* file, const std::string& location, std::string* error_msg);
64 
65   // Open an oat file backed by a std::vector with the given location.
66   static OatFile* OpenMemory(std::vector<uint8_t>& oat_contents,
67                              const std::string& location,
68                              std::string* error_msg);
69 
70   ~OatFile();
71 
IsExecutable()72   bool IsExecutable() const {
73     return is_executable_;
74   }
75 
76   bool IsPic() const;
77 
GetElfFile()78   ElfFile* GetElfFile() const {
79     CHECK_NE(reinterpret_cast<uintptr_t>(elf_file_.get()), reinterpret_cast<uintptr_t>(nullptr))
80         << "Cannot get an elf file from " << GetLocation();
81     return elf_file_.get();
82   }
83 
GetLocation()84   const std::string& GetLocation() const {
85     return location_;
86   }
87 
88   const OatHeader& GetOatHeader() const;
89 
90   class OatDexFile;
91 
92   class OatMethod {
93    public:
94     void LinkMethod(mirror::ArtMethod* method) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
95 
GetCodeOffset()96     uint32_t GetCodeOffset() const {
97       return code_offset_;
98     }
99 
GetPortableCode()100     const void* GetPortableCode() const {
101       // TODO: encode whether code is portable/quick in flags within OatMethod.
102       if (kUsePortableCompiler) {
103         return GetOatPointer<const void*>(code_offset_);
104       } else {
105         return nullptr;
106       }
107     }
108 
GetQuickCode()109     const void* GetQuickCode() const {
110       if (kUsePortableCompiler) {
111         return nullptr;
112       } else {
113         return GetOatPointer<const void*>(code_offset_);
114       }
115     }
116 
117     // Returns 0.
GetPortableCodeSize()118     uint32_t GetPortableCodeSize() const {
119       // TODO: With Quick, we store the size before the code. With Portable, the code is in a .o
120       // file we don't manage ourselves. ELF symbols do have a concept of size, so we could capture
121       // that and store it somewhere, such as the OatMethod.
122       return 0;
123     }
124 
125     // Returns size of quick code.
126     uint32_t GetQuickCodeSize() const;
127     uint32_t GetQuickCodeSizeOffset() const;
128 
129     // Returns OatQuickMethodHeader for debugging. Most callers should
130     // use more specific methods such as GetQuickCodeSize.
131     const OatQuickMethodHeader* GetOatQuickMethodHeader() const;
132     uint32_t GetOatQuickMethodHeaderOffset() const;
133 
134     size_t GetFrameSizeInBytes() const;
135     uint32_t GetCoreSpillMask() const;
136     uint32_t GetFpSpillMask() const;
137 
138     const uint8_t* GetMappingTable() const;
139     uint32_t GetMappingTableOffset() const;
140     uint32_t GetMappingTableOffsetOffset() const;
141 
142     const uint8_t* GetVmapTable() const;
143     uint32_t GetVmapTableOffset() const;
144     uint32_t GetVmapTableOffsetOffset() const;
145 
146     const uint8_t* GetGcMap() const;
147     uint32_t GetGcMapOffset() const;
148     uint32_t GetGcMapOffsetOffset() const;
149 
150     ~OatMethod();
151 
152     // Create an OatMethod with offsets relative to the given base address
153     OatMethod(const byte* base, const uint32_t code_offset);
154 
OatMethod()155     OatMethod() {}
156 
157    private:
158     template<class T>
GetOatPointer(uint32_t offset)159     T GetOatPointer(uint32_t offset) const {
160       if (offset == 0) {
161         return NULL;
162       }
163       return reinterpret_cast<T>(begin_ + offset);
164     }
165 
166     const byte* begin_;
167 
168     uint32_t code_offset_;
169 
170     friend class OatClass;
171   };
172 
173   class OatClass {
174    public:
GetStatus()175     mirror::Class::Status GetStatus() const {
176       return status_;
177     }
178 
GetType()179     OatClassType GetType() const {
180       return type_;
181     }
182 
183     // Get the OatMethod entry based on its index into the class
184     // defintion. Direct methods come first, followed by virtual
185     // methods. Note that runtime created methods such as miranda
186     // methods are not included.
187     const OatMethod GetOatMethod(uint32_t method_index) const;
188 
189     // Return a pointer to the OatMethodOffsets for the requested
190     // method_index, or nullptr if none is present. Note that most
191     // callers should use GetOatMethod.
192     const OatMethodOffsets* GetOatMethodOffsets(uint32_t method_index) const;
193 
194     // Return the offset from the start of the OatFile to the
195     // OatMethodOffsets for the requested method_index, or 0 if none
196     // is present. Note that most callers should use GetOatMethod.
197     uint32_t GetOatMethodOffsetsOffset(uint32_t method_index) const;
198 
OatClass()199     OatClass() {}
200 
201    private:
202     OatClass(const OatFile* oat_file,
203              mirror::Class::Status status,
204              OatClassType type,
205              uint32_t bitmap_size,
206              const uint32_t* bitmap_pointer,
207              const OatMethodOffsets* methods_pointer);
208 
209     const OatFile* oat_file_;
210 
211     mirror::Class::Status status_;
212 
213     OatClassType type_;
214 
215     const uint32_t* bitmap_;
216 
217     const OatMethodOffsets* methods_pointer_;
218 
219     friend class OatDexFile;
220   };
221 
222   class OatDexFile {
223    public:
224     // Opens the DexFile referred to by this OatDexFile from within the containing OatFile.
225     const DexFile* OpenDexFile(std::string* error_msg) const;
226 
GetOatFile()227     const OatFile* GetOatFile() const {
228       return oat_file_;
229     }
230 
231     // Returns the size of the DexFile refered to by this OatDexFile.
232     size_t FileSize() const;
233 
234     // Returns original path of DexFile that was the source of this OatDexFile.
GetDexFileLocation()235     const std::string& GetDexFileLocation() const {
236       return dex_file_location_;
237     }
238 
239     // Returns the canonical location of DexFile that was the source of this OatDexFile.
GetCanonicalDexFileLocation()240     const std::string& GetCanonicalDexFileLocation() const {
241       return canonical_dex_file_location_;
242     }
243 
244     // Returns checksum of original DexFile that was the source of this OatDexFile;
GetDexFileLocationChecksum()245     uint32_t GetDexFileLocationChecksum() const {
246       return dex_file_location_checksum_;
247     }
248 
249     // Returns the OatClass for the class specified by the given DexFile class_def_index.
250     OatClass GetOatClass(uint16_t class_def_index) const;
251 
252     // Returns the offset to the OatClass information. Most callers should use GetOatClass.
253     uint32_t GetOatClassOffset(uint16_t class_def_index) const;
254 
255     ~OatDexFile();
256 
257    private:
258     OatDexFile(const OatFile* oat_file,
259                const std::string& dex_file_location,
260                const std::string& canonical_dex_file_location,
261                uint32_t dex_file_checksum,
262                const byte* dex_file_pointer,
263                const uint32_t* oat_class_offsets_pointer);
264 
265     const OatFile* const oat_file_;
266     const std::string dex_file_location_;
267     const std::string canonical_dex_file_location_;
268     const uint32_t dex_file_location_checksum_;
269     const byte* const dex_file_pointer_;
270     const uint32_t* const oat_class_offsets_pointer_;
271 
272     friend class OatFile;
273     DISALLOW_COPY_AND_ASSIGN(OatDexFile);
274   };
275 
276   const OatDexFile* GetOatDexFile(const char* dex_location,
277                                   const uint32_t* const dex_location_checksum,
278                                   bool exception_if_not_found = true) const
279       LOCKS_EXCLUDED(secondary_lookup_lock_);
280 
GetOatDexFiles()281   const std::vector<const OatDexFile*>& GetOatDexFiles() const {
282     return oat_dex_files_storage_;
283   }
284 
Size()285   size_t Size() const {
286     return End() - Begin();
287   }
288 
289   const byte* Begin() const;
290   const byte* End() const;
291 
292  private:
293   static void CheckLocation(const std::string& location);
294 
295   static OatFile* OpenDlopen(const std::string& elf_filename,
296                              const std::string& location,
297                              byte* requested_base,
298                              std::string* error_msg);
299 
300   static OatFile* OpenElfFile(File* file,
301                               const std::string& location,
302                               byte* requested_base,
303                               uint8_t* oat_file_begin,  // Override base if not null
304                               bool writable,
305                               bool executable,
306                               std::string* error_msg);
307 
308   explicit OatFile(const std::string& filename, bool executable);
309   bool Dlopen(const std::string& elf_filename, byte* requested_base, std::string* error_msg);
310   bool ElfFileOpen(File* file, byte* requested_base,
311                    uint8_t* oat_file_begin,  // Override where the file is loaded to if not null
312                    bool writable, bool executable,
313                    std::string* error_msg);
314   bool Setup(std::string* error_msg);
315 
316   // The oat file name.
317   //
318   // The image will embed this to link its associated oat file.
319   const std::string location_;
320 
321   // Pointer to OatHeader.
322   const byte* begin_;
323 
324   // Pointer to end of oat region for bounds checking.
325   const byte* end_;
326 
327   // Was this oat_file loaded executable?
328   const bool is_executable_;
329 
330   // Backing memory map for oat file during when opened by ElfWriter during initial compilation.
331   std::unique_ptr<MemMap> mem_map_;
332 
333   // Backing memory map for oat file during cross compilation.
334   std::unique_ptr<ElfFile> elf_file_;
335 
336   // dlopen handle during runtime.
337   void* dlopen_handle_;
338 
339   // Owning storage for the OatDexFile objects.
340   std::vector<const OatDexFile*> oat_dex_files_storage_;
341 
342   // NOTE: We use a StringPiece as the key type to avoid a memory allocation on every
343   // lookup with a const char* key. The StringPiece doesn't own its backing storage,
344   // therefore we're using the OatDexFile::dex_file_location_ as the backing storage
345   // for keys in oat_dex_files_ and the string_cache_ entries for the backing storage
346   // of keys in secondary_oat_dex_files_ and oat_dex_files_by_canonical_location_.
347   typedef AllocationTrackingSafeMap<StringPiece, const OatDexFile*, kAllocatorTagOatFile> Table;
348 
349   // Map each location and canonical location (if different) retrieved from the
350   // oat file to its OatDexFile. This map doesn't change after it's constructed in Setup()
351   // and therefore doesn't need any locking and provides the cheapest dex file lookup
352   // for GetOatDexFile() for a very frequent use case. Never contains a nullptr value.
353   Table oat_dex_files_;
354 
355   // Lock guarding all members needed for secondary lookup in GetOatDexFile().
356   mutable Mutex secondary_lookup_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
357 
358   // If the primary oat_dex_files_ lookup fails, use a secondary map. This map stores
359   // the results of all previous secondary lookups, whether successful (non-null) or
360   // failed (null). If it doesn't contain an entry we need to calculate the canonical
361   // location and use oat_dex_files_by_canonical_location_.
362   mutable Table secondary_oat_dex_files_ GUARDED_BY(secondary_lookup_lock_);
363 
364   // Cache of strings. Contains the backing storage for keys in the secondary_oat_dex_files_
365   // and the lazily initialized oat_dex_files_by_canonical_location_.
366   // NOTE: We're keeping references to contained strings in form of StringPiece and adding
367   // new strings to the end. The adding of a new element must not touch any previously stored
368   // elements. std::list<> and std::deque<> satisfy this requirement, std::vector<> doesn't.
369   mutable std::list<std::string> string_cache_ GUARDED_BY(secondary_lookup_lock_);
370 
371   friend class OatClass;
372   friend class OatDexFile;
373   friend class OatDumper;  // For GetBase and GetLimit
374   DISALLOW_COPY_AND_ASSIGN(OatFile);
375 };
376 
377 }  // namespace art
378 
379 #endif  // ART_RUNTIME_OAT_FILE_H_
380