From 1f46923ff419face15f7232a8c33efc5beecea15 Mon Sep 17 00:00:00 2001 From: Steve Chamberlain Date: Thu, 6 Feb 1992 20:03:31 +0000 Subject: [PATCH] * 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. --- gdb/ChangeLog | 12 ++ gdb/h8300-tdep.c | 369 +++++++++++++++++++++++++++++++++++++++++-- gdb/remote-hms.c | 467 +++++++++++++++++++++++++++++++++++++++---------------- gdb/tm-h8300.h | 77 ++++++--- gdb/values.c | 21 ++- 5 files changed, 773 insertions(+), 173 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 5a7f166..97e9893 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -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 diff --git a/gdb/h8300-tdep.c b/gdb/h8300-tdep.c index 50a0092..4983e34 100644 --- a/gdb/h8300-tdep.c +++ b/gdb/h8300-tdep.c @@ -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 #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,16 +61,18 @@ CORE_ADDR start_pc; 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; @@ -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())); + + } + +} diff --git a/gdb/remote-hms.c b/gdb/remote-hms.c index 19df127..48df7a7 100644 --- a/gdb/remote-hms.c +++ b/gdb/remote-hms.c @@ -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 */ + +/* 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<>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= 0) +void hms_open(); + #define ON 1 #define OFF 0 static void @@ -109,25 +286,41 @@ int turnon; 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; @@ -138,21 +331,16 @@ 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"); - } + { + 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; } @@ -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}, + {9600, B9600}, + {19200, B19200}, {300, B300}, - {600, B600}, {1200, B1200}, - {1800, B1800}, {2400, B2400}, {4800, B4800}, - {9600, B9600}, - {19200, B19200}, - {38400, B38400}, {-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,12 +647,78 @@ char **p; } 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; @@ -501,32 +729,17 @@ hms_open (name, from_tty) } - 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 */ @@ -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) { diff --git a/gdb/tm-h8300.h b/gdb/tm-h8300.h index 1409dcc..330576e 100644 --- a/gdb/tm-h8300.h +++ b/gdb/tm-h8300.h @@ -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; diff --git a/gdb/values.c b/gdb/values.c index 2c8143d..e3c3187 100644 --- a/gdb/values.c +++ b/gdb/values.c @@ -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"); -- 2.7.4