diff --git a/configs/example/fs.py b/configs/example/fs.py
--- a/configs/example/fs.py
+++ b/configs/example/fs.py
@@ -82,6 +82,7 @@
 
 TestCPUClass.clock = '2GHz'
 DriveCPUClass.clock = '2GHz'
+TestCPUClass.tracer = FuncTrace()
 
 if options.benchmark:
     try:
diff --git a/configs/example/se.py b/configs/example/se.py
--- a/configs/example/se.py
+++ b/configs/example/se.py
@@ -124,7 +124,7 @@
 (CPUClass, test_mem_mode, FutureClass) = Simulation.setCPUClass(options)
 
 CPUClass.clock = '2GHz'
-
+CPUClass.tracer = FuncTrace(user_apps = [options.cmd])
 np = options.num_cpus
 
 system = System(cpu = [CPUClass(cpu_id=i) for i in xrange(np)],
diff --git a/src/base/loader/symtab.hh b/src/base/loader/symtab.hh
--- a/src/base/loader/symtab.hh
+++ b/src/base/loader/symtab.hh
@@ -34,6 +34,7 @@
 
 #include <iosfwd>
 #include <map>
+#include <string>
 
 #include "sim/host.hh"  // for Addr
 
diff --git a/src/cpu/ExeTracer.py b/src/cpu/FuncTrace.py
copy from src/cpu/ExeTracer.py
copy to src/cpu/FuncTrace.py
--- a/src/cpu/ExeTracer.py
+++ b/src/cpu/FuncTrace.py
@@ -24,13 +24,17 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #
-# Authors: Gabe Black
+# Authors: Ali Saidi
 
 from m5.SimObject import SimObject
 from m5.params import *
 from InstTracer import InstTracer
 
-class ExeTracer(InstTracer):
-    type = 'ExeTracer'
+class FuncTrace(InstTracer):
+    type = 'FuncTrace'
     cxx_namespace = 'Trace'
-    cxx_class = 'ExeTracer'
+    cxx_class = 'FuncTrace'
+
+    enabled = Param.Bool(True, "Is function tracing enabled?")
+    user_apps = VectorParam.String([], "List of path to apps to get symbols for")
+    begin = Param.Tick(0, "When to start tracing")
diff --git a/src/cpu/SConscript b/src/cpu/SConscript
--- a/src/cpu/SConscript
+++ b/src/cpu/SConscript
@@ -107,6 +107,7 @@
 SimObject('BaseCPU.py')
 SimObject('FuncUnit.py')
 SimObject('ExeTracer.py')
+SimObject('FuncTrace.py')
 SimObject('IntelTrace.py')
 
 Source('activity.cc')
@@ -114,6 +115,7 @@
 Source('cpuevent.cc')
 Source('exetrace.cc')
 Source('func_unit.cc')
+Source('functrace.cc')
 Source('inteltrace.cc')
 Source('pc_event.cc')
 Source('quiesce_event.cc')
diff --git a/src/cpu/exetrace.cc b/src/cpu/functrace.cc
copy from src/cpu/exetrace.cc
copy to src/cpu/functrace.cc
--- a/src/cpu/exetrace.cc
+++ b/src/cpu/functrace.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001-2005 The Regents of The University of Michigan
+ * Copyright (c) 2001-2008 The Regents of The University of Michigan
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,95 +25,107 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * Authors: Steve Reinhardt
- *          Lisa Hsu
- *          Nathan Binkert
- *          Steve Raasch
- */
+ * Authors: Ali Saidi
+ */ 
 
-#include <iomanip>
 
+#include <vector> 
+
+#include "arch/utility.hh"
+#if THE_ISA == ALPHA_ISA && FULL_SYSTEM
+#include "arch/alpha/linux/threadinfo.hh"
+#endif
+
+#include "base/loader/object_file.hh"
 #include "base/loader/symtab.hh"
 #include "cpu/base.hh"
-#include "cpu/exetrace.hh"
+#include "cpu/functrace.hh"
 #include "cpu/static_inst.hh"
 #include "cpu/thread_context.hh"
-#include "enums/OpClass.hh"
+
 
 using namespace std;
 using namespace TheISA;
 
 namespace Trace {
 
+FuncTrace::FuncTrace(const Params *p)
+    : InstTracer(p), beginTick(p->begin), enabled(p->enabled)
+{
+    //std::vector< std::string > strings;
+    vector<string>::const_iterator i;
+    i = p->user_apps.begin();
+    //i = strings.begin();
+
+    while (i != p->user_apps.end()) {
+        ObjectFile *of = createObjectFile(*i);
+        string sf;
+        if (!of)
+            fatal("Couldn't load symbols from file: %s\n", *i);
+        sf = *i;
+        sf.erase(0, sf.rfind('/') + 1);;
+        userApps[sf] = new SymbolTable;
+        bool result1 = of->loadGlobalSymbols(userApps[sf]);
+        bool result2 = of->loadLocalSymbols(userApps[sf]);
+        if (!result1 || !result2)
+            fatal("Failed to load symbols for %s\n", *i);
+        i++;
+    }
+}
+
+
+
 void
-Trace::ExeTracerRecord::dump()
+Trace::FuncTraceRecord::dump()
 {
-    ostream &outs = Trace::output();
+    ft->dump(when, thread, PC);
+}
 
-    if (IsOn(ExecTicks))
+void
+Trace::FuncTrace::dump(Tick when, ThreadContext *tc, Addr pc)
+{
+    string sym;
+    Addr sym_addr = 0;
+
+#if FULL_SYSTEM
+    if (!TheISA::inUserMode(tc)) 
+        debugSymbolTable->findNearestSymbol(pc, sym, sym_addr);
+#if THE_ISA == ALPHA_ISA
+    else {
+        Linux::ThreadInfo ti(tc);
+        string app = ti.curTaskName();
+        if (userApps.count(app))
+            userApps[app]->findNearestSymbol(pc, sym, sym_addr);
+        else
+            sym = "[" + app + "]";
+    }
+#else  // !ALPHA_ISA
+    sym = "[User Application]";
+#endif // ALPHA_ISA
+#else  // !FULL_SYSTEM
+    debugSymbolTable->findNearestSymbol(pc, sym, sym_addr);
+#endif // !FULL_SYSTEM
+    assert(sym != "");
+    
+    if (lastSymbol[tc] != sym) {
+        lastSymbol[tc] = sym;
+
+        ostream &outs = Trace::output();
         ccprintf(outs, "%7d: ", when);
+        outs << sym;
 
-    outs << thread->getCpuPtr()->name() << " ";
-
-    if (IsOn(ExecSpeculative))
-        outs << (misspeculating ? "-" : "+") << " ";
-
-    if (IsOn(ExecThread))
-        outs << "T" << thread->getThreadNum() << " : ";
-
-
-    std::string sym_str;
-    Addr sym_addr;
-    if (debugSymbolTable
-        && IsOn(ExecSymbol)
-        && debugSymbolTable->findNearestSymbol(PC, sym_str, sym_addr)) {
-        if (PC != sym_addr)
-            sym_str += csprintf("+%d", PC - sym_addr);
-        outs << "@" << sym_str << " : ";
+        outs << endl;
     }
-    else {
-        outs << "0x" << hex << PC << " : ";
-    }
-
-    //
-    //  Print decoded instruction
-    //
-
-    outs << setw(26) << left;
-    outs << staticInst->disassemble(PC, debugSymbolTable);
-    outs << " : ";
-
-    if (IsOn(ExecOpClass)) {
-        outs << Enums::OpClassStrings[staticInst->opClass()] << " : ";
-    }
-
-    if (IsOn(ExecResult) && data_status != DataInvalid) {
-        ccprintf(outs, " D=%#018x", data.as_int);
-    }
-
-    if (IsOn(ExecEffAddr) && addr_valid)
-        outs << " A=0x" << hex << addr;
-
-    if (IsOn(ExecFetchSeq) && fetch_seq_valid)
-        outs << "  FetchSeq=" << dec << fetch_seq;
-
-    if (IsOn(ExecCPSeq) && cp_seq_valid)
-        outs << "  CPSeq=" << dec << cp_seq;
-
-    //
-    //  End of line...
-    //
-    outs << endl;
 }
 
 /* namespace Trace */ }
 
 ////////////////////////////////////////////////////////////////////////
 //
-//  ExeTracer Simulation Object
+//  FuncTrace Simulation Object
 //
-Trace::ExeTracer *
-ExeTracerParams::create()
+Trace::FuncTrace *
+FuncTraceParams::create()
 {
-    return new Trace::ExeTracer(this);
+    return new Trace::FuncTrace(this);
 };
diff --git a/src/cpu/exetrace.hh b/src/cpu/functrace.hh
copy from src/cpu/exetrace.hh
copy to src/cpu/functrace.hh
--- a/src/cpu/exetrace.hh
+++ b/src/cpu/functrace.hh
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001-2005 The Regents of The University of Michigan
+ * Copyright (c) 2001-2008 The Regents of The University of Michigan
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,59 +25,71 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * Authors: Steve Reinhardt
+ * Authors: Ali Saidi
+ *          Steve Reinhardt
  *          Nathan Binkert
  */
 
-#ifndef __EXETRACE_HH__
-#define __EXETRACE_HH__
+#ifndef __CPU_FUNCTRACE_HH__
+#define __CPU_FUNCTRACE_HH__
+
+#include <map>
+#include <string>
 
 #include "base/trace.hh"
 #include "cpu/static_inst.hh"
 #include "sim/host.hh"
 #include "sim/insttracer.hh"
-#include "params/ExeTracer.hh"
+#include "params/FuncTrace.hh"
 
 class ThreadContext;
-
+class SymbolTable;
 
 namespace Trace {
 
-class ExeTracerRecord : public InstRecord
+class FuncTrace;
+
+class FuncTraceRecord : public InstRecord
 {
+  protected:
+    FuncTrace *ft;
   public:
-    ExeTracerRecord(Tick _when, ThreadContext *_thread,
+    FuncTraceRecord(FuncTrace *_ft, Tick _when, ThreadContext *_thread,
                const StaticInstPtr &_staticInst, Addr _pc, bool spec)
-        : InstRecord(_when, _thread, _staticInst, _pc, spec)
+        : InstRecord(_when, _thread, _staticInst, _pc, spec), ft(_ft)
     {
     }
 
     void dump();
 };
 
-class ExeTracer : public InstTracer
+class FuncTrace : public InstTracer
 {
+  protected:
+    Tick beginTick;
+    std::map<std::string, SymbolTable*> userApps;
+    std::map<ThreadContext*, std::string> lastSymbol;
+    bool enabled;
+
   public:
-    typedef ExeTracerParams Params;
-    ExeTracer(const Params *params) : InstTracer(params)
-    {}
+    typedef FuncTraceParams Params;
+    FuncTrace(const Params *params);
 
     InstRecord *
     getInstRecord(Tick when, ThreadContext *tc,
             const StaticInstPtr staticInst, Addr pc)
     {
-        if (!IsOn(ExecEnable))
+        if (!enabled)
+            return NULL;
+        
+        if (curTick < beginTick)
             return NULL;
 
-        if (!Trace::enabled)
-            return NULL;
-
-        if (!IsOn(ExecSpeculative) && tc->misspeculating())
-            return NULL;
-
-        return new ExeTracerRecord(when, tc,
+        return new FuncTraceRecord(this, when, tc,
                 staticInst, pc, tc->misspeculating());
     }
+
+    void dump(Tick when, ThreadContext *tc, Addr pc);
 };
 
 /* namespace Trace */ }
