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:
@@ -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.");
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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 *
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)...);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user