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
|