remote_gdb.cc revision 1762
110553Salexandru.dutu@amd.com/* 210553Salexandru.dutu@amd.com * Copyright (c) 2002-2005 The Regents of The University of Michigan 310553Salexandru.dutu@amd.com * All rights reserved. 410553Salexandru.dutu@amd.com * 510553Salexandru.dutu@amd.com * Redistribution and use in source and binary forms, with or without 610553Salexandru.dutu@amd.com * modification, are permitted provided that the following conditions are 710553Salexandru.dutu@amd.com * met: redistributions of source code must retain the above copyright 810553Salexandru.dutu@amd.com * notice, this list of conditions and the following disclaimer; 910553Salexandru.dutu@amd.com * redistributions in binary form must reproduce the above copyright 1010553Salexandru.dutu@amd.com * notice, this list of conditions and the following disclaimer in the 1110553Salexandru.dutu@amd.com * documentation and/or other materials provided with the distribution; 1210553Salexandru.dutu@amd.com * neither the name of the copyright holders nor the names of its 1310553Salexandru.dutu@amd.com * contributors may be used to endorse or promote products derived from 1410553Salexandru.dutu@amd.com * this software without specific prior written permission. 1510553Salexandru.dutu@amd.com * 1610553Salexandru.dutu@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1710553Salexandru.dutu@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1810553Salexandru.dutu@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1910553Salexandru.dutu@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2010553Salexandru.dutu@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2110553Salexandru.dutu@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2210553Salexandru.dutu@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2310553Salexandru.dutu@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2410553Salexandru.dutu@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2510553Salexandru.dutu@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2610553Salexandru.dutu@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2710553Salexandru.dutu@amd.com */ 2810553Salexandru.dutu@amd.com 2910553Salexandru.dutu@amd.com/* 3010553Salexandru.dutu@amd.com * Copyright (c) 1990, 1993 3110553Salexandru.dutu@amd.com * The Regents of the University of California. All rights reserved. 3211793Sbrandon.potter@amd.com * 3311659Salexandru.dutu@amd.com * This software was developed by the Computer Systems Engineering group 3411800Sbrandon.potter@amd.com * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 3510553Salexandru.dutu@amd.com * contributed to Berkeley. 3611800Sbrandon.potter@amd.com * 3710553Salexandru.dutu@amd.com * All advertising materials mentioning features or use of this software 3810553Salexandru.dutu@amd.com * must display the following acknowledgement: 3910553Salexandru.dutu@amd.com * This product includes software developed by the University of 4010553Salexandru.dutu@amd.com * California, Lawrence Berkeley Laboratories. 4110553Salexandru.dutu@amd.com * 4210553Salexandru.dutu@amd.com * Redistribution and use in source and binary forms, with or without 4310553Salexandru.dutu@amd.com * modification, are permitted provided that the following conditions 4410553Salexandru.dutu@amd.com * are met: 4510553Salexandru.dutu@amd.com * 1. Redistributions of source code must retain the above copyright 4610553Salexandru.dutu@amd.com * notice, this list of conditions and the following disclaimer. 4710553Salexandru.dutu@amd.com * 2. Redistributions in binary form must reproduce the above copyright 4810553Salexandru.dutu@amd.com * notice, this list of conditions and the following disclaimer in the 4910553Salexandru.dutu@amd.com * documentation and/or other materials provided with the distribution. 5010553Salexandru.dutu@amd.com * 3. All advertising materials mentioning features or use of this software 5110553Salexandru.dutu@amd.com * must display the following acknowledgement: 5211877Sbrandon.potter@amd.com * This product includes software developed by the University of 5311877Sbrandon.potter@amd.com * California, Berkeley and its contributors. 5411877Sbrandon.potter@amd.com * 4. Neither the name of the University nor the names of its contributors 5513613Sgabeblack@google.com * may be used to endorse or promote products derived from this software 5610553Salexandru.dutu@amd.com * without specific prior written permission. 5710553Salexandru.dutu@amd.com * 5810553Salexandru.dutu@amd.com * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 5910553Salexandru.dutu@amd.com * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 6010553Salexandru.dutu@amd.com * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 6110553Salexandru.dutu@amd.com * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 6210553Salexandru.dutu@amd.com * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 6310553Salexandru.dutu@amd.com * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 6410553Salexandru.dutu@amd.com * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 6510553Salexandru.dutu@amd.com * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 6610553Salexandru.dutu@amd.com * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 6710553Salexandru.dutu@amd.com * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 6810553Salexandru.dutu@amd.com * SUCH DAMAGE. 6910553Salexandru.dutu@amd.com * 7010553Salexandru.dutu@amd.com * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94 7114024Sgabeblack@google.com */ 7211659Salexandru.dutu@amd.com 7311659Salexandru.dutu@amd.com/*- 7411659Salexandru.dutu@amd.com * Copyright (c) 2001 The NetBSD Foundation, Inc. 7511659Salexandru.dutu@amd.com * All rights reserved. 7614010Sgabeblack@google.com * 7714010Sgabeblack@google.com * This code is derived from software contributed to The NetBSD Foundation 7811659Salexandru.dutu@amd.com * by Jason R. Thorpe. 7911659Salexandru.dutu@amd.com * 8011659Salexandru.dutu@amd.com * Redistribution and use in source and binary forms, with or without 8111659Salexandru.dutu@amd.com * modification, are permitted provided that the following conditions 8211659Salexandru.dutu@amd.com * are met: 8311659Salexandru.dutu@amd.com * 1. Redistributions of source code must retain the above copyright 8411659Salexandru.dutu@amd.com * notice, this list of conditions and the following disclaimer. 8511659Salexandru.dutu@amd.com * 2. Redistributions in binary form must reproduce the above copyright 8611659Salexandru.dutu@amd.com * notice, this list of conditions and the following disclaimer in the 8711659Salexandru.dutu@amd.com * documentation and/or other materials provided with the distribution. 8810553Salexandru.dutu@amd.com * 3. All advertising materials mentioning features or use of this software 8910553Salexandru.dutu@amd.com * must display the following acknowledgement: 9010553Salexandru.dutu@amd.com * 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 134using namespace std; 135 136#ifdef DEBUG 137RemoteGDB *theDebugger = NULL; 138 139void 140debugger() 141{ 142 if (theDebugger) 143 theDebugger->trap(ALPHA_KENTRY_IF); 144} 145#endif 146 147/////////////////////////////////////////////////////////// 148// 149// 150// 151 152GDBListener::Event::Event(GDBListener *l, int fd, int e) 153 : PollEvent(fd, e), listener(l) 154{} 155 156void 157GDBListener::Event::process(int revent) 158{ 159 listener->accept(); 160} 161 162GDBListener::GDBListener(RemoteGDB *g, int p) 163 : event(NULL), gdb(g), port(p) 164{} 165 166GDBListener::~GDBListener() 167{ 168 if (event) 169 delete event; 170} 171 172string 173GDBListener::name() 174{ 175 return gdb->name() + ".listener"; 176} 177 178void 179GDBListener::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 191void 192GDBListener::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// 211int digit2i(char); 212char i2digit(int); 213void mem2hex(void *, const void *, int); 214const char *hex2mem(void *, const char *, int); 215Addr hex2i(const char **); 216 217RemoteGDB::Event::Event(RemoteGDB *g, int fd, int e) 218 : PollEvent(fd, e), gdb(g) 219{} 220 221void 222RemoteGDB::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 230RemoteGDB::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 237RemoteGDB::~RemoteGDB() 238{ 239 if (event) 240 delete event; 241} 242 243string 244RemoteGDB::name() 245{ 246 return system->name() + ".remote_gdb"; 247} 248 249bool 250RemoteGDB::isattached() 251{ return attached; } 252 253void 254RemoteGDB::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 268void 269RemoteGDB::detach() 270{ 271 attached = false; 272 close(fd); 273 fd = -1; 274 275 pollQueue.remove(event); 276 DPRINTFN("remote gdb detached\n"); 277} 278 279const char * 280gdb_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// 323bool 324RemoteGDB::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// 373int 374RemoteGDB::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. 403void 404RemoteGDB::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// 421void 422RemoteGDB::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 433void 434RemoteGDB::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 442void 443RemoteGDB::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 453void 454RemoteGDB::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 466void 467RemoteGDB::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 499uint8_t 500RemoteGDB::getbyte() 501{ 502 uint8_t b; 503 ::read(fd, &b, 1); 504 return b; 505} 506 507void 508RemoteGDB::putbyte(uint8_t b) 509{ 510 ::write(fd, &b, 1); 511} 512 513// Send a packet to gdb 514void 515RemoteGDB::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 536int 537RemoteGDB::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. 586bool 587RemoteGDB::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. 647bool 648RemoteGDB::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 705PCEventQueue *RemoteGDB::getPcEventQueue() 706{ 707 return &system->pcEventQueue; 708} 709 710 711RemoteGDB::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 719void 720RemoteGDB::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 728bool 729RemoteGDB::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 737bool 738RemoteGDB::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 746bool 747RemoteGDB::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 763bool 764RemoteGDB::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 784const char * 785break_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. 802bool 803RemoteGDB::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 sprintf((char *)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 sprintf((char *)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. 1115int 1116digit2i(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. 1130char 1131i2digit(int n) 1132{ 1133 return ("0123456789abcdef"[n & 0x0f]); 1134} 1135 1136// Convert a byte array into an hex string. 1137void 1138mem2hex(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. 1154const char * 1155hex2mem(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. 1175Addr 1176hex2i(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 1191