src/java.base/share/native/libverify/check_code.c
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File bug_8129897 Sdiff src/java.base/share/native/libverify

src/java.base/share/native/libverify/check_code.c

Print this page


   1 /*
   2  * Copyright (c) 1994, 2014, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 142 
 143 int verify_verbose = 0;
 144 static struct context_type *GlobalContext;
 145 #endif
 146 
 147 enum {
 148     ITEM_Bogus,
 149     ITEM_Void,                  /* only as a function return value */
 150     ITEM_Integer,
 151     ITEM_Float,
 152     ITEM_Double,
 153     ITEM_Double_2,              /* 2nd word of double in register */
 154     ITEM_Long,
 155     ITEM_Long_2,                /* 2nd word of long in register */
 156     ITEM_Array,
 157     ITEM_Object,                /* Extra info field gives name. */
 158     ITEM_NewObject,             /* Like object, but uninitialized. */
 159     ITEM_InitObject,            /* "this" is init method, before call
 160                                     to super() */
 161     ITEM_ReturnAddress,         /* Extra info gives instr # of start pc */
 162     /* The following three are only used within array types.
 163      * Normally, we use ITEM_Integer, instead. */
 164     ITEM_Byte,
 165     ITEM_Short,
 166     ITEM_Char

 167 };
 168 
 169 
 170 #define UNKNOWN_STACK_SIZE -1
 171 #define UNKNOWN_REGISTER_COUNT -1
 172 #define UNKNOWN_RET_INSTRUCTION -1
 173 
 174 #undef MAX
 175 #undef MIN
 176 #define MAX(a, b) ((a) > (b) ? (a) : (b))
 177 #define MIN(a, b) ((a) < (b) ? (a) : (b))
 178 
 179 #define BITS_PER_INT   (CHAR_BIT * sizeof(int)/sizeof(char))
 180 #define SET_BIT(flags, i)  (flags[(i)/BITS_PER_INT] |= \
 181                                        ((unsigned)1 << ((i) % BITS_PER_INT)))
 182 #define IS_BIT_SET(flags, i) (flags[(i)/BITS_PER_INT] & \
 183                                        ((unsigned)1 << ((i) % BITS_PER_INT)))
 184 
 185 typedef unsigned int fullinfo_type;
 186 typedef unsigned int *bitvector;


1429                 CCerror(context, "Illegal dimension argument");
1430             break;
1431         default:
1432             this_idata->operand.fi = target;
1433         }
1434         break;
1435     }
1436 
1437     case JVM_OPC_newarray: {
1438         /* Cache the result of the JVM_OPC_newarray into the operand slot */
1439         fullinfo_type full_info;
1440         switch (code[offset + 1]) {
1441             case JVM_T_INT:
1442                 full_info = MAKE_FULLINFO(ITEM_Integer, 1, 0); break;
1443             case JVM_T_LONG:
1444                 full_info = MAKE_FULLINFO(ITEM_Long, 1, 0); break;
1445             case JVM_T_FLOAT:
1446                 full_info = MAKE_FULLINFO(ITEM_Float, 1, 0); break;
1447             case JVM_T_DOUBLE:
1448                 full_info = MAKE_FULLINFO(ITEM_Double, 1, 0); break;
1449             case JVM_T_BYTE: case JVM_T_BOOLEAN:


1450                 full_info = MAKE_FULLINFO(ITEM_Byte, 1, 0); break;
1451             case JVM_T_CHAR:
1452                 full_info = MAKE_FULLINFO(ITEM_Char, 1, 0); break;
1453             case JVM_T_SHORT:
1454                 full_info = MAKE_FULLINFO(ITEM_Short, 1, 0); break;
1455             default:
1456                 full_info = 0;          /* Keep lint happy */
1457                 CCerror(context, "Bad type passed to newarray");
1458         }
1459         this_idata->operand.fi = full_info;
1460         break;
1461     }
1462 
1463     /* Fudge iload_x, aload_x, etc to look like their generic cousin. */
1464     case JVM_OPC_iload_0: case JVM_OPC_iload_1: case JVM_OPC_iload_2: case JVM_OPC_iload_3:
1465         this_idata->opcode = JVM_OPC_iload;
1466         var = opcode - JVM_OPC_iload_0;
1467         goto check_local_variable;
1468 
1469     case JVM_OPC_fload_0: case JVM_OPC_fload_1: case JVM_OPC_fload_2: case JVM_OPC_fload_3:


