arch,base,cpu,kern,sim: Encapsulate symbols in a class.
authorGabe Black <gabeblack@google.com>
Tue, 21 Jan 2020 13:44:00 +0000 (05:44 -0800)
committerGabe Black <gabeblack@google.com>
Tue, 19 May 2020 22:32:21 +0000 (22:32 +0000)
The SymbolTable class had been tracking symbols as two independent
pieces, a name and an address, and acted as a way to translate between
them. Symbols can be more complex than that, and so this change
encapsulates the information associated with a symbol in a new class.

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

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

Change-Id: I8084f86fd737f697ec041bac86a635a315fd1194
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/24784
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
23 files changed:
src/arch/arm/freebsd/fs_workload.cc
src/arch/arm/insts/static_inst.cc
src/arch/arm/linux/fs_workload.cc
src/arch/arm/stacktrace.cc
src/arch/generic/linux/threadinfo.hh
src/arch/mips/isa/formats/branch.isa
src/arch/power/insts/branch.cc
src/arch/riscv/bare_metal/fs_workload.hh
src/arch/sparc/fs_workload.hh
src/arch/sparc/insts/branch.cc
src/arch/x86/stacktrace.cc
src/base/loader/elf_object.cc
src/base/loader/symtab.cc
src/base/loader/symtab.hh
src/cpu/base.cc
src/cpu/exetrace.cc
src/cpu/profile.cc
src/kern/linux/helpers.cc
src/sim/kernel_workload.hh
src/sim/pseudo_inst.cc
src/sim/workload.hh
src/unittest/nmtest.cc
src/unittest/symtest.cc

index 91a1d895c1870682b86d890d2f7e002a522b68eb..ea99b427387c59e065355d587ae3346c93e0034f 100644 (file)
@@ -88,8 +88,7 @@ FsFreebsd::initState()
 
     // Check if the kernel image has a symbol that tells us it supports
     // device trees.
