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 "class_linker-inl.h" 20 #include "dex_file-inl.h" 21 #include "gc/accounting/card_table-inl.h" 22 #include "mirror/art_field-inl.h" 23 #include "mirror/art_method-inl.h" 24 #include "mirror/class-inl.h" 25 #include "mirror/object-inl.h" 26 #include "object_utils.h" 27 #include "mirror/object_array-inl.h" 28 #include "mirror/proxy.h" 29 #include "reflection.h" 30 #include "scoped_thread_state_change.h" 31 #include "ScopedLocalRef.h" 32 #include "well_known_classes.h" 33 34 namespace art { 35 36 // Helper function to allocate array for FILLED_NEW_ARRAY. 37 mirror::Array* CheckAndAllocArrayFromCode(uint32_t type_idx, mirror::ArtMethod* referrer, 38 int32_t component_count, Thread* self, 39 bool access_check) { 40 if (UNLIKELY(component_count < 0)) { 41 ThrowNegativeArraySizeException(component_count); 42 return NULL; // Failure 43 } 44 mirror::Class* klass = referrer->GetDexCacheResolvedTypes()->Get(type_idx); 45 if (UNLIKELY(klass == NULL)) { // Not in dex cache so try to resolve 46 klass = Runtime::Current()->GetClassLinker()->ResolveType(type_idx, referrer); 47 if (klass == NULL) { // Error 48 DCHECK(self->IsExceptionPending()); 49 return NULL; // Failure 50 } 51 } 52 if (UNLIKELY(klass->IsPrimitive() && !klass->IsPrimitiveInt())) { 53 if (klass->IsPrimitiveLong() || klass->IsPrimitiveDouble()) { 54 ThrowRuntimeException("Bad filled array request for type %s", 55 PrettyDescriptor(klass).c_str()); 56 } else { 57 ThrowLocation throw_location = self->GetCurrentLocationForThrow(); 58 DCHECK(throw_location.GetMethod() == referrer); 59 self->ThrowNewExceptionF(throw_location, "Ljava/lang/InternalError;", 60 "Found type %s; filled-new-array not implemented for anything but \'int\'", 61 PrettyDescriptor(klass).c_str()); 62 } 63 return NULL; // Failure 64 } else { 65 if (access_check) { 66 mirror::Class* referrer_klass = referrer->GetDeclaringClass(); 67 if (UNLIKELY(!referrer_klass->CanAccess(klass))) { 68 ThrowIllegalAccessErrorClass(referrer_klass, klass); 69 return NULL; // Failure 70 } 71 } 72 DCHECK(klass->IsArrayClass()) << PrettyClass(klass); 73 return mirror::Array::Alloc(self, klass, component_count); 74 } 75 } 76 77 mirror::ArtField* FindFieldFromCode(uint32_t field_idx, const mirror::ArtMethod* referrer, 78 Thread* self, FindFieldType type, size_t expected_size, 79 bool access_check) { 80 bool is_primitive; 81 bool is_set; 82 bool is_static; 83 switch (type) { 84 case InstanceObjectRead: is_primitive = false; is_set = false; is_static = false; break; 85 case InstanceObjectWrite: is_primitive = false; is_set = true; is_static = false; break; 86 case InstancePrimitiveRead: is_primitive = true; is_set = false; is_static = false; break; 87 case InstancePrimitiveWrite: is_primitive = true; is_set = true; is_static = false; break; 88 case StaticObjectRead: is_primitive = false; is_set = false; is_static = true; break; 89 case StaticObjectWrite: is_primitive = false; is_set = true; is_static = true; break; 90 case StaticPrimitiveRead: is_primitive = true; is_set = false; is_static = true; break; 91 case StaticPrimitiveWrite: // Keep GCC happy by having a default handler, fall-through. 92 default: is_primitive = true; is_set = true; is_static = true; break; 93 } 94 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 95 mirror::ArtField* resolved_field = class_linker->ResolveField(field_idx, referrer, is_static); 96 if (UNLIKELY(resolved_field == NULL)) { 97 DCHECK(self->IsExceptionPending()); // Throw exception and unwind. 98 return NULL; // Failure. 99 } 100 mirror::Class* fields_class = resolved_field->GetDeclaringClass(); 101 if (access_check) { 102 if (UNLIKELY(resolved_field->IsStatic() != is_static)) { 103 ThrowIncompatibleClassChangeErrorField(resolved_field, is_static, referrer); 104 return NULL; 105 } 106 mirror::Class* referring_class = referrer->GetDeclaringClass(); 107 if (UNLIKELY(!referring_class->CanAccess(fields_class) || 108 !referring_class->CanAccessMember(fields_class, 109 resolved_field->GetAccessFlags()))) { 110 // The referring class can't access the resolved field, this may occur as a result of a 111 // protected field being made public by a sub-class. Resort to the dex file to determine 112 // the correct class for the access check. 113 const DexFile& dex_file = *referring_class->GetDexCache()->GetDexFile(); 114 fields_class = class_linker->ResolveType(dex_file, 115 dex_file.GetFieldId(field_idx).class_idx_, 116 referring_class); 117 if (UNLIKELY(!referring_class->CanAccess(fields_class))) { 118 ThrowIllegalAccessErrorClass(referring_class, fields_class); 119 return NULL; // failure 120 } else if (UNLIKELY(!referring_class->CanAccessMember(fields_class, 121 resolved_field->GetAccessFlags()))) { 122 ThrowIllegalAccessErrorField(referring_class, resolved_field); 123 return NULL; // failure 124 } 125 } 126 if (UNLIKELY(is_set && resolved_field->IsFinal() && (fields_class != referring_class))) { 127 ThrowIllegalAccessErrorFinalField(referrer, resolved_field); 128 return NULL; // failure 129 } else { 130 FieldHelper fh(resolved_field); 131 if (UNLIKELY(fh.IsPrimitiveType() != is_primitive || 132 fh.FieldSize() != expected_size)) { 133 ThrowLocation throw_location = self->GetCurrentLocationForThrow(); 134 DCHECK(throw_location.GetMethod() == referrer); 135 self->ThrowNewExceptionF(throw_location, "Ljava/lang/NoSuchFieldError;", 136 "Attempted read of %zd-bit %s on field '%s'", 137 expected_size * (32 / sizeof(int32_t)), 138 is_primitive ? "primitive" : "non-primitive", 139 PrettyField(resolved_field, true).c_str()); 140 return NULL; // failure 141 } 142 } 143 } 144 if (!is_static) { 145 // instance fields must be being accessed on an initialized class 146 return resolved_field; 147 } else { 148 // If the class is initialized we're done. 149 if (fields_class->IsInitialized()) { 150 return resolved_field; 151 } else if (Runtime::Current()->GetClassLinker()->EnsureInitialized(fields_class, true, true)) { 152 // Otherwise let's ensure the class is initialized before resolving the field. 153 return resolved_field; 154 } else { 155 DCHECK(self->IsExceptionPending()); // Throw exception and unwind 156 return NULL; // failure 157 } 158 } 159 } 160 161 // Slow path method resolution 162 mirror::ArtMethod* FindMethodFromCode(uint32_t method_idx, mirror::Object* this_object, 163 mirror::ArtMethod* referrer, 164 Thread* self, bool access_check, InvokeType type) { 165 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 166 bool is_direct = type == kStatic || type == kDirect; 167 mirror::ArtMethod* resolved_method = class_linker->ResolveMethod(method_idx, referrer, type); 168 if (UNLIKELY(resolved_method == NULL)) { 169 DCHECK(self->IsExceptionPending()); // Throw exception and unwind. 170 return NULL; // Failure. 171 } else if (UNLIKELY(this_object == NULL && type != kStatic)) { 172 // Maintain interpreter-like semantics where NullPointerException is thrown 173 // after potential NoSuchMethodError from class linker. 174 ThrowLocation throw_location = self->GetCurrentLocationForThrow(); 175 DCHECK(referrer == throw_location.GetMethod()); 176 ThrowNullPointerExceptionForMethodAccess(throw_location, method_idx, type); 177 return NULL; // Failure. 178 } else { 179 if (!access_check) { 180 if (is_direct) { 181 return resolved_method; 182 } else if (type == kInterface) { 183 mirror::ArtMethod* interface_method = 184 this_object->GetClass()->FindVirtualMethodForInterface(resolved_method); 185 if (UNLIKELY(interface_method == NULL)) { 186 ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(resolved_method, this_object, 187 referrer); 188 return NULL; // Failure. 189 } else { 190 return interface_method; 191 } 192 } else { 193 mirror::ObjectArray<mirror::ArtMethod>* vtable; 194 uint16_t vtable_index = resolved_method->GetMethodIndex(); 195 if (type == kSuper) { 196 vtable = referrer->GetDeclaringClass()->GetSuperClass()->GetVTable(); 197 } else { 198 vtable = this_object->GetClass()->GetVTable(); 199 } 200 // TODO: eliminate bounds check? 201 return vtable->Get(vtable_index); 202 } 203 } else { 204 // Incompatible class change should have been handled in resolve method. 205 if (UNLIKELY(resolved_method->CheckIncompatibleClassChange(type))) { 206 ThrowIncompatibleClassChangeError(type, resolved_method->GetInvokeType(), resolved_method, 207 referrer); 208 return NULL; // Failure. 209 } 210 mirror::Class* methods_class = resolved_method->GetDeclaringClass(); 211 mirror::Class* referring_class = referrer->GetDeclaringClass(); 212 if (UNLIKELY(!referring_class->CanAccess(methods_class) || 213 !referring_class->CanAccessMember(methods_class, 214 resolved_method->GetAccessFlags()))) { 215 // The referring class can't access the resolved method, this may occur as a result of a 216 // protected method being made public by implementing an interface that re-declares the 217 // method public. Resort to the dex file to determine the correct class for the access check 218 const DexFile& dex_file = *referring_class->GetDexCache()->GetDexFile(); 219 methods_class = class_linker->ResolveType(dex_file, 220 dex_file.GetMethodId(method_idx).class_idx_, 221 referring_class); 222 if (UNLIKELY(!referring_class->CanAccess(methods_class))) { 223 ThrowIllegalAccessErrorClassForMethodDispatch(referring_class, methods_class, 224 referrer, resolved_method, type); 225 return NULL; // Failure. 226 } else if (UNLIKELY(!referring_class->CanAccessMember(methods_class, 227 resolved_method->GetAccessFlags()))) { 228 ThrowIllegalAccessErrorMethod(referring_class, resolved_method); 229 return NULL; // Failure. 230 } 231 } 232 if (is_direct) { 233 return resolved_method; 234 } else if (type == kInterface) { 235 mirror::ArtMethod* interface_method = 236 this_object->GetClass()->FindVirtualMethodForInterface(resolved_method); 237 if (UNLIKELY(interface_method == NULL)) { 238 ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(resolved_method, this_object, 239 referrer); 240 return NULL; // Failure. 241 } else { 242 return interface_method; 243 } 244 } else { 245 mirror::ObjectArray<mirror::ArtMethod>* vtable; 246 uint16_t vtable_index = resolved_method->GetMethodIndex(); 247 if (type == kSuper) { 248 mirror::Class* super_class = referring_class->GetSuperClass(); 249 if (LIKELY(super_class != NULL)) { 250 vtable = referring_class->GetSuperClass()->GetVTable(); 251 } else { 252 vtable = NULL; 253 } 254 } else { 255 vtable = this_object->GetClass()->GetVTable(); 256 } 257 if (LIKELY(vtable != NULL && 258 vtable_index < static_cast<uint32_t>(vtable->GetLength()))) { 259 return vtable->GetWithoutChecks(vtable_index); 260 } else { 261 // Behavior to agree with that of the verifier. 262 MethodHelper mh(resolved_method); 263 ThrowNoSuchMethodError(type, resolved_method->GetDeclaringClass(), mh.GetName(), 264 mh.GetSignature()); 265 return NULL; // Failure. 266 } 267 } 268 } 269 } 270 } 271 272 void ThrowStackOverflowError(Thread* self) { 273 if (self->IsHandlingStackOverflow()) { 274 LOG(ERROR) << "Recursive stack overflow."; 275 // We don't fail here because SetStackEndForStackOverflow will print better diagnostics. 276 } 277 278 if (Runtime::Current()->GetInstrumentation()->AreExitStubsInstalled()) { 279 // Remove extra entry pushed onto second stack during method tracing. 280 Runtime::Current()->GetInstrumentation()->PopMethodForUnwind(self, false); 281 } 282 283 self->SetStackEndForStackOverflow(); // Allow space on the stack for constructor to execute. 284 JNIEnvExt* env = self->GetJniEnv(); 285 std::string msg("stack size "); 286 msg += PrettySize(self->GetStackSize()); 287 // Use low-level JNI routine and pre-baked error class to avoid class linking operations that 288 // would consume more stack. 289 int rc = ::art::ThrowNewException(env, WellKnownClasses::java_lang_StackOverflowError, 290 msg.c_str(), NULL); 291 if (rc != JNI_OK) { 292 // TODO: ThrowNewException failed presumably because of an OOME, we continue to throw the OOME 293 // or die in the CHECK below. We may want to throw a pre-baked StackOverflowError 294 // instead. 295 LOG(ERROR) << "Couldn't throw new StackOverflowError because JNI ThrowNew failed."; 296 CHECK(self->IsExceptionPending()); 297 } 298 self->ResetDefaultStackEnd(); // Return to default stack size. 299 } 300 301 JValue InvokeProxyInvocationHandler(ScopedObjectAccessUnchecked& soa, const char* shorty, 302 jobject rcvr_jobj, jobject interface_method_jobj, 303 std::vector<jvalue>& args) { 304 DCHECK(soa.Env()->IsInstanceOf(rcvr_jobj, WellKnownClasses::java_lang_reflect_Proxy)); 305 306 // Build argument array possibly triggering GC. 307 soa.Self()->AssertThreadSuspensionIsAllowable(); 308 jobjectArray args_jobj = NULL; 309 const JValue zero; 310 if (args.size() > 0) { 311 args_jobj = soa.Env()->NewObjectArray(args.size(), WellKnownClasses::java_lang_Object, NULL); 312 if (args_jobj == NULL) { 313 CHECK(soa.Self()->IsExceptionPending()); 314 return zero; 315 } 316 for (size_t i = 0; i < args.size(); ++i) { 317 if (shorty[i + 1] == 'L') { 318 jobject val = args.at(i).l; 319 soa.Env()->SetObjectArrayElement(args_jobj, i, val); 320 } else { 321 JValue jv; 322 jv.SetJ(args.at(i).j); 323 mirror::Object* val = BoxPrimitive(Primitive::GetType(shorty[i + 1]), jv); 324 if (val == NULL) { 325 CHECK(soa.Self()->IsExceptionPending()); 326 return zero; 327 } 328 soa.Decode<mirror::ObjectArray<mirror::Object>* >(args_jobj)->Set(i, val); 329 } 330 } 331 } 332 333 // Call Proxy.invoke(Proxy proxy, ArtMethod method, Object[] args). 334 jvalue invocation_args[3]; 335 invocation_args[0].l = rcvr_jobj; 336 invocation_args[1].l = interface_method_jobj; 337 invocation_args[2].l = args_jobj; 338 jobject result = 339 soa.Env()->CallStaticObjectMethodA(WellKnownClasses::java_lang_reflect_Proxy, 340 WellKnownClasses::java_lang_reflect_Proxy_invoke, 341 invocation_args); 342 343 // Unbox result and handle error conditions. 344 if (LIKELY(!soa.Self()->IsExceptionPending())) { 345 if (shorty[0] == 'V' || (shorty[0] == 'L' && result == NULL)) { 346 // Do nothing. 347 return zero; 348 } else { 349 mirror::Object* result_ref = soa.Decode<mirror::Object*>(result); 350 mirror::Object* rcvr = soa.Decode<mirror::Object*>(rcvr_jobj); 351 mirror::ArtMethod* interface_method = 352 soa.Decode<mirror::ArtMethod*>(interface_method_jobj); 353 mirror::Class* result_type = MethodHelper(interface_method).GetReturnType(); 354 mirror::ArtMethod* proxy_method; 355 if (interface_method->GetDeclaringClass()->IsInterface()) { 356 proxy_method = rcvr->GetClass()->FindVirtualMethodForInterface(interface_method); 357 } else { 358 // Proxy dispatch to a method defined in Object. 359 DCHECK(interface_method->GetDeclaringClass()->IsObjectClass()); 360 proxy_method = interface_method; 361 } 362 ThrowLocation throw_location(rcvr, proxy_method, -1); 363 JValue result_unboxed; 364 if (!UnboxPrimitiveForResult(throw_location, result_ref, result_type, result_unboxed)) { 365 DCHECK(soa.Self()->IsExceptionPending()); 366 return zero; 367 } 368 return result_unboxed; 369 } 370 } else { 371 // In the case of checked exceptions that aren't declared, the exception must be wrapped by 372 // a UndeclaredThrowableException. 373 mirror::Throwable* exception = soa.Self()->GetException(NULL); 374 if (exception->IsCheckedException()) { 375 mirror::Object* rcvr = soa.Decode<mirror::Object*>(rcvr_jobj); 376 mirror::SynthesizedProxyClass* proxy_class = 377 down_cast<mirror::SynthesizedProxyClass*>(rcvr->GetClass()); 378 mirror::ArtMethod* interface_method = 379 soa.Decode<mirror::ArtMethod*>(interface_method_jobj); 380 mirror::ArtMethod* proxy_method = 381 rcvr->GetClass()->FindVirtualMethodForInterface(interface_method); 382 int throws_index = -1; 383 size_t num_virt_methods = proxy_class->NumVirtualMethods(); 384 for (size_t i = 0; i < num_virt_methods; i++) { 385 if (proxy_class->GetVirtualMethod(i) == proxy_method) { 386 throws_index = i; 387 break; 388 } 389 } 390 CHECK_NE(throws_index, -1); 391 mirror::ObjectArray<mirror::Class>* declared_exceptions = proxy_class->GetThrows()->Get(throws_index); 392 mirror::Class* exception_class = exception->GetClass(); 393 bool declares_exception = false; 394 for (int i = 0; i < declared_exceptions->GetLength() && !declares_exception; i++) { 395 mirror::Class* declared_exception = declared_exceptions->Get(i); 396 declares_exception = declared_exception->IsAssignableFrom(exception_class); 397 } 398 if (!declares_exception) { 399 ThrowLocation throw_location(rcvr, proxy_method, -1); 400 soa.Self()->ThrowNewWrappedException(throw_location, 401 "Ljava/lang/reflect/UndeclaredThrowableException;", 402 NULL); 403 } 404 } 405 return zero; 406 } 407 } 408 409 } // namespace art 410