gem5  v22.0.0.1
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, 2021 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 <cassert>
136 #include <csignal>
137 #include <cstdint>
138 #include <cstdio>
139 #include <iterator>
140 #include <sstream>
141 #include <string>
142 #include <utility>
143 
144 #include "base/cprintf.hh"
145 #include "base/intmath.hh"
146 #include "base/logging.hh"
147 #include "base/socket.hh"
148 #include "base/trace.hh"
149 #include "cpu/base.hh"
150 #include "cpu/static_inst.hh"
151 #include "cpu/thread_context.hh"
152 #include "debug/GDBAll.hh"
153 #include "mem/port.hh"
154 #include "mem/port_proxy.hh"
157 #include "sim/full_system.hh"
158 #include "sim/process.hh"
159 #include "sim/system.hh"
160 
161 namespace gem5
162 {
163 
164 static const char GDBStart = '$';
165 static const char GDBEnd = '#';
166 static const char GDBGoodP = '+';
167 static const char GDBBadP = '-';
168 
169 class HardBreakpoint : public PCEvent
170 {
171  private:
173 
174  public:
175  int refcount;
176 
177  public:
179  : PCEvent(s, "HardBreakpoint Event", pc),
180  gdb(_gdb), refcount(0)
181  {
182  DPRINTF(GDBMisc, "creating hardware breakpoint at %#x\n", evpc);
183  }
184 
185  const std::string name() const override { return gdb->name() + ".hwbkpt"; }
186 
187  void
188  process(ThreadContext *tc) override
189  {
190  DPRINTF(GDBMisc, "handling hardware breakpoint at %#x\n", pc());
191 
192  if (tc == gdb->tc)
193  gdb->trap(tc->contextId(), SIGTRAP);
194  }
195 };
196 
197 namespace {
198 
199 // Exception to throw when the connection to the client is broken.
200 struct BadClient
201 {
202  const char *warning;
203  BadClient(const char *_warning=NULL) : warning(_warning)
204  {}
205 };
206 
207 // Exception to throw when an error needs to be reported to the client.
208 struct CmdError
209 {
210  std::string error;
211  CmdError(std::string _error) : error(_error)
212  {}
213 };
214 
215 // Exception to throw when something isn't supported.
216 class Unsupported {};
217 
218 // Convert a hex digit into an integer.
219 // This returns -1 if the argument passed is no valid hex digit.
220 int
221 digit2i(char c)
222 {
223  if (c >= '0' && c <= '9')
224  return (c - '0');
225  else if (c >= 'a' && c <= 'f')
226  return (c - 'a' + 10);
227  else if (c >= 'A' && c <= 'F')
228  return (c - 'A' + 10);
229  else
230  return -1;
231 }
232 
233 // Convert the low 4 bits of an integer into an hex digit.
234 char
235 i2digit(int n)
236 {
237  return "0123456789abcdef"[n & 0x0f];
238 }
239 
240 // Convert a byte array into an hex string.
241 void
242 mem2hex(char *vdst, const char *vsrc, int len)
243 {
244  char *dst = vdst;
245  const char *src = vsrc;
246 
247  while (len--) {
248  *dst++ = i2digit(*src >> 4);
249  *dst++ = i2digit(*src++);
250  }
251  *dst = '\0';
252 }
253 
254 // Convert an hex string into a byte array.
255 // This returns a pointer to the character following the last valid
256 // hex digit. If the string ends in the middle of a byte, NULL is
257 // returned.
258 const char *
259 hex2mem(char *vdst, const char *src, int max_len)
260 {
261  char *dst = vdst;
262  int msb, lsb;
263 
264  while (*src && max_len--) {
265  msb = digit2i(*src++);
266  if (msb < 0)
267  return (src - 1);
268  lsb = digit2i(*src++);
269  if (lsb < 0)
270  return (NULL);
271  *dst++ = (msb << 4) | lsb;
272  }
273  return src;
274 }
275 
276 // Convert an hex string into an integer.
277 // This returns a pointer to the character following the last valid
278 // hex digit.
279 Addr
280 hex2i(const char **srcp)
281 {
282  const char *src = *srcp;
283  Addr r = 0;
284  int nibble;
285 
286  while ((nibble = digit2i(*src)) >= 0) {
287  r *= 16;
288  r += nibble;
289  src++;
290  }
291  *srcp = src;
292  return r;
293 }
294 
295 bool
296 parseThreadId(const char **srcp, bool &all, bool &any, ContextID &tid)
297 {
298  all = any = false;
299  tid = 0;
300  const char *src = *srcp;
301  if (*src == '-') {
302  // This could be the start of -1, which means all threads.
303  src++;
304  if (*src++ != '1')
305  return false;
306  *srcp += 2;
307  all = true;
308  return true;
309  }
310  tid = hex2i(srcp);
311  // If *srcp still points to src, no characters were consumed and no thread
312  // id was found. Without this check, we can't tell the difference between
313  // zero and a parsing error.
314  if (*srcp == src)
315  return false;
316 
317  if (tid == 0)
318  any = true;
319 
320  tid--;
321 
322  return true;
323 }
324 
325 int
326 encodeThreadId(ContextID id)
327 {
328  // Thread ID 0 is reserved and means "pick any thread".
329  return id + 1;
330 }
331 
332 enum GdbBreakpointType
333 {
334  GdbSoftBp = '0',
335  GdbHardBp = '1',
336  GdbWriteWp = '2',
337  GdbReadWp = '3',
338  GdbAccWp = '4',
339 };
340 
341 const char *
342 breakType(char c)
343 {
344  switch(c) {
345  case GdbSoftBp: return "software breakpoint";
346  case GdbHardBp: return "hardware breakpoint";
347  case GdbWriteWp: return "write watchpoint";
348  case GdbReadWp: return "read watchpoint";
349  case GdbAccWp: return "access watchpoint";
350  default: return "unknown breakpoint/watchpoint";
351  }
352 }
353 
354 std::map<Addr, HardBreakpoint *> hardBreakMap;
355 
356 }
357 
358 BaseRemoteGDB::BaseRemoteGDB(System *_system, int _port) :
359  incomingConnectionEvent(nullptr), incomingDataEvent(nullptr),
360  _port(_port), fd(-1), sys(_system),
361  connectEvent(this), disconnectEvent(this), trapEvent(this),
362  singleStepEvent(*this)
363 {}
364 
366 {
368  delete incomingDataEvent;
369 }
370 
371 std::string
373 {
374  return sys->name() + ".remote_gdb";
375 }
376 
377 void
379 {
381  warn_once("Sockets disabled, not accepting gdb connections");
382  return;
383  }
384 
385  while (!listener.listen(_port, true)) {
386  DPRINTF(GDBMisc, "Can't bind port %d\n", _port);
387  _port++;
388  }
389 
391  new IncomingConnectionEvent(this, listener.getfd(), POLLIN);
393 
394  ccprintf(std::cerr, "%d: %s: listening for remote gdb on port %d\n",
395  curTick(), name(), _port);
396 }
397 
398 void
400 {
402  "Can't accept GDB connections without any threads!");
403 
405 
406  int sfd = listener.accept(true);
407 
408  if (sfd != -1) {
409  if (isAttached())
410  close(sfd);
411  else
412  attach(sfd);
413  }
414 }
415 
416 int
418 {
420  "Remote GDB port is unknown until listen() has been called.\n");
421  return _port;
422 }
423 
424 void
426 {
427  fd = f;
428 
429  attached = true;
430  DPRINTFN("remote gdb attached\n");
431 
432  processCommands();
433 
434  if (isAttached()) {
435  // At this point an initial communication with GDB is handled
436  // and we're ready to continue. Here we arrange IncomingDataEvent
437  // to get notified when GDB breaks in.
438  //
439  // However, GDB can decide to disconnect during that initial
440  // communication. In that case, we cannot arrange data event because
441  // the socket is already closed (not that it makes any sense, anyways).
442  //
443  // Hence the check above.
444  incomingDataEvent = new IncomingDataEvent(this, fd, POLLIN);
446  }
447 }
448 
449 void
451 {
452  attached = false;
453  clearSingleStep();
454  close(fd);
455  fd = -1;
456 
457  if (incomingDataEvent) {
458  // incomingDataEvent gets scheduled in attach() after
459  // initial communication with GDB is handled and GDB tells
460  // gem5 to continue.
461  //
462  // GDB can disconnect before that in which case `incomingDataEvent`
463  // is NULL.
464  //
465  // Hence the check above.
466 
468  incomingDataEvent = nullptr;
469  }
471  DPRINTFN("remote gdb detached\n");
472 }
473 
474 void
476 {
477  [[maybe_unused]] auto it_success = threads.insert({_tc->contextId(), _tc});
478  assert(it_success.second);
479  // If no ThreadContext is current selected, select this one.
480  if (!tc)
481  assert(selectThreadContext(_tc->contextId()));
482 
483  // Now that we have a thread, we can start listening.
484  if (!listener.islistening())
485  listen();
486 }
487 
488 void
490 {
491  auto it = threads.find(_tc->contextId());
492  panic_if(it == threads.end(), "No context with ID %d found.",
493  _tc->contextId());
494  it->second = _tc;
495 }
496 
497 bool
499 {
500  auto it = threads.find(id);
501  if (it == threads.end())
502  return false;
503 
504  tc = it->second;
505  // Update the register cache for the new thread context, if there is one.
506  if (regCachePtr)
508  return true;
509 }
510 
511 // This function does all command processing for interfacing to a
512 // remote gdb. Note that the error codes are ignored by gdb at
513 // present, but might eventually become meaningful. (XXX) It might
514 // makes sense to use POSIX errno values, because that is what the
515 // gdb/remote.c functions want to return.
516 void
517 BaseRemoteGDB::trap(ContextID id, int signum)
518 {
519  if (!attached)
520  return;
521 
522  if (tc->contextId() != id) {
523  if (!selectThreadContext(id))
524  return;
525  }
526 
527  DPRINTF(GDBMisc, "trap: PC=%s\n", tc->pcState());
528 
529  clearSingleStep();
530 
531  if (threadSwitching) {
532  threadSwitching = false;
533  // Tell GDB the thread switch has completed.
534  send("OK");
535  } else {
536  // Tell remote host that an exception has occurred.
537  send("S%02x", signum);
538  }
539 
540  processCommands(signum);
541 }
542 
543 void
545 {
546  if (connectEvent.scheduled()) {
547  warn("GDB connect event has already been scheduled!");
548  return;
549  }
550 
551  if (revent & POLLIN) {
553  }
554 }
555 
556 void
558 {
559  if (trapEvent.scheduled()) {
560  warn("GDB trap event has already been scheduled!");
561  return;
562  }
563 
564  if (revent & POLLIN) {
565  trapEvent.type(SIGILL);
566  trapEvent.id(tc->contextId());
568  } else if (revent & POLLNVAL) {
571  }
572 }
573 
574 uint8_t
576 {
577  uint8_t b;
578  if (::read(fd, &b, sizeof(b)) == sizeof(b))
579  return b;
580 
581  throw BadClient("Couldn't read data from debugger.");
582 }
583 
584 void
586 {
587  if (::write(fd, &b, sizeof(b)) == sizeof(b))
588  return;
589 
590  throw BadClient("Couldn't write data to the debugger.");
591 }
592 
593 // Receive a packet from gdb
594 void
596 {
597  uint8_t c;
598  int csum;
599  bp.resize(0);
600 
601  do {
602  csum = 0;
603  // Find the beginning of a packet
604  while ((c = getbyte()) != GDBStart);
605 
606  // Read until you find the end of the data in the packet, and keep
607  // track of the check sum.
608  while (true) {
609  c = getbyte();
610  if (c == GDBEnd)
611  break;
612  c &= 0x7f;
613  csum += c;
614  bp.push_back(c);
615  }
616 
617  // Mask the check sum.
618  csum &= 0xff;
619 
620  // Bring in the checksum. If the check sum matches, csum will be 0.
621  csum -= digit2i(getbyte()) * 16;
622  csum -= digit2i(getbyte());
623 
624  // If the check sum was correct
625  if (csum == 0) {
626  // Report that the packet was received correctly
627  putbyte(GDBGoodP);
628  // Sequence present?
629  if (bp.size() > 2 && bp[2] == ':') {
630  putbyte(bp[0]);
631  putbyte(bp[1]);
632  auto begin = std::begin(bp);
633  bp.erase(begin, std::next(begin, 3));
634  }
635  break;
636  }
637  // Otherwise, report that there was a mistake.
638  putbyte(GDBBadP);
639  } while (1);
640  // Sentinel.
641  bp.push_back('\0');
642  DPRINTF(GDBRecv, "recv: %s\n", bp.data());
643 }
644 
645 // Send a packet to gdb
646 void
647 BaseRemoteGDB::send(const char *bp)
648 {
649  const char *p;
650  uint8_t csum, c;
651 
652  DPRINTF(GDBSend, "send: %s\n", bp);
653 
654  do {
655  p = bp;
656  // Start sending a packet
657  putbyte(GDBStart);
658  // Send the contents, and also keep a check sum.
659  for (csum = 0; (c = *p); p++) {
660  putbyte(c);
661  csum += c;
662  }
663  // Send the ending character.
664  putbyte(GDBEnd);
665  // Send the checksum.
666  putbyte(i2digit(csum >> 4));
667  putbyte(i2digit(csum));
668  // Try transmitting over and over again until the other end doesn't
669  // send an error back.
670  c = getbyte();
671  } while ((c & 0x7f) == GDBBadP);
672 }
673 
674 void
676 {
677  // Stick frame regs into our reg cache.
678  regCachePtr = gdbRegs();
680 
681  GdbCommand::Context cmd_ctx;
682  cmd_ctx.type = signum;
684 
685  for (;;) {
686  try {
687  recv(data);
688  if (data.size() == 1)
689  throw BadClient();
690  cmd_ctx.cmdByte = data[0];
691  cmd_ctx.data = data.data() + 1;
692  // One for sentinel, one for cmdByte.
693  cmd_ctx.len = data.size() - 2;
694 
695  auto cmd_it = commandMap.find(cmd_ctx.cmdByte);
696  if (cmd_it == commandMap.end()) {
697  DPRINTF(GDBMisc, "Unknown command: %c(%#x)\n",
698  cmd_ctx.cmdByte, cmd_ctx.cmdByte);
699  throw Unsupported();
700  }
701  cmd_ctx.cmd = &(cmd_it->second);
702 
703  if (!(this->*(cmd_ctx.cmd->func))(cmd_ctx))
704  break;
705 
706  } catch (BadClient &e) {
707  if (e.warning)
708  warn(e.warning);
709  detach();
710  break;
711  } catch (Unsupported &e) {
712  send("");
713  } catch (CmdError &e) {
714  send(e.error);
715  } catch (std::exception &e) {
716  panic("Unrecognized GDB exception: %s", e.what());
717  } catch (...) {
718  panic("Unrecognized GDB exception.");
719  }
720  }
721 }
722 
723 // Read bytes from kernel address space for debugger.
724 bool
725 BaseRemoteGDB::read(Addr vaddr, size_t size, char *data)
726 {
727  DPRINTF(GDBRead, "read: addr=%#x, size=%d", vaddr, size);
728 
730  readBlob(vaddr, data, size);
731 
732 #if TRACING_ON
733  if (debug::GDBRead) {
734  if (debug::GDBExtra) {
735  char buf[1024];
736  mem2hex(buf, data, size);
737  DPRINTFNR(": %s\n", buf);
738  } else
739  DPRINTFNR("\n");
740  }
741 #endif
742 
743  return true;
744 }
745 
746 // Write bytes to kernel address space for debugger.
747 bool
748 BaseRemoteGDB::write(Addr vaddr, size_t size, const char *data)
749 {
750  if (debug::GDBWrite) {
751  DPRINTFN("write: addr=%#x, size=%d", vaddr, size);
752  if (debug::GDBExtra) {
753  char buf[1024];
754  mem2hex(buf, data, size);
755  DPRINTFNR(": %s\n", buf);
756  } else
757  DPRINTFNR("\n");
758  }
760  writeBlob(vaddr, data, size);
761 
762  return true;
763 }
764 
765 void
767 {
768  if (!singleStepEvent.scheduled())
770  trap(tc->contextId(), SIGTRAP);
771 }
772 
773 void
775 {
777 }
778 
779 void
781 {
782  if (!singleStepEvent.scheduled())
784 }
785 
786 void
788 {
789  if (!checkBpKind(kind))
790  throw BadClient("Invalid breakpoint kind.\n");
791 
792  return insertHardBreak(addr, kind);
793 }
794 
795 void
797 {
798  if (!checkBpKind(kind))
799  throw BadClient("Invalid breakpoint kind.\n");
800 
801  return removeHardBreak(addr, kind);
802 }
803 
804 void
806 {
807  if (!checkBpKind(kind))
808  throw BadClient("Invalid breakpoint kind.\n");
809 
810  DPRINTF(GDBMisc, "Inserting hardware breakpoint at %#x\n", addr);
811 
812  HardBreakpoint *&bkpt = hardBreakMap[addr];
813  if (bkpt == 0)
814  bkpt = new HardBreakpoint(this, sys, addr);
815 
816  bkpt->refcount++;
817 }
818 
819 void
821 {
822  if (!checkBpKind(kind))
823  throw BadClient("Invalid breakpoint kind.\n");
824 
825  DPRINTF(GDBMisc, "Removing hardware breakpoint at %#x\n", addr);
826 
827  auto i = hardBreakMap.find(addr);
828  if (i == hardBreakMap.end())
829  throw CmdError("E0C");
830 
831  HardBreakpoint *hbp = (*i).second;
832  if (--hbp->refcount == 0) {
833  delete hbp;
834  hardBreakMap.erase(i);
835  }
836 }
837 
838 void
840 {
841  if (delta == 0 && tc->status() != ThreadContext::Active) {
842  // If delta is zero, we're just trying to wait for an instruction
843  // boundary. If the CPU is not active, assume we're already at a
844  // boundary without waiting for the CPU to eventually wake up.
845  ev->process();
846  } else {
847  // Here "ticks" aren't simulator ticks which measure time, they're
848  // instructions committed by the CPU.
850  }
851 }
852 
853 void
855 {
856  if (ev->scheduled())
858 }
859 
860 std::map<char, BaseRemoteGDB::GdbCommand> BaseRemoteGDB::commandMap = {
861  // last signal
862  { '?', { "KGDB_SIGNAL", &BaseRemoteGDB::cmdSignal } },
863  // set baud (deprecated)
864  { 'b', { "KGDB_SET_BAUD", &BaseRemoteGDB::cmdUnsupported } },
865  // set breakpoint (deprecated)
866  { 'B', { "KGDB_SET_BREAK", &BaseRemoteGDB::cmdUnsupported } },
867  // resume
868  { 'c', { "KGDB_CONT", &BaseRemoteGDB::cmdCont } },
869  // continue with signal
870  { 'C', { "KGDB_ASYNC_CONT", &BaseRemoteGDB::cmdAsyncCont } },
871  // toggle debug flags (deprecated)
872  { 'd', { "KGDB_DEBUG", &BaseRemoteGDB::cmdUnsupported } },
873  // detach remote gdb
874  { 'D', { "KGDB_DETACH", &BaseRemoteGDB::cmdDetach } },
875  // read general registers
876  { 'g', { "KGDB_REG_R", &BaseRemoteGDB::cmdRegR } },
877  // write general registers
878  { 'G', { "KGDB_REG_W", &BaseRemoteGDB::cmdRegW } },
879  // set thread
880  { 'H', { "KGDB_SET_THREAD", &BaseRemoteGDB::cmdSetThread } },
881  // step a single cycle
882  { 'i', { "KGDB_CYCLE_STEP", &BaseRemoteGDB::cmdUnsupported } },
883  // signal then cycle step
884  { 'I', { "KGDB_SIG_CYCLE_STEP", &BaseRemoteGDB::cmdUnsupported } },
885  // kill program
886  { 'k', { "KGDB_KILL", &BaseRemoteGDB::cmdDetach } },
887  // read memory
888  { 'm', { "KGDB_MEM_R", &BaseRemoteGDB::cmdMemR } },
889  // write memory
890  { 'M', { "KGDB_MEM_W", &BaseRemoteGDB::cmdMemW } },
891  // read register
892  { 'p', { "KGDB_READ_REG", &BaseRemoteGDB::cmdUnsupported } },
893  // write register
894  { 'P', { "KGDB_SET_REG", &BaseRemoteGDB::cmdUnsupported } },
895  // query variable
896  { 'q', { "KGDB_QUERY_VAR", &BaseRemoteGDB::cmdQueryVar } },
897  // set variable
898  { 'Q', { "KGDB_SET_VAR", &BaseRemoteGDB::cmdUnsupported } },
899  // reset system (deprecated)
900  { 'r', { "KGDB_RESET", &BaseRemoteGDB::cmdUnsupported } },
901  // step
902  { 's', { "KGDB_STEP", &BaseRemoteGDB::cmdStep } },
903  // signal and step
904  { 'S', { "KGDB_ASYNC_STEP", &BaseRemoteGDB::cmdAsyncStep } },
905  // find out if the thread is alive
906  { 'T', { "KGDB_THREAD_ALIVE", &BaseRemoteGDB::cmdUnsupported } },
907  // target exited
908  { 'W', { "KGDB_TARGET_EXIT", &BaseRemoteGDB::cmdUnsupported } },
909  // write memory
910  { 'X', { "KGDB_BINARY_DLOAD", &BaseRemoteGDB::cmdUnsupported } },
911  // remove breakpoint or watchpoint
912  { 'z', { "KGDB_CLR_HW_BKPT", &BaseRemoteGDB::cmdClrHwBkpt } },
913  // insert breakpoint or watchpoint
914  { 'Z', { "KGDB_SET_HW_BKPT", &BaseRemoteGDB::cmdSetHwBkpt } },
915  // non-standard RSP extension: dump page table
916  { '.', { "GET_PAGE_TABLE", &BaseRemoteGDB::cmdDumpPageTable } },
917 };
918 
919 bool
921 {
922  return true;
923 }
924 
925 bool
927 {
928  DPRINTF(GDBMisc, "Unsupported command: %s\n", ctx.cmd->name);
929  DDUMP(GDBMisc, ctx.data, ctx.len);
930  throw Unsupported();
931 }
932 
933 
934 bool
936 {
937  send("S%02x", ctx.type);
938  return true;
939 }
940 
941 bool
943 {
944  const char *p = ctx.data;
945  if (ctx.len) {
946  Addr new_pc = hex2i(&p);
947  tc->pcState(new_pc);
948  }
949  clearSingleStep();
950  return false;
951 }
952 
953 bool
955 {
956  const char *p = ctx.data;
957  hex2i(&p);
958  if (*p++ == ';') {
959  Addr new_pc = hex2i(&p);
960  tc->pcState(new_pc);
961  }
962  clearSingleStep();
963  return false;
964 }
965 
966 bool
968 {
969  detach();
970  return false;
971 }
972 
973 bool
975 {
976  char buf[2 * regCachePtr->size() + 1];
977  buf[2 * regCachePtr->size()] = '\0';
978  mem2hex(buf, regCachePtr->data(), regCachePtr->size());
979  send(buf);
980  return true;
981 }
982 
983 bool
985 {
986  const char *p = ctx.data;
987  p = hex2mem(regCachePtr->data(), p, regCachePtr->size());
988  if (p == NULL || *p != '\0')
989  throw CmdError("E01");
990 
992  send("OK");
993 
994  return true;
995 }
996 
997 bool
999 {
1000  const char *p = ctx.data;
1001  char subcommand = *p++;
1002  int tid = 0;
1003  bool all, any;
1004  if (!parseThreadId(&p, all, any, tid))
1005  throw CmdError("E01");
1006 
1007  if (subcommand == 'c') {
1008  // We can only single step or continue all threads at once, since we
1009  // stop time itself and not individual threads.
1010  if (!all)
1011  throw CmdError("E02");
1012  } else if (subcommand == 'g') {
1013  // We don't currently support reading registers, memory, etc, from all
1014  // threads at once. GDB may never ask for this, but if it does we
1015  // should complain.
1016  if (all)
1017  throw CmdError("E03");
1018 
1019  // If GDB doesn't care which thread we're using, keep using the
1020  // current one, otherwise switch.
1021  if (!any && tid != tc->contextId()) {
1022  if (!selectThreadContext(tid))
1023  throw CmdError("E04");
1024  // Line up on an instruction boundary in the new thread.
1025  threadSwitching = true;
1026  trapEvent.id(tid);
1028  return false;
1029  }
1030  } else {
1031  throw CmdError("E05");
1032  }
1033 
1034  send("OK");
1035  return true;
1036 }
1037 
1038 bool
1040 {
1041  const char *p = ctx.data;
1042  Addr addr = hex2i(&p);
1043  if (*p++ != ',')
1044  throw CmdError("E02");
1045  size_t len = hex2i(&p);
1046  if (*p != '\0')
1047  throw CmdError("E03");
1048  if (!acc(addr, len))
1049  throw CmdError("E05");
1050 
1051  char buf[len];
1052  if (!read(addr, len, buf))
1053  throw CmdError("E05");
1054 
1055  char temp[2 * len + 1];
1056  temp[2 * len] = '\0';
1057  mem2hex(temp, buf, len);
1058  send(temp);
1059  return true;
1060 }
1061 
1062 bool
1064 {
1065  const char *p = ctx.data;
1066  Addr addr = hex2i(&p);
1067  if (*p++ != ',')
1068  throw CmdError("E06");
1069  size_t len = hex2i(&p);
1070  if (*p++ != ':')
1071  throw CmdError("E07");
1072  if (len * 2 > ctx.len - (p - ctx.data))
1073  throw CmdError("E08");
1074  char buf[len];
1075  p = (char *)hex2mem(buf, p, len);
1076  if (p == NULL)
1077  throw CmdError("E09");
1078  if (!acc(addr, len))
1079  throw CmdError("E0A");
1080  if (!write(addr, len, buf))
1081  throw CmdError("E0B");
1082  send("OK");
1083  return true;
1084 }
1085 
1086 namespace {
1087 
1089 splitAt(std::string str, const char * const delim)
1090 {
1091  size_t pos = str.find_first_of(delim);
1092  if (pos == std::string::npos)
1093  return std::pair<std::string, std::string>(str, "");
1094  else
1096  str.substr(0, pos), str.substr(pos + 1));
1097 }
1098 
1099 } // anonymous namespace
1100 
1101 std::map<std::string, BaseRemoteGDB::QuerySetCommand>
1103  { "C", { &BaseRemoteGDB::queryC } },
1104  { "Supported", { &BaseRemoteGDB::querySupported, ";" } },
1105  { "Xfer", { &BaseRemoteGDB::queryXfer } },
1106  { "fThreadInfo", { &BaseRemoteGDB::queryFThreadInfo } },
1107  { "sThreadInfo", { &BaseRemoteGDB::querySThreadInfo } },
1108 };
1109 
1110 void
1112 {
1113  send("QC%x", encodeThreadId(tc->contextId()));
1114 }
1115 
1116 void
1118 {
1119  std::ostringstream oss;
1120  // This reply field mandatory. We can receive arbitrarily
1121  // long packets, so we could choose it to be arbitrarily large.
1122  // This is just an arbitrary filler value that seems to work.
1123  oss << "PacketSize=1024";
1124  for (const auto& feature : availableFeatures())
1125  oss << ';' << feature;
1126  send(oss.str());
1127 }
1128 
1129 void
1131 {
1132  auto split = splitAt(ctx.args.at(0), ":");
1133  auto object = split.first;
1134 
1135  split = splitAt(split.second, ":");
1136  auto operation = split.first;
1137 
1138  // Only the "features" object and "read"ing are supported currently.
1139  if (object != "features" || operation != "read")
1140  throw Unsupported();
1141 
1142  // Extract the annex name.
1143  split = splitAt(split.second, ":");
1144  auto annex = split.first;
1145 
1146  // Read the contents of the annex.
1147  std::string content;
1148  if (!getXferFeaturesRead(annex, content))
1149  throw CmdError("E00");
1150 
1151  // Extract the offset and length.
1152  split = splitAt(split.second, ",");
1153  auto offset_str = split.first;
1154  auto length_str = split.second;
1155 
1156  const char *offset_ptr = offset_str.c_str();
1157  const char *length_ptr = length_str.c_str();
1158  auto offset = hex2i(&offset_ptr);
1159  auto length = hex2i(&length_ptr);
1160  if (offset_ptr != offset_str.c_str() + offset_str.length() ||
1161  length_ptr != length_str.c_str() + length_str.length()) {
1162  throw CmdError("E00");
1163  }
1164 
1165  std::string encoded;
1166  encodeXferResponse(content, encoded, offset, length);
1167  send(encoded);
1168 }
1169 
1170 void
1172 {
1173  threadInfoIdx = 0;
1174  querySThreadInfo(ctx);
1175 }
1176 
1177 void
1179 {
1180  if (threadInfoIdx >= threads.size()) {
1181  threadInfoIdx = 0;
1182  send("l");
1183  } else {
1184  auto it = threads.begin();
1185  std::advance(it, threadInfoIdx++);
1186  send("m%x", encodeThreadId(it->second->contextId()));
1187  }
1188 }
1189 
1190 bool
1192 {
1193  // The query command goes until the first ':', or the end of the string.
1194  std::string s(ctx.data, ctx.len);
1195  auto query_split = splitAt({ ctx.data, (size_t)ctx.len }, ":");
1196  const auto &query_str = query_split.first;
1197 
1198  // Look up the query command, and report if it isn't found.
1199  auto query_it = queryMap.find(query_str);
1200  if (query_it == queryMap.end()) {
1201  DPRINTF(GDBMisc, "Unknown query %s\n", s);
1202  throw Unsupported();
1203  }
1204 
1205  // If it was found, construct a context.
1206  QuerySetCommand::Context qctx(query_str);
1207 
1208  const auto &query = query_it->second;
1209  auto remaining = std::move(query_split.second);
1210  if (!query.argSep) {
1211  qctx.args.emplace_back(std::move(remaining));
1212  } else {
1213  while (remaining != "") {
1214  auto arg_split = splitAt(remaining, query.argSep);
1215  qctx.args.emplace_back(std::move(arg_split.first));
1216  remaining = std::move(arg_split.second);
1217  }
1218  }
1219 
1220  (this->*(query.func))(qctx);
1221 
1222  return true;
1223 }
1224 
1227 {
1228  return {};
1229 };
1230 
1231 bool
1233  const std::string &annex, std::string &output)
1234 {
1235  return false;
1236 }
1237 
1238 void
1240  const std::string &unencoded, std::string &encoded) const
1241 {
1242  for (const char& c : unencoded) {
1243  if (c == '$' || c == '#' || c == '}' || c == '*') {
1244  encoded += '}';
1245  encoded += c ^ 0x20;
1246  } else {
1247  encoded += c;
1248  }
1249  }
1250 }
1251 
1252 void
1253 BaseRemoteGDB::encodeXferResponse(const std::string &unencoded,
1254  std::string &encoded, size_t offset, size_t unencoded_length) const
1255 {
1256  if (offset + unencoded_length < unencoded.length())
1257  encoded += 'm';
1258  else
1259  encoded += 'l';
1260  encodeBinaryData(unencoded.substr(offset, unencoded_length), encoded);
1261 }
1262 
1263 bool
1265 {
1266  send(tc->getProcessPtr()->pTable->externalize().c_str());
1267  return true;
1268 }
1269 
1270 bool
1272 {
1273  const char *p = ctx.data;
1274  hex2i(&p); // Ignore the subcommand byte.
1275  if (*p++ == ';') {
1276  Addr new_pc = hex2i(&p);
1277  tc->pcState(new_pc);
1278  }
1279  setSingleStep();
1280  return false;
1281 }
1282 
1283 bool
1285 {
1286  if (ctx.len) {
1287  const char *p = ctx.data;
1288  Addr new_pc = hex2i(&p);
1289  tc->pcState(new_pc);
1290  }
1291  setSingleStep();
1292  return false;
1293 }
1294 
1295 bool
1297 {
1298  const char *p = ctx.data;
1299  char sub_cmd = *p++;
1300  if (*p++ != ',')
1301  throw CmdError("E0D");
1302  Addr addr = hex2i(&p);
1303  if (*p++ != ',')
1304  throw CmdError("E0D");
1305  size_t kind = hex2i(&p);
1306 
1307  DPRINTF(GDBMisc, "clear %s, addr=%#x, kind=%d\n",
1308  breakType(sub_cmd), addr, kind);
1309 
1310  switch (sub_cmd) {
1311  case GdbSoftBp:
1312  removeSoftBreak(addr, kind);
1313  break;
1314  case GdbHardBp:
1315  removeHardBreak(addr, kind);
1316  break;
1317  case GdbWriteWp:
1318  case GdbReadWp:
1319  case GdbAccWp:
1320  default: // unknown
1321  throw Unsupported();
1322  }
1323  send("OK");
1324 
1325  return true;
1326 }
1327 
1328 bool
1330 {
1331  const char *p = ctx.data;
1332  char sub_cmd = *p++;
1333  if (*p++ != ',')
1334  throw CmdError("E0D");
1335  Addr addr = hex2i(&p);
1336  if (*p++ != ',')
1337  throw CmdError("E0D");
1338  size_t kind = hex2i(&p);
1339 
1340  DPRINTF(GDBMisc, "set %s, addr=%#x, kind=%d\n",
1341  breakType(sub_cmd), addr, kind);
1342 
1343  switch (sub_cmd) {
1344  case GdbSoftBp:
1345  insertSoftBreak(addr, kind);
1346  break;
1347  case GdbHardBp:
1348  insertHardBreak(addr, kind);
1349  break;
1350  case GdbWriteWp:
1351  case GdbReadWp:
1352  case GdbAccWp:
1353  default: // unknown
1354  throw Unsupported();
1355  }
1356  send("OK");
1357 
1358  return true;
1359 }
1360 
1361 } // namespace gem5
gem5::BaseRemoteGDB::incomingData
void incomingData(int revent)
Definition: remote_gdb.cc:557
gem5::BaseRemoteGDB::queryXfer
void queryXfer(QuerySetCommand::Context &ctx)
Definition: remote_gdb.cc:1130
gem5::curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
gem5::VegaISA::s
Bitfield< 1 > s
Definition: pagetable.hh:64
gem5::VegaISA::f
Bitfield< 56 > f
Definition: pagetable.hh:53
gem5::SETranslatingPortProxy
Definition: se_translating_port_proxy.hh:49
socket.hh
gem5::BaseRemoteGDB::cmdUnsupported
bool cmdUnsupported(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:926
gem5::ThreadContext::Active
@ Active
Running.
Definition: thread_context.hh:109
gem5::GDBStart
static const char GDBStart
Definition: remote_gdb.cc:164
gem5::BaseRemoteGDB::isAttached
bool isAttached()
Definition: remote_gdb.hh:168
warn
#define warn(...)
Definition: logging.hh:246
gem5::BaseRemoteGDB::GdbCommand::Context::type
int type
Definition: remote_gdb.hh:331
gem5::BaseRemoteGDB::cmdDumpPageTable
bool cmdDumpPageTable(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1264
gem5::HardBreakpoint::name
const std::string name() const override
Definition: remote_gdb.cc:185
gem5::BaseRemoteGDB::HardBreakpoint
friend class HardBreakpoint
Definition: remote_gdb.hh:145
gem5::BaseRemoteGDB::cmdSetThread
bool cmdSetThread(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:998
system.hh
gem5::BaseRemoteGDB::insertSoftBreak
void insertSoftBreak(Addr addr, size_t kind)
Definition: remote_gdb.cc:787
data
const char data[]
Definition: circlebuf.test.cc:48
gem5::BaseRemoteGDB::listen
void listen()
Definition: remote_gdb.cc:378
gem5::BaseRemoteGDB::connectEvent
EventWrapper< BaseRemoteGDB, &BaseRemoteGDB::connect > connectEvent
Definition: remote_gdb.hh:274
gem5::BaseRemoteGDB::singleStepEvent
EventWrapper< BaseRemoteGDB, &BaseRemoteGDB::singleStep > singleStepEvent
Definition: remote_gdb.hh:305
gem5::ArmISA::fd
Bitfield< 14, 12 > fd
Definition: types.hh:150
gem5::BaseRemoteGDB::GdbCommand::name
const char *const name
Definition: remote_gdb.hh:338
gem5::BaseRemoteGDB::gdbRegs
virtual BaseGdbRegCache * gdbRegs()=0
warn_once
#define warn_once(...)
Definition: logging.hh:250
gem5::BaseRemoteGDB::cmdRegR
bool cmdRegR(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:974
gem5::output
static void output(const char *filename)
Definition: debug.cc:60
gem5::BaseRemoteGDB::encodeBinaryData
void encodeBinaryData(const std::string &unencoded, std::string &encoded) const
Definition: remote_gdb.cc:1239
remote_gdb.hh
gem5::BaseRemoteGDB::putbyte
void putbyte(uint8_t b)
Definition: remote_gdb.cc:585
gem5::pollQueue
PollQueue pollQueue
Definition: pollevent.cc:55
gem5::BaseRemoteGDB::scheduleInstCommitEvent
void scheduleInstCommitEvent(Event *ev, int delta)
Schedule an event which will be triggered "delta" instructions later.
Definition: remote_gdb.cc:839
gem5::ThreadContext::pcState
virtual const PCStateBase & pcState() const =0
gem5::BaseRemoteGDB::fd
int fd
Definition: remote_gdb.hh:236
gem5::EmulationPageTable::externalize
const std::string externalize() const
Dump all items in the pTable, to a concatenation of strings of the form Addr:Entry;.
Definition: page_table.cc:224
gem5::BaseRemoteGDB::listener
ListenSocket listener
Definition: remote_gdb.hh:232
gem5::BaseRemoteGDB::removeHardBreak
void removeHardBreak(Addr addr, size_t kind)
Definition: remote_gdb.cc:820
gem5::BaseRemoteGDB::commandMap
static std::map< char, GdbCommand > commandMap
Definition: remote_gdb.hh:344
translating_port_proxy.hh
gem5::BaseRemoteGDB::queryC
void queryC(QuerySetCommand::Context &ctx)
Definition: remote_gdb.cc:1111
gem5::ArmISA::e
Bitfield< 9 > e
Definition: misc_types.hh:65
gem5::BaseRemoteGDB::insertHardBreak
void insertHardBreak(Addr addr, size_t kind)
Definition: remote_gdb.cc:805
gem5::ThreadContext::contextId
virtual ContextID contextId() const =0
gem5::BaseRemoteGDB::acc
virtual bool acc(Addr addr, size_t len)=0
std::vector< char >
gem5::VegaISA::r
Bitfield< 5 > r
Definition: pagetable.hh:60
gem5::BaseRemoteGDB::cmdMemW
bool cmdMemW(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1063
gem5::BaseRemoteGDB::GdbCommand::Context::data
char * data
Definition: remote_gdb.hh:332
gem5::ArmISA::i
Bitfield< 7 > i
Definition: misc_types.hh:67
gem5::BaseRemoteGDB::sys
System * sys
Definition: remote_gdb.hh:267
gem5::BaseRemoteGDB::cmdStep
bool cmdStep(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1284
gem5::PollQueue::remove
void remove(PollEvent *event)
Definition: pollevent.cc:139
gem5::GDBEnd
static const char GDBEnd
Definition: remote_gdb.cc:165
gem5::ccprintf
void ccprintf(cp::Print &print)
Definition: cprintf.hh:130
gem5::BaseRemoteGDB::BaseRemoteGDB
BaseRemoteGDB(System *system, int _port)
Interface to other parts of the simulator.
Definition: remote_gdb.cc:358
gem5::ListenSocket::accept
virtual int accept(bool nodelay=false)
Definition: socket.cc:176
gem5::ThreadContext::status
virtual Status status() const =0
gem5::HardBreakpoint
Definition: remote_gdb.cc:169
gem5::BaseRemoteGDB::GdbCommand::Context::cmd
const GdbCommand * cmd
Definition: remote_gdb.hh:329
gem5::TranslatingPortProxy
This proxy attempts to translate virtual addresses using the TLBs.
Definition: translating_port_proxy.hh:60
gem5::BaseRemoteGDB::attach
void attach(int fd)
Definition: remote_gdb.cc:425
gem5::BaseRemoteGDB::port
int port() const
Definition: remote_gdb.cc:417
gem5::BaseGdbRegCache::getRegs
virtual void getRegs(ThreadContext *)=0
Fill the raw buffer from the registers in the ThreadContext.
gem5::ThreadContext::getCurrentInstCount
virtual Tick getCurrentInstCount()=0
gem5::BaseRemoteGDB::incomingDataEvent
IncomingDataEvent * incomingDataEvent
Definition: remote_gdb.hh:230
gem5::ListenSocket::getfd
int getfd() const
Definition: socket.hh:77
gem5::BaseRemoteGDB::GdbCommand::func
const Func func
Definition: remote_gdb.hh:339
gem5::VegaISA::c
Bitfield< 2 > c
Definition: pagetable.hh:63
DPRINTFNR
#define DPRINTFNR(...)
Definition: trace.hh:221
gem5::BaseRemoteGDB::encodeXferResponse
void encodeXferResponse(const std::string &unencoded, std::string &encoded, size_t offset, size_t unencoded_length) const
Definition: remote_gdb.cc:1253
gem5::System
Definition: system.hh:75
gem5::BaseRemoteGDB::availableFeatures
virtual std::vector< std::string > availableFeatures() const
Definition: remote_gdb.cc:1226
gem5::ArmISA::b
Bitfield< 7 > b
Definition: misc_types.hh:382
gem5::BaseRemoteGDB::incomingConnectionEvent
IncomingConnectionEvent * incomingConnectionEvent
Definition: remote_gdb.hh:229
gem5::ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:94
gem5::HardBreakpoint::gdb
BaseRemoteGDB * gdb
Definition: remote_gdb.cc:172
gem5::Named::name
virtual std::string name() const
Definition: named.hh:47
gem5::PCEvent::pc
Addr pc() const
Definition: pc_event.hh:61
gem5::VegaISA::p
Bitfield< 54 > p
Definition: pagetable.hh:70
gem5::BaseRemoteGDB::tc
ThreadContext * tc
Definition: remote_gdb.hh:270
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:186
gem5::Event
Definition: eventq.hh:251
gem5::BaseRemoteGDB::cmdSignal
bool cmdSignal(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:935
gem5::Process::pTable
EmulationPageTable * pTable
Definition: process.hh:185
gem5::HardBreakpoint::process
void process(ThreadContext *tc) override
Definition: remote_gdb.cc:188
gem5::PCEvent
Definition: pc_event.hh:45
gem5::BaseRemoteGDB::setSingleStep
void setSingleStep()
Definition: remote_gdb.cc:780
gem5::Event::process
virtual void process()=0
gem5::BaseRemoteGDB::name
std::string name()
Definition: remote_gdb.cc:372
port_proxy.hh
gem5::HardBreakpoint::HardBreakpoint
HardBreakpoint(BaseRemoteGDB *_gdb, PCEventScope *s, Addr pc)
Definition: remote_gdb.cc:178
process.hh
len
uint16_t len
Definition: helpers.cc:62
gem5::BaseRemoteGDB::cmdAsyncCont
bool cmdAsyncCont(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:954
gem5::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).
port.hh
gem5::BaseRemoteGDB::_port
int _port
Definition: remote_gdb.hh:233
gem5::GDBGoodP
static const char GDBGoodP
Definition: remote_gdb.cc:166
gem5::ArmISA::offset
Bitfield< 23, 0 > offset
Definition: types.hh:144
gem5::BaseGdbRegCache::data
virtual char * data() const =0
Return the pointer to the raw bytes buffer containing the register values.
gem5::ListenSocket::listen
virtual bool listen(int port, bool reuse=true)
Definition: socket.cc:122
cprintf.hh
gem5::BaseRemoteGDB::querySupported
void querySupported(QuerySetCommand::Context &ctx)
Definition: remote_gdb.cc:1117
static_inst.hh
gem5::PollQueue::schedule
void schedule(PollEvent *event)
Definition: pollevent.cc:159
gem5::BaseRemoteGDB::trapEvent
gem5::BaseRemoteGDB::TrapEvent trapEvent
gem5::BaseRemoteGDB::QuerySetCommand::Context
Definition: remote_gdb.hh:366
std::pair
STL pair class.
Definition: stl.hh:58
gem5::BaseRemoteGDB::replaceThreadContext
void replaceThreadContext(ThreadContext *tc)
Definition: remote_gdb.hh:54
gem5::BaseRemoteGDB::cmdRegW
bool cmdRegW(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:984
gem5::ListenSocket::allDisabled
static bool allDisabled()
Definition: socket.cc:71
gem5::BaseRemoteGDB::getXferFeaturesRead
virtual bool getXferFeaturesRead(const std::string &annex, std::string &output)
Get an XML target description.
Definition: remote_gdb.cc:1232
gem5::Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
gem5::BaseRemoteGDB::write
bool write(Addr addr, size_t size, const char *data)
Definition: remote_gdb.cc:748
gem5::HardBreakpoint::refcount
int refcount
Definition: remote_gdb.cc:175
gem5::BaseRemoteGDB::removeSoftBreak
void removeSoftBreak(Addr addr, size_t kind)
Definition: remote_gdb.cc:796
gem5::BaseRemoteGDB::IncomingDataEvent
SocketEvent<&BaseRemoteGDB::incomingData > IncomingDataEvent
Definition: remote_gdb.hh:224
gem5::BaseRemoteGDB::clearSingleStep
void clearSingleStep()
Definition: remote_gdb.cc:774
warning
const char * warning
Definition: remote_gdb.cc:202
gem5::BaseRemoteGDB::disconnectEvent
EventWrapper< BaseRemoteGDB, &BaseRemoteGDB::detach > disconnectEvent
Definition: remote_gdb.hh:275
DDUMP
#define DDUMP(x, data, count)
DPRINTF is a debugging trace facility that allows one to selectively enable tracing statements.
Definition: trace.hh:180
gem5::BaseRemoteGDB::detach
void detach()
Definition: remote_gdb.cc:450
gem5::BaseRemoteGDB::TrapEvent::id
void id(ContextID id)
Definition: remote_gdb.hh:289
full_system.hh
gem5::ThreadContext::scheduleInstCountEvent
virtual void scheduleInstCountEvent(Event *event, Tick count)=0
gem5::BaseRemoteGDB::IncomingConnectionEvent
SocketEvent<&BaseRemoteGDB::incomingConnection > IncomingConnectionEvent
Definition: remote_gdb.hh:222
gem5::ThreadContext::getProcessPtr
virtual Process * getProcessPtr()=0
gem5::FullSystem
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:220
gem5::BaseRemoteGDB::regCachePtr
BaseGdbRegCache * regCachePtr
Definition: remote_gdb.hh:272
gem5::BaseRemoteGDB::processCommands
void processCommands(int signum=0)
Definition: remote_gdb.cc:675
gem5::BaseRemoteGDB::GdbCommand::Context
Definition: remote_gdb.hh:327
gem5::BaseRemoteGDB::TrapEvent::type
void type(int t)
Definition: remote_gdb.hh:288
gem5::BaseRemoteGDB::selectThreadContext
bool selectThreadContext(ContextID id)
Definition: remote_gdb.cc:498
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:204
gem5::BaseRemoteGDB::cmdClrHwBkpt
bool cmdClrHwBkpt(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1296
gem5::BaseRemoteGDB::cmdSetHwBkpt
bool cmdSetHwBkpt(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1329
gem5::BaseGdbRegCache::setRegs
virtual void setRegs(ThreadContext *) const =0
Set the ThreadContext's registers from the values in the raw buffer.
gem5::BaseRemoteGDB::send
void send(const char *data)
Definition: remote_gdb.cc:647
base.hh
gem5::ThreadContext::descheduleInstCountEvent
virtual void descheduleInstCountEvent(Event *event)=0
gem5::ArmISA::n
Bitfield< 31 > n
Definition: misc_types.hh:456
gem5::BaseRemoteGDB::read
bool read(Addr addr, size_t size, char *data)
Definition: remote_gdb.cc:725
gem5::BaseRemoteGDB::descheduleInstCommitEvent
void descheduleInstCommitEvent(Event *ev)
Deschedule an instruction count based event.
Definition: remote_gdb.cc:854
gem5::BaseRemoteGDB::threadSwitching
bool threadSwitching
Definition: remote_gdb.hh:265
gem5::BaseRemoteGDB::queryMap
static std::map< std::string, QuerySetCommand > queryMap
Definition: remote_gdb.hh:384
gem5::BaseRemoteGDB::recv
void recv(std::vector< char > &bp)
Definition: remote_gdb.cc:595
gem5::BaseRemoteGDB::cmdDetach
bool cmdDetach(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:967
gem5::ContextID
int ContextID
Globally unique thread context ID.
Definition: types.hh:239
gem5::BaseRemoteGDB::addThreadContext
void addThreadContext(ThreadContext *_tc)
Definition: remote_gdb.cc:475
gem5::BaseRemoteGDB::QuerySetCommand::Context::args
std::vector< std::string > args
Definition: remote_gdb.hh:369
logging.hh
gem5::BaseRemoteGDB::cmdMemR
bool cmdMemR(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1039
gem5::BaseRemoteGDB::~BaseRemoteGDB
virtual ~BaseRemoteGDB()
Definition: remote_gdb.hh:57
se_translating_port_proxy.hh
trace.hh
gem5::BaseRemoteGDB::singleStep
void singleStep()
Definition: remote_gdb.cc:766
gem5::BaseRemoteGDB::incomingConnection
void incomingConnection(int revent)
Definition: remote_gdb.cc:544
gem5::BaseRemoteGDB
Definition: remote_gdb.hh:48
DPRINTFN
#define DPRINTFN(...)
Definition: trace.hh:214
gem5::MipsISA::vaddr
vaddr
Definition: pra_constants.hh:278
gem5::BaseRemoteGDB::GdbCommand::Context::cmdByte
char cmdByte
Definition: remote_gdb.hh:330
gem5::PCEvent::evpc
Addr evpc
Definition: pc_event.hh:50
gem5::BaseRemoteGDB::queryFThreadInfo
void queryFThreadInfo(QuerySetCommand::Context &ctx)
Definition: remote_gdb.cc:1171
intmath.hh
gem5::BaseRemoteGDB::cmdCont
bool cmdCont(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:942
gem5::BaseRemoteGDB::threads
std::map< ContextID, ThreadContext * > threads
Definition: remote_gdb.hh:269
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: gpu_translation_state.hh:37
gem5::BaseRemoteGDB::connect
void connect()
Definition: remote_gdb.cc:399
gem5::BaseRemoteGDB::cmdAsyncStep
bool cmdAsyncStep(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1271
gem5::BaseRemoteGDB::attached
bool attached
Definition: remote_gdb.hh:264
gem5::BaseRemoteGDB::threadInfoIdx
size_t threadInfoIdx
Definition: remote_gdb.hh:390
gem5::BaseRemoteGDB::cmdQueryVar
bool cmdQueryVar(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1191
gem5::GDBBadP
static const char GDBBadP
Definition: remote_gdb.cc:167
gem5::PCEventScope
Definition: pc_event.hh:67
thread_context.hh
gem5::BaseRemoteGDB::trap
bool trap(ContextID id, int type)
Definition: remote_gdb.hh:55
gem5::BaseRemoteGDB::querySThreadInfo
void querySThreadInfo(QuerySetCommand::Context &ctx)
Definition: remote_gdb.cc:1178
gem5::BaseRemoteGDB::GdbCommand::Context::len
int len
Definition: remote_gdb.hh:333
gem5::Event::scheduled
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:465
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
gem5::ListenSocket::islistening
bool islistening() const
Definition: socket.hh:78
gem5::X86ISA::addr
Bitfield< 3 > addr
Definition: types.hh:84
gem5::BaseRemoteGDB::getbyte
uint8_t getbyte()
Definition: remote_gdb.cc:575
error
std::string error
Definition: remote_gdb.cc:210
gem5::BaseRemoteGDB::checkBpKind
virtual bool checkBpKind(size_t kind)
Definition: remote_gdb.cc:920

Generated on Wed Jul 13 2022 10:39:11 for gem5 by doxygen 1.8.17