From nobody Mon Sep 17 00:00:00 2001 From: Pavel Rebriy Date: Wed, 28 Jun 2006 17:03:46 +0400 Subject: [PATCH] Verifier: invokespecial instruction check fix - Corrects verification check for invokespecial instruction. - Changes verification for classes which is using subroutines. - Improves verifier error and trace massages. --- build/build.bat | 0 vm/vmcore/src/verifier/Verifier.cpp | 14 +++++--- vm/vmcore/src/verifier/ver_dataflow.cpp | 10 +++++- vm/vmcore/src/verifier/ver_real.h | 1 + vm/vmcore/src/verifier/ver_utils.cpp | 55 ++++++++++++++++++++++++------- 5 files changed, 60 insertions(+), 20 deletions(-) mode change 100644 => 100755 build/build.bat 13a8949ee566081355bae27a7344433ab8c28f7d diff --git a/build/build.bat b/build/build.bat old mode 100644 new mode 100755 diff --git a/vm/vmcore/src/verifier/Verifier.cpp b/vm/vmcore/src/verifier/Verifier.cpp index 947df0a..0e5ea9d 100644 --- a/vm/vmcore/src/verifier/Verifier.cpp +++ b/vm/vmcore/src/verifier/Verifier.cpp @@ -3679,9 +3679,11 @@ vf_opcode_invokespecial( vf_Code_t *code if( !strcmp( cp_parse.method.m_name, "" ) ) { // set uninitialized check vf_set_in_vector_type( code, 0, SM_UNINITIALIZED ); + vf_set_in_vector_check( code, 0, VF_CHECK_DIRECT_SUPER ); + } else { + // set method access check + vf_set_in_vector_check( code, 0, VF_CHECK_INVOKESPECIAL ); } - // set method access check - vf_set_in_vector_check( code, 0, VF_CHECK_ACCESS_METHOD ); vf_set_in_vector_check_index( code, 0, cp_index ); return VER_OK; } // vf_opcode_invokespecial @@ -5323,7 +5325,10 @@ #endif // VERIFY_METHOD result = vf_verify_method_bytecode( &context ); context.ClearContext(); } - if (result != VER_OK) { + if( result == VER_NoSupportJSR ) { + result = VER_OK; + } + if (result != VER_OK ) { goto labelEnd_verifyClass; } } @@ -5345,9 +5350,6 @@ labelEnd_verifyClass: vf_delete_pool( context.m_pool ); delete context.m_type; *message = context.m_error; - if( result == VER_NoSupportJSR ) { - result = VER_OK; - } #if _VERIFY_DEBUG if( result != VER_OK ) { VERIFY_DEBUG( "VerifyError: " << (context.m_error ? context.m_error : "NULL") ); diff --git a/vm/vmcore/src/verifier/ver_dataflow.cpp b/vm/vmcore/src/verifier/ver_dataflow.cpp index 98d9bff..645a5fc 100644 --- a/vm/vmcore/src/verifier/ver_dataflow.cpp +++ b/vm/vmcore/src/verifier/ver_dataflow.cpp @@ -505,6 +505,14 @@ vf_check_entry_refs( vf_MapEntry_t *sour return result; } break; + case VF_CHECK_DIRECT_SUPER: // check is target class is direct super class of source + is_error = ctex->m_type->CheckTypes( target->m_vtype, source->m_vtype, + 0, VF_CHECK_DIRECT_SUPER ); + break; + case VF_CHECK_INVOKESPECIAL: // check invokespecial object reference + is_error = ctex->m_type->CheckTypes( target->m_vtype, source->m_vtype, + 0, VF_CHECK_INVOKESPECIAL ); + break; default: DIE( "Verifier: vf_check_entry_refs: unknown check in switch" ); } @@ -822,7 +830,7 @@ vf_check_instruction_in_vector( vf_MapEn VERIFY_REPORT( ctex, "(class: " << class_get_name( ctex->m_class ) << ", method: " << method_get_name( ctex->m_method ) << method_get_descriptor( ctex->m_method ) - << ") Data flow analysis error" ); + << ") Data flow analysis error (uninitialized)" ); return result; } // check initialization class in constructor diff --git a/vm/vmcore/src/verifier/ver_real.h b/vm/vmcore/src/verifier/ver_real.h index 49d446f..605a5cd 100644 --- a/vm/vmcore/src/verifier/ver_real.h +++ b/vm/vmcore/src/verifier/ver_real.h @@ -233,6 +233,7 @@ typedef enum { VF_CHECK_ACCESS_FIELD, VF_CHECK_ACCESS_METHOD, VF_CHECK_DIRECT_SUPER, + VF_CHECK_INVOKESPECIAL, VF_CHECK_NUM } vf_CheckConstraint_t; diff --git a/vm/vmcore/src/verifier/ver_utils.cpp b/vm/vmcore/src/verifier/ver_utils.cpp index 62febb9..44e7813 100644 --- a/vm/vmcore/src/verifier/ver_utils.cpp +++ b/vm/vmcore/src/verifier/ver_utils.cpp @@ -477,6 +477,7 @@ vf_TypePool::CheckTypes( vf_ValidType_t } } return false; + case VF_CHECK_ACCESS_FIELD: // check field access // compare types assert( required->number == 1 ); @@ -490,6 +491,7 @@ vf_TypePool::CheckTypes( vf_ValidType_t index, VF_CHECK_ACCESS_FIELD ); } return false; + case VF_CHECK_ACCESS_METHOD: // check method access // compare types assert( required->number == 1 ); @@ -503,10 +505,29 @@ vf_TypePool::CheckTypes( vf_ValidType_t index, VF_CHECK_ACCESS_METHOD ); } return false; + case VF_CHECK_DIRECT_SUPER: + if( required->number == 1 && available->number == 1 ) { + if( required->string[0] != available->string[0] ) { + SetRestriction( required->string[0], available->string[0], + 0, VF_CHECK_DIRECT_SUPER ); + } + return false; + } + return true; + + case VF_CHECK_INVOKESPECIAL: + assert( required->number == 1 ); + for( index1 = 0; index1 < available->number; index1++ ) { + SetRestriction( required->string[0], available->string[index1], + index, VF_CHECK_INVOKESPECIAL ); + } + return false; default: DIE("Verifier: CompareTypes: unknown check type in switch"); + return true; } - return true; + // unreachable code + assert(0); } // vf_TypePool::CheckTypes /** @@ -968,7 +989,8 @@ vf_is_assign_valid( class_handler source static bool vf_is_valid( class_handler source, // checked class class_handler target, // required class - vf_CheckConstraint_t check) // checked class type + class_handler current, // current class + unsigned check) // checked class type { switch( check ) { @@ -986,18 +1008,25 @@ vf_is_valid( class_handler source, return class_is_same_class( class_get_super_class( source ), target ); case VF_CHECK_ACCESS_FIELD: // protected field access case VF_CHECK_ACCESS_METHOD: // protected method acceess - if( class_is_same_package( source, target ) - || vf_is_super_class( source, target ) ) + if( class_is_same_package( source, current ) + || vf_is_super_class( source, current ) ) { return true; } - break; + return false; + case VF_CHECK_INVOKESPECIAL: + if( vf_is_super_class( source, current ) + && vf_is_super_class( current, target ) ) + { + return true; + } + return false; default: - VERIFY_DEBUG( "vf_is_valid: invalid check type" ); - vf_error(); - break; + DIE( "Verifier: vf_is_valid: invalid check type" ); + return false; } - return false; + // unreachable code + assert(0); } // vf_is_valid /** @@ -1009,7 +1038,7 @@ vf_check_without_loading( vf_TypeConstra { switch( restriction->check_type ) { - case VF_CHECK_DIRECT_SUPER: + case VF_CHECK_SUPER: /** * Extension for class java/lang/Object doesn't check * because it's expected all references extend it. @@ -1106,7 +1135,7 @@ vf_check_constraint( vf_TypeConstraint_t } // check restriction - if( !vf_is_valid( source, target, (vf_CheckConstraint_t)restriction->check_type ) ) { + if( !vf_is_valid( source, target, ctex->m_class, restriction->check_type ) ) { // return error switch( restriction->check_type ) { @@ -1230,7 +1259,7 @@ vf_check_access_constraint( const char * } // check access constraint - if( !vf_is_valid( instance, ctex->m_class, check_type ) ) + if( !vf_is_valid( instance, NULL, ctex->m_class, check_type ) ) { // return error switch( check_type ) @@ -1388,7 +1417,7 @@ vf_force_check_constraint( vf_TypeConstr } // check restriction - if( !vf_is_valid( source, target, check ) ) + if( !vf_is_valid( source, target, ctex->m_class, check ) ) { switch( check ) { -- 1.3.3