// output shift symbol (if out = true, output outside of brackets) static void out_symbol_shift(op_t &op, bool out = false) { if (op.tms_shift != TMS_OP_SHIFT_NULL) { if (((op.tms_shift & TMS_OP_SHIFT_OUT)!=0) == out) // check if the shift must be print inside or outside the brackets { switch(op.tms_shift & TMS_OP_SHIFT_TYPE) { case TMS_OP_SHIFTL_IMM: out_line(" << ",COLOR_SYMBOL); out_shift(op.tms_shift_value); break; case TMS_OP_SHIFTL_REG: out_line(" << ",COLOR_SYMBOL); out_register(ph.regNames[op.tms_shift_value]); break; case TMS_OP_SHIFTR_IMM: out_line(" >> ",COLOR_SYMBOL); out_shift(op.tms_shift_value); break; case TMS_OP_EQ: out_line(" == ",COLOR_SYMBOL); out_shift(op.tms_shift_value); break; case TMS_OP_NEQ: out_line(" != ",COLOR_SYMBOL); out_shift(op.tms_shift_value); break; default: error("interr: out: out_symbol_shift"); } } } }
/*--------------------------------------------------------------------------- * Purpose: Prints a usage message to the standard error stream. If * SNAME is non-null then print only usage information for * that particular switch, otherwise print full usage * information. * * Programmer: Robb Matzke * Wednesday, May 31, 2000 * * Modifications: *--------------------------------------------------------------------------- */ void switch_usage(switches_t *switches, const char *arg0, const char *sname) { size_t i; char synopsis[256]; /* Base name of executable */ const char *base = strrchr(arg0, '/'); base = base ? base+1 : arg0; if (!sname) { sprintf(synopsis, "usage: %s [SWITCHES] [--] [FILES]", base); out_line(OUT_STDERR, synopsis); out_line(OUT_STDERR, " Where SWITCHES are:"); } for (i=0; i<switches->nused; i++) { switch_t *sw = switches->sw+i; if (sname && (!sw->short_name || strcmp(sw->short_name, sname)) && (!sw->long_name || strcmp(sw->long_name, sname))) { continue; } out_line(OUT_STDERR, switch_synopsis(sw, synopsis)); out_putw(OUT_STDERR, sw->doc_string); out_nl(OUT_STDERR); } }
// Output an instruction void out(void) { // // print insn mnemonic // char buf[MAXSTR]; init_output_buffer(buf, sizeof(buf)); char postfix[5]; postfix[0] = '\0'; if ( is_jmp_cc(cmd.itype) ) qstrncpy(postfix, ConditionCodes[cmd.auxpref], sizeof(postfix)); OutMnem(8, postfix); // // print insn operands // out_one_operand(0); // output the first operand if ( cmd.Op2.type != o_void ) { out_symbol(','); OutChar(' '); out_one_operand(1); } if ( cmd.Op3.type != o_void ) { out_symbol(','); OutChar(' '); out_one_operand(2); } // output a character representation of the immediate values // embedded in the instruction as comments if ( isVoid(cmd.ea,uFlag,0)) OutImmChar(cmd.Op1 ); if ( isVoid(cmd.ea,uFlag,1)) OutImmChar(cmd.Op2 ); if ( isVoid(cmd.ea,uFlag,2)) OutImmChar(cmd.Op3 ); if ( gr_cmt != NULL ) { OutChar(' '); out_line(ash.cmnt, COLOR_AUTOCMT); OutChar(' '); out_line(gr_cmt, COLOR_AUTOCMT); if ( ash.cmnt2 != NULL ) { OutChar(' '); out_line(ash.cmnt2, COLOR_AUTOCMT); } gr_cmt = NULL; } term_output_buffer(); // terminate the output string gl_comm = 1; // ask to attach a possible user- // defined comment to it MakeLine(buf); // pass the generated line to the // kernel }
//---------------------------------------------------------------------- bool idaapi outop(op_t &x) { ea_t ea; if ( x.type == o_imm ) out_symbol('#'); char buf[MAXSTR]; switch ( x.type ) { case o_void: return 0; case o_imm: OutValue(x, OOFS_IFSIGN|OOFW_IMM); break; case o_reg: outreg(x.reg); break; case o_mem: // no break; case o_near: { ea = calc_mem(x); 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: { qsnprintf(buf, sizeof(buf), "%%%c%" FMT_EA "x", 'a' + x.reg, x.value); ea = calc_data_mem(x, as + x.reg); if ( ( ea != BADADDR ) && ( ( x.reg != SR3 ) || ( x.value < 6 ) ) ) { out_line(buf, COLOR_AUTOCMT); out_symbol(' '); out_address(ea, x); } else out_line(buf, COLOR_REG); } break; default: interr("out"); break; } return 1; }
//---------------------------------------------------------------------- void out(void) { char buf[MAXSTR]; init_output_buffer(buf, sizeof(buf)); int op; if (!(cmd.SpecialModes & TMS_MODE_USER_PARALLEL)) { if ((cmd.SpecialModes & TMS_MODE_LR) || (cmd.SpecialModes & TMS_MODE_CR)) { out_line(cmd.get_canon_mnem(), COLOR_INSN); out_line((cmd.SpecialModes & TMS_MODE_LR) ? ".lr ":".cr ", COLOR_INSN); } else OutMnem(); } else { // user-defined parallelism out_line("|| ", COLOR_INSN); out_line(cmd.get_canon_mnem(), COLOR_INSN); out_line(" ", COLOR_INSN); } for (op = 0; op < UA_MAXOP; op++) { if (cmd.Operands[op].type == o_void) break; if (op != 0) // not the first operand { if (cmd.Parallel != TMS_PARALLEL_BIT && op == cmd.Parallel) // multi-line instruction { term_output_buffer(); MakeLine(buf); // print the second instruction line init_output_buffer(buf, sizeof(buf)); if (cmd.SpecialModes & TMS_MODE_SIMULATE_USER_PARALLEL) out_line("|| ", COLOR_INSN); else out_line(":: ", COLOR_INSN); const char *insn2 = cmd.get_canon_mnem(); insn2 += strlen(insn2); insn2++; out_line(insn2, COLOR_INSN); } else out_symbol(','); OutChar(' '); } // print the operand out_one_operand(op); } // print immediate values for (op = 0; op < UA_MAXOP; op++) if ( isVoid(cmd.ea, uFlag, op) ) OutImmChar(cmd.Operands[op]); term_output_buffer(); gl_comm = 1; MakeLine(buf); }
//---------------------------------------------------------------------- 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); } }
static void out_relop(op_t &op) { out_register(ph.regNames[op.reg]); char *relop; switch(op.tms_relop) { case 0: relop = " == "; break; case 1: relop = " < "; break; case 2: relop = " >= "; break; case 3: relop = " != "; break; default: error("interr: out: o_relop"); } out_line(relop, COLOR_SYMBOL); switch(op.tms_relop_type) { case TMS_RELOP_REG: out_register(ph.regNames[int(op.value)]); break; case TMS_RELOP_IMM: out_symbol('#'); OutValue(op, OOFS_IFSIGN|OOF_SIGNED|OOF_NUMBER|OOFW_IMM); break; } }
static void out_shift(int value) { out_symbol('#'); char buf[8]; qsnprintf(buf, sizeof(buf), "%d", value); out_line(buf,COLOR_DNUM); }
static inline void line_repeat_else () { if (ifdef_line_repeat == StackVectorString_length(ifdef_stack)) { char buf[20]; sprintf(buf,"#line %ld",input_line); out_line(buf); } }
//---------------------------------------------------------------------- static bool out_port_address(ea_t addr) { const char *name = find_port(addr); if ( name != NULL ) { out_line(name, COLOR_IMPNAME); return true; } return false; }
void out_line_prefix(const char *pref, const char* format, va_list args) { char buff[SIZE] = {0}; strcpy(buff, pref); int len = strlen(buff); int i = vsnprintf(buff + len, sizeof(buff) - len, format, args); if (i == -1) buff[SIZE - 1] = 0; out_line(buff, i + len); }
//------------------------------------------------------------------ bool nec_find_ioport_bit(int port, int bit) { //поиск бита из регистра в списке портов const ioport_bit_t *b = find_ioport_bit(ports, numports, port, bit); if ( b != NULL && b->name != NULL ) { //выводим имя бита из регистра out_line(b->name, COLOR_IMPNAME); return true; } return false; }
static void out_operators_begin(op_t &op) { char *strings[TMS_OPERATORS_SIZE] = { "T3=", "!", "uns(", "dbl(", "rnd(", "pair(", "lo(", "hi(", "low_byte(", "high_byte(", "saturate(", "dual(", "port(" }; short operators = (op.tms_operator2 << 8) | (op.tms_operator1 &0xFF); for (int i = 0; i < TMS_OPERATORS_SIZE; i++) if (operators & (1<<i)) out_line(strings[i], COLOR_SYMBOL); }
//---------------------------------------------------------------------- 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); } }
//---------------------------------------------------------------------- void out(void) { char buf[MAXSTR]; static const char *const postfix[] = { "", "b"}; init_output_buffer(buf, sizeof(buf)); OutMnem(8, postfix[cmd.bytecmd]); if(cmd.itype == pdp_compcc) { uint i = 0, code, first = 0; static uint tabcc[8] = {pdp_clc, pdp_clv, pdp_clz, pdp_cln, pdp_sec, pdp_sev, pdp_sez, pdp_sen}; code = cmd.Op1.phrase; out_symbol('<'); if(code >= 020) { if((code ^= 020) == 0) OutLine(COLSTR("nop!^O20", SCOLOR_INSN)); i = 4; } for( ; code; i++, code >>= 1) if(code & 1) { if(first++) out_symbol('!'); out_line(ph.instruc[tabcc[i]].name, COLOR_INSN); } out_symbol('>'); }
//---------------------------------------------------------------------- void OutRegString(bool isWorkingReg, bool isPair, int regNum, int regBit = -1) { char buf[256]; // if it is a working register, output it with an R in front if (isWorkingReg) { if (!isPair) { qsnprintf(buf, sizeof(buf), "R%u", regNum); } else { qsnprintf(buf, sizeof(buf), "RR%u", regNum); } } else { // output either working or non-working reg if (!isPair) { // N.B. working registers start at 0xC0 if (regNum >= 0xC0) { qsnprintf(buf, sizeof(buf), "R%u", regNum - 0xC0); } else { qsnprintf(buf, sizeof(buf), "0%XH", regNum); } } else { // N.B. working registers start at 0xC0 if (regNum >= 0xC0) { qsnprintf(buf, sizeof(buf), "RR%u", regNum - 0xC0); } else { qsnprintf(buf, sizeof(buf), "0%XH", regNum); } } } out_register(buf); // output regBit if requested if (regBit != -1) { qsnprintf(buf, sizeof(buf), ".%i", regBit); out_line(buf, COLOR_DEFAULT); } }
// output an operand bool idaapi outop(op_t &x) { switch ( x.type ) { // register case o_reg: outreg(x.reg); break; // immediate case o_imm: { const ioport_t *port = find_sym(x.value); // this immediate is represented in the .cfg file if ( port != NULL ) { // output the port name instead of the numeric value out_line(port->name, COLOR_IMPNAME); } // otherwise, simply print the value else { out_symbol('#'); OutValue(x, OOFW_IMM|OOF_SIGNED); } } break; // displ @(imm, reg) case o_displ: out_symbol('@'); out_symbol('('); OutValue(x, OOF_SIGNED | OOF_ADDR | OOFW_32); out_symbol(','); OutChar(' '); outreg(x.reg); out_symbol(')'); break; // address case o_near: if ( !out_name_expr(x, toEA(cmd.cs, x.addr), x.addr) ) OutValue(x, OOF_ADDR | OOF_NUMBER | OOFS_NOSIGN | OOFW_32); break; // phrase case o_phrase: switch ( x.specflag1 ) { // @R case fRI: out_symbol('@'); if ( isDefArg(uFlag, x.n) ) { out_symbol('('); OutValue(x, 0); // will print 0 out_symbol(','); OutChar(' '); outreg(x.reg); out_symbol(')'); } else { outreg(x.reg); } break; // @R+ case fRIBA: out_symbol('@'); outreg(x.reg); out_symbol('+'); break; // @+R case fRIAA: out_symbol('@'); out_symbol('+'); outreg(x.reg); break; // @-R case fRIAS: out_symbol('@'); out_symbol('-'); outreg(x.reg); break; } break; } return 1; }
/*------------------------------------------------------------------------- * Function: out_prefix * * Purpose: Prints the prefix which appears at the left of every line * of output. The prefix is printed only if the current * column number is zero. * * Return: void * * Programmer: Robb Matzke * [email protected] * Dec 11 1996 * * Modifications: * * Robb Matzke, 3 Feb 1997 * Added the `silent' attribute to field descriptors. * * Robb Matzke, 3 Feb 1997 * If there is not prefix, then we print just space left of the * equal sign. * * Robb Matzke, 4 Feb 1997 * If two array prefix areas are adjacent then we combine them. * * Robb Matzke, 2000-06-28 * Prints table headers if any. *------------------------------------------------------------------------- */ void out_prefix (out_t *f) { int i, j, k, n, stride; int in_array=false; char buf[256]; if (0==f->col && !out_brokenpipe(f)) { if (isatty (fileno (f->f))) out_progress (NULL); /* Print table headers if any */ if (f->header) { char *header = f->header; f->header = NULL; out_line(f, header); free(header); } /* * Print the field names separated from one another by a dot. */ for (i=0; i<f->nfields; i++) { if (f->field[i].silent) continue; /* * The field name. */ if (f->field[i].name) { if (in_array) { putc (']', f->f); f->col += 1; in_array = false; } if (f->col) { putc ('.', f->f); f->col += 1; } fputs (f->field[i].name, f->f); f->col += strlen (f->field[i].name); } /* * Array indices. */ if (f->field[i].ndims>0) { if (in_array) { fputs (", ", f->f); f->col += 2; } else { putc ('[', f->f); f->col += 1; in_array = true; } n = f->field[i].elmtno; for (j=0; j<f->field[i].ndims; j++) { if (j) { fputs (", ", f->f); f->col += 2; } for (k=j+1,stride=1; k<f->field[i].ndims; k++) { stride *= f->field[i].dim[k]; } sprintf (buf, "%d", f->field[i].offset[j]+n/stride); n %= stride; fputs (buf, f->f); f->col += strlen(buf); } } } if (in_array) { putc (']', f->f); f->col += 1; in_array = false; } /* * Print the equal sign so the value starts not earlier than * the left margin. */ if (f->col+1>=OUT_LTMAR) { fputs ("=", f->f); f->col += 1; } else { fprintf (f->f, "%*s= ", OUT_LTMAR-(f->col+2), ""); f->col = OUT_LTMAR; } /* * Print the indentation */ n = OUT_LTMAR + f->indent*OUT_INDENT - f->col; if (n>0) { fprintf (f->f, "%*s", n, ""); f->col += n; } } }
void __stdcall out( void ) { char buf[MAXSTR]; init_output_buffer(buf, sizeof(buf)); OutMnem(); if (cmd.Op1.type != o_void) { // output first operand out_one_operand( 0 ); } if( cmd.Op2.type != o_void ) { //pading out_symbol( ',' ); OutChar( ' ' ); // output second operand out_one_operand( 1 ); } if( cmd.Op3.type != o_void ) { //pading out_symbol( ',' ); OutChar( ' ' ); // output third operand out_one_operand( 2 ); } if( cmd.Op4.type != o_void ) { //pading out_symbol( ',' ); OutChar( ' ' ); // output fourth operand out_one_operand( 3 ); } if( cmd.Op5.type != o_void ) { //pading out_symbol( ',' ); OutChar( ' ' ); // output fifth operand out_one_operand( 4 ); } if( cmd.Op6.type != o_void ) { //pading out_symbol( ',' ); OutChar( ' ' ); // output sixth operand out_one_operand( 5 ); } //more processing due to instructions //having more than 6 operands op_t op; op.flags = OF_SHOW; switch(cmd.insnpref) { case SWFACTION_PUSH: { uint16 length = get_word(cmd.ea + 1) + 3; uint16 p = cmd.auxpref; uint8 error = 0; while((length - p) > 0 && error == 0) { switch(get_byte(cmd.ea + p++)) { case 0: //string op.type = o_string; op.dtyp = dt_string; op.addr = cmd.ea + p; //increment the pointer past the string while((length - p) > 0 && get_byte(cmd.ea + p)){ p++; } if ((length - p) > 0) { p++; //adjust for the null caracter } else { error = 1; } break; case 1: //float op.type = o_imm; //op.dtyp = dt_float; op.dtyp = dt_dword; if ((length - p) >= 4) { op.value = get_long(cmd.ea + p); p += 4; } else { error = 1; } break; case 2: //null op.type = o_null; op.dtyp = dt_void; break; case 3: //undefined op.type = o_undefined; op.dtyp = dt_void; break; case 4: //register op.type = o_reg; op.dtyp = dt_byte; if ((length - p) >= 1) { op.reg = get_byte(cmd.ea + p++); } else { error = 1; } break; case 5: //bool op.type = o_bool; op.dtyp = dt_byte; if ((length - p) >= 1) { op.value = get_byte(cmd.ea + p++); } else { error = 1; } break; case 6: //double op.type = o_imm; op.dtyp = dt_double; if ((length - p) >= 8) { double d = (double)(get_qword(cmd.ea + p)); op.value = d; p += 8; } else { error = 1; } break; case 7: //integer op.type = o_imm; op.dtyp = dt_dword; if ((length - p) >= 4) { op.value = get_long(cmd.ea + p); p += 4; } else { error = 1; } break; case 8: //constant 8 op.type = o_const; op.dtyp = dt_byte; if ((length - p) >= 1) { op.value = get_byte(cmd.ea + p++); } else { error = 1; } break; case 9: //constant 16 op.type = o_const; op.dtyp = dt_word; if ((length - p) >= 2) { op.value = get_word(cmd.ea + p); p += 2; } else { error = 1; } default: //unknown type, will not search for more items if this happens error = 1; } //switch if (error == 0) { //pading out_symbol( ',' ); OutChar( ' ' ); // output extra operand outop(op); } } //while } //case break; case SWFACTION_TRY: //ToDo break; case SWFACTION_DEFINEFUNCTION: // Todo: highlight somehow the function body // this must be written some other place because // every time IDA rephreshes the view a duplicate line appears. :( //describe(cmd.ea + cmd.size, true, "%s {", cmd.segpref ? (char*)cmd.Op1.addr : "<anonymous>"); //describe(cmd.ea + cmd.size + get_word(cmd.ea + cmd.size - 2), true, " }"); break; default:; } term_output_buffer(); // attach a possible user-defined comment to this instruction gl_comm = 1; MakeLine( buf ); //multiline instruction printing switch (cmd.insnpref) { case SWFACTION_CONSTANTPOOL: { uint16 length = get_word(cmd.ea + 1); uint8 c = 0, count = 0; if(cmd.Op1.value == 0) break; //limit printed lines to 499 //IDA does not suport more than 500 per item if (cmd.Op1.value > 498) { cmd.Op1.value = 498; msg ("\nWarning: CONSTANTPOOL instruction ar %X has more that 498 declared constants!\n", cmd.ea); } char line[MAXSTR], buf[MAXSTR]; init_output_buffer(line, sizeof(line)); OutChar( ' ' ); out_char('0', COLOR_NUMBER); out_line(": \"",COLOR_SYMBOL); for (uint16 i = 2; i < length; i++) { c = get_byte(cmd.ea + i + 3); if (c == 0) { if (count++ < (cmd.Op1.value - 1)) { out_line("\"", COLOR_SYMBOL); //terminate buffer for current constant //and print it term_output_buffer(); MakeLine(line); //initialize buffer for next constant init_output_buffer(line, sizeof(line)); OutChar( ' ' ); qsnprintf(buf, MAXSTR, "%d", count); out_line(buf, COLOR_NUMBER); out_line(": \"", COLOR_SYMBOL); } else break; } else { if (is_printable(c)) out_char(c, COLOR_CHAR); else { qsnprintf(buf, MAXSTR, "\\x%02X", c); out_line(buf, COLOR_STRING); } }//else }//for out_char('"',COLOR_SYMBOL); //terminate buffer for last constant //and print it term_output_buffer(); MakeLine(line); } break; } }
bool __stdcall outop( op_t &x ) { char buf[MAXSTR]; switch( x.type ) { case o_imm: { switch(cmd.insnpref) { case SWFACTION_GETURL2: { switch(x.specflag1) { case 'M': if (x.value == 2) out_keyword("method:POST"); else x.value?out_keyword("method:GET"):out_keyword("method:none"); break; case 'T': x.value?out_keyword("target:sprite"):out_keyword("target:browser"); break; case 'V': x.value?out_keyword("vars:load"):out_keyword("vars:no"); } } break; case SWFACTION_CONSTANTPOOL: OutValue( x, OOFW_IMM ); break; case SWFACTION_GOTOFRAME2: if (x.n == 0) { x.value?out_keyword("play:yes"):out_keyword("play:no"); } else { OutValue( x, OOFW_IMM ); } break; case SWFACTION_DEFINEFUNCTION2: if (x.n == 5) { //output the parameters first uint16 p = cmd.auxpref, i = 0; uint16 param_length = get_word(cmd.ea + 1) - p -2; out_char('{', COLOR_SYMBOL); while (i < param_length) { uint8 reg = get_byte(cmd.ea + 3 + p + i); char* reg_name = buf; *reg_name = 0; while ((i++ < param_length) && ((*(reg_name++) = get_byte(cmd.ea + 3 + p + i))!= 0)) {;} i++; if (reg_name > buf && *(--reg_name) == 0) { char r[6]; out_char('{', COLOR_SYMBOL); if (reg) { qsnprintf(r, 5, "r%u", reg); out_register( r ); } else { out_char('0', COLOR_NUMBER); } out_line(",\"", COLOR_SYMBOL); out_line(buf, COLOR_CHAR); out_line("\"}, ", COLOR_SYMBOL); }//if }//while out_line("}, ", COLOR_SYMBOL); } OutValue( x, OOFW_IMM ); break; default: OutValue( x, OOFW_IMM ); } } break; case o_reg: qsnprintf(buf, MAXSTR, "r%u", x.reg); out_register( buf ); break; case o_near: if( !out_name_expr(x, x.addr, x.addr) ) { // if we could not create and output a name expression from the address OutValue(x, OOF_ADDR | OOF_NUMBER | OOFW_32); // instead output a raw value QueueMark(Q_noName, cmd.ea); //and mark this as a problem } break; case o_null: out_keyword("null"); break; case o_undefined: out_keyword("undefined"); break; case o_bool: x.value?out_keyword("true"):out_keyword("false"); break; case o_const: out_keyword("constant:"); OutValue( x, OOFW_IMM ); break; case o_string: { uint16 p = 0; char c; out_char('"', COLOR_SYMBOL); while ((c = get_byte(x.addr+p)) != 0) { if (is_printable(c)) { out_char(c, COLOR_CHAR); } else { qsnprintf(buf, MAXSTR, "\\x%02X", c); out_line(buf, COLOR_STRING); } p++; } out_char('"', COLOR_SYMBOL); } break; case o_void: return 0; default: warning( "out: %lx: bad optype %d", cmd.ea, x.type ); } return 1; }
void out_char (char c, color_t t) { char str[]={c, 0}; out_line(str, t); }
//---------------------------------------------------------------------- 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) { ea_t ea; switch ( x.type ) { case o_void: return 0; case o_reg: out_register(ph.regNames[x.reg]); break; case o_near: case o_far: out_address(calc_code_mem(x.addr, x.type == o_near), x, false, false); break; case o_imm: { const char *name = NULL; if ( idpflags & TMS320C54_IO && x.IOimm ) name = find_sym(x.value); if ( !x.NoCardinal ) out_symbol('#'); if ( name != NULL ) { out_line(name, COLOR_IMPNAME); } else { if ( !x.Signed ) OutValue(x, OOFW_IMM); else OutValue(x, OOFS_IFSIGN|OOF_SIGNED|OOF_NUMBER|OOFW_IMM); } break; } case o_local: OutValue(x, OOFW_IMM|OOF_ADDR); break; case o_mmr: case o_mem: case o_farmem: if ( x.IndirectAddressingMOD == ABSOLUTE_INDIRECT_ADRESSING ) { out_symbol('*'); out_symbol('('); } ea = calc_data_mem(x.addr, x.type == o_mem); if ( ea != BADADDR ) out_address(ea, x, true, x.IndirectAddressingMOD != ABSOLUTE_INDIRECT_ADRESSING); // no '@' if absolute "indirect" adressing else OutValue(x, OOFW_IMM|OOF_ADDR); if ( x.IndirectAddressingMOD == ABSOLUTE_INDIRECT_ADRESSING ) out_symbol(')'); break; case o_displ: // Indirect addressing mode { const char *reg = ph.regNames[x.reg]; char buf[8]; switch ( x.IndirectAddressingMOD ) { case 0: qsnprintf(buf, sizeof(buf), "*%s",reg); out_register(buf); break; case 1: qsnprintf(buf, sizeof(buf), "*%s-",reg); out_register(buf); break; case 2: qsnprintf(buf, sizeof(buf), "*%s+",reg); out_register(buf); break; case 3: qsnprintf(buf, sizeof(buf), "*+%s",reg); out_register(buf); break; case 4: qsnprintf(buf, sizeof(buf), "*%s-0B",reg); out_register(buf); break; case 5: qsnprintf(buf, sizeof(buf), "*%s-0",reg); out_register(buf); break; case 6: qsnprintf(buf, sizeof(buf), "*%s+0",reg); out_register(buf); break; case 7: qsnprintf(buf, sizeof(buf), "*%s+0B",reg); out_register(buf); break; case 8: qsnprintf(buf, sizeof(buf), "*%s-%%",reg); out_register(buf); break; case 9: qsnprintf(buf, sizeof(buf), "*%s-0%%",reg); out_register(buf); break; case 0xA: qsnprintf(buf, sizeof(buf), "*%s+%%",reg); out_register(buf); break; case 0xB: qsnprintf(buf, sizeof(buf), "*%s+0%%",reg); out_register(buf); break; case 0xC: qsnprintf(buf, sizeof(buf), "*%s(",reg); out_register(buf); OutValue(x, OOF_ADDR|OOF_SIGNED|OOFW_16); out_symbol(')'); break; case 0xD: qsnprintf(buf, sizeof(buf), "*+%s(",reg); out_register(buf); OutValue(x, OOF_ADDR|OOF_SIGNED|OOFW_16); out_symbol(')'); break; case 0xE: qsnprintf(buf, sizeof(buf), "*+%s(",reg); out_register(buf); OutValue(x, OOF_ADDR|OOF_SIGNED|OOFW_16); out_symbol(')'); out_symbol('%'); break; // this special adressing mode is now defined as o_farmem ! // case ABSOLUTE_INDIRECT_ADRESSING: // out_symbol('*'); // out_symbol('('); // OutValue(x, OOF_ADDR|OOF_SIGNED|OOFW_16); // out_symbol(')'); // break; default: error("interr: out: o_displ"); } break; } case o_bit: { if ( !x.NoCardinal ) out_symbol('#'); char buf[20]; qsnprintf(buf, sizeof(buf), "%d", int(x.value)); out_line(buf,COLOR_REG); break; } case o_cond8: out_cond8((uchar)x.value); break; case o_cond2: { const char *cond = ""; switch ( x.value ) { case 0: cond = "eq"; break; case 1: cond = "lt"; break; case 2: cond = "gt"; break; case 3: cond = "neq"; break; default: warning("interr: out 2-bit condition"); } out_line(cond, COLOR_REG); break; } default: error("interr: out"); break; } return 1; }
static void out_cond8(char value) { const char *cond = get_cond8(value); QASSERT(256, cond != NULL) ; out_line(cond, COLOR_REG); }
//---------------------------------------------------------------------- bool idaapi outop(op_t &x) { uval_t v; switch ( x.type ) { case o_imm: out_symbol('#'); OutValue(x, OOFW_IMM); break; case o_ind_reg: out_symbol('@'); case o_reg: OutReg(x.reg); break; case o_phrase: //ig: лучше out_keyword, чем простой OutLine() // так цвет будет правильный out_keyword(phrases[x.phrase]); break; case o_displ: OutValue(x, OOF_ADDR | OOFW_IMM); // x.addr out_symbol('('); OutReg(x.reg); out_symbol(')'); break; case o_ind_mem: out_symbol('@'); case o_mem: case o_near: v = map_addr(x.addr, x.n, x.type != o_near); if ( !out_name_expr(x, v, x.addr) ) { const char *name = z8_find_ioport(v); if ( name != NULL ) { out_line(name, COLOR_IMPNAME); } else { OutValue(x, OOF_ADDR | OOF_NUMBER | OOFS_NOSIGN | OOFW_16); QueueSet(Q_noName, cmd.ea); } } break; case o_void: return 0; default: warning("out: %a: bad optype %d", cmd.ea, x.type); } return 1; }
int dline_add(dline_t * dl, ea_t ea, char options) { char buf[256]; char tmp[256]; char dis[256]; char addr[30]; char * dll; int len; flags_t f; buf[0] = '\0'; f = getFlags(ea); generate_disasm_line(ea, dis, sizeof(dis)); decode_insn(ea); init_output_buffer(buf, sizeof(buf)); // Adds block label if (has_dummy_name(f)) { get_nice_colored_name(ea,tmp,sizeof(tmp),GNCN_NOSEG|GNCN_NOFUNC); out_snprintf("%s", tmp); out_line(":\n", COLOR_DATNAME); } if (options) { qsnprintf(addr, sizeof(addr), "%a", ea); out_snprintf("%s ", addr); } out_insert(get_output_ptr(), dis); term_output_buffer(); len = strlen(buf); if (dl->available < (len+3)) { dll = (char *)qrealloc(dl->lines, sizeof(char*) * (dl->num+len+256)); if (!dll) return -1; dl->available = len+256; dl->lines = dll; } if (dl->num) { dl->lines[dl->num] = '\n'; dl->num++; } memcpy(&dl->lines[dl->num], buf, len); dl->available -= len+1; dl->num += len; dl->lines[dl->num] = '\0'; return 0; }
static void out_cond(op_t &x) { char *reg = ph.regNames[x.reg]; switch(x.value) { case 0x00: out_register(reg); out_line(" == #", COLOR_SYMBOL); out_long(0, 10); break; case 0x10: out_register(reg); out_line(" != #", COLOR_SYMBOL); out_long(0, 10); break; case 0x20: out_register(reg); out_line(" < #", COLOR_SYMBOL); out_long(0, 10); break; case 0x30: out_register(reg); out_line(" <= #", COLOR_SYMBOL); out_long(0, 10); break; case 0x40: out_register(reg); out_line(" > #", COLOR_SYMBOL); out_long(0, 10); break; case 0x50: out_register(reg); out_line(" >= #", COLOR_SYMBOL); out_long(0, 10); break; case 0x60: out_line("overflow(", COLOR_SYMBOL); out_register(reg); out_symbol(')'); break; case 0x64: out_register(ph.regNames[TC1]); break; case 0x65: out_register(ph.regNames[TC2]); break; case 0x66: out_register(ph.regNames[CARRY]); break; case 0x68: out_register(ph.regNames[TC1]); out_line(" & ", COLOR_SYMBOL); out_register(ph.regNames[TC2]); break; case 0x69: out_register(ph.regNames[TC1]); out_line(" & !", COLOR_SYMBOL); out_register(ph.regNames[TC2]); break; case 0x6A: out_symbol('!'); out_register(ph.regNames[TC1]); out_line(" & ", COLOR_SYMBOL); out_register(ph.regNames[TC2]); break; case 0x6B: out_symbol('!'); out_register(ph.regNames[TC1]); out_line(" & !", COLOR_SYMBOL); out_register(ph.regNames[TC2]); break; case 0x70: out_line("!overflow(", COLOR_SYMBOL); out_register(reg); out_symbol(')'); break; case 0x74: out_symbol('!'); out_register(ph.regNames[TC1]); break; case 0x75: out_symbol('!'); out_register(ph.regNames[TC2]); break; case 0x76: out_symbol('!'); out_register(ph.regNames[CARRY]); break; case 0x78: out_register(ph.regNames[TC1]); out_line(" | ", COLOR_SYMBOL); out_register(ph.regNames[TC2]); break; case 0x79: out_register(ph.regNames[TC1]); out_line(" | !", COLOR_SYMBOL); out_register(ph.regNames[TC2]); break; case 0x7A: out_symbol('!'); out_register(ph.regNames[TC1]); out_line(" | ", COLOR_SYMBOL); out_register(ph.regNames[TC2]); break; case 0x7B: out_symbol('!'); out_register(ph.regNames[TC1]); out_line(" | !", COLOR_SYMBOL); out_register(ph.regNames[TC2]); break; case 0x7C: out_register(ph.regNames[TC1]); out_line(" ^ ", COLOR_SYMBOL); out_register(ph.regNames[TC2]); break; case 0x7D: out_register(ph.regNames[TC1]); out_line(" ^ !", COLOR_SYMBOL); out_register(ph.regNames[TC2]); break; case 0x7E: out_symbol('!'); out_register(ph.regNames[TC1]); out_line(" ^ ", COLOR_SYMBOL); out_register(ph.regNames[TC2]); break; case 0x7F: out_symbol('!'); out_register(ph.regNames[TC1]); out_line(" ^ !", COLOR_SYMBOL); out_register(ph.regNames[TC2]); break; default: error("interr: out: o_cond"); } }
// Output an operand bool outop(op_t &op) { switch ( op.type ) { // Data / Code memory address case o_near: case o_mem: BEG_TAG(op); out_addr(op); END_TAG(op); break; // Immediate value case o_imm: BEG_TAG(op); { const ioport_t * port = find_sym(op.value); // this immediate is represented in the .cfg file if ( port != NULL ) // output the port name instead of the numeric value out_line(port->name, COLOR_IMPNAME); // otherwise, simply print the value else out_imm(op); } END_TAG(op); break; // Displacement case o_displ: out_addr(op, false); out_symbol('('); out_reg(op); out_symbol(')'); break; // Register case o_reg: BEG_TAG(op); out_reg(op); END_TAG(op); if ( is_reg_with_bit(op) ) { out_symbol('.'); if ( is_bit_compl(op) ) out_symbol('!'); out_imm(op, true); } break; // Phrase case o_phrase: switch ( op.specflag2 ) { case fPI: // post increment out_symbol('('); out_reg(op); out_symbol(')'); out_symbol('+'); break; case fPD: // pre decrement out_symbol('-'); out_symbol('('); out_reg(op); out_symbol(')'); break; case fDISP: // displacement out_reg(op); out_symbol('('); { ushort reg = op.specflag2 << 8; reg |= op.specflag3; out_reg(reg); } out_symbol(')'); break; default: IDA_ERROR("Invalid phrase type in outop()"); } break; // No operand case o_void: break; default: IDA_ERROR("Invalid op.type in outop()"); } return 1; }
//---------------------------------------------------------------------- void idaapi out(void) { char buf[MAXSTR]; init_output_buffer(buf, sizeof(buf)); OutMnem(); out_one_operand(0); if ( cmd.Op2.type != o_void ) { out_symbol(','); OutChar(' '); out_one_operand(1); if ( cmd.IsParallel ) { // new line for Parallel instructions term_output_buffer(); MakeLine(buf); init_output_buffer(buf, sizeof(buf)); out_line("|| ", COLOR_INSN); const char *insn2 = NULL; switch ( cmd.itype ) { case TMS320C54_ld_mac: insn2 = "mac "; break; case TMS320C54_ld_macr: insn2 = "macr "; break; case TMS320C54_ld_mas: insn2 = "mas "; break; case TMS320C54_ld_masr: insn2 = "masr "; break; case TMS320C54_st_add: insn2 = "add "; break; case TMS320C54_st_sub: insn2 = "sub "; break; case TMS320C54_st_ld: insn2 = "ld "; break; case TMS320C54_st_mpy: insn2 = "mpy "; break; case TMS320C54_st_mac: insn2 = "mac "; break; case TMS320C54_st_macr: insn2 = "macr "; break; case TMS320C54_st_mas: insn2 = "mas "; break; case TMS320C54_st_masr: insn2 = "masr "; break; default: warning("interr: out parallel instruction"); } out_line(insn2, COLOR_INSN); } if ( cmd.Op3.type != o_void ) { if ( !cmd.IsParallel ) { out_symbol(','); OutChar(' '); } out_one_operand(2); if ( cmd.Op4_type != 0 ) { out_symbol(','); OutChar(' '); switch ( cmd.Op4_type ) { case o_reg: out_register(ph.regNames[cmd.Op4_value]); break; case o_cond8: out_cond8(cmd.Op4_value); break; default: break; } } } } if ( isVoid(cmd.ea, uFlag, 0) ) OutImmChar(cmd.Op1); if ( isVoid(cmd.ea, uFlag, 1) ) OutImmChar(cmd.Op2); if ( isVoid(cmd.ea, uFlag, 2) ) OutImmChar(cmd.Op3); term_output_buffer(); gl_comm = 1; MakeLine(buf); }
static void out_reg(op_t &op) { char *reg = ph.regNames[op.reg]; switch(op.tms_modifier) { case TMS_MODIFIER_NULL: out_register(reg); break; case TMS_MODIFIER_REG: out_symbol('*'); out_register(reg); break; case TMS_MODIFIER_REG_P: out_symbol('*'); out_register(reg); out_symbol('+'); break; case TMS_MODIFIER_REG_M: out_symbol('*'); out_register(reg); out_symbol('-'); break; case TMS_MODIFIER_REG_P_T0: out_line("*(", COLOR_SYMBOL); out_register(reg); out_symbol('+'); out_register(ph.regNames[T0]); out_symbol(')'); break; case TMS_MODIFIER_REG_P_T1: out_line("*(", COLOR_SYMBOL); out_register(reg); out_symbol('+'); out_register(ph.regNames[T1]); out_symbol(')'); break; case TMS_MODIFIER_REG_M_T0: out_line("*(", COLOR_SYMBOL); out_register(reg); out_symbol('-'); out_register(ph.regNames[T0]); out_symbol(')'); break; case TMS_MODIFIER_REG_M_T1: out_line("*(", COLOR_SYMBOL); out_register(reg); out_symbol('-'); out_register(ph.regNames[T1]); out_symbol(')'); break; case TMS_MODIFIER_REG_T0: out_symbol('*'); out_register(reg); out_symbol('('); out_register(ph.regNames[T0]); out_symbol(')'); break; case TMS_MODIFIER_REG_OFFSET: case TMS_MODIFIER_P_REG_OFFSET: out_symbol('*'); if (op.tms_modifier == TMS_MODIFIER_P_REG_OFFSET) out_symbol('+'); out_register(reg); out_line("(#", COLOR_SYMBOL); OutValue(op, OOFS_IFSIGN|OOF_SIGNED|OOF_NUMBER|OOFW_IMM); out_symbol(')'); break; case TMS_MODIFIER_REG_SHORT_OFFSET: out_symbol('*'); out_register(reg); out_line("(short(#", COLOR_SYMBOL); OutValue(op, OOFS_IFSIGN|OOF_SIGNED|OOF_NUMBER|OOFW_IMM); out_line("))", COLOR_SYMBOL); break; case TMS_MODIFIER_REG_T1: out_symbol('*'); out_register(reg); out_symbol('('); out_register(ph.regNames[T1]); out_symbol(')'); break; case TMS_MODIFIER_P_REG: out_symbol('+'); out_register(reg); break; case TMS_MODIFIER_M_REG: out_symbol('-'); out_register(reg); break; case TMS_MODIFIER_REG_P_T0B: out_line("*(", COLOR_SYMBOL); out_register(reg); out_symbol('+'); out_register("T0B"); out_symbol(')'); break; case TMS_MODIFIER_REG_M_T0B: out_line("*(", COLOR_SYMBOL); out_register(reg); out_symbol('-'); out_register("T0B"); out_symbol(')'); break; default: error("interr: out: o_reg: modifier"); } }