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, &regVal, 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, &regVal, 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, &regVal, 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, &regVal, 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, &regVal, 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, &regVal, 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