Annotation of 43BSDReno/contrib/emacs-18.55/gdb/remote.c, revision 1.1

1.1     ! root        1: /* Memory-access and commands for inferior process, for GDB.
        !             2:    Copyright (C)  1988 Free Software Foundation, Inc.
        !             3: 
        !             4: GDB is distributed in the hope that it will be useful, but WITHOUT ANY
        !             5: WARRANTY.  No author or distributor accepts responsibility to anyone
        !             6: for the consequences of using it or for whether it serves any
        !             7: particular purpose or works at all, unless he says so in writing.
        !             8: Refer to the GDB General Public License for full details.
        !             9: 
        !            10: Everyone is granted permission to copy, modify and redistribute GDB,
        !            11: but only under the conditions described in the GDB General Public
        !            12: License.  A copy of this license is supposed to have been given to you
        !            13: along with GDB so you can know your rights and responsibilities.  It
        !            14: should be in a file named COPYING.  Among other things, the copyright
        !            15: notice and this notice must be preserved on all copies.
        !            16: 
        !            17: In other words, go ahead and share GDB, but don't try to stop
        !            18: anyone else from sharing it farther.  Help stamp out software hoarding!
        !            19: */
        !            20: 
        !            21: /* Remote communication protocol.
        !            22:    All values are encoded in ascii hex digits.
        !            23: 
        !            24:        Request         Packet
        !            25: 
        !            26:        read registers  g
        !            27:        reply           XX....X         Each byte of register data
        !            28:                                        is described by two hex digits.
        !            29:                                        Registers are in the internal order
        !            30:                                        for GDB, and the bytes in a register
        !            31:                                        are in the same order the machine uses.
        !            32:                        or ENN          for an error.
        !            33: 
        !            34:        write regs      GXX..XX         Each byte of register data
        !            35:                                        is described by two hex digits.
        !            36:        reply           OK              for success
        !            37:                        ENN             for an error
        !            38: 
        !            39:        read mem        mAA..AA,LLLL    AA..AA is address, LLLL is length.
        !            40:        reply           XX..XX          XX..XX is mem contents
        !            41:                        or ENN          NN is errno
        !            42: 
        !            43:        write mem       MAA..AA,LLLL:XX..XX
        !            44:                                        AA..AA is address,
        !            45:                                        LLLL is number of bytes,
        !            46:                                        XX..XX is data
        !            47:        reply           OK              for success
        !            48:                        ENN             for an error
        !            49: 
        !            50:        cont            cAA..AA         AA..AA is address to resume
        !            51:                                        If AA..AA is omitted,
        !            52:                                        resume at same address.
        !            53: 
        !            54:        step            sAA..AA         AA..AA is address to resume
        !            55:                                        If AA..AA is omitted,
        !            56:                                        resume at same address.
        !            57: 
        !            58:        There is no immediate reply to step or cont.
        !            59:        The reply comes when the machine stops.
        !            60:        It is           SAA             AA is the "signal number"
        !            61: 
        !            62:        kill req        k
        !            63: */
        !            64: 
        !            65: #include <stdio.h>
        !            66: #include <signal.h>
        !            67: 
        !            68: #include "defs.h"
        !            69: #include "initialize.h"
        !            70: #include "param.h"
        !            71: #include "frame.h"
        !            72: #include "inferior.h"
        !            73: 
        !            74: #include "wait.h"
        !            75: #include <sys/ioctl.h>
        !            76: #include <a.out.h>
        !            77: #include <sys/file.h>
        !            78: 
        !            79: #ifdef HAVE_TERMIO
        !            80: #include <termio.h>
        !            81: #undef TIOCGETP
        !            82: #define TIOCGETP TCGETA
        !            83: #undef TIOCSETN
        !            84: #define TIOCSETN TCSETA
        !            85: #undef TIOCSETP
        !            86: #define TIOCSETP TCSETAF
        !            87: #define TERMINAL struct termio
        !            88: #else
        !            89: #include <sgtty.h>
        !            90: #define TERMINAL struct sgttyb
        !            91: #endif
        !            92: 
        !            93: int kiodebug;
        !            94: 
        !            95: int icache;
        !            96: 
        !            97: /* Descriptor for I/O to remote machine.  */
        !            98: int remote_desc;
        !            99: 
        !           100: #define        PBUFSIZ 300
        !           101: 
        !           102: static void remote_send ();
        !           103: static void putpkt ();
        !           104: static void getpkt ();
        !           105: static void dcache_flush ();
        !           106: 
        !           107: START_FILE
        !           108: 
        !           109: /* Open a connection to a remote debugger.
        !           110:    NAME is the filename used for communication.  */
        !           111: 
        !           112: void
        !           113: remote_open (name, from_tty)
        !           114:      char *name;
        !           115:      int from_tty;
        !           116: {
        !           117:   TERMINAL sg;
        !           118: 
        !           119:   remote_debugging = 0;
        !           120:   dcache_init ();
        !           121: 
        !           122:   remote_desc = open (name, O_RDWR);
        !           123:   if (remote_desc < 0)
        !           124:     perror_with_name (name);
        !           125: 
        !           126:   ioctl (remote_desc, TIOCGETP, &sg);
        !           127: #ifdef HAVE_TERMIO
        !           128:   sg.c_lflag &= ~ICANON;
        !           129: #else
        !           130:   sg.sg_flags = RAW;
        !           131: #endif
        !           132:   ioctl (remote_desc, TIOCSETP, &sg);
        !           133: 
        !           134:   if (from_tty)
        !           135:     printf ("Remote debugging using %s\n", name);
        !           136:   remote_debugging = 1;
        !           137: }
        !           138: 
        !           139: /* Convert hex digit A to a number.  */
        !           140: 
        !           141: static int
        !           142: fromhex (a)
        !           143:      int a;
        !           144: {
        !           145:   if (a >= '0' && a <= '9')
        !           146:     return a - '0';
        !           147:   else if (a >= 'a' && a <= 'f')
        !           148:     return a - 'a' + 10;
        !           149:   else
        !           150:     error ("Reply contains invalid hex digit");
        !           151: }
        !           152: 
        !           153: /* Convert number NIB to a hex digit.  */
        !           154: 
        !           155: static int
        !           156: tohex (nib)
        !           157:      int nib;
        !           158: {
        !           159:   if (nib < 10)
        !           160:     return '0'+nib;
        !           161:   else
        !           162:     return 'a'+nib-10;
        !           163: }
        !           164: 
        !           165: /* Tell the remote machine to resume.  */
        !           166: 
        !           167: int
        !           168: remote_resume (step, signal)
        !           169:      int step, signal;
        !           170: {
        !           171:   char buf[PBUFSIZ];
        !           172: 
        !           173:   dcache_flush ();
        !           174: 
        !           175:   strcpy (buf, step ? "s": "c");
        !           176: 
        !           177:   putpkt (buf);
        !           178: }
        !           179: 
        !           180: /* Wait until the remote machine stops, then return,
        !           181:    storing status in STATUS just as `wait' would.  */
        !           182: 
        !           183: int
        !           184: remote_wait (status)
        !           185:      WAITTYPE *status;
        !           186: {
        !           187:   char buf[PBUFSIZ];
        !           188: 
        !           189:   WSETEXIT ((*status), 0);
        !           190:   getpkt (buf);
        !           191:   if (buf[0] == 'E')
        !           192:     error ("Remote failure reply: %s", buf);
        !           193:   if (buf[0] != 'S')
        !           194:     error ("Invalid remote reply: %s", buf);
        !           195:   WSETSTOP ((*status), (((fromhex (buf[1])) << 4) + (fromhex (buf[2]))));
        !           196: }
        !           197: 
        !           198: /* Read the remote registers into the block REGS.  */
        !           199: 
        !           200: void
        !           201: remote_fetch_registers (regs)
        !           202:      char *regs;
        !           203: {
        !           204:   char buf[PBUFSIZ];
        !           205:   int i;
        !           206:   char *p;
        !           207: 
        !           208:   sprintf (buf, "g");
        !           209:   remote_send (buf);
        !           210: 
        !           211:   /* Reply describes registers byte by byte,
        !           212:      each byte encoded as two hex characters.  */
        !           213: 
        !           214:   p = buf;
        !           215:   for (i = 0; i < REGISTER_BYTES; i++)
        !           216:     {
        !           217:       if (p[0] == 0 || p[1] == 0)
        !           218:        error ("Remote reply is too short: %s", buf);
        !           219:       regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
        !           220:       p += 2;
        !           221:     }
        !           222: }
        !           223: 
        !           224: /* Store the remote registers from the contents of the block REGS.  */
        !           225: 
        !           226: void
        !           227: remote_store_registers (regs)
        !           228:      char *regs;
        !           229: {
        !           230:   char buf[PBUFSIZ];
        !           231:   int i;
        !           232:   char *p;
        !           233: 
        !           234:   buf[0] = 'G';
        !           235:   
        !           236:   /* Command describes registers byte by byte,
        !           237:      each byte encoded as two hex characters.  */
        !           238: 
        !           239:   p = buf + 1;
        !           240:   for (i = 0; i < REGISTER_BYTES; i++)
        !           241:     {
        !           242:       *p++ = (regs[i] > 4) & 0xf;
        !           243:       *p++ = regs[i] & 0xf;
        !           244:     }
        !           245: 
        !           246:   remote_send (buf);
        !           247: }
        !           248: 
        !           249: /* Read a word from remote address ADDR and return it.
        !           250:    This goes through the data cache.  */
        !           251: 
        !           252: int
        !           253: remote_fetch_word (addr)
        !           254:      CORE_ADDR addr;
        !           255: {
        !           256:   if (icache)
        !           257:     {
        !           258:       extern CORE_ADDR text_start, text_end;
        !           259: 
        !           260:       if (addr >= text_start && addr < text_end)
        !           261:        {
        !           262:          int buffer;
        !           263:          xfer_core_file (addr, &buffer, sizeof (int));
        !           264:          return buffer;
        !           265:        }
        !           266:     }
        !           267:   return dcache_fetch (addr);
        !           268: }
        !           269: 
        !           270: /* Write a word WORD into remote address ADDR.
        !           271:    This goes through the data cache.  */
        !           272: 
        !           273: void
        !           274: remote_store_word (addr, word)
        !           275:      CORE_ADDR addr;
        !           276:      int word;
        !           277: {
        !           278:   dcache_poke (addr, word);
        !           279: }
        !           280: 
        !           281: /* Write memory data directly to the remote machine.
        !           282:    This does not inform the data cache; the data cache uses this.
        !           283:    MEMADDR is the address in the remote memory space.
        !           284:    MYADDR is the address of the buffer in our space.
        !           285:    LEN is the number of bytes.  */
        !           286: 
        !           287: void
        !           288: remote_write_bytes (memaddr, myaddr, len)
        !           289:      CORE_ADDR memaddr;
        !           290:      char *myaddr;
        !           291:      int len;
        !           292: {
        !           293:   char buf[PBUFSIZ];
        !           294:   int i;
        !           295:   char *p;
        !           296: 
        !           297:   if (len > PBUFSIZ / 2 - 20)
        !           298:     abort ();
        !           299: 
        !           300:   sprintf (buf, "M%x,%x:", memaddr, len);
        !           301: 
        !           302:   /* Command describes registers byte by byte,
        !           303:      each byte encoded as two hex characters.  */
        !           304: 
        !           305:   p = buf + strlen (buf);
        !           306:   for (i = 0; i < len; i++)
        !           307:     {
        !           308:       *p++ = (myaddr[i] > 4) & 0xf;
        !           309:       *p++ = myaddr[i] & 0xf;
        !           310:     }
        !           311: 
        !           312:   remote_send (buf);
        !           313: }
        !           314: 
        !           315: /* Read memory data directly from the remote machine.
        !           316:    This does not use the data cache; the data cache uses this.
        !           317:    MEMADDR is the address in the remote memory space.
        !           318:    MYADDR is the address of the buffer in our space.
        !           319:    LEN is the number of bytes.  */
        !           320: 
        !           321: void
        !           322: remote_read_bytes (memaddr, myaddr, len)
        !           323:      CORE_ADDR memaddr;
        !           324:      char *myaddr;
        !           325:      int len;
        !           326: {
        !           327:   char buf[PBUFSIZ];
        !           328:   int i;
        !           329:   char *p;
        !           330: 
        !           331:   if (len > PBUFSIZ / 2 - 1)
        !           332:     abort ();
        !           333: 
        !           334:   sprintf (buf, "m%x,%x", memaddr, len);
        !           335:   remote_send (buf);
        !           336: 
        !           337:   /* Reply describes registers byte by byte,
        !           338:      each byte encoded as two hex characters.  */
        !           339: 
        !           340:   p = buf;
        !           341:   for (i = 0; i < REGISTER_BYTES; i++)
        !           342:     {
        !           343:       if (p[0] == 0 || p[1] == 0)
        !           344:        error ("Remote reply is too short: %s", buf);
        !           345:       myaddr[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
        !           346:       p += 2;
        !           347:     }
        !           348: }
        !           349: 
        !           350: /*
        !           351: 
        !           352: A debug packet whose contents are <data>
        !           353: is encapsulated for transmission in the form:
        !           354: 
        !           355:        $ <data> # CSUM1 CSUM2
        !           356: 
        !           357:        <data> must be ASCII alphanumeric and cannot include characters
        !           358:        '$' or '#'
        !           359: 
        !           360:        CSUM1 and CSUM2 are ascii hex representation of an 8-bit 
        !           361:        checksum of <data>, the most significant nibble is sent first.
        !           362:        the hex digits 0-9,a-f are used.
        !           363: 
        !           364: Receiver responds with:
        !           365: 
        !           366:        +       - if CSUM is correct and ready for next packet
        !           367:        -       - if CSUM is incorrect
        !           368: 
        !           369: */
        !           370: 
        !           371: /* Send the command in BUF to the remote machine,
        !           372:    and read the reply into BUF.
        !           373:    Report an error if we get an error reply.  */
        !           374: 
        !           375: static void
        !           376: remote_send (buf)
        !           377:      char *buf;
        !           378: {
        !           379:   int i;
        !           380:   putpkt (buf);
        !           381:   getpkt (buf);
        !           382: 
        !           383:   if (buf[0] == 'E')
        !           384:     error ("Remote failure reply: %s", buf);
        !           385: }
        !           386: 
        !           387: /* Send a packet to the remote machine, with error checking.
        !           388:    The data of the packet is in BUF.  */
        !           389: 
        !           390: static void
        !           391: putpkt (buf)
        !           392:      char *buf;
        !           393: {
        !           394:   int i;
        !           395:   char csum = 0;
        !           396:   char buf2[500];
        !           397:   char buf3[1];
        !           398:   int cnt = strlen (buf);
        !           399:   char *p;
        !           400: 
        !           401:   if (kiodebug)
        !           402:     fprintf (stderr, "Sending packet: %s\n", buf);
        !           403: 
        !           404:   /* Copy the packet into buffer BUF2, encapsulating it
        !           405:      and giving it a checksum.  */
        !           406: 
        !           407:   p = buf2;
        !           408:   *p++ = '$';
        !           409: 
        !           410:   for (i = 0; i < cnt; i++)
        !           411:     {
        !           412:       csum += buf[i];
        !           413:       *p++ = buf[i];
        !           414:     }
        !           415:   *p++ = '#';
        !           416:   *p++ = tohex ((csum >> 4) & 0xf);
        !           417:   *p++ = tohex (csum & 0xf);
        !           418: 
        !           419:   /* Send it over and over until we get a positive ack.  */
        !           420: 
        !           421:   do {
        !           422:     write (remote_desc, buf2, p - buf2);
        !           423:     read (remote_desc, buf3, 1);
        !           424:   } while (buf3[0] != '+');
        !           425: }
        !           426: 
        !           427: static int
        !           428: readchar ()
        !           429: {
        !           430:   char buf[1];
        !           431:   while (read (remote_desc, buf, 1) != 1) ;
        !           432:   return buf[0] & 0x7f;
        !           433: }
        !           434: 
        !           435: /* Read a packet from the remote machine, with error checking,
        !           436:    and store it in BUF.  */
        !           437: 
        !           438: static void
        !           439: getpkt (buf)
        !           440:      char *buf;
        !           441: {
        !           442:   char *bp;
        !           443:   char csum = 0;
        !           444:   int c, c1, c2;
        !           445:   extern kiodebug;
        !           446: 
        !           447:   while (1)
        !           448:     {
        !           449:       while ((c = readchar()) != '$');
        !           450: 
        !           451:       bp = buf;
        !           452:       while (1)
        !           453:        {
        !           454:          c = readchar ();
        !           455:          if (c == '#')
        !           456:            break;
        !           457:          *bp++ = c;
        !           458:          csum += c;
        !           459:        }
        !           460:       *bp = 0;
        !           461: 
        !           462:       c1 = fromhex (readchar ());
        !           463:       c2 = fromhex (readchar ());
        !           464:       if (csum == (c1 << 4) + c2)
        !           465:        break;
        !           466:       printf ("Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
        !           467:              (c1 << 4) + c2, csum, buf);
        !           468:       write (remote_desc, "-", 1);
        !           469:     }
        !           470: 
        !           471:   write (remote_desc, "+", 1);
        !           472: 
        !           473:   if (kiodebug)
        !           474:     fprintf (stderr,"Packet received :%s\n", buf);
        !           475: }
        !           476: 
        !           477: /* The data cache records all the data read from the remote machine
        !           478:    since the last time it stopped.
        !           479: 
        !           480:    Each cache block holds 16 bytes of data
        !           481:    starting at a multiple-of-16 address.  */
        !           482: 
        !           483: #define DCACHE_SIZE 64         /* Number of cache blocks */
        !           484: 
        !           485: struct dcache_block {
        !           486:        struct dcache_block *next, *last;
        !           487:        unsigned int addr;      /* Address for which data is recorded.  */
        !           488:        int data[4];
        !           489: };
        !           490: 
        !           491: struct dcache_block dcache_free, dcache_valid;
        !           492: 
        !           493: /* Free all the data cache blocks, thus discarding all cached data.  */ 
        !           494: 
        !           495: static void
        !           496: dcache_flush ()
        !           497: {
        !           498:   register struct dcache_block *db;
        !           499: 
        !           500:   while ((db = dcache_valid.next) != &dcache_valid)
        !           501:     {
        !           502:       remque (db);
        !           503:       insque (db, &dcache_free);
        !           504:     }
        !           505: }
        !           506: 
        !           507: /*
        !           508:  * If addr is present in the dcache, return the address of the block 
        !           509:  * containing it.
        !           510:  */
        !           511: 
        !           512: struct dcache_block *
        !           513: dcache_hit (addr)
        !           514: {
        !           515:   register struct dcache_block *db;
        !           516: 
        !           517:   if (addr & 3)
        !           518:     abort ();
        !           519: 
        !           520:   /* Search all cache blocks for one that is at this address.  */
        !           521:   db = dcache_valid.next;
        !           522:   while (db != &dcache_valid)
        !           523:     {
        !           524:       if ((addr & 0xfffffff0) == db->addr)
        !           525:        return db;
        !           526:       db = db->next;
        !           527:     }
        !           528:   return NULL;
        !           529: }
        !           530: 
        !           531: /*  Return the int data at address ADDR in dcache block DC.  */
        !           532: 
        !           533: int
        !           534: dcache_value (db, addr)
        !           535:      struct dcache_block *db;
        !           536:      unsigned int addr;
        !           537: {
        !           538:   if (addr & 3)
        !           539:     abort ();
        !           540:   return (db->data[(addr>>2)&3]);
        !           541: }
        !           542: 
        !           543: /* Get a free cache block, put it on the valid list,
        !           544:    and return its address.  The caller should store into the block
        !           545:    the address and data that it describes.  */
        !           546: 
        !           547: struct dcache_block *
        !           548: dcache_alloc ()
        !           549: {
        !           550:   register struct dcache_block *db;
        !           551: 
        !           552:   if ((db = dcache_free.next) == &dcache_free)
        !           553:     /* If we can't get one from the free list, take last valid */
        !           554:     db = dcache_valid.last;
        !           555: 
        !           556:   remque (db);
        !           557:   insque (db, &dcache_valid);
        !           558:   return (db);
        !           559: }
        !           560: 
        !           561: /* Return the contents of the word at address ADDR in the remote machine,
        !           562:    using the data cache.  */
        !           563: 
        !           564: int
        !           565: dcache_fetch (addr)
        !           566:      CORE_ADDR addr;
        !           567: {
        !           568:   register struct dcache_block *db;
        !           569: 
        !           570:   db = dcache_hit (addr);
        !           571:   if (db == 0)
        !           572:     {
        !           573:       db = dcache_alloc ();
        !           574:       remote_read_bytes (addr & ~0xf, db->data, 16);
        !           575:       db->addr = addr & ~0xf;
        !           576:     }
        !           577:   return (dcache_value (db, addr));
        !           578: }
        !           579: 
        !           580: /* Write the word at ADDR both in the data cache and in the remote machine.  */
        !           581: 
        !           582: dcache_poke (addr, data)
        !           583:      CORE_ADDR addr;
        !           584:      int data;
        !           585: {
        !           586:   register struct dcache_block *db;
        !           587: 
        !           588:   /* First make sure the word is IN the cache.  DB is its cache block.  */
        !           589:   db = dcache_hit (addr);
        !           590:   if (db == 0)
        !           591:     {
        !           592:       db = dcache_alloc ();
        !           593:       remote_read_bytes (addr & ~0xf, db->data, 16);
        !           594:       db->addr = addr & ~0xf;
        !           595:     }
        !           596: 
        !           597:   /* Modify the word in the cache.  */
        !           598:   db->data[(addr>>2)&3] = data;
        !           599: 
        !           600:   /* Send the changed word.  */
        !           601:   remote_write_bytes (addr, &data, 4);
        !           602: }
        !           603: 
        !           604: /* Initialize the data cache.  */
        !           605: 
        !           606: dcache_init ()
        !           607: {
        !           608:   register i;
        !           609:   register struct dcache_block *db;
        !           610: 
        !           611:   db = (struct dcache_block *) xmalloc (sizeof (struct dcache_block) * 
        !           612:                                        DCACHE_SIZE);
        !           613:   dcache_free.next = dcache_free.last = &dcache_free;
        !           614:   dcache_valid.next = dcache_valid.last = &dcache_valid;
        !           615:   for (i=0;i<DCACHE_SIZE;i++,db++)
        !           616:     insque (db, &dcache_free);
        !           617: }
        !           618: 
        !           619: static initialize ()
        !           620: {
        !           621: }
        !           622: 
        !           623: END_FILE

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.