/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * This source file is part of SableVM. * * * * See the file "LICENSE" for the copyright information and for * * the terms and conditions for copying, distribution and * * modification of this source file. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* m4svm_file_name */ /* ---------------------------------------------------------------------- m4svm_parse_number ---------------------------------------------------------------------- */ m4svm_define_begin v = ":], [:m4svm_parse_number:])"; /* -----------------------------------m4_dnl ----------------------------------- _svmh_parse_$1 -----------------------------------m4_dnl ----------------------------------- */ #define _svmm_parse_$1(env, current, size, result) \ _svmh_parse_$1 (env, ¤t, &size, &result) svm_static jint _svmh_parse_$1 (_svmt_JNIEnv *env, _svmt_u8 **pcurrent, size_t *psize, $3 * presult) { size_t i; $2 result = 0; if (*psize < sizeof ($2)) { _svmf_error_ClassFormatError (env); return JNI_ERR; } for (i = 0; i < sizeof ($2); i++) { result = (result << 8) | (*pcurrent)[i]; } *psize -= sizeof ($2); *pcurrent += sizeof ($2); *presult = result; return JNI_OK; } m4svm_define_end v = ":])"; /* ---------------------------------------------------------------------- m4svm_parse_constant_pool_entry ---------------------------------------------------------------------- */ void m4_dnl () { switch (dummy) { case dummy: m4svm_define_begin = ":], [:m4svm_parse_constant_pool_entry:])"; case SVM_$1: { _svmt_$1_info **pinfo = (_svmt_$1_info **) pentry; if (_svmm_cl_zalloc_$1_info (env, class_loader_info, *pinfo) != JNI_OK) { return JNI_ERR; } DREF (pinfo, tag) = tag; if (_svmf_parse_$1_info (env, class_loader_info, pcurrent, psize, class, *pinfo) != JNI_OK) { return JNI_ERR; } } break; m4svm_define_end = ":])"; } } /* ---------------------------------------------------------------------- m4svm_parse_cp_index ---------------------------------------------------------------------- */ m4svm_define_begin v = ":], [:m4svm_parse_cp_index:])"; /* -----------------------------------m4_dnl ----------------------------------- _svmh_parse_cp_index_$1 -----------------------------------m4_dnl ----------------------------------- */ #define _svmm_parse_cp_index_$1(env, current, size, class, result) \ _svmh_parse_cp_index_$1 (env, ¤t, &size, class, &result) svm_static jint _svmh_parse_cp_index_$1 (_svmt_JNIEnv *env, _svmt_u8 **pcurrent, size_t *psize, _svmt_class_info *class, _svmt_$1_info *** presult) { jint index; if (_svmm_parse_u16 (env, *pcurrent, *psize, index) != JNI_OK) { return JNI_ERR; } if (index >= class->constant_pool_count) { _svmf_error_ClassFormatError (env); return JNI_ERR; } *presult = (_svmt_$1_info **) & class->constant_pool[index]; return JNI_OK; } m4svm_define_end v = ":])"; /* ---------------------------------------------------------------------- m4svm_parse_attribute_if ---------------------------------------------------------------------- */ void m4_dnl () { m4svm_define_begin v = ":], [:m4svm_parse_attribute_if:])"; if (strcmp (name, "$1") == 0) { /* m4svm_comment_define([:m4svm_parse_attribute_1:], * [:[:m4svm_parse_attribute($:][:1):][::]m4_dnl:]) */ m4svm_parse_attribute_1 = dummy; } m4svm_define_end = ":])"; } /* ---------------------------------------------------------------------- m4svm_parse_attribute_elseif ---------------------------------------------------------------------- */ void m4_dnl () { if (dummy) m4svm_define_begin = ":], [:m4svm_parse_attribute_elseif:])"; else if (strcmp (name, "$1") == 0) { /* m4svm_comment_define([:m4svm_parse_attribute_1:], * [:[:m4svm_parse_attribute($:][:1):][::]m4_dnl:]) */ m4svm_parse_attribute_1 = dummy; } m4svm_define_end = ":])"; } /* ---------------------------------------------------------------------- m4svm_parse_attribute_else ---------------------------------------------------------------------- */ void m4_dnl () { if (dummy) m4svm_define_begin = ":], [:m4svm_parse_attribute_else:])"; else { /* m4svm_comment_define([:m4svm_parse_attribute_1:], * [:[:m4svm_parse_attribute($:][:1):][::]m4_dnl:]) */ m4svm_parse_attribute_1 = dummy; } m4svm_define_end = ":])"; } /* ---------------------------------------------------------------------- m4svm_parse_attribute ---------------------------------------------------------------------- */ void m4_dnl () { if (dummy) { m4svm_define_begin v = ":], [:m4svm_parse_attribute:])"; _svmt_$1_attribute **p$1attribute = (_svmt_$1_attribute **) pattribute; if (_svmm_cl_zalloc_$1_attribute (env, class_loader_info, *p$1attribute) != JNI_OK) { return JNI_ERR; } DREF (p$1attribute, name) = attribute_name; if (_svmf_parse_$1_attribute (env, class_loader_info, pcurrent, psize, length, class, *p$1attribute) != JNI_OK) { return JNI_ERR; } m4svm_define_end = ":])"; } } /* ---------------------------------------------------------------------- _svmm_parse_(number) ---------------------------------------------------------------------- */ /* m4svm_parse_number(s64, _svmt_s64, jlong) */ /* m4svm_parse_number(u32, _svmt_u32, jlong) */ /* m4svm_parse_number(s32, _svmt_s32, jint) */ /* m4svm_parse_number(u16, _svmt_u16, jint) */ /* ---------------------------------------------------------------------- _svmm_parse_cp_index_(*) ---------------------------------------------------------------------- */ /* m4svm_parse_cp_index(cp) */ /* m4svm_parse_cp_index(CONSTANT_Utf8) */ /* m4svm_parse_cp_index(CONSTANT_Class) */ /* m4svm_parse_cp_index(CONSTANT_NameAndType) */ /* m4svm_on(0)m4_dnl */ /* ---------------------------------------------------------------------- _svmh_parse_d64 ---------------------------------------------------------------------- */ #define _svmm_parse_d64(env, current, size, result) \ _svmh_parse_d64 (env, ¤t, &size, &result) svm_static jint _svmh_parse_d64 (_svmt_JNIEnv *env, _svmt_u8 **pcurrent, size_t *psize, jdouble *presult) { size_t i; _svmt_u64 result = 0; if (*psize < sizeof (_svmt_u64)) { _svmf_error_ClassFormatError (env); return JNI_ERR; } for (i = 0; i < sizeof (_svmt_u64); i++) { result = (result << 8) | (*pcurrent)[i]; } #if defined(__arm__) /* On ARM 'double' values have their two 32bit parts reversed. */ { _svmt_u64 result1, result2; result1 = result & 0xffffffff; result2 = result >> 32; result = (result1 << 32) | result2; } #endif *psize -= sizeof (_svmt_u64); *pcurrent += sizeof (_svmt_u64); *presult = *((jdouble *) &result); return JNI_OK; } /* ---------------------------------------------------------------------- _svmh_parse_f32 ---------------------------------------------------------------------- */ #define _svmm_parse_f32(env, current, size, result) \ _svmh_parse_f32 (env, ¤t, &size, &result) svm_static jint _svmh_parse_f32 (_svmt_JNIEnv *env, _svmt_u8 **pcurrent, size_t *psize, jfloat *presult) { size_t i; _svmt_u32 result = 0; if (*psize < sizeof (_svmt_u32)) { _svmf_error_ClassFormatError (env); return JNI_ERR; } for (i = 0; i < sizeof (_svmt_u32); i++) { result = (result << 8) | (*pcurrent)[i]; } *psize -= sizeof (_svmt_u32); *pcurrent += sizeof (_svmt_u32); *presult = *((jfloat *) &result); return JNI_OK; } /* ---------------------------------------------------------------------- _svmf_parse_CONSTANT_Class_info ---------------------------------------------------------------------- */ svm_static jint _svmf_parse_CONSTANT_Class_info (_svmt_JNIEnv *env, _svmt_class_loader_info *class_loader_info, _svmt_u8 **pcurrent, size_t *psize, _svmt_class_info *class, _svmt_CONSTANT_Class_info *info) { if (_svmm_parse_cp_index_CONSTANT_Utf8 (env, *pcurrent, *psize, class, info->name) != JNI_OK) { return JNI_ERR; } return JNI_OK; } /* ---------------------------------------------------------------------- _svmf_parse_CONSTANT_Fieldref_info ---------------------------------------------------------------------- */ svm_static jint _svmf_parse_CONSTANT_Fieldref_info (_svmt_JNIEnv *env, _svmt_class_loader_info *class_loader_info, _svmt_u8 **pcurrent, size_t *psize, _svmt_class_info *class, _svmt_CONSTANT_Fieldref_info *info) { if (_svmm_parse_cp_index_CONSTANT_Class (env, *pcurrent, *psize, class, info->class) != JNI_OK) { return JNI_ERR; } if (_svmm_parse_cp_index_CONSTANT_NameAndType (env, *pcurrent, *psize, class, info->name_and_type) != JNI_OK) { return JNI_ERR; } return JNI_OK; } /* ---------------------------------------------------------------------- _svmf_parse_CONSTANT_Methodref_info ---------------------------------------------------------------------- */ svm_static jint _svmf_parse_CONSTANT_Methodref_info (_svmt_JNIEnv *env, _svmt_class_loader_info *class_loader_info, _svmt_u8 **pcurrent, size_t *psize, _svmt_class_info *class, _svmt_CONSTANT_Methodref_info *info) { if (_svmm_parse_cp_index_CONSTANT_Class (env, *pcurrent, *psize, class, info->class) != JNI_OK) { return JNI_ERR; } if (_svmm_parse_cp_index_CONSTANT_NameAndType (env, *pcurrent, *psize, class, info->name_and_type) != JNI_OK) { return JNI_ERR; } return JNI_OK; } /* ---------------------------------------------------------------------- _svmf_parse_CONSTANT_InterfaceMethodref_info ---------------------------------------------------------------------- */ svm_static jint _svmf_parse_CONSTANT_InterfaceMethodref_info (_svmt_JNIEnv *env, _svmt_class_loader_info *class_loader_info, _svmt_u8 **pcurrent, size_t *psize, _svmt_class_info *class, _svmt_CONSTANT_InterfaceMethodref_info *info) { if (_svmm_parse_cp_index_CONSTANT_Class (env, *pcurrent, *psize, class, info->class) != JNI_OK) { return JNI_ERR; } if (_svmm_parse_cp_index_CONSTANT_NameAndType (env, *pcurrent, *psize, class, info->name_and_type) != JNI_OK) { return JNI_ERR; } return JNI_OK; } /* ---------------------------------------------------------------------- _svmf_parse_CONSTANT_String_info ---------------------------------------------------------------------- */ svm_static jint _svmf_parse_CONSTANT_String_info (_svmt_JNIEnv *env, _svmt_class_loader_info *class_loader_info, _svmt_u8 **pcurrent, size_t *psize, _svmt_class_info *class, _svmt_CONSTANT_String_info *info) { if (_svmm_parse_cp_index_CONSTANT_Utf8 (env, *pcurrent, *psize, class, info->string) != JNI_OK) { return JNI_ERR; } return JNI_OK; } /* ---------------------------------------------------------------------- _svmf_parse_CONSTANT_Integer_info ---------------------------------------------------------------------- */ svm_static jint _svmf_parse_CONSTANT_Integer_info (_svmt_JNIEnv *env, _svmt_class_loader_info *class_loader_info, _svmt_u8 **pcurrent, size_t *psize, _svmt_class_info *class, _svmt_CONSTANT_Integer_info *info) { if (_svmm_parse_s32 (env, *pcurrent, *psize, info->value) != JNI_OK) { return JNI_ERR; } return JNI_OK; } /* ---------------------------------------------------------------------- _svmf_parse_CONSTANT_Float_info ---------------------------------------------------------------------- */ svm_static jint _svmf_parse_CONSTANT_Float_info (_svmt_JNIEnv *env, _svmt_class_loader_info *class_loader_info, _svmt_u8 **pcurrent, size_t *psize, _svmt_class_info *class, _svmt_CONSTANT_Float_info *info) { if (_svmm_parse_f32 (env, *pcurrent, *psize, info->value) != JNI_OK) { return JNI_ERR; } return JNI_OK; } /* ---------------------------------------------------------------------- _svmf_parse_CONSTANT_Long_info ---------------------------------------------------------------------- */ svm_static jint _svmf_parse_CONSTANT_Long_info (_svmt_JNIEnv *env, _svmt_class_loader_info *class_loader_info, _svmt_u8 **pcurrent, size_t *psize, _svmt_class_info *class, _svmt_CONSTANT_Long_info *info) { if (_svmm_parse_s64 (env, *pcurrent, *psize, info->value) != JNI_OK) { return JNI_ERR; } return JNI_OK; } /* ---------------------------------------------------------------------- _svmf_parse_CONSTANT_Double_info ---------------------------------------------------------------------- */ svm_static jint _svmf_parse_CONSTANT_Double_info (_svmt_JNIEnv *env, _svmt_class_loader_info *class_loader_info, _svmt_u8 **pcurrent, size_t *psize, _svmt_class_info *class, _svmt_CONSTANT_Double_info *info) { if (_svmm_parse_d64 (env, *pcurrent, *psize, info->value) != JNI_OK) { return JNI_ERR; } return JNI_OK; } /* ---------------------------------------------------------------------- _svmf_parse_CONSTANT_NameAndType_info ---------------------------------------------------------------------- */ svm_static jint _svmf_parse_CONSTANT_NameAndType_info (_svmt_JNIEnv *env, _svmt_class_loader_info *class_loader_info, _svmt_u8 **pcurrent, size_t *psize, _svmt_class_info *class, _svmt_CONSTANT_NameAndType_info *info) { if (_svmm_parse_cp_index_CONSTANT_Utf8 (env, *pcurrent, *psize, class, info->name) != JNI_OK) { return JNI_ERR; } if (_svmm_parse_cp_index_CONSTANT_Utf8 (env, *pcurrent, *psize, class, info->descriptor) != JNI_OK) { return JNI_ERR; } return JNI_OK; } /* ---------------------------------------------------------------------- _svmf_parse_CONSTANT_Utf8_info ---------------------------------------------------------------------- */ svm_static jint _svmf_parse_CONSTANT_Utf8_info (_svmt_JNIEnv *env, _svmt_class_loader_info *class_loader_info, _svmt_u8 **pcurrent, size_t *psize, _svmt_class_info *class, _svmt_CONSTANT_Utf8_info *info) { if (_svmm_parse_u16 (env, *pcurrent, *psize, info->length) != JNI_OK) { return JNI_ERR; } if (*psize < (size_t) info->length) { _svmf_error_ClassFormatError (env); return JNI_ERR; } if (_svmm_cl_malloc_chars (env, class_loader_info, info->length + 1, info->value) != JNI_OK) { return JNI_ERR; } { jint length = info->length; jint i; *psize -= length; for (i = 0; i < length; i++) { jbyte b = *((*pcurrent)++); if ((b == 0) || ((b >= (jbyte) 0xf0) && (b <= (jbyte) 0xff))) { _svmf_error_ClassFormatError (env); return JNI_ERR; } info->value[i] = b; } info->value[length] = 0; } return JNI_OK; } /* ---------------------------------------------------------------------- _svmh_parse_constant_pool_entry ---------------------------------------------------------------------- */ #define _svmm_parse_constant_pool_entry(env,cli,current,size,class,entry) \ _svmh_parse_constant_pool_entry (env, cli, ¤t, &size, class, &entry) svm_static jint _svmh_parse_constant_pool_entry (_svmt_JNIEnv *env, _svmt_class_loader_info *class_loader_info, _svmt_u8 **pcurrent, size_t *psize, _svmt_class_info *class, _svmt_cp_info **pentry) { jint tag; if ((*psize)-- < 1) { _svmf_error_ClassFormatError (env); return JNI_ERR; } tag = *((*pcurrent)++); switch (tag) { /* constant pool entries *[::]/ m4svm_off() m4svm_parse_constant_pool_entry(CONSTANT_Class) m4svm_parse_constant_pool_entry(CONSTANT_Fieldref) m4svm_parse_constant_pool_entry(CONSTANT_Methodref) m4svm_parse_constant_pool_entry(CONSTANT_InterfaceMethodref) m4svm_parse_constant_pool_entry(CONSTANT_String) m4svm_parse_constant_pool_entry(CONSTANT_Integer) m4svm_parse_constant_pool_entry(CONSTANT_Float) m4svm_parse_constant_pool_entry(CONSTANT_Long) m4svm_parse_constant_pool_entry(CONSTANT_Double) m4svm_parse_constant_pool_entry(CONSTANT_NameAndType) m4svm_parse_constant_pool_entry(CONSTANT_Utf8) m4svm_on(0)m4_dnl */ default: { _svmf_error_ClassFormatError (env); return JNI_ERR; } break; } return JNI_OK; } /* ---------------------------------------------------------------------- _svmf_parse_ConstantValue_attribute ---------------------------------------------------------------------- */ svm_static jint _svmf_parse_ConstantValue_attribute (_svmt_JNIEnv *env, _svmt_class_loader_info *class_loader_info, _svmt_u8 **pcurrent, size_t *psize, jlong length, _svmt_class_info *class, _svmt_ConstantValue_attribute *attribute) { if (_svmm_parse_cp_index_cp (env, *pcurrent, *psize, class, attribute->constantvalue) != JNI_OK) { return JNI_ERR; } return JNI_OK; } /* ---------------------------------------------------------------------- _svmf_parse_Synthetic_attribute ---------------------------------------------------------------------- */ svm_static jint _svmf_parse_Synthetic_attribute (_svmt_JNIEnv *env, _svmt_class_loader_info *class_loader_info, _svmt_u8 **pcurrent, size_t *psize, jlong length, _svmt_class_info *class, _svmt_Synthetic_attribute *attribute) { return JNI_OK; } /* ---------------------------------------------------------------------- _svmf_parse_Deprecated_attribute ---------------------------------------------------------------------- */ svm_static jint _svmf_parse_Deprecated_attribute (_svmt_JNIEnv *env, _svmt_class_loader_info *class_loader_info, _svmt_u8 **pcurrent, size_t *psize, jlong length, _svmt_class_info *class, _svmt_Deprecated_attribute *attribute) { return JNI_OK; } /* ---------------------------------------------------------------------- _svmf_parse_unknown_attribute ---------------------------------------------------------------------- */ svm_static jint _svmf_parse_unknown_attribute (_svmt_JNIEnv *env, _svmt_class_loader_info *class_loader_info, _svmt_u8 **pcurrent, size_t *psize, jlong length, _svmt_class_info *class, _svmt_unknown_attribute *attribute) { if (*psize < (size_t) length) { _svmf_error_ClassFormatError (env); return JNI_ERR; } if (length > 0) { if (_svmm_cl_malloc_u8 (env, class_loader_info, length, attribute->info) != JNI_OK) { return JNI_ERR; } memcpy (attribute->info, pcurrent, length); *psize -= length; *pcurrent += length; } return JNI_OK; } /* ---------------------------------------------------------------------- _svmf_parse_LineNumberTable_attribute ---------------------------------------------------------------------- */ svm_static jint _svmf_parse_LineNumberTable_attribute (_svmt_JNIEnv *env, _svmt_class_loader_info *class_loader_info, _svmt_u8 **pcurrent, size_t *psize, jlong length, _svmt_class_info *class, _svmt_LineNumberTable_attribute *attribute) { if (_svmm_parse_u16 (env, *pcurrent, *psize, attribute->line_number_table_length) != JNI_OK) { return JNI_ERR; } if (attribute->line_number_table_length > 0) { jint line_number_table_length = attribute->line_number_table_length; jint i; if (_svmm_cl_zmalloc_line_number_table (env, class_loader_info, line_number_table_length, attribute->line_number_table) != JNI_OK) { return JNI_ERR; } for (i = 0; i < line_number_table_length; i++) { _svmt_line_number_table *line_number_entry = &attribute->line_number_table[i]; if (_svmm_parse_u16 (env, *pcurrent, *psize, line_number_entry->start_pc) != JNI_OK) { return JNI_ERR; } if (_svmm_parse_u16 (env, *pcurrent, *psize, line_number_entry->line_number) != JNI_OK) { return JNI_ERR; } } } return JNI_OK; } /* ---------------------------------------------------------------------- _svmf_parse_LocalVariableTable_attribute ---------------------------------------------------------------------- */ svm_static jint _svmf_parse_LocalVariableTable_attribute (_svmt_JNIEnv *env, _svmt_class_loader_info *class_loader_info, _svmt_u8 **pcurrent, size_t *psize, jlong length, _svmt_class_info *class, _svmt_LocalVariableTable_attribute *attribute) { if (_svmm_parse_u16 (env, *pcurrent, *psize, attribute->local_variable_table_length) != JNI_OK) { return JNI_ERR; } if (attribute->local_variable_table_length > 0) { jint local_variable_table_length = attribute->local_variable_table_length; jint i; if (_svmm_cl_zmalloc_local_variable_table (env, class_loader_info, local_variable_table_length, attribute->local_variable_table) != JNI_OK) { return JNI_ERR; } for (i = 0; i < local_variable_table_length; i++) { _svmt_local_variable_table *local_variable_entry = &attribute->local_variable_table[i]; if (_svmm_parse_u16 (env, *pcurrent, *psize, local_variable_entry->start_pc) != JNI_OK) { return JNI_ERR; } if (_svmm_parse_u16 (env, *pcurrent, *psize, local_variable_entry->length) != JNI_OK) { return JNI_ERR; } if (_svmm_parse_cp_index_CONSTANT_Utf8 (env, *pcurrent, *psize, class, local_variable_entry->name) != JNI_OK) { return JNI_ERR; } if (_svmm_parse_cp_index_CONSTANT_Utf8 (env, *pcurrent, *psize, class, local_variable_entry->descriptor) != JNI_OK) { return JNI_ERR; } if (_svmm_parse_u16 (env, *pcurrent, *psize, local_variable_entry->index) != JNI_OK) { return JNI_ERR; } } } return JNI_OK; } /* ---------------------------------------------------------------------- _svmf_parse_Exceptions_attribute ---------------------------------------------------------------------- */ svm_static jint _svmf_parse_Exceptions_attribute (_svmt_JNIEnv *env, _svmt_class_loader_info *class_loader_info, _svmt_u8 **pcurrent, size_t *psize, jlong length, _svmt_class_info *class, _svmt_Exceptions_attribute *attribute) { if (_svmm_parse_u16 (env, *pcurrent, *psize, attribute->number_of_exceptions) != JNI_OK) { return JNI_ERR; } if (attribute->number_of_exceptions > 0) { jint number_of_exceptions = attribute->number_of_exceptions; jint i; if (_svmm_cl_malloc_classes (env, class_loader_info, number_of_exceptions, attribute->exception_table) != JNI_OK) { return JNI_ERR; } for (i = 0; i < number_of_exceptions; i++) { if (_svmm_parse_cp_index_CONSTANT_Class (env, *pcurrent, *psize, class, attribute->exception_table[i]) != JNI_OK) { return JNI_ERR; } } } return JNI_OK; } /* ---------------------------------------------------------------------- _svmf_parse_InnerClasses_attribute ---------------------------------------------------------------------- */ svm_static jint _svmf_parse_InnerClasses_attribute (_svmt_JNIEnv *env, _svmt_class_loader_info *class_loader_info, _svmt_u8 **pcurrent, size_t *psize, jlong length, _svmt_class_info *class, _svmt_InnerClasses_attribute *attribute) { if (_svmm_parse_u16 (env, *pcurrent, *psize, attribute->number_of_classes) != JNI_OK) { return JNI_ERR; } if (attribute->number_of_classes > 0) { jint number_of_classes = attribute->number_of_classes; jint i; if (_svmm_cl_malloc_inner_classes (env, class_loader_info, number_of_classes, attribute->classes) != JNI_OK) { return JNI_ERR; } for (i = 0; i < number_of_classes; i++) { if (_svmm_parse_cp_index_CONSTANT_Class (env, *pcurrent, *psize, class, attribute->classes[i].inner_class_info) != JNI_OK) { return JNI_ERR; } if (_svmm_parse_cp_index_CONSTANT_Class (env, *pcurrent, *psize, class, attribute->classes[i].outer_class_info) != JNI_OK) { return JNI_ERR; } if (_svmm_parse_cp_index_CONSTANT_Utf8 (env, *pcurrent, *psize, class, attribute->classes[i].inner_name) != JNI_OK) { return JNI_ERR; } if (_svmm_parse_u16 (env, *pcurrent, *psize, attribute->classes[i].inner_class_access_flags) != JNI_OK) { return JNI_ERR; } } } return JNI_OK; } /* ---------------------------------------------------------------------- _svmf_parse_SourceFile_attribute ---------------------------------------------------------------------- */ svm_static jint _svmf_parse_SourceFile_attribute (_svmt_JNIEnv *env, _svmt_class_loader_info *class_loader_info, _svmt_u8 **pcurrent, size_t *psize, jlong length, _svmt_class_info *class, _svmt_SourceFile_attribute *attribute) { if (_svmm_parse_cp_index_CONSTANT_Utf8 (env, *pcurrent, *psize, class, attribute->sourcefile) != JNI_OK) { return JNI_ERR; } return JNI_OK; } /* ---------------------------------------------------------------------- _svmh_parse_code_attribute ---------------------------------------------------------------------- */ #define _svmm_parse_code_attribute(env,cli,current,size,class,attribute) \ _svmh_parse_code_attribute (env, cli, ¤t, &size, class, &attribute) svm_static jint _svmh_parse_code_attribute (_svmt_JNIEnv *env, _svmt_class_loader_info *class_loader_info, _svmt_u8 **pcurrent, size_t *psize, _svmt_class_info *class, _svmt_attribute_info **pattribute) { _svmt_CONSTANT_Utf8_info **attribute_name; jlong length; size_t old_size; char *name; /* attribute name */ if (_svmm_parse_cp_index_CONSTANT_Utf8 (env, *pcurrent, *psize, class, attribute_name) != JNI_OK) { return JNI_ERR; } if (CANNOT_DREF (attribute_name) || DREF (attribute_name, tag) != SVM_CONSTANT_Utf8) { _svmf_error_ClassFormatError (env); return JNI_ERR; } name = DREF (attribute_name, value); if (_svmm_parse_u32 (env, *pcurrent, *psize, length) != JNI_OK) { return JNI_ERR; } old_size = *psize; /* parse attributes *[::]/ m4svm_off() m4svm_parse_attribute_if(LineNumberTable) m4svm_parse_attribute_elseif(LocalVariableTable) m4svm_parse_attribute_else(unknown) m4svm_on(0)m4_dnl */ if (old_size - length != *psize) { _svmf_error_ClassFormatError (env); return JNI_ERR; } return JNI_OK; } /* ---------------------------------------------------------------------- _svmf_parse_Code_attribute ---------------------------------------------------------------------- */ svm_static jint _svmf_parse_Code_attribute (_svmt_JNIEnv *env, _svmt_class_loader_info *class_loader_info, _svmt_u8 **pcurrent, size_t *psize, jlong length, _svmt_class_info *class, _svmt_Code_attribute *attribute) { if (_svmm_parse_u16 (env, *pcurrent, *psize, attribute->max_stack) != JNI_OK) { return JNI_ERR; } if (_svmm_parse_u16 (env, *pcurrent, *psize, attribute->max_locals) != JNI_OK) { return JNI_ERR; } if (_svmm_parse_u32 (env, *pcurrent, *psize, attribute->code_length) != JNI_OK) { return JNI_ERR; } if (attribute->code_length > 0) { if (*psize < (size_t) attribute->code_length) { _svmf_error_ClassFormatError (env); return JNI_ERR; } if (_svmm_cl_malloc_u8 (env, class_loader_info, attribute->code_length, attribute->code) != JNI_OK) { return JNI_ERR; } memcpy (attribute->code, *pcurrent, attribute->code_length); *psize -= attribute->code_length; *pcurrent += attribute->code_length; } if (_svmm_parse_u16 (env, *pcurrent, *psize, attribute->exception_table_length) != JNI_OK) { return JNI_ERR; } if (attribute->exception_table_length > 0) { jint exception_table_length = attribute->exception_table_length; jint i; if (_svmm_cl_zmalloc_exception_table (env, class_loader_info, exception_table_length, attribute->exception_table) != JNI_OK) { return JNI_ERR; } for (i = 0; i < exception_table_length; i++) { _svmt_exception_table *exception = &attribute->exception_table[i]; if (_svmm_parse_u16 (env, *pcurrent, *psize, exception->start_pc) != JNI_OK) { return JNI_ERR; } if (_svmm_parse_u16 (env, *pcurrent, *psize, exception->end_pc) != JNI_OK) { return JNI_ERR; } if (_svmm_parse_u16 (env, *pcurrent, *psize, exception->handler_pc) != JNI_OK) { return JNI_ERR; } if (_svmm_parse_cp_index_CONSTANT_Class (env, *pcurrent, *psize, class, exception->catch_type) != JNI_OK) { return JNI_ERR; } } } /* attributes_count */ if (_svmm_parse_u16 (env, *pcurrent, *psize, attribute->attributes_count) != JNI_OK) { return JNI_ERR; } /* attributes */ if (attribute->attributes_count > 0) { jint attributes_count = attribute->attributes_count; jint nested_attribute; _svmt_attribute_info **attributes; if (_svmm_cl_malloc_attributes (env, class_loader_info, attributes_count, attribute->attributes) != JNI_OK) { return JNI_ERR; } attributes = attribute->attributes; for (nested_attribute = 0; nested_attribute < attributes_count; nested_attribute++) { if (_svmm_parse_code_attribute (env, class_loader_info, *pcurrent, *psize, class, attributes[nested_attribute]) != JNI_OK) { return JNI_ERR; } } } return JNI_OK; } /* ---------------------------------------------------------------------- _svmh_parse_field_attribute ---------------------------------------------------------------------- */ #define _svmm_parse_field_attribute(env,cli,current,size,class,attribute) \ _svmh_parse_field_attribute (env, cli, ¤t, &size, class, &attribute) svm_static jint _svmh_parse_field_attribute (_svmt_JNIEnv *env, _svmt_class_loader_info *class_loader_info, _svmt_u8 **pcurrent, size_t *psize, _svmt_class_info *class, _svmt_attribute_info **pattribute) { _svmt_CONSTANT_Utf8_info **attribute_name; jlong length; size_t old_size; char *name; /* attribute name */ if (_svmm_parse_cp_index_CONSTANT_Utf8 (env, *pcurrent, *psize, class, attribute_name) != JNI_OK) { return JNI_ERR; } if (CANNOT_DREF (attribute_name) || DREF (attribute_name, tag) != SVM_CONSTANT_Utf8) { _svmf_error_ClassFormatError (env); return JNI_ERR; } name = DREF (attribute_name, value); if (_svmm_parse_u32 (env, *pcurrent, *psize, length) != JNI_OK) { return JNI_ERR; } old_size = *psize; /* parse attributes *[::]/ m4svm_off() m4svm_parse_attribute_if(ConstantValue) m4svm_parse_attribute_elseif(Synthetic) m4svm_parse_attribute_elseif(Deprecated) m4svm_parse_attribute_else(unknown) m4svm_on(0)m4_dnl */ if (old_size - length != *psize) { _svmf_error_ClassFormatError (env); return JNI_ERR; } return JNI_OK; } /* ---------------------------------------------------------------------- _svmh_parse_method_attribute ---------------------------------------------------------------------- */ #define _svmm_parse_method_attribute(env,cli,current,size,class,attribute) \ _svmh_parse_method_attribute (env, cli, ¤t, &size, class, &attribute) svm_static jint _svmh_parse_method_attribute (_svmt_JNIEnv *env, _svmt_class_loader_info *class_loader_info, _svmt_u8 **pcurrent, size_t *psize, _svmt_class_info *class, _svmt_attribute_info **pattribute) { _svmt_CONSTANT_Utf8_info **attribute_name; jlong length; size_t old_size; char *name; /* attribute name */ if (_svmm_parse_cp_index_CONSTANT_Utf8 (env, *pcurrent, *psize, class, attribute_name) != JNI_OK) { return JNI_ERR; } if (CANNOT_DREF (attribute_name) || DREF (attribute_name, tag) != SVM_CONSTANT_Utf8) { _svmf_error_ClassFormatError (env); return JNI_ERR; } name = DREF (attribute_name, value); if (_svmm_parse_u32 (env, *pcurrent, *psize, length) != JNI_OK) { return JNI_ERR; } old_size = *psize; /* parse attributes *[::]/ m4svm_off() m4svm_parse_attribute_if(Code) m4svm_parse_attribute_elseif(Exceptions) m4svm_parse_attribute_elseif(Synthetic) m4svm_parse_attribute_elseif(Deprecated) m4svm_parse_attribute_else(unknown) m4svm_on(0)m4_dnl */ if (old_size - length != *psize) { _svmf_error_ClassFormatError (env); return JNI_ERR; } return JNI_OK; } /* ---------------------------------------------------------------------- _svmh_parse_class_attribute ---------------------------------------------------------------------- */ #define _svmm_parse_class_attribute(env,cli,current,size,class,attribute) \ _svmh_parse_class_attribute (env, cli, ¤t, &size, class, &attribute) svm_static jint _svmh_parse_class_attribute (_svmt_JNIEnv *env, _svmt_class_loader_info *class_loader_info, _svmt_u8 **pcurrent, size_t *psize, _svmt_class_info *class, _svmt_attribute_info **pattribute) { _svmt_CONSTANT_Utf8_info **attribute_name; jlong length; size_t old_size; char *name; /* attribute name */ if (_svmm_parse_cp_index_CONSTANT_Utf8 (env, *pcurrent, *psize, class, attribute_name) != JNI_OK) { return JNI_ERR; } if (CANNOT_DREF (attribute_name) || DREF (attribute_name, tag) != SVM_CONSTANT_Utf8) { _svmf_error_ClassFormatError (env); return JNI_ERR; } name = DREF (attribute_name, value); if (_svmm_parse_u32 (env, *pcurrent, *psize, length) != JNI_OK) { return JNI_ERR; } old_size = *psize; /* parse attributes *[::]/ m4svm_off() m4svm_parse_attribute_if(SourceFile) m4svm_parse_attribute_elseif(Deprecated) m4svm_parse_attribute_elseif(InnerClasses) m4svm_parse_attribute_else(unknown) m4svm_on(0)m4_dnl */ if (old_size - length != *psize) { _svmf_error_ClassFormatError (env); return JNI_ERR; } return JNI_OK; } /* ---------------------------------------------------------------------- _svmh_parse_class_file ---------------------------------------------------------------------- */ svm_static jint _svmh_parse_class_file (_svmt_JNIEnv *env, _svmt_class_loader_info *class_loader_info, size_t class_file_length, _svmt_u8 *class_file_bytes, _svmt_class_info **pclass) { _svmt_class_info *class; size_t size = class_file_length; _svmt_u8 *current = class_file_bytes; if (_svmm_cl_zalloc_class_info (env, class_loader_info, class) != JNI_OK) { return JNI_ERR; } class->class_loader_info = class_loader_info; class->is_array = JNI_FALSE; /* magic, version, constant pool count */ { jlong magic; if (_svmm_parse_u32 (env, current, size, magic) != JNI_OK) { return JNI_ERR; } if (magic != 0xCAFEBABE) { _svmf_error_ClassFormatError (env); return JNI_ERR; } } if (_svmm_parse_u16 (env, current, size, class->minor_version) != JNI_OK) { return JNI_ERR; } if (_svmm_parse_u16 (env, current, size, class->major_version) != JNI_OK) { return JNI_ERR; } if (_svmm_parse_u16 (env, current, size, class->constant_pool_count) != JNI_OK) { return JNI_ERR; } if (class->constant_pool_count < 1) { _svmf_error_ClassFormatError (env); return JNI_ERR; } /* constant_pool */ if (_svmm_cl_malloc_constant_pool (env, class_loader_info, class->constant_pool_count, class->constant_pool) != JNI_OK) { return JNI_ERR; } { jint entry; _svmt_cp_info **constant_pool = class->constant_pool; constant_pool[0] = NULL; for (entry = 1; entry < class->constant_pool_count; entry++) { if (_svmm_parse_constant_pool_entry (env, class_loader_info, current, size, class, constant_pool[entry]) != JNI_OK) { return JNI_ERR; } if (constant_pool[entry]->tag == SVM_CONSTANT_Long || constant_pool[entry]->tag == SVM_CONSTANT_Double) { if (++entry >= class->constant_pool_count) { _svmf_error_ClassFormatError (env); return JNI_ERR; } } } } /* access flags, this_class, super_class, interfaces_count */ if (_svmm_parse_u16 (env, current, size, class->access_flags) != JNI_OK) { return JNI_ERR; } if (_svmm_parse_cp_index_CONSTANT_Class (env, current, size, class, class->this_class) != JNI_OK) { return JNI_ERR; } if (_svmm_parse_cp_index_CONSTANT_Class (env, current, size, class, class->super_class) != JNI_OK) { return JNI_ERR; } if (_svmm_parse_u16 (env, current, size, class->interfaces_count) != JNI_OK) { return JNI_ERR; } /* interfaces */ if (class->interfaces_count > 0) { jint i; jint interfaces_count = class->interfaces_count; _svmt_CONSTANT_Class_info ***interfaces; if (_svmm_cl_malloc_classes (env, class_loader_info, interfaces_count, class->interfaces) != JNI_OK) { return JNI_ERR; } interfaces = class->interfaces; for (i = 0; i < interfaces_count; i++) { if (_svmm_parse_cp_index_CONSTANT_Class (env, current, size, class, interfaces[i]) != JNI_OK) { return JNI_ERR; } } } /* fields_count */ if (_svmm_parse_u16 (env, current, size, class->fields_count) != JNI_OK) { return JNI_ERR; } /* fields */ if (class->fields_count > 0) { jint fields_count = class->fields_count; jint i; if (_svmm_cl_zmalloc_fields (env, class_loader_info, fields_count, class->fields) != JNI_OK) { return JNI_ERR; } for (i = 0; i < fields_count; i++) { _svmt_field_info *field = &class->fields[i]; /* access_flags, name_index, descriptor_index, attributes_count */ if (_svmm_parse_u16 (env, current, size, field->access_flags) != JNI_OK) { return JNI_ERR; } if (_svmm_parse_cp_index_CONSTANT_Utf8 (env, current, size, class, field->name) != JNI_OK) { return JNI_ERR; } if (_svmm_parse_cp_index_CONSTANT_Utf8 (env, current, size, class, field->descriptor) != JNI_OK) { return JNI_ERR; } if (_svmm_parse_u16 (env, current, size, field->attributes_count) != JNI_OK) { return JNI_ERR; } /* attributes */ if (field->attributes_count > 0) { jint attributes_count = field->attributes_count; jint attribute; _svmt_attribute_info **attributes; if (_svmm_cl_malloc_attributes (env, class_loader_info, attributes_count, field->attributes) != JNI_OK) { return JNI_ERR; } attributes = field->attributes; for (attribute = 0; attribute < attributes_count; attribute++) { if (_svmm_parse_field_attribute (env, class_loader_info, current, size, class, attributes[attribute]) != JNI_OK) { return JNI_ERR; } } } } } /* methods_count */ if (_svmm_parse_u16 (env, current, size, class->methods_count) != JNI_OK) { return JNI_ERR; } /* methods */ if (class->methods_count > 0) { jint methods_count = class->methods_count; jint i; if (_svmm_cl_zmalloc_methods (env, class_loader_info, methods_count, class->methods) != JNI_OK) { return JNI_ERR; } for (i = 0; i < methods_count; i++) { _svmt_method_info *method = &class->methods[i]; /* access_flags, name_index, descriptor_index, attributes_count */ if (_svmm_parse_u16 (env, current, size, method->access_flags) != JNI_OK) { return JNI_ERR; } if (_svmm_parse_cp_index_CONSTANT_Utf8 (env, current, size, class, method->name) != JNI_OK) { return JNI_ERR; } if (_svmm_parse_cp_index_CONSTANT_Utf8 (env, current, size, class, method->descriptor) != JNI_OK) { return JNI_ERR; } if (_svmm_parse_u16 (env, current, size, method->attributes_count) != JNI_OK) { return JNI_ERR; } /* attributes */ if (method->attributes_count > 0) { jint attributes_count = method->attributes_count; jint attribute; _svmt_attribute_info **attributes; if (_svmm_cl_malloc_attributes (env, class_loader_info, attributes_count, method->attributes) != JNI_OK) { return JNI_ERR; } attributes = method->attributes; for (attribute = 0; attribute < attributes_count; attribute++) { if (_svmm_parse_method_attribute (env, class_loader_info, current, size, class, attributes[attribute]) != JNI_OK) { return JNI_ERR; } } } } } /* attributes_count */ if (_svmm_parse_u16 (env, current, size, class->attributes_count) != JNI_OK) { return JNI_ERR; } /* attributes */ if (class->attributes_count > 0) { jint attributes_count = class->attributes_count; jint attribute; _svmt_attribute_info **attributes; if (_svmm_cl_malloc_attributes (env, class_loader_info, attributes_count, class->attributes) != JNI_OK) { return JNI_ERR; } attributes = class->attributes; for (attribute = 0; attribute < attributes_count; attribute++) { if (_svmm_parse_class_attribute (env, class_loader_info, current, size, class, attributes[attribute]) != JNI_OK) { return JNI_ERR; } } } if (size != 0) { _svmf_error_ClassFormatError (env); return JNI_ERR; } if (CANNOT_DREF (class->this_class) || DREF (class->this_class, tag) != SVM_CONSTANT_Class || CANNOT_DREF (DREF (class->this_class, name)) || DREF (DREF (class->this_class, name), tag) != SVM_CONSTANT_Utf8) { _svmf_error_ClassFormatError (env); return JNI_ERR; } class->name = DREF (DREF (class->this_class, name), value); if (_svmm_cl_malloc_chars (env, class_loader_info, DREF (DREF (class->this_class, name), length) + 4, class->array_type_name) != JNI_OK) { return JNI_ERR; } strcpy (class->array_type_name, "[L"); strcat (class->array_type_name, class->name); strcat (class->array_type_name, ";"); *pclass = class; return JNI_OK; }