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

📄 tracer.c

📁 realview22.rar
💻 C
📖 第 1 页 / 共 5 页
字号:
/* tracer.c - module to trace memory accesses and instruction execution
 *            in ARMulator.
 * Copyright (c) 1996-1998 Advanced RISC Machines Limited. All Rights Reserved.
 * Copyright (c) 1998-1999  ARM Limited. All Rights Reserved.
 *
 * RCS $Revision: 1.11.2.31.2.6 $
 * Checkin $Date: 2004/10/25 15:27:43 $
 * Revising $Author: clamb $
 */

#define MODEL_NAME Tracer

#include <stdio.h>
#include <time.h>
#include <ctype.h>
#include <string.h>       /* for strcpy */
#include "hash.h"

/* needed for Conditional Instr evaluate */
#include "cvector.h"

#include "armul_cnf.h"

#include "minperip.h"
#include "rdi_prop.h"    /* for RDIProperty_GetAsNumeric */
#include "armul_callbackid.h"
#define JAVA_EXT_MASK 0x1FF

#include "javadis.h"     /* for disass_java */
#include "armjimm.h"     /* for java internals */
#include "disass.h"
#ifdef ETRACE
#include "rdi_rti.h"
#endif

#ifdef SOCKETS
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#endif


#include "armul_mem.h"


#ifndef NDEBUG
# if 1
# else
#  define VERBOSE_INIT_CPREG_TRACE
#  define VERBOSE_BUS
#  define VERBOSE_RDI_LOG
# endif
#endif

typedef uint8 byte;


#define stringify1(x) #x
#define stringify(x) stringify1(x)



#define CURRENTMODE RDIMode_Curr


/* from armcnf.h */
#define ARMulCnf_TraceInstructions (tag_t)"TRACEINSTRUCTIONS"
#define ARMulCnf_TraceMemory (tag_t)"TRACEMEMORY"
#define ARMulCnf_TraceIdle (tag_t)"TRACEIDLE"
#define ARMulCnf_TraceNonAcc (tag_t)"TRACENONACCOUNTED"
#define ARMulCnf_TraceWaits (tag_t)"TRACEWAITS"
#define ARMulCnf_TraceEvents (tag_t)"TRACEEVENTS"
#define ARMulCnf_TraceRegisters (tag_t)"TRACEREGISTERS"
#define ARMulCnf_Disassemble (tag_t)"DISASSEMBLE"
#define ARMulCnf_Unbuffered (tag_t)"UNBUFFERED"
#define ARMulCnf_StartOn (tag_t)"STARTON"
#define ARMulCnf_File (tag_t)"FILE"
#define ARMulCnf_BinFile (tag_t)"BINFILE"
#define ARMulCnf_Port (tag_t)"PORT"
#define ARMulCnf_Host (tag_t)"HOST"
#define ARMulCnf_Pipe (tag_t)"PIPE"
#define ARMulCnf_EventMask (tag_t)"EVENTMASK"
#define ARMulCnf_Event (tag_t)"EVENT"
#define ARMulCnf_Range (tag_t)"RANGE"
#define ARMulCnf_Sample (tag_t)"SAMPLE"
#define ARMulCnf_TraceBus (tag_t)"TRACEBUS"
#define ARMulCnf_RDILog (tag_t)"RDILOG"
#define ARMulCnf_TimeStamp (tag_t)"TIMESTAMP"
#define ARMulCnf_OpcodeFetch (tag_t)"OPCODEFETCH"
#define ARMulCnf_Arch (tag_t)"TRACEEIS"
#define ARMulCnf_AccessHit (tag_t)"TRACEHITTYPE"
#define ARMulCnf_TraceJazelleFakeOpcodes (tag_t)"TRACE_JAZELLEFAKEOPCODES"
#define ARMulCnf_TraceInstrIf (tag_t)"TRACEINSTRIF"

/* --- used to be in tracer.h --- */

#define TRACE_INSTR      0x00000001
#define TRACE_MEM        0x00000002
#define TRACE_IDLE       0x00000004
#define TRACE_RANGE      0x00000008
#define TRACE_PIPE       0x00000010     /* use pclose to close */
#define TRACE_TEXT       0x00000020     /* stream is plain text */
#define TRACE_EVENT      0x00000040
#define TRACE_DISASS     0x00000080     /* disassemble instruction stream */
#define TRACE_BUS        0x00000100     /* trace at the bus/core */
#define TRACE_NONACC     0x00000200     /* trace non-accounted accesses */
#define TRACE_WAITS      0x00000400     /* show wait states returned */
#define TRACE_REGISTER   0x00000800     /* trace changes to register values */  
#define TRACE_UNBUFF     0x00001000     /* unbuffered stream output */  
/* !Todo: Allow timestamps of CoreCycles. */
#define TRACE_TIMESTAMP  0x00002000     /* prepend time-stamps. */
#define TRACE_OPCODEFETCH 0x00004000    /* Trace opcode fetches. */
#define TRACE_ARCH       0x00008000     /* "Architectural" trace */
#define TRACE_ACCESSHIT  0x00010000
#define TRACE_JAZELLEFAKEOPCODES 0x00020000
/* used for boolean lookup. Instead need to copy something like binfile which passes in a parameter */

#define TRACE_STARTON    0x80000000     /* tracing always on */
#define TRACE_VERBOSE    0x40000000

/* type of data stored in DataItem 
  This can be added to, but will need additional code elsewhere
  It is linked directly to structs in the tracer code eg packet->instr, packet->pc etc
*/
enum DataItemType {
    Value,
    Instruction,
    PC
};


/* Functions for standard "dispatch" */
typedef int Tracer_PrintfProc(void *handle, const char *format, ...);
typedef int Tracer_PutSProc(const char *string, void *handle);
typedef int Tracer_PutCProc(char c, void *handle);
typedef int Tracer_WriteProc(void *packet, int size, int n, void *handle);
typedef int Tracer_CloseProc(void *handle);
typedef int Tracer_FlushProc(void *handle);

/* A record describing one coprocessor-register being traced. */
struct CPregTrace {
    unsigned32 mask; /* for asking the core */
    unsigned reg, cpnum;
    unsigned numwords;
    ARMword *old, *new;
};

/* Conditional Execution Trace structures */

typedef struct TExpr1 *Expr1;

typedef struct {
  unsigned32 addr;
  ARMul_acc acc;
} Tracer_Pipeline;

enum EPacketType {
    Trace_Instr,                /* instruction execution */
    Trace_MemAccess,            /* memory cycles, includes idles */
    Trace_BusAccess,
    Trace_Event                 /* other misc events */
};

/* datatype used to track the kind of instruction stored. Eg Value (ie a real number),
   Instruction, Program Counter. These allow the current instr or pc to be substituted
   at run time */
typedef struct {
    uint32 u32;
    enum DataItemType Datatype;
    void *v;
} Expr1DataItem;

enum INSTR_SET { ISET_ARM, ISET_THUMB, ISET_JAVA };

typedef struct {
  enum EPacketType type;
  union {
    struct {
      unsigned32 instr;
      unsigned32 pc;
      unsigned8 executed;       /* 1 if executed, 0 otherwise */
      enum INSTR_SET iset;
    } instr;
    struct {
      ARMul_acc acc;
      unsigned32 addr;
      unsigned32 word1,word2;
      int rv;                   /* return value from mem_access call */
      Tracer_Pipeline predict;
    } mem_access;
    struct {
      unsigned32 addr,addr2;
      unsigned int type;        /* see note in armdefs.h */
    } event;
  } u;
} Trace_Packet;

typedef void Expr1Func(Expr1, Expr1DataItem *, Trace_Packet *);

typedef struct {
    char const *name;
    int lpri,rpri;
    Expr1Func *func;
    Expr1DataItem data;
} Expr1Ident;

