1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2016 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 #include "dex_file_annotations.h"
18*795d594fSAndroid Build Coastguard Worker
19*795d594fSAndroid Build Coastguard Worker #include <stdlib.h>
20*795d594fSAndroid Build Coastguard Worker
21*795d594fSAndroid Build Coastguard Worker #include "android-base/macros.h"
22*795d594fSAndroid Build Coastguard Worker #include "android-base/stringprintf.h"
23*795d594fSAndroid Build Coastguard Worker #include "art_field-inl.h"
24*795d594fSAndroid Build Coastguard Worker #include "art_method-alloc-inl.h"
25*795d594fSAndroid Build Coastguard Worker #include "base/sdk_version.h"
26*795d594fSAndroid Build Coastguard Worker #include "class_linker-inl.h"
27*795d594fSAndroid Build Coastguard Worker #include "class_root-inl.h"
28*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file-inl.h"
29*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file_types.h"
30*795d594fSAndroid Build Coastguard Worker #include "dex/dex_instruction-inl.h"
31*795d594fSAndroid Build Coastguard Worker #include "jni/jni_internal.h"
32*795d594fSAndroid Build Coastguard Worker #include "jvalue-inl.h"
33*795d594fSAndroid Build Coastguard Worker #include "mirror/array-alloc-inl.h"
34*795d594fSAndroid Build Coastguard Worker #include "mirror/class-alloc-inl.h"
35*795d594fSAndroid Build Coastguard Worker #include "mirror/field.h"
36*795d594fSAndroid Build Coastguard Worker #include "mirror/method.h"
37*795d594fSAndroid Build Coastguard Worker #include "mirror/object_array-alloc-inl.h"
38*795d594fSAndroid Build Coastguard Worker #include "mirror/object_array-inl.h"
39*795d594fSAndroid Build Coastguard Worker #include "oat/oat_file.h"
40*795d594fSAndroid Build Coastguard Worker #include "obj_ptr-inl.h"
41*795d594fSAndroid Build Coastguard Worker #include "reflection.h"
42*795d594fSAndroid Build Coastguard Worker #include "thread.h"
43*795d594fSAndroid Build Coastguard Worker #include "well_known_classes.h"
44*795d594fSAndroid Build Coastguard Worker
45*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
46*795d594fSAndroid Build Coastguard Worker
47*795d594fSAndroid Build Coastguard Worker using android::base::StringPrintf;
48*795d594fSAndroid Build Coastguard Worker
49*795d594fSAndroid Build Coastguard Worker using dex::AnnotationItem;
50*795d594fSAndroid Build Coastguard Worker using dex::AnnotationSetItem;
51*795d594fSAndroid Build Coastguard Worker using dex::AnnotationSetRefItem;
52*795d594fSAndroid Build Coastguard Worker using dex::AnnotationSetRefList;
53*795d594fSAndroid Build Coastguard Worker using dex::AnnotationsDirectoryItem;
54*795d594fSAndroid Build Coastguard Worker using dex::FieldAnnotationsItem;
55*795d594fSAndroid Build Coastguard Worker using dex::MethodAnnotationsItem;
56*795d594fSAndroid Build Coastguard Worker using dex::ParameterAnnotationsItem;
57*795d594fSAndroid Build Coastguard Worker
58*795d594fSAndroid Build Coastguard Worker struct DexFile::AnnotationValue {
59*795d594fSAndroid Build Coastguard Worker JValue value_;
60*795d594fSAndroid Build Coastguard Worker uint8_t type_;
61*795d594fSAndroid Build Coastguard Worker };
62*795d594fSAndroid Build Coastguard Worker
63*795d594fSAndroid Build Coastguard Worker namespace {
64*795d594fSAndroid Build Coastguard Worker
65*795d594fSAndroid Build Coastguard Worker // A helper class that contains all the data needed to do annotation lookup.
66*795d594fSAndroid Build Coastguard Worker class ClassData {
67*795d594fSAndroid Build Coastguard Worker public:
REQUIRES_SHARED(Locks::mutator_lock_)68*795d594fSAndroid Build Coastguard Worker explicit ClassData(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_)
69*795d594fSAndroid Build Coastguard Worker : ClassData(ScopedNullHandle<mirror::Class>(), // klass
70*795d594fSAndroid Build Coastguard Worker method,
71*795d594fSAndroid Build Coastguard Worker *method->GetDexFile(),
72*795d594fSAndroid Build Coastguard Worker &method->GetClassDef()) {}
73*795d594fSAndroid Build Coastguard Worker
74*795d594fSAndroid Build Coastguard Worker // Requires Scope to be able to create at least 1 handles.
75*795d594fSAndroid Build Coastguard Worker template <typename Scope>
ClassData(Scope & hs,ArtField * field)76*795d594fSAndroid Build Coastguard Worker ClassData(Scope& hs, ArtField* field) REQUIRES_SHARED(Locks::mutator_lock_)
77*795d594fSAndroid Build Coastguard Worker : ClassData(hs.NewHandle(field->GetDeclaringClass())) { }
78*795d594fSAndroid Build Coastguard Worker
REQUIRES_SHARED(art::Locks::mutator_lock_)79*795d594fSAndroid Build Coastguard Worker explicit ClassData(Handle<mirror::Class> klass) REQUIRES_SHARED(art::Locks::mutator_lock_)
80*795d594fSAndroid Build Coastguard Worker : ClassData(klass, // klass
81*795d594fSAndroid Build Coastguard Worker nullptr, // method
82*795d594fSAndroid Build Coastguard Worker klass->GetDexFile(),
83*795d594fSAndroid Build Coastguard Worker klass->GetClassDef()) {}
84*795d594fSAndroid Build Coastguard Worker
GetDexFile() const85*795d594fSAndroid Build Coastguard Worker const DexFile& GetDexFile() const REQUIRES_SHARED(Locks::mutator_lock_) {
86*795d594fSAndroid Build Coastguard Worker return dex_file_;
87*795d594fSAndroid Build Coastguard Worker }
88*795d594fSAndroid Build Coastguard Worker
GetClassDef() const89*795d594fSAndroid Build Coastguard Worker const dex::ClassDef* GetClassDef() const REQUIRES_SHARED(Locks::mutator_lock_) {
90*795d594fSAndroid Build Coastguard Worker return class_def_;
91*795d594fSAndroid Build Coastguard Worker }
92*795d594fSAndroid Build Coastguard Worker
GetDexCache() const93*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::DexCache> GetDexCache() const REQUIRES_SHARED(Locks::mutator_lock_) {
94*795d594fSAndroid Build Coastguard Worker if (method_ != nullptr) {
95*795d594fSAndroid Build Coastguard Worker return method_->GetDexCache();
96*795d594fSAndroid Build Coastguard Worker } else {
97*795d594fSAndroid Build Coastguard Worker return real_klass_->GetDexCache();
98*795d594fSAndroid Build Coastguard Worker }
99*795d594fSAndroid Build Coastguard Worker }
100*795d594fSAndroid Build Coastguard Worker
GetClassLoader() const101*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ClassLoader> GetClassLoader() const REQUIRES_SHARED(Locks::mutator_lock_) {
102*795d594fSAndroid Build Coastguard Worker if (method_ != nullptr) {
103*795d594fSAndroid Build Coastguard Worker return method_->GetDeclaringClass()->GetClassLoader();
104*795d594fSAndroid Build Coastguard Worker } else {
105*795d594fSAndroid Build Coastguard Worker return real_klass_->GetClassLoader();
106*795d594fSAndroid Build Coastguard Worker }
107*795d594fSAndroid Build Coastguard Worker }
108*795d594fSAndroid Build Coastguard Worker
GetRealClass() const109*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> GetRealClass() const REQUIRES_SHARED(Locks::mutator_lock_) {
110*795d594fSAndroid Build Coastguard Worker if (method_ != nullptr) {
111*795d594fSAndroid Build Coastguard Worker return method_->GetDeclaringClass();
112*795d594fSAndroid Build Coastguard Worker } else {
113*795d594fSAndroid Build Coastguard Worker return real_klass_.Get();
114*795d594fSAndroid Build Coastguard Worker }
115*795d594fSAndroid Build Coastguard Worker }
116*795d594fSAndroid Build Coastguard Worker
117*795d594fSAndroid Build Coastguard Worker private:
ClassData(Handle<mirror::Class> klass,ArtMethod * method,const DexFile & dex_file,const dex::ClassDef * class_def)118*795d594fSAndroid Build Coastguard Worker ClassData(Handle<mirror::Class> klass,
119*795d594fSAndroid Build Coastguard Worker ArtMethod* method,
120*795d594fSAndroid Build Coastguard Worker const DexFile& dex_file,
121*795d594fSAndroid Build Coastguard Worker const dex::ClassDef* class_def) REQUIRES_SHARED(Locks::mutator_lock_)
122*795d594fSAndroid Build Coastguard Worker : real_klass_(klass),
123*795d594fSAndroid Build Coastguard Worker method_(method),
124*795d594fSAndroid Build Coastguard Worker dex_file_(dex_file),
125*795d594fSAndroid Build Coastguard Worker class_def_(class_def) {
126*795d594fSAndroid Build Coastguard Worker DCHECK((method_ == nullptr) || real_klass_.IsNull());
127*795d594fSAndroid Build Coastguard Worker }
128*795d594fSAndroid Build Coastguard Worker
129*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> real_klass_;
130*795d594fSAndroid Build Coastguard Worker ArtMethod* method_;
131*795d594fSAndroid Build Coastguard Worker const DexFile& dex_file_;
132*795d594fSAndroid Build Coastguard Worker const dex::ClassDef* class_def_;
133*795d594fSAndroid Build Coastguard Worker
134*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(ClassData);
135*795d594fSAndroid Build Coastguard Worker };
136*795d594fSAndroid Build Coastguard Worker
137*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> CreateAnnotationMember(const ClassData& klass,
138*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> annotation_class,
139*795d594fSAndroid Build Coastguard Worker const uint8_t** annotation)
140*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_);
141*795d594fSAndroid Build Coastguard Worker
IsVisibilityCompatible(uint32_t actual,uint32_t expected)142*795d594fSAndroid Build Coastguard Worker bool IsVisibilityCompatible(uint32_t actual, uint32_t expected) {
143*795d594fSAndroid Build Coastguard Worker if (expected == DexFile::kDexVisibilityRuntime) {
144*795d594fSAndroid Build Coastguard Worker if (IsSdkVersionSetAndAtMost(Runtime::Current()->GetTargetSdkVersion(), SdkVersion::kM)) {
145*795d594fSAndroid Build Coastguard Worker return actual == DexFile::kDexVisibilityRuntime || actual == DexFile::kDexVisibilityBuild;
146*795d594fSAndroid Build Coastguard Worker }
147*795d594fSAndroid Build Coastguard Worker }
148*795d594fSAndroid Build Coastguard Worker return actual == expected;
149*795d594fSAndroid Build Coastguard Worker }
150*795d594fSAndroid Build Coastguard Worker
FindAnnotationSetForField(const DexFile & dex_file,const dex::ClassDef & class_def,uint32_t field_index)151*795d594fSAndroid Build Coastguard Worker static const AnnotationSetItem* FindAnnotationSetForField(const DexFile& dex_file,
152*795d594fSAndroid Build Coastguard Worker const dex::ClassDef& class_def,
153*795d594fSAndroid Build Coastguard Worker uint32_t field_index)
154*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
155*795d594fSAndroid Build Coastguard Worker const AnnotationsDirectoryItem* annotations_dir = dex_file.GetAnnotationsDirectory(class_def);
156*795d594fSAndroid Build Coastguard Worker if (annotations_dir == nullptr) {
157*795d594fSAndroid Build Coastguard Worker return nullptr;
158*795d594fSAndroid Build Coastguard Worker }
159*795d594fSAndroid Build Coastguard Worker const FieldAnnotationsItem* field_annotations = dex_file.GetFieldAnnotations(annotations_dir);
160*795d594fSAndroid Build Coastguard Worker if (field_annotations == nullptr) {
161*795d594fSAndroid Build Coastguard Worker return nullptr;
162*795d594fSAndroid Build Coastguard Worker }
163*795d594fSAndroid Build Coastguard Worker uint32_t field_count = annotations_dir->fields_size_;
164*795d594fSAndroid Build Coastguard Worker for (uint32_t i = 0; i < field_count; ++i) {
165*795d594fSAndroid Build Coastguard Worker if (field_annotations[i].field_idx_ == field_index) {
166*795d594fSAndroid Build Coastguard Worker return dex_file.GetFieldAnnotationSetItem(field_annotations[i]);
167*795d594fSAndroid Build Coastguard Worker }
168*795d594fSAndroid Build Coastguard Worker }
169*795d594fSAndroid Build Coastguard Worker return nullptr;
170*795d594fSAndroid Build Coastguard Worker }
171*795d594fSAndroid Build Coastguard Worker
FindAnnotationSetForField(ArtField * field)172*795d594fSAndroid Build Coastguard Worker static const AnnotationSetItem* FindAnnotationSetForField(ArtField* field)
173*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
174*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> klass = field->GetDeclaringClass();
175*795d594fSAndroid Build Coastguard Worker const dex::ClassDef* class_def = klass->GetClassDef();
176*795d594fSAndroid Build Coastguard Worker if (class_def == nullptr) {
177*795d594fSAndroid Build Coastguard Worker DCHECK(klass->IsProxyClass());
178*795d594fSAndroid Build Coastguard Worker return nullptr;
179*795d594fSAndroid Build Coastguard Worker }
180*795d594fSAndroid Build Coastguard Worker return FindAnnotationSetForField(*field->GetDexFile(), *class_def, field->GetDexFieldIndex());
181*795d594fSAndroid Build Coastguard Worker }
182*795d594fSAndroid Build Coastguard Worker
SearchAnnotationSet(const DexFile & dex_file,const AnnotationSetItem * annotation_set,const char * descriptor,uint32_t visibility)183*795d594fSAndroid Build Coastguard Worker const AnnotationItem* SearchAnnotationSet(const DexFile& dex_file,
184*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set,
185*795d594fSAndroid Build Coastguard Worker const char* descriptor,
186*795d594fSAndroid Build Coastguard Worker uint32_t visibility)
187*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
188*795d594fSAndroid Build Coastguard Worker const AnnotationItem* result = nullptr;
189*795d594fSAndroid Build Coastguard Worker for (uint32_t i = 0; i < annotation_set->size_; ++i) {
190*795d594fSAndroid Build Coastguard Worker const AnnotationItem* annotation_item = dex_file.GetAnnotationItem(annotation_set, i);
191*795d594fSAndroid Build Coastguard Worker if (!IsVisibilityCompatible(annotation_item->visibility_, visibility)) {
192*795d594fSAndroid Build Coastguard Worker continue;
193*795d594fSAndroid Build Coastguard Worker }
194*795d594fSAndroid Build Coastguard Worker const uint8_t* annotation = annotation_item->annotation_;
195*795d594fSAndroid Build Coastguard Worker uint32_t type_index = DecodeUnsignedLeb128(&annotation);
196*795d594fSAndroid Build Coastguard Worker
197*795d594fSAndroid Build Coastguard Worker if (strcmp(descriptor, dex_file.GetTypeDescriptor(dex::TypeIndex(type_index))) == 0) {
198*795d594fSAndroid Build Coastguard Worker result = annotation_item;
199*795d594fSAndroid Build Coastguard Worker break;
200*795d594fSAndroid Build Coastguard Worker }
201*795d594fSAndroid Build Coastguard Worker }
202*795d594fSAndroid Build Coastguard Worker return result;
203*795d594fSAndroid Build Coastguard Worker }
204*795d594fSAndroid Build Coastguard Worker
SkipEncodedValueHeaderByte(const uint8_t ** annotation_ptr)205*795d594fSAndroid Build Coastguard Worker inline static void SkipEncodedValueHeaderByte(const uint8_t** annotation_ptr) {
206*795d594fSAndroid Build Coastguard Worker (*annotation_ptr)++;
207*795d594fSAndroid Build Coastguard Worker }
208*795d594fSAndroid Build Coastguard Worker
SkipAnnotationValue(const DexFile & dex_file,const uint8_t ** annotation_ptr)209*795d594fSAndroid Build Coastguard Worker bool SkipAnnotationValue(const DexFile& dex_file, const uint8_t** annotation_ptr)
210*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
211*795d594fSAndroid Build Coastguard Worker const uint8_t* annotation = *annotation_ptr;
212*795d594fSAndroid Build Coastguard Worker uint8_t header_byte = *(annotation++);
213*795d594fSAndroid Build Coastguard Worker uint8_t value_type = header_byte & DexFile::kDexAnnotationValueTypeMask;
214*795d594fSAndroid Build Coastguard Worker uint8_t value_arg = header_byte >> DexFile::kDexAnnotationValueArgShift;
215*795d594fSAndroid Build Coastguard Worker int32_t width = value_arg + 1;
216*795d594fSAndroid Build Coastguard Worker
217*795d594fSAndroid Build Coastguard Worker switch (value_type) {
218*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationByte:
219*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationShort:
220*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationChar:
221*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationInt:
222*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationLong:
223*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationFloat:
224*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationDouble:
225*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationMethodType:
226*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationMethodHandle:
227*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationString:
228*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationType:
229*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationMethod:
230*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationField:
231*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationEnum:
232*795d594fSAndroid Build Coastguard Worker break;
233*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationArray:
234*795d594fSAndroid Build Coastguard Worker {
235*795d594fSAndroid Build Coastguard Worker uint32_t size = DecodeUnsignedLeb128(&annotation);
236*795d594fSAndroid Build Coastguard Worker for (; size != 0u; --size) {
237*795d594fSAndroid Build Coastguard Worker if (!SkipAnnotationValue(dex_file, &annotation)) {
238*795d594fSAndroid Build Coastguard Worker return false;
239*795d594fSAndroid Build Coastguard Worker }
240*795d594fSAndroid Build Coastguard Worker }
241*795d594fSAndroid Build Coastguard Worker width = 0;
242*795d594fSAndroid Build Coastguard Worker break;
243*795d594fSAndroid Build Coastguard Worker }
244*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationAnnotation:
245*795d594fSAndroid Build Coastguard Worker {
246*795d594fSAndroid Build Coastguard Worker DecodeUnsignedLeb128(&annotation); // unused type_index
247*795d594fSAndroid Build Coastguard Worker uint32_t size = DecodeUnsignedLeb128(&annotation);
248*795d594fSAndroid Build Coastguard Worker for (; size != 0u; --size) {
249*795d594fSAndroid Build Coastguard Worker DecodeUnsignedLeb128(&annotation); // unused element_name_index
250*795d594fSAndroid Build Coastguard Worker if (!SkipAnnotationValue(dex_file, &annotation)) {
251*795d594fSAndroid Build Coastguard Worker return false;
252*795d594fSAndroid Build Coastguard Worker }
253*795d594fSAndroid Build Coastguard Worker }
254*795d594fSAndroid Build Coastguard Worker width = 0;
255*795d594fSAndroid Build Coastguard Worker break;
256*795d594fSAndroid Build Coastguard Worker }
257*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationBoolean:
258*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationNull:
259*795d594fSAndroid Build Coastguard Worker width = 0;
260*795d594fSAndroid Build Coastguard Worker break;
261*795d594fSAndroid Build Coastguard Worker default:
262*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << StringPrintf("Bad annotation element value byte 0x%02x", value_type);
263*795d594fSAndroid Build Coastguard Worker UNREACHABLE();
264*795d594fSAndroid Build Coastguard Worker }
265*795d594fSAndroid Build Coastguard Worker
266*795d594fSAndroid Build Coastguard Worker annotation += width;
267*795d594fSAndroid Build Coastguard Worker *annotation_ptr = annotation;
268*795d594fSAndroid Build Coastguard Worker return true;
269*795d594fSAndroid Build Coastguard Worker }
270*795d594fSAndroid Build Coastguard Worker
SearchEncodedAnnotation(const DexFile & dex_file,const uint8_t * annotation,const char * name)271*795d594fSAndroid Build Coastguard Worker const uint8_t* SearchEncodedAnnotation(const DexFile& dex_file,
272*795d594fSAndroid Build Coastguard Worker const uint8_t* annotation,
273*795d594fSAndroid Build Coastguard Worker const char* name)
274*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
275*795d594fSAndroid Build Coastguard Worker DecodeUnsignedLeb128(&annotation); // unused type_index
276*795d594fSAndroid Build Coastguard Worker uint32_t size = DecodeUnsignedLeb128(&annotation);
277*795d594fSAndroid Build Coastguard Worker
278*795d594fSAndroid Build Coastguard Worker while (size != 0) {
279*795d594fSAndroid Build Coastguard Worker uint32_t element_name_index = DecodeUnsignedLeb128(&annotation);
280*795d594fSAndroid Build Coastguard Worker const char* element_name =
281*795d594fSAndroid Build Coastguard Worker dex_file.GetStringData(dex_file.GetStringId(dex::StringIndex(element_name_index)));
282*795d594fSAndroid Build Coastguard Worker if (strcmp(name, element_name) == 0) {
283*795d594fSAndroid Build Coastguard Worker return annotation;
284*795d594fSAndroid Build Coastguard Worker }
285*795d594fSAndroid Build Coastguard Worker SkipAnnotationValue(dex_file, &annotation);
286*795d594fSAndroid Build Coastguard Worker size--;
287*795d594fSAndroid Build Coastguard Worker }
288*795d594fSAndroid Build Coastguard Worker return nullptr;
289*795d594fSAndroid Build Coastguard Worker }
290*795d594fSAndroid Build Coastguard Worker
FindAnnotationSetForMethod(const DexFile & dex_file,const dex::ClassDef & class_def,uint32_t method_index)291*795d594fSAndroid Build Coastguard Worker static const AnnotationSetItem* FindAnnotationSetForMethod(const DexFile& dex_file,
292*795d594fSAndroid Build Coastguard Worker const dex::ClassDef& class_def,
293*795d594fSAndroid Build Coastguard Worker uint32_t method_index) {
294*795d594fSAndroid Build Coastguard Worker const AnnotationsDirectoryItem* annotations_dir = dex_file.GetAnnotationsDirectory(class_def);
295*795d594fSAndroid Build Coastguard Worker if (annotations_dir == nullptr) {
296*795d594fSAndroid Build Coastguard Worker return nullptr;
297*795d594fSAndroid Build Coastguard Worker }
298*795d594fSAndroid Build Coastguard Worker const MethodAnnotationsItem* method_annotations = dex_file.GetMethodAnnotations(annotations_dir);
299*795d594fSAndroid Build Coastguard Worker if (method_annotations == nullptr) {
300*795d594fSAndroid Build Coastguard Worker return nullptr;
301*795d594fSAndroid Build Coastguard Worker }
302*795d594fSAndroid Build Coastguard Worker uint32_t method_count = annotations_dir->methods_size_;
303*795d594fSAndroid Build Coastguard Worker for (uint32_t i = 0; i < method_count; ++i) {
304*795d594fSAndroid Build Coastguard Worker if (method_annotations[i].method_idx_ == method_index) {
305*795d594fSAndroid Build Coastguard Worker return dex_file.GetMethodAnnotationSetItem(method_annotations[i]);
306*795d594fSAndroid Build Coastguard Worker }
307*795d594fSAndroid Build Coastguard Worker }
308*795d594fSAndroid Build Coastguard Worker return nullptr;
309*795d594fSAndroid Build Coastguard Worker }
310*795d594fSAndroid Build Coastguard Worker
FindAnnotationSetForMethod(ArtMethod * method)311*795d594fSAndroid Build Coastguard Worker inline const AnnotationSetItem* FindAnnotationSetForMethod(ArtMethod* method)
312*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
313*795d594fSAndroid Build Coastguard Worker if (method->IsProxyMethod()) {
314*795d594fSAndroid Build Coastguard Worker return nullptr;
315*795d594fSAndroid Build Coastguard Worker }
316*795d594fSAndroid Build Coastguard Worker return FindAnnotationSetForMethod(*method->GetDexFile(),
317*795d594fSAndroid Build Coastguard Worker method->GetClassDef(),
318*795d594fSAndroid Build Coastguard Worker method->GetDexMethodIndex());
319*795d594fSAndroid Build Coastguard Worker }
320*795d594fSAndroid Build Coastguard Worker
FindAnnotationsItemForMethod(ArtMethod * method)321*795d594fSAndroid Build Coastguard Worker const ParameterAnnotationsItem* FindAnnotationsItemForMethod(ArtMethod* method)
322*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
323*795d594fSAndroid Build Coastguard Worker const DexFile* dex_file = method->GetDexFile();
324*795d594fSAndroid Build Coastguard Worker const AnnotationsDirectoryItem* annotations_dir =
325*795d594fSAndroid Build Coastguard Worker dex_file->GetAnnotationsDirectory(method->GetClassDef());
326*795d594fSAndroid Build Coastguard Worker if (annotations_dir == nullptr) {
327*795d594fSAndroid Build Coastguard Worker return nullptr;
328*795d594fSAndroid Build Coastguard Worker }
329*795d594fSAndroid Build Coastguard Worker const ParameterAnnotationsItem* parameter_annotations =
330*795d594fSAndroid Build Coastguard Worker dex_file->GetParameterAnnotations(annotations_dir);
331*795d594fSAndroid Build Coastguard Worker if (parameter_annotations == nullptr) {
332*795d594fSAndroid Build Coastguard Worker return nullptr;
333*795d594fSAndroid Build Coastguard Worker }
334*795d594fSAndroid Build Coastguard Worker uint32_t method_index = method->GetDexMethodIndex();
335*795d594fSAndroid Build Coastguard Worker uint32_t parameter_count = annotations_dir->parameters_size_;
336*795d594fSAndroid Build Coastguard Worker for (uint32_t i = 0; i < parameter_count; ++i) {
337*795d594fSAndroid Build Coastguard Worker if (parameter_annotations[i].method_idx_ == method_index) {
338*795d594fSAndroid Build Coastguard Worker return ¶meter_annotations[i];
339*795d594fSAndroid Build Coastguard Worker }
340*795d594fSAndroid Build Coastguard Worker }
341*795d594fSAndroid Build Coastguard Worker return nullptr;
342*795d594fSAndroid Build Coastguard Worker }
343*795d594fSAndroid Build Coastguard Worker
FindAnnotationSetForClass(const ClassData & klass)344*795d594fSAndroid Build Coastguard Worker static const AnnotationSetItem* FindAnnotationSetForClass(const ClassData& klass)
345*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
346*795d594fSAndroid Build Coastguard Worker const DexFile& dex_file = klass.GetDexFile();
347*795d594fSAndroid Build Coastguard Worker const dex::ClassDef* class_def = klass.GetClassDef();
348*795d594fSAndroid Build Coastguard Worker if (class_def == nullptr) {
349*795d594fSAndroid Build Coastguard Worker DCHECK(klass.GetRealClass()->IsProxyClass());
350*795d594fSAndroid Build Coastguard Worker return nullptr;
351*795d594fSAndroid Build Coastguard Worker }
352*795d594fSAndroid Build Coastguard Worker const AnnotationsDirectoryItem* annotations_dir = dex_file.GetAnnotationsDirectory(*class_def);
353*795d594fSAndroid Build Coastguard Worker if (annotations_dir == nullptr) {
354*795d594fSAndroid Build Coastguard Worker return nullptr;
355*795d594fSAndroid Build Coastguard Worker }
356*795d594fSAndroid Build Coastguard Worker return dex_file.GetClassAnnotationSet(annotations_dir);
357*795d594fSAndroid Build Coastguard Worker }
358*795d594fSAndroid Build Coastguard Worker
ProcessEncodedAnnotation(const ClassData & klass,const uint8_t ** annotation)359*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> ProcessEncodedAnnotation(const ClassData& klass, const uint8_t** annotation)
360*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
361*795d594fSAndroid Build Coastguard Worker uint32_t type_index = DecodeUnsignedLeb128(annotation);
362*795d594fSAndroid Build Coastguard Worker uint32_t size = DecodeUnsignedLeb128(annotation);
363*795d594fSAndroid Build Coastguard Worker
364*795d594fSAndroid Build Coastguard Worker Thread* self = Thread::Current();
365*795d594fSAndroid Build Coastguard Worker StackHandleScope<4> hs(self);
366*795d594fSAndroid Build Coastguard Worker ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
367*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> annotation_class(hs.NewHandle(
368*795d594fSAndroid Build Coastguard Worker class_linker->ResolveType(dex::TypeIndex(type_index),
369*795d594fSAndroid Build Coastguard Worker hs.NewHandle(klass.GetDexCache()),
370*795d594fSAndroid Build Coastguard Worker hs.NewHandle(klass.GetClassLoader()))));
371*795d594fSAndroid Build Coastguard Worker if (annotation_class == nullptr) {
372*795d594fSAndroid Build Coastguard Worker LOG(INFO) << "Unable to resolve " << klass.GetRealClass()->PrettyClass()
373*795d594fSAndroid Build Coastguard Worker << " annotation class " << type_index;
374*795d594fSAndroid Build Coastguard Worker DCHECK(Thread::Current()->IsExceptionPending());
375*795d594fSAndroid Build Coastguard Worker Thread::Current()->ClearException();
376*795d594fSAndroid Build Coastguard Worker return nullptr;
377*795d594fSAndroid Build Coastguard Worker }
378*795d594fSAndroid Build Coastguard Worker
379*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> annotation_member_array_class =
380*795d594fSAndroid Build Coastguard Worker WellKnownClasses::ToClass(WellKnownClasses::libcore_reflect_AnnotationMember__array);
381*795d594fSAndroid Build Coastguard Worker if (annotation_member_array_class == nullptr) {
382*795d594fSAndroid Build Coastguard Worker return nullptr;
383*795d594fSAndroid Build Coastguard Worker }
384*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Object>> element_array = nullptr;
385*795d594fSAndroid Build Coastguard Worker if (size > 0) {
386*795d594fSAndroid Build Coastguard Worker element_array =
387*795d594fSAndroid Build Coastguard Worker mirror::ObjectArray<mirror::Object>::Alloc(self, annotation_member_array_class, size);
388*795d594fSAndroid Build Coastguard Worker if (element_array == nullptr) {
389*795d594fSAndroid Build Coastguard Worker LOG(ERROR) << "Failed to allocate annotation member array (" << size << " elements)";
390*795d594fSAndroid Build Coastguard Worker return nullptr;
391*795d594fSAndroid Build Coastguard Worker }
392*795d594fSAndroid Build Coastguard Worker }
393*795d594fSAndroid Build Coastguard Worker
394*795d594fSAndroid Build Coastguard Worker Handle<mirror::ObjectArray<mirror::Object>> h_element_array(hs.NewHandle(element_array));
395*795d594fSAndroid Build Coastguard Worker for (uint32_t i = 0; i < size; ++i) {
396*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> new_member = CreateAnnotationMember(klass, annotation_class, annotation);
397*795d594fSAndroid Build Coastguard Worker if (new_member == nullptr) {
398*795d594fSAndroid Build Coastguard Worker return nullptr;
399*795d594fSAndroid Build Coastguard Worker }
400*795d594fSAndroid Build Coastguard Worker h_element_array->SetWithoutChecks<false>(i, new_member);
401*795d594fSAndroid Build Coastguard Worker }
402*795d594fSAndroid Build Coastguard Worker
403*795d594fSAndroid Build Coastguard Worker ArtMethod* create_annotation_method =
404*795d594fSAndroid Build Coastguard Worker WellKnownClasses::libcore_reflect_AnnotationFactory_createAnnotation;
405*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> result = create_annotation_method->InvokeStatic<'L', 'L', 'L'>(
406*795d594fSAndroid Build Coastguard Worker self, annotation_class.Get(), h_element_array.Get());
407*795d594fSAndroid Build Coastguard Worker if (self->IsExceptionPending()) {
408*795d594fSAndroid Build Coastguard Worker LOG(INFO) << "Exception in AnnotationFactory.createAnnotation";
409*795d594fSAndroid Build Coastguard Worker return nullptr;
410*795d594fSAndroid Build Coastguard Worker }
411*795d594fSAndroid Build Coastguard Worker
412*795d594fSAndroid Build Coastguard Worker return result;
413*795d594fSAndroid Build Coastguard Worker }
414*795d594fSAndroid Build Coastguard Worker
415*795d594fSAndroid Build Coastguard Worker template <bool kTransactionActive>
ProcessAnnotationValue(const ClassData & klass,const uint8_t ** annotation_ptr,DexFile::AnnotationValue * annotation_value,Handle<mirror::Class> array_class,DexFile::AnnotationResultStyle result_style)416*795d594fSAndroid Build Coastguard Worker bool ProcessAnnotationValue(const ClassData& klass,
417*795d594fSAndroid Build Coastguard Worker const uint8_t** annotation_ptr,
418*795d594fSAndroid Build Coastguard Worker DexFile::AnnotationValue* annotation_value,
419*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> array_class,
420*795d594fSAndroid Build Coastguard Worker DexFile::AnnotationResultStyle result_style)
421*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
422*795d594fSAndroid Build Coastguard Worker const DexFile& dex_file = klass.GetDexFile();
423*795d594fSAndroid Build Coastguard Worker Thread* self = Thread::Current();
424*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> element_object = nullptr;
425*795d594fSAndroid Build Coastguard Worker bool set_object = false;
426*795d594fSAndroid Build Coastguard Worker Primitive::Type primitive_type = Primitive::kPrimVoid;
427*795d594fSAndroid Build Coastguard Worker const uint8_t* annotation = *annotation_ptr;
428*795d594fSAndroid Build Coastguard Worker uint8_t header_byte = *(annotation++);
429*795d594fSAndroid Build Coastguard Worker uint8_t value_type = header_byte & DexFile::kDexAnnotationValueTypeMask;
430*795d594fSAndroid Build Coastguard Worker uint8_t value_arg = header_byte >> DexFile::kDexAnnotationValueArgShift;
431*795d594fSAndroid Build Coastguard Worker int32_t width = value_arg + 1;
432*795d594fSAndroid Build Coastguard Worker annotation_value->type_ = value_type;
433*795d594fSAndroid Build Coastguard Worker
434*795d594fSAndroid Build Coastguard Worker switch (value_type) {
435*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationByte:
436*795d594fSAndroid Build Coastguard Worker annotation_value->value_.SetB(
437*795d594fSAndroid Build Coastguard Worker static_cast<int8_t>(DexFile::ReadSignedInt(annotation, value_arg)));
438*795d594fSAndroid Build Coastguard Worker primitive_type = Primitive::kPrimByte;
439*795d594fSAndroid Build Coastguard Worker break;
440*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationShort:
441*795d594fSAndroid Build Coastguard Worker annotation_value->value_.SetS(
442*795d594fSAndroid Build Coastguard Worker static_cast<int16_t>(DexFile::ReadSignedInt(annotation, value_arg)));
443*795d594fSAndroid Build Coastguard Worker primitive_type = Primitive::kPrimShort;
444*795d594fSAndroid Build Coastguard Worker break;
445*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationChar:
446*795d594fSAndroid Build Coastguard Worker annotation_value->value_.SetC(
447*795d594fSAndroid Build Coastguard Worker static_cast<uint16_t>(DexFile::ReadUnsignedInt(annotation, value_arg, false)));
448*795d594fSAndroid Build Coastguard Worker primitive_type = Primitive::kPrimChar;
449*795d594fSAndroid Build Coastguard Worker break;
450*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationInt:
451*795d594fSAndroid Build Coastguard Worker annotation_value->value_.SetI(DexFile::ReadSignedInt(annotation, value_arg));
452*795d594fSAndroid Build Coastguard Worker primitive_type = Primitive::kPrimInt;
453*795d594fSAndroid Build Coastguard Worker break;
454*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationLong:
455*795d594fSAndroid Build Coastguard Worker annotation_value->value_.SetJ(DexFile::ReadSignedLong(annotation, value_arg));
456*795d594fSAndroid Build Coastguard Worker primitive_type = Primitive::kPrimLong;
457*795d594fSAndroid Build Coastguard Worker break;
458*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationFloat:
459*795d594fSAndroid Build Coastguard Worker annotation_value->value_.SetI(DexFile::ReadUnsignedInt(annotation, value_arg, true));
460*795d594fSAndroid Build Coastguard Worker primitive_type = Primitive::kPrimFloat;
461*795d594fSAndroid Build Coastguard Worker break;
462*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationDouble:
463*795d594fSAndroid Build Coastguard Worker annotation_value->value_.SetJ(DexFile::ReadUnsignedLong(annotation, value_arg, true));
464*795d594fSAndroid Build Coastguard Worker primitive_type = Primitive::kPrimDouble;
465*795d594fSAndroid Build Coastguard Worker break;
466*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationBoolean:
467*795d594fSAndroid Build Coastguard Worker annotation_value->value_.SetZ(value_arg != 0);
468*795d594fSAndroid Build Coastguard Worker primitive_type = Primitive::kPrimBoolean;
469*795d594fSAndroid Build Coastguard Worker width = 0;
470*795d594fSAndroid Build Coastguard Worker break;
471*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationMethodType:
472*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationMethodHandle:
473*795d594fSAndroid Build Coastguard Worker // These annotations are unexpected here. Don't process them.
474*795d594fSAndroid Build Coastguard Worker LOG(WARNING) << StringPrintf("Unexpected annotation of type 0x%02x", value_type);
475*795d594fSAndroid Build Coastguard Worker return false;
476*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationString: {
477*795d594fSAndroid Build Coastguard Worker uint32_t index = DexFile::ReadUnsignedInt(annotation, value_arg, false);
478*795d594fSAndroid Build Coastguard Worker if (result_style == DexFile::kAllRaw) {
479*795d594fSAndroid Build Coastguard Worker annotation_value->value_.SetI(index);
480*795d594fSAndroid Build Coastguard Worker } else {
481*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(self);
482*795d594fSAndroid Build Coastguard Worker element_object = Runtime::Current()->GetClassLinker()->ResolveString(
483*795d594fSAndroid Build Coastguard Worker dex::StringIndex(index), hs.NewHandle(klass.GetDexCache()));
484*795d594fSAndroid Build Coastguard Worker set_object = true;
485*795d594fSAndroid Build Coastguard Worker if (element_object == nullptr) {
486*795d594fSAndroid Build Coastguard Worker return false;
487*795d594fSAndroid Build Coastguard Worker }
488*795d594fSAndroid Build Coastguard Worker }
489*795d594fSAndroid Build Coastguard Worker break;
490*795d594fSAndroid Build Coastguard Worker }
491*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationType: {
492*795d594fSAndroid Build Coastguard Worker uint32_t index = DexFile::ReadUnsignedInt(annotation, value_arg, false);
493*795d594fSAndroid Build Coastguard Worker if (result_style == DexFile::kAllRaw) {
494*795d594fSAndroid Build Coastguard Worker annotation_value->value_.SetI(index);
495*795d594fSAndroid Build Coastguard Worker } else {
496*795d594fSAndroid Build Coastguard Worker dex::TypeIndex type_index(index);
497*795d594fSAndroid Build Coastguard Worker StackHandleScope<2> hs(self);
498*795d594fSAndroid Build Coastguard Worker element_object = Runtime::Current()->GetClassLinker()->ResolveType(
499*795d594fSAndroid Build Coastguard Worker type_index,
500*795d594fSAndroid Build Coastguard Worker hs.NewHandle(klass.GetDexCache()),
501*795d594fSAndroid Build Coastguard Worker hs.NewHandle(klass.GetClassLoader()));
502*795d594fSAndroid Build Coastguard Worker set_object = true;
503*795d594fSAndroid Build Coastguard Worker if (element_object == nullptr) {
504*795d594fSAndroid Build Coastguard Worker CHECK(self->IsExceptionPending());
505*795d594fSAndroid Build Coastguard Worker if (result_style == DexFile::kAllObjects) {
506*795d594fSAndroid Build Coastguard Worker const char* msg = dex_file.GetTypeDescriptor(type_index);
507*795d594fSAndroid Build Coastguard Worker self->ThrowNewWrappedException("Ljava/lang/TypeNotPresentException;", msg);
508*795d594fSAndroid Build Coastguard Worker element_object = self->GetException();
509*795d594fSAndroid Build Coastguard Worker self->ClearException();
510*795d594fSAndroid Build Coastguard Worker } else {
511*795d594fSAndroid Build Coastguard Worker return false;
512*795d594fSAndroid Build Coastguard Worker }
513*795d594fSAndroid Build Coastguard Worker }
514*795d594fSAndroid Build Coastguard Worker }
515*795d594fSAndroid Build Coastguard Worker break;
516*795d594fSAndroid Build Coastguard Worker }
517*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationMethod: {
518*795d594fSAndroid Build Coastguard Worker uint32_t index = DexFile::ReadUnsignedInt(annotation, value_arg, false);
519*795d594fSAndroid Build Coastguard Worker if (result_style == DexFile::kAllRaw) {
520*795d594fSAndroid Build Coastguard Worker annotation_value->value_.SetI(index);
521*795d594fSAndroid Build Coastguard Worker } else {
522*795d594fSAndroid Build Coastguard Worker ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
523*795d594fSAndroid Build Coastguard Worker StackHandleScope<2> hs(self);
524*795d594fSAndroid Build Coastguard Worker ArtMethod* method = class_linker->ResolveMethodId(
525*795d594fSAndroid Build Coastguard Worker index,
526*795d594fSAndroid Build Coastguard Worker hs.NewHandle(klass.GetDexCache()),
527*795d594fSAndroid Build Coastguard Worker hs.NewHandle(klass.GetClassLoader()));
528*795d594fSAndroid Build Coastguard Worker if (method == nullptr) {
529*795d594fSAndroid Build Coastguard Worker return false;
530*795d594fSAndroid Build Coastguard Worker }
531*795d594fSAndroid Build Coastguard Worker PointerSize pointer_size = class_linker->GetImagePointerSize();
532*795d594fSAndroid Build Coastguard Worker set_object = true;
533*795d594fSAndroid Build Coastguard Worker if (method->IsConstructor()) {
534*795d594fSAndroid Build Coastguard Worker element_object = (pointer_size == PointerSize::k64)
535*795d594fSAndroid Build Coastguard Worker ? mirror::Constructor::CreateFromArtMethod<PointerSize::k64>(self, method)
536*795d594fSAndroid Build Coastguard Worker : mirror::Constructor::CreateFromArtMethod<PointerSize::k32>(self, method);
537*795d594fSAndroid Build Coastguard Worker } else {
538*795d594fSAndroid Build Coastguard Worker element_object = (pointer_size == PointerSize::k64)
539*795d594fSAndroid Build Coastguard Worker ? mirror::Method::CreateFromArtMethod<PointerSize::k64>(self, method)
540*795d594fSAndroid Build Coastguard Worker : mirror::Method::CreateFromArtMethod<PointerSize::k32>(self, method);
541*795d594fSAndroid Build Coastguard Worker }
542*795d594fSAndroid Build Coastguard Worker if (element_object == nullptr) {
543*795d594fSAndroid Build Coastguard Worker return false;
544*795d594fSAndroid Build Coastguard Worker }
545*795d594fSAndroid Build Coastguard Worker }
546*795d594fSAndroid Build Coastguard Worker break;
547*795d594fSAndroid Build Coastguard Worker }
548*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationField: {
549*795d594fSAndroid Build Coastguard Worker uint32_t index = DexFile::ReadUnsignedInt(annotation, value_arg, false);
550*795d594fSAndroid Build Coastguard Worker if (result_style == DexFile::kAllRaw) {
551*795d594fSAndroid Build Coastguard Worker annotation_value->value_.SetI(index);
552*795d594fSAndroid Build Coastguard Worker } else {
553*795d594fSAndroid Build Coastguard Worker StackHandleScope<2> hs(self);
554*795d594fSAndroid Build Coastguard Worker ArtField* field = Runtime::Current()->GetClassLinker()->ResolveFieldJLS(
555*795d594fSAndroid Build Coastguard Worker index,
556*795d594fSAndroid Build Coastguard Worker hs.NewHandle(klass.GetDexCache()),
557*795d594fSAndroid Build Coastguard Worker hs.NewHandle(klass.GetClassLoader()));
558*795d594fSAndroid Build Coastguard Worker if (field == nullptr) {
559*795d594fSAndroid Build Coastguard Worker return false;
560*795d594fSAndroid Build Coastguard Worker }
561*795d594fSAndroid Build Coastguard Worker set_object = true;
562*795d594fSAndroid Build Coastguard Worker element_object = mirror::Field::CreateFromArtField(self, field, true);
563*795d594fSAndroid Build Coastguard Worker if (element_object == nullptr) {
564*795d594fSAndroid Build Coastguard Worker return false;
565*795d594fSAndroid Build Coastguard Worker }
566*795d594fSAndroid Build Coastguard Worker }
567*795d594fSAndroid Build Coastguard Worker break;
568*795d594fSAndroid Build Coastguard Worker }
569*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationEnum: {
570*795d594fSAndroid Build Coastguard Worker uint32_t index = DexFile::ReadUnsignedInt(annotation, value_arg, false);
571*795d594fSAndroid Build Coastguard Worker if (result_style == DexFile::kAllRaw) {
572*795d594fSAndroid Build Coastguard Worker annotation_value->value_.SetI(index);
573*795d594fSAndroid Build Coastguard Worker } else {
574*795d594fSAndroid Build Coastguard Worker StackHandleScope<3> hs(self);
575*795d594fSAndroid Build Coastguard Worker ArtField* enum_field = Runtime::Current()->GetClassLinker()->ResolveField(
576*795d594fSAndroid Build Coastguard Worker index,
577*795d594fSAndroid Build Coastguard Worker hs.NewHandle(klass.GetDexCache()),
578*795d594fSAndroid Build Coastguard Worker hs.NewHandle(klass.GetClassLoader()),
579*795d594fSAndroid Build Coastguard Worker true);
580*795d594fSAndroid Build Coastguard Worker if (enum_field == nullptr) {
581*795d594fSAndroid Build Coastguard Worker return false;
582*795d594fSAndroid Build Coastguard Worker } else {
583*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> field_class(hs.NewHandle(enum_field->GetDeclaringClass()));
584*795d594fSAndroid Build Coastguard Worker Runtime::Current()->GetClassLinker()->EnsureInitialized(self, field_class, true, true);
585*795d594fSAndroid Build Coastguard Worker element_object = enum_field->GetObject(field_class.Get());
586*795d594fSAndroid Build Coastguard Worker set_object = true;
587*795d594fSAndroid Build Coastguard Worker }
588*795d594fSAndroid Build Coastguard Worker }
589*795d594fSAndroid Build Coastguard Worker break;
590*795d594fSAndroid Build Coastguard Worker }
591*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationArray:
592*795d594fSAndroid Build Coastguard Worker if (result_style == DexFile::kAllRaw || array_class == nullptr) {
593*795d594fSAndroid Build Coastguard Worker return false;
594*795d594fSAndroid Build Coastguard Worker } else {
595*795d594fSAndroid Build Coastguard Worker ScopedObjectAccessUnchecked soa(self);
596*795d594fSAndroid Build Coastguard Worker StackHandleScope<2> hs(self);
597*795d594fSAndroid Build Coastguard Worker uint32_t size = DecodeUnsignedLeb128(&annotation);
598*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> component_type(hs.NewHandle(array_class->GetComponentType()));
599*795d594fSAndroid Build Coastguard Worker Handle<mirror::Array> new_array(hs.NewHandle(mirror::Array::Alloc(
600*795d594fSAndroid Build Coastguard Worker self, array_class.Get(), size, array_class->GetComponentSizeShift(),
601*795d594fSAndroid Build Coastguard Worker Runtime::Current()->GetHeap()->GetCurrentAllocator())));
602*795d594fSAndroid Build Coastguard Worker if (new_array == nullptr) {
603*795d594fSAndroid Build Coastguard Worker LOG(ERROR) << "Annotation element array allocation failed with size " << size;
604*795d594fSAndroid Build Coastguard Worker return false;
605*795d594fSAndroid Build Coastguard Worker }
606*795d594fSAndroid Build Coastguard Worker DexFile::AnnotationValue new_annotation_value;
607*795d594fSAndroid Build Coastguard Worker for (uint32_t i = 0; i < size; ++i) {
608*795d594fSAndroid Build Coastguard Worker if (!ProcessAnnotationValue<kTransactionActive>(klass,
609*795d594fSAndroid Build Coastguard Worker &annotation,
610*795d594fSAndroid Build Coastguard Worker &new_annotation_value,
611*795d594fSAndroid Build Coastguard Worker component_type,
612*795d594fSAndroid Build Coastguard Worker DexFile::kPrimitivesOrObjects)) {
613*795d594fSAndroid Build Coastguard Worker return false;
614*795d594fSAndroid Build Coastguard Worker }
615*795d594fSAndroid Build Coastguard Worker if (!component_type->IsPrimitive()) {
616*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> obj = new_annotation_value.value_.GetL();
617*795d594fSAndroid Build Coastguard Worker new_array->AsObjectArray<mirror::Object>()->
618*795d594fSAndroid Build Coastguard Worker SetWithoutChecks<kTransactionActive>(i, obj);
619*795d594fSAndroid Build Coastguard Worker } else {
620*795d594fSAndroid Build Coastguard Worker switch (new_annotation_value.type_) {
621*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationByte:
622*795d594fSAndroid Build Coastguard Worker new_array->AsByteArray()->SetWithoutChecks<kTransactionActive>(
623*795d594fSAndroid Build Coastguard Worker i, new_annotation_value.value_.GetB());
624*795d594fSAndroid Build Coastguard Worker break;
625*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationShort:
626*795d594fSAndroid Build Coastguard Worker new_array->AsShortArray()->SetWithoutChecks<kTransactionActive>(
627*795d594fSAndroid Build Coastguard Worker i, new_annotation_value.value_.GetS());
628*795d594fSAndroid Build Coastguard Worker break;
629*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationChar:
630*795d594fSAndroid Build Coastguard Worker new_array->AsCharArray()->SetWithoutChecks<kTransactionActive>(
631*795d594fSAndroid Build Coastguard Worker i, new_annotation_value.value_.GetC());
632*795d594fSAndroid Build Coastguard Worker break;
633*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationInt:
634*795d594fSAndroid Build Coastguard Worker new_array->AsIntArray()->SetWithoutChecks<kTransactionActive>(
635*795d594fSAndroid Build Coastguard Worker i, new_annotation_value.value_.GetI());
636*795d594fSAndroid Build Coastguard Worker break;
637*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationLong:
638*795d594fSAndroid Build Coastguard Worker new_array->AsLongArray()->SetWithoutChecks<kTransactionActive>(
639*795d594fSAndroid Build Coastguard Worker i, new_annotation_value.value_.GetJ());
640*795d594fSAndroid Build Coastguard Worker break;
641*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationFloat:
642*795d594fSAndroid Build Coastguard Worker new_array->AsFloatArray()->SetWithoutChecks<kTransactionActive>(
643*795d594fSAndroid Build Coastguard Worker i, new_annotation_value.value_.GetF());
644*795d594fSAndroid Build Coastguard Worker break;
645*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationDouble:
646*795d594fSAndroid Build Coastguard Worker new_array->AsDoubleArray()->SetWithoutChecks<kTransactionActive>(
647*795d594fSAndroid Build Coastguard Worker i, new_annotation_value.value_.GetD());
648*795d594fSAndroid Build Coastguard Worker break;
649*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationBoolean:
650*795d594fSAndroid Build Coastguard Worker new_array->AsBooleanArray()->SetWithoutChecks<kTransactionActive>(
651*795d594fSAndroid Build Coastguard Worker i, new_annotation_value.value_.GetZ());
652*795d594fSAndroid Build Coastguard Worker break;
653*795d594fSAndroid Build Coastguard Worker default:
654*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << "Found invalid annotation value type while building annotation array";
655*795d594fSAndroid Build Coastguard Worker return false;
656*795d594fSAndroid Build Coastguard Worker }
657*795d594fSAndroid Build Coastguard Worker }
658*795d594fSAndroid Build Coastguard Worker }
659*795d594fSAndroid Build Coastguard Worker element_object = new_array.Get();
660*795d594fSAndroid Build Coastguard Worker set_object = true;
661*795d594fSAndroid Build Coastguard Worker width = 0;
662*795d594fSAndroid Build Coastguard Worker }
663*795d594fSAndroid Build Coastguard Worker break;
664*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationAnnotation:
665*795d594fSAndroid Build Coastguard Worker if (result_style == DexFile::kAllRaw) {
666*795d594fSAndroid Build Coastguard Worker return false;
667*795d594fSAndroid Build Coastguard Worker }
668*795d594fSAndroid Build Coastguard Worker element_object = ProcessEncodedAnnotation(klass, &annotation);
669*795d594fSAndroid Build Coastguard Worker if (element_object == nullptr) {
670*795d594fSAndroid Build Coastguard Worker return false;
671*795d594fSAndroid Build Coastguard Worker }
672*795d594fSAndroid Build Coastguard Worker set_object = true;
673*795d594fSAndroid Build Coastguard Worker width = 0;
674*795d594fSAndroid Build Coastguard Worker break;
675*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationNull:
676*795d594fSAndroid Build Coastguard Worker if (result_style == DexFile::kAllRaw) {
677*795d594fSAndroid Build Coastguard Worker annotation_value->value_.SetI(0);
678*795d594fSAndroid Build Coastguard Worker } else {
679*795d594fSAndroid Build Coastguard Worker CHECK(element_object == nullptr);
680*795d594fSAndroid Build Coastguard Worker set_object = true;
681*795d594fSAndroid Build Coastguard Worker }
682*795d594fSAndroid Build Coastguard Worker width = 0;
683*795d594fSAndroid Build Coastguard Worker break;
684*795d594fSAndroid Build Coastguard Worker default:
685*795d594fSAndroid Build Coastguard Worker LOG(ERROR) << StringPrintf("Bad annotation element value type 0x%02x", value_type);
686*795d594fSAndroid Build Coastguard Worker return false;
687*795d594fSAndroid Build Coastguard Worker }
688*795d594fSAndroid Build Coastguard Worker
689*795d594fSAndroid Build Coastguard Worker annotation += width;
690*795d594fSAndroid Build Coastguard Worker *annotation_ptr = annotation;
691*795d594fSAndroid Build Coastguard Worker
692*795d594fSAndroid Build Coastguard Worker if (result_style == DexFile::kAllObjects && primitive_type != Primitive::kPrimVoid) {
693*795d594fSAndroid Build Coastguard Worker element_object = BoxPrimitive(primitive_type, annotation_value->value_);
694*795d594fSAndroid Build Coastguard Worker set_object = true;
695*795d594fSAndroid Build Coastguard Worker }
696*795d594fSAndroid Build Coastguard Worker
697*795d594fSAndroid Build Coastguard Worker if (set_object) {
698*795d594fSAndroid Build Coastguard Worker annotation_value->value_.SetL(element_object);
699*795d594fSAndroid Build Coastguard Worker }
700*795d594fSAndroid Build Coastguard Worker
701*795d594fSAndroid Build Coastguard Worker return true;
702*795d594fSAndroid Build Coastguard Worker }
703*795d594fSAndroid Build Coastguard Worker
CreateAnnotationMember(const ClassData & klass,Handle<mirror::Class> annotation_class,const uint8_t ** annotation)704*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> CreateAnnotationMember(const ClassData& klass,
705*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> annotation_class,
706*795d594fSAndroid Build Coastguard Worker const uint8_t** annotation) {
707*795d594fSAndroid Build Coastguard Worker const DexFile& dex_file = klass.GetDexFile();
708*795d594fSAndroid Build Coastguard Worker Thread* self = Thread::Current();
709*795d594fSAndroid Build Coastguard Worker ScopedObjectAccessUnchecked soa(self);
710*795d594fSAndroid Build Coastguard Worker StackHandleScope<5> hs(self);
711*795d594fSAndroid Build Coastguard Worker uint32_t element_name_index = DecodeUnsignedLeb128(annotation);
712*795d594fSAndroid Build Coastguard Worker const char* name = dex_file.GetStringData(dex::StringIndex(element_name_index));
713*795d594fSAndroid Build Coastguard Worker
714*795d594fSAndroid Build Coastguard Worker PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
715*795d594fSAndroid Build Coastguard Worker ArtMethod* annotation_method =
716*795d594fSAndroid Build Coastguard Worker annotation_class->FindDeclaredVirtualMethodByName(name, pointer_size);
717*795d594fSAndroid Build Coastguard Worker if (annotation_method == nullptr) {
718*795d594fSAndroid Build Coastguard Worker return nullptr;
719*795d594fSAndroid Build Coastguard Worker }
720*795d594fSAndroid Build Coastguard Worker
721*795d594fSAndroid Build Coastguard Worker Handle<mirror::String> string_name =
722*795d594fSAndroid Build Coastguard Worker hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, name));
723*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(string_name == nullptr)) {
724*795d594fSAndroid Build Coastguard Worker LOG(ERROR) << "Failed to allocate name for annotation member";
725*795d594fSAndroid Build Coastguard Worker return nullptr;
726*795d594fSAndroid Build Coastguard Worker }
727*795d594fSAndroid Build Coastguard Worker
728*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> method_return = hs.NewHandle(annotation_method->ResolveReturnType());
729*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(method_return == nullptr)) {
730*795d594fSAndroid Build Coastguard Worker LOG(ERROR) << "Failed to resolve method return type for annotation member";
731*795d594fSAndroid Build Coastguard Worker return nullptr;
732*795d594fSAndroid Build Coastguard Worker }
733*795d594fSAndroid Build Coastguard Worker
734*795d594fSAndroid Build Coastguard Worker DexFile::AnnotationValue annotation_value;
735*795d594fSAndroid Build Coastguard Worker if (!ProcessAnnotationValue<false>(klass,
736*795d594fSAndroid Build Coastguard Worker annotation,
737*795d594fSAndroid Build Coastguard Worker &annotation_value,
738*795d594fSAndroid Build Coastguard Worker method_return,
739*795d594fSAndroid Build Coastguard Worker DexFile::kAllObjects)) {
740*795d594fSAndroid Build Coastguard Worker // TODO: Logging the error breaks run-test 005-annotations.
741*795d594fSAndroid Build Coastguard Worker // LOG(ERROR) << "Failed to process annotation value for annotation member";
742*795d594fSAndroid Build Coastguard Worker return nullptr;
743*795d594fSAndroid Build Coastguard Worker }
744*795d594fSAndroid Build Coastguard Worker Handle<mirror::Object> value_object = hs.NewHandle(annotation_value.value_.GetL());
745*795d594fSAndroid Build Coastguard Worker
746*795d594fSAndroid Build Coastguard Worker Handle<mirror::Method> method_object = hs.NewHandle((pointer_size == PointerSize::k64)
747*795d594fSAndroid Build Coastguard Worker ? mirror::Method::CreateFromArtMethod<PointerSize::k64>(self, annotation_method)
748*795d594fSAndroid Build Coastguard Worker : mirror::Method::CreateFromArtMethod<PointerSize::k32>(self, annotation_method));
749*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(method_object == nullptr)) {
750*795d594fSAndroid Build Coastguard Worker LOG(ERROR) << "Failed to create method object for annotation member";
751*795d594fSAndroid Build Coastguard Worker return nullptr;
752*795d594fSAndroid Build Coastguard Worker }
753*795d594fSAndroid Build Coastguard Worker
754*795d594fSAndroid Build Coastguard Worker Handle<mirror::Object> new_member =
755*795d594fSAndroid Build Coastguard Worker WellKnownClasses::libcore_reflect_AnnotationMember_init->NewObject<'L', 'L', 'L', 'L'>(
756*795d594fSAndroid Build Coastguard Worker hs, self, string_name, value_object, method_return, method_object);
757*795d594fSAndroid Build Coastguard Worker if (new_member == nullptr) {
758*795d594fSAndroid Build Coastguard Worker DCHECK(self->IsExceptionPending());
759*795d594fSAndroid Build Coastguard Worker LOG(ERROR) << "Failed to create annotation member";
760*795d594fSAndroid Build Coastguard Worker return nullptr;
761*795d594fSAndroid Build Coastguard Worker }
762*795d594fSAndroid Build Coastguard Worker
763*795d594fSAndroid Build Coastguard Worker return new_member.Get();
764*795d594fSAndroid Build Coastguard Worker }
765*795d594fSAndroid Build Coastguard Worker
GetAnnotationItemFromAnnotationSet(const ClassData & klass,const AnnotationSetItem * annotation_set,uint32_t visibility,Handle<mirror::Class> annotation_class)766*795d594fSAndroid Build Coastguard Worker const AnnotationItem* GetAnnotationItemFromAnnotationSet(const ClassData& klass,
767*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set,
768*795d594fSAndroid Build Coastguard Worker uint32_t visibility,
769*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> annotation_class)
770*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
771*795d594fSAndroid Build Coastguard Worker const DexFile& dex_file = klass.GetDexFile();
772*795d594fSAndroid Build Coastguard Worker for (uint32_t i = 0; i < annotation_set->size_; ++i) {
773*795d594fSAndroid Build Coastguard Worker const AnnotationItem* annotation_item = dex_file.GetAnnotationItem(annotation_set, i);
774*795d594fSAndroid Build Coastguard Worker if (!IsVisibilityCompatible(annotation_item->visibility_, visibility)) {
775*795d594fSAndroid Build Coastguard Worker continue;
776*795d594fSAndroid Build Coastguard Worker }
777*795d594fSAndroid Build Coastguard Worker const uint8_t* annotation = annotation_item->annotation_;
778*795d594fSAndroid Build Coastguard Worker uint32_t type_index = DecodeUnsignedLeb128(&annotation);
779*795d594fSAndroid Build Coastguard Worker ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
780*795d594fSAndroid Build Coastguard Worker Thread* self = Thread::Current();
781*795d594fSAndroid Build Coastguard Worker StackHandleScope<2> hs(self);
782*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> resolved_class = class_linker->ResolveType(
783*795d594fSAndroid Build Coastguard Worker dex::TypeIndex(type_index),
784*795d594fSAndroid Build Coastguard Worker hs.NewHandle(klass.GetDexCache()),
785*795d594fSAndroid Build Coastguard Worker hs.NewHandle(klass.GetClassLoader()));
786*795d594fSAndroid Build Coastguard Worker if (resolved_class == nullptr) {
787*795d594fSAndroid Build Coastguard Worker std::string temp;
788*795d594fSAndroid Build Coastguard Worker LOG(WARNING) << StringPrintf("Unable to resolve %s annotation class %d",
789*795d594fSAndroid Build Coastguard Worker klass.GetRealClass()->GetDescriptor(&temp), type_index);
790*795d594fSAndroid Build Coastguard Worker CHECK(self->IsExceptionPending());
791*795d594fSAndroid Build Coastguard Worker self->ClearException();
792*795d594fSAndroid Build Coastguard Worker continue;
793*795d594fSAndroid Build Coastguard Worker }
794*795d594fSAndroid Build Coastguard Worker if (resolved_class == annotation_class.Get()) {
795*795d594fSAndroid Build Coastguard Worker return annotation_item;
796*795d594fSAndroid Build Coastguard Worker }
797*795d594fSAndroid Build Coastguard Worker }
798*795d594fSAndroid Build Coastguard Worker
799*795d594fSAndroid Build Coastguard Worker return nullptr;
800*795d594fSAndroid Build Coastguard Worker }
801*795d594fSAndroid Build Coastguard Worker
GetAnnotationObjectFromAnnotationSet(const ClassData & klass,const AnnotationSetItem * annotation_set,uint32_t visibility,Handle<mirror::Class> annotation_class)802*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> GetAnnotationObjectFromAnnotationSet(const ClassData& klass,
803*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set,
804*795d594fSAndroid Build Coastguard Worker uint32_t visibility,
805*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> annotation_class)
806*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
807*795d594fSAndroid Build Coastguard Worker const AnnotationItem* annotation_item = GetAnnotationItemFromAnnotationSet(
808*795d594fSAndroid Build Coastguard Worker klass, annotation_set, visibility, annotation_class);
809*795d594fSAndroid Build Coastguard Worker if (annotation_item == nullptr) {
810*795d594fSAndroid Build Coastguard Worker return nullptr;
811*795d594fSAndroid Build Coastguard Worker }
812*795d594fSAndroid Build Coastguard Worker const uint8_t* annotation = annotation_item->annotation_;
813*795d594fSAndroid Build Coastguard Worker return ProcessEncodedAnnotation(klass, &annotation);
814*795d594fSAndroid Build Coastguard Worker }
815*795d594fSAndroid Build Coastguard Worker
GetAnnotationValue(const ClassData & klass,const AnnotationItem * annotation_item,const char * annotation_name,Handle<mirror::Class> array_class,uint32_t expected_type)816*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> GetAnnotationValue(const ClassData& klass,
817*795d594fSAndroid Build Coastguard Worker const AnnotationItem* annotation_item,
818*795d594fSAndroid Build Coastguard Worker const char* annotation_name,
819*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> array_class,
820*795d594fSAndroid Build Coastguard Worker uint32_t expected_type)
821*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
822*795d594fSAndroid Build Coastguard Worker const DexFile& dex_file = klass.GetDexFile();
823*795d594fSAndroid Build Coastguard Worker const uint8_t* annotation =
824*795d594fSAndroid Build Coastguard Worker SearchEncodedAnnotation(dex_file, annotation_item->annotation_, annotation_name);
825*795d594fSAndroid Build Coastguard Worker if (annotation == nullptr) {
826*795d594fSAndroid Build Coastguard Worker return nullptr;
827*795d594fSAndroid Build Coastguard Worker }
828*795d594fSAndroid Build Coastguard Worker DexFile::AnnotationValue annotation_value;
829*795d594fSAndroid Build Coastguard Worker bool result = Runtime::Current()->IsActiveTransaction()
830*795d594fSAndroid Build Coastguard Worker ? ProcessAnnotationValue<true>(klass,
831*795d594fSAndroid Build Coastguard Worker &annotation,
832*795d594fSAndroid Build Coastguard Worker &annotation_value,
833*795d594fSAndroid Build Coastguard Worker array_class,
834*795d594fSAndroid Build Coastguard Worker DexFile::kAllObjects)
835*795d594fSAndroid Build Coastguard Worker : ProcessAnnotationValue<false>(klass,
836*795d594fSAndroid Build Coastguard Worker &annotation,
837*795d594fSAndroid Build Coastguard Worker &annotation_value,
838*795d594fSAndroid Build Coastguard Worker array_class,
839*795d594fSAndroid Build Coastguard Worker DexFile::kAllObjects);
840*795d594fSAndroid Build Coastguard Worker if (!result) {
841*795d594fSAndroid Build Coastguard Worker return nullptr;
842*795d594fSAndroid Build Coastguard Worker }
843*795d594fSAndroid Build Coastguard Worker if (annotation_value.type_ != expected_type) {
844*795d594fSAndroid Build Coastguard Worker return nullptr;
845*795d594fSAndroid Build Coastguard Worker }
846*795d594fSAndroid Build Coastguard Worker return annotation_value.value_.GetL();
847*795d594fSAndroid Build Coastguard Worker }
848*795d594fSAndroid Build Coastguard Worker
849*795d594fSAndroid Build Coastguard Worker template<typename T>
GetAnnotationArrayValue(Handle<mirror::Class> klass,const char * annotation_name,const char * value_name)850*795d594fSAndroid Build Coastguard Worker static inline ObjPtr<mirror::ObjectArray<T>> GetAnnotationArrayValue(
851*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> klass,
852*795d594fSAndroid Build Coastguard Worker const char* annotation_name,
853*795d594fSAndroid Build Coastguard Worker const char* value_name)
854*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
855*795d594fSAndroid Build Coastguard Worker ClassData data(klass);
856*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
857*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
858*795d594fSAndroid Build Coastguard Worker return nullptr;
859*795d594fSAndroid Build Coastguard Worker }
860*795d594fSAndroid Build Coastguard Worker const AnnotationItem* annotation_item =
861*795d594fSAndroid Build Coastguard Worker SearchAnnotationSet(data.GetDexFile(), annotation_set, annotation_name,
862*795d594fSAndroid Build Coastguard Worker DexFile::kDexVisibilitySystem);
863*795d594fSAndroid Build Coastguard Worker if (annotation_item == nullptr) {
864*795d594fSAndroid Build Coastguard Worker return nullptr;
865*795d594fSAndroid Build Coastguard Worker }
866*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(Thread::Current());
867*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> class_array_class =
868*795d594fSAndroid Build Coastguard Worker hs.NewHandle(GetClassRoot<mirror::ObjectArray<T>>());
869*795d594fSAndroid Build Coastguard Worker DCHECK(class_array_class != nullptr);
870*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> obj = GetAnnotationValue(data,
871*795d594fSAndroid Build Coastguard Worker annotation_item,
872*795d594fSAndroid Build Coastguard Worker value_name,
873*795d594fSAndroid Build Coastguard Worker class_array_class,
874*795d594fSAndroid Build Coastguard Worker DexFile::kDexAnnotationArray);
875*795d594fSAndroid Build Coastguard Worker if (obj == nullptr) {
876*795d594fSAndroid Build Coastguard Worker return nullptr;
877*795d594fSAndroid Build Coastguard Worker }
878*795d594fSAndroid Build Coastguard Worker return obj->AsObjectArray<T>();
879*795d594fSAndroid Build Coastguard Worker }
880*795d594fSAndroid Build Coastguard Worker
GetSignatureValue(const ClassData & klass,const AnnotationSetItem * annotation_set)881*795d594fSAndroid Build Coastguard Worker static ObjPtr<mirror::ObjectArray<mirror::String>> GetSignatureValue(
882*795d594fSAndroid Build Coastguard Worker const ClassData& klass,
883*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set)
884*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
885*795d594fSAndroid Build Coastguard Worker const DexFile& dex_file = klass.GetDexFile();
886*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(Thread::Current());
887*795d594fSAndroid Build Coastguard Worker const AnnotationItem* annotation_item =
888*795d594fSAndroid Build Coastguard Worker SearchAnnotationSet(dex_file, annotation_set, "Ldalvik/annotation/Signature;",
889*795d594fSAndroid Build Coastguard Worker DexFile::kDexVisibilitySystem);
890*795d594fSAndroid Build Coastguard Worker if (annotation_item == nullptr) {
891*795d594fSAndroid Build Coastguard Worker return nullptr;
892*795d594fSAndroid Build Coastguard Worker }
893*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> string_array_class =
894*795d594fSAndroid Build Coastguard Worker hs.NewHandle(GetClassRoot<mirror::ObjectArray<mirror::String>>());
895*795d594fSAndroid Build Coastguard Worker DCHECK(string_array_class != nullptr);
896*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> obj =
897*795d594fSAndroid Build Coastguard Worker GetAnnotationValue(klass, annotation_item, "value", string_array_class,
898*795d594fSAndroid Build Coastguard Worker DexFile::kDexAnnotationArray);
899*795d594fSAndroid Build Coastguard Worker if (obj == nullptr) {
900*795d594fSAndroid Build Coastguard Worker return nullptr;
901*795d594fSAndroid Build Coastguard Worker }
902*795d594fSAndroid Build Coastguard Worker return obj->AsObjectArray<mirror::String>();
903*795d594fSAndroid Build Coastguard Worker }
904*795d594fSAndroid Build Coastguard Worker
GetThrowsValue(const ClassData & klass,const AnnotationSetItem * annotation_set)905*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Class>> GetThrowsValue(const ClassData& klass,
906*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set)
907*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
908*795d594fSAndroid Build Coastguard Worker const DexFile& dex_file = klass.GetDexFile();
909*795d594fSAndroid Build Coastguard Worker const AnnotationItem* annotation_item =
910*795d594fSAndroid Build Coastguard Worker SearchAnnotationSet(dex_file, annotation_set, "Ldalvik/annotation/Throws;",
911*795d594fSAndroid Build Coastguard Worker DexFile::kDexVisibilitySystem);
912*795d594fSAndroid Build Coastguard Worker if (annotation_item == nullptr) {
913*795d594fSAndroid Build Coastguard Worker return nullptr;
914*795d594fSAndroid Build Coastguard Worker }
915*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(Thread::Current());
916*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> class_array_class =
917*795d594fSAndroid Build Coastguard Worker hs.NewHandle(GetClassRoot<mirror::ObjectArray<mirror::Class>>());
918*795d594fSAndroid Build Coastguard Worker DCHECK(class_array_class != nullptr);
919*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> obj =
920*795d594fSAndroid Build Coastguard Worker GetAnnotationValue(klass, annotation_item, "value", class_array_class,
921*795d594fSAndroid Build Coastguard Worker DexFile::kDexAnnotationArray);
922*795d594fSAndroid Build Coastguard Worker if (obj == nullptr) {
923*795d594fSAndroid Build Coastguard Worker return nullptr;
924*795d594fSAndroid Build Coastguard Worker }
925*795d594fSAndroid Build Coastguard Worker return obj->AsObjectArray<mirror::Class>();
926*795d594fSAndroid Build Coastguard Worker }
927*795d594fSAndroid Build Coastguard Worker
ProcessAnnotationSet(const ClassData & klass,const AnnotationSetItem * annotation_set,uint32_t visibility)928*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Object>> ProcessAnnotationSet(
929*795d594fSAndroid Build Coastguard Worker const ClassData& klass,
930*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set,
931*795d594fSAndroid Build Coastguard Worker uint32_t visibility)
932*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
933*795d594fSAndroid Build Coastguard Worker const DexFile& dex_file = klass.GetDexFile();
934*795d594fSAndroid Build Coastguard Worker Thread* self = Thread::Current();
935*795d594fSAndroid Build Coastguard Worker StackHandleScope<2> hs(self);
936*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> annotation_array_class(hs.NewHandle(
937*795d594fSAndroid Build Coastguard Worker WellKnownClasses::ToClass(WellKnownClasses::java_lang_annotation_Annotation__array)));
938*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
939*795d594fSAndroid Build Coastguard Worker return mirror::ObjectArray<mirror::Object>::Alloc(self, annotation_array_class.Get(), 0);
940*795d594fSAndroid Build Coastguard Worker }
941*795d594fSAndroid Build Coastguard Worker
942*795d594fSAndroid Build Coastguard Worker uint32_t size = annotation_set->size_;
943*795d594fSAndroid Build Coastguard Worker Handle<mirror::ObjectArray<mirror::Object>> result(hs.NewHandle(
944*795d594fSAndroid Build Coastguard Worker mirror::ObjectArray<mirror::Object>::Alloc(self, annotation_array_class.Get(), size)));
945*795d594fSAndroid Build Coastguard Worker if (result == nullptr) {
946*795d594fSAndroid Build Coastguard Worker return nullptr;
947*795d594fSAndroid Build Coastguard Worker }
948*795d594fSAndroid Build Coastguard Worker
949*795d594fSAndroid Build Coastguard Worker uint32_t dest_index = 0;
950*795d594fSAndroid Build Coastguard Worker for (uint32_t i = 0; i < size; ++i) {
951*795d594fSAndroid Build Coastguard Worker const AnnotationItem* annotation_item = dex_file.GetAnnotationItem(annotation_set, i);
952*795d594fSAndroid Build Coastguard Worker // Note that we do not use IsVisibilityCompatible here because older code
953*795d594fSAndroid Build Coastguard Worker // was correct for this case.
954*795d594fSAndroid Build Coastguard Worker if (annotation_item->visibility_ != visibility) {
955*795d594fSAndroid Build Coastguard Worker continue;
956*795d594fSAndroid Build Coastguard Worker }
957*795d594fSAndroid Build Coastguard Worker const uint8_t* annotation = annotation_item->annotation_;
958*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> annotation_obj = ProcessEncodedAnnotation(klass, &annotation);
959*795d594fSAndroid Build Coastguard Worker if (annotation_obj != nullptr) {
960*795d594fSAndroid Build Coastguard Worker result->SetWithoutChecks<false>(dest_index, annotation_obj);
961*795d594fSAndroid Build Coastguard Worker ++dest_index;
962*795d594fSAndroid Build Coastguard Worker } else if (self->IsExceptionPending()) {
963*795d594fSAndroid Build Coastguard Worker return nullptr;
964*795d594fSAndroid Build Coastguard Worker }
965*795d594fSAndroid Build Coastguard Worker }
966*795d594fSAndroid Build Coastguard Worker
967*795d594fSAndroid Build Coastguard Worker if (dest_index == size) {
968*795d594fSAndroid Build Coastguard Worker return result.Get();
969*795d594fSAndroid Build Coastguard Worker }
970*795d594fSAndroid Build Coastguard Worker
971*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Object>> trimmed_result =
972*795d594fSAndroid Build Coastguard Worker mirror::ObjectArray<mirror::Object>::Alloc(self, annotation_array_class.Get(), dest_index);
973*795d594fSAndroid Build Coastguard Worker if (trimmed_result == nullptr) {
974*795d594fSAndroid Build Coastguard Worker return nullptr;
975*795d594fSAndroid Build Coastguard Worker }
976*795d594fSAndroid Build Coastguard Worker
977*795d594fSAndroid Build Coastguard Worker for (uint32_t i = 0; i < dest_index; ++i) {
978*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> obj = result->GetWithoutChecks(i);
979*795d594fSAndroid Build Coastguard Worker trimmed_result->SetWithoutChecks<false>(i, obj);
980*795d594fSAndroid Build Coastguard Worker }
981*795d594fSAndroid Build Coastguard Worker
982*795d594fSAndroid Build Coastguard Worker return trimmed_result;
983*795d594fSAndroid Build Coastguard Worker }
984*795d594fSAndroid Build Coastguard Worker
ProcessAnnotationSetRefList(const ClassData & klass,const AnnotationSetRefList * set_ref_list,uint32_t size)985*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Object>> ProcessAnnotationSetRefList(
986*795d594fSAndroid Build Coastguard Worker const ClassData& klass,
987*795d594fSAndroid Build Coastguard Worker const AnnotationSetRefList* set_ref_list,
988*795d594fSAndroid Build Coastguard Worker uint32_t size)
989*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
990*795d594fSAndroid Build Coastguard Worker const DexFile& dex_file = klass.GetDexFile();
991*795d594fSAndroid Build Coastguard Worker Thread* self = Thread::Current();
992*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(self);
993*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> annotation_array_class =
994*795d594fSAndroid Build Coastguard Worker WellKnownClasses::ToClass(WellKnownClasses::java_lang_annotation_Annotation__array);
995*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> annotation_array_array_class =
996*795d594fSAndroid Build Coastguard Worker Runtime::Current()->GetClassLinker()->FindArrayClass(self, annotation_array_class);
997*795d594fSAndroid Build Coastguard Worker if (annotation_array_array_class == nullptr) {
998*795d594fSAndroid Build Coastguard Worker return nullptr;
999*795d594fSAndroid Build Coastguard Worker }
1000*795d594fSAndroid Build Coastguard Worker Handle<mirror::ObjectArray<mirror::Object>> annotation_array_array(hs.NewHandle(
1001*795d594fSAndroid Build Coastguard Worker mirror::ObjectArray<mirror::Object>::Alloc(self, annotation_array_array_class, size)));
1002*795d594fSAndroid Build Coastguard Worker if (annotation_array_array == nullptr) {
1003*795d594fSAndroid Build Coastguard Worker LOG(ERROR) << "Annotation set ref array allocation failed";
1004*795d594fSAndroid Build Coastguard Worker return nullptr;
1005*795d594fSAndroid Build Coastguard Worker }
1006*795d594fSAndroid Build Coastguard Worker for (uint32_t index = 0; index < size; ++index) {
1007*795d594fSAndroid Build Coastguard Worker const AnnotationSetRefItem* set_ref_item = &set_ref_list->list_[index];
1008*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* set_item = dex_file.GetSetRefItemItem(set_ref_item);
1009*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> annotation_set = ProcessAnnotationSet(klass,
1010*795d594fSAndroid Build Coastguard Worker set_item,
1011*795d594fSAndroid Build Coastguard Worker DexFile::kDexVisibilityRuntime);
1012*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
1013*795d594fSAndroid Build Coastguard Worker return nullptr;
1014*795d594fSAndroid Build Coastguard Worker }
1015*795d594fSAndroid Build Coastguard Worker annotation_array_array->SetWithoutChecks<false>(index, annotation_set);
1016*795d594fSAndroid Build Coastguard Worker }
1017*795d594fSAndroid Build Coastguard Worker return annotation_array_array.Get();
1018*795d594fSAndroid Build Coastguard Worker }
1019*795d594fSAndroid Build Coastguard Worker } // namespace
1020*795d594fSAndroid Build Coastguard Worker
1021*795d594fSAndroid Build Coastguard Worker namespace annotations {
1022*795d594fSAndroid Build Coastguard Worker
GetAnnotationForField(ArtField * field,Handle<mirror::Class> annotation_class)1023*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> GetAnnotationForField(ArtField* field,
1024*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> annotation_class) {
1025*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set = FindAnnotationSetForField(field);
1026*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
1027*795d594fSAndroid Build Coastguard Worker return nullptr;
1028*795d594fSAndroid Build Coastguard Worker }
1029*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(Thread::Current());
1030*795d594fSAndroid Build Coastguard Worker const ClassData field_class(hs, field);
1031*795d594fSAndroid Build Coastguard Worker return GetAnnotationObjectFromAnnotationSet(field_class,
1032*795d594fSAndroid Build Coastguard Worker annotation_set,
1033*795d594fSAndroid Build Coastguard Worker DexFile::kDexVisibilityRuntime,
1034*795d594fSAndroid Build Coastguard Worker annotation_class);
1035*795d594fSAndroid Build Coastguard Worker }
1036*795d594fSAndroid Build Coastguard Worker
GetAnnotationsForField(ArtField * field)1037*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Object>> GetAnnotationsForField(ArtField* field) {
1038*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set = FindAnnotationSetForField(field);
1039*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(Thread::Current());
1040*795d594fSAndroid Build Coastguard Worker const ClassData field_class(hs, field);
1041*795d594fSAndroid Build Coastguard Worker return ProcessAnnotationSet(field_class, annotation_set, DexFile::kDexVisibilityRuntime);
1042*795d594fSAndroid Build Coastguard Worker }
1043*795d594fSAndroid Build Coastguard Worker
GetSignatureAnnotationForField(ArtField * field)1044*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::String>> GetSignatureAnnotationForField(ArtField* field) {
1045*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set = FindAnnotationSetForField(field);
1046*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
1047*795d594fSAndroid Build Coastguard Worker return nullptr;
1048*795d594fSAndroid Build Coastguard Worker }
1049*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(Thread::Current());
1050*795d594fSAndroid Build Coastguard Worker const ClassData field_class(hs, field);
1051*795d594fSAndroid Build Coastguard Worker return GetSignatureValue(field_class, annotation_set);
1052*795d594fSAndroid Build Coastguard Worker }
1053*795d594fSAndroid Build Coastguard Worker
IsFieldAnnotationPresent(ArtField * field,Handle<mirror::Class> annotation_class)1054*795d594fSAndroid Build Coastguard Worker bool IsFieldAnnotationPresent(ArtField* field, Handle<mirror::Class> annotation_class) {
1055*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set = FindAnnotationSetForField(field);
1056*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
1057*795d594fSAndroid Build Coastguard Worker return false;
1058*795d594fSAndroid Build Coastguard Worker }
1059*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(Thread::Current());
1060*795d594fSAndroid Build Coastguard Worker const ClassData field_class(hs, field);
1061*795d594fSAndroid Build Coastguard Worker const AnnotationItem* annotation_item = GetAnnotationItemFromAnnotationSet(
1062*795d594fSAndroid Build Coastguard Worker field_class, annotation_set, DexFile::kDexVisibilityRuntime, annotation_class);
1063*795d594fSAndroid Build Coastguard Worker return annotation_item != nullptr;
1064*795d594fSAndroid Build Coastguard Worker }
1065*795d594fSAndroid Build Coastguard Worker
GetAnnotationDefaultValue(ArtMethod * method)1066*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> GetAnnotationDefaultValue(ArtMethod* method) {
1067*795d594fSAndroid Build Coastguard Worker const ClassData klass(method);
1068*795d594fSAndroid Build Coastguard Worker const DexFile* dex_file = &klass.GetDexFile();
1069*795d594fSAndroid Build Coastguard Worker const AnnotationsDirectoryItem* annotations_dir =
1070*795d594fSAndroid Build Coastguard Worker dex_file->GetAnnotationsDirectory(*klass.GetClassDef());
1071*795d594fSAndroid Build Coastguard Worker if (annotations_dir == nullptr) {
1072*795d594fSAndroid Build Coastguard Worker return nullptr;
1073*795d594fSAndroid Build Coastguard Worker }
1074*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set =
1075*795d594fSAndroid Build Coastguard Worker dex_file->GetClassAnnotationSet(annotations_dir);
1076*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
1077*795d594fSAndroid Build Coastguard Worker return nullptr;
1078*795d594fSAndroid Build Coastguard Worker }
1079*795d594fSAndroid Build Coastguard Worker const AnnotationItem* annotation_item = SearchAnnotationSet(*dex_file, annotation_set,
1080*795d594fSAndroid Build Coastguard Worker "Ldalvik/annotation/AnnotationDefault;", DexFile::kDexVisibilitySystem);
1081*795d594fSAndroid Build Coastguard Worker if (annotation_item == nullptr) {
1082*795d594fSAndroid Build Coastguard Worker return nullptr;
1083*795d594fSAndroid Build Coastguard Worker }
1084*795d594fSAndroid Build Coastguard Worker const uint8_t* annotation =
1085*795d594fSAndroid Build Coastguard Worker SearchEncodedAnnotation(*dex_file, annotation_item->annotation_, "value");
1086*795d594fSAndroid Build Coastguard Worker if (annotation == nullptr) {
1087*795d594fSAndroid Build Coastguard Worker return nullptr;
1088*795d594fSAndroid Build Coastguard Worker }
1089*795d594fSAndroid Build Coastguard Worker uint8_t header_byte = *(annotation++);
1090*795d594fSAndroid Build Coastguard Worker if ((header_byte & DexFile::kDexAnnotationValueTypeMask) != DexFile::kDexAnnotationAnnotation) {
1091*795d594fSAndroid Build Coastguard Worker return nullptr;
1092*795d594fSAndroid Build Coastguard Worker }
1093*795d594fSAndroid Build Coastguard Worker annotation = SearchEncodedAnnotation(*dex_file, annotation, method->GetName());
1094*795d594fSAndroid Build Coastguard Worker if (annotation == nullptr) {
1095*795d594fSAndroid Build Coastguard Worker return nullptr;
1096*795d594fSAndroid Build Coastguard Worker }
1097*795d594fSAndroid Build Coastguard Worker DexFile::AnnotationValue annotation_value;
1098*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(Thread::Current());
1099*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> return_type(hs.NewHandle(method->ResolveReturnType()));
1100*795d594fSAndroid Build Coastguard Worker if (!ProcessAnnotationValue<false>(klass,
1101*795d594fSAndroid Build Coastguard Worker &annotation,
1102*795d594fSAndroid Build Coastguard Worker &annotation_value,
1103*795d594fSAndroid Build Coastguard Worker return_type,
1104*795d594fSAndroid Build Coastguard Worker DexFile::kAllObjects)) {
1105*795d594fSAndroid Build Coastguard Worker return nullptr;
1106*795d594fSAndroid Build Coastguard Worker }
1107*795d594fSAndroid Build Coastguard Worker return annotation_value.value_.GetL();
1108*795d594fSAndroid Build Coastguard Worker }
1109*795d594fSAndroid Build Coastguard Worker
GetAnnotationForMethod(ArtMethod * method,Handle<mirror::Class> annotation_class)1110*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> GetAnnotationForMethod(ArtMethod* method,
1111*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> annotation_class) {
1112*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set = FindAnnotationSetForMethod(method);
1113*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
1114*795d594fSAndroid Build Coastguard Worker return nullptr;
1115*795d594fSAndroid Build Coastguard Worker }
1116*795d594fSAndroid Build Coastguard Worker return GetAnnotationObjectFromAnnotationSet(ClassData(method), annotation_set,
1117*795d594fSAndroid Build Coastguard Worker DexFile::kDexVisibilityRuntime, annotation_class);
1118*795d594fSAndroid Build Coastguard Worker }
1119*795d594fSAndroid Build Coastguard Worker
GetAnnotationsForMethod(ArtMethod * method)1120*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Object>> GetAnnotationsForMethod(ArtMethod* method) {
1121*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set = FindAnnotationSetForMethod(method);
1122*795d594fSAndroid Build Coastguard Worker return ProcessAnnotationSet(ClassData(method),
1123*795d594fSAndroid Build Coastguard Worker annotation_set,
1124*795d594fSAndroid Build Coastguard Worker DexFile::kDexVisibilityRuntime);
1125*795d594fSAndroid Build Coastguard Worker }
1126*795d594fSAndroid Build Coastguard Worker
GetExceptionTypesForMethod(ArtMethod * method)1127*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Class>> GetExceptionTypesForMethod(ArtMethod* method) {
1128*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set = FindAnnotationSetForMethod(method);
1129*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
1130*795d594fSAndroid Build Coastguard Worker return nullptr;
1131*795d594fSAndroid Build Coastguard Worker }
1132*795d594fSAndroid Build Coastguard Worker return GetThrowsValue(ClassData(method), annotation_set);
1133*795d594fSAndroid Build Coastguard Worker }
1134*795d594fSAndroid Build Coastguard Worker
GetParameterAnnotations(ArtMethod * method)1135*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Object>> GetParameterAnnotations(ArtMethod* method) {
1136*795d594fSAndroid Build Coastguard Worker const DexFile* dex_file = method->GetDexFile();
1137*795d594fSAndroid Build Coastguard Worker const ParameterAnnotationsItem* parameter_annotations =
1138*795d594fSAndroid Build Coastguard Worker FindAnnotationsItemForMethod(method);
1139*795d594fSAndroid Build Coastguard Worker if (parameter_annotations == nullptr) {
1140*795d594fSAndroid Build Coastguard Worker return nullptr;
1141*795d594fSAndroid Build Coastguard Worker }
1142*795d594fSAndroid Build Coastguard Worker const AnnotationSetRefList* set_ref_list =
1143*795d594fSAndroid Build Coastguard Worker dex_file->GetParameterAnnotationSetRefList(parameter_annotations);
1144*795d594fSAndroid Build Coastguard Worker if (set_ref_list == nullptr) {
1145*795d594fSAndroid Build Coastguard Worker return nullptr;
1146*795d594fSAndroid Build Coastguard Worker }
1147*795d594fSAndroid Build Coastguard Worker uint32_t size = set_ref_list->size_;
1148*795d594fSAndroid Build Coastguard Worker return ProcessAnnotationSetRefList(ClassData(method), set_ref_list, size);
1149*795d594fSAndroid Build Coastguard Worker }
1150*795d594fSAndroid Build Coastguard Worker
GetNumberOfAnnotatedMethodParameters(ArtMethod * method)1151*795d594fSAndroid Build Coastguard Worker uint32_t GetNumberOfAnnotatedMethodParameters(ArtMethod* method) {
1152*795d594fSAndroid Build Coastguard Worker const DexFile* dex_file = method->GetDexFile();
1153*795d594fSAndroid Build Coastguard Worker const ParameterAnnotationsItem* parameter_annotations =
1154*795d594fSAndroid Build Coastguard Worker FindAnnotationsItemForMethod(method);
1155*795d594fSAndroid Build Coastguard Worker if (parameter_annotations == nullptr) {
1156*795d594fSAndroid Build Coastguard Worker return 0u;
1157*795d594fSAndroid Build Coastguard Worker }
1158*795d594fSAndroid Build Coastguard Worker const AnnotationSetRefList* set_ref_list =
1159*795d594fSAndroid Build Coastguard Worker dex_file->GetParameterAnnotationSetRefList(parameter_annotations);
1160*795d594fSAndroid Build Coastguard Worker if (set_ref_list == nullptr) {
1161*795d594fSAndroid Build Coastguard Worker return 0u;
1162*795d594fSAndroid Build Coastguard Worker }
1163*795d594fSAndroid Build Coastguard Worker return set_ref_list->size_;
1164*795d594fSAndroid Build Coastguard Worker }
1165*795d594fSAndroid Build Coastguard Worker
GetAnnotationForMethodParameter(ArtMethod * method,uint32_t parameter_idx,Handle<mirror::Class> annotation_class)1166*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> GetAnnotationForMethodParameter(ArtMethod* method,
1167*795d594fSAndroid Build Coastguard Worker uint32_t parameter_idx,
1168*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> annotation_class) {
1169*795d594fSAndroid Build Coastguard Worker const DexFile* dex_file = method->GetDexFile();
1170*795d594fSAndroid Build Coastguard Worker const ParameterAnnotationsItem* parameter_annotations = FindAnnotationsItemForMethod(method);
1171*795d594fSAndroid Build Coastguard Worker if (parameter_annotations == nullptr) {
1172*795d594fSAndroid Build Coastguard Worker return nullptr;
1173*795d594fSAndroid Build Coastguard Worker }
1174*795d594fSAndroid Build Coastguard Worker const AnnotationSetRefList* set_ref_list =
1175*795d594fSAndroid Build Coastguard Worker dex_file->GetParameterAnnotationSetRefList(parameter_annotations);
1176*795d594fSAndroid Build Coastguard Worker if (set_ref_list == nullptr) {
1177*795d594fSAndroid Build Coastguard Worker return nullptr;
1178*795d594fSAndroid Build Coastguard Worker }
1179*795d594fSAndroid Build Coastguard Worker if (parameter_idx >= set_ref_list->size_) {
1180*795d594fSAndroid Build Coastguard Worker return nullptr;
1181*795d594fSAndroid Build Coastguard Worker }
1182*795d594fSAndroid Build Coastguard Worker const AnnotationSetRefItem* annotation_set_ref = &set_ref_list->list_[parameter_idx];
1183*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set =
1184*795d594fSAndroid Build Coastguard Worker dex_file->GetSetRefItemItem(annotation_set_ref);
1185*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
1186*795d594fSAndroid Build Coastguard Worker return nullptr;
1187*795d594fSAndroid Build Coastguard Worker }
1188*795d594fSAndroid Build Coastguard Worker return GetAnnotationObjectFromAnnotationSet(ClassData(method),
1189*795d594fSAndroid Build Coastguard Worker annotation_set,
1190*795d594fSAndroid Build Coastguard Worker DexFile::kDexVisibilityRuntime,
1191*795d594fSAndroid Build Coastguard Worker annotation_class);
1192*795d594fSAndroid Build Coastguard Worker }
1193*795d594fSAndroid Build Coastguard Worker
GetParametersMetadataForMethod(ArtMethod * method,MutableHandle<mirror::ObjectArray<mirror::String>> * names,MutableHandle<mirror::IntArray> * access_flags)1194*795d594fSAndroid Build Coastguard Worker bool GetParametersMetadataForMethod(
1195*795d594fSAndroid Build Coastguard Worker ArtMethod* method,
1196*795d594fSAndroid Build Coastguard Worker /*out*/ MutableHandle<mirror::ObjectArray<mirror::String>>* names,
1197*795d594fSAndroid Build Coastguard Worker /*out*/ MutableHandle<mirror::IntArray>* access_flags) {
1198*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set =
1199*795d594fSAndroid Build Coastguard Worker FindAnnotationSetForMethod(method);
1200*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
1201*795d594fSAndroid Build Coastguard Worker return false;
1202*795d594fSAndroid Build Coastguard Worker }
1203*795d594fSAndroid Build Coastguard Worker
1204*795d594fSAndroid Build Coastguard Worker const DexFile* dex_file = method->GetDexFile();
1205*795d594fSAndroid Build Coastguard Worker const AnnotationItem* annotation_item =
1206*795d594fSAndroid Build Coastguard Worker SearchAnnotationSet(*dex_file,
1207*795d594fSAndroid Build Coastguard Worker annotation_set,
1208*795d594fSAndroid Build Coastguard Worker "Ldalvik/annotation/MethodParameters;",
1209*795d594fSAndroid Build Coastguard Worker DexFile::kDexVisibilitySystem);
1210*795d594fSAndroid Build Coastguard Worker if (annotation_item == nullptr) {
1211*795d594fSAndroid Build Coastguard Worker return false;
1212*795d594fSAndroid Build Coastguard Worker }
1213*795d594fSAndroid Build Coastguard Worker
1214*795d594fSAndroid Build Coastguard Worker StackHandleScope<4> hs(Thread::Current());
1215*795d594fSAndroid Build Coastguard Worker
1216*795d594fSAndroid Build Coastguard Worker // Extract the parameters' names String[].
1217*795d594fSAndroid Build Coastguard Worker ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1218*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> string_array_class =
1219*795d594fSAndroid Build Coastguard Worker hs.NewHandle(GetClassRoot<mirror::ObjectArray<mirror::String>>(class_linker));
1220*795d594fSAndroid Build Coastguard Worker DCHECK(string_array_class != nullptr);
1221*795d594fSAndroid Build Coastguard Worker
1222*795d594fSAndroid Build Coastguard Worker ClassData data(method);
1223*795d594fSAndroid Build Coastguard Worker Handle<mirror::Object> names_obj =
1224*795d594fSAndroid Build Coastguard Worker hs.NewHandle(GetAnnotationValue(data,
1225*795d594fSAndroid Build Coastguard Worker annotation_item,
1226*795d594fSAndroid Build Coastguard Worker "names",
1227*795d594fSAndroid Build Coastguard Worker string_array_class,
1228*795d594fSAndroid Build Coastguard Worker DexFile::kDexAnnotationArray));
1229*795d594fSAndroid Build Coastguard Worker if (names_obj == nullptr) {
1230*795d594fSAndroid Build Coastguard Worker return false;
1231*795d594fSAndroid Build Coastguard Worker }
1232*795d594fSAndroid Build Coastguard Worker
1233*795d594fSAndroid Build Coastguard Worker // Extract the parameters' access flags int[].
1234*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> int_array_class(hs.NewHandle(GetClassRoot<mirror::IntArray>(class_linker)));
1235*795d594fSAndroid Build Coastguard Worker DCHECK(int_array_class != nullptr);
1236*795d594fSAndroid Build Coastguard Worker Handle<mirror::Object> access_flags_obj =
1237*795d594fSAndroid Build Coastguard Worker hs.NewHandle(GetAnnotationValue(data,
1238*795d594fSAndroid Build Coastguard Worker annotation_item,
1239*795d594fSAndroid Build Coastguard Worker "accessFlags",
1240*795d594fSAndroid Build Coastguard Worker int_array_class,
1241*795d594fSAndroid Build Coastguard Worker DexFile::kDexAnnotationArray));
1242*795d594fSAndroid Build Coastguard Worker if (access_flags_obj == nullptr) {
1243*795d594fSAndroid Build Coastguard Worker return false;
1244*795d594fSAndroid Build Coastguard Worker }
1245*795d594fSAndroid Build Coastguard Worker
1246*795d594fSAndroid Build Coastguard Worker names->Assign(names_obj->AsObjectArray<mirror::String>());
1247*795d594fSAndroid Build Coastguard Worker access_flags->Assign(access_flags_obj->AsIntArray());
1248*795d594fSAndroid Build Coastguard Worker return true;
1249*795d594fSAndroid Build Coastguard Worker }
1250*795d594fSAndroid Build Coastguard Worker
GetSignatureAnnotationForMethod(ArtMethod * method)1251*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::String>> GetSignatureAnnotationForMethod(ArtMethod* method) {
1252*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set = FindAnnotationSetForMethod(method);
1253*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
1254*795d594fSAndroid Build Coastguard Worker return nullptr;
1255*795d594fSAndroid Build Coastguard Worker }
1256*795d594fSAndroid Build Coastguard Worker return GetSignatureValue(ClassData(method), annotation_set);
1257*795d594fSAndroid Build Coastguard Worker }
1258*795d594fSAndroid Build Coastguard Worker
IsMethodAnnotationPresent(ArtMethod * method,Handle<mirror::Class> annotation_class,uint32_t visibility)1259*795d594fSAndroid Build Coastguard Worker bool IsMethodAnnotationPresent(ArtMethod* method,
1260*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> annotation_class,
1261*795d594fSAndroid Build Coastguard Worker uint32_t visibility /* = DexFile::kDexVisibilityRuntime */) {
1262*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set = FindAnnotationSetForMethod(method);
1263*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
1264*795d594fSAndroid Build Coastguard Worker return false;
1265*795d594fSAndroid Build Coastguard Worker }
1266*795d594fSAndroid Build Coastguard Worker const AnnotationItem* annotation_item = GetAnnotationItemFromAnnotationSet(
1267*795d594fSAndroid Build Coastguard Worker ClassData(method), annotation_set, visibility, annotation_class);
1268*795d594fSAndroid Build Coastguard Worker return annotation_item != nullptr;
1269*795d594fSAndroid Build Coastguard Worker }
1270*795d594fSAndroid Build Coastguard Worker
DCheckNativeAnnotation(const char * descriptor,jclass cls)1271*795d594fSAndroid Build Coastguard Worker static void DCheckNativeAnnotation(const char* descriptor, jclass cls) {
1272*795d594fSAndroid Build Coastguard Worker if (kIsDebugBuild) {
1273*795d594fSAndroid Build Coastguard Worker ScopedObjectAccess soa(Thread::Current());
1274*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> klass = soa.Decode<mirror::Class>(cls);
1275*795d594fSAndroid Build Coastguard Worker ClassLinker* linker = Runtime::Current()->GetClassLinker();
1276*795d594fSAndroid Build Coastguard Worker // WellKnownClasses may not be initialized yet, so `klass` may be null.
1277*795d594fSAndroid Build Coastguard Worker if (klass != nullptr) {
1278*795d594fSAndroid Build Coastguard Worker // Lookup using the boot class path loader should yield the annotation class.
1279*795d594fSAndroid Build Coastguard Worker CHECK_EQ(klass, linker->LookupClass(soa.Self(), descriptor, /* class_loader= */ nullptr));
1280*795d594fSAndroid Build Coastguard Worker }
1281*795d594fSAndroid Build Coastguard Worker }
1282*795d594fSAndroid Build Coastguard Worker }
1283*795d594fSAndroid Build Coastguard Worker
1284*795d594fSAndroid Build Coastguard Worker // Check whether a method from the `dex_file` with the given `annotation_set`
1285*795d594fSAndroid Build Coastguard Worker // is annotated with `annotation_descriptor` with build visibility.
IsMethodBuildAnnotationPresent(const DexFile & dex_file,const AnnotationSetItem & annotation_set,const char * annotation_descriptor,jclass annotation_class)1286*795d594fSAndroid Build Coastguard Worker static bool IsMethodBuildAnnotationPresent(const DexFile& dex_file,
1287*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem& annotation_set,
1288*795d594fSAndroid Build Coastguard Worker const char* annotation_descriptor,
1289*795d594fSAndroid Build Coastguard Worker jclass annotation_class) {
1290*795d594fSAndroid Build Coastguard Worker for (uint32_t i = 0; i < annotation_set.size_; ++i) {
1291*795d594fSAndroid Build Coastguard Worker const AnnotationItem* annotation_item = dex_file.GetAnnotationItem(&annotation_set, i);
1292*795d594fSAndroid Build Coastguard Worker if (!IsVisibilityCompatible(annotation_item->visibility_, DexFile::kDexVisibilityBuild)) {
1293*795d594fSAndroid Build Coastguard Worker continue;
1294*795d594fSAndroid Build Coastguard Worker }
1295*795d594fSAndroid Build Coastguard Worker const uint8_t* annotation = annotation_item->annotation_;
1296*795d594fSAndroid Build Coastguard Worker uint32_t type_index = DecodeUnsignedLeb128(&annotation);
1297*795d594fSAndroid Build Coastguard Worker const char* descriptor = dex_file.GetTypeDescriptor(dex::TypeIndex(type_index));
1298*795d594fSAndroid Build Coastguard Worker if (strcmp(descriptor, annotation_descriptor) == 0) {
1299*795d594fSAndroid Build Coastguard Worker DCheckNativeAnnotation(descriptor, annotation_class);
1300*795d594fSAndroid Build Coastguard Worker return true;
1301*795d594fSAndroid Build Coastguard Worker }
1302*795d594fSAndroid Build Coastguard Worker }
1303*795d594fSAndroid Build Coastguard Worker return false;
1304*795d594fSAndroid Build Coastguard Worker }
1305*795d594fSAndroid Build Coastguard Worker
GetNativeMethodAnnotationAccessFlags(const DexFile & dex_file,const dex::AnnotationSetItem & annotation_set)1306*795d594fSAndroid Build Coastguard Worker static uint32_t GetNativeMethodAnnotationAccessFlags(const DexFile& dex_file,
1307*795d594fSAndroid Build Coastguard Worker const dex::AnnotationSetItem& annotation_set) {
1308*795d594fSAndroid Build Coastguard Worker uint32_t access_flags = 0u;
1309*795d594fSAndroid Build Coastguard Worker if (IsMethodBuildAnnotationPresent(
1310*795d594fSAndroid Build Coastguard Worker dex_file,
1311*795d594fSAndroid Build Coastguard Worker annotation_set,
1312*795d594fSAndroid Build Coastguard Worker "Ldalvik/annotation/optimization/FastNative;",
1313*795d594fSAndroid Build Coastguard Worker WellKnownClasses::dalvik_annotation_optimization_FastNative)) {
1314*795d594fSAndroid Build Coastguard Worker access_flags |= kAccFastNative;
1315*795d594fSAndroid Build Coastguard Worker }
1316*795d594fSAndroid Build Coastguard Worker if (IsMethodBuildAnnotationPresent(
1317*795d594fSAndroid Build Coastguard Worker dex_file,
1318*795d594fSAndroid Build Coastguard Worker annotation_set,
1319*795d594fSAndroid Build Coastguard Worker "Ldalvik/annotation/optimization/CriticalNative;",
1320*795d594fSAndroid Build Coastguard Worker WellKnownClasses::dalvik_annotation_optimization_CriticalNative)) {
1321*795d594fSAndroid Build Coastguard Worker access_flags |= kAccCriticalNative;
1322*795d594fSAndroid Build Coastguard Worker }
1323*795d594fSAndroid Build Coastguard Worker CHECK_NE(access_flags, kAccFastNative | kAccCriticalNative);
1324*795d594fSAndroid Build Coastguard Worker return access_flags;
1325*795d594fSAndroid Build Coastguard Worker }
1326*795d594fSAndroid Build Coastguard Worker
GetNativeMethodAnnotationAccessFlags(const DexFile & dex_file,const dex::ClassDef & class_def,uint32_t method_index)1327*795d594fSAndroid Build Coastguard Worker uint32_t GetNativeMethodAnnotationAccessFlags(const DexFile& dex_file,
1328*795d594fSAndroid Build Coastguard Worker const dex::ClassDef& class_def,
1329*795d594fSAndroid Build Coastguard Worker uint32_t method_index) {
1330*795d594fSAndroid Build Coastguard Worker const dex::AnnotationSetItem* annotation_set =
1331*795d594fSAndroid Build Coastguard Worker FindAnnotationSetForMethod(dex_file, class_def, method_index);
1332*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
1333*795d594fSAndroid Build Coastguard Worker return 0u;
1334*795d594fSAndroid Build Coastguard Worker }
1335*795d594fSAndroid Build Coastguard Worker return GetNativeMethodAnnotationAccessFlags(dex_file, *annotation_set);
1336*795d594fSAndroid Build Coastguard Worker }
1337*795d594fSAndroid Build Coastguard Worker
GetNativeMethodAnnotationAccessFlags(const DexFile & dex_file,const dex::MethodAnnotationsItem & method_annotations)1338*795d594fSAndroid Build Coastguard Worker uint32_t GetNativeMethodAnnotationAccessFlags(const DexFile& dex_file,
1339*795d594fSAndroid Build Coastguard Worker const dex::MethodAnnotationsItem& method_annotations) {
1340*795d594fSAndroid Build Coastguard Worker return GetNativeMethodAnnotationAccessFlags(
1341*795d594fSAndroid Build Coastguard Worker dex_file, *dex_file.GetMethodAnnotationSetItem(method_annotations));
1342*795d594fSAndroid Build Coastguard Worker }
1343*795d594fSAndroid Build Coastguard Worker
MethodIsNeverCompile(const DexFile & dex_file,const dex::AnnotationSetItem & annotation_set)1344*795d594fSAndroid Build Coastguard Worker static bool MethodIsNeverCompile(const DexFile& dex_file,
1345*795d594fSAndroid Build Coastguard Worker const dex::AnnotationSetItem& annotation_set) {
1346*795d594fSAndroid Build Coastguard Worker return IsMethodBuildAnnotationPresent(
1347*795d594fSAndroid Build Coastguard Worker dex_file,
1348*795d594fSAndroid Build Coastguard Worker annotation_set,
1349*795d594fSAndroid Build Coastguard Worker "Ldalvik/annotation/optimization/NeverCompile;",
1350*795d594fSAndroid Build Coastguard Worker WellKnownClasses::dalvik_annotation_optimization_NeverCompile);
1351*795d594fSAndroid Build Coastguard Worker }
1352*795d594fSAndroid Build Coastguard Worker
MethodIsNeverCompile(const DexFile & dex_file,const dex::ClassDef & class_def,uint32_t method_index)1353*795d594fSAndroid Build Coastguard Worker bool MethodIsNeverCompile(const DexFile& dex_file,
1354*795d594fSAndroid Build Coastguard Worker const dex::ClassDef& class_def,
1355*795d594fSAndroid Build Coastguard Worker uint32_t method_index) {
1356*795d594fSAndroid Build Coastguard Worker const dex::AnnotationSetItem* annotation_set =
1357*795d594fSAndroid Build Coastguard Worker FindAnnotationSetForMethod(dex_file, class_def, method_index);
1358*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
1359*795d594fSAndroid Build Coastguard Worker return false;
1360*795d594fSAndroid Build Coastguard Worker }
1361*795d594fSAndroid Build Coastguard Worker return MethodIsNeverCompile(dex_file, *annotation_set);
1362*795d594fSAndroid Build Coastguard Worker }
1363*795d594fSAndroid Build Coastguard Worker
MethodIsNeverCompile(const DexFile & dex_file,const dex::MethodAnnotationsItem & method_annotations)1364*795d594fSAndroid Build Coastguard Worker bool MethodIsNeverCompile(const DexFile& dex_file,
1365*795d594fSAndroid Build Coastguard Worker const dex::MethodAnnotationsItem& method_annotations) {
1366*795d594fSAndroid Build Coastguard Worker return MethodIsNeverCompile(dex_file, *dex_file.GetMethodAnnotationSetItem(method_annotations));
1367*795d594fSAndroid Build Coastguard Worker }
1368*795d594fSAndroid Build Coastguard Worker
MethodIsNeverInline(const DexFile & dex_file,const dex::ClassDef & class_def,uint32_t method_index)1369*795d594fSAndroid Build Coastguard Worker bool MethodIsNeverInline(const DexFile& dex_file,
1370*795d594fSAndroid Build Coastguard Worker const dex::ClassDef& class_def,
1371*795d594fSAndroid Build Coastguard Worker uint32_t method_index) {
1372*795d594fSAndroid Build Coastguard Worker const dex::AnnotationSetItem* annotation_set =
1373*795d594fSAndroid Build Coastguard Worker FindAnnotationSetForMethod(dex_file, class_def, method_index);
1374*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
1375*795d594fSAndroid Build Coastguard Worker return false;
1376*795d594fSAndroid Build Coastguard Worker }
1377*795d594fSAndroid Build Coastguard Worker return IsMethodBuildAnnotationPresent(
1378*795d594fSAndroid Build Coastguard Worker dex_file,
1379*795d594fSAndroid Build Coastguard Worker *annotation_set,
1380*795d594fSAndroid Build Coastguard Worker "Ldalvik/annotation/optimization/NeverInline;",
1381*795d594fSAndroid Build Coastguard Worker WellKnownClasses::dalvik_annotation_optimization_NeverInline);
1382*795d594fSAndroid Build Coastguard Worker }
1383*795d594fSAndroid Build Coastguard Worker
FieldIsReachabilitySensitive(const DexFile & dex_file,const dex::ClassDef & class_def,uint32_t field_index)1384*795d594fSAndroid Build Coastguard Worker bool FieldIsReachabilitySensitive(const DexFile& dex_file,
1385*795d594fSAndroid Build Coastguard Worker const dex::ClassDef& class_def,
1386*795d594fSAndroid Build Coastguard Worker uint32_t field_index)
1387*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
1388*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set =
1389*795d594fSAndroid Build Coastguard Worker FindAnnotationSetForField(dex_file, class_def, field_index);
1390*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
1391*795d594fSAndroid Build Coastguard Worker return false;
1392*795d594fSAndroid Build Coastguard Worker }
1393*795d594fSAndroid Build Coastguard Worker const AnnotationItem* annotation_item = SearchAnnotationSet(dex_file, annotation_set,
1394*795d594fSAndroid Build Coastguard Worker "Ldalvik/annotation/optimization/ReachabilitySensitive;", DexFile::kDexVisibilityRuntime);
1395*795d594fSAndroid Build Coastguard Worker // TODO: We're missing the equivalent of DCheckNativeAnnotation (not a DCHECK). Does it matter?
1396*795d594fSAndroid Build Coastguard Worker return annotation_item != nullptr;
1397*795d594fSAndroid Build Coastguard Worker }
1398*795d594fSAndroid Build Coastguard Worker
MethodIsReachabilitySensitive(const DexFile & dex_file,const dex::ClassDef & class_def,uint32_t method_index)1399*795d594fSAndroid Build Coastguard Worker bool MethodIsReachabilitySensitive(const DexFile& dex_file,
1400*795d594fSAndroid Build Coastguard Worker const dex::ClassDef& class_def,
1401*795d594fSAndroid Build Coastguard Worker uint32_t method_index)
1402*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
1403*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set =
1404*795d594fSAndroid Build Coastguard Worker FindAnnotationSetForMethod(dex_file, class_def, method_index);
1405*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
1406*795d594fSAndroid Build Coastguard Worker return false;
1407*795d594fSAndroid Build Coastguard Worker }
1408*795d594fSAndroid Build Coastguard Worker const AnnotationItem* annotation_item = SearchAnnotationSet(dex_file, annotation_set,
1409*795d594fSAndroid Build Coastguard Worker "Ldalvik/annotation/optimization/ReachabilitySensitive;", DexFile::kDexVisibilityRuntime);
1410*795d594fSAndroid Build Coastguard Worker return annotation_item != nullptr;
1411*795d594fSAndroid Build Coastguard Worker }
1412*795d594fSAndroid Build Coastguard Worker
MethodIsReachabilitySensitive(const DexFile & dex_file,uint32_t method_index)1413*795d594fSAndroid Build Coastguard Worker static bool MethodIsReachabilitySensitive(const DexFile& dex_file,
1414*795d594fSAndroid Build Coastguard Worker uint32_t method_index)
1415*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
1416*795d594fSAndroid Build Coastguard Worker DCHECK(method_index < dex_file.NumMethodIds());
1417*795d594fSAndroid Build Coastguard Worker const dex::MethodId& method_id = dex_file.GetMethodId(method_index);
1418*795d594fSAndroid Build Coastguard Worker dex::TypeIndex class_index = method_id.class_idx_;
1419*795d594fSAndroid Build Coastguard Worker const dex::ClassDef * class_def = dex_file.FindClassDef(class_index);
1420*795d594fSAndroid Build Coastguard Worker return class_def != nullptr
1421*795d594fSAndroid Build Coastguard Worker && MethodIsReachabilitySensitive(dex_file, *class_def, method_index);
1422*795d594fSAndroid Build Coastguard Worker }
1423*795d594fSAndroid Build Coastguard Worker
MethodContainsRSensitiveAccess(const DexFile & dex_file,const dex::ClassDef & class_def,uint32_t method_index)1424*795d594fSAndroid Build Coastguard Worker bool MethodContainsRSensitiveAccess(const DexFile& dex_file,
1425*795d594fSAndroid Build Coastguard Worker const dex::ClassDef& class_def,
1426*795d594fSAndroid Build Coastguard Worker uint32_t method_index)
1427*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
1428*795d594fSAndroid Build Coastguard Worker // TODO: This is too slow to run very regularly. Currently this is only invoked in the
1429*795d594fSAndroid Build Coastguard Worker // presence of @DeadReferenceSafe, which will be rare. In the long run, we need to quickly
1430*795d594fSAndroid Build Coastguard Worker // check once whether a class has any @ReachabilitySensitive annotations. If not, we can
1431*795d594fSAndroid Build Coastguard Worker // immediately return false here for any method in that class.
1432*795d594fSAndroid Build Coastguard Worker uint32_t code_item_offset = dex_file.FindCodeItemOffset(class_def, method_index);
1433*795d594fSAndroid Build Coastguard Worker const dex::CodeItem* code_item = dex_file.GetCodeItem(code_item_offset);
1434*795d594fSAndroid Build Coastguard Worker CodeItemInstructionAccessor accessor(dex_file, code_item);
1435*795d594fSAndroid Build Coastguard Worker if (!accessor.HasCodeItem()) {
1436*795d594fSAndroid Build Coastguard Worker return false;
1437*795d594fSAndroid Build Coastguard Worker }
1438*795d594fSAndroid Build Coastguard Worker for (DexInstructionIterator iter = accessor.begin(); iter != accessor.end(); ++iter) {
1439*795d594fSAndroid Build Coastguard Worker switch (iter->Opcode()) {
1440*795d594fSAndroid Build Coastguard Worker case Instruction::IGET:
1441*795d594fSAndroid Build Coastguard Worker case Instruction::IGET_WIDE:
1442*795d594fSAndroid Build Coastguard Worker case Instruction::IGET_OBJECT:
1443*795d594fSAndroid Build Coastguard Worker case Instruction::IGET_BOOLEAN:
1444*795d594fSAndroid Build Coastguard Worker case Instruction::IGET_BYTE:
1445*795d594fSAndroid Build Coastguard Worker case Instruction::IGET_CHAR:
1446*795d594fSAndroid Build Coastguard Worker case Instruction::IGET_SHORT:
1447*795d594fSAndroid Build Coastguard Worker case Instruction::IPUT:
1448*795d594fSAndroid Build Coastguard Worker case Instruction::IPUT_WIDE:
1449*795d594fSAndroid Build Coastguard Worker case Instruction::IPUT_OBJECT:
1450*795d594fSAndroid Build Coastguard Worker case Instruction::IPUT_BOOLEAN:
1451*795d594fSAndroid Build Coastguard Worker case Instruction::IPUT_BYTE:
1452*795d594fSAndroid Build Coastguard Worker case Instruction::IPUT_CHAR:
1453*795d594fSAndroid Build Coastguard Worker case Instruction::IPUT_SHORT:
1454*795d594fSAndroid Build Coastguard Worker {
1455*795d594fSAndroid Build Coastguard Worker uint32_t field_index = iter->VRegC_22c();
1456*795d594fSAndroid Build Coastguard Worker DCHECK(field_index < dex_file.NumFieldIds());
1457*795d594fSAndroid Build Coastguard Worker // We only guarantee to pay attention to the annotation if it's in the same class,
1458*795d594fSAndroid Build Coastguard Worker // or a containing class, but it's OK to do so in other cases.
1459*795d594fSAndroid Build Coastguard Worker const dex::FieldId& field_id = dex_file.GetFieldId(field_index);
1460*795d594fSAndroid Build Coastguard Worker dex::TypeIndex class_index = field_id.class_idx_;
1461*795d594fSAndroid Build Coastguard Worker const dex::ClassDef * field_class_def = dex_file.FindClassDef(class_index);
1462*795d594fSAndroid Build Coastguard Worker // We do not handle the case in which the field is declared in a superclass, and
1463*795d594fSAndroid Build Coastguard Worker // don't claim to do so. The annotated field should normally be private.
1464*795d594fSAndroid Build Coastguard Worker if (field_class_def != nullptr
1465*795d594fSAndroid Build Coastguard Worker && FieldIsReachabilitySensitive(dex_file, *field_class_def, field_index)) {
1466*795d594fSAndroid Build Coastguard Worker return true;
1467*795d594fSAndroid Build Coastguard Worker }
1468*795d594fSAndroid Build Coastguard Worker }
1469*795d594fSAndroid Build Coastguard Worker break;
1470*795d594fSAndroid Build Coastguard Worker case Instruction::INVOKE_SUPER:
1471*795d594fSAndroid Build Coastguard Worker // Cannot call method in same class. TODO: Try an explicit superclass lookup for
1472*795d594fSAndroid Build Coastguard Worker // better "best effort"?
1473*795d594fSAndroid Build Coastguard Worker break;
1474*795d594fSAndroid Build Coastguard Worker case Instruction::INVOKE_INTERFACE:
1475*795d594fSAndroid Build Coastguard Worker // We handle an interface call just like a virtual call. We will find annotations
1476*795d594fSAndroid Build Coastguard Worker // on interface methods/fields visible to us, but not of the annotation is in a
1477*795d594fSAndroid Build Coastguard Worker // super-interface. Again, we could just ignore it.
1478*795d594fSAndroid Build Coastguard Worker case Instruction::INVOKE_VIRTUAL:
1479*795d594fSAndroid Build Coastguard Worker case Instruction::INVOKE_DIRECT:
1480*795d594fSAndroid Build Coastguard Worker {
1481*795d594fSAndroid Build Coastguard Worker uint32_t called_method_index = iter->VRegB_35c();
1482*795d594fSAndroid Build Coastguard Worker if (MethodIsReachabilitySensitive(dex_file, called_method_index)) {
1483*795d594fSAndroid Build Coastguard Worker return true;
1484*795d594fSAndroid Build Coastguard Worker }
1485*795d594fSAndroid Build Coastguard Worker }
1486*795d594fSAndroid Build Coastguard Worker break;
1487*795d594fSAndroid Build Coastguard Worker case Instruction::INVOKE_INTERFACE_RANGE:
1488*795d594fSAndroid Build Coastguard Worker case Instruction::INVOKE_VIRTUAL_RANGE:
1489*795d594fSAndroid Build Coastguard Worker case Instruction::INVOKE_DIRECT_RANGE:
1490*795d594fSAndroid Build Coastguard Worker {
1491*795d594fSAndroid Build Coastguard Worker uint32_t called_method_index = iter->VRegB_3rc();
1492*795d594fSAndroid Build Coastguard Worker if (MethodIsReachabilitySensitive(dex_file, called_method_index)) {
1493*795d594fSAndroid Build Coastguard Worker return true;
1494*795d594fSAndroid Build Coastguard Worker }
1495*795d594fSAndroid Build Coastguard Worker }
1496*795d594fSAndroid Build Coastguard Worker break;
1497*795d594fSAndroid Build Coastguard Worker // We explicitly do not handle indirect ReachabilitySensitive accesses through VarHandles,
1498*795d594fSAndroid Build Coastguard Worker // etc. Thus we ignore INVOKE_CUSTOM / INVOKE_CUSTOM_RANGE / INVOKE_POLYMORPHIC /
1499*795d594fSAndroid Build Coastguard Worker // INVOKE_POLYMORPHIC_RANGE.
1500*795d594fSAndroid Build Coastguard Worker default:
1501*795d594fSAndroid Build Coastguard Worker // There is no way to add an annotation to array elements, and so far we've encountered no
1502*795d594fSAndroid Build Coastguard Worker // need for that, so we ignore AGET and APUT.
1503*795d594fSAndroid Build Coastguard Worker // It's impractical or impossible to garbage collect a class while one of its methods is
1504*795d594fSAndroid Build Coastguard Worker // on the call stack. We allow ReachabilitySensitive annotations on static methods and
1505*795d594fSAndroid Build Coastguard Worker // fields, but they can be safely ignored.
1506*795d594fSAndroid Build Coastguard Worker break;
1507*795d594fSAndroid Build Coastguard Worker }
1508*795d594fSAndroid Build Coastguard Worker }
1509*795d594fSAndroid Build Coastguard Worker return false;
1510*795d594fSAndroid Build Coastguard Worker }
1511*795d594fSAndroid Build Coastguard Worker
HasDeadReferenceSafeAnnotation(const DexFile & dex_file,const dex::ClassDef & class_def)1512*795d594fSAndroid Build Coastguard Worker bool HasDeadReferenceSafeAnnotation(const DexFile& dex_file,
1513*795d594fSAndroid Build Coastguard Worker const dex::ClassDef& class_def)
1514*795d594fSAndroid Build Coastguard Worker // TODO: This should check outer classes as well.
1515*795d594fSAndroid Build Coastguard Worker // It's conservatively correct not to do so.
1516*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
1517*795d594fSAndroid Build Coastguard Worker const AnnotationsDirectoryItem* annotations_dir =
1518*795d594fSAndroid Build Coastguard Worker dex_file.GetAnnotationsDirectory(class_def);
1519*795d594fSAndroid Build Coastguard Worker if (annotations_dir == nullptr) {
1520*795d594fSAndroid Build Coastguard Worker return false;
1521*795d594fSAndroid Build Coastguard Worker }
1522*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set = dex_file.GetClassAnnotationSet(annotations_dir);
1523*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
1524*795d594fSAndroid Build Coastguard Worker return false;
1525*795d594fSAndroid Build Coastguard Worker }
1526*795d594fSAndroid Build Coastguard Worker const AnnotationItem* annotation_item = SearchAnnotationSet(dex_file, annotation_set,
1527*795d594fSAndroid Build Coastguard Worker "Ldalvik/annotation/optimization/DeadReferenceSafe;", DexFile::kDexVisibilityRuntime);
1528*795d594fSAndroid Build Coastguard Worker return annotation_item != nullptr;
1529*795d594fSAndroid Build Coastguard Worker }
1530*795d594fSAndroid Build Coastguard Worker
GetAnnotationForClass(Handle<mirror::Class> klass,Handle<mirror::Class> annotation_class)1531*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> GetAnnotationForClass(Handle<mirror::Class> klass,
1532*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> annotation_class) {
1533*795d594fSAndroid Build Coastguard Worker ClassData data(klass);
1534*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
1535*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
1536*795d594fSAndroid Build Coastguard Worker return nullptr;
1537*795d594fSAndroid Build Coastguard Worker }
1538*795d594fSAndroid Build Coastguard Worker return GetAnnotationObjectFromAnnotationSet(data,
1539*795d594fSAndroid Build Coastguard Worker annotation_set,
1540*795d594fSAndroid Build Coastguard Worker DexFile::kDexVisibilityRuntime,
1541*795d594fSAndroid Build Coastguard Worker annotation_class);
1542*795d594fSAndroid Build Coastguard Worker }
1543*795d594fSAndroid Build Coastguard Worker
GetAnnotationsForClass(Handle<mirror::Class> klass)1544*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Object>> GetAnnotationsForClass(Handle<mirror::Class> klass) {
1545*795d594fSAndroid Build Coastguard Worker ClassData data(klass);
1546*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
1547*795d594fSAndroid Build Coastguard Worker return ProcessAnnotationSet(data, annotation_set, DexFile::kDexVisibilityRuntime);
1548*795d594fSAndroid Build Coastguard Worker }
1549*795d594fSAndroid Build Coastguard Worker
GetDeclaredClasses(Handle<mirror::Class> klass)1550*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Class>> GetDeclaredClasses(Handle<mirror::Class> klass) {
1551*795d594fSAndroid Build Coastguard Worker return GetAnnotationArrayValue<mirror::Class>(klass,
1552*795d594fSAndroid Build Coastguard Worker "Ldalvik/annotation/MemberClasses;",
1553*795d594fSAndroid Build Coastguard Worker "value");
1554*795d594fSAndroid Build Coastguard Worker }
1555*795d594fSAndroid Build Coastguard Worker
GetDeclaringClass(Handle<mirror::Class> klass)1556*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> GetDeclaringClass(Handle<mirror::Class> klass) {
1557*795d594fSAndroid Build Coastguard Worker ClassData data(klass);
1558*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
1559*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
1560*795d594fSAndroid Build Coastguard Worker return nullptr;
1561*795d594fSAndroid Build Coastguard Worker }
1562*795d594fSAndroid Build Coastguard Worker const AnnotationItem* annotation_item =
1563*795d594fSAndroid Build Coastguard Worker SearchAnnotationSet(data.GetDexFile(), annotation_set, "Ldalvik/annotation/EnclosingClass;",
1564*795d594fSAndroid Build Coastguard Worker DexFile::kDexVisibilitySystem);
1565*795d594fSAndroid Build Coastguard Worker if (annotation_item == nullptr) {
1566*795d594fSAndroid Build Coastguard Worker return nullptr;
1567*795d594fSAndroid Build Coastguard Worker }
1568*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> obj = GetAnnotationValue(data,
1569*795d594fSAndroid Build Coastguard Worker annotation_item,
1570*795d594fSAndroid Build Coastguard Worker "value",
1571*795d594fSAndroid Build Coastguard Worker ScopedNullHandle<mirror::Class>(),
1572*795d594fSAndroid Build Coastguard Worker DexFile::kDexAnnotationType);
1573*795d594fSAndroid Build Coastguard Worker if (obj == nullptr) {
1574*795d594fSAndroid Build Coastguard Worker return nullptr;
1575*795d594fSAndroid Build Coastguard Worker }
1576*795d594fSAndroid Build Coastguard Worker if (!obj->IsClass()) {
1577*795d594fSAndroid Build Coastguard Worker // TypeNotPresentException, throw the NoClassDefFoundError.
1578*795d594fSAndroid Build Coastguard Worker Thread::Current()->SetException(obj->AsThrowable()->GetCause());
1579*795d594fSAndroid Build Coastguard Worker return nullptr;
1580*795d594fSAndroid Build Coastguard Worker }
1581*795d594fSAndroid Build Coastguard Worker return obj->AsClass();
1582*795d594fSAndroid Build Coastguard Worker }
1583*795d594fSAndroid Build Coastguard Worker
GetEnclosingClass(Handle<mirror::Class> klass)1584*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> GetEnclosingClass(Handle<mirror::Class> klass) {
1585*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> declaring_class = GetDeclaringClass(klass);
1586*795d594fSAndroid Build Coastguard Worker if (declaring_class != nullptr || Thread::Current()->IsExceptionPending()) {
1587*795d594fSAndroid Build Coastguard Worker return declaring_class;
1588*795d594fSAndroid Build Coastguard Worker }
1589*795d594fSAndroid Build Coastguard Worker ClassData data(klass);
1590*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
1591*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
1592*795d594fSAndroid Build Coastguard Worker return nullptr;
1593*795d594fSAndroid Build Coastguard Worker }
1594*795d594fSAndroid Build Coastguard Worker const AnnotationItem* annotation_item =
1595*795d594fSAndroid Build Coastguard Worker SearchAnnotationSet(data.GetDexFile(),
1596*795d594fSAndroid Build Coastguard Worker annotation_set,
1597*795d594fSAndroid Build Coastguard Worker "Ldalvik/annotation/EnclosingMethod;",
1598*795d594fSAndroid Build Coastguard Worker DexFile::kDexVisibilitySystem);
1599*795d594fSAndroid Build Coastguard Worker if (annotation_item == nullptr) {
1600*795d594fSAndroid Build Coastguard Worker return nullptr;
1601*795d594fSAndroid Build Coastguard Worker }
1602*795d594fSAndroid Build Coastguard Worker const uint8_t* annotation =
1603*795d594fSAndroid Build Coastguard Worker SearchEncodedAnnotation(data.GetDexFile(), annotation_item->annotation_, "value");
1604*795d594fSAndroid Build Coastguard Worker if (annotation == nullptr) {
1605*795d594fSAndroid Build Coastguard Worker return nullptr;
1606*795d594fSAndroid Build Coastguard Worker }
1607*795d594fSAndroid Build Coastguard Worker DexFile::AnnotationValue annotation_value;
1608*795d594fSAndroid Build Coastguard Worker if (!ProcessAnnotationValue<false>(data,
1609*795d594fSAndroid Build Coastguard Worker &annotation,
1610*795d594fSAndroid Build Coastguard Worker &annotation_value,
1611*795d594fSAndroid Build Coastguard Worker ScopedNullHandle<mirror::Class>(),
1612*795d594fSAndroid Build Coastguard Worker DexFile::kAllRaw)) {
1613*795d594fSAndroid Build Coastguard Worker return nullptr;
1614*795d594fSAndroid Build Coastguard Worker }
1615*795d594fSAndroid Build Coastguard Worker if (annotation_value.type_ != DexFile::kDexAnnotationMethod) {
1616*795d594fSAndroid Build Coastguard Worker return nullptr;
1617*795d594fSAndroid Build Coastguard Worker }
1618*795d594fSAndroid Build Coastguard Worker StackHandleScope<2> hs(Thread::Current());
1619*795d594fSAndroid Build Coastguard Worker ArtMethod* method = Runtime::Current()->GetClassLinker()->ResolveMethodId(
1620*795d594fSAndroid Build Coastguard Worker annotation_value.value_.GetI(),
1621*795d594fSAndroid Build Coastguard Worker hs.NewHandle(data.GetDexCache()),
1622*795d594fSAndroid Build Coastguard Worker hs.NewHandle(data.GetClassLoader()));
1623*795d594fSAndroid Build Coastguard Worker if (method == nullptr) {
1624*795d594fSAndroid Build Coastguard Worker return nullptr;
1625*795d594fSAndroid Build Coastguard Worker }
1626*795d594fSAndroid Build Coastguard Worker return method->GetDeclaringClass();
1627*795d594fSAndroid Build Coastguard Worker }
1628*795d594fSAndroid Build Coastguard Worker
GetEnclosingMethod(Handle<mirror::Class> klass)1629*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> GetEnclosingMethod(Handle<mirror::Class> klass) {
1630*795d594fSAndroid Build Coastguard Worker ClassData data(klass);
1631*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
1632*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
1633*795d594fSAndroid Build Coastguard Worker return nullptr;
1634*795d594fSAndroid Build Coastguard Worker }
1635*795d594fSAndroid Build Coastguard Worker const AnnotationItem* annotation_item =
1636*795d594fSAndroid Build Coastguard Worker SearchAnnotationSet(data.GetDexFile(),
1637*795d594fSAndroid Build Coastguard Worker annotation_set,
1638*795d594fSAndroid Build Coastguard Worker "Ldalvik/annotation/EnclosingMethod;",
1639*795d594fSAndroid Build Coastguard Worker DexFile::kDexVisibilitySystem);
1640*795d594fSAndroid Build Coastguard Worker if (annotation_item == nullptr) {
1641*795d594fSAndroid Build Coastguard Worker return nullptr;
1642*795d594fSAndroid Build Coastguard Worker }
1643*795d594fSAndroid Build Coastguard Worker return GetAnnotationValue(data, annotation_item, "value", ScopedNullHandle<mirror::Class>(),
1644*795d594fSAndroid Build Coastguard Worker DexFile::kDexAnnotationMethod);
1645*795d594fSAndroid Build Coastguard Worker }
1646*795d594fSAndroid Build Coastguard Worker
GetInnerClass(Handle<mirror::Class> klass,ObjPtr<mirror::String> * name)1647*795d594fSAndroid Build Coastguard Worker bool GetInnerClass(Handle<mirror::Class> klass, /*out*/ ObjPtr<mirror::String>* name) {
1648*795d594fSAndroid Build Coastguard Worker ClassData data(klass);
1649*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
1650*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
1651*795d594fSAndroid Build Coastguard Worker return false;
1652*795d594fSAndroid Build Coastguard Worker }
1653*795d594fSAndroid Build Coastguard Worker const AnnotationItem* annotation_item = SearchAnnotationSet(
1654*795d594fSAndroid Build Coastguard Worker data.GetDexFile(),
1655*795d594fSAndroid Build Coastguard Worker annotation_set,
1656*795d594fSAndroid Build Coastguard Worker "Ldalvik/annotation/InnerClass;",
1657*795d594fSAndroid Build Coastguard Worker DexFile::kDexVisibilitySystem);
1658*795d594fSAndroid Build Coastguard Worker if (annotation_item == nullptr) {
1659*795d594fSAndroid Build Coastguard Worker return false;
1660*795d594fSAndroid Build Coastguard Worker }
1661*795d594fSAndroid Build Coastguard Worker const uint8_t* annotation =
1662*795d594fSAndroid Build Coastguard Worker SearchEncodedAnnotation(data.GetDexFile(), annotation_item->annotation_, "name");
1663*795d594fSAndroid Build Coastguard Worker if (annotation == nullptr) {
1664*795d594fSAndroid Build Coastguard Worker return false;
1665*795d594fSAndroid Build Coastguard Worker }
1666*795d594fSAndroid Build Coastguard Worker DexFile::AnnotationValue annotation_value;
1667*795d594fSAndroid Build Coastguard Worker if (!ProcessAnnotationValue<false>(data,
1668*795d594fSAndroid Build Coastguard Worker &annotation,
1669*795d594fSAndroid Build Coastguard Worker &annotation_value,
1670*795d594fSAndroid Build Coastguard Worker ScopedNullHandle<mirror::Class>(),
1671*795d594fSAndroid Build Coastguard Worker DexFile::kAllObjects)) {
1672*795d594fSAndroid Build Coastguard Worker return false;
1673*795d594fSAndroid Build Coastguard Worker }
1674*795d594fSAndroid Build Coastguard Worker if (annotation_value.type_ != DexFile::kDexAnnotationNull &&
1675*795d594fSAndroid Build Coastguard Worker annotation_value.type_ != DexFile::kDexAnnotationString) {
1676*795d594fSAndroid Build Coastguard Worker return false;
1677*795d594fSAndroid Build Coastguard Worker }
1678*795d594fSAndroid Build Coastguard Worker *name = down_cast<mirror::String*>(annotation_value.value_.GetL());
1679*795d594fSAndroid Build Coastguard Worker return true;
1680*795d594fSAndroid Build Coastguard Worker }
1681*795d594fSAndroid Build Coastguard Worker
GetInnerClassFlags(Handle<mirror::Class> klass,uint32_t * flags)1682*795d594fSAndroid Build Coastguard Worker bool GetInnerClassFlags(Handle<mirror::Class> klass, uint32_t* flags) {
1683*795d594fSAndroid Build Coastguard Worker ClassData data(klass);
1684*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
1685*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
1686*795d594fSAndroid Build Coastguard Worker return false;
1687*795d594fSAndroid Build Coastguard Worker }
1688*795d594fSAndroid Build Coastguard Worker const AnnotationItem* annotation_item =
1689*795d594fSAndroid Build Coastguard Worker SearchAnnotationSet(data.GetDexFile(), annotation_set, "Ldalvik/annotation/InnerClass;",
1690*795d594fSAndroid Build Coastguard Worker DexFile::kDexVisibilitySystem);
1691*795d594fSAndroid Build Coastguard Worker if (annotation_item == nullptr) {
1692*795d594fSAndroid Build Coastguard Worker return false;
1693*795d594fSAndroid Build Coastguard Worker }
1694*795d594fSAndroid Build Coastguard Worker const uint8_t* annotation =
1695*795d594fSAndroid Build Coastguard Worker SearchEncodedAnnotation(data.GetDexFile(), annotation_item->annotation_, "accessFlags");
1696*795d594fSAndroid Build Coastguard Worker if (annotation == nullptr) {
1697*795d594fSAndroid Build Coastguard Worker return false;
1698*795d594fSAndroid Build Coastguard Worker }
1699*795d594fSAndroid Build Coastguard Worker DexFile::AnnotationValue annotation_value;
1700*795d594fSAndroid Build Coastguard Worker if (!ProcessAnnotationValue<false>(data,
1701*795d594fSAndroid Build Coastguard Worker &annotation,
1702*795d594fSAndroid Build Coastguard Worker &annotation_value,
1703*795d594fSAndroid Build Coastguard Worker ScopedNullHandle<mirror::Class>(),
1704*795d594fSAndroid Build Coastguard Worker DexFile::kAllRaw)) {
1705*795d594fSAndroid Build Coastguard Worker return false;
1706*795d594fSAndroid Build Coastguard Worker }
1707*795d594fSAndroid Build Coastguard Worker if (annotation_value.type_ != DexFile::kDexAnnotationInt) {
1708*795d594fSAndroid Build Coastguard Worker return false;
1709*795d594fSAndroid Build Coastguard Worker }
1710*795d594fSAndroid Build Coastguard Worker *flags = annotation_value.value_.GetI();
1711*795d594fSAndroid Build Coastguard Worker return true;
1712*795d594fSAndroid Build Coastguard Worker }
1713*795d594fSAndroid Build Coastguard Worker
GetSignatureAnnotationForClass(Handle<mirror::Class> klass)1714*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::String>> GetSignatureAnnotationForClass(
1715*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> klass) {
1716*795d594fSAndroid Build Coastguard Worker ClassData data(klass);
1717*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
1718*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
1719*795d594fSAndroid Build Coastguard Worker return nullptr;
1720*795d594fSAndroid Build Coastguard Worker }
1721*795d594fSAndroid Build Coastguard Worker return GetSignatureValue(data, annotation_set);
1722*795d594fSAndroid Build Coastguard Worker }
1723*795d594fSAndroid Build Coastguard Worker
GetSourceDebugExtension(Handle<mirror::Class> klass)1724*795d594fSAndroid Build Coastguard Worker const char* GetSourceDebugExtension(Handle<mirror::Class> klass) {
1725*795d594fSAndroid Build Coastguard Worker // Before instantiating ClassData, check that klass has a DexCache
1726*795d594fSAndroid Build Coastguard Worker // assigned. The ClassData constructor indirectly dereferences it
1727*795d594fSAndroid Build Coastguard Worker // when calling klass->GetDexFile().
1728*795d594fSAndroid Build Coastguard Worker if (klass->GetDexCache() == nullptr) {
1729*795d594fSAndroid Build Coastguard Worker DCHECK(klass->IsPrimitive() || klass->IsArrayClass());
1730*795d594fSAndroid Build Coastguard Worker return nullptr;
1731*795d594fSAndroid Build Coastguard Worker }
1732*795d594fSAndroid Build Coastguard Worker
1733*795d594fSAndroid Build Coastguard Worker ClassData data(klass);
1734*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
1735*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
1736*795d594fSAndroid Build Coastguard Worker return nullptr;
1737*795d594fSAndroid Build Coastguard Worker }
1738*795d594fSAndroid Build Coastguard Worker
1739*795d594fSAndroid Build Coastguard Worker const AnnotationItem* annotation_item = SearchAnnotationSet(
1740*795d594fSAndroid Build Coastguard Worker data.GetDexFile(),
1741*795d594fSAndroid Build Coastguard Worker annotation_set,
1742*795d594fSAndroid Build Coastguard Worker "Ldalvik/annotation/SourceDebugExtension;",
1743*795d594fSAndroid Build Coastguard Worker DexFile::kDexVisibilitySystem);
1744*795d594fSAndroid Build Coastguard Worker if (annotation_item == nullptr) {
1745*795d594fSAndroid Build Coastguard Worker return nullptr;
1746*795d594fSAndroid Build Coastguard Worker }
1747*795d594fSAndroid Build Coastguard Worker
1748*795d594fSAndroid Build Coastguard Worker const uint8_t* annotation =
1749*795d594fSAndroid Build Coastguard Worker SearchEncodedAnnotation(data.GetDexFile(), annotation_item->annotation_, "value");
1750*795d594fSAndroid Build Coastguard Worker if (annotation == nullptr) {
1751*795d594fSAndroid Build Coastguard Worker return nullptr;
1752*795d594fSAndroid Build Coastguard Worker }
1753*795d594fSAndroid Build Coastguard Worker DexFile::AnnotationValue annotation_value;
1754*795d594fSAndroid Build Coastguard Worker if (!ProcessAnnotationValue<false>(data,
1755*795d594fSAndroid Build Coastguard Worker &annotation,
1756*795d594fSAndroid Build Coastguard Worker &annotation_value,
1757*795d594fSAndroid Build Coastguard Worker ScopedNullHandle<mirror::Class>(),
1758*795d594fSAndroid Build Coastguard Worker DexFile::kAllRaw)) {
1759*795d594fSAndroid Build Coastguard Worker return nullptr;
1760*795d594fSAndroid Build Coastguard Worker }
1761*795d594fSAndroid Build Coastguard Worker if (annotation_value.type_ != DexFile::kDexAnnotationString) {
1762*795d594fSAndroid Build Coastguard Worker return nullptr;
1763*795d594fSAndroid Build Coastguard Worker }
1764*795d594fSAndroid Build Coastguard Worker dex::StringIndex index(static_cast<uint32_t>(annotation_value.value_.GetI()));
1765*795d594fSAndroid Build Coastguard Worker return data.GetDexFile().GetStringData(index);
1766*795d594fSAndroid Build Coastguard Worker }
1767*795d594fSAndroid Build Coastguard Worker
GetNestHost(Handle<mirror::Class> klass)1768*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> GetNestHost(Handle<mirror::Class> klass) {
1769*795d594fSAndroid Build Coastguard Worker ClassData data(klass);
1770*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
1771*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
1772*795d594fSAndroid Build Coastguard Worker return nullptr;
1773*795d594fSAndroid Build Coastguard Worker }
1774*795d594fSAndroid Build Coastguard Worker const AnnotationItem* annotation_item =
1775*795d594fSAndroid Build Coastguard Worker SearchAnnotationSet(data.GetDexFile(), annotation_set, "Ldalvik/annotation/NestHost;",
1776*795d594fSAndroid Build Coastguard Worker DexFile::kDexVisibilitySystem);
1777*795d594fSAndroid Build Coastguard Worker if (annotation_item == nullptr) {
1778*795d594fSAndroid Build Coastguard Worker return nullptr;
1779*795d594fSAndroid Build Coastguard Worker }
1780*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> obj = GetAnnotationValue(data,
1781*795d594fSAndroid Build Coastguard Worker annotation_item,
1782*795d594fSAndroid Build Coastguard Worker "host",
1783*795d594fSAndroid Build Coastguard Worker ScopedNullHandle<mirror::Class>(),
1784*795d594fSAndroid Build Coastguard Worker DexFile::kDexAnnotationType);
1785*795d594fSAndroid Build Coastguard Worker if (obj == nullptr) {
1786*795d594fSAndroid Build Coastguard Worker return nullptr;
1787*795d594fSAndroid Build Coastguard Worker }
1788*795d594fSAndroid Build Coastguard Worker if (!obj->IsClass()) {
1789*795d594fSAndroid Build Coastguard Worker // TypeNotPresentException, throw the NoClassDefFoundError.
1790*795d594fSAndroid Build Coastguard Worker Thread::Current()->SetException(obj->AsThrowable()->GetCause());
1791*795d594fSAndroid Build Coastguard Worker return nullptr;
1792*795d594fSAndroid Build Coastguard Worker }
1793*795d594fSAndroid Build Coastguard Worker return obj->AsClass();
1794*795d594fSAndroid Build Coastguard Worker }
1795*795d594fSAndroid Build Coastguard Worker
GetNestMembers(Handle<mirror::Class> klass)1796*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Class>> GetNestMembers(Handle<mirror::Class> klass) {
1797*795d594fSAndroid Build Coastguard Worker return GetAnnotationArrayValue<mirror::Class>(klass,
1798*795d594fSAndroid Build Coastguard Worker "Ldalvik/annotation/NestMembers;",
1799*795d594fSAndroid Build Coastguard Worker "classes");
1800*795d594fSAndroid Build Coastguard Worker }
1801*795d594fSAndroid Build Coastguard Worker
GetPermittedSubclasses(Handle<mirror::Class> klass)1802*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Class>> GetPermittedSubclasses(Handle<mirror::Class> klass) {
1803*795d594fSAndroid Build Coastguard Worker return GetAnnotationArrayValue<mirror::Class>(klass,
1804*795d594fSAndroid Build Coastguard Worker "Ldalvik/annotation/PermittedSubclasses;",
1805*795d594fSAndroid Build Coastguard Worker "value");
1806*795d594fSAndroid Build Coastguard Worker }
1807*795d594fSAndroid Build Coastguard Worker
getRecordAnnotationElement(Handle<mirror::Class> klass,Handle<mirror::Class> array_class,const char * element_name)1808*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> getRecordAnnotationElement(Handle<mirror::Class> klass,
1809*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> array_class,
1810*795d594fSAndroid Build Coastguard Worker const char* element_name) {
1811*795d594fSAndroid Build Coastguard Worker ClassData data(klass);
1812*795d594fSAndroid Build Coastguard Worker const DexFile& dex_file = klass->GetDexFile();
1813*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
1814*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
1815*795d594fSAndroid Build Coastguard Worker return nullptr;
1816*795d594fSAndroid Build Coastguard Worker }
1817*795d594fSAndroid Build Coastguard Worker const AnnotationItem* annotation_item = SearchAnnotationSet(
1818*795d594fSAndroid Build Coastguard Worker dex_file, annotation_set, "Ldalvik/annotation/Record;", DexFile::kDexVisibilitySystem);
1819*795d594fSAndroid Build Coastguard Worker if (annotation_item == nullptr) {
1820*795d594fSAndroid Build Coastguard Worker return nullptr;
1821*795d594fSAndroid Build Coastguard Worker }
1822*795d594fSAndroid Build Coastguard Worker const uint8_t* annotation =
1823*795d594fSAndroid Build Coastguard Worker SearchEncodedAnnotation(dex_file, annotation_item->annotation_, element_name);
1824*795d594fSAndroid Build Coastguard Worker if (annotation == nullptr) {
1825*795d594fSAndroid Build Coastguard Worker return nullptr;
1826*795d594fSAndroid Build Coastguard Worker }
1827*795d594fSAndroid Build Coastguard Worker DexFile::AnnotationValue annotation_value;
1828*795d594fSAndroid Build Coastguard Worker bool result = Runtime::Current()->IsActiveTransaction()
1829*795d594fSAndroid Build Coastguard Worker ? ProcessAnnotationValue<true>(data,
1830*795d594fSAndroid Build Coastguard Worker &annotation,
1831*795d594fSAndroid Build Coastguard Worker &annotation_value,
1832*795d594fSAndroid Build Coastguard Worker array_class,
1833*795d594fSAndroid Build Coastguard Worker DexFile::kPrimitivesOrObjects)
1834*795d594fSAndroid Build Coastguard Worker : ProcessAnnotationValue<false>(data,
1835*795d594fSAndroid Build Coastguard Worker &annotation,
1836*795d594fSAndroid Build Coastguard Worker &annotation_value,
1837*795d594fSAndroid Build Coastguard Worker array_class,
1838*795d594fSAndroid Build Coastguard Worker DexFile::kPrimitivesOrObjects);
1839*795d594fSAndroid Build Coastguard Worker if (!result) {
1840*795d594fSAndroid Build Coastguard Worker return nullptr;
1841*795d594fSAndroid Build Coastguard Worker }
1842*795d594fSAndroid Build Coastguard Worker return annotation_value.value_.GetL();
1843*795d594fSAndroid Build Coastguard Worker }
1844*795d594fSAndroid Build Coastguard Worker
IsClassAnnotationPresent(Handle<mirror::Class> klass,Handle<mirror::Class> annotation_class)1845*795d594fSAndroid Build Coastguard Worker bool IsClassAnnotationPresent(Handle<mirror::Class> klass, Handle<mirror::Class> annotation_class) {
1846*795d594fSAndroid Build Coastguard Worker ClassData data(klass);
1847*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
1848*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
1849*795d594fSAndroid Build Coastguard Worker return false;
1850*795d594fSAndroid Build Coastguard Worker }
1851*795d594fSAndroid Build Coastguard Worker const AnnotationItem* annotation_item = GetAnnotationItemFromAnnotationSet(
1852*795d594fSAndroid Build Coastguard Worker data, annotation_set, DexFile::kDexVisibilityRuntime, annotation_class);
1853*795d594fSAndroid Build Coastguard Worker return annotation_item != nullptr;
1854*795d594fSAndroid Build Coastguard Worker }
1855*795d594fSAndroid Build Coastguard Worker
GetLineNumFromPC(const DexFile * dex_file,ArtMethod * method,uint32_t rel_pc)1856*795d594fSAndroid Build Coastguard Worker int32_t GetLineNumFromPC(const DexFile* dex_file, ArtMethod* method, uint32_t rel_pc) {
1857*795d594fSAndroid Build Coastguard Worker // For native method, lineno should be -2 to indicate it is native. Note that
1858*795d594fSAndroid Build Coastguard Worker // "line number == -2" is how libcore tells from StackTraceElement.
1859*795d594fSAndroid Build Coastguard Worker if (!method->HasCodeItem()) {
1860*795d594fSAndroid Build Coastguard Worker return -2;
1861*795d594fSAndroid Build Coastguard Worker }
1862*795d594fSAndroid Build Coastguard Worker
1863*795d594fSAndroid Build Coastguard Worker CodeItemDebugInfoAccessor accessor(method->DexInstructionDebugInfo());
1864*795d594fSAndroid Build Coastguard Worker DCHECK(accessor.HasCodeItem()) << method->PrettyMethod() << " " << dex_file->GetLocation();
1865*795d594fSAndroid Build Coastguard Worker
1866*795d594fSAndroid Build Coastguard Worker // A method with no line number info should return -1
1867*795d594fSAndroid Build Coastguard Worker uint32_t line_num = -1;
1868*795d594fSAndroid Build Coastguard Worker accessor.GetLineNumForPc(rel_pc, &line_num);
1869*795d594fSAndroid Build Coastguard Worker return line_num;
1870*795d594fSAndroid Build Coastguard Worker }
1871*795d594fSAndroid Build Coastguard Worker
1872*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive>
ReadValueToField(ArtField * field) const1873*795d594fSAndroid Build Coastguard Worker void RuntimeEncodedStaticFieldValueIterator::ReadValueToField(ArtField* field) const {
1874*795d594fSAndroid Build Coastguard Worker DCHECK(dex_cache_ != nullptr);
1875*795d594fSAndroid Build Coastguard Worker switch (type_) {
1876*795d594fSAndroid Build Coastguard Worker case kBoolean: field->SetBoolean<kTransactionActive>(field->GetDeclaringClass(), jval_.z);
1877*795d594fSAndroid Build Coastguard Worker break;
1878*795d594fSAndroid Build Coastguard Worker case kByte: field->SetByte<kTransactionActive>(field->GetDeclaringClass(), jval_.b); break;
1879*795d594fSAndroid Build Coastguard Worker case kShort: field->SetShort<kTransactionActive>(field->GetDeclaringClass(), jval_.s); break;
1880*795d594fSAndroid Build Coastguard Worker case kChar: field->SetChar<kTransactionActive>(field->GetDeclaringClass(), jval_.c); break;
1881*795d594fSAndroid Build Coastguard Worker case kInt: field->SetInt<kTransactionActive>(field->GetDeclaringClass(), jval_.i); break;
1882*795d594fSAndroid Build Coastguard Worker case kLong: field->SetLong<kTransactionActive>(field->GetDeclaringClass(), jval_.j); break;
1883*795d594fSAndroid Build Coastguard Worker case kFloat: field->SetFloat<kTransactionActive>(field->GetDeclaringClass(), jval_.f); break;
1884*795d594fSAndroid Build Coastguard Worker case kDouble: field->SetDouble<kTransactionActive>(field->GetDeclaringClass(), jval_.d); break;
1885*795d594fSAndroid Build Coastguard Worker case kNull: field->SetObject<kTransactionActive>(field->GetDeclaringClass(), nullptr); break;
1886*795d594fSAndroid Build Coastguard Worker case kString: {
1887*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::String> resolved = linker_->ResolveString(dex::StringIndex(jval_.i),
1888*795d594fSAndroid Build Coastguard Worker dex_cache_);
1889*795d594fSAndroid Build Coastguard Worker field->SetObject<kTransactionActive>(field->GetDeclaringClass(), resolved);
1890*795d594fSAndroid Build Coastguard Worker break;
1891*795d594fSAndroid Build Coastguard Worker }
1892*795d594fSAndroid Build Coastguard Worker case kType: {
1893*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> resolved = linker_->ResolveType(dex::TypeIndex(jval_.i),
1894*795d594fSAndroid Build Coastguard Worker dex_cache_,
1895*795d594fSAndroid Build Coastguard Worker class_loader_);
1896*795d594fSAndroid Build Coastguard Worker field->SetObject<kTransactionActive>(field->GetDeclaringClass(), resolved);
1897*795d594fSAndroid Build Coastguard Worker break;
1898*795d594fSAndroid Build Coastguard Worker }
1899*795d594fSAndroid Build Coastguard Worker default: UNIMPLEMENTED(FATAL) << ": type " << type_;
1900*795d594fSAndroid Build Coastguard Worker }
1901*795d594fSAndroid Build Coastguard Worker }
1902*795d594fSAndroid Build Coastguard Worker template
1903*795d594fSAndroid Build Coastguard Worker void RuntimeEncodedStaticFieldValueIterator::ReadValueToField<true>(ArtField* field) const;
1904*795d594fSAndroid Build Coastguard Worker template
1905*795d594fSAndroid Build Coastguard Worker void RuntimeEncodedStaticFieldValueIterator::ReadValueToField<false>(ArtField* field) const;
1906*795d594fSAndroid Build Coastguard Worker
VisitElement(AnnotationVisitor * visitor,const char * element_name,uint8_t depth,uint32_t element_index,const DexFile::AnnotationValue & annotation_value)1907*795d594fSAndroid Build Coastguard Worker inline static VisitorStatus VisitElement(AnnotationVisitor* visitor,
1908*795d594fSAndroid Build Coastguard Worker const char* element_name,
1909*795d594fSAndroid Build Coastguard Worker uint8_t depth,
1910*795d594fSAndroid Build Coastguard Worker uint32_t element_index,
1911*795d594fSAndroid Build Coastguard Worker const DexFile::AnnotationValue& annotation_value)
1912*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
1913*795d594fSAndroid Build Coastguard Worker if (depth == 0) {
1914*795d594fSAndroid Build Coastguard Worker return visitor->VisitAnnotationElement(
1915*795d594fSAndroid Build Coastguard Worker element_name, annotation_value.type_, annotation_value.value_);
1916*795d594fSAndroid Build Coastguard Worker } else {
1917*795d594fSAndroid Build Coastguard Worker return visitor->VisitArrayElement(
1918*795d594fSAndroid Build Coastguard Worker depth - 1, element_index, annotation_value.type_, annotation_value.value_);
1919*795d594fSAndroid Build Coastguard Worker }
1920*795d594fSAndroid Build Coastguard Worker }
1921*795d594fSAndroid Build Coastguard Worker
VisitEncodedValue(const ClassData & klass,const DexFile & dex_file,const uint8_t ** annotation_ptr,AnnotationVisitor * visitor,const char * element_name,uint8_t depth,uint32_t element_index)1922*795d594fSAndroid Build Coastguard Worker static VisitorStatus VisitEncodedValue(const ClassData& klass,
1923*795d594fSAndroid Build Coastguard Worker const DexFile& dex_file,
1924*795d594fSAndroid Build Coastguard Worker const uint8_t** annotation_ptr,
1925*795d594fSAndroid Build Coastguard Worker AnnotationVisitor* visitor,
1926*795d594fSAndroid Build Coastguard Worker const char* element_name,
1927*795d594fSAndroid Build Coastguard Worker uint8_t depth,
1928*795d594fSAndroid Build Coastguard Worker uint32_t element_index)
1929*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
1930*795d594fSAndroid Build Coastguard Worker DexFile::AnnotationValue annotation_value;
1931*795d594fSAndroid Build Coastguard Worker // kTransactionActive is safe because the result_style is kAllRaw.
1932*795d594fSAndroid Build Coastguard Worker bool is_consumed = ProcessAnnotationValue<false>(klass,
1933*795d594fSAndroid Build Coastguard Worker annotation_ptr,
1934*795d594fSAndroid Build Coastguard Worker &annotation_value,
1935*795d594fSAndroid Build Coastguard Worker ScopedNullHandle<mirror::Class>(),
1936*795d594fSAndroid Build Coastguard Worker DexFile::kAllRaw);
1937*795d594fSAndroid Build Coastguard Worker
1938*795d594fSAndroid Build Coastguard Worker VisitorStatus status =
1939*795d594fSAndroid Build Coastguard Worker VisitElement(visitor, element_name, depth, element_index, annotation_value);
1940*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(visitor->HasError())) {
1941*795d594fSAndroid Build Coastguard Worker // Stop visiting since we won't verify the class anyway.
1942*795d594fSAndroid Build Coastguard Worker return annotations::VisitorStatus::kVisitBreak;
1943*795d594fSAndroid Build Coastguard Worker }
1944*795d594fSAndroid Build Coastguard Worker
1945*795d594fSAndroid Build Coastguard Worker switch (annotation_value.type_) {
1946*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationArray: {
1947*795d594fSAndroid Build Coastguard Worker DCHECK(!is_consumed) << " unexpected consumption of array-typed element '" << element_name
1948*795d594fSAndroid Build Coastguard Worker << "' annotating the class " << klass.GetRealClass()->PrettyClass();
1949*795d594fSAndroid Build Coastguard Worker SkipEncodedValueHeaderByte(annotation_ptr);
1950*795d594fSAndroid Build Coastguard Worker uint32_t array_size = DecodeUnsignedLeb128(annotation_ptr);
1951*795d594fSAndroid Build Coastguard Worker uint8_t next_depth = depth + 1;
1952*795d594fSAndroid Build Coastguard Worker VisitorStatus element_status = (status == VisitorStatus::kVisitInner) ?
1953*795d594fSAndroid Build Coastguard Worker VisitorStatus::kVisitNext :
1954*795d594fSAndroid Build Coastguard Worker VisitorStatus::kVisitBreak;
1955*795d594fSAndroid Build Coastguard Worker uint32_t i = 0;
1956*795d594fSAndroid Build Coastguard Worker for (; i < array_size && element_status != VisitorStatus::kVisitBreak; ++i) {
1957*795d594fSAndroid Build Coastguard Worker element_status = VisitEncodedValue(
1958*795d594fSAndroid Build Coastguard Worker klass, dex_file, annotation_ptr, visitor, element_name, next_depth, i);
1959*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(visitor->HasError())) {
1960*795d594fSAndroid Build Coastguard Worker // Stop visiting since we won't verify the class anyway.
1961*795d594fSAndroid Build Coastguard Worker return annotations::VisitorStatus::kVisitBreak;
1962*795d594fSAndroid Build Coastguard Worker }
1963*795d594fSAndroid Build Coastguard Worker }
1964*795d594fSAndroid Build Coastguard Worker for (; i < array_size; ++i) {
1965*795d594fSAndroid Build Coastguard Worker SkipAnnotationValue(dex_file, annotation_ptr);
1966*795d594fSAndroid Build Coastguard Worker }
1967*795d594fSAndroid Build Coastguard Worker break;
1968*795d594fSAndroid Build Coastguard Worker }
1969*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationAnnotation: {
1970*795d594fSAndroid Build Coastguard Worker DCHECK(!is_consumed) << " unexpected consumption of annotation-typed element '"
1971*795d594fSAndroid Build Coastguard Worker << element_name << "' annotating the class "
1972*795d594fSAndroid Build Coastguard Worker << klass.GetRealClass()->PrettyClass();
1973*795d594fSAndroid Build Coastguard Worker SkipEncodedValueHeaderByte(annotation_ptr);
1974*795d594fSAndroid Build Coastguard Worker DecodeUnsignedLeb128(annotation_ptr); // unused type_index
1975*795d594fSAndroid Build Coastguard Worker uint32_t size = DecodeUnsignedLeb128(annotation_ptr);
1976*795d594fSAndroid Build Coastguard Worker for (; size != 0u; --size) {
1977*795d594fSAndroid Build Coastguard Worker DecodeUnsignedLeb128(annotation_ptr); // unused element_name_index
1978*795d594fSAndroid Build Coastguard Worker SkipAnnotationValue(dex_file, annotation_ptr);
1979*795d594fSAndroid Build Coastguard Worker }
1980*795d594fSAndroid Build Coastguard Worker break;
1981*795d594fSAndroid Build Coastguard Worker }
1982*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationMethodType:
1983*795d594fSAndroid Build Coastguard Worker case DexFile::kDexAnnotationMethodHandle:
1984*795d594fSAndroid Build Coastguard Worker // kDexAnnotationMethodType and kDexAnnotationMethodHandle return false in order to not
1985*795d594fSAndroid Build Coastguard Worker // crash the process but they are unexpected here.
1986*795d594fSAndroid Build Coastguard Worker visitor->SetErrorMsg(StringPrintf(
1987*795d594fSAndroid Build Coastguard Worker "Encountered unexpected annotation element type 0x%02x of %s for the class %s",
1988*795d594fSAndroid Build Coastguard Worker annotation_value.type_,
1989*795d594fSAndroid Build Coastguard Worker element_name,
1990*795d594fSAndroid Build Coastguard Worker klass.GetRealClass()->PrettyClass().c_str()));
1991*795d594fSAndroid Build Coastguard Worker // Stop visiting since we won't verify the class anyway.
1992*795d594fSAndroid Build Coastguard Worker return annotations::VisitorStatus::kVisitBreak;
1993*795d594fSAndroid Build Coastguard Worker default: {
1994*795d594fSAndroid Build Coastguard Worker // kDexAnnotationArray and kDexAnnotationAnnotation are the only 2 known value_types causing
1995*795d594fSAndroid Build Coastguard Worker // ProcessAnnotationValue return false. For other value_types, we shouldn't need to iterate
1996*795d594fSAndroid Build Coastguard Worker // over annotation_ptr and skip the value here.
1997*795d594fSAndroid Build Coastguard Worker DCHECK(is_consumed) << StringPrintf(
1998*795d594fSAndroid Build Coastguard Worker "consumed annotation element type 0x%02x of %s for the class %s",
1999*795d594fSAndroid Build Coastguard Worker annotation_value.type_,
2000*795d594fSAndroid Build Coastguard Worker element_name,
2001*795d594fSAndroid Build Coastguard Worker klass.GetRealClass()->PrettyClass().c_str());
2002*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(!is_consumed)) {
2003*795d594fSAndroid Build Coastguard Worker SkipAnnotationValue(dex_file, annotation_ptr);
2004*795d594fSAndroid Build Coastguard Worker }
2005*795d594fSAndroid Build Coastguard Worker break;
2006*795d594fSAndroid Build Coastguard Worker }
2007*795d594fSAndroid Build Coastguard Worker }
2008*795d594fSAndroid Build Coastguard Worker
2009*795d594fSAndroid Build Coastguard Worker return status;
2010*795d594fSAndroid Build Coastguard Worker }
2011*795d594fSAndroid Build Coastguard Worker
VisitClassAnnotations(Handle<mirror::Class> klass,AnnotationVisitor * visitor)2012*795d594fSAndroid Build Coastguard Worker void VisitClassAnnotations(Handle<mirror::Class> klass, AnnotationVisitor* visitor) {
2013*795d594fSAndroid Build Coastguard Worker ClassData data(klass);
2014*795d594fSAndroid Build Coastguard Worker const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
2015*795d594fSAndroid Build Coastguard Worker if (annotation_set == nullptr) {
2016*795d594fSAndroid Build Coastguard Worker return;
2017*795d594fSAndroid Build Coastguard Worker }
2018*795d594fSAndroid Build Coastguard Worker
2019*795d594fSAndroid Build Coastguard Worker const DexFile& dex_file = data.GetDexFile();
2020*795d594fSAndroid Build Coastguard Worker for (uint32_t i = 0; i < annotation_set->size_; ++i) {
2021*795d594fSAndroid Build Coastguard Worker const AnnotationItem* annotation_item = dex_file.GetAnnotationItem(annotation_set, i);
2022*795d594fSAndroid Build Coastguard Worker uint8_t visibility = annotation_item->visibility_;
2023*795d594fSAndroid Build Coastguard Worker const uint8_t* annotation = annotation_item->annotation_;
2024*795d594fSAndroid Build Coastguard Worker uint32_t type_index = DecodeUnsignedLeb128(&annotation);
2025*795d594fSAndroid Build Coastguard Worker const char* annotation_descriptor = dex_file.GetTypeDescriptor(dex::TypeIndex(type_index));
2026*795d594fSAndroid Build Coastguard Worker VisitorStatus status = visitor->VisitAnnotation(annotation_descriptor, visibility);
2027*795d594fSAndroid Build Coastguard Worker switch (status) {
2028*795d594fSAndroid Build Coastguard Worker case VisitorStatus::kVisitBreak:
2029*795d594fSAndroid Build Coastguard Worker return;
2030*795d594fSAndroid Build Coastguard Worker case VisitorStatus::kVisitNext:
2031*795d594fSAndroid Build Coastguard Worker continue;
2032*795d594fSAndroid Build Coastguard Worker case VisitorStatus::kVisitInner:
2033*795d594fSAndroid Build Coastguard Worker // Visit the annotation elements
2034*795d594fSAndroid Build Coastguard Worker break;
2035*795d594fSAndroid Build Coastguard Worker }
2036*795d594fSAndroid Build Coastguard Worker
2037*795d594fSAndroid Build Coastguard Worker uint32_t size = DecodeUnsignedLeb128(&annotation);
2038*795d594fSAndroid Build Coastguard Worker while (size != 0) {
2039*795d594fSAndroid Build Coastguard Worker uint32_t element_name_index = DecodeUnsignedLeb128(&annotation);
2040*795d594fSAndroid Build Coastguard Worker const char* element_name =
2041*795d594fSAndroid Build Coastguard Worker dex_file.GetStringData(dex_file.GetStringId(dex::StringIndex(element_name_index)));
2042*795d594fSAndroid Build Coastguard Worker
2043*795d594fSAndroid Build Coastguard Worker status = VisitEncodedValue(
2044*795d594fSAndroid Build Coastguard Worker data, dex_file, &annotation, visitor, element_name, /*depth=*/0, /*ignored*/ 0);
2045*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(visitor->HasError())) {
2046*795d594fSAndroid Build Coastguard Worker // Encountered an error, bail out since we won't verify the class anyway.
2047*795d594fSAndroid Build Coastguard Worker return;
2048*795d594fSAndroid Build Coastguard Worker }
2049*795d594fSAndroid Build Coastguard Worker if (status == VisitorStatus::kVisitBreak) {
2050*795d594fSAndroid Build Coastguard Worker break;
2051*795d594fSAndroid Build Coastguard Worker }
2052*795d594fSAndroid Build Coastguard Worker size--;
2053*795d594fSAndroid Build Coastguard Worker }
2054*795d594fSAndroid Build Coastguard Worker }
2055*795d594fSAndroid Build Coastguard Worker }
2056*795d594fSAndroid Build Coastguard Worker
2057*795d594fSAndroid Build Coastguard Worker } // namespace annotations
2058*795d594fSAndroid Build Coastguard Worker
2059*795d594fSAndroid Build Coastguard Worker } // namespace art
2060