exetrace.cc revision 3754
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