arch,base,cpu,kern,sim: Encapsulate symbols in a class.

The SymbolTable class had been tracking symbols as two independent
pieces, a name and an address, and acted as a way to translate between
them. Symbols can be more complex than that, and so this change
encapsulates the information associated with a symbol in a new class.

As a step towards simplifying the API for reading symbols from a
binary, this change also adds a "binding" field to that class so that
global, local and weak symbols can all go in the same table and be
differentiated later as needed. That should unify the current API
which has a method for each symbol type.

While the innards of SymbolTable were being reworked, this change
also makes that class more STL like by adding iterators, and begin
and end methods. These iterate over a new vector which holds all the
symbols. The address and name keyed maps now hold indexes into that
vector instead of the other half of the symbol.

Change-Id: I8084f86fd737f697ec041bac86a635a315fd1194
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/24784
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Gabe Black
2020-01-21 05:44:00 -08:00
parent fd580041fe
commit c5b2b8e19f
23 changed files with 274 additions and 239 deletions

View File

@@ -88,8 +88,7 @@ FsFreebsd::initState()
// Check if the kernel image has a symbol that tells us it supports
// device trees.
Addr addr;
fatal_if(!kernelSymtab->findAddress("fdt_get_range", addr),
fatal_if(kernelSymtab->find("fdt_get_range") == kernelSymtab->end(),
"Kernel must have fdt support.");
fatal_if(params()->dtb_filename == "", "dtb file is not specified.");

View File

@@ -393,18 +393,19 @@ void
ArmStaticInst::printTarget(std::ostream &os, Addr target,
const Loader::SymbolTable *symtab) const
{
Addr symbolAddr;
std::string symbol;
if (symtab && symtab->findNearestSymbol(target, symbol, symbolAddr)) {
ccprintf(os, "<%s", symbol);
if (symbolAddr != target)
ccprintf(os, "+%d>", target - symbolAddr);
else
ccprintf(os, ">");
} else {
ccprintf(os, "%#x", target);
if (symtab) {
auto it = symtab->findNearest(target);
if (it != symtab->end()) {
ccprintf(os, "<%s", it->name);
Addr delta = target - it->address;
if (delta)
ccprintf(os, "+%d>", delta);
else
ccprintf(os, ">");
return;
}
}
ccprintf(os, "%#x", target);
}
void
@@ -477,13 +478,14 @@ ArmStaticInst::printMemSymbol(std::ostream &os,
const Addr addr,
const std::string &suffix) const
{
Addr symbolAddr;
std::string symbol;
if (symtab && symtab->findNearestSymbol(addr, symbol, symbolAddr)) {
ccprintf(os, "%s%s", prefix, symbol);
if (symbolAddr != addr)
ccprintf(os, "+%d", addr - symbolAddr);
ccprintf(os, suffix);
if (symtab) {
auto it = symtab->findNearest(addr);
if (it != symtab->end()) {
ccprintf(os, "%s%s", prefix, it->name);
if (it->address != addr)
ccprintf(os, "+%d", addr - it->address);
ccprintf(os, suffix);
}
}
}

View File

@@ -82,11 +82,10 @@ FsLinux::initState()
}
// Setup boot data structure
Addr addr;
// Check if the kernel image has a symbol that tells us it supports
// device trees.
bool kernel_has_fdt_support =
kernelSymtab->findAddress("unflatten_device_tree", addr);
kernelSymtab->find("unflatten_device_tree") != kernelSymtab->end();
bool dtb_file_specified = params()->dtb_filename != "";
if (kernel_has_fdt_support && dtb_file_specified) {

View File

@@ -47,11 +47,10 @@ readSymbol(ThreadContext *tc, const std::string name)
PortProxy &vp = tc->getVirtProxy();
const auto *symtab = tc->getSystemPtr()->workload->symtab(tc);
Addr addr;
if (!symtab->findAddress(name, addr))
panic("thread info not compiled into kernel\n");
auto it = symtab->find(name);
panic_if(it == symtab->end(), "Thread info not compiled into kernel.");
return vp.read<int32_t>(addr, GuestByteOrder);
return vp.read<int32_t>(it->address, GuestByteOrder);
}
ProcessInfo::ProcessInfo(ThreadContext *_tc) : tc(_tc)

View File

@@ -46,15 +46,16 @@ class ThreadInfo
bool
get_data(const char *symbol, T &data)
{
Addr addr = 0;
if (!sys->workload->symtab(tc)->findAddress(symbol, addr)) {
auto *symtab = sys->workload->symtab(tc);
auto it = symtab->find(symbol);
if (it == symtab->end()) {
warn_once("Unable to find kernel symbol %s\n", symbol);
warn_once("Kernel not compiled with task_struct info; can't get "
"currently executing task/process/thread name/ids!\n");
return false;
}
data = tc->getVirtProxy().read<T>(addr, TheISA::GuestByteOrder);
data = tc->getVirtProxy().read<T>(it->address, TheISA::GuestByteOrder);
return true;
}

View File

@@ -193,11 +193,11 @@ output decoder {{
Addr target = pc + 4 + disp;
std::string str;
if (symtab && symtab->findSymbol(target, str))
ss << str;
Loader::SymbolTable::const_iterator it;
if (symtab && (it = symtab->find(target)) != symtab->end())
ss << it->name;
else
ccprintf(ss, "0x%x", target);
ccprintf(ss, "%#x", target);
return ss.str();
}
@@ -213,9 +213,9 @@ output decoder {{
Addr npc = pc + 4;
ccprintf(ss,"0x%x",(npc & 0xF0000000) | disp);
} else if (_numSrcRegs == 0) {
std::string str;
if (symtab && symtab->findSymbol(disp, str))
ss << str;
Loader::SymbolTable::const_iterator it;
if (symtab && (it = symtab->find(disp)) != symtab->end())
ss << it->name;
else
ccprintf(ss, "0x%x", disp);
} else if (_numSrcRegs == 1) {

View File

@@ -68,11 +68,11 @@ BranchPCRel::generateDisassembly(
Addr target = pc + disp;
std::string str;
if (symtab && symtab->findSymbol(target, str))
ss << str;
Loader::SymbolTable::const_iterator it;
if (symtab && (it = symtab->find(target)) != symtab->end())
ss << it->name;
else
ccprintf(ss, "0x%x", target);
ccprintf(ss, "%#x", target);
return ss.str();
}
@@ -91,11 +91,11 @@ BranchNonPCRel::generateDisassembly(
ccprintf(ss, "%-10s ", mnemonic);
std::string str;
if (symtab && symtab->findSymbol(targetAddr, str))
ss << str;
Loader::SymbolTable::const_iterator it;
if (symtab && (it = symtab->find(targetAddr)) != symtab->end())
ss << it->name;
else
ccprintf(ss, "0x%x", targetAddr);
ccprintf(ss, "%#x", targetAddr);
return ss.str();
}
@@ -118,11 +118,11 @@ BranchPCRelCond::generateDisassembly(
Addr target = pc + disp;
std::string str;
if (symtab && symtab->findSymbol(target, str))
ss << str;
Loader::SymbolTable::const_iterator it;
if (symtab && (it = symtab->find(target)) != symtab->end())
ss << it->name;
else
ccprintf(ss, "0x%x", target);
ccprintf(ss, "%#x", target);
return ss.str();
}
@@ -143,11 +143,11 @@ BranchNonPCRelCond::generateDisassembly(
ss << bo << ", " << bi << ", ";
std::string str;
if (symtab && symtab->findSymbol(targetAddr, str))
ss << str;
Loader::SymbolTable::const_iterator it;
if (symtab && (it = symtab->find(targetAddr)) != symtab->end())
ss << it->name;
else
ccprintf(ss, "0x%x", targetAddr);
ccprintf(ss, "%#x", targetAddr);
return ss.str();
}

View File

@@ -55,9 +55,9 @@ class BareMetal : public RiscvISA::FsWorkload
return bootloaderSymtab;
}
bool
insertSymbol(Addr address, const std::string &symbol) override
insertSymbol(const Loader::Symbol &symbol) override
{
return bootloaderSymtab->insert(address, symbol);
return bootloaderSymtab->insert(symbol);
}
};

View File

@@ -61,9 +61,9 @@ class FsWorkload : public Workload
}
bool
insertSymbol(Addr address, const std::string &symbol) override
insertSymbol(const Loader::Symbol &symbol) override
{
return defaultSymtab.insert(address, symbol);
return defaultSymtab.insert(symbol);
}
};

View File

@@ -77,18 +77,17 @@ BranchDisp::generateDisassembly(
Addr pc, const Loader::SymbolTable *symtab) const
{
std::stringstream response;
std::string symbol;
Addr symbol_addr;
Addr target = disp + pc;
printMnemonic(response, mnemonic);
ccprintf(response, "0x%x", target);
ccprintf(response, "%#x", target);
if (symtab && symtab->findNearestSymbol(target, symbol, symbol_addr)) {
ccprintf(response, " <%s", symbol);
if (symbol_addr != target)
ccprintf(response, "+%d>", target - symbol_addr);
Loader::SymbolTable::const_iterator it;
if (symtab && (it = symtab->findNearest(target)) != symtab->end()) {
ccprintf(response, " <%s", it->name);
if (it->address != target)
ccprintf(response, "+%d>", target - it->address);
else
ccprintf(response, ">");
}

View File

@@ -47,11 +47,10 @@ readSymbol(ThreadContext *tc, const std::string name)
PortProxy &vp = tc->getVirtProxy();
const auto *symtab = tc->getSystemPtr()->workload->symtab(tc);
Addr addr;
if (!symtab->findAddress(name, addr))
panic("thread info not compiled into kernel\n");
auto it = symtab->find(name);
panic_if(it == symtab->end(), "Thread info not compiled into kernel.");
return vp.read<int32_t>(addr, GuestByteOrder);
return vp.read<int32_t>(it->address, GuestByteOrder);
}
ProcessInfo::ProcessInfo(ThreadContext *_tc) : tc(_tc)
@@ -196,14 +195,15 @@ StackTrace::dump()
std::string symbol;
for (int i = 0, size = stack.size(); i < size; ++i) {
Addr addr = stack[size - i - 1];
Loader::SymbolTable::const_iterator it;
if (addr == user)
symbol = "user";
else if (addr == console)
symbol = "console";
else if (addr == unknown)
symbol = "unknown";
else
symtab->findSymbol(addr, symbol);
else if ((it = symtab->find(addr)) != symtab->end())
symbol = it->name;
DPRINTFN("%#x: %s\n", addr, symbol);
}

View File

@@ -341,7 +341,23 @@ ElfObject::loadSomeSymbols(SymbolTable *symtab, int binding, Addr mask,
elf_strptr(elf, shdr.sh_link, sym.st_name);
if (sym_name && sym_name[0] != '$') {
Addr value = sym.st_value - base + offset;
if (symtab->insert(value & mask, sym_name)) {
Loader::Symbol symbol;
symbol.address = value & mask;
symbol.name = sym_name;
switch (binding) {
case STB_GLOBAL:
symbol.binding = Loader::Symbol::Binding::Global;
break;
case STB_LOCAL:
symbol.binding = Loader::Symbol::Binding::Local;
break;
case STB_WEAK:
symbol.binding = Loader::Symbol::Binding::Weak;
break;
default:
panic("Unrecognized binding type");
}
if (symtab->insert(symbol)) {
DPRINTF(Loader, "Symbol: %-40s value %#x\n",
sym_name, value);
}

View File

@@ -35,6 +35,7 @@
#include "base/logging.hh"
#include "base/str.hh"
#include "base/trace.hh"
#include "base/types.hh"
#include "sim/serialize.hh"
@@ -48,26 +49,48 @@ SymbolTable *debugSymbolTable = NULL;
void
SymbolTable::clear()
{
addrTable.clear();
symbolTable.clear();
addrMap.clear();
nameMap.clear();
symbols.clear();
}
bool
SymbolTable::insert(Addr address, string symbol)
SymbolTable::insert(const Symbol &symbol)
{
if (symbol.empty())
if (symbol.name.empty())
return false;
if (!symbolTable.insert(make_pair(symbol, address)).second)
int idx = symbols.size();
if (!nameMap.insert({ symbol.name, idx }).second)
return false;
// There can be multiple symbols for the same address, so always
// update the addrTable multimap when we see a new symbol name.
addrTable.insert(make_pair(address, symbol));
addrMap.insert({ symbol.address, idx });
symbols.emplace_back(symbol);
return true;
}
bool
SymbolTable::insert(const SymbolTable &other)
{
// Check if any symbol in other already exists in our table.
NameMap intersection;
std::set_intersection(other.nameMap.begin(), other.nameMap.end(),
nameMap.begin(), nameMap.end(),
std::inserter(intersection, intersection.begin()),
nameMap.value_comp());
if (!intersection.empty())
return false;
for (const Symbol &symbol: other)
insert(symbol);
return true;
}
bool
SymbolTable::load(const string &filename)
@@ -92,51 +115,54 @@ SymbolTable::load(const string &filename)
if (address.empty())
return false;
string symbol = buffer.substr(idx + 1);
eat_white(symbol);
if (symbol.empty())
string name = buffer.substr(idx + 1);
eat_white(name);
if (name.empty())
return false;
Addr addr;
if (!to_number(address, addr))
return false;
if (!insert(addr, symbol))
if (!insert({ Symbol::Binding::Global, name, addr }))
return false;
}
file.close();
return true;
}
void
SymbolTable::serialize(const string &base, CheckpointOut &cp) const
{
paramOut(cp, base + ".size", addrTable.size());
paramOut(cp, base + ".size", symbols.size());
int i = 0;
ATable::const_iterator p, end = addrTable.end();
for (p = addrTable.begin(); p != end; ++p) {
paramOut(cp, csprintf("%s.addr_%d", base, i), p->first);
paramOut(cp, csprintf("%s.symbol_%d", base, i), p->second);
++i;
for (auto &symbol: symbols) {
paramOut(cp, csprintf("%s.addr_%d", base, i), symbol.address);
paramOut(cp, csprintf("%s.symbol_%d", base, i), symbol.name);
paramOut(cp, csprintf("%s.binding_%d", base, i), (int)symbol.binding);
i++;
}
}
void
SymbolTable::unserialize(const string &base, CheckpointIn &cp)
SymbolTable::unserialize(const string &base, CheckpointIn &cp,
Symbol::Binding default_binding)
{
clear();
int size;
paramIn(cp, base + ".size", size);
for (int i = 0; i < size; ++i) {
Addr addr;
std::string symbol;
Addr address;
std::string name;
Symbol::Binding binding = default_binding;
paramIn(cp, csprintf("%s.addr_%d", base, i), addr);
paramIn(cp, csprintf("%s.symbol_%d", base, i), symbol);
insert(addr, symbol);
paramIn(cp, csprintf("%s.addr_%d", base, i), address);
paramIn(cp, csprintf("%s.symbol_%d", base, i), name);
if (!optParamIn(cp, csprintf("%s.binding_%d", base, i), binding))
binding = default_binding;
insert({binding, name, address});
}
}

View File

@@ -32,140 +32,123 @@
#include <iosfwd>
#include <map>
#include <string>
#include <vector>
#include "base/trace.hh"
#include "base/types.hh"
#include "sim/serialize.hh"
namespace Loader
{
struct Symbol
{
enum class Binding {
Global,
Local,
Weak
};
Binding binding;
std::string name;
Addr address;
};
class SymbolTable
{
public:
typedef std::multimap<Addr, std::string> ATable;
typedef std::map<std::string, Addr> STable;
private:
ATable addrTable;
STable symbolTable;
typedef std::vector<Symbol> SymbolVector;
// Map addresses to an index into the symbol vector.
typedef std::multimap<Addr, int> AddrMap;
// Map a symbol name to an index into the symbol vector.
typedef std::map<std::string, int> NameMap;
SymbolVector symbols;
AddrMap addrMap;
NameMap nameMap;
private:
bool
upperBound(Addr addr, ATable::const_iterator &iter) const
upperBound(Addr addr, AddrMap::const_iterator &iter) const
{
// find first key *larger* than desired address
iter = addrTable.upper_bound(addr);
iter = addrMap.upper_bound(addr);
// if very first key is larger, we're out of luck
if (iter == addrTable.begin())
if (iter == addrMap.begin())
return false;
return true;
}
public:
SymbolTable() {}
SymbolTable(const std::string &file) { load(file); }
~SymbolTable() {}
typedef SymbolVector::iterator iterator;
typedef SymbolVector::const_iterator const_iterator;
const_iterator begin() const { return symbols.begin(); }
const_iterator end() const { return symbols.end(); }
void clear();
bool insert(Addr address, std::string symbol);
// Insert either a single symbol or the contents of an entire symbol table
// into this one.
bool insert(const Symbol &symbol);
bool insert(const SymbolTable &other);
bool load(const std::string &file);
const ATable &getAddrTable() const { return addrTable; }
const STable &getSymbolTable() const { return symbolTable; }
public:
void serialize(const std::string &base, CheckpointOut &cp) const;
void unserialize(const std::string &base, CheckpointIn &cp);
void unserialize(const std::string &base, CheckpointIn &cp,
Symbol::Binding default_binding=Symbol::Binding::Global);
public:
bool
findSymbol(Addr address, std::string &symbol) const
const_iterator
find(Addr address) const
{
ATable::const_iterator i = addrTable.find(address);
if (i == addrTable.end())
return false;
AddrMap::const_iterator i = addrMap.find(address);
if (i == addrMap.end())
return end();
// There are potentially multiple symbols that map to the same
// address. For simplicity, just return the first one.
symbol = (*i).second;
return true;
return symbols.begin() + i->second;
}
bool
findAddress(const std::string &symbol, Addr &address) const
const_iterator
find(const std::string &name) const
{
STable::const_iterator i = symbolTable.find(symbol);
if (i == symbolTable.end())
return false;
NameMap::const_iterator i = nameMap.find(name);
if (i == nameMap.end())
return end();
address = (*i).second;
return true;
return symbols.begin() + i->second;
}
/// Find the nearest symbol equal to or less than the supplied
/// address (e.g., the label for the enclosing function).
/// @param addr The address to look up.
/// @param symbol Return reference for symbol string.
/// @param symaddr Return reference for symbol address.
/// @param nextaddr Address of following symbol (for
/// determining valid range of symbol).
/// @retval True if a symbol was found.
bool
findNearestSymbol(Addr addr, std::string &symbol, Addr &symaddr,
Addr &nextaddr) const
/// @retval A const_iterator which points to the symbol if found, or end.
const_iterator
findNearest(Addr addr, Addr &nextaddr) const
{
ATable::const_iterator i;
AddrMap::const_iterator i = addrMap.end();
if (!upperBound(addr, i))
return false;
return end();
nextaddr = i->first;
--i;
symaddr = i->first;
symbol = i->second;
return true;
return symbols.begin() + i->second;
}
/// Overload for findNearestSymbol() for callers who don't care
/// about nextaddr.
bool
findNearestSymbol(Addr addr, std::string &symbol, Addr &symaddr) const
const_iterator
findNearest(Addr addr) const
{
ATable::const_iterator i;
AddrMap::const_iterator i = addrMap.end();
if (!upperBound(addr, i))
return false;
return end();
--i;
symaddr = i->first;
symbol = i->second;
return true;
}
bool
findNearestAddr(Addr addr, Addr &symaddr, Addr &nextaddr) const
{
ATable::const_iterator i;
if (!upperBound(addr, i))
return false;
nextaddr = i->first;
--i;
symaddr = i->first;
return true;
}
bool
findNearestAddr(Addr addr, Addr &symaddr) const
{
ATable::const_iterator i;
if (!upperBound(addr, i))
return false;
--i;
symaddr = i->first;
return true;
return symbols.begin() + i->second;
}
};

View File

@@ -757,15 +757,18 @@ BaseCPU::traceFunctionsInternal(Addr pc)
// if pc enters different function, print new function symbol and
// update saved range. Otherwise do nothing.
if (pc < currentFunctionStart || pc >= currentFunctionEnd) {
string sym_str;
bool found = Loader::debugSymbolTable->findNearestSymbol(
pc, sym_str, currentFunctionStart, currentFunctionEnd);
auto it = Loader::debugSymbolTable->findNearest(
pc, currentFunctionEnd);
if (!found) {
string sym_str;
if (it == Loader::debugSymbolTable->end()) {
// no symbol found: use addr as label
sym_str = csprintf("0x%x", pc);
sym_str = csprintf("%#x", pc);
currentFunctionStart = pc;
currentFunctionEnd = pc + 1;
} else {
sym_str = it->name;
currentFunctionStart = it->address;
}
ccprintf(*functionTraceStream, " (%d)\n%d: %s",

View File

@@ -76,27 +76,28 @@ Trace::ExeTracerRecord::traceInst(const StaticInstPtr &inst, bool ran)
if (Debug::ExecThread)
outs << "T" << thread->threadId() << " : ";
std::string sym_str;
Addr sym_addr;
Addr cur_pc = pc.instAddr();
Loader::SymbolTable::const_iterator it;
if (Loader::debugSymbolTable && Debug::ExecSymbol &&
(!FullSystem || !inUserMode(thread)) &&
Loader::debugSymbolTable->findNearestSymbol(
cur_pc, sym_str, sym_addr)) {
if (cur_pc != sym_addr)
sym_str += csprintf("+%d",cur_pc - sym_addr);
outs << "@" << sym_str;
(it = Loader::debugSymbolTable->findNearest(cur_pc)) !=
Loader::debugSymbolTable->end()) {
Addr delta = cur_pc - it->address;
if (delta)
ccprintf(outs, "@%s+%d", it->name, delta);
else
ccprintf(outs, "@%s", it->name);
} else {
outs << "0x" << hex << cur_pc;
ccprintf(outs, "%#x", cur_pc);
}
if (inst->isMicroop()) {
outs << "." << setw(2) << dec << pc.microPC();
ccprintf(outs, ".%2d", pc.microPC());
} else {
outs << " ";
ccprintf(outs, " ");
}
outs << " : ";
ccprintf(outs, " : ");
//
// Print decoded instruction

View File

@@ -57,6 +57,7 @@ ProfileNode::dump(const string &symbol, uint64_t id,
ccprintf(os, "\n");
Loader::SymbolTable::const_iterator it;
for (i = children.begin(); i != end; ++i) {
Addr addr = i->first;
string symbol;
@@ -66,7 +67,9 @@ ProfileNode::dump(const string &symbol, uint64_t id,
symbol = "console";
else if (addr == 3)
symbol = "unknown";
else if (!symtab->findSymbol(addr, symbol))
else if ((it = symtab->find(addr)) != symtab->end())
symbol = it->name;
else
panic("could not find symbol for address %#x\n", addr);
const ProfileNode *node = i->second;
@@ -127,13 +130,15 @@ FunctionProfile::dump(ThreadContext *tc, ostream &os) const
Addr pc = i->first;
Counter count = i->second;
std::string symbol;
if (pc == 1)
Loader::SymbolTable::const_iterator it;
if (pc == 1) {
ccprintf(os, "user %d\n", count);
else if (symtab->findSymbol(pc, symbol) && !symbol.empty())
ccprintf(os, "%s %d\n", symbol, count);
else
} else if ((it = symtab->find(pc)) != symtab->end() &&
!it->name.empty()) {
ccprintf(os, "%s %d\n", it->name, count);
} else {
ccprintf(os, "%#x %d\n", pc, count);
}
}
ccprintf(os, ">>>function data\n");
@@ -145,9 +150,9 @@ FunctionProfile::sample(ProfileNode *node, Addr pc)
{
node->count++;
Addr symaddr;
if (symtab->findNearestAddr(pc, symaddr)) {
pc_count[symaddr]++;
auto it = symtab->findNearest(pc);
if (it != symtab->end()) {
pc_count[it->address]++;
} else {
// record PC even if we don't have a symbol to avoid
// silently biasing the histogram

View File

@@ -96,24 +96,25 @@ Linux::dumpDmesg(ThreadContext *tc, std::ostream &os)
const auto *symtab = system->workload->symtab(tc);
PortProxy &proxy = tc->getVirtProxy();
Addr addr_lb = 0, addr_lb_len = 0, addr_first = 0, addr_next = 0;
const bool found_symbols =
symtab->findAddress("__log_buf", addr_lb) &&
symtab->findAddress("log_buf_len", addr_lb_len) &&
symtab->findAddress("log_first_idx", addr_first) &&
symtab->findAddress("log_next_idx", addr_next);
auto lb = symtab->find("__log_buf");
auto lb_len = symtab->find("log_buf_len");
auto first = symtab->find("log_first_idx");
auto next = symtab->find("log_next_idx");
if (!found_symbols) {
auto end_it = symtab->end();
if (lb == end_it || lb_len == end_it ||
first == end_it || next == end_it) {
warn("Failed to find kernel dmesg symbols.\n");
return;
}
uint32_t log_buf_len =
proxy.read<uint32_t>(addr_lb_len, TheISA::GuestByteOrder);
proxy.read<uint32_t>(lb_len->address, TheISA::GuestByteOrder);
uint32_t log_first_idx =
proxy.read<uint32_t>(addr_first, TheISA::GuestByteOrder);
proxy.read<uint32_t>(first->address, TheISA::GuestByteOrder);
uint32_t log_next_idx =
proxy.read<uint32_t>(addr_next, TheISA::GuestByteOrder);
proxy.read<uint32_t>(next->address, TheISA::GuestByteOrder);
if (log_first_idx >= log_buf_len || log_next_idx >= log_buf_len) {
warn("dmesg pointers/length corrupted\n");
@@ -129,7 +130,7 @@ Linux::dumpDmesg(ThreadContext *tc, std::ostream &os)
warn("Unexpected dmesg buffer length\n");
return;
}
proxy.readBlob(addr_lb + log_first_idx, log_buf.data(), length);
proxy.readBlob(lb->address + log_first_idx, log_buf.data(), length);
} else {
const int length_2 = log_buf_len - log_first_idx;
if (length_2 < 0 || length_2 + log_next_idx > log_buf.size()) {
@@ -137,8 +138,8 @@ Linux::dumpDmesg(ThreadContext *tc, std::ostream &os)
return;
}
length = log_buf_len;
proxy.readBlob(addr_lb + log_first_idx, log_buf.data(), length_2);
proxy.readBlob(addr_lb, log_buf.data() + length_2, log_next_idx);
proxy.readBlob(lb->address + log_first_idx, log_buf.data(), length_2);
proxy.readBlob(lb->address, log_buf.data() + length_2, log_next_idx);
}
// Print dmesg buffer content

View File

@@ -98,9 +98,9 @@ class KernelWorkload : public Workload
}
bool
insertSymbol(Addr address, const std::string &symbol) override
insertSymbol(const Loader::Symbol &symbol) override
{
return kernelSymtab->insert(address, symbol);
return kernelSymtab->insert(symbol);
}
void initState() override;

View File

@@ -241,8 +241,10 @@ loadsymbol(ThreadContext *tc)
if (!to_number(address, addr))
continue;
if (!tc->getSystemPtr()->workload->insertSymbol(addr, symbol))
if (!tc->getSystemPtr()->workload->insertSymbol(
{ Loader::Symbol::Binding::Global, symbol, addr })) {
continue;
}
DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
@@ -263,8 +265,10 @@ addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr)
DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
tc->getSystemPtr()->workload->insertSymbol(addr, symbol);
Loader::debugSymbolTable->insert(addr, symbol);
tc->getSystemPtr()->workload->insertSymbol(
{ Loader::Symbol::Binding::Global, symbol, addr });
Loader::debugSymbolTable->insert(
{ Loader::Symbol::Binding::Global, symbol, addr });
}
uint64_t

View File

@@ -50,7 +50,7 @@ class Workload : public SimObject
virtual Loader::Arch getArch() const = 0;
virtual const Loader::SymbolTable *symtab(ThreadContext *tc) = 0;
virtual bool insertSymbol(Addr address, const std::string &symbol) = 0;
virtual bool insertSymbol(const Loader::Symbol &symbol) = 0;
/** @{ */
/**
@@ -70,14 +70,12 @@ class Workload : public SimObject
addFuncEvent(const Loader::SymbolTable *symtab, const char *lbl,
const std::string &desc, Args... args)
{
Addr addr M5_VAR_USED = 0; // initialize only to avoid compiler warning
auto it = symtab->find(lbl);
if (it == symtab->end())
return nullptr;
if (symtab->findAddress(lbl, addr)) {
return new T(system, desc, fixFuncEventAddr(addr),
std::forward<Args>(args)...);
}
return nullptr;
return new T(system, desc, fixFuncEventAddr(it->address),
std::forward<Args>(args)...);
}
template <class T>

View File

@@ -52,27 +52,24 @@ main(int argc, char *argv[])
obj->loadLocalSymbols(&symtab);
if (argc == 2) {
Loader::SymbolTable::ATable::const_iterator i =
symtab.getAddrTable().begin();
Loader::SymbolTable::ATable::const_iterator end =
symtab.getAddrTable().end();
while (i != end) {
cprintf("%#x %s\n", i->first, i->second);
++i;
}
for (const Loader::Symbol &symbol: symtab)
cprintf("%#x %s\n", symbol.address, symbol.name);
} else {
string symbol = argv[2];
Addr address;
if (symbol[0] == '0' && symbol[1] == 'x') {
Loader::SymbolTable::const_iterator it;
if (to_number(symbol, address) &&
symtab.findSymbol(address, symbol))
cprintf("address = %#x, symbol = %s\n", address, symbol);
else
(it = symtab.find(address)) != symtab.end()) {
cprintf("address = %#x, symbol = %s\n", address, it->name);
} else {
cprintf("address = %#x was not found\n", address);
}
} else {
if (symtab.findAddress(symbol, address))
cprintf("symbol = %s address = %#x\n", symbol, address);
auto it = symtab.find(symbol);
if (it != symtab.end())
cprintf("symbol = %s address = %#x\n", symbol, it->address);
else
cprintf("symbol = %s was not found\n", symbol);
}

View File

@@ -60,19 +60,21 @@ main(int argc, char *argv[])
Addr address;
if (!to_number(symbol, address)) {
if (!symtab.findAddress(symbol, address)) {
auto it = symtab.find(symbol);
if (it == symtab.end()) {
cout << "could not find symbol: " << symbol << endl;
exit(1);
}
cout << symbol << " -> " << "0x" << hex << address << endl;
cout << symbol << " -> " << "0x" << hex << it->address << endl;
} else {
if (!symtab.findSymbol(address, symbol)) {
auto it = symtab.find(address);
if (it == symtab.end()) {
cout << "could not find address: " << address << endl;
exit(1);
}
cout << "0x" << hex << address << " -> " << symbol<< endl;
cout << "0x" << hex << address << " -> " << it->name << endl;
}
return 0;