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