void ClassTypeImpl::class_type_super_class(PacketInputStream *in, PacketOutputStream *out) { UsingFastOops fast_oops; InstanceClass::Fast clazz = in->read_class_ref(); InstanceClass::Fast superclass; if (clazz.is_null() || clazz().is_interface()) { out->write_int(0); } else { #ifdef AZZERT if (TraceDebugger) { tty->print("Superclass of class: "); JavaDebugger::print_class(&clazz); tty->print_cr(""); } #endif superclass = clazz().super(); if (superclass.is_null()) { out->write_int(0); } else { #ifdef AZZERT if (TraceDebugger) { tty->print("SuperClass = "); JavaDebugger::print_class(&superclass); tty->print_cr(", id = 0x%x", JavaDebugger::get_object_id_by_ref_nocreate(&superclass)); } #endif out->write_class(&superclass); } } out->send_packet(); }
void ObjectReferenceImpl::common_invoke_method(PacketInputStream *in, PacketOutputStream *out, bool is_static) { UsingFastOops fastoops; SETUP_ERROR_CHECKER_ARG; Oop::Fast this_object; JavaClass::Fast this_klass; Thread::Fast invoke_thread; InstanceClass::Fast ic; Method::Fast m, sync_method; int arg_count; jbyte type_tag, modified_tag; EntryActivation::Fast entry, sync_entry; int arg_index = 0; int options; #ifdef AZZERT if (TraceDebugger) { tty->print_cr("ObjectReferenceImpl: invoke %s method starting", (is_static ? "static" : "instance")); } #endif if (!is_static) { this_object = in->read_object(); if (this_object.is_null()) { out->send_error(JDWP_Error_INVALID_OBJECT); return; } invoke_thread = in->read_thread_ref(); ic = in->read_class_ref(); } else { // Why couldn't they use the same order as static invoke? ic = in->read_class_ref(); invoke_thread = in->read_thread_ref(); } if (invoke_thread.is_null()) { out->send_error(JDWP_Error_INVALID_THREAD); return; } if ((invoke_thread().status() & THREAD_DBG_SUSPENDED_BY_EVENT) == 0) { if (TraceDebugger) { tty->print_cr("ObjectReferenceImpl: Thread not suspended by event"); } out->send_error(JDWP_Error_THREAD_NOT_SUSPENDED); return; } if (ic.is_null()) { out->send_error(JDWP_Error_INVALID_CLASS); return; } m = JavaDebugger::get_method_by_id(&ic, in->read_long()); if (m.is_null()) { out->send_error(JDWP_Error_INVALID_METHODID); return; } #ifdef AZZERT if (TraceDebugger) { tty->print("ObjectReferenceImpl: invoke method "); m().print_value_on(tty); tty->cr(); tty->print(" class ref "); ic().print_name_on(tty); tty->cr(); } #endif arg_count = in->read_int(); arg_count += (!is_static ? 1 : 0); entry = Universe::new_entry_activation(&m, arg_count JVM_NO_CHECK); Signature::Fast sig = m().signature(); SignatureStream ss(&sig, is_static); // If it's an instance method we need to push the 'this_object' rather // than one of the arguments sitting in the input stream. if (!is_static) { entry().obj_at_put(arg_index++, &this_object); ss.next(); // point at arg just past 'this' } for (; !ss.eos() && arg_index < arg_count && !ss.is_return_type(); ss.next()) { type_tag = in->read_byte(); modified_tag = type_tag; if (type_tag == JDWP_Tag_STRING || type_tag == JDWP_Tag_THREAD || type_tag == JDWP_Tag_CLASS_OBJECT) { modified_tag = JDWP_Tag_OBJECT; } if (JavaDebugger::get_tag_from_type(ss.type()) != modified_tag) { if (TraceDebugger) { tty->print_cr("ObjectReferenceImpl: invoke method: illegal arg, type %d, expected %d ", type_tag, ss.type()); } out->send_error(JDWP_Error_ILLEGAL_ARGUMENT); return; } switch(type_tag) { case JDWP_Tag_INT: entry().int_at_put(arg_index++, in->read_int()); break; case JDWP_Tag_CHAR: entry().int_at_put(arg_index++, (int)in->read_char()); break; case JDWP_Tag_SHORT: entry().int_at_put(arg_index++, (int)in->read_short()); break; case JDWP_Tag_DOUBLE: entry().double_at_put(arg_index++, in->read_double()); break; case JDWP_Tag_LONG: entry().long_at_put(arg_index++, in->read_long()); break; case JDWP_Tag_BOOLEAN: entry().int_at_put(arg_index++, (int)in->read_boolean()); break; case JDWP_Tag_OBJECT: case JDWP_Tag_ARRAY: case JDWP_Tag_STRING: case JDWP_Tag_THREAD: case JDWP_Tag_CLASS_OBJECT: { UsingFastOops fastoops2; Oop::Fast o = in->read_object(); JavaClass::Fast o_klass = o().blueprint(); JavaClass::Fast sig_klass = ss.type_klass(); if (!sig_klass().is_subtype_of(&o_klass)) { out->send_error(JDWP_Error_ILLEGAL_ARGUMENT); return; } entry().obj_at_put(arg_index++, &o); break; } default: #ifdef AZZERT tty->print_cr("Unknown argument type %d", type_tag); out->send_error(JDWP_Error_ILLEGAL_ARGUMENT); return; #endif break; } } if (arg_index < arg_count || !ss.is_return_type()) { // if arg_index < arg_count we must have reached eos // if !return_type then the actual method has more args than the debugger // thinks out->send_error(JDWP_Error_ILLEGAL_ARGUMENT); return; } options = in->read_int(); if (options & JDWP_InvokeOptions_INVOKE_SINGLE_THREADED) { ThreadReferenceImpl::resume_specific_thread(&invoke_thread, -1); } else { ThreadReferenceImpl::resume_all_threads(-1); } sync_method = Universe::dbg_class()->find_local_method(Symbols::debugger_sync_name(), Symbols::obj_obj_int_int_int_int_void_signature()); if (sync_method.is_null()) { out->send_error(JDWP_Error_ILLEGAL_ARGUMENT); return; } #ifdef AZZERT Frame fr(&invoke_thread); GUARANTEE(fr.is_java_frame(), "Must have java frame before invoking method"); #endif address* stack_pointer = (address*)invoke_thread().stack_pointer(); address ret_addr = stack_pointer[-1 * JavaStackDirection]; int is_object_return = 0; if (ret_addr == (address)shared_call_vm_oop_return) { is_object_return = 1; } sync_entry = Universe::new_entry_activation(&sync_method, 6 JVM_NO_CHECK); sync_entry().obj_at_put(0, &entry); sync_entry().obj_at_put(1, in->transport()); sync_entry().int_at_put(2, in->id()); sync_entry().int_at_put(3, options); sync_entry().int_at_put(4, ss.type()); sync_entry().int_at_put(5, is_object_return); invoke_thread().append_pending_entry(&sync_entry); }
void ObjectReferenceImpl::object_field_getter_setter(PacketInputStream *in, PacketOutputStream *out, bool is_setter) { UsingFastOops fast_oops; int i; Oop::Fast object = in->read_object(); jint num = in->read_int(); if (object.is_null()) { out->send_error(JDWP_Error_INVALID_OBJECT); return; } // Create a buffered output stream so we can asynchronously send an error // Calculate the size based on half of the items being 'longs' #ifdef AZZERT if (TraceDebugger) { tty->print_cr("Object %s, objectID=%ld, object=0x%lx, count=%ld", (is_setter ? "Set" : "Get"), JavaDebugger::get_object_id_by_ref_nocreate(&object), object.obj(), num); } #endif if (!is_setter) { out->write_int(num); } for (i = 0; i < num; i++) { UsingFastOops fast_oops_2; InstanceClass::Fast fieldClazz = in->read_class_ref(); TypeArray::Fast fields; jint field_id = in->read_int(); if (fieldClazz.is_null()) { out->send_error(JDWP_Error_INVALID_FIELDID); return; } fields = fieldClazz().fields(); if (fields.is_null()) { out->send_error(JDWP_Error_INVALID_FIELDID); return; } if (field_id >=fields().length() / Field::NUMBER_OF_SLOTS) { out->send_error(JDWP_Error_INVALID_FIELDID); return; } Field field(&fieldClazz, field_id * Field::NUMBER_OF_SLOTS); char type_tag = (field.type() < T_OBJECT) ? JavaDebugger::get_tag_from_type(field.type()) : JDWP_Tag_OBJECT; if (is_setter) { read_value_to_address(in, &object, field.offset(), type_tag, false); } else { write_value_from_address(out, &object, field.offset(), type_tag, true, false); } #ifdef AZZERT if (TraceDebugger) { //AccessFlags field_access_flags = field.access_flags(); tty->print(" "); JavaDebugger::print_class(&fieldClazz), tty->print("."); JavaDebugger::print_field(&field); tty->print(": "); print_value_from_address(&object, field.offset(), type_tag); tty->print_cr(""); } #endif } out->send_packet(); }