1 /* 2 * Copyright (c) 2005, 2024, 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 #ifndef SHARE_PRIMS_JVMTICLASSFILERECONSTITUTER_HPP 26 #define SHARE_PRIMS_JVMTICLASSFILERECONSTITUTER_HPP 27 28 #include "jvmtifiles/jvmtiEnv.hpp" 29 #include "oops/constantPool.hpp" 30 31 32 class JvmtiConstantPoolReconstituter : public StackObj { 33 private: 34 int _cpool_size; 35 ConstantPool::SymbolHash* _symmap; 36 ConstantPool::SymbolHash* _classmap; 37 constantPoolHandle _cpool; 38 InstanceKlass* _ik; 39 jvmtiError _err; 40 41 protected: 42 InstanceKlass* ik() { return _ik; }; 43 constantPoolHandle cpool() { return _cpool; }; 44 45 u2 symbol_to_cpool_index(Symbol* sym) { 46 return _symmap->symbol_to_value(sym); 47 } 48 49 u2 class_symbol_to_cpool_index(Symbol* sym) { 50 return _classmap->symbol_to_value(sym); 51 } 52 53 public: 54 // Calls to this constructor must be proceeded by a ResourceMark 55 // and a HandleMark 56 JvmtiConstantPoolReconstituter(InstanceKlass* ik); 57 58 ~JvmtiConstantPoolReconstituter() { 59 if (_symmap != nullptr) { 60 delete _symmap; 61 _symmap = nullptr; 62 } 63 if (_classmap != nullptr) { 64 delete _classmap; 65 _classmap = nullptr; 66 } 67 } 68 69 70 void set_error(jvmtiError err) { _err = err; } 71 jvmtiError get_error() { return _err; } 72 73 int cpool_size() { return _cpool_size; } 74 75 void copy_cpool_bytes(unsigned char *cpool_bytes) { 76 if (cpool_bytes == nullptr) { 77 assert(cpool_bytes != nullptr, "cpool_bytes pointer must not be null"); 78 return; 79 } 80 cpool()->copy_cpool_bytes(cpool_size(), _symmap, cpool_bytes); 81 } 82 }; 83 84 85 class JvmtiClassFileReconstituter : public JvmtiConstantPoolReconstituter { 86 private: 87 size_t _buffer_size; 88 u1* _buffer; 89 u1* _buffer_ptr; 90 Thread* _thread; 91 92 enum { 93 // initial size should be power of two 94 initial_buffer_size = 1024 95 }; 96 97 inline Thread* thread() { return _thread; } 98 99 void write_class_file_format(); 100 void write_field_infos(); 101 void write_method_infos(); 102 void write_method_info(const methodHandle& method); 103 void write_code_attribute(const methodHandle& method); 104 void write_exceptions_attribute(ConstMethod* const_method); 105 void write_method_parameter_attribute(const ConstMethod* const_method); 106 void write_synthetic_attribute(); 107 void write_class_attributes(); 108 void write_source_file_attribute(); 109 void write_source_debug_extension_attribute(); 110 u2 line_number_table_entries(const methodHandle& method); 111 void write_line_number_table_attribute(const methodHandle& method, u2 num_entries); 112 void write_local_variable_table_attribute(const methodHandle& method, u2 num_entries); 113 void write_local_variable_type_table_attribute(const methodHandle& method, u2 num_entries); 114 void write_stackmap_table_attribute(const methodHandle& method, int stackmap_table_len); 115 u2 inner_classes_attribute_length(); 116 void write_inner_classes_attribute(int length); 117 void write_signature_attribute(u2 generic_signaure_index); 118 void write_attribute_name_index(const char* name); 119 void write_annotations_attribute(const char* attr_name, AnnotationArray* annos); 120 // With PreserveAllAnnotations option "runtime invisible" annotations 121 // (RuntimeInvisibleAnnotations/RuntimeInvisibleTypeAnnotations/RuntimeInvisibleParameterAnnotations) 122 // are considered "runtime visible" and ClassFileReconstituter writes them as 123 // RuntimeVisibleAnnotations/RuntimeVisibleTypeAnnotations/RuntimeVisibleParameterAnnotations. 124 // This helper method is for the corner case when "runtime visible" attribute name is not presents 125 // in the class constant pool and the annotations are written with fallback "runtime invisible" name. 126 void write_annotations_attribute(const char* attr_name, const char* fallback_attr_name, AnnotationArray* annos); 127 void write_bootstrapmethod_attribute(); 128 void write_nest_host_attribute(); 129 void write_nest_members_attribute(); 130 void write_permitted_subclasses_attribute(); 131 void write_record_attribute(); 132 133 address writeable_address(size_t size); 134 void write_u1(u1 x); 135 void write_u2(u2 x); 136 void write_u4(u4 x); 137 void write_u8(u8 x); 138 139 public: 140 // Calls to this constructor must be proceeded by a ResourceMark 141 // and a HandleMark 142 JvmtiClassFileReconstituter(InstanceKlass* ik) : 143 JvmtiConstantPoolReconstituter(ik) { 144 _buffer_size = initial_buffer_size; 145 _buffer = _buffer_ptr = NEW_RESOURCE_ARRAY(u1, _buffer_size); 146 _thread = Thread::current(); 147 write_class_file_format(); 148 }; 149 150 size_t class_file_size() { return _buffer_ptr - _buffer; } 151 152 u1* class_file_bytes() { return _buffer; } 153 154 static void copy_bytecodes(const methodHandle& method, unsigned char* bytecodes); 155 }; 156 157 #endif // SHARE_PRIMS_JVMTICLASSFILERECONSTITUTER_HPP