nativetrace.hh revision 6216
111986Sandreas.sandberg@arm.com/*
211986Sandreas.sandberg@arm.com * Copyright (c) 2001-2005 The Regents of The University of Michigan
311986Sandreas.sandberg@arm.com * All rights reserved.
411986Sandreas.sandberg@arm.com *
511986Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without
611986Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are
711986Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright
811986Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer;
911986Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright
1011986Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the
1112037Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution;
1211986Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its
1312391Sjason@lowepower.com * contributors may be used to endorse or promote products derived from
1411986Sandreas.sandberg@arm.com * this software without specific prior written permission.
1511986Sandreas.sandberg@arm.com *
1612037Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1711986Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1811986Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1911986Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2012037Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2112037Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2212037Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2312037Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2412037Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2512037Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2611986Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2712037Sandreas.sandberg@arm.com *
2812037Sandreas.sandberg@arm.com * Authors: Steve Reinhardt
2912037Sandreas.sandberg@arm.com *          Nathan Binkert
3012037Sandreas.sandberg@arm.com */
3112037Sandreas.sandberg@arm.com
3212037Sandreas.sandberg@arm.com#ifndef __CPU_NATIVETRACE_HH__
3312037Sandreas.sandberg@arm.com#define __CPU_NATIVETRACE_HH__
3412037Sandreas.sandberg@arm.com
3512037Sandreas.sandberg@arm.com#include "arch/x86/floatregs.hh"
3612037Sandreas.sandberg@arm.com#include "arch/x86/intregs.hh"
3712037Sandreas.sandberg@arm.com#include "base/trace.hh"
3812037Sandreas.sandberg@arm.com#include "base/types.hh"
3912037Sandreas.sandberg@arm.com#include "cpu/static_inst.hh"
4012037Sandreas.sandberg@arm.com#include "sim/insttracer.hh"
4112037Sandreas.sandberg@arm.com
4212037Sandreas.sandberg@arm.comclass ThreadContext;
4312037Sandreas.sandberg@arm.com
4412037Sandreas.sandberg@arm.comnamespace Trace {
4512037Sandreas.sandberg@arm.com
4612037Sandreas.sandberg@arm.comclass NativeTrace;
4712037Sandreas.sandberg@arm.com
4812037Sandreas.sandberg@arm.comclass NativeTraceRecord : public InstRecord
4912037Sandreas.sandberg@arm.com{
5012037Sandreas.sandberg@arm.com  protected:
5112037Sandreas.sandberg@arm.com    NativeTrace * parent;
5212037Sandreas.sandberg@arm.com
5312037Sandreas.sandberg@arm.com  public:
5412037Sandreas.sandberg@arm.com    NativeTraceRecord(NativeTrace * _parent,
5512037Sandreas.sandberg@arm.com               Tick _when, ThreadContext *_thread,
5612037Sandreas.sandberg@arm.com               const StaticInstPtr _staticInst, Addr _pc, bool spec,
5712037Sandreas.sandberg@arm.com               const StaticInstPtr _macroStaticInst = NULL, MicroPC _upc = 0)
5812037Sandreas.sandberg@arm.com        : InstRecord(_when, _thread, _staticInst, _pc, spec,
5912037Sandreas.sandberg@arm.com                _macroStaticInst, _upc),
6012037Sandreas.sandberg@arm.com        parent(_parent)
6112037Sandreas.sandberg@arm.com    {
6212037Sandreas.sandberg@arm.com    }
6312037Sandreas.sandberg@arm.com
6412037Sandreas.sandberg@arm.com    void dump();
6512037Sandreas.sandberg@arm.com};
6612037Sandreas.sandberg@arm.com
6712037Sandreas.sandberg@arm.comclass NativeTrace : public InstTracer
6812037Sandreas.sandberg@arm.com{
6912037Sandreas.sandberg@arm.com  protected:
7012037Sandreas.sandberg@arm.com    int fd;
7112037Sandreas.sandberg@arm.com
7211986Sandreas.sandberg@arm.com    ListenSocket native_listener;
7312391Sjason@lowepower.com
7412391Sjason@lowepower.com    bool checkRcx;
7512391Sjason@lowepower.com    bool checkR11;
7612391Sjason@lowepower.com    uint64_t oldRcxVal, oldR11Val;
7712391Sjason@lowepower.com    uint64_t oldRealRcxVal, oldRealR11Val;
7812391Sjason@lowepower.com
7912391Sjason@lowepower.com    struct ThreadState {
8012391Sjason@lowepower.com        uint64_t rax;
8112391Sjason@lowepower.com        uint64_t rcx;
8212391Sjason@lowepower.com        uint64_t rdx;
8312391Sjason@lowepower.com        uint64_t rbx;
8411986Sandreas.sandberg@arm.com        uint64_t rsp;
8511986Sandreas.sandberg@arm.com        uint64_t rbp;
8611986Sandreas.sandberg@arm.com        uint64_t rsi;
8712391Sjason@lowepower.com        uint64_t rdi;
8812037Sandreas.sandberg@arm.com        uint64_t r8;
8912037Sandreas.sandberg@arm.com        uint64_t r9;
9012037Sandreas.sandberg@arm.com        uint64_t r10;
9112037Sandreas.sandberg@arm.com        uint64_t r11;
9212037Sandreas.sandberg@arm.com        uint64_t r12;
9312037Sandreas.sandberg@arm.com        uint64_t r13;
9412037Sandreas.sandberg@arm.com        uint64_t r14;
9511986Sandreas.sandberg@arm.com        uint64_t r15;
9612391Sjason@lowepower.com        uint64_t rip;
9712037Sandreas.sandberg@arm.com        //This should be expanded to 16 if x87 registers are considered
9812037Sandreas.sandberg@arm.com        uint64_t mmx[8];
9912037Sandreas.sandberg@arm.com        uint64_t xmm[32];
10012037Sandreas.sandberg@arm.com
10112037Sandreas.sandberg@arm.com        void update(int fd)
10212037Sandreas.sandberg@arm.com        {
10312391Sjason@lowepower.com            int bytesLeft = sizeof(ThreadState);
10412037Sandreas.sandberg@arm.com            int bytesRead = 0;
10512037Sandreas.sandberg@arm.com            do
10612037Sandreas.sandberg@arm.com            {
10712037Sandreas.sandberg@arm.com                int res = read(fd, ((char *)this) + bytesRead, bytesLeft);
10812037Sandreas.sandberg@arm.com                if(res < 0)
10912037Sandreas.sandberg@arm.com                    panic("Read call failed! %s\n", strerror(errno));
11012037Sandreas.sandberg@arm.com                bytesLeft -= res;
11112037Sandreas.sandberg@arm.com                bytesRead += res;
11212037Sandreas.sandberg@arm.com            } while(bytesLeft);
11312037Sandreas.sandberg@arm.com            rax = TheISA::gtoh(rax);
11412037Sandreas.sandberg@arm.com            rcx = TheISA::gtoh(rcx);
11512037Sandreas.sandberg@arm.com            rdx = TheISA::gtoh(rdx);
11612037Sandreas.sandberg@arm.com            rbx = TheISA::gtoh(rbx);
11712037Sandreas.sandberg@arm.com            rsp = TheISA::gtoh(rsp);
11812037Sandreas.sandberg@arm.com            rbp = TheISA::gtoh(rbp);
11912037Sandreas.sandberg@arm.com            rsi = TheISA::gtoh(rsi);
12012037Sandreas.sandberg@arm.com            rdi = TheISA::gtoh(rdi);
12112037Sandreas.sandberg@arm.com            r8 = TheISA::gtoh(r8);
12212037Sandreas.sandberg@arm.com            r9 = TheISA::gtoh(r9);
12312037Sandreas.sandberg@arm.com            r10 = TheISA::gtoh(r10);
12412037Sandreas.sandberg@arm.com            r11 = TheISA::gtoh(r11);
12512037Sandreas.sandberg@arm.com            r12 = TheISA::gtoh(r12);
12612037Sandreas.sandberg@arm.com            r13 = TheISA::gtoh(r13);
12712037Sandreas.sandberg@arm.com            r14 = TheISA::gtoh(r14);
12812037Sandreas.sandberg@arm.com            r15 = TheISA::gtoh(r15);
12912037Sandreas.sandberg@arm.com            rip = TheISA::gtoh(rip);
13012037Sandreas.sandberg@arm.com            //This should be expanded if x87 registers are considered
13112037Sandreas.sandberg@arm.com            for (int i = 0; i < 8; i++)
13212037Sandreas.sandberg@arm.com                mmx[i] = TheISA::gtoh(mmx[i]);
13312037Sandreas.sandberg@arm.com            for (int i = 0; i < 32; i++)
13412037Sandreas.sandberg@arm.com                xmm[i] = TheISA::gtoh(xmm[i]);
13512037Sandreas.sandberg@arm.com        }
13612037Sandreas.sandberg@arm.com
13712037Sandreas.sandberg@arm.com        void update(ThreadContext * tc)
13812037Sandreas.sandberg@arm.com        {
13912037Sandreas.sandberg@arm.com            rax = tc->readIntReg(X86ISA::INTREG_RAX);
14012037Sandreas.sandberg@arm.com            rcx = tc->readIntReg(X86ISA::INTREG_RCX);
14112037Sandreas.sandberg@arm.com            rdx = tc->readIntReg(X86ISA::INTREG_RDX);
14212037Sandreas.sandberg@arm.com            rbx = tc->readIntReg(X86ISA::INTREG_RBX);
14312037Sandreas.sandberg@arm.com            rsp = tc->readIntReg(X86ISA::INTREG_RSP);
14412037Sandreas.sandberg@arm.com            rbp = tc->readIntReg(X86ISA::INTREG_RBP);
14512037Sandreas.sandberg@arm.com            rsi = tc->readIntReg(X86ISA::INTREG_RSI);
14612037Sandreas.sandberg@arm.com            rdi = tc->readIntReg(X86ISA::INTREG_RDI);
14712037Sandreas.sandberg@arm.com            r8 = tc->readIntReg(X86ISA::INTREG_R8);
14812037Sandreas.sandberg@arm.com            r9 = tc->readIntReg(X86ISA::INTREG_R9);
14912037Sandreas.sandberg@arm.com            r10 = tc->readIntReg(X86ISA::INTREG_R10);
15012037Sandreas.sandberg@arm.com            r11 = tc->readIntReg(X86ISA::INTREG_R11);
15112037Sandreas.sandberg@arm.com            r12 = tc->readIntReg(X86ISA::INTREG_R12);
15212037Sandreas.sandberg@arm.com            r13 = tc->readIntReg(X86ISA::INTREG_R13);
15312037Sandreas.sandberg@arm.com            r14 = tc->readIntReg(X86ISA::INTREG_R14);
15412037Sandreas.sandberg@arm.com            r15 = tc->readIntReg(X86ISA::INTREG_R15);
15512037Sandreas.sandberg@arm.com            rip = tc->readNextPC();
15611986Sandreas.sandberg@arm.com            //This should be expanded if x87 registers are considered
15711986Sandreas.sandberg@arm.com            for (int i = 0; i < 8; i++)
15811986Sandreas.sandberg@arm.com                mmx[i] = tc->readFloatRegBits(X86ISA::FLOATREG_MMX(i));
15911986Sandreas.sandberg@arm.com            for (int i = 0; i < 32; i++)
16011986Sandreas.sandberg@arm.com                xmm[i] = tc->readFloatRegBits(X86ISA::FLOATREG_XMM_BASE + i);
16111986Sandreas.sandberg@arm.com        }
16211986Sandreas.sandberg@arm.com
16311986Sandreas.sandberg@arm.com    };
16411986Sandreas.sandberg@arm.com
16511986Sandreas.sandberg@arm.com    ThreadState nState;
16611986Sandreas.sandberg@arm.com    ThreadState mState;
16712391Sjason@lowepower.com
16812037Sandreas.sandberg@arm.com
16912037Sandreas.sandberg@arm.com  public:
17012037Sandreas.sandberg@arm.com
17112037Sandreas.sandberg@arm.com    template<class T>
17212037Sandreas.sandberg@arm.com    bool
17312037Sandreas.sandberg@arm.com    checkReg(const char * regName, T &val, T &realVal)
17412037Sandreas.sandberg@arm.com    {
17512037Sandreas.sandberg@arm.com        if(val != realVal)
17612037Sandreas.sandberg@arm.com        {
17712037Sandreas.sandberg@arm.com            DPRINTFN("Register %s should be %#x but is %#x.\n",
17812037Sandreas.sandberg@arm.com                    regName, realVal, val);
17912037Sandreas.sandberg@arm.com            return false;
18012037Sandreas.sandberg@arm.com        }
18112037Sandreas.sandberg@arm.com        return true;
18212037Sandreas.sandberg@arm.com    }
18312037Sandreas.sandberg@arm.com
18412037Sandreas.sandberg@arm.com    bool
18512037Sandreas.sandberg@arm.com    checkRcxReg(const char * regName, uint64_t &, uint64_t &);
18612037Sandreas.sandberg@arm.com
18712037Sandreas.sandberg@arm.com    bool
18812037Sandreas.sandberg@arm.com    checkR11Reg(const char * regName, uint64_t &, uint64_t &);
18912037Sandreas.sandberg@arm.com
19012037Sandreas.sandberg@arm.com    bool
19112037Sandreas.sandberg@arm.com    checkXMM(int num, uint64_t mXmmBuf[], uint64_t nXmmBuf[]);
19212037Sandreas.sandberg@arm.com
19312037Sandreas.sandberg@arm.com    NativeTrace(const Params *p);
19412037Sandreas.sandberg@arm.com
19512037Sandreas.sandberg@arm.com    NativeTraceRecord *
19612037Sandreas.sandberg@arm.com    getInstRecord(Tick when, ThreadContext *tc,
19712037Sandreas.sandberg@arm.com            const StaticInstPtr staticInst, Addr pc,
19812037Sandreas.sandberg@arm.com            const StaticInstPtr macroStaticInst = NULL, MicroPC upc = 0)
19912037Sandreas.sandberg@arm.com    {
20012037Sandreas.sandberg@arm.com        if (tc->misspeculating())
20112037Sandreas.sandberg@arm.com            return NULL;
20212037Sandreas.sandberg@arm.com
20312037Sandreas.sandberg@arm.com        return new NativeTraceRecord(this, when, tc,
20412037Sandreas.sandberg@arm.com                staticInst, pc, tc->misspeculating(), macroStaticInst, upc);
20512037Sandreas.sandberg@arm.com    }
20612037Sandreas.sandberg@arm.com
20712037Sandreas.sandberg@arm.com    void
20812037Sandreas.sandberg@arm.com    check(ThreadContext *, bool syscall);
20912037Sandreas.sandberg@arm.com
21012037Sandreas.sandberg@arm.com    friend class NativeTraceRecord;
21112037Sandreas.sandberg@arm.com};
21212037Sandreas.sandberg@arm.com
21312037Sandreas.sandberg@arm.com/* namespace Trace */ }
21412391Sjason@lowepower.com
21511986Sandreas.sandberg@arm.com#endif // __CPU_NATIVETRACE_HH__
21611986Sandreas.sandberg@arm.com