Home | History | Annotate | Download | only in dex
      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