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 + -
显示快捷键?