update to ida 7.6, add builds
This commit is contained in:
386
idasdk76/module/pdp11/out.cpp
Normal file
386
idasdk76/module/pdp11/out.cpp
Normal file
@@ -0,0 +1,386 @@
|
||||
/*
|
||||
* Interactive disassembler (IDA)
|
||||
* Copyright (c) 1990-98 by Ilfak Guilfanov.
|
||||
* E-mail: ig@datarescue.com
|
||||
* PDP11 module.
|
||||
* Copyright (c) 1995-2006 by Iouri Kharon.
|
||||
* E-mail: yjh@styx.cabel.net
|
||||
*
|
||||
* ALL RIGHTS RESERVED.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pdp.hpp"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
class out_pdp_t : public outctx_t
|
||||
{
|
||||
out_pdp_t(void) = delete; // not used
|
||||
pdp11_t &pm() { return *static_cast<pdp11_t *>(procmod); }
|
||||
public:
|
||||
void OutReg(int rgnum) { out_register(ph.reg_names[rgnum]); }
|
||||
bool out_operand(const op_t &x);
|
||||
void out_insn(void);
|
||||
void out_proc_mnem(void);
|
||||
};
|
||||
CASSERT(sizeof(out_pdp_t) == sizeof(outctx_t));
|
||||
|
||||
DECLARE_OUT_FUNCS(out_pdp_t)
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
bool out_pdp_t::out_operand(const op_t &x)
|
||||
{
|
||||
ea_t segadr;
|
||||
switch ( x.type )
|
||||
{
|
||||
case o_void:
|
||||
return 0;
|
||||
case o_reg:
|
||||
OutReg(x.reg);
|
||||
break;
|
||||
case o_fpreg:
|
||||
OutReg(x.reg + 8);
|
||||
break;
|
||||
case o_imm: // 27
|
||||
if ( x.ill_imm )
|
||||
{
|
||||
out_symbol('(');
|
||||
OutReg(rPC);
|
||||
out_symbol(')');
|
||||
out_symbol('+');
|
||||
}
|
||||
else
|
||||
{
|
||||
out_symbol('#');
|
||||
if ( x.dtype == dt_float || x.dtype == dt_double )
|
||||
{
|
||||
char str[MAXSTR];
|
||||
if ( print_fpval(str, sizeof(str), &x.value, 2) )
|
||||
{
|
||||
char *p = str;
|
||||
while ( *p == ' ' )
|
||||
p++;
|
||||
out_symbol('^');
|
||||
out_symbol('F');
|
||||
out_line(p, COLOR_NUMBER);
|
||||
}
|
||||
else
|
||||
{
|
||||
out_long(x.value, 8);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
out_value(x, OOF_SIGNED | OOFW_IMM);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case o_mem: // 37/67/77
|
||||
case o_near: // jcc/ [jmp/call 37/67]
|
||||
case o_far:
|
||||
if ( x.phrase != 0 )
|
||||
{
|
||||
if ( x.phrase == 077 || x.phrase == 037 )
|
||||
out_symbol('@');
|
||||
if ( x.phrase == 037 )
|
||||
out_symbol('#');
|
||||
if ( x.addr16 < pm().ml.asect_top && !is_off(F, x.n) )
|
||||
{
|
||||
out_value(x, OOF_ADDR | OOF_NUMBER | OOFS_NOSIGN | OOFW_16);
|
||||
break;
|
||||
}
|
||||
}
|
||||
segadr = x.type == o_far
|
||||
? to_ea(x.segval, x.addr16)
|
||||
: map_code_ea(insn, x.addr16, x.n);
|
||||
if ( !out_name_expr(x, segadr, x.addr16) )
|
||||
{
|
||||
if ( x.type == o_far || x.addr16 < 0160000 )
|
||||
remember_problem(PR_NONAME, insn.ea);
|
||||
out_value(x, OOF_ADDR | OOF_NUMBER | OOFS_NOSIGN | OOFW_16);
|
||||
}
|
||||
break;
|
||||
case o_number: // EMT/TRAP/MARK/SPL
|
||||
out_value(x, OOF_NUMBER | OOFS_NOSIGN | OOFW_8);
|
||||
break;
|
||||
case o_displ: // 6x/7x (!67/!77)
|
||||
if ( x.phrase >= 070 )
|
||||
out_symbol('@');
|
||||
out_value(x, OOF_ADDR | OOF_SIGNED | OOFW_16);
|
||||
out_symbol('(');
|
||||
goto endregout;
|
||||
case o_phrase: // 1x/2x/3x/4x/5x (!27/!37)
|
||||
switch ( x.phrase >> 3 )
|
||||
{
|
||||
case 1:
|
||||
out_symbol('@');
|
||||
OutReg(x.phrase & 7);
|
||||
break;
|
||||
case 3:
|
||||
out_symbol('@');
|
||||
// fallthrough
|
||||
case 2:
|
||||
out_symbol('(');
|
||||
OutReg(x.phrase & 7);
|
||||
out_symbol(')');
|
||||
out_symbol('+');
|
||||
break;
|
||||
case 5:
|
||||
out_symbol('@');
|
||||
// fallthrough
|
||||
case 4:
|
||||
out_symbol('-');
|
||||
out_symbol('(');
|
||||
endregout:
|
||||
OutReg(x.phrase & 7);
|
||||
out_symbol(')');
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
warning("out: %" FMT_EA "o: bad optype %d", insn.ip, x.type);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void out_pdp_t::out_proc_mnem(void)
|
||||
{
|
||||
static const char *const postfix[] = { "", "b" };
|
||||
out_mnem(8, postfix[insn.bytecmd]);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void out_pdp_t::out_insn(void)
|
||||
{
|
||||
out_mnemonic();
|
||||
if ( insn.itype == pdp_compcc )
|
||||
{
|
||||
uint i = 0, code, first = 0;
|
||||
static const uint tabcc[8] =
|
||||
{
|
||||
pdp_clc, pdp_clv, pdp_clz, pdp_cln,
|
||||
pdp_sec, pdp_sev, pdp_sez, pdp_sen
|
||||
};
|
||||
code = insn.Op1.phrase;
|
||||
out_symbol('<');
|
||||
if ( code >= 020 )
|
||||
{
|
||||
if ( (code ^= 020) == 0 )
|
||||
out_line(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('>');
|
||||
}
|
||||
|
||||
out_one_operand(0);
|
||||
|
||||
if ( insn.Op2.type != o_void )
|
||||
{
|
||||
out_symbol(',');
|
||||
out_char(' ');
|
||||
out_one_operand(1);
|
||||
}
|
||||
|
||||
out_immchar_cmts();
|
||||
flush_outbuf();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void idaapi pdp_header(outctx_t &ctx)
|
||||
{
|
||||
ctx.gen_header(GH_PRINT_ALL_BUT_BYTESEX);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//lint -esym(1764, ctx) could be made const
|
||||
//lint -esym(818, seg) could be made const
|
||||
void pdp11_t::pdp_segstart(outctx_t &ctx, segment_t *seg)
|
||||
{
|
||||
if ( seg->type == SEG_IMEM )
|
||||
{
|
||||
ctx.flush_buf(COLSTR(".ASECT", SCOLOR_ASMDIR), DEFAULT_INDENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
qstring sname;
|
||||
get_visible_segm_name(&sname, seg);
|
||||
ctx.out_printf(COLSTR(".PSECT %s", SCOLOR_ASMDIR), sname.c_str());
|
||||
if ( seg->ovrname != 0 )
|
||||
{
|
||||
char bseg[MAX_NUMBUF];
|
||||
char breg[MAX_NUMBUF];
|
||||
btoa(bseg, sizeof(bseg), seg->ovrname & 0xFFFF, 10);
|
||||
btoa(breg, sizeof(breg), seg->ovrname >> 16, 10);
|
||||
ctx.out_printf(
|
||||
COLSTR(" %s Overlay Segment %s, Region %s", SCOLOR_AUTOCMT),
|
||||
ash.cmnt, bseg, breg);
|
||||
}
|
||||
ctx.flush_outbuf(0);
|
||||
}
|
||||
|
||||
if ( (inf_get_outflags() & OFLG_GEN_ORG) != 0 )
|
||||
{
|
||||
size_t org = size_t(ctx.insn_ea-get_segm_base(seg));
|
||||
if ( org != 0 && org != ml.asect_top && seg->comorg() )
|
||||
{
|
||||
ctx.out_tagon(COLOR_ASMDIR);
|
||||
ctx.out_line(ash.origin);
|
||||
ctx.out_line(ash.a_equ);
|
||||
if ( seg->type != SEG_IMEM )
|
||||
{
|
||||
ctx.out_line(ash.origin);
|
||||
ctx.out_char('+');
|
||||
}
|
||||
ctx.out_btoa(org);
|
||||
ctx.out_tagoff(COLOR_ASMDIR);
|
||||
ctx.flush_outbuf(DEFAULT_INDENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void pdp11_t::pdp_footer(outctx_t &ctx) const
|
||||
{
|
||||
if ( ash.end != NULL )
|
||||
{
|
||||
ctx.gen_empty_line();
|
||||
ctx.out_line(ash.end, COLOR_ASMDIR);
|
||||
qstring name;
|
||||
if ( get_colored_name(&name, inf_get_start_ea()) > 0 )
|
||||
{
|
||||
size_t i = strlen(ash.end);
|
||||
do
|
||||
ctx.out_char(' ');
|
||||
while ( ++i < 8 );
|
||||
ctx.out_line(name.begin());
|
||||
}
|
||||
ctx.flush_outbuf(DEFAULT_INDENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx.gen_cmt_line("end of file");
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
bool pdp11_t::out_equ(outctx_t &ctx, ea_t ea) const
|
||||
{
|
||||
segment_t *s = getseg(ea);
|
||||
char buf[MAXSTR];
|
||||
if ( s != NULL )
|
||||
{
|
||||
if ( s->type != SEG_IMEM && !is_loaded(ea) )
|
||||
{
|
||||
char num[MAX_NUMBUF];
|
||||
btoa(num, sizeof(num), get_item_size(ea));
|
||||
nowarn_qsnprintf(buf, sizeof(buf), ash.a_bss, num);
|
||||
ctx.flush_buf(buf);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void pdp11_t::pdp_data(outctx_t &ctx, bool analyze_only) const
|
||||
{
|
||||
char buf[MAXSTR];
|
||||
ushort v[5];
|
||||
ea_t endea;
|
||||
ushort i, j;
|
||||
|
||||
ea_t ea = ctx.insn_ea;
|
||||
if ( out_equ(ctx, ea) )
|
||||
return;
|
||||
|
||||
i = 0;
|
||||
flags_t F = ctx.F;
|
||||
if ( !is_unknown(F) )
|
||||
{
|
||||
if ( is_word(F) && get_radix(F,0) == 16 )
|
||||
i = 2;
|
||||
else if ( is_dword(F) )
|
||||
i = 4;
|
||||
else if ( is_qword(F) )
|
||||
i = 8;
|
||||
else if ( is_tbyte(F) )
|
||||
i = 10;
|
||||
if ( i == 0 )
|
||||
{
|
||||
ctx.out_data(analyze_only);
|
||||
return;
|
||||
}
|
||||
|
||||
int radix = get_radix(F, 0);
|
||||
endea = get_item_end(ea);
|
||||
for ( ; ea < endea; ea += i )
|
||||
{
|
||||
memset(v, 0, sizeof(v));
|
||||
if ( get_bytes(v, i, ea) != i || r50_to_asc(buf, v, i/2) != 0 )
|
||||
{
|
||||
ctx.out_keyword(".word ");
|
||||
for ( j = 0; j < i/2; j++ )
|
||||
{
|
||||
if ( j )
|
||||
ctx.out_symbol(',');
|
||||
btoa(buf, sizeof(buf), v[j], radix);
|
||||
ctx.out_line(buf, COLOR_NUMBER);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx.out_keyword(".rad50 ");
|
||||
ctx.out_tagon(COLOR_CHAR);
|
||||
ctx.out_char('/');
|
||||
ctx.out_line(buf);
|
||||
ctx.out_char('/');
|
||||
ctx.out_tagoff(COLOR_CHAR);
|
||||
}
|
||||
if ( ctx.flush_outbuf() )
|
||||
return; // too many lines
|
||||
}
|
||||
return;
|
||||
}
|
||||
// unknown
|
||||
if ( !is_loaded(ea) )
|
||||
{
|
||||
ctx.flush_buf(COLSTR(".blkb", SCOLOR_KEYWORD));
|
||||
}
|
||||
else
|
||||
{
|
||||
uchar c = get_byte(ea);
|
||||
|
||||
char cbuf[MAX_NUMBUF];
|
||||
btoa(cbuf, sizeof(cbuf), c);
|
||||
ctx.out_printf(COLSTR(".byte ", SCOLOR_KEYWORD)
|
||||
COLSTR("%4s ", SCOLOR_DNUM)
|
||||
COLSTR("%s %c", SCOLOR_AUTOCMT),
|
||||
cbuf,
|
||||
ash.cmnt,
|
||||
c >= ' ' ? c : ' ');
|
||||
if ( !(ea & 1) && (i = get_word(ea)) != 0 )
|
||||
{
|
||||
ctx.out_tagon(COLOR_AUTOCMT);
|
||||
ctx.out_char(' ');
|
||||
b2a32(buf, sizeof(buf), i, 2, 0);
|
||||
ctx.out_line(buf);
|
||||
ctx.out_char(' ');
|
||||
ushort w = i;
|
||||
r50_to_asc(buf, &w, 1);
|
||||
ctx.out_line(buf);
|
||||
ctx.out_tagoff(COLOR_AUTOCMT);
|
||||
}
|
||||
ctx.flush_outbuf();
|
||||
} // undefined
|
||||
}
|
||||
Reference in New Issue
Block a user