src/share/vm/classfile/verifier.cpp

Print this page


   1 /*
   2  * Copyright (c) 1998, 2011, 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  *


1351   RawBytecodeStream bcs(m);
1352 
1353   while (!bcs.is_last_bytecode()) {
1354     if (bcs.raw_next() != Bytecodes::_illegal) {
1355       int bci = bcs.bci();
1356       if (bcs.raw_code() == Bytecodes::_new) {
1357         code_data[bci] = NEW_OFFSET;
1358       } else {
1359         code_data[bci] = BYTECODE_OFFSET;
1360       }
1361     } else {
1362       verify_error(bcs.bci(), "Bad instruction");
1363       return NULL;
1364     }
1365   }
1366 
1367   return code_data;
1368 }
1369 
1370 void ClassVerifier::verify_exception_handler_table(u4 code_length, char* code_data, int& min, int& max, TRAPS) {
1371   typeArrayHandle exhandlers (THREAD, _method->exception_table());

1372   constantPoolHandle cp (THREAD, _method->constants());
1373 
1374   if (exhandlers() != NULL) {
1375     for(int i = 0; i < exhandlers->length();) {
1376       u2 start_pc = exhandlers->int_at(i++);
1377       u2 end_pc = exhandlers->int_at(i++);
1378       u2 handler_pc = exhandlers->int_at(i++);

1379       if (start_pc >= code_length || code_data[start_pc] == 0) {
1380         class_format_error("Illegal exception table start_pc %d", start_pc);
1381         return;
1382       }
1383       if (end_pc != code_length) {   // special case: end_pc == code_length
1384         if (end_pc > code_length || code_data[end_pc] == 0) {
1385           class_format_error("Illegal exception table end_pc %d", end_pc);
1386           return;
1387         }
1388       }
1389       if (handler_pc >= code_length || code_data[handler_pc] == 0) {
1390         class_format_error("Illegal exception table handler_pc %d", handler_pc);
1391         return;
1392       }
1393       int catch_type_index = exhandlers->int_at(i++);
1394       if (catch_type_index != 0) {
1395         VerificationType catch_type = cp_index_to_type(
1396           catch_type_index, cp, CHECK_VERIFY(this));
1397         VerificationType throwable =
1398           VerificationType::reference_type(vmSymbols::java_lang_Throwable());
1399         bool is_subclass = throwable.is_assignable_from(
1400           catch_type, this, CHECK_VERIFY(this));
1401         if (!is_subclass) {
1402           // 4286534: should throw VerifyError according to recent spec change
1403           verify_error(
1404             "Catch type is not a subclass of Throwable in handler %d",
1405             handler_pc);
1406           return;
1407         }
1408       }
1409       if (start_pc < min) min = start_pc;
1410       if (end_pc > max) max = end_pc;
1411     }
1412   }
1413 }
1414 
1415 void ClassVerifier::verify_local_variable_table(u4 code_length, char* code_data, TRAPS) {
1416   int localvariable_table_length = _method()->localvariable_table_length();
1417   if (localvariable_table_length > 0) {
1418     LocalVariableTableElement* table = _method()->localvariable_table_start();
1419     for (int i = 0; i < localvariable_table_length; i++) {
1420       u2 start_bci = table[i].start_bci;
1421       u2 length = table[i].length;
1422 
1423       if (start_bci >= code_length || code_data[start_bci] == 0) {
1424         class_format_error(
1425           "Illegal local variable table start_pc %d", start_bci);
1426         return;
1427       }
1428       u4 end_bci = (u4)(start_bci + length);
1429       if (end_bci != code_length) {
1430         if (end_bci >= code_length || code_data[end_bci] == 0) {
1431           class_format_error( "Illegal local variable table length %d", length);
1432           return;


1457         // report type error
1458         verify_error(bci, "Instruction type does not match stack map");
1459         return 0;
1460       }
1461       stackmap_index++;
1462     } else if (this_offset < bci) {
1463       // current_offset should have met this_offset.
1464       class_format_error("Bad stack map offset %d", this_offset);
1465       return 0;
1466     }
1467   } else if (no_control_flow) {
1468     verify_error(bci, "Expecting a stack map frame");
1469     return 0;
1470   }
1471   return stackmap_index;
1472 }
1473 
1474 void ClassVerifier::verify_exception_handler_targets(u2 bci, bool this_uninit, StackMapFrame* current_frame,
1475                                                      StackMapTable* stackmap_table, TRAPS) {
1476   constantPoolHandle cp (THREAD, _method->constants());
1477   typeArrayHandle exhandlers (THREAD, _method->exception_table());
1478   if (exhandlers() != NULL) {
1479     for(int i = 0; i < exhandlers->length();) {
1480       u2 start_pc = exhandlers->int_at(i++);
1481       u2 end_pc = exhandlers->int_at(i++);
1482       u2 handler_pc = exhandlers->int_at(i++);
1483       int catch_type_index = exhandlers->int_at(i++);


1484       if(bci >= start_pc && bci < end_pc) {
1485         u1 flags = current_frame->flags();
1486         if (this_uninit) {  flags |= FLAG_THIS_UNINIT; }
1487         StackMapFrame* new_frame = current_frame->frame_in_exception_handler(flags);
1488         if (catch_type_index != 0) {
1489           // We know that this index refers to a subclass of Throwable
1490           VerificationType catch_type = cp_index_to_type(
1491             catch_type_index, cp, CHECK_VERIFY(this));
1492           new_frame->push_stack(catch_type, CHECK_VERIFY(this));
1493         } else {
1494           VerificationType throwable =
1495             VerificationType::reference_type(vmSymbols::java_lang_Throwable());
1496           new_frame->push_stack(throwable, CHECK_VERIFY(this));
1497         }
1498         bool match = stackmap_table->match_stackmap(
1499           new_frame, handler_pc, true, false, CHECK_VERIFY(this));
1500         if (!match) {
1501           verify_error(bci,
1502             "Stack map does not match the one at exception handler %d",
1503             handler_pc);
1504           return;
1505         }
1506       }
1507     }
1508   }
1509 }
1510 
1511 void ClassVerifier::verify_cp_index(constantPoolHandle cp, int index, TRAPS) {
1512   int nconstants = cp->length();
1513   if ((index <= 0) || (index >= nconstants)) {
1514     verify_error("Illegal constant pool index %d in class %s",
1515       index, instanceKlass::cast(cp->pool_holder())->external_name());
1516     return;
1517   }
1518 }
1519 
1520 void ClassVerifier::verify_cp_type(
1521     int index, constantPoolHandle cp, unsigned int types, TRAPS) {
1522 
1523   // In some situations, bytecode rewriting may occur while we're verifying.
1524   // In this case, a constant pool cache exists and some indices refer to that
1525   // instead.  Be sure we don't pick up such indices by accident.
1526   // We must check was_recursively_verified() before we get here.
1527   guarantee(cp->cache() == NULL, "not rewritten yet");
1528 


   1 /*
   2  * Copyright (c) 1998, 2012, 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  *


1351   RawBytecodeStream bcs(m);
1352 
1353   while (!bcs.is_last_bytecode()) {
1354     if (bcs.raw_next() != Bytecodes::_illegal) {
1355       int bci = bcs.bci();
1356       if (bcs.raw_code() == Bytecodes::_new) {
1357         code_data[bci] = NEW_OFFSET;
1358       } else {
1359         code_data[bci] = BYTECODE_OFFSET;
1360       }
1361     } else {
1362       verify_error(bcs.bci(), "Bad instruction");
1363       return NULL;
1364     }
1365   }
1366 
1367   return code_data;
1368 }
1369 
1370 void ClassVerifier::verify_exception_handler_table(u4 code_length, char* code_data, int& min, int& max, TRAPS) {
1371   ExceptionTable exhandlers(_method());
1372   int exlength = exhandlers.length();
1373   constantPoolHandle cp (THREAD, _method->constants());
1374 
1375   for(int i = 0; i < exlength; i++) {
1376     //reacquire the table in case a GC happened
1377     ExceptionTable exhandlers(_method());
1378     u2 start_pc = exhandlers.start_pc(i);
1379     u2 end_pc = exhandlers.end_pc(i);
1380     u2 handler_pc = exhandlers.handler_pc(i);
1381     if (start_pc >= code_length || code_data[start_pc] == 0) {
1382       class_format_error("Illegal exception table start_pc %d", start_pc);
1383       return;
1384     }
1385     if (end_pc != code_length) {   // special case: end_pc == code_length
1386       if (end_pc > code_length || code_data[end_pc] == 0) {
1387         class_format_error("Illegal exception table end_pc %d", end_pc);
1388         return;
1389       }
1390     }
1391     if (handler_pc >= code_length || code_data[handler_pc] == 0) {
1392       class_format_error("Illegal exception table handler_pc %d", handler_pc);
1393       return;
1394     }
1395     int catch_type_index = exhandlers.catch_type_index(i);
1396     if (catch_type_index != 0) {
1397       VerificationType catch_type = cp_index_to_type(
1398         catch_type_index, cp, CHECK_VERIFY(this));
1399       VerificationType throwable =
1400         VerificationType::reference_type(vmSymbols::java_lang_Throwable());
1401       bool is_subclass = throwable.is_assignable_from(
1402         catch_type, this, CHECK_VERIFY(this));
1403       if (!is_subclass) {
1404         // 4286534: should throw VerifyError according to recent spec change
1405         verify_error(
1406           "Catch type is not a subclass of Throwable in handler %d",
1407           handler_pc);
1408         return;
1409       }
1410     }
1411     if (start_pc < min) min = start_pc;
1412     if (end_pc > max) max = end_pc;
1413   }

1414 }
1415 
1416 void ClassVerifier::verify_local_variable_table(u4 code_length, char* code_data, TRAPS) {
1417   int localvariable_table_length = _method()->localvariable_table_length();
1418   if (localvariable_table_length > 0) {
1419     LocalVariableTableElement* table = _method()->localvariable_table_start();
1420     for (int i = 0; i < localvariable_table_length; i++) {
1421       u2 start_bci = table[i].start_bci;
1422       u2 length = table[i].length;
1423 
1424       if (start_bci >= code_length || code_data[start_bci] == 0) {
1425         class_format_error(
1426           "Illegal local variable table start_pc %d", start_bci);
1427         return;
1428       }
1429       u4 end_bci = (u4)(start_bci + length);
1430       if (end_bci != code_length) {
1431         if (end_bci >= code_length || code_data[end_bci] == 0) {
1432           class_format_error( "Illegal local variable table length %d", length);
1433           return;


1458         // report type error
1459         verify_error(bci, "Instruction type does not match stack map");
1460         return 0;
1461       }
1462       stackmap_index++;
1463     } else if (this_offset < bci) {
1464       // current_offset should have met this_offset.
1465       class_format_error("Bad stack map offset %d", this_offset);
1466       return 0;
1467     }
1468   } else if (no_control_flow) {
1469     verify_error(bci, "Expecting a stack map frame");
1470     return 0;
1471   }
1472   return stackmap_index;
1473 }
1474 
1475 void ClassVerifier::verify_exception_handler_targets(u2 bci, bool this_uninit, StackMapFrame* current_frame,
1476                                                      StackMapTable* stackmap_table, TRAPS) {
1477   constantPoolHandle cp (THREAD, _method->constants());
1478   ExceptionTable exhandlers(_method());
1479   int exlength = exhandlers.length();
1480   for(int i = 0; i < exlength; i++) {
1481     //reacquire the table in case a GC happened
1482     ExceptionTable exhandlers(_method());
1483     u2 start_pc = exhandlers.start_pc(i);
1484     u2 end_pc = exhandlers.end_pc(i);
1485     u2 handler_pc = exhandlers.handler_pc(i);
1486     int catch_type_index = exhandlers.catch_type_index(i);
1487     if(bci >= start_pc && bci < end_pc) {
1488       u1 flags = current_frame->flags();
1489       if (this_uninit) {  flags |= FLAG_THIS_UNINIT; }
1490       StackMapFrame* new_frame = current_frame->frame_in_exception_handler(flags);
1491       if (catch_type_index != 0) {
1492         // We know that this index refers to a subclass of Throwable
1493         VerificationType catch_type = cp_index_to_type(
1494           catch_type_index, cp, CHECK_VERIFY(this));
1495         new_frame->push_stack(catch_type, CHECK_VERIFY(this));
1496       } else {
1497         VerificationType throwable =
1498           VerificationType::reference_type(vmSymbols::java_lang_Throwable());
1499         new_frame->push_stack(throwable, CHECK_VERIFY(this));
1500       }
1501       bool match = stackmap_table->match_stackmap(
1502         new_frame, handler_pc, true, false, CHECK_VERIFY(this));
1503       if (!match) {
1504         verify_error(bci,
1505           "Stack map does not match the one at exception handler %d",
1506           handler_pc);
1507         return;
1508       }
1509     }
1510   }

1511 }
1512 
1513 void ClassVerifier::verify_cp_index(constantPoolHandle cp, int index, TRAPS) {
1514   int nconstants = cp->length();
1515   if ((index <= 0) || (index >= nconstants)) {
1516     verify_error("Illegal constant pool index %d in class %s",
1517       index, instanceKlass::cast(cp->pool_holder())->external_name());
1518     return;
1519   }
1520 }
1521 
1522 void ClassVerifier::verify_cp_type(
1523     int index, constantPoolHandle cp, unsigned int types, TRAPS) {
1524 
1525   // In some situations, bytecode rewriting may occur while we're verifying.
1526   // In this case, a constant pool cache exists and some indices refer to that
1527   // instead.  Be sure we don't pick up such indices by accident.
1528   // We must check was_recursively_verified() before we get here.
1529   guarantee(cp->cache() == NULL, "not rewritten yet");
1530