exetrace.cc revision 3814:33bd4ec9d66a
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 diffCC   = false;
289        bool diffInst = false;
290        bool diffRegs = false;
291        bool diffTpc = false;
292        bool diffTnpc = false;
293        bool diffTstate = false;
294        bool diffTt = false;
295        bool diffTba = false;
296        bool diffHpstate = false;
297        bool diffHtstate = false;
298        bool diffHtba = false;
299        bool diffPstate = false;
300        bool diffY = false;
301        bool diffCcr = false;
302        bool diffTl = false;
303        bool diffGl = false;
304        bool diffAsi = false;
305        bool diffPil = false;
306        bool diffCwp = false;
307        bool diffCansave = false;
308        bool diffCanrestore = false;
309        bool diffOtherwin = false;
310        bool diffCleanwin = false;
311        Addr m5Pc, lgnPc;
312
313
314        if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) {
315            while (!compared) {
316                if (shared_data->flags == OWN_M5) {
317                    m5Pc = PC & TheISA::PAddrImplMask;
318                    lgnPc = shared_data->pc & TheISA::PAddrImplMask;
319                    if (lgnPc != m5Pc)
320                       diffPC = true;
321
322                    if (shared_data->cycle_count !=
323                            thread->getCpuPtr()->instCount())
324                        diffCC = true;
325
326                    if (shared_data->instruction !=
327                            (SparcISA::MachInst)staticInst->machInst) {
328                        diffInst = true;
329                    }
330                    for (int i = 0; i < TheISA::NumIntArchRegs; i++) {
331                        if (thread->readIntReg(i) != shared_data->intregs[i]) {
332                            diffRegs = true;
333                        }
334                    }
335                    uint64_t oldTl = thread->readMiscReg(MISCREG_TL);
336                    if (oldTl != shared_data->tl)
337                        diffTl = true;
338                    for (int i = 1; i <= MaxTL; i++) {
339                        thread->setMiscReg(MISCREG_TL, i);
340                        if (thread->readMiscReg(MISCREG_TPC) !=
341                                shared_data->tpc[i])
342                            diffTpc = true;
343                        if (thread->readMiscReg(MISCREG_TNPC) !=
344                                shared_data->tnpc[i])
345                            diffTnpc = true;
346                        if (thread->readMiscReg(MISCREG_TSTATE) !=
347                                shared_data->tstate[i])
348                            diffTstate = true;
349                        if (thread->readMiscReg(MISCREG_TT) !=
350                                shared_data->tt[i])
351                            diffTt = true;
352                        if (thread->readMiscReg(MISCREG_HTSTATE) !=
353                                shared_data->htstate[i])
354                            diffHtstate = true;
355                    }
356                    thread->setMiscReg(MISCREG_TL, oldTl);
357
358                    if(shared_data->tba != thread->readMiscReg(MISCREG_TBA))
359                        diffTba = true;
360                    //When the hpstate register is read by an instruction,
361                    //legion has bit 11 set. When it's in storage, it doesn't.
362                    //Since we don't directly support seperate interpretations
363                    //of the registers like that, the bit is always set to 1 and
364                    //we just don't compare it. It's not supposed to matter
365                    //anyway.
366                    if((shared_data->hpstate | (1 << 11)) != thread->readMiscReg(MISCREG_HPSTATE))
367                        diffHpstate = true;
368                    if(shared_data->htba != thread->readMiscReg(MISCREG_HTBA))
369                        diffHtba = true;
370                    if(shared_data->pstate != thread->readMiscReg(MISCREG_PSTATE))
371                        diffPstate = true;
372                    if(shared_data->y != thread->readMiscReg(MISCREG_Y))
373                        diffY = true;
374                    if(shared_data->ccr != thread->readMiscReg(MISCREG_CCR))
375                        diffCcr = true;
376                    if(shared_data->gl != thread->readMiscReg(MISCREG_GL))
377                        diffGl = true;
378                    if(shared_data->asi != thread->readMiscReg(MISCREG_ASI))
379                        diffAsi = true;
380                    if(shared_data->pil != thread->readMiscReg(MISCREG_PIL))
381                        diffPil = true;
382                    if(shared_data->cwp != thread->readMiscReg(MISCREG_CWP))
383                        diffCwp = true;
384                    if(shared_data->cansave != thread->readMiscReg(MISCREG_CANSAVE))
385                        diffCansave = true;
386                    if(shared_data->canrestore !=
387                            thread->readMiscReg(MISCREG_CANRESTORE))
388                        diffCanrestore = true;
389                    if(shared_data->otherwin != thread->readMiscReg(MISCREG_OTHERWIN))
390                        diffOtherwin = true;
391                    if(shared_data->cleanwin != thread->readMiscReg(MISCREG_CLEANWIN))
392                        diffCleanwin = true;
393
394                    if (diffPC || diffCC || diffInst || diffRegs || diffTpc ||
395                            diffTnpc || diffTstate || diffTt || diffHpstate ||
396                            diffHtstate || diffHtba || diffPstate || diffY ||
397                            diffCcr || diffTl || diffGl || diffAsi || diffPil ||
398                            diffCwp || diffCansave || diffCanrestore ||
399                            diffOtherwin || diffCleanwin) {
400                        outs << "Differences found between M5 and Legion:";
401                        if (diffPC)
402                            outs << " [PC]";
403                        if (diffCC)
404                            outs << " [CC]";
405                        if (diffInst)
406                            outs << " [Instruction]";
407                        if (diffRegs)
408                            outs << " [IntRegs]";
409                        if (diffTpc)
410                            outs << " [Tpc]";
411                        if (diffTnpc)
412                            outs << " [Tnpc]";
413                        if (diffTstate)
414                            outs << " [Tstate]";
415                        if (diffTt)
416                            outs << " [Tt]";
417                        if (diffHpstate)
418                            outs << " [Hpstate]";
419                        if (diffHtstate)
420                            outs << " [Htstate]";
421                        if (diffHtba)
422                            outs << " [Htba]";
423                        if (diffPstate)
424                            outs << " [Pstate]";
425                        if (diffY)
426                            outs << " [Y]";
427                        if (diffCcr)
428                            outs << " [Ccr]";
429                        if (diffTl)
430                            outs << " [Tl]";
431                        if (diffGl)
432                            outs << " [Gl]";
433                        if (diffAsi)
434                            outs << " [Asi]";
435                        if (diffPil)
436                            outs << " [Pil]";
437                        if (diffCwp)
438                            outs << " [Cwp]";
439                        if (diffCansave)
440                            outs << " [Cansave]";
441                        if (diffCanrestore)
442                            outs << " [Canrestore]";
443                        if (diffOtherwin)
444                            outs << " [Otherwin]";
445                        if (diffCleanwin)
446                            outs << " [Cleanwin]";
447                        outs << endl << endl;
448
449                        outs << right << setfill(' ') << setw(15)
450                             << "M5 PC: " << "0x"<< setw(16) << setfill('0')
451                             << hex << m5Pc << endl;
452                        outs << setfill(' ') << setw(15)
453                             << "Legion PC: " << "0x"<< setw(16) << setfill('0') << hex
454                             << lgnPc << endl << endl;
455
456                        outs << right << setfill(' ') << setw(15)
457                             << "M5 CC: " << "0x"<< setw(16) << setfill('0')
458                             << hex << thread->getCpuPtr()->instCount() << endl;
459                        outs << setfill(' ') << setw(15)
460                             << "Legion CC: " << "0x"<< setw(16) << setfill('0') << hex
461                             << shared_data->cycle_count << endl << endl;
462
463                        outs << setfill(' ') << setw(15)
464                             << "M5 Inst: "  << "0x"<< setw(8)
465                             << setfill('0') << hex << staticInst->machInst
466                             << staticInst->disassemble(m5Pc, debugSymbolTable)
467                             << endl;
468
469                        StaticInstPtr legionInst =
470                            StaticInst::decode(makeExtMI(shared_data->instruction,
471                                        thread));
472                        outs << setfill(' ') << setw(15)
473                             << " Legion Inst: "
474                             << "0x" << setw(8) << setfill('0') << hex
475                             << shared_data->instruction
476                             << legionInst->disassemble(lgnPc, debugSymbolTable)
477                             << endl << endl;
478
479                        printSectionHeader(outs, "General State");
480                        printColumnLabels(outs);
481                        printRegPair(outs, "HPstate",
482                                thread->readMiscReg(MISCREG_HPSTATE),
483                                shared_data->hpstate | (1 << 11));
484                        printRegPair(outs, "Htba",
485                                thread->readMiscReg(MISCREG_HTBA),
486                                shared_data->htba);
487                        printRegPair(outs, "Pstate",
488                                thread->readMiscReg(MISCREG_PSTATE),
489                                shared_data->pstate);
490                        printRegPair(outs, "Y",
491                                thread->readMiscReg(MISCREG_Y),
492                                shared_data->y);
493                        printRegPair(outs, "Ccr",
494                                thread->readMiscReg(MISCREG_CCR),
495                                shared_data->ccr);
496                        printRegPair(outs, "Tl",
497                                thread->readMiscReg(MISCREG_TL),
498                                shared_data->tl);
499                        printRegPair(outs, "Gl",
500                                thread->readMiscReg(MISCREG_GL),
501                                shared_data->gl);
502                        printRegPair(outs, "Asi",
503                                thread->readMiscReg(MISCREG_ASI),
504                                shared_data->asi);
505                        printRegPair(outs, "Pil",
506                                thread->readMiscReg(MISCREG_PIL),
507                                shared_data->pil);
508                        printRegPair(outs, "Cwp",
509                                thread->readMiscReg(MISCREG_CWP),
510                                shared_data->cwp);
511                        printRegPair(outs, "Cansave",
512                                thread->readMiscReg(MISCREG_CANSAVE),
513                                shared_data->cansave);
514                        printRegPair(outs, "Canrestore",
515                                thread->readMiscReg(MISCREG_CANRESTORE),
516                                shared_data->canrestore);
517                        printRegPair(outs, "Otherwin",
518                                thread->readMiscReg(MISCREG_OTHERWIN),
519                                shared_data->otherwin);
520                        printRegPair(outs, "Cleanwin",
521                                thread->readMiscReg(MISCREG_CLEANWIN),
522                                shared_data->cleanwin);
523                        outs << endl;
524                        for (int i = 1; i <= MaxTL; i++) {
525                            printLevelHeader(outs, i);
526                            printColumnLabels(outs);
527                            thread->setMiscReg(MISCREG_TL, i);
528                            printRegPair(outs, "Tpc",
529                                    thread->readMiscReg(MISCREG_TPC),
530                                    shared_data->tpc[i]);
531                            printRegPair(outs, "Tnpc",
532                                    thread->readMiscReg(MISCREG_TNPC),
533                                    shared_data->tnpc[i]);
534                            printRegPair(outs, "Tstate",
535                                    thread->readMiscReg(MISCREG_TSTATE),
536                                    shared_data->tstate[i]);
537                            printRegPair(outs, "Tt",
538                                    thread->readMiscReg(MISCREG_TT),
539                                    shared_data->tt[i]);
540                            printRegPair(outs, "Htstate",
541                                    thread->readMiscReg(MISCREG_HTSTATE),
542                                    shared_data->htstate[i]);
543                        }
544                        thread->setMiscReg(MISCREG_TL, oldTl);
545                        outs << endl;
546
547                        printSectionHeader(outs, "General Purpose Registers");
548                        static const char * regtypes[4] = {"%g", "%o", "%l", "%i"};
549                        for(int y = 0; y < 4; y++)
550                        {
551                            for(int x = 0; x < 8; x++)
552                            {
553                                char label[8];
554                                sprintf(label, "%s%d", regtypes[y], x);
555                                printRegPair(outs, label,
556                                        thread->readIntReg(y*8+x),
557                                        shared_data->intregs[y*8+x]);
558                                /*outs << regtypes[y] << x << "         " ;
559                                outs <<  "0x" << hex << setw(16)
560                                    << thread->readIntReg(y*8+x);
561                                if (thread->readIntReg(y*8 + x)
562                                        != shared_data->intregs[y*8+x])
563                                    outs << "     X     ";
564                                else
565                                    outs << "     |     ";
566                                outs << "0x" << setw(16) << hex
567                                    << shared_data->intregs[y*8+x]
568                                    << endl;*/
569                            }
570                        }
571                        fatal("Differences found between Legion and M5\n");
572                    }
573
574                    compared = true;
575                    shared_data->flags = OWN_LEGION;
576                }
577            } // while
578        } // if not microop
579    }
580#endif
581}
582
583
584vector<bool> Trace::InstRecord::flags(NUM_BITS);
585string Trace::InstRecord::trace_system;
586
587////////////////////////////////////////////////////////////////////////
588//
589// Parameter space for per-cycle execution address tracing options.
590// Derive from ParamContext so we can override checkParams() function.
591//
592class ExecutionTraceParamContext : public ParamContext
593{
594  public:
595    ExecutionTraceParamContext(const string &_iniSection)
596        : ParamContext(_iniSection)
597        {
598        }
599
600    void checkParams();	// defined at bottom of file
601};
602
603ExecutionTraceParamContext exeTraceParams("exetrace");
604
605Param<bool> exe_trace_spec(&exeTraceParams, "speculative",
606                           "capture speculative instructions", true);
607
608Param<bool> exe_trace_print_cycle(&exeTraceParams, "print_cycle",
609                                  "print cycle number", true);
610Param<bool> exe_trace_print_opclass(&exeTraceParams, "print_opclass",
611                                  "print op class", true);
612Param<bool> exe_trace_print_thread(&exeTraceParams, "print_thread",
613                                  "print thread number", true);
614Param<bool> exe_trace_print_effaddr(&exeTraceParams, "print_effaddr",
615                                  "print effective address", true);
616Param<bool> exe_trace_print_data(&exeTraceParams, "print_data",
617                                  "print result data", true);
618Param<bool> exe_trace_print_iregs(&exeTraceParams, "print_iregs",
619                                  "print all integer regs", false);
620Param<bool> exe_trace_print_fetchseq(&exeTraceParams, "print_fetchseq",
621                                  "print fetch sequence number", false);
622Param<bool> exe_trace_print_cp_seq(&exeTraceParams, "print_cpseq",
623                                  "print correct-path sequence number", false);
624Param<bool> exe_trace_print_reg_delta(&exeTraceParams, "print_reg_delta",
625                                  "print which registers changed to what", false);
626Param<bool> exe_trace_pc_symbol(&exeTraceParams, "pc_symbol",
627                                  "Use symbols for the PC if available", true);
628Param<bool> exe_trace_intel_format(&exeTraceParams, "intel_format",
629                                   "print trace in intel compatible format", false);
630Param<bool> exe_trace_legion_lockstep(&exeTraceParams, "legion_lockstep",
631                                   "Compare sim state to legion state every cycle",
632                                   false);
633Param<string> exe_trace_system(&exeTraceParams, "trace_system",
634                                   "print trace of which system (client or server)",
635                                   "client");
636
637
638//
639// Helper function for ExecutionTraceParamContext::checkParams() just
640// to get us into the InstRecord namespace
641//
642void
643Trace::InstRecord::setParams()
644{
645    flags[TRACE_MISSPEC]     = exe_trace_spec;
646
647    flags[PRINT_CYCLE]       = exe_trace_print_cycle;
648    flags[PRINT_OP_CLASS]    = exe_trace_print_opclass;
649    flags[PRINT_THREAD_NUM]  = exe_trace_print_thread;
650    flags[PRINT_RESULT_DATA] = exe_trace_print_effaddr;
651    flags[PRINT_EFF_ADDR]    = exe_trace_print_data;
652    flags[PRINT_INT_REGS]    = exe_trace_print_iregs;
653    flags[PRINT_FETCH_SEQ]   = exe_trace_print_fetchseq;
654    flags[PRINT_CP_SEQ]      = exe_trace_print_cp_seq;
655    flags[PRINT_REG_DELTA]   = exe_trace_print_reg_delta;
656    flags[PC_SYMBOL]         = exe_trace_pc_symbol;
657    flags[INTEL_FORMAT]      = exe_trace_intel_format;
658    flags[LEGION_LOCKSTEP]   = exe_trace_legion_lockstep;
659    trace_system	     = exe_trace_system;
660
661    // If were going to be in lockstep with Legion
662    // Setup shared memory, and get otherwise ready
663    if (flags[LEGION_LOCKSTEP]) {
664        int shmfd = shmget('M' << 24 | getuid(), sizeof(SharedData), 0777);
665        if (shmfd < 0)
666            fatal("Couldn't get shared memory fd. Is Legion running?");
667
668        shared_data = (SharedData*)shmat(shmfd, NULL, SHM_RND);
669        if (shared_data == (SharedData*)-1)
670            fatal("Couldn't allocate shared memory");
671
672        if (shared_data->flags != OWN_M5)
673            fatal("Shared memory has invalid owner");
674
675        if (shared_data->version != VERSION)
676            fatal("Shared Data is wrong version! M5: %d Legion: %d", VERSION,
677                    shared_data->version);
678
679        // step legion forward one cycle so we can get register values
680        shared_data->flags = OWN_LEGION;
681    }
682}
683
684void
685ExecutionTraceParamContext::checkParams()
686{
687    Trace::InstRecord::setParams();
688}
689
690