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

📄 tracer.c

📁 realview22.rar
💻 C
📖 第 1 页 / 共 5 页
字号:
    {
        /* !Todo: Allow the user to choose. */
#if 0
        ARMTime t1 = ARMulif_Time(&ts->coredesc);
#else
        ARMTime t1 = ARMulif_CoreCycles(&ts->coredesc);
#endif
        if (t1 != ts->LastTime)
        {
            tprintf(f,"T %08lX  ", (unsigned long)t1);
            ts->LastTime = t1;
        }
        else
            tprintf(f,"            ");
    }

    if (ts->prop & TRACE_ARCH)
        switch (packet->type) {
        case Trace_Instr:
        /* if doing instruction trace, check if conditional. If conditional, do expression eval first */
            /* ID of instruction access is "I[A|T|J][P|F]". */
        {
            uint32 result;
            char id[4];
            static char const iset2char[4]="ATJX";
            id[0]='I';
            id[1]=iset2char[packet->u.instr.iset];
            id[2]=(char)(packet->u.instr.executed ? 'P' : 'F');
            id[3]='\0';
            if ((strlen(ts->condexpr) != 0) && (ts->condexpr != NULL))
            {
                result = Expr1_EvalUint32(ts->parsedexpr,packet);
                if (result) 
                {
                    Hostif_ConsolePrint(ts->hostif,"Doing Trace, result (ARCH) = %d, instr:%08x, pc:%08x\n",result,packet->u.instr.instr, packet->u.instr.pc);
                    TraceAccess(ts,id,packet->u.instr.pc,
                                packet->u.instr.instr,
                                UNKNOWN_REG /* DESTReg not applicable */, packet);
                    /* Registers are handy! */
                    traceRegsAsText(ts);
                }
            } 
            else   /*if no condition, do trace anyway */ 
            {
                TraceAccess(ts,id,packet->u.instr.pc,
                                packet->u.instr.instr,
                                UNKNOWN_REG /* DESTReg not applicable */, packet);
                    /* Registers are handy! */
                traceRegsAsText(ts);    
            }
            return;
        }
        
        case Trace_BusAccess:
        case Trace_MemAccess:
            /* ID of memory access is "M[R|W][1|2|4]" */
        {
            char id[4];
            ARMul_acc acc=packet->u.mem_access.acc;
            int rv=packet->u.mem_access.rv;
            int width=1 << (acc & 15);
            assert(rv != 0);
            
            id[0]='M';
            id[1]=(char)(acc_READ(acc) ? 'R' : 'W');
            id[2]=(char)('0' + ((width > 32) ? 4 : (width / 8)));
            id[3]='\0';
            
            if (rv < 0 && (acc_CYCLE(acc) != acc_typeI)) {
                id[0] = 'X';
            }
            TraceAccess(ts,id,packet->u.mem_access.addr,
                        packet->u.mem_access.word1,
                        UNKNOWN_REG /* DESTReg unknown */, packet);
            if (width > 32)
                TraceAccess(ts,id,packet->u.mem_access.addr+4,
                            packet->u.mem_access.word2,
                            UNKNOWN_REG /* DESTReg unknown */, packet);
        }
        default: return;
        }
    else /* not TRACE_ARCH */
    switch (packet->type) 
    {
    case Trace_Instr: {
/* true means do instr trace, flase means don't */
      bool flag = TRUE;
      uint32 result=0;
      char buffer[256];
      ARMword instr=packet->u.instr.instr,pc=packet->u.instr.pc;
      unsigned executed=packet->u.instr.executed;

/* need conditional loop around whole case execution. If condition exists, check before debug,
   if not set, trace anyway. Initially do this with a flag set depending on the condition eval.
   More elegant would be to encapsulate the trace in a function. */

/* check the condition, set flag */
        if ((strlen(ts->condexpr) != 0) && (ts->condexpr != NULL))
        {
            result = Expr1_EvalUint32(ts->parsedexpr,packet);
            if (result) 
            {
                Hostif_ConsolePrint(ts->hostif,"Doing Trace, result = %d, instr:%08x\n",result, packet->u.instr.instr);
                flag = TRUE;
            } 
            else 
            {  /* result != expression, don't do trace */
                flag = FALSE;
            }
        } 
        else   /*if no condition, do trace anyway */ 
        {
            flag = TRUE;
        }

/* flag now set, do instr trace if it's set. */

        if (flag)
        {
          /* T for Taken, S for Skipped, J for Java. */
          tprintf(f,"I%c %08lX ", executed ?
                  ((packet->u.instr.iset==ISET_JAVA)?'J':'T') : 'S', pc);
          switch(packet->u.instr.iset)
          {
              case ISET_THUMB:
                  if(instr & 0xffff0000)
                      tprintf(f,"%08lx",instr);
                  else
                      tprintf(f, "%04lx", instr);
                  break;
              case ISET_JAVA:
              {    /* Kill the high bytes */
                  unsigned extrabytes = (instr >> 12) & 3; /* 0,1,2 */
                  static uint32 masks[4] = 
                      { 0x00000FFF, 0x00FF0FFF, 0xFFFF0FFF, 0xFFFF0FFF };
                  instr &= masks[extrabytes];
              }
              default:
                  tprintf(f, "%08lx", instr);
                  break;
          }

          if (ts->prop & TRACE_DISASS) {
            tracer_disass(ts, packet, instr, pc, buffer);
            if (!executed) {
              char *p;
              for (p=buffer; *p; p++)
                if (isupper((int)*p)) *p=(char)tolower((int)*p);
            }
            tputc(' ', f);
            tputs(buffer, f);
          }
          Tracer_newline(ts);
          traceRegsAsText(ts);
          }
        } /*end flag */
      break;

    case Trace_BusAccess:
    case Trace_MemAccess:
    {
      ARMul_acc acc=packet->u.mem_access.acc;
      unsigned32 addr=packet->u.mem_access.addr;
      int rv=packet->u.mem_access.rv;
      int width;

      /* all mem_access packets sent are to be displayed */
      width=Tracer_Acc(as, acc, addr,packet->type); /* prints "M" etc */

      if (acc_CYCLE(acc) != acc_typeI /* includes acc_Icycle */) {
        if (rv != 0) {
          tprintf(f," %0*.*lX", width, width, packet->u.mem_access.word1);
          if (acc_WIDTH(acc)==BITS_64)
            tprintf(f," %08lX", packet->u.mem_access.word2);
        }
      }
      if (rv < 0) {
        tputs(" (abort)", f);
      } else if (rv == 0) {
        tputs(" (wait)", f);
      }
      if (!acc_ACCOUNT(acc)) {
        /* display non-accounted accesses */
        if (acc_MREQ(acc))
          tprintf(f, acc_READ(acc) ? " (peek)" : " (poke)");
      }

      Tracer_newline(ts);
    }
    break;

    case Trace_Event: {
        char const *eventname = (packet->u.event.type >= SignalEvent_RESET &&
            packet->u.event.type <= SignalEvent_Stop) ?
            eventSignalNames[packet->u.event.type - SignalEvent_RESET] : "";
        char const * title = "";
        if (packet->u.event.type >= CoreEvent_Reset &&
            packet->u.event.type <= CoreEvent_Watchpoint)
        {
            eventname = 
                eventSignalNames[packet->u.event.type - CoreEvent_Reset];
            title = "Core ";
        }

        tprintf(f,"E %08lX %08lX %x %s%s",
              packet->u.event.addr,packet->u.event.addr2,
              packet->u.event.type, title, eventname);
        Tracer_newline(ts);
        break;
        }
    }
  } else {
    Tracer_WriteProc *twrite = ts->output.write;
    twrite(packet,sizeof(*packet),1,f);
    fflush(f);
  }
}

/*
 * Veneers onto DebugPrint
 */
static int DebugPutS(const char *s, void *handle)
{
  RDI_HostosInterface *hostif = (RDI_HostosInterface *)handle;
  Hostif_DebugPrint(hostif, "%s", s);
  return 0;
}

static int DebugPutC(char c, void *handle)
{
  RDI_HostosInterface *hostif = (RDI_HostosInterface *)handle;
  Hostif_DebugPrint(hostif, "%c", c);
  return 0;
}

   
/*
 * Open the trace stream.
 * Returns 1 on failure.
 */

static int Banner(TracerState *ts)
{    
  time_t now=time(NULL);
  void *f=ts->output.handle;
  Tracer_PrintfProc *tprintf = ts->output.tprintf;
  Tracer_PutSProc *tputs = ts->output.puts;
  Tracer_PutCProc *tputc = ts->output.putc;

  tprintf(f, "Date: %s", ctime(&now));
  tprintf(f, "Source: Armul");
  Tracer_newline(ts);
  tputs("Options: ", f);

  if (ts->prop & TRACE_INSTR) {
    char nextch = '(';
    tputs("Trace Instructions  ", f);

    if (ts->prop & TRACE_DISASS) {
      tputc(nextch, f);
      tputs("Disassemble", f);
      nextch = ',';
    }
    if (ts->prop & TRACE_REGISTER) {
      tputc(nextch, f);
      tputs("Registers", f);
      nextch = ',';
    }
    if (nextch != '(')
      tputs(")  ", f);
  }   
   
  if (ts->prop & TRACE_MEM) {
    char nextch = '(';
    tputs("Trace Memory Cycles  ", f);
    if (ts->prop & TRACE_IDLE) {
      tputc(nextch, f);
      tputs("Idles", f);
      nextch = ',';
    }
    if (ts->prop & TRACE_NONACC) {
      tputc(nextch, f);
      tputs("Non-accounted", f);
      nextch = ',';
    }
    if (ts->prop & TRACE_WAITS) {
      tputc(nextch, f);
      tputs("Waits", f);
      nextch = ',';
    }
    if (nextch != '(')
      tputs(")  ", f);
  }
  if (ts->prop & TRACE_EVENT)  tputs("Trace Events  ", f);
  Tracer_newline(ts);
  if (ts->prop & TRACE_RANGE)
  {
    tprintf(f, "Range: 0x%08lX -> 0x%08lX",
            ts->range_lo, ts->range_hi);
    Tracer_newline(ts);
  }
  if (ts->sample_base)
  {
    tprintf(f, "Sample: %ld", ts->sample_base);
    Tracer_newline(ts);
  }
  Tracer_newline(ts);
  return 0;
}