2233                                  "Expecting to find array of floats on stack");
2234                         break;
2235 
2236                     case 'D':   /* array of doubles */
2237                         if (top_type != MAKE_FULLINFO(ITEM_Double, 1, 0))
2238                             CCerror(context,
2239                                 "Expecting to find array of doubles on stack");
2240                         break;
2241 
2242                     case 'A': { /* array of addresses (arrays or objects) */
2243                         int indirection = GET_INDIRECTION(top_type);
2244                         if ((indirection == 0) ||
2245                             ((indirection == 1) &&
2246                                 (GET_ITEM_TYPE(top_type) != ITEM_Object)))
2247                             CCerror(context,
2248                                 "Expecting to find array of objects or arrays "
2249                                     "on stack");
2250                         break;
2251                     }
2252 
2253                     case 'B':   /* array of bytes */
2254                         if (top_type != MAKE_FULLINFO(ITEM_Byte, 1, 0))

2255                             CCerror(context,
2256                                   "Expecting to find array of bytes on stack");
2257                         break;
2258 
2259                     case 'C':   /* array of characters */
2260                         if (top_type != MAKE_FULLINFO(ITEM_Char, 1, 0))
2261                             CCerror(context,
2262                                   "Expecting to find array of chars on stack");
2263                         break;
2264 
2265                     case 'S':   /* array of shorts */
2266                         if (top_type != MAKE_FULLINFO(ITEM_Short, 1, 0))
2267                             CCerror(context,
2268                                  "Expecting to find array of shorts on stack");
2269                         break;
2270 
2271                     case '?':   /* any type of array is okay */
2272                         if (GET_INDIRECTION(top_type) == 0)
2273                             CCerror(context,
2274                                     "Expecting to find array on stack");
2275                         break;
2276 


