nativetrace.cc (5038:c996bb7f1a6d) nativetrace.cc (5049:16a0724434b8)
1/*
2 * Copyright (c) 2001-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Steve Reinhardt
29 * Lisa Hsu
30 * Nathan Binkert
31 * Steve Raasch
32 */
33
34#include <errno.h>
35
36#include "arch/regfile.hh"
37#include "arch/utility.hh"
38#include "base/loader/symtab.hh"
39#include "base/socket.hh"
40#include "cpu/nativetrace.hh"
41#include "cpu/static_inst.hh"
42#include "cpu/thread_context.hh"
43#include "params/NativeTrace.hh"
44
45//XXX This is temporary
46#include "arch/isa_specific.hh"
47
48using namespace std;
49using namespace TheISA;
50
51namespace Trace {
52
53NativeTrace::NativeTrace(const Params *p) : InstTracer(p)
54{
55 int port = 8000;
56 while(!native_listener.listen(port, true))
57 {
58 DPRINTF(GDBMisc, "Can't bind port %d\n", port);
59 port++;
60 }
61 ccprintf(cerr, "Listening for native process on port %d\n", port);
62 fd = native_listener.accept();
63 checkRcx = true;
64 checkR11 = true;
65}
66
67bool
68NativeTrace::checkRcxReg(const char * name, uint64_t &mVal, uint64_t &nVal)
69{
70 if(!checkRcx)
71 checkRcx = (mVal != oldRcxVal || nVal != oldRealRcxVal);
72 if(checkRcx)
73 return checkReg(name, mVal, nVal);
74 return true;
75}
76
77bool
78NativeTrace::checkR11Reg(const char * name, uint64_t &mVal, uint64_t &nVal)
79{
80 if(!checkR11)
81 checkR11 = (mVal != oldR11Val || nVal != oldRealR11Val);
82 if(checkR11)
83 return checkReg(name, mVal, nVal);
84 return true;
85}
86
1/*
2 * Copyright (c) 2001-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Steve Reinhardt
29 * Lisa Hsu
30 * Nathan Binkert
31 * Steve Raasch
32 */
33
34#include <errno.h>
35
36#include "arch/regfile.hh"
37#include "arch/utility.hh"
38#include "base/loader/symtab.hh"
39#include "base/socket.hh"
40#include "cpu/nativetrace.hh"
41#include "cpu/static_inst.hh"
42#include "cpu/thread_context.hh"
43#include "params/NativeTrace.hh"
44
45//XXX This is temporary
46#include "arch/isa_specific.hh"
47
48using namespace std;
49using namespace TheISA;
50
51namespace Trace {
52
53NativeTrace::NativeTrace(const Params *p) : InstTracer(p)
54{
55 int port = 8000;
56 while(!native_listener.listen(port, true))
57 {
58 DPRINTF(GDBMisc, "Can't bind port %d\n", port);
59 port++;
60 }
61 ccprintf(cerr, "Listening for native process on port %d\n", port);
62 fd = native_listener.accept();
63 checkRcx = true;
64 checkR11 = true;
65}
66
67bool
68NativeTrace::checkRcxReg(const char * name, uint64_t &mVal, uint64_t &nVal)
69{
70 if(!checkRcx)
71 checkRcx = (mVal != oldRcxVal || nVal != oldRealRcxVal);
72 if(checkRcx)
73 return checkReg(name, mVal, nVal);
74 return true;
75}
76
77bool
78NativeTrace::checkR11Reg(const char * name, uint64_t &mVal, uint64_t &nVal)
79{
80 if(!checkR11)
81 checkR11 = (mVal != oldR11Val || nVal != oldRealR11Val);
82 if(checkR11)
83 return checkReg(name, mVal, nVal);
84 return true;
85}
86
87bool
88NativeTrace::checkXMM(int num, uint64_t mXmmBuf[], uint64_t nXmmBuf[])
89{
90 if (mXmmBuf[num * 2] != nXmmBuf[num * 2] ||
91 mXmmBuf[num * 2 + 1] != nXmmBuf[num * 2 + 1]) {
92 DPRINTFN("Register xmm%d should be 0x%016x%016x but is 0x%016x%016x.\n",
93 num, nXmmBuf[num * 2 + 1], nXmmBuf[num * 2],
94 mXmmBuf[num * 2 + 1], mXmmBuf[num * 2]);
95 return false;
96 }
97 return true;
98}
99
87void
88Trace::NativeTraceRecord::dump()
89{
90 //Don't print what happens for each micro-op, just print out
91 //once at the last op, and for regular instructions.
92 if(!staticInst->isMicroop() || staticInst->isLastMicroop())
93 parent->check(thread, staticInst->isSyscall());
94}
95
96void
97Trace::NativeTrace::check(ThreadContext * tc, bool isSyscall)
98{
99// ostream &outs = Trace::output();
100 nState.update(fd);
101 mState.update(tc);
102
103 if(isSyscall)
104 {
105 checkRcx = false;
106 checkR11 = false;
107 oldRcxVal = mState.rcx;
108 oldRealRcxVal = nState.rcx;
109 oldR11Val = mState.r11;
110 oldRealR11Val = nState.r11;
111 }
112
113 checkReg("rax", mState.rax, nState.rax);
114 checkRcxReg("rcx", mState.rcx, nState.rcx);
115 checkReg("rdx", mState.rdx, nState.rdx);
116 checkReg("rbx", mState.rbx, nState.rbx);
117 checkReg("rsp", mState.rsp, nState.rsp);
118 checkReg("rbp", mState.rbp, nState.rbp);
119 checkReg("rsi", mState.rsi, nState.rsi);
120 checkReg("rdi", mState.rdi, nState.rdi);
121 checkReg("r8", mState.r8, nState.r8);
122 checkReg("r9", mState.r9, nState.r9);
123 checkReg("r10", mState.r10, nState.r10);
124 checkR11Reg("r11", mState.r11, nState.r11);
125 checkReg("r12", mState.r12, nState.r12);
126 checkReg("r13", mState.r13, nState.r13);
127 checkReg("r14", mState.r14, nState.r14);
128 checkReg("r15", mState.r15, nState.r15);
129 checkReg("rip", mState.rip, nState.rip);
100void
101Trace::NativeTraceRecord::dump()
102{
103 //Don't print what happens for each micro-op, just print out
104 //once at the last op, and for regular instructions.
105 if(!staticInst->isMicroop() || staticInst->isLastMicroop())
106 parent->check(thread, staticInst->isSyscall());
107}
108
109void
110Trace::NativeTrace::check(ThreadContext * tc, bool isSyscall)
111{
112// ostream &outs = Trace::output();
113 nState.update(fd);
114 mState.update(tc);
115
116 if(isSyscall)
117 {
118 checkRcx = false;
119 checkR11 = false;
120 oldRcxVal = mState.rcx;
121 oldRealRcxVal = nState.rcx;
122 oldR11Val = mState.r11;
123 oldRealR11Val = nState.r11;
124 }
125
126 checkReg("rax", mState.rax, nState.rax);
127 checkRcxReg("rcx", mState.rcx, nState.rcx);
128 checkReg("rdx", mState.rdx, nState.rdx);
129 checkReg("rbx", mState.rbx, nState.rbx);
130 checkReg("rsp", mState.rsp, nState.rsp);
131 checkReg("rbp", mState.rbp, nState.rbp);
132 checkReg("rsi", mState.rsi, nState.rsi);
133 checkReg("rdi", mState.rdi, nState.rdi);
134 checkReg("r8", mState.r8, nState.r8);
135 checkReg("r9", mState.r9, nState.r9);
136 checkReg("r10", mState.r10, nState.r10);
137 checkR11Reg("r11", mState.r11, nState.r11);
138 checkReg("r12", mState.r12, nState.r12);
139 checkReg("r13", mState.r13, nState.r13);
140 checkReg("r14", mState.r14, nState.r14);
141 checkReg("r15", mState.r15, nState.r15);
142 checkReg("rip", mState.rip, nState.rip);
143 checkXMM(0, mState.xmm, nState.xmm);
144 checkXMM(1, mState.xmm, nState.xmm);
145 checkXMM(2, mState.xmm, nState.xmm);
146 checkXMM(3, mState.xmm, nState.xmm);
147 checkXMM(4, mState.xmm, nState.xmm);
148 checkXMM(5, mState.xmm, nState.xmm);
149 checkXMM(6, mState.xmm, nState.xmm);
150 checkXMM(7, mState.xmm, nState.xmm);
151 checkXMM(8, mState.xmm, nState.xmm);
152 checkXMM(9, mState.xmm, nState.xmm);
153 checkXMM(10, mState.xmm, nState.xmm);
154 checkXMM(11, mState.xmm, nState.xmm);
155 checkXMM(12, mState.xmm, nState.xmm);
156 checkXMM(13, mState.xmm, nState.xmm);
157 checkXMM(14, mState.xmm, nState.xmm);
158 checkXMM(15, mState.xmm, nState.xmm);
130#if THE_ISA == SPARC_ISA
131 /*for(int f = 0; f <= 62; f+=2)
132 {
133 uint64_t regVal;
134 int res = read(fd, &regVal, sizeof(regVal));
135 if(res < 0)
136 panic("First read call failed! %s\n", strerror(errno));
137 regVal = TheISA::gtoh(regVal);
138 uint64_t realRegVal = thread->readFloatRegBits(f, 64);
139 if(regVal != realRegVal)
140 {
141 DPRINTF(ExecRegDelta, "Register f%d should be %#x but is %#x.\n", f, regVal, realRegVal);
142 }
143 }*/
144 uint64_t regVal;
145 int res = read(fd, &regVal, sizeof(regVal));
146 if(res < 0)
147 panic("First read call failed! %s\n", strerror(errno));
148 regVal = TheISA::gtoh(regVal);
149 uint64_t realRegVal = thread->readNextPC();
150 if(regVal != realRegVal)
151 {
152 DPRINTF(ExecRegDelta,
153 "Register pc should be %#x but is %#x.\n",
154 regVal, realRegVal);
155 }
156 res = read(fd, &regVal, sizeof(regVal));
157 if(res < 0)
158 panic("First read call failed! %s\n", strerror(errno));
159 regVal = TheISA::gtoh(regVal);
160 realRegVal = thread->readNextNPC();
161 if(regVal != realRegVal)
162 {
163 DPRINTF(ExecRegDelta,
164 "Register npc should be %#x but is %#x.\n",
165 regVal, realRegVal);
166 }
167 res = read(fd, &regVal, sizeof(regVal));
168 if(res < 0)
169 panic("First read call failed! %s\n", strerror(errno));
170 regVal = TheISA::gtoh(regVal);
171 realRegVal = thread->readIntReg(SparcISA::NumIntArchRegs + 2);
172 if((regVal & 0xF) != (realRegVal & 0xF))
173 {
174 DPRINTF(ExecRegDelta,
175 "Register ccr should be %#x but is %#x.\n",
176 regVal, realRegVal);
177 }
178#endif
179}
180
181/* namespace Trace */ }
182
183////////////////////////////////////////////////////////////////////////
184//
185// ExeTracer Simulation Object
186//
187Trace::NativeTrace *
188NativeTraceParams::create()
189{
190 return new Trace::NativeTrace(this);
191};
159#if THE_ISA == SPARC_ISA
160 /*for(int f = 0; f <= 62; f+=2)
161 {
162 uint64_t regVal;
163 int res = read(fd, &regVal, sizeof(regVal));
164 if(res < 0)
165 panic("First read call failed! %s\n", strerror(errno));
166 regVal = TheISA::gtoh(regVal);
167 uint64_t realRegVal = thread->readFloatRegBits(f, 64);
168 if(regVal != realRegVal)
169 {
170 DPRINTF(ExecRegDelta, "Register f%d should be %#x but is %#x.\n", f, regVal, realRegVal);
171 }
172 }*/
173 uint64_t regVal;
174 int res = read(fd, &regVal, sizeof(regVal));
175 if(res < 0)
176 panic("First read call failed! %s\n", strerror(errno));
177 regVal = TheISA::gtoh(regVal);
178 uint64_t realRegVal = thread->readNextPC();
179 if(regVal != realRegVal)
180 {
181 DPRINTF(ExecRegDelta,
182 "Register pc should be %#x but is %#x.\n",
183 regVal, realRegVal);
184 }
185 res = read(fd, &regVal, sizeof(regVal));
186 if(res < 0)
187 panic("First read call failed! %s\n", strerror(errno));
188 regVal = TheISA::gtoh(regVal);
189 realRegVal = thread->readNextNPC();
190 if(regVal != realRegVal)
191 {
192 DPRINTF(ExecRegDelta,
193 "Register npc should be %#x but is %#x.\n",
194 regVal, realRegVal);
195 }
196 res = read(fd, &regVal, sizeof(regVal));
197 if(res < 0)
198 panic("First read call failed! %s\n", strerror(errno));
199 regVal = TheISA::gtoh(regVal);
200 realRegVal = thread->readIntReg(SparcISA::NumIntArchRegs + 2);
201 if((regVal & 0xF) != (realRegVal & 0xF))
202 {
203 DPRINTF(ExecRegDelta,
204 "Register ccr should be %#x but is %#x.\n",
205 regVal, realRegVal);
206 }
207#endif
208}
209
210/* namespace Trace */ }
211
212////////////////////////////////////////////////////////////////////////
213//
214// ExeTracer Simulation Object
215//
216Trace::NativeTrace *
217NativeTraceParams::create()
218{
219 return new Trace::NativeTrace(this);
220};