< prev index next >

src/hotspot/share/interpreter/linkResolver.cpp

Print this page
rev 50800 : 8199940: Print more information about class loaders in IllegalAccessErrors.
Reviewed-by: lfoltan, mchung


 201 
 202 #ifdef ASSERT
 203 void CallInfo::verify() {
 204   switch (call_kind()) {  // the meaning and allowed value of index depends on kind
 205   case CallInfo::direct_call:
 206     if (_call_index == Method::nonvirtual_vtable_index)  break;
 207     // else fall through to check vtable index:
 208   case CallInfo::vtable_call:
 209     assert(resolved_klass()->verify_vtable_index(_call_index), "");
 210     break;
 211   case CallInfo::itable_call:
 212     assert(resolved_method()->method_holder()->verify_itable_index(_call_index), "");
 213     break;
 214   case CallInfo::unknown_kind:
 215     assert(call_kind() != CallInfo::unknown_kind, "CallInfo must be set");
 216     break;
 217   default:
 218     fatal("Unexpected call kind %d", call_kind());
 219   }
 220 }
 221 #endif //ASSERT
 222 
 223 #ifndef PRODUCT
 224 void CallInfo::print() {
 225   ResourceMark rm;
 226   const char* kindstr;
 227   switch (_call_kind) {
 228   case direct_call: kindstr = "direct";  break;
 229   case vtable_call: kindstr = "vtable";  break;
 230   case itable_call: kindstr = "itable";  break;
 231   default         : kindstr = "unknown"; break;
 232   }
 233   tty->print_cr("Call %s@%d %s", kindstr, _call_index,
 234                 _resolved_method.is_null() ? "(none)" : _resolved_method->name_and_sig_as_C_string());
 235 }
 236 #endif
 237 
 238 //------------------------------------------------------------------------------------------------------------------------
 239 // Implementation of LinkInfo
 240 
 241 LinkInfo::LinkInfo(const constantPoolHandle& pool, int index, const methodHandle& current_method, TRAPS) {


 277   ResourceMark rm;
 278   tty->print_cr("Link resolved_klass=%s name=%s signature=%s current_klass=%s check_access=%s",
 279                 _resolved_klass->name()->as_C_string(),
 280                 _name->as_C_string(),
 281                 _signature->as_C_string(),
 282                 _current_klass == NULL ? "(none)" : _current_klass->name()->as_C_string(),
 283                 _check_access ? "true" : "false");
 284 }
 285 #endif // PRODUCT
 286 //------------------------------------------------------------------------------------------------------------------------
 287 // Klass resolution
 288 
 289 void LinkResolver::check_klass_accessability(Klass* ref_klass, Klass* sel_klass,
 290                                              bool fold_type_to_class, TRAPS) {
 291   Klass* base_klass = sel_klass;
 292   if (fold_type_to_class) {
 293     if (sel_klass->is_objArray_klass()) {
 294       base_klass = ObjArrayKlass::cast(sel_klass)->bottom_klass();
 295     }
 296     // The element type could be a typeArray - we only need the access
 297     // check if it is an reference to another class.
 298     if (!base_klass->is_instance_klass()) {
 299       return;  // no relevant check to do
 300     }
 301   }
 302   Reflection::VerifyClassAccessResults vca_result =
 303     Reflection::verify_class_access(ref_klass, InstanceKlass::cast(base_klass), true);
 304   if (vca_result != Reflection::ACCESS_OK) {
 305     ResourceMark rm(THREAD);
 306     char* msg = Reflection::verify_class_access_msg(ref_klass,
 307                                                     InstanceKlass::cast(base_klass),
 308                                                     vca_result);

 309     if (msg == NULL) {
 310       Exceptions::fthrow(
 311         THREAD_AND_LOCATION,
 312         vmSymbols::java_lang_IllegalAccessError(),
 313         "failed to access class %s from class %s",
 314         base_klass->external_name(),
 315         ref_klass->external_name());



 316     } else {
 317       // Use module specific message returned by verify_class_access_msg().
 318       Exceptions::fthrow(
 319         THREAD_AND_LOCATION,
 320         vmSymbols::java_lang_IllegalAccessError(),
 321         "%s", msg);
 322     }
 323   }
 324 }
 325 
 326 //------------------------------------------------------------------------------------------------------------------------
 327 // Method resolution
 328 //
 329 // According to JVM spec. $5.4.3c & $5.4.3d
 330 
 331 // Look up method in klasses, including static methods
 332 // Then look up local default methods
 333 Method* LinkResolver::lookup_method_in_klasses(const LinkInfo& link_info,
 334                                                bool checkpolymorphism,
 335                                                bool in_imethod_resolve) {


 579     jint new_flags = flags.as_int();
 580     new_flags = new_flags & (~JVM_ACC_PROTECTED);
 581     new_flags = new_flags | JVM_ACC_PUBLIC;
 582     flags.set_flags(new_flags);
 583   }
 584 //  assert(extra_arg_result_or_null != NULL, "must be able to return extra argument");
 585 
 586   bool can_access = Reflection::verify_member_access(ref_klass,
 587                                                      resolved_klass,
 588                                                      sel_klass,
 589                                                      flags,
 590                                                      true, false, CHECK);
 591   // Any existing exceptions that may have been thrown, for example LinkageErrors
 592   // from nest-host resolution, have been allowed to propagate.
 593   if (!can_access) {
 594     ResourceMark rm(THREAD);
 595     bool same_module = (sel_klass->module() == ref_klass->module());
 596     Exceptions::fthrow(
 597       THREAD_AND_LOCATION,
 598       vmSymbols::java_lang_IllegalAccessError(),
 599       "class %s tried to access method %s.%s%s (%s%s%s)",
 600       ref_klass->external_name(),



 601       sel_klass->external_name(),
 602       sel_method->name()->as_C_string(),
 603       sel_method->signature()->as_C_string(),
 604       (same_module) ? ref_klass->joint_in_module_of_loader(sel_klass) : ref_klass->class_in_module_of_loader(),
 605       (same_module) ? "" : "; ",
 606       (same_module) ? "" : sel_klass->class_in_module_of_loader()
 607     );
 608     return;
 609   }
 610 }
 611 
 612 methodHandle LinkResolver::resolve_method_statically(Bytecodes::Code code,
 613                                                      const constantPoolHandle& pool, int index, TRAPS) {
 614   // This method is used only
 615   // (1) in C2 from InlineTree::ok_to_inline (via ciMethod::check_call),
 616   // and
 617   // (2) in Bytecode_invoke::static_target
 618   // It appears to fail when applied to an invokeinterface call site.
 619   // FIXME: Remove this method and ciMethod::check_call; refactor to use the other LinkResolver entry points.
 620   // resolve klass


 910 
 911   return resolved_method;
 912 }
 913 
 914 //------------------------------------------------------------------------------------------------------------------------
 915 // Field resolution
 916 
 917 void LinkResolver::check_field_accessability(Klass* ref_klass,
 918                                              Klass* resolved_klass,
 919                                              Klass* sel_klass,
 920                                              const fieldDescriptor& fd,
 921                                              TRAPS) {
 922   bool can_access = Reflection::verify_member_access(ref_klass,
 923                                                      resolved_klass,
 924                                                      sel_klass,
 925                                                      fd.access_flags(),
 926                                                      true, false, CHECK);
 927   // Any existing exceptions that may have been thrown, for example LinkageErrors
 928   // from nest-host resolution, have been allowed to propagate.
 929   if (!can_access) {

 930     ResourceMark rm(THREAD);
 931     Exceptions::fthrow(
 932       THREAD_AND_LOCATION,
 933       vmSymbols::java_lang_IllegalAccessError(),
 934       "tried to access field %s.%s from class %s",



 935       sel_klass->external_name(),
 936       fd.name()->as_C_string(),
 937       ref_klass->external_name()


 938     );
 939     return;
 940   }
 941 }
 942 
 943 void LinkResolver::resolve_field_access(fieldDescriptor& fd, const constantPoolHandle& pool, int index, const methodHandle& method, Bytecodes::Code byte, TRAPS) {
 944   LinkInfo link_info(pool, index, method, CHECK);
 945   resolve_field(fd, link_info, byte, true, CHECK);
 946 }
 947 
 948 void LinkResolver::resolve_field(fieldDescriptor& fd,
 949                                  const LinkInfo& link_info,
 950                                  Bytecodes::Code byte, bool initialize_class,
 951                                  TRAPS) {
 952   assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic ||
 953          byte == Bytecodes::_getfield  || byte == Bytecodes::_putfield  ||
 954          byte == Bytecodes::_nofast_getfield  || byte == Bytecodes::_nofast_putfield  ||
 955          (byte == Bytecodes::_nop && !link_info.check_access()), "bad field access bytecode");
 956 
 957   bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic);




 201 
 202 #ifdef ASSERT
 203 void CallInfo::verify() {
 204   switch (call_kind()) {  // the meaning and allowed value of index depends on kind
 205   case CallInfo::direct_call:
 206     if (_call_index == Method::nonvirtual_vtable_index)  break;
 207     // else fall through to check vtable index:
 208   case CallInfo::vtable_call:
 209     assert(resolved_klass()->verify_vtable_index(_call_index), "");
 210     break;
 211   case CallInfo::itable_call:
 212     assert(resolved_method()->method_holder()->verify_itable_index(_call_index), "");
 213     break;
 214   case CallInfo::unknown_kind:
 215     assert(call_kind() != CallInfo::unknown_kind, "CallInfo must be set");
 216     break;
 217   default:
 218     fatal("Unexpected call kind %d", call_kind());
 219   }
 220 }
 221 #endif // ASSERT
 222 
 223 #ifndef PRODUCT
 224 void CallInfo::print() {
 225   ResourceMark rm;
 226   const char* kindstr;
 227   switch (_call_kind) {
 228   case direct_call: kindstr = "direct";  break;
 229   case vtable_call: kindstr = "vtable";  break;
 230   case itable_call: kindstr = "itable";  break;
 231   default         : kindstr = "unknown"; break;
 232   }
 233   tty->print_cr("Call %s@%d %s", kindstr, _call_index,
 234                 _resolved_method.is_null() ? "(none)" : _resolved_method->name_and_sig_as_C_string());
 235 }
 236 #endif
 237 
 238 //------------------------------------------------------------------------------------------------------------------------
 239 // Implementation of LinkInfo
 240 
 241 LinkInfo::LinkInfo(const constantPoolHandle& pool, int index, const methodHandle& current_method, TRAPS) {


 277   ResourceMark rm;
 278   tty->print_cr("Link resolved_klass=%s name=%s signature=%s current_klass=%s check_access=%s",
 279                 _resolved_klass->name()->as_C_string(),
 280                 _name->as_C_string(),
 281                 _signature->as_C_string(),
 282                 _current_klass == NULL ? "(none)" : _current_klass->name()->as_C_string(),
 283                 _check_access ? "true" : "false");
 284 }
 285 #endif // PRODUCT
 286 //------------------------------------------------------------------------------------------------------------------------
 287 // Klass resolution
 288 
 289 void LinkResolver::check_klass_accessability(Klass* ref_klass, Klass* sel_klass,
 290                                              bool fold_type_to_class, TRAPS) {
 291   Klass* base_klass = sel_klass;
 292   if (fold_type_to_class) {
 293     if (sel_klass->is_objArray_klass()) {
 294       base_klass = ObjArrayKlass::cast(sel_klass)->bottom_klass();
 295     }
 296     // The element type could be a typeArray - we only need the access
 297     // check if it is a reference to another class.
 298     if (!base_klass->is_instance_klass()) {
 299       return;  // no relevant check to do
 300     }
 301   }
 302   Reflection::VerifyClassAccessResults vca_result =
 303     Reflection::verify_class_access(ref_klass, InstanceKlass::cast(base_klass), true);
 304   if (vca_result != Reflection::ACCESS_OK) {
 305     ResourceMark rm(THREAD);
 306     char* msg = Reflection::verify_class_access_msg(ref_klass,
 307                                                     InstanceKlass::cast(base_klass),
 308                                                     vca_result);
 309     bool same_module = (base_klass->module() == ref_klass->module());
 310     if (msg == NULL) {
 311       Exceptions::fthrow(
 312         THREAD_AND_LOCATION,
 313         vmSymbols::java_lang_IllegalAccessError(),
 314         "failed to access class %s from class %s (%s%s%s)",
 315         base_klass->external_name(),
 316         ref_klass->external_name(),
 317         (same_module) ? base_klass->joint_in_module_of_loader(ref_klass) : base_klass->class_in_module_of_loader(),
 318         (same_module) ? "" : "; ",
 319         (same_module) ? "" : ref_klass->class_in_module_of_loader());
 320     } else {
 321       // Use module specific message returned by verify_class_access_msg().
 322       Exceptions::fthrow(
 323         THREAD_AND_LOCATION,
 324         vmSymbols::java_lang_IllegalAccessError(),
 325         "%s", msg);
 326     }
 327   }
 328 }
 329 
 330 //------------------------------------------------------------------------------------------------------------------------
 331 // Method resolution
 332 //
 333 // According to JVM spec. $5.4.3c & $5.4.3d
 334 
 335 // Look up method in klasses, including static methods
 336 // Then look up local default methods
 337 Method* LinkResolver::lookup_method_in_klasses(const LinkInfo& link_info,
 338                                                bool checkpolymorphism,
 339                                                bool in_imethod_resolve) {


 583     jint new_flags = flags.as_int();
 584     new_flags = new_flags & (~JVM_ACC_PROTECTED);
 585     new_flags = new_flags | JVM_ACC_PUBLIC;
 586     flags.set_flags(new_flags);
 587   }
 588 //  assert(extra_arg_result_or_null != NULL, "must be able to return extra argument");
 589 
 590   bool can_access = Reflection::verify_member_access(ref_klass,
 591                                                      resolved_klass,
 592                                                      sel_klass,
 593                                                      flags,
 594                                                      true, false, CHECK);
 595   // Any existing exceptions that may have been thrown, for example LinkageErrors
 596   // from nest-host resolution, have been allowed to propagate.
 597   if (!can_access) {
 598     ResourceMark rm(THREAD);
 599     bool same_module = (sel_klass->module() == ref_klass->module());
 600     Exceptions::fthrow(
 601       THREAD_AND_LOCATION,
 602       vmSymbols::java_lang_IllegalAccessError(),
 603       "class %s tried to access %s%s%smethod %s.%s%s (%s%s%s)",
 604       ref_klass->external_name(),
 605       sel_method->is_abstract()  ? "abstract "  : "",
 606       sel_method->is_protected() ? "protected " : "",
 607       sel_method->is_private()   ? "private "   : "",
 608       sel_klass->external_name(),
 609       sel_method->name()->as_C_string(),
 610       sel_method->signature()->as_C_string(),
 611       (same_module) ? ref_klass->joint_in_module_of_loader(sel_klass) : ref_klass->class_in_module_of_loader(),
 612       (same_module) ? "" : "; ",
 613       (same_module) ? "" : sel_klass->class_in_module_of_loader()
 614     );
 615     return;
 616   }
 617 }
 618 
 619 methodHandle LinkResolver::resolve_method_statically(Bytecodes::Code code,
 620                                                      const constantPoolHandle& pool, int index, TRAPS) {
 621   // This method is used only
 622   // (1) in C2 from InlineTree::ok_to_inline (via ciMethod::check_call),
 623   // and
 624   // (2) in Bytecode_invoke::static_target
 625   // It appears to fail when applied to an invokeinterface call site.
 626   // FIXME: Remove this method and ciMethod::check_call; refactor to use the other LinkResolver entry points.
 627   // resolve klass


 917 
 918   return resolved_method;
 919 }
 920 
 921 //------------------------------------------------------------------------------------------------------------------------
 922 // Field resolution
 923 
 924 void LinkResolver::check_field_accessability(Klass* ref_klass,
 925                                              Klass* resolved_klass,
 926                                              Klass* sel_klass,
 927                                              const fieldDescriptor& fd,
 928                                              TRAPS) {
 929   bool can_access = Reflection::verify_member_access(ref_klass,
 930                                                      resolved_klass,
 931                                                      sel_klass,
 932                                                      fd.access_flags(),
 933                                                      true, false, CHECK);
 934   // Any existing exceptions that may have been thrown, for example LinkageErrors
 935   // from nest-host resolution, have been allowed to propagate.
 936   if (!can_access) {
 937     bool same_module = (sel_klass->module() == ref_klass->module());
 938     ResourceMark rm(THREAD);
 939     Exceptions::fthrow(
 940       THREAD_AND_LOCATION,
 941       vmSymbols::java_lang_IllegalAccessError(),
 942       "class %s tried to access %s%sfield %s.%s (%s%s%s)",
 943       ref_klass->external_name(),
 944       fd.is_protected() ? "protected " : "",
 945       fd.is_private()   ? "private "   : "",
 946       sel_klass->external_name(),
 947       fd.name()->as_C_string(),
 948       (same_module) ? ref_klass->joint_in_module_of_loader(sel_klass) : ref_klass->class_in_module_of_loader(),
 949       (same_module) ? "" : "; ",
 950       (same_module) ? "" : sel_klass->class_in_module_of_loader()
 951     );
 952     return;
 953   }
 954 }
 955 
 956 void LinkResolver::resolve_field_access(fieldDescriptor& fd, const constantPoolHandle& pool, int index, const methodHandle& method, Bytecodes::Code byte, TRAPS) {
 957   LinkInfo link_info(pool, index, method, CHECK);
 958   resolve_field(fd, link_info, byte, true, CHECK);
 959 }
 960 
 961 void LinkResolver::resolve_field(fieldDescriptor& fd,
 962                                  const LinkInfo& link_info,
 963                                  Bytecodes::Code byte, bool initialize_class,
 964                                  TRAPS) {
 965   assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic ||
 966          byte == Bytecodes::_getfield  || byte == Bytecodes::_putfield  ||
 967          byte == Bytecodes::_nofast_getfield  || byte == Bytecodes::_nofast_putfield  ||
 968          (byte == Bytecodes::_nop && !link_info.check_access()), "bad field access bytecode");
 969 
 970   bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic);


< prev index next >