1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2018 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_CLASS_ACCESSOR_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_LIBDEXFILE_DEX_CLASS_ACCESSOR_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include "code_item_accessors.h" 21*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file.h" 22*795d594fSAndroid Build Coastguard Worker #include "dex_file_types.h" 23*795d594fSAndroid Build Coastguard Worker #include "invoke_type.h" 24*795d594fSAndroid Build Coastguard Worker #include "modifiers.h" 25*795d594fSAndroid Build Coastguard Worker 26*795d594fSAndroid Build Coastguard Worker namespace art { 27*795d594fSAndroid Build Coastguard Worker 28*795d594fSAndroid Build Coastguard Worker namespace dex { 29*795d594fSAndroid Build Coastguard Worker struct ClassDef; 30*795d594fSAndroid Build Coastguard Worker struct CodeItem; 31*795d594fSAndroid Build Coastguard Worker class DexFileVerifier; 32*795d594fSAndroid Build Coastguard Worker } // namespace dex 33*795d594fSAndroid Build Coastguard Worker 34*795d594fSAndroid Build Coastguard Worker class ClassIteratorData; 35*795d594fSAndroid Build Coastguard Worker class DexFile; 36*795d594fSAndroid Build Coastguard Worker template <typename Iter> class IterationRange; 37*795d594fSAndroid Build Coastguard Worker class MethodReference; 38*795d594fSAndroid Build Coastguard Worker 39*795d594fSAndroid Build Coastguard Worker // Classes to access Dex data. 40*795d594fSAndroid Build Coastguard Worker class ClassAccessor { 41*795d594fSAndroid Build Coastguard Worker public: 42*795d594fSAndroid Build Coastguard Worker class BaseItem { 43*795d594fSAndroid Build Coastguard Worker public: BaseItem(const DexFile & dex_file,const uint8_t * ptr_pos,const uint8_t * hiddenapi_ptr_pos)44*795d594fSAndroid Build Coastguard Worker explicit BaseItem(const DexFile& dex_file, 45*795d594fSAndroid Build Coastguard Worker const uint8_t* ptr_pos, 46*795d594fSAndroid Build Coastguard Worker const uint8_t* hiddenapi_ptr_pos) 47*795d594fSAndroid Build Coastguard Worker : dex_file_(dex_file), ptr_pos_(ptr_pos), hiddenapi_ptr_pos_(hiddenapi_ptr_pos) {} 48*795d594fSAndroid Build Coastguard Worker GetIndex()49*795d594fSAndroid Build Coastguard Worker uint32_t GetIndex() const { 50*795d594fSAndroid Build Coastguard Worker return index_; 51*795d594fSAndroid Build Coastguard Worker } 52*795d594fSAndroid Build Coastguard Worker GetAccessFlags()53*795d594fSAndroid Build Coastguard Worker uint32_t GetAccessFlags() const { 54*795d594fSAndroid Build Coastguard Worker return access_flags_; 55*795d594fSAndroid Build Coastguard Worker } 56*795d594fSAndroid Build Coastguard Worker GetHiddenapiFlags()57*795d594fSAndroid Build Coastguard Worker uint32_t GetHiddenapiFlags() const { 58*795d594fSAndroid Build Coastguard Worker return hiddenapi_flags_; 59*795d594fSAndroid Build Coastguard Worker } 60*795d594fSAndroid Build Coastguard Worker IsFinal()61*795d594fSAndroid Build Coastguard Worker bool IsFinal() const { 62*795d594fSAndroid Build Coastguard Worker return (GetAccessFlags() & kAccFinal) != 0; 63*795d594fSAndroid Build Coastguard Worker } 64*795d594fSAndroid Build Coastguard Worker GetDexFile()65*795d594fSAndroid Build Coastguard Worker const DexFile& GetDexFile() const { 66*795d594fSAndroid Build Coastguard Worker return dex_file_; 67*795d594fSAndroid Build Coastguard Worker } 68*795d594fSAndroid Build Coastguard Worker GetDataPointer()69*795d594fSAndroid Build Coastguard Worker const uint8_t* GetDataPointer() const { 70*795d594fSAndroid Build Coastguard Worker return ptr_pos_; 71*795d594fSAndroid Build Coastguard Worker } 72*795d594fSAndroid Build Coastguard Worker MemberIsNative()73*795d594fSAndroid Build Coastguard Worker bool MemberIsNative() const { 74*795d594fSAndroid Build Coastguard Worker return GetAccessFlags() & kAccNative; 75*795d594fSAndroid Build Coastguard Worker } 76*795d594fSAndroid Build Coastguard Worker MemberIsFinal()77*795d594fSAndroid Build Coastguard Worker bool MemberIsFinal() const { 78*795d594fSAndroid Build Coastguard Worker return GetAccessFlags() & kAccFinal; 79*795d594fSAndroid Build Coastguard Worker } 80*795d594fSAndroid Build Coastguard Worker 81*795d594fSAndroid Build Coastguard Worker protected: 82*795d594fSAndroid Build Coastguard Worker // Internal data pointer for reading. 83*795d594fSAndroid Build Coastguard Worker const DexFile& dex_file_; 84*795d594fSAndroid Build Coastguard Worker const uint8_t* ptr_pos_ = nullptr; 85*795d594fSAndroid Build Coastguard Worker const uint8_t* hiddenapi_ptr_pos_ = nullptr; 86*795d594fSAndroid Build Coastguard Worker uint32_t index_ = 0u; 87*795d594fSAndroid Build Coastguard Worker uint32_t access_flags_ = 0u; 88*795d594fSAndroid Build Coastguard Worker uint32_t hiddenapi_flags_ = 0u; 89*795d594fSAndroid Build Coastguard Worker }; 90*795d594fSAndroid Build Coastguard Worker 91*795d594fSAndroid Build Coastguard Worker // A decoded version of the method of a class_data_item. 92*795d594fSAndroid Build Coastguard Worker class Method : public BaseItem { 93*795d594fSAndroid Build Coastguard Worker public: GetCodeItemOffset()94*795d594fSAndroid Build Coastguard Worker uint32_t GetCodeItemOffset() const { 95*795d594fSAndroid Build Coastguard Worker return code_off_; 96*795d594fSAndroid Build Coastguard Worker } 97*795d594fSAndroid Build Coastguard Worker GetInvokeType(uint32_t class_access_flags)98*795d594fSAndroid Build Coastguard Worker InvokeType GetInvokeType(uint32_t class_access_flags) const { 99*795d594fSAndroid Build Coastguard Worker return is_static_or_direct_ 100*795d594fSAndroid Build Coastguard Worker ? GetDirectMethodInvokeType() 101*795d594fSAndroid Build Coastguard Worker : GetVirtualMethodInvokeType(class_access_flags); 102*795d594fSAndroid Build Coastguard Worker } 103*795d594fSAndroid Build Coastguard Worker 104*795d594fSAndroid Build Coastguard Worker MethodReference GetReference() const; 105*795d594fSAndroid Build Coastguard Worker 106*795d594fSAndroid Build Coastguard Worker CodeItemInstructionAccessor GetInstructions() const; 107*795d594fSAndroid Build Coastguard Worker CodeItemDataAccessor GetInstructionsAndData() const; 108*795d594fSAndroid Build Coastguard Worker 109*795d594fSAndroid Build Coastguard Worker const dex::CodeItem* GetCodeItem() const; 110*795d594fSAndroid Build Coastguard Worker IsStaticOrDirect()111*795d594fSAndroid Build Coastguard Worker bool IsStaticOrDirect() const { 112*795d594fSAndroid Build Coastguard Worker return is_static_or_direct_; 113*795d594fSAndroid Build Coastguard Worker } 114*795d594fSAndroid Build Coastguard Worker 115*795d594fSAndroid Build Coastguard Worker private: 116*795d594fSAndroid Build Coastguard Worker Method(const DexFile& dex_file, 117*795d594fSAndroid Build Coastguard Worker const uint8_t* ptr_pos, 118*795d594fSAndroid Build Coastguard Worker const uint8_t* hiddenapi_ptr_pos = nullptr, 119*795d594fSAndroid Build Coastguard Worker bool is_static_or_direct = true) BaseItem(dex_file,ptr_pos,hiddenapi_ptr_pos)120*795d594fSAndroid Build Coastguard Worker : BaseItem(dex_file, ptr_pos, hiddenapi_ptr_pos), 121*795d594fSAndroid Build Coastguard Worker is_static_or_direct_(is_static_or_direct) {} 122*795d594fSAndroid Build Coastguard Worker 123*795d594fSAndroid Build Coastguard Worker void Read(); 124*795d594fSAndroid Build Coastguard Worker GetDirectMethodInvokeType()125*795d594fSAndroid Build Coastguard Worker InvokeType GetDirectMethodInvokeType() const { 126*795d594fSAndroid Build Coastguard Worker return (GetAccessFlags() & kAccStatic) != 0 ? kStatic : kDirect; 127*795d594fSAndroid Build Coastguard Worker } 128*795d594fSAndroid Build Coastguard Worker GetVirtualMethodInvokeType(uint32_t class_access_flags)129*795d594fSAndroid Build Coastguard Worker InvokeType GetVirtualMethodInvokeType(uint32_t class_access_flags) const { 130*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(GetAccessFlags() & kAccStatic, 0U); 131*795d594fSAndroid Build Coastguard Worker if ((class_access_flags & kAccInterface) != 0) { 132*795d594fSAndroid Build Coastguard Worker return kInterface; 133*795d594fSAndroid Build Coastguard Worker } else if ((GetAccessFlags() & kAccConstructor) != 0) { 134*795d594fSAndroid Build Coastguard Worker return kSuper; 135*795d594fSAndroid Build Coastguard Worker } else { 136*795d594fSAndroid Build Coastguard Worker return kVirtual; 137*795d594fSAndroid Build Coastguard Worker } 138*795d594fSAndroid Build Coastguard Worker } 139*795d594fSAndroid Build Coastguard Worker 140*795d594fSAndroid Build Coastguard Worker // Move to virtual method section. NextSection()141*795d594fSAndroid Build Coastguard Worker void NextSection() { 142*795d594fSAndroid Build Coastguard Worker DCHECK(is_static_or_direct_) << "Already in the virtual methods section"; 143*795d594fSAndroid Build Coastguard Worker is_static_or_direct_ = false; 144*795d594fSAndroid Build Coastguard Worker index_ = 0u; 145*795d594fSAndroid Build Coastguard Worker } 146*795d594fSAndroid Build Coastguard Worker 147*795d594fSAndroid Build Coastguard Worker bool is_static_or_direct_ = true; 148*795d594fSAndroid Build Coastguard Worker uint32_t code_off_ = 0u; 149*795d594fSAndroid Build Coastguard Worker 150*795d594fSAndroid Build Coastguard Worker friend class ClassAccessor; 151*795d594fSAndroid Build Coastguard Worker friend class dex::DexFileVerifier; 152*795d594fSAndroid Build Coastguard Worker }; 153*795d594fSAndroid Build Coastguard Worker 154*795d594fSAndroid Build Coastguard Worker // A decoded version of the field of a class_data_item. 155*795d594fSAndroid Build Coastguard Worker class Field : public BaseItem { 156*795d594fSAndroid Build Coastguard Worker public: 157*795d594fSAndroid Build Coastguard Worker Field(const DexFile& dex_file, 158*795d594fSAndroid Build Coastguard Worker const uint8_t* ptr_pos, 159*795d594fSAndroid Build Coastguard Worker const uint8_t* hiddenapi_ptr_pos = nullptr) BaseItem(dex_file,ptr_pos,hiddenapi_ptr_pos)160*795d594fSAndroid Build Coastguard Worker : BaseItem(dex_file, ptr_pos, hiddenapi_ptr_pos) {} 161*795d594fSAndroid Build Coastguard Worker IsStatic()162*795d594fSAndroid Build Coastguard Worker bool IsStatic() const { 163*795d594fSAndroid Build Coastguard Worker return is_static_; 164*795d594fSAndroid Build Coastguard Worker } 165*795d594fSAndroid Build Coastguard Worker 166*795d594fSAndroid Build Coastguard Worker private: 167*795d594fSAndroid Build Coastguard Worker void Read(); 168*795d594fSAndroid Build Coastguard Worker 169*795d594fSAndroid Build Coastguard Worker // Move to instance fields section. NextSection()170*795d594fSAndroid Build Coastguard Worker void NextSection() { 171*795d594fSAndroid Build Coastguard Worker index_ = 0u; 172*795d594fSAndroid Build Coastguard Worker is_static_ = false; 173*795d594fSAndroid Build Coastguard Worker } 174*795d594fSAndroid Build Coastguard Worker 175*795d594fSAndroid Build Coastguard Worker bool is_static_ = true; 176*795d594fSAndroid Build Coastguard Worker friend class ClassAccessor; 177*795d594fSAndroid Build Coastguard Worker friend class dex::DexFileVerifier; 178*795d594fSAndroid Build Coastguard Worker }; 179*795d594fSAndroid Build Coastguard Worker 180*795d594fSAndroid Build Coastguard Worker template <typename DataType> 181*795d594fSAndroid Build Coastguard Worker class DataIterator { 182*795d594fSAndroid Build Coastguard Worker public: 183*795d594fSAndroid Build Coastguard Worker using iterator_category = std::forward_iterator_tag; 184*795d594fSAndroid Build Coastguard Worker using value_type = DataType; 185*795d594fSAndroid Build Coastguard Worker using difference_type = ptrdiff_t; 186*795d594fSAndroid Build Coastguard Worker using pointer = value_type*; 187*795d594fSAndroid Build Coastguard Worker using reference = value_type&; 188*795d594fSAndroid Build Coastguard Worker DataIterator(const DexFile & dex_file,uint32_t position,uint32_t partition_pos,uint32_t iterator_end,const uint8_t * ptr_pos,const uint8_t * hiddenapi_ptr_pos)189*795d594fSAndroid Build Coastguard Worker DataIterator(const DexFile& dex_file, 190*795d594fSAndroid Build Coastguard Worker uint32_t position, 191*795d594fSAndroid Build Coastguard Worker uint32_t partition_pos, 192*795d594fSAndroid Build Coastguard Worker uint32_t iterator_end, 193*795d594fSAndroid Build Coastguard Worker const uint8_t* ptr_pos, 194*795d594fSAndroid Build Coastguard Worker const uint8_t* hiddenapi_ptr_pos) 195*795d594fSAndroid Build Coastguard Worker : data_(dex_file, ptr_pos, hiddenapi_ptr_pos), 196*795d594fSAndroid Build Coastguard Worker position_(position), 197*795d594fSAndroid Build Coastguard Worker partition_pos_(partition_pos), 198*795d594fSAndroid Build Coastguard Worker iterator_end_(iterator_end) { 199*795d594fSAndroid Build Coastguard Worker ReadData(); 200*795d594fSAndroid Build Coastguard Worker } 201*795d594fSAndroid Build Coastguard Worker IsValid()202*795d594fSAndroid Build Coastguard Worker bool IsValid() const { 203*795d594fSAndroid Build Coastguard Worker return position_ < iterator_end_; 204*795d594fSAndroid Build Coastguard Worker } 205*795d594fSAndroid Build Coastguard Worker 206*795d594fSAndroid Build Coastguard Worker // Value after modification. 207*795d594fSAndroid Build Coastguard Worker DataIterator& operator++() { 208*795d594fSAndroid Build Coastguard Worker ++position_; 209*795d594fSAndroid Build Coastguard Worker ReadData(); 210*795d594fSAndroid Build Coastguard Worker return *this; 211*795d594fSAndroid Build Coastguard Worker } 212*795d594fSAndroid Build Coastguard Worker 213*795d594fSAndroid Build Coastguard Worker const value_type& operator*() const { 214*795d594fSAndroid Build Coastguard Worker return data_; 215*795d594fSAndroid Build Coastguard Worker } 216*795d594fSAndroid Build Coastguard Worker 217*795d594fSAndroid Build Coastguard Worker const value_type* operator->() const { 218*795d594fSAndroid Build Coastguard Worker return &data_; 219*795d594fSAndroid Build Coastguard Worker } 220*795d594fSAndroid Build Coastguard Worker 221*795d594fSAndroid Build Coastguard Worker bool operator==(const DataIterator& rhs) const { 222*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(&data_.dex_file_, &rhs.data_.dex_file_) << "Comparing different dex files."; 223*795d594fSAndroid Build Coastguard Worker return position_ == rhs.position_; 224*795d594fSAndroid Build Coastguard Worker } 225*795d594fSAndroid Build Coastguard Worker 226*795d594fSAndroid Build Coastguard Worker bool operator!=(const DataIterator& rhs) const { 227*795d594fSAndroid Build Coastguard Worker return !(*this == rhs); 228*795d594fSAndroid Build Coastguard Worker } 229*795d594fSAndroid Build Coastguard Worker 230*795d594fSAndroid Build Coastguard Worker bool operator<(const DataIterator& rhs) const { 231*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(&data_.dex_file_, &rhs.data_.dex_file_) << "Comparing different dex files."; 232*795d594fSAndroid Build Coastguard Worker return position_ < rhs.position_; 233*795d594fSAndroid Build Coastguard Worker } 234*795d594fSAndroid Build Coastguard Worker 235*795d594fSAndroid Build Coastguard Worker bool operator>(const DataIterator& rhs) const { 236*795d594fSAndroid Build Coastguard Worker return rhs < *this; 237*795d594fSAndroid Build Coastguard Worker } 238*795d594fSAndroid Build Coastguard Worker 239*795d594fSAndroid Build Coastguard Worker bool operator<=(const DataIterator& rhs) const { 240*795d594fSAndroid Build Coastguard Worker return !(rhs < *this); 241*795d594fSAndroid Build Coastguard Worker } 242*795d594fSAndroid Build Coastguard Worker 243*795d594fSAndroid Build Coastguard Worker bool operator>=(const DataIterator& rhs) const { 244*795d594fSAndroid Build Coastguard Worker return !(*this < rhs); 245*795d594fSAndroid Build Coastguard Worker } 246*795d594fSAndroid Build Coastguard Worker GetDataPointer()247*795d594fSAndroid Build Coastguard Worker const uint8_t* GetDataPointer() const { 248*795d594fSAndroid Build Coastguard Worker return data_.ptr_pos_; 249*795d594fSAndroid Build Coastguard Worker } 250*795d594fSAndroid Build Coastguard Worker 251*795d594fSAndroid Build Coastguard Worker private: 252*795d594fSAndroid Build Coastguard Worker // Read data at current position. ReadData()253*795d594fSAndroid Build Coastguard Worker void ReadData() { 254*795d594fSAndroid Build Coastguard Worker if (IsValid()) { 255*795d594fSAndroid Build Coastguard Worker // At the end of the first section, go to the next section. 256*795d594fSAndroid Build Coastguard Worker if (position_ == partition_pos_) { 257*795d594fSAndroid Build Coastguard Worker data_.NextSection(); 258*795d594fSAndroid Build Coastguard Worker } 259*795d594fSAndroid Build Coastguard Worker data_.Read(); 260*795d594fSAndroid Build Coastguard Worker } 261*795d594fSAndroid Build Coastguard Worker } 262*795d594fSAndroid Build Coastguard Worker 263*795d594fSAndroid Build Coastguard Worker DataType data_; 264*795d594fSAndroid Build Coastguard Worker // Iterator position. 265*795d594fSAndroid Build Coastguard Worker uint32_t position_; 266*795d594fSAndroid Build Coastguard Worker // At partition_pos_, we go to the next section. 267*795d594fSAndroid Build Coastguard Worker const uint32_t partition_pos_; 268*795d594fSAndroid Build Coastguard Worker // At iterator_end_, the iterator is no longer valid. 269*795d594fSAndroid Build Coastguard Worker const uint32_t iterator_end_; 270*795d594fSAndroid Build Coastguard Worker 271*795d594fSAndroid Build Coastguard Worker friend class dex::DexFileVerifier; 272*795d594fSAndroid Build Coastguard Worker }; 273*795d594fSAndroid Build Coastguard Worker 274*795d594fSAndroid Build Coastguard Worker // Not explicit specifically for range-based loops. 275*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE ClassAccessor(const ClassIteratorData& data); // NOLINT [runtime/explicit] [5] 276*795d594fSAndroid Build Coastguard Worker 277*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE ClassAccessor(const DexFile& dex_file, 278*795d594fSAndroid Build Coastguard Worker const dex::ClassDef& class_def, 279*795d594fSAndroid Build Coastguard Worker bool parse_hiddenapi_class_data = false); 280*795d594fSAndroid Build Coastguard Worker 281*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE ClassAccessor(const DexFile& dex_file, uint32_t class_def_index); 282*795d594fSAndroid Build Coastguard Worker 283*795d594fSAndroid Build Coastguard Worker ClassAccessor(const DexFile& dex_file, 284*795d594fSAndroid Build Coastguard Worker const uint8_t* class_data, 285*795d594fSAndroid Build Coastguard Worker uint32_t class_def_index = DexFile::kDexNoIndex32, 286*795d594fSAndroid Build Coastguard Worker bool parse_hiddenapi_class_data = false); 287*795d594fSAndroid Build Coastguard Worker 288*795d594fSAndroid Build Coastguard Worker // Return the code item for a method. 289*795d594fSAndroid Build Coastguard Worker const dex::CodeItem* GetCodeItem(const Method& method) const; 290*795d594fSAndroid Build Coastguard Worker 291*795d594fSAndroid Build Coastguard Worker // Iterator data is not very iterator friendly, use visitors to get around this. 292*795d594fSAndroid Build Coastguard Worker template <typename StaticFieldVisitor, 293*795d594fSAndroid Build Coastguard Worker typename InstanceFieldVisitor, 294*795d594fSAndroid Build Coastguard Worker typename DirectMethodVisitor, 295*795d594fSAndroid Build Coastguard Worker typename VirtualMethodVisitor> 296*795d594fSAndroid Build Coastguard Worker void VisitFieldsAndMethods(const StaticFieldVisitor& static_field_visitor, 297*795d594fSAndroid Build Coastguard Worker const InstanceFieldVisitor& instance_field_visitor, 298*795d594fSAndroid Build Coastguard Worker const DirectMethodVisitor& direct_method_visitor, 299*795d594fSAndroid Build Coastguard Worker const VirtualMethodVisitor& virtual_method_visitor) const; 300*795d594fSAndroid Build Coastguard Worker 301*795d594fSAndroid Build Coastguard Worker template <typename DirectMethodVisitor, 302*795d594fSAndroid Build Coastguard Worker typename VirtualMethodVisitor> 303*795d594fSAndroid Build Coastguard Worker void VisitMethods(const DirectMethodVisitor& direct_method_visitor, 304*795d594fSAndroid Build Coastguard Worker const VirtualMethodVisitor& virtual_method_visitor) const; 305*795d594fSAndroid Build Coastguard Worker 306*795d594fSAndroid Build Coastguard Worker template <typename StaticFieldVisitor, 307*795d594fSAndroid Build Coastguard Worker typename InstanceFieldVisitor> 308*795d594fSAndroid Build Coastguard Worker void VisitFields(const StaticFieldVisitor& static_field_visitor, 309*795d594fSAndroid Build Coastguard Worker const InstanceFieldVisitor& instance_field_visitor) const; 310*795d594fSAndroid Build Coastguard Worker 311*795d594fSAndroid Build Coastguard Worker // Return the iteration range for all the fields. 312*795d594fSAndroid Build Coastguard Worker IterationRange<DataIterator<Field>> GetFields() const; 313*795d594fSAndroid Build Coastguard Worker 314*795d594fSAndroid Build Coastguard Worker // Return the iteration range for all the static fields. 315*795d594fSAndroid Build Coastguard Worker IterationRange<DataIterator<Field>> GetStaticFields() const; 316*795d594fSAndroid Build Coastguard Worker 317*795d594fSAndroid Build Coastguard Worker // Return the iteration range for all the instance fields. 318*795d594fSAndroid Build Coastguard Worker IterationRange<DataIterator<Field>> GetInstanceFields() const; 319*795d594fSAndroid Build Coastguard Worker 320*795d594fSAndroid Build Coastguard Worker // Return the iteration range for all the methods. 321*795d594fSAndroid Build Coastguard Worker IterationRange<DataIterator<Method>> GetMethods() const; 322*795d594fSAndroid Build Coastguard Worker 323*795d594fSAndroid Build Coastguard Worker // Return the iteration range for the direct methods. 324*795d594fSAndroid Build Coastguard Worker IterationRange<DataIterator<Method>> GetDirectMethods() const; 325*795d594fSAndroid Build Coastguard Worker 326*795d594fSAndroid Build Coastguard Worker // Return the iteration range for the virtual methods. 327*795d594fSAndroid Build Coastguard Worker IterationRange<DataIterator<Method>> GetVirtualMethods() const; 328*795d594fSAndroid Build Coastguard Worker NumStaticFields()329*795d594fSAndroid Build Coastguard Worker uint32_t NumStaticFields() const { 330*795d594fSAndroid Build Coastguard Worker return num_static_fields_; 331*795d594fSAndroid Build Coastguard Worker } 332*795d594fSAndroid Build Coastguard Worker NumInstanceFields()333*795d594fSAndroid Build Coastguard Worker uint32_t NumInstanceFields() const { 334*795d594fSAndroid Build Coastguard Worker return num_instance_fields_; 335*795d594fSAndroid Build Coastguard Worker } 336*795d594fSAndroid Build Coastguard Worker NumFields()337*795d594fSAndroid Build Coastguard Worker uint32_t NumFields() const { 338*795d594fSAndroid Build Coastguard Worker return NumStaticFields() + NumInstanceFields(); 339*795d594fSAndroid Build Coastguard Worker } 340*795d594fSAndroid Build Coastguard Worker NumDirectMethods()341*795d594fSAndroid Build Coastguard Worker uint32_t NumDirectMethods() const { 342*795d594fSAndroid Build Coastguard Worker return num_direct_methods_; 343*795d594fSAndroid Build Coastguard Worker } 344*795d594fSAndroid Build Coastguard Worker NumVirtualMethods()345*795d594fSAndroid Build Coastguard Worker uint32_t NumVirtualMethods() const { 346*795d594fSAndroid Build Coastguard Worker return num_virtual_methods_; 347*795d594fSAndroid Build Coastguard Worker } 348*795d594fSAndroid Build Coastguard Worker NumMethods()349*795d594fSAndroid Build Coastguard Worker uint32_t NumMethods() const { 350*795d594fSAndroid Build Coastguard Worker return NumDirectMethods() + NumVirtualMethods(); 351*795d594fSAndroid Build Coastguard Worker } 352*795d594fSAndroid Build Coastguard Worker 353*795d594fSAndroid Build Coastguard Worker const char* GetDescriptor() const; 354*795d594fSAndroid Build Coastguard Worker std::string_view GetDescriptorView() const; 355*795d594fSAndroid Build Coastguard Worker 356*795d594fSAndroid Build Coastguard Worker dex::TypeIndex GetClassIdx() const; 357*795d594fSAndroid Build Coastguard Worker GetDexFile()358*795d594fSAndroid Build Coastguard Worker const DexFile& GetDexFile() const { 359*795d594fSAndroid Build Coastguard Worker return dex_file_; 360*795d594fSAndroid Build Coastguard Worker } 361*795d594fSAndroid Build Coastguard Worker HasClassData()362*795d594fSAndroid Build Coastguard Worker bool HasClassData() const { 363*795d594fSAndroid Build Coastguard Worker return ptr_pos_ != nullptr; 364*795d594fSAndroid Build Coastguard Worker } 365*795d594fSAndroid Build Coastguard Worker HasHiddenapiClassData()366*795d594fSAndroid Build Coastguard Worker bool HasHiddenapiClassData() const { 367*795d594fSAndroid Build Coastguard Worker return hiddenapi_ptr_pos_ != nullptr; 368*795d594fSAndroid Build Coastguard Worker } 369*795d594fSAndroid Build Coastguard Worker GetClassDefIndex()370*795d594fSAndroid Build Coastguard Worker uint32_t GetClassDefIndex() const { 371*795d594fSAndroid Build Coastguard Worker return class_def_index_; 372*795d594fSAndroid Build Coastguard Worker } 373*795d594fSAndroid Build Coastguard Worker 374*795d594fSAndroid Build Coastguard Worker const dex::ClassDef& GetClassDef() const; 375*795d594fSAndroid Build Coastguard Worker 376*795d594fSAndroid Build Coastguard Worker protected: 377*795d594fSAndroid Build Coastguard Worker // Template visitor to reduce copy paste for visiting elements. 378*795d594fSAndroid Build Coastguard Worker // No thread safety analysis since the visitor may require capabilities. 379*795d594fSAndroid Build Coastguard Worker template <typename DataType, typename Visitor> 380*795d594fSAndroid Build Coastguard Worker void VisitMembers(size_t count, const Visitor& visitor, DataType* data) const 381*795d594fSAndroid Build Coastguard Worker NO_THREAD_SAFETY_ANALYSIS; 382*795d594fSAndroid Build Coastguard Worker 383*795d594fSAndroid Build Coastguard Worker // Return an iteration range for the first <count> fields. 384*795d594fSAndroid Build Coastguard Worker IterationRange<DataIterator<Field>> GetFieldsInternal(size_t count) const; 385*795d594fSAndroid Build Coastguard Worker 386*795d594fSAndroid Build Coastguard Worker // Return an iteration range for the first <count> methods. 387*795d594fSAndroid Build Coastguard Worker IterationRange<DataIterator<Method>> GetMethodsInternal(size_t count) const; 388*795d594fSAndroid Build Coastguard Worker 389*795d594fSAndroid Build Coastguard Worker const DexFile& dex_file_; 390*795d594fSAndroid Build Coastguard Worker const uint32_t class_def_index_; 391*795d594fSAndroid Build Coastguard Worker const uint8_t* ptr_pos_ = nullptr; // Pointer into stream of class_data_item. 392*795d594fSAndroid Build Coastguard Worker const uint8_t* hiddenapi_ptr_pos_ = nullptr; // Pointer into stream of hiddenapi_metadata. 393*795d594fSAndroid Build Coastguard Worker const uint32_t num_static_fields_ = 0u; 394*795d594fSAndroid Build Coastguard Worker const uint32_t num_instance_fields_ = 0u; 395*795d594fSAndroid Build Coastguard Worker const uint32_t num_direct_methods_ = 0u; 396*795d594fSAndroid Build Coastguard Worker const uint32_t num_virtual_methods_ = 0u; 397*795d594fSAndroid Build Coastguard Worker 398*795d594fSAndroid Build Coastguard Worker friend class dex::DexFileVerifier; 399*795d594fSAndroid Build Coastguard Worker }; 400*795d594fSAndroid Build Coastguard Worker 401*795d594fSAndroid Build Coastguard Worker } // namespace art 402*795d594fSAndroid Build Coastguard Worker 403*795d594fSAndroid Build Coastguard Worker #endif // ART_LIBDEXFILE_DEX_CLASS_ACCESSOR_H_ 404