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