From 5da62e633129bdbe913bd385c13fa2658706a29a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 21 Jan 2020 19:30:43 -0800 Subject: [PATCH] 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 Reviewed-by: Giacomo Travaglini Maintainer: Gabe Black Tested-by: kokoro --- src/arch/arm/freebsd/fs_workload.cc | 8 +- src/arch/arm/fs_workload.cc | 2 +- src/arch/arm/linux/fs_workload.cc | 8 +- src/arch/arm/stacktrace.cc | 6 +- src/arch/generic/linux/threadinfo.hh | 6 +- src/arch/riscv/bare_metal/fs_workload.cc | 4 +- src/arch/riscv/bare_metal/fs_workload.hh | 6 +- src/arch/sparc/fs_workload.hh | 4 +- src/arch/x86/stacktrace.cc | 10 +- src/base/loader/elf_object.cc | 172 ++++++++--------------- src/base/loader/elf_object.hh | 10 -- src/base/loader/object_file.hh | 30 +--- src/cpu/profile.cc | 12 +- src/cpu/profile.hh | 6 +- src/kern/linux/helpers.cc | 12 +- src/mem/abstract_mem.cc | 4 +- src/sim/kernel_workload.cc | 25 +--- src/sim/kernel_workload.hh | 9 +- src/sim/process.cc | 9 +- src/sim/syscall_emul.hh | 4 +- src/sim/workload.hh | 12 +- src/unittest/nmtest.cc | 13 +- 22 files changed, 128 insertions(+), 244 deletions(-) diff --git a/src/arch/arm/freebsd/fs_workload.cc b/src/arch/arm/freebsd/fs_workload.cc index e3660d9b1..d15e1a2e2 100644 --- a/src/arch/arm/freebsd/fs_workload.cc +++ b/src/arch/arm/freebsd/fs_workload.cc @@ -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."); diff --git a/src/arch/arm/fs_workload.cc b/src/arch/arm/fs_workload.cc index 4c654b822..5bd534fb4 100644 --- a/src/arch/arm/fs_workload.cc +++ b/src/arch/arm/fs_workload.cc @@ -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 diff --git a/src/arch/arm/linux/fs_workload.cc b/src/arch/arm/linux/fs_workload.cc index 7f0853fdc..d45c7f02c 100644 --- a/src/arch/arm/linux/fs_workload.cc +++ b/src/arch/arm/linux/fs_workload.cc @@ -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) { diff --git a/src/arch/arm/stacktrace.cc b/src/arch/arm/stacktrace.cc index 535cddd02..2c3957685 100644 --- a/src/arch/arm/stacktrace.cc +++ b/src/arch/arm/stacktrace.cc @@ -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(it->address, GuestByteOrder); } diff --git a/src/arch/generic/linux/threadinfo.hh b/src/arch/generic/linux/threadinfo.hh index 5e058cf2e..3024c8605 100644 --- a/src/arch/generic/linux/threadinfo.hh +++ b/src/arch/generic/linux/threadinfo.hh @@ -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"); diff --git a/src/arch/riscv/bare_metal/fs_workload.cc b/src/arch/riscv/bare_metal/fs_workload.cc index a82d1df2a..6a0c86ce6 100644 --- a/src/arch/riscv/bare_metal/fs_workload.cc +++ b/src/arch/riscv/bare_metal/fs_workload.cc @@ -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() diff --git a/src/arch/riscv/bare_metal/fs_workload.hh b/src/arch/riscv/bare_metal/fs_workload.hh index a142d4759..45478782b 100644 --- a/src/arch/riscv/bare_metal/fs_workload.hh +++ b/src/arch/riscv/bare_metal/fs_workload.hh @@ -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); } }; diff --git a/src/arch/sparc/fs_workload.hh b/src/arch/sparc/fs_workload.hh index 650ed37a0..5a0548550 100644 --- a/src/arch/sparc/fs_workload.hh +++ b/src/arch/sparc/fs_workload.hh @@ -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 diff --git a/src/arch/x86/stacktrace.cc b/src/arch/x86/stacktrace.cc index 0e5341c00..cb9e529ad 100644 --- a/src/arch/x86/stacktrace.cc +++ b/src/arch/x86/stacktrace.cc @@ -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(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); diff --git a/src/base/loader/elf_object.cc b/src/base/loader/elf_object.cc index ceafc53fb..49fbd6dd7 100644 --- a/src/base/loader/elf_object.cc +++ b/src/base/loader/elf_object.cc @@ -132,6 +132,7 @@ ElfObject::ElfObject(ImageFileDataPtr ifd) : ObjectFile(ifd) ObjectFile *obj = createObjectFile(interp_path); interpreter = dynamic_cast(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( - 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() { diff --git a/src/base/loader/elf_object.hh b/src/base/loader/elf_object.hh index f96c26caf..c262912af 100644 --- a/src/base/loader/elf_object.hh +++ b/src/base/loader/elf_object.hh @@ -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; diff --git a/src/base/loader/object_file.hh b/src/base/loader/object_file.hh index cdd82c3d2..9ff9997f7 100644 --- a/src/base/loader/object_file.hh +++ b/src/base/loader/object_file.hh @@ -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; diff --git a/src/cpu/profile.cc b/src/cpu/profile.cc index fee0681cb..d1826e439 100644 --- a/src/cpu/profile.cc +++ b/src/cpu/profile.cc @@ -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(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 diff --git a/src/cpu/profile.hh b/src/cpu/profile.hh index 0eb245545..96d552629 100644 --- a/src/cpu/profile.hh +++ b/src/cpu/profile.hh @@ -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 pc_count; TheISA::StackTrace trace; public: - FunctionProfile(const Loader::SymbolTable *symtab); + FunctionProfile(const Loader::SymbolTable &symtab); ~FunctionProfile(); ProfileNode *consume(ThreadContext *tc, const StaticInstPtr &inst); diff --git a/src/kern/linux/helpers.cc b/src/kern/linux/helpers.cc index 80ff52632..4cbac41b7 100644 --- a/src/kern/linux/helpers.cc +++ b/src/kern/linux/helpers.cc @@ -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) { diff --git a/src/mem/abstract_mem.cc b/src/mem/abstract_mem.cc index 678527e69..70d462615 100644 --- a/src/mem/abstract_mem.cc +++ b/src/mem/abstract_mem.cc @@ -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()); diff --git a/src/sim/kernel_workload.cc b/src/sim/kernel_workload.cc index 74f9fc775..d144872b1 100644 --- a/src/sim/kernel_workload.cc +++ b/src/sim/kernel_workload.cc @@ -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 * diff --git a/src/sim/kernel_workload.hh b/src/sim/kernel_workload.hh index 34406ebc5..e2aff08fd 100644 --- a/src/sim/kernel_workload.hh +++ b/src/sim/kernel_workload.hh @@ -69,7 +69,9 @@ class KernelWorkload : public Workload std::vector 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; diff --git a/src/sim/process.cc b/src/sim/process.cc index 9a8816375..3fab8536d 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -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 diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index 5b966cd78..f2cc22c2a 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -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)); } } } diff --git a/src/sim/workload.hh b/src/sim/workload.hh index e24aa746e..77390e248 100644 --- a/src/sim/workload.hh +++ b/src/sim/workload.hh @@ -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 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 T * - addFuncEvent(const Loader::SymbolTable *symtab, const char *lbl) + addFuncEvent(const Loader::SymbolTable &symtab, const char *lbl) { return addFuncEvent(symtab, lbl, lbl); } template T * - addFuncEventOrPanic(const Loader::SymbolTable *symtab, const char *lbl, + addFuncEventOrPanic(const Loader::SymbolTable &symtab, const char *lbl, Args... args) { T *e = addFuncEvent(symtab, lbl, std::forward(args)...); diff --git a/src/unittest/nmtest.cc b/src/unittest/nmtest.cc index 3601fa877..f25c5e1e2 100644 --- a/src/unittest/nmtest.cc +++ b/src/unittest/nmtest.cc @@ -31,7 +31,6 @@ #include #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); -- 2.30.2