exetrace.cc revision 3825:9b5e6c4d3ecb
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                        }
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
694