Changeset 1bbe2e1 in rtems


Ignore:
Timestamp:
Feb 27, 2002, 10:32:15 PM (19 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, 5, master
Children:
c52f1c7
Parents:
3f1c124
Message:

2001-02-27 Joel Sherrill <joel@…>

  • Significant modifications including adding thread support, the 'X' command, and reorganizing so that target CPU independent routines could be reused.
  • gdb_if.h: Added numerous prototypes.
  • mips-stub.c: Added thread support as well as 'X' command. Also noticed that the 'P' command was from the mips protocol.
  • rtems-stub-glue.c: New file. This file contains all generic support which should be able to be reused on another target CPU.
Location:
c/src/lib/libbsp
Files:
2 added
3 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/mips/shared/gdbstub/ChangeLog

    r3f1c124 r1bbe2e1  
     12001-02-27      Joel Sherrill <joel@OARcorp.com>
     2
     3        * Significant modifications including adding thread support, the 'X'
     4        command, and reorganizing so that target CPU independent routines
     5        could be reused.
     6        * gdb_if.h: Added numerous prototypes.
     7        * mips-stub.c: Added thread support as well as 'X' command.
     8        Also noticed that the 'P' command was from the mips protocol.
     9        * rtems-stub-glue.c: New file.  This file contains all generic
     10        support which should be able to be reused on another target CPU.
     11
    1122002-02-08      Joel Sherrill <joel@OARcorp.com>
    213
  • c/src/lib/libbsp/mips/shared/gdbstub/gdb_if.h

    r3f1c124 r1bbe2e1  
    1717#ifndef _GDB_IF_H
    1818#define _GDB_IF_H
     19
     20/* Max number of threads in qM response */
     21#define QM_MAX_THREADS (20)
     22
     23struct rtems_gdb_stub_thread_info {
     24  char display[256];
     25  char name[256];
     26  char more_display[256];
     27};
     28
     29/*
     30 *  Prototypes
     31 */
     32
     33int parse_zbreak(const char *in, int *type, unsigned char **addr, int *len);
     34
     35
     36char* mem2hstr(char *buf, const unsigned char *mem, int count);
     37int   hstr2mem(unsigned char *mem, const char *buf, int count);
     38void  set_mem_err(void);
     39unsigned char get_byte(const unsigned char *ptr);
     40void  set_byte(unsigned char *ptr, int val);
     41char* thread2vhstr(char *buf, int thread);
     42char* thread2fhstr(char *buf, int thread);
     43const char* fhstr2thread(const char *buf, int *thread);
     44const char* vhstr2thread(const char *buf, int *thread);
     45char* int2fhstr(char *buf, int val);
     46char* int2vhstr(char *buf, int vali);
     47const char* fhstr2int(const char *buf, int *ival);
     48const char* vhstr2int(const char *buf, int *ival);
     49int   hstr2byte(const char *buf, int *bval);
     50int   hstr2nibble(const char *buf, int *nibble);
     51
     52int rtems_gdb_stub_thread_support_ok(void);
     53int rtems_gdb_stub_get_current_thread(void);
     54int rtems_gdb_stub_get_next_thread(int);
     55int rtems_gdb_stub_get_offsets(
     56  unsigned char **text_addr,
     57  unsigned char **data_addr,
     58  unsigned char **bss_addr
     59);
     60int rtems_gdb_stub_get_thread_regs(
     61  int thread,
     62  unsigned int *registers
     63);
     64int rtems_gdb_stub_set_thread_regs(
     65  int thread,
     66  unsigned int *registers
     67);
     68void rtems_gdb_process_query(
     69  char *inbuffer,
     70  char *outbuffer,
     71  int   do_threads,
     72  int   thread
     73);
    1974
    2075/*
  • c/src/lib/libbsp/mips/shared/gdbstub/mips-stub.c

    r3f1c124 r1bbe2e1  
     1#define  GDB_STUB_ENABLE_THREAD_SUPPORT 1
    12/*******************************************************************************
    23
     
    127128#include <rtems.h>
    128129#include "gdb_if.h"
     130
     131extern int printk(const char *fmt, ...);
     132
     133/* Change it to something meaningful when debugging */
     134#undef ASSERT
     135#define ASSERT(x) if(!(x)) printk("ASSERT: stub: %d\n", __LINE__)
    129136
    130137/***************/
     
    186193#if (__mips == 3)
    187194typedef long long mips_register_t;
     195#define R_SZ 8
    188196#elif (__mips == 1)
    189197typedef unsigned int mips_register_t;
     198#define R_SZ 4
    190199#else
    191200#error "unknown MIPS ISA"
     
    193202static mips_register_t *registers;
    194203
     204#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
     205static char do_threads;      /* != 0 means we are supporting threads */
     206#endif
    195207
    196208/*
     
    212224static char outBuffer[BUFMAX];
    213225
     226/* Structure to keep info on a z-breaks */
     227#define BREAKNUM 32
     228struct z0break
     229{
     230  /* List support */
     231  struct z0break *next;
     232  struct z0break *prev;
     233
     234  /* Location, preserved data */
     235  unsigned char *address;
     236  char     buf[2];
     237};
     238
     239static struct z0break z0break_arr[BREAKNUM];
     240static struct z0break *z0break_avail = NULL;
     241static struct z0break *z0break_list  = NULL;
     242
    214243
    215244
     
    217246 * Convert an int to hex.
    218247 */
    219 static const char hexchars[] = "0123456789abcdef";
    220 
    221 #define highhex(x) hexchars [(x >> 4) & 0xf]
    222 #define lowhex(x) hexchars [x & 0xf]
     248const char gdb_hexchars[] = "0123456789abcdef";
     249
     250#define highhex(x) gdb_hexchars [(x >> 4) & 0xf]
     251#define lowhex(x) gdb_hexchars [x & 0xf]
    223252
    224253
     
    228257 */
    229258static char *
    230 mem2hex (int addr, int length, char *buf)
    231 {
     259mem2hex (void *_addr, int length, char *buf)
     260{
     261  unsigned int addr = (unsigned int) _addr;
     262
    232263  if (((addr & 0x7) == 0) && ((length & 0x7) == 0))      /* dword aligned */
    233264    {
     
    241272
    242273          for (i = 15; i >= 0; i--)
    243             *buf++ = hexchars [(k >> (i*4)) & 0xf];
     274            *buf++ = gdb_hexchars [(k >> (i*4)) & 0xf];
    244275        }
    245276    }
     
    255286
    256287          for (i = 7; i >= 0; i--)
    257             *buf++ = hexchars [(k >> (i*4)) & 0xf];
     288            *buf++ = gdb_hexchars [(k >> (i*4)) & 0xf];
    258289        }
    259290    }
     
    269300
    270301          for (i = 3; i >= 0; i--)
    271             *buf++ = hexchars [(k >> (i*4)) & 0xf];
     302            *buf++ = gdb_hexchars [(k >> (i*4)) & 0xf];
    272303        }
    273304    }
     
    283314
    284315          for (i = 1; i >= 0; i--)
    285             *buf++ = hexchars [(k >> (i*4)) & 0xf];
     316            *buf++ = gdb_hexchars [(k >> (i*4)) & 0xf];
    286317        }
    287318    }
     
    376407 */
    377408static int
    378 hex2mem (char *buf, int addr, int length)
    379 {
     409hex2mem (char *buf, void *_addr, int length)
     410{
     411  unsigned int addr = (unsigned int) _addr;
    380412  if (((addr & 0x7) == 0) && ((length & 0x7) == 0))      /* dword aligned */
    381413    {
     
    453485  return 1;
    454486}
     487
     488
     489/* Convert the binary stream in BUF to memory.
     490
     491   Gdb will escape $, #, and the escape char (0x7d).
     492   COUNT is the total number of bytes to write into
     493   memory. */
     494static unsigned char *
     495bin2mem (
     496  unsigned char *buf,
     497  unsigned char *mem,
     498  int   count
     499)
     500{
     501  int i;
     502
     503  for (i = 0; i < count; i++) {
     504      /* Check for any escaped characters. Be paranoid and
     505         only unescape chars that should be escaped. */
     506      if (*buf == 0x7d) {
     507          switch (*(buf+1)) {
     508            case 0x3:  /* # */
     509            case 0x4:  /* $ */
     510            case 0x5d: /* escape char */
     511              buf++;
     512              *buf |= 0x20;
     513              break;
     514            default:
     515              /* nothing */
     516              break;
     517            }
     518        }
     519
     520      *mem++ = *buf++;
     521    }
     522
     523  return mem;
     524}
     525
    455526
    456527
     
    780851}
    781852
     853/*
     854 *  This support function prepares and sends the message containing the
     855 *  basic information about this exception.
     856 */
     857
     858void gdb_stub_report_exception_info(
     859  rtems_vector_number vector,
     860  CPU_Interrupt_frame *frame,
     861  int                  thread
     862)
     863{
     864  char *optr;
     865  int sigval;
     866
     867  optr = outBuffer;
     868  *optr++ = 'T';
     869  sigval = computeSignal ();
     870  *optr++ = highhex (sigval);
     871  *optr++ = lowhex (sigval);
     872
     873  *optr++ = gdb_hexchars[SP];
     874  *optr++ = ':';
     875  optr    = mem2hstr(optr, (unsigned char *)&frame->sp, R_SZ );
     876  *optr++ = ';';
     877 
     878  *optr++ = gdb_hexchars[PC];
     879  *optr++ = ':';
     880  optr    = mem2hstr(optr, (unsigned char *)&frame->sp, R_SZ );
     881  *optr++ = ';';
     882
     883#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
     884  if (do_threads) {
     885    *optr++ = 't';
     886    *optr++ = 'h';
     887    *optr++ = 'r';
     888    *optr++ = 'e';
     889    *optr++ = 'a';
     890    *optr++ = 'd';
     891    *optr++ = ':';
     892    optr   = thread2vhstr(optr, thread);
     893    *optr++ = ';';
     894  }
     895#endif
     896  putpacket (outBuffer);
     897 
     898  *optr++ = '\0';
     899}
     900
     901
    782902
    783903
     
    787907 * reacts to gdb's requests.
    788908 */
     909
     910CPU_Interrupt_frame current_thread_registers;
     911
    789912void handle_exception (rtems_vector_number vector, CPU_Interrupt_frame *frame)
    790913{
    791914  int host_has_detached = 0;
    792   int sigval;
    793915  int regno, addr, length;
    794916  long long regval;
    795917  char *ptr;
     918  int  current_thread;  /* current generic thread */
     919  int  thread;          /* stopped thread: context exception happened in */
     920  void *regptr;
     921  int  binary;
    796922
    797923  registers = (mips_register_t *)frame;
    798924
    799   /* reply to host that an exception has occurred */
    800   sigval = computeSignal ();
    801   outBuffer[0] = 'S';
    802   outBuffer[1] = highhex (sigval);
    803   outBuffer[2] = lowhex (sigval);
    804   outBuffer[3] = '\0';
    805 
    806   putpacket (outBuffer);
     925  thread = 0;
     926#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
     927  if (do_threads) {
     928    thread = rtems_gdb_stub_get_current_thread();
     929  }
     930#endif
     931  current_thread = thread;
     932
     933  /* reply to host that an exception has occurred with some basic info */
     934  gdb_stub_report_exception_info(vector, frame, thread);
     935
    807936
    808937  /*
     
    812941  undoSStep ();
    813942
    814   while (!(host_has_detached))
    815     {
     943  while (!(host_has_detached)) {
    816944      outBuffer[0] = '\0';
    817945      getpacket (inBuffer);
    818 
    819       switch (inBuffer[0])
    820         {
     946      binary = 0;
     947
     948      switch (inBuffer[0]) {
    821949        case '?':
    822           outBuffer[0] = 'S';
    823           outBuffer[1] = highhex (sigval);
    824           outBuffer[2] = lowhex (sigval);
    825           outBuffer[3] = '\0';
    826           break;
    827 
    828         case 'd':
    829           /* toggle debug flag */
    830           break;
    831 
    832         case 'g':
    833           /* return the values of the CPU registers */
    834           mem2hex ((int) registers, sizeof registers, outBuffer);
    835           break;
    836 
    837         case 'G':
    838           /* set the values of the CPU registers - return OK */
    839           if (hex2mem (&inBuffer[1], (int) registers, sizeof registers))
     950          gdb_stub_report_exception_info(vector, frame, thread);
     951          break;
     952
     953        case 'd': /* toggle debug flag */
     954          /* can print ill-formed commands in valid packets & checksum errors */
     955          break;
     956
     957        case 'D':
     958          /* remote system is detaching - return OK and exit from debugger */
     959          strcpy (outBuffer, "OK");
     960          host_has_detached = 1;
     961          break;
     962
     963        case 'g':               /* return the values of the CPU registers */
     964          regptr = registers;
     965#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
     966          if (do_threads && current_thread != thread )
     967             regptr = &current_thread_registers;
     968#endif
     969          mem2hex (regptr, NUM_REGS * (sizeof registers), outBuffer);
     970
     971          break;
     972
     973        case 'G':       /* set the values of the CPU registers - return OK */
     974          regptr = registers;
     975#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
     976          if (do_threads && current_thread != thread )
     977             regptr = &current_thread_registers;
     978#endif
     979          if (hex2mem (&inBuffer[1], regptr, NUM_REGS * (sizeof registers)))
    840980              strcpy (outBuffer, "OK");
    841981          else
     
    8651005              && is_readable (addr, length)
    8661006              && (length < (BUFMAX - 4)/2))
    867             mem2hex (addr, length, outBuffer);
     1007            mem2hex ((void *)addr, length, outBuffer);
    8681008          else
    8691009            strcpy (outBuffer, "E01"); /* E01 = bad 'm' command */
    8701010          break;
    8711011
     1012        case 'X':  /* XAA..AA,LLLL:<binary data>#cs */
     1013          binary = 1;
    8721014        case 'M':
    8731015          /* MAA..AA,LLLL:  Write LLLL bytes at address AA..AA - return OK */
     
    8771019              && hexToInt (&ptr, &length)
    8781020              && *ptr++ == ':'
    879               && is_writeable (addr, length)
    880               && hex2mem (ptr, addr, length))
    881             strcpy (outBuffer, "OK");
     1021              && is_writeable (addr, length) ) {
     1022              if ( binary )
     1023                hex2mem (ptr, (void *)addr, length);
     1024              else
     1025                bin2mem (ptr, (void *)addr, length);
     1026              strcpy (outBuffer, "OK");
     1027          }
    8821028          else
    8831029            strcpy (outBuffer, "E02"); /* E02 = bad 'M' command */
     
    8991045          return;
    9001046
    901         case 'D':
    902           /* remote system is detaching - return OK and exit from debugger */
    903           strcpy (outBuffer, "OK");
    904           host_has_detached = 1;
    905           break;
    906 
    907         default:
    908           /* do nothing */
    909           break;
    910         }                       /* switch */
     1047        case 'k':  /* remove all zbreaks if any */
     1048          {
     1049            int ret;
     1050            struct z0break *z0, *z0last;
     1051
     1052            ret = 1;
     1053            z0last = NULL;
     1054
     1055            for (z0=z0break_list; z0!=NULL; z0=z0->next) {
     1056                if (!hstr2mem(z0->address, z0->buf, 1)) {
     1057                   ret = 0;
     1058                }
     1059
     1060                z0last = z0;
     1061            }
     1062
     1063            /* Free entries if any */
     1064            if (z0last != NULL) {
     1065              z0last->next  = z0break_avail;
     1066              z0break_avail = z0break_list;
     1067              z0break_list  = NULL;
     1068            }
     1069          }
     1070
     1071          break;
     1072
     1073        case 'q':   /* queries */
     1074#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
     1075          rtems_gdb_process_query( inBuffer, outBuffer, do_threads, thread );
     1076#endif
     1077          break;
     1078       
     1079        case 'H':  /* set new thread */
     1080#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
     1081          if (inBuffer[1] != 'g') {
     1082            break;
     1083          }
     1084         
     1085          if (!do_threads) {
     1086            break;
     1087          }
     1088         
     1089          {
     1090            int tmp, ret;
     1091           
     1092            /* Set new generic thread */
     1093            if (vhstr2thread(&inBuffer[2], &tmp) == NULL) {
     1094              strcpy(outBuffer, "E01");
     1095              break;
     1096            }
     1097
     1098            /* 0 means `thread' */
     1099            if (tmp == 0) {
     1100              tmp = thread;
     1101            }
     1102
     1103            if (tmp == current_thread) {
     1104              /* No changes */
     1105              strcpy(outBuffer, "OK");
     1106              break;
     1107            }
     1108
     1109            /* Save current thread registers if necessary */
     1110            if (current_thread != thread) {
     1111              ret = rtems_gdb_stub_set_thread_regs(
     1112                   current_thread, (unsigned int *) &current_thread_registers);
     1113              ASSERT(ret);
     1114            }
     1115
     1116            /* Read new registers if necessary */
     1117            if (tmp != thread) {
     1118                ret = rtems_gdb_stub_get_thread_regs(
     1119                    tmp, (unsigned int *) &current_thread_registers);
     1120
     1121                if (!ret) {
     1122                  /* Thread does not exist */
     1123                  strcpy(outBuffer, "E02");
     1124                  break;
     1125                }
     1126            }
     1127           
     1128            current_thread = tmp;
     1129            strcpy(outBuffer, "OK");
     1130          }
     1131
     1132#endif
     1133          break;
     1134
     1135        case 'Z':  /* Add breakpoint */
     1136          {
     1137            int ret, type, len;
     1138            unsigned char *address;
     1139            struct z0break *z0;
     1140
     1141            ret = parse_zbreak(inBuffer, &type, &address, &len);
     1142            if (!ret) {
     1143              strcpy(outBuffer, "E01");
     1144              break;
     1145            }
     1146
     1147            if (type != 0) {
     1148              /* We support only software break points so far */
     1149              break;
     1150            }
     1151
     1152            if (len != 1) {
     1153               strcpy(outBuffer, "E02");
     1154               break;
     1155            }
     1156
     1157            /* Let us check whether this break point already set */
     1158            for (z0=z0break_list; z0!=NULL; z0=z0->next) {
     1159                if (z0->address == address) {
     1160                  break;
     1161                }
     1162            }
     1163
     1164            if (z0 != NULL) {
     1165              /* Repeated packet */
     1166              strcpy(outBuffer, "OK");
     1167              break;
     1168            }
     1169
     1170            /* Let us allocate new break point */
     1171            if (z0break_avail == NULL) {
     1172              strcpy(outBuffer, "E03");
     1173              break;
     1174            }
     1175
     1176            /* Get entry */
     1177            z0 = z0break_avail;
     1178            z0break_avail = z0break_avail->next;
     1179
     1180            /* Let us copy memory from address add stuff the break point in */
     1181            if (mem2hstr(z0->buf, address, 1) == NULL ||
     1182                !hstr2mem(address, "cc" , 1)) {
     1183              /* Memory error */
     1184              z0->next = z0break_avail;
     1185              z0break_avail = z0;
     1186              strcpy(outBuffer, "E03");
     1187              break;
     1188            }
     1189
     1190            /* Fill it */
     1191            z0->address = address;
     1192
     1193            /* Add to the list */
     1194            z0->next = z0break_list;
     1195            z0->prev = NULL;
     1196
     1197            if (z0break_list != NULL) {
     1198              z0break_list->prev = z0;
     1199            }
     1200
     1201            z0break_list = z0;
     1202
     1203            strcpy(outBuffer, "OK");
     1204          }
     1205
     1206        case 'z': /* remove breakpoint */
     1207          {
     1208            int ret, type, len;
     1209            unsigned char  *address;
     1210            struct z0break *z0, *z0last;
     1211
     1212            if (inBuffer[1] == 'z') {
     1213                /* zz packet - remove all breaks */
     1214                ret = 1;
     1215                z0last = NULL;
     1216                for (z0=z0break_list; z0!=NULL; z0=z0->next) {
     1217                    if(!hstr2mem(z0->address, z0->buf, 1)) {
     1218                        ret = 0;
     1219                      }
     1220                     
     1221                     z0last = z0;
     1222                   }
     1223
     1224                /* Free entries if any */
     1225                if (z0last != NULL) {
     1226                    z0last->next  = z0break_avail;
     1227                    z0break_avail = z0break_list;
     1228                    z0break_list  = NULL;
     1229                  }
     1230
     1231                if (ret) {
     1232                  strcpy(outBuffer, "OK");
     1233                } else {
     1234                  strcpy(outBuffer, "E04");
     1235                }
     1236
     1237                break;
     1238              }
     1239             
     1240            ret = parse_zbreak(inBuffer, &type, &address, &len);
     1241            if (!ret) {
     1242                strcpy(outBuffer, "E01");
     1243                break;
     1244              }
     1245           
     1246            if (type != 0) {
     1247              /* We support only software break points so far */
     1248              break;
     1249            }
     1250
     1251            if (len != 1) {
     1252              strcpy(outBuffer, "E02");
     1253              break;
     1254            }
     1255           
     1256            /* Let us check whether this break point set */
     1257            for (z0=z0break_list; z0!=NULL; z0=z0->next) {
     1258              if (z0->address == address) {
     1259                break;
     1260              }
     1261            }
     1262             
     1263            if (z0 == NULL) {
     1264              /* Unknown breakpoint */
     1265              strcpy(outBuffer, "E03");
     1266              break;
     1267            }
     1268           
     1269            if (!hstr2mem(z0->address, z0->buf, 1)) {
     1270              strcpy(outBuffer, "E04");
     1271              break;
     1272            }
     1273   
     1274            /* Unlink entry */
     1275            if (z0->prev == NULL) {
     1276              z0break_list = z0->next;
     1277              if (z0break_list != NULL) {
     1278                z0break_list->prev = NULL;
     1279              }
     1280            } else if (z0->next == NULL) {
     1281              z0->prev->next = NULL;
     1282            } else {
     1283              z0->prev->next = z0->next;
     1284              z0->next->prev = z0->prev;
     1285           }
     1286
     1287           z0->next = z0break_avail;
     1288           z0break_avail = z0;
     1289           
     1290           strcpy(outBuffer, "OK");
     1291         }
     1292
     1293          break;
     1294        default: /* do nothing */
     1295          break;
     1296      }
    9111297
    9121298      /* reply to the request */
     
    9271313}
    9281314
     1315static char initialized;   /* 0 means we are not initialized */
     1316
    9291317void mips_gdb_stub_install(void)
    9301318{
    9311319  rtems_isr_entry old;
     1320  int i;
     1321
     1322  if (initialized) {
     1323    ASSERT(0);
     1324    return;
     1325  }
     1326
     1327  /* z0breaks */
     1328  for (i=0; i<(sizeof(z0break_arr)/sizeof(z0break_arr[0]))-1; i++) {
     1329    z0break_arr[i].next = &z0break_arr[i+1];
     1330  }
     1331
     1332  z0break_arr[i].next = NULL;
     1333  z0break_avail       = &z0break_arr[0];
     1334  z0break_list        = NULL;
     1335
    9321336
    9331337  rtems_interrupt_catch( (rtems_isr_entry) handle_exception, MIPS_EXCEPTION_SYSCALL, &old );
    9341338  /* rtems_interrupt_catch( handle_exception, MIPS_EXCEPTION_BREAK, &old ); */
    9351339
     1340  initialized = 1;
    9361341  /* get the attention of gdb */
    937   mips_break();
     1342  mips_break(1);
    9381343}
     1344
Note: See TracChangeset for help on using the changeset viewer.