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_LIBDEXFILE_DEX_DEX_FILE_H_
18 #define ART_LIBDEXFILE_DEX_DEX_FILE_H_
19 
20 #include <memory>
21 #include <string>
22 #include <vector>
23 
24 #include <android-base/logging.h>
25 
26 #include "base/globals.h"
27 #include "base/iteration_range.h"
28 #include "base/macros.h"
29 #include "base/value_object.h"
30 #include "dex_file_types.h"
31 #include "dex_instruction_iterator.h"
32 #include "hidden_api_access_flags.h"
33 #include "jni.h"
34 #include "modifiers.h"
35 
36 namespace art {
37 
38 class ClassDataItemIterator;
39 class CompactDexFile;
40 enum InvokeType : uint32_t;
41 class MemMap;
42 class OatDexFile;
43 class Signature;
44 class StandardDexFile;
45 class StringPiece;
46 class ZipArchive;
47 
48 // Some instances of DexFile own the storage referred to by DexFile.  Clients who create
49 // such management do so by subclassing Container.
50 class DexFileContainer {
51  public:
DexFileContainer()52   DexFileContainer() { }
~DexFileContainer()53   virtual ~DexFileContainer() { }
54   virtual int GetPermissions() = 0;
55   virtual bool IsReadOnly() = 0;
56   virtual bool EnableWrite() = 0;
57   virtual bool DisableWrite() = 0;
58 
59  private:
60   DISALLOW_COPY_AND_ASSIGN(DexFileContainer);
61 };
62 
63 // Dex file is the API that exposes native dex files (ordinary dex files) and CompactDex.
64 // Originally, the dex file format used by ART was mostly the same as APKs. The only change was
65 // quickened opcodes and layout optimizations.
66 // Since ART needs to support both native dex files and CompactDex files, the DexFile interface
67 // provides an abstraction to facilitate this.
68 class DexFile {
69  public:
70   // Number of bytes in the dex file magic.
71   static constexpr size_t kDexMagicSize = 4;
72   static constexpr size_t kDexVersionLen = 4;
73 
74   // First Dex format version enforcing class definition ordering rules.
75   static const uint32_t kClassDefinitionOrderEnforcedVersion = 37;
76 
77   static constexpr size_t kSha1DigestSize = 20;
78   static constexpr uint32_t kDexEndianConstant = 0x12345678;
79 
80   // The value of an invalid index.
81   static const uint16_t kDexNoIndex16 = 0xFFFF;
82 
83   // Raw header_item.
84   struct Header {
85     uint8_t magic_[8] = {};
86     uint32_t checksum_ = 0;  // See also location_checksum_
87     uint8_t signature_[kSha1DigestSize] = {};
88     uint32_t file_size_ = 0;  // size of entire file
89     uint32_t header_size_ = 0;  // offset to start of next section
90     uint32_t endian_tag_ = 0;
91     uint32_t link_size_ = 0;  // unused
92     uint32_t link_off_ = 0;  // unused
93     uint32_t map_off_ = 0;  // unused
94     uint32_t string_ids_size_ = 0;  // number of StringIds
95     uint32_t string_ids_off_ = 0;  // file offset of StringIds array
96     uint32_t type_ids_size_ = 0;  // number of TypeIds, we don't support more than 65535
97     uint32_t type_ids_off_ = 0;  // file offset of TypeIds array
98     uint32_t proto_ids_size_ = 0;  // number of ProtoIds, we don't support more than 65535
99     uint32_t proto_ids_off_ = 0;  // file offset of ProtoIds array
100     uint32_t field_ids_size_ = 0;  // number of FieldIds
101     uint32_t field_ids_off_ = 0;  // file offset of FieldIds array
102     uint32_t method_ids_size_ = 0;  // number of MethodIds
103     uint32_t method_ids_off_ = 0;  // file offset of MethodIds array
104     uint32_t class_defs_size_ = 0;  // number of ClassDefs
105     uint32_t class_defs_off_ = 0;  // file offset of ClassDef array
106     uint32_t data_size_ = 0;  // size of data section
107     uint32_t data_off_ = 0;  // file offset of data section
108 
109     // Decode the dex magic version
110     uint32_t GetVersion() const;
111   };
112 
113   // Map item type codes.
114   enum MapItemType : uint16_t {  // private
115     kDexTypeHeaderItem               = 0x0000,
116     kDexTypeStringIdItem             = 0x0001,
117     kDexTypeTypeIdItem               = 0x0002,
118     kDexTypeProtoIdItem              = 0x0003,
119     kDexTypeFieldIdItem              = 0x0004,
120     kDexTypeMethodIdItem             = 0x0005,
121     kDexTypeClassDefItem             = 0x0006,
122     kDexTypeCallSiteIdItem           = 0x0007,
123     kDexTypeMethodHandleItem         = 0x0008,
124     kDexTypeMapList                  = 0x1000,
125     kDexTypeTypeList                 = 0x1001,
126     kDexTypeAnnotationSetRefList     = 0x1002,
127     kDexTypeAnnotationSetItem        = 0x1003,
128     kDexTypeClassDataItem            = 0x2000,
129     kDexTypeCodeItem                 = 0x2001,
130     kDexTypeStringDataItem           = 0x2002,
131     kDexTypeDebugInfoItem            = 0x2003,
132     kDexTypeAnnotationItem           = 0x2004,
133     kDexTypeEncodedArrayItem         = 0x2005,
134     kDexTypeAnnotationsDirectoryItem = 0x2006,
135   };
136 
137   struct MapItem {
138     uint16_t type_;
139     uint16_t unused_;
140     uint32_t size_;
141     uint32_t offset_;
142   };
143 
144   struct MapList {
145     uint32_t size_;
146     MapItem list_[1];
147 
148    private:
149     DISALLOW_COPY_AND_ASSIGN(MapList);
150   };
151 
152   // Raw string_id_item.
153   struct StringId {
154     uint32_t string_data_off_;  // offset in bytes from the base address
155 
156    private:
157     DISALLOW_COPY_AND_ASSIGN(StringId);
158   };
159 
160   // Raw type_id_item.
161   struct TypeId {
162     dex::StringIndex descriptor_idx_;  // index into string_ids
163 
164    private:
165     DISALLOW_COPY_AND_ASSIGN(TypeId);
166   };
167 
168   // Raw field_id_item.
169   struct FieldId {
170     dex::TypeIndex class_idx_;   // index into type_ids_ array for defining class
171     dex::TypeIndex type_idx_;    // index into type_ids_ array for field type
172     dex::StringIndex name_idx_;  // index into string_ids_ array for field name
173 
174    private:
175     DISALLOW_COPY_AND_ASSIGN(FieldId);
176   };
177 
178   // Raw proto_id_item.
179   struct ProtoId {
180     dex::StringIndex shorty_idx_;     // index into string_ids array for shorty descriptor
181     dex::TypeIndex return_type_idx_;  // index into type_ids array for return type
182     uint16_t pad_;                    // padding = 0
183     uint32_t parameters_off_;         // file offset to type_list for parameter types
184 
185    private:
186     DISALLOW_COPY_AND_ASSIGN(ProtoId);
187   };
188 
189   // Raw method_id_item.
190   struct MethodId {
191     dex::TypeIndex class_idx_;   // index into type_ids_ array for defining class
192     uint16_t proto_idx_;         // index into proto_ids_ array for method prototype
193     dex::StringIndex name_idx_;  // index into string_ids_ array for method name
194 
195    private:
196     DISALLOW_COPY_AND_ASSIGN(MethodId);
197   };
198 
199   // Base code_item, compact dex and standard dex have different code item layouts.
200   struct CodeItem {
201    protected:
202     CodeItem() = default;
203 
204    private:
205     DISALLOW_COPY_AND_ASSIGN(CodeItem);
206   };
207 
208   // Raw class_def_item.
209   struct ClassDef {
210     dex::TypeIndex class_idx_;  // index into type_ids_ array for this class
211     uint16_t pad1_;  // padding = 0
212     uint32_t access_flags_;
213     dex::TypeIndex superclass_idx_;  // index into type_ids_ array for superclass
214     uint16_t pad2_;  // padding = 0
215     uint32_t interfaces_off_;  // file offset to TypeList
216     dex::StringIndex source_file_idx_;  // index into string_ids_ for source file name
217     uint32_t annotations_off_;  // file offset to annotations_directory_item
218     uint32_t class_data_off_;  // file offset to class_data_item
219     uint32_t static_values_off_;  // file offset to EncodedArray
220 
221     // Returns the valid access flags, that is, Java modifier bits relevant to the ClassDef type
222     // (class or interface). These are all in the lower 16b and do not contain runtime flags.
GetJavaAccessFlagsClassDef223     uint32_t GetJavaAccessFlags() const {
224       // Make sure that none of our runtime-only flags are set.
225       static_assert((kAccValidClassFlags & kAccJavaFlagsMask) == kAccValidClassFlags,
226                     "Valid class flags not a subset of Java flags");
227       static_assert((kAccValidInterfaceFlags & kAccJavaFlagsMask) == kAccValidInterfaceFlags,
228                     "Valid interface flags not a subset of Java flags");
229 
230       if ((access_flags_ & kAccInterface) != 0) {
231         // Interface.
232         return access_flags_ & kAccValidInterfaceFlags;
233       } else {
234         // Class.
235         return access_flags_ & kAccValidClassFlags;
236       }
237     }
238 
239     template <typename Visitor>
240     void VisitMethods(const DexFile* dex_file, const Visitor& visitor) const;
241 
242    private:
243     DISALLOW_COPY_AND_ASSIGN(ClassDef);
244   };
245 
246   // Raw type_item.
247   struct TypeItem {
248     dex::TypeIndex type_idx_;  // index into type_ids section
249 
250    private:
251     DISALLOW_COPY_AND_ASSIGN(TypeItem);
252   };
253 
254   // Raw type_list.
255   class TypeList {
256    public:
Size()257     uint32_t Size() const {
258       return size_;
259     }
260 
GetTypeItem(uint32_t idx)261     const TypeItem& GetTypeItem(uint32_t idx) const {
262       DCHECK_LT(idx, this->size_);
263       return this->list_[idx];
264     }
265 
266     // Size in bytes of the part of the list that is common.
GetHeaderSize()267     static constexpr size_t GetHeaderSize() {
268       return 4U;
269     }
270 
271     // Size in bytes of the whole type list including all the stored elements.
GetListSize(size_t count)272     static constexpr size_t GetListSize(size_t count) {
273       return GetHeaderSize() + sizeof(TypeItem) * count;
274     }
275 
276    private:
277     uint32_t size_;  // size of the list, in entries
278     TypeItem list_[1];  // elements of the list
279     DISALLOW_COPY_AND_ASSIGN(TypeList);
280   };
281 
282   // MethodHandle Types
283   enum class MethodHandleType : uint16_t {  // private
284     kStaticPut         = 0x0000,  // a setter for a given static field.
285     kStaticGet         = 0x0001,  // a getter for a given static field.
286     kInstancePut       = 0x0002,  // a setter for a given instance field.
287     kInstanceGet       = 0x0003,  // a getter for a given instance field.
288     kInvokeStatic      = 0x0004,  // an invoker for a given static method.
289     kInvokeInstance    = 0x0005,  // invoke_instance : an invoker for a given instance method. This
290                                   // can be any non-static method on any class (or interface) except
291                                   // for “<init>”.
292     kInvokeConstructor = 0x0006,  // an invoker for a given constructor.
293     kInvokeDirect      = 0x0007,  // an invoker for a direct (special) method.
294     kInvokeInterface   = 0x0008,  // an invoker for an interface method.
295     kLast = kInvokeInterface
296   };
297 
298   // raw method_handle_item
299   struct MethodHandleItem {
300     uint16_t method_handle_type_;
301     uint16_t reserved1_;            // Reserved for future use.
302     uint16_t field_or_method_idx_;  // Field index for accessors, method index otherwise.
303     uint16_t reserved2_;            // Reserved for future use.
304    private:
305     DISALLOW_COPY_AND_ASSIGN(MethodHandleItem);
306   };
307 
308   // raw call_site_id_item
309   struct CallSiteIdItem {
310     uint32_t data_off_;  // Offset into data section pointing to encoded array items.
311    private:
312     DISALLOW_COPY_AND_ASSIGN(CallSiteIdItem);
313   };
314 
315   // Raw try_item.
316   struct TryItem {
317     static constexpr size_t kAlignment = sizeof(uint32_t);
318 
319     uint32_t start_addr_;
320     uint16_t insn_count_;
321     uint16_t handler_off_;
322 
323    private:
324     TryItem() = default;
325     friend class DexWriter;
326     DISALLOW_COPY_AND_ASSIGN(TryItem);
327   };
328 
329   // Annotation constants.
330   enum {
331     kDexVisibilityBuild         = 0x00,     /* annotation visibility */
332     kDexVisibilityRuntime       = 0x01,
333     kDexVisibilitySystem        = 0x02,
334 
335     kDexAnnotationByte          = 0x00,
336     kDexAnnotationShort         = 0x02,
337     kDexAnnotationChar          = 0x03,
338     kDexAnnotationInt           = 0x04,
339     kDexAnnotationLong          = 0x06,
340     kDexAnnotationFloat         = 0x10,
341     kDexAnnotationDouble        = 0x11,
342     kDexAnnotationMethodType    = 0x15,
343     kDexAnnotationMethodHandle  = 0x16,
344     kDexAnnotationString        = 0x17,
345     kDexAnnotationType          = 0x18,
346     kDexAnnotationField         = 0x19,
347     kDexAnnotationMethod        = 0x1a,
348     kDexAnnotationEnum          = 0x1b,
349     kDexAnnotationArray         = 0x1c,
350     kDexAnnotationAnnotation    = 0x1d,
351     kDexAnnotationNull          = 0x1e,
352     kDexAnnotationBoolean       = 0x1f,
353 
354     kDexAnnotationValueTypeMask = 0x1f,     /* low 5 bits */
355     kDexAnnotationValueArgShift = 5,
356   };
357 
358   struct AnnotationsDirectoryItem {
359     uint32_t class_annotations_off_;
360     uint32_t fields_size_;
361     uint32_t methods_size_;
362     uint32_t parameters_size_;
363 
364    private:
365     DISALLOW_COPY_AND_ASSIGN(AnnotationsDirectoryItem);
366   };
367 
368   struct FieldAnnotationsItem {
369     uint32_t field_idx_;
370     uint32_t annotations_off_;
371 
372    private:
373     DISALLOW_COPY_AND_ASSIGN(FieldAnnotationsItem);
374   };
375 
376   struct MethodAnnotationsItem {
377     uint32_t method_idx_;
378     uint32_t annotations_off_;
379 
380    private:
381     DISALLOW_COPY_AND_ASSIGN(MethodAnnotationsItem);
382   };
383 
384   struct ParameterAnnotationsItem {
385     uint32_t method_idx_;
386     uint32_t annotations_off_;
387 
388    private:
389     DISALLOW_COPY_AND_ASSIGN(ParameterAnnotationsItem);
390   };
391 
392   struct AnnotationSetRefItem {
393     uint32_t annotations_off_;
394 
395    private:
396     DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefItem);
397   };
398 
399   struct AnnotationSetRefList {
400     uint32_t size_;
401     AnnotationSetRefItem list_[1];
402 
403    private:
404     DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefList);
405   };
406 
407   struct AnnotationSetItem {
408     uint32_t size_;
409     uint32_t entries_[1];
410 
411    private:
412     DISALLOW_COPY_AND_ASSIGN(AnnotationSetItem);
413   };
414 
415   struct AnnotationItem {
416     uint8_t visibility_;
417     uint8_t annotation_[1];
418 
419    private:
420     DISALLOW_COPY_AND_ASSIGN(AnnotationItem);
421   };
422 
423   enum AnnotationResultStyle {  // private
424     kAllObjects,
425     kPrimitivesOrObjects,
426     kAllRaw
427   };
428 
429   struct AnnotationValue;
430 
431   // Closes a .dex file.
432   virtual ~DexFile();
433 
GetLocation()434   const std::string& GetLocation() const {
435     return location_;
436   }
437 
438   // For DexFiles directly from .dex files, this is the checksum from the DexFile::Header.
439   // For DexFiles opened from a zip files, this will be the ZipEntry CRC32 of classes.dex.
GetLocationChecksum()440   uint32_t GetLocationChecksum() const {
441     return location_checksum_;
442   }
443 
GetHeader()444   const Header& GetHeader() const {
445     DCHECK(header_ != nullptr) << GetLocation();
446     return *header_;
447   }
448 
449   // Decode the dex magic version
GetDexVersion()450   uint32_t GetDexVersion() const {
451     return GetHeader().GetVersion();
452   }
453 
454   // Returns true if the byte string points to the magic value.
455   virtual bool IsMagicValid() const = 0;
456 
457   // Returns true if the byte string after the magic is the correct value.
458   virtual bool IsVersionValid() const = 0;
459 
460   // Returns true if the dex file supports default methods.
461   virtual bool SupportsDefaultMethods() const = 0;
462 
463   // Returns the maximum size in bytes needed to store an equivalent dex file strictly conforming to
464   // the dex file specification. That is the size if we wanted to get rid of all the
465   // quickening/compact-dexing/etc.
466   //
467   // TODO This should really be an exact size! b/72402467
468   virtual size_t GetDequickenedSize() const = 0;
469 
470   // Returns the number of string identifiers in the .dex file.
NumStringIds()471   size_t NumStringIds() const {
472     DCHECK(header_ != nullptr) << GetLocation();
473     return header_->string_ids_size_;
474   }
475 
476   // Returns the StringId at the specified index.
GetStringId(dex::StringIndex idx)477   const StringId& GetStringId(dex::StringIndex idx) const {
478     DCHECK_LT(idx.index_, NumStringIds()) << GetLocation();
479     return string_ids_[idx.index_];
480   }
481 
GetIndexForStringId(const StringId & string_id)482   dex::StringIndex GetIndexForStringId(const StringId& string_id) const {
483     CHECK_GE(&string_id, string_ids_) << GetLocation();
484     CHECK_LT(&string_id, string_ids_ + header_->string_ids_size_) << GetLocation();
485     return dex::StringIndex(&string_id - string_ids_);
486   }
487 
488   int32_t GetStringLength(const StringId& string_id) const;
489 
490   // Returns a pointer to the UTF-8 string data referred to by the given string_id as well as the
491   // length of the string when decoded as a UTF-16 string. Note the UTF-16 length is not the same
492   // as the string length of the string data.
493   const char* GetStringDataAndUtf16Length(const StringId& string_id, uint32_t* utf16_length) const;
494 
495   const char* GetStringData(const StringId& string_id) const;
496 
497   // Index version of GetStringDataAndUtf16Length.
498   const char* StringDataAndUtf16LengthByIdx(dex::StringIndex idx, uint32_t* utf16_length) const;
499 
500   const char* StringDataByIdx(dex::StringIndex idx) const;
501 
502   // Looks up a string id for a given modified utf8 string.
503   const StringId* FindStringId(const char* string) const;
504 
505   const TypeId* FindTypeId(const char* string) const;
506 
507   // Looks up a string id for a given utf16 string.
508   const StringId* FindStringId(const uint16_t* string, size_t length) const;
509 
510   // Returns the number of type identifiers in the .dex file.
NumTypeIds()511   uint32_t NumTypeIds() const {
512     DCHECK(header_ != nullptr) << GetLocation();
513     return header_->type_ids_size_;
514   }
515 
IsTypeIndexValid(dex::TypeIndex idx)516   bool IsTypeIndexValid(dex::TypeIndex idx) const {
517     return idx.IsValid() && idx.index_ < NumTypeIds();
518   }
519 
520   // Returns the TypeId at the specified index.
GetTypeId(dex::TypeIndex idx)521   const TypeId& GetTypeId(dex::TypeIndex idx) const {
522     DCHECK_LT(idx.index_, NumTypeIds()) << GetLocation();
523     return type_ids_[idx.index_];
524   }
525 
GetIndexForTypeId(const TypeId & type_id)526   dex::TypeIndex GetIndexForTypeId(const TypeId& type_id) const {
527     CHECK_GE(&type_id, type_ids_) << GetLocation();
528     CHECK_LT(&type_id, type_ids_ + header_->type_ids_size_) << GetLocation();
529     size_t result = &type_id - type_ids_;
530     DCHECK_LT(result, 65536U) << GetLocation();
531     return dex::TypeIndex(static_cast<uint16_t>(result));
532   }
533 
534   // Get the descriptor string associated with a given type index.
535   const char* StringByTypeIdx(dex::TypeIndex idx, uint32_t* unicode_length) const;
536 
537   const char* StringByTypeIdx(dex::TypeIndex idx) const;
538 
539   // Returns the type descriptor string of a type id.
540   const char* GetTypeDescriptor(const TypeId& type_id) const;
541 
542   // Looks up a type for the given string index
543   const TypeId* FindTypeId(dex::StringIndex string_idx) const;
544 
545   // Returns the number of field identifiers in the .dex file.
NumFieldIds()546   size_t NumFieldIds() const {
547     DCHECK(header_ != nullptr) << GetLocation();
548     return header_->field_ids_size_;
549   }
550 
551   // Returns the FieldId at the specified index.
GetFieldId(uint32_t idx)552   const FieldId& GetFieldId(uint32_t idx) const {
553     DCHECK_LT(idx, NumFieldIds()) << GetLocation();
554     return field_ids_[idx];
555   }
556 
GetIndexForFieldId(const FieldId & field_id)557   uint32_t GetIndexForFieldId(const FieldId& field_id) const {
558     CHECK_GE(&field_id, field_ids_) << GetLocation();
559     CHECK_LT(&field_id, field_ids_ + header_->field_ids_size_) << GetLocation();
560     return &field_id - field_ids_;
561   }
562 
563   // Looks up a field by its declaring class, name and type
564   const FieldId* FindFieldId(const DexFile::TypeId& declaring_klass,
565                              const DexFile::StringId& name,
566                              const DexFile::TypeId& type) const;
567 
568   uint32_t FindCodeItemOffset(const DexFile::ClassDef& class_def,
569                               uint32_t dex_method_idx) const;
570 
571   virtual uint32_t GetCodeItemSize(const DexFile::CodeItem& disk_code_item) const = 0;
572 
573   // Returns the declaring class descriptor string of a field id.
GetFieldDeclaringClassDescriptor(const FieldId & field_id)574   const char* GetFieldDeclaringClassDescriptor(const FieldId& field_id) const {
575     const DexFile::TypeId& type_id = GetTypeId(field_id.class_idx_);
576     return GetTypeDescriptor(type_id);
577   }
578 
579   // Returns the class descriptor string of a field id.
580   const char* GetFieldTypeDescriptor(const FieldId& field_id) const;
581 
582   // Returns the name of a field id.
583   const char* GetFieldName(const FieldId& field_id) const;
584 
585   // Returns the number of method identifiers in the .dex file.
NumMethodIds()586   size_t NumMethodIds() const {
587     DCHECK(header_ != nullptr) << GetLocation();
588     return header_->method_ids_size_;
589   }
590 
591   // Returns the MethodId at the specified index.
GetMethodId(uint32_t idx)592   const MethodId& GetMethodId(uint32_t idx) const {
593     DCHECK_LT(idx, NumMethodIds()) << GetLocation();
594     return method_ids_[idx];
595   }
596 
GetIndexForMethodId(const MethodId & method_id)597   uint32_t GetIndexForMethodId(const MethodId& method_id) const {
598     CHECK_GE(&method_id, method_ids_) << GetLocation();
599     CHECK_LT(&method_id, method_ids_ + header_->method_ids_size_) << GetLocation();
600     return &method_id - method_ids_;
601   }
602 
603   // Looks up a method by its declaring class, name and proto_id
604   const MethodId* FindMethodId(const DexFile::TypeId& declaring_klass,
605                                const DexFile::StringId& name,
606                                const DexFile::ProtoId& signature) const;
607 
608   // Returns the declaring class descriptor string of a method id.
609   const char* GetMethodDeclaringClassDescriptor(const MethodId& method_id) const;
610 
611   // Returns the prototype of a method id.
GetMethodPrototype(const MethodId & method_id)612   const ProtoId& GetMethodPrototype(const MethodId& method_id) const {
613     return GetProtoId(method_id.proto_idx_);
614   }
615 
616   // Returns a representation of the signature of a method id.
617   const Signature GetMethodSignature(const MethodId& method_id) const;
618 
619   // Returns a representation of the signature of a proto id.
620   const Signature GetProtoSignature(const ProtoId& proto_id) const;
621 
622   // Returns the name of a method id.
623   const char* GetMethodName(const MethodId& method_id) const;
624 
625   // Returns the shorty of a method by its index.
626   const char* GetMethodShorty(uint32_t idx) const;
627 
628   // Returns the shorty of a method id.
629   const char* GetMethodShorty(const MethodId& method_id) const;
630   const char* GetMethodShorty(const MethodId& method_id, uint32_t* length) const;
631 
632   // Returns the number of class definitions in the .dex file.
NumClassDefs()633   uint32_t NumClassDefs() const {
634     DCHECK(header_ != nullptr) << GetLocation();
635     return header_->class_defs_size_;
636   }
637 
638   // Returns the ClassDef at the specified index.
GetClassDef(uint16_t idx)639   const ClassDef& GetClassDef(uint16_t idx) const {
640     DCHECK_LT(idx, NumClassDefs()) << GetLocation();
641     return class_defs_[idx];
642   }
643 
GetIndexForClassDef(const ClassDef & class_def)644   uint16_t GetIndexForClassDef(const ClassDef& class_def) const {
645     CHECK_GE(&class_def, class_defs_) << GetLocation();
646     CHECK_LT(&class_def, class_defs_ + header_->class_defs_size_) << GetLocation();
647     return &class_def - class_defs_;
648   }
649 
650   // Returns the class descriptor string of a class definition.
651   const char* GetClassDescriptor(const ClassDef& class_def) const;
652 
653   // Looks up a class definition by its type index.
654   const ClassDef* FindClassDef(dex::TypeIndex type_idx) const;
655 
GetInterfacesList(const ClassDef & class_def)656   const TypeList* GetInterfacesList(const ClassDef& class_def) const {
657     return DataPointer<TypeList>(class_def.interfaces_off_);
658   }
659 
NumMethodHandles()660   uint32_t NumMethodHandles() const {
661     return num_method_handles_;
662   }
663 
GetMethodHandle(uint32_t idx)664   const MethodHandleItem& GetMethodHandle(uint32_t idx) const {
665     CHECK_LT(idx, NumMethodHandles());
666     return method_handles_[idx];
667   }
668 
NumCallSiteIds()669   uint32_t NumCallSiteIds() const {
670     return num_call_site_ids_;
671   }
672 
GetCallSiteId(uint32_t idx)673   const CallSiteIdItem& GetCallSiteId(uint32_t idx) const {
674     CHECK_LT(idx, NumCallSiteIds());
675     return call_site_ids_[idx];
676   }
677 
678   // Returns a pointer to the raw memory mapped class_data_item
GetClassData(const ClassDef & class_def)679   const uint8_t* GetClassData(const ClassDef& class_def) const {
680     return DataPointer<uint8_t>(class_def.class_data_off_);
681   }
682 
683   // Return the code item for a provided offset.
GetCodeItem(const uint32_t code_off)684   const CodeItem* GetCodeItem(const uint32_t code_off) const {
685     // May be null for native or abstract methods.
686     return DataPointer<CodeItem>(code_off);
687   }
688 
689   const char* GetReturnTypeDescriptor(const ProtoId& proto_id) const;
690 
691   // Returns the number of prototype identifiers in the .dex file.
NumProtoIds()692   size_t NumProtoIds() const {
693     DCHECK(header_ != nullptr) << GetLocation();
694     return header_->proto_ids_size_;
695   }
696 
697   // Returns the ProtoId at the specified index.
GetProtoId(uint16_t idx)698   const ProtoId& GetProtoId(uint16_t idx) const {
699     DCHECK_LT(idx, NumProtoIds()) << GetLocation();
700     return proto_ids_[idx];
701   }
702 
GetIndexForProtoId(const ProtoId & proto_id)703   uint16_t GetIndexForProtoId(const ProtoId& proto_id) const {
704     CHECK_GE(&proto_id, proto_ids_) << GetLocation();
705     CHECK_LT(&proto_id, proto_ids_ + header_->proto_ids_size_) << GetLocation();
706     return &proto_id - proto_ids_;
707   }
708 
709   // Looks up a proto id for a given return type and signature type list
710   const ProtoId* FindProtoId(dex::TypeIndex return_type_idx,
711                              const dex::TypeIndex* signature_type_idxs,
712                              uint32_t signature_length) const;
FindProtoId(dex::TypeIndex return_type_idx,const std::vector<dex::TypeIndex> & signature_type_idxs)713   const ProtoId* FindProtoId(dex::TypeIndex return_type_idx,
714                              const std::vector<dex::TypeIndex>& signature_type_idxs) const {
715     return FindProtoId(return_type_idx, &signature_type_idxs[0], signature_type_idxs.size());
716   }
717 
718   // Given a signature place the type ids into the given vector, returns true on success
719   bool CreateTypeList(const StringPiece& signature,
720                       dex::TypeIndex* return_type_idx,
721                       std::vector<dex::TypeIndex>* param_type_idxs) const;
722 
723   // Create a Signature from the given string signature or return Signature::NoSignature if not
724   // possible.
725   const Signature CreateSignature(const StringPiece& signature) const;
726 
727   // Returns the short form method descriptor for the given prototype.
728   const char* GetShorty(uint32_t proto_idx) const;
729 
GetProtoParameters(const ProtoId & proto_id)730   const TypeList* GetProtoParameters(const ProtoId& proto_id) const {
731     return DataPointer<TypeList>(proto_id.parameters_off_);
732   }
733 
GetEncodedStaticFieldValuesArray(const ClassDef & class_def)734   const uint8_t* GetEncodedStaticFieldValuesArray(const ClassDef& class_def) const {
735     return DataPointer<uint8_t>(class_def.static_values_off_);
736   }
737 
GetCallSiteEncodedValuesArray(const CallSiteIdItem & call_site_id)738   const uint8_t* GetCallSiteEncodedValuesArray(const CallSiteIdItem& call_site_id) const {
739     return DataBegin() + call_site_id.data_off_;
740   }
741 
742   static const TryItem* GetTryItems(const DexInstructionIterator& code_item_end, uint32_t offset);
743 
744   // Get the base of the encoded data for the given DexCode.
745   static const uint8_t* GetCatchHandlerData(const DexInstructionIterator& code_item_end,
746                                             uint32_t tries_size,
747                                             uint32_t offset);
748 
749   // Find which try region is associated with the given address (ie dex pc). Returns -1 if none.
750   static int32_t FindTryItem(const TryItem* try_items, uint32_t tries_size, uint32_t address);
751 
752   // Get the pointer to the start of the debugging data
GetDebugInfoStream(uint32_t debug_info_off)753   const uint8_t* GetDebugInfoStream(uint32_t debug_info_off) const {
754     // Check that the offset is in bounds.
755     // Note that although the specification says that 0 should be used if there
756     // is no debug information, some applications incorrectly use 0xFFFFFFFF.
757     return (debug_info_off == 0 || debug_info_off >= data_size_)
758         ? nullptr
759         : DataBegin() + debug_info_off;
760   }
761 
762   struct PositionInfo {
763     PositionInfo() = default;
764 
765     uint32_t address_ = 0;  // In 16-bit code units.
766     uint32_t line_ = 0;  // Source code line number starting at 1.
767     const char* source_file_ = nullptr;  // nullptr if the file from ClassDef still applies.
768     bool prologue_end_ = false;
769     bool epilogue_begin_ = false;
770   };
771 
772   struct LocalInfo {
773     LocalInfo() = default;
774 
775     const char* name_ = nullptr;  // E.g., list.  It can be nullptr if unknown.
776     const char* descriptor_ = nullptr;  // E.g., Ljava/util/LinkedList;
777     const char* signature_ = nullptr;  // E.g., java.util.LinkedList<java.lang.Integer>
778     uint32_t start_address_ = 0;  // PC location where the local is first defined.
779     uint32_t end_address_ = 0;  // PC location where the local is no longer defined.
780     uint16_t reg_ = 0;  // Dex register which stores the values.
781     bool is_live_ = false;  // Is the local defined and live.
782   };
783 
784   // Callback for "new locals table entry".
785   typedef void (*DexDebugNewLocalCb)(void* context, const LocalInfo& entry);
786 
787   static bool LineNumForPcCb(void* context, const PositionInfo& entry);
788 
GetAnnotationsDirectory(const ClassDef & class_def)789   const AnnotationsDirectoryItem* GetAnnotationsDirectory(const ClassDef& class_def) const {
790     return DataPointer<AnnotationsDirectoryItem>(class_def.annotations_off_);
791   }
792 
GetClassAnnotationSet(const AnnotationsDirectoryItem * anno_dir)793   const AnnotationSetItem* GetClassAnnotationSet(const AnnotationsDirectoryItem* anno_dir) const {
794     return DataPointer<AnnotationSetItem>(anno_dir->class_annotations_off_);
795   }
796 
GetFieldAnnotations(const AnnotationsDirectoryItem * anno_dir)797   const FieldAnnotationsItem* GetFieldAnnotations(const AnnotationsDirectoryItem* anno_dir) const {
798     return (anno_dir->fields_size_ == 0)
799          ? nullptr
800          : reinterpret_cast<const FieldAnnotationsItem*>(&anno_dir[1]);
801   }
802 
GetMethodAnnotations(const AnnotationsDirectoryItem * anno_dir)803   const MethodAnnotationsItem* GetMethodAnnotations(const AnnotationsDirectoryItem* anno_dir)
804       const {
805     if (anno_dir->methods_size_ == 0) {
806       return nullptr;
807     }
808     // Skip past the header and field annotations.
809     const uint8_t* addr = reinterpret_cast<const uint8_t*>(&anno_dir[1]);
810     addr += anno_dir->fields_size_ * sizeof(FieldAnnotationsItem);
811     return reinterpret_cast<const MethodAnnotationsItem*>(addr);
812   }
813 
GetParameterAnnotations(const AnnotationsDirectoryItem * anno_dir)814   const ParameterAnnotationsItem* GetParameterAnnotations(const AnnotationsDirectoryItem* anno_dir)
815       const {
816     if (anno_dir->parameters_size_ == 0) {
817       return nullptr;
818     }
819     // Skip past the header, field annotations, and method annotations.
820     const uint8_t* addr = reinterpret_cast<const uint8_t*>(&anno_dir[1]);
821     addr += anno_dir->fields_size_ * sizeof(FieldAnnotationsItem);
822     addr += anno_dir->methods_size_ * sizeof(MethodAnnotationsItem);
823     return reinterpret_cast<const ParameterAnnotationsItem*>(addr);
824   }
825 
GetFieldAnnotationSetItem(const FieldAnnotationsItem & anno_item)826   const AnnotationSetItem* GetFieldAnnotationSetItem(const FieldAnnotationsItem& anno_item) const {
827     return DataPointer<AnnotationSetItem>(anno_item.annotations_off_);
828   }
829 
GetMethodAnnotationSetItem(const MethodAnnotationsItem & anno_item)830   const AnnotationSetItem* GetMethodAnnotationSetItem(const MethodAnnotationsItem& anno_item)
831       const {
832     return DataPointer<AnnotationSetItem>(anno_item.annotations_off_);
833   }
834 
GetParameterAnnotationSetRefList(const ParameterAnnotationsItem * anno_item)835   const AnnotationSetRefList* GetParameterAnnotationSetRefList(
836       const ParameterAnnotationsItem* anno_item) const {
837     return DataPointer<AnnotationSetRefList>(anno_item->annotations_off_);
838   }
839 
GetAnnotationItemAtOffset(uint32_t offset)840   ALWAYS_INLINE const AnnotationItem* GetAnnotationItemAtOffset(uint32_t offset) const {
841     return DataPointer<AnnotationItem>(offset);
842   }
843 
GetAnnotationItem(const AnnotationSetItem * set_item,uint32_t index)844   const AnnotationItem* GetAnnotationItem(const AnnotationSetItem* set_item, uint32_t index) const {
845     DCHECK_LE(index, set_item->size_);
846     return GetAnnotationItemAtOffset(set_item->entries_[index]);
847   }
848 
GetSetRefItemItem(const AnnotationSetRefItem * anno_item)849   const AnnotationSetItem* GetSetRefItemItem(const AnnotationSetRefItem* anno_item) const {
850     return DataPointer<AnnotationSetItem>(anno_item->annotations_off_);
851   }
852 
853   // Debug info opcodes and constants
854   enum {
855     DBG_END_SEQUENCE         = 0x00,
856     DBG_ADVANCE_PC           = 0x01,
857     DBG_ADVANCE_LINE         = 0x02,
858     DBG_START_LOCAL          = 0x03,
859     DBG_START_LOCAL_EXTENDED = 0x04,
860     DBG_END_LOCAL            = 0x05,
861     DBG_RESTART_LOCAL        = 0x06,
862     DBG_SET_PROLOGUE_END     = 0x07,
863     DBG_SET_EPILOGUE_BEGIN   = 0x08,
864     DBG_SET_FILE             = 0x09,
865     DBG_FIRST_SPECIAL        = 0x0a,
866     DBG_LINE_BASE            = -4,
867     DBG_LINE_RANGE           = 15,
868   };
869 
870   struct LineNumFromPcContext {
LineNumFromPcContextLineNumFromPcContext871     LineNumFromPcContext(uint32_t address, uint32_t line_num)
872         : address_(address), line_num_(line_num) {}
873     uint32_t address_;
874     uint32_t line_num_;
875    private:
876     DISALLOW_COPY_AND_ASSIGN(LineNumFromPcContext);
877   };
878 
879   // Returns false if there is no debugging information or if it cannot be decoded.
880   template<typename NewLocalCallback, typename IndexToStringData, typename TypeIndexToStringData>
881   static bool DecodeDebugLocalInfo(const uint8_t* stream,
882                                    const std::string& location,
883                                    const char* declaring_class_descriptor,
884                                    const std::vector<const char*>& arg_descriptors,
885                                    const std::string& method_name,
886                                    bool is_static,
887                                    uint16_t registers_size,
888                                    uint16_t ins_size,
889                                    uint16_t insns_size_in_code_units,
890                                    IndexToStringData index_to_string_data,
891                                    TypeIndexToStringData type_index_to_string_data,
892                                    NewLocalCallback new_local,
893                                    void* context);
894   template<typename NewLocalCallback>
895   bool DecodeDebugLocalInfo(uint32_t registers_size,
896                             uint32_t ins_size,
897                             uint32_t insns_size_in_code_units,
898                             uint32_t debug_info_offset,
899                             bool is_static,
900                             uint32_t method_idx,
901                             NewLocalCallback new_local,
902                             void* context) const;
903 
904   // Returns false if there is no debugging information or if it cannot be decoded.
905   template<typename DexDebugNewPosition, typename IndexToStringData>
906   static bool DecodeDebugPositionInfo(const uint8_t* stream,
907                                       IndexToStringData index_to_string_data,
908                                       DexDebugNewPosition position_functor,
909                                       void* context);
910   template<typename DexDebugNewPosition>
911   bool DecodeDebugPositionInfo(uint32_t debug_info_offset,
912                                DexDebugNewPosition position_functor,
913                                void* context) const;
914 
GetSourceFile(const ClassDef & class_def)915   const char* GetSourceFile(const ClassDef& class_def) const {
916     if (!class_def.source_file_idx_.IsValid()) {
917       return nullptr;
918     } else {
919       return StringDataByIdx(class_def.source_file_idx_);
920     }
921   }
922 
923   int GetPermissions() const;
924 
925   bool IsReadOnly() const;
926 
927   bool EnableWrite() const;
928 
929   bool DisableWrite() const;
930 
Begin()931   const uint8_t* Begin() const {
932     return begin_;
933   }
934 
Size()935   size_t Size() const {
936     return size_;
937   }
938 
DataBegin()939   const uint8_t* DataBegin() const {
940     return data_begin_;
941   }
942 
DataSize()943   size_t DataSize() const {
944     return data_size_;
945   }
946 
947   template <typename T>
DataPointer(size_t offset)948   const T* DataPointer(size_t offset) const {
949     DCHECK_LT(offset, DataSize()) << "Offset past end of data section";
950     return (offset != 0u) ? reinterpret_cast<const T*>(DataBegin() + offset) : nullptr;
951   }
952 
GetOatDexFile()953   const OatDexFile* GetOatDexFile() const {
954     return oat_dex_file_;
955   }
956 
957   // Used by oat writer.
SetOatDexFile(OatDexFile * oat_dex_file)958   void SetOatDexFile(OatDexFile* oat_dex_file) const {
959     oat_dex_file_ = oat_dex_file;
960   }
961 
962   // Read MapItems and validate/set remaining offsets.
GetMapList()963   const DexFile::MapList* GetMapList() const {
964     return reinterpret_cast<const DexFile::MapList*>(DataBegin() + header_->map_off_);
965   }
966 
967   // Utility methods for reading integral values from a buffer.
968   static int32_t ReadSignedInt(const uint8_t* ptr, int zwidth);
969   static uint32_t ReadUnsignedInt(const uint8_t* ptr, int zwidth, bool fill_on_right);
970   static int64_t ReadSignedLong(const uint8_t* ptr, int zwidth);
971   static uint64_t ReadUnsignedLong(const uint8_t* ptr, int zwidth, bool fill_on_right);
972 
973   // Recalculates the checksum of the dex file. Does not use the current value in the header.
974   virtual uint32_t CalculateChecksum() const;
975   static uint32_t CalculateChecksum(const uint8_t* begin, size_t size);
976   static uint32_t ChecksumMemoryRange(const uint8_t* begin, size_t size);
977 
978   // Returns a human-readable form of the method at an index.
979   std::string PrettyMethod(uint32_t method_idx, bool with_signature = true) const;
980   // Returns a human-readable form of the field at an index.
981   std::string PrettyField(uint32_t field_idx, bool with_type = true) const;
982   // Returns a human-readable form of the type at an index.
983   std::string PrettyType(dex::TypeIndex type_idx) const;
984 
985   // Not virtual for performance reasons.
IsCompactDexFile()986   ALWAYS_INLINE bool IsCompactDexFile() const {
987     return is_compact_dex_;
988   }
IsStandardDexFile()989   ALWAYS_INLINE bool IsStandardDexFile() const {
990     return !is_compact_dex_;
991   }
992   ALWAYS_INLINE const StandardDexFile* AsStandardDexFile() const;
993   ALWAYS_INLINE const CompactDexFile* AsCompactDexFile() const;
994 
IsPlatformDexFile()995   ALWAYS_INLINE bool IsPlatformDexFile() const {
996     return is_platform_dex_;
997   }
998 
SetIsPlatformDexFile()999   ALWAYS_INLINE void SetIsPlatformDexFile() {
1000     is_platform_dex_ = true;
1001   }
1002 
IsInMainSection(const void * addr)1003   bool IsInMainSection(const void* addr) const {
1004     return Begin() <= addr && addr < Begin() + Size();
1005   }
1006 
IsInDataSection(const void * addr)1007   bool IsInDataSection(const void* addr) const {
1008     return DataBegin() <= addr && addr < DataBegin() + DataSize();
1009   }
1010 
GetContainer()1011   DexFileContainer* GetContainer() const {
1012     return container_.get();
1013   }
1014 
1015   // Changes the dex file pointed to by class_it to not have any hiddenapi flags.
1016   static void UnHideAccessFlags(ClassDataItemIterator& class_it);
1017 
1018  protected:
1019   // First Dex format version supporting default methods.
1020   static const uint32_t kDefaultMethodsVersion = 37;
1021 
1022   DexFile(const uint8_t* base,
1023           size_t size,
1024           const uint8_t* data_begin,
1025           size_t data_size,
1026           const std::string& location,
1027           uint32_t location_checksum,
1028           const OatDexFile* oat_dex_file,
1029           std::unique_ptr<DexFileContainer> container,
1030           bool is_compact_dex);
1031 
1032   // Top-level initializer that calls other Init methods.
1033   bool Init(std::string* error_msg);
1034 
1035   // Returns true if the header magic and version numbers are of the expected values.
1036   bool CheckMagicAndVersion(std::string* error_msg) const;
1037 
1038   // Initialize section info for sections only found in map. Returns true on success.
1039   void InitializeSectionsFromMapList();
1040 
1041   // The base address of the memory mapping.
1042   const uint8_t* const begin_;
1043 
1044   // The size of the underlying memory allocation in bytes.
1045   const size_t size_;
1046 
1047   // The base address of the data section (same as Begin() for standard dex).
1048   const uint8_t* const data_begin_;
1049 
1050   // The size of the data section.
1051   const size_t data_size_;
1052 
1053   // Typically the dex file name when available, alternatively some identifying string.
1054   //
1055   // The ClassLinker will use this to match DexFiles the boot class
1056   // path to DexCache::GetLocation when loading from an image.
1057   const std::string location_;
1058 
1059   const uint32_t location_checksum_;
1060 
1061   // Points to the header section.
1062   const Header* const header_;
1063 
1064   // Points to the base of the string identifier list.
1065   const StringId* const string_ids_;
1066 
1067   // Points to the base of the type identifier list.
1068   const TypeId* const type_ids_;
1069 
1070   // Points to the base of the field identifier list.
1071   const FieldId* const field_ids_;
1072 
1073   // Points to the base of the method identifier list.
1074   const MethodId* const method_ids_;
1075 
1076   // Points to the base of the prototype identifier list.
1077   const ProtoId* const proto_ids_;
1078 
1079   // Points to the base of the class definition list.
1080   const ClassDef* const class_defs_;
1081 
1082   // Points to the base of the method handles list.
1083   const MethodHandleItem* method_handles_;
1084 
1085   // Number of elements in the method handles list.
1086   size_t num_method_handles_;
1087 
1088   // Points to the base of the call sites id list.
1089   const CallSiteIdItem* call_site_ids_;
1090 
1091   // Number of elements in the call sites list.
1092   size_t num_call_site_ids_;
1093 
1094   // If this dex file was loaded from an oat file, oat_dex_file_ contains a
1095   // pointer to the OatDexFile it was loaded from. Otherwise oat_dex_file_ is
1096   // null.
1097   mutable const OatDexFile* oat_dex_file_;
1098 
1099   // Manages the underlying memory allocation.
1100   std::unique_ptr<DexFileContainer> container_;
1101 
1102   // If the dex file is a compact dex file. If false then the dex file is a standard dex file.
1103   const bool is_compact_dex_;
1104 
1105   // If the dex file is located in /system/framework/.
1106   bool is_platform_dex_;
1107 
1108   friend class DexFileLoader;
1109   friend class DexFileVerifierTest;
1110   friend class OatWriter;
1111 };
1112 
1113 std::ostream& operator<<(std::ostream& os, const DexFile& dex_file);
1114 
1115 // Iterate over a dex file's ProtoId's paramters
1116 class DexFileParameterIterator {
1117  public:
DexFileParameterIterator(const DexFile & dex_file,const DexFile::ProtoId & proto_id)1118   DexFileParameterIterator(const DexFile& dex_file, const DexFile::ProtoId& proto_id)
1119       : dex_file_(dex_file) {
1120     type_list_ = dex_file_.GetProtoParameters(proto_id);
1121     if (type_list_ != nullptr) {
1122       size_ = type_list_->Size();
1123     }
1124   }
HasNext()1125   bool HasNext() const { return pos_ < size_; }
Size()1126   size_t Size() const { return size_; }
Next()1127   void Next() { ++pos_; }
GetTypeIdx()1128   dex::TypeIndex GetTypeIdx() {
1129     return type_list_->GetTypeItem(pos_).type_idx_;
1130   }
GetDescriptor()1131   const char* GetDescriptor() {
1132     return dex_file_.StringByTypeIdx(dex::TypeIndex(GetTypeIdx()));
1133   }
1134  private:
1135   const DexFile& dex_file_;
1136   const DexFile::TypeList* type_list_ = nullptr;
1137   uint32_t size_ = 0;
1138   uint32_t pos_ = 0;
1139   DISALLOW_IMPLICIT_CONSTRUCTORS(DexFileParameterIterator);
1140 };
1141 
1142 // Abstract the signature of a method.
1143 class Signature : public ValueObject {
1144  public:
1145   std::string ToString() const;
1146 
NoSignature()1147   static Signature NoSignature() {
1148     return Signature();
1149   }
1150 
1151   bool IsVoid() const;
1152   uint32_t GetNumberOfParameters() const;
1153 
1154   bool operator==(const Signature& rhs) const;
1155   bool operator!=(const Signature& rhs) const {
1156     return !(*this == rhs);
1157   }
1158 
1159   bool operator==(const StringPiece& rhs) const;
1160 
1161  private:
Signature(const DexFile * dex,const DexFile::ProtoId & proto)1162   Signature(const DexFile* dex, const DexFile::ProtoId& proto) : dex_file_(dex), proto_id_(&proto) {
1163   }
1164 
1165   Signature() = default;
1166 
1167   friend class DexFile;
1168 
1169   const DexFile* const dex_file_ = nullptr;
1170   const DexFile::ProtoId* const proto_id_ = nullptr;
1171 };
1172 std::ostream& operator<<(std::ostream& os, const Signature& sig);
1173 
1174 // Iterate and decode class_data_item
1175 class ClassDataItemIterator {
1176  public:
ClassDataItemIterator(const DexFile & dex_file,const uint8_t * raw_class_data_item)1177   ClassDataItemIterator(const DexFile& dex_file, const uint8_t* raw_class_data_item)
1178       : dex_file_(dex_file), pos_(0), ptr_pos_(raw_class_data_item), last_idx_(0) {
1179     ReadClassDataHeader();
1180     if (EndOfInstanceFieldsPos() > 0) {
1181       ReadClassDataField();
1182     } else if (EndOfVirtualMethodsPos() > 0) {
1183       ReadClassDataMethod();
1184     }
1185   }
NumStaticFields()1186   uint32_t NumStaticFields() const {
1187     return header_.static_fields_size_;
1188   }
NumInstanceFields()1189   uint32_t NumInstanceFields() const {
1190     return header_.instance_fields_size_;
1191   }
NumDirectMethods()1192   uint32_t NumDirectMethods() const {
1193     return header_.direct_methods_size_;
1194   }
NumVirtualMethods()1195   uint32_t NumVirtualMethods() const {
1196     return header_.virtual_methods_size_;
1197   }
IsAtMethod()1198   bool IsAtMethod() const {
1199     return pos_ >= EndOfInstanceFieldsPos();
1200   }
HasNextStaticField()1201   bool HasNextStaticField() const {
1202     return pos_ < EndOfStaticFieldsPos();
1203   }
HasNextInstanceField()1204   bool HasNextInstanceField() const {
1205     return pos_ >= EndOfStaticFieldsPos() && pos_ < EndOfInstanceFieldsPos();
1206   }
HasNextDirectMethod()1207   bool HasNextDirectMethod() const {
1208     return pos_ >= EndOfInstanceFieldsPos() && pos_ < EndOfDirectMethodsPos();
1209   }
HasNextVirtualMethod()1210   bool HasNextVirtualMethod() const {
1211     return pos_ >= EndOfDirectMethodsPos() && pos_ < EndOfVirtualMethodsPos();
1212   }
HasNextMethod()1213   bool HasNextMethod() const {
1214     const bool result = pos_ >= EndOfInstanceFieldsPos() && pos_ < EndOfVirtualMethodsPos();
1215     DCHECK_EQ(result, HasNextDirectMethod() || HasNextVirtualMethod());
1216     return result;
1217   }
SkipStaticFields()1218   void SkipStaticFields() {
1219     while (HasNextStaticField()) {
1220       Next();
1221     }
1222   }
SkipInstanceFields()1223   void SkipInstanceFields() {
1224     while (HasNextInstanceField()) {
1225       Next();
1226     }
1227   }
SkipAllFields()1228   void SkipAllFields() {
1229     SkipStaticFields();
1230     SkipInstanceFields();
1231   }
SkipDirectMethods()1232   void SkipDirectMethods() {
1233     while (HasNextDirectMethod()) {
1234       Next();
1235     }
1236   }
SkipVirtualMethods()1237   void SkipVirtualMethods() {
1238     while (HasNextVirtualMethod()) {
1239       Next();
1240     }
1241   }
HasNext()1242   bool HasNext() const {
1243     return pos_ < EndOfVirtualMethodsPos();
1244   }
Next()1245   inline void Next() {
1246     pos_++;
1247     if (pos_ < EndOfStaticFieldsPos()) {
1248       last_idx_ = GetMemberIndex();
1249       ReadClassDataField();
1250     } else if (pos_ == EndOfStaticFieldsPos() && NumInstanceFields() > 0) {
1251       last_idx_ = 0;  // transition to next array, reset last index
1252       ReadClassDataField();
1253     } else if (pos_ < EndOfInstanceFieldsPos()) {
1254       last_idx_ = GetMemberIndex();
1255       ReadClassDataField();
1256     } else if (pos_ == EndOfInstanceFieldsPos() && NumDirectMethods() > 0) {
1257       last_idx_ = 0;  // transition to next array, reset last index
1258       ReadClassDataMethod();
1259     } else if (pos_ < EndOfDirectMethodsPos()) {
1260       last_idx_ = GetMemberIndex();
1261       ReadClassDataMethod();
1262     } else if (pos_ == EndOfDirectMethodsPos() && NumVirtualMethods() > 0) {
1263       last_idx_ = 0;  // transition to next array, reset last index
1264       ReadClassDataMethod();
1265     } else if (pos_ < EndOfVirtualMethodsPos()) {
1266       last_idx_ = GetMemberIndex();
1267       ReadClassDataMethod();
1268     } else {
1269       DCHECK(!HasNext());
1270     }
1271   }
GetMemberIndex()1272   uint32_t GetMemberIndex() const {
1273     if (pos_ < EndOfInstanceFieldsPos()) {
1274       return last_idx_ + field_.field_idx_delta_;
1275     } else {
1276       DCHECK_LT(pos_, EndOfVirtualMethodsPos());
1277       return last_idx_ + method_.method_idx_delta_;
1278     }
1279   }
GetRawMemberAccessFlags()1280   uint32_t GetRawMemberAccessFlags() const {
1281     if (pos_ < EndOfInstanceFieldsPos()) {
1282       return field_.access_flags_;
1283     } else {
1284       DCHECK_LT(pos_, EndOfVirtualMethodsPos());
1285       return method_.access_flags_;
1286     }
1287   }
GetFieldAccessFlags()1288   uint32_t GetFieldAccessFlags() const {
1289     return GetMemberAccessFlags() & kAccValidFieldFlags;
1290   }
GetMethodAccessFlags()1291   uint32_t GetMethodAccessFlags() const {
1292     return GetMemberAccessFlags() & kAccValidMethodFlags;
1293   }
GetMemberAccessFlags()1294   uint32_t GetMemberAccessFlags() const {
1295     return HiddenApiAccessFlags::RemoveFromDex(GetRawMemberAccessFlags());
1296   }
DecodeHiddenAccessFlags()1297   HiddenApiAccessFlags::ApiList DecodeHiddenAccessFlags() const {
1298     return HiddenApiAccessFlags::DecodeFromDex(GetRawMemberAccessFlags());
1299   }
MemberIsNative()1300   bool MemberIsNative() const {
1301     return GetRawMemberAccessFlags() & kAccNative;
1302   }
MemberIsFinal()1303   bool MemberIsFinal() const {
1304     return GetRawMemberAccessFlags() & kAccFinal;
1305   }
1306   ALWAYS_INLINE InvokeType GetMethodInvokeType(const DexFile::ClassDef& class_def) const;
GetMethodCodeItem()1307   const DexFile::CodeItem* GetMethodCodeItem() const {
1308     return dex_file_.GetCodeItem(method_.code_off_);
1309   }
GetMethodCodeItemOffset()1310   uint32_t GetMethodCodeItemOffset() const {
1311     return method_.code_off_;
1312   }
DataPointer()1313   const uint8_t* DataPointer() const {
1314     return ptr_pos_;
1315   }
EndDataPointer()1316   const uint8_t* EndDataPointer() const {
1317     CHECK(!HasNext());
1318     return ptr_pos_;
1319   }
1320 
1321  private:
1322   // A dex file's class_data_item is leb128 encoded, this structure holds a decoded form of the
1323   // header for a class_data_item
1324   struct ClassDataHeader {
1325     uint32_t static_fields_size_;  // the number of static fields
1326     uint32_t instance_fields_size_;  // the number of instance fields
1327     uint32_t direct_methods_size_;  // the number of direct methods
1328     uint32_t virtual_methods_size_;  // the number of virtual methods
1329   } header_;
1330 
1331   // Read and decode header from a class_data_item stream into header
1332   void ReadClassDataHeader();
1333 
EndOfStaticFieldsPos()1334   uint32_t EndOfStaticFieldsPos() const {
1335     return header_.static_fields_size_;
1336   }
EndOfInstanceFieldsPos()1337   uint32_t EndOfInstanceFieldsPos() const {
1338     return EndOfStaticFieldsPos() + header_.instance_fields_size_;
1339   }
EndOfDirectMethodsPos()1340   uint32_t EndOfDirectMethodsPos() const {
1341     return EndOfInstanceFieldsPos() + header_.direct_methods_size_;
1342   }
EndOfVirtualMethodsPos()1343   uint32_t EndOfVirtualMethodsPos() const {
1344     return EndOfDirectMethodsPos() + header_.virtual_methods_size_;
1345   }
1346 
1347   // A decoded version of the field of a class_data_item
1348   struct ClassDataField {
1349     uint32_t field_idx_delta_;  // delta of index into the field_ids array for FieldId
1350     uint32_t access_flags_;  // access flags for the field
ClassDataFieldClassDataField1351     ClassDataField() :  field_idx_delta_(0), access_flags_(0) {}
1352 
1353    private:
1354     DISALLOW_COPY_AND_ASSIGN(ClassDataField);
1355   };
1356   ClassDataField field_;
1357 
1358   // Read and decode a field from a class_data_item stream into field
1359   void ReadClassDataField();
1360 
1361   // A decoded version of the method of a class_data_item
1362   struct ClassDataMethod {
1363     uint32_t method_idx_delta_;  // delta of index into the method_ids array for MethodId
1364     uint32_t access_flags_;
1365     uint32_t code_off_;
ClassDataMethodClassDataMethod1366     ClassDataMethod() : method_idx_delta_(0), access_flags_(0), code_off_(0) {}
1367 
1368    private:
1369     DISALLOW_COPY_AND_ASSIGN(ClassDataMethod);
1370   };
1371   ClassDataMethod method_;
1372 
1373   // Read and decode a method from a class_data_item stream into method
1374   void ReadClassDataMethod();
1375 
1376   const DexFile& dex_file_;
1377   size_t pos_;  // integral number of items passed
1378   const uint8_t* ptr_pos_;  // pointer into stream of class_data_item
1379   uint32_t last_idx_;  // last read field or method index to apply delta to
1380   DISALLOW_IMPLICIT_CONSTRUCTORS(ClassDataItemIterator);
1381 };
1382 
1383 class EncodedArrayValueIterator {
1384  public:
1385   EncodedArrayValueIterator(const DexFile& dex_file, const uint8_t* array_data);
1386 
HasNext()1387   bool HasNext() const { return pos_ < array_size_; }
1388 
1389   void Next();
1390 
1391   enum ValueType {
1392     kByte         = 0x00,
1393     kShort        = 0x02,
1394     kChar         = 0x03,
1395     kInt          = 0x04,
1396     kLong         = 0x06,
1397     kFloat        = 0x10,
1398     kDouble       = 0x11,
1399     kMethodType   = 0x15,
1400     kMethodHandle = 0x16,
1401     kString       = 0x17,
1402     kType         = 0x18,
1403     kField        = 0x19,
1404     kMethod       = 0x1a,
1405     kEnum         = 0x1b,
1406     kArray        = 0x1c,
1407     kAnnotation   = 0x1d,
1408     kNull         = 0x1e,
1409     kBoolean      = 0x1f,
1410   };
1411 
GetValueType()1412   ValueType GetValueType() const { return type_; }
GetJavaValue()1413   const jvalue& GetJavaValue() const { return jval_; }
1414 
1415  protected:
1416   static constexpr uint8_t kEncodedValueTypeMask = 0x1f;  // 0b11111
1417   static constexpr uint8_t kEncodedValueArgShift = 5;
1418 
1419   const DexFile& dex_file_;
1420   size_t array_size_;  // Size of array.
1421   size_t pos_;  // Current position.
1422   const uint8_t* ptr_;  // Pointer into encoded data array.
1423   ValueType type_;  // Type of current encoded value.
1424   jvalue jval_;  // Value of current encoded value.
1425 
1426  private:
1427   DISALLOW_IMPLICIT_CONSTRUCTORS(EncodedArrayValueIterator);
1428 };
1429 std::ostream& operator<<(std::ostream& os, const EncodedArrayValueIterator::ValueType& code);
1430 
1431 class EncodedStaticFieldValueIterator : public EncodedArrayValueIterator {
1432  public:
EncodedStaticFieldValueIterator(const DexFile & dex_file,const DexFile::ClassDef & class_def)1433   EncodedStaticFieldValueIterator(const DexFile& dex_file,
1434                                   const DexFile::ClassDef& class_def)
1435       : EncodedArrayValueIterator(dex_file,
1436                                   dex_file.GetEncodedStaticFieldValuesArray(class_def))
1437   {}
1438 
1439  private:
1440   DISALLOW_IMPLICIT_CONSTRUCTORS(EncodedStaticFieldValueIterator);
1441 };
1442 std::ostream& operator<<(std::ostream& os, const EncodedStaticFieldValueIterator::ValueType& code);
1443 
1444 class CallSiteArrayValueIterator : public EncodedArrayValueIterator {
1445  public:
CallSiteArrayValueIterator(const DexFile & dex_file,const DexFile::CallSiteIdItem & call_site_id)1446   CallSiteArrayValueIterator(const DexFile& dex_file,
1447                              const DexFile::CallSiteIdItem& call_site_id)
1448       : EncodedArrayValueIterator(dex_file,
1449                                   dex_file.GetCallSiteEncodedValuesArray(call_site_id))
1450   {}
1451 
Size()1452   uint32_t Size() const { return array_size_; }
1453 
1454  private:
1455   DISALLOW_IMPLICIT_CONSTRUCTORS(CallSiteArrayValueIterator);
1456 };
1457 std::ostream& operator<<(std::ostream& os, const CallSiteArrayValueIterator::ValueType& code);
1458 
1459 }  // namespace art
1460 
1461 #endif  // ART_LIBDEXFILE_DEX_DEX_FILE_H_
1462