diff options
author | nobody <> | 2003-04-10 19:19:03 +0000 |
---|---|---|
committer | nobody <> | 2003-04-10 19:19:03 +0000 |
commit | fe4f91720c4fe11c562bca55353a2d3a04ea7818 (patch) | |
tree | dd7c5fbf04670f68629345ecc19fde5e3017f4de | |
parent | bad7deeefd1fa35f148ce755f6ee1e00c3c0d05e (diff) | |
download | gdb-cagney_frameaddr-20030409-mergepoint.zip gdb-cagney_frameaddr-20030409-mergepoint.tar.gz gdb-cagney_frameaddr-20030409-mergepoint.tar.bz2 |
This commit was manufactured by cvs2svn to create tagcagney_frameaddr-20030409-mergepoint
'cagney_frameaddr-20030409-mergepoint'.
Sprout from kettenis_i386newframe-20030406-branch 2003-04-06 14:50:16 UTC nobody 'This commit was manufactured by cvs2svn to create branch'
Cherrypick from master 2003-04-10 19:19:02 UTC Bob Wilson <bob.wilson@acm.org> ' * elf32-xtensa.c (elf_xtensa_relocate_section): Don't continue to the':
bfd/ChangeLog
bfd/dwarf2.c
bfd/elf32-mips.c
bfd/elf32-xtensa.c
bfd/elf64-alpha.c
bfd/elfn32-mips.c
bfd/elfxx-ia64.c
bfd/version.h
gdb/ChangeLog
gdb/Makefile.in
gdb/NEWS
gdb/alpha-tdep.c
gdb/arch-utils.c
gdb/arm-linux-tdep.c
gdb/arm-tdep.c
gdb/blockframe.c
gdb/breakpoint.c
gdb/config/i386/nm-ptx4.h
gdb/config/i386/nm-symmetry.h
gdb/config/i386/ptx.mh
gdb/config/i386/ptx.mt
gdb/config/i386/ptx4.mh
gdb/config/i386/ptx4.mt
gdb/config/i386/symmetry.mh
gdb/config/i386/symmetry.mt
gdb/config/i386/tm-ptx.h
gdb/config/i386/tm-ptx4.h
gdb/config/i386/tm-symmetry.h
gdb/config/i386/xm-ptx.h
gdb/config/i386/xm-ptx4.h
gdb/config/i386/xm-symmetry.h
gdb/config/mips/mipsm3.mh
gdb/config/mips/mipsm3.mt
gdb/config/mips/tm-mipsm3.h
gdb/config/mips/xm-mipsm3.h
gdb/config/nm-m3.h
gdb/configure.host
gdb/configure.tgt
gdb/d10v-tdep.c
gdb/defs.h
gdb/disasm.c
gdb/doc/ChangeLog
gdb/doc/gdbint.texinfo
gdb/doublest.c
gdb/doublest.h
gdb/dummy-frame.c
gdb/fork-child.c
gdb/frame.c
gdb/frame.h
gdb/gdbarch.c
gdb/gdbarch.h
gdb/gdbarch.sh
gdb/i386-cygwin-tdep.c
gdb/ia64-tdep.c
gdb/infcmd.c
gdb/inferior.h
gdb/infrun.c
gdb/m3-nat.c
gdb/mips-tdep.c
gdb/mipsm3-nat.c
gdb/objc-lang.c
gdb/remote-vx.c
gdb/rs6000-tdep.c
gdb/sh-tdep.c
gdb/solib-irix.c
gdb/solib-osf.c
gdb/solib-sunos.c
gdb/solib-svr4.c
gdb/sparc-tdep.c
gdb/symm-nat.c
gdb/symm-tdep.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/completion.exp
gdb/testsuite/gdb.c++/derivation.exp
gdb/testsuite/gdb.c++/overload.exp
gdb/testsuite/gdb.c++/userdef.exp
gdb/testsuite/gdb.mi/ChangeLog
gdb/testsuite/gdb.mi/gdb792.exp
gdb/utils.c
gdb/valprint.h
gdb/version.in
gdb/x86-64-tdep.c
gdb/xstormy16-tdep.c
include/opcode/ChangeLog
include/opcode/mips.h
opcodes/ChangeLog
opcodes/ia64-asmtab.c
opcodes/ia64-ic.tbl
opcodes/mips-dis.c
sim/v850/ChangeLog
89 files changed, 8244 insertions, 7437 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 1264aa3..ac7503e 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,35 @@ +2003-04-10 Bob Wilson <bob.wilson@acm.org> + + * elf32-xtensa.c (elf_xtensa_relocate_section): Don't continue to the + next relocation on an undefined symbol. + +2003-04-09 Richard Henderson <rth@redhat.com> + + * elf64-alpha.c (elf64_alpha_relocate_section) <R_ALPHA_GPREL32>: + Ignore relocations against r_symndx == 0. + +2003-04-09 H.J. Lu <hjl@gnu.org> + + * elf64-alpha.c (elf64_alpha_relocate_section): Don't return + FALSE for undefined symbols. + * elfxx-ia64.c (elfNN_ia64_relocate_section): Likewise. + +2003-04-09 Alexandre Oliva <aoliva@redhat.com> + + * dwarf2.c (_bfd_dwarf2_find_nearest_line): Try DWARF3-standard + and IRIX-specific shift-to-64-bit 4-byte lengths before following + addr_size. + +2003-04-08 Alexandre Oliva <aoliva@redhat.com> + + * elf32-mips.c (bfd_elf32_bfd_reloc_type_lookup): Detect (ctor) + pointer size from ABI, not arch_bits_per_address. + +2003-04-07 Kevin Buettner <kevinb@redhat.com> + + * elfn32-mips.c (elf32_mips_grok_prstatus): Adjust core file related + constants for n32 ABI. + 2003-04-06 Andrew Cagney <cagney@redhat.com> * simple.c (bfd_simple_get_relocated_section_contents): Disable diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c index 8a4cc64..c4a4423 100644 --- a/bfd/dwarf2.c +++ b/bfd/dwarf2.c @@ -1927,26 +1927,34 @@ _bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset, bfd_boolean found; unsigned int offset_size = addr_size; - if (addr_size == 4) + length = read_4_bytes (abfd, stash->info_ptr); + /* A 0xffffff length is the DWARF3 way of indicating we use + 64-bit offsets, instead of 32-bit offsets. */ + if (length == 0xffffffff) { - length = read_4_bytes (abfd, stash->info_ptr); - if (length == 0xffffffff) - { - offset_size = 8; - length = read_8_bytes (abfd, stash->info_ptr + 4); - stash->info_ptr += 8; - } - else if (length == 0) - { - /* Handle (non-standard) 64-bit DWARF2 formats. */ - offset_size = 8; - length = read_4_bytes (abfd, stash->info_ptr + 4); - stash->info_ptr += 4; - } + offset_size = 8; + length = read_8_bytes (abfd, stash->info_ptr + 4); + stash->info_ptr += 12; + } + /* A zero length is the IRIX way of indicating 64-bit offsets, + mostly because the 64-bit length will generally fit in 32 + bits, and the endianness helps. */ + else if (length == 0) + { + offset_size = 8; + length = read_4_bytes (abfd, stash->info_ptr + 4); + stash->info_ptr += 8; + } + /* In the absence of the hints above, we assume addr_size-sized + offsets, for backward-compatibility with pre-DWARF3 64-bit + platforms. */ + else if (addr_size == 8) + { + length = read_8_bytes (abfd, stash->info_ptr); + stash->info_ptr = 8; } else - length = read_8_bytes (abfd, stash->info_ptr); - stash->info_ptr += addr_size; + stash->info_ptr += 4; if (length > 0) { diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c index 1399f00..adf057b 100644 --- a/bfd/elf32-mips.c +++ b/bfd/elf32-mips.c @@ -1440,11 +1440,12 @@ bfd_elf32_bfd_reloc_type_lookup (abfd, code) case BFD_RELOC_CTOR: /* We need to handle BFD_RELOC_CTOR specially. Select the right relocation (R_MIPS_32 or R_MIPS_64) based on the - size of addresses on this architecture. */ - if (bfd_arch_bits_per_address (abfd) == 32) - return &howto_table[(int) R_MIPS_32]; - else + size of addresses of the ABI. */ + if ((elf_elfheader (abfd)->e_flags & (E_MIPS_ABI_O64 + | E_MIPS_ABI_EABI64)) != 0) return &elf_mips_ctor64_howto; + else + return &howto_table[(int) R_MIPS_32]; case BFD_RELOC_MIPS16_JMP: return &elf_mips16_jump_howto; diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c index 92fb98c..b991df4 100644 --- a/bfd/elf32-xtensa.c +++ b/bfd/elf32-xtensa.c @@ -1893,6 +1893,7 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd, bfd_reloc_status_type r; bfd_boolean is_weak_undef; bfd_boolean unresolved_reloc; + bfd_boolean warned; r_type = ELF32_R_TYPE (rel->r_info); if (r_type == (int) R_XTENSA_GNU_VTINHERIT @@ -1983,6 +1984,7 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd, sec = NULL; is_weak_undef = FALSE; unresolved_reloc = FALSE; + warned = FALSE; if (howto->partial_inplace) { @@ -2039,10 +2041,7 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd, (!info->shared || info->no_undefined || ELF_ST_VISIBILITY (h->other))))) return FALSE; - - /* To avoid any more warning messages, like "call out of - range", we continue immediately to the next relocation. */ - continue; + warned = TRUE; } } @@ -2171,7 +2170,7 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd, contents, rel->r_offset, is_weak_undef, &error_message); - if (r != bfd_reloc_ok) + if (r != bfd_reloc_ok && !warned) { const char *name; diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c index 9f564ca..bf18e205 100644 --- a/bfd/elf64-alpha.c +++ b/bfd/elf64-alpha.c @@ -4514,7 +4514,6 @@ elf64_alpha_relocate_section (output_bfd, info, input_bfd, input_section, (!info->shared || info->no_undefined || ELF_ST_VISIBILITY (h->root.other))))) return FALSE; - ret_val = FALSE; continue; } @@ -4580,8 +4579,20 @@ elf64_alpha_relocate_section (output_bfd, info, input_bfd, input_section, value -= gp; goto default_reloc; - case R_ALPHA_GPREL16: case R_ALPHA_GPREL32: + /* If the target section was a removed linkonce section, + r_symndx will be zero. In this case, assume that the + switch will not be used, so don't fill it in. If we + do nothing here, we'll get relocation truncated messages, + due to the placement of the application above 4GB. */ + if (r_symndx == 0) + { + r = bfd_reloc_ok; + break; + } + /* FALLTHRU */ + + case R_ALPHA_GPREL16: case R_ALPHA_GPRELLOW: if (dynamic_symbol_p) { diff --git a/bfd/elfn32-mips.c b/bfd/elfn32-mips.c index 9105d18..ab255fa 100644 --- a/bfd/elfn32-mips.c +++ b/bfd/elfn32-mips.c @@ -2024,7 +2024,7 @@ elf32_mips_grok_prstatus (abfd, note) default: return FALSE; - case 256: /* Linux/MIPS */ + case 440: /* Linux/MIPS N32 */ /* pr_cursig */ elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12); @@ -2033,7 +2033,7 @@ elf32_mips_grok_prstatus (abfd, note) /* pr_reg */ offset = 72; - raw_size = 180; + raw_size = 360; break; } diff --git a/bfd/elfxx-ia64.c b/bfd/elfxx-ia64.c index 3c8ec9e..bff78c8 100644 --- a/bfd/elfxx-ia64.c +++ b/bfd/elfxx-ia64.c @@ -3963,7 +3963,6 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section, (!info->shared || info->no_undefined || ELF_ST_VISIBILITY (h->other))))) return FALSE; - ret_val = FALSE; continue; } } diff --git a/bfd/version.h b/bfd/version.h index 0afe6a6..b4cc626 100644 --- a/bfd/version.h +++ b/bfd/version.h @@ -1,3 +1,3 @@ -#define BFD_VERSION_DATE 20030406 +#define BFD_VERSION_DATE 20030410 #define BFD_VERSION @bfd_version@ #define BFD_VERSION_STRING @bfd_version_string@ diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 8652060..8272137 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,237 @@ +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 diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 21255fe..4a13551 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -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) @@ -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 d3b5865..2cbec4e 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 712b03e..cba0175 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 fa4d8fa..781d420 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 5d8c538..748422b 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_frame_func (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 diff --git a/gdb/blockframe.c b/gdb/blockframe.c index cf691a3..47e576e 100644 --- a/gdb/blockframe.c +++ b/gdb/blockframe.c @@ -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/breakpoint.c b/gdb/breakpoint.c index b349457..8ab9e54 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -3418,7 +3418,7 @@ print_one_breakpoint (struct breakpoint *b, ui_out_text (uiout, "\tstop only in stack frame at "); /* FIXME: cagney/2002-12-01: Shouldn't be poeking around inside the frame ID. */ - ui_out_field_core_addr (uiout, "frame", b->frame_id.base); + ui_out_field_core_addr (uiout, "frame", b->frame_id.stack_addr); ui_out_text (uiout, "\n"); } diff --git a/gdb/config/i386/nm-ptx4.h b/gdb/config/i386/nm-ptx4.h index 9c8f41c..74db165 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 d3f57e6..72b7d8d 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 554b411..048f5e5 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 757df33..e9551e2 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 e4aa55e..4d23635 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 f347809..ad268f8 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 486a2fb..19c5264 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 a3dba70..8fccbd2 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 2f2bba3..4d3ba83 100644 --- a/gdb/config/i386/tm-ptx.h +++ b/gdb/config/i386/tm-ptx.h @@ -1,194 +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) - -#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 a13d4a6..5f83db4 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 ea22290..c8680a3 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 8987f29..1ecae0c 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 6059413..7f0605d 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 781a343..27711f2 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 864ad57..fc9f37c 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 66856d1..837b27e 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 9e2f490..dbc10d7 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 b2e9f4d..2207d3a 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 07bc26a..0cc84e3 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/configure.host b/gdb/configure.host index 98acc7e..8f96b0a 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 9a4dba3..df174a7 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/d10v-tdep.c b/gdb/d10v-tdep.c index 5e94de4..4ae8099 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) { @@ -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); @@ -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 e9aabc8..511855b 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 7c35033..ff30236 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 9df6edf..4ca81f6 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 3f68273..101240b 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 920d702..d98d045 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 991ee28..a320b7d 100644 --- a/gdb/dummy-frame.c +++ b/gdb/dummy-frame.c @@ -397,7 +397,8 @@ dummy_frame_this_id (struct frame_info *next_frame, (*this_id) = null_frame_id; return; } - (*this_prologue_cache) = find_dummy_frame ((*this_id).pc, (*this_id).base); + (*this_prologue_cache) = find_dummy_frame ((*this_id).code_addr, + (*this_id).stack_addr); } static struct frame_unwind dummy_frame_unwind = diff --git a/gdb/fork-child.c b/gdb/fork-child.c index 0b14a94..1dc28e8 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.c b/gdb/frame.c index 5e7f6f1..8c308b0 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -48,6 +48,77 @@ static int frame_debug; static int backtrace_below_main; +static void +fprint_frame_id (struct ui_file *file, struct frame_id id) +{ + 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) +{ + 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 frame. */ @@ -58,56 +129,105 @@ 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; - /* FIXME: cagney/2002-12-18: Instead of this hack, should only - store the frame ID in PREV_FRAME. */ - fi->frame = fi->id.base; + fi->unwind->this_id (fi->next, &fi->prologue_cache, &fi->this_id.value); + fi->this_id.p = 1; + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame_id (gdb_stdlog, fi->this_id.value); + fprintf_unfiltered (gdb_stdlog, " }\n"); + } } - return frame_id_build (fi->frame, get_frame_pc (fi)); + return frame_id_build (fi->this_id.value.stack_addr, get_frame_pc (fi)); } const struct frame_id null_frame_id; /* All zeros. */ struct frame_id -frame_id_build (CORE_ADDR base, CORE_ADDR func_or_pc) +frame_id_build (CORE_ADDR stack_addr, CORE_ADDR code_addr) { struct frame_id id; - id.base = base; - id.pc = func_or_pc; + id.stack_addr = stack_addr; + id.code_addr = code_addr; return id; } int frame_id_p (struct frame_id l) { - /* The .func can be NULL but the .base cannot. */ - return (l.base != 0); + int p; + /* The .code can be NULL but the .stack cannot. */ + p = (l.stack_addr != 0); + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "{ frame_id_p (l="); + fprint_frame_id (gdb_stdlog, l); + fprintf_unfiltered (gdb_stdlog, ") -> %d }\n", p); + } + return p; } int frame_id_eq (struct frame_id l, struct frame_id r) { - /* If .base is different, the frames are different. */ - if (l.base != r.base) - return 0; - /* Add a test to check that the frame ID's are for the same function - here. */ - return 1; + int eq; + 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; + 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.code_addr == r.code_addr) + /* The .stack and .code are identical, the ID's are identical. */ + eq = 1; + else + /* FIXME: cagney/2003-04-06: This should be zero. Can't yet do + this because most frame ID's are not being initialized + correctly. */ + eq = 1; + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "{ frame_id_eq (l="); + fprint_frame_id (gdb_stdlog, l); + fprintf_unfiltered (gdb_stdlog, ",r="); + fprint_frame_id (gdb_stdlog, r); + fprintf_unfiltered (gdb_stdlog, ") -> %d }\n", eq); + } + return eq; } int frame_id_inner (struct frame_id l, struct frame_id r) { - /* 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). */ - return INNER_THAN (l.base, r.base); + int inner; + 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); + fprintf_unfiltered (gdb_stdlog, ",r="); + fprint_frame_id (gdb_stdlog, r); + fprintf_unfiltered (gdb_stdlog, ") -> %d }\n", inner); + } + return inner; } struct frame_info * @@ -142,7 +262,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)) @@ -184,10 +304,15 @@ 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 @@ -197,6 +322,10 @@ frame_func_unwind (struct frame_info *fi) { 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 fi->prev_func.addr; } @@ -262,6 +391,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); @@ -282,6 +418,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 @@ -521,18 +677,16 @@ create_sentinel_frame (struct regcache *regcache) /* 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; - /* Always unwind the PC as part of creating this frame. This - ensures that the frame's PC points at something valid. */ - /* FIXME: cagney/2003-01-10: Problem here. Unwinding a sentinel - frame's PC may require information such as the frame's thread's - stop reason. Is it possible to get to that? */ - /* FIXME: cagney/2003-04-04: Once ->pc is eliminated, this - assignment can go away. */ - frame->pc = frame_pc_unwind (frame); /* Make the sentinel frame's ID valid, but invalid. That way all comparisons with it should fail. */ - frame->id_p = 1; - frame->id = null_frame_id; + 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; } @@ -821,7 +975,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) @@ -974,13 +1128,20 @@ 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)); fi->next = create_sentinel_frame (current_regcache); /* Select/initialize both the unwind function and the frame's type based on the PC. */ - fi->unwind = frame_unwind_find_by_pc (current_gdbarch, fi->pc); + fi->unwind = frame_unwind_find_by_pc (current_gdbarch, pc); if (fi->unwind->type != UNKNOWN_FRAME) fi->type = fi->unwind->type; else @@ -992,6 +1153,13 @@ create_new_frame (CORE_ADDR addr, CORE_ADDR pc) if (DEPRECATED_INIT_EXTRA_FRAME_INFO_P ()) DEPRECATED_INIT_EXTRA_FRAME_INFO (0, fi); + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, fi); + fprintf_unfiltered (gdb_stdlog, " }\n"); + } + return fi; } @@ -1020,6 +1188,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. */ @@ -1046,6 +1216,9 @@ legacy_get_prev_frame (struct frame_info *this_frame) struct frame_info *prev; int fromleaf; + /* 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 @@ -1080,7 +1253,7 @@ legacy_get_prev_frame (struct frame_info *this_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) @@ -1109,16 +1282,21 @@ legacy_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 legacy PC zero }\n"); + } return NULL; } /* 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, prev->pc); + prev->unwind = frame_unwind_find_by_pc (current_gdbarch, + get_frame_pc (prev)); if (prev->unwind->type == UNKNOWN_FRAME) - prev->type = frame_type_from_pc (prev->pc); + prev->type = frame_type_from_pc (get_frame_pc (prev)); else prev->type = prev->unwind->type; @@ -1142,7 +1320,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 { @@ -1151,15 +1330,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; } @@ -1172,12 +1355,6 @@ legacy_get_prev_frame (struct frame_info *this_frame) after the switch to storing the frame ID, instead of the frame base, in the frame object. */ - /* FIXME: cagney/2002-12-18: Instead of this hack, should only - store the frame ID in PREV_FRAME. */ - /* FIXME: cagney/2003-04-04: Once ->frame is eliminated, this - assignment can go. */ - prev->frame = prev->id.base; - /* Link it in. */ this_frame->prev = prev; @@ -1193,6 +1370,12 @@ legacy_get_prev_frame (struct frame_info *this_frame) { DEPRECATED_INIT_EXTRA_FRAME_INFO (0, prev); } + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, prev); + fprintf_unfiltered (gdb_stdlog, " } // legacy innermost frame\n"); + } return prev; } @@ -1246,11 +1429,29 @@ 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; @@ -1355,6 +1556,13 @@ legacy_get_prev_frame (struct frame_info *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; } @@ -1370,6 +1578,12 @@ legacy_get_prev_frame (struct frame_info *this_frame) if (prev->unwind->type != UNKNOWN_FRAME) { prev->type = prev->unwind->type; + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, prev); + fprintf_unfiltered (gdb_stdlog, " } // legacy with unwound type\n"); + } return prev; } @@ -1406,6 +1620,13 @@ legacy_get_prev_frame (struct frame_info *this_frame) go away. */ } + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, prev); + fprintf_unfiltered (gdb_stdlog, " } // legacy with confused type\n"); + } + return prev; } @@ -1418,6 +1639,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 @@ -1467,14 +1698,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 @@ -1502,8 +1740,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 @@ -1520,8 +1761,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; } @@ -1530,9 +1774,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; } @@ -1542,8 +1783,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; } @@ -1599,22 +1843,22 @@ 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. */ - /* FIXME: cagney/2003-04-04: Once ->pc is eliminated, this - assignment can go away. */ - prev_frame->pc = frame_pc_unwind (this_frame); - if (prev_frame->pc == 0) + if (frame_pc_unwind (this_frame) == 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 PC zero }\n"); + } return NULL; } /* Set the unwind functions based on that identified PC. */ prev_frame->unwind = frame_unwind_find_by_pc (current_gdbarch, - prev_frame->pc); + 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. @@ -1645,13 +1889,21 @@ 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) { - return frame->pc; + gdb_assert (frame->next != NULL); + return frame_pc_unwind (frame->next); } static int @@ -1682,13 +1934,7 @@ find_frame_sal (struct frame_info *frame, struct symtab_and_line *sal) CORE_ADDR get_frame_base (struct frame_info *fi) { - if (!fi->id_p) - { - /* HACK: Force the ID code to (indirectly) initialize the - ->frame pointer. */ - get_frame_id (fi); - } - return fi->frame; + return get_frame_id (fi).stack_addr; } /* High-level offsets into the frame. Used by the debug info. */ @@ -1792,8 +2038,10 @@ frame_extra_info_zalloc (struct frame_info *fi, long size) void deprecated_update_frame_pc_hack (struct frame_info *frame, CORE_ADDR pc) { - /* See comment in "frame.h". */ - frame->pc = 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 @@ -1803,16 +2051,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) { + 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->frame = base; + frame->this_id.value.stack_addr = base; } void diff --git a/gdb/frame.h b/gdb/frame.h index f928b9c..2468fc9 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. */ @@ -43,15 +44,24 @@ struct frame_info; struct frame_id { - /* The frame's address. This should be constant through out the - lifetime of a frame. */ + /* The frame's stack address. This shall be constant through out + 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 base; - /* The frame's current PC. While the PC within the function may - change, the function that contains the PC does not. Should this - instead be the frame's function? */ - CORE_ADDR pc; + CORE_ADDR stack_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. @@ -65,12 +75,12 @@ struct frame_id /* For convenience. All fields are zero. */ extern const struct frame_id null_frame_id; -/* Construct a frame ID. The second parameter isn't yet well defined. - It might be the containing function, or the resume PC (see comment - above in `struct frame_id')? A func/pc of zero indicates a - wildcard (i.e., do not use func in frame ID comparisons). */ -extern struct frame_id frame_id_build (CORE_ADDR base, - CORE_ADDR func_or_pc); +/* 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 code_addr); /* Returns non-zero when L is a valid frame (a valid frame has a non-zero .base). */ @@ -337,17 +347,6 @@ extern void frame_pop (struct frame_info *frame); struct frame_info { - /* Nominal address of the frame described. See comments at - get_frame_base() about what this means outside the *FRAME* - macros; in the *FRAME* macros, it can mean whatever makes most - sense for this machine. */ - CORE_ADDR frame; - - /* Address at which execution is occurring in this frame. - For the innermost frame, it's the current pc. - For other frames, it is a pc saved in the next frame. */ - CORE_ADDR pc; - /* Level of this frame. The inner-most (youngest) frame is at level 0. As you move towards the outer-most (oldest) frame, the level increases. This is a cached value. It could just as @@ -395,8 +394,10 @@ 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 address. */ struct @@ -405,10 +406,12 @@ struct frame_info int p; } 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 @@ -455,10 +458,14 @@ 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); diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index d08f146..257f2b9 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 b2644f7..c1f02c8 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -2385,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 e5cb51d..5807eb2 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -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 diff --git a/gdb/i386-cygwin-tdep.c b/gdb/i386-cygwin-tdep.c index b07911b..5911ec9 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/ia64-tdep.c b/gdb/ia64-tdep.c index 5e46d6b..7abd7ea 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 diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 3866690..01ab3d7 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 ae041f2..db0f4d9 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 74f1de1..3fda964 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 28e62a8..93ef57a 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/mips-tdep.c b/gdb/mips-tdep.c index f9424d7..3e8339b 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 22f947f..f1fd859 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 fe65bd8..bc937ca 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,8 +890,11 @@ 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) @@ -1027,8 +1030,11 @@ 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) @@ -1714,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 19153cf..d9650e3 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/rs6000-tdep.c b/gdb/rs6000-tdep.c index 08394de..4e7d374 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -1646,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; } } @@ -1892,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)); @@ -1908,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)); diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c index d30586c..b61eb23 100644 --- a/gdb/sh-tdep.c +++ b/gdb/sh-tdep.c @@ -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 1cfa452..26a776f 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 6f43a8f..b5dca60 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 25682e0..4072fab 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 7831108..1b0a43e 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 da50574..7a54b8f 100644 --- a/gdb/sparc-tdep.c +++ b/gdb/sparc-tdep.c @@ -437,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; } diff --git a/gdb/symm-nat.c b/gdb/symm-nat.c index 79caf5a..c4b2c9a 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 37a2f51..21c8436 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 981ba36..766a2cf 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,15 @@ +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 diff --git a/gdb/testsuite/gdb.base/completion.exp b/gdb/testsuite/gdb.base/completion.exp index 512bbdb..38bbd4b 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 9128730..10e3844 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 227b055..be60250 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 a46aba6..9a8fb02 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 d089462..d2aae78 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 3fc6df0..8196464 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 f8ac0fd..e72aec7 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.h b/gdb/valprint.h index 52314aa..4e2d166 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 6ec3c5d..003dd00 100644 --- a/gdb/version.in +++ b/gdb/version.in @@ -1 +1 @@ -2003-04-06-cvs +2003-04-10-cvs diff --git a/gdb/x86-64-tdep.c b/gdb/x86-64-tdep.c index 24b77af..d670ff4 100644 --- a/gdb/x86-64-tdep.c +++ b/gdb/x86-64-tdep.c @@ -781,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); diff --git a/gdb/xstormy16-tdep.c b/gdb/xstormy16-tdep.c index 255912b..3b4c656 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) diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog index 35c97a6..112540b 100644 --- a/include/opcode/ChangeLog +++ b/include/opcode/ChangeLog @@ -1,3 +1,7 @@ +2003-04-09 J. Grant <jg-binutils@jguk.org> + + * mips.h: Correct comment typo. + 2003-03-21 Martin Schwidefsky <schwidefsky@de.ibm.com> * s390.h (s390_opcode_arch_val): Rename to s390_opcode_mode_val. diff --git a/include/opcode/mips.h b/include/opcode/mips.h index 1f90cfd..476c8e3 100644 --- a/include/opcode/mips.h +++ b/include/opcode/mips.h @@ -197,7 +197,7 @@ struct mips_opcode unsigned long membership; }; -/* These are the characters which may appears in the args field of an +/* These are the characters which may appear in the args field of an instruction. They appear in the order in which the fields appear when the instruction is used. Commas and parentheses in the args string are ignored when assembling, and written into the output diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 683b913..af97830 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,16 @@ +2003-04-07 James E Wilson <wilson@tuliptree.org> + + * ia64-ic.tbl (fr-readers): Add mem-writers-fp. + * ia64-asmtab.c: Regenerate. + +2003-04-08 Alexandre Oliva <aoliva@redhat.com> + + * mips-dis.c (mips_gpr_names_newabi): Reverted previous patch. + +2003-04-07 Alexandre Oliva <aoliva@redhat.com> + + * mips-dis.c (mips_gpr_names_newabi): $12-$15 are named $t4-$t7. + 2003-04-04 Svein E. Seldal <Svein.Seldal@solidas.com> * tic4x-dis.c: Namespace cleanup. Replace s/c4x/tic4x and diff --git a/opcodes/ia64-asmtab.c b/opcodes/ia64-asmtab.c index a8aa976..2465d39 100644 --- a/opcodes/ia64-asmtab.c +++ b/opcodes/ia64-asmtab.c @@ -1544,30 +1544,36 @@ static const short dep235[] = { }; static const short dep236[] = { - 40, 41, 75, 96, 134, 148, 174, 267, 2165, 2166, 2169, 2172, 4135, + 0, 40, 41, 75, 76, 81, 83, 96, 110, 127, 128, 130, 131, 134, 135, 136, 138, + 139, 146, 163, 174, 178, 181, 267, 274, 2134, 2135, 2136, 2137, 2138, 2139, + 2165, 2166, 2169, 2172, 4135, 16524, 16526, 20613, }; static const short dep237[] = { + 40, 41, 75, 96, 134, 148, 174, 267, 2165, 2166, 2169, 2172, 4135, +}; + +static const short dep238[] = { 40, 41, 75, 96, 134, 135, 139, 148, 174, 267, 2165, 2166, 2169, 2172, 4135, }; -static const short dep238[] = { +static const short dep239[] = { 40, 41, 75, 96, 134, 148, 174, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 2312, 4135, 20613, }; -static const short dep239[] = { +static const short dep240[] = { 40, 41, 75, 96, 134, 135, 139, 148, 174, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 2312, 4135, 20613, }; -static const short dep240[] = { +static const short dep241[] = { 40, 41, 96, 174, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 2310, 4135, 16524, 16526, 18746, 18748, 18749, 18751, 20613, }; -static const short dep241[] = { +static const short dep242[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 26, 27, 28, 29, 30, 31, 96, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 197, 198, 200, 201, 203, 204, 206, 207, 208, @@ -1575,7 +1581,7 @@ static const short dep241[] = { 2312, 28852, 29002, }; -static const short dep242[] = { +static const short dep243[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 28, 29, 30, 31, 40, 41, 96, 134, 171, 174, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 197, 198, 200, 201, @@ -1732,13 +1738,14 @@ op_dependencies[] = { { NELS(dep233), dep233, NELS(dep232), dep232, }, { NELS(dep234), dep234, NELS(dep232), dep232, }, { NELS(dep233), dep233, NELS(dep235), dep235, }, - { NELS(dep236), dep236, NELS(dep31), dep31, }, + { NELS(dep236), dep236, NELS(dep217), dep217, }, { NELS(dep237), dep237, NELS(dep31), dep31, }, - { NELS(dep238), dep238, NELS(dep0), dep0, }, + { NELS(dep238), dep238, NELS(dep31), dep31, }, { NELS(dep239), dep239, NELS(dep0), dep0, }, - { NELS(dep240), dep240, NELS(dep62), dep62, }, + { NELS(dep240), dep240, NELS(dep0), dep0, }, + { NELS(dep241), dep241, NELS(dep62), dep62, }, { 0, NULL, 0, NULL, }, - { NELS(dep242), dep242, NELS(dep241), dep241, }, + { NELS(dep243), dep243, NELS(dep242), dep242, }, }; static const struct ia64_completer_table @@ -1758,7 +1765,7 @@ completer_table[] = { { 0x0, 0x0, 0, -1, -1, 0, 1, 0 }, { 0x0, 0x0, 0, 455, -1, 0, 1, 6 }, { 0x0, 0x0, 0, 518, -1, 0, 1, 17 }, - { 0x0, 0x0, 0, -1, -1, 0, 1, 150 }, + { 0x0, 0x0, 0, -1, -1, 0, 1, 151 }, { 0x0, 0x0, 0, 617, -1, 0, 1, 17 }, { 0x0, 0x0, 0, 1836, -1, 0, 1, 10 }, { 0x0, 0x0, 0, -1, -1, 0, 1, 9 }, @@ -1810,7 +1817,7 @@ completer_table[] = { { 0x0, 0x0, 0, 1181, -1, 0, 1, 33 }, { 0x0, 0x0, 0, -1, -1, 0, 1, 40 }, { 0x0, 0x0, 0, -1, -1, 0, 1, 33 }, - { 0x0, 0x0, 0, -1, -1, 0, 1, 150 }, + { 0x0, 0x0, 0, -1, -1, 0, 1, 151 }, { 0x0, 0x0, 0, -1, -1, 0, 1, 77 }, { 0x0, 0x0, 0, 1216, -1, 0, 1, 124 }, { 0x0, 0x0, 0, 1225, -1, 0, 1, 124 }, @@ -1843,9 +1850,9 @@ completer_table[] = { { 0x0, 0x0, 0, 1419, -1, 0, 1, 140 }, { 0x0, 0x0, 0, 1425, -1, 0, 1, 140 }, { 0x0, 0x0, 0, 1431, -1, 0, 1, 140 }, - { 0x0, 0x0, 0, 1435, -1, 0, 1, 145 }, - { 0x0, 0x0, 0, 1439, -1, 0, 1, 147 }, - { 0x0, 0x0, 0, 1443, -1, 0, 1, 147 }, + { 0x0, 0x0, 0, 1435, -1, 0, 1, 146 }, + { 0x0, 0x0, 0, 1439, -1, 0, 1, 148 }, + { 0x0, 0x0, 0, 1443, -1, 0, 1, 148 }, { 0x0, 0x0, 0, -1, -1, 0, 1, 79 }, { 0x0, 0x0, 0, 253, -1, 0, 1, 40 }, { 0x0, 0x0, 0, -1, -1, 0, 1, 0 }, @@ -1880,13 +1887,13 @@ completer_table[] = { { 0x0, 0x0, 0, -1, -1, 0, 1, 111 }, { 0x0, 0x0, 0, -1, -1, 0, 1, 112 }, { 0x0, 0x0, 0, -1, -1, 0, 1, 113 }, - { 0x0, 0x0, 0, -1, -1, 0, 1, 151 }, - { 0x0, 0x0, 0, -1, -1, 0, 1, 151 }, - { 0x0, 0x0, 0, -1, -1, 0, 1, 151 }, + { 0x0, 0x0, 0, -1, -1, 0, 1, 152 }, + { 0x0, 0x0, 0, -1, -1, 0, 1, 152 }, + { 0x0, 0x0, 0, -1, -1, 0, 1, 152 }, { 0x0, 0x0, 0, -1, -1, 0, 1, 71 }, { 0x0, 0x0, 0, -1, -1, 0, 1, 0 }, { 0x0, 0x0, 0, -1, -1, 0, 1, 0 }, - { 0x0, 0x0, 0, -1, -1, 0, 1, 150 }, + { 0x0, 0x0, 0, -1, -1, 0, 1, 151 }, { 0x0, 0x0, 0, -1, -1, 0, 1, 0 }, { 0x0, 0x0, 0, -1, -1, 0, 1, 0 }, { 0x0, 0x0, 0, 2394, -1, 0, 1, 0 }, @@ -1934,14 +1941,14 @@ completer_table[] = { { 0x0, 0x0, 0, 1723, -1, 0, 1, 138 }, { 0x0, 0x0, 0, 1726, -1, 0, 1, 131 }, { 0x0, 0x0, 0, 1729, -1, 0, 1, 138 }, - { 0x0, 0x0, 0, 1732, -1, 0, 1, 131 }, - { 0x0, 0x0, 0, 1733, -1, 0, 1, 131 }, - { 0x0, 0x0, 0, 1734, -1, 0, 1, 131 }, - { 0x0, 0x0, 0, 1735, -1, 0, 1, 131 }, - { 0x0, 0x0, 0, 1736, -1, 0, 1, 131 }, - { 0x0, 0x0, 0, 1737, -1, 0, 1, 131 }, - { 0x0, 0x0, 0, 1738, -1, 0, 1, 131 }, - { 0x0, 0x0, 0, 1739, -1, 0, 1, 131 }, + { 0x0, 0x0, 0, 1732, -1, 0, 1, 145 }, + { 0x0, 0x0, 0, 1733, -1, 0, 1, 145 }, + { 0x0, 0x0, 0, 1734, -1, 0, 1, 145 }, + { 0x0, 0x0, 0, 1735, -1, 0, 1, 145 }, + { 0x0, 0x0, 0, 1736, -1, 0, 1, 145 }, + { 0x0, 0x0, 0, 1737, -1, 0, 1, 145 }, + { 0x0, 0x0, 0, 1738, -1, 0, 1, 145 }, + { 0x0, 0x0, 0, 1739, -1, 0, 1, 145 }, { 0x0, 0x0, 0, -1, -1, 0, 1, 0 }, { 0x0, 0x0, 0, -1, -1, 0, 1, 0 }, { 0x0, 0x0, 0, -1, -1, 0, 1, 0 }, @@ -2453,7 +2460,7 @@ completer_table[] = { { 0x0, 0x0, 38, 960, -1, 0, 1, 95 }, { 0x0, 0x0, 38, -1, -1, 0, 1, 104 }, { 0x0, 0x0, 38, 966, -1, 0, 1, 116 }, - { 0x3, 0x3, 38, -1, -1, 30, 1, 149 }, + { 0x3, 0x3, 38, -1, -1, 30, 1, 150 }, { 0x0, 0x0, 38, 967, -1, 0, 1, 40 }, { 0x0, 0x0, 40, -1, 825, 0, 0, -1 }, { 0x0, 0x0, 40, -1, 833, 0, 0, -1 }, @@ -2546,21 +2553,21 @@ completer_table[] = { { 0x0, 0x0, 44, 942, -1, 0, 1, 0 }, { 0x0, 0x0, 44, 943, -1, 0, 1, 0 }, { 0x0, 0x0, 44, 944, -1, 0, 1, 0 }, - { 0x1, 0x1, 45, -1, 1433, 30, 1, 146 }, - { 0x1, 0x1, 45, 815, 1432, 30, 1, 145 }, - { 0x1, 0x1, 45, -1, 1437, 30, 1, 148 }, - { 0x1, 0x1, 45, 816, 1436, 30, 1, 147 }, - { 0x1, 0x1, 45, -1, 1441, 30, 1, 148 }, - { 0x1, 0x1, 45, 817, 1440, 30, 1, 147 }, + { 0x1, 0x1, 45, -1, 1433, 30, 1, 147 }, + { 0x1, 0x1, 45, 815, 1432, 30, 1, 146 }, + { 0x1, 0x1, 45, -1, 1437, 30, 1, 149 }, + { 0x1, 0x1, 45, 816, 1436, 30, 1, 148 }, + { 0x1, 0x1, 45, -1, 1441, 30, 1, 149 }, + { 0x1, 0x1, 45, 817, 1440, 30, 1, 148 }, { 0x3, 0x3, 46, -1, 978, 3, 1, 22 }, { 0x1, 0x1, 47, 1889, -1, 30, 1, 137 }, - { 0x1, 0x1, 47, 1920, -1, 30, 1, 149 }, + { 0x1, 0x1, 47, 1920, -1, 30, 1, 150 }, { 0x0, 0x0, 49, -1, -1, 0, 1, 40 }, { 0x0, 0x0, 49, -1, -1, 0, 1, 40 }, { 0x0, 0x0, 49, -1, -1, 0, 1, 40 }, - { 0x1, 0x1, 56, -1, 1434, 31, 1, 146 }, - { 0x1, 0x1, 56, -1, 1438, 31, 1, 148 }, - { 0x1, 0x1, 56, -1, 1442, 31, 1, 148 }, + { 0x1, 0x1, 56, -1, 1434, 31, 1, 147 }, + { 0x1, 0x1, 56, -1, 1438, 31, 1, 149 }, + { 0x1, 0x1, 56, -1, 1442, 31, 1, 149 }, { 0x0, 0x0, 56, -1, -1, 0, 1, 94 }, { 0x2, 0x3, 56, -1, -1, 27, 1, 94 }, { 0x1, 0x1, 56, -1, -1, 28, 1, 94 }, @@ -3175,34 +3182,34 @@ completer_table[] = { { 0x1, 0x1, 171, 1695, -1, 28, 1, 144 }, { 0x1, 0x1, 171, 1696, -1, 28, 1, 144 }, { 0x1, 0x1, 171, 1697, -1, 28, 1, 140 }, - { 0x1, 0x1, 171, 1448, -1, 28, 1, 145 }, - { 0x1, 0x1, 171, 1449, -1, 28, 1, 146 }, - { 0x1, 0x1, 171, 1450, -1, 28, 1, 146 }, - { 0x1, 0x1, 171, 1451, -1, 28, 1, 145 }, - { 0x1, 0x1, 171, 1452, -1, 28, 1, 147 }, - { 0x1, 0x1, 171, 1453, -1, 28, 1, 148 }, - { 0x1, 0x1, 171, 1454, -1, 28, 1, 148 }, - { 0x1, 0x1, 171, 1455, -1, 28, 1, 147 }, - { 0x1, 0x1, 171, 1456, -1, 28, 1, 147 }, - { 0x1, 0x1, 171, 1457, -1, 28, 1, 148 }, - { 0x1, 0x1, 171, 1458, -1, 28, 1, 148 }, - { 0x1, 0x1, 171, 1459, -1, 28, 1, 147 }, + { 0x1, 0x1, 171, 1448, -1, 28, 1, 146 }, + { 0x1, 0x1, 171, 1449, -1, 28, 1, 147 }, + { 0x1, 0x1, 171, 1450, -1, 28, 1, 147 }, + { 0x1, 0x1, 171, 1451, -1, 28, 1, 146 }, + { 0x1, 0x1, 171, 1452, -1, 28, 1, 148 }, + { 0x1, 0x1, 171, 1453, -1, 28, 1, 149 }, + { 0x1, 0x1, 171, 1454, -1, 28, 1, 149 }, + { 0x1, 0x1, 171, 1455, -1, 28, 1, 148 }, + { 0x1, 0x1, 171, 1456, -1, 28, 1, 148 }, + { 0x1, 0x1, 171, 1457, -1, 28, 1, 149 }, + { 0x1, 0x1, 171, 1458, -1, 28, 1, 149 }, + { 0x1, 0x1, 171, 1459, -1, 28, 1, 148 }, { 0x1, 0x1, 171, 1740, -1, 28, 1, 136 }, { 0x1, 0x1, 171, 1741, -1, 28, 1, 136 }, { 0x1, 0x1, 171, 1742, -1, 28, 1, 136 }, { 0x1, 0x1, 171, 1743, -1, 28, 1, 136 }, - { 0x1, 0x1, 172, 1698, -1, 29, 1, 145 }, - { 0x1, 0x1, 172, 1699, -1, 29, 1, 146 }, - { 0x1, 0x1, 172, 1700, -1, 29, 1, 146 }, - { 0x1, 0x1, 172, 1701, -1, 29, 1, 145 }, - { 0x1, 0x1, 172, 1702, -1, 29, 1, 147 }, - { 0x1, 0x1, 172, 1703, -1, 29, 1, 148 }, - { 0x1, 0x1, 172, 1704, -1, 29, 1, 148 }, - { 0x1, 0x1, 172, 1705, -1, 29, 1, 147 }, - { 0x1, 0x1, 172, 1706, -1, 29, 1, 147 }, - { 0x1, 0x1, 172, 1707, -1, 29, 1, 148 }, - { 0x1, 0x1, 172, 1708, -1, 29, 1, 148 }, - { 0x1, 0x1, 172, 1709, -1, 29, 1, 147 }, + { 0x1, 0x1, 172, 1698, -1, 29, 1, 146 }, + { 0x1, 0x1, 172, 1699, -1, 29, 1, 147 }, + { 0x1, 0x1, 172, 1700, -1, 29, 1, 147 }, + { 0x1, 0x1, 172, 1701, -1, 29, 1, 146 }, + { 0x1, 0x1, 172, 1702, -1, 29, 1, 148 }, + { 0x1, 0x1, 172, 1703, -1, 29, 1, 149 }, + { 0x1, 0x1, 172, 1704, -1, 29, 1, 149 }, + { 0x1, 0x1, 172, 1705, -1, 29, 1, 148 }, + { 0x1, 0x1, 172, 1706, -1, 29, 1, 148 }, + { 0x1, 0x1, 172, 1707, -1, 29, 1, 149 }, + { 0x1, 0x1, 172, 1708, -1, 29, 1, 149 }, + { 0x1, 0x1, 172, 1709, -1, 29, 1, 148 }, { 0x3, 0x3, 173, -1, -1, 28, 1, 135 }, { 0x3, 0x3, 173, -1, -1, 28, 1, 135 }, { 0x3, 0x3, 173, -1, -1, 28, 1, 134 }, @@ -3441,18 +3448,18 @@ completer_table[] = { { 0x3, 0x3, 173, -1, -1, 28, 1, 144 }, { 0x3, 0x3, 173, -1, -1, 28, 1, 144 }, { 0x3, 0x3, 173, 1919, -1, 28, 1, 140 }, - { 0x3, 0x3, 173, -1, -1, 28, 1, 145 }, { 0x3, 0x3, 173, -1, -1, 28, 1, 146 }, - { 0x3, 0x3, 173, 803, -1, 28, 1, 146 }, - { 0x3, 0x3, 173, 804, -1, 28, 1, 145 }, { 0x3, 0x3, 173, -1, -1, 28, 1, 147 }, + { 0x3, 0x3, 173, 803, -1, 28, 1, 147 }, + { 0x3, 0x3, 173, 804, -1, 28, 1, 146 }, { 0x3, 0x3, 173, -1, -1, 28, 1, 148 }, - { 0x3, 0x3, 173, 805, -1, 28, 1, 148 }, - { 0x3, 0x3, 173, 806, -1, 28, 1, 147 }, - { 0x3, 0x3, 173, -1, -1, 28, 1, 147 }, + { 0x3, 0x3, 173, -1, -1, 28, 1, 149 }, + { 0x3, 0x3, 173, 805, -1, 28, 1, 149 }, + { 0x3, 0x3, 173, 806, -1, 28, 1, 148 }, { 0x3, 0x3, 173, -1, -1, 28, 1, 148 }, - { 0x3, 0x3, 173, 807, -1, 28, 1, 148 }, - { 0x3, 0x3, 173, 808, -1, 28, 1, 147 }, + { 0x3, 0x3, 173, -1, -1, 28, 1, 149 }, + { 0x3, 0x3, 173, 807, -1, 28, 1, 149 }, + { 0x3, 0x3, 173, 808, -1, 28, 1, 148 }, { 0x3, 0x3, 173, -1, -1, 28, 1, 131 }, { 0x3, 0x3, 173, 1857, -1, 28, 1, 131 }, { 0x3, 0x3, 173, -1, -1, 28, 1, 138 }, @@ -3473,16 +3480,16 @@ completer_table[] = { { 0x3, 0x3, 173, -1, -1, 28, 1, 138 }, { 0x3, 0x3, 173, -1, -1, 28, 1, 139 }, { 0x3, 0x3, 173, 1865, -1, 28, 1, 138 }, - { 0x3, 0x3, 173, -1, -1, 28, 1, 131 }, - { 0x3, 0x3, 173, -1, -1, 28, 1, 131 }, - { 0x3, 0x3, 173, -1, -1, 28, 1, 131 }, - { 0x3, 0x3, 173, -1, -1, 28, 1, 131 }, - { 0x3, 0x3, 173, -1, -1, 28, 1, 131 }, - { 0x3, 0x3, 173, -1, -1, 28, 1, 131 }, - { 0x3, 0x3, 173, -1, -1, 28, 1, 131 }, - { 0x3, 0x3, 173, -1, -1, 28, 1, 131 }, - { 0x3, 0x3, 173, -1, -1, 28, 1, 131 }, - { 0x3, 0x3, 173, -1, -1, 28, 1, 131 }, + { 0x3, 0x3, 173, -1, -1, 28, 1, 145 }, + { 0x3, 0x3, 173, -1, -1, 28, 1, 145 }, + { 0x3, 0x3, 173, -1, -1, 28, 1, 145 }, + { 0x3, 0x3, 173, -1, -1, 28, 1, 145 }, + { 0x3, 0x3, 173, -1, -1, 28, 1, 145 }, + { 0x3, 0x3, 173, -1, -1, 28, 1, 145 }, + { 0x3, 0x3, 173, -1, -1, 28, 1, 145 }, + { 0x3, 0x3, 173, -1, -1, 28, 1, 145 }, + { 0x3, 0x3, 173, -1, -1, 28, 1, 145 }, + { 0x3, 0x3, 173, -1, -1, 28, 1, 145 }, { 0x3, 0x3, 173, -1, -1, 28, 1, 136 }, { 0x3, 0x3, 173, -1, -1, 28, 1, 136 }, { 0x3, 0x3, 173, -1, -1, 28, 1, 136 }, @@ -3663,7 +3670,7 @@ completer_table[] = { { 0x1, 0x1, 219, 250, 1414, 32, 1, 141 }, { 0x1, 0x1, 219, 251, 1420, 32, 1, 141 }, { 0x1, 0x1, 219, 252, 1426, 32, 1, 141 }, - { 0x1, 0x1, 219, 710, -1, 31, 1, 149 }, + { 0x1, 0x1, 219, 710, -1, 31, 1, 150 }, { 0x0, 0x0, 220, 2012, -1, 0, 1, 65 }, { 0x0, 0x0, 220, 2013, -1, 0, 1, 28 }, { 0x0, 0x0, 220, 24, -1, 0, 1, 28 }, @@ -4061,11 +4068,11 @@ completer_table[] = { { 0x1, 0x1, 225, -1, -1, 28, 1, 33 }, { 0x1, 0x1, 225, -1, -1, 28, 1, 33 }, { 0x0, 0x0, 232, 810, -1, 0, 1, 137 }, - { 0x0, 0x0, 232, 811, -1, 0, 1, 149 }, + { 0x0, 0x0, 232, 811, -1, 0, 1, 150 }, { 0x1, 0x1, 233, -1, 1725, 33, 1, 133 }, { 0x1, 0x1, 233, -1, 1728, 33, 1, 139 }, - { 0x0, 0x0, 233, -1, 1730, 0, 1, 131 }, - { 0x0, 0x0, 233, -1, 1731, 0, 1, 131 }, + { 0x0, 0x0, 233, -1, 1730, 0, 1, 145 }, + { 0x0, 0x0, 233, -1, 1731, 0, 1, 145 }, { 0x0, 0x0, 234, 744, 823, 0, 0, -1 }, { 0x0, 0x0, 234, 745, 831, 0, 0, -1 }, { 0x0, 0x0, 234, 746, 827, 0, 0, -1 }, diff --git a/opcodes/ia64-ic.tbl b/opcodes/ia64-ic.tbl index 3eab2eb..45e3bd5 100644 --- a/opcodes/ia64-ic.tbl +++ b/opcodes/ia64-ic.tbl @@ -20,7 +20,7 @@ fpcmp-s0; fpcmp[Field(sf)==s0] fpcmp-s1; fpcmp[Field(sf)==s1] fpcmp-s2; fpcmp[Field(sf)==s2] fpcmp-s3; fpcmp[Field(sf)==s3] -fr-readers; IC:fp-arith, IC:fp-non-arith, IC:pr-writers-fp, chk.s[Format in {M21}], getf +fr-readers; IC:fp-arith, IC:fp-non-arith, IC:pr-writers-fp, chk.s[Format in {M21}], getf, IC:mem-writers-fp fr-writers; IC:fp-arith, IC:fp-non-arith\fclass, IC:mem-readers-fp, setf gr-readers; IC:gr-readers-writers, IC:mem-readers, IC:mem-writers, chk.s, cmp, cmp4, fc, itc.i, itc.d, itr.i, itr.d, IC:mov-to-AR-gr, IC:mov-to-BR, IC:mov-to-CR, IC:mov-to-IND, IC:mov-from-IND, IC:mov-to-PR-allreg, IC:mov-to-PSR-l, IC:mov-to-PSR-um, IC:probe-all, ptc.e, ptc.g, ptc.ga, ptc.l, ptr.i, ptr.d, setf, tbit, tnat gr-readers-writers; IC:mov-from-IND, add, addl, addp4, adds, and, andcm, IC:czx, dep\dep[Format in {I13}], extr, IC:mem-readers-int, IC:ld-all-postinc, IC:lfetch-postinc, IC:mix, IC:mux, or, IC:pack, IC:padd, IC:pavg, IC:pavgsub, IC:pcmp, IC:pmax, IC:pmin, IC:pmpy, IC:pmpyshr, popcnt, IC:probe-nofault, IC:psad, IC:pshl, IC:pshladd, IC:pshr, IC:pshradd, IC:psub, shl, shladd, shladdp4, shr, shrp, IC:st-postinc, sub, IC:sxt, tak, thash, tpa, ttag, IC:unpack, xor, IC:zxt diff --git a/sim/v850/ChangeLog b/sim/v850/ChangeLog index 134f0fd..7d1075c 100644 --- a/sim/v850/ChangeLog +++ b/sim/v850/ChangeLog @@ -1,7 +1,7 @@ 2003-04-06 Nick Clifton <nickc@redhat.com> - * simops.c (OP_40): Delete. Move code to: - * v850-igen.c (): Here. Sign extend the first operand. + * simops.c (OP_40): Delete. Move code to... + * v850-igen.c (): ...Here. Sign extend the first operand. * simops.h (OP_40): Remove prototype. 2003-02-27 Andrew Cagney <cagney@redhat.com> |