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/stackMapTable.hpp"
 26 #include "classfile/verifier.hpp"
 27 #include "memory/resourceArea.hpp"
 28 #include "oops/constantPool.hpp"
 29 #include "oops/oop.inline.hpp"
 30 #include "runtime/handles.inline.hpp"
 31 
 32 StackMapTable::StackMapTable(StackMapReader* reader, TRAPS) {
 33   _code_length = reader->code_length();
 34   _frame_count = reader->get_frame_count();
 35   if (_frame_count > 0) {
 36     _frame_array = new GrowableArray<StackMapFrame*>(_frame_count);
 37     while (!reader->at_end()) {
 38       StackMapFrame* frame = reader->next(CHECK_VERIFY(reader->prev_frame()->verifier()));
 39       if (frame != nullptr) {
 40         _frame_array->push(frame);
 41       }
 42     }
 43     reader->check_end(CHECK);
 44     // Correct frame count based on how many actual frames are generated
 45     _frame_count = _frame_array->length();
 46   }
 47 }
 48 
 49 void StackMapReader::check_offset(StackMapFrame* frame) {
 50   int offset = frame->offset();
 51   if (offset >= _code_length || _code_data[offset] == 0) {
 52     _verifier->verify_error(ErrorContext::bad_stackmap(0, frame),
 53                             "StackMapTable error: bad offset");
 54   }
 55 }
 56 
 57 void StackMapReader::check_size(TRAPS) {
 58   if (_frame_count < _parsed_frame_count) {
 59     StackMapStream::stackmap_format_error("wrong attribute size", THREAD);
 60   }
 61 }
 62 
 63 void StackMapReader::check_end(TRAPS) {
 64   assert(_stream->at_end(), "must be");
 65   if (_frame_count != _parsed_frame_count) {
 66     StackMapStream::stackmap_format_error("wrong attribute size", THREAD);
 67   }
 68 }
 69 
 70 // This method is only called by method in StackMapTable.
 71 int StackMapTable::get_index_from_offset(int32_t offset) const {
 72   int i = 0;
 73   for (; i < _frame_count; i++) {
 74     if (_frame_array->at(i)->offset() == offset) {
 75       return i;
 76     }
 77   }
 78   return i;  // frame with offset doesn't exist in the array
 79 }
 80 
 81 bool StackMapTable::match_stackmap(
 82     StackMapFrame* frame, int32_t target,
 83     bool match, bool update, ErrorContext* ctx, TRAPS) const {
 84   int index = get_index_from_offset(target);
 85   return match_stackmap(frame, target, index, match, update, ctx, THREAD);
 86 }
 87 
 88 // Match and/or update current_frame to the frame in stackmap table with
 89 // specified offset and frame index. Return true if the two frames match.
 90 //
 91 // The values of match and update are:                  _match__update
 92 //
 93 // checking a branch target:                             true   false
 94 // checking an exception handler:                        true   false
 95 // linear bytecode verification following an
 96 // unconditional branch:                                 false  true
 97 // linear bytecode verification not following an
 98 // unconditional branch:                                 true   true
 99 bool StackMapTable::match_stackmap(
100     StackMapFrame* frame, int32_t target, int32_t frame_index,
101     bool match, bool update, ErrorContext* ctx, TRAPS) const {
102   if (frame_index < 0 || frame_index >= _frame_count) {
103     *ctx = ErrorContext::missing_stackmap(frame->offset());
104     frame->verifier()->verify_error(
105         *ctx, "Expecting a stackmap frame at branch target %d", target);
106     return false;
107   }
108 
109   StackMapFrame* stackmap_frame = _frame_array->at(frame_index);
110   bool result = true;
111   if (match) {
112     // Has direct control flow from last instruction, need to match the two
113     // frames.
114     result = frame->is_assignable_to(stackmap_frame,
115         ctx, CHECK_VERIFY_(frame->verifier(), result));
116   }
117   if (update) {
118     // Use the frame in stackmap table as current frame
119     int lsize = stackmap_frame->locals_size();
120     int ssize = stackmap_frame->stack_size();
121     if (frame->locals_size() > lsize || frame->stack_size() > ssize) {
122       // Make sure unused type array items are all _bogus_type.
123       frame->reset();
124     }
125     frame->set_locals_size(lsize);
126     frame->copy_locals(stackmap_frame);
127     frame->set_stack_size(ssize);
128     frame->copy_stack(stackmap_frame);
129     frame->set_flags(stackmap_frame->flags());
130     frame->set_assert_unset_fields(stackmap_frame->assert_unset_fields());
131   }
132   return result;
133 }
134 
135 void StackMapTable::check_jump_target(
136     StackMapFrame* frame, int bci, int offset, TRAPS) const {
137   ErrorContext ctx;
138   // Jump targets must be within the method and the method size is limited. See JVMS 4.11
139   int min_offset = -1 * max_method_code_size;
140   if (offset < min_offset || offset > max_method_code_size) {
141     frame->verifier()->verify_error(ErrorContext::bad_stackmap(bci, frame),
142         "Illegal target of jump or branch (bci %d + offset %d)", bci, offset);
143     return;
144   }
145   int target = bci + offset;
146   bool match = match_stackmap(
147     frame, target, true, false, &ctx, CHECK_VERIFY(frame->verifier()));
148   if (!match || (target < 0 || target >= _code_length)) {
149     frame->verifier()->verify_error(ctx,
150         "Inconsistent stackmap frames at branch target %d", target);
151   }
152 }
153 
154 void StackMapTable::print_on(outputStream* str) const {
155   str->print_cr("StackMapTable: frame_count = %d", _frame_count);
156   str->print_cr("table = {");
157   {
158     StreamIndentor si(str, 2);
159     for (int32_t i = 0; i < _frame_count; ++i) {
160       _frame_array->at(i)->print_on(str);
161     }
162   }
163   str->print_cr(" }");
164 }
165 
166 StackMapReader::StackMapReader(ClassVerifier* v, StackMapStream* stream,
167                                char* code_data, int32_t code_len,
168                                StackMapFrame* init_frame,
169                                u2 max_locals, u2 max_stack,
170                                StackMapFrame::AssertUnsetFieldTable* initial_strict_fields, TRAPS) :
171                                   _verifier(v), _stream(stream), _code_data(code_data),
172                                   _code_length(code_len), _parsed_frame_count(0),
173                                   _prev_frame(init_frame), _max_locals(max_locals),
174                                   _max_stack(max_stack), _assert_unset_fields_buffer(initial_strict_fields),
175                                   _first(true) {
176   methodHandle m = v->method();
177   if (m->has_stackmap_table()) {
178     _cp = constantPoolHandle(THREAD, m->constants());
179     _frame_count = _stream->get_u2(CHECK);
180   } else {
181     // There's no stackmap table present. Frame count and size are 0.
182     _frame_count = 0;
183   }
184 }
185 
186 int32_t StackMapReader::chop(
187     VerificationType* locals, int32_t length, int32_t chops) {
188   if (locals == nullptr) return -1;
189   int32_t pos = length - 1;
190   for (int32_t i=0; i<chops; i++) {
191     if (locals[pos].is_category2_2nd()) {
192       pos -= 2;
193     } else {
194       pos --;
195     }
196     if (pos<0 && i<(chops-1)) return -1;
197   }
198   return pos+1;
199 }
200 
201 #define CHECK_NT CHECK_(VerificationType::bogus_type())
202 
203 VerificationType StackMapReader::parse_verification_type(u1* flags, TRAPS) {
204   u1 tag = _stream->get_u1(CHECK_NT);
205   if (tag < (u1)ITEM_UninitializedThis) {
206     return VerificationType::from_tag(tag);
207   }
208   if (tag == ITEM_Object) {
209     u2 class_index = _stream->get_u2(CHECK_NT);
210     int nconstants = _cp->length();
211     if ((class_index <= 0 || class_index >= nconstants) ||
212         (!_cp->tag_at(class_index).is_klass() &&
213          !_cp->tag_at(class_index).is_unresolved_klass())) {
214       _stream->stackmap_format_error("bad class index", THREAD);
215       return VerificationType::bogus_type();
216     }
217     Symbol* klass_name = _cp->klass_name_at(class_index);
218     return VerificationType::reference_type(klass_name);
219   }
220   if (tag == ITEM_UninitializedThis) {
221     if (flags != nullptr) {
222       *flags |= FLAG_THIS_UNINIT;
223     }
224     return VerificationType::uninitialized_this_type();
225   }
226   if (tag == ITEM_Uninitialized) {
227     u2 offset = _stream->get_u2(CHECK_NT);
228     if (offset >= _code_length ||
229         _code_data[offset] != ClassVerifier::NEW_OFFSET) {
230       _verifier->class_format_error(
231         "StackMapTable format error: bad offset for Uninitialized");
232       return VerificationType::bogus_type();
233     }
234     return VerificationType::uninitialized_type(offset);
235   }
236   _stream->stackmap_format_error("bad verification type", THREAD);
237   return VerificationType::bogus_type();
238 }
239 
240 StackMapFrame* StackMapReader::next(TRAPS) {
241   _parsed_frame_count++;
242   check_size(CHECK_NULL);
243   StackMapFrame* frame = next_helper(CHECK_VERIFY_(_verifier, nullptr));
244   if (frame != nullptr) {
245     check_offset(frame);
246     if (frame->verifier()->has_error()) {
247       return nullptr;
248     }
249     _prev_frame = frame;
250   }
251   return frame;
252 }
253 
254 StackMapFrame* StackMapReader::next_helper(TRAPS) {
255   StackMapFrame* frame;
256   int offset;
257   VerificationType* locals = nullptr;
258   u1 frame_type = _stream->get_u1(CHECK_NULL);
259   if (frame_type == EARLY_LARVAL) {
260     u2 num_unset_fields = _stream->get_u2(CHECK_NULL);
261     StackMapFrame::AssertUnsetFieldTable* new_fields = new StackMapFrame::AssertUnsetFieldTable();
262 
263     for (u2 i = 0; i < num_unset_fields; i++) {
264       u2 index = _stream->get_u2(CHECK_NULL);
265 
266       if (!_cp->is_within_bounds(index) || !_cp->tag_at(index).is_name_and_type()) {
267         _prev_frame->verifier()->verify_error(
268           ErrorContext::bad_strict_fields(_prev_frame->offset(), _prev_frame),
269           "Invalid constant pool index in early larval frame: %d", index);
270         return nullptr;
271       }
272 
273       Symbol* name = _cp->symbol_at(_cp->name_ref_index_at(index));
274       Symbol* sig = _cp->symbol_at(_cp->signature_ref_index_at(index));
275       NameAndSig tmp(name, sig);
276 
277       if (!_prev_frame->assert_unset_fields()->contains(tmp)) {
278         log_info(verification)("NameAndType %s%s(CP index: %d) is not found among initial strict instance fields", name->as_C_string(), sig->as_C_string(), index);
279         StackMapFrame::print_strict_fields(_prev_frame->assert_unset_fields());
280         _prev_frame->verifier()->verify_error(
281             ErrorContext::bad_strict_fields(_prev_frame->offset(), _prev_frame),
282             "Strict fields not a subset of initial strict instance fields: %s:%s", name->as_C_string(), sig->as_C_string());
283         return nullptr;
284       } else {
285         new_fields->put(tmp, false);
286       }
287     }
288 
289     // Only modify strict instance fields the frame has uninitialized this
290     if (_prev_frame->flag_this_uninit()) {
291       _assert_unset_fields_buffer = _prev_frame->merge_unset_fields(new_fields);
292     } else if (new_fields->number_of_entries() > 0) {
293       _prev_frame->verifier()->verify_error(
294         ErrorContext::bad_strict_fields(_prev_frame->offset(), _prev_frame),
295         "Cannot have uninitialized strict fields after class initialization");
296       return nullptr;
297     }
298 
299     // Continue reading frame data
300     if (at_end()) {
301       _prev_frame->verifier()->verify_error(
302         ErrorContext::bad_strict_fields(_prev_frame->offset(), _prev_frame),
303         "Early larval frame must be followed by a base frame");
304       return nullptr;
305     }
306 
307     frame_type = _stream->get_u1(CHECK_NULL);
308     if (frame_type == EARLY_LARVAL) {
309       _prev_frame->verifier()->verify_error(
310         ErrorContext::bad_strict_fields(_prev_frame->offset(), _prev_frame),
311         "Early larval frame must be followed by a base frame");
312       return nullptr;
313     }
314   }
315 
316   if (frame_type <= SAME_FRAME_END) {
317     // same_frame
318     if (_first) {
319       offset = frame_type;
320       // Can't share the locals array since that is updated by the verifier.
321       if (_prev_frame->locals_size() > 0) {
322         locals = NEW_RESOURCE_ARRAY_IN_THREAD(
323           THREAD, VerificationType, _prev_frame->locals_size());
324       }
325     } else {
326       offset = _prev_frame->offset() + frame_type + 1;
327       locals = _prev_frame->locals();
328     }
329     frame = new StackMapFrame(
330       offset, _prev_frame->flags(), _prev_frame->locals_size(), 0,
331       _max_locals, _max_stack, locals, nullptr,
332       _assert_unset_fields_buffer, _verifier);
333     if (_first && locals != nullptr) {
334       frame->copy_locals(_prev_frame);
335     }
336     _first = false;
337     return frame;
338   }
339   if (frame_type <= SAME_LOCALS_1_STACK_ITEM_FRAME_END) {
340     // same_locals_1_stack_item_frame
341     if (_first) {
342       offset = frame_type - SAME_LOCALS_1_STACK_ITEM_FRAME_START;
343       // Can't share the locals array since that is updated by the verifier.
344       if (_prev_frame->locals_size() > 0) {
345         locals = NEW_RESOURCE_ARRAY_IN_THREAD(
346           THREAD, VerificationType, _prev_frame->locals_size());
347       }
348     } else {
349       offset = _prev_frame->offset() + frame_type - (SAME_LOCALS_1_STACK_ITEM_FRAME_START - 1);
350       locals = _prev_frame->locals();
351     }
352     VerificationType* stack = NEW_RESOURCE_ARRAY_IN_THREAD(
353       THREAD, VerificationType, 2);
354     u2 stack_size = 1;
355     stack[0] = parse_verification_type(nullptr, CHECK_VERIFY_(_verifier, nullptr));
356     if (stack[0].is_category2()) {
357       stack[1] = stack[0].to_category2_2nd();
358       stack_size = 2;
359     }
360     check_verification_type_array_size(
361       stack_size, _max_stack, CHECK_VERIFY_(_verifier, nullptr));
362     frame = new StackMapFrame(
363       offset, _prev_frame->flags(), _prev_frame->locals_size(), stack_size,
364       _max_locals, _max_stack, locals, stack,
365       _assert_unset_fields_buffer, _verifier);
366     if (_first && locals != nullptr) {
367       frame->copy_locals(_prev_frame);
368     }
369     _first = false;
370     return frame;
371   }
372 
373   u2 offset_delta = _stream->get_u2(CHECK_NULL);
374 
375   if (frame_type < EARLY_LARVAL) {
376     // reserved frame types
377     _stream->stackmap_format_error(
378       "reserved frame type", CHECK_VERIFY_(_verifier, nullptr));
379   }
380 
381   if (frame_type == SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
382     // same_locals_1_stack_item_frame_extended
383     if (_first) {
384       offset = offset_delta;
385       // Can't share the locals array since that is updated by the verifier.
386       if (_prev_frame->locals_size() > 0) {
387         locals = NEW_RESOURCE_ARRAY_IN_THREAD(
388           THREAD, VerificationType, _prev_frame->locals_size());
389       }
390     } else {
391       offset = _prev_frame->offset() + offset_delta + 1;
392       locals = _prev_frame->locals();
393     }
394     VerificationType* stack = NEW_RESOURCE_ARRAY_IN_THREAD(
395       THREAD, VerificationType, 2);
396     u2 stack_size = 1;
397     stack[0] = parse_verification_type(nullptr, CHECK_VERIFY_(_verifier, nullptr));
398     if (stack[0].is_category2()) {
399       stack[1] = stack[0].to_category2_2nd();
400       stack_size = 2;
401     }
402     check_verification_type_array_size(
403       stack_size, _max_stack, CHECK_VERIFY_(_verifier, nullptr));
404     frame = new StackMapFrame(
405       offset, _prev_frame->flags(), _prev_frame->locals_size(), stack_size,
406       _max_locals, _max_stack, locals, stack,
407       _assert_unset_fields_buffer, _verifier);
408     if (_first && locals != nullptr) {
409       frame->copy_locals(_prev_frame);
410     }
411     _first = false;
412     return frame;
413   }
414 
415   if (frame_type <= SAME_FRAME_EXTENDED) {
416     // chop_frame or same_frame_extended
417     locals = _prev_frame->locals();
418     int length = _prev_frame->locals_size();
419     int chops = SAME_FRAME_EXTENDED - frame_type;
420     int new_length = length;
421     u1 flags = _prev_frame->flags();
422     assert(chops == 0 || (frame_type >= CHOP_FRAME_START && frame_type <= CHOP_FRAME_END), "should be");
423     if (chops != 0) {
424       new_length = chop(locals, length, chops);
425       check_verification_type_array_size(
426         new_length, _max_locals, CHECK_VERIFY_(_verifier, nullptr));
427       // Recompute flags since uninitializedThis could have been chopped.
428       flags = 0;
429       for (int i=0; i<new_length; i++) {
430         if (locals[i].is_uninitialized_this()) {
431           flags |= FLAG_THIS_UNINIT;
432           break;
433         }
434       }
435     }
436     if (_first) {
437       offset = offset_delta;
438       // Can't share the locals array since that is updated by the verifier.
439       if (new_length > 0) {
440         locals = NEW_RESOURCE_ARRAY_IN_THREAD(
441           THREAD, VerificationType, new_length);
442       } else {
443         locals = nullptr;
444       }
445     } else {
446       offset = _prev_frame->offset() + offset_delta + 1;
447     }
448     frame = new StackMapFrame(
449       offset, flags, new_length, 0, _max_locals, _max_stack,
450       locals, nullptr,
451       _assert_unset_fields_buffer, _verifier);
452     if (_first && locals != nullptr) {
453       frame->copy_locals(_prev_frame);
454     }
455     _first = false;
456     return frame;
457   } else if (frame_type <= APPEND_FRAME_END) {
458     // append_frame
459     assert(frame_type >= APPEND_FRAME_START && frame_type <= APPEND_FRAME_END, "should be");
460     int appends = frame_type - APPEND_FRAME_START + 1;
461     int real_length = _prev_frame->locals_size();
462     int new_length = real_length + appends*2;
463     locals = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, VerificationType, new_length);
464     VerificationType* pre_locals = _prev_frame->locals();
465     for (int i = 0; i < _prev_frame->locals_size(); i++) {
466       locals[i] = pre_locals[i];
467     }
468     u1 flags = _prev_frame->flags();
469     for (int i = 0; i < appends; i++) {
470       locals[real_length] = parse_verification_type(&flags, CHECK_NULL);
471       if (locals[real_length].is_category2()) {
472         locals[real_length + 1] = locals[real_length].to_category2_2nd();
473         ++real_length;
474       }
475       ++real_length;
476     }
477     check_verification_type_array_size(
478       real_length, _max_locals, CHECK_VERIFY_(_verifier, nullptr));
479     if (_first) {
480       offset = offset_delta;
481     } else {
482       offset = _prev_frame->offset() + offset_delta + 1;
483     }
484     frame = new StackMapFrame(
485       offset, flags, real_length, 0, _max_locals,
486       _max_stack, locals, nullptr,
487       _assert_unset_fields_buffer, _verifier);
488     _first = false;
489     return frame;
490   }
491   if (frame_type == FULL_FRAME) {
492     // full_frame
493     u1 flags = 0;
494     u2 locals_size = _stream->get_u2(CHECK_NULL);
495     int real_locals_size = 0;
496     if (locals_size > 0) {
497       locals = NEW_RESOURCE_ARRAY_IN_THREAD(
498         THREAD, VerificationType, locals_size*2);
499     }
500     for (int i = 0; i < locals_size; i++) {
501       locals[real_locals_size] = parse_verification_type(&flags, CHECK_NULL);
502       if (locals[real_locals_size].is_category2()) {
503         locals[real_locals_size + 1] =
504           locals[real_locals_size].to_category2_2nd();
505         ++real_locals_size;
506       }
507       ++real_locals_size;
508     }
509     check_verification_type_array_size(
510       real_locals_size, _max_locals, CHECK_VERIFY_(_verifier, nullptr));
511     u2 stack_size = _stream->get_u2(CHECK_NULL);
512     int real_stack_size = 0;
513     VerificationType* stack = nullptr;
514     if (stack_size > 0) {
515       stack = NEW_RESOURCE_ARRAY_IN_THREAD(
516         THREAD, VerificationType, stack_size*2);
517     }
518     for (int i = 0; i < stack_size; i++) {
519       stack[real_stack_size] = parse_verification_type(nullptr, CHECK_NULL);
520       if (stack[real_stack_size].is_category2()) {
521         stack[real_stack_size + 1] = stack[real_stack_size].to_category2_2nd();
522         ++real_stack_size;
523       }
524       ++real_stack_size;
525     }
526     check_verification_type_array_size(
527       real_stack_size, _max_stack, CHECK_VERIFY_(_verifier, nullptr));
528     if (_first) {
529       offset = offset_delta;
530     } else {
531       offset = _prev_frame->offset() + offset_delta + 1;
532     }
533     frame = new StackMapFrame(
534       offset, flags, real_locals_size, real_stack_size,
535       _max_locals, _max_stack, locals, stack,
536       _assert_unset_fields_buffer, _verifier);
537     _first = false;
538     return frame;
539   }
540 
541   _stream->stackmap_format_error(
542     "reserved frame type", CHECK_VERIFY_(_prev_frame->verifier(), nullptr));
543   return nullptr;
544 }