1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker #ifndef ART_RUNTIME_DEX_DEX_FILE_ANNOTATIONS_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_DEX_DEX_FILE_ANNOTATIONS_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file.h" 21*795d594fSAndroid Build Coastguard Worker #include "handle.h" 22*795d594fSAndroid Build Coastguard Worker #include "mirror/dex_cache.h" 23*795d594fSAndroid Build Coastguard Worker #include "mirror/object_array.h" 24*795d594fSAndroid Build Coastguard Worker #include "obj_ptr.h" 25*795d594fSAndroid Build Coastguard Worker 26*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN { 27*795d594fSAndroid Build Coastguard Worker 28*795d594fSAndroid Build Coastguard Worker namespace mirror { 29*795d594fSAndroid Build Coastguard Worker class ClassLoader; 30*795d594fSAndroid Build Coastguard Worker } // namespace mirror 31*795d594fSAndroid Build Coastguard Worker class ArtField; 32*795d594fSAndroid Build Coastguard Worker class ArtMethod; 33*795d594fSAndroid Build Coastguard Worker class ClassLinker; 34*795d594fSAndroid Build Coastguard Worker 35*795d594fSAndroid Build Coastguard Worker namespace annotations { 36*795d594fSAndroid Build Coastguard Worker 37*795d594fSAndroid Build Coastguard Worker // Field annotations. 38*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> GetAnnotationForField(ArtField* field, 39*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> annotation_class) 40*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 41*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Object>> GetAnnotationsForField(ArtField* field) 42*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 43*795d594fSAndroid Build Coastguard Worker EXPORT ObjPtr<mirror::ObjectArray<mirror::String>> GetSignatureAnnotationForField(ArtField* field) 44*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 45*795d594fSAndroid Build Coastguard Worker bool IsFieldAnnotationPresent(ArtField* field, Handle<mirror::Class> annotation_class) 46*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 47*795d594fSAndroid Build Coastguard Worker 48*795d594fSAndroid Build Coastguard Worker // Method annotations. 49*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> GetAnnotationDefaultValue(ArtMethod* method) 50*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 51*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> GetAnnotationForMethod(ArtMethod* method, 52*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> annotation_class) 53*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 54*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Object>> GetAnnotationsForMethod(ArtMethod* method) 55*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 56*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Class>> GetExceptionTypesForMethod(ArtMethod* method) 57*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 58*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Object>> GetParameterAnnotations(ArtMethod* method) 59*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 60*795d594fSAndroid Build Coastguard Worker uint32_t GetNumberOfAnnotatedMethodParameters(ArtMethod* method) 61*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 62*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> GetAnnotationForMethodParameter(ArtMethod* method, 63*795d594fSAndroid Build Coastguard Worker uint32_t parameter_idx, 64*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> annotation_class) 65*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 66*795d594fSAndroid Build Coastguard Worker bool GetParametersMetadataForMethod( 67*795d594fSAndroid Build Coastguard Worker ArtMethod* method, 68*795d594fSAndroid Build Coastguard Worker /*out*/ MutableHandle<mirror::ObjectArray<mirror::String>>* names, 69*795d594fSAndroid Build Coastguard Worker /*out*/ MutableHandle<mirror::IntArray>* access_flags) REQUIRES_SHARED(Locks::mutator_lock_); 70*795d594fSAndroid Build Coastguard Worker EXPORT ObjPtr<mirror::ObjectArray<mirror::String>> GetSignatureAnnotationForMethod( 71*795d594fSAndroid Build Coastguard Worker ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_); 72*795d594fSAndroid Build Coastguard Worker // Check whether `method` is annotated with `annotation_class`. 73*795d594fSAndroid Build Coastguard Worker // If `lookup_in_resolved_boot_classes` is true, look up any of the 74*795d594fSAndroid Build Coastguard Worker // method's annotations' classes in the bootstrap class loader's 75*795d594fSAndroid Build Coastguard Worker // resolved types; if it is false (default value), resolve them as a 76*795d594fSAndroid Build Coastguard Worker // side effect. 77*795d594fSAndroid Build Coastguard Worker bool IsMethodAnnotationPresent(ArtMethod* method, 78*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> annotation_class, 79*795d594fSAndroid Build Coastguard Worker uint32_t visibility = DexFile::kDexVisibilityRuntime) 80*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 81*795d594fSAndroid Build Coastguard Worker 82*795d594fSAndroid Build Coastguard Worker // Check whether a method from the `dex_file` with the given `method_index` 83*795d594fSAndroid Build Coastguard Worker // is annotated with @dalvik.annotation.optimization.FastNative or 84*795d594fSAndroid Build Coastguard Worker // @dalvik.annotation.optimization.CriticalNative with build visibility. 85*795d594fSAndroid Build Coastguard Worker // If yes, return the associated access flags, i.e. kAccFastNative or kAccCriticalNative. 86*795d594fSAndroid Build Coastguard Worker EXPORT uint32_t GetNativeMethodAnnotationAccessFlags(const DexFile& dex_file, 87*795d594fSAndroid Build Coastguard Worker const dex::ClassDef& class_def, 88*795d594fSAndroid Build Coastguard Worker uint32_t method_index); 89*795d594fSAndroid Build Coastguard Worker // An overload of `GetNativeMethodAnnotationAccessFlags()` that takes a `MethodAnnotationsItem`. 90*795d594fSAndroid Build Coastguard Worker uint32_t GetNativeMethodAnnotationAccessFlags(const DexFile& dex_file, 91*795d594fSAndroid Build Coastguard Worker const dex::MethodAnnotationsItem& method_annotations); 92*795d594fSAndroid Build Coastguard Worker // Is the method from the `dex_file` with the given `field_index` 93*795d594fSAndroid Build Coastguard Worker // annotated with @dalvik.annotation.optimization.NeverCompile? 94*795d594fSAndroid Build Coastguard Worker EXPORT bool MethodIsNeverCompile(const DexFile& dex_file, 95*795d594fSAndroid Build Coastguard Worker const dex::ClassDef& class_def, 96*795d594fSAndroid Build Coastguard Worker uint32_t method_index); 97*795d594fSAndroid Build Coastguard Worker // An overload of `MethodIsNeverCompile()` that takes a `MethodAnnotationsItem`. 98*795d594fSAndroid Build Coastguard Worker bool MethodIsNeverCompile(const DexFile& dex_file, 99*795d594fSAndroid Build Coastguard Worker const dex::MethodAnnotationsItem& method_annotations); 100*795d594fSAndroid Build Coastguard Worker // Is the method from the `dex_file` with the given `field_index` 101*795d594fSAndroid Build Coastguard Worker // annotated with @dalvik.annotation.optimization.NeverInline? 102*795d594fSAndroid Build Coastguard Worker bool MethodIsNeverInline(const DexFile& dex_file, 103*795d594fSAndroid Build Coastguard Worker const dex::ClassDef& class_def, 104*795d594fSAndroid Build Coastguard Worker uint32_t method_index); 105*795d594fSAndroid Build Coastguard Worker // Is the field from the `dex_file` with the given `field_index` 106*795d594fSAndroid Build Coastguard Worker // annotated with @dalvik.annotation.optimization.ReachabilitySensitive? 107*795d594fSAndroid Build Coastguard Worker bool FieldIsReachabilitySensitive(const DexFile& dex_file, 108*795d594fSAndroid Build Coastguard Worker const dex::ClassDef& class_def, 109*795d594fSAndroid Build Coastguard Worker uint32_t field_index); 110*795d594fSAndroid Build Coastguard Worker // Is the method from the `dex_file` with the given `method_index` 111*795d594fSAndroid Build Coastguard Worker // annotated with @dalvik.annotation.optimization.ReachabilitySensitive? 112*795d594fSAndroid Build Coastguard Worker bool MethodIsReachabilitySensitive(const DexFile& dex_file, 113*795d594fSAndroid Build Coastguard Worker const dex::ClassDef& class_def, 114*795d594fSAndroid Build Coastguard Worker uint32_t method_index); 115*795d594fSAndroid Build Coastguard Worker // Does the method from the `dex_file` with the given `method_index` contain an access to a field 116*795d594fSAndroid Build Coastguard Worker // annotated with @dalvik.annotation.optimization.ReachabilitySensitive, or a call to a method 117*795d594fSAndroid Build Coastguard Worker // with that annotation? 118*795d594fSAndroid Build Coastguard Worker // Class_def is the class defining the method. We consider only accessses to classes or methods 119*795d594fSAndroid Build Coastguard Worker // declared in the static type of the corresponding object. We may overlook accesses to annotated 120*795d594fSAndroid Build Coastguard Worker // fields or methods that are in neither class_def nor a containing (outer) class. 121*795d594fSAndroid Build Coastguard Worker bool MethodContainsRSensitiveAccess(const DexFile& dex_file, 122*795d594fSAndroid Build Coastguard Worker const dex::ClassDef& class_def, 123*795d594fSAndroid Build Coastguard Worker uint32_t method_index); 124*795d594fSAndroid Build Coastguard Worker // Is the given class annotated with @dalvik.annotation.optimization.DeadReferenceSafe? 125*795d594fSAndroid Build Coastguard Worker bool HasDeadReferenceSafeAnnotation(const DexFile& dex_file, 126*795d594fSAndroid Build Coastguard Worker const dex::ClassDef& class_def); 127*795d594fSAndroid Build Coastguard Worker 128*795d594fSAndroid Build Coastguard Worker // Class annotations. 129*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> GetAnnotationForClass(Handle<mirror::Class> klass, 130*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> annotation_class) 131*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 132*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Object>> GetAnnotationsForClass(Handle<mirror::Class> klass) 133*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 134*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Class>> GetDeclaredClasses(Handle<mirror::Class> klass) 135*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 136*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> GetDeclaringClass(Handle<mirror::Class> klass) 137*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 138*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> GetEnclosingClass(Handle<mirror::Class> klass) 139*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 140*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> GetEnclosingMethod(Handle<mirror::Class> klass) 141*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 142*795d594fSAndroid Build Coastguard Worker bool GetInnerClass(Handle<mirror::Class> klass, /*out*/ ObjPtr<mirror::String>* name) 143*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 144*795d594fSAndroid Build Coastguard Worker bool GetInnerClassFlags(Handle<mirror::Class> klass, uint32_t* flags) 145*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 146*795d594fSAndroid Build Coastguard Worker EXPORT ObjPtr<mirror::ObjectArray<mirror::String>> GetSignatureAnnotationForClass( 147*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_); 148*795d594fSAndroid Build Coastguard Worker EXPORT const char* GetSourceDebugExtension(Handle<mirror::Class> klass) 149*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 150*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> GetNestHost(Handle<mirror::Class> klass) 151*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 152*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Class>> GetNestMembers(Handle<mirror::Class> klass) 153*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 154*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> getRecordAnnotationElement(Handle<mirror::Class> klass, 155*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> array_class, 156*795d594fSAndroid Build Coastguard Worker const char* element_name) 157*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 158*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Class>> GetPermittedSubclasses(Handle<mirror::Class> klass) 159*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 160*795d594fSAndroid Build Coastguard Worker bool IsClassAnnotationPresent(Handle<mirror::Class> klass, 161*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> annotation_class) 162*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 163*795d594fSAndroid Build Coastguard Worker 164*795d594fSAndroid Build Coastguard Worker // Map back from a PC to the line number in a method. 165*795d594fSAndroid Build Coastguard Worker int32_t GetLineNumFromPC(const DexFile* dex_file, ArtMethod* method, uint32_t rel_pc) 166*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 167*795d594fSAndroid Build Coastguard Worker 168*795d594fSAndroid Build Coastguard Worker // Annotations iterator. 169*795d594fSAndroid Build Coastguard Worker class RuntimeEncodedStaticFieldValueIterator : public EncodedStaticFieldValueIterator { 170*795d594fSAndroid Build Coastguard Worker public: 171*795d594fSAndroid Build Coastguard Worker // A constructor meant to be called from runtime code. RuntimeEncodedStaticFieldValueIterator(Handle<mirror::DexCache> dex_cache,Handle<mirror::ClassLoader> class_loader,ClassLinker * linker,const dex::ClassDef & class_def)172*795d594fSAndroid Build Coastguard Worker RuntimeEncodedStaticFieldValueIterator(Handle<mirror::DexCache> dex_cache, 173*795d594fSAndroid Build Coastguard Worker Handle<mirror::ClassLoader> class_loader, 174*795d594fSAndroid Build Coastguard Worker ClassLinker* linker, 175*795d594fSAndroid Build Coastguard Worker const dex::ClassDef& class_def) 176*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) 177*795d594fSAndroid Build Coastguard Worker : EncodedStaticFieldValueIterator(*dex_cache->GetDexFile(), class_def), 178*795d594fSAndroid Build Coastguard Worker dex_cache_(dex_cache), 179*795d594fSAndroid Build Coastguard Worker class_loader_(class_loader), 180*795d594fSAndroid Build Coastguard Worker linker_(linker) { 181*795d594fSAndroid Build Coastguard Worker } 182*795d594fSAndroid Build Coastguard Worker 183*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive> 184*795d594fSAndroid Build Coastguard Worker void ReadValueToField(ArtField* field) const REQUIRES_SHARED(Locks::mutator_lock_); 185*795d594fSAndroid Build Coastguard Worker 186*795d594fSAndroid Build Coastguard Worker private: 187*795d594fSAndroid Build Coastguard Worker const Handle<mirror::DexCache> dex_cache_; // Dex cache to resolve literal objects. 188*795d594fSAndroid Build Coastguard Worker const Handle<mirror::ClassLoader> class_loader_; // ClassLoader to resolve types. 189*795d594fSAndroid Build Coastguard Worker ClassLinker* const linker_; // Linker to resolve literal objects. 190*795d594fSAndroid Build Coastguard Worker DISALLOW_IMPLICIT_CONSTRUCTORS(RuntimeEncodedStaticFieldValueIterator); 191*795d594fSAndroid Build Coastguard Worker }; 192*795d594fSAndroid Build Coastguard Worker 193*795d594fSAndroid Build Coastguard Worker enum class VisitorStatus : uint8_t { kVisitBreak, kVisitNext, kVisitInner }; 194*795d594fSAndroid Build Coastguard Worker 195*795d594fSAndroid Build Coastguard Worker class AnnotationVisitor { 196*795d594fSAndroid Build Coastguard Worker public: ~AnnotationVisitor()197*795d594fSAndroid Build Coastguard Worker virtual ~AnnotationVisitor() {} 198*795d594fSAndroid Build Coastguard Worker virtual VisitorStatus VisitAnnotation(const char* annotation_descriptor, uint8_t visibility) = 0; 199*795d594fSAndroid Build Coastguard Worker virtual VisitorStatus VisitAnnotationElement(const char* element_name, 200*795d594fSAndroid Build Coastguard Worker uint8_t type, 201*795d594fSAndroid Build Coastguard Worker const JValue& value) = 0; 202*795d594fSAndroid Build Coastguard Worker virtual VisitorStatus VisitArrayElement(uint8_t depth, 203*795d594fSAndroid Build Coastguard Worker uint32_t index, 204*795d594fSAndroid Build Coastguard Worker uint8_t type, 205*795d594fSAndroid Build Coastguard Worker const JValue& value) = 0; 206*795d594fSAndroid Build Coastguard Worker HasError()207*795d594fSAndroid Build Coastguard Worker bool HasError() const { return has_error_; } SetErrorMsg(const std::string & msg)208*795d594fSAndroid Build Coastguard Worker void SetErrorMsg(const std::string& msg) { 209*795d594fSAndroid Build Coastguard Worker DCHECK(!has_error_) << "Already had an error set. New error: " << msg 210*795d594fSAndroid Build Coastguard Worker << ", old error: " << error_msg_; 211*795d594fSAndroid Build Coastguard Worker has_error_ = true; 212*795d594fSAndroid Build Coastguard Worker error_msg_ = msg; 213*795d594fSAndroid Build Coastguard Worker } GetErrorMsg()214*795d594fSAndroid Build Coastguard Worker const std::string& GetErrorMsg() const { return error_msg_; } 215*795d594fSAndroid Build Coastguard Worker 216*795d594fSAndroid Build Coastguard Worker protected: 217*795d594fSAndroid Build Coastguard Worker // Whether we found an error while visiting the annotations. If true, `error_msg_` will contain 218*795d594fSAndroid Build Coastguard Worker // the information about the error. 219*795d594fSAndroid Build Coastguard Worker bool has_error_ = false; 220*795d594fSAndroid Build Coastguard Worker std::string error_msg_; 221*795d594fSAndroid Build Coastguard Worker }; 222*795d594fSAndroid Build Coastguard Worker 223*795d594fSAndroid Build Coastguard Worker // Visit all annotation elements and array elements without creating 224*795d594fSAndroid Build Coastguard Worker // Arrays or Objects in the managed heap. 225*795d594fSAndroid Build Coastguard Worker void VisitClassAnnotations(Handle<mirror::Class> klass, AnnotationVisitor* visitor) 226*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 227*795d594fSAndroid Build Coastguard Worker 228*795d594fSAndroid Build Coastguard Worker } // namespace annotations 229*795d594fSAndroid Build Coastguard Worker 230*795d594fSAndroid Build Coastguard Worker } // namespace art 231*795d594fSAndroid Build Coastguard Worker 232*795d594fSAndroid Build Coastguard Worker #endif // ART_RUNTIME_DEX_DEX_FILE_ANNOTATIONS_H_ 233