symtab.hh revision 1912
11689SN/A/*
29444SAndreas.Sandberg@ARM.com * Copyright (c) 2002-2005 The Regents of The University of Michigan
39913Ssteve.reinhardt@amd.com * All rights reserved.
47854SAli.Saidi@ARM.com *
57854SAli.Saidi@ARM.com * Redistribution and use in source and binary forms, with or without
67854SAli.Saidi@ARM.com * modification, are permitted provided that the following conditions are
77854SAli.Saidi@ARM.com * met: redistributions of source code must retain the above copyright
87854SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer;
97854SAli.Saidi@ARM.com * redistributions in binary form must reproduce the above copyright
107854SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer in the
117854SAli.Saidi@ARM.com * documentation and/or other materials provided with the distribution;
127854SAli.Saidi@ARM.com * neither the name of the copyright holders nor the names of its
137854SAli.Saidi@ARM.com * contributors may be used to endorse or promote products derived from
147854SAli.Saidi@ARM.com * this software without specific prior written permission.
152329SN/A *
161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
271689SN/A */
281689SN/A
291689SN/A#ifndef __SYMTAB_HH__
301689SN/A#define __SYMTAB_HH__
311689SN/A
321689SN/A#include <map>
331689SN/A#include "targetarch/isa_traits.hh"	// for Addr
341689SN/A
351689SN/Aclass SymbolTable
361689SN/A{
371689SN/A  public:
381689SN/A    typedef std::map<Addr, std::string> ATable;
391689SN/A    typedef std::map<std::string, Addr> STable;
402665Ssaidi@eecs.umich.edu
412665Ssaidi@eecs.umich.edu  private:
422935Sksewell@umich.edu    ATable addrTable;
431689SN/A    STable symbolTable;
441689SN/A
459944Smatt.horsnell@ARM.com  private:
469944Smatt.horsnell@ARM.com    bool
479944Smatt.horsnell@ARM.com    upperBound(Addr addr, ATable::const_iterator &iter) const
481060SN/A    {
491060SN/A        // find first key *larger* than desired address
503773Sgblack@eecs.umich.edu        iter = addrTable.upper_bound(addr);
516329Sgblack@eecs.umich.edu
526658Snate@binkert.org        // if very first key is larger, we're out of luck
531717SN/A        if (iter == addrTable.begin())
549913Ssteve.reinhardt@amd.com            return false;
558232Snate@binkert.org
568232Snate@binkert.org        return true;
579527SMatt.Horsnell@arm.com    }
585529Snate@binkert.org
591060SN/A  public:
606221Snate@binkert.org    SymbolTable() {}
616221Snate@binkert.org    SymbolTable(const std::string &file) { load(file); }
621061SN/A    ~SymbolTable() {}
635529Snate@binkert.org
644329Sktlim@umich.edu    bool insert(Addr address, std::string symbol);
654329Sktlim@umich.edu    bool load(const std::string &file);
662292SN/A
672292SN/A    const ATable &getAddrTable() const { return addrTable; }
682292SN/A    const STable &getSymbolTable() const { return symbolTable; }
692292SN/A
705529Snate@binkert.org  public:
719920Syasuko.eckert@amd.com    bool
729920Syasuko.eckert@amd.com    findSymbol(Addr address, std::string &symbol) const
731060SN/A    {
742292SN/A        ATable::const_iterator i = addrTable.find(address);
758907Slukefahr@umich.edu        if (i == addrTable.end())
762292SN/A            return false;
772292SN/A
782292SN/A        symbol = (*i).second;
792292SN/A        return true;
802292SN/A    }
812292SN/A
822292SN/A    bool
831060SN/A    findAddress(const std::string &symbol, Addr &address) const
841060SN/A    {
851061SN/A        STable::const_iterator i = symbolTable.find(symbol);
861060SN/A        if (i == symbolTable.end())
872292SN/A            return false;
881062SN/A
891062SN/A        address = (*i).second;
908240Snate@binkert.org        return true;
911062SN/A    }
921062SN/A
931062SN/A    /// Find the nearest symbol equal to or less than the supplied
948240Snate@binkert.org    /// address (e.g., the label for the enclosing function).
951062SN/A    /// @param address The address to look up.
961062SN/A    /// @param symbol  Return reference for symbol string.
971062SN/A    /// @param sym_address Return reference for symbol address.
988240Snate@binkert.org    /// @param next_sym_address Address of following symbol (for
991062SN/A    /// determining valid range of symbol).
1001062SN/A    /// @retval True if a symbol was found.
1012301SN/A    bool
1028240Snate@binkert.org    findNearestSymbol(Addr addr, std::string &symbol, Addr &symaddr,
1032301SN/A                      Addr &nextaddr) const
1042301SN/A    {
1052292SN/A        ATable::const_iterator i;
1068240Snate@binkert.org        if (!upperBound(addr, i))
1072292SN/A            return false;
1082292SN/A
1091062SN/A        nextaddr = i->first;
1108240Snate@binkert.org        --i;
1111062SN/A        symaddr = i->first;
1121062SN/A        symbol = i->second;
1131062SN/A        return true;
1148240Snate@binkert.org    }
1151062SN/A
1161062SN/A    /// Overload for findNearestSymbol() for callers who don't care
1171062SN/A    /// about next_sym_address.
1188240Snate@binkert.org    bool
1191062SN/A    findNearestSymbol(Addr addr, std::string &symbol, Addr &symaddr) const
1201062SN/A    {
1211062SN/A        ATable::const_iterator i;
1228240Snate@binkert.org        if (!upperBound(addr, i))
1232292SN/A            return false;
1241062SN/A
1251062SN/A        --i;
1268240Snate@binkert.org        symaddr = i->first;
1272292SN/A        symbol = i->second;
1281062SN/A        return true;
1292292SN/A    }
1308240Snate@binkert.org
1312292SN/A
1322292SN/A    bool
1331062SN/A    findNearestAddr(Addr addr, Addr &symaddr, Addr &nextaddr) const
1348240Snate@binkert.org    {
1351062SN/A        ATable::const_iterator i;
1361062SN/A        if (!upperBound(addr, i))
1371062SN/A            return false;
1388240Snate@binkert.org
1391062SN/A        nextaddr = i->first;
1401062SN/A        --i;
1411062SN/A        symaddr = i->first;
1428240Snate@binkert.org        return true;
1431062SN/A    }
1441062SN/A
1451062SN/A    bool
1468240Snate@binkert.org    findNearestAddr(Addr addr, Addr &symaddr) const
1471062SN/A    {
1481062SN/A        ATable::const_iterator i;
1491062SN/A        if (!upperBound(addr, i))
1508240Snate@binkert.org            return false;
1511062SN/A
1521062SN/A        --i;
1532301SN/A        symaddr = i->first;
1548240Snate@binkert.org        return true;
1552301SN/A    }
1562301SN/A};
1572301SN/A
1582301SN/A/// Global unified debugging symbol table (for target).  Conceptually
1598240Snate@binkert.org/// there should be one of these per System object for full system,
1602301SN/A/// and per Process object for non-full-system, but so far one big
1612301SN/A/// global one has worked well enough.
1622301SN/Aextern SymbolTable *debugSymbolTable;
1632307SN/A
1648240Snate@binkert.org#endif // __SYMTAB_HH__
1652307SN/A