symtab.hh revision 11537
12SN/A/*
21762SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan
32SN/A * All rights reserved.
42SN/A *
52SN/A * Redistribution and use in source and binary forms, with or without
62SN/A * modification, are permitted provided that the following conditions are
72SN/A * met: redistributions of source code must retain the above copyright
82SN/A * notice, this list of conditions and the following disclaimer;
92SN/A * redistributions in binary form must reproduce the above copyright
102SN/A * notice, this list of conditions and the following disclaimer in the
112SN/A * documentation and/or other materials provided with the distribution;
122SN/A * neither the name of the copyright holders nor the names of its
132SN/A * contributors may be used to endorse or promote products derived from
142SN/A * this software without specific prior written permission.
152SN/A *
162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert
292665Ssaidi@eecs.umich.edu *          Steve Reinhardt
302SN/A */
312SN/A
322SN/A#ifndef __SYMTAB_HH__
332SN/A#define __SYMTAB_HH__
342SN/A
351984SN/A#include <iosfwd>
36857SN/A#include <map>
375952Ssaidi@eecs.umich.edu#include <string>
381984SN/A
396214Snate@binkert.org#include "base/types.hh"
4010905Sandreas.sandberg@arm.com#include "sim/serialize.hh"
412SN/A
422SN/Aclass SymbolTable
432SN/A{
441912SN/A  public:
4511537Sandreas.sandberg@arm.com    typedef std::multimap<Addr, std::string> ATable;
46857SN/A    typedef std::map<std::string, Addr> STable;
472SN/A
481912SN/A  private:
492SN/A    ATable addrTable;
502SN/A    STable symbolTable;
512SN/A
521912SN/A  private:
531912SN/A    bool
541912SN/A    upperBound(Addr addr, ATable::const_iterator &iter) const
551912SN/A    {
561912SN/A        // find first key *larger* than desired address
571912SN/A        iter = addrTable.upper_bound(addr);
581912SN/A
591912SN/A        // if very first key is larger, we're out of luck
601912SN/A        if (iter == addrTable.begin())
611912SN/A            return false;
621912SN/A
631912SN/A        return true;
641912SN/A    }
651912SN/A
662SN/A  public:
672SN/A    SymbolTable() {}
682SN/A    SymbolTable(const std::string &file) { load(file); }
692SN/A    ~SymbolTable() {}
702SN/A
711984SN/A    void clear();
722SN/A    bool insert(Addr address, std::string symbol);
732SN/A    bool load(const std::string &file);
742SN/A
751912SN/A    const ATable &getAddrTable() const { return addrTable; }
761912SN/A    const STable &getSymbolTable() const { return symbolTable; }
771912SN/A
781912SN/A  public:
7910905Sandreas.sandberg@arm.com    void serialize(const std::string &base, CheckpointOut &cp) const;
8010905Sandreas.sandberg@arm.com    void unserialize(const std::string &base, CheckpointIn &cp);
811984SN/A
821984SN/A  public:
831912SN/A    bool
841912SN/A    findSymbol(Addr address, std::string &symbol) const
851912SN/A    {
861912SN/A        ATable::const_iterator i = addrTable.find(address);
871912SN/A        if (i == addrTable.end())
881912SN/A            return false;
891912SN/A
9011537Sandreas.sandberg@arm.com        // There are potentially multiple symbols that map to the same
9111537Sandreas.sandberg@arm.com        // address. For simplicity, just return the first one.
921912SN/A        symbol = (*i).second;
931912SN/A        return true;
941912SN/A    }
951912SN/A
961912SN/A    bool
971912SN/A    findAddress(const std::string &symbol, Addr &address) const
981912SN/A    {
991912SN/A        STable::const_iterator i = symbolTable.find(symbol);
1001912SN/A        if (i == symbolTable.end())
1011912SN/A            return false;
1021912SN/A
1031912SN/A        address = (*i).second;
1041912SN/A        return true;
1051912SN/A    }
1061912SN/A
1071158SN/A    /// Find the nearest symbol equal to or less than the supplied
1081158SN/A    /// address (e.g., the label for the enclosing function).
1092982Sstever@eecs.umich.edu    /// @param addr     The address to look up.
1102982Sstever@eecs.umich.edu    /// @param symbol   Return reference for symbol string.
1112982Sstever@eecs.umich.edu    /// @param symaddr  Return reference for symbol address.
1122982Sstever@eecs.umich.edu    /// @param nextaddr Address of following symbol (for
1132982Sstever@eecs.umich.edu    ///                 determining valid range of symbol).
1141158SN/A    /// @retval True if a symbol was found.
1151912SN/A    bool
1161912SN/A    findNearestSymbol(Addr addr, std::string &symbol, Addr &symaddr,
1171912SN/A                      Addr &nextaddr) const
1181912SN/A    {
1191912SN/A        ATable::const_iterator i;
1201912SN/A        if (!upperBound(addr, i))
1211912SN/A            return false;
1221912SN/A
1231912SN/A        nextaddr = i->first;
1241912SN/A        --i;
1251912SN/A        symaddr = i->first;
1261912SN/A        symbol = i->second;
1271912SN/A        return true;
1281912SN/A    }
1291158SN/A
1301158SN/A    /// Overload for findNearestSymbol() for callers who don't care
1312982Sstever@eecs.umich.edu    /// about nextaddr.
1321912SN/A    bool
1331912SN/A    findNearestSymbol(Addr addr, std::string &symbol, Addr &symaddr) const
1341158SN/A    {
1351912SN/A        ATable::const_iterator i;
1361912SN/A        if (!upperBound(addr, i))
1371912SN/A            return false;
1381912SN/A
1391912SN/A        --i;
1401912SN/A        symaddr = i->first;
1411912SN/A        symbol = i->second;
1421912SN/A        return true;
1431158SN/A    }
1441158SN/A
1451158SN/A
1461912SN/A    bool
1471912SN/A    findNearestAddr(Addr addr, Addr &symaddr, Addr &nextaddr) const
1481912SN/A    {
1491912SN/A        ATable::const_iterator i;
1501912SN/A        if (!upperBound(addr, i))
1511912SN/A            return false;
1521912SN/A
1531912SN/A        nextaddr = i->first;
1541912SN/A        --i;
1551912SN/A        symaddr = i->first;
1561912SN/A        return true;
1571912SN/A    }
1581912SN/A
1591912SN/A    bool
1601912SN/A    findNearestAddr(Addr addr, Addr &symaddr) const
1611912SN/A    {
1621912SN/A        ATable::const_iterator i;
1631912SN/A        if (!upperBound(addr, i))
1641912SN/A            return false;
1651912SN/A
1661912SN/A        --i;
1671912SN/A        symaddr = i->first;
1681912SN/A        return true;
1691912SN/A    }
1702SN/A};
1712SN/A
1721158SN/A/// Global unified debugging symbol table (for target).  Conceptually
1731158SN/A/// there should be one of these per System object for full system,
1741158SN/A/// and per Process object for non-full-system, but so far one big
1751158SN/A/// global one has worked well enough.
1761158SN/Aextern SymbolTable *debugSymbolTable;
1771158SN/A
1782SN/A#endif // __SYMTAB_HH__
179