static Expr1Func push_u32_const_func;   /*(Expr1 e1, Expr1DataItem * data);*/
static Expr1Func push_instr_const_func; /*(Expr1 e1);*/
static Expr1Func push_pc_const_func;    /*(Expr1 e1);*/

static Expr1Ident NumericConstantID = 
{
    "#U32#", 0,0, push_u32_const_func, { 0, Value }
};

static Expr1Ident NumericConstantInstr = 
{
    "Instr", 0,0, push_instr_const_func, { 0, Instruction }
};

static Expr1Ident NumericConstantPC = 
{
    "PC", 0,0, push_pc_const_func, { 0, PC }
};


typedef struct {
    Expr1Func *func;
    Expr1DataItem data;
        char const *name; /* DEBUG_ONLY*/
} Expr1Codon;

struct TExpr1 {
    CVector idents;
    CVector code;
    CVector dataStack;
    CVector parseStack;
} TExpr1;


/* We have one of these per MemInterface we trace on. */
typedef struct ATracer {
    struct TracerState *ts;

  /* Pipeline prediction checking */
  Tracer_Pipeline current, advance;
  Tracer_Pipeline dside_current, dside_advance;
  Tracer_Pipeline iside_current, iside_advance;

  unsigned32 memfeatures;       /* features when displaying mem cycles */

  ARMul_MemInterface bus_mem, child;
  ARMul_MemInterfaceRef mem_ref;
  enum EPacketType packet_type;
    /* This one is 'const'. */
  enum EPacketType as_TraceType;

    /* For async2 memory-types */
  int armiss_err;

    /* For tracing times on an ARMul_Bus */
  ARMul_Bus *p_ABus;

} ATracer;

typedef struct
{
    uint32 eventnum;
/*    void *killhandle; */
    char const *name;
} TSEventNumberRecord;


BEGIN_STATE_DECL(Tracer)
  unsigned int not_tracing;     /* zero when RDILog_Trace is set */
  unsigned int trace_opened;    /* set to one once Tracer_Open called */
  struct {
    void *handle;               /* usually a FILE * */
    Tracer_PrintfProc *tprintf;  /* fprintf -- ANSI C says we can't use symbol printf here */
    Tracer_PutSProc *puts;      /* fputs */
    Tracer_PutCProc *putc;      /* fputc */
    Tracer_WriteProc *write;    /* fwrite */
    Tracer_CloseProc *close;    /* fclose */
    Tracer_FlushProc *flush;    /* fflush */
  } output;
  unsigned32 prop;
  uint32 initial_rdi_log;

  char condexpr[512];
/* stores the parsed expression for evaluation at run time */
  Expr1 parsedexpr;

  ATracer Core_Tracer, Bus_Tracer;

  unsigned32 prev_instr;        /* Thumb 2-instr BL disassembly */
  ARMword range_lo,range_hi;
  unsigned long sample,sample_base;
  unsigned int event_mask,event_set; /* masks for events */
  void *hourglass_kh,*trace_event_kh; /* handles for ARMulator callbacks */

  unsigned32 mainregister[16];
  unsigned32 cpsrregister, spsrregister;

  void *memcallback;  /* so we can deregister it */
  ARMTime LastTime;
  unsigned line_number;
  unsigned break_line;
  CVector cpregs; /* For traceing coprocessor-registers. */
  CVector ts_EventNumbers; /* of TSEventNumberRecord*/
  HashTable *ts_EventNumHash;
  uint32 ts_EventNumClasses;
  void *ts_numberredEvent_kh;

  bool_int ts_TraceJavaFakeCycles;

END_STATE_DECL(Tracer)

#define TRACE_MEMFEATURE_AMBA          0x1    /* use AMBA mnemonics */
#define TRACE_MEMFEATURE_PIPELINED     0x2    /* check next cycle info */




