arch,base,cpu,kerm,sim: Build a symbol table for object files.

Instead of calling into object files after the fact and asking them to
put symbols into a target symbol table, this change makes object files
fill in a symbol table themselves at construction. Then, that table can
be retrieved and used to fill in aggregate tables, masked, moved,
and/or filtered to have only one type of symbol binding.

This simplifies the symbol management API of the object file types
significantly, and makes it easier to deal with symbol tables alongside
binaries in the FS workload classes.

Change-Id: Ic9006ca432033d72589867c93d9c5f8a1d87f73c
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/24787
Reviewed-by: Bobby R. Bruce <bbruce@ucdavis.edu>
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 19:30:43 -08:00
parent 7f4d6c8388
commit 5da62e6331
22 changed files with 128 additions and 244 deletions

View File

@@ -81,14 +81,14 @@ FsFreebsd::initState()
// to do this permanently, for but early bootup work
// it is helpful.
if (params()->early_kernel_symbols) {
kernelObj->loadGlobalSymbols(kernelSymtab, 0, 0, _loadAddrMask);
kernelObj->loadGlobalSymbols(
&Loader::debugSymbolTable, 0, 0, _loadAddrMask);
auto phys_globals = kernelObj->symtab().globals()->mask(_loadAddrMask);
kernelSymtab.insert(*phys_globals);
Loader::debugSymbolTable.insert(*phys_globals);
}
// Check if the kernel image has a symbol that tells us it supports
// device trees.
fatal_if(kernelSymtab->find("fdt_get_range") == kernelSymtab->end(),
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

@@ -91,7 +91,7 @@ FsWorkload::FsWorkload(Params *p) : KernelWorkload(*p)
"Can't find a matching boot loader / kernel combination!");
if (bootldr)
bootldr->loadGlobalSymbols(&Loader::debugSymbolTable);
Loader::debugSymbolTable.insert(*bootldr->symtab().globals());
}
void

View File

@@ -76,16 +76,16 @@ FsLinux::initState()
// to do this permanently, for but early bootup work
// it is helpful.
if (params()->early_kernel_symbols) {
kernelObj->loadGlobalSymbols(kernelSymtab, 0, 0, _loadAddrMask);
kernelObj->loadGlobalSymbols(
&Loader::debugSymbolTable, 0, 0, _loadAddrMask);
auto phys_globals = kernelObj->symtab().globals()->mask(_loadAddrMask);
kernelSymtab.insert(*phys_globals);
Loader::debugSymbolTable.insert(*phys_globals);
}
// Setup boot data structure
// Check if the kernel image has a symbol that tells us it supports
// device trees.
bool kernel_has_fdt_support =
kernelSymtab->find("unflatten_device_tree") != kernelSymtab->end();
kernelSymtab.find("unflatten_device_tree") != kernelSymtab.end();
bool dtb_file_specified = params()->dtb_filename != "";
if (kernel_has_fdt_support && dtb_file_specified) {

View File

@@ -45,10 +45,10 @@ static int32_t
readSymbol(ThreadContext *tc, const std::string name)
{
PortProxy &vp = tc->getVirtProxy();
const auto *symtab = tc->getSystemPtr()->workload->symtab(tc);
const auto &symtab = tc->getSystemPtr()->workload->symtab(tc);
auto it = symtab->find(name);
panic_if(it == symtab->end(), "Thread info not compiled into kernel.");
auto it = symtab.find(name);
panic_if(it == symtab.end(), "Thread info not compiled into kernel.");
return vp.read<int32_t>(it->address, GuestByteOrder);
}

View File

@@ -46,9 +46,9 @@ class ThreadInfo
bool
get_data(const char *symbol, T &data)
{
auto *symtab = sys->workload->symtab(tc);
auto it = symtab->find(symbol);
if (it == symtab->end()) {
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");

View File

@@ -37,11 +37,11 @@ namespace RiscvISA
{
BareMetal::BareMetal(Params *p) : RiscvISA::FsWorkload(p),
bootloader(Loader::createObjectFile(p->bootloader)),
bootloaderSymtab(new Loader::SymbolTable)
bootloader(Loader::createObjectFile(p->bootloader))
{
fatal_if(!bootloader, "Could not load bootloader file %s.", p->bootloader);
_resetVect = bootloader->entryPoint();
bootloaderSymtab = bootloader->symtab();
}
BareMetal::~BareMetal()

View File

@@ -39,7 +39,7 @@ class BareMetal : public RiscvISA::FsWorkload
{
protected:
Loader::ObjectFile *bootloader;
Loader::SymbolTable *bootloaderSymtab;
Loader::SymbolTable bootloaderSymtab;
public:
typedef RiscvBareMetalParams Params;
@@ -49,7 +49,7 @@ class BareMetal : public RiscvISA::FsWorkload
void initState() override;
Loader::Arch getArch() const override { return bootloader->getArch(); }
const Loader::SymbolTable *
const Loader::SymbolTable &
symtab(ThreadContext *tc) override
{
return bootloaderSymtab;
@@ -57,7 +57,7 @@ class BareMetal : public RiscvISA::FsWorkload
bool
insertSymbol(const Loader::Symbol &symbol) override
{
return bootloaderSymtab->insert(symbol);
return bootloaderSymtab.insert(symbol);
}
};

View File

@@ -54,10 +54,10 @@ class FsWorkload : public Workload
}
Loader::Arch getArch() const override { return Loader::SPARC64; }
const Loader::SymbolTable *
const Loader::SymbolTable &
symtab(ThreadContext *tc) override
{
return &defaultSymtab;
return defaultSymtab;
}
bool

View File

@@ -45,10 +45,10 @@ static int32_t
readSymbol(ThreadContext *tc, const std::string name)
{
PortProxy &vp = tc->getVirtProxy();
const auto *symtab = tc->getSystemPtr()->workload->symtab(tc);
const auto &symtab = tc->getSystemPtr()->workload->symtab(tc);
auto it = symtab->find(name);
panic_if(it == symtab->end(), "Thread info not compiled into kernel.");
auto it = symtab.find(name);
panic_if(it == symtab.end(), "Thread info not compiled into kernel.");
return vp.read<int32_t>(it->address, GuestByteOrder);
}
@@ -188,7 +188,7 @@ void
StackTrace::dump()
{
StringWrap name(tc->getCpuPtr()->name());
const auto *symtab = tc->getSystemPtr()->workload->symtab(tc);
const auto &symtab = tc->getSystemPtr()->workload->symtab(tc);
DPRINTFN("------ Stack ------\n");
@@ -202,7 +202,7 @@ StackTrace::dump()
symbol = "console";
else if (addr == unknown)
symbol = "unknown";
else if ((it = symtab->find(addr)) != symtab->end())
else if ((it = symtab.find(addr)) != symtab.end())
symbol = it->name;
DPRINTFN("%#x: %s\n", addr, symbol);

View File

@@ -132,6 +132,7 @@ ElfObject::ElfObject(ImageFileDataPtr ifd) : ObjectFile(ifd)
ObjectFile *obj = createObjectFile(interp_path);
interpreter = dynamic_cast<ElfObject *>(obj);
assert(interpreter != nullptr);
_symtab.insert(obj->symtab());
}
}
@@ -144,6 +145,61 @@ ElfObject::ElfObject(ImageFileDataPtr ifd) : ObjectFile(ifd)
DPRINTFR(Loader, "%s\n", seg);
// We will actually read the sections when we need to load them
// check that header matches library version
if (elf_version(EV_CURRENT) == EV_NONE)
panic("wrong elf version number!");
// Get the first section
int sec_idx = 1; // there is a 0 but it is nothing, go figure
Elf_Scn *section = elf_getscn(elf, sec_idx);
// While there are no more sections
while (section) {
GElf_Shdr shdr;
gelf_getshdr(section, &shdr);
if (shdr.sh_type == SHT_SYMTAB) {
Elf_Data *data = elf_getdata(section, nullptr);
int count = shdr.sh_size / shdr.sh_entsize;
DPRINTF(Loader, "Found Symbol Table, %d symbols present.", count);
// Loop through all the symbols.
for (int i = 0; i < count; ++i) {
GElf_Sym sym;
gelf_getsym(data, i, &sym);
char *sym_name = elf_strptr(elf, shdr.sh_link, sym.st_name);
if (!sym_name || sym_name[0] == '$')
continue;
Loader::Symbol symbol;
symbol.address = sym.st_value;
symbol.name = sym_name;
switch (GELF_ST_BIND(sym.st_info)) {
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:
continue;
}
if (_symtab.insert(symbol)) {
DPRINTF(Loader, "Symbol: %-40s value %#x.\n",
symbol.name, symbol.address);
}
}
}
++sec_idx;
section = elf_getscn(elf, sec_idx);
}
}
std::string
@@ -300,122 +356,6 @@ ElfObject::~ElfObject()
elf_end(elf);
}
bool
ElfObject::loadSomeSymbols(SymbolTable *symtab, int binding, Addr mask,
Addr base, Addr offset)
{
if (!symtab)
return false;
// check that header matches library version
if (elf_version(EV_CURRENT) == EV_NONE)
panic("wrong elf version number!");
// get a pointer to elf structure
Elf *elf = elf_memory((char *)const_cast<uint8_t *>(
imageData->data()), imageData->len());
assert(elf != NULL);
// Get the first section
int sec_idx = 1; // there is a 0 but it is nothing, go figure
Elf_Scn *section = elf_getscn(elf, sec_idx);
// While there are no more sections
bool found = false;
while (section != NULL) {
GElf_Shdr shdr;
gelf_getshdr(section, &shdr);
if (shdr.sh_type == SHT_SYMTAB) {
found = true;
Elf_Data *data = elf_getdata(section, NULL);
int count = shdr.sh_size / shdr.sh_entsize;
DPRINTF(Loader, "Found Symbol Table, %d symbols present\n", count);
// loop through all the symbols, only loading global ones
for (int i = 0; i < count; ++i) {
GElf_Sym sym;
gelf_getsym(data, i, &sym);
if (GELF_ST_BIND(sym.st_info) == binding) {
char *sym_name =
elf_strptr(elf, shdr.sh_link, sym.st_name);
if (sym_name && sym_name[0] != '$') {
Addr value = sym.st_value - base + offset;
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);
}
}
}
}
}
++sec_idx;
section = elf_getscn(elf, sec_idx);
}
elf_end(elf);
return found;
}
bool
ElfObject::loadAllSymbols(SymbolTable *symtab, Addr base, Addr offset,
Addr addr_mask)
{
return (loadGlobalSymbols(symtab, base, offset, addr_mask) &&
loadLocalSymbols(symtab, base, offset, addr_mask) &&
loadWeakSymbols(symtab, base, offset, addr_mask));
}
bool
ElfObject::loadGlobalSymbols(SymbolTable *symtab, Addr base, Addr offset,
Addr addr_mask)
{
if (interpreter) {
interpreter->loadSomeSymbols(symtab, STB_GLOBAL, addr_mask,
base, offset);
}
return loadSomeSymbols(symtab, STB_GLOBAL, addr_mask, base, offset);
}
bool
ElfObject::loadLocalSymbols(SymbolTable *symtab, Addr base, Addr offset,
Addr addr_mask)
{
if (interpreter) {
interpreter->loadSomeSymbols(symtab, STB_LOCAL, addr_mask,
base, offset);
}
return loadSomeSymbols(symtab, STB_LOCAL, addr_mask, base, offset);
}
bool
ElfObject::loadWeakSymbols(SymbolTable *symtab, Addr base, Addr offset,
Addr addr_mask)
{
if (interpreter) {
interpreter->loadSomeSymbols(symtab, STB_WEAK, addr_mask,
base, offset);
}
return loadSomeSymbols(symtab, STB_WEAK, addr_mask, base, offset);
}
void
ElfObject::getSections()
{

View File

@@ -106,16 +106,6 @@ class ElfObject : public ObjectFile
MemoryImage buildImage() const override { return image; }
bool loadAllSymbols(SymbolTable *symtab, Addr base=0,
Addr offset=0, Addr addr_mask=MaxAddr) override;
bool loadGlobalSymbols(SymbolTable *symtab, Addr base=0,
Addr offset=0, Addr addr_mask=MaxAddr) override;
bool loadLocalSymbols(SymbolTable *symtab, Addr base=0,
Addr offset=0, Addr addr_mask=MaxAddr) override;
bool loadWeakSymbols(SymbolTable *symtab, Addr base=0,
Addr offset=0, Addr addr_mask=MaxAddr) override;
ObjectFile *getInterpreter() const override { return interpreter; }
std::string getInterpPath(const GElf_Phdr &phdr) const;

View File

@@ -34,6 +34,7 @@
#include "base/loader/image_file.hh"
#include "base/loader/image_file_data.hh"
#include "base/loader/memory_image.hh"
#include "base/loader/symtab.hh"
#include "base/logging.hh"
#include "base/types.hh"
@@ -72,36 +73,13 @@ class ObjectFile : public ImageFile
Arch arch = UnknownArch;
OpSys opSys = UnknownOpSys;
SymbolTable _symtab;
ObjectFile(ImageFileDataPtr ifd);
public:
virtual ~ObjectFile() {};
virtual bool
loadAllSymbols(SymbolTable *symtab, Addr base=0,
Addr offset=0, Addr mask=MaxAddr)
{
return true;
};
virtual bool
loadGlobalSymbols(SymbolTable *symtab, Addr base=0,
Addr offset=0, Addr mask=MaxAddr)
{
return true;
}
virtual bool
loadLocalSymbols(SymbolTable *symtab, Addr base=0,
Addr offset=0, Addr mask=MaxAddr)
{
return true;
}
virtual bool
loadWeakSymbols(SymbolTable *symtab, Addr base=0,
Addr offset=0, Addr mask=MaxAddr)
{
return true;
}
virtual ObjectFile *getInterpreter() const { return nullptr; }
virtual bool relocatable() const { return false; }
virtual Addr
@@ -121,6 +99,8 @@ class ObjectFile : public ImageFile
Arch getArch() const { return arch; }
OpSys getOpSys() const { return opSys; }
const SymbolTable &symtab() const { return _symtab; }
protected:
Addr entry = 0;

View File

@@ -46,7 +46,7 @@ ProfileNode::ProfileNode()
void
ProfileNode::dump(const string &symbol, uint64_t id,
const Loader::SymbolTable *symtab, ostream &os) const
const Loader::SymbolTable &symtab, ostream &os) const
{
ccprintf(os, "%#x %s %d ", id, symbol, count);
ChildList::const_iterator i, end = children.end();
@@ -67,7 +67,7 @@ ProfileNode::dump(const string &symbol, uint64_t id,
symbol = "console";
else if (addr == 3)
symbol = "unknown";
else if ((it = symtab->find(addr)) != symtab->end())
else if ((it = symtab.find(addr)) != symtab.end())
symbol = it->name;
else
panic("could not find symbol for address %#x\n", addr);
@@ -86,7 +86,7 @@ ProfileNode::clear()
i->second->clear();
}
FunctionProfile::FunctionProfile(const Loader::SymbolTable *_symtab)
FunctionProfile::FunctionProfile(const Loader::SymbolTable &_symtab)
: reset(0), symtab(_symtab)
{
reset = new MakeCallback<FunctionProfile, &FunctionProfile::clear>(this);
@@ -133,7 +133,7 @@ FunctionProfile::dump(ThreadContext *tc, ostream &os) const
Loader::SymbolTable::const_iterator it;
if (pc == 1) {
ccprintf(os, "user %d\n", count);
} else if ((it = symtab->find(pc)) != symtab->end() &&
} else if ((it = symtab.find(pc)) != symtab.end() &&
!it->name.empty()) {
ccprintf(os, "%s %d\n", it->name, count);
} else {
@@ -150,8 +150,8 @@ FunctionProfile::sample(ProfileNode *node, Addr pc)
{
node->count++;
auto it = symtab->findNearest(pc);
if (it != symtab->end()) {
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

View File

@@ -53,7 +53,7 @@ class ProfileNode
ProfileNode();
void dump(const std::string &symbol, uint64_t id,
const Loader::SymbolTable *symtab, std::ostream &os) const;
const Loader::SymbolTable &symtab, std::ostream &os) const;
void clear();
};
@@ -62,13 +62,13 @@ class FunctionProfile
{
private:
Callback *reset;
const Loader::SymbolTable *symtab;
const Loader::SymbolTable &symtab;
ProfileNode top;
std::map<Addr, Counter> pc_count;
TheISA::StackTrace trace;
public:
FunctionProfile(const Loader::SymbolTable *symtab);
FunctionProfile(const Loader::SymbolTable &symtab);
~FunctionProfile();
ProfileNode *consume(ThreadContext *tc, const StaticInstPtr &inst);

View File

@@ -93,15 +93,15 @@ Linux::dumpDmesg(ThreadContext *tc, std::ostream &os)
{
System *system = tc->getSystemPtr();
const ByteOrder bo = system->getGuestByteOrder();
const auto *symtab = system->workload->symtab(tc);
const auto &symtab = system->workload->symtab(tc);
PortProxy &proxy = tc->getVirtProxy();
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");
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");
auto end_it = symtab->end();
auto end_it = symtab.end();
if (lb == end_it || lb_len == end_it ||
first == end_it || next == end_it) {

View File

@@ -80,9 +80,7 @@ AbstractMemory::initState()
auto *object = Loader::createObjectFile(file, true);
fatal_if(!object, "%s: Could not load %s.", name(), file);
panic_if(!object->loadGlobalSymbols(&Loader::debugSymbolTable),
"%s: Could not load symbols from %s.", name(), file);
Loader::debugSymbolTable.insert(*object->symtab().globals());
Loader::MemoryImage image = object->buildImage();
AddrRange image_range(image.minAddr(), image.maxAddr());

View File

@@ -33,7 +33,7 @@
KernelWorkload::KernelWorkload(const Params &p) : Workload(&p), _params(p),
_loadAddrMask(p.load_addr_mask), _loadAddrOffset(p.load_addr_offset),
kernelSymtab(new Loader::SymbolTable), commandLine(p.command_line)
commandLine(p.command_line)
{
if (params().object_file == "") {
inform("No kernel set for full system simulation. "
@@ -60,18 +60,8 @@ KernelWorkload::KernelWorkload(const Params &p) : Workload(&p), _params(p),
return (a & _loadAddrMask) + _loadAddrOffset;
});
// load symbols
fatal_if(!kernelObj->loadGlobalSymbols(kernelSymtab),
"Could not load kernel symbols.");
fatal_if(!kernelObj->loadLocalSymbols(kernelSymtab),
"Could not load kernel local symbols.");
fatal_if(!kernelObj->loadGlobalSymbols(&Loader::debugSymbolTable),
"Could not load kernel symbols.");
fatal_if(!kernelObj->loadLocalSymbols(&Loader::debugSymbolTable),
"Could not load kernel local symbols.");
kernelSymtab = kernelObj->symtab();
Loader::debugSymbolTable.insert(kernelSymtab);
}
// Loading only needs to happen once and after memory system is
@@ -92,11 +82,6 @@ KernelWorkload::KernelWorkload(const Params &p) : Workload(&p), _params(p),
}
}
KernelWorkload::~KernelWorkload()
{
delete kernelSymtab;
}
void
KernelWorkload::initState()
{
@@ -142,13 +127,13 @@ KernelWorkload::initState()
void
KernelWorkload::serialize(CheckpointOut &cp) const
{
kernelSymtab->serialize("symtab", cp);
kernelSymtab.serialize("symtab", cp);
}
void
KernelWorkload::unserialize(CheckpointIn &cp)
{
kernelSymtab->unserialize("symtab", cp);
kernelSymtab.unserialize("symtab", cp);
}
KernelWorkload *

View File

@@ -69,7 +69,9 @@ class KernelWorkload : public Workload
std::vector<Loader::ObjectFile *> extras;
Loader::ObjectFile *kernelObj = nullptr;
Loader::SymbolTable *kernelSymtab = nullptr;
// Keep a separate copy of the kernel's symbol table so we can add things
// to it.
Loader::SymbolTable kernelSymtab;
const std::string commandLine;
@@ -82,7 +84,6 @@ class KernelWorkload : public Workload
Addr loadAddrOffset() const { return _loadAddrOffset; }
KernelWorkload(const Params &p);
~KernelWorkload();
Addr getEntry() const override { return kernelObj->entryPoint(); }
Loader::Arch
@@ -91,7 +92,7 @@ class KernelWorkload : public Workload
return kernelObj->getArch();
}
const Loader::SymbolTable *
const Loader::SymbolTable &
symtab(ThreadContext *tc) override
{
return kernelSymtab;
@@ -100,7 +101,7 @@ class KernelWorkload : public Workload
bool
insertSymbol(const Loader::Symbol &symbol) override
{
return kernelSymtab->insert(symbol);
return kernelSymtab.insert(symbol);
}
void initState() override;

View File

@@ -155,13 +155,8 @@ Process::Process(ProcessParams *params, EmulationPageTable *pTable,
image = objFile->buildImage();
if (::Loader::debugSymbolTable.empty()) {
if (!objFile->loadGlobalSymbols(&::Loader::debugSymbolTable) ||
!objFile->loadLocalSymbols(&::Loader::debugSymbolTable) ||
!objFile->loadWeakSymbols(&::Loader::debugSymbolTable)) {
::Loader::debugSymbolTable.clear();
}
}
if (::Loader::debugSymbolTable.empty())
::Loader::debugSymbolTable = objFile->symtab();
}
void

View File

@@ -1722,8 +1722,8 @@ mmapFunc(SyscallDesc *desc, ThreadContext *tc,
ffdp->getFileName());
if (lib) {
lib->loadAllSymbols(&Loader::debugSymbolTable,
lib->buildImage().minAddr(), start);
Addr offset = lib->buildImage().minAddr() + start;
Loader::debugSymbolTable.insert(*lib->symtab().offset(offset));
}
}
}

View File

@@ -49,7 +49,7 @@ class Workload : public SimObject
virtual Addr getEntry() const = 0;
virtual Loader::Arch getArch() const = 0;
virtual const Loader::SymbolTable *symtab(ThreadContext *tc) = 0;
virtual const Loader::SymbolTable &symtab(ThreadContext *tc) = 0;
virtual bool insertSymbol(const Loader::Symbol &symbol) = 0;
/** @{ */
@@ -67,11 +67,11 @@ class Workload : public SimObject
*/
template <class T, typename... Args>
T *
addFuncEvent(const Loader::SymbolTable *symtab, const char *lbl,
addFuncEvent(const Loader::SymbolTable &symtab, const char *lbl,
const std::string &desc, Args... args)
{
auto it = symtab->find(lbl);
if (it == symtab->end())
auto it = symtab.find(lbl);
if (it == symtab.end())
return nullptr;
return new T(system, desc, fixFuncEventAddr(it->address),
@@ -80,14 +80,14 @@ class Workload : public SimObject
template <class T>
T *
addFuncEvent(const Loader::SymbolTable *symtab, const char *lbl)
addFuncEvent(const Loader::SymbolTable &symtab, const char *lbl)
{
return addFuncEvent<T>(symtab, lbl, lbl);
}
template <class T, typename... Args>
T *
addFuncEventOrPanic(const Loader::SymbolTable *symtab, const char *lbl,
addFuncEventOrPanic(const Loader::SymbolTable &symtab, const char *lbl,
Args... args)
{
T *e = addFuncEvent<T>(symtab, lbl, std::forward<Args>(args)...);

View File

@@ -31,7 +31,6 @@
#include <vector>
#include "base/loader/object_file.hh"
#include "base/loader/symtab.hh"
#include "base/logging.hh"
#include "base/str.hh"
@@ -47,12 +46,8 @@ main(int argc, char *argv[])
if (!obj)
panic("file not found\n");
Loader::SymbolTable symtab;
obj->loadGlobalSymbols(&symtab);
obj->loadLocalSymbols(&symtab);
if (argc == 2) {
for (const Loader::Symbol &symbol: symtab)
for (const Loader::Symbol &symbol: obj->symtab())
cprintf("%#x %s\n", symbol.address, symbol.name);
} else {
string symbol = argv[2];
@@ -61,14 +56,14 @@ main(int argc, char *argv[])
if (symbol[0] == '0' && symbol[1] == 'x') {
Loader::SymbolTable::const_iterator it;
if (to_number(symbol, address) &&
(it = symtab.find(address)) != symtab.end()) {
(it = obj->symtab().find(address)) != obj->symtab().end()) {
cprintf("address = %#x, symbol = %s\n", address, it->name);
} else {
cprintf("address = %#x was not found\n", address);
}
} else {
auto it = symtab.find(symbol);
if (it != symtab.end())
auto it = obj->symtab().find(symbol);
if (it != obj->symtab().end())
cprintf("symbol = %s address = %#x\n", symbol, it->address);
else
cprintf("symbol = %s was not found\n", symbol);