nativetrace.cc revision 4776
14776Sgblack@eecs.umich.edu/* 24776Sgblack@eecs.umich.edu * Copyright (c) 2001-2005 The Regents of The University of Michigan 34776Sgblack@eecs.umich.edu * All rights reserved. 44776Sgblack@eecs.umich.edu * 54776Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 64776Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 74776Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 84776Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 94776Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 104776Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 114776Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 124776Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 134776Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 144776Sgblack@eecs.umich.edu * this software without specific prior written permission. 154776Sgblack@eecs.umich.edu * 164776Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 174776Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 184776Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 194776Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 204776Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 214776Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 224776Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 234776Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 244776Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 254776Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 264776Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 274776Sgblack@eecs.umich.edu * 284776Sgblack@eecs.umich.edu * Authors: Steve Reinhardt 294776Sgblack@eecs.umich.edu * Lisa Hsu 304776Sgblack@eecs.umich.edu * Nathan Binkert 314776Sgblack@eecs.umich.edu * Steve Raasch 324776Sgblack@eecs.umich.edu */ 334776Sgblack@eecs.umich.edu 344776Sgblack@eecs.umich.edu#include <errno.h> 354776Sgblack@eecs.umich.edu 364776Sgblack@eecs.umich.edu#include "arch/regfile.hh" 374776Sgblack@eecs.umich.edu#include "arch/utility.hh" 384776Sgblack@eecs.umich.edu#include "base/loader/symtab.hh" 394776Sgblack@eecs.umich.edu#include "base/socket.hh" 404776Sgblack@eecs.umich.edu#include "cpu/nativetrace.hh" 414776Sgblack@eecs.umich.edu#include "cpu/static_inst.hh" 424776Sgblack@eecs.umich.edu#include "cpu/thread_context.hh" 434776Sgblack@eecs.umich.edu#include "params/NativeTrace.hh" 444776Sgblack@eecs.umich.edu 454776Sgblack@eecs.umich.edu//XXX This is temporary 464776Sgblack@eecs.umich.edu#include "arch/isa_specific.hh" 474776Sgblack@eecs.umich.edu 484776Sgblack@eecs.umich.eduusing namespace std; 494776Sgblack@eecs.umich.eduusing namespace TheISA; 504776Sgblack@eecs.umich.edu 514776Sgblack@eecs.umich.edunamespace Trace { 524776Sgblack@eecs.umich.edu 534776Sgblack@eecs.umich.eduNativeTrace::NativeTrace(const std::string & _name) : InstTracer(_name) 544776Sgblack@eecs.umich.edu{ 554776Sgblack@eecs.umich.edu int port = 8000; 564776Sgblack@eecs.umich.edu while(!native_listener.listen(port, true)) 574776Sgblack@eecs.umich.edu { 584776Sgblack@eecs.umich.edu DPRINTF(GDBMisc, "Can't bind port %d\n", port); 594776Sgblack@eecs.umich.edu port++; 604776Sgblack@eecs.umich.edu } 614776Sgblack@eecs.umich.edu ccprintf(cerr, "Listening for native process on port %d\n", port); 624776Sgblack@eecs.umich.edu fd = native_listener.accept(); 634776Sgblack@eecs.umich.edu} 644776Sgblack@eecs.umich.edu 654776Sgblack@eecs.umich.edubool 664776Sgblack@eecs.umich.eduNativeTraceRecord::checkIntReg(const char * regName, int index, int size) 674776Sgblack@eecs.umich.edu{ 684776Sgblack@eecs.umich.edu uint64_t regVal; 694776Sgblack@eecs.umich.edu int res = read(parent->fd, ®Val, size); 704776Sgblack@eecs.umich.edu if(res < 0) 714776Sgblack@eecs.umich.edu panic("Read call failed! %s\n", strerror(errno)); 724776Sgblack@eecs.umich.edu regVal = TheISA::gtoh(regVal); 734776Sgblack@eecs.umich.edu uint64_t realRegVal = thread->readIntReg(index); 744776Sgblack@eecs.umich.edu if(regVal != realRegVal) 754776Sgblack@eecs.umich.edu { 764776Sgblack@eecs.umich.edu DPRINTFN("Register %s should be %#x but is %#x.\n", 774776Sgblack@eecs.umich.edu regName, regVal, realRegVal); 784776Sgblack@eecs.umich.edu return false; 794776Sgblack@eecs.umich.edu } 804776Sgblack@eecs.umich.edu return true; 814776Sgblack@eecs.umich.edu} 824776Sgblack@eecs.umich.edu 834776Sgblack@eecs.umich.edubool NativeTraceRecord::checkPC(const char * regName, int size) 844776Sgblack@eecs.umich.edu{ 854776Sgblack@eecs.umich.edu uint64_t regVal; 864776Sgblack@eecs.umich.edu int res = read(parent->fd, ®Val, size); 874776Sgblack@eecs.umich.edu if(res < 0) 884776Sgblack@eecs.umich.edu panic("Read call failed! %s\n", strerror(errno)); 894776Sgblack@eecs.umich.edu regVal = TheISA::gtoh(regVal); 904776Sgblack@eecs.umich.edu uint64_t realRegVal = thread->readNextPC(); 914776Sgblack@eecs.umich.edu if(regVal != realRegVal) 924776Sgblack@eecs.umich.edu { 934776Sgblack@eecs.umich.edu DPRINTFN("%s should be %#x but is %#x.\n", 944776Sgblack@eecs.umich.edu regName, regVal, realRegVal); 954776Sgblack@eecs.umich.edu return false; 964776Sgblack@eecs.umich.edu } 974776Sgblack@eecs.umich.edu return true; 984776Sgblack@eecs.umich.edu} 994776Sgblack@eecs.umich.edu 1004776Sgblack@eecs.umich.eduvoid 1014776Sgblack@eecs.umich.eduTrace::NativeTraceRecord::dump() 1024776Sgblack@eecs.umich.edu{ 1034776Sgblack@eecs.umich.edu// ostream &outs = Trace::output(); 1044776Sgblack@eecs.umich.edu 1054776Sgblack@eecs.umich.edu //Don't print what happens for each micro-op, just print out 1064776Sgblack@eecs.umich.edu //once at the last op, and for regular instructions. 1074776Sgblack@eecs.umich.edu if(!staticInst->isMicroop() || staticInst->isLastMicroop()) 1084776Sgblack@eecs.umich.edu { 1094776Sgblack@eecs.umich.edu checkIntReg("rax", INTREG_RAX, sizeof(uint64_t)); 1104776Sgblack@eecs.umich.edu checkIntReg("rbx", INTREG_RBX, sizeof(uint64_t)); 1114776Sgblack@eecs.umich.edu checkIntReg("rcx", INTREG_RCX, sizeof(uint64_t)); 1124776Sgblack@eecs.umich.edu checkIntReg("rdx", INTREG_RDX, sizeof(uint64_t)); 1134776Sgblack@eecs.umich.edu checkIntReg("rsp", INTREG_RSP, sizeof(uint64_t)); 1144776Sgblack@eecs.umich.edu checkIntReg("rbp", INTREG_RBP, sizeof(uint64_t)); 1154776Sgblack@eecs.umich.edu checkIntReg("rsi", INTREG_RSI, sizeof(uint64_t)); 1164776Sgblack@eecs.umich.edu checkIntReg("rdi", INTREG_RDI, sizeof(uint64_t)); 1174776Sgblack@eecs.umich.edu checkIntReg("r8", INTREG_R8, sizeof(uint64_t)); 1184776Sgblack@eecs.umich.edu checkIntReg("r9", INTREG_R9, sizeof(uint64_t)); 1194776Sgblack@eecs.umich.edu checkIntReg("r10", INTREG_R10, sizeof(uint64_t)); 1204776Sgblack@eecs.umich.edu checkIntReg("r11", INTREG_R11, sizeof(uint64_t)); 1214776Sgblack@eecs.umich.edu checkIntReg("r12", INTREG_R12, sizeof(uint64_t)); 1224776Sgblack@eecs.umich.edu checkIntReg("r13", INTREG_R13, sizeof(uint64_t)); 1234776Sgblack@eecs.umich.edu checkIntReg("r14", INTREG_R14, sizeof(uint64_t)); 1244776Sgblack@eecs.umich.edu checkIntReg("r15", INTREG_R15, sizeof(uint64_t)); 1254776Sgblack@eecs.umich.edu checkPC("rip", sizeof(uint64_t)); 1264776Sgblack@eecs.umich.edu#if THE_ISA == SPARC_ISA 1274776Sgblack@eecs.umich.edu /*for(int f = 0; f <= 62; f+=2) 1284776Sgblack@eecs.umich.edu { 1294776Sgblack@eecs.umich.edu uint64_t regVal; 1304776Sgblack@eecs.umich.edu int res = read(fd, ®Val, sizeof(regVal)); 1314776Sgblack@eecs.umich.edu if(res < 0) 1324776Sgblack@eecs.umich.edu panic("First read call failed! %s\n", strerror(errno)); 1334776Sgblack@eecs.umich.edu regVal = TheISA::gtoh(regVal); 1344776Sgblack@eecs.umich.edu uint64_t realRegVal = thread->readFloatRegBits(f, 64); 1354776Sgblack@eecs.umich.edu if(regVal != realRegVal) 1364776Sgblack@eecs.umich.edu { 1374776Sgblack@eecs.umich.edu DPRINTF(ExecRegDelta, "Register f%d should be %#x but is %#x.\n", f, regVal, realRegVal); 1384776Sgblack@eecs.umich.edu } 1394776Sgblack@eecs.umich.edu }*/ 1404776Sgblack@eecs.umich.edu uint64_t regVal; 1414776Sgblack@eecs.umich.edu int res = read(fd, ®Val, sizeof(regVal)); 1424776Sgblack@eecs.umich.edu if(res < 0) 1434776Sgblack@eecs.umich.edu panic("First read call failed! %s\n", strerror(errno)); 1444776Sgblack@eecs.umich.edu regVal = TheISA::gtoh(regVal); 1454776Sgblack@eecs.umich.edu uint64_t realRegVal = thread->readNextPC(); 1464776Sgblack@eecs.umich.edu if(regVal != realRegVal) 1474776Sgblack@eecs.umich.edu { 1484776Sgblack@eecs.umich.edu DPRINTF(ExecRegDelta, 1494776Sgblack@eecs.umich.edu "Register pc should be %#x but is %#x.\n", 1504776Sgblack@eecs.umich.edu regVal, realRegVal); 1514776Sgblack@eecs.umich.edu } 1524776Sgblack@eecs.umich.edu res = read(fd, ®Val, sizeof(regVal)); 1534776Sgblack@eecs.umich.edu if(res < 0) 1544776Sgblack@eecs.umich.edu panic("First read call failed! %s\n", strerror(errno)); 1554776Sgblack@eecs.umich.edu regVal = TheISA::gtoh(regVal); 1564776Sgblack@eecs.umich.edu realRegVal = thread->readNextNPC(); 1574776Sgblack@eecs.umich.edu if(regVal != realRegVal) 1584776Sgblack@eecs.umich.edu { 1594776Sgblack@eecs.umich.edu DPRINTF(ExecRegDelta, 1604776Sgblack@eecs.umich.edu "Register npc should be %#x but is %#x.\n", 1614776Sgblack@eecs.umich.edu regVal, realRegVal); 1624776Sgblack@eecs.umich.edu } 1634776Sgblack@eecs.umich.edu res = read(fd, ®Val, sizeof(regVal)); 1644776Sgblack@eecs.umich.edu if(res < 0) 1654776Sgblack@eecs.umich.edu panic("First read call failed! %s\n", strerror(errno)); 1664776Sgblack@eecs.umich.edu regVal = TheISA::gtoh(regVal); 1674776Sgblack@eecs.umich.edu realRegVal = thread->readIntReg(SparcISA::NumIntArchRegs + 2); 1684776Sgblack@eecs.umich.edu if((regVal & 0xF) != (realRegVal & 0xF)) 1694776Sgblack@eecs.umich.edu { 1704776Sgblack@eecs.umich.edu DPRINTF(ExecRegDelta, 1714776Sgblack@eecs.umich.edu "Register ccr should be %#x but is %#x.\n", 1724776Sgblack@eecs.umich.edu regVal, realRegVal); 1734776Sgblack@eecs.umich.edu } 1744776Sgblack@eecs.umich.edu#endif 1754776Sgblack@eecs.umich.edu } 1764776Sgblack@eecs.umich.edu} 1774776Sgblack@eecs.umich.edu 1784776Sgblack@eecs.umich.edu/* namespace Trace */ } 1794776Sgblack@eecs.umich.edu 1804776Sgblack@eecs.umich.edu//////////////////////////////////////////////////////////////////////// 1814776Sgblack@eecs.umich.edu// 1824776Sgblack@eecs.umich.edu// ExeTracer Simulation Object 1834776Sgblack@eecs.umich.edu// 1844776Sgblack@eecs.umich.eduTrace::NativeTrace * 1854776Sgblack@eecs.umich.eduNativeTraceParams::create() 1864776Sgblack@eecs.umich.edu{ 1874776Sgblack@eecs.umich.edu return new Trace::NativeTrace(name); 1884776Sgblack@eecs.umich.edu}; 189