diff options
Diffstat (limited to 'runtime/dex_file.cc')
-rw-r--r-- | runtime/dex_file.cc | 1311 |
1 files changed, 20 insertions, 1291 deletions
diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc index 76cd348d8e..03223b0d3c 100644 --- a/runtime/dex_file.cc +++ b/runtime/dex_file.cc @@ -27,8 +27,6 @@ #include <memory> #include <sstream> -#include "art_field-inl.h" -#include "art_method-inl.h" #include "base/enums.h" #include "base/file_magic.h" #include "base/hash_map.h" @@ -37,18 +35,13 @@ #include "base/stringprintf.h" #include "base/systrace.h" #include "base/unix_file/fd_file.h" -#include "class_linker-inl.h" #include "dex_file-inl.h" #include "dex_file_verifier.h" #include "globals.h" -#include "handle_scope-inl.h" #include "jvalue.h" #include "leb128.h" -#include "mirror/field.h" -#include "mirror/method.h" -#include "mirror/string.h" +#include "oat_file.h" #include "os.h" -#include "reflection.h" #include "safe_map.h" #include "thread.h" #include "type_lookup_table.h" @@ -510,16 +503,6 @@ DexFile::DexFile(const uint8_t* base, size_t size, oat_dex_file_(oat_dex_file) { CHECK(begin_ != nullptr) << GetLocation(); CHECK_GT(size_, 0U) << GetLocation(); - const uint8_t* lookup_data = (oat_dex_file != nullptr) - ? oat_dex_file->GetLookupTableData() - : nullptr; - if (lookup_data != nullptr) { - if (lookup_data + TypeLookupTable::RawDataLength(*this) > oat_dex_file->GetOatFile()->End()) { - LOG(WARNING) << "found truncated lookup table in " << GetLocation(); - } else { - lookup_table_.reset(TypeLookupTable::Open(lookup_data, *this)); - } - } } DexFile::~DexFile() { @@ -579,33 +562,12 @@ uint32_t DexFile::Header::GetVersion() const { return atoi(version); } -const DexFile::ClassDef* DexFile::FindClassDef(const char* descriptor, size_t hash) const { - DCHECK_EQ(ComputeModifiedUtf8Hash(descriptor), hash); - if (LIKELY(lookup_table_ != nullptr)) { - const uint32_t class_def_idx = lookup_table_->Lookup(descriptor, hash); - return (class_def_idx != DexFile::kDexNoIndex) ? &GetClassDef(class_def_idx) : nullptr; - } - +const DexFile::ClassDef* DexFile::FindClassDef(uint16_t type_idx) const { + size_t num_class_defs = NumClassDefs(); // Fast path for rare no class defs case. - const uint32_t num_class_defs = NumClassDefs(); if (num_class_defs == 0) { return nullptr; } - const TypeId* type_id = FindTypeId(descriptor); - if (type_id != nullptr) { - uint16_t type_idx = GetIndexForTypeId(*type_id); - for (size_t i = 0; i < num_class_defs; ++i) { - const ClassDef& class_def = GetClassDef(i); - if (class_def.class_idx_ == type_idx) { - return &class_def; - } - } - } - return nullptr; -} - -const DexFile::ClassDef* DexFile::FindClassDef(uint16_t type_idx) const { - size_t num_class_defs = NumClassDefs(); for (size_t i = 0; i < num_class_defs; ++i) { const ClassDef& class_def = GetClassDef(i); if (class_def.class_idx_ == type_idx) { @@ -796,10 +758,6 @@ const DexFile::ProtoId* DexFile::FindProtoId(uint16_t return_type_idx, return nullptr; } -void DexFile::CreateTypeLookupTable(uint8_t* storage) const { - lookup_table_.reset(TypeLookupTable::Create(*this, storage)); -} - // Given a signature place the type ids into the given vector bool DexFile::CreateTypeList(const StringPiece& signature, uint16_t* return_type_idx, std::vector<uint16_t>* param_type_idxs) const { @@ -864,22 +822,6 @@ const Signature DexFile::CreateSignature(const StringPiece& signature) const { return Signature(this, *proto_id); } -int32_t DexFile::GetLineNumFromPC(ArtMethod* method, uint32_t rel_pc) const { - // For native method, lineno should be -2 to indicate it is native. Note that - // "line number == -2" is how libcore tells from StackTraceElement. - if (method->GetCodeItemOffset() == 0) { - return -2; - } - - const CodeItem* code_item = GetCodeItem(method->GetCodeItemOffset()); - DCHECK(code_item != nullptr) << PrettyMethod(method) << " " << GetLocation(); - - // A method with no line number info should return -1 - LineNumFromPcContext context(rel_pc, -1); - DecodeDebugPositionInfo(code_item, LineNumForPcCb, &context); - return context.line_num_; -} - int32_t DexFile::FindTryItem(const CodeItem &code_item, uint32_t address) { // Note: Signed type is important for max and min. int32_t min = 0; @@ -1186,7 +1128,7 @@ std::string DexFile::GetDexCanonicalLocation(const char* dex_location) { } // Read a signed integer. "zwidth" is the zero-based byte count. -static int32_t ReadSignedInt(const uint8_t* ptr, int zwidth) { +int32_t DexFile::ReadSignedInt(const uint8_t* ptr, int zwidth) { int32_t val = 0; for (int i = zwidth; i >= 0; --i) { val = ((uint32_t)val >> 8) | (((int32_t)*ptr++) << 24); @@ -1197,7 +1139,7 @@ static int32_t ReadSignedInt(const uint8_t* ptr, int zwidth) { // Read an unsigned integer. "zwidth" is the zero-based byte count, // "fill_on_right" indicates which side we want to zero-fill from. -static uint32_t ReadUnsignedInt(const uint8_t* ptr, int zwidth, bool fill_on_right) { +uint32_t DexFile::ReadUnsignedInt(const uint8_t* ptr, int zwidth, bool fill_on_right) { uint32_t val = 0; for (int i = zwidth; i >= 0; --i) { val = (val >> 8) | (((uint32_t)*ptr++) << 24); @@ -1209,7 +1151,7 @@ static uint32_t ReadUnsignedInt(const uint8_t* ptr, int zwidth, bool fill_on_rig } // Read a signed long. "zwidth" is the zero-based byte count. -static int64_t ReadSignedLong(const uint8_t* ptr, int zwidth) { +int64_t DexFile::ReadSignedLong(const uint8_t* ptr, int zwidth) { int64_t val = 0; for (int i = zwidth; i >= 0; --i) { val = ((uint64_t)val >> 8) | (((int64_t)*ptr++) << 56); @@ -1220,7 +1162,7 @@ static int64_t ReadSignedLong(const uint8_t* ptr, int zwidth) { // Read an unsigned long. "zwidth" is the zero-based byte count, // "fill_on_right" indicates which side we want to zero-fill from. -static uint64_t ReadUnsignedLong(const uint8_t* ptr, int zwidth, bool fill_on_right) { +uint64_t DexFile::ReadUnsignedLong(const uint8_t* ptr, int zwidth, bool fill_on_right) { uint64_t val = 0; for (int i = zwidth; i >= 0; --i) { val = (val >> 8) | (((uint64_t)*ptr++) << 56); @@ -1233,1150 +1175,6 @@ static uint64_t ReadUnsignedLong(const uint8_t* ptr, int zwidth, bool fill_on_ri // Checks that visibility is as expected. Includes special behavior for M and // before to allow runtime and build visibility when expecting runtime. -static bool IsVisibilityCompatible(uint32_t actual, uint32_t expected) { - if (expected == DexFile::kDexVisibilityRuntime) { - int32_t sdk_version = Runtime::Current()->GetTargetSdkVersion(); - if (sdk_version > 0 && sdk_version <= 23) { - return actual == DexFile::kDexVisibilityRuntime || actual == DexFile::kDexVisibilityBuild; - } - } - return actual == expected; -} - -const DexFile::AnnotationSetItem* DexFile::FindAnnotationSetForField(ArtField* field) const { - mirror::Class* klass = field->GetDeclaringClass(); - const AnnotationsDirectoryItem* annotations_dir = GetAnnotationsDirectory(*klass->GetClassDef()); - if (annotations_dir == nullptr) { - return nullptr; - } - const FieldAnnotationsItem* field_annotations = GetFieldAnnotations(annotations_dir); - if (field_annotations == nullptr) { - return nullptr; - } - uint32_t field_index = field->GetDexFieldIndex(); - uint32_t field_count = annotations_dir->fields_size_; - for (uint32_t i = 0; i < field_count; ++i) { - if (field_annotations[i].field_idx_ == field_index) { - return GetFieldAnnotationSetItem(field_annotations[i]); - } - } - return nullptr; -} - -mirror::Object* DexFile::GetAnnotationForField(ArtField* field, - Handle<mirror::Class> annotation_class) const { - const AnnotationSetItem* annotation_set = FindAnnotationSetForField(field); - if (annotation_set == nullptr) { - return nullptr; - } - StackHandleScope<1> hs(Thread::Current()); - Handle<mirror::Class> field_class(hs.NewHandle(field->GetDeclaringClass())); - return GetAnnotationObjectFromAnnotationSet( - field_class, annotation_set, kDexVisibilityRuntime, annotation_class); -} - -mirror::ObjectArray<mirror::Object>* DexFile::GetAnnotationsForField(ArtField* field) const { - const AnnotationSetItem* annotation_set = FindAnnotationSetForField(field); - StackHandleScope<1> hs(Thread::Current()); - Handle<mirror::Class> field_class(hs.NewHandle(field->GetDeclaringClass())); - return ProcessAnnotationSet(field_class, annotation_set, kDexVisibilityRuntime); -} - -mirror::ObjectArray<mirror::String>* DexFile::GetSignatureAnnotationForField(ArtField* field) - const { - const AnnotationSetItem* annotation_set = FindAnnotationSetForField(field); - if (annotation_set == nullptr) { - return nullptr; - } - StackHandleScope<1> hs(Thread::Current()); - Handle<mirror::Class> field_class(hs.NewHandle(field->GetDeclaringClass())); - return GetSignatureValue(field_class, annotation_set); -} - -bool DexFile::IsFieldAnnotationPresent(ArtField* field, Handle<mirror::Class> annotation_class) - const { - const AnnotationSetItem* annotation_set = FindAnnotationSetForField(field); - if (annotation_set == nullptr) { - return false; - } - StackHandleScope<1> hs(Thread::Current()); - Handle<mirror::Class> field_class(hs.NewHandle(field->GetDeclaringClass())); - const AnnotationItem* annotation_item = GetAnnotationItemFromAnnotationSet( - field_class, annotation_set, kDexVisibilityRuntime, annotation_class); - return annotation_item != nullptr; -} - -const DexFile::AnnotationSetItem* DexFile::FindAnnotationSetForMethod(ArtMethod* method) const { - mirror::Class* klass = method->GetDeclaringClass(); - const AnnotationsDirectoryItem* annotations_dir = GetAnnotationsDirectory(*klass->GetClassDef()); - if (annotations_dir == nullptr) { - return nullptr; - } - const MethodAnnotationsItem* method_annotations = GetMethodAnnotations(annotations_dir); - if (method_annotations == nullptr) { - return nullptr; - } - uint32_t method_index = method->GetDexMethodIndex(); - uint32_t method_count = annotations_dir->methods_size_; - for (uint32_t i = 0; i < method_count; ++i) { - if (method_annotations[i].method_idx_ == method_index) { - return GetMethodAnnotationSetItem(method_annotations[i]); - } - } - return nullptr; -} - -const DexFile::ParameterAnnotationsItem* DexFile::FindAnnotationsItemForMethod(ArtMethod* method) - const { - mirror::Class* klass = method->GetDeclaringClass(); - const AnnotationsDirectoryItem* annotations_dir = GetAnnotationsDirectory(*klass->GetClassDef()); - if (annotations_dir == nullptr) { - return nullptr; - } - const ParameterAnnotationsItem* parameter_annotations = GetParameterAnnotations(annotations_dir); - if (parameter_annotations == nullptr) { - return nullptr; - } - uint32_t method_index = method->GetDexMethodIndex(); - uint32_t parameter_count = annotations_dir->parameters_size_; - for (uint32_t i = 0; i < parameter_count; ++i) { - if (parameter_annotations[i].method_idx_ == method_index) { - return ¶meter_annotations[i]; - } - } - return nullptr; -} - -mirror::Object* DexFile::GetAnnotationDefaultValue(ArtMethod* method) const { - mirror::Class* klass = method->GetDeclaringClass(); - const AnnotationsDirectoryItem* annotations_dir = GetAnnotationsDirectory(*klass->GetClassDef()); - if (annotations_dir == nullptr) { - return nullptr; - } - const AnnotationSetItem* annotation_set = GetClassAnnotationSet(annotations_dir); - if (annotation_set == nullptr) { - return nullptr; - } - const AnnotationItem* annotation_item = SearchAnnotationSet(annotation_set, - "Ldalvik/annotation/AnnotationDefault;", kDexVisibilitySystem); - if (annotation_item == nullptr) { - return nullptr; - } - const uint8_t* annotation = SearchEncodedAnnotation(annotation_item->annotation_, "value"); - if (annotation == nullptr) { - return nullptr; - } - uint8_t header_byte = *(annotation++); - if ((header_byte & kDexAnnotationValueTypeMask) != kDexAnnotationAnnotation) { - return nullptr; - } - annotation = SearchEncodedAnnotation(annotation, method->GetName()); - if (annotation == nullptr) { - return nullptr; - } - AnnotationValue annotation_value; - StackHandleScope<2> hs(Thread::Current()); - Handle<mirror::Class> h_klass(hs.NewHandle(klass)); - PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); - Handle<mirror::Class> return_type(hs.NewHandle( - method->GetReturnType(true /* resolve */, pointer_size))); - if (!ProcessAnnotationValue(h_klass, &annotation, &annotation_value, return_type, kAllObjects)) { - return nullptr; - } - return annotation_value.value_.GetL(); -} - -mirror::Object* DexFile::GetAnnotationForMethod(ArtMethod* method, - Handle<mirror::Class> annotation_class) const { - const AnnotationSetItem* annotation_set = FindAnnotationSetForMethod(method); - if (annotation_set == nullptr) { - return nullptr; - } - StackHandleScope<1> hs(Thread::Current()); - Handle<mirror::Class> method_class(hs.NewHandle(method->GetDeclaringClass())); - return GetAnnotationObjectFromAnnotationSet(method_class, annotation_set, - kDexVisibilityRuntime, annotation_class); -} - -mirror::ObjectArray<mirror::Object>* DexFile::GetAnnotationsForMethod(ArtMethod* method) const { - const AnnotationSetItem* annotation_set = FindAnnotationSetForMethod(method); - StackHandleScope<1> hs(Thread::Current()); - Handle<mirror::Class> method_class(hs.NewHandle(method->GetDeclaringClass())); - return ProcessAnnotationSet(method_class, annotation_set, kDexVisibilityRuntime); -} - -mirror::ObjectArray<mirror::Class>* DexFile::GetExceptionTypesForMethod(ArtMethod* method) const { - const AnnotationSetItem* annotation_set = FindAnnotationSetForMethod(method); - if (annotation_set == nullptr) { - return nullptr; - } - StackHandleScope<1> hs(Thread::Current()); - Handle<mirror::Class> method_class(hs.NewHandle(method->GetDeclaringClass())); - return GetThrowsValue(method_class, annotation_set); -} - -mirror::ObjectArray<mirror::Object>* DexFile::GetParameterAnnotations(ArtMethod* method) const { - const ParameterAnnotationsItem* parameter_annotations = FindAnnotationsItemForMethod(method); - if (parameter_annotations == nullptr) { - return nullptr; - } - const AnnotationSetRefList* set_ref_list = - GetParameterAnnotationSetRefList(parameter_annotations); - if (set_ref_list == nullptr) { - return nullptr; - } - uint32_t size = set_ref_list->size_; - StackHandleScope<1> hs(Thread::Current()); - Handle<mirror::Class> method_class(hs.NewHandle(method->GetDeclaringClass())); - return ProcessAnnotationSetRefList(method_class, set_ref_list, size); -} - -mirror::Object* DexFile::GetAnnotationForMethodParameter(ArtMethod* method, - uint32_t parameter_idx, - Handle<mirror::Class> annotation_class) - const { - const ParameterAnnotationsItem* parameter_annotations = FindAnnotationsItemForMethod(method); - if (parameter_annotations == nullptr) { - return nullptr; - } - const AnnotationSetRefList* set_ref_list = - GetParameterAnnotationSetRefList(parameter_annotations); - if (set_ref_list == nullptr) { - return nullptr; - } - - if (parameter_idx >= set_ref_list->size_) { - return nullptr; - } - const AnnotationSetRefItem* annotation_set_ref = &set_ref_list->list_[parameter_idx]; - const AnnotationSetItem* annotation_set = GetSetRefItemItem(annotation_set_ref); - - StackHandleScope<1> hs(Thread::Current()); - Handle<mirror::Class> method_class(hs.NewHandle(method->GetDeclaringClass())); - return GetAnnotationObjectFromAnnotationSet(method_class, - annotation_set, - kDexVisibilityRuntime, - annotation_class); -} - -mirror::ObjectArray<mirror::String>* DexFile::GetSignatureAnnotationForMethod(ArtMethod* method) - const { - const AnnotationSetItem* annotation_set = FindAnnotationSetForMethod(method); - if (annotation_set == nullptr) { - return nullptr; - } - StackHandleScope<1> hs(Thread::Current()); - Handle<mirror::Class> method_class(hs.NewHandle(method->GetDeclaringClass())); - return GetSignatureValue(method_class, annotation_set); -} - -bool DexFile::IsMethodAnnotationPresent(ArtMethod* method, - Handle<mirror::Class> annotation_class, - uint32_t visibility /* = kDexVisibilityRuntime */) - const { - const AnnotationSetItem* annotation_set = FindAnnotationSetForMethod(method); - if (annotation_set == nullptr) { - return false; - } - StackHandleScope<1> hs(Thread::Current()); - Handle<mirror::Class> method_class(hs.NewHandle(method->GetDeclaringClass())); - const AnnotationItem* annotation_item = GetAnnotationItemFromAnnotationSet(method_class, - annotation_set, - visibility, - annotation_class); - return annotation_item != nullptr; -} - -const DexFile::AnnotationSetItem* DexFile::FindAnnotationSetForClass(Handle<mirror::Class> klass) - const { - const AnnotationsDirectoryItem* annotations_dir = GetAnnotationsDirectory(*klass->GetClassDef()); - if (annotations_dir == nullptr) { - return nullptr; - } - return GetClassAnnotationSet(annotations_dir); -} - -mirror::Object* DexFile::GetAnnotationForClass(Handle<mirror::Class> klass, - Handle<mirror::Class> annotation_class) const { - const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass); - if (annotation_set == nullptr) { - return nullptr; - } - return GetAnnotationObjectFromAnnotationSet(klass, annotation_set, kDexVisibilityRuntime, - annotation_class); -} - -mirror::ObjectArray<mirror::Object>* DexFile::GetAnnotationsForClass(Handle<mirror::Class> klass) - const { - const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass); - return ProcessAnnotationSet(klass, annotation_set, kDexVisibilityRuntime); -} - -mirror::ObjectArray<mirror::Class>* DexFile::GetDeclaredClasses(Handle<mirror::Class> klass) const { - const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass); - if (annotation_set == nullptr) { - return nullptr; - } - const AnnotationItem* annotation_item = SearchAnnotationSet( - annotation_set, "Ldalvik/annotation/MemberClasses;", kDexVisibilitySystem); - if (annotation_item == nullptr) { - return nullptr; - } - StackHandleScope<1> hs(Thread::Current()); - mirror::Class* class_class = mirror::Class::GetJavaLangClass(); - Handle<mirror::Class> class_array_class(hs.NewHandle( - Runtime::Current()->GetClassLinker()->FindArrayClass(hs.Self(), &class_class))); - if (class_array_class.Get() == nullptr) { - return nullptr; - } - mirror::Object* obj = GetAnnotationValue( - klass, annotation_item, "value", class_array_class, kDexAnnotationArray); - if (obj == nullptr) { - return nullptr; - } - return obj->AsObjectArray<mirror::Class>(); -} - -mirror::Class* DexFile::GetDeclaringClass(Handle<mirror::Class> klass) const { - const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass); - if (annotation_set == nullptr) { - return nullptr; - } - const AnnotationItem* annotation_item = SearchAnnotationSet( - annotation_set, "Ldalvik/annotation/EnclosingClass;", kDexVisibilitySystem); - if (annotation_item == nullptr) { - return nullptr; - } - mirror::Object* obj = GetAnnotationValue(klass, - annotation_item, - "value", - ScopedNullHandle<mirror::Class>(), - kDexAnnotationType); - if (obj == nullptr) { - return nullptr; - } - return obj->AsClass(); -} - -mirror::Class* DexFile::GetEnclosingClass(Handle<mirror::Class> klass) const { - mirror::Class* declaring_class = GetDeclaringClass(klass); - if (declaring_class != nullptr) { - return declaring_class; - } - const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass); - if (annotation_set == nullptr) { - return nullptr; - } - const AnnotationItem* annotation_item = SearchAnnotationSet( - annotation_set, "Ldalvik/annotation/EnclosingMethod;", kDexVisibilitySystem); - if (annotation_item == nullptr) { - return nullptr; - } - const uint8_t* annotation = SearchEncodedAnnotation(annotation_item->annotation_, "value"); - if (annotation == nullptr) { - return nullptr; - } - AnnotationValue annotation_value; - if (!ProcessAnnotationValue(klass, - &annotation, - &annotation_value, - ScopedNullHandle<mirror::Class>(), - kAllRaw)) { - return nullptr; - } - if (annotation_value.type_ != kDexAnnotationMethod) { - return nullptr; - } - StackHandleScope<2> hs(Thread::Current()); - Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache())); - Handle<mirror::ClassLoader> class_loader(hs.NewHandle(klass->GetClassLoader())); - ArtMethod* method = Runtime::Current()->GetClassLinker()->ResolveMethodWithoutInvokeType( - klass->GetDexFile(), annotation_value.value_.GetI(), dex_cache, class_loader); - if (method == nullptr) { - return nullptr; - } - return method->GetDeclaringClass(); -} - -mirror::Object* DexFile::GetEnclosingMethod(Handle<mirror::Class> klass) const { - const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass); - if (annotation_set == nullptr) { - return nullptr; - } - const AnnotationItem* annotation_item = SearchAnnotationSet( - annotation_set, "Ldalvik/annotation/EnclosingMethod;", kDexVisibilitySystem); - if (annotation_item == nullptr) { - return nullptr; - } - return GetAnnotationValue( - klass, annotation_item, "value", ScopedNullHandle<mirror::Class>(), kDexAnnotationMethod); -} - -bool DexFile::GetInnerClass(Handle<mirror::Class> klass, mirror::String** name) const { - const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass); - if (annotation_set == nullptr) { - return false; - } - const AnnotationItem* annotation_item = SearchAnnotationSet( - annotation_set, "Ldalvik/annotation/InnerClass;", kDexVisibilitySystem); - if (annotation_item == nullptr) { - return false; - } - const uint8_t* annotation = SearchEncodedAnnotation(annotation_item->annotation_, "name"); - if (annotation == nullptr) { - return false; - } - AnnotationValue annotation_value; - if (!ProcessAnnotationValue(klass, - &annotation, - &annotation_value, - ScopedNullHandle<mirror::Class>(), - kAllObjects)) { - return false; - } - if (annotation_value.type_ != kDexAnnotationNull && - annotation_value.type_ != kDexAnnotationString) { - return false; - } - *name = down_cast<mirror::String*>(annotation_value.value_.GetL()); - return true; -} - -bool DexFile::GetInnerClassFlags(Handle<mirror::Class> klass, uint32_t* flags) const { - const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass); - if (annotation_set == nullptr) { - return false; - } - const AnnotationItem* annotation_item = SearchAnnotationSet( - annotation_set, "Ldalvik/annotation/InnerClass;", kDexVisibilitySystem); - if (annotation_item == nullptr) { - return false; - } - const uint8_t* annotation = SearchEncodedAnnotation(annotation_item->annotation_, "accessFlags"); - if (annotation == nullptr) { - return false; - } - AnnotationValue annotation_value; - if (!ProcessAnnotationValue(klass, - &annotation, - &annotation_value, - ScopedNullHandle<mirror::Class>(), - kAllRaw)) { - return false; - } - if (annotation_value.type_ != kDexAnnotationInt) { - return false; - } - *flags = annotation_value.value_.GetI(); - return true; -} - -mirror::ObjectArray<mirror::String>* DexFile::GetSignatureAnnotationForClass( - Handle<mirror::Class> klass) const { - const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass); - if (annotation_set == nullptr) { - return nullptr; - } - return GetSignatureValue(klass, annotation_set); -} - -bool DexFile::IsClassAnnotationPresent(Handle<mirror::Class> klass, - Handle<mirror::Class> annotation_class) const { - const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass); - if (annotation_set == nullptr) { - return false; - } - const AnnotationItem* annotation_item = GetAnnotationItemFromAnnotationSet( - klass, annotation_set, kDexVisibilityRuntime, annotation_class); - return annotation_item != nullptr; -} - -mirror::Object* DexFile::CreateAnnotationMember(Handle<mirror::Class> klass, - Handle<mirror::Class> annotation_class, const uint8_t** annotation) const { - Thread* self = Thread::Current(); - ScopedObjectAccessUnchecked soa(self); - StackHandleScope<5> hs(self); - uint32_t element_name_index = DecodeUnsignedLeb128(annotation); - const char* name = StringDataByIdx(element_name_index); - Handle<mirror::String> string_name( - hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, name))); - - PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); - ArtMethod* annotation_method = - annotation_class->FindDeclaredVirtualMethodByName(name, pointer_size); - if (annotation_method == nullptr) { - return nullptr; - } - Handle<mirror::Class> method_return(hs.NewHandle( - annotation_method->GetReturnType(true /* resolve */, pointer_size))); - - AnnotationValue annotation_value; - if (!ProcessAnnotationValue(klass, annotation, &annotation_value, method_return, kAllObjects)) { - return nullptr; - } - Handle<mirror::Object> value_object(hs.NewHandle(annotation_value.value_.GetL())); - - mirror::Class* annotation_member_class = - WellKnownClasses::ToClass(WellKnownClasses::libcore_reflect_AnnotationMember); - Handle<mirror::Object> new_member(hs.NewHandle(annotation_member_class->AllocObject(self))); - mirror::Method* method_obj_ptr; - DCHECK(!Runtime::Current()->IsActiveTransaction()); - if (pointer_size == PointerSize::k64) { - method_obj_ptr = mirror::Method::CreateFromArtMethod<PointerSize::k64, false>( - self, annotation_method); - } else { - method_obj_ptr = mirror::Method::CreateFromArtMethod<PointerSize::k32, false>( - self, annotation_method); - } - Handle<mirror::Method> method_object(hs.NewHandle(method_obj_ptr)); - - if (new_member.Get() == nullptr || string_name.Get() == nullptr || - method_object.Get() == nullptr || method_return.Get() == nullptr) { - LOG(ERROR) << StringPrintf("Failed creating annotation element (m=%p n=%p a=%p r=%p", - new_member.Get(), string_name.Get(), method_object.Get(), method_return.Get()); - return nullptr; - } - - JValue result; - ArtMethod* annotation_member_init = - soa.DecodeMethod(WellKnownClasses::libcore_reflect_AnnotationMember_init); - uint32_t args[5] = { static_cast<uint32_t>(reinterpret_cast<uintptr_t>(new_member.Get())), - static_cast<uint32_t>(reinterpret_cast<uintptr_t>(string_name.Get())), - static_cast<uint32_t>(reinterpret_cast<uintptr_t>(value_object.Get())), - static_cast<uint32_t>(reinterpret_cast<uintptr_t>(method_return.Get())), - static_cast<uint32_t>(reinterpret_cast<uintptr_t>(method_object.Get())) - }; - annotation_member_init->Invoke(self, args, sizeof(args), &result, "VLLLL"); - if (self->IsExceptionPending()) { - LOG(INFO) << "Exception in AnnotationMember.<init>"; - return nullptr; - } - - return new_member.Get(); -} - -const DexFile::AnnotationItem* DexFile::GetAnnotationItemFromAnnotationSet( - Handle<mirror::Class> klass, const AnnotationSetItem* annotation_set, uint32_t visibility, - Handle<mirror::Class> annotation_class) const { - for (uint32_t i = 0; i < annotation_set->size_; ++i) { - const AnnotationItem* annotation_item = GetAnnotationItem(annotation_set, i); - if (!IsVisibilityCompatible(annotation_item->visibility_, visibility)) { - continue; - } - const uint8_t* annotation = annotation_item->annotation_; - uint32_t type_index = DecodeUnsignedLeb128(&annotation); - mirror::Class* resolved_class = Runtime::Current()->GetClassLinker()->ResolveType( - klass->GetDexFile(), type_index, klass.Get()); - if (resolved_class == nullptr) { - std::string temp; - LOG(WARNING) << StringPrintf("Unable to resolve %s annotation class %d", - klass->GetDescriptor(&temp), type_index); - CHECK(Thread::Current()->IsExceptionPending()); - Thread::Current()->ClearException(); - continue; - } - if (resolved_class == annotation_class.Get()) { - return annotation_item; - } - } - - return nullptr; -} - -mirror::Object* DexFile::GetAnnotationObjectFromAnnotationSet(Handle<mirror::Class> klass, - const AnnotationSetItem* annotation_set, uint32_t visibility, - Handle<mirror::Class> annotation_class) const { - const AnnotationItem* annotation_item = - GetAnnotationItemFromAnnotationSet(klass, annotation_set, visibility, annotation_class); - if (annotation_item == nullptr) { - return nullptr; - } - const uint8_t* annotation = annotation_item->annotation_; - return ProcessEncodedAnnotation(klass, &annotation); -} - -mirror::Object* DexFile::GetAnnotationValue(Handle<mirror::Class> klass, - const AnnotationItem* annotation_item, const char* annotation_name, - Handle<mirror::Class> array_class, uint32_t expected_type) const { - const uint8_t* annotation = - SearchEncodedAnnotation(annotation_item->annotation_, annotation_name); - if (annotation == nullptr) { - return nullptr; - } - AnnotationValue annotation_value; - if (!ProcessAnnotationValue(klass, &annotation, &annotation_value, array_class, kAllObjects)) { - return nullptr; - } - if (annotation_value.type_ != expected_type) { - return nullptr; - } - return annotation_value.value_.GetL(); -} - -mirror::ObjectArray<mirror::String>* DexFile::GetSignatureValue(Handle<mirror::Class> klass, - const AnnotationSetItem* annotation_set) const { - StackHandleScope<1> hs(Thread::Current()); - const AnnotationItem* annotation_item = - SearchAnnotationSet(annotation_set, "Ldalvik/annotation/Signature;", kDexVisibilitySystem); - if (annotation_item == nullptr) { - return nullptr; - } - mirror::Class* string_class = mirror::String::GetJavaLangString(); - Handle<mirror::Class> string_array_class(hs.NewHandle( - Runtime::Current()->GetClassLinker()->FindArrayClass(Thread::Current(), &string_class))); - if (string_array_class.Get() == nullptr) { - return nullptr; - } - mirror::Object* obj = - GetAnnotationValue(klass, annotation_item, "value", string_array_class, kDexAnnotationArray); - if (obj == nullptr) { - return nullptr; - } - return obj->AsObjectArray<mirror::String>(); -} - -mirror::ObjectArray<mirror::Class>* DexFile::GetThrowsValue(Handle<mirror::Class> klass, - const AnnotationSetItem* annotation_set) const { - StackHandleScope<1> hs(Thread::Current()); - const AnnotationItem* annotation_item = - SearchAnnotationSet(annotation_set, "Ldalvik/annotation/Throws;", kDexVisibilitySystem); - if (annotation_item == nullptr) { - return nullptr; - } - mirror::Class* class_class = mirror::Class::GetJavaLangClass(); - Handle<mirror::Class> class_array_class(hs.NewHandle( - Runtime::Current()->GetClassLinker()->FindArrayClass(Thread::Current(), &class_class))); - if (class_array_class.Get() == nullptr) { - return nullptr; - } - mirror::Object* obj = - GetAnnotationValue(klass, annotation_item, "value", class_array_class, kDexAnnotationArray); - if (obj == nullptr) { - return nullptr; - } - return obj->AsObjectArray<mirror::Class>(); -} - -mirror::ObjectArray<mirror::Object>* DexFile::ProcessAnnotationSet(Handle<mirror::Class> klass, - const AnnotationSetItem* annotation_set, uint32_t visibility) const { - Thread* self = Thread::Current(); - ScopedObjectAccessUnchecked soa(self); - StackHandleScope<2> hs(self); - Handle<mirror::Class> annotation_array_class(hs.NewHandle( - soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_annotation_Annotation__array))); - if (annotation_set == nullptr) { - return mirror::ObjectArray<mirror::Object>::Alloc(self, annotation_array_class.Get(), 0); - } - - uint32_t size = annotation_set->size_; - Handle<mirror::ObjectArray<mirror::Object>> result(hs.NewHandle( - mirror::ObjectArray<mirror::Object>::Alloc(self, annotation_array_class.Get(), size))); - if (result.Get() == nullptr) { - return nullptr; - } - - uint32_t dest_index = 0; - for (uint32_t i = 0; i < size; ++i) { - const AnnotationItem* annotation_item = GetAnnotationItem(annotation_set, i); - // Note that we do not use IsVisibilityCompatible here because older code - // was correct for this case. - if (annotation_item->visibility_ != visibility) { - continue; - } - const uint8_t* annotation = annotation_item->annotation_; - mirror::Object* annotation_obj = ProcessEncodedAnnotation(klass, &annotation); - if (annotation_obj != nullptr) { - result->SetWithoutChecks<false>(dest_index, annotation_obj); - ++dest_index; - } else if (self->IsExceptionPending()) { - return nullptr; - } - } - - if (dest_index == size) { - return result.Get(); - } - - mirror::ObjectArray<mirror::Object>* trimmed_result = - mirror::ObjectArray<mirror::Object>::Alloc(self, annotation_array_class.Get(), dest_index); - if (trimmed_result == nullptr) { - return nullptr; - } - - for (uint32_t i = 0; i < dest_index; ++i) { - mirror::Object* obj = result->GetWithoutChecks(i); - trimmed_result->SetWithoutChecks<false>(i, obj); - } - - return trimmed_result; -} - -mirror::ObjectArray<mirror::Object>* DexFile::ProcessAnnotationSetRefList( - Handle<mirror::Class> klass, const AnnotationSetRefList* set_ref_list, uint32_t size) const { - Thread* self = Thread::Current(); - ScopedObjectAccessUnchecked soa(self); - StackHandleScope<1> hs(self); - mirror::Class* annotation_array_class = - soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_annotation_Annotation__array); - mirror::Class* annotation_array_array_class = - Runtime::Current()->GetClassLinker()->FindArrayClass(self, &annotation_array_class); - if (annotation_array_array_class == nullptr) { - return nullptr; - } - Handle<mirror::ObjectArray<mirror::Object>> annotation_array_array(hs.NewHandle( - mirror::ObjectArray<mirror::Object>::Alloc(self, annotation_array_array_class, size))); - if (annotation_array_array.Get() == nullptr) { - LOG(ERROR) << "Annotation set ref array allocation failed"; - return nullptr; - } - for (uint32_t index = 0; index < size; ++index) { - const AnnotationSetRefItem* set_ref_item = &set_ref_list->list_[index]; - const AnnotationSetItem* set_item = GetSetRefItemItem(set_ref_item); - mirror::Object* annotation_set = ProcessAnnotationSet(klass, set_item, kDexVisibilityRuntime); - if (annotation_set == nullptr) { - return nullptr; - } - annotation_array_array->SetWithoutChecks<false>(index, annotation_set); - } - return annotation_array_array.Get(); -} - -bool DexFile::ProcessAnnotationValue(Handle<mirror::Class> klass, const uint8_t** annotation_ptr, - AnnotationValue* annotation_value, Handle<mirror::Class> array_class, - DexFile::AnnotationResultStyle result_style) const { - Thread* self = Thread::Current(); - mirror::Object* element_object = nullptr; - bool set_object = false; - Primitive::Type primitive_type = Primitive::kPrimVoid; - const uint8_t* annotation = *annotation_ptr; - uint8_t header_byte = *(annotation++); - uint8_t value_type = header_byte & kDexAnnotationValueTypeMask; - uint8_t value_arg = header_byte >> kDexAnnotationValueArgShift; - int32_t width = value_arg + 1; - annotation_value->type_ = value_type; - - switch (value_type) { - case kDexAnnotationByte: - annotation_value->value_.SetB(static_cast<int8_t>(ReadSignedInt(annotation, value_arg))); - primitive_type = Primitive::kPrimByte; - break; - case kDexAnnotationShort: - annotation_value->value_.SetS(static_cast<int16_t>(ReadSignedInt(annotation, value_arg))); - primitive_type = Primitive::kPrimShort; - break; - case kDexAnnotationChar: - annotation_value->value_.SetC(static_cast<uint16_t>(ReadUnsignedInt(annotation, value_arg, - false))); - primitive_type = Primitive::kPrimChar; - break; - case kDexAnnotationInt: - annotation_value->value_.SetI(ReadSignedInt(annotation, value_arg)); - primitive_type = Primitive::kPrimInt; - break; - case kDexAnnotationLong: - annotation_value->value_.SetJ(ReadSignedLong(annotation, value_arg)); - primitive_type = Primitive::kPrimLong; - break; - case kDexAnnotationFloat: - annotation_value->value_.SetI(ReadUnsignedInt(annotation, value_arg, true)); - primitive_type = Primitive::kPrimFloat; - break; - case kDexAnnotationDouble: - annotation_value->value_.SetJ(ReadUnsignedLong(annotation, value_arg, true)); - primitive_type = Primitive::kPrimDouble; - break; - case kDexAnnotationBoolean: - annotation_value->value_.SetZ(value_arg != 0); - primitive_type = Primitive::kPrimBoolean; - width = 0; - break; - case kDexAnnotationString: { - uint32_t index = ReadUnsignedInt(annotation, value_arg, false); - if (result_style == kAllRaw) { - annotation_value->value_.SetI(index); - } else { - StackHandleScope<1> hs(self); - Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache())); - element_object = Runtime::Current()->GetClassLinker()->ResolveString( - klass->GetDexFile(), index, dex_cache); - set_object = true; - if (element_object == nullptr) { - return false; - } - } - break; - } - case kDexAnnotationType: { - uint32_t index = ReadUnsignedInt(annotation, value_arg, false); - if (result_style == kAllRaw) { - annotation_value->value_.SetI(index); - } else { - element_object = Runtime::Current()->GetClassLinker()->ResolveType( - klass->GetDexFile(), index, klass.Get()); - set_object = true; - if (element_object == nullptr) { - CHECK(self->IsExceptionPending()); - if (result_style == kAllObjects) { - const char* msg = StringByTypeIdx(index); - self->ThrowNewWrappedException("Ljava/lang/TypeNotPresentException;", msg); - element_object = self->GetException(); - self->ClearException(); - } else { - return false; - } - } - } - break; - } - case kDexAnnotationMethod: { - uint32_t index = ReadUnsignedInt(annotation, value_arg, false); - if (result_style == kAllRaw) { - annotation_value->value_.SetI(index); - } else { - StackHandleScope<2> hs(self); - Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache())); - Handle<mirror::ClassLoader> class_loader(hs.NewHandle(klass->GetClassLoader())); - ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); - ArtMethod* method = class_linker->ResolveMethodWithoutInvokeType( - klass->GetDexFile(), index, dex_cache, class_loader); - if (method == nullptr) { - return false; - } - PointerSize pointer_size = class_linker->GetImagePointerSize(); - set_object = true; - DCHECK(!Runtime::Current()->IsActiveTransaction()); - if (method->IsConstructor()) { - if (pointer_size == PointerSize::k64) { - element_object = mirror::Constructor::CreateFromArtMethod<PointerSize::k64, - false>(self, method); - } else { - element_object = mirror::Constructor::CreateFromArtMethod<PointerSize::k32, - false>(self, method); - } - } else { - if (pointer_size == PointerSize::k64) { - element_object = mirror::Method::CreateFromArtMethod<PointerSize::k64, - false>(self, method); - } else { - element_object = mirror::Method::CreateFromArtMethod<PointerSize::k32, - false>(self, method); - } - } - if (element_object == nullptr) { - return false; - } - } - break; - } - case kDexAnnotationField: { - uint32_t index = ReadUnsignedInt(annotation, value_arg, false); - if (result_style == kAllRaw) { - annotation_value->value_.SetI(index); - } else { - StackHandleScope<2> hs(self); - Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache())); - Handle<mirror::ClassLoader> class_loader(hs.NewHandle(klass->GetClassLoader())); - ArtField* field = Runtime::Current()->GetClassLinker()->ResolveFieldJLS( - klass->GetDexFile(), index, dex_cache, class_loader); - if (field == nullptr) { - return false; - } - set_object = true; - PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); - if (pointer_size == PointerSize::k64) { - element_object = mirror::Field::CreateFromArtField<PointerSize::k64>(self, field, true); - } else { - element_object = mirror::Field::CreateFromArtField<PointerSize::k32>(self, field, true); - } - if (element_object == nullptr) { - return false; - } - } - break; - } - case kDexAnnotationEnum: { - uint32_t index = ReadUnsignedInt(annotation, value_arg, false); - if (result_style == kAllRaw) { - annotation_value->value_.SetI(index); - } else { - StackHandleScope<3> hs(self); - Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache())); - Handle<mirror::ClassLoader> class_loader(hs.NewHandle(klass->GetClassLoader())); - ArtField* enum_field = Runtime::Current()->GetClassLinker()->ResolveField( - klass->GetDexFile(), index, dex_cache, class_loader, true); - if (enum_field == nullptr) { - return false; - } else { - Handle<mirror::Class> field_class(hs.NewHandle(enum_field->GetDeclaringClass())); - Runtime::Current()->GetClassLinker()->EnsureInitialized(self, field_class, true, true); - element_object = enum_field->GetObject(field_class.Get()); - set_object = true; - } - } - break; - } - case kDexAnnotationArray: - if (result_style == kAllRaw || array_class.Get() == nullptr) { - return false; - } else { - ScopedObjectAccessUnchecked soa(self); - StackHandleScope<2> hs(self); - uint32_t size = DecodeUnsignedLeb128(&annotation); - Handle<mirror::Class> component_type(hs.NewHandle(array_class->GetComponentType())); - Handle<mirror::Array> new_array(hs.NewHandle(mirror::Array::Alloc<true>( - self, array_class.Get(), size, array_class->GetComponentSizeShift(), - Runtime::Current()->GetHeap()->GetCurrentAllocator()))); - if (new_array.Get() == nullptr) { - LOG(ERROR) << "Annotation element array allocation failed with size " << size; - return false; - } - AnnotationValue new_annotation_value; - for (uint32_t i = 0; i < size; ++i) { - if (!ProcessAnnotationValue(klass, &annotation, &new_annotation_value, component_type, - kPrimitivesOrObjects)) { - return false; - } - if (!component_type->IsPrimitive()) { - mirror::Object* obj = new_annotation_value.value_.GetL(); - new_array->AsObjectArray<mirror::Object>()->SetWithoutChecks<false>(i, obj); - } else { - switch (new_annotation_value.type_) { - case kDexAnnotationByte: - new_array->AsByteArray()->SetWithoutChecks<false>( - i, new_annotation_value.value_.GetB()); - break; - case kDexAnnotationShort: - new_array->AsShortArray()->SetWithoutChecks<false>( - i, new_annotation_value.value_.GetS()); - break; - case kDexAnnotationChar: - new_array->AsCharArray()->SetWithoutChecks<false>( - i, new_annotation_value.value_.GetC()); - break; - case kDexAnnotationInt: - new_array->AsIntArray()->SetWithoutChecks<false>( - i, new_annotation_value.value_.GetI()); - break; - case kDexAnnotationLong: - new_array->AsLongArray()->SetWithoutChecks<false>( - i, new_annotation_value.value_.GetJ()); - break; - case kDexAnnotationFloat: - new_array->AsFloatArray()->SetWithoutChecks<false>( - i, new_annotation_value.value_.GetF()); - break; - case kDexAnnotationDouble: - new_array->AsDoubleArray()->SetWithoutChecks<false>( - i, new_annotation_value.value_.GetD()); - break; - case kDexAnnotationBoolean: - new_array->AsBooleanArray()->SetWithoutChecks<false>( - i, new_annotation_value.value_.GetZ()); - break; - default: - LOG(FATAL) << "Found invalid annotation value type while building annotation array"; - return false; - } - } - } - element_object = new_array.Get(); - set_object = true; - width = 0; - } - break; - case kDexAnnotationAnnotation: - if (result_style == kAllRaw) { - return false; - } - element_object = ProcessEncodedAnnotation(klass, &annotation); - if (element_object == nullptr) { - return false; - } - set_object = true; - width = 0; - break; - case kDexAnnotationNull: - if (result_style == kAllRaw) { - annotation_value->value_.SetI(0); - } else { - CHECK(element_object == nullptr); - set_object = true; - } - width = 0; - break; - default: - LOG(ERROR) << StringPrintf("Bad annotation element value type 0x%02x", value_type); - return false; - } - - annotation += width; - *annotation_ptr = annotation; - - if (result_style == kAllObjects && primitive_type != Primitive::kPrimVoid) { - element_object = BoxPrimitive(primitive_type, annotation_value->value_); - set_object = true; - } - - if (set_object) { - annotation_value->value_.SetL(element_object); - } - - return true; -} - -mirror::Object* DexFile::ProcessEncodedAnnotation(Handle<mirror::Class> klass, - const uint8_t** annotation) const { - uint32_t type_index = DecodeUnsignedLeb128(annotation); - uint32_t size = DecodeUnsignedLeb128(annotation); - - Thread* self = Thread::Current(); - ScopedObjectAccessUnchecked soa(self); - StackHandleScope<2> hs(self); - ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); - Handle<mirror::Class> annotation_class(hs.NewHandle( - class_linker->ResolveType(klass->GetDexFile(), type_index, klass.Get()))); - if (annotation_class.Get() == nullptr) { - LOG(INFO) << "Unable to resolve " << PrettyClass(klass.Get()) << " annotation class " - << type_index; - DCHECK(Thread::Current()->IsExceptionPending()); - Thread::Current()->ClearException(); - return nullptr; - } - - mirror::Class* annotation_member_class = - soa.Decode<mirror::Class*>(WellKnownClasses::libcore_reflect_AnnotationMember); - mirror::Class* annotation_member_array_class = - class_linker->FindArrayClass(self, &annotation_member_class); - if (annotation_member_array_class == nullptr) { - return nullptr; - } - mirror::ObjectArray<mirror::Object>* element_array = nullptr; - if (size > 0) { - element_array = - mirror::ObjectArray<mirror::Object>::Alloc(self, annotation_member_array_class, size); - if (element_array == nullptr) { - LOG(ERROR) << "Failed to allocate annotation member array (" << size << " elements)"; - return nullptr; - } - } - - Handle<mirror::ObjectArray<mirror::Object>> h_element_array(hs.NewHandle(element_array)); - for (uint32_t i = 0; i < size; ++i) { - mirror::Object* new_member = CreateAnnotationMember(klass, annotation_class, annotation); - if (new_member == nullptr) { - return nullptr; - } - h_element_array->SetWithoutChecks<false>(i, new_member); - } - - JValue result; - ArtMethod* create_annotation_method = - soa.DecodeMethod(WellKnownClasses::libcore_reflect_AnnotationFactory_createAnnotation); - uint32_t args[2] = { static_cast<uint32_t>(reinterpret_cast<uintptr_t>(annotation_class.Get())), - static_cast<uint32_t>(reinterpret_cast<uintptr_t>(h_element_array.Get())) }; - create_annotation_method->Invoke(self, args, sizeof(args), &result, "LLL"); - if (self->IsExceptionPending()) { - LOG(INFO) << "Exception in AnnotationFactory.createAnnotation"; - return nullptr; - } - - return result.GetL(); -} - -const DexFile::AnnotationItem* DexFile::SearchAnnotationSet(const AnnotationSetItem* annotation_set, - const char* descriptor, uint32_t visibility) const { - const AnnotationItem* result = nullptr; - for (uint32_t i = 0; i < annotation_set->size_; ++i) { - const AnnotationItem* annotation_item = GetAnnotationItem(annotation_set, i); - if (!IsVisibilityCompatible(annotation_item->visibility_, visibility)) { - continue; - } - const uint8_t* annotation = annotation_item->annotation_; - uint32_t type_index = DecodeUnsignedLeb128(&annotation); - - if (strcmp(descriptor, StringByTypeIdx(type_index)) == 0) { - result = annotation_item; - break; - } - } - return result; -} - -const uint8_t* DexFile::SearchEncodedAnnotation(const uint8_t* annotation, const char* name) const { - DecodeUnsignedLeb128(&annotation); // unused type_index - uint32_t size = DecodeUnsignedLeb128(&annotation); - - while (size != 0) { - uint32_t element_name_index = DecodeUnsignedLeb128(&annotation); - const char* element_name = GetStringData(GetStringId(element_name_index)); - if (strcmp(name, element_name) == 0) { - return annotation; - } - SkipAnnotationValue(&annotation); - size--; - } - return nullptr; -} - -bool DexFile::SkipAnnotationValue(const uint8_t** annotation_ptr) const { - const uint8_t* annotation = *annotation_ptr; - uint8_t header_byte = *(annotation++); - uint8_t value_type = header_byte & kDexAnnotationValueTypeMask; - uint8_t value_arg = header_byte >> kDexAnnotationValueArgShift; - int32_t width = value_arg + 1; - - switch (value_type) { - case kDexAnnotationByte: - case kDexAnnotationShort: - case kDexAnnotationChar: - case kDexAnnotationInt: - case kDexAnnotationLong: - case kDexAnnotationFloat: - case kDexAnnotationDouble: - case kDexAnnotationString: - case kDexAnnotationType: - case kDexAnnotationMethod: - case kDexAnnotationField: - case kDexAnnotationEnum: - break; - case kDexAnnotationArray: - { - uint32_t size = DecodeUnsignedLeb128(&annotation); - while (size--) { - if (!SkipAnnotationValue(&annotation)) { - return false; - } - } - width = 0; - break; - } - case kDexAnnotationAnnotation: - { - DecodeUnsignedLeb128(&annotation); // unused type_index - uint32_t size = DecodeUnsignedLeb128(&annotation); - while (size--) { - DecodeUnsignedLeb128(&annotation); // unused element_name_index - if (!SkipAnnotationValue(&annotation)) { - return false; - } - } - width = 0; - break; - } - case kDexAnnotationBoolean: - case kDexAnnotationNull: - width = 0; - break; - default: - LOG(FATAL) << StringPrintf("Bad annotation element value byte 0x%02x", value_type); - return false; - } - - annotation += width; - *annotation_ptr = annotation; - return true; -} - std::ostream& operator<<(std::ostream& os, const DexFile& dex_file) { os << StringPrintf("[DexFile: %s dex-checksum=%08x location-checksum=%08x %p-%p]", dex_file.GetLocation().c_str(), @@ -2460,50 +1258,13 @@ void ClassDataItemIterator::ReadClassDataMethod() { } } -EncodedStaticFieldValueIterator::EncodedStaticFieldValueIterator( - const DexFile& dex_file, - const DexFile::ClassDef& class_def) - : EncodedStaticFieldValueIterator(dex_file, - nullptr, - nullptr, - nullptr, - class_def, - -1, - kByte) { -} - -EncodedStaticFieldValueIterator::EncodedStaticFieldValueIterator( - const DexFile& dex_file, - Handle<mirror::DexCache>* dex_cache, - Handle<mirror::ClassLoader>* class_loader, - ClassLinker* linker, - const DexFile::ClassDef& class_def) - : EncodedStaticFieldValueIterator(dex_file, - dex_cache, class_loader, - linker, - class_def, - -1, - kByte) { - DCHECK(dex_cache_ != nullptr); - DCHECK(class_loader_ != nullptr); -} - -EncodedStaticFieldValueIterator::EncodedStaticFieldValueIterator( - const DexFile& dex_file, - Handle<mirror::DexCache>* dex_cache, - Handle<mirror::ClassLoader>* class_loader, - ClassLinker* linker, - const DexFile::ClassDef& class_def, - size_t pos, - ValueType type) +EncodedStaticFieldValueIterator::EncodedStaticFieldValueIterator(const DexFile& dex_file, + const DexFile::ClassDef& class_def) : dex_file_(dex_file), - dex_cache_(dex_cache), - class_loader_(class_loader), - linker_(linker), array_size_(), - pos_(pos), - type_(type) { - ptr_ = dex_file.GetEncodedStaticFieldValuesArray(class_def); + pos_(-1), + type_(kByte) { + ptr_ = dex_file_.GetEncodedStaticFieldValuesArray(class_def); if (ptr_ == nullptr) { array_size_ = 0; } else { @@ -2529,32 +1290,32 @@ void EncodedStaticFieldValueIterator::Next() { width = 0; break; case kByte: - jval_.i = ReadSignedInt(ptr_, value_arg); + jval_.i = DexFile::ReadSignedInt(ptr_, value_arg); CHECK(IsInt<8>(jval_.i)); break; case kShort: - jval_.i = ReadSignedInt(ptr_, value_arg); + jval_.i = DexFile::ReadSignedInt(ptr_, value_arg); CHECK(IsInt<16>(jval_.i)); break; case kChar: - jval_.i = ReadUnsignedInt(ptr_, value_arg, false); + jval_.i = DexFile::ReadUnsignedInt(ptr_, value_arg, false); CHECK(IsUint<16>(jval_.i)); break; case kInt: - jval_.i = ReadSignedInt(ptr_, value_arg); + jval_.i = DexFile::ReadSignedInt(ptr_, value_arg); break; case kLong: - jval_.j = ReadSignedLong(ptr_, value_arg); + jval_.j = DexFile::ReadSignedLong(ptr_, value_arg); break; case kFloat: - jval_.i = ReadUnsignedInt(ptr_, value_arg, true); + jval_.i = DexFile::ReadUnsignedInt(ptr_, value_arg, true); break; case kDouble: - jval_.j = ReadUnsignedLong(ptr_, value_arg, true); + jval_.j = DexFile::ReadUnsignedLong(ptr_, value_arg, true); break; case kString: case kType: - jval_.i = ReadUnsignedInt(ptr_, value_arg, false); + jval_.i = DexFile::ReadUnsignedInt(ptr_, value_arg, false); break; case kField: case kMethod: @@ -2574,38 +1335,6 @@ void EncodedStaticFieldValueIterator::Next() { ptr_ += width; } -template<bool kTransactionActive> -void EncodedStaticFieldValueIterator::ReadValueToField(ArtField* field) const { - DCHECK(dex_cache_ != nullptr); - DCHECK(class_loader_ != nullptr); - switch (type_) { - case kBoolean: field->SetBoolean<kTransactionActive>(field->GetDeclaringClass(), jval_.z); - break; - case kByte: field->SetByte<kTransactionActive>(field->GetDeclaringClass(), jval_.b); break; - case kShort: field->SetShort<kTransactionActive>(field->GetDeclaringClass(), jval_.s); break; - case kChar: field->SetChar<kTransactionActive>(field->GetDeclaringClass(), jval_.c); break; - case kInt: field->SetInt<kTransactionActive>(field->GetDeclaringClass(), jval_.i); break; - case kLong: field->SetLong<kTransactionActive>(field->GetDeclaringClass(), jval_.j); break; - case kFloat: field->SetFloat<kTransactionActive>(field->GetDeclaringClass(), jval_.f); break; - case kDouble: field->SetDouble<kTransactionActive>(field->GetDeclaringClass(), jval_.d); break; - case kNull: field->SetObject<kTransactionActive>(field->GetDeclaringClass(), nullptr); break; - case kString: { - mirror::String* resolved = linker_->ResolveString(dex_file_, jval_.i, *dex_cache_); - field->SetObject<kTransactionActive>(field->GetDeclaringClass(), resolved); - break; - } - case kType: { - mirror::Class* resolved = linker_->ResolveType(dex_file_, jval_.i, *dex_cache_, - *class_loader_); - field->SetObject<kTransactionActive>(field->GetDeclaringClass(), resolved); - break; - } - default: UNIMPLEMENTED(FATAL) << ": type " << type_; - } -} -template void EncodedStaticFieldValueIterator::ReadValueToField<true>(ArtField* field) const; -template void EncodedStaticFieldValueIterator::ReadValueToField<false>(ArtField* field) const; - CatchHandlerIterator::CatchHandlerIterator(const DexFile::CodeItem& code_item, uint32_t address) { handler_.address_ = -1; int32_t offset = -1; |