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

Generated on Wed Jul 28 2021 12:10:21 for gem5 by doxygen 1.8.17