< prev index next >

src/hotspot/share/classfile/classFileParser.cpp

Print this page
rev 48343 : imported patch JDK-8173382-classfile-version


  69 #include "utilities/bitMap.inline.hpp"
  70 #include "utilities/exceptions.hpp"
  71 #include "utilities/globalDefinitions.hpp"
  72 #include "utilities/growableArray.hpp"
  73 #include "utilities/macros.hpp"
  74 #include "utilities/ostream.hpp"
  75 #include "utilities/resourceHash.hpp"
  76 #if INCLUDE_CDS
  77 #include "classfile/systemDictionaryShared.hpp"
  78 #endif
  79 
  80 // We generally try to create the oops directly when parsing, rather than
  81 // allocating temporary data structures and copying the bytes twice. A
  82 // temporary area is only needed when parsing utf8 entries in the constant
  83 // pool and when parsing line number tables.
  84 
  85 // We add assert in debug mode when class format is not checked.
  86 
  87 #define JAVA_CLASSFILE_MAGIC              0xCAFEBABE
  88 #define JAVA_MIN_SUPPORTED_VERSION        45
  89 #define JAVA_MAX_SUPPORTED_VERSION        54
  90 #define JAVA_MAX_SUPPORTED_MINOR_VERSION  0
  91 
  92 // Used for two backward compatibility reasons:
  93 // - to check for new additions to the class file format in JDK1.5
  94 // - to check for bug fixes in the format checker in JDK1.5
  95 #define JAVA_1_5_VERSION                  49
  96 
  97 // Used for backward compatibility reasons:
  98 // - to check for javac bug fixes that happened after 1.5
  99 // - also used as the max version when running in jdk6
 100 #define JAVA_6_VERSION                    50
 101 
 102 // Used for backward compatibility reasons:
 103 // - to disallow argument and require ACC_STATIC for <clinit> methods
 104 #define JAVA_7_VERSION                    51
 105 
 106 // Extension method support.
 107 #define JAVA_8_VERSION                    52
 108 
 109 #define JAVA_9_VERSION                    53
 110 
 111 #define JAVA_10_VERSION                   54
 112 


 113 void ClassFileParser::set_class_bad_constant_seen(short bad_constant) {
 114   assert((bad_constant == 19 || bad_constant == 20) && _major_version >= JAVA_9_VERSION,
 115          "Unexpected bad constant pool entry");
 116   if (_bad_constant_seen == 0) _bad_constant_seen = bad_constant;
 117 }
 118 
 119 void ClassFileParser::parse_constant_pool_entries(const ClassFileStream* const stream,
 120                                                   ConstantPool* cp,
 121                                                   const int length,
 122                                                   TRAPS) {
 123   assert(stream != NULL, "invariant");
 124   assert(cp != NULL, "invariant");
 125 
 126   // Use a local copy of ClassFileStream. It helps the C++ compiler to optimize
 127   // this function (_current can be allocated in a register, with scalar
 128   // replacement of aggregates). The _current pointer is copied back to
 129   // stream() when this function returns. DON'T call another method within
 130   // this method that uses stream().
 131   const ClassFileStream cfs1 = *stream;
 132   const ClassFileStream* const cfs = &cfs1;


4625       THREAD_AND_LOCATION,
4626       vmSymbols::java_lang_ClassFormatError(),
4627       "Illegal class modifiers in class %s: 0x%X",
4628       _class_name->as_C_string(), flags
4629     );
4630     return;
4631   }
4632 }
4633 
4634 static bool has_illegal_visibility(jint flags) {
4635   const bool is_public    = (flags & JVM_ACC_PUBLIC)    != 0;
4636   const bool is_protected = (flags & JVM_ACC_PROTECTED) != 0;
4637   const bool is_private   = (flags & JVM_ACC_PRIVATE)   != 0;
4638 
4639   return ((is_public && is_protected) ||
4640           (is_public && is_private) ||
4641           (is_protected && is_private));
4642 }
4643 
4644 static bool is_supported_version(u2 major, u2 minor){
4645   const u2 max_version = JAVA_MAX_SUPPORTED_VERSION;
4646   return (major >= JAVA_MIN_SUPPORTED_VERSION) &&
4647          (major <= max_version) &&
4648          ((major != max_version) ||
4649           (minor <= JAVA_MAX_SUPPORTED_MINOR_VERSION));
4650 }
4651 
4652 void ClassFileParser::verify_legal_field_modifiers(jint flags,
4653                                                    bool is_interface,
4654                                                    TRAPS) const {
4655   if (!_need_verify) { return; }
4656 
4657   const bool is_public    = (flags & JVM_ACC_PUBLIC)    != 0;
4658   const bool is_protected = (flags & JVM_ACC_PROTECTED) != 0;
4659   const bool is_private   = (flags & JVM_ACC_PRIVATE)   != 0;
4660   const bool is_static    = (flags & JVM_ACC_STATIC)    != 0;
4661   const bool is_final     = (flags & JVM_ACC_FINAL)     != 0;
4662   const bool is_volatile  = (flags & JVM_ACC_VOLATILE)  != 0;
4663   const bool is_transient = (flags & JVM_ACC_TRANSIENT) != 0;
4664   const bool is_enum      = (flags & JVM_ACC_ENUM)      != 0;
4665   const bool major_gte_15 = _major_version >= JAVA_1_5_VERSION;
4666 
4667   bool is_illegal = false;
4668 
4669   if (is_interface) {


5791             _major_version,  _minor_version, _class_name->as_C_string());
5792     Exceptions::fthrow(
5793       THREAD_AND_LOCATION,
5794       vmSymbols::java_lang_UnsupportedClassVersionError(),
5795       "Unsupported major.minor version for dump time %u.%u",
5796       _major_version,
5797       _minor_version);
5798   }
5799 
5800   // Check version numbers - we check this even with verifier off
5801   if (!is_supported_version(_major_version, _minor_version)) {
5802     ResourceMark rm(THREAD);
5803     Exceptions::fthrow(
5804       THREAD_AND_LOCATION,
5805       vmSymbols::java_lang_UnsupportedClassVersionError(),
5806       "%s has been compiled by a more recent version of the Java Runtime (class file version %u.%u), "
5807       "this version of the Java Runtime only recognizes class file versions up to %u.%u",
5808       _class_name->as_C_string(),
5809       _major_version,
5810       _minor_version,
5811       JAVA_MAX_SUPPORTED_VERSION,
5812       JAVA_MAX_SUPPORTED_MINOR_VERSION);
5813     return;
5814   }
5815 
5816   stream->guarantee_more(3, CHECK); // length, first cp tag
5817   u2 cp_size = stream->get_u2_fast();
5818 
5819   guarantee_property(
5820     cp_size >= 1, "Illegal constant pool size %u in class file %s",
5821     cp_size, CHECK);
5822 
5823   _orig_cp_size = cp_size;
5824   if (int(cp_size) + _max_num_patched_klasses > 0xffff) {
5825     THROW_MSG(vmSymbols::java_lang_InternalError(), "not enough space for patched classes");
5826   }
5827   cp_size += _max_num_patched_klasses;
5828 
5829   _cp = ConstantPool::allocate(_loader_data,
5830                                cp_size,
5831                                CHECK);
5832 




  69 #include "utilities/bitMap.inline.hpp"
  70 #include "utilities/exceptions.hpp"
  71 #include "utilities/globalDefinitions.hpp"
  72 #include "utilities/growableArray.hpp"
  73 #include "utilities/macros.hpp"
  74 #include "utilities/ostream.hpp"
  75 #include "utilities/resourceHash.hpp"
  76 #if INCLUDE_CDS
  77 #include "classfile/systemDictionaryShared.hpp"
  78 #endif
  79 
  80 // We generally try to create the oops directly when parsing, rather than
  81 // allocating temporary data structures and copying the bytes twice. A
  82 // temporary area is only needed when parsing utf8 entries in the constant
  83 // pool and when parsing line number tables.
  84 
  85 // We add assert in debug mode when class format is not checked.
  86 
  87 #define JAVA_CLASSFILE_MAGIC              0xCAFEBABE
  88 #define JAVA_MIN_SUPPORTED_VERSION        45


  89 
  90 // Used for two backward compatibility reasons:
  91 // - to check for new additions to the class file format in JDK1.5
  92 // - to check for bug fixes in the format checker in JDK1.5
  93 #define JAVA_1_5_VERSION                  49
  94 
  95 // Used for backward compatibility reasons:
  96 // - to check for javac bug fixes that happened after 1.5
  97 // - also used as the max version when running in jdk6
  98 #define JAVA_6_VERSION                    50
  99 
 100 // Used for backward compatibility reasons:
 101 // - to disallow argument and require ACC_STATIC for <clinit> methods
 102 #define JAVA_7_VERSION                    51
 103 
 104 // Extension method support.
 105 #define JAVA_8_VERSION                    52
 106 
 107 #define JAVA_9_VERSION                    53
 108 
 109 #define JAVA_10_VERSION                   54
 110 
 111 #define JAVA_11_VERSION                   55
 112 
 113 void ClassFileParser::set_class_bad_constant_seen(short bad_constant) {
 114   assert((bad_constant == 19 || bad_constant == 20) && _major_version >= JAVA_9_VERSION,
 115          "Unexpected bad constant pool entry");
 116   if (_bad_constant_seen == 0) _bad_constant_seen = bad_constant;
 117 }
 118 
 119 void ClassFileParser::parse_constant_pool_entries(const ClassFileStream* const stream,
 120                                                   ConstantPool* cp,
 121                                                   const int length,
 122                                                   TRAPS) {
 123   assert(stream != NULL, "invariant");
 124   assert(cp != NULL, "invariant");
 125 
 126   // Use a local copy of ClassFileStream. It helps the C++ compiler to optimize
 127   // this function (_current can be allocated in a register, with scalar
 128   // replacement of aggregates). The _current pointer is copied back to
 129   // stream() when this function returns. DON'T call another method within
 130   // this method that uses stream().
 131   const ClassFileStream cfs1 = *stream;
 132   const ClassFileStream* const cfs = &cfs1;


4625       THREAD_AND_LOCATION,
4626       vmSymbols::java_lang_ClassFormatError(),
4627       "Illegal class modifiers in class %s: 0x%X",
4628       _class_name->as_C_string(), flags
4629     );
4630     return;
4631   }
4632 }
4633 
4634 static bool has_illegal_visibility(jint flags) {
4635   const bool is_public    = (flags & JVM_ACC_PUBLIC)    != 0;
4636   const bool is_protected = (flags & JVM_ACC_PROTECTED) != 0;
4637   const bool is_private   = (flags & JVM_ACC_PRIVATE)   != 0;
4638 
4639   return ((is_public && is_protected) ||
4640           (is_public && is_private) ||
4641           (is_protected && is_private));
4642 }
4643 
4644 static bool is_supported_version(u2 major, u2 minor){
4645   const u2 max_version = JVM_CLASSFILE_MAJOR_VERSION;
4646   return (major >= JAVA_MIN_SUPPORTED_VERSION) &&
4647          (major <= max_version) &&
4648          ((major != max_version) ||
4649           (minor <= JVM_CLASSFILE_MINOR_VERSION));
4650 }
4651 
4652 void ClassFileParser::verify_legal_field_modifiers(jint flags,
4653                                                    bool is_interface,
4654                                                    TRAPS) const {
4655   if (!_need_verify) { return; }
4656 
4657   const bool is_public    = (flags & JVM_ACC_PUBLIC)    != 0;
4658   const bool is_protected = (flags & JVM_ACC_PROTECTED) != 0;
4659   const bool is_private   = (flags & JVM_ACC_PRIVATE)   != 0;
4660   const bool is_static    = (flags & JVM_ACC_STATIC)    != 0;
4661   const bool is_final     = (flags & JVM_ACC_FINAL)     != 0;
4662   const bool is_volatile  = (flags & JVM_ACC_VOLATILE)  != 0;
4663   const bool is_transient = (flags & JVM_ACC_TRANSIENT) != 0;
4664   const bool is_enum      = (flags & JVM_ACC_ENUM)      != 0;
4665   const bool major_gte_15 = _major_version >= JAVA_1_5_VERSION;
4666 
4667   bool is_illegal = false;
4668 
4669   if (is_interface) {


5791             _major_version,  _minor_version, _class_name->as_C_string());
5792     Exceptions::fthrow(
5793       THREAD_AND_LOCATION,
5794       vmSymbols::java_lang_UnsupportedClassVersionError(),
5795       "Unsupported major.minor version for dump time %u.%u",
5796       _major_version,
5797       _minor_version);
5798   }
5799 
5800   // Check version numbers - we check this even with verifier off
5801   if (!is_supported_version(_major_version, _minor_version)) {
5802     ResourceMark rm(THREAD);
5803     Exceptions::fthrow(
5804       THREAD_AND_LOCATION,
5805       vmSymbols::java_lang_UnsupportedClassVersionError(),
5806       "%s has been compiled by a more recent version of the Java Runtime (class file version %u.%u), "
5807       "this version of the Java Runtime only recognizes class file versions up to %u.%u",
5808       _class_name->as_C_string(),
5809       _major_version,
5810       _minor_version,
5811       JVM_CLASSFILE_MAJOR_VERSION,
5812       JVM_CLASSFILE_MINOR_VERSION);
5813     return;
5814   }
5815 
5816   stream->guarantee_more(3, CHECK); // length, first cp tag
5817   u2 cp_size = stream->get_u2_fast();
5818 
5819   guarantee_property(
5820     cp_size >= 1, "Illegal constant pool size %u in class file %s",
5821     cp_size, CHECK);
5822 
5823   _orig_cp_size = cp_size;
5824   if (int(cp_size) + _max_num_patched_klasses > 0xffff) {
5825     THROW_MSG(vmSymbols::java_lang_InternalError(), "not enough space for patched classes");
5826   }
5827   cp_size += _max_num_patched_klasses;
5828 
5829   _cp = ConstantPool::allocate(_loader_data,
5830                                cp_size,
5831                                CHECK);
5832 


< prev index next >