gem5  v20.0.0.2
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
stacktrace.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2004-2005 The Regents of The University of Michigan
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met: redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer;
9  * redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution;
12  * neither the name of the copyright holders nor the names of its
13  * contributors may be used to endorse or promote products derived from
14  * this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include "arch/mips/stacktrace.hh"
30 
31 #include <string>
32 
33 #include "arch/mips/isa_traits.hh"
34 #include "base/bitfield.hh"
35 #include "base/trace.hh"
36 #include "cpu/base.hh"
37 #include "cpu/thread_context.hh"
38 #include "mem/port_proxy.hh"
39 #include "sim/system.hh"
40 
41 using namespace MipsISA;
42 
44 {}
45 
46 Addr
48 {
49  Addr base = ksp & ~0x3fff;
50  if (base == ULL(0xfffffc0000000000))
51  return 0;
52 
53  Addr tsk;
54 
55  PortProxy &vp = tc->getVirtProxy();
56  tsk = vp.read<Addr>(base + task_off, GuestByteOrder);
57 
58  return tsk;
59 }
60 
61 int
63 {
64  Addr task = this->task(ksp);
65  if (!task)
66  return -1;
67 
68  uint16_t pd;
69 
70  PortProxy &vp = tc->getVirtProxy();
71  pd = vp.read<uint16_t>(task + pid_off, GuestByteOrder);
72 
73  return pd;
74 }
75 
76 std::string
78 {
79  Addr task = this->task(ksp);
80  if (!task)
81  return "console";
82 
83  char comm[256];
84  tc->getVirtProxy().readString(comm, task + name_off, sizeof(comm));
85  if (!comm[0])
86  return "startup";
87 
88  return comm;
89 }
90 
92  : tc(0), stack(64)
93 {
94 }
95 
97  : tc(0), stack(64)
98 {
99  trace(_tc, inst);
100 }
101 
103 {
104 }
105 
106 void
107 StackTrace::trace(ThreadContext *_tc, bool is_call)
108 {
109  tc = _tc;
110  bool usermode = 0;
111 
112  if (usermode) {
113  stack.push_back(user);
114  return;
115  }
116 }
117 
118 bool
120 {
121  return false;
122 }
123 
124 bool
126 {
127  // lda $sp, -disp($sp)
128  //
129  // Opcode<31:26> == 0x08
130  // RA<25:21> == 30
131  // RB<20:16> == 30
132  // Disp<15:0>
133  const MachInst mem_mask = 0xffff0000;
134  const MachInst lda_pattern = 0x23de0000;
135  const MachInst lda_disp_mask = 0x0000ffff;
136 
137  // subq $sp, disp, $sp
138  // addq $sp, disp, $sp
139  //
140  // Opcode<31:26> == 0x10
141  // RA<25:21> == 30
142  // Lit<20:13>
143  // One<12> = 1
144  // Func<11:5> == 0x20 (addq)
145  // Func<11:5> == 0x29 (subq)
146  // RC<4:0> == 30
147  const MachInst intop_mask = 0xffe01fff;
148  const MachInst addq_pattern = 0x43c0141e;
149  const MachInst subq_pattern = 0x43c0153e;
150  const MachInst intop_disp_mask = 0x001fe000;
151  const int intop_disp_shift = 13;
152 
153  if ((inst & mem_mask) == lda_pattern)
154  disp = -sext<16>(inst & lda_disp_mask);
155  else if ((inst & intop_mask) == addq_pattern)
156  disp = -int((inst & intop_disp_mask) >> intop_disp_shift);
157  else if ((inst & intop_mask) == subq_pattern)
158  disp = int((inst & intop_disp_mask) >> intop_disp_shift);
159  else
160  return false;
161 
162  return true;
163 }
164 
165 bool
166 StackTrace::decodeSave(MachInst inst, int &reg, int &disp)
167 {
168  // lda $stq, disp($sp)
169  //
170  // Opcode<31:26> == 0x08
171  // RA<25:21> == ?
172  // RB<20:16> == 30
173  // Disp<15:0>
174  const MachInst stq_mask = 0xfc1f0000;
175  const MachInst stq_pattern = 0xb41e0000;
176  const MachInst stq_disp_mask = 0x0000ffff;
177  const MachInst reg_mask = 0x03e00000;
178  const int reg_shift = 21;
179 
180  if ((inst & stq_mask) == stq_pattern) {
181  reg = (inst & reg_mask) >> reg_shift;
182  disp = sext<16>(inst & stq_disp_mask);
183  } else {
184  return false;
185  }
186 
187  return true;
188 }
189 
190 /*
191  * Decode the function prologue for the function we're in, and note
192  * which registers are stored where, and how large the stack frame is.
193  */
194 bool
196  int &size, Addr &ra)
197 {
198  size = 0;
199  ra = 0;
200 
201  for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) {
202  MachInst inst = tc->getVirtProxy().read<MachInst>(pc);
203 
204  int reg, disp;
205  if (decodeStack(inst, disp)) {
206  if (size) {
207  return true;
208  }
209  size += disp;
210  } else if (decodeSave(inst, reg, disp)) {
211  if (!ra && reg == ReturnAddressReg) {
212  ra = tc->getVirtProxy().read<Addr>(sp + disp);
213  if (!ra) {
214  return false;
215  }
216  }
217  }
218  }
219 
220  return true;
221 }
222 
223 #if TRACING_ON
224 void
226 {
227  panic("Stack trace dump not implemented.\n");
228 }
229 #endif
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:163
Bitfield< 5, 3 > reg
Definition: types.hh:87
ProcessInfo(ThreadContext *_tc)
Definition: stacktrace.cc:43
ip6_addr_t addr
Definition: inet.hh:330
virtual PortProxy & getVirtProxy()=0
T read(Addr address) const
Read sizeof(T) bytes from address and return as object T.
Definition: port_proxy.hh:282
std::string name(Addr ksp) const
Definition: stacktrace.cc:77
void trace(ThreadContext *tc, bool is_call)
Definition: stacktrace.cc:107
ThreadContext is the external interface to all thread state for anything outside of the CPU...
ThreadContext * tc
Definition: stacktrace.hh:44
MipsISA::MachInst MachInst
Definition: stacktrace.hh:61
ThreadContext * tc
Definition: stacktrace.hh:63
bool decodeSave(MachInst inst, int &reg, int &disp)
Definition: stacktrace.cc:166
std::vector< Addr > stack
Definition: stacktrace.hh:64
PortProxy Object Declaration.
Bitfield< 4 > pc
bool isEntry(Addr addr)
Definition: stacktrace.cc:119
bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra)
Definition: stacktrace.cc:195
Addr task(Addr ksp) const
Definition: stacktrace.cc:47
Bitfield< 51, 12 > base
Definition: pagetable.hh:141
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:140
#define ULL(N)
uint64_t constant
Definition: types.hh:48
Bitfield< 20, 16 > ra
Definition: types.hh:45
Bitfield< 17, 16 > stack
Definition: misc.hh:587
This object is a proxy for a port or other object which implements the functional response protocol...
Definition: port_proxy.hh:80
void readString(std::string &str, Addr addr) const
Same as tryReadString, but insists on success.
Definition: port_proxy.hh:255
const int ReturnAddressReg
Definition: registers.hh:119
static const int user
Definition: stacktrace.hh:91
Bitfield< 4 > sp
void dump()
Dump all statistics data to the registered outputs.
Definition: statistics.cc:560
bool decodeStack(MachInst inst, int &disp)
Definition: stacktrace.cc:125
int pid(Addr ksp) const
Definition: stacktrace.cc:62
const ByteOrder GuestByteOrder
Definition: isa_traits.hh:40

Generated on Mon Jun 8 2020 15:34:40 for gem5 by doxygen 1.8.13