nativetrace.cc revision 5523
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
535523Snate@binkert.orgNativeTrace::NativeTrace(const Params *p)
545523Snate@binkert.org    : InstTracer(p)
554776Sgblack@eecs.umich.edu{
565523Snate@binkert.org    if (ListenSocket::allDisabled())
575523Snate@binkert.org        fatal("All listeners are disabled!");
585523Snate@binkert.org
594776Sgblack@eecs.umich.edu    int port = 8000;
604776Sgblack@eecs.umich.edu    while(!native_listener.listen(port, true))
614776Sgblack@eecs.umich.edu    {
624776Sgblack@eecs.umich.edu        DPRINTF(GDBMisc, "Can't bind port %d\n", port);
634776Sgblack@eecs.umich.edu        port++;
644776Sgblack@eecs.umich.edu    }
654776Sgblack@eecs.umich.edu    ccprintf(cerr, "Listening for native process on port %d\n", port);
664776Sgblack@eecs.umich.edu    fd = native_listener.accept();
674830Sgblack@eecs.umich.edu    checkRcx = true;
684830Sgblack@eecs.umich.edu    checkR11 = true;
694776Sgblack@eecs.umich.edu}
704776Sgblack@eecs.umich.edu
714776Sgblack@eecs.umich.edubool
724830Sgblack@eecs.umich.eduNativeTrace::checkRcxReg(const char * name, uint64_t &mVal, uint64_t &nVal)
734776Sgblack@eecs.umich.edu{
744830Sgblack@eecs.umich.edu    if(!checkRcx)
754830Sgblack@eecs.umich.edu        checkRcx = (mVal != oldRcxVal || nVal != oldRealRcxVal);
764830Sgblack@eecs.umich.edu    if(checkRcx)
774830Sgblack@eecs.umich.edu        return checkReg(name, mVal, nVal);
784776Sgblack@eecs.umich.edu    return true;
794776Sgblack@eecs.umich.edu}
804776Sgblack@eecs.umich.edu
814830Sgblack@eecs.umich.edubool
824830Sgblack@eecs.umich.eduNativeTrace::checkR11Reg(const char * name, uint64_t &mVal, uint64_t &nVal)
834776Sgblack@eecs.umich.edu{
844830Sgblack@eecs.umich.edu    if(!checkR11)
854830Sgblack@eecs.umich.edu        checkR11 = (mVal != oldR11Val || nVal != oldRealR11Val);
864830Sgblack@eecs.umich.edu    if(checkR11)
874830Sgblack@eecs.umich.edu        return checkReg(name, mVal, nVal);
884776Sgblack@eecs.umich.edu    return true;
894776Sgblack@eecs.umich.edu}
904776Sgblack@eecs.umich.edu
915049Sgblack@eecs.umich.edubool
925049Sgblack@eecs.umich.eduNativeTrace::checkXMM(int num, uint64_t mXmmBuf[], uint64_t nXmmBuf[])
935049Sgblack@eecs.umich.edu{
945049Sgblack@eecs.umich.edu    if (mXmmBuf[num * 2]     != nXmmBuf[num * 2] ||
955049Sgblack@eecs.umich.edu        mXmmBuf[num * 2 + 1] != nXmmBuf[num * 2 + 1]) {
965049Sgblack@eecs.umich.edu        DPRINTFN("Register xmm%d should be 0x%016x%016x but is 0x%016x%016x.\n",
975049Sgblack@eecs.umich.edu                num, nXmmBuf[num * 2 + 1], nXmmBuf[num * 2],
985049Sgblack@eecs.umich.edu                     mXmmBuf[num * 2 + 1], mXmmBuf[num * 2]);
995049Sgblack@eecs.umich.edu        return false;
1005049Sgblack@eecs.umich.edu    }
1015049Sgblack@eecs.umich.edu    return true;
1025049Sgblack@eecs.umich.edu}
1035049Sgblack@eecs.umich.edu
1044776Sgblack@eecs.umich.eduvoid
1054776Sgblack@eecs.umich.eduTrace::NativeTraceRecord::dump()
1064776Sgblack@eecs.umich.edu{
1074776Sgblack@eecs.umich.edu    //Don't print what happens for each micro-op, just print out
1084776Sgblack@eecs.umich.edu    //once at the last op, and for regular instructions.
1094776Sgblack@eecs.umich.edu    if(!staticInst->isMicroop() || staticInst->isLastMicroop())
1104830Sgblack@eecs.umich.edu    parent->check(thread, staticInst->isSyscall());
1114830Sgblack@eecs.umich.edu}
1124830Sgblack@eecs.umich.edu
1134830Sgblack@eecs.umich.eduvoid
1144830Sgblack@eecs.umich.eduTrace::NativeTrace::check(ThreadContext * tc, bool isSyscall)
1154830Sgblack@eecs.umich.edu{
1164830Sgblack@eecs.umich.edu//    ostream &outs = Trace::output();
1174830Sgblack@eecs.umich.edu    nState.update(fd);
1184830Sgblack@eecs.umich.edu    mState.update(tc);
1194830Sgblack@eecs.umich.edu
1204830Sgblack@eecs.umich.edu    if(isSyscall)
1214776Sgblack@eecs.umich.edu    {
1224830Sgblack@eecs.umich.edu        checkRcx = false;
1234830Sgblack@eecs.umich.edu        checkR11 = false;
1244830Sgblack@eecs.umich.edu        oldRcxVal = mState.rcx;
1254830Sgblack@eecs.umich.edu        oldRealRcxVal = nState.rcx;
1264830Sgblack@eecs.umich.edu        oldR11Val = mState.r11;
1274830Sgblack@eecs.umich.edu        oldRealR11Val = nState.r11;
1284830Sgblack@eecs.umich.edu    }
1294830Sgblack@eecs.umich.edu
1304830Sgblack@eecs.umich.edu    checkReg("rax", mState.rax, nState.rax);
1314830Sgblack@eecs.umich.edu    checkRcxReg("rcx", mState.rcx, nState.rcx);
1324830Sgblack@eecs.umich.edu    checkReg("rdx", mState.rdx, nState.rdx);
1334830Sgblack@eecs.umich.edu    checkReg("rbx", mState.rbx, nState.rbx);
1344830Sgblack@eecs.umich.edu    checkReg("rsp", mState.rsp, nState.rsp);
1354830Sgblack@eecs.umich.edu    checkReg("rbp", mState.rbp, nState.rbp);
1364830Sgblack@eecs.umich.edu    checkReg("rsi", mState.rsi, nState.rsi);
1374830Sgblack@eecs.umich.edu    checkReg("rdi", mState.rdi, nState.rdi);
1384830Sgblack@eecs.umich.edu    checkReg("r8",  mState.r8,  nState.r8);
1394830Sgblack@eecs.umich.edu    checkReg("r9",  mState.r9,  nState.r9);
1404830Sgblack@eecs.umich.edu    checkReg("r10", mState.r10, nState.r10);
1414830Sgblack@eecs.umich.edu    checkR11Reg("r11", mState.r11, nState.r11);
1424830Sgblack@eecs.umich.edu    checkReg("r12", mState.r12, nState.r12);
1434830Sgblack@eecs.umich.edu    checkReg("r13", mState.r13, nState.r13);
1444830Sgblack@eecs.umich.edu    checkReg("r14", mState.r14, nState.r14);
1454830Sgblack@eecs.umich.edu    checkReg("r15", mState.r15, nState.r15);
1464830Sgblack@eecs.umich.edu    checkReg("rip", mState.rip, nState.rip);
1475049Sgblack@eecs.umich.edu    checkXMM(0, mState.xmm, nState.xmm);
1485049Sgblack@eecs.umich.edu    checkXMM(1, mState.xmm, nState.xmm);
1495049Sgblack@eecs.umich.edu    checkXMM(2, mState.xmm, nState.xmm);
1505049Sgblack@eecs.umich.edu    checkXMM(3, mState.xmm, nState.xmm);
1515049Sgblack@eecs.umich.edu    checkXMM(4, mState.xmm, nState.xmm);
1525049Sgblack@eecs.umich.edu    checkXMM(5, mState.xmm, nState.xmm);
1535049Sgblack@eecs.umich.edu    checkXMM(6, mState.xmm, nState.xmm);
1545049Sgblack@eecs.umich.edu    checkXMM(7, mState.xmm, nState.xmm);
1555049Sgblack@eecs.umich.edu    checkXMM(8, mState.xmm, nState.xmm);
1565049Sgblack@eecs.umich.edu    checkXMM(9, mState.xmm, nState.xmm);
1575049Sgblack@eecs.umich.edu    checkXMM(10, mState.xmm, nState.xmm);
1585049Sgblack@eecs.umich.edu    checkXMM(11, mState.xmm, nState.xmm);
1595049Sgblack@eecs.umich.edu    checkXMM(12, mState.xmm, nState.xmm);
1605049Sgblack@eecs.umich.edu    checkXMM(13, mState.xmm, nState.xmm);
1615049Sgblack@eecs.umich.edu    checkXMM(14, mState.xmm, nState.xmm);
1625049Sgblack@eecs.umich.edu    checkXMM(15, mState.xmm, nState.xmm);
1634776Sgblack@eecs.umich.edu#if THE_ISA == SPARC_ISA
1644830Sgblack@eecs.umich.edu    /*for(int f = 0; f <= 62; f+=2)
1654830Sgblack@eecs.umich.edu    {
1664776Sgblack@eecs.umich.edu        uint64_t regVal;
1674776Sgblack@eecs.umich.edu        int res = read(fd, &regVal, sizeof(regVal));
1684776Sgblack@eecs.umich.edu        if(res < 0)
1694776Sgblack@eecs.umich.edu            panic("First read call failed! %s\n", strerror(errno));
1704776Sgblack@eecs.umich.edu        regVal = TheISA::gtoh(regVal);
1714830Sgblack@eecs.umich.edu        uint64_t realRegVal = thread->readFloatRegBits(f, 64);
1724776Sgblack@eecs.umich.edu        if(regVal != realRegVal)
1734776Sgblack@eecs.umich.edu        {
1744830Sgblack@eecs.umich.edu            DPRINTF(ExecRegDelta, "Register f%d should be %#x but is %#x.\n", f, regVal, realRegVal);
1754776Sgblack@eecs.umich.edu        }
1764830Sgblack@eecs.umich.edu    }*/
1774830Sgblack@eecs.umich.edu    uint64_t regVal;
1784830Sgblack@eecs.umich.edu    int res = read(fd, &regVal, sizeof(regVal));
1794830Sgblack@eecs.umich.edu    if(res < 0)
1804830Sgblack@eecs.umich.edu        panic("First read call failed! %s\n", strerror(errno));
1814830Sgblack@eecs.umich.edu    regVal = TheISA::gtoh(regVal);
1824830Sgblack@eecs.umich.edu    uint64_t realRegVal = thread->readNextPC();
1834830Sgblack@eecs.umich.edu    if(regVal != realRegVal)
1844830Sgblack@eecs.umich.edu    {
1854830Sgblack@eecs.umich.edu        DPRINTF(ExecRegDelta,
1864830Sgblack@eecs.umich.edu                "Register pc should be %#x but is %#x.\n",
1874830Sgblack@eecs.umich.edu                regVal, realRegVal);
1884830Sgblack@eecs.umich.edu    }
1894830Sgblack@eecs.umich.edu    res = read(fd, &regVal, sizeof(regVal));
1904830Sgblack@eecs.umich.edu    if(res < 0)
1914830Sgblack@eecs.umich.edu        panic("First read call failed! %s\n", strerror(errno));
1924830Sgblack@eecs.umich.edu    regVal = TheISA::gtoh(regVal);
1934830Sgblack@eecs.umich.edu    realRegVal = thread->readNextNPC();
1944830Sgblack@eecs.umich.edu    if(regVal != realRegVal)
1954830Sgblack@eecs.umich.edu    {
1964830Sgblack@eecs.umich.edu        DPRINTF(ExecRegDelta,
1974830Sgblack@eecs.umich.edu                "Register npc should be %#x but is %#x.\n",
1984830Sgblack@eecs.umich.edu                regVal, realRegVal);
1994830Sgblack@eecs.umich.edu    }
2004830Sgblack@eecs.umich.edu    res = read(fd, &regVal, sizeof(regVal));
2014830Sgblack@eecs.umich.edu    if(res < 0)
2024830Sgblack@eecs.umich.edu        panic("First read call failed! %s\n", strerror(errno));
2034830Sgblack@eecs.umich.edu    regVal = TheISA::gtoh(regVal);
2044830Sgblack@eecs.umich.edu    realRegVal = thread->readIntReg(SparcISA::NumIntArchRegs + 2);
2054830Sgblack@eecs.umich.edu    if((regVal & 0xF) != (realRegVal & 0xF))
2064830Sgblack@eecs.umich.edu    {
2074830Sgblack@eecs.umich.edu        DPRINTF(ExecRegDelta,
2084830Sgblack@eecs.umich.edu                "Register ccr should be %#x but is %#x.\n",
2094830Sgblack@eecs.umich.edu                regVal, realRegVal);
2104830Sgblack@eecs.umich.edu    }
2114776Sgblack@eecs.umich.edu#endif
2124776Sgblack@eecs.umich.edu}
2134776Sgblack@eecs.umich.edu
2144776Sgblack@eecs.umich.edu/* namespace Trace */ }
2154776Sgblack@eecs.umich.edu
2164776Sgblack@eecs.umich.edu////////////////////////////////////////////////////////////////////////
2174776Sgblack@eecs.umich.edu//
2184776Sgblack@eecs.umich.edu//  ExeTracer Simulation Object
2194776Sgblack@eecs.umich.edu//
2204776Sgblack@eecs.umich.eduTrace::NativeTrace *
2214776Sgblack@eecs.umich.eduNativeTraceParams::create()
2224776Sgblack@eecs.umich.edu{
2235038Sgblack@eecs.umich.edu    return new Trace::NativeTrace(this);
2244776Sgblack@eecs.umich.edu};
225