-    Addr addr;
-    fatal_if(!kernelSymtab->findAddress("fdt_get_range", addr),
+    fatal_if(kernelSymtab->find("fdt_get_range") == kernelSymtab->end(),
              "Kernel must have fdt support.");
     fatal_if(params()->dtb_filename == "", "dtb file is not specified.");
 
index 70e5fb95270ec2747acdf0d84cf617de7f6d7d90..9c686f6cacb40c7419cc4aa0405df15939c81fed 100644 (file)
@@ -393,18 +393,19 @@ void
 ArmStaticInst::printTarget(std::ostream &os, Addr target,
                            const Loader::SymbolTable *symtab) const
 {
-    Addr symbolAddr;
-    std::string symbol;
-
-    if (symtab && symtab->findNearestSymbol(target, symbol, symbolAddr)) {
-        ccprintf(os, "<%s", symbol);
-        if (symbolAddr != target)
-            ccprintf(os, "+%d>", target - symbolAddr);
-        else
-            ccprintf(os, ">");
-    } else {
-        ccprintf(os, "%#x", target);
+    if (symtab) {
+        auto it = symtab->findNearest(target);
+        if (it != symtab->end()) {
+            ccprintf(os, "<%s", it->name);
+            Addr delta = target - it->address;
+            if (delta)
+                ccprintf(os, "+%d>", delta);
+            else
+                ccprintf(os, ">");
+            return;
+        }
     }
+    ccprintf(os, "%#x", target);
 }
 
 void
@@ -477,13 +478,14 @@ ArmStaticInst::printMemSymbol(std::ostream &os,
                               const Addr addr,
                               const std::string &suffix) const
 {
-    Addr symbolAddr;
-    std::string symbol;
-    if (symtab && symtab->findNearestSymbol(addr, symbol, symbolAddr)) {
-        ccprintf(os, "%s%s", prefix, symbol);
-        if (symbolAddr != addr)
-            ccprintf(os, "+%d", addr - symbolAddr);
-        ccprintf(os, suffix);
+    if (symtab) {
+        auto it = symtab->findNearest(addr);
+        if (it != symtab->end()) {
+            ccprintf(os, "%s%s", prefix, it->name);
+            if (it->address != addr)
+                ccprintf(os, "+%d", addr - it->address);
+            ccprintf(os, suffix);
+        }
     }
 }
 
index cc28193d92717586105b81087a4d30dac77db580..9ebb1172b63969606cc6fd192939054f2d1dc6d1 100644 (file)
@@ -82,11 +82,10 @@ FsLinux::initState()
     }
 
     // Setup boot data structure
-    Addr addr;
     // Check if the kernel image has a symbol that tells us it supports
     // device trees.
     bool kernel_has_fdt_support =
-        kernelSymtab->findAddress("unflatten_device_tree", addr);
+        kernelSymtab->find("unflatten_device_tree") != kernelSymtab->end();
     bool dtb_file_specified = params()->dtb_filename != "";
 
     if (kernel_has_fdt_support && dtb_file_specified) {
index d0e702c6bcd10839c7bcb09bdec1967f03f1a0e4..535cddd0228ab4458cc30e2aab1014573c7045a9 100644 (file)
@@ -47,11 +47,10 @@ readSymbol(ThreadContext *tc, const std::string name)
     PortProxy &vp = tc->getVirtProxy();
     const auto *symtab = tc->getSystemPtr()->workload->symtab(tc);
 
-    Addr addr;
-    if (!symtab->findAddress(name, addr))
-        panic("thread info not compiled into kernel\n");
+    auto it = symtab->find(name);
+    panic_if(it == symtab->end(), "Thread info not compiled into kernel.");
 
-    return vp.read<int32_t>(addr, GuestByteOrder);
+    return vp.read<int32_t>(it->address, GuestByteOrder);
 }
 
 ProcessInfo::ProcessInfo(ThreadContext *_tc) : tc(_tc)
index 83e41b97a0a3d7286db3d3c1c57a944104e0709b..5e058cf2e9b883629472f6a1d9b72dc7a5edd3c5 100644 (file)
@@ -46,15 +46,16 @@ class ThreadInfo
     bool
     get_data(const char *symbol, T &data)
     {
-        Addr addr = 0;
-        if (!sys->workload->symtab(tc)->findAddress(symbol, addr)) {
+        auto *symtab = sys->workload->symtab(tc);
+        auto it = symtab->find(symbol);
+        if (it == symtab->end()) {
             warn_once("Unable to find kernel symbol %s\n", symbol);
             warn_once("Kernel not compiled with task_struct info; can't get "
                       "currently executing task/process/thread name/ids!\n");
             return false;
         }
 
-        data = tc->getVirtProxy().read<T>(addr, TheISA::GuestByteOrder);
+        data = tc->getVirtProxy().read<T>(it->address, TheISA::GuestByteOrder);
 
         return true;
     }
index 06662f092d796d83fecccf93a7b30a9f332b4723..4975a132142a338824d3efc93fdb0045ad5d315b 100644 (file)
@@ -193,11 +193,11 @@ output decoder {{
 
         Addr target = pc + 4 + disp;
 
-        std::string str;
-        if (symtab && symtab->findSymbol(target, str))
-            ss << str;
+        Loader::SymbolTable::const_iterator it;
+        if (symtab && (it = symtab->find(target)) != symtab->end())
+            ss << it->name;
         else
-            ccprintf(ss, "0x%x", target);
+            ccprintf(ss, "%#x", target);
 
         return ss.str();
     }
@@ -213,9 +213,9 @@ output decoder {{
             Addr npc = pc + 4;
             ccprintf(ss,"0x%x",(npc & 0xF0000000) | disp);
         } else if (_numSrcRegs == 0) {
-            std::string str;
-            if (symtab && symtab->findSymbol(disp, str))
-                ss << str;
+            Loader::SymbolTable::const_iterator it;
+            if (symtab && (it = symtab->find(disp)) != symtab->end())
+                ss << it->name;
             else
                 ccprintf(ss, "0x%x", disp);
         } else if (_numSrcRegs == 1) {
index 5fe0c4e8f190c4e42f5e7d44f2ac05a5d6a9eb6a..3511b6b3c9d3e1e331b6f7cc0a591627d2d17340 100644 (file)
@@ -68,11 +68,11 @@ BranchPCRel::generateDisassembly(
 
     Addr target = pc + disp;
 
-    std::string str;
-    if (symtab && symtab->findSymbol(target, str))
-        ss << str;
+    Loader::SymbolTable::const_iterator it;
+    if (symtab && (it = symtab->find(target)) != symtab->end())
+        ss << it->name;
     else
-        ccprintf(ss, "0x%x", target);
+        ccprintf(ss, "%#x", target);
 
     return ss.str();
 }
@@ -91,11 +91,11 @@ BranchNonPCRel::generateDisassembly(
 
     ccprintf(ss, "%-10s ", mnemonic);
 
-    std::string str;
-    if (symtab && symtab->findSymbol(targetAddr, str))
-        ss << str;
+    Loader::SymbolTable::const_iterator it;
+    if (symtab && (it = symtab->find(targetAddr)) != symtab->end())
+        ss << it->name;
     else
-        ccprintf(ss, "0x%x", targetAddr);
+        ccprintf(ss, "%#x", targetAddr);
 
     return ss.str();
 }
@@ -118,11 +118,11 @@ BranchPCRelCond::generateDisassembly(
 
     Addr target = pc + disp;
 
-    std::string str;
-    if (symtab && symtab->findSymbol(target, str))
-        ss << str;
+    Loader::SymbolTable::const_iterator it;
+    if (symtab && (it = symtab->find(target)) != symtab->end())
+        ss << it->name;
     else
-        ccprintf(ss, "0x%x", target);
+        ccprintf(ss, "%#x", target);
 
     return ss.str();
 }
@@ -143,11 +143,11 @@ BranchNonPCRelCond::generateDisassembly(
 
     ss << bo << ", " << bi << ", ";
 
-    std::string str;
-    if (symtab && symtab->findSymbol(targetAddr, str))
-        ss << str;
+    Loader::SymbolTable::const_iterator it;
+    if (symtab && (it = symtab->find(targetAddr)) != symtab->end())
+        ss << it->name;
     else
-        ccprintf(ss, "0x%x", targetAddr);
+        ccprintf(ss, "%#x", targetAddr);
 
     return ss.str();
 }
index 2e26ad1b205978bf599ee59baac57c043c291145..a142d47594bc22cbed8d77cc94133b9a510d7729 100644 (file)
@@ -55,9 +55,9 @@ class BareMetal : public RiscvISA::FsWorkload
         return bootloaderSymtab;
     }
     bool
-    insertSymbol(Addr address, const std::string &symbol) override
+    insertSymbol(const Loader::Symbol &symbol) override
     {
-        return bootloaderSymtab->insert(address, symbol);
+        return bootloaderSymtab->insert(symbol);
     }
 };
 
index 0323714e759b985d0f201bca7fb6fe3fce57d953..650ed37a02df05f87397e8e13b95c41e79752661 100644 (file)
@@ -61,9 +61,9 @@ class FsWorkload : public Workload
     }
 
     bool
-    insertSymbol(Addr address, const std::string &symbol) override
+    insertSymbol(const Loader::Symbol &symbol) override
     {
-        return defaultSymtab.insert(address, symbol);
+        return defaultSymtab.insert(symbol);
     }
 };
 
index 8ffa24165472745330f41c6d2e139b113125ef44..52517e62029d2378e9626c4c35f76445f1ff408e 100644 (file)
@@ -77,18 +77,17 @@ BranchDisp::generateDisassembly(
         Addr pc, const Loader::SymbolTable *symtab) const
 {
     std::stringstream response;
-    std::string symbol;
-    Addr symbol_addr;
 
     Addr target = disp + pc;
 
     printMnemonic(response, mnemonic);
-    ccprintf(response, "0x%x", target);
+    ccprintf(response, "%#x", target);
 
-    if (symtab && symtab->findNearestSymbol(target, symbol, symbol_addr)) {
-        ccprintf(response, " <%s", symbol);
-        if (symbol_addr != target)
-            ccprintf(response, "+%d>", target - symbol_addr);
+    Loader::SymbolTable::const_iterator it;
+    if (symtab && (it = symtab->findNearest(target)) != symtab->end()) {
+        ccprintf(response, " <%s", it->name);
+        if (it->address != target)
+            ccprintf(response, "+%d>", target - it->address);
         else
             ccprintf(response, ">");
     }
index a7c548ea248fb40329ddb251d8e19421f698598c..0e5341c006f2fc271db41a7534bc3c0cbec77a24 100644 (file)
@@ -47,11 +47,10 @@ readSymbol(ThreadContext *tc, const std::string name)
     PortProxy &vp = tc->getVirtProxy();
     const auto *symtab = tc->getSystemPtr()->workload->symtab(tc);
 
-    Addr addr;
-    if (!symtab->findAddress(name, addr))
-        panic("thread info not compiled into kernel\n");
+    auto it = symtab->find(name);
+    panic_if(it == symtab->end(), "Thread info not compiled into kernel.");
 
-    return vp.read<int32_t>(addr, GuestByteOrder);
+    return vp.read<int32_t>(it->address, GuestByteOrder);
 }
 
 ProcessInfo::ProcessInfo(ThreadContext *_tc) : tc(_tc)
@@ -196,14 +195,15 @@ StackTrace::dump()
     std::string symbol;
     for (int i = 0, size = stack.size(); i < size; ++i) {
         Addr addr = stack[size - i - 1];
+        Loader::SymbolTable::const_iterator it;
         if (addr == user)
             symbol = "user";
         else if (addr == console)
             symbol = "console";
         else if (addr == unknown)
             symbol = "unknown";
-        else
-            symtab->findSymbol(addr, symbol);
+        else if ((it = symtab->find(addr)) != symtab->end())
+            symbol = it->name;
 
         DPRINTFN("%#x: %s\n", addr, symbol);
     }
index 8876a8735136caa9cb77d28f8e01d6a26683461d..ceafc53fbf4006d63b7f5966ef4f338ba170453d 100644 (file)
@@ -341,7 +341,23 @@ ElfObject::loadSomeSymbols(SymbolTable *symtab, int binding, Addr mask,
                         elf_strptr(elf, shdr.sh_link, sym.st_name);
                     if (sym_name && sym_name[0] != '$') {
                         Addr value = sym.st_value - base + offset;
-                        if (symtab->insert(value & mask, sym_name)) {
+                        Loader::Symbol symbol;
+                        symbol.address = value & mask;
+                        symbol.name = sym_name;
+                        switch (binding) {
+                          case STB_GLOBAL:
+                            symbol.binding = Loader::Symbol::Binding::Global;
+                            break;
+                          case STB_LOCAL:
+                            symbol.binding = Loader::Symbol::Binding::Local;
+                            break;
+                          case STB_WEAK:
+                            symbol.binding = Loader::Symbol::Binding::Weak;
+                            break;
+                          default:
+                            panic("Unrecognized binding type");
+                        }
+                        if (symtab->insert(symbol)) {
                             DPRINTF(Loader, "Symbol: %-40s value %#x\n",
                                     sym_name, value);
                         }
index 9e0f1f68c5c7a68c78d96e23bac2851480cb1cd7..a8e1a153426b3047bf5fd263b66c8361e3f5cc89 100644 (file)
@@ -35,6 +35,7 @@
 
 #include "base/logging.hh"
 #include "base/str.hh"
+#include "base/trace.hh"
 #include "base/types.hh"
 #include "sim/serialize.hh"
 
@@ -48,26 +49,48 @@ SymbolTable *debugSymbolTable = NULL;
 void
 SymbolTable::clear()
 {
-    addrTable.clear();
-    symbolTable.clear();
+    addrMap.clear();
+    nameMap.clear();
+    symbols.clear();
 }
 
 bool
-SymbolTable::insert(Addr address, string symbol)
+SymbolTable::insert(const Symbol &symbol)
 {
-    if (symbol.empty())
+    if (symbol.name.empty())
         return false;
 
-    if (!symbolTable.insert(make_pair(symbol, address)).second)
+    int idx = symbols.size();
+
+    if (!nameMap.insert({ symbol.name, idx }).second)
         return false;
 
     // There can be multiple symbols for the same address, so always
     // update the addrTable multimap when we see a new symbol name.
-    addrTable.insert(make_pair(address, symbol));
+    addrMap.insert({ symbol.address, idx });
+
+    symbols.emplace_back(symbol);
 
     return true;
 }
 
+bool
+SymbolTable::insert(const SymbolTable &other)
+{
+    // Check if any symbol in other already exists in our table.
+    NameMap intersection;
+    std::set_intersection(other.nameMap.begin(), other.nameMap.end(),
+                          nameMap.begin(), nameMap.end(),
+                          std::inserter(intersection, intersection.begin()),
+                          nameMap.value_comp());
+    if (!intersection.empty())
+        return false;
+
+    for (const Symbol &symbol: other)
+        insert(symbol);
+
+    return true;
+}
 
 bool
 SymbolTable::load(const string &filename)
@@ -92,51 +115,54 @@ SymbolTable::load(const string &filename)
         if (address.empty())
             return false;
 
-        string symbol = buffer.substr(idx + 1);
-        eat_white(symbol);
-        if (symbol.empty())
+        string name = buffer.substr(idx + 1);
+        eat_white(name);
+        if (name.empty())
             return false;
 
         Addr addr;
         if (!to_number(address, addr))
             return false;
 
-        if (!insert(addr, symbol))
+        if (!insert({ Symbol::Binding::Global, name, addr }))
             return false;
     }
 
     file.close();
-
     return true;
 }
 
 void
 SymbolTable::serialize(const string &base, CheckpointOut &cp) const
 {
-    paramOut(cp, base + ".size", addrTable.size());
+    paramOut(cp, base + ".size", symbols.size());
 
     int i = 0;
-    ATable::const_iterator p, end = addrTable.end();
-    for (p = addrTable.begin(); p != end; ++p) {
-        paramOut(cp, csprintf("%s.addr_%d", base, i), p->first);
-        paramOut(cp, csprintf("%s.symbol_%d", base, i), p->second);
-        ++i;
+    for (auto &symbol: symbols) {
+        paramOut(cp, csprintf("%s.addr_%d", base, i), symbol.address);
+        paramOut(cp, csprintf("%s.symbol_%d", base, i), symbol.name);
+        paramOut(cp, csprintf("%s.binding_%d", base, i), (int)symbol.binding);
+        i++;
     }
 }
 
 void
-SymbolTable::unserialize(const string &base, CheckpointIn &cp)
+SymbolTable::unserialize(const string &base, CheckpointIn &cp,
+                         Symbol::Binding default_binding)
 {
     clear();
     int size;
     paramIn(cp, base + ".size", size);
     for (int i = 0; i < size; ++i) {
-        Addr addr;
-        std::string symbol;
-
-        paramIn(cp, csprintf("%s.addr_%d", base, i), addr);
-        paramIn(cp, csprintf("%s.symbol_%d", base, i), symbol);
-        insert(addr, symbol);
+        Addr address;
+        std::string name;
+        Symbol::Binding binding = default_binding;
+
+        paramIn(cp, csprintf("%s.addr_%d", base, i), address);
+        paramIn(cp, csprintf("%s.symbol_%d", base, i), name);
+        if (!optParamIn(cp, csprintf("%s.binding_%d", base, i), binding))
+            binding = default_binding;
+        insert({binding, name, address});
     }
 }
 
index b09d8545f4edbc4f52ac2528d5ec94a3f8da1ff6..38e97ea9c022038779b38a4e4f9ff11754fb401f 100644 (file)
 #include <iosfwd>
 #include <map>
 #include <string>
+#include <vector>
 
+#include "base/trace.hh"
 #include "base/types.hh"
 #include "sim/serialize.hh"
 
 namespace Loader
 {
 
-class SymbolTable
+struct Symbol
 {
-  public:
-    typedef std::multimap<Addr, std::string> ATable;
-    typedef std::map<std::string, Addr> STable;
+    enum class Binding {
+        Global,
+        Local,
+        Weak
+    };
+
+    Binding binding;
+    std::string name;
+    Addr address;
+};
 
+class SymbolTable
+{
   private:
-    ATable addrTable;
-    STable symbolTable;
+    typedef std::vector<Symbol> SymbolVector;
+    // Map addresses to an index into the symbol vector.
+    typedef std::multimap<Addr, int> AddrMap;
+    // Map a symbol name to an index into the symbol vector.
+    typedef std::map<std::string, int> NameMap;
+
+    SymbolVector symbols;
+    AddrMap addrMap;
+    NameMap nameMap;
 
-  private:
     bool
-    upperBound(Addr addr, ATable::const_iterator &iter) const
+    upperBound(Addr addr, AddrMap::const_iterator &iter) const
     {
         // find first key *larger* than desired address
-        iter = addrTable.upper_bound(addr);
+        iter = addrMap.upper_bound(addr);
 
         // if very first key is larger, we're out of luck
-        if (iter == addrTable.begin())
+        if (iter == addrMap.begin())
             return false;
 
         return true;
     }
 
   public:
-    SymbolTable() {}
-    SymbolTable(const std::string &file) { load(file); }
-    ~SymbolTable() {}
+    typedef SymbolVector::iterator iterator;
+    typedef SymbolVector::const_iterator const_iterator;
+
+    const_iterator begin() const { return symbols.begin(); }
+    const_iterator end() const { return symbols.end(); }
 
     void clear();
-    bool insert(Addr address, std::string symbol);
+    // Insert either a single symbol or the contents of an entire symbol table
+    // into this one.
+    bool insert(const Symbol &symbol);
+    bool insert(const SymbolTable &other);
     bool load(const std::string &file);
 
-    const ATable &getAddrTable() const { return addrTable; }
-    const STable &getSymbolTable() const { return symbolTable; }
-
-  public:
     void serialize(const std::string &base, CheckpointOut &cp) const;
-    void unserialize(const std::string &base, CheckpointIn &cp);
+    void unserialize(const std::string &base, CheckpointIn &cp,
+                     Symbol::Binding default_binding=Symbol::Binding::Global);
 
-  public:
-    bool
-    findSymbol(Addr address, std::string &symbol) const
+    const_iterator
+    find(Addr address) const
     {
-        ATable::const_iterator i = addrTable.find(address);
-        if (i == addrTable.end())
-            return false;
+        AddrMap::const_iterator i = addrMap.find(address);
+        if (i == addrMap.end())
+            return end();
 
         // There are potentially multiple symbols that map to the same
         // address. For simplicity, just return the first one.
-        symbol = (*i).second;
-        return true;
+        return symbols.begin() + i->second;
     }
 
-    bool
-    findAddress(const std::string &symbol, Addr &address) const
+    const_iterator
+    find(const std::string &name) const
     {
-        STable::const_iterator i = symbolTable.find(symbol);
-        if (i == symbolTable.end())
-            return false;
+        NameMap::const_iterator i = nameMap.find(name);
+        if (i == nameMap.end())
+            return end();
 
-        address = (*i).second;
-        return true;
+        return symbols.begin() + i->second;
     }
 
     /// Find the nearest symbol equal to or less than the supplied
     /// address (e.g., the label for the enclosing function).
     /// @param addr     The address to look up.
-    /// @param symbol   Return reference for symbol string.
-    /// @param symaddr  Return reference for symbol address.
     /// @param nextaddr Address of following symbol (for
     ///                 determining valid range of symbol).
-    /// @retval True if a symbol was found.
-    bool
-    findNearestSymbol(Addr addr, std::string &symbol, Addr &symaddr,
-                      Addr &nextaddr) const
+    /// @retval A const_iterator which points to the symbol if found, or end.
+    const_iterator
+    findNearest(Addr addr, Addr &nextaddr) const
     {
-        ATable::const_iterator i;
+        AddrMap::const_iterator i = addrMap.end();
         if (!upperBound(addr, i))
-            return false;
+            return end();
 
         nextaddr = i->first;
         --i;
-        symaddr = i->first;
-        symbol = i->second;
-        return true;
+        return symbols.begin() + i->second;
     }
 
     /// Overload for findNearestSymbol() for callers who don't care
     /// about nextaddr.
-    bool
-    findNearestSymbol(Addr addr, std::string &symbol, Addr &symaddr) const
+    const_iterator
+    findNearest(Addr addr) const
     {
-        ATable::const_iterator i;
+        AddrMap::const_iterator i = addrMap.end();
         if (!upperBound(addr, i))
-            return false;
+            return end();
 
         --i;
-        symaddr = i->first;
-        symbol = i->second;
-        return true;
-    }
-
-
-    bool
-    findNearestAddr(Addr addr, Addr &symaddr, Addr &nextaddr) const
-    {
-        ATable::const_iterator i;
-        if (!upperBound(addr, i))
-            return false;
-
-        nextaddr = i->first;
-        --i;
-        symaddr = i->first;
-        return true;
-    }
-
-    bool
-    findNearestAddr(Addr addr, Addr &symaddr) const
-    {
-        ATable::const_iterator i;
-        if (!upperBound(addr, i))
-            return false;
-
-        --i;
-        symaddr = i->first;
-        return true;
+        return symbols.begin() + i->second;
     }
 };
 
index 36474829f73466d13008799fb10e80ec79050eb0..a74e285cada6a854f4f94d07d491430c3fb5174d 100644 (file)
@@ -757,15 +757,18 @@ BaseCPU::traceFunctionsInternal(Addr pc)
     // if pc enters different function, print new function symbol and
     // update saved range.  Otherwise do nothing.
     if (pc < currentFunctionStart || pc >= currentFunctionEnd) {
-        string sym_str;
-        bool found = Loader::debugSymbolTable->findNearestSymbol(
-                pc, sym_str, currentFunctionStart, currentFunctionEnd);
+        auto it = Loader::debugSymbolTable->findNearest(
+                pc, currentFunctionEnd);
 
-        if (!found) {
+        string sym_str;
+        if (it == Loader::debugSymbolTable->end()) {
             // no symbol found: use addr as label
-            sym_str = csprintf("0x%x", pc);
+            sym_str = csprintf("%#x", pc);
             currentFunctionStart = pc;
             currentFunctionEnd = pc + 1;
+        } else {
+            sym_str = it->name;
+            currentFunctionStart = it->address;
         }
 
         ccprintf(*functionTraceStream, " (%d)\n%d: %s",
index 06154daa754ef951900a2cd5dc108530d1376c79..60c8fd0ac5e5d241291405c09dccbac99d76985f 100644 (file)
@@ -76,27 +76,28 @@ Trace::ExeTracerRecord::traceInst(const StaticInstPtr &inst, bool ran)
     if (Debug::ExecThread)
         outs << "T" << thread->threadId() << " : ";
 
-    std::string sym_str;
-    Addr sym_addr;
     Addr cur_pc = pc.instAddr();
+    Loader::SymbolTable::const_iterator it;
     if (Loader::debugSymbolTable && Debug::ExecSymbol &&
             (!FullSystem || !inUserMode(thread)) &&
-            Loader::debugSymbolTable->findNearestSymbol(
-                cur_pc, sym_str, sym_addr)) {
-        if (cur_pc != sym_addr)
-            sym_str += csprintf("+%d",cur_pc - sym_addr);
-        outs << "@" << sym_str;
+            (it = Loader::debugSymbolTable->findNearest(cur_pc)) !=
+                Loader::debugSymbolTable->end()) {
+        Addr delta = cur_pc - it->address;
+        if (delta)
+            ccprintf(outs, "@%s+%d", it->name, delta);
+        else
+            ccprintf(outs, "@%s", it->name);
     } else {
-        outs << "0x" << hex << cur_pc;
+        ccprintf(outs, "%#x", cur_pc);
     }
 
     if (inst->isMicroop()) {
-        outs << "." << setw(2) << dec << pc.microPC();
+        ccprintf(outs, ".%2d", pc.microPC());
     } else {
-        outs << "   ";
+        ccprintf(outs, "   ");
     }
 
-    outs << " : ";
+    ccprintf(outs, " : ");
 
     //
     //  Print decoded instruction
index aa2cff892a485098fde5673ff3c3e0ed8f3e4a26..fee0681cba356d8fc2b2332923091d2cf4bb6012 100644 (file)
@@ -57,6 +57,7 @@ ProfileNode::dump(const string &symbol, uint64_t id,
 
     ccprintf(os, "\n");
 
+    Loader::SymbolTable::const_iterator it;
     for (i = children.begin(); i != end; ++i) {
         Addr addr = i->first;
         string symbol;
@@ -66,7 +67,9 @@ ProfileNode::dump(const string &symbol, uint64_t id,
             symbol = "console";
         else if (addr == 3)
             symbol = "unknown";
-        else if (!symtab->findSymbol(addr, symbol))
+        else if ((it = symtab->find(addr)) != symtab->end())
+            symbol = it->name;
+        else
             panic("could not find symbol for address %#x\n", addr);
 
         const ProfileNode *node = i->second;
@@ -127,13 +130,15 @@ FunctionProfile::dump(ThreadContext *tc, ostream &os) const
         Addr pc = i->first;
         Counter count = i->second;
 
-        std::string symbol;
-        if (pc == 1)
+        Loader::SymbolTable::const_iterator it;
+        if (pc == 1) {
             ccprintf(os, "user %d\n", count);
-        else if (symtab->findSymbol(pc, symbol) && !symbol.empty())
-            ccprintf(os, "%s %d\n", symbol, count);
-        else
+        } else if ((it = symtab->find(pc)) != symtab->end() &&
+                !it->name.empty()) {
+            ccprintf(os, "%s %d\n", it->name, count);
+        } else {
             ccprintf(os, "%#x %d\n", pc, count);
+        }
     }
 
     ccprintf(os, ">>>function data\n");
@@ -145,9 +150,9 @@ FunctionProfile::sample(ProfileNode *node, Addr pc)
 {
     node->count++;
 
-    Addr symaddr;
-    if (symtab->findNearestAddr(pc, symaddr)) {
-        pc_count[symaddr]++;
+    auto it = symtab->findNearest(pc);
+    if (it != symtab->end()) {
+        pc_count[it->address]++;
     } else {
         // record PC even if we don't have a symbol to avoid
         // silently biasing the histogram
index 9286ab071a309f357694868180bd5bc7b6504af7..80ff52632543cc49aa053c82bf4faccfb26c47b8 100644 (file)
@@ -96,24 +96,25 @@ Linux::dumpDmesg(ThreadContext *tc, std::ostream &os)
     const auto *symtab = system->workload->symtab(tc);
     PortProxy &proxy = tc->getVirtProxy();
 
-    Addr addr_lb = 0, addr_lb_len = 0, addr_first = 0, addr_next = 0;
-    const bool found_symbols =
-        symtab->findAddress("__log_buf", addr_lb) &&
-        symtab->findAddress("log_buf_len", addr_lb_len) &&
-        symtab->findAddress("log_first_idx", addr_first) &&
-        symtab->findAddress("log_next_idx", addr_next);
-
-    if (!found_symbols) {
+    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();
+
+    if (lb == end_it || lb_len == end_it ||
+            first == end_it || next == end_it) {
         warn("Failed to find kernel dmesg symbols.\n");
         return;
     }
 
     uint32_t log_buf_len =
-        proxy.read<uint32_t>(addr_lb_len, TheISA::GuestByteOrder);
+        proxy.read<uint32_t>(lb_len->address, TheISA::GuestByteOrder);
     uint32_t log_first_idx =
-        proxy.read<uint32_t>(addr_first, TheISA::GuestByteOrder);
+        proxy.read<uint32_t>(first->address, TheISA::GuestByteOrder);
     uint32_t log_next_idx =
-        proxy.read<uint32_t>(addr_next, TheISA::GuestByteOrder);
+        proxy.read<uint32_t>(next->address, TheISA::GuestByteOrder);
 
     if (log_first_idx >= log_buf_len || log_next_idx >= log_buf_len) {
         warn("dmesg pointers/length corrupted\n");
@@ -129,7 +130,7 @@ Linux::dumpDmesg(ThreadContext *tc, std::ostream &os)
             warn("Unexpected dmesg buffer length\n");
             return;
         }
-        proxy.readBlob(addr_lb + log_first_idx, log_buf.data(), length);
+        proxy.readBlob(lb->address + log_first_idx, log_buf.data(), length);
     } else {
         const int length_2 = log_buf_len - log_first_idx;
         if (length_2 < 0 || length_2 + log_next_idx > log_buf.size()) {
@@ -137,8 +138,8 @@ Linux::dumpDmesg(ThreadContext *tc, std::ostream &os)
             return;
         }
         length = log_buf_len;
-        proxy.readBlob(addr_lb + log_first_idx, log_buf.data(), length_2);
-        proxy.readBlob(addr_lb, log_buf.data() + length_2, log_next_idx);
+        proxy.readBlob(lb->address + log_first_idx, log_buf.data(), length_2);
+        proxy.readBlob(lb->address, log_buf.data() + length_2, log_next_idx);
     }
 
     // Print dmesg buffer content
index b88051a5573cba709d870c9f428528b1aacfb453..34406ebc5051572104d522aef27bb68276fceda4 100644 (file)
@@ -98,9 +98,9 @@ class KernelWorkload : public Workload
     }
 
     bool
-    insertSymbol(Addr address, const std::string &symbol) override
+    insertSymbol(const Loader::Symbol &symbol) override
     {
-        return kernelSymtab->insert(address, symbol);
+        return kernelSymtab->insert(symbol);
     }
 
     void initState() override;
index c65fdc0162aec47cc209eb1d4388084cac2e34ce..64a9c449e78daa4f574ed4bc94b7846f7a667882 100644 (file)
@@ -241,8 +241,10 @@ loadsymbol(ThreadContext *tc)
         if (!to_number(address, addr))
             continue;
 
-        if (!tc->getSystemPtr()->workload->insertSymbol(addr, symbol))
+        if (!tc->getSystemPtr()->workload->insertSymbol(
+                    { Loader::Symbol::Binding::Global, symbol, addr })) {
             continue;
+        }
 
 
         DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
@@ -263,8 +265,10 @@ addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr)
 
     DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
 
-    tc->getSystemPtr()->workload->insertSymbol(addr, symbol);
-    Loader::debugSymbolTable->insert(addr, symbol);
+    tc->getSystemPtr()->workload->insertSymbol(
+            { Loader::Symbol::Binding::Global, symbol, addr });
+    Loader::debugSymbolTable->insert(
+            { Loader::Symbol::Binding::Global, symbol, addr });
 }
 
 uint64_t
index ca2dffbd4d055193723a97495f4ed1efe021ba13..e24aa746e8be0589277e1d8a4c3f73571b1e16fb 100644 (file)
@@ -50,7 +50,7 @@ class Workload : public SimObject
     virtual Loader::Arch getArch() const = 0;
 
     virtual const Loader::SymbolTable *symtab(ThreadContext *tc) = 0;
-    virtual bool insertSymbol(Addr address, const std::string &symbol) = 0;
+    virtual bool insertSymbol(const Loader::Symbol &symbol) = 0;
 
     /** @{ */
     /**
@@ -70,14 +70,12 @@ class Workload : public SimObject
     addFuncEvent(const Loader::SymbolTable *symtab, const char *lbl,
                  const std::string &desc, Args... args)
     {
-        Addr addr M5_VAR_USED = 0; // initialize only to avoid compiler warning
+        auto it = symtab->find(lbl);
+        if (it == symtab->end())
+            return nullptr;
 
-        if (symtab->findAddress(lbl, addr)) {
-            return new T(system, desc, fixFuncEventAddr(addr),
-                          std::forward<Args>(args)...);
-        }
-
-        return nullptr;
+        return new T(system, desc, fixFuncEventAddr(it->address),
+                      std::forward<Args>(args)...);
     }
 
     template <class T>
index f444a90d43ad9c443e136f8d76865d509b6fb9e8..3601fa877fa7b8197ba8ce5d0624f3b2eaa6e4e9 100644 (file)
@@ -52,27 +52,24 @@ main(int argc, char *argv[])
     obj->loadLocalSymbols(&symtab);
 
     if (argc == 2) {
-        Loader::SymbolTable::ATable::const_iterator i =
-            symtab.getAddrTable().begin();
-        Loader::SymbolTable::ATable::const_iterator end =
-            symtab.getAddrTable().end();
-        while (i != end) {
-            cprintf("%#x %s\n", i->first, i->second);
-            ++i;
-        }
+        for (const Loader::Symbol &symbol: symtab)
+            cprintf("%#x %s\n", symbol.address, symbol.name);
     } else {
         string symbol = argv[2];
         Addr address;
 
         if (symbol[0] == '0' && symbol[1] == 'x') {
+            Loader::SymbolTable::const_iterator it;
             if (to_number(symbol, address) &&
-                symtab.findSymbol(address, symbol))
-                cprintf("address = %#x, symbol = %s\n", address, symbol);
-            else
+                (it = symtab.find(address)) != symtab.end()) {
+                cprintf("address = %#x, symbol = %s\n", address, it->name);
+            } else {
                 cprintf("address = %#x was not found\n", address);
+            }
         } else {
-            if (symtab.findAddress(symbol, address))
-                cprintf("symbol = %s address = %#x\n", symbol, address);
+            auto it = symtab.find(symbol);
+            if (it != symtab.end())
+                cprintf("symbol = %s address = %#x\n", symbol, it->address);
             else
                 cprintf("symbol = %s was not found\n", symbol);
         }
index fd006b482e34705b25f88e13ed5c6363f457133b..369e1a4d908d681dfb3c76e707ab6c1b89320f23 100644 (file)
@@ -60,19 +60,21 @@ main(int argc, char *argv[])
     Addr address;
 
     if (!to_number(symbol, address)) {
-        if (!symtab.findAddress(symbol, address)) {
+        auto it = symtab.find(symbol);
+        if (it == symtab.end()) {
             cout << "could not find symbol: " << symbol << endl;
             exit(1);
         }
 
-        cout << symbol << " -> " << "0x" << hex << address << endl;
+        cout << symbol << " -> " << "0x" << hex << it->address << endl;
     } else {
-        if (!symtab.findSymbol(address, symbol)) {
+        auto it = symtab.find(address);
+        if (it == symtab.end()) {
             cout << "could not find address: " << address << endl;
             exit(1);
         }
 
-        cout << "0x" << hex << address << " -> " << symbol<< endl;
+        cout << "0x" << hex << address << " -> " << it->name << endl;
     }
 
     return 0;