예제 #1
0
static int
my_print_insn (CGEN_CPU_DESC cd,
	       bfd_vma pc,
	       disassemble_info *info)
{
  bfd_byte buffer[CGEN_MAX_INSN_SIZE];
  bfd_byte *buf = buffer;
  int status;
  int buflen = (pc & 3) == 0 ? 4 : 2;
  int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG;
  bfd_byte *x;

  /* Read the base part of the insn.  */

  status = (*info->read_memory_func) (pc - ((!big_p && (pc & 3) != 0) ? 2 : 0),
                                      buf, buflen, info);
  if (status != 0)
    {
      (*info->memory_error_func) (status, pc, info);
      return -1;
    }

  /* 32 bit insn?  */
  x = (big_p ? &buf[0] : &buf[3]);
  if ((pc & 3) == 0 && (*x & 0x80) != 0)
    return print_insn (cd, pc, info, buf, buflen);

  /* Print the first insn.  */
  if ((pc & 3) == 0)
    {
      buf += (big_p ? 0 : 2);
      if (print_insn (cd, pc, info, buf, 2) == 0)
	(*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
      buf += (big_p ? 2 : -2);
    }

  x = (big_p ? &buf[0] : &buf[1]);
  if (*x & 0x80)
    {
      /* Parallel.  */
      (*info->fprintf_func) (info->stream, " || ");
      *x &= 0x7f;
    }
  else
    (*info->fprintf_func) (info->stream, " -> ");

  /* The "& 3" is to pass a consistent address.
     Parallel insns arguably both begin on the word boundary.
     Also, branch insns are calculated relative to the word boundary.  */
  if (print_insn (cd, pc & ~ (bfd_vma) 3, info, buf, 2) == 0)
    (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);

  return (pc & 3) ? 2 : 4;
}
예제 #2
0
파일: epiphany-dis.c 프로젝트: 5kg/gdb
static int
epiphany_print_insn (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
{
  bfd_byte buf[CGEN_MAX_INSN_SIZE];
  int buflen;
  int status;

  info->bytes_per_chunk = 2;

  /* Attempt to read the base part of the insn.  */
  info->bytes_per_line = buflen = cd->base_insn_bitsize / 8;
  status = (*info->read_memory_func) (pc, buf, buflen, info);

  /* Try again with the minimum part, if min < base.  */
  if (status != 0 && (cd->min_insn_bitsize < cd->base_insn_bitsize))
    {
      info->bytes_per_line = buflen = cd->min_insn_bitsize / 8;
      status = (*info->read_memory_func) (pc, buf, buflen, info);
    }

  if (status != 0)
    {
      (*info->memory_error_func) (status, pc, info);
      return -1;
    }

  return print_insn (cd, pc, info, buf, buflen);
}
/* Dump insn INSN honoring FLAGS.  */
void
dump_insn_rtx_1 (rtx insn, int flags)
{
  int all;

  /* flags == -1 also means dumping all.  */
  all = (flags & 1);;
  if (all)
    flags |= DUMP_INSN_RTX_ALL;

  sel_print ("(");

  if (flags & DUMP_INSN_RTX_UID)
    sel_print ("%d;", INSN_UID (insn));

  if (flags & DUMP_INSN_RTX_PATTERN)
    {
      char buf[2048];

      print_insn (buf, insn, 0);
      sel_print ("%s;", buf);
    }

  if (flags & DUMP_INSN_RTX_BBN)
    {
      basic_block bb = BLOCK_FOR_INSN (insn);

      sel_print ("bb:%d;", bb != NULL ? bb->index : -1);
    }

  sel_print (")");
}
예제 #4
0
/* Function to apply to all instruction that need printing */
int process_insn(x86_inst_t * insn, void * ctx) {
  trace_interface_t * trace = (trace_interface_t *) ctx;
  /* Print analysis progress */
  if ((insn->insn_ctr % PROGRESS_GAP) == 0) {
    int percent = (trace_get_curr_filepos(trace) * 101) /
                    trace->trace_byte_size;
    print_percent(stderr, percent);
  }

  /* Print instruction */
  print_insn(out_stream, insn, intel_format, verbose, print_counter);

  return 0;
}
예제 #5
0
/* Emit a slim dump of X (an insn) to the file F, including any register
   note attached to the instruction.  */
void
dump_insn_slim (FILE *f, const_rtx x)
{
  char t[BUF_LEN + 32];
  rtx note;

  print_insn (t, x, 1);
  fputs (t, f);
  putc ('\n', f);
  if (INSN_P (x) && REG_NOTES (x))
    for (note = REG_NOTES (x); note; note = XEXP (note, 1))
      {
        print_value (t, XEXP (note, 0), 1);
	fprintf (f, "      %s: %s\n",
		 GET_REG_NOTE_NAME (REG_NOTE_KIND (note)), t);
      }
}
예제 #6
0
파일: sched-vis.c 프로젝트: ChaosJohn/gcc
static void
print_insn_with_notes (pretty_printer *pp, const_rtx x)
{
  pp_string (pp, print_rtx_head);
  print_insn (pp, x, 1);
  pp_newline (pp);
  if (INSN_P (x) && REG_NOTES (x))
    for (rtx note = REG_NOTES (x); note; note = XEXP (note, 1))
      {
	pp_printf (pp, "%s      %s ", print_rtx_head,
		   GET_REG_NOTE_NAME (REG_NOTE_KIND (note)));
	if (GET_CODE (note) == INT_LIST)
	  pp_printf (pp, "%d", XINT (note, 0));
	else
	  print_pattern (pp, XEXP (note, 0), 1);
	pp_newline (pp);
      }
}
예제 #7
0
파일: sched-vis.c 프로젝트: Fokycnuk/gcc
void
visualize_scheduled_insns (int clock)
{
  int i, unit;

  /* If no more room, split table into two.  */
  if (n_visual_lines >= MAX_VISUAL_LINES)
    {
      print_block_visualization ("(incomplete)");
      init_block_visualization ();
    }

  n_visual_lines++;

  sprintf (visual_tbl + strlen (visual_tbl), ";;   %-8d", clock);
  for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
    if (function_units[unit].bitmask & target_units)
      for (i = 0; i < function_units[unit].multiplicity; i++)
	{
	  int instance = unit + i * FUNCTION_UNITS_SIZE;
	  rtx insn = get_unit_last_insn (instance);

	  /* Print insns that still keep the unit busy.  */
	  if (insn
	      && actual_hazard_this_instance (unit, instance, insn, clock, 0))
	    {
	      char str[BUF_LEN];
	      print_insn (str, insn, 0);
	      str[INSN_LEN] = '\0';
	      sprintf (visual_tbl + strlen (visual_tbl), "  %-33s", str);
	    }
	  else
	    sprintf (visual_tbl + strlen (visual_tbl), "  %-33s", "------------------------------");
	}

  /* Print insns that are not assigned to any unit.  */
  for (i = 0; i < n_vis_no_unit; i++)
    sprintf (visual_tbl + strlen (visual_tbl), "  %-8d",
	     INSN_UID (vis_no_unit[i]));
  n_vis_no_unit = 0;

  sprintf (visual_tbl + strlen (visual_tbl), "\n");
}
예제 #8
0
bool stride_count_seq(const u_char *data, u_int length, double freq[], int pos){
    if( counted[pos]){
        return true;
    }
	u_int i = 0;
	while( i < length){
		int ret = print_insn((bfd_vma)(data + i), &disasm_info);
		if( ret < 0)
            return false;
		int insn_size = (ret>>MOD);
        int insn_type = (ret & ((1<<MOD) - 1));

        if( insn_type == INSTRUCTION_TYPE_PRIV || insn_type == INSTRUCTION_TYPE_INVL){
            return false;
        }

        if( counted[pos + i])
            return true;
        counted[pos + i] = true;
        freq[insn_type - 1]++;
         switch (insn_type) {
            case INSTRUCTION_TYPE_JMP: //fall through
            case INSTRUCTION_TYPE_JMPC:
            case INSTRUCTION_TYPE_LOOP:
            case INSTRUCTION_TYPE_CALL:
            case INSTRUCTION_TYPE_ENTER:
            case INSTRUCTION_TYPE_JECXZ:
                return true;
                break;
            default:
                break;
        }
        i += (u_int) insn_size;

	}
	return true;
}
예제 #9
0
파일: disas.c 프로젝트: doremi/emulator
void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
{
    target_ulong pc;
    int count;
    struct disassemble_info disasm_info;
    int (*print_insn)(bfd_vma pc, disassemble_info *info);

    INIT_DISASSEMBLE_INFO(disasm_info, out, fprintf);

    disasm_info.read_memory_func = target_read_memory;
    disasm_info.buffer_vma = code;
    disasm_info.buffer_length = size;

#ifdef TARGET_WORDS_BIGENDIAN
    disasm_info.endian = BFD_ENDIAN_BIG;
#else
    disasm_info.endian = BFD_ENDIAN_LITTLE;
#endif

	print_insn = print_insn_arm;

    for (pc = code; size > 0; pc += count, size -= count) {
	fprintf(out, "0x" TARGET_FMT_lx ":  ", pc);
	count = print_insn(pc, &disasm_info);
	fprintf(out, "\n");
	if (count < 0)
	    break;
        if (size < count) {
            fprintf(out,
                    "Disassembler disagrees with translator over instruction "
                    "decoding\n"
                    "Please report this to [email protected]\n");
            break;
        }
    }
}
예제 #10
0
static
void disassemble_to_buffer(TranslationBlock *tb, DisasBuffer *str) {
    unsigned long pc;
    struct disassemble_info disasm_info;
    int (*print_insn)(bfd_vma pc, disassemble_info *info);

    INIT_DISASSEMBLE_INFO(disasm_info, (FILE *)str, disas_fprintf);

    disasm_info.buffer = tb->tc_ptr;
    disasm_info.buffer_vma = (unsigned long)tb->tc_ptr;
    disasm_info.buffer_length = tb->size;

#ifdef HOST_WORDS_BIGENDIAN
    disasm_info.endian = BFD_ENDIAN_BIG;
#else
    disasm_info.endian = BFD_ENDIAN_LITTLE;
#endif
#if defined(__i386__)
    disasm_info.mach = bfd_mach_i386_i386;
    print_insn = print_insn_i386;
#elif defined(__x86_64__)
    disasm_info.mach = bfd_mach_x86_64;
    print_insn = print_insn_i386;
#elif defined(_ARCH_PPC)
    print_insn = print_insn_ppc;
#elif defined(__alpha__)
    print_insn = print_insn_alpha;
#elif defined(__sparc__)
    print_insn = print_insn_sparc;
#if defined(__sparc_v8plus__) || defined(__sparc_v8plusa__) || defined(__sparc_v9__)
    disasm_info.mach = bfd_mach_sparc_v9b;
#endif
#elif defined(__arm__)
    print_insn = print_insn_arm;
#elif defined(__MIPSEB__)
    print_insn = print_insn_big_mips;
#elif defined(__MIPSEL__)
    print_insn = print_insn_little_mips;
#elif defined(__m68k__)
    print_insn = print_insn_m68k;
#elif defined(__s390__)
    print_insn = print_insn_s390;
#elif defined(__hppa__)
    print_insn = print_insn_hppa;
#elif defined(__ia64__)
    print_insn = print_insn_ia64;
#else
    fprintf(out, "0x%lx: Asm output not supported on this arch\n",
            (long) code);
    return;
#endif

    int icount = 0;
    int count = 0;
    for (pc = (unsigned long)tb->tc_ptr;
            icount < tb->size && count < DISAS_BUFFER_SIZE; )
    {
        int before = str->size;
        print_insn(pc, &disasm_info);
        int after = str->size;

        if (after == DISAS_BUFFER_SIZE)
            break;

        icount += after - before;

        str->buffer[after++] = '\n';

        pc += after - before;
        count += after - before;
    }
    str->buffer[count] = 0;
}
예제 #11
0
static void decode_insn(struct pt_insn_decoder *decoder,
			const struct ptxed_options *options,
			struct ptxed_stats *stats)
{
	xed_state_t xed;
	uint64_t offset, sync, time;

	if (!options) {
		printf("[internal error]\n");
		return;
	}

	xed_state_zero(&xed);

	offset = 0ull;
	sync = 0ull;
	time = 0ull;
	for (;;) {
		struct pt_insn insn;
		int errcode;

		/* Initialize the IP - we use it for error reporting. */
		insn.ip = 0ull;

		errcode = pt_insn_sync_forward(decoder);
		if (errcode < 0) {
			uint64_t new_sync;

			if (errcode == -pte_eos)
				break;

			diagnose_insn("sync error", decoder, &insn, errcode);

			/* Let's see if we made any progress.  If we haven't,
			 * we likely never will.  Bail out.
			 *
			 * We intentionally report the error twice to indicate
			 * that we tried to re-sync.  Maybe it even changed.
			 */
			errcode = pt_insn_get_offset(decoder, &new_sync);
			if (errcode < 0 || (new_sync <= sync))
				break;

			sync = new_sync;
			continue;
		}

		for (;;) {
			if (options->print_offset) {
				errcode = pt_insn_get_offset(decoder, &offset);
				if (errcode < 0)
					break;
			}

			if (options->print_time) {
				errcode = pt_insn_time(decoder, &time, NULL,
						       NULL);
				if (errcode < 0)
					break;
			}

			errcode = pt_insn_next(decoder, &insn, sizeof(insn));
			if (errcode < 0) {
				/* Even in case of errors, we may have succeeded
				 * in decoding the current instruction.
				 */
				if (insn.iclass != ptic_error) {
					if (!options->quiet)
						print_insn(&insn, &xed, options,
							   offset, time);
					if (stats)
						stats->insn += 1;
				}
				break;
			}

			if (!options->quiet)
				print_insn(&insn, &xed, options, offset, time);

			if (stats)
				stats->insn += 1;

			if (errcode & pts_eos) {
				if (!insn.disabled && !options->quiet)
					printf("[end of trace]\n");

				errcode = -pte_eos;
				break;
			}
		}

		/* We shouldn't break out of the loop without an error. */
		if (!errcode)
			errcode = -pte_internal;

		/* We're done when we reach the end of the trace stream. */
		if (errcode == -pte_eos)
			break;

		diagnose_insn("error", decoder, &insn, errcode);
	}
}
예제 #12
0
/**
 * We try to decode from all arrays code, we keep track "pos" in the array scan_cache.
 * @param code array we need to decode. This array has size length
 * @param pos the position of "code" in array cached
 * @param length size of code we want to decode.
 * @return SCANNED_VALID if scan from pos to the end succesfully, otherwise SCANNED_INVALID
 */
static int racewalk_go(const u_char *code, u_int pos, u_int length) {
    if ( scan_cache[pos] != NOT_SCANNED)
        return scan_cache[pos];
    if ( length < 1)
        return SCANNED_VALID;
    u_int npos = (pos + shift) >= the_sled_length ? (pos + shift - the_sled_length) : (pos + shift);
    bool jmp = false;

    if ( decode_cache[npos] != NOT_DECODED) {
        // We never decode an instruction twice
        jmp = decode_cache[npos] >= JMP ? 1 : 0;
    } else {
        int ret = print_insn((bfd_vma)code, &disasm_info);
        if ( ret < 0) {
            decode_cache[npos] = DECODED_INVALID;
        } else {
            int insn_size = (ret>>MOD);
            int insn_type = (ret & ((1<<MOD) - 1));
            switch (insn_type) {
            case INSTRUCTION_TYPE_JMP: //fall through
            case INSTRUCTION_TYPE_JMPC:
            case INSTRUCTION_TYPE_LOOP:
            case INSTRUCTION_TYPE_CALL:
            case INSTRUCTION_TYPE_ENTER:
            case INSTRUCTION_TYPE_JECXZ:
                jmp = true;
                break;
            default:
                jmp = false;
                break;
            }

            switch (insn_type) {
            case INSTRUCTION_TYPE_INVL: //fall through
            case INSTRUCTION_TYPE_PRIV:
                decode_cache[npos] = DECODED_INVALID;
                break;
            default:
                decode_cache[npos] = insn_size + JMP * (int)(jmp ? 1 : 0);
                break;
            }
        }
    }
    if ( decode_cache[npos] == DECODED_INVALID) {
        return scan_cache[pos] = SCANNED_INVALID;
    } else {
        if ( jmp) {
            return scan_cache[pos] = SCANNED_VALID;
        }
        u_int res = (u_int) decode_cache[npos];
        if ( res < length) {
            int cur = racewalk_go(code + res, pos + res, length - res);
            if ( cur == SCANNED_INVALID) {
                seq = seq & ~(1<<(pos & 0x3));
            }
            return scan_cache[pos] = cur;
        } else {
            return scan_cache[pos] = SCANNED_VALID;
        }
    }
}