📄 remote-es1800.c
字号:
/* Memory-access and commands for remote es1800 processes, for GDB. Copyright (C) 1988, 1992 Free Software Foundation, Inc. This file is added to GDB to make it possible to do debugging via an ES-1800 emulator. The code was originally written by Johan Holmberg TT/SJ Ericsson Telecom AB and later modified byJohan Henriksson TT/SJ. It was modified for gdb 4.0 by TX/DK Jan Nordenand by TX/DKG Harald Johansen.This file is part of GDB.GDB is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 1, or (at your option)any later version.GDB is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GDB; see the file COPYING. If not, write tothe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. *//* Emulator communication protocol. All values are encoded in ascii hex digits. RequestCommandReply read registers:DR<cr> - 0 - - 1 - - 2 - - 3 - - 4 - - 5 - -- 6 - - 7 - D = XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXXA = XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX PC = XXXXXX SSP = XXXXXX USP = XXXXXX SR = XXXXXXXX >Each byte of register data is described by two hex digits. write regsD0=XXXXXXXX<cr> >D1=XXXXXXXX<cr> >D2=XXXXXXXX<cr> >D3=XXXXXXXX<cr> >D4=XXXXXXXX<cr> >D5=XXXXXXXX<cr> >D6=XXXXXXXX<cr> >D7=XXXXXXXX<cr> >A0=XXXXXXXX<cr> >A1=XXXXXXXX<cr> >A2=XXXXXXXX<cr> >A3=XXXXXXXX<cr> >A4=XXXXXXXX<cr> >A5=XXXXXXXX<cr> >A6=XXXXXXXX<cr> >A7=XXXXXXXX<cr> >SR=XXXXXXXX<cr> >PC=XXXXXX<cr> >Each byte of register data is described by two hex digits. read mem@.BAA..AA$FFFFFFXX >AA..AA is address, XXXXXXX is the contents write mem @.BAA..AA=$XXXXXXXX >AA..AA is address, XXXXXXXX is data contPC=$AA..AA >RBKR>AA..AA is address to resume. If AA..AA is omitted, resume at same address. stepPC=$AA..AA >STPR>AA..AA is address to resume. If AA..AA is omitted, resume at same address. kill reqSTP >*/#include <stdio.h>#include <signal.h>#include <sys/ioctl.h>#include <sys/file.h>#include <errno.h>#include <ctype.h>#include <string.h>#include <setjmp.h>#include <fcntl.h>#include "defs.h"#include "frame.h"#include "inferior.h"#include "target.h"#include "wait.h"#include "terminal.h"#include "command.h"#ifdef USG#include <sys/types.h>#include <sgtty.h>#endif#include <signal.h>/* External variables referenced. */extern bfd *exec_bfd;/* Prototypes for local functions */static voides1800_child_detach PARAMS ((char *, int));static voides1800_child_open PARAMS ((char *, int));static void es1800_transparent PARAMS ((char *, int));static voides1800_create_inferior PARAMS ((char *, char *, char **));static voides1800_load PARAMS ((char *, int));static voides1800_kill PARAMS ((void));static intverify_break PARAMS ((int));static intes1800_remove_breakpoint PARAMS ((CORE_ADDR, char *));static intes1800_insert_breakpoint PARAMS ((CORE_ADDR, char *));static voides1800_files_info PARAMS ((struct target_ops *));static intes1800_xfer_inferior_memory PARAMS ((CORE_ADDR, char *, int, int, struct target_ops *));static void es1800_prepare_to_store PARAMS ((void));static intes1800_wait PARAMS ((WAITTYPE *));static voides1800_resume PARAMS ((int, int));static voides1800_detach PARAMS ((char *, int));static voides1800_attach PARAMS ((char *, int));static intdamn_b PARAMS ((char *));static voides1800_open PARAMS ((char *, int));static voides1800_timer PARAMS ((void));static voides1800_reset PARAMS ((char *));static voides1800_request_quit PARAMS ((void));static intreadchar PARAMS ((void));static voidexpect PARAMS ((char *, int));static voidexpect_prompt PARAMS ((void));static voiddownload PARAMS ((FILE *, int, int));#if 0static voidbfd_copy PARAMS ((bfd *, bfd *));#endifstatic voidget_break_addr PARAMS ((int, CORE_ADDR *));static intfromhex PARAMS ((int));static inttohex PARAMS ((int));static voides1800_close PARAMS ((int));static voides1800_fetch_registers PARAMS ((void));static voides1800_fetch_register PARAMS ((int));static voides1800_store_register PARAMS ((int));static voides1800_read_bytes PARAMS ((CORE_ADDR, char *, int));static voides1800_write_bytes PARAMS ((CORE_ADDR, char *, int));static voidsend_with_reply PARAMS ((char *, char *, int));static voidsend_command PARAMS ((char *));static voidsend PARAMS ((char *));static voidgetmessage PARAMS ((char *, int));static voides1800_mourn_inferior PARAMS ((void));static voides1800_create_break_insn PARAMS ((char *, int));static voides1800_init_break PARAMS ((char *, int));/* Local variables */#define LOG_FILE "es1800.log"#if defined (LOG_FILE)static FILE *log_file;#endifextern struct target_ops es1800_ops; /* Forward decl */extern struct target_ops es1800_child_ops; /* Forward decl */static int kiodebug;static int timeout = 100; static char *savename; /* Name of i/o device used */static TERMINAL es1800_sg_save; /* Save stty state */static int es1800_fc_save; /* Save fcntl state *//* indicates that the emulator uses 32-bit data-adress (68020-mode) instead of 24-bit (68000 -mode) */static int m68020;#define MODE (m68020 ? "M68020" : "M68000" )#define ES1800_BREAK_VEC (0xf)/* Descriptor for I/O to remote machine. Initialize it to -1 so that es1800_open knows that we don't have a file open when the program starts. */static int es1800_desc = -1;#define PBUFSIZ 1000#define HDRLEN sizeof("@.BAAAAAAAA=$VV\r")/* Maximum number of bytes to read/write at once. The value here is chosen to fill up a packet. */#define MAXBUFBYTES ((PBUFSIZ-150)*16/75 )static int es1800_break_vec = 0;static char es1800_break_insn[2];static long es1800_break_address;static void (*old_sigint)(); /* Old signal-handler for sigint */static jmp_buf interrupt;/* Local signalhandler to allow breaking tranfers or program run. Rely on global variables: old_sigint(), interrupt */static voides1800_request_quit (){ /* restore original signalhandler */ signal (SIGINT, old_sigint); longjmp (interrupt, 1);}/* Reset emulator. Sending reset character(octal 32) to emulator. quit - return to '(esgdb)' prompt or continue */static voides1800_reset (quit) char *quit;{ char buf[80]; if (quit) { printf ("\nResetting emulator... "); } strcpy (buf, "\032"); send (buf); expect_prompt (); if (quit) { error ("done\n"); }}/* Called when SIGALRM signal sent due to alarm() timeout. Rely on global variables: timeout */#ifndef HAVE_TERMIOstatic voides1800_timer (){ if (kiodebug) { printf ("es1800_timer called\n"); } alarm (timeout);}#endif /* HAVE_TERMIO *//* Open a connection to a remote debugger and push the new target onto the stack. Check if the emulator is responding and find out what kind of processor the emulator is connected to. Initiate the breakpoint handling in the emulator. name - the filename used for communication (ex. '/dev/tta') from_tty - says whether to be verbose or not */static voides1800_open (name, from_tty) char *name; int from_tty;{ TERMINAL sg; char buf[PBUFSIZ]; char *p; int i, fcflag; char *baudrate; m68020 = 0; if (!name) /* no device name given in target command */ { error_no_arg ("serial port device name"); } baudrate = baud_rate ? baud_rate : "19200"; /* default baudrate = 19200 */ target_preopen (from_tty); es1800_close (0); /* open the device and configure it for communication */#ifndef DEBUG_STDIN es1800_desc = open (name, O_RDWR); if (es1800_desc < 0) { perror_with_name (name); } savename = savestring (name, strlen (name)); if (ioctl (es1800_desc, TIOCGETP, &sg) == -1) { perror_with_name (name); } es1800_sg_save = sg; if ((fcflag = fcntl (es1800_desc, F_GETFL, 0)) == -1) { perror_with_name ("fcntl serial"); } es1800_fc_save = fcflag; fcflag = (fcflag & (FREAD | FWRITE)); /* mask out any funny stuff */ if (fcntl (es1800_desc, F_SETFL, fcflag) == -1) { perror_with_name ("fcntl serial"); }#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 = CBREAK+TANDEM;#endif if ((ioctl (es1800_desc, TIOCSETP, &sg)) == -1) { perror ("es1800_open: error in ioctl"); }#endif /* DEBUG_STDIN */ push_target (&es1800_ops); /* Switch to using remote target now */ if (from_tty) { printf ("Remote ES1800 debugging using %s\n", name); }#ifndef HAVE_TERMIO#ifndef NO_SIGINTERRUPT /* Cause SIGALRM's to make reads fail with EINTR instead of resuming the read. */ if (siginterrupt (SIGALRM, 1) != 0) { perror ("es1800_open: error in siginterrupt"); }#endif /* NO_SIGINTERRUPT */ /* Set up read timeout timer. */ if ((void(*)()) signal (SIGALRM, es1800_timer) == (void(*)()) -1) { perror ("es1800_open: error in signal"); }#endif /* HAVE_TERMIO */#if defined (LOG_FILE) log_file = fopen (LOG_FILE, "w"); if (log_file == NULL) { perror_with_name (LOG_FILE); }#endif /* LOG_FILE */ /* Hello? Are you there?, also check mode */ /* send_with_reply( "DB 0 TO 1", buf, sizeof(buf)); */ /* for (p = buf, i = 0; *p++ =='0';) */ /* count the number of zeros */ /* i++; */ send ("\032"); getmessage (buf, sizeof (buf)); /* send reset character */ if (from_tty) { printf ("Checking mode.... "); } /* m68020 = (i==8); */ /* if eight zeros then we are in m68020 mode */ /* What kind of processor am i talking to ?*/ p = buf; while (*p++ != '\n') {;} while (*p++ != '\n') {;} while (*p++ != '\n') {;} for (i = 0; i < 20; i++, p++) {;} m68020 = !strncmp (p, "68020", 5); if (from_tty) { printf ("You are in %s(%c%c%c%c%c)-mode\n", MODE, p[0], p[1], p[2], p[3], p[4]); } /* if no init_break statement is present in .gdb file we have to check whether to download a breakpoint routine or not */#if 0 if ((es1800_break_vec == 0) || (verify_break (es1800_break_vec) != 0) && query ("No breakpoint routine in ES 1800 emulator!\nDownload a breakpoint routine to the emulator? ")) { CORE_ADDR memaddress; printf ("Give the start address of the breakpoint routine: "); scanf ("%li", &memaddress); es1800_init_break ((es1800_break_vec ? es1800_break_vec : ES1800_BREAK_VEC), memaddress); }#endif}/* Close out all files and local state before this target loses control. quitting - are we quitting gdb now? */static voides1800_close (quitting) int quitting;{ if (es1800_desc >= 0) { printf ("\nClosing connection to emulator...\n"); ioctl (es1800_desc, TIOCSETP, &es1800_sg_save); fcntl (es1800_desc,F_SETFL, es1800_fc_save); close (es1800_desc); es1800_desc = -1; } if (savename != NULL) { free (savename); } savename = NULL;#if defined (LOG_FILE) if (log_file != NULL) { if (ferror (log_file)) { printf ("Error writing log file.\n"); } if (fclose (log_file) != 0) { printf ("Error closing log file.\n"); } log_file = NULL; }#endif /* LOG_FILE */}/* damn_b() Translate baud rates from integers to damn B_codes. Unix should have outgrown this crap years ago, but even POSIX wouldn't buck it. rate - the baudrate given as a string return value: the baudrate as a B_code */#ifndef B19200# define B19200 EXTA#endif#ifndef B38400# define B38400 EXTB#endifstruct
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -