describing enum.
* defs.h: added new #define for TARGET_PTR_BIT, defaults to size
of target int.
* h8300-tdep.c, remote-hms.c, tm-h8300.h: too many changes to count
* symtab.c (lookup_reference_type, lookup_ptr_type): use
TARGET_PTR_BIT to determine size of a pointer
* values.c (unpack_long): when unpacking a REF or a PTR don't
assume the size of the type.
+Thu Feb 6 11:51:39 1992 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * coffread.c (read_enum_type): Use the size of a target int when
+ describing enum.
+ * defs.h: added new #define for TARGET_PTR_BIT, defaults to size
+ of target int.
+ * h8300-tdep.c, remote-hms.c, tm-h8300.h: too many changes to count
+ * symtab.c (lookup_reference_type, lookup_ptr_type): use
+ TARGET_PTR_BIT to determine size of a pointer
+ * values.c (unpack_long): when unpacking a REF or a PTR don't
+ assume the size of the type.
+
Wed Feb 5 22:29:59 1992 John Gilmore (gnu at cygnus.com)
* mipsread.c (parse_symbol): Avoid clobbering enum pointer when
+/* Target-machine dependent code for Hitachi H8/300, for GDB.
+ Copyright (C) 1988, 1990, 1991 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/*
+ Contributed by Steve Chamberlain
+ sac@cygnus.com
+ */
+
#include <stdio.h>
#include "defs.h"
+#include "frame.h"
+#include "obstack.h"
+#include "symtab.h"
+#define UNSIGNED_SHORT(X) ((X) & 0xffff)
/* an easy to debug H8 stack frame looks like:
0x6df2 push r2
subs r5,sp
*/
+
#define IS_PUSH(x) ((x & 0xff00)==0x6d00)
+#define IS_MOVE_FP(x) (x == 0x0d76)
+#define IS_MOV_SP_FP(x) (x == 0x0d76)
+#define IS_SUB2_SP(x) (x==0x1b87)
+#define IS_MOVK_R5(x) (x==0x7905)
+CORE_ADDR examine_prologue();
+
+void frame_find_saved_regs ();
CORE_ADDR h8300_skip_prologue(start_pc)
CORE_ADDR start_pc;
{
+
/* Skip past all push insns */
short int w;
start_pc+=2;
w = read_memory_integer(start_pc, 2);
}
-return start_pc;
-
-}
-h8300_pop_frame()
-{
- printf("pop frame\n");
+ /* Skip past a move to FP */
+ if (IS_MOVE_FP(w)) {
+ start_pc +=2 ;
+ w = read_memory_integer(start_pc, 2);
+ }
+
+ return start_pc;
}
+
int
print_insn(memaddr, stream)
CORE_ADDR memaddr;
/* Nothing is bigger than 8 bytes */
char data[8];
read_memory (memaddr, data, sizeof(data));
- return print_insn_h8300(memaddr, data , stream);
-
-
+ return print_insn_h8300(memaddr, data, stream);
}
+/* Given a GDB frame, determine the address of the calling function's frame.
+ This will be used to create a new GDB frame struct, and then
+ INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
+
+ For us, the frame address is its stack pointer value, so we look up
+ the function prologue to determine the caller's sp value, and return it. */
+
+FRAME_ADDR
+FRAME_CHAIN (thisframe)
+ FRAME thisframe;
+{
+
+ frame_find_saved_regs (thisframe, (struct frame_saved_regs *) 0);
+ return thisframe->fsr->regs[SP_REGNUM];
+}
+
- FRAME_CHAIN()
- {
-
- printf("Frame chain\n");
-
- }
-
+
+/* Put here the code to store, into a struct frame_saved_regs,
+ the addresses of the saved registers of frame described by FRAME_INFO.
+ This includes special registers such as pc and fp saved in special
+ ways in the stack frame. sp is even more special:
+ the address we return for it IS the sp for the next frame.
+
+ We cache the result of doing this in the frame_cache_obstack, since
+ it is fairly expensive. */
+
+void
+frame_find_saved_regs (fi, fsr)
+ struct frame_info *fi;
+ struct frame_saved_regs *fsr;
+{
+ register CORE_ADDR next_addr;
+ register CORE_ADDR *saved_regs;
+ register int regnum;
+ register struct frame_saved_regs *cache_fsr;
+ extern struct obstack frame_cache_obstack;
+ CORE_ADDR ip;
+ struct symtab_and_line sal;
+ CORE_ADDR limit;
+
+ if (!fi->fsr)
+ {
+ cache_fsr = (struct frame_saved_regs *)
+ obstack_alloc (&frame_cache_obstack,
+ sizeof (struct frame_saved_regs));
+ bzero (cache_fsr, sizeof (struct frame_saved_regs));
+ fi->fsr = cache_fsr;
+
+ /* Find the start and end of the function prologue. If the PC
+ is in the function prologue, we only consider the part that
+ has executed already. */
+
+ ip = get_pc_function_start (fi->pc);
+ sal = find_pc_line (ip, 0);
+ limit = (sal.end && sal.end < fi->pc) ? sal.end: fi->pc;
+
+ /* This will fill in fields in *fi as well as in cache_fsr. */
+ examine_prologue (ip, limit, fi->frame, cache_fsr, fi);
+ }
+
+ if (fsr)
+ *fsr = *fi->fsr;
+}
+
+/* Fetch the instruction at ADDR, returning 0 if ADDR is beyond LIM or
+ is not the address of a valid instruction, the address of the next
+ instruction beyond ADDR otherwise. *PWORD1 receives the first word
+ of the instruction.*/
+
+
+CORE_ADDR
+NEXT_PROLOGUE_INSN(addr, lim, pword1)
+CORE_ADDR addr;
+CORE_ADDR lim;
+short *pword1;
+{
+ if (addr < lim+8)
+ {
+ read_memory (addr, pword1, sizeof(*pword1));
+ SWAP_TARGET_AND_HOST (pword1, sizeof (short));
+ return addr + 2;
+ }
+
+ return 0;
+
+}
+
+/* Examine the prologue of a function. `ip' points to the first instruction.
+ `limit' is the limit of the prologue (e.g. the addr of the first
+ linenumber, or perhaps the program counter if we're stepping through).
+ `frame_sp' is the stack pointer value in use in this frame.
+ `fsr' is a pointer to a frame_saved_regs structure into which we put
+ info about the registers saved by this frame.
+ `fi' is a struct frame_info pointer; we fill in various fields in it
+ to reflect the offsets of the arg pointer and the locals pointer. */
+
+/* We will find two sorts of prologue, framefull and non framefull:
+
+ push r2
+ push r3
+ push fp
+ mov sp,fp
+ stack_ad
+
+ and
+ push x
+ push y
+ stack_ad
+
+*/
+
+static CORE_ADDR
+examine_prologue (ip, limit, after_prolog_fp, fsr, fi)
+ register CORE_ADDR ip;
+ register CORE_ADDR limit;
+ FRAME_ADDR after_prolog_fp;
+ struct frame_saved_regs *fsr;
+ struct frame_info *fi;
+{
+ register CORE_ADDR next_ip;
+ int r;
+ int i;
+ int have_fp = 0;
+
+ register int src;
+ register struct pic_prologue_code *pcode;
+ INSN_WORD insn_word;
+ int size, offset;
+ unsigned int reg_save_depth = 2; /* Number of things pushed onto
+ stack, starts at 2, 'cause the
+ PC is already there */
+
+ unsigned int auto_depth = 0; /* Number of bytes of autos */
+
+ char in_frame[NUM_REGS]; /* One for each reg */
+
+ memset(in_frame, 1, NUM_REGS);
+
+ if (after_prolog_fp == 0) {
+ after_prolog_fp = read_register(SP_REGNUM);
+ }
+ if (ip == 0 || ip & ~0xffff) return 0;
+
+ next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn_word);
+
+ /* Skip over any push instructions, and remember where they were saved */
+
+
+ while (next_ip && IS_PUSH(insn_word))
+ {
+ ip = next_ip;
+ in_frame[insn_word & 0x7] = reg_save_depth;
+ next_ip = NEXT_PROLOGUE_INSN(ip, limit, &insn_word);
+ reg_save_depth +=2;
+
+ }
+
+
+ /* Is this a move into the fp */
+ if (next_ip && IS_MOV_SP_FP(insn_word))
+ {
+ ip = next_ip;
+ next_ip = NEXT_PROLOGUE_INSN(ip, limit, &insn_word);
+ have_fp = 1;
+
+ }
+
+
+ /* Skip over any stack adjustment, happens either with a number of
+ sub#2,sp or a mov #x,r5 sub r5,sp */
+
+
+ if (next_ip && IS_SUB2_SP(insn_word))
+ {
+ while (next_ip && IS_SUB2_SP(insn_word))
+ {
+ auto_depth +=2 ;
+ ip = next_ip;
+ next_ip = NEXT_PROLOGUE_INSN(ip, limit, &insn_word);
+ }
+ }
+ else
+ {
+ if (next_ip && IS_MOVK_R5(insn_word))
+ {
+ ip = next_ip;
+ next_ip = NEXT_PROLOGUE_INSN(ip, limit, &insn_word);
+ auto_depth += insn_word;
+ ip +=4;
+
+ }
+ }
+
+
+
+ /* The args are always reffed based from the stack pointer */
+ fi->args_pointer = after_prolog_fp - auto_depth;
+ /* Locals are always reffed based from the fp */
+ fi->locals_pointer = after_prolog_fp ;
+ /* The PC is at a known place */
+ fi->from_pc = read_memory_integer(after_prolog_fp + reg_save_depth-2 , 2);
+
+
+ /* Rememeber any others too */
+
+ in_frame[PC_REGNUM] = 0;
+
+ for (r = 0; r < NUM_REGS; r++)
+ {
+ if (in_frame[r] != 1)
+ {
+ fsr->regs[r] = after_prolog_fp + reg_save_depth - in_frame[r] -2;
+ }
+ else
+ {
+ fsr->regs[r] = 0;
+ }
+ }
+ if (have_fp)
+ /* We keep the old FP in the SP spot */
+ fsr->regs[SP_REGNUM] = read_memory_integer(fsr->regs[6],2);
+ else
+ fsr->regs[SP_REGNUM] = after_prolog_fp + reg_save_depth;
+
+ return (ip);
+}
+
+void
+init_extra_frame_info (fromleaf, fi)
+ int fromleaf;
+ struct frame_info *fi;
+{
+ fi->fsr = 0; /* Not yet allocated */
+ fi->args_pointer = 0; /* Unknown */
+ fi->locals_pointer = 0; /* Unknown */
+ fi->from_pc = 0;
+
+}
+/* Return the saved PC from this frame.
+
+ If the frame has a memory copy of SRP_REGNUM, use that. If not,
+ just use the register SRP_REGNUM itself. */
+
+CORE_ADDR
+frame_saved_pc (frame)
+FRAME frame;
+
+{
+ return frame->from_pc;
+}
+
+
+CORE_ADDR
+frame_locals_address (fi)
+ struct frame_info *fi;
+{
+ if (!fi->locals_pointer)
+ {
+ struct frame_saved_regs ignore;
+ get_frame_saved_regs(fi, &ignore);
+
+ }
+ return fi->locals_pointer;
+}
+
+/* Return the address of the argument block for the frame
+ described by FI. Returns 0 if the address is unknown. */
+
+CORE_ADDR
+frame_args_address (fi)
+ struct frame_info *fi;
+{
+ if (!fi->args_pointer)
+ {
+ struct frame_saved_regs ignore;
+ get_frame_saved_regs(fi, &ignore);
+
+ }
+
+ return fi->args_pointer;
+}
+
+
+void h8300_pop_frame()
+{
+ unsigned regnum;
+ struct frame_saved_regs fsr;
+ struct frame_info *fi;
+
+ FRAME frame = get_current_frame();
+ fi = get_frame_info(frame);
+ get_frame_saved_regs(fi, &fsr);
+
+ for (regnum = 0; regnum < NUM_REGS; regnum ++)
+ {
+ if(fsr.regs[regnum])
+ {
+ write_register(regnum, read_memory_integer (fsr.regs[regnum], 2));
+ }
+
+ flush_cached_frames();
+ set_current_frame(create_new_frame(read_register(FP_REGNUM),
+ read_pc()));
+
+ }
+
+}
-/* Remote debugging interface for HMS Monitor Version 1.0
+/* Remote debugging interface for Hitachi HMS Monitor Version 1.0
Copyright 1992 Free Software Foundation, Inc.
extern struct target_ops hms_ops;
-#define DEBUG
+static int quiet = 1;
+
#ifdef DEBUG
-# define DENTER(NAME) (printf_filtered("Entering %s\n",NAME), fflush(stdout))
-# define DEXIT(NAME) (printf_filtered("Exiting %s\n",NAME), fflush(stdout))
+# define DENTER(NAME) if (!quiet) (printf_filtered("Entering %s\n",NAME), fflush(stdout))
+# define DEXIT(NAME) if (!quiet) (printf_filtered("Exiting %s\n",NAME), fflush(stdout))
#else
# define DENTER(NAME)
# define DEXIT(NAME)
#endif
+/***********************************************************************/
+/* Caching stuff stolen from remote-nindy.c */
+
+/* The data cache records all the data read from the remote machine
+ since the last time it stopped.
+
+ Each cache block holds LINE_SIZE bytes of data
+ starting at a multiple-of-LINE_SIZE address. */
+
+
+#define LINE_SIZE_POWER 4
+#define LINE_SIZE (1<<LINE_SIZE_POWER) /* eg 1<<3 == 8 */
+#define LINE_SIZE_MASK ((LINE_SIZE-1)) /* eg 7*2+1= 111*/
+#define DCACHE_SIZE 64 /* Number of cache blocks */
+#define XFORM(x) ((x&LINE_SIZE_MASK)>>2)
+struct dcache_block {
+ struct dcache_block *next, *last;
+ unsigned int addr; /* Address for which data is recorded. */
+ int data[LINE_SIZE/sizeof(int)];
+};
+
+struct dcache_block dcache_free, dcache_valid;
+
+/* Free all the data cache blocks, thus discarding all cached data. */
+static
+void
+dcache_flush ()
+{
+ register struct dcache_block *db;
+
+ while ((db = dcache_valid.next) != &dcache_valid)
+ {
+ remque (db);
+ insque (db, &dcache_free);
+ }
+}
+
+/*
+ * If addr is present in the dcache, return the address of the block
+ * containing it.
+ */
+static
+struct dcache_block *
+dcache_hit (addr)
+ unsigned int addr;
+{
+ register struct dcache_block *db;
+
+ if (addr & 3)
+ abort ();
+
+ /* Search all cache blocks for one that is at this address. */
+ db = dcache_valid.next;
+ while (db != &dcache_valid)
+ {
+ if ((addr & ~LINE_SIZE_MASK)== db->addr)
+ return db;
+ db = db->next;
+ }
+ return NULL;
+}
+
+/* Return the int data at address ADDR in dcache block DC. */
+static
+int
+dcache_value (db, addr)
+ struct dcache_block *db;
+ unsigned int addr;
+{
+ if (addr & 3)
+ abort ();
+ return (db->data[XFORM(addr)]);
+}
+
+/* Get a free cache block, put or keep it on the valid list,
+ and return its address. The caller should store into the block
+ the address and data that it describes, then remque it from the
+ free list and insert it into the valid list. This procedure
+ prevents errors from creeping in if a ninMemGet is interrupted
+ (which used to put garbage blocks in the valid list...). */
+static
+struct dcache_block *
+dcache_alloc ()
+{
+ register struct dcache_block *db;
+
+ if ((db = dcache_free.next) == &dcache_free)
+ {
+ /* If we can't get one from the free list, take last valid and put
+ it on the free list. */
+ db = dcache_valid.last;
+ remque (db);
+ insque (db, &dcache_free);
+ }
+
+ remque (db);
+ insque (db, &dcache_valid);
+ return (db);
+}
+
+/* Return the contents of the word at address ADDR in the remote machine,
+ using the data cache. */
+static
+int
+dcache_fetch (addr)
+ CORE_ADDR addr;
+{
+ register struct dcache_block *db;
+
+ db = dcache_hit (addr);
+ if (db == 0)
+ {
+ db = dcache_alloc ();
+ immediate_quit++;
+ hms_read_inferior_memory(addr & ~LINE_SIZE_MASK, (unsigned char *)db->data, LINE_SIZE);
+ immediate_quit--;
+ db->addr = addr & ~LINE_SIZE_MASK;
+ remque (db); /* Off the free list */
+ insque (db, &dcache_valid); /* On the valid list */
+ }
+ return (dcache_value (db, addr));
+}
+
+/* Write the word at ADDR both in the data cache and in the remote machine. */
+static void
+dcache_poke (addr, data)
+ CORE_ADDR addr;
+ int data;
+{
+ register struct dcache_block *db;
+
+ /* First make sure the word is IN the cache. DB is its cache block. */
+ db = dcache_hit (addr);
+ if (db == 0)
+ {
+ db = dcache_alloc ();
+ immediate_quit++;
+ hms_write_inferior_memory(addr & ~LINE_SIZE_MASK, (unsigned char *)db->data, LINE_SIZE);
+ immediate_quit--;
+ db->addr = addr & ~LINE_SIZE_MASK;
+ remque (db); /* Off the free list */
+ insque (db, &dcache_valid); /* On the valid list */
+ }
+
+ /* Modify the word in the cache. */
+ db->data[XFORM(addr)] = data;
+
+ /* Send the changed word. */
+ immediate_quit++;
+ hms_write_inferior_memory(addr, (unsigned char *)&data, 4);
+ immediate_quit--;
+}
+
+/* The cache itself. */
+struct dcache_block the_cache[DCACHE_SIZE];
+
+/* Initialize the data cache. */
+static void
+dcache_init ()
+{
+ register i;
+ register struct dcache_block *db;
+
+ db = the_cache;
+ dcache_free.next = dcache_free.last = &dcache_free;
+ dcache_valid.next = dcache_valid.last = &dcache_valid;
+ for (i=0;i<DCACHE_SIZE;i++,db++)
+ insque (db, &dcache_free);
+}
-static int timeout = 5;
+
+/***********************************************************************
+ * I/O stuff stolen from remote-eb.c
+ ***********************************************************************/
+
+static int timeout = 2;
static char *dev_name = "/dev/ttya";
-static int quiet;
+
/* Descriptor for I/O to remote machine. Initialize it to -1 so that
hms_open knows that we don't have a file open when the program
#define OPEN(x) ((x) >= 0)
+void hms_open();
+
#define ON 1
#define OFF 0
static void
ioctl (desc, TIOCSETP, &sg);
}
-/* Suck up all the input from the hms */
-slurp_input()
+
+/* Read a character from the remote system, doing all the fancy
+ timeout stuff. */
+static int
+readchar ()
{
- char buf[8];
+ char buf;
+ buf = '\0';
#ifdef HAVE_TERMIO
/* termio does the timeout for us. */
- while (read (hms_desc, buf, 8) > 0);
+ read (hms_desc, &buf, 1);
#else
alarm (timeout);
- while (read (hms_desc, buf, 8) > 0);
+ if (read (hms_desc, &buf, 1) < 0)
+ {
+ if (errno == EINTR)
+ error ("Timeout reading from remote system.");
+ else
+ perror_with_name ("remote");
+ }
alarm (0);
#endif
+
+ if (buf == '\0')
+ error ("Timeout reading from remote system.");
+
+ if (!quiet)
+ printf("%c",buf);
+
+ return buf & 0x7f;
}
-/* Read a character from the remote system, doing all the fancy
- timeout stuff. */
static int
-readchar ()
+readchar_nofail ()
{
char buf;
#else
alarm (timeout);
if (read (hms_desc, &buf, 1) < 0)
- {
- if (errno == EINTR)
- error ("Timeout reading from remote system.");
- else
- perror_with_name ("remote");
- }
+ {
+ return 0;
+ }
alarm (0);
#endif
- if (buf == '\0')
- error ("Timeout reading from remote system.");
-
-if (!quiet)
- printf("'%c'",buf);
-
+ if (buf == '\0')
+ {
+ return 0;
+ }
return buf & 0x7f;
}
void
hms_timer ()
{
-#if 0
- if (kiodebug)
- printf ("hms_timer called\n");
-#endif
n_alarms++;
}
#endif
-/* malloc'd name of the program on the remote system. */
-static char *prog_name = NULL;
/* Number of SIGTRAPs we need to simulate. That is, the next
NEED_ARTIFICIAL_TRAP calls to hms_wait should just return
char *arg;
int from_tty;
{
-#if 0
- DENTER("hms_kill()");
- fprintf (hms_stream, "K");
- fprintf (hms_stream, "\r");
- expect_prompt ();
- DEXIT("hms_kill()");
-#endif
}
+
+static check_open()
+{
+ if (!OPEN(hms_desc)) {
+ hms_open("",0);
+ }
+}
+
/*
* Download a file specified in 'args', to the hms.
*/
char buffer[1024];
DENTER("hms_load()");
- if (!OPEN(hms_desc))
- {
- printf_filtered("HMS not open. Use 'target' command to open HMS\n");
- return;
- }
+ check_open();
+
+ dcache_flush();
+ inferior_pid = 0;
abfd = bfd_openr(args,"coff-h8300");
if (!abfd)
{
- printf_filtered("Can't open a bfd on file\n");
+ printf_filtered("Unable to open file %s\n", args);
return;
}
error ("No exec file specified");
entry_pt = (int) bfd_get_start_address (exec_bfd);
-
+ check_open();
+
if (OPEN(hms_desc))
{
/* Clear the input because what the hms sends back is different
* depending on whether it was running or not.
*/
- /* slurp_input(); /* After this there should be a prompt */
+
hms_write_cr("r");
expect_prompt();
- printf_filtered("Do you want to download '%s' (y/n)? [y] : ",prog_name);
- {
- char buffer[10];
- gets(buffer);
- if (*buffer != 'n') {
- hms_load(prog_name,0);
- }
- }
insert_breakpoints (); /* Needed to get correct instruction in cache */
proceed(entry_pt, -1, 0);
- } else
- {
- printf_filtered("Hms not open yet.\n");
- }
+ }
DEXIT("hms_create_inferior()");
}
#endif
static struct {int rate, damn_b;} baudtab[] = {
- {0, B0},
- {50, B50},
- {75, B75},
- {110, B110},
- {134, B134},
- {150, B150},
- {200, B200},
+ {9600, B9600},
+ {19200, B19200},
{300, B300},
- {600, B600},
{1200, B1200},
- {1800, B1800},
{2400, B2400},
{4800, B4800},
- {9600, B9600},
- {19200, B19200},
- {38400, B38400},
{-1, -1},
};
for (i = 0; baudtab[i].rate != -1; i++)
if (rate == baudtab[i].rate) return baudtab[i].damn_b;
- return B38400; /* Random */
+ return B19200;
}
}
static int baudrate = 9600;
+
+static int
+is_baudrate_right()
+{
+
+
+ /* Put this port into NORMAL mode, send the 'normal' character */
+ hms_write("\001", 1); /* Control A */
+ hms_write("\r", 1); /* Cr */
+
+ while ( readchar_nofail()) /* Skip noise we put there */
+ ;
+
+ hms_write("r");
+ if (readchar_nofail() == 'r')
+ return 1;
+
+ /* Not the right baudrate, or the board's not on */
+ return 0;
+
+
+}
+static void
+set_rate()
+{
+ TERMINAL sg;
+ ioctl (hms_desc, TIOCGETP, &sg);
+#ifdef HAVE_TERMIO
+ sg.c_cc[VMIN] = 0; /* read with timeout. */
+ sg.c_cc[VTIME] = timeout * 10;
+ sg.c_lflag &= ~(ICANON | ECHO);
+ sg.c_cflag = (sg.c_cflag & ~CBAUD) | damn_b (baudrate);
+#else
+ sg.sg_ispeed = damn_b (baudrate);
+ sg.sg_ospeed = damn_b (baudrate);
+ sg.sg_flags |= RAW | ANYP;
+ sg.sg_flags &= ~ECHO;
+#endif
+
+ ioctl (hms_desc, TIOCSETP, &sg);
+}
+
+static void
+get_baudrate_right()
+{
+
+ int which_rate = 0;
+
+ while (!is_baudrate_right())
+ {
+ if (baudtab[which_rate].rate == -1)
+ {
+ which_rate = 0;
+ }
+ else
+ {
+ which_rate++;
+ }
+
+ baudrate = baudtab[which_rate].rate;
+ printf_filtered("Board not responding, trying %d baud\n",baudrate);
+ QUIT;
+ set_rate();
+ }
+}
+
static void
hms_open (name, from_tty)
char *name;
int from_tty;
{
- TERMINAL sg;
+
unsigned int prl;
char *p;
}
- printf("Input string %s\n", name);
-
- prog_name = get_word(&name);
-
hms_close (0);
hms_desc = open (dev_name, O_RDWR);
if (hms_desc < 0)
perror_with_name (dev_name);
- ioctl (hms_desc, TIOCGETP, &sg);
-#ifdef HAVE_TERMIO
- sg.c_cc[VMIN] = 0; /* read with timeout. */
- sg.c_cc[VTIME] = timeout * 10;
- sg.c_lflag &= ~(ICANON | ECHO);
- sg.c_cflag = (sg.c_cflag & ~CBAUD) | damn_b (baudrate);
-#else
- sg.sg_ispeed = damn_b (baudrate);
- sg.sg_ospeed = damn_b (baudrate);
- sg.sg_flags |= RAW | ANYP;
- sg.sg_flags &= ~ECHO;
-#endif
- ioctl (hms_desc, TIOCSETP, &sg);
+ set_rate();
+
+ dcache_init();
- push_target (&hms_ops);
/* start_remote (); /* Initialize gdb process mechanisms */
perror ("hms_open: error in signal");
#endif
-
- /* Put this port into NORMAL mode, send the 'normal' character */
- hms_write("\001", 1); /* Control A */
- hms_write("\r", 1); /* Cr */
- expect_prompt ();
+ get_baudrate_right();
/* Hello? Are you there? */
write (hms_desc, "\r", 1);
hms_clear_breakpoints();
- printf_filtered("Remote debugging on an H8/300 HMS via %s %s.\n",dev_name,prog_name);
+ printf_filtered("Remote debugging on an H8/300 HMS via %s.\n",dev_name);
DEXIT("hms_open()");
}
{
DENTER("hms_attach()");
- if (from_tty)
- printf_filtered ("Attaching to remote program %s.\n", prog_name);
/* push_target(&hms_ops); /* This done in hms_open() */
int step, sig;
{
DENTER("hms_resume()");
+ dcache_flush();
+
if (step)
{
hms_write_cr("s");
of the string cannot recur in the string, or we will not
find some cases of the string in the input. */
- static char bpt[] = "At breakpoint:";
+ static char bpt[] = "At breakpoint:\r";
/* It would be tempting to look for "\n[__exit + 0x8]\n"
but that requires loading symbols with "yc i" and even if
we did do that we don't know that the file has symbols. */
int ch_handled;
int old_timeout = timeout;
int old_immediate_quit = immediate_quit;
-
+ int swallowed_cr = 0;
+
DENTER("hms_wait()");
WSETEXIT ((*status), 0);
if (need_artificial_trap != 0)
- {
- WSETSTOP ((*status), SIGTRAP);
- need_artificial_trap--;
- return 0;
- }
+ {
+ WSETSTOP ((*status), SIGTRAP);
+ need_artificial_trap--;
+ return 0;
+ }
- timeout = 0; /* Don't time out -- user program is running. */
- immediate_quit = 1; /* Helps ability to QUIT */
+ timeout = 0; /* Don't time out -- user program is running. */
+ immediate_quit = 1; /* Helps ability to QUIT */
while (1) {
- QUIT; /* Let user quit and leave process running */
+ QUIT; /* Let user quit and leave process running */
ch_handled = 0;
ch = readchar ();
if (ch == *bp) {
bp++;
if (*bp == '\0')
- break;
+ break;
ch_handled = 1;
*swallowed_p++ = ch;
- } else
- bp = bpt;
+ } else
+ bp = bpt;
if (ch == *ep || *ep == '?') {
ep++;
if (*ep == '\0')
- break;
+ break;
if (!ch_handled)
- *swallowed_p++ = ch;
+ *swallowed_p++ = ch;
ch_handled = 1;
- }, sal.line);
-d979 3
+ } else
+ ep = exitmsg;
if (!ch_handled) {
char *p;
/* Print out any characters which have been swallowed. */
timeout = old_timeout;
immediate_quit = old_immediate_quit;
- printf ("%s is at %s:%d.\n",
- local_hex_string(sal.pc),
- sal.symtab->filename, sal.line);
DEXIT("hms_wait()");
return 0;
}
}
}
- printf ("Line %d of \"%s\" is at pc %s but contains no code.\n",
- sal.line, sal.symtab->filename, local_hex_string(start_pc));
+hms_write_cr(s)
+char *s;
{
hms_write( s, strlen(s));
- printf ("Line %d of \"%s\" starts at pc %s",
- sal.line, sal.symtab->filename,
- local_hex_string(start_pc));
- printf (" and ends at %s.\n",
- local_hex_string(end_pc));
+hms_write("\r",1);
+}
+
+static void
+hms_fetch_registers ()
{
#define REGREPLY_SIZE 79
char linebuf[REGREPLY_SIZE+1];
int s ;
int gottok;
- printf ("Line number %d is out of range for \"%s\".\n",
- sal.line, sal.symtab->filename);
+ REGISTER_TYPE reg[NUM_REGS];
+ int foo[8];
check_open();
do
int regno;
{
- printf ("Expression not found\n");
+ /* printf("hms_store_register() called.\n"); fflush(stdout); /* */
if (regno == -1)
hms_store_registers ();
else
addr = memaddr & - sizeof (int);
count = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
- printf ("Expression not found\n");
+
buffer = (int *)alloca (count * sizeof (int));
if (write)
{
/* Contributed by Steve Chamberlain sac@cygnus.com */
-#define IEEE_FLOAT 1
+
+#define UNSIGNED_SHORT(X) ((X) & 0xffff)
+
+
+#define EXTRA_FRAME_INFO \
+ struct frame_saved_regs *fsr; \
+ CORE_ADDR from_pc; \
+ CORE_ADDR args_pointer;\
+ CORE_ADDR locals_pointer ;
+
+
+
+/* Zero the frame_saved_regs pointer when the frame is initialized,
+ so that FRAME_FIND_SAVED_REGS () will know to allocate and
+ initialize a frame_saved_regs struct the first time it is called.
+ Set the arg_pointer to -1, which is not valid; 0 and other values
+ indicate real, cached values. */
+
+#define INIT_EXTRA_FRAME_INFO(fromleaf, fi) \
+ init_extra_frame_info (fromleaf, fi)
+
+extern void init_extra_frame_info ();
+
+
+#define IEEE_FLOAT
/* Define the bit, byte, and word ordering of the machine. */
#define TARGET_BYTE_ORDER BIG_ENDIAN
some instructions. */
#define SAVED_PC_AFTER_CALL(frame) \
-read_memory_integer (read_register (SP_REGNUM), 2)
+UNSIGNED_SHORT(read_memory_integer (read_register (SP_REGNUM), 2))
/* Stack grows downward. */
define this before including this file. */
-#define DECR_PC_AFTER_BREAK 2
+#define DECR_PC_AFTER_BREAK 0
/* Nonzero if instruction at PC is a return instruction. */
/* Store the address of the place in which to copy the structure the
subroutine will return. This is called from call_function. */
-#define STORE_STRUCT_RETURN(ADDR, SP) \
- { write_register (0, (ADDR)); abort(); }
+/*#define STORE_STRUCT_RETURN(ADDR, SP) \
+ { write_register (0, (ADDR)); abort(); }*/
/* Extract from an array REGBUF containing the (raw) register state
a function return value of type TYPE, and copy that, in virtual format,
- into VALBUF. This is assuming that floating point values are returned
- as doubles in d0/d1. */
-
+ into VALBUF. */
#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
- bcopy ((char *)(REGBUF) + \
- (TYPE_LENGTH(TYPE) >= 4 ? 0 : 4 - TYPE_LENGTH(TYPE)), \
- VALBUF, TYPE_LENGTH(TYPE))
+ bcopy ((char *)(REGBUF), VALBUF, TYPE_LENGTH(TYPE))
/* Write into appropriate registers a function return value
#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \
(FRAMELESS) = frameless_look_for_prologue(FI)
-#define FRAME_SAVED_PC(FRAME) (read_memory_integer ((FRAME)->frame + 2, 2))
+/* Any function with a frame looks like this
+ SECOND ARG
+ FIRST ARG
+ RET PC
+ SAVED R2
+ SAVED R3
+ SAVED FP <-FP POINTS HERE
+ LOCALS0
+ LOCALS1 <-SP POINTS HERE
+
+ */
+#define FRAME_SAVED_PC(FRAME) frame_saved_pc(FRAME)
-#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame)
+#define FRAME_ARGS_ADDRESS(fi) frame_args_address(fi)
-#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
+#define FRAME_LOCALS_ADDRESS(fi) frame_locals_address(fi);
/* Set VAL to the number of args passed to frame described by FI.
Can set VAL to -1, meaning no way to tell. */
/* Return number of bytes at start of arglist that are not really args. */
-#define FRAME_ARGS_SKIP 4
+#define FRAME_ARGS_SKIP 0
/* Put here the code to store, into a struct frame_saved_regs,
the addresses of the saved registers of frame described by FRAME_INFO.
ways in the stack frame. sp is even more special:
the address we return for it IS the sp for the next frame. */
-#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) abort();
+#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
+ frame_find_saved_regs(frame_info, &(frame_saved_regs))
\f
/* Push an empty stack frame, to record the current PC, etc. */
-#define PUSH_DUMMY_FRAME { h8300_push_dummy_frame (); }
+/*#define PUSH_DUMMY_FRAME { h8300_push_dummy_frame (); }*/
/* Discard from the stack the innermost frame, restoring all registers. */
#define SHORT_INT_MAX 32767
#define SHORT_INT_MIN -32768
-#undef longest_to_int
-#define longest_to_int(x) (x & 0xffff)
-
#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) \
{ bcopy ((FROM), (TO), 2); }
#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO) \
{ bcopy ((FROM), (TO), 4); }
+
+#define BEFORE_MAIN_LOOP_HOOK \
+ hms_before_main_loop();
+
+
+#define NAMES_HAVE_UNDERSCORE
+
+typedef unsigned short INSN_WORD;
else if (code == TYPE_CODE_PTR
|| code == TYPE_CODE_REF)
{
- if (len == sizeof (CORE_ADDR))
- {
- CORE_ADDR retval;
- bcopy (valaddr, &retval, sizeof (retval));
- SWAP_TARGET_AND_HOST (&retval, sizeof (retval));
- return retval;
- }
+ if (len == sizeof(long))
+ {
+ long retval;
+ bcopy (valaddr, &retval, sizeof(retval));
+ SWAP_TARGET_AND_HOST (&retval, sizeof(retval));
+ return retval;
+ }
+ else if (len == sizeof(short))
+ {
+ short retval;
+ bcopy (valaddr, &retval, len);
+ SWAP_TARGET_AND_HOST (&retval, len);
+ return retval;
+ }
}
else if (code == TYPE_CODE_MEMBER)
error ("not implemented: member types in unpack_long");