Merge gblack@m5.eecs.umich.edu:/bk/multiarch
[gem5.git] / arch / alpha / stacktrace.cc
index fdad9d6731cd4908dce367eada7dabc6357a8bdd..89b6b73a91f1dc1884c1951530649c3104b2433f 100644 (file)
@@ -37,6 +37,7 @@
 #include "cpu/exec_context.hh"
 
 using namespace std;
+using namespace AlphaISA;
 
 ProcessInfo::ProcessInfo(ExecContext *_xc)
     : xc(_xc)
@@ -103,25 +104,42 @@ 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);
+}
+
+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->regs.npc;
     bool kernel = xc->system->kernelStart <= pc && pc <= xc->system->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;
+    SymbolTable *symtab = xc->system->kernelSymtab;
     Addr ksp = xc->regs.intRegFile[TheISA::StackPointerReg];
     Addr bottom = ksp & ~0x3fff;
     Addr addr;
@@ -151,10 +169,15 @@ 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;
         }
 
@@ -162,34 +185,33 @@ StackTrace::StackTrace(ExecContext *_xc, bool is_call)
             pc <= xc->system->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;
@@ -302,18 +324,18 @@ void
 StackTrace::dump()
 {
     StringWrap name(xc->cpu->name());
-    SymbolTable *symtab = xc->system->allSymtab;
+    SymbolTable *symtab = xc->system->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);