//---------------------------------------------------------------------- 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; } }
/* * 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); }