3711     }
3712     context->err_code = CC_ClassFormatError;
3713     longjmp(context->jump_buffer, 1);
3714 }
3715 
3716 static char
3717 signature_to_fieldtype(context_type *context,
3718                        const char **signature_p, fullinfo_type *full_info_p)
3719 {
3720     const char *p = *signature_p;
3721     fullinfo_type full_info = MAKE_FULLINFO(ITEM_Bogus, 0, 0);
3722     char result;
3723     int array_depth = 0;
3724 
3725     for (;;) {
3726         switch(*p++) {
3727             default:
3728                 result = 0;
3729                 break;
3730 
3731             case JVM_SIGNATURE_BOOLEAN: case JVM_SIGNATURE_BYTE:







3732                 full_info = (array_depth > 0)
3733                               ? MAKE_FULLINFO(ITEM_Byte, 0, 0)
3734                               : MAKE_FULLINFO(ITEM_Integer, 0, 0);
3735                 result = 'I';
3736                 break;
3737 
3738             case JVM_SIGNATURE_CHAR:
3739                 full_info = (array_depth > 0)
3740                               ? MAKE_FULLINFO(ITEM_Char, 0, 0)
3741                               : MAKE_FULLINFO(ITEM_Integer, 0, 0);
3742                 result = 'I';
3743                 break;
3744 
3745             case JVM_SIGNATURE_SHORT:
3746                 full_info = (array_depth > 0)
3747                               ? MAKE_FULLINFO(ITEM_Short, 0, 0)
3748                               : MAKE_FULLINFO(ITEM_Integer, 0, 0);
3749                 result = 'I';
3750                 break;
3751 


3814                                      GET_EXTRA_INFO(full_info));
3815         return 'A';
3816     }
3817 }
3818 
3819 
3820 /* Given an array type, create the type that has one less level of
3821  * indirection.
3822  */
3823 
3824 static fullinfo_type
3825 decrement_indirection(fullinfo_type array_info)
3826 {
3827     if (array_info == NULL_FULLINFO) {
3828         return NULL_FULLINFO;
3829     } else {
3830         int type = GET_ITEM_TYPE(array_info);
3831         int indirection = GET_INDIRECTION(array_info) - 1;
3832         int extra_info = GET_EXTRA_INFO(array_info);
3833         if (   (indirection == 0)
3834                && ((type == ITEM_Short || type == ITEM_Byte || type == ITEM_Char)))
3835             type = ITEM_Integer;
3836         return MAKE_FULLINFO(type, indirection, extra_info);
3837     }
3838 }
3839 
3840 
3841 /* See if we can assign an object of the "from" type to an object
3842  * of the "to" type.
3843  */
3844 
3845 static jboolean isAssignableTo(context_type *context,
3846                              fullinfo_type from, fullinfo_type to)
3847 {
3848     return (merge_fullinfo_types(context, from, to, JNI_TRUE) == to);
3849 }
3850 
3851 /* Given two fullinfo_type's, find their lowest common denominator.  If
3852  * the assignable_p argument is non-null, we're really just calling to find
3853  * out if "<target> := <value>" is a legitimate assignment.
3854  *


4269         case ITEM_ReturnAddress:
4270             jio_fprintf(stdout, "a"); break;
4271         case ITEM_Object:
4272             if (!verbose) {
4273                 jio_fprintf(stdout, "A");
4274             } else {
4275                 unsigned short extra = GET_EXTRA_INFO(type);
4276                 if (extra == 0) {
4277                     jio_fprintf(stdout, "/Null/");
4278                 } else {
4279                     const char *name = ID_to_class_name(context, extra);
4280                     const char *name2 = strrchr(name, '/');
4281                     jio_fprintf(stdout, "/%s/", name2 ? name2 + 1 : name);
4282                 }
4283             }
4284             break;
4285         case ITEM_Char:
4286             jio_fprintf(stdout, "C"); break;
4287         case ITEM_Short:
4288             jio_fprintf(stdout, "S"); break;


4289         case ITEM_Byte:
4290             jio_fprintf(stdout, "B"); break;
4291         case ITEM_NewObject:
4292             if (!verbose) {
4293                 jio_fprintf(stdout, "@");
4294             } else {
4295                 int inum = GET_EXTRA_INFO(type);
4296                 fullinfo_type real_type =
4297                     context->instruction_data[inum].operand2.fi;
4298                 jio_fprintf(stdout, ">");
4299                 print_fullinfo_type(context, real_type, JNI_TRUE);
4300                 jio_fprintf(stdout, "<");
4301             }
4302             break;
4303         case ITEM_InitObject:
4304             jio_fprintf(stdout, verbose ? ">/this/<" : "@");
4305             break;
4306 
4307         default:
4308             jio_fprintf(stdout, "?"); break;


   1 /*
   2  * Copyright (c) 1994, 2015, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 142 
 143 int verify_verbose = 0;
 144 static struct context_type *GlobalContext;
 145 #endif
 146 
 147 enum {
 148     ITEM_Bogus,
 149     ITEM_Void,                  /* only as a function return value */
 150     ITEM_Integer,
 151     ITEM_Float,
 152     ITEM_Double,
 153     ITEM_Double_2,              /* 2nd word of double in register */
 154     ITEM_Long,
 155     ITEM_Long_2,                /* 2nd word of long in register */
 156     ITEM_Array,
 157     ITEM_Object,                /* Extra info field gives name. */
 158     ITEM_NewObject,             /* Like object, but uninitialized. */
 159     ITEM_InitObject,            /* "this" is init method, before call
 160                                     to super() */
 161     ITEM_ReturnAddress,         /* Extra info gives instr # of start pc */
 162     /* The following four are only used within array types.
 163      * Normally, we use ITEM_Integer, instead. */
 164     ITEM_Byte,
 165     ITEM_Short,
 166     ITEM_Char,
 167     ITEM_Boolean
 168 };
 169 
 170 
 171 #define UNKNOWN_STACK_SIZE -1
 172 #define UNKNOWN_REGISTER_COUNT -1
 173 #define UNKNOWN_RET_INSTRUCTION -1
 174 
 175 #undef MAX
 176 #undef MIN
 177 #define MAX(a, b) ((a) > (b) ? (a) : (b))
 178 #define MIN(a, b) ((a) < (b) ? (a) : (b))
 179 
 180 #define BITS_PER_INT   (CHAR_BIT * sizeof(int)/sizeof(char))
 181 #define SET_BIT(flags, i)  (flags[(i)/BITS_PER_INT] |= \
 182                                        ((unsigned)1 << ((i) % BITS_PER_INT)))
 183 #define IS_BIT_SET(flags, i) (flags[(i)/BITS_PER_INT] & \
 184                                        ((unsigned)1 << ((i) % BITS_PER_INT)))
 185 
 186 typedef unsigned int fullinfo_type;
 187 typedef unsigned int *bitvector;


