diff options
| -rw-r--r-- | libdexfile/dex/dex_file-inl.h | 32 | ||||
| -rw-r--r-- | libdexfile/dex/dex_file.cc | 45 | ||||
| -rw-r--r-- | libdexfile/dex/dex_file.h | 208 | ||||
| -rw-r--r-- | libdexfile/dex/modifiers.h | 5 |
4 files changed, 8 insertions, 282 deletions
diff --git a/libdexfile/dex/dex_file-inl.h b/libdexfile/dex/dex_file-inl.h index 09668594dd..c512361586 100644 --- a/libdexfile/dex/dex_file-inl.h +++ b/libdexfile/dex/dex_file-inl.h @@ -204,26 +204,6 @@ inline bool Signature::operator==(const Signature& rhs) const { return true; } -inline -InvokeType ClassDataItemIterator::GetMethodInvokeType(const DexFile::ClassDef& class_def) const { - if (HasNextDirectMethod()) { - if ((GetRawMemberAccessFlags() & kAccStatic) != 0) { - return kStatic; - } else { - return kDirect; - } - } else { - DCHECK_EQ(GetRawMemberAccessFlags() & kAccStatic, 0U); - if ((class_def.access_flags_ & kAccInterface) != 0) { - return kInterface; - } else if ((GetRawMemberAccessFlags() & kAccConstructor) != 0) { - return kSuper; - } else { - return kVirtual; - } - } -} - template<typename NewLocalCallback, typename IndexToStringData, typename TypeIndexToStringData> bool DexFile::DecodeDebugLocalInfo(const uint8_t* stream, const std::string& location, @@ -518,18 +498,6 @@ inline const uint8_t* DexFile::GetCatchHandlerData(const DexInstructionIterator& return handler_data + offset; } -template <typename Visitor> -inline void DexFile::ClassDef::VisitMethods(const DexFile* dex_file, const Visitor& visitor) const { - const uint8_t* class_data = dex_file->GetClassData(*this); - if (class_data != nullptr) { - ClassDataItemIterator it(*dex_file, class_data); - it.SkipAllFields(); - for (; it.HasNext(); it.Next()) { - visitor(it); - } - } -} - inline IterationRange<ClassIterator> DexFile::GetClasses() const { return { ClassIterator(*this, 0u), ClassIterator(*this, NumClassDefs()) }; } diff --git a/libdexfile/dex/dex_file.cc b/libdexfile/dex/dex_file.cc index f1f896058c..a2198b7c98 100644 --- a/libdexfile/dex/dex_file.cc +++ b/libdexfile/dex/dex_file.cc @@ -31,6 +31,7 @@ #include "base/enums.h" #include "base/leb128.h" #include "base/stl_util.h" +#include "class_accessor-inl.h" #include "descriptors_names.h" #include "dex_file-inl.h" #include "standard_dex_file.h" @@ -219,21 +220,12 @@ const DexFile::ClassDef* DexFile::FindClassDef(dex::TypeIndex type_idx) const { uint32_t DexFile::FindCodeItemOffset(const DexFile::ClassDef& class_def, uint32_t method_idx) const { - const uint8_t* class_data = GetClassData(class_def); - CHECK(class_data != nullptr); - ClassDataItemIterator it(*this, class_data); - it.SkipAllFields(); - while (it.HasNextDirectMethod()) { - if (it.GetMemberIndex() == method_idx) { - return it.GetMethodCodeItemOffset(); + ClassAccessor accessor(*this, class_def); + CHECK(accessor.HasClassData()); + for (const ClassAccessor::Method& method : accessor.GetMethods()) { + if (method.GetIndex() == method_idx) { + return method.GetCodeItemOffset(); } - it.Next(); - } - while (it.HasNextVirtualMethod()) { - if (it.GetMemberIndex() == method_idx) { - return it.GetMethodCodeItemOffset(); - } - it.Next(); } LOG(FATAL) << "Unable to find method " << method_idx; UNREACHABLE(); @@ -684,31 +676,6 @@ std::ostream& operator<<(std::ostream& os, const Signature& sig) { return os << sig.ToString(); } -// Decodes the header section from the class data bytes. -void ClassDataItemIterator::ReadClassDataHeader() { - CHECK(ptr_pos_ != nullptr); - header_.static_fields_size_ = DecodeUnsignedLeb128(&ptr_pos_); - header_.instance_fields_size_ = DecodeUnsignedLeb128(&ptr_pos_); - header_.direct_methods_size_ = DecodeUnsignedLeb128(&ptr_pos_); - header_.virtual_methods_size_ = DecodeUnsignedLeb128(&ptr_pos_); -} - -void ClassDataItemIterator::ReadClassDataField() { - field_.field_idx_delta_ = DecodeUnsignedLeb128(&ptr_pos_); - field_.access_flags_ = DecodeUnsignedLeb128(&ptr_pos_); - // The user of the iterator is responsible for checking if there - // are unordered or duplicate indexes. -} - -void ClassDataItemIterator::ReadClassDataMethod() { - method_.method_idx_delta_ = DecodeUnsignedLeb128(&ptr_pos_); - method_.access_flags_ = DecodeUnsignedLeb128(&ptr_pos_); - method_.code_off_ = DecodeUnsignedLeb128(&ptr_pos_); - if (last_idx_ != 0 && method_.method_idx_delta_ == 0) { - LOG(WARNING) << "Duplicate method in " << dex_file_.GetLocation(); - } -} - EncodedArrayValueIterator::EncodedArrayValueIterator(const DexFile& dex_file, const uint8_t* array_data) : dex_file_(dex_file), diff --git a/libdexfile/dex/dex_file.h b/libdexfile/dex/dex_file.h index 25cd2f4ddc..98787d1dd0 100644 --- a/libdexfile/dex/dex_file.h +++ b/libdexfile/dex/dex_file.h @@ -238,9 +238,6 @@ class DexFile { } } - template <typename Visitor> - void VisitMethods(const DexFile* dex_file, const Visitor& visitor) const; - private: DISALLOW_COPY_AND_ASSIGN(ClassDef); }; @@ -1174,211 +1171,6 @@ class Signature : public ValueObject { }; std::ostream& operator<<(std::ostream& os, const Signature& sig); -// Iterate and decode class_data_item -class ClassDataItemIterator { - public: - ClassDataItemIterator(const DexFile& dex_file, const uint8_t* raw_class_data_item) - : dex_file_(dex_file), pos_(0), ptr_pos_(raw_class_data_item), last_idx_(0) { - ReadClassDataHeader(); - if (EndOfInstanceFieldsPos() > 0) { - ReadClassDataField(); - } else if (EndOfVirtualMethodsPos() > 0) { - ReadClassDataMethod(); - } - } - uint32_t NumStaticFields() const { - return header_.static_fields_size_; - } - uint32_t NumInstanceFields() const { - return header_.instance_fields_size_; - } - uint32_t NumDirectMethods() const { - return header_.direct_methods_size_; - } - uint32_t NumVirtualMethods() const { - return header_.virtual_methods_size_; - } - bool IsAtMethod() const { - return pos_ >= EndOfInstanceFieldsPos(); - } - bool IsAtVirtualMethod() const { - return pos_ >= EndOfDirectMethodsPos(); - } - bool HasNextStaticField() const { - return pos_ < EndOfStaticFieldsPos(); - } - bool HasNextInstanceField() const { - return pos_ >= EndOfStaticFieldsPos() && pos_ < EndOfInstanceFieldsPos(); - } - bool HasNextDirectMethod() const { - return pos_ >= EndOfInstanceFieldsPos() && pos_ < EndOfDirectMethodsPos(); - } - bool HasNextVirtualMethod() const { - return pos_ >= EndOfDirectMethodsPos() && pos_ < EndOfVirtualMethodsPos(); - } - bool HasNextMethod() const { - const bool result = pos_ >= EndOfInstanceFieldsPos() && pos_ < EndOfVirtualMethodsPos(); - DCHECK_EQ(result, HasNextDirectMethod() || HasNextVirtualMethod()); - return result; - } - void SkipStaticFields() { - while (HasNextStaticField()) { - Next(); - } - } - void SkipInstanceFields() { - while (HasNextInstanceField()) { - Next(); - } - } - void SkipAllFields() { - SkipStaticFields(); - SkipInstanceFields(); - } - void SkipDirectMethods() { - while (HasNextDirectMethod()) { - Next(); - } - } - void SkipVirtualMethods() { - while (HasNextVirtualMethod()) { - Next(); - } - } - bool HasNext() const { - return pos_ < EndOfVirtualMethodsPos(); - } - inline void Next() { - pos_++; - if (pos_ < EndOfStaticFieldsPos()) { - last_idx_ = GetMemberIndex(); - ReadClassDataField(); - } else if (pos_ == EndOfStaticFieldsPos() && NumInstanceFields() > 0) { - last_idx_ = 0; // transition to next array, reset last index - ReadClassDataField(); - } else if (pos_ < EndOfInstanceFieldsPos()) { - last_idx_ = GetMemberIndex(); - ReadClassDataField(); - } else if (pos_ == EndOfInstanceFieldsPos() && NumDirectMethods() > 0) { - last_idx_ = 0; // transition to next array, reset last index - ReadClassDataMethod(); - } else if (pos_ < EndOfDirectMethodsPos()) { - last_idx_ = GetMemberIndex(); - ReadClassDataMethod(); - } else if (pos_ == EndOfDirectMethodsPos() && NumVirtualMethods() > 0) { - last_idx_ = 0; // transition to next array, reset last index - ReadClassDataMethod(); - } else if (pos_ < EndOfVirtualMethodsPos()) { - last_idx_ = GetMemberIndex(); - ReadClassDataMethod(); - } else { - DCHECK(!HasNext()); - } - } - uint32_t GetMemberIndex() const { - if (pos_ < EndOfInstanceFieldsPos()) { - return last_idx_ + field_.field_idx_delta_; - } else { - DCHECK_LT(pos_, EndOfVirtualMethodsPos()); - return last_idx_ + method_.method_idx_delta_; - } - } - uint32_t GetRawMemberAccessFlags() const { - if (pos_ < EndOfInstanceFieldsPos()) { - return field_.access_flags_; - } else { - DCHECK_LT(pos_, EndOfVirtualMethodsPos()); - return method_.access_flags_; - } - } - uint32_t GetFieldAccessFlags() const { - return GetMemberAccessFlags() & kAccValidFieldFlags; - } - uint32_t GetMethodAccessFlags() const { - return GetMemberAccessFlags() & kAccValidMethodFlags; - } - uint32_t GetMemberAccessFlags() const { - return HiddenApiAccessFlags::RemoveFromDex(GetRawMemberAccessFlags()); - } - HiddenApiAccessFlags::ApiList DecodeHiddenAccessFlags() const { - return HiddenApiAccessFlags::DecodeFromDex(GetRawMemberAccessFlags()); - } - bool MemberIsNative() const { - return GetRawMemberAccessFlags() & kAccNative; - } - bool MemberIsFinal() const { - return GetRawMemberAccessFlags() & kAccFinal; - } - ALWAYS_INLINE InvokeType GetMethodInvokeType(const DexFile::ClassDef& class_def) const; - const DexFile::CodeItem* GetMethodCodeItem() const { - return dex_file_.GetCodeItem(method_.code_off_); - } - uint32_t GetMethodCodeItemOffset() const { - return method_.code_off_; - } - const uint8_t* DataPointer() const { - return ptr_pos_; - } - const uint8_t* EndDataPointer() const { - CHECK(!HasNext()); - return ptr_pos_; - } - - private: - // A dex file's class_data_item is leb128 encoded, this structure holds a decoded form of the - // header for a class_data_item - struct ClassDataHeader { - uint32_t static_fields_size_; // the number of static fields - uint32_t instance_fields_size_; // the number of instance fields - uint32_t direct_methods_size_; // the number of direct methods - uint32_t virtual_methods_size_; // the number of virtual methods - } header_; - - // Read and decode header from a class_data_item stream into header - void ReadClassDataHeader(); - - uint32_t EndOfStaticFieldsPos() const { - return header_.static_fields_size_; - } - uint32_t EndOfInstanceFieldsPos() const { - return EndOfStaticFieldsPos() + header_.instance_fields_size_; - } - uint32_t EndOfDirectMethodsPos() const { - return EndOfInstanceFieldsPos() + header_.direct_methods_size_; - } - uint32_t EndOfVirtualMethodsPos() const { - return EndOfDirectMethodsPos() + header_.virtual_methods_size_; - } - - // A decoded version of the field of a class_data_item - struct ClassDataField { - uint32_t field_idx_delta_; // delta of index into the field_ids array for FieldId - uint32_t access_flags_; // access flags for the field - ClassDataField() : field_idx_delta_(0), access_flags_(0) {} - }; - ClassDataField field_; - - // Read and decode a field from a class_data_item stream into field - void ReadClassDataField(); - - // A decoded version of the method of a class_data_item - struct ClassDataMethod { - uint32_t method_idx_delta_; // delta of index into the method_ids array for MethodId - uint32_t access_flags_; - uint32_t code_off_; - ClassDataMethod() : method_idx_delta_(0), access_flags_(0), code_off_(0) {} - }; - ClassDataMethod method_; - - // Read and decode a method from a class_data_item stream into method - void ReadClassDataMethod(); - - const DexFile& dex_file_; - size_t pos_; // integral number of items passed - const uint8_t* ptr_pos_; // pointer into stream of class_data_item - uint32_t last_idx_; // last read field or method index to apply delta to -}; - class EncodedArrayValueIterator { public: EncodedArrayValueIterator(const DexFile& dex_file, const uint8_t* array_data); diff --git a/libdexfile/dex/modifiers.h b/libdexfile/dex/modifiers.h index be82fff65c..38f8455b64 100644 --- a/libdexfile/dex/modifiers.h +++ b/libdexfile/dex/modifiers.h @@ -42,9 +42,8 @@ static constexpr uint32_t kAccEnum = 0x4000; // class, field, ic (1.5) static constexpr uint32_t kAccJavaFlagsMask = 0xffff; // bits set from Java sources (low 16) -// The following flags are used to insert hidden API access flags into boot -// class path dex files. They are decoded by DexFile::ClassDataItemIterator and -// removed from the access flags before used by the runtime. +// The following flags are used to insert hidden API access flags into boot class path dex files. +// They are decoded by ClassAccessor and removed from the access flags before used by the runtime. static constexpr uint32_t kAccDexHiddenBit = 0x00000020; // field, method (not native) static constexpr uint32_t kAccDexHiddenBitNative = 0x00000200; // method (native) |