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

📄 sim-trace.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
    for (i = 0; i < MAX_NR_PROCESSORS; ++i)      {	sim_cpu *cpu = STATE_CPU (sd, i);	if (ADDR_RANGE_RANGES (TRACE_RANGE (CPU_TRACE_DATA (cpu)))	    && ! TRACE_INSN_P (cpu))	  {	    sim_io_eprintf_cpu (cpu, "Tracing address range specified without --trace-insn.\n");	    sim_io_eprintf_cpu (cpu, "Address range ignored.\n");	    sim_addr_range_delete (TRACE_RANGE (CPU_TRACE_DATA (cpu)),				   0, ~ (address_word) 0);	  }      }  }#endif  return SIM_RC_OK;}static voidtrace_uninstall (SIM_DESC sd){  int i,j;  FILE *sfile = TRACE_FILE (STATE_TRACE_DATA (sd));  if (sfile != NULL)    fclose (sfile);  for (i = 0; i < MAX_NR_PROCESSORS; ++i)    {      FILE *cfile = TRACE_FILE (CPU_TRACE_DATA (STATE_CPU (sd, i)));      if (cfile != NULL && cfile != sfile)	{	  /* If output from different cpus is going to the same file,	     avoid closing the file twice.  */	  for (j = 0; j < i; ++j)	    if (TRACE_FILE (CPU_TRACE_DATA (STATE_CPU (sd, j))) == cfile)	      break;	  if (i == j)	    fclose (cfile);	}    }}typedef enum {  trace_fmt_invalid,  trace_fmt_word,  trace_fmt_fp,  trace_fmt_fpu,  trace_fmt_string,  trace_fmt_bool,  trace_fmt_addr,  trace_fmt_instruction_incomplete,} data_fmt;/* compute the nr of trace data units consumed by data */static intsave_data_size (TRACE_DATA *data,		long size){  return ((size + sizeof (TRACE_INPUT_DATA (data) [0]) - 1)	  / sizeof (TRACE_INPUT_DATA (data) [0]));}/* Archive DATA into the trace buffer */static voidsave_data (SIM_DESC sd,	   TRACE_DATA *data,	   data_fmt fmt,	   long size,	   void *buf){  int i = TRACE_INPUT_IDX (data);  if (i == sizeof (TRACE_INPUT_FMT (data)))    sim_io_error (sd, "trace buffer overflow");  TRACE_INPUT_FMT (data) [i] = fmt;  TRACE_INPUT_SIZE (data) [i] = size;  memcpy (&TRACE_INPUT_DATA (data) [i], buf, size);  i += save_data_size (data, size);  TRACE_INPUT_IDX (data) = i;}static voidprint_data (SIM_DESC sd,	    sim_cpu *cpu,	    data_fmt fmt,	    long size,	    void *data){  switch (fmt)    {    case trace_fmt_instruction_incomplete:      trace_printf (sd, cpu, " (instruction incomplete)");      break;    case trace_fmt_word:    case trace_fmt_addr:      {	switch (size)	  {	  case sizeof (unsigned32):	    trace_printf (sd, cpu, " 0x%08lx", (long) * (unsigned32*) data);	    break;	  case sizeof (unsigned64):	    trace_printf (sd, cpu, " 0x%08lx%08lx",			  (long) ((* (unsigned64*) data) >> 32),			  (long) * (unsigned64*) data);	    break;	  default:	    abort ();	  }	break;      }    case trace_fmt_bool:      {	SIM_ASSERT (size == sizeof (int));	trace_printf (sd, cpu, " %-8s",		      (* (int*) data) ? "true" : "false");	break;      }    case trace_fmt_fp:      {	sim_fpu fp;	switch (size)	  {	    /* FIXME: Assumes sizeof float == 4; sizeof double == 8 */	  case 4:	    sim_fpu_32to (&fp, *(unsigned32*)data);	    break;	  case 8:	    sim_fpu_64to (&fp, *(unsigned64*)data);	    break;	  default:	    abort ();	  }	trace_printf (sd, cpu, " %8g", sim_fpu_2d (&fp));	switch (size)	  {	  case 4:	    trace_printf (sd, cpu, " (0x%08lx)",			  (long) *(unsigned32*)data);	    break;	  case 8:	    trace_printf (sd, cpu, " (0x%08lx%08lx)",			  (long) (*(unsigned64*)data >> 32),			  (long) (*(unsigned64*)data));	    break;	  default:	    abort ();	  }	break;      }    case trace_fmt_fpu:      /* FIXME: At present sim_fpu data is stored as a double */      trace_printf (sd, cpu, " %8g", * (double*) data);      break;    case trace_fmt_string:      trace_printf (sd, cpu, " %-8s", (char*) data);      break;    default:      abort ();    }}		  static const char *trace_idx_to_str (int trace_idx){  static char num[8];  switch (trace_idx)    {    case TRACE_ALU_IDX:     return "alu:     ";    case TRACE_INSN_IDX:    return "insn:    ";    case TRACE_DECODE_IDX:  return "decode:  ";    case TRACE_EXTRACT_IDX: return "extract: ";    case TRACE_MEMORY_IDX:  return "memory:  ";    case TRACE_CORE_IDX:    return "core:    ";    case TRACE_EVENTS_IDX:  return "events:  ";    case TRACE_FPU_IDX:     return "fpu:     ";    case TRACE_BRANCH_IDX:  return "branch:  ";    case TRACE_VPU_IDX:     return "vpu:     ";    default:      sprintf (num, "?%d?", trace_idx);      return num;    }}static voidtrace_results (SIM_DESC sd,	       sim_cpu *cpu,	       int trace_idx,	       int last_input){  TRACE_DATA *data = CPU_TRACE_DATA (cpu);  int nr_out;  int i;  /* cross check trace_idx against TRACE_IDX (data)? */  /* prefix */  trace_printf (sd, cpu, "%s %s",		trace_idx_to_str (TRACE_IDX (data)),		TRACE_PREFIX (data));  TRACE_IDX (data) = 0;  for (i = 0, nr_out = 0;       i < TRACE_INPUT_IDX (data);       i += save_data_size (data, TRACE_INPUT_SIZE (data) [i]), nr_out++)    {      if (i == last_input)	{	  int pad = (strlen (" 0x") + sizeof (unsigned_word) * 2);	  int padding = pad * (3 - nr_out);	  if (padding < 0)	    padding = 0;	  padding += strlen (" ::");	  trace_printf (sd, cpu, "%*s", padding, " ::");	}      print_data (sd, cpu,		  TRACE_INPUT_FMT (data) [i],		  TRACE_INPUT_SIZE (data) [i],		  &TRACE_INPUT_DATA (data) [i]);    }  trace_printf (sd, cpu, "\n");}voidtrace_prefix (SIM_DESC sd,	      sim_cpu *cpu,	      sim_cia cia,	      address_word pc,	      int line_p,	      const char *filename,	      int linenum,	      const char *fmt,	      ...){  TRACE_DATA *data = CPU_TRACE_DATA (cpu);  va_list ap;  char *prefix = TRACE_PREFIX (data);  char *chp; /* FIXME: The TRACE_PREFIX_WIDTH should be determined at build time using    known information about the disassembled instructions. */#ifndef TRACE_PREFIX_WIDTH#define TRACE_PREFIX_WIDTH 48#endif  int width = TRACE_PREFIX_WIDTH;  /* if the previous trace data wasn't flushed, flush it now with a     note indicating that the trace was incomplete. */  if (TRACE_IDX (data) != 0)    {      int last_input = TRACE_INPUT_IDX (data);      save_data (sd, data, trace_fmt_instruction_incomplete, 1, "");      trace_results (sd, cpu, TRACE_IDX (data), last_input);    }  TRACE_IDX (data) = 0;  TRACE_INPUT_IDX (data) = 0;  /* Create the text prefix for this new instruction: */  if (!line_p)    {      if (filename)	{	  sprintf (prefix, "%s:%-*d 0x%.*lx ",		   filename,		   SIZE_LINE_NUMBER, linenum,		   SIZE_PC, (long) pc);	}      else	{	  sprintf (prefix, "0x%.*lx ",		   SIZE_PC, (long) pc);	  /* Shrink the width by the amount that we didn't print.  */	  width -= SIZE_LINE_NUMBER + SIZE_PC + 8;	}      chp = strchr (prefix, '\0');      va_start (ap, fmt);      vsprintf (chp, fmt, ap);      va_end (ap);    }  else    {      char buf[256];      buf[0] = 0;      if (STATE_TEXT_SECTION (CPU_STATE (cpu))	  && pc >= STATE_TEXT_START (CPU_STATE (cpu))	  && pc < STATE_TEXT_END (CPU_STATE (cpu)))	{	  const char *pc_filename = (const char *)0;	  const char *pc_function = (const char *)0;	  unsigned int pc_linenum = 0;	  bfd *abfd;	  asymbol **asymbols;	  abfd = STATE_PROG_BFD (CPU_STATE (cpu));	  asymbols = STATE_PROG_SYMS (CPU_STATE (cpu));	  if (asymbols == NULL)	    {	      long symsize;	      long symbol_count;	      symsize = bfd_get_symtab_upper_bound (abfd);	      if (symsize < 0)		{		  sim_engine_abort (sd, cpu, cia, "could not read symbols");		}	      asymbols = (asymbol **) xmalloc (symsize);	      symbol_count = bfd_canonicalize_symtab (abfd, asymbols);	      if (symbol_count < 0)		{		  sim_engine_abort (sd, cpu, cia, "could not canonicalize symbols");		}	      STATE_PROG_SYMS (CPU_STATE (cpu)) = asymbols;	    }	  if (bfd_find_nearest_line (abfd,				     STATE_TEXT_SECTION (CPU_STATE (cpu)),				     asymbols,				     pc - STATE_TEXT_START (CPU_STATE (cpu)),				     &pc_filename, &pc_function, &pc_linenum))	    {	      char *p = buf;	      if (pc_linenum)		{		  sprintf (p, "#%-*d ", SIZE_LINE_NUMBER, pc_linenum);		  p += strlen (p);		}	      else		{		  sprintf (p, "%-*s ", SIZE_LINE_NUMBER+1, "---");		  p += SIZE_LINE_NUMBER+2;		}	      if (pc_function)		{		  sprintf (p, "%s ", pc_function);		  p += strlen (p);		}	      else if (pc_filename)		{		  char *q = (char *) strrchr (pc_filename, '/');		  sprintf (p, "%s ", (q) ? q+1 : pc_filename);		  p += strlen (p);		}	      if (*p == ' ')		*p = '\0';	    }	}      sprintf (prefix, "0x%.*x %-*.*s ",	       SIZE_PC, (unsigned) pc,	       SIZE_LOCATION, SIZE_LOCATION, buf);      chp = strchr (prefix, '\0');      va_start (ap, fmt);      vsprintf (chp, fmt, ap);      va_end (ap);    }  /* Pad it out to TRACE_PREFIX_WIDTH.  */  chp = strchr (prefix, '\0');  if (chp - prefix < width)    {      memset (chp, ' ', width - (chp - prefix));      chp = &prefix [width];      *chp = '\0';    }  strcpy (chp, " -");  /* check that we've not over flowed the prefix buffer */  if (strlen (prefix) >= sizeof (TRACE_PREFIX (data)))    abort ();}voidtrace_generic (SIM_DESC sd,	       sim_cpu *cpu,	       int trace_idx,	       const char *fmt,	       ...){  va_list ap;  trace_printf (sd, cpu, "%s %s",		trace_idx_to_str (trace_idx),		TRACE_PREFIX (CPU_TRACE_DATA (cpu)));  va_start (ap, fmt);  trace_vprintf (sd, cpu, fmt, ap);  va_end (ap);  trace_printf (sd, cpu, "\n");}voidtrace_input0 (SIM_DESC sd,	      sim_cpu *cpu,	      int trace_idx){  TRACE_DATA *data = CPU_TRACE_DATA (cpu);  TRACE_IDX (data) = trace_idx;}voidtrace_input_word1 (SIM_DESC sd,		   sim_cpu *cpu,		   int trace_idx,		   unsigned_word d0){  TRACE_DATA *data = CPU_TRACE_DATA (cpu);  TRACE_IDX (data) = trace_idx;  save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d0);}voidtrace_input_word2 (SIM_DESC sd,		   sim_cpu *cpu,		   int trace_idx,		   unsigned_word d0,		   unsigned_word d1){  TRACE_DATA *data = CPU_TRACE_DATA (cpu);  TRACE_IDX (data) = trace_idx;  save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d0);  save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d1);}voidtrace_input_word3 (SIM_DESC sd,		   sim_cpu *cpu,		   int trace_idx,		   unsigned_word d0,		   unsigned_word d1,		   unsigned_word d2){  TRACE_DATA *data = CPU_TRACE_DATA (cpu);  TRACE_IDX (data) = trace_idx;  save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d0);  save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d1);  save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d2);}voidtrace_input_word4 (SIM_DESC sd,		   sim_cpu *cpu,		   int trace_idx,		   unsigned_word d0,		   unsigned_word d1,		   unsigned_word d2,		   unsigned_word d3){  TRACE_DATA *data = CPU_TRACE_DATA (cpu);  TRACE_IDX (data) = trace_idx;  save_data (sd, data, trace_fmt_word, sizeof (d0), &d0);  save_data (sd, data, trace_fmt_word, sizeof (d1), &d1);

⌨️ 快捷键说明

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