2229 } |
2229 } |
2230 default: ShouldNotReachHere(); |
2230 default: ShouldNotReachHere(); |
2231 } |
2231 } |
2232 } |
2232 } |
2233 |
2233 |
|
2234 // Look at the method's handlers. If the bci is in the handler's try block |
|
2235 // then check if the handler_pc is already on the stack. If not, push it. |
|
2236 void ClassVerifier::push_handlers(ExceptionTable* exhandlers, |
|
2237 GrowableArray<u4>* handler_stack, |
|
2238 u4 bci) { |
|
2239 int exlength = exhandlers->length(); |
|
2240 for(int x = 0; x < exlength; x++) { |
|
2241 if (bci >= exhandlers->start_pc(x) && bci < exhandlers->end_pc(x)) { |
|
2242 handler_stack->append_if_missing(exhandlers->handler_pc(x)); |
|
2243 } |
|
2244 } |
|
2245 } |
|
2246 |
|
2247 // Return TRUE if all code paths starting with start_bc_offset end in |
|
2248 // bytecode athrow or loop. |
|
2249 bool ClassVerifier::ends_in_athrow(u4 start_bc_offset) { |
|
2250 ResourceMark rm; |
|
2251 // Create bytecode stream. |
|
2252 RawBytecodeStream bcs(method()); |
|
2253 u4 code_length = method()->code_size(); |
|
2254 bcs.set_start(start_bc_offset); |
|
2255 u4 target; |
|
2256 // Create stack for storing bytecode start offsets for if* and *switch. |
|
2257 GrowableArray<u4>* bci_stack = new GrowableArray<u4>(30); |
|
2258 // Create stack for handlers for try blocks containing this handler. |
|
2259 GrowableArray<u4>* handler_stack = new GrowableArray<u4>(30); |
|
2260 // Create list of visited branch opcodes (goto* and if*). |
|
2261 GrowableArray<u4>* visited_branches = new GrowableArray<u4>(30); |
|
2262 ExceptionTable exhandlers(_method()); |
|
2263 |
|
2264 while (true) { |
|
2265 if (bcs.is_last_bytecode()) { |
|
2266 // if no more starting offsets to parse or if at the end of the |
|
2267 // method then return false. |
|
2268 if ((bci_stack->is_empty()) || ((u4)bcs.end_bci() == code_length)) |
|
2269 return false; |
|
2270 // Pop a bytecode starting offset and scan from there. |
|
2271 bcs.set_start(bci_stack->pop()); |
|
2272 } |
|
2273 Bytecodes::Code opcode = bcs.raw_next(); |
|
2274 u4 bci = bcs.bci(); |
|
2275 |
|
2276 // If the bytecode is in a TRY block, push its handlers so they |
|
2277 // will get parsed. |
|
2278 push_handlers(&exhandlers, handler_stack, bci); |
|
2279 |
|
2280 switch (opcode) { |
|
2281 case Bytecodes::_if_icmpeq: |
|
2282 case Bytecodes::_if_icmpne: |
|
2283 case Bytecodes::_if_icmplt: |
|
2284 case Bytecodes::_if_icmpge: |
|
2285 case Bytecodes::_if_icmpgt: |
|
2286 case Bytecodes::_if_icmple: |
|
2287 case Bytecodes::_ifeq: |
|
2288 case Bytecodes::_ifne: |
|
2289 case Bytecodes::_iflt: |
|
2290 case Bytecodes::_ifge: |
|
2291 case Bytecodes::_ifgt: |
|
2292 case Bytecodes::_ifle: |
|
2293 case Bytecodes::_if_acmpeq: |
|
2294 case Bytecodes::_if_acmpne: |
|
2295 case Bytecodes::_ifnull: |
|
2296 case Bytecodes::_ifnonnull: |
|
2297 target = bcs.dest(); |
|
2298 if (visited_branches->contains(bci)) { |
|
2299 if (bci_stack->is_empty()) return true; |
|
2300 // Pop a bytecode starting offset and scan from there. |
|
2301 bcs.set_start(bci_stack->pop()); |
|
2302 } else { |
|
2303 if (target > bci) { // forward branch |
|
2304 if (target >= code_length) return false; |
|
2305 // Push the branch target onto the stack. |
|
2306 bci_stack->push(target); |
|
2307 // then, scan bytecodes starting with next. |
|
2308 bcs.set_start(bcs.next_bci()); |
|
2309 } else { // backward branch |
|
2310 // Push bytecode offset following backward branch onto the stack. |
|
2311 bci_stack->push(bcs.next_bci()); |
|
2312 // Check bytecodes starting with branch target. |
|
2313 bcs.set_start(target); |
|
2314 } |
|
2315 // Record target so we don't branch here again. |
|
2316 visited_branches->append(bci); |
|
2317 } |
|
2318 break; |
|
2319 |
|
2320 case Bytecodes::_goto: |
|
2321 case Bytecodes::_goto_w: |
|
2322 target = (opcode == Bytecodes::_goto ? bcs.dest() : bcs.dest_w()); |
|
2323 if (visited_branches->contains(bci)) { |
|
2324 if (bci_stack->is_empty()) return true; |
|
2325 // Been here before, pop new starting offset from stack. |
|
2326 bcs.set_start(bci_stack->pop()); |
|
2327 } else { |
|
2328 if (target >= code_length) return false; |
|
2329 // Continue scanning from the target onward. |
|
2330 bcs.set_start(target); |
|
2331 // Record target so we don't branch here again. |
|
2332 visited_branches->append(bci); |
|
2333 } |
|
2334 break; |
|
2335 |
|
2336 // Check that all switch alternatives end in 'athrow' bytecodes. Since it |
|
2337 // is difficult to determine where each switch alternative ends, parse |
|
2338 // each switch alternative until either hit a 'return', 'athrow', or reach |
|
2339 // the end of the method's bytecodes. This is gross but should be okay |
|
2340 // because: |
|
2341 // 1. tableswitch and lookupswitch byte codes in handlers for ctor explicit |
|
2342 // constructor invocations should be rare. |
|
2343 // 2. if each switch alternative ends in an athrow then the parsing should be |
|
2344 // short. If there is no athrow then it is bogus code, anyway. |
|
2345 case Bytecodes::_lookupswitch: |
|
2346 case Bytecodes::_tableswitch: |
|
2347 { |
|
2348 address aligned_bcp = (address) round_to((intptr_t)(bcs.bcp() + 1), jintSize); |
|
2349 u4 default_offset = Bytes::get_Java_u4(aligned_bcp) + bci; |
|
2350 int keys, delta; |
|
2351 if (opcode == Bytecodes::_tableswitch) { |
|
2352 jint low = (jint)Bytes::get_Java_u4(aligned_bcp + jintSize); |
|
2353 jint high = (jint)Bytes::get_Java_u4(aligned_bcp + 2*jintSize); |
|
2354 // This is invalid, but let the regular bytecode verifier |
|
2355 // report this because the user will get a better error message. |
|
2356 if (low > high) return true; |
|
2357 keys = high - low + 1; |
|
2358 delta = 1; |
|
2359 } else { |
|
2360 keys = (int)Bytes::get_Java_u4(aligned_bcp + jintSize); |
|
2361 delta = 2; |
|
2362 } |
|
2363 // Invalid, let the regular bytecode verifier deal with it. |
|
2364 if (keys < 0) return true; |
|
2365 |
|
2366 // Push the offset of the next bytecode onto the stack. |
|
2367 bci_stack->push(bcs.next_bci()); |
|
2368 |
|
2369 // Push the switch alternatives onto the stack. |
|
2370 for (int i = 0; i < keys; i++) { |
|
2371 u4 target = bci + (jint)Bytes::get_Java_u4(aligned_bcp+(3+i*delta)*jintSize); |
|
2372 if (target > code_length) return false; |
|
2373 bci_stack->push(target); |
|
2374 } |
|
2375 |
|
2376 // Start bytecode parsing for the switch at the default alternative. |
|
2377 if (default_offset > code_length) return false; |
|
2378 bcs.set_start(default_offset); |
|
2379 break; |
|
2380 } |
|
2381 |
|
2382 case Bytecodes::_return: |
|
2383 return false; |
|
2384 |
|
2385 case Bytecodes::_athrow: |
|
2386 { |
|
2387 if (bci_stack->is_empty()) { |
|
2388 if (handler_stack->is_empty()) { |
|
2389 return true; |
|
2390 } else { |
|
2391 // Parse the catch handlers for try blocks containing athrow. |
|
2392 bcs.set_start(handler_stack->pop()); |
|
2393 } |
|
2394 } else { |
|
2395 // Pop a bytecode offset and starting scanning from there. |
|
2396 bcs.set_start(bci_stack->pop()); |
|
2397 } |
|
2398 } |
|
2399 break; |
|
2400 |
|
2401 default: |
|
2402 ; |
|
2403 } // end switch |
|
2404 } // end while loop |
|
2405 |
|
2406 return false; |
|
2407 } |
|
2408 |
2234 void ClassVerifier::verify_invoke_init( |
2409 void ClassVerifier::verify_invoke_init( |
2235 RawBytecodeStream* bcs, u2 ref_class_index, VerificationType ref_class_type, |
2410 RawBytecodeStream* bcs, u2 ref_class_index, VerificationType ref_class_type, |
2236 StackMapFrame* current_frame, u4 code_length, bool *this_uninit, |
2411 StackMapFrame* current_frame, u4 code_length, bool *this_uninit, |
2237 constantPoolHandle cp, TRAPS) { |
2412 constantPoolHandle cp, TRAPS) { |
2238 u2 bci = bcs->bci(); |
2413 u2 bci = bcs->bci(); |
2248 TypeOrigin::implicit(current_type())), |
2423 TypeOrigin::implicit(current_type())), |
2249 "Bad <init> method call"); |
2424 "Bad <init> method call"); |
2250 return; |
2425 return; |
2251 } |
2426 } |
2252 |
2427 |
2253 // Make sure that this call is not done from within a TRY block because |
2428 // Check if this call is done from inside of a TRY block. If so, make |
2254 // that can result in returning an incomplete object. Simply checking |
2429 // sure that all catch clause paths end in a throw. Otherwise, this |
2255 // (bci >= start_pc) also ensures that this call is not done after a TRY |
2430 // can result in returning an incomplete object. |
2256 // block. That is also illegal because this call must be the first Java |
|
2257 // statement in the constructor. |
|
2258 ExceptionTable exhandlers(_method()); |
2431 ExceptionTable exhandlers(_method()); |
2259 int exlength = exhandlers.length(); |
2432 int exlength = exhandlers.length(); |
2260 for(int i = 0; i < exlength; i++) { |
2433 for(int i = 0; i < exlength; i++) { |
2261 if (bci >= exhandlers.start_pc(i)) { |
2434 u2 start_pc = exhandlers.start_pc(i); |
2262 verify_error(ErrorContext::bad_code(bci), |
2435 u2 end_pc = exhandlers.end_pc(i); |
2263 "Bad <init> method call from after the start of a try block"); |
2436 |
2264 return; |
2437 if (bci >= start_pc && bci < end_pc) { |
|
2438 if (!ends_in_athrow(exhandlers.handler_pc(i))) { |
|
2439 verify_error(ErrorContext::bad_code(bci), |
|
2440 "Bad <init> method call from after the start of a try block"); |
|
2441 return; |
|
2442 } else if (VerboseVerification) { |
|
2443 ResourceMark rm; |
|
2444 tty->print_cr( |
|
2445 "Survived call to ends_in_athrow(): %s", |
|
2446 current_class()->name()->as_C_string()); |
|
2447 } |
2265 } |
2448 } |
2266 } |
2449 } |
2267 |
2450 |
2268 current_frame->initialize_object(type, current_type()); |
2451 current_frame->initialize_object(type, current_type()); |
2269 *this_uninit = true; |
2452 *this_uninit = true; |