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