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/array_ref.h" 41 #include "base/macros.h" 42 #include "base/utils.h" 43 #include "class_linker.h" 44 #include "class_loader_utils.h" 45 #include "class_table-inl.h" 46 #include "common_throws.h" 47 #include "dex/art_dex_file_loader.h" 48 #include "dex/dex_file_annotations.h" 49 #include "dex/dex_file_loader.h" 50 #include "dex/primitive.h" 51 #include "events-inl.h" 52 #include "fixed_up_dex_file.h" 53 #include "gc/heap-visit-objects-inl.h" 54 #include "gc/heap.h" 55 #include "gc_root.h" 56 #include "handle.h" 57 #include "jni_env_ext-inl.h" 58 #include "jni_internal.h" 59 #include "mirror/array-inl.h" 60 #include "mirror/class-inl.h" 61 #include "mirror/class_ext.h" 62 #include "mirror/object-inl.h" 63 #include "mirror/object-refvisitor-inl.h" 64 #include "mirror/object_array-inl.h" 65 #include "mirror/object_reference.h" 66 #include "mirror/reference.h" 67 #include "nativehelper/scoped_local_ref.h" 68 #include "reflection.h" 69 #include "runtime.h" 70 #include "runtime_callbacks.h" 71 #include "scoped_thread_state_change-inl.h" 72 #include "thread-current-inl.h" 73 #include "thread_list.h" 74 #include "ti_class_loader-inl.h" 75 #include "ti_phase.h" 76 #include "ti_redefine.h" 77 #include "well_known_classes.h" 78 79 namespace openjdkjvmti { 80 81 using android::base::StringPrintf; 82 83 static std::unique_ptr<const art::DexFile> MakeSingleDexFile(art::Thread* self, 84 const char* descriptor, 85 const std::string& orig_location, 86 jint final_len, 87 const unsigned char* final_dex_data) 88 REQUIRES_SHARED(art::Locks::mutator_lock_) { 89 // Make the mmap 90 std::string error_msg; 91 art::ArrayRef<const unsigned char> final_data(final_dex_data, final_len); 92 std::unique_ptr<art::MemMap> map(Redefiner::MoveDataToMemMap(orig_location, 93 final_data, 94 &error_msg)); 95 if (map.get() == nullptr) { 96 LOG(WARNING) << "Unable to allocate mmap for redefined dex file! Error was: " << error_msg; 97 self->ThrowOutOfMemoryError(StringPrintf( 98 "Unable to allocate dex file for transformation of %s", descriptor).c_str()); 99 return nullptr; 100 } 101 102 // Make a dex-file 103 if (map->Size() < sizeof(art::DexFile::Header)) { 104 LOG(WARNING) << "Could not read dex file header because dex_data was too short"; 105 art::ThrowClassFormatError(nullptr, 106 "Unable to read transformed dex file of %s", 107 descriptor); 108 return nullptr; 109 } 110 uint32_t checksum = reinterpret_cast<const art::DexFile::Header*>(map->Begin())->checksum_; 111 std::string map_name = map->GetName(); 112 const art::ArtDexFileLoader dex_file_loader; 113 std::unique_ptr<const art::DexFile> dex_file(dex_file_loader.Open(map_name, 114 checksum, 115 std::move(map), 116 /*verify*/true, 117 /*verify_checksum*/true, 118 &error_msg)); 119 if (dex_file.get() == nullptr) { 120 LOG(WARNING) << "Unable to load modified dex file for " << descriptor << ": " << error_msg; 121 art::ThrowClassFormatError(nullptr, 122 "Unable to read transformed dex file of %s because %s", 123 descriptor, 124 error_msg.c_str()); 125 return nullptr; 126 } 127 if (dex_file->NumClassDefs() != 1) { 128 LOG(WARNING) << "Dex file contains more than 1 class_def. Ignoring."; 129 // TODO Throw some other sort of error here maybe? 130 art::ThrowClassFormatError( 131 nullptr, 132 "Unable to use transformed dex file of %s because it contained too many classes", 133 descriptor); 134 return nullptr; 135 } 136 return dex_file; 137 } 138 139 // A deleter that acts like the jvmtiEnv->Deallocate so that asan does not get tripped up. 140 // TODO We should everything use the actual jvmtiEnv->Allocate/Deallocate functions once we can 141 // figure out which env to use. 142 template <typename T> 143 class FakeJvmtiDeleter { 144 public: 145 FakeJvmtiDeleter() {} 146 147 FakeJvmtiDeleter(FakeJvmtiDeleter&) = default; 148 FakeJvmtiDeleter(FakeJvmtiDeleter&&) = default; 149 FakeJvmtiDeleter& operator=(const FakeJvmtiDeleter&) = default; 150 151 template <typename U> void operator()(const U* ptr) const { 152 if (ptr != nullptr) { 153 free(const_cast<U*>(ptr)); 154 } 155 } 156 }; 157 158 struct ClassCallback : public art::ClassLoadCallback { 159 void ClassPreDefine(const char* descriptor, 160 art::Handle<art::mirror::Class> klass, 161 art::Handle<art::mirror::ClassLoader> class_loader, 162 const art::DexFile& initial_dex_file, 163 const art::DexFile::ClassDef& initial_class_def ATTRIBUTE_UNUSED, 164 /*out*/art::DexFile const** final_dex_file, 165 /*out*/art::DexFile::ClassDef const** final_class_def) 166 OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) { 167 bool is_enabled = 168 event_handler->IsEventEnabledAnywhere(ArtJvmtiEvent::kClassFileLoadHookRetransformable) || 169 event_handler->IsEventEnabledAnywhere(ArtJvmtiEvent::kClassFileLoadHookNonRetransformable); 170 if (!is_enabled) { 171 return; 172 } 173 if (descriptor[0] != 'L') { 174 // It is a primitive or array. Just return 175 return; 176 } 177 jvmtiPhase phase = PhaseUtil::GetPhaseUnchecked(); 178 if (UNLIKELY(phase != JVMTI_PHASE_START && phase != JVMTI_PHASE_LIVE)) { 179 // We want to wait until we are at least in the START phase so that all WellKnownClasses and 180 // mirror classes have been initialized and loaded. The runtime relies on these classes having 181 // specific fields and methods present. Since PreDefine hooks don't need to abide by this 182 // restriction we will simply not send the event for these classes. 183 LOG(WARNING) << "Ignoring load of class <" << descriptor << "> as it is being loaded during " 184 << "runtime initialization."; 185 return; 186 } 187 188 art::Thread* self = art::Thread::Current(); 189 ArtClassDefinition def; 190 def.InitFirstLoad(descriptor, class_loader, initial_dex_file); 191 192 // Call all non-retransformable agents. 193 Transformer::TransformSingleClassDirect<ArtJvmtiEvent::kClassFileLoadHookNonRetransformable>( 194 event_handler, self, &def); 195 196 std::vector<unsigned char> post_non_retransform; 197 if (def.IsModified()) { 198 // Copy the dex data after the non-retransformable events. 199 post_non_retransform.resize(def.GetDexData().size()); 200 memcpy(post_non_retransform.data(), def.GetDexData().data(), post_non_retransform.size()); 201 } 202 203 // Call all retransformable agents. 204 Transformer::TransformSingleClassDirect<ArtJvmtiEvent::kClassFileLoadHookRetransformable>( 205 event_handler, self, &def); 206 207 if (def.IsModified()) { 208 LOG(WARNING) << "Changing class " << descriptor; 209 art::StackHandleScope<2> hs(self); 210 // Save the results of all the non-retransformable agents. 211 // First allocate the ClassExt 212 art::Handle<art::mirror::ClassExt> ext(hs.NewHandle(klass->EnsureExtDataPresent(self))); 213 // Make sure we have a ClassExt. This is fine even though we are a temporary since it will 214 // get copied. 215 if (ext.IsNull()) { 216 // We will just return failure if we fail to allocate 217 LOG(WARNING) << "Could not allocate ext-data for class '" << descriptor << "'. " 218 << "Aborting transformation since we will be unable to store it."; 219 self->AssertPendingOOMException(); 220 return; 221 } 222 223 // Allocate the byte array to store the dex file bytes in. 224 art::MutableHandle<art::mirror::Object> arr(hs.NewHandle<art::mirror::Object>(nullptr)); 225 if (post_non_retransform.empty() && strcmp(descriptor, "Ljava/lang/Long;") != 0) { 226 // we didn't have any non-retransformable agents. We can just cache a pointer to the 227 // initial_dex_file. It will be kept live by the class_loader. 228 jlong dex_ptr = reinterpret_cast<uintptr_t>(&initial_dex_file); 229 art::JValue val; 230 val.SetJ(dex_ptr); 231 arr.Assign(art::BoxPrimitive(art::Primitive::kPrimLong, val)); 232 } else { 233 arr.Assign(art::mirror::ByteArray::AllocateAndFill( 234 self, 235 reinterpret_cast<const signed char*>(post_non_retransform.data()), 236 post_non_retransform.size())); 237 } 238 if (arr.IsNull()) { 239 LOG(WARNING) << "Unable to allocate memory for initial dex-file. Aborting transformation"; 240 self->AssertPendingOOMException(); 241 return; 242 } 243 244 std::unique_ptr<const art::DexFile> dex_file(MakeSingleDexFile(self, 245 descriptor, 246 initial_dex_file.GetLocation(), 247 def.GetDexData().size(), 248 def.GetDexData().data())); 249 if (dex_file.get() == nullptr) { 250 return; 251 } 252 253 // TODO Check Redefined dex file for all invariants. 254 LOG(WARNING) << "Dex file created by class-definition time transformation of " 255 << descriptor << " is not checked for all retransformation invariants."; 256 257 if (!ClassLoaderHelper::AddToClassLoader(self, class_loader, dex_file.get())) { 258 LOG(ERROR) << "Unable to add " << descriptor << " to class loader!"; 259 return; 260 } 261 262 // Actually set the ClassExt's original bytes once we have actually succeeded. 263 ext->SetOriginalDexFile(arr.Get()); 264 // Set the return values 265 *final_class_def = &dex_file->GetClassDef(0); 266 *final_dex_file = dex_file.release(); 267 } 268 } 269 270 void ClassLoad(art::Handle<art::mirror::Class> klass) REQUIRES_SHARED(art::Locks::mutator_lock_) { 271 if (event_handler->IsEventEnabledAnywhere(ArtJvmtiEvent::kClassLoad)) { 272 art::Thread* thread = art::Thread::Current(); 273 ScopedLocalRef<jclass> jklass(thread->GetJniEnv(), 274 thread->GetJniEnv()->AddLocalReference<jclass>(klass.Get())); 275 art::ObjPtr<art::mirror::Object> peer(thread->GetPeer()); 276 ScopedLocalRef<jthread> thread_jni( 277 thread->GetJniEnv(), 278 peer.IsNull() ? nullptr : thread->GetJniEnv()->AddLocalReference<jthread>(peer)); 279 event_handler->DispatchEvent<ArtJvmtiEvent::kClassLoad>( 280 thread, 281 static_cast<JNIEnv*>(thread->GetJniEnv()), 282 thread_jni.get(), 283 jklass.get()); 284 if (klass->IsTemp()) { 285 AddTempClass(thread, jklass.get()); 286 } 287 } 288 } 289 290 void ClassPrepare(art::Handle<art::mirror::Class> temp_klass, 291 art::Handle<art::mirror::Class> klass) 292 REQUIRES_SHARED(art::Locks::mutator_lock_) { 293 if (event_handler->IsEventEnabledAnywhere(ArtJvmtiEvent::kClassPrepare)) { 294 art::Thread* thread = art::Thread::Current(); 295 if (temp_klass.Get() != klass.Get()) { 296 DCHECK(temp_klass->IsTemp()); 297 DCHECK(temp_klass->IsRetired()); 298 HandleTempClass(thread, temp_klass, klass); 299 } 300 ScopedLocalRef<jclass> jklass(thread->GetJniEnv(), 301 thread->GetJniEnv()->AddLocalReference<jclass>(klass.Get())); 302 art::ObjPtr<art::mirror::Object> peer(thread->GetPeer()); 303 ScopedLocalRef<jthread> thread_jni( 304 thread->GetJniEnv(), 305 peer.IsNull() ? nullptr : thread->GetJniEnv()->AddLocalReference<jthread>(peer)); 306 event_handler->DispatchEvent<ArtJvmtiEvent::kClassPrepare>( 307 thread, 308 static_cast<JNIEnv*>(thread->GetJniEnv()), 309 thread_jni.get(), 310 jklass.get()); 311 } 312 } 313 314 // To support parallel class-loading, we need to perform some locking dances here. Namely, 315 // the fixup stage must not be holding the temp_classes lock when it fixes up the system 316 // (as that requires suspending all mutators). 317 318 void AddTempClass(art::Thread* self, jclass klass) { 319 std::unique_lock<std::mutex> mu(temp_classes_lock); 320 jclass global_klass = reinterpret_cast<jclass>(self->GetJniEnv()->NewGlobalRef(klass)); 321 temp_classes.push_back(global_klass); 322 } 323 324 void HandleTempClass(art::Thread* self, 325 art::Handle<art::mirror::Class> temp_klass, 326 art::Handle<art::mirror::Class> klass) 327 REQUIRES_SHARED(art::Locks::mutator_lock_) { 328 bool requires_fixup = false; 329 { 330 std::unique_lock<std::mutex> mu(temp_classes_lock); 331 if (temp_classes.empty()) { 332 return; 333 } 334 335 for (auto it = temp_classes.begin(); it != temp_classes.end(); ++it) { 336 if (temp_klass.Get() == art::ObjPtr<art::mirror::Class>::DownCast(self->DecodeJObject(*it))) { 337 self->GetJniEnv()->DeleteGlobalRef(*it); 338 temp_classes.erase(it); 339 requires_fixup = true; 340 break; 341 } 342 } 343 } 344 if (requires_fixup) { 345 FixupTempClass(self, temp_klass, klass); 346 } 347 } 348 349 void FixupTempClass(art::Thread* self, 350 art::Handle<art::mirror::Class> temp_klass, 351 art::Handle<art::mirror::Class> klass) 352 REQUIRES_SHARED(art::Locks::mutator_lock_) { 353 // Suspend everything. 354 art::gc::Heap* heap = art::Runtime::Current()->GetHeap(); 355 if (heap->IsGcConcurrentAndMoving()) { 356 // Need to take a heap dump while GC isn't running. See the 357 // comment in Heap::VisitObjects(). 358 heap->IncrementDisableMovingGC(self); 359 } 360 { 361 art::ScopedThreadSuspension sts(self, art::kWaitingForVisitObjects); 362 art::ScopedSuspendAll ssa("FixupTempClass"); 363 364 art::mirror::Class* input = temp_klass.Get(); 365 art::mirror::Class* output = klass.Get(); 366 367 FixupGlobalReferenceTables(input, output); 368 FixupLocalReferenceTables(self, input, output); 369 FixupHeap(input, output); 370 } 371 if (heap->IsGcConcurrentAndMoving()) { 372 heap->DecrementDisableMovingGC(self); 373 } 374 } 375 376 class RootUpdater : public art::RootVisitor { 377 public: 378 RootUpdater(const art::mirror::Class* input, art::mirror::Class* output) 379 : input_(input), output_(output) {} 380 381 void VisitRoots(art::mirror::Object*** roots, 382 size_t count, 383 const art::RootInfo& info ATTRIBUTE_UNUSED) 384 OVERRIDE { 385 for (size_t i = 0; i != count; ++i) { 386 if (*roots[i] == input_) { 387 *roots[i] = output_; 388 } 389 } 390 } 391 392 void VisitRoots(art::mirror::CompressedReference<art::mirror::Object>** roots, 393 size_t count, 394 const art::RootInfo& info ATTRIBUTE_UNUSED) 395 OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) { 396 for (size_t i = 0; i != count; ++i) { 397 if (roots[i]->AsMirrorPtr() == input_) { 398 roots[i]->Assign(output_); 399 } 400 } 401 } 402 403 private: 404 const art::mirror::Class* input_; 405 art::mirror::Class* output_; 406 }; 407 408 void FixupGlobalReferenceTables(art::mirror::Class* input, art::mirror::Class* output) 409 REQUIRES(art::Locks::mutator_lock_) { 410 art::JavaVMExt* java_vm = art::Runtime::Current()->GetJavaVM(); 411 412 // Fix up the global table with a root visitor. 413 RootUpdater global_update(input, output); 414 java_vm->VisitRoots(&global_update); 415 416 class WeakGlobalUpdate : public art::IsMarkedVisitor { 417 public: 418 WeakGlobalUpdate(art::mirror::Class* root_input, art::mirror::Class* root_output) 419 : input_(root_input), output_(root_output) {} 420 421 art::mirror::Object* IsMarked(art::mirror::Object* obj) OVERRIDE { 422 if (obj == input_) { 423 return output_; 424 } 425 return obj; 426 } 427 428 private: 429 const art::mirror::Class* input_; 430 art::mirror::Class* output_; 431 }; 432 WeakGlobalUpdate weak_global_update(input, output); 433 java_vm->SweepJniWeakGlobals(&weak_global_update); 434 } 435 436 void FixupLocalReferenceTables(art::Thread* self, 437 art::mirror::Class* input, 438 art::mirror::Class* output) 439 REQUIRES(art::Locks::mutator_lock_) { 440 class LocalUpdate { 441 public: 442 LocalUpdate(const art::mirror::Class* root_input, art::mirror::Class* root_output) 443 : input_(root_input), output_(root_output) {} 444 445 static void Callback(art::Thread* t, void* arg) REQUIRES(art::Locks::mutator_lock_) { 446 LocalUpdate* local = reinterpret_cast<LocalUpdate*>(arg); 447 448 // Fix up the local table with a root visitor. 449 RootUpdater local_update(local->input_, local->output_); 450 t->GetJniEnv()->VisitJniLocalRoots( 451 &local_update, art::RootInfo(art::kRootJNILocal, t->GetThreadId())); 452 } 453 454 private: 455 const art::mirror::Class* input_; 456 art::mirror::Class* output_; 457 }; 458 LocalUpdate local_upd(input, output); 459 art::MutexLock mu(self, *art::Locks::thread_list_lock_); 460 art::Runtime::Current()->GetThreadList()->ForEach(LocalUpdate::Callback, &local_upd); 461 } 462 463 void FixupHeap(art::mirror::Class* input, art::mirror::Class* output) 464 REQUIRES(art::Locks::mutator_lock_) { 465 class HeapFixupVisitor { 466 public: 467 HeapFixupVisitor(const art::mirror::Class* root_input, art::mirror::Class* root_output) 468 : input_(root_input), output_(root_output) {} 469 470 void operator()(art::mirror::Object* src, 471 art::MemberOffset field_offset, 472 bool is_static ATTRIBUTE_UNUSED) const 473 REQUIRES_SHARED(art::Locks::mutator_lock_) { 474 art::mirror::HeapReference<art::mirror::Object>* trg = 475 src->GetFieldObjectReferenceAddr(field_offset); 476 if (trg->AsMirrorPtr() == input_) { 477 DCHECK_NE(field_offset.Uint32Value(), 0u); // This shouldn't be the class field of 478 // an object. 479 trg->Assign(output_); 480 } 481 } 482 483 void operator()(art::ObjPtr<art::mirror::Class> klass ATTRIBUTE_UNUSED, 484 art::ObjPtr<art::mirror::Reference> reference) const 485 REQUIRES_SHARED(art::Locks::mutator_lock_) { 486 art::mirror::Object* val = reference->GetReferent(); 487 if (val == input_) { 488 reference->SetReferent<false>(output_); 489 } 490 } 491 492 void VisitRoot(art::mirror::CompressedReference<art::mirror::Object>* root ATTRIBUTE_UNUSED) 493 const { 494 LOG(FATAL) << "Unreachable"; 495 } 496 497 void VisitRootIfNonNull( 498 art::mirror::CompressedReference<art::mirror::Object>* root ATTRIBUTE_UNUSED) const { 499 LOG(FATAL) << "Unreachable"; 500 } 501 502 private: 503 const art::mirror::Class* input_; 504 art::mirror::Class* output_; 505 }; 506 HeapFixupVisitor hfv(input, output); 507 auto object_visitor = [&](art::mirror::Object* obj) { 508 obj->VisitReferences<false>(hfv, hfv); // Visit references, not native roots. 509 }; 510 art::Runtime::Current()->GetHeap()->VisitObjectsPaused(object_visitor); 511 } 512 513 // A set of all the temp classes we have handed out. We have to fix up references to these. 514 // For simplicity, we store the temp classes as JNI global references in a vector. Normally a 515 // Prepare event will closely follow, so the vector should be small. 516 std::mutex temp_classes_lock; 517 std::vector<jclass> temp_classes; 518 519 EventHandler* event_handler = nullptr; 520 }; 521 522 ClassCallback gClassCallback; 523 524 void ClassUtil::Register(EventHandler* handler) { 525 gClassCallback.event_handler = handler; 526 art::ScopedThreadStateChange stsc(art::Thread::Current(), 527 art::ThreadState::kWaitingForDebuggerToAttach); 528 art::ScopedSuspendAll ssa("Add load callback"); 529 art::Runtime::Current()->GetRuntimeCallbacks()->AddClassLoadCallback(&gClassCallback); 530 } 531 532 void ClassUtil::Unregister() { 533 art::ScopedThreadStateChange stsc(art::Thread::Current(), 534 art::ThreadState::kWaitingForDebuggerToAttach); 535 art::ScopedSuspendAll ssa("Remove thread callback"); 536 art::Runtime* runtime = art::Runtime::Current(); 537 runtime->GetRuntimeCallbacks()->RemoveClassLoadCallback(&gClassCallback); 538 } 539 540 jvmtiError ClassUtil::GetClassFields(jvmtiEnv* env, 541 jclass jklass, 542 jint* field_count_ptr, 543 jfieldID** fields_ptr) { 544 art::ScopedObjectAccess soa(art::Thread::Current()); 545 art::ObjPtr<art::mirror::Class> klass = soa.Decode<art::mirror::Class>(jklass); 546 if (klass == nullptr) { 547 return ERR(INVALID_CLASS); 548 } 549 550 // Check if this class is a temporary class object used for loading. Since we are seeing it the 551 // class must not have been prepared yet since otherwise the fixup would have gotten the jobject 552 // to point to the final class object. 553 if (klass->IsTemp() || klass->IsRetired()) { 554 return ERR(CLASS_NOT_PREPARED); 555 } 556 557 if (field_count_ptr == nullptr || fields_ptr == nullptr) { 558 return ERR(NULL_POINTER); 559 } 560 561 art::IterationRange<art::StrideIterator<art::ArtField>> ifields = klass->GetIFields(); 562 art::IterationRange<art::StrideIterator<art::ArtField>> sfields = klass->GetSFields(); 563 size_t array_size = klass->NumInstanceFields() + klass->NumStaticFields(); 564 565 unsigned char* out_ptr; 566 jvmtiError allocError = env->Allocate(array_size * sizeof(jfieldID), &out_ptr); 567 if (allocError != ERR(NONE)) { 568 return allocError; 569 } 570 jfieldID* field_array = reinterpret_cast<jfieldID*>(out_ptr); 571 572 size_t array_idx = 0; 573 for (art::ArtField& field : sfields) { 574 field_array[array_idx] = art::jni::EncodeArtField(&field); 575 ++array_idx; 576 } 577 for (art::ArtField& field : ifields) { 578 field_array[array_idx] = art::jni::EncodeArtField(&field); 579 ++array_idx; 580 } 581 582 *field_count_ptr = static_cast<jint>(array_size); 583 *fields_ptr = field_array; 584 585 return ERR(NONE); 586 } 587 588 jvmtiError ClassUtil::GetClassMethods(jvmtiEnv* env, 589 jclass jklass, 590 jint* method_count_ptr, 591 jmethodID** methods_ptr) { 592 art::ScopedObjectAccess soa(art::Thread::Current()); 593 art::ObjPtr<art::mirror::Class> klass = soa.Decode<art::mirror::Class>(jklass); 594 if (klass == nullptr) { 595 return ERR(INVALID_CLASS); 596 } 597 598 // Check if this class is a temporary class object used for loading. Since we are seeing it the 599 // class must not have been prepared yet since otherwise the fixup would have gotten the jobject 600 // to point to the final class object. 601 if (klass->IsTemp() || klass->IsRetired()) { 602 return ERR(CLASS_NOT_PREPARED); 603 } 604 605 if (method_count_ptr == nullptr || methods_ptr == nullptr) { 606 return ERR(NULL_POINTER); 607 } 608 609 size_t array_size = klass->NumDeclaredVirtualMethods() + klass->NumDirectMethods(); 610 unsigned char* out_ptr; 611 jvmtiError allocError = env->Allocate(array_size * sizeof(jmethodID), &out_ptr); 612 if (allocError != ERR(NONE)) { 613 return allocError; 614 } 615 jmethodID* method_array = reinterpret_cast<jmethodID*>(out_ptr); 616 617 if (art::kIsDebugBuild) { 618 size_t count = 0; 619 for (auto& m ATTRIBUTE_UNUSED : klass->GetDeclaredMethods(art::kRuntimePointerSize)) { 620 count++; 621 } 622 CHECK_EQ(count, klass->NumDirectMethods() + klass->NumDeclaredVirtualMethods()); 623 } 624 625 size_t array_idx = 0; 626 for (auto& m : klass->GetDeclaredMethods(art::kRuntimePointerSize)) { 627 method_array[array_idx] = art::jni::EncodeArtMethod(&m); 628 ++array_idx; 629 } 630 631 *method_count_ptr = static_cast<jint>(array_size); 632 *methods_ptr = method_array; 633 634 return ERR(NONE); 635 } 636 637 jvmtiError ClassUtil::GetImplementedInterfaces(jvmtiEnv* env, 638 jclass jklass, 639 jint* interface_count_ptr, 640 jclass** interfaces_ptr) { 641 art::ScopedObjectAccess soa(art::Thread::Current()); 642 art::ObjPtr<art::mirror::Class> klass = soa.Decode<art::mirror::Class>(jklass); 643 if (klass == nullptr) { 644 return ERR(INVALID_CLASS); 645 } 646 647 if (interface_count_ptr == nullptr || interfaces_ptr == nullptr) { 648 return ERR(NULL_POINTER); 649 } 650 651 // Need to handle array specifically. Arrays implement Serializable and Cloneable, but the 652 // spec says these should not be reported. 653 if (klass->IsArrayClass()) { 654 *interface_count_ptr = 0; 655 *interfaces_ptr = nullptr; // TODO: Should we allocate a dummy here? 656 return ERR(NONE); 657 } 658 659 size_t array_size = klass->NumDirectInterfaces(); 660 unsigned char* out_ptr; 661 jvmtiError allocError = env->Allocate(array_size * sizeof(jclass), &out_ptr); 662 if (allocError != ERR(NONE)) { 663 return allocError; 664 } 665 jclass* interface_array = reinterpret_cast<jclass*>(out_ptr); 666 667 art::StackHandleScope<1> hs(soa.Self()); 668 art::Handle<art::mirror::Class> h_klass(hs.NewHandle(klass)); 669 670 for (uint32_t idx = 0; idx != array_size; ++idx) { 671 art::ObjPtr<art::mirror::Class> inf_klass = 672 art::mirror::Class::ResolveDirectInterface(soa.Self(), h_klass, idx); 673 if (inf_klass == nullptr) { 674 soa.Self()->ClearException(); 675 env->Deallocate(out_ptr); 676 // TODO: What is the right error code here? 677 return ERR(INTERNAL); 678 } 679 interface_array[idx] = soa.AddLocalReference<jclass>(inf_klass); 680 } 681 682 *interface_count_ptr = static_cast<jint>(array_size); 683 *interfaces_ptr = interface_array; 684 685 return ERR(NONE); 686 } 687 688 jvmtiError ClassUtil::GetClassSignature(jvmtiEnv* env, 689 jclass jklass, 690 char** signature_ptr, 691 char** generic_ptr) { 692 art::ScopedObjectAccess soa(art::Thread::Current()); 693 art::ObjPtr<art::mirror::Class> klass = soa.Decode<art::mirror::Class>(jklass); 694 if (klass == nullptr) { 695 return ERR(INVALID_CLASS); 696 } 697 698 JvmtiUniquePtr<char[]> sig_copy; 699 if (signature_ptr != nullptr) { 700 std::string storage; 701 const char* descriptor = klass->GetDescriptor(&storage); 702 703 jvmtiError ret; 704 sig_copy = CopyString(env, descriptor, &ret); 705 if (sig_copy == nullptr) { 706 return ret; 707 } 708 *signature_ptr = sig_copy.get(); 709 } 710 711 if (generic_ptr != nullptr) { 712 *generic_ptr = nullptr; 713 if (!klass->IsProxyClass() && klass->GetDexCache() != nullptr) { 714 art::StackHandleScope<1> hs(soa.Self()); 715 art::Handle<art::mirror::Class> h_klass = hs.NewHandle(klass); 716 art::mirror::ObjectArray<art::mirror::String>* str_array = 717 art::annotations::GetSignatureAnnotationForClass(h_klass); 718 if (str_array != nullptr) { 719 std::ostringstream oss; 720 for (int32_t i = 0; i != str_array->GetLength(); ++i) { 721 oss << str_array->Get(i)->ToModifiedUtf8(); 722 } 723 std::string output_string = oss.str(); 724 jvmtiError ret; 725 JvmtiUniquePtr<char[]> copy = CopyString(env, output_string.c_str(), &ret); 726 if (copy == nullptr) { 727 return ret; 728 } 729 *generic_ptr = copy.release(); 730 } else if (soa.Self()->IsExceptionPending()) { 731 // TODO: Should we report an error here? 732 soa.Self()->ClearException(); 733 } 734 } 735 } 736 737 // Everything is fine, release the buffers. 738 sig_copy.release(); 739 740 return ERR(NONE); 741 } 742 743 jvmtiError ClassUtil::GetClassStatus(jvmtiEnv* env ATTRIBUTE_UNUSED, 744 jclass jklass, 745 jint* status_ptr) { 746 art::ScopedObjectAccess soa(art::Thread::Current()); 747 art::ObjPtr<art::mirror::Class> klass = soa.Decode<art::mirror::Class>(jklass); 748 if (klass == nullptr) { 749 return ERR(INVALID_CLASS); 750 } 751 752 if (status_ptr == nullptr) { 753 return ERR(NULL_POINTER); 754 } 755 756 if (klass->IsArrayClass()) { 757 *status_ptr = JVMTI_CLASS_STATUS_ARRAY; 758 } else if (klass->IsPrimitive()) { 759 *status_ptr = JVMTI_CLASS_STATUS_PRIMITIVE; 760 } else { 761 *status_ptr = JVMTI_CLASS_STATUS_VERIFIED; // All loaded classes are structurally verified. 762 // This is finicky. If there's an error, we'll say it wasn't prepared. 763 if (klass->IsResolved()) { 764 *status_ptr |= JVMTI_CLASS_STATUS_PREPARED; 765 } 766 if (klass->IsInitialized()) { 767 *status_ptr |= JVMTI_CLASS_STATUS_INITIALIZED; 768 } 769 // Technically the class may be erroneous for other reasons, but we do not have enough info. 770 if (klass->IsErroneous()) { 771 *status_ptr |= JVMTI_CLASS_STATUS_ERROR; 772 } 773 } 774 775 return ERR(NONE); 776 } 777 778 template <typename T> 779 static jvmtiError ClassIsT(jclass jklass, T test, jboolean* is_t_ptr) { 780 art::ScopedObjectAccess soa(art::Thread::Current()); 781 art::ObjPtr<art::mirror::Class> klass = soa.Decode<art::mirror::Class>(jklass); 782 if (klass == nullptr) { 783 return ERR(INVALID_CLASS); 784 } 785 786 if (is_t_ptr == nullptr) { 787 return ERR(NULL_POINTER); 788 } 789 790 *is_t_ptr = test(klass) ? JNI_TRUE : JNI_FALSE; 791 return ERR(NONE); 792 } 793 794 jvmtiError ClassUtil::IsInterface(jvmtiEnv* env ATTRIBUTE_UNUSED, 795 jclass jklass, 796 jboolean* is_interface_ptr) { 797 auto test = [](art::ObjPtr<art::mirror::Class> klass) REQUIRES_SHARED(art::Locks::mutator_lock_) { 798 return klass->IsInterface(); 799 }; 800 return ClassIsT(jklass, test, is_interface_ptr); 801 } 802 803 jvmtiError ClassUtil::IsArrayClass(jvmtiEnv* env ATTRIBUTE_UNUSED, 804 jclass jklass, 805 jboolean* is_array_class_ptr) { 806 auto test = [](art::ObjPtr<art::mirror::Class> klass) REQUIRES_SHARED(art::Locks::mutator_lock_) { 807 return klass->IsArrayClass(); 808 }; 809 return ClassIsT(jklass, test, is_array_class_ptr); 810 } 811 812 // Keep this in sync with Class.getModifiers(). 813 static uint32_t ClassGetModifiers(art::Thread* self, art::ObjPtr<art::mirror::Class> klass) 814 REQUIRES_SHARED(art::Locks::mutator_lock_) { 815 if (klass->IsArrayClass()) { 816 uint32_t component_modifiers = ClassGetModifiers(self, klass->GetComponentType()); 817 if ((component_modifiers & art::kAccInterface) != 0) { 818 component_modifiers &= ~(art::kAccInterface | art::kAccStatic); 819 } 820 return art::kAccAbstract | art::kAccFinal | component_modifiers; 821 } 822 823 uint32_t modifiers = klass->GetAccessFlags() & art::kAccJavaFlagsMask; 824 825 art::StackHandleScope<1> hs(self); 826 art::Handle<art::mirror::Class> h_klass(hs.NewHandle(klass)); 827 return art::mirror::Class::GetInnerClassFlags(h_klass, modifiers); 828 } 829 830 jvmtiError ClassUtil::GetClassModifiers(jvmtiEnv* env ATTRIBUTE_UNUSED, 831 jclass jklass, 832 jint* modifiers_ptr) { 833 art::ScopedObjectAccess soa(art::Thread::Current()); 834 art::ObjPtr<art::mirror::Class> klass = soa.Decode<art::mirror::Class>(jklass); 835 if (klass == nullptr) { 836 return ERR(INVALID_CLASS); 837 } 838 839 if (modifiers_ptr == nullptr) { 840 return ERR(NULL_POINTER); 841 } 842 843 *modifiers_ptr = ClassGetModifiers(soa.Self(), klass); 844 845 return ERR(NONE); 846 } 847 848 jvmtiError ClassUtil::GetClassLoader(jvmtiEnv* env ATTRIBUTE_UNUSED, 849 jclass jklass, 850 jobject* classloader_ptr) { 851 art::ScopedObjectAccess soa(art::Thread::Current()); 852 art::ObjPtr<art::mirror::Class> klass = soa.Decode<art::mirror::Class>(jklass); 853 if (klass == nullptr) { 854 return ERR(INVALID_CLASS); 855 } 856 857 if (classloader_ptr == nullptr) { 858 return ERR(NULL_POINTER); 859 } 860 861 *classloader_ptr = soa.AddLocalReference<jobject>(klass->GetClassLoader()); 862 863 return ERR(NONE); 864 } 865 866 // Copies unique class descriptors into the classes list from dex_files. 867 static jvmtiError CopyClassDescriptors(jvmtiEnv* env, 868 const std::vector<const art::DexFile*>& dex_files, 869 /*out*/jint* count_ptr, 870 /*out*/char*** classes) { 871 jvmtiError res = OK; 872 std::set<art::StringPiece> unique_descriptors; 873 std::vector<const char*> descriptors; 874 auto add_descriptor = [&](const char* desc) { 875 // Don't add duplicates. 876 if (res == OK && unique_descriptors.find(desc) == unique_descriptors.end()) { 877 // The desc will remain valid since we hold a ref to the class_loader. 878 unique_descriptors.insert(desc); 879 descriptors.push_back(CopyString(env, desc, &res).release()); 880 } 881 }; 882 for (const art::DexFile* dex_file : dex_files) { 883 uint32_t num_defs = dex_file->NumClassDefs(); 884 for (uint32_t i = 0; i < num_defs; i++) { 885 add_descriptor(dex_file->GetClassDescriptor(dex_file->GetClassDef(i))); 886 } 887 } 888 char** out_data = nullptr; 889 if (res == OK) { 890 res = env->Allocate(sizeof(char*) * descriptors.size(), 891 reinterpret_cast<unsigned char**>(&out_data)); 892 } 893 if (res != OK) { 894 env->Deallocate(reinterpret_cast<unsigned char*>(out_data)); 895 // Failed to allocate. Cleanup everything. 896 for (const char* data : descriptors) { 897 env->Deallocate(reinterpret_cast<unsigned char*>(const_cast<char*>(data))); 898 } 899 descriptors.clear(); 900 return res; 901 } 902 // Everything is good. 903 memcpy(out_data, descriptors.data(), sizeof(char*) * descriptors.size()); 904 *count_ptr = static_cast<jint>(descriptors.size()); 905 *classes = out_data; 906 return OK; 907 } 908 909 jvmtiError ClassUtil::GetClassLoaderClassDescriptors(jvmtiEnv* env, 910 jobject loader, 911 /*out*/jint* count_ptr, 912 /*out*/char*** classes) { 913 art::Thread* self = art::Thread::Current(); 914 if (env == nullptr) { 915 return ERR(INVALID_ENVIRONMENT); 916 } else if (self == nullptr) { 917 return ERR(UNATTACHED_THREAD); 918 } else if (count_ptr == nullptr || classes == nullptr) { 919 return ERR(NULL_POINTER); 920 } 921 art::JNIEnvExt* jnienv = self->GetJniEnv(); 922 if (loader == nullptr || 923 jnienv->IsInstanceOf(loader, art::WellKnownClasses::java_lang_BootClassLoader)) { 924 // We can just get the dex files directly for the boot class path. 925 return CopyClassDescriptors(env, 926 art::Runtime::Current()->GetClassLinker()->GetBootClassPath(), 927 count_ptr, 928 classes); 929 } 930 if (!jnienv->IsInstanceOf(loader, art::WellKnownClasses::java_lang_ClassLoader)) { 931 return ERR(ILLEGAL_ARGUMENT); 932 } else if (!jnienv->IsInstanceOf(loader, 933 art::WellKnownClasses::dalvik_system_BaseDexClassLoader)) { 934 LOG(ERROR) << "GetClassLoaderClassDescriptors is only implemented for BootClassPath and " 935 << "dalvik.system.BaseDexClassLoader class loaders"; 936 // TODO Possibly return OK With no classes would be better since these ones cannot have any 937 // real classes associated with them. 938 return ERR(NOT_IMPLEMENTED); 939 } 940 941 art::ScopedObjectAccess soa(self); 942 art::StackHandleScope<1> hs(self); 943 art::Handle<art::mirror::ClassLoader> class_loader( 944 hs.NewHandle(soa.Decode<art::mirror::ClassLoader>(loader))); 945 std::vector<const art::DexFile*> dex_files; 946 art::VisitClassLoaderDexFiles( 947 soa, 948 class_loader, 949 [&](const art::DexFile* dex_file) { 950 dex_files.push_back(dex_file); 951 return true; // Continue with other dex files. 952 }); 953 // We hold the loader so the dex files won't go away until after this call at worst. 954 return CopyClassDescriptors(env, dex_files, count_ptr, classes); 955 } 956 957 jvmtiError ClassUtil::GetClassLoaderClasses(jvmtiEnv* env, 958 jobject initiating_loader, 959 jint* class_count_ptr, 960 jclass** classes_ptr) { 961 UNUSED(env, initiating_loader, class_count_ptr, classes_ptr); 962 963 if (class_count_ptr == nullptr || classes_ptr == nullptr) { 964 return ERR(NULL_POINTER); 965 } 966 art::Thread* self = art::Thread::Current(); 967 if (!self->GetJniEnv()->IsInstanceOf(initiating_loader, 968 art::WellKnownClasses::java_lang_ClassLoader)) { 969 return ERR(ILLEGAL_ARGUMENT); 970 } 971 if (self->GetJniEnv()->IsInstanceOf(initiating_loader, 972 art::WellKnownClasses::java_lang_BootClassLoader)) { 973 // Need to use null for the BootClassLoader. 974 initiating_loader = nullptr; 975 } 976 977 art::ScopedObjectAccess soa(self); 978 art::ObjPtr<art::mirror::ClassLoader> class_loader = 979 soa.Decode<art::mirror::ClassLoader>(initiating_loader); 980 981 art::ClassLinker* class_linker = art::Runtime::Current()->GetClassLinker(); 982 983 art::ReaderMutexLock mu(self, *art::Locks::classlinker_classes_lock_); 984 985 art::ClassTable* class_table = class_linker->ClassTableForClassLoader(class_loader); 986 if (class_table == nullptr) { 987 // Nothing loaded. 988 *class_count_ptr = 0; 989 *classes_ptr = nullptr; 990 return ERR(NONE); 991 } 992 993 struct ClassTableCount { 994 bool operator()(art::ObjPtr<art::mirror::Class> klass) { 995 DCHECK(klass != nullptr); 996 ++count; 997 return true; 998 } 999 1000 size_t count = 0; 1001 }; 1002 ClassTableCount ctc; 1003 class_table->Visit(ctc); 1004 1005 if (ctc.count == 0) { 1006 // Nothing loaded. 1007 *class_count_ptr = 0; 1008 *classes_ptr = nullptr; 1009 return ERR(NONE); 1010 } 1011 1012 unsigned char* data; 1013 jvmtiError data_result = env->Allocate(ctc.count * sizeof(jclass), &data); 1014 if (data_result != ERR(NONE)) { 1015 return data_result; 1016 } 1017 jclass* class_array = reinterpret_cast<jclass*>(data); 1018 1019 struct ClassTableFill { 1020 bool operator()(art::ObjPtr<art::mirror::Class> klass) 1021 REQUIRES_SHARED(art::Locks::mutator_lock_) { 1022 DCHECK(klass != nullptr); 1023 DCHECK_LT(count, ctc_ref.count); 1024 local_class_array[count++] = soa_ptr->AddLocalReference<jclass>(klass); 1025 return true; 1026 } 1027 1028 jclass* local_class_array; 1029 const ClassTableCount& ctc_ref; 1030 art::ScopedObjectAccess* soa_ptr; 1031 size_t count; 1032 }; 1033 ClassTableFill ctf = { class_array, ctc, &soa, 0 }; 1034 class_table->Visit(ctf); 1035 DCHECK_EQ(ctc.count, ctf.count); 1036 1037 *class_count_ptr = ctc.count; 1038 *classes_ptr = class_array; 1039 1040 return ERR(NONE); 1041 } 1042 1043 jvmtiError ClassUtil::GetClassVersionNumbers(jvmtiEnv* env ATTRIBUTE_UNUSED, 1044 jclass jklass, 1045 jint* minor_version_ptr, 1046 jint* major_version_ptr) { 1047 art::ScopedObjectAccess soa(art::Thread::Current()); 1048 if (jklass == nullptr) { 1049 return ERR(INVALID_CLASS); 1050 } 1051 art::ObjPtr<art::mirror::Object> jklass_obj = soa.Decode<art::mirror::Object>(jklass); 1052 if (!jklass_obj->IsClass()) { 1053 return ERR(INVALID_CLASS); 1054 } 1055 art::ObjPtr<art::mirror::Class> klass = jklass_obj->AsClass(); 1056 if (klass->IsPrimitive() || klass->IsArrayClass()) { 1057 return ERR(INVALID_CLASS); 1058 } 1059 1060 if (minor_version_ptr == nullptr || major_version_ptr == nullptr) { 1061 return ERR(NULL_POINTER); 1062 } 1063 1064 // Note: proxies will show the dex file version of java.lang.reflect.Proxy, as that is 1065 // what their dex cache copies from. 1066 uint32_t version = klass->GetDexFile().GetHeader().GetVersion(); 1067 1068 *major_version_ptr = static_cast<jint>(version); 1069 *minor_version_ptr = 0; 1070 1071 return ERR(NONE); 1072 } 1073 1074 jvmtiError ClassUtil::GetSourceFileName(jvmtiEnv* env, jclass jklass, char** source_name_ptr) { 1075 art::ScopedObjectAccess soa(art::Thread::Current()); 1076 if (jklass == nullptr) { 1077 return ERR(INVALID_CLASS); 1078 } 1079 art::ObjPtr<art::mirror::Object> jklass_obj = soa.Decode<art::mirror::Object>(jklass); 1080 if (!jklass_obj->IsClass()) { 1081 return ERR(INVALID_CLASS); 1082 } 1083 art::ObjPtr<art::mirror::Class> klass = jklass_obj->AsClass(); 1084 if (klass->IsPrimitive() || klass->IsArrayClass()) { 1085 return ERR(ABSENT_INFORMATION); 1086 } 1087 JvmtiUniquePtr<char[]> source_copy; 1088 const char* file_name = klass->GetSourceFile(); 1089 if (file_name == nullptr) { 1090 return ERR(ABSENT_INFORMATION); 1091 } 1092 jvmtiError ret; 1093 source_copy = CopyString(env, file_name, &ret); 1094 if (source_copy == nullptr) { 1095 return ret; 1096 } 1097 *source_name_ptr = source_copy.release(); 1098 return OK; 1099 } 1100 1101 jvmtiError ClassUtil::GetSourceDebugExtension(jvmtiEnv* env, 1102 jclass jklass, 1103 char** source_debug_extension_ptr) { 1104 art::ScopedObjectAccess soa(art::Thread::Current()); 1105 if (jklass == nullptr) { 1106 return ERR(INVALID_CLASS); 1107 } 1108 art::ObjPtr<art::mirror::Object> jklass_obj = soa.Decode<art::mirror::Object>(jklass); 1109 if (!jklass_obj->IsClass()) { 1110 return ERR(INVALID_CLASS); 1111 } 1112 art::StackHandleScope<1> hs(art::Thread::Current()); 1113 art::Handle<art::mirror::Class> klass(hs.NewHandle(jklass_obj->AsClass())); 1114 if (klass->IsPrimitive() || klass->IsArrayClass()) { 1115 return ERR(ABSENT_INFORMATION); 1116 } 1117 JvmtiUniquePtr<char[]> ext_copy; 1118 const char* data = art::annotations::GetSourceDebugExtension(klass); 1119 if (data == nullptr) { 1120 return ERR(ABSENT_INFORMATION); 1121 } 1122 jvmtiError ret; 1123 ext_copy = CopyString(env, data, &ret); 1124 if (ext_copy == nullptr) { 1125 return ret; 1126 } 1127 *source_debug_extension_ptr = ext_copy.release(); 1128 return OK; 1129 } 1130 1131 } // namespace openjdkjvmti 1132