1 /*
2 * Copyright (c) 2003, 2018, 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 *
37 case ITEM_Float: return float_type();
38 case ITEM_Double: return double_type();
39 case ITEM_Long: return long_type();
40 case ITEM_Null: return null_type();
41 default:
42 ShouldNotReachHere();
43 return bogus_type();
44 }
45 }
46
47 bool VerificationType::resolve_and_check_assignability(InstanceKlass* klass, Symbol* name,
48 Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object, TRAPS) {
49 HandleMark hm(THREAD);
50 Klass* this_class = SystemDictionary::resolve_or_fail(
51 name, Handle(THREAD, klass->class_loader()),
52 Handle(THREAD, klass->protection_domain()), true, CHECK_false);
53 if (log_is_enabled(Debug, class, resolve)) {
54 Verifier::trace_class_resolution(this_class, klass);
55 }
56
57 if (this_class->is_interface() && (!from_field_is_protected ||
58 from_name != vmSymbols::java_lang_Object())) {
59 // If we are not trying to access a protected field or method in
60 // java.lang.Object then, for arrays, we only allow assignability
61 // to interfaces java.lang.Cloneable and java.io.Serializable.
62 // Otherwise, we treat interfaces as java.lang.Object.
63 return !from_is_array ||
64 this_class == SystemDictionary::Cloneable_klass() ||
65 this_class == SystemDictionary::Serializable_klass();
66 } else if (from_is_object) {
67 Klass* from_class = SystemDictionary::resolve_or_fail(
68 from_name, Handle(THREAD, klass->class_loader()),
69 Handle(THREAD, klass->protection_domain()), true, CHECK_false);
70 if (log_is_enabled(Debug, class, resolve)) {
71 Verifier::trace_class_resolution(from_class, klass);
72 }
73 return InstanceKlass::cast(from_class)->is_subclass_of(this_class);
74 }
75
76 return false;
90 } else if (is_object()) {
91 // We need check the class hierarchy to check assignability
92 if (name() == vmSymbols::java_lang_Object()) {
93 // any object or array is assignable to java.lang.Object
94 return true;
95 }
96
97 if (DumpSharedSpaces && SystemDictionaryShared::add_verification_constraint(klass,
98 name(), from.name(), from_field_is_protected, from.is_array(),
99 from.is_object())) {
100 // If add_verification_constraint() returns true, the resolution/check should be
101 // delayed until runtime.
102 return true;
103 }
104
105 return resolve_and_check_assignability(klass, name(), from.name(),
106 from_field_is_protected, from.is_array(), from.is_object(), THREAD);
107 } else if (is_array() && from.is_array()) {
108 VerificationType comp_this = get_component(context, CHECK_false);
109 VerificationType comp_from = from.get_component(context, CHECK_false);
110 if (!comp_this.is_bogus() && !comp_from.is_bogus()) {
111 return comp_this.is_component_assignable_from(comp_from, context,
112 from_field_is_protected, THREAD);
113 }
114 }
115 return false;
116 }
117
118 VerificationType VerificationType::get_component(ClassVerifier *context, TRAPS) const {
119 assert(is_array() && name()->utf8_length() >= 2, "Must be a valid array");
120 Symbol* component;
121 switch (name()->char_at(1)) {
122 case 'Z': return VerificationType(Boolean);
123 case 'B': return VerificationType(Byte);
124 case 'C': return VerificationType(Char);
125 case 'S': return VerificationType(Short);
126 case 'I': return VerificationType(Integer);
127 case 'J': return VerificationType(Long);
128 case 'F': return VerificationType(Float);
129 case 'D': return VerificationType(Double);
130 case '[':
131 component = context->create_temporary_symbol(
132 name(), 1, name()->utf8_length(),
133 CHECK_(VerificationType::bogus_type()));
134 return VerificationType::reference_type(component);
135 case 'L':
136 component = context->create_temporary_symbol(
137 name(), 2, name()->utf8_length() - 1,
138 CHECK_(VerificationType::bogus_type()));
139 return VerificationType::reference_type(component);
140 default:
141 // Met an invalid type signature, e.g. [X
142 return VerificationType::bogus_type();
143 }
144 }
145
146 void VerificationType::print_on(outputStream* st) const {
147 switch (_u._data) {
148 case Bogus: st->print("top"); break;
149 case Category1: st->print("category1"); break;
150 case Category2: st->print("category2"); break;
151 case Category2_2nd: st->print("category2_2nd"); break;
152 case Boolean: st->print("boolean"); break;
153 case Byte: st->print("byte"); break;
154 case Short: st->print("short"); break;
155 case Char: st->print("char"); break;
156 case Integer: st->print("integer"); break;
157 case Float: st->print("float"); break;
158 case Long: st->print("long"); break;
159 case Double: st->print("double"); break;
160 case Long_2nd: st->print("long_2nd"); break;
161 case Double_2nd: st->print("double_2nd"); break;
162 case Null: st->print("null"); break;
163 case ReferenceQuery: st->print("reference type"); break;
164 case Category1Query: st->print("category1 type"); break;
165 case Category2Query: st->print("category2 type"); break;
166 case Category2_2ndQuery: st->print("category2_2nd type"); break;
167 default:
168 if (is_uninitialized_this()) {
169 st->print("uninitializedThis");
170 } else if (is_uninitialized()) {
171 st->print("uninitialized %d", bci());
172 } else {
173 if (name() != NULL) {
174 name()->print_value_on(st);
175 } else {
176 st->print_cr("NULL");
177 }
178 }
179 }
180 }
|
1 /*
2 * Copyright (c) 2003, 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 *
37 case ITEM_Float: return float_type();
38 case ITEM_Double: return double_type();
39 case ITEM_Long: return long_type();
40 case ITEM_Null: return null_type();
41 default:
42 ShouldNotReachHere();
43 return bogus_type();
44 }
45 }
46
47 bool VerificationType::resolve_and_check_assignability(InstanceKlass* klass, Symbol* name,
48 Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object, TRAPS) {
49 HandleMark hm(THREAD);
50 Klass* this_class = SystemDictionary::resolve_or_fail(
51 name, Handle(THREAD, klass->class_loader()),
52 Handle(THREAD, klass->protection_domain()), true, CHECK_false);
53 if (log_is_enabled(Debug, class, resolve)) {
54 Verifier::trace_class_resolution(this_class, klass);
55 }
56
57 if (this_class->access_flags().is_value_type()) return false;
58 if (this_class->is_interface() && (!from_field_is_protected ||
59 from_name != vmSymbols::java_lang_Object())) {
60 // If we are not trying to access a protected field or method in
61 // java.lang.Object then, for arrays, we only allow assignability
62 // to interfaces java.lang.Cloneable and java.io.Serializable.
63 // Otherwise, we treat interfaces as java.lang.Object.
64 return !from_is_array ||
65 this_class == SystemDictionary::Cloneable_klass() ||
66 this_class == SystemDictionary::Serializable_klass();
67 } else if (from_is_object) {
68 Klass* from_class = SystemDictionary::resolve_or_fail(
69 from_name, Handle(THREAD, klass->class_loader()),
70 Handle(THREAD, klass->protection_domain()), true, CHECK_false);
71 if (log_is_enabled(Debug, class, resolve)) {
72 Verifier::trace_class_resolution(from_class, klass);
73 }
74 return InstanceKlass::cast(from_class)->is_subclass_of(this_class);
75 }
76
77 return false;
91 } else if (is_object()) {
92 // We need check the class hierarchy to check assignability
93 if (name() == vmSymbols::java_lang_Object()) {
94 // any object or array is assignable to java.lang.Object
95 return true;
96 }
97
98 if (DumpSharedSpaces && SystemDictionaryShared::add_verification_constraint(klass,
99 name(), from.name(), from_field_is_protected, from.is_array(),
100 from.is_object())) {
101 // If add_verification_constraint() returns true, the resolution/check should be
102 // delayed until runtime.
103 return true;
104 }
105
106 return resolve_and_check_assignability(klass, name(), from.name(),
107 from_field_is_protected, from.is_array(), from.is_object(), THREAD);
108 } else if (is_array() && from.is_array()) {
109 VerificationType comp_this = get_component(context, CHECK_false);
110 VerificationType comp_from = from.get_component(context, CHECK_false);
111
112 /*
113 // This code implements non-covariance between value type arrays and both
114 // arrays of objects and arrays of interface types. If covariance is
115 // supported for value type arrays then this code should be removed.
116 if (comp_from.is_valuetype() && !comp_this.is_null() && comp_this.is_reference()) {
117 // An array of value types is not assignable to an array of java.lang.Objects.
118 if (comp_this.name() == vmSymbols::java_lang_Object()) {
119 return false;
120 }
121
122 // Need to load 'comp_this' to see if it is an interface.
123 InstanceKlass* klass = context->current_class();
124 {
125 HandleMark hm(THREAD);
126 Klass* comp_this_class = SystemDictionary::resolve_or_fail(
127 comp_this.name(), Handle(THREAD, klass->class_loader()),
128 Handle(THREAD, klass->protection_domain()), true, CHECK_false);
129 klass->class_loader_data()->record_dependency(comp_this_class);
130 if (log_is_enabled(Debug, class, resolve)) {
131 Verifier::trace_class_resolution(comp_this_class, klass);
132 }
133 // An array of value types is not assignable to an array of interface types.
134 if (comp_this_class->is_interface()) {
135 return false;
136 }
137 }
138 }
139 */
140 if (!comp_this.is_bogus() && !comp_from.is_bogus()) {
141 return comp_this.is_component_assignable_from(comp_from, context,
142 from_field_is_protected, THREAD);
143 }
144 }
145 return false;
146 }
147
148 bool VerificationType::is_valuetype_assignable_from(const VerificationType& from) const {
149 // Check that 'from' is not null, is a value type, and is the same value type.
150 assert(is_valuetype(), "called with a non-valuetype type");
151 assert(!is_null(), "valuetype is not null");
152 assert(name() != vmSymbols::java_lang_Object(), "java.lang.Object is a value type?");
153 return (!from.is_null() && from.is_valuetype() && name() == from.name());
154 }
155
156 bool VerificationType::is_ref_assignable_from_value_type(const VerificationType& from, ClassVerifier* context, TRAPS) const {
157 assert(!from.is_null(), "Value type should not be null");
158 if (!is_null() && (name()->is_same_fundamental_type(from.name()) ||
159 name() == vmSymbols::java_lang_Object())) {
160 return true;
161 }
162
163 // Need to load 'this' to see if it is an interface.
164 InstanceKlass* klass = context->current_class();
165 {
166 HandleMark hm(THREAD);
167 Klass* this_class = SystemDictionary::resolve_or_fail(
168 name(), Handle(THREAD, klass->class_loader()),
169 Handle(THREAD, klass->protection_domain()), true, CHECK_false);
170 klass->class_loader_data()->record_dependency(this_class);
171 if (log_is_enabled(Debug, class, resolve)) {
172 Verifier::trace_class_resolution(this_class, klass);
173 }
174 return (this_class->is_interface());
175 }
176 }
177
178 VerificationType VerificationType::get_component(ClassVerifier *context, TRAPS) const {
179 assert(is_array() && name()->utf8_length() >= 2, "Must be a valid array");
180 Symbol* component;
181 switch (name()->char_at(1)) {
182 case 'Z': return VerificationType(Boolean);
183 case 'B': return VerificationType(Byte);
184 case 'C': return VerificationType(Char);
185 case 'S': return VerificationType(Short);
186 case 'I': return VerificationType(Integer);
187 case 'J': return VerificationType(Long);
188 case 'F': return VerificationType(Float);
189 case 'D': return VerificationType(Double);
190 case '[':
191 component = context->create_temporary_symbol(
192 name(), 1, name()->utf8_length(),
193 CHECK_(VerificationType::bogus_type()));
194 return VerificationType::reference_type(component);
195 case 'L':
196 component = context->create_temporary_symbol(
197 name(), 2, name()->utf8_length() - 1,
198 CHECK_(VerificationType::bogus_type()));
199 return VerificationType::reference_type(component);
200 case 'Q':
201 component = context->create_temporary_symbol(
202 name(), 2, name()->utf8_length() - 1,
203 CHECK_(VerificationType::bogus_type()));
204 return VerificationType::valuetype_type(component);
205 default:
206 // Met an invalid type signature, e.g. [X
207 return VerificationType::bogus_type();
208 }
209 }
210
211 void VerificationType::print_on(outputStream* st) const {
212 switch (_u._data) {
213 case Bogus: st->print("top"); break;
214 case Category1: st->print("category1"); break;
215 case Category2: st->print("category2"); break;
216 case Category2_2nd: st->print("category2_2nd"); break;
217 case Boolean: st->print("boolean"); break;
218 case Byte: st->print("byte"); break;
219 case Short: st->print("short"); break;
220 case Char: st->print("char"); break;
221 case Integer: st->print("integer"); break;
222 case Float: st->print("float"); break;
223 case Long: st->print("long"); break;
224 case Double: st->print("double"); break;
225 case Long_2nd: st->print("long_2nd"); break;
226 case Double_2nd: st->print("double_2nd"); break;
227 case Null: st->print("null"); break;
228 case ReferenceQuery: st->print("reference type"); break;
229 case ValueTypeQuery: st->print("value type"); break;
230 case NonScalarQuery: st->print("reference or value type"); break;
231 case Category1Query: st->print("category1 type"); break;
232 case Category2Query: st->print("category2 type"); break;
233 case Category2_2ndQuery: st->print("category2_2nd type"); break;
234 default:
235 if (is_uninitialized_this()) {
236 st->print("uninitializedThis");
237 } else if (is_uninitialized()) {
238 st->print("uninitialized %d", bci());
239 } else if (is_valuetype()) {
240 name()->print_Qvalue_on(st);
241 } else {
242 if (name() != NULL) {
243 name()->print_value_on(st);
244 } else {
245 st->print_cr("NULL");
246 }
247 }
248 }
249 }
|