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