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