⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gdb_interface.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 1996-1998 by the Board of Trustees *    of Leland Stanford Junior University. *  * This file is part of the SimOS distribution.  * See LICENSE file for terms of the license.  * *//***************************************************************** * Interface to GDB. For debugging OS or Apps ontop of simulator. *****************************************************************/#ifndef _LONGLONG#define _LONGLONG#endif#define R4000 1#include <sys/types.h>#include <sys/file.h>#include <unistd.h>#include <sys/socket.h>#include <memory.h>#include <sys/mman.h>#include <sys/signal.h>#include <sys/time.h>#include <netinet/in.h>#include <netinet/tcp.h>#include <string.h>#include "simutil.h"#include <setjmp.h>#include "sim.h"#include "simtypes.h"#include "syslimits.h"#include "arch_specifics.h"#include "machine_params.h"#include "cpu_interface.h"#include "sim_error.h"#include "gdb_interface.h"static int sfd;   /* Open socket for connection */static int rfd = -1;   /* Open fd for connection */static int debug_from_poll = 0;  /* we entered the debugger because the                                  * poll on the socket showed something                                   */static int remote_debug = 0;static int AttachGdb(int sfd, int fdactive);static int read_cpu(char* buf);static int fromhex(int);static int tohex(int);static int putpkt(int fd, char *buf);static int readchar(int fd);static int getpkt(int fd, char *buf);static void write_ok(char *buf);static void write_enn(char *buf);static void convert_int_to_ascii(char *from, char *to, int n);static void convert_ascii_to_int(char *from, char *to, int n);static int read_memory(char* buf, VA memaddr, unsigned int len, uint cpuno);static int write_memory(char* buf, VA memaddr, unsigned int len, uint cpuno);static char* findchar(char* s, int c);static void prepare_resume_reply(char *buf, unsigned int sig, unsigned int cpuno);int DebugPort;    /* default value */#ifdef __alpha#define  MEMORY_SCANF "%x,%lx,%x"#else#define  MEMORY_SCANF "%x,%llx,%x"#endif/***************************************************************** * Simdebug_init * * Initialize the debugger c module.  *****************************************************************/voidSimdebug_init(void){   struct sockaddr_in sockaddr;   int tmp;      if (!DebugPort) {      return;   }   sfd = socket (PF_INET, SOCK_STREAM, 0);   if (sfd < 0) {      CPUWarning("Can't open debug socket");      ASSERT(0);      return;   }      /* Allow rapid reuse of this port. */   tmp = 1;   if (setsockopt (sfd, SOL_SOCKET, SO_REUSEADDR, (char *)&tmp, sizeof(tmp)) < 0) {      CPUWarning("simdebug setsockopt SO_REUSEADDR");      /* Not fatal */   }   bzero((char *)&sockaddr, sizeof(struct sockaddr_in));    sockaddr.sin_family = PF_INET;   sockaddr.sin_port = htons(DebugPort);   sockaddr.sin_addr.s_addr = INADDR_ANY;      while (bind (sfd, (struct sockaddr *)&sockaddr, sizeof (sockaddr)) || listen (sfd, 1)) {      DebugPort++;      sockaddr.sin_port = htons(DebugPort);   }}/**************************************************************** * AttachGdb * ****************************************************************/static intAttachGdb(int fd, int fdactive){   struct sockaddr_in sockaddr;   int tmp;   int gdb_fd;   if (!fdactive)      CPUWarning("\nEnter debugger, port = %d, waiting...\n ", DebugPort);   tmp = sizeof (sockaddr);   gdb_fd  = accept (fd, (struct sockaddr *)&sockaddr, &tmp);   if (gdb_fd == -1) {      CPUWarning("Debugger accept failed\n");      return gdb_fd;   }      if (!fdactive)      CPUWarning("attached\n");   /* Tell TCP not to delay small packets.  This greatly speeds up      interactive response. */   tmp = 1;   setsockopt (gdb_fd, IPPROTO_TCP, TCP_NODELAY,               (char *)&tmp, sizeof(tmp));   return gdb_fd;}/***************************************************************** * Simdebug_pollfd and Simdebug_fdactive * * someone needs to poll the gdb connection if it is open in case * the user types ^C.  This is currently piggy-backed onto the * select polling done by the Visual control subsystem * (see visual.c::VisualControl). * * when the gdb connection is closed, we poll the listener fd (sfd) * so a gdb attach request causes us to enter the debugger immediately. * *****************************************************************/int Simdebug_pollfd(void){   if (rfd != -1) {      return rfd;   } else {      return sfd;   }}void Simdebug_fdactive(void){   /* gdb sent us something.  This won't get called in the    * middle of Simdebug_run because the debug run loop owns    * the system during that time, so the visual callback won't    * happen.     *    * That's good, because on embra this passes through a few    * functions and calls right into simdebug_run.    */   if (remote_debug) {      CPUWarning("Simdebug_fdactive: poll saw data on debugger port\n");   }   debug_from_poll = 1;   CPUVec.Handle_Debug_Signal(-1, 0);  /* -1 => any cpu, 0 => this                                        * is a direct debug request,                                        * not a signal that should                                        * fire the sigusr annotation                                        */}static int CanSingleStep(CPUType cpuType){#if defined(SIM_MIPS32) || defined(SIM_MIPS64)    return (cpuType == MIPSY);#elif defined(SIM_X86)    return (cpuType == X86SIM);#else    return 0;#endif}/***************************************************************** * Simdebug_run *  * Main call to handle the simulator side of a gdb session. *****************************************************************/Simdebug_resultSimdebug_run(int sig, int start_cpuno){   char *b;   static char cmd_buf[BUFSIZ+1];   int i = 0;   Simdebug_result ret = SD_CONTINUE;   int pid;   unsigned int cpuno        = 0; /* current cpu number */      if (remote_debug) {      CPUWarning("Simdebug_run: sig %d, start_cpuno %d\n", sig, start_cpuno);   }   if (rfd <= 0) {      /* establishing a new connection.  GDB does not expect to see       * a reason-for-stop packet 'S' in this initial setup transaction.       */      rfd = AttachGdb(sfd, debug_from_poll);      if (rfd < 0) {         return SD_CONTINUE;	 /* could not get debugger */      }      debug_from_poll = 0;   /* whether or not we entered from poll doesn't                              * matter this time, but we'd better reset it                              * before next time this function runs                              */   } else {      /* reestablish an old connection.  We might get here either       * for internal reasons (hitting a breakpoint) or for external       * reasons (gdb sent us a ^C).  If external, we need to swallow       * the break packet.  Then in either case, let GDB know why       * we stopped.       */      if (debug_from_poll) {         debug_from_poll = 0;         if (getpkt (rfd, cmd_buf) < 0) goto errout;         /* the only thing we expect to see when polling is the          * break instruction          */         if (cmd_buf[0] != 'b') {            CPUWarning("Simdebug_run: unexpected command from gdb, expected ^C\n");         }         /* make gdb happy: it sent a ^C so it should get one back */         sig = SIGINT;      }      /* Inform the remote debugger we have entered debugging mode. */      sprintf (cmd_buf, "S%02x%02x", sig, start_cpuno);      if (putpkt (rfd, cmd_buf) < 0) goto errout;   }   while (1) {      char ch;      i = 0;      if (getpkt (rfd, cmd_buf) < 0) goto errout;      if (remote_debug) {         CPUWarning( "GETPKT: %s\n", cmd_buf);      }            ch = cmd_buf[i++];      SIM_DEBUG(('g', "gdb command %c \n",ch));      switch (ch) {      case '?':         prepare_resume_reply (cmd_buf, sig, start_cpuno);         break;      case 'b':         /* nop: this is the packet sent when the user types ^C. No          * effect during main loop          */         write_enn (cmd_buf);         break;      case 'g': {         int i;         cpuno = read_cpu(cmd_buf+1);         if (cpuno >= TOTAL_CPUS) {            write_enn (cmd_buf);         } else {            Reg r=0;            b = cmd_buf;            for (i = 0; i < GDB_NUM_REGS; i++) {               if (CPUVec.GetRegister(cpuno, i, &r) == FAILURE) {                  r = 0;               }	       /*		* flip the bytes around 		*/#if  defined(SIM_ALPHA) || defined(SIM_MIPS64)               /*                * bugnion:                 * 64 bit support                * actually, the ifdef should be based on which remote gdb we                * are talking to. Maybe a good thing to have an exchange protocol                * at startup to make sure that gdb is not going to be confused                */	       r = HO2MO_8(r);               convert_int_to_ascii ((char *) &r, b, 4*2);                b += 8*2;#else	       r = HO2MO_4((int)r);               convert_int_to_ascii ((char *) &r, b, 4);                b += 8;#endif            }            *b = 0;         }         break;      }      case 'G': {         cpuno = read_cpu(cmd_buf+1);         if (cpuno >= TOTAL_CPUS) {            write_enn (cmd_buf);         } else {            int succeeded = 1;            b = cmd_buf + 3;            for (i = 0; i < GDB_NUM_REGS; i++) {               unsigned int reg = 0;#if defined(SIM_ALPHA) || defined(SIM_MIPS64)               convert_ascii_to_int (b, (char *) &reg, 4*2);	       reg = MO2HO_8(reg);               if (CPUVec.PutRegister(cpuno, i, reg) == FAILURE) {               }               b += 8*2;#else               convert_ascii_to_int (b, (char *) &reg, 4);	       reg = MO2HO_4(reg);               if (CPUVec.PutRegister(cpuno, i, (Reg)(Reg32_s)reg) == FAILURE) {               }               b += 8;#endif            }            if (succeeded) {               write_ok (cmd_buf);            } else {               write_enn (cmd_buf);            }         }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -