⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tracer.c

📁 realview22.rar
💻 C
📖 第 1 页 / 共 5 页
字号:
  void *f=ts->output.handle;
  Tracer_PrintfProc *tprintf = ts->output.tprintf;
  Tracer_PutCProc *tputc = ts->output.putc;
  int width=8;

  switch(packet_type) {
  case Trace_BusAccess:
      tputc('B',f);
      break;
  case Trace_MemAccess:
  default:
      tputc('M',f);
  }
  if (acc_CYCLE(acc) == acc_Icycle)
      {
    /* This is used for 2 purposes:
     *   - SDT 7TDMI ARMulator generates these for 'internal cycles'
     *     Not bus idles because needed to decode merged IS cycles
     *     However SDT 7TDMI does not provide correct address.
     *   - AMBA real bus idle cycles
     */
    tputc('I',f); /* has no relevant address or data */
  } else {
    if (acc_MREQ(acc)) {
      /* These casts are needed to remove warnings under MSVC++ */
      tputc((char)(acc_SEQ(acc) ? 'S' : 'N'), f);
      tputc((char)(acc_READ(acc) ? 'R' : 'W'), f);
      switch (acc_WIDTH(acc)) {
      case BITS_8:  tputc('1',f); width=2; break;
      case BITS_16: tputc('2',f); width=4; break;
      case BITS_32: tputc('4',f); break;
      case BITS_64: tputc('8',f); break;
      default: tputc('r',f); break; /* reserved */
      }
      tputc((char)(acc_OPC(acc) ? 'O' : '_'), f);
      tputc((char)(acc_LOCK(acc) ? 'L' : '_'), f);
      tputc((char)(acc_SPEC(acc) ? 'S' : '_'), f);
      tputc((char)(acc_DMORE(acc) ? 'D' : '_'), f);

      if (ts->prop & TRACE_ACCESSHIT)
      {
          if (packet_type == Trace_MemAccess)
          {
              uint64 data = 0;
              static uint32 pID[2] = {BMPropertyID_MemAccessHit,0};
              ATracer *as = &ts->Core_Tracer;
              int err = as->mem_ref.master_info(
                  as->mem_ref.handle, ACCESS_READ_WORD, pID ,&data);
              if (err== RDIError_NoError)
              {
                  unsigned ht = (unsigned)data & MemAccessHit_TypeMASK;
                  tprintf(f,"(%s%c%x)",MemAccessHit_Names1[ht],
                          "?UIDxxxxxxxxxxxx"[(data>>4)&0xF],
                          (unsigned)(data>>16));
              }
              else
              {
                  tprintf(f,"(" "??" ")");
              }
          }
#if 0
          else
          {
              tprintf(f,"<%u>", (unsigned)packet->type);
          }
#endif
      }


    } else { /* not mreq */
      if (as->memfeatures & TRACE_MEMFEATURE_AMBA) {
        tputc((char)(acc_SEQ(acc) ? 'r' /* reserved */ : 'A'), f);
        tputc((char)(acc_READ(acc) ? 'R' : 'W'), f);
        switch (acc_WIDTH(acc)) {
        case BITS_8:  tputc('1',f); width=2; break;
        case BITS_16: tputc('2',f); width=4; break;
        case BITS_32: tputc('4',f); break;
        case BITS_64: tputc('8',f); break;
        default: tputc('_',f); break; /* reserved */
      }
      tputc((char)(acc_OPC(acc) ? 'O' : '_'), f);
      tputc((char)(acc_LOCK(acc) ? 'L' : '_'), f);
      tputc((char)(acc_SPEC(acc) ? 'S' : '_'), f);
      tputc((char)(acc_DMORE(acc) ? 'D' : '_'), f);
      } else if (acc_SPEC(acc)) {
        tputc((char)(acc_SEQ(acc) ? 'S' /* reserved */ : 'N'), f);
        tputc((char)(acc_READ(acc) ? 'R' : 'W'), f);
        switch (acc_WIDTH(acc)) {
        case BITS_8:  tputc('1',f); width=2; break;
        case BITS_16: tputc('2',f); width=4; break;
        case BITS_32: tputc('4',f); break;
        case BITS_64: tputc('8',f); break;
        default: tputc('_',f); break; /* reserved */
        }
        tputc((char)(acc_OPC(acc) ? 'O' : '_'), f);
        tputc((char)(acc_LOCK(acc) ? 'L' : '_'), f);
        tputc((char)(acc_SPEC(acc) ? 'S' : '_'), f);
        tputc((char)(acc_DMORE(acc) ? 'D' : '_'), f);
      } else if (acc_KILL(acc)) {
        tputc((char)(acc_SEQ(acc) ? 'S' : 'N'), f);
        tputc((char)(acc_READ(acc) ? 'R' : 'W'), f);
        switch (acc_WIDTH(acc)) {
        case BITS_8:  tputc('1',f); width=2; break;
        case BITS_16: tputc('2',f); width=4; break;
        case BITS_32: tputc('4',f); break;
        case BITS_64: tputc('8',f); break;
        default: tputc('_',f); break; /* reserved */
        }
        tputc((char)(acc_OPC(acc) ? 'O' : '_'), f);
        tputc((char)(acc_LOCK(acc) ? 'L' : '_'), f);
        tputc((char)(acc_KILL(acc) ? 'K' : '_'), f);
        tputc((char)(acc_DMORE(acc) ? 'D' : '_'), f);
      } else {
        tputc((char)(acc_SEQ(acc) ? 'C' : 'I'),f);
        if (acc_OPC(acc)) tputc('O', f);
        /* Trace time on Bus if we can and should. */
        if ((ts->prop & TRACE_TIMESTAMP) &&
            packet_type == Trace_BusAccess &&
            as->p_ABus != NULL)
        {
            tprintf(f, " @%08x", (unsigned)as->p_ABus->bus_BusyUntil);
        }
      }
    }
    if (as->memfeatures & TRACE_MEMFEATURE_AMBA) {
      switch (acc_BURST_TYPE(acc)) {
      case acc_burst_none:  tputc('_',f); break;
      case acc_burst_4word: tputc('4',f); break;
      case acc_burst_8word: tputc('8',f); break;
      default:              tputc('r',f); break; /* reserved */
      }
    }

    if (acc_MREQ(acc) || acc_SPEC(acc) || (as->memfeatures & TRACE_MEMFEATURE_AMBA))
      /* no valid address supplied in ARMulator idle cycles */
      tprintf(f, " %08lX", addr);
  }

  return width;
}

static char const *eventSignalNames[] = {
    "RESET","UNDEF","SWI","PABORT","DABORT","SE","IRQ","FIQ",
    "BreakPt","WatchPt","Stop"
};


/* Purpose: Trigger a breakpoint when on required line. */
static void Tracer_newline(TracerState *ts)
{
    void *f=ts->output.handle;
    Tracer_PutCProc *tputc = ts->output.putc;
    tputc('\n', f);
    if (++ts->line_number == ts->break_line) {
        /* Maybe RDIError_WatchpointAccessed, or RDIError_UserInterrupt? */
        ARMulif_StopExecution(&ts->coredesc,RDIError_BreakpointReached);
    }
}


static void tracer_javadis(uint32 instr, ARMword pc, char *buffer)
{
    byte bytes[3];
    bytes[0]=(byte)instr;
    bytes[1]=(byte)(instr>>16);
    bytes[2]=(byte)(instr>>24);

    if ((instr & JAVA_EXT_MASK) > 0xFF)
    {
        switch (instr & JAVA_EXT_MASK)
        {
        case JAVA_EXT_NULL_POINTER:
            sprintf(buffer,"Internal_NULL_POINTER");
            break;
        case JAVA_EXT_ARRAY_BOUNDS:
            sprintf(buffer,"Internal_ARRAY_BOUNDS");
            break;
        case JAVA_EXT_JAVA_DISABLED:
            sprintf(buffer,"Internal_JAVA_DISABLED");
            break;
        case JAVA_EXT_VFP_EXCEPTION:
            sprintf(buffer,"Internal_VFP_EXCEPTION");
            break;
        case JAVA_EXT_PREFETCH_ABORT:
            sprintf(buffer,"Internal_PREFETCH_ABORT");
            break;
        case JAVA_EXT_INVALID_CONFIG:
            sprintf(buffer,"Internal_INVALID_CONFIG");
            break;
        case JAVA_EXT_NOT_FIRST_CYCLE: /* Not expected ! */
            sprintf(buffer,"Internal_NOT_FIRST_CYCLE");
            break;
        case JAVA_EXT_ENTERRINGJAVA:
            sprintf(buffer,"Internal_ENTERRINGJAVA");
            break;
        case JAVA_EXT_BOUNCE2SUPPORT:
            sprintf(buffer,"Internal_BOUNCE2SUPPORT");
            break;
        default:
            sprintf(buffer,"Internal_Unknown:0x%03x",
                    (unsigned)(instr & JAVA_EXT_MASK));
            return;
        }
        return;
    }

    /* There is a problem with disassembling some opcodes which take extra
     * words after them, so we special-case those here. */
    switch (bytes[0])
    {
    case 170: sprintf(buffer,"tableswitch");
        break;
    case 171: sprintf(buffer,"lookupswitch");
        break;
    default:
        (void)disass_java(bytes,pc,buffer);
    }
}

static void tracer_disass(TracerState *ts, Trace_Packet *packet,
                          uint32 instr, ARMword pc, char *buffer)
{
    switch(packet->u.instr.iset) 
    {
    case ISET_THUMB:
    {
        unsigned top5 = instr>>11;
        /* Complications for Thumb 2-instruction BL...
         * ARM disass API (current instr, next instr) is not ideal
         * for disassembling instructions as they are executed, where
         * want to specify current instr & previous instr.
         */
        if (instr & 0xFFFF0000) { /* Must already be a double hw instruction */
            disass_16(instr >> 16, instr & 0xFFFF, pc, buffer, NULL, cb_proc);
        } else if (top5==0x1E) {
            strcpy(buffer, "(1st instr of BL pair)");
            ts->prev_instr=instr;
        } else if (top5==0x1F || top5 == 0x1D) {  /* second instruction */
            /* if prev_instr is invalid, disass_16 shows "???" */
            disass_16(ts->prev_instr,instr,pc-2,buffer,NULL,cb_proc);
        } else {
            disass_16(instr,0,pc,buffer,NULL,cb_proc);
        }
    }
        break;
    case ISET_ARM:
        disass(instr,pc,buffer,NULL,cb_proc);
        break;
    case ISET_JAVA:
        tracer_javadis(instr, pc, buffer);
        break;
    default:
        sprintf(buffer,"(UNKNOWN INSTRUCTION SET)");
        break;
    }
}


/* Tracing for Arch mode.*/
#define UNKNOWN_REG ((ARMword)-1)

static void TraceAccess(TracerState *ts, char id[], ARMword address, 
                        ARMword data, ARMword reg,
                        Trace_Packet *packet)
{
    void *f=ts->output.handle;
    Tracer_PrintfProc *tprintf = ts->output.tprintf;
    Tracer_PutSProc *tputs = ts->output.puts;
    Tracer_PutCProc *tputc = ts->output.putc;
    char localid[4];
    
    localid[0] = id[0];
    localid[1] = id[1];
    localid[2] = id[2];
    localid[3] = '\0';
    if (localid[0] == 'I') { /* instruction */
        switch (localid[1])
        {
        default:
        case 'J': /* JAVA */
        case 'A': /* ARM */
            tprintf(f,"%3s %08x %08x ", localid, (unsigned)address,
                        (unsigned)data);
            break;
        case 'T': /* Thumb */
            tprintf(f,"%3s %08x %04x ", localid, (unsigned)address,
                    (unsigned)data);
            break;
        }

        if (ts->prop & TRACE_DISASS) {
            ARMword instr = data; char buffer[256];
            ARMword pc = address;

            tracer_disass(ts, packet, instr, pc, buffer);
            if (!(id[2]=='P')/*executed*/) {
                char *p;
                for (p=buffer; *p; p++)
                    if (isupper((int)*p)) *p=(char)tolower((int)*p);
            }
            tputc(' ', f);
            tputs(buffer, f);
        }
    }
    else
    {   /* not Instruction */
        if (reg != UNKNOWN_REG)
            tprintf(f,"%3s %08x %08x %1x", localid, (unsigned)address,
                    (unsigned)data,(unsigned)reg);
        else
            tprintf(f,"%3s %08x %08x", localid, (unsigned)address,
                    (unsigned)data);
    }
    Tracer_newline(ts);
}

