gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups 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 std;
45 using namespace MipsISA;
46 
47 ProcessInfo::ProcessInfo(ThreadContext *_tc) : tc(_tc)
48 {}
49 
50 Addr
52 {
53  Addr base = ksp & ~0x3fff;
54  if (base == ULL(0xfffffc0000000000))
55  return 0;
56 
57  Addr tsk;
58 
60  tsk = vp.readGtoH<Addr>(base + task_off);
61 
62  return tsk;
63 }
64 
65 int
67 {
68  Addr task = this->task(ksp);
69  if (!task)
70  return -1;
71 
72  uint16_t pd;
73 
75  pd = vp.readGtoH<uint16_t>(task + pid_off);
76 
77  return pd;
78 }
79 
80 string
82 {
83  Addr task = this->task(ksp);
84  if (!task)
85  return "console";
86 
87  char comm[256];
88  CopyStringOut(tc, comm, task + name_off, sizeof(comm));
89  if (!comm[0])
90  return "startup";
91 
92  return comm;
93 }
94 
96  : tc(0), stack(64)
97 {
98 }
99 
101  : tc(0), stack(64)
102 {
103  trace(_tc, inst);
104 }
105 
107 {
108 }
109 
110 void
111 StackTrace::trace(ThreadContext *_tc, bool is_call)
112 {
113  tc = _tc;
114  bool usermode = 0;
115 
116  if (usermode) {
117  stack.push_back(user);
118  return;
119  }
120 }
121 
122 bool
124 {
125  return false;
126 }
127 
128 bool
130 {
131  // lda $sp, -disp($sp)
132  //
133  // Opcode<31:26> == 0x08
134  // RA<25:21> == 30
135  // RB<20:16> == 30
136  // Disp<15:0>
137  const MachInst mem_mask = 0xffff0000;
138  const MachInst lda_pattern = 0x23de0000;
139  const MachInst lda_disp_mask = 0x0000ffff;
140 
141  // subq $sp, disp, $sp
142  // addq $sp, disp, $sp
143  //
144  // Opcode<31:26> == 0x10
145  // RA<25:21> == 30
146  // Lit<20:13>
147  // One<12> = 1
148  // Func<11:5> == 0x20 (addq)
149  // Func<11:5> == 0x29 (subq)
150  // RC<4:0> == 30
151  const MachInst intop_mask = 0xffe01fff;
152  const MachInst addq_pattern = 0x43c0141e;
153  const MachInst subq_pattern = 0x43c0153e;
154  const MachInst intop_disp_mask = 0x001fe000;
155  const int intop_disp_shift = 13;
156 
157  if ((inst & mem_mask) == lda_pattern)
158  disp = -sext<16>(inst & lda_disp_mask);
159  else if ((inst & intop_mask) == addq_pattern)
160  disp = -int((inst & intop_disp_mask) >> intop_disp_shift);
161  else if ((inst & intop_mask) == subq_pattern)
162  disp = int((inst & intop_disp_mask) >> intop_disp_shift);
163  else
164  return false;
165 
166  return true;
167 }
168 
169 bool
170 StackTrace::decodeSave(MachInst inst, int &reg, int &disp)
171 {
172  // lda $stq, disp($sp)
173  //
174  // Opcode<31:26> == 0x08
175  // RA<25:21> == ?
176  // RB<20:16> == 30
177  // Disp<15:0>
178  const MachInst stq_mask = 0xfc1f0000;
179  const MachInst stq_pattern = 0xb41e0000;
180  const MachInst stq_disp_mask = 0x0000ffff;
181  const MachInst reg_mask = 0x03e00000;
182  const int reg_shift = 21;
183 
184  if ((inst & stq_mask) == stq_pattern) {
185  reg = (inst & reg_mask) >> reg_shift;
186  disp = sext<16>(inst & stq_disp_mask);
187  } else {
188  return false;
189  }
190 
191  return true;
192 }
193 
194 /*
195  * Decode the function prologue for the function we're in, and note
196  * which registers are stored where, and how large the stack frame is.
197  */
198 bool
200  int &size, Addr &ra)
201 {
202  size = 0;
203  ra = 0;
204 
205  for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) {
206  MachInst inst;
207  CopyOut(tc, (uint8_t *)&inst, pc, sizeof(MachInst));
208 
209  int reg, disp;
210  if (decodeStack(inst, disp)) {
211  if (size) {
212  return true;
213  }
214  size += disp;
215  } else if (decodeSave(inst, reg, disp)) {
216  if (!ra && reg == ReturnAddressReg) {
217  CopyOut(tc, (uint8_t *)&ra, sp + disp, sizeof(Addr));
218  if (!ra) {
219  return false;
220  }
221  }
222  }
223  }
224 
225  return true;
226 }
227 
228 #if TRACING_ON
229 void
231 {
232  panic("Stack trace dump not implemented.\n");
233 }
234 #endif
A TranslatingPortProxy in FS mode translates a virtual address to a physical address and then calls t...
Bitfield< 5, 3 > reg
Definition: types.hh:89
#define panic(...)
Definition: misc.hh:153
ip6_addr_t addr
Definition: inet.hh:335
void trace(ThreadContext *tc, bool is_call)
Definition: stacktrace.cc:111
void CopyOut(ThreadContext *tc, void *dest, Addr src, size_t cplen)
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:170
std::vector< Addr > stack
Definition: stacktrace.hh:66
Bitfield< 4 > pc
bool isEntry(Addr addr)
Definition: stacktrace.cc:123
bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra)
Definition: stacktrace.cc:199
Addr task(Addr ksp) const
Definition: stacktrace.cc:51
void CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen)
std::string name(Addr ksp) const
Definition: stacktrace.cc:81
Bitfield< 51, 12 > base
Definition: pagetable.hh:85
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
int pid(Addr ksp) const
Definition: stacktrace.cc:66
Bitfield< 17, 16 > stack
Definition: misc.hh:588
virtual FSTranslatingPortProxy & getVirtProxy()=0
int size()
Definition: pagetable.hh:146
const int ReturnAddressReg
Definition: registers.hh:115
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:517
bool decodeStack(MachInst inst, int &disp)
Definition: stacktrace.cc:129

Generated on Fri Jun 9 2017 13:03:36 for gem5 by doxygen 1.8.6