gem5  v22.1.0.0
remote_gdb.cc
Go to the documentation of this file.
1 /*
2  * Copyright 2015 LabWare
3  * Copyright 2014 Google, Inc.
4  * Copyright (c) 2007 The Hewlett-Packard Development Company
5  * All rights reserved.
6  *
7  * The license below extends only to copyright in the software and shall
8  * not be construed as granting a license to any other intellectual
9  * property including but not limited to intellectual property relating
10  * to a hardware implementation of the functionality of the software
11  * licensed hereunder. You may use the software subject to the license
12  * terms below provided that you ensure that this notice is replicated
13  * unmodified and in its entirety in all distributions of the software,
14  * modified or unmodified, in source code or in binary form.
15  *
16  * Redistribution and use in source and binary forms, with or without
17  * modification, are permitted provided that the following conditions are
18  * met: redistributions of source code must retain the above copyright
19  * notice, this list of conditions and the following disclaimer;
20  * redistributions in binary form must reproduce the above copyright
21  * notice, this list of conditions and the following disclaimer in the
22  * documentation and/or other materials provided with the distribution;
23  * neither the name of the copyright holders nor the names of its
24  * contributors may be used to endorse or promote products derived from
25  * this software without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38  */
39 
40 #include "arch/x86/remote_gdb.hh"
41 
42 #include <sys/signal.h>
43 #include <unistd.h>
44 
45 #include <string>
46 
47 #include "arch/x86/mmu.hh"
49 #include "arch/x86/process.hh"
50 #include "arch/x86/regs/int.hh"
51 #include "arch/x86/regs/misc.hh"
53 #include "base/logging.hh"
54 #include "base/remote_gdb.hh"
55 #include "base/socket.hh"
56 #include "base/trace.hh"
57 #include "cpu/base.hh"
58 #include "cpu/thread_context.hh"
59 #include "debug/GDBAcc.hh"
60 #include "mem/page_table.hh"
61 #include "sim/full_system.hh"
62 #include "sim/workload.hh"
63 
64 namespace gem5
65 {
66 
67 using namespace X86ISA;
68 
69 RemoteGDB::RemoteGDB(System *_system, int _port) :
70  BaseRemoteGDB(_system, _port), regCache32(this), regCache64(this)
71 {}
72 
73 bool
74 RemoteGDB::acc(Addr va, size_t len)
75 {
76  if (FullSystem) {
77  Walker *walker = dynamic_cast<MMU *>(
78  context()->getMMUPtr())->getDataWalker();
79  unsigned logBytes;
80  Fault fault = walker->startFunctional(context(), va, logBytes,
81  BaseMMU::Read);
82  if (fault != NoFault)
83  return false;
84 
85  Addr endVa = va + len - 1;
86  if ((va & ~mask(logBytes)) == (endVa & ~mask(logBytes)))
87  return true;
88 
89  fault = walker->startFunctional(context(), endVa, logBytes,
90  BaseMMU::Read);
91  return fault == NoFault;
92  } else {
93  return context()->getProcessPtr()->pTable->lookup(va) != nullptr;
94  }
95 }
96 
97 BaseGdbRegCache*
98 RemoteGDB::gdbRegs()
99 {
100  // First, try to figure out which type of register cache to return based
101  // on the architecture reported by the workload.
102  if (system()->workload) {
103  auto arch = system()->workload->getArch();
104  if (arch == loader::X86_64) {
105  return &regCache64;
106  } else if (arch == loader::I386) {
107  return &regCache32;
108  } else if (arch != loader::UnknownArch) {
109  panic("Unrecognized workload arch %s.",
110  loader::archToString(arch));
111  }
112  }
113 
114  // If that didn't work, decide based on the current mode of the context.
115  HandyM5Reg m5reg = context()->readMiscRegNoEffect(misc_reg::M5Reg);
116  if (m5reg.submode == SixtyFourBitMode)
117  return &regCache64;
118  else
119  return &regCache32;
120 }
121 
122 
123 
124 void
125 RemoteGDB::AMD64GdbRegCache::getRegs(ThreadContext *context)
126 {
127  DPRINTF(GDBAcc, "getRegs in remotegdb \n");
128  r.rax = context->getReg(int_reg::Rax);
129  r.rbx = context->getReg(int_reg::Rbx);
130  r.rcx = context->getReg(int_reg::Rcx);
131  r.rdx = context->getReg(int_reg::Rdx);
132  r.rsi = context->getReg(int_reg::Rsi);
133  r.rdi = context->getReg(int_reg::Rdi);
134  r.rbp = context->getReg(int_reg::Rbp);
135  r.rsp = context->getReg(int_reg::Rsp);
136  r.r8 = context->getReg(int_reg::R8);
137  r.r9 = context->getReg(int_reg::R9);
138  r.r10 = context->getReg(int_reg::R10);
139  r.r11 = context->getReg(int_reg::R11);
140  r.r12 = context->getReg(int_reg::R12);
141  r.r13 = context->getReg(int_reg::R13);
142  r.r14 = context->getReg(int_reg::R14);
143  r.r15 = context->getReg(int_reg::R15);
144  r.rip = context->pcState().instAddr();
145  r.eflags = context->readMiscRegNoEffect(misc_reg::Rflags);
146  r.cs = context->readMiscRegNoEffect(misc_reg::Cs);
147  r.ss = context->readMiscRegNoEffect(misc_reg::Ss);
148  r.ds = context->readMiscRegNoEffect(misc_reg::Ds);
149  r.es = context->readMiscRegNoEffect(misc_reg::Es);
150  r.fs = context->readMiscRegNoEffect(misc_reg::Fs);
151  r.gs = context->readMiscRegNoEffect(misc_reg::Gs);
152 }
153 
154 void
155 RemoteGDB::X86GdbRegCache::getRegs(ThreadContext *context)
156 {
157  DPRINTF(GDBAcc, "getRegs in remotegdb \n");
158  r.eax = context->getReg(int_reg::Rax);
159  r.ecx = context->getReg(int_reg::Rcx);
160  r.edx = context->getReg(int_reg::Rdx);
161  r.ebx = context->getReg(int_reg::Rbx);
162  r.esp = context->getReg(int_reg::Rsp);
163  r.ebp = context->getReg(int_reg::Rbp);
164  r.esi = context->getReg(int_reg::Rsi);
165  r.edi = context->getReg(int_reg::Rdi);
166  r.eip = context->pcState().instAddr();
167  r.eflags = context->readMiscRegNoEffect(misc_reg::Rflags);
168  r.cs = context->readMiscRegNoEffect(misc_reg::Cs);
169  r.ss = context->readMiscRegNoEffect(misc_reg::Ss);
170  r.ds = context->readMiscRegNoEffect(misc_reg::Ds);
171  r.es = context->readMiscRegNoEffect(misc_reg::Es);
172  r.fs = context->readMiscRegNoEffect(misc_reg::Fs);
173  r.gs = context->readMiscRegNoEffect(misc_reg::Gs);
174 }
175 
176 void
177 RemoteGDB::AMD64GdbRegCache::setRegs(ThreadContext *context) const
178 {
179  DPRINTF(GDBAcc, "setRegs in remotegdb \n");
180  context->setReg(int_reg::Rax, r.rax);
181  context->setReg(int_reg::Rbx, r.rbx);
182  context->setReg(int_reg::Rcx, r.rcx);
183  context->setReg(int_reg::Rdx, r.rdx);
184  context->setReg(int_reg::Rsi, r.rsi);
185  context->setReg(int_reg::Rdi, r.rdi);
186  context->setReg(int_reg::Rbp, r.rbp);
187  context->setReg(int_reg::Rsp, r.rsp);
188  context->setReg(int_reg::R8, r.r8);
189  context->setReg(int_reg::R9, r.r9);
190  context->setReg(int_reg::R10, r.r10);
191  context->setReg(int_reg::R11, r.r11);
192  context->setReg(int_reg::R12, r.r12);
193  context->setReg(int_reg::R13, r.r13);
194  context->setReg(int_reg::R14, r.r14);
195  context->setReg(int_reg::R15, r.r15);
196  context->pcState(r.rip);
197  context->setMiscReg(misc_reg::Rflags, r.eflags);
198  if (r.cs != context->readMiscRegNoEffect(misc_reg::Cs))
199  warn("Remote gdb: Ignoring update to CS.\n");
200  if (r.ss != context->readMiscRegNoEffect(misc_reg::Ss))
201  warn("Remote gdb: Ignoring update to SS.\n");
202  if (r.ds != context->readMiscRegNoEffect(misc_reg::Ds))
203  warn("Remote gdb: Ignoring update to DS.\n");
204  if (r.es != context->readMiscRegNoEffect(misc_reg::Es))
205  warn("Remote gdb: Ignoring update to ES.\n");
206  if (r.fs != context->readMiscRegNoEffect(misc_reg::Fs))
207  warn("Remote gdb: Ignoring update to FS.\n");
208  if (r.gs != context->readMiscRegNoEffect(misc_reg::Gs))
209  warn("Remote gdb: Ignoring update to GS.\n");
210 }
211 
212 void
213 RemoteGDB::X86GdbRegCache::setRegs(ThreadContext *context) const
214 {
215  DPRINTF(GDBAcc, "setRegs in remotegdb \n");
216  context->setReg(int_reg::Rax, r.eax);
217  context->setReg(int_reg::Rcx, r.ecx);
218  context->setReg(int_reg::Rdx, r.edx);
219  context->setReg(int_reg::Rbx, r.ebx);
220  context->setReg(int_reg::Rsp, r.esp);
221  context->setReg(int_reg::Rbp, r.ebp);
222  context->setReg(int_reg::Rsi, r.esi);
223  context->setReg(int_reg::Rdi, r.edi);
224  context->pcState(r.eip);
225  context->setMiscReg(misc_reg::Rflags, r.eflags);
226  if (r.cs != context->readMiscRegNoEffect(misc_reg::Cs))
227  warn("Remote gdb: Ignoring update to CS.\n");
228  if (r.ss != context->readMiscRegNoEffect(misc_reg::Ss))
229  warn("Remote gdb: Ignoring update to SS.\n");
230  if (r.ds != context->readMiscRegNoEffect(misc_reg::Ds))
231  warn("Remote gdb: Ignoring update to DS.\n");
232  if (r.es != context->readMiscRegNoEffect(misc_reg::Es))
233  warn("Remote gdb: Ignoring update to ES.\n");
234  if (r.fs != context->readMiscRegNoEffect(misc_reg::Fs))
235  warn("Remote gdb: Ignoring update to FS.\n");
236  if (r.gs != context->readMiscRegNoEffect(misc_reg::Gs))
237  warn("Remote gdb: Ignoring update to GS.\n");
238 }
239 
240 } // namespace gem5
#define DPRINTF(x,...)
Definition: trace.hh:186
Addr instAddr() const
Returns the memory address of the instruction this PC points to.
Definition: pcstate.hh:107
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual void setMiscReg(RegIndex misc_reg, RegVal val)=0
virtual RegVal getReg(const RegId &reg) const
virtual const PCStateBase & pcState() const =0
virtual void setReg(const RegId &reg, RegVal val)
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
RemoteGDB(System *system, int _port)
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
uint16_t len
Definition: helpers.cc:62
#define warn(...)
Definition: logging.hh:246
constexpr RegId R9
Definition: int.hh:195
constexpr RegId R12
Definition: int.hh:198
constexpr RegId R8
Definition: int.hh:194
constexpr RegId R11
Definition: int.hh:197
constexpr RegId R14
Definition: int.hh:200
constexpr RegId R10
Definition: int.hh:196
constexpr RegId R15
Definition: int.hh:201
constexpr RegId R13
Definition: int.hh:199
Bitfield< 3, 0 > mask
Definition: pcstate.hh:63
Bitfield< 8 > va
Definition: misc_types.hh:282
Bitfield< 5 > r
Definition: pagetable.hh:60
constexpr RegId Rbx
Definition: int.hh:135
constexpr RegId Rsi
Definition: int.hh:138
constexpr RegId Rax
Definition: int.hh:132
constexpr RegId Rdx
Definition: int.hh:134
constexpr RegId Rsp
Definition: int.hh:136
constexpr RegId Rdi
Definition: int.hh:139
constexpr RegId Rbp
Definition: int.hh:137
constexpr RegId Rcx
Definition: int.hh:133
Bitfield< 15 > system
Definition: misc.hh:1004
@ SixtyFourBitMode
Definition: types.hh:204
const char * archToString(Arch arch)
Definition: object_file.cc:58
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
std::shared_ptr< FaultBase > Fault
Definition: types.hh:248
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:220
constexpr decltype(nullptr) NoFault
Definition: types.hh:253
Declarations of a non-full system Page Table.

Generated on Wed Dec 21 2022 10:22:25 for gem5 by doxygen 1.9.1