Exemple #1
0
//----------------------------------------------------------------------
static void trace_sp(void)
{
  // @sp++
  if ( cmd.Op1.type == o_phrase
    && issp(cmd.Op1.reg)
    && cmd.Op1.phtype == ph_post )
  {
    ssize_t size = get_dtyp_size(cmd.Op2.dtyp);
    if ( cmd.Op2.type == o_reglist )
      size *= cmd.Op2.nregs;
    add_stkpnt(size);
    return;
  }

  // @--sp
  if ( cmd.Op2.type == o_phrase
    && issp(cmd.Op2.reg)
    && cmd.Op2.phtype == ph_pre )
  {
    ssize_t size = get_dtyp_size(cmd.Op1.dtyp);
    if ( cmd.Op1.type == o_reglist )
      size *= cmd.Op1.nregs;
    add_stkpnt(-size);
    return;
  }

  int v;
  switch ( cmd.itype )
  {
    case H8_add:
    case H8_adds:
      if ( !issp(cmd.Op2.reg) )
        break;
      if ( get_op_value(cmd.Op1, &v) )
        add_stkpnt(v);
      break;
    case H8_sub:
    case H8_subs:
      if ( !issp(cmd.Op2.reg) )
        break;
      if ( get_op_value(cmd.Op1, &v) )
        add_stkpnt(-v);
      break;
    case H8_push:
      add_stkpnt(-get_dtyp_size(cmd.Op1.dtyp));
      break;
    case H8_pop:
      add_stkpnt( get_dtyp_size(cmd.Op1.dtyp));
      break;
  }
}
//----------------------------------------------------------------------
static void trace_sp(void)
{
  // @sp++
  if ( is_sp_inc(cmd.Op1) )
  {
    int size = 2;
    if ( cmd.Op2.type == o_reglist )
      size *= calc_reglist_count(cmd.Op2.reg);
    add_stkpnt(size);
    return;
  }

  // @--sp
  if ( is_sp_dec(cmd.Op2) )
  {
    int size = 2;
    if ( cmd.Op1.type == o_reglist )
      size *= calc_reglist_count(cmd.Op1.reg);
    add_stkpnt(-size);
    return;
  }
  // xxx @--sp
  if ( is_sp_dec(cmd.Op1) )
  {
    add_stkpnt(-2);
    return;
  }

  int v;
  switch ( cmd.itype )
  {
    case H8500_add_g:
    case H8500_add_q:
    case H8500_adds:
      if ( issp(cmd.Op2.reg) && get_op_value(cmd.Op1, &v) )
        add_stkpnt(v);
      break;
    case H8500_sub:
    case H8500_subs:
      if ( issp(cmd.Op2.reg) && get_op_value(cmd.Op1, &v) )
        add_stkpnt(-v);
      break;
  }
}
Exemple #3
0
/*
 * Display a disassembled instruction with annotation
 */
static void print_one_insn(struct ca_dis_insn* insn, struct ui_out* uiout)
{
	int i, pos;
	struct ca_operand* dst_op;

	ui_out_text(uiout, insn->dis_string);

	pos = strlen(insn->dis_string);
	if (pos < MAX_SPACING)
		ui_out_spaces(uiout, MAX_SPACING - pos);
	ui_out_text(uiout, " ## ");

	if (insn->num_operand == 0)
	{
		ui_out_text(uiout, "\n");
		return;
	}

	// special case
	/*if (insn->call)
	{
		// reminder that $rax is set to return value after a "call" instruction
		// if the called function has an integer return value
		// (unfortunately return type is not known for a function)
		ui_out_text(uiout, "(%rax=? on return) ");
	}*/

	dst_op = &insn->operands[0];
	// annotation of object context
	if (insn->annotate)
	{
		size_t ptr_sz = g_ptr_bit >> 3;
		int has_value = 0;
		size_t val = 0xcdcdcdcd;
		int op_size = insn->op_size;
		const char* symname = NULL;
		struct win_type type = {0,0};
		int is_vptr         = 0;
		char* name_to_free = NULL;

		// update register context by "pc"
		set_current_reg_pointers(insn);

		// Get the instruction's destination value/symbol/type
		if (dst_op->type == CA_OP_MEMORY)
		{
			// if the destination is a known local variable
			if (is_stack_address(dst_op))
			{
				address_t addr = get_address(dst_op);
				struct ca_stack_var* sval = get_stack_var(addr);
				if (sval)
				{
					symname = sval->sym_name;
					type = sval->type;
				}
				else
				{
					/*struct symbol* sym;
					struct object_reference aref;
					memset(&aref, 0, sizeof(aref));
					aref.vaddr = addr;
					aref.value = 0;
					aref.target_index = -1;
					sym = get_stack_sym(&aref, NULL, NULL);
					if (sym)
					{
						symname = SYMBOL_PRINT_NAME (sym);
						type = SYMBOL_TYPE(sym);
					}*/
					get_stack_sym_and_type(addr, &symname, &type);
				}
			}
			// could it be a known heap object
			if (!symname && !type.mod_base)
			{
				// this function will allocate buffer for the symbol name if any, remember to free it
				get_op_symbol_type(dst_op, 0, &name_to_free, &type, NULL);
				symname = name_to_free;
			}
			// Since flag insn->annotate is set, dst_op's value should be calculated
			val = get_op_value(dst_op, op_size);
			has_value = 1;
		}
		else if (dst_op->type == CA_OP_REGISTER)
		{
			struct ca_reg_value* dst_reg = get_reg_at_pc(dst_op->reg.index, insn->pc);
			if (dst_reg)
			{
				symname = dst_reg->sym_name;
				type    = dst_reg->type;
				is_vptr = dst_reg->vptr;
				if (dst_reg->has_value)
				{
					has_value = 1;
					val = dst_reg->value;
				}
			}
		}
		else if (dst_op->type == CA_OP_IMMEDIATE)
		{
			val = get_op_value(dst_op, op_size);
			has_value = 1;
		}

		if (dst_op->type != CA_OP_IMMEDIATE)
		{
			// Name and value (if known) of destination
			print_one_operand(uiout, dst_op, op_size);
			if (has_value)
				ui_out_message(uiout, 0, "="PRINT_FORMAT_POINTER, val);
			else
				ui_out_text(uiout, "=?");
		}

		// Symbol or type of destination
		if (dst_op->type == CA_OP_REGISTER
			&& dst_op->reg.index == RSP)
		{
			if (val == g_debug_context.sp)
				ui_out_text(uiout, " End of function prologue");
			ui_out_text(uiout, "\n");
		}
		else
		{
			// symbol or type is known
			if (symname || type.mod_base)
			{
				ui_out_text(uiout, "(");
				if (symname)
				{
					ui_out_message(uiout, 0, "symbol=\"%s\"", symname);
				}
				if (type.mod_base)
				{
					//CHECK_TYPEDEF(type);
					if (symname)
						ui_out_text(uiout, " ");
					ui_out_text(uiout, "type=\"");
					/*if (is_vptr)
					{
						const char * type_name = type_name_no_tag(type);
						if (type_name)
							ui_out_message(uiout, 0, "vtable for %s", type_name);
						else
						{
							ui_out_text(uiout, "vtable for ");
							print_type_name (type);
						}
					}
					else*/
						print_type_name (type);
					ui_out_text(uiout, "\"");
				}
				ui_out_text(uiout, ")\n");
			}
			// whatever we can get form the value
			else
			{
				address_t location = 0;
				int offset = 0;

				//if (insn->num_operand > 1)
				//{
				//	struct ca_operand* src_op = &insn->operands[1];
				//	get_location(src_op, &location, &offset);
				//}

				print_op_value_context (val,
						op_size > 0 ? op_size : ptr_sz,
						location, offset, insn->lea);
			}
		}
		if (name_to_free)
			free (name_to_free);
	}