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
This commit is contained in:
parent
2e0695ec9a
commit
fed64a3b36
|
@ -109,6 +109,7 @@ base_sources = Split('''
|
||||||
cpu/full_cpu/issue.cc
|
cpu/full_cpu/issue.cc
|
||||||
cpu/full_cpu/ls_queue.cc
|
cpu/full_cpu/ls_queue.cc
|
||||||
cpu/full_cpu/machine_queue.cc
|
cpu/full_cpu/machine_queue.cc
|
||||||
|
cpu/full_cpu/pc_sample_profile.cc
|
||||||
cpu/full_cpu/pipetrace.cc
|
cpu/full_cpu/pipetrace.cc
|
||||||
cpu/full_cpu/readyq.cc
|
cpu/full_cpu/readyq.cc
|
||||||
cpu/full_cpu/reg_info.cc
|
cpu/full_cpu/reg_info.cc
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#include <list>
|
#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.
|
* function that gets called when the callback queue is processed.
|
||||||
*/
|
*/
|
||||||
class Callback
|
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)()>
|
template <class T, void (T::* F)()>
|
||||||
class MakeCallback : public Callback
|
class MakeCallback : public Callback
|
||||||
{
|
{
|
||||||
|
@ -113,6 +115,7 @@ class MakeCallback : public Callback
|
||||||
MakeCallback(T *o)
|
MakeCallback(T *o)
|
||||||
: object(o)
|
: object(o)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void process() { (object->*F)(); }
|
void process() { (object->*F)(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,8 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
SymbolTable *debugSymbolTable = NULL;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
SymbolTable::insert(Addr address, string symbol)
|
SymbolTable::insert(Addr address, string symbol)
|
||||||
{
|
{
|
||||||
|
@ -95,26 +97,20 @@ SymbolTable::load(const string &filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
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);
|
// find first key *larger* than desired address
|
||||||
|
ATable::const_iterator i = addrTable.upper_bound(address);
|
||||||
|
|
||||||
// check for PALCode
|
// if very first key is larger, we're out of luck
|
||||||
if (address & 0x1)
|
if (i == addrTable.begin())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// first check for the end
|
next_sym_address = i->first;
|
||||||
if (i == addrTable.end())
|
--i;
|
||||||
i--;
|
sym_address = i->first;
|
||||||
else if (i == addrTable.begin() && (*i).first != address)
|
symbol = i->second;
|
||||||
return false;
|
|
||||||
else if ((*i).first != address)
|
|
||||||
i--;
|
|
||||||
|
|
||||||
symbol = (*i).second;
|
|
||||||
|
|
||||||
if (address != (*i).first)
|
|
||||||
symbol += csprintf("+%d", address - (*i).first);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,27 @@ class SymbolTable
|
||||||
bool insert(Addr address, std::string symbol);
|
bool insert(Addr address, std::string symbol);
|
||||||
bool load(const std::string &file);
|
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 findSymbol(Addr address, std::string &symbol) const;
|
||||||
bool findAddress(const std::string &symbol, Addr &address) const;
|
bool findAddress(const std::string &symbol, Addr &address) const;
|
||||||
|
|
||||||
|
@ -57,4 +77,10 @@ class SymbolTable
|
||||||
Addr find(const std::string &symbol) const;
|
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__
|
#endif // __SYMTAB_HH__
|
||||||
|
|
|
@ -48,8 +48,6 @@ using namespace std;
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
SymbolTable *debugSymbolTable = NULL;
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Trace::InstRecord::dump(ostream &outs)
|
Trace::InstRecord::dump(ostream &outs)
|
||||||
{
|
{
|
||||||
|
@ -66,11 +64,17 @@ Trace::InstRecord::dump(ostream &outs)
|
||||||
outs << "T" << thread << " : ";
|
outs << "T" << thread << " : ";
|
||||||
|
|
||||||
|
|
||||||
std::string str;
|
std::string sym_str;
|
||||||
if ((debugSymbolTable) && (debugSymbolTable->findNearestSymbol(PC, str)))
|
Addr sym_addr;
|
||||||
outs << "@" << setw(17) << str << " : ";
|
if (debugSymbolTable
|
||||||
else
|
&& 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 << " : ";
|
outs << "0x" << hex << PC << " : ";
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Print decoded instruction
|
// Print decoded instruction
|
||||||
|
|
|
@ -49,8 +49,6 @@
|
||||||
#include "targetarch/vtophys.hh"
|
#include "targetarch/vtophys.hh"
|
||||||
#include "sim/debug.hh"
|
#include "sim/debug.hh"
|
||||||
|
|
||||||
extern SymbolTable *debugSymbolTable;
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
LinuxSystem::LinuxSystem(Params *p)
|
LinuxSystem::LinuxSystem(Params *p)
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
|
|
||||||
#include "base/intmath.hh"
|
#include "base/intmath.hh"
|
||||||
#include "base/loader/object_file.hh"
|
#include "base/loader/object_file.hh"
|
||||||
|
#include "base/loader/symtab.hh"
|
||||||
#include "base/statistics.hh"
|
#include "base/statistics.hh"
|
||||||
#include "cpu/exec_context.hh"
|
#include "cpu/exec_context.hh"
|
||||||
#include "cpu/full_cpu/smt.hh"
|
#include "cpu/full_cpu/smt.hh"
|
||||||
|
@ -263,6 +264,18 @@ LiveProcess::LiveProcess(const string &name, ObjectFile *objFile,
|
||||||
// load object file into target memory
|
// load object file into target memory
|
||||||
objFile->loadSections(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
|
// Set up stack. On Alpha, stack goes below text section. This
|
||||||
// code should get moved to some architecture-specific spot.
|
// code should get moved to some architecture-specific spot.
|
||||||
stack_base = text_base - (409600+4096);
|
stack_base = text_base - (409600+4096);
|
||||||
|
|
|
@ -44,8 +44,6 @@ vector<System *> System::systemList;
|
||||||
|
|
||||||
int System::numSystemsRunning = 0;
|
int System::numSystemsRunning = 0;
|
||||||
|
|
||||||
extern SymbolTable *debugSymbolTable;
|
|
||||||
|
|
||||||
System::System(Params *p)
|
System::System(Params *p)
|
||||||
: SimObject(p->name), memctrl(p->memctrl), physmem(p->physmem),
|
: SimObject(p->name), memctrl(p->memctrl), physmem(p->physmem),
|
||||||
init_param(p->init_param), params(p)
|
init_param(p->init_param), params(p)
|
||||||
|
|
Loading…
Reference in a new issue