• 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_DEX_FILE_H_
18 #define ART_RUNTIME_DEX_FILE_H_
19 
20 #include <memory>
21 #include <string>
22 #include <unordered_map>
23 #include <vector>
24 
25 #include "base/hash_map.h"
26 #include "base/logging.h"
27 #include "base/mutex.h"  // For Locks::mutator_lock_.
28 #include "base/value_object.h"
29 #include "globals.h"
30 #include "invoke_type.h"
31 #include "jni.h"
32 #include "modifiers.h"
33 #include "utf.h"
34 
35 namespace art {
36 
37 // TODO: remove dependencies on mirror classes, primarily by moving
38 // EncodedStaticFieldValueIterator to its own file.
39 namespace mirror {
40   class ClassLoader;
41   class DexCache;
42 }  // namespace mirror
43 class ArtField;
44 class ArtMethod;
45 class ClassLinker;
46 class MemMap;
47 class OatDexFile;
48 class Signature;
49 template<class T> class Handle;
50 class StringPiece;
51 class ZipArchive;
52 
53 // TODO: move all of the macro functionality into the DexCache class.
54 class DexFile {
55  public:
56   static const uint8_t kDexMagic[];
57   static const uint8_t kDexMagicVersion[];
58   static constexpr size_t kSha1DigestSize = 20;
59   static constexpr uint32_t kDexEndianConstant = 0x12345678;
60 
61   // name of the DexFile entry within a zip archive
62   static const char* kClassesDex;
63 
64   // The value of an invalid index.
65   static const uint32_t kDexNoIndex = 0xFFFFFFFF;
66 
67   // The value of an invalid index.
68   static const uint16_t kDexNoIndex16 = 0xFFFF;
69 
70   // The separator charactor in MultiDex locations.
71   static constexpr char kMultiDexSeparator = ':';
72 
73   // A string version of the previous. This is a define so that we can merge string literals in the
74   // preprocessor.
75   #define kMultiDexSeparatorString ":"
76 
77   // Raw header_item.
78   struct Header {
79     uint8_t magic_[8];
80     uint32_t checksum_;  // See also location_checksum_
81     uint8_t signature_[kSha1DigestSize];
82     uint32_t file_size_;  // size of entire file
83     uint32_t header_size_;  // offset to start of next section
84     uint32_t endian_tag_;
85     uint32_t link_size_;  // unused
86     uint32_t link_off_;  // unused
87     uint32_t map_off_;  // unused
88     uint32_t string_ids_size_;  // number of StringIds
89     uint32_t string_ids_off_;  // file offset of StringIds array
90     uint32_t type_ids_size_;  // number of TypeIds, we don't support more than 65535
91     uint32_t type_ids_off_;  // file offset of TypeIds array
92     uint32_t proto_ids_size_;  // number of ProtoIds, we don't support more than 65535
93     uint32_t proto_ids_off_;  // file offset of ProtoIds array
94     uint32_t field_ids_size_;  // number of FieldIds
95     uint32_t field_ids_off_;  // file offset of FieldIds array
96     uint32_t method_ids_size_;  // number of MethodIds
97     uint32_t method_ids_off_;  // file offset of MethodIds array
98     uint32_t class_defs_size_;  // number of ClassDefs
99     uint32_t class_defs_off_;  // file offset of ClassDef array
100     uint32_t data_size_;  // unused
101     uint32_t data_off_;  // unused
102 
103    private:
104     DISALLOW_COPY_AND_ASSIGN(Header);
105   };
106 
107   // Map item type codes.
108   enum {
109     kDexTypeHeaderItem               = 0x0000,
110     kDexTypeStringIdItem             = 0x0001,
111     kDexTypeTypeIdItem               = 0x0002,
112     kDexTypeProtoIdItem              = 0x0003,
113     kDexTypeFieldIdItem              = 0x0004,
114     kDexTypeMethodIdItem             = 0x0005,
115     kDexTypeClassDefItem             = 0x0006,
116     kDexTypeMapList                  = 0x1000,
117     kDexTypeTypeList                 = 0x1001,
118     kDexTypeAnnotationSetRefList     = 0x1002,
119     kDexTypeAnnotationSetItem        = 0x1003,
120     kDexTypeClassDataItem            = 0x2000,
121     kDexTypeCodeItem                 = 0x2001,
122     kDexTypeStringDataItem           = 0x2002,
123     kDexTypeDebugInfoItem            = 0x2003,
124     kDexTypeAnnotationItem           = 0x2004,
125     kDexTypeEncodedArrayItem         = 0x2005,
126     kDexTypeAnnotationsDirectoryItem = 0x2006,
127   };
128 
129   struct MapItem {
130     uint16_t type_;
131     uint16_t unused_;
132     uint32_t size_;
133     uint32_t offset_;
134 
135    private:
136     DISALLOW_COPY_AND_ASSIGN(MapItem);
137   };
138 
139   struct MapList {
140     uint32_t size_;
141     MapItem list_[1];
142 
143    private:
144     DISALLOW_COPY_AND_ASSIGN(MapList);
145   };
146 
147   // Raw string_id_item.
148   struct StringId {
149     uint32_t string_data_off_;  // offset in bytes from the base address
150 
151    private:
152     DISALLOW_COPY_AND_ASSIGN(StringId);
153   };
154 
155   // Raw type_id_item.
156   struct TypeId {
157     uint32_t descriptor_idx_;  // index into string_ids
158 
159    private:
160     DISALLOW_COPY_AND_ASSIGN(TypeId);
161   };
162 
163   // Raw field_id_item.
164   struct FieldId {
165     uint16_t class_idx_;  // index into type_ids_ array for defining class
166     uint16_t type_idx_;  // index into type_ids_ array for field type
167     uint32_t name_idx_;  // index into string_ids_ array for field name
168 
169    private:
170     DISALLOW_COPY_AND_ASSIGN(FieldId);
171   };
172 
173   // Raw method_id_item.
174   struct MethodId {
175     uint16_t class_idx_;  // index into type_ids_ array for defining class
176     uint16_t proto_idx_;  // index into proto_ids_ array for method prototype
177     uint32_t name_idx_;  // index into string_ids_ array for method name
178 
179    private:
180     DISALLOW_COPY_AND_ASSIGN(MethodId);
181   };
182 
183   // Raw proto_id_item.
184   struct ProtoId {
185     uint32_t shorty_idx_;  // index into string_ids array for shorty descriptor
186     uint16_t return_type_idx_;  // index into type_ids array for return type
187     uint16_t pad_;             // padding = 0
188     uint32_t parameters_off_;  // file offset to type_list for parameter types
189 
190    private:
191     DISALLOW_COPY_AND_ASSIGN(ProtoId);
192   };
193 
194   // Raw class_def_item.
195   struct ClassDef {
196     uint16_t class_idx_;  // index into type_ids_ array for this class
197     uint16_t pad1_;  // padding = 0
198     uint32_t access_flags_;
199     uint16_t superclass_idx_;  // index into type_ids_ array for superclass
200     uint16_t pad2_;  // padding = 0
201     uint32_t interfaces_off_;  // file offset to TypeList
202     uint32_t source_file_idx_;  // index into string_ids_ for source file name
203     uint32_t annotations_off_;  // file offset to annotations_directory_item
204     uint32_t class_data_off_;  // file offset to class_data_item
205     uint32_t static_values_off_;  // file offset to EncodedArray
206 
207     // Returns the valid access flags, that is, Java modifier bits relevant to the ClassDef type
208     // (class or interface). These are all in the lower 16b and do not contain runtime flags.
GetJavaAccessFlagsClassDef209     uint32_t GetJavaAccessFlags() const {
210       // Make sure that none of our runtime-only flags are set.
211       static_assert((kAccValidClassFlags & kAccJavaFlagsMask) == kAccValidClassFlags,
212                     "Valid class flags not a subset of Java flags");
213       static_assert((kAccValidInterfaceFlags & kAccJavaFlagsMask) == kAccValidInterfaceFlags,
214                     "Valid interface flags not a subset of Java flags");
215 
216       if ((access_flags_ & kAccInterface) != 0) {
217         // Interface.
218         return access_flags_ & kAccValidInterfaceFlags;
219       } else {
220         // Class.
221         return access_flags_ & kAccValidClassFlags;
222       }
223     }
224 
225    private:
226     DISALLOW_COPY_AND_ASSIGN(ClassDef);
227   };
228 
229   // Raw type_item.
230   struct TypeItem {
231     uint16_t type_idx_;  // index into type_ids section
232 
233    private:
234     DISALLOW_COPY_AND_ASSIGN(TypeItem);
235   };
236 
237   // Raw type_list.
238   class TypeList {
239    public:
Size()240     uint32_t Size() const {
241       return size_;
242     }
243 
GetTypeItem(uint32_t idx)244     const TypeItem& GetTypeItem(uint32_t idx) const {
245       DCHECK_LT(idx, this->size_);
246       return this->list_[idx];
247     }
248 
249     // Size in bytes of the part of the list that is common.
GetHeaderSize()250     static constexpr size_t GetHeaderSize() {
251       return 4U;
252     }
253 
254     // Size in bytes of the whole type list including all the stored elements.
GetListSize(size_t count)255     static constexpr size_t GetListSize(size_t count) {
256       return GetHeaderSize() + sizeof(TypeItem) * count;
257     }
258 
259    private:
260     uint32_t size_;  // size of the list, in entries
261     TypeItem list_[1];  // elements of the list
262     DISALLOW_COPY_AND_ASSIGN(TypeList);
263   };
264 
265   // Raw code_item.
266   struct CodeItem {
267     uint16_t registers_size_;
268     uint16_t ins_size_;
269     uint16_t outs_size_;
270     uint16_t tries_size_;
271     uint32_t debug_info_off_;  // file offset to debug info stream
272     uint32_t insns_size_in_code_units_;  // size of the insns array, in 2 byte code units
273     uint16_t insns_[1];
274 
275    private:
276     DISALLOW_COPY_AND_ASSIGN(CodeItem);
277   };
278 
279   // Raw try_item.
280   struct TryItem {
281     uint32_t start_addr_;
282     uint16_t insn_count_;
283     uint16_t handler_off_;
284 
285    private:
286     DISALLOW_COPY_AND_ASSIGN(TryItem);
287   };
288 
289   // Annotation constants.
290   enum {
291     kDexVisibilityBuild         = 0x00,     /* annotation visibility */
292     kDexVisibilityRuntime       = 0x01,
293     kDexVisibilitySystem        = 0x02,
294 
295     kDexAnnotationByte          = 0x00,
296     kDexAnnotationShort         = 0x02,
297     kDexAnnotationChar          = 0x03,
298     kDexAnnotationInt           = 0x04,
299     kDexAnnotationLong          = 0x06,
300     kDexAnnotationFloat         = 0x10,
301     kDexAnnotationDouble        = 0x11,
302     kDexAnnotationString        = 0x17,
303     kDexAnnotationType          = 0x18,
304     kDexAnnotationField         = 0x19,
305     kDexAnnotationMethod        = 0x1a,
306     kDexAnnotationEnum          = 0x1b,
307     kDexAnnotationArray         = 0x1c,
308     kDexAnnotationAnnotation    = 0x1d,
309     kDexAnnotationNull          = 0x1e,
310     kDexAnnotationBoolean       = 0x1f,
311 
312     kDexAnnotationValueTypeMask = 0x1f,     /* low 5 bits */
313     kDexAnnotationValueArgShift = 5,
314   };
315 
316   struct AnnotationsDirectoryItem {
317     uint32_t class_annotations_off_;
318     uint32_t fields_size_;
319     uint32_t methods_size_;
320     uint32_t parameters_size_;
321 
322    private:
323     DISALLOW_COPY_AND_ASSIGN(AnnotationsDirectoryItem);
324   };
325 
326   struct FieldAnnotationsItem {
327     uint32_t field_idx_;
328     uint32_t annotations_off_;
329 
330    private:
331     DISALLOW_COPY_AND_ASSIGN(FieldAnnotationsItem);
332   };
333 
334   struct MethodAnnotationsItem {
335     uint32_t method_idx_;
336     uint32_t annotations_off_;
337 
338    private:
339     DISALLOW_COPY_AND_ASSIGN(MethodAnnotationsItem);
340   };
341 
342   struct ParameterAnnotationsItem {
343     uint32_t method_idx_;
344     uint32_t annotations_off_;
345 
346    private:
347     DISALLOW_COPY_AND_ASSIGN(ParameterAnnotationsItem);
348   };
349 
350   struct AnnotationSetRefItem {
351     uint32_t annotations_off_;
352 
353    private:
354     DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefItem);
355   };
356 
357   struct AnnotationSetRefList {
358     uint32_t size_;
359     AnnotationSetRefItem list_[1];
360 
361    private:
362     DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefList);
363   };
364 
365   struct AnnotationSetItem {
366     uint32_t size_;
367     uint32_t entries_[1];
368 
369    private:
370     DISALLOW_COPY_AND_ASSIGN(AnnotationSetItem);
371   };
372 
373   struct AnnotationItem {
374     uint8_t visibility_;
375     uint8_t annotation_[1];
376 
377    private:
378     DISALLOW_COPY_AND_ASSIGN(AnnotationItem);
379   };
380 
381   // Returns the checksum of a file for comparison with GetLocationChecksum().
382   // For .dex files, this is the header checksum.
383   // For zip files, this is the classes.dex zip entry CRC32 checksum.
384   // Return true if the checksum could be found, false otherwise.
385   static bool GetChecksum(const char* filename, uint32_t* checksum, std::string* error_msg);
386 
387   // Opens .dex files found in the container, guessing the container format based on file extension.
388   static bool Open(const char* filename, const char* location, std::string* error_msg,
389                    std::vector<std::unique_ptr<const DexFile>>* dex_files);
390 
391   // Checks whether the given file has the dex magic, or is a zip file with a classes.dex entry.
392   // If this function returns false, Open will not succeed. The inverse is not true, however.
393   static bool MaybeDex(const char* filename);
394 
395   // Opens .dex file, backed by existing memory
Open(const uint8_t * base,size_t size,const std::string & location,uint32_t location_checksum,const OatDexFile * oat_dex_file,std::string * error_msg)396   static std::unique_ptr<const DexFile> Open(const uint8_t* base, size_t size,
397                                              const std::string& location,
398                                              uint32_t location_checksum,
399                                              const OatDexFile* oat_dex_file,
400                                              std::string* error_msg) {
401     return OpenMemory(base, size, location, location_checksum, nullptr, oat_dex_file, error_msg);
402   }
403 
404   // Open all classesXXX.dex files from a zip archive.
405   static bool OpenFromZip(const ZipArchive& zip_archive, const std::string& location,
406                           std::string* error_msg,
407                           std::vector<std::unique_ptr<const DexFile>>* dex_files);
408 
409   // Closes a .dex file.
410   virtual ~DexFile();
411 
GetLocation()412   const std::string& GetLocation() const {
413     return location_;
414   }
415 
416   // For normal dex files, location and base location coincide. If a dex file is part of a multidex
417   // archive, the base location is the name of the originating jar/apk, stripped of any internal
418   // classes*.dex path.
GetBaseLocation(const char * location)419   static std::string GetBaseLocation(const char* location) {
420     const char* pos = strrchr(location, kMultiDexSeparator);
421     if (pos == nullptr) {
422       return location;
423     } else {
424       return std::string(location, pos - location);
425     }
426   }
427 
GetBaseLocation(const std::string & location)428   static std::string GetBaseLocation(const std::string& location) {
429     return GetBaseLocation(location.c_str());
430   }
431 
432   // Returns the ':classes*.dex' part of the dex location. Returns an empty
433   // string if there is no multidex suffix for the given location.
434   // The kMultiDexSeparator is included in the returned suffix.
GetMultiDexSuffix(const std::string & location)435   static std::string GetMultiDexSuffix(const std::string& location) {
436     size_t pos = location.rfind(kMultiDexSeparator);
437     if (pos == std::string::npos) {
438       return "";
439     } else {
440       return location.substr(pos);
441     }
442   }
443 
GetBaseLocation()444   std::string GetBaseLocation() const {
445     return GetBaseLocation(location_);
446   }
447 
448   // For DexFiles directly from .dex files, this is the checksum from the DexFile::Header.
449   // For DexFiles opened from a zip files, this will be the ZipEntry CRC32 of classes.dex.
GetLocationChecksum()450   uint32_t GetLocationChecksum() const {
451     return location_checksum_;
452   }
453 
GetHeader()454   const Header& GetHeader() const {
455     DCHECK(header_ != nullptr) << GetLocation();
456     return *header_;
457   }
458 
459   // Decode the dex magic version
460   uint32_t GetVersion() const;
461 
462   // Returns true if the byte string points to the magic value.
463   static bool IsMagicValid(const uint8_t* magic);
464 
465   // Returns true if the byte string after the magic is the correct value.
466   static bool IsVersionValid(const uint8_t* magic);
467 
468   // Returns the number of string identifiers in the .dex file.
NumStringIds()469   size_t NumStringIds() const {
470     DCHECK(header_ != nullptr) << GetLocation();
471     return header_->string_ids_size_;
472   }
473 
474   // Returns the StringId at the specified index.
GetStringId(uint32_t idx)475   const StringId& GetStringId(uint32_t idx) const {
476     DCHECK_LT(idx, NumStringIds()) << GetLocation();
477     return string_ids_[idx];
478   }
479 
GetIndexForStringId(const StringId & string_id)480   uint32_t GetIndexForStringId(const StringId& string_id) const {
481     CHECK_GE(&string_id, string_ids_) << GetLocation();
482     CHECK_LT(&string_id, string_ids_ + header_->string_ids_size_) << GetLocation();
483     return &string_id - string_ids_;
484   }
485 
486   int32_t GetStringLength(const StringId& string_id) const;
487 
488   // Returns a pointer to the UTF-8 string data referred to by the given string_id as well as the
489   // length of the string when decoded as a UTF-16 string. Note the UTF-16 length is not the same
490   // as the string length of the string data.
491   const char* GetStringDataAndUtf16Length(const StringId& string_id, uint32_t* utf16_length) const;
492 
GetStringData(const StringId & string_id)493   const char* GetStringData(const StringId& string_id) const {
494     uint32_t ignored;
495     return GetStringDataAndUtf16Length(string_id, &ignored);
496   }
497 
498   // Index version of GetStringDataAndUtf16Length.
StringDataAndUtf16LengthByIdx(uint32_t idx,uint32_t * utf16_length)499   const char* StringDataAndUtf16LengthByIdx(uint32_t idx, uint32_t* utf16_length) const {
500     if (idx == kDexNoIndex) {
501       *utf16_length = 0;
502       return nullptr;
503     }
504     const StringId& string_id = GetStringId(idx);
505     return GetStringDataAndUtf16Length(string_id, utf16_length);
506   }
507 
StringDataByIdx(uint32_t idx)508   const char* StringDataByIdx(uint32_t idx) const {
509     uint32_t unicode_length;
510     return StringDataAndUtf16LengthByIdx(idx, &unicode_length);
511   }
512 
513   // Looks up a string id for a given modified utf8 string.
514   const StringId* FindStringId(const char* string) const;
515 
516   // Looks up a string id for a given utf16 string.
517   const StringId* FindStringId(const uint16_t* string, size_t length) const;
518 
519   // Returns the number of type identifiers in the .dex file.
NumTypeIds()520   uint32_t NumTypeIds() const {
521     DCHECK(header_ != nullptr) << GetLocation();
522     return header_->type_ids_size_;
523   }
524 
525   // Returns the TypeId at the specified index.
GetTypeId(uint32_t idx)526   const TypeId& GetTypeId(uint32_t idx) const {
527     DCHECK_LT(idx, NumTypeIds()) << GetLocation();
528     return type_ids_[idx];
529   }
530 
GetIndexForTypeId(const TypeId & type_id)531   uint16_t GetIndexForTypeId(const TypeId& type_id) const {
532     CHECK_GE(&type_id, type_ids_) << GetLocation();
533     CHECK_LT(&type_id, type_ids_ + header_->type_ids_size_) << GetLocation();
534     size_t result = &type_id - type_ids_;
535     DCHECK_LT(result, 65536U) << GetLocation();
536     return static_cast<uint16_t>(result);
537   }
538 
539   // Get the descriptor string associated with a given type index.
StringByTypeIdx(uint32_t idx,uint32_t * unicode_length)540   const char* StringByTypeIdx(uint32_t idx, uint32_t* unicode_length) const {
541     const TypeId& type_id = GetTypeId(idx);
542     return StringDataAndUtf16LengthByIdx(type_id.descriptor_idx_, unicode_length);
543   }
544 
StringByTypeIdx(uint32_t idx)545   const char* StringByTypeIdx(uint32_t idx) const {
546     const TypeId& type_id = GetTypeId(idx);
547     return StringDataByIdx(type_id.descriptor_idx_);
548   }
549 
550   // Returns the type descriptor string of a type id.
GetTypeDescriptor(const TypeId & type_id)551   const char* GetTypeDescriptor(const TypeId& type_id) const {
552     return StringDataByIdx(type_id.descriptor_idx_);
553   }
554 
555   // Looks up a type for the given string index
556   const TypeId* FindTypeId(uint32_t string_idx) const;
557 
558   // Returns the number of field identifiers in the .dex file.
NumFieldIds()559   size_t NumFieldIds() const {
560     DCHECK(header_ != nullptr) << GetLocation();
561     return header_->field_ids_size_;
562   }
563 
564   // Returns the FieldId at the specified index.
GetFieldId(uint32_t idx)565   const FieldId& GetFieldId(uint32_t idx) const {
566     DCHECK_LT(idx, NumFieldIds()) << GetLocation();
567     return field_ids_[idx];
568   }
569 
GetIndexForFieldId(const FieldId & field_id)570   uint32_t GetIndexForFieldId(const FieldId& field_id) const {
571     CHECK_GE(&field_id, field_ids_) << GetLocation();
572     CHECK_LT(&field_id, field_ids_ + header_->field_ids_size_) << GetLocation();
573     return &field_id - field_ids_;
574   }
575 
576   // Looks up a field by its declaring class, name and type
577   const FieldId* FindFieldId(const DexFile::TypeId& declaring_klass,
578                              const DexFile::StringId& name,
579                              const DexFile::TypeId& type) const;
580 
581   // Returns the declaring class descriptor string of a field id.
GetFieldDeclaringClassDescriptor(const FieldId & field_id)582   const char* GetFieldDeclaringClassDescriptor(const FieldId& field_id) const {
583     const DexFile::TypeId& type_id = GetTypeId(field_id.class_idx_);
584     return GetTypeDescriptor(type_id);
585   }
586 
587   // Returns the class descriptor string of a field id.
GetFieldTypeDescriptor(const FieldId & field_id)588   const char* GetFieldTypeDescriptor(const FieldId& field_id) const {
589     const DexFile::TypeId& type_id = GetTypeId(field_id.type_idx_);
590     return GetTypeDescriptor(type_id);
591   }
592 
593   // Returns the name of a field id.
GetFieldName(const FieldId & field_id)594   const char* GetFieldName(const FieldId& field_id) const {
595     return StringDataByIdx(field_id.name_idx_);
596   }
597 
598   // Returns the number of method identifiers in the .dex file.
NumMethodIds()599   size_t NumMethodIds() const {
600     DCHECK(header_ != nullptr) << GetLocation();
601     return header_->method_ids_size_;
602   }
603 
604   // Returns the MethodId at the specified index.
GetMethodId(uint32_t idx)605   const MethodId& GetMethodId(uint32_t idx) const {
606     DCHECK_LT(idx, NumMethodIds()) << GetLocation();
607     return method_ids_[idx];
608   }
609 
GetIndexForMethodId(const MethodId & method_id)610   uint32_t GetIndexForMethodId(const MethodId& method_id) const {
611     CHECK_GE(&method_id, method_ids_) << GetLocation();
612     CHECK_LT(&method_id, method_ids_ + header_->method_ids_size_) << GetLocation();
613     return &method_id - method_ids_;
614   }
615 
616   // Looks up a method by its declaring class, name and proto_id
617   const MethodId* FindMethodId(const DexFile::TypeId& declaring_klass,
618                                const DexFile::StringId& name,
619                                const DexFile::ProtoId& signature) const;
620 
621   // Returns the declaring class descriptor string of a method id.
GetMethodDeclaringClassDescriptor(const MethodId & method_id)622   const char* GetMethodDeclaringClassDescriptor(const MethodId& method_id) const {
623     const DexFile::TypeId& type_id = GetTypeId(method_id.class_idx_);
624     return GetTypeDescriptor(type_id);
625   }
626 
627   // Returns the prototype of a method id.
GetMethodPrototype(const MethodId & method_id)628   const ProtoId& GetMethodPrototype(const MethodId& method_id) const {
629     return GetProtoId(method_id.proto_idx_);
630   }
631 
632   // Returns a representation of the signature of a method id.
633   const Signature GetMethodSignature(const MethodId& method_id) const;
634 
635   // Returns the name of a method id.
GetMethodName(const MethodId & method_id)636   const char* GetMethodName(const MethodId& method_id) const {
637     return StringDataByIdx(method_id.name_idx_);
638   }
639 
640   // Returns the shorty of a method id.
GetMethodShorty(const MethodId & method_id)641   const char* GetMethodShorty(const MethodId& method_id) const {
642     return StringDataByIdx(GetProtoId(method_id.proto_idx_).shorty_idx_);
643   }
GetMethodShorty(const MethodId & method_id,uint32_t * length)644   const char* GetMethodShorty(const MethodId& method_id, uint32_t* length) const {
645     // Using the UTF16 length is safe here as shorties are guaranteed to be ASCII characters.
646     return StringDataAndUtf16LengthByIdx(GetProtoId(method_id.proto_idx_).shorty_idx_, length);
647   }
648   // Returns the number of class definitions in the .dex file.
NumClassDefs()649   uint32_t NumClassDefs() const {
650     DCHECK(header_ != nullptr) << GetLocation();
651     return header_->class_defs_size_;
652   }
653 
654   // Returns the ClassDef at the specified index.
GetClassDef(uint16_t idx)655   const ClassDef& GetClassDef(uint16_t idx) const {
656     DCHECK_LT(idx, NumClassDefs()) << GetLocation();
657     return class_defs_[idx];
658   }
659 
GetIndexForClassDef(const ClassDef & class_def)660   uint16_t GetIndexForClassDef(const ClassDef& class_def) const {
661     CHECK_GE(&class_def, class_defs_) << GetLocation();
662     CHECK_LT(&class_def, class_defs_ + header_->class_defs_size_) << GetLocation();
663     return &class_def - class_defs_;
664   }
665 
666   // Returns the class descriptor string of a class definition.
GetClassDescriptor(const ClassDef & class_def)667   const char* GetClassDescriptor(const ClassDef& class_def) const {
668     return StringByTypeIdx(class_def.class_idx_);
669   }
670 
671   // Looks up a class definition by its class descriptor. Hash must be
672   // ComputeModifiedUtf8Hash(descriptor).
673   const ClassDef* FindClassDef(const char* descriptor, size_t hash) const;
674 
675   // Looks up a class definition by its type index.
676   const ClassDef* FindClassDef(uint16_t type_idx) const;
677 
GetInterfacesList(const ClassDef & class_def)678   const TypeList* GetInterfacesList(const ClassDef& class_def) const {
679     if (class_def.interfaces_off_ == 0) {
680         return nullptr;
681     } else {
682       const uint8_t* addr = begin_ + class_def.interfaces_off_;
683       return reinterpret_cast<const TypeList*>(addr);
684     }
685   }
686 
687   // Returns a pointer to the raw memory mapped class_data_item
GetClassData(const ClassDef & class_def)688   const uint8_t* GetClassData(const ClassDef& class_def) const {
689     if (class_def.class_data_off_ == 0) {
690       return nullptr;
691     } else {
692       return begin_ + class_def.class_data_off_;
693     }
694   }
695 
696   //
GetCodeItem(const uint32_t code_off)697   const CodeItem* GetCodeItem(const uint32_t code_off) const {
698     if (code_off == 0) {
699       return nullptr;  // native or abstract method
700     } else {
701       const uint8_t* addr = begin_ + code_off;
702       return reinterpret_cast<const CodeItem*>(addr);
703     }
704   }
705 
GetReturnTypeDescriptor(const ProtoId & proto_id)706   const char* GetReturnTypeDescriptor(const ProtoId& proto_id) const {
707     return StringByTypeIdx(proto_id.return_type_idx_);
708   }
709 
710   // Returns the number of prototype identifiers in the .dex file.
NumProtoIds()711   size_t NumProtoIds() const {
712     DCHECK(header_ != nullptr) << GetLocation();
713     return header_->proto_ids_size_;
714   }
715 
716   // Returns the ProtoId at the specified index.
GetProtoId(uint32_t idx)717   const ProtoId& GetProtoId(uint32_t idx) const {
718     DCHECK_LT(idx, NumProtoIds()) << GetLocation();
719     return proto_ids_[idx];
720   }
721 
GetIndexForProtoId(const ProtoId & proto_id)722   uint16_t GetIndexForProtoId(const ProtoId& proto_id) const {
723     CHECK_GE(&proto_id, proto_ids_) << GetLocation();
724     CHECK_LT(&proto_id, proto_ids_ + header_->proto_ids_size_) << GetLocation();
725     return &proto_id - proto_ids_;
726   }
727 
728   // Looks up a proto id for a given return type and signature type list
729   const ProtoId* FindProtoId(uint16_t return_type_idx,
730                              const uint16_t* signature_type_idxs, uint32_t signature_length) const;
FindProtoId(uint16_t return_type_idx,const std::vector<uint16_t> & signature_type_idxs)731   const ProtoId* FindProtoId(uint16_t return_type_idx,
732                              const std::vector<uint16_t>& signature_type_idxs) const {
733     return FindProtoId(return_type_idx, &signature_type_idxs[0], signature_type_idxs.size());
734   }
735 
736   // Given a signature place the type ids into the given vector, returns true on success
737   bool CreateTypeList(const StringPiece& signature, uint16_t* return_type_idx,
738                       std::vector<uint16_t>* param_type_idxs) const;
739 
740   // Create a Signature from the given string signature or return Signature::NoSignature if not
741   // possible.
742   const Signature CreateSignature(const StringPiece& signature) const;
743 
744   // Returns the short form method descriptor for the given prototype.
GetShorty(uint32_t proto_idx)745   const char* GetShorty(uint32_t proto_idx) const {
746     const ProtoId& proto_id = GetProtoId(proto_idx);
747     return StringDataByIdx(proto_id.shorty_idx_);
748   }
749 
GetProtoParameters(const ProtoId & proto_id)750   const TypeList* GetProtoParameters(const ProtoId& proto_id) const {
751     if (proto_id.parameters_off_ == 0) {
752       return nullptr;
753     } else {
754       const uint8_t* addr = begin_ + proto_id.parameters_off_;
755       return reinterpret_cast<const TypeList*>(addr);
756     }
757   }
758 
GetEncodedStaticFieldValuesArray(const ClassDef & class_def)759   const uint8_t* GetEncodedStaticFieldValuesArray(const ClassDef& class_def) const {
760     if (class_def.static_values_off_ == 0) {
761       return 0;
762     } else {
763       return begin_ + class_def.static_values_off_;
764     }
765   }
766 
767   static const TryItem* GetTryItems(const CodeItem& code_item, uint32_t offset);
768 
769   // Get the base of the encoded data for the given DexCode.
GetCatchHandlerData(const CodeItem & code_item,uint32_t offset)770   static const uint8_t* GetCatchHandlerData(const CodeItem& code_item, uint32_t offset) {
771     const uint8_t* handler_data =
772         reinterpret_cast<const uint8_t*>(GetTryItems(code_item, code_item.tries_size_));
773     return handler_data + offset;
774   }
775 
776   // Find which try region is associated with the given address (ie dex pc). Returns -1 if none.
777   static int32_t FindTryItem(const CodeItem &code_item, uint32_t address);
778 
779   // Find the handler offset associated with the given address (ie dex pc). Returns -1 if none.
780   static int32_t FindCatchHandlerOffset(const CodeItem &code_item, uint32_t address);
781 
782   // Get the pointer to the start of the debugging data
GetDebugInfoStream(const CodeItem * code_item)783   const uint8_t* GetDebugInfoStream(const CodeItem* code_item) const {
784     if (code_item->debug_info_off_ == 0) {
785       return nullptr;
786     } else {
787       return begin_ + code_item->debug_info_off_;
788     }
789   }
790 
791   // Callback for "new position table entry".
792   // Returning true causes the decoder to stop early.
793   typedef bool (*DexDebugNewPositionCb)(void* context, uint32_t address, uint32_t line_num);
794 
795   // Callback for "new locals table entry". "signature" is an empty string
796   // if no signature is available for an entry.
797   typedef void (*DexDebugNewLocalCb)(void* context, uint16_t reg,
798                                      uint32_t start_address,
799                                      uint32_t end_address,
800                                      const char* name,
801                                      const char* descriptor,
802                                      const char* signature);
803 
804   static bool LineNumForPcCb(void* context, uint32_t address, uint32_t line_num);
805 
806   // Debug info opcodes and constants
807   enum {
808     DBG_END_SEQUENCE         = 0x00,
809     DBG_ADVANCE_PC           = 0x01,
810     DBG_ADVANCE_LINE         = 0x02,
811     DBG_START_LOCAL          = 0x03,
812     DBG_START_LOCAL_EXTENDED = 0x04,
813     DBG_END_LOCAL            = 0x05,
814     DBG_RESTART_LOCAL        = 0x06,
815     DBG_SET_PROLOGUE_END     = 0x07,
816     DBG_SET_EPILOGUE_BEGIN   = 0x08,
817     DBG_SET_FILE             = 0x09,
818     DBG_FIRST_SPECIAL        = 0x0a,
819     DBG_LINE_BASE            = -4,
820     DBG_LINE_RANGE           = 15,
821   };
822 
823   struct LocalInfo {
LocalInfoLocalInfo824     LocalInfo()
825         : name_(nullptr), descriptor_(nullptr), signature_(nullptr), start_address_(0),
826           is_live_(false) {}
827 
828     const char* name_;  // E.g., list
829     const char* descriptor_;  // E.g., Ljava/util/LinkedList;
830     const char* signature_;  // E.g., java.util.LinkedList<java.lang.Integer>
831     uint16_t start_address_;  // PC location where the local is first defined.
832     bool is_live_;  // Is the local defined and live.
833 
834    private:
835     DISALLOW_COPY_AND_ASSIGN(LocalInfo);
836   };
837 
838   struct LineNumFromPcContext {
LineNumFromPcContextLineNumFromPcContext839     LineNumFromPcContext(uint32_t address, uint32_t line_num)
840         : address_(address), line_num_(line_num) {}
841     uint32_t address_;
842     uint32_t line_num_;
843    private:
844     DISALLOW_COPY_AND_ASSIGN(LineNumFromPcContext);
845   };
846 
InvokeLocalCbIfLive(void * context,int reg,uint32_t end_address,LocalInfo * local_in_reg,DexDebugNewLocalCb local_cb)847   void InvokeLocalCbIfLive(void* context, int reg, uint32_t end_address,
848                            LocalInfo* local_in_reg, DexDebugNewLocalCb local_cb) const {
849     if (local_cb != nullptr && local_in_reg[reg].is_live_) {
850       local_cb(context, reg, local_in_reg[reg].start_address_, end_address,
851           local_in_reg[reg].name_, local_in_reg[reg].descriptor_,
852           local_in_reg[reg].signature_ != nullptr ? local_in_reg[reg].signature_ : "");
853     }
854   }
855 
856   // Determine the source file line number based on the program counter.
857   // "pc" is an offset, in 16-bit units, from the start of the method's code.
858   //
859   // Returns -1 if no match was found (possibly because the source files were
860   // compiled without "-g", so no line number information is present).
861   // Returns -2 for native methods (as expected in exception traces).
862   //
863   // This is used by runtime; therefore use art::Method not art::DexFile::Method.
864   int32_t GetLineNumFromPC(ArtMethod* method, uint32_t rel_pc) const
865       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
866 
867   void DecodeDebugInfo(const CodeItem* code_item, bool is_static, uint32_t method_idx,
868                        DexDebugNewPositionCb position_cb, DexDebugNewLocalCb local_cb,
869                        void* context) const;
870 
GetSourceFile(const ClassDef & class_def)871   const char* GetSourceFile(const ClassDef& class_def) const {
872     if (class_def.source_file_idx_ == 0xffffffff) {
873       return nullptr;
874     } else {
875       return StringDataByIdx(class_def.source_file_idx_);
876     }
877   }
878 
879   int GetPermissions() const;
880 
881   bool IsReadOnly() const;
882 
883   bool EnableWrite() const;
884 
885   bool DisableWrite() const;
886 
Begin()887   const uint8_t* Begin() const {
888     return begin_;
889   }
890 
Size()891   size_t Size() const {
892     return size_;
893   }
894 
895   // Return the name of the index-th classes.dex in a multidex zip file. This is classes.dex for
896   // index == 0, and classes{index + 1}.dex else.
897   static std::string GetMultiDexClassesDexName(size_t index);
898 
899   // Return the (possibly synthetic) dex location for a multidex entry. This is dex_location for
900   // index == 0, and dex_location + multi-dex-separator + GetMultiDexClassesDexName(index) else.
901   static std::string GetMultiDexLocation(size_t index, const char* dex_location);
902 
903   // Returns the canonical form of the given dex location.
904   //
905   // There are different flavors of "dex locations" as follows:
906   // the file name of a dex file:
907   //     The actual file path that the dex file has on disk.
908   // dex_location:
909   //     This acts as a key for the class linker to know which dex file to load.
910   //     It may correspond to either an old odex file or a particular dex file
911   //     inside an oat file. In the first case it will also match the file name
912   //     of the dex file. In the second case (oat) it will include the file name
913   //     and possibly some multidex annotation to uniquely identify it.
914   // canonical_dex_location:
915   //     the dex_location where it's file name part has been made canonical.
916   static std::string GetDexCanonicalLocation(const char* dex_location);
917 
GetOatDexFile()918   const OatDexFile* GetOatDexFile() const {
919     return oat_dex_file_;
920   }
921 
922  private:
923   // Opens a .dex file
924   static std::unique_ptr<const DexFile> OpenFile(int fd, const char* location,
925                                                  bool verify, std::string* error_msg);
926 
927   // Opens dex files from within a .jar, .zip, or .apk file
928   static bool OpenZip(int fd, const std::string& location, std::string* error_msg,
929                       std::vector<std::unique_ptr<const DexFile>>* dex_files);
930 
931   enum class ZipOpenErrorCode {  // private
932     kNoError,
933     kEntryNotFound,
934     kExtractToMemoryError,
935     kDexFileError,
936     kMakeReadOnlyError,
937     kVerifyError
938   };
939 
940   // Opens .dex file from the entry_name in a zip archive. error_code is undefined when non-null
941   // return.
942   static std::unique_ptr<const DexFile> Open(const ZipArchive& zip_archive, const char* entry_name,
943                                              const std::string& location, std::string* error_msg,
944                                              ZipOpenErrorCode* error_code);
945 
946   // Opens a .dex file at the given address backed by a MemMap
947   static std::unique_ptr<const DexFile> OpenMemory(const std::string& location,
948                                                    uint32_t location_checksum,
949                                                    MemMap* mem_map,
950                                                    std::string* error_msg);
951 
952   // Opens a .dex file at the given address, optionally backed by a MemMap
953   static std::unique_ptr<const DexFile> OpenMemory(const uint8_t* dex_file,
954                                                    size_t size,
955                                                    const std::string& location,
956                                                    uint32_t location_checksum,
957                                                    MemMap* mem_map,
958                                                    const OatDexFile* oat_dex_file,
959                                                    std::string* error_msg);
960 
961   DexFile(const uint8_t* base, size_t size,
962           const std::string& location,
963           uint32_t location_checksum,
964           MemMap* mem_map,
965           const OatDexFile* oat_dex_file);
966 
967   // Top-level initializer that calls other Init methods.
968   bool Init(std::string* error_msg);
969 
970   // Returns true if the header magic and version numbers are of the expected values.
971   bool CheckMagicAndVersion(std::string* error_msg) const;
972 
973   void DecodeDebugInfo0(const CodeItem* code_item, bool is_static, uint32_t method_idx,
974       DexDebugNewPositionCb position_cb, DexDebugNewLocalCb local_cb,
975       void* context, const uint8_t* stream, LocalInfo* local_in_reg) const;
976 
977   // Check whether a location denotes a multidex dex file. This is a very simple check: returns
978   // whether the string contains the separator character.
979   static bool IsMultiDexLocation(const char* location);
980 
981 
982   // The base address of the memory mapping.
983   const uint8_t* const begin_;
984 
985   // The size of the underlying memory allocation in bytes.
986   const size_t size_;
987 
988   // Typically the dex file name when available, alternatively some identifying string.
989   //
990   // The ClassLinker will use this to match DexFiles the boot class
991   // path to DexCache::GetLocation when loading from an image.
992   const std::string location_;
993 
994   const uint32_t location_checksum_;
995 
996   // Manages the underlying memory allocation.
997   std::unique_ptr<MemMap> mem_map_;
998 
999   // Points to the header section.
1000   const Header* const header_;
1001 
1002   // Points to the base of the string identifier list.
1003   const StringId* const string_ids_;
1004 
1005   // Points to the base of the type identifier list.
1006   const TypeId* const type_ids_;
1007 
1008   // Points to the base of the field identifier list.
1009   const FieldId* const field_ids_;
1010 
1011   // Points to the base of the method identifier list.
1012   const MethodId* const method_ids_;
1013 
1014   // Points to the base of the prototype identifier list.
1015   const ProtoId* const proto_ids_;
1016 
1017   // Points to the base of the class definition list.
1018   const ClassDef* const class_defs_;
1019 
1020   // Number of misses finding a class def from a descriptor.
1021   mutable Atomic<uint32_t> find_class_def_misses_;
1022 
1023   struct UTF16EmptyFn {
MakeEmptyUTF16EmptyFn1024     void MakeEmpty(std::pair<const char*, const ClassDef*>& pair) const {
1025       pair.first = nullptr;
1026       pair.second = nullptr;
1027     }
IsEmptyUTF16EmptyFn1028     bool IsEmpty(const std::pair<const char*, const ClassDef*>& pair) const {
1029       if (pair.first == nullptr) {
1030         DCHECK(pair.second == nullptr);
1031         return true;
1032       }
1033       return false;
1034     }
1035   };
1036   struct UTF16HashCmp {
1037     // Hash function.
operatorUTF16HashCmp1038     size_t operator()(const char* key) const {
1039       return ComputeModifiedUtf8Hash(key);
1040     }
1041     // std::equal function.
operatorUTF16HashCmp1042     bool operator()(const char* a, const char* b) const {
1043       return CompareModifiedUtf8ToModifiedUtf8AsUtf16CodePointValues(a, b) == 0;
1044     }
1045   };
1046   typedef HashMap<const char*, const ClassDef*, UTF16EmptyFn, UTF16HashCmp, UTF16HashCmp> Index;
1047   mutable Atomic<Index*> class_def_index_;
1048 
1049   // If this dex file was loaded from an oat file, oat_dex_file_ contains a
1050   // pointer to the OatDexFile it was loaded from. Otherwise oat_dex_file_ is
1051   // null.
1052   const OatDexFile* oat_dex_file_;
1053 };
1054 
1055 struct DexFileReference {
DexFileReferenceDexFileReference1056   DexFileReference(const DexFile* file, uint32_t idx) : dex_file(file), index(idx) { }
1057   const DexFile* dex_file;
1058   uint32_t index;
1059 };
1060 
1061 std::ostream& operator<<(std::ostream& os, const DexFile& dex_file);
1062 
1063 // Iterate over a dex file's ProtoId's paramters
1064 class DexFileParameterIterator {
1065  public:
DexFileParameterIterator(const DexFile & dex_file,const DexFile::ProtoId & proto_id)1066   DexFileParameterIterator(const DexFile& dex_file, const DexFile::ProtoId& proto_id)
1067       : dex_file_(dex_file), size_(0), pos_(0) {
1068     type_list_ = dex_file_.GetProtoParameters(proto_id);
1069     if (type_list_ != nullptr) {
1070       size_ = type_list_->Size();
1071     }
1072   }
HasNext()1073   bool HasNext() const { return pos_ < size_; }
Next()1074   void Next() { ++pos_; }
GetTypeIdx()1075   uint16_t GetTypeIdx() {
1076     return type_list_->GetTypeItem(pos_).type_idx_;
1077   }
GetDescriptor()1078   const char* GetDescriptor() {
1079     return dex_file_.StringByTypeIdx(GetTypeIdx());
1080   }
1081  private:
1082   const DexFile& dex_file_;
1083   const DexFile::TypeList* type_list_;
1084   uint32_t size_;
1085   uint32_t pos_;
1086   DISALLOW_IMPLICIT_CONSTRUCTORS(DexFileParameterIterator);
1087 };
1088 
1089 // Abstract the signature of a method.
1090 class Signature : public ValueObject {
1091  public:
1092   std::string ToString() const;
1093 
NoSignature()1094   static Signature NoSignature() {
1095     return Signature();
1096   }
1097 
1098   bool operator==(const Signature& rhs) const;
1099   bool operator!=(const Signature& rhs) const {
1100     return !(*this == rhs);
1101   }
1102 
1103   bool operator==(const StringPiece& rhs) const;
1104 
1105  private:
Signature(const DexFile * dex,const DexFile::ProtoId & proto)1106   Signature(const DexFile* dex, const DexFile::ProtoId& proto) : dex_file_(dex), proto_id_(&proto) {
1107   }
1108 
Signature()1109   Signature() : dex_file_(nullptr), proto_id_(nullptr) {
1110   }
1111 
1112   friend class DexFile;
1113 
1114   const DexFile* const dex_file_;
1115   const DexFile::ProtoId* const proto_id_;
1116 };
1117 std::ostream& operator<<(std::ostream& os, const Signature& sig);
1118 
1119 // Iterate and decode class_data_item
1120 class ClassDataItemIterator {
1121  public:
ClassDataItemIterator(const DexFile & dex_file,const uint8_t * raw_class_data_item)1122   ClassDataItemIterator(const DexFile& dex_file, const uint8_t* raw_class_data_item)
1123       : dex_file_(dex_file), pos_(0), ptr_pos_(raw_class_data_item), last_idx_(0) {
1124     ReadClassDataHeader();
1125     if (EndOfInstanceFieldsPos() > 0) {
1126       ReadClassDataField();
1127     } else if (EndOfVirtualMethodsPos() > 0) {
1128       ReadClassDataMethod();
1129     }
1130   }
NumStaticFields()1131   uint32_t NumStaticFields() const {
1132     return header_.static_fields_size_;
1133   }
NumInstanceFields()1134   uint32_t NumInstanceFields() const {
1135     return header_.instance_fields_size_;
1136   }
NumDirectMethods()1137   uint32_t NumDirectMethods() const {
1138     return header_.direct_methods_size_;
1139   }
NumVirtualMethods()1140   uint32_t NumVirtualMethods() const {
1141     return header_.virtual_methods_size_;
1142   }
HasNextStaticField()1143   bool HasNextStaticField() const {
1144     return pos_ < EndOfStaticFieldsPos();
1145   }
HasNextInstanceField()1146   bool HasNextInstanceField() const {
1147     return pos_ >= EndOfStaticFieldsPos() && pos_ < EndOfInstanceFieldsPos();
1148   }
HasNextDirectMethod()1149   bool HasNextDirectMethod() const {
1150     return pos_ >= EndOfInstanceFieldsPos() && pos_ < EndOfDirectMethodsPos();
1151   }
HasNextVirtualMethod()1152   bool HasNextVirtualMethod() const {
1153     return pos_ >= EndOfDirectMethodsPos() && pos_ < EndOfVirtualMethodsPos();
1154   }
HasNext()1155   bool HasNext() const {
1156     return pos_ < EndOfVirtualMethodsPos();
1157   }
Next()1158   inline void Next() {
1159     pos_++;
1160     if (pos_ < EndOfStaticFieldsPos()) {
1161       last_idx_ = GetMemberIndex();
1162       ReadClassDataField();
1163     } else if (pos_ == EndOfStaticFieldsPos() && NumInstanceFields() > 0) {
1164       last_idx_ = 0;  // transition to next array, reset last index
1165       ReadClassDataField();
1166     } else if (pos_ < EndOfInstanceFieldsPos()) {
1167       last_idx_ = GetMemberIndex();
1168       ReadClassDataField();
1169     } else if (pos_ == EndOfInstanceFieldsPos() && NumDirectMethods() > 0) {
1170       last_idx_ = 0;  // transition to next array, reset last index
1171       ReadClassDataMethod();
1172     } else if (pos_ < EndOfDirectMethodsPos()) {
1173       last_idx_ = GetMemberIndex();
1174       ReadClassDataMethod();
1175     } else if (pos_ == EndOfDirectMethodsPos() && NumVirtualMethods() > 0) {
1176       last_idx_ = 0;  // transition to next array, reset last index
1177       ReadClassDataMethod();
1178     } else if (pos_ < EndOfVirtualMethodsPos()) {
1179       last_idx_ = GetMemberIndex();
1180       ReadClassDataMethod();
1181     } else {
1182       DCHECK(!HasNext());
1183     }
1184   }
GetMemberIndex()1185   uint32_t GetMemberIndex() const {
1186     if (pos_ < EndOfInstanceFieldsPos()) {
1187       return last_idx_ + field_.field_idx_delta_;
1188     } else {
1189       DCHECK_LT(pos_, EndOfVirtualMethodsPos());
1190       return last_idx_ + method_.method_idx_delta_;
1191     }
1192   }
GetRawMemberAccessFlags()1193   uint32_t GetRawMemberAccessFlags() const {
1194     if (pos_ < EndOfInstanceFieldsPos()) {
1195       return field_.access_flags_;
1196     } else {
1197       DCHECK_LT(pos_, EndOfVirtualMethodsPos());
1198       return method_.access_flags_;
1199     }
1200   }
GetFieldAccessFlags()1201   uint32_t GetFieldAccessFlags() const {
1202     return GetRawMemberAccessFlags() & kAccValidFieldFlags;
1203   }
GetMethodAccessFlags()1204   uint32_t GetMethodAccessFlags() const {
1205     return GetRawMemberAccessFlags() & kAccValidMethodFlags;
1206   }
MemberIsNative()1207   bool MemberIsNative() const {
1208     return GetRawMemberAccessFlags() & kAccNative;
1209   }
MemberIsFinal()1210   bool MemberIsFinal() const {
1211     return GetRawMemberAccessFlags() & kAccFinal;
1212   }
GetMethodInvokeType(const DexFile::ClassDef & class_def)1213   InvokeType GetMethodInvokeType(const DexFile::ClassDef& class_def) const {
1214     if (HasNextDirectMethod()) {
1215       if ((GetRawMemberAccessFlags() & kAccStatic) != 0) {
1216         return kStatic;
1217       } else {
1218         return kDirect;
1219       }
1220     } else {
1221       DCHECK_EQ(GetRawMemberAccessFlags() & kAccStatic, 0U);
1222       if ((class_def.access_flags_ & kAccInterface) != 0) {
1223         return kInterface;
1224       } else if ((GetRawMemberAccessFlags() & kAccConstructor) != 0) {
1225         return kSuper;
1226       } else {
1227         return kVirtual;
1228       }
1229     }
1230   }
GetMethodCodeItem()1231   const DexFile::CodeItem* GetMethodCodeItem() const {
1232     return dex_file_.GetCodeItem(method_.code_off_);
1233   }
GetMethodCodeItemOffset()1234   uint32_t GetMethodCodeItemOffset() const {
1235     return method_.code_off_;
1236   }
EndDataPointer()1237   const uint8_t* EndDataPointer() const {
1238     CHECK(!HasNext());
1239     return ptr_pos_;
1240   }
1241 
1242  private:
1243   // A dex file's class_data_item is leb128 encoded, this structure holds a decoded form of the
1244   // header for a class_data_item
1245   struct ClassDataHeader {
1246     uint32_t static_fields_size_;  // the number of static fields
1247     uint32_t instance_fields_size_;  // the number of instance fields
1248     uint32_t direct_methods_size_;  // the number of direct methods
1249     uint32_t virtual_methods_size_;  // the number of virtual methods
1250   } header_;
1251 
1252   // Read and decode header from a class_data_item stream into header
1253   void ReadClassDataHeader();
1254 
EndOfStaticFieldsPos()1255   uint32_t EndOfStaticFieldsPos() const {
1256     return header_.static_fields_size_;
1257   }
EndOfInstanceFieldsPos()1258   uint32_t EndOfInstanceFieldsPos() const {
1259     return EndOfStaticFieldsPos() + header_.instance_fields_size_;
1260   }
EndOfDirectMethodsPos()1261   uint32_t EndOfDirectMethodsPos() const {
1262     return EndOfInstanceFieldsPos() + header_.direct_methods_size_;
1263   }
EndOfVirtualMethodsPos()1264   uint32_t EndOfVirtualMethodsPos() const {
1265     return EndOfDirectMethodsPos() + header_.virtual_methods_size_;
1266   }
1267 
1268   // A decoded version of the field of a class_data_item
1269   struct ClassDataField {
1270     uint32_t field_idx_delta_;  // delta of index into the field_ids array for FieldId
1271     uint32_t access_flags_;  // access flags for the field
ClassDataFieldClassDataField1272     ClassDataField() :  field_idx_delta_(0), access_flags_(0) {}
1273 
1274    private:
1275     DISALLOW_COPY_AND_ASSIGN(ClassDataField);
1276   };
1277   ClassDataField field_;
1278 
1279   // Read and decode a field from a class_data_item stream into field
1280   void ReadClassDataField();
1281 
1282   // A decoded version of the method of a class_data_item
1283   struct ClassDataMethod {
1284     uint32_t method_idx_delta_;  // delta of index into the method_ids array for MethodId
1285     uint32_t access_flags_;
1286     uint32_t code_off_;
ClassDataMethodClassDataMethod1287     ClassDataMethod() : method_idx_delta_(0), access_flags_(0), code_off_(0) {}
1288 
1289    private:
1290     DISALLOW_COPY_AND_ASSIGN(ClassDataMethod);
1291   };
1292   ClassDataMethod method_;
1293 
1294   // Read and decode a method from a class_data_item stream into method
1295   void ReadClassDataMethod();
1296 
1297   const DexFile& dex_file_;
1298   size_t pos_;  // integral number of items passed
1299   const uint8_t* ptr_pos_;  // pointer into stream of class_data_item
1300   uint32_t last_idx_;  // last read field or method index to apply delta to
1301   DISALLOW_IMPLICIT_CONSTRUCTORS(ClassDataItemIterator);
1302 };
1303 
1304 class EncodedStaticFieldValueIterator {
1305  public:
1306   EncodedStaticFieldValueIterator(const DexFile& dex_file, Handle<mirror::DexCache>* dex_cache,
1307                                   Handle<mirror::ClassLoader>* class_loader,
1308                                   ClassLinker* linker, const DexFile::ClassDef& class_def)
1309       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
1310 
1311   template<bool kTransactionActive>
1312   void ReadValueToField(ArtField* field) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
1313 
HasNext()1314   bool HasNext() const { return pos_ < array_size_; }
1315 
1316   void Next();
1317 
1318   enum ValueType {
1319     kByte = 0x00,
1320     kShort = 0x02,
1321     kChar = 0x03,
1322     kInt = 0x04,
1323     kLong = 0x06,
1324     kFloat = 0x10,
1325     kDouble = 0x11,
1326     kString = 0x17,
1327     kType = 0x18,
1328     kField = 0x19,
1329     kMethod = 0x1a,
1330     kEnum = 0x1b,
1331     kArray = 0x1c,
1332     kAnnotation = 0x1d,
1333     kNull = 0x1e,
1334     kBoolean = 0x1f
1335   };
1336 
1337  private:
1338   static constexpr uint8_t kEncodedValueTypeMask = 0x1f;  // 0b11111
1339   static constexpr uint8_t kEncodedValueArgShift = 5;
1340 
1341   const DexFile& dex_file_;
1342   Handle<mirror::DexCache>* const dex_cache_;  // Dex cache to resolve literal objects.
1343   Handle<mirror::ClassLoader>* const class_loader_;  // ClassLoader to resolve types.
1344   ClassLinker* linker_;  // Linker to resolve literal objects.
1345   size_t array_size_;  // Size of array.
1346   size_t pos_;  // Current position.
1347   const uint8_t* ptr_;  // Pointer into encoded data array.
1348   ValueType type_;  // Type of current encoded value.
1349   jvalue jval_;  // Value of current encoded value.
1350   DISALLOW_IMPLICIT_CONSTRUCTORS(EncodedStaticFieldValueIterator);
1351 };
1352 std::ostream& operator<<(std::ostream& os, const EncodedStaticFieldValueIterator::ValueType& code);
1353 
1354 class CatchHandlerIterator {
1355   public:
1356     CatchHandlerIterator(const DexFile::CodeItem& code_item, uint32_t address);
1357 
1358     CatchHandlerIterator(const DexFile::CodeItem& code_item,
1359                          const DexFile::TryItem& try_item);
1360 
CatchHandlerIterator(const uint8_t * handler_data)1361     explicit CatchHandlerIterator(const uint8_t* handler_data) {
1362       Init(handler_data);
1363     }
1364 
GetHandlerTypeIndex()1365     uint16_t GetHandlerTypeIndex() const {
1366       return handler_.type_idx_;
1367     }
GetHandlerAddress()1368     uint32_t GetHandlerAddress() const {
1369       return handler_.address_;
1370     }
1371     void Next();
HasNext()1372     bool HasNext() const {
1373       return remaining_count_ != -1 || catch_all_;
1374     }
1375     // End of this set of catch blocks, convenience method to locate next set of catch blocks
EndDataPointer()1376     const uint8_t* EndDataPointer() const {
1377       CHECK(!HasNext());
1378       return current_data_;
1379     }
1380 
1381   private:
1382     void Init(const DexFile::CodeItem& code_item, int32_t offset);
1383     void Init(const uint8_t* handler_data);
1384 
1385     struct CatchHandlerItem {
1386       uint16_t type_idx_;  // type index of the caught exception type
1387       uint32_t address_;  // handler address
1388     } handler_;
1389     const uint8_t* current_data_;  // the current handler in dex file.
1390     int32_t remaining_count_;   // number of handlers not read.
1391     bool catch_all_;            // is there a handler that will catch all exceptions in case
1392                                 // that all typed handler does not match.
1393 };
1394 
1395 }  // namespace art
1396 
1397 #endif  // ART_RUNTIME_DEX_FILE_H_
1398