Mercurial > hg > graal-jvmci-8
comparison src/share/vm/runtime/javaCalls.cpp @ 465:dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
Summary: Fix adds support for verifying arguments with -Xcheck:jni.
Reviewed-by: coleenp
author | poonam |
---|---|
date | Thu, 04 Dec 2008 17:29:56 -0800 |
parents | a61af66fc99e |
children | ad8c8ca4ab0f c6065343356f |
comparison
equal
deleted
inserted
replaced
414:348be627a148 | 465:dc16daa0329d |
---|---|
307 assert(!thread->handle_area()->no_handle_mark_active(), "cannot call out to Java here"); | 307 assert(!thread->handle_area()->no_handle_mark_active(), "cannot call out to Java here"); |
308 | 308 |
309 | 309 |
310 CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();) | 310 CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();) |
311 | 311 |
312 // Make sure that the arguments have the right type | 312 // Verify the arguments |
313 debug_only(args->verify(method, result->get_type(), thread)); | 313 |
314 if (CheckJNICalls) { | |
315 args->verify(method, result->get_type(), thread); | |
316 } | |
317 else debug_only(args->verify(method, result->get_type(), thread)); | |
314 | 318 |
315 // Ignore call if method is empty | 319 // Ignore call if method is empty |
316 if (method->is_empty_method()) { | 320 if (method->is_empty_method()) { |
317 assert(result->get_type() == T_VOID, "an empty method must return a void value"); | 321 assert(result->get_type() == T_VOID, "an empty method must return a void value"); |
318 return; | 322 return; |
429 } | 433 } |
430 // Return argument vector | 434 // Return argument vector |
431 return TaggedStackInterpreter ? _parameters : _value; | 435 return TaggedStackInterpreter ? _parameters : _value; |
432 } | 436 } |
433 | 437 |
434 //-------------------------------------------------------------------------------------- | |
435 // Non-Product code | |
436 #ifndef PRODUCT | |
437 | 438 |
438 class SignatureChekker : public SignatureIterator { | 439 class SignatureChekker : public SignatureIterator { |
439 private: | 440 private: |
440 bool *_is_oop; | 441 bool *_is_oop; |
441 int _pos; | 442 int _pos; |
442 BasicType _return_type; | 443 BasicType _return_type; |
444 intptr_t* _value; | |
445 Thread* _thread; | |
443 | 446 |
444 public: | 447 public: |
445 bool _is_return; | 448 bool _is_return; |
446 | 449 |
447 SignatureChekker(symbolHandle signature, BasicType return_type, bool is_static, bool* is_oop) : SignatureIterator(signature) { | 450 SignatureChekker(symbolHandle signature, BasicType return_type, bool is_static, bool* is_oop, intptr_t* value, Thread* thread) : SignatureIterator(signature) { |
448 _is_oop = is_oop; | 451 _is_oop = is_oop; |
449 _is_return = false; | 452 _is_return = false; |
450 _return_type = return_type; | 453 _return_type = return_type; |
451 _pos = 0; | 454 _pos = 0; |
455 _value = value; | |
456 _thread = thread; | |
457 | |
452 if (!is_static) { | 458 if (!is_static) { |
453 check_value(true); // Receiver must be an oop | 459 check_value(true); // Receiver must be an oop |
454 } | 460 } |
455 } | 461 } |
456 | 462 |
487 void check_obj(BasicType t) { | 493 void check_obj(BasicType t) { |
488 if (_is_return) { | 494 if (_is_return) { |
489 check_return_type(t); | 495 check_return_type(t); |
490 return; | 496 return; |
491 } | 497 } |
498 | |
499 // verify handle and the oop pointed to by handle | |
500 int p = _pos; | |
501 bool bad = false; | |
502 // If argument is oop | |
503 if (_is_oop[p]) { | |
504 intptr_t v = _value[p]; | |
505 if (v != 0 ) { | |
506 size_t t = (size_t)v; | |
507 bad = (t < (size_t)os::vm_page_size() ) || !(*(oop*)v)->is_oop_or_null(true); | |
508 if (CheckJNICalls && bad) { | |
509 ReportJNIFatalError((JavaThread*)_thread, "Bad JNI oop argument"); | |
510 } | |
511 } | |
512 // for the regular debug case. | |
513 assert(!bad, "Bad JNI oop argument"); | |
514 } | |
515 | |
492 check_value(true); | 516 check_value(true); |
493 } | 517 } |
494 | 518 |
495 void do_bool() { check_int(T_BOOLEAN); } | 519 void do_bool() { check_int(T_BOOLEAN); } |
496 void do_char() { check_int(T_CHAR); } | 520 void do_char() { check_int(T_CHAR); } |
503 void do_void() { check_return_type(T_VOID); } | 527 void do_void() { check_return_type(T_VOID); } |
504 void do_object(int begin, int end) { check_obj(T_OBJECT); } | 528 void do_object(int begin, int end) { check_obj(T_OBJECT); } |
505 void do_array(int begin, int end) { check_obj(T_OBJECT); } | 529 void do_array(int begin, int end) { check_obj(T_OBJECT); } |
506 }; | 530 }; |
507 | 531 |
532 | |
508 void JavaCallArguments::verify(methodHandle method, BasicType return_type, | 533 void JavaCallArguments::verify(methodHandle method, BasicType return_type, |
509 Thread *thread) { | 534 Thread *thread) { |
510 guarantee(method->size_of_parameters() == size_of_parameters(), "wrong no. of arguments pushed"); | 535 guarantee(method->size_of_parameters() == size_of_parameters(), "wrong no. of arguments pushed"); |
511 | 536 |
512 // Treat T_OBJECT and T_ARRAY as the same | 537 // Treat T_OBJECT and T_ARRAY as the same |
513 if (return_type == T_ARRAY) return_type = T_OBJECT; | 538 if (return_type == T_ARRAY) return_type = T_OBJECT; |
514 | 539 |
515 // Check that oop information is correct | 540 // Check that oop information is correct |
516 symbolHandle signature (thread, method->signature()); | 541 symbolHandle signature (thread, method->signature()); |
517 | 542 |
518 SignatureChekker sc(signature, return_type, method->is_static(),_is_oop); | 543 SignatureChekker sc(signature, return_type, method->is_static(),_is_oop, _value, thread); |
519 sc.iterate_parameters(); | 544 sc.iterate_parameters(); |
520 sc.check_doing_return(true); | 545 sc.check_doing_return(true); |
521 sc.iterate_returntype(); | 546 sc.iterate_returntype(); |
522 } | 547 } |
523 | 548 |
524 #endif // PRODUCT |