harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gshiman...@apache.org
Subject svn commit: r485699 - in /harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier: Graph.cpp ver_dataflow.cpp ver_real.h
Date Mon, 11 Dec 2006 15:15:30 GMT
Author: gshimansky
Date: Mon Dec 11 07:15:29 2006
New Revision: 485699

URL: http://svn.apache.org/viewvc?view=rev&rev=485699
Log:
Applied HARMONY-2394 [drlvm][verifier] VM throws VerifyError when uninitialized object is
used in aload/astore instructions

Tests passed on ubuntu6 x86, windows 2003 server and suse9 x86_64


Modified:
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier/Graph.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier/ver_dataflow.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier/ver_real.h

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier/Graph.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier/Graph.cpp?view=diff&rev=485699&r1=485698&r2=485699
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier/Graph.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier/Graph.cpp Mon Dec 11 07:15:29 2006
@@ -375,6 +375,30 @@
 } // vf_Graph::CleanNodesMark
 
 /**
+ * Sets local variable reference initialization flag for node.
+ */
+void
+vf_Graph::SetNodeInitFlag( unsigned num,    // graph node number
+                           bool flag)       // node flag
+{
+    // check node number is in range.
+    assert( num < m_nodenum );
+    GetNode( num )->m_initialized = flag;
+    return;
+} // vf_Graph::SetNodeInitFlag
+
+/**
+ * Gets local variable reference initialization flag for node.
+ */
+bool
+vf_Graph::GetNodeInitFlag( unsigned num )   // graph node number
+{
+    // check node number is in range.
+    assert( num < m_nodenum );
+    return GetNode( num )->m_initialized;
+} // vf_Graph::GetNodeInitFlag
+
+/**
  * Function receives IN data flow vector of node.
  */
 vf_MapVector_t *
