gem5  [DEVELOP-FOR-23.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, 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/select.h>
133 #include <sys/time.h>
134 #include <unistd.h>
135 
136 #include <cassert>
137 #include <csignal>
138 #include <cstdint>
139 #include <cstdio>
140 #include <iterator>
141 #include <sstream>
142 #include <string>
143 #include <utility>
144 
145 #include "base/cprintf.hh"
146 #include "base/intmath.hh"
147 #include "base/logging.hh"
148 #include "base/socket.hh"
149 #include "base/trace.hh"
150 #include "cpu/base.hh"
151 #include "cpu/static_inst.hh"
152 #include "cpu/thread_context.hh"
153 #include "debug/GDBAll.hh"
154 #include "mem/port.hh"
155 #include "mem/port_proxy.hh"
158 #include "sim/full_system.hh"
159 #include "sim/process.hh"
160 #include "sim/sim_events.hh"
161 #include "sim/system.hh"
162 
163 namespace gem5
164 {
165 
166 static const char GDBStart = '$';
167 static const char GDBEnd = '#';
168 static const char GDBGoodP = '+';
169 static const char GDBBadP = '-';
170 
171 class HardBreakpoint : public PCEvent
172 {
173  private:
175 
176  public:
177  int refcount;
178 
179  public:
181  : PCEvent(s, "HardBreakpoint Event", pc),
182  gdb(_gdb), refcount(0)
183  {
184  DPRINTF(GDBMisc, "creating hardware breakpoint at %#x\n", evpc);
185  }
186 
187  const std::string name() const override { return gdb->name() + ".hwbkpt"; }
188 
189  void
190  process(ThreadContext *tc) override
191  {
192  DPRINTF(GDBMisc, "handling hardware breakpoint at %#x\n", pc());
193 
194  if (tc == gdb->tc)
195  gdb->trap(tc->contextId(), GDBSignal::TRAP,"");
196  }
197 };
198 
199 namespace {
200 
201 // Exception to throw when the connection to the client is broken.
202 struct BadClient
203 {
204  const char *warning;
205  BadClient(const char *_warning=NULL) : warning(_warning)
206  {}
207 };
208 
209 // Exception to throw when an error needs to be reported to the client.
210 struct CmdError
211 {
212  std::string error;
213  CmdError(std::string _error) : error(_error)
214  {}
215 };
216 
217 // Exception to throw when something isn't supported.
218 class Unsupported {};
219 
220 // Convert a hex digit into an integer.
221 // This returns -1 if the argument passed is no valid hex digit.
222 int
223 digit2i(char c)
224 {
225  if (c >= '0' && c <= '9')
226  return (c - '0');
227  else if (c >= 'a' && c <= 'f')
228  return (c - 'a' + 10);
229  else if (c >= 'A' && c <= 'F')
230  return (c - 'A' + 10);
231  else
232  return -1;
233 }
234 
235 //convert a hex to a char
236 char
237 hex2c(char c0,char c1)
238 {
239  char temp[3] = {c0,c1,'\0'};
240  return std::stoi(temp,0,16);
241 }
242 
243 //this function will be used in a future patch
244 //convert a encoded string to a string
245 std::string
246 hexS2string(std::string hex_in)
247 {
248  std::string out="";
249  for (unsigned int i = 0; i + 1 < hex_in.length();i += 2){
250  out.push_back(hex2c(hex_in[i],hex_in[i+1]));
251  }
252  return out;
253 }
254 
255 //convert a string to a hex encoded string
256 std::string
257 string2hexS(std::string in)
258 {
259  std::string out = "";
260  for (auto ch : in){
261  char temp[3] = " ";
262  std::snprintf(temp,3,"%02hhx",ch);
263  out.append(temp);
264  }
265  return out;
266 }
267 
268 // Convert the low 4 bits of an integer into an hex digit.
269 char
270 i2digit(int n)
271 {
272  return "0123456789abcdef"[n & 0x0f];
273 }
274 
275 // Convert a byte array into an hex string.
276 void
277 mem2hex(char *vdst, const char *vsrc, int len)
278 {
279  char *dst = vdst;
280  const char *src = vsrc;
281 
282  while (len--) {
283  *dst++ = i2digit(*src >> 4);
284  *dst++ = i2digit(*src++);
285  }
286  *dst = '\0';
287 }
288 
289 // Convert an hex string into a byte array.
290 // This returns a pointer to the character following the last valid
291 // hex digit. If the string ends in the middle of a byte, NULL is
292 // returned.
293 const char *
294 hex2mem(char *vdst, const char *src, int max_len)
295 {
296  char *dst = vdst;
297  int msb, lsb;
298 
299  while (*src && max_len--) {
300  msb = digit2i(*src++);
301  if (msb < 0)
302  return (src - 1);
303  lsb = digit2i(*src++);
304  if (lsb < 0)
305  return (NULL);
306  *dst++ = (msb << 4) | lsb;
307  }
308  return src;
309 }
310 
311 // Convert an hex string into an integer.
312 // This returns a pointer to the character following the last valid
313 // hex digit.
314 Addr
315 hex2i(const char **srcp)
316 {
317  const char *src = *srcp;
318  Addr r = 0;
319  int nibble;
320 
321  while ((nibble = digit2i(*src)) >= 0) {
322  r *= 16;
323  r += nibble;
324  src++;
325  }
326  *srcp = src;
327  return r;
328 }
329 
330 bool
331 parseThreadId(const char **srcp, bool &all, bool &any, ContextID &tid)
332 {
333  all = any = false;
334  tid = 0;
335  const char *src = *srcp;
336  if (*src == '-') {
337  // This could be the start of -1, which means all threads.
338  src++;
339  if (*src++ != '1')
340  return false;
341  *srcp += 2;
342  all = true;
343  return true;
344  }
345  tid = hex2i(srcp);
346  // If *srcp still points to src, no characters were consumed and no thread
347  // id was found. Without this check, we can't tell the difference between
348  // zero and a parsing error.
349  if (*srcp == src)
350  return false;
351 
352  if (tid == 0)
353  any = true;
354 
355  tid--;
356 
357  return true;
358 }
359 
360 int
361 encodeThreadId(ContextID id)
362 {
363  // Thread ID 0 is reserved and means "pick any thread".
364  return id + 1;
365 }
366 
367 enum GdbBreakpointType
368 {
369  GdbSoftBp = '0',
370  GdbHardBp = '1',
371  GdbWriteWp = '2',
372  GdbReadWp = '3',
373  GdbAccWp = '4',
374 };
375 
376 const char *
377 breakType(char c)
378 {
379  switch(c) {
380  case GdbSoftBp: return "software breakpoint";
381  case GdbHardBp: return "hardware breakpoint";
382  case GdbWriteWp: return "write watchpoint";
383  case GdbReadWp: return "read watchpoint";
384  case GdbAccWp: return "access watchpoint";
385  default: return "unknown breakpoint/watchpoint";
386  }
387 }
388 
389 std::map<Addr, HardBreakpoint *> hardBreakMap;
390 
391 }
392 
394  ListenSocketConfig _listen_config) :
395  incomingConnectionEvent(nullptr), incomingDataEvent(nullptr),
396  fd(-1), sys(_system), connectEvent(*this), disconnectEvent(*this),
397  trapEvent(this), singleStepEvent(*this)
398 {
399  listener = _listen_config.build(name());
400 }
401 
403 {
405  delete incomingDataEvent;
406 }
407 
408 std::string
410 {
411  return sys->name() + ".remote_gdb";
412 }
413 
414 void
416 {
418  warn_once("Sockets disabled, not accepting gdb connections");
419  return;
420  }
421 
422  listener->listen();
423 
425  new IncomingConnectionEvent(this, listener->getfd(), POLLIN);
427 }
428 
429 void
431 {
432  panic_if(!listener->islistening(),
433  "Can't accept GDB connections without any threads!");
434 
436 
437  int sfd = listener->accept();
438 
439  if (sfd != -1) {
440  if (isAttached())
441  close(sfd);
442  else
443  attach(sfd);
444  }
445 }
446 
447 const ListenSocket &
449 {
450  panic_if(!listener->islistening(),
451  "Remote GDB socket is unknown until listen() has been called.");
452  return *listener;
453 }
454 
455 void
457 {
458  fd = f;
459 
460  attached = true;
461  DPRINTFN("remote gdb attached\n");
462 
463  processCommands();
464 
465  if (isAttached()) {
466  // At this point an initial communication with GDB is handled
467  // and we're ready to continue. Here we arrange IncomingDataEvent
468  // to get notified when GDB breaks in.
469  //
470  // However, GDB can decide to disconnect during that initial
471  // communication. In that case, we cannot arrange data event because
472  // the socket is already closed (not that it makes any sense, anyways).
473  //
474  // Hence the check above.
475  incomingDataEvent = new IncomingDataEvent(this, fd, POLLIN);
477  }
478 }
479 
480 void
482 {
483  attached = false;
484  clearSingleStep();
485  close(fd);
486  fd = -1;
487 
488  if (incomingDataEvent) {
489  // incomingDataEvent gets scheduled in attach() after
490  // initial communication with GDB is handled and GDB tells
491  // gem5 to continue.
492  //
493  // GDB can disconnect before that in which case `incomingDataEvent`
494  // is NULL.
495  //
496  // Hence the check above.
497 
499  incomingDataEvent = nullptr;
500  }
502  DPRINTFN("remote gdb detached\n");
503 }
504 
505 void
507 {
508  [[maybe_unused]] auto it_success = threads.insert({_tc->contextId(), _tc});
509  assert(it_success.second);
510  // If no ThreadContext is current selected, select this one.
511  if (!tc)
512  assert(selectThreadContext(_tc->contextId()));
513 
514  // Now that we have a thread, we can start listening.
515  if (!listener->islistening())
516  listen();
517 }
518 
519 void
521 {
522  auto it = threads.find(_tc->contextId());
523  panic_if(it == threads.end(), "No context with ID %d found.",
524  _tc->contextId());
525  it->second = _tc;
526 }
527 
528 bool
530 {
531  auto it = threads.find(id);
532  if (it == threads.end())
533  return false;
534 
535  tc = it->second;
536  // Update the register cache for the new thread context, if there is one.
537  if (regCachePtr)
539  return true;
540 }
541 
542 // This function does all command processing for interfacing to a
543 // remote gdb. Note that the error codes are ignored by gdb at
544 // present, but might eventually become meaningful. (XXX) It might
545 // makes sense to use POSIX errno values, because that is what the
546 // gdb/remote.c functions want to return.
547 void
548 BaseRemoteGDB::trap(ContextID id, GDBSignal sig,const std::string& stopReason)
549 {
550  if (!attached)
551  return;
552 
553  if (tc->contextId() != id) {
554  //prevent thread switch when single stepping
555  if (singleStepEvent.scheduled()){
556  return;
557  }
558  DPRINTF(GDBMisc, "Finishing thread switch");
559  if (!selectThreadContext(id))
560  return;
561  }
562 
563 
564  DPRINTF(GDBMisc, "trap: PC=%s\n", tc->pcState());
565 
566  clearSingleStep();
567  if (stopReason=="monitor_return"){
568  //should wnot send any Tpacket here
569  send("OK");
570  }else if (threadSwitching) {
571  threadSwitching = false;
572  // Tell GDB the thread switch has completed.
573  send("OK");
574  } else {
575  // Tell remote host that an exception has occurred.
576  sendTPacket(sig,id,stopReason);
577  }
578 
579  processCommands(sig);
580 }
581 
582 bool
583 BaseRemoteGDB::sendMessage(std::string message)
584 {
585  if (!attached)
586  return false;
587  DPRINTF(GDBMisc, "passing message %s\n", message);
588  sendOPacket(message);
589  return true;
590 }
591 
592 void
594 {
595  if (connectEvent.scheduled()) {
596  warn("GDB connect event has already been scheduled!");
597  return;
598  }
599 
600  if (revent & POLLIN) {
602  }
603 }
604 
605 void
607 {
608  if (trapEvent.scheduled()) {
609  warn("GDB trap event has already been scheduled!");
610  return;
611  }
612 
613  if (revent & POLLIN) {
614  scheduleTrapEvent(tc->contextId(),GDBSignal::ILL,0,"");
615  } else if (revent & POLLNVAL) {
618  }
619 }
620 
621 uint8_t
623 {
624  uint8_t b;
625  while (!try_getbyte(&b,-1));//no timeout
626  return b;
627 }
628 
629 bool
630 BaseRemoteGDB::try_getbyte(uint8_t* c,int timeout_ms)
631 {
632  if (!c)
633  panic("try_getbyte called with a null pointer as c");
634  int res,retval;
635  //Allow read to fail if it was interrupted by a signal (EINTR).
636  errno = 0;
637  //preparing fd_sets
638  fd_set rfds;
639  FD_ZERO(&rfds);
640  FD_SET(fd, &rfds);
641 
642  //setting up a timeout if timeout_ms is positive
643  struct timeval tv;struct timeval* tv_ptr;
644  if (timeout_ms >= 0){
645  tv.tv_sec = timeout_ms/1000;
646  tv.tv_usec = timeout_ms%1000;
647  tv_ptr = &tv;
648  }else{
649  tv_ptr = NULL;
650  }
651  //Using select to check if the FD is ready to be read.
652  while(true){
653  do {
654  errno = 0;
655  retval = ::select(fd + 1, &rfds, NULL, NULL, tv_ptr);
656  if (retval < 0 && errno != EINTR){//error
657  DPRINTF(GDBMisc,"getbyte failed errno=%i retval=%i\n",
658  errno,retval);
659  throw BadClient("Couldn't read data from debugger.");
660  }
661  //a EINTR error means that the select call was interrupted
662  //by another signal
663  }while (errno == EINTR);
664  if (retval == 0)
665  return false;//timed out
666  //reading (retval>0)
667  res = ::read(fd, c, sizeof(*c));
668  if (res == sizeof(*c))
669  return true;//read successfully
670  //read failed (?) retrying select
671  }
672 }
673 void
675 {
676  if (::write(fd, &b, sizeof(b)) == sizeof(b))
677  return;
678 
679  throw BadClient("Couldn't write data to the debugger.");
680 }
681 
682 // Receive a packet from gdb
683 void
685 {
686  uint8_t c;
687  int csum;
688  bp.resize(0);
689 
690  do {
691  csum = 0;
692  // Find the beginning of a packet
693  while ((c = getbyte()) != GDBStart);
694 
695  // Read until you find the end of the data in the packet, and keep
696  // track of the check sum.
697  while (true) {
698  c = getbyte();
699  if (c == GDBEnd)
700  break;
701  c &= 0x7f;
702  csum += c;
703  bp.push_back(c);
704  }
705 
706  // Mask the check sum.
707  csum &= 0xff;
708 
709  // Bring in the checksum. If the check sum matches, csum will be 0.
710  csum -= digit2i(getbyte()) * 16;
711  csum -= digit2i(getbyte());
712 
713  // If the check sum was correct
714  if (csum == 0) {
715  // Report that the packet was received correctly
716  putbyte(GDBGoodP);
717  // Sequence present?
718  if (bp.size() > 2 && bp[2] == ':') {
719  putbyte(bp[0]);
720  putbyte(bp[1]);
721  auto begin = std::begin(bp);
722  bp.erase(begin, std::next(begin, 3));
723  }
724  break;
725  }
726  // Otherwise, report that there was a mistake.
727  putbyte(GDBBadP);
728  } while (1);
729  // Sentinel.
730  bp.push_back('\0');
731  DPRINTF(GDBRecv, "recv: %s\n", bp.data());
732 }
733 
734 // Send a packet to gdb
735 void
736 BaseRemoteGDB::send(const char *bp)
737 {
738  const char *p;
739  uint8_t csum, c;
740 
741  DPRINTF(GDBSend, "send: %s\n", bp);
742  //removing GDBBadP that could be waiting in the buffer
743  while (try_getbyte(&c,0));
744  do {
745  p = bp;
746  // Start sending a packet
747  putbyte(GDBStart);
748  // Send the contents, and also keep a check sum.
749  for (csum = 0; (c = *p); p++) {
750  putbyte(c);
751  csum += c;
752  }
753  // Send the ending character.
754  putbyte(GDBEnd);
755  // Send the checksum.
756  putbyte(i2digit(csum >> 4));
757  putbyte(i2digit(csum));
758  // Try transmitting over and over again until the other end doesn't
759  // send an error back.
760  c = getbyte();
761  if ((c & 0x7f) == GDBBadP)
762  DPRINTF(GDBSend, "PacketError\n");
763  } while ((c & 0x7f) == GDBBadP);
764 }
765 
766 void
768 {
769  // Stick frame regs into our reg cache.
770  regCachePtr = gdbRegs();
772 
773  GdbCommand::Context cmd_ctx;
774  cmd_ctx.type = sig;
776 
777  for (;;) {
778  try {
779  recv(data);
780  if (data.size() == 1)
781  throw BadClient();
782  cmd_ctx.cmdByte = data[0];
783  cmd_ctx.data = data.data() + 1;
784  // One for sentinel, one for cmdByte.
785  cmd_ctx.len = data.size() - 2;
786 
787  auto cmd_it = commandMap.find(cmd_ctx.cmdByte);
788  if (cmd_it == commandMap.end()) {
789  DPRINTF(GDBMisc, "Unknown command: %c(%#x)\n",
790  cmd_ctx.cmdByte, cmd_ctx.cmdByte);
791  throw Unsupported();
792  }
793  cmd_ctx.cmd = &(cmd_it->second);
794 
795  if (!(this->*(cmd_ctx.cmd->func))(cmd_ctx))
796  break;
797 
798  } catch (BadClient &e) {
799  if (e.warning)
800  warn(e.warning);
801  detach();
802  break;
803  } catch (Unsupported &e) {
804  send("");
805  } catch (CmdError &e) {
806  send(e.error);
807  } catch (std::exception &e) {
808  panic("Unrecognized GDB exception: %s", e.what());
809  } catch (...) {
810  panic("Unrecognized GDB exception.");
811  }
812  }
813 }
814 
815 bool
817 {
818  TranslatingPortProxy fs_proxy(tc);
819  SETranslatingPortProxy se_proxy(tc);
820  PortProxy &virt_proxy = FullSystem ? fs_proxy : se_proxy;
821 
822  virt_proxy.readBlob(vaddr, data, size);
823  return true;
824 }
825 
826 bool
827 BaseRemoteGDB::writeBlob(Addr vaddr, size_t size, const char *data)
828 {
829  TranslatingPortProxy fs_proxy(tc);
830  SETranslatingPortProxy se_proxy(tc);
831  PortProxy &virt_proxy = FullSystem ? fs_proxy : se_proxy;
832 
833  virt_proxy.writeBlob(vaddr, data, size);
834  return true;
835 }
836 
837 // Read bytes from kernel address space for debugger.
838 bool
839 BaseRemoteGDB::read(Addr vaddr, size_t size, char *data)
840 {
841  DPRINTF(GDBRead, "read: addr=%#x, size=%d", vaddr, size);
842 
843  bool res = readBlob(vaddr, size, data);
844 
845  if (!res)
846  return false;
847 
848 #if TRACING_ON
849  if (debug::GDBRead) {
850  if (debug::GDBExtra) {
851  char buf[1024];
852  mem2hex(buf, data, size);
853  DPRINTFNR(": %s\n", buf);
854  } else
855  DPRINTFNR("\n");
856  }
857 #endif
858 
859  return true;
860 }
861 
862 // Write bytes to kernel address space for debugger.
863 bool
864 BaseRemoteGDB::write(Addr vaddr, size_t size, const char *data)
865 {
866  if (debug::GDBWrite) {
867  DPRINTFN("write: addr=%#x, size=%d", vaddr, size);
868  if (debug::GDBExtra) {
869  char buf[1024];
870  mem2hex(buf, data, size);
871  DPRINTFNR(": %s\n", buf);
872  } else
873  DPRINTFNR("\n");
874  }
875  return writeBlob(vaddr, size, data);
876 }
877 
878 void
880 {
881  if (!singleStepEvent.scheduled())
883  trap(tc->contextId(), GDBSignal::TRAP);
884 }
885 
886 void
888 {
890 }
891 
892 void
894 {
895  if (!singleStepEvent.scheduled())
897 }
898 
899 void
901 {
902  if (!checkBpKind(kind))
903  throw BadClient("Invalid breakpoint kind.\n");
904 
905  return insertHardBreak(addr, kind);
906 }
907 
908 void
910 {
911  if (!checkBpKind(kind))
912  throw BadClient("Invalid breakpoint kind.\n");
913 
914  return removeHardBreak(addr, kind);
915 }
916 
917 void
919 {
920  if (!checkBpKind(kind))
921  throw BadClient("Invalid breakpoint kind.\n");
922 
923  DPRINTF(GDBMisc, "Inserting hardware breakpoint at %#x\n", addr);
924 
925  HardBreakpoint *&bkpt = hardBreakMap[addr];
926  if (bkpt == 0)
927  bkpt = new HardBreakpoint(this, sys, addr);
928 
929  bkpt->refcount++;
930 }
931 
932 void
934 {
935  if (!checkBpKind(kind))
936  throw BadClient("Invalid breakpoint kind.\n");
937 
938  DPRINTF(GDBMisc, "Removing hardware breakpoint at %#x\n", addr);
939 
940  auto i = hardBreakMap.find(addr);
941  if (i == hardBreakMap.end())
942  throw CmdError("E0C");
943 
944  HardBreakpoint *hbp = (*i).second;
945  if (--hbp->refcount == 0) {
946  delete hbp;
947  hardBreakMap.erase(i);
948  }
949 }
950 
951 void
953  const std::string& stopReason)
954 {
955  if (!stopReason.empty()){
956  send("T%02xcore:%x;thread:%x;%s;",
957  (uint8_t)sig,id + 1,id + 1,stopReason);
958  }else{
959  send("T%02xcore:%x;thread:%x;",
960  (uint8_t)sig,id + 1,id + 1);
961  }
962 }
963 void
965  send("S%02x",(uint8_t)sig);
966 }
967 void
968 BaseRemoteGDB::sendOPacket(const std::string message){
969  send("O" + string2hexS(message));
970 }
971 
972 void
973 BaseRemoteGDB::scheduleTrapEvent(ContextID id,GDBSignal sig,int delta,
974  std::string stopReason){
975  ThreadContext* _tc = threads[id];
976  panic_if(_tc == nullptr, "Unknown context id :%i",id);
977  trapEvent.id(id);
978  trapEvent.type(sig);
979  trapEvent.stopReason(stopReason);
980  if (!trapEvent.scheduled())
982 }
983 
984 void
986 {
987  if (delta == 0 && _tc->status() != ThreadContext::Active) {
988  // If delta is zero, we're just trying to wait for an instruction
989  // boundary. If the CPU is not active, assume we're already at a
990  // boundary without waiting for the CPU to eventually wake up.
991  ev->process();
992  } else {
993  // Here "ticks" aren't simulator ticks which measure time, they're
994  // instructions committed by the CPU.
995  _tc->scheduleInstCountEvent(ev, _tc->getCurrentInstCount() + delta);
996  }
997 }
998 
999 void
1001 {
1002  if (ev->scheduled())
1004 }
1005 
1006 std::map<char, BaseRemoteGDB::GdbCommand> BaseRemoteGDB::commandMap = {
1007  // last signal
1008  { '?', { "KGDB_SIGNAL", &BaseRemoteGDB::cmdSignal } },
1009  // set baud (deprecated)
1010  { 'b', { "KGDB_SET_BAUD", &BaseRemoteGDB::cmdUnsupported } },
1011  // set breakpoint (deprecated)
1012  { 'B', { "KGDB_SET_BREAK", &BaseRemoteGDB::cmdUnsupported } },
1013  // resume
1014  { 'c', { "KGDB_CONT", &BaseRemoteGDB::cmdCont } },
1015  // continue with signal
1016  { 'C', { "KGDB_ASYNC_CONT", &BaseRemoteGDB::cmdAsyncCont } },
1017  // toggle debug flags (deprecated)
1018  { 'd', { "KGDB_DEBUG", &BaseRemoteGDB::cmdUnsupported } },
1019  // detach remote gdb
1020  { 'D', { "KGDB_DETACH", &BaseRemoteGDB::cmdDetach } },
1021  // read general registers
1022  { 'g', { "KGDB_REG_R", &BaseRemoteGDB::cmdRegR } },
1023  // write general registers
1024  { 'G', { "KGDB_REG_W", &BaseRemoteGDB::cmdRegW } },
1025  // set thread
1026  { 'H', { "KGDB_SET_THREAD", &BaseRemoteGDB::cmdSetThread } },
1027  // step a single cycle
1028  { 'i', { "KGDB_CYCLE_STEP", &BaseRemoteGDB::cmdUnsupported } },
1029  // signal then cycle step
1030  { 'I', { "KGDB_SIG_CYCLE_STEP", &BaseRemoteGDB::cmdUnsupported } },
1031  // kill program
1032  { 'k', { "KGDB_KILL", &BaseRemoteGDB::cmdDetach } },
1033  // read memory
1034  { 'm', { "KGDB_MEM_R", &BaseRemoteGDB::cmdMemR } },
1035  // write memory
1036  { 'M', { "KGDB_MEM_W", &BaseRemoteGDB::cmdMemW } },
1037  // read register
1038  { 'p', { "KGDB_READ_REG", &BaseRemoteGDB::cmdUnsupported } },
1039  // write register
1040  { 'P', { "KGDB_SET_REG", &BaseRemoteGDB::cmdUnsupported } },
1041  // query variable
1042  { 'q', { "KGDB_QUERY_VAR", &BaseRemoteGDB::cmdQueryVar } },
1043  // set variable
1044  { 'Q', { "KGDB_SET_VAR", &BaseRemoteGDB::cmdUnsupported } },
1045  // reset system (deprecated)
1046  { 'r', { "KGDB_RESET", &BaseRemoteGDB::cmdUnsupported } },
1047  // step
1048  { 's', { "KGDB_STEP", &BaseRemoteGDB::cmdStep } },
1049  // signal and step
1050  { 'S', { "KGDB_ASYNC_STEP", &BaseRemoteGDB::cmdAsyncStep } },
1051  // find out if the thread is alive
1052  { 'T', { "KGDB_THREAD_ALIVE", &BaseRemoteGDB::cmdIsThreadAlive } },
1053  //multi letter command
1054  { 'v', { "KGDB_MULTI_LETTER", &BaseRemoteGDB::cmdMultiLetter } },
1055  // target exited
1056  { 'W', { "KGDB_TARGET_EXIT", &BaseRemoteGDB::cmdUnsupported } },
1057  // write memory
1058  { 'X', { "KGDB_BINARY_DLOAD", &BaseRemoteGDB::cmdUnsupported } },
1059  // remove breakpoint or watchpoint
1060  { 'z', { "KGDB_CLR_HW_BKPT", &BaseRemoteGDB::cmdClrHwBkpt } },
1061  // insert breakpoint or watchpoint
1062  { 'Z', { "KGDB_SET_HW_BKPT", &BaseRemoteGDB::cmdSetHwBkpt } },
1063  // non-standard RSP extension: dump page table
1064  { '.', { "GET_PAGE_TABLE", &BaseRemoteGDB::cmdDumpPageTable } },
1065 };
1066 
1067 bool
1069 {
1070  return true;
1071 }
1072 
1073 bool
1075 {
1076  DPRINTF(GDBMisc, "Unsupported command: %s\n", ctx.cmd->name);
1077  DDUMP(GDBMisc, ctx.data, ctx.len);
1078  throw Unsupported();
1079 }
1080 
1081 
1082 bool
1084 {
1085  sendTPacket(ctx.type,tc->contextId(),"");
1086  return true;
1087 }
1088 
1089 bool
1091 {
1092  const char *p = ctx.data;
1093  if (ctx.len) {
1094  Addr new_pc = hex2i(&p);
1095  tc->pcState(new_pc);
1096  }
1097  clearSingleStep();
1098  return false;
1099 }
1100 
1101 bool
1103 {
1104  const char *p = ctx.data;
1105  hex2i(&p);
1106  if (*p++ == ';') {
1107  Addr new_pc = hex2i(&p);
1108  tc->pcState(new_pc);
1109  }
1110  clearSingleStep();
1111  return false;
1112 }
1113 
1114 bool
1116 {
1117  detach();
1118  return false;
1119 }
1120 
1121 bool
1123 {
1124  char buf[2 * regCachePtr->size() + 1];
1125  buf[2 * regCachePtr->size()] = '\0';
1126  mem2hex(buf, regCachePtr->data(), regCachePtr->size());
1127  send(buf);
1128  return true;
1129 }
1130 
1131 bool
1133 {
1134  const char *p = ctx.data;
1135  p = hex2mem(regCachePtr->data(), p, regCachePtr->size());
1136  if (p == NULL || *p != '\0')
1137  throw CmdError("E01");
1138 
1140  send("OK");
1141 
1142  return true;
1143 }
1144 
1145 bool
1147 {
1148  const char *p = ctx.data;
1149  char subcommand = *p++;
1150  int tid = 0;
1151  bool all, any;
1152  if (!parseThreadId(&p, all, any, tid))
1153  throw CmdError("E01");
1154 
1155  if (subcommand == 'c') {
1156  // We can only single step or continue all threads at once, since we
1157  // stop time itself and not individual threads.
1158  if (!all)
1159  throw CmdError("E02");
1160  } else if (subcommand == 'g') {
1161  // We don't currently support reading registers, memory, etc, from all
1162  // threads at once. GDB may never ask for this, but if it does we
1163  // should complain.
1164  if (all)
1165  throw CmdError("E03");
1166 
1167  // If GDB doesn't care which thread we're using, keep using the
1168  // current one, otherwise switch.
1169  if (!any && tid != tc->contextId()) {
1170  if (!selectThreadContext(tid))
1171  throw CmdError("E04");
1172  // Line up on an instruction boundary in the new thread.
1173  threadSwitching = true;
1174  scheduleTrapEvent(tid,GDBSignal::ZERO,0,"");
1175  return false;
1176  }
1177  } else {
1178  throw CmdError("E05");
1179  }
1180 
1181  send("OK");
1182  return true;
1183 }
1184 
1185 bool
1187 {
1188  const char *p = ctx.data;
1189  int tid = 0;
1190  bool all, any;
1191  if (!parseThreadId(&p, all, any, tid))
1192  throw CmdError("E01");
1193  if (all)
1194  throw CmdError("E03");
1195  if (threads.find(tid) == threads.end())
1196  throw CmdError("E04");
1197  send("OK");
1198  return true;
1199 }
1200 
1201 bool
1203 {
1204  const char *p = ctx.data;
1205  Addr addr = hex2i(&p);
1206  if (*p++ != ',')
1207  throw CmdError("E02");
1208  size_t len = hex2i(&p);
1209  if (*p != '\0')
1210  throw CmdError("E03");
1211  if (!acc(addr, len))
1212  throw CmdError("E05");
1213 
1214  char buf[len];
1215  if (!read(addr, len, buf))
1216  throw CmdError("E05");
1217 
1218  char temp[2 * len + 1];
1219  temp[2 * len] = '\0';
1220  mem2hex(temp, buf, len);
1221  send(temp);
1222  return true;
1223 }
1224 
1225 bool
1227 {
1228  const char *p = ctx.data;
1229  Addr addr = hex2i(&p);
1230  if (*p++ != ',')
1231  throw CmdError("E06");
1232  size_t len = hex2i(&p);
1233  if (*p++ != ':')
1234  throw CmdError("E07");
1235  if (len * 2 > ctx.len - (p - ctx.data))
1236  throw CmdError("E08");
1237  char buf[len];
1238  p = (char *)hex2mem(buf, p, len);
1239  if (p == NULL)
1240  throw CmdError("E09");
1241  if (!acc(addr, len))
1242  throw CmdError("E0A");
1243  if (!write(addr, len, buf))
1244  throw CmdError("E0B");
1245  send("OK");
1246  return true;
1247 }
1248 
1249 bool
1251 {
1253  new_ctx.type = ctx.type;
1254  strtok(ctx.data,";?");
1255  char* sep = strtok(NULL,";:?");
1256 
1257  int txt_len = (sep != NULL) ? (sep - ctx.data) : strlen(ctx.data);
1258  DPRINTF(GDBMisc, "Multi-letter: %s , len=%i\n", ctx.data,txt_len);
1259  new_ctx.cmdTxt = std::string(ctx.data,txt_len);
1260  new_ctx.data = sep;
1261  new_ctx.len = ctx.len - txt_len;
1262  try {
1263  auto cmd_it = multiLetterMap.find(new_ctx.cmdTxt);
1264  if (cmd_it == multiLetterMap.end()) {
1265  DPRINTF(GDBMisc, "Unknown command: %s\n", new_ctx.cmdTxt);
1266  throw Unsupported();
1267  }
1268  new_ctx.cmd = &(cmd_it->second);
1269 
1270  return (this->*(new_ctx.cmd->func))(new_ctx);
1271  //catching errors: we don't need to catch anything else
1272  //as it will be handled by processCommands
1273  } catch (CmdError &e) {
1274  send(e.error);
1275  }
1276  return false;
1277 }
1278 
1279 std::map<std::string, BaseRemoteGDB::GdbMultiLetterCommand>
1281  { "MustReplyEmpty", { "KGDB_REPLY_EMPTY", &BaseRemoteGDB::cmdReplyEmpty}},
1282  { "Kill", { "KGDB_VKILL", &BaseRemoteGDB::cmdVKill}},
1283 };
1284 
1285 
1286 bool
1288 {
1289  send("");
1290  return true;
1291 }
1292 
1293 bool
1295 {
1296  warn("GDB command for kill received detaching instead");
1297  detach();
1298  return false;
1299 }
1300 
1301 bool
1303 {
1304  DPRINTF(GDBMisc, "Unsupported Multi name command : %s\n",
1305  ctx.cmd->name);
1306  DDUMP(GDBMisc, ctx.data, ctx.len);
1307  throw Unsupported();
1308 }
1309 
1310 namespace {
1311 
1313 splitAt(std::string str, const char * const delim)
1314 {
1315  size_t pos = str.find_first_of(delim);
1316  if (pos == std::string::npos)
1317  return std::pair<std::string, std::string>(str, "");
1318  else
1320  str.substr(0, pos), str.substr(pos + 1));
1321 }
1322 
1323 } // anonymous namespace
1324 
1325 std::map<std::string, BaseRemoteGDB::QuerySetCommand>
1327  { "C", { &BaseRemoteGDB::queryC } },
1328  { "Rcmd", { &BaseRemoteGDB::queryRcmd} },
1329  { "Attached", { &BaseRemoteGDB::queryAttached} },
1330  { "Supported", { &BaseRemoteGDB::querySupported, ";" } },
1331  { "Xfer", { &BaseRemoteGDB::queryXfer } },
1332  { "Symbol", { &BaseRemoteGDB::querySymbol ,":" } },
1333  { "fThreadInfo", { &BaseRemoteGDB::queryFThreadInfo } },
1334  { "sThreadInfo", { &BaseRemoteGDB::querySThreadInfo } },
1335 };
1336 
1337 bool
1339 {
1340  send("QC%x", encodeThreadId(tc->contextId()));
1341  return true;
1342 }
1343 
1344 bool
1346 {
1347  std::ostringstream oss;
1348  // This reply field mandatory. We can receive arbitrarily
1349  // long packets, so we could choose it to be arbitrarily large.
1350  // This is just an arbitrary filler value that seems to work.
1351  oss << "PacketSize=1024";
1352  for (const auto& feature : availableFeatures())
1353  oss << ';' << feature;
1354  send(oss.str());
1355  return true;
1356 }
1357 
1358 bool
1360 {
1361  auto split = splitAt(ctx.args.at(0), ":");
1362  auto object = split.first;
1363 
1364  split = splitAt(split.second, ":");
1365  auto operation = split.first;
1366 
1367  // Only the "features" object and "read"ing are supported currently.
1368  if (object != "features" || operation != "read")
1369  throw Unsupported();
1370 
1371  // Extract the annex name.
1372  split = splitAt(split.second, ":");
1373  auto annex = split.first;
1374 
1375  // Read the contents of the annex.
1376  std::string content;
1377  if (!getXferFeaturesRead(annex, content))
1378  throw CmdError("E00");
1379 
1380  // Extract the offset and length.
1381  split = splitAt(split.second, ",");
1382  auto offset_str = split.first;
1383  auto length_str = split.second;
1384 
1385  const char *offset_ptr = offset_str.c_str();
1386  const char *length_ptr = length_str.c_str();
1387  auto offset = hex2i(&offset_ptr);
1388  auto length = hex2i(&length_ptr);
1389  if (offset_ptr != offset_str.c_str() + offset_str.length() ||
1390  length_ptr != length_str.c_str() + length_str.length()) {
1391  throw CmdError("E00");
1392  }
1393 
1394  std::string encoded;
1395  encodeXferResponse(content, encoded, offset, length);
1396  send(encoded);
1397  return true;
1398 }
1399 bool
1401 {
1402  //The target does not need to look up any (more) symbols.
1403  send("OK");
1404  return true;
1405 }
1406 bool
1408 {
1409  std::string pid="";
1410  if (!ctx.args.empty() && !ctx.args[0].empty()){
1411  pid=ctx.args[0];
1412  }
1413  DPRINTF(GDBMisc, "QAttached : pid=%s\n",pid);
1414  //The remote server is attached to an existing process.
1415  send("1");
1416  return true;
1417 }
1418 
1420 {
1423  public:
1424  MonitorCallEvent(BaseRemoteGDB& gdb,ContextID id,const std::string &_cause,
1425  int code):
1426  GlobalSimLoopExitEvent(_cause,code), gdb(gdb),id(id)
1427  {};
1428  void process() override{
1430  }
1431  void clean() override{
1432  //trapping now
1433  //this is the only point in time when we can call trap
1434  //before any breakpoint triggers
1435  gdb.trap(id,GDBSignal::ZERO,"monitor_return");
1436  delete this;
1437  }
1439  DPRINTF(Event,"MonitorCallEvent destructed\n");;
1440  }
1441 };
1442 
1443 bool
1445  std::string message=hexS2string(ctx.args[0]);
1446  DPRINTF(GDBMisc, "Rcmd Query: %s => %s\n", ctx.args[0],message);
1447  //Tick when = curTick();
1448  new MonitorCallEvent(*this,tc->contextId(),"GDB_MONITOR:"+ message, 0);
1449  return false;
1450 }
1451 
1452 bool
1454 {
1455  threadInfoIdx = 0;
1456  querySThreadInfo(ctx);
1457  return true;
1458 }
1459 
1460 bool
1462 {
1463  if (threadInfoIdx >= threads.size()) {
1464  threadInfoIdx = 0;
1465  send("l");
1466  } else {
1467  auto it = threads.begin();
1468  std::advance(it, threadInfoIdx++);
1469  send("m%x", encodeThreadId(it->second->contextId()));
1470  }
1471  return true;
1472 }
1473 
1474 bool
1476 {
1477  // The query command goes until the first ':', or the end of the string.
1478  std::string s(ctx.data, ctx.len);
1479  auto query_split = splitAt({ ctx.data, (size_t)ctx.len }, ":,");
1480  const auto &query_str = query_split.first;
1481 
1482  // Look up the query command, and report if it isn't found.
1483  auto query_it = queryMap.find(query_str);
1484  if (query_it == queryMap.end()) {
1485  DPRINTF(GDBMisc, "Unknown query %s\n", s);
1486  throw Unsupported();
1487  }
1488 
1489  // If it was found, construct a context.
1490  QuerySetCommand::Context qctx(query_str);
1491 
1492  const auto &query = query_it->second;
1493  auto remaining = std::move(query_split.second);
1494  if (!query.argSep) {
1495  qctx.args.emplace_back(std::move(remaining));
1496  } else {
1497  while (remaining != "") {
1498  auto arg_split = splitAt(remaining, query.argSep);
1499  qctx.args.emplace_back(std::move(arg_split.first));
1500  remaining = std::move(arg_split.second);
1501  }
1502  }
1503  //returning true if the query want to pursue GDB command processing
1504  //false means that the command processing stop until it's trigger again.
1505  return (this->*(query.func))(qctx);
1506 }
1507 
1510 {
1511  return {};
1512 };
1513 
1514 bool
1516  const std::string &annex, std::string &output)
1517 {
1518  return false;
1519 }
1520 
1521 void
1523  const std::string &unencoded, std::string &encoded) const
1524 {
1525  for (const char& c : unencoded) {
1526  if (c == '$' || c == '#' || c == '}' || c == '*') {
1527  encoded += '}';
1528  encoded += c ^ 0x20;
1529  } else {
1530  encoded += c;
1531  }
1532  }
1533 }
1534 
1535 void
1536 BaseRemoteGDB::encodeXferResponse(const std::string &unencoded,
1537  std::string &encoded, size_t offset, size_t unencoded_length) const
1538 {
1539  if (offset + unencoded_length < unencoded.length())
1540  encoded += 'm';
1541  else
1542  encoded += 'l';
1543  encodeBinaryData(unencoded.substr(offset, unencoded_length), encoded);
1544 }
1545 
1546 bool
1548 {
1549  send(tc->getProcessPtr()->pTable->externalize().c_str());
1550  return true;
1551 }
1552 
1553 bool
1555 {
1556  const char *p = ctx.data;
1557  hex2i(&p); // Ignore the subcommand byte.
1558  if (*p++ == ';') {
1559  Addr new_pc = hex2i(&p);
1560  tc->pcState(new_pc);
1561  }
1562  setSingleStep();
1563  return false;
1564 }
1565 
1566 bool
1568 {
1569  if (ctx.len) {
1570  const char *p = ctx.data;
1571  Addr new_pc = hex2i(&p);
1572  tc->pcState(new_pc);
1573  }
1574  setSingleStep();
1575  return false;
1576 }
1577 
1578 bool
1580 {
1581  const char *p = ctx.data;
1582  char sub_cmd = *p++;
1583  if (*p++ != ',')
1584  throw CmdError("E0D");
1585  Addr addr = hex2i(&p);
1586  if (*p++ != ',')
1587  throw CmdError("E0D");
1588  size_t kind = hex2i(&p);
1589 
1590  DPRINTF(GDBMisc, "clear %s, addr=%#x, kind=%d\n",
1591  breakType(sub_cmd), addr, kind);
1592 
1593  switch (sub_cmd) {
1594  case GdbSoftBp:
1595  removeSoftBreak(addr, kind);
1596  break;
1597  case GdbHardBp:
1598  removeHardBreak(addr, kind);
1599  break;
1600  case GdbWriteWp:
1601  case GdbReadWp:
1602  case GdbAccWp:
1603  default: // unknown
1604  throw Unsupported();
1605  }
1606  send("OK");
1607 
1608  return true;
1609 }
1610 
1611 bool
1613 {
1614  const char *p = ctx.data;
1615  char sub_cmd = *p++;
1616  if (*p++ != ',')
1617  throw CmdError("E0D");
1618  Addr addr = hex2i(&p);
1619  if (*p++ != ',')
1620  throw CmdError("E0D");
1621  size_t kind = hex2i(&p);
1622 
1623  DPRINTF(GDBMisc, "set %s, addr=%#x, kind=%d\n",
1624  breakType(sub_cmd), addr, kind);
1625 
1626  switch (sub_cmd) {
1627  case GdbSoftBp:
1628  insertSoftBreak(addr, kind);
1629  break;
1630  case GdbHardBp:
1631  insertHardBreak(addr, kind);
1632  break;
1633  case GdbWriteWp:
1634  case GdbReadWp:
1635  case GdbAccWp:
1636  default: // unknown
1637  throw Unsupported();
1638  }
1639  send("OK");
1640 
1641  return true;
1642 }
1643 
1644 } // namespace gem5
gem5::BaseRemoteGDB::incomingData
void incomingData(int revent)
Definition: remote_gdb.cc:606
gem5::BaseRemoteGDB::hostSocket
const ListenSocket & hostSocket() const
Definition: remote_gdb.cc:448
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:1074
gem5::BaseRemoteGDB::sendMessage
bool sendMessage(std::string message)
Definition: remote_gdb.cc:583
gem5::BaseRemoteGDB::GdbMultiLetterCommand::name
const char *const name
Definition: remote_gdb.hh:373
gem5::ThreadContext::Active
@ Active
Running.
Definition: thread_context.hh:103
gem5::BaseRemoteGDB::cmdVKill
bool cmdVKill(GdbMultiLetterCommand::Context &ctx)
Definition: remote_gdb.cc:1294
gem5::BaseRemoteGDB::scheduleTrapEvent
void scheduleTrapEvent(ContextID id, GDBSignal type, int delta, std::string stopReason)
Definition: remote_gdb.cc:973
gem5::GDBStart
static const char GDBStart
Definition: remote_gdb.cc:166
gem5::BaseRemoteGDB::isAttached
bool isAttached()
Definition: remote_gdb.hh:168
gem5::BaseRemoteGDB::multiLetterMap
static std::map< std::string, GdbMultiLetterCommand > multiLetterMap
Definition: remote_gdb.hh:381
warn
#define warn(...)
Definition: logging.hh:256
gem5::BaseRemoteGDB::cmdDumpPageTable
bool cmdDumpPageTable(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1547
gem5::HardBreakpoint::name
const std::string name() const override
Definition: remote_gdb.cc:187
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::cmdMultiLetter
bool cmdMultiLetter(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1250
gem5::BaseRemoteGDB::HardBreakpoint
friend class HardBreakpoint
Definition: remote_gdb.hh:145
gem5::BaseRemoteGDB::cmdSetThread
bool cmdSetThread(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1146
system.hh
gem5::BaseRemoteGDB::sendOPacket
void sendOPacket(const std::string message)
Definition: remote_gdb.cc:968
gem5::BaseRemoteGDB::querySymbol
bool querySymbol(QuerySetCommand::Context &ctx)
Definition: remote_gdb.cc:1400
gem5::BaseRemoteGDB::cmdMultiUnsupported
bool cmdMultiUnsupported(GdbMultiLetterCommand::Context &ctx)
Definition: remote_gdb.cc:1302
gem5::BaseRemoteGDB::insertSoftBreak
void insertSoftBreak(Addr addr, size_t kind)
Definition: remote_gdb.cc:900
data
const char data[]
Definition: circlebuf.test.cc:48
gem5::BaseRemoteGDB::listen
void listen()
Definition: remote_gdb.cc:415
gem5::BaseRemoteGDB::GdbMultiLetterCommand::func
const Func func
Definition: remote_gdb.hh:374
gem5::ArmISA::fd
Bitfield< 14, 12 > fd
Definition: types.hh:150
gem5::GlobalSimLoopExitEvent::code
int code
Definition: sim_events.hh:60
gem5::BaseRemoteGDB::GdbCommand::name
const char *const name
Definition: remote_gdb.hh:351
gem5::BaseRemoteGDB::gdbRegs
virtual BaseGdbRegCache * gdbRegs()=0
sim_events.hh
warn_once
#define warn_once(...)
Definition: logging.hh:260
gem5::BaseRemoteGDB::cmdRegR
bool cmdRegR(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1122
gem5::RiscvISA::all
Bitfield< 31, 0 > all
Definition: types.hh:77
gem5::output
static void output(const char *filename)
Definition: debug.cc:60
gem5::BaseRemoteGDB::GdbMultiLetterCommand::Context::data
char * data
Definition: remote_gdb.hh:367
gem5::BaseRemoteGDB::cmdIsThreadAlive
bool cmdIsThreadAlive(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1186
gem5::BaseRemoteGDB::encodeBinaryData
void encodeBinaryData(const std::string &unencoded, std::string &encoded) const
Definition: remote_gdb.cc:1522
remote_gdb.hh
gem5::BaseRemoteGDB::putbyte
void putbyte(uint8_t b)
Definition: remote_gdb.cc:674
gem5::MonitorCallEvent
Definition: remote_gdb.cc:1419
gem5::pollQueue
PollQueue pollQueue
Definition: pollevent.cc:55
gem5::BaseRemoteGDB::scheduleInstCommitEvent
void scheduleInstCommitEvent(Event *ev, int delta, ThreadContext *_tc)
Schedule an event which will be triggered "delta" instructions later.
Definition: remote_gdb.cc:985
gem5::ThreadContext::pcState
virtual const PCStateBase & pcState() const =0
gem5::BaseRemoteGDB::fd
int fd
Definition: remote_gdb.hh:237
gem5::ListenSocketConfig
Definition: socket.hh:114
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::removeHardBreak
void removeHardBreak(Addr addr, size_t kind)
Definition: remote_gdb.cc:933
gem5::ListenSocket
Definition: socket.hh:46
gem5::BaseRemoteGDB::commandMap
static std::map< char, GdbCommand > commandMap
Definition: remote_gdb.hh:357
translating_port_proxy.hh
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:918
gem5::MonitorCallEvent::id
ContextID id
Definition: remote_gdb.cc:1422
gem5::MonitorCallEvent::process
void process() override
Definition: remote_gdb.cc:1428
gem5::GlobalSimLoopExitEvent
Definition: sim_events.hh:55
gem5::ThreadContext::contextId
virtual ContextID contextId() const =0
gem5::BaseRemoteGDB::acc
virtual bool acc(Addr addr, size_t len)=0
gem5::BaseRemoteGDB::read
bool read(Addr vaddr, size_t size, char *data)
Definition: remote_gdb.cc:839
std::vector< char >
gem5::BaseRemoteGDB::singleStepEvent
MemberEventWrapper<&BaseRemoteGDB::singleStep > singleStepEvent
Definition: remote_gdb.hh:310
gem5::BaseRemoteGDB::GdbMultiLetterCommand::Context
Definition: remote_gdb.hh:362
gem5::BaseRemoteGDB::connectEvent
MemberEventWrapper<&BaseRemoteGDB::connect > connectEvent
Definition: remote_gdb.hh:276
gem5::VegaISA::r
Bitfield< 5 > r
Definition: pagetable.hh:60
gem5::BaseRemoteGDB::cmdMemW
bool cmdMemW(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1226
gem5::BaseRemoteGDB::GdbMultiLetterCommand::Context::len
int len
Definition: remote_gdb.hh:368
gem5::BaseRemoteGDB::GdbCommand::Context::data
char * data
Definition: remote_gdb.hh:345
gem5::ArmISA::i
Bitfield< 7 > i
Definition: misc_types.hh:67
gem5::BaseRemoteGDB::sys
System * sys
Definition: remote_gdb.hh:269
gem5::MonitorCallEvent::gdb
BaseRemoteGDB & gdb
Definition: remote_gdb.cc:1421
gem5::BaseRemoteGDB::cmdStep
bool cmdStep(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1567
gem5::BaseRemoteGDB::TrapEvent::stopReason
void stopReason(std::string s)
Definition: remote_gdb.hh:292
gem5::PollQueue::remove
void remove(PollEvent *event)
Definition: pollevent.cc:139
gem5::ListenSocketConfig::build
ListenSocketPtr build(const std::string &name) const
Definition: socket.hh:123
gem5::GDBEnd
static const char GDBEnd
Definition: remote_gdb.cc:167
gem5::BaseRemoteGDB::GdbCommand::Context::type
GDBSignal type
Definition: remote_gdb.hh:344
gem5::BaseRemoteGDB::sendTPacket
void sendTPacket(GDBSignal sig, ContextID id, const std::string &stopReason)
Definition: remote_gdb.cc:952
gem5::BaseRemoteGDB::queryXfer
bool queryXfer(QuerySetCommand::Context &ctx)
Definition: remote_gdb.cc:1359
gem5::ThreadContext::status
virtual Status status() const =0
gem5::HardBreakpoint
Definition: remote_gdb.cc:171
gem5::BaseRemoteGDB::BaseRemoteGDB
BaseRemoteGDB(System *system, ListenSocketConfig _listen_config)
Interface to other parts of the simulator.
Definition: remote_gdb.cc:393
gem5::BaseRemoteGDB::queryC
bool queryC(QuerySetCommand::Context &ctx)
Definition: remote_gdb.cc:1338
gem5::BaseRemoteGDB::GdbCommand::Context::cmd
const GdbCommand * cmd
Definition: remote_gdb.hh:342
gem5::TranslatingPortProxy
This proxy attempts to translate virtual addresses using the TLBs.
Definition: translating_port_proxy.hh:60
gem5::BaseRemoteGDB::queryRcmd
bool queryRcmd(QuerySetCommand::Context &ctx)
Definition: remote_gdb.cc:1444
gem5::BaseRemoteGDB::attach
void attach(int fd)
Definition: remote_gdb.cc:456
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:232
gem5::BaseRemoteGDB::GdbCommand::func
const Func func
Definition: remote_gdb.hh:352
gem5::VegaISA::c
Bitfield< 2 > c
Definition: pagetable.hh:63
DPRINTFNR
#define DPRINTFNR(...)
Definition: trace.hh:245
gem5::BaseRemoteGDB::encodeXferResponse
void encodeXferResponse(const std::string &unencoded, std::string &encoded, size_t offset, size_t unencoded_length) const
Definition: remote_gdb.cc:1536
gem5::System
Definition: system.hh:74
gem5::BaseRemoteGDB::availableFeatures
virtual std::vector< std::string > availableFeatures() const
Definition: remote_gdb.cc:1509
gem5::ArmISA::b
Bitfield< 7 > b
Definition: misc_types.hh:438
gem5::BaseRemoteGDB::incomingConnectionEvent
IncomingConnectionEvent * incomingConnectionEvent
Definition: remote_gdb.hh:231
gem5::ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:88
gem5::BaseRemoteGDB::writeBlob
virtual bool writeBlob(Addr vaddr, size_t size, const char *data)
Definition: remote_gdb.cc:827
gem5::HardBreakpoint::gdb
BaseRemoteGDB * gdb
Definition: remote_gdb.cc:174
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::GdbMultiLetterCommand::Context::cmd
const GdbMultiLetterCommand * cmd
Definition: remote_gdb.hh:364
gem5::BaseRemoteGDB::tc
ThreadContext * tc
Definition: remote_gdb.hh:272
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:210
gem5::Event
Definition: eventq.hh:254
gem5::BaseRemoteGDB::cmdSignal
bool cmdSignal(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1083
gem5::Process::pTable
EmulationPageTable * pTable
Definition: process.hh:184
gem5::HardBreakpoint::process
void process(ThreadContext *tc) override
Definition: remote_gdb.cc:190
gem5::PCEvent
Definition: pc_event.hh:45
gem5::BaseRemoteGDB::setSingleStep
void setSingleStep()
Definition: remote_gdb.cc:893
gem5::Event::process
virtual void process()=0
gem5::BaseRemoteGDB::name
std::string name()
Definition: remote_gdb.cc:409
port_proxy.hh
gem5::HardBreakpoint::HardBreakpoint
HardBreakpoint(BaseRemoteGDB *_gdb, PCEventScope *s, Addr pc)
Definition: remote_gdb.cc:180
process.hh
len
uint16_t len
Definition: helpers.cc:62
gem5::BaseRemoteGDB::cmdAsyncCont
bool cmdAsyncCont(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1102
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::MonitorCallEvent::MonitorCallEvent
MonitorCallEvent(BaseRemoteGDB &gdb, ContextID id, const std::string &_cause, int code)
Definition: remote_gdb.cc:1424
gem5::GDBGoodP
static const char GDBGoodP
Definition: remote_gdb.cc:168
gem5::BaseRemoteGDB::queryAttached
bool queryAttached(QuerySetCommand::Context &ctx)
Definition: remote_gdb.cc:1407
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
static_inst.hh
gem5::PollQueue::schedule
void schedule(PollEvent *event)
Definition: pollevent.cc:159
gem5::BaseRemoteGDB::listener
ListenSocketPtr listener
Definition: remote_gdb.hh:234
gem5::BaseRemoteGDB::querySupported
bool querySupported(QuerySetCommand::Context &ctx)
Definition: remote_gdb.cc:1345
gem5::BaseRemoteGDB::trapEvent
gem5::BaseRemoteGDB::TrapEvent trapEvent
gem5::MonitorCallEvent::~MonitorCallEvent
~MonitorCallEvent()
Definition: remote_gdb.cc:1438
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::BaseRemoteGDB::QuerySetCommand::Context
Definition: remote_gdb.hh:411
std::pair
STL pair class.
Definition: stl.hh:58
gem5::GlobalSimLoopExitEvent::process
virtual void process()
Definition: sim_events.cc:80
gem5::BaseRemoteGDB::querySThreadInfo
bool querySThreadInfo(QuerySetCommand::Context &ctx)
Definition: remote_gdb.cc:1461
gem5::BaseRemoteGDB::replaceThreadContext
void replaceThreadContext(ThreadContext *tc)
Definition: remote_gdb.hh:54
gem5::BaseRemoteGDB::cmdRegW
bool cmdRegW(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1132
gem5::ListenSocket::allDisabled
static bool allDisabled()
Definition: socket.cc:90
gem5::BaseRemoteGDB::getXferFeaturesRead
virtual bool getXferFeaturesRead(const std::string &annex, std::string &output)
Get an XML target description.
Definition: remote_gdb.cc:1515
gem5::Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
gem5::HardBreakpoint::refcount
int refcount
Definition: remote_gdb.cc:177
gem5::BaseRemoteGDB::GdbMultiLetterCommand::Context::type
GDBSignal type
Definition: remote_gdb.hh:366
gem5::BaseRemoteGDB::removeSoftBreak
void removeSoftBreak(Addr addr, size_t kind)
Definition: remote_gdb.cc:909
gem5::BaseRemoteGDB::IncomingDataEvent
SocketEvent<&BaseRemoteGDB::incomingData > IncomingDataEvent
Definition: remote_gdb.hh:226
gem5::BaseRemoteGDB::clearSingleStep
void clearSingleStep()
Definition: remote_gdb.cc:887
warning
const char * warning
Definition: remote_gdb.cc:204
gem5::BaseRemoteGDB::write
bool write(Addr vaddr, size_t size, const char *data)
Definition: remote_gdb.cc:864
gem5::BaseRemoteGDB::queryFThreadInfo
bool queryFThreadInfo(QuerySetCommand::Context &ctx)
Definition: remote_gdb.cc:1453
DDUMP
#define DDUMP(x, data, count)
DPRINTF is a debugging trace facility that allows one to selectively enable tracing statements.
Definition: trace.hh:204
gem5::BaseRemoteGDB::detach
void detach()
Definition: remote_gdb.cc:481
gem5::BaseRemoteGDB::TrapEvent::id
void id(ContextID id)
Definition: remote_gdb.hh:293
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:224
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:274
gem5::BaseRemoteGDB::disconnectEvent
MemberEventWrapper<&BaseRemoteGDB::detach > disconnectEvent
Definition: remote_gdb.hh:277
gem5::BaseRemoteGDB::GdbCommand::Context
Definition: remote_gdb.hh:340
gem5::BaseRemoteGDB::processCommands
void processCommands(GDBSignal sig=GDBSignal::ZERO)
Definition: remote_gdb.cc:767
gem5::BaseRemoteGDB::selectThreadContext
bool selectThreadContext(ContextID id)
Definition: remote_gdb.cc:529
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:214
gem5::BaseRemoteGDB::GdbMultiLetterCommand::Context::cmdTxt
std::string cmdTxt
Definition: remote_gdb.hh:365
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:1579
gem5::BaseRemoteGDB::cmdSetHwBkpt
bool cmdSetHwBkpt(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1612
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:736
base.hh
gem5::ThreadContext::descheduleInstCountEvent
virtual void descheduleInstCountEvent(Event *event)=0
gem5::ArmISA::n
Bitfield< 31 > n
Definition: misc_types.hh:513
gem5::BaseRemoteGDB::descheduleInstCommitEvent
void descheduleInstCommitEvent(Event *ev)
Deschedule an instruction count based event.
Definition: remote_gdb.cc:1000
gem5::BaseRemoteGDB::threadSwitching
bool threadSwitching
Definition: remote_gdb.hh:267
gem5::BaseRemoteGDB::cmdReplyEmpty
bool cmdReplyEmpty(GdbMultiLetterCommand::Context &ctx)
Definition: remote_gdb.cc:1287
gem5::BaseRemoteGDB::queryMap
static std::map< std::string, QuerySetCommand > queryMap
Definition: remote_gdb.hh:429
gem5::BaseRemoteGDB::recv
void recv(std::vector< char > &bp)
Definition: remote_gdb.cc:684
gem5::BaseRemoteGDB::cmdDetach
bool cmdDetach(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1115
gem5::ContextID
int ContextID
Globally unique thread context ID.
Definition: types.hh:239
gem5::BaseRemoteGDB::addThreadContext
void addThreadContext(ThreadContext *_tc)
Definition: remote_gdb.cc:506
gem5::BaseRemoteGDB::QuerySetCommand::Context::args
std::vector< std::string > args
Definition: remote_gdb.hh:414
logging.hh
gem5::BaseRemoteGDB::cmdMemR
bool cmdMemR(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1202
gem5::BaseRemoteGDB::~BaseRemoteGDB
virtual ~BaseRemoteGDB()
Definition: remote_gdb.hh:57
gem5::ArmISA::id
Bitfield< 33 > id
Definition: misc_types.hh:305
gem5::BaseRemoteGDB::sendSPacket
void sendSPacket(GDBSignal sig)
Definition: remote_gdb.cc:964
se_translating_port_proxy.hh
trace.hh
gem5::BaseRemoteGDB::singleStep
void singleStep()
Definition: remote_gdb.cc:879
gem5::BaseRemoteGDB::incomingConnection
void incomingConnection(int revent)
Definition: remote_gdb.cc:593
gem5::BaseRemoteGDB
Definition: remote_gdb.hh:48
DPRINTFN
#define DPRINTFN(...)
Definition: trace.hh:238
gem5::MipsISA::vaddr
vaddr
Definition: pra_constants.hh:278
gem5::BaseRemoteGDB::GdbCommand::Context::cmdByte
char cmdByte
Definition: remote_gdb.hh:343
gem5::PCEvent::evpc
Addr evpc
Definition: pc_event.hh:50
intmath.hh
gem5::BaseRemoteGDB::cmdCont
bool cmdCont(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1090
gem5::BaseRemoteGDB::threads
std::map< ContextID, ThreadContext * > threads
Definition: remote_gdb.hh:271
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: gpu_translation_state.hh:37
gem5::BaseRemoteGDB::try_getbyte
bool try_getbyte(uint8_t *c, int timeout=-1)
Definition: remote_gdb.cc:630
gem5::BaseRemoteGDB::connect
void connect()
Definition: remote_gdb.cc:430
gem5::BaseRemoteGDB::TrapEvent::type
void type(GDBSignal t)
Definition: remote_gdb.hh:291
gem5::BaseRemoteGDB::readBlob
virtual bool readBlob(Addr vaddr, size_t size, char *data)
Definition: remote_gdb.cc:816
gem5::BaseRemoteGDB::cmdAsyncStep
bool cmdAsyncStep(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1554
gem5::BaseRemoteGDB::attached
bool attached
Definition: remote_gdb.hh:266
gem5::BaseRemoteGDB::threadInfoIdx
size_t threadInfoIdx
Definition: remote_gdb.hh:438
gem5::BaseRemoteGDB::cmdQueryVar
bool cmdQueryVar(GdbCommand::Context &ctx)
Definition: remote_gdb.cc:1475
gem5::GDBBadP
static const char GDBBadP
Definition: remote_gdb.cc:169
gem5::PCEventScope
Definition: pc_event.hh:67
thread_context.hh
gem5::BaseRemoteGDB::GdbCommand::Context::len
int len
Definition: remote_gdb.hh:346
gem5::Event::scheduled
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:458
gem5::MonitorCallEvent::clean
void clean() override
Definition: remote_gdb.cc:1431
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:188
gem5::X86ISA::addr
Bitfield< 3 > addr
Definition: types.hh:84
gem5::BaseRemoteGDB::getbyte
uint8_t getbyte()
Definition: remote_gdb.cc:622
error
std::string error
Definition: remote_gdb.cc:212
gem5::BaseRemoteGDB::checkBpKind
virtual bool checkBpKind(size_t kind)
Definition: remote_gdb.cc:1068

Generated on Sun Jul 30 2023 01:56:47 for gem5 by doxygen 1.8.17