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 <android-base/logging.h>
21 
22 #include <array>
23 #include <memory>
24 #include <optional>
25 #include <string>
26 #include <string_view>
27 #include <vector>
28 
29 #include "base/array_ref.h"
30 #include "base/globals.h"
31 #include "base/macros.h"
32 #include "base/mman.h"  // For the PROT_* and MAP_* constants.
33 #include "base/value_object.h"
34 #include "dex_file_structs.h"
35 #include "dex_file_types.h"
36 #include "jni.h"
37 #include "modifiers.h"
38 
39 namespace art {
40 
41 class ClassDataItemIterator;
42 class ClassIterator;
43 class CompactDexFile;
44 class DexInstructionIterator;
45 enum InvokeType : uint32_t;
46 template <typename Iter> class IterationRange;
47 class MemMap;
48 class OatDexFile;
49 class Signature;
50 class StandardDexFile;
51 class ZipArchive;
52 
53 namespace hiddenapi {
54 enum class Domain : char;
55 }  // namespace hiddenapi
56 
57 // Owns the physical storage that backs one or more DexFiles (that is, it can be shared).
58 // It frees the storage (e.g. closes file) when all DexFiles that use it are all closed.
59 //
60 // The memory range must include all data used by the DexFiles including any shared data.
61 //
62 // It might also include surrounding non-dex data (e.g. it might represent vdex file).
63 class DexFileContainer {
64  public:
DexFileContainer()65   DexFileContainer() { }
~DexFileContainer()66   virtual ~DexFileContainer() {}
67 
68   virtual bool IsReadOnly() const = 0;
69 
70   // Make the underlying writeable. Return true on success (memory can be written).
71   virtual bool EnableWrite() = 0;
72   // Make the underlying read-only. Return true on success (memory is read-only now).
73   virtual bool DisableWrite() = 0;
74 
75   virtual const uint8_t* Begin() const = 0;
76   virtual const uint8_t* End() const = 0;
Size()77   size_t Size() const { return End() - Begin(); }
78 
79   // TODO: Remove. This is only used by dexlayout to override the data section of the dex header,
80   //       and redirect it to intermediate memory buffer at completely unrelated memory location.
Data()81   virtual ArrayRef<const uint8_t> Data() const { return {}; }
82 
IsZip()83   bool IsZip() const { return is_zip_; }
SetIsZip()84   void SetIsZip() { is_zip_ = true; }
IsFileMap()85   virtual bool IsFileMap() const { return false; }
86 
87  private:
88   bool is_zip_ = false;
89   DISALLOW_COPY_AND_ASSIGN(DexFileContainer);
90 };
91 
92 class MemoryDexFileContainer : public DexFileContainer {
93  public:
MemoryDexFileContainer(const uint8_t * begin,const uint8_t * end)94   MemoryDexFileContainer(const uint8_t* begin, const uint8_t* end) : begin_(begin), end_(end) {}
MemoryDexFileContainer(const uint8_t * begin,size_t size)95   MemoryDexFileContainer(const uint8_t* begin, size_t size) : begin_(begin), end_(begin + size) {}
IsReadOnly()96   bool IsReadOnly() const override { return true; }
EnableWrite()97   bool EnableWrite() override { return false; }
DisableWrite()98   bool DisableWrite() override { return false; }
Begin()99   const uint8_t* Begin() const override { return begin_; }
End()100   const uint8_t* End() const override { return end_; }
101 
102  private:
103   const uint8_t* const begin_;
104   const uint8_t* const end_;
105   DISALLOW_COPY_AND_ASSIGN(MemoryDexFileContainer);
106 };
107 
108 // Dex file is the API that exposes native dex files (ordinary dex files) and CompactDex.
109 // Originally, the dex file format used by ART was mostly the same as APKs. The only change was
110 // quickened opcodes and layout optimizations.
111 // Since ART needs to support both native dex files and CompactDex files, the DexFile interface
112 // provides an abstraction to facilitate this.
113 class DexFile {
114  public:
115   // Number of bytes in the dex file magic.
116   static constexpr size_t kDexMagicSize = 4;
117   static constexpr size_t kDexVersionLen = 4;
118 
119   static constexpr uint32_t kDexContainerVersion = 41;
120 
121   // First Dex format version enforcing class definition ordering rules.
122   static constexpr uint32_t kClassDefinitionOrderEnforcedVersion = 37;
123 
124   static constexpr size_t kSha1DigestSize = 20;
125   static constexpr uint32_t kDexEndianConstant = 0x12345678;
126 
127   // The value of an invalid index.
128   static constexpr uint16_t kDexNoIndex16 = 0xFFFF;
129   static constexpr uint32_t kDexNoIndex32 = 0xFFFFFFFF;
130 
131   using Magic = std::array<uint8_t, 8>;
132 
133   struct Sha1 : public std::array<uint8_t, kSha1DigestSize> {
134     std::string ToString() const;
135   };
136 
137   static_assert(std::is_standard_layout_v<Sha1>);
138 
139   // Raw header_item.
140   struct Header {
141     Magic magic_ = {};
142     uint32_t checksum_ = 0;  // See also location_checksum_
143     Sha1 signature_ = {};
144     uint32_t file_size_ = 0;  // size of entire file
145     uint32_t header_size_ = 0;  // offset to start of next section
146     uint32_t endian_tag_ = 0;
147     uint32_t link_size_ = 0;  // unused
148     uint32_t link_off_ = 0;  // unused
149     uint32_t map_off_ = 0;  // map list offset from data_off_
150     uint32_t string_ids_size_ = 0;  // number of StringIds
151     uint32_t string_ids_off_ = 0;  // file offset of StringIds array
152     uint32_t type_ids_size_ = 0;  // number of TypeIds, we don't support more than 65535
153     uint32_t type_ids_off_ = 0;  // file offset of TypeIds array
154     uint32_t proto_ids_size_ = 0;  // number of ProtoIds, we don't support more than 65535
155     uint32_t proto_ids_off_ = 0;  // file offset of ProtoIds array
156     uint32_t field_ids_size_ = 0;  // number of FieldIds
157     uint32_t field_ids_off_ = 0;  // file offset of FieldIds array
158     uint32_t method_ids_size_ = 0;  // number of MethodIds
159     uint32_t method_ids_off_ = 0;  // file offset of MethodIds array
160     uint32_t class_defs_size_ = 0;  // number of ClassDefs
161     uint32_t class_defs_off_ = 0;  // file offset of ClassDef array
162     uint32_t data_size_ = 0;  // size of data section
163     uint32_t data_off_ = 0;  // file offset of data section
164 
165     // Decode the dex magic version
166     uint32_t GetVersion() const;
167 
168     // Get the header_size that is expected for this version.
169     uint32_t GetExpectedHeaderSize() const;
170 
171     // Returns true for standard DEX version 41 or newer.
172     bool HasDexContainer() const;
173 
174     // Returns offset of this header within the container.
175     // Returns 0 for older dex versions without container.
176     uint32_t HeaderOffset() const;
177 
178     // Returns size of the whole container.
179     // Returns file_size_ for older dex versions without container.
180     uint32_t ContainerSize() const;
181 
182     // Set the DEX container fields to the given values.
183     // Must be [0, file_size_) for older dex versions.
184     void SetDexContainer(size_t header_offset, size_t container_size);
185   };
186 
187   struct HeaderV41 : public Header {
188     uint32_t container_size_ = 0;  // total size of all dex files in the container.
189     uint32_t header_offset_ = 0;   // offset of this dex's header in the container.
190   };
191 
192   // Map item type codes.
193   enum MapItemType : uint16_t {  // private
194     kDexTypeHeaderItem               = 0x0000,
195     kDexTypeStringIdItem             = 0x0001,
196     kDexTypeTypeIdItem               = 0x0002,
197     kDexTypeProtoIdItem              = 0x0003,
198     kDexTypeFieldIdItem              = 0x0004,
199     kDexTypeMethodIdItem             = 0x0005,
200     kDexTypeClassDefItem             = 0x0006,
201     kDexTypeCallSiteIdItem           = 0x0007,
202     kDexTypeMethodHandleItem         = 0x0008,
203     kDexTypeMapList                  = 0x1000,
204     kDexTypeTypeList                 = 0x1001,
205     kDexTypeAnnotationSetRefList     = 0x1002,
206     kDexTypeAnnotationSetItem        = 0x1003,
207     kDexTypeClassDataItem            = 0x2000,
208     kDexTypeCodeItem                 = 0x2001,
209     kDexTypeStringDataItem           = 0x2002,
210     kDexTypeDebugInfoItem            = 0x2003,
211     kDexTypeAnnotationItem           = 0x2004,
212     kDexTypeEncodedArrayItem         = 0x2005,
213     kDexTypeAnnotationsDirectoryItem = 0x2006,
214     kDexTypeHiddenapiClassData       = 0xF000,
215   };
216 
217   // MethodHandle Types
218   enum class MethodHandleType : uint16_t {  // private
219     kStaticPut         = 0x0000,  // a setter for a given static field.
220     kStaticGet         = 0x0001,  // a getter for a given static field.
221     kInstancePut       = 0x0002,  // a setter for a given instance field.
222     kInstanceGet       = 0x0003,  // a getter for a given instance field.
223     kInvokeStatic      = 0x0004,  // an invoker for a given static method.
224     kInvokeInstance    = 0x0005,  // invoke_instance : an invoker for a given instance method. This
225                                   // can be any non-static method on any class (or interface) except
226                                   // for “<init>”.
227     kInvokeConstructor = 0x0006,  // an invoker for a given constructor.
228     kInvokeDirect      = 0x0007,  // an invoker for a direct (special) method.
229     kInvokeInterface   = 0x0008,  // an invoker for an interface method.
230     kLast = kInvokeInterface
231   };
232 
233   // Annotation constants.
234   enum {
235     kDexVisibilityBuild         = 0x00,     /* annotation visibility */
236     kDexVisibilityRuntime       = 0x01,
237     kDexVisibilitySystem        = 0x02,
238 
239     kDexAnnotationByte          = 0x00,
240     kDexAnnotationShort         = 0x02,
241     kDexAnnotationChar          = 0x03,
242     kDexAnnotationInt           = 0x04,
243     kDexAnnotationLong          = 0x06,
244     kDexAnnotationFloat         = 0x10,
245     kDexAnnotationDouble        = 0x11,
246     kDexAnnotationMethodType    = 0x15,
247     kDexAnnotationMethodHandle  = 0x16,
248     kDexAnnotationString        = 0x17,
249     kDexAnnotationType          = 0x18,
250     kDexAnnotationField         = 0x19,
251     kDexAnnotationMethod        = 0x1a,
252     kDexAnnotationEnum          = 0x1b,
253     kDexAnnotationArray         = 0x1c,
254     kDexAnnotationAnnotation    = 0x1d,
255     kDexAnnotationNull          = 0x1e,
256     kDexAnnotationBoolean       = 0x1f,
257 
258     kDexAnnotationValueTypeMask = 0x1f,     /* low 5 bits */
259     kDexAnnotationValueArgShift = 5,
260   };
261 
262   enum AnnotationResultStyle {  // private
263     kAllObjects,
264     kPrimitivesOrObjects,
265     kAllRaw
266   };
267 
268   struct AnnotationValue;
269 
270   // Closes a .dex file.
271   virtual ~DexFile();
272 
GetLocation()273   const std::string& GetLocation() const {
274     return location_;
275   }
276 
277   // For DexFiles directly from .dex files, this is the checksum from the DexFile::Header.
278   // For DexFiles opened from a zip files, this will be the ZipEntry CRC32 of classes.dex.
GetLocationChecksum()279   uint32_t GetLocationChecksum() const {
280     return location_checksum_;
281   }
282 
GetSha1()283   Sha1 GetSha1() const { return header_->signature_; }
284 
GetHeader()285   const Header& GetHeader() const {
286     DCHECK(header_ != nullptr) << GetLocation();
287     return *header_;
288   }
289 
290   // Decode the dex magic version
GetDexVersion()291   uint32_t GetDexVersion() const {
292     return GetHeader().GetVersion();
293   }
294 
295   // Returns true if this is DEX V41 or later (i.e. supports container).
296   // Returns true even if the container contains just a single DEX file.
HasDexContainer()297   bool HasDexContainer() const { return GetHeader().HasDexContainer(); }
298 
299   // Returns the whole memory range of the DEX V41 container.
300   // Returns just the range of the DEX file for V40 or older.
GetDexContainerRange()301   ArrayRef<const uint8_t> GetDexContainerRange() const {
302     return {Begin() - header_->HeaderOffset(), header_->ContainerSize()};
303   }
304 
IsDexContainerFirstEntry()305   bool IsDexContainerFirstEntry() const { return Begin() == GetDexContainerRange().begin(); }
306 
IsDexContainerLastEntry()307   bool IsDexContainerLastEntry() const { return End() == GetDexContainerRange().end(); }
308 
309   // Returns true if the byte string points to the magic value.
310   virtual bool IsMagicValid() const = 0;
311 
312   // Returns true if the byte string after the magic is the correct value.
313   virtual bool IsVersionValid() const = 0;
314 
315   // Returns true if the dex file supports default methods.
316   virtual bool SupportsDefaultMethods() const = 0;
317 
318   // Returns the maximum size in bytes needed to store an equivalent dex file strictly conforming to
319   // the dex file specification. That is the size if we wanted to get rid of all the
320   // quickening/compact-dexing/etc.
321   //
322   // TODO This should really be an exact size! b/72402467
323   virtual size_t GetDequickenedSize() const = 0;
324 
325   // Returns the number of string identifiers in the .dex file.
NumStringIds()326   size_t NumStringIds() const {
327     DCHECK(header_ != nullptr) << GetLocation();
328     return header_->string_ids_size_;
329   }
330 
331   // Returns the StringId at the specified index.
GetStringId(dex::StringIndex idx)332   const dex::StringId& GetStringId(dex::StringIndex idx) const {
333     DCHECK_LT(idx.index_, NumStringIds()) << GetLocation();
334     return string_ids_[idx.index_];
335   }
336 
GetIndexForStringId(const dex::StringId & string_id)337   dex::StringIndex GetIndexForStringId(const dex::StringId& string_id) const {
338     CHECK_GE(&string_id, string_ids_) << GetLocation();
339     CHECK_LT(&string_id, string_ids_ + header_->string_ids_size_) << GetLocation();
340     return dex::StringIndex(&string_id - string_ids_);
341   }
342 
343   // Returns a pointer to the UTF-8 string data referred to by the given string_id as well as the
344   // length of the string when decoded as a UTF-16 string. Note the UTF-16 length is not the same
345   // as the string length of the string data.
346   const char* GetStringDataAndUtf16Length(const dex::StringId& string_id,
347                                           uint32_t* utf16_length) const;
348   const char* GetStringDataAndUtf16Length(dex::StringIndex string_idx,
349                                           uint32_t* utf16_length) const;
350 
351   uint32_t GetStringUtf16Length(const dex::StringId& string_id) const;
352 
353   const char* GetStringData(const dex::StringId& string_id) const;
354   const char* GetStringData(dex::StringIndex string_idx) const;
355 
356   std::string_view GetStringView(const dex::StringId& string_id) const;
357   std::string_view GetStringView(dex::StringIndex string_idx) const;
358 
359   // Looks up a string id for a given modified utf8 string.
360   const dex::StringId* FindStringId(const char* string) const;
361 
362   // Returns the number of type identifiers in the .dex file.
NumTypeIds()363   uint32_t NumTypeIds() const {
364     DCHECK(header_ != nullptr) << GetLocation();
365     return header_->type_ids_size_;
366   }
367 
IsTypeIndexValid(dex::TypeIndex idx)368   bool IsTypeIndexValid(dex::TypeIndex idx) const {
369     return idx.IsValid() && idx.index_ < NumTypeIds();
370   }
371 
372   // Returns the TypeId at the specified index.
GetTypeId(dex::TypeIndex idx)373   const dex::TypeId& GetTypeId(dex::TypeIndex idx) const {
374     DCHECK_LT(idx.index_, NumTypeIds()) << GetLocation();
375     return type_ids_[idx.index_];
376   }
377 
GetIndexForTypeId(const dex::TypeId & type_id)378   dex::TypeIndex GetIndexForTypeId(const dex::TypeId& type_id) const {
379     CHECK_GE(&type_id, type_ids_) << GetLocation();
380     CHECK_LT(&type_id, type_ids_ + header_->type_ids_size_) << GetLocation();
381     size_t result = &type_id - type_ids_;
382     DCHECK_LT(result, 65536U) << GetLocation();
383     return dex::TypeIndex(static_cast<uint16_t>(result));
384   }
385 
386   // Returns the type descriptor string of a type id.
387   const char* GetTypeDescriptor(const dex::TypeId& type_id) const;
388   const char* GetTypeDescriptor(dex::TypeIndex type_idx) const;
389   std::string_view GetTypeDescriptorView(const dex::TypeId& type_id) const;
390   std::string_view GetTypeDescriptorView(dex::TypeIndex type_idx) const;
391 
392   const dex::TypeId* FindTypeId(std::string_view descriptor) const;
393 
394   // Looks up a type for the given string index
395   const dex::TypeId* FindTypeId(dex::StringIndex string_idx) const;
396 
397   // Returns the number of field identifiers in the .dex file.
NumFieldIds()398   size_t NumFieldIds() const {
399     DCHECK(header_ != nullptr) << GetLocation();
400     return header_->field_ids_size_;
401   }
402 
403   // Returns the FieldId at the specified index.
GetFieldId(uint32_t idx)404   const dex::FieldId& GetFieldId(uint32_t idx) const {
405     DCHECK_LT(idx, NumFieldIds()) << GetLocation();
406     return field_ids_[idx];
407   }
408 
GetIndexForFieldId(const dex::FieldId & field_id)409   uint32_t GetIndexForFieldId(const dex::FieldId& field_id) const {
410     CHECK_GE(&field_id, field_ids_) << GetLocation();
411     CHECK_LT(&field_id, field_ids_ + header_->field_ids_size_) << GetLocation();
412     return &field_id - field_ids_;
413   }
414 
415   // Looks up a field by its declaring class, name and type
416   const dex::FieldId* FindFieldId(const dex::TypeId& declaring_klass,
417                                   const dex::StringId& name,
418                                   const dex::TypeId& type) const;
419 
420   // Return the code-item offset associated with the class and method or nullopt
421   // if the method does not exist or has no code.
422   std::optional<uint32_t> GetCodeItemOffset(const dex::ClassDef& class_def,
423                                             uint32_t dex_method_idx) const;
424 
425   // Return the code-item offset associated with the class and method or
426   // LOG(FATAL) if the method does not exist or has no code.
427   uint32_t FindCodeItemOffset(const dex::ClassDef& class_def,
428                               uint32_t dex_method_idx) const;
429 
430   virtual uint32_t GetCodeItemSize(const dex::CodeItem& disk_code_item) const = 0;
431 
432   // Returns the declaring class descriptor string of a field id.
433   const char* GetFieldDeclaringClassDescriptor(const dex::FieldId& field_id) const;
434   const char* GetFieldDeclaringClassDescriptor(uint32_t field_idx) const;
435   std::string_view GetFieldDeclaringClassDescriptorView(const dex::FieldId& field_id) const;
436   std::string_view GetFieldDeclaringClassDescriptorView(uint32_t field_idx) const;
437 
438   // Returns the class descriptor string of a field id.
439   const char* GetFieldTypeDescriptor(const dex::FieldId& field_id) const;
440   const char* GetFieldTypeDescriptor(uint32_t field_idx) const;
441   std::string_view GetFieldTypeDescriptorView(const dex::FieldId& field_id) const;
442   std::string_view GetFieldTypeDescriptorView(uint32_t field_idx) const;
443 
444   // Returns the name of a field id.
445   const char* GetFieldName(const dex::FieldId& field_id) const;
446   const char* GetFieldName(uint32_t field_idx) const;
447   std::string_view GetFieldNameView(const dex::FieldId& field_id) const;
448   std::string_view GetFieldNameView(uint32_t field_idx) const;
449 
450   // Returns the number of method identifiers in the .dex file.
NumMethodIds()451   size_t NumMethodIds() const {
452     DCHECK(header_ != nullptr) << GetLocation();
453     return header_->method_ids_size_;
454   }
455 
456   // Returns the MethodId at the specified index.
GetMethodId(uint32_t idx)457   const dex::MethodId& GetMethodId(uint32_t idx) const {
458     DCHECK_LT(idx, NumMethodIds()) << GetLocation();
459     return method_ids_[idx];
460   }
461 
GetIndexForMethodId(const dex::MethodId & method_id)462   uint32_t GetIndexForMethodId(const dex::MethodId& method_id) const {
463     CHECK_GE(&method_id, method_ids_) << GetLocation();
464     CHECK_LT(&method_id, method_ids_ + header_->method_ids_size_) << GetLocation();
465     return &method_id - method_ids_;
466   }
467 
468   // Looks up a method by its declaring class, name and proto_id
469   const dex::MethodId* FindMethodId(const dex::TypeId& declaring_klass,
470                                     const dex::StringId& name,
471                                     const dex::ProtoId& signature) const;
472 
473   const dex::MethodId* FindMethodIdByIndex(dex::TypeIndex declaring_klass,
474                                            dex::StringIndex name,
475                                            dex::ProtoIndex signature) const;
476 
477   // Returns the declaring class descriptor string of a method id.
478   const char* GetMethodDeclaringClassDescriptor(const dex::MethodId& method_id) const;
479   const char* GetMethodDeclaringClassDescriptor(uint32_t method_idx) const;
480   std::string_view GetMethodDeclaringClassDescriptorView(const dex::MethodId& method_id) const;
481   std::string_view GetMethodDeclaringClassDescriptorView(uint32_t method_idx) const;
482 
483   // Returns the prototype of a method id.
GetMethodPrototype(const dex::MethodId & method_id)484   const dex::ProtoId& GetMethodPrototype(const dex::MethodId& method_id) const {
485     return GetProtoId(method_id.proto_idx_);
486   }
487 
488   // Returns a representation of the signature of a method id.
489   const Signature GetMethodSignature(const dex::MethodId& method_id) const;
490 
491   // Returns a representation of the signature of a proto id.
492   const Signature GetProtoSignature(const dex::ProtoId& proto_id) const;
493 
494   // Returns the name of a method id.
495   const char* GetMethodName(const dex::MethodId& method_id) const;
496   const char* GetMethodName(const dex::MethodId& method_id, uint32_t* utf_length) const;
497   const char* GetMethodName(uint32_t method_idx) const;
498   const char* GetMethodName(uint32_t method_idx, uint32_t* utf_length) const;
499   std::string_view GetMethodNameView(const dex::MethodId& method_id) const;
500   std::string_view GetMethodNameView(uint32_t method_idx) const;
501 
502   // Returns the shorty of a method by its index.
503   const char* GetMethodShorty(uint32_t idx) const;
504   std::string_view GetMethodShortyView(uint32_t idx) const;
505 
506   // Returns the shorty of a method id.
507   const char* GetMethodShorty(const dex::MethodId& method_id) const;
508   const char* GetMethodShorty(const dex::MethodId& method_id, uint32_t* length) const;
509   std::string_view GetMethodShortyView(const dex::MethodId& method_id) const;
510 
511   // Returns the number of class definitions in the .dex file.
NumClassDefs()512   uint32_t NumClassDefs() const {
513     DCHECK(header_ != nullptr) << GetLocation();
514     return header_->class_defs_size_;
515   }
516 
517   // Returns the ClassDef at the specified index.
GetClassDef(uint16_t idx)518   const dex::ClassDef& GetClassDef(uint16_t idx) const {
519     DCHECK_LT(idx, NumClassDefs()) << GetLocation();
520     return class_defs_[idx];
521   }
522 
GetIndexForClassDef(const dex::ClassDef & class_def)523   uint16_t GetIndexForClassDef(const dex::ClassDef& class_def) const {
524     CHECK_GE(&class_def, class_defs_) << GetLocation();
525     CHECK_LT(&class_def, class_defs_ + header_->class_defs_size_) << GetLocation();
526     return &class_def - class_defs_;
527   }
528 
529   // Returns the class descriptor string of a class definition.
530   const char* GetClassDescriptor(const dex::ClassDef& class_def) const;
531 
532   // Looks up a class definition by its type index.
533   const dex::ClassDef* FindClassDef(dex::TypeIndex type_idx) const;
534 
GetInterfacesList(const dex::ClassDef & class_def)535   const dex::TypeList* GetInterfacesList(const dex::ClassDef& class_def) const {
536     return DataPointer<dex::TypeList>(class_def.interfaces_off_);
537   }
538 
NumMethodHandles()539   uint32_t NumMethodHandles() const {
540     return num_method_handles_;
541   }
542 
GetMethodHandle(uint32_t idx)543   const dex::MethodHandleItem& GetMethodHandle(uint32_t idx) const {
544     CHECK_LT(idx, NumMethodHandles());
545     return method_handles_[idx];
546   }
547 
NumCallSiteIds()548   uint32_t NumCallSiteIds() const {
549     return num_call_site_ids_;
550   }
551 
GetCallSiteId(uint32_t idx)552   const dex::CallSiteIdItem& GetCallSiteId(uint32_t idx) const {
553     CHECK_LT(idx, NumCallSiteIds());
554     return call_site_ids_[idx];
555   }
556 
557   // Returns a pointer to the raw memory mapped class_data_item
GetClassData(const dex::ClassDef & class_def)558   const uint8_t* GetClassData(const dex::ClassDef& class_def) const {
559     return DataPointer<uint8_t>(class_def.class_data_off_);
560   }
561 
562   // Return the code item for a provided offset.
GetCodeItem(const uint32_t code_off)563   const dex::CodeItem* GetCodeItem(const uint32_t code_off) const {
564     // May be null for native or abstract methods.
565     return DataPointer<dex::CodeItem>(code_off);
566   }
567 
568   const char* GetReturnTypeDescriptor(const dex::ProtoId& proto_id) const;
569 
570   // Returns the number of prototype identifiers in the .dex file.
NumProtoIds()571   size_t NumProtoIds() const {
572     DCHECK(header_ != nullptr) << GetLocation();
573     return header_->proto_ids_size_;
574   }
575 
576   // Returns the ProtoId at the specified index.
GetProtoId(dex::ProtoIndex idx)577   const dex::ProtoId& GetProtoId(dex::ProtoIndex idx) const {
578     DCHECK_LT(idx.index_, NumProtoIds()) << GetLocation();
579     return proto_ids_[idx.index_];
580   }
581 
GetIndexForProtoId(const dex::ProtoId & proto_id)582   dex::ProtoIndex GetIndexForProtoId(const dex::ProtoId& proto_id) const {
583     CHECK_GE(&proto_id, proto_ids_) << GetLocation();
584     CHECK_LT(&proto_id, proto_ids_ + header_->proto_ids_size_) << GetLocation();
585     return dex::ProtoIndex(&proto_id - proto_ids_);
586   }
587 
588   // Looks up a proto id for a given return type and signature type list
589   const dex::ProtoId* FindProtoId(dex::TypeIndex return_type_idx,
590                                   const dex::TypeIndex* signature_type_idxs,
591                              uint32_t signature_length) const;
FindProtoId(dex::TypeIndex return_type_idx,const std::vector<dex::TypeIndex> & signature_type_idxs)592   const dex::ProtoId* FindProtoId(dex::TypeIndex return_type_idx,
593                                   const std::vector<dex::TypeIndex>& signature_type_idxs) const {
594     return FindProtoId(return_type_idx, &signature_type_idxs[0], signature_type_idxs.size());
595   }
596 
597   // Given a signature place the type ids into the given vector, returns true on success
598   bool CreateTypeList(std::string_view signature,
599                       dex::TypeIndex* return_type_idx,
600                       std::vector<dex::TypeIndex>* param_type_idxs) const;
601 
602   // Returns the short form method descriptor for the given prototype.
603   const char* GetShorty(dex::ProtoIndex proto_idx) const;
604   std::string_view GetShortyView(dex::ProtoIndex proto_idx) const;
605   std::string_view GetShortyView(const dex::ProtoId& proto_id) const;
606 
GetProtoParameters(const dex::ProtoId & proto_id)607   const dex::TypeList* GetProtoParameters(const dex::ProtoId& proto_id) const {
608     return DataPointer<dex::TypeList>(proto_id.parameters_off_);
609   }
610 
GetEncodedStaticFieldValuesArray(const dex::ClassDef & class_def)611   const uint8_t* GetEncodedStaticFieldValuesArray(const dex::ClassDef& class_def) const {
612     return DataPointer<uint8_t>(class_def.static_values_off_);
613   }
614 
GetCallSiteEncodedValuesArray(const dex::CallSiteIdItem & call_site_id)615   const uint8_t* GetCallSiteEncodedValuesArray(const dex::CallSiteIdItem& call_site_id) const {
616     return DataBegin() + call_site_id.data_off_;
617   }
618 
619   dex::ProtoIndex GetProtoIndexForCallSite(uint32_t call_site_idx) const;
620 
621   static const dex::TryItem* GetTryItems(const DexInstructionIterator& code_item_end,
622                                          uint32_t offset);
623 
624   // Get the base of the encoded data for the given DexCode.
625   static const uint8_t* GetCatchHandlerData(const DexInstructionIterator& code_item_end,
626                                             uint32_t tries_size,
627                                             uint32_t offset);
628 
629   // Find which try region is associated with the given address (ie dex pc). Returns -1 if none.
630   static int32_t FindTryItem(const dex::TryItem* try_items, uint32_t tries_size, uint32_t address);
631 
632   // Get the pointer to the start of the debugging data
GetDebugInfoStream(uint32_t debug_info_off)633   const uint8_t* GetDebugInfoStream(uint32_t debug_info_off) const {
634     // Check that the offset is in bounds.
635     // Note that although the specification says that 0 should be used if there
636     // is no debug information, some applications incorrectly use 0xFFFFFFFF.
637     return (debug_info_off == 0 || debug_info_off >= DataSize()) ? nullptr :
638                                                                    DataBegin() + debug_info_off;
639   }
640 
641   struct PositionInfo {
642     PositionInfo() = default;
643 
644     uint32_t address_ = 0;  // In 16-bit code units.
645     uint32_t line_ = 0;  // Source code line number starting at 1.
646     const char* source_file_ = nullptr;  // nullptr if the file from ClassDef still applies.
647     bool prologue_end_ = false;
648     bool epilogue_begin_ = false;
649   };
650 
651   struct LocalInfo {
652     LocalInfo() = default;
653 
654     const char* name_ = nullptr;  // E.g., list.  It can be nullptr if unknown.
655     const char* descriptor_ = nullptr;  // E.g., Ljava/util/LinkedList;
656     const char* signature_ = nullptr;  // E.g., java.util.LinkedList<java.lang.Integer>
657     uint32_t start_address_ = 0;  // PC location where the local is first defined.
658     uint32_t end_address_ = 0;  // PC location where the local is no longer defined.
659     uint16_t reg_ = 0;  // Dex register which stores the values.
660     bool is_live_ = false;  // Is the local defined and live.
661   };
662 
663   // Callback for "new locals table entry".
664   using DexDebugNewLocalCb = void (*)(void* context, const LocalInfo& entry);
665 
GetAnnotationsDirectory(const dex::ClassDef & class_def)666   const dex::AnnotationsDirectoryItem* GetAnnotationsDirectory(const dex::ClassDef& class_def)
667       const {
668     return DataPointer<dex::AnnotationsDirectoryItem>(class_def.annotations_off_);
669   }
670 
GetClassAnnotationSet(const dex::AnnotationsDirectoryItem * anno_dir)671   const dex::AnnotationSetItem* GetClassAnnotationSet(const dex::AnnotationsDirectoryItem* anno_dir)
672       const {
673     return DataPointer<dex::AnnotationSetItem>(anno_dir->class_annotations_off_);
674   }
675 
GetFieldAnnotations(const dex::AnnotationsDirectoryItem * anno_dir)676   const dex::FieldAnnotationsItem* GetFieldAnnotations(
677       const dex::AnnotationsDirectoryItem* anno_dir) const {
678     return (anno_dir->fields_size_ == 0)
679          ? nullptr
680          : reinterpret_cast<const dex::FieldAnnotationsItem*>(&anno_dir[1]);
681   }
682 
GetMethodAnnotations(const dex::AnnotationsDirectoryItem * anno_dir)683   const dex::MethodAnnotationsItem* GetMethodAnnotations(
684       const dex::AnnotationsDirectoryItem* anno_dir) const {
685     if (anno_dir->methods_size_ == 0) {
686       return nullptr;
687     }
688     // Skip past the header and field annotations.
689     const uint8_t* addr = reinterpret_cast<const uint8_t*>(&anno_dir[1]);
690     addr += anno_dir->fields_size_ * sizeof(dex::FieldAnnotationsItem);
691     return reinterpret_cast<const dex::MethodAnnotationsItem*>(addr);
692   }
693 
GetParameterAnnotations(const dex::AnnotationsDirectoryItem * anno_dir)694   const dex::ParameterAnnotationsItem* GetParameterAnnotations(
695       const dex::AnnotationsDirectoryItem* anno_dir) const {
696     if (anno_dir->parameters_size_ == 0) {
697       return nullptr;
698     }
699     // Skip past the header, field annotations, and method annotations.
700     const uint8_t* addr = reinterpret_cast<const uint8_t*>(&anno_dir[1]);
701     addr += anno_dir->fields_size_ * sizeof(dex::FieldAnnotationsItem);
702     addr += anno_dir->methods_size_ * sizeof(dex::MethodAnnotationsItem);
703     return reinterpret_cast<const dex::ParameterAnnotationsItem*>(addr);
704   }
705 
GetFieldAnnotationSetItem(const dex::FieldAnnotationsItem & anno_item)706   const dex::AnnotationSetItem* GetFieldAnnotationSetItem(
707       const dex::FieldAnnotationsItem& anno_item) const {
708     // `DexFileVerifier` checks that the offset is not zero.
709     return NonNullDataPointer<dex::AnnotationSetItem>(anno_item.annotations_off_);
710   }
711 
GetMethodAnnotationSetItem(const dex::MethodAnnotationsItem & anno_item)712   const dex::AnnotationSetItem* GetMethodAnnotationSetItem(
713       const dex::MethodAnnotationsItem& anno_item) const {
714     // `DexFileVerifier` checks that the offset is not zero.
715     return NonNullDataPointer<dex::AnnotationSetItem>(anno_item.annotations_off_);
716   }
717 
GetParameterAnnotationSetRefList(const dex::ParameterAnnotationsItem * anno_item)718   const dex::AnnotationSetRefList* GetParameterAnnotationSetRefList(
719       const dex::ParameterAnnotationsItem* anno_item) const {
720     return DataPointer<dex::AnnotationSetRefList>(anno_item->annotations_off_);
721   }
722 
GetAnnotationItemAtOffset(uint32_t offset)723   ALWAYS_INLINE const dex::AnnotationItem* GetAnnotationItemAtOffset(uint32_t offset) const {
724     return DataPointer<dex::AnnotationItem>(offset);
725   }
726 
GetHiddenapiClassDataAtOffset(uint32_t offset)727   ALWAYS_INLINE const dex::HiddenapiClassData* GetHiddenapiClassDataAtOffset(uint32_t offset)
728       const {
729     return DataPointer<dex::HiddenapiClassData>(offset);
730   }
731 
GetHiddenapiClassData()732   ALWAYS_INLINE const dex::HiddenapiClassData* GetHiddenapiClassData() const {
733     return hiddenapi_class_data_;
734   }
735 
HasHiddenapiClassData()736   ALWAYS_INLINE bool HasHiddenapiClassData() const {
737     return hiddenapi_class_data_ != nullptr;
738   }
739 
GetAnnotationItem(const dex::AnnotationSetItem * set_item,uint32_t index)740   const dex::AnnotationItem* GetAnnotationItem(const dex::AnnotationSetItem* set_item,
741                                                uint32_t index) const {
742     DCHECK_LE(index, set_item->size_);
743     return GetAnnotationItemAtOffset(set_item->entries_[index]);
744   }
745 
GetSetRefItemItem(const dex::AnnotationSetRefItem * anno_item)746   const dex::AnnotationSetItem* GetSetRefItemItem(const dex::AnnotationSetRefItem* anno_item)
747       const {
748     return DataPointer<dex::AnnotationSetItem>(anno_item->annotations_off_);
749   }
750 
751   // Debug info opcodes and constants
752   enum {
753     DBG_END_SEQUENCE         = 0x00,
754     DBG_ADVANCE_PC           = 0x01,
755     DBG_ADVANCE_LINE         = 0x02,
756     DBG_START_LOCAL          = 0x03,
757     DBG_START_LOCAL_EXTENDED = 0x04,
758     DBG_END_LOCAL            = 0x05,
759     DBG_RESTART_LOCAL        = 0x06,
760     DBG_SET_PROLOGUE_END     = 0x07,
761     DBG_SET_EPILOGUE_BEGIN   = 0x08,
762     DBG_SET_FILE             = 0x09,
763     DBG_FIRST_SPECIAL        = 0x0a,
764     DBG_LINE_BASE            = -4,
765     DBG_LINE_RANGE           = 15,
766   };
767 
768   // Returns false if there is no debugging information or if it cannot be decoded.
769   template<typename NewLocalCallback, typename IndexToStringData, typename TypeIndexToStringData>
770   static bool DecodeDebugLocalInfo(const uint8_t* stream,
771                                    const std::string& location,
772                                    const char* declaring_class_descriptor,
773                                    const std::vector<const char*>& arg_descriptors,
774                                    const std::string& method_name,
775                                    bool is_static,
776                                    uint16_t registers_size,
777                                    uint16_t ins_size,
778                                    uint16_t insns_size_in_code_units,
779                                    const IndexToStringData& index_to_string_data,
780                                    const TypeIndexToStringData& type_index_to_string_data,
781                                    const NewLocalCallback& new_local) NO_THREAD_SAFETY_ANALYSIS;
782   template<typename NewLocalCallback>
783   bool DecodeDebugLocalInfo(uint32_t registers_size,
784                             uint32_t ins_size,
785                             uint32_t insns_size_in_code_units,
786                             uint32_t debug_info_offset,
787                             bool is_static,
788                             uint32_t method_idx,
789                             const NewLocalCallback& new_local) const;
790 
791   // Returns false if there is no debugging information or if it cannot be decoded.
792   template<typename DexDebugNewPosition, typename IndexToStringData>
793   static bool DecodeDebugPositionInfo(const uint8_t* stream,
794                                       IndexToStringData&& index_to_string_data,
795                                       DexDebugNewPosition&& position_functor);
796 
GetSourceFile(const dex::ClassDef & class_def)797   const char* GetSourceFile(const dex::ClassDef& class_def) const {
798     if (!class_def.source_file_idx_.IsValid()) {
799       return nullptr;
800     } else {
801       return GetStringData(class_def.source_file_idx_);
802     }
803   }
804 
805   bool IsReadOnly() const;
806 
807   bool EnableWrite() const;
808 
809   bool DisableWrite() const;
810 
Begin()811   const uint8_t* Begin() const { return begin_; }
812 
End()813   const uint8_t* End() const { return Begin() + Size(); }
814 
Size()815   size_t Size() const { return header_->file_size_; }
816 
SizeIncludingSharedData()817   size_t SizeIncludingSharedData() const { return GetDexContainerRange().end() - Begin(); }
818 
819   static ArrayRef<const uint8_t> GetDataRange(const uint8_t* data, DexFileContainer* container);
820 
DataBegin()821   const uint8_t* DataBegin() const { return data_.data(); }
822 
DataSize()823   size_t DataSize() const { return data_.size(); }
824 
825   template <typename T>
DataPointer(size_t offset)826   const T* DataPointer(size_t offset) const {
827     return (offset != 0u) ? NonNullDataPointer<T>(offset) : nullptr;
828   }
829 
830   template <typename T>
NonNullDataPointer(size_t offset)831   const T* NonNullDataPointer(size_t offset) const {
832     DCHECK_NE(offset, 0u);
833     DCHECK_LT(offset, DataSize()) << "Offset past end of data section";
834     return reinterpret_cast<const T*>(DataBegin() + offset);
835   }
836 
GetOatDexFile()837   const OatDexFile* GetOatDexFile() const {
838     return oat_dex_file_;
839   }
840 
841   // Used by oat writer.
SetOatDexFile(const OatDexFile * oat_dex_file)842   void SetOatDexFile(const OatDexFile* oat_dex_file) const {
843     oat_dex_file_ = oat_dex_file;
844   }
845 
846   // Read MapItems and validate/set remaining offsets.
GetMapList()847   const dex::MapList* GetMapList() const {
848     return reinterpret_cast<const dex::MapList*>(DataBegin() + header_->map_off_);
849   }
850 
851   // Utility methods for reading integral values from a buffer.
852   static int32_t ReadSignedInt(const uint8_t* ptr, int zwidth);
853   static uint32_t ReadUnsignedInt(const uint8_t* ptr, int zwidth, bool fill_on_right);
854   static int64_t ReadSignedLong(const uint8_t* ptr, int zwidth);
855   static uint64_t ReadUnsignedLong(const uint8_t* ptr, int zwidth, bool fill_on_right);
856 
857   // Recalculates the checksum of the dex file. Does not use the current value in the header.
858   virtual uint32_t CalculateChecksum() const;
859   static uint32_t CalculateChecksum(const uint8_t* begin, size_t size);
860   static uint32_t ChecksumMemoryRange(const uint8_t* begin, size_t size);
861 
862   // Number of bytes at the beginning of the dex file header which are skipped
863   // when computing the adler32 checksum of the entire file.
864   static constexpr uint32_t kNumNonChecksumBytes = OFFSETOF_MEMBER(DexFile::Header, signature_);
865 
866   // Appends a human-readable form of the method at an index.
867   void AppendPrettyMethod(uint32_t method_idx, bool with_signature, std::string* result) const;
868   // Returns a human-readable form of the field at an index.
869   std::string PrettyField(uint32_t field_idx, bool with_type = true) const;
870   // Returns a human-readable form of the type at an index.
871   std::string PrettyType(dex::TypeIndex type_idx) const;
872 
873   ALWAYS_INLINE std::string PrettyMethod(uint32_t method_idx, bool with_signature = true) const {
874     std::string result;
875     AppendPrettyMethod(method_idx, with_signature, &result);
876     return result;
877   }
878 
879   // Not virtual for performance reasons.
IsCompactDexFile()880   ALWAYS_INLINE bool IsCompactDexFile() const {
881     return is_compact_dex_;
882   }
IsStandardDexFile()883   ALWAYS_INLINE bool IsStandardDexFile() const {
884     return !is_compact_dex_;
885   }
886   ALWAYS_INLINE const StandardDexFile* AsStandardDexFile() const;
887   ALWAYS_INLINE const CompactDexFile* AsCompactDexFile() const;
888 
GetHiddenapiDomain()889   hiddenapi::Domain GetHiddenapiDomain() const { return hiddenapi_domain_; }
SetHiddenapiDomain(hiddenapi::Domain value)890   void SetHiddenapiDomain(hiddenapi::Domain value) const { hiddenapi_domain_ = value; }
891 
IsInMainSection(const void * addr)892   bool IsInMainSection(const void* addr) const {
893     return Begin() <= addr && addr < Begin() + Size();
894   }
895 
IsInDataSection(const void * addr)896   bool IsInDataSection(const void* addr) const {
897     return DataBegin() <= addr && addr < DataBegin() + DataSize();
898   }
899 
GetContainer()900   const std::shared_ptr<DexFileContainer>& GetContainer() const { return container_; }
901 
902   IterationRange<ClassIterator> GetClasses() const;
903 
904   template <typename Visitor>
905   static uint32_t DecodeDebugInfoParameterNames(const uint8_t** debug_info,
906                                                 Visitor&& visitor);
907 
908   static inline bool StringEquals(const DexFile* df1, dex::StringIndex sidx1,
909                                   const DexFile* df2, dex::StringIndex sidx2);
910 
911   static int CompareDescriptors(std::string_view lhs, std::string_view rhs);
912   static int CompareMemberNames(std::string_view lhs, std::string_view rhs);
913 
914   static std::string_view StringViewFromUtf16Length(const char* utf8_data, size_t utf16_length);
915 
916  protected:
917   // First Dex format version supporting default methods.
918   static constexpr uint32_t kDefaultMethodsVersion = 37;
919 
920   DexFile(const uint8_t* base,
921           const std::string& location,
922           uint32_t location_checksum,
923           const OatDexFile* oat_dex_file,
924           // Shared since several dex files may be stored in the same logical container.
925           std::shared_ptr<DexFileContainer> container,
926           bool is_compact_dex);
927 
928   template <typename T>
929   const T* GetSection(const uint32_t* offset, DexFileContainer* container);
930 
931   // Top-level initializer that calls other Init methods.
932   bool Init(std::string* error_msg);
933 
934   // Returns true if the header magic and version numbers are of the expected values.
935   bool CheckMagicAndVersion(std::string* error_msg) const;
936 
937   // Initialize section info for sections only found in map. Returns true on success.
938   void InitializeSectionsFromMapList();
939 
940   // The base address of the memory mapping.
941   const uint8_t* const begin_;
942 
943   size_t unused_size_ = 0;  // Preserve layout for DRM (b/305203031).
944 
945   // Data memory range: Most dex offsets are relative to this memory range.
946   // Standard dex: same as (begin_, size_).
947   // Dex container: all dex files (starting from the first header).
948   // Compact: shared data which is located after all non-shared data.
949   //
950   // This is different to the "data section" in the standard dex header.
951   ArrayRef<const uint8_t> const data_;
952 
953   // The full absolute path to the dex file, if it was loaded from disk.
954   //
955   // Can also be a path to a multidex container (typically apk), followed by
956   // DexFileLoader.kMultiDexSeparator (i.e. '!') and the file inside the
957   // container.
958   //
959   // On host this may not be an absolute path.
960   //
961   // On device libnativeloader uses this to determine the location of the java
962   // package or shared library, which decides where to load native libraries
963   // from.
964   //
965   // The ClassLinker will use this to match DexFiles the boot class
966   // path to DexCache::GetLocation when loading from an image.
967   const std::string location_;
968 
969   const uint32_t location_checksum_;
970 
971   // Points to the header section.
972   const Header* const header_;
973 
974   // Points to the base of the string identifier list.
975   const dex::StringId* const string_ids_;
976 
977   // Points to the base of the type identifier list.
978   const dex::TypeId* const type_ids_;
979 
980   // Points to the base of the field identifier list.
981   const dex::FieldId* const field_ids_;
982 
983   // Points to the base of the method identifier list.
984   const dex::MethodId* const method_ids_;
985 
986   // Points to the base of the prototype identifier list.
987   const dex::ProtoId* const proto_ids_;
988 
989   // Points to the base of the class definition list.
990   const dex::ClassDef* const class_defs_;
991 
992   // Points to the base of the method handles list.
993   const dex::MethodHandleItem* method_handles_;
994 
995   // Number of elements in the method handles list.
996   size_t num_method_handles_;
997 
998   // Points to the base of the call sites id list.
999   const dex::CallSiteIdItem* call_site_ids_;
1000 
1001   // Number of elements in the call sites list.
1002   size_t num_call_site_ids_;
1003 
1004   // Points to the base of the hiddenapi class data item_, or nullptr if the dex
1005   // file does not have one.
1006   const dex::HiddenapiClassData* hiddenapi_class_data_;
1007 
1008   // If this dex file was loaded from an oat file, oat_dex_file_ contains a
1009   // pointer to the OatDexFile it was loaded from. Otherwise oat_dex_file_ is
1010   // null.
1011   mutable const OatDexFile* oat_dex_file_;
1012 
1013   // Manages the underlying memory allocation.
1014   std::shared_ptr<DexFileContainer> container_;
1015 
1016   // If the dex file is a compact dex file. If false then the dex file is a standard dex file.
1017   const bool is_compact_dex_;
1018 
1019   // The domain this dex file belongs to for hidden API access checks.
1020   // It is decleared `mutable` because the domain is assigned after the DexFile
1021   // has been created and can be changed later by the runtime.
1022   mutable hiddenapi::Domain hiddenapi_domain_;
1023 
1024   friend class DexFileLoader;
1025   friend class DexFileVerifierTest;
1026   friend class OatWriter;
1027 };
1028 
1029 std::ostream& operator<<(std::ostream& os, const DexFile& dex_file);
1030 
1031 // Iterate over a dex file's ProtoId's paramters
1032 class DexFileParameterIterator {
1033  public:
DexFileParameterIterator(const DexFile & dex_file,const dex::ProtoId & proto_id)1034   DexFileParameterIterator(const DexFile& dex_file, const dex::ProtoId& proto_id)
1035       : dex_file_(dex_file) {
1036     type_list_ = dex_file_.GetProtoParameters(proto_id);
1037     if (type_list_ != nullptr) {
1038       size_ = type_list_->Size();
1039     }
1040   }
HasNext()1041   bool HasNext() const { return pos_ < size_; }
Size()1042   size_t Size() const { return size_; }
Next()1043   void Next() { ++pos_; }
GetTypeIdx()1044   dex::TypeIndex GetTypeIdx() {
1045     return type_list_->GetTypeItem(pos_).type_idx_;
1046   }
GetDescriptor()1047   const char* GetDescriptor() {
1048     return dex_file_.GetTypeDescriptor(dex::TypeIndex(GetTypeIdx()));
1049   }
1050  private:
1051   const DexFile& dex_file_;
1052   const dex::TypeList* type_list_ = nullptr;
1053   uint32_t size_ = 0;
1054   uint32_t pos_ = 0;
1055   DISALLOW_IMPLICIT_CONSTRUCTORS(DexFileParameterIterator);
1056 };
1057 
1058 class EncodedArrayValueIterator {
1059  public:
1060   EncodedArrayValueIterator(const DexFile& dex_file, const uint8_t* array_data);
1061 
HasNext()1062   bool HasNext() const { return pos_ < array_size_; }
1063 
1064   WARN_UNUSED bool MaybeNext();
1065 
Next()1066   ALWAYS_INLINE void Next() {
1067     bool ok = MaybeNext();
1068     DCHECK(ok) << "Unknown type: " << GetValueType();
1069   }
1070 
1071   enum ValueType {
1072     kByte         = 0x00,
1073     kShort        = 0x02,
1074     kChar         = 0x03,
1075     kInt          = 0x04,
1076     kLong         = 0x06,
1077     kFloat        = 0x10,
1078     kDouble       = 0x11,
1079     kMethodType   = 0x15,
1080     kMethodHandle = 0x16,
1081     kString       = 0x17,
1082     kType         = 0x18,
1083     kField        = 0x19,
1084     kMethod       = 0x1a,
1085     kEnum         = 0x1b,
1086     kArray        = 0x1c,
1087     kAnnotation   = 0x1d,
1088     kNull         = 0x1e,
1089     kBoolean      = 0x1f,
1090     kEndOfInput   = 0xff,
1091   };
1092 
GetValueType()1093   ValueType GetValueType() const { return type_; }
GetJavaValue()1094   const jvalue& GetJavaValue() const { return jval_; }
1095 
1096  protected:
1097   static constexpr uint8_t kEncodedValueTypeMask = 0x1f;  // 0b11111
1098   static constexpr uint8_t kEncodedValueArgShift = 5;
1099 
1100   const DexFile& dex_file_;
1101   size_t array_size_;  // Size of array.
1102   size_t pos_;  // Current position.
1103   const uint8_t* ptr_;  // Pointer into encoded data array.
1104   ValueType type_;  // Type of current encoded value.
1105   jvalue jval_;  // Value of current encoded value.
1106 
1107  private:
1108   DISALLOW_IMPLICIT_CONSTRUCTORS(EncodedArrayValueIterator);
1109 };
1110 std::ostream& operator<<(std::ostream& os, EncodedArrayValueIterator::ValueType code);
1111 
1112 class EncodedStaticFieldValueIterator : public EncodedArrayValueIterator {
1113  public:
EncodedStaticFieldValueIterator(const DexFile & dex_file,const dex::ClassDef & class_def)1114   EncodedStaticFieldValueIterator(const DexFile& dex_file,
1115                                   const dex::ClassDef& class_def)
1116       : EncodedArrayValueIterator(dex_file,
1117                                   dex_file.GetEncodedStaticFieldValuesArray(class_def))
1118   {}
1119 
1120  private:
1121   DISALLOW_IMPLICIT_CONSTRUCTORS(EncodedStaticFieldValueIterator);
1122 };
1123 
1124 class CallSiteArrayValueIterator : public EncodedArrayValueIterator {
1125  public:
CallSiteArrayValueIterator(const DexFile & dex_file,const dex::CallSiteIdItem & call_site_id)1126   CallSiteArrayValueIterator(const DexFile& dex_file,
1127                              const dex::CallSiteIdItem& call_site_id)
1128       : EncodedArrayValueIterator(dex_file,
1129                                   dex_file.GetCallSiteEncodedValuesArray(call_site_id))
1130   {}
1131 
Size()1132   uint32_t Size() const { return array_size_; }
1133 
1134  private:
1135   DISALLOW_IMPLICIT_CONSTRUCTORS(CallSiteArrayValueIterator);
1136 };
1137 
1138 }  // namespace art
1139 
1140 #endif  // ART_LIBDEXFILE_DEX_DEX_FILE_H_
1141