gem5  v21.0.1.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 "cpu/base.hh"
145 #include "cpu/static_inst.hh"
146 #include "cpu/thread_context.hh"
147 #include "debug/GDBAll.hh"
148 #include "mem/port.hh"
149 #include "mem/port_proxy.hh"
150 #include "sim/full_system.hh"
151 #include "sim/system.hh"
152 
153 static const char GDBStart = '$';
154 static const char GDBEnd = '#';
155 static const char GDBGoodP = '+';
156 static const char GDBBadP = '-';
157 
159 
160 class HardBreakpoint : public PCEvent
161 {
162  private:
164 
165  public:
166  int refcount;
167 
168  public:
170  : PCEvent(s, "HardBreakpoint Event", pc),
171  gdb(_gdb), refcount(0)
172  {
173  DPRINTF(GDBMisc, "creating hardware breakpoint at %#x\n", evpc);
174  }
175 
176  const std::string name() const override { return gdb->name() + ".hwbkpt"; }
177 
178  void
179  process(ThreadContext *tc) override
180  {
181  DPRINTF(GDBMisc, "handling hardware breakpoint at %#x\n", pc());
182 
183  if (tc == gdb->tc)
184  gdb->trap(SIGTRAP);
185  }
186 };
187 
188 namespace {
189 
190 // Exception to throw when the connection to the client is broken.
191 struct BadClient
192 {
193  const char *warning;
194  BadClient(const char *_warning=NULL) : warning(_warning)
195  {}
196 };
197 
198 // Exception to throw when an error needs to be reported to the client.
199 struct CmdError
200 {
201  std::string error;
202  CmdError(std::string _error) : error(_error)
203  {}
204 };
205 
206 // Exception to throw when something isn't supported.
207 class Unsupported {};
208 
209 // Convert a hex digit into an integer.
210 // This returns -1 if the argument passed is no valid hex digit.
211 int
212 digit2i(char c)
213 {
214  if (c >= '0' && c <= '9')
215  return (c - '0');
216  else if (c >= 'a' && c <= 'f')
217  return (c - 'a' + 10);
218  else if (c >= 'A' && c <= 'F')
219  return (c - 'A' + 10);
220  else
221  return (-1);
222 }
223 
224 // Convert the low 4 bits of an integer into an hex digit.
225 char
226 i2digit(int n)
227 {
228  return ("0123456789abcdef"[n & 0x0f]);
229 }
230 
231 // Convert a byte array into an hex string.
232 void
233 mem2hex(char *vdst, const char *vsrc, int len)
234 {
235  char *dst = vdst;
236  const char *src = vsrc;
237 
238  while (len--) {
239  *dst++ = i2digit(*src >> 4);
240  *dst++ = i2digit(*src++);
241  }
242  *dst = '\0';
243 }
244 
245 // Convert an hex string into a byte array.
246 // This returns a pointer to the character following the last valid
247 // hex digit. If the string ends in the middle of a byte, NULL is
248 // returned.
249 const char *
250 hex2mem(char *vdst, const char *src, int maxlen)
251 {
252  char *dst = vdst;
253  int msb, lsb;
254 
255  while (*src && maxlen--) {
256  msb = digit2i(*src++);
257  if (msb < 0)
258  return (src - 1);
259  lsb = digit2i(*src++);
260  if (lsb < 0)
261  return (NULL);
262  *dst++ = (msb << 4) | lsb;
263  }
264  return src;
265 }
266 
267 // Convert an hex string into an integer.
268 // This returns a pointer to the character following the last valid
269 // hex digit.
270 Addr
271 hex2i(const char **srcp)
272 {
273  const char *src = *srcp;
274  Addr r = 0;
275  int nibble;
276 
277  while ((nibble = digit2i(*src)) >= 0) {
278  r *= 16;
279  r += nibble;
280  src++;
281  }
282  *srcp = src;
283  return r;
284 }
285 
286 enum GdbBreakpointType {
287  GdbSoftBp = '0',
288  GdbHardBp = '1',
289  GdbWriteWp = '2',
290  GdbReadWp = '3',
291  GdbAccWp = '4',
292 };
293 
294 #ifndef NDEBUG
295 const char *
296 break_type(char c)
297 {
298  switch(c) {
299  case GdbSoftBp: return "software breakpoint";
300  case GdbHardBp: return "hardware breakpoint";
301  case GdbWriteWp: return "write watchpoint";
302  case GdbReadWp: return "read watchpoint";
303  case GdbAccWp: return "access watchpoint";
304  default: return "unknown breakpoint/watchpoint";
305  }
306 }
307 #endif
308 
309 std::map<Addr, HardBreakpoint *> hardBreakMap;
310 
311 }
312 
314  connectEvent(nullptr), dataEvent(nullptr), _port(_port), fd(-1),
315  active(false), attached(false), sys(_system), tc(c),
316  trapEvent(this), singleStepEvent(*this)
317 {
318  debuggers.push_back(this);
319 }
320 
322 {
323  delete connectEvent;
324  delete dataEvent;
325 }
326 
327 std::string
329 {
330  return sys->name() + ".remote_gdb";
331 }
332 
333 void
335 {
337  warn_once("Sockets disabled, not accepting gdb connections");
338  return;
339  }
340 
341  while (!listener.listen(_port, true)) {
342  DPRINTF(GDBMisc, "Can't bind port %d\n", _port);
343  _port++;
344  }
345 
346  connectEvent = new ConnectEvent(this, listener.getfd(), POLLIN);
348 
349  ccprintf(std::cerr, "%d: %s: listening for remote gdb on port %d\n",
350  curTick(), name(), _port);
351 }
352 
353 void
355 {
357  "Cannot accept GDB connections if we're not listening!");
358 
359  int sfd = listener.accept(true);
360 
361  if (sfd != -1) {
362  if (isAttached())
363  close(sfd);
364  else
365  attach(sfd);
366  }
367 }
368 
369 int
371 {
373  "Remote GDB port is unknown until listen() has been called.\n");
374  return _port;
375 }
376 
377 void
379 {
380  fd = f;
381 
382  dataEvent = new DataEvent(this, fd, POLLIN);
384 
385  attached = true;
386  DPRINTFN("remote gdb attached\n");
387 }
388 
389 void
391 {
392  attached = false;
393  active = false;
394  clearSingleStep();
395  close(fd);
396  fd = -1;
397 
399  DPRINTFN("remote gdb detached\n");
400 }
401 
402 // This function does all command processing for interfacing to a
403 // remote gdb. Note that the error codes are ignored by gdb at
404 // present, but might eventually become meaningful. (XXX) It might
405 // makes sense to use POSIX errno values, because that is what the
406 // gdb/remote.c functions want to return.
407 bool
409 {
410 
411  if (!attached)
412  return false;
413 
414  DPRINTF(GDBMisc, "trap: PC=%s\n", tc->pcState());
415 
416  clearSingleStep();
417 
418  /*
419  * The first entry to this function is normally through
420  * a breakpoint trap in kgdb_connect(), in which case we
421  * must advance past the breakpoint because gdb will not.
422  *
423  * On the first entry here, we expect that gdb is not yet
424  * listening to us, so just enter the interaction loop.
425  * After the debugger is "active" (connected) it will be
426  * waiting for a "signaled" message from us.
427  */
428  if (!active) {
429  active = true;
430  } else {
431  // Tell remote host that an exception has occurred.
432  send(csprintf("S%02x", type).c_str());
433  }
434 
435  // Stick frame regs into our reg cache.
436  regCachePtr = gdbRegs();
438 
439  GdbCommand::Context cmdCtx;
440  cmdCtx.type = type;
442 
443  for (;;) {
444  try {
445  recv(data);
446  if (data.size() == 1)
447  throw BadClient();
448  cmdCtx.cmd_byte = data[0];
449  cmdCtx.data = data.data() + 1;
450  // One for sentinel, one for cmd_byte.
451  cmdCtx.len = data.size() - 2;
452 
453  auto cmdIt = command_map.find(cmdCtx.cmd_byte);
454  if (cmdIt == command_map.end()) {
455  DPRINTF(GDBMisc, "Unknown command: %c(%#x)\n",
456  cmdCtx.cmd_byte, cmdCtx.cmd_byte);
457  throw Unsupported();
458  }
459  cmdCtx.cmd = &(cmdIt->second);
460 
461  if (!(this->*(cmdCtx.cmd->func))(cmdCtx))
462  break;
463 
464  } catch (BadClient &e) {
465  if (e.warning)
466  warn(e.warning);
467  detach();
468  break;
469  } catch (Unsupported &e) {
470  send("");
471  } catch (CmdError &e) {
472  send(e.error.c_str());
473  } catch (...) {
474  panic("Unrecognzied GDB exception.");
475  }
476  }
477 
478  return true;
479 }
480 
481 void
483 {
484  if (trapEvent.scheduled()) {
485  warn("GDB trap event has already been scheduled!");
486  return;
487  }
488 
489  if (revent & POLLIN) {
490  trapEvent.type(SIGILL);
492  } else if (revent & POLLNVAL) {
494  detach();
495  }
496 }
497 
498 uint8_t
500 {
501  uint8_t b;
502  if (::read(fd, &b, sizeof(b)) == sizeof(b))
503  return b;
504 
505  throw BadClient("Couldn't read data from debugger.");
506 }
507 
508 void
510 {
511  if (::write(fd, &b, sizeof(b)) == sizeof(b))
512  return;
513 
514  throw BadClient("Couldn't write data to the debugger.");
515 }
516 
517 // Receive a packet from gdb
518 void
520 {
521  uint8_t c;
522  int csum;
523  bp.resize(0);
524 
525  do {
526  csum = 0;
527  // Find the beginning of a packet
528  while ((c = getbyte()) != GDBStart);
529 
530  // Read until you find the end of the data in the packet, and keep
531  // track of the check sum.
532  while (true) {
533  c = getbyte();
534  if (c == GDBEnd)
535  break;
536  c &= 0x7f;
537  csum += c;
538  bp.push_back(c);
539  }
540 
541  // Mask the check sum.
542  csum &= 0xff;
543 
544  // Bring in the checksum. If the check sum matches, csum will be 0.
545  csum -= digit2i(getbyte()) * 16;
546  csum -= digit2i(getbyte());
547 
548  // If the check sum was correct
549  if (csum == 0) {
550  // Report that the packet was received correctly
551  putbyte(GDBGoodP);
552  // Sequence present?
553  if (bp.size() > 2 && bp[2] == ':') {
554  putbyte(bp[0]);
555  putbyte(bp[1]);
556  auto begin = std::begin(bp);
557  bp.erase(begin, std::next(begin, 3));
558  }
559  break;
560  }
561  // Otherwise, report that there was a mistake.
562  putbyte(GDBBadP);
563  } while (1);
564  // Sentinel.
565  bp.push_back('\0');
566  DPRINTF(GDBRecv, "recv: %s\n", bp.data());
567 }
568 
569 // Send a packet to gdb
570 void
571 BaseRemoteGDB::send(const char *bp)
572 {
573  const char *p;
574  uint8_t csum, c;
575 
576  DPRINTF(GDBSend, "send: %s\n", bp);
577 
578  do {
579  p = bp;
580  // Start sending a packet
581  putbyte(GDBStart);
582  // Send the contents, and also keep a check sum.
583  for (csum = 0; (c = *p); p++) {
584  putbyte(c);
585  csum += c;
586  }
587  // Send the ending character.
588  putbyte(GDBEnd);
589  // Send the checksum.
590  putbyte(i2digit(csum >> 4));
591  putbyte(i2digit(csum));
592  // Try transmitting over and over again until the other end doesn't
593  // send an error back.
594  c = getbyte();
595  } while ((c & 0x7f) == GDBBadP);
596 }
597 
598 // Read bytes from kernel address space for debugger.
599 bool
600 BaseRemoteGDB::read(Addr vaddr, size_t size, char *data)
601 {
602  DPRINTF(GDBRead, "read: addr=%#x, size=%d", vaddr, size);
603 
604  PortProxy &proxy = tc->getVirtProxy();
605  proxy.readBlob(vaddr, data, size);
606 
607 #if TRACING_ON
608  if (DTRACE(GDBRead)) {
609  if (DTRACE(GDBExtra)) {
610  char buf[1024];
611  mem2hex(buf, data, size);
612  DPRINTFNR(": %s\n", buf);
613  } else
614  DPRINTFNR("\n");
615  }
616 #endif
617 
618  return true;
619 }
620 
621 // Write bytes to kernel address space for debugger.
622 bool
623 BaseRemoteGDB::write(Addr vaddr, size_t size, const char *data)
624 {
625  if (DTRACE(GDBWrite)) {
626  DPRINTFN("write: addr=%#x, size=%d", vaddr, size);
627  if (DTRACE(GDBExtra)) {
628  char buf[1024];
629  mem2hex(buf, data, size);
630  DPRINTFNR(": %s\n", buf);
631  } else
632  DPRINTFNR("\n");
633  }
634  PortProxy &proxy = tc->getVirtProxy();
635  proxy.writeBlob(vaddr, data, size);
636 
637  return true;
638 }
639 
640 void
642 {
643  if (!singleStepEvent.scheduled())
645  trap(SIGTRAP);
646 }
647 
648 void
650 {
652 }
653 
654 void
656 {
657  if (!singleStepEvent.scheduled())
659 }
660 
661 void
663 {
664  if (!checkBpLen(len))
665  throw BadClient("Invalid breakpoint length\n");
666 
667  return insertHardBreak(addr, len);
668 }
669 
670 void
672 {
673  if (!checkBpLen(len))
674  throw BadClient("Invalid breakpoint length.\n");
675 
676  return removeHardBreak(addr, len);
677 }
678 
679 void
681 {
682  if (!checkBpLen(len))
683  throw BadClient("Invalid breakpoint length\n");
684 
685  DPRINTF(GDBMisc, "Inserting hardware breakpoint at %#x\n", addr);
686 
687  HardBreakpoint *&bkpt = hardBreakMap[addr];
688  if (bkpt == 0)
689  bkpt = new HardBreakpoint(this, sys, addr);
690 
691  bkpt->refcount++;
692 }
693 
694 void
696 {
697  if (!checkBpLen(len))
698  throw BadClient("Invalid breakpoint length\n");
699 
700  DPRINTF(GDBMisc, "Removing hardware breakpoint at %#x\n", addr);
701 
702  auto i = hardBreakMap.find(addr);
703  if (i == hardBreakMap.end())
704  throw CmdError("E0C");
705 
706  HardBreakpoint *hbp = (*i).second;
707  if (--hbp->refcount == 0) {
708  delete hbp;
709  hardBreakMap.erase(i);
710  }
711 }
712 
713 void
715 {
716  // Here "ticks" aren't simulator ticks which measure time, they're
717  // instructions committed by the CPU.
719 }
720 
721 void
723 {
724  if (ev->scheduled())
726 }
727 
728 std::map<char, BaseRemoteGDB::GdbCommand> BaseRemoteGDB::command_map = {
729  // last signal
730  { '?', { "KGDB_SIGNAL", &BaseRemoteGDB::cmd_signal } },
731  // set baud (deprecated)
732  { 'b', { "KGDB_SET_BAUD", &BaseRemoteGDB::cmd_unsupported } },
733  // set breakpoint (deprecated)
734  { 'B', { "KGDB_SET_BREAK", &BaseRemoteGDB::cmd_unsupported } },
735  // resume
736  { 'c', { "KGDB_CONT", &BaseRemoteGDB::cmd_cont } },
737  // continue with signal
738  { 'C', { "KGDB_ASYNC_CONT", &BaseRemoteGDB::cmd_async_cont } },
739  // toggle debug flags (deprecated)
740  { 'd', { "KGDB_DEBUG", &BaseRemoteGDB::cmd_unsupported } },
741  // detach remote gdb
742  { 'D', { "KGDB_DETACH", &BaseRemoteGDB::cmd_detach } },
743  // read general registers
744  { 'g', { "KGDB_REG_R", &BaseRemoteGDB::cmd_reg_r } },
745  // write general registers
746  { 'G', { "KGDB_REG_W", &BaseRemoteGDB::cmd_reg_w } },
747  // set thread
748  { 'H', { "KGDB_SET_THREAD", &BaseRemoteGDB::cmd_set_thread } },
749  // step a single cycle
750  { 'i', { "KGDB_CYCLE_STEP", &BaseRemoteGDB::cmd_unsupported } },
751  // signal then cycle step
752  { 'I', { "KGDB_SIG_CYCLE_STEP", &BaseRemoteGDB::cmd_unsupported } },
753  // kill program
754  { 'k', { "KGDB_KILL", &BaseRemoteGDB::cmd_detach } },
755  // read memory
756  { 'm', { "KGDB_MEM_R", &BaseRemoteGDB::cmd_mem_r } },
757  // write memory
758  { 'M', { "KGDB_MEM_W", &BaseRemoteGDB::cmd_mem_w } },
759  // read register
760  { 'p', { "KGDB_READ_REG", &BaseRemoteGDB::cmd_unsupported } },
761  // write register
762  { 'P', { "KGDB_SET_REG", &BaseRemoteGDB::cmd_unsupported } },
763  // query variable
764  { 'q', { "KGDB_QUERY_VAR", &BaseRemoteGDB::cmd_query_var } },
765  // set variable
766  { 'Q', { "KGDB_SET_VAR", &BaseRemoteGDB::cmd_unsupported } },
767  // reset system (deprecated)
768  { 'r', { "KGDB_RESET", &BaseRemoteGDB::cmd_unsupported } },
769  // step
770  { 's', { "KGDB_STEP", &BaseRemoteGDB::cmd_step } },
771  // signal and step
772  { 'S', { "KGDB_ASYNC_STEP", &BaseRemoteGDB::cmd_async_step } },
773  // find out if the thread is alive
774  { 'T', { "KGDB_THREAD_ALIVE", &BaseRemoteGDB::cmd_unsupported } },
775  // target exited
776  { 'W', { "KGDB_TARGET_EXIT", &BaseRemoteGDB::cmd_unsupported } },
777  // write memory
778  { 'X', { "KGDB_BINARY_DLOAD", &BaseRemoteGDB::cmd_unsupported } },
779  // remove breakpoint or watchpoint
780  { 'z', { "KGDB_CLR_HW_BKPT", &BaseRemoteGDB::cmd_clr_hw_bkpt } },
781  // insert breakpoint or watchpoint
782  { 'Z', { "KGDB_SET_HW_BKPT", &BaseRemoteGDB::cmd_set_hw_bkpt } },
783 };
784 
785 bool
787 {
788  return true;
789 }
790 
791 bool
793 {
794  DPRINTF(GDBMisc, "Unsupported command: %s\n", ctx.cmd->name);
795  DDUMP(GDBMisc, ctx.data, ctx.len);
796  throw Unsupported();
797 }
798 
799 
800 bool
802 {
803  send(csprintf("S%02x", ctx.type).c_str());
804  return true;
805 }
806 
807 bool
809 {
810  const char *p = ctx.data;
811  if (ctx.len) {
812  Addr newPc = hex2i(&p);
813  tc->pcState(newPc);
814  }
815  clearSingleStep();
816  return false;
817 }
818 
819 bool
821 {
822  const char *p = ctx.data;
823  hex2i(&p);
824  if (*p++ == ';') {
825  Addr newPc = hex2i(&p);
826  tc->pcState(newPc);
827  }
828  clearSingleStep();
829  return false;
830 }
831 
832 bool
834 {
835  detach();
836  return false;
837 }
838 
839 bool
841 {
842  char buf[2 * regCachePtr->size() + 1];
843  buf[2 * regCachePtr->size()] = '\0';
844  mem2hex(buf, regCachePtr->data(), regCachePtr->size());
845  send(buf);
846  return true;
847 }
848 
849 bool
851 {
852  const char *p = ctx.data;
853  p = hex2mem(regCachePtr->data(), p, regCachePtr->size());
854  if (p == NULL || *p != '\0')
855  throw CmdError("E01");
856 
858  send("OK");
859 
860  return true;
861 }
862 
863 bool
865 {
866  const char *p = ctx.data + 1; // Ignore the subcommand byte.
867  if (hex2i(&p) != 0)
868  throw CmdError("E01");
869  send("OK");
870  return true;
871 }
872 
873 bool
875 {
876  const char *p = ctx.data;
877  Addr addr = hex2i(&p);
878  if (*p++ != ',')
879  throw CmdError("E02");
880  size_t len = hex2i(&p);
881  if (*p != '\0')
882  throw CmdError("E03");
883  if (!acc(addr, len))
884  throw CmdError("E05");
885 
886  char buf[len];
887  if (!read(addr, len, buf))
888  throw CmdError("E05");
889 
890  char temp[2 * len + 1];
891  temp[2 * len] = '\0';
892  mem2hex(temp, buf, len);
893  send(temp);
894  return true;
895 }
896 
897 bool
899 {
900  const char *p = ctx.data;
901  Addr addr = hex2i(&p);
902  if (*p++ != ',')
903  throw CmdError("E06");
904  size_t len = hex2i(&p);
905  if (*p++ != ':')
906  throw CmdError("E07");
907  if (len * 2 > ctx.len - (p - ctx.data))
908  throw CmdError("E08");
909  char buf[len];
910  p = (char *)hex2mem(buf, p, len);
911  if (p == NULL)
912  throw CmdError("E09");
913  if (!acc(addr, len))
914  throw CmdError("E0A");
915  if (!write(addr, len, buf))
916  throw CmdError("E0B");
917  send("OK");
918  return true;
919 }
920 
921 bool
923 {
924  std::string s(ctx.data, ctx.len - 1);
925  std::string xfer_read_prefix = "Xfer:features:read:";
926  if (s.rfind("Supported:", 0) == 0) {
927  std::ostringstream oss;
928  // This reply field mandatory. We can receive arbitrarily
929  // long packets, so we could choose it to be arbitrarily large.
930  // This is just an arbitrary filler value that seems to work.
931  oss << "PacketSize=1024";
932  for (const auto& feature : availableFeatures())
933  oss << ';' << feature;
934  send(oss.str().c_str());
935  } else if (s.rfind(xfer_read_prefix, 0) == 0) {
936  size_t offset, length;
937  auto value_string = s.substr(xfer_read_prefix.length());
938  auto colon_pos = value_string.find(':');
939  auto comma_pos = value_string.find(',');
940  if (colon_pos == std::string::npos || comma_pos == std::string::npos)
941  throw CmdError("E00");
942  std::string annex;
943  if (!getXferFeaturesRead(value_string.substr(0, colon_pos), annex))
944  throw CmdError("E00");
945  try {
946  offset = std::stoull(
947  value_string.substr(colon_pos + 1, comma_pos), NULL, 16);
948  length = std::stoull(
949  value_string.substr(comma_pos + 1), NULL, 16);
950  } catch (std::invalid_argument& e) {
951  throw CmdError("E00");
952  } catch (std::out_of_range& e) {
953  throw CmdError("E00");
954  }
955  std::string encoded;
956  encodeXferResponse(annex, encoded, offset, length);
957  send(encoded.c_str());
958  } else if (s == "C") {
959  send("QC0");
960  } else {
961  throw Unsupported();
962  }
963  return true;
964 }
965 
968 {
969  return {};
970 };
971 
972 bool
974  const std::string &annex, std::string &output)
975 {
976  return false;
977 }
978 
979 void
981  const std::string &unencoded, std::string &encoded) const
982 {
983  for (const char& c : unencoded) {
984  if (c == '$' || c == '#' || c == '}' || c == '*') {
985  encoded += '}';
986  encoded += c ^ 0x20;
987  } else {
988  encoded += c;
989  }
990  }
991 }
992 
993 void
994 BaseRemoteGDB::encodeXferResponse(const std::string &unencoded,
995  std::string &encoded, size_t offset, size_t unencoded_length) const
996 {
997  if (offset + unencoded_length < unencoded.length())
998  encoded += 'm';
999  else
1000  encoded += 'l';
1001  encodeBinaryData(unencoded.substr(offset, unencoded_length), encoded);
1002 }
1003 
1004 bool
1006 {
1007  const char *p = ctx.data;
1008  hex2i(&p); // Ignore the subcommand byte.
1009  if (*p++ == ';') {
1010  Addr newPc = hex2i(&p);
1011  tc->pcState(newPc);
1012  }
1013  setSingleStep();
1014  return false;
1015 }
1016 
1017 bool
1019 {
1020  if (ctx.len) {
1021  const char *p = ctx.data;
1022  Addr newPc = hex2i(&p);
1023  tc->pcState(newPc);
1024  }
1025  setSingleStep();
1026  return false;
1027 }
1028 
1029 bool
1031 {
1032  const char *p = ctx.data;
1033  char subcmd = *p++;
1034  if (*p++ != ',')
1035  throw CmdError("E0D");
1036  Addr addr = hex2i(&p);
1037  if (*p++ != ',')
1038  throw CmdError("E0D");
1039  size_t len = hex2i(&p);
1040 
1041  DPRINTF(GDBMisc, "clear %s, addr=%#x, len=%d\n",
1042  break_type(subcmd), addr, len);
1043 
1044  switch (subcmd) {
1045  case GdbSoftBp:
1047  break;
1048  case GdbHardBp:
1050  break;
1051  case GdbWriteWp:
1052  case GdbReadWp:
1053  case GdbAccWp:
1054  default: // unknown
1055  throw Unsupported();
1056  }
1057  send("OK");
1058 
1059  return true;
1060 }
1061 
1062 bool
1064 {
1065  const char *p = ctx.data;
1066  char subcmd = *p++;
1067  if (*p++ != ',')
1068  throw CmdError("E0D");
1069  Addr addr = hex2i(&p);
1070  if (*p++ != ',')
1071  throw CmdError("E0D");
1072  size_t len = hex2i(&p);
1073 
1074  DPRINTF(GDBMisc, "set %s, addr=%#x, len=%d\n",
1075  break_type(subcmd), addr, len);
1076 
1077  switch (subcmd) {
1078  case GdbSoftBp:
1080  break;
1081  case GdbHardBp:
1083  break;
1084  case GdbWriteWp:
1085  case GdbReadWp:
1086  case GdbAccWp:
1087  default: // unknown
1088  throw Unsupported();
1089  }
1090  send("OK");
1091 
1092  return true;
1093 }
BaseRemoteGDB::command_map
static std::map< char, GdbCommand > command_map
Definition: remote_gdb.hh:283
BaseRemoteGDB::~BaseRemoteGDB
virtual ~BaseRemoteGDB()
Definition: remote_gdb.hh:51
BaseRemoteGDB::TrapEvent::type
void type(int t)
Definition: remote_gdb.hh:228
BaseRemoteGDB::port
int port() const
Definition: remote_gdb.cc:370
BaseRemoteGDB::attach
void attach(int fd)
Definition: remote_gdb.cc:378
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:211
Event::scheduled
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:462
BaseRemoteGDB::singleStep
void singleStep()
Definition: remote_gdb.cc:641
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:1063
HardBreakpoint::refcount
int refcount
Definition: remote_gdb.cc:166
warn
#define warn(...)
Definition: logging.hh:239
BaseRemoteGDB::encodeXferResponse
void encodeXferResponse(const std::string &unencoded, std::string &encoded, size_t offset, size_t unencoded_length) const
Definition: remote_gdb.cc:994
ListenSocket::listen
virtual bool listen(int port, bool reuse=true)
Definition: socket.cc:97
system.hh
ThreadContext::getCurrentInstCount
virtual Tick getCurrentInstCount()=0
data
const char data[]
Definition: circlebuf.test.cc:47
BaseRemoteGDB::putbyte
void putbyte(uint8_t b)
Definition: remote_gdb.cc:509
BaseRemoteGDB::cmd_async_step
bool cmd_async_step(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1005
warn_once
#define warn_once(...)
Definition: logging.hh:243
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
HardBreakpoint
Definition: remote_gdb.cc:160
BaseRemoteGDB::cmd_signal
bool cmd_signal(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:801
remote_gdb.hh
BaseRemoteGDB::encodeBinaryData
void encodeBinaryData(const std::string &unencoded, std::string &encoded) const
Definition: remote_gdb.cc:980
ArmISA::fd
Bitfield< 14, 12 > fd
Definition: types.hh:159
HardBreakpoint::HardBreakpoint
HardBreakpoint(BaseRemoteGDB *_gdb, PCEventScope *s, Addr pc)
Definition: remote_gdb.cc:169
BaseRemoteGDB::cmd_cont
bool cmd_cont(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:808
BaseRemoteGDB::cmd_unsupported
bool cmd_unsupported(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:792
ListenSocket::accept
virtual int accept(bool nodelay=false)
Definition: socket.cc:146
GDBStart
static const char GDBStart
Definition: remote_gdb.cc:153
BaseRemoteGDB::removeHardBreak
void removeHardBreak(Addr addr, size_t len)
Definition: remote_gdb.cc:695
BaseRemoteGDB::cmd_set_thread
bool cmd_set_thread(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:864
GDBEnd
static const char GDBEnd
Definition: remote_gdb.cc:154
BaseRemoteGDB::connect
void connect()
Definition: remote_gdb.cc:354
BaseRemoteGDB::incomingData
void incomingData(int revent)
Definition: remote_gdb.cc:482
DTRACE
#define DTRACE(x)
Definition: debug.hh:156
BaseRemoteGDB::DataEvent
SocketEvent<&BaseRemoteGDB::incomingData > DataEvent
Definition: remote_gdb.hh:186
std::vector
STL vector class.
Definition: stl.hh:37
BaseRemoteGDB::singleStepEvent
EventWrapper< BaseRemoteGDB, &BaseRemoteGDB::singleStep > singleStepEvent
Definition: remote_gdb.hh:244
PollQueue::schedule
void schedule(PollEvent *event)
Definition: pollevent.cc:157
BaseRemoteGDB::cmd_mem_r
bool cmd_mem_r(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:874
debuggers
std::vector< BaseRemoteGDB * > debuggers
Definition: remote_gdb.cc:158
PCEvent::pc
Addr pc() const
Definition: pc_event.hh:58
BaseRemoteGDB::tc
ThreadContext * tc
Definition: remote_gdb.hh:214
BaseRemoteGDB::GdbCommand::Context::len
int len
Definition: remote_gdb.hh:272
BaseRemoteGDB::clearSingleStep
void clearSingleStep()
Definition: remote_gdb.cc:649
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:163
BaseRemoteGDB::insertSoftBreak
void insertSoftBreak(Addr addr, size_t len)
Definition: remote_gdb.cc:662
pollQueue
PollQueue pollQueue
Definition: pollevent.cc:53
BaseRemoteGDB::setSingleStep
void setSingleStep()
Definition: remote_gdb.cc:655
GDBBadP
static const char GDBBadP
Definition: remote_gdb.cc:156
DPRINTFNR
#define DPRINTFNR(...)
Definition: trace.hh:242
BaseRemoteGDB::GdbCommand::func
const Func func
Definition: remote_gdb.hh:278
BaseRemoteGDB::listener
ListenSocket listener
Definition: remote_gdb.hh:194
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:408
Event
Definition: eventq.hh:248
BaseRemoteGDB::GdbCommand::Context::cmd
const GdbCommand * cmd
Definition: remote_gdb.hh:268
System
Definition: system.hh:73
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:237
BaseRemoteGDB::_port
int _port
Definition: remote_gdb.hh:195
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:714
MipsISA::vaddr
vaddr
Definition: pra_constants.hh:275
BaseRemoteGDB::getbyte
uint8_t getbyte()
Definition: remote_gdb.cc:499
BaseRemoteGDB::write
bool write(Addr addr, size_t size, const char *data)
Definition: remote_gdb.cc:623
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:132
HardBreakpoint::process
void process(ThreadContext *tc) override
Definition: remote_gdb.cc:179
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:722
BaseRemoteGDB::GdbCommand::name
const char *const name
Definition: remote_gdb.hh:277
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:213
BaseRemoteGDB::cmd_mem_w
bool cmd_mem_w(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:898
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:148
BaseRemoteGDB::dataEvent
DataEvent * dataEvent
Definition: remote_gdb.hh:192
BaseRemoteGDB::acc
virtual bool acc(Addr addr, size_t len)=0
BaseRemoteGDB::isAttached
bool isAttached()
Definition: remote_gdb.hh:155
BaseRemoteGDB::connectEvent
ConnectEvent * connectEvent
Definition: remote_gdb.hh:191
DDUMP
#define DDUMP(x, data, count)
DPRINTF is a debugging trace facility that allows one to selectively enable tracing statements.
Definition: trace.hh:236
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:820
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:269
X86ISA::addr
Bitfield< 3 > addr
Definition: types.hh:80
SimObject::name
virtual const std::string name() const
Definition: sim_object.hh:182
BaseRemoteGDB::cmd_detach
bool cmd_detach(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:833
ThreadContext::getVirtProxy
virtual PortProxy & getVirtProxy()=0
PCEvent::evpc
Addr evpc
Definition: pc_event.hh:47
BaseRemoteGDB::getXferFeaturesRead
virtual bool getXferFeaturesRead(const std::string &annex, std::string &output)
Get an XML target description.
Definition: remote_gdb.cc:973
ThreadContext::scheduleInstCountEvent
virtual void scheduleInstCountEvent(Event *event, Tick count)=0
ListenSocket::allDisabled
static bool allDisabled()
Definition: socket.cc:68
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:270
BaseRemoteGDB::removeSoftBreak
void removeSoftBreak(Addr addr, size_t len)
Definition: remote_gdb.cc:671
BaseRemoteGDB::availableFeatures
virtual std::vector< std::string > availableFeatures() const
Definition: remote_gdb.cc:967
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:922
PollQueue::remove
void remove(PollEvent *event)
Definition: pollevent.cc:137
base.hh
BaseRemoteGDB::cmd_clr_hw_bkpt
bool cmd_clr_hw_bkpt(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1030
BaseRemoteGDB::active
bool active
Definition: remote_gdb.hh:210
BaseRemoteGDB::fd
int fd
Definition: remote_gdb.hh:198
BaseRemoteGDB::cmd_step
bool cmd_step(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1018
ArmISA::len
Bitfield< 18, 16 > len
Definition: miscregs_types.hh:439
ccprintf
void ccprintf(cp::Print &print)
Definition: cprintf.hh:127
BaseRemoteGDB::insertHardBreak
void insertHardBreak(Addr addr, size_t len)
Definition: remote_gdb.cc:680
GDBGoodP
static const char GDBGoodP
Definition: remote_gdb.cc:155
X86ISA::type
type
Definition: misc.hh:727
BaseRemoteGDB::checkBpLen
virtual bool checkBpLen(size_t len)
Definition: remote_gdb.cc:786
ArmISA::c
Bitfield< 29 > c
Definition: miscregs_types.hh:50
PCEvent
Definition: pc_event.hh:42
BaseRemoteGDB::name
std::string name()
Definition: remote_gdb.cc:328
curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:43
trace.hh
BaseRemoteGDB::ConnectEvent
SocketEvent<&BaseRemoteGDB::connectWrapper > ConnectEvent
Definition: remote_gdb.hh:185
DPRINTFN
#define DPRINTFN(...)
Definition: trace.hh:241
BaseRemoteGDB::GdbCommand::Context
Definition: remote_gdb.hh:266
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
intmath.hh
HardBreakpoint::name
const std::string name() const override
Definition: remote_gdb.cc:176
ArmISA::s
Bitfield< 4 > s
Definition: miscregs_types.hh:556
BaseRemoteGDB::listen
void listen()
Definition: remote_gdb.cc:334
BaseRemoteGDB::cmd_reg_r
bool cmd_reg_r(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:840
BaseRemoteGDB::trapEvent
BaseRemoteGDB::TrapEvent trapEvent
BaseRemoteGDB::regCachePtr
BaseGdbRegCache * regCachePtr
Definition: remote_gdb.hh:216
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:600
BaseRemoteGDB::GdbCommand::Context::data
char * data
Definition: remote_gdb.hh:271
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:390
BaseRemoteGDB::recv
void recv(std::vector< char > &bp)
Definition: remote_gdb.cc:519
BaseRemoteGDB::cmd_reg_w
bool cmd_reg_w(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:850
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
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:313
BaseGdbRegCache::getRegs
virtual void getRegs(ThreadContext *)=0
Fill the raw buffer from the registers in the ThreadContext.
ArmISA::offset
Bitfield< 23, 0 > offset
Definition: types.hh:153
BaseRemoteGDB::send
void send(const char *data)
Definition: remote_gdb.cc:571

Generated on Tue Jun 22 2021 15:28:21 for gem5 by doxygen 1.8.17