@@ -979,47 +1003,25 @@
 Verifier_Result
 vf_create_graph( vf_Context_t *ctex )   // verifier context
 {
-    unsigned len,
-             last,
-             node,
-             index,
-             count,
-             codeNum,
-             nodeCount,
-             handlcount,
-             *code2node;
-    vf_Code_t *code,
-               *codeInstr;
-    vf_Graph_t *vGraph;
-    Verifier_Result result = VER_OK;
-
-    /** 
-     * Get context
-     */
-    unsigned char* code_end = method_get_bytecode( ctex->m_method )
-                 + method_get_code_length( ctex->m_method );
-    handlcount = method_get_exc_handler_number( ctex->m_method );
-    code = ctex->m_code;
-    codeNum = ctex->m_codeNum;
-
     /**
      * Create graph
      */
     ctex->m_graph = new vf_Graph( ctex->m_nodeNum, ctex->m_edgeNum, ctex->m_pool
);
-    vGraph = ctex->m_graph;
 
     /**
      * Create decoding array: code to node
      */
-    code2node = (unsigned*)vf_alloc_pool_memory( ctex->m_pool, 
-                            codeNum * sizeof(unsigned) );
+    unsigned* code2node = (unsigned*)vf_alloc_pool_memory( ctex->m_pool,
+                            ctex->m_codeNum * sizeof(unsigned) );
     /** 
      * Create start-entry and handler nodes
      */
-    vGraph->NewNode( 0, 0, 0 );
-    for( index = 1; index < handlcount + 1; index++ ) {
-        vGraph->NewNode( index, index, 0 );
-        vGraph->SetNodeStackModifier( index, 1 ); 
+    unsigned index;
+    unsigned short handlcount = method_get_exc_handler_number( ctex->m_method );
+    ctex->m_graph->NewNode( 0, 0, 0 );
+    for( index = 1; index < (unsigned)handlcount + 1; index++ ) {
+        ctex->m_graph->NewNode( index, index, 0 );
+        ctex->m_graph->SetNodeStackModifier( index, 1 );
     }
 
     /**
@@ -1028,38 +1030,43 @@
      * Skip the first instruction, because we create the first node
      * at his end instruction.
      */
+    unsigned len;
+    unsigned last;
+    unsigned nodeCount;
     for( last = nodeCount = 1 + handlcount, index = last + 1;
-         index < codeNum - 1;
+         index < ctex->m_codeNum - 1;
          index++ ) 
     {
-        if( vf_is_begin_basic_block( &code[index] ) ) {
+        if( vf_is_begin_basic_block( &ctex->m_code[index] ) ) {
             // set graph nodes
-            len = code[index].m_addr - code[last].m_addr;
-            vGraph->NewNode( last, index - 1, len );
-            vGraph->SetNodeStackModifier( nodeCount, 
-                        vf_get_node_stack_deep( &code[last], &code[index - 1] ) );
+            len = ctex->m_code[index].m_addr - ctex->m_code[last].m_addr;
+            ctex->m_graph->NewNode( last, index - 1, len );
+            ctex->m_graph->SetNodeStackModifier( nodeCount,
+                        vf_get_node_stack_deep( &ctex->m_code[last], &ctex->m_code[index
- 1] ) );
             code2node[last] = nodeCount++;
             last = index;
         }
     }
     // set last node with code segment
-    len = code_end - code[last].m_addr;
-    vGraph->NewNode( last, index - 1, len );
-    vGraph->SetNodeStackModifier( nodeCount, 
-        vf_get_node_stack_deep( &code[last], &code[index - 1] ) );
+    unsigned char* code_end = method_get_bytecode( ctex->m_method )
+                                 + method_get_code_length( ctex->m_method );
+    len = code_end - ctex->m_code[last].m_addr;
+    ctex->m_graph->NewNode( last, index - 1, len );
+    ctex->m_graph->SetNodeStackModifier( nodeCount,
+        vf_get_node_stack_deep( &ctex->m_code[last], &ctex->m_code[index -
1] ) );
     code2node[last] = nodeCount++;
     // set exit node
-    vGraph->NewNode( codeNum - 1, 0, 0 );
-    code2node[codeNum - 1] = nodeCount++;
+    ctex->m_graph->NewNode( ctex->m_codeNum - 1, 0, 0 );
+    code2node[ctex->m_codeNum - 1] = nodeCount++;
     assert( ctex->m_nodeNum == nodeCount );
 
     /**
      * Create edges
      * First edge from start-entry node to first code node
      */
-    vGraph->NewEdge( 0, handlcount + 1 );
+    ctex->m_graph->NewEdge( 0, handlcount + 1 );
     for( index = 1; index < nodeCount - 1; index++ ) {
-        codeInstr = &code[ vGraph->GetNodeLastInstr( index ) ];
+        vf_Code_t* codeInstr = &ctex->m_code[ ctex->m_graph->GetNodeLastInstr(
index ) ];
         // check correct branching
         if( codeInstr->m_addr && *codeInstr->m_addr == OPCODE_WIDE ) {
             // node ends in wide instruction
@@ -1067,20 +1074,24 @@
                 << ", method: " << method_get_name( ctex->m_method )
                 << method_get_descriptor( ctex->m_method )
                 << ") Illegal target of jump or branch" );
-            result = VER_ErrorBranch;
-            goto labelEnd_createGraph; 
+            return VER_ErrorBranch;
         }
         // set control flow edges
         if( codeInstr->m_offcount ) {
-            for( count = 0; count < codeInstr->m_offcount; count++ ) {
+            for( unsigned count = 0; count < codeInstr->m_offcount; count++ ) {
 #if _VERIFY_DEBUG
                 if( code2node[ codeInstr->m_off[count] ] == 0 ) {
                     VERIFY_DEBUG( "vf_create_graph: error graph construction" );
                     vf_error();
                 }
 #endif // _VERIFY_DEBUG
-                node = code2node[ codeInstr->m_off[count] ];
-                vGraph->NewEdge( index, node );
+                unsigned node = code2node[ codeInstr->m_off[count] ];
+                ctex->m_graph->NewEdge( index, node );
+                if( node < index ) {
+                    // node has backward branch,
+                    // thus the reference in local variables have to be initialized
+                    ctex->m_graph->SetNodeInitFlag( node, true );
+                }
             }
         } else {
             if( index + 1 == nodeCount - 1 ) {
@@ -1089,17 +1100,20 @@
                     << ", method: " << method_get_name( ctex->m_method )
                     << method_get_descriptor( ctex->m_method )
                     << ") Falling off the end of the code" );
-                result = VER_ErrorBranch;
-                goto labelEnd_createGraph; 
+                return VER_ErrorBranch;
             }
-            vGraph->NewEdge( index, index + 1 );
+            ctex->m_graph->NewEdge( index, index + 1 );
         }
-        // set exception handler edges
         if( codeInstr->m_handler != NULL ) {
-            for( count = 0; count < handlcount; count++ ) {
+            // node is protected by exception handler,
+            // thus the reference in local variables have to be initialized
+            ctex->m_graph->SetNodeInitFlag( index, true );
+
+            // set exception handler edges
+            for( unsigned count = 0; count < handlcount; count++ ) {
                 if( codeInstr->m_handler[count] ) {
                     // set edge to exception handler entry
-                    vGraph->NewEdge( index, count + 1 );
+                    ctex->m_graph->NewEdge( index, count + 1 );
                 }
             }
         }
@@ -1107,16 +1121,14 @@
 
 #if _VERIFY_DEBUG
     if( ctex->m_dump.m_graph ) {
-        vGraph->DumpGraph( ctex );
+        ctex->m_graph->DumpGraph( ctex );
     }
     if( ctex->m_dump.m_dot_graph ) {
-        vGraph->DumpDotGraph( ctex );
+        ctex->m_graph->DumpDotGraph( ctex );
     }
 #endif // _VERIFY_DEBUG
 
-labelEnd_createGraph:
-
-    return result;
+    return VER_OK;
 } // vf_create_graph
 
 /************************************************************

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier/ver_dataflow.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier/ver_dataflow.cpp?view=diff&rev=485699&r1=485698&r2=485699
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier/ver_dataflow.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier/ver_dataflow.cpp Mon Dec 11 07:15:29
2006
@@ -437,6 +437,7 @@
 static inline Verifier_Result
 vf_check_entry_refs( vf_MapEntry_t *source,    // stack map entry
                      vf_MapEntry_t *target,    // required map entry
+                     bool local_init,          // initialization flag of locals
                      vf_Context_t *ctex)       // verifier context
 {
     // check entries type
@@ -458,12 +459,15 @@
     }
     // check initialization
     if( source->m_type == SM_UNINITIALIZED && target->m_type != SM_UNINITIALIZED)
{
-        if( source->m_new == 0                                  // SM_UNINITIALIZED_THIS
-            && (target->m_ctype == VF_CHECK_UNINITIALIZED_THIS  // astore/aload
-                || target->m_ctype == VF_CHECK_ACCESS_FIELD ) ) // putfield/getfield
+        if( (source->m_new == 0 && target->m_ctype == VF_CHECK_ACCESS_FIELD)
+            || (local_init == false && target->m_ctype == VF_CHECK_UNINITIALIZED_THIS)
)
         {
-            // uninitialized this could be used in getfield/putfield
-            // and aload/astore instructions
+            // 1. In initialization method instance fields of this
+            //    that are declared in the current class may be assigned
+            //    before calling any instance initialization method
+            // 2. Uninitialized class instance can be stored in
+            //    a local variable if no backward branch is taken or
+            //    the code isn't protected by exception handler.
         } else {
             VERIFY_REPORT( ctex, "(class: " << class_get_name( ctex->m_class ) 
                 << ", method: " << method_get_name( ctex->m_method )
@@ -535,6 +539,7 @@
 static inline Verifier_Result
 vf_check_entry_types( vf_MapEntry_t *entry1,    // stack map entry
                       vf_MapEntry_t *entry2,    // required map entry
+                      bool local_init,          // initialization flag of locals
                       bool *need_copy,          // pointer to copy flag
                       vf_Context_t *ctex)       // verifier context
 {
@@ -543,7 +548,8 @@
     case SM_REF:
         // check reference entries
         {
-            Verifier_Result result = vf_check_entry_refs( entry1, entry2, ctex );
+            Verifier_Result result = 
+                vf_check_entry_refs( entry1, entry2, local_init, ctex );
             *need_copy = true;
             return result;
         }
@@ -759,6 +765,7 @@
                                 vf_MapEntry_t *buf,         // buf storage vector
                                 vf_MapEntry_t *invector,    // code instruction IN vector
                                 unsigned len,               // IN vector length
+                                bool local_init,            // initialization flag of locals
                                 bool *need_init,            // init uninitialized entry
                                 vf_Context_t *ctex)         // verifier context
 {
@@ -795,7 +802,7 @@
                 newvector->m_ctype = VF_CHECK_NONE;
             }
             // check entry types
-            result = vf_check_entry_refs( entry, newvector, ctex );
+            result = vf_check_entry_refs( entry, newvector, local_init, ctex );
             if( result != VER_OK ) {
                 VERIFY_REPORT( ctex, "(class: " << class_get_name( ctex->m_class
)
                     << ", method: " << method_get_name( ctex->m_method )
@@ -806,7 +813,7 @@
             break;
         case SM_REF:
             // check entry references
-            result = vf_check_entry_refs( entry, vector, ctex );
+            result = vf_check_entry_refs( entry, vector, local_init, ctex );
             if( result != VER_OK ) {
                 if( !ctex->m_error ) {
                     VERIFY_REPORT( ctex, "(class: " << class_get_name( ctex->m_class
) 
@@ -828,7 +835,7 @@
                     << ") Double initialization of object reference" );
                 return VER_ErrorDataFlow;
             }
-            result = vf_check_entry_refs( entry, vector, ctex );
+            result = vf_check_entry_refs( entry, vector, local_init, ctex );
             if( result != VER_OK ) {
                 VERIFY_REPORT( ctex, "(class: " << class_get_name( ctex->m_class
) 
                     << ", method: " << method_get_name( ctex->m_method )
@@ -850,7 +857,7 @@
             break;
         default:
             // check entry types
-            result = vf_check_entry_types( entry, vector, &copy, ctex );
+            result = vf_check_entry_types( entry, vector, local_init, &copy, ctex );
             if( result != VER_OK ) {
                 VERIFY_REPORT( ctex, "(class: " << class_get_name( ctex->m_class
) 
                     << ", method: " << method_get_name( ctex->m_method )
@@ -873,7 +880,8 @@
  * Function receives code instruction OUT data flow vector.
  */
 static Verifier_Result
-vf_get_instruction_out_vector( vf_Code_t *instr,            // code instruction
+vf_get_instruction_out_vector( unsigned node_num,           // graph node
+                               vf_Code_t *instr,            // code instruction
                                vf_MapVector_t *invector,    // incoming data flow vector
                                vf_MapEntry_t *buf,          // buf storage vector
                                vf_Context_t *ctex)          // verifier context
@@ -889,7 +897,8 @@
     vf_MapEntry_t *locals = invector->m_local;
     // check instruction in vector
     Verifier_Result result = vf_check_instruction_in_vector( stack, locals, buf,
-        instr->m_invector, instr->m_inlen, &need_init, ctex );
+        instr->m_invector, instr->m_inlen, ctex->m_graph->GetNodeInitFlag(node_num),
+        &need_init, ctex );
     if( result != VER_OK ) {
         return result;
     }
@@ -1020,7 +1029,7 @@
             {
                 continue;
             } else {
-                result = vf_get_instruction_out_vector( &instr[index], invector, 
+                result = vf_get_instruction_out_vector( node_num, &instr[index], invector,

                     buf, ctex );
             }
             if( result != VER_OK ) {
@@ -1165,7 +1174,7 @@
         // check stack type
         vf_MapEntry_t *entry = invector->m_stack + index;
         // check entry types
-        Verifier_Result result = vf_check_entry_types( entry, vector, &copy, ctex );
+        Verifier_Result result = vf_check_entry_types( entry, vector, true, &copy, ctex
);
         if( result != VER_OK ) {
             VERIFY_REPORT( ctex, "(class: " << class_get_name( ctex->m_class ) 
                 << ", method: " << method_get_name( ctex->m_method )

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier/ver_real.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier/ver_real.h?view=diff&rev=485699&r1=485698&r2=485699
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier/ver_real.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier/ver_real.h Mon Dec 11 07:15:29 2006
@@ -412,18 +412,19 @@
  */
 struct vf_Node_s
 {
-    vf_MapVector_t m_invector;      ///< stack map IN node vector
-    vf_MapVector_t m_outvector;     ///< stack map OUT node vector
-    unsigned m_start;               ///< beginning of the first instruction of the BB
-    unsigned m_end;                 ///< beginning of the last instruction of the BB.
-    unsigned m_inedge;              ///< the first of incoming node edges
-    unsigned m_outedge;             ///< the first of outcoming node edges
-    unsigned m_len;                 ///< length of the basic block
-    unsigned m_innum;               ///< number of incoming edges
-    unsigned m_outnum;              ///< number of outcoming edges
-    unsigned m_nodecount;           ///< node count in enumeration
-    int m_stack;                    ///< stack deep of node
-    int m_mark;                     ///< node mark
+    vf_MapVector_t m_invector;          ///< stack map IN node vector
+    vf_MapVector_t m_outvector;         ///< stack map OUT node vector
+    unsigned m_start;                   ///< beginning of the first instruction of the
BB
+    unsigned m_end;                     ///< beginning of the last instruction of the
BB.
+    unsigned m_inedge;                  ///< the first of incoming node edges
+    unsigned m_outedge;                 ///< the first of outcoming node edges
+    unsigned m_len;                     ///< length of the basic block
+    unsigned m_innum;                   ///< number of incoming edges
+    unsigned m_outnum;                  ///< number of outcoming edges
+    unsigned m_nodecount;               ///< node count in enumeration
+    int m_stack;                        ///< stack deep of node
+    int m_mark;                         ///< node mark
+    bool m_initialized;                 ///< reference in local variable should be initialized
 };
 
 /**
@@ -625,6 +626,21 @@
      * Function removes node mark.
      */
     void CleanNodesMark();
+
+    /**
+     * Sets local variable reference initialization flag for node.
+     * @param node_num - graph node number
+     * @param flag     - node flag
+     */
+    void SetNodeInitFlag( unsigned node_num, bool flag );
+
+    /**
+     * Gets local variable reference initialization flag for node.
+     * @param node_num - graph node number
+     * @return Returns <code>true</code> if local variable reference have
+     *  to be initialized else returns <code>false</code>.
+     */
+    bool GetNodeInitFlag( unsigned node_num );
 
     /**
      * Function creates <i>IN</i> data flow vector of node.



Mime
View raw message