//-------------------------------------------------------------------------- int out_commented(const char *p, color_t ntag) { if ( ntag != _CURCOL) out_tagon(ntag ); register int i = out_snprintf("%s %s", ash.cmnt, p); if ( ntag != _CURCOL) out_tagoff(ntag ); return(i); }
//---------------------------------------------------------------------- static void out_address(ea_t ea, op_t &x, bool mapping, bool at) { regnum_t reg = get_mapped_register(ea); if ( mapping && reg != rnone) out_register(ph.regNames[reg] ); else { #ifndef TMS320C54_NO_NAME_NO_REF char buf[MAXSTR]; // since tms320c54 uses memory mapping, we turn off verification // of name expression values (3d arg of get_name_expr is BADADDR) if ( get_name_expr(cmd.ea+x.offb, x.n, ea, BADADDR, buf, sizeof(buf)) > 0 ) { if ( at) out_symbol('@' ); OutLine(buf); } else #endif { out_tagon(COLOR_ERROR); OutValue(x, OOFW_IMM|OOF_ADDR); out_tagoff(COLOR_ERROR); QueueMark(Q_noName, cmd.ea); } } }
//--------------------------------------------------------------------------- uchar putVal(op_t &x, uchar mode, uchar warn) { char str[MAXSTR]; uint32 sv_bufsize = bufsize; char *sv_bufbeg = bufbeg, *sv_ptr = get_output_ptr(); init_output_buffer(str, sizeof(str)); { flags_t sv_uFlag = uFlag; uFlag = 0; OutValue(x, mode); uFlag = sv_uFlag; } out_zero(); init_output_buffer(sv_bufbeg, sv_bufsize); set_output_ptr(sv_ptr); if ( warn) out_tagon(COLOR_ERROR ); { register size_t i; if ( !warn) i = tag_strlen(str ); else i = tag_remove(str, str, 0); if ( chkOutLine(str, i)) return(0 ); } if ( warn) out_tagoff(COLOR_ERROR ); return(1); }
//---------------------------------------------------------------------- static void outmem(op_t &x, ea_t ea) { char buf[MAXSTR]; if ( get_name_expr(cmd.ea+x.offb, x.n, ea, BADADDR, buf, sizeof(buf)) <= 0 ) { const ioport_t *p = find_sym(x.addr); if ( p == NULL ) { out_tagon(COLOR_ERROR); OutLong(x.addr, 16); out_tagoff(COLOR_ERROR); QueueMark(Q_noName,cmd.ea); } else { out_line(p->name, COLOR_IMPNAME); } } else { bool complex = strchr(buf, '+') || strchr(buf, '-'); if ( complex ) out_symbol(ash.lbrace); OutLine(buf); if ( complex ) out_symbol(ash.rbrace); } }
//---------------------------------------------------------------------- size_t debLine(void) { OutChar('"'); out_tagoff(COLOR_STRING); if ( change_line()) return(0 ); return(putDeb(1)); }
//--------------------------------------------------------------------------- uchar putVal(const op_t &x, uchar mode, uchar warn) { char *ptr = get_output_ptr(); { flags_t sv_uFlag = uFlag; uFlag = 0; OutValue(x, mode); uFlag = sv_uFlag; } char str[MAXSTR]; char *end = set_output_ptr(ptr); size_t len = end - ptr; qstrncpy(str, ptr, qmin(len+1, sizeof(str))); if ( warn ) out_tagon(COLOR_ERROR); if ( warn ) len = tag_remove(str, str, 0); else len = tag_strlen(str); if ( chkOutLine(str, len) ) return 0; if ( warn ) out_tagoff(COLOR_ERROR); return 1; }
//---------------------------------------------------------------------- static void out_bad_address(ea_t addr) { out_tagon(COLOR_ERROR); OutLong(addr, 16); out_tagoff(COLOR_ERROR); QueueMark(Q_noName, cmd.ea); }
//-------------------------------------------------------------------------- // returns number of positions advanced int out_commented(const char *p, color_t color) { if ( color != COLOR_NONE ) out_tagon(color); int npos = out_snprintf("%s %s", ash.cmnt, p); if ( color != COLOR_NONE ) out_tagoff(color); return npos; }
//---------------------------------------------------------------------- static void out_bad_address(ea_t addr) { if ( !out_port_address(addr) ) { out_tagon(COLOR_ERROR); OutLong(addr, 16); out_tagoff(COLOR_ERROR); QueueSet(Q_noName, cmd.ea); } }
//--------------------------------------------------------------------------- static char putMethodLabel(ushort off) { char str[32]; int len = qsnprintf(str, sizeof(str), "met%03u_%s", curSeg.id.Number, off ? "end" : "begin"); if ( !checkLine(len)) return(1 ); out_tagon(COLOR_CODNAME); outLine(str, len); out_tagoff(COLOR_CODNAME); return(0); }
//---------------------------------------------------------------------- static void out_address(ea_t ea, op_t &x) { segment_t *s = getseg(ea); ea_t value = s != NULL ? ea - get_segm_base(s) : ea; if ( !out_name_expr(x, ea, value) ) { out_tagon(COLOR_ERROR); out_snprintf("%a", ea); out_tagoff(COLOR_ERROR); QueueSet(Q_noName, cmd.ea); } }
//---------------------------------------------------------------------- static void out_address(ea_t ea, op_t &x) { if ( !out_name_expr(x, ea,/* ea */ BADADDR) ) { out_tagon(COLOR_ERROR); OutValue(x, OOFW_IMM|OOF_ADDR|OOFW_16); out_snprintf(" (ea = %a)", ea); out_tagoff(COLOR_ERROR); QueueMark(Q_noName, cmd.ea); } }
//---------------------------------------------------------------------- static void out_bad_address(ea_t addr) { const char *name = find_sym((int)addr); if ( name != NULL ) { out_line(name, COLOR_IMPNAME); } else { out_tagon(COLOR_ERROR); OutLong(addr, 16); out_tagoff(COLOR_ERROR); QueueMark(Q_noName, cmd.ea); } }
uchar OutUtf8(ushort index, fmt_t mode, color_t ntag) { register size_t size = (maxpos - curpos) - outcnt; if ( (int)size <= MIN_ARG_SIZE ) { DEB_ASSERT(((int)size < 0), "OutUtf8"); if ( (size = putLine/*outProc*/()) == 0) return(1 ); } if ( ntag) out_tagon(ntag ); ref_pos = get_output_ptr(); if ( fmtString(index, size, mode, /**outProc*/putLine) < 0) return(1 ); outcnt += get_output_ptr() - ref_pos; if ( ntag) out_tagoff(ntag ); return(0); }
// output an address static void outaddr(op_t &op, const bool replace_with_label = true) { bool ind = is_addr_ind(op); // is operand indirect ? bool sp = is_addr_sp(op); // is operand special page ? int size = 16; // operand is 16 bits long if ( ind) out_symbol('(' ); if ( sp) { out_symbol('\\' ); size = 8; /* just display the first 8 bits */ } if ( !out_name_expr(op, toEA(cmd.cs, op.addr), op.addr) || !replace_with_label) { if ( replace_with_label) out_tagon(COLOR_ERROR ); OutValue(op, OOF_ADDR | OOFS_NOSIGN | (size < 16 ? OOFW_8 : OOFW_16) ); if ( replace_with_label) out_tagoff(COLOR_ERROR ); } if ( ind) out_symbol(')' ); }
//---------------------------------------------------------------------- uchar putShort(ushort value, uchar wsym) { char *p = get_output_ptr(); out_tagon(COLOR_ERROR); if ( wsym ) OutChar(wsym); OutLong(value, #ifdef __debug__ debugmode ? 16 : #endif 10); out_tagoff(COLOR_ERROR); char tmpstr[32]; char *end = set_output_ptr(p); size_t len = end - p; qstrncpy(tmpstr, p, qmin(len+1, sizeof(tmpstr))); return chkOutLine(tmpstr, tag_strlen(tmpstr)); }
uchar OutUtf8(ushort index, fmt_t mode, color_t color) { size_t size = (maxpos - curpos) - outcnt; if ( (int)size <= MIN_ARG_SIZE ) { DEB_ASSERT(((int)size < 0), "OutUtf8"); size = putLine(); if ( size == 0 ) return 1; } if ( color != COLOR_NONE ) out_tagon(color); ref_pos = get_output_ptr(); if ( fmtString(index, size, mode, putLine) < 0 ) return 1; outcnt += get_output_ptr() - ref_pos; if ( color != COLOR_NONE ) out_tagoff(color); return 0; }
//---------------------------------------------------------------------- uchar putShort(ushort value, uchar wsym) { char tmpstr[32]; register char *p = get_output_ptr(); out_tagon(COLOR_ERROR); if ( wsym) OutChar(wsym ); OutLong(value, #ifdef __debug__ debugmode ? 16 : #endif 10); out_tagoff(COLOR_ERROR); register size_t len = get_output_ptr() - p; memcpy(tmpstr, p, len); tmpstr[len] ='\0'; *p = '\0'; set_output_ptr(p); return(chkOutLine(tmpstr, tag_strlen(tmpstr))); }
//---------------------------------------------------------------------- static size_t putLine(void) { color_t color = COLOR_NONE; out_zero(); if ( g_bufbeg != NULL ) { char *p = strrchr(g_bufbeg, COLOR_ON); if ( p != NULL && p[1] && strchr(p+2, COLOR_OFF) == NULL ) // second - PARANOYA { color = (color_t)*(p + 1); out_tagoff(color); } } out_symbol('\\'); if ( change_line(curpos != 0 && !no_prim) ) return 0; curpos = 0; if ( color != COLOR_NONE ) out_tagon(color); ref_pos = get_output_ptr(); return maxpos; }
//---------------------------------------------------------------------- static size_t putLine(void) { register color_t ntag = _CURCOL; out_zero(); { register char *p = strrchr(bufbeg, COLOR_ON); if ( p && p[1] && !strchr(p+2, COLOR_OFF) ) { // second - PARANOYA ntag = (color_t)*(p + 1); out_tagoff(ntag); } } out_symbol('\\'); if ( change_line(curpos != 0 && !no_prim)) return(0 ); curpos = 0; #ifdef __BORLANDC__ #if _CURCOL != 0 #error #endif #endif if ( ntag) out_tagon(ntag ); ref_pos = get_output_ptr(); return(maxpos); }
//---------------------------------------------------------------------- static void out_address(op_t &op) { ea_t ea; if (op.type == o_near) ea = calc_code_mem(op.addr); else if (op.type == o_mem) ea = calc_data_mem(op); else if (op.type == o_io) ea = calc_io_mem(op); int reg = -1; if (op.type == o_mem) reg = get_mapped_register(ea); // print begin of the modifier switch(op.tms_modifier) { case TMS_MODIFIER_NULL: break; case TMS_MODIFIER_DMA: if ((int)reg == -1) out_symbol('@'); break; case TMS_MODIFIER_ABS16: case TMS_MODIFIER_PTR: out_symbol('*'); if (op.tms_modifier == TMS_MODIFIER_ABS16) out_line("abs16", COLOR_SYMBOL); out_line("(#", COLOR_SYMBOL); break; case TMS_MODIFIER_MMAP: out_line("mmap(@", COLOR_SYMBOL); break; case TMS_MODIFIER_PORT: out_line("port(#", COLOR_SYMBOL); break; case TMS_MODIFIER_PORT_AT: out_line("port(@", COLOR_SYMBOL); break; default: error("interr: out: o_address: modifier_begin"); } if (op.type != o_io) { if (int(reg) != -1) // memory mapped register out_register(ph.regNames[reg]); else { #ifndef TMS320C55_NO_NAME_NO_REF if ( !out_name_expr(op, ea, ea) ) #endif { out_tagon(COLOR_ERROR); if (op.type != o_mem) OutLong(op.addr, 16); else OutLong(op.addr, 16); out_tagoff(COLOR_ERROR); QueueMark(Q_noName, cmd.ea); } } } else // IO address { if (ea != BADADDR) { const char *name = NULL; if (idpflags & TMS320C55_IO) name = find_sym(ea); if (name) out_line(name, COLOR_IMPNAME); else OutLong(ea, 16); } else { out_tagon(COLOR_ERROR); OutLong(op.addr, 16); out_tagoff(COLOR_ERROR); } } // print end of the modifier switch(op.tms_modifier) { case TMS_MODIFIER_NULL: case TMS_MODIFIER_DMA: break; case TMS_MODIFIER_ABS16: case TMS_MODIFIER_PTR: case TMS_MODIFIER_MMAP: case TMS_MODIFIER_PORT: case TMS_MODIFIER_PORT_AT: out_symbol(')'); break; default: error("interr: out: o_address: modifier_begin"); } }
bool idaapi outop(op_t& x) { uchar warn = 0; switch ( x.type ) { case o_near: if ( x.ref ) ++warn; else { if ( outName(cmd.ea + x.offb, x.n, curSeg.startEA, x.addr, &warn) ) break; if ( warn ) goto badop; } if ( putVal(x, OOF_ADDR | OOF_NUMBER | OOFS_NOSIGN | OOFW_32, warn) ) break; //PASS THRU case o_void: badop: return(false); case o_imm: if ( x.ref == 2 ) ++warn; if ( putVal(x, OOFW_IMM | OOF_NUMBER | (x.ref ? OOFS_NOSIGN : OOF_SIGNED ), warn)) break; goto badop; case o_mem: if ( jasmin() ) goto putVarNum; if ( x.ref ) { putAddr: ++warn; } else { if ( outName(cmd.ea + x.offb, x.n, curSeg.DataBase, x.addr, &warn) ) break; if ( warn ) goto badop; } putVarNum: if ( putVal(x, OOF_ADDR | OOF_NUMBER | OOFS_NOSIGN | OOFW_16, warn) ) break; goto badop; case o_cpool: if ( !x.cp_ind) OUT_KEYWORD("NULL" ); else { if ( x.ref ) goto putAddr; if ( !OutConstant(x) ) goto badop; } break; case o_array: if ( !x.ref ) { int i = (uchar)x.cp_type - (T_BOOLEAN-1); // -1 - correct tp_decl if ( i < 0 || i > T_LONG - (T_BOOLEAN-1) || chkOutKeyword(tp_decl[i].str, tp_decl[i].size) ) goto badop; } else { static const char tt_bogust[] = "BOGUST_TYPE-"; if ( !checkLine(sizeof(tt_bogust) + 2) ) goto badop; out_tagon(COLOR_ERROR); outcnt += out_snprintf("%c%s%u", WARN_SYM, tt_bogust, (uchar)x.cp_type); out_tagoff(COLOR_ERROR); } break; default: warning("out: %a: bad optype %d", cmd.ip, x.type); break; } return(true); }
//---------------------------------------------------------------------- uchar OutConstant(op_t& x, uchar impdsc) { register uchar savetype = x.dtyp; register fmt_t fmt = fmt_dscr; register color_t ntag; switch ( (uchar)x.cp_type ) { default: warning("OC: bad constant type %u", (uchar)x.cp_type); break; case CONSTANT_Long: x.dtyp = dt_qword; goto outNum; case CONSTANT_Double: x.dtyp = dt_double; goto outNum; case CONSTANT_Integer: x.dtyp = dt_dword; goto outNum; case CONSTANT_Float: x.dtyp = dt_float; outNum: if ( putVal(x, OOF_NUMBER | OOF_SIGNED | OOFW_IMM, 0) ) break; badconst: return(0); case CONSTANT_String: if ( OutUtf8(x._name, fmt_string, COLOR_STRING) ) goto badconst; break; case CONSTANT_Class: #ifdef __BORLANDC__ #if ( fmt_cast+1) != fmt_classname || (fmt_classname+1 ) != fmt_fullname #error #endif #endif if ( OutUtf8(x._name, (fmt_t )x.addr_shorts.high, ( (fmt_t)x.addr_shorts.high < fmt_cast || (fmt_t)x.addr_shorts.high > fmt_fullname) ? COLOR_KEYWORD : (cmd.xtrn_ip == 0xFFFF ? COLOR_DNAME : COLOR_IMPNAME))) goto badconst; break; case CONSTANT_InterfaceMethodref: case CONSTANT_Methodref: fmt = fmt_retdscr; case CONSTANT_Fieldref: #ifdef VIEW_WITHOUT_TYPE if ( impdsc ) #endif if ( !jasmin() && OutUtf8(x._dscr, fmt, COLOR_KEYWORD) ) goto badconst; out_tagon(ntag = (x._class == curClass.This.Dscr) ? COLOR_DNAME : COLOR_IMPNAME); if ( jasmin() || (ntag == COLOR_IMPNAME && !impdsc) ) { // other class if ( OutUtf8(x._name, fmt_classname) || chkOutDot() ) goto badconst; } if ( OutUtf8(x._subnam, fmt_name) ) goto badconst; // Field out_tagoff(ntag); if ( jasmin() ) { if ( fmt == fmt_retdscr ) fmt = fmt_signature; // no space at end else if ( chkOutSpace() ) goto badconst; } else { if ( fmt != fmt_retdscr ) break; fmt = fmt_paramstr; } if ( OutUtf8(x._dscr, fmt, COLOR_KEYWORD) ) goto badconst; break; } x.dtyp = savetype; return(1); }
//---------------------------------------------------------------------- uchar OutConstant(op_t& x, uchar impdsc) { uchar savetype = x.dtyp; fmt_t fmt = fmt_dscr; color_t color; switch ( (uchar)x.cp_type ) { default: warning("OC: bad constant type %u", (uchar)x.cp_type); break; case CONSTANT_Long: x.dtyp = dt_qword; goto outNum; case CONSTANT_Double: x.dtyp = dt_double; goto outNum; case CONSTANT_Integer: x.dtyp = dt_dword; goto outNum; case CONSTANT_Float: x.dtyp = dt_float; outNum: if ( putVal(x, OOF_NUMBER | OOF_SIGNED | OOFW_IMM, 0) ) break; badconst: return 0; case CONSTANT_String: if ( OutUtf8(x._name, fmt_string, COLOR_STRING) ) goto badconst; break; case CONSTANT_Class: CASSERT((fmt_cast+1) == fmt_classname && (fmt_classname+1) == fmt_fullname); { fmt_t f2 = (fmt_t )x.addr_shorts.high; color_t c2 = f2 < fmt_cast || f2 > fmt_fullname ? COLOR_KEYWORD : cmd.xtrn_ip == 0xFFFF ? COLOR_DNAME : COLOR_IMPNAME; if ( OutUtf8(x._name, f2, c2) ) goto badconst; } break; case CONSTANT_InterfaceMethodref: case CONSTANT_Methodref: fmt = fmt_retdscr; case CONSTANT_Fieldref: #ifdef VIEW_WITHOUT_TYPE if ( impdsc ) #endif if ( !jasmin() && OutUtf8(x._dscr, fmt, COLOR_KEYWORD) ) goto badconst; color = x._class == curClass.This.Dscr ? COLOR_DNAME : COLOR_IMPNAME; out_tagon(color); if ( jasmin() || (color == COLOR_IMPNAME && !impdsc) ) // other class { if ( OutUtf8(x._name, fmt_classname) || chkOutDot() ) goto badconst; } if ( OutUtf8(x._subnam, fmt_name) ) goto badconst; // Field out_tagoff(color); if ( jasmin() ) { if ( fmt == fmt_retdscr ) fmt = fmt_signature; // no space at end else if ( chkOutSpace() ) goto badconst; } else { if ( fmt != fmt_retdscr ) break; fmt = fmt_paramstr; } if ( OutUtf8(x._dscr, fmt, COLOR_KEYWORD) ) goto badconst; break; } x.dtyp = savetype; return 1; }
//---------------------------------------------------------------------- bool outop(op_t &x) { ea_t ea; char buf[MAXSTR]; if ( x.type == o_imm ) out_symbol('#'); switch ( x.type ) { case o_void: return 0; case o_imm: if ( x.amode & amode_signed ) OutValue(x, OOF_SIGNED|OOFW_IMM); else OutValue(x, OOFS_IFSIGN|OOFW_IMM); break; case o_reg: outreg(x.reg); break; case o_mem: // no break; ea = calc_mem(x); if ( ea != BADADDR ) out_address(ea, x); else { out_tagon(COLOR_ERROR); OutValue(x, OOFW_IMM|OOF_ADDR|OOFW_16); out_tagoff(COLOR_ERROR); } break; case o_near: { ea_t ea = calc_mem(x); // xmem ioports if ( x.amode & (amode_x) && out_port_address(x.addr) ) { char nbuf[MAXSTR]; const char *pnam = find_port(x.addr); const char *name = get_true_name(BADADDR, ea, nbuf, sizeof(nbuf)); if ( name == NULL || strcmp(name, pnam) != 0 ) set_name(ea, pnam); break; } if ( ea == cmd.ea+cmd.size ) out_ip_rel(cmd.size); else if ( !out_name_expr(x, ea, x.addr) ) out_bad_address(x.addr); } break; case o_phrase: { if ( x.phtype < 4 ) { qsnprintf(buf, sizeof(buf), formats[x.phtype], x.phrase); out_colored_register_line(buf); } if ( x.phtype == 4 ) { out_symbol('('); outreg(x.reg); out_symbol(')'); } } break; case o_local: { out_colored_register_line(formats2[x.phtype]); OutValue(x, OOF_SIGNED|OOF_ADDR); if ( x.phtype == 0 ) out_symbol(')'); break; } case o_textphrase: { char buf[MAXSTR]; switch ( x.textphtype ) { case text_swap: out_line(swap_formats[x.phrase], COLOR_REG); break; case text_banke: int comma; char r0[10], r1[10], r4[10], cfgi[10]; comma = 0; r0[0]=r1[0]=r4[0]=cfgi[0]='\0'; if ( x.phrase & 0x01 ) //cfgi { qsnprintf(cfgi, sizeof(cfgi), "cfgi"); comma = 1; } if ( x.phrase & 0x02 ) //r4 { qsnprintf(r4, sizeof(r4), "r4%s", (comma?", ":"")); comma = 1; } if ( x.phrase & 0x04 ) //r1 { qsnprintf(r1, sizeof(r1), "r1%s", (comma?", ":"")); comma = 1; } if ( x.phrase & 0x08 ) //r0 qsnprintf(r0, sizeof(r0), "r0%s", (comma?", ":"")); qsnprintf(buf, sizeof(buf), "%s%s%s%s", r0, r1, r4, cfgi ); out_line(buf, COLOR_REG); break; case text_cntx: out_symbol( (x.phrase ? 'r': 's') ); break; case text_dmod: if ( x.phrase ) qsnprintf(buf, sizeof(buf), " no modulo"); else qsnprintf(buf, sizeof(buf), " modulo"); out_line(buf, COLOR_REG); break; case text_eu: qsnprintf(buf, sizeof(buf), " eu"); out_line(buf, COLOR_REG); break; } } break; default: interr("out"); break; } return 1; }