Пример #1
0
/* Prints the instruction by calling print_arguments after proper matching: */
int
print_insn_crx(bfd_vma memaddr, struct disassemble_info *info)
{
  int is_decoded;     /* Nonzero means instruction has a match.  */

  /* Initialize global variables: */
  cst4flag = 0;
  size_changed = 0;

  /* Retrieve the encoding from current memory location: */
  get_words_at_PC(memaddr, info);
  /* Find a matching opcode in table: */
  is_decoded = match_opcode();
  /* If found, print the instruction's mnemonic and arguments: */
  if ((is_decoded > 0) && (((words[0] << 16) != 0) || (words[1] != 0)))
    {
      info->fprintf_func(info->stream, "%s", instruction->mnemonic);
      if ((currInsn.nargs = get_number_of_operands()) != 0)
	info->fprintf_func(info->stream, "\t");
      make_instruction();
      print_arguments(&currInsn, memaddr, info);
      return currInsn.size;
    }

  /* No match found: */
  info->fprintf_func(info->stream, "%s ", ILLEGAL);
  return 2;
}
Пример #2
0
static int
check_c_ret(uint32_t **instr)
{
	uint16_t *instr1;
	int i;

	for (i = 0; i < 2; i++) {
		instr1 = (uint16_t *)(*instr) + i;
		if (match_opcode(*instr1, (MATCH_C_JR | (X_RA << RD_SHIFT)),
		    (MASK_C_JR | RD_MASK))) {
			*instr = (uint32_t *)instr1;
			return (1);
		}
	}

	return (0);
}
Пример #3
0
static int
check_c_sdsp(uint32_t **instr)
{
	uint16_t *instr1;
	int i;

	for (i = 0; i < 2; i++) {
		instr1 = (uint16_t *)(*instr) + i;
		if (match_opcode(*instr1, (MATCH_C_SDSP | RS2_C_RA),
		    (MASK_C_SDSP | RS2_C_MASK))) {
			*instr = (uint32_t *)instr1;
			return (1);
		}
	}

	return (0);
}
Пример #4
0
int
fbt_provide_module_function(linker_file_t lf, int symindx,
    linker_symval_t *symval, void *opaque)
{
	fbt_probe_t *fbt, *retfbt;
	uint32_t *instr, *limit;
	const char *name;
	char *modname;
	int patchval;
	int rval;

	modname = opaque;
	name = symval->name;

	/* Check if function is excluded from instrumentation */
	if (fbt_excluded(name))
		return (0);

	instr = (uint32_t *)(symval->value);
	limit = (uint32_t *)(symval->value + symval->size);

	/* Look for sd operation */
	for (; instr < limit; instr++) {
		/* Look for a non-compressed store of ra to sp */
		if (match_opcode(*instr, (MATCH_SD | RS2_RA | RS1_SP),
		    (MASK_SD | RS2_MASK | RS1_MASK))) {
			rval = DTRACE_INVOP_SD;
			patchval = FBT_PATCHVAL;
			break;
		}

		/* Look for a 'C'-compressed store of ra to sp. */
		if (check_c_sdsp(&instr)) {
			rval = DTRACE_INVOP_C_SDSP;
			patchval = FBT_C_PATCHVAL;
			break;
		}
	}

	if (instr >= limit)
		return (0);

	fbt = malloc(sizeof (fbt_probe_t), M_FBT, M_WAITOK | M_ZERO);
	fbt->fbtp_name = name;
	fbt->fbtp_id = dtrace_probe_create(fbt_id, modname,
	    name, FBT_ENTRY, 3, fbt);
	fbt->fbtp_patchpoint = instr;
	fbt->fbtp_ctl = lf;
	fbt->fbtp_loadcnt = lf->loadcnt;
	fbt->fbtp_savedval = *instr;
	fbt->fbtp_patchval = patchval;
	fbt->fbtp_rval = rval;
	fbt->fbtp_symindx = symindx;

	fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];
	fbt_probetab[FBT_ADDR2NDX(instr)] = fbt;

	lf->fbt_nentries++;

	retfbt = NULL;
