sim: Add some methods to create derived symbol tables.
authorGabe Black <gabeblack@google.com>
Wed, 22 Jan 2020 03:29:03 +0000 (19:29 -0800)
committerGabe Black <gabeblack@google.com>
Wed, 20 May 2020 02:37:54 +0000 (02:37 +0000)
These tables are based on passing the symbols in the current table
through some sort of operator function which can chose to add those
symbols, modified versions of those symbols, or nothing at all into a
new symbol table.

The new table is returned as a shared_ptr so its memory will be
managed automatically.

Change-Id: I8809336e2fc2fda63b16a0400536116ca852ca13
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/24786
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/base/loader/symtab.hh

index 30f0a4fcb2abd5b73c86233cc24b1a9e77a6e4de..1e99fecd71f5526ecf89627887c388347d4907d5 100644 (file)
 #ifndef __SYMTAB_HH__
 #define __SYMTAB_HH__
 
+#include <functional>
 #include <iosfwd>
 #include <map>
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -56,6 +58,9 @@ struct Symbol
 
 class SymbolTable
 {
+  public:
+    typedef std::shared_ptr<SymbolTable> SymbolTablePtr;
+
   private:
     typedef std::vector<Symbol> SymbolVector;
     // Map addresses to an index into the symbol vector.
@@ -80,6 +85,39 @@ class SymbolTable
         return true;
     }
 
+    typedef std::function<void(SymbolTable &symtab,
+                               const Symbol &symbol)> SymTabOp;
+    SymbolTablePtr
+    operate(SymTabOp op) const
+    {
+        SymbolTablePtr symtab(new SymbolTable);
+        for (const auto &symbol: symbols)
+            op(*symtab, symbol);
+        return symtab;
+    }
+
+    typedef std::function<bool(const Symbol &symbol)> SymTabFilter;
+    SymbolTablePtr
+    filter(SymTabFilter filter) const
+    {
+        SymTabOp apply_filter =
+            [filter](SymbolTable &symtab, const Symbol &symbol) {
+            if (filter(symbol)) {
+                symtab.insert(symbol);
+            }
+        };
+        return operate(apply_filter);
+    }
+
+    SymbolTablePtr
+    filterByBinding(Symbol::Binding binding) const
+    {
+        auto filt = [binding](const Symbol &symbol) {
+            return symbol.binding == binding;
+        };
+        return filter(filt);
+    }
+
   public:
     typedef SymbolVector::iterator iterator;
     typedef SymbolVector::const_iterator const_iterator;
@@ -95,6 +133,46 @@ class SymbolTable
     bool load(const std::string &file);
     bool empty() const { return symbols.empty(); }
 
+    SymbolTablePtr
+    offset(Addr by) const
+    {
+        SymTabOp op = [by](SymbolTable &symtab, const Symbol &symbol) {
+            Symbol sym = symbol;
+            sym.address += by;
+            symtab.insert(sym);
+        };
+        return operate(op);
+    }
+
+    SymbolTablePtr
+    mask(Addr m) const
+    {
+        SymTabOp op = [m](SymbolTable &symtab, const Symbol &symbol) {
+            Symbol sym = symbol;
+            sym.address &= m;
+            symtab.insert(sym);
+        };
+        return operate(op);
+    }
+
+    SymbolTablePtr
+    globals() const
+    {
+        return filterByBinding(Symbol::Binding::Global);
+    }
+
+    SymbolTablePtr
+    locals() const
+    {
+        return filterByBinding(Symbol::Binding::Local);
+    }
+
+    SymbolTablePtr
+    weaks() const
+    {
+        return filterByBinding(Symbol::Binding::Weak);
+    }
+
     void serialize(const std::string &base, CheckpointOut &cp) const;
     void unserialize(const std::string &base, CheckpointIn &cp,
                      Symbol::Binding default_binding=Symbol::Binding::Global);