mem-cache: Add multiple eviction stats
[gem5.git] / src / arch / x86 / stacktrace.cc
index d887ac2939344dbdb481a64ed4e77d8f91744533..0141a9e75cec223e5ee1326f02fa5376a61ca223 100644 (file)
  * Authors: Nathan Binkert
  */
 
+#include "arch/x86/stacktrace.hh"
+
 #include <string>
 
 #include "arch/x86/isa_traits.hh"
-#include "arch/x86/stacktrace.hh"
 #include "arch/x86/vtophys.hh"
 #include "base/bitfield.hh"
 #include "base/trace.hh"
 #include "mem/fs_translating_port_proxy.hh"
 #include "sim/system.hh"
 
-using namespace std;
 namespace X86ISA
 {
-    ProcessInfo::ProcessInfo(ThreadContext *_tc)
-        : tc(_tc)
-    {
-        Addr addr = 0;
 
-        FSTranslatingPortProxy &vp = tc->getVirtProxy();
+static int32_t
+readSymbol(ThreadContext *tc, const std::string name)
+{
+    PortProxy &vp = tc->getVirtProxy();
+    SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
 
-        if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
-            panic("thread info not compiled into kernel\n");
-        thread_info_size = vp.readGtoH<int32_t>(addr);
+    Addr addr;
+    if (!symtab->findAddress(name, addr))
+        panic("thread info not compiled into kernel\n");
 
-        if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr))
-            panic("thread info not compiled into kernel\n");
-        task_struct_size = vp.readGtoH<int32_t>(addr);
+    return vp.read<int32_t>(addr, GuestByteOrder);
+}
 
-        if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr))
-            panic("thread info not compiled into kernel\n");
-        task_off = vp.readGtoH<int32_t>(addr);
+ProcessInfo::ProcessInfo(ThreadContext *_tc) : tc(_tc)
+{
+    thread_info_size = readSymbol(tc, "thread_info_size");
+    task_struct_size = readSymbol(tc, "task_struct_size");
+    task_off = readSymbol(tc, "thread_info_task");
+    pid_off = readSymbol(tc, "task_struct_pid");
+    name_off = readSymbol(tc, "task_struct_comm");
+}
 
-        if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr))
-            panic("thread info not compiled into kernel\n");
-        pid_off = vp.readGtoH<int32_t>(addr);
+Addr
+ProcessInfo::task(Addr ksp) const
+{
+    Addr base = ksp & ~0x3fff;
+    if (base == ULL(0xfffffc0000000000))
+        return 0;
 
-        if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr))
-            panic("thread info not compiled into kernel\n");
-        name_off = vp.readGtoH<int32_t>(addr);
-    }
+    Addr tsk;
 
-    Addr
-    ProcessInfo::task(Addr ksp) const
-    {
-        Addr base = ksp & ~0x3fff;
-        if (base == ULL(0xfffffc0000000000))
-            return 0;
+    PortProxy &vp = tc->getVirtProxy();
+    tsk = vp.read<Addr>(base + task_off, GuestByteOrder);
 
-        Addr tsk;
+    return tsk;
+}
 
-        FSTranslatingPortProxy &vp = tc->getVirtProxy();
-        tsk = vp.readGtoH<Addr>(base + task_off);
+int
+ProcessInfo::pid(Addr ksp) const
+{
+    Addr task = this->task(ksp);
+    if (!task)
+        return -1;
 
-        return tsk;
-    }
+    uint16_t pd;
 
-    int
-    ProcessInfo::pid(Addr ksp) const
-    {
-        Addr task = this->task(ksp);
-        if (!task)
-            return -1;
+    PortProxy &vp = tc->getVirtProxy();
+    pd = vp.read<uint16_t>(task + pid_off, GuestByteOrder);
 
-        uint16_t pd;
+    return pd;
+}
 
-        FSTranslatingPortProxy &vp = tc->getVirtProxy();
-        pd = vp.readGtoH<uint16_t>(task + pid_off);
+std::string
+ProcessInfo::name(Addr ksp) const
+{
+    Addr task = this->task(ksp);
+    if (!task)
+        return "console";
 
-        return pd;
-    }
+    char comm[256];
+    tc->getVirtProxy().readString(comm, task + name_off, sizeof(comm));
+    if (!comm[0])
+        return "startup";
 
-    string
-    ProcessInfo::name(Addr ksp) const
-    {
-        Addr task = this->task(ksp);
-        if (!task)
-            return "console";
+    return comm;
+}
 
-        char comm[256];
-        CopyStringOut(tc, comm, task + name_off, sizeof(comm));
-        if (!comm[0])
-            return "startup";
+StackTrace::StackTrace()
+    : tc(0), stack(64)
+{
+}
 
