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