summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Reinhardt <stever@eecs.umich.edu>2004-11-15 01:56:40 -0500
committerSteve Reinhardt <stever@eecs.umich.edu>2004-11-15 01:56:40 -0500
commitfed64a3b3634315bce420b2bc63312c1fa62bb8f (patch)
treefa45a0e8c3154c7e1e27e393198fd1e2ad1cd5fb
parent2e0695ec9ae9bbc798c8164e9dd66f59fef93b4e (diff)
downloadgem5-fed64a3b3634315bce420b2bc63312c1fa62bb8f.tar.xz
Add support for sampled PC profiling to FullCPU.
Simple text list of symbol (or address) and count will be dumped to m5prof.<cpu-name> if the cpu's pc_sample_interval param is set. SConscript: Add cpu/full_cpu/pc_sample_profile.cc base/callback.hh: Add a comment about MakeCallback. Fix type in another comment. base/loader/symtab.cc: Revamp findNearestSymbol() to provide addresses of both nearest symbols (preceding and following) as well as string for former. Move global definition of debugSymbolTable here too. base/loader/symtab.hh: Revamp findNearestSymbol() to provide addresses of both nearest symbols (preceding and following) as well as string for former. Move global declaration of debugSymbolTable here too. cpu/exetrace.cc: Use new findNearestSymbol() interface for trace symbols. kern/linux/linux_system.cc: sim/system.cc: Remove extern of debugSymbolTable (now in symtab.hh) sim/process.cc: Initialize debugSymbolTable if binary has a symbol table. --HG-- extra : convert_revision : 0b5393dc39c40ac88c953684708f1125da550671
-rw-r--r--SConscript1
-rw-r--r--base/callback.hh7
-rw-r--r--base/loader/symtab.cc28
-rw-r--r--base/loader/symtab.hh28
-rw-r--r--cpu/exetrace.cc16
-rw-r--r--kern/linux/linux_system.cc2
-rw-r--r--sim/process.cc13
-rw-r--r--sim/system.cc2
8 files changed, 68 insertions, 29 deletions
diff --git a/SConscript b/SConscript
index 7769d0708..3938f792f 100644
--- a/SConscript
+++ b/SConscript
@@ -109,6 +109,7 @@ base_sources = Split('''
cpu/full_cpu/issue.cc
cpu/full_cpu/ls_queue.cc
cpu/full_cpu/machine_queue.cc
+ cpu/full_cpu/pc_sample_profile.cc
cpu/full_cpu/pipetrace.cc
cpu/full_cpu/readyq.cc
cpu/full_cpu/reg_info.cc
diff --git a/base/callback.hh b/base/callback.hh
index 342ab7e0f..cc2a2f429 100644
--- a/base/callback.hh
+++ b/base/callback.hh
@@ -32,7 +32,7 @@
#include <list>
/**
- * Generic callback class. This base class provides a virutal process
+ * Generic callback class. This base class provides a virtual process
* function that gets called when the callback queue is processed.
*/
class Callback
@@ -103,6 +103,8 @@ class CallbackQueue
}
};
+/// Helper template class to turn a simple class member function into
+/// a callback.
template <class T, void (T::* F)()>
class MakeCallback : public Callback
{
@@ -111,8 +113,9 @@ class MakeCallback : public Callback
public:
MakeCallback(T *o)
- : object(o)
+ : object(o)
{ }
+
void process() { (object->*F)(); }
};
diff --git a/base/loader/symtab.cc b/base/loader/symtab.cc
index f6abf7e3d..c018ae4f8 100644
--- a/base/loader/symtab.cc
+++ b/base/loader/symtab.cc
@@ -38,6 +38,8 @@
using namespace std;
+SymbolTable *debugSymbolTable = NULL;
+
bool
SymbolTable::insert(Addr address, string symbol)
{
@@ -95,26 +97,20 @@ SymbolTable::load(const string &filename)
}
bool
-SymbolTable::findNearestSymbol(Addr address, string &symbol) const
+SymbolTable::findNearestSymbol(Addr address, string &symbol,
+ Addr &sym_address, Addr &next_sym_address) const
{
- ATable::const_iterator i = addrTable.lower_bound(address);
-
- // check for PALCode
- if (address & 0x1)
- return false;
+ // find first key *larger* than desired address
+ ATable::const_iterator i = addrTable.upper_bound(address);
- // first check for the end
- if (i == addrTable.end())
- i--;
- else if (i == addrTable.begin() && (*i).first != address)
+ // if very first key is larger, we're out of luck
+ if (i == addrTable.begin())
return false;
- else if ((*i).first != address)
- i--;
-
- symbol = (*i).second;
- if (address != (*i).first)
- symbol += csprintf("+%d", address - (*i).first);
+ next_sym_address = i->first;
+ --i;
+ sym_address = i->first;
+ symbol = i->second;
return true;
}
diff --git a/base/loader/symtab.hh b/base/loader/symtab.hh
index 48230c7a2..df3783991 100644
--- a/base/loader/symtab.hh
+++ b/base/loader/symtab.hh
@@ -49,7 +49,27 @@ class SymbolTable
bool insert(Addr address, std::string symbol);
bool load(const std::string &file);
- bool findNearestSymbol(Addr address, std::string &symbol) const;
+ /// Find the nearest symbol equal to or less than the supplied
+ /// address (e.g., the label for the enclosing function).
+ /// @param address The address to look up.
+ /// @param symbol Return reference for symbol string.
+ /// @param sym_address Return reference for symbol address.
+ /// @param next_sym_address Address of following symbol (for
+ /// determining valid range of symbol).
+ /// @retval True if a symbol was found.
+ bool findNearestSymbol(Addr address, std::string &symbol,
+ Addr &sym_address, Addr &next_sym_address) const;
+
+ /// Overload for findNearestSymbol() for callers who don't care
+ /// about next_sym_address.
+ bool findNearestSymbol(Addr address, std::string &symbol,
+ Addr &sym_address) const
+ {
+ Addr dummy;
+ return findNearestSymbol(address, symbol, sym_address, dummy);
+ }
+
+
bool findSymbol(Addr address, std::string &symbol) const;
bool findAddress(const std::string &symbol, Addr &address) const;
@@ -57,4 +77,10 @@ class SymbolTable
Addr find(const std::string &symbol) const;
};
+/// Global unified debugging symbol table (for target). Conceptually
+/// there should be one of these per System object for full system,
+/// and per Process object for non-full-system, but so far one big
+/// global one has worked well enough.
+extern SymbolTable *debugSymbolTable;
+
#endif // __SYMTAB_HH__
diff --git a/cpu/exetrace.cc b/cpu/exetrace.cc
index e31c3590c..58fb7d668 100644
--- a/cpu/exetrace.cc
+++ b/cpu/exetrace.cc
@@ -48,8 +48,6 @@ using namespace std;
//
-SymbolTable *debugSymbolTable = NULL;
-
void
Trace::InstRecord::dump(ostream &outs)
{
@@ -66,11 +64,17 @@ Trace::InstRecord::dump(ostream &outs)
outs << "T" << thread << " : ";
- std::string str;
- if ((debugSymbolTable) && (debugSymbolTable->findNearestSymbol(PC, str)))
- outs << "@" << setw(17) << str << " : ";
- else
+ std::string sym_str;
+ Addr sym_addr;
+ if (debugSymbolTable
+ && debugSymbolTable->findNearestSymbol(PC, sym_str, sym_addr)) {
+ if (PC != sym_addr)
+ sym_str += csprintf("+%d", addr - sym_addr);
+ outs << "@" << setw(17) << sym_str << " : ";
+ }
+ else {
outs << "0x" << hex << PC << " : ";
+ }
//
// Print decoded instruction
diff --git a/kern/linux/linux_system.cc b/kern/linux/linux_system.cc
index 12bfafd6b..c5d35a4fc 100644
--- a/kern/linux/linux_system.cc
+++ b/kern/linux/linux_system.cc
@@ -49,8 +49,6 @@
#include "targetarch/vtophys.hh"
#include "sim/debug.hh"
-extern SymbolTable *debugSymbolTable;
-
using namespace std;
LinuxSystem::LinuxSystem(Params *p)
diff --git a/sim/process.cc b/sim/process.cc
index 98db1f2e0..bd1a2d8fd 100644
--- a/sim/process.cc
+++ b/sim/process.cc
@@ -34,6 +34,7 @@
#include "base/intmath.hh"
#include "base/loader/object_file.hh"
+#include "base/loader/symtab.hh"
#include "base/statistics.hh"
#include "cpu/exec_context.hh"
#include "cpu/full_cpu/smt.hh"
@@ -263,6 +264,18 @@ LiveProcess::LiveProcess(const string &name, ObjectFile *objFile,
// load object file into target memory
objFile->loadSections(memory);
+ // load up symbols, if any... these may be used for debugging or
+ // profiling.
+ if (!debugSymbolTable) {
+ debugSymbolTable = new SymbolTable();
+ if (!objFile->loadGlobalSymbols(debugSymbolTable) ||
+ !objFile->loadLocalSymbols(debugSymbolTable)) {
+ // didn't load any symbols
+ delete debugSymbolTable;
+ debugSymbolTable = NULL;
+ }
+ }
+
// Set up stack. On Alpha, stack goes below text section. This
// code should get moved to some architecture-specific spot.
stack_base = text_base - (409600+4096);
diff --git a/sim/system.cc b/sim/system.cc
index 1b1a145c6..c6a65f9d9 100644
--- a/sim/system.cc
+++ b/sim/system.cc
@@ -44,8 +44,6 @@ vector<System *> System::systemList;
int System::numSystemsRunning = 0;
-extern SymbolTable *debugSymbolTable;
-
System::System(Params *p)
: SimObject(p->name), memctrl(p->memctrl), physmem(p->physmem),
init_param(p->init_param), params(p)