static struct {
  tag_t option;
  unsigned long flag;
  char *print;
} TraceOption[] = {
 {   ARMulCnf_TraceInstructions, TRACE_INSTR,    "Instructions"},
 {   ARMulCnf_TraceMemory,       TRACE_MEM,      "Memory accesses"},
 {   ARMulCnf_TraceIdle,         TRACE_IDLE,     "Idle cycles"},
 {   ARMulCnf_TraceEvents,       TRACE_EVENT,    "Events"},
 {   ARMulCnf_Disassemble,       TRACE_DISASS,   "Disassemble"},
 {   ARMulCnf_Unbuffered,        TRACE_UNBUFF,   "Unbuffered"},
 {   ARMulCnf_StartOn,           TRACE_STARTON,  "Start on"},
 {   ARMulCnf_TraceBus,          TRACE_BUS,      "Trace bus"},
 {   ARMulCnf_TraceNonAcc,       TRACE_NONACC,   "Non-accounted"},
 {   ARMulCnf_TraceWaits,        TRACE_WAITS,    "Waits"},
 {   ARMulCnf_TraceRegisters,    TRACE_REGISTER, "Trace registers"},
 {   ARMulCnf_TimeStamp,         TRACE_TIMESTAMP, "TimeStamp"},
 {   ARMulCnf_OpcodeFetch,       TRACE_OPCODEFETCH,"Opcode Fetch"},
 {   ARMulCnf_Arch,              TRACE_ARCH,      "EIS-format"},
 {   ARMulCnf_AccessHit,         TRACE_ACCESSHIT, "Hit-type"},
 {   ARMulCnf_TraceJazelleFakeOpcodes, TRACE_JAZELLEFAKEOPCODES, "Jazelle-FakeOps"},
 {   NULL, 0, NULL}
};

/* other option fields */


/* Condition Instruction Trace Functions */

Expr1 Expr1_ParseString(char const *txt, char *errbuf, size_t errbuf_size);

Expr1 Expr1_AddVariableUint32(Expr1 e1, char const *name, uint32 *addr);

uint32 Expr1_EvalUint32(Expr1 e1, Trace_Packet *packet);

void Expr1_Destroy(Expr1 *p_e1);

static Expr1 Expr1_New(void)
{
    Expr1 e1 = (Expr1) calloc(1,sizeof(TExpr1));
    if (e1)
    {
        CVector_Init(&e1->idents, sizeof(Expr1Ident));
        CVector_Init(&e1->code, sizeof(Expr1Codon));
        CVector_Init(&e1->dataStack, sizeof(Expr1DataItem));
        CVector_Init(&e1->parseStack, sizeof(Expr1Ident));
    }
    return e1;
}

static void push_uint32(Expr1 e1, uint32 v)
{
    int retval;
    Expr1DataItem d;
    d.Datatype = Value;
    d.u32 = v;
    retval = CVector_Append(&e1->dataStack,&d);
}

static void push_instr(Expr1 e1)
{
    int retval;
    Expr1DataItem d;
    d.u32 = 0;
    d.Datatype = Instruction;
    retval = CVector_Append(&e1->dataStack,&d);
}

static void push_pc(Expr1 e1)
{
    int retval;
    Expr1DataItem d;
    d.u32 = 0;
    d.Datatype = PC;
    retval = CVector_Append(&e1->dataStack,&d);
}

static uint32 pop_uint32(Expr1 e1, Trace_Packet *packet)
{
    Expr1DataItem d;
        assert(CVector_Count(&e1->dataStack) > 0);
    (void)CVector_Pop(&e1->dataStack,&d);
    if (d.Datatype == Value){
#ifdef VERBOSE
        printf("VALUE: %08x\n",(unsigned)d.u32);
#endif
       return d.u32;
    }
    else if (d.Datatype == Instruction)
    { 
#ifdef VERBOSE
        printf("INSTR: %08x\n",(unsigned)packet->u.instr.instr);
#endif
        return packet->u.instr.instr;
    }
    else if (d.Datatype == PC) 
    {
#ifdef VERBOSE
        printf("PC: %08x\n",(unsigned)packet->u.instr.pc);
#endif
        return packet->u.instr.pc; 
    } 

⌨️ 快捷键说明

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