1 /* 2 * Copyright (c) 2003, 2025, 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 "classfile/stackMapFrame.hpp" 26 #include "classfile/verifier.hpp" 27 #include "classfile/vmSymbols.hpp" 28 #include "memory/resourceArea.hpp" 29 #include "oops/oop.inline.hpp" 30 #include "oops/symbol.hpp" 31 #include "runtime/handles.inline.hpp" 32 #include "utilities/globalDefinitions.hpp" 33 34 StackMapFrame::StackMapFrame(u2 max_locals, u2 max_stack, AssertUnsetFieldTable* initial_strict_fields, ClassVerifier* v) : 35 _offset(0), _locals_size(0), _stack_size(0), 36 _stack_mark(0), _max_locals(max_locals), 37 _max_stack(max_stack), _flags(0), _assert_unset_fields(initial_strict_fields), _verifier(v) { 38 Thread* thr = v->thread(); 39 _locals = NEW_RESOURCE_ARRAY_IN_THREAD(thr, VerificationType, max_locals); 40 _stack = NEW_RESOURCE_ARRAY_IN_THREAD(thr, VerificationType, max_stack); 41 int32_t i; 42 for(i = 0; i < max_locals; i++) { 43 _locals[i] = VerificationType::bogus_type(); 44 } 45 for(i = 0; i < max_stack; i++) { 46 _stack[i] = VerificationType::bogus_type(); 47 } 48 } 49 50 void StackMapFrame::unsatisfied_strict_fields_error(InstanceKlass* klass, int bci) { 51 // Default these to `<Unknown>` as they will be replaced with the correct 52 // values by the `find_unset` lambda as we only call this code when 53 // an error has already been determined. This just provides a safe 54 // obvious fallback value. 55 Symbol* name = vmSymbols::unknown_class_name(); 56 Symbol* sig = vmSymbols::unknown_class_name(); 57 int num_uninit_fields = 0; 58 59 auto find_unset = [&] (const NameAndSig& key, const bool& value) { 60 if (!value) { 61 name = key._name; 62 sig = key._signature; 63 num_uninit_fields++; 64 } 65 }; 66 assert_unset_fields()->iterate_all(find_unset); 67 68 verifier()->verify_error( 69 ErrorContext::bad_strict_fields(bci, this), 70 "All strict final fields must be initialized before super(): %d field(s), %s:%s in %s", 71 num_uninit_fields, 72 name->as_C_string(), 73 sig->as_C_string(), 74 klass->name()->as_C_string() 75 ); 76 } 77 78 void StackMapFrame::print_strict_fields(AssertUnsetFieldTable* table) { 79 ResourceMark rm; 80 auto printfields = [&] (const NameAndSig& key, const bool& value) { 81 log_info(verification)("Strict field: %s%s (Satisfied: %s)", 82 key._name->as_C_string(), 83 key._signature->as_C_string(), 84 value ? "true" : "false"); 85 }; 86 table->iterate_all(printfields); 87 } 88 89 StackMapFrame* StackMapFrame::frame_in_exception_handler(u1 flags) { 90 Thread* thr = _verifier->thread(); 91 VerificationType* stack = NEW_RESOURCE_ARRAY_IN_THREAD(thr, VerificationType, 1); 92 StackMapFrame* frame = new StackMapFrame(_offset, flags, _locals_size, 0, 93 _max_locals, _max_stack, _locals, stack, 94 _assert_unset_fields, _verifier); 95 return frame; 96 } 97 98 void StackMapFrame::initialize_object( 99 VerificationType old_object, VerificationType new_object) { 100 int32_t i; 101 for (i = 0; i < _max_locals; i++) { 102 if (_locals[i].equals(old_object)) { 103 _locals[i] = new_object; 104 } 105 } 106 for (i = 0; i < _stack_size; i++) { 107 if (_stack[i].equals(old_object)) { 108 _stack[i] = new_object; 109 } 110 } 111 if (old_object == VerificationType::uninitialized_this_type()) { 112 // "this" has been initialized - reset flags 113 _flags = 0; 114 } 115 } 116 117 VerificationType StackMapFrame::set_locals_from_arg( 118 const methodHandle& m, VerificationType thisKlass) { 119 SignatureStream ss(m->signature()); 120 int init_local_num = 0; 121 if (!m->is_static()) { 122 init_local_num++; 123 // add one extra argument for instance method 124 if (m->is_object_constructor() && 125 thisKlass.name() != vmSymbols::java_lang_Object()) { 126 _locals[0] = VerificationType::uninitialized_this_type(); 127 _flags |= FLAG_THIS_UNINIT; 128 } else { 129 _locals[0] = thisKlass; 130 } 131 } 132 133 // local num may be greater than size of parameters because long/double occupies two slots 134 while(!ss.at_return_type()) { 135 init_local_num += _verifier->change_sig_to_verificationType( 136 &ss, &_locals[init_local_num]); 137 ss.next(); 138 } 139 _locals_size = init_local_num; 140 141 switch (ss.type()) { 142 case T_OBJECT: 143 case T_ARRAY: 144 { 145 Symbol* sig = ss.as_symbol(); 146 if (!sig->is_permanent()) { 147 // Create another symbol to save as signature stream unreferences 148 // this symbol. 149 Symbol *sig_copy = 150 verifier()->create_temporary_symbol(sig); 151 assert(sig_copy == sig, "symbols don't match"); 152 sig = sig_copy; 153 } 154 return VerificationType::reference_type(sig); 155 } 156 case T_INT: return VerificationType::integer_type(); 157 case T_BYTE: return VerificationType::byte_type(); 158 case T_CHAR: return VerificationType::char_type(); 159 case T_SHORT: return VerificationType::short_type(); 160 case T_BOOLEAN: return VerificationType::boolean_type(); 161 case T_FLOAT: return VerificationType::float_type(); 162 case T_DOUBLE: return VerificationType::double_type(); 163 case T_LONG: return VerificationType::long_type(); 164 case T_VOID: return VerificationType::bogus_type(); 165 default: 166 ShouldNotReachHere(); 167 } 168 return VerificationType::bogus_type(); 169 } 170 171 void StackMapFrame::copy_locals(const StackMapFrame* src) { 172 int32_t len = src->locals_size() < _locals_size ? 173 src->locals_size() : _locals_size; 174 for (int32_t i = 0; i < len; i++) { 175 _locals[i] = src->locals()[i]; 176 } 177 } 178 179 void StackMapFrame::copy_stack(const StackMapFrame* src) { 180 int32_t len = src->stack_size() < _stack_size ? 181 src->stack_size() : _stack_size; 182 for (int32_t i = 0; i < len; i++) { 183 _stack[i] = src->stack()[i]; 184 } 185 } 186 187 // Returns the location of the first mismatch, or 'len' if there are no 188 // mismatches 189 int StackMapFrame::is_assignable_to( 190 VerificationType* from, VerificationType* to, int32_t len, TRAPS) const { 191 int32_t i = 0; 192 for (i = 0; i < len; i++) { 193 if (!to[i].is_assignable_from(from[i], verifier(), false, THREAD)) { 194 break; 195 } 196 } 197 return i; 198 } 199 200 bool StackMapFrame::is_assignable_to( 201 const StackMapFrame* target, ErrorContext* ctx, TRAPS) const { 202 if (_max_locals != target->max_locals()) { 203 *ctx = ErrorContext::locals_size_mismatch( 204 _offset, (StackMapFrame*)this, (StackMapFrame*)target); 205 return false; 206 } 207 if (_stack_size != target->stack_size()) { 208 *ctx = ErrorContext::stack_size_mismatch( 209 _offset, (StackMapFrame*)this, (StackMapFrame*)target); 210 return false; 211 } 212 // Only need to compare type elements up to target->locals() or target->stack(). 213 // The remaining type elements in this state can be ignored because they are 214 // assignable to bogus type. 215 int mismatch_loc; 216 mismatch_loc = is_assignable_to( 217 _locals, target->locals(), target->locals_size(), THREAD); 218 if (mismatch_loc != target->locals_size()) { 219 *ctx = ErrorContext::bad_type(target->offset(), 220 TypeOrigin::local(mismatch_loc, (StackMapFrame*)this), 221 TypeOrigin::sm_local(mismatch_loc, (StackMapFrame*)target)); 222 return false; 223 } 224 mismatch_loc = is_assignable_to(_stack, target->stack(), _stack_size, THREAD); 225 if (mismatch_loc != _stack_size) { 226 *ctx = ErrorContext::bad_type(target->offset(), 227 TypeOrigin::stack(mismatch_loc, (StackMapFrame*)this), 228 TypeOrigin::sm_stack(mismatch_loc, (StackMapFrame*)target)); 229 return false; 230 } 231 232 // Check that assert unset fields are compatible 233 bool compatible = verify_unset_fields_compatibility(target->assert_unset_fields()); 234 if (!compatible) { 235 print_strict_fields(assert_unset_fields()); 236 print_strict_fields(target->assert_unset_fields()); 237 *ctx = ErrorContext::strict_fields_mismatch(target->offset(), 238 (StackMapFrame*)this, (StackMapFrame*)target); 239 return false; 240 } 241 242 if ((_flags | target->flags()) == target->flags()) { 243 return true; 244 } else { 245 *ctx = ErrorContext::bad_flags(target->offset(), 246 (StackMapFrame*)this, (StackMapFrame*)target); 247 return false; 248 } 249 } 250 251 VerificationType StackMapFrame::pop_stack_ex(VerificationType type, TRAPS) { 252 if (_stack_size <= 0) { 253 verifier()->verify_error( 254 ErrorContext::stack_underflow(_offset, this), 255 "Operand stack underflow"); 256 return VerificationType::bogus_type(); 257 } 258 VerificationType top = _stack[--_stack_size]; 259 bool subtype = type.is_assignable_from( 260 top, verifier(), false, CHECK_(VerificationType::bogus_type())); 261 if (!subtype) { 262 verifier()->verify_error( 263 ErrorContext::bad_type(_offset, stack_top_ctx(), 264 TypeOrigin::implicit(type)), 265 "Bad type on operand stack"); 266 return VerificationType::bogus_type(); 267 } 268 return top; 269 } 270 271 VerificationType StackMapFrame::get_local( 272 int32_t index, VerificationType type, TRAPS) { 273 if (index >= _max_locals) { 274 verifier()->verify_error( 275 ErrorContext::bad_local_index(_offset, index), 276 "Local variable table overflow"); 277 return VerificationType::bogus_type(); 278 } 279 bool subtype = type.is_assignable_from(_locals[index], 280 verifier(), false, CHECK_(VerificationType::bogus_type())); 281 if (!subtype) { 282 verifier()->verify_error( 283 ErrorContext::bad_type(_offset, 284 TypeOrigin::local(index, this), 285 TypeOrigin::implicit(type)), 286 "Bad local variable type"); 287 return VerificationType::bogus_type(); 288 } 289 if(index >= _locals_size) { _locals_size = index + 1; } 290 return _locals[index]; 291 } 292 293 void StackMapFrame::get_local_2( 294 int32_t index, VerificationType type1, VerificationType type2, TRAPS) { 295 assert(type1.is_long() || type1.is_double(), "must be long/double"); 296 assert(type2.is_long2() || type2.is_double2(), "must be long/double_2"); 297 if (index >= _locals_size - 1) { 298 verifier()->verify_error( 299 ErrorContext::bad_local_index(_offset, index), 300 "get long/double overflows locals"); 301 return; 302 } 303 bool subtype = type1.is_assignable_from(_locals[index], verifier(), false, CHECK); 304 if (!subtype) { 305 verifier()->verify_error( 306 ErrorContext::bad_type(_offset, 307 TypeOrigin::local(index, this), TypeOrigin::implicit(type1)), 308 "Bad local variable type"); 309 } else { 310 subtype = type2.is_assignable_from(_locals[index + 1], verifier(), false, CHECK); 311 if (!subtype) { 312 /* Unreachable? All local store routines convert a split long or double 313 * into a TOP during the store. So we should never end up seeing an 314 * orphaned half. */ 315 verifier()->verify_error( 316 ErrorContext::bad_type(_offset, 317 TypeOrigin::local(index + 1, this), TypeOrigin::implicit(type2)), 318 "Bad local variable type"); 319 } 320 } 321 } 322 323 void StackMapFrame::set_local(int32_t index, VerificationType type, TRAPS) { 324 assert(!type.is_check(), "Must be a real type"); 325 if (index >= _max_locals) { 326 verifier()->verify_error( 327 ErrorContext::bad_local_index(_offset, index), 328 "Local variable table overflow"); 329 return; 330 } 331 // If type at index is double or long, set the next location to be unusable 332 if (_locals[index].is_double() || _locals[index].is_long()) { 333 assert((index + 1) < _locals_size, "Local variable table overflow"); 334 _locals[index + 1] = VerificationType::bogus_type(); 335 } 336 // If type at index is double_2 or long_2, set the previous location to be unusable 337 if (_locals[index].is_double2() || _locals[index].is_long2()) { 338 assert(index >= 1, "Local variable table underflow"); 339 _locals[index - 1] = VerificationType::bogus_type(); 340 } 341 _locals[index] = type; 342 if (index >= _locals_size) { 343 #ifdef ASSERT 344 for (int i=_locals_size; i<index; i++) { 345 assert(_locals[i] == VerificationType::bogus_type(), 346 "holes must be bogus type"); 347 } 348 #endif 349 _locals_size = index + 1; 350 } 351 } 352 353 void StackMapFrame::set_local_2( 354 int32_t index, VerificationType type1, VerificationType type2, TRAPS) { 355 assert(type1.is_long() || type1.is_double(), "must be long/double"); 356 assert(type2.is_long2() || type2.is_double2(), "must be long/double_2"); 357 if (index >= _max_locals - 1) { 358 verifier()->verify_error( 359 ErrorContext::bad_local_index(_offset, index), 360 "Local variable table overflow"); 361 return; 362 } 363 // If type at index+1 is double or long, set the next location to be unusable 364 if (_locals[index+1].is_double() || _locals[index+1].is_long()) { 365 assert((index + 2) < _locals_size, "Local variable table overflow"); 366 _locals[index + 2] = VerificationType::bogus_type(); 367 } 368 // If type at index is double_2 or long_2, set the previous location to be unusable 369 if (_locals[index].is_double2() || _locals[index].is_long2()) { 370 assert(index >= 1, "Local variable table underflow"); 371 _locals[index - 1] = VerificationType::bogus_type(); 372 } 373 _locals[index] = type1; 374 _locals[index+1] = type2; 375 if (index >= _locals_size - 1) { 376 #ifdef ASSERT 377 for (int i=_locals_size; i<index; i++) { 378 assert(_locals[i] == VerificationType::bogus_type(), 379 "holes must be bogus type"); 380 } 381 #endif 382 _locals_size = index + 2; 383 } 384 } 385 386 TypeOrigin StackMapFrame::stack_top_ctx() { 387 return TypeOrigin::stack(_stack_size, this); 388 } 389 390 void StackMapFrame::print_on(outputStream* str) const { 391 str->print_cr("bci: @%d", _offset); 392 str->print_cr("flags: {%s }", 393 flag_this_uninit() ? " flagThisUninit" : ""); 394 str->print("locals: {"); 395 for (int32_t i = 0; i < _locals_size; ++i) { 396 str->print(" "); 397 _locals[i].print_on(str); 398 if (i != _locals_size - 1) { 399 str->print(","); 400 } 401 } 402 str->print_cr(" }"); 403 str->print("stack: {"); 404 for (int32_t j = 0; j < _stack_size; ++j) { 405 str->print(" "); 406 _stack[j].print_on(str); 407 if (j != _stack_size - 1) { 408 str->print(","); 409 } 410 } 411 str->print_cr(" }"); 412 } --- EOF ---