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