1 /* Copyright (C) 2016 The Android Open Source Project 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This file implements interfaces from the file jvmti.h. This implementation 5 * is licensed under the same terms as the file jvmti.h. The 6 * copyright and license information for the file jvmti.h follows. 7 * 8 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. 9 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10 * 11 * This code is free software; you can redistribute it and/or modify it 12 * under the terms of the GNU General Public License version 2 only, as 13 * published by the Free Software Foundation. Oracle designates this 14 * particular file as subject to the "Classpath" exception as provided 15 * by Oracle in the LICENSE file that accompanied this code. 16 * 17 * This code is distributed in the hope that it will be useful, but WITHOUT 18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20 * version 2 for more details (a copy is included in the LICENSE file that 21 * accompanied this code). 22 * 23 * You should have received a copy of the GNU General Public License version 24 * 2 along with this work; if not, write to the Free Software Foundation, 25 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 26 * 27 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 28 * or visit www.oracle.com if you need additional information or have any 29 * questions. 30 */ 31 32 #include "ti_class.h" 33 34 #include "android-base/stringprintf.h" 35 36 #include <mutex> 37 #include <unordered_set> 38 39 #include "art_jvmti.h" 40 #include "base/macros.h" 41 #include "class_table-inl.h" 42 #include "class_linker.h" 43 #include "common_throws.h" 44 #include "dex_file_annotations.h" 45 #include "events-inl.h" 46 #include "fixed_up_dex_file.h" 47 #include "gc/heap.h" 48 #include "gc_root.h" 49 #include "handle.h" 50 #include "jni_env_ext-inl.h" 51 #include "jni_internal.h" 52 #include "mirror/array-inl.h" 53 #include "mirror/class-inl.h" 54 #include "mirror/class_ext.h" 55 #include "mirror/object_array-inl.h" 56 #include "mirror/object_reference.h" 57 #include "mirror/object-inl.h" 58 #include "mirror/object-refvisitor-inl.h" 59 #include "mirror/reference.h" 60 #include "primitive.h" 61 #include "reflection.h" 62 #include "runtime.h" 63 #include "runtime_callbacks.h" 64 #include "ScopedLocalRef.h" 65 #include "scoped_thread_state_change-inl.h" 66 #include "thread-inl.h" 67 #include "thread_list.h" 68 #include "ti_class_loader.h" 69 #include "ti_phase.h" 70 #include "ti_redefine.h" 71 #include "utils.h" 72 #include "well_known_classes.h" 73 74 namespace openjdkjvmti { 75 76 using android::base::StringPrintf; 77 78 static std::unique_ptr<const art::DexFile> MakeSingleDexFile(art::Thread* self, 79 const char* descriptor, 80 const std::string& orig_location, 81 jint final_len, 82 const unsigned char* final_dex_data) 83 REQUIRES_SHARED(art::Locks::mutator_lock_) { 84 // Make the mmap 85 std::string error_msg; 86 art::ArraySlice<const unsigned char> final_data(final_dex_data, final_len); 87 std::unique_ptr<art::MemMap> map(Redefiner::MoveDataToMemMap(orig_location, 88 final_data, 89 &error_msg)); 90 if (map.get() == nullptr) { 91 LOG(WARNING) << "Unable to allocate mmap for redefined dex file! Error was: " << error_msg; 92 self->ThrowOutOfMemoryError(StringPrintf( 93 "Unable to allocate dex file for transformation of %s", descriptor).c_str()); 94 return nullptr; 95 } 96 97 // Make a dex-file 98 if (map->Size() < sizeof(art::DexFile::Header)) { 99 LOG(WARNING) << "Could not read dex file header because dex_data was too short"; 100 art::ThrowClassFormatError(nullptr, 101 "Unable to read transformed dex file of %s", 102 descriptor); 103 return nullptr; 104 } 105 uint32_t checksum = reinterpret_cast<const art::DexFile::Header*>(map->Begin())->checksum_; 106 std::unique_ptr<const art::DexFile> dex_file(art::DexFile::Open(map->GetName(), 107 checksum, 108 std::move(map), 109 /*verify*/true, 110 /*verify_checksum*/true, 111 &error_msg)); 112 if (dex_file.get() == nullptr) { 113 LOG(WARNING) << "Unable to load modified dex file for " << descriptor << ": " << error_msg; 114 art::ThrowClassFormatError(nullptr, 115 "Unable to read transformed dex file of %s because %s", 116 descriptor, 117 error_msg.c_str()); 118 return nullptr; 119 } 120 if (dex_file->NumClassDefs() != 1) { 121 LOG(WARNING) << "Dex file contains more than 1 class_def. Ignoring."; 122 // TODO Throw some other sort of error here maybe? 123 art::ThrowClassFormatError( 124 nullptr, 125 "Unable to use transformed dex file of %s because it contained too many classes", 126 descriptor); 127 return nullptr; 128 } 129 return dex_file; 130 } 131 132 struct ClassCallback : public art::ClassLoadCallback { 133 void ClassPreDefine(const char* descriptor, 134 art::Handle<art::mirror::Class> klass, 135 art::Handle<art::mirror::ClassLoader> class_loader, 136 const art::DexFile& initial_dex_file, 137 const art::DexFile::ClassDef& initial_class_def ATTRIBUTE_UNUSED, 138 /*out*/art::DexFile const** final_dex_file, 139 /*out*/art::DexFile::ClassDef const** final_class_def) 140 OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) { 141 bool is_enabled = 142 event_handler->IsEventEnabledAnywhere(ArtJvmtiEvent::kClassFileLoadHookRetransformable) || 143 event_handler->IsEventEnabledAnywhere(ArtJvmtiEvent::kClassFileLoadHookNonRetransformable); 144 if (!is_enabled) { 145 return; 146 } 147 if (descriptor[0] != 'L') { 148 // It is a primitive or array. Just return 149 return; 150 } 151 jvmtiPhase phase = PhaseUtil::GetPhaseUnchecked(); 152 if (UNLIKELY(phase != JVMTI_PHASE_START && phase != JVMTI_PHASE_LIVE)) { 153 // We want to wait until we are at least in the START phase so that all WellKnownClasses and 154 // mirror classes have been initialized and loaded. The runtime relies on these classes having 155 // specific fields and methods present. Since PreDefine hooks don't need to abide by this 156 // restriction we will simply not send the event for these classes. 157 LOG(WARNING) << "Ignoring load of class <" << descriptor << "> as it is being loaded during " 158 << "runtime initialization."; 159 return; 160 } 161 162 // Strip the 'L' and ';' from the descriptor 163 std::string name(std::string(descriptor).substr(1, strlen(descriptor) - 2)); 164 165 art::Thread* self = art::Thread::Current(); 166 art::JNIEnvExt* env = self->GetJniEnv(); 167 ScopedLocalRef<jobject> loader( 168 env, class_loader.IsNull() ? nullptr : env->AddLocalReference<jobject>(class_loader.Get())); 169 std::unique_ptr<FixedUpDexFile> dex_file_copy(FixedUpDexFile::Create(initial_dex_file)); 170 171 // Go back to native. 172 art::ScopedThreadSuspension sts(self, art::ThreadState::kNative); 173 // Call all Non-retransformable agents. 174 jint post_no_redefine_len = 0; 175 unsigned char* post_no_redefine_dex_data = nullptr; 176 std::unique_ptr<const unsigned char> post_no_redefine_unique_ptr(nullptr); 177 event_handler->DispatchEvent<ArtJvmtiEvent::kClassFileLoadHookNonRetransformable>( 178 self, 179 static_cast<JNIEnv*>(env), 180 static_cast<jclass>(nullptr), // The class doesn't really exist yet so send null. 181 loader.get(), 182 name.c_str(), 183 static_cast<jobject>(nullptr), // Android doesn't seem to have protection domains 184 static_cast<jint>(dex_file_copy->Size()), 185 static_cast<const unsigned char*>(dex_file_copy->Begin()), 186 static_cast<jint*>(&post_no_redefine_len), 187 static_cast<unsigned char**>(&post_no_redefine_dex_data)); 188 if (post_no_redefine_dex_data == nullptr) { 189 DCHECK_EQ(post_no_redefine_len, 0); 190 post_no_redefine_dex_data = const_cast<unsigned char*>(dex_file_copy->Begin()); 191 post_no_redefine_len = dex_file_copy->Size(); 192 } else { 193 post_no_redefine_unique_ptr = std::unique_ptr<const unsigned char>(post_no_redefine_dex_data); 194 DCHECK_GT(post_no_redefine_len, 0); 195 } 196 // Call all retransformable agents. 197 jint final_len = 0; 198 unsigned char* final_dex_data = nullptr; 199 std::unique_ptr<const unsigned char> final_dex_unique_ptr(nullptr); 200 event_handler->DispatchEvent<ArtJvmtiEvent::kClassFileLoadHookRetransformable>( 201 self, 202 static_cast<JNIEnv*>(env), 203 static_cast<jclass>(nullptr), // The class doesn't really exist yet so send null. 204 loader.get(), 205 name.c_str(), 206 static_cast<jobject>(nullptr), // Android doesn't seem to have protection domains 207 static_cast<jint>(post_no_redefine_len), 208 static_cast<const unsigned char*>(post_no_redefine_dex_data), 209 static_cast<jint*>(&final_len), 210 static_cast<unsigned char**>(&final_dex_data)); 211 if (final_dex_data == nullptr) { 212 DCHECK_EQ(final_len, 0); 213 final_dex_data = post_no_redefine_dex_data; 214 final_len = post_no_redefine_len; 215 } else { 216 final_dex_unique_ptr = std::unique_ptr<const unsigned char>(final_dex_data); 217 DCHECK_GT(final_len, 0); 218 } 219 220 if (final_dex_data != dex_file_copy->Begin()) { 221 LOG(WARNING) << "Changing class " << descriptor; 222 art::ScopedObjectAccess soa(self); 223 art::StackHandleScope<2> hs(self); 224 // Save the results of all the non-retransformable agents. 225 // First allocate the ClassExt 226 art::Handle<art::mirror::ClassExt> ext(hs.NewHandle(klass->EnsureExtDataPresent(self))); 227 // Make sure we have a ClassExt. This is fine even though we are a temporary since it will 228 // get copied. 229 if (ext.IsNull()) { 230 // We will just return failure if we fail to allocate 231 LOG(WARNING) << "Could not allocate ext-data for class '" << descriptor << "'. " 232 << "Aborting transformation since we will be unable to store it."; 233 self->AssertPendingOOMException(); 234 return; 235 } 236 237 // Allocate the byte array to store the dex file bytes in. 238 art::MutableHandle<art::mirror::Object> arr(hs.NewHandle<art::mirror::Object>(nullptr)); 239 if (post_no_redefine_dex_data == dex_file_copy->Begin() && name != "java/lang/Long") { 240 // we didn't have any non-retransformable agents. We can just cache a pointer to the 241 // initial_dex_file. It will be kept live by the class_loader. 242 jlong dex_ptr = reinterpret_cast<uintptr_t>(&initial_dex_file); 243 art::JValue val; 244 val.SetJ(dex_ptr); 245 arr.Assign(art::BoxPrimitive(art::Primitive::kPrimLong, val)); 246 } else { 247 arr.Assign(art::mirror::ByteArray::AllocateAndFill( 248 self, 249 reinterpret_cast<const signed char*>(post_no_redefine_dex_data), 250 post_no_redefine_len)); 251 } 252 if (arr.IsNull()) { 253 LOG(WARNING) << "Unable to allocate memory for initial dex-file. Aborting transformation"; 254 self->AssertPendingOOMException(); 255 return; 256 } 257 258 std::unique_ptr<const art::DexFile> dex_file(MakeSingleDexFile(self, 259 descriptor, 260 initial_dex_file.GetLocation(), 261 final_len, 262 final_dex_data)); 263 if (dex_file.get() == nullptr) { 264 return; 265 } 266 267 // TODO Check Redefined dex file for all invariants. 268 LOG(WARNING) << "Dex file created by class-definition time transformation of " 269 << descriptor << " is not checked for all retransformation invariants."; 270 271 if (!ClassLoaderHelper::AddToClassLoader(self, class_loader, dex_file.get())) { 272 LOG(ERROR) << "Unable to add " << descriptor << " to class loader!"; 273 return; 274 } 275 276 // Actually set the ClassExt's original bytes once we have actually succeeded. 277 ext->SetOriginalDexFile(arr.Get()); 278 // Set the return values 279 *final_class_def = &dex_file->GetClassDef(0); 280 *final_dex_file = dex_file.release(); 281 } 282 } 283 284 void ClassLoad(art::Handle<art::mirror::Class> klass) REQUIRES_SHARED(art::Locks::mutator_lock_) { 285 if (event_handler->IsEventEnabledAnywhere(ArtJvmtiEvent::kClassLoad)) { 286 art::Thread* thread = art::Thread::Current(); 287 ScopedLocalRef<jclass> jklass(thread->GetJniEnv(), 288 thread->GetJniEnv()->AddLocalReference<jclass>(klass.Get())); 289 ScopedLocalRef<jthread> thread_jni( 290 thread->GetJniEnv(), thread->GetJniEnv()->AddLocalReference<jthread>(thread->GetPeer())); 291 { 292 art::ScopedThreadSuspension sts(thread, art::ThreadState::kNative); 293 event_handler->DispatchEvent<ArtJvmtiEvent::kClassLoad>( 294 thread, 295 static_cast<JNIEnv*>(thread->GetJniEnv()), 296 thread_jni.get(), 297 jklass.get()); 298 } 299 if (klass->IsTemp()) { 300 AddTempClass(thread, jklass.get()); 301 } 302 } 303 } 304 305 void ClassPrepare(art::Handle<art::mirror::Class> temp_klass, 306 art::Handle<art::mirror::Class> klass) 307 REQUIRES_SHARED(art::Locks::mutator_lock_) { 308 if (event_handler->IsEventEnabledAnywhere(ArtJvmtiEvent::kClassPrepare)) { 309 art::Thread* thread = art::Thread::Current(); 310 if (temp_klass.Get() != klass.Get()) { 311 DCHECK(temp_klass->IsTemp()); 312 DCHECK(temp_klass->IsRetired()); 313 HandleTempClass(thread, temp_klass, klass); 314 } 315 ScopedLocalRef<jclass> jklass(thread->GetJniEnv(), 316 thread->GetJniEnv()->AddLocalReference<jclass>(klass.Get())); 317 ScopedLocalRef<jthread> thread_jni( 318 thread->GetJniEnv(), thread->GetJniEnv()->AddLocalReference<jthread>(thread->GetPeer())); 319 art::ScopedThreadSuspension sts(thread, art::ThreadState::kNative); 320 event_handler->DispatchEvent<ArtJvmtiEvent::kClassPrepare>( 321 thread, 322 static_cast<JNIEnv*>(thread->GetJniEnv()), 323 thread_jni.get(), 324 jklass.get()); 325 } 326 } 327 328 // To support parallel class-loading, we need to perform some locking dances here. Namely, 329 // the fixup stage must not be holding the temp_classes lock when it fixes up the system 330 // (as that requires suspending all mutators). 331 332 void AddTempClass(art::Thread* self, jclass klass) { 333 std::unique_lock<std::mutex> mu(temp_classes_lock); 334 jclass global_klass = reinterpret_cast<jclass>(self->GetJniEnv()->NewGlobalRef(klass)); 335 temp_classes.push_back(global_klass); 336 } 337 338 void HandleTempClass(art::Thread* self, 339 art::Handle<art::mirror::Class> temp_klass, 340 art::Handle<art::mirror::Class> klass) 341 REQUIRES_SHARED(art::Locks::mutator_lock_) { 342 bool requires_fixup = false; 343 { 344 std::unique_lock<std::mutex> mu(temp_classes_lock); 345 if (temp_classes.empty()) { 346 return; 347 } 348 349 for (auto it = temp_classes.begin(); it != temp_classes.end(); ++it) { 350 if (temp_klass.Get() == art::ObjPtr<art::mirror::Class>::DownCast(self->DecodeJObject(*it))) { 351 self->GetJniEnv()->DeleteGlobalRef(*it); 352 temp_classes.erase(it); 353 requires_fixup = true; 354 break; 355 } 356 } 357 } 358 if (requires_fixup) { 359 FixupTempClass(self, temp_klass, klass); 360 } 361 } 362 363 void FixupTempClass(art::Thread* self, 364 art::Handle<art::mirror::Class> temp_klass, 365 art::Handle<art::mirror::Class> klass) 366 REQUIRES_SHARED(art::Locks::mutator_lock_) { 367 // Suspend everything. 368 art::gc::Heap* heap = art::Runtime::Current()->GetHeap(); 369 if (heap->IsGcConcurrentAndMoving()) { 370 // Need to take a heap dump while GC isn't running. See the 371 // comment in Heap::VisitObjects(). 372 heap->IncrementDisableMovingGC(self); 373 } 374 { 375 art::ScopedThreadSuspension sts(self, art::kWaitingForVisitObjects); 376 art::ScopedSuspendAll ssa("FixupTempClass"); 377 378 art::mirror::Class* input = temp_klass.Get(); 379 art::mirror::Class* output = klass.Get(); 380 381 FixupGlobalReferenceTables(input, output); 382 FixupLocalReferenceTables(self, input, output); 383 FixupHeap(input, output); 384 } 385 if (heap->IsGcConcurrentAndMoving()) { 386 heap->DecrementDisableMovingGC(self); 387 } 388 } 389 390 class RootUpdater : public art::RootVisitor { 391 public: 392 RootUpdater(const art::mirror::Class* input, art::mirror::Class* output) 393 : input_(input), output_(output) {} 394 395 void VisitRoots(art::mirror::Object*** roots, 396 size_t count, 397 const art::RootInfo& info ATTRIBUTE_UNUSED) 398 OVERRIDE { 399 for (size_t i = 0; i != count; ++i) { 400 if (*roots[i] == input_) { 401 *roots[i] = output_; 402 } 403 } 404 } 405 406 void VisitRoots(art::mirror::CompressedReference<art::mirror::Object>** roots, 407 size_t count, 408 const art::RootInfo& info ATTRIBUTE_UNUSED) 409 OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) { 410 for (size_t i = 0; i != count; ++i) { 411 if (roots[i]->AsMirrorPtr() == input_) { 412 roots[i]->Assign(output_); 413 } 414 } 415 } 416 417 private: 418 const art::mirror::Class* input_; 419 art::mirror::Class* output_; 420 }; 421 422 void FixupGlobalReferenceTables(art::mirror::Class* input, art::mirror::Class* output) 423 REQUIRES(art::Locks::mutator_lock_) { 424 art::JavaVMExt* java_vm = art::Runtime::Current()->GetJavaVM(); 425 426 // Fix up the global table with a root visitor. 427 RootUpdater global_update(input, output); 428 java_vm->VisitRoots(&global_update); 429 430 class WeakGlobalUpdate : public art::IsMarkedVisitor { 431 public: 432 WeakGlobalUpdate(art::mirror::Class* root_input, art::mirror::Class* root_output) 433 : input_(root_input), output_(root_output) {} 434 435 art::mirror::Object* IsMarked(art::mirror::Object* obj) OVERRIDE { 436 if (obj == input_) { 437 return output_; 438 } 439 return obj; 440 } 441 442 private: 443 const art::mirror::Class* input_; 444 art::mirror::Class* output_; 445 }; 446 WeakGlobalUpdate weak_global_update(input, output); 447 java_vm->SweepJniWeakGlobals(&weak_global_update); 448 } 449 450 void FixupLocalReferenceTables(art::Thread* self, 451 art::mirror::Class* input, 452 art::mirror::Class* output) 453 REQUIRES(art::Locks::mutator_lock_) { 454 class LocalUpdate { 455 public: 456 LocalUpdate(const art::mirror::Class* root_input, art::mirror::Class* root_output) 457 : input_(root_input), output_(root_output) {} 458 459 static void Callback(art::Thread* t, void* arg) REQUIRES(art::Locks::mutator_lock_) { 460 LocalUpdate* local = reinterpret_cast<LocalUpdate*>(arg); 461 462 // Fix up the local table with a root visitor. 463 RootUpdater local_update(local->input_, local->output_); 464 t->GetJniEnv()->locals.VisitRoots( 465 &local_update, art::RootInfo(art::kRootJNILocal, t->GetThreadId())); 466 } 467 468 private: 469 const art::mirror::Class* input_; 470 art::mirror::Class* output_; 471 }; 472 LocalUpdate local_upd(input, output); 473 art::MutexLock mu(self, *art::Locks::thread_list_lock_); 474 art::Runtime::Current()->GetThreadList()->ForEach(LocalUpdate::Callback, &local_upd); 475 } 476 477 void FixupHeap(art::mirror::Class* input, art::mirror::Class* output) 478 REQUIRES(art::Locks::mutator_lock_) { 479 class HeapFixupVisitor { 480 public: 481 HeapFixupVisitor(const art::mirror::Class* root_input, art::mirror::Class* root_output) 482 : input_(root_input), output_(root_output) {} 483 484 void operator()(art::mirror::Object* src, 485 art::MemberOffset field_offset, 486 bool is_static ATTRIBUTE_UNUSED) const 487 REQUIRES_SHARED(art::Locks::mutator_lock_) { 488 art::mirror::HeapReference<art::mirror::Object>* trg = 489 src->GetFieldObjectReferenceAddr(field_offset); 490 if (trg->AsMirrorPtr() == input_) { 491 DCHECK_NE(field_offset.Uint32Value(), 0u); // This shouldn't be the class field of 492 // an object. 493 trg->Assign(output_); 494 } 495 } 496 497 void operator()(art::ObjPtr<art::mirror::Class> klass ATTRIBUTE_UNUSED, 498 art::ObjPtr<art::mirror::Reference> reference) const 499 REQUIRES_SHARED(art::Locks::mutator_lock_) { 500 art::mirror::Object* val = reference->GetReferent(); 501 if (val == input_) { 502 reference->SetReferent<false>(output_); 503 } 504 } 505 506 void VisitRoot(art::mirror::CompressedReference<art::mirror::Object>* root ATTRIBUTE_UNUSED) 507 const { 508 LOG(FATAL) << "Unreachable"; 509 } 510 511 void VisitRootIfNonNull( 512 art::mirror::CompressedReference<art::mirror::Object>* root ATTRIBUTE_UNUSED) const { 513 LOG(FATAL) << "Unreachable"; 514 } 515 516 static void AllObjectsCallback(art::mirror::Object* obj, void* arg) 517 REQUIRES_SHARED(art::Locks::mutator_lock_) { 518 HeapFixupVisitor* hfv = reinterpret_cast<HeapFixupVisitor*>(arg); 519 520 // Visit references, not native roots. 521 obj->VisitReferences<false>(*hfv, *hfv); 522 } 523 524 private: 525 const art::mirror::Class* input_; 526 art::mirror::Class* output_; 527 }; 528 HeapFixupVisitor hfv(input, output); 529 art::Runtime::Current()->GetHeap()->VisitObjectsPaused(HeapFixupVisitor::AllObjectsCallback, 530 &hfv); 531 } 532 533 // A set of all the temp classes we have handed out. We have to fix up references to these. 534 // For simplicity, we store the temp classes as JNI global references in a vector. Normally a 535 // Prepare event will closely follow, so the vector should be small. 536 std::mutex temp_classes_lock; 537 std::vector<jclass> temp_classes; 538 539 EventHandler* event_handler = nullptr; 540 }; 541 542 ClassCallback gClassCallback; 543 544 void ClassUtil::Register(EventHandler* handler) { 545 gClassCallback.event_handler = handler; 546 art::ScopedThreadStateChange stsc(art::Thread::Current(), 547 art::ThreadState::kWaitingForDebuggerToAttach); 548 art::ScopedSuspendAll ssa("Add load callback"); 549 art::Runtime::Current()->GetRuntimeCallbacks()->AddClassLoadCallback(&gClassCallback); 550 } 551 552 void ClassUtil::Unregister() { 553 art::ScopedThreadStateChange stsc(art::Thread::Current(), 554 art::ThreadState::kWaitingForDebuggerToAttach); 555 art::ScopedSuspendAll ssa("Remove thread callback"); 556 art::Runtime* runtime = art::Runtime::Current(); 557 runtime->GetRuntimeCallbacks()->RemoveClassLoadCallback(&gClassCallback); 558 } 559 560 jvmtiError ClassUtil::GetClassFields(jvmtiEnv* env, 561 jclass jklass, 562 jint* field_count_ptr, 563 jfieldID** fields_ptr) { 564 art::ScopedObjectAccess soa(art::Thread::Current()); 565 art::ObjPtr<art::mirror::Class> klass = soa.Decode<art::mirror::Class>(jklass); 566 if (klass == nullptr) { 567 return ERR(INVALID_CLASS); 568 } 569 570 if (field_count_ptr == nullptr || fields_ptr == nullptr) { 571 return ERR(NULL_POINTER); 572 } 573 574 art::IterationRange<art::StrideIterator<art::ArtField>> ifields = klass->GetIFields(); 575 art::IterationRange<art::StrideIterator<art::ArtField>> sfields = klass->GetSFields(); 576 size_t array_size = klass->NumInstanceFields() + klass->NumStaticFields(); 577 578 unsigned char* out_ptr; 579 jvmtiError allocError = env->Allocate(array_size * sizeof(jfieldID), &out_ptr); 580 if (allocError != ERR(NONE)) { 581 return allocError; 582 } 583 jfieldID* field_array = reinterpret_cast<jfieldID*>(out_ptr); 584 585 size_t array_idx = 0; 586 for (art::ArtField& field : sfields) { 587 field_array[array_idx] = art::jni::EncodeArtField(&field); 588 ++array_idx; 589 } 590 for (art::ArtField& field : ifields) { 591 field_array[array_idx] = art::jni::EncodeArtField(&field); 592 ++array_idx; 593 } 594 595 *field_count_ptr = static_cast<jint>(array_size); 596 *fields_ptr = field_array; 597 598 return ERR(NONE); 599 } 600 601 jvmtiError ClassUtil::GetClassMethods(jvmtiEnv* env, 602 jclass jklass, 603 jint* method_count_ptr, 604 jmethodID** methods_ptr) { 605 art::ScopedObjectAccess soa(art::Thread::Current()); 606 art::ObjPtr<art::mirror::Class> klass = soa.Decode<art::mirror::Class>(jklass); 607 if (klass == nullptr) { 608 return ERR(INVALID_CLASS); 609 } 610 611 if (method_count_ptr == nullptr || methods_ptr == nullptr) { 612 return ERR(NULL_POINTER); 613 } 614 615 size_t array_size = klass->NumDeclaredVirtualMethods() + klass->NumDirectMethods(); 616 unsigned char* out_ptr; 617 jvmtiError allocError = env->Allocate(array_size * sizeof(jmethodID), &out_ptr); 618 if (allocError != ERR(NONE)) { 619 return allocError; 620 } 621 jmethodID* method_array = reinterpret_cast<jmethodID*>(out_ptr); 622 623 if (art::kIsDebugBuild) { 624 size_t count = 0; 625 for (auto& m ATTRIBUTE_UNUSED : klass->GetDeclaredMethods(art::kRuntimePointerSize)) { 626 count++; 627 } 628 CHECK_EQ(count, klass->NumDirectMethods() + klass->NumDeclaredVirtualMethods()); 629 } 630 631 size_t array_idx = 0; 632 for (auto& m : klass->GetDeclaredMethods(art::kRuntimePointerSize)) { 633 method_array[array_idx] = art::jni::EncodeArtMethod(&m); 634 ++array_idx; 635 } 636 637 *method_count_ptr = static_cast<jint>(array_size); 638 *methods_ptr = method_array; 639 640 return ERR(NONE); 641 } 642 643 jvmtiError ClassUtil::GetImplementedInterfaces(jvmtiEnv* env, 644 jclass jklass, 645 jint* interface_count_ptr, 646 jclass** interfaces_ptr) { 647 art::ScopedObjectAccess soa(art::Thread::Current()); 648 art::ObjPtr<art::mirror::Class> klass = soa.Decode<art::mirror::Class>(jklass); 649 if (klass == nullptr) { 650 return ERR(INVALID_CLASS); 651 } 652 653 if (interface_count_ptr == nullptr || interfaces_ptr == nullptr) { 654 return ERR(NULL_POINTER); 655 } 656 657 // Need to handle array specifically. Arrays implement Serializable and Cloneable, but the 658 // spec says these should not be reported. 659 if (klass->IsArrayClass()) { 660 *interface_count_ptr = 0; 661 *interfaces_ptr = nullptr; // TODO: Should we allocate a dummy here? 662 return ERR(NONE); 663 } 664 665 size_t array_size = klass->NumDirectInterfaces(); 666 unsigned char* out_ptr; 667 jvmtiError allocError = env->Allocate(array_size * sizeof(jclass), &out_ptr); 668 if (allocError != ERR(NONE)) { 669 return allocError; 670 } 671 jclass* interface_array = reinterpret_cast<jclass*>(out_ptr); 672 673 art::StackHandleScope<1> hs(soa.Self()); 674 art::Handle<art::mirror::Class> h_klass(hs.NewHandle(klass)); 675 676 for (uint32_t idx = 0; idx != array_size; ++idx) { 677 art::ObjPtr<art::mirror::Class> inf_klass = 678 art::mirror::Class::ResolveDirectInterface(soa.Self(), h_klass, idx); 679 if (inf_klass == nullptr) { 680 soa.Self()->ClearException(); 681 env->Deallocate(out_ptr); 682 // TODO: What is the right error code here? 683 return ERR(INTERNAL); 684 } 685 interface_array[idx] = soa.AddLocalReference<jclass>(inf_klass); 686 } 687 688 *interface_count_ptr = static_cast<jint>(array_size); 689 *interfaces_ptr = interface_array; 690 691 return ERR(NONE); 692 } 693 694 jvmtiError ClassUtil::GetClassSignature(jvmtiEnv* env, 695 jclass jklass, 696 char** signature_ptr, 697 char** generic_ptr) { 698 art::ScopedObjectAccess soa(art::Thread::Current()); 699 art::ObjPtr<art::mirror::Class> klass = soa.Decode<art::mirror::Class>(jklass); 700 if (klass == nullptr) { 701 return ERR(INVALID_CLASS); 702 } 703 704 JvmtiUniquePtr<char[]> sig_copy; 705 if (signature_ptr != nullptr) { 706 std::string storage; 707 const char* descriptor = klass->GetDescriptor(&storage); 708 709 jvmtiError ret; 710 sig_copy = CopyString(env, descriptor, &ret); 711 if (sig_copy == nullptr) { 712 return ret; 713 } 714 *signature_ptr = sig_copy.get(); 715 } 716 717 if (generic_ptr != nullptr) { 718 *generic_ptr = nullptr; 719 if (!klass->IsProxyClass() && klass->GetDexCache() != nullptr) { 720 art::StackHandleScope<1> hs(soa.Self()); 721 art::Handle<art::mirror::Class> h_klass = hs.NewHandle(klass); 722 art::mirror::ObjectArray<art::mirror::String>* str_array = 723 art::annotations::GetSignatureAnnotationForClass(h_klass); 724 if (str_array != nullptr) { 725 std::ostringstream oss; 726 for (int32_t i = 0; i != str_array->GetLength(); ++i) { 727 oss << str_array->Get(i)->ToModifiedUtf8(); 728 } 729 std::string output_string = oss.str(); 730 jvmtiError ret; 731 JvmtiUniquePtr<char[]> copy = CopyString(env, output_string.c_str(), &ret); 732 if (copy == nullptr) { 733 return ret; 734 } 735 *generic_ptr = copy.release(); 736 } else if (soa.Self()->IsExceptionPending()) { 737 // TODO: Should we report an error here? 738 soa.Self()->ClearException(); 739 } 740 } 741 } 742 743 // Everything is fine, release the buffers. 744 sig_copy.release(); 745 746 return ERR(NONE); 747 } 748 749 jvmtiError ClassUtil::GetClassStatus(jvmtiEnv* env ATTRIBUTE_UNUSED, 750 jclass jklass, 751 jint* status_ptr) { 752 art::ScopedObjectAccess soa(art::Thread::Current()); 753 art::ObjPtr<art::mirror::Class> klass = soa.Decode<art::mirror::Class>(jklass); 754 if (klass == nullptr) { 755 return ERR(INVALID_CLASS); 756 } 757 758 if (status_ptr == nullptr) { 759 return ERR(NULL_POINTER); 760 } 761 762 if (klass->IsArrayClass()) { 763 *status_ptr = JVMTI_CLASS_STATUS_ARRAY; 764 } else if (klass->IsPrimitive()) { 765 *status_ptr = JVMTI_CLASS_STATUS_PRIMITIVE; 766 } else { 767 *status_ptr = JVMTI_CLASS_STATUS_VERIFIED; // All loaded classes are structurally verified. 768 // This is finicky. If there's an error, we'll say it wasn't prepared. 769 if (klass->IsResolved()) { 770 *status_ptr |= JVMTI_CLASS_STATUS_PREPARED; 771 } 772 if (klass->IsInitialized()) { 773 *status_ptr |= JVMTI_CLASS_STATUS_INITIALIZED; 774 } 775 // Technically the class may be erroneous for other reasons, but we do not have enough info. 776 if (klass->IsErroneous()) { 777 *status_ptr |= JVMTI_CLASS_STATUS_ERROR; 778 } 779 } 780 781 return ERR(NONE); 782 } 783 784 template <typename T> 785 static jvmtiError ClassIsT(jclass jklass, T test, jboolean* is_t_ptr) { 786 art::ScopedObjectAccess soa(art::Thread::Current()); 787 art::ObjPtr<art::mirror::Class> klass = soa.Decode<art::mirror::Class>(jklass); 788 if (klass == nullptr) { 789 return ERR(INVALID_CLASS); 790 } 791 792 if (is_t_ptr == nullptr) { 793 return ERR(NULL_POINTER); 794 } 795 796 *is_t_ptr = test(klass) ? JNI_TRUE : JNI_FALSE; 797 return ERR(NONE); 798 } 799 800 jvmtiError ClassUtil::IsInterface(jvmtiEnv* env ATTRIBUTE_UNUSED, 801 jclass jklass, 802 jboolean* is_interface_ptr) { 803 auto test = [](art::ObjPtr<art::mirror::Class> klass) REQUIRES_SHARED(art::Locks::mutator_lock_) { 804 return klass->IsInterface(); 805 }; 806 return ClassIsT(jklass, test, is_interface_ptr); 807 } 808 809 jvmtiError ClassUtil::IsArrayClass(jvmtiEnv* env ATTRIBUTE_UNUSED, 810 jclass jklass, 811 jboolean* is_array_class_ptr) { 812 auto test = [](art::ObjPtr<art::mirror::Class> klass) REQUIRES_SHARED(art::Locks::mutator_lock_) { 813 return klass->IsArrayClass(); 814 }; 815 return ClassIsT(jklass, test, is_array_class_ptr); 816 } 817 818 // Keep this in sync with Class.getModifiers(). 819 static uint32_t ClassGetModifiers(art::Thread* self, art::ObjPtr<art::mirror::Class> klass) 820 REQUIRES_SHARED(art::Locks::mutator_lock_) { 821 if (klass->IsArrayClass()) { 822 uint32_t component_modifiers = ClassGetModifiers(self, klass->GetComponentType()); 823 if ((component_modifiers & art::kAccInterface) != 0) { 824 component_modifiers &= ~(art::kAccInterface | art::kAccStatic); 825 } 826 return art::kAccAbstract | art::kAccFinal | component_modifiers; 827 } 828 829 uint32_t modifiers = klass->GetAccessFlags() & art::kAccJavaFlagsMask; 830 831 art::StackHandleScope<1> hs(self); 832 art::Handle<art::mirror::Class> h_klass(hs.NewHandle(klass)); 833 return art::mirror::Class::GetInnerClassFlags(h_klass, modifiers); 834 } 835 836 jvmtiError ClassUtil::GetClassModifiers(jvmtiEnv* env ATTRIBUTE_UNUSED, 837 jclass jklass, 838 jint* modifiers_ptr) { 839 art::ScopedObjectAccess soa(art::Thread::Current()); 840 art::ObjPtr<art::mirror::Class> klass = soa.Decode<art::mirror::Class>(jklass); 841 if (klass == nullptr) { 842 return ERR(INVALID_CLASS); 843 } 844 845 if (modifiers_ptr == nullptr) { 846 return ERR(NULL_POINTER); 847 } 848 849 *modifiers_ptr = ClassGetModifiers(soa.Self(), klass); 850 851 return ERR(NONE); 852 } 853 854 jvmtiError ClassUtil::GetClassLoader(jvmtiEnv* env ATTRIBUTE_UNUSED, 855 jclass jklass, 856 jobject* classloader_ptr) { 857 art::ScopedObjectAccess soa(art::Thread::Current()); 858 art::ObjPtr<art::mirror::Class> klass = soa.Decode<art::mirror::Class>(jklass); 859 if (klass == nullptr) { 860 return ERR(INVALID_CLASS); 861 } 862 863 if (classloader_ptr == nullptr) { 864 return ERR(NULL_POINTER); 865 } 866 867 *classloader_ptr = soa.AddLocalReference<jobject>(klass->GetClassLoader()); 868 869 return ERR(NONE); 870 } 871 872 jvmtiError ClassUtil::GetClassLoaderClasses(jvmtiEnv* env, 873 jobject initiating_loader, 874 jint* class_count_ptr, 875 jclass** classes_ptr) { 876 UNUSED(env, initiating_loader, class_count_ptr, classes_ptr); 877 878 if (class_count_ptr == nullptr || classes_ptr == nullptr) { 879 return ERR(NULL_POINTER); 880 } 881 art::Thread* self = art::Thread::Current(); 882 if (!self->GetJniEnv()->IsInstanceOf(initiating_loader, 883 art::WellKnownClasses::java_lang_ClassLoader)) { 884 return ERR(ILLEGAL_ARGUMENT); 885 } 886 if (self->GetJniEnv()->IsInstanceOf(initiating_loader, 887 art::WellKnownClasses::java_lang_BootClassLoader)) { 888 // Need to use null for the BootClassLoader. 889 initiating_loader = nullptr; 890 } 891 892 art::ScopedObjectAccess soa(self); 893 art::ObjPtr<art::mirror::ClassLoader> class_loader = 894 soa.Decode<art::mirror::ClassLoader>(initiating_loader); 895 896 art::ClassLinker* class_linker = art::Runtime::Current()->GetClassLinker(); 897 898 art::ReaderMutexLock mu(self, *art::Locks::classlinker_classes_lock_); 899 900 art::ClassTable* class_table = class_linker->ClassTableForClassLoader(class_loader); 901 if (class_table == nullptr) { 902 // Nothing loaded. 903 *class_count_ptr = 0; 904 *classes_ptr = nullptr; 905 return ERR(NONE); 906 } 907 908 struct ClassTableCount { 909 bool operator()(art::ObjPtr<art::mirror::Class> klass) { 910 DCHECK(klass != nullptr); 911 ++count; 912 return true; 913 } 914 915 size_t count = 0; 916 }; 917 ClassTableCount ctc; 918 class_table->Visit(ctc); 919 920 if (ctc.count == 0) { 921 // Nothing loaded. 922 *class_count_ptr = 0; 923 *classes_ptr = nullptr; 924 return ERR(NONE); 925 } 926 927 unsigned char* data; 928 jvmtiError data_result = env->Allocate(ctc.count * sizeof(jclass), &data); 929 if (data_result != ERR(NONE)) { 930 return data_result; 931 } 932 jclass* class_array = reinterpret_cast<jclass*>(data); 933 934 struct ClassTableFill { 935 bool operator()(art::ObjPtr<art::mirror::Class> klass) 936 REQUIRES_SHARED(art::Locks::mutator_lock_) { 937 DCHECK(klass != nullptr); 938 DCHECK_LT(count, ctc_ref.count); 939 local_class_array[count++] = soa_ptr->AddLocalReference<jclass>(klass); 940 return true; 941 } 942 943 jclass* local_class_array; 944 const ClassTableCount& ctc_ref; 945 art::ScopedObjectAccess* soa_ptr; 946 size_t count; 947 }; 948 ClassTableFill ctf = { class_array, ctc, &soa, 0 }; 949 class_table->Visit(ctf); 950 DCHECK_EQ(ctc.count, ctf.count); 951 952 *class_count_ptr = ctc.count; 953 *classes_ptr = class_array; 954 955 return ERR(NONE); 956 } 957 958 jvmtiError ClassUtil::GetClassVersionNumbers(jvmtiEnv* env ATTRIBUTE_UNUSED, 959 jclass jklass, 960 jint* minor_version_ptr, 961 jint* major_version_ptr) { 962 art::ScopedObjectAccess soa(art::Thread::Current()); 963 if (jklass == nullptr) { 964 return ERR(INVALID_CLASS); 965 } 966 art::ObjPtr<art::mirror::Object> jklass_obj = soa.Decode<art::mirror::Object>(jklass); 967 if (!jklass_obj->IsClass()) { 968 return ERR(INVALID_CLASS); 969 } 970 art::ObjPtr<art::mirror::Class> klass = jklass_obj->AsClass(); 971 if (klass->IsPrimitive() || klass->IsArrayClass()) { 972 return ERR(INVALID_CLASS); 973 } 974 975 if (minor_version_ptr == nullptr || major_version_ptr == nullptr) { 976 return ERR(NULL_POINTER); 977 } 978 979 // Note: proxies will show the dex file version of java.lang.reflect.Proxy, as that is 980 // what their dex cache copies from. 981 uint32_t version = klass->GetDexFile().GetHeader().GetVersion(); 982 983 *major_version_ptr = static_cast<jint>(version); 984 *minor_version_ptr = 0; 985 986 return ERR(NONE); 987 } 988 989 } // namespace openjdkjvmti 990