15882Snate@binkert.org/* 25882Snate@binkert.org * Copyright (c) 2003-2005 The Regents of The University of Michigan 35882Snate@binkert.org * All rights reserved. 45882Snate@binkert.org * 55882Snate@binkert.org * Redistribution and use in source and binary forms, with or without 65882Snate@binkert.org * modification, are permitted provided that the following conditions are 75882Snate@binkert.org * met: redistributions of source code must retain the above copyright 85882Snate@binkert.org * notice, this list of conditions and the following disclaimer; 95882Snate@binkert.org * redistributions in binary form must reproduce the above copyright 105882Snate@binkert.org * notice, this list of conditions and the following disclaimer in the 115882Snate@binkert.org * documentation and/or other materials provided with the distribution; 125882Snate@binkert.org * neither the name of the copyright holders nor the names of its 135882Snate@binkert.org * contributors may be used to endorse or promote products derived from 145882Snate@binkert.org * this software without specific prior written permission. 155882Snate@binkert.org * 165882Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 175882Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 185882Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 195882Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 205882Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 215882Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 225882Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 235882Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245882Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255882Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 265882Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275882Snate@binkert.org * 285882Snate@binkert.org * Authors: Nathan Binkert 295882Snate@binkert.org */ 305882Snate@binkert.org 3111793Sbrandon.potter@amd.com#include "base/debug.hh" 3211793Sbrandon.potter@amd.com 335882Snate@binkert.org#include <sys/types.h> 345882Snate@binkert.org#include <unistd.h> 355882Snate@binkert.org 368232Snate@binkert.org#include <algorithm> 378229Snate@binkert.org#include <csignal> 388229Snate@binkert.org 395882Snate@binkert.org#include "base/cprintf.hh" 4012334Sgabeblack@google.com#include "base/logging.hh" 418232Snate@binkert.org 428232Snate@binkert.orgusing namespace std; 435882Snate@binkert.org 448231Snate@binkert.orgnamespace Debug { 458231Snate@binkert.org 468232Snate@binkert.org// 478232Snate@binkert.org// This function will cause the process to signal itself with a 488232Snate@binkert.org// SIGTRAP which is ignored if not in gdb, but will cause the debugger 498232Snate@binkert.org// to break if in gdb. 508232Snate@binkert.org// 515882Snate@binkert.orgvoid 528231Snate@binkert.orgbreakpoint() 535882Snate@binkert.org{ 545882Snate@binkert.org#ifndef NDEBUG 555882Snate@binkert.org kill(getpid(), SIGTRAP); 565882Snate@binkert.org#else 578231Snate@binkert.org cprintf("Debug::breakpoint suppressed, compiled with NDEBUG\n"); 585882Snate@binkert.org#endif 595882Snate@binkert.org} 608231Snate@binkert.org 618232Snate@binkert.org// 628232Snate@binkert.org// Flags for debugging purposes. Primarily for trace.hh 638232Snate@binkert.org// 648232Snate@binkert.orgint allFlagsVersion = 0; 658232Snate@binkert.orgFlagsMap & 668232Snate@binkert.orgallFlags() 678232Snate@binkert.org{ 688232Snate@binkert.org static FlagsMap flags; 698232Snate@binkert.org return flags; 708232Snate@binkert.org} 718232Snate@binkert.org 7211153SCurtis.Dunham@arm.combool SimpleFlag::_active = false; 7311153SCurtis.Dunham@arm.com 748232Snate@binkert.orgFlag * 758232Snate@binkert.orgfindFlag(const std::string &name) 768232Snate@binkert.org{ 778232Snate@binkert.org FlagsMap::iterator i = allFlags().find(name); 788232Snate@binkert.org if (i == allFlags().end()) 798232Snate@binkert.org return NULL; 808232Snate@binkert.org return i->second; 818232Snate@binkert.org} 828232Snate@binkert.org 838232Snate@binkert.orgFlag::Flag(const char *name, const char *desc) 848232Snate@binkert.org : _name(name), _desc(desc) 858232Snate@binkert.org{ 868232Snate@binkert.org pair<FlagsMap::iterator, bool> result = 878232Snate@binkert.org allFlags().insert(make_pair(name, this)); 888232Snate@binkert.org 898232Snate@binkert.org if (!result.second) 908232Snate@binkert.org panic("Flag %s already defined!", name); 918232Snate@binkert.org 928232Snate@binkert.org ++allFlagsVersion; 938232Snate@binkert.org} 948232Snate@binkert.org 958232Snate@binkert.orgFlag::~Flag() 968232Snate@binkert.org{ 978232Snate@binkert.org // should find and remove flag. 988232Snate@binkert.org} 998232Snate@binkert.org 1008232Snate@binkert.orgvoid 10111153SCurtis.Dunham@arm.comSimpleFlag::enableAll() 10211153SCurtis.Dunham@arm.com{ 10311153SCurtis.Dunham@arm.com _active = true; 10411153SCurtis.Dunham@arm.com for (auto& i : allFlags()) 10511153SCurtis.Dunham@arm.com i.second->sync(); 10611153SCurtis.Dunham@arm.com} 10711153SCurtis.Dunham@arm.com 10811153SCurtis.Dunham@arm.comvoid 10911153SCurtis.Dunham@arm.comSimpleFlag::disableAll() 11011153SCurtis.Dunham@arm.com{ 11111153SCurtis.Dunham@arm.com _active = false; 11211153SCurtis.Dunham@arm.com for (auto& i : allFlags()) 11311153SCurtis.Dunham@arm.com i.second->sync(); 11411153SCurtis.Dunham@arm.com} 11511153SCurtis.Dunham@arm.com 11611153SCurtis.Dunham@arm.comvoid 1178232Snate@binkert.orgCompoundFlag::enable() 1188232Snate@binkert.org{ 11911153SCurtis.Dunham@arm.com for (auto& k : _kids) 12011153SCurtis.Dunham@arm.com k->enable(); 1218232Snate@binkert.org} 1228232Snate@binkert.org 1238232Snate@binkert.orgvoid 1248232Snate@binkert.orgCompoundFlag::disable() 1258232Snate@binkert.org{ 12611153SCurtis.Dunham@arm.com for (auto& k : _kids) 12711153SCurtis.Dunham@arm.com k->disable(); 1288232Snate@binkert.org} 1298232Snate@binkert.org 1308232Snate@binkert.orgstruct AllFlags : public Flag 1318232Snate@binkert.org{ 1328232Snate@binkert.org AllFlags() 1338232Snate@binkert.org : Flag("All", "All Flags") 1348232Snate@binkert.org {} 1358232Snate@binkert.org 1368232Snate@binkert.org void 1378232Snate@binkert.org enable() 1388232Snate@binkert.org { 1398232Snate@binkert.org FlagsMap::iterator i = allFlags().begin(); 1408232Snate@binkert.org FlagsMap::iterator end = allFlags().end(); 1418232Snate@binkert.org for (; i != end; ++i) 1428232Snate@binkert.org if (i->second != this) 1438232Snate@binkert.org i->second->enable(); 1448232Snate@binkert.org } 1458232Snate@binkert.org 1468232Snate@binkert.org void 1478232Snate@binkert.org disable() 1488232Snate@binkert.org { 1498232Snate@binkert.org FlagsMap::iterator i = allFlags().begin(); 1508232Snate@binkert.org FlagsMap::iterator end = allFlags().end(); 1518232Snate@binkert.org for (; i != end; ++i) 1528232Snate@binkert.org if (i->second != this) 1538699Ssteve.reinhardt@amd.com i->second->disable(); 1548232Snate@binkert.org } 1558232Snate@binkert.org}; 1568232Snate@binkert.org 1578232Snate@binkert.orgAllFlags theAllFlags; 1588232Snate@binkert.orgFlag *const All = &theAllFlags; 1598232Snate@binkert.org 1608232Snate@binkert.orgbool 1618232Snate@binkert.orgchangeFlag(const char *s, bool value) 1628232Snate@binkert.org{ 1638232Snate@binkert.org Flag *f = findFlag(s); 1648232Snate@binkert.org if (!f) 1658232Snate@binkert.org return false; 1668232Snate@binkert.org 1678232Snate@binkert.org if (value) 1688232Snate@binkert.org f->enable(); 1698232Snate@binkert.org else 1708232Snate@binkert.org f->disable(); 1718232Snate@binkert.org 1728232Snate@binkert.org return true; 1738232Snate@binkert.org} 1748232Snate@binkert.org 1758231Snate@binkert.org} // namespace Debug 1768232Snate@binkert.org 1778232Snate@binkert.org// add a set of functions that can easily be invoked from gdb 1788232Snate@binkert.orgvoid 1798232Snate@binkert.orgsetDebugFlag(const char *string) 1808232Snate@binkert.org{ 1818232Snate@binkert.org Debug::changeFlag(string, true); 1828232Snate@binkert.org} 1838232Snate@binkert.org 1848232Snate@binkert.orgvoid 1858232Snate@binkert.orgclearDebugFlag(const char *string) 1868232Snate@binkert.org{ 1878232Snate@binkert.org Debug::changeFlag(string, false); 1888232Snate@binkert.org} 1898232Snate@binkert.org 1908232Snate@binkert.orgvoid 1918232Snate@binkert.orgdumpDebugFlags() 1928232Snate@binkert.org{ 1938232Snate@binkert.org using namespace Debug; 1948232Snate@binkert.org FlagsMap::iterator i = allFlags().begin(); 1958232Snate@binkert.org FlagsMap::iterator end = allFlags().end(); 1968232Snate@binkert.org for (; i != end; ++i) { 1978232Snate@binkert.org SimpleFlag *f = dynamic_cast<SimpleFlag *>(i->second); 1988232Snate@binkert.org if (f && f->status()) 1998232Snate@binkert.org cprintf("%s\n", f->name()); 2008232Snate@binkert.org } 2018232Snate@binkert.org} 202