1430                 CCerror(context, "Illegal dimension argument");
1431             break;
1432         default:
1433             this_idata->operand.fi = target;
1434         }
1435         break;
1436     }
1437 
1438     case JVM_OPC_newarray: {
1439         /* Cache the result of the JVM_OPC_newarray into the operand slot */
1440         fullinfo_type full_info;
1441         switch (code[offset + 1]) {
1442             case JVM_T_INT:
1443                 full_info = MAKE_FULLINFO(ITEM_Integer, 1, 0); break;
1444             case JVM_T_LONG:
1445                 full_info = MAKE_FULLINFO(ITEM_Long, 1, 0); break;
1446             case JVM_T_FLOAT:
1447                 full_info = MAKE_FULLINFO(ITEM_Float, 1, 0); break;
1448             case JVM_T_DOUBLE:
1449                 full_info = MAKE_FULLINFO(ITEM_Double, 1, 0); break;
1450             case JVM_T_BOOLEAN:
1451                 full_info = MAKE_FULLINFO(ITEM_Boolean, 1, 0); break;
1452             case JVM_T_BYTE:
1453                 full_info = MAKE_FULLINFO(ITEM_Byte, 1, 0); break;
1454             case JVM_T_CHAR:
1455                 full_info = MAKE_FULLINFO(ITEM_Char, 1, 0); break;
1456             case JVM_T_SHORT:
1457                 full_info = MAKE_FULLINFO(ITEM_Short, 1, 0); break;
1458             default:
1459                 full_info = 0;          /* Keep lint happy */
1460                 CCerror(context, "Bad type passed to newarray");
1461         }
1462         this_idata->operand.fi = full_info;
1463         break;
1464     }
1465 
1466     /* Fudge iload_x, aload_x, etc to look like their generic cousin. */
1467     case JVM_OPC_iload_0: case JVM_OPC_iload_1: case JVM_OPC_iload_2: case JVM_OPC_iload_3:
1468         this_idata->opcode = JVM_OPC_iload;
1469         var = opcode - JVM_OPC_iload_0;
1470         goto check_local_variable;
1471 
1472     case JVM_OPC_fload_0: case JVM_OPC_fload_1: case JVM_OPC_fload_2: case JVM_OPC_fload_3:


2236                                  "Expecting to find array of floats on stack");
2237                         break;
2238 
2239                     case 'D':   /* array of doubles */
2240                         if (top_type != MAKE_FULLINFO(ITEM_Double, 1, 0))
2241                             CCerror(context,
2242                                 "Expecting to find array of doubles on stack");
2243                         break;
2244 
2245                     case 'A': { /* array of addresses (arrays or objects) */
2246                         int indirection = GET_INDIRECTION(top_type);
2247                         if ((indirection == 0) ||
2248                             ((indirection == 1) &&
2249                                 (GET_ITEM_TYPE(top_type) != ITEM_Object)))
2250                             CCerror(context,
2251                                 "Expecting to find array of objects or arrays "
2252                                     "on stack");
2253                         break;
2254                     }
2255 
2256                     case 'B': case 'Z':   /* array of bytes or booleans */
2257                         if (top_type != MAKE_FULLINFO(ITEM_Byte, 1, 0) &&
2258                             top_type != MAKE_FULLINFO(ITEM_Boolean, 1, 0))
2259                             CCerror(context,
2260                                   "Expecting to find array of bytes or Booleans on stack");
2261                         break;
2262 
2263                     case 'C':   /* array of characters */
2264                         if (top_type != MAKE_FULLINFO(ITEM_Char, 1, 0))
2265                             CCerror(context,
2266                                   "Expecting to find array of chars on stack");
2267                         break;
2268 
2269                     case 'S':   /* array of shorts */
2270                         if (top_type != MAKE_FULLINFO(ITEM_Short, 1, 0))
2271                             CCerror(context,
2272                                  "Expecting to find array of shorts on stack");
2273                         break;
2274 
2275                     case '?':   /* any type of array is okay */
2276                         if (GET_INDIRECTION(top_type) == 0)
2277                             CCerror(context,
2278                                     "Expecting to find array on stack");
2279                         break;
2280 


