Merge ktlim@zizzer:/bk/m5
[gem5.git] / arch / alpha / stacktrace.cc
index fdad9d6731cd4908dce367eada7dabc6357a8bdd..26656ab5cb1861f62aac503f607de6e785778f10 100644 (file)
 #include "base/trace.hh"
 #include "cpu/base.hh"
 #include "cpu/exec_context.hh"
+#include "sim/system.hh"
 
 using namespace std;
+using namespace AlphaISA;
 
 ProcessInfo::ProcessInfo(ExecContext *_xc)
     : xc(_xc)
 {
     Addr addr = 0;
 
-    if (!xc->system->kernelSymtab->findAddress("thread_info_size", addr))
+    if (!xc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
         panic("thread info not compiled into kernel\n");
     thread_info_size = *(int32_t *)vtomem(xc, addr, sizeof(int32_t));
 
-    if (!xc->system->kernelSymtab->findAddress("task_struct_size", addr))
+    if (!xc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr))
         panic("thread info not compiled into kernel\n");
     task_struct_size = *(int32_t *)vtomem(xc, addr, sizeof(int32_t));
 
-    if (!xc->system->kernelSymtab->findAddress("thread_info_task", addr))
+    if (!xc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr))
         panic("thread info not compiled into kernel\n");
     task_off = *(int32_t *)vtomem(xc, addr, sizeof(int32_t));
 
-    if (!xc->system->kernelSymtab->findAddress("task_struct_pid", addr))
+    if (!xc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr))
         panic("thread info not compiled into kernel\n");
     pid_off = *(int32_t *)vtomem(xc, addr, sizeof(int32_t));
 
-    if (!xc->system->kernelSymtab->findAddress("task_struct_comm", addr))
+    if (!xc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr))
         panic("thread info not compiled into kernel\n");
     name_off = *(int32_t *)vtomem(xc, addr, sizeof(int32_t));
 }
@@ -103,26 +105,44 @@ ProcessInfo::name(Addr ksp) const
     return comm;
 }
 
-StackTrace::StackTrace(ExecContext *_xc, bool is_call)
-    : xc(_xc)
+StackTrace::StackTrace()
+    : xc(0), stack(64)
+{
+}
+
+StackTrace::StackTrace(ExecContext *_xc, StaticInstPtr inst)
+    : xc(0), stack(64)
 {
-    bool usermode = (xc->regs.ipr[AlphaISA::IPR_DTB_CM] & 0x18) != 0;
+    trace(_xc, inst);
+}
 
-    Addr pc = xc->regs.npc;
-    bool kernel = xc->system->kernelStart <= pc && pc <= xc->system->kernelEnd;
+StackTrace::~StackTrace()
+{
+}
+
+void
+StackTrace::trace(ExecContext *_xc, bool is_call)
+{
+    xc = _xc;
+
+    bool usermode = (xc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
+
+    Addr pc = xc->readNextPC();
+    bool kernel = xc->getSystemPtr()->kernelStart <= pc &&
+        pc <= xc->getSystemPtr()->kernelEnd;
 
     if (usermode) {
-        stack.push_back(1);
+        stack.push_back(user);
         return;
     }
 
     if (!kernel) {
-        stack.push_back(2);
+        stack.push_back(console);
         return;
     }
 
-    SymbolTable *symtab = xc->system->allSymtab;
-    Addr ksp = xc->regs.intRegFile[TheISA::StackPointerReg];
+    SymbolTable *symtab = xc->getSystemPtr()->kernelSymtab;
+    Addr ksp = xc->readIntReg(TheISA::StackPointerReg);
     Addr bottom = ksp & ~0x3fff;
     Addr addr;
 
@@ -131,7 +151,7 @@ StackTrace::StackTrace(ExecContext *_xc, bool is_call)
             panic("could not find address %#x", pc);
 
         stack.push_back(addr);
-        pc = xc->regs.pc;
+        pc = xc->readPC();
     }
 
     Addr ra;
@@ -151,45 +171,49 @@ StackTrace::StackTrace(ExecContext *_xc, bool is_call)
             if (!ra)
                 return;
 
+            if (size <= 0) {
+                stack.push_back(unknown);
+                return;
+            }
+
             pc = ra;
             ksp += size;
         } else {
-            stack.push_back(3);
+            stack.push_back(unknown);
             return;
         }
 
-        bool kernel = xc->system->kernelStart <= pc &&
-            pc <= xc->system->kernelEnd;
+        bool kernel = xc->getSystemPtr()->kernelStart <= pc &&
+            pc <= xc->getSystemPtr()->kernelEnd;
         if (!kernel)
             return;
+
+        if (stack.size() >= 1000)
+            panic("unwinding too far");
     }
 
     panic("unwinding too far");
 }
 
-StackTrace::~StackTrace()
-{
-}
-
 bool
 StackTrace::isEntry(Addr addr)
 {
-    if (addr == xc->regs.ipr[AlphaISA::IPR_PALtemp12])
+    if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp12))
         return true;
 
-    if (addr == xc->regs.ipr[AlphaISA::IPR_PALtemp7])
+    if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp7))
         return true;
 
-    if (addr == xc->regs.ipr[AlphaISA::IPR_PALtemp11])
+    if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp11))
         return true;
 
-    if (addr == xc->regs.ipr[AlphaISA::IPR_PALtemp21])
+    if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp21))
         return true;
 
-    if (addr == xc->regs.ipr[AlphaISA::IPR_PALtemp9])
+    if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp9))
         return true;
 
-    if (addr == xc->regs.ipr[AlphaISA::IPR_PALtemp2])
+    if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp2))
         return true;
 
     return false;
@@ -301,19 +325,19 @@ StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func,
 void
 StackTrace::dump()
 {
-    StringWrap name(xc->cpu->name());
-    SymbolTable *symtab = xc->system->allSymtab;
+    StringWrap name(xc->getCpuPtr()->name());
+    SymbolTable *symtab = xc->getSystemPtr()->kernelSymtab;
 
     DPRINTFN("------ Stack ------\n");
 
     string symbol;
     for (int i = 0, size = stack.size(); i < size; ++i) {
         Addr addr = stack[size - i - 1];
-        if (addr == 1)
+        if (addr == user)
             symbol = "user";
-        else if (addr == 2)
+        else if (addr == console)
             symbol = "console";
-        else if (addr == 3)
+        else if (addr == unknown)
             symbol = "unknown";
         else
             symtab->findSymbol(addr, symbol);