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) 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/x86/stacktrace.hh"
30 
31 #include <string>
32 
33 #include "arch/x86/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 namespace X86ISA
42 {
43 
44 static int32_t
45 readSymbol(ThreadContext *tc, const std::string name)
46 {
47  PortProxy &vp = tc->getVirtProxy();
48  const auto *symtab = tc->getSystemPtr()->workload->symtab(tc);
49 
50  auto it = symtab->find(name);
51  panic_if(it == symtab->end(), "Thread info not compiled into kernel.");
52 
53  return vp.read<int32_t>(it->address, GuestByteOrder);
54 }
55 
57 {
58  thread_info_size = readSymbol(tc, "thread_info_size");
59  task_struct_size = readSymbol(tc, "task_struct_size");
60  task_off = readSymbol(tc, "thread_info_task");
61  pid_off = readSymbol(tc, "task_struct_pid");
62  name_off = readSymbol(tc, "task_struct_comm");
63 }
64 
65 Addr
67 {
68  Addr base = ksp & ~0x3fff;
69  if (base == ULL(0xfffffc0000000000))
70  return 0;
71 
72  Addr tsk;
73 
74  PortProxy &vp = tc->getVirtProxy();
75  tsk = vp.read<Addr>(base + task_off, GuestByteOrder);
76 
77  return tsk;
78 }
79 
80 int
82 {
83  Addr task = this->task(ksp);
84  if (!task)
85  return -1;
86 
87  uint16_t pd;
88 
89  PortProxy &vp = tc->getVirtProxy();
90  pd = vp.read<uint16_t>(task + pid_off, GuestByteOrder);
91 
92  return pd;
93 }
94 
95 std::string
97 {
98  Addr task = this->task(ksp);
99  if (!task)
100  return "console";
101 
102  char comm[256];
103  tc->getVirtProxy().readString(comm, task + name_off, sizeof(comm));
104  if (!comm[0])
105  return "startup";
106 
107  return comm;
108 }
109 
111  : tc(0), stack(64)
112 {
113 }
114 
116  : tc(0), stack(64)
117 {
118  trace(_tc, inst);
119 }
120 
122 {
123 }
124 
125 void
126 StackTrace::trace(ThreadContext *_tc, bool is_call)
127 {
128 }
129 
130 bool
132 {
133  return false;
134 }
135 
136 bool
138 {
139  disp = 0;
140  return true;
141 }
142 
143 bool
144 StackTrace::decodeSave(MachInst inst, int &reg, int &disp)
145 {
146  reg = 0;
147  disp = 0;
148  return true;
149 }
150 
151 /*
152  * Decode the function prologue for the function we're in, and note
153  * which registers are stored where, and how large the stack frame is.
154  */
155 bool
157  int &size, Addr &ra)
158 {
159  size = 0;
160  ra = 0;
161 
162  for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) {
163  MachInst inst = tc->getVirtProxy().read<MachInst>(pc);
164 
165  int reg, disp;
166  if (decodeStack(inst, disp)) {
167  if (size) {
168  // panic("decoding frame size again");
169  return true;
170  }
171  size += disp;
172  } else if (decodeSave(inst, reg, disp)) {
173  if (!ra && reg == ReturnAddressReg) {
174  ra = tc->getVirtProxy().read<Addr>(sp + disp);
175  if (!ra) {
176  // panic("no return address value pc=%#x\n", pc);
177  return false;
178  }
179  }
180  }
181  }
182 
183  return true;
184 }
185 
186 #if TRACING_ON
187 void
189 {
191  const auto *symtab = tc->getSystemPtr()->workload->symtab(tc);
192 
193  DPRINTFN("------ Stack ------\n");
194 
195  std::string symbol;
196  for (int i = 0, size = stack.size(); i < size; ++i) {
197  Addr addr = stack[size - i - 1];
199  if (addr == user)
200  symbol = "user";
201  else if (addr == console)
202  symbol = "console";
203  else if (addr == unknown)
204  symbol = "unknown";
205  else if ((it = symtab->find(addr)) != symtab->end())
206  symbol = it->name;
207 
208  DPRINTFN("%#x: %s\n", addr, symbol);
209  }
210 }
211 
212 #endif
213 }
virtual System * getSystemPtr()=0
virtual const Loader::SymbolTable * symtab(ThreadContext *tc)=0
Bitfield< 5, 3 > reg
Definition: types.hh:87
ThreadContext * tc
Definition: stacktrace.hh:63
const std::string & name()
Definition: trace.cc:50
Bitfield< 7 > i
ThreadContext * tc
Definition: stacktrace.hh:44
ProcessInfo(ThreadContext *_tc)
Definition: stacktrace.cc:56
Addr task(Addr ksp) const
Definition: stacktrace.cc:66
const ByteOrder GuestByteOrder
Definition: isa_traits.hh:48
virtual PortProxy & getVirtProxy()=0
Bitfield< 0 > sp
T read(Addr address) const
Read sizeof(T) bytes from address and return as object T.
Definition: port_proxy.hh:282
virtual BaseCPU * getCpuPtr()=0
Bitfield< 19 > pc
Definition: misc.hh:805
bool isEntry(Addr addr)
Definition: stacktrace.cc:131
ThreadContext is the external interface to all thread state for anything outside of the CPU...
#define DPRINTFN(...)
Definition: trace.hh:226
bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra)
Definition: stacktrace.cc:156
const int ReturnAddressReg
Definition: registers.hh:87
bool decodeStack(MachInst inst, int &disp)
Definition: stacktrace.cc:137
PortProxy Object Declaration.
std::string name(Addr ksp) const
Definition: stacktrace.cc:96
Bitfield< 51, 12 > base
Definition: pagetable.hh:141
static const int unknown
Definition: stacktrace.hh:93
uint64_t MachInst
Definition: types.hh:52
Workload * workload
OS kernel.
Definition: system.hh:213
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
bool decodeSave(MachInst inst, int &reg, int &disp)
Definition: stacktrace.cc:144
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 trace(ThreadContext *tc, bool is_call)
Definition: stacktrace.cc:126
void readString(std::string &str, Addr addr) const
Same as tryReadString, but insists on success.
Definition: port_proxy.hh:255
virtual const std::string name() const
Definition: sim_object.hh:128
SymbolVector::const_iterator const_iterator
Definition: symtab.hh:123
static const int console
Definition: stacktrace.hh:92
This is exposed globally, independent of the ISA.
Definition: acpi.hh:55
static const int user
Definition: stacktrace.hh:91
const_iterator find(Addr address) const
Definition: symtab.hh:181
void dump()
Dump all statistics data to the registered outputs.
Definition: statistics.cc:560
int pid(Addr ksp) const
Definition: stacktrace.cc:81
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:181
Bitfield< 3 > addr
Definition: types.hh:79
static int32_t readSymbol(ThreadContext *tc, const std::string name)
Definition: stacktrace.cc:45
std::vector< Addr > stack
Definition: stacktrace.hh:64

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