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 <fstream>
35#include <iomanip>
36#include <sys/ipc.h>
37#include <sys/shm.h>
38
39#include "arch/regfile.hh"
40#include "arch/utility.hh"
41#include "base/loader/symtab.hh"
42#include "config/full_system.hh"
43#include "cpu/base.hh"
44#include "cpu/exetrace.hh"
45#include "cpu/static_inst.hh"
46#include "sim/param.hh"
47#include "sim/system.hh"
48
49#if FULL_SYSTEM
50#include "arch/tlb.hh"
51#endif
52
53//XXX This is temporary
54#include "arch/isa_specific.hh"
55#include "cpu/m5legion_interface.h"
56
57using namespace std;
58using namespace TheISA;
59
60namespace Trace {
61SharedData *shared_data = NULL;
62}
63
64////////////////////////////////////////////////////////////////////////
65//
66// Methods for the InstRecord object
67//
68
69#if THE_ISA == SPARC_ISA
70
71inline char * genCenteredLabel(int length, char * buffer, char * label)
72{
73 int labelLength = strlen(label);
74 assert(labelLength <= length);
75 int leftPad = (length - labelLength) / 2;
76 int rightPad = length - leftPad - labelLength;
77 char format[64];
78 sprintf(format, "%%%ds%%s%%%ds", leftPad, rightPad);
79 sprintf(buffer, format, "", label, "");
80 return buffer;
81}
82
83inline void printRegPair(ostream & os, char const * title, uint64_t a, uint64_t b)
84{
85 ccprintf(os, " %16s | %#018x %s %#-018x \n",
86 title, a, (a == b) ? "|" : "X", b);
87}
88
89inline void printColumnLabels(ostream & os)
90{
91 static char * regLabel = genCenteredLabel(16, new char[17], "Register");
92 static char * m5Label = genCenteredLabel(18, new char[18], "M5");
93 static char * legionLabel = genCenteredLabel(18, new char[18], "Legion");
94 ccprintf(os, " %s | %s | %s \n", regLabel, m5Label, legionLabel);
95 ccprintf(os, "--------------------+-----------------------+-----------------------\n");
96}
97
98inline void printSectionHeader(ostream & os, char * name)
99{
100 char sectionString[70];
101 genCenteredLabel(69, sectionString, name);
102 ccprintf(os, "====================================================================\n");
103 ccprintf(os, "%69s\n", sectionString);
104 ccprintf(os, "====================================================================\n");
105}
106
107inline void printLevelHeader(ostream & os, int level)
108{
109 char sectionString[70];
110 char levelName[70];
111 sprintf(levelName, "Trap stack level %d", level);
112 genCenteredLabel(69, sectionString, levelName);
113 ccprintf(os, "====================================================================\n");
114 ccprintf(os, "%69s\n", sectionString);
115 ccprintf(os, "====================================================================\n");
116}
117
118#endif
119
120void
121Trace::InstRecord::dump(ostream &outs)
122{
123 if (flags[PRINT_REG_DELTA])
124 {
125#if THE_ISA == SPARC_ISA
126 //Don't print what happens for each micro-op, just print out
127 //once at the last op, and for regular instructions.
128 if(!staticInst->isMicroOp() || staticInst->isLastMicroOp())
129 {
130 static uint64_t regs[32] = {
131 0, 0, 0, 0, 0, 0, 0, 0,
132 0, 0, 0, 0, 0, 0, 0, 0,
133 0, 0, 0, 0, 0, 0, 0, 0,
134 0, 0, 0, 0, 0, 0, 0, 0};
135 static uint64_t ccr = 0;
136 static uint64_t y = 0;
137 static uint64_t floats[32];
138 uint64_t newVal;
139 static const char * prefixes[4] = {"G", "O", "L", "I"};
140
141 outs << hex;
142 outs << "PC = " << thread->readNextPC();
143 outs << " NPC = " << thread->readNextNPC();
144 newVal = thread->readMiscReg(SparcISA::MISCREG_CCR);
145 if(newVal != ccr)
146 {
147 outs << " CCR = " << newVal;
148 ccr = newVal;
149 }
150 newVal = thread->readMiscReg(SparcISA::MISCREG_Y);
151 if(newVal != y)
152 {
153 outs << " Y = " << newVal;
154 y = newVal;
155 }
156 for(int y = 0; y < 4; y++)
157 {
158 for(int x = 0; x < 8; x++)
159 {
160 int index = x + 8 * y;
161 newVal = thread->readIntReg(index);
162 if(regs[index] != newVal)
163 {
164 outs << " " << prefixes[y] << dec << x << " = " << hex << newVal;
165 regs[index] = newVal;
166 }
167 }
168 }
169 for(int y = 0; y < 32; y++)
170 {
171 newVal = thread->readFloatRegBits(2 * y, 64);
172 if(floats[y] != newVal)
173 {
174 outs << " F" << dec << (2 * y) << " = " << hex << newVal;
175 floats[y] = newVal;
176 }
177 }
178 outs << dec << endl;
179 }
180#endif
181 }
182 else if (flags[INTEL_FORMAT]) {
183#if FULL_SYSTEM
184 bool is_trace_system = (thread->getCpuPtr()->system->name() == trace_system);
185#else
186 bool is_trace_system = true;
187#endif
188 if (is_trace_system) {
189 ccprintf(outs, "%7d ) ", cycle);
190 outs << "0x" << hex << PC << ":\t";
191 if (staticInst->isLoad()) {
192 outs << "<RD 0x" << hex << addr;
193 outs << ">";
194 } else if (staticInst->isStore()) {
195 outs << "<WR 0x" << hex << addr;
196 outs << ">";
197 }
198 outs << endl;
199 }
200 } else {
201 if (flags[PRINT_CYCLE])
202 ccprintf(outs, "%7d: ", cycle);
203
204 outs << thread->getCpuPtr()->name() << " ";
205
206 if (flags[TRACE_MISSPEC])
207 outs << (misspeculating ? "-" : "+") << " ";
208
209 if (flags[PRINT_THREAD_NUM])
210 outs << "T" << thread->getThreadNum() << " : ";
211
212
213 std::string sym_str;
214 Addr sym_addr;
215 if (debugSymbolTable
216 && debugSymbolTable->findNearestSymbol(PC, sym_str, sym_addr)
217 && flags[PC_SYMBOL]) {
218 if (PC != sym_addr)
219 sym_str += csprintf("+%d", PC - sym_addr);
220 outs << "@" << sym_str << " : ";
221 }
222 else {
223 outs << "0x" << hex << PC << " : ";
224 }
225
226 //
227 // Print decoded instruction
228 //
229
230#if defined(__GNUC__) && (__GNUC__ < 3)
231 // There's a bug in gcc 2.x library that prevents setw()
232 // from working properly on strings
233 string mc(staticInst->disassemble(PC, debugSymbolTable));
234 while (mc.length() < 26)
235 mc += " ";
236 outs << mc;
237#else
238 outs << setw(26) << left << staticInst->disassemble(PC, debugSymbolTable);
239#endif
240
241 outs << " : ";
242
243 if (flags[PRINT_OP_CLASS]) {
244 outs << opClassStrings[staticInst->opClass()] << " : ";
245 }
246
247 if (flags[PRINT_RESULT_DATA] && data_status != DataInvalid) {
248 outs << " D=";
249#if 0
250 if (data_status == DataDouble)
251 ccprintf(outs, "%f", data.as_double);
252 else
253 ccprintf(outs, "%#018x", data.as_int);
254#else
255 ccprintf(outs, "%#018x", data.as_int);
256#endif
257 }
258
259 if (flags[PRINT_EFF_ADDR] && addr_valid)
260 outs << " A=0x" << hex << addr;
261
262 if (flags[PRINT_INT_REGS] && regs_valid) {
263 for (int i = 0; i < TheISA::NumIntRegs;)
264 for (int j = i + 1; i <= j; i++)
265 ccprintf(outs, "r%02d = %#018x%s", i,
266 iregs->regs.readReg(i),
267 ((i == j) ? "\n" : " "));
268 outs << "\n";
269 }
270
271 if (flags[PRINT_FETCH_SEQ] && fetch_seq_valid)
272 outs << " FetchSeq=" << dec << fetch_seq;
273
274 if (flags[PRINT_CP_SEQ] && cp_seq_valid)
275 outs << " CPSeq=" << dec << cp_seq;
276
277 //
278 // End of line...
279 //
280 outs << endl;
281 }
282#if THE_ISA == SPARC_ISA
283 // Compare
284 if (flags[LEGION_LOCKSTEP])
285 {
286 bool compared = false;
287 bool diffPC = false;
288 bool diffInst = false;
289 bool diffRegs = false;
290 bool diffTpc = false;
291 bool diffTnpc = false;
292 bool diffTstate = false;
293 bool diffTt = false;
294 bool diffTba = false;
295 bool diffHpstate = false;
296 bool diffHtstate = false;
297 bool diffHtba = false;
298 bool diffPstate = false;
299 bool diffY = false;
300 bool diffCcr = false;
301 bool diffTl = false;
302 bool diffGl = false;
303 bool diffAsi = false;
304 bool diffPil = false;
305 bool diffCwp = false;
306 bool diffCansave = false;
307 bool diffCanrestore = false;
308 bool diffOtherwin = false;
309 bool diffCleanwin = false;
310 Addr m5Pc, lgnPc;
311
312
313 if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) {
314 while (!compared) {
245 m5Pc = PC & TheISA::PAddrImplMask;
246 lgnPc = shared_data->pc & TheISA::PAddrImplMask;
315 if (shared_data->flags == OWN_M5) {
316 m5Pc = PC & TheISA::PAddrImplMask;
317 lgnPc = shared_data->pc & TheISA::PAddrImplMask;
318 if (lgnPc != m5Pc)
319 diffPC = true;
320 if (shared_data->instruction !=
321 (SparcISA::MachInst)staticInst->machInst) {
322 diffInst = true;
323 }
324 for (int i = 0; i < TheISA::NumRegularIntRegs; i++) {
325 if (thread->readIntReg(i) != shared_data->intregs[i]) {
326 diffRegs = true;
327 }
328 }
329 uint64_t oldTl = thread->readMiscReg(MISCREG_TL);
330 if (oldTl != shared_data->tl)
331 diffTl = true;
332 for (int i = 1; i <= MaxTL; i++) {
333 thread->setMiscReg(MISCREG_TL, i);
334 if (thread->readMiscReg(MISCREG_TPC) !=
335 shared_data->tpc[i])
336 diffTpc = true;
337 if (thread->readMiscReg(MISCREG_TNPC) !=
338 shared_data->tnpc[i])
339 diffTnpc = true;
340 if (thread->readMiscReg(MISCREG_TSTATE) !=
341 shared_data->tstate[i])
342 diffTstate = true;
343 if (thread->readMiscReg(MISCREG_TT) !=
344 shared_data->tt[i])
345 diffTt = true;
346 if (thread->readMiscReg(MISCREG_HTSTATE) !=
347 shared_data->htstate[i])
348 diffHtstate = true;
349 }
350 thread->setMiscReg(MISCREG_TL, oldTl);
351
260 if (diffPC || diffInst || diffRegs ) {
352 if(shared_data->tba != thread->readMiscReg(MISCREG_TBA))
353 diffTba = true;
354 //When the hpstate register is read by an instruction,
355 //legion has bit 11 set. When it's in storage, it doesn't.
356 //Since we don't directly support seperate interpretations
357 //of the registers like that, the bit is always set to 1 and
358 //we just don't compare it. It's not supposed to matter
359 //anyway.
360 if((shared_data->hpstate | (1 << 11)) != thread->readMiscReg(MISCREG_HPSTATE))
361 diffHpstate = true;
362 if(shared_data->htba != thread->readMiscReg(MISCREG_HTBA))
363 diffHtba = true;
364 if(shared_data->pstate != thread->readMiscReg(MISCREG_PSTATE))
365 diffPstate = true;
366 if(shared_data->y != thread->readMiscReg(MISCREG_Y))
367 diffY = true;
368 if(shared_data->ccr != thread->readMiscReg(MISCREG_CCR))
369 diffCcr = true;
370 if(shared_data->gl != thread->readMiscReg(MISCREG_GL))
371 diffGl = true;
372 if(shared_data->asi != thread->readMiscReg(MISCREG_ASI))
373 diffAsi = true;
374 if(shared_data->pil != thread->readMiscReg(MISCREG_PIL))
375 diffPil = true;
376 if(shared_data->cwp != thread->readMiscReg(MISCREG_CWP))
377 diffCwp = true;
378 if(shared_data->cansave != thread->readMiscReg(MISCREG_CANSAVE))
379 diffCansave = true;
380 if(shared_data->canrestore !=
381 thread->readMiscReg(MISCREG_CANRESTORE))
382 diffCanrestore = true;
383 if(shared_data->otherwin != thread->readMiscReg(MISCREG_OTHERWIN))
384 diffOtherwin = true;
385 if(shared_data->cleanwin != thread->readMiscReg(MISCREG_CLEANWIN))
386 diffCleanwin = true;
387
388 if (diffPC || diffInst || diffRegs || diffTpc || diffTnpc ||
389 diffTstate || diffTt || diffHpstate ||
390 diffHtstate || diffHtba || diffPstate || diffY ||
391 diffCcr || diffTl || diffGl || diffAsi || diffPil ||
392 diffCwp || diffCansave || diffCanrestore ||
393 diffOtherwin || diffCleanwin) {
394 outs << "Differences found between M5 and Legion:";
395 if (diffPC)
396 outs << " [PC]";
397 if (diffInst)
398 outs << " [Instruction]";
399 if (diffRegs)
400 outs << " [IntRegs]";
401 if (diffTpc)
402 outs << " [Tpc]";
403 if (diffTnpc)
404 outs << " [Tnpc]";
405 if (diffTstate)
406 outs << " [Tstate]";
407 if (diffTt)
408 outs << " [Tt]";
409 if (diffHpstate)
410 outs << " [Hpstate]";
411 if (diffHtstate)
412 outs << " [Htstate]";
413 if (diffHtba)
414 outs << " [Htba]";
415 if (diffPstate)
416 outs << " [Pstate]";
417 if (diffY)
418 outs << " [Y]";
419 if (diffCcr)
420 outs << " [Ccr]";
421 if (diffTl)
422 outs << " [Tl]";
423 if (diffGl)
424 outs << " [Gl]";
425 if (diffAsi)
426 outs << " [Asi]";
427 if (diffPil)
428 outs << " [Pil]";
429 if (diffCwp)
430 outs << " [Cwp]";
431 if (diffCansave)
432 outs << " [Cansave]";
433 if (diffCanrestore)
434 outs << " [Canrestore]";
435 if (diffOtherwin)
436 outs << " [Otherwin]";
437 if (diffCleanwin)
438 outs << " [Cleanwin]";
439 outs << endl << endl;
440
441 outs << right << setfill(' ') << setw(15)
442 << "M5 PC: " << "0x"<< setw(16) << setfill('0')
443 << hex << m5Pc << endl;
444 outs << setfill(' ') << setw(15)
445 << "Legion PC: " << "0x"<< setw(16) << setfill('0') << hex
446 << lgnPc << endl << endl;
447
448 outs << setfill(' ') << setw(15)
449 << "M5 Inst: " << "0x"<< setw(8)
450 << setfill('0') << hex << staticInst->machInst
451 << staticInst->disassemble(m5Pc, debugSymbolTable)
452 << endl;
453
283 StaticInstPtr legionInst = StaticInst::decode(makeExtMI(shared_data->instruction, thread));
454 StaticInstPtr legionInst =
455 StaticInst::decode(makeExtMI(shared_data->instruction,
456 thread));
457 outs << setfill(' ') << setw(15)
458 << " Legion Inst: "
459 << "0x" << setw(8) << setfill('0') << hex
460 << shared_data->instruction
461 << legionInst->disassemble(lgnPc, debugSymbolTable)
289 << endl;
462 << endl << endl;
463
464 printSectionHeader(outs, "General State");
465 printColumnLabels(outs);
466 printRegPair(outs, "HPstate",
467 thread->readMiscReg(MISCREG_HPSTATE),
468 shared_data->hpstate | (1 << 11));
469 printRegPair(outs, "Htba",
470 thread->readMiscReg(MISCREG_HTBA),
471 shared_data->htba);
472 printRegPair(outs, "Pstate",
473 thread->readMiscReg(MISCREG_PSTATE),
474 shared_data->pstate);
475 printRegPair(outs, "Y",
476 thread->readMiscReg(MISCREG_Y),
477 shared_data->y);
478 printRegPair(outs, "Ccr",
479 thread->readMiscReg(MISCREG_CCR),
480 shared_data->ccr);
481 printRegPair(outs, "Tl",
482 thread->readMiscReg(MISCREG_TL),
483 shared_data->tl);
484 printRegPair(outs, "Gl",
485 thread->readMiscReg(MISCREG_GL),
486 shared_data->gl);
487 printRegPair(outs, "Asi",
488 thread->readMiscReg(MISCREG_ASI),
489 shared_data->asi);
490 printRegPair(outs, "Pil",
491 thread->readMiscReg(MISCREG_PIL),
492 shared_data->pil);
493 printRegPair(outs, "Cwp",
494 thread->readMiscReg(MISCREG_CWP),
495 shared_data->cwp);
496 printRegPair(outs, "Cansave",
497 thread->readMiscReg(MISCREG_CANSAVE),
498 shared_data->cansave);
499 printRegPair(outs, "Canrestore",
500 thread->readMiscReg(MISCREG_CANRESTORE),
501 shared_data->canrestore);
502 printRegPair(outs, "Otherwin",
503 thread->readMiscReg(MISCREG_OTHERWIN),
504 shared_data->otherwin);
505 printRegPair(outs, "Cleanwin",
506 thread->readMiscReg(MISCREG_CLEANWIN),
507 shared_data->cleanwin);
508 outs << endl;
509 for (int i = 1; i <= MaxTL; i++) {
510 printLevelHeader(outs, i);
511 printColumnLabels(outs);
512 thread->setMiscReg(MISCREG_TL, i);
513 printRegPair(outs, "Tpc",
514 thread->readMiscReg(MISCREG_TPC),
515 shared_data->tpc[i]);
516 printRegPair(outs, "Tnpc",
517 thread->readMiscReg(MISCREG_TNPC),
518 shared_data->tnpc[i]);
519 printRegPair(outs, "Tstate",
520 thread->readMiscReg(MISCREG_TSTATE),
521 shared_data->tstate[i]);
522 printRegPair(outs, "Tt",
523 thread->readMiscReg(MISCREG_TT),
524 shared_data->tt[i]);
525 printRegPair(outs, "Htstate",
526 thread->readMiscReg(MISCREG_HTSTATE),
527 shared_data->htstate[i]);
528 }
529 thread->setMiscReg(MISCREG_TL, oldTl);
530 outs << endl;
531
532 printSectionHeader(outs, "General Purpose Registers");
533 static const char * regtypes[4] = {"%g", "%o", "%l", "%i"};
534 for(int y = 0; y < 4; y++)
535 {
536 for(int x = 0; x < 8; x++)
537 {
298 outs << regtypes[y] << x << " " ;
299 outs << "0x" << hex << setw(16) << thread->readIntReg(y*8+x);
300 if (thread->readIntReg(y*8 + x) != shared_data->intregs[y*8+x])
538 char label[8];
539 sprintf(label, "%s%d", regtypes[y], x);
540 printRegPair(outs, label,
541 thread->readIntReg(y*8+x),
542 shared_data->intregs[y*8+x]);
543 /*outs << regtypes[y] << x << " " ;
544 outs << "0x" << hex << setw(16)
545 << thread->readIntReg(y*8+x);
546 if (thread->readIntReg(y*8 + x)
547 != shared_data->intregs[y*8+x])
548 outs << " X ";
549 else
550 outs << " | ";
304 outs << "0x" << setw(16) << hex << shared_data->intregs[y*8+x]
305 << endl;
551 outs << "0x" << setw(16) << hex
552 << shared_data->intregs[y*8+x]
553 << endl;*/
554 }
555 }
556 fatal("Differences found between Legion and M5\n");
557 }
558
559 compared = true;
560 shared_data->flags = OWN_LEGION;
561 }
562 } // while
563 } // if not microop
564 }
565#endif
566}
567
568
569vector<bool> Trace::InstRecord::flags(NUM_BITS);
570string Trace::InstRecord::trace_system;
571
572////////////////////////////////////////////////////////////////////////
573//
574// Parameter space for per-cycle execution address tracing options.
575// Derive from ParamContext so we can override checkParams() function.
576//
577class ExecutionTraceParamContext : public ParamContext
578{
579 public:
580 ExecutionTraceParamContext(const string &_iniSection)
581 : ParamContext(_iniSection)
582 {
583 }
584
585 void checkParams(); // defined at bottom of file
586};
587
588ExecutionTraceParamContext exeTraceParams("exetrace");
589
590Param<bool> exe_trace_spec(&exeTraceParams, "speculative",
591 "capture speculative instructions", true);
592
593Param<bool> exe_trace_print_cycle(&exeTraceParams, "print_cycle",
594 "print cycle number", true);
595Param<bool> exe_trace_print_opclass(&exeTraceParams, "print_opclass",
596 "print op class", true);
597Param<bool> exe_trace_print_thread(&exeTraceParams, "print_thread",
598 "print thread number", true);
599Param<bool> exe_trace_print_effaddr(&exeTraceParams, "print_effaddr",
600 "print effective address", true);
601Param<bool> exe_trace_print_data(&exeTraceParams, "print_data",
602 "print result data", true);
603Param<bool> exe_trace_print_iregs(&exeTraceParams, "print_iregs",
604 "print all integer regs", false);
605Param<bool> exe_trace_print_fetchseq(&exeTraceParams, "print_fetchseq",
606 "print fetch sequence number", false);
607Param<bool> exe_trace_print_cp_seq(&exeTraceParams, "print_cpseq",
608 "print correct-path sequence number", false);
609Param<bool> exe_trace_print_reg_delta(&exeTraceParams, "print_reg_delta",
610 "print which registers changed to what", false);
611Param<bool> exe_trace_pc_symbol(&exeTraceParams, "pc_symbol",
612 "Use symbols for the PC if available", true);
613Param<bool> exe_trace_intel_format(&exeTraceParams, "intel_format",
614 "print trace in intel compatible format", false);
615Param<bool> exe_trace_legion_lockstep(&exeTraceParams, "legion_lockstep",
616 "Compare sim state to legion state every cycle",
617 false);
618Param<string> exe_trace_system(&exeTraceParams, "trace_system",
619 "print trace of which system (client or server)",
620 "client");
621
622
623//
624// Helper function for ExecutionTraceParamContext::checkParams() just
625// to get us into the InstRecord namespace
626//
627void
628Trace::InstRecord::setParams()
629{
630 flags[TRACE_MISSPEC] = exe_trace_spec;
631
632 flags[PRINT_CYCLE] = exe_trace_print_cycle;
633 flags[PRINT_OP_CLASS] = exe_trace_print_opclass;
634 flags[PRINT_THREAD_NUM] = exe_trace_print_thread;
635 flags[PRINT_RESULT_DATA] = exe_trace_print_effaddr;
636 flags[PRINT_EFF_ADDR] = exe_trace_print_data;
637 flags[PRINT_INT_REGS] = exe_trace_print_iregs;
638 flags[PRINT_FETCH_SEQ] = exe_trace_print_fetchseq;
639 flags[PRINT_CP_SEQ] = exe_trace_print_cp_seq;
640 flags[PRINT_REG_DELTA] = exe_trace_print_reg_delta;
641 flags[PC_SYMBOL] = exe_trace_pc_symbol;
642 flags[INTEL_FORMAT] = exe_trace_intel_format;
643 flags[LEGION_LOCKSTEP] = exe_trace_legion_lockstep;
644 trace_system = exe_trace_system;
645
646 // If were going to be in lockstep with Legion
647 // Setup shared memory, and get otherwise ready
648 if (flags[LEGION_LOCKSTEP]) {
649 int shmfd = shmget('M' << 24 | getuid(), sizeof(SharedData), 0777);
650 if (shmfd < 0)
651 fatal("Couldn't get shared memory fd. Is Legion running?");
652
653 shared_data = (SharedData*)shmat(shmfd, NULL, SHM_RND);
654 if (shared_data == (SharedData*)-1)
655 fatal("Couldn't allocate shared memory");
656
657 if (shared_data->flags != OWN_M5)
658 fatal("Shared memory has invalid owner");
659
660 if (shared_data->version != VERSION)
661 fatal("Shared Data is wrong version! M5: %d Legion: %d", VERSION,
662 shared_data->version);
663
664 // step legion forward one cycle so we can get register values
665 shared_data->flags = OWN_LEGION;
666 }
667}
668
669void
670ExecutionTraceParamContext::checkParams()
671{
672 Trace::InstRecord::setParams();
673}
674