gem5  v20.1.0.0
remote_gdb.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018 ARM Limited
3  *
4  * The license below extends only to copyright in the software and shall
5  * not be construed as granting a license to any other intellectual
6  * property including but not limited to intellectual property relating
7  * to a hardware implementation of the functionality of the software
8  * licensed hereunder. You may use the software subject to the license
9  * terms below provided that you ensure that this notice is replicated
10  * unmodified and in its entirety in all distributions of the software,
11  * modified or unmodified, in source code or in binary form.
12  *
13  * Copyright 2015 LabWare
14  * Copyright 2014 Google, Inc.
15  * Copyright (c) 2002-2005 The Regents of The University of Michigan
16  * All rights reserved.
17  *
18  * Redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions are
20  * met: redistributions of source code must retain the above copyright
21  * notice, this list of conditions and the following disclaimer;
22  * redistributions in binary form must reproduce the above copyright
23  * notice, this list of conditions and the following disclaimer in the
24  * documentation and/or other materials provided with the distribution;
25  * neither the name of the copyright holders nor the names of its
26  * contributors may be used to endorse or promote products derived from
27  * this software without specific prior written permission.
28  *
29  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40  */
41 
42 /*
43  * Copyright (c) 1990, 1993 The Regents of the University of California
44  * All rights reserved
45  *
46  * This software was developed by the Computer Systems Engineering group
47  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
48  * contributed to Berkeley.
49  *
50  * 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, Lawrence Berkeley Laboratories.
54  *
55  * Redistribution and use in source and binary forms, with or without
56  * modification, are permitted provided that the following conditions
57  * are met:
58  * 1. Redistributions of source code must retain the above copyright
59  * notice, this list of conditions and the following disclaimer.
60  * 2. Redistributions in binary form must reproduce the above copyright
61  * notice, this list of conditions and the following disclaimer in the
62  * documentation and/or other materials provided with the distribution.
63  * 3. All advertising materials mentioning features or use of this software
64  * must display the following acknowledgement:
65  * This product includes software developed by the University of
66  * California, Berkeley and its contributors.
67  * 4. Neither the name of the University nor the names of its contributors
68  * may be used to endorse or promote products derived from this software
69  * without specific prior written permission.
70  *
71  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
72  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
73  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
74  * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
75  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
76  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
77  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
78  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
79  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
80  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
81  * SUCH DAMAGE.
82  *
83  * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94
84  */
85 
86 /*-
87  * Copyright (c) 2001 The NetBSD Foundation, Inc.
88  * All rights reserved.
89  *
90  * This code is derived from software contributed to The NetBSD Foundation
91  * by Jason R. Thorpe.
92  *
93  * Redistribution and use in source and binary forms, with or without
94  * modification, are permitted provided that the following conditions
95  * are met:
96  * 1. Redistributions of source code must retain the above copyright
97  * notice, this list of conditions and the following disclaimer.
98  * 2. Redistributions in binary form must reproduce the above copyright
99  * notice, this list of conditions and the following disclaimer in the
100  * documentation and/or other materials provided with the distribution.
101  * 3. All advertising materials mentioning features or use of this software
102  * must display the following acknowledgement:
103  * This product includes software developed by the NetBSD
104  * Foundation, Inc. and its contributors.
105  * 4. Neither the name of The NetBSD Foundation nor the names of its
106  * contributors may be used to endorse or promote products derived
107  * from this software without specific prior written permission.
108  *
109  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
110  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
111  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
112  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
113  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
114  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
115  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
116  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
117  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
118  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
119  * POSSIBILITY OF SUCH DAMAGE.
120  */
121 
122 /*
123  * $NetBSD: kgdb_stub.c,v 1.8 2001/07/07 22:58:00 wdk Exp $
124  *
125  * Taken from NetBSD
126  *
127  * "Stub" to allow remote cpu to debug over a serial line using gdb.
128  */
129 
130 #include "base/remote_gdb.hh"
131 
132 #include <sys/signal.h>
133 #include <unistd.h>
134 
135 #include <csignal>
136 #include <cstdint>
137 #include <cstdio>
138 #include <sstream>
139 #include <string>
140 
141 #include "base/intmath.hh"
142 #include "base/socket.hh"
143 #include "base/trace.hh"
144 #include "config/the_isa.hh"
145 #include "cpu/base.hh"
146 #include "cpu/static_inst.hh"
147 #include "cpu/thread_context.hh"
148 #include "debug/GDBAll.hh"
149 #include "mem/port.hh"
150 #include "mem/port_proxy.hh"
151 #include "sim/full_system.hh"
152 #include "sim/system.hh"
153 
154 using namespace std;
155 using namespace TheISA;
156 
157 static const char GDBStart = '$';
158 static const char GDBEnd = '#';
159 static const char GDBGoodP = '+';
160 static const char GDBBadP = '-';
161 
163 
164 class HardBreakpoint : public PCEvent
165 {
166  private:
168 
169  public:
170  int refcount;
171 
172  public:
174  : PCEvent(s, "HardBreakpoint Event", pc),
175  gdb(_gdb), refcount(0)
176  {
177  DPRINTF(GDBMisc, "creating hardware breakpoint at %#x\n", evpc);
178  }
179 
180  const std::string name() const override { return gdb->name() + ".hwbkpt"; }
181 
182  void
183  process(ThreadContext *tc) override
184  {
185  DPRINTF(GDBMisc, "handling hardware breakpoint at %#x\n", pc());
186 
187  if (tc == gdb->tc)
188  gdb->trap(SIGTRAP);
189  }
190 };
191 
192 namespace {
193 
194 // Exception to throw when the connection to the client is broken.
195 struct BadClient
196 {
197  const char *warning;
198  BadClient(const char *_warning=NULL) : warning(_warning)
199  {}
200 };
201 
202 // Exception to throw when an error needs to be reported to the client.
203 struct CmdError
204 {
205  string error;
206  CmdError(std::string _error) : error(_error)
207  {}
208 };
209 
210 // Exception to throw when something isn't supported.
211 class Unsupported {};
212 
213 // Convert a hex digit into an integer.
214 // This returns -1 if the argument passed is no valid hex digit.
215 int
216 digit2i(char c)
217 {
218  if (c >= '0' && c <= '9')
219  return (c - '0');
220  else if (c >= 'a' && c <= 'f')
221  return (c - 'a' + 10);
222  else if (c >= 'A' && c <= 'F')
223  return (c - 'A' + 10);
224  else
225  return (-1);
226 }
227 
228 // Convert the low 4 bits of an integer into an hex digit.
229 char
230 i2digit(int n)
231 {
232  return ("0123456789abcdef"[n & 0x0f]);
233 }
234 
235 // Convert a byte array into an hex string.
236 void
237 mem2hex(char *vdst, const char *vsrc, int len)
238 {
239  char *dst = vdst;
240  const char *src = vsrc;
241 
242  while (len--) {
243  *dst++ = i2digit(*src >> 4);
244  *dst++ = i2digit(*src++);
245  }
246  *dst = '\0';
247 }
248 
249 // Convert an hex string into a byte array.
250 // This returns a pointer to the character following the last valid
251 // hex digit. If the string ends in the middle of a byte, NULL is
252 // returned.
253 const char *
254 hex2mem(char *vdst, const char *src, int maxlen)
255 {
256  char *dst = vdst;
257  int msb, lsb;
258 
259  while (*src && maxlen--) {
260  msb = digit2i(*src++);
261  if (msb < 0)
262  return (src - 1);
263  lsb = digit2i(*src++);
264  if (lsb < 0)
265  return (NULL);
266  *dst++ = (msb << 4) | lsb;
267  }
268  return src;
269 }
270 
271 // Convert an hex string into an integer.
272 // This returns a pointer to the character following the last valid
273 // hex digit.
274 Addr
275 hex2i(const char **srcp)
276 {
277  const char *src = *srcp;
278  Addr r = 0;
279  int nibble;
280 
281  while ((nibble = digit2i(*src)) >= 0) {
282  r *= 16;
283  r += nibble;
284  src++;
285  }
286  *srcp = src;
287  return r;
288 }
289 
290 enum GdbBreakpointType {
291  GdbSoftBp = '0',
292  GdbHardBp = '1',
293  GdbWriteWp = '2',
294  GdbReadWp = '3',
295  GdbAccWp = '4',
296 };
297 
298 #ifndef NDEBUG
299 const char *
300 break_type(char c)
301 {
302  switch(c) {
303  case GdbSoftBp: return "software breakpoint";
304  case GdbHardBp: return "hardware breakpoint";
305  case GdbWriteWp: return "write watchpoint";
306  case GdbReadWp: return "read watchpoint";
307  case GdbAccWp: return "access watchpoint";
308  default: return "unknown breakpoint/watchpoint";
309  }
310 }
311 #endif
312 
313 std::map<Addr, HardBreakpoint *> hardBreakMap;
314 
315 }
316 
318  connectEvent(nullptr), dataEvent(nullptr), _port(_port), fd(-1),
319  active(false), attached(false), sys(_system), tc(c),
320  trapEvent(this), singleStepEvent(*this)
321 {
322  debuggers.push_back(this);
323 }
324 
326 {
327  delete connectEvent;
328  delete dataEvent;
329 }
330 
331 string
333 {
334  return sys->name() + ".remote_gdb";
335 }
336 
337 void
339 {
341  warn_once("Sockets disabled, not accepting gdb connections");
342  return;
343  }
344 
345  while (!listener.listen(_port, true)) {
346  DPRINTF(GDBMisc, "Can't bind port %d\n", _port);
347  _port++;
348  }
349 
350  connectEvent = new ConnectEvent(this, listener.getfd(), POLLIN);
352 
353  ccprintf(cerr, "%d: %s: listening for remote gdb on port %d\n",
354  curTick(), name(), _port);
355 }
356 
357 void
359 {
361  "Cannot accept GDB connections if we're not listening!");
362 
363  int sfd = listener.accept(true);
364 
365  if (sfd != -1) {
366  if (isAttached())
367  close(sfd);
368  else
369  attach(sfd);
370  }
371 }
372 
373 int
375 {
377  "Remote GDB port is unknown until listen() has been called.\n");
378  return _port;
379 }
380 
381 void
383 {
384  fd = f;
385 
386  dataEvent = new DataEvent(this, fd, POLLIN);
388 
389  attached = true;
390  DPRINTFN("remote gdb attached\n");
391 }
392 
393 void
395 {
396  attached = false;
397  active = false;
398  clearSingleStep();
399  close(fd);
400  fd = -1;
401 
403  DPRINTFN("remote gdb detached\n");
404 }
405 
406 // This function does all command processing for interfacing to a
407 // remote gdb. Note that the error codes are ignored by gdb at
408 // present, but might eventually become meaningful. (XXX) It might
409 // makes sense to use POSIX errno values, because that is what the
410 // gdb/remote.c functions want to return.
411 bool
413 {
414 
415  if (!attached)
416  return false;
417 
418  DPRINTF(GDBMisc, "trap: PC=%s\n", tc->pcState());
419 
420  clearSingleStep();
421 
422  /*
423  * The first entry to this function is normally through
424  * a breakpoint trap in kgdb_connect(), in which case we
425  * must advance past the breakpoint because gdb will not.
426  *
427  * On the first entry here, we expect that gdb is not yet
428  * listening to us, so just enter the interaction loop.
429  * After the debugger is "active" (connected) it will be
430  * waiting for a "signaled" message from us.
431  */
432  if (!active) {
433  active = true;
434  } else {
435  // Tell remote host that an exception has occurred.
436  send(csprintf("S%02x", type).c_str());
437  }
438 
439  // Stick frame regs into our reg cache.
440  regCachePtr = gdbRegs();
442 
443  GdbCommand::Context cmdCtx;
444  cmdCtx.type = type;
446 
447  for (;;) {
448  try {
449  recv(data);
450  if (data.size() == 1)
451  throw BadClient();
452  cmdCtx.cmd_byte = data[0];
453  cmdCtx.data = data.data() + 1;
454  // One for sentinel, one for cmd_byte.
455  cmdCtx.len = data.size() - 2;
456 
457  auto cmdIt = command_map.find(cmdCtx.cmd_byte);
458  if (cmdIt == command_map.end()) {
459  DPRINTF(GDBMisc, "Unknown command: %c(%#x)\n",
460  cmdCtx.cmd_byte, cmdCtx.cmd_byte);
461  throw Unsupported();
462  }
463  cmdCtx.cmd = &(cmdIt->second);
464 
465  if (!(this->*(cmdCtx.cmd->func))(cmdCtx))
466  break;
467 
468  } catch (BadClient &e) {
469  if (e.warning)
470  warn(e.warning);
471  detach();
472  break;
473  } catch (Unsupported &e) {
474  send("");
475  } catch (CmdError &e) {
476  send(e.error.c_str());
477  } catch (...) {
478  panic("Unrecognzied GDB exception.");
479  }
480  }
481 
482  return true;
483 }
484 
485 void
487 {
488  if (trapEvent.scheduled()) {
489  warn("GDB trap event has already been scheduled!");
490  return;
491  }
492 
493  if (revent & POLLIN) {
494  trapEvent.type(SIGILL);
496  } else if (revent & POLLNVAL) {
498  detach();
499  }
500 }
501 
502 uint8_t
504 {
505  uint8_t b;
506  if (::read(fd, &b, sizeof(b)) == sizeof(b))
507  return b;
508 
509  throw BadClient("Couldn't read data from debugger.");
510 }
511 
512 void
514 {
515  if (::write(fd, &b, sizeof(b)) == sizeof(b))
516  return;
517 
518  throw BadClient("Couldn't write data to the debugger.");
519 }
520 
521 // Receive a packet from gdb
522 void
524 {
525  uint8_t c;
526  int csum;
527  bp.resize(0);
528 
529  do {
530  csum = 0;
531  // Find the beginning of a packet
532  while ((c = getbyte()) != GDBStart);
533 
534  // Read until you find the end of the data in the packet, and keep
535  // track of the check sum.
536  while (true) {
537  c = getbyte();
538  if (c == GDBEnd)
539  break;
540  c &= 0x7f;
541  csum += c;
542  bp.push_back(c);
543  }
544 
545  // Mask the check sum.
546  csum &= 0xff;
547 
548  // Bring in the checksum. If the check sum matches, csum will be 0.
549  csum -= digit2i(getbyte()) * 16;
550  csum -= digit2i(getbyte());
551 
552  // If the check sum was correct
553  if (csum == 0) {
554  // Report that the packet was received correctly
555  putbyte(GDBGoodP);
556  // Sequence present?
557  if (bp.size() > 2 && bp[2] == ':') {
558  putbyte(bp[0]);
559  putbyte(bp[1]);
560  auto begin = std::begin(bp);
561  bp.erase(begin, std::next(begin, 3));
562  }
563  break;
564  }
565  // Otherwise, report that there was a mistake.
566  putbyte(GDBBadP);
567  } while (1);
568  // Sentinel.
569  bp.push_back('\0');
570  DPRINTF(GDBRecv, "recv: %s\n", bp.data());
571 }
572 
573 // Send a packet to gdb
574 void
575 BaseRemoteGDB::send(const char *bp)
576 {
577  const char *p;
578  uint8_t csum, c;
579 
580  DPRINTF(GDBSend, "send: %s\n", bp);
581 
582  do {
583  p = bp;
584  // Start sending a packet
585  putbyte(GDBStart);
586  // Send the contents, and also keep a check sum.
587  for (csum = 0; (c = *p); p++) {
588  putbyte(c);
589  csum += c;
590  }
591  // Send the ending character.
592  putbyte(GDBEnd);
593  // Send the checksum.
594  putbyte(i2digit(csum >> 4));
595  putbyte(i2digit(csum));
596  // Try transmitting over and over again until the other end doesn't
597  // send an error back.
598  c = getbyte();
599  } while ((c & 0x7f) == GDBBadP);
600 }
601 
602 // Read bytes from kernel address space for debugger.
603 bool
604 BaseRemoteGDB::read(Addr vaddr, size_t size, char *data)
605 {
606  DPRINTF(GDBRead, "read: addr=%#x, size=%d", vaddr, size);
607 
608  PortProxy &proxy = tc->getVirtProxy();
609  proxy.readBlob(vaddr, data, size);
610 
611 #if TRACING_ON
612  if (DTRACE(GDBRead)) {
613  if (DTRACE(GDBExtra)) {
614  char buf[1024];
615  mem2hex(buf, data, size);
616  DPRINTFNR(": %s\n", buf);
617  } else
618  DPRINTFNR("\n");
619  }
620 #endif
621 
622  return true;
623 }
624 
625 // Write bytes to kernel address space for debugger.
626 bool
627 BaseRemoteGDB::write(Addr vaddr, size_t size, const char *data)
628 {
629  if (DTRACE(GDBWrite)) {
630  DPRINTFN("write: addr=%#x, size=%d", vaddr, size);
631  if (DTRACE(GDBExtra)) {
632  char buf[1024];
633  mem2hex(buf, data, size);
634  DPRINTFNR(": %s\n", buf);
635  } else
636  DPRINTFNR("\n");
637  }
638  PortProxy &proxy = tc->getVirtProxy();
639  proxy.writeBlob(vaddr, data, size);
640 
641  return true;
642 }
643 
644 void
646 {
647  if (!singleStepEvent.scheduled())
649  trap(SIGTRAP);
650 }
651 
652 void
654 {
656 }
657 
658 void
660 {
661  if (!singleStepEvent.scheduled())
663 }
664 
665 void
667 {
668  if (!checkBpLen(len))
669  throw BadClient("Invalid breakpoint length\n");
670 
671  return insertHardBreak(addr, len);
672 }
673 
674 void
676 {
677  if (!checkBpLen(len))
678  throw BadClient("Invalid breakpoint length.\n");
679 
680  return removeHardBreak(addr, len);
681 }
682 
683 void
685 {
686  if (!checkBpLen(len))
687  throw BadClient("Invalid breakpoint length\n");
688 
689  DPRINTF(GDBMisc, "Inserting hardware breakpoint at %#x\n", addr);
690 
691  HardBreakpoint *&bkpt = hardBreakMap[addr];
692  if (bkpt == 0)
693  bkpt = new HardBreakpoint(this, sys, addr);
694 
695  bkpt->refcount++;
696 }
697 
698 void
700 {
701  if (!checkBpLen(len))
702  throw BadClient("Invalid breakpoint length\n");
703 
704  DPRINTF(GDBMisc, "Removing hardware breakpoint at %#x\n", addr);
705 
706  auto i = hardBreakMap.find(addr);
707  if (i == hardBreakMap.end())
708  throw CmdError("E0C");
709 
710  HardBreakpoint *hbp = (*i).second;
711  if (--hbp->refcount == 0) {
712  delete hbp;
713  hardBreakMap.erase(i);
714  }
715 }
716 
717 void
719 {
720  DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", bkpt);
721  removeHardBreak(bkpt, sizeof(TheISA::MachInst));
722  bkpt = 0;
723 }
724 
725 void
727 {
728  DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", bkpt);
729  insertHardBreak(bkpt, sizeof(TheISA::MachInst));
730 }
731 
732 void
734 {
735  // Here "ticks" aren't simulator ticks which measure time, they're
736  // instructions committed by the CPU.
738 }
739 
740 void
742 {
743  if (ev->scheduled())
745 }
746 
747 std::map<char, BaseRemoteGDB::GdbCommand> BaseRemoteGDB::command_map = {
748  // last signal
749  { '?', { "KGDB_SIGNAL", &BaseRemoteGDB::cmd_signal } },
750  // set baud (deprecated)
751  { 'b', { "KGDB_SET_BAUD", &BaseRemoteGDB::cmd_unsupported } },
752  // set breakpoint (deprecated)
753  { 'B', { "KGDB_SET_BREAK", &BaseRemoteGDB::cmd_unsupported } },
754  // resume
755  { 'c', { "KGDB_CONT", &BaseRemoteGDB::cmd_cont } },
756  // continue with signal
757  { 'C', { "KGDB_ASYNC_CONT", &BaseRemoteGDB::cmd_async_cont } },
758  // toggle debug flags (deprecated)
759  { 'd', { "KGDB_DEBUG", &BaseRemoteGDB::cmd_unsupported } },
760  // detach remote gdb
761  { 'D', { "KGDB_DETACH", &BaseRemoteGDB::cmd_detach } },
762  // read general registers
763  { 'g', { "KGDB_REG_R", &BaseRemoteGDB::cmd_reg_r } },
764  // write general registers
765  { 'G', { "KGDB_REG_W", &BaseRemoteGDB::cmd_reg_w } },
766  // set thread
767  { 'H', { "KGDB_SET_THREAD", &BaseRemoteGDB::cmd_set_thread } },
768  // step a single cycle
769  { 'i', { "KGDB_CYCLE_STEP", &BaseRemoteGDB::cmd_unsupported } },
770  // signal then cycle step
771  { 'I', { "KGDB_SIG_CYCLE_STEP", &BaseRemoteGDB::cmd_unsupported } },
772  // kill program
773  { 'k', { "KGDB_KILL", &BaseRemoteGDB::cmd_detach } },
774  // read memory
775  { 'm', { "KGDB_MEM_R", &BaseRemoteGDB::cmd_mem_r } },
776  // write memory
777  { 'M', { "KGDB_MEM_W", &BaseRemoteGDB::cmd_mem_w } },
778  // read register
779  { 'p', { "KGDB_READ_REG", &BaseRemoteGDB::cmd_unsupported } },
780  // write register
781  { 'P', { "KGDB_SET_REG", &BaseRemoteGDB::cmd_unsupported } },
782  // query variable
783  { 'q', { "KGDB_QUERY_VAR", &BaseRemoteGDB::cmd_query_var } },
784  // set variable
785  { 'Q', { "KGDB_SET_VAR", &BaseRemoteGDB::cmd_unsupported } },
786  // reset system (deprecated)
787  { 'r', { "KGDB_RESET", &BaseRemoteGDB::cmd_unsupported } },
788  // step
789  { 's', { "KGDB_STEP", &BaseRemoteGDB::cmd_step } },
790  // signal and step
791  { 'S', { "KGDB_ASYNC_STEP", &BaseRemoteGDB::cmd_async_step } },
792  // find out if the thread is alive
793  { 'T', { "KGDB_THREAD_ALIVE", &BaseRemoteGDB::cmd_unsupported } },
794  // target exited
795  { 'W', { "KGDB_TARGET_EXIT", &BaseRemoteGDB::cmd_unsupported } },
796  // write memory
797  { 'X', { "KGDB_BINARY_DLOAD", &BaseRemoteGDB::cmd_unsupported } },
798  // remove breakpoint or watchpoint
799  { 'z', { "KGDB_CLR_HW_BKPT", &BaseRemoteGDB::cmd_clr_hw_bkpt } },
800  // insert breakpoint or watchpoint
801  { 'Z', { "KGDB_SET_HW_BKPT", &BaseRemoteGDB::cmd_set_hw_bkpt } },
802 };
803 
804 bool
806 {
807  return len == sizeof(MachInst);
808 }
809 
810 bool
812 {
813  DPRINTF(GDBMisc, "Unsupported command: %s\n", ctx.cmd->name);
814  DDUMP(GDBMisc, ctx.data, ctx.len);
815  throw Unsupported();
816 }
817 
818 
819 bool
821 {
822  send(csprintf("S%02x", ctx.type).c_str());
823  return true;
824 }
825 
826 bool
828 {
829  const char *p = ctx.data;
830  if (ctx.len) {
831  Addr newPc = hex2i(&p);
832  tc->pcState(newPc);
833  }
834  clearSingleStep();
835  return false;
836 }
837 
838 bool
840 {
841  const char *p = ctx.data;
842  hex2i(&p);
843  if (*p++ == ';') {
844  Addr newPc = hex2i(&p);
845  tc->pcState(newPc);
846  }
847  clearSingleStep();
848  return false;
849 }
850 
851 bool
853 {
854  detach();
855  return false;
856 }
857 
858 bool
860 {
861  char buf[2 * regCachePtr->size() + 1];
862  buf[2 * regCachePtr->size()] = '\0';
863  mem2hex(buf, regCachePtr->data(), regCachePtr->size());
864  send(buf);
865  return true;
866 }
867 
868 bool
870 {
871  const char *p = ctx.data;
872  p = hex2mem(regCachePtr->data(), p, regCachePtr->size());
873  if (p == NULL || *p != '\0')
874  throw CmdError("E01");
875 
877  send("OK");
878 
879  return true;
880 }
881 
882 bool
884 {
885  const char *p = ctx.data + 1; // Ignore the subcommand byte.
886  if (hex2i(&p) != 0)
887  throw CmdError("E01");
888  send("OK");
889  return true;
890 }
891 
892 bool
894 {
895  const char *p = ctx.data;
896  Addr addr = hex2i(&p);
897  if (*p++ != ',')
898  throw CmdError("E02");
899  size_t len = hex2i(&p);
900  if (*p != '\0')
901  throw CmdError("E03");
902  if (!acc(addr, len))
903  throw CmdError("E05");
904 
905  char buf[len];
906  if (!read(addr, len, buf))
907  throw CmdError("E05");
908 
909  char temp[2 * len + 1];
910  temp[2 * len] = '\0';
911  mem2hex(temp, buf, len);
912  send(temp);
913  return true;
914 }
915 
916 bool
918 {
919  const char *p = ctx.data;
920  Addr addr = hex2i(&p);
921  if (*p++ != ',')
922  throw CmdError("E06");
923  size_t len = hex2i(&p);
924  if (*p++ != ':')
925  throw CmdError("E07");
926  if (len * 2 > ctx.len - (p - ctx.data))
927  throw CmdError("E08");
928  char buf[len];
929  p = (char *)hex2mem(buf, p, len);
930  if (p == NULL)
931  throw CmdError("E09");
932  if (!acc(addr, len))
933  throw CmdError("E0A");
934  if (!write(addr, len, buf))
935  throw CmdError("E0B");
936  send("OK");
937  return true;
938 }
939 
940 bool
942 {
943  string s(ctx.data, ctx.len - 1);
944  string xfer_read_prefix = "Xfer:features:read:";
945  if (s.rfind("Supported:", 0) == 0) {
946  std::ostringstream oss;
947  // This reply field mandatory. We can receive arbitrarily
948  // long packets, so we could choose it to be arbitrarily large.
949  // This is just an arbitrary filler value that seems to work.
950  oss << "PacketSize=1024";
951  for (const auto& feature : availableFeatures())
952  oss << ';' << feature;
953  send(oss.str().c_str());
954  } else if (s.rfind(xfer_read_prefix, 0) == 0) {
955  size_t offset, length;
956  auto value_string = s.substr(xfer_read_prefix.length());
957  auto colon_pos = value_string.find(':');
958  auto comma_pos = value_string.find(',');
959  if (colon_pos == std::string::npos || comma_pos == std::string::npos)
960  throw CmdError("E00");
961  std::string annex;
962  if (!getXferFeaturesRead(value_string.substr(0, colon_pos), annex))
963  throw CmdError("E00");
964  try {
965  offset = std::stoull(
966  value_string.substr(colon_pos + 1, comma_pos), NULL, 16);
967  length = std::stoull(
968  value_string.substr(comma_pos + 1), NULL, 16);
969  } catch (std::invalid_argument& e) {
970  throw CmdError("E00");
971  } catch (std::out_of_range& e) {
972  throw CmdError("E00");
973  }
974  std::string encoded;
975  encodeXferResponse(annex, encoded, offset, length);
976  send(encoded.c_str());
977  } else if (s == "C") {
978  send("QC0");
979  } else {
980  throw Unsupported();
981  }
982  return true;
983 }
984 
987 {
988  return {};
989 };
990 
991 bool
993  const std::string &annex, std::string &output)
994 {
995  return false;
996 }
997 
998 void
1000  const std::string &unencoded, std::string &encoded) const
1001 {
1002  for (const char& c : unencoded) {
1003  if (c == '$' || c == '#' || c == '}' || c == '*') {
1004  encoded += '}';
1005  encoded += c ^ 0x20;
1006  } else {
1007  encoded += c;
1008  }
1009  }
1010 }
1011 
1012 void
1013 BaseRemoteGDB::encodeXferResponse(const std::string &unencoded,
1014  std::string &encoded, size_t offset, size_t unencoded_length) const
1015 {
1016  if (offset + unencoded_length < unencoded.length())
1017  encoded += 'm';
1018  else
1019  encoded += 'l';
1020  encodeBinaryData(unencoded.substr(offset, unencoded_length), encoded);
1021 }
1022 
1023 bool
1025 {
1026  const char *p = ctx.data;
1027  hex2i(&p); // Ignore the subcommand byte.
1028  if (*p++ == ';') {
1029  Addr newPc = hex2i(&p);
1030  tc->pcState(newPc);
1031  }
1032  setSingleStep();
1033  return false;
1034 }
1035 
1036 bool
1038 {
1039  if (ctx.len) {
1040  const char *p = ctx.data;
1041  Addr newPc = hex2i(&p);
1042  tc->pcState(newPc);
1043  }
1044  setSingleStep();
1045  return false;
1046 }
1047 
1048 bool
1050 {
1051  const char *p = ctx.data;
1052  char subcmd = *p++;
1053  if (*p++ != ',')
1054  throw CmdError("E0D");
1055  Addr addr = hex2i(&p);
1056  if (*p++ != ',')
1057  throw CmdError("E0D");
1058  size_t len = hex2i(&p);
1059 
1060  DPRINTF(GDBMisc, "clear %s, addr=%#x, len=%d\n",
1061  break_type(subcmd), addr, len);
1062 
1063  switch (subcmd) {
1064  case GdbSoftBp:
1066  break;
1067  case GdbHardBp:
1069  break;
1070  case GdbWriteWp:
1071  case GdbReadWp:
1072  case GdbAccWp:
1073  default: // unknown
1074  throw Unsupported();
1075  }
1076  send("OK");
1077 
1078  return true;
1079 }
1080 
1081 bool
1083 {
1084  const char *p = ctx.data;
1085  char subcmd = *p++;
1086  if (*p++ != ',')
1087  throw CmdError("E0D");
1088  Addr addr = hex2i(&p);
1089  if (*p++ != ',')
1090  throw CmdError("E0D");
1091  size_t len = hex2i(&p);
1092 
1093  DPRINTF(GDBMisc, "set %s, addr=%#x, len=%d\n",
1094  break_type(subcmd), addr, len);
1095 
1096  switch (subcmd) {
1097  case GdbSoftBp:
1099  break;
1100  case GdbHardBp:
1102  break;
1103  case GdbWriteWp:
1104  case GdbReadWp:
1105  case GdbAccWp:
1106  default: // unknown
1107  throw Unsupported();
1108  }
1109  send("OK");
1110 
1111  return true;
1112 }
BaseRemoteGDB::command_map
static std::map< char, GdbCommand > command_map
Definition: remote_gdb.hh:284
BaseRemoteGDB::~BaseRemoteGDB
virtual ~BaseRemoteGDB()
Definition: remote_gdb.hh:51
BaseRemoteGDB::TrapEvent::type
void type(int t)
Definition: remote_gdb.hh:226
BaseRemoteGDB::port
int port() const
Definition: remote_gdb.cc:374
BaseRemoteGDB::attach
void attach(int fd)
Definition: remote_gdb.cc:382
output
static void output(const char *filename)
Definition: debug.cc:60
ThreadContext::descheduleInstCountEvent
virtual void descheduleInstCountEvent(Event *event)=0
BaseRemoteGDB::attached
bool attached
Definition: remote_gdb.hh:209
Event::scheduled
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:460
BaseRemoteGDB::singleStep
void singleStep()
Definition: remote_gdb.cc:645
socket.hh
BaseGdbRegCache::size
virtual size_t size() const =0
Return the size of the raw buffer, in bytes (i.e., half of the number of digits in the g/G packet).
BaseRemoteGDB::cmd_set_hw_bkpt
bool cmd_set_hw_bkpt(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1082
HardBreakpoint::refcount
int refcount
Definition: remote_gdb.cc:170
warn
#define warn(...)
Definition: logging.hh:239
length
uint8_t length
Definition: inet.hh:422
BaseRemoteGDB::encodeXferResponse
void encodeXferResponse(const std::string &unencoded, std::string &encoded, size_t offset, size_t unencoded_length) const
Definition: remote_gdb.cc:1013
ListenSocket::listen
virtual bool listen(int port, bool reuse=true)
Definition: socket.cc:99
system.hh
ThreadContext::getCurrentInstCount
virtual Tick getCurrentInstCount()=0
data
const char data[]
Definition: circlebuf.test.cc:42
BaseRemoteGDB::putbyte
void putbyte(uint8_t b)
Definition: remote_gdb.cc:513
BaseRemoteGDB::cmd_async_step
bool cmd_async_step(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1024
warn_once
#define warn_once(...)
Definition: logging.hh:243
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
HardBreakpoint
Definition: remote_gdb.cc:164
ArmISA::MachInst
uint32_t MachInst
Definition: types.hh:52
BaseRemoteGDB::cmd_signal
bool cmd_signal(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:820
remote_gdb.hh
BaseRemoteGDB::encodeBinaryData
void encodeBinaryData(const std::string &unencoded, std::string &encoded) const
Definition: remote_gdb.cc:999
ArmISA::fd
Bitfield< 14, 12 > fd
Definition: types.hh:159
TheISA
Definition: decode_cache.hh:37
HardBreakpoint::HardBreakpoint
HardBreakpoint(BaseRemoteGDB *_gdb, PCEventScope *s, Addr pc)
Definition: remote_gdb.cc:173
type
uint8_t type
Definition: inet.hh:421
BaseRemoteGDB::cmd_cont
bool cmd_cont(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:827
BaseRemoteGDB::cmd_unsupported
bool cmd_unsupported(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:811
ListenSocket::accept
virtual int accept(bool nodelay=false)
Definition: socket.cc:148
GDBStart
static const char GDBStart
Definition: remote_gdb.cc:157
BaseRemoteGDB::removeHardBreak
void removeHardBreak(Addr addr, size_t len)
Definition: remote_gdb.cc:699
BaseRemoteGDB::cmd_set_thread
bool cmd_set_thread(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:883
GDBEnd
static const char GDBEnd
Definition: remote_gdb.cc:158
BaseRemoteGDB::connect
void connect()
Definition: remote_gdb.cc:358
BaseRemoteGDB::incomingData
void incomingData(int revent)
Definition: remote_gdb.cc:486
DTRACE
#define DTRACE(x)
Definition: debug.hh:146
BaseRemoteGDB::DataEvent
SocketEvent<&BaseRemoteGDB::incomingData > DataEvent
Definition: remote_gdb.hh:184
std::vector
STL vector class.
Definition: stl.hh:37
BaseRemoteGDB::singleStepEvent
EventWrapper< BaseRemoteGDB, &BaseRemoteGDB::singleStep > singleStepEvent
Definition: remote_gdb.hh:242
PollQueue::schedule
void schedule(PollEvent *event)
Definition: pollevent.cc:159
BaseRemoteGDB::cmd_mem_r
bool cmd_mem_r(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:893
BaseRemoteGDB::tc
ThreadContext * tc
Definition: remote_gdb.hh:212
BaseRemoteGDB::GdbCommand::Context::len
int len
Definition: remote_gdb.hh:273
BaseRemoteGDB::clearSingleStep
void clearSingleStep()
Definition: remote_gdb.cc:653
PortProxy::writeBlob
void writeBlob(Addr addr, const void *p, int size) const
Same as tryWriteBlob, but insists on success.
Definition: port_proxy.hh:187
ArmISA::n
Bitfield< 31 > n
Definition: miscregs_types.hh:450
HardBreakpoint::gdb
BaseRemoteGDB * gdb
Definition: remote_gdb.cc:167
BaseRemoteGDB::insertSoftBreak
void insertSoftBreak(Addr addr, size_t len)
Definition: remote_gdb.cc:666
pollQueue
PollQueue pollQueue
Definition: pollevent.cc:55
BaseRemoteGDB::setSingleStep
void setSingleStep()
Definition: remote_gdb.cc:659
GDBBadP
static const char GDBBadP
Definition: remote_gdb.cc:160
DPRINTFNR
#define DPRINTFNR(...)
Definition: trace.hh:239
BaseRemoteGDB::GdbCommand::func
const Func func
Definition: remote_gdb.hh:279
BaseRemoteGDB::listener
ListenSocket listener
Definition: remote_gdb.hh:192
BaseRemoteGDB::clearTempBreakpoint
void clearTempBreakpoint(Addr &bkpt)
Definition: remote_gdb.cc:718
ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:88
BaseRemoteGDB::trap
bool trap(int type)
Definition: remote_gdb.cc:412
Event
Definition: eventq.hh:246
BaseRemoteGDB::GdbCommand::Context::cmd
const GdbCommand * cmd
Definition: remote_gdb.hh:269
System
Definition: system.hh:73
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:234
BaseRemoteGDB::_port
int _port
Definition: remote_gdb.hh:193
ListenSocket::getfd
int getfd() const
Definition: socket.hh:72
BaseRemoteGDB::scheduleInstCommitEvent
void scheduleInstCommitEvent(Event *ev, int delta)
Schedule an event which will be triggered "delta" instructions later.
Definition: remote_gdb.cc:733
MipsISA::vaddr
vaddr
Definition: pra_constants.hh:275
MipsISA::pc
Bitfield< 4 > pc
Definition: pra_constants.hh:240
BaseRemoteGDB::getbyte
uint8_t getbyte()
Definition: remote_gdb.cc:503
BaseRemoteGDB::write
bool write(Addr addr, size_t size, const char *data)
Definition: remote_gdb.cc:627
BaseRemoteGDB::gdbRegs
virtual BaseGdbRegCache * gdbRegs()=0
MipsISA::r
r
Definition: pra_constants.hh:95
port_proxy.hh
BaseRemoteGDB::HardBreakpoint
friend class HardBreakpoint
Definition: remote_gdb.hh:130
HardBreakpoint::process
void process(ThreadContext *tc) override
Definition: remote_gdb.cc:183
port.hh
ListenSocket::islistening
bool islistening() const
Definition: socket.hh:73
BaseRemoteGDB::descheduleInstCommitEvent
void descheduleInstCommitEvent(Event *ev)
Deschedule an instruction count based event.
Definition: remote_gdb.cc:741
BaseRemoteGDB::GdbCommand::name
const char *const name
Definition: remote_gdb.hh:278
static_inst.hh
PCEventScope
Definition: pc_event.hh:64
BaseGdbRegCache::data
virtual char * data() const =0
Return the pointer to the raw bytes buffer containing the register values.
BaseRemoteGDB::sys
System * sys
Definition: remote_gdb.hh:211
BaseRemoteGDB::cmd_mem_w
bool cmd_mem_w(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:917
BaseRemoteGDB
Definition: remote_gdb.hh:43
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
BaseRemoteGDB::dataEvent
DataEvent * dataEvent
Definition: remote_gdb.hh:190
BaseRemoteGDB::acc
virtual bool acc(Addr addr, size_t len)=0
BaseRemoteGDB::isAttached
bool isAttached()
Definition: remote_gdb.hh:153
BaseRemoteGDB::connectEvent
ConnectEvent * connectEvent
Definition: remote_gdb.hh:189
DDUMP
#define DDUMP(x, data, count)
DPRINTF is a debugging trace facility that allows one to selectively enable tracing statements.
Definition: trace.hh:233
full_system.hh
BaseGdbRegCache::setRegs
virtual void setRegs(ThreadContext *) const =0
Set the ThreadContext's registers from the values in the raw buffer.
BaseRemoteGDB::cmd_async_cont
bool cmd_async_cont(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:839
ArmISA::e
Bitfield< 9 > e
Definition: miscregs_types.hh:61
ThreadContext::pcState
virtual TheISA::PCState pcState() const =0
BaseRemoteGDB::GdbCommand::Context::cmd_byte
char cmd_byte
Definition: remote_gdb.hh:270
SimObject::name
virtual const std::string name() const
Definition: sim_object.hh:133
BaseRemoteGDB::cmd_detach
bool cmd_detach(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:852
ThreadContext::getVirtProxy
virtual PortProxy & getVirtProxy()=0
BaseRemoteGDB::getXferFeaturesRead
virtual bool getXferFeaturesRead(const std::string &annex, std::string &output)
Get an XML target description.
Definition: remote_gdb.cc:992
ThreadContext::scheduleInstCountEvent
virtual void scheduleInstCountEvent(Event *event, Tick count)=0
ListenSocket::allDisabled
static bool allDisabled()
Definition: socket.cc:70
panic_if
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:197
BaseRemoteGDB::GdbCommand::Context::type
int type
Definition: remote_gdb.hh:271
BaseRemoteGDB::removeSoftBreak
void removeSoftBreak(Addr addr, size_t len)
Definition: remote_gdb.cc:675
BaseRemoteGDB::availableFeatures
virtual std::vector< std::string > availableFeatures() const
Definition: remote_gdb.cc:986
PortProxy
This object is a proxy for a port or other object which implements the functional response protocol,...
Definition: port_proxy.hh:80
ArmISA::b
Bitfield< 7 > b
Definition: miscregs_types.hh:376
BaseRemoteGDB::cmd_query_var
bool cmd_query_var(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:941
PollQueue::remove
void remove(PollEvent *event)
Definition: pollevent.cc:139
base.hh
BaseRemoteGDB::cmd_clr_hw_bkpt
bool cmd_clr_hw_bkpt(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1049
std
Overload hash function for BasicBlockRange type.
Definition: vec_reg.hh:587
BaseRemoteGDB::active
bool active
Definition: remote_gdb.hh:208
BaseRemoteGDB::fd
int fd
Definition: remote_gdb.hh:196
BaseRemoteGDB::cmd_step
bool cmd_step(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1037
ArmISA::len
Bitfield< 18, 16 > len
Definition: miscregs_types.hh:439
addr
ip6_addr_t addr
Definition: inet.hh:423
ccprintf
void ccprintf(cp::Print &print)
Definition: cprintf.hh:127
BaseRemoteGDB::name
std::string name()
Definition: remote_gdb.cc:332
BaseRemoteGDB::insertHardBreak
void insertHardBreak(Addr addr, size_t len)
Definition: remote_gdb.cc:684
GDBGoodP
static const char GDBGoodP
Definition: remote_gdb.cc:159
BaseRemoteGDB::checkBpLen
virtual bool checkBpLen(size_t len)
Definition: remote_gdb.cc:805
ArmISA::c
Bitfield< 29 > c
Definition: miscregs_types.hh:50
PCEvent
Definition: pc_event.hh:42
trace.hh
BaseRemoteGDB::ConnectEvent
SocketEvent<&BaseRemoteGDB::connectWrapper > ConnectEvent
Definition: remote_gdb.hh:183
DPRINTFN
#define DPRINTFN(...)
Definition: trace.hh:238
BaseRemoteGDB::GdbCommand::Context
Definition: remote_gdb.hh:267
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
intmath.hh
HardBreakpoint::name
const std::string name() const override
Definition: remote_gdb.cc:180
ArmISA::s
Bitfield< 4 > s
Definition: miscregs_types.hh:556
BaseRemoteGDB::listen
void listen()
Definition: remote_gdb.cc:338
BaseRemoteGDB::cmd_reg_r
bool cmd_reg_r(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:859
BaseRemoteGDB::trapEvent
BaseRemoteGDB::TrapEvent trapEvent
BaseRemoteGDB::regCachePtr
BaseGdbRegCache * regCachePtr
Definition: remote_gdb.hh:214
BaseRemoteGDB::setTempBreakpoint
void setTempBreakpoint(Addr bkpt)
Definition: remote_gdb.cc:726
PortProxy::readBlob
void readBlob(Addr addr, void *p, int size) const
Higher level interfaces based on the above.
Definition: port_proxy.hh:177
BaseRemoteGDB::read
bool read(Addr addr, size_t size, char *data)
Definition: remote_gdb.cc:604
BaseRemoteGDB::GdbCommand::Context::data
char * data
Definition: remote_gdb.hh:272
csprintf
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:158
thread_context.hh
BaseRemoteGDB::detach
void detach()
Definition: remote_gdb.cc:394
BaseRemoteGDB::recv
void recv(std::vector< char > &bp)
Definition: remote_gdb.cc:523
BaseRemoteGDB::cmd_reg_w
bool cmd_reg_w(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:869
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
debuggers
vector< BaseRemoteGDB * > debuggers
Definition: remote_gdb.cc:162
ArmISA::f
Bitfield< 6 > f
Definition: miscregs_types.hh:64
BaseRemoteGDB::BaseRemoteGDB
BaseRemoteGDB(System *system, ThreadContext *context, int _port)
Interface to other parts of the simulator.
Definition: remote_gdb.cc:317
BaseGdbRegCache::getRegs
virtual void getRegs(ThreadContext *)=0
Fill the raw buffer from the registers in the ThreadContext.
curTick
Tick curTick()
The current simulated tick.
Definition: core.hh:45
ArmISA::offset
Bitfield< 23, 0 > offset
Definition: types.hh:153
BaseRemoteGDB::send
void send(const char *data)
Definition: remote_gdb.cc:575

Generated on Wed Sep 30 2020 14:02:01 for gem5 by doxygen 1.8.17