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