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