tracechild_sparc.cc
来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· CC 代码 · 共 488 行 · 第 1/2 页
CC
488 行
//Multiply the displacement by 4. I'm assuming the compiler is //smart enough to turn this into a shift. disp *= 4; target1 = pc + disp; } else if(bn) target1 = npc + 4; else target1 = npc; return 1; } else { target1 = npc; return 1; }}bool SparcTraceChild::step(){ //Increment the count of the number of instructions executed instructions++; //Two important considerations are that the address of the instruction //being breakpointed should be word (64bit) aligned, and that both the //next instruction and the instruction after that need to be breakpointed //so that annulled branches will still stop as well. /* * Useful constants */ const static uint64_t breakInst = 0x91d02001; const static uint64_t lowBreakInst = breakInst; const static uint64_t highBreakInst = breakInst << 32; const static uint64_t breakWord = breakInst | (breakInst << 32); const static uint64_t lowMask = 0xFFFFFFFFULL; const static uint64_t highMask = lowMask << 32; /* * storage for the original contents of the child process's memory */ uint64_t originalInst, originalAnnulInst; /* * Get information about where the process is and is headed next. */ uint64_t currentPC = getRegVal(PC); bool unalignedPC = currentPC & 7; uint64_t alignedPC = currentPC & (~7); uint64_t nextPC = getRegVal(NPC); bool unalignedNPC = nextPC & 7; uint64_t alignedNPC = nextPC & (~7); //Get the current instruction uint64_t curInst = ptrace(PTRACE_PEEKTEXT, pid, alignedPC); curInst = unalignedPC ? (curInst & 0xffffffffULL) : (curInst >> 32); uint64_t bp1, bp2; int numTargets = getTargets(curInst, currentPC, nextPC, bp1, bp2); assert(numTargets == 1 || numTargets == 2); bool unalignedBp1 = bp1 & 7; uint64_t alignedBp1 = bp1 & (~7); bool unalignedBp2 = bp2 & 7; uint64_t alignedBp2 = bp2 & (~7); uint64_t origBp1, origBp2; /* * Set the first breakpoint */ origBp1 = ptrace(PTRACE_PEEKTEXT, pid, alignedBp1, 0); uint64_t newBp1 = origBp1; newBp1 &= unalignedBp1 ? highMask : lowMask; newBp1 |= unalignedBp1 ? lowBreakInst : highBreakInst; if(ptrace(PTRACE_POKETEXT, pid, alignedBp1, newBp1) != 0) cerr << "Poke failed" << endl; /* * Set the second breakpoint if necessary */ if(numTargets == 2) { origBp2 = ptrace(PTRACE_PEEKTEXT, pid, alignedBp2, 0); uint64_t newBp2 = origBp2; newBp2 &= unalignedBp2 ? highMask : lowMask; newBp2 |= unalignedBp2 ? lowBreakInst : highBreakInst; if(ptrace(PTRACE_POKETEXT, pid, alignedBp2, newBp2) != 0) cerr << "Poke failed" << endl; } /* * Restart the child process */ //Note that the "addr" parameter is supposed to be ignored, but in at //least one version of the kernel, it must be 1 or it will set what //pc to continue from if(ptrace(PTRACE_CONT, pid, 1, 0) != 0) cerr << "Cont failed" << endl; doWait(); /* * Update our record of the child's state */ update(pid); /* * Put back the original contents of the childs address space in the * reverse order. */ if(numTargets == 2) { if(ptrace(PTRACE_POKETEXT, pid, alignedBp2, origBp2) != 0) cerr << "Poke failed" << endl; } if(ptrace(PTRACE_POKETEXT, pid, alignedBp1, origBp1) != 0) cerr << "Poke failed" << endl;}int64_t SparcTraceChild::getRegVal(int num){ return getRegs(theregs, thefpregs, locals, inputs, num);}int64_t SparcTraceChild::getOldRegVal(int num){ return getRegs(oldregs, oldfpregs, oldLocals, oldInputs, num);}char * SparcTraceChild::printReg(int num){ sprintf(printBuffer, "0x%016llx", getRegVal(num)); return printBuffer;}ostream & SparcTraceChild::outputStartState(ostream & os){ bool v8 = false; uint64_t sp = getSP(); if(sp % 2) { os << "Detected a 64 bit executable.\n"; v8 = false; } else { os << "Detected a 32 bit executable.\n"; v8 = true; } uint64_t pc = getPC(); char obuf[1024]; sprintf(obuf, "Initial stack pointer = 0x%016llx\n", sp); os << obuf; sprintf(obuf, "Initial program counter = 0x%016llx\n", pc); os << obuf; if(!v8) { //Take out the stack bias sp += 2047; } //Output the window save area for(unsigned int x = 0; x < 16; x++) { uint64_t regspot = ptrace(PTRACE_PEEKDATA, pid, sp, 0); if(v8) regspot = regspot >> 32; sprintf(obuf, "0x%016llx: Window save %d = 0x%016llx\n", sp, x+1, regspot); os << obuf; sp += v8 ? 4 : 8; } //Output the argument count uint64_t cargc = ptrace(PTRACE_PEEKDATA, pid, sp, 0); if(v8) cargc = cargc >> 32; sprintf(obuf, "0x%016llx: Argc = 0x%016llx\n", sp, cargc); os << obuf; sp += v8 ? 4 : 8; //Output argv pointers int argCount = 0; uint64_t cargv; do { cargv = ptrace(PTRACE_PEEKDATA, pid, sp, 0); if(v8) cargv = cargv >> 32; sprintf(obuf, "0x%016llx: argv[%d] = 0x%016llx\n", sp, argCount++, cargv); os << obuf; sp += v8 ? 4 : 8; } while(cargv); //Output the envp pointers int envCount = 0; uint64_t cenvp; do { cenvp = ptrace(PTRACE_PEEKDATA, pid, sp, 0); if(v8) cenvp = cenvp >> 32; sprintf(obuf, "0x%016llx: envp[%d] = 0x%016llx\n", sp, envCount++, cenvp); os << obuf; sp += v8 ? 4 : 8; } while(cenvp); uint64_t auxType, auxVal; do { auxType = ptrace(PTRACE_PEEKDATA, pid, sp, 0); if(v8) auxType = auxType >> 32; sp += (v8 ? 4 : 8); auxVal = ptrace(PTRACE_PEEKDATA, pid, sp, 0); if(v8) auxVal = auxVal >> 32; sp += (v8 ? 4 : 8); sprintf(obuf, "0x%016llx: Auxiliary vector = {0x%016llx, 0x%016llx}\n", sp - 8, auxType, auxVal); os << obuf; } while(auxType != 0 || auxVal != 0); //Print out the argument strings, environment strings, and file name. string current; uint64_t buf; uint64_t currentStart = sp; bool clearedInitialPadding = false; do { buf = ptrace(PTRACE_PEEKDATA, pid, sp, 0); char * cbuf = (char *)&buf; for(int x = 0; x < sizeof(uint32_t); x++) { if(cbuf[x]) current += cbuf[x]; else { sprintf(obuf, "0x%016llx: \"%s\"\n", currentStart, current.c_str()); os << obuf; current = ""; currentStart = sp + x + 1; } } sp += (v8 ? 4 : 8); clearedInitialPadding = clearedInitialPadding || buf != 0; } while(!clearedInitialPadding || buf != 0); return os;}TraceChild * genTraceChild(){ return new SparcTraceChild;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?