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