* 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.
This commit is contained in:
Steve Chamberlain 1992-02-06 20:03:31 +00:00
parent ab6c26bae1
commit 1f46923ff4
5 changed files with 784 additions and 184 deletions

View file

@ -1,3 +1,15 @@
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

View file

@ -1,5 +1,33 @@
/* 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
@ -10,11 +38,20 @@
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;
@ -24,15 +61,17 @@ CORE_ADDR start_pc;
start_pc+=2;
w = read_memory_integer(start_pc, 2);
}
return start_pc;
/* Skip past a move to FP */
if (IS_MOVE_FP(w)) {
start_pc +=2 ;
w = read_memory_integer(start_pc, 2);
}
return start_pc;
}
h8300_pop_frame()
{
printf("pop frame\n");
}
int
print_insn(memaddr, stream)
@ -42,18 +81,316 @@ FILE *stream;
/* 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()));
}
}

View file

@ -1,4 +1,4 @@
/* 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.
@ -55,22 +55,197 @@ static int hms_clear_breakpoints();
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 */
static int timeout = 5;
/* 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);
}
/***********************************************************************
* 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
@ -79,6 +254,8 @@ int hms_desc = -1;
#define OPEN(x) ((x) >= 0)
void hms_open();
#define ON 1
#define OFF 0
static void
@ -109,20 +286,6 @@ int turnon;
ioctl (desc, TIOCSETP, &sg);
}
/* Suck up all the input from the hms */
slurp_input()
{
char buf[8];
#ifdef HAVE_TERMIO
/* termio does the timeout for us. */
while (read (hms_desc, buf, 8) > 0);
#else
alarm (timeout);
while (read (hms_desc, buf, 8) > 0);
alarm (0);
#endif
}
/* Read a character from the remote system, doing all the fancy
timeout stuff. */
@ -138,24 +301,49 @@ readchar ()
#else
alarm (timeout);
if (read (hms_desc, &buf, 1) < 0)
{
if (errno == EINTR)
error ("Timeout reading from remote system.");
else
perror_with_name ("remote");
}
{
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.");
error ("Timeout reading from remote system.");
if (!quiet)
printf("'%c'",buf);
if (!quiet)
printf("%c",buf);
return buf & 0x7f;
}
static int
readchar_nofail ()
{
char buf;
buf = '\0';
#ifdef HAVE_TERMIO
/* termio does the timeout for us. */
read (hms_desc, &buf, 1);
#else
alarm (timeout);
if (read (hms_desc, &buf, 1) < 0)
{
return 0;
}
alarm (0);
#endif
if (buf == '\0')
{
return 0;
}
return buf & 0x7f;
}
/* Keep discarding input from the remote system, until STRING is found.
Let the user break out immediately. */
static void
@ -267,16 +455,10 @@ volatile int n_alarms;
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
@ -289,15 +471,16 @@ hms_kill(arg,from_tty)
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.
*/
@ -312,15 +495,14 @@ int fromtty;
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;
}
@ -366,7 +548,8 @@ hms_create_inferior (execfile, args, env)
error ("No exec file specified");
entry_pt = (int) bfd_get_start_address (exec_bfd);
check_open();
if (OPEN(hms_desc))
{
@ -376,28 +559,17 @@ hms_create_inferior (execfile, args, env)
/* 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()");
}
@ -412,22 +584,12 @@ hms_create_inferior (execfile, args, env)
#endif
static struct {int rate, damn_b;} baudtab[] = {
{0, B0},
{50, B50},
{75, B75},
{110, B110},
{134, B134},
{150, B150},
{200, B200},
{300, B300},
{600, B600},
{1200, B1200},
{1800, B1800},
{2400, B2400},
{4800, B4800},
{9600, B9600},
{19200, B19200},
{38400, B38400},
{300, B300},
{1200, B1200},
{2400, B2400},
{4800, B4800},
{-1, -1},
};
@ -438,7 +600,7 @@ static int damn_b (rate)
for (i = 0; baudtab[i].rate != -1; i++)
if (rate == baudtab[i].rate) return baudtab[i].damn_b;
return B38400; /* Random */
return B19200;
}
@ -485,31 +647,32 @@ char **p;
}
static int baudrate = 9600;
static void
hms_open (name, from_tty)
char *name;
int from_tty;
{
TERMINAL sg;
unsigned int prl;
char *p;
DENTER("hms_open()");
if(name == 0)
{
name = "";
}
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);
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. */
@ -524,9 +687,59 @@ hms_open (name, from_tty)
#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;
{
unsigned int prl;
char *p;
DENTER("hms_open()");
if(name == 0)
{
name = "";
}
hms_close (0);
hms_desc = open (dev_name, O_RDWR);
if (hms_desc < 0)
perror_with_name (dev_name);
set_rate();
dcache_init();
push_target (&hms_ops);
/* start_remote (); /* Initialize gdb process mechanisms */
@ -543,11 +756,7 @@ hms_open (name, from_tty)
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);
@ -558,7 +767,7 @@ hms_open (name, from_tty)
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()");
}
@ -603,8 +812,6 @@ hms_attach (args, from_tty)
{
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() */
@ -655,6 +862,8 @@ hms_resume (step, sig)
int step, sig;
{
DENTER("hms_resume()");
dcache_flush();
if (step)
{
hms_write_cr("s");
@ -686,7 +895,7 @@ hms_wait (status)
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. */
@ -703,43 +912,44 @@ hms_wait (status)
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. */
@ -769,9 +979,6 @@ d979 3
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;
}
@ -851,15 +1058,15 @@ if (!quiet)
}
}
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];
@ -867,8 +1074,8 @@ hms_write( s, strlen(s));
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
@ -942,7 +1149,7 @@ hms_store_register (regno)
int regno;
{
printf ("Expression not found\n");
/* printf("hms_store_register() called.\n"); fflush(stdout); /* */
if (regno == -1)
hms_store_registers ();
else
@ -1020,7 +1227,7 @@ hms_xfer_inferior_memory(memaddr, myaddr, len, write, target)
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)
{

View file

@ -19,7 +19,31 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* 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
@ -46,7 +70,7 @@ extern CORE_ADDR h8300_skip_prologue ();
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. */
@ -69,7 +93,7 @@ read_memory_integer (read_register (SP_REGNUM), 2)
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. */
@ -157,19 +181,15 @@ read_memory_integer (read_register (SP_REGNUM), 2)
/* 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
@ -220,11 +240,22 @@ read_memory_integer (read_register (SP_REGNUM), 2)
#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. */
@ -237,7 +268,7 @@ read_memory_integer (read_register (SP_REGNUM), 2)
/* 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.
@ -245,12 +276,13 @@ read_memory_integer (read_register (SP_REGNUM), 2)
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))
/* 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. */
@ -259,11 +291,16 @@ read_memory_integer (read_register (SP_REGNUM), 2)
#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;

View file

@ -690,13 +690,20 @@ unpack_long (type, valaddr)
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");