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-inl.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 element_object = (pointer_size == PointerSize::k64)
529 ? mirror::Constructor::CreateFromArtMethod<PointerSize::k64>(self, method)
530 : mirror::Constructor::CreateFromArtMethod<PointerSize::k32>(self, method);
531 } else {
532 element_object = (pointer_size == PointerSize::k64)
533 ? mirror::Method::CreateFromArtMethod<PointerSize::k64>(self, method)
534 : mirror::Method::CreateFromArtMethod<PointerSize::k32>(self, method);
535 }
536 if (element_object == nullptr) {
537 return false;
538 }
539 }
540 break;
541 }
542 case DexFile::kDexAnnotationField: {
543 uint32_t index = DexFile::ReadUnsignedInt(annotation, value_arg, false);
544 if (result_style == DexFile::kAllRaw) {
545 annotation_value->value_.SetI(index);
546 } else {
547 StackHandleScope<2> hs(self);
548 ArtField* field = Runtime::Current()->GetClassLinker()->ResolveFieldJLS(
549 index,
550 hs.NewHandle(klass.GetDexCache()),
551 hs.NewHandle(klass.GetClassLoader()));
552 if (field == nullptr) {
553 return false;
554 }
555 set_object = true;
556 element_object = mirror::Field::CreateFromArtField(self, field, true);
557 if (element_object == nullptr) {
558 return false;
559 }
560 }
561 break;
562 }
563 case DexFile::kDexAnnotationEnum: {
564 uint32_t index = DexFile::ReadUnsignedInt(annotation, value_arg, false);
565 if (result_style == DexFile::kAllRaw) {
566 annotation_value->value_.SetI(index);
567 } else {
568 StackHandleScope<3> hs(self);
569 ArtField* enum_field = Runtime::Current()->GetClassLinker()->ResolveField(
570 index,
571 hs.NewHandle(klass.GetDexCache()),
572 hs.NewHandle(klass.GetClassLoader()),
573 true);
574 if (enum_field == nullptr) {
575 return false;
576 } else {
577 Handle<mirror::Class> field_class(hs.NewHandle(enum_field->GetDeclaringClass()));
578 Runtime::Current()->GetClassLinker()->EnsureInitialized(self, field_class, true, true);
579 element_object = enum_field->GetObject(field_class.Get());
580 set_object = true;
581 }
582 }
583 break;
584 }
585 case DexFile::kDexAnnotationArray:
586 if (result_style == DexFile::kAllRaw || array_class == nullptr) {
587 return false;
588 } else {
589 ScopedObjectAccessUnchecked soa(self);
590 StackHandleScope<2> hs(self);
591 uint32_t size = DecodeUnsignedLeb128(&annotation);
592 Handle<mirror::Class> component_type(hs.NewHandle(array_class->GetComponentType()));
593 Handle<mirror::Array> new_array(hs.NewHandle(mirror::Array::Alloc(
594 self, array_class.Get(), size, array_class->GetComponentSizeShift(),
595 Runtime::Current()->GetHeap()->GetCurrentAllocator())));
596 if (new_array == nullptr) {
597 LOG(ERROR) << "Annotation element array allocation failed with size " << size;
598 return false;
599 }
600 DexFile::AnnotationValue new_annotation_value;
601 for (uint32_t i = 0; i < size; ++i) {
602 if (!ProcessAnnotationValue<kTransactionActive>(klass,
603 &annotation,
604 &new_annotation_value,
605 component_type,
606 DexFile::kPrimitivesOrObjects)) {
607 return false;
608 }
609 if (!component_type->IsPrimitive()) {
610 ObjPtr<mirror::Object> obj = new_annotation_value.value_.GetL();
611 new_array->AsObjectArray<mirror::Object>()->
612 SetWithoutChecks<kTransactionActive>(i, obj);
613 } else {
614 switch (new_annotation_value.type_) {
615 case DexFile::kDexAnnotationByte:
616 new_array->AsByteArray()->SetWithoutChecks<kTransactionActive>(
617 i, new_annotation_value.value_.GetB());
618 break;
619 case DexFile::kDexAnnotationShort:
620 new_array->AsShortArray()->SetWithoutChecks<kTransactionActive>(
621 i, new_annotation_value.value_.GetS());
622 break;
623 case DexFile::kDexAnnotationChar:
624 new_array->AsCharArray()->SetWithoutChecks<kTransactionActive>(
625 i, new_annotation_value.value_.GetC());
626 break;
627 case DexFile::kDexAnnotationInt:
628 new_array->AsIntArray()->SetWithoutChecks<kTransactionActive>(
629 i, new_annotation_value.value_.GetI());
630 break;
631 case DexFile::kDexAnnotationLong:
632 new_array->AsLongArray()->SetWithoutChecks<kTransactionActive>(
633 i, new_annotation_value.value_.GetJ());
634 break;
635 case DexFile::kDexAnnotationFloat:
636 new_array->AsFloatArray()->SetWithoutChecks<kTransactionActive>(
637 i, new_annotation_value.value_.GetF());
638 break;
639 case DexFile::kDexAnnotationDouble:
640 new_array->AsDoubleArray()->SetWithoutChecks<kTransactionActive>(
641 i, new_annotation_value.value_.GetD());
642 break;
643 case DexFile::kDexAnnotationBoolean:
644 new_array->AsBooleanArray()->SetWithoutChecks<kTransactionActive>(
645 i, new_annotation_value.value_.GetZ());
646 break;
647 default:
648 LOG(FATAL) << "Found invalid annotation value type while building annotation array";
649 return false;
650 }
651 }
652 }
653 element_object = new_array.Get();
654 set_object = true;
655 width = 0;
656 }
657 break;
658 case DexFile::kDexAnnotationAnnotation:
659 if (result_style == DexFile::kAllRaw) {
660 return false;
661 }
662 element_object = ProcessEncodedAnnotation(klass, &annotation);
663 if (element_object == nullptr) {
664 return false;
665 }
666 set_object = true;
667 width = 0;
668 break;
669 case DexFile::kDexAnnotationNull:
670 if (result_style == DexFile::kAllRaw) {
671 annotation_value->value_.SetI(0);
672 } else {
673 CHECK(element_object == nullptr);
674 set_object = true;
675 }
676 width = 0;
677 break;
678 default:
679 LOG(ERROR) << StringPrintf("Bad annotation element value type 0x%02x", value_type);
680 return false;
681 }
682
683 annotation += width;
684 *annotation_ptr = annotation;
685
686 if (result_style == DexFile::kAllObjects && primitive_type != Primitive::kPrimVoid) {
687 element_object = BoxPrimitive(primitive_type, annotation_value->value_);
688 set_object = true;
689 }
690
691 if (set_object) {
692 annotation_value->value_.SetL(element_object);
693 }
694
695 return true;
696 }
697
CreateAnnotationMember(const ClassData & klass,Handle<mirror::Class> annotation_class,const uint8_t ** annotation)698 ObjPtr<mirror::Object> CreateAnnotationMember(const ClassData& klass,
699 Handle<mirror::Class> annotation_class,
700 const uint8_t** annotation) {
701 const DexFile& dex_file = klass.GetDexFile();
702 Thread* self = Thread::Current();
703 ScopedObjectAccessUnchecked soa(self);
704 StackHandleScope<5> hs(self);
705 uint32_t element_name_index = DecodeUnsignedLeb128(annotation);
706 const char* name = dex_file.StringDataByIdx(dex::StringIndex(element_name_index));
707 Handle<mirror::String> string_name(
708 hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, name)));
709
710 PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
711 ArtMethod* annotation_method =
712 annotation_class->FindDeclaredVirtualMethodByName(name, pointer_size);
713 if (annotation_method == nullptr) {
714 return nullptr;
715 }
716 Handle<mirror::Class> method_return(hs.NewHandle(annotation_method->ResolveReturnType()));
717
718 DexFile::AnnotationValue annotation_value;
719 if (!ProcessAnnotationValue<false>(klass,
720 annotation,
721 &annotation_value,
722 method_return,
723 DexFile::kAllObjects)) {
724 return nullptr;
725 }
726 Handle<mirror::Object> value_object(hs.NewHandle(annotation_value.value_.GetL()));
727
728 ObjPtr<mirror::Class> annotation_member_class =
729 WellKnownClasses::ToClass(WellKnownClasses::libcore_reflect_AnnotationMember);
730 Handle<mirror::Object> new_member(hs.NewHandle(annotation_member_class->AllocObject(self)));
731 ObjPtr<mirror::Method> method_obj_ptr = (pointer_size == PointerSize::k64)
732 ? mirror::Method::CreateFromArtMethod<PointerSize::k64>(self, annotation_method)
733 : mirror::Method::CreateFromArtMethod<PointerSize::k32>(self, annotation_method);
734 Handle<mirror::Method> method_object(hs.NewHandle(method_obj_ptr));
735
736 if (new_member == nullptr || string_name == nullptr ||
737 method_object == nullptr || method_return == nullptr) {
738 LOG(ERROR) << StringPrintf("Failed creating annotation element (m=%p n=%p a=%p r=%p",
739 new_member.Get(), string_name.Get(), method_object.Get(), method_return.Get());
740 return nullptr;
741 }
742
743 JValue result;
744 ArtMethod* annotation_member_init =
745 jni::DecodeArtMethod(WellKnownClasses::libcore_reflect_AnnotationMember_init);
746 uint32_t args[5] = { static_cast<uint32_t>(reinterpret_cast<uintptr_t>(new_member.Get())),
747 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(string_name.Get())),
748 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(value_object.Get())),
749 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(method_return.Get())),
750 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(method_object.Get()))
751 };
752 annotation_member_init->Invoke(self, args, sizeof(args), &result, "VLLLL");
753 if (self->IsExceptionPending()) {
754 LOG(INFO) << "Exception in AnnotationMember.<init>";
755 return nullptr;
756 }
757
758 return new_member.Get();
759 }
760
GetAnnotationItemFromAnnotationSet(const ClassData & klass,const AnnotationSetItem * annotation_set,uint32_t visibility,Handle<mirror::Class> annotation_class)761 const AnnotationItem* GetAnnotationItemFromAnnotationSet(const ClassData& klass,
762 const AnnotationSetItem* annotation_set,
763 uint32_t visibility,
764 Handle<mirror::Class> annotation_class)
765 REQUIRES_SHARED(Locks::mutator_lock_) {
766 const DexFile& dex_file = klass.GetDexFile();
767 for (uint32_t i = 0; i < annotation_set->size_; ++i) {
768 const AnnotationItem* annotation_item = dex_file.GetAnnotationItem(annotation_set, i);
769 if (!IsVisibilityCompatible(annotation_item->visibility_, visibility)) {
770 continue;
771 }
772 const uint8_t* annotation = annotation_item->annotation_;
773 uint32_t type_index = DecodeUnsignedLeb128(&annotation);
774 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
775 Thread* self = Thread::Current();
776 StackHandleScope<2> hs(self);
777 ObjPtr<mirror::Class> resolved_class = class_linker->ResolveType(
778 dex::TypeIndex(type_index),
779 hs.NewHandle(klass.GetDexCache()),
780 hs.NewHandle(klass.GetClassLoader()));
781 if (resolved_class == nullptr) {
782 std::string temp;
783 LOG(WARNING) << StringPrintf("Unable to resolve %s annotation class %d",
784 klass.GetRealClass()->GetDescriptor(&temp), type_index);
785 CHECK(self->IsExceptionPending());
786 self->ClearException();
787 continue;
788 }
789 if (resolved_class == annotation_class.Get()) {
790 return annotation_item;
791 }
792 }
793
794 return nullptr;
795 }
796
GetAnnotationObjectFromAnnotationSet(const ClassData & klass,const AnnotationSetItem * annotation_set,uint32_t visibility,Handle<mirror::Class> annotation_class)797 ObjPtr<mirror::Object> GetAnnotationObjectFromAnnotationSet(const ClassData& klass,
798 const AnnotationSetItem* annotation_set,
799 uint32_t visibility,
800 Handle<mirror::Class> annotation_class)
801 REQUIRES_SHARED(Locks::mutator_lock_) {
802 const AnnotationItem* annotation_item = GetAnnotationItemFromAnnotationSet(
803 klass, annotation_set, visibility, annotation_class);
804 if (annotation_item == nullptr) {
805 return nullptr;
806 }
807 const uint8_t* annotation = annotation_item->annotation_;
808 return ProcessEncodedAnnotation(klass, &annotation);
809 }
810
GetAnnotationValue(const ClassData & klass,const AnnotationItem * annotation_item,const char * annotation_name,Handle<mirror::Class> array_class,uint32_t expected_type)811 ObjPtr<mirror::Object> GetAnnotationValue(const ClassData& klass,
812 const AnnotationItem* annotation_item,
813 const char* annotation_name,
814 Handle<mirror::Class> array_class,
815 uint32_t expected_type)
816 REQUIRES_SHARED(Locks::mutator_lock_) {
817 const DexFile& dex_file = klass.GetDexFile();
818 const uint8_t* annotation =
819 SearchEncodedAnnotation(dex_file, annotation_item->annotation_, annotation_name);
820 if (annotation == nullptr) {
821 return nullptr;
822 }
823 DexFile::AnnotationValue annotation_value;
824 bool result = Runtime::Current()->IsActiveTransaction()
825 ? ProcessAnnotationValue<true>(klass,
826 &annotation,
827 &annotation_value,
828 array_class,
829 DexFile::kAllObjects)
830 : ProcessAnnotationValue<false>(klass,
831 &annotation,
832 &annotation_value,
833 array_class,
834 DexFile::kAllObjects);
835 if (!result) {
836 return nullptr;
837 }
838 if (annotation_value.type_ != expected_type) {
839 return nullptr;
840 }
841 return annotation_value.value_.GetL();
842 }
843
GetSignatureValue(const ClassData & klass,const AnnotationSetItem * annotation_set)844 static ObjPtr<mirror::ObjectArray<mirror::String>> GetSignatureValue(
845 const ClassData& klass,
846 const AnnotationSetItem* annotation_set)
847 REQUIRES_SHARED(Locks::mutator_lock_) {
848 const DexFile& dex_file = klass.GetDexFile();
849 StackHandleScope<1> hs(Thread::Current());
850 const AnnotationItem* annotation_item =
851 SearchAnnotationSet(dex_file, annotation_set, "Ldalvik/annotation/Signature;",
852 DexFile::kDexVisibilitySystem);
853 if (annotation_item == nullptr) {
854 return nullptr;
855 }
856 Handle<mirror::Class> string_array_class =
857 hs.NewHandle(GetClassRoot<mirror::ObjectArray<mirror::String>>());
858 DCHECK(string_array_class != nullptr);
859 ObjPtr<mirror::Object> obj =
860 GetAnnotationValue(klass, annotation_item, "value", string_array_class,
861 DexFile::kDexAnnotationArray);
862 if (obj == nullptr) {
863 return nullptr;
864 }
865 return obj->AsObjectArray<mirror::String>();
866 }
867
GetThrowsValue(const ClassData & klass,const AnnotationSetItem * annotation_set)868 ObjPtr<mirror::ObjectArray<mirror::Class>> GetThrowsValue(const ClassData& klass,
869 const AnnotationSetItem* annotation_set)
870 REQUIRES_SHARED(Locks::mutator_lock_) {
871 const DexFile& dex_file = klass.GetDexFile();
872 const AnnotationItem* annotation_item =
873 SearchAnnotationSet(dex_file, annotation_set, "Ldalvik/annotation/Throws;",
874 DexFile::kDexVisibilitySystem);
875 if (annotation_item == nullptr) {
876 return nullptr;
877 }
878 StackHandleScope<1> hs(Thread::Current());
879 Handle<mirror::Class> class_array_class =
880 hs.NewHandle(GetClassRoot<mirror::ObjectArray<mirror::Class>>());
881 DCHECK(class_array_class != nullptr);
882 ObjPtr<mirror::Object> obj =
883 GetAnnotationValue(klass, annotation_item, "value", class_array_class,
884 DexFile::kDexAnnotationArray);
885 if (obj == nullptr) {
886 return nullptr;
887 }
888 return obj->AsObjectArray<mirror::Class>();
889 }
890
ProcessAnnotationSet(const ClassData & klass,const AnnotationSetItem * annotation_set,uint32_t visibility)891 ObjPtr<mirror::ObjectArray<mirror::Object>> ProcessAnnotationSet(
892 const ClassData& klass,
893 const AnnotationSetItem* annotation_set,
894 uint32_t visibility)
895 REQUIRES_SHARED(Locks::mutator_lock_) {
896 const DexFile& dex_file = klass.GetDexFile();
897 Thread* self = Thread::Current();
898 ScopedObjectAccessUnchecked soa(self);
899 StackHandleScope<2> hs(self);
900 Handle<mirror::Class> annotation_array_class(hs.NewHandle(
901 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_annotation_Annotation__array)));
902 if (annotation_set == nullptr) {
903 return mirror::ObjectArray<mirror::Object>::Alloc(self, annotation_array_class.Get(), 0);
904 }
905
906 uint32_t size = annotation_set->size_;
907 Handle<mirror::ObjectArray<mirror::Object>> result(hs.NewHandle(
908 mirror::ObjectArray<mirror::Object>::Alloc(self, annotation_array_class.Get(), size)));
909 if (result == nullptr) {
910 return nullptr;
911 }
912
913 uint32_t dest_index = 0;
914 for (uint32_t i = 0; i < size; ++i) {
915 const AnnotationItem* annotation_item = dex_file.GetAnnotationItem(annotation_set, i);
916 // Note that we do not use IsVisibilityCompatible here because older code
917 // was correct for this case.
918 if (annotation_item->visibility_ != visibility) {
919 continue;
920 }
921 const uint8_t* annotation = annotation_item->annotation_;
922 ObjPtr<mirror::Object> annotation_obj = ProcessEncodedAnnotation(klass, &annotation);
923 if (annotation_obj != nullptr) {
924 result->SetWithoutChecks<false>(dest_index, annotation_obj);
925 ++dest_index;
926 } else if (self->IsExceptionPending()) {
927 return nullptr;
928 }
929 }
930
931 if (dest_index == size) {
932 return result.Get();
933 }
934
935 ObjPtr<mirror::ObjectArray<mirror::Object>> trimmed_result =
936 mirror::ObjectArray<mirror::Object>::Alloc(self, annotation_array_class.Get(), dest_index);
937 if (trimmed_result == nullptr) {
938 return nullptr;
939 }
940
941 for (uint32_t i = 0; i < dest_index; ++i) {
942 ObjPtr<mirror::Object> obj = result->GetWithoutChecks(i);
943 trimmed_result->SetWithoutChecks<false>(i, obj);
944 }
945
946 return trimmed_result;
947 }
948
ProcessAnnotationSetRefList(const ClassData & klass,const AnnotationSetRefList * set_ref_list,uint32_t size)949 ObjPtr<mirror::ObjectArray<mirror::Object>> ProcessAnnotationSetRefList(
950 const ClassData& klass,
951 const AnnotationSetRefList* set_ref_list,
952 uint32_t size)
953 REQUIRES_SHARED(Locks::mutator_lock_) {
954 const DexFile& dex_file = klass.GetDexFile();
955 Thread* self = Thread::Current();
956 ScopedObjectAccessUnchecked soa(self);
957 StackHandleScope<1> hs(self);
958 ObjPtr<mirror::Class> annotation_array_class =
959 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_annotation_Annotation__array);
960 ObjPtr<mirror::Class> annotation_array_array_class =
961 Runtime::Current()->GetClassLinker()->FindArrayClass(self, annotation_array_class);
962 if (annotation_array_array_class == nullptr) {
963 return nullptr;
964 }
965 Handle<mirror::ObjectArray<mirror::Object>> annotation_array_array(hs.NewHandle(
966 mirror::ObjectArray<mirror::Object>::Alloc(self, annotation_array_array_class, size)));
967 if (annotation_array_array == nullptr) {
968 LOG(ERROR) << "Annotation set ref array allocation failed";
969 return nullptr;
970 }
971 for (uint32_t index = 0; index < size; ++index) {
972 const AnnotationSetRefItem* set_ref_item = &set_ref_list->list_[index];
973 const AnnotationSetItem* set_item = dex_file.GetSetRefItemItem(set_ref_item);
974 ObjPtr<mirror::Object> annotation_set = ProcessAnnotationSet(klass,
975 set_item,
976 DexFile::kDexVisibilityRuntime);
977 if (annotation_set == nullptr) {
978 return nullptr;
979 }
980 annotation_array_array->SetWithoutChecks<false>(index, annotation_set);
981 }
982 return annotation_array_array.Get();
983 }
984 } // namespace
985
986 namespace annotations {
987
GetAnnotationForField(ArtField * field,Handle<mirror::Class> annotation_class)988 ObjPtr<mirror::Object> GetAnnotationForField(ArtField* field,
989 Handle<mirror::Class> annotation_class) {
990 const AnnotationSetItem* annotation_set = FindAnnotationSetForField(field);
991 if (annotation_set == nullptr) {
992 return nullptr;
993 }
994 StackHandleScope<1> hs(Thread::Current());
995 const ClassData field_class(hs, field);
996 return GetAnnotationObjectFromAnnotationSet(field_class,
997 annotation_set,
998 DexFile::kDexVisibilityRuntime,
999 annotation_class);
1000 }
1001
GetAnnotationsForField(ArtField * field)1002 ObjPtr<mirror::ObjectArray<mirror::Object>> GetAnnotationsForField(ArtField* field) {
1003 const AnnotationSetItem* annotation_set = FindAnnotationSetForField(field);
1004 StackHandleScope<1> hs(Thread::Current());
1005 const ClassData field_class(hs, field);
1006 return ProcessAnnotationSet(field_class, annotation_set, DexFile::kDexVisibilityRuntime);
1007 }
1008
GetSignatureAnnotationForField(ArtField * field)1009 ObjPtr<mirror::ObjectArray<mirror::String>> GetSignatureAnnotationForField(ArtField* field) {
1010 const AnnotationSetItem* annotation_set = FindAnnotationSetForField(field);
1011 if (annotation_set == nullptr) {
1012 return nullptr;
1013 }
1014 StackHandleScope<1> hs(Thread::Current());
1015 const ClassData field_class(hs, field);
1016 return GetSignatureValue(field_class, annotation_set);
1017 }
1018
IsFieldAnnotationPresent(ArtField * field,Handle<mirror::Class> annotation_class)1019 bool IsFieldAnnotationPresent(ArtField* field, Handle<mirror::Class> annotation_class) {
1020 const AnnotationSetItem* annotation_set = FindAnnotationSetForField(field);
1021 if (annotation_set == nullptr) {
1022 return false;
1023 }
1024 StackHandleScope<1> hs(Thread::Current());
1025 const ClassData field_class(hs, field);
1026 const AnnotationItem* annotation_item = GetAnnotationItemFromAnnotationSet(
1027 field_class, annotation_set, DexFile::kDexVisibilityRuntime, annotation_class);
1028 return annotation_item != nullptr;
1029 }
1030
GetAnnotationDefaultValue(ArtMethod * method)1031 ObjPtr<mirror::Object> GetAnnotationDefaultValue(ArtMethod* method) {
1032 const ClassData klass(method);
1033 const DexFile* dex_file = &klass.GetDexFile();
1034 const AnnotationsDirectoryItem* annotations_dir =
1035 dex_file->GetAnnotationsDirectory(*klass.GetClassDef());
1036 if (annotations_dir == nullptr) {
1037 return nullptr;
1038 }
1039 const AnnotationSetItem* annotation_set =
1040 dex_file->GetClassAnnotationSet(annotations_dir);
1041 if (annotation_set == nullptr) {
1042 return nullptr;
1043 }
1044 const AnnotationItem* annotation_item = SearchAnnotationSet(*dex_file, annotation_set,
1045 "Ldalvik/annotation/AnnotationDefault;", DexFile::kDexVisibilitySystem);
1046 if (annotation_item == nullptr) {
1047 return nullptr;
1048 }
1049 const uint8_t* annotation =
1050 SearchEncodedAnnotation(*dex_file, annotation_item->annotation_, "value");
1051 if (annotation == nullptr) {
1052 return nullptr;
1053 }
1054 uint8_t header_byte = *(annotation++);
1055 if ((header_byte & DexFile::kDexAnnotationValueTypeMask) != DexFile::kDexAnnotationAnnotation) {
1056 return nullptr;
1057 }
1058 annotation = SearchEncodedAnnotation(*dex_file, annotation, method->GetName());
1059 if (annotation == nullptr) {
1060 return nullptr;
1061 }
1062 DexFile::AnnotationValue annotation_value;
1063 StackHandleScope<1> hs(Thread::Current());
1064 Handle<mirror::Class> return_type(hs.NewHandle(method->ResolveReturnType()));
1065 if (!ProcessAnnotationValue<false>(klass,
1066 &annotation,
1067 &annotation_value,
1068 return_type,
1069 DexFile::kAllObjects)) {
1070 return nullptr;
1071 }
1072 return annotation_value.value_.GetL();
1073 }
1074
GetAnnotationForMethod(ArtMethod * method,Handle<mirror::Class> annotation_class)1075 ObjPtr<mirror::Object> GetAnnotationForMethod(ArtMethod* method,
1076 Handle<mirror::Class> annotation_class) {
1077 const AnnotationSetItem* annotation_set = FindAnnotationSetForMethod(method);
1078 if (annotation_set == nullptr) {
1079 return nullptr;
1080 }
1081 return GetAnnotationObjectFromAnnotationSet(ClassData(method), annotation_set,
1082 DexFile::kDexVisibilityRuntime, annotation_class);
1083 }
1084
GetAnnotationsForMethod(ArtMethod * method)1085 ObjPtr<mirror::ObjectArray<mirror::Object>> GetAnnotationsForMethod(ArtMethod* method) {
1086 const AnnotationSetItem* annotation_set = FindAnnotationSetForMethod(method);
1087 return ProcessAnnotationSet(ClassData(method),
1088 annotation_set,
1089 DexFile::kDexVisibilityRuntime);
1090 }
1091
GetExceptionTypesForMethod(ArtMethod * method)1092 ObjPtr<mirror::ObjectArray<mirror::Class>> GetExceptionTypesForMethod(ArtMethod* method) {
1093 const AnnotationSetItem* annotation_set = FindAnnotationSetForMethod(method);
1094 if (annotation_set == nullptr) {
1095 return nullptr;
1096 }
1097 return GetThrowsValue(ClassData(method), annotation_set);
1098 }
1099
GetParameterAnnotations(ArtMethod * method)1100 ObjPtr<mirror::ObjectArray<mirror::Object>> GetParameterAnnotations(ArtMethod* method) {
1101 const DexFile* dex_file = method->GetDexFile();
1102 const ParameterAnnotationsItem* parameter_annotations =
1103 FindAnnotationsItemForMethod(method);
1104 if (parameter_annotations == nullptr) {
1105 return nullptr;
1106 }
1107 const AnnotationSetRefList* set_ref_list =
1108 dex_file->GetParameterAnnotationSetRefList(parameter_annotations);
1109 if (set_ref_list == nullptr) {
1110 return nullptr;
1111 }
1112 uint32_t size = set_ref_list->size_;
1113 return ProcessAnnotationSetRefList(ClassData(method), set_ref_list, size);
1114 }
1115
GetNumberOfAnnotatedMethodParameters(ArtMethod * method)1116 uint32_t GetNumberOfAnnotatedMethodParameters(ArtMethod* method) {
1117 const DexFile* dex_file = method->GetDexFile();
1118 const ParameterAnnotationsItem* parameter_annotations =
1119 FindAnnotationsItemForMethod(method);
1120 if (parameter_annotations == nullptr) {
1121 return 0u;
1122 }
1123 const AnnotationSetRefList* set_ref_list =
1124 dex_file->GetParameterAnnotationSetRefList(parameter_annotations);
1125 if (set_ref_list == nullptr) {
1126 return 0u;
1127 }
1128 return set_ref_list->size_;
1129 }
1130
GetAnnotationForMethodParameter(ArtMethod * method,uint32_t parameter_idx,Handle<mirror::Class> annotation_class)1131 ObjPtr<mirror::Object> GetAnnotationForMethodParameter(ArtMethod* method,
1132 uint32_t parameter_idx,
1133 Handle<mirror::Class> annotation_class) {
1134 const DexFile* dex_file = method->GetDexFile();
1135 const ParameterAnnotationsItem* parameter_annotations = FindAnnotationsItemForMethod(method);
1136 if (parameter_annotations == nullptr) {
1137 return nullptr;
1138 }
1139 const AnnotationSetRefList* set_ref_list =
1140 dex_file->GetParameterAnnotationSetRefList(parameter_annotations);
1141 if (set_ref_list == nullptr) {
1142 return nullptr;
1143 }
1144 if (parameter_idx >= set_ref_list->size_) {
1145 return nullptr;
1146 }
1147 const AnnotationSetRefItem* annotation_set_ref = &set_ref_list->list_[parameter_idx];
1148 const AnnotationSetItem* annotation_set =
1149 dex_file->GetSetRefItemItem(annotation_set_ref);
1150 if (annotation_set == nullptr) {
1151 return nullptr;
1152 }
1153 return GetAnnotationObjectFromAnnotationSet(ClassData(method),
1154 annotation_set,
1155 DexFile::kDexVisibilityRuntime,
1156 annotation_class);
1157 }
1158
GetParametersMetadataForMethod(ArtMethod * method,MutableHandle<mirror::ObjectArray<mirror::String>> * names,MutableHandle<mirror::IntArray> * access_flags)1159 bool GetParametersMetadataForMethod(
1160 ArtMethod* method,
1161 /*out*/ MutableHandle<mirror::ObjectArray<mirror::String>>* names,
1162 /*out*/ MutableHandle<mirror::IntArray>* access_flags) {
1163 const AnnotationSetItem* annotation_set =
1164 FindAnnotationSetForMethod(method);
1165 if (annotation_set == nullptr) {
1166 return false;
1167 }
1168
1169 const DexFile* dex_file = method->GetDexFile();
1170 const AnnotationItem* annotation_item =
1171 SearchAnnotationSet(*dex_file,
1172 annotation_set,
1173 "Ldalvik/annotation/MethodParameters;",
1174 DexFile::kDexVisibilitySystem);
1175 if (annotation_item == nullptr) {
1176 return false;
1177 }
1178
1179 StackHandleScope<4> hs(Thread::Current());
1180
1181 // Extract the parameters' names String[].
1182 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1183 Handle<mirror::Class> string_array_class =
1184 hs.NewHandle(GetClassRoot<mirror::ObjectArray<mirror::String>>(class_linker));
1185 DCHECK(string_array_class != nullptr);
1186
1187 ClassData data(method);
1188 Handle<mirror::Object> names_obj =
1189 hs.NewHandle(GetAnnotationValue(data,
1190 annotation_item,
1191 "names",
1192 string_array_class,
1193 DexFile::kDexAnnotationArray));
1194 if (names_obj == nullptr) {
1195 return false;
1196 }
1197
1198 // Extract the parameters' access flags int[].
1199 Handle<mirror::Class> int_array_class(hs.NewHandle(GetClassRoot<mirror::IntArray>(class_linker)));
1200 DCHECK(int_array_class != nullptr);
1201 Handle<mirror::Object> access_flags_obj =
1202 hs.NewHandle(GetAnnotationValue(data,
1203 annotation_item,
1204 "accessFlags",
1205 int_array_class,
1206 DexFile::kDexAnnotationArray));
1207 if (access_flags_obj == nullptr) {
1208 return false;
1209 }
1210
1211 names->Assign(names_obj->AsObjectArray<mirror::String>());
1212 access_flags->Assign(access_flags_obj->AsIntArray());
1213 return true;
1214 }
1215
GetSignatureAnnotationForMethod(ArtMethod * method)1216 ObjPtr<mirror::ObjectArray<mirror::String>> GetSignatureAnnotationForMethod(ArtMethod* method) {
1217 const AnnotationSetItem* annotation_set = FindAnnotationSetForMethod(method);
1218 if (annotation_set == nullptr) {
1219 return nullptr;
1220 }
1221 return GetSignatureValue(ClassData(method), annotation_set);
1222 }
1223
IsMethodAnnotationPresent(ArtMethod * method,Handle<mirror::Class> annotation_class,uint32_t visibility)1224 bool IsMethodAnnotationPresent(ArtMethod* method,
1225 Handle<mirror::Class> annotation_class,
1226 uint32_t visibility /* = DexFile::kDexVisibilityRuntime */) {
1227 const AnnotationSetItem* annotation_set = FindAnnotationSetForMethod(method);
1228 if (annotation_set == nullptr) {
1229 return false;
1230 }
1231 const AnnotationItem* annotation_item = GetAnnotationItemFromAnnotationSet(
1232 ClassData(method), annotation_set, visibility, annotation_class);
1233 return annotation_item != nullptr;
1234 }
1235
DCheckNativeAnnotation(const char * descriptor,jclass cls)1236 static void DCheckNativeAnnotation(const char* descriptor, jclass cls) {
1237 if (kIsDebugBuild) {
1238 ScopedObjectAccess soa(Thread::Current());
1239 ObjPtr<mirror::Class> klass = soa.Decode<mirror::Class>(cls);
1240 ClassLinker* linker = Runtime::Current()->GetClassLinker();
1241 // WellKnownClasses may not be initialized yet, so `klass` may be null.
1242 if (klass != nullptr) {
1243 // Lookup using the boot class path loader should yield the annotation class.
1244 CHECK_EQ(klass, linker->LookupClass(soa.Self(), descriptor, /* class_loader= */ nullptr));
1245 }
1246 }
1247 }
1248
1249 // Check whether a method from the `dex_file` with the given `annotation_set`
1250 // is annotated with `annotation_descriptor` with build visibility.
IsMethodBuildAnnotationPresent(const DexFile & dex_file,const AnnotationSetItem & annotation_set,const char * annotation_descriptor,jclass annotation_class)1251 static bool IsMethodBuildAnnotationPresent(const DexFile& dex_file,
1252 const AnnotationSetItem& annotation_set,
1253 const char* annotation_descriptor,
1254 jclass annotation_class) {
1255 for (uint32_t i = 0; i < annotation_set.size_; ++i) {
1256 const AnnotationItem* annotation_item = dex_file.GetAnnotationItem(&annotation_set, i);
1257 if (!IsVisibilityCompatible(annotation_item->visibility_, DexFile::kDexVisibilityBuild)) {
1258 continue;
1259 }
1260 const uint8_t* annotation = annotation_item->annotation_;
1261 uint32_t type_index = DecodeUnsignedLeb128(&annotation);
1262 const char* descriptor = dex_file.StringByTypeIdx(dex::TypeIndex(type_index));
1263 if (strcmp(descriptor, annotation_descriptor) == 0) {
1264 DCheckNativeAnnotation(descriptor, annotation_class);
1265 return true;
1266 }
1267 }
1268 return false;
1269 }
1270
GetNativeMethodAnnotationAccessFlags(const DexFile & dex_file,const dex::ClassDef & class_def,uint32_t method_index)1271 uint32_t GetNativeMethodAnnotationAccessFlags(const DexFile& dex_file,
1272 const dex::ClassDef& class_def,
1273 uint32_t method_index) {
1274 const dex::AnnotationSetItem* annotation_set =
1275 FindAnnotationSetForMethod(dex_file, class_def, method_index);
1276 if (annotation_set == nullptr) {
1277 return 0u;
1278 }
1279 uint32_t access_flags = 0u;
1280 if (IsMethodBuildAnnotationPresent(
1281 dex_file,
1282 *annotation_set,
1283 "Ldalvik/annotation/optimization/FastNative;",
1284 WellKnownClasses::dalvik_annotation_optimization_FastNative)) {
1285 access_flags |= kAccFastNative;
1286 }
1287 if (IsMethodBuildAnnotationPresent(
1288 dex_file,
1289 *annotation_set,
1290 "Ldalvik/annotation/optimization/CriticalNative;",
1291 WellKnownClasses::dalvik_annotation_optimization_CriticalNative)) {
1292 access_flags |= kAccCriticalNative;
1293 }
1294 CHECK_NE(access_flags, kAccFastNative | kAccCriticalNative);
1295 return access_flags;
1296 }
1297
FieldIsReachabilitySensitive(const DexFile & dex_file,const dex::ClassDef & class_def,uint32_t field_index)1298 bool FieldIsReachabilitySensitive(const DexFile& dex_file,
1299 const dex::ClassDef& class_def,
1300 uint32_t field_index)
1301 REQUIRES_SHARED(Locks::mutator_lock_) {
1302 const AnnotationSetItem* annotation_set =
1303 FindAnnotationSetForField(dex_file, class_def, field_index);
1304 if (annotation_set == nullptr) {
1305 return false;
1306 }
1307 const AnnotationItem* annotation_item = SearchAnnotationSet(dex_file, annotation_set,
1308 "Ldalvik/annotation/optimization/ReachabilitySensitive;", DexFile::kDexVisibilityRuntime);
1309 // TODO: We're missing the equivalent of DCheckNativeAnnotation (not a DCHECK). Does it matter?
1310 return annotation_item != nullptr;
1311 }
1312
MethodIsReachabilitySensitive(const DexFile & dex_file,const dex::ClassDef & class_def,uint32_t method_index)1313 bool MethodIsReachabilitySensitive(const DexFile& dex_file,
1314 const dex::ClassDef& class_def,
1315 uint32_t method_index)
1316 REQUIRES_SHARED(Locks::mutator_lock_) {
1317 const AnnotationSetItem* annotation_set =
1318 FindAnnotationSetForMethod(dex_file, class_def, method_index);
1319 if (annotation_set == nullptr) {
1320 return false;
1321 }
1322 const AnnotationItem* annotation_item = SearchAnnotationSet(dex_file, annotation_set,
1323 "Ldalvik/annotation/optimization/ReachabilitySensitive;", DexFile::kDexVisibilityRuntime);
1324 return annotation_item != nullptr;
1325 }
1326
MethodIsReachabilitySensitive(const DexFile & dex_file,uint32_t method_index)1327 static bool MethodIsReachabilitySensitive(const DexFile& dex_file,
1328 uint32_t method_index)
1329 REQUIRES_SHARED(Locks::mutator_lock_) {
1330 DCHECK(method_index < dex_file.NumMethodIds());
1331 const dex::MethodId& method_id = dex_file.GetMethodId(method_index);
1332 dex::TypeIndex class_index = method_id.class_idx_;
1333 const dex::ClassDef * class_def = dex_file.FindClassDef(class_index);
1334 return class_def != nullptr
1335 && MethodIsReachabilitySensitive(dex_file, *class_def, method_index);
1336 }
1337
MethodContainsRSensitiveAccess(const DexFile & dex_file,const dex::ClassDef & class_def,uint32_t method_index)1338 bool MethodContainsRSensitiveAccess(const DexFile& dex_file,
1339 const dex::ClassDef& class_def,
1340 uint32_t method_index)
1341 REQUIRES_SHARED(Locks::mutator_lock_) {
1342 // TODO: This is too slow to run very regularly. Currently this is only invoked in the
1343 // presence of @DeadReferenceSafe, which will be rare. In the long run, we need to quickly
1344 // check once whether a class has any @ReachabilitySensitive annotations. If not, we can
1345 // immediately return false here for any method in that class.
1346 uint32_t code_item_offset = dex_file.FindCodeItemOffset(class_def, method_index);
1347 const dex::CodeItem* code_item = dex_file.GetCodeItem(code_item_offset);
1348 CodeItemInstructionAccessor accessor(dex_file, code_item);
1349 if (!accessor.HasCodeItem()) {
1350 return false;
1351 }
1352 for (DexInstructionIterator iter = accessor.begin(); iter != accessor.end(); ++iter) {
1353 switch (iter->Opcode()) {
1354 case Instruction::IGET:
1355 case Instruction::IGET_WIDE:
1356 case Instruction::IGET_OBJECT:
1357 case Instruction::IGET_BOOLEAN:
1358 case Instruction::IGET_BYTE:
1359 case Instruction::IGET_CHAR:
1360 case Instruction::IGET_SHORT:
1361 case Instruction::IPUT:
1362 case Instruction::IPUT_WIDE:
1363 case Instruction::IPUT_OBJECT:
1364 case Instruction::IPUT_BOOLEAN:
1365 case Instruction::IPUT_BYTE:
1366 case Instruction::IPUT_CHAR:
1367 case Instruction::IPUT_SHORT:
1368 {
1369 uint32_t field_index = iter->VRegC_22c();
1370 DCHECK(field_index < dex_file.NumFieldIds());
1371 // We only guarantee to pay attention to the annotation if it's in the same class,
1372 // or a containing class, but it's OK to do so in other cases.
1373 const dex::FieldId& field_id = dex_file.GetFieldId(field_index);
1374 dex::TypeIndex class_index = field_id.class_idx_;
1375 const dex::ClassDef * field_class_def = dex_file.FindClassDef(class_index);
1376 // We do not handle the case in which the field is declared in a superclass, and
1377 // don't claim to do so. The annotated field should normally be private.
1378 if (field_class_def != nullptr
1379 && FieldIsReachabilitySensitive(dex_file, *field_class_def, field_index)) {
1380 return true;
1381 }
1382 }
1383 break;
1384 case Instruction::INVOKE_SUPER:
1385 // Cannot call method in same class. TODO: Try an explicit superclass lookup for
1386 // better "best effort"?
1387 break;
1388 case Instruction::INVOKE_INTERFACE:
1389 // We handle an interface call just like a virtual call. We will find annotations
1390 // on interface methods/fields visible to us, but not of the annotation is in a
1391 // super-interface. Again, we could just ignore it.
1392 case Instruction::INVOKE_VIRTUAL:
1393 case Instruction::INVOKE_DIRECT:
1394 {
1395 uint32_t called_method_index = iter->VRegB_35c();
1396 if (MethodIsReachabilitySensitive(dex_file, called_method_index)) {
1397 return true;
1398 }
1399 }
1400 break;
1401 case Instruction::INVOKE_INTERFACE_RANGE:
1402 case Instruction::INVOKE_VIRTUAL_RANGE:
1403 case Instruction::INVOKE_DIRECT_RANGE:
1404 {
1405 uint32_t called_method_index = iter->VRegB_3rc();
1406 if (MethodIsReachabilitySensitive(dex_file, called_method_index)) {
1407 return true;
1408 }
1409 }
1410 break;
1411 // We explicitly do not handle indirect ReachabilitySensitive accesses through VarHandles,
1412 // etc. Thus we ignore INVOKE_CUSTOM / INVOKE_CUSTOM_RANGE / INVOKE_POLYMORPHIC /
1413 // INVOKE_POLYMORPHIC_RANGE.
1414 default:
1415 // There is no way to add an annotation to array elements, and so far we've encountered no
1416 // need for that, so we ignore AGET and APUT.
1417 // It's impractical or impossible to garbage collect a class while one of its methods is
1418 // on the call stack. We allow ReachabilitySensitive annotations on static methods and
1419 // fields, but they can be safely ignored.
1420 break;
1421 }
1422 }
1423 return false;
1424 }
1425
HasDeadReferenceSafeAnnotation(const DexFile & dex_file,const dex::ClassDef & class_def)1426 bool HasDeadReferenceSafeAnnotation(const DexFile& dex_file,
1427 const dex::ClassDef& class_def)
1428 // TODO: This should check outer classes as well.
1429 // It's conservatively correct not to do so.
1430 REQUIRES_SHARED(Locks::mutator_lock_) {
1431 const AnnotationsDirectoryItem* annotations_dir =
1432 dex_file.GetAnnotationsDirectory(class_def);
1433 if (annotations_dir == nullptr) {
1434 return false;
1435 }
1436 const AnnotationSetItem* annotation_set = dex_file.GetClassAnnotationSet(annotations_dir);
1437 if (annotation_set == nullptr) {
1438 return false;
1439 }
1440 const AnnotationItem* annotation_item = SearchAnnotationSet(dex_file, annotation_set,
1441 "Ldalvik/annotation/optimization/DeadReferenceSafe;", DexFile::kDexVisibilityRuntime);
1442 return annotation_item != nullptr;
1443 }
1444
GetAnnotationForClass(Handle<mirror::Class> klass,Handle<mirror::Class> annotation_class)1445 ObjPtr<mirror::Object> GetAnnotationForClass(Handle<mirror::Class> klass,
1446 Handle<mirror::Class> annotation_class) {
1447 ClassData data(klass);
1448 const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
1449 if (annotation_set == nullptr) {
1450 return nullptr;
1451 }
1452 return GetAnnotationObjectFromAnnotationSet(data,
1453 annotation_set,
1454 DexFile::kDexVisibilityRuntime,
1455 annotation_class);
1456 }
1457
GetAnnotationsForClass(Handle<mirror::Class> klass)1458 ObjPtr<mirror::ObjectArray<mirror::Object>> GetAnnotationsForClass(Handle<mirror::Class> klass) {
1459 ClassData data(klass);
1460 const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
1461 return ProcessAnnotationSet(data, annotation_set, DexFile::kDexVisibilityRuntime);
1462 }
1463
GetDeclaredClasses(Handle<mirror::Class> klass)1464 ObjPtr<mirror::ObjectArray<mirror::Class>> GetDeclaredClasses(Handle<mirror::Class> klass) {
1465 ClassData data(klass);
1466 const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
1467 if (annotation_set == nullptr) {
1468 return nullptr;
1469 }
1470 const AnnotationItem* annotation_item =
1471 SearchAnnotationSet(data.GetDexFile(), annotation_set, "Ldalvik/annotation/MemberClasses;",
1472 DexFile::kDexVisibilitySystem);
1473 if (annotation_item == nullptr) {
1474 return nullptr;
1475 }
1476 StackHandleScope<1> hs(Thread::Current());
1477 Handle<mirror::Class> class_array_class =
1478 hs.NewHandle(GetClassRoot<mirror::ObjectArray<mirror::Class>>());
1479 DCHECK(class_array_class != nullptr);
1480 ObjPtr<mirror::Object> obj =
1481 GetAnnotationValue(data, annotation_item, "value", class_array_class,
1482 DexFile::kDexAnnotationArray);
1483 if (obj == nullptr) {
1484 return nullptr;
1485 }
1486 return obj->AsObjectArray<mirror::Class>();
1487 }
1488
GetDeclaringClass(Handle<mirror::Class> klass)1489 ObjPtr<mirror::Class> GetDeclaringClass(Handle<mirror::Class> klass) {
1490 ClassData data(klass);
1491 const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
1492 if (annotation_set == nullptr) {
1493 return nullptr;
1494 }
1495 const AnnotationItem* annotation_item =
1496 SearchAnnotationSet(data.GetDexFile(), annotation_set, "Ldalvik/annotation/EnclosingClass;",
1497 DexFile::kDexVisibilitySystem);
1498 if (annotation_item == nullptr) {
1499 return nullptr;
1500 }
1501 ObjPtr<mirror::Object> obj = GetAnnotationValue(data,
1502 annotation_item,
1503 "value",
1504 ScopedNullHandle<mirror::Class>(),
1505 DexFile::kDexAnnotationType);
1506 if (obj == nullptr) {
1507 return nullptr;
1508 }
1509 return obj->AsClass();
1510 }
1511
GetEnclosingClass(Handle<mirror::Class> klass)1512 ObjPtr<mirror::Class> GetEnclosingClass(Handle<mirror::Class> klass) {
1513 ObjPtr<mirror::Class> declaring_class = GetDeclaringClass(klass);
1514 if (declaring_class != nullptr) {
1515 return declaring_class;
1516 }
1517 ClassData data(klass);
1518 const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
1519 if (annotation_set == nullptr) {
1520 return nullptr;
1521 }
1522 const AnnotationItem* annotation_item =
1523 SearchAnnotationSet(data.GetDexFile(),
1524 annotation_set,
1525 "Ldalvik/annotation/EnclosingMethod;",
1526 DexFile::kDexVisibilitySystem);
1527 if (annotation_item == nullptr) {
1528 return nullptr;
1529 }
1530 const uint8_t* annotation =
1531 SearchEncodedAnnotation(data.GetDexFile(), annotation_item->annotation_, "value");
1532 if (annotation == nullptr) {
1533 return nullptr;
1534 }
1535 DexFile::AnnotationValue annotation_value;
1536 if (!ProcessAnnotationValue<false>(data,
1537 &annotation,
1538 &annotation_value,
1539 ScopedNullHandle<mirror::Class>(),
1540 DexFile::kAllRaw)) {
1541 return nullptr;
1542 }
1543 if (annotation_value.type_ != DexFile::kDexAnnotationMethod) {
1544 return nullptr;
1545 }
1546 StackHandleScope<2> hs(Thread::Current());
1547 ArtMethod* method = Runtime::Current()->GetClassLinker()->ResolveMethodWithoutInvokeType(
1548 annotation_value.value_.GetI(),
1549 hs.NewHandle(data.GetDexCache()),
1550 hs.NewHandle(data.GetClassLoader()));
1551 if (method == nullptr) {
1552 return nullptr;
1553 }
1554 return method->GetDeclaringClass();
1555 }
1556
GetEnclosingMethod(Handle<mirror::Class> klass)1557 ObjPtr<mirror::Object> GetEnclosingMethod(Handle<mirror::Class> klass) {
1558 ClassData data(klass);
1559 const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
1560 if (annotation_set == nullptr) {
1561 return nullptr;
1562 }
1563 const AnnotationItem* annotation_item =
1564 SearchAnnotationSet(data.GetDexFile(),
1565 annotation_set,
1566 "Ldalvik/annotation/EnclosingMethod;",
1567 DexFile::kDexVisibilitySystem);
1568 if (annotation_item == nullptr) {
1569 return nullptr;
1570 }
1571 return GetAnnotationValue(data, annotation_item, "value", ScopedNullHandle<mirror::Class>(),
1572 DexFile::kDexAnnotationMethod);
1573 }
1574
GetInnerClass(Handle<mirror::Class> klass,ObjPtr<mirror::String> * name)1575 bool GetInnerClass(Handle<mirror::Class> klass, /*out*/ ObjPtr<mirror::String>* name) {
1576 ClassData data(klass);
1577 const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
1578 if (annotation_set == nullptr) {
1579 return false;
1580 }
1581 const AnnotationItem* annotation_item = SearchAnnotationSet(
1582 data.GetDexFile(),
1583 annotation_set,
1584 "Ldalvik/annotation/InnerClass;",
1585 DexFile::kDexVisibilitySystem);
1586 if (annotation_item == nullptr) {
1587 return false;
1588 }
1589 const uint8_t* annotation =
1590 SearchEncodedAnnotation(data.GetDexFile(), annotation_item->annotation_, "name");
1591 if (annotation == nullptr) {
1592 return false;
1593 }
1594 DexFile::AnnotationValue annotation_value;
1595 if (!ProcessAnnotationValue<false>(data,
1596 &annotation,
1597 &annotation_value,
1598 ScopedNullHandle<mirror::Class>(),
1599 DexFile::kAllObjects)) {
1600 return false;
1601 }
1602 if (annotation_value.type_ != DexFile::kDexAnnotationNull &&
1603 annotation_value.type_ != DexFile::kDexAnnotationString) {
1604 return false;
1605 }
1606 *name = down_cast<mirror::String*>(annotation_value.value_.GetL());
1607 return true;
1608 }
1609
GetInnerClassFlags(Handle<mirror::Class> klass,uint32_t * flags)1610 bool GetInnerClassFlags(Handle<mirror::Class> klass, uint32_t* flags) {
1611 ClassData data(klass);
1612 const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
1613 if (annotation_set == nullptr) {
1614 return false;
1615 }
1616 const AnnotationItem* annotation_item =
1617 SearchAnnotationSet(data.GetDexFile(), annotation_set, "Ldalvik/annotation/InnerClass;",
1618 DexFile::kDexVisibilitySystem);
1619 if (annotation_item == nullptr) {
1620 return false;
1621 }
1622 const uint8_t* annotation =
1623 SearchEncodedAnnotation(data.GetDexFile(), annotation_item->annotation_, "accessFlags");
1624 if (annotation == nullptr) {
1625 return false;
1626 }
1627 DexFile::AnnotationValue annotation_value;
1628 if (!ProcessAnnotationValue<false>(data,
1629 &annotation,
1630 &annotation_value,
1631 ScopedNullHandle<mirror::Class>(),
1632 DexFile::kAllRaw)) {
1633 return false;
1634 }
1635 if (annotation_value.type_ != DexFile::kDexAnnotationInt) {
1636 return false;
1637 }
1638 *flags = annotation_value.value_.GetI();
1639 return true;
1640 }
1641
GetSignatureAnnotationForClass(Handle<mirror::Class> klass)1642 ObjPtr<mirror::ObjectArray<mirror::String>> GetSignatureAnnotationForClass(
1643 Handle<mirror::Class> klass) {
1644 ClassData data(klass);
1645 const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
1646 if (annotation_set == nullptr) {
1647 return nullptr;
1648 }
1649 return GetSignatureValue(data, annotation_set);
1650 }
1651
GetSourceDebugExtension(Handle<mirror::Class> klass)1652 const char* GetSourceDebugExtension(Handle<mirror::Class> klass) {
1653 // Before instantiating ClassData, check that klass has a DexCache
1654 // assigned. The ClassData constructor indirectly dereferences it
1655 // when calling klass->GetDexFile().
1656 if (klass->GetDexCache() == nullptr) {
1657 DCHECK(klass->IsPrimitive() || klass->IsArrayClass());
1658 return nullptr;
1659 }
1660
1661 ClassData data(klass);
1662 const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
1663 if (annotation_set == nullptr) {
1664 return nullptr;
1665 }
1666
1667 const AnnotationItem* annotation_item = SearchAnnotationSet(
1668 data.GetDexFile(),
1669 annotation_set,
1670 "Ldalvik/annotation/SourceDebugExtension;",
1671 DexFile::kDexVisibilitySystem);
1672 if (annotation_item == nullptr) {
1673 return nullptr;
1674 }
1675
1676 const uint8_t* annotation =
1677 SearchEncodedAnnotation(data.GetDexFile(), annotation_item->annotation_, "value");
1678 if (annotation == nullptr) {
1679 return nullptr;
1680 }
1681 DexFile::AnnotationValue annotation_value;
1682 if (!ProcessAnnotationValue<false>(data,
1683 &annotation,
1684 &annotation_value,
1685 ScopedNullHandle<mirror::Class>(),
1686 DexFile::kAllRaw)) {
1687 return nullptr;
1688 }
1689 if (annotation_value.type_ != DexFile::kDexAnnotationString) {
1690 return nullptr;
1691 }
1692 dex::StringIndex index(static_cast<uint32_t>(annotation_value.value_.GetI()));
1693 return data.GetDexFile().StringDataByIdx(index);
1694 }
1695
IsClassAnnotationPresent(Handle<mirror::Class> klass,Handle<mirror::Class> annotation_class)1696 bool IsClassAnnotationPresent(Handle<mirror::Class> klass, Handle<mirror::Class> annotation_class) {
1697 ClassData data(klass);
1698 const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
1699 if (annotation_set == nullptr) {
1700 return false;
1701 }
1702 const AnnotationItem* annotation_item = GetAnnotationItemFromAnnotationSet(
1703 data, annotation_set, DexFile::kDexVisibilityRuntime, annotation_class);
1704 return annotation_item != nullptr;
1705 }
1706
GetLineNumFromPC(const DexFile * dex_file,ArtMethod * method,uint32_t rel_pc)1707 int32_t GetLineNumFromPC(const DexFile* dex_file, ArtMethod* method, uint32_t rel_pc) {
1708 // For native method, lineno should be -2 to indicate it is native. Note that
1709 // "line number == -2" is how libcore tells from StackTraceElement.
1710 if (!method->HasCodeItem()) {
1711 return -2;
1712 }
1713
1714 CodeItemDebugInfoAccessor accessor(method->DexInstructionDebugInfo());
1715 DCHECK(accessor.HasCodeItem()) << method->PrettyMethod() << " " << dex_file->GetLocation();
1716
1717 // A method with no line number info should return -1
1718 uint32_t line_num = -1;
1719 accessor.GetLineNumForPc(rel_pc, &line_num);
1720 return line_num;
1721 }
1722
1723 template<bool kTransactionActive>
ReadValueToField(ArtField * field) const1724 void RuntimeEncodedStaticFieldValueIterator::ReadValueToField(ArtField* field) const {
1725 DCHECK(dex_cache_ != nullptr);
1726 switch (type_) {
1727 case kBoolean: field->SetBoolean<kTransactionActive>(field->GetDeclaringClass(), jval_.z);
1728 break;
1729 case kByte: field->SetByte<kTransactionActive>(field->GetDeclaringClass(), jval_.b); break;
1730 case kShort: field->SetShort<kTransactionActive>(field->GetDeclaringClass(), jval_.s); break;
1731 case kChar: field->SetChar<kTransactionActive>(field->GetDeclaringClass(), jval_.c); break;
1732 case kInt: field->SetInt<kTransactionActive>(field->GetDeclaringClass(), jval_.i); break;
1733 case kLong: field->SetLong<kTransactionActive>(field->GetDeclaringClass(), jval_.j); break;
1734 case kFloat: field->SetFloat<kTransactionActive>(field->GetDeclaringClass(), jval_.f); break;
1735 case kDouble: field->SetDouble<kTransactionActive>(field->GetDeclaringClass(), jval_.d); break;
1736 case kNull: field->SetObject<kTransactionActive>(field->GetDeclaringClass(), nullptr); break;
1737 case kString: {
1738 ObjPtr<mirror::String> resolved = linker_->ResolveString(dex::StringIndex(jval_.i),
1739 dex_cache_);
1740 field->SetObject<kTransactionActive>(field->GetDeclaringClass(), resolved);
1741 break;
1742 }
1743 case kType: {
1744 ObjPtr<mirror::Class> resolved = linker_->ResolveType(dex::TypeIndex(jval_.i),
1745 dex_cache_,
1746 class_loader_);
1747 field->SetObject<kTransactionActive>(field->GetDeclaringClass(), resolved);
1748 break;
1749 }
1750 default: UNIMPLEMENTED(FATAL) << ": type " << type_;
1751 }
1752 }
1753 template
1754 void RuntimeEncodedStaticFieldValueIterator::ReadValueToField<true>(ArtField* field) const;
1755 template
1756 void RuntimeEncodedStaticFieldValueIterator::ReadValueToField<false>(ArtField* field) const;
1757
1758 } // namespace annotations
1759
1760 } // namespace art
1761