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