2 * Copyright (C) 2011 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #ifndef ART_RUNTIME_OAT_FILE_H_
18 #define ART_RUNTIME_OAT_FILE_H_
24 #include "base/mutex.h"
25 #include "base/stringpiece.h"
27 #include "invoke_type.h"
29 #include "mirror/class.h"
39 class OatMethodOffsets;
46 } // namespace collector
51 // Special classpath that skips shared library check.
52 static constexpr const char* kSpecialSharedLibrary = "&";
54 typedef art::OatDexFile OatDexFile;
56 // Opens an oat file contained within the given elf file. This is always opened as
57 // non-executable at the moment.
58 static OatFile* OpenWithElfFile(ElfFile* elf_file, const std::string& location,
59 const char* abs_dex_location,
60 std::string* error_msg);
61 // Open an oat file. Returns null on failure. Requested base can
62 // optionally be used to request where the file should be loaded.
63 // See the ResolveRelativeEncodedDexLocation for a description of how the
64 // abs_dex_location argument is used.
65 static OatFile* Open(const std::string& filename,
66 const std::string& location,
67 uint8_t* requested_base,
68 uint8_t* oat_file_begin,
71 const char* abs_dex_location,
72 std::string* error_msg);
74 // Open an oat file from an already opened File.
75 // Does not use dlopen underneath so cannot be used for runtime use
76 // where relocations may be required. Currently used from
77 // ImageWriter which wants to open a writable version from an existing
78 // file descriptor for patching.
79 static OatFile* OpenWritable(File* file, const std::string& location,
80 const char* abs_dex_location,
81 std::string* error_msg);
82 // Opens an oat file from an already opened File. Maps it PROT_READ, MAP_PRIVATE.
83 static OatFile* OpenReadable(File* file, const std::string& location,
84 const char* abs_dex_location,
85 std::string* error_msg);
89 bool IsExecutable() const {
90 return is_executable_;
93 bool HasPatchInfo() const;
97 // Indicates whether the oat file was compiled with full debugging capability.
98 bool IsDebuggable() const;
100 CompilerFilter::Filter GetCompilerFilter() const;
102 const std::string& GetLocation() const {
106 const OatHeader& GetOatHeader() const;
108 class OatMethod FINAL {
110 void LinkMethod(ArtMethod* method) const;
112 uint32_t GetCodeOffset() const;
114 const void* GetQuickCode() const;
116 // Returns size of quick code.
117 uint32_t GetQuickCodeSize() const;
118 uint32_t GetQuickCodeSizeOffset() const;
120 // Returns OatQuickMethodHeader for debugging. Most callers should
121 // use more specific methods such as GetQuickCodeSize.
122 const OatQuickMethodHeader* GetOatQuickMethodHeader() const;
123 uint32_t GetOatQuickMethodHeaderOffset() const;
125 size_t GetFrameSizeInBytes() const;
126 uint32_t GetCoreSpillMask() const;
127 uint32_t GetFpSpillMask() const;
129 const uint8_t* GetVmapTable() const;
130 uint32_t GetVmapTableOffset() const;
131 uint32_t GetVmapTableOffsetOffset() const;
133 // Create an OatMethod with offsets relative to the given base address
134 OatMethod(const uint8_t* base, const uint32_t code_offset)
135 : begin_(base), code_offset_(code_offset) {
137 OatMethod(const OatMethod&) = default;
140 OatMethod& operator=(const OatMethod&) = default;
142 // A representation of an invalid OatMethod, used when an OatMethod or OatClass can't be found.
143 // See ClassLinker::FindOatMethodFor.
144 static const OatMethod Invalid() {
145 return OatMethod(nullptr, -1);
150 T GetOatPointer(uint32_t offset) const {
154 return reinterpret_cast<T>(begin_ + offset);
157 const uint8_t* begin_;
158 uint32_t code_offset_;
160 friend class OatClass;
163 class OatClass FINAL {
165 mirror::Class::Status GetStatus() const {
169 OatClassType GetType() const {
173 // Get the OatMethod entry based on its index into the class
174 // defintion. Direct methods come first, followed by virtual
175 // methods. Note that runtime created methods such as miranda
176 // methods are not included.
177 const OatMethod GetOatMethod(uint32_t method_index) const;
179 // Return a pointer to the OatMethodOffsets for the requested
180 // method_index, or null if none is present. Note that most
181 // callers should use GetOatMethod.
182 const OatMethodOffsets* GetOatMethodOffsets(uint32_t method_index) const;
184 // Return the offset from the start of the OatFile to the
185 // OatMethodOffsets for the requested method_index, or 0 if none
186 // is present. Note that most callers should use GetOatMethod.
187 uint32_t GetOatMethodOffsetsOffset(uint32_t method_index) const;
189 // A representation of an invalid OatClass, used when an OatClass can't be found.
190 // See ClassLinker::FindOatClass.
191 static OatClass Invalid() {
192 return OatClass(nullptr, mirror::Class::kStatusError, kOatClassNoneCompiled, 0, nullptr,
197 OatClass(const OatFile* oat_file,
198 mirror::Class::Status status,
200 uint32_t bitmap_size,
201 const uint32_t* bitmap_pointer,
202 const OatMethodOffsets* methods_pointer);
204 const OatFile* const oat_file_;
206 const mirror::Class::Status status_;
208 const OatClassType type_;
210 const uint32_t* const bitmap_;
212 const OatMethodOffsets* const methods_pointer_;
214 friend class art::OatDexFile;
216 const OatDexFile* GetOatDexFile(const char* dex_location,
217 const uint32_t* const dex_location_checksum,
218 bool exception_if_not_found = true) const
219 REQUIRES(!secondary_lookup_lock_);
221 const std::vector<const OatDexFile*>& GetOatDexFiles() const {
222 return oat_dex_files_storage_;
225 size_t Size() const {
226 return End() - Begin();
229 bool Contains(const void* p) const {
230 return p >= Begin() && p < End();
233 size_t BssSize() const {
234 return BssEnd() - BssBegin();
237 const uint8_t* Begin() const;
238 const uint8_t* End() const;
240 const uint8_t* BssBegin() const;
241 const uint8_t* BssEnd() const;
243 // Returns the absolute dex location for the encoded relative dex location.
245 // If not null, abs_dex_location is used to resolve the absolute dex
246 // location of relative dex locations encoded in the oat file.
247 // For example, given absolute location "/data/app/foo/base.apk", encoded
248 // dex locations "base.apk", "base.apk:classes2.dex", etc. would be resolved
249 // to "/data/app/foo/base.apk", "/data/app/foo/base.apk:classes2.dex", etc.
250 // Relative encoded dex locations that don't match the given abs_dex_location
251 // are left unchanged.
252 static std::string ResolveRelativeEncodedDexLocation(
253 const char* abs_dex_location, const std::string& rel_dex_location);
255 // Create a dependency list (dex locations and checksums) for the given dex files.
256 static std::string EncodeDexFileDependencies(const std::vector<const DexFile*>& dex_files);
258 // Check the given dependency list against their dex files - thus the name "Static," this does
259 // not check the class-loader environment, only whether there have been file updates.
260 static bool CheckStaticDexFileDependencies(const char* dex_dependencies, std::string* msg);
262 // Get the dex locations of a dependency list. Note: this is *not* cleaned for synthetic
263 // locations of multidex files.
264 static bool GetDexLocationsFromDependencies(const char* dex_dependencies,
265 std::vector<std::string>* locations);
268 OatFile(const std::string& filename, bool executable);
271 // The oat file name.
273 // The image will embed this to link its associated oat file.
274 const std::string location_;
276 // Pointer to OatHeader.
277 const uint8_t* begin_;
279 // Pointer to end of oat region for bounds checking.
282 // Pointer to the .bss section, if present, otherwise null.
285 // Pointer to the end of the .bss section, if present, otherwise null.
288 // Was this oat_file loaded executable?
289 const bool is_executable_;
291 // Owning storage for the OatDexFile objects.
292 std::vector<const OatDexFile*> oat_dex_files_storage_;
294 // NOTE: We use a StringPiece as the key type to avoid a memory allocation on every
295 // lookup with a const char* key. The StringPiece doesn't own its backing storage,
296 // therefore we're using the OatDexFile::dex_file_location_ as the backing storage
297 // for keys in oat_dex_files_ and the string_cache_ entries for the backing storage
298 // of keys in secondary_oat_dex_files_ and oat_dex_files_by_canonical_location_.
299 typedef AllocationTrackingSafeMap<StringPiece, const OatDexFile*, kAllocatorTagOatFile> Table;
301 // Map each location and canonical location (if different) retrieved from the
302 // oat file to its OatDexFile. This map doesn't change after it's constructed in Setup()
303 // and therefore doesn't need any locking and provides the cheapest dex file lookup
304 // for GetOatDexFile() for a very frequent use case. Never contains a null value.
305 Table oat_dex_files_;
307 // Lock guarding all members needed for secondary lookup in GetOatDexFile().
308 mutable Mutex secondary_lookup_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
310 // If the primary oat_dex_files_ lookup fails, use a secondary map. This map stores
311 // the results of all previous secondary lookups, whether successful (non-null) or
312 // failed (null). If it doesn't contain an entry we need to calculate the canonical
313 // location and use oat_dex_files_by_canonical_location_.
314 mutable Table secondary_oat_dex_files_ GUARDED_BY(secondary_lookup_lock_);
316 // Cache of strings. Contains the backing storage for keys in the secondary_oat_dex_files_
317 // and the lazily initialized oat_dex_files_by_canonical_location_.
318 // NOTE: We're keeping references to contained strings in form of StringPiece and adding
319 // new strings to the end. The adding of a new element must not touch any previously stored
320 // elements. std::list<> and std::deque<> satisfy this requirement, std::vector<> doesn't.
321 mutable std::list<std::string> string_cache_ GUARDED_BY(secondary_lookup_lock_);
323 friend class gc::collector::DummyOatFile; // For modifying begin_ and end_.
324 friend class OatClass;
325 friend class art::OatDexFile;
326 friend class OatDumper; // For GetBase and GetLimit
327 friend class OatFileBase;
328 DISALLOW_COPY_AND_ASSIGN(OatFile);
331 // OatDexFile should be an inner class of OatFile. Unfortunately, C++ doesn't
332 // support forward declarations of inner classes, and we want to
333 // forward-declare OatDexFile so that we can store an opaque pointer to an
334 // OatDexFile in DexFile.
335 class OatDexFile FINAL {
337 // Opens the DexFile referred to by this OatDexFile from within the containing OatFile.
338 std::unique_ptr<const DexFile> OpenDexFile(std::string* error_msg) const;
340 const OatFile* GetOatFile() const {
344 // Returns the size of the DexFile refered to by this OatDexFile.
345 size_t FileSize() const;
347 // Returns original path of DexFile that was the source of this OatDexFile.
348 const std::string& GetDexFileLocation() const {
349 return dex_file_location_;
352 // Returns the canonical location of DexFile that was the source of this OatDexFile.
353 const std::string& GetCanonicalDexFileLocation() const {
354 return canonical_dex_file_location_;
357 // Returns checksum of original DexFile that was the source of this OatDexFile;
358 uint32_t GetDexFileLocationChecksum() const {
359 return dex_file_location_checksum_;
362 // Returns the OatClass for the class specified by the given DexFile class_def_index.
363 OatFile::OatClass GetOatClass(uint16_t class_def_index) const;
365 // Returns the offset to the OatClass information. Most callers should use GetOatClass.
366 uint32_t GetOatClassOffset(uint16_t class_def_index) const;
368 uint8_t* GetDexCacheArrays() const {
369 return dex_cache_arrays_;
372 const uint8_t* GetLookupTableData() const {
373 return lookup_table_data_;
376 const uint8_t* GetDexFilePointer() const {
377 return dex_file_pointer_;
383 OatDexFile(const OatFile* oat_file,
384 const std::string& dex_file_location,
385 const std::string& canonical_dex_file_location,
386 uint32_t dex_file_checksum,
387 const uint8_t* dex_file_pointer,
388 const uint8_t* lookup_table_data,
389 const uint32_t* oat_class_offsets_pointer,
390 uint8_t* dex_cache_arrays);
392 const OatFile* const oat_file_;
393 const std::string dex_file_location_;
394 const std::string canonical_dex_file_location_;
395 const uint32_t dex_file_location_checksum_;
396 const uint8_t* const dex_file_pointer_;
397 const uint8_t* lookup_table_data_;
398 const uint32_t* const oat_class_offsets_pointer_;
399 uint8_t* const dex_cache_arrays_;
401 friend class OatFile;
402 friend class OatFileBase;
403 DISALLOW_COPY_AND_ASSIGN(OatDexFile);
408 #endif // ART_RUNTIME_OAT_FILE_H_