-        return comm;
-    }
+StackTrace::StackTrace(ThreadContext *_tc, const StaticInstPtr &inst)
+    : tc(0), stack(64)
+{
+    trace(_tc, inst);
+}
 
-    StackTrace::StackTrace()
-        : tc(0), stack(64)
-    {
-    }
+StackTrace::~StackTrace()
+{
+}
 
-    StackTrace::StackTrace(ThreadContext *_tc, const StaticInstPtr &inst)
-        : tc(0), stack(64)
-    {
-        trace(_tc, inst);
-    }
+void
+StackTrace::trace(ThreadContext *_tc, bool is_call)
+{
+}
 
-    StackTrace::~StackTrace()
-    {
-    }
+bool
+StackTrace::isEntry(Addr addr)
+{
+    return false;
+}
 
-    void
-    StackTrace::trace(ThreadContext *_tc, bool is_call)
-    {
-    }
+bool
+StackTrace::decodeStack(MachInst inst, int &disp)
+{
+    disp = 0;
+    return true;
+}
 
-    bool
-    StackTrace::isEntry(Addr addr)
-    {
-        return false;
-    }
+bool
+StackTrace::decodeSave(MachInst inst, int &reg, int &disp)
+{
+    reg = 0;
+    disp = 0;
+    return true;
+}
 
-    bool
-    StackTrace::decodeStack(MachInst inst, int &disp)
-    {
-        disp = 0;
-        return true;
-    }
+/*
+ * Decode the function prologue for the function we're in, and note
+ * which registers are stored where, and how large the stack frame is.
+ */
+bool
+StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func,
+                           int &size, Addr &ra)
+{
+    size = 0;
+    ra = 0;
 
-    bool
-    StackTrace::decodeSave(MachInst inst, int &reg, int &disp)
-    {
-        reg = 0;
-        disp = 0;
-        return true;
-    }
+    for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) {
+        MachInst inst = tc->getVirtProxy().read<MachInst>(pc);
 
-    /*
-     * Decode the function prologue for the function we're in, and note
-     * which registers are stored where, and how large the stack frame is.
-     */
-    bool
-    StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func,
-                               int &size, Addr &ra)
-    {
-        size = 0;
-        ra = 0;
-
-        for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) {
-            MachInst inst;
-            CopyOut(tc, (uint8_t *)&inst, pc, sizeof(MachInst));
-
-            int reg, disp;
-            if (decodeStack(inst, disp)) {
-                if (size) {
-                    // panic("decoding frame size again");
-                    return true;
-                }
-                size += disp;
-            } else if (decodeSave(inst, reg, disp)) {
-                if (!ra && reg == ReturnAddressReg) {
-                    CopyOut(tc, (uint8_t *)&ra, sp + disp, sizeof(Addr));
-                    if (!ra) {
-                        // panic("no return address value pc=%#x\n", pc);
-                        return false;
-                    }
+        int reg, disp;
+        if (decodeStack(inst, disp)) {
+            if (size) {
+                // panic("decoding frame size again");
+                return true;
+            }
+            size += disp;
+        } else if (decodeSave(inst, reg, disp)) {
+            if (!ra && reg == ReturnAddressReg) {
+                ra = tc->getVirtProxy().read<Addr>(sp + disp);
+                if (!ra) {
+                    // panic("no return address value pc=%#x\n", pc);
+                    return false;
                 }
             }
         }
-
-        return true;
     }
 
+    return true;
+}
+
 #if TRACING_ON
-    void
-    StackTrace::dump()
-    {
-        StringWrap name(tc->getCpuPtr()->name());
-        SymbolTable *symtab = tc->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 == user)
-                symbol = "user";
-            else if (addr == console)
-                symbol = "console";
-            else if (addr == unknown)
-                symbol = "unknown";
-            else
-                symtab->findSymbol(addr, symbol);
-
-            DPRINTFN("%#x: %s\n", addr, symbol);
-        }
+void
+StackTrace::dump()
+{
+    StringWrap name(tc->getCpuPtr()->name());
+    SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
+
+    DPRINTFN("------ Stack ------\n");
+
+    std::string symbol;
+    for (int i = 0, size = stack.size(); i < size; ++i) {
+        Addr addr = stack[size - i - 1];
+        if (addr == user)
+            symbol = "user";
+        else if (addr == console)
+            symbol = "console";
+        else if (addr == unknown)
+            symbol = "unknown";
+        else
+            symtab->findSymbol(addr, symbol);
+
+        DPRINTFN("%#x: %s\n", addr, symbol);
     }
+}
+
 #endif
 }