again:
	for (; instr < limit; instr++) {
		/* Look for non-compressed return */
		if (match_opcode(*instr, (MATCH_JALR | (X_RA << RS1_SHIFT)),
		    (MASK_JALR | RD_MASK | RS1_MASK | IMM_MASK))) {
			rval = DTRACE_INVOP_RET;
			patchval = FBT_PATCHVAL;
			break;
		}

		/* Look for 'C'-compressed return */
		if (check_c_ret(&instr)) {
			rval = DTRACE_INVOP_C_RET;
			patchval = FBT_C_PATCHVAL;
			break;
		}
	}

	if (instr >= limit)
		return (0);

	/*
	 * We have a winner!
	 */
	fbt = malloc(sizeof (fbt_probe_t), M_FBT, M_WAITOK | M_ZERO);
	fbt->fbtp_name = name;
	if (retfbt == NULL) {
		fbt->fbtp_id = dtrace_probe_create(fbt_id, modname,
		    name, FBT_RETURN, 3, fbt);
	} else {
		retfbt->fbtp_probenext = fbt;
		fbt->fbtp_id = retfbt->fbtp_id;
	}
	retfbt = fbt;

	fbt->fbtp_patchpoint = instr;
	fbt->fbtp_ctl = lf;
	fbt->fbtp_loadcnt = lf->loadcnt;
	fbt->fbtp_symindx = symindx;
	fbt->fbtp_rval = rval;
	fbt->fbtp_savedval = *instr;
	fbt->fbtp_patchval = patchval;
	fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];
	fbt_probetab[FBT_ADDR2NDX(instr)] = fbt;

	lf->fbt_nentries++;

	instr++;
	goto again;
}
Пример #5
0
// do the same work as m68k_disasm but some instructions dis-assembled by the
// UAE engine use a weird/wrong naming scheme so we remap them here rather than
// touching the newcpu.c & table68k files because this file may be updated when 
// upgrading the UAE engine.
int m68k_dasm(char **line, uint32_t addr)
{
	char output[1024];
	int offset;
	gchar** split;
	int idx;

	// get UAE disassembly
	offset = m68k_disasm(output, addr);

	// split string into address, opcode and operand
	split = g_strsplit(output, " ", 3);

	// search for opcode to rewrite
	idx = match_opcode(split[1]);
	if(idx != -1)
	{
		gchar *tmp;
		
		switch(idx)
		{
		case 0:		/* ORI to SR #<data>,SR		*/
			{
				char c = split[1][5];

				g_free(split[1]);
				split[1] = g_strdup_printf("ORI.%c", c);
			
				tmp = g_strconcat(split[2], ",SR", NULL);
				g_free(split[2]);
				split[2] = tmp;
			}
			break;
		case 1:		/* ANDI to SR #<data>,SR	*/
			{
				char c = split[1][6];
			
				g_free(split[1]);
				split[1] = g_strdup_printf("ANDI.%c", c);
			
				tmp = g_strconcat(split[2], ",SR", NULL);
				g_free(split[2]);
				split[2] = tmp;
			}
			break;
		case 2:		/* EORI to SR #<data>,SR	*/
			{
				char c = split[1][6]; 
			
				g_free(split[1]);
				split[1] = g_strdup_printf("EORI.%c", c);
			
				tmp = g_strconcat(split[2], ",SR", NULL);
				g_free(split[2]);
				split[2] = tmp;
			}
			break;
		case 3:		/* MOVE from SR: SR,<ea>		*/
			{
				char c = split[1][6];

				g_free(split[1]);
				split[1] = g_strdup_printf("MOVE.%c", c);
			
				tmp = g_strconcat("SR,", split[2], NULL);
				g_free(split[2]);
				split[2] = tmp;
			}
			break;
		case 4:		/* MOVE to SR: <ea>,SR		*/
			{
				char c = split[1][6];
			
				g_free(split[1]);
				split[1] = g_strdup_printf("MOVE.%c", c);
			
				tmp = g_strconcat(split[2], ",SR", NULL);
				g_free(split[2]);
				split[2] = tmp;
			}
			break;
		case 5:	/* MOVE An,USP	*/
			g_free(split[1]);
			split[1] = g_strdup("MOVE");
			
			tmp = g_strconcat(split[2], ",USP", NULL);
			g_free(split[2]);
			split[2] = tmp;
			break;
		case 6:	/* MOVE USP,An	*/
			g_free(split[1]);
			split[1] = g_strdup("MOVE");
			
			tmp = g_strconcat("USP,", split[2], NULL);
			g_free(split[2]);
			split[2] = tmp;
			break;
		case 7:		/* MOVEM <ea>,<list>	*/
			{
				char c = split[1][6];
				char *p, *q;
				uint16_t mask;

				g_free(split[1]);
				split[1] = g_strdup_printf("MOVEM.%c", c);

				p = split[2];
				q = strchr(split[2], ',');
				q++;

				sscanf(p, "#$%" SCNx16, &mask);
				if(q[0] != '-')
					tmp = g_strdup_printf("%s,%s", q, create_reg_lists(mask));
				else
					tmp = g_strdup_printf("%s,%s", q, create_rev_reg_lists(mask));

				g_free(split[2]);
				split[2] = tmp;
			}
			break;
		case 8:		/* MOVEM <list>, <ea>	*/
			{
				char c = split[1][6];
				char *p, *q;
				uint16_t mask;

				g_free(split[1]);
				split[1] = g_strdup_printf("MOVEM.%c", c);

				p = split[2];
				q = strchr(split[2], ',');
				q++;

				sscanf(p, "#$%" SCNx16, &mask);
				if(q[0] != '-')
					tmp = g_strdup_printf("%s,%s", create_reg_lists(mask), q);
				else
					tmp = g_strdup_printf("%s,%s", q, create_rev_reg_lists(mask));

				g_free(split[2]);
				split[2] = tmp;
			}
			break;
		case 9:		/* MOVEP <Dx>,<(d16,Ay)> */
		case 10:	/* MOVEP <(d16,Ay)>,<Dx> */
			{
				char c = split[1][6];

				g_free(split[1]);
				split[1] = g_strdup_printf("MOVEP.%c", c);
			}
			break;
		case 11:	/* TRAP #<vector>	*/
		case 12:	/* RESET.L			*/
		case 13:	/* NOP.L			*/
		case 14:	/* STOP.L			*/
		case 15:	/* RTE.L			*/
		case 16:	/* RTS.L			*/
		case 17:	/* JMP.L			*/
		case 18:	/* LEA.L			*/
			{
				char *p = strchr(split[1], '.');
				if(p) *p = '\0';
			}
			break;
		case 20:	/* BRA				*/
			{
				tmp = g_strdup_printf("BRA.%c", split[1][3]);
				g_free(split[1]);
				split[1] = tmp;
			}
		break;

		case 19:	/* BTST				*/
		default:
			break;
		}
	}

	// search for [value] and reject it at end of line
	if(strchr(split[2], '['))
	{
		char *p = strchr(split[2], '[');
		char *q = strrchr(split[2], ']');
		char tmp[256];

		p--;
		q++;
		strncpy(tmp, p, q - p);
		tmp[q-p] = '\0';
		strcpy(p, q);
		strcat(split[2], tmp);
	}

	*line = g_strdup_printf("%s %s %s", 
			split[0] ? split[0] : "", 
			split[1] ? split[1] : "",
			split[2] ? split[2] : "");
	g_strfreev(split);

	return offset;
}