/* Returns 0:Ok, else error. */
static unsigned Tracer_Open(TracerState *ts)
{
  const char *option;
  unsigned verbose;

  verbose=ts->prop & TRACE_VERBOSE;

  if (ToolConf_DLookupBool(ts->config, ARMulCnf_RDILog, FALSE)) {
    /* output to the rdi_log window */
    /* talk directly, rather than via DebugPrint, as it should be faster,
     * and DebugPrint checks rdi_log bit 1
     */
      union { void const *c; void *v; } u;
      u.c = ts->hostif;
      ts->output.handle = u.v;
    ts->output.tprintf = (Tracer_PrintfProc *)Hostif_DebugPrint;
    ts->output.puts = DebugPutS;
    ts->output.putc = DebugPutC;
    ts->prop|=TRACE_TEXT;

    return Banner(ts);
  }

  option=ToolConf_Lookup(ts->config, ARMulCnf_File);
  if (option!=NULL && option[0]) {
    FILE *f = fopen(option,"w");
    if (f == NULL) {
      fprintf(stderr,"Could not open trace file '%s' - abandoning trace.\n",
              option);
      return 1;
    }
    ts->output.handle = f;
    ts->output.tprintf = (Tracer_PrintfProc *)fprintf;
    ts->output.puts = (Tracer_PutSProc *)fputs;
    ts->output.putc = (Tracer_PutCProc *)fputc;
    ts->output.close = (Tracer_CloseProc *)fclose;
    ts->output.flush = (Tracer_FlushProc *)fflush;

    ts->prop|=TRACE_TEXT;

    return Banner(ts);
  }

  option=ToolConf_Lookup(ts->config, ARMulCnf_BinFile);
  if (option!=NULL && option[0]) {
    FILE *f = fopen(option,"wb");
    if (f == NULL) {
      fprintf(stderr,"Could not open trace file '%s' - abandoning trace.\n",
              option);
      return 1;
    }
    ts->output.handle = f;
    ts->output.write = (Tracer_WriteProc *)fwrite;
    ts->output.close = (Tracer_CloseProc *)fclose;
    ts->output.flush = (Tracer_FlushProc *)fflush;
    return 0;
  }

#ifdef SOCKETS
  option=ToolConf_Lookup(ts->config, ARMulCnf_Port);
  if (option) {
    long port;
      
    port=strtol(option,NULL,0);

    option=ToolConf_Lookup(ts->config, ARMulCnf_Host);

    if (option) {
      struct hostent *host;
      struct sockaddr_in con;
      int sock;
      
      host=gethostbyname(option);

      if (host==NULL) {
        Hostif_ConsolePrint(ts->hostif,"Could not resolve host '%s'\n",
                           option);
        return 1;
      }
        
      if (verbose)
        Hostif_ConsolePrint(ts->hostif,"Tracing to %s:%d\n",option,port);

      sock=socket(AF_INET,SOCK_STREAM,0);
      if (sock==-1) {
        Hostif_ConsolePrint(ts->hostif,"Could not open trace port\n");
        return 1;
      }
        
      memset(&con,'\0',sizeof(con));
      con.sin_family=AF_INET;
      memcpy(&con.sin_addr,host->h_addr,sizeof(con.sin_addr));
      con.sin_port=htons(port & 0xffff);
        
      if (connect(sock,(struct sockaddr *)&con, sizeof(con))!=0) {
        close(sock);
        Hostif_ConsolePrint(ts->hostif,"Failed to open socket\n");
        return 1;
      }

      ts->output.handle=(void *)fdopen(sock,"wb");
      if (ts->output.handle!=NULL) return 0;
      ts->output.write = (Tracer_WriteProc *)fwrite;
      ts->output.close = (Tracer_CloseProc *)fclose;
      ts->output.flush = (Tracer_FlushProc *)fflush;

      Hostif_ConsolePrint(ts->hostif,"Failed to fdopen socket.\n");
      return 1;
    }

    Hostif_ConsolePrint(ts->hostif,"PORT configured with no HOST.\n");
    return 1;
  }
#endif

#ifdef PIPE

⌨️ 快捷键说明

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