diff options
Diffstat (limited to 'gdb')
89 files changed, 8453 insertions, 7748 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a0eb7ff3a07..dc17be22d6a 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,56 +1,400 @@ -2003-04-03 Andrew Cagney <cagney@redhat.com> - - * frame.c (legacy_get_prev_frame): Revert a frame_id_eq test, - instead comparing the frame PCs. - -2003-04-03 Andrew Cagney <cagney@redhat.com> - - * frame.c (frame_id_eq): Update. Compare function addresses. - (get_frame_func): New function. - (frame_func_unwind): New function. - (legacy_get_prev_frame): Move linking of prev to next to the start - of the function. - (frame_id_p): Update. - (get_frame_id): Return the frame's "id". Do not set "frame". - (frame_id_build): Update. - (frame_id_inner): Update. - (create_sentinel_frame): Do not set the "pc". +2003-04-10 Andrew Cagney <cagney@redhat.com> + + * frame.c (get_frame_id): Return this frame's "id". + (frame_id_eq): Fail when code addresses do not match. + (legacy_saved_regs_this_id): Set this frame ID's code_addr to + zero. + (create_new_frame): Set the frame's ID. + (legacy_get_prev_frame): Set prev's frame ID code_addr to the + function start. + * d10v-tdep.c (d10v_frame_unwind_cache): Check for a zero func. + (d10v_frame_this_id): Get the frame's function, use frame_id_eq. + +2003-04-10 Andrew Cagney <cagney@redhat.com> + + * frame.c (fprint_frame_id): New function. + (fprint_frame_type, fprint_frame): New function. + (frame_pc_unwind, frame_func_unwind): Add/update trace code. + (create_sentinel_frame, get_frame_id): Ditto. + (frame_id_p, frame_id_eq): Ditto. + (frame_id_inner, create_new_frame): Ditto. + (legacy_get_prev_frame, get_prev_frame): Ditto. + (deprecated_update_frame_pc_hack): Ditto. + (frame_register_unwind): Ditto. + (deprecated_update_frame_base_hack): Ditto. + +2003-04-10 Corinna Vinschen <vinschen@redhat.com> + + * i386-cygwin-tdep.c (i386_cygwin_frame_chain): New function. + (i386_cygwin_init_abi): Set i386_cygwin_frame_chain as new + frame_chain function. + * Makefile.in: Add dependencies due to above change. + +2003-04-10 Corinna Vinschen <vinschen@redhat.com> + + * blockframe.c (legacy_frame_chain_valid): Move call to + DEPRECATED_FRAME_CHAIN_VALID before calls to inside_entry_func and + inside_entry_file. + +2003-04-09 Andrew Cagney <cagney@redhat.com> + + * frame.h (struct frame_id): Replace "pc" and "base" with + "stack_addr" and "code_addr". Update comments. + (frame_id_build): Update parameter names and comment. + (struct frame_info): Replace "id_p" and "id" with "this_id". + * dummy-frame.c (dummy_frame_this_id): Update. + * breakpoint.c (print_one_breakpoint): Update. + * frame.c (get_frame_id): Update. + (get_frame_base, frame_id_build): Update. + (create_sentinel_frame, legacy_get_prev_frame): Update. + (deprecated_update_frame_base_hack): Update. + (frame_id_p, frame_id_eq): Rework, return 0 when an invalid ID. + (frame_id_inner): Ditto. + +2003-04-09 Andrew Cagney <cagney@redhat.com> + + * defs.h (gdb_print_host_address): Make "addr" parameter a + pointer constant. + * utils.c (gdb_print_host_address): Update. + +2003-04-09 Kevin Buettner <kevinb@redhat.com> + + * rs6000-tdep.c (frame_get_saved_regs): Don't assume that the + register number for R0 is 0. + +2003-04-09 J. Brobecker <brobecker@gnat.com> + + * frame.h (struct gdbarch): Add opaque structure definition + to avoid a compilation warning on LynxOS 4.0. + +2003-04-09 Andrew Cagney <cagney@redhat.com> + + * frame.h (struct frame_info): Delete field "pc". Replace + "pc_unwind_cache" and "pc_unwind_cache_p" with "prev_pc" + structure. + * frame.c (frame_pc_unwind): Update. + (create_sentinel_frame): Do not set "pc". + (get_prev_frame): Do not set "pc". Use frame_pc_unwind. + (get_frame_pc): Call frame_pc_unwind. + (deprecated_update_frame_pc_hack): Update. + (create_new_frame): Use "pc" not "->pc". + +2003-04-09 Andrew Cagney <cagney@redhat.com> + + * frame.c (get_frame_id): Eliminate code updating "frame". + (legacy_get_prev_frame): Ditto. + (get_frame_base): Return id.base directly. + (deprecated_update_frame_base_hack): Update "id.base". + * frame.h (struct frame_info): Delete field "frame". + +2003-04-09 Andrew Cagney <cagney@redhat.com> + + * NEWS: Mention that the "Sequent family" is obsolete. + * configure.tgt: Obsolete i[3456]86-sequent-bsd*, + i[3456]86-sequent-sysv4*, and i[3456]86-sequent-sysv*. + * configure.host: Obsolete i[3456]86-sequent-bsd*, + i[3456]86-sequent-sysv4*, and i[3456]86-sequent-sysv*. + * config/i386/tm-ptx4.h: Obsolete file. + * config/i386/tm-ptx.h: Obsolete file. + * symm-tdep.c: Obsolete file. + * config/i386/symmetry.mt: Obsolete file. + * config/i386/tm-symmetry.h: Obsolete file. + * symm-nat.c: Obsolete file. + * config/i386/nm-symmetry.h: Obsolete file. + * config/i386/xm-symmetry.h: Obsolete file. + * config/i386/symmetry.mh: Obsolete file. + * config/i386/nm-ptx4.h: Obsolete file. + * config/i386/ptx4.mh: Obsolete file. + * config/i386/ptx.mt: Obsolete file. + * config/i386/ptx.mh: Obsolete file. + * config/i386/xm-ptx4.h: Obsolete file. + * config/i386/xm-ptx.h: Obsolete file. + +2003-04-09 Andrew Cagney <cagney@redhat.com> + + Obsolete mips*-*-mach3*. + * NEWS: Mention that mips*-*-mach3* is obsolete. + * m3-nat.c: Obsolete file. + * config/nm-m3.h: Obsolete file. + * config/mips/tm-mipsm3.h: Obsolete file. + * config/mips/mipsm3.mt: Obsolete file. + * config/mips/mipsm3.mh: Obsolete file. + * config/mips/xm-mipsm3.h: Obsolete file. + * mipsm3-nat.c: Obsolete file. + * configure.host: Obsolete mips-dec-mach3*. + * configure.tgt: Obsolete mips*-*-mach3*. + +2003-04-09 Andrew Cagney <cagney@redhat.com> + + * doublest.h: Update copyright. + (deprecated_store_floating, deprecated_extract_floating): Rename + store_floating and extract_floating. Update comments. + * doublest.c: Update copyright. + (extract_floating_by_length): Replace extract_floating. + (store_floating_by_length): Replace store_floating. + (deprecated_extract_floating): New function. + (deprecated_store_floating): New function. + (extract_typed_floating): Call extract_floating_by_length. + (store_typed_floating): Call store_floating_by_length. + * x86-64-tdep.c (x86_64_store_return_value): Update. + * sh-tdep.c (sh3e_sh4_extract_return_value): Update. + (sh64_extract_return_value): Update. + (sh_sh4_register_convert_to_virtual): Update. + (sh_sh64_register_convert_to_virtual): Update. + (sh_sh4_register_convert_to_raw): Update. + (sh_sh64_register_convert_to_raw): Update. + * rs6000-tdep.c (rs6000_register_convert_to_virtual): Update. + (rs6000_register_convert_to_raw): Update. + * ia64-tdep.c (ia64_register_convert_to_virtual): Update. + (ia64_register_convert_to_raw): Update. + * config/i386/tm-symmetry.h (REGISTER_CONVERT_TO_RAW): Update. + (REGISTER_CONVERT_TO_VIRTUAL): Update. + * arm-linux-tdep.c (arm_linux_push_arguments): Update. + * alpha-tdep.c (alpha_register_convert_to_virtual): Update. + (alpha_register_convert_to_raw): Update. + +2003-04-08 Andrew Cagney <cagney@redhat.com> + + * gdbarch.sh (SAVED_PC_AFTER_CALL): Add a predicate. + * gdbarch.h, gdbarch.c: Re-generate. + * d10v-tdep.c (d10v_saved_pc_after_call): Delete function. + (d10v_gdbarch_init): Do not set saved_pc_after_call. + * infrun.c (step_over_function): Call SAVED_PC_AFTER_CALL_P + conditionally, use frame_pc_unwind as an alternative. Add + comments. + * arch-utils.c (init_frame_pc_default): Only call + SAVED_PC_AFTER_CALL when available. + +2003-04-08 Elena Zannoni <ezannoni@redhat.com> + + * infrun.c (stop_soon): Rename from stop_soon_quietly. + (struct inferior_status): Rename stop_soon_quietly field to stop_soon. + (clear_proceed_status): Rename stop_soon_quietly to stop_soon. + (start_remote): Ditto. + (handle_inferior_event): Ditto. + (save_inferior_status): Ditto. + (restore_inferior_status): Ditto. + * infcmd.c (attach_command): Ditto. + * fork-child.c (startup_inferior): Ditto. + * inferior.h (stop_soon): Rename from stop_soon_quietly. + * alpha-tdep.c (heuristic_proc_start): Ditto. + * mips-tdep.c (heuristic_proc_start): Ditto. + * solib-svr4.c (svr4_solib_create_inferior_hook): Ditto. + * solib-sunos.c (sunos_solib_create_inferior_hook): Ditto. + * solib-osf.c (osf_solib_create_inferior_hook): Ditto. + * solib-irix.c (irix_solib_create_inferior_hook): Ditto. + * remote-vx.c (vx_create_inferior): Ditto. + +2003-04-08 Elena Zannoni <ezannoni@redhat.com> + + * infrun.c (stop_soon_quietly): Make it an enum, to better + override the default behavior of handle_inferior_event. + (clear_proceed_status): Update uses of stop_soon_quietly to + reflect that it is now an enum. + (start_remote): Ditto. + (handle_inferior_event): Change logic a bit if stop_soon_quietly + is set to handle the new GNU/Linux kernel behavior for + attach/sigstop. Update uses of stop_soon_quietly. + * inferior.h (enum stop_kind): New enum. + * infcmd.c (attach_command): Use STOP_QUIETLY_NO_SIGSTOP. + Reset normal handle_inferior_event behavior, afterwards. + * fork-child.c (startup_inferior): Update. + * alpha-tdep.c (heuristic_proc_start): Update. + * solib-svr4.c (svr4_solib_create_inferior_hook): Update. + * solib-sunos.c (sunos_solib_create_inferior_hook): Update. + * solib-osf.c (osf_solib_create_inferior_hook): Update. + * solib-irix.c (irix_solib_create_inferior_hook): Update. + * remote-vx.c (vx_create_inferior): Update. + * mips-tdep.c (heuristic_proc_start): Update. + +2003-04-07 Elena Zannoni <ezannoni@redhat.com> + + * disasm.c (dump_insns): Move variables inside loop, or they will + be freed more than once, causing wild memory corruptions. + (gdb_disassembly): Look for the substring "-thread", + instead of "-threads" in the target name, to make sure to find + the 'multi-thread' target. Also, make sure we do the right thing + with the "core" target. + +2003-04-07 Kevin Buettner <kevinb@redhat.com> + + * mips-tdep.c (mips_print_fp_register): New function, created from + do_fp_register_row(). Registers are now (also) printed as hex. + Only one register is printed per row. + (mips_print_register, do_fp_register_row): Print floating point + registers with mips_print_fp_register(). + +2003-04-06 Andrew Cagney <cagney@redhat.com> + + * valprint.h (inspect_it): Add extern declaration. + * objc-lang.c (value_nsstring): Avoid assignment inside of "if". + (selectors_info, classes_info): Ditto. + (find_objc_msgcall): Fix indentation. + (objc_printstr): Delete extern declarations. + + * arm-tdep.c (arm_frameless_function_invocation): Fix typo. + +2003-04-06 Andrew Cagney <cagney@redhat.com> + + * frame.h (legacy_frame_chain_valid): Rename frame_chain_valid. + Update comment. + * frame.c (legacy_saved_regs_this_id): Update. + (legacy_get_prev_frame): Update. + * xstormy16-tdep.c: Update comment. + * sparc-tdep.c (sparc_frame_chain): Update comment. + * blockframe.c (legacy_frame_chain_valid): Update. + +2003-04-06 Andrew Cagney <cagney@redhat.com> + + * valprint.c (val_print_type_code_int): Delete #ifdef + PRINT_TYPELESS_INTEGER code. + + * gdbarch.sh (DEPRECATED_USE_GENERIC_DUMMY_FRAMES) + (CALL_DUMMY_LOCATION, DEPRECATED_PC_IN_CALL_DUMMY): Allow partial + multi-arch definition. + * gdbarch.h: Re-generate. + +2003-04-05 Andrew Cagney <cagney@redhat.com> + + Eliminate FRAME_FIND_SAVED_REGS. + * config/pa/tm-hppah.h (hppa_hpux_frame_find_saved_regs_in_sigtramp): + Change FSR parameter to a pointer. + * config/pa/tm-hppa64.h (FRAME_FIND_SAVED_REGS_IN_SIGTRAMP): + Assume FSR parameter is a pointer. + * hppa-hpux-tdep.c (hppa_hpux_frame_find_saved_regs_in_sigtramp): + Make fsr a pointer. + * hppa-tdep.c (hppa_frame_find_saved_regs): New function. + (hppa_frame_saved_pc): Call hppa_frame_init_saved_regs. Make + saved_regs a pointer. + (hppa_frame_saved_pc): Ditto. + (find_dummy_frame_regs): Make frame_saved_regs a pointer + (hppa_pop_frame): Call hppa_frame_init_saved_regs. Make fsr a + pointer. + (restore_pc_queue): Make fsr a pointer. + (hppa_frame_find_saved_regs): Make frame_saved_regs a pointer. + (hppa_frame_chain): Make saved_regs a pointer, call + hppa_frame_init_saved_regs. + * sparc-tdep.c: Include "gdb_assert.h". + (sparc_frame_find_saved_regs): Replace internal_error with + gdb_assert. + * remote-vxsparc.c (vx_read_register): Delete reference to + FRAME_FIND_SAVED_REGS. + * gdbarch.sh: Delete check for FRAME_FIND_SAVED_REGS. + * gdbarch.h: Regenerate. + * frame.h (DEPRECATED_FRAME_INIT_SAVED_REGS): Delete macro. + (deprecated_get_frame_saved_regs): Delete declaration. + (struct frame_saved_regs): Delete definition. + * frame.c (deprecated_get_frame_saved_regs): Delete function. + * config/pa/tm-hppa.h (hppa_frame_init_saved_regs): Declare. + (hppa_frame_find_saved_regs): Delete declaration. + (FRAME_FIND_SAVED_REGS): Delete macro. + (DEPRECATED_FRAME_INIT_SAVED_REGS): Define. + * config/i386/tm-ptx.h (FRAME_FIND_SAVED_REGS): Delete + FRAME_FIND_SAVED_REGS in comment. + +2003-04-05 Andrew Cagney <cagney@redhat.com> + + * frame.c (frame_func_unwind, get_frame_func): New functions. + * frame.h (get_frame_func, frame_func_unwind): Declare. + (struct frame_info): Add field "prev_func" for caching the + previous frame's function address. + * arm-tdep.c (arm_frameless_function_invocation): Combine + get_pc_function_start and get_frame_pc into get_frame_func. + * sh-tdep.c (sh_nofp_frame_init_saved_regs): Ditto. + (sh64_nofp_frame_init_saved_regs): Ditto. + * s390-tdep.c (s390_function_start): Ditto. + * rs6000-tdep.c (rs6000_pop_frame): Ditto. + (rs6000_frameless_function_invocation): Ditto. + (rs6000_frame_saved_pc): Ditto. + * m68k-tdep.c (m68k_frame_init_saved_regs): Ditto. + * ia64-tdep.c (ia64_frame_init_saved_regs): Ditto. + * i386-tdep.c (i386_frameless_signal_p): Ditto. + (i386_frame_init_saved_regs): Ditto. + * hppa-tdep.c (hppa_frame_find_saved_regs): Ditto. + * d10v-tdep.c (d10v_frame_unwind_cache): Combine + get_pc_function_start and frame_pc_unwind into frame_func_unwind. + * cris-tdep.c (cris_frame_init_saved_regs): Ditto. + * blockframe.c (frameless_look_for_prologue): Ditto. + +2003-04-05 Andrew Cagney <cagney@redhat.com> + + * frame.c (legacy_get_prev_frame): Link prev to next at the + function start. Update comments. + +2003-04-05 Andrew Cagney <cagney@redhat.com> + + * frame.c (get_frame_id): Update comment. + (legacy_get_prev_frame): Update comment. + * gdbarch.sh: Delete check for EXTRA_FRAME_INFO. + * gdbarch.h: Regenerate. + * config/sparc/tm-sparc.h (EXTRA_FRAME_INFO): Delete. + * frame.h: Delete #ifdef EXTRA_FRAME_INFO code. + +2003-04-05 Andrew Cagney <cagney@redhat.com> + + * stack.c (print_frame_info): Use get_frame_pc. + +2003-04-04 Andrew Cagney <cagney@redhat.com> + + * frame.c (get_prev_frame): Do not call frame_type_from_pc. Set + the frame's type from the unwinder. + (get_frame_type): Map UNKNOWN_FRAME onto NORMAL_FRAME. + (create_new_frame, legacy_get_prev_frame): When the unwinder's + type isn't UNKNOWN_FRAME, initalize "type" from the unwinder. + (get_frame_base_address): Use get_frame_type. + (get_frame_locals_address, get_frame_args_address): Ditto. + (legacy_saved_regs_unwinder): Set the type to UNKNOWN_TYPE. + * frame.h (enum frame_type): Add UNKNOWN_FRAME. + (struct frame_info): Add comment explaining why the frame contains + a "type" field. + * dummy-frame.c (dummy_frame_unwind): Set the type to DUMMY_FRAME. + * d10v-tdep.c (d10v_frame_unwind): Set the type to NORMAL_FRAME. + * sentinel-frame.c (sentinel_frame_unwinder): Set the type to + NORMAL_FRAME. + * frame-unwind.h: Include "frame.h". + (struct frame_unwind): Add "type" field. + * Makefile.in (frame_unwind_h): Add $(frame_h). + +2003-04-04 Andrew Cagney <cagney@redhat.com> + + * x86-64-tdep.c (x86_64_unwind_dummy_id): Use frame_id_build. + * dummy-frame.c (dummy_frame_this_id): Use frame_id_build. + * d10v-tdep.c (d10v_frame_this_id): Use get_frame_pc and + get_frame_base. + (d10v_unwind_dummy_id): Use frame_id_build. + * frame.c (find_frame_sal): Use get_frame_pc. + (create_new_frame): Use deprecated_update_frame_pc_hack and + deprecated_update_frame_base_hack. + (create_sentinel_frame): Add comment about ->pc going away. + (get_prev_frame): Add comment about ->pc going away. + (legacy_get_prev_frame): Use get_frame_base, get_frame_pc, + frame_id_build, deprecated_update_frame_pc_hack and + deprecated_update_frame_base_hack. (select_frame): Use get_frame_pc. (legacy_saved_regs_this_id): Use frame_id_build. - (create_new_frame): Set the frame's ID. Store the PC in the - sentinel frame's PC unwind cache. - (legacy_get_prev_frame): Do not set "pc" or "frame". Instead use - frame_pc_unwind, frame_id_build, deprecated_update_frame_pc_hack, - and deprecated_update_frame_base_hack. - (get_prev_frame): Do not set "pc" or "frame", instead use - frame_pc_unwind. - (get_frame_pc): Use frame_pc_unwind. - (find_frame_sal): Use get_frame_pc. - (get_frame_base): Return the frame ID's stack address. - (deprecated_update_frame_base_hack): Set the frame ID's stack - address. - (frame_id_eq, frame_id_p, frame_id_inner, get_frame_id): Add debug - print statements. - - * d10v-tdep.c (d10v_frame_unwind_cache): Use frame_func_unwind. - (d10v_frame_this_id): Get the frame's function. - (d10v_frame_this_id): Use frame_id_eq. - (d10v_unwind_dummy_id): Use frame_id_build. - * stack.c (print_frame_info): Use get_frame_pc. +2003-04-04 Elena Zannoni <ezannoni@redhat.com> - * dummy-frame.c (dummy_frame_this_id): Use frame_id_build. Update - parameter to find_dummy_frame. + * x86-64-tdep.c (x86_64_push_arguments): Handle correctly the + signed integer case. + (classify_argument): Handle enumerations and references. - * breakpoint.c (print_one_breakpoint): Update. +2003-04-04 Andrew Cagney <cagney@redhat.com> - * frame.h (struct frame_id): Rename "base" to "stack_addr", - replace "pc" with "func_addr". - (frame_id_build): Update parameter names and comment. - (struct frame_info): Delete "frame" and "pc" fields. - (frame_func_unwind): Declare. - (get_frame_func): Declare. - (struct frame_info): Add field "func". + * frame.c (create_sentinel_frame): Initialize the sentinel frame's + ID to NULL. + +2003-04-01 Adam Fedor <fedor@gnu.org> + + * gdb/objc-lang.c (selectors_info): Replace calls to + SYMBOL_DEMANGLED_NAME and DEPRECATED_SYMBOL_NAME with + SYMBOL_NATURAL_NAME. + (classes_info, find_methods): Likewise. + +2003-04-03 Kevin Buettner <kevinb@redhat.com> + + * rs6000-tdep.c (rs6000_gdbarch_init): For xcoff executables, set + ``mach'' to the value determined by bfd_default_set_arch_mach(). 2003-04-02 Bob Rossi <bob_rossi@cox.net> diff --git a/gdb/Makefile.in b/gdb/Makefile.in index c5ba5d84218..4a13551c8e5 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -641,7 +641,7 @@ event_top_h = event-top.h expression_h = expression.h $(symtab_h) $(doublest_h) f_lang_h = f-lang.h frame_h = frame.h -frame_unwind_h = frame-unwind.h +frame_unwind_h = frame-unwind.h $(frame_h) frame_base_h = frame-base.h gdb_events_h = gdb-events.h gdb_stabs_h = gdb-stabs.h @@ -1798,7 +1798,7 @@ i386gnu-tdep.o: i386gnu-tdep.c $(defs_h) $(i386_tdep_h) $(osabi_h) i386ly-tdep.o: i386ly-tdep.c $(defs_h) $(gdbcore_h) $(inferior_h) \ $(regcache_h) $(target_h) $(i386_tdep_h) $(osabi_h) i386-cygwin-tdep.o: i386-cygwin-tdep.c $(defs_h) $(gdb_string_h) \ - $(i386_tdep_h) $(osabi_h) + $(i386_tdep_h) $(osabi_h) $(gdbcore_h) $(frame_h) $(dummy_frame_h) i386nbsd-tdep.o: i386nbsd-tdep.c $(defs_h) $(gdbtypes_h) $(gdbcore_h) \ $(regcache_h) $(arch_utils_h) $(i386_tdep_h) $(i387_tdep_h) \ $(nbsd_tdep_h) $(solib_svr4_h) $(osabi_h) @@ -2208,9 +2208,9 @@ sparc-linux-nat.o: sparc-linux-nat.c $(defs_h) $(regcache_h) $(gregset_h) sparc-nat.o: sparc-nat.c $(defs_h) $(inferior_h) $(target_h) $(gdbcore_h) \ $(regcache_h) $(gdb_wait_h) sparc-stub.o: sparc-stub.c -sparc-tdep.o: sparc-tdep.c $(defs_h) $(arch_utils_h) $(frame_h) \ - $(inferior_h) $(target_h) $(value_h) $(bfd_h) $(gdb_string_h) \ - $(regcache_h) $(osabi_h) $(gregset_h) $(gdbcore_h) $(symfile_h) +sparc-tdep.o: sparc-tdep.c $(defs_h) $(arch_utils_h) $(frame_h) $(inferior_h) \ + $(target_h) $(value_h) $(bfd_h) $(gdb_string_h) $(regcache_h) \ + $(osabi_h) $(gregset_h) $(gdbcore_h) $(gdb_assert_h) $(symfile_h) sparc64nbsd-nat.o: sparc64nbsd-nat.c $(defs_h) $(inferior_h) $(regcache_h) \ $(sparcnbsd_tdep_h) sparcl-stub.o: sparcl-stub.c @@ -44,6 +44,10 @@ H8/500 simulator h8500-hitachi-hms or h8500hms HP/PA running BSD hppa*-*-bsd* HP/PA running OSF/1 hppa*-*-osf* HP/PA Pro target hppa*-*-pro* +PMAX (MIPS) running Mach 3.0 mips*-*-mach3* +Sequent family i[3456]86-sequent-sysv4* + i[3456]86-sequent-sysv* + i[3456]86-sequent-bsd* * REMOVED configurations and files diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c index d3b58656e6c..2cbec4ef413 100644 --- a/gdb/alpha-tdep.c +++ b/gdb/alpha-tdep.c @@ -554,10 +554,10 @@ heuristic_proc_start (CORE_ADDR pc) if (start_pc < fence) { /* It's not clear to me why we reach this point when - stop_soon_quietly, but with this test, at least we + stop_soon, but with this test, at least we don't print out warnings for every child forked (eg, on decstation). 22apr93 rich@cygnus.com. */ - if (!stop_soon_quietly) + if (stop_soon == NO_STOP_QUIETLY) { static int blurb_printed = 0; @@ -1458,8 +1458,8 @@ alpha_register_convert_to_virtual (int regnum, struct type *valtype, if (TYPE_CODE (valtype) == TYPE_CODE_FLT) { - double d = extract_floating (raw_buffer, REGISTER_RAW_SIZE (regnum)); - store_floating (virtual_buffer, TYPE_LENGTH (valtype), d); + double d = deprecated_extract_floating (raw_buffer, REGISTER_RAW_SIZE (regnum)); + deprecated_store_floating (virtual_buffer, TYPE_LENGTH (valtype), d); } else if (TYPE_CODE (valtype) == TYPE_CODE_INT && TYPE_LENGTH (valtype) <= 4) { @@ -1484,8 +1484,8 @@ alpha_register_convert_to_raw (struct type *valtype, int regnum, if (TYPE_CODE (valtype) == TYPE_CODE_FLT) { - double d = extract_floating (virtual_buffer, TYPE_LENGTH (valtype)); - store_floating (raw_buffer, REGISTER_RAW_SIZE (regnum), d); + double d = deprecated_extract_floating (virtual_buffer, TYPE_LENGTH (valtype)); + deprecated_store_floating (raw_buffer, REGISTER_RAW_SIZE (regnum), d); } else if (TYPE_CODE (valtype) == TYPE_CODE_INT && TYPE_LENGTH (valtype) <= 4) { diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c index 712b03ebcc9..cba0175709d 100644 --- a/gdb/arch-utils.c +++ b/gdb/arch-utils.c @@ -383,7 +383,7 @@ init_frame_pc_noop (int fromleaf, struct frame_info *prev) CORE_ADDR init_frame_pc_default (int fromleaf, struct frame_info *prev) { - if (fromleaf) + if (fromleaf && SAVED_PC_AFTER_CALL_P ()) return SAVED_PC_AFTER_CALL (get_next_frame (prev)); else if (get_next_frame (prev) != NULL) return DEPRECATED_FRAME_SAVED_PC (get_next_frame (prev)); diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c index fa4d8fa00ca..781d4204a2c 100644 --- a/gdb/arm-linux-tdep.c +++ b/gdb/arm-linux-tdep.c @@ -181,10 +181,10 @@ arm_linux_push_arguments (int nargs, struct value **args, CORE_ADDR sp, if (TYPE_CODE_FLT == typecode && REGISTER_SIZE == len) { DOUBLEST dblval; - dblval = extract_floating (val, len); + dblval = deprecated_extract_floating (val, len); len = TARGET_DOUBLE_BIT / TARGET_CHAR_BIT; val = alloca (len); - store_floating (val, len, dblval); + deprecated_store_floating (val, len, dblval); } /* If the argument is a pointer to a function, and it is a Thumb diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 21d84887d7a..748422b8de3 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -295,7 +295,7 @@ arm_frameless_function_invocation (struct frame_info *fi) stmdb sp!, {} sub sp, ip, #4. */ - func_start = (get_pc_function_start (get_frame_pc (fi)) + FUNCTION_START_OFFSET); + func_start = (get_frame_func (fi) + FUNCTION_START_OFFSET); after_prologue = SKIP_PROLOGUE (func_start); /* There are some frameless functions whose first two instructions @@ -1383,7 +1383,7 @@ push_stack_item (struct stack_item *prev, void *contents, int len) { struct stack_item *si; si = xmalloc (sizeof (struct stack_item)); - si->data = malloc (len); + si->data = xmalloc (len); si->len = len; si->prev = prev; memcpy (si->data, contents, len); diff --git a/gdb/blockframe.c b/gdb/blockframe.c index 364be9e0ef1..47e576e8211 100644 --- a/gdb/blockframe.c +++ b/gdb/blockframe.c @@ -146,7 +146,7 @@ frameless_look_for_prologue (struct frame_info *frame) { CORE_ADDR func_start, after_prologue; - func_start = get_pc_function_start (get_frame_pc (frame)); + func_start = get_frame_func (frame); if (func_start) { func_start += FUNCTION_START_OFFSET; @@ -554,12 +554,12 @@ deprecated_pc_in_call_dummy_at_entry_point (CORE_ADDR pc, CORE_ADDR sp, && (pc) <= (CALL_DUMMY_ADDRESS () + DECR_PC_AFTER_BREAK)); } -/* Function: frame_chain_valid - Returns true for a user frame or a call_function_by_hand dummy frame, - and false for the CRT0 start-up frame. Purpose is to terminate backtrace. */ +/* Returns true for a user frame or a call_function_by_hand dummy + frame, and false for the CRT0 start-up frame. Purpose is to + terminate backtrace. */ int -frame_chain_valid (CORE_ADDR fp, struct frame_info *fi) +legacy_frame_chain_valid (CORE_ADDR fp, struct frame_info *fi) { /* Don't prune CALL_DUMMY frames. */ if (DEPRECATED_USE_GENERIC_DUMMY_FRAMES @@ -575,6 +575,11 @@ frame_chain_valid (CORE_ADDR fp, struct frame_info *fi) if (INNER_THAN (fp, get_frame_base (fi))) return 0; + /* If the architecture has a custom DEPRECATED_FRAME_CHAIN_VALID, + call it now. */ + if (DEPRECATED_FRAME_CHAIN_VALID_P ()) + return DEPRECATED_FRAME_CHAIN_VALID (fp, fi); + /* If we're already inside the entry function for the main objfile, then it isn't valid. */ if (inside_entry_func (get_frame_pc (fi))) @@ -587,10 +592,5 @@ frame_chain_valid (CORE_ADDR fp, struct frame_info *fi) if (inside_entry_file (frame_pc_unwind (fi))) return 0; - /* If the architecture has a custom DEPRECATED_FRAME_CHAIN_VALID, - call it now. */ - if (DEPRECATED_FRAME_CHAIN_VALID_P ()) - return DEPRECATED_FRAME_CHAIN_VALID (fp, fi); - return 1; } diff --git a/gdb/config/i386/nm-ptx4.h b/gdb/config/i386/nm-ptx4.h index 9c8f41c2b82..74db16546e7 100644 --- a/gdb/config/i386/nm-ptx4.h +++ b/gdb/config/i386/nm-ptx4.h @@ -1,66 +1,66 @@ -/* Definitions to make GDB run on a Sequent Symmetry under ptx - with Weitek 1167 and i387 support. - Copyright 1986, 1987, 1989, 1992, 1994, 1996, 2000 - Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "regcache.h" - -#include "config/nm-sysv4.h" - -#undef USE_PROC_FS - -#include "i386/nm-symmetry.h" - -#define PTRACE_READ_REGS(pid,regaddr) mptrace (XPT_RREGS, (pid), (regaddr), 0) -#define PTRACE_WRITE_REGS(pid,regaddr) \ - mptrace (XPT_WREGS, (pid), (regaddr), 0) - -/* Override copies of {fetch,store}_inferior_registers in infptrace.c. */ - -#define FETCH_INFERIOR_REGISTERS - -/* We must fetch all the regs before storing, since we store all at once. */ - -#define CHILD_PREPARE_TO_STORE() deprecated_read_register_bytes (0, NULL, REGISTER_BYTES) - -#define CHILD_WAIT -struct target_waitstatus; -extern ptid_t child_wait (ptid_t, struct target_waitstatus *); - -/* - * ptx does attach as of ptx version 2.1. Prior to that, the interface - * exists but does not work. - * - * FIXME: Using attach/detach requires using the ptx MPDEBUGGER - * interface. There are still problems with that, so for now don't - * enable attach/detach. If you turn it on anyway, it will mostly - * work, but has a number of bugs. -fubar, 2/94. - */ -/*#define ATTACH_DETACH 1 */ -#undef ATTACH_DETACH -#define PTRACE_ATTACH XPT_DEBUG -#define PTRACE_DETACH XPT_UNDEBUG -/* - * The following drivel is needed because there are two ptrace-ish - * calls on ptx: ptrace() and mptrace(), each of which does about half - * of the ptrace functions. - */ -#define PTRACE_ATTACH_CALL(pid) ptx_do_attach(pid) -#define PTRACE_DETACH_CALL(pid, signo) ptx_do_detach(pid, signo) +// OBSOLETE /* Definitions to make GDB run on a Sequent Symmetry under ptx +// OBSOLETE with Weitek 1167 and i387 support. +// OBSOLETE Copyright 1986, 1987, 1989, 1992, 1994, 1996, 2000 +// OBSOLETE Free Software Foundation, Inc. +// OBSOLETE +// OBSOLETE This file is part of GDB. +// OBSOLETE +// OBSOLETE This program is free software; you can redistribute it and/or modify +// OBSOLETE it under the terms of the GNU General Public License as published by +// OBSOLETE the Free Software Foundation; either version 2 of the License, or +// OBSOLETE (at your option) any later version. +// OBSOLETE +// OBSOLETE This program is distributed in the hope that it will be useful, +// OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of +// OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// OBSOLETE GNU General Public License for more details. +// OBSOLETE +// OBSOLETE You should have received a copy of the GNU General Public License +// OBSOLETE along with this program; if not, write to the Free Software +// OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, +// OBSOLETE Boston, MA 02111-1307, USA. */ +// OBSOLETE +// OBSOLETE #include "regcache.h" +// OBSOLETE +// OBSOLETE #include "config/nm-sysv4.h" +// OBSOLETE +// OBSOLETE #undef USE_PROC_FS +// OBSOLETE +// OBSOLETE #include "i386/nm-symmetry.h" +// OBSOLETE +// OBSOLETE #define PTRACE_READ_REGS(pid,regaddr) mptrace (XPT_RREGS, (pid), (regaddr), 0) +// OBSOLETE #define PTRACE_WRITE_REGS(pid,regaddr) \ +// OBSOLETE mptrace (XPT_WREGS, (pid), (regaddr), 0) +// OBSOLETE +// OBSOLETE /* Override copies of {fetch,store}_inferior_registers in infptrace.c. */ +// OBSOLETE +// OBSOLETE #define FETCH_INFERIOR_REGISTERS +// OBSOLETE +// OBSOLETE /* We must fetch all the regs before storing, since we store all at once. */ +// OBSOLETE +// OBSOLETE #define CHILD_PREPARE_TO_STORE() deprecated_read_register_bytes (0, NULL, REGISTER_BYTES) +// OBSOLETE +// OBSOLETE #define CHILD_WAIT +// OBSOLETE struct target_waitstatus; +// OBSOLETE extern ptid_t child_wait (ptid_t, struct target_waitstatus *); +// OBSOLETE +// OBSOLETE /* +// OBSOLETE * ptx does attach as of ptx version 2.1. Prior to that, the interface +// OBSOLETE * exists but does not work. +// OBSOLETE * +// OBSOLETE * FIXME: Using attach/detach requires using the ptx MPDEBUGGER +// OBSOLETE * interface. There are still problems with that, so for now don't +// OBSOLETE * enable attach/detach. If you turn it on anyway, it will mostly +// OBSOLETE * work, but has a number of bugs. -fubar, 2/94. +// OBSOLETE */ +// OBSOLETE /*#define ATTACH_DETACH 1 */ +// OBSOLETE #undef ATTACH_DETACH +// OBSOLETE #define PTRACE_ATTACH XPT_DEBUG +// OBSOLETE #define PTRACE_DETACH XPT_UNDEBUG +// OBSOLETE /* +// OBSOLETE * The following drivel is needed because there are two ptrace-ish +// OBSOLETE * calls on ptx: ptrace() and mptrace(), each of which does about half +// OBSOLETE * of the ptrace functions. +// OBSOLETE */ +// OBSOLETE #define PTRACE_ATTACH_CALL(pid) ptx_do_attach(pid) +// OBSOLETE #define PTRACE_DETACH_CALL(pid, signo) ptx_do_detach(pid, signo) diff --git a/gdb/config/i386/nm-symmetry.h b/gdb/config/i386/nm-symmetry.h index d3f57e692b8..72b7d8dc0b5 100644 --- a/gdb/config/i386/nm-symmetry.h +++ b/gdb/config/i386/nm-symmetry.h @@ -1,50 +1,50 @@ -/* Definitions to make GDB run on a Sequent Symmetry under dynix 3.0, - with Weitek 1167 and i387 support. - Copyright 1986, 1987, 1989, 1992, 1994, 1996, 1998, 2000 - Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "regcache.h" - -/* Override copies of {fetch,store}_inferior_registers in infptrace.c. */ - -#define FETCH_INFERIOR_REGISTERS - -/* We must fetch all the regs before storing, since we store all at once. */ - -#define CHILD_PREPARE_TO_STORE() deprecated_read_register_bytes (0, NULL, REGISTER_BYTES) - -#ifdef _SEQUENT_ -#define CHILD_WAIT -extern ptid_t child_wait (ptid_t, struct target_waitstatus *); -#endif - -/* This is the amount to subtract from u.u_ar0 - to get the offset in the core file of the register values. */ - -#ifdef _SEQUENT_ -#include <sys/param.h> -#include <sys/user.h> -#include <sys/mc_vmparam.h> -/* VA_UAREA is defined in <sys/mc_vmparam.h>, and is dependant upon - sizeof(struct user) */ -#define KERNEL_U_ADDR (VA_UAREA) /* ptx */ -#else -#define KERNEL_U_ADDR (0x80000000 - (UPAGES * NBPG)) /* dynix */ -#endif +// OBSOLETE /* Definitions to make GDB run on a Sequent Symmetry under dynix 3.0, +// OBSOLETE with Weitek 1167 and i387 support. +// OBSOLETE Copyright 1986, 1987, 1989, 1992, 1994, 1996, 1998, 2000 +// OBSOLETE Free Software Foundation, Inc. +// OBSOLETE +// OBSOLETE This file is part of GDB. +// OBSOLETE +// OBSOLETE This program is free software; you can redistribute it and/or modify +// OBSOLETE it under the terms of the GNU General Public License as published by +// OBSOLETE the Free Software Foundation; either version 2 of the License, or +// OBSOLETE (at your option) any later version. +// OBSOLETE +// OBSOLETE This program is distributed in the hope that it will be useful, +// OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of +// OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// OBSOLETE GNU General Public License for more details. +// OBSOLETE +// OBSOLETE You should have received a copy of the GNU General Public License +// OBSOLETE along with this program; if not, write to the Free Software +// OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, +// OBSOLETE Boston, MA 02111-1307, USA. */ +// OBSOLETE +// OBSOLETE #include "regcache.h" +// OBSOLETE +// OBSOLETE /* Override copies of {fetch,store}_inferior_registers in infptrace.c. */ +// OBSOLETE +// OBSOLETE #define FETCH_INFERIOR_REGISTERS +// OBSOLETE +// OBSOLETE /* We must fetch all the regs before storing, since we store all at once. */ +// OBSOLETE +// OBSOLETE #define CHILD_PREPARE_TO_STORE() deprecated_read_register_bytes (0, NULL, REGISTER_BYTES) +// OBSOLETE +// OBSOLETE #ifdef _SEQUENT_ +// OBSOLETE #define CHILD_WAIT +// OBSOLETE extern ptid_t child_wait (ptid_t, struct target_waitstatus *); +// OBSOLETE #endif +// OBSOLETE +// OBSOLETE /* This is the amount to subtract from u.u_ar0 +// OBSOLETE to get the offset in the core file of the register values. */ +// OBSOLETE +// OBSOLETE #ifdef _SEQUENT_ +// OBSOLETE #include <sys/param.h> +// OBSOLETE #include <sys/user.h> +// OBSOLETE #include <sys/mc_vmparam.h> +// OBSOLETE /* VA_UAREA is defined in <sys/mc_vmparam.h>, and is dependant upon +// OBSOLETE sizeof(struct user) */ +// OBSOLETE #define KERNEL_U_ADDR (VA_UAREA) /* ptx */ +// OBSOLETE #else +// OBSOLETE #define KERNEL_U_ADDR (0x80000000 - (UPAGES * NBPG)) /* dynix */ +// OBSOLETE #endif diff --git a/gdb/config/i386/ptx.mh b/gdb/config/i386/ptx.mh index 554b4119c76..048f5e5130b 100644 --- a/gdb/config/i386/ptx.mh +++ b/gdb/config/i386/ptx.mh @@ -1,7 +1,7 @@ -# Host: Sequent Symmetry running ptx 1.3, with Weitek 1167 or i387 - -XM_FILE= xm-ptx.h -NATDEPFILES= inftarg.o fork-child.o symm-nat.o corelow.o core-aout.o -XM_CLIBS= -lPW -lseq - -NAT_FILE= nm-symmetry.h +# OBSOLETE # Host: Sequent Symmetry running ptx 1.3, with Weitek 1167 or i387 +# OBSOLETE +# OBSOLETE XM_FILE= xm-ptx.h +# OBSOLETE NATDEPFILES= inftarg.o fork-child.o symm-nat.o corelow.o core-aout.o +# OBSOLETE XM_CLIBS= -lPW -lseq +# OBSOLETE +# OBSOLETE NAT_FILE= nm-symmetry.h diff --git a/gdb/config/i386/ptx.mt b/gdb/config/i386/ptx.mt index 757df3328fc..e9551e21c18 100644 --- a/gdb/config/i386/ptx.mt +++ b/gdb/config/i386/ptx.mt @@ -1,3 +1,3 @@ -# Target: Sequent Symmetry running ptx 2.0, with Weitek 1167 or i387. -TDEPFILES= symm-tdep.o i387-tdep.o i386-tdep.o -TM_FILE= tm-ptx.h +# OBSOLETE # Target: Sequent Symmetry running ptx 2.0, with Weitek 1167 or i387. +# OBSOLETE TDEPFILES= symm-tdep.o i387-tdep.o i386-tdep.o +# OBSOLETE TM_FILE= tm-ptx.h diff --git a/gdb/config/i386/ptx4.mh b/gdb/config/i386/ptx4.mh index e4aa55e88a0..4d236359f47 100644 --- a/gdb/config/i386/ptx4.mh +++ b/gdb/config/i386/ptx4.mh @@ -1,8 +1,8 @@ -# Host: Sequent Symmetry running ptx 1.3, with Weitek 1167 or i387 - -XM_FILE= xm-ptx4.h -NATDEPFILES= inftarg.o fork-child.o symm-nat.o corelow.o core-aout.o \ - core-regset.o solib.o solib-svr4.o solib-legacy.o -XM_CLIBS= -lseq - -NAT_FILE= nm-ptx4.h +# OBSOLETE # Host: Sequent Symmetry running ptx 1.3, with Weitek 1167 or i387 +# OBSOLETE +# OBSOLETE XM_FILE= xm-ptx4.h +# OBSOLETE NATDEPFILES= inftarg.o fork-child.o symm-nat.o corelow.o core-aout.o \ +# OBSOLETE core-regset.o solib.o solib-svr4.o solib-legacy.o +# OBSOLETE XM_CLIBS= -lseq +# OBSOLETE +# OBSOLETE NAT_FILE= nm-ptx4.h diff --git a/gdb/config/i386/ptx4.mt b/gdb/config/i386/ptx4.mt index f3478091996..ad268f8c540 100644 --- a/gdb/config/i386/ptx4.mt +++ b/gdb/config/i386/ptx4.mt @@ -1,3 +1,3 @@ -# Target: Sequent Symmetry running ptx 4.0, with Weitek 1167 or i387. -TDEPFILES= symm-tdep.o i387-tdep.o i386-tdep.o -TM_FILE= tm-ptx4.h +# OBSOLETE # Target: Sequent Symmetry running ptx 4.0, with Weitek 1167 or i387. +# OBSOLETE TDEPFILES= symm-tdep.o i387-tdep.o i386-tdep.o +# OBSOLETE TM_FILE= tm-ptx4.h diff --git a/gdb/config/i386/symmetry.mh b/gdb/config/i386/symmetry.mh index 486a2fbe170..19c5264ff8a 100644 --- a/gdb/config/i386/symmetry.mh +++ b/gdb/config/i386/symmetry.mh @@ -1,4 +1,4 @@ -# Host: Sequent Symmetry running Dynix 3.0, with Weitek 1167 or i387. -XM_FILE= xm-symmetry.h -NAT_FILE= nm-symmetry.h -NATDEPFILES= inftarg.o fork-child.o corelow.o core-aout.o symm-nat.o +# OBSOLETE # Host: Sequent Symmetry running Dynix 3.0, with Weitek 1167 or i387. +# OBSOLETE XM_FILE= xm-symmetry.h +# OBSOLETE NAT_FILE= nm-symmetry.h +# OBSOLETE NATDEPFILES= inftarg.o fork-child.o corelow.o core-aout.o symm-nat.o diff --git a/gdb/config/i386/symmetry.mt b/gdb/config/i386/symmetry.mt index a3dba70bd82..8fccbd26f05 100644 --- a/gdb/config/i386/symmetry.mt +++ b/gdb/config/i386/symmetry.mt @@ -1,3 +1,3 @@ -# Target: Sequent Symmetry running Dynix 3.0, with Weitek 1167 or i387. -TDEPFILES= i386-tdep.o symm-tdep.o i387-tdep.o -TM_FILE= tm-symmetry.h +# OBSOLETE # Target: Sequent Symmetry running Dynix 3.0, with Weitek 1167 or i387. +# OBSOLETE TDEPFILES= i386-tdep.o symm-tdep.o i387-tdep.o +# OBSOLETE TM_FILE= tm-symmetry.h diff --git a/gdb/config/i386/tm-ptx.h b/gdb/config/i386/tm-ptx.h index 80026e3568e..4d3ba83c30d 100644 --- a/gdb/config/i386/tm-ptx.h +++ b/gdb/config/i386/tm-ptx.h @@ -1,200 +1,194 @@ -/* Target machine definitions for GDB on a Sequent Symmetry under ptx - with Weitek 1167 and i387 support. - - Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 2000, - 2003 Free Software Foundation, Inc. - - Symmetry version by Jay Vosburgh (fubar@sequent.com). - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#ifndef TM_PTX_H -#define TM_PTX_H 1 - -/* I don't know if this will work for cross-debugging, even if you do get - a copy of the right include file. */ - -#include <sys/reg.h> - -#ifdef SEQUENT_PTX4 -#include "i386/tm-i386.h" -#else /* !SEQUENT_PTX4 */ -#include "i386/tm-i386.h" -#endif - -/* Amount PC must be decremented by after a breakpoint. This is often the - number of bytes in BREAKPOINT but not always (such as now). */ - -#undef DECR_PC_AFTER_BREAK -#define DECR_PC_AFTER_BREAK 0 - -/* Number of machine registers */ - -#undef NUM_REGS -#define NUM_REGS 49 - -/* Initializer for an array of names of registers. There should be at least - NUM_REGS strings in this initializer. Any excess ones are simply ignored. - The order of the first 8 registers must match the compiler's numbering - scheme (which is the same as the 386 scheme) and also regmap in the various - *-nat.c files. */ - -#undef REGISTER_NAME -#define REGISTER_NAMES { "eax", "ecx", "edx", "ebx", \ - "esp", "ebp", "esi", "edi", \ - "eip", "eflags", "st0", "st1", \ - "st2", "st3", "st4", "st5", \ - "st6", "st7", "fp1", "fp2", \ - "fp3", "fp4", "fp5", "fp6", \ - "fp7", "fp8", "fp9", "fp10", \ - "fp11", "fp12", "fp13", "fp14", \ - "fp15", "fp16", "fp17", "fp18", \ - "fp19", "fp20", "fp21", "fp22", \ - "fp23", "fp24", "fp25", "fp26", \ - "fp27", "fp28", "fp29", "fp30", \ - "fp31" } - -/* Register numbers of various important registers. - Note that some of these values are "real" register numbers, - and correspond to the general registers of the machine, - and some are "phony" register numbers which are too large - to be actual register numbers as far as the user is concerned - but do serve to get the desired values when passed to read_register. */ - -#define EAX_REGNUM 0 -#define ECX_REGNUM 1 -#define EDX_REGNUM 2 -#define EBX_REGNUM 3 - -#define ESP_REGNUM 4 -#define EBP_REGNUM 5 - -#define ESI_REGNUM 6 -#define EDI_REGNUM 7 - -#define EIP_REGNUM 8 -#define EFLAGS_REGNUM 9 - -#define ST0_REGNUM 10 -#define ST1_REGNUM 11 -#define ST2_REGNUM 12 -#define ST3_REGNUM 13 - -#define ST4_REGNUM 14 -#define ST5_REGNUM 15 -#define ST6_REGNUM 16 -#define ST7_REGNUM 17 - -#define FP1_REGNUM 18 /* first 1167 register */ -/* Get %fp2 - %fp31 by addition, since they are contiguous */ - -#undef SP_REGNUM -#define SP_REGNUM ESP_REGNUM /* Contains address of top of stack */ -#undef FP_REGNUM -#define FP_REGNUM EBP_REGNUM /* Contains address of executing stack frame */ -#undef PC_REGNUM -#define PC_REGNUM EIP_REGNUM /* Contains program counter */ -#undef PS_REGNUM -#define PS_REGNUM EFLAGS_REGNUM /* Contains processor status */ - -/* - * For ptx, this is a little bit bizarre, since the register block - * is below the u area in memory. This means that blockend here ends - * up being negative (for the call from coredep.c) since the value in - * u.u_ar0 will be less than KERNEL_U_ADDR (and coredep.c passes us - * u.u_ar0 - KERNEL_U_ADDR in blockend). Since we also define - * FETCH_INFERIOR_REGISTERS (and supply our own functions for that), - * the core file case will be the only use of this function. - */ - -#define REGISTER_U_ADDR(addr, blockend, regno) \ -{ (addr) = ptx_register_u_addr((blockend), (regno)); } - -extern int ptx_register_u_addr (int, int); - -/* Total amount of space needed to store our copies of the machine's - register state, the array `registers'. 10 i*86 registers, 8 i387 - registers, and 31 Weitek 1167 registers */ - -#undef REGISTER_BYTES -#define REGISTER_BYTES ((10 * 4) + (8 * 10) + (31 * 4)) - -/* Largest value REGISTER_RAW_SIZE can have. */ - -#undef DEPRECATED_MAX_REGISTER_RAW_SIZE -#define DEPRECATED_MAX_REGISTER_RAW_SIZE 10 - -/* Nonzero if register N requires conversion - from raw format to virtual format. */ - -#undef REGISTER_CONVERTIBLE -#define REGISTER_CONVERTIBLE(N) \ -((N < ST0_REGNUM) ? 0 : \ - (N < FP1_REGNUM) ? 1 : \ - 0) - -/* Convert data from raw format for register REGNUM - to virtual format for register REGNUM. */ -extern const struct floatformat floatformat_i387_ext; /* from floatformat.h */ - -#undef REGISTER_CONVERT_TO_VIRTUAL -#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \ -((REGNUM < ST0_REGNUM) ? (void)memcpy ((TO), (FROM), 4) : \ - (REGNUM < FP1_REGNUM) ? (void)floatformat_to_double(&floatformat_i387_ext, \ - (FROM),(TO)) : \ - (void)memcpy ((TO), (FROM), 4)) - -/* Convert data from virtual format for register REGNUM - to raw format for register REGNUM. */ - -#undef REGISTER_CONVERT_TO_RAW -#define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO) \ -((REGNUM < ST0_REGNUM) ? (void)memcpy ((TO), (FROM), 4) : \ - (REGNUM < FP1_REGNUM) ? (void)floatformat_from_double(&floatformat_i387_ext, \ - (FROM),(TO)) : \ - (void)memcpy ((TO), (FROM), 4)) - -/* Return the GDB type object for the "standard" data type - of data in register N. */ -/* - * Note: the 1167 registers (the last line, builtin_type_float) are - * generally used in pairs, with each pair being treated as a double. - * It it also possible to use them singly as floats. I'm not sure how - * in gdb to treat the register pair pseudo-doubles. -fubar - */ -#undef REGISTER_VIRTUAL_TYPE -#define REGISTER_VIRTUAL_TYPE(N) \ -((N < ST0_REGNUM) ? builtin_type_int : \ - (N < FP1_REGNUM) ? builtin_type_double : \ - builtin_type_float) - -/* Extract from an array REGBUF containing the (raw) register state - a function return value of type TYPE, and copy that, in virtual format, - into VALBUF. */ - -#undef DEPRECATED_EXTRACT_RETURN_VALUE -#define DEPRECATED_EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \ - symmetry_extract_return_value(TYPE, REGBUF, VALBUF) - -/* - #undef FRAME_FIND_SAVED_REGS - #define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \ - { ptx_frame_find_saved_regs((frame_info), &(frame_saved_regs)); } - */ - -#endif /* ifndef TM_PTX_H */ +// OBSOLETE /* Target machine definitions for GDB on a Sequent Symmetry under ptx +// OBSOLETE with Weitek 1167 and i387 support. +// OBSOLETE +// OBSOLETE Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 2000, +// OBSOLETE 2003 Free Software Foundation, Inc. +// OBSOLETE +// OBSOLETE Symmetry version by Jay Vosburgh (fubar@sequent.com). +// OBSOLETE +// OBSOLETE This file is part of GDB. +// OBSOLETE +// OBSOLETE This program is free software; you can redistribute it and/or modify +// OBSOLETE it under the terms of the GNU General Public License as published by +// OBSOLETE the Free Software Foundation; either version 2 of the License, or +// OBSOLETE (at your option) any later version. +// OBSOLETE +// OBSOLETE This program is distributed in the hope that it will be useful, +// OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of +// OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// OBSOLETE GNU General Public License for more details. +// OBSOLETE +// OBSOLETE You should have received a copy of the GNU General Public License +// OBSOLETE along with this program; if not, write to the Free Software +// OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, +// OBSOLETE Boston, MA 02111-1307, USA. */ +// OBSOLETE +// OBSOLETE #ifndef TM_PTX_H +// OBSOLETE #define TM_PTX_H 1 +// OBSOLETE +// OBSOLETE /* I don't know if this will work for cross-debugging, even if you do get +// OBSOLETE a copy of the right include file. */ +// OBSOLETE +// OBSOLETE #include <sys/reg.h> +// OBSOLETE +// OBSOLETE #ifdef SEQUENT_PTX4 +// OBSOLETE #include "i386/tm-i386.h" +// OBSOLETE #else /* !SEQUENT_PTX4 */ +// OBSOLETE #include "i386/tm-i386.h" +// OBSOLETE #endif +// OBSOLETE +// OBSOLETE /* Amount PC must be decremented by after a breakpoint. This is often the +// OBSOLETE number of bytes in BREAKPOINT but not always (such as now). */ +// OBSOLETE +// OBSOLETE #undef DECR_PC_AFTER_BREAK +// OBSOLETE #define DECR_PC_AFTER_BREAK 0 +// OBSOLETE +// OBSOLETE /* Number of machine registers */ +// OBSOLETE +// OBSOLETE #undef NUM_REGS +// OBSOLETE #define NUM_REGS 49 +// OBSOLETE +// OBSOLETE /* Initializer for an array of names of registers. There should be at least +// OBSOLETE NUM_REGS strings in this initializer. Any excess ones are simply ignored. +// OBSOLETE The order of the first 8 registers must match the compiler's numbering +// OBSOLETE scheme (which is the same as the 386 scheme) and also regmap in the various +// OBSOLETE *-nat.c files. */ +// OBSOLETE +// OBSOLETE #undef REGISTER_NAME +// OBSOLETE #define REGISTER_NAMES { "eax", "ecx", "edx", "ebx", \ +// OBSOLETE "esp", "ebp", "esi", "edi", \ +// OBSOLETE "eip", "eflags", "st0", "st1", \ +// OBSOLETE "st2", "st3", "st4", "st5", \ +// OBSOLETE "st6", "st7", "fp1", "fp2", \ +// OBSOLETE "fp3", "fp4", "fp5", "fp6", \ +// OBSOLETE "fp7", "fp8", "fp9", "fp10", \ +// OBSOLETE "fp11", "fp12", "fp13", "fp14", \ +// OBSOLETE "fp15", "fp16", "fp17", "fp18", \ +// OBSOLETE "fp19", "fp20", "fp21", "fp22", \ +// OBSOLETE "fp23", "fp24", "fp25", "fp26", \ +// OBSOLETE "fp27", "fp28", "fp29", "fp30", \ +// OBSOLETE "fp31" } +// OBSOLETE +// OBSOLETE /* Register numbers of various important registers. +// OBSOLETE Note that some of these values are "real" register numbers, +// OBSOLETE and correspond to the general registers of the machine, +// OBSOLETE and some are "phony" register numbers which are too large +// OBSOLETE to be actual register numbers as far as the user is concerned +// OBSOLETE but do serve to get the desired values when passed to read_register. */ +// OBSOLETE +// OBSOLETE #define EAX_REGNUM 0 +// OBSOLETE #define ECX_REGNUM 1 +// OBSOLETE #define EDX_REGNUM 2 +// OBSOLETE #define EBX_REGNUM 3 +// OBSOLETE +// OBSOLETE #define ESP_REGNUM 4 +// OBSOLETE #define EBP_REGNUM 5 +// OBSOLETE +// OBSOLETE #define ESI_REGNUM 6 +// OBSOLETE #define EDI_REGNUM 7 +// OBSOLETE +// OBSOLETE #define EIP_REGNUM 8 +// OBSOLETE #define EFLAGS_REGNUM 9 +// OBSOLETE +// OBSOLETE #define ST0_REGNUM 10 +// OBSOLETE #define ST1_REGNUM 11 +// OBSOLETE #define ST2_REGNUM 12 +// OBSOLETE #define ST3_REGNUM 13 +// OBSOLETE +// OBSOLETE #define ST4_REGNUM 14 +// OBSOLETE #define ST5_REGNUM 15 +// OBSOLETE #define ST6_REGNUM 16 +// OBSOLETE #define ST7_REGNUM 17 +// OBSOLETE +// OBSOLETE #define FP1_REGNUM 18 /* first 1167 register */ +// OBSOLETE /* Get %fp2 - %fp31 by addition, since they are contiguous */ +// OBSOLETE +// OBSOLETE #undef SP_REGNUM +// OBSOLETE #define SP_REGNUM ESP_REGNUM /* Contains address of top of stack */ +// OBSOLETE #undef FP_REGNUM +// OBSOLETE #define FP_REGNUM EBP_REGNUM /* Contains address of executing stack frame */ +// OBSOLETE #undef PC_REGNUM +// OBSOLETE #define PC_REGNUM EIP_REGNUM /* Contains program counter */ +// OBSOLETE #undef PS_REGNUM +// OBSOLETE #define PS_REGNUM EFLAGS_REGNUM /* Contains processor status */ +// OBSOLETE +// OBSOLETE /* +// OBSOLETE * For ptx, this is a little bit bizarre, since the register block +// OBSOLETE * is below the u area in memory. This means that blockend here ends +// OBSOLETE * up being negative (for the call from coredep.c) since the value in +// OBSOLETE * u.u_ar0 will be less than KERNEL_U_ADDR (and coredep.c passes us +// OBSOLETE * u.u_ar0 - KERNEL_U_ADDR in blockend). Since we also define +// OBSOLETE * FETCH_INFERIOR_REGISTERS (and supply our own functions for that), +// OBSOLETE * the core file case will be the only use of this function. +// OBSOLETE */ +// OBSOLETE +// OBSOLETE #define REGISTER_U_ADDR(addr, blockend, regno) \ +// OBSOLETE { (addr) = ptx_register_u_addr((blockend), (regno)); } +// OBSOLETE +// OBSOLETE extern int ptx_register_u_addr (int, int); +// OBSOLETE +// OBSOLETE /* Total amount of space needed to store our copies of the machine's +// OBSOLETE register state, the array `registers'. 10 i*86 registers, 8 i387 +// OBSOLETE registers, and 31 Weitek 1167 registers */ +// OBSOLETE +// OBSOLETE #undef REGISTER_BYTES +// OBSOLETE #define REGISTER_BYTES ((10 * 4) + (8 * 10) + (31 * 4)) +// OBSOLETE +// OBSOLETE /* Largest value REGISTER_RAW_SIZE can have. */ +// OBSOLETE +// OBSOLETE #undef DEPRECATED_MAX_REGISTER_RAW_SIZE +// OBSOLETE #define DEPRECATED_MAX_REGISTER_RAW_SIZE 10 +// OBSOLETE +// OBSOLETE /* Nonzero if register N requires conversion +// OBSOLETE from raw format to virtual format. */ +// OBSOLETE +// OBSOLETE #undef REGISTER_CONVERTIBLE +// OBSOLETE #define REGISTER_CONVERTIBLE(N) \ +// OBSOLETE ((N < ST0_REGNUM) ? 0 : \ +// OBSOLETE (N < FP1_REGNUM) ? 1 : \ +// OBSOLETE 0) +// OBSOLETE +// OBSOLETE /* Convert data from raw format for register REGNUM +// OBSOLETE to virtual format for register REGNUM. */ +// OBSOLETE extern const struct floatformat floatformat_i387_ext; /* from floatformat.h */ +// OBSOLETE +// OBSOLETE #undef REGISTER_CONVERT_TO_VIRTUAL +// OBSOLETE #define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \ +// OBSOLETE ((REGNUM < ST0_REGNUM) ? (void)memcpy ((TO), (FROM), 4) : \ +// OBSOLETE (REGNUM < FP1_REGNUM) ? (void)floatformat_to_double(&floatformat_i387_ext, \ +// OBSOLETE (FROM),(TO)) : \ +// OBSOLETE (void)memcpy ((TO), (FROM), 4)) +// OBSOLETE +// OBSOLETE /* Convert data from virtual format for register REGNUM +// OBSOLETE to raw format for register REGNUM. */ +// OBSOLETE +// OBSOLETE #undef REGISTER_CONVERT_TO_RAW +// OBSOLETE #define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO) \ +// OBSOLETE ((REGNUM < ST0_REGNUM) ? (void)memcpy ((TO), (FROM), 4) : \ +// OBSOLETE (REGNUM < FP1_REGNUM) ? (void)floatformat_from_double(&floatformat_i387_ext, \ +// OBSOLETE (FROM),(TO)) : \ +// OBSOLETE (void)memcpy ((TO), (FROM), 4)) +// OBSOLETE +// OBSOLETE /* Return the GDB type object for the "standard" data type +// OBSOLETE of data in register N. */ +// OBSOLETE /* +// OBSOLETE * Note: the 1167 registers (the last line, builtin_type_float) are +// OBSOLETE * generally used in pairs, with each pair being treated as a double. +// OBSOLETE * It it also possible to use them singly as floats. I'm not sure how +// OBSOLETE * in gdb to treat the register pair pseudo-doubles. -fubar +// OBSOLETE */ +// OBSOLETE #undef REGISTER_VIRTUAL_TYPE +// OBSOLETE #define REGISTER_VIRTUAL_TYPE(N) \ +// OBSOLETE ((N < ST0_REGNUM) ? builtin_type_int : \ +// OBSOLETE (N < FP1_REGNUM) ? builtin_type_double : \ +// OBSOLETE builtin_type_float) +// OBSOLETE +// OBSOLETE /* Extract from an array REGBUF containing the (raw) register state +// OBSOLETE a function return value of type TYPE, and copy that, in virtual format, +// OBSOLETE into VALBUF. */ +// OBSOLETE +// OBSOLETE #undef DEPRECATED_EXTRACT_RETURN_VALUE +// OBSOLETE #define DEPRECATED_EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \ +// OBSOLETE symmetry_extract_return_value(TYPE, REGBUF, VALBUF) +// OBSOLETE +// OBSOLETE #endif /* ifndef TM_PTX_H */ diff --git a/gdb/config/i386/tm-ptx4.h b/gdb/config/i386/tm-ptx4.h index a13d4a63a7f..5f83db40c0a 100644 --- a/gdb/config/i386/tm-ptx4.h +++ b/gdb/config/i386/tm-ptx4.h @@ -1,26 +1,26 @@ -/* Target machine definitions for GDB on a Sequent Symmetry under ptx - with Weitek 1167 and i387 support. - Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994 - Free Software Foundation, Inc. - Symmetry version by Jay Vosburgh (fubar@sequent.com). - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#define SEQUENT_PTX4 - -#include "i386/tm-ptx.h" +// OBSOLETE /* Target machine definitions for GDB on a Sequent Symmetry under ptx +// OBSOLETE with Weitek 1167 and i387 support. +// OBSOLETE Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994 +// OBSOLETE Free Software Foundation, Inc. +// OBSOLETE Symmetry version by Jay Vosburgh (fubar@sequent.com). +// OBSOLETE +// OBSOLETE This file is part of GDB. +// OBSOLETE +// OBSOLETE This program is free software; you can redistribute it and/or modify +// OBSOLETE it under the terms of the GNU General Public License as published by +// OBSOLETE the Free Software Foundation; either version 2 of the License, or +// OBSOLETE (at your option) any later version. +// OBSOLETE +// OBSOLETE This program is distributed in the hope that it will be useful, +// OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of +// OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// OBSOLETE GNU General Public License for more details. +// OBSOLETE +// OBSOLETE You should have received a copy of the GNU General Public License +// OBSOLETE along with this program; if not, write to the Free Software +// OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, +// OBSOLETE Boston, MA 02111-1307, USA. */ +// OBSOLETE +// OBSOLETE #define SEQUENT_PTX4 +// OBSOLETE +// OBSOLETE #include "i386/tm-ptx.h" diff --git a/gdb/config/i386/tm-symmetry.h b/gdb/config/i386/tm-symmetry.h index ea2229090e7..c8680a360a7 100644 --- a/gdb/config/i386/tm-symmetry.h +++ b/gdb/config/i386/tm-symmetry.h @@ -1,291 +1,291 @@ -/* Target machine definitions for GDB on a Sequent Symmetry under dynix 3.0, - with Weitek 1167 and i387 support. - - Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 2003 Free - Software Foundation, Inc. - - Symmetry version by Jay Vosburgh (fubar@sequent.com). - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#ifndef TM_SYMMETRY_H -#define TM_SYMMETRY_H 1 - -#include "regcache.h" -#include "doublest.h" - -/* I don't know if this will work for cross-debugging, even if you do get - a copy of the right include file. */ -#include <machine/reg.h> - -#include "i386/tm-i386.h" - -/* Amount PC must be decremented by after a breakpoint. This is often the - number of bytes in BREAKPOINT but not always (such as now). */ - -#undef DECR_PC_AFTER_BREAK -#define DECR_PC_AFTER_BREAK 0 - -/* Number of machine registers */ - -#undef NUM_REGS -#define NUM_REGS 49 - -/* Initializer for an array of names of registers. - There should be NUM_REGS strings in this initializer. */ - -/* Initializer for an array of names of registers. There should be at least - NUM_REGS strings in this initializer. Any excess ones are simply ignored. - Symmetry registers are in this weird order to match the register numbers - in the symbol table entries. If you change the order, things will probably - break mysteriously for no apparent reason. Also note that the st(0)... - st(7) 387 registers are represented as st0...st7. */ - -#undef REGISTER_NAME -#define REGISTER_NAMES { "eax", "edx", "ecx", "st0", "st1", \ - "ebx", "esi", "edi", "st2", "st3", \ - "st4", "st5", "st6", "st7", "esp", \ - "ebp", "eip", "eflags","fp1", "fp2", \ - "fp3", "fp4", "fp5", "fp6", "fp7", \ - "fp8", "fp9", "fp10", "fp11", "fp12", \ - "fp13", "fp14", "fp15", "fp16", "fp17", \ - "fp18", "fp19", "fp20", "fp21", "fp22", \ - "fp23", "fp24", "fp25", "fp26", "fp27", \ - "fp28", "fp29", "fp30", "fp31" } - -/* Register numbers of various important registers. - Note that some of these values are "real" register numbers, - and correspond to the general registers of the machine, - and some are "phony" register numbers which are too large - to be actual register numbers as far as the user is concerned - but do serve to get the desired values when passed to read_register. */ - -#define EAX_REGNUM 0 -#define EDX_REGNUM 1 -#define ECX_REGNUM 2 -#define ST0_REGNUM 3 -#define ST1_REGNUM 4 -#define EBX_REGNUM 5 -#define ESI_REGNUM 6 -#define EDI_REGNUM 7 -#define ST2_REGNUM 8 -#define ST3_REGNUM 9 - -#define ST4_REGNUM 10 -#define ST5_REGNUM 11 -#define ST6_REGNUM 12 -#define ST7_REGNUM 13 - -#define FP1_REGNUM 18 /* first 1167 register */ -/* Get %fp2 - %fp31 by addition, since they are contiguous */ - -#undef SP_REGNUM -#define SP_REGNUM 14 /* (usp) Contains address of top of stack */ -#define ESP_REGNUM 14 -#undef FP_REGNUM -#define FP_REGNUM 15 /* (ebp) Contains address of executing stack frame */ -#define EBP_REGNUM 15 -#undef PC_REGNUM -#define PC_REGNUM 16 /* (eip) Contains program counter */ -#define EIP_REGNUM 16 -#undef PS_REGNUM -#define PS_REGNUM 17 /* (ps) Contains processor status */ -#define EFLAGS_REGNUM 17 - -/* - * Following macro translates i386 opcode register numbers to Symmetry - * register numbers. This is used by i386_frame_find_saved_regs. - * - * %eax %ecx %edx %ebx %esp %ebp %esi %edi - * i386 0 1 2 3 4 5 6 7 - * Symmetry 0 2 1 5 14 15 6 7 - * - */ -#define I386_REGNO_TO_SYMMETRY(n) \ -((n)==0?0 :(n)==1?2 :(n)==2?1 :(n)==3?5 :(n)==4?14 :(n)==5?15 :(n)) - -/* The magic numbers below are offsets into u_ar0 in the user struct. - * They live in <machine/reg.h>. Gdb calls this macro with blockend - * holding u.u_ar0 - KERNEL_U_ADDR. Only the registers listed are - * saved in the u area (along with a few others that aren't useful - * here. See <machine/reg.h>). - */ - -#define REGISTER_U_ADDR(addr, blockend, regno) \ -{ struct user foo; /* needed for finding fpu regs */ \ -switch (regno) { \ - case 0: \ - addr = blockend + EAX * sizeof(int); break; \ - case 1: \ - addr = blockend + EDX * sizeof(int); break; \ - case 2: \ - addr = blockend + ECX * sizeof(int); break; \ - case 3: /* st(0) */ \ - addr = ((int)&foo.u_fpusave.fpu_stack[0][0] - (int)&foo); \ - break; \ - case 4: /* st(1) */ \ - addr = ((int) &foo.u_fpusave.fpu_stack[1][0] - (int)&foo); \ - break; \ - case 5: \ - addr = blockend + EBX * sizeof(int); break; \ - case 6: \ - addr = blockend + ESI * sizeof(int); break; \ - case 7: \ - addr = blockend + EDI * sizeof(int); break; \ - case 8: /* st(2) */ \ - addr = ((int) &foo.u_fpusave.fpu_stack[2][0] - (int)&foo); \ - break; \ - case 9: /* st(3) */ \ - addr = ((int) &foo.u_fpusave.fpu_stack[3][0] - (int)&foo); \ - break; \ - case 10: /* st(4) */ \ - addr = ((int) &foo.u_fpusave.fpu_stack[4][0] - (int)&foo); \ - break; \ - case 11: /* st(5) */ \ - addr = ((int) &foo.u_fpusave.fpu_stack[5][0] - (int)&foo); \ - break; \ - case 12: /* st(6) */ \ - addr = ((int) &foo.u_fpusave.fpu_stack[6][0] - (int)&foo); \ - break; \ - case 13: /* st(7) */ \ - addr = ((int) &foo.u_fpusave.fpu_stack[7][0] - (int)&foo); \ - break; \ - case 14: \ - addr = blockend + ESP * sizeof(int); break; \ - case 15: \ - addr = blockend + EBP * sizeof(int); break; \ - case 16: \ - addr = blockend + EIP * sizeof(int); break; \ - case 17: \ - addr = blockend + FLAGS * sizeof(int); break; \ - case 18: /* fp1 */ \ - case 19: /* fp2 */ \ - case 20: /* fp3 */ \ - case 21: /* fp4 */ \ - case 22: /* fp5 */ \ - case 23: /* fp6 */ \ - case 24: /* fp7 */ \ - case 25: /* fp8 */ \ - case 26: /* fp9 */ \ - case 27: /* fp10 */ \ - case 28: /* fp11 */ \ - case 29: /* fp12 */ \ - case 30: /* fp13 */ \ - case 31: /* fp14 */ \ - case 32: /* fp15 */ \ - case 33: /* fp16 */ \ - case 34: /* fp17 */ \ - case 35: /* fp18 */ \ - case 36: /* fp19 */ \ - case 37: /* fp20 */ \ - case 38: /* fp21 */ \ - case 39: /* fp22 */ \ - case 40: /* fp23 */ \ - case 41: /* fp24 */ \ - case 42: /* fp25 */ \ - case 43: /* fp26 */ \ - case 44: /* fp27 */ \ - case 45: /* fp28 */ \ - case 46: /* fp29 */ \ - case 47: /* fp30 */ \ - case 48: /* fp31 */ \ - addr = ((int) &foo.u_fpasave.fpa_regs[(regno)-18] - (int)&foo); \ - } \ -} - -/* Total amount of space needed to store our copies of the machine's - register state, the array `registers'. 10 i*86 registers, 8 i387 - registers, and 31 Weitek 1167 registers */ - -#undef REGISTER_BYTES -#define REGISTER_BYTES ((10 * 4) + (8 * 10) + (31 * 4)) - -/* Nonzero if register N requires conversion - from raw format to virtual format. */ - -#undef REGISTER_CONVERTIBLE -#define REGISTER_CONVERTIBLE(N) \ -(((N) < 3) ? 0 : \ -((N) < 5) ? 1 : \ -((N) < 8) ? 0 : \ -((N) < 14) ? 1 : \ - 0) - -#include "floatformat.h" - -/* Convert data from raw format for register REGNUM in buffer FROM - to virtual format with type TYPE in buffer TO. */ - -#undef REGISTER_CONVERT_TO_VIRTUAL -#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \ -{ \ - DOUBLEST val; \ - floatformat_to_doublest (&floatformat_i387_ext, (FROM), &val); \ - store_floating ((TO), TYPE_LENGTH (TYPE), val); \ -} - -/* Convert data from virtual format with type TYPE in buffer FROM - to raw format for register REGNUM in buffer TO. */ - -#undef REGISTER_CONVERT_TO_RAW -#define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO) \ -{ \ - DOUBLEST val = extract_floating ((FROM), TYPE_LENGTH (TYPE)); \ - floatformat_from_doublest (&floatformat_i387_ext, &val, (TO)); \ -} - -/* Return the GDB type object for the "standard" data type - of data in register N. */ - -#undef REGISTER_VIRTUAL_TYPE -#define REGISTER_VIRTUAL_TYPE(N) \ -((N < 3) ? builtin_type_int : \ -(N < 5) ? builtin_type_double : \ -(N < 8) ? builtin_type_int : \ -(N < 14) ? builtin_type_double : \ - builtin_type_int) - -/* Store the address of the place in which to copy the structure the - subroutine will return. This is called from call_function. - Native cc passes the address in eax, gcc (up to version 2.5.8) - passes it on the stack. gcc should be fixed in future versions to - adopt native cc conventions. */ - -#undef DEPRECATED_PUSH_ARGUMENTS -#undef STORE_STRUCT_RETURN -#define STORE_STRUCT_RETURN(ADDR, SP) write_register(0, (ADDR)) - -/* Extract from an array REGBUF containing the (raw) register state - a function return value of type TYPE, and copy that, in virtual format, - into VALBUF. */ - -#undef DEPRECATED_EXTRACT_RETURN_VALUE -#define DEPRECATED_EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \ - symmetry_extract_return_value(TYPE, REGBUF, VALBUF) - -/* The following redefines make backtracing through sigtramp work. - They manufacture a fake sigtramp frame and obtain the saved pc in sigtramp - from the sigcontext structure which is pushed by the kernel on the - user stack, along with a pointer to it. */ - -#define IN_SIGTRAMP(pc, name) ((name) && STREQ ("_sigcode", name)) - -/* Offset to saved PC in sigcontext, from <signal.h>. */ -#define SIGCONTEXT_PC_OFFSET 16 - -#endif /* ifndef TM_SYMMETRY_H */ +// OBSOLETE /* Target machine definitions for GDB on a Sequent Symmetry under dynix 3.0, +// OBSOLETE with Weitek 1167 and i387 support. +// OBSOLETE +// OBSOLETE Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 2003 Free +// OBSOLETE Software Foundation, Inc. +// OBSOLETE +// OBSOLETE Symmetry version by Jay Vosburgh (fubar@sequent.com). +// OBSOLETE +// OBSOLETE This file is part of GDB. +// OBSOLETE +// OBSOLETE This program is free software; you can redistribute it and/or modify +// OBSOLETE it under the terms of the GNU General Public License as published by +// OBSOLETE the Free Software Foundation; either version 2 of the License, or +// OBSOLETE (at your option) any later version. +// OBSOLETE +// OBSOLETE This program is distributed in the hope that it will be useful, +// OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of +// OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// OBSOLETE GNU General Public License for more details. +// OBSOLETE +// OBSOLETE You should have received a copy of the GNU General Public License +// OBSOLETE along with this program; if not, write to the Free Software +// OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, +// OBSOLETE Boston, MA 02111-1307, USA. */ +// OBSOLETE +// OBSOLETE #ifndef TM_SYMMETRY_H +// OBSOLETE #define TM_SYMMETRY_H 1 +// OBSOLETE +// OBSOLETE #include "regcache.h" +// OBSOLETE #include "doublest.h" +// OBSOLETE +// OBSOLETE /* I don't know if this will work for cross-debugging, even if you do get +// OBSOLETE a copy of the right include file. */ +// OBSOLETE #include <machine/reg.h> +// OBSOLETE +// OBSOLETE #include "i386/tm-i386.h" +// OBSOLETE +// OBSOLETE /* Amount PC must be decremented by after a breakpoint. This is often the +// OBSOLETE number of bytes in BREAKPOINT but not always (such as now). */ +// OBSOLETE +// OBSOLETE #undef DECR_PC_AFTER_BREAK +// OBSOLETE #define DECR_PC_AFTER_BREAK 0 +// OBSOLETE +// OBSOLETE /* Number of machine registers */ +// OBSOLETE +// OBSOLETE #undef NUM_REGS +// OBSOLETE #define NUM_REGS 49 +// OBSOLETE +// OBSOLETE /* Initializer for an array of names of registers. +// OBSOLETE There should be NUM_REGS strings in this initializer. */ +// OBSOLETE +// OBSOLETE /* Initializer for an array of names of registers. There should be at least +// OBSOLETE NUM_REGS strings in this initializer. Any excess ones are simply ignored. +// OBSOLETE Symmetry registers are in this weird order to match the register numbers +// OBSOLETE in the symbol table entries. If you change the order, things will probably +// OBSOLETE break mysteriously for no apparent reason. Also note that the st(0)... +// OBSOLETE st(7) 387 registers are represented as st0...st7. */ +// OBSOLETE +// OBSOLETE #undef REGISTER_NAME +// OBSOLETE #define REGISTER_NAMES { "eax", "edx", "ecx", "st0", "st1", \ +// OBSOLETE "ebx", "esi", "edi", "st2", "st3", \ +// OBSOLETE "st4", "st5", "st6", "st7", "esp", \ +// OBSOLETE "ebp", "eip", "eflags","fp1", "fp2", \ +// OBSOLETE "fp3", "fp4", "fp5", "fp6", "fp7", \ +// OBSOLETE "fp8", "fp9", "fp10", "fp11", "fp12", \ +// OBSOLETE "fp13", "fp14", "fp15", "fp16", "fp17", \ +// OBSOLETE "fp18", "fp19", "fp20", "fp21", "fp22", \ +// OBSOLETE "fp23", "fp24", "fp25", "fp26", "fp27", \ +// OBSOLETE "fp28", "fp29", "fp30", "fp31" } +// OBSOLETE +// OBSOLETE /* Register numbers of various important registers. +// OBSOLETE Note that some of these values are "real" register numbers, +// OBSOLETE and correspond to the general registers of the machine, +// OBSOLETE and some are "phony" register numbers which are too large +// OBSOLETE to be actual register numbers as far as the user is concerned +// OBSOLETE but do serve to get the desired values when passed to read_register. */ +// OBSOLETE +// OBSOLETE #define EAX_REGNUM 0 +// OBSOLETE #define EDX_REGNUM 1 +// OBSOLETE #define ECX_REGNUM 2 +// OBSOLETE #define ST0_REGNUM 3 +// OBSOLETE #define ST1_REGNUM 4 +// OBSOLETE #define EBX_REGNUM 5 +// OBSOLETE #define ESI_REGNUM 6 +// OBSOLETE #define EDI_REGNUM 7 +// OBSOLETE #define ST2_REGNUM 8 +// OBSOLETE #define ST3_REGNUM 9 +// OBSOLETE +// OBSOLETE #define ST4_REGNUM 10 +// OBSOLETE #define ST5_REGNUM 11 +// OBSOLETE #define ST6_REGNUM 12 +// OBSOLETE #define ST7_REGNUM 13 +// OBSOLETE +// OBSOLETE #define FP1_REGNUM 18 /* first 1167 register */ +// OBSOLETE /* Get %fp2 - %fp31 by addition, since they are contiguous */ +// OBSOLETE +// OBSOLETE #undef SP_REGNUM +// OBSOLETE #define SP_REGNUM 14 /* (usp) Contains address of top of stack */ +// OBSOLETE #define ESP_REGNUM 14 +// OBSOLETE #undef FP_REGNUM +// OBSOLETE #define FP_REGNUM 15 /* (ebp) Contains address of executing stack frame */ +// OBSOLETE #define EBP_REGNUM 15 +// OBSOLETE #undef PC_REGNUM +// OBSOLETE #define PC_REGNUM 16 /* (eip) Contains program counter */ +// OBSOLETE #define EIP_REGNUM 16 +// OBSOLETE #undef PS_REGNUM +// OBSOLETE #define PS_REGNUM 17 /* (ps) Contains processor status */ +// OBSOLETE #define EFLAGS_REGNUM 17 +// OBSOLETE +// OBSOLETE /* +// OBSOLETE * Following macro translates i386 opcode register numbers to Symmetry +// OBSOLETE * register numbers. This is used by i386_frame_find_saved_regs. +// OBSOLETE * +// OBSOLETE * %eax %ecx %edx %ebx %esp %ebp %esi %edi +// OBSOLETE * i386 0 1 2 3 4 5 6 7 +// OBSOLETE * Symmetry 0 2 1 5 14 15 6 7 +// OBSOLETE * +// OBSOLETE */ +// OBSOLETE #define I386_REGNO_TO_SYMMETRY(n) \ +// OBSOLETE ((n)==0?0 :(n)==1?2 :(n)==2?1 :(n)==3?5 :(n)==4?14 :(n)==5?15 :(n)) +// OBSOLETE +// OBSOLETE /* The magic numbers below are offsets into u_ar0 in the user struct. +// OBSOLETE * They live in <machine/reg.h>. Gdb calls this macro with blockend +// OBSOLETE * holding u.u_ar0 - KERNEL_U_ADDR. Only the registers listed are +// OBSOLETE * saved in the u area (along with a few others that aren't useful +// OBSOLETE * here. See <machine/reg.h>). +// OBSOLETE */ +// OBSOLETE +// OBSOLETE #define REGISTER_U_ADDR(addr, blockend, regno) \ +// OBSOLETE { struct user foo; /* needed for finding fpu regs */ \ +// OBSOLETE switch (regno) { \ +// OBSOLETE case 0: \ +// OBSOLETE addr = blockend + EAX * sizeof(int); break; \ +// OBSOLETE case 1: \ +// OBSOLETE addr = blockend + EDX * sizeof(int); break; \ +// OBSOLETE case 2: \ +// OBSOLETE addr = blockend + ECX * sizeof(int); break; \ +// OBSOLETE case 3: /* st(0) */ \ +// OBSOLETE addr = ((int)&foo.u_fpusave.fpu_stack[0][0] - (int)&foo); \ +// OBSOLETE break; \ +// OBSOLETE case 4: /* st(1) */ \ +// OBSOLETE addr = ((int) &foo.u_fpusave.fpu_stack[1][0] - (int)&foo); \ +// OBSOLETE break; \ +// OBSOLETE case 5: \ +// OBSOLETE addr = blockend + EBX * sizeof(int); break; \ +// OBSOLETE case 6: \ +// OBSOLETE addr = blockend + ESI * sizeof(int); break; \ +// OBSOLETE case 7: \ +// OBSOLETE addr = blockend + EDI * sizeof(int); break; \ +// OBSOLETE case 8: /* st(2) */ \ +// OBSOLETE addr = ((int) &foo.u_fpusave.fpu_stack[2][0] - (int)&foo); \ +// OBSOLETE break; \ +// OBSOLETE case 9: /* st(3) */ \ +// OBSOLETE addr = ((int) &foo.u_fpusave.fpu_stack[3][0] - (int)&foo); \ +// OBSOLETE break; \ +// OBSOLETE case 10: /* st(4) */ \ +// OBSOLETE addr = ((int) &foo.u_fpusave.fpu_stack[4][0] - (int)&foo); \ +// OBSOLETE break; \ +// OBSOLETE case 11: /* st(5) */ \ +// OBSOLETE addr = ((int) &foo.u_fpusave.fpu_stack[5][0] - (int)&foo); \ +// OBSOLETE break; \ +// OBSOLETE case 12: /* st(6) */ \ +// OBSOLETE addr = ((int) &foo.u_fpusave.fpu_stack[6][0] - (int)&foo); \ +// OBSOLETE break; \ +// OBSOLETE case 13: /* st(7) */ \ +// OBSOLETE addr = ((int) &foo.u_fpusave.fpu_stack[7][0] - (int)&foo); \ +// OBSOLETE break; \ +// OBSOLETE case 14: \ +// OBSOLETE addr = blockend + ESP * sizeof(int); break; \ +// OBSOLETE case 15: \ +// OBSOLETE addr = blockend + EBP * sizeof(int); break; \ +// OBSOLETE case 16: \ +// OBSOLETE addr = blockend + EIP * sizeof(int); break; \ +// OBSOLETE case 17: \ +// OBSOLETE addr = blockend + FLAGS * sizeof(int); break; \ +// OBSOLETE case 18: /* fp1 */ \ +// OBSOLETE case 19: /* fp2 */ \ +// OBSOLETE case 20: /* fp3 */ \ +// OBSOLETE case 21: /* fp4 */ \ +// OBSOLETE case 22: /* fp5 */ \ +// OBSOLETE case 23: /* fp6 */ \ +// OBSOLETE case 24: /* fp7 */ \ +// OBSOLETE case 25: /* fp8 */ \ +// OBSOLETE case 26: /* fp9 */ \ +// OBSOLETE case 27: /* fp10 */ \ +// OBSOLETE case 28: /* fp11 */ \ +// OBSOLETE case 29: /* fp12 */ \ +// OBSOLETE case 30: /* fp13 */ \ +// OBSOLETE case 31: /* fp14 */ \ +// OBSOLETE case 32: /* fp15 */ \ +// OBSOLETE case 33: /* fp16 */ \ +// OBSOLETE case 34: /* fp17 */ \ +// OBSOLETE case 35: /* fp18 */ \ +// OBSOLETE case 36: /* fp19 */ \ +// OBSOLETE case 37: /* fp20 */ \ +// OBSOLETE case 38: /* fp21 */ \ +// OBSOLETE case 39: /* fp22 */ \ +// OBSOLETE case 40: /* fp23 */ \ +// OBSOLETE case 41: /* fp24 */ \ +// OBSOLETE case 42: /* fp25 */ \ +// OBSOLETE case 43: /* fp26 */ \ +// OBSOLETE case 44: /* fp27 */ \ +// OBSOLETE case 45: /* fp28 */ \ +// OBSOLETE case 46: /* fp29 */ \ +// OBSOLETE case 47: /* fp30 */ \ +// OBSOLETE case 48: /* fp31 */ \ +// OBSOLETE addr = ((int) &foo.u_fpasave.fpa_regs[(regno)-18] - (int)&foo); \ +// OBSOLETE } \ +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Total amount of space needed to store our copies of the machine's +// OBSOLETE register state, the array `registers'. 10 i*86 registers, 8 i387 +// OBSOLETE registers, and 31 Weitek 1167 registers */ +// OBSOLETE +// OBSOLETE #undef REGISTER_BYTES +// OBSOLETE #define REGISTER_BYTES ((10 * 4) + (8 * 10) + (31 * 4)) +// OBSOLETE +// OBSOLETE /* Nonzero if register N requires conversion +// OBSOLETE from raw format to virtual format. */ +// OBSOLETE +// OBSOLETE #undef REGISTER_CONVERTIBLE +// OBSOLETE #define REGISTER_CONVERTIBLE(N) \ +// OBSOLETE (((N) < 3) ? 0 : \ +// OBSOLETE ((N) < 5) ? 1 : \ +// OBSOLETE ((N) < 8) ? 0 : \ +// OBSOLETE ((N) < 14) ? 1 : \ +// OBSOLETE 0) +// OBSOLETE +// OBSOLETE #include "floatformat.h" +// OBSOLETE +// OBSOLETE /* Convert data from raw format for register REGNUM in buffer FROM +// OBSOLETE to virtual format with type TYPE in buffer TO. */ +// OBSOLETE +// OBSOLETE #undef REGISTER_CONVERT_TO_VIRTUAL +// OBSOLETE #define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \ +// OBSOLETE { \ +// OBSOLETE DOUBLEST val; \ +// OBSOLETE floatformat_to_doublest (&floatformat_i387_ext, (FROM), &val); \ +// OBSOLETE deprecated_store_floating ((TO), TYPE_LENGTH (TYPE), val); \ +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Convert data from virtual format with type TYPE in buffer FROM +// OBSOLETE to raw format for register REGNUM in buffer TO. */ +// OBSOLETE +// OBSOLETE #undef REGISTER_CONVERT_TO_RAW +// OBSOLETE #define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO) \ +// OBSOLETE { \ +// OBSOLETE DOUBLEST val = deprecated_extract_floating ((FROM), TYPE_LENGTH (TYPE)); \ +// OBSOLETE floatformat_from_doublest (&floatformat_i387_ext, &val, (TO)); \ +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Return the GDB type object for the "standard" data type +// OBSOLETE of data in register N. */ +// OBSOLETE +// OBSOLETE #undef REGISTER_VIRTUAL_TYPE +// OBSOLETE #define REGISTER_VIRTUAL_TYPE(N) \ +// OBSOLETE ((N < 3) ? builtin_type_int : \ +// OBSOLETE (N < 5) ? builtin_type_double : \ +// OBSOLETE (N < 8) ? builtin_type_int : \ +// OBSOLETE (N < 14) ? builtin_type_double : \ +// OBSOLETE builtin_type_int) +// OBSOLETE +// OBSOLETE /* Store the address of the place in which to copy the structure the +// OBSOLETE subroutine will return. This is called from call_function. +// OBSOLETE Native cc passes the address in eax, gcc (up to version 2.5.8) +// OBSOLETE passes it on the stack. gcc should be fixed in future versions to +// OBSOLETE adopt native cc conventions. */ +// OBSOLETE +// OBSOLETE #undef DEPRECATED_PUSH_ARGUMENTS +// OBSOLETE #undef STORE_STRUCT_RETURN +// OBSOLETE #define STORE_STRUCT_RETURN(ADDR, SP) write_register(0, (ADDR)) +// OBSOLETE +// OBSOLETE /* Extract from an array REGBUF containing the (raw) register state +// OBSOLETE a function return value of type TYPE, and copy that, in virtual format, +// OBSOLETE into VALBUF. */ +// OBSOLETE +// OBSOLETE #undef DEPRECATED_EXTRACT_RETURN_VALUE +// OBSOLETE #define DEPRECATED_EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \ +// OBSOLETE symmetry_extract_return_value(TYPE, REGBUF, VALBUF) +// OBSOLETE +// OBSOLETE /* The following redefines make backtracing through sigtramp work. +// OBSOLETE They manufacture a fake sigtramp frame and obtain the saved pc in sigtramp +// OBSOLETE from the sigcontext structure which is pushed by the kernel on the +// OBSOLETE user stack, along with a pointer to it. */ +// OBSOLETE +// OBSOLETE #define IN_SIGTRAMP(pc, name) ((name) && STREQ ("_sigcode", name)) +// OBSOLETE +// OBSOLETE /* Offset to saved PC in sigcontext, from <signal.h>. */ +// OBSOLETE #define SIGCONTEXT_PC_OFFSET 16 +// OBSOLETE +// OBSOLETE #endif /* ifndef TM_SYMMETRY_H */ diff --git a/gdb/config/i386/xm-ptx.h b/gdb/config/i386/xm-ptx.h index 8987f297133..1ecae0cd9d7 100644 --- a/gdb/config/i386/xm-ptx.h +++ b/gdb/config/i386/xm-ptx.h @@ -1,38 +1,38 @@ -/* Definitions to make GDB run on a Sequent Symmetry under ptx, with - Weitek 1167 and i387 support. - Copyright 1986, 1987, 1989, 1992, 1993, 1994, 1995 - Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* Symmetry version by Jay Vosburgh (fubar@sequent.com) */ - -#ifdef _SEQUENT_PTX4_ -#include "config/xm-sysv4.h" -#endif /* _SEQUENT_PTX4_ */ - -/* This machine doesn't have the siginterrupt call. */ -#define NO_SIGINTERRUPT - -#define HAVE_WAIT_STRUCT - -#undef HAVE_TERMIO -#define HAVE_TERMIOS -#define USG - -#define USE_O_NOCTTY +// OBSOLETE /* Definitions to make GDB run on a Sequent Symmetry under ptx, with +// OBSOLETE Weitek 1167 and i387 support. +// OBSOLETE Copyright 1986, 1987, 1989, 1992, 1993, 1994, 1995 +// OBSOLETE Free Software Foundation, Inc. +// OBSOLETE +// OBSOLETE This file is part of GDB. +// OBSOLETE +// OBSOLETE This program is free software; you can redistribute it and/or modify +// OBSOLETE it under the terms of the GNU General Public License as published by +// OBSOLETE the Free Software Foundation; either version 2 of the License, or +// OBSOLETE (at your option) any later version. +// OBSOLETE +// OBSOLETE This program is distributed in the hope that it will be useful, +// OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of +// OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// OBSOLETE GNU General Public License for more details. +// OBSOLETE +// OBSOLETE You should have received a copy of the GNU General Public License +// OBSOLETE along with this program; if not, write to the Free Software +// OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, +// OBSOLETE Boston, MA 02111-1307, USA. */ +// OBSOLETE +// OBSOLETE /* Symmetry version by Jay Vosburgh (fubar@sequent.com) */ +// OBSOLETE +// OBSOLETE #ifdef _SEQUENT_PTX4_ +// OBSOLETE #include "config/xm-sysv4.h" +// OBSOLETE #endif /* _SEQUENT_PTX4_ */ +// OBSOLETE +// OBSOLETE /* This machine doesn't have the siginterrupt call. */ +// OBSOLETE #define NO_SIGINTERRUPT +// OBSOLETE +// OBSOLETE #define HAVE_WAIT_STRUCT +// OBSOLETE +// OBSOLETE #undef HAVE_TERMIO +// OBSOLETE #define HAVE_TERMIOS +// OBSOLETE #define USG +// OBSOLETE +// OBSOLETE #define USE_O_NOCTTY diff --git a/gdb/config/i386/xm-ptx4.h b/gdb/config/i386/xm-ptx4.h index 605941315c9..7f0605d3e6a 100644 --- a/gdb/config/i386/xm-ptx4.h +++ b/gdb/config/i386/xm-ptx4.h @@ -1,27 +1,27 @@ -/* Definitions to make GDB run on a Sequent Symmetry under ptx, with - Weitek 1167 and i387 support. - Copyright 1986, 1987, 1989, 1992, 1993, 1994 - Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* Symmetry version by Jay Vosburgh (fubar@sequent.com) */ - -#include "config/xm-sysv4.h" - -#include "i386/xm-ptx.h" +// OBSOLETE /* Definitions to make GDB run on a Sequent Symmetry under ptx, with +// OBSOLETE Weitek 1167 and i387 support. +// OBSOLETE Copyright 1986, 1987, 1989, 1992, 1993, 1994 +// OBSOLETE Free Software Foundation, Inc. +// OBSOLETE +// OBSOLETE This file is part of GDB. +// OBSOLETE +// OBSOLETE This program is free software; you can redistribute it and/or modify +// OBSOLETE it under the terms of the GNU General Public License as published by +// OBSOLETE the Free Software Foundation; either version 2 of the License, or +// OBSOLETE (at your option) any later version. +// OBSOLETE +// OBSOLETE This program is distributed in the hope that it will be useful, +// OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of +// OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// OBSOLETE GNU General Public License for more details. +// OBSOLETE +// OBSOLETE You should have received a copy of the GNU General Public License +// OBSOLETE along with this program; if not, write to the Free Software +// OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, +// OBSOLETE Boston, MA 02111-1307, USA. */ +// OBSOLETE +// OBSOLETE /* Symmetry version by Jay Vosburgh (fubar@sequent.com) */ +// OBSOLETE +// OBSOLETE #include "config/xm-sysv4.h" +// OBSOLETE +// OBSOLETE #include "i386/xm-ptx.h" diff --git a/gdb/config/i386/xm-symmetry.h b/gdb/config/i386/xm-symmetry.h index 781a343961a..27711f257d4 100644 --- a/gdb/config/i386/xm-symmetry.h +++ b/gdb/config/i386/xm-symmetry.h @@ -1,28 +1,28 @@ -/* Definitions to make GDB run on a Sequent Symmetry under - dynix 3.1, with Weitek 1167 and i387 support. - Copyright 1986, 1987, 1989, 1992, 1993, 1994 - Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* Symmetry version by Jay Vosburgh (fubar@sequent.com) */ - -/* This machine doesn't have the siginterrupt call. */ -#define NO_SIGINTERRUPT - -#define HAVE_WAIT_STRUCT +// OBSOLETE /* Definitions to make GDB run on a Sequent Symmetry under +// OBSOLETE dynix 3.1, with Weitek 1167 and i387 support. +// OBSOLETE Copyright 1986, 1987, 1989, 1992, 1993, 1994 +// OBSOLETE Free Software Foundation, Inc. +// OBSOLETE +// OBSOLETE This file is part of GDB. +// OBSOLETE +// OBSOLETE This program is free software; you can redistribute it and/or modify +// OBSOLETE it under the terms of the GNU General Public License as published by +// OBSOLETE the Free Software Foundation; either version 2 of the License, or +// OBSOLETE (at your option) any later version. +// OBSOLETE +// OBSOLETE This program is distributed in the hope that it will be useful, +// OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of +// OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// OBSOLETE GNU General Public License for more details. +// OBSOLETE +// OBSOLETE You should have received a copy of the GNU General Public License +// OBSOLETE along with this program; if not, write to the Free Software +// OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, +// OBSOLETE Boston, MA 02111-1307, USA. */ +// OBSOLETE +// OBSOLETE /* Symmetry version by Jay Vosburgh (fubar@sequent.com) */ +// OBSOLETE +// OBSOLETE /* This machine doesn't have the siginterrupt call. */ +// OBSOLETE #define NO_SIGINTERRUPT +// OBSOLETE +// OBSOLETE #define HAVE_WAIT_STRUCT diff --git a/gdb/config/mips/mipsm3.mh b/gdb/config/mips/mipsm3.mh index 864ad57e24d..fc9f37c3f4a 100644 --- a/gdb/config/mips/mipsm3.mh +++ b/gdb/config/mips/mipsm3.mh @@ -1,6 +1,6 @@ -# Host: Little endian MIPS machine such as pmax -# running Mach 3.0 operating system - -NATDEPFILES= mipsm3-nat.o m3-nat.o core-aout.o -XM_FILE= xm-mipsm3.h -NAT_FILE= ../nm-m3.h +# OBSOLETE # Host: Little endian MIPS machine such as pmax +# OBSOLETE # running Mach 3.0 operating system +# OBSOLETE +# OBSOLETE NATDEPFILES= mipsm3-nat.o m3-nat.o core-aout.o +# OBSOLETE XM_FILE= xm-mipsm3.h +# OBSOLETE NAT_FILE= ../nm-m3.h diff --git a/gdb/config/mips/mipsm3.mt b/gdb/config/mips/mipsm3.mt index 66856d16c04..837b27ee65e 100644 --- a/gdb/config/mips/mipsm3.mt +++ b/gdb/config/mips/mipsm3.mt @@ -1,4 +1,4 @@ -# Target: Little-endian MIPS machine such as pmax -# running Mach 3.0 operating system -TDEPFILES= mips-tdep.o -TM_FILE= tm-mipsm3.h +# OBSOLETE # Target: Little-endian MIPS machine such as pmax +# OBSOLETE # running Mach 3.0 operating system +# OBSOLETE TDEPFILES= mips-tdep.o +# OBSOLETE TM_FILE= tm-mipsm3.h diff --git a/gdb/config/mips/tm-mipsm3.h b/gdb/config/mips/tm-mipsm3.h index 9e2f4901d7a..dbc10d7117b 100644 --- a/gdb/config/mips/tm-mipsm3.h +++ b/gdb/config/mips/tm-mipsm3.h @@ -1,67 +1,67 @@ -/* Definitions to make GDB run on a mips box under Mach 3.0 - Copyright 1992, 1993, 1998 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* Mach specific definitions for little endian mips (e.g. pmax) - * running Mach 3.0 - * - * Author: Jukka Virtanen <jtv@hut.fi> - */ - -/* Include common definitions for Mach3 systems */ -#include "config/nm-m3.h" - -/* Define offsets to access CPROC stack when it does not have - * a kernel thread. - */ - -/* From mk/user/threads/mips/csw.s */ -#define SAVED_FP (12*4) -#define SAVED_PC (13*4) -#define SAVED_BYTES (14*4) - -/* Using these, define our offsets to items strored in - * cproc_switch in csw.s - */ -#define MACHINE_CPROC_SP_OFFSET SAVED_BYTES -#define MACHINE_CPROC_PC_OFFSET SAVED_PC -#define MACHINE_CPROC_FP_OFFSET SAVED_FP - -/* Thread flavors used in setting the Trace state. - - * In <mach/machine/thread_status.h> - */ -#define TRACE_FLAVOR MIPS_EXC_STATE -#define TRACE_FLAVOR_SIZE MIPS_EXC_STATE_COUNT -#define TRACE_SET(x,state) ((struct mips_exc_state *)state)->cause = EXC_SST; -#define TRACE_CLEAR(x,state) 0 - -/* Mach supports attach/detach */ -#define ATTACH_DETACH 1 - -#include "mips/tm-mips.h" - -/* Address of end of user stack space. - * for MACH, see <machine/vmparam.h> - */ -#undef STACK_END_ADDR -#define STACK_END_ADDR USRSTACK - -/* Output registers in tabular format */ -#define TABULAR_REGISTER_OUTPUT +// OBSOLETE /* Definitions to make GDB run on a mips box under Mach 3.0 +// OBSOLETE Copyright 1992, 1993, 1998 Free Software Foundation, Inc. +// OBSOLETE +// OBSOLETE This file is part of GDB. +// OBSOLETE +// OBSOLETE This program is free software; you can redistribute it and/or modify +// OBSOLETE it under the terms of the GNU General Public License as published by +// OBSOLETE the Free Software Foundation; either version 2 of the License, or +// OBSOLETE (at your option) any later version. +// OBSOLETE +// OBSOLETE This program is distributed in the hope that it will be useful, +// OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of +// OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// OBSOLETE GNU General Public License for more details. +// OBSOLETE +// OBSOLETE You should have received a copy of the GNU General Public License +// OBSOLETE along with this program; if not, write to the Free Software +// OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, +// OBSOLETE Boston, MA 02111-1307, USA. */ +// OBSOLETE +// OBSOLETE /* Mach specific definitions for little endian mips (e.g. pmax) +// OBSOLETE * running Mach 3.0 +// OBSOLETE * +// OBSOLETE * Author: Jukka Virtanen <jtv@hut.fi> +// OBSOLETE */ +// OBSOLETE +// OBSOLETE /* Include common definitions for Mach3 systems */ +// OBSOLETE #include "config/nm-m3.h" +// OBSOLETE +// OBSOLETE /* Define offsets to access CPROC stack when it does not have +// OBSOLETE * a kernel thread. +// OBSOLETE */ +// OBSOLETE +// OBSOLETE /* From mk/user/threads/mips/csw.s */ +// OBSOLETE #define SAVED_FP (12*4) +// OBSOLETE #define SAVED_PC (13*4) +// OBSOLETE #define SAVED_BYTES (14*4) +// OBSOLETE +// OBSOLETE /* Using these, define our offsets to items strored in +// OBSOLETE * cproc_switch in csw.s +// OBSOLETE */ +// OBSOLETE #define MACHINE_CPROC_SP_OFFSET SAVED_BYTES +// OBSOLETE #define MACHINE_CPROC_PC_OFFSET SAVED_PC +// OBSOLETE #define MACHINE_CPROC_FP_OFFSET SAVED_FP +// OBSOLETE +// OBSOLETE /* Thread flavors used in setting the Trace state. +// OBSOLETE +// OBSOLETE * In <mach/machine/thread_status.h> +// OBSOLETE */ +// OBSOLETE #define TRACE_FLAVOR MIPS_EXC_STATE +// OBSOLETE #define TRACE_FLAVOR_SIZE MIPS_EXC_STATE_COUNT +// OBSOLETE #define TRACE_SET(x,state) ((struct mips_exc_state *)state)->cause = EXC_SST; +// OBSOLETE #define TRACE_CLEAR(x,state) 0 +// OBSOLETE +// OBSOLETE /* Mach supports attach/detach */ +// OBSOLETE #define ATTACH_DETACH 1 +// OBSOLETE +// OBSOLETE #include "mips/tm-mips.h" +// OBSOLETE +// OBSOLETE /* Address of end of user stack space. +// OBSOLETE * for MACH, see <machine/vmparam.h> +// OBSOLETE */ +// OBSOLETE #undef STACK_END_ADDR +// OBSOLETE #define STACK_END_ADDR USRSTACK +// OBSOLETE +// OBSOLETE /* Output registers in tabular format */ +// OBSOLETE #define TABULAR_REGISTER_OUTPUT diff --git a/gdb/config/mips/xm-mipsm3.h b/gdb/config/mips/xm-mipsm3.h index b2e9f4d5330..2207d3ab896 100644 --- a/gdb/config/mips/xm-mipsm3.h +++ b/gdb/config/mips/xm-mipsm3.h @@ -1,29 +1,29 @@ -/* Definitions to make GDB run on a mips box under 4.3bsd. - Copyright 1986, 1987, 1989, 1993 Free Software Foundation, Inc. - Contributed by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin - and by Alessandro Forin(af@cs.cmu.edu) at CMU - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#define KERNEL_U_ADDR 0 /* Not needed. */ - -/* Only used for core files on DECstations. */ - -#define REGISTER_U_ADDR(addr, blockend, regno) \ - if (regno < 38) addr = (NBPG*UPAGES) + (regno - 38)*sizeof(int);\ - else addr = 0; /* ..somewhere in the pcb */ +// OBSOLETE /* Definitions to make GDB run on a mips box under 4.3bsd. +// OBSOLETE Copyright 1986, 1987, 1989, 1993 Free Software Foundation, Inc. +// OBSOLETE Contributed by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin +// OBSOLETE and by Alessandro Forin(af@cs.cmu.edu) at CMU +// OBSOLETE +// OBSOLETE This file is part of GDB. +// OBSOLETE +// OBSOLETE This program is free software; you can redistribute it and/or modify +// OBSOLETE it under the terms of the GNU General Public License as published by +// OBSOLETE the Free Software Foundation; either version 2 of the License, or +// OBSOLETE (at your option) any later version. +// OBSOLETE +// OBSOLETE This program is distributed in the hope that it will be useful, +// OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of +// OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// OBSOLETE GNU General Public License for more details. +// OBSOLETE +// OBSOLETE You should have received a copy of the GNU General Public License +// OBSOLETE along with this program; if not, write to the Free Software +// OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, +// OBSOLETE Boston, MA 02111-1307, USA. */ +// OBSOLETE +// OBSOLETE #define KERNEL_U_ADDR 0 /* Not needed. */ +// OBSOLETE +// OBSOLETE /* Only used for core files on DECstations. */ +// OBSOLETE +// OBSOLETE #define REGISTER_U_ADDR(addr, blockend, regno) \ +// OBSOLETE if (regno < 38) addr = (NBPG*UPAGES) + (regno - 38)*sizeof(int);\ +// OBSOLETE else addr = 0; /* ..somewhere in the pcb */ diff --git a/gdb/config/nm-m3.h b/gdb/config/nm-m3.h index 07bc26aa0c4..0cc84e34daf 100644 --- a/gdb/config/nm-m3.h +++ b/gdb/config/nm-m3.h @@ -1,126 +1,126 @@ -/* Mach 3.0 common definitions and global vars. - - Copyright 1992, 1993, 1994, 1996 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#ifndef NM_M3_H -#define NM_M3_H - -#include <mach.h> -#include "regcache.h" - -/* Mach3 doesn't declare errno in <errno.h>. */ -extern int errno; - -/* Task port of our debugged inferior. */ - -extern task_t inferior_task; - -/* Thread port of the current thread in the inferior. */ - -extern thread_t current_thread; - -/* If nonzero, we must suspend/abort && resume threads - * when setting or getting the state. - */ -extern int must_suspend_thread; - -#define PREPARE_TO_PROCEED(select_it) mach3_prepare_to_proceed(select_it) - -/* Try to get the privileged host port for authentication to machid - - * If you can get this, you may debug anything on this host. - * - * If you can't, gdb gives it's own task port as the - * authentication port - */ -#define mach_privileged_host_port() task_by_pid(-1) - -/* - * This is the MIG ID number of the emulator/server bsd_execve() RPC call. - * - * It SHOULD never change, but if it does, gdb `run' - * command won't work until you fix this define. - * - */ -#define MIG_EXEC_SYSCALL_ID 101000 - -/* If our_message_port gets a msg with this ID, - * GDB suspends it's inferior and enters command level. - * (Useful at least if ^C does not work) - */ -#define GDB_MESSAGE_ID_STOP 0x41151 - -/* wait3 WNOHANG is defined in <sys/wait.h> but - * for some reason gdb does not want to include - * that file. - * - * If your system defines WNOHANG differently, this has to be changed. - */ -#define WNOHANG 1 - -/* Before storing, we need to read all the registers. */ - -#define CHILD_PREPARE_TO_STORE() deprecated_read_register_bytes (0, NULL, REGISTER_BYTES) - -/* Check if the inferior exists */ -#define MACH_ERROR_NO_INFERIOR \ - do if (!MACH_PORT_VALID (inferior_task)) \ - error ("Inferior task does not exist."); while(0) - -/* Error handler for mach calls */ -#define CHK(str,ret) \ - do if (ret != KERN_SUCCESS) \ - error ("Gdb %s [%d] %s : %s\n",__FILE__,__LINE__,str, \ - mach_error_string(ret)); while(0) - -/* This is from POE9 emulator/emul_stack.h - */ -/* - * Top of emulator stack holds link and reply port. - */ -struct emul_stack_top - { - struct emul_stack_top *link; - mach_port_t reply_port; - }; - -#define EMULATOR_STACK_SIZE (4096*4) - -#define THREAD_ALLOWED_TO_BREAK(mid) mach_thread_for_breakpoint (mid) - -#define THREAD_PARSE_ID(arg) mach_thread_parse_id (arg) - -#define THREAD_OUTPUT_ID(mid) mach_thread_output_id (mid) - -#define ATTACH_TO_THREAD attach_to_thread - -/* Don't do wait_for_inferior on attach. */ -#define ATTACH_NO_WAIT - -/* Do Mach 3 dependent operations when ^C or a STOP is requested */ -#define DO_QUIT() mach3_quit () - -#if 0 -/* This is bogus. It is NOT OK to quit out of target_wait. */ -/* If in mach_msg() and ^C is typed set immediate_quit */ -#define REQUEST_QUIT() mach3_request_quit () -#endif - -#endif /* NM_M3_H */ +// OBSOLETE /* Mach 3.0 common definitions and global vars. +// OBSOLETE +// OBSOLETE Copyright 1992, 1993, 1994, 1996 Free Software Foundation, Inc. +// OBSOLETE +// OBSOLETE This file is part of GDB. +// OBSOLETE +// OBSOLETE This program is free software; you can redistribute it and/or modify +// OBSOLETE it under the terms of the GNU General Public License as published by +// OBSOLETE the Free Software Foundation; either version 2 of the License, or +// OBSOLETE (at your option) any later version. +// OBSOLETE +// OBSOLETE This program is distributed in the hope that it will be useful, +// OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of +// OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// OBSOLETE GNU General Public License for more details. +// OBSOLETE +// OBSOLETE You should have received a copy of the GNU General Public License +// OBSOLETE along with this program; if not, write to the Free Software +// OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, +// OBSOLETE Boston, MA 02111-1307, USA. */ +// OBSOLETE +// OBSOLETE #ifndef NM_M3_H +// OBSOLETE #define NM_M3_H +// OBSOLETE +// OBSOLETE #include <mach.h> +// OBSOLETE #include "regcache.h" +// OBSOLETE +// OBSOLETE /* Mach3 doesn't declare errno in <errno.h>. */ +// OBSOLETE extern int errno; +// OBSOLETE +// OBSOLETE /* Task port of our debugged inferior. */ +// OBSOLETE +// OBSOLETE extern task_t inferior_task; +// OBSOLETE +// OBSOLETE /* Thread port of the current thread in the inferior. */ +// OBSOLETE +// OBSOLETE extern thread_t current_thread; +// OBSOLETE +// OBSOLETE /* If nonzero, we must suspend/abort && resume threads +// OBSOLETE * when setting or getting the state. +// OBSOLETE */ +// OBSOLETE extern int must_suspend_thread; +// OBSOLETE +// OBSOLETE #define PREPARE_TO_PROCEED(select_it) mach3_prepare_to_proceed(select_it) +// OBSOLETE +// OBSOLETE /* Try to get the privileged host port for authentication to machid +// OBSOLETE +// OBSOLETE * If you can get this, you may debug anything on this host. +// OBSOLETE * +// OBSOLETE * If you can't, gdb gives it's own task port as the +// OBSOLETE * authentication port +// OBSOLETE */ +// OBSOLETE #define mach_privileged_host_port() task_by_pid(-1) +// OBSOLETE +// OBSOLETE /* +// OBSOLETE * This is the MIG ID number of the emulator/server bsd_execve() RPC call. +// OBSOLETE * +// OBSOLETE * It SHOULD never change, but if it does, gdb `run' +// OBSOLETE * command won't work until you fix this define. +// OBSOLETE * +// OBSOLETE */ +// OBSOLETE #define MIG_EXEC_SYSCALL_ID 101000 +// OBSOLETE +// OBSOLETE /* If our_message_port gets a msg with this ID, +// OBSOLETE * GDB suspends it's inferior and enters command level. +// OBSOLETE * (Useful at least if ^C does not work) +// OBSOLETE */ +// OBSOLETE #define GDB_MESSAGE_ID_STOP 0x41151 +// OBSOLETE +// OBSOLETE /* wait3 WNOHANG is defined in <sys/wait.h> but +// OBSOLETE * for some reason gdb does not want to include +// OBSOLETE * that file. +// OBSOLETE * +// OBSOLETE * If your system defines WNOHANG differently, this has to be changed. +// OBSOLETE */ +// OBSOLETE #define WNOHANG 1 +// OBSOLETE +// OBSOLETE /* Before storing, we need to read all the registers. */ +// OBSOLETE +// OBSOLETE #define CHILD_PREPARE_TO_STORE() deprecated_read_register_bytes (0, NULL, REGISTER_BYTES) +// OBSOLETE +// OBSOLETE /* Check if the inferior exists */ +// OBSOLETE #define MACH_ERROR_NO_INFERIOR \ +// OBSOLETE do if (!MACH_PORT_VALID (inferior_task)) \ +// OBSOLETE error ("Inferior task does not exist."); while(0) +// OBSOLETE +// OBSOLETE /* Error handler for mach calls */ +// OBSOLETE #define CHK(str,ret) \ +// OBSOLETE do if (ret != KERN_SUCCESS) \ +// OBSOLETE error ("Gdb %s [%d] %s : %s\n",__FILE__,__LINE__,str, \ +// OBSOLETE mach_error_string(ret)); while(0) +// OBSOLETE +// OBSOLETE /* This is from POE9 emulator/emul_stack.h +// OBSOLETE */ +// OBSOLETE /* +// OBSOLETE * Top of emulator stack holds link and reply port. +// OBSOLETE */ +// OBSOLETE struct emul_stack_top +// OBSOLETE { +// OBSOLETE struct emul_stack_top *link; +// OBSOLETE mach_port_t reply_port; +// OBSOLETE }; +// OBSOLETE +// OBSOLETE #define EMULATOR_STACK_SIZE (4096*4) +// OBSOLETE +// OBSOLETE #define THREAD_ALLOWED_TO_BREAK(mid) mach_thread_for_breakpoint (mid) +// OBSOLETE +// OBSOLETE #define THREAD_PARSE_ID(arg) mach_thread_parse_id (arg) +// OBSOLETE +// OBSOLETE #define THREAD_OUTPUT_ID(mid) mach_thread_output_id (mid) +// OBSOLETE +// OBSOLETE #define ATTACH_TO_THREAD attach_to_thread +// OBSOLETE +// OBSOLETE /* Don't do wait_for_inferior on attach. */ +// OBSOLETE #define ATTACH_NO_WAIT +// OBSOLETE +// OBSOLETE /* Do Mach 3 dependent operations when ^C or a STOP is requested */ +// OBSOLETE #define DO_QUIT() mach3_quit () +// OBSOLETE +// OBSOLETE #if 0 +// OBSOLETE /* This is bogus. It is NOT OK to quit out of target_wait. */ +// OBSOLETE /* If in mach_msg() and ^C is typed set immediate_quit */ +// OBSOLETE #define REQUEST_QUIT() mach3_request_quit () +// OBSOLETE #endif +// OBSOLETE +// OBSOLETE #endif /* NM_M3_H */ diff --git a/gdb/config/pa/tm-hppa.h b/gdb/config/pa/tm-hppa.h index 9c26c798258..6089b32b526 100644 --- a/gdb/config/pa/tm-hppa.h +++ b/gdb/config/pa/tm-hppa.h @@ -441,11 +441,9 @@ extern int hppa_frame_num_args (struct frame_info *frame); #define FRAME_ARGS_SKIP 0 #endif -#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \ - hppa_frame_find_saved_regs (frame_info, &frame_saved_regs) -extern void hppa_frame_find_saved_regs (struct frame_info *, - struct frame_saved_regs *); - +extern void hppa_frame_init_saved_regs (struct frame_info *); +#define DEPRECATED_FRAME_INIT_SAVED_REGS(FI) \ + hppa_frame_init_saved_regs (FI) /* Things needed for making the inferior call functions. */ diff --git a/gdb/config/pa/tm-hppa64.h b/gdb/config/pa/tm-hppa64.h index b2b98e40895..503e42688df 100644 --- a/gdb/config/pa/tm-hppa64.h +++ b/gdb/config/pa/tm-hppa64.h @@ -312,11 +312,11 @@ call_dummy for (i = 0; i < NUM_REGS; i++) \ { \ if (i == SP_REGNUM) \ - (FSR)->regs[SP_REGNUM] = read_memory_integer (TMP1 + SP_REGNUM * 8, 8); \ + (FSR)[SP_REGNUM] = read_memory_integer (TMP1 + SP_REGNUM * 8, 8); \ else if (i >= FP0_REGNUM) \ - (FSR)->regs[i] = TMP2 + (i - FP0_REGNUM) * 8; \ + (FSR)[i] = TMP2 + (i - FP0_REGNUM) * 8; \ else \ - (FSR)->regs[i] = TMP1 + i * 8; \ + (FSR)[i] = TMP1 + i * 8; \ } \ } diff --git a/gdb/config/pa/tm-hppah.h b/gdb/config/pa/tm-hppah.h index 4e68de992f1..5a457a9db3a 100644 --- a/gdb/config/pa/tm-hppah.h +++ b/gdb/config/pa/tm-hppah.h @@ -46,9 +46,8 @@ extern void hppa_hpux_frame_base_before_sigtramp (struct frame_info *fi, #define FRAME_BASE_BEFORE_SIGTRAMP(FRAME, TMP) \ hppa_hpux_frame_base_before_sigtramp (FRAME, TMP) -struct frame_saved_regs; extern void hppa_hpux_frame_find_saved_regs_in_sigtramp - (struct frame_info *fi, struct frame_saved_regs *fsr); + (struct frame_info *fi, CORE_ADDR *fsr); #define FRAME_FIND_SAVED_REGS_IN_SIGTRAMP(FRAME, FSR) \ hppa_hpux_frame_find_saved_regs_in_sigtramp (FRAME, FSR) diff --git a/gdb/config/sparc/tm-sparc.h b/gdb/config/sparc/tm-sparc.h index ef3996232cc..544a562ffae 100644 --- a/gdb/config/sparc/tm-sparc.h +++ b/gdb/config/sparc/tm-sparc.h @@ -406,53 +406,6 @@ extern CORE_ADDR sparc_pc_adjust (CORE_ADDR); /* DEPRECATED_FRAME_CHAIN takes a frame's nominal address and produces the frame's chain-pointer. */ -/* In the case of the Sun 4, the frame-chain's nominal address - is held in the frame pointer register. - - On the Sun4, the frame (in %fp) is %sp for the previous frame. - From the previous frame's %sp, we can find the previous frame's - %fp: it is in the save area just above the previous frame's %sp. - - If we are setting up an arbitrary frame, we'll need to know where - it ends. Hence the following. This part of the frame cache - structure should be checked before it is assumed that this frame's - bottom is in the stack pointer. - - If there isn't a frame below this one, the bottom of this frame is - in the stack pointer. - - If there is a frame below this one, and the frame pointers are - identical, it's a leaf frame and the bottoms are the same also. - - Otherwise the bottom of this frame is the top of the next frame. - - The bottom field is misnamed, since it might imply that memory from - bottom to frame contains this frame. That need not be true if - stack frames are allocated in different segments (e.g. some on a - stack, some on a heap in the data segment). - - GCC 2.6 and later can generate ``flat register window'' code that - makes frames by explicitly saving those registers that need to be - saved. %i7 is used as the frame pointer, and the frame is laid out - so that flat and non-flat calls can be intermixed freely within a - program. Unfortunately for GDB, this means it must detect and - record the flatness of frames. - - Since the prologue in a flat frame also tells us where fp and pc - have been stashed (the frame is of variable size, so their location - is not fixed), it's convenient to record them in the frame info. */ - -#define EXTRA_FRAME_INFO \ - CORE_ADDR bottom; \ - int in_prologue; \ - int flat; \ - /* Following fields only relevant for flat frames. */ \ - CORE_ADDR pc_addr; \ - CORE_ADDR fp_addr; \ - /* Add this to ->frame to get the value of the stack pointer at the */ \ - /* time of the register saves. */ \ - int sp_offset; - /* We need to override DEPRECATED_GET_SAVED_REGISTER so that we can deal with the way outs change into ins in different frames. */ diff --git a/gdb/configure.host b/gdb/configure.host index 98acc7e02af..8f96b0a842c 100644 --- a/gdb/configure.host +++ b/gdb/configure.host @@ -49,9 +49,9 @@ hppa*-*-hpux*) gdb_host=hppahpux ;; # OBSOLETE hppa*-*-osf*) gdb_host=hppaosf ;; i[3456]86-ncr-*) gdb_host=ncr3000 ;; -i[3456]86-sequent-bsd*) gdb_host=symmetry ;; # dynix -i[3456]86-sequent-sysv4*) gdb_host=ptx4 ;; -i[3456]86-sequent-sysv*) gdb_host=ptx ;; +# OBSOLETE i[3456]86-sequent-bsd*) gdb_host=symmetry ;; # dynix +# OBSOLETE i[3456]86-sequent-sysv4*) gdb_host=ptx4 ;; +# OBSOLETE i[3456]86-sequent-sysv*) gdb_host=ptx ;; i[3456]86-*-bsd*) gdb_host=i386bsd ;; i[3456]86-*-dgux*) gdb_host=i386v4 ;; i[3456]86-*-freebsd*) gdb_host=fbsd ;; @@ -94,7 +94,7 @@ m68*-sun-sunos3*) gdb_host=sun3os3 ;; m68*-sun-sunos4*) gdb_host=sun3os4 ;; m68*-sun-*) gdb_host=sun3os4 ;; -mips-dec-mach3*) gdb_host=mipsm3 ;; +# OBSOLETE mips-dec-mach3*) gdb_host=mipsm3 ;; mips-dec-*) gdb_host=decstation ;; mips-little-*) gdb_host=littlemips ;; mips-sgi-irix3*) gdb_host=irix3 ;; diff --git a/gdb/configure.tgt b/gdb/configure.tgt index 9a4dba3bf0b..df174a79369 100644 --- a/gdb/configure.tgt +++ b/gdb/configure.tgt @@ -81,9 +81,9 @@ hppa*-*-hiux*) gdb_target=hppahpux ;; # OBSOLETE hppa*-*-osf*) gdb_target=hppaosf ;; hppa*-*-*) gdb_target=hppa ;; -i[3456]86-sequent-bsd*) gdb_target=symmetry ;; -i[3456]86-sequent-sysv4*) gdb_target=ptx4 ;; -i[3456]86-sequent-sysv*) gdb_target=ptx ;; +# OBSOLETE i[3456]86-sequent-bsd*) gdb_target=symmetry ;; +# OBSOLETE i[3456]86-sequent-sysv4*) gdb_target=ptx4 ;; +# OBSOLETE i[3456]86-sequent-sysv*) gdb_target=ptx ;; i[3456]86-ncr-*) gdb_target=ncr3000 ;; i[3456]86-*-bsd*) gdb_target=i386bsd ;; i[3456]86-*-netbsd*) gdb_target=nbsd ;; @@ -172,7 +172,7 @@ mips*-*-linux*) gdb_target=linux build_gdbserver=yes ;; mips*-*-netbsd*) gdb_target=nbsd ;; -mips*-*-mach3*) gdb_target=mipsm3 ;; +# OBSOLETE mips*-*-mach3*) gdb_target=mipsm3 ;; mips*-*-sysv4*) gdb_target=mipsv4 ;; mips*-*-sysv*) gdb_target=bigmips ;; mips*-*-riscos*) gdb_target=bigmips ;; diff --git a/gdb/cris-tdep.c b/gdb/cris-tdep.c index 4f9ee9b84eb..2258a17b7cc 100644 --- a/gdb/cris-tdep.c +++ b/gdb/cris-tdep.c @@ -1178,7 +1178,7 @@ cris_frame_init_saved_regs (struct frame_info *fi) } else { - ip = get_pc_function_start (get_frame_pc (fi)); + ip = get_frame_func (fi); sal = find_pc_line (ip, 0); /* If there is no symbol information then sal.end == 0, and we end up diff --git a/gdb/d10v-tdep.c b/gdb/d10v-tdep.c index a6bc742e783..001aaf07104 100644 --- a/gdb/d10v-tdep.c +++ b/gdb/d10v-tdep.c @@ -488,17 +488,6 @@ d10v_extract_struct_value_address (struct regcache *regcache) return (addr | DMEM_START); } -/* Immediately after a function call, return the saved pc. We can't - use frame->return_pc beause that is determined by reading R13 off - the stack and that may not be written yet. */ - -static CORE_ADDR -d10v_saved_pc_after_call (struct frame_info *frame) -{ - return ((read_register (LR_REGNUM) << 2) - | IMEM_START); -} - static int check_prologue (unsigned short op) { @@ -1553,6 +1542,7 @@ d10v_frame_prev_register (struct frame_info *next_frame, } static const struct frame_unwind d10v_frame_unwind = { + NORMAL_FRAME, d10v_frame_this_id, d10v_frame_prev_register }; @@ -1587,7 +1577,6 @@ static struct frame_id d10v_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) { ULONGEST base; - struct frame_id id; frame_unwind_unsigned_register (next_frame, SP_REGNUM, &base); return frame_id_build (d10v_make_daddr (base), frame_pc_unwind (next_frame)); } @@ -1700,7 +1689,6 @@ d10v_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_frame_args_skip (gdbarch, 0); set_gdbarch_frameless_function_invocation (gdbarch, frameless_look_for_prologue); - set_gdbarch_saved_pc_after_call (gdbarch, d10v_saved_pc_after_call); set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown); set_gdbarch_stack_align (gdbarch, d10v_stack_align); diff --git a/gdb/defs.h b/gdb/defs.h index 636b515da52..35d23df9caa 100644 --- a/gdb/defs.h +++ b/gdb/defs.h @@ -479,7 +479,7 @@ extern void fputstr_unfiltered (const char *str, int quotr, struct ui_file * str extern void fputstrn_unfiltered (const char *str, int n, int quotr, struct ui_file * stream); /* Display the host ADDR on STREAM formatted as ``0x%x''. */ -extern void gdb_print_host_address (void *addr, struct ui_file *stream); +extern void gdb_print_host_address (const void *addr, struct ui_file *stream); /* Convert a CORE_ADDR into a HEX string. paddr() is like %08lx. paddr_nz() is like %lx. paddr_u() is like %lu. paddr_width() is diff --git a/gdb/disasm.c b/gdb/disasm.c index e9aabc88ac7..511855b5901 100644 --- a/gdb/disasm.c +++ b/gdb/disasm.c @@ -93,14 +93,15 @@ dump_insns (struct ui_out *uiout, disassemble_info * di, /* parts of the symbolic representation of the address */ int unmapped; - char *filename = NULL; - char *name = NULL; int offset; int line; struct cleanup *ui_out_chain; for (pc = low; pc < high;) { + char *filename = NULL; + char *name = NULL; + QUIT; if (how_many >= 0) { @@ -358,7 +359,8 @@ gdb_disassembly (struct ui_out *uiout, if (strcmp (target_shortname, "child") == 0 || strcmp (target_shortname, "procfs") == 0 || strcmp (target_shortname, "vxprocess") == 0 - || strstr (target_shortname, "-threads") != NULL) + || strcmp (target_shortname, "core") == 0 + || strstr (target_shortname, "-thread") != NULL) gdb_disassemble_from_exec = 0; /* It's a child process, read inferior mem */ else gdb_disassemble_from_exec = 1; /* It's remote, read the exec file */ diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 7c350336a6b..ff3023614cb 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,13 @@ +2003-04-08 Andrew Cagney <cagney@redhat.com> + + * gdbint.texinfo (Target Architecture Definition): Delete + references to EXTRA_FRAME_INFO. + +2003-04-08 Andrew Cagney <cagney@redhat.com> + + * gdbint.texinfo (Target Architecture Definition): Delete + PRINT_TYPELESS_INTEGER. + 2003-04-02 J. Brobecker <brobecker@gnat.com> * observer.texi (GDB Observers): Adjust the documentation for the diff --git a/gdb/doc/gdbint.texinfo b/gdb/doc/gdbint.texinfo index 9df6edffffc..4ca81f6777d 100644 --- a/gdb/doc/gdbint.texinfo +++ b/gdb/doc/gdbint.texinfo @@ -3273,7 +3273,7 @@ current stack frame storing each in @code{frame->saved_regs}. Space for @code{DEPRECATED_FRAME_INIT_SAVED_REGS} using @code{frame_saved_regs_zalloc}. -@code{FRAME_FIND_SAVED_REGS} and @code{EXTRA_FRAME_INFO} are deprecated. +@code{FRAME_FIND_SAVED_REGS} is deprecated. @item FRAME_NUM_ARGS (@var{fi}) @findex FRAME_NUM_ARGS @@ -3674,11 +3674,6 @@ The number of the ``next program counter'' register, if defined. If non-zero, round arguments to a boundary of this many bits before pushing them on the stack. -@item PRINT_TYPELESS_INTEGER -@findex PRINT_TYPELESS_INTEGER -This is an obscure substitute for @code{print_longest} that seems to -have been defined for the Convex target. - @item PROCESS_LINENUMBER_HOOK @findex PROCESS_LINENUMBER_HOOK A hook defined for XCOFF reading. @@ -4143,8 +4138,6 @@ Add the macro @code{GDB_MULTI_ARCH}, defined as 0 (zero), to the file@* Some mechanisms do not work with multi-arch. They include: @table @code -@item EXTRA_FRAME_INFO -Delete. @item FRAME_FIND_SAVED_REGS Replaced with @code{DEPRECATED_FRAME_INIT_SAVED_REGS} @end table diff --git a/gdb/doublest.c b/gdb/doublest.c index 3f68273877c..101240b5b6d 100644 --- a/gdb/doublest.c +++ b/gdb/doublest.c @@ -1,7 +1,8 @@ /* Floating point routines for GDB, the GNU debugger. - Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, - 1997, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. + + Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, + 1996, 1997, 1998, 1999, 2000, 2001, 2003 Free Software Foundation, + Inc. This file is part of GDB. @@ -663,8 +664,8 @@ floatformat_from_type (const struct type *type) /* Extract a floating-point number of length LEN from a target-order byte-stream at ADDR. Returns the value as type DOUBLEST. */ -DOUBLEST -extract_floating (const void *addr, int len) +static DOUBLEST +extract_floating_by_length (const void *addr, int len) { const struct floatformat *fmt = floatformat_from_length (len); DOUBLEST val; @@ -679,11 +680,17 @@ extract_floating (const void *addr, int len) return val; } +DOUBLEST +deprecated_extract_floating (const void *addr, int len) +{ + return extract_floating_by_length (addr, len); +} + /* Store VAL as a floating-point number of length LEN to a target-order byte-stream at ADDR. */ -void -store_floating (void *addr, int len, DOUBLEST val) +static void +store_floating_by_length (void *addr, int len, DOUBLEST val) { const struct floatformat *fmt = floatformat_from_length (len); @@ -697,6 +704,12 @@ store_floating (void *addr, int len, DOUBLEST val) floatformat_from_doublest (fmt, &val, addr); } +void +deprecated_store_floating (void *addr, int len, DOUBLEST val) +{ + store_floating_by_length (addr, len, val); +} + /* Extract a floating-point number of type TYPE from a target-order byte-stream at ADDR. Returns the value as type DOUBLEST. */ @@ -708,7 +721,9 @@ extract_typed_floating (const void *addr, const struct type *type) gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT); if (TYPE_FLOATFORMAT (type) == NULL) - return extract_floating (addr, TYPE_LENGTH (type)); + /* Not all code remembers to set the FLOATFORMAT (language + specific code? stabs?) so handle that here as a special case. */ + return extract_floating_by_length (addr, TYPE_LENGTH (type)); floatformat_to_doublest (TYPE_FLOATFORMAT (type), addr, &retval); return retval; @@ -743,7 +758,9 @@ store_typed_floating (void *addr, const struct type *type, DOUBLEST val) memset (addr, 0, TYPE_LENGTH (type)); if (TYPE_FLOATFORMAT (type) == NULL) - store_floating (addr, TYPE_LENGTH (type), val); + /* Not all code remembers to set the FLOATFORMAT (language + specific code? stabs?) so handle that here as a special case. */ + store_floating_by_length (addr, TYPE_LENGTH (type), val); else floatformat_from_doublest (TYPE_FLOATFORMAT (type), &val, addr); } diff --git a/gdb/doublest.h b/gdb/doublest.h index 920d7026db4..d98d045c987 100644 --- a/gdb/doublest.h +++ b/gdb/doublest.h @@ -1,7 +1,8 @@ /* Floating point definitions for GDB. - Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, - 1997, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. + + Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, + 1996, 1997, 1998, 1999, 2000, 2001, 2003 Free Software Foundation, + Inc. This file is part of GDB. @@ -59,12 +60,16 @@ extern int floatformat_is_negative (const struct floatformat *, char *); extern int floatformat_is_nan (const struct floatformat *, char *); extern char *floatformat_mantissa (const struct floatformat *, char *); -/* These two functions are deprecated in favour of - extract_typed_floating and store_typed_floating. See comments in - 'doublest.c' for details. */ +/* These functions have been replaced by extract_typed_floating and + store_typed_floating. + + Most calls are passing in TYPE_LENGTH (TYPE) so can be changed to + just pass the TYPE. The remainder pass in the length of a + register, those calls should instead pass in the floating point + type that corresponds to that length. */ -extern DOUBLEST extract_floating (const void *addr, int len); -extern void store_floating (void *addr, int len, DOUBLEST val); +extern DOUBLEST deprecated_extract_floating (const void *addr, int len); +extern void deprecated_store_floating (void *addr, int len, DOUBLEST val); /* Given TYPE, return its floatformat. TYPE_FLOATFORMAT() may return NULL. type_floatformat() detects that and returns a floatformat diff --git a/gdb/dummy-frame.c b/gdb/dummy-frame.c index eee36c69b2c..a320b7d3b9f 100644 --- a/gdb/dummy-frame.c +++ b/gdb/dummy-frame.c @@ -383,9 +383,8 @@ dummy_frame_this_id (struct frame_info *next_frame, get_prev_frame code has already created THIS frame and linked it in to the frame chain (a pretty bold assumption), extract the ID from THIS base / pc. */ - (*this_id) - = frame_id_build (get_frame_base (get_prev_frame (next_frame)), - get_frame_pc (get_prev_frame (next_frame))); + (*this_id) = frame_id_build (get_frame_base (get_prev_frame (next_frame)), + get_frame_pc (get_prev_frame (next_frame))); } else { @@ -398,12 +397,13 @@ dummy_frame_this_id (struct frame_info *next_frame, (*this_id) = null_frame_id; return; } - (*this_prologue_cache) = find_dummy_frame ((*this_id).func_addr, + (*this_prologue_cache) = find_dummy_frame ((*this_id).code_addr, (*this_id).stack_addr); } static struct frame_unwind dummy_frame_unwind = { + DUMMY_FRAME, dummy_frame_this_id, dummy_frame_prev_register }; diff --git a/gdb/fork-child.c b/gdb/fork-child.c index 0b14a946186..1dc28e822d4 100644 --- a/gdb/fork-child.c +++ b/gdb/fork-child.c @@ -409,7 +409,8 @@ startup_inferior (int ntraps) #else while (1) { - stop_soon_quietly = 1; /* Make wait_for_inferior be quiet */ + /* Make wait_for_inferior be quiet */ + stop_soon = STOP_QUIETLY; wait_for_inferior (); if (stop_signal != TARGET_SIGNAL_TRAP) { @@ -444,5 +445,5 @@ startup_inferior (int ntraps) } } #endif /* STARTUP_INFERIOR */ - stop_soon_quietly = 0; + stop_soon = NO_STOP_QUIETLY; } diff --git a/gdb/frame-unwind.h b/gdb/frame-unwind.h index 099f9dee420..ad1efdf353b 100644 --- a/gdb/frame-unwind.h +++ b/gdb/frame-unwind.h @@ -28,6 +28,8 @@ struct frame_unwind; struct gdbarch; struct regcache; +#include "frame.h" /* For enum frame_type. */ + /* Return the frame unwind methods for the function that contains PC, or NULL if this this unwinder can't handle this frame. */ @@ -128,7 +130,9 @@ typedef void (frame_prev_register_ftype) (struct frame_info *next_frame, struct frame_unwind { - /* Should the frame's type go here? */ + /* The frame's type. Should this instead be a collection of + predicates that test the frame for various attributes? */ + enum frame_type type; /* Should an attribute indicating the frame's address-in-block go here? */ frame_this_id_ftype *this_id; diff --git a/gdb/frame.c b/gdb/frame.c index 8e42f589000..18c62f4618f 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -48,21 +48,75 @@ static int frame_debug; static int backtrace_below_main; -/* Utility to print a frame ID. */ static void fprint_frame_id (struct ui_file *file, struct frame_id id) { - fprintf_unfiltered (file, "stack=0x%s func=0x%s", - paddr (id.stack_addr), - paddr (id.func_addr)); + fprintf_unfiltered (file, "{stack=0x%s,code=0x%s}", + paddr_nz (id.stack_addr), + paddr_nz (id.code_addr)); +} + +static void +fprint_frame_type (struct ui_file *file, enum frame_type type) +{ + switch (type) + { + case UNKNOWN_FRAME: + fprintf_unfiltered (file, "UNKNOWN_FRAME"); + return; + case NORMAL_FRAME: + fprintf_unfiltered (file, "NORMAL_FRAME"); + return; + case DUMMY_FRAME: + fprintf_unfiltered (file, "DUMMY_FRAME"); + return; + case SIGTRAMP_FRAME: + fprintf_unfiltered (file, "SIGTRAMP_FRAME"); + return; + default: + fprintf_unfiltered (file, "<unknown type>"); + return; + }; } static void fprint_frame (struct ui_file *file, struct frame_info *fi) { - fprintf_unfiltered (gdb_stdlog, "frame %d @0x%s: ID ", - fi->level, paddr (get_frame_pc (fi))); - fprint_frame_id (gdb_stdlog, fi->id); + if (fi == NULL) + { + fprintf_unfiltered (file, "<NULL frame>"); + return; + } + fprintf_unfiltered (file, "{"); + fprintf_unfiltered (file, "level=%d", fi->level); + fprintf_unfiltered (file, ","); + fprintf_unfiltered (file, "type="); + fprint_frame_type (file, fi->type); + fprintf_unfiltered (file, ","); + fprintf_unfiltered (file, "unwind="); + if (fi->unwind != NULL) + gdb_print_host_address (fi->unwind, file); + else + fprintf_unfiltered (file, "<unknown>"); + fprintf_unfiltered (file, ","); + fprintf_unfiltered (file, "pc="); + if (fi->next != NULL && fi->next->prev_pc.p) + fprintf_unfiltered (file, "0x%s", paddr_nz (fi->next->prev_pc.value)); + else + fprintf_unfiltered (file, "<unknown>"); + fprintf_unfiltered (file, ","); + fprintf_unfiltered (file, "id="); + if (fi->this_id.p) + fprint_frame_id (file, fi->this_id.value); + else + fprintf_unfiltered (file, "<unknown>"); + fprintf_unfiltered (file, ","); + fprintf_unfiltered (file, "func="); + if (fi->next != NULL && fi->next->prev_func.p) + fprintf_unfiltered (file, "0x%s", paddr_nz (fi->next->prev_func.addr)); + else + fprintf_unfiltered (file, "<unknown>"); + fprintf_unfiltered (file, "}"); } /* Return a frame uniq ID that can be used to, later, re-find the @@ -75,29 +129,33 @@ get_frame_id (struct frame_info *fi) { return null_frame_id; } - if (!fi->id_p) + if (!fi->this_id.p) { gdb_assert (!legacy_frame_p (current_gdbarch)); + if (frame_debug) + fprintf_unfiltered (gdb_stdlog, "{ get_frame_id (fi=%d) ", + fi->level); /* Find THIS frame's ID. */ - fi->unwind->this_id (fi->next, &fi->prologue_cache, &fi->id); - fi->id_p = 1; + fi->unwind->this_id (fi->next, &fi->prologue_cache, &fi->this_id.value); + fi->this_id.p = 1; if (frame_debug) { - fprint_frame (gdb_stdlog, fi); - fprintf_unfiltered (gdb_stdlog, "\n"); + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame_id (gdb_stdlog, fi->this_id.value); + fprintf_unfiltered (gdb_stdlog, " }\n"); } } - return fi->id; + return fi->this_id.value; } const struct frame_id null_frame_id; /* All zeros. */ struct frame_id -frame_id_build (CORE_ADDR stack_addr, CORE_ADDR func_addr) +frame_id_build (CORE_ADDR stack_addr, CORE_ADDR code_addr) { struct frame_id id; id.stack_addr = stack_addr; - id.func_addr = func_addr; + id.code_addr = code_addr; return id; } @@ -105,17 +163,13 @@ int frame_id_p (struct frame_id l) { int p; - /* The .func can be NULL but the .base cannot. */ + /* The .code can be NULL but the .stack cannot. */ p = (l.stack_addr != 0); if (frame_debug) { - fprintf_unfiltered (gdb_stdlog, "ID "); + fprintf_unfiltered (gdb_stdlog, "{ frame_id_p (l="); fprint_frame_id (gdb_stdlog, l); - if (p) - fprintf_unfiltered (gdb_stdlog, " .OK"); - else - fprintf_unfiltered (gdb_stdlog, " !OK"); - fprintf_unfiltered (gdb_stdlog, "\n"); + fprintf_unfiltered (gdb_stdlog, ") -> %d }\n", p); } return p; } @@ -124,33 +178,29 @@ int frame_id_eq (struct frame_id l, struct frame_id r) { int eq; - /* Compare stacks. The stack addresses must always match and can - never be zero. */ if (l.stack_addr == 0 || r.stack_addr == 0) + /* Like a NaN, if either ID is invalid, the result is false. */ eq = 0; else if (l.stack_addr != r.stack_addr) + /* If .stack addresses are different, the frames are different. */ eq = 0; - /* Compare functions. A zero function address acts like a wild - card, otherwize a perfect match is expected. */ - else if (l.func_addr == 0 || r.func_addr == 0) + else if (l.code_addr == 0 || r.code_addr == 0) + /* A zero code addr is a wild card, always succeed. */ eq = 1; - else if (l.func_addr == r.func_addr) + else if (l.code_addr == r.code_addr) + /* The .stack and .code are identical, the ID's are identical. */ eq = 1; else /* No luck. */ eq = 0; if (frame_debug) { - fprintf_unfiltered (gdb_stdlog, "ID "); + fprintf_unfiltered (gdb_stdlog, "{ frame_id_eq (l="); fprint_frame_id (gdb_stdlog, l); - if (eq) - fprintf_unfiltered (gdb_stdlog, " .EQ "); - else - fprintf_unfiltered (gdb_stdlog, " !EQ "); - fprintf_unfiltered (gdb_stdlog, "ID "); - fprint_frame_id (gdb_stdlog, r) ; - fprintf_unfiltered (gdb_stdlog, "\n"); - } + fprintf_unfiltered (gdb_stdlog, ",r="); + fprint_frame_id (gdb_stdlog, r); + fprintf_unfiltered (gdb_stdlog, ") -> %d }\n", eq); + } return eq; } @@ -158,20 +208,22 @@ int frame_id_inner (struct frame_id l, struct frame_id r) { int inner; - /* Only return non-zero when strictly inner than. Note that, per - comment in "frame.h", there is some fuzz here. Frameless - functions are not strictly inner than (same .base but different - .func). */ - inner = gdbarch_inner_than (current_gdbarch, l.stack_addr, r.stack_addr); + if (l.stack_addr == 0 || r.stack_addr == 0) + /* Like NaN, any operation involving an invalid ID always fails. */ + inner = 0; + else + /* Only return non-zero when strictly inner than. Note that, per + comment in "frame.h", there is some fuzz here. Frameless + functions are not strictly inner than (same .stack but + different .code). */ + inner = INNER_THAN (l.stack_addr, r.stack_addr); if (frame_debug) { + fprintf_unfiltered (gdb_stdlog, "{ frame_id_inner (l="); fprint_frame_id (gdb_stdlog, l); - if (inner) - fprintf_unfiltered (gdb_stdlog, " .INNER "); - else - fprintf_unfiltered (gdb_stdlog, " !INNER "); + fprintf_unfiltered (gdb_stdlog, ",r="); fprint_frame_id (gdb_stdlog, r); - fprintf_unfiltered (gdb_stdlog, "\n"); + fprintf_unfiltered (gdb_stdlog, ") -> %d }\n", inner); } return inner; } @@ -208,7 +260,7 @@ frame_find_by_id (struct frame_id id) CORE_ADDR frame_pc_unwind (struct frame_info *this_frame) { - if (!this_frame->pc_unwind_cache_p) + if (!this_frame->prev_pc.p) { CORE_ADDR pc; if (gdbarch_unwind_pc_p (current_gdbarch)) @@ -250,30 +302,38 @@ frame_pc_unwind (struct frame_info *this_frame) } else internal_error (__FILE__, __LINE__, "No gdbarch_unwind_pc method"); - this_frame->pc_unwind_cache = pc; - this_frame->pc_unwind_cache_p = 1; + this_frame->prev_pc.value = pc; + this_frame->prev_pc.p = 1; + if (frame_debug) + fprintf_unfiltered (gdb_stdlog, + "{ frame_pc_unwind (this_frame=%d) -> 0x%s }\n", + this_frame->level, + paddr_nz (this_frame->prev_pc.value)); } - return this_frame->pc_unwind_cache; + return this_frame->prev_pc.value; } CORE_ADDR -frame_func_unwind (struct frame_info *this_frame) +frame_func_unwind (struct frame_info *fi) { - if (!this_frame->func.p) + if (!fi->prev_func.p) { - CORE_ADDR pc = frame_pc_unwind (this_frame); - this_frame->func.cache = get_pc_function_start (pc); + fi->prev_func.p = 1; + fi->prev_func.addr = get_pc_function_start (frame_pc_unwind (fi)); + if (frame_debug) + fprintf_unfiltered (gdb_stdlog, + "{ frame_func_unwind (fi=%d) -> 0x%s }\n", + fi->level, paddr_nz (fi->prev_func.addr)); } - return this_frame->func.cache; + return fi->prev_func.addr; } CORE_ADDR -get_frame_func (struct frame_info *this_frame) +get_frame_func (struct frame_info *fi) { - return frame_func_unwind (this_frame->next); + return frame_func_unwind (fi->next); } - static int do_frame_unwind_register (void *src, int regnum, void *buf) { @@ -329,6 +389,13 @@ frame_register_unwind (struct frame_info *frame, int regnum, { struct frame_unwind_cache *cache; + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, + "{ frame_register_unwind (frame=%d,regnum=\"%s\",...) ", + frame->level, frame_map_regnum_to_name (regnum)); + } + /* Require all but BUFFERP to be valid. A NULL BUFFERP indicates that the value proper does not need to be fetched. */ gdb_assert (optimizedp != NULL); @@ -349,6 +416,26 @@ frame_register_unwind (struct frame_info *frame, int regnum, frame->unwind->prev_register (frame->next, &frame->prologue_cache, regnum, optimizedp, lvalp, addrp, realnump, bufferp); + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "->"); + fprintf_unfiltered (gdb_stdlog, " *optimizedp=%d", (*optimizedp)); + fprintf_unfiltered (gdb_stdlog, " *lvalp=%d", (int) (*lvalp)); + fprintf_unfiltered (gdb_stdlog, " *addrp=0x%s", paddr_nz ((*addrp))); + fprintf_unfiltered (gdb_stdlog, " *bufferp="); + if (bufferp == NULL) + fprintf_unfiltered (gdb_stdlog, "<NULL>"); + else + { + int i; + const char *buf = bufferp; + fprintf_unfiltered (gdb_stdlog, "["); + for (i = 0; i < register_size (current_gdbarch, regnum); i++) + fprintf_unfiltered (gdb_stdlog, "%02x", buf[i]); + fprintf_unfiltered (gdb_stdlog, "]"); + } + fprintf_unfiltered (gdb_stdlog, " }\n"); + } } void @@ -585,15 +672,19 @@ create_sentinel_frame (struct regcache *regcache) frame->prologue_cache = sentinel_frame_cache (regcache); /* For the moment there is only one sentinel frame implementation. */ frame->unwind = sentinel_frame_unwind; - /* Give it a really large frame ID. */ - frame->id_p = 1; - if (INNER_THAN (1, 2)) - frame->id = frame_id_build (0, 0); - else - frame->id = frame_id_build (-1, 0); /* Link this frame back to itself. The frame is self referential (the unwound PC is the same as the pc), so make it so. */ frame->next = frame; + /* Make the sentinel frame's ID valid, but invalid. That way all + comparisons with it should fail. */ + frame->this_id.p = 1; + frame->this_id.value = null_frame_id; + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "{ create_sentinel_frame (...) -> "); + fprint_frame (gdb_stdlog, frame); + fprintf_unfiltered (gdb_stdlog, " }\n"); + } return frame; } @@ -667,10 +758,6 @@ get_current_frame (void) if (catch_exceptions (uiout, unwind_to_current_frame, sentinel_frame, NULL, RETURN_MASK_ERROR) != 0) { - if (frame_debug) - { - fprintf_unfiltered (gdb_stdlog, "Oops!\n"); - } /* Oops! Fake a current frame? Is this useful? It has a PC of zero, for instance. */ current_frame = sentinel_frame; @@ -842,7 +929,7 @@ legacy_saved_regs_this_id (struct frame_info *next_frame, unwinding a sentinel frame, the PC of which is pointing at a stack dummy. Fake up the dummy frame's ID using the same sequence as is found a traditional unwinder. */ - (*id) = frame_id_build (read_fp (), 0 /*read_pc ()*/); + (*id) = frame_id_build (read_fp (), 0); return; } @@ -886,7 +973,7 @@ legacy_saved_regs_this_id (struct frame_info *next_frame, gdb_assert (DEPRECATED_FRAME_CHAIN_P ()); base = DEPRECATED_FRAME_CHAIN (next_frame); - if (!frame_chain_valid (base, next_frame)) + if (!legacy_frame_chain_valid (base, next_frame)) return; } if (base == 0) @@ -899,6 +986,8 @@ legacy_saved_regs_this_id (struct frame_info *next_frame, } const struct frame_unwind legacy_saved_regs_unwinder = { + /* Not really. It gets overridden by legacy_get_prev_frame. */ + UNKNOWN_FRAME, legacy_saved_regs_this_id, legacy_saved_regs_prev_register }; @@ -1037,27 +1126,42 @@ create_new_frame (CORE_ADDR addr, CORE_ADDR pc) { struct frame_info *fi; + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, + "{ create_new_frame (addr=0x%s, pc=0x%s) ", + paddr_nz (addr), paddr_nz (pc)); + } + fi = frame_obstack_zalloc (sizeof (struct frame_info)); /* FIXME: cagney/2003-04-02: Should this instead try to map that pc onto a function. */ - if (frame_debug) - fprintf_unfiltered (gdb_stdlog, "create new frame\n"); - - fi->id = frame_id_build (addr, pc); - fi->id_p = 1; + fi->this_id.p = 1; + fi->this_id.value = frame_id_build (addr, pc); fi->next = create_sentinel_frame (current_regcache); - fi->next->pc_unwind_cache = pc; - fi->next->pc_unwind_cache_p = 1; - fi->type = frame_type_from_pc (pc); + /* Select/initialize both the unwind function and the frame's type + based on the PC. */ + fi->unwind = frame_unwind_find_by_pc (current_gdbarch, pc); + if (fi->unwind->type != UNKNOWN_FRAME) + fi->type = fi->unwind->type; + else + fi->type = frame_type_from_pc (pc); + + deprecated_update_frame_base_hack (fi, addr); + deprecated_update_frame_pc_hack (fi, pc); if (DEPRECATED_INIT_EXTRA_FRAME_INFO_P ()) DEPRECATED_INIT_EXTRA_FRAME_INFO (0, fi); - /* Select/initialize an unwind function. */ - fi->unwind = frame_unwind_find_by_pc (current_gdbarch, get_frame_pc (fi)); + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, fi); + fprintf_unfiltered (gdb_stdlog, " }\n"); + } return fi; } @@ -1087,6 +1191,8 @@ flush_cached_frames (void) current_frame = NULL; /* Invalidate cache */ select_frame (NULL); annotate_frames_invalid (); + if (frame_debug) + fprintf_unfiltered (gdb_stdlog, "{ flush_cached_frames () }\n"); } /* Flush the frame cache, and start a new one if necessary. */ @@ -1113,10 +1219,10 @@ legacy_get_prev_frame (struct frame_info *this_frame) struct frame_info *prev; int fromleaf; - /* Allocate the new frame but do not wire it in to the frame chain. - Some (bad) code in INIT_FRAME_EXTRA_INFO tries to look along - frame->next to pull some fancy tricks (of course such code is, by - definition, recursive). Try to prevent it. + /* Don't frame_debug print legacy_get_prev_frame() here, just + confuses the output. */ + + /* Allocate the new frame. There is no reason to worry about memory leaks, should the remainder of the function fail. The allocated memory will be @@ -1126,11 +1232,15 @@ legacy_get_prev_frame (struct frame_info *this_frame) prev = FRAME_OBSTACK_ZALLOC (struct frame_info); prev->level = this_frame->level + 1; - /* Link prev to this. This ensures that functions such as - get_frame_pc(), called by all the deprecated init functions - below, and implemented using frame_pc_unwind (prev->next) work. - Don't link this to prev as this stops functions walking up the - frame chain to this partially initialized method. */ + /* Do not completly wire it in to the frame chain. Some (bad) code + in INIT_FRAME_EXTRA_INFO tries to look along frame->prev to pull + some fancy tricks (of course such code is, by definition, + recursive). + + On the other hand, methods, such as get_frame_pc() and + get_frame_base() rely on being able to walk along the frame + chain. Make certain that at least they work by providing that + link. Of course things manipulating prev can't go back. */ prev->next = this_frame; /* NOTE: cagney/2002-11-18: Should have been correctly setting the @@ -1143,10 +1253,10 @@ legacy_get_prev_frame (struct frame_info *this_frame) Unfortunatly those same work-arounds rely on the type defaulting to NORMAL_FRAME. Ulgh! The new frame code does not have this problem. */ - prev->type = NORMAL_FRAME; + prev->type = UNKNOWN_FRAME; /* A legacy frame's ID is always computed here. Mark it as valid. */ - prev->id_p = 1; + prev->this_id.p = 1; /* Handle sentinel frame unwind as a special case. */ if (this_frame->level < 0) @@ -1169,20 +1279,29 @@ legacy_get_prev_frame (struct frame_info *this_frame) because (well ignoring the PPC) a dummy frame can be located using THIS_FRAME's frame ID. */ - if (frame_pc_unwind (this_frame) == 0) + deprecated_update_frame_pc_hack (prev, frame_pc_unwind (this_frame)); + if (get_frame_pc (prev) == 0) { /* The allocated PREV_FRAME will be reclaimed when the frame obstack is next purged. */ if (frame_debug) - fprintf_unfiltered (gdb_stdlog, - "Outermost frame - unwound PC zero\n"); + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, NULL); + fprintf_unfiltered (gdb_stdlog, + " // unwound legacy PC zero }\n"); + } return NULL; } - prev->type = frame_type_from_pc (frame_pc_unwind (this_frame)); - /* Set the unwind functions based on that identified PC. */ + /* Set the unwind functions based on that identified PC. Ditto + for the "type" but strongly prefer the unwinder's frame type. */ prev->unwind = frame_unwind_find_by_pc (current_gdbarch, - frame_pc_unwind (this_frame)); + get_frame_pc (prev)); + if (prev->unwind->type == UNKNOWN_FRAME) + prev->type = frame_type_from_pc (get_frame_pc (prev)); + else + prev->type = prev->unwind->type; /* Find the prev's frame's ID. */ if (prev->type == DUMMY_FRAME @@ -1204,7 +1323,8 @@ legacy_get_prev_frame (struct frame_info *this_frame) dummy ID from the next frame. Note that this method uses frame_register_unwind to obtain the register values needed to determine the dummy frame's ID. */ - prev->id = gdbarch_unwind_dummy_id (current_gdbarch, this_frame); + prev->this_id.value = gdbarch_unwind_dummy_id (current_gdbarch, + this_frame); } else { @@ -1213,15 +1333,19 @@ legacy_get_prev_frame (struct frame_info *this_frame) using the same sequence as is found a traditional unwinder. Once all architectures supply the unwind_dummy_id method, this code can go away. */ - prev->id = frame_id_build (read_fp (), read_pc ()); + prev->this_id.value = frame_id_build (read_fp (), read_pc ()); } /* Check that the unwound ID is valid. */ - if (!frame_id_p (prev->id)) + if (!frame_id_p (prev->this_id.value)) { if (frame_debug) - fprintf_unfiltered (gdb_stdlog, - "Outermost legacy sentinel frame - unwound frame ID invalid\n"); + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, NULL); + fprintf_unfiltered (gdb_stdlog, + " // unwound legacy ID invalid }\n"); + } return NULL; } @@ -1251,14 +1375,15 @@ legacy_get_prev_frame (struct frame_info *this_frame) } if (prev->type == NORMAL_FRAME) - prev->id.func_addr = get_pc_function_start (prev->id.func_addr); + prev->this_id.value.code_addr + = get_pc_function_start (prev->this_id.value.code_addr); if (frame_debug) { + fprintf_unfiltered (gdb_stdlog, "-> "); fprint_frame (gdb_stdlog, prev); - fprintf_unfiltered (gdb_stdlog, "\n"); + fprintf_unfiltered (gdb_stdlog, " } // legacy innermost frame\n"); } - return prev; } @@ -1312,15 +1437,32 @@ legacy_get_prev_frame (struct frame_info *this_frame) gdb_assert (DEPRECATED_FRAME_CHAIN_P ()); address = DEPRECATED_FRAME_CHAIN (this_frame); - if (!frame_chain_valid (address, this_frame)) - return 0; + if (!legacy_frame_chain_valid (address, this_frame)) + { + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, NULL); + fprintf_unfiltered (gdb_stdlog, + " // legacy frame chain invalid }\n"); + } + return NULL; + } } if (address == 0) - return 0; + { + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, NULL); + fprintf_unfiltered (gdb_stdlog, + " // legacy frame chain NULL }\n"); + } + return NULL; + } /* Link in the already allocated prev frame. */ this_frame->prev = prev; - prev->next = this_frame; deprecated_update_frame_base_hack (prev, address); /* This change should not be needed, FIXME! We should determine @@ -1397,8 +1539,9 @@ legacy_get_prev_frame (struct frame_info *this_frame) that PC value. */ if (DEPRECATED_INIT_FRAME_PC_FIRST_P ()) - deprecated_update_frame_pc_hack - (prev, DEPRECATED_INIT_FRAME_PC_FIRST (fromleaf, prev)); + deprecated_update_frame_pc_hack (prev, + DEPRECATED_INIT_FRAME_PC_FIRST (fromleaf, + prev)); if (DEPRECATED_INIT_EXTRA_FRAME_INFO_P ()) DEPRECATED_INIT_EXTRA_FRAME_INFO (fromleaf, prev); @@ -1407,21 +1550,27 @@ legacy_get_prev_frame (struct frame_info *this_frame) FRAME_SAVED_PC may use that queue to figure out its value (see tm-sparc.h). We want the pc saved in the inferior frame. */ if (DEPRECATED_INIT_FRAME_PC_P ()) - deprecated_update_frame_pc_hack - (prev, DEPRECATED_INIT_FRAME_PC (fromleaf, prev)); + deprecated_update_frame_pc_hack (prev, + DEPRECATED_INIT_FRAME_PC (fromleaf, + prev)); /* If ->frame and ->pc are unchanged, we are in the process of getting ourselves into an infinite backtrace. Some architectures check this in DEPRECATED_FRAME_CHAIN or thereabouts, but it seems like there is no reason this can't be an architecture-independent check. */ - /* NOTE: cagney/2003-04-04: Don't convert this to frame_id_eq. At - this stage the ID's address is not valid, so need to use the pc. */ - if (prev->id.stack_addr == this_frame->id.stack_addr + if (get_frame_base (prev) == get_frame_base (this_frame) && get_frame_pc (prev) == get_frame_pc (this_frame)) { this_frame->prev = NULL; obstack_free (&frame_cache_obstack, prev); + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, NULL); + fprintf_unfiltered (gdb_stdlog, + " // legacy this.id == prev.id }\n"); + } return NULL; } @@ -1432,6 +1581,23 @@ legacy_get_prev_frame (struct frame_info *this_frame) prev->unwind = frame_unwind_find_by_pc (current_gdbarch, get_frame_pc (prev)); + /* If the unwinder provides a frame type, use it. Otherwize + continue on to that heuristic mess. */ + if (prev->unwind->type != UNKNOWN_FRAME) + { + prev->type = prev->unwind->type; + if (prev->type == NORMAL_FRAME) + prev->this_id.value.code_addr + = get_pc_function_start (prev->this_id.value.code_addr); + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, prev); + fprintf_unfiltered (gdb_stdlog, " } // legacy with unwound type\n"); + } + return prev; + } + /* NOTE: cagney/2002-11-18: The code segments, found in create_new_frame and get_prev_frame(), that initializes the frames type is subtly different. The latter only updates ->type @@ -1454,8 +1620,7 @@ legacy_get_prev_frame (struct frame_info *this_frame) Unforunatly, its the INIT code that sets the PC (Hmm, catch 22). */ char *name; - find_pc_partial_function (get_frame_pc (prev), - &name, NULL, NULL); + find_pc_partial_function (get_frame_pc (prev), &name, NULL, NULL); if (PC_IN_SIGTRAMP (get_frame_pc (prev), name)) prev->type = SIGTRAMP_FRAME; /* FIXME: cagney/2002-11-11: Leave prev->type alone. Some @@ -1466,17 +1631,17 @@ legacy_get_prev_frame (struct frame_info *this_frame) go away. */ } + if (prev->type == NORMAL_FRAME) + prev->this_id.value.code_addr + = get_pc_function_start (prev->this_id.value.code_addr); + if (frame_debug) { - fprintf_unfiltered (gdb_stdlog, "frame %d @0x%s: ID ", - prev->level, paddr (get_frame_pc (prev))); - fprint_frame_id (gdb_stdlog, prev->id); - fprintf_unfiltered (gdb_stdlog, "\n"); + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, prev); + fprintf_unfiltered (gdb_stdlog, " } // legacy with confused type\n"); } - if (prev->type == NORMAL_FRAME) - prev->id.func_addr = get_pc_function_start (prev->id.func_addr); - return prev; } @@ -1489,6 +1654,16 @@ get_prev_frame (struct frame_info *this_frame) { struct frame_info *prev_frame; + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "{ get_prev_frame (this_frame="); + if (this_frame != NULL) + fprintf_unfiltered (gdb_stdlog, "%d", this_frame->level); + else + fprintf_unfiltered (gdb_stdlog, "<NULL>"); + fprintf_unfiltered (gdb_stdlog, ") "); + } + /* Return the inner-most frame, when the caller passes in NULL. */ /* NOTE: cagney/2002-11-09: Not sure how this would happen. The caller should have previously obtained a valid frame using @@ -1538,14 +1713,21 @@ get_prev_frame (struct frame_info *this_frame) allow unwinds past main(), that just happens. */ { if (frame_debug) - fprintf_unfiltered (gdb_stdlog, - "Outermost frame - inside main func.\n"); + fprintf_unfiltered (gdb_stdlog, "-> NULL // inside main func }\n"); return NULL; } /* Only try to do the unwind once. */ if (this_frame->prev_p) - return this_frame->prev; + { + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, this_frame->prev); + fprintf_unfiltered (gdb_stdlog, " // cached \n"); + } + return this_frame->prev; + } this_frame->prev_p = 1; #if 0 @@ -1573,8 +1755,11 @@ get_prev_frame (struct frame_info *this_frame) && inside_entry_file (get_frame_pc (this_frame))) { if (frame_debug) - fprintf_unfiltered (gdb_stdlog, - "Outermost frame - inside entry file\n"); + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, NULL); + fprintf_unfiltered (gdb_stdlog, " // inside entry file }\n"); + } return NULL; } #endif @@ -1591,8 +1776,11 @@ get_prev_frame (struct frame_info *this_frame) && inside_entry_func (get_frame_pc (this_frame))) { if (frame_debug) - fprintf_unfiltered (gdb_stdlog, - "Outermost frame - inside entry func\n"); + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, NULL); + fprintf_unfiltered (gdb_stdlog, "// inside entry func }\n"); + } return NULL; } @@ -1601,9 +1789,6 @@ get_prev_frame (struct frame_info *this_frame) if (legacy_frame_p (current_gdbarch)) { prev_frame = legacy_get_prev_frame (this_frame); - if (frame_debug && prev_frame == NULL) - fprintf_unfiltered (gdb_stdlog, - "Outermost frame - legacy_get_prev_frame NULL.\n"); return prev_frame; } @@ -1613,8 +1798,11 @@ get_prev_frame (struct frame_info *this_frame) if (this_frame->level >= 0 && !frame_id_p (get_frame_id (this_frame))) { if (frame_debug) - fprintf_filtered (gdb_stdlog, - "Outermost frame - this ID is NULL\n"); + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, NULL); + fprintf_unfiltered (gdb_stdlog, " // this ID is NULL }\n"); + } return NULL; } @@ -1675,16 +1863,29 @@ get_prev_frame (struct frame_info *this_frame) /* The allocated PREV_FRAME will be reclaimed when the frame obstack is next purged. */ if (frame_debug) - fprintf_unfiltered (gdb_stdlog, - "Outermost frame - unwound PC zero\n"); + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, NULL); + fprintf_unfiltered (gdb_stdlog, " // unwound PC zero }\n"); + } return NULL; } - prev_frame->type = frame_type_from_pc (frame_pc_unwind (this_frame)); /* Set the unwind functions based on that identified PC. */ prev_frame->unwind = frame_unwind_find_by_pc (current_gdbarch, frame_pc_unwind (this_frame)); + /* FIXME: cagney/2003-04-02: Rather than storing the frame's type in + the frame, the unwinder's type should be returned directly. + Unfortunatly, legacy code, called by legacy_get_prev_frame, + explicitly set the frames type using the method + deprecated_set_frame_type(). */ + gdb_assert (prev_frame->unwind->type != UNKNOWN_FRAME); + prev_frame->type = prev_frame->unwind->type; + + /* Can the frame's type and unwinder be computed on demand? That + would make a frame's creation really really lite! */ + /* The prev's frame's ID is computed by demand in get_frame_id(). */ /* The unwound frame ID is validate at the start of this function, @@ -1703,12 +1904,20 @@ get_prev_frame (struct frame_info *this_frame) this_frame->prev = prev_frame; prev_frame->next = this_frame; + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, prev_frame); + fprintf_unfiltered (gdb_stdlog, " }\n"); + } + return prev_frame; } CORE_ADDR get_frame_pc (struct frame_info *frame) { + gdb_assert (frame->next != NULL); return frame_pc_unwind (frame->next); } @@ -1748,7 +1957,7 @@ get_frame_base (struct frame_info *fi) CORE_ADDR get_frame_base_address (struct frame_info *fi) { - if (fi->type != NORMAL_FRAME) + if (get_frame_type (fi) != NORMAL_FRAME) return 0; if (fi->base == NULL) fi->base = frame_base_find_by_pc (current_gdbarch, get_frame_pc (fi)); @@ -1763,7 +1972,7 @@ CORE_ADDR get_frame_locals_address (struct frame_info *fi) { void **cache; - if (fi->type != NORMAL_FRAME) + if (get_frame_type (fi) != NORMAL_FRAME) return 0; /* If there isn't a frame address method, find it. */ if (fi->base == NULL) @@ -1781,7 +1990,7 @@ CORE_ADDR get_frame_args_address (struct frame_info *fi) { void **cache; - if (fi->type != NORMAL_FRAME) + if (get_frame_type (fi) != NORMAL_FRAME) return 0; /* If there isn't a frame address method, find it. */ if (fi->base == NULL) @@ -1815,7 +2024,10 @@ get_frame_type (struct frame_info *frame) if (!DEPRECATED_USE_GENERIC_DUMMY_FRAMES && deprecated_frame_in_dummy (frame)) return DUMMY_FRAME; - return frame->type; + if (frame->type == UNKNOWN_FRAME) + return NORMAL_FRAME; + else + return frame->type; } void @@ -1825,34 +2037,6 @@ deprecated_set_frame_type (struct frame_info *frame, enum frame_type type) frame->type = type; } -#ifdef FRAME_FIND_SAVED_REGS -/* XXX - deprecated. This is a compatibility function for targets - that do not yet implement DEPRECATED_FRAME_INIT_SAVED_REGS. */ -/* Find the addresses in which registers are saved in FRAME. */ - -void -deprecated_get_frame_saved_regs (struct frame_info *frame, - struct frame_saved_regs *saved_regs_addr) -{ - if (frame->saved_regs == NULL) - { - frame->saved_regs = (CORE_ADDR *) - frame_obstack_zalloc (SIZEOF_FRAME_SAVED_REGS); - } - if (saved_regs_addr == NULL) - { - struct frame_saved_regs saved_regs; - FRAME_FIND_SAVED_REGS (frame, saved_regs); - memcpy (frame->saved_regs, &saved_regs, SIZEOF_FRAME_SAVED_REGS); - } - else - { - FRAME_FIND_SAVED_REGS (frame, *saved_regs_addr); - memcpy (frame->saved_regs, saved_regs_addr, SIZEOF_FRAME_SAVED_REGS); - } -} -#endif - struct frame_extra_info * get_frame_extra_info (struct frame_info *fi) { @@ -1869,6 +2053,10 @@ frame_extra_info_zalloc (struct frame_info *fi, long size) void deprecated_update_frame_pc_hack (struct frame_info *frame, CORE_ADDR pc) { + if (frame_debug) + fprintf_unfiltered (gdb_stdlog, + "{ deprecated_update_frame_pc_hack (frame=%d,pc=0x%s) }\n", + frame->level, paddr_nz (pc)); /* NOTE: cagney/2003-03-11: Some architectures (e.g., Arm) are maintaining a locally allocated frame object. Since such frame's are not in the frame chain, it isn't possible to assume that the @@ -1878,16 +2066,20 @@ deprecated_update_frame_pc_hack (struct frame_info *frame, CORE_ADDR pc) /* While we're at it, update this frame's cached PC value, found in the next frame. Oh for the day when "struct frame_info" is opaque and this hack on hack can just go away. */ - frame->next->pc_unwind_cache = pc; - frame->next->pc_unwind_cache_p = 1; + frame->next->prev_pc.value = pc; + frame->next->prev_pc.p = 1; } } void deprecated_update_frame_base_hack (struct frame_info *frame, CORE_ADDR base) { - frame->id_p = 1; - frame->id.stack_addr = base; + if (frame_debug) + fprintf_unfiltered (gdb_stdlog, + "{ deprecated_update_frame_base_hack (frame=%d,base=0x%s) }\n", + frame->level, paddr_nz (base)); + /* See comment in "frame.h". */ + frame->this_id.value.stack_addr = base; } void diff --git a/gdb/frame.h b/gdb/frame.h index 4e96bfe911c..2468fc9b7e2 100644 --- a/gdb/frame.h +++ b/gdb/frame.h @@ -27,6 +27,7 @@ struct symtab_and_line; struct frame_unwind; struct frame_base; struct block; +struct gdbarch; /* A legacy unwinder to prop up architectures using the old style saved regs array. */ @@ -44,17 +45,23 @@ struct frame_info; struct frame_id { /* The frame's stack address. This shall be constant through out - the lifetime of a frame. Since the frame's lifetime includes the - prologue, and the value needs to always fall on or within the - bounds of the frame, this stack value is best pointed at the - inner-most address of the previous frame. */ + the lifetime of a frame. Note that this requirement applies to + not just the function body, but also the prologue and (in theory + at least) the epilogue. Since that value needs to fall either on + the boundary, or within the frame's address range, the frame's + outer-most address (the inner-most address of the previous frame) + is used. Watch out for all the legacy targets that still use the + function pointer register or stack pointer register. They are + wrong. */ /* NOTE: cagney/2002-11-16: The ia64 has two stacks and hence two frame bases. This will need to be expanded to accomodate that. */ CORE_ADDR stack_addr; - /* The frame's function address. This shall be constant through out - the lifetime of the frame. While the PC within the function may - change, the function that contains the PC does not. */ - CORE_ADDR func_addr; + /* The frame's code address. This shall be constant through out the + lifetime of the frame. While the PC (a.k.a. resume address) + changes as the function is executed, this code address cannot. + Typically, it is set to the address of the entry point of the + frame's function (as returned by frame_func_unwind(). */ + CORE_ADDR code_addr; }; /* Methods for constructing and comparing Frame IDs. @@ -68,11 +75,12 @@ struct frame_id /* For convenience. All fields are zero. */ extern const struct frame_id null_frame_id; -/* Construct a frame ID. The first parameter is the frame's stack - address, and the second the frame's function (or zero, to indicate - a wild card). */ +/* Construct a frame ID. The first parameter is the frame's constant + stack address (typically the outer-bound), and the second the + frame's constant code address (typically the entry point) (or zero, + to indicate a wild card). */ extern struct frame_id frame_id_build (CORE_ADDR stack_addr, - CORE_ADDR func_addr); + CORE_ADDR code_addr); /* Returns non-zero when L is a valid frame (a valid frame has a non-zero .base). */ @@ -151,6 +159,12 @@ extern struct frame_info *frame_find_by_id (struct frame_id id); this frame. */ extern CORE_ADDR get_frame_pc (struct frame_info *); +/* Following on from the `resume' address. Return the entry point + address of the function containing that resume address, or zero if + that function isn't known. */ +extern CORE_ADDR frame_func_unwind (struct frame_info *fi); +extern CORE_ADDR get_frame_func (struct frame_info *fi); + /* Closely related to the resume address, various symbol table attributes that are determined by the PC. Note that for a normal frame, the PC refers to the resume address after the return, and @@ -227,6 +241,11 @@ extern int frame_relative_level (struct frame_info *fi); enum frame_type { + /* The frame's type hasn't yet been defined. This is a catch-all + for legacy code that uses really strange technicques, such as + deprecated_set_frame_type, to set the frame's type. New code + should not use this value. */ + UNKNOWN_FRAME, /* A true stack frame, created by the target program during normal execution. */ NORMAL_FRAME, @@ -311,35 +330,10 @@ extern const char *frame_map_regnum_to_name (int regnum); extern CORE_ADDR frame_pc_unwind (struct frame_info *frame); -/* Unwind/return the frame's function, or 0 if the frame's function is - unknown. This is a wrapper to get_pc_function_start of - frame_pc_unwind. */ -extern CORE_ADDR frame_func_unwind (struct frame_info *frame); -extern CORE_ADDR get_frame_func (struct frame_info *frame); - - /* Discard the specified frame. Restoring the registers to the state of the caller. */ extern void frame_pop (struct frame_info *frame); -/* Describe the saved registers of a frame. */ - -#if defined (EXTRA_FRAME_INFO) || defined (FRAME_FIND_SAVED_REGS) -/* XXXX - deprecated */ -struct frame_saved_regs - { - /* For each register R (except the SP), regs[R] is the address at - which it was saved on entry to the frame, or zero if it was not - saved on entry to this frame. This includes special registers - such as pc and fp saved in special ways in the stack frame. - - regs[SP_REGNUM] is different. It holds the actual SP, not the - address at which it was saved. */ - - CORE_ADDR regs[NUM_REGS]; - }; -#endif - /* We keep a cache of stack frames, each of which is a "struct frame_info". The innermost one gets allocated (in wait_for_inferior) each time the inferior stops; current_frame @@ -365,6 +359,10 @@ struct frame_info int level; /* The frame's type. */ + /* FIXME: cagney/2003-04-02: Should instead be returning + ->unwind->type. Unfortunatly, legacy code is still explicitly + setting the type using the method deprecated_set_frame_type. + Eliminate that method and this field can be eliminated. */ enum frame_type type; /* For each register, address of where it was saved on entry to @@ -377,13 +375,6 @@ struct frame_info initialized by DEPRECATED_FRAME_INIT_SAVED_REGS(). */ CORE_ADDR *saved_regs; /*NUM_REGS + NUM_PSEUDO_REGS*/ -#ifdef EXTRA_FRAME_INFO - /* XXXX - deprecated */ - /* Anything extra for this structure that may have been defined - in the machine dependent files. */ - EXTRA_FRAME_INFO -#endif - /* Anything extra for this structure that may have been defined in the machine dependent files. */ /* Allocated by frame_extra_info_zalloc () which is called / @@ -403,20 +394,24 @@ struct frame_info const struct frame_unwind *unwind; /* Cached copy of the previous frame's resume address. */ - int pc_unwind_cache_p; - CORE_ADDR pc_unwind_cache; + struct { + int p; + CORE_ADDR value; + } prev_pc; - /* Cached copy of the previous frame's function. */ + /* Cached copy of the previous frame's function address. */ struct { + CORE_ADDR addr; int p; - CORE_ADDR cache; - } func; + } prev_func; - /* This frame's ID. Note that the frame's ID, base and PC contain - redundant information. */ - int id_p; - struct frame_id id; + /* This frame's ID. */ + struct + { + int p; + struct frame_id value; + } this_id; /* The frame's high-level base methods, and corresponding cache. The high level base methods are selected based on the frame's @@ -463,21 +458,17 @@ enum print_what extern void *frame_obstack_zalloc (unsigned long size); #define FRAME_OBSTACK_ZALLOC(TYPE) ((TYPE *) frame_obstack_zalloc (sizeof (TYPE))) -/* If DEPRECATED_FRAME_CHAIN_VALID returns zero it means that the - given frame is the outermost one and has no caller. */ +/* If legacy_frame_chain_valid() returns zero it means that the given + frame is the outermost one and has no caller. -extern int frame_chain_valid (CORE_ADDR, struct frame_info *); + This method has been superseeded by the per-architecture + frame_unwind_pc() (returns 0 to indicate an invalid return address) + and per-frame this_id() (returns a NULL frame ID to indicate an + invalid frame). */ +extern int legacy_frame_chain_valid (CORE_ADDR, struct frame_info *); extern void generic_save_dummy_frame_tos (CORE_ADDR sp); - -#ifdef FRAME_FIND_SAVED_REGS -/* XXX - deprecated */ -#define DEPRECATED_FRAME_INIT_SAVED_REGS(FI) deprecated_get_frame_saved_regs (FI, NULL) -extern void deprecated_get_frame_saved_regs (struct frame_info *, - struct frame_saved_regs *); -#endif - extern struct block *get_frame_block (struct frame_info *, CORE_ADDR *addr_in_block); diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index d08f14652b9..257f2b91cbe 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -728,9 +728,7 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of unwind_pc, has predicate */ /* Skip verify of frame_args_address, invalid_p == 0 */ /* Skip verify of frame_locals_address, invalid_p == 0 */ - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->saved_pc_after_call == 0)) - fprintf_unfiltered (log, "\n\tsaved_pc_after_call"); + /* Skip verify of saved_pc_after_call, has predicate */ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && (gdbarch->frame_num_args == 0)) fprintf_unfiltered (log, "\n\tframe_num_args"); @@ -2152,6 +2150,15 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) (long) current_gdbarch->return_value_on_stack /*RETURN_VALUE_ON_STACK ()*/); #endif +#ifdef SAVED_PC_AFTER_CALL_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "SAVED_PC_AFTER_CALL_P()", + XSTRING (SAVED_PC_AFTER_CALL_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: SAVED_PC_AFTER_CALL_P() = %d\n", + SAVED_PC_AFTER_CALL_P ()); +#endif #ifdef SAVED_PC_AFTER_CALL fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", @@ -4902,6 +4909,13 @@ set_gdbarch_frame_locals_address (struct gdbarch *gdbarch, gdbarch->frame_locals_address = frame_locals_address; } +int +gdbarch_saved_pc_after_call_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->saved_pc_after_call != 0; +} + CORE_ADDR gdbarch_saved_pc_after_call (struct gdbarch *gdbarch, struct frame_info *frame) { diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index 596f13194d3..c1f02c81e52 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -55,18 +55,6 @@ extern struct gdbarch *current_gdbarch; /* If any of the following are defined, the target wasn't correctly converted. */ -#if GDB_MULTI_ARCH -#if defined (EXTRA_FRAME_INFO) -#error "EXTRA_FRAME_INFO: replaced by struct frame_extra_info" -#endif -#endif - -#if GDB_MULTI_ARCH -#if defined (FRAME_FIND_SAVED_REGS) -#error "FRAME_FIND_SAVED_REGS: replaced by DEPRECATED_FRAME_INIT_SAVED_REGS" -#endif -#endif - #if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PURE) && defined (GDB_TM_FILE) #error "GDB_TM_FILE: Pure multi-arch targets do not have a tm.h file." #endif @@ -1116,14 +1104,12 @@ extern void set_gdbarch_get_longjmp_target (struct gdbarch *gdbarch, gdbarch_get extern int gdbarch_deprecated_use_generic_dummy_frames (struct gdbarch *gdbarch); extern void set_gdbarch_deprecated_use_generic_dummy_frames (struct gdbarch *gdbarch, int deprecated_use_generic_dummy_frames); -#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_USE_GENERIC_DUMMY_FRAMES) +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_USE_GENERIC_DUMMY_FRAMES) #error "Non multi-arch definition of DEPRECATED_USE_GENERIC_DUMMY_FRAMES" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_USE_GENERIC_DUMMY_FRAMES) +#if !defined (DEPRECATED_USE_GENERIC_DUMMY_FRAMES) #define DEPRECATED_USE_GENERIC_DUMMY_FRAMES (gdbarch_deprecated_use_generic_dummy_frames (current_gdbarch)) #endif -#endif /* Default (value) for non- multi-arch platforms. */ #if (!GDB_MULTI_ARCH) && !defined (CALL_DUMMY_LOCATION) @@ -1132,14 +1118,12 @@ extern void set_gdbarch_deprecated_use_generic_dummy_frames (struct gdbarch *gdb extern int gdbarch_call_dummy_location (struct gdbarch *gdbarch); extern void set_gdbarch_call_dummy_location (struct gdbarch *gdbarch, int call_dummy_location); -#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (CALL_DUMMY_LOCATION) +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (CALL_DUMMY_LOCATION) #error "Non multi-arch definition of CALL_DUMMY_LOCATION" #endif -#if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) || !defined (CALL_DUMMY_LOCATION) +#if !defined (CALL_DUMMY_LOCATION) #define CALL_DUMMY_LOCATION (gdbarch_call_dummy_location (current_gdbarch)) #endif -#endif /* Default (function) for non- multi-arch platforms. */ #if (!GDB_MULTI_ARCH) && !defined (CALL_DUMMY_ADDRESS) @@ -1204,10 +1188,10 @@ extern void set_gdbarch_call_dummy_length (struct gdbarch *gdbarch, int call_dum #endif extern int gdbarch_deprecated_pc_in_call_dummy_p (struct gdbarch *gdbarch); -#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_PC_IN_CALL_DUMMY_P) +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_PC_IN_CALL_DUMMY_P) #error "Non multi-arch definition of DEPRECATED_PC_IN_CALL_DUMMY" #endif -#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_PC_IN_CALL_DUMMY_P) +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_PC_IN_CALL_DUMMY_P) #define DEPRECATED_PC_IN_CALL_DUMMY_P() (gdbarch_deprecated_pc_in_call_dummy_p (current_gdbarch)) #endif @@ -1219,11 +1203,11 @@ extern int gdbarch_deprecated_pc_in_call_dummy_p (struct gdbarch *gdbarch); typedef int (gdbarch_deprecated_pc_in_call_dummy_ftype) (CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR frame_address); extern int gdbarch_deprecated_pc_in_call_dummy (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR frame_address); extern void set_gdbarch_deprecated_pc_in_call_dummy (struct gdbarch *gdbarch, gdbarch_deprecated_pc_in_call_dummy_ftype *deprecated_pc_in_call_dummy); -#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_PC_IN_CALL_DUMMY) +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DEPRECATED_PC_IN_CALL_DUMMY) #error "Non multi-arch definition of DEPRECATED_PC_IN_CALL_DUMMY" #endif #if GDB_MULTI_ARCH -#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_PC_IN_CALL_DUMMY) +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DEPRECATED_PC_IN_CALL_DUMMY) #define DEPRECATED_PC_IN_CALL_DUMMY(pc, sp, frame_address) (gdbarch_deprecated_pc_in_call_dummy (current_gdbarch, pc, sp, frame_address)) #endif #endif @@ -2401,6 +2385,31 @@ extern void set_gdbarch_frame_locals_address (struct gdbarch *gdbarch, gdbarch_f #endif #endif +#if defined (SAVED_PC_AFTER_CALL) +/* Legacy for systems yet to multi-arch SAVED_PC_AFTER_CALL */ +#if !defined (SAVED_PC_AFTER_CALL_P) +#define SAVED_PC_AFTER_CALL_P() (1) +#endif +#endif + +/* Default predicate for non- multi-arch targets. */ +#if (!GDB_MULTI_ARCH) && !defined (SAVED_PC_AFTER_CALL_P) +#define SAVED_PC_AFTER_CALL_P() (0) +#endif + +extern int gdbarch_saved_pc_after_call_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SAVED_PC_AFTER_CALL_P) +#error "Non multi-arch definition of SAVED_PC_AFTER_CALL" +#endif +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (SAVED_PC_AFTER_CALL_P) +#define SAVED_PC_AFTER_CALL_P() (gdbarch_saved_pc_after_call_p (current_gdbarch)) +#endif + +/* Default (function) for non- multi-arch platforms. */ +#if (!GDB_MULTI_ARCH) && !defined (SAVED_PC_AFTER_CALL) +#define SAVED_PC_AFTER_CALL(frame) (internal_error (__FILE__, __LINE__, "SAVED_PC_AFTER_CALL"), 0) +#endif + typedef CORE_ADDR (gdbarch_saved_pc_after_call_ftype) (struct frame_info *frame); extern CORE_ADDR gdbarch_saved_pc_after_call (struct gdbarch *gdbarch, struct frame_info *frame); extern void set_gdbarch_saved_pc_after_call (struct gdbarch *gdbarch, gdbarch_saved_pc_after_call_ftype *saved_pc_after_call); diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh index fa91815f8ef..5807eb21c8c 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -518,8 +518,8 @@ F:2:GET_LONGJMP_TARGET:int:get_longjmp_target:CORE_ADDR *pc:pc::0:0 # behaviour here (and hence entrench it further) gdbarch simply # reqires that these methods be set up from the word go. This also # avoids any potential problems with moving beyond multi-arch partial. -v:1:DEPRECATED_USE_GENERIC_DUMMY_FRAMES:int:deprecated_use_generic_dummy_frames:::::1::0 -v:1:CALL_DUMMY_LOCATION:int:call_dummy_location:::::AT_ENTRY_POINT::0 +v::DEPRECATED_USE_GENERIC_DUMMY_FRAMES:int:deprecated_use_generic_dummy_frames:::::1::0 +v::CALL_DUMMY_LOCATION:int:call_dummy_location:::::AT_ENTRY_POINT::0 f::CALL_DUMMY_ADDRESS:CORE_ADDR:call_dummy_address:void::::entry_point_address::0 v::CALL_DUMMY_START_OFFSET:CORE_ADDR:call_dummy_start_offset v::CALL_DUMMY_BREAKPOINT_OFFSET:CORE_ADDR:call_dummy_breakpoint_offset @@ -529,7 +529,7 @@ v::CALL_DUMMY_LENGTH:int:call_dummy_length # is false, the corresponding function works. This simplifies the # migration process - old code, calling DEPRECATED_PC_IN_CALL_DUMMY(), # doesn't need to be modified. -F:1:DEPRECATED_PC_IN_CALL_DUMMY:int:deprecated_pc_in_call_dummy:CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR frame_address:pc, sp, frame_address::generic_pc_in_call_dummy:generic_pc_in_call_dummy +F::DEPRECATED_PC_IN_CALL_DUMMY:int:deprecated_pc_in_call_dummy:CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR frame_address:pc, sp, frame_address::generic_pc_in_call_dummy:generic_pc_in_call_dummy v::CALL_DUMMY_WORDS:LONGEST *:call_dummy_words::::0:legacy_call_dummy_words::0:0x%08lx v::SIZEOF_CALL_DUMMY_WORDS:int:sizeof_call_dummy_words::::0:legacy_sizeof_call_dummy_words::0 V:2:DEPRECATED_CALL_DUMMY_STACK_ADJUST:int:deprecated_call_dummy_stack_adjust::::0 @@ -599,7 +599,7 @@ F:2:DEPRECATED_FRAME_SAVED_PC:CORE_ADDR:deprecated_frame_saved_pc:struct frame_i M::UNWIND_PC:CORE_ADDR:unwind_pc:struct frame_info *next_frame:next_frame: f:2:FRAME_ARGS_ADDRESS:CORE_ADDR:frame_args_address:struct frame_info *fi:fi::0:get_frame_base::0 f:2:FRAME_LOCALS_ADDRESS:CORE_ADDR:frame_locals_address:struct frame_info *fi:fi::0:get_frame_base::0 -f:2:SAVED_PC_AFTER_CALL:CORE_ADDR:saved_pc_after_call:struct frame_info *frame:frame::0:0 +F::SAVED_PC_AFTER_CALL:CORE_ADDR:saved_pc_after_call:struct frame_info *frame:frame f:2:FRAME_NUM_ARGS:int:frame_num_args:struct frame_info *frame:frame::0:0 # F:2:STACK_ALIGN:CORE_ADDR:stack_align:CORE_ADDR sp:sp::0:0 @@ -820,18 +820,6 @@ extern struct gdbarch *current_gdbarch; /* If any of the following are defined, the target wasn't correctly converted. */ -#if GDB_MULTI_ARCH -#if defined (EXTRA_FRAME_INFO) -#error "EXTRA_FRAME_INFO: replaced by struct frame_extra_info" -#endif -#endif - -#if GDB_MULTI_ARCH -#if defined (FRAME_FIND_SAVED_REGS) -#error "FRAME_FIND_SAVED_REGS: replaced by DEPRECATED_FRAME_INIT_SAVED_REGS" -#endif -#endif - #if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PURE) && defined (GDB_TM_FILE) #error "GDB_TM_FILE: Pure multi-arch targets do not have a tm.h file." #endif diff --git a/gdb/hppa-hpux-tdep.c b/gdb/hppa-hpux-tdep.c index 3d1ca88ce50..1e1cb917820 100644 --- a/gdb/hppa-hpux-tdep.c +++ b/gdb/hppa-hpux-tdep.c @@ -35,7 +35,7 @@ void hppa_hpux_frame_saved_pc_in_sigtramp (struct frame_info *fi, void hppa_hpux_frame_base_before_sigtramp (struct frame_info *fi, CORE_ADDR *tmp); void hppa_hpux_frame_find_saved_regs_in_sigtramp - (struct frame_info *fi, struct frame_saved_regs *fsr); + (struct frame_info *fi, CORE_ADDR *fsr); int hppa_hpux_pc_in_sigtramp (CORE_ADDR pc, char *name) @@ -79,7 +79,7 @@ hppa_hpux_frame_base_before_sigtramp (struct frame_info *fi, void hppa_hpux_frame_find_saved_regs_in_sigtramp (struct frame_info *fi, - struct frame_saved_regs *fsr) + CORE_ADDR *fsr) { int i; const CORE_ADDR tmp = (fi)->frame + (10 * 4); @@ -87,9 +87,9 @@ hppa_hpux_frame_find_saved_regs_in_sigtramp (struct frame_info *fi, for (i = 0; i < NUM_REGS; i++) { if (i == SP_REGNUM) - (fsr)->regs[SP_REGNUM] = read_memory_integer (tmp + SP_REGNUM * 4, 4); + fsr[SP_REGNUM] = read_memory_integer (tmp + SP_REGNUM * 4, 4); else - (fsr)->regs[i] = tmp + i * 4; + fsr[i] = tmp + i * 4; } } diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c index 2e0c192250c..896d638e9e7 100644 --- a/gdb/hppa-tdep.c +++ b/gdb/hppa-tdep.c @@ -78,8 +78,7 @@ static unsigned extract_5R_store (unsigned int); static unsigned extract_5r_store (unsigned int); -static void find_dummy_frame_regs (struct frame_info *, - struct frame_saved_regs *); +static void find_dummy_frame_regs (struct frame_info *, CORE_ADDR *); static int find_proc_framesize (CORE_ADDR); @@ -103,7 +102,7 @@ static int low_sign_extend (unsigned int, unsigned int); static int sign_extend (unsigned int, unsigned int); -static int restore_pc_queue (struct frame_saved_regs *); +static int restore_pc_queue (CORE_ADDR *); static int hppa_alignof (struct type *); @@ -943,13 +942,13 @@ hppa_frame_saved_pc (struct frame_info *frame) && ((get_frame_type (frame->next) == SIGTRAMP_FRAME) || pc_in_interrupt_handler (frame->next->pc))) { - struct frame_saved_regs saved_regs; - - deprecated_get_frame_saved_regs (frame->next, &saved_regs); - if (read_memory_integer (saved_regs.regs[FLAGS_REGNUM], + CORE_ADDR *saved_regs; + hppa_frame_init_saved_regs (frame->next); + saved_regs = get_frame_saved_regs (frame->next); + if (read_memory_integer (saved_regs[FLAGS_REGNUM], TARGET_PTR_BIT / 8) & 0x2) { - pc = read_memory_integer (saved_regs.regs[31], + pc = read_memory_integer (saved_regs[31], TARGET_PTR_BIT / 8) & ~0x3; /* Syscalls are really two frames. The syscall stub itself @@ -957,11 +956,11 @@ hppa_frame_saved_pc (struct frame_info *frame) a return pointer in %r31. We return the %rp variant if %r31 is the same as frame->pc. */ if (pc == frame->pc) - pc = read_memory_integer (saved_regs.regs[RP_REGNUM], + pc = read_memory_integer (saved_regs[RP_REGNUM], TARGET_PTR_BIT / 8) & ~0x3; } else - pc = read_memory_integer (saved_regs.regs[RP_REGNUM], + pc = read_memory_integer (saved_regs[RP_REGNUM], TARGET_PTR_BIT / 8) & ~0x3; } else @@ -983,13 +982,13 @@ hppa_frame_saved_pc (struct frame_info *frame) && ((get_frame_type (frame->next) == SIGTRAMP_FRAME) || pc_in_interrupt_handler (frame->next->pc))) { - struct frame_saved_regs saved_regs; - - deprecated_get_frame_saved_regs (frame->next, &saved_regs); - if (read_memory_integer (saved_regs.regs[FLAGS_REGNUM], + CORE_ADDR *saved_regs; + hppa_frame_init_saved_regs (frame->next); + saved_regs = get_frame_saved_regs (frame->next); + if (read_memory_integer (saved_regs[FLAGS_REGNUM], TARGET_PTR_BIT / 8) & 0x2) { - pc = read_memory_integer (saved_regs.regs[31], + pc = read_memory_integer (saved_regs[31], TARGET_PTR_BIT / 8) & ~0x3; /* Syscalls are really two frames. The syscall stub itself @@ -997,11 +996,11 @@ hppa_frame_saved_pc (struct frame_info *frame) a return pointer in %r31. We return the %rp variant if %r31 is the same as frame->pc. */ if (pc == frame->pc) - pc = read_memory_integer (saved_regs.regs[RP_REGNUM], + pc = read_memory_integer (saved_regs[RP_REGNUM], TARGET_PTR_BIT / 8) & ~0x3; } else - pc = read_memory_integer (saved_regs.regs[RP_REGNUM], + pc = read_memory_integer (saved_regs[RP_REGNUM], TARGET_PTR_BIT / 8) & ~0x3; } else if (rp_offset == 0) @@ -1129,9 +1128,9 @@ hppa_frame_chain (struct frame_info *frame) /* A frame in the current frame list, or zero. */ struct frame_info *saved_regs_frame = 0; - /* Where the registers were saved in saved_regs_frame. - If saved_regs_frame is zero, this is garbage. */ - struct frame_saved_regs saved_regs; + /* Where the registers were saved in saved_regs_frame. If + saved_regs_frame is zero, this is garbage. */ + CORE_ADDR *saved_regs = NULL; CORE_ADDR caller_pc; @@ -1258,11 +1257,12 @@ hppa_frame_chain (struct frame_info *frame) /* The unwind entry claims that r3 is saved here. However, in optimized code, GCC often doesn't actually save r3. We'll discover this if we look at the prologue. */ - deprecated_get_frame_saved_regs (tmp_frame, &saved_regs); + hppa_frame_init_saved_regs (tmp_frame); + saved_regs = get_frame_saved_regs (tmp_frame); saved_regs_frame = tmp_frame; /* If we have an address for r3, that's good. */ - if (saved_regs.regs[FP_REGNUM]) + if (saved_regs[FP_REGNUM]) break; } } @@ -1307,21 +1307,24 @@ hppa_frame_chain (struct frame_info *frame) system call has a variable sized stack frame. */ if (tmp_frame != saved_regs_frame) - deprecated_get_frame_saved_regs (tmp_frame, &saved_regs); + { + hppa_frame_init_saved_regs (tmp_frame); + saved_regs = get_frame_saved_regs (tmp_frame); + } /* Abominable hack. */ if (current_target.to_has_execution == 0 - && ((saved_regs.regs[FLAGS_REGNUM] - && (read_memory_integer (saved_regs.regs[FLAGS_REGNUM], + && ((saved_regs[FLAGS_REGNUM] + && (read_memory_integer (saved_regs[FLAGS_REGNUM], TARGET_PTR_BIT / 8) & 0x2)) - || (saved_regs.regs[FLAGS_REGNUM] == 0 + || (saved_regs[FLAGS_REGNUM] == 0 && read_register (FLAGS_REGNUM) & 0x2))) { u = find_unwind_entry (DEPRECATED_FRAME_SAVED_PC (frame)); if (!u) { - return read_memory_integer (saved_regs.regs[FP_REGNUM], + return read_memory_integer (saved_regs[FP_REGNUM], TARGET_PTR_BIT / 8); } else @@ -1330,7 +1333,7 @@ hppa_frame_chain (struct frame_info *frame) } } - return read_memory_integer (saved_regs.regs[FP_REGNUM], + return read_memory_integer (saved_regs[FP_REGNUM], TARGET_PTR_BIT / 8); } } @@ -1342,21 +1345,24 @@ hppa_frame_chain (struct frame_info *frame) tmp_frame = tmp_frame->next; if (tmp_frame != saved_regs_frame) - deprecated_get_frame_saved_regs (tmp_frame, &saved_regs); + { + hppa_frame_init_saved_regs (tmp_frame); + saved_regs = get_frame_saved_regs (tmp_frame); + } /* Abominable hack. See above. */ if (current_target.to_has_execution == 0 - && ((saved_regs.regs[FLAGS_REGNUM] - && (read_memory_integer (saved_regs.regs[FLAGS_REGNUM], + && ((saved_regs[FLAGS_REGNUM] + && (read_memory_integer (saved_regs[FLAGS_REGNUM], TARGET_PTR_BIT / 8) & 0x2)) - || (saved_regs.regs[FLAGS_REGNUM] == 0 + || (saved_regs[FLAGS_REGNUM] == 0 && read_register (FLAGS_REGNUM) & 0x2))) { u = find_unwind_entry (DEPRECATED_FRAME_SAVED_PC (frame)); if (!u) { - return read_memory_integer (saved_regs.regs[FP_REGNUM], + return read_memory_integer (saved_regs[FP_REGNUM], TARGET_PTR_BIT / 8); } else @@ -1496,26 +1502,26 @@ hppa_push_dummy_frame (void) static void find_dummy_frame_regs (struct frame_info *frame, - struct frame_saved_regs *frame_saved_regs) + CORE_ADDR frame_saved_regs[]) { CORE_ADDR fp = frame->frame; int i; /* The 32bit and 64bit ABIs save RP into different locations. */ if (REGISTER_SIZE == 8) - frame_saved_regs->regs[RP_REGNUM] = (fp - 16) & ~0x3; + frame_saved_regs[RP_REGNUM] = (fp - 16) & ~0x3; else - frame_saved_regs->regs[RP_REGNUM] = (fp - 20) & ~0x3; + frame_saved_regs[RP_REGNUM] = (fp - 20) & ~0x3; - frame_saved_regs->regs[FP_REGNUM] = fp; + frame_saved_regs[FP_REGNUM] = fp; - frame_saved_regs->regs[1] = fp + (2 * REGISTER_SIZE); + frame_saved_regs[1] = fp + (2 * REGISTER_SIZE); for (fp += 3 * REGISTER_SIZE, i = 3; i < 32; i++) { if (i != FP_REGNUM) { - frame_saved_regs->regs[i] = fp; + frame_saved_regs[i] = fp; fp += REGISTER_SIZE; } } @@ -1525,14 +1531,14 @@ find_dummy_frame_regs (struct frame_info *frame, fp += 4; for (i = FP0_REGNUM; i < NUM_REGS; i++, fp += 8) - frame_saved_regs->regs[i] = fp; - - frame_saved_regs->regs[IPSW_REGNUM] = fp; - frame_saved_regs->regs[SAR_REGNUM] = fp + REGISTER_SIZE; - frame_saved_regs->regs[PCOQ_HEAD_REGNUM] = fp + 2 * REGISTER_SIZE; - frame_saved_regs->regs[PCSQ_HEAD_REGNUM] = fp + 3 * REGISTER_SIZE; - frame_saved_regs->regs[PCOQ_TAIL_REGNUM] = fp + 4 * REGISTER_SIZE; - frame_saved_regs->regs[PCSQ_TAIL_REGNUM] = fp + 5 * REGISTER_SIZE; + frame_saved_regs[i] = fp; + + frame_saved_regs[IPSW_REGNUM] = fp; + frame_saved_regs[SAR_REGNUM] = fp + REGISTER_SIZE; + frame_saved_regs[PCOQ_HEAD_REGNUM] = fp + 2 * REGISTER_SIZE; + frame_saved_regs[PCSQ_HEAD_REGNUM] = fp + 3 * REGISTER_SIZE; + frame_saved_regs[PCOQ_TAIL_REGNUM] = fp + 4 * REGISTER_SIZE; + frame_saved_regs[PCSQ_TAIL_REGNUM] = fp + 5 * REGISTER_SIZE; } void @@ -1541,44 +1547,45 @@ hppa_pop_frame (void) register struct frame_info *frame = get_current_frame (); register CORE_ADDR fp, npc, target_pc; register int regnum; - struct frame_saved_regs fsr; + CORE_ADDR *fsr; double freg_buffer; fp = get_frame_base (frame); - deprecated_get_frame_saved_regs (frame, &fsr); + hppa_frame_init_saved_regs (frame); + fsr = get_frame_saved_regs (frame); #ifndef NO_PC_SPACE_QUEUE_RESTORE - if (fsr.regs[IPSW_REGNUM]) /* Restoring a call dummy frame */ - restore_pc_queue (&fsr); + if (fsr[IPSW_REGNUM]) /* Restoring a call dummy frame */ + restore_pc_queue (fsr); #endif for (regnum = 31; regnum > 0; regnum--) - if (fsr.regs[regnum]) - write_register (regnum, read_memory_integer (fsr.regs[regnum], + if (fsr[regnum]) + write_register (regnum, read_memory_integer (fsr[regnum], REGISTER_SIZE)); for (regnum = NUM_REGS - 1; regnum >= FP0_REGNUM; regnum--) - if (fsr.regs[regnum]) + if (fsr[regnum]) { - read_memory (fsr.regs[regnum], (char *) &freg_buffer, 8); + read_memory (fsr[regnum], (char *) &freg_buffer, 8); deprecated_write_register_bytes (REGISTER_BYTE (regnum), (char *) &freg_buffer, 8); } - if (fsr.regs[IPSW_REGNUM]) + if (fsr[IPSW_REGNUM]) write_register (IPSW_REGNUM, - read_memory_integer (fsr.regs[IPSW_REGNUM], + read_memory_integer (fsr[IPSW_REGNUM], REGISTER_SIZE)); - if (fsr.regs[SAR_REGNUM]) + if (fsr[SAR_REGNUM]) write_register (SAR_REGNUM, - read_memory_integer (fsr.regs[SAR_REGNUM], + read_memory_integer (fsr[SAR_REGNUM], REGISTER_SIZE)); /* If the PC was explicitly saved, then just restore it. */ - if (fsr.regs[PCOQ_TAIL_REGNUM]) + if (fsr[PCOQ_TAIL_REGNUM]) { - npc = read_memory_integer (fsr.regs[PCOQ_TAIL_REGNUM], + npc = read_memory_integer (fsr[PCOQ_TAIL_REGNUM], REGISTER_SIZE); write_register (PCOQ_TAIL_REGNUM, npc); } @@ -1591,7 +1598,7 @@ hppa_pop_frame (void) write_register (FP_REGNUM, read_memory_integer (fp, REGISTER_SIZE)); - if (fsr.regs[IPSW_REGNUM]) /* call dummy */ + if (fsr[IPSW_REGNUM]) /* call dummy */ write_register (SP_REGNUM, fp - 48); else write_register (SP_REGNUM, fp); @@ -1604,7 +1611,7 @@ hppa_pop_frame (void) Don't skip through the trampoline if we're popping a dummy frame. */ target_pc = SKIP_TRAMPOLINE_CODE (npc & ~0x3) & ~0x3; - if (target_pc && !fsr.regs[IPSW_REGNUM]) + if (target_pc && !fsr[IPSW_REGNUM]) { struct symtab_and_line sal; struct breakpoint *breakpoint; @@ -1635,10 +1642,10 @@ hppa_pop_frame (void) queue space registers. */ static int -restore_pc_queue (struct frame_saved_regs *fsr) +restore_pc_queue (CORE_ADDR *fsr) { CORE_ADDR pc = read_pc (); - CORE_ADDR new_pc = read_memory_integer (fsr->regs[PCOQ_HEAD_REGNUM], + CORE_ADDR new_pc = read_memory_integer (fsr[PCOQ_HEAD_REGNUM], TARGET_PTR_BIT / 8); struct target_waitstatus w; int insn_count; @@ -1657,7 +1664,7 @@ restore_pc_queue (struct frame_saved_regs *fsr) So, load up the registers and single step until we are in the right place. */ - write_register (21, read_memory_integer (fsr->regs[PCSQ_HEAD_REGNUM], + write_register (21, read_memory_integer (fsr[PCSQ_HEAD_REGNUM], REGISTER_SIZE)); write_register (22, new_pc); @@ -3842,15 +3849,15 @@ hppa_skip_prologue (CORE_ADDR pc) return (skip_prologue_hard_way (pc)); } -/* Put here the code to store, into a struct frame_saved_regs, - the addresses of the saved registers of frame described by FRAME_INFO. - This includes special registers such as pc and fp saved in special - ways in the stack frame. sp is even more special: - the address we return for it IS the sp for the next frame. */ +/* Put here the code to store, into the SAVED_REGS, the addresses of + the saved registers of frame described by FRAME_INFO. This + includes special registers such as pc and fp saved in special ways + in the stack frame. sp is even more special: the address we return + for it IS the sp for the next frame. */ void hppa_frame_find_saved_regs (struct frame_info *frame_info, - struct frame_saved_regs *frame_saved_regs) + CORE_ADDR frame_saved_regs[]) { CORE_ADDR pc; struct unwind_table_entry *u; @@ -3861,7 +3868,7 @@ hppa_frame_find_saved_regs (struct frame_info *frame_info, int final_iteration; /* Zero out everything. */ - memset (frame_saved_regs, '\0', sizeof (struct frame_saved_regs)); + memset (frame_saved_regs, '\0', SIZEOF_FRAME_SAVED_REGS); /* Call dummy frames always look the same, so there's no need to examine the dummy code to determine locations of saved registers; @@ -3892,11 +3899,11 @@ hppa_frame_find_saved_regs (struct frame_info *frame_info, { /* SP is a little special. */ if (i == SP_REGNUM) - frame_saved_regs->regs[SP_REGNUM] + frame_saved_regs[SP_REGNUM] = read_memory_integer (frame_info->frame + SP_REGNUM * 4, TARGET_PTR_BIT / 8); else - frame_saved_regs->regs[i] = frame_info->frame + i * 4; + frame_saved_regs[i] = frame_info->frame + i * 4; } return; } @@ -3912,7 +3919,7 @@ hppa_frame_find_saved_regs (struct frame_info *frame_info, /* Get the starting address of the function referred to by the PC saved in frame. */ - pc = get_pc_function_start (frame_info->pc); + pc = get_frame_func (frame_info); /* Yow! */ u = find_unwind_entry (pc); @@ -3945,7 +3952,7 @@ hppa_frame_find_saved_regs (struct frame_info *frame_info, /* The frame always represents the value of %sp at entry to the current function (and is thus equivalent to the "saved" stack pointer. */ - frame_saved_regs->regs[SP_REGNUM] = frame_info->frame; + frame_saved_regs[SP_REGNUM] = frame_info->frame; /* Loop until we find everything of interest or hit a branch. @@ -3980,12 +3987,12 @@ hppa_frame_find_saved_regs (struct frame_info *frame_info, if (inst == 0x6bc23fd9) /* stw rp,-0x14(sr0,sp) */ { save_rp = 0; - frame_saved_regs->regs[RP_REGNUM] = frame_info->frame - 20; + frame_saved_regs[RP_REGNUM] = frame_info->frame - 20; } else if (inst == 0x0fc212c1) /* std rp,-0x10(sr0,sp) */ { save_rp = 0; - frame_saved_regs->regs[RP_REGNUM] = frame_info->frame - 16; + frame_saved_regs[RP_REGNUM] = frame_info->frame - 16; } /* Note if we saved SP into the stack. This also happens to indicate @@ -3993,7 +4000,7 @@ hppa_frame_find_saved_regs (struct frame_info *frame_info, if ( (inst & 0xffffc000) == 0x6fc10000 /* stw,ma r1,N(sr0,sp) */ || (inst & 0xffffc00c) == 0x73c10008) /* std,ma r1,N(sr0,sp) */ { - frame_saved_regs->regs[FP_REGNUM] = frame_info->frame; + frame_saved_regs[FP_REGNUM] = frame_info->frame; save_sp = 0; } @@ -4007,10 +4014,10 @@ hppa_frame_find_saved_regs (struct frame_info *frame_info, /* stwm with a positive displacement is a *post modify*. */ if ((inst >> 26) == 0x1b && extract_14 (inst) >= 0) - frame_saved_regs->regs[reg] = frame_info->frame; + frame_saved_regs[reg] = frame_info->frame; /* A std has explicit post_modify forms. */ else if ((inst & 0xfc00000c0) == 0x70000008) - frame_saved_regs->regs[reg] = frame_info->frame; + frame_saved_regs[reg] = frame_info->frame; else { CORE_ADDR offset; @@ -4024,10 +4031,10 @@ hppa_frame_find_saved_regs (struct frame_info *frame_info, /* Handle code with and without frame pointers. */ if (u->Save_SP) - frame_saved_regs->regs[reg] + frame_saved_regs[reg] = frame_info->frame + offset; else - frame_saved_regs->regs[reg] + frame_saved_regs[reg] = (frame_info->frame + (u->Total_frame_size << 3) + offset); } @@ -4060,12 +4067,12 @@ hppa_frame_find_saved_regs (struct frame_info *frame_info, /* 1st HP CC FP register store. After this instruction we've set enough state that the GCC and HPCC code are both handled in the same manner. */ - frame_saved_regs->regs[reg + FP4_REGNUM + 4] = frame_info->frame; + frame_saved_regs[reg + FP4_REGNUM + 4] = frame_info->frame; fp_loc = 8; } else { - frame_saved_regs->regs[reg + FP0_REGNUM + 4] + frame_saved_regs[reg + FP0_REGNUM + 4] = frame_info->frame + fp_loc; fp_loc += 8; } @@ -4085,6 +4092,17 @@ hppa_frame_find_saved_regs (struct frame_info *frame_info, } } +/* XXX - deprecated. This is a compatibility function for targets + that do not yet implement DEPRECATED_FRAME_INIT_SAVED_REGS. */ +/* Find the addresses in which registers are saved in FRAME. */ + +void +hppa_frame_init_saved_regs (struct frame_info *frame) +{ + if (get_frame_saved_regs (frame) == NULL) + frame_saved_regs_zalloc (frame); + hppa_frame_find_saved_regs (frame, get_frame_saved_regs (frame)); +} /* Exception handling support for the HP-UX ANSI C++ compiler. The compiler (aCC) provides a callback for exception events; diff --git a/gdb/i386-cygwin-tdep.c b/gdb/i386-cygwin-tdep.c index b07911b3b33..5911ec9b91a 100644 --- a/gdb/i386-cygwin-tdep.c +++ b/gdb/i386-cygwin-tdep.c @@ -20,8 +20,37 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "defs.h" #include "gdb_string.h" +#include "gdbcore.h" #include "i386-tdep.h" #include "osabi.h" +#include "frame.h" +#include "dummy-frame.h" + +static int +i386_cygwin_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe) +{ + /* In the context where this is used, we get the saved PC before we've + successfully unwound far enough to be sure what we've got (it may + be a signal handler caller). If we're dealing with a signal + handler caller, this will return valid, which is fine. If not, + it'll make the correct test. */ + return ((get_frame_type (thisframe) == SIGTRAMP_FRAME) || chain != 0); +} +/* Return the chain-pointer for FRAME. In the case of the i386, the + frame's nominal address is the address of a 4-byte word containing + the calling frame's address. */ +static CORE_ADDR +i386_cygwin_frame_chain (struct frame_info *frame) +{ + if (pc_in_dummy_frame (get_frame_pc (frame))) + return get_frame_base (frame); + + if (get_frame_type (frame) == SIGTRAMP_FRAME + || i386_frameless_signal_p (frame)) + return get_frame_base (frame); + + return read_memory_unsigned_integer (get_frame_base (frame), 4); +} static void i386_cygwin_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) @@ -29,6 +58,8 @@ i386_cygwin_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); tdep->struct_return = reg_struct_return; + set_gdbarch_deprecated_frame_chain (gdbarch, i386_cygwin_frame_chain); + set_gdbarch_deprecated_frame_chain_valid (gdbarch, i386_cygwin_frame_chain_valid); } static enum gdb_osabi diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index 7ef1f6e80e0..317d7261e79 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -502,7 +502,7 @@ i386_frameless_signal_p (struct frame_info *frame) return (get_next_frame (frame) && get_frame_type (get_next_frame (frame)) == SIGTRAMP_FRAME && (frameless_look_for_prologue (frame) - || get_frame_pc (frame) == get_pc_function_start (get_frame_pc (frame)))); + || get_frame_pc (frame) == get_frame_func (frame))); } /* Return the chain-pointer for FRAME. In the case of the i386, the @@ -714,7 +714,7 @@ i386_frame_init_saved_regs (struct frame_info *fip) frame_saved_regs_zalloc (fip); - pc = get_pc_function_start (get_frame_pc (fip)); + pc = get_frame_func (fip); if (pc != 0) locals = i386_get_frame_setup (pc); diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c index ecb49197291..7abd7ea3321 100644 --- a/gdb/ia64-tdep.c +++ b/gdb/ia64-tdep.c @@ -273,7 +273,7 @@ ia64_register_convert_to_virtual (int regnum, struct type *type, { DOUBLEST val; floatformat_to_doublest (&floatformat_ia64_ext, from, &val); - store_floating(to, TYPE_LENGTH(type), val); + deprecated_store_floating (to, TYPE_LENGTH(type), val); } else error("ia64_register_convert_to_virtual called with non floating point register number"); @@ -285,7 +285,7 @@ ia64_register_convert_to_raw (struct type *type, int regnum, { if (regnum >= IA64_FR0_REGNUM && regnum <= IA64_FR127_REGNUM) { - DOUBLEST val = extract_floating (from, TYPE_LENGTH(type)); + DOUBLEST val = deprecated_extract_floating (from, TYPE_LENGTH(type)); floatformat_from_doublest (&floatformat_ia64_ext, &val, to); } else @@ -1205,7 +1205,7 @@ ia64_frame_init_saved_regs (struct frame_info *frame) { CORE_ADDR func_start; - func_start = get_pc_function_start (get_frame_pc (frame)); + func_start = get_frame_func (frame); examine_prologue (func_start, get_frame_pc (frame), frame); } } diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 38666905706..01ab3d7b0de 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -1910,8 +1910,13 @@ attach_command (char *args, int from_tty) /* No traps are generated when attaching to inferior under Mach 3 or GNU hurd. */ #ifndef ATTACH_NO_WAIT - stop_soon_quietly = 1; + /* Careful here. See comments in inferior.h. Basically some OSes + don't ignore SIGSTOPs on continue requests anymore. We need a + way for handle_inferior_event to reset the stop_signal variable + after an attach, and this is what STOP_QUIETLY_NO_SIGSTOP is for. */ + stop_soon = STOP_QUIETLY_NO_SIGSTOP; wait_for_inferior (); + stop_soon = NO_STOP_QUIETLY; #endif /* diff --git a/gdb/inferior.h b/gdb/inferior.h index ae041f25004..db0f4d98bea 100644 --- a/gdb/inferior.h +++ b/gdb/inferior.h @@ -390,12 +390,37 @@ extern enum step_over_calls_kind step_over_calls; extern int step_multi; -/* Nonzero means expecting a trap and caller will handle it themselves. - It is used after attach, due to attaching to a process; - when running in the shell before the child program has been exec'd; - and when running some kinds of remote stuff (FIXME?). */ +/* Nonzero means expecting a trap and caller will handle it + themselves. It is used when running in the shell before the child + program has been exec'd; and when running some kinds of remote + stuff (FIXME?). */ + +/* It is also used after attach, due to attaching to a process. This + is a bit trickier. When doing an attach, the kernel stops the + debuggee with a SIGSTOP. On newer GNU/Linux kernels (>= 2.5.61) + the handling of SIGSTOP for a ptraced process has changed. Earlier + versions of the kernel would ignore these SIGSTOPs, while now + SIGSTOP is treated like any other signal, i.e. it is not muffled. + + If the gdb user does a 'continue' after the 'attach', gdb passes + the global variable stop_signal (which stores the signal from the + attach, SIGSTOP) to the ptrace(PTRACE_CONT,...) call. This is + problematic, because the kernel doesn't ignore such SIGSTOP + now. I.e. it is reported back to gdb, which in turn presents it + back to the user. + + To avoid the problem, we use STOP_QUIETLY_NO_SIGSTOP, which allows + gdb to clear the value of stop_signal after the attach, so that it + is not passed back down to the kernel. */ + +enum stop_kind + { + NO_STOP_QUIETLY = 0, + STOP_QUIETLY, + STOP_QUIETLY_NO_SIGSTOP + }; -extern int stop_soon_quietly; +extern enum stop_kind stop_soon; /* Nonzero if proceed is being used for a "finish" command or a similar situation when stop_registers should be saved. */ diff --git a/gdb/infrun.c b/gdb/infrun.c index 74f1de1f672..3fda9649f07 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -286,7 +286,7 @@ int stop_after_trap; when running in the shell before the child program has been exec'd; and when running some kinds of remote stuff (FIXME?). */ -int stop_soon_quietly; +enum stop_kind stop_soon; /* Nonzero if proceed is being used for a "finish" command or a similar situation when stop_registers should be saved. */ @@ -659,7 +659,7 @@ clear_proceed_status (void) step_frame_id = null_frame_id; step_over_calls = STEP_OVER_UNDEBUGGABLE; stop_after_trap = 0; - stop_soon_quietly = 0; + stop_soon = NO_STOP_QUIETLY; proceed_to_finish = 0; breakpoint_proceeded = 1; /* We're about to proceed... */ @@ -802,7 +802,7 @@ start_remote (void) { init_thread_list (); init_wait_for_inferior (); - stop_soon_quietly = 1; + stop_soon = STOP_QUIETLY; trap_expected = 0; /* Always go on waiting for the target, regardless of the mode. */ @@ -1258,7 +1258,7 @@ handle_inferior_event (struct execution_control_state *ecs) might be the shell which has just loaded some objects, otherwise add the symbols for the newly loaded objects. */ #ifdef SOLIB_ADD - if (!stop_soon_quietly) + if (stop_soon == NO_STOP_QUIETLY) { /* Remove breakpoints, SOLIB_ADD might adjust breakpoint addresses via breakpoint_re_set. */ @@ -1757,7 +1757,9 @@ handle_inferior_event (struct execution_control_state *ecs) if (stop_signal == TARGET_SIGNAL_TRAP || (breakpoints_inserted && (stop_signal == TARGET_SIGNAL_ILL - || stop_signal == TARGET_SIGNAL_EMT)) || stop_soon_quietly) + || stop_signal == TARGET_SIGNAL_EMT)) + || stop_soon == STOP_QUIETLY + || stop_soon == STOP_QUIETLY_NO_SIGSTOP) { if (stop_signal == TARGET_SIGNAL_TRAP && stop_after_trap) { @@ -1765,9 +1767,24 @@ handle_inferior_event (struct execution_control_state *ecs) stop_stepping (ecs); return; } - if (stop_soon_quietly) + + /* This is originated from start_remote(), start_inferior() and + shared libraries hook functions. */ + if (stop_soon == STOP_QUIETLY) + { + stop_stepping (ecs); + return; + } + + /* This originates from attach_command(). We need to overwrite + the stop_signal here, because some kernels don't ignore a + SIGSTOP in a subsequent ptrace(PTRACE_SONT,SOGSTOP) call. + See more comments in inferior.h. */ + if (stop_soon == STOP_QUIETLY_NO_SIGSTOP) { stop_stepping (ecs); + if (stop_signal == TARGET_SIGNAL_STOP) + stop_signal = TARGET_SIGNAL_0; return; } @@ -2658,7 +2675,44 @@ step_over_function (struct execution_control_state *ecs) struct symtab_and_line sr_sal; init_sal (&sr_sal); /* initialize to zeros */ - sr_sal.pc = ADDR_BITS_REMOVE (SAVED_PC_AFTER_CALL (get_current_frame ())); + + /* NOTE: cagney/2003-04-06: + + At this point the equality get_frame_pc() == get_frame_func() + should hold. This may make it possible for this code to tell the + frame where it's function is, instead of the reverse. This would + avoid the need to search for the frame's function, which can get + very messy when there is no debug info available (look at the + heuristic find pc start code found in targets like the MIPS). */ + + /* NOTE: cagney/2003-04-06: Deprecate SAVED_PC_AFTER_CALL? + + The intent of SAVED_PC_AFTER_CALL was to: + + - provide a very light weight equivalent to frame_unwind_pc() + (nee FRAME_SAVED_PC) that avoids the prologue analyzer + + - avoid handling the case where the PC hasn't been saved in the + prologue analyzer + + Unfortunatly, not five lines further down, is a call to + get_frame_id() and that is guarenteed to trigger the prologue + analyzer. + + The `correct fix' is for the prologe analyzer to handle the case + where the prologue is incomplete (PC in prologue) and, + consequently, the return pc has not yet been saved. It should be + noted that the prologue analyzer needs to handle this case + anyway: frameless leaf functions that don't save the return PC; + single stepping through a prologue. + + The d10v handles all this by bailing out of the prologue analsis + when it reaches the current instruction. */ + + if (SAVED_PC_AFTER_CALL_P ()) + sr_sal.pc = ADDR_BITS_REMOVE (SAVED_PC_AFTER_CALL (get_current_frame ())); + else + sr_sal.pc = ADDR_BITS_REMOVE (frame_pc_unwind (get_current_frame ())); sr_sal.section = find_pc_overlay (sr_sal.pc); check_for_old_step_resume_breakpoint (); @@ -3460,7 +3514,7 @@ struct inferior_status enum step_over_calls_kind step_over_calls; CORE_ADDR step_resume_break_address; int stop_after_trap; - int stop_soon_quietly; + int stop_soon; struct regcache *stop_registers; /* These are here because if call_function_by_hand has written some @@ -3506,7 +3560,7 @@ save_inferior_status (int restore_stack_info) inf_status->step_frame_id = step_frame_id; inf_status->step_over_calls = step_over_calls; inf_status->stop_after_trap = stop_after_trap; - inf_status->stop_soon_quietly = stop_soon_quietly; + inf_status->stop_soon = stop_soon; /* Save original bpstat chain here; replace it with copy of chain. If caller's caller is walking the chain, they'll be happier if we hand them back the original chain when restore_inferior_status is @@ -3560,7 +3614,7 @@ restore_inferior_status (struct inferior_status *inf_status) step_frame_id = inf_status->step_frame_id; step_over_calls = inf_status->step_over_calls; stop_after_trap = inf_status->stop_after_trap; - stop_soon_quietly = inf_status->stop_soon_quietly; + stop_soon = inf_status->stop_soon; bpstat_clear (&stop_bpstat); stop_bpstat = inf_status->stop_bpstat; breakpoint_proceeded = inf_status->breakpoint_proceeded; diff --git a/gdb/m3-nat.c b/gdb/m3-nat.c index 28e62a87f76..93ef57a5f20 100644 --- a/gdb/m3-nat.c +++ b/gdb/m3-nat.c @@ -1,4566 +1,4566 @@ -/* Interface GDB to Mach 3.0 operating systems. - (Most) Mach 3.0 related routines live in this file. - - Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, - 2002 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* - * Author: Jukka Virtanen <jtv@hut.fi> - * Computing Centre - * Helsinki University of Technology - * Finland - * - * Thanks to my friends who helped with ideas and testing: - * - * Johannes Helander, Antti Louko, Tero Mononen, - * jvh@cs.hut.fi alo@hut.fi tmo@cs.hut.fi - * - * Tero Kivinen and Eamonn McManus - * kivinen@cs.hut.fi emcmanus@gr.osf.org - * - */ - -#include <stdio.h> - -#include <mach.h> -#include <servers/netname.h> -#include <servers/machid.h> -#include <mach/message.h> -#include <mach/notify.h> -#include <mach_error.h> -#include <mach/exception.h> -#include <mach/vm_attributes.h> - -#include "defs.h" -#include "inferior.h" -#include "symtab.h" -#include "value.h" -#include "language.h" -#include "target.h" -#include "gdb_wait.h" -#include "gdbcmd.h" -#include "gdbcore.h" -#include "regcache.h" - -#if 0 -#include <servers/machid_lib.h> -#else -#define MACH_TYPE_TASK 1 -#define MACH_TYPE_THREAD 2 -#endif - -/* Included only for signal names and NSIG - - * note: There are many problems in signal handling with - * gdb in Mach 3.0 in general. - */ -#include <signal.h> -#define SIG_UNKNOWN 0 /* Exception that has no matching unix signal */ - -#include <cthreads.h> - -/* This is what a cproc looks like. This is here partly because - cthread_internals.h is not a header we can just #include, partly with - an eye towards perhaps getting this to work with cross-debugging - someday. Best solution is if CMU publishes a real interface to this - stuff. */ -#define CPROC_NEXT_OFFSET 0 -#define CPROC_NEXT_SIZE (TARGET_PTR_BIT / HOST_CHAR_BIT) -#define CPROC_INCARNATION_OFFSET (CPROC_NEXT_OFFSET + CPROC_NEXT_SIZE) -#define CPROC_INCARNATION_SIZE (sizeof (cthread_t)) -#define CPROC_LIST_OFFSET (CPROC_INCARNATION_OFFSET + CPROC_INCARNATION_SIZE) -#define CPROC_LIST_SIZE (TARGET_PTR_BIT / HOST_CHAR_BIT) -#define CPROC_WAIT_OFFSET (CPROC_LIST_OFFSET + CPROC_LIST_SIZE) -#define CPROC_WAIT_SIZE (TARGET_PTR_BIT / HOST_CHAR_BIT) -#define CPROC_REPLY_OFFSET (CPROC_WAIT_OFFSET + CPROC_WAIT_SIZE) -#define CPROC_REPLY_SIZE (sizeof (mach_port_t)) -#define CPROC_CONTEXT_OFFSET (CPROC_REPLY_OFFSET + CPROC_REPLY_SIZE) -#define CPROC_CONTEXT_SIZE (TARGET_INT_BIT / HOST_CHAR_BIT) -#define CPROC_LOCK_OFFSET (CPROC_CONTEXT_OFFSET + CPROC_CONTEXT_SIZE) -#define CPROC_LOCK_SIZE (sizeof (spin_lock_t)) -#define CPROC_STATE_OFFSET (CPROC_LOCK_OFFSET + CPROC_LOCK_SIZE) -#define CPROC_STATE_SIZE (TARGET_INT_BIT / HOST_CHAR_BIT) -#define CPROC_WIRED_OFFSET (CPROC_STATE_OFFSET + CPROC_STATE_SIZE) -#define CPROC_WIRED_SIZE (sizeof (mach_port_t)) -#define CPROC_BUSY_OFFSET (CPROC_WIRED_OFFSET + CPROC_WIRED_SIZE) -#define CPROC_BUSY_SIZE (TARGET_INT_BIT / HOST_CHAR_BIT) -#define CPROC_MSG_OFFSET (CPROC_BUSY_OFFSET + CPROC_BUSY_SIZE) -#define CPROC_MSG_SIZE (sizeof (mach_msg_header_t)) -#define CPROC_BASE_OFFSET (CPROC_MSG_OFFSET + CPROC_MSG_SIZE) -#define CPROC_BASE_SIZE (TARGET_INT_BIT / HOST_CHAR_BIT) -#define CPROC_SIZE_OFFSET (CPROC_BASE_OFFSET + CPROC_BASE_SIZE) -#define CPROC_SIZE_SIZE (TARGET_INT_BIT / HOST_CHAR_BIT) -#define CPROC_SIZE (CPROC_SIZE_OFFSET + CPROC_SIZE_SIZE) - -/* Values for the state field in the cproc. */ -#define CPROC_RUNNING 0 -#define CPROC_SWITCHING 1 -#define CPROC_BLOCKED 2 -#define CPROC_CONDWAIT 4 - -/* For cproc and kernel thread mapping */ -typedef struct gdb_thread - { - mach_port_t name; - CORE_ADDR sp; - CORE_ADDR pc; - CORE_ADDR fp; - boolean_t in_emulator; - int slotid; - - /* This is for the mthreads list. It points to the cproc list. - Perhaps the two lists should be merged (or perhaps it was a mistake - to make them both use a struct gdb_thread). */ - struct gdb_thread *cproc; - - /* These are for the cproc list, which is linked through the next field - of the struct gdb_thread. */ - char raw_cproc[CPROC_SIZE]; - /* The cthread which is pointed to by the incarnation field from the - cproc. This points to the copy we've read into GDB. */ - cthread_t cthread; - /* Point back to the mthreads list. */ - int reverse_map; - struct gdb_thread *next; - } - *gdb_thread_t; - -/* - * Actions for Mach exceptions. - * - * sigmap field maps the exception to corresponding Unix signal. - * - * I do not know how to map the exception to unix signal - * if SIG_UNKNOWN is specified. - */ - -struct exception_list - { - char *name; - boolean_t forward; - boolean_t print; - int sigmap; - } -exception_map[] = -{ - { - "not_mach3_exception", FALSE, TRUE, SIG_UNKNOWN - } - , - { - "EXC_BAD_ACCESS", FALSE, TRUE, SIGSEGV - } - , - { - "EXC_BAD_INSTRUCTION", FALSE, TRUE, SIGILL - } - , - { - "EXC_ARITHMETIC", FALSE, TRUE, SIGFPE - } - , - { - "EXC_EMULATION", FALSE, TRUE, SIGEMT - } - , /* ??? */ - { - "EXC_SOFTWARE", FALSE, TRUE, SIG_UNKNOWN - } - , - { - "EXC_BREAKPOINT", FALSE, FALSE, SIGTRAP - } -}; - -/* Mach exception table size */ -int max_exception = sizeof (exception_map) / sizeof (struct exception_list) - 1; - -#define MAX_EXCEPTION max_exception - -WAITTYPE wait_status; - -/* If you define this, intercepted bsd server calls will be - * dumped while waiting the inferior to EXEC the correct - * program - */ -/* #define DUMP_SYSCALL /* debugging interceptor */ - -/* xx_debug() outputs messages if this is nonzero. - * If > 1, DUMP_SYSCALL will dump message contents. - */ -int debug_level = 0; - -/* "Temporary" debug stuff */ -void -xx_debug (char *fmt, int a, int b, int c) -{ - if (debug_level) - warning (fmt, a, b, c); -} - -/* This is in libmach.a */ -extern mach_port_t name_server_port; - -/* Set in catch_exception_raise */ -int stop_exception, stop_code, stop_subcode; -int stopped_in_exception; - -/* Thread that was the active thread when we stopped */ -thread_t stop_thread = MACH_PORT_NULL; - -char *hostname = ""; - -/* Set when task is attached or created */ -boolean_t emulator_present = FALSE; - -task_t inferior_task; -thread_t current_thread; - -/* Exception ports for inferior task */ -mach_port_t inferior_exception_port = MACH_PORT_NULL; -mach_port_t inferior_old_exception_port = MACH_PORT_NULL; - -/* task exceptions and notifications */ -mach_port_t inferior_wait_port_set = MACH_PORT_NULL; -mach_port_t our_notify_port = MACH_PORT_NULL; - -/* This is "inferior_wait_port_set" when not single stepping, and - * "singlestepped_thread_port" when we are single stepping. - * - * This is protected by a cleanup function: discard_single_step() - */ -mach_port_t currently_waiting_for = MACH_PORT_NULL; - -/* A port for external messages to gdb. - * External in the meaning that they do not come - * from the inferior_task, but rather from external - * tasks. - * - * As a debugging feature: - * A debugger debugging another debugger can stop the - * inferior debugger by the following command sequence - * (without running external programs) - * - * (top-gdb) set stop_inferior_gdb () - * (top-gdb) continue - */ -mach_port_t our_message_port = MACH_PORT_NULL; - -/* For single stepping */ -mach_port_t thread_exception_port = MACH_PORT_NULL; -mach_port_t thread_saved_exception_port = MACH_PORT_NULL; -mach_port_t singlestepped_thread_port = MACH_PORT_NULL; - -/* For machid calls */ -mach_port_t mid_server = MACH_PORT_NULL; -mach_port_t mid_auth = MACH_PORT_NULL; - -/* If gdb thinks the inferior task is not suspended, it - * must take suspend/abort the threads when it reads the state. - */ -int must_suspend_thread = 0; - -/* When single stepping, we switch the port that mach_really_wait() listens to. - * This cleanup is a guard to prevent the port set from being left to - * the singlestepped_thread_port when error() is called. - * This is nonzero only when we are single stepping. - */ -#define NULL_CLEANUP (struct cleanup *)0 -struct cleanup *cleanup_step = NULL_CLEANUP; - - -static struct target_ops m3_ops; - -static void m3_kill_inferior (); - -#if 0 -#define MACH_TYPE_EXCEPTION_PORT -1 -#endif - -/* Chain of ports to remember requested notifications. */ - -struct port_chain - { - struct port_chain *next; - mach_port_t port; - int type; - int mid; /* Now only valid with MACH_TYPE_THREAD and */ - /* MACH_TYPE_THREAD */ - }; -typedef struct port_chain *port_chain_t; - -/* Room for chain nodes comes from pchain_obstack */ -struct obstack pchain_obstack; -struct obstack *port_chain_obstack = &pchain_obstack; - -/* For thread handling */ -struct obstack Cproc_obstack; -struct obstack *cproc_obstack = &Cproc_obstack; - -/* the list of notified ports */ -port_chain_t notify_chain = (port_chain_t) NULL; - -port_chain_t -port_chain_insert (port_chain_t list, mach_port_t name, int type) -{ - kern_return_t ret; - port_chain_t new; - int mid; - - if (!MACH_PORT_VALID (name)) - return list; - - if (type == MACH_TYPE_TASK || type == MACH_TYPE_THREAD) - { - if (!MACH_PORT_VALID (mid_server)) - { - warning ("Machid server port invalid, can not map port 0x%x to MID", - name); - mid = name; - } - else - { - ret = machid_mach_register (mid_server, mid_auth, name, type, &mid); - - if (ret != KERN_SUCCESS) - { - warning ("Can not map name (0x%x) to MID with machid", name); - mid = name; - } - } - } - else - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - - new = (port_chain_t) obstack_alloc (port_chain_obstack, - sizeof (struct port_chain)); - new->next = list; - new->port = name; - new->type = type; - new->mid = mid; - - return new; -} - -port_chain_t -port_chain_delete (port_chain_t list, mach_port_t elem) -{ - if (list) - if (list->port == elem) - list = list->next; - else - while (list->next) - { - if (list->next->port == elem) - list->next = list->next->next; /* GCd with obstack_free() */ - else - list = list->next; - } - return list; -} - -void -port_chain_destroy (struct obstack *ostack) -{ - obstack_free (ostack, 0); - obstack_init (ostack); -} - -port_chain_t -port_chain_member (port_chain_t list, mach_port_t elem) -{ - while (list) - { - if (list->port == elem) - return list; - list = list->next; - } - return (port_chain_t) NULL; -} - -int -map_port_name_to_mid (mach_port_t name, int type) -{ - port_chain_t elem; - - if (!MACH_PORT_VALID (name)) - return -1; - - elem = port_chain_member (notify_chain, name); - - if (elem && (elem->type == type)) - return elem->mid; - - if (elem) - return -1; - - if (!MACH_PORT_VALID (mid_server)) - { - warning ("Machid server port invalid, can not map port 0x%x to mid", - name); - return -1; - } - else - { - int mid; - kern_return_t ret; - - ret = machid_mach_register (mid_server, mid_auth, name, type, &mid); - - if (ret != KERN_SUCCESS) - { - warning ("Can not map name (0x%x) to mid with machid", name); - return -1; - } - return mid; - } -} - -/* Guard for currently_waiting_for and singlestepped_thread_port */ -static void -discard_single_step (thread_t thread) -{ - currently_waiting_for = inferior_wait_port_set; - - cleanup_step = NULL_CLEANUP; - if (MACH_PORT_VALID (thread) && MACH_PORT_VALID (singlestepped_thread_port)) - setup_single_step (thread, FALSE); -} - -setup_single_step (thread_t thread, boolean_t start_step) -{ - kern_return_t ret; - - if (!MACH_PORT_VALID (thread)) - error ("Invalid thread supplied to setup_single_step"); - else - { - mach_port_t teport; - - /* Get the current thread exception port */ - ret = thread_get_exception_port (thread, &teport); - CHK ("Getting thread's exception port", ret); - - if (start_step) - { - if (MACH_PORT_VALID (singlestepped_thread_port)) - { - warning ("Singlestepped_thread_port (0x%x) is still valid?", - singlestepped_thread_port); - singlestepped_thread_port = MACH_PORT_NULL; - } - - /* If we are already stepping this thread */ - if (MACH_PORT_VALID (teport) && teport == thread_exception_port) - { - ret = mach_port_deallocate (mach_task_self (), teport); - CHK ("Could not deallocate thread exception port", ret); - } - else - { - ret = thread_set_exception_port (thread, thread_exception_port); - CHK ("Setting exception port for thread", ret); -#if 0 - /* Insert thread exception port to wait port set */ - ret = mach_port_move_member (mach_task_self (), - thread_exception_port, - inferior_wait_port_set); - CHK ("Moving thread exception port to inferior_wait_port_set", - ret); -#endif - thread_saved_exception_port = teport; - } - - thread_trace (thread, TRUE); - - singlestepped_thread_port = thread_exception_port; - currently_waiting_for = singlestepped_thread_port; - cleanup_step = make_cleanup (discard_single_step, thread); - } - else - { - if (!MACH_PORT_VALID (teport)) - error ("Single stepped thread had an invalid exception port?"); - - if (teport != thread_exception_port) - error ("Single stepped thread had an unknown exception port?"); - - ret = mach_port_deallocate (mach_task_self (), teport); - CHK ("Couldn't deallocate thread exception port", ret); -#if 0 - /* Remove thread exception port from wait port set */ - ret = mach_port_move_member (mach_task_self (), - thread_exception_port, - MACH_PORT_NULL); - CHK ("Removing thread exception port from inferior_wait_port_set", - ret); -#endif - /* Restore thread's old exception port */ - ret = thread_set_exception_port (thread, - thread_saved_exception_port); - CHK ("Restoring stepped thread's exception port", ret); - - if (MACH_PORT_VALID (thread_saved_exception_port)) - (void) mach_port_deallocate (mach_task_self (), - thread_saved_exception_port); - - thread_trace (thread, FALSE); - - singlestepped_thread_port = MACH_PORT_NULL; - currently_waiting_for = inferior_wait_port_set; - if (cleanup_step) - discard_cleanups (cleanup_step); - } - } -} - -static -request_notify (mach_port_t name, mach_msg_id_t variant, int type) -{ - kern_return_t ret; - mach_port_t previous_port_dummy = MACH_PORT_NULL; - - if (!MACH_PORT_VALID (name)) - return; - - if (port_chain_member (notify_chain, name)) - return; - - ret = mach_port_request_notification (mach_task_self (), - name, - variant, - 1, - our_notify_port, - MACH_MSG_TYPE_MAKE_SEND_ONCE, - &previous_port_dummy); - CHK ("Serious: request_notify failed", ret); - - (void) mach_port_deallocate (mach_task_self (), - previous_port_dummy); - - notify_chain = port_chain_insert (notify_chain, name, type); -} - -reverse_msg_bits (mach_msg_header_t *msgp, int type) -{ - int rbits, lbits; - rbits = MACH_MSGH_BITS_REMOTE (msgp->msgh_bits); - lbits = type; - msgp->msgh_bits = - (msgp->msgh_bits & ~MACH_MSGH_BITS_PORTS_MASK) | - MACH_MSGH_BITS (lbits, rbits); -} - -/* On the third day He said: - - Let this be global - and then it was global. - - When creating the inferior fork, the - child code in inflow.c sets the name of the - bootstrap_port in its address space to this - variable. - - The name is transferred to our address space - with mach3_read_inferior(). - - Thou shalt not do this with - task_get_bootstrap_port() in this task, since - the name in the inferior task is different than - the one we get. - - For blessed are the meek, as they shall inherit - the address space. - */ -mach_port_t original_server_port_name = MACH_PORT_NULL; - - -/* Called from inferior after FORK but before EXEC */ -static void -m3_trace_me (void) -{ - kern_return_t ret; - - /* Get the NAME of the bootstrap port in this task - so that GDB can read it */ - ret = task_get_bootstrap_port (mach_task_self (), - &original_server_port_name); - if (ret != KERN_SUCCESS) - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - ret = mach_port_deallocate (mach_task_self (), - original_server_port_name); - if (ret != KERN_SUCCESS) - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - - /* Suspend this task to let the parent change my ports. - Resumed by the debugger */ - ret = task_suspend (mach_task_self ()); - if (ret != KERN_SUCCESS) - internal_error (__FILE__, __LINE__, "failed internal consistency check"); -} - -/* - * Intercept system calls to Unix server. - * After EXEC_COUNTER calls to exec(), return. - * - * Pre-assertion: Child is suspended. (Not verified) - * Post-condition: Child is suspended after EXEC_COUNTER exec() calls. - */ - -void -intercept_exec_calls (int exec_counter) -{ - int terminal_initted = 0; - - struct syscall_msg_t - { - mach_msg_header_t header; - mach_msg_type_t type; - char room[2000]; /* Enuff space */ - }; - - struct syscall_msg_t syscall_in, syscall_out; - - mach_port_t fake_server; - mach_port_t original_server_send; - mach_port_t original_exec_reply; - mach_port_t exec_reply; - mach_port_t exec_reply_send; - mach_msg_type_name_t acquired; - mach_port_t emulator_server_port_name; - struct task_basic_info info; - mach_msg_type_number_t info_count; - - kern_return_t ret; - - if (exec_counter <= 0) - return; /* We are already set up in the correct program */ - - ret = mach_port_allocate (mach_task_self (), - MACH_PORT_RIGHT_RECEIVE, - &fake_server); - CHK ("create inferior_fake_server port failed", ret); - - /* Wait for inferior_task to suspend itself */ - while (1) - { - info_count = sizeof (info); - ret = task_info (inferior_task, - TASK_BASIC_INFO, - (task_info_t) & info, - &info_count); - CHK ("Task info", ret); - - if (info.suspend_count) - break; - - /* Note that the definition of the parameter was undefined - * at the time of this writing, so I just use an `ad hoc' value. - */ - (void) swtch_pri (42); /* Universal Priority Value */ - } - - /* Read the inferior's bootstrap port name */ - if (!mach3_read_inferior (&original_server_port_name, - &original_server_port_name, - sizeof (original_server_port_name))) - error ("Can't read inferior task bootstrap port name"); - - /* @@ BUG: If more than 1 send right GDB will FAIL!!! */ - /* Should get refs, and set them back when restoring */ - /* Steal the original bsd server send right from inferior */ - ret = mach_port_extract_right (inferior_task, - original_server_port_name, - MACH_MSG_TYPE_MOVE_SEND, - &original_server_send, - &acquired); - CHK ("mach_port_extract_right (bsd server send)", ret); - - if (acquired != MACH_MSG_TYPE_PORT_SEND) - error ("Incorrect right extracted, send right to bsd server expected"); - - ret = mach_port_insert_right (inferior_task, - original_server_port_name, - fake_server, - MACH_MSG_TYPE_MAKE_SEND); - CHK ("mach_port_insert_right (fake server send)", ret); - - xx_debug ("inferior task bsd server ports set up \nfs %x, ospn %x, oss %x\n", - fake_server, - original_server_port_name, original_server_send); - - /* A receive right to the reply generated by unix server exec() request */ - ret = mach_port_allocate (mach_task_self (), - MACH_PORT_RIGHT_RECEIVE, - &exec_reply); - CHK ("create intercepted_reply_port port failed", ret); - - /* Pass this send right to Unix server so it replies to us after exec() */ - ret = mach_port_extract_right (mach_task_self (), - exec_reply, - MACH_MSG_TYPE_MAKE_SEND_ONCE, - &exec_reply_send, - &acquired); - CHK ("mach_port_extract_right (exec_reply)", ret); - - if (acquired != MACH_MSG_TYPE_PORT_SEND_ONCE) - error ("Incorrect right extracted, send once expected for exec reply"); - - ret = mach_port_move_member (mach_task_self (), - fake_server, - inferior_wait_port_set); - CHK ("Moving fake syscall port to inferior_wait_port_set", ret); - - xx_debug ("syscall fake server set up, resuming inferior\n"); - - ret = task_resume (inferior_task); - CHK ("task_resume (startup)", ret); - - /* Read requests from the inferior. - Pass directly through everything else except exec() calls. - */ - while (exec_counter > 0) - { - ret = mach_msg (&syscall_in.header, /* header */ - MACH_RCV_MSG, /* options */ - 0, /* send size */ - sizeof (struct syscall_msg_t), /* receive size */ - inferior_wait_port_set, /* receive_name */ - MACH_MSG_TIMEOUT_NONE, - MACH_PORT_NULL); - CHK ("mach_msg (intercepted sycall)", ret); - -#ifdef DUMP_SYSCALL - print_msg (&syscall_in.header); -#endif - - /* ASSERT : msgh_local_port == fake_server */ - - if (notify_server (&syscall_in.header, &syscall_out.header)) - error ("received a notify while intercepting syscalls"); - - if (syscall_in.header.msgh_id == MIG_EXEC_SYSCALL_ID) - { - xx_debug ("Received EXEC SYSCALL, counter = %d\n", exec_counter); - if (exec_counter == 1) - { - original_exec_reply = syscall_in.header.msgh_remote_port; - syscall_in.header.msgh_remote_port = exec_reply_send; - } - - if (!terminal_initted) - { - /* Now that the child has exec'd we know it has already set its - process group. On POSIX systems, tcsetpgrp will fail with - EPERM if we try it before the child's setpgid. */ - - /* Set up the "saved terminal modes" of the inferior - based on what modes we are starting it with. */ - target_terminal_init (); - - /* Install inferior's terminal modes. */ - target_terminal_inferior (); - - terminal_initted = 1; - } - - exec_counter--; - } - - syscall_in.header.msgh_local_port = syscall_in.header.msgh_remote_port; - syscall_in.header.msgh_remote_port = original_server_send; - - reverse_msg_bits (&syscall_in.header, MACH_MSG_TYPE_COPY_SEND); - - ret = mach_msg_send (&syscall_in.header); - CHK ("Forwarded syscall", ret); - } - - ret = mach_port_move_member (mach_task_self (), - fake_server, - MACH_PORT_NULL); - CHK ("Moving fake syscall out of inferior_wait_port_set", ret); - - ret = mach_port_move_member (mach_task_self (), - exec_reply, - inferior_wait_port_set); - CHK ("Moving exec_reply to inferior_wait_port_set", ret); - - ret = mach_msg (&syscall_in.header, /* header */ - MACH_RCV_MSG, /* options */ - 0, /* send size */ - sizeof (struct syscall_msg_t), /* receive size */ - inferior_wait_port_set, /* receive_name */ - MACH_MSG_TIMEOUT_NONE, - MACH_PORT_NULL); - CHK ("mach_msg (exec reply)", ret); - - ret = task_suspend (inferior_task); - CHK ("Suspending inferior after last exec", ret); - - must_suspend_thread = 0; - - xx_debug ("Received exec reply from bsd server, suspended inferior task\n"); - -#ifdef DUMP_SYSCALL - print_msg (&syscall_in.header); -#endif - - /* Message should appear as if it came from the unix server */ - syscall_in.header.msgh_local_port = MACH_PORT_NULL; - - /* and go to the inferior task original reply port */ - syscall_in.header.msgh_remote_port = original_exec_reply; - - reverse_msg_bits (&syscall_in.header, MACH_MSG_TYPE_MOVE_SEND_ONCE); - - ret = mach_msg_send (&syscall_in.header); - CHK ("Forwarding exec reply to inferior", ret); - - /* Garbage collect */ - ret = mach_port_deallocate (inferior_task, - original_server_port_name); - CHK ("deallocating fake server send right", ret); - - ret = mach_port_insert_right (inferior_task, - original_server_port_name, - original_server_send, - MACH_MSG_TYPE_MOVE_SEND); - CHK ("Restoring the original bsd server send right", ret); - - ret = mach_port_destroy (mach_task_self (), - fake_server); - fake_server = MACH_PORT_DEAD; - CHK ("mach_port_destroy (fake_server)", ret); - - ret = mach_port_destroy (mach_task_self (), - exec_reply); - exec_reply = MACH_PORT_DEAD; - CHK ("mach_port_destroy (exec_reply)", ret); - - xx_debug ("Done with exec call interception\n"); -} - -void -consume_send_rights (thread_array_t thread_list, int thread_count) -{ - int index; - - if (!thread_count) - return; - - for (index = 0; index < thread_count; index++) - { - /* Since thread kill command kills threads, don't check ret */ - (void) mach_port_deallocate (mach_task_self (), - thread_list[index]); - } -} - -/* suspend/abort/resume a thread. */ -setup_thread (mach_port_t thread, int what) -{ - kern_return_t ret; - - if (what) - { - ret = thread_suspend (thread); - CHK ("setup_thread thread_suspend", ret); - - ret = thread_abort (thread); - CHK ("setup_thread thread_abort", ret); - } - else - { - ret = thread_resume (thread); - CHK ("setup_thread thread_resume", ret); - } -} - -int -map_slot_to_mid (int slot, thread_array_t threads, int thread_count) -{ - kern_return_t ret; - int deallocate = 0; - int index; - int mid; - - if (!threads) - { - deallocate++; - ret = task_threads (inferior_task, &threads, &thread_count); - CHK ("Can not select a thread from a dead task", ret); - } - - if (slot < 0 || slot >= thread_count) - { - if (deallocate) - { - consume_send_rights (threads, thread_count); - (void) vm_deallocate (mach_task_self (), (vm_address_t) threads, - (thread_count * sizeof (mach_port_t))); - } - if (slot < 0) - error ("invalid slot number"); - else - return -(slot + 1); - } - - mid = map_port_name_to_mid (threads[slot], MACH_TYPE_THREAD); - - if (deallocate) - { - consume_send_rights (threads, thread_count); - (void) vm_deallocate (mach_task_self (), (vm_address_t) threads, - (thread_count * sizeof (mach_port_t))); - } - - return mid; -} - -static int -parse_thread_id (char *arg, int thread_count, int slots) -{ - kern_return_t ret; - int mid; - int slot; - int index; - - if (arg == 0) - return 0; - - while (*arg && (*arg == ' ' || *arg == '\t')) - arg++; - - if (!*arg) - return 0; - - /* Currently parse MID and @SLOTNUMBER */ - if (*arg != '@') - { - mid = atoi (arg); - if (mid <= 0) - error ("valid thread mid expected"); - return mid; - } - - arg++; - slot = atoi (arg); - - if (slot < 0) - error ("invalid slot number"); - - /* If you want slot numbers to remain slot numbers, set slots. - - * Well, since 0 is reserved, return the ordinal number - * of the thread rather than the slot number. Awk, this - * counts as a kludge. - */ - if (slots) - return -(slot + 1); - - if (thread_count && slot >= thread_count) - return -(slot + 1); - - mid = map_slot_to_mid (slot); - - return mid; -} - -/* THREAD_ID 0 is special; it selects the first kernel - * thread from the list (i.e. SLOTNUMBER 0) - * This is used when starting the program with 'run' or when attaching. - * - * If FLAG is 0 the context is not changed, and the registers, frame, etc - * will continue to describe the old thread. - * - * If FLAG is nonzero, really select the thread. - * If FLAG is 2, the THREAD_ID is a slotnumber instead of a mid. - * - */ -kern_return_t -select_thread (mach_port_t task, int thread_id, int flag) -{ - thread_array_t thread_list; - int thread_count; - kern_return_t ret; - int index; - thread_t new_thread = MACH_PORT_NULL; - - if (thread_id < 0) - error ("Can't select cprocs without kernel thread"); - - ret = task_threads (task, &thread_list, &thread_count); - if (ret != KERN_SUCCESS) - { - warning ("Can not select a thread from a dead task"); - m3_kill_inferior (); - return KERN_FAILURE; - } - - if (thread_count == 0) - { - /* The task can not do anything anymore, but it still - * exists as a container for memory and ports. - */ - registers_changed (); - warning ("Task %d has no threads", - map_port_name_to_mid (task, MACH_TYPE_TASK)); - current_thread = MACH_PORT_NULL; - (void) vm_deallocate (mach_task_self (), - (vm_address_t) thread_list, - (thread_count * sizeof (mach_port_t))); - return KERN_FAILURE; - } - - if (!thread_id || flag == 2) - { - /* First thread or a slotnumber */ - if (!thread_id) - new_thread = thread_list[0]; - else - { - if (thread_id < thread_count) - new_thread = thread_list[thread_id]; - else - { - (void) vm_deallocate (mach_task_self (), - (vm_address_t) thread_list, - (thread_count * sizeof (mach_port_t))); - error ("No such thread slot number : %d", thread_id); - } - } - } - else - { - for (index = 0; index < thread_count; index++) - if (thread_id == map_port_name_to_mid (thread_list[index], - MACH_TYPE_THREAD)) - { - new_thread = thread_list[index]; - index = -1; - break; - } - - if (index != -1) - error ("No thread with mid %d", thread_id); - } - - /* Notify when the selected thread dies */ - request_notify (new_thread, MACH_NOTIFY_DEAD_NAME, MACH_TYPE_THREAD); - - ret = vm_deallocate (mach_task_self (), - (vm_address_t) thread_list, - (thread_count * sizeof (mach_port_t))); - CHK ("vm_deallocate", ret); - - if (!flag) - current_thread = new_thread; - else - { -#if 0 - if (MACH_PORT_VALID (current_thread)) - { - /* Store the gdb's view of the thread we are deselecting - - * @@ I think gdb updates registers immediately when they are - * changed, so don't do this. - */ - ret = thread_abort (current_thread); - CHK ("Could not abort system calls when saving state of old thread", - ret); - target_prepare_to_store (); - target_store_registers (-1); - } -#endif - - registers_changed (); - - current_thread = new_thread; - - ret = thread_abort (current_thread); - CHK ("Could not abort system calls when selecting a thread", ret); - - stop_pc = read_pc (); - flush_cached_frames (); - - select_frame (get_current_frame ()); - } - - return KERN_SUCCESS; -} - -/* - * Switch to use thread named NEW_THREAD. - * Return it's MID - */ -int -switch_to_thread (thread_t new_thread) -{ - thread_t saved_thread = current_thread; - int mid; - - mid = map_port_name_to_mid (new_thread, - MACH_TYPE_THREAD); - if (mid == -1) - warning ("Can't map thread name 0x%x to mid", new_thread); - else if (select_thread (inferior_task, mid, 1) != KERN_SUCCESS) - { - if (current_thread) - current_thread = saved_thread; - error ("Could not select thread %d", mid); - } - - return mid; -} - -/* Do this in gdb after doing FORK but before STARTUP_INFERIOR. - * Note that the registers are not yet valid in the inferior task. - */ -static int -m3_trace_him (int pid) -{ - kern_return_t ret; - - push_target (&m3_ops); - - inferior_task = task_by_pid (pid); - - if (!MACH_PORT_VALID (inferior_task)) - error ("Can not map Unix pid %d to Mach task", pid); - - /* Clean up previous notifications and create new ones */ - setup_notify_port (1); - - /* When notification appears, the inferior task has died */ - request_notify (inferior_task, MACH_NOTIFY_DEAD_NAME, MACH_TYPE_TASK); - - emulator_present = have_emulator_p (inferior_task); - - /* By default, select the first thread, - * If task has no threads, gives a warning - * Does not fetch registers, since they are not yet valid. - */ - select_thread (inferior_task, 0, 0); - - inferior_exception_port = MACH_PORT_NULL; - - setup_exception_port (); - - xx_debug ("Now the debugged task is created\n"); - - /* One trap to exec the shell, one to exec the program being debugged. */ - intercept_exec_calls (2); - - return pid; -} - -setup_exception_port (void) -{ - kern_return_t ret; - - ret = mach_port_allocate (mach_task_self (), - MACH_PORT_RIGHT_RECEIVE, - &inferior_exception_port); - CHK ("mach_port_allocate", ret); - - /* add send right */ - ret = mach_port_insert_right (mach_task_self (), - inferior_exception_port, - inferior_exception_port, - MACH_MSG_TYPE_MAKE_SEND); - CHK ("mach_port_insert_right", ret); - - ret = mach_port_move_member (mach_task_self (), - inferior_exception_port, - inferior_wait_port_set); - CHK ("mach_port_move_member", ret); - - ret = task_get_special_port (inferior_task, - TASK_EXCEPTION_PORT, - &inferior_old_exception_port); - CHK ("task_get_special_port(old exc)", ret); - - ret = task_set_special_port (inferior_task, - TASK_EXCEPTION_PORT, - inferior_exception_port); - CHK ("task_set_special_port", ret); - - ret = mach_port_deallocate (mach_task_self (), - inferior_exception_port); - CHK ("mack_port_deallocate", ret); - -#if 0 - /* When notify appears, the inferior_task's exception - * port has been destroyed. - * - * Not used, since the dead_name_notification already - * appears when task dies. - * - */ - request_notify (inferior_exception_port, - MACH_NOTIFY_NO_SENDERS, - MACH_TYPE_EXCEPTION_PORT); -#endif -} - -/* Nonzero if gdb is waiting for a message */ -int mach_really_waiting; - -/* Wait for the inferior to stop for some reason. - - Loop on notifications until inferior_task dies. - - Loop on exceptions until stopped_in_exception comes true. - (e.g. we receive a single step trace trap) - - a message arrives to gdb's message port - - There is no other way to exit this loop. - - Returns the inferior_ptid for rest of gdb. - Side effects: Set *OURSTATUS. */ -ptid_t -mach_really_wait (ptid_t ptid, struct target_waitstatus *ourstatus) -{ - kern_return_t ret; - int w; - - struct msg - { - mach_msg_header_t header; - mach_msg_type_t foo; - int data[8000]; - } - in_msg, out_msg; - - /* Either notify (death), exception or message can stop the inferior */ - stopped_in_exception = FALSE; - - while (1) - { - QUIT; - - stop_exception = stop_code = stop_subcode = -1; - stop_thread = MACH_PORT_NULL; - - mach_really_waiting = 1; - ret = mach_msg (&in_msg.header, /* header */ - MACH_RCV_MSG, /* options */ - 0, /* send size */ - sizeof (struct msg), /* receive size */ - currently_waiting_for, /* receive name */ - MACH_MSG_TIMEOUT_NONE, - MACH_PORT_NULL); - mach_really_waiting = 0; - CHK ("mach_msg (receive)", ret); - - /* Check if we received a notify of the childs' death */ - if (notify_server (&in_msg.header, &out_msg.header)) - { - /* If inferior_task is null then the inferior has - gone away and we want to return to command level. - Otherwise it was just an informative message and we - need to look to see if there are any more. */ - if (inferior_task != MACH_PORT_NULL) - continue; - else - { - /* Collect Unix exit status for gdb */ - - wait3 (&w, WNOHANG, 0); - - /* This mess is here to check that the rest of - * gdb knows that the inferior died. It also - * tries to hack around the fact that Mach 3.0 (mk69) - * unix server (ux28) does not always know what - * has happened to it's children when mach-magic - * is applied on them. - */ - if ((!WIFEXITED (w) && WIFSTOPPED (w)) || - (WIFEXITED (w) && WEXITSTATUS (w) > 0377)) - { - WSETEXIT (w, 0); - warning ("Using exit value 0 for terminated task"); - } - else if (!WIFEXITED (w)) - { - int sig = WTERMSIG (w); - - /* Signals cause problems. Warn the user. */ - if (sig != SIGKILL) /* Bad luck if garbage matches this */ - warning ("The terminating signal stuff may be nonsense"); - else if (sig > NSIG) - { - WSETEXIT (w, 0); - warning ("Using exit value 0 for terminated task"); - } - } - store_waitstatus (ourstatus, w); - return inferior_ptid; - } - } - - /* Hmm. Check for exception, as it was not a notification. - exc_server() does an upcall to catch_exception_raise() - if this rpc is an exception. Further actions are decided - there. - */ - if (!exc_server (&in_msg.header, &out_msg.header)) - { - - /* Not an exception, check for message. - - * Messages don't come from the inferior, or if they - * do they better be asynchronous or it will hang. - */ - if (gdb_message_server (&in_msg.header)) - continue; - - error ("Unrecognized message received in mach_really_wait"); - } - - /* Send the reply of the exception rpc to the suspended task */ - ret = mach_msg_send (&out_msg.header); - CHK ("mach_msg_send (exc reply)", ret); - - if (stopped_in_exception) - { - /* Get unix state. May be changed in mach3_exception_actions() */ - wait3 (&w, WNOHANG, 0); - - mach3_exception_actions (&w, FALSE, "Task"); - - store_waitstatus (ourstatus, w); - return inferior_ptid; - } - } -} - -/* Called by macro DO_QUIT() in utils.c(quit). - * This is called just before calling error() to return to command level - */ -void -mach3_quit (void) -{ - int mid; - kern_return_t ret; - - if (mach_really_waiting) - { - ret = task_suspend (inferior_task); - - if (ret != KERN_SUCCESS) - { - warning ("Could not suspend task for interrupt: %s", - mach_error_string (ret)); - mach_really_waiting = 0; - return; - } - } - - must_suspend_thread = 0; - mach_really_waiting = 0; - - mid = map_port_name_to_mid (current_thread, MACH_TYPE_THREAD); - if (mid == -1) - { - warning ("Selecting first existing kernel thread"); - mid = 0; - } - - current_thread = MACH_PORT_NULL; /* Force setup */ - select_thread (inferior_task, mid, 1); - - return; -} - -#if 0 -/* bogus bogus bogus. It is NOT OK to quit out of target_wait. */ - -/* If ^C is typed when we are waiting for a message - * and your Unix server is able to notice that we - * should quit now. - * - * Called by REQUEST_QUIT() from utils.c(request_quit) - */ -void -mach3_request_quit (void) -{ - if (mach_really_waiting) - immediate_quit = 1; -} -#endif - -/* - * Gdb message server. - * Currently implemented is the STOP message, that causes - * gdb to return to the command level like ^C had been typed from terminal. - */ -int -gdb_message_server (mach_msg_header_t *InP) -{ - kern_return_t ret; - int mid; - - if (InP->msgh_local_port == our_message_port) - { - /* A message coming to our_message_port. Check validity */ - switch (InP->msgh_id) - { - - case GDB_MESSAGE_ID_STOP: - ret = task_suspend (inferior_task); - if (ret != KERN_SUCCESS) - warning ("Could not suspend task for stop message: %s", - mach_error_string (ret)); - - /* QUIT in mach_really_wait() loop. */ - request_quit (0); - break; - - default: - warning ("Invalid message id %d received, ignored.", - InP->msgh_id); - break; - } - - return 1; - } - - /* Message not handled by this server */ - return 0; -} - -/* NOTE: This is not an RPC call. It is a simpleroutine. - - * This is not called from this gdb code. - * - * It may be called by another debugger to cause this - * debugger to enter command level: - * - * (gdb) set stop_inferior_gdb () - * (gdb) continue - * - * External program "stop-gdb" implements this also. - */ -void -stop_inferior_gdb (void) -{ - kern_return_t ret; - - /* Code generated by mig, with minor cleanups :-) - - * simpleroutine stop_inferior_gdb (our_message_port : mach_port_t); - */ - - typedef struct - { - mach_msg_header_t Head; - } - Request; - - Request Mess; - - register Request *InP = &Mess; - - InP->Head.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, 0); - - /* msgh_size passed as argument */ - InP->Head.msgh_remote_port = our_message_port; - InP->Head.msgh_local_port = MACH_PORT_NULL; - InP->Head.msgh_seqno = 0; - InP->Head.msgh_id = GDB_MESSAGE_ID_STOP; - - ret = mach_msg (&InP->Head, - MACH_SEND_MSG | MACH_MSG_OPTION_NONE, - sizeof (Request), - 0, - MACH_PORT_NULL, - MACH_MSG_TIMEOUT_NONE, - MACH_PORT_NULL); -} - -#ifdef THREAD_ALLOWED_TO_BREAK -/* - * Return 1 if the MID specifies the thread that caused the - * last exception. - * Since catch_exception_raise() selects the thread causing - * the last exception to current_thread, we just check that - * it is selected and the last exception was a breakpoint. - */ -int -mach_thread_for_breakpoint (int mid) -{ - int cmid = map_port_name_to_mid (current_thread, MACH_TYPE_THREAD); - - if (mid < 0) - { - mid = map_slot_to_mid (-(mid + 1), 0, 0); - if (mid < 0) - return 0; /* Don't stop, no such slot */ - } - - if (!mid || cmid == -1) - return 1; /* stop */ - - return cmid == mid && stop_exception == EXC_BREAKPOINT; -} -#endif /* THREAD_ALLOWED_TO_BREAK */ - -#ifdef THREAD_PARSE_ID -/* - * Map a thread id string (MID or a @SLOTNUMBER) - * to a thread-id. - * - * 0 matches all threads. - * Otherwise the meaning is defined only in this file. - * (mach_thread_for_breakpoint uses it) - * - * @@ This allows non-existent MIDs to be specified. - * It now also allows non-existent slots to be - * specified. (Slot numbers stored are negative, - * and the magnitude is one greater than the actual - * slot index. (Since 0 is reserved)) - */ -int -mach_thread_parse_id (char *arg) -{ - int mid; - if (arg == 0) - error ("thread id expected"); - mid = parse_thread_id (arg, 0, 1); - - return mid; -} -#endif /* THREAD_PARSE_ID */ - -#ifdef THREAD_OUTPUT_ID -char * -mach_thread_output_id (int mid) -{ - static char foobar[20]; - - if (mid > 0) - sprintf (foobar, "mid %d", mid); - else if (mid < 0) - sprintf (foobar, "@%d", -(mid + 1)); - else - sprintf (foobar, "*any thread*"); - - return foobar; -} -#endif /* THREAD_OUTPUT_ID */ - -/* Called with hook PREPARE_TO_PROCEED() from infrun.c. - - * If we have switched threads and stopped at breakpoint return 1 otherwise 0. - * - * if SELECT_IT is nonzero, reselect the thread that was active when - * we stopped at a breakpoint. - * - * Note that this implementation is potentially redundant now that - * default_prepare_to_proceed() has been added. - * - * FIXME This may not support switching threads after Ctrl-C - * correctly. The default implementation does support this. - */ - -mach3_prepare_to_proceed (int select_it) -{ - if (stop_thread && - stop_thread != current_thread && - stop_exception == EXC_BREAKPOINT) - { - int mid; - - if (!select_it) - return 1; - - mid = switch_to_thread (stop_thread); - - return 1; - } - - return 0; -} - -/* this stuff here is an upcall via libmach/excServer.c - and mach_really_wait which does the actual upcall. - - The code will pass the exception to the inferior if: - - - The task that signaled is not the inferior task - (e.g. when debugging another debugger) - - - The user has explicitely requested to pass on the exceptions. - (e.g to the default unix exception handler, which maps - exceptions to signals, or the user has her own exception handler) - - - If the thread that signaled is being single-stepped and it - has set it's own exception port and the exception is not - EXC_BREAKPOINT. (Maybe this is not desirable?) - */ - -kern_return_t -catch_exception_raise (mach_port_t port, thread_t thread, task_t task, - int exception, int code, int subcode) -{ - kern_return_t ret; - boolean_t signal_thread; - int mid = map_port_name_to_mid (thread, MACH_TYPE_THREAD); - - if (!MACH_PORT_VALID (thread)) - { - /* If the exception was sent and thread dies before we - receive it, THREAD will be MACH_PORT_DEAD - */ - - current_thread = thread = MACH_PORT_NULL; - error ("Received exception from nonexistent thread"); - } - - /* Check if the task died in transit. - * @@ Isn't the thread also invalid in such case? - */ - if (!MACH_PORT_VALID (task)) - { - current_thread = thread = MACH_PORT_NULL; - error ("Received exception from nonexistent task"); - } - - if (exception < 0 || exception > MAX_EXCEPTION) - internal_error (__FILE__, __LINE__, - "catch_exception_raise: unknown exception code %d thread %d", - exception, - mid); - - if (!MACH_PORT_VALID (inferior_task)) - error ("got an exception, but inferior_task is null or dead"); - - stop_exception = exception; - stop_code = code; - stop_subcode = subcode; - stop_thread = thread; - - signal_thread = exception != EXC_BREAKPOINT && - port == singlestepped_thread_port && - MACH_PORT_VALID (thread_saved_exception_port); - - /* If it was not our inferior or if we want to forward - * the exception to the inferior's handler, do it here - * - * Note: If you have forwarded EXC_BREAKPOINT I trust you know why. - */ - if (task != inferior_task || - signal_thread || - exception_map[exception].forward) - { - mach_port_t eport = inferior_old_exception_port; - - if (signal_thread) - { - /* - GDB now forwards the exeption to thread's original handler, - since the user propably knows what he is doing. - Give a message, though. - */ - - mach3_exception_actions ((WAITTYPE *) NULL, TRUE, "Thread"); - eport = thread_saved_exception_port; - } - - /* Send the exception to the original handler */ - ret = exception_raise (eport, - thread, - task, - exception, - code, - subcode); - - (void) mach_port_deallocate (mach_task_self (), task); - (void) mach_port_deallocate (mach_task_self (), thread); - - /* If we come here, we don't want to trace any more, since we - * will never stop for tracing anyway. - */ - discard_single_step (thread); - - /* Do not stop the inferior */ - return ret; - } - - /* Now gdb handles the exception */ - stopped_in_exception = TRUE; - - ret = task_suspend (task); - CHK ("Error suspending inferior after exception", ret); - - must_suspend_thread = 0; - - if (current_thread != thread) - { - if (MACH_PORT_VALID (singlestepped_thread_port)) - /* Cleanup discards single stepping */ - error ("Exception from thread %d while singlestepping thread %d", - mid, - map_port_name_to_mid (current_thread, MACH_TYPE_THREAD)); - - /* Then select the thread that caused the exception */ - if (select_thread (inferior_task, mid, 0) != KERN_SUCCESS) - error ("Could not select thread %d causing exception", mid); - else - warning ("Gdb selected thread %d", mid); - } - - /* If we receive an exception that is not breakpoint - * exception, we interrupt the single step and return to - * debugger. Trace condition is cleared. - */ - if (MACH_PORT_VALID (singlestepped_thread_port)) - { - if (stop_exception != EXC_BREAKPOINT) - warning ("Single step interrupted by exception"); - else if (port == singlestepped_thread_port) - { - /* Single step exception occurred, remove trace bit - * and return to gdb. - */ - if (!MACH_PORT_VALID (current_thread)) - error ("Single stepped thread is not valid"); - - /* Resume threads, but leave the task suspended */ - resume_all_threads (0); - } - else - warning ("Breakpoint while single stepping?"); - - discard_single_step (current_thread); - } - - (void) mach_port_deallocate (mach_task_self (), task); - (void) mach_port_deallocate (mach_task_self (), thread); - - return KERN_SUCCESS; -} - -int -port_valid (mach_port_t port, int mask) -{ - kern_return_t ret; - mach_port_type_t type; - - ret = mach_port_type (mach_task_self (), - port, - &type); - if (ret != KERN_SUCCESS || (type & mask) != mask) - return 0; - return 1; -} - -/* @@ No vm read cache implemented yet */ -boolean_t vm_read_cache_valid = FALSE; - -/* - * Read inferior task's LEN bytes from ADDR and copy it to MYADDR - * in gdb's address space. - * - * Return 0 on failure; number of bytes read otherwise. - */ -int -mach3_read_inferior (CORE_ADDR addr, char *myaddr, int length) -{ - kern_return_t ret; - vm_address_t low_address = (vm_address_t) trunc_page (addr); - vm_size_t aligned_length = - (vm_size_t) round_page (addr + length) - low_address; - pointer_t copied_memory; - int copy_count; - - /* Get memory from inferior with page aligned addresses */ - ret = vm_read (inferior_task, - low_address, - aligned_length, - &copied_memory, - ©_count); - if (ret != KERN_SUCCESS) - { - /* the problem is that the inferior might be killed for whatever reason - * before we go to mach_really_wait. This is one place that ought to - * catch many of those errors. - * @@ A better fix would be to make all external events to GDB - * to arrive via a SINGLE port set. (Including user input!) - */ - - if (!port_valid (inferior_task, MACH_PORT_TYPE_SEND)) - { - m3_kill_inferior (); - error ("Inferior killed (task port invalid)"); - } - else - { -#ifdef OSF - extern int errno; - /* valprint.c gives nicer format if this does not - screw it. Eamonn seems to like this, so I enable - it if OSF is defined... - */ - warning ("[read inferior %x failed: %s]", - addr, mach_error_string (ret)); - errno = 0; -#endif - return 0; - } - } - - memcpy (myaddr, (char *) addr - low_address + copied_memory, length); - - ret = vm_deallocate (mach_task_self (), - copied_memory, - copy_count); - CHK ("mach3_read_inferior vm_deallocate failed", ret); - - return length; -} - -#define CHK_GOTO_OUT(str,ret) \ - do if (ret != KERN_SUCCESS) { errstr = #str; goto out; } while(0) - -struct vm_region_list -{ - struct vm_region_list *next; - vm_prot_t protection; - vm_address_t start; - vm_size_t length; -}; - -struct obstack region_obstack; - -/* - * Write inferior task's LEN bytes from ADDR and copy it to MYADDR - * in gdb's address space. - */ -int -mach3_write_inferior (CORE_ADDR addr, char *myaddr, int length) -{ - kern_return_t ret; - vm_address_t low_address = (vm_address_t) trunc_page (addr); - vm_size_t aligned_length = - (vm_size_t) round_page (addr + length) - low_address; - pointer_t copied_memory; - int copy_count; - int deallocate = 0; - - char *errstr = "Bug in mach3_write_inferior"; - - struct vm_region_list *region_element; - struct vm_region_list *region_head = (struct vm_region_list *) NULL; - - /* Get memory from inferior with page aligned addresses */ - ret = vm_read (inferior_task, - low_address, - aligned_length, - &copied_memory, - ©_count); - CHK_GOTO_OUT ("mach3_write_inferior vm_read failed", ret); - - deallocate++; - - memcpy ((char *) addr - low_address + copied_memory, myaddr, length); - - obstack_init (®ion_obstack); - - /* Do writes atomically. - * First check for holes and unwritable memory. - */ - { - vm_size_t remaining_length = aligned_length; - vm_address_t region_address = low_address; - - struct vm_region_list *scan; - - while (region_address < low_address + aligned_length) - { - vm_prot_t protection; - vm_prot_t max_protection; - vm_inherit_t inheritance; - boolean_t shared; - mach_port_t object_name; - vm_offset_t offset; - vm_size_t region_length = remaining_length; - vm_address_t old_address = region_address; - - ret = vm_region (inferior_task, - ®ion_address, - ®ion_length, - &protection, - &max_protection, - &inheritance, - &shared, - &object_name, - &offset); - CHK_GOTO_OUT ("vm_region failed", ret); - - /* Check for holes in memory */ - if (old_address != region_address) - { - warning ("No memory at 0x%x. Nothing written", - old_address); - ret = KERN_SUCCESS; - length = 0; - goto out; - } - - if (!(max_protection & VM_PROT_WRITE)) - { - warning ("Memory at address 0x%x is unwritable. Nothing written", - old_address); - ret = KERN_SUCCESS; - length = 0; - goto out; - } - - /* Chain the regions for later use */ - region_element = - (struct vm_region_list *) - obstack_alloc (®ion_obstack, sizeof (struct vm_region_list)); - - region_element->protection = protection; - region_element->start = region_address; - region_element->length = region_length; - - /* Chain the regions along with protections */ - region_element->next = region_head; - region_head = region_element; - - region_address += region_length; - remaining_length = remaining_length - region_length; - } - - /* If things fail after this, we give up. - * Somebody is messing up inferior_task's mappings. - */ - - /* Enable writes to the chained vm regions */ - for (scan = region_head; scan; scan = scan->next) - { - boolean_t protection_changed = FALSE; - - if (!(scan->protection & VM_PROT_WRITE)) - { - ret = vm_protect (inferior_task, - scan->start, - scan->length, - FALSE, - scan->protection | VM_PROT_WRITE); - CHK_GOTO_OUT ("vm_protect: enable write failed", ret); - } - } - - ret = vm_write (inferior_task, - low_address, - copied_memory, - aligned_length); - CHK_GOTO_OUT ("vm_write failed", ret); - - /* Set up the original region protections, if they were changed */ - for (scan = region_head; scan; scan = scan->next) - { - boolean_t protection_changed = FALSE; - - if (!(scan->protection & VM_PROT_WRITE)) - { - ret = vm_protect (inferior_task, - scan->start, - scan->length, - FALSE, - scan->protection); - CHK_GOTO_OUT ("vm_protect: enable write failed", ret); - } - } - } - -out: - if (deallocate) - { - obstack_free (®ion_obstack, 0); - - (void) vm_deallocate (mach_task_self (), - copied_memory, - copy_count); - } - - if (ret != KERN_SUCCESS) - { - warning ("%s %s", errstr, mach_error_string (ret)); - return 0; - } - - return length; -} - -/* Return 0 on failure, number of bytes handled otherwise. TARGET is - ignored. */ -static int -m3_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, - struct target_ops *target) -{ - int result; - - if (write) - result = mach3_write_inferior (memaddr, myaddr, len); - else - result = mach3_read_inferior (memaddr, myaddr, len); - - return result; -} - - -static char * -translate_state (int state) -{ - switch (state) - { - case TH_STATE_RUNNING: - return ("R"); - case TH_STATE_STOPPED: - return ("S"); - case TH_STATE_WAITING: - return ("W"); - case TH_STATE_UNINTERRUPTIBLE: - return ("U"); - case TH_STATE_HALTED: - return ("H"); - default: - return ("?"); - } -} - -static char * -translate_cstate (int state) -{ - switch (state) - { - case CPROC_RUNNING: - return "R"; - case CPROC_SWITCHING: - return "S"; - case CPROC_BLOCKED: - return "B"; - case CPROC_CONDWAIT: - return "C"; - case CPROC_CONDWAIT | CPROC_SWITCHING: - return "CS"; - default: - return "?"; - } -} - -/* type == MACH_MSG_TYPE_COPY_SEND || type == MACH_MSG_TYPE_MAKE_SEND */ - -mach_port_t /* no mach_port_name_t found in include files. */ -map_inferior_port_name (mach_port_t inferior_name, mach_msg_type_name_t type) -{ - kern_return_t ret; - mach_msg_type_name_t acquired; - mach_port_t iport; - - ret = mach_port_extract_right (inferior_task, - inferior_name, - type, - &iport, - &acquired); - CHK ("mach_port_extract_right (map_inferior_port_name)", ret); - - if (acquired != MACH_MSG_TYPE_PORT_SEND) - error ("Incorrect right extracted, (map_inferior_port_name)"); - - ret = mach_port_deallocate (mach_task_self (), - iport); - CHK ("Deallocating mapped port (map_inferior_port_name)", ret); - - return iport; -} - -/* - * Naming convention: - * Always return user defined name if found. - * _K == A kernel thread with no matching CPROC - * _C == A cproc with no current cthread - * _t == A cthread with no user defined name - * - * The digits that follow the _names are the SLOT number of the - * kernel thread if there is such a thing, otherwise just a negation - * of the sequential number of such cprocs. - */ - -static char buf[7]; - -static char * -get_thread_name (gdb_thread_t one_cproc, int id) -{ - if (one_cproc) - if (one_cproc->cthread == NULL) - { - /* cproc not mapped to any cthread */ - sprintf (buf, "_C%d", id); - } - else if (!one_cproc->cthread->name) - { - /* cproc and cthread, but no name */ - sprintf (buf, "_t%d", id); - } - else - return (char *) (one_cproc->cthread->name); - else - { - if (id < 0) - warning ("Inconsistency in thread name id %d", id); - - /* Kernel thread without cproc */ - sprintf (buf, "_K%d", id); - } - - return buf; -} - -int -fetch_thread_info (mach_port_t task, gdb_thread_t *mthreads_out) -{ - kern_return_t ret; - thread_array_t th_table; - int th_count; - gdb_thread_t mthreads = NULL; - int index; - - ret = task_threads (task, &th_table, &th_count); - if (ret != KERN_SUCCESS) - { - warning ("Error getting inferior's thread list:%s", - mach_error_string (ret)); - m3_kill_inferior (); - return -1; - } - - mthreads = (gdb_thread_t) - obstack_alloc - (cproc_obstack, - th_count * sizeof (struct gdb_thread)); - - for (index = 0; index < th_count; index++) - { - thread_t saved_thread = MACH_PORT_NULL; - int mid; - - if (must_suspend_thread) - setup_thread (th_table[index], 1); - - if (th_table[index] != current_thread) - { - saved_thread = current_thread; - - mid = switch_to_thread (th_table[index]); - } - - mthreads[index].name = th_table[index]; - mthreads[index].cproc = NULL; /* map_cprocs_to_kernel_threads() */ - mthreads[index].in_emulator = FALSE; - mthreads[index].slotid = index; - - mthreads[index].sp = read_register (SP_REGNUM); - mthreads[index].fp = read_register (FP_REGNUM); - mthreads[index].pc = read_pc (); - - if (MACH_PORT_VALID (saved_thread)) - mid = switch_to_thread (saved_thread); - - if (must_suspend_thread) - setup_thread (th_table[index], 0); - } - - consume_send_rights (th_table, th_count); - ret = vm_deallocate (mach_task_self (), (vm_address_t) th_table, - (th_count * sizeof (mach_port_t))); - if (ret != KERN_SUCCESS) - { - warning ("Error trying to deallocate thread list : %s", - mach_error_string (ret)); - } - - *mthreads_out = mthreads; - - return th_count; -} - - -/* - * Current emulator always saves the USP on top of - * emulator stack below struct emul_stack_top stuff. - */ -CORE_ADDR -fetch_usp_from_emulator_stack (CORE_ADDR sp) -{ - CORE_ADDR stack_pointer; - - sp = (sp & ~(EMULATOR_STACK_SIZE - 1)) + - EMULATOR_STACK_SIZE - sizeof (struct emul_stack_top); - - if (mach3_read_inferior (sp, - &stack_pointer, - sizeof (CORE_ADDR)) != sizeof (CORE_ADDR)) - { - warning ("Can't read user sp from emulator stack address 0x%x", sp); - return 0; - } - - return stack_pointer; -} - -#ifdef MK67 - -/* get_emulation_vector() interface was changed after mk67 */ -#define EMUL_VECTOR_COUNT 400 /* Value does not matter too much */ - -#endif /* MK67 */ - -/* Check if the emulator exists at task's address space. - */ -boolean_t -have_emulator_p (task_t task) -{ - kern_return_t ret; -#ifndef EMUL_VECTOR_COUNT - vm_offset_t *emulation_vector; - int n; -#else - vm_offset_t emulation_vector[EMUL_VECTOR_COUNT]; - int n = EMUL_VECTOR_COUNT; -#endif - int i; - int vector_start; - - ret = task_get_emulation_vector (task, - &vector_start, -#ifndef EMUL_VECTOR_COUNT - &emulation_vector, -#else - emulation_vector, -#endif - &n); - CHK ("task_get_emulation_vector", ret); - xx_debug ("%d vectors from %d at 0x%08x\n", - n, vector_start, emulation_vector); - - for (i = 0; i < n; i++) - { - vm_offset_t entry = emulation_vector[i]; - - if (EMULATOR_BASE <= entry && entry <= EMULATOR_END) - return TRUE; - else if (entry) - { - static boolean_t informed = FALSE; - if (!informed) - { - warning ("Emulation vector address 0x08%x outside emulator space", - entry); - informed = TRUE; - } - } - } - return FALSE; -} - -/* Map cprocs to kernel threads and vice versa. */ - -void -map_cprocs_to_kernel_threads (gdb_thread_t cprocs, gdb_thread_t mthreads, - int thread_count) -{ - int index; - gdb_thread_t scan; - boolean_t all_mapped = TRUE; - LONGEST stack_base; - LONGEST stack_size; - - for (scan = cprocs; scan; scan = scan->next) - { - /* Default to: no kernel thread for this cproc */ - scan->reverse_map = -1; - - /* Check if the cproc is found by its stack */ - for (index = 0; index < thread_count; index++) - { - stack_base = - extract_signed_integer (scan->raw_cproc + CPROC_BASE_OFFSET, - CPROC_BASE_SIZE); - stack_size = - extract_signed_integer (scan->raw_cproc + CPROC_SIZE_OFFSET, - CPROC_SIZE_SIZE); - if ((mthreads + index)->sp > stack_base && - (mthreads + index)->sp <= stack_base + stack_size) - { - (mthreads + index)->cproc = scan; - scan->reverse_map = index; - break; - } - } - all_mapped &= (scan->reverse_map != -1); - } - - /* Check for threads that are currently in the emulator. - * If so, they have a different stack, and the still unmapped - * cprocs may well get mapped to these threads. - * - * If: - * - cproc stack does not match any kernel thread stack pointer - * - there is at least one extra kernel thread - * that has no cproc mapped above. - * - some kernel thread stack pointer points to emulator space - * then we find the user stack pointer saved in the emulator - * stack, and try to map that to the cprocs. - * - * Also set in_emulator for kernel threads. - */ - - if (emulator_present) - { - for (index = 0; index < thread_count; index++) - { - CORE_ADDR emul_sp; - CORE_ADDR usp; - - gdb_thread_t mthread = (mthreads + index); - emul_sp = mthread->sp; - - if (mthread->cproc == NULL && - EMULATOR_BASE <= emul_sp && emul_sp <= EMULATOR_END) - { - mthread->in_emulator = emulator_present; - - if (!all_mapped && cprocs) - { - usp = fetch_usp_from_emulator_stack (emul_sp); - - /* @@ Could be more accurate */ - if (!usp) - error ("Zero stack pointer read from emulator?"); - - /* Try to match this stack pointer to the cprocs that - * don't yet have a kernel thread. - */ - for (scan = cprocs; scan; scan = scan->next) - { - - /* Check is this unmapped CPROC stack contains - * the user stack pointer saved in the - * emulator. - */ - if (scan->reverse_map == -1) - { - stack_base = - extract_signed_integer - (scan->raw_cproc + CPROC_BASE_OFFSET, - CPROC_BASE_SIZE); - stack_size = - extract_signed_integer - (scan->raw_cproc + CPROC_SIZE_OFFSET, - CPROC_SIZE_SIZE); - if (usp > stack_base && - usp <= stack_base + stack_size) - { - mthread->cproc = scan; - scan->reverse_map = index; - break; - } - } - } - } - } - } - } -} - -/* - * Format of the thread_list command - * - * slot mid sel name emul ks susp cstate wired address - */ -#define TL_FORMAT "%-2.2s %5d%c %-10.10s %1.1s%s%-5.5s %-2.2s %-5.5s " - -#define TL_HEADER "\n@ MID Name KState CState Where\n" - -void -print_tl_address (struct ui_file *stream, CORE_ADDR pc) -{ - if (!lookup_minimal_symbol_by_pc (pc)) - fprintf_filtered (stream, local_hex_format (), pc); - else - { - extern int addressprint; - extern int asm_demangle; - - int store = addressprint; - addressprint = 0; - print_address_symbolic (pc, stream, asm_demangle, ""); - addressprint = store; - } -} - -/* For thread names, but also for gdb_message_port external name */ -#define MAX_NAME_LEN 50 - -/* Returns the address of variable NAME or 0 if not found */ -CORE_ADDR -lookup_address_of_variable (char *name) -{ - struct symbol *sym; - CORE_ADDR symaddr = 0; - struct minimal_symbol *msymbol; - - sym = lookup_symbol (name, - (struct block *) NULL, - VAR_NAMESPACE, - (int *) NULL, - (struct symtab **) NULL); - - if (sym) - symaddr = SYMBOL_VALUE (sym); - - if (!symaddr) - { - msymbol = lookup_minimal_symbol (name, NULL, NULL); - - if (msymbol && msymbol->type == mst_data) - symaddr = SYMBOL_VALUE_ADDRESS (msymbol); - } - - return symaddr; -} - -static gdb_thread_t -get_cprocs (void) -{ - gdb_thread_t cproc_head; - gdb_thread_t cproc_copy; - CORE_ADDR their_cprocs; - char *buf; - char *name; - cthread_t cthread; - CORE_ADDR symaddr; - - buf = alloca (TARGET_PTR_BIT / HOST_CHAR_BIT); - symaddr = lookup_address_of_variable ("cproc_list"); - - if (!symaddr) - { - /* cproc_list is not in a file compiled with debugging - symbols, but don't give up yet */ - - symaddr = lookup_address_of_variable ("cprocs"); - - if (symaddr) - { - static int informed = 0; - if (!informed) - { - informed++; - warning ("Your program is loaded with an old threads library."); - warning ("GDB does not know the old form of threads"); - warning ("so things may not work."); - } - } - } - - /* Stripped or no -lthreads loaded or "cproc_list" is in wrong segment. */ - if (!symaddr) - return NULL; - - /* Get the address of the first cproc in the task */ - if (!mach3_read_inferior (symaddr, - buf, - TARGET_PTR_BIT / HOST_CHAR_BIT)) - error ("Can't read cproc master list at address (0x%x).", symaddr); - their_cprocs = extract_address (buf, TARGET_PTR_BIT / HOST_CHAR_BIT); - - /* Scan the CPROCs in the task. - CPROCs are chained with LIST field, not NEXT field, which - chains mutexes, condition variables and queues */ - - cproc_head = NULL; - - while (their_cprocs != (CORE_ADDR) 0) - { - CORE_ADDR cproc_copy_incarnation; - cproc_copy = (gdb_thread_t) obstack_alloc (cproc_obstack, - sizeof (struct gdb_thread)); - - if (!mach3_read_inferior (their_cprocs, - &cproc_copy->raw_cproc[0], - CPROC_SIZE)) - error ("Can't read next cproc at 0x%x.", their_cprocs); - - their_cprocs = - extract_address (cproc_copy->raw_cproc + CPROC_LIST_OFFSET, - CPROC_LIST_SIZE); - cproc_copy_incarnation = - extract_address (cproc_copy->raw_cproc + CPROC_INCARNATION_OFFSET, - CPROC_INCARNATION_SIZE); - - if (cproc_copy_incarnation == (CORE_ADDR) 0) - cproc_copy->cthread = NULL; - else - { - /* This CPROC has an attached CTHREAD. Get its name */ - cthread = (cthread_t) obstack_alloc (cproc_obstack, - sizeof (struct cthread)); - - if (!mach3_read_inferior (cproc_copy_incarnation, - cthread, - sizeof (struct cthread))) - error ("Can't read next thread at 0x%x.", - cproc_copy_incarnation); - - cproc_copy->cthread = cthread; - - if (cthread->name) - { - name = (char *) obstack_alloc (cproc_obstack, MAX_NAME_LEN); - - if (!mach3_read_inferior (cthread->name, name, MAX_NAME_LEN)) - error ("Can't read next thread's name at 0x%x.", cthread->name); - - cthread->name = name; - } - } - - /* insert in front */ - cproc_copy->next = cproc_head; - cproc_head = cproc_copy; - } - return cproc_head; -} - -#ifndef FETCH_CPROC_STATE -/* - * Check if your machine does not grok the way this routine - * fetches the FP,PC and SP of a cproc that is not - * currently attached to any kernel thread (e.g. its cproc.context - * field points to the place in stack where the context - * is saved). - * - * If it doesn't, define your own routine. - */ -#define FETCH_CPROC_STATE(mth) mach3_cproc_state (mth) - -int -mach3_cproc_state (gdb_thread_t mthread) -{ - int context; - - if (!mthread || !mthread->cproc) - return -1; - - context = extract_signed_integer - (mthread->cproc->raw_cproc + CPROC_CONTEXT_OFFSET, - CPROC_CONTEXT_SIZE); - if (context == 0) - return -1; - - mthread->sp = context + MACHINE_CPROC_SP_OFFSET; - - if (mach3_read_inferior (context + MACHINE_CPROC_PC_OFFSET, - &mthread->pc, - sizeof (CORE_ADDR)) != sizeof (CORE_ADDR)) - { - warning ("Can't read cproc pc from inferior"); - return -1; - } - - if (mach3_read_inferior (context + MACHINE_CPROC_FP_OFFSET, - &mthread->fp, - sizeof (CORE_ADDR)) != sizeof (CORE_ADDR)) - { - warning ("Can't read cproc fp from inferior"); - return -1; - } - - return 0; -} -#endif /* FETCH_CPROC_STATE */ - - -void -thread_list_command (void) -{ - thread_basic_info_data_t ths; - int thread_count; - gdb_thread_t cprocs; - gdb_thread_t scan; - int index; - char *name; - char selected; - char *wired; - int infoCnt; - kern_return_t ret; - mach_port_t mid_or_port; - gdb_thread_t their_threads; - gdb_thread_t kthread; - - int neworder = 1; - - char *fmt = "There are %d kernel threads in task %d.\n"; - - int tmid = map_port_name_to_mid (inferior_task, MACH_TYPE_TASK); - - MACH_ERROR_NO_INFERIOR; - - thread_count = fetch_thread_info (inferior_task, - &their_threads); - if (thread_count == -1) - return; - - if (thread_count == 1) - fmt = "There is %d kernel thread in task %d.\n"; - - printf_filtered (fmt, thread_count, tmid); - - puts_filtered (TL_HEADER); - - cprocs = get_cprocs (); - - map_cprocs_to_kernel_threads (cprocs, their_threads, thread_count); - - for (scan = cprocs; scan; scan = scan->next) - { - int mid; - char buf[10]; - char slot[3]; - int cproc_state = - extract_signed_integer - (scan->raw_cproc + CPROC_STATE_OFFSET, CPROC_STATE_SIZE); - - selected = ' '; - - /* a wired cproc? */ - wired = (extract_address (scan->raw_cproc + CPROC_WIRED_OFFSET, - CPROC_WIRED_SIZE) - ? "wired" : ""); - - if (scan->reverse_map != -1) - kthread = (their_threads + scan->reverse_map); - else - kthread = NULL; - - if (kthread) - { - /* These cprocs have a kernel thread */ - - mid = map_port_name_to_mid (kthread->name, MACH_TYPE_THREAD); - - infoCnt = THREAD_BASIC_INFO_COUNT; - - ret = thread_info (kthread->name, - THREAD_BASIC_INFO, - (thread_info_t) & ths, - &infoCnt); - - if (ret != KERN_SUCCESS) - { - warning ("Unable to get basic info on thread %d : %s", - mid, - mach_error_string (ret)); - continue; - } - - /* Who is the first to have more than 100 threads */ - sprintf (slot, "%d", kthread->slotid % 100); - - if (kthread->name == current_thread) - selected = '*'; - - if (ths.suspend_count) - sprintf (buf, "%d", ths.suspend_count); - else - buf[0] = '\000'; - -#if 0 - if (ths.flags & TH_FLAGS_SWAPPED) - strcat (buf, "S"); -#endif - - if (ths.flags & TH_FLAGS_IDLE) - strcat (buf, "I"); - - printf_filtered (TL_FORMAT, - slot, - mid, - selected, - get_thread_name (scan, kthread->slotid), - kthread->in_emulator ? "E" : "", - translate_state (ths.run_state), - buf, - translate_cstate (cproc_state), - wired); - print_tl_address (gdb_stdout, kthread->pc); - } - else - { - /* These cprocs don't have a kernel thread. - * find out the calling frame with - * FETCH_CPROC_STATE. - */ - - struct gdb_thread state; - -#if 0 - /* jtv -> emcmanus: why do you want this here? */ - if (scan->incarnation == NULL) - continue; /* EMcM */ -#endif - - printf_filtered (TL_FORMAT, - "-", - -neworder, /* Pseudo MID */ - selected, - get_thread_name (scan, -neworder), - "", - "-", /* kernel state */ - "", - translate_cstate (cproc_state), - ""); - state.cproc = scan; - - if (FETCH_CPROC_STATE (&state) == -1) - puts_filtered ("???"); - else - print_tl_address (gdb_stdout, state.pc); - - neworder++; - } - puts_filtered ("\n"); - } - - /* Scan for kernel threads without cprocs */ - for (index = 0; index < thread_count; index++) - { - if (!their_threads[index].cproc) - { - int mid; - - char buf[10]; - char slot[3]; - - mach_port_t name = their_threads[index].name; - - mid = map_port_name_to_mid (name, MACH_TYPE_THREAD); - - infoCnt = THREAD_BASIC_INFO_COUNT; - - ret = thread_info (name, - THREAD_BASIC_INFO, - (thread_info_t) & ths, - &infoCnt); - - if (ret != KERN_SUCCESS) - { - warning ("Unable to get basic info on thread %d : %s", - mid, - mach_error_string (ret)); - continue; - } - - sprintf (slot, "%d", index % 100); - - if (name == current_thread) - selected = '*'; - else - selected = ' '; - - if (ths.suspend_count) - sprintf (buf, "%d", ths.suspend_count); - else - buf[0] = '\000'; - -#if 0 - if (ths.flags & TH_FLAGS_SWAPPED) - strcat (buf, "S"); -#endif - - if (ths.flags & TH_FLAGS_IDLE) - strcat (buf, "I"); - - printf_filtered (TL_FORMAT, - slot, - mid, - selected, - get_thread_name (NULL, index), - their_threads[index].in_emulator ? "E" : "", - translate_state (ths.run_state), - buf, - "", /* No cproc state */ - ""); /* Can't be wired */ - print_tl_address (gdb_stdout, their_threads[index].pc); - puts_filtered ("\n"); - } - } - - obstack_free (cproc_obstack, 0); - obstack_init (cproc_obstack); -} - -void -thread_select_command (char *args, int from_tty) -{ - int mid; - thread_array_t thread_list; - int thread_count; - kern_return_t ret; - int is_slot = 0; - - MACH_ERROR_NO_INFERIOR; - - if (!args) - error_no_arg ("MID or @SLOTNUMBER to specify a thread to select"); - - while (*args == ' ' || *args == '\t') - args++; - - if (*args == '@') - { - is_slot++; - args++; - } - - mid = atoi (args); - - if (mid == 0) - if (!is_slot || *args != '0') /* Rudimentary checks */ - error ("You must select threads by MID or @SLOTNUMBER"); - - if (select_thread (inferior_task, mid, is_slot ? 2 : 1) != KERN_SUCCESS) - return; - - if (from_tty) - printf_filtered ("Thread %d selected\n", - is_slot ? map_port_name_to_mid (current_thread, - MACH_TYPE_THREAD) : mid); -} - -thread_trace (mach_port_t thread, boolean_t set) -{ - int flavor = TRACE_FLAVOR; - unsigned int stateCnt = TRACE_FLAVOR_SIZE; - kern_return_t ret; - thread_state_data_t state; - - if (!MACH_PORT_VALID (thread)) - { - warning ("thread_trace: invalid thread"); - return; - } - - if (must_suspend_thread) - setup_thread (thread, 1); - - ret = thread_get_state (thread, flavor, state, &stateCnt); - CHK ("thread_trace: error reading thread state", ret); - - if (set) - { - TRACE_SET (thread, state); - } - else - { - if (!TRACE_CLEAR (thread, state)) - { - if (must_suspend_thread) - setup_thread (thread, 0); - return; - } - } - - ret = thread_set_state (thread, flavor, state, stateCnt); - CHK ("thread_trace: error writing thread state", ret); - if (must_suspend_thread) - setup_thread (thread, 0); -} - -#ifdef FLUSH_INFERIOR_CACHE - -/* When over-writing code on some machines the I-Cache must be flushed - explicitly, because it is not kept coherent by the lazy hardware. - This definitely includes breakpoints, for instance, or else we - end up looping in mysterious Bpt traps */ - -flush_inferior_icache (CORE_ADDR pc, int amount) -{ - vm_machine_attribute_val_t flush = MATTR_VAL_ICACHE_FLUSH; - kern_return_t ret; - - ret = vm_machine_attribute (inferior_task, - pc, - amount, - MATTR_CACHE, - &flush); - if (ret != KERN_SUCCESS) - warning ("Error flushing inferior's cache : %s", - mach_error_string (ret)); -} -#endif /* FLUSH_INFERIOR_CACHE */ - - -static -suspend_all_threads (int from_tty) -{ - kern_return_t ret; - thread_array_t thread_list; - int thread_count, index; - int infoCnt; - thread_basic_info_data_t th_info; - - - ret = task_threads (inferior_task, &thread_list, &thread_count); - if (ret != KERN_SUCCESS) - { - warning ("Could not suspend inferior threads."); - m3_kill_inferior (); - throw_exception (RETURN_ERROR); - } - - for (index = 0; index < thread_count; index++) - { - int mid; - - mid = map_port_name_to_mid (thread_list[index], - MACH_TYPE_THREAD); - - ret = thread_suspend (thread_list[index]); - - if (ret != KERN_SUCCESS) - warning ("Error trying to suspend thread %d : %s", - mid, mach_error_string (ret)); - - if (from_tty) - { - infoCnt = THREAD_BASIC_INFO_COUNT; - ret = thread_info (thread_list[index], - THREAD_BASIC_INFO, - (thread_info_t) & th_info, - &infoCnt); - CHK ("suspend can't get thread info", ret); - - warning ("Thread %d suspend count is %d", - mid, th_info.suspend_count); - } - } - - consume_send_rights (thread_list, thread_count); - ret = vm_deallocate (mach_task_self (), - (vm_address_t) thread_list, - (thread_count * sizeof (int))); - CHK ("Error trying to deallocate thread list", ret); -} - -void -thread_suspend_command (char *args, int from_tty) -{ - kern_return_t ret; - int mid; - mach_port_t saved_thread; - int infoCnt; - thread_basic_info_data_t th_info; - - MACH_ERROR_NO_INFERIOR; - - if (!strcasecmp (args, "all")) - { - suspend_all_threads (from_tty); - return; - } - - saved_thread = current_thread; - - mid = parse_thread_id (args, 0, 0); - - if (mid < 0) - error ("You can suspend only existing kernel threads with MID or @SLOTNUMBER"); - - if (mid == 0) - mid = map_port_name_to_mid (current_thread, MACH_TYPE_THREAD); - else if (select_thread (inferior_task, mid, 0) != KERN_SUCCESS) - { - if (current_thread) - current_thread = saved_thread; - error ("Could not select thread %d", mid); - } - - ret = thread_suspend (current_thread); - if (ret != KERN_SUCCESS) - warning ("thread_suspend failed : %s", - mach_error_string (ret)); - - infoCnt = THREAD_BASIC_INFO_COUNT; - ret = thread_info (current_thread, - THREAD_BASIC_INFO, - (thread_info_t) & th_info, - &infoCnt); - CHK ("suspend can't get thread info", ret); - - warning ("Thread %d suspend count is %d", mid, th_info.suspend_count); - - current_thread = saved_thread; -} - -resume_all_threads (int from_tty) -{ - kern_return_t ret; - thread_array_t thread_list; - int thread_count, index; - int mid; - int infoCnt; - thread_basic_info_data_t th_info; - - ret = task_threads (inferior_task, &thread_list, &thread_count); - if (ret != KERN_SUCCESS) - { - m3_kill_inferior (); - error ("task_threads", mach_error_string (ret)); - } - - for (index = 0; index < thread_count; index++) - { - infoCnt = THREAD_BASIC_INFO_COUNT; - ret = thread_info (thread_list[index], - THREAD_BASIC_INFO, - (thread_info_t) & th_info, - &infoCnt); - CHK ("resume_all can't get thread info", ret); - - mid = map_port_name_to_mid (thread_list[index], - MACH_TYPE_THREAD); - - if (!th_info.suspend_count) - { - if (mid != -1 && from_tty) - warning ("Thread %d is not suspended", mid); - continue; - } - - ret = thread_resume (thread_list[index]); - - if (ret != KERN_SUCCESS) - warning ("Error trying to resume thread %d : %s", - mid, mach_error_string (ret)); - else if (mid != -1 && from_tty) - warning ("Thread %d suspend count is %d", - mid, --th_info.suspend_count); - } - - consume_send_rights (thread_list, thread_count); - ret = vm_deallocate (mach_task_self (), - (vm_address_t) thread_list, - (thread_count * sizeof (int))); - CHK ("Error trying to deallocate thread list", ret); -} - -void -thread_resume_command (char *args, int from_tty) -{ - int mid; - mach_port_t saved_thread; - kern_return_t ret; - thread_basic_info_data_t th_info; - int infoCnt = THREAD_BASIC_INFO_COUNT; - - MACH_ERROR_NO_INFERIOR; - - if (!strcasecmp (args, "all")) - { - resume_all_threads (from_tty); - return; - } - - saved_thread = current_thread; - - mid = parse_thread_id (args, 0, 0); - - if (mid < 0) - error ("You can resume only existing kernel threads with MID or @SLOTNUMBER"); - - if (mid == 0) - mid = map_port_name_to_mid (current_thread, MACH_TYPE_THREAD); - else if (select_thread (inferior_task, mid, 0) != KERN_SUCCESS) - { - if (current_thread) - current_thread = saved_thread; - throw_exception (RETURN_ERROR); - } - - ret = thread_info (current_thread, - THREAD_BASIC_INFO, - (thread_info_t) & th_info, - &infoCnt); - CHK ("resume can't get thread info", ret); - - if (!th_info.suspend_count) - { - warning ("Thread %d is not suspended", mid); - goto out; - } - - ret = thread_resume (current_thread); - if (ret != KERN_SUCCESS) - warning ("thread_resume failed : %s", - mach_error_string (ret)); - else - { - th_info.suspend_count--; - warning ("Thread %d suspend count is %d", mid, th_info.suspend_count); - } - -out: - current_thread = saved_thread; -} - -void -thread_kill_command (char *args, int from_tty) -{ - int mid; - kern_return_t ret; - int thread_count; - thread_array_t thread_table; - int index; - mach_port_t thread_to_kill = MACH_PORT_NULL; - - - MACH_ERROR_NO_INFERIOR; - - if (!args) - error_no_arg ("thread mid to kill from the inferior task"); - - mid = parse_thread_id (args, 0, 0); - - if (mid < 0) - error ("You can kill only existing kernel threads with MID or @SLOTNUMBER"); - - if (mid) - { - ret = machid_mach_port (mid_server, mid_auth, mid, &thread_to_kill); - CHK ("thread_kill_command: machid_mach_port map failed", ret); - } - else - mid = map_port_name_to_mid (current_thread, MACH_TYPE_THREAD); - - /* Don't allow gdb to kill *any* thread in the system. Use mkill program for that */ - ret = task_threads (inferior_task, &thread_table, &thread_count); - CHK ("Error getting inferior's thread list", ret); - - if (thread_to_kill == current_thread) - { - ret = thread_terminate (thread_to_kill); - CHK ("Thread could not be terminated", ret); - - if (select_thread (inferior_task, 0, 1) != KERN_SUCCESS) - warning ("Last thread was killed, use \"kill\" command to kill task"); - } - else - for (index = 0; index < thread_count; index++) - if (thread_table[index] == thread_to_kill) - { - ret = thread_terminate (thread_to_kill); - CHK ("Thread could not be terminated", ret); - } - - if (thread_count > 1) - consume_send_rights (thread_table, thread_count); - - ret = vm_deallocate (mach_task_self (), (vm_address_t) thread_table, - (thread_count * sizeof (mach_port_t))); - CHK ("Error trying to deallocate thread list", ret); - - warning ("Thread %d killed", mid); -} - - -/* Task specific commands; add more if you like */ - -void -task_resume_command (char *args, int from_tty) -{ - kern_return_t ret; - task_basic_info_data_t ta_info; - int infoCnt = TASK_BASIC_INFO_COUNT; - int mid = map_port_name_to_mid (inferior_task, MACH_TYPE_TASK); - - MACH_ERROR_NO_INFERIOR; - - /* Would be trivial to change, but is it desirable? */ - if (args) - error ("Currently gdb can resume only it's inferior task"); - - ret = task_info (inferior_task, - TASK_BASIC_INFO, - (task_info_t) & ta_info, - &infoCnt); - CHK ("task_resume_command: task_info failed", ret); - - if (ta_info.suspend_count == 0) - error ("Inferior task %d is not suspended", mid); - else if (ta_info.suspend_count == 1 && - from_tty && - !query ("Suspend count is now 1. Do you know what you are doing? ")) - error ("Task not resumed"); - - ret = task_resume (inferior_task); - CHK ("task_resume_command: task_resume", ret); - - if (ta_info.suspend_count == 1) - { - warning ("Inferior task %d is no longer suspended", mid); - must_suspend_thread = 1; - /* @@ This is not complete: Registers change all the time when not - suspended! */ - registers_changed (); - } - else - warning ("Inferior task %d suspend count is now %d", - mid, ta_info.suspend_count - 1); -} - - -void -task_suspend_command (char *args, int from_tty) -{ - kern_return_t ret; - task_basic_info_data_t ta_info; - int infoCnt = TASK_BASIC_INFO_COUNT; - int mid = map_port_name_to_mid (inferior_task, MACH_TYPE_TASK); - - MACH_ERROR_NO_INFERIOR; - - /* Would be trivial to change, but is it desirable? */ - if (args) - error ("Currently gdb can suspend only it's inferior task"); - - ret = task_suspend (inferior_task); - CHK ("task_suspend_command: task_suspend", ret); - - must_suspend_thread = 0; - - ret = task_info (inferior_task, - TASK_BASIC_INFO, - (task_info_t) & ta_info, - &infoCnt); - CHK ("task_suspend_command: task_info failed", ret); - - warning ("Inferior task %d suspend count is now %d", - mid, ta_info.suspend_count); -} - -static char * -get_size (int bytes) -{ - static char size[30]; - int zz = bytes / 1024; - - if (zz / 1024) - sprintf (size, "%-2.1f M", ((float) bytes) / (1024.0 * 1024.0)); - else - sprintf (size, "%d K", zz); - - return size; -} - -/* Does this require the target task to be suspended?? I don't think so. */ -void -task_info_command (char *args, int from_tty) -{ - int mid = -5; - mach_port_t task; - kern_return_t ret; - task_basic_info_data_t ta_info; - int infoCnt = TASK_BASIC_INFO_COUNT; - int page_size = round_page (1); - int thread_count = 0; - - if (MACH_PORT_VALID (inferior_task)) - mid = map_port_name_to_mid (inferior_task, - MACH_TYPE_TASK); - - task = inferior_task; - - if (args) - { - int tmid = atoi (args); - - if (tmid <= 0) - error ("Invalid mid %d for task info", tmid); - - if (tmid != mid) - { - mid = tmid; - ret = machid_mach_port (mid_server, mid_auth, tmid, &task); - CHK ("task_info_command: machid_mach_port map failed", ret); - } - } - - if (mid < 0) - error ("You have to give the task MID as an argument"); - - ret = task_info (task, - TASK_BASIC_INFO, - (task_info_t) & ta_info, - &infoCnt); - CHK ("task_info_command: task_info failed", ret); - - printf_filtered ("\nTask info for task %d:\n\n", mid); - printf_filtered (" Suspend count : %d\n", ta_info.suspend_count); - printf_filtered (" Base priority : %d\n", ta_info.base_priority); - printf_filtered (" Virtual size : %s\n", get_size (ta_info.virtual_size)); - printf_filtered (" Resident size : %s\n", get_size (ta_info.resident_size)); - - { - thread_array_t thread_list; - - ret = task_threads (task, &thread_list, &thread_count); - CHK ("task_info_command: task_threads", ret); - - printf_filtered (" Thread count : %d\n", thread_count); - - consume_send_rights (thread_list, thread_count); - ret = vm_deallocate (mach_task_self (), - (vm_address_t) thread_list, - (thread_count * sizeof (int))); - CHK ("Error trying to deallocate thread list", ret); - } - if (have_emulator_p (task)) - printf_filtered (" Emulator at : 0x%x..0x%x\n", - EMULATOR_BASE, EMULATOR_END); - else - printf_filtered (" No emulator.\n"); - - if (thread_count && task == inferior_task) - printf_filtered ("\nUse the \"thread list\" command to see the threads\n"); -} - -/* You may either FORWARD the exception to the inferior, or KEEP - * it and return to GDB command level. - * - * exception mid [ forward | keep ] - */ - -static void -exception_command (char *args, int from_tty) -{ - char *scan = args; - int exception; - int len; - - if (!args) - error_no_arg ("exception number action"); - - while (*scan == ' ' || *scan == '\t') - scan++; - - if ('0' <= *scan && *scan <= '9') - while ('0' <= *scan && *scan <= '9') - scan++; - else - error ("exception number action"); - - exception = atoi (args); - if (exception <= 0 || exception > MAX_EXCEPTION) - error ("Allowed exception numbers are in range 1..%d", - MAX_EXCEPTION); - - if (*scan != ' ' && *scan != '\t') - error ("exception number must be followed by a space"); - else - while (*scan == ' ' || *scan == '\t') - scan++; - - args = scan; - len = 0; - while (*scan) - { - len++; - scan++; - } - - if (!len) - error ("exception number action"); - - if (!strncasecmp (args, "forward", len)) - exception_map[exception].forward = TRUE; - else if (!strncasecmp (args, "keep", len)) - exception_map[exception].forward = FALSE; - else - error ("exception action is either \"keep\" or \"forward\""); -} - -static void -print_exception_info (int exception) -{ - boolean_t forward = exception_map[exception].forward; - - printf_filtered ("%s\t(%d): ", exception_map[exception].name, - exception); - if (!forward) - if (exception_map[exception].sigmap != SIG_UNKNOWN) - printf_filtered ("keep and handle as signal %d\n", - exception_map[exception].sigmap); - else - printf_filtered ("keep and handle as unknown signal %d\n", - exception_map[exception].sigmap); - else - printf_filtered ("forward exception to inferior\n"); -} - -void -exception_info (char *args, int from_tty) -{ - int exception; - - if (!args) - for (exception = 1; exception <= MAX_EXCEPTION; exception++) - print_exception_info (exception); - else - { - exception = atoi (args); - - if (exception <= 0 || exception > MAX_EXCEPTION) - error ("Invalid exception number, values from 1 to %d allowed", - MAX_EXCEPTION); - print_exception_info (exception); - } -} - -/* Check for actions for mach exceptions. - */ -mach3_exception_actions (WAITTYPE *w, boolean_t force_print_only, char *who) -{ - boolean_t force_print = FALSE; - - - if (force_print_only || - exception_map[stop_exception].sigmap == SIG_UNKNOWN) - force_print = TRUE; - else - WSETSTOP (*w, exception_map[stop_exception].sigmap); - - if (exception_map[stop_exception].print || force_print) - { - target_terminal_ours (); - - printf_filtered ("\n%s received %s exception : ", - who, - exception_map[stop_exception].name); - - wrap_here (" "); - - switch (stop_exception) - { - case EXC_BAD_ACCESS: - printf_filtered ("referencing address 0x%x : %s\n", - stop_subcode, - mach_error_string (stop_code)); - break; - case EXC_BAD_INSTRUCTION: - printf_filtered - ("illegal or undefined instruction. code %d subcode %d\n", - stop_code, stop_subcode); - break; - case EXC_ARITHMETIC: - printf_filtered ("code %d\n", stop_code); - break; - case EXC_EMULATION: - printf_filtered ("code %d subcode %d\n", stop_code, stop_subcode); - break; - case EXC_SOFTWARE: - printf_filtered ("%s specific, code 0x%x\n", - stop_code < 0xffff ? "hardware" : "os emulation", - stop_code); - break; - case EXC_BREAKPOINT: - printf_filtered ("type %d (machine dependent)\n", - stop_code); - break; - default: - internal_error (__FILE__, __LINE__, - "Unknown exception"); - } - } -} - -setup_notify_port (int create_new) -{ - kern_return_t ret; - - if (MACH_PORT_VALID (our_notify_port)) - { - ret = mach_port_destroy (mach_task_self (), our_notify_port); - CHK ("Could not destroy our_notify_port", ret); - } - - our_notify_port = MACH_PORT_NULL; - notify_chain = (port_chain_t) NULL; - port_chain_destroy (port_chain_obstack); - - if (create_new) - { - ret = mach_port_allocate (mach_task_self (), - MACH_PORT_RIGHT_RECEIVE, - &our_notify_port); - if (ret != KERN_SUCCESS) - internal_error (__FILE__, __LINE__, - "Creating notify port %s", mach_error_string (ret)); - - ret = mach_port_move_member (mach_task_self (), - our_notify_port, - inferior_wait_port_set); - if (ret != KERN_SUCCESS) - internal_error (__FILE__, __LINE__, - "initial move member %s", mach_error_string (ret)); - } -} - -/* - * Register our message port to the net name server - * - * Currently used only by the external stop-gdb program - * since ^C does not work if you would like to enter - * gdb command level while debugging your program. - * - * NOTE: If the message port is sometimes used for other - * purposes also, the NAME must not be a guessable one. - * Then, there should be a way to change it. - */ - -char registered_name[MAX_NAME_LEN]; - -void -message_port_info (char *args, int from_tty) -{ - if (registered_name[0]) - printf_filtered ("gdb's message port name: '%s'\n", - registered_name); - else - printf_filtered ("gdb's message port is not currently registered\n"); -} - -void -gdb_register_port (char *name, mach_port_t port) -{ - kern_return_t ret; - static int already_signed = 0; - int len; - - if (!MACH_PORT_VALID (port) || !name || !*name) - { - warning ("Invalid registration request"); - return; - } - - if (!already_signed) - { - ret = mach_port_insert_right (mach_task_self (), - our_message_port, - our_message_port, - MACH_MSG_TYPE_MAKE_SEND); - CHK ("Failed to create a signature to our_message_port", ret); - already_signed = 1; - } - else if (already_signed > 1) - { - ret = netname_check_out (name_server_port, - registered_name, - our_message_port); - CHK ("Failed to check out gdb's message port", ret); - registered_name[0] = '\000'; - already_signed = 1; - } - - ret = netname_check_in (name_server_port, /* Name server port */ - name, /* Name of service */ - our_message_port, /* Signature */ - port); /* Creates a new send right */ - CHK ("Failed to check in the port", ret); - - len = 0; - while (len < MAX_NAME_LEN && *(name + len)) - { - registered_name[len] = *(name + len); - len++; - } - registered_name[len] = '\000'; - already_signed = 2; -} - -struct cmd_list_element *cmd_thread_list; -struct cmd_list_element *cmd_task_list; - -/*ARGSUSED */ -static void -thread_command (char *arg, int from_tty) -{ - printf_unfiltered ("\"thread\" must be followed by the name of a thread command.\n"); - help_list (cmd_thread_list, "thread ", -1, gdb_stdout); -} - -/*ARGSUSED */ -static void -task_command (char *arg, int from_tty) -{ - printf_unfiltered ("\"task\" must be followed by the name of a task command.\n"); - help_list (cmd_task_list, "task ", -1, gdb_stdout); -} - -add_mach_specific_commands (void) -{ - /* Thread handling commands */ - - /* FIXME: Move our thread support into the generic thread.c stuff so we - can share that code. */ - add_prefix_cmd ("mthread", class_stack, thread_command, - "Generic command for handling Mach threads in the debugged task.", - &cmd_thread_list, "thread ", 0, &cmdlist); - - add_com_alias ("th", "mthread", class_stack, 1); - - add_cmd ("select", class_stack, thread_select_command, - "Select and print MID of the selected thread", - &cmd_thread_list); - add_cmd ("list", class_stack, thread_list_command, - "List info of task's threads. Selected thread is marked with '*'", - &cmd_thread_list); - add_cmd ("suspend", class_run, thread_suspend_command, - "Suspend one or all of the threads in the selected task.", - &cmd_thread_list); - add_cmd ("resume", class_run, thread_resume_command, - "Resume one or all of the threads in the selected task.", - &cmd_thread_list); - add_cmd ("kill", class_run, thread_kill_command, - "Kill the specified thread MID from inferior task.", - &cmd_thread_list); -#if 0 - /* The rest of this support (condition_thread) was not merged. It probably - should not be merged in this form, but instead added to the generic GDB - thread support. */ - add_cmd ("break", class_breakpoint, condition_thread, - "Breakpoint N will only be effective for thread MID or @SLOT\n\ - If MID/@SLOT is omitted allow all threads to break at breakpoint", - &cmd_thread_list); -#endif - /* Thread command shorthands (for backward compatibility) */ - add_alias_cmd ("ts", "mthread select", 0, 0, &cmdlist); - add_alias_cmd ("tl", "mthread list", 0, 0, &cmdlist); - - /* task handling commands */ - - add_prefix_cmd ("task", class_stack, task_command, - "Generic command for handling debugged task.", - &cmd_task_list, "task ", 0, &cmdlist); - - add_com_alias ("ta", "task", class_stack, 1); - - add_cmd ("suspend", class_run, task_suspend_command, - "Suspend the inferior task.", - &cmd_task_list); - add_cmd ("resume", class_run, task_resume_command, - "Resume the inferior task.", - &cmd_task_list); - add_cmd ("info", no_class, task_info_command, - "Print information about the specified task.", - &cmd_task_list); - - /* Print my message port name */ - - add_info ("message-port", message_port_info, - "Returns the name of gdb's message port in the netnameserver"); - - /* Exception commands */ - - add_info ("exceptions", exception_info, - "What debugger does when program gets various exceptions.\n\ -Specify an exception number as argument to print info on that\n\ -exception only."); - - add_com ("exception", class_run, exception_command, - "Specify how to handle an exception.\n\ -Args are exception number followed by \"forward\" or \"keep\".\n\ -`Forward' means forward the exception to the program's normal exception\n\ -handler.\n\ -`Keep' means reenter debugger if this exception happens, and GDB maps\n\ -the exception to some signal (see info exception)\n\ -Normally \"keep\" is used to return to GDB on exception."); -} - -kern_return_t -do_mach_notify_dead_name (mach_port_t notify, mach_port_t name) -{ - kern_return_t kr = KERN_SUCCESS; - - /* Find the thing that notified */ - port_chain_t element = port_chain_member (notify_chain, name); - - /* Take name of from unreceived dead name notification list */ - notify_chain = port_chain_delete (notify_chain, name); - - if (!element) - error ("Received a dead name notify from unchained port (0x%x)", name); - - switch (element->type) - { - - case MACH_TYPE_THREAD: - target_terminal_ours_for_output (); - if (name == current_thread) - { - printf_filtered ("\nCurrent thread %d died", element->mid); - current_thread = MACH_PORT_NULL; - } - else - printf_filtered ("\nThread %d died", element->mid); - - break; - - case MACH_TYPE_TASK: - target_terminal_ours_for_output (); - if (name != inferior_task) - printf_filtered ("Task %d died, but it was not the selected task", - element->mid); - else - { - printf_filtered ("Current task %d died", element->mid); - - mach_port_destroy (mach_task_self (), name); - inferior_task = MACH_PORT_NULL; - - if (notify_chain) - warning ("There were still unreceived dead_name_notifications???"); - - /* Destroy the old notifications */ - setup_notify_port (0); - - } - break; - - default: - error ("Unregistered dead_name 0x%x notification received. Type is %d, mid is 0x%x", - name, element->type, element->mid); - break; - } - - return KERN_SUCCESS; -} - -kern_return_t -do_mach_notify_msg_accepted (mach_port_t notify, mach_port_t name) -{ - warning ("do_mach_notify_msg_accepted : notify %x, name %x", - notify, name); - return KERN_SUCCESS; -} - -kern_return_t -do_mach_notify_no_senders (mach_port_t notify, mach_port_mscount_t mscount) -{ - warning ("do_mach_notify_no_senders : notify %x, mscount %x", - notify, mscount); - return KERN_SUCCESS; -} - -kern_return_t -do_mach_notify_port_deleted (mach_port_t notify, mach_port_t name) -{ - warning ("do_mach_notify_port_deleted : notify %x, name %x", - notify, name); - return KERN_SUCCESS; -} - -kern_return_t -do_mach_notify_port_destroyed (mach_port_t notify, mach_port_t rights) -{ - warning ("do_mach_notify_port_destroyed : notify %x, rights %x", - notify, rights); - return KERN_SUCCESS; -} - -kern_return_t -do_mach_notify_send_once (mach_port_t notify) -{ -#ifdef DUMP_SYSCALL - /* MANY of these are generated. */ - warning ("do_mach_notify_send_once : notify %x", - notify); -#endif - return KERN_SUCCESS; -} - -/* Kills the inferior. It's gone when you call this */ -static void -kill_inferior_fast (void) -{ - WAITTYPE w; - - if (PIDGET (inferior_ptid) == 0 || PIDGET (inferior_ptid) == 1) - return; - - /* kill() it, since the Unix server does not otherwise notice when - * killed with task_terminate(). - */ - if (PIDGET (inferior_ptid) > 0) - kill (PIDGET (inferior_ptid), SIGKILL); - - /* It's propably terminate already */ - (void) task_terminate (inferior_task); - - inferior_task = MACH_PORT_NULL; - current_thread = MACH_PORT_NULL; - - wait3 (&w, WNOHANG, 0); - - setup_notify_port (0); -} - -static void -m3_kill_inferior (void) -{ - kill_inferior_fast (); - target_mourn_inferior (); -} - -/* Clean up after the inferior dies. */ - -static void -m3_mourn_inferior (void) -{ - unpush_target (&m3_ops); - generic_mourn_inferior (); -} - - -/* Fork an inferior process, and start debugging it. */ - -static void -m3_create_inferior (char *exec_file, char *allargs, char **env) -{ - fork_inferior (exec_file, allargs, env, m3_trace_me, m3_trace_him, NULL, NULL); - /* We are at the first instruction we care about. */ - /* Pedal to the metal... */ - proceed ((CORE_ADDR) -1, 0, 0); -} - -/* Mark our target-struct as eligible for stray "run" and "attach" - commands. */ -static int -m3_can_run (void) -{ - return 1; -} - -/* Mach 3.0 does not need ptrace for anything - * Make sure nobody uses it on mach. - */ -ptrace (int a, int b, int c, int d) -{ - error ("Lose, Lose! Somebody called ptrace\n"); -} - -/* Resume execution of the inferior process. - If STEP is nonzero, single-step it. - If SIGNAL is nonzero, give it that signal. */ - -void -m3_resume (ptid_t ptid, int step, enum target_signal signal) -{ - kern_return_t ret; - - if (step) - { - thread_basic_info_data_t th_info; - unsigned int infoCnt = THREAD_BASIC_INFO_COUNT; - - /* There is no point in single stepping when current_thread - * is dead. - */ - if (!MACH_PORT_VALID (current_thread)) - error ("No thread selected; can not single step"); - - /* If current_thread is suspended, tracing it would never return. - */ - ret = thread_info (current_thread, - THREAD_BASIC_INFO, - (thread_info_t) & th_info, - &infoCnt); - CHK ("child_resume: can't get thread info", ret); - - if (th_info.suspend_count) - error ("Can't trace a suspended thread. Use \"thread resume\" command to resume it"); - } - - vm_read_cache_valid = FALSE; - - if (signal && PIDGET (inferior_ptid) > 0) /* Do not signal, if attached by MID */ - kill (PIDGET (inferior_ptid), target_signal_to_host (signal)); - - if (step) - { - suspend_all_threads (0); - - setup_single_step (current_thread, TRUE); - - ret = thread_resume (current_thread); - CHK ("thread_resume", ret); - } - - ret = task_resume (inferior_task); - if (ret == KERN_FAILURE) - warning ("Task was not suspended"); - else - CHK ("Resuming task", ret); - - /* HACK HACK This is needed by the multiserver system HACK HACK */ - while ((ret = task_resume (inferior_task)) == KERN_SUCCESS) - /* make sure it really runs */ ; - /* HACK HACK This is needed by the multiserver system HACK HACK */ -} - -#ifdef ATTACH_DETACH - -/* Start debugging the process with the given task */ -void -task_attach (task_t tid) -{ - kern_return_t ret; - inferior_task = tid; - - ret = task_suspend (inferior_task); - CHK ("task_attach: task_suspend", ret); - - must_suspend_thread = 0; - - setup_notify_port (1); - - request_notify (inferior_task, MACH_NOTIFY_DEAD_NAME, MACH_TYPE_TASK); - - setup_exception_port (); - - emulator_present = have_emulator_p (inferior_task); - - attach_flag = 1; -} - -/* Well, we can call error also here and leave the - * target stack inconsistent. Sigh. - * Fix this sometime (the only way to fail here is that - * the task has no threads at all, which is rare, but - * possible; or if the target task has died, which is also - * possible, but unlikely, since it has been suspended. - * (Someone must have killed it)) - */ -void -attach_to_thread (void) -{ - if (select_thread (inferior_task, 0, 1) != KERN_SUCCESS) - error ("Could not select any threads to attach to"); -} - -mid_attach (int mid) -{ - kern_return_t ret; - - ret = machid_mach_port (mid_server, mid_auth, mid, &inferior_task); - CHK ("mid_attach: machid_mach_port", ret); - - task_attach (inferior_task); - - return mid; -} - -/* - * Start debugging the process whose unix process-id is PID. - * A negative "pid" value is legal and signifies a mach_id not a unix pid. - * - * Prevent (possible unwanted) dangerous operations by enabled users - * like "atta 0" or "atta foo" (equal to the previous :-) and - * "atta pidself". Anyway, the latter is allowed by specifying a MID. - */ -static int -m3_do_attach (int pid) -{ - kern_return_t ret; - - if (pid == 0) - error ("MID=0, Debugging the master unix server does not compute"); - - /* Foo. This assumes gdb has a unix pid */ - if (pid == getpid ()) - error ("I will debug myself only by mid. (Gdb would suspend itself!)"); - - if (pid < 0) - { - mid_attach (-(pid)); - - /* inferior_ptid will be NEGATIVE! */ - inferior_ptid = pid_to_ptid (pid); - - return PIDGET (inferior_ptid); - } - - inferior_task = task_by_pid (pid); - if (!MACH_PORT_VALID (inferior_task)) - error ("Cannot map Unix pid %d to Mach task port", pid); - - task_attach (inferior_task); - - inferior_ptid = pid_to_ptid (pid); - - return PIDGET (inferior_ptid); -} - -/* Attach to process PID, then initialize for debugging it - and wait for the trace-trap that results from attaching. */ - -static void -m3_attach (char *args, int from_tty) -{ - char *exec_file; - int pid; - - if (!args) - error_no_arg ("process-id to attach"); - - pid = atoi (args); - - if (pid == getpid ()) /* Trying to masturbate? */ - error ("I refuse to debug myself!"); - - if (from_tty) - { - exec_file = (char *) get_exec_file (0); - - if (exec_file) - printf_unfiltered ("Attaching to program `%s', %s\n", exec_file, - target_pid_to_str (pid_to_ptid (pid))); - else - printf_unfiltered ("Attaching to %s\n", - target_pid_to_str (pid_to_ptid (pid))); - - gdb_flush (gdb_stdout); - } - - m3_do_attach (pid_to_ptid (pid)); - inferior_ptid = pid_to_ptid (pid); - push_target (&m3_ops); -} - -void -deallocate_inferior_ports (void) -{ - kern_return_t ret; - thread_array_t thread_list; - int thread_count, index; - - if (!MACH_PORT_VALID (inferior_task)) - return; - - ret = task_threads (inferior_task, &thread_list, &thread_count); - if (ret != KERN_SUCCESS) - { - warning ("deallocate_inferior_ports: task_threads", - mach_error_string (ret)); - return; - } - - /* Get rid of send rights to task threads */ - for (index = 0; index < thread_count; index++) - { - int rights; - ret = mach_port_get_refs (mach_task_self (), - thread_list[index], - MACH_PORT_RIGHT_SEND, - &rights); - CHK ("deallocate_inferior_ports: get refs", ret); - - if (rights > 0) - { - ret = mach_port_mod_refs (mach_task_self (), - thread_list[index], - MACH_PORT_RIGHT_SEND, - -rights); - CHK ("deallocate_inferior_ports: mod refs", ret); - } - } - - ret = mach_port_mod_refs (mach_task_self (), - inferior_exception_port, - MACH_PORT_RIGHT_RECEIVE, - -1); - CHK ("deallocate_inferior_ports: cannot get rid of exception port", ret); - - ret = mach_port_deallocate (mach_task_self (), - inferior_task); - CHK ("deallocate_task_port: deallocating inferior_task", ret); - - current_thread = MACH_PORT_NULL; - inferior_task = MACH_PORT_NULL; -} - -/* Stop debugging the process whose number is PID - and continue it with signal number SIGNAL. - SIGNAL = 0 means just continue it. */ - -static void -m3_do_detach (int signal) -{ - kern_return_t ret; - - MACH_ERROR_NO_INFERIOR; - - if (current_thread != MACH_PORT_NULL) - { - /* Store the gdb's view of the thread we are deselecting - * before we detach. - * @@ I am really not sure if this is ever needeed. - */ - target_prepare_to_store (); - target_store_registers (-1); - } - - ret = task_set_special_port (inferior_task, - TASK_EXCEPTION_PORT, - inferior_old_exception_port); - CHK ("task_set_special_port", ret); - - /* Discard all requested notifications */ - setup_notify_port (0); - - if (remove_breakpoints ()) - warning ("Could not remove breakpoints when detaching"); - - if (signal && PIDGET (inferior_ptid) > 0) - kill (PIDGET (inferior_ptid), signal); - - /* the task might be dead by now */ - (void) task_resume (inferior_task); - - deallocate_inferior_ports (); - - attach_flag = 0; -} - -/* Take a program previously attached to and detaches it. - The program resumes execution and will no longer stop - on signals, etc. We'd better not have left any breakpoints - in the program or it'll die when it hits one. For this - to work, it may be necessary for the process to have been - previously attached. It *might* work if the program was - started via fork. */ - -static void -m3_detach (char *args, int from_tty) -{ - int siggnal = 0; - - if (from_tty) - { - char *exec_file = get_exec_file (0); - if (exec_file == 0) - exec_file = ""; - printf_unfiltered ("Detaching from program: %s %s\n", - exec_file, target_pid_to_str (inferior_ptid)); - gdb_flush (gdb_stdout); - } - if (args) - siggnal = atoi (args); - - m3_do_detach (siggnal); - inferior_ptid = null_ptid; - unpush_target (&m3_ops); /* Pop out of handling an inferior */ -} -#endif /* ATTACH_DETACH */ - -/* Get ready to modify the registers array. On machines which store - individual registers, this doesn't need to do anything. On machines - which store all the registers in one fell swoop, this makes sure - that registers contains all the registers from the program being - debugged. */ - -static void -m3_prepare_to_store (void) -{ -#ifdef CHILD_PREPARE_TO_STORE - CHILD_PREPARE_TO_STORE (); -#endif -} - -/* Print status information about what we're accessing. */ - -static void -m3_files_info (struct target_ops *ignore) -{ - /* FIXME: should print MID and all that crap. */ - printf_unfiltered ("\tUsing the running image of %s %s.\n", - attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid)); -} - -static void -m3_open (char *arg, int from_tty) -{ - error ("Use the \"run\" command to start a Unix child process."); -} - -#ifdef DUMP_SYSCALL -#define STR(x) #x - -char *bsd1_names[] = -{ - "execve", - "fork", - "take_signal", - "sigreturn", - "getrusage", - "chdir", - "chroot", - "open", - "creat", - "mknod", - "link", - "symlink", - "unlink", - "access", - "stat", - "readlink", - "chmod", - "chown", - "utimes", - "truncate", - "rename", - "mkdir", - "rmdir", - "xutimes", - "mount", - "umount", - "acct", - "setquota", - "write_short", - "write_long", - "send_short", - "send_long", - "sendto_short", - "sendto_long", - "select", - "task_by_pid", - "recvfrom_short", - "recvfrom_long", - "setgroups", - "setrlimit", - "sigvec", - "sigstack", - "settimeofday", - "adjtime", - "setitimer", - "sethostname", - "bind", - "accept", - "connect", - "setsockopt", - "getsockopt", - "getsockname", - "getpeername", - "init_process", - "table_set", - "table_get", - "pioctl", - "emulator_error", - "readwrite", - "share_wakeup", - 0, - "maprw_request_it", - "maprw_release_it", - "maprw_remap", - "pid_by_task", -}; - -int bsd1_nnames = sizeof (bsd1_names) / sizeof (bsd1_names[0]); - -char * -name_str (int name, char *buf) -{ - switch (name) - { - case MACH_MSG_TYPE_BOOLEAN: - return "boolean"; - case MACH_MSG_TYPE_INTEGER_16: - return "short"; - case MACH_MSG_TYPE_INTEGER_32: - return "long"; - case MACH_MSG_TYPE_CHAR: - return "char"; - case MACH_MSG_TYPE_BYTE: - return "byte"; - case MACH_MSG_TYPE_REAL: - return "real"; - case MACH_MSG_TYPE_STRING: - return "string"; - default: - sprintf (buf, "%d", name); - return buf; - } -} - -char * -id_str (int id, char *buf) -{ - char *p; - if (id >= 101000 && id < 101000 + bsd1_nnames) - { - if (p = bsd1_names[id - 101000]) - return p; - } - if (id == 102000) - return "psignal_retry"; - if (id == 100000) - return "syscall"; - sprintf (buf, "%d", id); - return buf; -} - -print_msg (mach_msg_header_t *mp) -{ - char *fmt_x = "%20s : 0x%08x\n"; - char *fmt_d = "%20s : %10d\n"; - char *fmt_s = "%20s : %s\n"; - char buf[100]; - - puts_filtered ("\n"); -#define pr(fmt,h,x) printf_filtered(fmt,STR(x),(h).x) - pr (fmt_x, (*mp), msgh_bits); - pr (fmt_d, (*mp), msgh_size); - pr (fmt_x, (*mp), msgh_remote_port); - pr (fmt_x, (*mp), msgh_local_port); - pr (fmt_d, (*mp), msgh_kind); - printf_filtered (fmt_s, STR (msgh_id), id_str (mp->msgh_id, buf)); - - if (debug_level > 1) - { - char *p, *ep, *dp; - int plen; - p = (char *) mp; - ep = p + mp->msgh_size; - p += sizeof (*mp); - for (; p < ep; p += plen) - { - mach_msg_type_t *tp; - mach_msg_type_long_t *tlp; - int name, size, number; - tp = (mach_msg_type_t *) p; - if (tp->msgt_longform) - { - tlp = (mach_msg_type_long_t *) tp; - name = tlp->msgtl_name; - size = tlp->msgtl_size; - number = tlp->msgtl_number; - plen = sizeof (*tlp); - } - else - { - name = tp->msgt_name; - size = tp->msgt_size; - number = tp->msgt_number; - plen = sizeof (*tp); - } - printf_filtered ("name=%-16s size=%2d number=%7d inline=%d long=%d deal=%d\n", - name_str (name, buf), size, number, tp->msgt_inline, - tp->msgt_longform, tp->msgt_deallocate); - dp = p + plen; - if (tp->msgt_inline) - { - int l; - l = size * number / 8; - l = (l + sizeof (long) - 1) & ~((sizeof (long)) - 1); - plen += l; - print_data (dp, size, number); - } - else - { - plen += sizeof (int *); - } - printf_filtered ("plen=%d\n", plen); - } - } -} - -print_data (char *p, int size, int number) -{ - int *ip; - short *sp; - int i; - - switch (size) - { - case 8: - for (i = 0; i < number; i++) - { - printf_filtered (" %02x", p[i]); - } - break; - case 16: - sp = (short *) p; - for (i = 0; i < number; i++) - { - printf_filtered (" %04x", sp[i]); - } - break; - case 32: - ip = (int *) p; - for (i = 0; i < number; i++) - { - printf_filtered (" %08x", ip[i]); - } - break; - } - puts_filtered ("\n"); -} -#endif /* DUMP_SYSCALL */ - -static void -m3_stop (void) -{ - error ("to_stop target function not implemented"); -} - -static char * -m3_pid_to_exec_file (int pid) -{ - error ("to_pid_to_exec_file target function not implemented"); - return NULL; /* To keep all compilers happy. */ -} - -static void -init_m3_ops (void) -{ - m3_ops.to_shortname = "mach"; - m3_ops.to_longname = "Mach child process"; - m3_ops.to_doc = "Mach child process (started by the \"run\" command)."; - m3_ops.to_open = m3_open; - m3_ops.to_attach = m3_attach; - m3_ops.to_detach = m3_detach; - m3_ops.to_resume = m3_resume; - m3_ops.to_wait = mach_really_wait; - m3_ops.to_fetch_registers = fetch_inferior_registers; - m3_ops.to_store_registers = store_inferior_registers; - m3_ops.to_prepare_to_store = m3_prepare_to_store; - m3_ops.to_xfer_memory = m3_xfer_memory; - m3_ops.to_files_info = m3_files_info; - m3_ops.to_insert_breakpoint = memory_insert_breakpoint; - m3_ops.to_remove_breakpoint = memory_remove_breakpoint; - m3_ops.to_terminal_init = terminal_init_inferior; - m3_ops.to_terminal_inferior = terminal_inferior; - m3_ops.to_terminal_ours_for_output = terminal_ours_for_output; - m3_ops.to_terminal_save_ours = terminal_save_ours; - m3_ops.to_terminal_ours = terminal_ours; - m3_ops.to_terminal_info = child_terminal_info; - m3_ops.to_kill = m3_kill_inferior; - m3_ops.to_create_inferior = m3_create_inferior; - m3_ops.to_mourn_inferior = m3_mourn_inferior; - m3_ops.to_can_run = m3_can_run; - m3_ops.to_stop = m3_stop; - m3_ops.to_pid_to_exec_file = m3_pid_to_exec_file; - m3_ops.to_stratum = process_stratum; - m3_ops.to_has_all_memory = 1; - m3_ops.to_has_memory = 1; - m3_ops.to_has_stack = 1; - m3_ops.to_has_registers = 1; - m3_ops.to_has_execution = 1; - m3_ops.to_magic = OPS_MAGIC; -} - -void -_initialize_m3_nat (void) -{ - kern_return_t ret; - - init_m3_ops (); - add_target (&m3_ops); - - ret = mach_port_allocate (mach_task_self (), - MACH_PORT_RIGHT_PORT_SET, - &inferior_wait_port_set); - if (ret != KERN_SUCCESS) - internal_error (__FILE__, __LINE__, - "initial port set %s", mach_error_string (ret)); - - /* mach_really_wait now waits for this */ - currently_waiting_for = inferior_wait_port_set; - - ret = netname_look_up (name_server_port, hostname, "MachID", &mid_server); - if (ret != KERN_SUCCESS) - { - mid_server = MACH_PORT_NULL; - - warning ("initialize machid: netname_lookup_up(MachID) : %s", - mach_error_string (ret)); - warning ("Some (most?) features disabled..."); - } - - mid_auth = mach_privileged_host_port (); - if (mid_auth == MACH_PORT_NULL) - mid_auth = mach_task_self (); - - obstack_init (port_chain_obstack); - - ret = mach_port_allocate (mach_task_self (), - MACH_PORT_RIGHT_RECEIVE, - &thread_exception_port); - CHK ("Creating thread_exception_port for single stepping", ret); - - ret = mach_port_insert_right (mach_task_self (), - thread_exception_port, - thread_exception_port, - MACH_MSG_TYPE_MAKE_SEND); - CHK ("Inserting send right to thread_exception_port", ret); - - /* Allocate message port */ - ret = mach_port_allocate (mach_task_self (), - MACH_PORT_RIGHT_RECEIVE, - &our_message_port); - if (ret != KERN_SUCCESS) - warning ("Creating message port %s", mach_error_string (ret)); - else - { - char buf[MAX_NAME_LEN]; - ret = mach_port_move_member (mach_task_self (), - our_message_port, - inferior_wait_port_set); - if (ret != KERN_SUCCESS) - warning ("message move member %s", mach_error_string (ret)); - - - /* @@@@ No way to change message port name currently */ - /* Foo. This assumes gdb has a unix pid */ - sprintf (buf, "gdb-%d", getpid ()); - gdb_register_port (buf, our_message_port); - } - - /* Heap for thread commands */ - obstack_init (cproc_obstack); - - add_mach_specific_commands (); -} +// OBSOLETE /* Interface GDB to Mach 3.0 operating systems. +// OBSOLETE (Most) Mach 3.0 related routines live in this file. +// OBSOLETE +// OBSOLETE Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +// OBSOLETE 2002 Free Software Foundation, Inc. +// OBSOLETE +// OBSOLETE This file is part of GDB. +// OBSOLETE +// OBSOLETE This program is free software; you can redistribute it and/or modify +// OBSOLETE it under the terms of the GNU General Public License as published by +// OBSOLETE the Free Software Foundation; either version 2 of the License, or +// OBSOLETE (at your option) any later version. +// OBSOLETE +// OBSOLETE This program is distributed in the hope that it will be useful, +// OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of +// OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// OBSOLETE GNU General Public License for more details. +// OBSOLETE +// OBSOLETE You should have received a copy of the GNU General Public License +// OBSOLETE along with this program; if not, write to the Free Software +// OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, +// OBSOLETE Boston, MA 02111-1307, USA. */ +// OBSOLETE +// OBSOLETE /* +// OBSOLETE * Author: Jukka Virtanen <jtv@hut.fi> +// OBSOLETE * Computing Centre +// OBSOLETE * Helsinki University of Technology +// OBSOLETE * Finland +// OBSOLETE * +// OBSOLETE * Thanks to my friends who helped with ideas and testing: +// OBSOLETE * +// OBSOLETE * Johannes Helander, Antti Louko, Tero Mononen, +// OBSOLETE * jvh@cs.hut.fi alo@hut.fi tmo@cs.hut.fi +// OBSOLETE * +// OBSOLETE * Tero Kivinen and Eamonn McManus +// OBSOLETE * kivinen@cs.hut.fi emcmanus@gr.osf.org +// OBSOLETE * +// OBSOLETE */ +// OBSOLETE +// OBSOLETE #include <stdio.h> +// OBSOLETE +// OBSOLETE #include <mach.h> +// OBSOLETE #include <servers/netname.h> +// OBSOLETE #include <servers/machid.h> +// OBSOLETE #include <mach/message.h> +// OBSOLETE #include <mach/notify.h> +// OBSOLETE #include <mach_error.h> +// OBSOLETE #include <mach/exception.h> +// OBSOLETE #include <mach/vm_attributes.h> +// OBSOLETE +// OBSOLETE #include "defs.h" +// OBSOLETE #include "inferior.h" +// OBSOLETE #include "symtab.h" +// OBSOLETE #include "value.h" +// OBSOLETE #include "language.h" +// OBSOLETE #include "target.h" +// OBSOLETE #include "gdb_wait.h" +// OBSOLETE #include "gdbcmd.h" +// OBSOLETE #include "gdbcore.h" +// OBSOLETE #include "regcache.h" +// OBSOLETE +// OBSOLETE #if 0 +// OBSOLETE #include <servers/machid_lib.h> +// OBSOLETE #else +// OBSOLETE #define MACH_TYPE_TASK 1 +// OBSOLETE #define MACH_TYPE_THREAD 2 +// OBSOLETE #endif +// OBSOLETE +// OBSOLETE /* Included only for signal names and NSIG +// OBSOLETE +// OBSOLETE * note: There are many problems in signal handling with +// OBSOLETE * gdb in Mach 3.0 in general. +// OBSOLETE */ +// OBSOLETE #include <signal.h> +// OBSOLETE #define SIG_UNKNOWN 0 /* Exception that has no matching unix signal */ +// OBSOLETE +// OBSOLETE #include <cthreads.h> +// OBSOLETE +// OBSOLETE /* This is what a cproc looks like. This is here partly because +// OBSOLETE cthread_internals.h is not a header we can just #include, partly with +// OBSOLETE an eye towards perhaps getting this to work with cross-debugging +// OBSOLETE someday. Best solution is if CMU publishes a real interface to this +// OBSOLETE stuff. */ +// OBSOLETE #define CPROC_NEXT_OFFSET 0 +// OBSOLETE #define CPROC_NEXT_SIZE (TARGET_PTR_BIT / HOST_CHAR_BIT) +// OBSOLETE #define CPROC_INCARNATION_OFFSET (CPROC_NEXT_OFFSET + CPROC_NEXT_SIZE) +// OBSOLETE #define CPROC_INCARNATION_SIZE (sizeof (cthread_t)) +// OBSOLETE #define CPROC_LIST_OFFSET (CPROC_INCARNATION_OFFSET + CPROC_INCARNATION_SIZE) +// OBSOLETE #define CPROC_LIST_SIZE (TARGET_PTR_BIT / HOST_CHAR_BIT) +// OBSOLETE #define CPROC_WAIT_OFFSET (CPROC_LIST_OFFSET + CPROC_LIST_SIZE) +// OBSOLETE #define CPROC_WAIT_SIZE (TARGET_PTR_BIT / HOST_CHAR_BIT) +// OBSOLETE #define CPROC_REPLY_OFFSET (CPROC_WAIT_OFFSET + CPROC_WAIT_SIZE) +// OBSOLETE #define CPROC_REPLY_SIZE (sizeof (mach_port_t)) +// OBSOLETE #define CPROC_CONTEXT_OFFSET (CPROC_REPLY_OFFSET + CPROC_REPLY_SIZE) +// OBSOLETE #define CPROC_CONTEXT_SIZE (TARGET_INT_BIT / HOST_CHAR_BIT) +// OBSOLETE #define CPROC_LOCK_OFFSET (CPROC_CONTEXT_OFFSET + CPROC_CONTEXT_SIZE) +// OBSOLETE #define CPROC_LOCK_SIZE (sizeof (spin_lock_t)) +// OBSOLETE #define CPROC_STATE_OFFSET (CPROC_LOCK_OFFSET + CPROC_LOCK_SIZE) +// OBSOLETE #define CPROC_STATE_SIZE (TARGET_INT_BIT / HOST_CHAR_BIT) +// OBSOLETE #define CPROC_WIRED_OFFSET (CPROC_STATE_OFFSET + CPROC_STATE_SIZE) +// OBSOLETE #define CPROC_WIRED_SIZE (sizeof (mach_port_t)) +// OBSOLETE #define CPROC_BUSY_OFFSET (CPROC_WIRED_OFFSET + CPROC_WIRED_SIZE) +// OBSOLETE #define CPROC_BUSY_SIZE (TARGET_INT_BIT / HOST_CHAR_BIT) +// OBSOLETE #define CPROC_MSG_OFFSET (CPROC_BUSY_OFFSET + CPROC_BUSY_SIZE) +// OBSOLETE #define CPROC_MSG_SIZE (sizeof (mach_msg_header_t)) +// OBSOLETE #define CPROC_BASE_OFFSET (CPROC_MSG_OFFSET + CPROC_MSG_SIZE) +// OBSOLETE #define CPROC_BASE_SIZE (TARGET_INT_BIT / HOST_CHAR_BIT) +// OBSOLETE #define CPROC_SIZE_OFFSET (CPROC_BASE_OFFSET + CPROC_BASE_SIZE) +// OBSOLETE #define CPROC_SIZE_SIZE (TARGET_INT_BIT / HOST_CHAR_BIT) +// OBSOLETE #define CPROC_SIZE (CPROC_SIZE_OFFSET + CPROC_SIZE_SIZE) +// OBSOLETE +// OBSOLETE /* Values for the state field in the cproc. */ +// OBSOLETE #define CPROC_RUNNING 0 +// OBSOLETE #define CPROC_SWITCHING 1 +// OBSOLETE #define CPROC_BLOCKED 2 +// OBSOLETE #define CPROC_CONDWAIT 4 +// OBSOLETE +// OBSOLETE /* For cproc and kernel thread mapping */ +// OBSOLETE typedef struct gdb_thread +// OBSOLETE { +// OBSOLETE mach_port_t name; +// OBSOLETE CORE_ADDR sp; +// OBSOLETE CORE_ADDR pc; +// OBSOLETE CORE_ADDR fp; +// OBSOLETE boolean_t in_emulator; +// OBSOLETE int slotid; +// OBSOLETE +// OBSOLETE /* This is for the mthreads list. It points to the cproc list. +// OBSOLETE Perhaps the two lists should be merged (or perhaps it was a mistake +// OBSOLETE to make them both use a struct gdb_thread). */ +// OBSOLETE struct gdb_thread *cproc; +// OBSOLETE +// OBSOLETE /* These are for the cproc list, which is linked through the next field +// OBSOLETE of the struct gdb_thread. */ +// OBSOLETE char raw_cproc[CPROC_SIZE]; +// OBSOLETE /* The cthread which is pointed to by the incarnation field from the +// OBSOLETE cproc. This points to the copy we've read into GDB. */ +// OBSOLETE cthread_t cthread; +// OBSOLETE /* Point back to the mthreads list. */ +// OBSOLETE int reverse_map; +// OBSOLETE struct gdb_thread *next; +// OBSOLETE } +// OBSOLETE *gdb_thread_t; +// OBSOLETE +// OBSOLETE /* +// OBSOLETE * Actions for Mach exceptions. +// OBSOLETE * +// OBSOLETE * sigmap field maps the exception to corresponding Unix signal. +// OBSOLETE * +// OBSOLETE * I do not know how to map the exception to unix signal +// OBSOLETE * if SIG_UNKNOWN is specified. +// OBSOLETE */ +// OBSOLETE +// OBSOLETE struct exception_list +// OBSOLETE { +// OBSOLETE char *name; +// OBSOLETE boolean_t forward; +// OBSOLETE boolean_t print; +// OBSOLETE int sigmap; +// OBSOLETE } +// OBSOLETE exception_map[] = +// OBSOLETE { +// OBSOLETE { +// OBSOLETE "not_mach3_exception", FALSE, TRUE, SIG_UNKNOWN +// OBSOLETE } +// OBSOLETE , +// OBSOLETE { +// OBSOLETE "EXC_BAD_ACCESS", FALSE, TRUE, SIGSEGV +// OBSOLETE } +// OBSOLETE , +// OBSOLETE { +// OBSOLETE "EXC_BAD_INSTRUCTION", FALSE, TRUE, SIGILL +// OBSOLETE } +// OBSOLETE , +// OBSOLETE { +// OBSOLETE "EXC_ARITHMETIC", FALSE, TRUE, SIGFPE +// OBSOLETE } +// OBSOLETE , +// OBSOLETE { +// OBSOLETE "EXC_EMULATION", FALSE, TRUE, SIGEMT +// OBSOLETE } +// OBSOLETE , /* ??? */ +// OBSOLETE { +// OBSOLETE "EXC_SOFTWARE", FALSE, TRUE, SIG_UNKNOWN +// OBSOLETE } +// OBSOLETE , +// OBSOLETE { +// OBSOLETE "EXC_BREAKPOINT", FALSE, FALSE, SIGTRAP +// OBSOLETE } +// OBSOLETE }; +// OBSOLETE +// OBSOLETE /* Mach exception table size */ +// OBSOLETE int max_exception = sizeof (exception_map) / sizeof (struct exception_list) - 1; +// OBSOLETE +// OBSOLETE #define MAX_EXCEPTION max_exception +// OBSOLETE +// OBSOLETE WAITTYPE wait_status; +// OBSOLETE +// OBSOLETE /* If you define this, intercepted bsd server calls will be +// OBSOLETE * dumped while waiting the inferior to EXEC the correct +// OBSOLETE * program +// OBSOLETE */ +// OBSOLETE /* #define DUMP_SYSCALL /* debugging interceptor */ +// OBSOLETE +// OBSOLETE /* xx_debug() outputs messages if this is nonzero. +// OBSOLETE * If > 1, DUMP_SYSCALL will dump message contents. +// OBSOLETE */ +// OBSOLETE int debug_level = 0; +// OBSOLETE +// OBSOLETE /* "Temporary" debug stuff */ +// OBSOLETE void +// OBSOLETE xx_debug (char *fmt, int a, int b, int c) +// OBSOLETE { +// OBSOLETE if (debug_level) +// OBSOLETE warning (fmt, a, b, c); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* This is in libmach.a */ +// OBSOLETE extern mach_port_t name_server_port; +// OBSOLETE +// OBSOLETE /* Set in catch_exception_raise */ +// OBSOLETE int stop_exception, stop_code, stop_subcode; +// OBSOLETE int stopped_in_exception; +// OBSOLETE +// OBSOLETE /* Thread that was the active thread when we stopped */ +// OBSOLETE thread_t stop_thread = MACH_PORT_NULL; +// OBSOLETE +// OBSOLETE char *hostname = ""; +// OBSOLETE +// OBSOLETE /* Set when task is attached or created */ +// OBSOLETE boolean_t emulator_present = FALSE; +// OBSOLETE +// OBSOLETE task_t inferior_task; +// OBSOLETE thread_t current_thread; +// OBSOLETE +// OBSOLETE /* Exception ports for inferior task */ +// OBSOLETE mach_port_t inferior_exception_port = MACH_PORT_NULL; +// OBSOLETE mach_port_t inferior_old_exception_port = MACH_PORT_NULL; +// OBSOLETE +// OBSOLETE /* task exceptions and notifications */ +// OBSOLETE mach_port_t inferior_wait_port_set = MACH_PORT_NULL; +// OBSOLETE mach_port_t our_notify_port = MACH_PORT_NULL; +// OBSOLETE +// OBSOLETE /* This is "inferior_wait_port_set" when not single stepping, and +// OBSOLETE * "singlestepped_thread_port" when we are single stepping. +// OBSOLETE * +// OBSOLETE * This is protected by a cleanup function: discard_single_step() +// OBSOLETE */ +// OBSOLETE mach_port_t currently_waiting_for = MACH_PORT_NULL; +// OBSOLETE +// OBSOLETE /* A port for external messages to gdb. +// OBSOLETE * External in the meaning that they do not come +// OBSOLETE * from the inferior_task, but rather from external +// OBSOLETE * tasks. +// OBSOLETE * +// OBSOLETE * As a debugging feature: +// OBSOLETE * A debugger debugging another debugger can stop the +// OBSOLETE * inferior debugger by the following command sequence +// OBSOLETE * (without running external programs) +// OBSOLETE * +// OBSOLETE * (top-gdb) set stop_inferior_gdb () +// OBSOLETE * (top-gdb) continue +// OBSOLETE */ +// OBSOLETE mach_port_t our_message_port = MACH_PORT_NULL; +// OBSOLETE +// OBSOLETE /* For single stepping */ +// OBSOLETE mach_port_t thread_exception_port = MACH_PORT_NULL; +// OBSOLETE mach_port_t thread_saved_exception_port = MACH_PORT_NULL; +// OBSOLETE mach_port_t singlestepped_thread_port = MACH_PORT_NULL; +// OBSOLETE +// OBSOLETE /* For machid calls */ +// OBSOLETE mach_port_t mid_server = MACH_PORT_NULL; +// OBSOLETE mach_port_t mid_auth = MACH_PORT_NULL; +// OBSOLETE +// OBSOLETE /* If gdb thinks the inferior task is not suspended, it +// OBSOLETE * must take suspend/abort the threads when it reads the state. +// OBSOLETE */ +// OBSOLETE int must_suspend_thread = 0; +// OBSOLETE +// OBSOLETE /* When single stepping, we switch the port that mach_really_wait() listens to. +// OBSOLETE * This cleanup is a guard to prevent the port set from being left to +// OBSOLETE * the singlestepped_thread_port when error() is called. +// OBSOLETE * This is nonzero only when we are single stepping. +// OBSOLETE */ +// OBSOLETE #define NULL_CLEANUP (struct cleanup *)0 +// OBSOLETE struct cleanup *cleanup_step = NULL_CLEANUP; +// OBSOLETE +// OBSOLETE +// OBSOLETE static struct target_ops m3_ops; +// OBSOLETE +// OBSOLETE static void m3_kill_inferior (); +// OBSOLETE +// OBSOLETE #if 0 +// OBSOLETE #define MACH_TYPE_EXCEPTION_PORT -1 +// OBSOLETE #endif +// OBSOLETE +// OBSOLETE /* Chain of ports to remember requested notifications. */ +// OBSOLETE +// OBSOLETE struct port_chain +// OBSOLETE { +// OBSOLETE struct port_chain *next; +// OBSOLETE mach_port_t port; +// OBSOLETE int type; +// OBSOLETE int mid; /* Now only valid with MACH_TYPE_THREAD and */ +// OBSOLETE /* MACH_TYPE_THREAD */ +// OBSOLETE }; +// OBSOLETE typedef struct port_chain *port_chain_t; +// OBSOLETE +// OBSOLETE /* Room for chain nodes comes from pchain_obstack */ +// OBSOLETE struct obstack pchain_obstack; +// OBSOLETE struct obstack *port_chain_obstack = &pchain_obstack; +// OBSOLETE +// OBSOLETE /* For thread handling */ +// OBSOLETE struct obstack Cproc_obstack; +// OBSOLETE struct obstack *cproc_obstack = &Cproc_obstack; +// OBSOLETE +// OBSOLETE /* the list of notified ports */ +// OBSOLETE port_chain_t notify_chain = (port_chain_t) NULL; +// OBSOLETE +// OBSOLETE port_chain_t +// OBSOLETE port_chain_insert (port_chain_t list, mach_port_t name, int type) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE port_chain_t new; +// OBSOLETE int mid; +// OBSOLETE +// OBSOLETE if (!MACH_PORT_VALID (name)) +// OBSOLETE return list; +// OBSOLETE +// OBSOLETE if (type == MACH_TYPE_TASK || type == MACH_TYPE_THREAD) +// OBSOLETE { +// OBSOLETE if (!MACH_PORT_VALID (mid_server)) +// OBSOLETE { +// OBSOLETE warning ("Machid server port invalid, can not map port 0x%x to MID", +// OBSOLETE name); +// OBSOLETE mid = name; +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE ret = machid_mach_register (mid_server, mid_auth, name, type, &mid); +// OBSOLETE +// OBSOLETE if (ret != KERN_SUCCESS) +// OBSOLETE { +// OBSOLETE warning ("Can not map name (0x%x) to MID with machid", name); +// OBSOLETE mid = name; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE } +// OBSOLETE else +// OBSOLETE internal_error (__FILE__, __LINE__, "failed internal consistency check"); +// OBSOLETE +// OBSOLETE new = (port_chain_t) obstack_alloc (port_chain_obstack, +// OBSOLETE sizeof (struct port_chain)); +// OBSOLETE new->next = list; +// OBSOLETE new->port = name; +// OBSOLETE new->type = type; +// OBSOLETE new->mid = mid; +// OBSOLETE +// OBSOLETE return new; +// OBSOLETE } +// OBSOLETE +// OBSOLETE port_chain_t +// OBSOLETE port_chain_delete (port_chain_t list, mach_port_t elem) +// OBSOLETE { +// OBSOLETE if (list) +// OBSOLETE if (list->port == elem) +// OBSOLETE list = list->next; +// OBSOLETE else +// OBSOLETE while (list->next) +// OBSOLETE { +// OBSOLETE if (list->next->port == elem) +// OBSOLETE list->next = list->next->next; /* GCd with obstack_free() */ +// OBSOLETE else +// OBSOLETE list = list->next; +// OBSOLETE } +// OBSOLETE return list; +// OBSOLETE } +// OBSOLETE +// OBSOLETE void +// OBSOLETE port_chain_destroy (struct obstack *ostack) +// OBSOLETE { +// OBSOLETE obstack_free (ostack, 0); +// OBSOLETE obstack_init (ostack); +// OBSOLETE } +// OBSOLETE +// OBSOLETE port_chain_t +// OBSOLETE port_chain_member (port_chain_t list, mach_port_t elem) +// OBSOLETE { +// OBSOLETE while (list) +// OBSOLETE { +// OBSOLETE if (list->port == elem) +// OBSOLETE return list; +// OBSOLETE list = list->next; +// OBSOLETE } +// OBSOLETE return (port_chain_t) NULL; +// OBSOLETE } +// OBSOLETE +// OBSOLETE int +// OBSOLETE map_port_name_to_mid (mach_port_t name, int type) +// OBSOLETE { +// OBSOLETE port_chain_t elem; +// OBSOLETE +// OBSOLETE if (!MACH_PORT_VALID (name)) +// OBSOLETE return -1; +// OBSOLETE +// OBSOLETE elem = port_chain_member (notify_chain, name); +// OBSOLETE +// OBSOLETE if (elem && (elem->type == type)) +// OBSOLETE return elem->mid; +// OBSOLETE +// OBSOLETE if (elem) +// OBSOLETE return -1; +// OBSOLETE +// OBSOLETE if (!MACH_PORT_VALID (mid_server)) +// OBSOLETE { +// OBSOLETE warning ("Machid server port invalid, can not map port 0x%x to mid", +// OBSOLETE name); +// OBSOLETE return -1; +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE int mid; +// OBSOLETE kern_return_t ret; +// OBSOLETE +// OBSOLETE ret = machid_mach_register (mid_server, mid_auth, name, type, &mid); +// OBSOLETE +// OBSOLETE if (ret != KERN_SUCCESS) +// OBSOLETE { +// OBSOLETE warning ("Can not map name (0x%x) to mid with machid", name); +// OBSOLETE return -1; +// OBSOLETE } +// OBSOLETE return mid; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Guard for currently_waiting_for and singlestepped_thread_port */ +// OBSOLETE static void +// OBSOLETE discard_single_step (thread_t thread) +// OBSOLETE { +// OBSOLETE currently_waiting_for = inferior_wait_port_set; +// OBSOLETE +// OBSOLETE cleanup_step = NULL_CLEANUP; +// OBSOLETE if (MACH_PORT_VALID (thread) && MACH_PORT_VALID (singlestepped_thread_port)) +// OBSOLETE setup_single_step (thread, FALSE); +// OBSOLETE } +// OBSOLETE +// OBSOLETE setup_single_step (thread_t thread, boolean_t start_step) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE +// OBSOLETE if (!MACH_PORT_VALID (thread)) +// OBSOLETE error ("Invalid thread supplied to setup_single_step"); +// OBSOLETE else +// OBSOLETE { +// OBSOLETE mach_port_t teport; +// OBSOLETE +// OBSOLETE /* Get the current thread exception port */ +// OBSOLETE ret = thread_get_exception_port (thread, &teport); +// OBSOLETE CHK ("Getting thread's exception port", ret); +// OBSOLETE +// OBSOLETE if (start_step) +// OBSOLETE { +// OBSOLETE if (MACH_PORT_VALID (singlestepped_thread_port)) +// OBSOLETE { +// OBSOLETE warning ("Singlestepped_thread_port (0x%x) is still valid?", +// OBSOLETE singlestepped_thread_port); +// OBSOLETE singlestepped_thread_port = MACH_PORT_NULL; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* If we are already stepping this thread */ +// OBSOLETE if (MACH_PORT_VALID (teport) && teport == thread_exception_port) +// OBSOLETE { +// OBSOLETE ret = mach_port_deallocate (mach_task_self (), teport); +// OBSOLETE CHK ("Could not deallocate thread exception port", ret); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE ret = thread_set_exception_port (thread, thread_exception_port); +// OBSOLETE CHK ("Setting exception port for thread", ret); +// OBSOLETE #if 0 +// OBSOLETE /* Insert thread exception port to wait port set */ +// OBSOLETE ret = mach_port_move_member (mach_task_self (), +// OBSOLETE thread_exception_port, +// OBSOLETE inferior_wait_port_set); +// OBSOLETE CHK ("Moving thread exception port to inferior_wait_port_set", +// OBSOLETE ret); +// OBSOLETE #endif +// OBSOLETE thread_saved_exception_port = teport; +// OBSOLETE } +// OBSOLETE +// OBSOLETE thread_trace (thread, TRUE); +// OBSOLETE +// OBSOLETE singlestepped_thread_port = thread_exception_port; +// OBSOLETE currently_waiting_for = singlestepped_thread_port; +// OBSOLETE cleanup_step = make_cleanup (discard_single_step, thread); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE if (!MACH_PORT_VALID (teport)) +// OBSOLETE error ("Single stepped thread had an invalid exception port?"); +// OBSOLETE +// OBSOLETE if (teport != thread_exception_port) +// OBSOLETE error ("Single stepped thread had an unknown exception port?"); +// OBSOLETE +// OBSOLETE ret = mach_port_deallocate (mach_task_self (), teport); +// OBSOLETE CHK ("Couldn't deallocate thread exception port", ret); +// OBSOLETE #if 0 +// OBSOLETE /* Remove thread exception port from wait port set */ +// OBSOLETE ret = mach_port_move_member (mach_task_self (), +// OBSOLETE thread_exception_port, +// OBSOLETE MACH_PORT_NULL); +// OBSOLETE CHK ("Removing thread exception port from inferior_wait_port_set", +// OBSOLETE ret); +// OBSOLETE #endif +// OBSOLETE /* Restore thread's old exception port */ +// OBSOLETE ret = thread_set_exception_port (thread, +// OBSOLETE thread_saved_exception_port); +// OBSOLETE CHK ("Restoring stepped thread's exception port", ret); +// OBSOLETE +// OBSOLETE if (MACH_PORT_VALID (thread_saved_exception_port)) +// OBSOLETE (void) mach_port_deallocate (mach_task_self (), +// OBSOLETE thread_saved_exception_port); +// OBSOLETE +// OBSOLETE thread_trace (thread, FALSE); +// OBSOLETE +// OBSOLETE singlestepped_thread_port = MACH_PORT_NULL; +// OBSOLETE currently_waiting_for = inferior_wait_port_set; +// OBSOLETE if (cleanup_step) +// OBSOLETE discard_cleanups (cleanup_step); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE static +// OBSOLETE request_notify (mach_port_t name, mach_msg_id_t variant, int type) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE mach_port_t previous_port_dummy = MACH_PORT_NULL; +// OBSOLETE +// OBSOLETE if (!MACH_PORT_VALID (name)) +// OBSOLETE return; +// OBSOLETE +// OBSOLETE if (port_chain_member (notify_chain, name)) +// OBSOLETE return; +// OBSOLETE +// OBSOLETE ret = mach_port_request_notification (mach_task_self (), +// OBSOLETE name, +// OBSOLETE variant, +// OBSOLETE 1, +// OBSOLETE our_notify_port, +// OBSOLETE MACH_MSG_TYPE_MAKE_SEND_ONCE, +// OBSOLETE &previous_port_dummy); +// OBSOLETE CHK ("Serious: request_notify failed", ret); +// OBSOLETE +// OBSOLETE (void) mach_port_deallocate (mach_task_self (), +// OBSOLETE previous_port_dummy); +// OBSOLETE +// OBSOLETE notify_chain = port_chain_insert (notify_chain, name, type); +// OBSOLETE } +// OBSOLETE +// OBSOLETE reverse_msg_bits (mach_msg_header_t *msgp, int type) +// OBSOLETE { +// OBSOLETE int rbits, lbits; +// OBSOLETE rbits = MACH_MSGH_BITS_REMOTE (msgp->msgh_bits); +// OBSOLETE lbits = type; +// OBSOLETE msgp->msgh_bits = +// OBSOLETE (msgp->msgh_bits & ~MACH_MSGH_BITS_PORTS_MASK) | +// OBSOLETE MACH_MSGH_BITS (lbits, rbits); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* On the third day He said: +// OBSOLETE +// OBSOLETE Let this be global +// OBSOLETE and then it was global. +// OBSOLETE +// OBSOLETE When creating the inferior fork, the +// OBSOLETE child code in inflow.c sets the name of the +// OBSOLETE bootstrap_port in its address space to this +// OBSOLETE variable. +// OBSOLETE +// OBSOLETE The name is transferred to our address space +// OBSOLETE with mach3_read_inferior(). +// OBSOLETE +// OBSOLETE Thou shalt not do this with +// OBSOLETE task_get_bootstrap_port() in this task, since +// OBSOLETE the name in the inferior task is different than +// OBSOLETE the one we get. +// OBSOLETE +// OBSOLETE For blessed are the meek, as they shall inherit +// OBSOLETE the address space. +// OBSOLETE */ +// OBSOLETE mach_port_t original_server_port_name = MACH_PORT_NULL; +// OBSOLETE +// OBSOLETE +// OBSOLETE /* Called from inferior after FORK but before EXEC */ +// OBSOLETE static void +// OBSOLETE m3_trace_me (void) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE +// OBSOLETE /* Get the NAME of the bootstrap port in this task +// OBSOLETE so that GDB can read it */ +// OBSOLETE ret = task_get_bootstrap_port (mach_task_self (), +// OBSOLETE &original_server_port_name); +// OBSOLETE if (ret != KERN_SUCCESS) +// OBSOLETE internal_error (__FILE__, __LINE__, "failed internal consistency check"); +// OBSOLETE ret = mach_port_deallocate (mach_task_self (), +// OBSOLETE original_server_port_name); +// OBSOLETE if (ret != KERN_SUCCESS) +// OBSOLETE internal_error (__FILE__, __LINE__, "failed internal consistency check"); +// OBSOLETE +// OBSOLETE /* Suspend this task to let the parent change my ports. +// OBSOLETE Resumed by the debugger */ +// OBSOLETE ret = task_suspend (mach_task_self ()); +// OBSOLETE if (ret != KERN_SUCCESS) +// OBSOLETE internal_error (__FILE__, __LINE__, "failed internal consistency check"); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* +// OBSOLETE * Intercept system calls to Unix server. +// OBSOLETE * After EXEC_COUNTER calls to exec(), return. +// OBSOLETE * +// OBSOLETE * Pre-assertion: Child is suspended. (Not verified) +// OBSOLETE * Post-condition: Child is suspended after EXEC_COUNTER exec() calls. +// OBSOLETE */ +// OBSOLETE +// OBSOLETE void +// OBSOLETE intercept_exec_calls (int exec_counter) +// OBSOLETE { +// OBSOLETE int terminal_initted = 0; +// OBSOLETE +// OBSOLETE struct syscall_msg_t +// OBSOLETE { +// OBSOLETE mach_msg_header_t header; +// OBSOLETE mach_msg_type_t type; +// OBSOLETE char room[2000]; /* Enuff space */ +// OBSOLETE }; +// OBSOLETE +// OBSOLETE struct syscall_msg_t syscall_in, syscall_out; +// OBSOLETE +// OBSOLETE mach_port_t fake_server; +// OBSOLETE mach_port_t original_server_send; +// OBSOLETE mach_port_t original_exec_reply; +// OBSOLETE mach_port_t exec_reply; +// OBSOLETE mach_port_t exec_reply_send; +// OBSOLETE mach_msg_type_name_t acquired; +// OBSOLETE mach_port_t emulator_server_port_name; +// OBSOLETE struct task_basic_info info; +// OBSOLETE mach_msg_type_number_t info_count; +// OBSOLETE +// OBSOLETE kern_return_t ret; +// OBSOLETE +// OBSOLETE if (exec_counter <= 0) +// OBSOLETE return; /* We are already set up in the correct program */ +// OBSOLETE +// OBSOLETE ret = mach_port_allocate (mach_task_self (), +// OBSOLETE MACH_PORT_RIGHT_RECEIVE, +// OBSOLETE &fake_server); +// OBSOLETE CHK ("create inferior_fake_server port failed", ret); +// OBSOLETE +// OBSOLETE /* Wait for inferior_task to suspend itself */ +// OBSOLETE while (1) +// OBSOLETE { +// OBSOLETE info_count = sizeof (info); +// OBSOLETE ret = task_info (inferior_task, +// OBSOLETE TASK_BASIC_INFO, +// OBSOLETE (task_info_t) & info, +// OBSOLETE &info_count); +// OBSOLETE CHK ("Task info", ret); +// OBSOLETE +// OBSOLETE if (info.suspend_count) +// OBSOLETE break; +// OBSOLETE +// OBSOLETE /* Note that the definition of the parameter was undefined +// OBSOLETE * at the time of this writing, so I just use an `ad hoc' value. +// OBSOLETE */ +// OBSOLETE (void) swtch_pri (42); /* Universal Priority Value */ +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Read the inferior's bootstrap port name */ +// OBSOLETE if (!mach3_read_inferior (&original_server_port_name, +// OBSOLETE &original_server_port_name, +// OBSOLETE sizeof (original_server_port_name))) +// OBSOLETE error ("Can't read inferior task bootstrap port name"); +// OBSOLETE +// OBSOLETE /* @@ BUG: If more than 1 send right GDB will FAIL!!! */ +// OBSOLETE /* Should get refs, and set them back when restoring */ +// OBSOLETE /* Steal the original bsd server send right from inferior */ +// OBSOLETE ret = mach_port_extract_right (inferior_task, +// OBSOLETE original_server_port_name, +// OBSOLETE MACH_MSG_TYPE_MOVE_SEND, +// OBSOLETE &original_server_send, +// OBSOLETE &acquired); +// OBSOLETE CHK ("mach_port_extract_right (bsd server send)", ret); +// OBSOLETE +// OBSOLETE if (acquired != MACH_MSG_TYPE_PORT_SEND) +// OBSOLETE error ("Incorrect right extracted, send right to bsd server expected"); +// OBSOLETE +// OBSOLETE ret = mach_port_insert_right (inferior_task, +// OBSOLETE original_server_port_name, +// OBSOLETE fake_server, +// OBSOLETE MACH_MSG_TYPE_MAKE_SEND); +// OBSOLETE CHK ("mach_port_insert_right (fake server send)", ret); +// OBSOLETE +// OBSOLETE xx_debug ("inferior task bsd server ports set up \nfs %x, ospn %x, oss %x\n", +// OBSOLETE fake_server, +// OBSOLETE original_server_port_name, original_server_send); +// OBSOLETE +// OBSOLETE /* A receive right to the reply generated by unix server exec() request */ +// OBSOLETE ret = mach_port_allocate (mach_task_self (), +// OBSOLETE MACH_PORT_RIGHT_RECEIVE, +// OBSOLETE &exec_reply); +// OBSOLETE CHK ("create intercepted_reply_port port failed", ret); +// OBSOLETE +// OBSOLETE /* Pass this send right to Unix server so it replies to us after exec() */ +// OBSOLETE ret = mach_port_extract_right (mach_task_self (), +// OBSOLETE exec_reply, +// OBSOLETE MACH_MSG_TYPE_MAKE_SEND_ONCE, +// OBSOLETE &exec_reply_send, +// OBSOLETE &acquired); +// OBSOLETE CHK ("mach_port_extract_right (exec_reply)", ret); +// OBSOLETE +// OBSOLETE if (acquired != MACH_MSG_TYPE_PORT_SEND_ONCE) +// OBSOLETE error ("Incorrect right extracted, send once expected for exec reply"); +// OBSOLETE +// OBSOLETE ret = mach_port_move_member (mach_task_self (), +// OBSOLETE fake_server, +// OBSOLETE inferior_wait_port_set); +// OBSOLETE CHK ("Moving fake syscall port to inferior_wait_port_set", ret); +// OBSOLETE +// OBSOLETE xx_debug ("syscall fake server set up, resuming inferior\n"); +// OBSOLETE +// OBSOLETE ret = task_resume (inferior_task); +// OBSOLETE CHK ("task_resume (startup)", ret); +// OBSOLETE +// OBSOLETE /* Read requests from the inferior. +// OBSOLETE Pass directly through everything else except exec() calls. +// OBSOLETE */ +// OBSOLETE while (exec_counter > 0) +// OBSOLETE { +// OBSOLETE ret = mach_msg (&syscall_in.header, /* header */ +// OBSOLETE MACH_RCV_MSG, /* options */ +// OBSOLETE 0, /* send size */ +// OBSOLETE sizeof (struct syscall_msg_t), /* receive size */ +// OBSOLETE inferior_wait_port_set, /* receive_name */ +// OBSOLETE MACH_MSG_TIMEOUT_NONE, +// OBSOLETE MACH_PORT_NULL); +// OBSOLETE CHK ("mach_msg (intercepted sycall)", ret); +// OBSOLETE +// OBSOLETE #ifdef DUMP_SYSCALL +// OBSOLETE print_msg (&syscall_in.header); +// OBSOLETE #endif +// OBSOLETE +// OBSOLETE /* ASSERT : msgh_local_port == fake_server */ +// OBSOLETE +// OBSOLETE if (notify_server (&syscall_in.header, &syscall_out.header)) +// OBSOLETE error ("received a notify while intercepting syscalls"); +// OBSOLETE +// OBSOLETE if (syscall_in.header.msgh_id == MIG_EXEC_SYSCALL_ID) +// OBSOLETE { +// OBSOLETE xx_debug ("Received EXEC SYSCALL, counter = %d\n", exec_counter); +// OBSOLETE if (exec_counter == 1) +// OBSOLETE { +// OBSOLETE original_exec_reply = syscall_in.header.msgh_remote_port; +// OBSOLETE syscall_in.header.msgh_remote_port = exec_reply_send; +// OBSOLETE } +// OBSOLETE +// OBSOLETE if (!terminal_initted) +// OBSOLETE { +// OBSOLETE /* Now that the child has exec'd we know it has already set its +// OBSOLETE process group. On POSIX systems, tcsetpgrp will fail with +// OBSOLETE EPERM if we try it before the child's setpgid. */ +// OBSOLETE +// OBSOLETE /* Set up the "saved terminal modes" of the inferior +// OBSOLETE based on what modes we are starting it with. */ +// OBSOLETE target_terminal_init (); +// OBSOLETE +// OBSOLETE /* Install inferior's terminal modes. */ +// OBSOLETE target_terminal_inferior (); +// OBSOLETE +// OBSOLETE terminal_initted = 1; +// OBSOLETE } +// OBSOLETE +// OBSOLETE exec_counter--; +// OBSOLETE } +// OBSOLETE +// OBSOLETE syscall_in.header.msgh_local_port = syscall_in.header.msgh_remote_port; +// OBSOLETE syscall_in.header.msgh_remote_port = original_server_send; +// OBSOLETE +// OBSOLETE reverse_msg_bits (&syscall_in.header, MACH_MSG_TYPE_COPY_SEND); +// OBSOLETE +// OBSOLETE ret = mach_msg_send (&syscall_in.header); +// OBSOLETE CHK ("Forwarded syscall", ret); +// OBSOLETE } +// OBSOLETE +// OBSOLETE ret = mach_port_move_member (mach_task_self (), +// OBSOLETE fake_server, +// OBSOLETE MACH_PORT_NULL); +// OBSOLETE CHK ("Moving fake syscall out of inferior_wait_port_set", ret); +// OBSOLETE +// OBSOLETE ret = mach_port_move_member (mach_task_self (), +// OBSOLETE exec_reply, +// OBSOLETE inferior_wait_port_set); +// OBSOLETE CHK ("Moving exec_reply to inferior_wait_port_set", ret); +// OBSOLETE +// OBSOLETE ret = mach_msg (&syscall_in.header, /* header */ +// OBSOLETE MACH_RCV_MSG, /* options */ +// OBSOLETE 0, /* send size */ +// OBSOLETE sizeof (struct syscall_msg_t), /* receive size */ +// OBSOLETE inferior_wait_port_set, /* receive_name */ +// OBSOLETE MACH_MSG_TIMEOUT_NONE, +// OBSOLETE MACH_PORT_NULL); +// OBSOLETE CHK ("mach_msg (exec reply)", ret); +// OBSOLETE +// OBSOLETE ret = task_suspend (inferior_task); +// OBSOLETE CHK ("Suspending inferior after last exec", ret); +// OBSOLETE +// OBSOLETE must_suspend_thread = 0; +// OBSOLETE +// OBSOLETE xx_debug ("Received exec reply from bsd server, suspended inferior task\n"); +// OBSOLETE +// OBSOLETE #ifdef DUMP_SYSCALL +// OBSOLETE print_msg (&syscall_in.header); +// OBSOLETE #endif +// OBSOLETE +// OBSOLETE /* Message should appear as if it came from the unix server */ +// OBSOLETE syscall_in.header.msgh_local_port = MACH_PORT_NULL; +// OBSOLETE +// OBSOLETE /* and go to the inferior task original reply port */ +// OBSOLETE syscall_in.header.msgh_remote_port = original_exec_reply; +// OBSOLETE +// OBSOLETE reverse_msg_bits (&syscall_in.header, MACH_MSG_TYPE_MOVE_SEND_ONCE); +// OBSOLETE +// OBSOLETE ret = mach_msg_send (&syscall_in.header); +// OBSOLETE CHK ("Forwarding exec reply to inferior", ret); +// OBSOLETE +// OBSOLETE /* Garbage collect */ +// OBSOLETE ret = mach_port_deallocate (inferior_task, +// OBSOLETE original_server_port_name); +// OBSOLETE CHK ("deallocating fake server send right", ret); +// OBSOLETE +// OBSOLETE ret = mach_port_insert_right (inferior_task, +// OBSOLETE original_server_port_name, +// OBSOLETE original_server_send, +// OBSOLETE MACH_MSG_TYPE_MOVE_SEND); +// OBSOLETE CHK ("Restoring the original bsd server send right", ret); +// OBSOLETE +// OBSOLETE ret = mach_port_destroy (mach_task_self (), +// OBSOLETE fake_server); +// OBSOLETE fake_server = MACH_PORT_DEAD; +// OBSOLETE CHK ("mach_port_destroy (fake_server)", ret); +// OBSOLETE +// OBSOLETE ret = mach_port_destroy (mach_task_self (), +// OBSOLETE exec_reply); +// OBSOLETE exec_reply = MACH_PORT_DEAD; +// OBSOLETE CHK ("mach_port_destroy (exec_reply)", ret); +// OBSOLETE +// OBSOLETE xx_debug ("Done with exec call interception\n"); +// OBSOLETE } +// OBSOLETE +// OBSOLETE void +// OBSOLETE consume_send_rights (thread_array_t thread_list, int thread_count) +// OBSOLETE { +// OBSOLETE int index; +// OBSOLETE +// OBSOLETE if (!thread_count) +// OBSOLETE return; +// OBSOLETE +// OBSOLETE for (index = 0; index < thread_count; index++) +// OBSOLETE { +// OBSOLETE /* Since thread kill command kills threads, don't check ret */ +// OBSOLETE (void) mach_port_deallocate (mach_task_self (), +// OBSOLETE thread_list[index]); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* suspend/abort/resume a thread. */ +// OBSOLETE setup_thread (mach_port_t thread, int what) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE +// OBSOLETE if (what) +// OBSOLETE { +// OBSOLETE ret = thread_suspend (thread); +// OBSOLETE CHK ("setup_thread thread_suspend", ret); +// OBSOLETE +// OBSOLETE ret = thread_abort (thread); +// OBSOLETE CHK ("setup_thread thread_abort", ret); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE ret = thread_resume (thread); +// OBSOLETE CHK ("setup_thread thread_resume", ret); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE int +// OBSOLETE map_slot_to_mid (int slot, thread_array_t threads, int thread_count) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE int deallocate = 0; +// OBSOLETE int index; +// OBSOLETE int mid; +// OBSOLETE +// OBSOLETE if (!threads) +// OBSOLETE { +// OBSOLETE deallocate++; +// OBSOLETE ret = task_threads (inferior_task, &threads, &thread_count); +// OBSOLETE CHK ("Can not select a thread from a dead task", ret); +// OBSOLETE } +// OBSOLETE +// OBSOLETE if (slot < 0 || slot >= thread_count) +// OBSOLETE { +// OBSOLETE if (deallocate) +// OBSOLETE { +// OBSOLETE consume_send_rights (threads, thread_count); +// OBSOLETE (void) vm_deallocate (mach_task_self (), (vm_address_t) threads, +// OBSOLETE (thread_count * sizeof (mach_port_t))); +// OBSOLETE } +// OBSOLETE if (slot < 0) +// OBSOLETE error ("invalid slot number"); +// OBSOLETE else +// OBSOLETE return -(slot + 1); +// OBSOLETE } +// OBSOLETE +// OBSOLETE mid = map_port_name_to_mid (threads[slot], MACH_TYPE_THREAD); +// OBSOLETE +// OBSOLETE if (deallocate) +// OBSOLETE { +// OBSOLETE consume_send_rights (threads, thread_count); +// OBSOLETE (void) vm_deallocate (mach_task_self (), (vm_address_t) threads, +// OBSOLETE (thread_count * sizeof (mach_port_t))); +// OBSOLETE } +// OBSOLETE +// OBSOLETE return mid; +// OBSOLETE } +// OBSOLETE +// OBSOLETE static int +// OBSOLETE parse_thread_id (char *arg, int thread_count, int slots) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE int mid; +// OBSOLETE int slot; +// OBSOLETE int index; +// OBSOLETE +// OBSOLETE if (arg == 0) +// OBSOLETE return 0; +// OBSOLETE +// OBSOLETE while (*arg && (*arg == ' ' || *arg == '\t')) +// OBSOLETE arg++; +// OBSOLETE +// OBSOLETE if (!*arg) +// OBSOLETE return 0; +// OBSOLETE +// OBSOLETE /* Currently parse MID and @SLOTNUMBER */ +// OBSOLETE if (*arg != '@') +// OBSOLETE { +// OBSOLETE mid = atoi (arg); +// OBSOLETE if (mid <= 0) +// OBSOLETE error ("valid thread mid expected"); +// OBSOLETE return mid; +// OBSOLETE } +// OBSOLETE +// OBSOLETE arg++; +// OBSOLETE slot = atoi (arg); +// OBSOLETE +// OBSOLETE if (slot < 0) +// OBSOLETE error ("invalid slot number"); +// OBSOLETE +// OBSOLETE /* If you want slot numbers to remain slot numbers, set slots. +// OBSOLETE +// OBSOLETE * Well, since 0 is reserved, return the ordinal number +// OBSOLETE * of the thread rather than the slot number. Awk, this +// OBSOLETE * counts as a kludge. +// OBSOLETE */ +// OBSOLETE if (slots) +// OBSOLETE return -(slot + 1); +// OBSOLETE +// OBSOLETE if (thread_count && slot >= thread_count) +// OBSOLETE return -(slot + 1); +// OBSOLETE +// OBSOLETE mid = map_slot_to_mid (slot); +// OBSOLETE +// OBSOLETE return mid; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* THREAD_ID 0 is special; it selects the first kernel +// OBSOLETE * thread from the list (i.e. SLOTNUMBER 0) +// OBSOLETE * This is used when starting the program with 'run' or when attaching. +// OBSOLETE * +// OBSOLETE * If FLAG is 0 the context is not changed, and the registers, frame, etc +// OBSOLETE * will continue to describe the old thread. +// OBSOLETE * +// OBSOLETE * If FLAG is nonzero, really select the thread. +// OBSOLETE * If FLAG is 2, the THREAD_ID is a slotnumber instead of a mid. +// OBSOLETE * +// OBSOLETE */ +// OBSOLETE kern_return_t +// OBSOLETE select_thread (mach_port_t task, int thread_id, int flag) +// OBSOLETE { +// OBSOLETE thread_array_t thread_list; +// OBSOLETE int thread_count; +// OBSOLETE kern_return_t ret; +// OBSOLETE int index; +// OBSOLETE thread_t new_thread = MACH_PORT_NULL; +// OBSOLETE +// OBSOLETE if (thread_id < 0) +// OBSOLETE error ("Can't select cprocs without kernel thread"); +// OBSOLETE +// OBSOLETE ret = task_threads (task, &thread_list, &thread_count); +// OBSOLETE if (ret != KERN_SUCCESS) +// OBSOLETE { +// OBSOLETE warning ("Can not select a thread from a dead task"); +// OBSOLETE m3_kill_inferior (); +// OBSOLETE return KERN_FAILURE; +// OBSOLETE } +// OBSOLETE +// OBSOLETE if (thread_count == 0) +// OBSOLETE { +// OBSOLETE /* The task can not do anything anymore, but it still +// OBSOLETE * exists as a container for memory and ports. +// OBSOLETE */ +// OBSOLETE registers_changed (); +// OBSOLETE warning ("Task %d has no threads", +// OBSOLETE map_port_name_to_mid (task, MACH_TYPE_TASK)); +// OBSOLETE current_thread = MACH_PORT_NULL; +// OBSOLETE (void) vm_deallocate (mach_task_self (), +// OBSOLETE (vm_address_t) thread_list, +// OBSOLETE (thread_count * sizeof (mach_port_t))); +// OBSOLETE return KERN_FAILURE; +// OBSOLETE } +// OBSOLETE +// OBSOLETE if (!thread_id || flag == 2) +// OBSOLETE { +// OBSOLETE /* First thread or a slotnumber */ +// OBSOLETE if (!thread_id) +// OBSOLETE new_thread = thread_list[0]; +// OBSOLETE else +// OBSOLETE { +// OBSOLETE if (thread_id < thread_count) +// OBSOLETE new_thread = thread_list[thread_id]; +// OBSOLETE else +// OBSOLETE { +// OBSOLETE (void) vm_deallocate (mach_task_self (), +// OBSOLETE (vm_address_t) thread_list, +// OBSOLETE (thread_count * sizeof (mach_port_t))); +// OBSOLETE error ("No such thread slot number : %d", thread_id); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE for (index = 0; index < thread_count; index++) +// OBSOLETE if (thread_id == map_port_name_to_mid (thread_list[index], +// OBSOLETE MACH_TYPE_THREAD)) +// OBSOLETE { +// OBSOLETE new_thread = thread_list[index]; +// OBSOLETE index = -1; +// OBSOLETE break; +// OBSOLETE } +// OBSOLETE +// OBSOLETE if (index != -1) +// OBSOLETE error ("No thread with mid %d", thread_id); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Notify when the selected thread dies */ +// OBSOLETE request_notify (new_thread, MACH_NOTIFY_DEAD_NAME, MACH_TYPE_THREAD); +// OBSOLETE +// OBSOLETE ret = vm_deallocate (mach_task_self (), +// OBSOLETE (vm_address_t) thread_list, +// OBSOLETE (thread_count * sizeof (mach_port_t))); +// OBSOLETE CHK ("vm_deallocate", ret); +// OBSOLETE +// OBSOLETE if (!flag) +// OBSOLETE current_thread = new_thread; +// OBSOLETE else +// OBSOLETE { +// OBSOLETE #if 0 +// OBSOLETE if (MACH_PORT_VALID (current_thread)) +// OBSOLETE { +// OBSOLETE /* Store the gdb's view of the thread we are deselecting +// OBSOLETE +// OBSOLETE * @@ I think gdb updates registers immediately when they are +// OBSOLETE * changed, so don't do this. +// OBSOLETE */ +// OBSOLETE ret = thread_abort (current_thread); +// OBSOLETE CHK ("Could not abort system calls when saving state of old thread", +// OBSOLETE ret); +// OBSOLETE target_prepare_to_store (); +// OBSOLETE target_store_registers (-1); +// OBSOLETE } +// OBSOLETE #endif +// OBSOLETE +// OBSOLETE registers_changed (); +// OBSOLETE +// OBSOLETE current_thread = new_thread; +// OBSOLETE +// OBSOLETE ret = thread_abort (current_thread); +// OBSOLETE CHK ("Could not abort system calls when selecting a thread", ret); +// OBSOLETE +// OBSOLETE stop_pc = read_pc (); +// OBSOLETE flush_cached_frames (); +// OBSOLETE +// OBSOLETE select_frame (get_current_frame ()); +// OBSOLETE } +// OBSOLETE +// OBSOLETE return KERN_SUCCESS; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* +// OBSOLETE * Switch to use thread named NEW_THREAD. +// OBSOLETE * Return it's MID +// OBSOLETE */ +// OBSOLETE int +// OBSOLETE switch_to_thread (thread_t new_thread) +// OBSOLETE { +// OBSOLETE thread_t saved_thread = current_thread; +// OBSOLETE int mid; +// OBSOLETE +// OBSOLETE mid = map_port_name_to_mid (new_thread, +// OBSOLETE MACH_TYPE_THREAD); +// OBSOLETE if (mid == -1) +// OBSOLETE warning ("Can't map thread name 0x%x to mid", new_thread); +// OBSOLETE else if (select_thread (inferior_task, mid, 1) != KERN_SUCCESS) +// OBSOLETE { +// OBSOLETE if (current_thread) +// OBSOLETE current_thread = saved_thread; +// OBSOLETE error ("Could not select thread %d", mid); +// OBSOLETE } +// OBSOLETE +// OBSOLETE return mid; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Do this in gdb after doing FORK but before STARTUP_INFERIOR. +// OBSOLETE * Note that the registers are not yet valid in the inferior task. +// OBSOLETE */ +// OBSOLETE static int +// OBSOLETE m3_trace_him (int pid) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE +// OBSOLETE push_target (&m3_ops); +// OBSOLETE +// OBSOLETE inferior_task = task_by_pid (pid); +// OBSOLETE +// OBSOLETE if (!MACH_PORT_VALID (inferior_task)) +// OBSOLETE error ("Can not map Unix pid %d to Mach task", pid); +// OBSOLETE +// OBSOLETE /* Clean up previous notifications and create new ones */ +// OBSOLETE setup_notify_port (1); +// OBSOLETE +// OBSOLETE /* When notification appears, the inferior task has died */ +// OBSOLETE request_notify (inferior_task, MACH_NOTIFY_DEAD_NAME, MACH_TYPE_TASK); +// OBSOLETE +// OBSOLETE emulator_present = have_emulator_p (inferior_task); +// OBSOLETE +// OBSOLETE /* By default, select the first thread, +// OBSOLETE * If task has no threads, gives a warning +// OBSOLETE * Does not fetch registers, since they are not yet valid. +// OBSOLETE */ +// OBSOLETE select_thread (inferior_task, 0, 0); +// OBSOLETE +// OBSOLETE inferior_exception_port = MACH_PORT_NULL; +// OBSOLETE +// OBSOLETE setup_exception_port (); +// OBSOLETE +// OBSOLETE xx_debug ("Now the debugged task is created\n"); +// OBSOLETE +// OBSOLETE /* One trap to exec the shell, one to exec the program being debugged. */ +// OBSOLETE intercept_exec_calls (2); +// OBSOLETE +// OBSOLETE return pid; +// OBSOLETE } +// OBSOLETE +// OBSOLETE setup_exception_port (void) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE +// OBSOLETE ret = mach_port_allocate (mach_task_self (), +// OBSOLETE MACH_PORT_RIGHT_RECEIVE, +// OBSOLETE &inferior_exception_port); +// OBSOLETE CHK ("mach_port_allocate", ret); +// OBSOLETE +// OBSOLETE /* add send right */ +// OBSOLETE ret = mach_port_insert_right (mach_task_self (), +// OBSOLETE inferior_exception_port, +// OBSOLETE inferior_exception_port, +// OBSOLETE MACH_MSG_TYPE_MAKE_SEND); +// OBSOLETE CHK ("mach_port_insert_right", ret); +// OBSOLETE +// OBSOLETE ret = mach_port_move_member (mach_task_self (), +// OBSOLETE inferior_exception_port, +// OBSOLETE inferior_wait_port_set); +// OBSOLETE CHK ("mach_port_move_member", ret); +// OBSOLETE +// OBSOLETE ret = task_get_special_port (inferior_task, +// OBSOLETE TASK_EXCEPTION_PORT, +// OBSOLETE &inferior_old_exception_port); +// OBSOLETE CHK ("task_get_special_port(old exc)", ret); +// OBSOLETE +// OBSOLETE ret = task_set_special_port (inferior_task, +// OBSOLETE TASK_EXCEPTION_PORT, +// OBSOLETE inferior_exception_port); +// OBSOLETE CHK ("task_set_special_port", ret); +// OBSOLETE +// OBSOLETE ret = mach_port_deallocate (mach_task_self (), +// OBSOLETE inferior_exception_port); +// OBSOLETE CHK ("mack_port_deallocate", ret); +// OBSOLETE +// OBSOLETE #if 0 +// OBSOLETE /* When notify appears, the inferior_task's exception +// OBSOLETE * port has been destroyed. +// OBSOLETE * +// OBSOLETE * Not used, since the dead_name_notification already +// OBSOLETE * appears when task dies. +// OBSOLETE * +// OBSOLETE */ +// OBSOLETE request_notify (inferior_exception_port, +// OBSOLETE MACH_NOTIFY_NO_SENDERS, +// OBSOLETE MACH_TYPE_EXCEPTION_PORT); +// OBSOLETE #endif +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Nonzero if gdb is waiting for a message */ +// OBSOLETE int mach_really_waiting; +// OBSOLETE +// OBSOLETE /* Wait for the inferior to stop for some reason. +// OBSOLETE - Loop on notifications until inferior_task dies. +// OBSOLETE - Loop on exceptions until stopped_in_exception comes true. +// OBSOLETE (e.g. we receive a single step trace trap) +// OBSOLETE - a message arrives to gdb's message port +// OBSOLETE +// OBSOLETE There is no other way to exit this loop. +// OBSOLETE +// OBSOLETE Returns the inferior_ptid for rest of gdb. +// OBSOLETE Side effects: Set *OURSTATUS. */ +// OBSOLETE ptid_t +// OBSOLETE mach_really_wait (ptid_t ptid, struct target_waitstatus *ourstatus) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE int w; +// OBSOLETE +// OBSOLETE struct msg +// OBSOLETE { +// OBSOLETE mach_msg_header_t header; +// OBSOLETE mach_msg_type_t foo; +// OBSOLETE int data[8000]; +// OBSOLETE } +// OBSOLETE in_msg, out_msg; +// OBSOLETE +// OBSOLETE /* Either notify (death), exception or message can stop the inferior */ +// OBSOLETE stopped_in_exception = FALSE; +// OBSOLETE +// OBSOLETE while (1) +// OBSOLETE { +// OBSOLETE QUIT; +// OBSOLETE +// OBSOLETE stop_exception = stop_code = stop_subcode = -1; +// OBSOLETE stop_thread = MACH_PORT_NULL; +// OBSOLETE +// OBSOLETE mach_really_waiting = 1; +// OBSOLETE ret = mach_msg (&in_msg.header, /* header */ +// OBSOLETE MACH_RCV_MSG, /* options */ +// OBSOLETE 0, /* send size */ +// OBSOLETE sizeof (struct msg), /* receive size */ +// OBSOLETE currently_waiting_for, /* receive name */ +// OBSOLETE MACH_MSG_TIMEOUT_NONE, +// OBSOLETE MACH_PORT_NULL); +// OBSOLETE mach_really_waiting = 0; +// OBSOLETE CHK ("mach_msg (receive)", ret); +// OBSOLETE +// OBSOLETE /* Check if we received a notify of the childs' death */ +// OBSOLETE if (notify_server (&in_msg.header, &out_msg.header)) +// OBSOLETE { +// OBSOLETE /* If inferior_task is null then the inferior has +// OBSOLETE gone away and we want to return to command level. +// OBSOLETE Otherwise it was just an informative message and we +// OBSOLETE need to look to see if there are any more. */ +// OBSOLETE if (inferior_task != MACH_PORT_NULL) +// OBSOLETE continue; +// OBSOLETE else +// OBSOLETE { +// OBSOLETE /* Collect Unix exit status for gdb */ +// OBSOLETE +// OBSOLETE wait3 (&w, WNOHANG, 0); +// OBSOLETE +// OBSOLETE /* This mess is here to check that the rest of +// OBSOLETE * gdb knows that the inferior died. It also +// OBSOLETE * tries to hack around the fact that Mach 3.0 (mk69) +// OBSOLETE * unix server (ux28) does not always know what +// OBSOLETE * has happened to it's children when mach-magic +// OBSOLETE * is applied on them. +// OBSOLETE */ +// OBSOLETE if ((!WIFEXITED (w) && WIFSTOPPED (w)) || +// OBSOLETE (WIFEXITED (w) && WEXITSTATUS (w) > 0377)) +// OBSOLETE { +// OBSOLETE WSETEXIT (w, 0); +// OBSOLETE warning ("Using exit value 0 for terminated task"); +// OBSOLETE } +// OBSOLETE else if (!WIFEXITED (w)) +// OBSOLETE { +// OBSOLETE int sig = WTERMSIG (w); +// OBSOLETE +// OBSOLETE /* Signals cause problems. Warn the user. */ +// OBSOLETE if (sig != SIGKILL) /* Bad luck if garbage matches this */ +// OBSOLETE warning ("The terminating signal stuff may be nonsense"); +// OBSOLETE else if (sig > NSIG) +// OBSOLETE { +// OBSOLETE WSETEXIT (w, 0); +// OBSOLETE warning ("Using exit value 0 for terminated task"); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE store_waitstatus (ourstatus, w); +// OBSOLETE return inferior_ptid; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Hmm. Check for exception, as it was not a notification. +// OBSOLETE exc_server() does an upcall to catch_exception_raise() +// OBSOLETE if this rpc is an exception. Further actions are decided +// OBSOLETE there. +// OBSOLETE */ +// OBSOLETE if (!exc_server (&in_msg.header, &out_msg.header)) +// OBSOLETE { +// OBSOLETE +// OBSOLETE /* Not an exception, check for message. +// OBSOLETE +// OBSOLETE * Messages don't come from the inferior, or if they +// OBSOLETE * do they better be asynchronous or it will hang. +// OBSOLETE */ +// OBSOLETE if (gdb_message_server (&in_msg.header)) +// OBSOLETE continue; +// OBSOLETE +// OBSOLETE error ("Unrecognized message received in mach_really_wait"); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Send the reply of the exception rpc to the suspended task */ +// OBSOLETE ret = mach_msg_send (&out_msg.header); +// OBSOLETE CHK ("mach_msg_send (exc reply)", ret); +// OBSOLETE +// OBSOLETE if (stopped_in_exception) +// OBSOLETE { +// OBSOLETE /* Get unix state. May be changed in mach3_exception_actions() */ +// OBSOLETE wait3 (&w, WNOHANG, 0); +// OBSOLETE +// OBSOLETE mach3_exception_actions (&w, FALSE, "Task"); +// OBSOLETE +// OBSOLETE store_waitstatus (ourstatus, w); +// OBSOLETE return inferior_ptid; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Called by macro DO_QUIT() in utils.c(quit). +// OBSOLETE * This is called just before calling error() to return to command level +// OBSOLETE */ +// OBSOLETE void +// OBSOLETE mach3_quit (void) +// OBSOLETE { +// OBSOLETE int mid; +// OBSOLETE kern_return_t ret; +// OBSOLETE +// OBSOLETE if (mach_really_waiting) +// OBSOLETE { +// OBSOLETE ret = task_suspend (inferior_task); +// OBSOLETE +// OBSOLETE if (ret != KERN_SUCCESS) +// OBSOLETE { +// OBSOLETE warning ("Could not suspend task for interrupt: %s", +// OBSOLETE mach_error_string (ret)); +// OBSOLETE mach_really_waiting = 0; +// OBSOLETE return; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE must_suspend_thread = 0; +// OBSOLETE mach_really_waiting = 0; +// OBSOLETE +// OBSOLETE mid = map_port_name_to_mid (current_thread, MACH_TYPE_THREAD); +// OBSOLETE if (mid == -1) +// OBSOLETE { +// OBSOLETE warning ("Selecting first existing kernel thread"); +// OBSOLETE mid = 0; +// OBSOLETE } +// OBSOLETE +// OBSOLETE current_thread = MACH_PORT_NULL; /* Force setup */ +// OBSOLETE select_thread (inferior_task, mid, 1); +// OBSOLETE +// OBSOLETE return; +// OBSOLETE } +// OBSOLETE +// OBSOLETE #if 0 +// OBSOLETE /* bogus bogus bogus. It is NOT OK to quit out of target_wait. */ +// OBSOLETE +// OBSOLETE /* If ^C is typed when we are waiting for a message +// OBSOLETE * and your Unix server is able to notice that we +// OBSOLETE * should quit now. +// OBSOLETE * +// OBSOLETE * Called by REQUEST_QUIT() from utils.c(request_quit) +// OBSOLETE */ +// OBSOLETE void +// OBSOLETE mach3_request_quit (void) +// OBSOLETE { +// OBSOLETE if (mach_really_waiting) +// OBSOLETE immediate_quit = 1; +// OBSOLETE } +// OBSOLETE #endif +// OBSOLETE +// OBSOLETE /* +// OBSOLETE * Gdb message server. +// OBSOLETE * Currently implemented is the STOP message, that causes +// OBSOLETE * gdb to return to the command level like ^C had been typed from terminal. +// OBSOLETE */ +// OBSOLETE int +// OBSOLETE gdb_message_server (mach_msg_header_t *InP) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE int mid; +// OBSOLETE +// OBSOLETE if (InP->msgh_local_port == our_message_port) +// OBSOLETE { +// OBSOLETE /* A message coming to our_message_port. Check validity */ +// OBSOLETE switch (InP->msgh_id) +// OBSOLETE { +// OBSOLETE +// OBSOLETE case GDB_MESSAGE_ID_STOP: +// OBSOLETE ret = task_suspend (inferior_task); +// OBSOLETE if (ret != KERN_SUCCESS) +// OBSOLETE warning ("Could not suspend task for stop message: %s", +// OBSOLETE mach_error_string (ret)); +// OBSOLETE +// OBSOLETE /* QUIT in mach_really_wait() loop. */ +// OBSOLETE request_quit (0); +// OBSOLETE break; +// OBSOLETE +// OBSOLETE default: +// OBSOLETE warning ("Invalid message id %d received, ignored.", +// OBSOLETE InP->msgh_id); +// OBSOLETE break; +// OBSOLETE } +// OBSOLETE +// OBSOLETE return 1; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Message not handled by this server */ +// OBSOLETE return 0; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* NOTE: This is not an RPC call. It is a simpleroutine. +// OBSOLETE +// OBSOLETE * This is not called from this gdb code. +// OBSOLETE * +// OBSOLETE * It may be called by another debugger to cause this +// OBSOLETE * debugger to enter command level: +// OBSOLETE * +// OBSOLETE * (gdb) set stop_inferior_gdb () +// OBSOLETE * (gdb) continue +// OBSOLETE * +// OBSOLETE * External program "stop-gdb" implements this also. +// OBSOLETE */ +// OBSOLETE void +// OBSOLETE stop_inferior_gdb (void) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE +// OBSOLETE /* Code generated by mig, with minor cleanups :-) +// OBSOLETE +// OBSOLETE * simpleroutine stop_inferior_gdb (our_message_port : mach_port_t); +// OBSOLETE */ +// OBSOLETE +// OBSOLETE typedef struct +// OBSOLETE { +// OBSOLETE mach_msg_header_t Head; +// OBSOLETE } +// OBSOLETE Request; +// OBSOLETE +// OBSOLETE Request Mess; +// OBSOLETE +// OBSOLETE register Request *InP = &Mess; +// OBSOLETE +// OBSOLETE InP->Head.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, 0); +// OBSOLETE +// OBSOLETE /* msgh_size passed as argument */ +// OBSOLETE InP->Head.msgh_remote_port = our_message_port; +// OBSOLETE InP->Head.msgh_local_port = MACH_PORT_NULL; +// OBSOLETE InP->Head.msgh_seqno = 0; +// OBSOLETE InP->Head.msgh_id = GDB_MESSAGE_ID_STOP; +// OBSOLETE +// OBSOLETE ret = mach_msg (&InP->Head, +// OBSOLETE MACH_SEND_MSG | MACH_MSG_OPTION_NONE, +// OBSOLETE sizeof (Request), +// OBSOLETE 0, +// OBSOLETE MACH_PORT_NULL, +// OBSOLETE MACH_MSG_TIMEOUT_NONE, +// OBSOLETE MACH_PORT_NULL); +// OBSOLETE } +// OBSOLETE +// OBSOLETE #ifdef THREAD_ALLOWED_TO_BREAK +// OBSOLETE /* +// OBSOLETE * Return 1 if the MID specifies the thread that caused the +// OBSOLETE * last exception. +// OBSOLETE * Since catch_exception_raise() selects the thread causing +// OBSOLETE * the last exception to current_thread, we just check that +// OBSOLETE * it is selected and the last exception was a breakpoint. +// OBSOLETE */ +// OBSOLETE int +// OBSOLETE mach_thread_for_breakpoint (int mid) +// OBSOLETE { +// OBSOLETE int cmid = map_port_name_to_mid (current_thread, MACH_TYPE_THREAD); +// OBSOLETE +// OBSOLETE if (mid < 0) +// OBSOLETE { +// OBSOLETE mid = map_slot_to_mid (-(mid + 1), 0, 0); +// OBSOLETE if (mid < 0) +// OBSOLETE return 0; /* Don't stop, no such slot */ +// OBSOLETE } +// OBSOLETE +// OBSOLETE if (!mid || cmid == -1) +// OBSOLETE return 1; /* stop */ +// OBSOLETE +// OBSOLETE return cmid == mid && stop_exception == EXC_BREAKPOINT; +// OBSOLETE } +// OBSOLETE #endif /* THREAD_ALLOWED_TO_BREAK */ +// OBSOLETE +// OBSOLETE #ifdef THREAD_PARSE_ID +// OBSOLETE /* +// OBSOLETE * Map a thread id string (MID or a @SLOTNUMBER) +// OBSOLETE * to a thread-id. +// OBSOLETE * +// OBSOLETE * 0 matches all threads. +// OBSOLETE * Otherwise the meaning is defined only in this file. +// OBSOLETE * (mach_thread_for_breakpoint uses it) +// OBSOLETE * +// OBSOLETE * @@ This allows non-existent MIDs to be specified. +// OBSOLETE * It now also allows non-existent slots to be +// OBSOLETE * specified. (Slot numbers stored are negative, +// OBSOLETE * and the magnitude is one greater than the actual +// OBSOLETE * slot index. (Since 0 is reserved)) +// OBSOLETE */ +// OBSOLETE int +// OBSOLETE mach_thread_parse_id (char *arg) +// OBSOLETE { +// OBSOLETE int mid; +// OBSOLETE if (arg == 0) +// OBSOLETE error ("thread id expected"); +// OBSOLETE mid = parse_thread_id (arg, 0, 1); +// OBSOLETE +// OBSOLETE return mid; +// OBSOLETE } +// OBSOLETE #endif /* THREAD_PARSE_ID */ +// OBSOLETE +// OBSOLETE #ifdef THREAD_OUTPUT_ID +// OBSOLETE char * +// OBSOLETE mach_thread_output_id (int mid) +// OBSOLETE { +// OBSOLETE static char foobar[20]; +// OBSOLETE +// OBSOLETE if (mid > 0) +// OBSOLETE sprintf (foobar, "mid %d", mid); +// OBSOLETE else if (mid < 0) +// OBSOLETE sprintf (foobar, "@%d", -(mid + 1)); +// OBSOLETE else +// OBSOLETE sprintf (foobar, "*any thread*"); +// OBSOLETE +// OBSOLETE return foobar; +// OBSOLETE } +// OBSOLETE #endif /* THREAD_OUTPUT_ID */ +// OBSOLETE +// OBSOLETE /* Called with hook PREPARE_TO_PROCEED() from infrun.c. +// OBSOLETE +// OBSOLETE * If we have switched threads and stopped at breakpoint return 1 otherwise 0. +// OBSOLETE * +// OBSOLETE * if SELECT_IT is nonzero, reselect the thread that was active when +// OBSOLETE * we stopped at a breakpoint. +// OBSOLETE * +// OBSOLETE * Note that this implementation is potentially redundant now that +// OBSOLETE * default_prepare_to_proceed() has been added. +// OBSOLETE * +// OBSOLETE * FIXME This may not support switching threads after Ctrl-C +// OBSOLETE * correctly. The default implementation does support this. +// OBSOLETE */ +// OBSOLETE +// OBSOLETE mach3_prepare_to_proceed (int select_it) +// OBSOLETE { +// OBSOLETE if (stop_thread && +// OBSOLETE stop_thread != current_thread && +// OBSOLETE stop_exception == EXC_BREAKPOINT) +// OBSOLETE { +// OBSOLETE int mid; +// OBSOLETE +// OBSOLETE if (!select_it) +// OBSOLETE return 1; +// OBSOLETE +// OBSOLETE mid = switch_to_thread (stop_thread); +// OBSOLETE +// OBSOLETE return 1; +// OBSOLETE } +// OBSOLETE +// OBSOLETE return 0; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* this stuff here is an upcall via libmach/excServer.c +// OBSOLETE and mach_really_wait which does the actual upcall. +// OBSOLETE +// OBSOLETE The code will pass the exception to the inferior if: +// OBSOLETE +// OBSOLETE - The task that signaled is not the inferior task +// OBSOLETE (e.g. when debugging another debugger) +// OBSOLETE +// OBSOLETE - The user has explicitely requested to pass on the exceptions. +// OBSOLETE (e.g to the default unix exception handler, which maps +// OBSOLETE exceptions to signals, or the user has her own exception handler) +// OBSOLETE +// OBSOLETE - If the thread that signaled is being single-stepped and it +// OBSOLETE has set it's own exception port and the exception is not +// OBSOLETE EXC_BREAKPOINT. (Maybe this is not desirable?) +// OBSOLETE */ +// OBSOLETE +// OBSOLETE kern_return_t +// OBSOLETE catch_exception_raise (mach_port_t port, thread_t thread, task_t task, +// OBSOLETE int exception, int code, int subcode) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE boolean_t signal_thread; +// OBSOLETE int mid = map_port_name_to_mid (thread, MACH_TYPE_THREAD); +// OBSOLETE +// OBSOLETE if (!MACH_PORT_VALID (thread)) +// OBSOLETE { +// OBSOLETE /* If the exception was sent and thread dies before we +// OBSOLETE receive it, THREAD will be MACH_PORT_DEAD +// OBSOLETE */ +// OBSOLETE +// OBSOLETE current_thread = thread = MACH_PORT_NULL; +// OBSOLETE error ("Received exception from nonexistent thread"); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Check if the task died in transit. +// OBSOLETE * @@ Isn't the thread also invalid in such case? +// OBSOLETE */ +// OBSOLETE if (!MACH_PORT_VALID (task)) +// OBSOLETE { +// OBSOLETE current_thread = thread = MACH_PORT_NULL; +// OBSOLETE error ("Received exception from nonexistent task"); +// OBSOLETE } +// OBSOLETE +// OBSOLETE if (exception < 0 || exception > MAX_EXCEPTION) +// OBSOLETE internal_error (__FILE__, __LINE__, +// OBSOLETE "catch_exception_raise: unknown exception code %d thread %d", +// OBSOLETE exception, +// OBSOLETE mid); +// OBSOLETE +// OBSOLETE if (!MACH_PORT_VALID (inferior_task)) +// OBSOLETE error ("got an exception, but inferior_task is null or dead"); +// OBSOLETE +// OBSOLETE stop_exception = exception; +// OBSOLETE stop_code = code; +// OBSOLETE stop_subcode = subcode; +// OBSOLETE stop_thread = thread; +// OBSOLETE +// OBSOLETE signal_thread = exception != EXC_BREAKPOINT && +// OBSOLETE port == singlestepped_thread_port && +// OBSOLETE MACH_PORT_VALID (thread_saved_exception_port); +// OBSOLETE +// OBSOLETE /* If it was not our inferior or if we want to forward +// OBSOLETE * the exception to the inferior's handler, do it here +// OBSOLETE * +// OBSOLETE * Note: If you have forwarded EXC_BREAKPOINT I trust you know why. +// OBSOLETE */ +// OBSOLETE if (task != inferior_task || +// OBSOLETE signal_thread || +// OBSOLETE exception_map[exception].forward) +// OBSOLETE { +// OBSOLETE mach_port_t eport = inferior_old_exception_port; +// OBSOLETE +// OBSOLETE if (signal_thread) +// OBSOLETE { +// OBSOLETE /* +// OBSOLETE GDB now forwards the exeption to thread's original handler, +// OBSOLETE since the user propably knows what he is doing. +// OBSOLETE Give a message, though. +// OBSOLETE */ +// OBSOLETE +// OBSOLETE mach3_exception_actions ((WAITTYPE *) NULL, TRUE, "Thread"); +// OBSOLETE eport = thread_saved_exception_port; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Send the exception to the original handler */ +// OBSOLETE ret = exception_raise (eport, +// OBSOLETE thread, +// OBSOLETE task, +// OBSOLETE exception, +// OBSOLETE code, +// OBSOLETE subcode); +// OBSOLETE +// OBSOLETE (void) mach_port_deallocate (mach_task_self (), task); +// OBSOLETE (void) mach_port_deallocate (mach_task_self (), thread); +// OBSOLETE +// OBSOLETE /* If we come here, we don't want to trace any more, since we +// OBSOLETE * will never stop for tracing anyway. +// OBSOLETE */ +// OBSOLETE discard_single_step (thread); +// OBSOLETE +// OBSOLETE /* Do not stop the inferior */ +// OBSOLETE return ret; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Now gdb handles the exception */ +// OBSOLETE stopped_in_exception = TRUE; +// OBSOLETE +// OBSOLETE ret = task_suspend (task); +// OBSOLETE CHK ("Error suspending inferior after exception", ret); +// OBSOLETE +// OBSOLETE must_suspend_thread = 0; +// OBSOLETE +// OBSOLETE if (current_thread != thread) +// OBSOLETE { +// OBSOLETE if (MACH_PORT_VALID (singlestepped_thread_port)) +// OBSOLETE /* Cleanup discards single stepping */ +// OBSOLETE error ("Exception from thread %d while singlestepping thread %d", +// OBSOLETE mid, +// OBSOLETE map_port_name_to_mid (current_thread, MACH_TYPE_THREAD)); +// OBSOLETE +// OBSOLETE /* Then select the thread that caused the exception */ +// OBSOLETE if (select_thread (inferior_task, mid, 0) != KERN_SUCCESS) +// OBSOLETE error ("Could not select thread %d causing exception", mid); +// OBSOLETE else +// OBSOLETE warning ("Gdb selected thread %d", mid); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* If we receive an exception that is not breakpoint +// OBSOLETE * exception, we interrupt the single step and return to +// OBSOLETE * debugger. Trace condition is cleared. +// OBSOLETE */ +// OBSOLETE if (MACH_PORT_VALID (singlestepped_thread_port)) +// OBSOLETE { +// OBSOLETE if (stop_exception != EXC_BREAKPOINT) +// OBSOLETE warning ("Single step interrupted by exception"); +// OBSOLETE else if (port == singlestepped_thread_port) +// OBSOLETE { +// OBSOLETE /* Single step exception occurred, remove trace bit +// OBSOLETE * and return to gdb. +// OBSOLETE */ +// OBSOLETE if (!MACH_PORT_VALID (current_thread)) +// OBSOLETE error ("Single stepped thread is not valid"); +// OBSOLETE +// OBSOLETE /* Resume threads, but leave the task suspended */ +// OBSOLETE resume_all_threads (0); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE warning ("Breakpoint while single stepping?"); +// OBSOLETE +// OBSOLETE discard_single_step (current_thread); +// OBSOLETE } +// OBSOLETE +// OBSOLETE (void) mach_port_deallocate (mach_task_self (), task); +// OBSOLETE (void) mach_port_deallocate (mach_task_self (), thread); +// OBSOLETE +// OBSOLETE return KERN_SUCCESS; +// OBSOLETE } +// OBSOLETE +// OBSOLETE int +// OBSOLETE port_valid (mach_port_t port, int mask) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE mach_port_type_t type; +// OBSOLETE +// OBSOLETE ret = mach_port_type (mach_task_self (), +// OBSOLETE port, +// OBSOLETE &type); +// OBSOLETE if (ret != KERN_SUCCESS || (type & mask) != mask) +// OBSOLETE return 0; +// OBSOLETE return 1; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* @@ No vm read cache implemented yet */ +// OBSOLETE boolean_t vm_read_cache_valid = FALSE; +// OBSOLETE +// OBSOLETE /* +// OBSOLETE * Read inferior task's LEN bytes from ADDR and copy it to MYADDR +// OBSOLETE * in gdb's address space. +// OBSOLETE * +// OBSOLETE * Return 0 on failure; number of bytes read otherwise. +// OBSOLETE */ +// OBSOLETE int +// OBSOLETE mach3_read_inferior (CORE_ADDR addr, char *myaddr, int length) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE vm_address_t low_address = (vm_address_t) trunc_page (addr); +// OBSOLETE vm_size_t aligned_length = +// OBSOLETE (vm_size_t) round_page (addr + length) - low_address; +// OBSOLETE pointer_t copied_memory; +// OBSOLETE int copy_count; +// OBSOLETE +// OBSOLETE /* Get memory from inferior with page aligned addresses */ +// OBSOLETE ret = vm_read (inferior_task, +// OBSOLETE low_address, +// OBSOLETE aligned_length, +// OBSOLETE &copied_memory, +// OBSOLETE ©_count); +// OBSOLETE if (ret != KERN_SUCCESS) +// OBSOLETE { +// OBSOLETE /* the problem is that the inferior might be killed for whatever reason +// OBSOLETE * before we go to mach_really_wait. This is one place that ought to +// OBSOLETE * catch many of those errors. +// OBSOLETE * @@ A better fix would be to make all external events to GDB +// OBSOLETE * to arrive via a SINGLE port set. (Including user input!) +// OBSOLETE */ +// OBSOLETE +// OBSOLETE if (!port_valid (inferior_task, MACH_PORT_TYPE_SEND)) +// OBSOLETE { +// OBSOLETE m3_kill_inferior (); +// OBSOLETE error ("Inferior killed (task port invalid)"); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE #ifdef OSF +// OBSOLETE extern int errno; +// OBSOLETE /* valprint.c gives nicer format if this does not +// OBSOLETE screw it. Eamonn seems to like this, so I enable +// OBSOLETE it if OSF is defined... +// OBSOLETE */ +// OBSOLETE warning ("[read inferior %x failed: %s]", +// OBSOLETE addr, mach_error_string (ret)); +// OBSOLETE errno = 0; +// OBSOLETE #endif +// OBSOLETE return 0; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE memcpy (myaddr, (char *) addr - low_address + copied_memory, length); +// OBSOLETE +// OBSOLETE ret = vm_deallocate (mach_task_self (), +// OBSOLETE copied_memory, +// OBSOLETE copy_count); +// OBSOLETE CHK ("mach3_read_inferior vm_deallocate failed", ret); +// OBSOLETE +// OBSOLETE return length; +// OBSOLETE } +// OBSOLETE +// OBSOLETE #define CHK_GOTO_OUT(str,ret) \ +// OBSOLETE do if (ret != KERN_SUCCESS) { errstr = #str; goto out; } while(0) +// OBSOLETE +// OBSOLETE struct vm_region_list +// OBSOLETE { +// OBSOLETE struct vm_region_list *next; +// OBSOLETE vm_prot_t protection; +// OBSOLETE vm_address_t start; +// OBSOLETE vm_size_t length; +// OBSOLETE }; +// OBSOLETE +// OBSOLETE struct obstack region_obstack; +// OBSOLETE +// OBSOLETE /* +// OBSOLETE * Write inferior task's LEN bytes from ADDR and copy it to MYADDR +// OBSOLETE * in gdb's address space. +// OBSOLETE */ +// OBSOLETE int +// OBSOLETE mach3_write_inferior (CORE_ADDR addr, char *myaddr, int length) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE vm_address_t low_address = (vm_address_t) trunc_page (addr); +// OBSOLETE vm_size_t aligned_length = +// OBSOLETE (vm_size_t) round_page (addr + length) - low_address; +// OBSOLETE pointer_t copied_memory; +// OBSOLETE int copy_count; +// OBSOLETE int deallocate = 0; +// OBSOLETE +// OBSOLETE char *errstr = "Bug in mach3_write_inferior"; +// OBSOLETE +// OBSOLETE struct vm_region_list *region_element; +// OBSOLETE struct vm_region_list *region_head = (struct vm_region_list *) NULL; +// OBSOLETE +// OBSOLETE /* Get memory from inferior with page aligned addresses */ +// OBSOLETE ret = vm_read (inferior_task, +// OBSOLETE low_address, +// OBSOLETE aligned_length, +// OBSOLETE &copied_memory, +// OBSOLETE ©_count); +// OBSOLETE CHK_GOTO_OUT ("mach3_write_inferior vm_read failed", ret); +// OBSOLETE +// OBSOLETE deallocate++; +// OBSOLETE +// OBSOLETE memcpy ((char *) addr - low_address + copied_memory, myaddr, length); +// OBSOLETE +// OBSOLETE obstack_init (®ion_obstack); +// OBSOLETE +// OBSOLETE /* Do writes atomically. +// OBSOLETE * First check for holes and unwritable memory. +// OBSOLETE */ +// OBSOLETE { +// OBSOLETE vm_size_t remaining_length = aligned_length; +// OBSOLETE vm_address_t region_address = low_address; +// OBSOLETE +// OBSOLETE struct vm_region_list *scan; +// OBSOLETE +// OBSOLETE while (region_address < low_address + aligned_length) +// OBSOLETE { +// OBSOLETE vm_prot_t protection; +// OBSOLETE vm_prot_t max_protection; +// OBSOLETE vm_inherit_t inheritance; +// OBSOLETE boolean_t shared; +// OBSOLETE mach_port_t object_name; +// OBSOLETE vm_offset_t offset; +// OBSOLETE vm_size_t region_length = remaining_length; +// OBSOLETE vm_address_t old_address = region_address; +// OBSOLETE +// OBSOLETE ret = vm_region (inferior_task, +// OBSOLETE ®ion_address, +// OBSOLETE ®ion_length, +// OBSOLETE &protection, +// OBSOLETE &max_protection, +// OBSOLETE &inheritance, +// OBSOLETE &shared, +// OBSOLETE &object_name, +// OBSOLETE &offset); +// OBSOLETE CHK_GOTO_OUT ("vm_region failed", ret); +// OBSOLETE +// OBSOLETE /* Check for holes in memory */ +// OBSOLETE if (old_address != region_address) +// OBSOLETE { +// OBSOLETE warning ("No memory at 0x%x. Nothing written", +// OBSOLETE old_address); +// OBSOLETE ret = KERN_SUCCESS; +// OBSOLETE length = 0; +// OBSOLETE goto out; +// OBSOLETE } +// OBSOLETE +// OBSOLETE if (!(max_protection & VM_PROT_WRITE)) +// OBSOLETE { +// OBSOLETE warning ("Memory at address 0x%x is unwritable. Nothing written", +// OBSOLETE old_address); +// OBSOLETE ret = KERN_SUCCESS; +// OBSOLETE length = 0; +// OBSOLETE goto out; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Chain the regions for later use */ +// OBSOLETE region_element = +// OBSOLETE (struct vm_region_list *) +// OBSOLETE obstack_alloc (®ion_obstack, sizeof (struct vm_region_list)); +// OBSOLETE +// OBSOLETE region_element->protection = protection; +// OBSOLETE region_element->start = region_address; +// OBSOLETE region_element->length = region_length; +// OBSOLETE +// OBSOLETE /* Chain the regions along with protections */ +// OBSOLETE region_element->next = region_head; +// OBSOLETE region_head = region_element; +// OBSOLETE +// OBSOLETE region_address += region_length; +// OBSOLETE remaining_length = remaining_length - region_length; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* If things fail after this, we give up. +// OBSOLETE * Somebody is messing up inferior_task's mappings. +// OBSOLETE */ +// OBSOLETE +// OBSOLETE /* Enable writes to the chained vm regions */ +// OBSOLETE for (scan = region_head; scan; scan = scan->next) +// OBSOLETE { +// OBSOLETE boolean_t protection_changed = FALSE; +// OBSOLETE +// OBSOLETE if (!(scan->protection & VM_PROT_WRITE)) +// OBSOLETE { +// OBSOLETE ret = vm_protect (inferior_task, +// OBSOLETE scan->start, +// OBSOLETE scan->length, +// OBSOLETE FALSE, +// OBSOLETE scan->protection | VM_PROT_WRITE); +// OBSOLETE CHK_GOTO_OUT ("vm_protect: enable write failed", ret); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE ret = vm_write (inferior_task, +// OBSOLETE low_address, +// OBSOLETE copied_memory, +// OBSOLETE aligned_length); +// OBSOLETE CHK_GOTO_OUT ("vm_write failed", ret); +// OBSOLETE +// OBSOLETE /* Set up the original region protections, if they were changed */ +// OBSOLETE for (scan = region_head; scan; scan = scan->next) +// OBSOLETE { +// OBSOLETE boolean_t protection_changed = FALSE; +// OBSOLETE +// OBSOLETE if (!(scan->protection & VM_PROT_WRITE)) +// OBSOLETE { +// OBSOLETE ret = vm_protect (inferior_task, +// OBSOLETE scan->start, +// OBSOLETE scan->length, +// OBSOLETE FALSE, +// OBSOLETE scan->protection); +// OBSOLETE CHK_GOTO_OUT ("vm_protect: enable write failed", ret); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE out: +// OBSOLETE if (deallocate) +// OBSOLETE { +// OBSOLETE obstack_free (®ion_obstack, 0); +// OBSOLETE +// OBSOLETE (void) vm_deallocate (mach_task_self (), +// OBSOLETE copied_memory, +// OBSOLETE copy_count); +// OBSOLETE } +// OBSOLETE +// OBSOLETE if (ret != KERN_SUCCESS) +// OBSOLETE { +// OBSOLETE warning ("%s %s", errstr, mach_error_string (ret)); +// OBSOLETE return 0; +// OBSOLETE } +// OBSOLETE +// OBSOLETE return length; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Return 0 on failure, number of bytes handled otherwise. TARGET is +// OBSOLETE ignored. */ +// OBSOLETE static int +// OBSOLETE m3_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, +// OBSOLETE struct target_ops *target) +// OBSOLETE { +// OBSOLETE int result; +// OBSOLETE +// OBSOLETE if (write) +// OBSOLETE result = mach3_write_inferior (memaddr, myaddr, len); +// OBSOLETE else +// OBSOLETE result = mach3_read_inferior (memaddr, myaddr, len); +// OBSOLETE +// OBSOLETE return result; +// OBSOLETE } +// OBSOLETE +// OBSOLETE +// OBSOLETE static char * +// OBSOLETE translate_state (int state) +// OBSOLETE { +// OBSOLETE switch (state) +// OBSOLETE { +// OBSOLETE case TH_STATE_RUNNING: +// OBSOLETE return ("R"); +// OBSOLETE case TH_STATE_STOPPED: +// OBSOLETE return ("S"); +// OBSOLETE case TH_STATE_WAITING: +// OBSOLETE return ("W"); +// OBSOLETE case TH_STATE_UNINTERRUPTIBLE: +// OBSOLETE return ("U"); +// OBSOLETE case TH_STATE_HALTED: +// OBSOLETE return ("H"); +// OBSOLETE default: +// OBSOLETE return ("?"); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE static char * +// OBSOLETE translate_cstate (int state) +// OBSOLETE { +// OBSOLETE switch (state) +// OBSOLETE { +// OBSOLETE case CPROC_RUNNING: +// OBSOLETE return "R"; +// OBSOLETE case CPROC_SWITCHING: +// OBSOLETE return "S"; +// OBSOLETE case CPROC_BLOCKED: +// OBSOLETE return "B"; +// OBSOLETE case CPROC_CONDWAIT: +// OBSOLETE return "C"; +// OBSOLETE case CPROC_CONDWAIT | CPROC_SWITCHING: +// OBSOLETE return "CS"; +// OBSOLETE default: +// OBSOLETE return "?"; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* type == MACH_MSG_TYPE_COPY_SEND || type == MACH_MSG_TYPE_MAKE_SEND */ +// OBSOLETE +// OBSOLETE mach_port_t /* no mach_port_name_t found in include files. */ +// OBSOLETE map_inferior_port_name (mach_port_t inferior_name, mach_msg_type_name_t type) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE mach_msg_type_name_t acquired; +// OBSOLETE mach_port_t iport; +// OBSOLETE +// OBSOLETE ret = mach_port_extract_right (inferior_task, +// OBSOLETE inferior_name, +// OBSOLETE type, +// OBSOLETE &iport, +// OBSOLETE &acquired); +// OBSOLETE CHK ("mach_port_extract_right (map_inferior_port_name)", ret); +// OBSOLETE +// OBSOLETE if (acquired != MACH_MSG_TYPE_PORT_SEND) +// OBSOLETE error ("Incorrect right extracted, (map_inferior_port_name)"); +// OBSOLETE +// OBSOLETE ret = mach_port_deallocate (mach_task_self (), +// OBSOLETE iport); +// OBSOLETE CHK ("Deallocating mapped port (map_inferior_port_name)", ret); +// OBSOLETE +// OBSOLETE return iport; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* +// OBSOLETE * Naming convention: +// OBSOLETE * Always return user defined name if found. +// OBSOLETE * _K == A kernel thread with no matching CPROC +// OBSOLETE * _C == A cproc with no current cthread +// OBSOLETE * _t == A cthread with no user defined name +// OBSOLETE * +// OBSOLETE * The digits that follow the _names are the SLOT number of the +// OBSOLETE * kernel thread if there is such a thing, otherwise just a negation +// OBSOLETE * of the sequential number of such cprocs. +// OBSOLETE */ +// OBSOLETE +// OBSOLETE static char buf[7]; +// OBSOLETE +// OBSOLETE static char * +// OBSOLETE get_thread_name (gdb_thread_t one_cproc, int id) +// OBSOLETE { +// OBSOLETE if (one_cproc) +// OBSOLETE if (one_cproc->cthread == NULL) +// OBSOLETE { +// OBSOLETE /* cproc not mapped to any cthread */ +// OBSOLETE sprintf (buf, "_C%d", id); +// OBSOLETE } +// OBSOLETE else if (!one_cproc->cthread->name) +// OBSOLETE { +// OBSOLETE /* cproc and cthread, but no name */ +// OBSOLETE sprintf (buf, "_t%d", id); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE return (char *) (one_cproc->cthread->name); +// OBSOLETE else +// OBSOLETE { +// OBSOLETE if (id < 0) +// OBSOLETE warning ("Inconsistency in thread name id %d", id); +// OBSOLETE +// OBSOLETE /* Kernel thread without cproc */ +// OBSOLETE sprintf (buf, "_K%d", id); +// OBSOLETE } +// OBSOLETE +// OBSOLETE return buf; +// OBSOLETE } +// OBSOLETE +// OBSOLETE int +// OBSOLETE fetch_thread_info (mach_port_t task, gdb_thread_t *mthreads_out) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE thread_array_t th_table; +// OBSOLETE int th_count; +// OBSOLETE gdb_thread_t mthreads = NULL; +// OBSOLETE int index; +// OBSOLETE +// OBSOLETE ret = task_threads (task, &th_table, &th_count); +// OBSOLETE if (ret != KERN_SUCCESS) +// OBSOLETE { +// OBSOLETE warning ("Error getting inferior's thread list:%s", +// OBSOLETE mach_error_string (ret)); +// OBSOLETE m3_kill_inferior (); +// OBSOLETE return -1; +// OBSOLETE } +// OBSOLETE +// OBSOLETE mthreads = (gdb_thread_t) +// OBSOLETE obstack_alloc +// OBSOLETE (cproc_obstack, +// OBSOLETE th_count * sizeof (struct gdb_thread)); +// OBSOLETE +// OBSOLETE for (index = 0; index < th_count; index++) +// OBSOLETE { +// OBSOLETE thread_t saved_thread = MACH_PORT_NULL; +// OBSOLETE int mid; +// OBSOLETE +// OBSOLETE if (must_suspend_thread) +// OBSOLETE setup_thread (th_table[index], 1); +// OBSOLETE +// OBSOLETE if (th_table[index] != current_thread) +// OBSOLETE { +// OBSOLETE saved_thread = current_thread; +// OBSOLETE +// OBSOLETE mid = switch_to_thread (th_table[index]); +// OBSOLETE } +// OBSOLETE +// OBSOLETE mthreads[index].name = th_table[index]; +// OBSOLETE mthreads[index].cproc = NULL; /* map_cprocs_to_kernel_threads() */ +// OBSOLETE mthreads[index].in_emulator = FALSE; +// OBSOLETE mthreads[index].slotid = index; +// OBSOLETE +// OBSOLETE mthreads[index].sp = read_register (SP_REGNUM); +// OBSOLETE mthreads[index].fp = read_register (FP_REGNUM); +// OBSOLETE mthreads[index].pc = read_pc (); +// OBSOLETE +// OBSOLETE if (MACH_PORT_VALID (saved_thread)) +// OBSOLETE mid = switch_to_thread (saved_thread); +// OBSOLETE +// OBSOLETE if (must_suspend_thread) +// OBSOLETE setup_thread (th_table[index], 0); +// OBSOLETE } +// OBSOLETE +// OBSOLETE consume_send_rights (th_table, th_count); +// OBSOLETE ret = vm_deallocate (mach_task_self (), (vm_address_t) th_table, +// OBSOLETE (th_count * sizeof (mach_port_t))); +// OBSOLETE if (ret != KERN_SUCCESS) +// OBSOLETE { +// OBSOLETE warning ("Error trying to deallocate thread list : %s", +// OBSOLETE mach_error_string (ret)); +// OBSOLETE } +// OBSOLETE +// OBSOLETE *mthreads_out = mthreads; +// OBSOLETE +// OBSOLETE return th_count; +// OBSOLETE } +// OBSOLETE +// OBSOLETE +// OBSOLETE /* +// OBSOLETE * Current emulator always saves the USP on top of +// OBSOLETE * emulator stack below struct emul_stack_top stuff. +// OBSOLETE */ +// OBSOLETE CORE_ADDR +// OBSOLETE fetch_usp_from_emulator_stack (CORE_ADDR sp) +// OBSOLETE { +// OBSOLETE CORE_ADDR stack_pointer; +// OBSOLETE +// OBSOLETE sp = (sp & ~(EMULATOR_STACK_SIZE - 1)) + +// OBSOLETE EMULATOR_STACK_SIZE - sizeof (struct emul_stack_top); +// OBSOLETE +// OBSOLETE if (mach3_read_inferior (sp, +// OBSOLETE &stack_pointer, +// OBSOLETE sizeof (CORE_ADDR)) != sizeof (CORE_ADDR)) +// OBSOLETE { +// OBSOLETE warning ("Can't read user sp from emulator stack address 0x%x", sp); +// OBSOLETE return 0; +// OBSOLETE } +// OBSOLETE +// OBSOLETE return stack_pointer; +// OBSOLETE } +// OBSOLETE +// OBSOLETE #ifdef MK67 +// OBSOLETE +// OBSOLETE /* get_emulation_vector() interface was changed after mk67 */ +// OBSOLETE #define EMUL_VECTOR_COUNT 400 /* Value does not matter too much */ +// OBSOLETE +// OBSOLETE #endif /* MK67 */ +// OBSOLETE +// OBSOLETE /* Check if the emulator exists at task's address space. +// OBSOLETE */ +// OBSOLETE boolean_t +// OBSOLETE have_emulator_p (task_t task) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE #ifndef EMUL_VECTOR_COUNT +// OBSOLETE vm_offset_t *emulation_vector; +// OBSOLETE int n; +// OBSOLETE #else +// OBSOLETE vm_offset_t emulation_vector[EMUL_VECTOR_COUNT]; +// OBSOLETE int n = EMUL_VECTOR_COUNT; +// OBSOLETE #endif +// OBSOLETE int i; +// OBSOLETE int vector_start; +// OBSOLETE +// OBSOLETE ret = task_get_emulation_vector (task, +// OBSOLETE &vector_start, +// OBSOLETE #ifndef EMUL_VECTOR_COUNT +// OBSOLETE &emulation_vector, +// OBSOLETE #else +// OBSOLETE emulation_vector, +// OBSOLETE #endif +// OBSOLETE &n); +// OBSOLETE CHK ("task_get_emulation_vector", ret); +// OBSOLETE xx_debug ("%d vectors from %d at 0x%08x\n", +// OBSOLETE n, vector_start, emulation_vector); +// OBSOLETE +// OBSOLETE for (i = 0; i < n; i++) +// OBSOLETE { +// OBSOLETE vm_offset_t entry = emulation_vector[i]; +// OBSOLETE +// OBSOLETE if (EMULATOR_BASE <= entry && entry <= EMULATOR_END) +// OBSOLETE return TRUE; +// OBSOLETE else if (entry) +// OBSOLETE { +// OBSOLETE static boolean_t informed = FALSE; +// OBSOLETE if (!informed) +// OBSOLETE { +// OBSOLETE warning ("Emulation vector address 0x08%x outside emulator space", +// OBSOLETE entry); +// OBSOLETE informed = TRUE; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE } +// OBSOLETE return FALSE; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Map cprocs to kernel threads and vice versa. */ +// OBSOLETE +// OBSOLETE void +// OBSOLETE map_cprocs_to_kernel_threads (gdb_thread_t cprocs, gdb_thread_t mthreads, +// OBSOLETE int thread_count) +// OBSOLETE { +// OBSOLETE int index; +// OBSOLETE gdb_thread_t scan; +// OBSOLETE boolean_t all_mapped = TRUE; +// OBSOLETE LONGEST stack_base; +// OBSOLETE LONGEST stack_size; +// OBSOLETE +// OBSOLETE for (scan = cprocs; scan; scan = scan->next) +// OBSOLETE { +// OBSOLETE /* Default to: no kernel thread for this cproc */ +// OBSOLETE scan->reverse_map = -1; +// OBSOLETE +// OBSOLETE /* Check if the cproc is found by its stack */ +// OBSOLETE for (index = 0; index < thread_count; index++) +// OBSOLETE { +// OBSOLETE stack_base = +// OBSOLETE extract_signed_integer (scan->raw_cproc + CPROC_BASE_OFFSET, +// OBSOLETE CPROC_BASE_SIZE); +// OBSOLETE stack_size = +// OBSOLETE extract_signed_integer (scan->raw_cproc + CPROC_SIZE_OFFSET, +// OBSOLETE CPROC_SIZE_SIZE); +// OBSOLETE if ((mthreads + index)->sp > stack_base && +// OBSOLETE (mthreads + index)->sp <= stack_base + stack_size) +// OBSOLETE { +// OBSOLETE (mthreads + index)->cproc = scan; +// OBSOLETE scan->reverse_map = index; +// OBSOLETE break; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE all_mapped &= (scan->reverse_map != -1); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Check for threads that are currently in the emulator. +// OBSOLETE * If so, they have a different stack, and the still unmapped +// OBSOLETE * cprocs may well get mapped to these threads. +// OBSOLETE * +// OBSOLETE * If: +// OBSOLETE * - cproc stack does not match any kernel thread stack pointer +// OBSOLETE * - there is at least one extra kernel thread +// OBSOLETE * that has no cproc mapped above. +// OBSOLETE * - some kernel thread stack pointer points to emulator space +// OBSOLETE * then we find the user stack pointer saved in the emulator +// OBSOLETE * stack, and try to map that to the cprocs. +// OBSOLETE * +// OBSOLETE * Also set in_emulator for kernel threads. +// OBSOLETE */ +// OBSOLETE +// OBSOLETE if (emulator_present) +// OBSOLETE { +// OBSOLETE for (index = 0; index < thread_count; index++) +// OBSOLETE { +// OBSOLETE CORE_ADDR emul_sp; +// OBSOLETE CORE_ADDR usp; +// OBSOLETE +// OBSOLETE gdb_thread_t mthread = (mthreads + index); +// OBSOLETE emul_sp = mthread->sp; +// OBSOLETE +// OBSOLETE if (mthread->cproc == NULL && +// OBSOLETE EMULATOR_BASE <= emul_sp && emul_sp <= EMULATOR_END) +// OBSOLETE { +// OBSOLETE mthread->in_emulator = emulator_present; +// OBSOLETE +// OBSOLETE if (!all_mapped && cprocs) +// OBSOLETE { +// OBSOLETE usp = fetch_usp_from_emulator_stack (emul_sp); +// OBSOLETE +// OBSOLETE /* @@ Could be more accurate */ +// OBSOLETE if (!usp) +// OBSOLETE error ("Zero stack pointer read from emulator?"); +// OBSOLETE +// OBSOLETE /* Try to match this stack pointer to the cprocs that +// OBSOLETE * don't yet have a kernel thread. +// OBSOLETE */ +// OBSOLETE for (scan = cprocs; scan; scan = scan->next) +// OBSOLETE { +// OBSOLETE +// OBSOLETE /* Check is this unmapped CPROC stack contains +// OBSOLETE * the user stack pointer saved in the +// OBSOLETE * emulator. +// OBSOLETE */ +// OBSOLETE if (scan->reverse_map == -1) +// OBSOLETE { +// OBSOLETE stack_base = +// OBSOLETE extract_signed_integer +// OBSOLETE (scan->raw_cproc + CPROC_BASE_OFFSET, +// OBSOLETE CPROC_BASE_SIZE); +// OBSOLETE stack_size = +// OBSOLETE extract_signed_integer +// OBSOLETE (scan->raw_cproc + CPROC_SIZE_OFFSET, +// OBSOLETE CPROC_SIZE_SIZE); +// OBSOLETE if (usp > stack_base && +// OBSOLETE usp <= stack_base + stack_size) +// OBSOLETE { +// OBSOLETE mthread->cproc = scan; +// OBSOLETE scan->reverse_map = index; +// OBSOLETE break; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE } +// OBSOLETE } +// OBSOLETE } +// OBSOLETE } +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* +// OBSOLETE * Format of the thread_list command +// OBSOLETE * +// OBSOLETE * slot mid sel name emul ks susp cstate wired address +// OBSOLETE */ +// OBSOLETE #define TL_FORMAT "%-2.2s %5d%c %-10.10s %1.1s%s%-5.5s %-2.2s %-5.5s " +// OBSOLETE +// OBSOLETE #define TL_HEADER "\n@ MID Name KState CState Where\n" +// OBSOLETE +// OBSOLETE void +// OBSOLETE print_tl_address (struct ui_file *stream, CORE_ADDR pc) +// OBSOLETE { +// OBSOLETE if (!lookup_minimal_symbol_by_pc (pc)) +// OBSOLETE fprintf_filtered (stream, local_hex_format (), pc); +// OBSOLETE else +// OBSOLETE { +// OBSOLETE extern int addressprint; +// OBSOLETE extern int asm_demangle; +// OBSOLETE +// OBSOLETE int store = addressprint; +// OBSOLETE addressprint = 0; +// OBSOLETE print_address_symbolic (pc, stream, asm_demangle, ""); +// OBSOLETE addressprint = store; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* For thread names, but also for gdb_message_port external name */ +// OBSOLETE #define MAX_NAME_LEN 50 +// OBSOLETE +// OBSOLETE /* Returns the address of variable NAME or 0 if not found */ +// OBSOLETE CORE_ADDR +// OBSOLETE lookup_address_of_variable (char *name) +// OBSOLETE { +// OBSOLETE struct symbol *sym; +// OBSOLETE CORE_ADDR symaddr = 0; +// OBSOLETE struct minimal_symbol *msymbol; +// OBSOLETE +// OBSOLETE sym = lookup_symbol (name, +// OBSOLETE (struct block *) NULL, +// OBSOLETE VAR_NAMESPACE, +// OBSOLETE (int *) NULL, +// OBSOLETE (struct symtab **) NULL); +// OBSOLETE +// OBSOLETE if (sym) +// OBSOLETE symaddr = SYMBOL_VALUE (sym); +// OBSOLETE +// OBSOLETE if (!symaddr) +// OBSOLETE { +// OBSOLETE msymbol = lookup_minimal_symbol (name, NULL, NULL); +// OBSOLETE +// OBSOLETE if (msymbol && msymbol->type == mst_data) +// OBSOLETE symaddr = SYMBOL_VALUE_ADDRESS (msymbol); +// OBSOLETE } +// OBSOLETE +// OBSOLETE return symaddr; +// OBSOLETE } +// OBSOLETE +// OBSOLETE static gdb_thread_t +// OBSOLETE get_cprocs (void) +// OBSOLETE { +// OBSOLETE gdb_thread_t cproc_head; +// OBSOLETE gdb_thread_t cproc_copy; +// OBSOLETE CORE_ADDR their_cprocs; +// OBSOLETE char *buf; +// OBSOLETE char *name; +// OBSOLETE cthread_t cthread; +// OBSOLETE CORE_ADDR symaddr; +// OBSOLETE +// OBSOLETE buf = alloca (TARGET_PTR_BIT / HOST_CHAR_BIT); +// OBSOLETE symaddr = lookup_address_of_variable ("cproc_list"); +// OBSOLETE +// OBSOLETE if (!symaddr) +// OBSOLETE { +// OBSOLETE /* cproc_list is not in a file compiled with debugging +// OBSOLETE symbols, but don't give up yet */ +// OBSOLETE +// OBSOLETE symaddr = lookup_address_of_variable ("cprocs"); +// OBSOLETE +// OBSOLETE if (symaddr) +// OBSOLETE { +// OBSOLETE static int informed = 0; +// OBSOLETE if (!informed) +// OBSOLETE { +// OBSOLETE informed++; +// OBSOLETE warning ("Your program is loaded with an old threads library."); +// OBSOLETE warning ("GDB does not know the old form of threads"); +// OBSOLETE warning ("so things may not work."); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Stripped or no -lthreads loaded or "cproc_list" is in wrong segment. */ +// OBSOLETE if (!symaddr) +// OBSOLETE return NULL; +// OBSOLETE +// OBSOLETE /* Get the address of the first cproc in the task */ +// OBSOLETE if (!mach3_read_inferior (symaddr, +// OBSOLETE buf, +// OBSOLETE TARGET_PTR_BIT / HOST_CHAR_BIT)) +// OBSOLETE error ("Can't read cproc master list at address (0x%x).", symaddr); +// OBSOLETE their_cprocs = extract_address (buf, TARGET_PTR_BIT / HOST_CHAR_BIT); +// OBSOLETE +// OBSOLETE /* Scan the CPROCs in the task. +// OBSOLETE CPROCs are chained with LIST field, not NEXT field, which +// OBSOLETE chains mutexes, condition variables and queues */ +// OBSOLETE +// OBSOLETE cproc_head = NULL; +// OBSOLETE +// OBSOLETE while (their_cprocs != (CORE_ADDR) 0) +// OBSOLETE { +// OBSOLETE CORE_ADDR cproc_copy_incarnation; +// OBSOLETE cproc_copy = (gdb_thread_t) obstack_alloc (cproc_obstack, +// OBSOLETE sizeof (struct gdb_thread)); +// OBSOLETE +// OBSOLETE if (!mach3_read_inferior (their_cprocs, +// OBSOLETE &cproc_copy->raw_cproc[0], +// OBSOLETE CPROC_SIZE)) +// OBSOLETE error ("Can't read next cproc at 0x%x.", their_cprocs); +// OBSOLETE +// OBSOLETE their_cprocs = +// OBSOLETE extract_address (cproc_copy->raw_cproc + CPROC_LIST_OFFSET, +// OBSOLETE CPROC_LIST_SIZE); +// OBSOLETE cproc_copy_incarnation = +// OBSOLETE extract_address (cproc_copy->raw_cproc + CPROC_INCARNATION_OFFSET, +// OBSOLETE CPROC_INCARNATION_SIZE); +// OBSOLETE +// OBSOLETE if (cproc_copy_incarnation == (CORE_ADDR) 0) +// OBSOLETE cproc_copy->cthread = NULL; +// OBSOLETE else +// OBSOLETE { +// OBSOLETE /* This CPROC has an attached CTHREAD. Get its name */ +// OBSOLETE cthread = (cthread_t) obstack_alloc (cproc_obstack, +// OBSOLETE sizeof (struct cthread)); +// OBSOLETE +// OBSOLETE if (!mach3_read_inferior (cproc_copy_incarnation, +// OBSOLETE cthread, +// OBSOLETE sizeof (struct cthread))) +// OBSOLETE error ("Can't read next thread at 0x%x.", +// OBSOLETE cproc_copy_incarnation); +// OBSOLETE +// OBSOLETE cproc_copy->cthread = cthread; +// OBSOLETE +// OBSOLETE if (cthread->name) +// OBSOLETE { +// OBSOLETE name = (char *) obstack_alloc (cproc_obstack, MAX_NAME_LEN); +// OBSOLETE +// OBSOLETE if (!mach3_read_inferior (cthread->name, name, MAX_NAME_LEN)) +// OBSOLETE error ("Can't read next thread's name at 0x%x.", cthread->name); +// OBSOLETE +// OBSOLETE cthread->name = name; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* insert in front */ +// OBSOLETE cproc_copy->next = cproc_head; +// OBSOLETE cproc_head = cproc_copy; +// OBSOLETE } +// OBSOLETE return cproc_head; +// OBSOLETE } +// OBSOLETE +// OBSOLETE #ifndef FETCH_CPROC_STATE +// OBSOLETE /* +// OBSOLETE * Check if your machine does not grok the way this routine +// OBSOLETE * fetches the FP,PC and SP of a cproc that is not +// OBSOLETE * currently attached to any kernel thread (e.g. its cproc.context +// OBSOLETE * field points to the place in stack where the context +// OBSOLETE * is saved). +// OBSOLETE * +// OBSOLETE * If it doesn't, define your own routine. +// OBSOLETE */ +// OBSOLETE #define FETCH_CPROC_STATE(mth) mach3_cproc_state (mth) +// OBSOLETE +// OBSOLETE int +// OBSOLETE mach3_cproc_state (gdb_thread_t mthread) +// OBSOLETE { +// OBSOLETE int context; +// OBSOLETE +// OBSOLETE if (!mthread || !mthread->cproc) +// OBSOLETE return -1; +// OBSOLETE +// OBSOLETE context = extract_signed_integer +// OBSOLETE (mthread->cproc->raw_cproc + CPROC_CONTEXT_OFFSET, +// OBSOLETE CPROC_CONTEXT_SIZE); +// OBSOLETE if (context == 0) +// OBSOLETE return -1; +// OBSOLETE +// OBSOLETE mthread->sp = context + MACHINE_CPROC_SP_OFFSET; +// OBSOLETE +// OBSOLETE if (mach3_read_inferior (context + MACHINE_CPROC_PC_OFFSET, +// OBSOLETE &mthread->pc, +// OBSOLETE sizeof (CORE_ADDR)) != sizeof (CORE_ADDR)) +// OBSOLETE { +// OBSOLETE warning ("Can't read cproc pc from inferior"); +// OBSOLETE return -1; +// OBSOLETE } +// OBSOLETE +// OBSOLETE if (mach3_read_inferior (context + MACHINE_CPROC_FP_OFFSET, +// OBSOLETE &mthread->fp, +// OBSOLETE sizeof (CORE_ADDR)) != sizeof (CORE_ADDR)) +// OBSOLETE { +// OBSOLETE warning ("Can't read cproc fp from inferior"); +// OBSOLETE return -1; +// OBSOLETE } +// OBSOLETE +// OBSOLETE return 0; +// OBSOLETE } +// OBSOLETE #endif /* FETCH_CPROC_STATE */ +// OBSOLETE +// OBSOLETE +// OBSOLETE void +// OBSOLETE thread_list_command (void) +// OBSOLETE { +// OBSOLETE thread_basic_info_data_t ths; +// OBSOLETE int thread_count; +// OBSOLETE gdb_thread_t cprocs; +// OBSOLETE gdb_thread_t scan; +// OBSOLETE int index; +// OBSOLETE char *name; +// OBSOLETE char selected; +// OBSOLETE char *wired; +// OBSOLETE int infoCnt; +// OBSOLETE kern_return_t ret; +// OBSOLETE mach_port_t mid_or_port; +// OBSOLETE gdb_thread_t their_threads; +// OBSOLETE gdb_thread_t kthread; +// OBSOLETE +// OBSOLETE int neworder = 1; +// OBSOLETE +// OBSOLETE char *fmt = "There are %d kernel threads in task %d.\n"; +// OBSOLETE +// OBSOLETE int tmid = map_port_name_to_mid (inferior_task, MACH_TYPE_TASK); +// OBSOLETE +// OBSOLETE MACH_ERROR_NO_INFERIOR; +// OBSOLETE +// OBSOLETE thread_count = fetch_thread_info (inferior_task, +// OBSOLETE &their_threads); +// OBSOLETE if (thread_count == -1) +// OBSOLETE return; +// OBSOLETE +// OBSOLETE if (thread_count == 1) +// OBSOLETE fmt = "There is %d kernel thread in task %d.\n"; +// OBSOLETE +// OBSOLETE printf_filtered (fmt, thread_count, tmid); +// OBSOLETE +// OBSOLETE puts_filtered (TL_HEADER); +// OBSOLETE +// OBSOLETE cprocs = get_cprocs (); +// OBSOLETE +// OBSOLETE map_cprocs_to_kernel_threads (cprocs, their_threads, thread_count); +// OBSOLETE +// OBSOLETE for (scan = cprocs; scan; scan = scan->next) +// OBSOLETE { +// OBSOLETE int mid; +// OBSOLETE char buf[10]; +// OBSOLETE char slot[3]; +// OBSOLETE int cproc_state = +// OBSOLETE extract_signed_integer +// OBSOLETE (scan->raw_cproc + CPROC_STATE_OFFSET, CPROC_STATE_SIZE); +// OBSOLETE +// OBSOLETE selected = ' '; +// OBSOLETE +// OBSOLETE /* a wired cproc? */ +// OBSOLETE wired = (extract_address (scan->raw_cproc + CPROC_WIRED_OFFSET, +// OBSOLETE CPROC_WIRED_SIZE) +// OBSOLETE ? "wired" : ""); +// OBSOLETE +// OBSOLETE if (scan->reverse_map != -1) +// OBSOLETE kthread = (their_threads + scan->reverse_map); +// OBSOLETE else +// OBSOLETE kthread = NULL; +// OBSOLETE +// OBSOLETE if (kthread) +// OBSOLETE { +// OBSOLETE /* These cprocs have a kernel thread */ +// OBSOLETE +// OBSOLETE mid = map_port_name_to_mid (kthread->name, MACH_TYPE_THREAD); +// OBSOLETE +// OBSOLETE infoCnt = THREAD_BASIC_INFO_COUNT; +// OBSOLETE +// OBSOLETE ret = thread_info (kthread->name, +// OBSOLETE THREAD_BASIC_INFO, +// OBSOLETE (thread_info_t) & ths, +// OBSOLETE &infoCnt); +// OBSOLETE +// OBSOLETE if (ret != KERN_SUCCESS) +// OBSOLETE { +// OBSOLETE warning ("Unable to get basic info on thread %d : %s", +// OBSOLETE mid, +// OBSOLETE mach_error_string (ret)); +// OBSOLETE continue; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Who is the first to have more than 100 threads */ +// OBSOLETE sprintf (slot, "%d", kthread->slotid % 100); +// OBSOLETE +// OBSOLETE if (kthread->name == current_thread) +// OBSOLETE selected = '*'; +// OBSOLETE +// OBSOLETE if (ths.suspend_count) +// OBSOLETE sprintf (buf, "%d", ths.suspend_count); +// OBSOLETE else +// OBSOLETE buf[0] = '\000'; +// OBSOLETE +// OBSOLETE #if 0 +// OBSOLETE if (ths.flags & TH_FLAGS_SWAPPED) +// OBSOLETE strcat (buf, "S"); +// OBSOLETE #endif +// OBSOLETE +// OBSOLETE if (ths.flags & TH_FLAGS_IDLE) +// OBSOLETE strcat (buf, "I"); +// OBSOLETE +// OBSOLETE printf_filtered (TL_FORMAT, +// OBSOLETE slot, +// OBSOLETE mid, +// OBSOLETE selected, +// OBSOLETE get_thread_name (scan, kthread->slotid), +// OBSOLETE kthread->in_emulator ? "E" : "", +// OBSOLETE translate_state (ths.run_state), +// OBSOLETE buf, +// OBSOLETE translate_cstate (cproc_state), +// OBSOLETE wired); +// OBSOLETE print_tl_address (gdb_stdout, kthread->pc); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE /* These cprocs don't have a kernel thread. +// OBSOLETE * find out the calling frame with +// OBSOLETE * FETCH_CPROC_STATE. +// OBSOLETE */ +// OBSOLETE +// OBSOLETE struct gdb_thread state; +// OBSOLETE +// OBSOLETE #if 0 +// OBSOLETE /* jtv -> emcmanus: why do you want this here? */ +// OBSOLETE if (scan->incarnation == NULL) +// OBSOLETE continue; /* EMcM */ +// OBSOLETE #endif +// OBSOLETE +// OBSOLETE printf_filtered (TL_FORMAT, +// OBSOLETE "-", +// OBSOLETE -neworder, /* Pseudo MID */ +// OBSOLETE selected, +// OBSOLETE get_thread_name (scan, -neworder), +// OBSOLETE "", +// OBSOLETE "-", /* kernel state */ +// OBSOLETE "", +// OBSOLETE translate_cstate (cproc_state), +// OBSOLETE ""); +// OBSOLETE state.cproc = scan; +// OBSOLETE +// OBSOLETE if (FETCH_CPROC_STATE (&state) == -1) +// OBSOLETE puts_filtered ("???"); +// OBSOLETE else +// OBSOLETE print_tl_address (gdb_stdout, state.pc); +// OBSOLETE +// OBSOLETE neworder++; +// OBSOLETE } +// OBSOLETE puts_filtered ("\n"); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Scan for kernel threads without cprocs */ +// OBSOLETE for (index = 0; index < thread_count; index++) +// OBSOLETE { +// OBSOLETE if (!their_threads[index].cproc) +// OBSOLETE { +// OBSOLETE int mid; +// OBSOLETE +// OBSOLETE char buf[10]; +// OBSOLETE char slot[3]; +// OBSOLETE +// OBSOLETE mach_port_t name = their_threads[index].name; +// OBSOLETE +// OBSOLETE mid = map_port_name_to_mid (name, MACH_TYPE_THREAD); +// OBSOLETE +// OBSOLETE infoCnt = THREAD_BASIC_INFO_COUNT; +// OBSOLETE +// OBSOLETE ret = thread_info (name, +// OBSOLETE THREAD_BASIC_INFO, +// OBSOLETE (thread_info_t) & ths, +// OBSOLETE &infoCnt); +// OBSOLETE +// OBSOLETE if (ret != KERN_SUCCESS) +// OBSOLETE { +// OBSOLETE warning ("Unable to get basic info on thread %d : %s", +// OBSOLETE mid, +// OBSOLETE mach_error_string (ret)); +// OBSOLETE continue; +// OBSOLETE } +// OBSOLETE +// OBSOLETE sprintf (slot, "%d", index % 100); +// OBSOLETE +// OBSOLETE if (name == current_thread) +// OBSOLETE selected = '*'; +// OBSOLETE else +// OBSOLETE selected = ' '; +// OBSOLETE +// OBSOLETE if (ths.suspend_count) +// OBSOLETE sprintf (buf, "%d", ths.suspend_count); +// OBSOLETE else +// OBSOLETE buf[0] = '\000'; +// OBSOLETE +// OBSOLETE #if 0 +// OBSOLETE if (ths.flags & TH_FLAGS_SWAPPED) +// OBSOLETE strcat (buf, "S"); +// OBSOLETE #endif +// OBSOLETE +// OBSOLETE if (ths.flags & TH_FLAGS_IDLE) +// OBSOLETE strcat (buf, "I"); +// OBSOLETE +// OBSOLETE printf_filtered (TL_FORMAT, +// OBSOLETE slot, +// OBSOLETE mid, +// OBSOLETE selected, +// OBSOLETE get_thread_name (NULL, index), +// OBSOLETE their_threads[index].in_emulator ? "E" : "", +// OBSOLETE translate_state (ths.run_state), +// OBSOLETE buf, +// OBSOLETE "", /* No cproc state */ +// OBSOLETE ""); /* Can't be wired */ +// OBSOLETE print_tl_address (gdb_stdout, their_threads[index].pc); +// OBSOLETE puts_filtered ("\n"); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE obstack_free (cproc_obstack, 0); +// OBSOLETE obstack_init (cproc_obstack); +// OBSOLETE } +// OBSOLETE +// OBSOLETE void +// OBSOLETE thread_select_command (char *args, int from_tty) +// OBSOLETE { +// OBSOLETE int mid; +// OBSOLETE thread_array_t thread_list; +// OBSOLETE int thread_count; +// OBSOLETE kern_return_t ret; +// OBSOLETE int is_slot = 0; +// OBSOLETE +// OBSOLETE MACH_ERROR_NO_INFERIOR; +// OBSOLETE +// OBSOLETE if (!args) +// OBSOLETE error_no_arg ("MID or @SLOTNUMBER to specify a thread to select"); +// OBSOLETE +// OBSOLETE while (*args == ' ' || *args == '\t') +// OBSOLETE args++; +// OBSOLETE +// OBSOLETE if (*args == '@') +// OBSOLETE { +// OBSOLETE is_slot++; +// OBSOLETE args++; +// OBSOLETE } +// OBSOLETE +// OBSOLETE mid = atoi (args); +// OBSOLETE +// OBSOLETE if (mid == 0) +// OBSOLETE if (!is_slot || *args != '0') /* Rudimentary checks */ +// OBSOLETE error ("You must select threads by MID or @SLOTNUMBER"); +// OBSOLETE +// OBSOLETE if (select_thread (inferior_task, mid, is_slot ? 2 : 1) != KERN_SUCCESS) +// OBSOLETE return; +// OBSOLETE +// OBSOLETE if (from_tty) +// OBSOLETE printf_filtered ("Thread %d selected\n", +// OBSOLETE is_slot ? map_port_name_to_mid (current_thread, +// OBSOLETE MACH_TYPE_THREAD) : mid); +// OBSOLETE } +// OBSOLETE +// OBSOLETE thread_trace (mach_port_t thread, boolean_t set) +// OBSOLETE { +// OBSOLETE int flavor = TRACE_FLAVOR; +// OBSOLETE unsigned int stateCnt = TRACE_FLAVOR_SIZE; +// OBSOLETE kern_return_t ret; +// OBSOLETE thread_state_data_t state; +// OBSOLETE +// OBSOLETE if (!MACH_PORT_VALID (thread)) +// OBSOLETE { +// OBSOLETE warning ("thread_trace: invalid thread"); +// OBSOLETE return; +// OBSOLETE } +// OBSOLETE +// OBSOLETE if (must_suspend_thread) +// OBSOLETE setup_thread (thread, 1); +// OBSOLETE +// OBSOLETE ret = thread_get_state (thread, flavor, state, &stateCnt); +// OBSOLETE CHK ("thread_trace: error reading thread state", ret); +// OBSOLETE +// OBSOLETE if (set) +// OBSOLETE { +// OBSOLETE TRACE_SET (thread, state); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE if (!TRACE_CLEAR (thread, state)) +// OBSOLETE { +// OBSOLETE if (must_suspend_thread) +// OBSOLETE setup_thread (thread, 0); +// OBSOLETE return; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE ret = thread_set_state (thread, flavor, state, stateCnt); +// OBSOLETE CHK ("thread_trace: error writing thread state", ret); +// OBSOLETE if (must_suspend_thread) +// OBSOLETE setup_thread (thread, 0); +// OBSOLETE } +// OBSOLETE +// OBSOLETE #ifdef FLUSH_INFERIOR_CACHE +// OBSOLETE +// OBSOLETE /* When over-writing code on some machines the I-Cache must be flushed +// OBSOLETE explicitly, because it is not kept coherent by the lazy hardware. +// OBSOLETE This definitely includes breakpoints, for instance, or else we +// OBSOLETE end up looping in mysterious Bpt traps */ +// OBSOLETE +// OBSOLETE flush_inferior_icache (CORE_ADDR pc, int amount) +// OBSOLETE { +// OBSOLETE vm_machine_attribute_val_t flush = MATTR_VAL_ICACHE_FLUSH; +// OBSOLETE kern_return_t ret; +// OBSOLETE +// OBSOLETE ret = vm_machine_attribute (inferior_task, +// OBSOLETE pc, +// OBSOLETE amount, +// OBSOLETE MATTR_CACHE, +// OBSOLETE &flush); +// OBSOLETE if (ret != KERN_SUCCESS) +// OBSOLETE warning ("Error flushing inferior's cache : %s", +// OBSOLETE mach_error_string (ret)); +// OBSOLETE } +// OBSOLETE #endif /* FLUSH_INFERIOR_CACHE */ +// OBSOLETE +// OBSOLETE +// OBSOLETE static +// OBSOLETE suspend_all_threads (int from_tty) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE thread_array_t thread_list; +// OBSOLETE int thread_count, index; +// OBSOLETE int infoCnt; +// OBSOLETE thread_basic_info_data_t th_info; +// OBSOLETE +// OBSOLETE +// OBSOLETE ret = task_threads (inferior_task, &thread_list, &thread_count); +// OBSOLETE if (ret != KERN_SUCCESS) +// OBSOLETE { +// OBSOLETE warning ("Could not suspend inferior threads."); +// OBSOLETE m3_kill_inferior (); +// OBSOLETE throw_exception (RETURN_ERROR); +// OBSOLETE } +// OBSOLETE +// OBSOLETE for (index = 0; index < thread_count; index++) +// OBSOLETE { +// OBSOLETE int mid; +// OBSOLETE +// OBSOLETE mid = map_port_name_to_mid (thread_list[index], +// OBSOLETE MACH_TYPE_THREAD); +// OBSOLETE +// OBSOLETE ret = thread_suspend (thread_list[index]); +// OBSOLETE +// OBSOLETE if (ret != KERN_SUCCESS) +// OBSOLETE warning ("Error trying to suspend thread %d : %s", +// OBSOLETE mid, mach_error_string (ret)); +// OBSOLETE +// OBSOLETE if (from_tty) +// OBSOLETE { +// OBSOLETE infoCnt = THREAD_BASIC_INFO_COUNT; +// OBSOLETE ret = thread_info (thread_list[index], +// OBSOLETE THREAD_BASIC_INFO, +// OBSOLETE (thread_info_t) & th_info, +// OBSOLETE &infoCnt); +// OBSOLETE CHK ("suspend can't get thread info", ret); +// OBSOLETE +// OBSOLETE warning ("Thread %d suspend count is %d", +// OBSOLETE mid, th_info.suspend_count); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE consume_send_rights (thread_list, thread_count); +// OBSOLETE ret = vm_deallocate (mach_task_self (), +// OBSOLETE (vm_address_t) thread_list, +// OBSOLETE (thread_count * sizeof (int))); +// OBSOLETE CHK ("Error trying to deallocate thread list", ret); +// OBSOLETE } +// OBSOLETE +// OBSOLETE void +// OBSOLETE thread_suspend_command (char *args, int from_tty) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE int mid; +// OBSOLETE mach_port_t saved_thread; +// OBSOLETE int infoCnt; +// OBSOLETE thread_basic_info_data_t th_info; +// OBSOLETE +// OBSOLETE MACH_ERROR_NO_INFERIOR; +// OBSOLETE +// OBSOLETE if (!strcasecmp (args, "all")) +// OBSOLETE { +// OBSOLETE suspend_all_threads (from_tty); +// OBSOLETE return; +// OBSOLETE } +// OBSOLETE +// OBSOLETE saved_thread = current_thread; +// OBSOLETE +// OBSOLETE mid = parse_thread_id (args, 0, 0); +// OBSOLETE +// OBSOLETE if (mid < 0) +// OBSOLETE error ("You can suspend only existing kernel threads with MID or @SLOTNUMBER"); +// OBSOLETE +// OBSOLETE if (mid == 0) +// OBSOLETE mid = map_port_name_to_mid (current_thread, MACH_TYPE_THREAD); +// OBSOLETE else if (select_thread (inferior_task, mid, 0) != KERN_SUCCESS) +// OBSOLETE { +// OBSOLETE if (current_thread) +// OBSOLETE current_thread = saved_thread; +// OBSOLETE error ("Could not select thread %d", mid); +// OBSOLETE } +// OBSOLETE +// OBSOLETE ret = thread_suspend (current_thread); +// OBSOLETE if (ret != KERN_SUCCESS) +// OBSOLETE warning ("thread_suspend failed : %s", +// OBSOLETE mach_error_string (ret)); +// OBSOLETE +// OBSOLETE infoCnt = THREAD_BASIC_INFO_COUNT; +// OBSOLETE ret = thread_info (current_thread, +// OBSOLETE THREAD_BASIC_INFO, +// OBSOLETE (thread_info_t) & th_info, +// OBSOLETE &infoCnt); +// OBSOLETE CHK ("suspend can't get thread info", ret); +// OBSOLETE +// OBSOLETE warning ("Thread %d suspend count is %d", mid, th_info.suspend_count); +// OBSOLETE +// OBSOLETE current_thread = saved_thread; +// OBSOLETE } +// OBSOLETE +// OBSOLETE resume_all_threads (int from_tty) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE thread_array_t thread_list; +// OBSOLETE int thread_count, index; +// OBSOLETE int mid; +// OBSOLETE int infoCnt; +// OBSOLETE thread_basic_info_data_t th_info; +// OBSOLETE +// OBSOLETE ret = task_threads (inferior_task, &thread_list, &thread_count); +// OBSOLETE if (ret != KERN_SUCCESS) +// OBSOLETE { +// OBSOLETE m3_kill_inferior (); +// OBSOLETE error ("task_threads", mach_error_string (ret)); +// OBSOLETE } +// OBSOLETE +// OBSOLETE for (index = 0; index < thread_count; index++) +// OBSOLETE { +// OBSOLETE infoCnt = THREAD_BASIC_INFO_COUNT; +// OBSOLETE ret = thread_info (thread_list[index], +// OBSOLETE THREAD_BASIC_INFO, +// OBSOLETE (thread_info_t) & th_info, +// OBSOLETE &infoCnt); +// OBSOLETE CHK ("resume_all can't get thread info", ret); +// OBSOLETE +// OBSOLETE mid = map_port_name_to_mid (thread_list[index], +// OBSOLETE MACH_TYPE_THREAD); +// OBSOLETE +// OBSOLETE if (!th_info.suspend_count) +// OBSOLETE { +// OBSOLETE if (mid != -1 && from_tty) +// OBSOLETE warning ("Thread %d is not suspended", mid); +// OBSOLETE continue; +// OBSOLETE } +// OBSOLETE +// OBSOLETE ret = thread_resume (thread_list[index]); +// OBSOLETE +// OBSOLETE if (ret != KERN_SUCCESS) +// OBSOLETE warning ("Error trying to resume thread %d : %s", +// OBSOLETE mid, mach_error_string (ret)); +// OBSOLETE else if (mid != -1 && from_tty) +// OBSOLETE warning ("Thread %d suspend count is %d", +// OBSOLETE mid, --th_info.suspend_count); +// OBSOLETE } +// OBSOLETE +// OBSOLETE consume_send_rights (thread_list, thread_count); +// OBSOLETE ret = vm_deallocate (mach_task_self (), +// OBSOLETE (vm_address_t) thread_list, +// OBSOLETE (thread_count * sizeof (int))); +// OBSOLETE CHK ("Error trying to deallocate thread list", ret); +// OBSOLETE } +// OBSOLETE +// OBSOLETE void +// OBSOLETE thread_resume_command (char *args, int from_tty) +// OBSOLETE { +// OBSOLETE int mid; +// OBSOLETE mach_port_t saved_thread; +// OBSOLETE kern_return_t ret; +// OBSOLETE thread_basic_info_data_t th_info; +// OBSOLETE int infoCnt = THREAD_BASIC_INFO_COUNT; +// OBSOLETE +// OBSOLETE MACH_ERROR_NO_INFERIOR; +// OBSOLETE +// OBSOLETE if (!strcasecmp (args, "all")) +// OBSOLETE { +// OBSOLETE resume_all_threads (from_tty); +// OBSOLETE return; +// OBSOLETE } +// OBSOLETE +// OBSOLETE saved_thread = current_thread; +// OBSOLETE +// OBSOLETE mid = parse_thread_id (args, 0, 0); +// OBSOLETE +// OBSOLETE if (mid < 0) +// OBSOLETE error ("You can resume only existing kernel threads with MID or @SLOTNUMBER"); +// OBSOLETE +// OBSOLETE if (mid == 0) +// OBSOLETE mid = map_port_name_to_mid (current_thread, MACH_TYPE_THREAD); +// OBSOLETE else if (select_thread (inferior_task, mid, 0) != KERN_SUCCESS) +// OBSOLETE { +// OBSOLETE if (current_thread) +// OBSOLETE current_thread = saved_thread; +// OBSOLETE throw_exception (RETURN_ERROR); +// OBSOLETE } +// OBSOLETE +// OBSOLETE ret = thread_info (current_thread, +// OBSOLETE THREAD_BASIC_INFO, +// OBSOLETE (thread_info_t) & th_info, +// OBSOLETE &infoCnt); +// OBSOLETE CHK ("resume can't get thread info", ret); +// OBSOLETE +// OBSOLETE if (!th_info.suspend_count) +// OBSOLETE { +// OBSOLETE warning ("Thread %d is not suspended", mid); +// OBSOLETE goto out; +// OBSOLETE } +// OBSOLETE +// OBSOLETE ret = thread_resume (current_thread); +// OBSOLETE if (ret != KERN_SUCCESS) +// OBSOLETE warning ("thread_resume failed : %s", +// OBSOLETE mach_error_string (ret)); +// OBSOLETE else +// OBSOLETE { +// OBSOLETE th_info.suspend_count--; +// OBSOLETE warning ("Thread %d suspend count is %d", mid, th_info.suspend_count); +// OBSOLETE } +// OBSOLETE +// OBSOLETE out: +// OBSOLETE current_thread = saved_thread; +// OBSOLETE } +// OBSOLETE +// OBSOLETE void +// OBSOLETE thread_kill_command (char *args, int from_tty) +// OBSOLETE { +// OBSOLETE int mid; +// OBSOLETE kern_return_t ret; +// OBSOLETE int thread_count; +// OBSOLETE thread_array_t thread_table; +// OBSOLETE int index; +// OBSOLETE mach_port_t thread_to_kill = MACH_PORT_NULL; +// OBSOLETE +// OBSOLETE +// OBSOLETE MACH_ERROR_NO_INFERIOR; +// OBSOLETE +// OBSOLETE if (!args) +// OBSOLETE error_no_arg ("thread mid to kill from the inferior task"); +// OBSOLETE +// OBSOLETE mid = parse_thread_id (args, 0, 0); +// OBSOLETE +// OBSOLETE if (mid < 0) +// OBSOLETE error ("You can kill only existing kernel threads with MID or @SLOTNUMBER"); +// OBSOLETE +// OBSOLETE if (mid) +// OBSOLETE { +// OBSOLETE ret = machid_mach_port (mid_server, mid_auth, mid, &thread_to_kill); +// OBSOLETE CHK ("thread_kill_command: machid_mach_port map failed", ret); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE mid = map_port_name_to_mid (current_thread, MACH_TYPE_THREAD); +// OBSOLETE +// OBSOLETE /* Don't allow gdb to kill *any* thread in the system. Use mkill program for that */ +// OBSOLETE ret = task_threads (inferior_task, &thread_table, &thread_count); +// OBSOLETE CHK ("Error getting inferior's thread list", ret); +// OBSOLETE +// OBSOLETE if (thread_to_kill == current_thread) +// OBSOLETE { +// OBSOLETE ret = thread_terminate (thread_to_kill); +// OBSOLETE CHK ("Thread could not be terminated", ret); +// OBSOLETE +// OBSOLETE if (select_thread (inferior_task, 0, 1) != KERN_SUCCESS) +// OBSOLETE warning ("Last thread was killed, use \"kill\" command to kill task"); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE for (index = 0; index < thread_count; index++) +// OBSOLETE if (thread_table[index] == thread_to_kill) +// OBSOLETE { +// OBSOLETE ret = thread_terminate (thread_to_kill); +// OBSOLETE CHK ("Thread could not be terminated", ret); +// OBSOLETE } +// OBSOLETE +// OBSOLETE if (thread_count > 1) +// OBSOLETE consume_send_rights (thread_table, thread_count); +// OBSOLETE +// OBSOLETE ret = vm_deallocate (mach_task_self (), (vm_address_t) thread_table, +// OBSOLETE (thread_count * sizeof (mach_port_t))); +// OBSOLETE CHK ("Error trying to deallocate thread list", ret); +// OBSOLETE +// OBSOLETE warning ("Thread %d killed", mid); +// OBSOLETE } +// OBSOLETE +// OBSOLETE +// OBSOLETE /* Task specific commands; add more if you like */ +// OBSOLETE +// OBSOLETE void +// OBSOLETE task_resume_command (char *args, int from_tty) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE task_basic_info_data_t ta_info; +// OBSOLETE int infoCnt = TASK_BASIC_INFO_COUNT; +// OBSOLETE int mid = map_port_name_to_mid (inferior_task, MACH_TYPE_TASK); +// OBSOLETE +// OBSOLETE MACH_ERROR_NO_INFERIOR; +// OBSOLETE +// OBSOLETE /* Would be trivial to change, but is it desirable? */ +// OBSOLETE if (args) +// OBSOLETE error ("Currently gdb can resume only it's inferior task"); +// OBSOLETE +// OBSOLETE ret = task_info (inferior_task, +// OBSOLETE TASK_BASIC_INFO, +// OBSOLETE (task_info_t) & ta_info, +// OBSOLETE &infoCnt); +// OBSOLETE CHK ("task_resume_command: task_info failed", ret); +// OBSOLETE +// OBSOLETE if (ta_info.suspend_count == 0) +// OBSOLETE error ("Inferior task %d is not suspended", mid); +// OBSOLETE else if (ta_info.suspend_count == 1 && +// OBSOLETE from_tty && +// OBSOLETE !query ("Suspend count is now 1. Do you know what you are doing? ")) +// OBSOLETE error ("Task not resumed"); +// OBSOLETE +// OBSOLETE ret = task_resume (inferior_task); +// OBSOLETE CHK ("task_resume_command: task_resume", ret); +// OBSOLETE +// OBSOLETE if (ta_info.suspend_count == 1) +// OBSOLETE { +// OBSOLETE warning ("Inferior task %d is no longer suspended", mid); +// OBSOLETE must_suspend_thread = 1; +// OBSOLETE /* @@ This is not complete: Registers change all the time when not +// OBSOLETE suspended! */ +// OBSOLETE registers_changed (); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE warning ("Inferior task %d suspend count is now %d", +// OBSOLETE mid, ta_info.suspend_count - 1); +// OBSOLETE } +// OBSOLETE +// OBSOLETE +// OBSOLETE void +// OBSOLETE task_suspend_command (char *args, int from_tty) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE task_basic_info_data_t ta_info; +// OBSOLETE int infoCnt = TASK_BASIC_INFO_COUNT; +// OBSOLETE int mid = map_port_name_to_mid (inferior_task, MACH_TYPE_TASK); +// OBSOLETE +// OBSOLETE MACH_ERROR_NO_INFERIOR; +// OBSOLETE +// OBSOLETE /* Would be trivial to change, but is it desirable? */ +// OBSOLETE if (args) +// OBSOLETE error ("Currently gdb can suspend only it's inferior task"); +// OBSOLETE +// OBSOLETE ret = task_suspend (inferior_task); +// OBSOLETE CHK ("task_suspend_command: task_suspend", ret); +// OBSOLETE +// OBSOLETE must_suspend_thread = 0; +// OBSOLETE +// OBSOLETE ret = task_info (inferior_task, +// OBSOLETE TASK_BASIC_INFO, +// OBSOLETE (task_info_t) & ta_info, +// OBSOLETE &infoCnt); +// OBSOLETE CHK ("task_suspend_command: task_info failed", ret); +// OBSOLETE +// OBSOLETE warning ("Inferior task %d suspend count is now %d", +// OBSOLETE mid, ta_info.suspend_count); +// OBSOLETE } +// OBSOLETE +// OBSOLETE static char * +// OBSOLETE get_size (int bytes) +// OBSOLETE { +// OBSOLETE static char size[30]; +// OBSOLETE int zz = bytes / 1024; +// OBSOLETE +// OBSOLETE if (zz / 1024) +// OBSOLETE sprintf (size, "%-2.1f M", ((float) bytes) / (1024.0 * 1024.0)); +// OBSOLETE else +// OBSOLETE sprintf (size, "%d K", zz); +// OBSOLETE +// OBSOLETE return size; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Does this require the target task to be suspended?? I don't think so. */ +// OBSOLETE void +// OBSOLETE task_info_command (char *args, int from_tty) +// OBSOLETE { +// OBSOLETE int mid = -5; +// OBSOLETE mach_port_t task; +// OBSOLETE kern_return_t ret; +// OBSOLETE task_basic_info_data_t ta_info; +// OBSOLETE int infoCnt = TASK_BASIC_INFO_COUNT; +// OBSOLETE int page_size = round_page (1); +// OBSOLETE int thread_count = 0; +// OBSOLETE +// OBSOLETE if (MACH_PORT_VALID (inferior_task)) +// OBSOLETE mid = map_port_name_to_mid (inferior_task, +// OBSOLETE MACH_TYPE_TASK); +// OBSOLETE +// OBSOLETE task = inferior_task; +// OBSOLETE +// OBSOLETE if (args) +// OBSOLETE { +// OBSOLETE int tmid = atoi (args); +// OBSOLETE +// OBSOLETE if (tmid <= 0) +// OBSOLETE error ("Invalid mid %d for task info", tmid); +// OBSOLETE +// OBSOLETE if (tmid != mid) +// OBSOLETE { +// OBSOLETE mid = tmid; +// OBSOLETE ret = machid_mach_port (mid_server, mid_auth, tmid, &task); +// OBSOLETE CHK ("task_info_command: machid_mach_port map failed", ret); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE if (mid < 0) +// OBSOLETE error ("You have to give the task MID as an argument"); +// OBSOLETE +// OBSOLETE ret = task_info (task, +// OBSOLETE TASK_BASIC_INFO, +// OBSOLETE (task_info_t) & ta_info, +// OBSOLETE &infoCnt); +// OBSOLETE CHK ("task_info_command: task_info failed", ret); +// OBSOLETE +// OBSOLETE printf_filtered ("\nTask info for task %d:\n\n", mid); +// OBSOLETE printf_filtered (" Suspend count : %d\n", ta_info.suspend_count); +// OBSOLETE printf_filtered (" Base priority : %d\n", ta_info.base_priority); +// OBSOLETE printf_filtered (" Virtual size : %s\n", get_size (ta_info.virtual_size)); +// OBSOLETE printf_filtered (" Resident size : %s\n", get_size (ta_info.resident_size)); +// OBSOLETE +// OBSOLETE { +// OBSOLETE thread_array_t thread_list; +// OBSOLETE +// OBSOLETE ret = task_threads (task, &thread_list, &thread_count); +// OBSOLETE CHK ("task_info_command: task_threads", ret); +// OBSOLETE +// OBSOLETE printf_filtered (" Thread count : %d\n", thread_count); +// OBSOLETE +// OBSOLETE consume_send_rights (thread_list, thread_count); +// OBSOLETE ret = vm_deallocate (mach_task_self (), +// OBSOLETE (vm_address_t) thread_list, +// OBSOLETE (thread_count * sizeof (int))); +// OBSOLETE CHK ("Error trying to deallocate thread list", ret); +// OBSOLETE } +// OBSOLETE if (have_emulator_p (task)) +// OBSOLETE printf_filtered (" Emulator at : 0x%x..0x%x\n", +// OBSOLETE EMULATOR_BASE, EMULATOR_END); +// OBSOLETE else +// OBSOLETE printf_filtered (" No emulator.\n"); +// OBSOLETE +// OBSOLETE if (thread_count && task == inferior_task) +// OBSOLETE printf_filtered ("\nUse the \"thread list\" command to see the threads\n"); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* You may either FORWARD the exception to the inferior, or KEEP +// OBSOLETE * it and return to GDB command level. +// OBSOLETE * +// OBSOLETE * exception mid [ forward | keep ] +// OBSOLETE */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE exception_command (char *args, int from_tty) +// OBSOLETE { +// OBSOLETE char *scan = args; +// OBSOLETE int exception; +// OBSOLETE int len; +// OBSOLETE +// OBSOLETE if (!args) +// OBSOLETE error_no_arg ("exception number action"); +// OBSOLETE +// OBSOLETE while (*scan == ' ' || *scan == '\t') +// OBSOLETE scan++; +// OBSOLETE +// OBSOLETE if ('0' <= *scan && *scan <= '9') +// OBSOLETE while ('0' <= *scan && *scan <= '9') +// OBSOLETE scan++; +// OBSOLETE else +// OBSOLETE error ("exception number action"); +// OBSOLETE +// OBSOLETE exception = atoi (args); +// OBSOLETE if (exception <= 0 || exception > MAX_EXCEPTION) +// OBSOLETE error ("Allowed exception numbers are in range 1..%d", +// OBSOLETE MAX_EXCEPTION); +// OBSOLETE +// OBSOLETE if (*scan != ' ' && *scan != '\t') +// OBSOLETE error ("exception number must be followed by a space"); +// OBSOLETE else +// OBSOLETE while (*scan == ' ' || *scan == '\t') +// OBSOLETE scan++; +// OBSOLETE +// OBSOLETE args = scan; +// OBSOLETE len = 0; +// OBSOLETE while (*scan) +// OBSOLETE { +// OBSOLETE len++; +// OBSOLETE scan++; +// OBSOLETE } +// OBSOLETE +// OBSOLETE if (!len) +// OBSOLETE error ("exception number action"); +// OBSOLETE +// OBSOLETE if (!strncasecmp (args, "forward", len)) +// OBSOLETE exception_map[exception].forward = TRUE; +// OBSOLETE else if (!strncasecmp (args, "keep", len)) +// OBSOLETE exception_map[exception].forward = FALSE; +// OBSOLETE else +// OBSOLETE error ("exception action is either \"keep\" or \"forward\""); +// OBSOLETE } +// OBSOLETE +// OBSOLETE static void +// OBSOLETE print_exception_info (int exception) +// OBSOLETE { +// OBSOLETE boolean_t forward = exception_map[exception].forward; +// OBSOLETE +// OBSOLETE printf_filtered ("%s\t(%d): ", exception_map[exception].name, +// OBSOLETE exception); +// OBSOLETE if (!forward) +// OBSOLETE if (exception_map[exception].sigmap != SIG_UNKNOWN) +// OBSOLETE printf_filtered ("keep and handle as signal %d\n", +// OBSOLETE exception_map[exception].sigmap); +// OBSOLETE else +// OBSOLETE printf_filtered ("keep and handle as unknown signal %d\n", +// OBSOLETE exception_map[exception].sigmap); +// OBSOLETE else +// OBSOLETE printf_filtered ("forward exception to inferior\n"); +// OBSOLETE } +// OBSOLETE +// OBSOLETE void +// OBSOLETE exception_info (char *args, int from_tty) +// OBSOLETE { +// OBSOLETE int exception; +// OBSOLETE +// OBSOLETE if (!args) +// OBSOLETE for (exception = 1; exception <= MAX_EXCEPTION; exception++) +// OBSOLETE print_exception_info (exception); +// OBSOLETE else +// OBSOLETE { +// OBSOLETE exception = atoi (args); +// OBSOLETE +// OBSOLETE if (exception <= 0 || exception > MAX_EXCEPTION) +// OBSOLETE error ("Invalid exception number, values from 1 to %d allowed", +// OBSOLETE MAX_EXCEPTION); +// OBSOLETE print_exception_info (exception); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Check for actions for mach exceptions. +// OBSOLETE */ +// OBSOLETE mach3_exception_actions (WAITTYPE *w, boolean_t force_print_only, char *who) +// OBSOLETE { +// OBSOLETE boolean_t force_print = FALSE; +// OBSOLETE +// OBSOLETE +// OBSOLETE if (force_print_only || +// OBSOLETE exception_map[stop_exception].sigmap == SIG_UNKNOWN) +// OBSOLETE force_print = TRUE; +// OBSOLETE else +// OBSOLETE WSETSTOP (*w, exception_map[stop_exception].sigmap); +// OBSOLETE +// OBSOLETE if (exception_map[stop_exception].print || force_print) +// OBSOLETE { +// OBSOLETE target_terminal_ours (); +// OBSOLETE +// OBSOLETE printf_filtered ("\n%s received %s exception : ", +// OBSOLETE who, +// OBSOLETE exception_map[stop_exception].name); +// OBSOLETE +// OBSOLETE wrap_here (" "); +// OBSOLETE +// OBSOLETE switch (stop_exception) +// OBSOLETE { +// OBSOLETE case EXC_BAD_ACCESS: +// OBSOLETE printf_filtered ("referencing address 0x%x : %s\n", +// OBSOLETE stop_subcode, +// OBSOLETE mach_error_string (stop_code)); +// OBSOLETE break; +// OBSOLETE case EXC_BAD_INSTRUCTION: +// OBSOLETE printf_filtered +// OBSOLETE ("illegal or undefined instruction. code %d subcode %d\n", +// OBSOLETE stop_code, stop_subcode); +// OBSOLETE break; +// OBSOLETE case EXC_ARITHMETIC: +// OBSOLETE printf_filtered ("code %d\n", stop_code); +// OBSOLETE break; +// OBSOLETE case EXC_EMULATION: +// OBSOLETE printf_filtered ("code %d subcode %d\n", stop_code, stop_subcode); +// OBSOLETE break; +// OBSOLETE case EXC_SOFTWARE: +// OBSOLETE printf_filtered ("%s specific, code 0x%x\n", +// OBSOLETE stop_code < 0xffff ? "hardware" : "os emulation", +// OBSOLETE stop_code); +// OBSOLETE break; +// OBSOLETE case EXC_BREAKPOINT: +// OBSOLETE printf_filtered ("type %d (machine dependent)\n", +// OBSOLETE stop_code); +// OBSOLETE break; +// OBSOLETE default: +// OBSOLETE internal_error (__FILE__, __LINE__, +// OBSOLETE "Unknown exception"); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE setup_notify_port (int create_new) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE +// OBSOLETE if (MACH_PORT_VALID (our_notify_port)) +// OBSOLETE { +// OBSOLETE ret = mach_port_destroy (mach_task_self (), our_notify_port); +// OBSOLETE CHK ("Could not destroy our_notify_port", ret); +// OBSOLETE } +// OBSOLETE +// OBSOLETE our_notify_port = MACH_PORT_NULL; +// OBSOLETE notify_chain = (port_chain_t) NULL; +// OBSOLETE port_chain_destroy (port_chain_obstack); +// OBSOLETE +// OBSOLETE if (create_new) +// OBSOLETE { +// OBSOLETE ret = mach_port_allocate (mach_task_self (), +// OBSOLETE MACH_PORT_RIGHT_RECEIVE, +// OBSOLETE &our_notify_port); +// OBSOLETE if (ret != KERN_SUCCESS) +// OBSOLETE internal_error (__FILE__, __LINE__, +// OBSOLETE "Creating notify port %s", mach_error_string (ret)); +// OBSOLETE +// OBSOLETE ret = mach_port_move_member (mach_task_self (), +// OBSOLETE our_notify_port, +// OBSOLETE inferior_wait_port_set); +// OBSOLETE if (ret != KERN_SUCCESS) +// OBSOLETE internal_error (__FILE__, __LINE__, +// OBSOLETE "initial move member %s", mach_error_string (ret)); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* +// OBSOLETE * Register our message port to the net name server +// OBSOLETE * +// OBSOLETE * Currently used only by the external stop-gdb program +// OBSOLETE * since ^C does not work if you would like to enter +// OBSOLETE * gdb command level while debugging your program. +// OBSOLETE * +// OBSOLETE * NOTE: If the message port is sometimes used for other +// OBSOLETE * purposes also, the NAME must not be a guessable one. +// OBSOLETE * Then, there should be a way to change it. +// OBSOLETE */ +// OBSOLETE +// OBSOLETE char registered_name[MAX_NAME_LEN]; +// OBSOLETE +// OBSOLETE void +// OBSOLETE message_port_info (char *args, int from_tty) +// OBSOLETE { +// OBSOLETE if (registered_name[0]) +// OBSOLETE printf_filtered ("gdb's message port name: '%s'\n", +// OBSOLETE registered_name); +// OBSOLETE else +// OBSOLETE printf_filtered ("gdb's message port is not currently registered\n"); +// OBSOLETE } +// OBSOLETE +// OBSOLETE void +// OBSOLETE gdb_register_port (char *name, mach_port_t port) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE static int already_signed = 0; +// OBSOLETE int len; +// OBSOLETE +// OBSOLETE if (!MACH_PORT_VALID (port) || !name || !*name) +// OBSOLETE { +// OBSOLETE warning ("Invalid registration request"); +// OBSOLETE return; +// OBSOLETE } +// OBSOLETE +// OBSOLETE if (!already_signed) +// OBSOLETE { +// OBSOLETE ret = mach_port_insert_right (mach_task_self (), +// OBSOLETE our_message_port, +// OBSOLETE our_message_port, +// OBSOLETE MACH_MSG_TYPE_MAKE_SEND); +// OBSOLETE CHK ("Failed to create a signature to our_message_port", ret); +// OBSOLETE already_signed = 1; +// OBSOLETE } +// OBSOLETE else if (already_signed > 1) +// OBSOLETE { +// OBSOLETE ret = netname_check_out (name_server_port, +// OBSOLETE registered_name, +// OBSOLETE our_message_port); +// OBSOLETE CHK ("Failed to check out gdb's message port", ret); +// OBSOLETE registered_name[0] = '\000'; +// OBSOLETE already_signed = 1; +// OBSOLETE } +// OBSOLETE +// OBSOLETE ret = netname_check_in (name_server_port, /* Name server port */ +// OBSOLETE name, /* Name of service */ +// OBSOLETE our_message_port, /* Signature */ +// OBSOLETE port); /* Creates a new send right */ +// OBSOLETE CHK ("Failed to check in the port", ret); +// OBSOLETE +// OBSOLETE len = 0; +// OBSOLETE while (len < MAX_NAME_LEN && *(name + len)) +// OBSOLETE { +// OBSOLETE registered_name[len] = *(name + len); +// OBSOLETE len++; +// OBSOLETE } +// OBSOLETE registered_name[len] = '\000'; +// OBSOLETE already_signed = 2; +// OBSOLETE } +// OBSOLETE +// OBSOLETE struct cmd_list_element *cmd_thread_list; +// OBSOLETE struct cmd_list_element *cmd_task_list; +// OBSOLETE +// OBSOLETE /*ARGSUSED */ +// OBSOLETE static void +// OBSOLETE thread_command (char *arg, int from_tty) +// OBSOLETE { +// OBSOLETE printf_unfiltered ("\"thread\" must be followed by the name of a thread command.\n"); +// OBSOLETE help_list (cmd_thread_list, "thread ", -1, gdb_stdout); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /*ARGSUSED */ +// OBSOLETE static void +// OBSOLETE task_command (char *arg, int from_tty) +// OBSOLETE { +// OBSOLETE printf_unfiltered ("\"task\" must be followed by the name of a task command.\n"); +// OBSOLETE help_list (cmd_task_list, "task ", -1, gdb_stdout); +// OBSOLETE } +// OBSOLETE +// OBSOLETE add_mach_specific_commands (void) +// OBSOLETE { +// OBSOLETE /* Thread handling commands */ +// OBSOLETE +// OBSOLETE /* FIXME: Move our thread support into the generic thread.c stuff so we +// OBSOLETE can share that code. */ +// OBSOLETE add_prefix_cmd ("mthread", class_stack, thread_command, +// OBSOLETE "Generic command for handling Mach threads in the debugged task.", +// OBSOLETE &cmd_thread_list, "thread ", 0, &cmdlist); +// OBSOLETE +// OBSOLETE add_com_alias ("th", "mthread", class_stack, 1); +// OBSOLETE +// OBSOLETE add_cmd ("select", class_stack, thread_select_command, +// OBSOLETE "Select and print MID of the selected thread", +// OBSOLETE &cmd_thread_list); +// OBSOLETE add_cmd ("list", class_stack, thread_list_command, +// OBSOLETE "List info of task's threads. Selected thread is marked with '*'", +// OBSOLETE &cmd_thread_list); +// OBSOLETE add_cmd ("suspend", class_run, thread_suspend_command, +// OBSOLETE "Suspend one or all of the threads in the selected task.", +// OBSOLETE &cmd_thread_list); +// OBSOLETE add_cmd ("resume", class_run, thread_resume_command, +// OBSOLETE "Resume one or all of the threads in the selected task.", +// OBSOLETE &cmd_thread_list); +// OBSOLETE add_cmd ("kill", class_run, thread_kill_command, +// OBSOLETE "Kill the specified thread MID from inferior task.", +// OBSOLETE &cmd_thread_list); +// OBSOLETE #if 0 +// OBSOLETE /* The rest of this support (condition_thread) was not merged. It probably +// OBSOLETE should not be merged in this form, but instead added to the generic GDB +// OBSOLETE thread support. */ +// OBSOLETE add_cmd ("break", class_breakpoint, condition_thread, +// OBSOLETE "Breakpoint N will only be effective for thread MID or @SLOT\n\ +// OBSOLETE If MID/@SLOT is omitted allow all threads to break at breakpoint", +// OBSOLETE &cmd_thread_list); +// OBSOLETE #endif +// OBSOLETE /* Thread command shorthands (for backward compatibility) */ +// OBSOLETE add_alias_cmd ("ts", "mthread select", 0, 0, &cmdlist); +// OBSOLETE add_alias_cmd ("tl", "mthread list", 0, 0, &cmdlist); +// OBSOLETE +// OBSOLETE /* task handling commands */ +// OBSOLETE +// OBSOLETE add_prefix_cmd ("task", class_stack, task_command, +// OBSOLETE "Generic command for handling debugged task.", +// OBSOLETE &cmd_task_list, "task ", 0, &cmdlist); +// OBSOLETE +// OBSOLETE add_com_alias ("ta", "task", class_stack, 1); +// OBSOLETE +// OBSOLETE add_cmd ("suspend", class_run, task_suspend_command, +// OBSOLETE "Suspend the inferior task.", +// OBSOLETE &cmd_task_list); +// OBSOLETE add_cmd ("resume", class_run, task_resume_command, +// OBSOLETE "Resume the inferior task.", +// OBSOLETE &cmd_task_list); +// OBSOLETE add_cmd ("info", no_class, task_info_command, +// OBSOLETE "Print information about the specified task.", +// OBSOLETE &cmd_task_list); +// OBSOLETE +// OBSOLETE /* Print my message port name */ +// OBSOLETE +// OBSOLETE add_info ("message-port", message_port_info, +// OBSOLETE "Returns the name of gdb's message port in the netnameserver"); +// OBSOLETE +// OBSOLETE /* Exception commands */ +// OBSOLETE +// OBSOLETE add_info ("exceptions", exception_info, +// OBSOLETE "What debugger does when program gets various exceptions.\n\ +// OBSOLETE Specify an exception number as argument to print info on that\n\ +// OBSOLETE exception only."); +// OBSOLETE +// OBSOLETE add_com ("exception", class_run, exception_command, +// OBSOLETE "Specify how to handle an exception.\n\ +// OBSOLETE Args are exception number followed by \"forward\" or \"keep\".\n\ +// OBSOLETE `Forward' means forward the exception to the program's normal exception\n\ +// OBSOLETE handler.\n\ +// OBSOLETE `Keep' means reenter debugger if this exception happens, and GDB maps\n\ +// OBSOLETE the exception to some signal (see info exception)\n\ +// OBSOLETE Normally \"keep\" is used to return to GDB on exception."); +// OBSOLETE } +// OBSOLETE +// OBSOLETE kern_return_t +// OBSOLETE do_mach_notify_dead_name (mach_port_t notify, mach_port_t name) +// OBSOLETE { +// OBSOLETE kern_return_t kr = KERN_SUCCESS; +// OBSOLETE +// OBSOLETE /* Find the thing that notified */ +// OBSOLETE port_chain_t element = port_chain_member (notify_chain, name); +// OBSOLETE +// OBSOLETE /* Take name of from unreceived dead name notification list */ +// OBSOLETE notify_chain = port_chain_delete (notify_chain, name); +// OBSOLETE +// OBSOLETE if (!element) +// OBSOLETE error ("Received a dead name notify from unchained port (0x%x)", name); +// OBSOLETE +// OBSOLETE switch (element->type) +// OBSOLETE { +// OBSOLETE +// OBSOLETE case MACH_TYPE_THREAD: +// OBSOLETE target_terminal_ours_for_output (); +// OBSOLETE if (name == current_thread) +// OBSOLETE { +// OBSOLETE printf_filtered ("\nCurrent thread %d died", element->mid); +// OBSOLETE current_thread = MACH_PORT_NULL; +// OBSOLETE } +// OBSOLETE else +// OBSOLETE printf_filtered ("\nThread %d died", element->mid); +// OBSOLETE +// OBSOLETE break; +// OBSOLETE +// OBSOLETE case MACH_TYPE_TASK: +// OBSOLETE target_terminal_ours_for_output (); +// OBSOLETE if (name != inferior_task) +// OBSOLETE printf_filtered ("Task %d died, but it was not the selected task", +// OBSOLETE element->mid); +// OBSOLETE else +// OBSOLETE { +// OBSOLETE printf_filtered ("Current task %d died", element->mid); +// OBSOLETE +// OBSOLETE mach_port_destroy (mach_task_self (), name); +// OBSOLETE inferior_task = MACH_PORT_NULL; +// OBSOLETE +// OBSOLETE if (notify_chain) +// OBSOLETE warning ("There were still unreceived dead_name_notifications???"); +// OBSOLETE +// OBSOLETE /* Destroy the old notifications */ +// OBSOLETE setup_notify_port (0); +// OBSOLETE +// OBSOLETE } +// OBSOLETE break; +// OBSOLETE +// OBSOLETE default: +// OBSOLETE error ("Unregistered dead_name 0x%x notification received. Type is %d, mid is 0x%x", +// OBSOLETE name, element->type, element->mid); +// OBSOLETE break; +// OBSOLETE } +// OBSOLETE +// OBSOLETE return KERN_SUCCESS; +// OBSOLETE } +// OBSOLETE +// OBSOLETE kern_return_t +// OBSOLETE do_mach_notify_msg_accepted (mach_port_t notify, mach_port_t name) +// OBSOLETE { +// OBSOLETE warning ("do_mach_notify_msg_accepted : notify %x, name %x", +// OBSOLETE notify, name); +// OBSOLETE return KERN_SUCCESS; +// OBSOLETE } +// OBSOLETE +// OBSOLETE kern_return_t +// OBSOLETE do_mach_notify_no_senders (mach_port_t notify, mach_port_mscount_t mscount) +// OBSOLETE { +// OBSOLETE warning ("do_mach_notify_no_senders : notify %x, mscount %x", +// OBSOLETE notify, mscount); +// OBSOLETE return KERN_SUCCESS; +// OBSOLETE } +// OBSOLETE +// OBSOLETE kern_return_t +// OBSOLETE do_mach_notify_port_deleted (mach_port_t notify, mach_port_t name) +// OBSOLETE { +// OBSOLETE warning ("do_mach_notify_port_deleted : notify %x, name %x", +// OBSOLETE notify, name); +// OBSOLETE return KERN_SUCCESS; +// OBSOLETE } +// OBSOLETE +// OBSOLETE kern_return_t +// OBSOLETE do_mach_notify_port_destroyed (mach_port_t notify, mach_port_t rights) +// OBSOLETE { +// OBSOLETE warning ("do_mach_notify_port_destroyed : notify %x, rights %x", +// OBSOLETE notify, rights); +// OBSOLETE return KERN_SUCCESS; +// OBSOLETE } +// OBSOLETE +// OBSOLETE kern_return_t +// OBSOLETE do_mach_notify_send_once (mach_port_t notify) +// OBSOLETE { +// OBSOLETE #ifdef DUMP_SYSCALL +// OBSOLETE /* MANY of these are generated. */ +// OBSOLETE warning ("do_mach_notify_send_once : notify %x", +// OBSOLETE notify); +// OBSOLETE #endif +// OBSOLETE return KERN_SUCCESS; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Kills the inferior. It's gone when you call this */ +// OBSOLETE static void +// OBSOLETE kill_inferior_fast (void) +// OBSOLETE { +// OBSOLETE WAITTYPE w; +// OBSOLETE +// OBSOLETE if (PIDGET (inferior_ptid) == 0 || PIDGET (inferior_ptid) == 1) +// OBSOLETE return; +// OBSOLETE +// OBSOLETE /* kill() it, since the Unix server does not otherwise notice when +// OBSOLETE * killed with task_terminate(). +// OBSOLETE */ +// OBSOLETE if (PIDGET (inferior_ptid) > 0) +// OBSOLETE kill (PIDGET (inferior_ptid), SIGKILL); +// OBSOLETE +// OBSOLETE /* It's propably terminate already */ +// OBSOLETE (void) task_terminate (inferior_task); +// OBSOLETE +// OBSOLETE inferior_task = MACH_PORT_NULL; +// OBSOLETE current_thread = MACH_PORT_NULL; +// OBSOLETE +// OBSOLETE wait3 (&w, WNOHANG, 0); +// OBSOLETE +// OBSOLETE setup_notify_port (0); +// OBSOLETE } +// OBSOLETE +// OBSOLETE static void +// OBSOLETE m3_kill_inferior (void) +// OBSOLETE { +// OBSOLETE kill_inferior_fast (); +// OBSOLETE target_mourn_inferior (); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Clean up after the inferior dies. */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE m3_mourn_inferior (void) +// OBSOLETE { +// OBSOLETE unpush_target (&m3_ops); +// OBSOLETE generic_mourn_inferior (); +// OBSOLETE } +// OBSOLETE +// OBSOLETE +// OBSOLETE /* Fork an inferior process, and start debugging it. */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE m3_create_inferior (char *exec_file, char *allargs, char **env) +// OBSOLETE { +// OBSOLETE fork_inferior (exec_file, allargs, env, m3_trace_me, m3_trace_him, NULL, NULL); +// OBSOLETE /* We are at the first instruction we care about. */ +// OBSOLETE /* Pedal to the metal... */ +// OBSOLETE proceed ((CORE_ADDR) -1, 0, 0); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Mark our target-struct as eligible for stray "run" and "attach" +// OBSOLETE commands. */ +// OBSOLETE static int +// OBSOLETE m3_can_run (void) +// OBSOLETE { +// OBSOLETE return 1; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Mach 3.0 does not need ptrace for anything +// OBSOLETE * Make sure nobody uses it on mach. +// OBSOLETE */ +// OBSOLETE ptrace (int a, int b, int c, int d) +// OBSOLETE { +// OBSOLETE error ("Lose, Lose! Somebody called ptrace\n"); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Resume execution of the inferior process. +// OBSOLETE If STEP is nonzero, single-step it. +// OBSOLETE If SIGNAL is nonzero, give it that signal. */ +// OBSOLETE +// OBSOLETE void +// OBSOLETE m3_resume (ptid_t ptid, int step, enum target_signal signal) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE +// OBSOLETE if (step) +// OBSOLETE { +// OBSOLETE thread_basic_info_data_t th_info; +// OBSOLETE unsigned int infoCnt = THREAD_BASIC_INFO_COUNT; +// OBSOLETE +// OBSOLETE /* There is no point in single stepping when current_thread +// OBSOLETE * is dead. +// OBSOLETE */ +// OBSOLETE if (!MACH_PORT_VALID (current_thread)) +// OBSOLETE error ("No thread selected; can not single step"); +// OBSOLETE +// OBSOLETE /* If current_thread is suspended, tracing it would never return. +// OBSOLETE */ +// OBSOLETE ret = thread_info (current_thread, +// OBSOLETE THREAD_BASIC_INFO, +// OBSOLETE (thread_info_t) & th_info, +// OBSOLETE &infoCnt); +// OBSOLETE CHK ("child_resume: can't get thread info", ret); +// OBSOLETE +// OBSOLETE if (th_info.suspend_count) +// OBSOLETE error ("Can't trace a suspended thread. Use \"thread resume\" command to resume it"); +// OBSOLETE } +// OBSOLETE +// OBSOLETE vm_read_cache_valid = FALSE; +// OBSOLETE +// OBSOLETE if (signal && PIDGET (inferior_ptid) > 0) /* Do not signal, if attached by MID */ +// OBSOLETE kill (PIDGET (inferior_ptid), target_signal_to_host (signal)); +// OBSOLETE +// OBSOLETE if (step) +// OBSOLETE { +// OBSOLETE suspend_all_threads (0); +// OBSOLETE +// OBSOLETE setup_single_step (current_thread, TRUE); +// OBSOLETE +// OBSOLETE ret = thread_resume (current_thread); +// OBSOLETE CHK ("thread_resume", ret); +// OBSOLETE } +// OBSOLETE +// OBSOLETE ret = task_resume (inferior_task); +// OBSOLETE if (ret == KERN_FAILURE) +// OBSOLETE warning ("Task was not suspended"); +// OBSOLETE else +// OBSOLETE CHK ("Resuming task", ret); +// OBSOLETE +// OBSOLETE /* HACK HACK This is needed by the multiserver system HACK HACK */ +// OBSOLETE while ((ret = task_resume (inferior_task)) == KERN_SUCCESS) +// OBSOLETE /* make sure it really runs */ ; +// OBSOLETE /* HACK HACK This is needed by the multiserver system HACK HACK */ +// OBSOLETE } +// OBSOLETE +// OBSOLETE #ifdef ATTACH_DETACH +// OBSOLETE +// OBSOLETE /* Start debugging the process with the given task */ +// OBSOLETE void +// OBSOLETE task_attach (task_t tid) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE inferior_task = tid; +// OBSOLETE +// OBSOLETE ret = task_suspend (inferior_task); +// OBSOLETE CHK ("task_attach: task_suspend", ret); +// OBSOLETE +// OBSOLETE must_suspend_thread = 0; +// OBSOLETE +// OBSOLETE setup_notify_port (1); +// OBSOLETE +// OBSOLETE request_notify (inferior_task, MACH_NOTIFY_DEAD_NAME, MACH_TYPE_TASK); +// OBSOLETE +// OBSOLETE setup_exception_port (); +// OBSOLETE +// OBSOLETE emulator_present = have_emulator_p (inferior_task); +// OBSOLETE +// OBSOLETE attach_flag = 1; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Well, we can call error also here and leave the +// OBSOLETE * target stack inconsistent. Sigh. +// OBSOLETE * Fix this sometime (the only way to fail here is that +// OBSOLETE * the task has no threads at all, which is rare, but +// OBSOLETE * possible; or if the target task has died, which is also +// OBSOLETE * possible, but unlikely, since it has been suspended. +// OBSOLETE * (Someone must have killed it)) +// OBSOLETE */ +// OBSOLETE void +// OBSOLETE attach_to_thread (void) +// OBSOLETE { +// OBSOLETE if (select_thread (inferior_task, 0, 1) != KERN_SUCCESS) +// OBSOLETE error ("Could not select any threads to attach to"); +// OBSOLETE } +// OBSOLETE +// OBSOLETE mid_attach (int mid) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE +// OBSOLETE ret = machid_mach_port (mid_server, mid_auth, mid, &inferior_task); +// OBSOLETE CHK ("mid_attach: machid_mach_port", ret); +// OBSOLETE +// OBSOLETE task_attach (inferior_task); +// OBSOLETE +// OBSOLETE return mid; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* +// OBSOLETE * Start debugging the process whose unix process-id is PID. +// OBSOLETE * A negative "pid" value is legal and signifies a mach_id not a unix pid. +// OBSOLETE * +// OBSOLETE * Prevent (possible unwanted) dangerous operations by enabled users +// OBSOLETE * like "atta 0" or "atta foo" (equal to the previous :-) and +// OBSOLETE * "atta pidself". Anyway, the latter is allowed by specifying a MID. +// OBSOLETE */ +// OBSOLETE static int +// OBSOLETE m3_do_attach (int pid) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE +// OBSOLETE if (pid == 0) +// OBSOLETE error ("MID=0, Debugging the master unix server does not compute"); +// OBSOLETE +// OBSOLETE /* Foo. This assumes gdb has a unix pid */ +// OBSOLETE if (pid == getpid ()) +// OBSOLETE error ("I will debug myself only by mid. (Gdb would suspend itself!)"); +// OBSOLETE +// OBSOLETE if (pid < 0) +// OBSOLETE { +// OBSOLETE mid_attach (-(pid)); +// OBSOLETE +// OBSOLETE /* inferior_ptid will be NEGATIVE! */ +// OBSOLETE inferior_ptid = pid_to_ptid (pid); +// OBSOLETE +// OBSOLETE return PIDGET (inferior_ptid); +// OBSOLETE } +// OBSOLETE +// OBSOLETE inferior_task = task_by_pid (pid); +// OBSOLETE if (!MACH_PORT_VALID (inferior_task)) +// OBSOLETE error ("Cannot map Unix pid %d to Mach task port", pid); +// OBSOLETE +// OBSOLETE task_attach (inferior_task); +// OBSOLETE +// OBSOLETE inferior_ptid = pid_to_ptid (pid); +// OBSOLETE +// OBSOLETE return PIDGET (inferior_ptid); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Attach to process PID, then initialize for debugging it +// OBSOLETE and wait for the trace-trap that results from attaching. */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE m3_attach (char *args, int from_tty) +// OBSOLETE { +// OBSOLETE char *exec_file; +// OBSOLETE int pid; +// OBSOLETE +// OBSOLETE if (!args) +// OBSOLETE error_no_arg ("process-id to attach"); +// OBSOLETE +// OBSOLETE pid = atoi (args); +// OBSOLETE +// OBSOLETE if (pid == getpid ()) /* Trying to masturbate? */ +// OBSOLETE error ("I refuse to debug myself!"); +// OBSOLETE +// OBSOLETE if (from_tty) +// OBSOLETE { +// OBSOLETE exec_file = (char *) get_exec_file (0); +// OBSOLETE +// OBSOLETE if (exec_file) +// OBSOLETE printf_unfiltered ("Attaching to program `%s', %s\n", exec_file, +// OBSOLETE target_pid_to_str (pid_to_ptid (pid))); +// OBSOLETE else +// OBSOLETE printf_unfiltered ("Attaching to %s\n", +// OBSOLETE target_pid_to_str (pid_to_ptid (pid))); +// OBSOLETE +// OBSOLETE gdb_flush (gdb_stdout); +// OBSOLETE } +// OBSOLETE +// OBSOLETE m3_do_attach (pid_to_ptid (pid)); +// OBSOLETE inferior_ptid = pid_to_ptid (pid); +// OBSOLETE push_target (&m3_ops); +// OBSOLETE } +// OBSOLETE +// OBSOLETE void +// OBSOLETE deallocate_inferior_ports (void) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE thread_array_t thread_list; +// OBSOLETE int thread_count, index; +// OBSOLETE +// OBSOLETE if (!MACH_PORT_VALID (inferior_task)) +// OBSOLETE return; +// OBSOLETE +// OBSOLETE ret = task_threads (inferior_task, &thread_list, &thread_count); +// OBSOLETE if (ret != KERN_SUCCESS) +// OBSOLETE { +// OBSOLETE warning ("deallocate_inferior_ports: task_threads", +// OBSOLETE mach_error_string (ret)); +// OBSOLETE return; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Get rid of send rights to task threads */ +// OBSOLETE for (index = 0; index < thread_count; index++) +// OBSOLETE { +// OBSOLETE int rights; +// OBSOLETE ret = mach_port_get_refs (mach_task_self (), +// OBSOLETE thread_list[index], +// OBSOLETE MACH_PORT_RIGHT_SEND, +// OBSOLETE &rights); +// OBSOLETE CHK ("deallocate_inferior_ports: get refs", ret); +// OBSOLETE +// OBSOLETE if (rights > 0) +// OBSOLETE { +// OBSOLETE ret = mach_port_mod_refs (mach_task_self (), +// OBSOLETE thread_list[index], +// OBSOLETE MACH_PORT_RIGHT_SEND, +// OBSOLETE -rights); +// OBSOLETE CHK ("deallocate_inferior_ports: mod refs", ret); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE ret = mach_port_mod_refs (mach_task_self (), +// OBSOLETE inferior_exception_port, +// OBSOLETE MACH_PORT_RIGHT_RECEIVE, +// OBSOLETE -1); +// OBSOLETE CHK ("deallocate_inferior_ports: cannot get rid of exception port", ret); +// OBSOLETE +// OBSOLETE ret = mach_port_deallocate (mach_task_self (), +// OBSOLETE inferior_task); +// OBSOLETE CHK ("deallocate_task_port: deallocating inferior_task", ret); +// OBSOLETE +// OBSOLETE current_thread = MACH_PORT_NULL; +// OBSOLETE inferior_task = MACH_PORT_NULL; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Stop debugging the process whose number is PID +// OBSOLETE and continue it with signal number SIGNAL. +// OBSOLETE SIGNAL = 0 means just continue it. */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE m3_do_detach (int signal) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE +// OBSOLETE MACH_ERROR_NO_INFERIOR; +// OBSOLETE +// OBSOLETE if (current_thread != MACH_PORT_NULL) +// OBSOLETE { +// OBSOLETE /* Store the gdb's view of the thread we are deselecting +// OBSOLETE * before we detach. +// OBSOLETE * @@ I am really not sure if this is ever needeed. +// OBSOLETE */ +// OBSOLETE target_prepare_to_store (); +// OBSOLETE target_store_registers (-1); +// OBSOLETE } +// OBSOLETE +// OBSOLETE ret = task_set_special_port (inferior_task, +// OBSOLETE TASK_EXCEPTION_PORT, +// OBSOLETE inferior_old_exception_port); +// OBSOLETE CHK ("task_set_special_port", ret); +// OBSOLETE +// OBSOLETE /* Discard all requested notifications */ +// OBSOLETE setup_notify_port (0); +// OBSOLETE +// OBSOLETE if (remove_breakpoints ()) +// OBSOLETE warning ("Could not remove breakpoints when detaching"); +// OBSOLETE +// OBSOLETE if (signal && PIDGET (inferior_ptid) > 0) +// OBSOLETE kill (PIDGET (inferior_ptid), signal); +// OBSOLETE +// OBSOLETE /* the task might be dead by now */ +// OBSOLETE (void) task_resume (inferior_task); +// OBSOLETE +// OBSOLETE deallocate_inferior_ports (); +// OBSOLETE +// OBSOLETE attach_flag = 0; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Take a program previously attached to and detaches it. +// OBSOLETE The program resumes execution and will no longer stop +// OBSOLETE on signals, etc. We'd better not have left any breakpoints +// OBSOLETE in the program or it'll die when it hits one. For this +// OBSOLETE to work, it may be necessary for the process to have been +// OBSOLETE previously attached. It *might* work if the program was +// OBSOLETE started via fork. */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE m3_detach (char *args, int from_tty) +// OBSOLETE { +// OBSOLETE int siggnal = 0; +// OBSOLETE +// OBSOLETE if (from_tty) +// OBSOLETE { +// OBSOLETE char *exec_file = get_exec_file (0); +// OBSOLETE if (exec_file == 0) +// OBSOLETE exec_file = ""; +// OBSOLETE printf_unfiltered ("Detaching from program: %s %s\n", +// OBSOLETE exec_file, target_pid_to_str (inferior_ptid)); +// OBSOLETE gdb_flush (gdb_stdout); +// OBSOLETE } +// OBSOLETE if (args) +// OBSOLETE siggnal = atoi (args); +// OBSOLETE +// OBSOLETE m3_do_detach (siggnal); +// OBSOLETE inferior_ptid = null_ptid; +// OBSOLETE unpush_target (&m3_ops); /* Pop out of handling an inferior */ +// OBSOLETE } +// OBSOLETE #endif /* ATTACH_DETACH */ +// OBSOLETE +// OBSOLETE /* Get ready to modify the registers array. On machines which store +// OBSOLETE individual registers, this doesn't need to do anything. On machines +// OBSOLETE which store all the registers in one fell swoop, this makes sure +// OBSOLETE that registers contains all the registers from the program being +// OBSOLETE debugged. */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE m3_prepare_to_store (void) +// OBSOLETE { +// OBSOLETE #ifdef CHILD_PREPARE_TO_STORE +// OBSOLETE CHILD_PREPARE_TO_STORE (); +// OBSOLETE #endif +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Print status information about what we're accessing. */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE m3_files_info (struct target_ops *ignore) +// OBSOLETE { +// OBSOLETE /* FIXME: should print MID and all that crap. */ +// OBSOLETE printf_unfiltered ("\tUsing the running image of %s %s.\n", +// OBSOLETE attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid)); +// OBSOLETE } +// OBSOLETE +// OBSOLETE static void +// OBSOLETE m3_open (char *arg, int from_tty) +// OBSOLETE { +// OBSOLETE error ("Use the \"run\" command to start a Unix child process."); +// OBSOLETE } +// OBSOLETE +// OBSOLETE #ifdef DUMP_SYSCALL +// OBSOLETE #define STR(x) #x +// OBSOLETE +// OBSOLETE char *bsd1_names[] = +// OBSOLETE { +// OBSOLETE "execve", +// OBSOLETE "fork", +// OBSOLETE "take_signal", +// OBSOLETE "sigreturn", +// OBSOLETE "getrusage", +// OBSOLETE "chdir", +// OBSOLETE "chroot", +// OBSOLETE "open", +// OBSOLETE "creat", +// OBSOLETE "mknod", +// OBSOLETE "link", +// OBSOLETE "symlink", +// OBSOLETE "unlink", +// OBSOLETE "access", +// OBSOLETE "stat", +// OBSOLETE "readlink", +// OBSOLETE "chmod", +// OBSOLETE "chown", +// OBSOLETE "utimes", +// OBSOLETE "truncate", +// OBSOLETE "rename", +// OBSOLETE "mkdir", +// OBSOLETE "rmdir", +// OBSOLETE "xutimes", +// OBSOLETE "mount", +// OBSOLETE "umount", +// OBSOLETE "acct", +// OBSOLETE "setquota", +// OBSOLETE "write_short", +// OBSOLETE "write_long", +// OBSOLETE "send_short", +// OBSOLETE "send_long", +// OBSOLETE "sendto_short", +// OBSOLETE "sendto_long", +// OBSOLETE "select", +// OBSOLETE "task_by_pid", +// OBSOLETE "recvfrom_short", +// OBSOLETE "recvfrom_long", +// OBSOLETE "setgroups", +// OBSOLETE "setrlimit", +// OBSOLETE "sigvec", +// OBSOLETE "sigstack", +// OBSOLETE "settimeofday", +// OBSOLETE "adjtime", +// OBSOLETE "setitimer", +// OBSOLETE "sethostname", +// OBSOLETE "bind", +// OBSOLETE "accept", +// OBSOLETE "connect", +// OBSOLETE "setsockopt", +// OBSOLETE "getsockopt", +// OBSOLETE "getsockname", +// OBSOLETE "getpeername", +// OBSOLETE "init_process", +// OBSOLETE "table_set", +// OBSOLETE "table_get", +// OBSOLETE "pioctl", +// OBSOLETE "emulator_error", +// OBSOLETE "readwrite", +// OBSOLETE "share_wakeup", +// OBSOLETE 0, +// OBSOLETE "maprw_request_it", +// OBSOLETE "maprw_release_it", +// OBSOLETE "maprw_remap", +// OBSOLETE "pid_by_task", +// OBSOLETE }; +// OBSOLETE +// OBSOLETE int bsd1_nnames = sizeof (bsd1_names) / sizeof (bsd1_names[0]); +// OBSOLETE +// OBSOLETE char * +// OBSOLETE name_str (int name, char *buf) +// OBSOLETE { +// OBSOLETE switch (name) +// OBSOLETE { +// OBSOLETE case MACH_MSG_TYPE_BOOLEAN: +// OBSOLETE return "boolean"; +// OBSOLETE case MACH_MSG_TYPE_INTEGER_16: +// OBSOLETE return "short"; +// OBSOLETE case MACH_MSG_TYPE_INTEGER_32: +// OBSOLETE return "long"; +// OBSOLETE case MACH_MSG_TYPE_CHAR: +// OBSOLETE return "char"; +// OBSOLETE case MACH_MSG_TYPE_BYTE: +// OBSOLETE return "byte"; +// OBSOLETE case MACH_MSG_TYPE_REAL: +// OBSOLETE return "real"; +// OBSOLETE case MACH_MSG_TYPE_STRING: +// OBSOLETE return "string"; +// OBSOLETE default: +// OBSOLETE sprintf (buf, "%d", name); +// OBSOLETE return buf; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE char * +// OBSOLETE id_str (int id, char *buf) +// OBSOLETE { +// OBSOLETE char *p; +// OBSOLETE if (id >= 101000 && id < 101000 + bsd1_nnames) +// OBSOLETE { +// OBSOLETE if (p = bsd1_names[id - 101000]) +// OBSOLETE return p; +// OBSOLETE } +// OBSOLETE if (id == 102000) +// OBSOLETE return "psignal_retry"; +// OBSOLETE if (id == 100000) +// OBSOLETE return "syscall"; +// OBSOLETE sprintf (buf, "%d", id); +// OBSOLETE return buf; +// OBSOLETE } +// OBSOLETE +// OBSOLETE print_msg (mach_msg_header_t *mp) +// OBSOLETE { +// OBSOLETE char *fmt_x = "%20s : 0x%08x\n"; +// OBSOLETE char *fmt_d = "%20s : %10d\n"; +// OBSOLETE char *fmt_s = "%20s : %s\n"; +// OBSOLETE char buf[100]; +// OBSOLETE +// OBSOLETE puts_filtered ("\n"); +// OBSOLETE #define pr(fmt,h,x) printf_filtered(fmt,STR(x),(h).x) +// OBSOLETE pr (fmt_x, (*mp), msgh_bits); +// OBSOLETE pr (fmt_d, (*mp), msgh_size); +// OBSOLETE pr (fmt_x, (*mp), msgh_remote_port); +// OBSOLETE pr (fmt_x, (*mp), msgh_local_port); +// OBSOLETE pr (fmt_d, (*mp), msgh_kind); +// OBSOLETE printf_filtered (fmt_s, STR (msgh_id), id_str (mp->msgh_id, buf)); +// OBSOLETE +// OBSOLETE if (debug_level > 1) +// OBSOLETE { +// OBSOLETE char *p, *ep, *dp; +// OBSOLETE int plen; +// OBSOLETE p = (char *) mp; +// OBSOLETE ep = p + mp->msgh_size; +// OBSOLETE p += sizeof (*mp); +// OBSOLETE for (; p < ep; p += plen) +// OBSOLETE { +// OBSOLETE mach_msg_type_t *tp; +// OBSOLETE mach_msg_type_long_t *tlp; +// OBSOLETE int name, size, number; +// OBSOLETE tp = (mach_msg_type_t *) p; +// OBSOLETE if (tp->msgt_longform) +// OBSOLETE { +// OBSOLETE tlp = (mach_msg_type_long_t *) tp; +// OBSOLETE name = tlp->msgtl_name; +// OBSOLETE size = tlp->msgtl_size; +// OBSOLETE number = tlp->msgtl_number; +// OBSOLETE plen = sizeof (*tlp); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE name = tp->msgt_name; +// OBSOLETE size = tp->msgt_size; +// OBSOLETE number = tp->msgt_number; +// OBSOLETE plen = sizeof (*tp); +// OBSOLETE } +// OBSOLETE printf_filtered ("name=%-16s size=%2d number=%7d inline=%d long=%d deal=%d\n", +// OBSOLETE name_str (name, buf), size, number, tp->msgt_inline, +// OBSOLETE tp->msgt_longform, tp->msgt_deallocate); +// OBSOLETE dp = p + plen; +// OBSOLETE if (tp->msgt_inline) +// OBSOLETE { +// OBSOLETE int l; +// OBSOLETE l = size * number / 8; +// OBSOLETE l = (l + sizeof (long) - 1) & ~((sizeof (long)) - 1); +// OBSOLETE plen += l; +// OBSOLETE print_data (dp, size, number); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE plen += sizeof (int *); +// OBSOLETE } +// OBSOLETE printf_filtered ("plen=%d\n", plen); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE print_data (char *p, int size, int number) +// OBSOLETE { +// OBSOLETE int *ip; +// OBSOLETE short *sp; +// OBSOLETE int i; +// OBSOLETE +// OBSOLETE switch (size) +// OBSOLETE { +// OBSOLETE case 8: +// OBSOLETE for (i = 0; i < number; i++) +// OBSOLETE { +// OBSOLETE printf_filtered (" %02x", p[i]); +// OBSOLETE } +// OBSOLETE break; +// OBSOLETE case 16: +// OBSOLETE sp = (short *) p; +// OBSOLETE for (i = 0; i < number; i++) +// OBSOLETE { +// OBSOLETE printf_filtered (" %04x", sp[i]); +// OBSOLETE } +// OBSOLETE break; +// OBSOLETE case 32: +// OBSOLETE ip = (int *) p; +// OBSOLETE for (i = 0; i < number; i++) +// OBSOLETE { +// OBSOLETE printf_filtered (" %08x", ip[i]); +// OBSOLETE } +// OBSOLETE break; +// OBSOLETE } +// OBSOLETE puts_filtered ("\n"); +// OBSOLETE } +// OBSOLETE #endif /* DUMP_SYSCALL */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE m3_stop (void) +// OBSOLETE { +// OBSOLETE error ("to_stop target function not implemented"); +// OBSOLETE } +// OBSOLETE +// OBSOLETE static char * +// OBSOLETE m3_pid_to_exec_file (int pid) +// OBSOLETE { +// OBSOLETE error ("to_pid_to_exec_file target function not implemented"); +// OBSOLETE return NULL; /* To keep all compilers happy. */ +// OBSOLETE } +// OBSOLETE +// OBSOLETE static void +// OBSOLETE init_m3_ops (void) +// OBSOLETE { +// OBSOLETE m3_ops.to_shortname = "mach"; +// OBSOLETE m3_ops.to_longname = "Mach child process"; +// OBSOLETE m3_ops.to_doc = "Mach child process (started by the \"run\" command)."; +// OBSOLETE m3_ops.to_open = m3_open; +// OBSOLETE m3_ops.to_attach = m3_attach; +// OBSOLETE m3_ops.to_detach = m3_detach; +// OBSOLETE m3_ops.to_resume = m3_resume; +// OBSOLETE m3_ops.to_wait = mach_really_wait; +// OBSOLETE m3_ops.to_fetch_registers = fetch_inferior_registers; +// OBSOLETE m3_ops.to_store_registers = store_inferior_registers; +// OBSOLETE m3_ops.to_prepare_to_store = m3_prepare_to_store; +// OBSOLETE m3_ops.to_xfer_memory = m3_xfer_memory; +// OBSOLETE m3_ops.to_files_info = m3_files_info; +// OBSOLETE m3_ops.to_insert_breakpoint = memory_insert_breakpoint; +// OBSOLETE m3_ops.to_remove_breakpoint = memory_remove_breakpoint; +// OBSOLETE m3_ops.to_terminal_init = terminal_init_inferior; +// OBSOLETE m3_ops.to_terminal_inferior = terminal_inferior; +// OBSOLETE m3_ops.to_terminal_ours_for_output = terminal_ours_for_output; +// OBSOLETE m3_ops.to_terminal_save_ours = terminal_save_ours; +// OBSOLETE m3_ops.to_terminal_ours = terminal_ours; +// OBSOLETE m3_ops.to_terminal_info = child_terminal_info; +// OBSOLETE m3_ops.to_kill = m3_kill_inferior; +// OBSOLETE m3_ops.to_create_inferior = m3_create_inferior; +// OBSOLETE m3_ops.to_mourn_inferior = m3_mourn_inferior; +// OBSOLETE m3_ops.to_can_run = m3_can_run; +// OBSOLETE m3_ops.to_stop = m3_stop; +// OBSOLETE m3_ops.to_pid_to_exec_file = m3_pid_to_exec_file; +// OBSOLETE m3_ops.to_stratum = process_stratum; +// OBSOLETE m3_ops.to_has_all_memory = 1; +// OBSOLETE m3_ops.to_has_memory = 1; +// OBSOLETE m3_ops.to_has_stack = 1; +// OBSOLETE m3_ops.to_has_registers = 1; +// OBSOLETE m3_ops.to_has_execution = 1; +// OBSOLETE m3_ops.to_magic = OPS_MAGIC; +// OBSOLETE } +// OBSOLETE +// OBSOLETE void +// OBSOLETE _initialize_m3_nat (void) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE +// OBSOLETE init_m3_ops (); +// OBSOLETE add_target (&m3_ops); +// OBSOLETE +// OBSOLETE ret = mach_port_allocate (mach_task_self (), +// OBSOLETE MACH_PORT_RIGHT_PORT_SET, +// OBSOLETE &inferior_wait_port_set); +// OBSOLETE if (ret != KERN_SUCCESS) +// OBSOLETE internal_error (__FILE__, __LINE__, +// OBSOLETE "initial port set %s", mach_error_string (ret)); +// OBSOLETE +// OBSOLETE /* mach_really_wait now waits for this */ +// OBSOLETE currently_waiting_for = inferior_wait_port_set; +// OBSOLETE +// OBSOLETE ret = netname_look_up (name_server_port, hostname, "MachID", &mid_server); +// OBSOLETE if (ret != KERN_SUCCESS) +// OBSOLETE { +// OBSOLETE mid_server = MACH_PORT_NULL; +// OBSOLETE +// OBSOLETE warning ("initialize machid: netname_lookup_up(MachID) : %s", +// OBSOLETE mach_error_string (ret)); +// OBSOLETE warning ("Some (most?) features disabled..."); +// OBSOLETE } +// OBSOLETE +// OBSOLETE mid_auth = mach_privileged_host_port (); +// OBSOLETE if (mid_auth == MACH_PORT_NULL) +// OBSOLETE mid_auth = mach_task_self (); +// OBSOLETE +// OBSOLETE obstack_init (port_chain_obstack); +// OBSOLETE +// OBSOLETE ret = mach_port_allocate (mach_task_self (), +// OBSOLETE MACH_PORT_RIGHT_RECEIVE, +// OBSOLETE &thread_exception_port); +// OBSOLETE CHK ("Creating thread_exception_port for single stepping", ret); +// OBSOLETE +// OBSOLETE ret = mach_port_insert_right (mach_task_self (), +// OBSOLETE thread_exception_port, +// OBSOLETE thread_exception_port, +// OBSOLETE MACH_MSG_TYPE_MAKE_SEND); +// OBSOLETE CHK ("Inserting send right to thread_exception_port", ret); +// OBSOLETE +// OBSOLETE /* Allocate message port */ +// OBSOLETE ret = mach_port_allocate (mach_task_self (), +// OBSOLETE MACH_PORT_RIGHT_RECEIVE, +// OBSOLETE &our_message_port); +// OBSOLETE if (ret != KERN_SUCCESS) +// OBSOLETE warning ("Creating message port %s", mach_error_string (ret)); +// OBSOLETE else +// OBSOLETE { +// OBSOLETE char buf[MAX_NAME_LEN]; +// OBSOLETE ret = mach_port_move_member (mach_task_self (), +// OBSOLETE our_message_port, +// OBSOLETE inferior_wait_port_set); +// OBSOLETE if (ret != KERN_SUCCESS) +// OBSOLETE warning ("message move member %s", mach_error_string (ret)); +// OBSOLETE +// OBSOLETE +// OBSOLETE /* @@@@ No way to change message port name currently */ +// OBSOLETE /* Foo. This assumes gdb has a unix pid */ +// OBSOLETE sprintf (buf, "gdb-%d", getpid ()); +// OBSOLETE gdb_register_port (buf, our_message_port); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Heap for thread commands */ +// OBSOLETE obstack_init (cproc_obstack); +// OBSOLETE +// OBSOLETE add_mach_specific_commands (); +// OBSOLETE } diff --git a/gdb/m68k-tdep.c b/gdb/m68k-tdep.c index 7a9886b5076..a93a156080e 100644 --- a/gdb/m68k-tdep.c +++ b/gdb/m68k-tdep.c @@ -614,7 +614,7 @@ m68k_frame_init_saved_regs (struct frame_info *frame_info) } else { - pc = get_pc_function_start (get_frame_pc (frame_info)); + pc = get_frame_func (frame_info); nextinsn = read_memory_unsigned_integer (pc, 2); if (P_PEA_FP == nextinsn diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index f9424d76946..3e8339b92d0 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -1818,10 +1818,10 @@ heuristic_proc_start (CORE_ADDR pc) if (start_pc < fence) { /* It's not clear to me why we reach this point when - stop_soon_quietly, but with this test, at least we + stop_soon, but with this test, at least we don't print out warnings for every child forked (eg, on decstation). 22apr93 rich@cygnus.com. */ - if (!stop_soon_quietly) + if (stop_soon == NO_STOP_QUIETLY) { static int blurb_printed = 0; @@ -4049,154 +4049,126 @@ mips_read_fp_register_double (int regno, char *rare_buffer) } static void -mips_print_register (int regnum, int all) -{ - char *raw_buffer = alloca (MAX_REGISTER_RAW_SIZE); - - /* Get the data in raw format. */ - if (!frame_register_read (deprecated_selected_frame, regnum, raw_buffer)) - { - printf_filtered ("%s: [Invalid]", REGISTER_NAME (regnum)); - return; - } - - /* If we have a actual 32-bit floating point register (or we are in - 32-bit compatibility mode), and the register is even-numbered, - also print it as a double (spanning two registers). */ - if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT - && (REGISTER_RAW_SIZE (regnum) == 4 - || mips2_fp_compat ()) - && !((regnum - FP0_REGNUM) & 1)) - { - char *dbuffer = alloca (2 * MAX_REGISTER_RAW_SIZE); - - mips_read_fp_register_double (regnum, dbuffer); - - printf_filtered ("(d%d: ", regnum - FP0_REGNUM); - val_print (mips_double_register_type (), dbuffer, 0, 0, - gdb_stdout, 0, 1, 0, Val_pretty_default); - printf_filtered ("); "); - } - fputs_filtered (REGISTER_NAME (regnum), gdb_stdout); - - /* The problem with printing numeric register names (r26, etc.) is that - the user can't use them on input. Probably the best solution is to - fix it so that either the numeric or the funky (a2, etc.) names - are accepted on input. */ - if (regnum < MIPS_NUMREGS) - printf_filtered ("(r%d): ", regnum); - else - printf_filtered (": "); - - /* If virtual format is floating, print it that way. */ - if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT) - if (REGISTER_RAW_SIZE (regnum) == 8 && !mips2_fp_compat ()) - { - /* We have a meaningful 64-bit value in this register. Show - it as a 32-bit float and a 64-bit double. */ - int offset = 4 * (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG); - - printf_filtered (" (float) "); - val_print (mips_float_register_type (), raw_buffer + offset, 0, 0, - gdb_stdout, 0, 1, 0, Val_pretty_default); - printf_filtered (", (double) "); - val_print (mips_double_register_type (), raw_buffer, 0, 0, - gdb_stdout, 0, 1, 0, Val_pretty_default); - } - else - val_print (REGISTER_VIRTUAL_TYPE (regnum), raw_buffer, 0, 0, - gdb_stdout, 0, 1, 0, Val_pretty_default); - /* Else print as integer in hex. */ - else - { - int offset; - - if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) - offset = REGISTER_RAW_SIZE (regnum) - REGISTER_VIRTUAL_SIZE (regnum); - else - offset = 0; - - print_scalar_formatted (raw_buffer + offset, - REGISTER_VIRTUAL_TYPE (regnum), - 'x', 0, gdb_stdout); - } -} - -/* Replacement for generic do_registers_info. - Print regs in pretty columns. */ - -static int -do_fp_register_row (int regnum) +mips_print_fp_register (int regnum) { /* do values for FP (float) regs */ char *raw_buffer; double doub, flt1, flt2; /* doubles extracted from raw hex data */ - int inv1, inv2, inv3; + int inv1, inv2, namelen; raw_buffer = (char *) alloca (2 * REGISTER_RAW_SIZE (FP0_REGNUM)); + printf_filtered ("%s:", REGISTER_NAME (regnum)); + printf_filtered ("%*s", 4 - (int) strlen (REGISTER_NAME (regnum)), ""); + if (REGISTER_RAW_SIZE (regnum) == 4 || mips2_fp_compat ()) { - /* 4-byte registers: we can fit two registers per row. */ - /* Also print every pair of 4-byte regs as an 8-byte double. */ + /* 4-byte registers: Print hex and floating. Also print even + numbered registers as doubles. */ mips_read_fp_register_single (regnum, raw_buffer); flt1 = unpack_double (mips_float_register_type (), raw_buffer, &inv1); - mips_read_fp_register_single (regnum + 1, raw_buffer); - flt2 = unpack_double (mips_float_register_type (), raw_buffer, &inv2); - - mips_read_fp_register_double (regnum, raw_buffer); - doub = unpack_double (mips_double_register_type (), raw_buffer, &inv3); + print_scalar_formatted (raw_buffer, builtin_type_uint32, 'x', 'w', + gdb_stdout); - printf_filtered (" %-5s", REGISTER_NAME (regnum)); + printf_filtered (" flt: "); if (inv1) - printf_filtered (": <invalid float>"); + printf_filtered (" <invalid float> "); else printf_filtered ("%-17.9g", flt1); - printf_filtered (" %-5s", REGISTER_NAME (regnum + 1)); - if (inv2) - printf_filtered (": <invalid float>"); - else - printf_filtered ("%-17.9g", flt2); - - printf_filtered (" dbl: "); - if (inv3) - printf_filtered ("<invalid double>"); - else - printf_filtered ("%-24.17g", doub); - printf_filtered ("\n"); + if (regnum % 2 == 0) + { + mips_read_fp_register_double (regnum, raw_buffer); + doub = unpack_double (mips_double_register_type (), raw_buffer, + &inv2); - /* may want to do hex display here (future enhancement) */ - regnum += 2; + printf_filtered (" dbl: "); + if (inv2) + printf_filtered ("<invalid double>"); + else + printf_filtered ("%-24.17g", doub); + } } else { - /* Eight byte registers: print each one as float AND as double. */ + /* Eight byte registers: print each one as hex, float and double. */ mips_read_fp_register_single (regnum, raw_buffer); flt1 = unpack_double (mips_float_register_type (), raw_buffer, &inv1); mips_read_fp_register_double (regnum, raw_buffer); - doub = unpack_double (mips_double_register_type (), raw_buffer, &inv3); + doub = unpack_double (mips_double_register_type (), raw_buffer, &inv2); + + + print_scalar_formatted (raw_buffer, builtin_type_uint64, 'x', 'g', + gdb_stdout); - printf_filtered (" %-5s: ", REGISTER_NAME (regnum)); + printf_filtered (" flt: "); if (inv1) printf_filtered ("<invalid float>"); else - printf_filtered ("flt: %-17.9g", flt1); + printf_filtered ("%-17.9g", flt1); printf_filtered (" dbl: "); - if (inv3) + if (inv2) printf_filtered ("<invalid double>"); else printf_filtered ("%-24.17g", doub); + } +} - printf_filtered ("\n"); - /* may want to do hex display here (future enhancement) */ - regnum++; +static void +mips_print_register (int regnum, int all) +{ + char *raw_buffer = alloca (MAX_REGISTER_RAW_SIZE); + int offset; + + if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT) + { + mips_print_fp_register (regnum); + return; } - return regnum; + + /* Get the data in raw format. */ + if (!frame_register_read (deprecated_selected_frame, regnum, raw_buffer)) + { + printf_filtered ("%s: [Invalid]", REGISTER_NAME (regnum)); + return; + } + + fputs_filtered (REGISTER_NAME (regnum), gdb_stdout); + + /* The problem with printing numeric register names (r26, etc.) is that + the user can't use them on input. Probably the best solution is to + fix it so that either the numeric or the funky (a2, etc.) names + are accepted on input. */ + if (regnum < MIPS_NUMREGS) + printf_filtered ("(r%d): ", regnum); + else + printf_filtered (": "); + + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + offset = REGISTER_RAW_SIZE (regnum) - REGISTER_VIRTUAL_SIZE (regnum); + else + offset = 0; + + print_scalar_formatted (raw_buffer + offset, + REGISTER_VIRTUAL_TYPE (regnum), + 'x', 0, gdb_stdout); } +/* Replacement for generic do_registers_info. + Print regs in pretty columns. */ + +static int +do_fp_register_row (int regnum) +{ + printf_filtered (" "); + mips_print_fp_register (regnum); + printf_filtered ("\n"); + return regnum + 1; +} + + /* Print a row's worth of GP (int) registers, with name labels above */ static int diff --git a/gdb/mipsm3-nat.c b/gdb/mipsm3-nat.c index 22f947f9db2..f1fd8590ce8 100644 --- a/gdb/mipsm3-nat.c +++ b/gdb/mipsm3-nat.c @@ -1,386 +1,386 @@ -/* Definitions to make GDB run on a mips box under Mach 3.0 - Copyright 1992, 1993, 1998, 2000, 2001 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* Mach specific routines for little endian mips (e.g. pmax) - * running Mach 3.0 - * - * Author: Jukka Virtanen <jtv@hut.fi> - */ - -#include "defs.h" -#include "inferior.h" -#include "regcache.h" - -#include <stdio.h> - -#include <mach.h> -#include <mach/message.h> -#include <mach/exception.h> -#include <mach_error.h> - -/* Find offsets to thread states at compile time. - * If your compiler does not grok this, check the hand coded - * offsets and use them. - */ - -#if 1 - -#define REG_OFFSET(reg) (int)(&((struct mips_thread_state *)0)->reg) -#define CREG_OFFSET(reg) (int)(&((struct mips_float_state *)0)->reg) -#define EREG_OFFSET(reg) (int)(&((struct mips_exc_state *)0)->reg) - -/* at reg_offset[i] is the offset to the mips_thread_state - * location where the gdb registers[i] is stored. - * - * -1 means mach does not save it anywhere. - */ -static int reg_offset[] = -{ - /* zero at v0 v1 */ - -1, REG_OFFSET (r1), REG_OFFSET (r2), REG_OFFSET (r3), - - /* a0 a1 a2 a3 */ - REG_OFFSET (r4), REG_OFFSET (r5), REG_OFFSET (r6), REG_OFFSET (r7), - - /* t0 t1 t2 t3 */ - REG_OFFSET (r8), REG_OFFSET (r9), REG_OFFSET (r10), REG_OFFSET (r11), - - /* t4 t5 t6 t7 */ - REG_OFFSET (r12), REG_OFFSET (r13), REG_OFFSET (r14), REG_OFFSET (r15), - - /* s0 s1 s2 s3 */ - REG_OFFSET (r16), REG_OFFSET (r17), REG_OFFSET (r18), REG_OFFSET (r19), - - /* s4 s5 s6 s7 */ - REG_OFFSET (r20), REG_OFFSET (r21), REG_OFFSET (r22), REG_OFFSET (r23), - - /* t8 t9 k0 k1 */ - REG_OFFSET (r24), REG_OFFSET (r25), REG_OFFSET (r26), REG_OFFSET (r27), - - /* gp sp s8(30) == fp(72) ra */ - REG_OFFSET (r28), REG_OFFSET (r29), REG_OFFSET (r30), REG_OFFSET (r31), - - /* sr(32) PS_REGNUM */ - EREG_OFFSET (coproc_state), - - /* lo(33) hi(34) */ - REG_OFFSET (mdlo), REG_OFFSET (mdhi), - - /* bad(35) cause(36) pc(37) */ - EREG_OFFSET (address), EREG_OFFSET (cause), REG_OFFSET (pc), - - /* f0(38) f1(39) f2(40) f3(41) */ - CREG_OFFSET (r0), CREG_OFFSET (r1), CREG_OFFSET (r2), CREG_OFFSET (r3), - CREG_OFFSET (r4), CREG_OFFSET (r5), CREG_OFFSET (r6), CREG_OFFSET (r7), - CREG_OFFSET (r8), CREG_OFFSET (r9), CREG_OFFSET (r10), CREG_OFFSET (r11), - CREG_OFFSET (r12), CREG_OFFSET (r13), CREG_OFFSET (r14), CREG_OFFSET (r15), - CREG_OFFSET (r16), CREG_OFFSET (r17), CREG_OFFSET (r18), CREG_OFFSET (r19), - CREG_OFFSET (r20), CREG_OFFSET (r21), CREG_OFFSET (r22), CREG_OFFSET (r23), - CREG_OFFSET (r24), CREG_OFFSET (r25), CREG_OFFSET (r26), CREG_OFFSET (r27), - CREG_OFFSET (r28), CREG_OFFSET (r29), CREG_OFFSET (r30), CREG_OFFSET (r31), - - /* fsr(70) fir(71) fp(72) == s8(30) */ - CREG_OFFSET (csr), CREG_OFFSET (esr), REG_OFFSET (r30) -}; -#else -/* If the compiler does not grok the above defines */ -static int reg_offset[] = -{ -/* mach_thread_state offsets: */ - -1, 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, - 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, -/*sr, lo, hi,addr,cause,pc */ - 8, 124, 128, 4, 0, 132, -/* mach_float_state offsets: */ - 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124, -/*fsr,fir */ - 128, 132, -/* FP_REGNUM pseudo maps to s8==r30 in mach_thread_state */ - 116 -}; -#endif - -/* Fetch COUNT contiguous registers from thread STATE starting from REGNUM - * Caller knows that the regs handled in one transaction are of same size. - */ -#define FETCH_REGS(state, regnum, count) \ - memcpy (&deprecated_registers[REGISTER_BYTE (regnum)], \ - (char *)state+reg_offset[ regnum ], \ - count*REGISTER_SIZE) - -/* Store COUNT contiguous registers to thread STATE starting from REGNUM */ -#define STORE_REGS(state, regnum, count) \ - memcpy ((char *)state+reg_offset[ regnum ], \ - &deprecated_registers[REGISTER_BYTE (regnum)], \ - count*REGISTER_SIZE) - -#define REGS_ALL -1 -#define REGS_NORMAL 1 -#define REGS_EXC 2 -#define REGS_COP1 4 - -/* Hardware regs that matches FP_REGNUM */ -#define MACH_FP_REGNUM 30 - -/* Fech thread's registers. if regno == -1, fetch all regs */ -void -fetch_inferior_registers (int regno) -{ - kern_return_t ret; - - thread_state_data_t state; - struct mips_exc_state exc_state; - - int stateCnt = MIPS_THREAD_STATE_COUNT; - - int which_regs = 0; /* A bit mask */ - - if (!MACH_PORT_VALID (current_thread)) - error ("fetch inferior registers: Invalid thread"); - - if (regno < -1 || regno >= NUM_REGS) - error ("invalid register %d supplied to fetch_inferior_registers", regno); - - if (regno == -1) - which_regs = REGS_ALL; - else if (regno == ZERO_REGNUM) - { - int zero = 0; - supply_register (ZERO_REGNUM, &zero); - return; - } - else if ((ZERO_REGNUM < regno && regno < PS_REGNUM) - || regno == FP_REGNUM - || regno == LO_REGNUM - || regno == HI_REGNUM - || regno == PC_REGNUM) - which_regs = REGS_NORMAL; - else if (FP0_REGNUM <= regno && regno <= FCRIR_REGNUM) - which_regs = REGS_COP1 | REGS_EXC; - else - which_regs = REGS_EXC; - - /* fetch regs saved to mips_thread_state */ - if (which_regs & REGS_NORMAL) - { - ret = thread_get_state (current_thread, - MIPS_THREAD_STATE, - state, - &stateCnt); - CHK ("fetch inferior registers: thread_get_state", ret); - - if (which_regs == REGS_NORMAL) - { - /* Fetch also FP_REGNUM if fetching MACH_FP_REGNUM and vice versa */ - if (regno == MACH_FP_REGNUM || regno == FP_REGNUM) - { - supply_register (FP_REGNUM, - (char *) state + reg_offset[MACH_FP_REGNUM]); - supply_register (MACH_FP_REGNUM, - (char *) state + reg_offset[MACH_FP_REGNUM]); - } - else - supply_register (regno, - (char *) state + reg_offset[regno]); - return; - } - - /* ZERO_REGNUM is always zero */ - *(int *) deprecated_registers = 0; - - /* Copy thread saved regs 1..31 to gdb's reg value array - * Luckily, they are contiquous - */ - FETCH_REGS (state, 1, 31); - - /* Copy mdlo and mdhi */ - FETCH_REGS (state, LO_REGNUM, 2); - - /* Copy PC */ - FETCH_REGS (state, PC_REGNUM, 1); - - /* Mach 3.0 saves FP to MACH_FP_REGNUM. - * For some reason gdb wants to assign a pseudo register for it. - */ - FETCH_REGS (state, FP_REGNUM, 1); - } - - /* Read exc state. Also read if need to fetch floats */ - if (which_regs & REGS_EXC) - { - stateCnt = MIPS_EXC_STATE_COUNT; - ret = thread_get_state (current_thread, - MIPS_EXC_STATE, - (thread_state_t) & exc_state, - &stateCnt); - CHK ("fetch inferior regs (exc): thread_get_state", ret); - - /* We need to fetch exc_state to see if the floating - * state is valid for the thread. - */ - - /* cproc_state: Which coprocessors the thread uses */ - supply_register (PS_REGNUM, - (char *) &exc_state + reg_offset[PS_REGNUM]); - - if (which_regs == REGS_EXC || which_regs == REGS_ALL) - { - supply_register (BADVADDR_REGNUM, - (char *) &exc_state + reg_offset[BADVADDR_REGNUM]); - - supply_register (CAUSE_REGNUM, - (char *) &exc_state + reg_offset[CAUSE_REGNUM]); - if (which_regs == REGS_EXC) - return; - } - } - - - if (which_regs & REGS_COP1) - { - /* If the thread does not have saved COPROC1, set regs to zero */ - - if (!(exc_state.coproc_state & MIPS_STATUS_USE_COP1)) - bzero (&deprecated_registers[REGISTER_BYTE (FP0_REGNUM)], - sizeof (struct mips_float_state)); - else - { - stateCnt = MIPS_FLOAT_STATE_COUNT; - ret = thread_get_state (current_thread, - MIPS_FLOAT_STATE, - state, - &stateCnt); - CHK ("fetch inferior regs (floats): thread_get_state", ret); - - if (regno != -1) - { - supply_register (regno, - (char *) state + reg_offset[regno]); - return; - } - - FETCH_REGS (state, FP0_REGNUM, 34); - } - } - - /* All registers are valid, if not returned yet */ - deprecated_registers_fetched (); -} - -/* Store gdb's view of registers to the thread. - * All registers are always valid when entering here. - * @@ ahem, maybe that is too strict, we could validate the necessary ones - * here. - * - * Hmm. It seems that gdb set $reg=value command first reads everything, - * then sets the reg and then stores everything. -> we must make sure - * that the immutable registers are not changed by reading them first. - */ - -void -store_inferior_registers (register int regno) -{ - thread_state_data_t state; - kern_return_t ret; - - if (!MACH_PORT_VALID (current_thread)) - error ("store inferior registers: Invalid thread"); - - /* Check for read only regs. - * @@ If some of these is can be changed, fix this - */ - if (regno == ZERO_REGNUM || - regno == PS_REGNUM || - regno == BADVADDR_REGNUM || - regno == CAUSE_REGNUM || - regno == FCRIR_REGNUM) - { - message ("You can not alter read-only register `%s'", - REGISTER_NAME (regno)); - fetch_inferior_registers (regno); - return; - } - - if (regno == -1) - { - /* Don't allow these to change */ - - /* ZERO_REGNUM */ - *(int *) deprecated_registers = 0; - - fetch_inferior_registers (PS_REGNUM); - fetch_inferior_registers (BADVADDR_REGNUM); - fetch_inferior_registers (CAUSE_REGNUM); - fetch_inferior_registers (FCRIR_REGNUM); - } - - if (regno == -1 || (ZERO_REGNUM < regno && regno <= PC_REGNUM)) - { -#if 1 - /* Mach 3.0 saves thread's FP to MACH_FP_REGNUM. - * GDB wants assigns a pseudo register FP_REGNUM for frame pointer. - * - * @@@ Here I assume (!) that gdb's FP has the value that - * should go to threads frame pointer. If not true, this - * fails badly!!!!! - */ - memcpy (&deprecated_registers[REGISTER_BYTE (MACH_FP_REGNUM)], - &deprecated_registers[REGISTER_BYTE (FP_REGNUM)], - REGISTER_RAW_SIZE (FP_REGNUM)); -#endif - - /* Save gdb's regs 1..31 to thread saved regs 1..31 - * Luckily, they are contiquous - */ - STORE_REGS (state, 1, 31); - - /* Save mdlo, mdhi */ - STORE_REGS (state, LO_REGNUM, 2); - - /* Save PC */ - STORE_REGS (state, PC_REGNUM, 1); - - ret = thread_set_state (current_thread, - MIPS_THREAD_STATE, - state, - MIPS_FLOAT_STATE_COUNT); - CHK ("store inferior regs : thread_set_state", ret); - } - - if (regno == -1 || regno >= FP0_REGNUM) - { - /* If thread has floating state, save it */ - if (read_register (PS_REGNUM) & MIPS_STATUS_USE_COP1) - { - /* Do NOT save FCRIR_REGNUM */ - STORE_REGS (state, FP0_REGNUM, 33); - - ret = thread_set_state (current_thread, - MIPS_FLOAT_STATE, - state, - MIPS_FLOAT_STATE_COUNT); - CHK ("store inferior registers (floats): thread_set_state", ret); - } - else if (regno != -1) - message - ("Thread does not use floating point unit, floating regs not saved"); - } -} +// OBSOLETE /* Definitions to make GDB run on a mips box under Mach 3.0 +// OBSOLETE Copyright 1992, 1993, 1998, 2000, 2001 Free Software Foundation, Inc. +// OBSOLETE +// OBSOLETE This file is part of GDB. +// OBSOLETE +// OBSOLETE This program is free software; you can redistribute it and/or modify +// OBSOLETE it under the terms of the GNU General Public License as published by +// OBSOLETE the Free Software Foundation; either version 2 of the License, or +// OBSOLETE (at your option) any later version. +// OBSOLETE +// OBSOLETE This program is distributed in the hope that it will be useful, +// OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of +// OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// OBSOLETE GNU General Public License for more details. +// OBSOLETE +// OBSOLETE You should have received a copy of the GNU General Public License +// OBSOLETE along with this program; if not, write to the Free Software +// OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, +// OBSOLETE Boston, MA 02111-1307, USA. */ +// OBSOLETE +// OBSOLETE /* Mach specific routines for little endian mips (e.g. pmax) +// OBSOLETE * running Mach 3.0 +// OBSOLETE * +// OBSOLETE * Author: Jukka Virtanen <jtv@hut.fi> +// OBSOLETE */ +// OBSOLETE +// OBSOLETE #include "defs.h" +// OBSOLETE #include "inferior.h" +// OBSOLETE #include "regcache.h" +// OBSOLETE +// OBSOLETE #include <stdio.h> +// OBSOLETE +// OBSOLETE #include <mach.h> +// OBSOLETE #include <mach/message.h> +// OBSOLETE #include <mach/exception.h> +// OBSOLETE #include <mach_error.h> +// OBSOLETE +// OBSOLETE /* Find offsets to thread states at compile time. +// OBSOLETE * If your compiler does not grok this, check the hand coded +// OBSOLETE * offsets and use them. +// OBSOLETE */ +// OBSOLETE +// OBSOLETE #if 1 +// OBSOLETE +// OBSOLETE #define REG_OFFSET(reg) (int)(&((struct mips_thread_state *)0)->reg) +// OBSOLETE #define CREG_OFFSET(reg) (int)(&((struct mips_float_state *)0)->reg) +// OBSOLETE #define EREG_OFFSET(reg) (int)(&((struct mips_exc_state *)0)->reg) +// OBSOLETE +// OBSOLETE /* at reg_offset[i] is the offset to the mips_thread_state +// OBSOLETE * location where the gdb registers[i] is stored. +// OBSOLETE * +// OBSOLETE * -1 means mach does not save it anywhere. +// OBSOLETE */ +// OBSOLETE static int reg_offset[] = +// OBSOLETE { +// OBSOLETE /* zero at v0 v1 */ +// OBSOLETE -1, REG_OFFSET (r1), REG_OFFSET (r2), REG_OFFSET (r3), +// OBSOLETE +// OBSOLETE /* a0 a1 a2 a3 */ +// OBSOLETE REG_OFFSET (r4), REG_OFFSET (r5), REG_OFFSET (r6), REG_OFFSET (r7), +// OBSOLETE +// OBSOLETE /* t0 t1 t2 t3 */ +// OBSOLETE REG_OFFSET (r8), REG_OFFSET (r9), REG_OFFSET (r10), REG_OFFSET (r11), +// OBSOLETE +// OBSOLETE /* t4 t5 t6 t7 */ +// OBSOLETE REG_OFFSET (r12), REG_OFFSET (r13), REG_OFFSET (r14), REG_OFFSET (r15), +// OBSOLETE +// OBSOLETE /* s0 s1 s2 s3 */ +// OBSOLETE REG_OFFSET (r16), REG_OFFSET (r17), REG_OFFSET (r18), REG_OFFSET (r19), +// OBSOLETE +// OBSOLETE /* s4 s5 s6 s7 */ +// OBSOLETE REG_OFFSET (r20), REG_OFFSET (r21), REG_OFFSET (r22), REG_OFFSET (r23), +// OBSOLETE +// OBSOLETE /* t8 t9 k0 k1 */ +// OBSOLETE REG_OFFSET (r24), REG_OFFSET (r25), REG_OFFSET (r26), REG_OFFSET (r27), +// OBSOLETE +// OBSOLETE /* gp sp s8(30) == fp(72) ra */ +// OBSOLETE REG_OFFSET (r28), REG_OFFSET (r29), REG_OFFSET (r30), REG_OFFSET (r31), +// OBSOLETE +// OBSOLETE /* sr(32) PS_REGNUM */ +// OBSOLETE EREG_OFFSET (coproc_state), +// OBSOLETE +// OBSOLETE /* lo(33) hi(34) */ +// OBSOLETE REG_OFFSET (mdlo), REG_OFFSET (mdhi), +// OBSOLETE +// OBSOLETE /* bad(35) cause(36) pc(37) */ +// OBSOLETE EREG_OFFSET (address), EREG_OFFSET (cause), REG_OFFSET (pc), +// OBSOLETE +// OBSOLETE /* f0(38) f1(39) f2(40) f3(41) */ +// OBSOLETE CREG_OFFSET (r0), CREG_OFFSET (r1), CREG_OFFSET (r2), CREG_OFFSET (r3), +// OBSOLETE CREG_OFFSET (r4), CREG_OFFSET (r5), CREG_OFFSET (r6), CREG_OFFSET (r7), +// OBSOLETE CREG_OFFSET (r8), CREG_OFFSET (r9), CREG_OFFSET (r10), CREG_OFFSET (r11), +// OBSOLETE CREG_OFFSET (r12), CREG_OFFSET (r13), CREG_OFFSET (r14), CREG_OFFSET (r15), +// OBSOLETE CREG_OFFSET (r16), CREG_OFFSET (r17), CREG_OFFSET (r18), CREG_OFFSET (r19), +// OBSOLETE CREG_OFFSET (r20), CREG_OFFSET (r21), CREG_OFFSET (r22), CREG_OFFSET (r23), +// OBSOLETE CREG_OFFSET (r24), CREG_OFFSET (r25), CREG_OFFSET (r26), CREG_OFFSET (r27), +// OBSOLETE CREG_OFFSET (r28), CREG_OFFSET (r29), CREG_OFFSET (r30), CREG_OFFSET (r31), +// OBSOLETE +// OBSOLETE /* fsr(70) fir(71) fp(72) == s8(30) */ +// OBSOLETE CREG_OFFSET (csr), CREG_OFFSET (esr), REG_OFFSET (r30) +// OBSOLETE }; +// OBSOLETE #else +// OBSOLETE /* If the compiler does not grok the above defines */ +// OBSOLETE static int reg_offset[] = +// OBSOLETE { +// OBSOLETE /* mach_thread_state offsets: */ +// OBSOLETE -1, 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, +// OBSOLETE 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, +// OBSOLETE /*sr, lo, hi,addr,cause,pc */ +// OBSOLETE 8, 124, 128, 4, 0, 132, +// OBSOLETE /* mach_float_state offsets: */ +// OBSOLETE 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, +// OBSOLETE 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124, +// OBSOLETE /*fsr,fir */ +// OBSOLETE 128, 132, +// OBSOLETE /* FP_REGNUM pseudo maps to s8==r30 in mach_thread_state */ +// OBSOLETE 116 +// OBSOLETE }; +// OBSOLETE #endif +// OBSOLETE +// OBSOLETE /* Fetch COUNT contiguous registers from thread STATE starting from REGNUM +// OBSOLETE * Caller knows that the regs handled in one transaction are of same size. +// OBSOLETE */ +// OBSOLETE #define FETCH_REGS(state, regnum, count) \ +// OBSOLETE memcpy (&deprecated_registers[REGISTER_BYTE (regnum)], \ +// OBSOLETE (char *)state+reg_offset[ regnum ], \ +// OBSOLETE count*REGISTER_SIZE) +// OBSOLETE +// OBSOLETE /* Store COUNT contiguous registers to thread STATE starting from REGNUM */ +// OBSOLETE #define STORE_REGS(state, regnum, count) \ +// OBSOLETE memcpy ((char *)state+reg_offset[ regnum ], \ +// OBSOLETE &deprecated_registers[REGISTER_BYTE (regnum)], \ +// OBSOLETE count*REGISTER_SIZE) +// OBSOLETE +// OBSOLETE #define REGS_ALL -1 +// OBSOLETE #define REGS_NORMAL 1 +// OBSOLETE #define REGS_EXC 2 +// OBSOLETE #define REGS_COP1 4 +// OBSOLETE +// OBSOLETE /* Hardware regs that matches FP_REGNUM */ +// OBSOLETE #define MACH_FP_REGNUM 30 +// OBSOLETE +// OBSOLETE /* Fech thread's registers. if regno == -1, fetch all regs */ +// OBSOLETE void +// OBSOLETE fetch_inferior_registers (int regno) +// OBSOLETE { +// OBSOLETE kern_return_t ret; +// OBSOLETE +// OBSOLETE thread_state_data_t state; +// OBSOLETE struct mips_exc_state exc_state; +// OBSOLETE +// OBSOLETE int stateCnt = MIPS_THREAD_STATE_COUNT; +// OBSOLETE +// OBSOLETE int which_regs = 0; /* A bit mask */ +// OBSOLETE +// OBSOLETE if (!MACH_PORT_VALID (current_thread)) +// OBSOLETE error ("fetch inferior registers: Invalid thread"); +// OBSOLETE +// OBSOLETE if (regno < -1 || regno >= NUM_REGS) +// OBSOLETE error ("invalid register %d supplied to fetch_inferior_registers", regno); +// OBSOLETE +// OBSOLETE if (regno == -1) +// OBSOLETE which_regs = REGS_ALL; +// OBSOLETE else if (regno == ZERO_REGNUM) +// OBSOLETE { +// OBSOLETE int zero = 0; +// OBSOLETE supply_register (ZERO_REGNUM, &zero); +// OBSOLETE return; +// OBSOLETE } +// OBSOLETE else if ((ZERO_REGNUM < regno && regno < PS_REGNUM) +// OBSOLETE || regno == FP_REGNUM +// OBSOLETE || regno == LO_REGNUM +// OBSOLETE || regno == HI_REGNUM +// OBSOLETE || regno == PC_REGNUM) +// OBSOLETE which_regs = REGS_NORMAL; +// OBSOLETE else if (FP0_REGNUM <= regno && regno <= FCRIR_REGNUM) +// OBSOLETE which_regs = REGS_COP1 | REGS_EXC; +// OBSOLETE else +// OBSOLETE which_regs = REGS_EXC; +// OBSOLETE +// OBSOLETE /* fetch regs saved to mips_thread_state */ +// OBSOLETE if (which_regs & REGS_NORMAL) +// OBSOLETE { +// OBSOLETE ret = thread_get_state (current_thread, +// OBSOLETE MIPS_THREAD_STATE, +// OBSOLETE state, +// OBSOLETE &stateCnt); +// OBSOLETE CHK ("fetch inferior registers: thread_get_state", ret); +// OBSOLETE +// OBSOLETE if (which_regs == REGS_NORMAL) +// OBSOLETE { +// OBSOLETE /* Fetch also FP_REGNUM if fetching MACH_FP_REGNUM and vice versa */ +// OBSOLETE if (regno == MACH_FP_REGNUM || regno == FP_REGNUM) +// OBSOLETE { +// OBSOLETE supply_register (FP_REGNUM, +// OBSOLETE (char *) state + reg_offset[MACH_FP_REGNUM]); +// OBSOLETE supply_register (MACH_FP_REGNUM, +// OBSOLETE (char *) state + reg_offset[MACH_FP_REGNUM]); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE supply_register (regno, +// OBSOLETE (char *) state + reg_offset[regno]); +// OBSOLETE return; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* ZERO_REGNUM is always zero */ +// OBSOLETE *(int *) deprecated_registers = 0; +// OBSOLETE +// OBSOLETE /* Copy thread saved regs 1..31 to gdb's reg value array +// OBSOLETE * Luckily, they are contiquous +// OBSOLETE */ +// OBSOLETE FETCH_REGS (state, 1, 31); +// OBSOLETE +// OBSOLETE /* Copy mdlo and mdhi */ +// OBSOLETE FETCH_REGS (state, LO_REGNUM, 2); +// OBSOLETE +// OBSOLETE /* Copy PC */ +// OBSOLETE FETCH_REGS (state, PC_REGNUM, 1); +// OBSOLETE +// OBSOLETE /* Mach 3.0 saves FP to MACH_FP_REGNUM. +// OBSOLETE * For some reason gdb wants to assign a pseudo register for it. +// OBSOLETE */ +// OBSOLETE FETCH_REGS (state, FP_REGNUM, 1); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Read exc state. Also read if need to fetch floats */ +// OBSOLETE if (which_regs & REGS_EXC) +// OBSOLETE { +// OBSOLETE stateCnt = MIPS_EXC_STATE_COUNT; +// OBSOLETE ret = thread_get_state (current_thread, +// OBSOLETE MIPS_EXC_STATE, +// OBSOLETE (thread_state_t) & exc_state, +// OBSOLETE &stateCnt); +// OBSOLETE CHK ("fetch inferior regs (exc): thread_get_state", ret); +// OBSOLETE +// OBSOLETE /* We need to fetch exc_state to see if the floating +// OBSOLETE * state is valid for the thread. +// OBSOLETE */ +// OBSOLETE +// OBSOLETE /* cproc_state: Which coprocessors the thread uses */ +// OBSOLETE supply_register (PS_REGNUM, +// OBSOLETE (char *) &exc_state + reg_offset[PS_REGNUM]); +// OBSOLETE +// OBSOLETE if (which_regs == REGS_EXC || which_regs == REGS_ALL) +// OBSOLETE { +// OBSOLETE supply_register (BADVADDR_REGNUM, +// OBSOLETE (char *) &exc_state + reg_offset[BADVADDR_REGNUM]); +// OBSOLETE +// OBSOLETE supply_register (CAUSE_REGNUM, +// OBSOLETE (char *) &exc_state + reg_offset[CAUSE_REGNUM]); +// OBSOLETE if (which_regs == REGS_EXC) +// OBSOLETE return; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE +// OBSOLETE if (which_regs & REGS_COP1) +// OBSOLETE { +// OBSOLETE /* If the thread does not have saved COPROC1, set regs to zero */ +// OBSOLETE +// OBSOLETE if (!(exc_state.coproc_state & MIPS_STATUS_USE_COP1)) +// OBSOLETE bzero (&deprecated_registers[REGISTER_BYTE (FP0_REGNUM)], +// OBSOLETE sizeof (struct mips_float_state)); +// OBSOLETE else +// OBSOLETE { +// OBSOLETE stateCnt = MIPS_FLOAT_STATE_COUNT; +// OBSOLETE ret = thread_get_state (current_thread, +// OBSOLETE MIPS_FLOAT_STATE, +// OBSOLETE state, +// OBSOLETE &stateCnt); +// OBSOLETE CHK ("fetch inferior regs (floats): thread_get_state", ret); +// OBSOLETE +// OBSOLETE if (regno != -1) +// OBSOLETE { +// OBSOLETE supply_register (regno, +// OBSOLETE (char *) state + reg_offset[regno]); +// OBSOLETE return; +// OBSOLETE } +// OBSOLETE +// OBSOLETE FETCH_REGS (state, FP0_REGNUM, 34); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* All registers are valid, if not returned yet */ +// OBSOLETE deprecated_registers_fetched (); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Store gdb's view of registers to the thread. +// OBSOLETE * All registers are always valid when entering here. +// OBSOLETE * @@ ahem, maybe that is too strict, we could validate the necessary ones +// OBSOLETE * here. +// OBSOLETE * +// OBSOLETE * Hmm. It seems that gdb set $reg=value command first reads everything, +// OBSOLETE * then sets the reg and then stores everything. -> we must make sure +// OBSOLETE * that the immutable registers are not changed by reading them first. +// OBSOLETE */ +// OBSOLETE +// OBSOLETE void +// OBSOLETE store_inferior_registers (register int regno) +// OBSOLETE { +// OBSOLETE thread_state_data_t state; +// OBSOLETE kern_return_t ret; +// OBSOLETE +// OBSOLETE if (!MACH_PORT_VALID (current_thread)) +// OBSOLETE error ("store inferior registers: Invalid thread"); +// OBSOLETE +// OBSOLETE /* Check for read only regs. +// OBSOLETE * @@ If some of these is can be changed, fix this +// OBSOLETE */ +// OBSOLETE if (regno == ZERO_REGNUM || +// OBSOLETE regno == PS_REGNUM || +// OBSOLETE regno == BADVADDR_REGNUM || +// OBSOLETE regno == CAUSE_REGNUM || +// OBSOLETE regno == FCRIR_REGNUM) +// OBSOLETE { +// OBSOLETE message ("You can not alter read-only register `%s'", +// OBSOLETE REGISTER_NAME (regno)); +// OBSOLETE fetch_inferior_registers (regno); +// OBSOLETE return; +// OBSOLETE } +// OBSOLETE +// OBSOLETE if (regno == -1) +// OBSOLETE { +// OBSOLETE /* Don't allow these to change */ +// OBSOLETE +// OBSOLETE /* ZERO_REGNUM */ +// OBSOLETE *(int *) deprecated_registers = 0; +// OBSOLETE +// OBSOLETE fetch_inferior_registers (PS_REGNUM); +// OBSOLETE fetch_inferior_registers (BADVADDR_REGNUM); +// OBSOLETE fetch_inferior_registers (CAUSE_REGNUM); +// OBSOLETE fetch_inferior_registers (FCRIR_REGNUM); +// OBSOLETE } +// OBSOLETE +// OBSOLETE if (regno == -1 || (ZERO_REGNUM < regno && regno <= PC_REGNUM)) +// OBSOLETE { +// OBSOLETE #if 1 +// OBSOLETE /* Mach 3.0 saves thread's FP to MACH_FP_REGNUM. +// OBSOLETE * GDB wants assigns a pseudo register FP_REGNUM for frame pointer. +// OBSOLETE * +// OBSOLETE * @@@ Here I assume (!) that gdb's FP has the value that +// OBSOLETE * should go to threads frame pointer. If not true, this +// OBSOLETE * fails badly!!!!! +// OBSOLETE */ +// OBSOLETE memcpy (&deprecated_registers[REGISTER_BYTE (MACH_FP_REGNUM)], +// OBSOLETE &deprecated_registers[REGISTER_BYTE (FP_REGNUM)], +// OBSOLETE REGISTER_RAW_SIZE (FP_REGNUM)); +// OBSOLETE #endif +// OBSOLETE +// OBSOLETE /* Save gdb's regs 1..31 to thread saved regs 1..31 +// OBSOLETE * Luckily, they are contiquous +// OBSOLETE */ +// OBSOLETE STORE_REGS (state, 1, 31); +// OBSOLETE +// OBSOLETE /* Save mdlo, mdhi */ +// OBSOLETE STORE_REGS (state, LO_REGNUM, 2); +// OBSOLETE +// OBSOLETE /* Save PC */ +// OBSOLETE STORE_REGS (state, PC_REGNUM, 1); +// OBSOLETE +// OBSOLETE ret = thread_set_state (current_thread, +// OBSOLETE MIPS_THREAD_STATE, +// OBSOLETE state, +// OBSOLETE MIPS_FLOAT_STATE_COUNT); +// OBSOLETE CHK ("store inferior regs : thread_set_state", ret); +// OBSOLETE } +// OBSOLETE +// OBSOLETE if (regno == -1 || regno >= FP0_REGNUM) +// OBSOLETE { +// OBSOLETE /* If thread has floating state, save it */ +// OBSOLETE if (read_register (PS_REGNUM) & MIPS_STATUS_USE_COP1) +// OBSOLETE { +// OBSOLETE /* Do NOT save FCRIR_REGNUM */ +// OBSOLETE STORE_REGS (state, FP0_REGNUM, 33); +// OBSOLETE +// OBSOLETE ret = thread_set_state (current_thread, +// OBSOLETE MIPS_FLOAT_STATE, +// OBSOLETE state, +// OBSOLETE MIPS_FLOAT_STATE_COUNT); +// OBSOLETE CHK ("store inferior registers (floats): thread_set_state", ret); +// OBSOLETE } +// OBSOLETE else if (regno != -1) +// OBSOLETE message +// OBSOLETE ("Thread does not use floating point unit, floating regs not saved"); +// OBSOLETE } +// OBSOLETE } diff --git a/gdb/objc-lang.c b/gdb/objc-lang.c index 6fbbaa7fd2d..bc937ca7ea0 100644 --- a/gdb/objc-lang.c +++ b/gdb/objc-lang.c @@ -199,8 +199,10 @@ value_nsstring (char *ptr, int len) if (!target_has_execution) return 0; /* Can't call into inferior to create NSString. */ - if (!(sym = lookup_struct_typedef("NSString", 0, 1)) && - !(sym = lookup_struct_typedef("NXString", 0, 1))) + sym = lookup_struct_typedef("NSString", 0, 1); + if (sym == NULL) + sym = lookup_struct_typedef("NXString", 0, 1); + if (sym == NULL) type = lookup_pointer_type(builtin_type_void); else type = lookup_pointer_type(SYMBOL_TYPE (sym)); @@ -369,8 +371,6 @@ objc_printstr (struct ui_file *stream, char *string, int in_quotes = 0; int need_comma = 0; extern int inspect_it; - extern int repeat_count_threshold; - extern int print_max; /* If the string was not truncated due to `set print elements', and the last byte of it is a null, we don't print that, in @@ -890,16 +890,17 @@ selectors_info (char *regexp, int from_tty) } if (regexp != NULL) - if (0 != (val = re_comp (myregexp))) - error ("Invalid regexp (%s): %s", val, regexp); + { + val = re_comp (myregexp); + if (val != 0) + error ("Invalid regexp (%s): %s", val, regexp); + } /* First time thru is JUST to get max length and count. */ ALL_MSYMBOLS (objfile, msymbol) { QUIT; - name = SYMBOL_DEMANGLED_NAME (msymbol); - if (name == NULL) - name = DEPRECATED_SYMBOL_NAME (msymbol); + name = SYMBOL_NATURAL_NAME (msymbol); if (name && (name[0] == '-' || name[0] == '+') && name[1] == '[') /* Got a method name. */ @@ -930,9 +931,7 @@ selectors_info (char *regexp, int from_tty) ALL_MSYMBOLS (objfile, msymbol) { QUIT; - name = SYMBOL_DEMANGLED_NAME (msymbol); - if (name == NULL) - name = DEPRECATED_SYMBOL_NAME (msymbol); + name = SYMBOL_NATURAL_NAME (msymbol); if (name && (name[0] == '-' || name[0] == '+') && name[1] == '[') /* Got a method name. */ @@ -956,9 +955,7 @@ selectors_info (char *regexp, int from_tty) char *p = asel; QUIT; - name = SYMBOL_DEMANGLED_NAME (sym_arr[ix]); - if (name == NULL) - name = DEPRECATED_SYMBOL_NAME (sym_arr[ix]); + name = SYMBOL_NATURAL_NAME (sym_arr[ix]); name = strchr (name, ' ') + 1; if (p[0] && specialcmp(name, p) == 0) continue; /* Seen this one already (not unique). */ @@ -1033,16 +1030,17 @@ classes_info (char *regexp, int from_tty) } if (regexp != NULL) - if (0 != (val = re_comp (myregexp))) - error ("Invalid regexp (%s): %s", val, regexp); + { + val = re_comp (myregexp); + if (val != 0) + error ("Invalid regexp (%s): %s", val, regexp); + } /* First time thru is JUST to get max length and count. */ ALL_MSYMBOLS (objfile, msymbol) { QUIT; - name = SYMBOL_DEMANGLED_NAME (msymbol); - if (name == NULL) - name = DEPRECATED_SYMBOL_NAME (msymbol); + name = SYMBOL_NATURAL_NAME (msymbol); if (name && (name[0] == '-' || name[0] == '+') && name[1] == '[') /* Got a method name. */ @@ -1066,9 +1064,7 @@ classes_info (char *regexp, int from_tty) ALL_MSYMBOLS (objfile, msymbol) { QUIT; - name = SYMBOL_DEMANGLED_NAME (msymbol); - if (name == NULL) - name = DEPRECATED_SYMBOL_NAME (msymbol); + name = SYMBOL_NATURAL_NAME (msymbol); if (name && (name[0] == '-' || name[0] == '+') && name[1] == '[') /* Got a method name. */ @@ -1085,9 +1081,7 @@ classes_info (char *regexp, int from_tty) char *p = aclass; QUIT; - name = SYMBOL_DEMANGLED_NAME (sym_arr[ix]); - if (name == NULL) - name = DEPRECATED_SYMBOL_NAME (sym_arr[ix]); + name = SYMBOL_NATURAL_NAME (sym_arr[ix]); name += 2; if (p[0] && specialcmp(name, p) == 0) continue; /* Seen this one already (not unique). */ @@ -1348,9 +1342,7 @@ find_methods (struct symtab *symtab, char type, /* Not in the specified symtab. */ continue; - symname = SYMBOL_DEMANGLED_NAME (msymbol); - if (symname == NULL) - symname = DEPRECATED_SYMBOL_NAME (msymbol); + symname = SYMBOL_NATURAL_NAME (msymbol); if (symname == NULL) continue; @@ -1386,10 +1378,8 @@ find_methods (struct symtab *symtab, char type, sym = find_pc_function (SYMBOL_VALUE_ADDRESS (msymbol)); if (sym != NULL) { - const char *newsymname = SYMBOL_DEMANGLED_NAME (sym); + const char *newsymname = SYMBOL_NATURAL_NAME (sym); - if (newsymname == NULL) - newsymname = DEPRECATED_SYMBOL_NAME (sym); if (strcmp (symname, newsymname) == 0) { /* Found a high-level method sym: swap it into the @@ -1730,7 +1720,10 @@ find_objc_msgcall (CORE_ADDR pc, CORE_ADDR *new_pc) unsigned int i; find_objc_msgsend (); - if (new_pc != NULL) { *new_pc = 0; } + if (new_pc != NULL) + { + *new_pc = 0; + } for (i = 0; i < nmethcalls; i++) if ((pc >= methcalls[i].begin) && (pc < methcalls[i].end)) diff --git a/gdb/remote-vx.c b/gdb/remote-vx.c index 19153cf05b7..d9650e3426f 100644 --- a/gdb/remote-vx.c +++ b/gdb/remote-vx.c @@ -67,7 +67,7 @@ extern void vx_read_register (); extern void vx_write_register (); extern void symbol_file_command (); -extern int stop_soon_quietly; /* for wait_for_inferior */ +extern enum stop_kind stop_soon; /* for wait_for_inferior */ static int net_step (); static int net_ptrace_clnt_call (); /* Forward decl */ @@ -243,9 +243,9 @@ vx_create_inferior (char *exec_file, char *args, char **env) /* Install inferior's terminal modes. */ target_terminal_inferior (); - stop_soon_quietly = 1; + stop_soon = STOP_QUIETLY; wait_for_inferior (); /* Get the task spawn event */ - stop_soon_quietly = 0; + stop_soon = NO_STOP_QUIETLY; /* insert_step_breakpoint (); FIXME, do we need this? */ proceed (-1, TARGET_SIGNAL_DEFAULT, 0); diff --git a/gdb/remote-vxsparc.c b/gdb/remote-vxsparc.c index eb59b9fb43a..a97c18eed99 100644 --- a/gdb/remote-vxsparc.c +++ b/gdb/remote-vxsparc.c @@ -97,10 +97,9 @@ vx_read_register (int regno) bcopy (&sparc_greg_packet[SPARC_R_Y], &deprecated_registers[REGISTER_BYTE (Y_REGNUM)], 6 * SPARC_GREG_SIZE); - /* Now write the local and in registers to the register window - spill area in the frame. VxWorks does not do this for the - active frame automatically; it greatly simplifies debugging - (FRAME_FIND_SAVED_REGS, in particular, depends on this). */ + /* Now write the local and in registers to the register window spill + area in the frame. VxWorks does not do this for the active frame + automatically; it greatly simplifies debugging. */ sp = extract_address (&deprecated_registers[REGISTER_BYTE (SP_REGNUM)], REGISTER_RAW_SIZE (SP_REGNUM)); diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index ef330282782..4e7d374e56e 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -990,7 +990,7 @@ rs6000_pop_frame (void) still in the link register, otherwise walk the frames and retrieve the saved %pc value in the previous frame. */ - addr = get_pc_function_start (get_frame_pc (frame)); + addr = get_frame_func (frame); (void) skip_prologue (addr, get_frame_pc (frame), &fdata); wordsize = gdbarch_tdep (current_gdbarch)->wordsize; @@ -1499,7 +1499,7 @@ rs6000_frameless_function_invocation (struct frame_info *fi) && !(get_frame_type (get_next_frame (fi)) == SIGTRAMP_FRAME)) return 0; - func_start = get_pc_function_start (get_frame_pc (fi)); + func_start = get_frame_func (fi); /* If we failed to find the start of the function, it is a mistake to inspect the instructions. */ @@ -1540,7 +1540,7 @@ rs6000_frame_saved_pc (struct frame_info *fi) return deprecated_read_register_dummy (get_frame_pc (fi), get_frame_base (fi), PC_REGNUM); - func_start = get_pc_function_start (get_frame_pc (fi)); + func_start = get_frame_func (fi); /* If we failed to find the start of the function, it is a mistake to inspect the instructions. */ @@ -1596,8 +1596,7 @@ frame_get_saved_regs (struct frame_info *fi, struct rs6000_framedata *fdatap) if (fdatap == NULL) { fdatap = &work_fdata; - (void) skip_prologue (get_pc_function_start (get_frame_pc (fi)), - get_frame_pc (fi), fdatap); + (void) skip_prologue (get_frame_func (fi), get_frame_pc (fi), fdatap); } frame_saved_regs_zalloc (fi); @@ -1647,7 +1646,7 @@ frame_get_saved_regs (struct frame_info *fi, struct rs6000_framedata *fdatap) CORE_ADDR gpr_addr = frame_addr + fdatap->gpr_offset; for (i = fdatap->saved_gpr; i < 32; i++) { - get_frame_saved_regs (fi)[i] = gpr_addr; + get_frame_saved_regs (fi)[tdep->ppc_gp0_regnum + i] = gpr_addr; gpr_addr += wordsize; } } @@ -1720,8 +1719,7 @@ frame_initial_stack_address (struct frame_info *fi) /* Find out if this function is using an alloca register. */ - (void) skip_prologue (get_pc_function_start (get_frame_pc (fi)), - get_frame_pc (fi), &fdata); + (void) skip_prologue (get_frame_func (fi), get_frame_pc (fi), &fdata); /* If saved registers of this frame are not known yet, read and cache them. */ @@ -1894,8 +1892,8 @@ rs6000_register_convert_to_virtual (int n, struct type *type, { if (TYPE_LENGTH (type) != REGISTER_RAW_SIZE (n)) { - double val = extract_floating (from, REGISTER_RAW_SIZE (n)); - store_floating (to, TYPE_LENGTH (type), val); + double val = deprecated_extract_floating (from, REGISTER_RAW_SIZE (n)); + deprecated_store_floating (to, TYPE_LENGTH (type), val); } else memcpy (to, from, REGISTER_RAW_SIZE (n)); @@ -1910,8 +1908,8 @@ rs6000_register_convert_to_raw (struct type *type, int n, { if (TYPE_LENGTH (type) != REGISTER_RAW_SIZE (n)) { - double val = extract_floating (from, TYPE_LENGTH (type)); - store_floating (to, REGISTER_RAW_SIZE (n), val); + double val = deprecated_extract_floating (from, TYPE_LENGTH (type)); + deprecated_store_floating (to, REGISTER_RAW_SIZE (n), val); } else memcpy (to, from, REGISTER_RAW_SIZE (n)); @@ -2741,9 +2739,9 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) else { arch = bfd_arch_powerpc; - mach = 0; - bfd_default_set_arch_mach (&abfd, arch, mach); + bfd_default_set_arch_mach (&abfd, arch, 0); info.bfd_arch_info = bfd_get_arch_info (&abfd); + mach = info.bfd_arch_info->mach; } tdep = xmalloc (sizeof (struct gdbarch_tdep)); tdep->wordsize = wordsize; diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c index deff25d4f2d..2f8f4ff971b 100644 --- a/gdb/s390-tdep.c +++ b/gdb/s390-tdep.c @@ -775,7 +775,7 @@ s390_function_start (struct frame_info *fi) if (get_frame_extra_info (fi) && get_frame_extra_info (fi)->initialised) function_start = get_frame_extra_info (fi)->function_start; else if (get_frame_pc (fi)) - function_start = get_pc_function_start (get_frame_pc (fi)); + function_start = get_frame_func (fi); return function_start; } diff --git a/gdb/sentinel-frame.c b/gdb/sentinel-frame.c index e4060d27767..dab16478413 100644 --- a/gdb/sentinel-frame.c +++ b/gdb/sentinel-frame.c @@ -83,6 +83,8 @@ sentinel_frame_this_id (struct frame_info *next_frame, const struct frame_unwind sentinel_frame_unwinder = { + /* Should the sentinel frame be given a special type? */ + NORMAL_FRAME, sentinel_frame_this_id, sentinel_frame_prev_register }; diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c index 804b34a5de5..b61eb2364f3 100644 --- a/gdb/sh-tdep.c +++ b/gdb/sh-tdep.c @@ -1116,7 +1116,7 @@ sh_nofp_frame_init_saved_regs (struct frame_info *fi) that does not appear to be part of the prologue. But give up after 20 of them, since we're getting silly then. */ - pc = get_pc_function_start (get_frame_pc (fi)); + pc = get_frame_func (fi); if (!pc) { deprecated_update_frame_pc_hack (fi, 0); @@ -1456,7 +1456,7 @@ sh64_nofp_frame_init_saved_regs (struct frame_info *fi) that does not appear to be part of the prologue. But give up after 20 of them, since we're getting silly then. */ - pc = get_pc_function_start (get_frame_pc (fi)); + pc = get_frame_func (fi); if (!pc) { deprecated_update_frame_pc_hack (fi, 0); @@ -1657,7 +1657,7 @@ sh_fp_frame_init_saved_regs (struct frame_info *fi) that does not appear to be part of the prologue. But give up after 20 of them, since we're getting silly then. */ - pc = get_pc_function_start (get_frame_pc (fi)); + pc = get_frame_func (fi); if (!pc) { deprecated_update_frame_pc_hack (fi, 0); @@ -2414,7 +2414,7 @@ sh3e_sh4_extract_return_value (struct type *type, char *regbuf, char *valbuf) floatformat_to_doublest (&floatformat_ieee_double_big, (char *) regbuf + REGISTER_BYTE (return_register), &val); - store_floating (valbuf, len, val); + deprecated_store_floating (valbuf, len, val); } else if (len <= 4) { @@ -2467,7 +2467,7 @@ sh64_extract_return_value (struct type *type, char *regbuf, char *valbuf) else floatformat_to_doublest (&floatformat_ieee_double_big, (char *) regbuf + offset, &val); - store_floating (valbuf, len, val); + deprecated_store_floating (valbuf, len, val); } } else @@ -3403,7 +3403,7 @@ sh_sh4_register_convert_to_virtual (int regnum, struct type *type, { DOUBLEST val; floatformat_to_doublest (&floatformat_ieee_double_littlebyte_bigword, from, &val); - store_floating (to, TYPE_LENGTH (type), val); + deprecated_store_floating (to, TYPE_LENGTH (type), val); } else error ("sh_register_convert_to_virtual called with non DR register number"); @@ -3429,7 +3429,7 @@ sh_sh64_register_convert_to_virtual (int regnum, struct type *type, { DOUBLEST val; floatformat_to_doublest (&floatformat_ieee_double_littlebyte_bigword, from, &val); - store_floating(to, TYPE_LENGTH(type), val); + deprecated_store_floating(to, TYPE_LENGTH(type), val); } else error("sh_register_convert_to_virtual called with non DR register number"); @@ -3444,7 +3444,7 @@ sh_sh4_register_convert_to_raw (struct type *type, int regnum, if (regnum >= tdep->DR0_REGNUM && regnum <= tdep->DR_LAST_REGNUM) { - DOUBLEST val = extract_floating (from, TYPE_LENGTH(type)); + DOUBLEST val = deprecated_extract_floating (from, TYPE_LENGTH(type)); floatformat_from_doublest (&floatformat_ieee_double_littlebyte_bigword, &val, to); } else @@ -3469,7 +3469,7 @@ sh_sh64_register_convert_to_raw (struct type *type, int regnum, || (regnum >= tdep->DR0_C_REGNUM && regnum <= tdep->DR_LAST_C_REGNUM)) { - DOUBLEST val = extract_floating (from, TYPE_LENGTH(type)); + DOUBLEST val = deprecated_extract_floating (from, TYPE_LENGTH(type)); floatformat_from_doublest (&floatformat_ieee_double_littlebyte_bigword, &val, to); } else diff --git a/gdb/solib-irix.c b/gdb/solib-irix.c index 1cfa452b06d..26a776ff283 100644 --- a/gdb/solib-irix.c +++ b/gdb/solib-irix.c @@ -436,7 +436,7 @@ irix_solib_create_inferior_hook (void) out what we need to know about them. */ clear_proceed_status (); - stop_soon_quietly = 1; + stop_soon = STOP_QUIETLY; stop_signal = TARGET_SIGNAL_0; do { @@ -459,10 +459,10 @@ irix_solib_create_inferior_hook (void) But we are stopped in the startup code and we might not have symbols for the startup code, so heuristic_proc_start could be called and will put out an annoying warning. - Delaying the resetting of stop_soon_quietly until after symbol loading + Delaying the resetting of stop_soon until after symbol loading suppresses the warning. */ solib_add ((char *) 0, 0, (struct target_ops *) 0, auto_solib_add); - stop_soon_quietly = 0; + stop_soon = NO_STOP_QUIETLY; re_enable_breakpoints_in_shlibs (); } diff --git a/gdb/solib-osf.c b/gdb/solib-osf.c index 6f43a8f0e49..b5dca60750d 100644 --- a/gdb/solib-osf.c +++ b/gdb/solib-osf.c @@ -321,7 +321,7 @@ osf_solib_create_inferior_hook (void) out what we need to know about them. */ clear_proceed_status (); - stop_soon_quietly = 1; + stop_soon = STOP_QUIETLY; stop_signal = TARGET_SIGNAL_0; do { @@ -334,10 +334,10 @@ osf_solib_create_inferior_hook (void) But we are stopped in the runtime loader and we do not have symbols for the runtime loader. So heuristic_proc_start will be called and will put out an annoying warning. - Delaying the resetting of stop_soon_quietly until after symbol loading + Delaying the resetting of stop_soon until after symbol loading suppresses the warning. */ solib_add ((char *) 0, 0, (struct target_ops *) 0, auto_solib_add); - stop_soon_quietly = 0; + stop_soon = NO_STOP_QUIETLY; /* Enable breakpoints disabled (unnecessarily) by clear_solib(). */ re_enable_breakpoints_in_shlibs (); diff --git a/gdb/solib-sunos.c b/gdb/solib-sunos.c index 25682e02caa..4072fab5f4c 100644 --- a/gdb/solib-sunos.c +++ b/gdb/solib-sunos.c @@ -829,7 +829,7 @@ sunos_solib_create_inferior_hook (void) out what we need to know about them. */ clear_proceed_status (); - stop_soon_quietly = 1; + stop_soon = STOP_QUIETLY; stop_signal = TARGET_SIGNAL_0; do { @@ -837,7 +837,7 @@ sunos_solib_create_inferior_hook (void) wait_for_inferior (); } while (stop_signal != TARGET_SIGNAL_TRAP); - stop_soon_quietly = 0; + stop_soon = NO_STOP_QUIETLY; /* We are now either at the "mapping complete" breakpoint (or somewhere else, a condition we aren't prepared to deal with anyway), so adjust diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c index 78311086a3d..1b0a43e97d4 100644 --- a/gdb/solib-svr4.c +++ b/gdb/solib-svr4.c @@ -1290,7 +1290,7 @@ svr4_solib_create_inferior_hook (void) out what we need to know about them. */ clear_proceed_status (); - stop_soon_quietly = 1; + stop_soon = STOP_QUIETLY; stop_signal = TARGET_SIGNAL_0; do { @@ -1298,7 +1298,7 @@ svr4_solib_create_inferior_hook (void) wait_for_inferior (); } while (stop_signal != TARGET_SIGNAL_TRAP); - stop_soon_quietly = 0; + stop_soon = NO_STOP_QUIETLY; #endif /* defined(_SCO_DS) */ } diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c index 0e57aefd9d5..7a54b8ff120 100644 --- a/gdb/sparc-tdep.c +++ b/gdb/sparc-tdep.c @@ -41,6 +41,7 @@ #endif #include "gdbcore.h" +#include "gdb_assert.h" #include "symfile.h" /* for 'entry_point_address' */ @@ -436,16 +437,17 @@ sparc_frame_chain (struct frame_info *frame) about the chain value. If it really is zero, we detect it later in sparc_init_prev_frame. - Note: kevinb/2003-02-18: The constant 1 used to be returned - here, but, after some recent changes to frame_chain_valid(), - this value is no longer suitable for causing frame_chain_valid() - to "not worry about the chain value." The constant ~0 (i.e, - 0xfff...) causes the failing test in frame_chain_valid() to - succeed thus preserving the "not worry" property. I had considered - using something like ``get_frame_base (frame) + 1''. However, I think - a constant value is better, because when debugging this problem, - I knew that something funny was going on as soon as I saw the - constant 1 being used as the frame chain elsewhere in GDB. */ + Note: kevinb/2003-02-18: The constant 1 used to be returned here, + but, after some recent changes to legacy_frame_chain_valid(), + this value is no longer suitable for causing + legacy_frame_chain_valid() to "not worry about the chain value." + The constant ~0 (i.e, 0xfff...) causes the failing test in + legacy_frame_chain_valid() to succeed thus preserving the "not + worry" property. I had considered using something like + ``get_frame_base (frame) + 1''. However, I think a constant + value is better, because when debugging this problem, I knew that + something funny was going on as soon as I saw the constant 1 + being used as the frame chain elsewhere in GDB. */ return ~ (CORE_ADDR) 0; } @@ -1133,9 +1135,7 @@ sparc_frame_find_saved_regs (struct frame_info *fi, CORE_ADDR *saved_regs_addr) register int regnum; CORE_ADDR frame_addr = get_frame_base (fi); - if (!fi) - internal_error (__FILE__, __LINE__, - "Bad frame info struct in FRAME_FIND_SAVED_REGS"); + gdb_assert (fi != NULL); memset (saved_regs_addr, 0, NUM_REGS * sizeof (CORE_ADDR)); diff --git a/gdb/symm-nat.c b/gdb/symm-nat.c index 79caf5a938e..c4b2c9a12d6 100644 --- a/gdb/symm-nat.c +++ b/gdb/symm-nat.c @@ -1,902 +1,902 @@ -/* Sequent Symmetry host interface, for GDB when running under Unix. - - Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1999, - 2000, 2001, 2003 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* FIXME, some 387-specific items of use taken from i387-tdep.c -- ought to be - merged back in. */ - -#include "defs.h" -#include "frame.h" -#include "inferior.h" -#include "symtab.h" -#include "target.h" -#include "regcache.h" - -/* FIXME: What is the _INKERNEL define for? */ -#define _INKERNEL -#include <signal.h> -#undef _INKERNEL -#include "gdb_wait.h" -#include <sys/param.h> -#include <sys/user.h> -#include <sys/proc.h> -#include <sys/dir.h> -#include <sys/ioctl.h> -#include "gdb_stat.h" -#ifdef _SEQUENT_ -#include <sys/ptrace.h> -#else -/* Dynix has only machine/ptrace.h, which is already included by sys/user.h */ -/* Dynix has no mptrace call */ -#define mptrace ptrace -#endif -#include "gdbcore.h" -#include <fcntl.h> -#include <sgtty.h> -#define TERMINAL struct sgttyb - -#include "gdbcore.h" - -void -store_inferior_registers (int regno) -{ - struct pt_regset regs; - int i; - - /* FIXME: Fetching the registers is a kludge to initialize all elements - in the fpu and fpa status. This works for normal debugging, but - might cause problems when calling functions in the inferior. - At least fpu_control and fpa_pcr (probably more) should be added - to the registers array to solve this properly. */ - mptrace (XPT_RREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) & regs, 0); - - regs.pr_eax = *(int *) &deprecated_registers[REGISTER_BYTE (0)]; - regs.pr_ebx = *(int *) &deprecated_registers[REGISTER_BYTE (5)]; - regs.pr_ecx = *(int *) &deprecated_registers[REGISTER_BYTE (2)]; - regs.pr_edx = *(int *) &deprecated_registers[REGISTER_BYTE (1)]; - regs.pr_esi = *(int *) &deprecated_registers[REGISTER_BYTE (6)]; - regs.pr_edi = *(int *) &deprecated_registers[REGISTER_BYTE (7)]; - regs.pr_esp = *(int *) &deprecated_registers[REGISTER_BYTE (14)]; - regs.pr_ebp = *(int *) &deprecated_registers[REGISTER_BYTE (15)]; - regs.pr_eip = *(int *) &deprecated_registers[REGISTER_BYTE (16)]; - regs.pr_flags = *(int *) &deprecated_registers[REGISTER_BYTE (17)]; - for (i = 0; i < 31; i++) - { - regs.pr_fpa.fpa_regs[i] = - *(int *) &deprecated_registers[REGISTER_BYTE (FP1_REGNUM + i)]; - } - memcpy (regs.pr_fpu.fpu_stack[0], &deprecated_registers[REGISTER_BYTE (ST0_REGNUM)], 10); - memcpy (regs.pr_fpu.fpu_stack[1], &deprecated_registers[REGISTER_BYTE (ST1_REGNUM)], 10); - memcpy (regs.pr_fpu.fpu_stack[2], &deprecated_registers[REGISTER_BYTE (ST2_REGNUM)], 10); - memcpy (regs.pr_fpu.fpu_stack[3], &deprecated_registers[REGISTER_BYTE (ST3_REGNUM)], 10); - memcpy (regs.pr_fpu.fpu_stack[4], &deprecated_registers[REGISTER_BYTE (ST4_REGNUM)], 10); - memcpy (regs.pr_fpu.fpu_stack[5], &deprecated_registers[REGISTER_BYTE (ST5_REGNUM)], 10); - memcpy (regs.pr_fpu.fpu_stack[6], &deprecated_registers[REGISTER_BYTE (ST6_REGNUM)], 10); - memcpy (regs.pr_fpu.fpu_stack[7], &deprecated_registers[REGISTER_BYTE (ST7_REGNUM)], 10); - mptrace (XPT_WREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) & regs, 0); -} - -void -fetch_inferior_registers (int regno) -{ - int i; - struct pt_regset regs; - - deprecated_registers_fetched (); - - mptrace (XPT_RREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) & regs, 0); - *(int *) &deprecated_registers[REGISTER_BYTE (EAX_REGNUM)] = regs.pr_eax; - *(int *) &rdeprecated_egisters[REGISTER_BYTE (EBX_REGNUM)] = regs.pr_ebx; - *(int *) &deprecated_registers[REGISTER_BYTE (ECX_REGNUM)] = regs.pr_ecx; - *(int *) &deprecated_registers[REGISTER_BYTE (EDX_REGNUM)] = regs.pr_edx; - *(int *) &deprecated_registers[REGISTER_BYTE (ESI_REGNUM)] = regs.pr_esi; - *(int *) &deprecated_registers[REGISTER_BYTE (EDI_REGNUM)] = regs.pr_edi; - *(int *) &deprecated_registers[REGISTER_BYTE (EBP_REGNUM)] = regs.pr_ebp; - *(int *) &deprecated_registers[REGISTER_BYTE (ESP_REGNUM)] = regs.pr_esp; - *(int *) &deprecated_registers[REGISTER_BYTE (EIP_REGNUM)] = regs.pr_eip; - *(int *) &deprecated_registers[REGISTER_BYTE (EFLAGS_REGNUM)] = regs.pr_flags; - for (i = 0; i < FPA_NREGS; i++) - { - *(int *) &deprecated_registers[REGISTER_BYTE (FP1_REGNUM + i)] = - regs.pr_fpa.fpa_regs[i]; - } - memcpy (&deprecated_registers[REGISTER_BYTE (ST0_REGNUM)], regs.pr_fpu.fpu_stack[0], 10); - memcpy (&deprecated_registers[REGISTER_BYTE (ST1_REGNUM)], regs.pr_fpu.fpu_stack[1], 10); - memcpy (&deprecated_registers[REGISTER_BYTE (ST2_REGNUM)], regs.pr_fpu.fpu_stack[2], 10); - memcpy (&deprecated_registers[REGISTER_BYTE (ST3_REGNUM)], regs.pr_fpu.fpu_stack[3], 10); - memcpy (&deprecated_registers[REGISTER_BYTE (ST4_REGNUM)], regs.pr_fpu.fpu_stack[4], 10); - memcpy (&deprecated_registers[REGISTER_BYTE (ST5_REGNUM)], regs.pr_fpu.fpu_stack[5], 10); - memcpy (&deprecated_registers[REGISTER_BYTE (ST6_REGNUM)], regs.pr_fpu.fpu_stack[6], 10); - memcpy (&deprecated_registers[REGISTER_BYTE (ST7_REGNUM)], regs.pr_fpu.fpu_stack[7], 10); -} - -/* FIXME: This should be merged with i387-tdep.c as well. */ -static -print_fpu_status (struct pt_regset ep) -{ - int i; - int bothstatus; - int top; - int fpreg; - unsigned char *p; - - printf_unfiltered ("80387:"); - if (ep.pr_fpu.fpu_ip == 0) - { - printf_unfiltered (" not in use.\n"); - return; - } - else - { - printf_unfiltered ("\n"); - } - if (ep.pr_fpu.fpu_status != 0) - { - print_387_status_word (ep.pr_fpu.fpu_status); - } - print_387_control_word (ep.pr_fpu.fpu_control); - printf_unfiltered ("last exception: "); - printf_unfiltered ("opcode 0x%x; ", ep.pr_fpu.fpu_rsvd4); - printf_unfiltered ("pc 0x%x:0x%x; ", ep.pr_fpu.fpu_cs, ep.pr_fpu.fpu_ip); - printf_unfiltered ("operand 0x%x:0x%x\n", ep.pr_fpu.fpu_data_offset, ep.pr_fpu.fpu_op_sel); - - top = (ep.pr_fpu.fpu_status >> 11) & 7; - - printf_unfiltered ("regno tag msb lsb value\n"); - for (fpreg = 7; fpreg >= 0; fpreg--) - { - double val; - - printf_unfiltered ("%s %d: ", fpreg == top ? "=>" : " ", fpreg); - - switch ((ep.pr_fpu.fpu_tag >> (fpreg * 2)) & 3) - { - case 0: - printf_unfiltered ("valid "); - break; - case 1: - printf_unfiltered ("zero "); - break; - case 2: - printf_unfiltered ("trap "); - break; - case 3: - printf_unfiltered ("empty "); - break; - } - for (i = 9; i >= 0; i--) - printf_unfiltered ("%02x", ep.pr_fpu.fpu_stack[fpreg][i]); - - i387_to_double ((char *) ep.pr_fpu.fpu_stack[fpreg], (char *) &val); - printf_unfiltered (" %g\n", val); - } - if (ep.pr_fpu.fpu_rsvd1) - warning ("rsvd1 is 0x%x\n", ep.pr_fpu.fpu_rsvd1); - if (ep.pr_fpu.fpu_rsvd2) - warning ("rsvd2 is 0x%x\n", ep.pr_fpu.fpu_rsvd2); - if (ep.pr_fpu.fpu_rsvd3) - warning ("rsvd3 is 0x%x\n", ep.pr_fpu.fpu_rsvd3); - if (ep.pr_fpu.fpu_rsvd5) - warning ("rsvd5 is 0x%x\n", ep.pr_fpu.fpu_rsvd5); -} - - -print_1167_control_word (unsigned int pcr) -{ - int pcr_tmp; - - pcr_tmp = pcr & FPA_PCR_MODE; - printf_unfiltered ("\tMODE= %#x; RND= %#x ", pcr_tmp, pcr_tmp & 12); - switch (pcr_tmp & 12) - { - case 0: - printf_unfiltered ("RN (Nearest Value)"); - break; - case 1: - printf_unfiltered ("RZ (Zero)"); - break; - case 2: - printf_unfiltered ("RP (Positive Infinity)"); - break; - case 3: - printf_unfiltered ("RM (Negative Infinity)"); - break; - } - printf_unfiltered ("; IRND= %d ", pcr_tmp & 2); - if (0 == pcr_tmp & 2) - { - printf_unfiltered ("(same as RND)\n"); - } - else - { - printf_unfiltered ("(toward zero)\n"); - } - pcr_tmp = pcr & FPA_PCR_EM; - printf_unfiltered ("\tEM= %#x", pcr_tmp); - if (pcr_tmp & FPA_PCR_EM_DM) - printf_unfiltered (" DM"); - if (pcr_tmp & FPA_PCR_EM_UOM) - printf_unfiltered (" UOM"); - if (pcr_tmp & FPA_PCR_EM_PM) - printf_unfiltered (" PM"); - if (pcr_tmp & FPA_PCR_EM_UM) - printf_unfiltered (" UM"); - if (pcr_tmp & FPA_PCR_EM_OM) - printf_unfiltered (" OM"); - if (pcr_tmp & FPA_PCR_EM_ZM) - printf_unfiltered (" ZM"); - if (pcr_tmp & FPA_PCR_EM_IM) - printf_unfiltered (" IM"); - printf_unfiltered ("\n"); - pcr_tmp = FPA_PCR_CC; - printf_unfiltered ("\tCC= %#x", pcr_tmp); - if (pcr_tmp & FPA_PCR_20MHZ) - printf_unfiltered (" 20MHZ"); - if (pcr_tmp & FPA_PCR_CC_Z) - printf_unfiltered (" Z"); - if (pcr_tmp & FPA_PCR_CC_C2) - printf_unfiltered (" C2"); - - /* Dynix defines FPA_PCR_CC_C0 to 0x100 and ptx defines - FPA_PCR_CC_C1 to 0x100. Use whichever is defined and assume - the OS knows what it is doing. */ -#ifdef FPA_PCR_CC_C1 - if (pcr_tmp & FPA_PCR_CC_C1) - printf_unfiltered (" C1"); -#else - if (pcr_tmp & FPA_PCR_CC_C0) - printf_unfiltered (" C0"); -#endif - - switch (pcr_tmp) - { - case FPA_PCR_CC_Z: - printf_unfiltered (" (Equal)"); - break; -#ifdef FPA_PCR_CC_C1 - case FPA_PCR_CC_C1: -#else - case FPA_PCR_CC_C0: -#endif - printf_unfiltered (" (Less than)"); - break; - case 0: - printf_unfiltered (" (Greater than)"); - break; - case FPA_PCR_CC_Z | -#ifdef FPA_PCR_CC_C1 - FPA_PCR_CC_C1 -#else - FPA_PCR_CC_C0 -#endif - | FPA_PCR_CC_C2: - printf_unfiltered (" (Unordered)"); - break; - default: - printf_unfiltered (" (Undefined)"); - break; - } - printf_unfiltered ("\n"); - pcr_tmp = pcr & FPA_PCR_AE; - printf_unfiltered ("\tAE= %#x", pcr_tmp); - if (pcr_tmp & FPA_PCR_AE_DE) - printf_unfiltered (" DE"); - if (pcr_tmp & FPA_PCR_AE_UOE) - printf_unfiltered (" UOE"); - if (pcr_tmp & FPA_PCR_AE_PE) - printf_unfiltered (" PE"); - if (pcr_tmp & FPA_PCR_AE_UE) - printf_unfiltered (" UE"); - if (pcr_tmp & FPA_PCR_AE_OE) - printf_unfiltered (" OE"); - if (pcr_tmp & FPA_PCR_AE_ZE) - printf_unfiltered (" ZE"); - if (pcr_tmp & FPA_PCR_AE_EE) - printf_unfiltered (" EE"); - if (pcr_tmp & FPA_PCR_AE_IE) - printf_unfiltered (" IE"); - printf_unfiltered ("\n"); -} - -print_1167_regs (long regs[FPA_NREGS]) -{ - int i; - - union - { - double d; - long l[2]; - } - xd; - union - { - float f; - long l; - } - xf; - - - for (i = 0; i < FPA_NREGS; i++) - { - xf.l = regs[i]; - printf_unfiltered ("%%fp%d: raw= %#x, single= %f", i + 1, regs[i], xf.f); - if (!(i & 1)) - { - printf_unfiltered ("\n"); - } - else - { - xd.l[1] = regs[i]; - xd.l[0] = regs[i + 1]; - printf_unfiltered (", double= %f\n", xd.d); - } - } -} - -print_fpa_status (struct pt_regset ep) -{ - - printf_unfiltered ("WTL 1167:"); - if (ep.pr_fpa.fpa_pcr != 0) - { - printf_unfiltered ("\n"); - print_1167_control_word (ep.pr_fpa.fpa_pcr); - print_1167_regs (ep.pr_fpa.fpa_regs); - } - else - { - printf_unfiltered (" not in use.\n"); - } -} - -#if 0 /* disabled because it doesn't go through the target vector. */ -i386_float_info (void) -{ - char ubuf[UPAGES * NBPG]; - struct pt_regset regset; - - if (have_inferior_p ()) - { - PTRACE_READ_REGS (PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) & regset); - } - else - { - int corechan = bfd_cache_lookup (core_bfd); - if (lseek (corechan, 0, 0) < 0) - { - perror ("seek on core file"); - } - if (myread (corechan, ubuf, UPAGES * NBPG) < 0) - { - perror ("read on core file"); - } - /* only interested in the floating point registers */ - regset.pr_fpu = ((struct user *) ubuf)->u_fpusave; - regset.pr_fpa = ((struct user *) ubuf)->u_fpasave; - } - print_fpu_status (regset); - print_fpa_status (regset); -} -#endif - -static volatile int got_sigchld; - -/*ARGSUSED */ -/* This will eventually be more interesting. */ -void -sigchld_handler (int signo) -{ - got_sigchld++; -} - -/* - * Signals for which the default action does not cause the process - * to die. See <sys/signal.h> for where this came from (alas, we - * can't use those macros directly) - */ -#ifndef sigmask -#define sigmask(s) (1 << ((s) - 1)) -#endif -#define SIGNALS_DFL_SAFE sigmask(SIGSTOP) | sigmask(SIGTSTP) | \ - sigmask(SIGTTIN) | sigmask(SIGTTOU) | sigmask(SIGCHLD) | \ - sigmask(SIGCONT) | sigmask(SIGWINCH) | sigmask(SIGPWR) | \ - sigmask(SIGURG) | sigmask(SIGPOLL) - -#ifdef ATTACH_DETACH -/* - * Thanks to XPT_MPDEBUGGER, we have to mange child_wait(). - */ -ptid_t -child_wait (ptid_t ptid, struct target_waitstatus *status) -{ - int save_errno, rv, xvaloff, saoff, sa_hand; - struct pt_stop pt; - struct user u; - sigset_t set; - /* Host signal number for a signal which the inferior terminates with, or - 0 if it hasn't terminated due to a signal. */ - static int death_by_signal = 0; -#ifdef SVR4_SHARED_LIBS /* use this to distinguish ptx 2 vs ptx 4 */ - prstatus_t pstatus; -#endif - int pid = PIDGET (ptid); - - do - { - set_sigint_trap (); /* Causes SIGINT to be passed on to the - attached process. */ - save_errno = errno; - - got_sigchld = 0; - - sigemptyset (&set); - - while (got_sigchld == 0) - { - sigsuspend (&set); - } - - clear_sigint_trap (); - - rv = mptrace (XPT_STOPSTAT, 0, (char *) &pt, 0); - if (-1 == rv) - { - printf ("XPT_STOPSTAT: errno %d\n", errno); /* DEBUG */ - continue; - } - - pid = pt.ps_pid; - - if (pid != PIDGET (inferior_ptid)) - { - /* NOTE: the mystery fork in csh/tcsh needs to be ignored. - * We should not return new children for the initial run - * of a process until it has done the exec. - */ - /* inferior probably forked; send it on its way */ - rv = mptrace (XPT_UNDEBUG, pid, 0, 0); - if (-1 == rv) - { - printf ("child_wait: XPT_UNDEBUG: pid %d: %s\n", pid, - safe_strerror (errno)); - } - continue; - } - /* FIXME: Do we deal with fork notification correctly? */ - switch (pt.ps_reason) - { - case PTS_FORK: - /* multi proc: treat like PTS_EXEC */ - /* - * Pretend this didn't happen, since gdb isn't set up - * to deal with stops on fork. - */ - rv = ptrace (PT_CONTSIG, pid, 1, 0); - if (-1 == rv) - { - printf ("PTS_FORK: PT_CONTSIG: error %d\n", errno); - } - continue; - case PTS_EXEC: - /* - * Pretend this is a SIGTRAP. - */ - status->kind = TARGET_WAITKIND_STOPPED; - status->value.sig = TARGET_SIGNAL_TRAP; - break; - case PTS_EXIT: - /* - * Note: we stop before the exit actually occurs. Extract - * the exit code from the uarea. If we're stopped in the - * exit() system call, the exit code will be in - * u.u_ap[0]. An exit due to an uncaught signal will have - * something else in here, see the comment in the default: - * case, below. Finally,let the process exit. - */ - if (death_by_signal) - { - status->kind = TARGET_WAITKIND_SIGNALED; - status->value.sig = target_signal_from_host (death_by_signal); - death_by_signal = 0; - break; - } - xvaloff = (unsigned long) &u.u_ap[0] - (unsigned long) &u; - errno = 0; - rv = ptrace (PT_RUSER, pid, (char *) xvaloff, 0); - status->kind = TARGET_WAITKIND_EXITED; - status->value.integer = rv; - /* - * addr & data to mptrace() don't matter here, since - * the process is already dead. - */ - rv = mptrace (XPT_UNDEBUG, pid, 0, 0); - if (-1 == rv) - { - printf ("child_wait: PTS_EXIT: XPT_UNDEBUG: pid %d error %d\n", pid, - errno); - } - break; - case PTS_WATCHPT_HIT: - internal_error (__FILE__, __LINE__, - "PTS_WATCHPT_HIT\n"); - break; - default: - /* stopped by signal */ - status->kind = TARGET_WAITKIND_STOPPED; - status->value.sig = target_signal_from_host (pt.ps_reason); - death_by_signal = 0; - - if (0 == (SIGNALS_DFL_SAFE & sigmask (pt.ps_reason))) - { - break; - } - /* else default action of signal is to die */ -#ifdef SVR4_SHARED_LIBS - rv = ptrace (PT_GET_PRSTATUS, pid, (char *) &pstatus, 0); - if (-1 == rv) - error ("child_wait: signal %d PT_GET_PRSTATUS: %s\n", - pt.ps_reason, safe_strerror (errno)); - if (pstatus.pr_cursig != pt.ps_reason) - { - printf ("pstatus signal %d, pt signal %d\n", - pstatus.pr_cursig, pt.ps_reason); - } - sa_hand = (int) pstatus.pr_action.sa_handler; -#else - saoff = (unsigned long) &u.u_sa[0] - (unsigned long) &u; - saoff += sizeof (struct sigaction) * (pt.ps_reason - 1); - errno = 0; - sa_hand = ptrace (PT_RUSER, pid, (char *) saoff, 0); - if (errno) - error ("child_wait: signal %d: RUSER: %s\n", - pt.ps_reason, safe_strerror (errno)); -#endif - if ((int) SIG_DFL == sa_hand) - { - /* we will be dying */ - death_by_signal = pt.ps_reason; - } - break; - } - - } - while (pid != PIDGET (inferior_ptid)); /* Some other child died or stopped */ - - return pid_to_ptid (pid); -} -#else /* !ATTACH_DETACH */ -/* - * Simple child_wait() based on inftarg.c child_wait() for use until - * the MPDEBUGGER child_wait() works properly. This will go away when - * that is fixed. - */ -ptid_t -child_wait (ptid_t ptid, struct target_waitstatus *ourstatus) -{ - int save_errno; - int status; - int pid = PIDGET (ptid); - - do - { - pid = wait (&status); - save_errno = errno; - - if (pid == -1) - { - if (save_errno == EINTR) - continue; - fprintf (stderr, "Child process unexpectedly missing: %s.\n", - safe_strerror (save_errno)); - ourstatus->kind = TARGET_WAITKIND_SIGNALLED; - ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN; - return pid_to_ptid (-1); - } - } - while (pid != PIDGET (inferior_ptid)); /* Some other child died or stopped */ - store_waitstatus (ourstatus, status); - return pid_to_ptid (pid); -} -#endif /* ATTACH_DETACH */ - - - -/* This function simply calls ptrace with the given arguments. - It exists so that all calls to ptrace are isolated in this - machine-dependent file. */ -int -call_ptrace (int request, int pid, PTRACE_ARG3_TYPE addr, int data) -{ - return ptrace (request, pid, addr, data); -} - -int -call_mptrace (int request, int pid, PTRACE_ARG3_TYPE addr, int data) -{ - return mptrace (request, pid, addr, data); -} - -#if defined (DEBUG_PTRACE) -/* For the rest of the file, use an extra level of indirection */ -/* This lets us breakpoint usefully on call_ptrace. */ -#define ptrace call_ptrace -#define mptrace call_mptrace -#endif - -void -kill_inferior (void) -{ - if (ptid_equal (inferior_ptid, null_ptid)) - return; - - /* For MPDEBUGGER, don't use PT_KILL, since the child will stop - again with a PTS_EXIT. Just hit him with SIGKILL (so he stops) - and detach. */ - - kill (PIDGET (inferior_ptid), SIGKILL); -#ifdef ATTACH_DETACH - detach (SIGKILL); -#else /* ATTACH_DETACH */ - ptrace (PT_KILL, PIDGET (inferior_ptid), 0, 0); - wait ((int *) NULL); -#endif /* ATTACH_DETACH */ - target_mourn_inferior (); -} - -/* Resume execution of the inferior process. - If STEP is nonzero, single-step it. - If SIGNAL is nonzero, give it that signal. */ - -void -child_resume (ptid_t ptid, int step, enum target_signal signal) -{ - int pid = PIDGET (ptid); - - errno = 0; - - if (pid == -1) - pid = PIDGET (inferior_ptid); - - /* An address of (PTRACE_ARG3_TYPE)1 tells ptrace to continue from where - it was. (If GDB wanted it to start some other way, we have already - written a new PC value to the child.) - - If this system does not support PT_SSTEP, a higher level function will - have called single_step() to transmute the step request into a - continue request (by setting breakpoints on all possible successor - instructions), so we don't have to worry about that here. */ - - if (step) - ptrace (PT_SSTEP, pid, (PTRACE_ARG3_TYPE) 1, signal); - else - ptrace (PT_CONTSIG, pid, (PTRACE_ARG3_TYPE) 1, signal); - - if (errno) - perror_with_name ("ptrace"); -} - -#ifdef ATTACH_DETACH -/* Start debugging the process whose number is PID. */ -int -attach (int pid) -{ - sigset_t set; - int rv; - - rv = mptrace (XPT_DEBUG, pid, 0, 0); - if (-1 == rv) - { - error ("mptrace(XPT_DEBUG): %s", safe_strerror (errno)); - } - rv = mptrace (XPT_SIGNAL, pid, 0, SIGSTOP); - if (-1 == rv) - { - error ("mptrace(XPT_SIGNAL): %s", safe_strerror (errno)); - } - attach_flag = 1; - return pid; -} - -void -detach (int signo) -{ - int rv; - - rv = mptrace (XPT_UNDEBUG, PIDGET (inferior_ptid), 1, signo); - if (-1 == rv) - { - error ("mptrace(XPT_UNDEBUG): %s", safe_strerror (errno)); - } - attach_flag = 0; -} - -#endif /* ATTACH_DETACH */ - -/* Default the type of the ptrace transfer to int. */ -#ifndef PTRACE_XFER_TYPE -#define PTRACE_XFER_TYPE int -#endif - - -/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory - in the NEW_SUN_PTRACE case. - It ought to be straightforward. But it appears that writing did - not write the data that I specified. I cannot understand where - it got the data that it actually did write. */ - -/* Copy LEN bytes to or from inferior's memory starting at MEMADDR - to debugger memory starting at MYADDR. Copy to inferior if - WRITE is nonzero. TARGET is ignored. - - Returns the length copied, which is either the LEN argument or zero. - This xfer function does not do partial moves, since child_ops - doesn't allow memory operations to cross below us in the target stack - anyway. */ - -int -child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, - struct mem_attrib *attrib, - struct target_ops *target) -{ - register int i; - /* Round starting address down to longword boundary. */ - register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE); - /* Round ending address up; get number of longwords that makes. */ - register int count - = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1) - / sizeof (PTRACE_XFER_TYPE); - /* Allocate buffer of that many longwords. */ - /* FIXME (alloca): This code, cloned from infptrace.c, is unsafe - because it uses alloca to allocate a buffer of arbitrary size. - For very large xfers, this could crash GDB's stack. */ - register PTRACE_XFER_TYPE *buffer - = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE)); - - if (write) - { - /* Fill start and end extra bytes of buffer with existing memory data. */ - - if (addr != memaddr || len < (int) sizeof (PTRACE_XFER_TYPE)) - { - /* Need part of initial word -- fetch it. */ - buffer[0] = ptrace (PT_RTEXT, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) addr, - 0); - } - - if (count > 1) /* FIXME, avoid if even boundary */ - { - buffer[count - 1] - = ptrace (PT_RTEXT, PIDGET (inferior_ptid), - ((PTRACE_ARG3_TYPE) - (addr + (count - 1) * sizeof (PTRACE_XFER_TYPE))), - 0); - } - - /* Copy data to be written over corresponding part of buffer */ - - memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), - myaddr, - len); - - /* Write the entire buffer. */ - - for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE)) - { - errno = 0; - ptrace (PT_WDATA, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) addr, - buffer[i]); - if (errno) - { - /* Using the appropriate one (I or D) is necessary for - Gould NP1, at least. */ - errno = 0; - ptrace (PT_WTEXT, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) addr, - buffer[i]); - } - if (errno) - return 0; - } - } - else - { - /* Read all the longwords */ - for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE)) - { - errno = 0; - buffer[i] = ptrace (PT_RTEXT, PIDGET (inferior_ptid), - (PTRACE_ARG3_TYPE) addr, 0); - if (errno) - return 0; - QUIT; - } - - /* Copy appropriate bytes out of the buffer. */ - memcpy (myaddr, - (char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), - len); - } - return len; -} - - -void -_initialize_symm_nat (void) -{ -#ifdef ATTACH_DETACH -/* - * the MPDEBUGGER is necessary for process tree debugging and attach - * to work, but it alters the behavior of debugged processes, so other - * things (at least child_wait()) will have to change to accomodate - * that. - * - * Note that attach is not implemented in dynix 3, and not in ptx - * until version 2.1 of the OS. - */ - int rv; - sigset_t set; - struct sigaction sact; - - rv = mptrace (XPT_MPDEBUGGER, 0, 0, 0); - if (-1 == rv) - { - internal_error (__FILE__, __LINE__, - "_initialize_symm_nat(): mptrace(XPT_MPDEBUGGER): %s", - safe_strerror (errno)); - } - - /* - * Under MPDEBUGGER, we get SIGCLHD when a traced process does - * anything of interest. - */ - - /* - * Block SIGCHLD. We leave it blocked all the time, and then - * call sigsuspend() in child_wait() to wait for the child - * to do something. None of these ought to fail, but check anyway. - */ - sigemptyset (&set); - rv = sigaddset (&set, SIGCHLD); - if (-1 == rv) - { - internal_error (__FILE__, __LINE__, - "_initialize_symm_nat(): sigaddset(SIGCHLD): %s", - safe_strerror (errno)); - } - rv = sigprocmask (SIG_BLOCK, &set, (sigset_t *) NULL); - if (-1 == rv) - { - internal_error (__FILE__, __LINE__, - "_initialize_symm_nat(): sigprocmask(SIG_BLOCK): %s", - safe_strerror (errno)); - } - - sact.sa_handler = sigchld_handler; - sigemptyset (&sact.sa_mask); - sact.sa_flags = SA_NOCLDWAIT; /* keep the zombies away */ - rv = sigaction (SIGCHLD, &sact, (struct sigaction *) NULL); - if (-1 == rv) - { - internal_error (__FILE__, __LINE__, - "_initialize_symm_nat(): sigaction(SIGCHLD): %s", - safe_strerror (errno)); - } -#endif -} +// OBSOLETE /* Sequent Symmetry host interface, for GDB when running under Unix. +// OBSOLETE +// OBSOLETE Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1999, +// OBSOLETE 2000, 2001, 2003 Free Software Foundation, Inc. +// OBSOLETE +// OBSOLETE This file is part of GDB. +// OBSOLETE +// OBSOLETE This program is free software; you can redistribute it and/or modify +// OBSOLETE it under the terms of the GNU General Public License as published by +// OBSOLETE the Free Software Foundation; either version 2 of the License, or +// OBSOLETE (at your option) any later version. +// OBSOLETE +// OBSOLETE This program is distributed in the hope that it will be useful, +// OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of +// OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// OBSOLETE GNU General Public License for more details. +// OBSOLETE +// OBSOLETE You should have received a copy of the GNU General Public License +// OBSOLETE along with this program; if not, write to the Free Software +// OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, +// OBSOLETE Boston, MA 02111-1307, USA. */ +// OBSOLETE +// OBSOLETE /* FIXME, some 387-specific items of use taken from i387-tdep.c -- ought to be +// OBSOLETE merged back in. */ +// OBSOLETE +// OBSOLETE #include "defs.h" +// OBSOLETE #include "frame.h" +// OBSOLETE #include "inferior.h" +// OBSOLETE #include "symtab.h" +// OBSOLETE #include "target.h" +// OBSOLETE #include "regcache.h" +// OBSOLETE +// OBSOLETE /* FIXME: What is the _INKERNEL define for? */ +// OBSOLETE #define _INKERNEL +// OBSOLETE #include <signal.h> +// OBSOLETE #undef _INKERNEL +// OBSOLETE #include "gdb_wait.h" +// OBSOLETE #include <sys/param.h> +// OBSOLETE #include <sys/user.h> +// OBSOLETE #include <sys/proc.h> +// OBSOLETE #include <sys/dir.h> +// OBSOLETE #include <sys/ioctl.h> +// OBSOLETE #include "gdb_stat.h" +// OBSOLETE #ifdef _SEQUENT_ +// OBSOLETE #include <sys/ptrace.h> +// OBSOLETE #else +// OBSOLETE /* Dynix has only machine/ptrace.h, which is already included by sys/user.h */ +// OBSOLETE /* Dynix has no mptrace call */ +// OBSOLETE #define mptrace ptrace +// OBSOLETE #endif +// OBSOLETE #include "gdbcore.h" +// OBSOLETE #include <fcntl.h> +// OBSOLETE #include <sgtty.h> +// OBSOLETE #define TERMINAL struct sgttyb +// OBSOLETE +// OBSOLETE #include "gdbcore.h" +// OBSOLETE +// OBSOLETE void +// OBSOLETE store_inferior_registers (int regno) +// OBSOLETE { +// OBSOLETE struct pt_regset regs; +// OBSOLETE int i; +// OBSOLETE +// OBSOLETE /* FIXME: Fetching the registers is a kludge to initialize all elements +// OBSOLETE in the fpu and fpa status. This works for normal debugging, but +// OBSOLETE might cause problems when calling functions in the inferior. +// OBSOLETE At least fpu_control and fpa_pcr (probably more) should be added +// OBSOLETE to the registers array to solve this properly. */ +// OBSOLETE mptrace (XPT_RREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) & regs, 0); +// OBSOLETE +// OBSOLETE regs.pr_eax = *(int *) &deprecated_registers[REGISTER_BYTE (0)]; +// OBSOLETE regs.pr_ebx = *(int *) &deprecated_registers[REGISTER_BYTE (5)]; +// OBSOLETE regs.pr_ecx = *(int *) &deprecated_registers[REGISTER_BYTE (2)]; +// OBSOLETE regs.pr_edx = *(int *) &deprecated_registers[REGISTER_BYTE (1)]; +// OBSOLETE regs.pr_esi = *(int *) &deprecated_registers[REGISTER_BYTE (6)]; +// OBSOLETE regs.pr_edi = *(int *) &deprecated_registers[REGISTER_BYTE (7)]; +// OBSOLETE regs.pr_esp = *(int *) &deprecated_registers[REGISTER_BYTE (14)]; +// OBSOLETE regs.pr_ebp = *(int *) &deprecated_registers[REGISTER_BYTE (15)]; +// OBSOLETE regs.pr_eip = *(int *) &deprecated_registers[REGISTER_BYTE (16)]; +// OBSOLETE regs.pr_flags = *(int *) &deprecated_registers[REGISTER_BYTE (17)]; +// OBSOLETE for (i = 0; i < 31; i++) +// OBSOLETE { +// OBSOLETE regs.pr_fpa.fpa_regs[i] = +// OBSOLETE *(int *) &deprecated_registers[REGISTER_BYTE (FP1_REGNUM + i)]; +// OBSOLETE } +// OBSOLETE memcpy (regs.pr_fpu.fpu_stack[0], &deprecated_registers[REGISTER_BYTE (ST0_REGNUM)], 10); +// OBSOLETE memcpy (regs.pr_fpu.fpu_stack[1], &deprecated_registers[REGISTER_BYTE (ST1_REGNUM)], 10); +// OBSOLETE memcpy (regs.pr_fpu.fpu_stack[2], &deprecated_registers[REGISTER_BYTE (ST2_REGNUM)], 10); +// OBSOLETE memcpy (regs.pr_fpu.fpu_stack[3], &deprecated_registers[REGISTER_BYTE (ST3_REGNUM)], 10); +// OBSOLETE memcpy (regs.pr_fpu.fpu_stack[4], &deprecated_registers[REGISTER_BYTE (ST4_REGNUM)], 10); +// OBSOLETE memcpy (regs.pr_fpu.fpu_stack[5], &deprecated_registers[REGISTER_BYTE (ST5_REGNUM)], 10); +// OBSOLETE memcpy (regs.pr_fpu.fpu_stack[6], &deprecated_registers[REGISTER_BYTE (ST6_REGNUM)], 10); +// OBSOLETE memcpy (regs.pr_fpu.fpu_stack[7], &deprecated_registers[REGISTER_BYTE (ST7_REGNUM)], 10); +// OBSOLETE mptrace (XPT_WREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) & regs, 0); +// OBSOLETE } +// OBSOLETE +// OBSOLETE void +// OBSOLETE fetch_inferior_registers (int regno) +// OBSOLETE { +// OBSOLETE int i; +// OBSOLETE struct pt_regset regs; +// OBSOLETE +// OBSOLETE deprecated_registers_fetched (); +// OBSOLETE +// OBSOLETE mptrace (XPT_RREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) & regs, 0); +// OBSOLETE *(int *) &deprecated_registers[REGISTER_BYTE (EAX_REGNUM)] = regs.pr_eax; +// OBSOLETE *(int *) &rdeprecated_egisters[REGISTER_BYTE (EBX_REGNUM)] = regs.pr_ebx; +// OBSOLETE *(int *) &deprecated_registers[REGISTER_BYTE (ECX_REGNUM)] = regs.pr_ecx; +// OBSOLETE *(int *) &deprecated_registers[REGISTER_BYTE (EDX_REGNUM)] = regs.pr_edx; +// OBSOLETE *(int *) &deprecated_registers[REGISTER_BYTE (ESI_REGNUM)] = regs.pr_esi; +// OBSOLETE *(int *) &deprecated_registers[REGISTER_BYTE (EDI_REGNUM)] = regs.pr_edi; +// OBSOLETE *(int *) &deprecated_registers[REGISTER_BYTE (EBP_REGNUM)] = regs.pr_ebp; +// OBSOLETE *(int *) &deprecated_registers[REGISTER_BYTE (ESP_REGNUM)] = regs.pr_esp; +// OBSOLETE *(int *) &deprecated_registers[REGISTER_BYTE (EIP_REGNUM)] = regs.pr_eip; +// OBSOLETE *(int *) &deprecated_registers[REGISTER_BYTE (EFLAGS_REGNUM)] = regs.pr_flags; +// OBSOLETE for (i = 0; i < FPA_NREGS; i++) +// OBSOLETE { +// OBSOLETE *(int *) &deprecated_registers[REGISTER_BYTE (FP1_REGNUM + i)] = +// OBSOLETE regs.pr_fpa.fpa_regs[i]; +// OBSOLETE } +// OBSOLETE memcpy (&deprecated_registers[REGISTER_BYTE (ST0_REGNUM)], regs.pr_fpu.fpu_stack[0], 10); +// OBSOLETE memcpy (&deprecated_registers[REGISTER_BYTE (ST1_REGNUM)], regs.pr_fpu.fpu_stack[1], 10); +// OBSOLETE memcpy (&deprecated_registers[REGISTER_BYTE (ST2_REGNUM)], regs.pr_fpu.fpu_stack[2], 10); +// OBSOLETE memcpy (&deprecated_registers[REGISTER_BYTE (ST3_REGNUM)], regs.pr_fpu.fpu_stack[3], 10); +// OBSOLETE memcpy (&deprecated_registers[REGISTER_BYTE (ST4_REGNUM)], regs.pr_fpu.fpu_stack[4], 10); +// OBSOLETE memcpy (&deprecated_registers[REGISTER_BYTE (ST5_REGNUM)], regs.pr_fpu.fpu_stack[5], 10); +// OBSOLETE memcpy (&deprecated_registers[REGISTER_BYTE (ST6_REGNUM)], regs.pr_fpu.fpu_stack[6], 10); +// OBSOLETE memcpy (&deprecated_registers[REGISTER_BYTE (ST7_REGNUM)], regs.pr_fpu.fpu_stack[7], 10); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* FIXME: This should be merged with i387-tdep.c as well. */ +// OBSOLETE static +// OBSOLETE print_fpu_status (struct pt_regset ep) +// OBSOLETE { +// OBSOLETE int i; +// OBSOLETE int bothstatus; +// OBSOLETE int top; +// OBSOLETE int fpreg; +// OBSOLETE unsigned char *p; +// OBSOLETE +// OBSOLETE printf_unfiltered ("80387:"); +// OBSOLETE if (ep.pr_fpu.fpu_ip == 0) +// OBSOLETE { +// OBSOLETE printf_unfiltered (" not in use.\n"); +// OBSOLETE return; +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE printf_unfiltered ("\n"); +// OBSOLETE } +// OBSOLETE if (ep.pr_fpu.fpu_status != 0) +// OBSOLETE { +// OBSOLETE print_387_status_word (ep.pr_fpu.fpu_status); +// OBSOLETE } +// OBSOLETE print_387_control_word (ep.pr_fpu.fpu_control); +// OBSOLETE printf_unfiltered ("last exception: "); +// OBSOLETE printf_unfiltered ("opcode 0x%x; ", ep.pr_fpu.fpu_rsvd4); +// OBSOLETE printf_unfiltered ("pc 0x%x:0x%x; ", ep.pr_fpu.fpu_cs, ep.pr_fpu.fpu_ip); +// OBSOLETE printf_unfiltered ("operand 0x%x:0x%x\n", ep.pr_fpu.fpu_data_offset, ep.pr_fpu.fpu_op_sel); +// OBSOLETE +// OBSOLETE top = (ep.pr_fpu.fpu_status >> 11) & 7; +// OBSOLETE +// OBSOLETE printf_unfiltered ("regno tag msb lsb value\n"); +// OBSOLETE for (fpreg = 7; fpreg >= 0; fpreg--) +// OBSOLETE { +// OBSOLETE double val; +// OBSOLETE +// OBSOLETE printf_unfiltered ("%s %d: ", fpreg == top ? "=>" : " ", fpreg); +// OBSOLETE +// OBSOLETE switch ((ep.pr_fpu.fpu_tag >> (fpreg * 2)) & 3) +// OBSOLETE { +// OBSOLETE case 0: +// OBSOLETE printf_unfiltered ("valid "); +// OBSOLETE break; +// OBSOLETE case 1: +// OBSOLETE printf_unfiltered ("zero "); +// OBSOLETE break; +// OBSOLETE case 2: +// OBSOLETE printf_unfiltered ("trap "); +// OBSOLETE break; +// OBSOLETE case 3: +// OBSOLETE printf_unfiltered ("empty "); +// OBSOLETE break; +// OBSOLETE } +// OBSOLETE for (i = 9; i >= 0; i--) +// OBSOLETE printf_unfiltered ("%02x", ep.pr_fpu.fpu_stack[fpreg][i]); +// OBSOLETE +// OBSOLETE i387_to_double ((char *) ep.pr_fpu.fpu_stack[fpreg], (char *) &val); +// OBSOLETE printf_unfiltered (" %g\n", val); +// OBSOLETE } +// OBSOLETE if (ep.pr_fpu.fpu_rsvd1) +// OBSOLETE warning ("rsvd1 is 0x%x\n", ep.pr_fpu.fpu_rsvd1); +// OBSOLETE if (ep.pr_fpu.fpu_rsvd2) +// OBSOLETE warning ("rsvd2 is 0x%x\n", ep.pr_fpu.fpu_rsvd2); +// OBSOLETE if (ep.pr_fpu.fpu_rsvd3) +// OBSOLETE warning ("rsvd3 is 0x%x\n", ep.pr_fpu.fpu_rsvd3); +// OBSOLETE if (ep.pr_fpu.fpu_rsvd5) +// OBSOLETE warning ("rsvd5 is 0x%x\n", ep.pr_fpu.fpu_rsvd5); +// OBSOLETE } +// OBSOLETE +// OBSOLETE +// OBSOLETE print_1167_control_word (unsigned int pcr) +// OBSOLETE { +// OBSOLETE int pcr_tmp; +// OBSOLETE +// OBSOLETE pcr_tmp = pcr & FPA_PCR_MODE; +// OBSOLETE printf_unfiltered ("\tMODE= %#x; RND= %#x ", pcr_tmp, pcr_tmp & 12); +// OBSOLETE switch (pcr_tmp & 12) +// OBSOLETE { +// OBSOLETE case 0: +// OBSOLETE printf_unfiltered ("RN (Nearest Value)"); +// OBSOLETE break; +// OBSOLETE case 1: +// OBSOLETE printf_unfiltered ("RZ (Zero)"); +// OBSOLETE break; +// OBSOLETE case 2: +// OBSOLETE printf_unfiltered ("RP (Positive Infinity)"); +// OBSOLETE break; +// OBSOLETE case 3: +// OBSOLETE printf_unfiltered ("RM (Negative Infinity)"); +// OBSOLETE break; +// OBSOLETE } +// OBSOLETE printf_unfiltered ("; IRND= %d ", pcr_tmp & 2); +// OBSOLETE if (0 == pcr_tmp & 2) +// OBSOLETE { +// OBSOLETE printf_unfiltered ("(same as RND)\n"); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE printf_unfiltered ("(toward zero)\n"); +// OBSOLETE } +// OBSOLETE pcr_tmp = pcr & FPA_PCR_EM; +// OBSOLETE printf_unfiltered ("\tEM= %#x", pcr_tmp); +// OBSOLETE if (pcr_tmp & FPA_PCR_EM_DM) +// OBSOLETE printf_unfiltered (" DM"); +// OBSOLETE if (pcr_tmp & FPA_PCR_EM_UOM) +// OBSOLETE printf_unfiltered (" UOM"); +// OBSOLETE if (pcr_tmp & FPA_PCR_EM_PM) +// OBSOLETE printf_unfiltered (" PM"); +// OBSOLETE if (pcr_tmp & FPA_PCR_EM_UM) +// OBSOLETE printf_unfiltered (" UM"); +// OBSOLETE if (pcr_tmp & FPA_PCR_EM_OM) +// OBSOLETE printf_unfiltered (" OM"); +// OBSOLETE if (pcr_tmp & FPA_PCR_EM_ZM) +// OBSOLETE printf_unfiltered (" ZM"); +// OBSOLETE if (pcr_tmp & FPA_PCR_EM_IM) +// OBSOLETE printf_unfiltered (" IM"); +// OBSOLETE printf_unfiltered ("\n"); +// OBSOLETE pcr_tmp = FPA_PCR_CC; +// OBSOLETE printf_unfiltered ("\tCC= %#x", pcr_tmp); +// OBSOLETE if (pcr_tmp & FPA_PCR_20MHZ) +// OBSOLETE printf_unfiltered (" 20MHZ"); +// OBSOLETE if (pcr_tmp & FPA_PCR_CC_Z) +// OBSOLETE printf_unfiltered (" Z"); +// OBSOLETE if (pcr_tmp & FPA_PCR_CC_C2) +// OBSOLETE printf_unfiltered (" C2"); +// OBSOLETE +// OBSOLETE /* Dynix defines FPA_PCR_CC_C0 to 0x100 and ptx defines +// OBSOLETE FPA_PCR_CC_C1 to 0x100. Use whichever is defined and assume +// OBSOLETE the OS knows what it is doing. */ +// OBSOLETE #ifdef FPA_PCR_CC_C1 +// OBSOLETE if (pcr_tmp & FPA_PCR_CC_C1) +// OBSOLETE printf_unfiltered (" C1"); +// OBSOLETE #else +// OBSOLETE if (pcr_tmp & FPA_PCR_CC_C0) +// OBSOLETE printf_unfiltered (" C0"); +// OBSOLETE #endif +// OBSOLETE +// OBSOLETE switch (pcr_tmp) +// OBSOLETE { +// OBSOLETE case FPA_PCR_CC_Z: +// OBSOLETE printf_unfiltered (" (Equal)"); +// OBSOLETE break; +// OBSOLETE #ifdef FPA_PCR_CC_C1 +// OBSOLETE case FPA_PCR_CC_C1: +// OBSOLETE #else +// OBSOLETE case FPA_PCR_CC_C0: +// OBSOLETE #endif +// OBSOLETE printf_unfiltered (" (Less than)"); +// OBSOLETE break; +// OBSOLETE case 0: +// OBSOLETE printf_unfiltered (" (Greater than)"); +// OBSOLETE break; +// OBSOLETE case FPA_PCR_CC_Z | +// OBSOLETE #ifdef FPA_PCR_CC_C1 +// OBSOLETE FPA_PCR_CC_C1 +// OBSOLETE #else +// OBSOLETE FPA_PCR_CC_C0 +// OBSOLETE #endif +// OBSOLETE | FPA_PCR_CC_C2: +// OBSOLETE printf_unfiltered (" (Unordered)"); +// OBSOLETE break; +// OBSOLETE default: +// OBSOLETE printf_unfiltered (" (Undefined)"); +// OBSOLETE break; +// OBSOLETE } +// OBSOLETE printf_unfiltered ("\n"); +// OBSOLETE pcr_tmp = pcr & FPA_PCR_AE; +// OBSOLETE printf_unfiltered ("\tAE= %#x", pcr_tmp); +// OBSOLETE if (pcr_tmp & FPA_PCR_AE_DE) +// OBSOLETE printf_unfiltered (" DE"); +// OBSOLETE if (pcr_tmp & FPA_PCR_AE_UOE) +// OBSOLETE printf_unfiltered (" UOE"); +// OBSOLETE if (pcr_tmp & FPA_PCR_AE_PE) +// OBSOLETE printf_unfiltered (" PE"); +// OBSOLETE if (pcr_tmp & FPA_PCR_AE_UE) +// OBSOLETE printf_unfiltered (" UE"); +// OBSOLETE if (pcr_tmp & FPA_PCR_AE_OE) +// OBSOLETE printf_unfiltered (" OE"); +// OBSOLETE if (pcr_tmp & FPA_PCR_AE_ZE) +// OBSOLETE printf_unfiltered (" ZE"); +// OBSOLETE if (pcr_tmp & FPA_PCR_AE_EE) +// OBSOLETE printf_unfiltered (" EE"); +// OBSOLETE if (pcr_tmp & FPA_PCR_AE_IE) +// OBSOLETE printf_unfiltered (" IE"); +// OBSOLETE printf_unfiltered ("\n"); +// OBSOLETE } +// OBSOLETE +// OBSOLETE print_1167_regs (long regs[FPA_NREGS]) +// OBSOLETE { +// OBSOLETE int i; +// OBSOLETE +// OBSOLETE union +// OBSOLETE { +// OBSOLETE double d; +// OBSOLETE long l[2]; +// OBSOLETE } +// OBSOLETE xd; +// OBSOLETE union +// OBSOLETE { +// OBSOLETE float f; +// OBSOLETE long l; +// OBSOLETE } +// OBSOLETE xf; +// OBSOLETE +// OBSOLETE +// OBSOLETE for (i = 0; i < FPA_NREGS; i++) +// OBSOLETE { +// OBSOLETE xf.l = regs[i]; +// OBSOLETE printf_unfiltered ("%%fp%d: raw= %#x, single= %f", i + 1, regs[i], xf.f); +// OBSOLETE if (!(i & 1)) +// OBSOLETE { +// OBSOLETE printf_unfiltered ("\n"); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE xd.l[1] = regs[i]; +// OBSOLETE xd.l[0] = regs[i + 1]; +// OBSOLETE printf_unfiltered (", double= %f\n", xd.d); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE print_fpa_status (struct pt_regset ep) +// OBSOLETE { +// OBSOLETE +// OBSOLETE printf_unfiltered ("WTL 1167:"); +// OBSOLETE if (ep.pr_fpa.fpa_pcr != 0) +// OBSOLETE { +// OBSOLETE printf_unfiltered ("\n"); +// OBSOLETE print_1167_control_word (ep.pr_fpa.fpa_pcr); +// OBSOLETE print_1167_regs (ep.pr_fpa.fpa_regs); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE printf_unfiltered (" not in use.\n"); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE #if 0 /* disabled because it doesn't go through the target vector. */ +// OBSOLETE i386_float_info (void) +// OBSOLETE { +// OBSOLETE char ubuf[UPAGES * NBPG]; +// OBSOLETE struct pt_regset regset; +// OBSOLETE +// OBSOLETE if (have_inferior_p ()) +// OBSOLETE { +// OBSOLETE PTRACE_READ_REGS (PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) & regset); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE int corechan = bfd_cache_lookup (core_bfd); +// OBSOLETE if (lseek (corechan, 0, 0) < 0) +// OBSOLETE { +// OBSOLETE perror ("seek on core file"); +// OBSOLETE } +// OBSOLETE if (myread (corechan, ubuf, UPAGES * NBPG) < 0) +// OBSOLETE { +// OBSOLETE perror ("read on core file"); +// OBSOLETE } +// OBSOLETE /* only interested in the floating point registers */ +// OBSOLETE regset.pr_fpu = ((struct user *) ubuf)->u_fpusave; +// OBSOLETE regset.pr_fpa = ((struct user *) ubuf)->u_fpasave; +// OBSOLETE } +// OBSOLETE print_fpu_status (regset); +// OBSOLETE print_fpa_status (regset); +// OBSOLETE } +// OBSOLETE #endif +// OBSOLETE +// OBSOLETE static volatile int got_sigchld; +// OBSOLETE +// OBSOLETE /*ARGSUSED */ +// OBSOLETE /* This will eventually be more interesting. */ +// OBSOLETE void +// OBSOLETE sigchld_handler (int signo) +// OBSOLETE { +// OBSOLETE got_sigchld++; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* +// OBSOLETE * Signals for which the default action does not cause the process +// OBSOLETE * to die. See <sys/signal.h> for where this came from (alas, we +// OBSOLETE * can't use those macros directly) +// OBSOLETE */ +// OBSOLETE #ifndef sigmask +// OBSOLETE #define sigmask(s) (1 << ((s) - 1)) +// OBSOLETE #endif +// OBSOLETE #define SIGNALS_DFL_SAFE sigmask(SIGSTOP) | sigmask(SIGTSTP) | \ +// OBSOLETE sigmask(SIGTTIN) | sigmask(SIGTTOU) | sigmask(SIGCHLD) | \ +// OBSOLETE sigmask(SIGCONT) | sigmask(SIGWINCH) | sigmask(SIGPWR) | \ +// OBSOLETE sigmask(SIGURG) | sigmask(SIGPOLL) +// OBSOLETE +// OBSOLETE #ifdef ATTACH_DETACH +// OBSOLETE /* +// OBSOLETE * Thanks to XPT_MPDEBUGGER, we have to mange child_wait(). +// OBSOLETE */ +// OBSOLETE ptid_t +// OBSOLETE child_wait (ptid_t ptid, struct target_waitstatus *status) +// OBSOLETE { +// OBSOLETE int save_errno, rv, xvaloff, saoff, sa_hand; +// OBSOLETE struct pt_stop pt; +// OBSOLETE struct user u; +// OBSOLETE sigset_t set; +// OBSOLETE /* Host signal number for a signal which the inferior terminates with, or +// OBSOLETE 0 if it hasn't terminated due to a signal. */ +// OBSOLETE static int death_by_signal = 0; +// OBSOLETE #ifdef SVR4_SHARED_LIBS /* use this to distinguish ptx 2 vs ptx 4 */ +// OBSOLETE prstatus_t pstatus; +// OBSOLETE #endif +// OBSOLETE int pid = PIDGET (ptid); +// OBSOLETE +// OBSOLETE do +// OBSOLETE { +// OBSOLETE set_sigint_trap (); /* Causes SIGINT to be passed on to the +// OBSOLETE attached process. */ +// OBSOLETE save_errno = errno; +// OBSOLETE +// OBSOLETE got_sigchld = 0; +// OBSOLETE +// OBSOLETE sigemptyset (&set); +// OBSOLETE +// OBSOLETE while (got_sigchld == 0) +// OBSOLETE { +// OBSOLETE sigsuspend (&set); +// OBSOLETE } +// OBSOLETE +// OBSOLETE clear_sigint_trap (); +// OBSOLETE +// OBSOLETE rv = mptrace (XPT_STOPSTAT, 0, (char *) &pt, 0); +// OBSOLETE if (-1 == rv) +// OBSOLETE { +// OBSOLETE printf ("XPT_STOPSTAT: errno %d\n", errno); /* DEBUG */ +// OBSOLETE continue; +// OBSOLETE } +// OBSOLETE +// OBSOLETE pid = pt.ps_pid; +// OBSOLETE +// OBSOLETE if (pid != PIDGET (inferior_ptid)) +// OBSOLETE { +// OBSOLETE /* NOTE: the mystery fork in csh/tcsh needs to be ignored. +// OBSOLETE * We should not return new children for the initial run +// OBSOLETE * of a process until it has done the exec. +// OBSOLETE */ +// OBSOLETE /* inferior probably forked; send it on its way */ +// OBSOLETE rv = mptrace (XPT_UNDEBUG, pid, 0, 0); +// OBSOLETE if (-1 == rv) +// OBSOLETE { +// OBSOLETE printf ("child_wait: XPT_UNDEBUG: pid %d: %s\n", pid, +// OBSOLETE safe_strerror (errno)); +// OBSOLETE } +// OBSOLETE continue; +// OBSOLETE } +// OBSOLETE /* FIXME: Do we deal with fork notification correctly? */ +// OBSOLETE switch (pt.ps_reason) +// OBSOLETE { +// OBSOLETE case PTS_FORK: +// OBSOLETE /* multi proc: treat like PTS_EXEC */ +// OBSOLETE /* +// OBSOLETE * Pretend this didn't happen, since gdb isn't set up +// OBSOLETE * to deal with stops on fork. +// OBSOLETE */ +// OBSOLETE rv = ptrace (PT_CONTSIG, pid, 1, 0); +// OBSOLETE if (-1 == rv) +// OBSOLETE { +// OBSOLETE printf ("PTS_FORK: PT_CONTSIG: error %d\n", errno); +// OBSOLETE } +// OBSOLETE continue; +// OBSOLETE case PTS_EXEC: +// OBSOLETE /* +// OBSOLETE * Pretend this is a SIGTRAP. +// OBSOLETE */ +// OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; +// OBSOLETE status->value.sig = TARGET_SIGNAL_TRAP; +// OBSOLETE break; +// OBSOLETE case PTS_EXIT: +// OBSOLETE /* +// OBSOLETE * Note: we stop before the exit actually occurs. Extract +// OBSOLETE * the exit code from the uarea. If we're stopped in the +// OBSOLETE * exit() system call, the exit code will be in +// OBSOLETE * u.u_ap[0]. An exit due to an uncaught signal will have +// OBSOLETE * something else in here, see the comment in the default: +// OBSOLETE * case, below. Finally,let the process exit. +// OBSOLETE */ +// OBSOLETE if (death_by_signal) +// OBSOLETE { +// OBSOLETE status->kind = TARGET_WAITKIND_SIGNALED; +// OBSOLETE status->value.sig = target_signal_from_host (death_by_signal); +// OBSOLETE death_by_signal = 0; +// OBSOLETE break; +// OBSOLETE } +// OBSOLETE xvaloff = (unsigned long) &u.u_ap[0] - (unsigned long) &u; +// OBSOLETE errno = 0; +// OBSOLETE rv = ptrace (PT_RUSER, pid, (char *) xvaloff, 0); +// OBSOLETE status->kind = TARGET_WAITKIND_EXITED; +// OBSOLETE status->value.integer = rv; +// OBSOLETE /* +// OBSOLETE * addr & data to mptrace() don't matter here, since +// OBSOLETE * the process is already dead. +// OBSOLETE */ +// OBSOLETE rv = mptrace (XPT_UNDEBUG, pid, 0, 0); +// OBSOLETE if (-1 == rv) +// OBSOLETE { +// OBSOLETE printf ("child_wait: PTS_EXIT: XPT_UNDEBUG: pid %d error %d\n", pid, +// OBSOLETE errno); +// OBSOLETE } +// OBSOLETE break; +// OBSOLETE case PTS_WATCHPT_HIT: +// OBSOLETE internal_error (__FILE__, __LINE__, +// OBSOLETE "PTS_WATCHPT_HIT\n"); +// OBSOLETE break; +// OBSOLETE default: +// OBSOLETE /* stopped by signal */ +// OBSOLETE status->kind = TARGET_WAITKIND_STOPPED; +// OBSOLETE status->value.sig = target_signal_from_host (pt.ps_reason); +// OBSOLETE death_by_signal = 0; +// OBSOLETE +// OBSOLETE if (0 == (SIGNALS_DFL_SAFE & sigmask (pt.ps_reason))) +// OBSOLETE { +// OBSOLETE break; +// OBSOLETE } +// OBSOLETE /* else default action of signal is to die */ +// OBSOLETE #ifdef SVR4_SHARED_LIBS +// OBSOLETE rv = ptrace (PT_GET_PRSTATUS, pid, (char *) &pstatus, 0); +// OBSOLETE if (-1 == rv) +// OBSOLETE error ("child_wait: signal %d PT_GET_PRSTATUS: %s\n", +// OBSOLETE pt.ps_reason, safe_strerror (errno)); +// OBSOLETE if (pstatus.pr_cursig != pt.ps_reason) +// OBSOLETE { +// OBSOLETE printf ("pstatus signal %d, pt signal %d\n", +// OBSOLETE pstatus.pr_cursig, pt.ps_reason); +// OBSOLETE } +// OBSOLETE sa_hand = (int) pstatus.pr_action.sa_handler; +// OBSOLETE #else +// OBSOLETE saoff = (unsigned long) &u.u_sa[0] - (unsigned long) &u; +// OBSOLETE saoff += sizeof (struct sigaction) * (pt.ps_reason - 1); +// OBSOLETE errno = 0; +// OBSOLETE sa_hand = ptrace (PT_RUSER, pid, (char *) saoff, 0); +// OBSOLETE if (errno) +// OBSOLETE error ("child_wait: signal %d: RUSER: %s\n", +// OBSOLETE pt.ps_reason, safe_strerror (errno)); +// OBSOLETE #endif +// OBSOLETE if ((int) SIG_DFL == sa_hand) +// OBSOLETE { +// OBSOLETE /* we will be dying */ +// OBSOLETE death_by_signal = pt.ps_reason; +// OBSOLETE } +// OBSOLETE break; +// OBSOLETE } +// OBSOLETE +// OBSOLETE } +// OBSOLETE while (pid != PIDGET (inferior_ptid)); /* Some other child died or stopped */ +// OBSOLETE +// OBSOLETE return pid_to_ptid (pid); +// OBSOLETE } +// OBSOLETE #else /* !ATTACH_DETACH */ +// OBSOLETE /* +// OBSOLETE * Simple child_wait() based on inftarg.c child_wait() for use until +// OBSOLETE * the MPDEBUGGER child_wait() works properly. This will go away when +// OBSOLETE * that is fixed. +// OBSOLETE */ +// OBSOLETE ptid_t +// OBSOLETE child_wait (ptid_t ptid, struct target_waitstatus *ourstatus) +// OBSOLETE { +// OBSOLETE int save_errno; +// OBSOLETE int status; +// OBSOLETE int pid = PIDGET (ptid); +// OBSOLETE +// OBSOLETE do +// OBSOLETE { +// OBSOLETE pid = wait (&status); +// OBSOLETE save_errno = errno; +// OBSOLETE +// OBSOLETE if (pid == -1) +// OBSOLETE { +// OBSOLETE if (save_errno == EINTR) +// OBSOLETE continue; +// OBSOLETE fprintf (stderr, "Child process unexpectedly missing: %s.\n", +// OBSOLETE safe_strerror (save_errno)); +// OBSOLETE ourstatus->kind = TARGET_WAITKIND_SIGNALLED; +// OBSOLETE ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN; +// OBSOLETE return pid_to_ptid (-1); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE while (pid != PIDGET (inferior_ptid)); /* Some other child died or stopped */ +// OBSOLETE store_waitstatus (ourstatus, status); +// OBSOLETE return pid_to_ptid (pid); +// OBSOLETE } +// OBSOLETE #endif /* ATTACH_DETACH */ +// OBSOLETE +// OBSOLETE +// OBSOLETE +// OBSOLETE /* This function simply calls ptrace with the given arguments. +// OBSOLETE It exists so that all calls to ptrace are isolated in this +// OBSOLETE machine-dependent file. */ +// OBSOLETE int +// OBSOLETE call_ptrace (int request, int pid, PTRACE_ARG3_TYPE addr, int data) +// OBSOLETE { +// OBSOLETE return ptrace (request, pid, addr, data); +// OBSOLETE } +// OBSOLETE +// OBSOLETE int +// OBSOLETE call_mptrace (int request, int pid, PTRACE_ARG3_TYPE addr, int data) +// OBSOLETE { +// OBSOLETE return mptrace (request, pid, addr, data); +// OBSOLETE } +// OBSOLETE +// OBSOLETE #if defined (DEBUG_PTRACE) +// OBSOLETE /* For the rest of the file, use an extra level of indirection */ +// OBSOLETE /* This lets us breakpoint usefully on call_ptrace. */ +// OBSOLETE #define ptrace call_ptrace +// OBSOLETE #define mptrace call_mptrace +// OBSOLETE #endif +// OBSOLETE +// OBSOLETE void +// OBSOLETE kill_inferior (void) +// OBSOLETE { +// OBSOLETE if (ptid_equal (inferior_ptid, null_ptid)) +// OBSOLETE return; +// OBSOLETE +// OBSOLETE /* For MPDEBUGGER, don't use PT_KILL, since the child will stop +// OBSOLETE again with a PTS_EXIT. Just hit him with SIGKILL (so he stops) +// OBSOLETE and detach. */ +// OBSOLETE +// OBSOLETE kill (PIDGET (inferior_ptid), SIGKILL); +// OBSOLETE #ifdef ATTACH_DETACH +// OBSOLETE detach (SIGKILL); +// OBSOLETE #else /* ATTACH_DETACH */ +// OBSOLETE ptrace (PT_KILL, PIDGET (inferior_ptid), 0, 0); +// OBSOLETE wait ((int *) NULL); +// OBSOLETE #endif /* ATTACH_DETACH */ +// OBSOLETE target_mourn_inferior (); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Resume execution of the inferior process. +// OBSOLETE If STEP is nonzero, single-step it. +// OBSOLETE If SIGNAL is nonzero, give it that signal. */ +// OBSOLETE +// OBSOLETE void +// OBSOLETE child_resume (ptid_t ptid, int step, enum target_signal signal) +// OBSOLETE { +// OBSOLETE int pid = PIDGET (ptid); +// OBSOLETE +// OBSOLETE errno = 0; +// OBSOLETE +// OBSOLETE if (pid == -1) +// OBSOLETE pid = PIDGET (inferior_ptid); +// OBSOLETE +// OBSOLETE /* An address of (PTRACE_ARG3_TYPE)1 tells ptrace to continue from where +// OBSOLETE it was. (If GDB wanted it to start some other way, we have already +// OBSOLETE written a new PC value to the child.) +// OBSOLETE +// OBSOLETE If this system does not support PT_SSTEP, a higher level function will +// OBSOLETE have called single_step() to transmute the step request into a +// OBSOLETE continue request (by setting breakpoints on all possible successor +// OBSOLETE instructions), so we don't have to worry about that here. */ +// OBSOLETE +// OBSOLETE if (step) +// OBSOLETE ptrace (PT_SSTEP, pid, (PTRACE_ARG3_TYPE) 1, signal); +// OBSOLETE else +// OBSOLETE ptrace (PT_CONTSIG, pid, (PTRACE_ARG3_TYPE) 1, signal); +// OBSOLETE +// OBSOLETE if (errno) +// OBSOLETE perror_with_name ("ptrace"); +// OBSOLETE } +// OBSOLETE +// OBSOLETE #ifdef ATTACH_DETACH +// OBSOLETE /* Start debugging the process whose number is PID. */ +// OBSOLETE int +// OBSOLETE attach (int pid) +// OBSOLETE { +// OBSOLETE sigset_t set; +// OBSOLETE int rv; +// OBSOLETE +// OBSOLETE rv = mptrace (XPT_DEBUG, pid, 0, 0); +// OBSOLETE if (-1 == rv) +// OBSOLETE { +// OBSOLETE error ("mptrace(XPT_DEBUG): %s", safe_strerror (errno)); +// OBSOLETE } +// OBSOLETE rv = mptrace (XPT_SIGNAL, pid, 0, SIGSTOP); +// OBSOLETE if (-1 == rv) +// OBSOLETE { +// OBSOLETE error ("mptrace(XPT_SIGNAL): %s", safe_strerror (errno)); +// OBSOLETE } +// OBSOLETE attach_flag = 1; +// OBSOLETE return pid; +// OBSOLETE } +// OBSOLETE +// OBSOLETE void +// OBSOLETE detach (int signo) +// OBSOLETE { +// OBSOLETE int rv; +// OBSOLETE +// OBSOLETE rv = mptrace (XPT_UNDEBUG, PIDGET (inferior_ptid), 1, signo); +// OBSOLETE if (-1 == rv) +// OBSOLETE { +// OBSOLETE error ("mptrace(XPT_UNDEBUG): %s", safe_strerror (errno)); +// OBSOLETE } +// OBSOLETE attach_flag = 0; +// OBSOLETE } +// OBSOLETE +// OBSOLETE #endif /* ATTACH_DETACH */ +// OBSOLETE +// OBSOLETE /* Default the type of the ptrace transfer to int. */ +// OBSOLETE #ifndef PTRACE_XFER_TYPE +// OBSOLETE #define PTRACE_XFER_TYPE int +// OBSOLETE #endif +// OBSOLETE +// OBSOLETE +// OBSOLETE /* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory +// OBSOLETE in the NEW_SUN_PTRACE case. +// OBSOLETE It ought to be straightforward. But it appears that writing did +// OBSOLETE not write the data that I specified. I cannot understand where +// OBSOLETE it got the data that it actually did write. */ +// OBSOLETE +// OBSOLETE /* Copy LEN bytes to or from inferior's memory starting at MEMADDR +// OBSOLETE to debugger memory starting at MYADDR. Copy to inferior if +// OBSOLETE WRITE is nonzero. TARGET is ignored. +// OBSOLETE +// OBSOLETE Returns the length copied, which is either the LEN argument or zero. +// OBSOLETE This xfer function does not do partial moves, since child_ops +// OBSOLETE doesn't allow memory operations to cross below us in the target stack +// OBSOLETE anyway. */ +// OBSOLETE +// OBSOLETE int +// OBSOLETE child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, +// OBSOLETE struct mem_attrib *attrib, +// OBSOLETE struct target_ops *target) +// OBSOLETE { +// OBSOLETE register int i; +// OBSOLETE /* Round starting address down to longword boundary. */ +// OBSOLETE register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE); +// OBSOLETE /* Round ending address up; get number of longwords that makes. */ +// OBSOLETE register int count +// OBSOLETE = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1) +// OBSOLETE / sizeof (PTRACE_XFER_TYPE); +// OBSOLETE /* Allocate buffer of that many longwords. */ +// OBSOLETE /* FIXME (alloca): This code, cloned from infptrace.c, is unsafe +// OBSOLETE because it uses alloca to allocate a buffer of arbitrary size. +// OBSOLETE For very large xfers, this could crash GDB's stack. */ +// OBSOLETE register PTRACE_XFER_TYPE *buffer +// OBSOLETE = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE)); +// OBSOLETE +// OBSOLETE if (write) +// OBSOLETE { +// OBSOLETE /* Fill start and end extra bytes of buffer with existing memory data. */ +// OBSOLETE +// OBSOLETE if (addr != memaddr || len < (int) sizeof (PTRACE_XFER_TYPE)) +// OBSOLETE { +// OBSOLETE /* Need part of initial word -- fetch it. */ +// OBSOLETE buffer[0] = ptrace (PT_RTEXT, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) addr, +// OBSOLETE 0); +// OBSOLETE } +// OBSOLETE +// OBSOLETE if (count > 1) /* FIXME, avoid if even boundary */ +// OBSOLETE { +// OBSOLETE buffer[count - 1] +// OBSOLETE = ptrace (PT_RTEXT, PIDGET (inferior_ptid), +// OBSOLETE ((PTRACE_ARG3_TYPE) +// OBSOLETE (addr + (count - 1) * sizeof (PTRACE_XFER_TYPE))), +// OBSOLETE 0); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Copy data to be written over corresponding part of buffer */ +// OBSOLETE +// OBSOLETE memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), +// OBSOLETE myaddr, +// OBSOLETE len); +// OBSOLETE +// OBSOLETE /* Write the entire buffer. */ +// OBSOLETE +// OBSOLETE for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE)) +// OBSOLETE { +// OBSOLETE errno = 0; +// OBSOLETE ptrace (PT_WDATA, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) addr, +// OBSOLETE buffer[i]); +// OBSOLETE if (errno) +// OBSOLETE { +// OBSOLETE /* Using the appropriate one (I or D) is necessary for +// OBSOLETE Gould NP1, at least. */ +// OBSOLETE errno = 0; +// OBSOLETE ptrace (PT_WTEXT, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) addr, +// OBSOLETE buffer[i]); +// OBSOLETE } +// OBSOLETE if (errno) +// OBSOLETE return 0; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE /* Read all the longwords */ +// OBSOLETE for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE)) +// OBSOLETE { +// OBSOLETE errno = 0; +// OBSOLETE buffer[i] = ptrace (PT_RTEXT, PIDGET (inferior_ptid), +// OBSOLETE (PTRACE_ARG3_TYPE) addr, 0); +// OBSOLETE if (errno) +// OBSOLETE return 0; +// OBSOLETE QUIT; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Copy appropriate bytes out of the buffer. */ +// OBSOLETE memcpy (myaddr, +// OBSOLETE (char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), +// OBSOLETE len); +// OBSOLETE } +// OBSOLETE return len; +// OBSOLETE } +// OBSOLETE +// OBSOLETE +// OBSOLETE void +// OBSOLETE _initialize_symm_nat (void) +// OBSOLETE { +// OBSOLETE #ifdef ATTACH_DETACH +// OBSOLETE /* +// OBSOLETE * the MPDEBUGGER is necessary for process tree debugging and attach +// OBSOLETE * to work, but it alters the behavior of debugged processes, so other +// OBSOLETE * things (at least child_wait()) will have to change to accomodate +// OBSOLETE * that. +// OBSOLETE * +// OBSOLETE * Note that attach is not implemented in dynix 3, and not in ptx +// OBSOLETE * until version 2.1 of the OS. +// OBSOLETE */ +// OBSOLETE int rv; +// OBSOLETE sigset_t set; +// OBSOLETE struct sigaction sact; +// OBSOLETE +// OBSOLETE rv = mptrace (XPT_MPDEBUGGER, 0, 0, 0); +// OBSOLETE if (-1 == rv) +// OBSOLETE { +// OBSOLETE internal_error (__FILE__, __LINE__, +// OBSOLETE "_initialize_symm_nat(): mptrace(XPT_MPDEBUGGER): %s", +// OBSOLETE safe_strerror (errno)); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* +// OBSOLETE * Under MPDEBUGGER, we get SIGCLHD when a traced process does +// OBSOLETE * anything of interest. +// OBSOLETE */ +// OBSOLETE +// OBSOLETE /* +// OBSOLETE * Block SIGCHLD. We leave it blocked all the time, and then +// OBSOLETE * call sigsuspend() in child_wait() to wait for the child +// OBSOLETE * to do something. None of these ought to fail, but check anyway. +// OBSOLETE */ +// OBSOLETE sigemptyset (&set); +// OBSOLETE rv = sigaddset (&set, SIGCHLD); +// OBSOLETE if (-1 == rv) +// OBSOLETE { +// OBSOLETE internal_error (__FILE__, __LINE__, +// OBSOLETE "_initialize_symm_nat(): sigaddset(SIGCHLD): %s", +// OBSOLETE safe_strerror (errno)); +// OBSOLETE } +// OBSOLETE rv = sigprocmask (SIG_BLOCK, &set, (sigset_t *) NULL); +// OBSOLETE if (-1 == rv) +// OBSOLETE { +// OBSOLETE internal_error (__FILE__, __LINE__, +// OBSOLETE "_initialize_symm_nat(): sigprocmask(SIG_BLOCK): %s", +// OBSOLETE safe_strerror (errno)); +// OBSOLETE } +// OBSOLETE +// OBSOLETE sact.sa_handler = sigchld_handler; +// OBSOLETE sigemptyset (&sact.sa_mask); +// OBSOLETE sact.sa_flags = SA_NOCLDWAIT; /* keep the zombies away */ +// OBSOLETE rv = sigaction (SIGCHLD, &sact, (struct sigaction *) NULL); +// OBSOLETE if (-1 == rv) +// OBSOLETE { +// OBSOLETE internal_error (__FILE__, __LINE__, +// OBSOLETE "_initialize_symm_nat(): sigaction(SIGCHLD): %s", +// OBSOLETE safe_strerror (errno)); +// OBSOLETE } +// OBSOLETE #endif +// OBSOLETE } diff --git a/gdb/symm-tdep.c b/gdb/symm-tdep.c index 37a2f511aa7..21c843680e1 100644 --- a/gdb/symm-tdep.c +++ b/gdb/symm-tdep.c @@ -1,102 +1,102 @@ -/* Sequent Symmetry target interface, for GDB. - Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 2000 - Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* many 387-specific items of use taken from i386-dep.c */ - -#include "defs.h" -#include "frame.h" -#include "inferior.h" -#include "symtab.h" - -#include <signal.h> -#include <sys/param.h> -#include <sys/user.h> -#include <sys/dir.h> -#include <sys/ioctl.h> -#include "gdb_stat.h" -#include "gdbcore.h" -#include <fcntl.h> - -void -symmetry_extract_return_value (struct type *type, char *regbuf, char *valbuf) -{ - union - { - double d; - int l[2]; - } - xd; - struct minimal_symbol *msymbol; - float f; - - if (TYPE_CODE_FLT == TYPE_CODE (type)) - { - msymbol = lookup_minimal_symbol ("1167_flt", NULL, NULL); - if (msymbol != NULL) - { - /* found "1167_flt" means 1167, %fp2-%fp3 */ - /* float & double; 19= %fp2, 20= %fp3 */ - /* no single precision on 1167 */ - xd.l[1] = *((int *) ®buf[REGISTER_BYTE (19)]); - xd.l[0] = *((int *) ®buf[REGISTER_BYTE (20)]); - switch (TYPE_LENGTH (type)) - { - case 4: - /* FIXME: broken for cross-debugging. */ - f = (float) xd.d; - memcpy (valbuf, &f, TYPE_LENGTH (type)); - break; - case 8: - /* FIXME: broken for cross-debugging. */ - memcpy (valbuf, &xd.d, TYPE_LENGTH (type)); - break; - default: - error ("Unknown floating point size"); - break; - } - } - else - { - /* 387 %st(0), gcc uses this */ - i387_to_double (((int *) ®buf[REGISTER_BYTE (3)]), - &xd.d); - switch (TYPE_LENGTH (type)) - { - case 4: /* float */ - f = (float) xd.d; - /* FIXME: broken for cross-debugging. */ - memcpy (valbuf, &f, 4); - break; - case 8: /* double */ - /* FIXME: broken for cross-debugging. */ - memcpy (valbuf, &xd.d, 8); - break; - default: - error ("Unknown floating point size"); - break; - } - } - } - else - { - memcpy (valbuf, regbuf, TYPE_LENGTH (type)); - } -} +// OBSOLETE /* Sequent Symmetry target interface, for GDB. +// OBSOLETE Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 2000 +// OBSOLETE Free Software Foundation, Inc. +// OBSOLETE +// OBSOLETE This file is part of GDB. +// OBSOLETE +// OBSOLETE This program is free software; you can redistribute it and/or modify +// OBSOLETE it under the terms of the GNU General Public License as published by +// OBSOLETE the Free Software Foundation; either version 2 of the License, or +// OBSOLETE (at your option) any later version. +// OBSOLETE +// OBSOLETE This program is distributed in the hope that it will be useful, +// OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of +// OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// OBSOLETE GNU General Public License for more details. +// OBSOLETE +// OBSOLETE You should have received a copy of the GNU General Public License +// OBSOLETE along with this program; if not, write to the Free Software +// OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, +// OBSOLETE Boston, MA 02111-1307, USA. */ +// OBSOLETE +// OBSOLETE /* many 387-specific items of use taken from i386-dep.c */ +// OBSOLETE +// OBSOLETE #include "defs.h" +// OBSOLETE #include "frame.h" +// OBSOLETE #include "inferior.h" +// OBSOLETE #include "symtab.h" +// OBSOLETE +// OBSOLETE #include <signal.h> +// OBSOLETE #include <sys/param.h> +// OBSOLETE #include <sys/user.h> +// OBSOLETE #include <sys/dir.h> +// OBSOLETE #include <sys/ioctl.h> +// OBSOLETE #include "gdb_stat.h" +// OBSOLETE #include "gdbcore.h" +// OBSOLETE #include <fcntl.h> +// OBSOLETE +// OBSOLETE void +// OBSOLETE symmetry_extract_return_value (struct type *type, char *regbuf, char *valbuf) +// OBSOLETE { +// OBSOLETE union +// OBSOLETE { +// OBSOLETE double d; +// OBSOLETE int l[2]; +// OBSOLETE } +// OBSOLETE xd; +// OBSOLETE struct minimal_symbol *msymbol; +// OBSOLETE float f; +// OBSOLETE +// OBSOLETE if (TYPE_CODE_FLT == TYPE_CODE (type)) +// OBSOLETE { +// OBSOLETE msymbol = lookup_minimal_symbol ("1167_flt", NULL, NULL); +// OBSOLETE if (msymbol != NULL) +// OBSOLETE { +// OBSOLETE /* found "1167_flt" means 1167, %fp2-%fp3 */ +// OBSOLETE /* float & double; 19= %fp2, 20= %fp3 */ +// OBSOLETE /* no single precision on 1167 */ +// OBSOLETE xd.l[1] = *((int *) ®buf[REGISTER_BYTE (19)]); +// OBSOLETE xd.l[0] = *((int *) ®buf[REGISTER_BYTE (20)]); +// OBSOLETE switch (TYPE_LENGTH (type)) +// OBSOLETE { +// OBSOLETE case 4: +// OBSOLETE /* FIXME: broken for cross-debugging. */ +// OBSOLETE f = (float) xd.d; +// OBSOLETE memcpy (valbuf, &f, TYPE_LENGTH (type)); +// OBSOLETE break; +// OBSOLETE case 8: +// OBSOLETE /* FIXME: broken for cross-debugging. */ +// OBSOLETE memcpy (valbuf, &xd.d, TYPE_LENGTH (type)); +// OBSOLETE break; +// OBSOLETE default: +// OBSOLETE error ("Unknown floating point size"); +// OBSOLETE break; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE /* 387 %st(0), gcc uses this */ +// OBSOLETE i387_to_double (((int *) ®buf[REGISTER_BYTE (3)]), +// OBSOLETE &xd.d); +// OBSOLETE switch (TYPE_LENGTH (type)) +// OBSOLETE { +// OBSOLETE case 4: /* float */ +// OBSOLETE f = (float) xd.d; +// OBSOLETE /* FIXME: broken for cross-debugging. */ +// OBSOLETE memcpy (valbuf, &f, 4); +// OBSOLETE break; +// OBSOLETE case 8: /* double */ +// OBSOLETE /* FIXME: broken for cross-debugging. */ +// OBSOLETE memcpy (valbuf, &xd.d, 8); +// OBSOLETE break; +// OBSOLETE default: +// OBSOLETE error ("Unknown floating point size"); +// OBSOLETE break; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE memcpy (valbuf, regbuf, TYPE_LENGTH (type)); +// OBSOLETE } +// OBSOLETE } diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 0cadc56900d..766a2cf0b2d 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,29 @@ +2003-04-10 Elena Zannoni <ezannoni@redhat.com> + + * gdb.base/completion.exp: Use string_to_regexp to match the + working directory name. + +2003-04-09 Jim Blandy <jimb@redhat.com> + + * gdb.c++/derivation.exp, gdb.c++/overload.exp, + gdb.c++/userdef.exp: If GDB fails to restore the selected frame + after an inferior function call, report the failure, but allow the + test to continue. + +2003-04-05 Stephane Carrez <stcarrez@nerim.fr> + + * gdb.base/break.exp: marker4() is defined at line 46 when compiled + with -DPROTOTYPES. + +2003-04-05 Stephane Carrez <stcarrez@nerim.fr> + + * gdb.base/break.exp: Revert last patch. + +2003-04-04 Stephane Carrez <stcarrez@nerim.fr> + + * gdb.base/break.exp: marker4() is defined at line 46 when compiled + with -DPROTOTYPES. + 2003-04-02 Andrew Cagney <cagney@redhat.com> * gdb.base/callfuncs.exp: Make "print add" messages unique. diff --git a/gdb/testsuite/gdb.base/break.exp b/gdb/testsuite/gdb.base/break.exp index fbc0e117e0a..38820ec9fc9 100644 --- a/gdb/testsuite/gdb.base/break.exp +++ b/gdb/testsuite/gdb.base/break.exp @@ -914,6 +914,10 @@ gdb_expect { -re "Breakpoint $decimal, $hex in marker4 \\(d=177601976\\) at .*$srcfile:51\[\r\n\]+51\[\t \]+void marker4.*" { pass "run until breakpoint set at small function, optimized file" } + -re "Breakpoint $decimal, marker4 \\(d=177601976\\) at .*$srcfile:46\[\r\n\]+46\[\t \]+void marker4.*" { + # marker4() is defined at line 46 when compiled with -DPROTOTYPES + pass "run until breakpoint set at small function, optimized file (line 46)" + } -re ".*$gdb_prompt " { fail "run until breakpoint set at small function, optimized file" } diff --git a/gdb/testsuite/gdb.base/completion.exp b/gdb/testsuite/gdb.base/completion.exp index 512bbdbcd2e..38bbd4b73c9 100644 --- a/gdb/testsuite/gdb.base/completion.exp +++ b/gdb/testsuite/gdb.base/completion.exp @@ -669,7 +669,14 @@ cd ${srcdir} set fullsrcdir [pwd] cd ${mydir} -gdb_test "cd ${fullsrcdir}" "Working directory ${fullsrcdir}.*" "cd to \${srcdir}" +# If the directory name contains a '+' we must escape it, adding a backslash. +# If not, the test below will fail because it will interpret the '+' as a +# regexp operator. We use string_to_regexp for this purpose. + +gdb_test "cd ${fullsrcdir}" \ + "Working directory [string_to_regexp ${fullsrcdir}].*" \ + "cd to \${srcdir}" + send_gdb "file ./gdb.base/compl\t" sleep 1 gdb_expect { diff --git a/gdb/testsuite/gdb.c++/derivation.exp b/gdb/testsuite/gdb.c++/derivation.exp index 9128730bcd9..10e3844b0ad 100644 --- a/gdb/testsuite/gdb.c++/derivation.exp +++ b/gdb/testsuite/gdb.c++/derivation.exp @@ -300,6 +300,24 @@ gdb_expect { timeout { fail "(timeout) print value of g_instance.afoo()" } } + +# If GDB fails to restore the selected frame properly after the +# inferior function call above (see GDB PR 1155 for an explanation of +# why this might happen), all the subsequent tests will fail. We +# should detect report that failure, but let the marker call finish so +# that the rest of the tests can run undisturbed. +gdb_test_multiple "frame" "re-selected 'main' frame after inferior call" { + -re "#0 marker1.*$gdb_prompt $" { + setup_kfail "gdb/1155" s390-*-linux-gnu + fail "re-selected 'main' frame after inferior call" + gdb_test "finish" ".*main.*at .*derivation.cc:21\[79\].*" \ + "finish call to marker1" + } + -re "#1 ($hex in )?main.*$gdb_prompt $" { + pass "re-selected 'main' frame after inferior call" + } +} + send_gdb "print g_instance.bfoo()\n" gdb_expect { -re ".\[0-9\]* = 2.*$gdb_prompt $" { diff --git a/gdb/testsuite/gdb.c++/overload.exp b/gdb/testsuite/gdb.c++/overload.exp index 227b0553ced..be60250aead 100644 --- a/gdb/testsuite/gdb.c++/overload.exp +++ b/gdb/testsuite/gdb.c++/overload.exp @@ -120,6 +120,24 @@ gdb_expect { } +# If GDB fails to restore the selected frame properly after the +# inferior function call above (see GDB PR 1155 for an explanation of +# why this might happen), all the subsequent tests will fail. We +# should detect and report that failure, but let the marker call +# finish so that the rest of the tests can run undisturbed. +gdb_test_multiple "frame" "re-selected 'main' frame after inferior call" { + -re "#0 marker1.*$gdb_prompt $" { + setup_kfail "gdb/1155" s390-*-linux-gnu + fail "re-selected 'main' frame after inferior call" + gdb_test "finish" ".*main.*at .*overload.cc:7\[78\].*" \ + "finish call to marker1" + } + -re "#1 ($hex in )?main.*$gdb_prompt $" { + pass "re-selected 'main' frame after inferior call" + } +} + + send_gdb "print foo_instance1.overloadargs(1, 2)\n" gdb_expect { -re ".\[0-9\]* = 2\r\n$gdb_prompt $" { diff --git a/gdb/testsuite/gdb.c++/userdef.exp b/gdb/testsuite/gdb.c++/userdef.exp index a46aba60564..9a8fb02f162 100644 --- a/gdb/testsuite/gdb.c++/userdef.exp +++ b/gdb/testsuite/gdb.c++/userdef.exp @@ -66,6 +66,23 @@ send_gdb "break marker1\n" ; gdb_expect -re ".*$gdb_prompt $" gdb_test "print one + two" "\\\$\[0-9\]* = {x = 6, y = 8}" +# If GDB fails to restore the selected frame properly after the +# inferior function call above (see GDB PR 1155 for an explanation of +# why this might happen), all the subsequent tests will fail. We +# should detect report that failure, but let the marker call finish so +# that the rest of the tests can run undisturbed. +gdb_test_multiple "frame" "re-selected 'main' frame after inferior call" { + -re "#0 marker1.*$gdb_prompt $" { + setup_kfail "gdb/1155" s390-*-linux-gnu + fail "re-selected 'main' frame after inferior call" + gdb_test "finish" ".*main.*at .*userdef.cc:27\[67\].*" \ + "finish call to marker1" + } + -re "#1 ($hex in )?main.*$gdb_prompt $" { + pass "re-selected 'main' frame after inferior call" + } +} + gdb_test "print one - two" "\\\$\[0-9\]* = {x = -2, y = -2}" gdb_test "print one * two" "\\\$\[0-9\]* = {x = 8, y = 15}" diff --git a/gdb/testsuite/gdb.mi/ChangeLog b/gdb/testsuite/gdb.mi/ChangeLog index d08946276c9..d2aae785bb4 100644 --- a/gdb/testsuite/gdb.mi/ChangeLog +++ b/gdb/testsuite/gdb.mi/ChangeLog @@ -1,3 +1,7 @@ +2003-04-08 Andrew Cagney <cagney@redhat.com> + + * gdb792.exp: Skip when C++. + 2003-02-23 Stephane Carrez <stcarrez@nerim.fr> * mi-syn-frame.exp: Don't run this test when gdb,nosignals is set. diff --git a/gdb/testsuite/gdb.mi/gdb792.exp b/gdb/testsuite/gdb.mi/gdb792.exp index 3fc6df00ab4..8196464e647 100644 --- a/gdb/testsuite/gdb.mi/gdb792.exp +++ b/gdb/testsuite/gdb.mi/gdb792.exp @@ -21,6 +21,8 @@ # test gdb/792 # +if { [skip_cplus_tests] } { continue } + load_lib mi-support.exp set MIFLAGS "-i=mi" diff --git a/gdb/utils.c b/gdb/utils.c index f8ac0fd41a8..e72aec72a2b 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -1261,7 +1261,7 @@ print_spaces (register int n, register struct ui_file *file) /* Print a host address. */ void -gdb_print_host_address (void *addr, struct ui_file *stream) +gdb_print_host_address (const void *addr, struct ui_file *stream) { /* We could use the %p conversion specifier to fprintf if we had any diff --git a/gdb/valprint.c b/gdb/valprint.c index b1c47a123d4..d4b8bf5faf7 100644 --- a/gdb/valprint.c +++ b/gdb/valprint.c @@ -205,12 +205,8 @@ val_print_type_code_int (struct type *type, char *valaddr, } else { -#ifdef PRINT_TYPELESS_INTEGER - PRINT_TYPELESS_INTEGER (stream, type, unpack_long (type, valaddr)); -#else print_longest (stream, TYPE_UNSIGNED (type) ? 'u' : 'd', 0, unpack_long (type, valaddr)); -#endif } } diff --git a/gdb/valprint.h b/gdb/valprint.h index 52314aaa191..4e2d1661ad2 100644 --- a/gdb/valprint.h +++ b/gdb/valprint.h @@ -33,6 +33,12 @@ extern int objectprint; /* Controls looking up an object's derived type extern unsigned int print_max; /* Max # of chars for strings/vectors */ +/* Flag to low-level print routines that this value is being printed + in an epoch window. We'd like to pass this as a parameter, but + every routine would need to take it. Perhaps we can encapsulate + this in the I/O stream once we have GNU stdio. */ +extern int inspect_it; + /* Print repeat counts if there are more than this many repetitions of an element in an array. Referenced by the low level language dependent print routines. */ diff --git a/gdb/version.in b/gdb/version.in index 8ba75cc4155..003dd00bb02 100644 --- a/gdb/version.in +++ b/gdb/version.in @@ -1 +1 @@ -2003-04-03-cvs +2003-04-10-cvs diff --git a/gdb/x86-64-tdep.c b/gdb/x86-64-tdep.c index 5d43e015819..d670ff436db 100644 --- a/gdb/x86-64-tdep.c +++ b/gdb/x86-64-tdep.c @@ -471,6 +471,8 @@ classify_argument (struct type *type, return 2; } break; + case TYPE_CODE_ENUM: + case TYPE_CODE_REF: case TYPE_CODE_INT: case TYPE_CODE_PTR: switch (bytes) @@ -700,11 +702,17 @@ x86_64_push_arguments (int nargs, struct value **args, CORE_ADDR sp, intreg += 2; break; case X86_64_INTEGERSI_CLASS: - deprecated_write_register_gen (int_parameter_registers[intreg / 2], - VALUE_CONTENTS_ALL (args[i]) + offset); - offset += 8; - intreg++; - break; + { + LONGEST num + = extract_signed_integer (VALUE_CONTENTS_ALL (args[i]) + + offset, 4); + regcache_raw_write_signed (current_regcache, + int_parameter_registers[intreg / 2], num); + + offset += 8; + intreg++; + break; + } case X86_64_SSEDF_CLASS: case X86_64_SSESF_CLASS: case X86_64_SSE_CLASS: @@ -773,7 +781,7 @@ x86_64_store_return_value (struct type *type, struct regcache *regcache, floating point format used by the FPU. This is probably not exactly how it would happen on the target itself, but it is the best we can do. */ - val = extract_floating (valbuf, TYPE_LENGTH (type)); + val = deprecated_extract_floating (valbuf, TYPE_LENGTH (type)); floatformat_from_doublest (&floatformat_i387_ext, &val, buf); regcache_cooked_write_part (regcache, FP0_REGNUM, 0, FPU_REG_RAW_SIZE, buf); @@ -936,12 +944,9 @@ x86_64_save_dummy_frame_tos (CORE_ADDR sp) static struct frame_id x86_64_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *frame) { - struct frame_id id; - - id.pc = frame_pc_unwind (frame); - frame_unwind_unsigned_register (frame, SP_REGNUM, &id.base); - - return id; + CORE_ADDR base; + frame_unwind_unsigned_register (frame, SP_REGNUM, &base); + return frame_id_build (base, frame_pc_unwind (frame)); } void diff --git a/gdb/xstormy16-tdep.c b/gdb/xstormy16-tdep.c index 255912b19fc..3b4c656c5d5 100644 --- a/gdb/xstormy16-tdep.c +++ b/gdb/xstormy16-tdep.c @@ -748,9 +748,8 @@ xstormy16_frame_init_saved_regs (struct frame_info *fi) /* Function: xstormy16_frame_saved_pc Returns the return address for the selected frame. - Called by frame_info, frame_chain_valid, and sometimes by - get_prev_frame. -*/ + Called by frame_info, legacy_frame_chain_valid, and sometimes by + get_prev_frame. */ static CORE_ADDR xstormy16_frame_saved_pc (struct frame_info *fi) |