diff options
author | Andrew Cagney <cagney@redhat.com> | 2003-02-04 23:26:43 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 2003-02-04 23:26:43 +0000 |
commit | c20ef709c57de74d5f7955d173d9a67ebdea5c50 (patch) | |
tree | 5f5b6136ba3c6b5b2d4ecc92059d2589e061f51c | |
parent | 65d22babac4a5f9f7eaa8aad98924a12eab6aef8 (diff) | |
download | gdb-c20ef709c57de74d5f7955d173d9a67ebdea5c50.tar.gz |
2003-02-04 Andrew Cagney <ac131313@redhat.com>
* NEWS: Note that the m32r-*-elf* is obsolete.
* monitor.c (monitor_expect): Obsolete reference to m32r.
* configure.tgt: Mark m32r-*-elf* as obsolete.
* MAINTAINERS: Mark m32k as obsolete.
* m32r-rom.c: Obsolete file.
* config/m32r/m32r.mt: Obsolete file.
* config/m32r/tm-m32r.h: Obsolete file.
* m32r-stub.c: Obsolete file.
* m32r-tdep.c: Obsolete file.
-rw-r--r-- | gdb/ChangeLog | 12 | ||||
-rw-r--r-- | gdb/MAINTAINERS | 4 | ||||
-rw-r--r-- | gdb/NEWS | 1 | ||||
-rw-r--r-- | gdb/config/m32r/m32r.mt | 10 | ||||
-rw-r--r-- | gdb/config/m32r/tm-m32r.h | 462 | ||||
-rw-r--r-- | gdb/configure.tgt | 2 | ||||
-rw-r--r-- | gdb/m32r-rom.c | 1252 | ||||
-rw-r--r-- | gdb/m32r-stub.c | 3436 | ||||
-rw-r--r-- | gdb/m32r-tdep.c | 1416 | ||||
-rw-r--r-- | gdb/monitor.c | 14 |
10 files changed, 3311 insertions, 3298 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 1bae648426f..eb94d4c03cd 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,17 @@ 2003-02-04 Andrew Cagney <ac131313@redhat.com> + * NEWS: Note that the m32r-*-elf* is obsolete. + * monitor.c (monitor_expect): Obsolete reference to m32r. + * configure.tgt: Mark m32r-*-elf* as obsolete. + * MAINTAINERS: Mark m32k as obsolete. + * m32r-rom.c: Obsolete file. + * config/m32r/m32r.mt: Obsolete file. + * config/m32r/tm-m32r.h: Obsolete file. + * m32r-stub.c: Obsolete file. + * m32r-tdep.c: Obsolete file. + +2003-02-04 Andrew Cagney <ac131313@redhat.com> + * NEWS: Mention that the z8k-zilog-none is obsolete. * MAINTAINERS: Mark z8k as obsolete. * configure.tgt: Obsolete the z8k-*-coff* target. diff --git a/gdb/MAINTAINERS b/gdb/MAINTAINERS index 02d19e2886c..88428aaee25 100644 --- a/gdb/MAINTAINERS +++ b/gdb/MAINTAINERS @@ -94,9 +94,7 @@ maintainer works with the native maintainer when resolving API issues. (--target=ia64-elf broken) Kevin Buettner kevinb@redhat.com - m32r (--target=m32r-elf broken) - Michael Snyder msnyder@redhat.com - OBSOLETE candidate, not multi-arch + m32r (--target=m32r-elf OBSOLETE) m68hc11 --target=m68hc11-elf ,-Werror , Stephane Carrez stcarrez@nerim.fr @@ -37,6 +37,7 @@ been commented out. Unless there is activity to revive these configurations, the next release of GDB will have their sources permanently REMOVED. +Mitsubishi M32R/D w/simulator m32r-*-elf* Z8000 simulator z8k-zilog-none or z8ksim Matsushita MN10200 w/simulator mn10200-*-* H8/500 simulator h8500-hitachi-hms or h8500hms diff --git a/gdb/config/m32r/m32r.mt b/gdb/config/m32r/m32r.mt index a200853b602..a2816084290 100644 --- a/gdb/config/m32r/m32r.mt +++ b/gdb/config/m32r/m32r.mt @@ -1,5 +1,5 @@ -# Target: Mitsubishi m32r processor -TDEPFILES= m32r-tdep.o monitor.o m32r-rom.o dsrec.o -TM_FILE= tm-m32r.h -SIM_OBS = remote-sim.o -SIM = ../sim/m32r/libsim.a +# OBSOLETE # Target: Mitsubishi m32r processor +# OBSOLETE TDEPFILES= m32r-tdep.o monitor.o m32r-rom.o dsrec.o +# OBSOLETE TM_FILE= tm-m32r.h +# OBSOLETE SIM_OBS = remote-sim.o +# OBSOLETE SIM = ../sim/m32r/libsim.a diff --git a/gdb/config/m32r/tm-m32r.h b/gdb/config/m32r/tm-m32r.h index aa9249996ab..89af4e3ab31 100644 --- a/gdb/config/m32r/tm-m32r.h +++ b/gdb/config/m32r/tm-m32r.h @@ -1,231 +1,231 @@ -/* Parameters for execution on a Mitsubishi m32r processor. - Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 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. */ - -#include "regcache.h" - -/* Used by mswin. */ -#define TARGET_M32R 1 - -/* mvs_check REGISTER_NAMES */ -#define REGISTER_NAMES \ -{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \ - "r8", "r9", "r10", "r11", "r12", "fp", "lr", "sp", \ - "psw", "cbr", "spi", "spu", "bpc", "pc", "accl", "acch", \ - /* "cond", "sm", "bsm", "ie", "bie", "bcarry", */ \ -} -/* mvs_check NUM_REGS */ -#define NUM_REGS 24 - -/* mvs_check REGISTER_SIZE */ -#define REGISTER_SIZE 4 -/* mvs_check MAX_REGISTER_RAW_SIZE */ -#define MAX_REGISTER_RAW_SIZE 4 - -/* mvs_check *_REGNUM */ -#define R0_REGNUM 0 -#define STRUCT_RETURN_REGNUM 0 -#define ARG0_REGNUM 0 -#define ARGLAST_REGNUM 3 -#define V0_REGNUM 0 -#define V1_REGNUM 1 -#define FP_REGNUM 13 -#define RP_REGNUM 14 -#define SP_REGNUM 15 -#define PSW_REGNUM 16 -#define CBR_REGNUM 17 -#define SPI_REGNUM 18 -#define SPU_REGNUM 19 -#define BPC_REGNUM 20 -#define PC_REGNUM 21 -#define ACCL_REGNUM 22 -#define ACCH_REGNUM 23 - -/* mvs_check REGISTER_BYTES */ -#define REGISTER_BYTES (NUM_REGS * 4) - -/* mvs_check REGISTER_VIRTUAL_TYPE */ -#define REGISTER_VIRTUAL_TYPE(REG) builtin_type_int - -/* mvs_check REGISTER_BYTE */ -#define REGISTER_BYTE(REG) ((REG) * 4) -/* mvs_check REGISTER_VIRTUAL_SIZE */ -#define REGISTER_VIRTUAL_SIZE(REG) 4 -/* mvs_check REGISTER_RAW_SIZE */ -#define REGISTER_RAW_SIZE(REG) 4 - -/* mvs_check MAX_REGISTER_VIRTUAL_SIZE */ -#define MAX_REGISTER_VIRTUAL_SIZE 4 - -/* mvs_check BREAKPOINT */ -#define BREAKPOINT {0x10, 0xf1} - -/* mvs_no_check FUNCTION_START_OFFSET */ -#define FUNCTION_START_OFFSET 0 - -/* mvs_check DECR_PC_AFTER_BREAK */ -#define DECR_PC_AFTER_BREAK 0 - -/* mvs_check INNER_THAN */ -#define INNER_THAN(lhs,rhs) ((lhs) < (rhs)) - -/* mvs_check SAVED_PC_AFTER_CALL */ -#define SAVED_PC_AFTER_CALL(fi) read_register (RP_REGNUM) - -struct frame_info; -struct frame_saved_regs; -struct type; -struct value; - -/* Define other aspects of the stack frame. - We keep the offsets of all saved registers, 'cause we need 'em a lot! - We also keep the current size of the stack frame, and whether - the frame pointer is valid (for frameless functions, and when we're - still in the prologue of a function with a frame) */ - -/* mvs_check EXTRA_FRAME_INFO */ -#define EXTRA_FRAME_INFO \ - struct frame_saved_regs fsr; \ - int framesize; \ - int using_frame_pointer; - - -extern void m32r_init_extra_frame_info (struct frame_info *fi); -/* mvs_check INIT_EXTRA_FRAME_INFO */ -#define INIT_EXTRA_FRAME_INFO(fromleaf, fi) m32r_init_extra_frame_info (fi) -/* mvs_no_check DEPRECATED_INIT_FRAME_PC */ -#define DEPRECATED_INIT_FRAME_PC init_frame_pc_noop - -extern void -m32r_frame_find_saved_regs (struct frame_info *fi, - struct frame_saved_regs *regaddr); - -/* Put here the code to store, into a struct frame_saved_regs, - the addresses of the saved registers of frame described by FRAME_INFO. - This includes special registers such as pc and fp saved in special - ways in the stack frame. sp is even more special: - the address we return for it IS the sp for the next frame. */ - -/* mvs_check FRAME_FIND_SAVED_REGS */ -#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \ - m32r_frame_find_saved_regs(frame_info, &(frame_saved_regs)) - -extern CORE_ADDR m32r_frame_chain (struct frame_info *fi); -/* mvs_check FRAME_CHAIN */ -#define FRAME_CHAIN(fi) m32r_frame_chain (fi) - -extern CORE_ADDR m32r_find_callers_reg (struct frame_info *fi, int regnum); -extern CORE_ADDR m32r_frame_saved_pc (struct frame_info *); -/* mvs_check FRAME_SAVED_PC */ -#define FRAME_SAVED_PC(fi) m32r_frame_saved_pc (fi) - -/* mvs_check DEPRECATED_EXTRACT_RETURN_VALUE */ -#define DEPRECATED_EXTRACT_RETURN_VALUE(TYPE, REGBUF, VALBUF) \ - memcpy ((VALBUF), \ - (char *)(REGBUF) + REGISTER_BYTE (V0_REGNUM) + \ - ((TYPE_LENGTH (TYPE) > 4 ? 8 : 4) - TYPE_LENGTH (TYPE)), \ - TYPE_LENGTH (TYPE)) - -/* mvs_check DEPRECATED_STORE_RETURN_VALUE */ -#define DEPRECATED_STORE_RETURN_VALUE(TYPE, VALBUF) \ - deprecated_write_register_bytes(REGISTER_BYTE (V0_REGNUM) + \ - ((TYPE_LENGTH (TYPE) > 4 ? 8:4) - TYPE_LENGTH (TYPE)),\ - (VALBUF), TYPE_LENGTH (TYPE)); - -extern CORE_ADDR m32r_skip_prologue (CORE_ADDR pc); -/* mvs_check SKIP_PROLOGUE */ -#define SKIP_PROLOGUE(pc) (m32r_skip_prologue (pc)) - -/* mvs_no_check FRAME_ARGS_SKIP */ -#define FRAME_ARGS_SKIP 0 - -/* mvs_no_check FRAME_ARGS_ADDRESS */ -#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame) -/* mvs_no_check FRAME_LOCALS_ADDRESS */ -#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame) -/* mvs_no_check FRAME_NUM_ARGS */ -#define FRAME_NUM_ARGS(fi) (-1) - -extern void m32r_write_sp (CORE_ADDR val); -#define TARGET_WRITE_SP m32r_write_sp - - - - - - -/* struct passing and returning stuff */ -#define STORE_STRUCT_RETURN(STRUCT_ADDR, SP) \ - write_register (0, STRUCT_ADDR) - -extern use_struct_convention_fn m32r_use_struct_convention; -#define USE_STRUCT_CONVENTION(GCC_P, TYPE) m32r_use_struct_convention (GCC_P, TYPE) - -#define DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \ - extract_address (REGBUF + REGISTER_BYTE (V0_REGNUM), \ - REGISTER_RAW_SIZE (V0_REGNUM)) - -#define REG_STRUCT_HAS_ADDR(gcc_p,type) (TYPE_LENGTH (type) > 8) - - -/* generic dummy frame stuff */ - -#define PUSH_DUMMY_FRAME generic_push_dummy_frame () -#define DEPRECATED_PC_IN_CALL_DUMMY(PC, SP, FP) generic_pc_in_call_dummy (PC, SP, FP) - - -/* target-specific dummy_frame stuff */ - -extern struct frame_info *m32r_pop_frame (struct frame_info *frame); -/* mvs_check POP_FRAME */ -#define POP_FRAME m32r_pop_frame (get_current_frame ()) - -/* mvs_no_check STACK_ALIGN */ -/* #define STACK_ALIGN(x) ((x + 3) & ~3) */ - -extern CORE_ADDR m32r_push_return_address (CORE_ADDR, CORE_ADDR); -extern CORE_ADDR m32r_push_arguments (int nargs, - struct value **args, - CORE_ADDR sp, - unsigned char struct_return, - CORE_ADDR struct_addr); - - - -/* mvs_no_check PUSH_ARGUMENTS */ -#define PUSH_ARGUMENTS(NARGS, ARGS, SP, STRUCT_RETURN, STRUCT_ADDR) \ - (m32r_push_arguments (NARGS, ARGS, SP, STRUCT_RETURN, STRUCT_ADDR)) - -#define PUSH_RETURN_ADDRESS(PC, SP) m32r_push_return_address (PC, SP) - -/* override the standard get_saved_register function with - one that takes account of generic CALL_DUMMY frames */ -#define GET_SAVED_REGISTER(raw_buffer, optimized, addrp, frame, regnum, lval) \ - deprecated_generic_get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval) - - -#define DEPRECATED_USE_GENERIC_DUMMY_FRAMES 1 -#define CALL_DUMMY {0} -#define CALL_DUMMY_LENGTH (0) -#define CALL_DUMMY_START_OFFSET (0) -#define CALL_DUMMY_BREAKPOINT_OFFSET (0) -#define FIX_CALL_DUMMY(DUMMY1, STARTADDR, FUNADDR, NARGS, ARGS, TYPE, GCCP) -#define CALL_DUMMY_LOCATION AT_ENTRY_POINT -#define CALL_DUMMY_ADDRESS() entry_point_address () +// OBSOLETE /* Parameters for execution on a Mitsubishi m32r processor. +// OBSOLETE Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// 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 /* Used by mswin. */ +// OBSOLETE #define TARGET_M32R 1 +// OBSOLETE +// OBSOLETE /* mvs_check REGISTER_NAMES */ +// OBSOLETE #define REGISTER_NAMES \ +// OBSOLETE { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \ +// OBSOLETE "r8", "r9", "r10", "r11", "r12", "fp", "lr", "sp", \ +// OBSOLETE "psw", "cbr", "spi", "spu", "bpc", "pc", "accl", "acch", \ +// OBSOLETE /* "cond", "sm", "bsm", "ie", "bie", "bcarry", */ \ +// OBSOLETE } +// OBSOLETE /* mvs_check NUM_REGS */ +// OBSOLETE #define NUM_REGS 24 +// OBSOLETE +// OBSOLETE /* mvs_check REGISTER_SIZE */ +// OBSOLETE #define REGISTER_SIZE 4 +// OBSOLETE /* mvs_check MAX_REGISTER_RAW_SIZE */ +// OBSOLETE #define MAX_REGISTER_RAW_SIZE 4 +// OBSOLETE +// OBSOLETE /* mvs_check *_REGNUM */ +// OBSOLETE #define R0_REGNUM 0 +// OBSOLETE #define STRUCT_RETURN_REGNUM 0 +// OBSOLETE #define ARG0_REGNUM 0 +// OBSOLETE #define ARGLAST_REGNUM 3 +// OBSOLETE #define V0_REGNUM 0 +// OBSOLETE #define V1_REGNUM 1 +// OBSOLETE #define FP_REGNUM 13 +// OBSOLETE #define RP_REGNUM 14 +// OBSOLETE #define SP_REGNUM 15 +// OBSOLETE #define PSW_REGNUM 16 +// OBSOLETE #define CBR_REGNUM 17 +// OBSOLETE #define SPI_REGNUM 18 +// OBSOLETE #define SPU_REGNUM 19 +// OBSOLETE #define BPC_REGNUM 20 +// OBSOLETE #define PC_REGNUM 21 +// OBSOLETE #define ACCL_REGNUM 22 +// OBSOLETE #define ACCH_REGNUM 23 +// OBSOLETE +// OBSOLETE /* mvs_check REGISTER_BYTES */ +// OBSOLETE #define REGISTER_BYTES (NUM_REGS * 4) +// OBSOLETE +// OBSOLETE /* mvs_check REGISTER_VIRTUAL_TYPE */ +// OBSOLETE #define REGISTER_VIRTUAL_TYPE(REG) builtin_type_int +// OBSOLETE +// OBSOLETE /* mvs_check REGISTER_BYTE */ +// OBSOLETE #define REGISTER_BYTE(REG) ((REG) * 4) +// OBSOLETE /* mvs_check REGISTER_VIRTUAL_SIZE */ +// OBSOLETE #define REGISTER_VIRTUAL_SIZE(REG) 4 +// OBSOLETE /* mvs_check REGISTER_RAW_SIZE */ +// OBSOLETE #define REGISTER_RAW_SIZE(REG) 4 +// OBSOLETE +// OBSOLETE /* mvs_check MAX_REGISTER_VIRTUAL_SIZE */ +// OBSOLETE #define MAX_REGISTER_VIRTUAL_SIZE 4 +// OBSOLETE +// OBSOLETE /* mvs_check BREAKPOINT */ +// OBSOLETE #define BREAKPOINT {0x10, 0xf1} +// OBSOLETE +// OBSOLETE /* mvs_no_check FUNCTION_START_OFFSET */ +// OBSOLETE #define FUNCTION_START_OFFSET 0 +// OBSOLETE +// OBSOLETE /* mvs_check DECR_PC_AFTER_BREAK */ +// OBSOLETE #define DECR_PC_AFTER_BREAK 0 +// OBSOLETE +// OBSOLETE /* mvs_check INNER_THAN */ +// OBSOLETE #define INNER_THAN(lhs,rhs) ((lhs) < (rhs)) +// OBSOLETE +// OBSOLETE /* mvs_check SAVED_PC_AFTER_CALL */ +// OBSOLETE #define SAVED_PC_AFTER_CALL(fi) read_register (RP_REGNUM) +// OBSOLETE +// OBSOLETE struct frame_info; +// OBSOLETE struct frame_saved_regs; +// OBSOLETE struct type; +// OBSOLETE struct value; +// OBSOLETE +// OBSOLETE /* Define other aspects of the stack frame. +// OBSOLETE We keep the offsets of all saved registers, 'cause we need 'em a lot! +// OBSOLETE We also keep the current size of the stack frame, and whether +// OBSOLETE the frame pointer is valid (for frameless functions, and when we're +// OBSOLETE still in the prologue of a function with a frame) */ +// OBSOLETE +// OBSOLETE /* mvs_check EXTRA_FRAME_INFO */ +// OBSOLETE #define EXTRA_FRAME_INFO \ +// OBSOLETE struct frame_saved_regs fsr; \ +// OBSOLETE int framesize; \ +// OBSOLETE int using_frame_pointer; +// OBSOLETE +// OBSOLETE +// OBSOLETE extern void m32r_init_extra_frame_info (struct frame_info *fi); +// OBSOLETE /* mvs_check INIT_EXTRA_FRAME_INFO */ +// OBSOLETE #define INIT_EXTRA_FRAME_INFO(fromleaf, fi) m32r_init_extra_frame_info (fi) +// OBSOLETE /* mvs_no_check DEPRECATED_INIT_FRAME_PC */ +// OBSOLETE #define DEPRECATED_INIT_FRAME_PC init_frame_pc_noop +// OBSOLETE +// OBSOLETE extern void +// OBSOLETE m32r_frame_find_saved_regs (struct frame_info *fi, +// OBSOLETE struct frame_saved_regs *regaddr); +// OBSOLETE +// OBSOLETE /* Put here the code to store, into a struct frame_saved_regs, +// OBSOLETE the addresses of the saved registers of frame described by FRAME_INFO. +// OBSOLETE This includes special registers such as pc and fp saved in special +// OBSOLETE ways in the stack frame. sp is even more special: +// OBSOLETE the address we return for it IS the sp for the next frame. */ +// OBSOLETE +// OBSOLETE /* mvs_check FRAME_FIND_SAVED_REGS */ +// OBSOLETE #define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \ +// OBSOLETE m32r_frame_find_saved_regs(frame_info, &(frame_saved_regs)) +// OBSOLETE +// OBSOLETE extern CORE_ADDR m32r_frame_chain (struct frame_info *fi); +// OBSOLETE /* mvs_check FRAME_CHAIN */ +// OBSOLETE #define FRAME_CHAIN(fi) m32r_frame_chain (fi) +// OBSOLETE +// OBSOLETE extern CORE_ADDR m32r_find_callers_reg (struct frame_info *fi, int regnum); +// OBSOLETE extern CORE_ADDR m32r_frame_saved_pc (struct frame_info *); +// OBSOLETE /* mvs_check FRAME_SAVED_PC */ +// OBSOLETE #define FRAME_SAVED_PC(fi) m32r_frame_saved_pc (fi) +// OBSOLETE +// OBSOLETE /* mvs_check DEPRECATED_EXTRACT_RETURN_VALUE */ +// OBSOLETE #define DEPRECATED_EXTRACT_RETURN_VALUE(TYPE, REGBUF, VALBUF) \ +// OBSOLETE memcpy ((VALBUF), \ +// OBSOLETE (char *)(REGBUF) + REGISTER_BYTE (V0_REGNUM) + \ +// OBSOLETE ((TYPE_LENGTH (TYPE) > 4 ? 8 : 4) - TYPE_LENGTH (TYPE)), \ +// OBSOLETE TYPE_LENGTH (TYPE)) +// OBSOLETE +// OBSOLETE /* mvs_check DEPRECATED_STORE_RETURN_VALUE */ +// OBSOLETE #define DEPRECATED_STORE_RETURN_VALUE(TYPE, VALBUF) \ +// OBSOLETE deprecated_write_register_bytes(REGISTER_BYTE (V0_REGNUM) + \ +// OBSOLETE ((TYPE_LENGTH (TYPE) > 4 ? 8:4) - TYPE_LENGTH (TYPE)),\ +// OBSOLETE (VALBUF), TYPE_LENGTH (TYPE)); +// OBSOLETE +// OBSOLETE extern CORE_ADDR m32r_skip_prologue (CORE_ADDR pc); +// OBSOLETE /* mvs_check SKIP_PROLOGUE */ +// OBSOLETE #define SKIP_PROLOGUE(pc) (m32r_skip_prologue (pc)) +// OBSOLETE +// OBSOLETE /* mvs_no_check FRAME_ARGS_SKIP */ +// OBSOLETE #define FRAME_ARGS_SKIP 0 +// OBSOLETE +// OBSOLETE /* mvs_no_check FRAME_ARGS_ADDRESS */ +// OBSOLETE #define FRAME_ARGS_ADDRESS(fi) ((fi)->frame) +// OBSOLETE /* mvs_no_check FRAME_LOCALS_ADDRESS */ +// OBSOLETE #define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame) +// OBSOLETE /* mvs_no_check FRAME_NUM_ARGS */ +// OBSOLETE #define FRAME_NUM_ARGS(fi) (-1) +// OBSOLETE +// OBSOLETE extern void m32r_write_sp (CORE_ADDR val); +// OBSOLETE #define TARGET_WRITE_SP m32r_write_sp +// OBSOLETE +// OBSOLETE +// OBSOLETE +// OBSOLETE +// OBSOLETE +// OBSOLETE +// OBSOLETE /* struct passing and returning stuff */ +// OBSOLETE #define STORE_STRUCT_RETURN(STRUCT_ADDR, SP) \ +// OBSOLETE write_register (0, STRUCT_ADDR) +// OBSOLETE +// OBSOLETE extern use_struct_convention_fn m32r_use_struct_convention; +// OBSOLETE #define USE_STRUCT_CONVENTION(GCC_P, TYPE) m32r_use_struct_convention (GCC_P, TYPE) +// OBSOLETE +// OBSOLETE #define DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \ +// OBSOLETE extract_address (REGBUF + REGISTER_BYTE (V0_REGNUM), \ +// OBSOLETE REGISTER_RAW_SIZE (V0_REGNUM)) +// OBSOLETE +// OBSOLETE #define REG_STRUCT_HAS_ADDR(gcc_p,type) (TYPE_LENGTH (type) > 8) +// OBSOLETE +// OBSOLETE +// OBSOLETE /* generic dummy frame stuff */ +// OBSOLETE +// OBSOLETE #define PUSH_DUMMY_FRAME generic_push_dummy_frame () +// OBSOLETE #define DEPRECATED_PC_IN_CALL_DUMMY(PC, SP, FP) generic_pc_in_call_dummy (PC, SP, FP) +// OBSOLETE +// OBSOLETE +// OBSOLETE /* target-specific dummy_frame stuff */ +// OBSOLETE +// OBSOLETE extern struct frame_info *m32r_pop_frame (struct frame_info *frame); +// OBSOLETE /* mvs_check POP_FRAME */ +// OBSOLETE #define POP_FRAME m32r_pop_frame (get_current_frame ()) +// OBSOLETE +// OBSOLETE /* mvs_no_check STACK_ALIGN */ +// OBSOLETE /* #define STACK_ALIGN(x) ((x + 3) & ~3) */ +// OBSOLETE +// OBSOLETE extern CORE_ADDR m32r_push_return_address (CORE_ADDR, CORE_ADDR); +// OBSOLETE extern CORE_ADDR m32r_push_arguments (int nargs, +// OBSOLETE struct value **args, +// OBSOLETE CORE_ADDR sp, +// OBSOLETE unsigned char struct_return, +// OBSOLETE CORE_ADDR struct_addr); +// OBSOLETE +// OBSOLETE +// OBSOLETE +// OBSOLETE /* mvs_no_check PUSH_ARGUMENTS */ +// OBSOLETE #define PUSH_ARGUMENTS(NARGS, ARGS, SP, STRUCT_RETURN, STRUCT_ADDR) \ +// OBSOLETE (m32r_push_arguments (NARGS, ARGS, SP, STRUCT_RETURN, STRUCT_ADDR)) +// OBSOLETE +// OBSOLETE #define PUSH_RETURN_ADDRESS(PC, SP) m32r_push_return_address (PC, SP) +// OBSOLETE +// OBSOLETE /* override the standard get_saved_register function with +// OBSOLETE one that takes account of generic CALL_DUMMY frames */ +// OBSOLETE #define GET_SAVED_REGISTER(raw_buffer, optimized, addrp, frame, regnum, lval) \ +// OBSOLETE deprecated_generic_get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval) +// OBSOLETE +// OBSOLETE +// OBSOLETE #define DEPRECATED_USE_GENERIC_DUMMY_FRAMES 1 +// OBSOLETE #define CALL_DUMMY {0} +// OBSOLETE #define CALL_DUMMY_LENGTH (0) +// OBSOLETE #define CALL_DUMMY_START_OFFSET (0) +// OBSOLETE #define CALL_DUMMY_BREAKPOINT_OFFSET (0) +// OBSOLETE #define FIX_CALL_DUMMY(DUMMY1, STARTADDR, FUNADDR, NARGS, ARGS, TYPE, GCCP) +// OBSOLETE #define CALL_DUMMY_LOCATION AT_ENTRY_POINT +// OBSOLETE #define CALL_DUMMY_ADDRESS() entry_point_address () diff --git a/gdb/configure.tgt b/gdb/configure.tgt index 68ab81359e2..dea61dec079 100644 --- a/gdb/configure.tgt +++ b/gdb/configure.tgt @@ -116,7 +116,7 @@ ia64-*-linux*) gdb_target=linux ;; ia64*-*-*) gdb_target=ia64 ;; -m32r-*-elf*) gdb_target=m32r ;; +# OBSOLETE m32r-*-elf*) gdb_target=m32r ;; m68hc11*-*-*|m6811*-*-*) gdb_target=m68hc11 ;; diff --git a/gdb/m32r-rom.c b/gdb/m32r-rom.c index b4bfefdf210..f8ac1542409 100644 --- a/gdb/m32r-rom.c +++ b/gdb/m32r-rom.c @@ -1,626 +1,626 @@ -/* Remote debugging interface to m32r and mon2000 ROM monitors for GDB, - the GNU debugger. - Copyright 1996, 1997, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. - - Adapted by Michael Snyder of Cygnus Support. - - 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. */ - -/* This module defines communication with the Mitsubishi m32r monitor */ - -#include "defs.h" -#include "gdbcore.h" -#include "target.h" -#include "monitor.h" -#include "serial.h" -#include "symtab.h" -#include "command.h" -#include "gdbcmd.h" -#include "symfile.h" /* for generic load */ -#include <time.h> /* for time_t */ -#include "gdb_string.h" -#include "objfiles.h" /* for ALL_OBJFILES etc. */ -#include "inferior.h" /* for write_pc() */ -#include <ctype.h> -#include "regcache.h" - -extern void report_transfer_performance (unsigned long, time_t, time_t); - -/* - * All this stuff just to get my host computer's IP address! - */ -#include <sys/types.h> -#include <netdb.h> /* for hostent */ -#include <netinet/in.h> /* for struct in_addr */ -#if 1 -#include <arpa/inet.h> /* for inet_ntoa */ -#endif - -static char *board_addr; /* user-settable IP address for M32R-EVA */ -static char *server_addr; /* user-settable IP address for gdb host */ -static char *download_path; /* user-settable path for SREC files */ - - -/* - * Function: m32r_load_1 (helper function) - */ - -static void -m32r_load_section (bfd *abfd, asection *s, void *obj) -{ - unsigned int *data_count = obj; - if (s->flags & SEC_LOAD) - { - bfd_size_type section_size = bfd_section_size (abfd, s); - bfd_vma section_base = bfd_section_lma (abfd, s); - unsigned int buffer, i; - - *data_count += section_size; - - printf_filtered ("Loading section %s, size 0x%lx lma ", - bfd_section_name (abfd, s), section_size); - print_address_numeric (section_base, 1, gdb_stdout); - printf_filtered ("\n"); - gdb_flush (gdb_stdout); - monitor_printf ("%s mw\r", paddr_nz (section_base)); - for (i = 0; i < section_size; i += 4) - { - QUIT; - monitor_expect (" -> ", NULL, 0); - bfd_get_section_contents (abfd, s, (char *) &buffer, i, 4); - monitor_printf ("%x\n", buffer); - } - monitor_expect (" -> ", NULL, 0); - monitor_printf ("q\n"); - monitor_expect_prompt (NULL, 0); - } -} - -static int -m32r_load_1 (void *dummy) -{ - int data_count = 0; - - bfd_map_over_sections ((bfd *) dummy, m32r_load_section, &data_count); - return data_count; -} - -/* - * Function: m32r_load (an alternate way to load) - */ - -static void -m32r_load (char *filename, int from_tty) -{ - bfd *abfd; - asection *s; - unsigned int i, data_count = 0; - time_t start_time, end_time; /* for timing of download */ - - if (filename == NULL || filename[0] == 0) - filename = get_exec_file (1); - - abfd = bfd_openr (filename, 0); - if (!abfd) - error ("Unable to open file %s\n", filename); - if (bfd_check_format (abfd, bfd_object) == 0) - error ("File is not an object file\n"); - start_time = time (NULL); -#if 0 - for (s = abfd->sections; s; s = s->next) - if (s->flags & SEC_LOAD) - { - bfd_size_type section_size = bfd_section_size (abfd, s); - bfd_vma section_base = bfd_section_vma (abfd, s); - unsigned int buffer; - - data_count += section_size; - - printf_filtered ("Loading section %s, size 0x%lx vma ", - bfd_section_name (abfd, s), section_size); - print_address_numeric (section_base, 1, gdb_stdout); - printf_filtered ("\n"); - gdb_flush (gdb_stdout); - monitor_printf ("%x mw\r", section_base); - for (i = 0; i < section_size; i += 4) - { - monitor_expect (" -> ", NULL, 0); - bfd_get_section_contents (abfd, s, (char *) &buffer, i, 4); - monitor_printf ("%x\n", buffer); - } - monitor_expect (" -> ", NULL, 0); - monitor_printf ("q\n"); - monitor_expect_prompt (NULL, 0); - } -#else - if (!(catch_errors (m32r_load_1, abfd, "Load aborted!\n", RETURN_MASK_ALL))) - { - monitor_printf ("q\n"); - return; - } -#endif - end_time = time (NULL); - printf_filtered ("Start address 0x%lx\n", bfd_get_start_address (abfd)); - report_transfer_performance (data_count, start_time, end_time); - - /* Finally, make the PC point at the start address */ - if (exec_bfd) - write_pc (bfd_get_start_address (exec_bfd)); - - inferior_ptid = null_ptid; /* No process now */ - - /* This is necessary because many things were based on the PC at the - time that we attached to the monitor, which is no longer valid - now that we have loaded new code (and just changed the PC). - Another way to do this might be to call normal_stop, except that - the stack may not be valid, and things would get horribly - confused... */ - - clear_symtab_users (); -} - -static void -m32r_load_gen (char *filename, int from_tty) -{ - generic_load (filename, from_tty); -} - -static void m32r_open (char *args, int from_tty); -static void mon2000_open (char *args, int from_tty); - -/* This array of registers needs to match the indexes used by GDB. The - whole reason this exists is because the various ROM monitors use - different names than GDB does, and don't support all the registers - either. So, typing "info reg sp" becomes an "A7". */ - -static char *m32r_regnames[] = -{"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", - "psw", "cbr", "spi", "spu", "bpc", "pc", "accl", "acch", -}; - -static void -m32r_supply_register (char *regname, int regnamelen, char *val, int vallen) -{ - int regno; - int num_regs = sizeof (m32r_regnames) / sizeof (m32r_regnames[0]); - - for (regno = 0; regno < num_regs; regno++) - if (strncmp (regname, m32r_regnames[regno], regnamelen) == 0) - break; - - if (regno >= num_regs) - return; /* no match */ - - if (regno == ACCL_REGNUM) - { /* special handling for 64-bit acc reg */ - monitor_supply_register (ACCH_REGNUM, val); - val = strchr (val, ':'); /* skip past ':' to get 2nd word */ - if (val != NULL) - monitor_supply_register (ACCL_REGNUM, val + 1); - } - else - { - monitor_supply_register (regno, val); - if (regno == PSW_REGNUM) - { - unsigned long psw = strtoul (val, NULL, 16); - char *zero = "00000000", *one = "00000001"; - -#ifdef SM_REGNUM - /* Stack mode bit */ - monitor_supply_register (SM_REGNUM, (psw & 0x80) ? one : zero); -#endif -#ifdef BSM_REGNUM - /* Backup stack mode bit */ - monitor_supply_register (BSM_REGNUM, (psw & 0x8000) ? one : zero); -#endif -#ifdef IE_REGNUM - /* Interrupt enable bit */ - monitor_supply_register (IE_REGNUM, (psw & 0x40) ? one : zero); -#endif -#ifdef BIE_REGNUM - /* Backup interrupt enable bit */ - monitor_supply_register (BIE_REGNUM, (psw & 0x4000) ? one : zero); -#endif -#ifdef COND_REGNUM - /* Condition bit (carry etc.) */ - monitor_supply_register (COND_REGNUM, (psw & 0x1) ? one : zero); -#endif -#ifdef CBR_REGNUM - monitor_supply_register (CBR_REGNUM, (psw & 0x1) ? one : zero); -#endif -#ifdef BPC_REGNUM - monitor_supply_register (BPC_REGNUM, zero); /* KLUDGE: (???????) */ -#endif -#ifdef BCARRY_REGNUM - monitor_supply_register (BCARRY_REGNUM, zero); /* KLUDGE: (??????) */ -#endif - } - - if (regno == SPI_REGNUM || regno == SPU_REGNUM) - { /* special handling for stack pointer (spu or spi) */ - unsigned long stackmode = read_register (PSW_REGNUM) & 0x80; - - if (regno == SPI_REGNUM && !stackmode) /* SP == SPI */ - monitor_supply_register (SP_REGNUM, val); - else if (regno == SPU_REGNUM && stackmode) /* SP == SPU */ - monitor_supply_register (SP_REGNUM, val); - } - } -} - -/* m32r RevC board monitor */ - -static struct target_ops m32r_ops; - -static char *m32r_inits[] = -{"\r", NULL}; - -static struct monitor_ops m32r_cmds; - -static void -init_m32r_cmds (void) -{ - m32r_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_REGISTER_VALUE_FIRST; - m32r_cmds.init = m32r_inits; /* Init strings */ - m32r_cmds.cont = "go\r"; /* continue command */ - m32r_cmds.step = "step\r"; /* single step */ - m32r_cmds.stop = NULL; /* interrupt command */ - m32r_cmds.set_break = "%x +bp\r"; /* set a breakpoint */ - m32r_cmds.clr_break = "%x -bp\r"; /* clear a breakpoint */ - m32r_cmds.clr_all_break = "bpoff\r"; /* clear all breakpoints */ - m32r_cmds.fill = "%x %x %x fill\r"; /* fill (start length val) */ - m32r_cmds.setmem.cmdb = "%x 1 %x fill\r"; /* setmem.cmdb (addr, value) */ - m32r_cmds.setmem.cmdw = "%x 1 %x fillh\r"; /* setmem.cmdw (addr, value) */ - m32r_cmds.setmem.cmdl = "%x 1 %x fillw\r"; /* setmem.cmdl (addr, value) */ - m32r_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */ - m32r_cmds.setmem.resp_delim = NULL; /* setmem.resp_delim */ - m32r_cmds.setmem.term = NULL; /* setmem.term */ - m32r_cmds.setmem.term_cmd = NULL; /* setmem.term_cmd */ - m32r_cmds.getmem.cmdb = "%x %x dump\r"; /* getmem.cmdb (addr, len) */ - m32r_cmds.getmem.cmdw = NULL; /* getmem.cmdw (addr, len) */ - m32r_cmds.getmem.cmdl = NULL; /* getmem.cmdl (addr, len) */ - m32r_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */ - m32r_cmds.getmem.resp_delim = ": "; /* getmem.resp_delim */ - m32r_cmds.getmem.term = NULL; /* getmem.term */ - m32r_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */ - m32r_cmds.setreg.cmd = "%x to %%%s\r"; /* setreg.cmd (name, value) */ - m32r_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */ - m32r_cmds.setreg.term = NULL; /* setreg.term */ - m32r_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */ - m32r_cmds.getreg.cmd = NULL; /* getreg.cmd (name) */ - m32r_cmds.getreg.resp_delim = NULL; /* getreg.resp_delim */ - m32r_cmds.getreg.term = NULL; /* getreg.term */ - m32r_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */ - m32r_cmds.dump_registers = ".reg\r"; /* dump_registers */ - m32r_cmds.register_pattern = "\\(\\w+\\) += \\([0-9a-fA-F]+\\b\\)"; /* register_pattern */ - m32r_cmds.supply_register = m32r_supply_register; /* supply_register */ - m32r_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */ - m32r_cmds.load = NULL; /* download command */ - m32r_cmds.loadresp = NULL; /* load response */ - m32r_cmds.prompt = "ok "; /* monitor command prompt */ - m32r_cmds.line_term = "\r"; /* end-of-line terminator */ - m32r_cmds.cmd_end = NULL; /* optional command terminator */ - m32r_cmds.target = &m32r_ops; /* target operations */ - m32r_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */ - m32r_cmds.regnames = m32r_regnames; /* registers names */ - m32r_cmds.magic = MONITOR_OPS_MAGIC; /* magic */ -} /* init_m32r_cmds */ - -static void -m32r_open (char *args, int from_tty) -{ - monitor_open (args, &m32r_cmds, from_tty); -} - -/* Mon2000 monitor (MSA2000 board) */ - -static struct target_ops mon2000_ops; -static struct monitor_ops mon2000_cmds; - -static void -init_mon2000_cmds (void) -{ - mon2000_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_REGISTER_VALUE_FIRST; - mon2000_cmds.init = m32r_inits; /* Init strings */ - mon2000_cmds.cont = "go\r"; /* continue command */ - mon2000_cmds.step = "step\r"; /* single step */ - mon2000_cmds.stop = NULL; /* interrupt command */ - mon2000_cmds.set_break = "%x +bp\r"; /* set a breakpoint */ - mon2000_cmds.clr_break = "%x -bp\r"; /* clear a breakpoint */ - mon2000_cmds.clr_all_break = "bpoff\r"; /* clear all breakpoints */ - mon2000_cmds.fill = "%x %x %x fill\r"; /* fill (start length val) */ - mon2000_cmds.setmem.cmdb = "%x 1 %x fill\r"; /* setmem.cmdb (addr, value) */ - mon2000_cmds.setmem.cmdw = "%x 1 %x fillh\r"; /* setmem.cmdw (addr, value) */ - mon2000_cmds.setmem.cmdl = "%x 1 %x fillw\r"; /* setmem.cmdl (addr, value) */ - mon2000_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */ - mon2000_cmds.setmem.resp_delim = NULL; /* setmem.resp_delim */ - mon2000_cmds.setmem.term = NULL; /* setmem.term */ - mon2000_cmds.setmem.term_cmd = NULL; /* setmem.term_cmd */ - mon2000_cmds.getmem.cmdb = "%x %x dump\r"; /* getmem.cmdb (addr, len) */ - mon2000_cmds.getmem.cmdw = NULL; /* getmem.cmdw (addr, len) */ - mon2000_cmds.getmem.cmdl = NULL; /* getmem.cmdl (addr, len) */ - mon2000_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */ - mon2000_cmds.getmem.resp_delim = ": "; /* getmem.resp_delim */ - mon2000_cmds.getmem.term = NULL; /* getmem.term */ - mon2000_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */ - mon2000_cmds.setreg.cmd = "%x to %%%s\r"; /* setreg.cmd (name, value) */ - mon2000_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */ - mon2000_cmds.setreg.term = NULL; /* setreg.term */ - mon2000_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */ - mon2000_cmds.getreg.cmd = NULL; /* getreg.cmd (name) */ - mon2000_cmds.getreg.resp_delim = NULL; /* getreg.resp_delim */ - mon2000_cmds.getreg.term = NULL; /* getreg.term */ - mon2000_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */ - mon2000_cmds.dump_registers = ".reg\r"; /* dump_registers */ - mon2000_cmds.register_pattern = "\\(\\w+\\) += \\([0-9a-fA-F]+\\b\\)"; /* register_pattern */ - mon2000_cmds.supply_register = m32r_supply_register; /* supply_register */ - mon2000_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */ - mon2000_cmds.load = NULL; /* download command */ - mon2000_cmds.loadresp = NULL; /* load response */ - mon2000_cmds.prompt = "Mon2000>"; /* monitor command prompt */ - mon2000_cmds.line_term = "\r"; /* end-of-line terminator */ - mon2000_cmds.cmd_end = NULL; /* optional command terminator */ - mon2000_cmds.target = &mon2000_ops; /* target operations */ - mon2000_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */ - mon2000_cmds.regnames = m32r_regnames; /* registers names */ - mon2000_cmds.magic = MONITOR_OPS_MAGIC; /* magic */ -} /* init_mon2000_cmds */ - -static void -mon2000_open (char *args, int from_tty) -{ - monitor_open (args, &mon2000_cmds, from_tty); -} - -/* Function: set_board_address - Tell the BootOne monitor what it's ethernet IP address is. */ - -static void -m32r_set_board_address (char *args, int from_tty) -{ - int resp_len; - char buf[1024]; - - if (args && *args) - { - monitor_printf ("ulip %s\n", args); - resp_len = monitor_expect_prompt (buf, sizeof (buf)); - /* now parse the result for success */ - } - else - error ("Requires argument (IP address for M32R-EVA board)"); -} - -/* Function: set_server_address - Tell the BootOne monitor what gdb's ethernet IP address is. */ - -static void -m32r_set_server_address (char *args, int from_tty) -{ - int resp_len; - char buf[1024]; - - if (args && *args) - { - monitor_printf ("uhip %s\n", args); - resp_len = monitor_expect_prompt (buf, sizeof (buf)); - /* now parse the result for success */ - } - else - error ("Requires argument (IP address of GDB's host computer)"); -} - -/* Function: set_download_path - Tell the BootOne monitor the default path for downloadable SREC files. */ - -static void -m32r_set_download_path (char *args, int from_tty) -{ - int resp_len; - char buf[1024]; - - if (args && *args) - { - monitor_printf ("up %s\n", args); - resp_len = monitor_expect_prompt (buf, sizeof (buf)); - /* now parse the result for success */ - } - else - error ("Requires argument (default path for downloadable SREC files)"); -} - -static void -m32r_upload_command (char *args, int from_tty) -{ - bfd *abfd; - asection *s; - time_t start_time, end_time; /* for timing of download */ - int resp_len, data_count = 0; - char buf[1024]; - struct hostent *hostent; - struct in_addr inet_addr; - - /* first check to see if there's an ethernet port! */ - monitor_printf ("ust\r"); - resp_len = monitor_expect_prompt (buf, sizeof (buf)); - if (!strchr (buf, ':')) - error ("No ethernet connection!"); - - if (board_addr == 0) - { - /* scan second colon in the output from the "ust" command */ - char *myIPaddress = strchr (strchr (buf, ':') + 1, ':') + 1; - - while (isspace (*myIPaddress)) - myIPaddress++; - - if (!strncmp (myIPaddress, "0.0.", 4)) /* empty */ - error ("Please use 'set board-address' to set the M32R-EVA board's IP address."); - if (strchr (myIPaddress, '(')) - *(strchr (myIPaddress, '(')) = '\0'; /* delete trailing junk */ - board_addr = xstrdup (myIPaddress); - } - if (server_addr == 0) - { - buf[0] = 0; - gethostname (buf, sizeof (buf)); - if (buf[0] != 0) - hostent = gethostbyname (buf); - if (hostent != 0) - { -#if 1 - memcpy (&inet_addr.s_addr, hostent->h_addr, - sizeof (inet_addr.s_addr)); - server_addr = (char *) inet_ntoa (inet_addr); -#else - server_addr = (char *) inet_ntoa (hostent->h_addr); -#endif - } - if (server_addr == 0) /* failed? */ - error ("Need to know gdb host computer's IP address (use 'set server-address')"); - } - - if (args == 0 || args[0] == 0) /* no args: upload the current file */ - args = get_exec_file (1); - - if (args[0] != '/' && download_path == 0) - { - if (current_directory) - download_path = xstrdup (current_directory); - else - error ("Need to know default download path (use 'set download-path')"); - } - - start_time = time (NULL); - monitor_printf ("uhip %s\r", server_addr); - resp_len = monitor_expect_prompt (buf, sizeof (buf)); /* parse result? */ - monitor_printf ("ulip %s\r", board_addr); - resp_len = monitor_expect_prompt (buf, sizeof (buf)); /* parse result? */ - if (args[0] != '/') - monitor_printf ("up %s\r", download_path); /* use default path */ - else - monitor_printf ("up\r"); /* rooted filename/path */ - resp_len = monitor_expect_prompt (buf, sizeof (buf)); /* parse result? */ - - if (strrchr (args, '.') && !strcmp (strrchr (args, '.'), ".srec")) - monitor_printf ("ul %s\r", args); - else /* add ".srec" suffix */ - monitor_printf ("ul %s.srec\r", args); - resp_len = monitor_expect_prompt (buf, sizeof (buf)); /* parse result? */ - - if (buf[0] == 0 || strstr (buf, "complete") == 0) - error ("Upload file not found: %s.srec\nCheck IP addresses and download path.", args); - else - printf_filtered (" -- Ethernet load complete.\n"); - - end_time = time (NULL); - abfd = bfd_openr (args, 0); - if (abfd != NULL) - { /* Download is done -- print section statistics */ - if (bfd_check_format (abfd, bfd_object) == 0) - { - printf_filtered ("File is not an object file\n"); - } - for (s = abfd->sections; s; s = s->next) - if (s->flags & SEC_LOAD) - { - bfd_size_type section_size = bfd_section_size (abfd, s); - bfd_vma section_base = bfd_section_lma (abfd, s); - unsigned int buffer; - - data_count += section_size; - - printf_filtered ("Loading section %s, size 0x%lx lma ", - bfd_section_name (abfd, s), section_size); - print_address_numeric (section_base, 1, gdb_stdout); - printf_filtered ("\n"); - gdb_flush (gdb_stdout); - } - /* Finally, make the PC point at the start address */ - write_pc (bfd_get_start_address (abfd)); - report_transfer_performance (data_count, start_time, end_time); - printf_filtered ("Start address 0x%lx\n", bfd_get_start_address (abfd)); - } - inferior_ptid = null_ptid; /* No process now */ - - /* This is necessary because many things were based on the PC at the - time that we attached to the monitor, which is no longer valid - now that we have loaded new code (and just changed the PC). - Another way to do this might be to call normal_stop, except that - the stack may not be valid, and things would get horribly - confused... */ - - clear_symtab_users (); -} - -void -_initialize_m32r_rom (void) -{ - /* Initialize m32r RevC monitor target */ - init_m32r_cmds (); - init_monitor_ops (&m32r_ops); - - m32r_ops.to_shortname = "m32r"; - m32r_ops.to_longname = "m32r monitor"; - m32r_ops.to_load = m32r_load_gen; /* monitor lacks a download command */ - m32r_ops.to_doc = "Debug via the m32r monitor.\n\ -Specify the serial device it is connected to (e.g. /dev/ttya)."; - m32r_ops.to_open = m32r_open; - add_target (&m32r_ops); - - /* Initialize mon2000 monitor target */ - init_mon2000_cmds (); - init_monitor_ops (&mon2000_ops); - - mon2000_ops.to_shortname = "mon2000"; - mon2000_ops.to_longname = "Mon2000 monitor"; - mon2000_ops.to_load = m32r_load_gen; /* monitor lacks a download command */ - mon2000_ops.to_doc = "Debug via the Mon2000 monitor.\n\ -Specify the serial device it is connected to (e.g. /dev/ttya)."; - mon2000_ops.to_open = mon2000_open; - add_target (&mon2000_ops); - - add_show_from_set - (add_set_cmd ("download-path", class_obscure, var_string, - (char *) &download_path, - "Set the default path for downloadable SREC files.", - &setlist), - &showlist); - - add_show_from_set - (add_set_cmd ("board-address", class_obscure, var_string, - (char *) &board_addr, - "Set IP address for M32R-EVA target board.", - &setlist), - &showlist); - - add_show_from_set - (add_set_cmd ("server-address", class_obscure, var_string, - (char *) &server_addr, - "Set IP address for download server (GDB's host computer).", - &setlist), - &showlist); - - add_com ("upload", class_obscure, m32r_upload_command, - "Upload the srec file via the monitor's Ethernet upload capability."); - - add_com ("tload", class_obscure, m32r_load, "test upload command."); -} +// OBSOLETE /* Remote debugging interface to m32r and mon2000 ROM monitors for GDB, +// OBSOLETE the GNU debugger. +// OBSOLETE Copyright 1996, 1997, 1998, 1999, 2000, 2001 +// OBSOLETE Free Software Foundation, Inc. +// OBSOLETE +// OBSOLETE Adapted by Michael Snyder of Cygnus Support. +// 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 /* This module defines communication with the Mitsubishi m32r monitor */ +// OBSOLETE +// OBSOLETE #include "defs.h" +// OBSOLETE #include "gdbcore.h" +// OBSOLETE #include "target.h" +// OBSOLETE #include "monitor.h" +// OBSOLETE #include "serial.h" +// OBSOLETE #include "symtab.h" +// OBSOLETE #include "command.h" +// OBSOLETE #include "gdbcmd.h" +// OBSOLETE #include "symfile.h" /* for generic load */ +// OBSOLETE #include <time.h> /* for time_t */ +// OBSOLETE #include "gdb_string.h" +// OBSOLETE #include "objfiles.h" /* for ALL_OBJFILES etc. */ +// OBSOLETE #include "inferior.h" /* for write_pc() */ +// OBSOLETE #include <ctype.h> +// OBSOLETE #include "regcache.h" +// OBSOLETE +// OBSOLETE extern void report_transfer_performance (unsigned long, time_t, time_t); +// OBSOLETE +// OBSOLETE /* +// OBSOLETE * All this stuff just to get my host computer's IP address! +// OBSOLETE */ +// OBSOLETE #include <sys/types.h> +// OBSOLETE #include <netdb.h> /* for hostent */ +// OBSOLETE #include <netinet/in.h> /* for struct in_addr */ +// OBSOLETE #if 1 +// OBSOLETE #include <arpa/inet.h> /* for inet_ntoa */ +// OBSOLETE #endif +// OBSOLETE +// OBSOLETE static char *board_addr; /* user-settable IP address for M32R-EVA */ +// OBSOLETE static char *server_addr; /* user-settable IP address for gdb host */ +// OBSOLETE static char *download_path; /* user-settable path for SREC files */ +// OBSOLETE +// OBSOLETE +// OBSOLETE /* +// OBSOLETE * Function: m32r_load_1 (helper function) +// OBSOLETE */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE m32r_load_section (bfd *abfd, asection *s, void *obj) +// OBSOLETE { +// OBSOLETE unsigned int *data_count = obj; +// OBSOLETE if (s->flags & SEC_LOAD) +// OBSOLETE { +// OBSOLETE bfd_size_type section_size = bfd_section_size (abfd, s); +// OBSOLETE bfd_vma section_base = bfd_section_lma (abfd, s); +// OBSOLETE unsigned int buffer, i; +// OBSOLETE +// OBSOLETE *data_count += section_size; +// OBSOLETE +// OBSOLETE printf_filtered ("Loading section %s, size 0x%lx lma ", +// OBSOLETE bfd_section_name (abfd, s), section_size); +// OBSOLETE print_address_numeric (section_base, 1, gdb_stdout); +// OBSOLETE printf_filtered ("\n"); +// OBSOLETE gdb_flush (gdb_stdout); +// OBSOLETE monitor_printf ("%s mw\r", paddr_nz (section_base)); +// OBSOLETE for (i = 0; i < section_size; i += 4) +// OBSOLETE { +// OBSOLETE QUIT; +// OBSOLETE monitor_expect (" -> ", NULL, 0); +// OBSOLETE bfd_get_section_contents (abfd, s, (char *) &buffer, i, 4); +// OBSOLETE monitor_printf ("%x\n", buffer); +// OBSOLETE } +// OBSOLETE monitor_expect (" -> ", NULL, 0); +// OBSOLETE monitor_printf ("q\n"); +// OBSOLETE monitor_expect_prompt (NULL, 0); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE static int +// OBSOLETE m32r_load_1 (void *dummy) +// OBSOLETE { +// OBSOLETE int data_count = 0; +// OBSOLETE +// OBSOLETE bfd_map_over_sections ((bfd *) dummy, m32r_load_section, &data_count); +// OBSOLETE return data_count; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* +// OBSOLETE * Function: m32r_load (an alternate way to load) +// OBSOLETE */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE m32r_load (char *filename, int from_tty) +// OBSOLETE { +// OBSOLETE bfd *abfd; +// OBSOLETE asection *s; +// OBSOLETE unsigned int i, data_count = 0; +// OBSOLETE time_t start_time, end_time; /* for timing of download */ +// OBSOLETE +// OBSOLETE if (filename == NULL || filename[0] == 0) +// OBSOLETE filename = get_exec_file (1); +// OBSOLETE +// OBSOLETE abfd = bfd_openr (filename, 0); +// OBSOLETE if (!abfd) +// OBSOLETE error ("Unable to open file %s\n", filename); +// OBSOLETE if (bfd_check_format (abfd, bfd_object) == 0) +// OBSOLETE error ("File is not an object file\n"); +// OBSOLETE start_time = time (NULL); +// OBSOLETE #if 0 +// OBSOLETE for (s = abfd->sections; s; s = s->next) +// OBSOLETE if (s->flags & SEC_LOAD) +// OBSOLETE { +// OBSOLETE bfd_size_type section_size = bfd_section_size (abfd, s); +// OBSOLETE bfd_vma section_base = bfd_section_vma (abfd, s); +// OBSOLETE unsigned int buffer; +// OBSOLETE +// OBSOLETE data_count += section_size; +// OBSOLETE +// OBSOLETE printf_filtered ("Loading section %s, size 0x%lx vma ", +// OBSOLETE bfd_section_name (abfd, s), section_size); +// OBSOLETE print_address_numeric (section_base, 1, gdb_stdout); +// OBSOLETE printf_filtered ("\n"); +// OBSOLETE gdb_flush (gdb_stdout); +// OBSOLETE monitor_printf ("%x mw\r", section_base); +// OBSOLETE for (i = 0; i < section_size; i += 4) +// OBSOLETE { +// OBSOLETE monitor_expect (" -> ", NULL, 0); +// OBSOLETE bfd_get_section_contents (abfd, s, (char *) &buffer, i, 4); +// OBSOLETE monitor_printf ("%x\n", buffer); +// OBSOLETE } +// OBSOLETE monitor_expect (" -> ", NULL, 0); +// OBSOLETE monitor_printf ("q\n"); +// OBSOLETE monitor_expect_prompt (NULL, 0); +// OBSOLETE } +// OBSOLETE #else +// OBSOLETE if (!(catch_errors (m32r_load_1, abfd, "Load aborted!\n", RETURN_MASK_ALL))) +// OBSOLETE { +// OBSOLETE monitor_printf ("q\n"); +// OBSOLETE return; +// OBSOLETE } +// OBSOLETE #endif +// OBSOLETE end_time = time (NULL); +// OBSOLETE printf_filtered ("Start address 0x%lx\n", bfd_get_start_address (abfd)); +// OBSOLETE report_transfer_performance (data_count, start_time, end_time); +// OBSOLETE +// OBSOLETE /* Finally, make the PC point at the start address */ +// OBSOLETE if (exec_bfd) +// OBSOLETE write_pc (bfd_get_start_address (exec_bfd)); +// OBSOLETE +// OBSOLETE inferior_ptid = null_ptid; /* No process now */ +// OBSOLETE +// OBSOLETE /* This is necessary because many things were based on the PC at the +// OBSOLETE time that we attached to the monitor, which is no longer valid +// OBSOLETE now that we have loaded new code (and just changed the PC). +// OBSOLETE Another way to do this might be to call normal_stop, except that +// OBSOLETE the stack may not be valid, and things would get horribly +// OBSOLETE confused... */ +// OBSOLETE +// OBSOLETE clear_symtab_users (); +// OBSOLETE } +// OBSOLETE +// OBSOLETE static void +// OBSOLETE m32r_load_gen (char *filename, int from_tty) +// OBSOLETE { +// OBSOLETE generic_load (filename, from_tty); +// OBSOLETE } +// OBSOLETE +// OBSOLETE static void m32r_open (char *args, int from_tty); +// OBSOLETE static void mon2000_open (char *args, int from_tty); +// OBSOLETE +// OBSOLETE /* This array of registers needs to match the indexes used by GDB. The +// OBSOLETE whole reason this exists is because the various ROM monitors use +// OBSOLETE different names than GDB does, and don't support all the registers +// OBSOLETE either. So, typing "info reg sp" becomes an "A7". */ +// OBSOLETE +// OBSOLETE static char *m32r_regnames[] = +// OBSOLETE {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", +// OBSOLETE "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", +// OBSOLETE "psw", "cbr", "spi", "spu", "bpc", "pc", "accl", "acch", +// OBSOLETE }; +// OBSOLETE +// OBSOLETE static void +// OBSOLETE m32r_supply_register (char *regname, int regnamelen, char *val, int vallen) +// OBSOLETE { +// OBSOLETE int regno; +// OBSOLETE int num_regs = sizeof (m32r_regnames) / sizeof (m32r_regnames[0]); +// OBSOLETE +// OBSOLETE for (regno = 0; regno < num_regs; regno++) +// OBSOLETE if (strncmp (regname, m32r_regnames[regno], regnamelen) == 0) +// OBSOLETE break; +// OBSOLETE +// OBSOLETE if (regno >= num_regs) +// OBSOLETE return; /* no match */ +// OBSOLETE +// OBSOLETE if (regno == ACCL_REGNUM) +// OBSOLETE { /* special handling for 64-bit acc reg */ +// OBSOLETE monitor_supply_register (ACCH_REGNUM, val); +// OBSOLETE val = strchr (val, ':'); /* skip past ':' to get 2nd word */ +// OBSOLETE if (val != NULL) +// OBSOLETE monitor_supply_register (ACCL_REGNUM, val + 1); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE monitor_supply_register (regno, val); +// OBSOLETE if (regno == PSW_REGNUM) +// OBSOLETE { +// OBSOLETE unsigned long psw = strtoul (val, NULL, 16); +// OBSOLETE char *zero = "00000000", *one = "00000001"; +// OBSOLETE +// OBSOLETE #ifdef SM_REGNUM +// OBSOLETE /* Stack mode bit */ +// OBSOLETE monitor_supply_register (SM_REGNUM, (psw & 0x80) ? one : zero); +// OBSOLETE #endif +// OBSOLETE #ifdef BSM_REGNUM +// OBSOLETE /* Backup stack mode bit */ +// OBSOLETE monitor_supply_register (BSM_REGNUM, (psw & 0x8000) ? one : zero); +// OBSOLETE #endif +// OBSOLETE #ifdef IE_REGNUM +// OBSOLETE /* Interrupt enable bit */ +// OBSOLETE monitor_supply_register (IE_REGNUM, (psw & 0x40) ? one : zero); +// OBSOLETE #endif +// OBSOLETE #ifdef BIE_REGNUM +// OBSOLETE /* Backup interrupt enable bit */ +// OBSOLETE monitor_supply_register (BIE_REGNUM, (psw & 0x4000) ? one : zero); +// OBSOLETE #endif +// OBSOLETE #ifdef COND_REGNUM +// OBSOLETE /* Condition bit (carry etc.) */ +// OBSOLETE monitor_supply_register (COND_REGNUM, (psw & 0x1) ? one : zero); +// OBSOLETE #endif +// OBSOLETE #ifdef CBR_REGNUM +// OBSOLETE monitor_supply_register (CBR_REGNUM, (psw & 0x1) ? one : zero); +// OBSOLETE #endif +// OBSOLETE #ifdef BPC_REGNUM +// OBSOLETE monitor_supply_register (BPC_REGNUM, zero); /* KLUDGE: (???????) */ +// OBSOLETE #endif +// OBSOLETE #ifdef BCARRY_REGNUM +// OBSOLETE monitor_supply_register (BCARRY_REGNUM, zero); /* KLUDGE: (??????) */ +// OBSOLETE #endif +// OBSOLETE } +// OBSOLETE +// OBSOLETE if (regno == SPI_REGNUM || regno == SPU_REGNUM) +// OBSOLETE { /* special handling for stack pointer (spu or spi) */ +// OBSOLETE unsigned long stackmode = read_register (PSW_REGNUM) & 0x80; +// OBSOLETE +// OBSOLETE if (regno == SPI_REGNUM && !stackmode) /* SP == SPI */ +// OBSOLETE monitor_supply_register (SP_REGNUM, val); +// OBSOLETE else if (regno == SPU_REGNUM && stackmode) /* SP == SPU */ +// OBSOLETE monitor_supply_register (SP_REGNUM, val); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* m32r RevC board monitor */ +// OBSOLETE +// OBSOLETE static struct target_ops m32r_ops; +// OBSOLETE +// OBSOLETE static char *m32r_inits[] = +// OBSOLETE {"\r", NULL}; +// OBSOLETE +// OBSOLETE static struct monitor_ops m32r_cmds; +// OBSOLETE +// OBSOLETE static void +// OBSOLETE init_m32r_cmds (void) +// OBSOLETE { +// OBSOLETE m32r_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_REGISTER_VALUE_FIRST; +// OBSOLETE m32r_cmds.init = m32r_inits; /* Init strings */ +// OBSOLETE m32r_cmds.cont = "go\r"; /* continue command */ +// OBSOLETE m32r_cmds.step = "step\r"; /* single step */ +// OBSOLETE m32r_cmds.stop = NULL; /* interrupt command */ +// OBSOLETE m32r_cmds.set_break = "%x +bp\r"; /* set a breakpoint */ +// OBSOLETE m32r_cmds.clr_break = "%x -bp\r"; /* clear a breakpoint */ +// OBSOLETE m32r_cmds.clr_all_break = "bpoff\r"; /* clear all breakpoints */ +// OBSOLETE m32r_cmds.fill = "%x %x %x fill\r"; /* fill (start length val) */ +// OBSOLETE m32r_cmds.setmem.cmdb = "%x 1 %x fill\r"; /* setmem.cmdb (addr, value) */ +// OBSOLETE m32r_cmds.setmem.cmdw = "%x 1 %x fillh\r"; /* setmem.cmdw (addr, value) */ +// OBSOLETE m32r_cmds.setmem.cmdl = "%x 1 %x fillw\r"; /* setmem.cmdl (addr, value) */ +// OBSOLETE m32r_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */ +// OBSOLETE m32r_cmds.setmem.resp_delim = NULL; /* setmem.resp_delim */ +// OBSOLETE m32r_cmds.setmem.term = NULL; /* setmem.term */ +// OBSOLETE m32r_cmds.setmem.term_cmd = NULL; /* setmem.term_cmd */ +// OBSOLETE m32r_cmds.getmem.cmdb = "%x %x dump\r"; /* getmem.cmdb (addr, len) */ +// OBSOLETE m32r_cmds.getmem.cmdw = NULL; /* getmem.cmdw (addr, len) */ +// OBSOLETE m32r_cmds.getmem.cmdl = NULL; /* getmem.cmdl (addr, len) */ +// OBSOLETE m32r_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */ +// OBSOLETE m32r_cmds.getmem.resp_delim = ": "; /* getmem.resp_delim */ +// OBSOLETE m32r_cmds.getmem.term = NULL; /* getmem.term */ +// OBSOLETE m32r_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */ +// OBSOLETE m32r_cmds.setreg.cmd = "%x to %%%s\r"; /* setreg.cmd (name, value) */ +// OBSOLETE m32r_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */ +// OBSOLETE m32r_cmds.setreg.term = NULL; /* setreg.term */ +// OBSOLETE m32r_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */ +// OBSOLETE m32r_cmds.getreg.cmd = NULL; /* getreg.cmd (name) */ +// OBSOLETE m32r_cmds.getreg.resp_delim = NULL; /* getreg.resp_delim */ +// OBSOLETE m32r_cmds.getreg.term = NULL; /* getreg.term */ +// OBSOLETE m32r_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */ +// OBSOLETE m32r_cmds.dump_registers = ".reg\r"; /* dump_registers */ +// OBSOLETE m32r_cmds.register_pattern = "\\(\\w+\\) += \\([0-9a-fA-F]+\\b\\)"; /* register_pattern */ +// OBSOLETE m32r_cmds.supply_register = m32r_supply_register; /* supply_register */ +// OBSOLETE m32r_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */ +// OBSOLETE m32r_cmds.load = NULL; /* download command */ +// OBSOLETE m32r_cmds.loadresp = NULL; /* load response */ +// OBSOLETE m32r_cmds.prompt = "ok "; /* monitor command prompt */ +// OBSOLETE m32r_cmds.line_term = "\r"; /* end-of-line terminator */ +// OBSOLETE m32r_cmds.cmd_end = NULL; /* optional command terminator */ +// OBSOLETE m32r_cmds.target = &m32r_ops; /* target operations */ +// OBSOLETE m32r_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */ +// OBSOLETE m32r_cmds.regnames = m32r_regnames; /* registers names */ +// OBSOLETE m32r_cmds.magic = MONITOR_OPS_MAGIC; /* magic */ +// OBSOLETE } /* init_m32r_cmds */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE m32r_open (char *args, int from_tty) +// OBSOLETE { +// OBSOLETE monitor_open (args, &m32r_cmds, from_tty); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Mon2000 monitor (MSA2000 board) */ +// OBSOLETE +// OBSOLETE static struct target_ops mon2000_ops; +// OBSOLETE static struct monitor_ops mon2000_cmds; +// OBSOLETE +// OBSOLETE static void +// OBSOLETE init_mon2000_cmds (void) +// OBSOLETE { +// OBSOLETE mon2000_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_REGISTER_VALUE_FIRST; +// OBSOLETE mon2000_cmds.init = m32r_inits; /* Init strings */ +// OBSOLETE mon2000_cmds.cont = "go\r"; /* continue command */ +// OBSOLETE mon2000_cmds.step = "step\r"; /* single step */ +// OBSOLETE mon2000_cmds.stop = NULL; /* interrupt command */ +// OBSOLETE mon2000_cmds.set_break = "%x +bp\r"; /* set a breakpoint */ +// OBSOLETE mon2000_cmds.clr_break = "%x -bp\r"; /* clear a breakpoint */ +// OBSOLETE mon2000_cmds.clr_all_break = "bpoff\r"; /* clear all breakpoints */ +// OBSOLETE mon2000_cmds.fill = "%x %x %x fill\r"; /* fill (start length val) */ +// OBSOLETE mon2000_cmds.setmem.cmdb = "%x 1 %x fill\r"; /* setmem.cmdb (addr, value) */ +// OBSOLETE mon2000_cmds.setmem.cmdw = "%x 1 %x fillh\r"; /* setmem.cmdw (addr, value) */ +// OBSOLETE mon2000_cmds.setmem.cmdl = "%x 1 %x fillw\r"; /* setmem.cmdl (addr, value) */ +// OBSOLETE mon2000_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */ +// OBSOLETE mon2000_cmds.setmem.resp_delim = NULL; /* setmem.resp_delim */ +// OBSOLETE mon2000_cmds.setmem.term = NULL; /* setmem.term */ +// OBSOLETE mon2000_cmds.setmem.term_cmd = NULL; /* setmem.term_cmd */ +// OBSOLETE mon2000_cmds.getmem.cmdb = "%x %x dump\r"; /* getmem.cmdb (addr, len) */ +// OBSOLETE mon2000_cmds.getmem.cmdw = NULL; /* getmem.cmdw (addr, len) */ +// OBSOLETE mon2000_cmds.getmem.cmdl = NULL; /* getmem.cmdl (addr, len) */ +// OBSOLETE mon2000_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */ +// OBSOLETE mon2000_cmds.getmem.resp_delim = ": "; /* getmem.resp_delim */ +// OBSOLETE mon2000_cmds.getmem.term = NULL; /* getmem.term */ +// OBSOLETE mon2000_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */ +// OBSOLETE mon2000_cmds.setreg.cmd = "%x to %%%s\r"; /* setreg.cmd (name, value) */ +// OBSOLETE mon2000_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */ +// OBSOLETE mon2000_cmds.setreg.term = NULL; /* setreg.term */ +// OBSOLETE mon2000_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */ +// OBSOLETE mon2000_cmds.getreg.cmd = NULL; /* getreg.cmd (name) */ +// OBSOLETE mon2000_cmds.getreg.resp_delim = NULL; /* getreg.resp_delim */ +// OBSOLETE mon2000_cmds.getreg.term = NULL; /* getreg.term */ +// OBSOLETE mon2000_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */ +// OBSOLETE mon2000_cmds.dump_registers = ".reg\r"; /* dump_registers */ +// OBSOLETE mon2000_cmds.register_pattern = "\\(\\w+\\) += \\([0-9a-fA-F]+\\b\\)"; /* register_pattern */ +// OBSOLETE mon2000_cmds.supply_register = m32r_supply_register; /* supply_register */ +// OBSOLETE mon2000_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */ +// OBSOLETE mon2000_cmds.load = NULL; /* download command */ +// OBSOLETE mon2000_cmds.loadresp = NULL; /* load response */ +// OBSOLETE mon2000_cmds.prompt = "Mon2000>"; /* monitor command prompt */ +// OBSOLETE mon2000_cmds.line_term = "\r"; /* end-of-line terminator */ +// OBSOLETE mon2000_cmds.cmd_end = NULL; /* optional command terminator */ +// OBSOLETE mon2000_cmds.target = &mon2000_ops; /* target operations */ +// OBSOLETE mon2000_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */ +// OBSOLETE mon2000_cmds.regnames = m32r_regnames; /* registers names */ +// OBSOLETE mon2000_cmds.magic = MONITOR_OPS_MAGIC; /* magic */ +// OBSOLETE } /* init_mon2000_cmds */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE mon2000_open (char *args, int from_tty) +// OBSOLETE { +// OBSOLETE monitor_open (args, &mon2000_cmds, from_tty); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Function: set_board_address +// OBSOLETE Tell the BootOne monitor what it's ethernet IP address is. */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE m32r_set_board_address (char *args, int from_tty) +// OBSOLETE { +// OBSOLETE int resp_len; +// OBSOLETE char buf[1024]; +// OBSOLETE +// OBSOLETE if (args && *args) +// OBSOLETE { +// OBSOLETE monitor_printf ("ulip %s\n", args); +// OBSOLETE resp_len = monitor_expect_prompt (buf, sizeof (buf)); +// OBSOLETE /* now parse the result for success */ +// OBSOLETE } +// OBSOLETE else +// OBSOLETE error ("Requires argument (IP address for M32R-EVA board)"); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Function: set_server_address +// OBSOLETE Tell the BootOne monitor what gdb's ethernet IP address is. */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE m32r_set_server_address (char *args, int from_tty) +// OBSOLETE { +// OBSOLETE int resp_len; +// OBSOLETE char buf[1024]; +// OBSOLETE +// OBSOLETE if (args && *args) +// OBSOLETE { +// OBSOLETE monitor_printf ("uhip %s\n", args); +// OBSOLETE resp_len = monitor_expect_prompt (buf, sizeof (buf)); +// OBSOLETE /* now parse the result for success */ +// OBSOLETE } +// OBSOLETE else +// OBSOLETE error ("Requires argument (IP address of GDB's host computer)"); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Function: set_download_path +// OBSOLETE Tell the BootOne monitor the default path for downloadable SREC files. */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE m32r_set_download_path (char *args, int from_tty) +// OBSOLETE { +// OBSOLETE int resp_len; +// OBSOLETE char buf[1024]; +// OBSOLETE +// OBSOLETE if (args && *args) +// OBSOLETE { +// OBSOLETE monitor_printf ("up %s\n", args); +// OBSOLETE resp_len = monitor_expect_prompt (buf, sizeof (buf)); +// OBSOLETE /* now parse the result for success */ +// OBSOLETE } +// OBSOLETE else +// OBSOLETE error ("Requires argument (default path for downloadable SREC files)"); +// OBSOLETE } +// OBSOLETE +// OBSOLETE static void +// OBSOLETE m32r_upload_command (char *args, int from_tty) +// OBSOLETE { +// OBSOLETE bfd *abfd; +// OBSOLETE asection *s; +// OBSOLETE time_t start_time, end_time; /* for timing of download */ +// OBSOLETE int resp_len, data_count = 0; +// OBSOLETE char buf[1024]; +// OBSOLETE struct hostent *hostent; +// OBSOLETE struct in_addr inet_addr; +// OBSOLETE +// OBSOLETE /* first check to see if there's an ethernet port! */ +// OBSOLETE monitor_printf ("ust\r"); +// OBSOLETE resp_len = monitor_expect_prompt (buf, sizeof (buf)); +// OBSOLETE if (!strchr (buf, ':')) +// OBSOLETE error ("No ethernet connection!"); +// OBSOLETE +// OBSOLETE if (board_addr == 0) +// OBSOLETE { +// OBSOLETE /* scan second colon in the output from the "ust" command */ +// OBSOLETE char *myIPaddress = strchr (strchr (buf, ':') + 1, ':') + 1; +// OBSOLETE +// OBSOLETE while (isspace (*myIPaddress)) +// OBSOLETE myIPaddress++; +// OBSOLETE +// OBSOLETE if (!strncmp (myIPaddress, "0.0.", 4)) /* empty */ +// OBSOLETE error ("Please use 'set board-address' to set the M32R-EVA board's IP address."); +// OBSOLETE if (strchr (myIPaddress, '(')) +// OBSOLETE *(strchr (myIPaddress, '(')) = '\0'; /* delete trailing junk */ +// OBSOLETE board_addr = xstrdup (myIPaddress); +// OBSOLETE } +// OBSOLETE if (server_addr == 0) +// OBSOLETE { +// OBSOLETE buf[0] = 0; +// OBSOLETE gethostname (buf, sizeof (buf)); +// OBSOLETE if (buf[0] != 0) +// OBSOLETE hostent = gethostbyname (buf); +// OBSOLETE if (hostent != 0) +// OBSOLETE { +// OBSOLETE #if 1 +// OBSOLETE memcpy (&inet_addr.s_addr, hostent->h_addr, +// OBSOLETE sizeof (inet_addr.s_addr)); +// OBSOLETE server_addr = (char *) inet_ntoa (inet_addr); +// OBSOLETE #else +// OBSOLETE server_addr = (char *) inet_ntoa (hostent->h_addr); +// OBSOLETE #endif +// OBSOLETE } +// OBSOLETE if (server_addr == 0) /* failed? */ +// OBSOLETE error ("Need to know gdb host computer's IP address (use 'set server-address')"); +// OBSOLETE } +// OBSOLETE +// OBSOLETE if (args == 0 || args[0] == 0) /* no args: upload the current file */ +// OBSOLETE args = get_exec_file (1); +// OBSOLETE +// OBSOLETE if (args[0] != '/' && download_path == 0) +// OBSOLETE { +// OBSOLETE if (current_directory) +// OBSOLETE download_path = xstrdup (current_directory); +// OBSOLETE else +// OBSOLETE error ("Need to know default download path (use 'set download-path')"); +// OBSOLETE } +// OBSOLETE +// OBSOLETE start_time = time (NULL); +// OBSOLETE monitor_printf ("uhip %s\r", server_addr); +// OBSOLETE resp_len = monitor_expect_prompt (buf, sizeof (buf)); /* parse result? */ +// OBSOLETE monitor_printf ("ulip %s\r", board_addr); +// OBSOLETE resp_len = monitor_expect_prompt (buf, sizeof (buf)); /* parse result? */ +// OBSOLETE if (args[0] != '/') +// OBSOLETE monitor_printf ("up %s\r", download_path); /* use default path */ +// OBSOLETE else +// OBSOLETE monitor_printf ("up\r"); /* rooted filename/path */ +// OBSOLETE resp_len = monitor_expect_prompt (buf, sizeof (buf)); /* parse result? */ +// OBSOLETE +// OBSOLETE if (strrchr (args, '.') && !strcmp (strrchr (args, '.'), ".srec")) +// OBSOLETE monitor_printf ("ul %s\r", args); +// OBSOLETE else /* add ".srec" suffix */ +// OBSOLETE monitor_printf ("ul %s.srec\r", args); +// OBSOLETE resp_len = monitor_expect_prompt (buf, sizeof (buf)); /* parse result? */ +// OBSOLETE +// OBSOLETE if (buf[0] == 0 || strstr (buf, "complete") == 0) +// OBSOLETE error ("Upload file not found: %s.srec\nCheck IP addresses and download path.", args); +// OBSOLETE else +// OBSOLETE printf_filtered (" -- Ethernet load complete.\n"); +// OBSOLETE +// OBSOLETE end_time = time (NULL); +// OBSOLETE abfd = bfd_openr (args, 0); +// OBSOLETE if (abfd != NULL) +// OBSOLETE { /* Download is done -- print section statistics */ +// OBSOLETE if (bfd_check_format (abfd, bfd_object) == 0) +// OBSOLETE { +// OBSOLETE printf_filtered ("File is not an object file\n"); +// OBSOLETE } +// OBSOLETE for (s = abfd->sections; s; s = s->next) +// OBSOLETE if (s->flags & SEC_LOAD) +// OBSOLETE { +// OBSOLETE bfd_size_type section_size = bfd_section_size (abfd, s); +// OBSOLETE bfd_vma section_base = bfd_section_lma (abfd, s); +// OBSOLETE unsigned int buffer; +// OBSOLETE +// OBSOLETE data_count += section_size; +// OBSOLETE +// OBSOLETE printf_filtered ("Loading section %s, size 0x%lx lma ", +// OBSOLETE bfd_section_name (abfd, s), section_size); +// OBSOLETE print_address_numeric (section_base, 1, gdb_stdout); +// OBSOLETE printf_filtered ("\n"); +// OBSOLETE gdb_flush (gdb_stdout); +// OBSOLETE } +// OBSOLETE /* Finally, make the PC point at the start address */ +// OBSOLETE write_pc (bfd_get_start_address (abfd)); +// OBSOLETE report_transfer_performance (data_count, start_time, end_time); +// OBSOLETE printf_filtered ("Start address 0x%lx\n", bfd_get_start_address (abfd)); +// OBSOLETE } +// OBSOLETE inferior_ptid = null_ptid; /* No process now */ +// OBSOLETE +// OBSOLETE /* This is necessary because many things were based on the PC at the +// OBSOLETE time that we attached to the monitor, which is no longer valid +// OBSOLETE now that we have loaded new code (and just changed the PC). +// OBSOLETE Another way to do this might be to call normal_stop, except that +// OBSOLETE the stack may not be valid, and things would get horribly +// OBSOLETE confused... */ +// OBSOLETE +// OBSOLETE clear_symtab_users (); +// OBSOLETE } +// OBSOLETE +// OBSOLETE void +// OBSOLETE _initialize_m32r_rom (void) +// OBSOLETE { +// OBSOLETE /* Initialize m32r RevC monitor target */ +// OBSOLETE init_m32r_cmds (); +// OBSOLETE init_monitor_ops (&m32r_ops); +// OBSOLETE +// OBSOLETE m32r_ops.to_shortname = "m32r"; +// OBSOLETE m32r_ops.to_longname = "m32r monitor"; +// OBSOLETE m32r_ops.to_load = m32r_load_gen; /* monitor lacks a download command */ +// OBSOLETE m32r_ops.to_doc = "Debug via the m32r monitor.\n\ +// OBSOLETE Specify the serial device it is connected to (e.g. /dev/ttya)."; +// OBSOLETE m32r_ops.to_open = m32r_open; +// OBSOLETE add_target (&m32r_ops); +// OBSOLETE +// OBSOLETE /* Initialize mon2000 monitor target */ +// OBSOLETE init_mon2000_cmds (); +// OBSOLETE init_monitor_ops (&mon2000_ops); +// OBSOLETE +// OBSOLETE mon2000_ops.to_shortname = "mon2000"; +// OBSOLETE mon2000_ops.to_longname = "Mon2000 monitor"; +// OBSOLETE mon2000_ops.to_load = m32r_load_gen; /* monitor lacks a download command */ +// OBSOLETE mon2000_ops.to_doc = "Debug via the Mon2000 monitor.\n\ +// OBSOLETE Specify the serial device it is connected to (e.g. /dev/ttya)."; +// OBSOLETE mon2000_ops.to_open = mon2000_open; +// OBSOLETE add_target (&mon2000_ops); +// OBSOLETE +// OBSOLETE add_show_from_set +// OBSOLETE (add_set_cmd ("download-path", class_obscure, var_string, +// OBSOLETE (char *) &download_path, +// OBSOLETE "Set the default path for downloadable SREC files.", +// OBSOLETE &setlist), +// OBSOLETE &showlist); +// OBSOLETE +// OBSOLETE add_show_from_set +// OBSOLETE (add_set_cmd ("board-address", class_obscure, var_string, +// OBSOLETE (char *) &board_addr, +// OBSOLETE "Set IP address for M32R-EVA target board.", +// OBSOLETE &setlist), +// OBSOLETE &showlist); +// OBSOLETE +// OBSOLETE add_show_from_set +// OBSOLETE (add_set_cmd ("server-address", class_obscure, var_string, +// OBSOLETE (char *) &server_addr, +// OBSOLETE "Set IP address for download server (GDB's host computer).", +// OBSOLETE &setlist), +// OBSOLETE &showlist); +// OBSOLETE +// OBSOLETE add_com ("upload", class_obscure, m32r_upload_command, +// OBSOLETE "Upload the srec file via the monitor's Ethernet upload capability."); +// OBSOLETE +// OBSOLETE add_com ("tload", class_obscure, m32r_load, "test upload command."); +// OBSOLETE } diff --git a/gdb/m32r-stub.c b/gdb/m32r-stub.c index 2e69b4403ea..d9be3eb84e6 100644 --- a/gdb/m32r-stub.c +++ b/gdb/m32r-stub.c @@ -1,1718 +1,1718 @@ -/**************************************************************************** - - THIS SOFTWARE IS NOT COPYRIGHTED - - HP offers the following for use in the public domain. HP makes no - warranty with regard to the software or it's performance and the - user accepts the software "AS IS" with all faults. - - HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD - TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - -****************************************************************************/ - -/**************************************************************************** - * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $ - * - * Module name: remcom.c $ - * Revision: 1.34 $ - * Date: 91/03/09 12:29:49 $ - * Contributor: Lake Stevens Instrument Division$ - * - * Description: low level support for gdb debugger. $ - * - * Considerations: only works on target hardware $ - * - * Written by: Glenn Engel $ - * ModuleState: Experimental $ - * - * NOTES: See Below $ - * - * Modified for M32R by Michael Snyder, Cygnus Support. - * - * To enable debugger support, two things need to happen. One, a - * call to set_debug_traps() is necessary in order to allow any breakpoints - * or error conditions to be properly intercepted and reported to gdb. - * Two, a breakpoint needs to be generated to begin communication. This - * is most easily accomplished by a call to breakpoint(). Breakpoint() - * simulates a breakpoint by executing a trap #1. - * - * The external function exceptionHandler() is - * used to attach a specific handler to a specific M32R vector number. - * It should use the same privilege level it runs at. It should - * install it as an interrupt gate so that interrupts are masked - * while the handler runs. - * - * Because gdb will sometimes write to the stack area to execute function - * calls, this program cannot rely on using the supervisor stack so it - * uses it's own stack area reserved in the int array remcomStack. - * - ************* - * - * The following gdb commands are supported: - * - * command function Return value - * - * g return the value of the CPU registers hex data or ENN - * G set the value of the CPU registers OK or ENN - * - * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN - * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN - * XAA..AA,LLLL: Write LLLL binary bytes at address OK or ENN - * AA..AA - * - * c Resume at current address SNN ( signal NN) - * cAA..AA Continue at address AA..AA SNN - * - * s Step one instruction SNN - * sAA..AA Step one instruction from AA..AA SNN - * - * k kill - * - * ? What was the last sigval ? SNN (signal NN) - * - * All commands and responses are sent with a packet which includes a - * checksum. A packet consists of - * - * $<packet info>#<checksum>. - * - * where - * <packet info> :: <characters representing the command or response> - * <checksum> :: <two hex digits computed as modulo 256 sum of <packetinfo>> - * - * When a packet is received, it is first acknowledged with either '+' or '-'. - * '+' indicates a successful transfer. '-' indicates a failed transfer. - * - * Example: - * - * Host: Reply: - * $m0,10#2a +$00010203040506070809101112131415#42 - * - ****************************************************************************/ - - -/************************************************************************ - * - * external low-level support routines - */ -extern void putDebugChar(); /* write a single character */ -extern int getDebugChar(); /* read and return a single char */ -extern void exceptionHandler(); /* assign an exception handler */ - -/***************************************************************************** - * BUFMAX defines the maximum number of characters in inbound/outbound buffers - * at least NUMREGBYTES*2 are needed for register packets - */ -#define BUFMAX 400 - -static char initialized; /* boolean flag. != 0 means we've been initialized */ - -int remote_debug; -/* debug > 0 prints ill-formed commands in valid packets & checksum errors */ - -static const unsigned char hexchars[]="0123456789abcdef"; - -#define NUMREGS 24 - -/* Number of bytes of registers. */ -#define NUMREGBYTES (NUMREGS * 4) -enum regnames { R0, R1, R2, R3, R4, R5, R6, R7, - R8, R9, R10, R11, R12, R13, R14, R15, - PSW, CBR, SPI, SPU, BPC, PC, ACCL, ACCH }; - -enum SYS_calls { - SYS_null, - SYS_exit, - SYS_open, - SYS_close, - SYS_read, - SYS_write, - SYS_lseek, - SYS_unlink, - SYS_getpid, - SYS_kill, - SYS_fstat, - SYS_sbrk, - SYS_fork, - SYS_execve, - SYS_wait4, - SYS_link, - SYS_chdir, - SYS_stat, - SYS_utime, - SYS_chown, - SYS_chmod, - SYS_time, - SYS_pipe }; - -static int registers[NUMREGS]; - -#define STACKSIZE 8096 -static unsigned char remcomInBuffer[BUFMAX]; -static unsigned char remcomOutBuffer[BUFMAX]; -static int remcomStack[STACKSIZE/sizeof(int)]; -static int* stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1]; - -static unsigned int save_vectors[18]; /* previous exception vectors */ - -/* Indicate to caller of mem2hex or hex2mem that there has been an error. */ -static volatile int mem_err = 0; - -/* Store the vector number here (since GDB only gets the signal - number through the usual means, and that's not very specific). */ -int gdb_m32r_vector = -1; - -#if 0 -#include "syscall.h" /* for SYS_exit, SYS_write etc. */ -#endif - -/* Global entry points: - */ - -extern void handle_exception(int); -extern void set_debug_traps(void); -extern void breakpoint(void); - -/* Local functions: - */ - -static int computeSignal(int); -static void putpacket(unsigned char *); -static unsigned char *getpacket(void); - -static unsigned char *mem2hex(unsigned char *, unsigned char *, int, int); -static unsigned char *hex2mem(unsigned char *, unsigned char *, int, int); -static int hexToInt(unsigned char **, int *); -static unsigned char *bin2mem(unsigned char *, unsigned char *, int, int); -static void stash_registers(void); -static void restore_registers(void); -static int prepare_to_step(int); -static int finish_from_step(void); -static unsigned long crc32 (unsigned char *, int, unsigned long); - -static void gdb_error(char *, char *); -static int gdb_putchar(int), gdb_puts(char *), gdb_write(char *, int); - -static unsigned char *strcpy (unsigned char *, const unsigned char *); -static int strlen (const unsigned char *); - -/* - * This function does all command procesing for interfacing to gdb. - */ - -void -handle_exception(int exceptionVector) -{ - int sigval, stepping; - int addr, length, i; - unsigned char * ptr; - unsigned char buf[16]; - int binary; - - /* Do not call finish_from_step() if this is not a trap #1 - * (breakpoint trap). Without this check, the finish_from_step() - * might interpret a system call trap as a single step trap. This - * can happen if: the stub receives 's' and exits, but an interrupt - * was pending; the interrupt is now handled and causes the stub to - * be reentered because some function makes a system call. - */ - if (exceptionVector == 1) /* Trap exception? */ - if (!finish_from_step()) /* Go see if stepping state needs update. */ - return; /* "false step": let the target continue */ - - gdb_m32r_vector = exceptionVector; - - if (remote_debug) - { - mem2hex((unsigned char *) &exceptionVector, buf, 4, 0); - gdb_error("Handle exception %s, ", buf); - mem2hex((unsigned char *) ®isters[PC], buf, 4, 0); - gdb_error("PC == 0x%s\n", buf); - } - - /* reply to host that an exception has occurred */ - sigval = computeSignal( exceptionVector ); - - ptr = remcomOutBuffer; - - *ptr++ = 'T'; /* notify gdb with signo, PC, FP and SP */ - *ptr++ = hexchars[sigval >> 4]; - *ptr++ = hexchars[sigval & 0xf]; - - *ptr++ = hexchars[PC >> 4]; - *ptr++ = hexchars[PC & 0xf]; - *ptr++ = ':'; - ptr = mem2hex((unsigned char *)®isters[PC], ptr, 4, 0); /* PC */ - *ptr++ = ';'; - - *ptr++ = hexchars[R13 >> 4]; - *ptr++ = hexchars[R13 & 0xf]; - *ptr++ = ':'; - ptr = mem2hex((unsigned char *)®isters[R13], ptr, 4, 0); /* FP */ - *ptr++ = ';'; - - *ptr++ = hexchars[R15 >> 4]; - *ptr++ = hexchars[R15 & 0xf]; - *ptr++ = ':'; - ptr = mem2hex((unsigned char *)®isters[R15], ptr, 4, 0); /* SP */ - *ptr++ = ';'; - *ptr++ = 0; - - if (exceptionVector == 0) /* simulated SYS call stuff */ - { - mem2hex((unsigned char *) ®isters[PC], buf, 4, 0); - switch (registers[R0]) { - case SYS_exit: - gdb_error("Target program has exited at %s\n", buf); - ptr = remcomOutBuffer; - *ptr++ = 'W'; - sigval = registers[R1] & 0xff; - *ptr++ = hexchars[sigval >> 4]; - *ptr++ = hexchars[sigval & 0xf]; - *ptr++ = 0; - break; - case SYS_open: - gdb_error("Target attempts SYS_open call at %s\n", buf); - break; - case SYS_close: - gdb_error("Target attempts SYS_close call at %s\n", buf); - break; - case SYS_read: - gdb_error("Target attempts SYS_read call at %s\n", buf); - break; - case SYS_write: - if (registers[R1] == 1 || /* write to stdout */ - registers[R1] == 2) /* write to stderr */ - { /* (we can do that) */ - registers[R0] = gdb_write((void *) registers[R2], registers[R3]); - return; - } - else - gdb_error("Target attempts SYS_write call at %s\n", buf); - break; - case SYS_lseek: - gdb_error("Target attempts SYS_lseek call at %s\n", buf); - break; - case SYS_unlink: - gdb_error("Target attempts SYS_unlink call at %s\n", buf); - break; - case SYS_getpid: - gdb_error("Target attempts SYS_getpid call at %s\n", buf); - break; - case SYS_kill: - gdb_error("Target attempts SYS_kill call at %s\n", buf); - break; - case SYS_fstat: - gdb_error("Target attempts SYS_fstat call at %s\n", buf); - break; - default: - gdb_error("Target attempts unknown SYS call at %s\n", buf); - break; - } - } - - putpacket(remcomOutBuffer); - - stepping = 0; - - while (1==1) { - remcomOutBuffer[0] = 0; - ptr = getpacket(); - binary = 0; - switch (*ptr++) { - default: /* Unknown code. Return an empty reply message. */ - break; - case 'R': - if (hexToInt (&ptr, &addr)) - registers[PC] = addr; - strcpy(remcomOutBuffer, "OK"); - break; - case '!': - strcpy(remcomOutBuffer, "OK"); - break; - case 'X': /* XAA..AA,LLLL:<binary data>#cs */ - binary = 1; - case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ - /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */ - { - if (hexToInt(&ptr,&addr)) - if (*(ptr++) == ',') - if (hexToInt(&ptr,&length)) - if (*(ptr++) == ':') - { - mem_err = 0; - if (binary) - bin2mem (ptr, (unsigned char *) addr, length, 1); - else - hex2mem(ptr, (unsigned char*) addr, length, 1); - if (mem_err) { - strcpy (remcomOutBuffer, "E03"); - gdb_error ("memory fault", ""); - } else { - strcpy(remcomOutBuffer,"OK"); - } - ptr = 0; - } - if (ptr) - { - strcpy(remcomOutBuffer,"E02"); - } - } - break; - case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ - /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */ - if (hexToInt(&ptr,&addr)) - if (*(ptr++) == ',') - if (hexToInt(&ptr,&length)) - { - ptr = 0; - mem_err = 0; - mem2hex((unsigned char*) addr, remcomOutBuffer, length, 1); - if (mem_err) { - strcpy (remcomOutBuffer, "E03"); - gdb_error ("memory fault", ""); - } - } - if (ptr) - { - strcpy(remcomOutBuffer,"E01"); - } - break; - case '?': - remcomOutBuffer[0] = 'S'; - remcomOutBuffer[1] = hexchars[sigval >> 4]; - remcomOutBuffer[2] = hexchars[sigval % 16]; - remcomOutBuffer[3] = 0; - break; - case 'd': - remote_debug = !(remote_debug); /* toggle debug flag */ - break; - case 'g': /* return the value of the CPU registers */ - mem2hex((unsigned char*) registers, remcomOutBuffer, NUMREGBYTES, 0); - break; - case 'P': /* set the value of a single CPU register - return OK */ - { - int regno; - - if (hexToInt (&ptr, ®no) && *ptr++ == '=') - if (regno >= 0 && regno < NUMREGS) - { - int stackmode; - - hex2mem (ptr, (unsigned char *) ®isters[regno], 4, 0); - /* - * Since we just changed a single CPU register, let's - * make sure to keep the several stack pointers consistant. - */ - stackmode = registers[PSW] & 0x80; - if (regno == R15) /* stack pointer changed */ - { /* need to change SPI or SPU */ - if (stackmode == 0) - registers[SPI] = registers[R15]; - else - registers[SPU] = registers[R15]; - } - else if (regno == SPU) /* "user" stack pointer changed */ - { - if (stackmode != 0) /* stack in user mode: copy SP */ - registers[R15] = registers[SPU]; - } - else if (regno == SPI) /* "interrupt" stack pointer changed */ - { - if (stackmode == 0) /* stack in interrupt mode: copy SP */ - registers[R15] = registers[SPI]; - } - else if (regno == PSW) /* stack mode may have changed! */ - { /* force SP to either SPU or SPI */ - if (stackmode == 0) /* stack in user mode */ - registers[R15] = registers[SPI]; - else /* stack in interrupt mode */ - registers[R15] = registers[SPU]; - } - strcpy (remcomOutBuffer, "OK"); - break; - } - strcpy (remcomOutBuffer, "E01"); - break; - } - case 'G': /* set the value of the CPU registers - return OK */ - hex2mem(ptr, (unsigned char*) registers, NUMREGBYTES, 0); - strcpy(remcomOutBuffer,"OK"); - break; - case 's': /* sAA..AA Step one instruction from AA..AA(optional) */ - stepping = 1; - case 'c': /* cAA..AA Continue from address AA..AA(optional) */ - /* try to read optional parameter, pc unchanged if no parm */ - if (hexToInt(&ptr,&addr)) - registers[ PC ] = addr; - - if (stepping) /* single-stepping */ - { - if (!prepare_to_step(0)) /* set up for single-step */ - { - /* prepare_to_step has already emulated the target insn: - Send SIGTRAP to gdb, don't resume the target at all. */ - ptr = remcomOutBuffer; - *ptr++ = 'T'; /* Simulate stopping with SIGTRAP */ - *ptr++ = '0'; - *ptr++ = '5'; - - *ptr++ = hexchars[PC >> 4]; /* send PC */ - *ptr++ = hexchars[PC & 0xf]; - *ptr++ = ':'; - ptr = mem2hex((unsigned char *)®isters[PC], ptr, 4, 0); - *ptr++ = ';'; - - *ptr++ = hexchars[R13 >> 4]; /* send FP */ - *ptr++ = hexchars[R13 & 0xf]; - *ptr++ = ':'; - ptr = mem2hex((unsigned char *)®isters[R13], ptr, 4, 0); - *ptr++ = ';'; - - *ptr++ = hexchars[R15 >> 4]; /* send SP */ - *ptr++ = hexchars[R15 & 0xf]; - *ptr++ = ':'; - ptr = mem2hex((unsigned char *)®isters[R15], ptr, 4, 0); - *ptr++ = ';'; - *ptr++ = 0; - - break; - } - } - else /* continuing, not single-stepping */ - { - /* OK, about to do a "continue". First check to see if the - target pc is on an odd boundary (second instruction in the - word). If so, we must do a single-step first, because - ya can't jump or return back to an odd boundary! */ - if ((registers[PC] & 2) != 0) - prepare_to_step(1); - } - - return; - - case 'D': /* Detach */ -#if 0 - /* I am interpreting this to mean, release the board from control - by the remote stub. To do this, I am restoring the original - (or at least previous) exception vectors. - */ - for (i = 0; i < 18; i++) - exceptionHandler (i, save_vectors[i]); - putpacket ("OK"); - return; /* continue the inferior */ -#else - strcpy(remcomOutBuffer,"OK"); - break; -#endif - case 'q': - if (*ptr++ == 'C' && - *ptr++ == 'R' && - *ptr++ == 'C' && - *ptr++ == ':') - { - unsigned long start, len, our_crc; - - if (hexToInt (&ptr, (int *) &start) && - *ptr++ == ',' && - hexToInt (&ptr, (int *) &len)) - { - remcomOutBuffer[0] = 'C'; - our_crc = crc32 ((unsigned char *) start, len, 0xffffffff); - mem2hex ((char *) &our_crc, - &remcomOutBuffer[1], - sizeof (long), - 0); - } /* else do nothing */ - } /* else do nothing */ - break; - - case 'k': /* kill the program */ - continue; - } /* switch */ - - /* reply to the request */ - putpacket(remcomOutBuffer); - } -} - -/* qCRC support */ - -/* Table used by the crc32 function to calcuate the checksum. */ -static unsigned long crc32_table[256] = {0, 0}; - -static unsigned long -crc32 (unsigned char *buf, int len, unsigned long crc) -{ - if (! crc32_table[1]) - { - /* Initialize the CRC table and the decoding table. */ - int i, j; - unsigned long c; - - for (i = 0; i < 256; i++) - { - for (c = i << 24, j = 8; j > 0; --j) - c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1); - crc32_table[i] = c; - } - } - - while (len--) - { - crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buf) & 255]; - buf++; - } - return crc; -} - -static int -hex (unsigned char ch) -{ - if ((ch >= 'a') && (ch <= 'f')) return (ch-'a'+10); - if ((ch >= '0') && (ch <= '9')) return (ch-'0'); - if ((ch >= 'A') && (ch <= 'F')) return (ch-'A'+10); - return (-1); -} - -/* scan for the sequence $<data>#<checksum> */ - -unsigned char * -getpacket (void) -{ - unsigned char *buffer = &remcomInBuffer[0]; - unsigned char checksum; - unsigned char xmitcsum; - int count; - char ch; - - while (1) - { - /* wait around for the start character, ignore all other characters */ - while ((ch = getDebugChar ()) != '$') - ; - -retry: - checksum = 0; - xmitcsum = -1; - count = 0; - - /* now, read until a # or end of buffer is found */ - while (count < BUFMAX) - { - ch = getDebugChar (); - if (ch == '$') - goto retry; - if (ch == '#') - break; - checksum = checksum + ch; - buffer[count] = ch; - count = count + 1; - } - buffer[count] = 0; - - if (ch == '#') - { - ch = getDebugChar (); - xmitcsum = hex (ch) << 4; - ch = getDebugChar (); - xmitcsum += hex (ch); - - if (checksum != xmitcsum) - { - if (remote_debug) - { - unsigned char buf[16]; - - mem2hex((unsigned char *) &checksum, buf, 4, 0); - gdb_error("Bad checksum: my count = %s, ", buf); - mem2hex((unsigned char *) &xmitcsum, buf, 4, 0); - gdb_error("sent count = %s\n", buf); - gdb_error(" -- Bad buffer: \"%s\"\n", buffer); - } - putDebugChar ('-'); /* failed checksum */ - } - else - { - putDebugChar ('+'); /* successful transfer */ - - /* if a sequence char is present, reply the sequence ID */ - if (buffer[2] == ':') - { - putDebugChar (buffer[0]); - putDebugChar (buffer[1]); - - return &buffer[3]; - } - - return &buffer[0]; - } - } - } -} - -/* send the packet in buffer. */ - -static void -putpacket (unsigned char *buffer) -{ - unsigned char checksum; - int count; - char ch; - - /* $<packet info>#<checksum>. */ - do { - putDebugChar('$'); - checksum = 0; - count = 0; - - while (ch=buffer[count]) { - putDebugChar(ch); - checksum += ch; - count += 1; - } - putDebugChar('#'); - putDebugChar(hexchars[checksum >> 4]); - putDebugChar(hexchars[checksum % 16]); - } while (getDebugChar() != '+'); -} - -/* Address of a routine to RTE to if we get a memory fault. */ - -static void (*volatile mem_fault_routine)() = 0; - -static void -set_mem_err (void) -{ - mem_err = 1; -} - -/* Check the address for safe access ranges. As currently defined, - this routine will reject the "expansion bus" address range(s). - To make those ranges useable, someone must implement code to detect - whether there's anything connected to the expansion bus. */ - -static int -mem_safe (unsigned char *addr) -{ -#define BAD_RANGE_ONE_START ((unsigned char *) 0x600000) -#define BAD_RANGE_ONE_END ((unsigned char *) 0xa00000) -#define BAD_RANGE_TWO_START ((unsigned char *) 0xff680000) -#define BAD_RANGE_TWO_END ((unsigned char *) 0xff800000) - - if (addr < BAD_RANGE_ONE_START) return 1; /* safe */ - if (addr < BAD_RANGE_ONE_END) return 0; /* unsafe */ - if (addr < BAD_RANGE_TWO_START) return 1; /* safe */ - if (addr < BAD_RANGE_TWO_END) return 0; /* unsafe */ -} - -/* These are separate functions so that they are so short and sweet - that the compiler won't save any registers (if there is a fault - to mem_fault, they won't get restored, so there better not be any - saved). */ -static int -get_char (unsigned char *addr) -{ -#if 1 - if (mem_fault_routine && !mem_safe(addr)) - { - mem_fault_routine (); - return 0; - } -#endif - return *addr; -} - -static void -set_char (unsigned char *addr, unsigned char val) -{ -#if 1 - if (mem_fault_routine && !mem_safe (addr)) - { - mem_fault_routine (); - return; - } -#endif - *addr = val; -} - -/* Convert the memory pointed to by mem into hex, placing result in buf. - Return a pointer to the last char put in buf (null). - If MAY_FAULT is non-zero, then we should set mem_err in response to - a fault; if zero treat a fault like any other fault in the stub. */ - -static unsigned char * -mem2hex (unsigned char *mem, unsigned char *buf, int count, int may_fault) -{ - int i; - unsigned char ch; - - if (may_fault) - mem_fault_routine = set_mem_err; - for (i=0;i<count;i++) { - ch = get_char (mem++); - if (may_fault && mem_err) - return (buf); - *buf++ = hexchars[ch >> 4]; - *buf++ = hexchars[ch % 16]; - } - *buf = 0; - if (may_fault) - mem_fault_routine = 0; - return(buf); -} - -/* Convert the hex array pointed to by buf into binary to be placed in mem. - Return a pointer to the character AFTER the last byte written. */ - -static unsigned char* -hex2mem (unsigned char *buf, unsigned char *mem, int count, int may_fault) -{ - int i; - unsigned char ch; - - if (may_fault) - mem_fault_routine = set_mem_err; - for (i=0;i<count;i++) { - ch = hex(*buf++) << 4; - ch = ch + hex(*buf++); - set_char (mem++, ch); - if (may_fault && mem_err) - return (mem); - } - if (may_fault) - mem_fault_routine = 0; - return(mem); -} - -/* Convert the binary stream in BUF to memory. - - Gdb will escape $, #, and the escape char (0x7d). - COUNT is the total number of bytes to write into - memory. */ -static unsigned char * -bin2mem (unsigned char *buf, unsigned char *mem, int count, int may_fault) -{ - int i; - unsigned char ch; - - if (may_fault) - mem_fault_routine = set_mem_err; - for (i = 0; i < count; i++) - { - /* Check for any escaped characters. Be paranoid and - only unescape chars that should be escaped. */ - if (*buf == 0x7d) - { - switch (*(buf+1)) - { - case 0x3: /* # */ - case 0x4: /* $ */ - case 0x5d: /* escape char */ - buf++; - *buf |= 0x20; - break; - default: - /* nothing */ - break; - } - } - - set_char (mem++, *buf++); - - if (may_fault && mem_err) - return mem; - } - - if (may_fault) - mem_fault_routine = 0; - return mem; -} - -/* this function takes the m32r exception vector and attempts to - translate this number into a unix compatible signal value */ - -static int -computeSignal (int exceptionVector) -{ - int sigval; - switch (exceptionVector) { - case 0 : sigval = 23; break; /* I/O trap */ - case 1 : sigval = 5; break; /* breakpoint */ - case 2 : sigval = 5; break; /* breakpoint */ - case 3 : sigval = 5; break; /* breakpoint */ - case 4 : sigval = 5; break; /* breakpoint */ - case 5 : sigval = 5; break; /* breakpoint */ - case 6 : sigval = 5; break; /* breakpoint */ - case 7 : sigval = 5; break; /* breakpoint */ - case 8 : sigval = 5; break; /* breakpoint */ - case 9 : sigval = 5; break; /* breakpoint */ - case 10 : sigval = 5; break; /* breakpoint */ - case 11 : sigval = 5; break; /* breakpoint */ - case 12 : sigval = 5; break; /* breakpoint */ - case 13 : sigval = 5; break; /* breakpoint */ - case 14 : sigval = 5; break; /* breakpoint */ - case 15 : sigval = 5; break; /* breakpoint */ - case 16 : sigval = 10; break; /* BUS ERROR (alignment) */ - case 17 : sigval = 2; break; /* INTerrupt */ - default : sigval = 7; break; /* "software generated" */ - } - return (sigval); -} - -/**********************************************/ -/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */ -/* RETURN NUMBER OF CHARS PROCESSED */ -/**********************************************/ -static int -hexToInt (unsigned char **ptr, int *intValue) -{ - int numChars = 0; - int hexValue; - - *intValue = 0; - while (**ptr) - { - hexValue = hex(**ptr); - if (hexValue >=0) - { - *intValue = (*intValue <<4) | hexValue; - numChars ++; - } - else - break; - (*ptr)++; - } - return (numChars); -} - -/* - Table of branch instructions: - - 10B6 RTE return from trap or exception - 1FCr JMP jump - 1ECr JL jump and link - 7Fxx BRA branch - FFxxxxxx BRA branch (long) - B09rxxxx BNEZ branch not-equal-zero - Br1rxxxx BNE branch not-equal - 7Dxx BNC branch not-condition - FDxxxxxx BNC branch not-condition (long) - B0Arxxxx BLTZ branch less-than-zero - B0Crxxxx BLEZ branch less-equal-zero - 7Exx BL branch and link - FExxxxxx BL branch and link (long) - B0Drxxxx BGTZ branch greater-than-zero - B0Brxxxx BGEZ branch greater-equal-zero - B08rxxxx BEQZ branch equal-zero - Br0rxxxx BEQ branch equal - 7Cxx BC branch condition - FCxxxxxx BC branch condition (long) - */ - -static int -isShortBranch (unsigned char *instr) -{ - unsigned char instr0 = instr[0] & 0x7F; /* mask off high bit */ - - if (instr0 == 0x10 && instr[1] == 0xB6) /* RTE */ - return 1; /* return from trap or exception */ - - if (instr0 == 0x1E || instr0 == 0x1F) /* JL or JMP */ - if ((instr[1] & 0xF0) == 0xC0) - return 2; /* jump thru a register */ - - if (instr0 == 0x7C || instr0 == 0x7D || /* BC, BNC, BL, BRA */ - instr0 == 0x7E || instr0 == 0x7F) - return 3; /* eight bit PC offset */ - - return 0; -} - -static int -isLongBranch (unsigned char *instr) -{ - if (instr[0] == 0xFC || instr[0] == 0xFD || /* BRA, BNC, BL, BC */ - instr[0] == 0xFE || instr[0] == 0xFF) /* 24 bit relative */ - return 4; - if ((instr[0] & 0xF0) == 0xB0) /* 16 bit relative */ - { - if ((instr[1] & 0xF0) == 0x00 || /* BNE, BEQ */ - (instr[1] & 0xF0) == 0x10) - return 5; - if (instr[0] == 0xB0) /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ, BEQZ */ - if ((instr[1] & 0xF0) == 0x80 || (instr[1] & 0xF0) == 0x90 || - (instr[1] & 0xF0) == 0xA0 || (instr[1] & 0xF0) == 0xB0 || - (instr[1] & 0xF0) == 0xC0 || (instr[1] & 0xF0) == 0xD0) - return 6; - } - return 0; -} - -/* if address is NOT on a 4-byte boundary, or high-bit of instr is zero, - then it's a 2-byte instruction, else it's a 4-byte instruction. */ - -#define INSTRUCTION_SIZE(addr) \ - ((((int) addr & 2) || (((unsigned char *) addr)[0] & 0x80) == 0) ? 2 : 4) - -static int -isBranch (unsigned char *instr) -{ - if (INSTRUCTION_SIZE(instr) == 2) - return isShortBranch(instr); - else - return isLongBranch(instr); -} - -static int -willBranch (unsigned char *instr, int branchCode) -{ - switch (branchCode) - { - case 0: return 0; /* not a branch */ - case 1: return 1; /* RTE */ - case 2: return 1; /* JL or JMP */ - case 3: /* BC, BNC, BL, BRA (short) */ - case 4: /* BC, BNC, BL, BRA (long) */ - switch (instr[0] & 0x0F) - { - case 0xC: /* Branch if Condition Register */ - return (registers[CBR] != 0); - case 0xD: /* Branch if NOT Condition Register */ - return (registers[CBR] == 0); - case 0xE: /* Branch and Link */ - case 0xF: /* Branch (unconditional) */ - return 1; - default: /* oops? */ - return 0; - } - case 5: /* BNE, BEQ */ - switch (instr[1] & 0xF0) - { - case 0x00: /* Branch if r1 equal to r2 */ - return (registers[instr[0] & 0x0F] == registers[instr[1] & 0x0F]); - case 0x10: /* Branch if r1 NOT equal to r2 */ - return (registers[instr[0] & 0x0F] != registers[instr[1] & 0x0F]); - default: /* oops? */ - return 0; - } - case 6: /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ ,BEQZ */ - switch (instr[1] & 0xF0) - { - case 0x80: /* Branch if reg equal to zero */ - return (registers[instr[1] & 0x0F] == 0); - case 0x90: /* Branch if reg NOT equal to zero */ - return (registers[instr[1] & 0x0F] != 0); - case 0xA0: /* Branch if reg less than zero */ - return (registers[instr[1] & 0x0F] < 0); - case 0xB0: /* Branch if reg greater or equal to zero */ - return (registers[instr[1] & 0x0F] >= 0); - case 0xC0: /* Branch if reg less than or equal to zero */ - return (registers[instr[1] & 0x0F] <= 0); - case 0xD0: /* Branch if reg greater than zero */ - return (registers[instr[1] & 0x0F] > 0); - default: /* oops? */ - return 0; - } - default: /* oops? */ - return 0; - } -} - -static int -branchDestination (unsigned char *instr, int branchCode) -{ - switch (branchCode) { - default: - case 0: /* not a branch */ - return 0; - case 1: /* RTE */ - return registers[BPC] & ~3; /* pop BPC into PC */ - case 2: /* JL or JMP */ - return registers[instr[1] & 0x0F] & ~3; /* jump thru a register */ - case 3: /* BC, BNC, BL, BRA (short, 8-bit relative offset) */ - return (((int) instr) & ~3) + ((char) instr[1] << 2); - case 4: /* BC, BNC, BL, BRA (long, 24-bit relative offset) */ - return ((int) instr + - ((((char) instr[1] << 16) | (instr[2] << 8) | (instr[3])) << 2)); - case 5: /* BNE, BEQ (16-bit relative offset) */ - case 6: /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ ,BEQZ (ditto) */ - return ((int) instr + ((((char) instr[2] << 8) | (instr[3])) << 2)); - } - - /* An explanatory note: in the last three return expressions, I have - cast the most-significant byte of the return offset to char. - What this accomplishes is sign extension. If the other - less-significant bytes were signed as well, they would get sign - extended too and, if negative, their leading bits would clobber - the bits of the more-significant bytes ahead of them. There are - other ways I could have done this, but sign extension from - odd-sized integers is always a pain. */ -} - -static void -branchSideEffects (unsigned char *instr, int branchCode) -{ - switch (branchCode) - { - case 1: /* RTE */ - return; /* I <THINK> this is already handled... */ - case 2: /* JL (or JMP) */ - case 3: /* BL (or BC, BNC, BRA) */ - case 4: - if ((instr[0] & 0x0F) == 0x0E) /* branch/jump and link */ - registers[R14] = (registers[PC] & ~3) + 4; - return; - default: /* any other branch has no side effects */ - return; - } -} - -static struct STEPPING_CONTEXT { - int stepping; /* true when we've started a single-step */ - unsigned long target_addr; /* the instr we're trying to execute */ - unsigned long target_size; /* the size of the target instr */ - unsigned long noop_addr; /* where we've inserted a no-op, if any */ - unsigned long trap1_addr; /* the trap following the target instr */ - unsigned long trap2_addr; /* the trap at a branch destination, if any */ - unsigned short noop_save; /* instruction overwritten by our no-op */ - unsigned short trap1_save; /* instruction overwritten by trap1 */ - unsigned short trap2_save; /* instruction overwritten by trap2 */ - unsigned short continue_p; /* true if NOT returning to gdb after step */ -} stepping; - -/* Function: prepare_to_step - Called from handle_exception to prepare the user program to single-step. - Places a trap instruction after the target instruction, with special - extra handling for branch instructions and for instructions in the - second half-word of a word. - - Returns: True if we should actually execute the instruction; - False if we are going to emulate executing the instruction, - in which case we simply report to GDB that the instruction - has already been executed. */ - -#define TRAP1 0x10f1; /* trap #1 instruction */ -#define NOOP 0x7000; /* noop instruction */ - -static unsigned short trap1 = TRAP1; -static unsigned short noop = NOOP; - -static int -prepare_to_step(continue_p) - int continue_p; /* if this isn't REALLY a single-step (see below) */ -{ - unsigned long pc = registers[PC]; - int branchCode = isBranch((unsigned char *) pc); - unsigned char *p; - - /* zero out the stepping context - (paranoia -- it should already be zeroed) */ - for (p = (unsigned char *) &stepping; - p < ((unsigned char *) &stepping) + sizeof(stepping); - p++) - *p = 0; - - if (branchCode != 0) /* next instruction is a branch */ - { - branchSideEffects((unsigned char *) pc, branchCode); - if (willBranch((unsigned char *)pc, branchCode)) - registers[PC] = branchDestination((unsigned char *) pc, branchCode); - else - registers[PC] = pc + INSTRUCTION_SIZE(pc); - return 0; /* branch "executed" -- just notify GDB */ - } - else if (((int) pc & 2) != 0) /* "second-slot" instruction */ - { - /* insert no-op before pc */ - stepping.noop_addr = pc - 2; - stepping.noop_save = *(unsigned short *) stepping.noop_addr; - *(unsigned short *) stepping.noop_addr = noop; - /* insert trap after pc */ - stepping.trap1_addr = pc + 2; - stepping.trap1_save = *(unsigned short *) stepping.trap1_addr; - *(unsigned short *) stepping.trap1_addr = trap1; - } - else /* "first-slot" instruction */ - { - /* insert trap after pc */ - stepping.trap1_addr = pc + INSTRUCTION_SIZE(pc); - stepping.trap1_save = *(unsigned short *) stepping.trap1_addr; - *(unsigned short *) stepping.trap1_addr = trap1; - } - /* "continue_p" means that we are actually doing a continue, and not - being requested to single-step by GDB. Sometimes we have to do - one single-step before continuing, because the PC is on a half-word - boundary. There's no way to simply resume at such an address. */ - stepping.continue_p = continue_p; - stepping.stepping = 1; /* starting a single-step */ - return 1; -} - -/* Function: finish_from_step - Called from handle_exception to finish up when the user program - returns from a single-step. Replaces the instructions that had - been overwritten by traps or no-ops, - - Returns: True if we should notify GDB that the target stopped. - False if we only single-stepped because we had to before we - could continue (ie. we were trying to continue at a - half-word boundary). In that case don't notify GDB: - just "continue continuing". */ - -static int -finish_from_step (void) -{ - if (stepping.stepping) /* anything to do? */ - { - int continue_p = stepping.continue_p; - unsigned char *p; - - if (stepping.noop_addr) /* replace instr "under" our no-op */ - *(unsigned short *) stepping.noop_addr = stepping.noop_save; - if (stepping.trap1_addr) /* replace instr "under" our trap */ - *(unsigned short *) stepping.trap1_addr = stepping.trap1_save; - if (stepping.trap2_addr) /* ditto our other trap, if any */ - *(unsigned short *) stepping.trap2_addr = stepping.trap2_save; - - for (p = (unsigned char *) &stepping; /* zero out the stepping context */ - p < ((unsigned char *) &stepping) + sizeof(stepping); - p++) - *p = 0; - - return !(continue_p); - } - else /* we didn't single-step, therefore this must be a legitimate stop */ - return 1; -} - -struct PSWreg { /* separate out the bit flags in the PSW register */ - int pad1 : 16; - int bsm : 1; - int bie : 1; - int pad2 : 5; - int bc : 1; - int sm : 1; - int ie : 1; - int pad3 : 5; - int c : 1; -} *psw; - -/* Upon entry the value for LR to save has been pushed. - We unpush that so that the value for the stack pointer saved is correct. - Upon entry, all other registers are assumed to have not been modified - since the interrupt/trap occured. */ - -asm (" -stash_registers: - push r0 - push r1 - seth r1, #shigh(registers) - add3 r1, r1, #low(registers) - pop r0 ; r1 - st r0, @(4,r1) - pop r0 ; r0 - st r0, @r1 - addi r1, #4 ; only add 4 as subsequent saves are `pre inc' - st r2, @+r1 - st r3, @+r1 - st r4, @+r1 - st r5, @+r1 - st r6, @+r1 - st r7, @+r1 - st r8, @+r1 - st r9, @+r1 - st r10, @+r1 - st r11, @+r1 - st r12, @+r1 - st r13, @+r1 ; fp - pop r0 ; lr (r14) - st r0, @+r1 - st sp, @+r1 ; sp contains right value at this point - mvfc r0, cr0 - st r0, @+r1 ; cr0 == PSW - mvfc r0, cr1 - st r0, @+r1 ; cr1 == CBR - mvfc r0, cr2 - st r0, @+r1 ; cr2 == SPI - mvfc r0, cr3 - st r0, @+r1 ; cr3 == SPU - mvfc r0, cr6 - st r0, @+r1 ; cr6 == BPC - st r0, @+r1 ; PC == BPC - mvfaclo r0 - st r0, @+r1 ; ACCL - mvfachi r0 - st r0, @+r1 ; ACCH - jmp lr"); - -/* C routine to clean up what stash_registers did. - It is called after calling stash_registers. - This is separate from stash_registers as we want to do this in C - but doing stash_registers in C isn't straightforward. */ - -static void -cleanup_stash (void) -{ - psw = (struct PSWreg *) ®isters[PSW]; /* fields of PSW register */ - psw->sm = psw->bsm; /* fix up pre-trap values of psw fields */ - psw->ie = psw->bie; - psw->c = psw->bc; - registers[CBR] = psw->bc; /* fix up pre-trap "C" register */ - -#if 0 /* FIXME: Was in previous version. Necessary? - (Remember that we use the "rte" insn to return from the - trap/interrupt so the values of bsm, bie, bc are important. */ - psw->bsm = psw->bie = psw->bc = 0; /* zero post-trap values */ -#endif - - /* FIXME: Copied from previous version. This can probably be deleted - since methinks stash_registers has already done this. */ - registers[PC] = registers[BPC]; /* pre-trap PC */ - - /* FIXME: Copied from previous version. Necessary? */ - if (psw->sm) /* copy R15 into (psw->sm ? SPU : SPI) */ - registers[SPU] = registers[R15]; - else - registers[SPI] = registers[R15]; -} - -asm (" -restore_and_return: - seth r0, #shigh(registers+8) - add3 r0, r0, #low(registers+8) - ld r2, @r0+ ; restore r2 - ld r3, @r0+ ; restore r3 - ld r4, @r0+ ; restore r4 - ld r5, @r0+ ; restore r5 - ld r6, @r0+ ; restore r6 - ld r7, @r0+ ; restore r7 - ld r8, @r0+ ; restore r8 - ld r9, @r0+ ; restore r9 - ld r10, @r0+ ; restore r10 - ld r11, @r0+ ; restore r11 - ld r12, @r0+ ; restore r12 - ld r13, @r0+ ; restore r13 - ld r14, @r0+ ; restore r14 - ld r15, @r0+ ; restore r15 - addi r0, #4 ; don't restore PSW (rte will do it) - ld r1, @r0+ ; restore cr1 == CBR (no-op, because it's read only) - mvtc r1, cr1 - ld r1, @r0+ ; restore cr2 == SPI - mvtc r1, cr2 - ld r1, @r0+ ; restore cr3 == SPU - mvtc r1, cr3 - addi r0, #4 ; skip BPC - ld r1, @r0+ ; restore cr6 (BPC) == PC - mvtc r1, cr6 - ld r1, @r0+ ; restore ACCL - mvtaclo r1 - ld r1, @r0+ ; restore ACCH - mvtachi r1 - seth r0, #shigh(registers) - add3 r0, r0, #low(registers) - ld r1, @(4,r0) ; restore r1 - ld r0, @r0 ; restore r0 - rte"); - -/* General trap handler, called after the registers have been stashed. - NUM is the trap/exception number. */ - -static void -process_exception (int num) -{ - cleanup_stash (); - asm volatile (" - seth r1, #shigh(stackPtr) - add3 r1, r1, #low(stackPtr) - ld r15, @r1 ; setup local stack (protect user stack) - mv r0, %0 - bl handle_exception - bl restore_and_return" - : : "r" (num) : "r0", "r1"); -} - -void _catchException0 (); - -asm (" -_catchException0: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #0 - bl process_exception"); - -void _catchException1 (); - -asm (" -_catchException1: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - bl cleanup_stash - seth r1, #shigh(stackPtr) - add3 r1, r1, #low(stackPtr) - ld r15, @r1 ; setup local stack (protect user stack) - seth r1, #shigh(registers + 21*4) ; PC - add3 r1, r1, #low(registers + 21*4) - ld r0, @r1 - addi r0, #-4 ; back up PC for breakpoint trap. - st r0, @r1 ; FIXME: what about bp in right slot? - ldi r0, #1 - bl handle_exception - bl restore_and_return"); - -void _catchException2 (); - -asm (" -_catchException2: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #2 - bl process_exception"); - -void _catchException3 (); - -asm (" -_catchException3: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #3 - bl process_exception"); - -void _catchException4 (); - -asm (" -_catchException4: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #4 - bl process_exception"); - -void _catchException5 (); - -asm (" -_catchException5: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #5 - bl process_exception"); - -void _catchException6 (); - -asm (" -_catchException6: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #6 - bl process_exception"); - -void _catchException7 (); - -asm (" -_catchException7: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #7 - bl process_exception"); - -void _catchException8 (); - -asm (" -_catchException8: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #8 - bl process_exception"); - -void _catchException9 (); - -asm (" -_catchException9: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #9 - bl process_exception"); - -void _catchException10 (); - -asm (" -_catchException10: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #10 - bl process_exception"); - -void _catchException11 (); - -asm (" -_catchException11: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #11 - bl process_exception"); - -void _catchException12 (); - -asm (" -_catchException12: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #12 - bl process_exception"); - -void _catchException13 (); - -asm (" -_catchException13: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #13 - bl process_exception"); - -void _catchException14 (); - -asm (" -_catchException14: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #14 - bl process_exception"); - -void _catchException15 (); - -asm (" -_catchException15: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #15 - bl process_exception"); - -void _catchException16 (); - -asm (" -_catchException16: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #16 - bl process_exception"); - -void _catchException17 (); - -asm (" -_catchException17: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #17 - bl process_exception"); - - -/* this function is used to set up exception handlers for tracing and - breakpoints */ -void -set_debug_traps (void) -{ - /* extern void remcomHandler(); */ - int i; - - for (i = 0; i < 18; i++) /* keep a copy of old vectors */ - if (save_vectors[i] == 0) /* only copy them the first time */ - save_vectors[i] = getExceptionHandler (i); - - stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1]; - - exceptionHandler (0, _catchException0); - exceptionHandler (1, _catchException1); - exceptionHandler (2, _catchException2); - exceptionHandler (3, _catchException3); - exceptionHandler (4, _catchException4); - exceptionHandler (5, _catchException5); - exceptionHandler (6, _catchException6); - exceptionHandler (7, _catchException7); - exceptionHandler (8, _catchException8); - exceptionHandler (9, _catchException9); - exceptionHandler (10, _catchException10); - exceptionHandler (11, _catchException11); - exceptionHandler (12, _catchException12); - exceptionHandler (13, _catchException13); - exceptionHandler (14, _catchException14); - exceptionHandler (15, _catchException15); - exceptionHandler (16, _catchException16); - /* exceptionHandler (17, _catchException17); */ - - initialized = 1; -} - -/* This function will generate a breakpoint exception. It is used at the - beginning of a program to sync up with a debugger and can be used - otherwise as a quick means to stop program execution and "break" into - the debugger. */ - -#define BREAKPOINT() asm volatile (" trap #2"); - -void -breakpoint (void) -{ - if (initialized) - BREAKPOINT(); -} - -/* STDOUT section: - Stuff pertaining to simulating stdout by sending chars to gdb to be echoed. - Functions: gdb_putchar(char ch) - gdb_puts(char *str) - gdb_write(char *str, int len) - gdb_error(char *format, char *parm) - */ - -/* Function: gdb_putchar(int) - Make gdb write a char to stdout. - Returns: the char */ - -static int -gdb_putchar (int ch) -{ - char buf[4]; - - buf[0] = 'O'; - buf[1] = hexchars[ch >> 4]; - buf[2] = hexchars[ch & 0x0F]; - buf[3] = 0; - putpacket(buf); - return ch; -} - -/* Function: gdb_write(char *, int) - Make gdb write n bytes to stdout (not assumed to be null-terminated). - Returns: number of bytes written */ - -static int -gdb_write (char *data, int len) -{ - char *buf, *cpy; - int i; - - buf = remcomOutBuffer; - buf[0] = 'O'; - i = 0; - while (i < len) - { - for (cpy = buf+1; - i < len && cpy < buf + sizeof(remcomOutBuffer) - 3; - i++) - { - *cpy++ = hexchars[data[i] >> 4]; - *cpy++ = hexchars[data[i] & 0x0F]; - } - *cpy = 0; - putpacket(buf); - } - return len; -} - -/* Function: gdb_puts(char *) - Make gdb write a null-terminated string to stdout. - Returns: the length of the string */ - -static int -gdb_puts (char *str) -{ - return gdb_write(str, strlen(str)); -} - -/* Function: gdb_error(char *, char *) - Send an error message to gdb's stdout. - First string may have 1 (one) optional "%s" in it, which - will cause the optional second string to be inserted. */ - -static void -gdb_error (char *format, char *parm) -{ - char buf[400], *cpy; - int len; - - if (remote_debug) - { - if (format && *format) - len = strlen(format); - else - return; /* empty input */ - - if (parm && *parm) - len += strlen(parm); - - for (cpy = buf; *format; ) - { - if (format[0] == '%' && format[1] == 's') /* include second string */ - { - format += 2; /* advance two chars instead of just one */ - while (parm && *parm) - *cpy++ = *parm++; - } - else - *cpy++ = *format++; - } - *cpy = '\0'; - gdb_puts(buf); - } -} - -static unsigned char * -strcpy (unsigned char *dest, const unsigned char *src) -{ - unsigned char *ret = dest; - - if (dest && src) - { - while (*src) - *dest++ = *src++; - *dest = 0; - } - return ret; -} - -static int -strlen (const unsigned char *src) -{ - int ret; - - for (ret = 0; *src; src++) - ret++; - - return ret; -} - -#if 0 -void exit (code) - int code; -{ - _exit (code); -} - -int atexit (void *p) -{ - return 0; -} - -void abort (void) -{ - _exit (1); -} -#endif +// OBSOLETE /**************************************************************************** +// OBSOLETE +// OBSOLETE THIS SOFTWARE IS NOT COPYRIGHTED +// OBSOLETE +// OBSOLETE HP offers the following for use in the public domain. HP makes no +// OBSOLETE warranty with regard to the software or it's performance and the +// OBSOLETE user accepts the software "AS IS" with all faults. +// OBSOLETE +// OBSOLETE HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD +// OBSOLETE TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OBSOLETE OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// OBSOLETE +// OBSOLETE ****************************************************************************/ +// OBSOLETE +// OBSOLETE /**************************************************************************** +// OBSOLETE * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $ +// OBSOLETE * +// OBSOLETE * Module name: remcom.c $ +// OBSOLETE * Revision: 1.34 $ +// OBSOLETE * Date: 91/03/09 12:29:49 $ +// OBSOLETE * Contributor: Lake Stevens Instrument Division$ +// OBSOLETE * +// OBSOLETE * Description: low level support for gdb debugger. $ +// OBSOLETE * +// OBSOLETE * Considerations: only works on target hardware $ +// OBSOLETE * +// OBSOLETE * Written by: Glenn Engel $ +// OBSOLETE * ModuleState: Experimental $ +// OBSOLETE * +// OBSOLETE * NOTES: See Below $ +// OBSOLETE * +// OBSOLETE * Modified for M32R by Michael Snyder, Cygnus Support. +// OBSOLETE * +// OBSOLETE * To enable debugger support, two things need to happen. One, a +// OBSOLETE * call to set_debug_traps() is necessary in order to allow any breakpoints +// OBSOLETE * or error conditions to be properly intercepted and reported to gdb. +// OBSOLETE * Two, a breakpoint needs to be generated to begin communication. This +// OBSOLETE * is most easily accomplished by a call to breakpoint(). Breakpoint() +// OBSOLETE * simulates a breakpoint by executing a trap #1. +// OBSOLETE * +// OBSOLETE * The external function exceptionHandler() is +// OBSOLETE * used to attach a specific handler to a specific M32R vector number. +// OBSOLETE * It should use the same privilege level it runs at. It should +// OBSOLETE * install it as an interrupt gate so that interrupts are masked +// OBSOLETE * while the handler runs. +// OBSOLETE * +// OBSOLETE * Because gdb will sometimes write to the stack area to execute function +// OBSOLETE * calls, this program cannot rely on using the supervisor stack so it +// OBSOLETE * uses it's own stack area reserved in the int array remcomStack. +// OBSOLETE * +// OBSOLETE ************* +// OBSOLETE * +// OBSOLETE * The following gdb commands are supported: +// OBSOLETE * +// OBSOLETE * command function Return value +// OBSOLETE * +// OBSOLETE * g return the value of the CPU registers hex data or ENN +// OBSOLETE * G set the value of the CPU registers OK or ENN +// OBSOLETE * +// OBSOLETE * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN +// OBSOLETE * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN +// OBSOLETE * XAA..AA,LLLL: Write LLLL binary bytes at address OK or ENN +// OBSOLETE * AA..AA +// OBSOLETE * +// OBSOLETE * c Resume at current address SNN ( signal NN) +// OBSOLETE * cAA..AA Continue at address AA..AA SNN +// OBSOLETE * +// OBSOLETE * s Step one instruction SNN +// OBSOLETE * sAA..AA Step one instruction from AA..AA SNN +// OBSOLETE * +// OBSOLETE * k kill +// OBSOLETE * +// OBSOLETE * ? What was the last sigval ? SNN (signal NN) +// OBSOLETE * +// OBSOLETE * All commands and responses are sent with a packet which includes a +// OBSOLETE * checksum. A packet consists of +// OBSOLETE * +// OBSOLETE * $<packet info>#<checksum>. +// OBSOLETE * +// OBSOLETE * where +// OBSOLETE * <packet info> :: <characters representing the command or response> +// OBSOLETE * <checksum> :: <two hex digits computed as modulo 256 sum of <packetinfo>> +// OBSOLETE * +// OBSOLETE * When a packet is received, it is first acknowledged with either '+' or '-'. +// OBSOLETE * '+' indicates a successful transfer. '-' indicates a failed transfer. +// OBSOLETE * +// OBSOLETE * Example: +// OBSOLETE * +// OBSOLETE * Host: Reply: +// OBSOLETE * $m0,10#2a +$00010203040506070809101112131415#42 +// OBSOLETE * +// OBSOLETE ****************************************************************************/ +// OBSOLETE +// OBSOLETE +// OBSOLETE /************************************************************************ +// OBSOLETE * +// OBSOLETE * external low-level support routines +// OBSOLETE */ +// OBSOLETE extern void putDebugChar(); /* write a single character */ +// OBSOLETE extern int getDebugChar(); /* read and return a single char */ +// OBSOLETE extern void exceptionHandler(); /* assign an exception handler */ +// OBSOLETE +// OBSOLETE /***************************************************************************** +// OBSOLETE * BUFMAX defines the maximum number of characters in inbound/outbound buffers +// OBSOLETE * at least NUMREGBYTES*2 are needed for register packets +// OBSOLETE */ +// OBSOLETE #define BUFMAX 400 +// OBSOLETE +// OBSOLETE static char initialized; /* boolean flag. != 0 means we've been initialized */ +// OBSOLETE +// OBSOLETE int remote_debug; +// OBSOLETE /* debug > 0 prints ill-formed commands in valid packets & checksum errors */ +// OBSOLETE +// OBSOLETE static const unsigned char hexchars[]="0123456789abcdef"; +// OBSOLETE +// OBSOLETE #define NUMREGS 24 +// OBSOLETE +// OBSOLETE /* Number of bytes of registers. */ +// OBSOLETE #define NUMREGBYTES (NUMREGS * 4) +// OBSOLETE enum regnames { R0, R1, R2, R3, R4, R5, R6, R7, +// OBSOLETE R8, R9, R10, R11, R12, R13, R14, R15, +// OBSOLETE PSW, CBR, SPI, SPU, BPC, PC, ACCL, ACCH }; +// OBSOLETE +// OBSOLETE enum SYS_calls { +// OBSOLETE SYS_null, +// OBSOLETE SYS_exit, +// OBSOLETE SYS_open, +// OBSOLETE SYS_close, +// OBSOLETE SYS_read, +// OBSOLETE SYS_write, +// OBSOLETE SYS_lseek, +// OBSOLETE SYS_unlink, +// OBSOLETE SYS_getpid, +// OBSOLETE SYS_kill, +// OBSOLETE SYS_fstat, +// OBSOLETE SYS_sbrk, +// OBSOLETE SYS_fork, +// OBSOLETE SYS_execve, +// OBSOLETE SYS_wait4, +// OBSOLETE SYS_link, +// OBSOLETE SYS_chdir, +// OBSOLETE SYS_stat, +// OBSOLETE SYS_utime, +// OBSOLETE SYS_chown, +// OBSOLETE SYS_chmod, +// OBSOLETE SYS_time, +// OBSOLETE SYS_pipe }; +// OBSOLETE +// OBSOLETE static int registers[NUMREGS]; +// OBSOLETE +// OBSOLETE #define STACKSIZE 8096 +// OBSOLETE static unsigned char remcomInBuffer[BUFMAX]; +// OBSOLETE static unsigned char remcomOutBuffer[BUFMAX]; +// OBSOLETE static int remcomStack[STACKSIZE/sizeof(int)]; +// OBSOLETE static int* stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1]; +// OBSOLETE +// OBSOLETE static unsigned int save_vectors[18]; /* previous exception vectors */ +// OBSOLETE +// OBSOLETE /* Indicate to caller of mem2hex or hex2mem that there has been an error. */ +// OBSOLETE static volatile int mem_err = 0; +// OBSOLETE +// OBSOLETE /* Store the vector number here (since GDB only gets the signal +// OBSOLETE number through the usual means, and that's not very specific). */ +// OBSOLETE int gdb_m32r_vector = -1; +// OBSOLETE +// OBSOLETE #if 0 +// OBSOLETE #include "syscall.h" /* for SYS_exit, SYS_write etc. */ +// OBSOLETE #endif +// OBSOLETE +// OBSOLETE /* Global entry points: +// OBSOLETE */ +// OBSOLETE +// OBSOLETE extern void handle_exception(int); +// OBSOLETE extern void set_debug_traps(void); +// OBSOLETE extern void breakpoint(void); +// OBSOLETE +// OBSOLETE /* Local functions: +// OBSOLETE */ +// OBSOLETE +// OBSOLETE static int computeSignal(int); +// OBSOLETE static void putpacket(unsigned char *); +// OBSOLETE static unsigned char *getpacket(void); +// OBSOLETE +// OBSOLETE static unsigned char *mem2hex(unsigned char *, unsigned char *, int, int); +// OBSOLETE static unsigned char *hex2mem(unsigned char *, unsigned char *, int, int); +// OBSOLETE static int hexToInt(unsigned char **, int *); +// OBSOLETE static unsigned char *bin2mem(unsigned char *, unsigned char *, int, int); +// OBSOLETE static void stash_registers(void); +// OBSOLETE static void restore_registers(void); +// OBSOLETE static int prepare_to_step(int); +// OBSOLETE static int finish_from_step(void); +// OBSOLETE static unsigned long crc32 (unsigned char *, int, unsigned long); +// OBSOLETE +// OBSOLETE static void gdb_error(char *, char *); +// OBSOLETE static int gdb_putchar(int), gdb_puts(char *), gdb_write(char *, int); +// OBSOLETE +// OBSOLETE static unsigned char *strcpy (unsigned char *, const unsigned char *); +// OBSOLETE static int strlen (const unsigned char *); +// OBSOLETE +// OBSOLETE /* +// OBSOLETE * This function does all command procesing for interfacing to gdb. +// OBSOLETE */ +// OBSOLETE +// OBSOLETE void +// OBSOLETE handle_exception(int exceptionVector) +// OBSOLETE { +// OBSOLETE int sigval, stepping; +// OBSOLETE int addr, length, i; +// OBSOLETE unsigned char * ptr; +// OBSOLETE unsigned char buf[16]; +// OBSOLETE int binary; +// OBSOLETE +// OBSOLETE /* Do not call finish_from_step() if this is not a trap #1 +// OBSOLETE * (breakpoint trap). Without this check, the finish_from_step() +// OBSOLETE * might interpret a system call trap as a single step trap. This +// OBSOLETE * can happen if: the stub receives 's' and exits, but an interrupt +// OBSOLETE * was pending; the interrupt is now handled and causes the stub to +// OBSOLETE * be reentered because some function makes a system call. +// OBSOLETE */ +// OBSOLETE if (exceptionVector == 1) /* Trap exception? */ +// OBSOLETE if (!finish_from_step()) /* Go see if stepping state needs update. */ +// OBSOLETE return; /* "false step": let the target continue */ +// OBSOLETE +// OBSOLETE gdb_m32r_vector = exceptionVector; +// OBSOLETE +// OBSOLETE if (remote_debug) +// OBSOLETE { +// OBSOLETE mem2hex((unsigned char *) &exceptionVector, buf, 4, 0); +// OBSOLETE gdb_error("Handle exception %s, ", buf); +// OBSOLETE mem2hex((unsigned char *) ®isters[PC], buf, 4, 0); +// OBSOLETE gdb_error("PC == 0x%s\n", buf); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* reply to host that an exception has occurred */ +// OBSOLETE sigval = computeSignal( exceptionVector ); +// OBSOLETE +// OBSOLETE ptr = remcomOutBuffer; +// OBSOLETE +// OBSOLETE *ptr++ = 'T'; /* notify gdb with signo, PC, FP and SP */ +// OBSOLETE *ptr++ = hexchars[sigval >> 4]; +// OBSOLETE *ptr++ = hexchars[sigval & 0xf]; +// OBSOLETE +// OBSOLETE *ptr++ = hexchars[PC >> 4]; +// OBSOLETE *ptr++ = hexchars[PC & 0xf]; +// OBSOLETE *ptr++ = ':'; +// OBSOLETE ptr = mem2hex((unsigned char *)®isters[PC], ptr, 4, 0); /* PC */ +// OBSOLETE *ptr++ = ';'; +// OBSOLETE +// OBSOLETE *ptr++ = hexchars[R13 >> 4]; +// OBSOLETE *ptr++ = hexchars[R13 & 0xf]; +// OBSOLETE *ptr++ = ':'; +// OBSOLETE ptr = mem2hex((unsigned char *)®isters[R13], ptr, 4, 0); /* FP */ +// OBSOLETE *ptr++ = ';'; +// OBSOLETE +// OBSOLETE *ptr++ = hexchars[R15 >> 4]; +// OBSOLETE *ptr++ = hexchars[R15 & 0xf]; +// OBSOLETE *ptr++ = ':'; +// OBSOLETE ptr = mem2hex((unsigned char *)®isters[R15], ptr, 4, 0); /* SP */ +// OBSOLETE *ptr++ = ';'; +// OBSOLETE *ptr++ = 0; +// OBSOLETE +// OBSOLETE if (exceptionVector == 0) /* simulated SYS call stuff */ +// OBSOLETE { +// OBSOLETE mem2hex((unsigned char *) ®isters[PC], buf, 4, 0); +// OBSOLETE switch (registers[R0]) { +// OBSOLETE case SYS_exit: +// OBSOLETE gdb_error("Target program has exited at %s\n", buf); +// OBSOLETE ptr = remcomOutBuffer; +// OBSOLETE *ptr++ = 'W'; +// OBSOLETE sigval = registers[R1] & 0xff; +// OBSOLETE *ptr++ = hexchars[sigval >> 4]; +// OBSOLETE *ptr++ = hexchars[sigval & 0xf]; +// OBSOLETE *ptr++ = 0; +// OBSOLETE break; +// OBSOLETE case SYS_open: +// OBSOLETE gdb_error("Target attempts SYS_open call at %s\n", buf); +// OBSOLETE break; +// OBSOLETE case SYS_close: +// OBSOLETE gdb_error("Target attempts SYS_close call at %s\n", buf); +// OBSOLETE break; +// OBSOLETE case SYS_read: +// OBSOLETE gdb_error("Target attempts SYS_read call at %s\n", buf); +// OBSOLETE break; +// OBSOLETE case SYS_write: +// OBSOLETE if (registers[R1] == 1 || /* write to stdout */ +// OBSOLETE registers[R1] == 2) /* write to stderr */ +// OBSOLETE { /* (we can do that) */ +// OBSOLETE registers[R0] = gdb_write((void *) registers[R2], registers[R3]); +// OBSOLETE return; +// OBSOLETE } +// OBSOLETE else +// OBSOLETE gdb_error("Target attempts SYS_write call at %s\n", buf); +// OBSOLETE break; +// OBSOLETE case SYS_lseek: +// OBSOLETE gdb_error("Target attempts SYS_lseek call at %s\n", buf); +// OBSOLETE break; +// OBSOLETE case SYS_unlink: +// OBSOLETE gdb_error("Target attempts SYS_unlink call at %s\n", buf); +// OBSOLETE break; +// OBSOLETE case SYS_getpid: +// OBSOLETE gdb_error("Target attempts SYS_getpid call at %s\n", buf); +// OBSOLETE break; +// OBSOLETE case SYS_kill: +// OBSOLETE gdb_error("Target attempts SYS_kill call at %s\n", buf); +// OBSOLETE break; +// OBSOLETE case SYS_fstat: +// OBSOLETE gdb_error("Target attempts SYS_fstat call at %s\n", buf); +// OBSOLETE break; +// OBSOLETE default: +// OBSOLETE gdb_error("Target attempts unknown SYS call at %s\n", buf); +// OBSOLETE break; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE putpacket(remcomOutBuffer); +// OBSOLETE +// OBSOLETE stepping = 0; +// OBSOLETE +// OBSOLETE while (1==1) { +// OBSOLETE remcomOutBuffer[0] = 0; +// OBSOLETE ptr = getpacket(); +// OBSOLETE binary = 0; +// OBSOLETE switch (*ptr++) { +// OBSOLETE default: /* Unknown code. Return an empty reply message. */ +// OBSOLETE break; +// OBSOLETE case 'R': +// OBSOLETE if (hexToInt (&ptr, &addr)) +// OBSOLETE registers[PC] = addr; +// OBSOLETE strcpy(remcomOutBuffer, "OK"); +// OBSOLETE break; +// OBSOLETE case '!': +// OBSOLETE strcpy(remcomOutBuffer, "OK"); +// OBSOLETE break; +// OBSOLETE case 'X': /* XAA..AA,LLLL:<binary data>#cs */ +// OBSOLETE binary = 1; +// OBSOLETE case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ +// OBSOLETE /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */ +// OBSOLETE { +// OBSOLETE if (hexToInt(&ptr,&addr)) +// OBSOLETE if (*(ptr++) == ',') +// OBSOLETE if (hexToInt(&ptr,&length)) +// OBSOLETE if (*(ptr++) == ':') +// OBSOLETE { +// OBSOLETE mem_err = 0; +// OBSOLETE if (binary) +// OBSOLETE bin2mem (ptr, (unsigned char *) addr, length, 1); +// OBSOLETE else +// OBSOLETE hex2mem(ptr, (unsigned char*) addr, length, 1); +// OBSOLETE if (mem_err) { +// OBSOLETE strcpy (remcomOutBuffer, "E03"); +// OBSOLETE gdb_error ("memory fault", ""); +// OBSOLETE } else { +// OBSOLETE strcpy(remcomOutBuffer,"OK"); +// OBSOLETE } +// OBSOLETE ptr = 0; +// OBSOLETE } +// OBSOLETE if (ptr) +// OBSOLETE { +// OBSOLETE strcpy(remcomOutBuffer,"E02"); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE break; +// OBSOLETE case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ +// OBSOLETE /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */ +// OBSOLETE if (hexToInt(&ptr,&addr)) +// OBSOLETE if (*(ptr++) == ',') +// OBSOLETE if (hexToInt(&ptr,&length)) +// OBSOLETE { +// OBSOLETE ptr = 0; +// OBSOLETE mem_err = 0; +// OBSOLETE mem2hex((unsigned char*) addr, remcomOutBuffer, length, 1); +// OBSOLETE if (mem_err) { +// OBSOLETE strcpy (remcomOutBuffer, "E03"); +// OBSOLETE gdb_error ("memory fault", ""); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE if (ptr) +// OBSOLETE { +// OBSOLETE strcpy(remcomOutBuffer,"E01"); +// OBSOLETE } +// OBSOLETE break; +// OBSOLETE case '?': +// OBSOLETE remcomOutBuffer[0] = 'S'; +// OBSOLETE remcomOutBuffer[1] = hexchars[sigval >> 4]; +// OBSOLETE remcomOutBuffer[2] = hexchars[sigval % 16]; +// OBSOLETE remcomOutBuffer[3] = 0; +// OBSOLETE break; +// OBSOLETE case 'd': +// OBSOLETE remote_debug = !(remote_debug); /* toggle debug flag */ +// OBSOLETE break; +// OBSOLETE case 'g': /* return the value of the CPU registers */ +// OBSOLETE mem2hex((unsigned char*) registers, remcomOutBuffer, NUMREGBYTES, 0); +// OBSOLETE break; +// OBSOLETE case 'P': /* set the value of a single CPU register - return OK */ +// OBSOLETE { +// OBSOLETE int regno; +// OBSOLETE +// OBSOLETE if (hexToInt (&ptr, ®no) && *ptr++ == '=') +// OBSOLETE if (regno >= 0 && regno < NUMREGS) +// OBSOLETE { +// OBSOLETE int stackmode; +// OBSOLETE +// OBSOLETE hex2mem (ptr, (unsigned char *) ®isters[regno], 4, 0); +// OBSOLETE /* +// OBSOLETE * Since we just changed a single CPU register, let's +// OBSOLETE * make sure to keep the several stack pointers consistant. +// OBSOLETE */ +// OBSOLETE stackmode = registers[PSW] & 0x80; +// OBSOLETE if (regno == R15) /* stack pointer changed */ +// OBSOLETE { /* need to change SPI or SPU */ +// OBSOLETE if (stackmode == 0) +// OBSOLETE registers[SPI] = registers[R15]; +// OBSOLETE else +// OBSOLETE registers[SPU] = registers[R15]; +// OBSOLETE } +// OBSOLETE else if (regno == SPU) /* "user" stack pointer changed */ +// OBSOLETE { +// OBSOLETE if (stackmode != 0) /* stack in user mode: copy SP */ +// OBSOLETE registers[R15] = registers[SPU]; +// OBSOLETE } +// OBSOLETE else if (regno == SPI) /* "interrupt" stack pointer changed */ +// OBSOLETE { +// OBSOLETE if (stackmode == 0) /* stack in interrupt mode: copy SP */ +// OBSOLETE registers[R15] = registers[SPI]; +// OBSOLETE } +// OBSOLETE else if (regno == PSW) /* stack mode may have changed! */ +// OBSOLETE { /* force SP to either SPU or SPI */ +// OBSOLETE if (stackmode == 0) /* stack in user mode */ +// OBSOLETE registers[R15] = registers[SPI]; +// OBSOLETE else /* stack in interrupt mode */ +// OBSOLETE registers[R15] = registers[SPU]; +// OBSOLETE } +// OBSOLETE strcpy (remcomOutBuffer, "OK"); +// OBSOLETE break; +// OBSOLETE } +// OBSOLETE strcpy (remcomOutBuffer, "E01"); +// OBSOLETE break; +// OBSOLETE } +// OBSOLETE case 'G': /* set the value of the CPU registers - return OK */ +// OBSOLETE hex2mem(ptr, (unsigned char*) registers, NUMREGBYTES, 0); +// OBSOLETE strcpy(remcomOutBuffer,"OK"); +// OBSOLETE break; +// OBSOLETE case 's': /* sAA..AA Step one instruction from AA..AA(optional) */ +// OBSOLETE stepping = 1; +// OBSOLETE case 'c': /* cAA..AA Continue from address AA..AA(optional) */ +// OBSOLETE /* try to read optional parameter, pc unchanged if no parm */ +// OBSOLETE if (hexToInt(&ptr,&addr)) +// OBSOLETE registers[ PC ] = addr; +// OBSOLETE +// OBSOLETE if (stepping) /* single-stepping */ +// OBSOLETE { +// OBSOLETE if (!prepare_to_step(0)) /* set up for single-step */ +// OBSOLETE { +// OBSOLETE /* prepare_to_step has already emulated the target insn: +// OBSOLETE Send SIGTRAP to gdb, don't resume the target at all. */ +// OBSOLETE ptr = remcomOutBuffer; +// OBSOLETE *ptr++ = 'T'; /* Simulate stopping with SIGTRAP */ +// OBSOLETE *ptr++ = '0'; +// OBSOLETE *ptr++ = '5'; +// OBSOLETE +// OBSOLETE *ptr++ = hexchars[PC >> 4]; /* send PC */ +// OBSOLETE *ptr++ = hexchars[PC & 0xf]; +// OBSOLETE *ptr++ = ':'; +// OBSOLETE ptr = mem2hex((unsigned char *)®isters[PC], ptr, 4, 0); +// OBSOLETE *ptr++ = ';'; +// OBSOLETE +// OBSOLETE *ptr++ = hexchars[R13 >> 4]; /* send FP */ +// OBSOLETE *ptr++ = hexchars[R13 & 0xf]; +// OBSOLETE *ptr++ = ':'; +// OBSOLETE ptr = mem2hex((unsigned char *)®isters[R13], ptr, 4, 0); +// OBSOLETE *ptr++ = ';'; +// OBSOLETE +// OBSOLETE *ptr++ = hexchars[R15 >> 4]; /* send SP */ +// OBSOLETE *ptr++ = hexchars[R15 & 0xf]; +// OBSOLETE *ptr++ = ':'; +// OBSOLETE ptr = mem2hex((unsigned char *)®isters[R15], ptr, 4, 0); +// OBSOLETE *ptr++ = ';'; +// OBSOLETE *ptr++ = 0; +// OBSOLETE +// OBSOLETE break; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE else /* continuing, not single-stepping */ +// OBSOLETE { +// OBSOLETE /* OK, about to do a "continue". First check to see if the +// OBSOLETE target pc is on an odd boundary (second instruction in the +// OBSOLETE word). If so, we must do a single-step first, because +// OBSOLETE ya can't jump or return back to an odd boundary! */ +// OBSOLETE if ((registers[PC] & 2) != 0) +// OBSOLETE prepare_to_step(1); +// OBSOLETE } +// OBSOLETE +// OBSOLETE return; +// OBSOLETE +// OBSOLETE case 'D': /* Detach */ +// OBSOLETE #if 0 +// OBSOLETE /* I am interpreting this to mean, release the board from control +// OBSOLETE by the remote stub. To do this, I am restoring the original +// OBSOLETE (or at least previous) exception vectors. +// OBSOLETE */ +// OBSOLETE for (i = 0; i < 18; i++) +// OBSOLETE exceptionHandler (i, save_vectors[i]); +// OBSOLETE putpacket ("OK"); +// OBSOLETE return; /* continue the inferior */ +// OBSOLETE #else +// OBSOLETE strcpy(remcomOutBuffer,"OK"); +// OBSOLETE break; +// OBSOLETE #endif +// OBSOLETE case 'q': +// OBSOLETE if (*ptr++ == 'C' && +// OBSOLETE *ptr++ == 'R' && +// OBSOLETE *ptr++ == 'C' && +// OBSOLETE *ptr++ == ':') +// OBSOLETE { +// OBSOLETE unsigned long start, len, our_crc; +// OBSOLETE +// OBSOLETE if (hexToInt (&ptr, (int *) &start) && +// OBSOLETE *ptr++ == ',' && +// OBSOLETE hexToInt (&ptr, (int *) &len)) +// OBSOLETE { +// OBSOLETE remcomOutBuffer[0] = 'C'; +// OBSOLETE our_crc = crc32 ((unsigned char *) start, len, 0xffffffff); +// OBSOLETE mem2hex ((char *) &our_crc, +// OBSOLETE &remcomOutBuffer[1], +// OBSOLETE sizeof (long), +// OBSOLETE 0); +// OBSOLETE } /* else do nothing */ +// OBSOLETE } /* else do nothing */ +// OBSOLETE break; +// OBSOLETE +// OBSOLETE case 'k': /* kill the program */ +// OBSOLETE continue; +// OBSOLETE } /* switch */ +// OBSOLETE +// OBSOLETE /* reply to the request */ +// OBSOLETE putpacket(remcomOutBuffer); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* qCRC support */ +// OBSOLETE +// OBSOLETE /* Table used by the crc32 function to calcuate the checksum. */ +// OBSOLETE static unsigned long crc32_table[256] = {0, 0}; +// OBSOLETE +// OBSOLETE static unsigned long +// OBSOLETE crc32 (unsigned char *buf, int len, unsigned long crc) +// OBSOLETE { +// OBSOLETE if (! crc32_table[1]) +// OBSOLETE { +// OBSOLETE /* Initialize the CRC table and the decoding table. */ +// OBSOLETE int i, j; +// OBSOLETE unsigned long c; +// OBSOLETE +// OBSOLETE for (i = 0; i < 256; i++) +// OBSOLETE { +// OBSOLETE for (c = i << 24, j = 8; j > 0; --j) +// OBSOLETE c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1); +// OBSOLETE crc32_table[i] = c; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE while (len--) +// OBSOLETE { +// OBSOLETE crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buf) & 255]; +// OBSOLETE buf++; +// OBSOLETE } +// OBSOLETE return crc; +// OBSOLETE } +// OBSOLETE +// OBSOLETE static int +// OBSOLETE hex (unsigned char ch) +// OBSOLETE { +// OBSOLETE if ((ch >= 'a') && (ch <= 'f')) return (ch-'a'+10); +// OBSOLETE if ((ch >= '0') && (ch <= '9')) return (ch-'0'); +// OBSOLETE if ((ch >= 'A') && (ch <= 'F')) return (ch-'A'+10); +// OBSOLETE return (-1); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* scan for the sequence $<data>#<checksum> */ +// OBSOLETE +// OBSOLETE unsigned char * +// OBSOLETE getpacket (void) +// OBSOLETE { +// OBSOLETE unsigned char *buffer = &remcomInBuffer[0]; +// OBSOLETE unsigned char checksum; +// OBSOLETE unsigned char xmitcsum; +// OBSOLETE int count; +// OBSOLETE char ch; +// OBSOLETE +// OBSOLETE while (1) +// OBSOLETE { +// OBSOLETE /* wait around for the start character, ignore all other characters */ +// OBSOLETE while ((ch = getDebugChar ()) != '$') +// OBSOLETE ; +// OBSOLETE +// OBSOLETE retry: +// OBSOLETE checksum = 0; +// OBSOLETE xmitcsum = -1; +// OBSOLETE count = 0; +// OBSOLETE +// OBSOLETE /* now, read until a # or end of buffer is found */ +// OBSOLETE while (count < BUFMAX) +// OBSOLETE { +// OBSOLETE ch = getDebugChar (); +// OBSOLETE if (ch == '$') +// OBSOLETE goto retry; +// OBSOLETE if (ch == '#') +// OBSOLETE break; +// OBSOLETE checksum = checksum + ch; +// OBSOLETE buffer[count] = ch; +// OBSOLETE count = count + 1; +// OBSOLETE } +// OBSOLETE buffer[count] = 0; +// OBSOLETE +// OBSOLETE if (ch == '#') +// OBSOLETE { +// OBSOLETE ch = getDebugChar (); +// OBSOLETE xmitcsum = hex (ch) << 4; +// OBSOLETE ch = getDebugChar (); +// OBSOLETE xmitcsum += hex (ch); +// OBSOLETE +// OBSOLETE if (checksum != xmitcsum) +// OBSOLETE { +// OBSOLETE if (remote_debug) +// OBSOLETE { +// OBSOLETE unsigned char buf[16]; +// OBSOLETE +// OBSOLETE mem2hex((unsigned char *) &checksum, buf, 4, 0); +// OBSOLETE gdb_error("Bad checksum: my count = %s, ", buf); +// OBSOLETE mem2hex((unsigned char *) &xmitcsum, buf, 4, 0); +// OBSOLETE gdb_error("sent count = %s\n", buf); +// OBSOLETE gdb_error(" -- Bad buffer: \"%s\"\n", buffer); +// OBSOLETE } +// OBSOLETE putDebugChar ('-'); /* failed checksum */ +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE putDebugChar ('+'); /* successful transfer */ +// OBSOLETE +// OBSOLETE /* if a sequence char is present, reply the sequence ID */ +// OBSOLETE if (buffer[2] == ':') +// OBSOLETE { +// OBSOLETE putDebugChar (buffer[0]); +// OBSOLETE putDebugChar (buffer[1]); +// OBSOLETE +// OBSOLETE return &buffer[3]; +// OBSOLETE } +// OBSOLETE +// OBSOLETE return &buffer[0]; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* send the packet in buffer. */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE putpacket (unsigned char *buffer) +// OBSOLETE { +// OBSOLETE unsigned char checksum; +// OBSOLETE int count; +// OBSOLETE char ch; +// OBSOLETE +// OBSOLETE /* $<packet info>#<checksum>. */ +// OBSOLETE do { +// OBSOLETE putDebugChar('$'); +// OBSOLETE checksum = 0; +// OBSOLETE count = 0; +// OBSOLETE +// OBSOLETE while (ch=buffer[count]) { +// OBSOLETE putDebugChar(ch); +// OBSOLETE checksum += ch; +// OBSOLETE count += 1; +// OBSOLETE } +// OBSOLETE putDebugChar('#'); +// OBSOLETE putDebugChar(hexchars[checksum >> 4]); +// OBSOLETE putDebugChar(hexchars[checksum % 16]); +// OBSOLETE } while (getDebugChar() != '+'); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Address of a routine to RTE to if we get a memory fault. */ +// OBSOLETE +// OBSOLETE static void (*volatile mem_fault_routine)() = 0; +// OBSOLETE +// OBSOLETE static void +// OBSOLETE set_mem_err (void) +// OBSOLETE { +// OBSOLETE mem_err = 1; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Check the address for safe access ranges. As currently defined, +// OBSOLETE this routine will reject the "expansion bus" address range(s). +// OBSOLETE To make those ranges useable, someone must implement code to detect +// OBSOLETE whether there's anything connected to the expansion bus. */ +// OBSOLETE +// OBSOLETE static int +// OBSOLETE mem_safe (unsigned char *addr) +// OBSOLETE { +// OBSOLETE #define BAD_RANGE_ONE_START ((unsigned char *) 0x600000) +// OBSOLETE #define BAD_RANGE_ONE_END ((unsigned char *) 0xa00000) +// OBSOLETE #define BAD_RANGE_TWO_START ((unsigned char *) 0xff680000) +// OBSOLETE #define BAD_RANGE_TWO_END ((unsigned char *) 0xff800000) +// OBSOLETE +// OBSOLETE if (addr < BAD_RANGE_ONE_START) return 1; /* safe */ +// OBSOLETE if (addr < BAD_RANGE_ONE_END) return 0; /* unsafe */ +// OBSOLETE if (addr < BAD_RANGE_TWO_START) return 1; /* safe */ +// OBSOLETE if (addr < BAD_RANGE_TWO_END) return 0; /* unsafe */ +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* These are separate functions so that they are so short and sweet +// OBSOLETE that the compiler won't save any registers (if there is a fault +// OBSOLETE to mem_fault, they won't get restored, so there better not be any +// OBSOLETE saved). */ +// OBSOLETE static int +// OBSOLETE get_char (unsigned char *addr) +// OBSOLETE { +// OBSOLETE #if 1 +// OBSOLETE if (mem_fault_routine && !mem_safe(addr)) +// OBSOLETE { +// OBSOLETE mem_fault_routine (); +// OBSOLETE return 0; +// OBSOLETE } +// OBSOLETE #endif +// OBSOLETE return *addr; +// OBSOLETE } +// OBSOLETE +// OBSOLETE static void +// OBSOLETE set_char (unsigned char *addr, unsigned char val) +// OBSOLETE { +// OBSOLETE #if 1 +// OBSOLETE if (mem_fault_routine && !mem_safe (addr)) +// OBSOLETE { +// OBSOLETE mem_fault_routine (); +// OBSOLETE return; +// OBSOLETE } +// OBSOLETE #endif +// OBSOLETE *addr = val; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Convert the memory pointed to by mem into hex, placing result in buf. +// OBSOLETE Return a pointer to the last char put in buf (null). +// OBSOLETE If MAY_FAULT is non-zero, then we should set mem_err in response to +// OBSOLETE a fault; if zero treat a fault like any other fault in the stub. */ +// OBSOLETE +// OBSOLETE static unsigned char * +// OBSOLETE mem2hex (unsigned char *mem, unsigned char *buf, int count, int may_fault) +// OBSOLETE { +// OBSOLETE int i; +// OBSOLETE unsigned char ch; +// OBSOLETE +// OBSOLETE if (may_fault) +// OBSOLETE mem_fault_routine = set_mem_err; +// OBSOLETE for (i=0;i<count;i++) { +// OBSOLETE ch = get_char (mem++); +// OBSOLETE if (may_fault && mem_err) +// OBSOLETE return (buf); +// OBSOLETE *buf++ = hexchars[ch >> 4]; +// OBSOLETE *buf++ = hexchars[ch % 16]; +// OBSOLETE } +// OBSOLETE *buf = 0; +// OBSOLETE if (may_fault) +// OBSOLETE mem_fault_routine = 0; +// OBSOLETE return(buf); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Convert the hex array pointed to by buf into binary to be placed in mem. +// OBSOLETE Return a pointer to the character AFTER the last byte written. */ +// OBSOLETE +// OBSOLETE static unsigned char* +// OBSOLETE hex2mem (unsigned char *buf, unsigned char *mem, int count, int may_fault) +// OBSOLETE { +// OBSOLETE int i; +// OBSOLETE unsigned char ch; +// OBSOLETE +// OBSOLETE if (may_fault) +// OBSOLETE mem_fault_routine = set_mem_err; +// OBSOLETE for (i=0;i<count;i++) { +// OBSOLETE ch = hex(*buf++) << 4; +// OBSOLETE ch = ch + hex(*buf++); +// OBSOLETE set_char (mem++, ch); +// OBSOLETE if (may_fault && mem_err) +// OBSOLETE return (mem); +// OBSOLETE } +// OBSOLETE if (may_fault) +// OBSOLETE mem_fault_routine = 0; +// OBSOLETE return(mem); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Convert the binary stream in BUF to memory. +// OBSOLETE +// OBSOLETE Gdb will escape $, #, and the escape char (0x7d). +// OBSOLETE COUNT is the total number of bytes to write into +// OBSOLETE memory. */ +// OBSOLETE static unsigned char * +// OBSOLETE bin2mem (unsigned char *buf, unsigned char *mem, int count, int may_fault) +// OBSOLETE { +// OBSOLETE int i; +// OBSOLETE unsigned char ch; +// OBSOLETE +// OBSOLETE if (may_fault) +// OBSOLETE mem_fault_routine = set_mem_err; +// OBSOLETE for (i = 0; i < count; i++) +// OBSOLETE { +// OBSOLETE /* Check for any escaped characters. Be paranoid and +// OBSOLETE only unescape chars that should be escaped. */ +// OBSOLETE if (*buf == 0x7d) +// OBSOLETE { +// OBSOLETE switch (*(buf+1)) +// OBSOLETE { +// OBSOLETE case 0x3: /* # */ +// OBSOLETE case 0x4: /* $ */ +// OBSOLETE case 0x5d: /* escape char */ +// OBSOLETE buf++; +// OBSOLETE *buf |= 0x20; +// OBSOLETE break; +// OBSOLETE default: +// OBSOLETE /* nothing */ +// OBSOLETE break; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE set_char (mem++, *buf++); +// OBSOLETE +// OBSOLETE if (may_fault && mem_err) +// OBSOLETE return mem; +// OBSOLETE } +// OBSOLETE +// OBSOLETE if (may_fault) +// OBSOLETE mem_fault_routine = 0; +// OBSOLETE return mem; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* this function takes the m32r exception vector and attempts to +// OBSOLETE translate this number into a unix compatible signal value */ +// OBSOLETE +// OBSOLETE static int +// OBSOLETE computeSignal (int exceptionVector) +// OBSOLETE { +// OBSOLETE int sigval; +// OBSOLETE switch (exceptionVector) { +// OBSOLETE case 0 : sigval = 23; break; /* I/O trap */ +// OBSOLETE case 1 : sigval = 5; break; /* breakpoint */ +// OBSOLETE case 2 : sigval = 5; break; /* breakpoint */ +// OBSOLETE case 3 : sigval = 5; break; /* breakpoint */ +// OBSOLETE case 4 : sigval = 5; break; /* breakpoint */ +// OBSOLETE case 5 : sigval = 5; break; /* breakpoint */ +// OBSOLETE case 6 : sigval = 5; break; /* breakpoint */ +// OBSOLETE case 7 : sigval = 5; break; /* breakpoint */ +// OBSOLETE case 8 : sigval = 5; break; /* breakpoint */ +// OBSOLETE case 9 : sigval = 5; break; /* breakpoint */ +// OBSOLETE case 10 : sigval = 5; break; /* breakpoint */ +// OBSOLETE case 11 : sigval = 5; break; /* breakpoint */ +// OBSOLETE case 12 : sigval = 5; break; /* breakpoint */ +// OBSOLETE case 13 : sigval = 5; break; /* breakpoint */ +// OBSOLETE case 14 : sigval = 5; break; /* breakpoint */ +// OBSOLETE case 15 : sigval = 5; break; /* breakpoint */ +// OBSOLETE case 16 : sigval = 10; break; /* BUS ERROR (alignment) */ +// OBSOLETE case 17 : sigval = 2; break; /* INTerrupt */ +// OBSOLETE default : sigval = 7; break; /* "software generated" */ +// OBSOLETE } +// OBSOLETE return (sigval); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /**********************************************/ +// OBSOLETE /* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */ +// OBSOLETE /* RETURN NUMBER OF CHARS PROCESSED */ +// OBSOLETE /**********************************************/ +// OBSOLETE static int +// OBSOLETE hexToInt (unsigned char **ptr, int *intValue) +// OBSOLETE { +// OBSOLETE int numChars = 0; +// OBSOLETE int hexValue; +// OBSOLETE +// OBSOLETE *intValue = 0; +// OBSOLETE while (**ptr) +// OBSOLETE { +// OBSOLETE hexValue = hex(**ptr); +// OBSOLETE if (hexValue >=0) +// OBSOLETE { +// OBSOLETE *intValue = (*intValue <<4) | hexValue; +// OBSOLETE numChars ++; +// OBSOLETE } +// OBSOLETE else +// OBSOLETE break; +// OBSOLETE (*ptr)++; +// OBSOLETE } +// OBSOLETE return (numChars); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* +// OBSOLETE Table of branch instructions: +// OBSOLETE +// OBSOLETE 10B6 RTE return from trap or exception +// OBSOLETE 1FCr JMP jump +// OBSOLETE 1ECr JL jump and link +// OBSOLETE 7Fxx BRA branch +// OBSOLETE FFxxxxxx BRA branch (long) +// OBSOLETE B09rxxxx BNEZ branch not-equal-zero +// OBSOLETE Br1rxxxx BNE branch not-equal +// OBSOLETE 7Dxx BNC branch not-condition +// OBSOLETE FDxxxxxx BNC branch not-condition (long) +// OBSOLETE B0Arxxxx BLTZ branch less-than-zero +// OBSOLETE B0Crxxxx BLEZ branch less-equal-zero +// OBSOLETE 7Exx BL branch and link +// OBSOLETE FExxxxxx BL branch and link (long) +// OBSOLETE B0Drxxxx BGTZ branch greater-than-zero +// OBSOLETE B0Brxxxx BGEZ branch greater-equal-zero +// OBSOLETE B08rxxxx BEQZ branch equal-zero +// OBSOLETE Br0rxxxx BEQ branch equal +// OBSOLETE 7Cxx BC branch condition +// OBSOLETE FCxxxxxx BC branch condition (long) +// OBSOLETE */ +// OBSOLETE +// OBSOLETE static int +// OBSOLETE isShortBranch (unsigned char *instr) +// OBSOLETE { +// OBSOLETE unsigned char instr0 = instr[0] & 0x7F; /* mask off high bit */ +// OBSOLETE +// OBSOLETE if (instr0 == 0x10 && instr[1] == 0xB6) /* RTE */ +// OBSOLETE return 1; /* return from trap or exception */ +// OBSOLETE +// OBSOLETE if (instr0 == 0x1E || instr0 == 0x1F) /* JL or JMP */ +// OBSOLETE if ((instr[1] & 0xF0) == 0xC0) +// OBSOLETE return 2; /* jump thru a register */ +// OBSOLETE +// OBSOLETE if (instr0 == 0x7C || instr0 == 0x7D || /* BC, BNC, BL, BRA */ +// OBSOLETE instr0 == 0x7E || instr0 == 0x7F) +// OBSOLETE return 3; /* eight bit PC offset */ +// OBSOLETE +// OBSOLETE return 0; +// OBSOLETE } +// OBSOLETE +// OBSOLETE static int +// OBSOLETE isLongBranch (unsigned char *instr) +// OBSOLETE { +// OBSOLETE if (instr[0] == 0xFC || instr[0] == 0xFD || /* BRA, BNC, BL, BC */ +// OBSOLETE instr[0] == 0xFE || instr[0] == 0xFF) /* 24 bit relative */ +// OBSOLETE return 4; +// OBSOLETE if ((instr[0] & 0xF0) == 0xB0) /* 16 bit relative */ +// OBSOLETE { +// OBSOLETE if ((instr[1] & 0xF0) == 0x00 || /* BNE, BEQ */ +// OBSOLETE (instr[1] & 0xF0) == 0x10) +// OBSOLETE return 5; +// OBSOLETE if (instr[0] == 0xB0) /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ, BEQZ */ +// OBSOLETE if ((instr[1] & 0xF0) == 0x80 || (instr[1] & 0xF0) == 0x90 || +// OBSOLETE (instr[1] & 0xF0) == 0xA0 || (instr[1] & 0xF0) == 0xB0 || +// OBSOLETE (instr[1] & 0xF0) == 0xC0 || (instr[1] & 0xF0) == 0xD0) +// OBSOLETE return 6; +// OBSOLETE } +// OBSOLETE return 0; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* if address is NOT on a 4-byte boundary, or high-bit of instr is zero, +// OBSOLETE then it's a 2-byte instruction, else it's a 4-byte instruction. */ +// OBSOLETE +// OBSOLETE #define INSTRUCTION_SIZE(addr) \ +// OBSOLETE ((((int) addr & 2) || (((unsigned char *) addr)[0] & 0x80) == 0) ? 2 : 4) +// OBSOLETE +// OBSOLETE static int +// OBSOLETE isBranch (unsigned char *instr) +// OBSOLETE { +// OBSOLETE if (INSTRUCTION_SIZE(instr) == 2) +// OBSOLETE return isShortBranch(instr); +// OBSOLETE else +// OBSOLETE return isLongBranch(instr); +// OBSOLETE } +// OBSOLETE +// OBSOLETE static int +// OBSOLETE willBranch (unsigned char *instr, int branchCode) +// OBSOLETE { +// OBSOLETE switch (branchCode) +// OBSOLETE { +// OBSOLETE case 0: return 0; /* not a branch */ +// OBSOLETE case 1: return 1; /* RTE */ +// OBSOLETE case 2: return 1; /* JL or JMP */ +// OBSOLETE case 3: /* BC, BNC, BL, BRA (short) */ +// OBSOLETE case 4: /* BC, BNC, BL, BRA (long) */ +// OBSOLETE switch (instr[0] & 0x0F) +// OBSOLETE { +// OBSOLETE case 0xC: /* Branch if Condition Register */ +// OBSOLETE return (registers[CBR] != 0); +// OBSOLETE case 0xD: /* Branch if NOT Condition Register */ +// OBSOLETE return (registers[CBR] == 0); +// OBSOLETE case 0xE: /* Branch and Link */ +// OBSOLETE case 0xF: /* Branch (unconditional) */ +// OBSOLETE return 1; +// OBSOLETE default: /* oops? */ +// OBSOLETE return 0; +// OBSOLETE } +// OBSOLETE case 5: /* BNE, BEQ */ +// OBSOLETE switch (instr[1] & 0xF0) +// OBSOLETE { +// OBSOLETE case 0x00: /* Branch if r1 equal to r2 */ +// OBSOLETE return (registers[instr[0] & 0x0F] == registers[instr[1] & 0x0F]); +// OBSOLETE case 0x10: /* Branch if r1 NOT equal to r2 */ +// OBSOLETE return (registers[instr[0] & 0x0F] != registers[instr[1] & 0x0F]); +// OBSOLETE default: /* oops? */ +// OBSOLETE return 0; +// OBSOLETE } +// OBSOLETE case 6: /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ ,BEQZ */ +// OBSOLETE switch (instr[1] & 0xF0) +// OBSOLETE { +// OBSOLETE case 0x80: /* Branch if reg equal to zero */ +// OBSOLETE return (registers[instr[1] & 0x0F] == 0); +// OBSOLETE case 0x90: /* Branch if reg NOT equal to zero */ +// OBSOLETE return (registers[instr[1] & 0x0F] != 0); +// OBSOLETE case 0xA0: /* Branch if reg less than zero */ +// OBSOLETE return (registers[instr[1] & 0x0F] < 0); +// OBSOLETE case 0xB0: /* Branch if reg greater or equal to zero */ +// OBSOLETE return (registers[instr[1] & 0x0F] >= 0); +// OBSOLETE case 0xC0: /* Branch if reg less than or equal to zero */ +// OBSOLETE return (registers[instr[1] & 0x0F] <= 0); +// OBSOLETE case 0xD0: /* Branch if reg greater than zero */ +// OBSOLETE return (registers[instr[1] & 0x0F] > 0); +// OBSOLETE default: /* oops? */ +// OBSOLETE return 0; +// OBSOLETE } +// OBSOLETE default: /* oops? */ +// OBSOLETE return 0; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE static int +// OBSOLETE branchDestination (unsigned char *instr, int branchCode) +// OBSOLETE { +// OBSOLETE switch (branchCode) { +// OBSOLETE default: +// OBSOLETE case 0: /* not a branch */ +// OBSOLETE return 0; +// OBSOLETE case 1: /* RTE */ +// OBSOLETE return registers[BPC] & ~3; /* pop BPC into PC */ +// OBSOLETE case 2: /* JL or JMP */ +// OBSOLETE return registers[instr[1] & 0x0F] & ~3; /* jump thru a register */ +// OBSOLETE case 3: /* BC, BNC, BL, BRA (short, 8-bit relative offset) */ +// OBSOLETE return (((int) instr) & ~3) + ((char) instr[1] << 2); +// OBSOLETE case 4: /* BC, BNC, BL, BRA (long, 24-bit relative offset) */ +// OBSOLETE return ((int) instr + +// OBSOLETE ((((char) instr[1] << 16) | (instr[2] << 8) | (instr[3])) << 2)); +// OBSOLETE case 5: /* BNE, BEQ (16-bit relative offset) */ +// OBSOLETE case 6: /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ ,BEQZ (ditto) */ +// OBSOLETE return ((int) instr + ((((char) instr[2] << 8) | (instr[3])) << 2)); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* An explanatory note: in the last three return expressions, I have +// OBSOLETE cast the most-significant byte of the return offset to char. +// OBSOLETE What this accomplishes is sign extension. If the other +// OBSOLETE less-significant bytes were signed as well, they would get sign +// OBSOLETE extended too and, if negative, their leading bits would clobber +// OBSOLETE the bits of the more-significant bytes ahead of them. There are +// OBSOLETE other ways I could have done this, but sign extension from +// OBSOLETE odd-sized integers is always a pain. */ +// OBSOLETE } +// OBSOLETE +// OBSOLETE static void +// OBSOLETE branchSideEffects (unsigned char *instr, int branchCode) +// OBSOLETE { +// OBSOLETE switch (branchCode) +// OBSOLETE { +// OBSOLETE case 1: /* RTE */ +// OBSOLETE return; /* I <THINK> this is already handled... */ +// OBSOLETE case 2: /* JL (or JMP) */ +// OBSOLETE case 3: /* BL (or BC, BNC, BRA) */ +// OBSOLETE case 4: +// OBSOLETE if ((instr[0] & 0x0F) == 0x0E) /* branch/jump and link */ +// OBSOLETE registers[R14] = (registers[PC] & ~3) + 4; +// OBSOLETE return; +// OBSOLETE default: /* any other branch has no side effects */ +// OBSOLETE return; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE static struct STEPPING_CONTEXT { +// OBSOLETE int stepping; /* true when we've started a single-step */ +// OBSOLETE unsigned long target_addr; /* the instr we're trying to execute */ +// OBSOLETE unsigned long target_size; /* the size of the target instr */ +// OBSOLETE unsigned long noop_addr; /* where we've inserted a no-op, if any */ +// OBSOLETE unsigned long trap1_addr; /* the trap following the target instr */ +// OBSOLETE unsigned long trap2_addr; /* the trap at a branch destination, if any */ +// OBSOLETE unsigned short noop_save; /* instruction overwritten by our no-op */ +// OBSOLETE unsigned short trap1_save; /* instruction overwritten by trap1 */ +// OBSOLETE unsigned short trap2_save; /* instruction overwritten by trap2 */ +// OBSOLETE unsigned short continue_p; /* true if NOT returning to gdb after step */ +// OBSOLETE } stepping; +// OBSOLETE +// OBSOLETE /* Function: prepare_to_step +// OBSOLETE Called from handle_exception to prepare the user program to single-step. +// OBSOLETE Places a trap instruction after the target instruction, with special +// OBSOLETE extra handling for branch instructions and for instructions in the +// OBSOLETE second half-word of a word. +// OBSOLETE +// OBSOLETE Returns: True if we should actually execute the instruction; +// OBSOLETE False if we are going to emulate executing the instruction, +// OBSOLETE in which case we simply report to GDB that the instruction +// OBSOLETE has already been executed. */ +// OBSOLETE +// OBSOLETE #define TRAP1 0x10f1; /* trap #1 instruction */ +// OBSOLETE #define NOOP 0x7000; /* noop instruction */ +// OBSOLETE +// OBSOLETE static unsigned short trap1 = TRAP1; +// OBSOLETE static unsigned short noop = NOOP; +// OBSOLETE +// OBSOLETE static int +// OBSOLETE prepare_to_step(continue_p) +// OBSOLETE int continue_p; /* if this isn't REALLY a single-step (see below) */ +// OBSOLETE { +// OBSOLETE unsigned long pc = registers[PC]; +// OBSOLETE int branchCode = isBranch((unsigned char *) pc); +// OBSOLETE unsigned char *p; +// OBSOLETE +// OBSOLETE /* zero out the stepping context +// OBSOLETE (paranoia -- it should already be zeroed) */ +// OBSOLETE for (p = (unsigned char *) &stepping; +// OBSOLETE p < ((unsigned char *) &stepping) + sizeof(stepping); +// OBSOLETE p++) +// OBSOLETE *p = 0; +// OBSOLETE +// OBSOLETE if (branchCode != 0) /* next instruction is a branch */ +// OBSOLETE { +// OBSOLETE branchSideEffects((unsigned char *) pc, branchCode); +// OBSOLETE if (willBranch((unsigned char *)pc, branchCode)) +// OBSOLETE registers[PC] = branchDestination((unsigned char *) pc, branchCode); +// OBSOLETE else +// OBSOLETE registers[PC] = pc + INSTRUCTION_SIZE(pc); +// OBSOLETE return 0; /* branch "executed" -- just notify GDB */ +// OBSOLETE } +// OBSOLETE else if (((int) pc & 2) != 0) /* "second-slot" instruction */ +// OBSOLETE { +// OBSOLETE /* insert no-op before pc */ +// OBSOLETE stepping.noop_addr = pc - 2; +// OBSOLETE stepping.noop_save = *(unsigned short *) stepping.noop_addr; +// OBSOLETE *(unsigned short *) stepping.noop_addr = noop; +// OBSOLETE /* insert trap after pc */ +// OBSOLETE stepping.trap1_addr = pc + 2; +// OBSOLETE stepping.trap1_save = *(unsigned short *) stepping.trap1_addr; +// OBSOLETE *(unsigned short *) stepping.trap1_addr = trap1; +// OBSOLETE } +// OBSOLETE else /* "first-slot" instruction */ +// OBSOLETE { +// OBSOLETE /* insert trap after pc */ +// OBSOLETE stepping.trap1_addr = pc + INSTRUCTION_SIZE(pc); +// OBSOLETE stepping.trap1_save = *(unsigned short *) stepping.trap1_addr; +// OBSOLETE *(unsigned short *) stepping.trap1_addr = trap1; +// OBSOLETE } +// OBSOLETE /* "continue_p" means that we are actually doing a continue, and not +// OBSOLETE being requested to single-step by GDB. Sometimes we have to do +// OBSOLETE one single-step before continuing, because the PC is on a half-word +// OBSOLETE boundary. There's no way to simply resume at such an address. */ +// OBSOLETE stepping.continue_p = continue_p; +// OBSOLETE stepping.stepping = 1; /* starting a single-step */ +// OBSOLETE return 1; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Function: finish_from_step +// OBSOLETE Called from handle_exception to finish up when the user program +// OBSOLETE returns from a single-step. Replaces the instructions that had +// OBSOLETE been overwritten by traps or no-ops, +// OBSOLETE +// OBSOLETE Returns: True if we should notify GDB that the target stopped. +// OBSOLETE False if we only single-stepped because we had to before we +// OBSOLETE could continue (ie. we were trying to continue at a +// OBSOLETE half-word boundary). In that case don't notify GDB: +// OBSOLETE just "continue continuing". */ +// OBSOLETE +// OBSOLETE static int +// OBSOLETE finish_from_step (void) +// OBSOLETE { +// OBSOLETE if (stepping.stepping) /* anything to do? */ +// OBSOLETE { +// OBSOLETE int continue_p = stepping.continue_p; +// OBSOLETE unsigned char *p; +// OBSOLETE +// OBSOLETE if (stepping.noop_addr) /* replace instr "under" our no-op */ +// OBSOLETE *(unsigned short *) stepping.noop_addr = stepping.noop_save; +// OBSOLETE if (stepping.trap1_addr) /* replace instr "under" our trap */ +// OBSOLETE *(unsigned short *) stepping.trap1_addr = stepping.trap1_save; +// OBSOLETE if (stepping.trap2_addr) /* ditto our other trap, if any */ +// OBSOLETE *(unsigned short *) stepping.trap2_addr = stepping.trap2_save; +// OBSOLETE +// OBSOLETE for (p = (unsigned char *) &stepping; /* zero out the stepping context */ +// OBSOLETE p < ((unsigned char *) &stepping) + sizeof(stepping); +// OBSOLETE p++) +// OBSOLETE *p = 0; +// OBSOLETE +// OBSOLETE return !(continue_p); +// OBSOLETE } +// OBSOLETE else /* we didn't single-step, therefore this must be a legitimate stop */ +// OBSOLETE return 1; +// OBSOLETE } +// OBSOLETE +// OBSOLETE struct PSWreg { /* separate out the bit flags in the PSW register */ +// OBSOLETE int pad1 : 16; +// OBSOLETE int bsm : 1; +// OBSOLETE int bie : 1; +// OBSOLETE int pad2 : 5; +// OBSOLETE int bc : 1; +// OBSOLETE int sm : 1; +// OBSOLETE int ie : 1; +// OBSOLETE int pad3 : 5; +// OBSOLETE int c : 1; +// OBSOLETE } *psw; +// OBSOLETE +// OBSOLETE /* Upon entry the value for LR to save has been pushed. +// OBSOLETE We unpush that so that the value for the stack pointer saved is correct. +// OBSOLETE Upon entry, all other registers are assumed to have not been modified +// OBSOLETE since the interrupt/trap occured. */ +// OBSOLETE +// OBSOLETE asm (" +// OBSOLETE stash_registers: +// OBSOLETE push r0 +// OBSOLETE push r1 +// OBSOLETE seth r1, #shigh(registers) +// OBSOLETE add3 r1, r1, #low(registers) +// OBSOLETE pop r0 ; r1 +// OBSOLETE st r0, @(4,r1) +// OBSOLETE pop r0 ; r0 +// OBSOLETE st r0, @r1 +// OBSOLETE addi r1, #4 ; only add 4 as subsequent saves are `pre inc' +// OBSOLETE st r2, @+r1 +// OBSOLETE st r3, @+r1 +// OBSOLETE st r4, @+r1 +// OBSOLETE st r5, @+r1 +// OBSOLETE st r6, @+r1 +// OBSOLETE st r7, @+r1 +// OBSOLETE st r8, @+r1 +// OBSOLETE st r9, @+r1 +// OBSOLETE st r10, @+r1 +// OBSOLETE st r11, @+r1 +// OBSOLETE st r12, @+r1 +// OBSOLETE st r13, @+r1 ; fp +// OBSOLETE pop r0 ; lr (r14) +// OBSOLETE st r0, @+r1 +// OBSOLETE st sp, @+r1 ; sp contains right value at this point +// OBSOLETE mvfc r0, cr0 +// OBSOLETE st r0, @+r1 ; cr0 == PSW +// OBSOLETE mvfc r0, cr1 +// OBSOLETE st r0, @+r1 ; cr1 == CBR +// OBSOLETE mvfc r0, cr2 +// OBSOLETE st r0, @+r1 ; cr2 == SPI +// OBSOLETE mvfc r0, cr3 +// OBSOLETE st r0, @+r1 ; cr3 == SPU +// OBSOLETE mvfc r0, cr6 +// OBSOLETE st r0, @+r1 ; cr6 == BPC +// OBSOLETE st r0, @+r1 ; PC == BPC +// OBSOLETE mvfaclo r0 +// OBSOLETE st r0, @+r1 ; ACCL +// OBSOLETE mvfachi r0 +// OBSOLETE st r0, @+r1 ; ACCH +// OBSOLETE jmp lr"); +// OBSOLETE +// OBSOLETE /* C routine to clean up what stash_registers did. +// OBSOLETE It is called after calling stash_registers. +// OBSOLETE This is separate from stash_registers as we want to do this in C +// OBSOLETE but doing stash_registers in C isn't straightforward. */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE cleanup_stash (void) +// OBSOLETE { +// OBSOLETE psw = (struct PSWreg *) ®isters[PSW]; /* fields of PSW register */ +// OBSOLETE psw->sm = psw->bsm; /* fix up pre-trap values of psw fields */ +// OBSOLETE psw->ie = psw->bie; +// OBSOLETE psw->c = psw->bc; +// OBSOLETE registers[CBR] = psw->bc; /* fix up pre-trap "C" register */ +// OBSOLETE +// OBSOLETE #if 0 /* FIXME: Was in previous version. Necessary? +// OBSOLETE (Remember that we use the "rte" insn to return from the +// OBSOLETE trap/interrupt so the values of bsm, bie, bc are important. */ +// OBSOLETE psw->bsm = psw->bie = psw->bc = 0; /* zero post-trap values */ +// OBSOLETE #endif +// OBSOLETE +// OBSOLETE /* FIXME: Copied from previous version. This can probably be deleted +// OBSOLETE since methinks stash_registers has already done this. */ +// OBSOLETE registers[PC] = registers[BPC]; /* pre-trap PC */ +// OBSOLETE +// OBSOLETE /* FIXME: Copied from previous version. Necessary? */ +// OBSOLETE if (psw->sm) /* copy R15 into (psw->sm ? SPU : SPI) */ +// OBSOLETE registers[SPU] = registers[R15]; +// OBSOLETE else +// OBSOLETE registers[SPI] = registers[R15]; +// OBSOLETE } +// OBSOLETE +// OBSOLETE asm (" +// OBSOLETE restore_and_return: +// OBSOLETE seth r0, #shigh(registers+8) +// OBSOLETE add3 r0, r0, #low(registers+8) +// OBSOLETE ld r2, @r0+ ; restore r2 +// OBSOLETE ld r3, @r0+ ; restore r3 +// OBSOLETE ld r4, @r0+ ; restore r4 +// OBSOLETE ld r5, @r0+ ; restore r5 +// OBSOLETE ld r6, @r0+ ; restore r6 +// OBSOLETE ld r7, @r0+ ; restore r7 +// OBSOLETE ld r8, @r0+ ; restore r8 +// OBSOLETE ld r9, @r0+ ; restore r9 +// OBSOLETE ld r10, @r0+ ; restore r10 +// OBSOLETE ld r11, @r0+ ; restore r11 +// OBSOLETE ld r12, @r0+ ; restore r12 +// OBSOLETE ld r13, @r0+ ; restore r13 +// OBSOLETE ld r14, @r0+ ; restore r14 +// OBSOLETE ld r15, @r0+ ; restore r15 +// OBSOLETE addi r0, #4 ; don't restore PSW (rte will do it) +// OBSOLETE ld r1, @r0+ ; restore cr1 == CBR (no-op, because it's read only) +// OBSOLETE mvtc r1, cr1 +// OBSOLETE ld r1, @r0+ ; restore cr2 == SPI +// OBSOLETE mvtc r1, cr2 +// OBSOLETE ld r1, @r0+ ; restore cr3 == SPU +// OBSOLETE mvtc r1, cr3 +// OBSOLETE addi r0, #4 ; skip BPC +// OBSOLETE ld r1, @r0+ ; restore cr6 (BPC) == PC +// OBSOLETE mvtc r1, cr6 +// OBSOLETE ld r1, @r0+ ; restore ACCL +// OBSOLETE mvtaclo r1 +// OBSOLETE ld r1, @r0+ ; restore ACCH +// OBSOLETE mvtachi r1 +// OBSOLETE seth r0, #shigh(registers) +// OBSOLETE add3 r0, r0, #low(registers) +// OBSOLETE ld r1, @(4,r0) ; restore r1 +// OBSOLETE ld r0, @r0 ; restore r0 +// OBSOLETE rte"); +// OBSOLETE +// OBSOLETE /* General trap handler, called after the registers have been stashed. +// OBSOLETE NUM is the trap/exception number. */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE process_exception (int num) +// OBSOLETE { +// OBSOLETE cleanup_stash (); +// OBSOLETE asm volatile (" +// OBSOLETE seth r1, #shigh(stackPtr) +// OBSOLETE add3 r1, r1, #low(stackPtr) +// OBSOLETE ld r15, @r1 ; setup local stack (protect user stack) +// OBSOLETE mv r0, %0 +// OBSOLETE bl handle_exception +// OBSOLETE bl restore_and_return" +// OBSOLETE : : "r" (num) : "r0", "r1"); +// OBSOLETE } +// OBSOLETE +// OBSOLETE void _catchException0 (); +// OBSOLETE +// OBSOLETE asm (" +// OBSOLETE _catchException0: +// OBSOLETE push lr +// OBSOLETE bl stash_registers +// OBSOLETE ; Note that at this point the pushed value of `lr' has been popped +// OBSOLETE ldi r0, #0 +// OBSOLETE bl process_exception"); +// OBSOLETE +// OBSOLETE void _catchException1 (); +// OBSOLETE +// OBSOLETE asm (" +// OBSOLETE _catchException1: +// OBSOLETE push lr +// OBSOLETE bl stash_registers +// OBSOLETE ; Note that at this point the pushed value of `lr' has been popped +// OBSOLETE bl cleanup_stash +// OBSOLETE seth r1, #shigh(stackPtr) +// OBSOLETE add3 r1, r1, #low(stackPtr) +// OBSOLETE ld r15, @r1 ; setup local stack (protect user stack) +// OBSOLETE seth r1, #shigh(registers + 21*4) ; PC +// OBSOLETE add3 r1, r1, #low(registers + 21*4) +// OBSOLETE ld r0, @r1 +// OBSOLETE addi r0, #-4 ; back up PC for breakpoint trap. +// OBSOLETE st r0, @r1 ; FIXME: what about bp in right slot? +// OBSOLETE ldi r0, #1 +// OBSOLETE bl handle_exception +// OBSOLETE bl restore_and_return"); +// OBSOLETE +// OBSOLETE void _catchException2 (); +// OBSOLETE +// OBSOLETE asm (" +// OBSOLETE _catchException2: +// OBSOLETE push lr +// OBSOLETE bl stash_registers +// OBSOLETE ; Note that at this point the pushed value of `lr' has been popped +// OBSOLETE ldi r0, #2 +// OBSOLETE bl process_exception"); +// OBSOLETE +// OBSOLETE void _catchException3 (); +// OBSOLETE +// OBSOLETE asm (" +// OBSOLETE _catchException3: +// OBSOLETE push lr +// OBSOLETE bl stash_registers +// OBSOLETE ; Note that at this point the pushed value of `lr' has been popped +// OBSOLETE ldi r0, #3 +// OBSOLETE bl process_exception"); +// OBSOLETE +// OBSOLETE void _catchException4 (); +// OBSOLETE +// OBSOLETE asm (" +// OBSOLETE _catchException4: +// OBSOLETE push lr +// OBSOLETE bl stash_registers +// OBSOLETE ; Note that at this point the pushed value of `lr' has been popped +// OBSOLETE ldi r0, #4 +// OBSOLETE bl process_exception"); +// OBSOLETE +// OBSOLETE void _catchException5 (); +// OBSOLETE +// OBSOLETE asm (" +// OBSOLETE _catchException5: +// OBSOLETE push lr +// OBSOLETE bl stash_registers +// OBSOLETE ; Note that at this point the pushed value of `lr' has been popped +// OBSOLETE ldi r0, #5 +// OBSOLETE bl process_exception"); +// OBSOLETE +// OBSOLETE void _catchException6 (); +// OBSOLETE +// OBSOLETE asm (" +// OBSOLETE _catchException6: +// OBSOLETE push lr +// OBSOLETE bl stash_registers +// OBSOLETE ; Note that at this point the pushed value of `lr' has been popped +// OBSOLETE ldi r0, #6 +// OBSOLETE bl process_exception"); +// OBSOLETE +// OBSOLETE void _catchException7 (); +// OBSOLETE +// OBSOLETE asm (" +// OBSOLETE _catchException7: +// OBSOLETE push lr +// OBSOLETE bl stash_registers +// OBSOLETE ; Note that at this point the pushed value of `lr' has been popped +// OBSOLETE ldi r0, #7 +// OBSOLETE bl process_exception"); +// OBSOLETE +// OBSOLETE void _catchException8 (); +// OBSOLETE +// OBSOLETE asm (" +// OBSOLETE _catchException8: +// OBSOLETE push lr +// OBSOLETE bl stash_registers +// OBSOLETE ; Note that at this point the pushed value of `lr' has been popped +// OBSOLETE ldi r0, #8 +// OBSOLETE bl process_exception"); +// OBSOLETE +// OBSOLETE void _catchException9 (); +// OBSOLETE +// OBSOLETE asm (" +// OBSOLETE _catchException9: +// OBSOLETE push lr +// OBSOLETE bl stash_registers +// OBSOLETE ; Note that at this point the pushed value of `lr' has been popped +// OBSOLETE ldi r0, #9 +// OBSOLETE bl process_exception"); +// OBSOLETE +// OBSOLETE void _catchException10 (); +// OBSOLETE +// OBSOLETE asm (" +// OBSOLETE _catchException10: +// OBSOLETE push lr +// OBSOLETE bl stash_registers +// OBSOLETE ; Note that at this point the pushed value of `lr' has been popped +// OBSOLETE ldi r0, #10 +// OBSOLETE bl process_exception"); +// OBSOLETE +// OBSOLETE void _catchException11 (); +// OBSOLETE +// OBSOLETE asm (" +// OBSOLETE _catchException11: +// OBSOLETE push lr +// OBSOLETE bl stash_registers +// OBSOLETE ; Note that at this point the pushed value of `lr' has been popped +// OBSOLETE ldi r0, #11 +// OBSOLETE bl process_exception"); +// OBSOLETE +// OBSOLETE void _catchException12 (); +// OBSOLETE +// OBSOLETE asm (" +// OBSOLETE _catchException12: +// OBSOLETE push lr +// OBSOLETE bl stash_registers +// OBSOLETE ; Note that at this point the pushed value of `lr' has been popped +// OBSOLETE ldi r0, #12 +// OBSOLETE bl process_exception"); +// OBSOLETE +// OBSOLETE void _catchException13 (); +// OBSOLETE +// OBSOLETE asm (" +// OBSOLETE _catchException13: +// OBSOLETE push lr +// OBSOLETE bl stash_registers +// OBSOLETE ; Note that at this point the pushed value of `lr' has been popped +// OBSOLETE ldi r0, #13 +// OBSOLETE bl process_exception"); +// OBSOLETE +// OBSOLETE void _catchException14 (); +// OBSOLETE +// OBSOLETE asm (" +// OBSOLETE _catchException14: +// OBSOLETE push lr +// OBSOLETE bl stash_registers +// OBSOLETE ; Note that at this point the pushed value of `lr' has been popped +// OBSOLETE ldi r0, #14 +// OBSOLETE bl process_exception"); +// OBSOLETE +// OBSOLETE void _catchException15 (); +// OBSOLETE +// OBSOLETE asm (" +// OBSOLETE _catchException15: +// OBSOLETE push lr +// OBSOLETE bl stash_registers +// OBSOLETE ; Note that at this point the pushed value of `lr' has been popped +// OBSOLETE ldi r0, #15 +// OBSOLETE bl process_exception"); +// OBSOLETE +// OBSOLETE void _catchException16 (); +// OBSOLETE +// OBSOLETE asm (" +// OBSOLETE _catchException16: +// OBSOLETE push lr +// OBSOLETE bl stash_registers +// OBSOLETE ; Note that at this point the pushed value of `lr' has been popped +// OBSOLETE ldi r0, #16 +// OBSOLETE bl process_exception"); +// OBSOLETE +// OBSOLETE void _catchException17 (); +// OBSOLETE +// OBSOLETE asm (" +// OBSOLETE _catchException17: +// OBSOLETE push lr +// OBSOLETE bl stash_registers +// OBSOLETE ; Note that at this point the pushed value of `lr' has been popped +// OBSOLETE ldi r0, #17 +// OBSOLETE bl process_exception"); +// OBSOLETE +// OBSOLETE +// OBSOLETE /* this function is used to set up exception handlers for tracing and +// OBSOLETE breakpoints */ +// OBSOLETE void +// OBSOLETE set_debug_traps (void) +// OBSOLETE { +// OBSOLETE /* extern void remcomHandler(); */ +// OBSOLETE int i; +// OBSOLETE +// OBSOLETE for (i = 0; i < 18; i++) /* keep a copy of old vectors */ +// OBSOLETE if (save_vectors[i] == 0) /* only copy them the first time */ +// OBSOLETE save_vectors[i] = getExceptionHandler (i); +// OBSOLETE +// OBSOLETE stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1]; +// OBSOLETE +// OBSOLETE exceptionHandler (0, _catchException0); +// OBSOLETE exceptionHandler (1, _catchException1); +// OBSOLETE exceptionHandler (2, _catchException2); +// OBSOLETE exceptionHandler (3, _catchException3); +// OBSOLETE exceptionHandler (4, _catchException4); +// OBSOLETE exceptionHandler (5, _catchException5); +// OBSOLETE exceptionHandler (6, _catchException6); +// OBSOLETE exceptionHandler (7, _catchException7); +// OBSOLETE exceptionHandler (8, _catchException8); +// OBSOLETE exceptionHandler (9, _catchException9); +// OBSOLETE exceptionHandler (10, _catchException10); +// OBSOLETE exceptionHandler (11, _catchException11); +// OBSOLETE exceptionHandler (12, _catchException12); +// OBSOLETE exceptionHandler (13, _catchException13); +// OBSOLETE exceptionHandler (14, _catchException14); +// OBSOLETE exceptionHandler (15, _catchException15); +// OBSOLETE exceptionHandler (16, _catchException16); +// OBSOLETE /* exceptionHandler (17, _catchException17); */ +// OBSOLETE +// OBSOLETE initialized = 1; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* This function will generate a breakpoint exception. It is used at the +// OBSOLETE beginning of a program to sync up with a debugger and can be used +// OBSOLETE otherwise as a quick means to stop program execution and "break" into +// OBSOLETE the debugger. */ +// OBSOLETE +// OBSOLETE #define BREAKPOINT() asm volatile (" trap #2"); +// OBSOLETE +// OBSOLETE void +// OBSOLETE breakpoint (void) +// OBSOLETE { +// OBSOLETE if (initialized) +// OBSOLETE BREAKPOINT(); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* STDOUT section: +// OBSOLETE Stuff pertaining to simulating stdout by sending chars to gdb to be echoed. +// OBSOLETE Functions: gdb_putchar(char ch) +// OBSOLETE gdb_puts(char *str) +// OBSOLETE gdb_write(char *str, int len) +// OBSOLETE gdb_error(char *format, char *parm) +// OBSOLETE */ +// OBSOLETE +// OBSOLETE /* Function: gdb_putchar(int) +// OBSOLETE Make gdb write a char to stdout. +// OBSOLETE Returns: the char */ +// OBSOLETE +// OBSOLETE static int +// OBSOLETE gdb_putchar (int ch) +// OBSOLETE { +// OBSOLETE char buf[4]; +// OBSOLETE +// OBSOLETE buf[0] = 'O'; +// OBSOLETE buf[1] = hexchars[ch >> 4]; +// OBSOLETE buf[2] = hexchars[ch & 0x0F]; +// OBSOLETE buf[3] = 0; +// OBSOLETE putpacket(buf); +// OBSOLETE return ch; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Function: gdb_write(char *, int) +// OBSOLETE Make gdb write n bytes to stdout (not assumed to be null-terminated). +// OBSOLETE Returns: number of bytes written */ +// OBSOLETE +// OBSOLETE static int +// OBSOLETE gdb_write (char *data, int len) +// OBSOLETE { +// OBSOLETE char *buf, *cpy; +// OBSOLETE int i; +// OBSOLETE +// OBSOLETE buf = remcomOutBuffer; +// OBSOLETE buf[0] = 'O'; +// OBSOLETE i = 0; +// OBSOLETE while (i < len) +// OBSOLETE { +// OBSOLETE for (cpy = buf+1; +// OBSOLETE i < len && cpy < buf + sizeof(remcomOutBuffer) - 3; +// OBSOLETE i++) +// OBSOLETE { +// OBSOLETE *cpy++ = hexchars[data[i] >> 4]; +// OBSOLETE *cpy++ = hexchars[data[i] & 0x0F]; +// OBSOLETE } +// OBSOLETE *cpy = 0; +// OBSOLETE putpacket(buf); +// OBSOLETE } +// OBSOLETE return len; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Function: gdb_puts(char *) +// OBSOLETE Make gdb write a null-terminated string to stdout. +// OBSOLETE Returns: the length of the string */ +// OBSOLETE +// OBSOLETE static int +// OBSOLETE gdb_puts (char *str) +// OBSOLETE { +// OBSOLETE return gdb_write(str, strlen(str)); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Function: gdb_error(char *, char *) +// OBSOLETE Send an error message to gdb's stdout. +// OBSOLETE First string may have 1 (one) optional "%s" in it, which +// OBSOLETE will cause the optional second string to be inserted. */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE gdb_error (char *format, char *parm) +// OBSOLETE { +// OBSOLETE char buf[400], *cpy; +// OBSOLETE int len; +// OBSOLETE +// OBSOLETE if (remote_debug) +// OBSOLETE { +// OBSOLETE if (format && *format) +// OBSOLETE len = strlen(format); +// OBSOLETE else +// OBSOLETE return; /* empty input */ +// OBSOLETE +// OBSOLETE if (parm && *parm) +// OBSOLETE len += strlen(parm); +// OBSOLETE +// OBSOLETE for (cpy = buf; *format; ) +// OBSOLETE { +// OBSOLETE if (format[0] == '%' && format[1] == 's') /* include second string */ +// OBSOLETE { +// OBSOLETE format += 2; /* advance two chars instead of just one */ +// OBSOLETE while (parm && *parm) +// OBSOLETE *cpy++ = *parm++; +// OBSOLETE } +// OBSOLETE else +// OBSOLETE *cpy++ = *format++; +// OBSOLETE } +// OBSOLETE *cpy = '\0'; +// OBSOLETE gdb_puts(buf); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE static unsigned char * +// OBSOLETE strcpy (unsigned char *dest, const unsigned char *src) +// OBSOLETE { +// OBSOLETE unsigned char *ret = dest; +// OBSOLETE +// OBSOLETE if (dest && src) +// OBSOLETE { +// OBSOLETE while (*src) +// OBSOLETE *dest++ = *src++; +// OBSOLETE *dest = 0; +// OBSOLETE } +// OBSOLETE return ret; +// OBSOLETE } +// OBSOLETE +// OBSOLETE static int +// OBSOLETE strlen (const unsigned char *src) +// OBSOLETE { +// OBSOLETE int ret; +// OBSOLETE +// OBSOLETE for (ret = 0; *src; src++) +// OBSOLETE ret++; +// OBSOLETE +// OBSOLETE return ret; +// OBSOLETE } +// OBSOLETE +// OBSOLETE #if 0 +// OBSOLETE void exit (code) +// OBSOLETE int code; +// OBSOLETE { +// OBSOLETE _exit (code); +// OBSOLETE } +// OBSOLETE +// OBSOLETE int atexit (void *p) +// OBSOLETE { +// OBSOLETE return 0; +// OBSOLETE } +// OBSOLETE +// OBSOLETE void abort (void) +// OBSOLETE { +// OBSOLETE _exit (1); +// OBSOLETE } +// OBSOLETE #endif diff --git a/gdb/m32r-tdep.c b/gdb/m32r-tdep.c index 64842347ccf..93edbf99a2d 100644 --- a/gdb/m32r-tdep.c +++ b/gdb/m32r-tdep.c @@ -1,708 +1,708 @@ -/* Target-dependent code for the Mitsubishi m32r for GDB, the GNU debugger. - - Copyright 1996, 1998, 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. */ - -#include "defs.h" -#include "frame.h" -#include "inferior.h" -#include "target.h" -#include "value.h" -#include "bfd.h" -#include "gdb_string.h" -#include "gdbcore.h" -#include "symfile.h" -#include "regcache.h" - -/* Function: m32r_use_struct_convention - Return nonzero if call_function should allocate stack space for a - struct return? */ -int -m32r_use_struct_convention (int gcc_p, struct type *type) -{ - return (TYPE_LENGTH (type) > 8); -} - -/* Function: frame_find_saved_regs - Return the frame_saved_regs structure for the frame. - Doesn't really work for dummy frames, but it does pass back - an empty frame_saved_regs, so I guess that's better than total failure */ - -void -m32r_frame_find_saved_regs (struct frame_info *fi, - struct frame_saved_regs *regaddr) -{ - memcpy (regaddr, &fi->fsr, sizeof (struct frame_saved_regs)); -} - -/* Turn this on if you want to see just how much instruction decoding - if being done, its quite a lot - */ -#if 0 -static void -dump_insn (char *commnt, CORE_ADDR pc, int insn) -{ - printf_filtered (" %s %08x %08x ", - commnt, (unsigned int) pc, (unsigned int) insn); - TARGET_PRINT_INSN (pc, &tm_print_insn_info); - printf_filtered ("\n"); -} -#define insn_debug(args) { printf_filtered args; } -#else -#define dump_insn(a,b,c) {} -#define insn_debug(args) {} -#endif - -#define DEFAULT_SEARCH_LIMIT 44 - -/* Function: scan_prologue - This function decodes the target function prologue to determine - 1) the size of the stack frame, and 2) which registers are saved on it. - It saves the offsets of saved regs in the frame_saved_regs argument, - and returns the frame size. */ - -/* - The sequence it currently generates is: - - if (varargs function) { ddi sp,#n } - push registers - if (additional stack <= 256) { addi sp,#-stack } - else if (additional stack < 65k) { add3 sp,sp,#-stack - - } else if (additional stack) { - seth sp,#(stack & 0xffff0000) - or3 sp,sp,#(stack & 0x0000ffff) - sub sp,r4 - } - if (frame pointer) { - mv sp,fp - } - - These instructions are scheduled like everything else, so you should stop at - the first branch instruction. - - */ - -/* This is required by skip prologue and by m32r_init_extra_frame_info. - The results of decoding a prologue should be cached because this - thrashing is getting nuts. - I am thinking of making a container class with two indexes, name and - address. It may be better to extend the symbol table. - */ - -static void -decode_prologue (CORE_ADDR start_pc, CORE_ADDR scan_limit, CORE_ADDR *pl_endptr, /* var parameter */ - unsigned long *framelength, struct frame_info *fi, - struct frame_saved_regs *fsr) -{ - unsigned long framesize; - int insn; - int op1; - int maybe_one_more = 0; - CORE_ADDR after_prologue = 0; - CORE_ADDR after_stack_adjust = 0; - CORE_ADDR current_pc; - - - framesize = 0; - after_prologue = 0; - insn_debug (("rd prolog l(%d)\n", scan_limit - current_pc)); - - for (current_pc = start_pc; current_pc < scan_limit; current_pc += 2) - { - - insn = read_memory_unsigned_integer (current_pc, 2); - dump_insn ("insn-1", current_pc, insn); /* MTZ */ - - /* If this is a 32 bit instruction, we dont want to examine its - immediate data as though it were an instruction */ - if (current_pc & 0x02) - { /* Clear the parallel execution bit from 16 bit instruction */ - if (maybe_one_more) - { /* The last instruction was a branch, usually terminates - the series, but if this is a parallel instruction, - it may be a stack framing instruction */ - if (!(insn & 0x8000)) - { - insn_debug (("Really done")); - break; /* nope, we are really done */ - } - } - insn &= 0x7fff; /* decode this instruction further */ - } - else - { - if (maybe_one_more) - break; /* This isnt the one more */ - if (insn & 0x8000) - { - insn_debug (("32 bit insn\n")); - if (current_pc == scan_limit) - scan_limit += 2; /* extend the search */ - current_pc += 2; /* skip the immediate data */ - if (insn == 0x8faf) /* add3 sp, sp, xxxx */ - /* add 16 bit sign-extended offset */ - { - insn_debug (("stack increment\n")); - framesize += -((short) read_memory_unsigned_integer (current_pc, 2)); - } - else - { - if (((insn >> 8) == 0xe4) && /* ld24 r4, xxxxxx; sub sp, r4 */ - read_memory_unsigned_integer (current_pc + 2, 2) == 0x0f24) - { /* subtract 24 bit sign-extended negative-offset */ - dump_insn ("insn-2", current_pc + 2, insn); - insn = read_memory_unsigned_integer (current_pc - 2, 4); - dump_insn ("insn-3(l4)", current_pc - 2, insn); - if (insn & 0x00800000) /* sign extend */ - insn |= 0xff000000; /* negative */ - else - insn &= 0x00ffffff; /* positive */ - framesize += insn; - } - } - after_prologue = current_pc; - continue; - } - } - op1 = insn & 0xf000; /* isolate just the first nibble */ - - if ((insn & 0xf0ff) == 0x207f) - { /* st reg, @-sp */ - int regno; - insn_debug (("push\n")); -#if 0 /* No, PUSH FP is not an indication that we will use a frame pointer. */ - if (((insn & 0xffff) == 0x2d7f) && fi) - fi->using_frame_pointer = 1; -#endif - framesize += 4; -#if 0 -/* Why should we increase the scan limit, just because we did a push? - And if there is a reason, surely we would only want to do it if we - had already reached the scan limit... */ - if (current_pc == scan_limit) - scan_limit += 2; -#endif - regno = ((insn >> 8) & 0xf); - if (fsr) /* save_regs offset */ - fsr->regs[regno] = framesize; - after_prologue = 0; - continue; - } - if ((insn >> 8) == 0x4f) /* addi sp, xx */ - /* add 8 bit sign-extended offset */ - { - int stack_adjust = (char) (insn & 0xff); - - /* there are probably two of these stack adjustments: - 1) A negative one in the prologue, and - 2) A positive one in the epilogue. - We are only interested in the first one. */ - - if (stack_adjust < 0) - { - framesize -= stack_adjust; - after_prologue = 0; - /* A frameless function may have no "mv fp, sp". - In that case, this is the end of the prologue. */ - after_stack_adjust = current_pc + 2; - } - continue; - } - if (insn == 0x1d8f) - { /* mv fp, sp */ - if (fi) - fi->using_frame_pointer = 1; /* fp is now valid */ - insn_debug (("done fp found\n")); - after_prologue = current_pc + 2; - break; /* end of stack adjustments */ - } - if (insn == 0x7000) /* Nop looks like a branch, continue explicitly */ - { - insn_debug (("nop\n")); - after_prologue = current_pc + 2; - continue; /* nop occurs between pushes */ - } - /* End of prolog if any of these are branch instructions */ - if ((op1 == 0x7000) - || (op1 == 0xb000) - || (op1 == 0xf000)) - { - after_prologue = current_pc; - insn_debug (("Done: branch\n")); - maybe_one_more = 1; - continue; - } - /* Some of the branch instructions are mixed with other types */ - if (op1 == 0x1000) - { - int subop = insn & 0x0ff0; - if ((subop == 0x0ec0) || (subop == 0x0fc0)) - { - insn_debug (("done: jmp\n")); - after_prologue = current_pc; - maybe_one_more = 1; - continue; /* jmp , jl */ - } - } - } - - if (current_pc >= scan_limit) - { - if (pl_endptr) - { -#if 1 - if (after_stack_adjust != 0) - /* We did not find a "mv fp,sp", but we DID find - a stack_adjust. Is it safe to use that as the - end of the prologue? I just don't know. */ - { - *pl_endptr = after_stack_adjust; - if (framelength) - *framelength = framesize; - } - else -#endif - /* We reached the end of the loop without finding the end - of the prologue. No way to win -- we should report failure. - The way we do that is to return the original start_pc. - GDB will set a breakpoint at the start of the function (etc.) */ - *pl_endptr = start_pc; - } - return; - } - if (after_prologue == 0) - after_prologue = current_pc; - - insn_debug ((" framesize %d, firstline %08x\n", framesize, after_prologue)); - if (framelength) - *framelength = framesize; - if (pl_endptr) - *pl_endptr = after_prologue; -} /* decode_prologue */ - -/* Function: skip_prologue - Find end of function prologue */ - -CORE_ADDR -m32r_skip_prologue (CORE_ADDR pc) -{ - CORE_ADDR func_addr, func_end; - struct symtab_and_line sal; - - /* See what the symbol table says */ - - if (find_pc_partial_function (pc, NULL, &func_addr, &func_end)) - { - sal = find_pc_line (func_addr, 0); - - if (sal.line != 0 && sal.end <= func_end) - { - - insn_debug (("BP after prologue %08x\n", sal.end)); - func_end = sal.end; - } - else - /* Either there's no line info, or the line after the prologue is after - the end of the function. In this case, there probably isn't a - prologue. */ - { - insn_debug (("No line info, line(%x) sal_end(%x) funcend(%x)\n", - sal.line, sal.end, func_end)); - func_end = min (func_end, func_addr + DEFAULT_SEARCH_LIMIT); - } - } - else - func_end = pc + DEFAULT_SEARCH_LIMIT; - decode_prologue (pc, func_end, &sal.end, 0, 0, 0); - return sal.end; -} - -static unsigned long -m32r_scan_prologue (struct frame_info *fi, struct frame_saved_regs *fsr) -{ - struct symtab_and_line sal; - CORE_ADDR prologue_start, prologue_end, current_pc; - unsigned long framesize = 0; - - /* this code essentially duplicates skip_prologue, - but we need the start address below. */ - - if (find_pc_partial_function (fi->pc, NULL, &prologue_start, &prologue_end)) - { - sal = find_pc_line (prologue_start, 0); - - if (sal.line == 0) /* no line info, use current PC */ - if (prologue_start == entry_point_address ()) - return 0; - } - else - { - prologue_start = fi->pc; - prologue_end = prologue_start + 48; /* We're in the boondocks: - allow for 16 pushes, an add, - and "mv fp,sp" */ - } -#if 0 - prologue_end = min (prologue_end, fi->pc); -#endif - insn_debug (("fipc(%08x) start(%08x) end(%08x)\n", - fi->pc, prologue_start, prologue_end)); - prologue_end = min (prologue_end, prologue_start + DEFAULT_SEARCH_LIMIT); - decode_prologue (prologue_start, prologue_end, &prologue_end, &framesize, - fi, fsr); - return framesize; -} - -/* Function: init_extra_frame_info - This function actually figures out the frame address for a given pc and - sp. This is tricky on the m32r because we sometimes don't use an explicit - frame pointer, and the previous stack pointer isn't necessarily recorded - on the stack. The only reliable way to get this info is to - examine the prologue. */ - -void -m32r_init_extra_frame_info (struct frame_info *fi) -{ - int reg; - - if (fi->next) - fi->pc = FRAME_SAVED_PC (fi->next); - - memset (fi->fsr.regs, '\000', sizeof fi->fsr.regs); - - if (DEPRECATED_PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) - { - /* We need to setup fi->frame here because run_stack_dummy gets it wrong - by assuming it's always FP. */ - fi->frame = deprecated_read_register_dummy (fi->pc, fi->frame, - SP_REGNUM); - fi->framesize = 0; - return; - } - else - { - fi->using_frame_pointer = 0; - fi->framesize = m32r_scan_prologue (fi, &fi->fsr); - - if (!fi->next) - if (fi->using_frame_pointer) - { - fi->frame = read_register (FP_REGNUM); - } - else - fi->frame = read_register (SP_REGNUM); - else - /* fi->next means this is not the innermost frame */ if (fi->using_frame_pointer) - /* we have an FP */ - if (fi->next->fsr.regs[FP_REGNUM] != 0) /* caller saved our FP */ - fi->frame = read_memory_integer (fi->next->fsr.regs[FP_REGNUM], 4); - for (reg = 0; reg < NUM_REGS; reg++) - if (fi->fsr.regs[reg] != 0) - fi->fsr.regs[reg] = fi->frame + fi->framesize - fi->fsr.regs[reg]; - } -} - -/* Function: m32r_virtual_frame_pointer - Return the register that the function uses for a frame pointer, - plus any necessary offset to be applied to the register before - any frame pointer offsets. */ - -void -m32r_virtual_frame_pointer (CORE_ADDR pc, long *reg, long *offset) -{ - struct frame_info *fi = deprecated_frame_xmalloc (); - struct cleanup *old_chain = make_cleanup (xfree, fi); - - /* Set up a dummy frame_info. */ - fi->next = NULL; - fi->prev = NULL; - fi->frame = 0; - fi->pc = pc; - - /* Analyze the prolog and fill in the extra info. */ - m32r_init_extra_frame_info (fi); - - /* Results will tell us which type of frame it uses. */ - if (fi->using_frame_pointer) - { - *reg = FP_REGNUM; - *offset = 0; - } - else - { - *reg = SP_REGNUM; - *offset = 0; - } - do_cleanups (old_chain); -} - -/* Function: find_callers_reg - Find REGNUM on the stack. Otherwise, it's in an active register. One thing - we might want to do here is to check REGNUM against the clobber mask, and - somehow flag it as invalid if it isn't saved on the stack somewhere. This - would provide a graceful failure mode when trying to get the value of - caller-saves registers for an inner frame. */ - -CORE_ADDR -m32r_find_callers_reg (struct frame_info *fi, int regnum) -{ - for (; fi; fi = fi->next) - if (DEPRECATED_PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) - return deprecated_read_register_dummy (fi->pc, fi->frame, regnum); - else if (fi->fsr.regs[regnum] != 0) - return read_memory_integer (fi->fsr.regs[regnum], - REGISTER_RAW_SIZE (regnum)); - return read_register (regnum); -} - -/* Function: frame_chain Given a GDB frame, determine the address of - the calling function's frame. This will be used to create a new - GDB frame struct, and then INIT_EXTRA_FRAME_INFO and - DEPRECATED_INIT_FRAME_PC will be called for the new frame. For - m32r, we save the frame size when we initialize the frame_info. */ - -CORE_ADDR -m32r_frame_chain (struct frame_info *fi) -{ - CORE_ADDR fn_start, callers_pc, fp; - - /* is this a dummy frame? */ - if (DEPRECATED_PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) - return fi->frame; /* dummy frame same as caller's frame */ - - /* is caller-of-this a dummy frame? */ - callers_pc = FRAME_SAVED_PC (fi); /* find out who called us: */ - fp = m32r_find_callers_reg (fi, FP_REGNUM); - if (DEPRECATED_PC_IN_CALL_DUMMY (callers_pc, fp, fp)) - return fp; /* dummy frame's frame may bear no relation to ours */ - - if (find_pc_partial_function (fi->pc, 0, &fn_start, 0)) - if (fn_start == entry_point_address ()) - return 0; /* in _start fn, don't chain further */ - if (fi->framesize == 0) - { - printf_filtered ("cannot determine frame size @ %s , pc(%s)\n", - paddr (fi->frame), - paddr (fi->pc)); - return 0; - } - insn_debug (("m32rx frame %08x\n", fi->frame + fi->framesize)); - return fi->frame + fi->framesize; -} - -/* Function: push_return_address (pc) - Set up the return address for the inferior function call. - Necessary for targets that don't actually execute a JSR/BSR instruction - (ie. when using an empty CALL_DUMMY) */ - -CORE_ADDR -m32r_push_return_address (CORE_ADDR pc, CORE_ADDR sp) -{ - write_register (RP_REGNUM, CALL_DUMMY_ADDRESS ()); - return sp; -} - - -/* Function: pop_frame - Discard from the stack the innermost frame, - restoring all saved registers. */ - -struct frame_info * -m32r_pop_frame (struct frame_info *frame) -{ - int regnum; - - if (DEPRECATED_PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame)) - generic_pop_dummy_frame (); - else - { - for (regnum = 0; regnum < NUM_REGS; regnum++) - if (frame->fsr.regs[regnum] != 0) - write_register (regnum, - read_memory_integer (frame->fsr.regs[regnum], 4)); - - write_register (PC_REGNUM, FRAME_SAVED_PC (frame)); - write_register (SP_REGNUM, read_register (FP_REGNUM)); - if (read_register (PSW_REGNUM) & 0x80) - write_register (SPU_REGNUM, read_register (SP_REGNUM)); - else - write_register (SPI_REGNUM, read_register (SP_REGNUM)); - } - flush_cached_frames (); - return NULL; -} - -/* Function: frame_saved_pc - Find the caller of this frame. We do this by seeing if RP_REGNUM is saved - in the stack anywhere, otherwise we get it from the registers. */ - -CORE_ADDR -m32r_frame_saved_pc (struct frame_info *fi) -{ - if (DEPRECATED_PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) - return deprecated_read_register_dummy (fi->pc, fi->frame, PC_REGNUM); - else - return m32r_find_callers_reg (fi, RP_REGNUM); -} - -/* Function: push_arguments - Setup the function arguments for calling a function in the inferior. - - On the Mitsubishi M32R architecture, there are four registers (R0 to R3) - which are dedicated for passing function arguments. Up to the first - four arguments (depending on size) may go into these registers. - The rest go on the stack. - - Arguments that are smaller than 4 bytes will still take up a whole - register or a whole 32-bit word on the stack, and will be - right-justified in the register or the stack word. This includes - chars, shorts, and small aggregate types. - - Arguments of 8 bytes size are split between two registers, if - available. If only one register is available, the argument will - be split between the register and the stack. Otherwise it is - passed entirely on the stack. Aggregate types with sizes between - 4 and 8 bytes are passed entirely on the stack, and are left-justified - within the double-word (as opposed to aggregates smaller than 4 bytes - which are right-justified). - - Aggregates of greater than 8 bytes are first copied onto the stack, - and then a pointer to the copy is passed in the place of the normal - argument (either in a register if available, or on the stack). - - Functions that must return an aggregate type can return it in the - normal return value registers (R0 and R1) if its size is 8 bytes or - less. For larger return values, the caller must allocate space for - the callee to copy the return value to. A pointer to this space is - passed as an implicit first argument, always in R0. */ - -CORE_ADDR -m32r_push_arguments (int nargs, struct value **args, CORE_ADDR sp, - unsigned char struct_return, CORE_ADDR struct_addr) -{ - int stack_offset, stack_alloc; - int argreg; - int argnum; - struct type *type; - CORE_ADDR regval; - char *val; - char valbuf[4]; - int len; - int odd_sized_struct; - - /* first force sp to a 4-byte alignment */ - sp = sp & ~3; - - argreg = ARG0_REGNUM; - /* The "struct return pointer" pseudo-argument goes in R0 */ - if (struct_return) - write_register (argreg++, struct_addr); - - /* Now make sure there's space on the stack */ - for (argnum = 0, stack_alloc = 0; - argnum < nargs; argnum++) - stack_alloc += ((TYPE_LENGTH (VALUE_TYPE (args[argnum])) + 3) & ~3); - sp -= stack_alloc; /* make room on stack for args */ - - - /* Now load as many as possible of the first arguments into - registers, and push the rest onto the stack. There are 16 bytes - in four registers available. Loop thru args from first to last. */ - - argreg = ARG0_REGNUM; - for (argnum = 0, stack_offset = 0; argnum < nargs; argnum++) - { - type = VALUE_TYPE (args[argnum]); - len = TYPE_LENGTH (type); - memset (valbuf, 0, sizeof (valbuf)); - if (len < 4) - { /* value gets right-justified in the register or stack word */ - memcpy (valbuf + (4 - len), - (char *) VALUE_CONTENTS (args[argnum]), len); - val = valbuf; - } - else - val = (char *) VALUE_CONTENTS (args[argnum]); - - if (len > 4 && (len & 3) != 0) - odd_sized_struct = 1; /* such structs go entirely on stack */ - else - odd_sized_struct = 0; - while (len > 0) - { - if (argreg > ARGLAST_REGNUM || odd_sized_struct) - { /* must go on the stack */ - write_memory (sp + stack_offset, val, 4); - stack_offset += 4; - } - /* NOTE WELL!!!!! This is not an "else if" clause!!! - That's because some *&^%$ things get passed on the stack - AND in the registers! */ - if (argreg <= ARGLAST_REGNUM) - { /* there's room in a register */ - regval = extract_address (val, REGISTER_RAW_SIZE (argreg)); - write_register (argreg++, regval); - } - /* Store the value 4 bytes at a time. This means that things - larger than 4 bytes may go partly in registers and partly - on the stack. */ - len -= REGISTER_RAW_SIZE (argreg); - val += REGISTER_RAW_SIZE (argreg); - } - } - return sp; -} - -/* Function: fix_call_dummy - If there is real CALL_DUMMY code (eg. on the stack), this function - has the responsability to insert the address of the actual code that - is the target of the target function call. */ - -void -m32r_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs, - struct value **args, struct type *type, int gcc_p) -{ - /* ld24 r8, <(imm24) fun> */ - *(unsigned long *) (dummy) = (fun & 0x00ffffff) | 0xe8000000; -} - - -/* Function: m32r_write_sp - Because SP is really a read-only register that mirrors either SPU or SPI, - we must actually write one of those two as well, depending on PSW. */ - -void -m32r_write_sp (CORE_ADDR val) -{ - unsigned long psw = read_register (PSW_REGNUM); - - if (psw & 0x80) /* stack mode: user or interrupt */ - write_register (SPU_REGNUM, val); - else - write_register (SPI_REGNUM, val); - write_register (SP_REGNUM, val); -} - -void -_initialize_m32r_tdep (void) -{ - tm_print_insn = print_insn_m32r; -} +// OBSOLETE /* Target-dependent code for the Mitsubishi m32r for GDB, the GNU debugger. +// OBSOLETE +// OBSOLETE Copyright 1996, 1998, 1999, 2000, 2001, 2003 Free Software +// OBSOLETE 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 "defs.h" +// OBSOLETE #include "frame.h" +// OBSOLETE #include "inferior.h" +// OBSOLETE #include "target.h" +// OBSOLETE #include "value.h" +// OBSOLETE #include "bfd.h" +// OBSOLETE #include "gdb_string.h" +// OBSOLETE #include "gdbcore.h" +// OBSOLETE #include "symfile.h" +// OBSOLETE #include "regcache.h" +// OBSOLETE +// OBSOLETE /* Function: m32r_use_struct_convention +// OBSOLETE Return nonzero if call_function should allocate stack space for a +// OBSOLETE struct return? */ +// OBSOLETE int +// OBSOLETE m32r_use_struct_convention (int gcc_p, struct type *type) +// OBSOLETE { +// OBSOLETE return (TYPE_LENGTH (type) > 8); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Function: frame_find_saved_regs +// OBSOLETE Return the frame_saved_regs structure for the frame. +// OBSOLETE Doesn't really work for dummy frames, but it does pass back +// OBSOLETE an empty frame_saved_regs, so I guess that's better than total failure */ +// OBSOLETE +// OBSOLETE void +// OBSOLETE m32r_frame_find_saved_regs (struct frame_info *fi, +// OBSOLETE struct frame_saved_regs *regaddr) +// OBSOLETE { +// OBSOLETE memcpy (regaddr, &fi->fsr, sizeof (struct frame_saved_regs)); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Turn this on if you want to see just how much instruction decoding +// OBSOLETE if being done, its quite a lot +// OBSOLETE */ +// OBSOLETE #if 0 +// OBSOLETE static void +// OBSOLETE dump_insn (char *commnt, CORE_ADDR pc, int insn) +// OBSOLETE { +// OBSOLETE printf_filtered (" %s %08x %08x ", +// OBSOLETE commnt, (unsigned int) pc, (unsigned int) insn); +// OBSOLETE TARGET_PRINT_INSN (pc, &tm_print_insn_info); +// OBSOLETE printf_filtered ("\n"); +// OBSOLETE } +// OBSOLETE #define insn_debug(args) { printf_filtered args; } +// OBSOLETE #else +// OBSOLETE #define dump_insn(a,b,c) {} +// OBSOLETE #define insn_debug(args) {} +// OBSOLETE #endif +// OBSOLETE +// OBSOLETE #define DEFAULT_SEARCH_LIMIT 44 +// OBSOLETE +// OBSOLETE /* Function: scan_prologue +// OBSOLETE This function decodes the target function prologue to determine +// OBSOLETE 1) the size of the stack frame, and 2) which registers are saved on it. +// OBSOLETE It saves the offsets of saved regs in the frame_saved_regs argument, +// OBSOLETE and returns the frame size. */ +// OBSOLETE +// OBSOLETE /* +// OBSOLETE The sequence it currently generates is: +// OBSOLETE +// OBSOLETE if (varargs function) { ddi sp,#n } +// OBSOLETE push registers +// OBSOLETE if (additional stack <= 256) { addi sp,#-stack } +// OBSOLETE else if (additional stack < 65k) { add3 sp,sp,#-stack +// OBSOLETE +// OBSOLETE } else if (additional stack) { +// OBSOLETE seth sp,#(stack & 0xffff0000) +// OBSOLETE or3 sp,sp,#(stack & 0x0000ffff) +// OBSOLETE sub sp,r4 +// OBSOLETE } +// OBSOLETE if (frame pointer) { +// OBSOLETE mv sp,fp +// OBSOLETE } +// OBSOLETE +// OBSOLETE These instructions are scheduled like everything else, so you should stop at +// OBSOLETE the first branch instruction. +// OBSOLETE +// OBSOLETE */ +// OBSOLETE +// OBSOLETE /* This is required by skip prologue and by m32r_init_extra_frame_info. +// OBSOLETE The results of decoding a prologue should be cached because this +// OBSOLETE thrashing is getting nuts. +// OBSOLETE I am thinking of making a container class with two indexes, name and +// OBSOLETE address. It may be better to extend the symbol table. +// OBSOLETE */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE decode_prologue (CORE_ADDR start_pc, CORE_ADDR scan_limit, CORE_ADDR *pl_endptr, /* var parameter */ +// OBSOLETE unsigned long *framelength, struct frame_info *fi, +// OBSOLETE struct frame_saved_regs *fsr) +// OBSOLETE { +// OBSOLETE unsigned long framesize; +// OBSOLETE int insn; +// OBSOLETE int op1; +// OBSOLETE int maybe_one_more = 0; +// OBSOLETE CORE_ADDR after_prologue = 0; +// OBSOLETE CORE_ADDR after_stack_adjust = 0; +// OBSOLETE CORE_ADDR current_pc; +// OBSOLETE +// OBSOLETE +// OBSOLETE framesize = 0; +// OBSOLETE after_prologue = 0; +// OBSOLETE insn_debug (("rd prolog l(%d)\n", scan_limit - current_pc)); +// OBSOLETE +// OBSOLETE for (current_pc = start_pc; current_pc < scan_limit; current_pc += 2) +// OBSOLETE { +// OBSOLETE +// OBSOLETE insn = read_memory_unsigned_integer (current_pc, 2); +// OBSOLETE dump_insn ("insn-1", current_pc, insn); /* MTZ */ +// OBSOLETE +// OBSOLETE /* If this is a 32 bit instruction, we dont want to examine its +// OBSOLETE immediate data as though it were an instruction */ +// OBSOLETE if (current_pc & 0x02) +// OBSOLETE { /* Clear the parallel execution bit from 16 bit instruction */ +// OBSOLETE if (maybe_one_more) +// OBSOLETE { /* The last instruction was a branch, usually terminates +// OBSOLETE the series, but if this is a parallel instruction, +// OBSOLETE it may be a stack framing instruction */ +// OBSOLETE if (!(insn & 0x8000)) +// OBSOLETE { +// OBSOLETE insn_debug (("Really done")); +// OBSOLETE break; /* nope, we are really done */ +// OBSOLETE } +// OBSOLETE } +// OBSOLETE insn &= 0x7fff; /* decode this instruction further */ +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE if (maybe_one_more) +// OBSOLETE break; /* This isnt the one more */ +// OBSOLETE if (insn & 0x8000) +// OBSOLETE { +// OBSOLETE insn_debug (("32 bit insn\n")); +// OBSOLETE if (current_pc == scan_limit) +// OBSOLETE scan_limit += 2; /* extend the search */ +// OBSOLETE current_pc += 2; /* skip the immediate data */ +// OBSOLETE if (insn == 0x8faf) /* add3 sp, sp, xxxx */ +// OBSOLETE /* add 16 bit sign-extended offset */ +// OBSOLETE { +// OBSOLETE insn_debug (("stack increment\n")); +// OBSOLETE framesize += -((short) read_memory_unsigned_integer (current_pc, 2)); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE if (((insn >> 8) == 0xe4) && /* ld24 r4, xxxxxx; sub sp, r4 */ +// OBSOLETE read_memory_unsigned_integer (current_pc + 2, 2) == 0x0f24) +// OBSOLETE { /* subtract 24 bit sign-extended negative-offset */ +// OBSOLETE dump_insn ("insn-2", current_pc + 2, insn); +// OBSOLETE insn = read_memory_unsigned_integer (current_pc - 2, 4); +// OBSOLETE dump_insn ("insn-3(l4)", current_pc - 2, insn); +// OBSOLETE if (insn & 0x00800000) /* sign extend */ +// OBSOLETE insn |= 0xff000000; /* negative */ +// OBSOLETE else +// OBSOLETE insn &= 0x00ffffff; /* positive */ +// OBSOLETE framesize += insn; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE after_prologue = current_pc; +// OBSOLETE continue; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE op1 = insn & 0xf000; /* isolate just the first nibble */ +// OBSOLETE +// OBSOLETE if ((insn & 0xf0ff) == 0x207f) +// OBSOLETE { /* st reg, @-sp */ +// OBSOLETE int regno; +// OBSOLETE insn_debug (("push\n")); +// OBSOLETE #if 0 /* No, PUSH FP is not an indication that we will use a frame pointer. */ +// OBSOLETE if (((insn & 0xffff) == 0x2d7f) && fi) +// OBSOLETE fi->using_frame_pointer = 1; +// OBSOLETE #endif +// OBSOLETE framesize += 4; +// OBSOLETE #if 0 +// OBSOLETE /* Why should we increase the scan limit, just because we did a push? +// OBSOLETE And if there is a reason, surely we would only want to do it if we +// OBSOLETE had already reached the scan limit... */ +// OBSOLETE if (current_pc == scan_limit) +// OBSOLETE scan_limit += 2; +// OBSOLETE #endif +// OBSOLETE regno = ((insn >> 8) & 0xf); +// OBSOLETE if (fsr) /* save_regs offset */ +// OBSOLETE fsr->regs[regno] = framesize; +// OBSOLETE after_prologue = 0; +// OBSOLETE continue; +// OBSOLETE } +// OBSOLETE if ((insn >> 8) == 0x4f) /* addi sp, xx */ +// OBSOLETE /* add 8 bit sign-extended offset */ +// OBSOLETE { +// OBSOLETE int stack_adjust = (char) (insn & 0xff); +// OBSOLETE +// OBSOLETE /* there are probably two of these stack adjustments: +// OBSOLETE 1) A negative one in the prologue, and +// OBSOLETE 2) A positive one in the epilogue. +// OBSOLETE We are only interested in the first one. */ +// OBSOLETE +// OBSOLETE if (stack_adjust < 0) +// OBSOLETE { +// OBSOLETE framesize -= stack_adjust; +// OBSOLETE after_prologue = 0; +// OBSOLETE /* A frameless function may have no "mv fp, sp". +// OBSOLETE In that case, this is the end of the prologue. */ +// OBSOLETE after_stack_adjust = current_pc + 2; +// OBSOLETE } +// OBSOLETE continue; +// OBSOLETE } +// OBSOLETE if (insn == 0x1d8f) +// OBSOLETE { /* mv fp, sp */ +// OBSOLETE if (fi) +// OBSOLETE fi->using_frame_pointer = 1; /* fp is now valid */ +// OBSOLETE insn_debug (("done fp found\n")); +// OBSOLETE after_prologue = current_pc + 2; +// OBSOLETE break; /* end of stack adjustments */ +// OBSOLETE } +// OBSOLETE if (insn == 0x7000) /* Nop looks like a branch, continue explicitly */ +// OBSOLETE { +// OBSOLETE insn_debug (("nop\n")); +// OBSOLETE after_prologue = current_pc + 2; +// OBSOLETE continue; /* nop occurs between pushes */ +// OBSOLETE } +// OBSOLETE /* End of prolog if any of these are branch instructions */ +// OBSOLETE if ((op1 == 0x7000) +// OBSOLETE || (op1 == 0xb000) +// OBSOLETE || (op1 == 0xf000)) +// OBSOLETE { +// OBSOLETE after_prologue = current_pc; +// OBSOLETE insn_debug (("Done: branch\n")); +// OBSOLETE maybe_one_more = 1; +// OBSOLETE continue; +// OBSOLETE } +// OBSOLETE /* Some of the branch instructions are mixed with other types */ +// OBSOLETE if (op1 == 0x1000) +// OBSOLETE { +// OBSOLETE int subop = insn & 0x0ff0; +// OBSOLETE if ((subop == 0x0ec0) || (subop == 0x0fc0)) +// OBSOLETE { +// OBSOLETE insn_debug (("done: jmp\n")); +// OBSOLETE after_prologue = current_pc; +// OBSOLETE maybe_one_more = 1; +// OBSOLETE continue; /* jmp , jl */ +// OBSOLETE } +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE if (current_pc >= scan_limit) +// OBSOLETE { +// OBSOLETE if (pl_endptr) +// OBSOLETE { +// OBSOLETE #if 1 +// OBSOLETE if (after_stack_adjust != 0) +// OBSOLETE /* We did not find a "mv fp,sp", but we DID find +// OBSOLETE a stack_adjust. Is it safe to use that as the +// OBSOLETE end of the prologue? I just don't know. */ +// OBSOLETE { +// OBSOLETE *pl_endptr = after_stack_adjust; +// OBSOLETE if (framelength) +// OBSOLETE *framelength = framesize; +// OBSOLETE } +// OBSOLETE else +// OBSOLETE #endif +// OBSOLETE /* We reached the end of the loop without finding the end +// OBSOLETE of the prologue. No way to win -- we should report failure. +// OBSOLETE The way we do that is to return the original start_pc. +// OBSOLETE GDB will set a breakpoint at the start of the function (etc.) */ +// OBSOLETE *pl_endptr = start_pc; +// OBSOLETE } +// OBSOLETE return; +// OBSOLETE } +// OBSOLETE if (after_prologue == 0) +// OBSOLETE after_prologue = current_pc; +// OBSOLETE +// OBSOLETE insn_debug ((" framesize %d, firstline %08x\n", framesize, after_prologue)); +// OBSOLETE if (framelength) +// OBSOLETE *framelength = framesize; +// OBSOLETE if (pl_endptr) +// OBSOLETE *pl_endptr = after_prologue; +// OBSOLETE } /* decode_prologue */ +// OBSOLETE +// OBSOLETE /* Function: skip_prologue +// OBSOLETE Find end of function prologue */ +// OBSOLETE +// OBSOLETE CORE_ADDR +// OBSOLETE m32r_skip_prologue (CORE_ADDR pc) +// OBSOLETE { +// OBSOLETE CORE_ADDR func_addr, func_end; +// OBSOLETE struct symtab_and_line sal; +// OBSOLETE +// OBSOLETE /* See what the symbol table says */ +// OBSOLETE +// OBSOLETE if (find_pc_partial_function (pc, NULL, &func_addr, &func_end)) +// OBSOLETE { +// OBSOLETE sal = find_pc_line (func_addr, 0); +// OBSOLETE +// OBSOLETE if (sal.line != 0 && sal.end <= func_end) +// OBSOLETE { +// OBSOLETE +// OBSOLETE insn_debug (("BP after prologue %08x\n", sal.end)); +// OBSOLETE func_end = sal.end; +// OBSOLETE } +// OBSOLETE else +// OBSOLETE /* Either there's no line info, or the line after the prologue is after +// OBSOLETE the end of the function. In this case, there probably isn't a +// OBSOLETE prologue. */ +// OBSOLETE { +// OBSOLETE insn_debug (("No line info, line(%x) sal_end(%x) funcend(%x)\n", +// OBSOLETE sal.line, sal.end, func_end)); +// OBSOLETE func_end = min (func_end, func_addr + DEFAULT_SEARCH_LIMIT); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE else +// OBSOLETE func_end = pc + DEFAULT_SEARCH_LIMIT; +// OBSOLETE decode_prologue (pc, func_end, &sal.end, 0, 0, 0); +// OBSOLETE return sal.end; +// OBSOLETE } +// OBSOLETE +// OBSOLETE static unsigned long +// OBSOLETE m32r_scan_prologue (struct frame_info *fi, struct frame_saved_regs *fsr) +// OBSOLETE { +// OBSOLETE struct symtab_and_line sal; +// OBSOLETE CORE_ADDR prologue_start, prologue_end, current_pc; +// OBSOLETE unsigned long framesize = 0; +// OBSOLETE +// OBSOLETE /* this code essentially duplicates skip_prologue, +// OBSOLETE but we need the start address below. */ +// OBSOLETE +// OBSOLETE if (find_pc_partial_function (fi->pc, NULL, &prologue_start, &prologue_end)) +// OBSOLETE { +// OBSOLETE sal = find_pc_line (prologue_start, 0); +// OBSOLETE +// OBSOLETE if (sal.line == 0) /* no line info, use current PC */ +// OBSOLETE if (prologue_start == entry_point_address ()) +// OBSOLETE return 0; +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE prologue_start = fi->pc; +// OBSOLETE prologue_end = prologue_start + 48; /* We're in the boondocks: +// OBSOLETE allow for 16 pushes, an add, +// OBSOLETE and "mv fp,sp" */ +// OBSOLETE } +// OBSOLETE #if 0 +// OBSOLETE prologue_end = min (prologue_end, fi->pc); +// OBSOLETE #endif +// OBSOLETE insn_debug (("fipc(%08x) start(%08x) end(%08x)\n", +// OBSOLETE fi->pc, prologue_start, prologue_end)); +// OBSOLETE prologue_end = min (prologue_end, prologue_start + DEFAULT_SEARCH_LIMIT); +// OBSOLETE decode_prologue (prologue_start, prologue_end, &prologue_end, &framesize, +// OBSOLETE fi, fsr); +// OBSOLETE return framesize; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Function: init_extra_frame_info +// OBSOLETE This function actually figures out the frame address for a given pc and +// OBSOLETE sp. This is tricky on the m32r because we sometimes don't use an explicit +// OBSOLETE frame pointer, and the previous stack pointer isn't necessarily recorded +// OBSOLETE on the stack. The only reliable way to get this info is to +// OBSOLETE examine the prologue. */ +// OBSOLETE +// OBSOLETE void +// OBSOLETE m32r_init_extra_frame_info (struct frame_info *fi) +// OBSOLETE { +// OBSOLETE int reg; +// OBSOLETE +// OBSOLETE if (fi->next) +// OBSOLETE fi->pc = FRAME_SAVED_PC (fi->next); +// OBSOLETE +// OBSOLETE memset (fi->fsr.regs, '\000', sizeof fi->fsr.regs); +// OBSOLETE +// OBSOLETE if (DEPRECATED_PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) +// OBSOLETE { +// OBSOLETE /* We need to setup fi->frame here because run_stack_dummy gets it wrong +// OBSOLETE by assuming it's always FP. */ +// OBSOLETE fi->frame = deprecated_read_register_dummy (fi->pc, fi->frame, +// OBSOLETE SP_REGNUM); +// OBSOLETE fi->framesize = 0; +// OBSOLETE return; +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE fi->using_frame_pointer = 0; +// OBSOLETE fi->framesize = m32r_scan_prologue (fi, &fi->fsr); +// OBSOLETE +// OBSOLETE if (!fi->next) +// OBSOLETE if (fi->using_frame_pointer) +// OBSOLETE { +// OBSOLETE fi->frame = read_register (FP_REGNUM); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE fi->frame = read_register (SP_REGNUM); +// OBSOLETE else +// OBSOLETE /* fi->next means this is not the innermost frame */ if (fi->using_frame_pointer) +// OBSOLETE /* we have an FP */ +// OBSOLETE if (fi->next->fsr.regs[FP_REGNUM] != 0) /* caller saved our FP */ +// OBSOLETE fi->frame = read_memory_integer (fi->next->fsr.regs[FP_REGNUM], 4); +// OBSOLETE for (reg = 0; reg < NUM_REGS; reg++) +// OBSOLETE if (fi->fsr.regs[reg] != 0) +// OBSOLETE fi->fsr.regs[reg] = fi->frame + fi->framesize - fi->fsr.regs[reg]; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Function: m32r_virtual_frame_pointer +// OBSOLETE Return the register that the function uses for a frame pointer, +// OBSOLETE plus any necessary offset to be applied to the register before +// OBSOLETE any frame pointer offsets. */ +// OBSOLETE +// OBSOLETE void +// OBSOLETE m32r_virtual_frame_pointer (CORE_ADDR pc, long *reg, long *offset) +// OBSOLETE { +// OBSOLETE struct frame_info *fi = deprecated_frame_xmalloc (); +// OBSOLETE struct cleanup *old_chain = make_cleanup (xfree, fi); +// OBSOLETE +// OBSOLETE /* Set up a dummy frame_info. */ +// OBSOLETE fi->next = NULL; +// OBSOLETE fi->prev = NULL; +// OBSOLETE fi->frame = 0; +// OBSOLETE fi->pc = pc; +// OBSOLETE +// OBSOLETE /* Analyze the prolog and fill in the extra info. */ +// OBSOLETE m32r_init_extra_frame_info (fi); +// OBSOLETE +// OBSOLETE /* Results will tell us which type of frame it uses. */ +// OBSOLETE if (fi->using_frame_pointer) +// OBSOLETE { +// OBSOLETE *reg = FP_REGNUM; +// OBSOLETE *offset = 0; +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE *reg = SP_REGNUM; +// OBSOLETE *offset = 0; +// OBSOLETE } +// OBSOLETE do_cleanups (old_chain); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Function: find_callers_reg +// OBSOLETE Find REGNUM on the stack. Otherwise, it's in an active register. One thing +// OBSOLETE we might want to do here is to check REGNUM against the clobber mask, and +// OBSOLETE somehow flag it as invalid if it isn't saved on the stack somewhere. This +// OBSOLETE would provide a graceful failure mode when trying to get the value of +// OBSOLETE caller-saves registers for an inner frame. */ +// OBSOLETE +// OBSOLETE CORE_ADDR +// OBSOLETE m32r_find_callers_reg (struct frame_info *fi, int regnum) +// OBSOLETE { +// OBSOLETE for (; fi; fi = fi->next) +// OBSOLETE if (DEPRECATED_PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) +// OBSOLETE return deprecated_read_register_dummy (fi->pc, fi->frame, regnum); +// OBSOLETE else if (fi->fsr.regs[regnum] != 0) +// OBSOLETE return read_memory_integer (fi->fsr.regs[regnum], +// OBSOLETE REGISTER_RAW_SIZE (regnum)); +// OBSOLETE return read_register (regnum); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Function: frame_chain Given a GDB frame, determine the address of +// OBSOLETE the calling function's frame. This will be used to create a new +// OBSOLETE GDB frame struct, and then INIT_EXTRA_FRAME_INFO and +// OBSOLETE DEPRECATED_INIT_FRAME_PC will be called for the new frame. For +// OBSOLETE m32r, we save the frame size when we initialize the frame_info. */ +// OBSOLETE +// OBSOLETE CORE_ADDR +// OBSOLETE m32r_frame_chain (struct frame_info *fi) +// OBSOLETE { +// OBSOLETE CORE_ADDR fn_start, callers_pc, fp; +// OBSOLETE +// OBSOLETE /* is this a dummy frame? */ +// OBSOLETE if (DEPRECATED_PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) +// OBSOLETE return fi->frame; /* dummy frame same as caller's frame */ +// OBSOLETE +// OBSOLETE /* is caller-of-this a dummy frame? */ +// OBSOLETE callers_pc = FRAME_SAVED_PC (fi); /* find out who called us: */ +// OBSOLETE fp = m32r_find_callers_reg (fi, FP_REGNUM); +// OBSOLETE if (DEPRECATED_PC_IN_CALL_DUMMY (callers_pc, fp, fp)) +// OBSOLETE return fp; /* dummy frame's frame may bear no relation to ours */ +// OBSOLETE +// OBSOLETE if (find_pc_partial_function (fi->pc, 0, &fn_start, 0)) +// OBSOLETE if (fn_start == entry_point_address ()) +// OBSOLETE return 0; /* in _start fn, don't chain further */ +// OBSOLETE if (fi->framesize == 0) +// OBSOLETE { +// OBSOLETE printf_filtered ("cannot determine frame size @ %s , pc(%s)\n", +// OBSOLETE paddr (fi->frame), +// OBSOLETE paddr (fi->pc)); +// OBSOLETE return 0; +// OBSOLETE } +// OBSOLETE insn_debug (("m32rx frame %08x\n", fi->frame + fi->framesize)); +// OBSOLETE return fi->frame + fi->framesize; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Function: push_return_address (pc) +// OBSOLETE Set up the return address for the inferior function call. +// OBSOLETE Necessary for targets that don't actually execute a JSR/BSR instruction +// OBSOLETE (ie. when using an empty CALL_DUMMY) */ +// OBSOLETE +// OBSOLETE CORE_ADDR +// OBSOLETE m32r_push_return_address (CORE_ADDR pc, CORE_ADDR sp) +// OBSOLETE { +// OBSOLETE write_register (RP_REGNUM, CALL_DUMMY_ADDRESS ()); +// OBSOLETE return sp; +// OBSOLETE } +// OBSOLETE +// OBSOLETE +// OBSOLETE /* Function: pop_frame +// OBSOLETE Discard from the stack the innermost frame, +// OBSOLETE restoring all saved registers. */ +// OBSOLETE +// OBSOLETE struct frame_info * +// OBSOLETE m32r_pop_frame (struct frame_info *frame) +// OBSOLETE { +// OBSOLETE int regnum; +// OBSOLETE +// OBSOLETE if (DEPRECATED_PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame)) +// OBSOLETE generic_pop_dummy_frame (); +// OBSOLETE else +// OBSOLETE { +// OBSOLETE for (regnum = 0; regnum < NUM_REGS; regnum++) +// OBSOLETE if (frame->fsr.regs[regnum] != 0) +// OBSOLETE write_register (regnum, +// OBSOLETE read_memory_integer (frame->fsr.regs[regnum], 4)); +// OBSOLETE +// OBSOLETE write_register (PC_REGNUM, FRAME_SAVED_PC (frame)); +// OBSOLETE write_register (SP_REGNUM, read_register (FP_REGNUM)); +// OBSOLETE if (read_register (PSW_REGNUM) & 0x80) +// OBSOLETE write_register (SPU_REGNUM, read_register (SP_REGNUM)); +// OBSOLETE else +// OBSOLETE write_register (SPI_REGNUM, read_register (SP_REGNUM)); +// OBSOLETE } +// OBSOLETE flush_cached_frames (); +// OBSOLETE return NULL; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Function: frame_saved_pc +// OBSOLETE Find the caller of this frame. We do this by seeing if RP_REGNUM is saved +// OBSOLETE in the stack anywhere, otherwise we get it from the registers. */ +// OBSOLETE +// OBSOLETE CORE_ADDR +// OBSOLETE m32r_frame_saved_pc (struct frame_info *fi) +// OBSOLETE { +// OBSOLETE if (DEPRECATED_PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) +// OBSOLETE return deprecated_read_register_dummy (fi->pc, fi->frame, PC_REGNUM); +// OBSOLETE else +// OBSOLETE return m32r_find_callers_reg (fi, RP_REGNUM); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Function: push_arguments +// OBSOLETE Setup the function arguments for calling a function in the inferior. +// OBSOLETE +// OBSOLETE On the Mitsubishi M32R architecture, there are four registers (R0 to R3) +// OBSOLETE which are dedicated for passing function arguments. Up to the first +// OBSOLETE four arguments (depending on size) may go into these registers. +// OBSOLETE The rest go on the stack. +// OBSOLETE +// OBSOLETE Arguments that are smaller than 4 bytes will still take up a whole +// OBSOLETE register or a whole 32-bit word on the stack, and will be +// OBSOLETE right-justified in the register or the stack word. This includes +// OBSOLETE chars, shorts, and small aggregate types. +// OBSOLETE +// OBSOLETE Arguments of 8 bytes size are split between two registers, if +// OBSOLETE available. If only one register is available, the argument will +// OBSOLETE be split between the register and the stack. Otherwise it is +// OBSOLETE passed entirely on the stack. Aggregate types with sizes between +// OBSOLETE 4 and 8 bytes are passed entirely on the stack, and are left-justified +// OBSOLETE within the double-word (as opposed to aggregates smaller than 4 bytes +// OBSOLETE which are right-justified). +// OBSOLETE +// OBSOLETE Aggregates of greater than 8 bytes are first copied onto the stack, +// OBSOLETE and then a pointer to the copy is passed in the place of the normal +// OBSOLETE argument (either in a register if available, or on the stack). +// OBSOLETE +// OBSOLETE Functions that must return an aggregate type can return it in the +// OBSOLETE normal return value registers (R0 and R1) if its size is 8 bytes or +// OBSOLETE less. For larger return values, the caller must allocate space for +// OBSOLETE the callee to copy the return value to. A pointer to this space is +// OBSOLETE passed as an implicit first argument, always in R0. */ +// OBSOLETE +// OBSOLETE CORE_ADDR +// OBSOLETE m32r_push_arguments (int nargs, struct value **args, CORE_ADDR sp, +// OBSOLETE unsigned char struct_return, CORE_ADDR struct_addr) +// OBSOLETE { +// OBSOLETE int stack_offset, stack_alloc; +// OBSOLETE int argreg; +// OBSOLETE int argnum; +// OBSOLETE struct type *type; +// OBSOLETE CORE_ADDR regval; +// OBSOLETE char *val; +// OBSOLETE char valbuf[4]; +// OBSOLETE int len; +// OBSOLETE int odd_sized_struct; +// OBSOLETE +// OBSOLETE /* first force sp to a 4-byte alignment */ +// OBSOLETE sp = sp & ~3; +// OBSOLETE +// OBSOLETE argreg = ARG0_REGNUM; +// OBSOLETE /* The "struct return pointer" pseudo-argument goes in R0 */ +// OBSOLETE if (struct_return) +// OBSOLETE write_register (argreg++, struct_addr); +// OBSOLETE +// OBSOLETE /* Now make sure there's space on the stack */ +// OBSOLETE for (argnum = 0, stack_alloc = 0; +// OBSOLETE argnum < nargs; argnum++) +// OBSOLETE stack_alloc += ((TYPE_LENGTH (VALUE_TYPE (args[argnum])) + 3) & ~3); +// OBSOLETE sp -= stack_alloc; /* make room on stack for args */ +// OBSOLETE +// OBSOLETE +// OBSOLETE /* Now load as many as possible of the first arguments into +// OBSOLETE registers, and push the rest onto the stack. There are 16 bytes +// OBSOLETE in four registers available. Loop thru args from first to last. */ +// OBSOLETE +// OBSOLETE argreg = ARG0_REGNUM; +// OBSOLETE for (argnum = 0, stack_offset = 0; argnum < nargs; argnum++) +// OBSOLETE { +// OBSOLETE type = VALUE_TYPE (args[argnum]); +// OBSOLETE len = TYPE_LENGTH (type); +// OBSOLETE memset (valbuf, 0, sizeof (valbuf)); +// OBSOLETE if (len < 4) +// OBSOLETE { /* value gets right-justified in the register or stack word */ +// OBSOLETE memcpy (valbuf + (4 - len), +// OBSOLETE (char *) VALUE_CONTENTS (args[argnum]), len); +// OBSOLETE val = valbuf; +// OBSOLETE } +// OBSOLETE else +// OBSOLETE val = (char *) VALUE_CONTENTS (args[argnum]); +// OBSOLETE +// OBSOLETE if (len > 4 && (len & 3) != 0) +// OBSOLETE odd_sized_struct = 1; /* such structs go entirely on stack */ +// OBSOLETE else +// OBSOLETE odd_sized_struct = 0; +// OBSOLETE while (len > 0) +// OBSOLETE { +// OBSOLETE if (argreg > ARGLAST_REGNUM || odd_sized_struct) +// OBSOLETE { /* must go on the stack */ +// OBSOLETE write_memory (sp + stack_offset, val, 4); +// OBSOLETE stack_offset += 4; +// OBSOLETE } +// OBSOLETE /* NOTE WELL!!!!! This is not an "else if" clause!!! +// OBSOLETE That's because some *&^%$ things get passed on the stack +// OBSOLETE AND in the registers! */ +// OBSOLETE if (argreg <= ARGLAST_REGNUM) +// OBSOLETE { /* there's room in a register */ +// OBSOLETE regval = extract_address (val, REGISTER_RAW_SIZE (argreg)); +// OBSOLETE write_register (argreg++, regval); +// OBSOLETE } +// OBSOLETE /* Store the value 4 bytes at a time. This means that things +// OBSOLETE larger than 4 bytes may go partly in registers and partly +// OBSOLETE on the stack. */ +// OBSOLETE len -= REGISTER_RAW_SIZE (argreg); +// OBSOLETE val += REGISTER_RAW_SIZE (argreg); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE return sp; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Function: fix_call_dummy +// OBSOLETE If there is real CALL_DUMMY code (eg. on the stack), this function +// OBSOLETE has the responsability to insert the address of the actual code that +// OBSOLETE is the target of the target function call. */ +// OBSOLETE +// OBSOLETE void +// OBSOLETE m32r_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs, +// OBSOLETE struct value **args, struct type *type, int gcc_p) +// OBSOLETE { +// OBSOLETE /* ld24 r8, <(imm24) fun> */ +// OBSOLETE *(unsigned long *) (dummy) = (fun & 0x00ffffff) | 0xe8000000; +// OBSOLETE } +// OBSOLETE +// OBSOLETE +// OBSOLETE /* Function: m32r_write_sp +// OBSOLETE Because SP is really a read-only register that mirrors either SPU or SPI, +// OBSOLETE we must actually write one of those two as well, depending on PSW. */ +// OBSOLETE +// OBSOLETE void +// OBSOLETE m32r_write_sp (CORE_ADDR val) +// OBSOLETE { +// OBSOLETE unsigned long psw = read_register (PSW_REGNUM); +// OBSOLETE +// OBSOLETE if (psw & 0x80) /* stack mode: user or interrupt */ +// OBSOLETE write_register (SPU_REGNUM, val); +// OBSOLETE else +// OBSOLETE write_register (SPI_REGNUM, val); +// OBSOLETE write_register (SP_REGNUM, val); +// OBSOLETE } +// OBSOLETE +// OBSOLETE void +// OBSOLETE _initialize_m32r_tdep (void) +// OBSOLETE { +// OBSOLETE tm_print_insn = print_insn_m32r; +// OBSOLETE } diff --git a/gdb/monitor.c b/gdb/monitor.c index 8f1450069b7..f58ed2aa6ef 100644 --- a/gdb/monitor.c +++ b/gdb/monitor.c @@ -569,12 +569,14 @@ monitor_expect (char *string, char *buf, int buflen) return 0; } } - else if ((c == '\021' || c == '\023') && - (STREQ (targ_ops->to_shortname, "m32r") - || STREQ (targ_ops->to_shortname, "mon2000"))) - { /* m32r monitor emits random DC1/DC3 chars */ - continue; - } +#if 0 + // OBSOLETE else if ((c == '\021' || c == '\023') && + // OBSOLETE (STREQ (targ_ops->to_shortname, "m32r") + // OBSOLETE || STREQ (targ_ops->to_shortname, "mon2000"))) + // OBSOLETE { /* m32r monitor emits random DC1/DC3 chars */ + // OBSOLETE continue; + // OBSOLETE } +#endif else { /* We got a character that doesn't match the string. We need to |