diff --git a/src/base/loader/symtab.hh b/src/base/loader/symtab.hh index 03fbb8e244..3e287c278b 100644 --- a/src/base/loader/symtab.hh +++ b/src/base/loader/symtab.hh @@ -1,4 +1,5 @@ /* + * Copyright (c) 2021 Daniel R. Carvalho * Copyright (c) 2002-2005 The Regents of The University of Michigan * All rights reserved. * @@ -64,16 +65,24 @@ class SymbolTable typedef std::shared_ptr SymbolTablePtr; private: + /** Vector containing all the symbols in the table. */ typedef std::vector SymbolVector; - // Map addresses to an index into the symbol vector. + /** Map addresses to an index into the symbol vector. */ typedef std::multimap AddrMap; - // Map a symbol name to an index into the symbol vector. + /** Map a symbol name to an index into the symbol vector. */ typedef std::map NameMap; SymbolVector symbols; AddrMap addrMap; NameMap nameMap; + /** + * Get the first address larger than the given address, if any. + * + * @param addr The address to compare against. + * @param iter An iterator to the larger-address entry. + * @return True if successful; false if no larger addresses exist. + */ bool upperBound(Addr addr, AddrMap::const_iterator &iter) const { @@ -87,8 +96,21 @@ class SymbolTable return true; } + /** + * A function that applies an operation on a symbol with respect to a + * symbol table. The operation can, for example, simply add the symbol + * to the table; modify and insert the symbol; do nothing at all; etc. + */ typedef std::function SymTabOp; + + /** + * Create a derived symbol table by applying an operation on the symbols + * of the current table. The current table is not modified. + * + * @param op The operation to be applied to the new table. + * @return The new table. + */ SymbolTablePtr operate(SymTabOp op) const { @@ -98,7 +120,20 @@ class SymbolTable return symtab; } + /** + * A function that applies a condition to the symbol provided to decide + * whether the symbol is accepted, or if it must be filtered out. + */ typedef std::function SymTabFilter; + + /** + * Applies a filter to the symbols of the table to generate a new table. + * The filter decides whether the symbols will be inserted in the new + * table or not. + * + * @param filter The filter to be applied. + * @return A new table, filtered. + */ SymbolTablePtr filter(SymTabFilter filter) const { @@ -111,6 +146,13 @@ class SymbolTable return operate(apply_filter); } + /** + * Generate a new table by applying a filter that only accepts the symbols + * whose binding matches the given binding. + * + * @param The binding that must be matched. + * @return A new table, filtered by binding. + */ SymbolTablePtr filterByBinding(Symbol::Binding binding) const { @@ -124,27 +166,66 @@ class SymbolTable typedef SymbolVector::iterator iterator; typedef SymbolVector::const_iterator const_iterator; + /** @return An iterator to the beginning of the symbol vector. */ const_iterator begin() const { return symbols.begin(); } + + /** @return An iterator to the end of the symbol vector. */ const_iterator end() const { return symbols.end(); } + /** Clears the table. */ void clear(); - // Insert either a single symbol or the contents of an entire symbol table - // into this one. + + /** + * Insert a new symbol in the table if it does not already exist. The + * symbol must have a defined name. + * + * @param symbol The symbol to be inserted. + * @return True if successful; false if table already contains the symbol. + */ bool insert(const Symbol &symbol); + + /** + * Copies the symbols of another table to this table if there are no + * common symbols between the tables. + * + * @param symbol The symbol to be inserted. + * @return True if successful; false if tables contain any common symbols. + */ bool insert(const SymbolTable &other); + + /** + * Verifies whether the table is empty. + * + * @return Whether the symbol table is empty. + */ bool empty() const { return symbols.empty(); } + /** + * Generate a new table by applying an offset to the symbols of the + * current table. The current table is not modified. + * + * @param addr_offset The offset to be applied. + * @return The new table. + */ SymbolTablePtr - offset(Addr by) const + offset(Addr addr_offset) const { - SymTabOp op = [by](SymbolTable &symtab, const Symbol &symbol) { - Symbol sym = symbol; - sym.address += by; - symtab.insert(sym); - }; + SymTabOp op = + [addr_offset](SymbolTable &symtab, const Symbol &symbol) { + Symbol sym = symbol; + sym.address += addr_offset; + symtab.insert(sym); + }; return operate(op); } + /** + * Generate a new table by a mask to the symbols of the current table. + * The current table is not modified. + * + * @param m The mask to be applied. + * @return The new table. + */ SymbolTablePtr mask(Addr m) const { @@ -156,10 +237,13 @@ class SymbolTable return operate(op); } - /// Modify symbol name with a given transform function. - /// @param func The transform function accepting the reference of - /// symbol name. - /// @retval SymbolTablePtr A pointer to the modified SymbolTable copy. + /** + * Modify the symbols' name with a given transform function. + * + * @param func The transform function accepting the reference of the + * symbol's name. + * @retval SymbolTablePtr A pointer to the modified SymbolTable copy. + */ SymbolTablePtr rename(std::function func) const { @@ -171,28 +255,66 @@ class SymbolTable return operate(op); } + /** + * Generates a new symbol table containing only global symbols. + * + * @return The new table. + */ SymbolTablePtr globals() const { return filterByBinding(Symbol::Binding::Global); } + /** + * Generates a new symbol table containing only local symbols. + * + * @return The new table. + */ SymbolTablePtr locals() const { return filterByBinding(Symbol::Binding::Local); } + /** + * Generates a new symbol table containing only weak symbols. + * + * @return The new table. + */ SymbolTablePtr weaks() const { return filterByBinding(Symbol::Binding::Weak); } + /** + * Serialize the table's contents. + * + * @param base The base section. + * @param cp The checkpoint to use. + */ void serialize(const std::string &base, CheckpointOut &cp) const; + + /** + * Populate the table by unserializing a checkpoint. + * + * @param base The base section. + * @param cp The checkpoint to use. + * @param default_binding The binding to be used if an unserialized + * symbol's binding is not found. + */ void unserialize(const std::string &base, CheckpointIn &cp, Symbol::Binding default_binding=Symbol::Binding::Global); + /** + * Search for a symbol by its address. Since many symbols can map to the + * same address, this function returns the first found. If the symbol is + * not found this function returns the end() iterator. + * + * @param address The address of the symbol being searched for. + * @return A const iterator to the symbol. end() if not found. + */ const_iterator find(Addr address) const { @@ -205,6 +327,13 @@ class SymbolTable return symbols.begin() + i->second; } + /** + * Search for a symbol by its name. If the symbol is not found this + * function returns the end() iterator. + * + * @param name The name of the symbol being searched for. + * @return A const iterator to the symbol. end() if not found. + */ const_iterator find(const std::string &name) const { @@ -215,26 +344,31 @@ class SymbolTable 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 nextaddr Address of following symbol (for - /// determining valid range of symbol). - /// @retval A const_iterator which points to the symbol if found, or end. + /** + * 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 next_addr Address of following symbol (to determine the valid + * range of the symbol). + * @retval A const_iterator which points to the symbol if found, or end. + */ const_iterator - findNearest(Addr addr, Addr &nextaddr) const + findNearest(Addr addr, Addr &next_addr) const { AddrMap::const_iterator i = addrMap.end(); if (!upperBound(addr, i)) return end(); - nextaddr = i->first; + next_addr = i->first; --i; return symbols.begin() + i->second; } - /// Overload for findNearestSymbol() for callers who don't care - /// about nextaddr. + /** + * Overload for findNearestSymbol() for callers who don't care + * about nextaddr. + */ const_iterator findNearest(Addr addr) const { @@ -247,10 +381,12 @@ class SymbolTable } }; -/// Global unified debugging symbol table (for target). Conceptually -/// there should be one of these per System object for full system, -/// and per Process object for non-full-system, but so far one big -/// global one has worked well enough. +/** + * Global unified debugging symbol table (for target). Conceptually + * there should be one of these per System object for full system, + * and per Process object for non-full-system, but so far one big + * global one has worked well enough. + */ extern SymbolTable debugSymbolTable; } // namespace loader