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