remote_gdb.cc revision 56
1/* $Id$ */
2/*
3 * Copyright (c) 1990, 1993
4 *	The Regents of the University of California.  All rights reserved.
5 *
6 * This software was developed by the Computer Systems Engineering group
7 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
8 * contributed to Berkeley.
9 *
10 * All advertising materials mentioning features or use of this software
11 * must display the following acknowledgement:
12 *	This product includes software developed by the University of
13 *	California, Lawrence Berkeley Laboratories.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 *    notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 *    notice, this list of conditions and the following disclaimer in the
22 *    documentation and/or other materials provided with the distribution.
23 * 3. All advertising materials mentioning features or use of this software
24 *    must display the following acknowledgement:
25 *	This product includes software developed by the University of
26 *	California, Berkeley and its contributors.
27 * 4. Neither the name of the University nor the names of its contributors
28 *    may be used to endorse or promote products derived from this software
29 *    without specific prior written permission.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
32 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
35 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
39 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
40 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41 * SUCH DAMAGE.
42 *
43 *	@(#)kgdb_stub.c	8.4 (Berkeley) 1/12/94
44 */
45
46/*-
47 * Copyright (c) 2001 The NetBSD Foundation, Inc.
48 * All rights reserved.
49 *
50 * This code is derived from software contributed to The NetBSD Foundation
51 * by Jason R. Thorpe.
52 *
53 * Redistribution and use in source and binary forms, with or without
54 * modification, are permitted provided that the following conditions
55 * are met:
56 * 1. Redistributions of source code must retain the above copyright
57 *    notice, this list of conditions and the following disclaimer.
58 * 2. Redistributions in binary form must reproduce the above copyright
59 *    notice, this list of conditions and the following disclaimer in the
60 *    documentation and/or other materials provided with the distribution.
61 * 3. All advertising materials mentioning features or use of this software
62 *    must display the following acknowledgement:
63 *	This product includes software developed by the NetBSD
64 *	Foundation, Inc. and its contributors.
65 * 4. Neither the name of The NetBSD Foundation nor the names of its
66 *    contributors may be used to endorse or promote products derived
67 *    from this software without specific prior written permission.
68 *
69 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
70 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
71 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
72 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
73 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
74 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
75 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
76 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
77 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
78 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
79 * POSSIBILITY OF SUCH DAMAGE.
80 */
81
82/*
83 * $NetBSD: kgdb_stub.c,v 1.8 2001/07/07 22:58:00 wdk Exp $
84 *
85 * Taken from NetBSD
86 *
87 * "Stub" to allow remote cpu to debug over a serial line using gdb.
88 */
89
90#include <sys/signal.h>
91
92#include <unistd.h>
93
94#include <string>
95
96#include "cpu/exec_context.hh"
97#include "base/intmath.hh"
98#include "base/kgdb.h"
99
100#include "mem/functional_mem/physical_memory.hh"
101#include "base/remote_gdb.hh"
102#include "base/socket.hh"
103#include "base/trace.hh"
104#include "targetarch/vtophys.hh"
105#include "sim/system.hh"
106#include "cpu/static_inst.hh"
107
108using namespace std;
109
110#ifdef DEBUG
111RemoteGDB *theDebugger = NULL;
112
113void
114debugger()
115{
116    if (theDebugger)
117        theDebugger->trap(ALPHA_KENTRY_IF);
118}
119#endif
120
121///////////////////////////////////////////////////////////
122//
123//
124//
125
126GDBListener::Event::Event(GDBListener *l, int fd, int e)
127    : PollEvent(fd, e), listener(l)
128{}
129
130void
131GDBListener::Event::process(int revent)
132{
133    listener->accept();
134}
135
136GDBListener::GDBListener(RemoteGDB *g, int p)
137    : event(NULL), gdb(g), port(p)
138{}
139
140GDBListener::~GDBListener()
141{
142    if (event)
143        delete event;
144}
145
146void
147GDBListener::listen()
148{
149    while (!listener.listen(port, true)) {
150        DPRINTF(RGDB, "GDBListener(listen): Can't bind port %d\n", port);
151        port++;
152    }
153
154    cerr << "Listening for remote gdb connection on port " << port << endl;
155    event = new Event(this, listener.getfd(), POLLIN);
156    pollQueue.schedule(event);
157}
158
159void
160GDBListener::accept()
161{
162    if (!listener.islistening())
163        panic("GDBListener(accept): cannot accept a connection if we're not listening!");
164
165    int sfd = listener.accept(true);
166
167    if (sfd != -1) {
168        if (gdb->isattached())
169            close(sfd);
170        else
171            gdb->attach(sfd);
172    }
173}
174
175///////////////////////////////////////////////////////////
176//
177//
178//
179int digit2i(char);
180char i2digit(int);
181void mem2hex(void *, const void *, int);
182const char *hex2mem(void *, const char *, int);
183Addr hex2i(const char **);
184
185RemoteGDB::Event::Event(RemoteGDB *g, int fd, int e)
186    : PollEvent(fd, e), gdb(g)
187{}
188
189void
190RemoteGDB::Event::process(int revent)
191{ gdb->trap(ALPHA_KENTRY_IF); }
192
193RemoteGDB::RemoteGDB(System *_system, ExecContext *c)
194    : event(NULL), fd(-1), active(false), attached(false),
195      system(_system), pmem(_system->physmem), context(c)
196{
197#ifdef DEBUG
198    theDebugger = this;
199#endif
200    memset(gdbregs, 0, sizeof(gdbregs));
201}
202
203RemoteGDB::~RemoteGDB()
204{
205    if (event)
206        delete event;
207}
208
209bool
210RemoteGDB::isattached()
211{ return attached; }
212
213void
214RemoteGDB::attach(int f)
215{
216    fd = f;
217
218    event = new Event(this, fd, POLLIN);
219    pollQueue.schedule(event);
220
221    attached = true;
222    DPRINTFN("remote gdb attached\n");
223}
224
225void
226RemoteGDB::detach()
227{
228    attached = false;
229    close(fd);
230    fd = -1;
231
232    pollQueue.remove(event);
233    DPRINTFN("remote gdb detached\n");
234}
235
236const char *
237gdb_command(char cmd)
238{
239    switch (cmd) {
240      case KGDB_SIGNAL: return "KGDB_SIGNAL";
241      case KGDB_SET_BAUD: return "KGDB_SET_BAUD";
242      case KGDB_SET_BREAK: return "KGDB_SET_BREAK";
243      case KGDB_CONT: return "KGDB_CONT";
244      case KGDB_ASYNC_CONT: return "KGDB_ASYNC_CONT";
245      case KGDB_DEBUG: return "KGDB_DEBUG";
246      case KGDB_DETACH: return "KGDB_DETACH";
247      case KGDB_REG_R: return "KGDB_REG_R";
248      case KGDB_REG_W: return "KGDB_REG_W";
249      case KGDB_SET_THREAD: return "KGDB_SET_THREAD";
250      case KGDB_CYCLE_STEP: return "KGDB_CYCLE_STEP";
251      case KGDB_SIG_CYCLE_STEP: return "KGDB_SIG_CYCLE_STEP";
252      case KGDB_KILL: return "KGDB_KILL";
253      case KGDB_MEM_W: return "KGDB_MEM_W";
254      case KGDB_MEM_R: return "KGDB_MEM_R";
255      case KGDB_SET_REG: return "KGDB_SET_REG";
256      case KGDB_READ_REG: return "KGDB_READ_REG";
257      case KGDB_QUERY_VAR: return "KGDB_QUERY_VAR";
258      case KGDB_SET_VAR: return "KGDB_SET_VAR";
259      case KGDB_RESET: return "KGDB_RESET";
260      case KGDB_STEP: return "KGDB_STEP";
261      case KGDB_ASYNC_STEP: return "KGDB_ASYNC_STEP";
262      case KGDB_THREAD_ALIVE: return "KGDB_THREAD_ALIVE";
263      case KGDB_TARGET_EXIT: return "KGDB_TARGET_EXIT";
264      case KGDB_BINARY_DLOAD: return "KGDB_BINARY_DLOAD";
265      case KGDB_CLR_HW_BKPT: return "KGDB_CLR_HW_BKPT";
266      case KGDB_SET_HW_BKPT: return "KGDB_SET_HW_BKPT";
267      case KGDB_START: return "KGDB_START";
268      case KGDB_END: return "KGDB_END";
269      case KGDB_GOODP: return "KGDB_GOODP";
270      case KGDB_BADP: return "KGDB_BADP";
271      default: return "KGDB_UNKNOWN";
272    }
273}
274
275///////////////////////////////////////////////////////////
276// RemoteGDB::acc
277//
278//	Determine if the mapping at va..(va+len) is valid.
279//
280bool
281RemoteGDB::acc(Addr va, size_t len)
282{
283    Addr last_va;
284    Addr pte;
285
286    va = alpha_trunc_page(va);
287    last_va = alpha_round_page(va + len);
288
289    do  {
290        if (va < ALPHA_K0SEG_BASE) {
291            DPRINTF(RGDB, "RGDB(acc):   Mapping is invalid %#x < K0SEG\n", va);
292            return false;
293        }
294
295        if (va < ALPHA_K1SEG_BASE) {
296            if (va < (ALPHA_K0SEG_BASE + pmem->getSize())) {
297                DPRINTF(RGDB, "RGDB(acc):   Mapping is valid  K0SEG <= "
298                        "%#x < K0SEG + size\n", va);
299                return true;
300            } else {
301                DPRINTF(RGDB, "RGDB(acc):   Mapping is invalid %#x < K0SEG\n",
302                        va);
303                return false;
304            }
305        }
306
307        Addr ptbr = context->regs.ipr[AlphaISA::IPR_PALtemp20];
308        pte = kernel_pte_lookup(pmem, ptbr, va);
309        if (!pte || !entry_valid(pmem->phys_read_qword(pte))) {
310            DPRINTF(RGDB, "RGDB(acc):   %#x pte is invalid\n", va);
311            return false;
312        }
313        va += ALPHA_PGBYTES;
314    } while (va < last_va);
315
316    DPRINTF(RGDB, "RGDB(acc):   %#x mapping is valid\n", va);
317    return true;
318}
319
320///////////////////////////////////////////////////////////
321// RemoteGDB::signal
322//
323//	Translate a trap number into a Unix-compatible signal number.
324//	(GDB only understands Unix signal numbers.)
325//
326int
327RemoteGDB::signal(int type)
328{
329    switch (type) {
330      case ALPHA_KENTRY_UNA:
331        return (SIGBUS);
332
333      case ALPHA_KENTRY_ARITH:
334        return (SIGFPE);
335
336      case ALPHA_KENTRY_IF:
337        return (SIGILL);
338
339      case ALPHA_KENTRY_MM:
340        return (SIGSEGV);
341
342      default:
343        panic("unknown signal type");
344        return 0;
345    }
346}
347
348///////////////////////////////////////////////////////////
349// RemoteGDB::getregs
350//
351//	Translate the kernel debugger register format into
352//	the GDB register format.
353void
354RemoteGDB::getregs()
355{
356    memset(gdbregs, 0, sizeof(gdbregs));
357    memcpy(&gdbregs[KGDB_REG_V0], context->regs.intRegFile, 32 * sizeof(uint64_t));
358#ifdef KGDB_FP_REGS
359    memcpy(&gdbregs[KGDB_REG_F0], context->regs.floatRegFile.q,
360           32 * sizeof(uint64_t));
361#endif
362    gdbregs[KGDB_REG_PC] = context->regs.pc;
363}
364
365///////////////////////////////////////////////////////////
366// RemoteGDB::setregs
367//
368//	Translate the GDB register format into the kernel
369//	debugger register format.
370//
371void
372RemoteGDB::setregs()
373{
374    memcpy(context->regs.intRegFile, &gdbregs[KGDB_REG_V0], 32 * sizeof(uint64_t));
375#ifdef KGDB_FP_REGS
376    memcpy(context->regs.floatRegFile.q, &gdbregs[KGDB_REG_F0],
377           32 * sizeof(uint64_t));
378#endif
379    context->regs.pc = gdbregs[KGDB_REG_PC];
380}
381
382void
383RemoteGDB::setTempBreakpoint(TempBreakpoint &bkpt, Addr addr)
384{
385    DPRINTF(RGDB, "RGDB(setTempBreakpoint): addr=%#x\n", addr);
386
387    bkpt.address = addr;
388    insertHardBreak(addr, 4);
389}
390
391void
392RemoteGDB::clearTempBreakpoint(TempBreakpoint &bkpt)
393{
394    DPRINTF(RGDB, "RGDB(setTempBreakpoint): addr=%#x\n",
395            bkpt.address);
396
397
398    removeHardBreak(bkpt.address, 4);
399    bkpt.address = 0;
400}
401
402void
403RemoteGDB::clearSingleStep()
404{
405    DPRINTF(RGDB, "clearSingleStep bt_addr=%#x nt_addr=%#x\n",
406            takenBkpt.address, notTakenBkpt.address);
407
408    if (takenBkpt.address != 0)
409        clearTempBreakpoint(takenBkpt);
410
411    if (notTakenBkpt.address != 0)
412        clearTempBreakpoint(notTakenBkpt);
413}
414
415void
416RemoteGDB::setSingleStep()
417{
418    Addr pc = context->regs.pc;
419    Addr npc, bpc;
420    bool set_bt = false;
421
422    npc = pc + sizeof(MachInst);
423
424    // User was stopped at pc, e.g. the instruction at pc was not
425    // executed.
426    MachInst inst = read<MachInst>(pc);
427    StaticInstPtr<TheISA> si(inst);
428    if (si->hasBranchTarget(pc, context, bpc)) {
429        // Don't bother setting a breakpoint on the taken branch if it
430        // is the same as the next pc
431        if (bpc != npc)
432            set_bt = true;
433    }
434
435    DPRINTF(RGDB, "setSingleStep bt_addr=%#x nt_addr=%#x\n",
436            takenBkpt.address, notTakenBkpt.address);
437
438    setTempBreakpoint(notTakenBkpt, npc);
439
440    if (set_bt)
441        setTempBreakpoint(takenBkpt, bpc);
442}
443
444/////////////////////////
445//
446//
447
448uint8_t
449RemoteGDB::getbyte()
450{
451    uint8_t b;
452    ::read(fd, &b, 1);
453    return b;
454}
455
456void
457RemoteGDB::putbyte(uint8_t b)
458{
459    ::write(fd, &b, 1);
460}
461
462// Send a packet to gdb
463void
464RemoteGDB::send(const char *bp)
465{
466    const char *p;
467    uint8_t csum, c;
468
469//    DPRINTF(RGDB, "RGDB(send):  %s\n", bp);
470
471    do {
472        p = bp;
473        putbyte(KGDB_START);
474        for (csum = 0; (c = *p); p++) {
475            putbyte(c);
476            csum += c;
477        }
478        putbyte(KGDB_END);
479        putbyte(i2digit(csum >> 4));
480        putbyte(i2digit(csum));
481    } while ((c = getbyte() & 0x7f) == KGDB_BADP);
482}
483
484// Receive a packet from gdb
485int
486RemoteGDB::recv(char *bp, int maxlen)
487{
488    char *p;
489    int c, csum;
490    int len;
491
492    do {
493        p = bp;
494        csum = len = 0;
495        while ((c = getbyte()) != KGDB_START)
496            ;
497
498        while ((c = getbyte()) != KGDB_END && len < maxlen) {
499            c &= 0x7f;
500            csum += c;
501            *p++ = c;
502            len++;
503        }
504        csum &= 0xff;
505        *p = '\0';
506
507        if (len >= maxlen) {
508            putbyte(KGDB_BADP);
509            continue;
510        }
511
512        csum -= digit2i(getbyte()) * 16;
513        csum -= digit2i(getbyte());
514
515        if (csum == 0) {
516            putbyte(KGDB_GOODP);
517            // Sequence present?
518            if (bp[2] == ':') {
519                putbyte(bp[0]);
520                putbyte(bp[1]);
521                len -= 3;
522                bcopy(bp + 3, bp, len);
523            }
524            break;
525        }
526        putbyte(KGDB_BADP);
527    } while (1);
528
529//    DPRINTF(RGDB, "RGDB(recv):  %s: %s\n", gdb_command(*bp), bp);
530
531    return (len);
532}
533
534// Read bytes from kernel address space for debugger.
535bool
536RemoteGDB::read(Addr vaddr, size_t size, char *data)
537{
538    static Addr lastaddr = 0;
539    static size_t lastsize = 0;
540
541    uint8_t *maddr;
542
543    if (vaddr < 10) {
544      DPRINTF(RGDB, "\nRGDB(read):  reading memory location zero!\n");
545      vaddr = lastaddr + lastsize;
546    }
547
548    DPRINTF(RGDB, "RGDB(read):  addr=%#x, size=%d", vaddr, size);
549#if TRACING_ON
550    char *d = data;
551    size_t s = size;
552#endif
553
554    lastaddr = vaddr;
555    lastsize = size;
556
557    size_t count = min((Addr)size,
558                       VMPageSize - (vaddr & (VMPageSize - 1)));
559
560    maddr = vtomem(context, vaddr, count);
561    memcpy(data, maddr, count);
562
563    vaddr += count;
564    data += count;
565    size -= count;
566
567    while (size >= VMPageSize) {
568        maddr = vtomem(context, vaddr, count);
569        memcpy(data, maddr, VMPageSize);
570
571        vaddr += VMPageSize;
572        data += VMPageSize;
573        size -= VMPageSize;
574    }
575
576    if (size > 0) {
577        maddr = vtomem(context, vaddr, count);
578        memcpy(data, maddr, size);
579    }
580
581#if TRACING_ON
582    if (DTRACE(RGDB)) {
583      char buf[1024];
584      mem2hex(buf, d, s);
585      cprintf(": %s\n", buf);
586    }
587#endif
588
589    return true;
590}
591
592// Write bytes to kernel address space for debugger.
593bool
594RemoteGDB::write(Addr vaddr, size_t size, const char *data)
595{
596    static Addr lastaddr = 0;
597    static size_t lastsize = 0;
598
599    uint8_t *maddr;
600
601    if (vaddr < 10) {
602      DPRINTF(RGDB, "RGDB(write): writing memory location zero!\n");
603      vaddr = lastaddr + lastsize;
604    }
605
606    if (DTRACE(RGDB)) {
607      char buf[1024];
608      mem2hex(buf, data, size);
609      cprintf("RGDB(write): addr=%#x, size=%d: %s\n", vaddr, size, buf);
610    }
611
612    lastaddr = vaddr;
613    lastsize = size;
614
615    size_t count = min((Addr)size,
616                       VMPageSize - (vaddr & (VMPageSize - 1)));
617
618    maddr = vtomem(context, vaddr, count);
619    memcpy(maddr, data, count);
620
621    vaddr += count;
622    data += count;
623    size -= count;
624
625    while (size >= VMPageSize) {
626        maddr = vtomem(context, vaddr, count);
627        memcpy(maddr, data, VMPageSize);
628
629        vaddr += VMPageSize;
630        data += VMPageSize;
631        size -= VMPageSize;
632    }
633
634    if (size > 0) {
635        maddr = vtomem(context, vaddr, count);
636        memcpy(maddr, data, size);
637    }
638
639#ifdef IMB
640    alpha_pal_imb();
641#endif
642
643    return true;
644}
645
646
647PCEventQueue *RemoteGDB::getPcEventQueue()
648{
649    return &system->pcEventQueue;
650}
651
652
653RemoteGDB::HardBreakpoint::HardBreakpoint(RemoteGDB *_gdb, Addr pc)
654    : PCEvent(_gdb->getPcEventQueue(), "HardBreakpoint Event", pc),
655      gdb(_gdb), refcount(0)
656{
657    DPRINTF(RGDB, "creating hardware breakpoint at %#x\n", evpc);
658    schedule();
659}
660
661void
662RemoteGDB::HardBreakpoint::process(ExecContext *xc)
663{
664    DPRINTF(RGDB, "handling hardware breakpoint at %#x\n", pc());
665
666    if (xc == gdb->context)
667        gdb->trap(ALPHA_KENTRY_IF);
668}
669
670bool
671RemoteGDB::insertSoftBreak(Addr addr, size_t len)
672{
673    if (len != sizeof(MachInst))
674        panic("invalid length\n");
675
676    return insertHardBreak(addr, len);
677}
678
679bool
680RemoteGDB::removeSoftBreak(Addr addr, size_t len)
681{
682    if (len != sizeof(MachInst))
683        panic("invalid length\n");
684
685    return removeHardBreak(addr, len);
686}
687
688bool
689RemoteGDB::insertHardBreak(Addr addr, size_t len)
690{
691    if (len != sizeof(MachInst))
692        panic("invalid length\n");
693
694    DPRINTF(RGDB, "inserting hardware breakpoint at %#x\n", addr);
695
696    HardBreakpoint *&bkpt = hardBreakMap[addr];
697    if (bkpt == 0)
698        bkpt = new HardBreakpoint(this, addr);
699
700    bkpt->refcount++;
701
702    return true;
703
704#if 0
705    break_iter_t i = hardBreakMap.find(addr);
706    if (i == hardBreakMap.end()) {
707        HardBreakpoint *bkpt = new HardBreakpoint(this, addr);
708        hardBreakMap[addr] = bkpt;
709        i = hardBreakMap.insert(make_pair(addr, bkpt));
710        if (i == hardBreakMap.end())
711            return false;
712    }
713
714    (*i).second->refcount++;
715#endif
716}
717
718bool
719RemoteGDB::removeHardBreak(Addr addr, size_t len)
720{
721    if (len != sizeof(MachInst))
722        panic("invalid length\n");
723
724    DPRINTF(RGDB, "removing hardware breakpoint at %#x\n", addr);
725
726    break_iter_t i = hardBreakMap.find(addr);
727    if (i == hardBreakMap.end())
728        return false;
729
730    HardBreakpoint *hbp = (*i).second;
731    if (--hbp->refcount == 0) {
732        delete hbp;
733        hardBreakMap.erase(i);
734    }
735
736    return true;
737}
738
739const char *
740break_type(char c)
741{
742    switch(c) {
743      case '0': return "software breakpoint";
744      case '1': return "hardware breakpoint";
745      case '2': return "write watchpoint";
746      case '3': return "read watchpoint";
747      case '4': return "access watchpoint";
748      default: return "unknown breakpoint/watchpoint";
749    }
750}
751
752// This function does all command processing for interfacing to a
753// remote gdb.  Note that the error codes are ignored by gdb at
754// present, but might eventually become meaningful. (XXX) It might
755// makes sense to use POSIX errno values, because that is what the
756// gdb/remote.c functions want to return.
757bool
758RemoteGDB::trap(int type)
759{
760    uint64_t val;
761    size_t datalen, len;
762    char data[KGDB_BUFLEN + 1];
763    char buffer[sizeof(gdbregs) * 2 + 256];
764    char temp[KGDB_BUFLEN];
765    const char *p;
766    char command, subcmd;
767    string var;
768    bool ret;
769
770    if (!attached)
771        return false;
772
773    DPRINTF(RGDB, "RGDB(trap): PC=%#x NPC=%#x\n",
774            context->regs.pc, context->regs.npc);
775
776    clearSingleStep();
777
778    /*
779     * The first entry to this function is normally through
780     * a breakpoint trap in kgdb_connect(), in which case we
781     * must advance past the breakpoint because gdb will not.
782     *
783     * On the first entry here, we expect that gdb is not yet
784     * listening to us, so just enter the interaction loop.
785     * After the debugger is "active" (connected) it will be
786     * waiting for a "signaled" message from us.
787     */
788    if (!active) {
789        if (!IS_BREAKPOINT_TRAP(type, 0)) {
790            // No debugger active -- let trap handle this.
791            return false;
792        }
793        active = true;
794    } else {
795        // Tell remote host that an exception has occurred.
796        sprintf((char *)buffer, "S%02x", signal(type));
797        send(buffer);
798    }
799
800    // Stick frame regs into our reg cache.
801    getregs();
802
803    for (;;) {
804        datalen = recv(data, sizeof(data));
805        data[sizeof(data) - 1] = 0; // Sentinel
806        command = data[0];
807        subcmd = 0;
808        p = data + 1;
809        switch (command) {
810
811          case KGDB_SIGNAL:
812            // if this command came from a running gdb, answer it --
813            // the other guy has no way of knowing if we're in or out
814            // of this loop when he issues a "remote-signal".
815            sprintf((char *)buffer, "S%02x", signal(type));
816            send(buffer);
817            continue;
818
819          case KGDB_REG_R:
820            if (2 * sizeof(gdbregs) > sizeof(buffer))
821                panic("buffer too small");
822
823            mem2hex(buffer, gdbregs, sizeof(gdbregs));
824            send(buffer);
825            continue;
826
827          case KGDB_REG_W:
828            p = hex2mem(gdbregs, p, sizeof(gdbregs));
829            if (p == NULL || *p != '\0')
830                send("E01");
831            else {
832                setregs();
833                send("OK");
834            }
835            continue;
836
837#if 0
838          case KGDB_SET_REG:
839            val = hex2i(&p);
840            if (*p++ != '=') {
841                send("E01");
842                continue;
843            }
844            if (val < 0 && val >= KGDB_NUMREGS) {
845                send("E01");
846                continue;
847            }
848
849            gdbregs[val] = hex2i(&p);
850            setregs();
851            send("OK");
852
853            continue;
854#endif
855
856          case KGDB_MEM_R:
857            val = hex2i(&p);
858            if (*p++ != ',') {
859                send("E02");
860                continue;
861            }
862            len = hex2i(&p);
863            if (*p != '\0') {
864                send("E03");
865                continue;
866            }
867            if (len > sizeof(buffer)) {
868                send("E04");
869                continue;
870            }
871            if (!acc(val, len)) {
872                send("E05");
873                continue;
874            }
875
876            if (read(val, (size_t)len, (char *)buffer)) {
877              mem2hex(temp, buffer, len);
878              send(temp);
879            } else {
880              send("E05");
881            }
882            continue;
883
884          case KGDB_MEM_W:
885            val = hex2i(&p);
886            if (*p++ != ',') {
887                send("E06");
888                continue;
889            }
890            len = hex2i(&p);
891            if (*p++ != ':') {
892                send("E07");
893                continue;
894            }
895            if (len > datalen - (p - data)) {
896                send("E08");
897                continue;
898            }
899            p = hex2mem(buffer, p, sizeof(buffer));
900            if (p == NULL) {
901                send("E09");
902                continue;
903            }
904            if (!acc(val, len)) {
905                send("E0A");
906                continue;
907            }
908            if (write(val, (size_t)len, (char *)buffer))
909              send("OK");
910            else
911              send("E0B");
912            continue;
913
914          case KGDB_SET_THREAD:
915            subcmd = *p++;
916            val = hex2i(&p);
917            if (val == 0)
918                send("OK");
919            else
920                send("E01");
921            continue;
922
923          case KGDB_DETACH:
924          case KGDB_KILL:
925            active = false;
926            clearSingleStep();
927            detach();
928            goto out;
929
930          case KGDB_ASYNC_CONT:
931            subcmd = hex2i(&p);
932            if (*p++ == ';') {
933                val = hex2i(&p);
934                context->regs.pc = val;
935                context->regs.npc = val + sizeof(MachInst);
936            }
937            clearSingleStep();
938            goto out;
939
940          case KGDB_CONT:
941            if (p - data < datalen) {
942                val = hex2i(&p);
943                context->regs.pc = val;
944                context->regs.npc = val + sizeof(MachInst);
945            }
946            clearSingleStep();
947            goto out;
948
949          case KGDB_ASYNC_STEP:
950            subcmd = hex2i(&p);
951            if (*p++ == ';') {
952                val = hex2i(&p);
953                context->regs.pc = val;
954                context->regs.npc = val + sizeof(MachInst);
955            }
956            setSingleStep();
957            goto out;
958
959          case KGDB_STEP:
960            if (p - data < datalen) {
961                val = hex2i(&p);
962                context->regs.pc = val;
963                context->regs.npc = val + sizeof(MachInst);
964            }
965            setSingleStep();
966            goto out;
967
968          case KGDB_CLR_HW_BKPT:
969            subcmd = *p++;
970            if (*p++ != ',') send("E0D");
971            val = hex2i(&p);
972            if (*p++ != ',') send("E0D");
973            len = hex2i(&p);
974
975            DPRINTF(RGDB, "kgdb: clear %s, addr=%#x, len=%d\n",
976                    break_type(subcmd), val, len);
977
978            ret = false;
979
980            switch (subcmd) {
981              case '0': // software breakpoint
982                ret = removeSoftBreak(val, len);
983                break;
984
985              case '1': // hardware breakpoint
986                ret = removeHardBreak(val, len);
987                break;
988
989              case '2': // write watchpoint
990              case '3': // read watchpoint
991              case '4': // access watchpoint
992              default: // unknown
993                send("");
994                break;
995            }
996
997            send(ret ? "OK" : "E0C");
998            continue;
999
1000          case KGDB_SET_HW_BKPT:
1001            subcmd = *p++;
1002            if (*p++ != ',') send("E0D");
1003            val = hex2i(&p);
1004            if (*p++ != ',') send("E0D");
1005            len = hex2i(&p);
1006
1007            DPRINTF(RGDB, "kgdb: set %s, addr=%#x, len=%d\n",
1008                    break_type(subcmd), val, len);
1009
1010            ret = false;
1011
1012            switch (subcmd) {
1013              case '0': // software breakpoint
1014                ret = insertSoftBreak(val, len);
1015                break;
1016
1017              case '1': // hardware breakpoint
1018                ret = insertHardBreak(val, len);
1019                break;
1020
1021              case '2': // write watchpoint
1022              case '3': // read watchpoint
1023              case '4': // access watchpoint
1024              default: // unknown
1025                send("");
1026                break;
1027            }
1028
1029            send(ret ? "OK" : "E0C");
1030            continue;
1031
1032          case KGDB_QUERY_VAR:
1033            var = string(p, datalen - 1);
1034            if (var == "C")
1035                send("QC0");
1036            else
1037                send("");
1038            continue;
1039
1040          case KGDB_SET_BAUD:
1041          case KGDB_SET_BREAK:
1042          case KGDB_DEBUG:
1043          case KGDB_CYCLE_STEP:
1044          case KGDB_SIG_CYCLE_STEP:
1045          case KGDB_READ_REG:
1046          case KGDB_SET_VAR:
1047          case KGDB_RESET:
1048          case KGDB_THREAD_ALIVE:
1049          case KGDB_TARGET_EXIT:
1050          case KGDB_BINARY_DLOAD:
1051            // Unsupported command
1052            DPRINTF(RGDB, "kgdb: Unsupported command: %s\n",
1053                    gdb_command(command));
1054            DDUMP(RGDB, (uint8_t *)data, datalen);
1055            send("");
1056            continue;
1057
1058          default:
1059            // Unknown command.
1060            DPRINTF(RGDB, "kgdb: Unknown command: %c(%#x)\n",
1061                    command, command);
1062            send("");
1063            continue;
1064
1065
1066        }
1067    }
1068
1069  out:
1070    return true;
1071}
1072
1073// Convert a hex digit into an integer.
1074// This returns -1 if the argument passed is no valid hex digit.
1075int
1076digit2i(char c)
1077{
1078    if (c >= '0' && c <= '9')
1079        return (c - '0');
1080    else if (c >= 'a' && c <= 'f')
1081        return (c - 'a' + 10);
1082    else if (c >= 'A' && c <= 'F')
1083
1084        return (c - 'A' + 10);
1085    else
1086        return (-1);
1087}
1088
1089// Convert the low 4 bits of an integer into an hex digit.
1090char
1091i2digit(int n)
1092{
1093    return ("0123456789abcdef"[n & 0x0f]);
1094}
1095
1096// Convert a byte array into an hex string.
1097void
1098mem2hex(void *vdst, const void *vsrc, int len)
1099{
1100    char *dst = (char *)vdst;
1101    const char *src = (const char *)vsrc;
1102
1103    while (len--) {
1104        *dst++ = i2digit(*src >> 4);
1105        *dst++ = i2digit(*src++);
1106    }
1107    *dst = '\0';
1108}
1109
1110// Convert an hex string into a byte array.
1111// This returns a pointer to the character following the last valid
1112// hex digit. If the string ends in the middle of a byte, NULL is
1113// returned.
1114const char *
1115hex2mem(void *vdst, const char *src, int maxlen)
1116{
1117    char *dst = (char *)vdst;
1118    int msb, lsb;
1119
1120    while (*src && maxlen--) {
1121        msb = digit2i(*src++);
1122        if (msb < 0)
1123            return (src - 1);
1124        lsb = digit2i(*src++);
1125        if (lsb < 0)
1126            return (NULL);
1127        *dst++ = (msb << 4) | lsb;
1128    }
1129    return (src);
1130}
1131
1132// Convert an hex string into an integer.
1133// This returns a pointer to the character following the last valid
1134// hex digit.
1135Addr
1136hex2i(const char **srcp)
1137{
1138    const char *src = *srcp;
1139    Addr r = 0;
1140    int nibble;
1141
1142    while ((nibble = digit2i(*src)) >= 0) {
1143        r *= 16;
1144        r += nibble;
1145        src++;
1146    }
1147    *srcp = src;
1148    return (r);
1149}
1150
1151