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