1 /* 2 * Copyright (C) 2012 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 "entrypoints/entrypoint_utils.h" 18 19 #include "art_field-inl.h" 20 #include "art_method-inl.h" 21 #include "base/enums.h" 22 #include "base/mutex.h" 23 #include "base/sdk_version.h" 24 #include "class_linker-inl.h" 25 #include "dex/dex_file-inl.h" 26 #include "entrypoints/entrypoint_utils-inl.h" 27 #include "entrypoints/quick/callee_save_frame.h" 28 #include "entrypoints/runtime_asm_entrypoints.h" 29 #include "gc/accounting/card_table-inl.h" 30 #include "jni/java_vm_ext.h" 31 #include "mirror/class-inl.h" 32 #include "mirror/method.h" 33 #include "mirror/object-inl.h" 34 #include "mirror/object_array-inl.h" 35 #include "nth_caller_visitor.h" 36 #include "oat_quick_method_header.h" 37 #include "reflection.h" 38 #include "scoped_thread_state_change-inl.h" 39 #include "well_known_classes.h" 40 41 namespace art { 42 43 void CheckReferenceResult(Handle<mirror::Object> o, Thread* self) { 44 if (o == nullptr) { 45 return; 46 } 47 // Make sure that the result is an instance of the type this method was expected to return. 48 ArtMethod* method = self->GetCurrentMethod(nullptr); 49 ObjPtr<mirror::Class> return_type = method->ResolveReturnType(); 50 51 if (!o->InstanceOf(return_type)) { 52 Runtime::Current()->GetJavaVM()->JniAbortF(nullptr, 53 "attempt to return an instance of %s from %s", 54 o->PrettyTypeOf().c_str(), 55 method->PrettyMethod().c_str()); 56 } 57 } 58 59 JValue InvokeProxyInvocationHandler(ScopedObjectAccessAlreadyRunnable& soa, 60 const char* shorty, 61 jobject rcvr_jobj, 62 jobject interface_method_jobj, 63 std::vector<jvalue>& args) { 64 DCHECK(soa.Env()->IsInstanceOf(rcvr_jobj, WellKnownClasses::java_lang_reflect_Proxy)); 65 66 // Build argument array possibly triggering GC. 67 soa.Self()->AssertThreadSuspensionIsAllowable(); 68 jobjectArray args_jobj = nullptr; 69 const JValue zero; 70 uint32_t target_sdk_version = Runtime::Current()->GetTargetSdkVersion(); 71 // Do not create empty arrays unless needed to maintain Dalvik bug compatibility. 72 if (args.size() > 0 || IsSdkVersionSetAndAtMost(target_sdk_version, SdkVersion::kL)) { 73 args_jobj = soa.Env()->NewObjectArray(args.size(), WellKnownClasses::java_lang_Object, nullptr); 74 if (args_jobj == nullptr) { 75 CHECK(soa.Self()->IsExceptionPending()); 76 return zero; 77 } 78 for (size_t i = 0; i < args.size(); ++i) { 79 if (shorty[i + 1] == 'L') { 80 jobject val = args[i].l; 81 soa.Env()->SetObjectArrayElement(args_jobj, i, val); 82 } else { 83 JValue jv; 84 jv.SetJ(args[i].j); 85 ObjPtr<mirror::Object> val = BoxPrimitive(Primitive::GetType(shorty[i + 1]), jv); 86 if (val == nullptr) { 87 CHECK(soa.Self()->IsExceptionPending()); 88 return zero; 89 } 90 soa.Decode<mirror::ObjectArray<mirror::Object>>(args_jobj)->Set<false>(i, val); 91 } 92 } 93 } 94 95 // Call Proxy.invoke(Proxy proxy, Method method, Object[] args). 96 jvalue invocation_args[3]; 97 invocation_args[0].l = rcvr_jobj; 98 invocation_args[1].l = interface_method_jobj; 99 invocation_args[2].l = args_jobj; 100 jobject result = 101 soa.Env()->CallStaticObjectMethodA(WellKnownClasses::java_lang_reflect_Proxy, 102 WellKnownClasses::java_lang_reflect_Proxy_invoke, 103 invocation_args); 104 105 // Unbox result and handle error conditions. 106 if (LIKELY(!soa.Self()->IsExceptionPending())) { 107 if (shorty[0] == 'V' || (shorty[0] == 'L' && result == nullptr)) { 108 // Do nothing. 109 return zero; 110 } else { 111 ArtMethod* interface_method = 112 soa.Decode<mirror::Method>(interface_method_jobj)->GetArtMethod(); 113 // This can cause thread suspension. 114 ObjPtr<mirror::Class> result_type = interface_method->ResolveReturnType(); 115 ObjPtr<mirror::Object> result_ref = soa.Decode<mirror::Object>(result); 116 JValue result_unboxed; 117 if (!UnboxPrimitiveForResult(result_ref, result_type, &result_unboxed)) { 118 DCHECK(soa.Self()->IsExceptionPending()); 119 return zero; 120 } 121 return result_unboxed; 122 } 123 } else { 124 // In the case of checked exceptions that aren't declared, the exception must be wrapped by 125 // a UndeclaredThrowableException. 126 ObjPtr<mirror::Throwable> exception = soa.Self()->GetException(); 127 if (exception->IsCheckedException()) { 128 bool declares_exception = false; 129 { 130 ScopedAssertNoThreadSuspension ants(__FUNCTION__); 131 ObjPtr<mirror::Object> rcvr = soa.Decode<mirror::Object>(rcvr_jobj); 132 ObjPtr<mirror::Class> proxy_class = rcvr->GetClass(); 133 ObjPtr<mirror::Method> interface_method = soa.Decode<mirror::Method>(interface_method_jobj); 134 ArtMethod* proxy_method = rcvr->GetClass()->FindVirtualMethodForInterface( 135 interface_method->GetArtMethod(), kRuntimePointerSize); 136 auto virtual_methods = proxy_class->GetVirtualMethodsSlice(kRuntimePointerSize); 137 size_t num_virtuals = proxy_class->NumVirtualMethods(); 138 size_t method_size = ArtMethod::Size(kRuntimePointerSize); 139 // Rely on the fact that the methods are contiguous to determine the index of the method in 140 // the slice. 141 int throws_index = (reinterpret_cast<uintptr_t>(proxy_method) - 142 reinterpret_cast<uintptr_t>(&virtual_methods[0])) / method_size; 143 CHECK_LT(throws_index, static_cast<int>(num_virtuals)); 144 ObjPtr<mirror::ObjectArray<mirror::Class>> declared_exceptions = 145 proxy_class->GetProxyThrows()->Get(throws_index); 146 ObjPtr<mirror::Class> exception_class = exception->GetClass(); 147 for (int32_t i = 0; i < declared_exceptions->GetLength() && !declares_exception; i++) { 148 ObjPtr<mirror::Class> declared_exception = declared_exceptions->Get(i); 149 declares_exception = declared_exception->IsAssignableFrom(exception_class); 150 } 151 } 152 if (!declares_exception) { 153 soa.Self()->ThrowNewWrappedException("Ljava/lang/reflect/UndeclaredThrowableException;", 154 nullptr); 155 } 156 } 157 return zero; 158 } 159 } 160 161 bool FillArrayData(ObjPtr<mirror::Object> obj, const Instruction::ArrayDataPayload* payload) { 162 DCHECK_EQ(payload->ident, static_cast<uint16_t>(Instruction::kArrayDataSignature)); 163 if (UNLIKELY(obj == nullptr)) { 164 ThrowNullPointerException("null array in FILL_ARRAY_DATA"); 165 return false; 166 } 167 ObjPtr<mirror::Array> array = obj->AsArray(); 168 DCHECK(!array->IsObjectArray()); 169 if (UNLIKELY(static_cast<int32_t>(payload->element_count) > array->GetLength())) { 170 Thread* self = Thread::Current(); 171 self->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;", 172 "failed FILL_ARRAY_DATA; length=%d, index=%d", 173 array->GetLength(), payload->element_count); 174 return false; 175 } 176 // Copy data from dex file to memory assuming both are little endian. 177 uint32_t size_in_bytes = payload->element_count * payload->element_width; 178 memcpy(array->GetRawData(payload->element_width, 0), payload->data, size_in_bytes); 179 return true; 180 } 181 182 static inline std::pair<ArtMethod*, uintptr_t> DoGetCalleeSaveMethodOuterCallerAndPc( 183 ArtMethod** sp, CalleeSaveType type) REQUIRES_SHARED(Locks::mutator_lock_) { 184 DCHECK_EQ(*sp, Runtime::Current()->GetCalleeSaveMethod(type)); 185 186 const size_t callee_frame_size = RuntimeCalleeSaveFrame::GetFrameSize(type); 187 auto** caller_sp = reinterpret_cast<ArtMethod**>( 188 reinterpret_cast<uintptr_t>(sp) + callee_frame_size); 189 const size_t callee_return_pc_offset = RuntimeCalleeSaveFrame::GetReturnPcOffset(type); 190 uintptr_t caller_pc = *reinterpret_cast<uintptr_t*>( 191 (reinterpret_cast<uint8_t*>(sp) + callee_return_pc_offset)); 192 ArtMethod* outer_method = *caller_sp; 193 return std::make_pair(outer_method, caller_pc); 194 } 195 196 static inline ArtMethod* DoGetCalleeSaveMethodCaller(ArtMethod* outer_method, 197 uintptr_t caller_pc, 198 bool do_caller_check) 199 REQUIRES_SHARED(Locks::mutator_lock_) { 200 ArtMethod* caller = outer_method; 201 if (LIKELY(caller_pc != reinterpret_cast<uintptr_t>(GetQuickInstrumentationExitPc()))) { 202 if (outer_method != nullptr) { 203 const OatQuickMethodHeader* current_code = outer_method->GetOatQuickMethodHeader(caller_pc); 204 DCHECK(current_code != nullptr); 205 DCHECK(current_code->IsOptimized()); 206 uintptr_t native_pc_offset = current_code->NativeQuickPcOffset(caller_pc); 207 CodeInfo code_info(current_code, CodeInfo::DecodeFlags::InlineInfoOnly); 208 StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset); 209 DCHECK(stack_map.IsValid()); 210 BitTableRange<InlineInfo> inline_infos = code_info.GetInlineInfosOf(stack_map); 211 if (!inline_infos.empty()) { 212 caller = GetResolvedMethod(outer_method, code_info, inline_infos); 213 } 214 } 215 if (kIsDebugBuild && do_caller_check) { 216 // Note that do_caller_check is optional, as this method can be called by 217 // stubs, and tests without a proper call stack. 218 NthCallerVisitor visitor(Thread::Current(), 1, true); 219 visitor.WalkStack(); 220 CHECK_EQ(caller, visitor.caller); 221 } 222 } else { 223 // We're instrumenting, just use the StackVisitor which knows how to 224 // handle instrumented frames. 225 NthCallerVisitor visitor(Thread::Current(), 1, true); 226 visitor.WalkStack(); 227 caller = visitor.caller; 228 } 229 return caller; 230 } 231 232 ArtMethod* GetCalleeSaveMethodCaller(ArtMethod** sp, CalleeSaveType type, bool do_caller_check) 233 REQUIRES_SHARED(Locks::mutator_lock_) { 234 ScopedAssertNoThreadSuspension ants(__FUNCTION__); 235 auto outer_caller_and_pc = DoGetCalleeSaveMethodOuterCallerAndPc(sp, type); 236 ArtMethod* outer_method = outer_caller_and_pc.first; 237 uintptr_t caller_pc = outer_caller_and_pc.second; 238 ArtMethod* caller = DoGetCalleeSaveMethodCaller(outer_method, caller_pc, do_caller_check); 239 return caller; 240 } 241 242 CallerAndOuterMethod GetCalleeSaveMethodCallerAndOuterMethod(Thread* self, CalleeSaveType type) { 243 CallerAndOuterMethod result; 244 ScopedAssertNoThreadSuspension ants(__FUNCTION__); 245 ArtMethod** sp = self->GetManagedStack()->GetTopQuickFrameKnownNotTagged(); 246 auto outer_caller_and_pc = DoGetCalleeSaveMethodOuterCallerAndPc(sp, type); 247 result.outer_method = outer_caller_and_pc.first; 248 uintptr_t caller_pc = outer_caller_and_pc.second; 249 result.caller = 250 DoGetCalleeSaveMethodCaller(result.outer_method, caller_pc, /* do_caller_check= */ true); 251 return result; 252 } 253 254 ArtMethod* GetCalleeSaveOuterMethod(Thread* self, CalleeSaveType type) { 255 ScopedAssertNoThreadSuspension ants(__FUNCTION__); 256 ArtMethod** sp = self->GetManagedStack()->GetTopQuickFrameKnownNotTagged(); 257 return DoGetCalleeSaveMethodOuterCallerAndPc(sp, type).first; 258 } 259 260 ObjPtr<mirror::MethodHandle> ResolveMethodHandleFromCode(ArtMethod* referrer, 261 uint32_t method_handle_idx) { 262 Thread::PoisonObjectPointersIfDebug(); 263 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 264 return class_linker->ResolveMethodHandle(Thread::Current(), method_handle_idx, referrer); 265 } 266 267 ObjPtr<mirror::MethodType> ResolveMethodTypeFromCode(ArtMethod* referrer, 268 dex::ProtoIndex proto_idx) { 269 Thread::PoisonObjectPointersIfDebug(); 270 ObjPtr<mirror::MethodType> method_type = 271 referrer->GetDexCache()->GetResolvedMethodType(proto_idx); 272 if (UNLIKELY(method_type == nullptr)) { 273 StackHandleScope<2> hs(Thread::Current()); 274 Handle<mirror::DexCache> dex_cache(hs.NewHandle(referrer->GetDexCache())); 275 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(referrer->GetClassLoader())); 276 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 277 method_type = class_linker->ResolveMethodType(hs.Self(), proto_idx, dex_cache, class_loader); 278 } 279 return method_type; 280 } 281 282 } // namespace art 283