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