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 *ctx = ErrorContext::strict_fields_mismatch(target->offset(), 232 (StackMapFrame*)this, (StackMapFrame*)target); 233 return false; 234 } 235 236 if ((_flags | target->flags()) == target->flags()) { 237 return true; 238 } else { 239 *ctx = ErrorContext::bad_flags(target->offset(), 240 (StackMapFrame*)this, (StackMapFrame*)target); 241 return false; 242 } 243 } 244 245 VerificationType StackMapFrame::pop_stack_ex(VerificationType type, TRAPS) { 246 if (_stack_size <= 0) { 247 verifier()->verify_error( 248 ErrorContext::stack_underflow(_offset, this), 249 "Operand stack underflow"); 250 return VerificationType::bogus_type(); 251 } 252 VerificationType top = _stack[--_stack_size]; 253 bool subtype = type.is_assignable_from( 254 top, verifier(), false, CHECK_(VerificationType::bogus_type())); 255 if (!subtype) { 256 verifier()->verify_error( 257 ErrorContext::bad_type(_offset, stack_top_ctx(), 258 TypeOrigin::implicit(type)), 259 "Bad type on operand stack"); 260 return VerificationType::bogus_type(); 261 } 262 return top; 263 } 264 265 VerificationType StackMapFrame::get_local( 266 int32_t index, VerificationType type, TRAPS) { 267 if (index >= _max_locals) { 268 verifier()->verify_error( 269 ErrorContext::bad_local_index(_offset, index), 270 "Local variable table overflow"); 271 return VerificationType::bogus_type(); 272 } 273 bool subtype = type.is_assignable_from(_locals[index], 274 verifier(), false, CHECK_(VerificationType::bogus_type())); 275 if (!subtype) { 276 verifier()->verify_error( 277 ErrorContext::bad_type(_offset, 278 TypeOrigin::local(index, this), 279 TypeOrigin::implicit(type)), 280 "Bad local variable type"); 281 return VerificationType::bogus_type(); 282 } 283 if(index >= _locals_size) { _locals_size = index + 1; } 284 return _locals[index]; 285 } 286 287 void StackMapFrame::get_local_2( 288 int32_t index, VerificationType type1, VerificationType type2, TRAPS) { 289 assert(type1.is_long() || type1.is_double(), "must be long/double"); 290 assert(type2.is_long2() || type2.is_double2(), "must be long/double_2"); 291 if (index >= _locals_size - 1) { 292 verifier()->verify_error( 293 ErrorContext::bad_local_index(_offset, index), 294 "get long/double overflows locals"); 295 return; 296 } 297 bool subtype = type1.is_assignable_from(_locals[index], verifier(), false, CHECK); 298 if (!subtype) { 299 verifier()->verify_error( 300 ErrorContext::bad_type(_offset, 301 TypeOrigin::local(index, this), TypeOrigin::implicit(type1)), 302 "Bad local variable type"); 303 } else { 304 subtype = type2.is_assignable_from(_locals[index + 1], verifier(), false, CHECK); 305 if (!subtype) { 306 /* Unreachable? All local store routines convert a split long or double 307 * into a TOP during the store. So we should never end up seeing an 308 * orphaned half. */ 309 verifier()->verify_error( 310 ErrorContext::bad_type(_offset, 311 TypeOrigin::local(index + 1, this), TypeOrigin::implicit(type2)), 312 "Bad local variable type"); 313 } 314 } 315 } 316 317 void StackMapFrame::set_local(int32_t index, VerificationType type, TRAPS) { 318 assert(!type.is_check(), "Must be a real type"); 319 if (index >= _max_locals) { 320 verifier()->verify_error( 321 ErrorContext::bad_local_index(_offset, index), 322 "Local variable table overflow"); 323 return; 324 } 325 // If type at index is double or long, set the next location to be unusable 326 if (_locals[index].is_double() || _locals[index].is_long()) { 327 assert((index + 1) < _locals_size, "Local variable table overflow"); 328 _locals[index + 1] = VerificationType::bogus_type(); 329 } 330 // If type at index is double_2 or long_2, set the previous location to be unusable 331 if (_locals[index].is_double2() || _locals[index].is_long2()) { 332 assert(index >= 1, "Local variable table underflow"); 333 _locals[index - 1] = VerificationType::bogus_type(); 334 } 335 _locals[index] = type; 336 if (index >= _locals_size) { 337 #ifdef ASSERT 338 for (int i=_locals_size; i<index; i++) { 339 assert(_locals[i] == VerificationType::bogus_type(), 340 "holes must be bogus type"); 341 } 342 #endif 343 _locals_size = index + 1; 344 } 345 } 346 347 void StackMapFrame::set_local_2( 348 int32_t index, VerificationType type1, VerificationType type2, TRAPS) { 349 assert(type1.is_long() || type1.is_double(), "must be long/double"); 350 assert(type2.is_long2() || type2.is_double2(), "must be long/double_2"); 351 if (index >= _max_locals - 1) { 352 verifier()->verify_error( 353 ErrorContext::bad_local_index(_offset, index), 354 "Local variable table overflow"); 355 return; 356 } 357 // If type at index+1 is double or long, set the next location to be unusable 358 if (_locals[index+1].is_double() || _locals[index+1].is_long()) { 359 assert((index + 2) < _locals_size, "Local variable table overflow"); 360 _locals[index + 2] = VerificationType::bogus_type(); 361 } 362 // If type at index is double_2 or long_2, set the previous location to be unusable 363 if (_locals[index].is_double2() || _locals[index].is_long2()) { 364 assert(index >= 1, "Local variable table underflow"); 365 _locals[index - 1] = VerificationType::bogus_type(); 366 } 367 _locals[index] = type1; 368 _locals[index+1] = type2; 369 if (index >= _locals_size - 1) { 370 #ifdef ASSERT 371 for (int i=_locals_size; i<index; i++) { 372 assert(_locals[i] == VerificationType::bogus_type(), 373 "holes must be bogus type"); 374 } 375 #endif 376 _locals_size = index + 2; 377 } 378 } 379 380 TypeOrigin StackMapFrame::stack_top_ctx() { 381 return TypeOrigin::stack(_stack_size, this); 382 } 383 384 void StackMapFrame::print_on(outputStream* str) const { 385 str->indent().print_cr("bci: @%d", _offset); 386 str->indent().print_cr("flags: {%s }", 387 flag_this_uninit() ? " flagThisUninit" : ""); 388 str->indent().print("locals: {"); 389 for (int32_t i = 0; i < _locals_size; ++i) { 390 str->print(" "); 391 _locals[i].print_on(str); 392 if (i != _locals_size - 1) { 393 str->print(","); 394 } 395 } 396 str->print_cr(" }"); 397 str->indent().print("stack: {"); 398 for (int32_t j = 0; j < _stack_size; ++j) { 399 str->print(" "); 400 _stack[j].print_on(str); 401 if (j != _stack_size - 1) { 402 str->print(","); 403 } 404 } 405 str->print_cr(" }"); 406 }