3715     }
3716     context->err_code = CC_ClassFormatError;
3717     longjmp(context->jump_buffer, 1);
3718 }
3719 
3720 static char
3721 signature_to_fieldtype(context_type *context,
3722                        const char **signature_p, fullinfo_type *full_info_p)
3723 {
3724     const char *p = *signature_p;
3725     fullinfo_type full_info = MAKE_FULLINFO(ITEM_Bogus, 0, 0);
3726     char result;
3727     int array_depth = 0;
3728 
3729     for (;;) {
3730         switch(*p++) {
3731             default:
3732                 result = 0;
3733                 break;
3734 
3735             case JVM_SIGNATURE_BOOLEAN:
3736                 full_info = (array_depth > 0)
3737                               ? MAKE_FULLINFO(ITEM_Boolean, 0, 0)
3738                               : MAKE_FULLINFO(ITEM_Integer, 0, 0);
3739                 result = 'I';
3740                 break;
3741 
3742             case JVM_SIGNATURE_BYTE:
3743                 full_info = (array_depth > 0)
3744                               ? MAKE_FULLINFO(ITEM_Byte, 0, 0)
3745                               : MAKE_FULLINFO(ITEM_Integer, 0, 0);
3746                 result = 'I';
3747                 break;
3748 
3749             case JVM_SIGNATURE_CHAR:
3750                 full_info = (array_depth > 0)
3751                               ? MAKE_FULLINFO(ITEM_Char, 0, 0)
3752                               : MAKE_FULLINFO(ITEM_Integer, 0, 0);
3753                 result = 'I';
3754                 break;
3755 
3756             case JVM_SIGNATURE_SHORT:
3757                 full_info = (array_depth > 0)
3758                               ? MAKE_FULLINFO(ITEM_Short, 0, 0)
3759                               : MAKE_FULLINFO(ITEM_Integer, 0, 0);
3760                 result = 'I';
3761                 break;
3762 


3825                                      GET_EXTRA_INFO(full_info));
3826         return 'A';
3827     }
3828 }
3829 
3830 
3831 /* Given an array type, create the type that has one less level of
3832  * indirection.
3833  */
3834 
3835 static fullinfo_type
3836 decrement_indirection(fullinfo_type array_info)
3837 {
3838     if (array_info == NULL_FULLINFO) {
3839         return NULL_FULLINFO;
3840     } else {
3841         int type = GET_ITEM_TYPE(array_info);
3842         int indirection = GET_INDIRECTION(array_info) - 1;
3843         int extra_info = GET_EXTRA_INFO(array_info);
3844         if (   (indirection == 0)
3845                && ((type == ITEM_Short || type == ITEM_Byte || type == ITEM_Boolean || type == ITEM_Char)))
3846             type = ITEM_Integer;
3847         return MAKE_FULLINFO(type, indirection, extra_info);
3848     }
3849 }
3850 
3851 
3852 /* See if we can assign an object of the "from" type to an object
3853  * of the "to" type.
3854  */
3855 
3856 static jboolean isAssignableTo(context_type *context,
3857                              fullinfo_type from, fullinfo_type to)
3858 {
3859     return (merge_fullinfo_types(context, from, to, JNI_TRUE) == to);
3860 }
3861 
3862 /* Given two fullinfo_type's, find their lowest common denominator.  If
3863  * the assignable_p argument is non-null, we're really just calling to find
3864  * out if "<target> := <value>" is a legitimate assignment.
3865  *


4280         case ITEM_ReturnAddress:
4281             jio_fprintf(stdout, "a"); break;
4282         case ITEM_Object:
4283             if (!verbose) {
4284                 jio_fprintf(stdout, "A");
4285             } else {
4286                 unsigned short extra = GET_EXTRA_INFO(type);
4287                 if (extra == 0) {
4288                     jio_fprintf(stdout, "/Null/");
4289                 } else {
4290                     const char *name = ID_to_class_name(context, extra);
4291                     const char *name2 = strrchr(name, '/');
4292                     jio_fprintf(stdout, "/%s/", name2 ? name2 + 1 : name);
4293                 }
4294             }
4295             break;
4296         case ITEM_Char:
4297             jio_fprintf(stdout, "C"); break;
4298         case ITEM_Short:
4299             jio_fprintf(stdout, "S"); break;
4300         case ITEM_Boolean:
4301             jio_fprintf(stdout, "Z"); break;
4302         case ITEM_Byte:
4303             jio_fprintf(stdout, "B"); break;
4304         case ITEM_NewObject:
4305             if (!verbose) {
4306                 jio_fprintf(stdout, "@");
4307             } else {
4308                 int inum = GET_EXTRA_INFO(type);
4309                 fullinfo_type real_type =
4310                     context->instruction_data[inum].operand2.fi;
4311                 jio_fprintf(stdout, ">");
4312                 print_fullinfo_type(context, real_type, JNI_TRUE);
4313                 jio_fprintf(stdout, "<");
4314             }
4315             break;
4316         case ITEM_InitObject:
4317             jio_fprintf(stdout, verbose ? ">/this/<" : "@");
4318             break;
4319 
4320         default:
4321             jio_fprintf(stdout, "?"); break;


src/java.base/share/native/libverify/check_code.c
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File