From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 32138 invoked by alias); 11 Jul 2003 07:15:15 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 32131 invoked from network); 11 Jul 2003 07:15:12 -0000 Received: from unknown (HELO mail04.idc.renesas.com) (202.234.163.13) by sources.redhat.com with SMTP; 11 Jul 2003 07:15:12 -0000 Received: from mail04.idc.renesas.com (localhost [127.0.0.1]) by mail04.idc.renesas.com with ESMTP id h6B7F6nw020401 for ; Fri, 11 Jul 2003 16:15:06 +0900 (JST) Received: from guardian04.idc.renesas.com ([172.20.8.135]) by mail04.idc.renesas.com with ESMTP id h6B7F5HT020395 for ; Fri, 11 Jul 2003 16:15:05 +0900 (JST) Received: (from root@localhost) by guardian04.idc.renesas.com with id h6B7F7rO029683 for gdb-patches@sources.redhat.com; Fri, 11 Jul 2003 16:15:07 +0900 (JST) Received: from unknown [172.20.8.68] by guardian04.idc.renesas.com with SMTP id SAA29680 ; Fri, 11 Jul 2003 16:15:07 +0900 Received: from mta01.idc.renesas.com (localhost [127.0.0.1]) by mta01.idc.renesas.com with ESMTP id h6B7F42L015995 for ; Fri, 11 Jul 2003 16:15:04 +0900 (JST) Received: from rnsmtp01.hoku_r.renesas.com ([10.145.246.51]) by mta01.idc.renesas.com with ESMTP id h6B7F3qr015992 for ; Fri, 11 Jul 2003 16:15:03 +0900 (JST) Received: from mrkaisv.hoku.renesas.com ([10.145.105.245]) by rnsmtp01.hoku_r.renesas.com (8.9.3/3.7W) with ESMTP id QAA24416 for ; Fri, 11 Jul 2003 16:15:04 +0900 (JST) Received: from KEI (unknown [10.145.105.81]) by mrkaisv.hoku.renesas.com (Postfix) with SMTP id 6C8B2798337 for ; Fri, 11 Jul 2003 16:15:03 +0900 (JST) Message-ID: <02ec01c3477c$8ddf3c00$5169910a@KEI> From: "Kei Sakamoto" To: References: <007701c341d0$5d44aa50$5169910a@KEI> Subject: Re: [PATCH] revised m32r target Date: Fri, 11 Jul 2003 07:15:00 -0000 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_02E9_01C347C7.FDA9E620" X-Priority: 3 X-MSMail-Priority: Normal X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165 X-SW-Source: 2003-07/txt/msg00234.txt.bz2 This is a multi-part message in MIME format. ------=_NextPart_000_02E9_01C347C7.FDA9E620 Content-Type: text/plain; charset="iso-2022-jp" Content-Transfer-Encoding: 7bit Content-length: 1317 Hello, Would anyone take a look at this patch? Is this OK to commit? === Kei Sakamoto ----- Original Message ----- From: "Kei Sakamoto" To: Sent: Friday, July 04, 2003 11:02 AM Subject: [PATCH] revised m32r target > Hello, > > These are the revised m32r patches. The m32r is now pure > multi-arched and contains no deprecated code. > > I attached the following new files: > m32r-tdep.c > m32r-stub.c > m32r-rom.c > config/m32r/m32r.mt > > I also attached a patch file for configure.tgt and toplevel > configure. > > I tested the revised m32r target with sim and newlib. > > === gdb Summary === > > # of expected passes 8008 > # of unexpected failures 39 > # of unexpected successes 3 > # of expected failures 52 > # of known failures 17 > # of unresolved testcases 1 > # of untested testcases 3 > # of unsupported tests 11 > > While I was testing the revised m32r target, I found several > bugs of gdb and testcases. I'll send patches for them later. > > > 2003-07-04 Kei Sakamoto > > * configure.tgt : Add m32r-*-*. > * m32r-rom.c, m32r-stub.c m32r-tdep.c, > config/m32r/m32r.mt: New files. > ------=_NextPart_000_02E9_01C347C7.FDA9E620 Content-Type: application/octet-stream; name="m32r-tdep.c" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="m32r-tdep.c" Content-length: 31586 /* Target-dependent code for Renesas M32R, for GDB.=0A= =0A= Copyright 1996, 1998, 1999, 2000, 2001, 2002, 2003 Free Software=0A= Foundation, Inc.=0A= =0A= This file is part of GDB.=0A= =0A= This program is free software; you can redistribute it and/or modify=0A= it under the terms of the GNU General Public License as published by=0A= the Free Software Foundation; either version 2 of the License, or=0A= (at your option) any later version.=0A= =0A= This program is distributed in the hope that it will be useful,=0A= but WITHOUT ANY WARRANTY; without even the implied warranty of=0A= MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the=0A= GNU General Public License for more details.=0A= =0A= You should have received a copy of the GNU General Public License=0A= along with this program; if not, write to the Free Software=0A= Foundation, Inc., 59 Temple Place - Suite 330,=0A= Boston, MA 02111-1307, USA. */=0A= =0A= #include "defs.h"=0A= #include "frame.h"=0A= #include "frame-unwind.h"=0A= #include "frame-base.h"=0A= #include "symtab.h"=0A= #include "gdbtypes.h"=0A= #include "gdbcmd.h"=0A= #include "gdbcore.h"=0A= #include "gdb_string.h"=0A= #include "value.h"=0A= #include "inferior.h"=0A= #include "symfile.h"=0A= #include "objfiles.h"=0A= #include "language.h"=0A= #include "arch-utils.h"=0A= #include "regcache.h"=0A= #include "trad-frame.h"=0A= =0A= #include "gdb_assert.h"=0A= =0A= struct gdbarch_tdep=0A= {=0A= /* gdbarch target dependent data here. Currently unused for M32R. */=0A= };=0A= =0A= /* m32r register names. */=0A= =0A= enum=0A= {=0A= R0_REGNUM =3D 0,=0A= R3_REGNUM =3D 3,=0A= M32R_FP_REGNUM =3D 13,=0A= LR_REGNUM =3D 14,=0A= M32R_SP_REGNUM =3D 15,=0A= PSW_REGNUM =3D 16,=0A= M32R_PC_REGNUM =3D 21,=0A= /* m32r calling convention. */=0A= ARG1_REGNUM =3D R0_REGNUM,=0A= ARGN_REGNUM =3D R3_REGNUM,=0A= RET1_REGNUM =3D R0_REGNUM,=0A= };=0A= =0A= /* Local functions */=0A= =0A= extern void _initialize_m32r_tdep (void);=0A= =0A= static CORE_ADDR=0A= m32r_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)=0A= {=0A= /* Align to the size of an instruction (so that they can safely be=0A= pushed onto the stack. */=0A= return sp & ~3;=0A= }=0A= =0A= /* Should we use EXTRACT_STRUCT_VALUE_ADDRESS instead of=0A= EXTRACT_RETURN_VALUE? GCC_P is true if compiled with gcc=0A= and TYPE is the type (which is known to be struct, union or array).=0A= =0A= The m32r returns anything less than 8 bytes in size in=0A= registers. */=0A= =0A= static int=0A= m32r_use_struct_convention (int gcc_p, struct type *type)=0A= {=0A= return (TYPE_LENGTH (type) > 8);=0A= }=0A= =0A= =0A= /* BREAKPOINT */=0A= #define M32R_BE_BREAKPOINT32 {0x10, 0xf1, 0x70, 0x00}=0A= #define M32R_LE_BREAKPOINT32 {0xf1, 0x10, 0x00, 0x70}=0A= #define M32R_BE_BREAKPOINT16 {0x10, 0xf1}=0A= #define M32R_LE_BREAKPOINT16 {0xf1, 0x10}=0A= =0A= static int=0A= m32r_memory_insert_breakpoint (CORE_ADDR addr, char *contents_cache)=0A= {=0A= int val;=0A= unsigned char *bp;=0A= int bplen;=0A= =0A= bplen =3D (addr & 3) ? 2 : 4;=0A= =0A= /* Save the memory contents. */=0A= val =3D target_read_memory (addr, contents_cache, bplen);=0A= if (val !=3D 0)=0A= return val; /* return error */=0A= =0A= /* Determine appropriate breakpoint contents and size for this address. = */=0A= if (TARGET_BYTE_ORDER =3D=3D BFD_ENDIAN_BIG)=0A= {=0A= if (((addr & 3) =3D=3D 0) &&=0A= ((contents_cache[0] & 0x80) || (contents_cache[2] & 0x80)))=0A= {=0A= static unsigned char insn[] =3D M32R_BE_BREAKPOINT32;=0A= bp =3D insn;=0A= bplen =3D sizeof (insn);=0A= }=0A= else=0A= {=0A= static unsigned char insn[] =3D M32R_BE_BREAKPOINT16;=0A= bp =3D insn;=0A= bplen =3D sizeof (insn);=0A= }=0A= }=0A= else=0A= { /* little-endian */=0A= if (((addr & 3) =3D=3D 0) &&=0A= ((contents_cache[1] & 0x80) || (contents_cache[3] & 0x80)))=0A= {=0A= static unsigned char insn[] =3D M32R_LE_BREAKPOINT32;=0A= bp =3D insn;=0A= bplen =3D sizeof (insn);=0A= }=0A= else=0A= {=0A= static unsigned char insn[] =3D M32R_LE_BREAKPOINT16;=0A= bp =3D insn;=0A= bplen =3D sizeof (insn);=0A= }=0A= }=0A= =0A= /* Write the breakpoint. */=0A= val =3D target_write_memory (addr, (char *) bp, bplen);=0A= return val;=0A= }=0A= =0A= static int=0A= m32r_memory_remove_breakpoint (CORE_ADDR addr, char *contents_cache)=0A= {=0A= int val;=0A= int bplen;=0A= =0A= /* Determine appropriate breakpoint contents and size for this address. = */=0A= if (TARGET_BYTE_ORDER =3D=3D BFD_ENDIAN_BIG)=0A= {=0A= if (((addr & 3) =3D=3D 0) &&=0A= ((contents_cache[0] & 0x80) || (contents_cache[2] & 0x80)))=0A= {=0A= static unsigned char insn[] =3D M32R_BE_BREAKPOINT32;=0A= bplen =3D sizeof (insn);=0A= }=0A= else=0A= {=0A= static unsigned char insn[] =3D M32R_BE_BREAKPOINT16;=0A= bplen =3D sizeof (insn);=0A= }=0A= }=0A= else=0A= {=0A= /* little-endian */=0A= if (((addr & 3) =3D=3D 0) &&=0A= ((contents_cache[1] & 0x80) || (contents_cache[3] & 0x80)))=0A= {=0A= static unsigned char insn[] =3D M32R_BE_BREAKPOINT32;=0A= bplen =3D sizeof (insn);=0A= }=0A= else=0A= {=0A= static unsigned char insn[] =3D M32R_BE_BREAKPOINT16;=0A= bplen =3D sizeof (insn);=0A= }=0A= }=0A= =0A= /* Write contents. */=0A= val =3D target_write_memory (addr, contents_cache, bplen);=0A= return val;=0A= }=0A= =0A= static const unsigned char *=0A= m32r_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)=0A= {=0A= unsigned char *bp;=0A= =0A= /* Determine appropriate breakpoint. */=0A= if (TARGET_BYTE_ORDER =3D=3D BFD_ENDIAN_BIG)=0A= {=0A= if ((*pcptr & 3) =3D=3D 0)=0A= {=0A= static unsigned char insn[] =3D M32R_BE_BREAKPOINT32;=0A= bp =3D insn;=0A= *lenptr =3D sizeof (insn);=0A= }=0A= else=0A= {=0A= static unsigned char insn[] =3D M32R_BE_BREAKPOINT16;=0A= bp =3D insn;=0A= *lenptr =3D sizeof (insn);=0A= }=0A= }=0A= else=0A= {=0A= if ((*pcptr & 3) =3D=3D 0)=0A= {=0A= static unsigned char insn[] =3D M32R_LE_BREAKPOINT32;=0A= bp =3D insn;=0A= *lenptr =3D sizeof (insn);=0A= }=0A= else=0A= {=0A= static unsigned char insn[] =3D M32R_LE_BREAKPOINT16;=0A= bp =3D insn;=0A= *lenptr =3D sizeof (insn);=0A= }=0A= }=0A= =0A= return bp;=0A= }=0A= =0A= =0A= char *m32r_register_names[] =3D {=0A= "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",=0A= "r8", "r9", "r10", "r11", "r12", "fp", "lr", "sp",=0A= "psw", "cbr", "spi", "spu", "bpc", "pc", "accl", "acch",=0A= "evb"=0A= };=0A= =0A= static int=0A= m32r_num_regs (void)=0A= {=0A= return (sizeof (m32r_register_names) / sizeof (m32r_register_names[0]));= =0A= }=0A= =0A= static const char *=0A= m32r_register_name (int reg_nr)=0A= {=0A= if (reg_nr < 0)=0A= return NULL;=0A= if (reg_nr >=3D m32r_num_regs ())=0A= return NULL;=0A= return m32r_register_names[reg_nr];=0A= }=0A= =0A= =0A= /* Return the GDB type object for the "standard" data type=0A= of data in register N. */=0A= =0A= static struct type *=0A= m32r_register_type (struct gdbarch *gdbarch, int reg_nr)=0A= {=0A= if (reg_nr =3D=3D M32R_PC_REGNUM)=0A= return builtin_type_void_func_ptr;=0A= else if (reg_nr =3D=3D M32R_SP_REGNUM || reg_nr =3D=3D M32R_FP_REGNUM)=0A= return builtin_type_void_data_ptr;=0A= else=0A= return builtin_type_int32;=0A= }=0A= =0A= =0A= /* Write into appropriate registers a function return value=0A= of type TYPE, given in virtual format.=20=20=0A= =0A= Things always get returned in RET1_REGNUM, RET2_REGNUM. */=0A= =0A= static void=0A= m32r_store_return_value (struct type *type, struct regcache *regcache,=0A= const void *valbuf)=0A= {=0A= CORE_ADDR regval;=0A= int len =3D TYPE_LENGTH (type);=0A= =0A= regval =3D extract_unsigned_integer (valbuf, len > 4 ? 4 : len);=0A= regcache_cooked_write_unsigned (regcache, RET1_REGNUM, regval);=0A= =0A= if (len > 4)=0A= {=0A= regval =3D extract_unsigned_integer (valbuf + 4, len - 4);=0A= regcache_cooked_write_unsigned (regcache, RET1_REGNUM + 1, regval);= =0A= }=0A= }=0A= =0A= /* Extract from an array REGBUF containing the (raw) register state=0A= the address in which a function should return its structure value,=0A= as a CORE_ADDR (or an expression that can be used as one). */=0A= =0A= static CORE_ADDR=0A= m32r_extract_struct_value_address (struct regcache *regcache)=0A= {=0A= ULONGEST addr;=0A= regcache_cooked_read_unsigned (regcache, ARG1_REGNUM, &addr);=0A= return addr;=0A= }=0A= =0A= =0A= /* This is required by skip_prologue. The results of decoding a prologue=0A= should be cached because this thrashing is getting nuts. */=0A= =0A= static void=0A= decode_prologue (CORE_ADDR start_pc, CORE_ADDR scan_limit,=0A= CORE_ADDR *pl_endptr)=0A= {=0A= unsigned long framesize;=0A= int insn;=0A= int op1;=0A= int maybe_one_more =3D 0;=0A= CORE_ADDR after_prologue =3D 0;=0A= CORE_ADDR after_stack_adjust =3D 0;=0A= CORE_ADDR current_pc;=0A= =0A= framesize =3D 0;=0A= after_prologue =3D 0;=0A= =0A= for (current_pc =3D start_pc; current_pc < scan_limit; current_pc +=3D 2)= =0A= {=0A= insn =3D read_memory_unsigned_integer (current_pc, 2);=0A= =0A= /* If this is a 32 bit instruction, we dont want to examine its=0A= immediate data as though it were an instruction */=0A= if (current_pc & 0x02)=0A= {=0A= /* Clear the parallel execution bit from 16 bit instruction */=0A= if (maybe_one_more)=0A= {=0A= /* The last instruction was a branch, usually terminates=0A= the series, but if this is a parallel instruction,=0A= it may be a stack framing instruction */=0A= if (!(insn & 0x8000))=0A= {=0A= /* nope, we are really done */=0A= break;=0A= }=0A= }=0A= /* decode this instruction further */=0A= insn &=3D 0x7fff;=0A= }=0A= else=0A= {=0A= if (maybe_one_more)=0A= break; /* This isnt the one more */=0A= if (insn & 0x8000)=0A= {=0A= if (current_pc =3D=3D scan_limit)=0A= scan_limit +=3D 2; /* extend the search */=0A= current_pc +=3D 2; /* skip the immediate data */=0A= if (insn =3D=3D 0x8faf) /* add3 sp, sp, xxxx */=0A= /* add 16 bit sign-extended offset */=0A= {=0A= framesize +=3D=0A= -((short) read_memory_unsigned_integer (current_pc, 2));=0A= }=0A= else=0A= {=0A= if (((insn >> 8) =3D=3D 0xe4) && /* ld24 r4, xxxxxx; sub sp, r4 */=0A= read_memory_unsigned_integer (current_pc + 2,=0A= 2) =3D=3D 0x0f24)=0A= /* subtract 24 bit sign-extended negative-offset */=0A= {=0A= insn =3D read_memory_unsigned_integer (current_pc - 2, 4);=0A= if (insn & 0x00800000) /* sign extend */=0A= insn |=3D 0xff000000; /* negative */=0A= else=0A= insn &=3D 0x00ffffff; /* positive */=0A= framesize +=3D insn;=0A= }=0A= }=0A= after_prologue =3D current_pc;=0A= continue;=0A= }=0A= }=0A= op1 =3D insn & 0xf000; /* isolate just the first nibble */=0A= =0A= if ((insn & 0xf0ff) =3D=3D 0x207f)=0A= { /* st reg, @-sp */=0A= int regno;=0A= framesize +=3D 4;=0A= regno =3D ((insn >> 8) & 0xf);=0A= after_prologue =3D 0;=0A= continue;=0A= }=0A= if ((insn >> 8) =3D=3D 0x4f) /* addi sp, xx */=0A= /* add 8 bit sign-extended offset */=0A= {=0A= int stack_adjust =3D (char) (insn & 0xff);=0A= =0A= /* there are probably two of these stack adjustments:=0A= 1) A negative one in the prologue, and=0A= 2) A positive one in the epilogue.=0A= We are only interested in the first one. */=0A= =0A= if (stack_adjust < 0)=0A= {=0A= framesize -=3D stack_adjust;=0A= after_prologue =3D 0;=0A= /* A frameless function may have no "mv fp, sp".=0A= In that case, this is the end of the prologue. */=0A= after_stack_adjust =3D current_pc + 2;=0A= }=0A= continue;=0A= }=0A= if (insn =3D=3D 0x1d8f)=0A= { /* mv fp, sp */=0A= after_prologue =3D current_pc + 2;=0A= break; /* end of stack adjustments */=0A= }=0A= /* Nop looks like a branch, continue explicitly */=0A= if (insn =3D=3D 0x7000)=0A= {=0A= after_prologue =3D current_pc + 2;=0A= continue; /* nop occurs between pushes */=0A= }=0A= /* End of prolog if any of these are branch instructions */=0A= if ((op1 =3D=3D 0x7000) || (op1 =3D=3D 0xb000) || (op1 =3D=3D 0xf000)= )=0A= {=0A= after_prologue =3D current_pc;=0A= maybe_one_more =3D 1;=0A= continue;=0A= }=0A= /* Some of the branch instructions are mixed with other types */=0A= if (op1 =3D=3D 0x1000)=0A= {=0A= int subop =3D insn & 0x0ff0;=0A= if ((subop =3D=3D 0x0ec0) || (subop =3D=3D 0x0fc0))=0A= {=0A= after_prologue =3D current_pc;=0A= maybe_one_more =3D 1;=0A= continue; /* jmp , jl */=0A= }=0A= }=0A= }=0A= =0A= if (current_pc >=3D scan_limit)=0A= {=0A= if (pl_endptr)=0A= {=0A= if (after_stack_adjust !=3D 0)=0A= /* We did not find a "mv fp,sp", but we DID find=0A= a stack_adjust. Is it safe to use that as the=0A= end of the prologue? I just don't know. */=0A= {=0A= *pl_endptr =3D after_stack_adjust;=0A= }=0A= else=0A= /* We reached the end of the loop without finding the end=0A= of the prologue. No way to win -- we should report failure.=20=20= =0A= The way we do that is to return the original start_pc.=0A= GDB will set a breakpoint at the start of the function (etc.) */=0A= *pl_endptr =3D start_pc;=0A= }=0A= return;=0A= }=0A= if (after_prologue =3D=3D 0)=0A= after_prologue =3D current_pc;=0A= =0A= if (pl_endptr)=0A= *pl_endptr =3D after_prologue;=0A= } /* decode_prologue */=0A= =0A= /* Function: skip_prologue=0A= Find end of function prologue */=0A= =0A= #define DEFAULT_SEARCH_LIMIT 44=0A= =0A= CORE_ADDR=0A= m32r_skip_prologue (CORE_ADDR pc)=0A= {=0A= CORE_ADDR func_addr, func_end;=0A= struct symtab_and_line sal;=0A= =0A= /* See what the symbol table says */=0A= =0A= if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))=0A= {=0A= sal =3D find_pc_line (func_addr, 0);=0A= =0A= if (sal.line !=3D 0 && sal.end <=3D func_end)=0A= {=0A= func_end =3D sal.end;=0A= }=0A= else=0A= /* Either there's no line info, or the line after the prologue is after=0A= the end of the function. In this case, there probably isn't a=0A= prologue. */=0A= {=0A= func_end =3D min (func_end, func_addr + DEFAULT_SEARCH_LIMIT);=0A= }=0A= }=0A= else=0A= func_end =3D pc + DEFAULT_SEARCH_LIMIT;=0A= decode_prologue (pc, func_end, &sal.end);=0A= return sal.end;=0A= }=0A= =0A= =0A= struct m32r_unwind_cache=0A= {=0A= /* The previous frame's inner most stack address. Used as this=0A= frame ID's stack_addr. */=0A= CORE_ADDR prev_sp;=0A= /* The frame's base, optionally used by the high-level debug info. */=0A= CORE_ADDR base;=0A= int size;=0A= /* How far the SP and r13 (FP) have been offset from the start of=0A= the stack frame (as defined by the previous frame's stack=0A= pointer). */=0A= LONGEST sp_offset;=0A= LONGEST r13_offset;=0A= int uses_frame;=0A= /* Table indicating the location of each and every register. */=0A= struct trad_frame_saved_reg *saved_regs;=0A= };=0A= =0A= /* Put here the code to store, into fi->saved_regs, the addresses of=0A= the saved registers of frame described by FRAME_INFO. This=0A= includes special registers such as pc and fp saved in special ways=0A= in the stack frame. sp is even more special: the address we return=0A= for it IS the sp for the next frame. */=0A= =0A= static struct m32r_unwind_cache *=0A= m32r_frame_unwind_cache (struct frame_info *next_frame,=0A= void **this_prologue_cache)=0A= {=0A= CORE_ADDR pc;=0A= ULONGEST prev_sp;=0A= ULONGEST this_base;=0A= unsigned long op;=0A= int i;=0A= struct m32r_unwind_cache *info;=0A= =0A= if ((*this_prologue_cache))=0A= return (*this_prologue_cache);=0A= =0A= info =3D FRAME_OBSTACK_ZALLOC (struct m32r_unwind_cache);=0A= (*this_prologue_cache) =3D info;=0A= info->saved_regs =3D trad_frame_alloc_saved_regs (next_frame);=0A= =0A= info->size =3D 0;=0A= info->sp_offset =3D 0;=0A= =0A= info->uses_frame =3D 0;=0A= for (pc =3D frame_func_unwind (next_frame);=0A= pc > 0 && pc < frame_pc_unwind (next_frame); pc +=3D 2)=0A= {=0A= if ((pc & 2) =3D=3D 0)=0A= {=0A= op =3D get_frame_memory_unsigned (next_frame, pc, 4);=0A= if ((op & 0x80000000) =3D=3D 0x80000000)=0A= {=0A= /* 32-bit instruction */=0A= if ((op & 0xffff0000) =3D=3D 0x8faf0000)=0A= {=0A= /* add3 sp,sp,xxxx */=0A= short n =3D op & 0xffff;=0A= info->sp_offset +=3D n;=0A= }=0A= else if (((op >> 8) =3D=3D 0xe4) && /* ld24 r4, xxxxxx; sub sp, r4 *= /=0A= get_frame_memory_unsigned (next_frame, pc + 4,=0A= 2) =3D=3D 0x0f24)=0A= {=0A= unsigned long n =3D op & 0xffffff;=0A= info->sp_offset +=3D n;=0A= pc +=3D 2;=0A= }=0A= else=0A= break;=0A= =0A= pc +=3D 2;=0A= continue;=0A= }=0A= }=0A= =0A= /* 16-bit instructions */=0A= op =3D get_frame_memory_unsigned (next_frame, pc, 2) & 0x7fff;=0A= if ((op & 0xf0ff) =3D=3D 0x207f)=0A= {=0A= /* st rn, @-sp */=0A= int regno =3D ((op >> 8) & 0xf);=0A= info->sp_offset -=3D 4;=0A= info->saved_regs[regno].addr =3D info->sp_offset;=0A= }=0A= else if ((op & 0xff00) =3D=3D 0x4f00)=0A= {=0A= /* addi sp, xx */=0A= int n =3D (char) (op & 0xff);=0A= info->sp_offset +=3D n;=0A= }=0A= else if (op =3D=3D 0x1d8f)=0A= {=0A= /* mv fp, sp */=0A= info->uses_frame =3D 1;=0A= info->r13_offset =3D info->sp_offset;=0A= }=0A= else if (op =3D=3D 0x7000)=0A= /* nop */=0A= continue;=0A= else=0A= break;=0A= }=0A= =0A= info->size =3D -info->sp_offset;=0A= =0A= /* Compute the previous frame's stack pointer (which is also the=0A= frame's ID's stack address), and this frame's base pointer. */=0A= if (info->uses_frame)=0A= {=0A= /* The SP was moved to the FP. This indicates that a new frame=0A= was created. Get THIS frame's FP value by unwinding it from=0A= the next frame. */=0A= frame_unwind_unsigned_register (next_frame, M32R_FP_REGNUM, &this_bas= e);=0A= /* The FP points at the last saved register. Adjust the FP back=0A= to before the first saved register giving the SP. */=0A= prev_sp =3D this_base + info->size;=0A= }=0A= else=0A= {=0A= /* Assume that the FP is this frame's SP but with that pushed=0A= stack space added back. */=0A= frame_unwind_unsigned_register (next_frame, M32R_SP_REGNUM, &this_bas= e);=0A= prev_sp =3D this_base + info->size;=0A= }=0A= =0A= /* Convert that SP/BASE into real addresses. */=0A= info->prev_sp =3D prev_sp;=0A= info->base =3D this_base;=0A= =0A= /* Adjust all the saved registers so that they contain addresses and=0A= not offsets. */=0A= for (i =3D 0; i < NUM_REGS - 1; i++)=0A= if (trad_frame_addr_p (info->saved_regs, i))=0A= info->saved_regs[i].addr =3D (info->prev_sp + info->saved_regs[i].add= r);=0A= =0A= /* The call instruction moves the caller's PC in the callee's LR.=0A= Since this is an unwind, do the reverse. Copy the location of LR=0A= into PC (the address / regnum) so that a request for PC will be=0A= converted into a request for the LR. */=0A= info->saved_regs[M32R_PC_REGNUM] =3D info->saved_regs[LR_REGNUM];=0A= =0A= /* The previous frame's SP needed to be computed. Save the computed=0A= value. */=0A= trad_frame_set_value (info->saved_regs, M32R_SP_REGNUM, prev_sp);=0A= =0A= return info;=0A= }=0A= =0A= static CORE_ADDR=0A= m32r_read_pc (ptid_t ptid)=0A= {=0A= ptid_t save_ptid;=0A= CORE_ADDR pc;=0A= =0A= save_ptid =3D inferior_ptid;=0A= inferior_ptid =3D ptid;=0A= pc =3D (int) read_register (M32R_PC_REGNUM);=0A= inferior_ptid =3D save_ptid;=0A= return pc;=0A= }=0A= =0A= static void=0A= m32r_write_pc (CORE_ADDR val, ptid_t ptid)=0A= {=0A= ptid_t save_ptid;=0A= =0A= save_ptid =3D inferior_ptid;=0A= inferior_ptid =3D ptid;=0A= write_register (M32R_PC_REGNUM, val);=0A= inferior_ptid =3D save_ptid;=0A= }=0A= =0A= static CORE_ADDR=0A= m32r_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)=0A= {=0A= ULONGEST sp;=0A= frame_unwind_unsigned_register (next_frame, M32R_SP_REGNUM, &sp);=0A= return sp;=0A= }=0A= =0A= =0A= static CORE_ADDR=0A= m32r_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,=0A= struct regcache *regcache, CORE_ADDR bp_addr, int nargs,=0A= struct value **args, CORE_ADDR sp, int struct_return,=0A= CORE_ADDR struct_addr)=0A= {=0A= int stack_offset, stack_alloc;=0A= int argreg =3D ARG1_REGNUM;=0A= int argnum;=0A= struct type *type;=0A= enum type_code typecode;=0A= CORE_ADDR regval;=0A= char *val;=0A= char valbuf[MAX_REGISTER_SIZE];=0A= int len;=0A= int odd_sized_struct;=0A= =0A= /* first force sp to a 4-byte alignment */=0A= sp =3D sp & ~3;=0A= =0A= /* Set the return address. For the m32r, the return breakpoint is=0A= always at BP_ADDR. */=0A= regcache_cooked_write_unsigned (regcache, LR_REGNUM, bp_addr);=0A= =0A= /* If STRUCT_RETURN is true, then the struct return address (in=0A= STRUCT_ADDR) will consume the first argument-passing register.=0A= Both adjust the register count and store that value. */=0A= if (struct_return)=0A= {=0A= regcache_cooked_write_unsigned (regcache, argreg, struct_addr);=0A= argreg++;=0A= }=0A= =0A= /* Now make sure there's space on the stack */=0A= for (argnum =3D 0, stack_alloc =3D 0; argnum < nargs; argnum++)=0A= stack_alloc +=3D ((TYPE_LENGTH (VALUE_TYPE (args[argnum])) + 3) & ~3);= =0A= sp -=3D stack_alloc; /* make room on stack for args */=0A= =0A= for (argnum =3D 0, stack_offset =3D 0; argnum < nargs; argnum++)=0A= {=0A= type =3D VALUE_TYPE (args[argnum]);=0A= typecode =3D TYPE_CODE (type);=0A= len =3D TYPE_LENGTH (type);=0A= =0A= memset (valbuf, 0, sizeof (valbuf));=0A= =0A= /* Passes structures that do not fit in 2 registers by reference. */= =0A= if (len > 8=0A= && (typecode =3D=3D TYPE_CODE_STRUCT || typecode =3D=3D TYPE_CODE_UNION)= )=0A= {=0A= store_unsigned_integer (valbuf, 4, VALUE_ADDRESS (args[argnum]));=0A= typecode =3D TYPE_CODE_PTR;=0A= len =3D 4;=0A= val =3D valbuf;=0A= }=0A= else if (len < 4)=0A= {=0A= /* value gets right-justified in the register or stack word */=0A= memcpy (valbuf + (REGISTER_RAW_SIZE (argreg) - len),=0A= (char *) VALUE_CONTENTS (args[argnum]), len);=0A= val =3D valbuf;=0A= }=0A= else=0A= val =3D (char *) VALUE_CONTENTS (args[argnum]);=0A= =0A= while (len > 0)=0A= {=0A= if (argreg > ARGN_REGNUM)=0A= {=0A= /* must go on the stack */=0A= write_memory (sp + stack_offset, val, 4);=0A= stack_offset +=3D 4;=0A= }=0A= else if (argreg <=3D ARGN_REGNUM)=0A= {=0A= /* there's room in a register */=0A= regval =3D=0A= extract_unsigned_integer (val, REGISTER_RAW_SIZE (argreg));=0A= regcache_cooked_write_unsigned (regcache, argreg++, regval);=0A= }=0A= =0A= /* Store the value 4 bytes at a time. This means that things=0A= larger than 4 bytes may go partly in registers and partly=0A= on the stack. */=0A= len -=3D REGISTER_RAW_SIZE (argreg);=0A= val +=3D REGISTER_RAW_SIZE (argreg);=0A= }=0A= }=0A= =0A= /* Finally, update the SP register. */=0A= regcache_cooked_write_unsigned (regcache, M32R_SP_REGNUM, sp);=0A= =0A= return sp;=0A= }=0A= =0A= =0A= /* Given a return value in `regbuf' with a type `valtype',=20=0A= extract and copy its value into `valbuf'. */=0A= =0A= static void=0A= m32r_extract_return_value (struct type *type, struct regcache *regcache,=0A= void *dst)=0A= {=0A= bfd_byte *valbuf =3D dst;=0A= int len =3D TYPE_LENGTH (type);=0A= ULONGEST tmp;=0A= =0A= /* By using store_unsigned_integer we avoid having to do=0A= anything special for small big-endian values. */=0A= regcache_cooked_read_unsigned (regcache, RET1_REGNUM, &tmp);=0A= store_unsigned_integer (valbuf, (len > 4 ? len - 4 : len), tmp);=0A= =0A= /* Ignore return values more than 8 bytes in size because the m32r=0A= returns anything more than 8 bytes in the stack. */=0A= if (len > 4)=0A= {=0A= regcache_cooked_read_unsigned (regcache, RET1_REGNUM + 1, &tmp);=0A= store_unsigned_integer (valbuf + len - 4, 4, tmp);=0A= }=0A= }=0A= =0A= =0A= static CORE_ADDR=0A= m32r_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)=0A= {=0A= ULONGEST pc;=0A= frame_unwind_unsigned_register (next_frame, M32R_PC_REGNUM, &pc);=0A= return pc;=0A= }=0A= =0A= /* Given a GDB frame, determine the address of the calling function's=0A= frame. This will be used to create a new GDB frame struct. */=0A= =0A= static void=0A= m32r_frame_this_id (struct frame_info *next_frame,=0A= void **this_prologue_cache, struct frame_id *this_id)=0A= {=0A= struct m32r_unwind_cache *info=0A= =3D m32r_frame_unwind_cache (next_frame, this_prologue_cache);=0A= CORE_ADDR base;=0A= CORE_ADDR func;=0A= struct minimal_symbol *msym_stack;=0A= struct frame_id id;=0A= =0A= /* The FUNC is easy. */=0A= func =3D frame_func_unwind (next_frame);=0A= =0A= /* This is meant to halt the backtrace at "_start". Make sure we=0A= don't halt it at a generic dummy frame. */=0A= if (inside_entry_file (func))=0A= return;=0A= =0A= /* Check if the stack is empty. */=0A= msym_stack =3D lookup_minimal_symbol ("_stack", NULL, NULL);=0A= if (msym_stack && info->base =3D=3D SYMBOL_VALUE_ADDRESS (msym_stack))=0A= return;=0A= =0A= /* Hopefully the prologue analysis either correctly determined the=0A= frame's base (which is the SP from the previous frame), or set=0A= that base to "NULL". */=0A= base =3D info->prev_sp;=0A= if (base =3D=3D 0)=0A= return;=0A= =0A= id =3D frame_id_build (base, func);=0A= =0A= /* Check that we're not going round in circles with the same frame=0A= ID (but avoid applying the test to sentinel frames which do go=0A= round in circles). Can't use frame_id_eq() as that doesn't yet=0A= compare the frame's PC value. */=0A= if (frame_relative_level (next_frame) >=3D 0=0A= && get_frame_type (next_frame) !=3D DUMMY_FRAME=0A= && frame_id_eq (get_frame_id (next_frame), id))=0A= return;=0A= =0A= (*this_id) =3D id;=0A= }=0A= =0A= static void=0A= m32r_frame_prev_register (struct frame_info *next_frame,=0A= void **this_prologue_cache,=0A= int regnum, int *optimizedp,=0A= enum lval_type *lvalp, CORE_ADDR *addrp,=0A= int *realnump, void *bufferp)=0A= {=0A= struct m32r_unwind_cache *info=0A= =3D m32r_frame_unwind_cache (next_frame, this_prologue_cache);=0A= trad_frame_prev_register (next_frame, info->saved_regs, regnum,=0A= optimizedp, lvalp, addrp, realnump, bufferp);=0A= }=0A= =0A= static const struct frame_unwind m32r_frame_unwind =3D {=0A= NORMAL_FRAME,=0A= m32r_frame_this_id,=0A= m32r_frame_prev_register=0A= };=0A= =0A= static const struct frame_unwind *=0A= m32r_frame_p (CORE_ADDR pc)=0A= {=0A= return &m32r_frame_unwind;=0A= }=0A= =0A= static CORE_ADDR=0A= m32r_frame_base_address (struct frame_info *next_frame, void **this_cache)= =0A= {=0A= struct m32r_unwind_cache *info=0A= =3D m32r_frame_unwind_cache (next_frame, this_cache);=0A= return info->base;=0A= }=0A= =0A= static const struct frame_base m32r_frame_base =3D {=0A= &m32r_frame_unwind,=0A= m32r_frame_base_address,=0A= m32r_frame_base_address,=0A= m32r_frame_base_address=0A= };=0A= =0A= /* Assuming NEXT_FRAME->prev is a dummy, return the frame ID of that=0A= dummy frame. The frame ID's base needs to match the TOS value=0A= saved by save_dummy_frame_tos(), and the PC match the dummy frame's=0A= breakpoint. */=0A= =0A= static struct frame_id=0A= m32r_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_fram= e)=0A= {=0A= return frame_id_build (m32r_unwind_sp (gdbarch, next_frame),=0A= frame_pc_unwind (next_frame));=0A= }=0A= =0A= =0A= static gdbarch_init_ftype m32r_gdbarch_init;=0A= =0A= static struct gdbarch *=0A= m32r_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)= =0A= {=0A= struct gdbarch *gdbarch;=0A= struct gdbarch_tdep *tdep;=0A= =0A= /* If there is already a candidate, use it. */=0A= arches =3D gdbarch_list_lookup_by_info (arches, &info);=0A= if (arches !=3D NULL)=0A= return arches->gdbarch;=0A= =0A= /* Allocate space for the new architecture. */=0A= tdep =3D XMALLOC (struct gdbarch_tdep);=0A= gdbarch =3D gdbarch_alloc (&info, tdep);=0A= =0A= set_gdbarch_read_pc (gdbarch, m32r_read_pc);=0A= set_gdbarch_write_pc (gdbarch, m32r_write_pc);=0A= set_gdbarch_unwind_sp (gdbarch, m32r_unwind_sp);=0A= =0A= set_gdbarch_num_regs (gdbarch, m32r_num_regs ());=0A= set_gdbarch_sp_regnum (gdbarch, M32R_SP_REGNUM);=0A= set_gdbarch_register_name (gdbarch, m32r_register_name);=0A= set_gdbarch_register_type (gdbarch, m32r_register_type);=0A= =0A= set_gdbarch_extract_return_value (gdbarch, m32r_extract_return_value);=0A= set_gdbarch_push_dummy_call (gdbarch, m32r_push_dummy_call);=0A= set_gdbarch_store_return_value (gdbarch, m32r_store_return_value);=0A= set_gdbarch_extract_struct_value_address (gdbarch,=0A= m32r_extract_struct_value_address);=0A= set_gdbarch_use_struct_convention (gdbarch, m32r_use_struct_convention);= =0A= =0A= set_gdbarch_skip_prologue (gdbarch, m32r_skip_prologue);=0A= set_gdbarch_inner_than (gdbarch, core_addr_lessthan);=0A= set_gdbarch_decr_pc_after_break (gdbarch, 0);=0A= set_gdbarch_function_start_offset (gdbarch, 0);=0A= set_gdbarch_breakpoint_from_pc (gdbarch, m32r_breakpoint_from_pc);=0A= set_gdbarch_memory_insert_breakpoint (gdbarch,=0A= m32r_memory_insert_breakpoint);=0A= set_gdbarch_memory_remove_breakpoint (gdbarch,=0A= m32r_memory_remove_breakpoint);=0A= =0A= set_gdbarch_frame_args_skip (gdbarch, 0);=0A= set_gdbarch_frameless_function_invocation (gdbarch,=0A= frameless_look_for_prologue);=0A= =0A= set_gdbarch_frame_align (gdbarch, m32r_frame_align);=0A= =0A= frame_unwind_append_predicate (gdbarch, m32r_frame_p);=0A= frame_base_set_default (gdbarch, &m32r_frame_base);=0A= =0A= /* Methods for saving / extracting a dummy frame's ID. The ID's=0A= stack address must match the SP value returned by=0A= PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos. */=0A= set_gdbarch_unwind_dummy_id (gdbarch, m32r_unwind_dummy_id);=0A= =0A= /* Return the unwound PC value. */=0A= set_gdbarch_unwind_pc (gdbarch, m32r_unwind_pc);=0A= =0A= set_gdbarch_print_insn (gdbarch, print_insn_m32r);=0A= =0A= return gdbarch;=0A= }=0A= =0A= void=0A= _initialize_m32r_tdep (void)=0A= {=0A= register_gdbarch_init (bfd_arch_m32r, m32r_gdbarch_init);=0A= }=0A= ------=_NextPart_000_02E9_01C347C7.FDA9E620 Content-Type: application/octet-stream; name="m32r-stub.c" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="m32r-stub.c" Content-length: 54891 /**************************************************************************= **=0A= =0A= THIS SOFTWARE IS NOT COPYRIGHTED=0A= =0A= HP offers the following for use in the public domain. HP makes no=0A= warranty with regard to the software or it's performance and the=0A= user accepts the software "AS IS" with all faults.=0A= =0A= HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD=0A= TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES=0A= OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.=0A= =0A= ***************************************************************************= */=0A= =0A= /**************************************************************************= **=0A= * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $=0A= *=0A= * Module name: remcom.c $=0A= * Revision: 1.34 $=0A= * Date: 91/03/09 12:29:49 $=0A= * Contributor: Lake Stevens Instrument Division$=0A= *=0A= * Description: low level support for gdb debugger. $=0A= *=0A= * Considerations: only works on target hardware $=0A= *=0A= * Written by: Glenn Engel $=0A= * ModuleState: Experimental $=0A= *=0A= * NOTES: See Below $=0A= *=0A= * Modified for M32R by Michael Snyder, Cygnus Support.=0A= *=0A= * To enable debugger support, two things need to happen. One, a=0A= * call to set_debug_traps() is necessary in order to allow any breakpoint= s=0A= * or error conditions to be properly intercepted and reported to gdb.=0A= * Two, a breakpoint needs to be generated to begin communication. This= =0A= * is most easily accomplished by a call to breakpoint(). Breakpoint()=0A= * simulates a breakpoint by executing a trap #1.=0A= *=0A= * The external function exceptionHandler() is=0A= * used to attach a specific handler to a specific M32R vector number.=0A= * It should use the same privilege level it runs at. It should=0A= * install it as an interrupt gate so that interrupts are masked=0A= * while the handler runs.=0A= *=0A= * Because gdb will sometimes write to the stack area to execute function= =0A= * calls, this program cannot rely on using the supervisor stack so it=0A= * uses it's own stack area reserved in the int array remcomStack.=0A= *=0A= *************=0A= *=0A= * The following gdb commands are supported:=0A= *=0A= * command function Return value=0A= *=0A= * g return the value of the CPU registers hex data or ENN= =0A= * G set the value of the CPU registers OK or ENN=0A= *=0A= * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN= =0A= * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN=0A= * XAA..AA,LLLL: Write LLLL binary bytes at address OK or ENN=0A= * AA..AA=0A= *=0A= * c Resume at current address SNN ( signal N= N)=0A= * cAA..AA Continue at address AA..AA SNN=0A= *=0A= * s Step one instruction SNN=0A= * sAA..AA Step one instruction from AA..AA SNN=0A= *=0A= * k kill=0A= *=0A= * ? What was the last sigval ? SNN (signal NN= )=0A= *=0A= * All commands and responses are sent with a packet which includes a=0A= * checksum. A packet consists of=0A= *=0A= * $#.=0A= *=0A= * where=0A= * :: =0A= * :: >=0A= *=0A= * When a packet is received, it is first acknowledged with either '+' or '= -'.=0A= * '+' indicates a successful transfer. '-' indicates a failed transfer.= =0A= *=0A= * Example:=0A= *=0A= * Host: Reply:=0A= * $m0,10#2a +$00010203040506070809101112131415#42=0A= *=0A= **************************************************************************= **/=0A= =0A= =0A= /************************************************************************= =0A= *=0A= * external low-level support routines=0A= */=0A= extern void putDebugChar (); /* write a single character */=0A= extern int getDebugChar (); /* read and return a single char */=0A= extern void exceptionHandler (); /* assign an exception handler */=0A= =0A= /**************************************************************************= ***=0A= * BUFMAX defines the maximum number of characters in inbound/outbound buff= ers=0A= * at least NUMREGBYTES*2 are needed for register packets=20=0A= */=0A= #define BUFMAX 400=0A= =0A= static char initialized; /* boolean flag. !=3D 0 means we've been initializ= ed */=0A= =0A= int remote_debug;=0A= /* debug > 0 prints ill-formed commands in valid packets & checksum error= s */=0A= =0A= static const unsigned char hexchars[] =3D "0123456789abcdef";=0A= =0A= #define NUMREGS 24=0A= =0A= /* Number of bytes of registers. */=0A= #define NUMREGBYTES (NUMREGS * 4)=0A= enum regnames=0A= { R0, R1, R2, R3, R4, R5, R6, R7,=0A= R8, R9, R10, R11, R12, R13, R14, R15,=0A= PSW, CBR, SPI, SPU, BPC, PC, ACCL, ACCH=0A= };=0A= =0A= enum SYS_calls=0A= {=0A= SYS_null,=0A= SYS_exit,=0A= SYS_open,=0A= SYS_close,=0A= SYS_read,=0A= SYS_write,=0A= SYS_lseek,=0A= SYS_unlink,=0A= SYS_getpid,=0A= SYS_kill,=0A= SYS_fstat,=0A= SYS_sbrk,=0A= SYS_fork,=0A= SYS_execve,=0A= SYS_wait4,=0A= SYS_link,=0A= SYS_chdir,=0A= SYS_stat,=0A= SYS_utime,=0A= SYS_chown,=0A= SYS_chmod,=0A= SYS_time,=0A= SYS_pipe=0A= };=0A= =0A= static int registers[NUMREGS];=0A= =0A= #define STACKSIZE 8096=0A= static unsigned char remcomInBuffer[BUFMAX];=0A= static unsigned char remcomOutBuffer[BUFMAX];=0A= static int remcomStack[STACKSIZE / sizeof (int)];=0A= static int *stackPtr =3D &remcomStack[STACKSIZE / sizeof (int) - 1];=0A= =0A= static unsigned int save_vectors[18]; /* previous exception vectors */=0A= =0A= /* Indicate to caller of mem2hex or hex2mem that there has been an error. *= /=0A= static volatile int mem_err =3D 0;=0A= =0A= /* Store the vector number here (since GDB only gets the signal=0A= number through the usual means, and that's not very specific). */=0A= int gdb_m32r_vector =3D -1;=0A= =0A= #if 0=0A= #include "syscall.h" /* for SYS_exit, SYS_write etc. */=0A= #endif=0A= =0A= /* Global entry points:=0A= */=0A= =0A= extern void handle_exception (int);=0A= extern void set_debug_traps (void);=0A= extern void breakpoint (void);=0A= =0A= /* Local functions:=0A= */=0A= =0A= static int computeSignal (int);=0A= static void putpacket (unsigned char *);=0A= static unsigned char *getpacket (void);=0A= =0A= static unsigned char *mem2hex (unsigned char *, unsigned char *, int, int);= =0A= static unsigned char *hex2mem (unsigned char *, unsigned char *, int, int);= =0A= static int hexToInt (unsigned char **, int *);=0A= static unsigned char *bin2mem (unsigned char *, unsigned char *, int, int);= =0A= static void stash_registers (void);=0A= static void restore_registers (void);=0A= static int prepare_to_step (int);=0A= static int finish_from_step (void);=0A= static unsigned long crc32 (unsigned char *, int, unsigned long);=0A= =0A= static void gdb_error (char *, char *);=0A= static int gdb_putchar (int), gdb_puts (char *), gdb_write (char *, int);= =0A= =0A= static unsigned char *strcpy (unsigned char *, const unsigned char *);=0A= static int strlen (const unsigned char *);=0A= =0A= /*=0A= * This function does all command procesing for interfacing to gdb.=0A= */=0A= =0A= void=0A= handle_exception (int exceptionVector)=0A= {=0A= int sigval, stepping;=0A= int addr, length, i;=0A= unsigned char *ptr;=0A= unsigned char buf[16];=0A= int binary;=0A= =0A= if (!finish_from_step ())=0A= return; /* "false step": let the target continue */=0A= =0A= gdb_m32r_vector =3D exceptionVector;=0A= =0A= if (remote_debug)=0A= {=0A= mem2hex ((unsigned char *) &exceptionVector, buf, 4, 0);=0A= gdb_error ("Handle exception %s, ", buf);=0A= mem2hex ((unsigned char *) ®isters[PC], buf, 4, 0);=0A= gdb_error ("PC =3D=3D 0x%s\n", buf);=0A= }=0A= =0A= /* reply to host that an exception has occurred */=0A= sigval =3D computeSignal (exceptionVector);=0A= =0A= ptr =3D remcomOutBuffer;=0A= =0A= *ptr++ =3D 'T'; /* notify gdb with signo, PC, FP and SP */=0A= *ptr++ =3D hexchars[sigval >> 4];=0A= *ptr++ =3D hexchars[sigval & 0xf];=0A= =0A= *ptr++ =3D hexchars[PC >> 4];=0A= *ptr++ =3D hexchars[PC & 0xf];=0A= *ptr++ =3D ':';=0A= ptr =3D mem2hex ((unsigned char *) ®isters[PC], ptr, 4, 0); /* PC */= =0A= *ptr++ =3D ';';=0A= =0A= *ptr++ =3D hexchars[R13 >> 4];=0A= *ptr++ =3D hexchars[R13 & 0xf];=0A= *ptr++ =3D ':';=0A= ptr =3D mem2hex ((unsigned char *) ®isters[R13], ptr, 4, 0); /* FP */= =0A= *ptr++ =3D ';';=0A= =0A= *ptr++ =3D hexchars[R15 >> 4];=0A= *ptr++ =3D hexchars[R15 & 0xf];=0A= *ptr++ =3D ':';=0A= ptr =3D mem2hex ((unsigned char *) ®isters[R15], ptr, 4, 0); /* SP */= =0A= *ptr++ =3D ';';=0A= *ptr++ =3D 0;=0A= =0A= if (exceptionVector =3D=3D 0) /* simulated SYS call stuff */=0A= {=0A= mem2hex ((unsigned char *) ®isters[PC], buf, 4, 0);=0A= switch (registers[R0])=0A= {=0A= case SYS_exit:=0A= gdb_error ("Target program has exited at %s\n", buf);=0A= ptr =3D remcomOutBuffer;=0A= *ptr++ =3D 'W';=0A= sigval =3D registers[R1] & 0xff;=0A= *ptr++ =3D hexchars[sigval >> 4];=0A= *ptr++ =3D hexchars[sigval & 0xf];=0A= *ptr++ =3D 0;=0A= break;=0A= case SYS_open:=0A= gdb_error ("Target attempts SYS_open call at %s\n", buf);=0A= break;=0A= case SYS_close:=0A= gdb_error ("Target attempts SYS_close call at %s\n", buf);=0A= break;=0A= case SYS_read:=0A= gdb_error ("Target attempts SYS_read call at %s\n", buf);=0A= break;=0A= case SYS_write:=0A= if (registers[R1] =3D=3D 1 || /* write to stdout */=0A= registers[R1] =3D=3D 2) /* write to stderr */=0A= { /* (we can do that) */=0A= registers[R0] =3D=0A= gdb_write ((void *) registers[R2], registers[R3]);=0A= return;=0A= }=0A= else=0A= gdb_error ("Target attempts SYS_write call at %s\n", buf);=0A= break;=0A= case SYS_lseek:=0A= gdb_error ("Target attempts SYS_lseek call at %s\n", buf);=0A= break;=0A= case SYS_unlink:=0A= gdb_error ("Target attempts SYS_unlink call at %s\n", buf);=0A= break;=0A= case SYS_getpid:=0A= gdb_error ("Target attempts SYS_getpid call at %s\n", buf);=0A= break;=0A= case SYS_kill:=0A= gdb_error ("Target attempts SYS_kill call at %s\n", buf);=0A= break;=0A= case SYS_fstat:=0A= gdb_error ("Target attempts SYS_fstat call at %s\n", buf);=0A= break;=0A= default:=0A= gdb_error ("Target attempts unknown SYS call at %s\n", buf);=0A= break;=0A= }=0A= }=0A= =0A= putpacket (remcomOutBuffer);=0A= =0A= stepping =3D 0;=0A= =0A= while (1 =3D=3D 1)=0A= {=0A= remcomOutBuffer[0] =3D 0;=0A= ptr =3D getpacket ();=0A= binary =3D 0;=0A= switch (*ptr++)=0A= {=0A= default: /* Unknown code. Return an empty reply message. */=0A= break;=0A= case 'R':=0A= if (hexToInt (&ptr, &addr))=0A= registers[PC] =3D addr;=0A= strcpy (remcomOutBuffer, "OK");=0A= break;=0A= case '!':=0A= strcpy (remcomOutBuffer, "OK");=0A= break;=0A= case 'X': /* XAA..AA,LLLL:#cs */=0A= binary =3D 1;=0A= case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */= =0A= /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR =3D 0 */=0A= {=0A= if (hexToInt (&ptr, &addr))=0A= if (*(ptr++) =3D=3D ',')=0A= if (hexToInt (&ptr, &length))=0A= if (*(ptr++) =3D=3D ':')=0A= {=0A= mem_err =3D 0;=0A= if (binary)=0A= bin2mem (ptr, (unsigned char *) addr, length, 1);=0A= else=0A= hex2mem (ptr, (unsigned char *) addr, length, 1);=0A= if (mem_err)=0A= {=0A= strcpy (remcomOutBuffer, "E03");=0A= gdb_error ("memory fault", "");=0A= }=0A= else=0A= {=0A= strcpy (remcomOutBuffer, "OK");=0A= }=0A= ptr =3D 0;=0A= }=0A= if (ptr)=0A= {=0A= strcpy (remcomOutBuffer, "E02");=0A= }=0A= }=0A= break;=0A= case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */=0A= /* TRY TO READ %x,%x. IF SUCCEED, SET PTR =3D 0 */=0A= if (hexToInt (&ptr, &addr))=0A= if (*(ptr++) =3D=3D ',')=0A= if (hexToInt (&ptr, &length))=0A= {=0A= ptr =3D 0;=0A= mem_err =3D 0;=0A= mem2hex ((unsigned char *) addr, remcomOutBuffer, length,=0A= 1);=0A= if (mem_err)=0A= {=0A= strcpy (remcomOutBuffer, "E03");=0A= gdb_error ("memory fault", "");=0A= }=0A= }=0A= if (ptr)=0A= {=0A= strcpy (remcomOutBuffer, "E01");=0A= }=0A= break;=0A= case '?':=0A= remcomOutBuffer[0] =3D 'S';=0A= remcomOutBuffer[1] =3D hexchars[sigval >> 4];=0A= remcomOutBuffer[2] =3D hexchars[sigval % 16];=0A= remcomOutBuffer[3] =3D 0;=0A= break;=0A= case 'd':=0A= remote_debug =3D !(remote_debug); /* toggle debug flag */=0A= break;=0A= case 'g': /* return the value of the CPU registers */=0A= mem2hex ((unsigned char *) registers, remcomOutBuffer, NUMREGBYTES,=0A= 0);=0A= break;=0A= case 'P': /* set the value of a single CPU register - return OK */=0A= {=0A= int regno;=0A= =0A= if (hexToInt (&ptr, ®no) && *ptr++ =3D=3D '=3D')=0A= if (regno >=3D 0 && regno < NUMREGS)=0A= {=0A= int stackmode;=0A= =0A= hex2mem (ptr, (unsigned char *) ®isters[regno], 4, 0);=0A= /*=0A= * Since we just changed a single CPU register, let's=0A= * make sure to keep the several stack pointers consistant.=0A= */=0A= stackmode =3D registers[PSW] & 0x80;=0A= if (regno =3D=3D R15) /* stack pointer changed */=0A= { /* need to change SPI or SPU */=0A= if (stackmode =3D=3D 0)=0A= registers[SPI] =3D registers[R15];=0A= else=0A= registers[SPU] =3D registers[R15];=0A= }=0A= else if (regno =3D=3D SPU) /* "user" stack pointer changed */=0A= {=0A= if (stackmode !=3D 0) /* stack in user mode: copy SP */=0A= registers[R15] =3D registers[SPU];=0A= }=0A= else if (regno =3D=3D SPI) /* "interrupt" stack pointer changed */=0A= {=0A= if (stackmode =3D=3D 0) /* stack in interrupt mode: copy SP */=0A= registers[R15] =3D registers[SPI];=0A= }=0A= else if (regno =3D=3D PSW) /* stack mode may have changed! */=0A= { /* force SP to either SPU or SPI */=0A= if (stackmode =3D=3D 0) /* stack in user mode */=0A= registers[R15] =3D registers[SPI];=0A= else /* stack in interrupt mode */=0A= registers[R15] =3D registers[SPU];=0A= }=0A= strcpy (remcomOutBuffer, "OK");=0A= break;=0A= }=0A= strcpy (remcomOutBuffer, "E01");=0A= break;=0A= }=0A= case 'G': /* set the value of the CPU registers - return OK */=0A= hex2mem (ptr, (unsigned char *) registers, NUMREGBYTES, 0);=0A= strcpy (remcomOutBuffer, "OK");=0A= break;=0A= case 's': /* sAA..AA Step one instruction from AA..AA(optional) */= =0A= stepping =3D 1;=0A= case 'c': /* cAA..AA Continue from address AA..AA(optional) */=0A= /* try to read optional parameter, pc unchanged if no parm */=0A= if (hexToInt (&ptr, &addr))=0A= registers[PC] =3D addr;=0A= =0A= if (stepping) /* single-stepping */=0A= {=0A= if (!prepare_to_step (0)) /* set up for single-step */=0A= {=0A= /* prepare_to_step has already emulated the target insn:=0A= Send SIGTRAP to gdb, don't resume the target at all. */=0A= ptr =3D remcomOutBuffer;=0A= *ptr++ =3D 'T'; /* Simulate stopping with SIGTRAP */=0A= *ptr++ =3D '0';=0A= *ptr++ =3D '5';=0A= =0A= *ptr++ =3D hexchars[PC >> 4]; /* send PC */=0A= *ptr++ =3D hexchars[PC & 0xf];=0A= *ptr++ =3D ':';=0A= ptr =3D mem2hex ((unsigned char *) ®isters[PC], ptr, 4, 0);=0A= *ptr++ =3D ';';=0A= =0A= *ptr++ =3D hexchars[R13 >> 4]; /* send FP */=0A= *ptr++ =3D hexchars[R13 & 0xf];=0A= *ptr++ =3D ':';=0A= ptr =3D=0A= mem2hex ((unsigned char *) ®isters[R13], ptr, 4, 0);=0A= *ptr++ =3D ';';=0A= =0A= *ptr++ =3D hexchars[R15 >> 4]; /* send SP */=0A= *ptr++ =3D hexchars[R15 & 0xf];=0A= *ptr++ =3D ':';=0A= ptr =3D=0A= mem2hex ((unsigned char *) ®isters[R15], ptr, 4, 0);=0A= *ptr++ =3D ';';=0A= *ptr++ =3D 0;=0A= =0A= break;=0A= }=0A= }=0A= else /* continuing, not single-stepping */=0A= {=0A= /* OK, about to do a "continue". First check to see if the=20=0A= target pc is on an odd boundary (second instruction in the=20=0A= word). If so, we must do a single-step first, because=20=0A= ya can't jump or return back to an odd boundary! */=0A= if ((registers[PC] & 2) !=3D 0)=0A= prepare_to_step (1);=0A= }=0A= =0A= return;=0A= =0A= case 'D': /* Detach */=0A= #if 0=0A= /* I am interpreting this to mean, release the board from control=20=0A= by the remote stub. To do this, I am restoring the original=0A= (or at least previous) exception vectors.=0A= */=0A= for (i =3D 0; i < 18; i++)=0A= exceptionHandler (i, save_vectors[i]);=0A= putpacket ("OK");=0A= return; /* continue the inferior */=0A= #else=0A= strcpy (remcomOutBuffer, "OK");=0A= break;=0A= #endif=0A= case 'q':=0A= if (*ptr++ =3D=3D 'C' &&=0A= *ptr++ =3D=3D 'R' && *ptr++ =3D=3D 'C' && *ptr++ =3D=3D ':')=0A= {=0A= unsigned long start, len, our_crc;=0A= =0A= if (hexToInt (&ptr, (int *) &start) &&=0A= *ptr++ =3D=3D ',' && hexToInt (&ptr, (int *) &len))=0A= {=0A= remcomOutBuffer[0] =3D 'C';=0A= our_crc =3D crc32 ((unsigned char *) start, len, 0xffffffff);=0A= mem2hex ((char *) &our_crc,=0A= &remcomOutBuffer[1], sizeof (long), 0);=0A= } /* else do nothing */=0A= } /* else do nothing */=0A= break;=0A= =0A= case 'k': /* kill the program */=0A= continue;=0A= } /* switch */=0A= =0A= /* reply to the request */=0A= putpacket (remcomOutBuffer);=0A= }=0A= }=0A= =0A= /* qCRC support */=0A= =0A= /* Table used by the crc32 function to calcuate the checksum. */=0A= static unsigned long crc32_table[256] =3D { 0, 0 };=0A= =0A= static unsigned long=0A= crc32 (unsigned char *buf, int len, unsigned long crc)=0A= {=0A= if (!crc32_table[1])=0A= {=0A= /* Initialize the CRC table and the decoding table. */=0A= int i, j;=0A= unsigned long c;=0A= =0A= for (i =3D 0; i < 256; i++)=0A= {=0A= for (c =3D i << 24, j =3D 8; j > 0; --j)=0A= c =3D c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);=0A= crc32_table[i] =3D c;=0A= }=0A= }=0A= =0A= while (len--)=0A= {=0A= crc =3D (crc << 8) ^ crc32_table[((crc >> 24) ^ *buf) & 255];=0A= buf++;=0A= }=0A= return crc;=0A= }=0A= =0A= static int=0A= hex (unsigned char ch)=0A= {=0A= if ((ch >=3D 'a') && (ch <=3D 'f'))=0A= return (ch - 'a' + 10);=0A= if ((ch >=3D '0') && (ch <=3D '9'))=0A= return (ch - '0');=0A= if ((ch >=3D 'A') && (ch <=3D 'F'))=0A= return (ch - 'A' + 10);=0A= return (-1);=0A= }=0A= =0A= /* scan for the sequence $# */=0A= =0A= unsigned char *=0A= getpacket (void)=0A= {=0A= unsigned char *buffer =3D &remcomInBuffer[0];=0A= unsigned char checksum;=0A= unsigned char xmitcsum;=0A= int count;=0A= char ch;=0A= =0A= while (1)=0A= {=0A= /* wait around for the start character, ignore all other characters *= /=0A= while ((ch =3D getDebugChar ()) !=3D '$')=0A= ;=0A= =0A= retry:=0A= checksum =3D 0;=0A= xmitcsum =3D -1;=0A= count =3D 0;=0A= =0A= /* now, read until a # or end of buffer is found */=0A= while (count < BUFMAX)=0A= {=0A= ch =3D getDebugChar ();=0A= if (ch =3D=3D '$')=0A= goto retry;=0A= if (ch =3D=3D '#')=0A= break;=0A= checksum =3D checksum + ch;=0A= buffer[count] =3D ch;=0A= count =3D count + 1;=0A= }=0A= buffer[count] =3D 0;=0A= =0A= if (ch =3D=3D '#')=0A= {=0A= ch =3D getDebugChar ();=0A= xmitcsum =3D hex (ch) << 4;=0A= ch =3D getDebugChar ();=0A= xmitcsum +=3D hex (ch);=0A= =0A= if (checksum !=3D xmitcsum)=0A= {=0A= if (remote_debug)=0A= {=0A= unsigned char buf[16];=0A= =0A= mem2hex ((unsigned char *) &checksum, buf, 4, 0);=0A= gdb_error ("Bad checksum: my count =3D %s, ", buf);=0A= mem2hex ((unsigned char *) &xmitcsum, buf, 4, 0);=0A= gdb_error ("sent count =3D %s\n", buf);=0A= gdb_error (" -- Bad buffer: \"%s\"\n", buffer);=0A= }=0A= putDebugChar ('-'); /* failed checksum */=0A= }=0A= else=0A= {=0A= putDebugChar ('+'); /* successful transfer */=0A= =0A= /* if a sequence char is present, reply the sequence ID */=0A= if (buffer[2] =3D=3D ':')=0A= {=0A= putDebugChar (buffer[0]);=0A= putDebugChar (buffer[1]);=0A= =0A= return &buffer[3];=0A= }=0A= =0A= return &buffer[0];=0A= }=0A= }=0A= }=0A= }=0A= =0A= /* send the packet in buffer. */=0A= =0A= static void=0A= putpacket (unsigned char *buffer)=0A= {=0A= unsigned char checksum;=0A= int count;=0A= char ch;=0A= =0A= /* $#. */=0A= do=0A= {=0A= putDebugChar ('$');=0A= checksum =3D 0;=0A= count =3D 0;=0A= =0A= while (ch =3D buffer[count])=0A= {=0A= putDebugChar (ch);=0A= checksum +=3D ch;=0A= count +=3D 1;=0A= }=0A= putDebugChar ('#');=0A= putDebugChar (hexchars[checksum >> 4]);=0A= putDebugChar (hexchars[checksum % 16]);=0A= }=0A= while (getDebugChar () !=3D '+');=0A= }=0A= =0A= /* Address of a routine to RTE to if we get a memory fault. */=0A= =0A= static void (*volatile mem_fault_routine) () =3D 0;=0A= =0A= static void=0A= set_mem_err (void)=0A= {=0A= mem_err =3D 1;=0A= }=0A= =0A= /* Check the address for safe access ranges. As currently defined,=0A= this routine will reject the "expansion bus" address range(s).=0A= To make those ranges useable, someone must implement code to detect=0A= whether there's anything connected to the expansion bus. */=0A= =0A= static int=0A= mem_safe (unsigned char *addr)=0A= {=0A= #define BAD_RANGE_ONE_START ((unsigned char *) 0x600000)=0A= #define BAD_RANGE_ONE_END ((unsigned char *) 0xa00000)=0A= #define BAD_RANGE_TWO_START ((unsigned char *) 0xff680000)=0A= #define BAD_RANGE_TWO_END ((unsigned char *) 0xff800000)=0A= =0A= if (addr < BAD_RANGE_ONE_START)=0A= return 1; /* safe */=0A= if (addr < BAD_RANGE_ONE_END)=0A= return 0; /* unsafe */=0A= if (addr < BAD_RANGE_TWO_START)=0A= return 1; /* safe */=0A= if (addr < BAD_RANGE_TWO_END)=0A= return 0; /* unsafe */=0A= }=0A= =0A= /* These are separate functions so that they are so short and sweet=0A= that the compiler won't save any registers (if there is a fault=0A= to mem_fault, they won't get restored, so there better not be any=0A= saved). */=0A= static int=0A= get_char (unsigned char *addr)=0A= {=0A= #if 1=0A= if (mem_fault_routine && !mem_safe (addr))=0A= {=0A= mem_fault_routine ();=0A= return 0;=0A= }=0A= #endif=0A= return *addr;=0A= }=0A= =0A= static void=0A= set_char (unsigned char *addr, unsigned char val)=0A= {=0A= #if 1=0A= if (mem_fault_routine && !mem_safe (addr))=0A= {=0A= mem_fault_routine ();=0A= return;=0A= }=0A= #endif=0A= *addr =3D val;=0A= }=0A= =0A= /* Convert the memory pointed to by mem into hex, placing result in buf.=0A= Return a pointer to the last char put in buf (null).=0A= If MAY_FAULT is non-zero, then we should set mem_err in response to=0A= a fault; if zero treat a fault like any other fault in the stub. */=0A= =0A= static unsigned char *=0A= mem2hex (unsigned char *mem, unsigned char *buf, int count, int may_fault)= =0A= {=0A= int i;=0A= unsigned char ch;=0A= =0A= if (may_fault)=0A= mem_fault_routine =3D set_mem_err;=0A= for (i =3D 0; i < count; i++)=0A= {=0A= ch =3D get_char (mem++);=0A= if (may_fault && mem_err)=0A= return (buf);=0A= *buf++ =3D hexchars[ch >> 4];=0A= *buf++ =3D hexchars[ch % 16];=0A= }=0A= *buf =3D 0;=0A= if (may_fault)=0A= mem_fault_routine =3D 0;=0A= return (buf);=0A= }=0A= =0A= /* Convert the hex array pointed to by buf into binary to be placed in mem.= =0A= Return a pointer to the character AFTER the last byte written. */=0A= =0A= static unsigned char *=0A= hex2mem (unsigned char *buf, unsigned char *mem, int count, int may_fault)= =0A= {=0A= int i;=0A= unsigned char ch;=0A= =0A= if (may_fault)=0A= mem_fault_routine =3D set_mem_err;=0A= for (i =3D 0; i < count; i++)=0A= {=0A= ch =3D hex (*buf++) << 4;=0A= ch =3D ch + hex (*buf++);=0A= set_char (mem++, ch);=0A= if (may_fault && mem_err)=0A= return (mem);=0A= }=0A= if (may_fault)=0A= mem_fault_routine =3D 0;=0A= return (mem);=0A= }=0A= =0A= /* Convert the binary stream in BUF to memory.=0A= =0A= Gdb will escape $, #, and the escape char (0x7d).=0A= COUNT is the total number of bytes to write into=0A= memory. */=0A= static unsigned char *=0A= bin2mem (unsigned char *buf, unsigned char *mem, int count, int may_fault)= =0A= {=0A= int i;=0A= unsigned char ch;=0A= =0A= if (may_fault)=0A= mem_fault_routine =3D set_mem_err;=0A= for (i =3D 0; i < count; i++)=0A= {=0A= /* Check for any escaped characters. Be paranoid and=0A= only unescape chars that should be escaped. */=0A= if (*buf =3D=3D 0x7d)=0A= {=0A= switch (*(buf + 1))=0A= {=0A= case 0x3: /* # */=0A= case 0x4: /* $ */=0A= case 0x5d: /* escape char */=0A= buf++;=0A= *buf |=3D 0x20;=0A= break;=0A= default:=0A= /* nothing */=0A= break;=0A= }=0A= }=0A= =0A= set_char (mem++, *buf++);=0A= =0A= if (may_fault && mem_err)=0A= return mem;=0A= }=0A= =0A= if (may_fault)=0A= mem_fault_routine =3D 0;=0A= return mem;=0A= }=0A= =0A= /* this function takes the m32r exception vector and attempts to=0A= translate this number into a unix compatible signal value */=0A= =0A= static int=0A= computeSignal (int exceptionVector)=0A= {=0A= int sigval;=0A= switch (exceptionVector)=0A= {=0A= case 0:=0A= sigval =3D 23;=0A= break; /* I/O trap */=0A= case 1:=0A= sigval =3D 5;=0A= break; /* breakpoint */=0A= case 2:=0A= sigval =3D 5;=0A= break; /* breakpoint */=0A= case 3:=0A= sigval =3D 5;=0A= break; /* breakpoint */=0A= case 4:=0A= sigval =3D 5;=0A= break; /* breakpoint */=0A= case 5:=0A= sigval =3D 5;=0A= break; /* breakpoint */=0A= case 6:=0A= sigval =3D 5;=0A= break; /* breakpoint */=0A= case 7:=0A= sigval =3D 5;=0A= break; /* breakpoint */=0A= case 8:=0A= sigval =3D 5;=0A= break; /* breakpoint */=0A= case 9:=0A= sigval =3D 5;=0A= break; /* breakpoint */=0A= case 10:=0A= sigval =3D 5;=0A= break; /* breakpoint */=0A= case 11:=0A= sigval =3D 5;=0A= break; /* breakpoint */=0A= case 12:=0A= sigval =3D 5;=0A= break; /* breakpoint */=0A= case 13:=0A= sigval =3D 5;=0A= break; /* breakpoint */=0A= case 14:=0A= sigval =3D 5;=0A= break; /* breakpoint */=0A= case 15:=0A= sigval =3D 5;=0A= break; /* breakpoint */=0A= case 16:=0A= sigval =3D 10;=0A= break; /* BUS ERROR (alignment) */=0A= case 17:=0A= sigval =3D 2;=0A= break; /* INTerrupt */=0A= default:=0A= sigval =3D 7;=0A= break; /* "software generated" */=0A= }=0A= return (sigval);=0A= }=0A= =0A= /**********************************************/=0A= /* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */=0A= /* RETURN NUMBER OF CHARS PROCESSED */=0A= /**********************************************/=0A= static int=0A= hexToInt (unsigned char **ptr, int *intValue)=0A= {=0A= int numChars =3D 0;=0A= int hexValue;=0A= =0A= *intValue =3D 0;=0A= while (**ptr)=0A= {=0A= hexValue =3D hex (**ptr);=0A= if (hexValue >=3D 0)=0A= {=0A= *intValue =3D (*intValue << 4) | hexValue;=0A= numChars++;=0A= }=0A= else=0A= break;=0A= (*ptr)++;=0A= }=0A= return (numChars);=0A= }=0A= =0A= /*=0A= Table of branch instructions:=0A= =20=20=0A= 10B6 RTE return from trap or exception=0A= 1FCr JMP jump=0A= 1ECr JL jump and link=0A= 7Fxx BRA branch=0A= FFxxxxxx BRA branch (long)=0A= B09rxxxx BNEZ branch not-equal-zero=0A= Br1rxxxx BNE branch not-equal=0A= 7Dxx BNC branch not-condition=0A= FDxxxxxx BNC branch not-condition (long)=0A= B0Arxxxx BLTZ branch less-than-zero=0A= B0Crxxxx BLEZ branch less-equal-zero=0A= 7Exx BL branch and link=0A= FExxxxxx BL branch and link (long)=0A= B0Drxxxx BGTZ branch greater-than-zero=0A= B0Brxxxx BGEZ branch greater-equal-zero=0A= B08rxxxx BEQZ branch equal-zero=0A= Br0rxxxx BEQ branch equal=0A= 7Cxx BC branch condition=0A= FCxxxxxx BC branch condition (long)=0A= */=0A= =0A= static int=0A= isShortBranch (unsigned char *instr)=0A= {=0A= unsigned char instr0 =3D instr[0] & 0x7F; /* mask off high bit */=0A= =0A= if (instr0 =3D=3D 0x10 && instr[1] =3D=3D 0xB6) /* RTE */=0A= return 1; /* return from trap or exception */=0A= =0A= if (instr0 =3D=3D 0x1E || instr0 =3D=3D 0x1F) /* JL or JMP */=0A= if ((instr[1] & 0xF0) =3D=3D 0xC0)=0A= return 2; /* jump thru a register */=0A= =0A= if (instr0 =3D=3D 0x7C || instr0 =3D=3D 0x7D || /* BC, BNC, BL, BRA */=0A= instr0 =3D=3D 0x7E || instr0 =3D=3D 0x7F)=0A= return 3; /* eight bit PC offset */=0A= =0A= return 0;=0A= }=0A= =0A= static int=0A= isLongBranch (unsigned char *instr)=0A= {=0A= if (instr[0] =3D=3D 0xFC || instr[0] =3D=3D 0xFD || /* BRA, BNC, BL, BC *= /=0A= instr[0] =3D=3D 0xFE || instr[0] =3D=3D 0xFF) /* 24 bit relative */= =0A= return 4;=0A= if ((instr[0] & 0xF0) =3D=3D 0xB0) /* 16 bit relative */=0A= {=0A= if ((instr[1] & 0xF0) =3D=3D 0x00 || /* BNE, BEQ */=0A= (instr[1] & 0xF0) =3D=3D 0x10)=0A= return 5;=0A= if (instr[0] =3D=3D 0xB0) /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ, BEQZ */=0A= if ((instr[1] & 0xF0) =3D=3D 0x80 || (instr[1] & 0xF0) =3D=3D 0x90 ||=0A= (instr[1] & 0xF0) =3D=3D 0xA0 || (instr[1] & 0xF0) =3D=3D 0xB0 ||=0A= (instr[1] & 0xF0) =3D=3D 0xC0 || (instr[1] & 0xF0) =3D=3D 0xD0)=0A= return 6;=0A= }=0A= return 0;=0A= }=0A= =0A= /* if address is NOT on a 4-byte boundary, or high-bit of instr is zero,=20= =0A= then it's a 2-byte instruction, else it's a 4-byte instruction. */=0A= =0A= #define INSTRUCTION_SIZE(addr) \=0A= ((((int) addr & 2) || (((unsigned char *) addr)[0] & 0x80) =3D=3D 0) ? = 2 : 4)=0A= =0A= static int=0A= isBranch (unsigned char *instr)=0A= {=0A= if (INSTRUCTION_SIZE (instr) =3D=3D 2)=0A= return isShortBranch (instr);=0A= else=0A= return isLongBranch (instr);=0A= }=0A= =0A= static int=0A= willBranch (unsigned char *instr, int branchCode)=0A= {=0A= switch (branchCode)=0A= {=0A= case 0:=0A= return 0; /* not a branch */=0A= case 1:=0A= return 1; /* RTE */=0A= case 2:=0A= return 1; /* JL or JMP */=0A= case 3: /* BC, BNC, BL, BRA (short) */=0A= case 4: /* BC, BNC, BL, BRA (long) */=0A= switch (instr[0] & 0x0F)=0A= {=0A= case 0xC: /* Branch if Condition Register */=0A= return (registers[CBR] !=3D 0);=0A= case 0xD: /* Branch if NOT Condition Register */=0A= return (registers[CBR] =3D=3D 0);=0A= case 0xE: /* Branch and Link */=0A= case 0xF: /* Branch (unconditional) */=0A= return 1;=0A= default: /* oops? */=0A= return 0;=0A= }=0A= case 5: /* BNE, BEQ */=0A= switch (instr[1] & 0xF0)=0A= {=0A= case 0x00: /* Branch if r1 equal to r2 */=0A= return (registers[instr[0] & 0x0F] =3D=3D registers[instr[1] & 0x0F]);= =0A= case 0x10: /* Branch if r1 NOT equal to r2 */=0A= return (registers[instr[0] & 0x0F] !=3D registers[instr[1] & 0x0F]);=0A= default: /* oops? */=0A= return 0;=0A= }=0A= case 6: /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ ,BEQZ */=0A= switch (instr[1] & 0xF0)=0A= {=0A= case 0x80: /* Branch if reg equal to zero */=0A= return (registers[instr[1] & 0x0F] =3D=3D 0);=0A= case 0x90: /* Branch if reg NOT equal to zero */=0A= return (registers[instr[1] & 0x0F] !=3D 0);=0A= case 0xA0: /* Branch if reg less than zero */=0A= return (registers[instr[1] & 0x0F] < 0);=0A= case 0xB0: /* Branch if reg greater or equal to zero */=0A= return (registers[instr[1] & 0x0F] >=3D 0);=0A= case 0xC0: /* Branch if reg less than or equal to zero */=0A= return (registers[instr[1] & 0x0F] <=3D 0);=0A= case 0xD0: /* Branch if reg greater than zero */=0A= return (registers[instr[1] & 0x0F] > 0);=0A= default: /* oops? */=0A= return 0;=0A= }=0A= default: /* oops? */=0A= return 0;=0A= }=0A= }=0A= =0A= static int=0A= branchDestination (unsigned char *instr, int branchCode)=0A= {=0A= switch (branchCode)=0A= {=0A= default:=0A= case 0: /* not a branch */=0A= return 0;=0A= case 1: /* RTE */=0A= return registers[BPC] & ~3; /* pop BPC into PC */=0A= case 2: /* JL or JMP */=0A= return registers[instr[1] & 0x0F] & ~3; /* jump thru a register */=0A= case 3: /* BC, BNC, BL, BRA (short, 8-bit relative offset) */=0A= return (((int) instr) & ~3) + ((char) instr[1] << 2);=0A= case 4: /* BC, BNC, BL, BRA (long, 24-bit relative offset) */=0A= return ((int) instr +=0A= ((((char) instr[1] << 16) | (instr[2] << 8) | (instr[3])) <<=0A= 2));=0A= case 5: /* BNE, BEQ (16-bit relative offset) */=0A= case 6: /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ ,BEQZ (ditto) */=0A= return ((int) instr + ((((char) instr[2] << 8) | (instr[3])) << 2));= =0A= }=0A= =0A= /* An explanatory note: in the last three return expressions, I have=0A= cast the most-significant byte of the return offset to char.=0A= What this accomplishes is sign extension. If the other=0A= less-significant bytes were signed as well, they would get sign=0A= extended too and, if negative, their leading bits would clobber=0A= the bits of the more-significant bytes ahead of them. There are=0A= other ways I could have done this, but sign extension from=0A= odd-sized integers is always a pain. */=0A= }=0A= =0A= static void=0A= branchSideEffects (unsigned char *instr, int branchCode)=0A= {=0A= switch (branchCode)=0A= {=0A= case 1: /* RTE */=0A= return; /* I this is already handled... */=0A= case 2: /* JL (or JMP) */=0A= case 3: /* BL (or BC, BNC, BRA) */=0A= case 4:=0A= if ((instr[0] & 0x0F) =3D=3D 0x0E) /* branch/jump and link */=0A= registers[R14] =3D (registers[PC] & ~3) + 4;=0A= return;=0A= default: /* any other branch has no side effects */=0A= return;=0A= }=0A= }=0A= =0A= static struct STEPPING_CONTEXT=0A= {=0A= int stepping; /* true when we've started a single-step */=0A= unsigned long target_addr; /* the instr we're trying to execute */=0A= unsigned long target_size; /* the size of the target instr */=0A= unsigned long noop_addr; /* where we've inserted a no-op, if any */=0A= unsigned long trap1_addr; /* the trap following the target instr */=0A= unsigned long trap2_addr; /* the trap at a branch destination, if any */= =0A= unsigned short noop_save; /* instruction overwritten by our no-op */=0A= unsigned short trap1_save; /* instruction overwritten by trap1 */=0A= unsigned short trap2_save; /* instruction overwritten by trap2 */=0A= unsigned short continue_p; /* true if NOT returning to gdb after step */= =0A= } stepping;=0A= =0A= /* Function: prepare_to_step=0A= Called from handle_exception to prepare the user program to single-step.= =0A= Places a trap instruction after the target instruction, with special=20= =0A= extra handling for branch instructions and for instructions in the=20=0A= second half-word of a word.=20=20=0A= =0A= Returns: True if we should actually execute the instruction;=20=0A= False if we are going to emulate executing the instruction,=0A= in which case we simply report to GDB that the instruction=20=0A= has already been executed. */=0A= =0A= #define TRAP1 0x10f1; /* trap #1 instruction */=0A= #define NOOP 0x7000; /* noop instruction */=0A= =0A= static unsigned short trap1 =3D TRAP1;=0A= static unsigned short noop =3D NOOP;=0A= =0A= static int=0A= prepare_to_step (continue_p)=0A= int continue_p; /* if this isn't REALLY a single-step (see below) */= =0A= {=0A= unsigned long pc =3D registers[PC];=0A= int branchCode =3D isBranch ((unsigned char *) pc);=0A= unsigned char *p;=0A= =0A= /* zero out the stepping context=20=0A= (paranoia -- it should already be zeroed) */=0A= for (p =3D (unsigned char *) &stepping;=0A= p < ((unsigned char *) &stepping) + sizeof (stepping); p++)=0A= *p =3D 0;=0A= =0A= if (branchCode !=3D 0) /* next instruction is a branch */=0A= {=0A= branchSideEffects ((unsigned char *) pc, branchCode);=0A= if (willBranch ((unsigned char *) pc, branchCode))=0A= registers[PC] =3D branchDestination ((unsigned char *) pc, branchCode);=0A= else=0A= registers[PC] =3D pc + INSTRUCTION_SIZE (pc);=0A= return 0; /* branch "executed" -- just notify GDB */=0A= }=0A= else if (((int) pc & 2) !=3D 0) /* "second-slot" instruction */=0A= {=0A= /* insert no-op before pc */=0A= stepping.noop_addr =3D pc - 2;=0A= stepping.noop_save =3D *(unsigned short *) stepping.noop_addr;=0A= *(unsigned short *) stepping.noop_addr =3D noop;=0A= /* insert trap after pc */=0A= stepping.trap1_addr =3D pc + 2;=0A= stepping.trap1_save =3D *(unsigned short *) stepping.trap1_addr;=0A= *(unsigned short *) stepping.trap1_addr =3D trap1;=0A= }=0A= else /* "first-slot" instruction */=0A= {=0A= /* insert trap after pc */=0A= stepping.trap1_addr =3D pc + INSTRUCTION_SIZE (pc);=0A= stepping.trap1_save =3D *(unsigned short *) stepping.trap1_addr;=0A= *(unsigned short *) stepping.trap1_addr =3D trap1;=0A= }=0A= /* "continue_p" means that we are actually doing a continue, and not=20= =0A= being requested to single-step by GDB. Sometimes we have to do=0A= one single-step before continuing, because the PC is on a half-word=0A= boundary. There's no way to simply resume at such an address. */=0A= stepping.continue_p =3D continue_p;=0A= stepping.stepping =3D 1; /* starting a single-step */=0A= return 1;=0A= }=0A= =0A= /* Function: finish_from_step=0A= Called from handle_exception to finish up when the user program=20=0A= returns from a single-step. Replaces the instructions that had=0A= been overwritten by traps or no-ops,=20=0A= =0A= Returns: True if we should notify GDB that the target stopped.=0A= False if we only single-stepped because we had to before we=0A= could continue (ie. we were trying to continue at a=20=0A= half-word boundary). In that case don't notify GDB:=0A= just "continue continuing". */=0A= =0A= static int=0A= finish_from_step (void)=0A= {=0A= if (stepping.stepping) /* anything to do? */=0A= {=0A= int continue_p =3D stepping.continue_p;=0A= unsigned char *p;=0A= =0A= if (stepping.noop_addr) /* replace instr "under" our no-op */=0A= *(unsigned short *) stepping.noop_addr =3D stepping.noop_save;=0A= if (stepping.trap1_addr) /* replace instr "under" our trap */=0A= *(unsigned short *) stepping.trap1_addr =3D stepping.trap1_save;=0A= if (stepping.trap2_addr) /* ditto our other trap, if any */=0A= *(unsigned short *) stepping.trap2_addr =3D stepping.trap2_save;=0A= =0A= for (p =3D (unsigned char *) &stepping; /* zero out the stepping cont= ext */=0A= p < ((unsigned char *) &stepping) + sizeof (stepping); p++)=0A= *p =3D 0;=0A= =0A= return !(continue_p);=0A= }=0A= else /* we didn't single-step, therefore this must be a legitimate sto= p */=0A= return 1;=0A= }=0A= =0A= struct PSWreg=0A= { /* separate out the bit flags in the PSW register */=0A= int pad1:16;=0A= int bsm:1;=0A= int bie:1;=0A= int pad2:5;=0A= int bc:1;=0A= int sm:1;=0A= int ie:1;=0A= int pad3:5;=0A= int c:1;=0A= } *psw;=0A= =0A= /* Upon entry the value for LR to save has been pushed.=0A= We unpush that so that the value for the stack pointer saved is correct.= =0A= Upon entry, all other registers are assumed to have not been modified=0A= since the interrupt/trap occured. */=0A= =0A= asm ("=0A= stash_registers:=0A= push r0=0A= push r1=0A= seth r1, #shigh(registers)=0A= add3 r1, r1, #low(registers)=0A= pop r0 ; r1=0A= st r0, @(4,r1)=0A= pop r0 ; r0=0A= st r0, @r1=0A= addi r1, #4 ; only add 4 as subsequent saves are `pre inc'=0A= st r2, @+r1=0A= st r3, @+r1=0A= st r4, @+r1=0A= st r5, @+r1=0A= st r6, @+r1=0A= st r7, @+r1=0A= st r8, @+r1=0A= st r9, @+r1=0A= st r10, @+r1=0A= st r11, @+r1=0A= st r12, @+r1=0A= st r13, @+r1 ; fp=0A= pop r0 ; lr (r14)=0A= st r0, @+r1=0A= st sp, @+r1 ; sp contains right value at this point=0A= mvfc r0, cr0=0A= st r0, @+r1 ; cr0 =3D=3D PSW=0A= mvfc r0, cr1=0A= st r0, @+r1 ; cr1 =3D=3D CBR=0A= mvfc r0, cr2=0A= st r0, @+r1 ; cr2 =3D=3D SPI=0A= mvfc r0, cr3=0A= st r0, @+r1 ; cr3 =3D=3D SPU=0A= mvfc r0, cr6=0A= st r0, @+r1 ; cr6 =3D=3D BPC=0A= st r0, @+r1 ; PC =3D=3D BPC=0A= mvfaclo r0=0A= st r0, @+r1 ; ACCL=0A= mvfachi r0=0A= st r0, @+r1 ; ACCH=0A= jmp lr");=0A= =0A= /* C routine to clean up what stash_registers did.=0A= It is called after calling stash_registers.=0A= This is separate from stash_registers as we want to do this in C=0A= but doing stash_registers in C isn't straightforward. */=0A= =0A= static void=0A= cleanup_stash (void)=0A= {=0A= psw =3D (struct PSWreg *) ®isters[PSW]; /* fields of PSW register */= =0A= psw->sm =3D psw->bsm; /* fix up pre-trap values of psw fields */=0A= psw->ie =3D psw->bie;=0A= psw->c =3D psw->bc;=0A= registers[CBR] =3D psw->bc; /* fix up pre-trap "C" register */=0A= =0A= #if 0 /* FIXME: Was in previous version. Necessary?=0A= (Remember that we use the "rte" insn to return from the=0A= trap/interrupt so the values of bsm, bie, bc are important. */=0A= psw->bsm =3D psw->bie =3D psw->bc =3D 0; /* zero post-trap values */=0A= #endif=0A= =0A= /* FIXME: Copied from previous version. This can probably be deleted=0A= since methinks stash_registers has already done this. */=0A= registers[PC] =3D registers[BPC]; /* pre-trap PC */=0A= =0A= /* FIXME: Copied from previous version. Necessary? */=0A= if (psw->sm) /* copy R15 into (psw->sm ? SPU : SPI) */=0A= registers[SPU] =3D registers[R15];=0A= else=0A= registers[SPI] =3D registers[R15];=0A= }=0A= =0A= asm ("=0A= restore_and_return:=0A= seth r0, #shigh(registers+8)=0A= add3 r0, r0, #low(registers+8)=0A= ld r2, @r0+ ; restore r2=0A= ld r3, @r0+ ; restore r3=0A= ld r4, @r0+ ; restore r4=0A= ld r5, @r0+ ; restore r5=0A= ld r6, @r0+ ; restore r6=0A= ld r7, @r0+ ; restore r7=0A= ld r8, @r0+ ; restore r8=0A= ld r9, @r0+ ; restore r9=0A= ld r10, @r0+ ; restore r10=0A= ld r11, @r0+ ; restore r11=0A= ld r12, @r0+ ; restore r12=0A= ld r13, @r0+ ; restore r13=0A= ld r14, @r0+ ; restore r14=0A= ld r15, @r0+ ; restore r15=0A= ld r1, @r0+ ; restore cr0 =3D=3D PSW=0A= mvtc r1, cr0=0A= ld r1, @r0+ ; restore cr1 =3D=3D CBR (no-op, because it's read only)=0A= mvtc r1, cr1=0A= ld r1, @r0+ ; restore cr2 =3D=3D SPI=0A= mvtc r1, cr2=0A= ld r1, @r0+ ; restore cr3 =3D=3D SPU=0A= mvtc r1, cr3=0A= addi r0, #4 ; skip BPC=0A= ld r1, @r0+ ; restore cr6 (BPC) =3D=3D PC=0A= mvtc r1, cr6=0A= ld r1, @r0+ ; restore ACCL=0A= mvtaclo r1=0A= ld r1, @r0+ ; restore ACCH=0A= mvtachi r1=0A= seth r0, #shigh(registers)=0A= add3 r0, r0, #low(registers)=0A= ld r1, @(4,r0) ; restore r1=0A= ld r0, @r0 ; restore r0=0A= rte");=0A= =0A= /* General trap handler, called after the registers have been stashed.=0A= NUM is the trap/exception number. */=0A= =0A= static void=0A= process_exception (int num)=0A= {=0A= cleanup_stash ();=0A= asm volatile ("=0A= seth r1, #shigh(stackPtr)=0A= add3 r1, r1, #low(stackPtr)=0A= ld r15, @r1 ; setup local stack (protect user stack)=0A= mv r0, %0=0A= bl handle_exception=0A= bl restore_and_return"::"r" (num):"r0", "r1");=0A= }=0A= =0A= void _catchException0 ();=0A= =0A= asm ("=0A= _catchException0:=0A= push lr=0A= bl stash_registers=0A= ; Note that at this point the pushed value of `lr' has been popped=0A= ldi r0, #0=0A= bl process_exception");=0A= =0A= void _catchException1 ();=0A= =0A= asm ("=0A= _catchException1:=0A= push lr=0A= bl stash_registers=0A= ; Note that at this point the pushed value of `lr' has been popped=0A= bl cleanup_stash=0A= seth r1, #shigh(stackPtr)=0A= add3 r1, r1, #low(stackPtr)=0A= ld r15, @r1 ; setup local stack (protect user stack)=0A= seth r1, #shigh(registers + 21*4) ; PC=0A= add3 r1, r1, #low(registers + 21*4)=0A= ld r0, @r1=0A= addi r0, #-4 ; back up PC for breakpoint trap.=0A= st r0, @r1 ; FIXME: what about bp in right slot?=0A= ldi r0, #1=0A= bl handle_exception=0A= bl restore_and_return");=0A= =0A= void _catchException2 ();=0A= =0A= asm ("=0A= _catchException2:=0A= push lr=0A= bl stash_registers=0A= ; Note that at this point the pushed value of `lr' has been popped=0A= ldi r0, #2=0A= bl process_exception");=0A= =0A= void _catchException3 ();=0A= =0A= asm ("=0A= _catchException3:=0A= push lr=0A= bl stash_registers=0A= ; Note that at this point the pushed value of `lr' has been popped=0A= ldi r0, #3=0A= bl process_exception");=0A= =0A= void _catchException4 ();=0A= =0A= asm ("=0A= _catchException4:=0A= push lr=0A= bl stash_registers=0A= ; Note that at this point the pushed value of `lr' has been popped=0A= ldi r0, #4=0A= bl process_exception");=0A= =0A= void _catchException5 ();=0A= =0A= asm ("=0A= _catchException5:=0A= push lr=0A= bl stash_registers=0A= ; Note that at this point the pushed value of `lr' has been popped=0A= ldi r0, #5=0A= bl process_exception");=0A= =0A= void _catchException6 ();=0A= =0A= asm ("=0A= _catchException6:=0A= push lr=0A= bl stash_registers=0A= ; Note that at this point the pushed value of `lr' has been popped=0A= ldi r0, #6=0A= bl process_exception");=0A= =0A= void _catchException7 ();=0A= =0A= asm ("=0A= _catchException7:=0A= push lr=0A= bl stash_registers=0A= ; Note that at this point the pushed value of `lr' has been popped=0A= ldi r0, #7=0A= bl process_exception");=0A= =0A= void _catchException8 ();=0A= =0A= asm ("=0A= _catchException8:=0A= push lr=0A= bl stash_registers=0A= ; Note that at this point the pushed value of `lr' has been popped=0A= ldi r0, #8=0A= bl process_exception");=0A= =0A= void _catchException9 ();=0A= =0A= asm ("=0A= _catchException9:=0A= push lr=0A= bl stash_registers=0A= ; Note that at this point the pushed value of `lr' has been popped=0A= ldi r0, #9=0A= bl process_exception");=0A= =0A= void _catchException10 ();=0A= =0A= asm ("=0A= _catchException10:=0A= push lr=0A= bl stash_registers=0A= ; Note that at this point the pushed value of `lr' has been popped=0A= ldi r0, #10=0A= bl process_exception");=0A= =0A= void _catchException11 ();=0A= =0A= asm ("=0A= _catchException11:=0A= push lr=0A= bl stash_registers=0A= ; Note that at this point the pushed value of `lr' has been popped=0A= ldi r0, #11=0A= bl process_exception");=0A= =0A= void _catchException12 ();=0A= =0A= asm ("=0A= _catchException12:=0A= push lr=0A= bl stash_registers=0A= ; Note that at this point the pushed value of `lr' has been popped=0A= ldi r0, #12=0A= bl process_exception");=0A= =0A= void _catchException13 ();=0A= =0A= asm ("=0A= _catchException13:=0A= push lr=0A= bl stash_registers=0A= ; Note that at this point the pushed value of `lr' has been popped=0A= ldi r0, #13=0A= bl process_exception");=0A= =0A= void _catchException14 ();=0A= =0A= asm ("=0A= _catchException14:=0A= push lr=0A= bl stash_registers=0A= ; Note that at this point the pushed value of `lr' has been popped=0A= ldi r0, #14=0A= bl process_exception");=0A= =0A= void _catchException15 ();=0A= =0A= asm ("=0A= _catchException15:=0A= push lr=0A= bl stash_registers=0A= ; Note that at this point the pushed value of `lr' has been popped=0A= ldi r0, #15=0A= bl process_exception");=0A= =0A= void _catchException16 ();=0A= =0A= asm ("=0A= _catchException16:=0A= push lr=0A= bl stash_registers=0A= ; Note that at this point the pushed value of `lr' has been popped=0A= ldi r0, #16=0A= bl process_exception");=0A= =0A= void _catchException17 ();=0A= =0A= asm ("=0A= _catchException17:=0A= push lr=0A= bl stash_registers=0A= ; Note that at this point the pushed value of `lr' has been popped=0A= ldi r0, #17=0A= bl process_exception");=0A= =0A= =0A= /* this function is used to set up exception handlers for tracing and=0A= breakpoints */=0A= void=0A= set_debug_traps (void)=0A= {=0A= /* extern void remcomHandler(); */=0A= int i;=0A= =0A= for (i =3D 0; i < 18; i++) /* keep a copy of old vectors */=0A= if (save_vectors[i] =3D=3D 0) /* only copy them the first time */=0A= save_vectors[i] =3D getExceptionHandler (i);=0A= =0A= stackPtr =3D &remcomStack[STACKSIZE / sizeof (int) - 1];=0A= =0A= exceptionHandler (0, _catchException0);=0A= exceptionHandler (1, _catchException1);=0A= exceptionHandler (2, _catchException2);=0A= exceptionHandler (3, _catchException3);=0A= exceptionHandler (4, _catchException4);=0A= exceptionHandler (5, _catchException5);=0A= exceptionHandler (6, _catchException6);=0A= exceptionHandler (7, _catchException7);=0A= exceptionHandler (8, _catchException8);=0A= exceptionHandler (9, _catchException9);=0A= exceptionHandler (10, _catchException10);=0A= exceptionHandler (11, _catchException11);=0A= exceptionHandler (12, _catchException12);=0A= exceptionHandler (13, _catchException13);=0A= exceptionHandler (14, _catchException14);=0A= exceptionHandler (15, _catchException15);=0A= exceptionHandler (16, _catchException16);=0A= /* exceptionHandler (17, _catchException17); */=0A= =0A= initialized =3D 1;=0A= }=0A= =0A= /* This function will generate a breakpoint exception. It is used at the= =0A= beginning of a program to sync up with a debugger and can be used=0A= otherwise as a quick means to stop program execution and "break" into=0A= the debugger. */=0A= =0A= #define BREAKPOINT() asm volatile (" trap #2");=0A= =0A= void=0A= breakpoint (void)=0A= {=0A= if (initialized)=0A= BREAKPOINT ();=0A= }=0A= =0A= /* STDOUT section:=0A= Stuff pertaining to simulating stdout by sending chars to gdb to be echo= ed.=0A= Functions: gdb_putchar(char ch)=0A= gdb_puts(char *str)=0A= gdb_write(char *str, int len)=0A= gdb_error(char *format, char *parm)=0A= */=0A= =0A= /* Function: gdb_putchar(int)=0A= Make gdb write a char to stdout.=0A= Returns: the char */=0A= =0A= static int=0A= gdb_putchar (int ch)=0A= {=0A= char buf[4];=0A= =0A= buf[0] =3D 'O';=0A= buf[1] =3D hexchars[ch >> 4];=0A= buf[2] =3D hexchars[ch & 0x0F];=0A= buf[3] =3D 0;=0A= putpacket (buf);=0A= return ch;=0A= }=0A= =0A= /* Function: gdb_write(char *, int)=0A= Make gdb write n bytes to stdout (not assumed to be null-terminated).=0A= Returns: number of bytes written */=0A= =0A= static int=0A= gdb_write (char *data, int len)=0A= {=0A= char *buf, *cpy;=0A= int i;=0A= =0A= buf =3D remcomOutBuffer;=0A= buf[0] =3D 'O';=0A= i =3D 0;=0A= while (i < len)=0A= {=0A= for (cpy =3D buf + 1;=0A= i < len && cpy < buf + sizeof (remcomOutBuffer) - 3; i++)=0A= {=0A= *cpy++ =3D hexchars[data[i] >> 4];=0A= *cpy++ =3D hexchars[data[i] & 0x0F];=0A= }=0A= *cpy =3D 0;=0A= putpacket (buf);=0A= }=0A= return len;=0A= }=0A= =0A= /* Function: gdb_puts(char *)=0A= Make gdb write a null-terminated string to stdout.=0A= Returns: the length of the string */=0A= =0A= static int=0A= gdb_puts (char *str)=0A= {=0A= return gdb_write (str, strlen (str));=0A= }=0A= =0A= /* Function: gdb_error(char *, char *)=0A= Send an error message to gdb's stdout.=0A= First string may have 1 (one) optional "%s" in it, which=0A= will cause the optional second string to be inserted. */=0A= =0A= static void=0A= gdb_error (char *format, char *parm)=0A= {=0A= char buf[400], *cpy;=0A= int len;=0A= =0A= if (remote_debug)=0A= {=0A= if (format && *format)=0A= len =3D strlen (format);=0A= else=0A= return; /* empty input */=0A= =0A= if (parm && *parm)=0A= len +=3D strlen (parm);=0A= =0A= for (cpy =3D buf; *format;)=0A= {=0A= if (format[0] =3D=3D '%' && format[1] =3D=3D 's') /* include second stri= ng */=0A= {=0A= format +=3D 2; /* advance two chars instead of just one */=0A= while (parm && *parm)=0A= *cpy++ =3D *parm++;=0A= }=0A= else=0A= *cpy++ =3D *format++;=0A= }=0A= *cpy =3D '\0';=0A= gdb_puts (buf);=0A= }=0A= }=0A= =0A= static unsigned char *=0A= strcpy (unsigned char *dest, const unsigned char *src)=0A= {=0A= unsigned char *ret =3D dest;=0A= =0A= if (dest && src)=0A= {=0A= while (*src)=0A= *dest++ =3D *src++;=0A= *dest =3D 0;=0A= }=0A= return ret;=0A= }=0A= =0A= static int=0A= strlen (const unsigned char *src)=0A= {=0A= int ret;=0A= =0A= for (ret =3D 0; *src; src++)=0A= ret++;=0A= =0A= return ret;=0A= }=0A= =0A= #if 0=0A= void=0A= exit (code)=0A= int code;=0A= {=0A= _exit (code);=0A= }=0A= =0A= int=0A= atexit (void *p)=0A= {=0A= return 0;=0A= }=0A= =0A= void=0A= abort (void)=0A= {=0A= _exit (1);=0A= }=0A= #endif=0A= ------=_NextPart_000_02E9_01C347C7.FDA9E620 Content-Type: application/octet-stream; name="m32r-rom.c" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="m32r-rom.c" Content-length: 24734 /* Remote debugging interface to m32r and mon2000 ROM monitors for GDB,=20= =0A= the GNU debugger.=0A= Copyright 1996, 1997, 1998, 1999, 2000, 2001=0A= Free Software Foundation, Inc.=0A= =0A= Adapted by Michael Snyder of Cygnus Support.=0A= =0A= This file is part of GDB.=0A= =0A= This program is free software; you can redistribute it and/or modify=0A= it under the terms of the GNU General Public License as published by=0A= the Free Software Foundation; either version 2 of the License, or=0A= (at your option) any later version.=0A= =0A= This program is distributed in the hope that it will be useful,=0A= but WITHOUT ANY WARRANTY; without even the implied warranty of=0A= MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the=0A= GNU General Public License for more details.=0A= =0A= You should have received a copy of the GNU General Public License=0A= along with this program; if not, write to the Free Software=0A= Foundation, Inc., 59 Temple Place - Suite 330,=0A= Boston, MA 02111-1307, USA. */=0A= =0A= /* This module defines communication with the Renesas m32r monitor */=0A= =0A= #include "defs.h"=0A= #include "gdbcore.h"=0A= #include "target.h"=0A= #include "monitor.h"=0A= #include "serial.h"=0A= #include "symtab.h"=0A= #include "command.h"=0A= #include "gdbcmd.h"=0A= #include "symfile.h" /* for generic load */=0A= #include /* for time_t */=0A= #include "gdb_string.h"=0A= #include "objfiles.h" /* for ALL_OBJFILES etc. */=0A= #include "inferior.h" /* for write_pc() */=0A= #include =0A= #include "regcache.h"=0A= =0A= extern void report_transfer_performance (unsigned long, time_t, time_t);=0A= =0A= /*=0A= * All this stuff just to get my host computer's IP address!=0A= */=0A= #include =0A= #include /* for hostent */=0A= #include /* for struct in_addr */=0A= #if 1=0A= #include /* for inet_ntoa */=0A= #endif=0A= =0A= static char *board_addr; /* user-settable IP address for M32R-EVA */=0A= static char *server_addr; /* user-settable IP address for gdb host */=0A= static char *download_path; /* user-settable path for SREC files */=0A= =0A= =0A= /* REGNUM */=0A= #define PSW_REGNUM 16=0A= #define SPI_REGNUM 18=0A= #define SPU_REGNUM 19=0A= #define ACCL_REGNUM 22=0A= #define ACCH_REGNUM 23=0A= =0A= =0A= /*=20=0A= * Function: m32r_load_1 (helper function)=0A= */=0A= =0A= static void=0A= m32r_load_section (bfd *abfd, asection *s, void *obj)=0A= {=0A= unsigned int *data_count =3D obj;=0A= if (s->flags & SEC_LOAD)=0A= {=0A= bfd_size_type section_size =3D bfd_section_size (abfd, s);=0A= bfd_vma section_base =3D bfd_section_lma (abfd, s);=0A= unsigned int buffer, i;=0A= =0A= *data_count +=3D section_size;=0A= =0A= printf_filtered ("Loading section %s, size 0x%lx lma ",=0A= bfd_section_name (abfd, s), section_size);=0A= print_address_numeric (section_base, 1, gdb_stdout);=0A= printf_filtered ("\n");=0A= gdb_flush (gdb_stdout);=0A= monitor_printf ("%s mw\r", paddr_nz (section_base));=0A= for (i =3D 0; i < section_size; i +=3D 4)=0A= {=0A= QUIT;=0A= monitor_expect (" -> ", NULL, 0);=0A= bfd_get_section_contents (abfd, s, (char *) &buffer, i, 4);=0A= monitor_printf ("%x\n", buffer);=0A= }=0A= monitor_expect (" -> ", NULL, 0);=0A= monitor_printf ("q\n");=0A= monitor_expect_prompt (NULL, 0);=0A= }=0A= }=0A= =0A= static int=0A= m32r_load_1 (void *dummy)=0A= {=0A= int data_count =3D 0;=0A= =0A= bfd_map_over_sections ((bfd *) dummy, m32r_load_section, &data_count);=0A= return data_count;=0A= }=0A= =0A= /*=20=0A= * Function: m32r_load (an alternate way to load)=20=0A= */=0A= =0A= static void=0A= m32r_load (char *filename, int from_tty)=0A= {=0A= bfd *abfd;=0A= asection *s;=0A= unsigned int i, data_count =3D 0;=0A= time_t start_time, end_time; /* for timing of download */=0A= =0A= if (filename =3D=3D NULL || filename[0] =3D=3D 0)=0A= filename =3D get_exec_file (1);=0A= =0A= abfd =3D bfd_openr (filename, 0);=0A= if (!abfd)=0A= error ("Unable to open file %s\n", filename);=0A= if (bfd_check_format (abfd, bfd_object) =3D=3D 0)=0A= error ("File is not an object file\n");=0A= start_time =3D time (NULL);=0A= #if 0=0A= for (s =3D abfd->sections; s; s =3D s->next)=0A= if (s->flags & SEC_LOAD)=0A= {=0A= bfd_size_type section_size =3D bfd_section_size (abfd, s);=0A= bfd_vma section_base =3D bfd_section_vma (abfd, s);=0A= unsigned int buffer;=0A= =0A= data_count +=3D section_size;=0A= =0A= printf_filtered ("Loading section %s, size 0x%lx vma ",=0A= bfd_section_name (abfd, s), section_size);=0A= print_address_numeric (section_base, 1, gdb_stdout);=0A= printf_filtered ("\n");=0A= gdb_flush (gdb_stdout);=0A= monitor_printf ("%x mw\r", section_base);=0A= for (i =3D 0; i < section_size; i +=3D 4)=0A= {=0A= monitor_expect (" -> ", NULL, 0);=0A= bfd_get_section_contents (abfd, s, (char *) &buffer, i, 4);=0A= monitor_printf ("%x\n", buffer);=0A= }=0A= monitor_expect (" -> ", NULL, 0);=0A= monitor_printf ("q\n");=0A= monitor_expect_prompt (NULL, 0);=0A= }=0A= #else=0A= if (!(catch_errors (m32r_load_1, abfd, "Load aborted!\n", RETURN_MASK_ALL= )))=0A= {=0A= monitor_printf ("q\n");=0A= return;=0A= }=0A= #endif=0A= end_time =3D time (NULL);=0A= printf_filtered ("Start address 0x%lx\n", bfd_get_start_address (abfd));= =0A= report_transfer_performance (data_count, start_time, end_time);=0A= =0A= /* Finally, make the PC point at the start address */=0A= if (exec_bfd)=0A= write_pc (bfd_get_start_address (exec_bfd));=0A= =0A= inferior_ptid =3D null_ptid; /* No process now */=0A= =0A= /* This is necessary because many things were based on the PC at the=0A= time that we attached to the monitor, which is no longer valid=0A= now that we have loaded new code (and just changed the PC).=0A= Another way to do this might be to call normal_stop, except that=0A= the stack may not be valid, and things would get horribly=0A= confused... */=0A= =0A= clear_symtab_users ();=0A= }=0A= =0A= static void=0A= m32r_load_gen (char *filename, int from_tty)=0A= {=0A= generic_load (filename, from_tty);=0A= }=0A= =0A= static void m32r_open (char *args, int from_tty);=0A= static void mon2000_open (char *args, int from_tty);=0A= =0A= /* This array of registers needs to match the indexes used by GDB. The=0A= whole reason this exists is because the various ROM monitors use=0A= different names than GDB does, and don't support all the registers=0A= either. So, typing "info reg sp" becomes an "A7". */=0A= =0A= static char *m32r_regnames[] =3D=0A= { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",=0A= "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",=0A= "psw", "cbr", "spi", "spu", "bpc", "pc", "accl", "acch",=0A= };=0A= =0A= static void=0A= m32r_supply_register (char *regname, int regnamelen, char *val, int vallen)= =0A= {=0A= int regno;=0A= int num_regs =3D sizeof (m32r_regnames) / sizeof (m32r_regnames[0]);=0A= =0A= for (regno =3D 0; regno < num_regs; regno++)=0A= if (strncmp (regname, m32r_regnames[regno], regnamelen) =3D=3D 0)=0A= break;=0A= =0A= if (regno >=3D num_regs)=0A= return; /* no match */=0A= =0A= if (regno =3D=3D ACCL_REGNUM)=0A= { /* special handling for 64-bit acc reg */=0A= monitor_supply_register (ACCH_REGNUM, val);=0A= val =3D strchr (val, ':'); /* skip past ':' to get 2nd word */=0A= if (val !=3D NULL)=0A= monitor_supply_register (ACCL_REGNUM, val + 1);=0A= }=0A= else=0A= {=0A= monitor_supply_register (regno, val);=0A= if (regno =3D=3D PSW_REGNUM)=0A= {=0A= unsigned long psw =3D strtoul (val, NULL, 16);=0A= char *zero =3D "00000000", *one =3D "00000001";=0A= =0A= #ifdef SM_REGNUM=0A= /* Stack mode bit */=0A= monitor_supply_register (SM_REGNUM, (psw & 0x80) ? one : zero);=0A= #endif=0A= #ifdef BSM_REGNUM=0A= /* Backup stack mode bit */=0A= monitor_supply_register (BSM_REGNUM, (psw & 0x8000) ? one : zero);=0A= #endif=0A= #ifdef IE_REGNUM=0A= /* Interrupt enable bit */=0A= monitor_supply_register (IE_REGNUM, (psw & 0x40) ? one : zero);=0A= #endif=0A= #ifdef BIE_REGNUM=0A= /* Backup interrupt enable bit */=0A= monitor_supply_register (BIE_REGNUM, (psw & 0x4000) ? one : zero);=0A= #endif=0A= #ifdef COND_REGNUM=0A= /* Condition bit (carry etc.) */=0A= monitor_supply_register (COND_REGNUM, (psw & 0x1) ? one : zero);=0A= #endif=0A= #ifdef CBR_REGNUM=0A= monitor_supply_register (CBR_REGNUM, (psw & 0x1) ? one : zero);=0A= #endif=0A= #ifdef BPC_REGNUM=0A= monitor_supply_register (BPC_REGNUM, zero); /* KLUDGE: (???????) */=0A= #endif=0A= #ifdef BCARRY_REGNUM=0A= monitor_supply_register (BCARRY_REGNUM, zero); /* KLUDGE: (??????) */=0A= #endif=0A= }=0A= =0A= if (regno =3D=3D SPI_REGNUM || regno =3D=3D SPU_REGNUM)=0A= { /* special handling for stack pointer (spu or spi) */=0A= unsigned long stackmode =3D read_register (PSW_REGNUM) & 0x80;=0A= =0A= if (regno =3D=3D SPI_REGNUM && !stackmode) /* SP =3D=3D SPI */=0A= monitor_supply_register (SP_REGNUM, val);=0A= else if (regno =3D=3D SPU_REGNUM && stackmode) /* SP =3D=3D SPU */=0A= monitor_supply_register (SP_REGNUM, val);=0A= }=0A= }=0A= }=0A= =0A= /* m32r RevC board monitor */=0A= =0A= static struct target_ops m32r_ops;=0A= =0A= static char *m32r_inits[] =3D { "\r", NULL };=0A= =0A= static struct monitor_ops m32r_cmds;=0A= =0A= static void=0A= init_m32r_cmds (void)=0A= {=0A= m32r_cmds.flags =3D MO_CLR_BREAK_USES_ADDR | MO_REGISTER_VALUE_FIRST;=0A= m32r_cmds.init =3D m32r_inits; /* Init strings */=0A= m32r_cmds.cont =3D "go\r"; /* continue command */=0A= m32r_cmds.step =3D "step\r"; /* single step */=0A= m32r_cmds.stop =3D NULL; /* interrupt command */=0A= m32r_cmds.set_break =3D "%x +bp\r"; /* set a breakpoint */=0A= m32r_cmds.clr_break =3D "%x -bp\r"; /* clear a breakpoint */=0A= m32r_cmds.clr_all_break =3D "bpoff\r"; /* clear all breakpoints */=0A= m32r_cmds.fill =3D "%x %x %x fill\r"; /* fill (start length val) */=0A= m32r_cmds.setmem.cmdb =3D "%x 1 %x fill\r"; /* setmem.cmdb (addr, value) = */=0A= m32r_cmds.setmem.cmdw =3D "%x 1 %x fillh\r"; /* setmem.cmdw (addr, value)= */=0A= m32r_cmds.setmem.cmdl =3D "%x 1 %x fillw\r"; /* setmem.cmdl (addr, value)= */=0A= m32r_cmds.setmem.cmdll =3D NULL; /* setmem.cmdll (addr, value) */=0A= m32r_cmds.setmem.resp_delim =3D NULL; /* setmem.resp_delim */=0A= m32r_cmds.setmem.term =3D NULL; /* setmem.term */=0A= m32r_cmds.setmem.term_cmd =3D NULL; /* setmem.term_cmd */=0A= m32r_cmds.getmem.cmdb =3D "%x %x dump\r"; /* getmem.cmdb (addr, len) */= =0A= m32r_cmds.getmem.cmdw =3D NULL; /* getmem.cmdw (addr, len) */=0A= m32r_cmds.getmem.cmdl =3D NULL; /* getmem.cmdl (addr, len) */=0A= m32r_cmds.getmem.cmdll =3D NULL; /* getmem.cmdll (addr, len) */=0A= m32r_cmds.getmem.resp_delim =3D ": "; /* getmem.resp_delim */=0A= m32r_cmds.getmem.term =3D NULL; /* getmem.term */=0A= m32r_cmds.getmem.term_cmd =3D NULL; /* getmem.term_cmd */=0A= m32r_cmds.setreg.cmd =3D "%x to %%%s\r"; /* setreg.cmd (name, value) */= =0A= m32r_cmds.setreg.resp_delim =3D NULL; /* setreg.resp_delim */=0A= m32r_cmds.setreg.term =3D NULL; /* setreg.term */=0A= m32r_cmds.setreg.term_cmd =3D NULL; /* setreg.term_cmd */=0A= m32r_cmds.getreg.cmd =3D NULL; /* getreg.cmd (name) */=0A= m32r_cmds.getreg.resp_delim =3D NULL; /* getreg.resp_delim */=0A= m32r_cmds.getreg.term =3D NULL; /* getreg.term */=0A= m32r_cmds.getreg.term_cmd =3D NULL; /* getreg.term_cmd */=0A= m32r_cmds.dump_registers =3D ".reg\r"; /* dump_registers */=0A= m32r_cmds.register_pattern =3D "\\(\\w+\\) +=3D \\([0-9a-fA-F]+\\b\\)"; /= * register_pattern */=0A= m32r_cmds.supply_register =3D m32r_supply_register; /* supply_register */= =0A= m32r_cmds.load_routine =3D NULL; /* load_routine (defaults to SRECs) */= =0A= m32r_cmds.load =3D NULL; /* download command */=0A= m32r_cmds.loadresp =3D NULL; /* load response */=0A= m32r_cmds.prompt =3D "ok "; /* monitor command prompt */=0A= m32r_cmds.line_term =3D "\r"; /* end-of-line terminator */=0A= m32r_cmds.cmd_end =3D NULL; /* optional command terminator */=0A= m32r_cmds.target =3D &m32r_ops; /* target operations */=0A= m32r_cmds.stopbits =3D SERIAL_1_STOPBITS; /* number of stop bits */=0A= m32r_cmds.regnames =3D m32r_regnames; /* registers names */=0A= m32r_cmds.magic =3D MONITOR_OPS_MAGIC; /* magic */=0A= } /* init_m32r_cmds */=0A= =0A= static void=0A= m32r_open (char *args, int from_tty)=0A= {=0A= monitor_open (args, &m32r_cmds, from_tty);=0A= }=0A= =0A= /* Mon2000 monitor (MSA2000 board) */=0A= =0A= static struct target_ops mon2000_ops;=0A= static struct monitor_ops mon2000_cmds;=0A= =0A= static void=0A= init_mon2000_cmds (void)=0A= {=0A= mon2000_cmds.flags =3D MO_CLR_BREAK_USES_ADDR | MO_REGISTER_VALUE_FIRST;= =0A= mon2000_cmds.init =3D m32r_inits; /* Init strings */=0A= mon2000_cmds.cont =3D "go\r"; /* continue command */=0A= mon2000_cmds.step =3D "step\r"; /* single step */=0A= mon2000_cmds.stop =3D NULL; /* interrupt command */=0A= mon2000_cmds.set_break =3D "%x +bp\r"; /* set a breakpoint */=0A= mon2000_cmds.clr_break =3D "%x -bp\r"; /* clear a breakpoint */=0A= mon2000_cmds.clr_all_break =3D "bpoff\r"; /* clear all breakpoints */=0A= mon2000_cmds.fill =3D "%x %x %x fill\r"; /* fill (start length val) */=0A= mon2000_cmds.setmem.cmdb =3D "%x 1 %x fill\r"; /* setmem.cmdb (addr, valu= e) */=0A= mon2000_cmds.setmem.cmdw =3D "%x 1 %x fillh\r"; /* setmem.cmdw (addr, val= ue) */=0A= mon2000_cmds.setmem.cmdl =3D "%x 1 %x fillw\r"; /* setmem.cmdl (addr, val= ue) */=0A= mon2000_cmds.setmem.cmdll =3D NULL; /* setmem.cmdll (addr, value) */=0A= mon2000_cmds.setmem.resp_delim =3D NULL; /* setmem.resp_delim */=0A= mon2000_cmds.setmem.term =3D NULL; /* setmem.term */=0A= mon2000_cmds.setmem.term_cmd =3D NULL; /* setmem.term_cmd */=0A= mon2000_cmds.getmem.cmdb =3D "%x %x dump\r"; /* getmem.cmdb (addr, len) *= /=0A= mon2000_cmds.getmem.cmdw =3D NULL; /* getmem.cmdw (addr, len) */=0A= mon2000_cmds.getmem.cmdl =3D NULL; /* getmem.cmdl (addr, len) */=0A= mon2000_cmds.getmem.cmdll =3D NULL; /* getmem.cmdll (addr, len) */=0A= mon2000_cmds.getmem.resp_delim =3D ": "; /* getmem.resp_delim */=0A= mon2000_cmds.getmem.term =3D NULL; /* getmem.term */=0A= mon2000_cmds.getmem.term_cmd =3D NULL; /* getmem.term_cmd */=0A= mon2000_cmds.setreg.cmd =3D "%x to %%%s\r"; /* setreg.cmd (name, value) *= /=0A= mon2000_cmds.setreg.resp_delim =3D NULL; /* setreg.resp_delim */=0A= mon2000_cmds.setreg.term =3D NULL; /* setreg.term */=0A= mon2000_cmds.setreg.term_cmd =3D NULL; /* setreg.term_cmd */=0A= mon2000_cmds.getreg.cmd =3D NULL; /* getreg.cmd (name) */=0A= mon2000_cmds.getreg.resp_delim =3D NULL; /* getreg.resp_delim */=0A= mon2000_cmds.getreg.term =3D NULL; /* getreg.term */=0A= mon2000_cmds.getreg.term_cmd =3D NULL; /* getreg.term_cmd */=0A= mon2000_cmds.dump_registers =3D ".reg\r"; /* dump_registers */=0A= mon2000_cmds.register_pattern =3D "\\(\\w+\\) +=3D \\([0-9a-fA-F]+\\b\\)"= ; /* register_pattern */=0A= mon2000_cmds.supply_register =3D m32r_supply_register; /* supply_register= */=0A= mon2000_cmds.load_routine =3D NULL; /* load_routine (defaults to SRECs) *= /=0A= mon2000_cmds.load =3D NULL; /* download command */=0A= mon2000_cmds.loadresp =3D NULL; /* load response */=0A= mon2000_cmds.prompt =3D "Mon2000>"; /* monitor command prompt */=0A= mon2000_cmds.line_term =3D "\r"; /* end-of-line terminator */=0A= mon2000_cmds.cmd_end =3D NULL; /* optional command terminator */=0A= mon2000_cmds.target =3D &mon2000_ops; /* target operations */=0A= mon2000_cmds.stopbits =3D SERIAL_1_STOPBITS; /* number of stop bits */=0A= mon2000_cmds.regnames =3D m32r_regnames; /* registers names */=0A= mon2000_cmds.magic =3D MONITOR_OPS_MAGIC; /* magic */=0A= } /* init_mon2000_cmds */=0A= =0A= static void=0A= mon2000_open (char *args, int from_tty)=0A= {=0A= monitor_open (args, &mon2000_cmds, from_tty);=0A= }=0A= =0A= /* Function: set_board_address=0A= Tell the BootOne monitor what it's ethernet IP address is. */=0A= =0A= static void=0A= m32r_set_board_address (char *args, int from_tty)=0A= {=0A= int resp_len;=0A= char buf[1024];=0A= =0A= if (args && *args)=0A= {=0A= monitor_printf ("ulip %s\n", args);=0A= resp_len =3D monitor_expect_prompt (buf, sizeof (buf));=0A= /* now parse the result for success */=0A= }=0A= else=0A= error ("Requires argument (IP address for M32R-EVA board)");=0A= }=0A= =0A= /* Function: set_server_address=0A= Tell the BootOne monitor what gdb's ethernet IP address is. */=0A= =0A= static void=0A= m32r_set_server_address (char *args, int from_tty)=0A= {=0A= int resp_len;=0A= char buf[1024];=0A= =0A= if (args && *args)=0A= {=0A= monitor_printf ("uhip %s\n", args);=0A= resp_len =3D monitor_expect_prompt (buf, sizeof (buf));=0A= /* now parse the result for success */=0A= }=0A= else=0A= error ("Requires argument (IP address of GDB's host computer)");=0A= }=0A= =0A= /* Function: set_download_path=0A= Tell the BootOne monitor the default path for downloadable SREC files. *= /=0A= =0A= static void=0A= m32r_set_download_path (char *args, int from_tty)=0A= {=0A= int resp_len;=0A= char buf[1024];=0A= =0A= if (args && *args)=0A= {=0A= monitor_printf ("up %s\n", args);=0A= resp_len =3D monitor_expect_prompt (buf, sizeof (buf));=0A= /* now parse the result for success */=0A= }=0A= else=0A= error ("Requires argument (default path for downloadable SREC files)");= =0A= }=0A= =0A= static void=0A= m32r_upload_command (char *args, int from_tty)=0A= {=0A= bfd *abfd;=0A= asection *s;=0A= time_t start_time, end_time; /* for timing of download */=0A= int resp_len, data_count =3D 0;=0A= char buf[1024];=0A= struct hostent *hostent;=0A= struct in_addr inet_addr;=0A= =0A= /* first check to see if there's an ethernet port! */=0A= monitor_printf ("ust\r");=0A= resp_len =3D monitor_expect_prompt (buf, sizeof (buf));=0A= if (!strchr (buf, ':'))=0A= error ("No ethernet connection!");=0A= =0A= if (board_addr =3D=3D 0)=0A= {=0A= /* scan second colon in the output from the "ust" command */=0A= char *myIPaddress =3D strchr (strchr (buf, ':') + 1, ':') + 1;=0A= =0A= while (isspace (*myIPaddress))=0A= myIPaddress++;=0A= =0A= if (!strncmp (myIPaddress, "0.0.", 4)) /* empty */=0A= error=0A= ("Please use 'set board-address' to set the M32R-EVA board's IP address.= ");=0A= if (strchr (myIPaddress, '('))=0A= *(strchr (myIPaddress, '(')) =3D '\0'; /* delete trailing junk */=0A= board_addr =3D xstrdup (myIPaddress);=0A= }=0A= if (server_addr =3D=3D 0)=0A= {=0A= buf[0] =3D 0;=0A= gethostname (buf, sizeof (buf));=0A= if (buf[0] !=3D 0)=0A= hostent =3D gethostbyname (buf);=0A= if (hostent !=3D 0)=0A= {=0A= #if 1=0A= memcpy (&inet_addr.s_addr, hostent->h_addr,=0A= sizeof (inet_addr.s_addr));=0A= server_addr =3D (char *) inet_ntoa (inet_addr);=0A= #else=0A= server_addr =3D (char *) inet_ntoa (hostent->h_addr);=0A= #endif=0A= }=0A= if (server_addr =3D=3D 0) /* failed? */=0A= error=0A= ("Need to know gdb host computer's IP address (use 'set server-address')= ");=0A= }=0A= =0A= if (args =3D=3D 0 || args[0] =3D=3D 0) /* no args: upload the current fil= e */=0A= args =3D get_exec_file (1);=0A= =0A= if (args[0] !=3D '/' && download_path =3D=3D 0)=0A= {=0A= if (current_directory)=0A= download_path =3D xstrdup (current_directory);=0A= else=0A= error=0A= ("Need to know default download path (use 'set download-path')");=0A= }=0A= =0A= start_time =3D time (NULL);=0A= monitor_printf ("uhip %s\r", server_addr);=0A= resp_len =3D monitor_expect_prompt (buf, sizeof (buf)); /* parse result? = */=0A= monitor_printf ("ulip %s\r", board_addr);=0A= resp_len =3D monitor_expect_prompt (buf, sizeof (buf)); /* parse result? = */=0A= if (args[0] !=3D '/')=0A= monitor_printf ("up %s\r", download_path); /* use default path */=0A= else=0A= monitor_printf ("up\r"); /* rooted filename/path */=0A= resp_len =3D monitor_expect_prompt (buf, sizeof (buf)); /* parse result? = */=0A= =0A= if (strrchr (args, '.') && !strcmp (strrchr (args, '.'), ".srec"))=0A= monitor_printf ("ul %s\r", args);=0A= else /* add ".srec" suffix */=0A= monitor_printf ("ul %s.srec\r", args);=0A= resp_len =3D monitor_expect_prompt (buf, sizeof (buf)); /* parse result? = */=0A= =0A= if (buf[0] =3D=3D 0 || strstr (buf, "complete") =3D=3D 0)=0A= error=0A= ("Upload file not found: %s.srec\nCheck IP addresses and download pat= h.",=0A= args);=0A= else=0A= printf_filtered (" -- Ethernet load complete.\n");=0A= =0A= end_time =3D time (NULL);=0A= abfd =3D bfd_openr (args, 0);=0A= if (abfd !=3D NULL)=0A= { /* Download is done -- print section statistics */=0A= if (bfd_check_format (abfd, bfd_object) =3D=3D 0)=0A= {=0A= printf_filtered ("File is not an object file\n");=0A= }=0A= for (s =3D abfd->sections; s; s =3D s->next)=0A= if (s->flags & SEC_LOAD)=0A= {=0A= bfd_size_type section_size =3D bfd_section_size (abfd, s);=0A= bfd_vma section_base =3D bfd_section_lma (abfd, s);=0A= unsigned int buffer;=0A= =0A= data_count +=3D section_size;=0A= =0A= printf_filtered ("Loading section %s, size 0x%lx lma ",=0A= bfd_section_name (abfd, s), section_size);=0A= print_address_numeric (section_base, 1, gdb_stdout);=0A= printf_filtered ("\n");=0A= gdb_flush (gdb_stdout);=0A= }=0A= /* Finally, make the PC point at the start address */=0A= write_pc (bfd_get_start_address (abfd));=0A= report_transfer_performance (data_count, start_time, end_time);=0A= printf_filtered ("Start address 0x%lx\n", bfd_get_start_address (abfd= ));=0A= }=0A= inferior_ptid =3D null_ptid; /* No process now */=0A= =0A= /* This is necessary because many things were based on the PC at the=0A= time that we attached to the monitor, which is no longer valid=0A= now that we have loaded new code (and just changed the PC).=0A= Another way to do this might be to call normal_stop, except that=0A= the stack may not be valid, and things would get horribly=0A= confused... */=0A= =0A= clear_symtab_users ();=0A= }=0A= =0A= void=0A= _initialize_m32r_rom (void)=0A= {=0A= /* Initialize m32r RevC monitor target */=0A= init_m32r_cmds ();=0A= init_monitor_ops (&m32r_ops);=0A= =0A= m32r_ops.to_shortname =3D "m32r";=0A= m32r_ops.to_longname =3D "m32r monitor";=0A= m32r_ops.to_load =3D m32r_load_gen; /* monitor lacks a download command *= /=0A= m32r_ops.to_doc =3D "Debug via the m32r monitor.\n\=0A= Specify the serial device it is connected to (e.g. /dev/ttya).";=0A= m32r_ops.to_open =3D m32r_open;=0A= add_target (&m32r_ops);=0A= =0A= /* Initialize mon2000 monitor target */=0A= init_mon2000_cmds ();=0A= init_monitor_ops (&mon2000_ops);=0A= =0A= mon2000_ops.to_shortname =3D "mon2000";=0A= mon2000_ops.to_longname =3D "Mon2000 monitor";=0A= mon2000_ops.to_load =3D m32r_load_gen; /* monitor lacks a download comman= d */=0A= mon2000_ops.to_doc =3D "Debug via the Mon2000 monitor.\n\=0A= Specify the serial device it is connected to (e.g. /dev/ttya).";=0A= mon2000_ops.to_open =3D mon2000_open;=0A= add_target (&mon2000_ops);=0A= =0A= add_show_from_set=0A= (add_set_cmd ("download-path", class_obscure, var_string,=0A= (char *) &download_path,=0A= "Set the default path for downloadable SREC files.",=0A= &setlist), &showlist);=0A= =0A= add_show_from_set=0A= (add_set_cmd ("board-address", class_obscure, var_string,=0A= (char *) &board_addr,=0A= "Set IP address for M32R-EVA target board.",=0A= &setlist), &showlist);=0A= =0A= add_show_from_set=0A= (add_set_cmd ("server-address", class_obscure, var_string,=0A= (char *) &server_addr,=0A= "Set IP address for download server (GDB's host computer).",=0A= &setlist), &showlist);=0A= =0A= add_com ("upload", class_obscure, m32r_upload_command,=0A= "Upload the srec file via the monitor's Ethernet upload capability.");= =0A= =0A= add_com ("tload", class_obscure, m32r_load, "test upload command.");=0A= }=0A= ------=_NextPart_000_02E9_01C347C7.FDA9E620 Content-Type: application/octet-stream; name="m32r.mt" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="m32r.mt" Content-length: 157 # Target: Renesas m32r processor=0A= TDEPFILES=3D m32r-tdep.o monitor.o m32r-rom.o dsrec.o=0A= SIM_OBS =3D remote-sim.o=0A= SIM =3D ../sim/m32r/libsim.a=0A= ------=_NextPart_000_02E9_01C347C7.FDA9E620 Content-Type: application/octet-stream; name="diffs.dat" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="diffs.dat" Content-length: 1348 diff -Naur insight-20030703.orig/src/configure insight-20030703/src/configu= re=0A= --- insight-20030703.orig/src/configure Sat Jun 28 02:34:33 2003=0A= +++ insight-20030703/src/configure Fri Jul 4 09:17:15 2003=0A= @@ -1259,9 +1259,6 @@=0A= i[3456789]86-*-beos*)=0A= noconfigdirs=3D"$noconfigdirs gdb target-newlib target-libgloss ${libg= cj}"=0A= ;;=0A= - m32r-*-*)=0A= - noconfigdirs=3D"$noconfigdirs ${libgcj} gdb"=0A= - ;;=0A= m68hc11-*-*|m6811-*-*|m68hc12-*-*|m6812-*-*)=0A= noconfigdirs=3D"$noconfigdirs target-libiberty target-libstdc++-v3 ${l= ibgcj}"=0A= ;;=0A= diff -Naur insight-20030703.orig/src/gdb/configure.tgt insight-20030703/src= /gdb/configure.tgt=0A= --- insight-20030703.orig/src/gdb/configure.tgt Sat Jun 14 02:49:49 2003=0A= +++ insight-20030703/src/gdb/configure.tgt Fri Jul 4 09:17:15 2003=0A= @@ -113,7 +113,7 @@=0A= ;;=0A= ia64*-*-*) gdb_target=3Dia64 ;;=0A= =20=0A= -# OBSOLETE m32r-*-elf*) gdb_target=3Dm32r ;;=0A= +m32r-*-*) gdb_target=3Dm32r ;;=0A= =20=0A= m68hc11*-*-*|m6811*-*-*) gdb_target=3Dm68hc11 ;;=0A= =20=0A= @@ -264,6 +264,7 @@=0A= =20=0A= case "${gdb_target}" in=0A= d10v) gdb_multi_arch=3Dyes ;;=0A= +m32r) gdb_multi_arch=3Dyes ;;=0A= m68hc11) gdb_multi_arch=3Dyes ;;=0A= mn10300) gdb_multi_arch=3Dyes ;;=0A= x86-64linux) gdb_multi_arch=3Dyes ;;=0A= ------=_NextPart_000_02E9_01C347C7.FDA9E620--