update to ida 7.6, add builds
This commit is contained in:
813
idasdk76/module/java/oututil.cpp
Normal file
813
idasdk76/module/java/oututil.cpp
Normal file
@@ -0,0 +1,813 @@
|
||||
#include "java.hpp"
|
||||
#include "oututil.hpp"
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// returns number of positions advanced
|
||||
int out_java_t::out_commented(const char *p, color_t color)
|
||||
{
|
||||
if ( color != COLOR_NONE )
|
||||
out_tagon(color);
|
||||
size_t inplen = outbuf.length();
|
||||
out_printf("%s %s", ash.cmnt, p);
|
||||
int npos = outbuf.length() - inplen;
|
||||
if ( color != COLOR_NONE )
|
||||
out_tagoff(color);
|
||||
return npos;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
bool out_java_t::change_line(bool main)
|
||||
{
|
||||
bool overflow = false;
|
||||
if ( pm().g_bufinited )
|
||||
{
|
||||
pm().outcnt = 0;
|
||||
uchar sv = inf_get_indent();
|
||||
inf_set_indent((uchar)pm().curpos);
|
||||
overflow = flush_buf(outbuf.c_str(), main ? -1 : pm().curpos);
|
||||
inf_set_indent(sv);
|
||||
// for autocomment with call fmtName
|
||||
outbuf.qclear();
|
||||
outbuf.reserve(pm().g_bufsize);
|
||||
}
|
||||
return overflow;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
size_t out_java_t::putLine(java_t &pm)
|
||||
{
|
||||
color_t color = COLOR_NONE;
|
||||
|
||||
if ( pm.g_bufinited )
|
||||
{
|
||||
const char *p = strrchr(outbuf.c_str(), 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(pm.curpos != 0 && !pm.no_prim) )
|
||||
return 0;
|
||||
pm.curpos = 0;
|
||||
if ( color != COLOR_NONE )
|
||||
out_tagon(color);
|
||||
pm.ref_pos = outbuf.length();
|
||||
return pm.maxpos;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
bool out_java_t::checkLine(size_t size)
|
||||
{
|
||||
if ( !pm().g_bufinited )
|
||||
return true;
|
||||
if ( pm().maxpos - pm().curpos > pm().outcnt + size )
|
||||
return true;
|
||||
return putLine(pm()) != 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
bool out_java_t::chkOutLine(const char *str, size_t len)
|
||||
{
|
||||
if ( !checkLine(len) )
|
||||
return true;
|
||||
pm().outcnt += len;
|
||||
out_line(str);
|
||||
return false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
bool out_java_t::chkOutKeyword(const char *str, uint len)
|
||||
{
|
||||
if ( !checkLine(len) )
|
||||
return true;
|
||||
OutKeyword(str, len);
|
||||
return false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
bool out_java_t::chkOutSymbol(char c)
|
||||
{
|
||||
if ( !checkLine(1) )
|
||||
return true;
|
||||
++pm().outcnt;
|
||||
out_symbol(c);
|
||||
return false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
bool out_java_t::chkOutChar(char c)
|
||||
{
|
||||
if ( !checkLine(1) )
|
||||
return true;
|
||||
++pm().outcnt;
|
||||
out_char(c);
|
||||
return false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
bool out_java_t::chkOutSymSpace(char c)
|
||||
{
|
||||
if ( !checkLine(2) )
|
||||
return true;
|
||||
out_symbol(c);
|
||||
out_char(' ');
|
||||
pm().outcnt += 2;
|
||||
return false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
uchar out_java_t::putShort(ushort value, uchar wsym)
|
||||
{
|
||||
size_t inplen = outbuf.length();
|
||||
|
||||
out_tagon(COLOR_ERROR);
|
||||
if ( wsym )
|
||||
out_char(wsym);
|
||||
out_btoa(value,
|
||||
#ifdef __debug__
|
||||
debugmode ? 16 :
|
||||
#endif
|
||||
10);
|
||||
out_tagoff(COLOR_ERROR);
|
||||
|
||||
char tmpstr[32];
|
||||
size_t curlen = outbuf.length();
|
||||
size_t len = curlen - inplen;
|
||||
qstrncpy(tmpstr, &outbuf[inplen], qmin(len+1, sizeof(tmpstr)));
|
||||
outbuf.resize(inplen);
|
||||
return chkOutLine(tmpstr, tag_strlen(tmpstr));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
char out_java_t::outName(ea_t from, int n, ea_t ea, uval_t off, uchar *rbad)
|
||||
{
|
||||
qstring qbuf;
|
||||
|
||||
if ( get_name_expr(&qbuf, from, n, ea + off, off) <= 0 )
|
||||
{
|
||||
remember_problem(PR_NONAME, insn.ea);
|
||||
return 0;
|
||||
}
|
||||
if ( chkOutLine(qbuf.begin(), tag_strlen(qbuf.begin())) )
|
||||
{
|
||||
*rbad = 1;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
uchar out_java_t::putVal(const op_t &x, uchar mode, uchar warn)
|
||||
{
|
||||
size_t inplen = outbuf.length();
|
||||
|
||||
{
|
||||
flags_t saved = F;
|
||||
F = 0;
|
||||
out_value(x, mode);
|
||||
F = saved;
|
||||
}
|
||||
|
||||
char str[MAXSTR];
|
||||
size_t curlen = outbuf.length();
|
||||
size_t len = curlen - inplen;
|
||||
qstrncpy(str, &outbuf[inplen], qmin(len+1, sizeof(str)));
|
||||
outbuf.resize(inplen);
|
||||
|
||||
if ( warn )
|
||||
out_tagon(COLOR_ERROR);
|
||||
|
||||
if ( warn )
|
||||
{
|
||||
qstring qstr;
|
||||
len = tag_remove(&qstr, str);
|
||||
qstrncpy(str, qstr.c_str(), sizeof(str));
|
||||
}
|
||||
else
|
||||
{
|
||||
len = tag_strlen(str);
|
||||
}
|
||||
|
||||
if ( chkOutLine(str, len) )
|
||||
return 0;
|
||||
|
||||
if ( warn )
|
||||
out_tagoff(COLOR_ERROR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
CASSERT(MIN_ARG_SIZE >= 2 && MIN_ARG_SIZE < 30);
|
||||
|
||||
uchar out_java_t::OutUtf8(ushort index, fmt_t mode, color_t color)
|
||||
{
|
||||
size_t size = (pm().maxpos - pm().curpos) - pm().outcnt;
|
||||
|
||||
if ( (int)size <= MIN_ARG_SIZE )
|
||||
{
|
||||
DEB_ASSERT(((int)size < 0), "OutUtf8");
|
||||
size = putLine(pm());
|
||||
if ( size == 0 )
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( color != COLOR_NONE )
|
||||
out_tagon(color);
|
||||
pm().ref_pos = outbuf.length();
|
||||
struct ida_local lambda_t
|
||||
{
|
||||
static size_t call_putLine(java_t &pm, out_java_t *oj)
|
||||
{
|
||||
return oj->putLine(pm);
|
||||
}
|
||||
};
|
||||
if ( fmtString(pm(), index, size, mode, lambda_t::call_putLine) < 0 )
|
||||
return 1;
|
||||
pm().outcnt += outbuf.length() - pm().ref_pos;
|
||||
if ( color != COLOR_NONE )
|
||||
out_tagoff(color);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
uchar out_java_t::out_index(ushort index, fmt_t mode, color_t color, uchar as_index)
|
||||
{
|
||||
if ( as_index )
|
||||
{
|
||||
if ( !(pm().idpflags & (IDM_BADIDXSTR | IDM_OUTASM)) // no store in file
|
||||
|| !pm().is_valid_string_index(index) )
|
||||
{
|
||||
return putShort(index);
|
||||
}
|
||||
color = COLOR_ERROR;
|
||||
mode = fmt_string;
|
||||
}
|
||||
return OutUtf8(index, mode, color);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
uchar out_java_t::out_alt_ind(uint32 val)
|
||||
{
|
||||
if ( (ushort)val )
|
||||
return OutUtf8((ushort)val, fmt_fullname, COLOR_IMPNAME);
|
||||
return putShort((ushort)(val >> 16));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// special label format/scan procedures
|
||||
//--------------------------------------------------------------------------
|
||||
void out_java_t::out_method_label(uchar is_end)
|
||||
{
|
||||
set_gen_cmt(true);
|
||||
set_gen_xrefs(true);
|
||||
gen_printf(0, COLSTR("met%03u_%s%s", SCOLOR_CODNAME), pm().curSeg.id.Number,
|
||||
is_end ? "end" : "begin", COLSTR(":", SCOLOR_SYMBOL));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
char out_java_t::putMethodLabel(ushort off)
|
||||
{
|
||||
char str[32];
|
||||
int len = qsnprintf(str, sizeof(str), "met%03u_%s", pm().curSeg.id.Number,
|
||||
off ? "end" : "begin");
|
||||
|
||||
if ( !checkLine(len) )
|
||||
return 1;
|
||||
out_tagon(COLOR_CODNAME);
|
||||
outLine(str, len);
|
||||
out_tagoff(COLOR_CODNAME);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// procedure for get_ref_addr
|
||||
ssize_t java_t::check_special_label(const char *buf, size_t len) const
|
||||
{
|
||||
if ( len >= sizeof("met000_end")-1
|
||||
&& (*(uint32*)buf & 0xFFFFFF) == ('m'|('e'<<8)|('t'<<16)) )
|
||||
{
|
||||
|
||||
switch ( *(uint32*)&buf[len -= 4] )
|
||||
{
|
||||
case ('_'|('e'<<8)|('n'<<16)|('d'<<24)):
|
||||
break;
|
||||
case ('e'|('g'<<8)|('i'<<16)|('n'<<24)):
|
||||
if ( len >= sizeof("met000_begin")-1 - 4
|
||||
&& *(ushort*)&buf[len -= 2] == ('_'|('b'<<8)) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
// no break
|
||||
default:
|
||||
len |= -1; // as flag
|
||||
break;
|
||||
}
|
||||
if ( len <= sizeof("met00000")-1 )
|
||||
{
|
||||
size_t off = curSeg.CodeSize;
|
||||
if ( buf[len+1] == 'b' )
|
||||
off = 0;
|
||||
size_t n = 0;
|
||||
size_t j = sizeof("met")-1;
|
||||
while ( true )
|
||||
{
|
||||
if ( !qisdigit((uchar)buf[j]) )
|
||||
break;
|
||||
n = n*10 + (buf[j] - '0');
|
||||
if ( ++j == len )
|
||||
{
|
||||
if ( n >= 0x10000 || (ushort)n != curSeg.id.Number )
|
||||
break;
|
||||
return off;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// end of special-label procedures
|
||||
//----------------------------------------------------------------------
|
||||
uchar out_java_t::outOffName(ushort off)
|
||||
{
|
||||
if ( !off || off == pm().curSeg.CodeSize )
|
||||
return putMethodLabel(off);
|
||||
if ( off < pm().curSeg.CodeSize )
|
||||
{
|
||||
uchar err = 0;
|
||||
if ( outName(pm().curSeg.start_ea + pm().curSeg.CodeSize, 0,
|
||||
pm().curSeg.start_ea, off, &err) )
|
||||
return 0; // good
|
||||
if ( err )
|
||||
return 1; // bad
|
||||
}
|
||||
return putShort(off, 0);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
bool out_java_t::block_begin(uchar off)
|
||||
{
|
||||
return flush_buf(COLSTR("{", SCOLOR_SYMBOL), off);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
bool out_java_t::block_end(uint32 off)
|
||||
{
|
||||
return flush_buf(COLSTR("}", SCOLOR_SYMBOL), off);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
bool out_java_t::block_close(uint32 off, const char *name)
|
||||
{
|
||||
if ( !jasmin() )
|
||||
return block_end(off);
|
||||
return gen_printf(off, COLSTR(".end %s", SCOLOR_KEYWORD), name);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
bool out_java_t::close_comment(void)
|
||||
{
|
||||
return flush_buf(COLSTR("*/", SCOLOR_AUTOCMT), 0);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
uchar out_java_t::out_nodelist(uval_t nodeid, uchar pos, const char *pref)
|
||||
{
|
||||
netnode node(nodeid);
|
||||
uval_t cnt = node.altval(0);
|
||||
if ( cnt == 0 )
|
||||
DESTROYED("out::nodelist");
|
||||
|
||||
uval_t off = 0;
|
||||
if ( pref ) // jasmin
|
||||
{
|
||||
if ( change_line() )
|
||||
{
|
||||
bad:
|
||||
return 0;
|
||||
}
|
||||
off = strlen(pref);
|
||||
}
|
||||
|
||||
uint i = 0;
|
||||
while ( true )
|
||||
{
|
||||
if ( pref ) // jasmin (single directive per line)
|
||||
{
|
||||
pm().curpos = pos;
|
||||
out_keyword(pref);
|
||||
pm().outcnt = off;
|
||||
}
|
||||
else if ( i && chkOutSymSpace(',') )
|
||||
{
|
||||
goto bad; // prompted list
|
||||
}
|
||||
if ( out_alt_ind((uint32)node.altval(++i)) )
|
||||
goto bad;
|
||||
if ( i >= cnt )
|
||||
return 1;
|
||||
if ( pref && change_line() )
|
||||
goto bad; // jasmin
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void out_java_t::init_prompted_output(uchar pos)
|
||||
{
|
||||
pm().maxpos = inf_get_margin();
|
||||
// if ( maxpos < 32 )
|
||||
// maxpos = 32;
|
||||
// if ( maxpos > MAXSTR - 4 )
|
||||
// maxpos = MAXSTR - 4;
|
||||
|
||||
#ifdef __debug__
|
||||
if ( debugmode == -1
|
||||
&& inf.show_line_pref() && inf_get_margin() == 77 && !inf.bin_prefix_size )
|
||||
{
|
||||
maxpos -= gl_psize;
|
||||
}
|
||||
#endif
|
||||
pm().g_bufsize = (MAXSTR*2) - STR_PRESERVED;
|
||||
pm().g_bufinited = true;
|
||||
outbuf.qclear();
|
||||
outbuf.reserve(pm().g_bufsize);
|
||||
pm().curpos = pos;
|
||||
pm().outcnt = 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void out_java_t::term_prompted_output(void)
|
||||
{
|
||||
outbuf.qclear();
|
||||
pm().g_bufinited = false;
|
||||
pm().g_bufsize = 0;
|
||||
pm().maxpos = 0;
|
||||
pm().curpos = -1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
uchar out_java_t::OutConstant(const op_t &_x, bool include_descriptor)
|
||||
{
|
||||
op_t x = _x;
|
||||
fmt_t fmt = fmt_FieldDescriptor;
|
||||
color_t color;
|
||||
|
||||
insn_t cur_insn;
|
||||
decode_insn(&cur_insn, insn_ea);
|
||||
switch ( (uchar)x.cp_type )
|
||||
{
|
||||
default:
|
||||
warning("OC: bad constant type %u", (uchar)x.cp_type);
|
||||
break;
|
||||
|
||||
case CONSTANT_Long:
|
||||
x.dtype = dt_qword;
|
||||
goto outNum;
|
||||
case CONSTANT_Double:
|
||||
x.dtype = dt_double;
|
||||
goto outNum;
|
||||
case CONSTANT_Integer:
|
||||
x.dtype = dt_dword;
|
||||
goto outNum;
|
||||
case CONSTANT_Float:
|
||||
x.dtype = dt_float;
|
||||
outNum:
|
||||
if ( putVal(x, OOF_NUMBER | OOF_SIGNED | OOFW_IMM, 0) )
|
||||
break;
|
||||
badconst:
|
||||
return 0;
|
||||
|
||||
case CONSTANT_Utf8:
|
||||
if ( OutUtf8(x.cp_ind, fmt_string, COLOR_STRING) )
|
||||
goto badconst;
|
||||
break;
|
||||
|
||||
case CONSTANT_String:
|
||||
if ( OutUtf8(x._name, fmt_string, COLOR_STRING) )
|
||||
goto badconst;
|
||||
break;
|
||||
|
||||
case CONSTANT_NameAndType:
|
||||
nameandtype:
|
||||
if ( OutUtf8(x._class, fmt_fullname)
|
||||
|| OutUtf8(x._name, fmt_fullname) )
|
||||
{
|
||||
goto badconst;
|
||||
}
|
||||
break;
|
||||
|
||||
case CONSTANT_InvokeDynamic:
|
||||
{
|
||||
const_desc_t invdyn;
|
||||
if ( pm().ConstantNode.supval(x.cp_ind, &invdyn, sizeof(invdyn)) != sizeof(invdyn) )
|
||||
goto badconst;
|
||||
// Retrieve NameAndType
|
||||
const_desc_t nat;
|
||||
if ( pm().ConstantNode.supval(invdyn._name, &nat, sizeof(nat)) != sizeof(nat) )
|
||||
goto badconst;
|
||||
memset(&x, 0, sizeof(x));
|
||||
copy_const_to_opnd(x, nat);
|
||||
x.ref = 0;
|
||||
x.cp_type = nat.type;
|
||||
x.cp_ind = invdyn._name;
|
||||
goto nameandtype;
|
||||
}
|
||||
break;
|
||||
|
||||
case CONSTANT_MethodHandle:
|
||||
{
|
||||
const_desc_t tmp;
|
||||
if ( pm().ConstantNode.supval(x._mhr_index, &tmp, sizeof(tmp)) != sizeof(tmp) )
|
||||
goto badconst;
|
||||
op_t tmpop;
|
||||
memset(&tmpop, 0, sizeof(tmpop));
|
||||
copy_const_to_opnd(tmpop, tmp);
|
||||
tmpop.ref = 0; // as flag
|
||||
tmpop.cp_type = tmp.type;
|
||||
tmpop.cp_ind = x._mhr_index;
|
||||
OutConstant(tmpop, include_descriptor);
|
||||
}
|
||||
break;
|
||||
|
||||
case CONSTANT_MethodType:
|
||||
if ( OutUtf8(x._mtd_index, fmt_fullname, COLOR_KEYWORD) )
|
||||
goto badconst;
|
||||
break;
|
||||
|
||||
case CONSTANT_Class:
|
||||
CASSERT((fmt_ClassName_or_Array+1) == fmt_ClassName && (fmt_ClassName+1) == fmt_fullname);
|
||||
{
|
||||
fmt_t f2 = (fmt_t )x.addr_shorts.high;
|
||||
color_t c2 = f2 < fmt_ClassName_or_Array || f2 > fmt_fullname ? COLOR_KEYWORD
|
||||
: cur_insn.xtrn_ip == 0xFFFF ? COLOR_DNAME : COLOR_IMPNAME;
|
||||
|
||||
if ( OutUtf8(x._name, f2, c2) )
|
||||
goto badconst;
|
||||
}
|
||||
break;
|
||||
|
||||
case CONSTANT_InterfaceMethodref:
|
||||
case CONSTANT_Methodref:
|
||||
fmt = fmt_method_ReturnType;
|
||||
// fallthrough
|
||||
case CONSTANT_Fieldref:
|
||||
#ifdef VIEW_WITHOUT_TYPE
|
||||
if ( include_descriptor )
|
||||
#endif
|
||||
if ( !jasmin() && OutUtf8(x._dscr, fmt, COLOR_KEYWORD) )
|
||||
goto badconst;
|
||||
color = x._class == pm().curClass.This.Dscr ? COLOR_DNAME : COLOR_IMPNAME;
|
||||
out_tagon(color);
|
||||
if ( jasmin() || (color == COLOR_IMPNAME && !include_descriptor) ) // other class
|
||||
{
|
||||
if ( OutUtf8(x._name, fmt_ClassName) || chkOutDot() )
|
||||
goto badconst;
|
||||
}
|
||||
if ( OutUtf8(x._subnam, fmt_UnqualifiedName) )
|
||||
goto badconst; // Field
|
||||
out_tagoff(color);
|
||||
if ( jasmin() )
|
||||
{
|
||||
if ( fmt == fmt_method_ReturnType )
|
||||
fmt = fmt_FieldDescriptor_nospace; // no space at end
|
||||
else if ( chkOutSpace() )
|
||||
goto badconst;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( fmt != fmt_method_ReturnType )
|
||||
break;
|
||||
fmt = fmt_method_TypeSignature;
|
||||
}
|
||||
if ( OutUtf8(x._dscr, fmt, COLOR_KEYWORD) )
|
||||
goto badconst;
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// FIXME: there should be a better way of suppressing borders in disassembly
|
||||
void out_java_t::myBorder(void)
|
||||
{
|
||||
gen_empty_line();
|
||||
if ( pm().user_limiter )
|
||||
{
|
||||
inf_set_limiter(LMT_THIN);
|
||||
gen_border_line(false);
|
||||
}
|
||||
inf_set_limiter(0); // do not output border between method & vars :(
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
uchar out_java_t::out_problems(char str[MAXSTR], const char *prefix)
|
||||
{
|
||||
if ( pm().curClass.extflg & XFL_C_ERRLOAD )
|
||||
{
|
||||
myBorder();
|
||||
gen_printf(DEFAULT_INDENT,
|
||||
COLSTR("%s This class has had loading time problem(s)", SCOLOR_ERROR),
|
||||
prefix);
|
||||
if ( pm().curClass.msgNode )
|
||||
{
|
||||
gen_empty_line();
|
||||
if ( pm().print_loader_messages(str, prefix, this) == -1 )
|
||||
return 1;
|
||||
}
|
||||
myBorder();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
uchar out_java_t::putScope(ushort scope, uint32 doff)
|
||||
{
|
||||
if ( !scope || scope == pm().curSeg.CodeSize )
|
||||
return putMethodLabel(scope);
|
||||
|
||||
if ( scope < pm().curSeg.CodeSize )
|
||||
{
|
||||
uchar err = 0;
|
||||
if ( outName(pm().curSeg.DataBase + doff, 0, pm().curSeg.start_ea, scope, &err) )
|
||||
return 0;
|
||||
if ( err )
|
||||
return 1;
|
||||
}
|
||||
|
||||
return putShort(scope, 0);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
size_t out_java_t::debLine(java_t &)
|
||||
{
|
||||
out_char('"');
|
||||
out_tagoff(COLOR_STRING);
|
||||
if ( change_line() )
|
||||
return 0;
|
||||
return putDeb(1);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void out_java_t::OutKeyword(const char *str, size_t len)
|
||||
{
|
||||
pm().outcnt += len;
|
||||
out_keyword(str);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void out_java_t::outLine(const char *str, uint len)
|
||||
{
|
||||
pm().outcnt += len;
|
||||
out_line(str);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
uchar out_java_t::chkOutDot(void)
|
||||
{
|
||||
return chkOutChar('.');
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void out_java_t::OutSpace(void)
|
||||
{
|
||||
++pm().outcnt;
|
||||
out_char(' ');
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
uchar out_java_t::chkOutSpace(void)
|
||||
{
|
||||
return chkOutChar(' ');
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
size_t out_java_t::putDeb(uchar next)
|
||||
{
|
||||
OUT_KEYWORD(".debug ");
|
||||
out_tagon(COLOR_STRING);
|
||||
if ( next )
|
||||
out_char('"');
|
||||
return pm().maxpos - pm().outcnt;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
bool out_java_t::out_operand(const op_t &x)
|
||||
{
|
||||
int outf;
|
||||
uchar warn = 0;
|
||||
|
||||
switch ( x.type )
|
||||
{
|
||||
case o_near:
|
||||
if ( x.ref )
|
||||
{
|
||||
++warn;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( outName(insn.ea + x.offb, x.n, pm().curSeg.start_ea, x.addr, &warn) )
|
||||
break;
|
||||
if ( warn )
|
||||
goto badop;
|
||||
}
|
||||
if ( putVal(x, OOF_ADDR | OOF_NUMBER | OOFS_NOSIGN | OOFW_32, warn) )
|
||||
break;
|
||||
// no break
|
||||
case o_void:
|
||||
badop:
|
||||
return false;
|
||||
|
||||
case o_imm:
|
||||
if ( x.ref == 2 )
|
||||
++warn;
|
||||
outf = OOFW_IMM | OOF_NUMBER | (x.ref ? OOFS_NOSIGN : OOF_SIGNED);
|
||||
if ( putVal(x, outf, warn) )
|
||||
break;
|
||||
goto badop;
|
||||
|
||||
case o_mem:
|
||||
if ( jasmin() )
|
||||
goto putidcv_num;
|
||||
if ( x.ref )
|
||||
{
|
||||
putAddr:
|
||||
++warn;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( outName(insn.ea + x.offb, x.n, pm().curSeg.DataBase, x.addr, &warn) )
|
||||
break;
|
||||
if ( warn )
|
||||
goto badop;
|
||||
}
|
||||
putidcv_num:
|
||||
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 )
|
||||
{
|
||||
uchar btype = 0;
|
||||
switch ( uchar(x.cp_type) )
|
||||
{
|
||||
case T_BOOLEAN: btype = j_bool; break;
|
||||
case T_CHAR: btype = j_char; break;
|
||||
case T_FLOAT: btype = j_float; break;
|
||||
case T_DOUBLE: btype = j_double; break;
|
||||
case T_BYTE: btype = j_byte; break;
|
||||
case T_SHORT: btype = j_short; break;
|
||||
case T_INT: btype = j_int; break;
|
||||
case T_LONG: btype = j_long; break;
|
||||
}
|
||||
const TXS *tname = get_base_typename(btype);
|
||||
if ( tname == 0 || chkOutKeyword(tname->str, tname->size) )
|
||||
goto badop;
|
||||
}
|
||||
else
|
||||
{
|
||||
static const char tt_bogust[] = "BOGUST_TYPE-";
|
||||
|
||||
if ( !checkLine(sizeof(tt_bogust) + 2) )
|
||||
goto badop;
|
||||
out_tagon(COLOR_ERROR);
|
||||
size_t inplen = outbuf.length();
|
||||
out_printf("%c%s%u", WARN_SYM, tt_bogust, (uchar)x.cp_type);
|
||||
pm().outcnt += outbuf.length() - inplen;
|
||||
out_tagoff(COLOR_ERROR);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
warning("out: %a: bad optype %d", insn.ip, x.type);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void java_t::java_footer(outctx_t &ctx)
|
||||
{
|
||||
if ( !jasmin() )
|
||||
{
|
||||
out_java_t *p = (out_java_t *)&ctx;
|
||||
p->block_end(0);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user