• 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/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                        bool executable,
53                        std::string* error_msg);
54 
55   // Open an oat file from an already opened File.
56   // Does not use dlopen underneath so cannot be used for runtime use
57   // where relocations may be required. Currently used from
58   // ImageWriter which wants to open a writable version from an existing
59   // file descriptor for patching.
60   static OatFile* OpenWritable(File* file, const std::string& location, std::string* error_msg);
61   // Opens an oat file from an already opened File. Maps it PROT_READ, MAP_PRIVATE.
62   static OatFile* OpenReadable(File* file, const std::string& location, std::string* error_msg);
63 
64   // Open an oat file backed by a std::vector with the given location.
65   static OatFile* OpenMemory(std::vector<uint8_t>& oat_contents,
66                              const std::string& location,
67                              std::string* error_msg);
68 
69   ~OatFile();
70 
IsExecutable()71   bool IsExecutable() const {
72     return is_executable_;
73   }
74 
GetElfFile()75   ElfFile* GetElfFile() const {
76     CHECK_NE(reinterpret_cast<uintptr_t>(elf_file_.get()), reinterpret_cast<uintptr_t>(nullptr))
77         << "Cannot get an elf file from " << GetLocation();
78     return elf_file_.get();
79   }
80 
GetLocation()81   const std::string& GetLocation() const {
82     return location_;
83   }
84 
85   const OatHeader& GetOatHeader() const;
86 
87   class OatDexFile;
88 
89   class OatMethod {
90    public:
91     void LinkMethod(mirror::ArtMethod* method) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
92 
GetCodeOffset()93     uint32_t GetCodeOffset() const {
94       return code_offset_;
95     }
GetNativeGcMapOffset()96     uint32_t GetNativeGcMapOffset() const {
97       return native_gc_map_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 
GetNativeGcMap()134     const uint8_t* GetNativeGcMap() const {
135       return GetOatPointer<const uint8_t*>(native_gc_map_offset_);
136     }
137 
138     size_t GetFrameSizeInBytes() const;
139     uint32_t GetCoreSpillMask() const;
140     uint32_t GetFpSpillMask() const;
141 
142     const uint8_t* GetMappingTable() const;
143     uint32_t GetMappingTableOffset() const;
144     uint32_t GetMappingTableOffsetOffset() const;
145 
146     const uint8_t* GetVmapTable() const;
147     uint32_t GetVmapTableOffset() const;
148     uint32_t GetVmapTableOffsetOffset() const;
149 
150     ~OatMethod();
151 
152     // Create an OatMethod with offsets relative to the given base address
153     OatMethod(const byte* base,
154               const uint32_t code_offset,
155               const uint32_t gc_map_offset);
156 
OatMethod()157     OatMethod() {}
158 
159    private:
160     template<class T>
GetOatPointer(uint32_t offset)161     T GetOatPointer(uint32_t offset) const {
162       if (offset == 0) {
163         return NULL;
164       }
165       return reinterpret_cast<T>(begin_ + offset);
166     }
167 
168     const byte* begin_;
169 
170     uint32_t code_offset_;
171     uint32_t native_gc_map_offset_;
172 
173     friend class OatClass;
174   };
175 
176   class OatClass {
177    public:
GetStatus()178     mirror::Class::Status GetStatus() const {
179       return status_;
180     }
181 
GetType()182     OatClassType GetType() const {
183       return type_;
184     }
185 
186     // Get the OatMethod entry based on its index into the class
187     // defintion. Direct methods come first, followed by virtual
188     // methods. Note that runtime created methods such as miranda
189     // methods are not included.
190     const OatMethod GetOatMethod(uint32_t method_index) const;
191 
192     // Return a pointer to the OatMethodOffsets for the requested
193     // method_index, or nullptr if none is present. Note that most
194     // callers should use GetOatMethod.
195     const OatMethodOffsets* GetOatMethodOffsets(uint32_t method_index) const;
196 
197     // Return the offset from the start of the OatFile to the
198     // OatMethodOffsets for the requested method_index, or 0 if none
199     // is present. Note that most callers should use GetOatMethod.
200     uint32_t GetOatMethodOffsetsOffset(uint32_t method_index) const;
201 
OatClass()202     OatClass() {}
203 
204    private:
205     OatClass(const OatFile* oat_file,
206              mirror::Class::Status status,
207              OatClassType type,
208              uint32_t bitmap_size,
209              const uint32_t* bitmap_pointer,
210              const OatMethodOffsets* methods_pointer);
211 
212     const OatFile* oat_file_;
213 
214     mirror::Class::Status status_;
215 
216     OatClassType type_;
217 
218     const uint32_t* bitmap_;
219 
220     const OatMethodOffsets* methods_pointer_;
221 
222     friend class OatDexFile;
223   };
224 
225   class OatDexFile {
226    public:
227     // Opens the DexFile referred to by this OatDexFile from within the containing OatFile.
228     const DexFile* OpenDexFile(std::string* error_msg) const;
229 
GetOatFile()230     const OatFile* GetOatFile() const {
231       return oat_file_;
232     }
233 
234     // Returns the size of the DexFile refered to by this OatDexFile.
235     size_t FileSize() const;
236 
237     // Returns original path of DexFile that was the source of this OatDexFile.
GetDexFileLocation()238     const std::string& GetDexFileLocation() const {
239       return dex_file_location_;
240     }
241 
242     // Returns the canonical location of DexFile that was the source of this OatDexFile.
GetCanonicalDexFileLocation()243     const std::string& GetCanonicalDexFileLocation() const {
244       return canonical_dex_file_location_;
245     }
246 
247     // Returns checksum of original DexFile that was the source of this OatDexFile;
GetDexFileLocationChecksum()248     uint32_t GetDexFileLocationChecksum() const {
249       return dex_file_location_checksum_;
250     }
251 
252     // Returns the OatClass for the class specified by the given DexFile class_def_index.
253     OatClass GetOatClass(uint16_t class_def_index) const;
254 
255     // Returns the offset to the OatClass information. Most callers should use GetOatClass.
256     uint32_t GetOatClassOffset(uint16_t class_def_index) const;
257 
258     ~OatDexFile();
259 
260    private:
261     OatDexFile(const OatFile* oat_file,
262                const std::string& dex_file_location,
263                const std::string& canonical_dex_file_location,
264                uint32_t dex_file_checksum,
265                const byte* dex_file_pointer,
266                const uint32_t* oat_class_offsets_pointer);
267 
268     const OatFile* const oat_file_;
269     const std::string dex_file_location_;
270     const std::string canonical_dex_file_location_;
271     const uint32_t dex_file_location_checksum_;
272     const byte* const dex_file_pointer_;
273     const uint32_t* const oat_class_offsets_pointer_;
274 
275     friend class OatFile;
276     DISALLOW_COPY_AND_ASSIGN(OatDexFile);
277   };
278 
279   const OatDexFile* GetOatDexFile(const char* dex_location,
280                                   const uint32_t* const dex_location_checksum,
281                                   bool exception_if_not_found = true) const
282       LOCKS_EXCLUDED(secondary_lookup_lock_);
283 
GetOatDexFiles()284   const std::vector<const OatDexFile*>& GetOatDexFiles() const {
285     return oat_dex_files_storage_;
286   }
287 
Size()288   size_t Size() const {
289     return End() - Begin();
290   }
291 
292   const byte* Begin() const;
293   const byte* End() const;
294 
295  private:
296   static void CheckLocation(const std::string& location);
297 
298   static OatFile* OpenDlopen(const std::string& elf_filename,
299                              const std::string& location,
300                              byte* requested_base,
301                              std::string* error_msg);
302 
303   static OatFile* OpenElfFile(File* file,
304                               const std::string& location,
305                               byte* requested_base,
306                               bool writable,
307                               bool executable,
308                               std::string* error_msg);
309 
310   explicit OatFile(const std::string& filename, bool executable);
311   bool Dlopen(const std::string& elf_filename, byte* requested_base, std::string* error_msg);
312   bool ElfFileOpen(File* file, byte* requested_base, 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