1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_LIBDEXFILE_DEX_CLASS_ACCESSOR_INL_H_ 18 #define ART_LIBDEXFILE_DEX_CLASS_ACCESSOR_INL_H_ 19 20 #include "class_accessor.h" 21 22 #include "base/hiddenapi_flags.h" 23 #include "base/leb128.h" 24 #include "base/utils.h" 25 #include "class_iterator.h" 26 #include "code_item_accessors-inl.h" 27 #include "dex_file.h" 28 #include "method_reference.h" 29 30 namespace art { 31 32 inline ClassAccessor::ClassAccessor(const ClassIteratorData& data) 33 : ClassAccessor(data.dex_file_, data.class_def_idx_) {} 34 35 inline ClassAccessor::ClassAccessor(const DexFile& dex_file, 36 const dex::ClassDef& class_def, 37 bool parse_hiddenapi_class_data) 38 : ClassAccessor(dex_file, 39 dex_file.GetClassData(class_def), 40 dex_file.GetIndexForClassDef(class_def), 41 parse_hiddenapi_class_data) {} 42 43 inline ClassAccessor::ClassAccessor(const DexFile& dex_file, uint32_t class_def_index) 44 : ClassAccessor(dex_file, dex_file.GetClassDef(class_def_index)) {} 45 46 inline ClassAccessor::ClassAccessor(const DexFile& dex_file, 47 const uint8_t* class_data, 48 uint32_t class_def_index, 49 bool parse_hiddenapi_class_data) 50 : dex_file_(dex_file), 51 class_def_index_(class_def_index), 52 ptr_pos_(class_data), 53 hiddenapi_ptr_pos_(nullptr), 54 num_static_fields_(ptr_pos_ != nullptr ? DecodeUnsignedLeb128(&ptr_pos_) : 0u), 55 num_instance_fields_(ptr_pos_ != nullptr ? DecodeUnsignedLeb128(&ptr_pos_) : 0u), 56 num_direct_methods_(ptr_pos_ != nullptr ? DecodeUnsignedLeb128(&ptr_pos_) : 0u), 57 num_virtual_methods_(ptr_pos_ != nullptr ? DecodeUnsignedLeb128(&ptr_pos_) : 0u) { 58 if (parse_hiddenapi_class_data && class_def_index != DexFile::kDexNoIndex32) { 59 const dex::HiddenapiClassData* hiddenapi_class_data = dex_file.GetHiddenapiClassData(); 60 if (hiddenapi_class_data != nullptr) { 61 hiddenapi_ptr_pos_ = hiddenapi_class_data->GetFlagsPointer(class_def_index); 62 } 63 } 64 } 65 66 inline void ClassAccessor::Method::Read() { 67 index_ += DecodeUnsignedLeb128(&ptr_pos_); 68 access_flags_ = DecodeUnsignedLeb128(&ptr_pos_); 69 code_off_ = DecodeUnsignedLeb128(&ptr_pos_); 70 if (hiddenapi_ptr_pos_ != nullptr) { 71 hiddenapi_flags_ = DecodeUnsignedLeb128(&hiddenapi_ptr_pos_); 72 DCHECK(hiddenapi::ApiList(hiddenapi_flags_).IsValid()); 73 } 74 } 75 76 inline MethodReference ClassAccessor::Method::GetReference() const { 77 return MethodReference(&dex_file_, GetIndex()); 78 } 79 80 81 inline void ClassAccessor::Field::Read() { 82 index_ += DecodeUnsignedLeb128(&ptr_pos_); 83 access_flags_ = DecodeUnsignedLeb128(&ptr_pos_); 84 if (hiddenapi_ptr_pos_ != nullptr) { 85 hiddenapi_flags_ = DecodeUnsignedLeb128(&hiddenapi_ptr_pos_); 86 DCHECK(hiddenapi::ApiList(hiddenapi_flags_).IsValid()); 87 } 88 } 89 90 template <typename DataType, typename Visitor> 91 inline void ClassAccessor::VisitMembers(size_t count, 92 const Visitor& visitor, 93 DataType* data) const { 94 DCHECK(data != nullptr); 95 for ( ; count != 0; --count) { 96 data->Read(); 97 visitor(*data); 98 } 99 } 100 101 template <typename StaticFieldVisitor, 102 typename InstanceFieldVisitor, 103 typename DirectMethodVisitor, 104 typename VirtualMethodVisitor> 105 inline void ClassAccessor::VisitFieldsAndMethods( 106 const StaticFieldVisitor& static_field_visitor, 107 const InstanceFieldVisitor& instance_field_visitor, 108 const DirectMethodVisitor& direct_method_visitor, 109 const VirtualMethodVisitor& virtual_method_visitor) const { 110 Field field(dex_file_, ptr_pos_, hiddenapi_ptr_pos_); 111 VisitMembers(num_static_fields_, static_field_visitor, &field); 112 field.NextSection(); 113 VisitMembers(num_instance_fields_, instance_field_visitor, &field); 114 115 Method method(dex_file_, field.ptr_pos_, field.hiddenapi_ptr_pos_, /*is_static_or_direct*/ true); 116 VisitMembers(num_direct_methods_, direct_method_visitor, &method); 117 method.NextSection(); 118 VisitMembers(num_virtual_methods_, virtual_method_visitor, &method); 119 } 120 121 template <typename DirectMethodVisitor, 122 typename VirtualMethodVisitor> 123 inline void ClassAccessor::VisitMethods(const DirectMethodVisitor& direct_method_visitor, 124 const VirtualMethodVisitor& virtual_method_visitor) const { 125 VisitFieldsAndMethods(VoidFunctor(), 126 VoidFunctor(), 127 direct_method_visitor, 128 virtual_method_visitor); 129 } 130 131 template <typename StaticFieldVisitor, 132 typename InstanceFieldVisitor> 133 inline void ClassAccessor::VisitFields(const StaticFieldVisitor& static_field_visitor, 134 const InstanceFieldVisitor& instance_field_visitor) const { 135 VisitFieldsAndMethods(static_field_visitor, 136 instance_field_visitor, 137 VoidFunctor(), 138 VoidFunctor()); 139 } 140 141 inline const dex::CodeItem* ClassAccessor::GetCodeItem(const Method& method) const { 142 return dex_file_.GetCodeItem(method.GetCodeItemOffset()); 143 } 144 145 inline CodeItemInstructionAccessor ClassAccessor::Method::GetInstructions() const { 146 return CodeItemInstructionAccessor(dex_file_, dex_file_.GetCodeItem(GetCodeItemOffset())); 147 } 148 149 inline CodeItemDataAccessor ClassAccessor::Method::GetInstructionsAndData() const { 150 return CodeItemDataAccessor(dex_file_, dex_file_.GetCodeItem(GetCodeItemOffset())); 151 } 152 153 inline const char* ClassAccessor::GetDescriptor() const { 154 return dex_file_.StringByTypeIdx(GetClassIdx()); 155 } 156 157 inline const dex::CodeItem* ClassAccessor::Method::GetCodeItem() const { 158 return dex_file_.GetCodeItem(code_off_); 159 } 160 161 inline IterationRange<ClassAccessor::DataIterator<ClassAccessor::Field>> 162 ClassAccessor::GetFieldsInternal(size_t count) const { 163 return { 164 DataIterator<Field>(dex_file_, 165 0u, 166 num_static_fields_, 167 count, 168 ptr_pos_, 169 hiddenapi_ptr_pos_), 170 DataIterator<Field>(dex_file_, 171 count, 172 num_static_fields_, 173 count, 174 // The following pointers are bogus but unused in the `end` iterator. 175 ptr_pos_, 176 hiddenapi_ptr_pos_) }; 177 } 178 179 // Return an iteration range for the first <count> methods. 180 inline IterationRange<ClassAccessor::DataIterator<ClassAccessor::Method>> 181 ClassAccessor::GetMethodsInternal(size_t count) const { 182 // Skip over the fields. 183 Field field(dex_file_, ptr_pos_, hiddenapi_ptr_pos_); 184 VisitMembers(NumFields(), VoidFunctor(), &field); 185 // Return the iterator pair. 186 return { 187 DataIterator<Method>(dex_file_, 188 0u, 189 num_direct_methods_, 190 count, 191 field.ptr_pos_, 192 field.hiddenapi_ptr_pos_), 193 DataIterator<Method>(dex_file_, 194 count, 195 num_direct_methods_, 196 count, 197 // The following pointers are bogus but unused in the `end` iterator. 198 field.ptr_pos_, 199 field.hiddenapi_ptr_pos_) }; 200 } 201 202 inline IterationRange<ClassAccessor::DataIterator<ClassAccessor::Field>> ClassAccessor::GetFields() 203 const { 204 return GetFieldsInternal(num_static_fields_ + num_instance_fields_); 205 } 206 207 inline IterationRange<ClassAccessor::DataIterator<ClassAccessor::Field>> 208 ClassAccessor::GetStaticFields() const { 209 return GetFieldsInternal(num_static_fields_); 210 } 211 212 213 inline IterationRange<ClassAccessor::DataIterator<ClassAccessor::Field>> 214 ClassAccessor::GetInstanceFields() const { 215 IterationRange<ClassAccessor::DataIterator<ClassAccessor::Field>> fields = GetFields(); 216 // Skip the static fields. 217 return { std::next(fields.begin(), NumStaticFields()), fields.end() }; 218 } 219 220 inline IterationRange<ClassAccessor::DataIterator<ClassAccessor::Method>> 221 ClassAccessor::GetMethods() const { 222 return GetMethodsInternal(NumMethods()); 223 } 224 225 inline IterationRange<ClassAccessor::DataIterator<ClassAccessor::Method>> 226 ClassAccessor::GetDirectMethods() const { 227 return GetMethodsInternal(NumDirectMethods()); 228 } 229 230 inline IterationRange<ClassAccessor::DataIterator<ClassAccessor::Method>> 231 ClassAccessor::GetVirtualMethods() const { 232 IterationRange<DataIterator<Method>> methods = GetMethods(); 233 // Skip the direct fields. 234 return { std::next(methods.begin(), NumDirectMethods()), methods.end() }; 235 } 236 237 inline dex::TypeIndex ClassAccessor::GetClassIdx() const { 238 return dex_file_.GetClassDef(class_def_index_).class_idx_; 239 } 240 241 inline const dex::ClassDef& ClassAccessor::GetClassDef() const { 242 return dex_file_.GetClassDef(GetClassDefIndex()); 243 } 244 245 } // namespace art 246 247 #endif // ART_LIBDEXFILE_DEX_CLASS_ACCESSOR_INL_H_ 248