gem5  v19.0.0.0
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  * Authors: Nathan Binkert
29  */
30 
31 #include "arch/mips/stacktrace.hh"
32 
33 #include <string>
34 
35 #include "arch/mips/isa_traits.hh"
36 #include "arch/mips/vtophys.hh"
37 #include "base/bitfield.hh"
38 #include "base/trace.hh"
39 #include "cpu/base.hh"
40 #include "cpu/thread_context.hh"
42 #include "sim/system.hh"
43 
44 using namespace MipsISA;
45 
47 {}
48 
49 Addr
51 {
52  Addr base = ksp & ~0x3fff;
53  if (base == ULL(0xfffffc0000000000))
54  return 0;
55 
56  Addr tsk;
57 
58  PortProxy &vp = tc->getVirtProxy();
59  tsk = vp.read<Addr>(base + task_off, GuestByteOrder);
60 
61  return tsk;
62 }
63 
64 int
66 {
67  Addr task = this->task(ksp);
68  if (!task)
69  return -1;
70 
71  uint16_t pd;
72 
73  PortProxy &vp = tc->getVirtProxy();
74  pd = vp.read<uint16_t>(task + pid_off, GuestByteOrder);
75 
76  return pd;
77 }
78 
79 std::string
81 {
82  Addr task = this->task(ksp);
83  if (!task)
84  return "console";
85 
86  char comm[256];
87  tc->getVirtProxy().readString(comm, task + name_off, sizeof(comm));
88  if (!comm[0])
89  return "startup";
90 
91  return comm;
92 }
93 
95  : tc(0), stack(64)
96 {
97 }
98 
100  : tc(0), stack(64)
101 {
102  trace(_tc, inst);
103 }
104 
106 {
107 }
108 
109 void
110 StackTrace::trace(ThreadContext *_tc, bool is_call)
111 {
112  tc = _tc;
113  bool usermode = 0;
114 
115  if (usermode) {
116  stack.push_back(user);
117  return;
118  }
119 }
120 
121 bool
123 {
124  return false;
125 }
126 
127 bool
129 {
130  // lda $sp, -disp($sp)
131  //
132  // Opcode<31:26> == 0x08
133  // RA<25:21> == 30
134  // RB<20:16> == 30
135  // Disp<15:0>
136  const MachInst mem_mask = 0xffff0000;
137  const MachInst lda_pattern = 0x23de0000;
138  const MachInst lda_disp_mask = 0x0000ffff;
139 
140  // subq $sp, disp, $sp
141  // addq $sp, disp, $sp
142  //
143  // Opcode<31:26> == 0x10
144  // RA<25:21> == 30
145  // Lit<20:13>
146  // One<12> = 1
147  // Func<11:5> == 0x20 (addq)
148  // Func<11:5> == 0x29 (subq)
149  // RC<4:0> == 30
150  const MachInst intop_mask = 0xffe01fff;
151  const MachInst addq_pattern = 0x43c0141e;
152  const MachInst subq_pattern = 0x43c0153e;
153  const MachInst intop_disp_mask = 0x001fe000;
154  const int intop_disp_shift = 13;
155 
156  if ((inst & mem_mask) == lda_pattern)
157  disp = -sext<16>(inst & lda_disp_mask);
158  else if ((inst & intop_mask) == addq_pattern)
159  disp = -int((inst & intop_disp_mask) >> intop_disp_shift);
160  else if ((inst & intop_mask) == subq_pattern)
161  disp = int((inst & intop_disp_mask) >> intop_disp_shift);
162  else
163  return false;
164 
165  return true;
166 }
167 
168 bool
169 StackTrace::decodeSave(MachInst inst, int &reg, int &disp)
170 {
171  // lda $stq, disp($sp)
172  //
173  // Opcode<31:26> == 0x08
174  // RA<25:21> == ?
175  // RB<20:16> == 30
176  // Disp<15:0>
177  const MachInst stq_mask = 0xfc1f0000;
178  const MachInst stq_pattern = 0xb41e0000;
179  const MachInst stq_disp_mask = 0x0000ffff;
180  const MachInst reg_mask = 0x03e00000;
181  const int reg_shift = 21;
182 
183  if ((inst & stq_mask) == stq_pattern) {
184  reg = (inst & reg_mask) >> reg_shift;
185  disp = sext<16>(inst & stq_disp_mask);
186  } else {
187  return false;
188  }
189 
190  return true;
191 }
192 
193 /*
194  * Decode the function prologue for the function we're in, and note
195  * which registers are stored where, and how large the stack frame is.
196  */
197 bool
199  int &size, Addr &ra)
200 {
201  size = 0;
202  ra = 0;
203 
204  for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) {
205  MachInst inst = tc->getVirtProxy().read<MachInst>(pc);
206 
207  int reg, disp;
208  if (decodeStack(inst, disp)) {
209  if (size) {
210  return true;
211  }
212  size += disp;
213  } else if (decodeSave(inst, reg, disp)) {
214  if (!ra && reg == ReturnAddressReg) {
215  ra = tc->getVirtProxy().read<Addr>(sp + disp);
216  if (!ra) {
217  return false;
218  }
219  }
220  }
221  }
222 
223  return true;
224 }
225 
226 #if TRACING_ON
227 void
229 {
230  panic("Stack trace dump not implemented.\n");
231 }
232 #endif
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:167
Bitfield< 5, 3 > reg
Definition: types.hh:89
ProcessInfo(ThreadContext *_tc)
Definition: stacktrace.cc:46
ip6_addr_t addr
Definition: inet.hh:335
virtual PortProxy & getVirtProxy()=0
T read(Addr address) const
Read sizeof(T) bytes from address and return as object T.
Definition: port_proxy.hh:284
std::string name(Addr ksp) const
Definition: stacktrace.cc:80
void trace(ThreadContext *tc, bool is_call)
Definition: stacktrace.cc:110
ThreadContext is the external interface to all thread state for anything outside of the CPU...
ThreadContext * tc
Definition: stacktrace.hh:46
MipsISA::MachInst MachInst
Definition: stacktrace.hh:63
ThreadContext * tc
Definition: stacktrace.hh:65
bool decodeSave(MachInst inst, int &reg, int &disp)
Definition: stacktrace.cc:169
std::vector< Addr > stack
Definition: stacktrace.hh:66
Bitfield< 4 > pc
bool isEntry(Addr addr)
Definition: stacktrace.cc:122
bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra)
Definition: stacktrace.cc:198
Addr task(Addr ksp) const
Definition: stacktrace.cc:50
Bitfield< 51, 12 > base
Definition: pagetable.hh:142
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
#define ULL(N)
uint64_t constant
Definition: types.hh:50
Bitfield< 20, 16 > ra
Definition: types.hh:47
Bitfield< 17, 16 > stack
Definition: misc.hh:589
This object is a proxy for a port or other object which implements the functional response protocol...
Definition: port_proxy.hh:82
void readString(std::string &str, Addr addr) const
Same as tryReadString, but insists on success.
Definition: port_proxy.hh:257
const int ReturnAddressReg
Definition: registers.hh:121
static const int user
Definition: stacktrace.hh:93
Bitfield< 4 > sp
TranslatingPortProxy Object Declaration for FS.
void dump()
Dump all statistics data to the registered outputs.
Definition: statistics.cc:561
bool decodeStack(MachInst inst, int &disp)
Definition: stacktrace.cc:128
int pid(Addr ksp) const
Definition: stacktrace.cc:65
const ByteOrder GuestByteOrder
Definition: isa_traits.hh:44

Generated on Fri Feb 28 2020 16:26:56 for gem5 by doxygen 1.8.13