1 /*
   2 * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
   3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4 *
   5 * This code is free software; you can redistribute it and/or modify it
   6 * under the terms of the GNU General Public License version 2 only, as
   7 * published by the Free Software Foundation.
   8 *
   9 * This code is distributed in the hope that it will be useful, but WITHOUT
  10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12 * version 2 for more details (a copy is included in the LICENSE file that
  13 * accompanied this code).
  14 *
  15 * You should have received a copy of the GNU General Public License version
  16 * 2 along with this work; if not, write to the Free Software Foundation,
  17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18 *
  19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20 * or visit www.oracle.com if you need additional information or have any
  21 * questions.
  22 *
  23 */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/classFileParser.hpp"
  27 #include "classfile/classFileStream.hpp"
  28 #include "classfile/classLoader.hpp"
  29 #include "classfile/classLoaderData.hpp"
  30 #include "classfile/classLoaderData.inline.hpp"
  31 #include "classfile/klassFactory.hpp"
  32 #include "memory/filemap.hpp"
  33 #include "memory/metaspaceShared.hpp"
  34 #include "memory/resourceArea.hpp"
  35 #include "prims/jvmtiEnvBase.hpp"
  36 #include "prims/jvmtiRedefineClasses.hpp"
  37 #include "runtime/handles.inline.hpp"
  38 #include "utilities/macros.hpp"
  39 #if INCLUDE_JFR
  40 #include "jfr/support/jfrKlassExtension.hpp"
  41 #endif
  42 
  43 
  44 // called during initial loading of a shared class
  45 InstanceKlass* KlassFactory::check_shared_class_file_load_hook(
  46                                           InstanceKlass* ik,
  47                                           Symbol* class_name,
  48                                           Handle class_loader,
  49                                           Handle protection_domain,
  50                                           const ClassFileStream *cfs,
  51                                           TRAPS) {
  52 #if INCLUDE_CDS && INCLUDE_JVMTI
  53   assert(ik != NULL, "sanity");
  54   assert(ik->is_shared(), "expecting a shared class");
  55   if (JvmtiExport::should_post_class_file_load_hook()) {
  56     assert(THREAD->is_Java_thread(), "must be JavaThread");
  57 
  58     // Post the CFLH
  59     JvmtiCachedClassFileData* cached_class_file = NULL;
  60     if (cfs == NULL) {
  61       cfs = FileMapInfo::open_stream_for_jvmti(ik, class_loader, CHECK_NULL);
  62     }
  63     unsigned char* ptr = (unsigned char*)cfs->buffer();
  64     unsigned char* end_ptr = ptr + cfs->length();
  65     unsigned char* old_ptr = ptr;
  66     JvmtiExport::post_class_file_load_hook(class_name,
  67                                            class_loader,
  68                                            protection_domain,
  69                                            &ptr,
  70                                            &end_ptr,
  71                                            &cached_class_file);
  72     if (old_ptr != ptr) {
  73       // JVMTI agent has modified class file data.
  74       // Set new class file stream using JVMTI agent modified class file data.
  75       ClassLoaderData* loader_data =
  76         ClassLoaderData::class_loader_data(class_loader());
  77       int path_index = ik->shared_classpath_index();
  78       ClassFileStream* stream = new ClassFileStream(ptr,
  79                                                     end_ptr - ptr,
  80                                                     cfs->source(),
  81                                                     ClassFileStream::verify);
  82       ClassFileParser parser(stream,
  83                              class_name,
  84                              loader_data,
  85                              protection_domain,
  86                              NULL,  // unsafe_anonymous_host
  87                              NULL,  // cp_patches
  88                              false, // is_nonfindable
  89                              false, // can_access_vm_annotations
  90                              ClassFileParser::BROADCAST, // publicity level
  91                              CHECK_NULL);
  92       InstanceKlass* new_ik = parser.create_instance_klass(true, // changed_by_loadhook
  93                                                            NULL,  // dynamic_nest_host
  94                                                            Handle(), // classData
  95                                                            CHECK_NULL);
  96 
  97       if (cached_class_file != NULL) {
  98         new_ik->set_cached_class_file(cached_class_file);
  99       }
 100 
 101       if (class_loader.is_null()) {
 102         ResourceMark rm;
 103         ClassLoader::add_package(class_name->as_C_string(), path_index, THREAD);
 104       }
 105 
 106       return new_ik;
 107     }
 108   }
 109 #endif
 110 
 111   return NULL;
 112 }
 113 
 114 
 115 static ClassFileStream* check_class_file_load_hook(ClassFileStream* stream,
 116                                                    Symbol* name,
 117                                                    ClassLoaderData* loader_data,
 118                                                    Handle protection_domain,
 119                                                    JvmtiCachedClassFileData** cached_class_file,
 120                                                    TRAPS) {
 121 
 122   assert(stream != NULL, "invariant");
 123 
 124   if (JvmtiExport::should_post_class_file_load_hook()) {
 125     assert(THREAD->is_Java_thread(), "must be a JavaThread");
 126     const JavaThread* jt = (JavaThread*)THREAD;
 127 
 128     Handle class_loader(THREAD, loader_data->class_loader());
 129 
 130     // Get the cached class file bytes (if any) from the class that
 131     // is being redefined or retransformed. We use jvmti_thread_state()
 132     // instead of JvmtiThreadState::state_for(jt) so we don't allocate
 133     // a JvmtiThreadState any earlier than necessary. This will help
 134     // avoid the bug described by 7126851.
 135 
 136     JvmtiThreadState* state = jt->jvmti_thread_state();
 137 
 138     if (state != NULL) {
 139       Klass* k = state->get_class_being_redefined();
 140 
 141       if (k != NULL) {
 142         InstanceKlass* class_being_redefined = InstanceKlass::cast(k);
 143         *cached_class_file = class_being_redefined->get_cached_class_file();
 144       }
 145     }
 146 
 147     unsigned char* ptr = const_cast<unsigned char*>(stream->buffer());
 148     unsigned char* end_ptr = ptr + stream->length();
 149 
 150     JvmtiExport::post_class_file_load_hook(name,
 151                                            class_loader,
 152                                            protection_domain,
 153                                            &ptr,
 154                                            &end_ptr,
 155                                            cached_class_file);
 156 
 157     if (ptr != stream->buffer()) {
 158       // JVMTI agent has modified class file data.
 159       // Set new class file stream using JVMTI agent modified class file data.
 160       stream = new ClassFileStream(ptr,
 161                                    end_ptr - ptr,
 162                                    stream->source(),
 163                                    stream->need_verify());
 164     }
 165   }
 166 
 167   return stream;
 168 }
 169 
 170 
 171 InstanceKlass* KlassFactory::create_from_stream(ClassFileStream* stream,
 172                                                 Symbol* name,
 173                                                 ClassLoaderData* loader_data,
 174                                                 Handle protection_domain,
 175                                                 const InstanceKlass* unsafe_anonymous_host,
 176                                                 GrowableArray<Handle>* cp_patches,
 177                                                 const bool is_nonfindable,
 178                                                 const bool can_access_vm_annotations,
 179                                                 InstanceKlass* dynamic_nest_host,
 180                                                 Handle classData,
 181                                                 TRAPS) {
 182   assert(stream != NULL, "invariant");
 183   assert(loader_data != NULL, "invariant");
 184   assert(THREAD->is_Java_thread(), "must be a JavaThread");
 185 
 186   ResourceMark rm;
 187   HandleMark hm;
 188 
 189   JvmtiCachedClassFileData* cached_class_file = NULL;
 190 
 191   ClassFileStream* old_stream = stream;
 192 
 193   // increment counter
 194   THREAD->statistical_info().incr_define_class_count();
 195 
 196   assert(!(is_nonfindable && (unsafe_anonymous_host != NULL)),
 197          "nonFindable class has an anonymous host");
 198 
 199   // Skip this processing for VM nonfindable or anonymous classes
 200   if (!is_nonfindable && (unsafe_anonymous_host == NULL)) {
 201     stream = check_class_file_load_hook(stream,
 202                                         name,
 203                                         loader_data,
 204                                         protection_domain,
 205                                         &cached_class_file,
 206                                         CHECK_NULL);
 207   }
 208 
 209   ClassFileParser parser(stream,
 210                          name,
 211                          loader_data,
 212                          protection_domain,
 213                          unsafe_anonymous_host,
 214                          cp_patches,
 215                          is_nonfindable,
 216                          can_access_vm_annotations,
 217                          ClassFileParser::BROADCAST, // publicity level
 218                          CHECK_NULL);
 219 
 220   InstanceKlass* result = parser.create_instance_klass(old_stream != stream, dynamic_nest_host, classData, CHECK_NULL);
 221   assert(result == parser.create_instance_klass(old_stream != stream, NULL, classData, THREAD), "invariant");
 222 
 223   if (result == NULL) {
 224     return NULL;
 225   }
 226 
 227   if (cached_class_file != NULL) {
 228     // JVMTI: we have an InstanceKlass now, tell it about the cached bytes
 229     result->set_cached_class_file(cached_class_file);
 230   }
 231 
 232   JFR_ONLY(ON_KLASS_CREATION(result, parser, THREAD);)
 233 
 234 #if INCLUDE_CDS
 235   if (DumpSharedSpaces) {
 236     ClassLoader::record_result(result, stream, THREAD);
 237   }
 238 #endif // INCLUDE_CDS
 239 
 240   return result;
 241 }