comparison src/share/vm/classfile/classFileParser.cpp @ 7983:24a91505f9d5

8006949: Update hotspot for MethodParameters format change 8006907: Hotspot should reject classfiles with multiple MethodParameters attributes Summary: Update to Hotspot's processing of MethodParameters attributes in classfiles Reviewed-by: coleenp, jrose
author emc
date Mon, 04 Feb 2013 13:05:32 -0500
parents 22ead76da3f4
children 927a311d00f9
comparison
equal deleted inserted replaced
7981:ce5467120c84 7983:24a91505f9d5
1945 u2** localvariable_table_start; 1945 u2** localvariable_table_start;
1946 u2* localvariable_type_table_length; 1946 u2* localvariable_type_table_length;
1947 u2** localvariable_type_table_start; 1947 u2** localvariable_type_table_start;
1948 u2 method_parameters_length = 0; 1948 u2 method_parameters_length = 0;
1949 u1* method_parameters_data = NULL; 1949 u1* method_parameters_data = NULL;
1950 bool method_parameters_seen = false;
1951 bool method_parameters_four_byte_flags;
1950 bool parsed_code_attribute = false; 1952 bool parsed_code_attribute = false;
1951 bool parsed_checked_exceptions_attribute = false; 1953 bool parsed_checked_exceptions_attribute = false;
1952 bool parsed_stackmap_attribute = false; 1954 bool parsed_stackmap_attribute = false;
1953 // stackmap attribute - JDK1.5 1955 // stackmap attribute - JDK1.5
1954 Array<u1>* stackmap_data = NULL; 1956 Array<u1>* stackmap_data = NULL;
2155 checked_exceptions_start = 2157 checked_exceptions_start =
2156 parse_checked_exceptions(&checked_exceptions_length, 2158 parse_checked_exceptions(&checked_exceptions_length,
2157 method_attribute_length, 2159 method_attribute_length,
2158 cp, CHECK_(nullHandle)); 2160 cp, CHECK_(nullHandle));
2159 } else if (method_attribute_name == vmSymbols::tag_method_parameters()) { 2161 } else if (method_attribute_name == vmSymbols::tag_method_parameters()) {
2162 // reject multiple method parameters
2163 if (method_parameters_seen) {
2164 classfile_parse_error("Multiple MethodParameters attributes in class file %s", CHECK_(nullHandle));
2165 }
2166 method_parameters_seen = true;
2160 method_parameters_length = cfs->get_u1_fast(); 2167 method_parameters_length = cfs->get_u1_fast();
2161 // Track the actual size (note: this is written for clarity; a 2168 // Track the actual size (note: this is written for clarity; a
2162 // decent compiler will CSE and constant-fold this into a single 2169 // decent compiler will CSE and constant-fold this into a single
2163 // expression) 2170 // expression)
2164 u2 actual_size = 1; 2171 // Use the attribute length to figure out the size of flags
2172 if (method_attribute_length == (method_parameters_length * 6u) + 1u) {
2173 method_parameters_four_byte_flags = true;
2174 } else if (method_attribute_length == (method_parameters_length * 4u) + 1u) {
2175 method_parameters_four_byte_flags = false;
2176 } else {
2177 classfile_parse_error(
2178 "Invalid MethodParameters method attribute length %u in class file",
2179 method_attribute_length, CHECK_(nullHandle));
2180 }
2165 method_parameters_data = cfs->get_u1_buffer(); 2181 method_parameters_data = cfs->get_u1_buffer();
2166 actual_size += 2 * method_parameters_length;
2167 cfs->skip_u2_fast(method_parameters_length); 2182 cfs->skip_u2_fast(method_parameters_length);
2168 actual_size += 4 * method_parameters_length; 2183 if (method_parameters_four_byte_flags) {
2169 cfs->skip_u4_fast(method_parameters_length); 2184 cfs->skip_u4_fast(method_parameters_length);
2170 // Enforce attribute length 2185 } else {
2171 if (method_attribute_length != actual_size) { 2186 cfs->skip_u2_fast(method_parameters_length);
2172 classfile_parse_error(
2173 "Invalid MethodParameters method attribute length %u in class file %s",
2174 method_attribute_length, CHECK_(nullHandle));
2175 } 2187 }
2176 // ignore this attribute if it cannot be reflected 2188 // ignore this attribute if it cannot be reflected
2177 if (!SystemDictionary::Parameter_klass_loaded()) 2189 if (!SystemDictionary::Parameter_klass_loaded())
2178 method_parameters_length = 0; 2190 method_parameters_length = 0;
2179 } else if (method_attribute_name == vmSymbols::tag_synthetic()) { 2191 } else if (method_attribute_name == vmSymbols::tag_synthetic()) {
2314 } 2326 }
2315 2327
2316 // Copy method parameters 2328 // Copy method parameters
2317 if (method_parameters_length > 0) { 2329 if (method_parameters_length > 0) {
2318 MethodParametersElement* elem = m->constMethod()->method_parameters_start(); 2330 MethodParametersElement* elem = m->constMethod()->method_parameters_start();
2319 for(int i = 0; i < method_parameters_length; i++) { 2331 for (int i = 0; i < method_parameters_length; i++) {
2320 elem[i].name_cp_index = 2332 elem[i].name_cp_index = Bytes::get_Java_u2(method_parameters_data);
2321 Bytes::get_Java_u2(method_parameters_data);
2322 method_parameters_data += 2; 2333 method_parameters_data += 2;
2323 u4 flags = Bytes::get_Java_u4(method_parameters_data); 2334 if (method_parameters_four_byte_flags) {
2324 // This caused an alignment fault on Sparc, if flags was a u4 2335 elem[i].flags = Bytes::get_Java_u4(method_parameters_data);
2325 elem[i].flags_lo = extract_low_short_from_int(flags); 2336 method_parameters_data += 4;
2326 elem[i].flags_hi = extract_high_short_from_int(flags); 2337 } else {
2327 method_parameters_data += 4; 2338 elem[i].flags = Bytes::get_Java_u2(method_parameters_data);
2339 method_parameters_data += 2;
2340 }
2328 } 2341 }
2329 } 2342 }
2330 2343
2331 // Copy checked exceptions 2344 // Copy checked exceptions
2332 if (checked_exceptions_length > 0) { 2345 if (checked_exceptions_length > 0) {