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