/* Returns RDIError_NoError => data at *data. */
static int tracer_GetCPReg(RDI_ModuleDesc *mdesc,
                           unsigned32 CPnum,
                           unsigned32 mask,
                           unsigned32 *data)
{
    return mdesc->rdi->CPread(mdesc->handle, CPnum, mask, data);
}

/* Return True if words are not the same .*/
static bool tracer_word_diff(uint32 *old, uint32 *new, unsigned numwords)
{
    while (numwords--)
    {
        if (*old++ != *new++)
            return TRUE;
    }
    return FALSE;
}

/**/
static void traceRegsAsText(TracerState *ts)
{
    if (ts->prop & TRACE_REGISTER) {
        void *f=ts->output.handle;
        Tracer_PrintfProc *tprintf = ts->output.tprintf;
        /* Tracer_PutSProc *tputs = ts->output.puts; */
        /* Tracer_PutCProc *tputc = ts->output.putc; */

        char nextchar = '\n';
        int regnum;
        unsigned32 regvalue;
        /* We miss out r15 because it's not useful, and is displayed
         * differently between 9 and 10 */
        for (regnum=0; regnum<16-1; regnum++) {
            regvalue=ARMulif_GetReg(&ts->coredesc, CURRENTMODE ,regnum);
            if (regvalue != ts->mainregister[regnum]) {
                if (nextchar == '\n') tprintf(f,"R ");
                else tprintf(f,", ");
                tprintf(f, "r%d=%08lx", regnum, regvalue);
                nextchar = ',';
                ts->mainregister[regnum] = regvalue;
            }
        }
        
        regvalue=ARMulif_GetCPSR(&ts->coredesc);
        if (regvalue != ts->cpsrregister) {
            if (nextchar == '\n') tprintf(f,"R ");
            else tprintf(f,", ");
            tprintf(f, "cpsr=%08lx", regvalue);
            nextchar = ',';
            ts->cpsrregister = regvalue;
        }

        regvalue=ARMulif_GetSPSR(&ts->coredesc,CURRENTMODE);
        if (regvalue != ts->spsrregister) {
            if (nextchar == '\n') tprintf(f,"R ");
            else tprintf(f,", ");
            tprintf(f, "spsr=%08lx", regvalue);
            nextchar = ',';
            ts->spsrregister = regvalue;
        }


        if (nextchar==',') Tracer_newline(ts);
    }

    if (CVector_Count(&ts->cpregs)) {
        void *f=ts->output.handle;
        Tracer_PrintfProc *tprintf = ts->output.tprintf;
        char nextchar = '\n';
        unsigned i;
        /* We miss out r15 because the information is provided elsewhere, 
         *  and is displayed
         * differently between 9 and 10 */
        for (i=0; i < CVector_Count(&ts->cpregs); i++) {
            struct CPregTrace *cpr = CVector_At(&ts->cpregs,i);
            int err = tracer_GetCPReg(&ts->coredesc, cpr->cpnum, cpr->mask,
                                      cpr->new);/* data */
            if (err == RDIError_NoError && cpr->numwords > 0 &&
                tracer_word_diff(cpr->old,cpr->new,cpr->numwords))
            {
                if (nextchar == '\n') tprintf(f,"RCP ");
                else tprintf(f,", ");
                tprintf(f, "p%dc%d=0x%08lx", cpr->cpnum, cpr->reg,
                        cpr->new[0]);
                {unsigned j;
                for (j=1; j< cpr->numwords; j++)
                    tprintf(f, "_%08lx", cpr->new[j]);
                }
                nextchar = ',';
                {void *temp = cpr->old;
                 cpr->old=cpr->new; cpr->new=temp;
                }
            }
        }
        if (nextchar==',') Tracer_newline(ts);
    }
}


static void Tracer_Dispatch(ATracer *as, Trace_Packet *packet)
{
  TracerState *ts = as->ts;
  void *f=ts->output.handle;
  if (ts->prop & TRACE_TEXT) {
    Tracer_PrintfProc *tprintf = ts->output.tprintf;
    Tracer_PutSProc *tputs = ts->output.puts;
    Tracer_PutCProc *tputc = ts->output.putc;

    if (ts->prop & TRACE_TIMESTAMP)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -