arch,base,cpu,kerm,sim: Build a symbol table for object files.
authorGabe Black <gabeblack@google.com>
Wed, 22 Jan 2020 03:30:43 +0000 (19:30 -0800)
committerGabe Black <gabeblack@google.com>
Tue, 9 Jun 2020 23:37:29 +0000 (23:37 +0000)
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>
22 files changed:
src/arch/arm/freebsd/fs_workload.cc
src/arch/arm/fs_workload.cc
src/arch/arm/linux/fs_workload.cc
src/arch/arm/stacktrace.cc
src/arch/generic/linux/threadinfo.hh
src/arch/riscv/bare_metal/fs_workload.cc
src/arch/riscv/bare_metal/fs_workload.hh
src/arch/sparc/fs_workload.hh
src/arch/x86/stacktrace.cc
src/base/loader/elf_object.cc
src/base/loader/elf_object.hh
src/base/loader/object_file.hh
src/cpu/profile.cc
src/cpu/profile.hh
src/kern/linux/helpers.cc
src/mem/abstract_mem.cc
src/sim/kernel_workload.cc
src/sim/kernel_workload.hh
src/sim/process.cc
src/sim/syscall_emul.hh
src/sim/workload.hh
src/unittest/nmtest.cc

index e3660d9b17dbc5da33803052e629a0e4e8798313..d15e1a2e25d0f5d06c7574921c6fae82d7bbfe47 100644 (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.");
 
index 4c654b82205e31429ddefca11a245e541b56e009..5bd534fb480c8e8b221448eb0a1be88e536e8d06 100644 (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
index 7f0853fdcf8887207a35349d8fada9888f199fff..d45c7f02cfd37f9081a164dae5042db47f98f9e2 100644 (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) {
index 535cddd0228ab4458cc30e2aab1014573c7045a9..2c39576859594df994566116ac5eca231ec34630 100644 (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);
 }
index 5e058cf2e9b883629472f6a1d9b72dc7a5edd3c5..3024c8605d77cb469b2a6156128240f05a9e570b 100644 (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");
index a82d1df2acbbae1d5cb6d36e502ac1fe08da6c91..6a0c86ce6c5082fa50d7431a5193286c414568c3 100644 (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()
index a142d47594bc22cbed8d77cc94133b9a510d7729..45478782bc21c9849bd776585996a029f564ba0a 100644 (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);
     }
 };
 
index 650ed37a02df05f87397e8e13b95c41e79752661..5a054855000847f69bdc2b6908554413862328ca 100644 (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
index 0e5341c006f2fc271db41a7534bc3c0cbec77a24..cb9e529ad81488ed1a1fb3b2ed4a9068f9b87d1f 100644 (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);
index ceafc53fbf4006d63b7f5966ef4f338ba170453d..49fbd6dd7b0195981a54b6c3eeb36c0003ec5b22 100644 (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()
 {
index f96c26caf6c449a10feaa8dbe363717326d8c612..c262912af598d74c2d2eb4754af86a8d152d3b4f 100644 (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;
 
index cdd82c3d2004ff28bb5b3a8cce16c3cc9e8290da..9ff9997f73d68b8f0fbd74c43c4328bbdb351a74 100644 (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;
 
index fee0681cba356d8fc2b2332923091d2cf4bb6012..d1826e439623e1abcc6634b08f0e2c57a8a5845f 100644 (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
index 0eb245545926ad94dc0c775ff0031963addf8f35..96d55262975f7c6f948c5e035a562e934b8bbbbb 100644 (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);
index 80ff52632543cc49aa053c82bf4faccfb26c47b8..4cbac41b731ae1658b4896b2897dd66c20bae2e1 100644 (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) {
index 678527e69e9615e8b88fc8974479c7ff1e7458c8..70d4626159ed65c3dfe006745f77bfaee95cc954 100644 (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());
index 74f9fc7755cb5fa81c3ef3a7aa244ab1ea63b6eb..d144872b1d4ed5acc11787b884c902d4cc1628a1 100644 (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 *
index 34406ebc5051572104d522aef27bb68276fceda4..e2aff08fdb750d64ec1c2746293d66f9fa8e8897 100644 (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;
index 9a88163754af5383174ecd036f81d39dc8b42d89..3fab8536d7b48571106dbfaa30b75084570ca5cb 100644 (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
index 5b966cd7873cb3717a8417f58e0cb4296960d511..f2cc22c2ac83d4605b857293f464783e69e8ea39 100644 (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));
             }
         }
     }
index e24aa746e8be0589277e1d8a4c3f73571b1e16fb..77390e248fd010d6984bf3d810552f85bfa973d0 100644 (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)...);
index 3601fa877fa7b8197ba8ce5d0624f3b2eaa6e4e9..f25c5e1e236cdaf6aa54e306605618ec6b1c0bbd 100644 (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);