Fixes to libdisasm, also use it a bit more

This commit is contained in:
Artur K 2012-07-19 19:37:30 +02:00
parent c1eb8df114
commit d5e1fc733f
46 changed files with 1463 additions and 1331 deletions

View File

@ -109,17 +109,15 @@ size_t Ia32_Decoder::decode_operand_value( unsigned char *buf, size_t buf_len,
op->type = op_absolute; op->type = op_absolute;
/* segment:offset address used in far calls */ /* segment:offset address used in far calls */
x86_imm_sized( buf, buf_len,
&op->data.absolute.segment, 2 );
if ( m_decoded->addr_size == 4 ) { if ( m_decoded->addr_size == 4 ) {
x86_imm_sized( buf, buf_len, x86_imm_sized( buf, buf_len, &op->data.absolute.offset.off32, 4 );
&op->data.absolute.offset.off32, 4 );
size = 6;
} else {
x86_imm_sized( buf, buf_len,
&op->data.absolute.offset.off16, 2 );
size = 4; size = 4;
} else {
x86_imm_sized( buf, buf_len,&op->data.absolute.offset.off16, 2 );
size = 2;
} }
x86_imm_sized( buf+size, buf_len-size, &op->data.absolute.segment, 2 );
size+=2;
break; break;
case ADDRMETH_I: /* Immediate val */ case ADDRMETH_I: /* Immediate val */
@ -140,17 +138,24 @@ size_t Ia32_Decoder::decode_operand_value( unsigned char *buf, size_t buf_len,
op->data.far_offset depending on the size of op->data.far_offset depending on the size of
the operand */ the operand */
op->flags.op_signed = true; op->flags.op_signed = true;
if ( op_size == 1 ) { switch(op_size)
/* one-byte near offset */ {
op->type = op_relative_near; case 1:
x86_imm_signsized(buf, buf_len, &op->data.relative_near, 1); /* one-byte near offset */
} else { op->type = op_relative_near;
/* far offset...is this truly signed? */ size = x86_imm_signsized(buf, buf_len, &op->data.relative_near, 1);
op->type = op_relative_far; break;
x86_imm_signsized(buf, buf_len, case 2:
&op->data.relative_far, op_size ); op->type = op_relative_far;
int16_t offset_val;
size = x86_imm_signsized(buf, buf_len,&offset_val, 2);
op->data.relative_far=offset_val;
break;
default:
assert(false);
size=0;
} }
size = op_size;
break; break;
case ADDRMETH_O: /* No ModR/M; op is word/dword offset */ case ADDRMETH_O: /* No ModR/M; op is word/dword offset */
/* NOTE: these are actually RVAs not offsets to seg!! */ /* NOTE: these are actually RVAs not offsets to seg!! */
@ -258,7 +263,7 @@ size_t Ia32_Decoder::decode_operand_size( unsigned int op_type, x86_op_t *op ) {
* value s a 16:16 pointer or a 16:32 pointer, where * value s a 16:16 pointer or a 16:32 pointer, where
* the first '16' is a segment */ * the first '16' is a segment */
size = (m_decoded->addr_size == 4) ? 6 : 4; size = (m_decoded->addr_size == 4) ? 6 : 4;
op->datatype = (size == 4) ? op_descr32 : op_descr16; op->datatype = (size == 6) ? op_descr32 : op_descr16;
break; break;
case OPTYPE_b: /* byte, ignore op-size */ case OPTYPE_b: /* byte, ignore op-size */
size = 1; size = 1;

View File

@ -6,17 +6,17 @@
#endif #endif
#include <cstring> #include <cstring>
#include <cstdlib> #include <cstdlib>
#include <cassert>
#include <stdint.h> #include <stdint.h>
/* 'NEW" types /* 'NEW" types
* __________________________________________________________________________*/ * __________________________________________________________________________*/
#ifndef LIBDISASM_QWORD_H /* do not interfere with qword.h */ #ifndef LIBDISASM_QWORD_H /* do not interfere with qword.h */
#define LIBDISASM_QWORD_H #define LIBDISASM_QWORD_H
#ifdef _MSC_VER #ifdef _MSC_VER
typedef __int64 qword_t; typedef __int64 qword_t;
#else #else
typedef int64_t qword_t; typedef int64_t qword_t;
#endif #endif
#endif #endif
#include <sys/types.h> #include <sys/types.h>
@ -36,7 +36,7 @@
* this allows the report to recover from errors, or just log them. * this allows the report to recover from errors, or just log them.
*/ */
enum x86_report_codes { enum x86_report_codes {
report_disasm_bounds, /* RVA OUT OF BOUNDS : The disassembler could report_disasm_bounds, /* RVA OUT OF BOUNDS : The disassembler could
not disassemble the supplied RVA as it is not disassemble the supplied RVA as it is
out of the range of the buffer. The out of the range of the buffer. The
application should store the address and application should store the address and
@ -44,21 +44,21 @@ enum x86_report_codes {
binary it is in, then disassemble the binary it is in, then disassemble the
address from the bytes in that section. address from the bytes in that section.
data: uint32_t rva */ data: uint32_t rva */
report_insn_bounds, /* INSTRUCTION OUT OF BOUNDS: The disassembler report_insn_bounds, /* INSTRUCTION OUT OF BOUNDS: The disassembler
could not disassemble the instruction as could not disassemble the instruction as
the instruction would require bytes beyond the instruction would require bytes beyond
the end of the current buffer. This usually the end of the current buffer. This usually
indicated garbage bytes at the end of a indicated garbage bytes at the end of a
buffer, or an incorrectly-sized buffer. buffer, or an incorrectly-sized buffer.
data: uint32_t rva */ data: uint32_t rva */
report_invalid_insn, /* INVALID INSTRUCTION: The disassembler could report_invalid_insn, /* INVALID INSTRUCTION: The disassembler could
not disassemble the instruction as it has an not disassemble the instruction as it has an
invalid combination of opcodes and operands. invalid combination of opcodes and operands.
This will stop automated disassembly; the This will stop automated disassembly; the
application can restart the disassembly application can restart the disassembly
after the invalid instruction. after the invalid instruction.
data: uint32_t rva */ data: uint32_t rva */
report_unknown report_unknown
}; };
/* Disassembly formats: /* Disassembly formats:
* AT&T is standard AS/GAS-style: "mnemonic\tsrc, dest, imm" * AT&T is standard AS/GAS-style: "mnemonic\tsrc, dest, imm"
@ -68,12 +68,12 @@ enum x86_report_codes {
* Raw is addr|offset|size|bytes|prefix... see libdisasm_formats.7 * Raw is addr|offset|size|bytes|prefix... see libdisasm_formats.7
*/ */
enum x86_asm_format { enum x86_asm_format {
unknown_syntax = 0, /* never use! */ unknown_syntax = 0, /* never use! */
native_syntax, /* header: 35 bytes */ native_syntax, /* header: 35 bytes */
intel_syntax, /* header: 23 bytes */ intel_syntax, /* header: 23 bytes */
att_syntax, /* header: 23 bytes */ att_syntax, /* header: 23 bytes */
xml_syntax, /* header: 679 bytes */ xml_syntax, /* header: 679 bytes */
raw_syntax /* header: 172 bytes */ raw_syntax /* header: 172 bytes */
}; };
/* 'arg' is optional arbitrary data provided by the code passing the /* 'arg' is optional arbitrary data provided by the code passing the
@ -86,10 +86,10 @@ typedef void (*DISASM_REPORTER)( enum x86_report_codes code,
/* ========================================= Libdisasm Management Routines */ /* ========================================= Libdisasm Management Routines */
enum x86_options { /* these can be ORed together */ enum x86_options { /* these can be ORed together */
opt_none= 0, opt_none= 0,
opt_ignore_nulls=1, /* ignore sequences of > 4 NULL bytes */ opt_ignore_nulls=1, /* ignore sequences of > 4 NULL bytes */
opt_16_bit=2, /* 16-bit/DOS disassembly */ opt_16_bit=2, /* 16-bit/DOS disassembly */
opt_att_mnemonics=4 /* use AT&T syntax names for alternate opcode mnemonics */ opt_att_mnemonics=4 /* use AT&T syntax names for alternate opcode mnemonics */
}; };
/* ========================================= Instruction Representation */ /* ========================================= Instruction Representation */
@ -110,35 +110,35 @@ enum x86_options { /* these can be ORed together */
#define MAX_INSN_XML_STRING 4096 /* 2 * 8 * MAX_OP_XML_STRING */ #define MAX_INSN_XML_STRING 4096 /* 2 * 8 * MAX_OP_XML_STRING */
enum x86_reg_type { /* NOTE: these may be ORed together */ enum x86_reg_type { /* NOTE: these may be ORed together */
reg_undef = 0x00000, // used only in ia32_reg_table initializater reg_undef = 0x00000, // used only in ia32_reg_table initializater
reg_gen = 0x00001, /* general purpose */ reg_gen = 0x00001, /* general purpose */
reg_in = 0x00002, /* incoming args, ala RISC */ reg_in = 0x00002, /* incoming args, ala RISC */
reg_out = 0x00004, /* args to calls, ala RISC */ reg_out = 0x00004, /* args to calls, ala RISC */
reg_local = 0x00008, /* local vars, ala RISC */ reg_local = 0x00008, /* local vars, ala RISC */
reg_fpu = 0x00010, /* FPU data register */ reg_fpu = 0x00010, /* FPU data register */
reg_seg = 0x00020, /* segment register */ reg_seg = 0x00020, /* segment register */
reg_simd = 0x00040, /* SIMD/MMX reg */ reg_simd = 0x00040, /* SIMD/MMX reg */
reg_sys = 0x00080, /* restricted/system register */ reg_sys = 0x00080, /* restricted/system register */
reg_sp = 0x00100, /* stack pointer */ reg_sp = 0x00100, /* stack pointer */
reg_fp = 0x00200, /* frame pointer */ reg_fp = 0x00200, /* frame pointer */
reg_pc = 0x00400, /* program counter */ reg_pc = 0x00400, /* program counter */
reg_retaddr = 0x00800, /* return addr for func */ reg_retaddr = 0x00800, /* return addr for func */
reg_cond = 0x01000, /* condition code / flags */ reg_cond = 0x01000, /* condition code / flags */
reg_zero = 0x02000, /* zero register, ala RISC */ reg_zero = 0x02000, /* zero register, ala RISC */
reg_ret = 0x04000, /* return value */ reg_ret = 0x04000, /* return value */
reg_src = 0x10000, /* array/rep source */ reg_src = 0x10000, /* array/rep source */
reg_dest = 0x20000, /* array/rep destination */ reg_dest = 0x20000, /* array/rep destination */
reg_count = 0x40000 /* array/rep/loop counter */ reg_count = 0x40000 /* array/rep/loop counter */
}; };
/* x86_reg_t : an X86 CPU register */ /* x86_reg_t : an X86 CPU register */
struct x86_reg_t { struct x86_reg_t {
char name[MAX_REGNAME]; char name[MAX_REGNAME];
enum x86_reg_type type; /* what register is used for */ enum x86_reg_type type; /* what register is used for */
unsigned int size; /* size of register in bytes */ unsigned int size; /* size of register in bytes */
unsigned int id; /* register ID #, for quick compares */ unsigned int id; /* register ID #, for quick compares */
unsigned int alias; /* ID of reg this is an alias for */ unsigned int alias; /* ID of reg this is an alias for */
unsigned int shift; /* amount to shift aliased reg by */ unsigned int shift; /* amount to shift aliased reg by */
x86_reg_t * aliased_reg( ) { x86_reg_t * aliased_reg( ) {
x86_reg_t * reg = (x86_reg_t * )calloc( sizeof(x86_reg_t), 1 ); x86_reg_t * reg = (x86_reg_t * )calloc( sizeof(x86_reg_t), 1 );
reg->x86_reg_from_id( id ); reg->x86_reg_from_id( id );
@ -149,92 +149,92 @@ struct x86_reg_t {
/* x86_ea_t : an X86 effective address (address expression) */ /* x86_ea_t : an X86 effective address (address expression) */
typedef struct { typedef struct {
unsigned int scale; /* scale factor */ unsigned int scale; /* scale factor */
x86_reg_t index, base; /* index, base registers */ x86_reg_t index, base; /* index, base registers */
int32_t disp; /* displacement */ int32_t disp; /* displacement */
char disp_sign; /* is negative? 1/0 */ char disp_sign; /* is negative? 1/0 */
char disp_size; /* 0, 1, 2, 4 */ char disp_size; /* 0, 1, 2, 4 */
} x86_ea_t; } x86_ea_t;
/* x86_absolute_t : an X86 segment:offset address (descriptor) */ /* x86_absolute_t : an X86 segment:offset address (descriptor) */
typedef struct { typedef struct {
unsigned short segment; /* loaded directly into CS */ unsigned short segment; /* loaded directly into CS */
union { union {
unsigned short off16; /* loaded directly into IP */ unsigned short off16; /* loaded directly into IP */
uint32_t off32; /* loaded directly into EIP */ uint32_t off32; /* loaded directly into EIP */
} offset; } offset;
} x86_absolute_t; } x86_absolute_t;
enum x86_op_type { /* mutually exclusive */ enum x86_op_type { /* mutually exclusive */
op_unused = 0, /* empty/unused operand: should never occur */ op_unused = 0, /* empty/unused operand: should never occur */
op_register = 1, /* CPU register */ op_register = 1, /* CPU register */
op_immediate = 2, /* Immediate Value */ op_immediate = 2, /* Immediate Value */
op_relative_near = 3, /* Relative offset from IP */ op_relative_near = 3, /* Relative offset from IP */
op_relative_far = 4, /* Relative offset from IP */ op_relative_far = 4, /* Relative offset from IP */
op_absolute = 5, /* Absolute address (ptr16:32) */ op_absolute = 5, /* Absolute address (ptr16:32) */
op_expression = 6, /* Address expression (scale/index/base/disp) */ op_expression = 6, /* Address expression (scale/index/base/disp) */
op_offset = 7, /* Offset from start of segment (m32) */ op_offset = 7, /* Offset from start of segment (m32) */
op_unknown op_unknown
}; };
#define x86_optype_is_address( optype ) \ #define x86_optype_is_address( optype ) \
( optype == op_absolute || optype == op_offset ) ( optype == op_absolute || optype == op_offset )
#define x86_optype_is_relative( optype ) \ #define x86_optype_is_relative( optype ) \
( optype == op_relative_near || optype == op_relative_far ) ( optype == op_relative_near || optype == op_relative_far )
#define x86_optype_is_memory( optype ) \ #define x86_optype_is_memory( optype ) \
( optype > op_immediate && optype < op_unknown ) ( optype > op_immediate && optype < op_unknown )
enum x86_op_datatype { /* these use Intel's lame terminology */ enum x86_op_datatype { /* these use Intel's lame terminology */
op_byte = 1, /* 1 byte integer */ op_byte = 1, /* 1 byte integer */
op_word = 2, /* 2 byte integer */ op_word = 2, /* 2 byte integer */
op_dword = 3, /* 4 byte integer */ op_dword = 3, /* 4 byte integer */
op_qword = 4, /* 8 byte integer */ op_qword = 4, /* 8 byte integer */
op_dqword = 5, /* 16 byte integer */ op_dqword = 5, /* 16 byte integer */
op_sreal = 6, /* 4 byte real (single real) */ op_sreal = 6, /* 4 byte real (single real) */
op_dreal = 7, /* 8 byte real (double real) */ op_dreal = 7, /* 8 byte real (double real) */
op_extreal = 8, /* 10 byte real (extended real) */ op_extreal = 8, /* 10 byte real (extended real) */
op_bcd = 9, /* 10 byte binary-coded decimal */ op_bcd = 9, /* 10 byte binary-coded decimal */
op_ssimd = 10, /* 16 byte : 4 packed single FP (SIMD, MMX) */ op_ssimd = 10, /* 16 byte : 4 packed single FP (SIMD, MMX) */
op_dsimd = 11, /* 16 byte : 2 packed double FP (SIMD, MMX) */ op_dsimd = 11, /* 16 byte : 2 packed double FP (SIMD, MMX) */
op_sssimd = 12, /* 4 byte : scalar single FP (SIMD, MMX) */ op_sssimd = 12, /* 4 byte : scalar single FP (SIMD, MMX) */
op_sdsimd = 13, /* 8 byte : scalar double FP (SIMD, MMX) */ op_sdsimd = 13, /* 8 byte : scalar double FP (SIMD, MMX) */
op_descr32 = 14, /* 6 byte Intel descriptor 2:4 */ op_descr32 = 14, /* 6 byte Intel descriptor 2:4 */
op_descr16 = 15, /* 4 byte Intel descriptor 2:2 */ op_descr16 = 15, /* 4 byte Intel descriptor 2:2 */
op_pdescr32 = 16, /* 6 byte Intel pseudo-descriptor 32:16 */ op_pdescr32 = 16, /* 6 byte Intel pseudo-descriptor 32:16 */
op_pdescr16 = 17, /* 6 byte Intel pseudo-descriptor 8:24:16 */ op_pdescr16 = 17, /* 6 byte Intel pseudo-descriptor 8:24:16 */
op_bounds16 = 18, /* signed 16:16 lower:upper bounds */ op_bounds16 = 18, /* signed 16:16 lower:upper bounds */
op_bounds32 = 19, /* signed 32:32 lower:upper bounds */ op_bounds32 = 19, /* signed 32:32 lower:upper bounds */
op_fpuenv16 = 20, /* 14 byte FPU control/environment data */ op_fpuenv16 = 20, /* 14 byte FPU control/environment data */
op_fpuenv32 = 21, /* 28 byte FPU control/environment data */ op_fpuenv32 = 21, /* 28 byte FPU control/environment data */
op_fpustate16 = 22, /* 94 byte FPU state (env & reg stack) */ op_fpustate16 = 22, /* 94 byte FPU state (env & reg stack) */
op_fpustate32 = 23, /* 108 byte FPU state (env & reg stack) */ op_fpustate32 = 23, /* 108 byte FPU state (env & reg stack) */
op_fpregset = 24, /* 512 bytes: register set */ op_fpregset = 24, /* 512 bytes: register set */
op_fpreg = 25, /* FPU register */ op_fpreg = 25, /* FPU register */
op_none = 0xFF /* operand without a datatype (INVLPG) */ op_none = 0xFF /* operand without a datatype (INVLPG) */
}; };
enum x86_op_access { /* ORed together */ enum x86_op_access { /* ORed together */
op_read = 1, op_read = 1,
op_write = 2, op_write = 2,
op_execute = 4 op_execute = 4
}; };
struct x86_op_flags { /* ORed together, but segs are mutually exclusive */ struct x86_op_flags { /* ORed together, but segs are mutually exclusive */
union { union {
unsigned int op_signed:1, /* signed integer */ unsigned int op_signed:1, /* signed integer */
op_string:1,// = 2, /* possible string or array */ op_string:1,// = 2, /* possible string or array */
op_constant:1,// = 4, /* symbolic constant */ op_constant:1,// = 4, /* symbolic constant */
op_pointer:1,// = 8, /* operand points to a memory address */ op_pointer:1,// = 8, /* operand points to a memory address */
op_sysref:1,// = 0x010, /* operand is a syscall number */ op_sysref:1,// = 0x010, /* operand is a syscall number */
op_implied:1,// = 0x020, /* operand is implicit in the insn */ op_implied:1,// = 0x020, /* operand is implicit in the insn */
op_hardcode:1,// = 0x40, /* operand is hardcoded in insn definition */ op_hardcode:1,// = 0x40, /* operand is hardcoded in insn definition */
/* NOTE: an 'implied' operand is one which can be considered a side /* NOTE: an 'implied' operand is one which can be considered a side
* effect of the insn, e.g. %esp being modified by PUSH or POP. A * effect of the insn, e.g. %esp being modified by PUSH or POP. A
* 'hard-coded' operand is one which is specified in the instruction * 'hard-coded' operand is one which is specified in the instruction
* definition, e.g. %es:%edi in MOVSB or 1 in ROL Eb, 1. The difference * definition, e.g. %es:%edi in MOVSB or 1 in ROL Eb, 1. The difference
* is that hard-coded operands are printed by disassemblers and are * is that hard-coded operands are printed by disassemblers and are
* required to re-assemble, while implicit operands are invisible. */ * required to re-assemble, while implicit operands are invisible. */
op_seg : 3; op_seg : 3;
unsigned int whole; unsigned int whole;
}; };
enum { enum {
@ -250,43 +250,43 @@ struct x86_op_flags { /* ORed together, but segs are mutually exclusive */
/* x86_op_t : an X86 instruction operand */ /* x86_op_t : an X86 instruction operand */
struct x86_op_t{ struct x86_op_t{
friend struct x86_insn_t; friend struct x86_insn_t;
enum x86_op_type type; /* operand type */ enum x86_op_type type; /* operand type */
enum x86_op_datatype datatype; /* operand size */ enum x86_op_datatype datatype; /* operand size */
enum x86_op_access access; /* operand access [RWX] */ enum x86_op_access access; /* operand access [RWX] */
x86_op_flags flags; /* misc flags */ x86_op_flags flags; /* misc flags */
union { union {
/* sizeof will have to work on these union members! */ /* sizeof will have to work on these union members! */
/* immediate values */ /* immediate values */
char sbyte; char sbyte;
short sword; short sword;
int32_t sdword; int32_t sdword;
qword_t sqword; qword_t sqword;
unsigned char byte; unsigned char byte;
unsigned short word; unsigned short word;
uint32_t dword; uint32_t dword;
qword_t qword; qword_t qword;
float sreal; float sreal;
double dreal; double dreal;
/* misc large/non-native types */ /* misc large/non-native types */
unsigned char extreal[10]; unsigned char extreal[10];
unsigned char bcd[10]; unsigned char bcd[10];
qword_t dqword[2]; qword_t dqword[2];
unsigned char simd[16]; unsigned char simd[16];
unsigned char fpuenv[28]; unsigned char fpuenv[28];
/* offset from segment */ /* offset from segment */
uint32_t offset; uint32_t offset;
/* ID of CPU register */ /* ID of CPU register */
x86_reg_t reg; x86_reg_t reg;
/* offsets from current insn */ /* offsets from current insn */
char relative_near; char relative_near;
int32_t relative_far; int32_t relative_far;
/* segment:offset */ /* segment:offset */
x86_absolute_t absolute; x86_absolute_t absolute;
/* effective address [expression] */ /* effective address [expression] */
x86_ea_t expression; x86_ea_t expression;
} data; } data;
/* this is needed to make formatting operands more sane */ /* this is needed to make formatting operands more sane */
void * insn; /* pointer to x86_insn_t owning operand */ void * insn; /* pointer to x86_insn_t owning operand */
size_t size() size_t size()
{ {
return operand_size(); return operand_size();
@ -301,6 +301,29 @@ struct x86_op_t{
bool is_relative( ) { bool is_relative( ) {
return ( type == op_relative_near || type == op_relative_far ); return ( type == op_relative_near || type == op_relative_far );
} }
int32_t getAddress()
{
assert(is_address()||is_relative());
switch(type)
{
case op_absolute:
{
if(datatype==op_descr16)
return (int32_t(data.absolute.segment)<<4) + data.absolute.offset.off16;
else
return (int32_t(data.absolute.segment)<<4) + data.absolute.offset.off32;
}
case op_offset:
return data.offset;
case op_relative_near:
return data.relative_near;
case op_relative_far:
return data.relative_far;
default:
assert(false);
return ~0;
}
}
char * format( enum x86_asm_format format ); char * format( enum x86_asm_format format );
x86_op_t * copy() x86_op_t * copy()
{ {
@ -319,119 +342,119 @@ private:
* list in an insn. Users wishing to add operands to this list, e.g. to add * list in an insn. Users wishing to add operands to this list, e.g. to add
* implicit operands, should use x86_operand_new in x86_operand_list.h */ * implicit operands, should use x86_operand_new in x86_operand_list.h */
struct x86_oplist_t { struct x86_oplist_t {
x86_op_t op; x86_op_t op;
struct x86_oplist_t *next; struct x86_oplist_t *next;
}; };
enum x86_insn_type { enum x86_insn_type {
insn_invalid = 0, /* invalid instruction */ insn_invalid = 0, /* invalid instruction */
/* insn_controlflow */ /* insn_controlflow */
insn_jmp = 0x1001, insn_jmp = 0x1001,
insn_jcc = 0x1002, insn_jcc = 0x1002,
insn_call = 0x1003, insn_call = 0x1003,
insn_callcc = 0x1004, insn_callcc = 0x1004,
insn_return = 0x1005, insn_return = 0x1005,
/* insn_arithmetic */ /* insn_arithmetic */
insn_add = 0x2001, insn_add = 0x2001,
insn_sub = 0x2002, insn_sub = 0x2002,
insn_mul = 0x2003, insn_mul = 0x2003,
insn_div = 0x2004, insn_div = 0x2004,
insn_inc = 0x2005, insn_inc = 0x2005,
insn_dec = 0x2006, insn_dec = 0x2006,
insn_shl = 0x2007, insn_shl = 0x2007,
insn_shr = 0x2008, insn_shr = 0x2008,
insn_rol = 0x2009, insn_rol = 0x2009,
insn_ror = 0x200A, insn_ror = 0x200A,
/* insn_logic */ /* insn_logic */
insn_and = 0x3001, insn_and = 0x3001,
insn_or = 0x3002, insn_or = 0x3002,
insn_xor = 0x3003, insn_xor = 0x3003,
insn_not = 0x3004, insn_not = 0x3004,
insn_neg = 0x3005, insn_neg = 0x3005,
/* insn_stack */ /* insn_stack */
insn_push = 0x4001, insn_push = 0x4001,
insn_pop = 0x4002, insn_pop = 0x4002,
insn_pushregs = 0x4003, insn_pushregs = 0x4003,
insn_popregs = 0x4004, insn_popregs = 0x4004,
insn_pushflags = 0x4005, insn_pushflags = 0x4005,
insn_popflags = 0x4006, insn_popflags = 0x4006,
insn_enter = 0x4007, insn_enter = 0x4007,
insn_leave = 0x4008, insn_leave = 0x4008,
/* insn_comparison */ /* insn_comparison */
insn_test = 0x5001, insn_test = 0x5001,
insn_cmp = 0x5002, insn_cmp = 0x5002,
/* insn_move */ /* insn_move */
insn_mov = 0x6001, /* move */ insn_mov = 0x6001, /* move */
insn_movcc = 0x6002, /* conditional move */ insn_movcc = 0x6002, /* conditional move */
insn_xchg = 0x6003, /* exchange */ insn_xchg = 0x6003, /* exchange */
insn_xchgcc = 0x6004, /* conditional exchange */ insn_xchgcc = 0x6004, /* conditional exchange */
/* insn_string */ /* insn_string */
insn_strcmp = 0x7001, insn_strcmp = 0x7001,
insn_strload = 0x7002, insn_strload = 0x7002,
insn_strmov = 0x7003, insn_strmov = 0x7003,
insn_strstore = 0x7004, insn_strstore = 0x7004,
insn_translate = 0x7005, /* xlat */ insn_translate = 0x7005, /* xlat */
/* insn_bit_manip */ /* insn_bit_manip */
insn_bittest = 0x8001, insn_bittest = 0x8001,
insn_bitset = 0x8002, insn_bitset = 0x8002,
insn_bitclear = 0x8003, insn_bitclear = 0x8003,
/* insn_flag_manip */ /* insn_flag_manip */
insn_clear_carry = 0x9001, insn_clear_carry = 0x9001,
insn_clear_zero = 0x9002, insn_clear_zero = 0x9002,
insn_clear_oflow = 0x9003, insn_clear_oflow = 0x9003,
insn_clear_dir = 0x9004, insn_clear_dir = 0x9004,
insn_clear_sign = 0x9005, insn_clear_sign = 0x9005,
insn_clear_parity = 0x9006, insn_clear_parity = 0x9006,
insn_set_carry = 0x9007, insn_set_carry = 0x9007,
insn_set_zero = 0x9008, insn_set_zero = 0x9008,
insn_set_oflow = 0x9009, insn_set_oflow = 0x9009,
insn_set_dir = 0x900A, insn_set_dir = 0x900A,
insn_set_sign = 0x900B, insn_set_sign = 0x900B,
insn_set_parity = 0x900C, insn_set_parity = 0x900C,
insn_tog_carry = 0x9010, insn_tog_carry = 0x9010,
insn_tog_zero = 0x9020, insn_tog_zero = 0x9020,
insn_tog_oflow = 0x9030, insn_tog_oflow = 0x9030,
insn_tog_dir = 0x9040, insn_tog_dir = 0x9040,
insn_tog_sign = 0x9050, insn_tog_sign = 0x9050,
insn_tog_parity = 0x9060, insn_tog_parity = 0x9060,
/* insn_fpu */ /* insn_fpu */
insn_fmov = 0xA001, insn_fmov = 0xA001,
insn_fmovcc = 0xA002, insn_fmovcc = 0xA002,
insn_fneg = 0xA003, insn_fneg = 0xA003,
insn_fabs = 0xA004, insn_fabs = 0xA004,
insn_fadd = 0xA005, insn_fadd = 0xA005,
insn_fsub = 0xA006, insn_fsub = 0xA006,
insn_fmul = 0xA007, insn_fmul = 0xA007,
insn_fdiv = 0xA008, insn_fdiv = 0xA008,
insn_fsqrt = 0xA009, insn_fsqrt = 0xA009,
insn_fcmp = 0xA00A, insn_fcmp = 0xA00A,
insn_fcos = 0xA00C, insn_fcos = 0xA00C,
insn_fldpi = 0xA00D, insn_fldpi = 0xA00D,
insn_fldz = 0xA00E, insn_fldz = 0xA00E,
insn_ftan = 0xA00F, insn_ftan = 0xA00F,
insn_fsine = 0xA010, insn_fsine = 0xA010,
insn_fsys = 0xA020, insn_fsys = 0xA020,
/* insn_interrupt */ /* insn_interrupt */
insn_int = 0xD001, insn_int = 0xD001,
insn_intcc = 0xD002, /* not present in x86 ISA */ insn_intcc = 0xD002, /* not present in x86 ISA */
insn_iret = 0xD003, insn_iret = 0xD003,
insn_bound = 0xD004, insn_bound = 0xD004,
insn_debug = 0xD005, insn_debug = 0xD005,
insn_trace = 0xD006, insn_trace = 0xD006,
insn_invalid_op = 0xD007, insn_invalid_op = 0xD007,
insn_oflow = 0xD008, insn_oflow = 0xD008,
/* insn_system */ /* insn_system */
insn_halt = 0xE001, insn_halt = 0xE001,
insn_in = 0xE002, /* input from port/bus */ insn_in = 0xE002, /* input from port/bus */
insn_out = 0xE003, /* output to port/bus */ insn_out = 0xE003, /* output to port/bus */
insn_cpuid = 0xE004, insn_cpuid = 0xE004,
insn_lmsw = 0xE005, insn_lmsw = 0xE005,
insn_smsw = 0xE006, insn_smsw = 0xE006,
insn_clts = 0xE007, insn_clts = 0xE007,
/* insn_other */ /* insn_other */
insn_nop = 0xF001, insn_nop = 0xF001,
insn_bcdconv = 0xF002, /* convert to or from BCD */ insn_bcdconv = 0xF002, /* convert to or from BCD */
insn_szconv = 0xF003 /* change size of operand */ insn_szconv = 0xF003 /* change size of operand */
}; };
/* These flags specify special characteristics of the instruction, such as /* These flags specify special characteristics of the instruction, such as
@ -440,11 +463,11 @@ enum x86_insn_type {
* NOTE : These may not be accurate for all instructions; updates to the * NOTE : These may not be accurate for all instructions; updates to the
* opcode tables have not been completed. */ * opcode tables have not been completed. */
enum x86_insn_note { enum x86_insn_note {
insn_note_ring0 = 1, /* Only available in ring 0 */ insn_note_ring0 = 1, /* Only available in ring 0 */
insn_note_smm = 2, /* "" in System Management Mode */ insn_note_smm = 2, /* "" in System Management Mode */
insn_note_serial = 4, /* Serializing instruction */ insn_note_serial = 4, /* Serializing instruction */
insn_note_nonswap = 8, /* Does not swap arguments in att-style formatting */ insn_note_nonswap = 8, /* Does not swap arguments in att-style formatting */
insn_note_nosuffix = 16 /* Does not have size suffix in att-style formatting */ insn_note_nosuffix = 16 /* Does not have size suffix in att-style formatting */
}; };
/* This specifies what effects the instruction has on the %eflags register */ /* This specifies what effects the instruction has on the %eflags register */
@ -458,22 +481,22 @@ enum x86_eflags
insn_eflag_parity insn_eflag_parity
}; };
enum x86_flag_status { enum x86_flag_status {
insn_carry_set = 0x1, /* CF */ insn_carry_set = 0x1, /* CF */
insn_zero_set = 0x2, /* ZF */ insn_zero_set = 0x2, /* ZF */
insn_oflow_set = 0x4, /* OF */ insn_oflow_set = 0x4, /* OF */
insn_dir_set = 0x8, /* DF */ insn_dir_set = 0x8, /* DF */
insn_sign_set = 0x10, /* SF */ insn_sign_set = 0x10, /* SF */
insn_parity_set = 0x20, /* PF */ insn_parity_set = 0x20, /* PF */
insn_carry_or_zero_set = 0x40, insn_carry_or_zero_set = 0x40,
insn_zero_set_or_sign_ne_oflow = 0x80, insn_zero_set_or_sign_ne_oflow = 0x80,
insn_carry_clear = 0x100, insn_carry_clear = 0x100,
insn_zero_clear = 0x200, insn_zero_clear = 0x200,
insn_oflow_clear = 0x400, insn_oflow_clear = 0x400,
insn_dir_clear = 0x800, insn_dir_clear = 0x800,
insn_sign_clear = 0x1000, insn_sign_clear = 0x1000,
insn_parity_clear = 0x2000, insn_parity_clear = 0x2000,
insn_sign_eq_oflow = 0x4000, insn_sign_eq_oflow = 0x4000,
insn_sign_ne_oflow = 0x8000 insn_sign_ne_oflow = 0x8000
}; };
/* The CPU model in which the insturction first appeared; this can be used /* The CPU model in which the insturction first appeared; this can be used
@ -482,19 +505,19 @@ enum x86_flag_status {
* NOTE : These may not be accurate for all instructions; updates to the * NOTE : These may not be accurate for all instructions; updates to the
* opcode tables have not been completed. */ * opcode tables have not been completed. */
enum x86_insn_cpu { enum x86_insn_cpu {
cpu_8086 = 1, /* Intel */ cpu_8086 = 1, /* Intel */
cpu_80286 = 2, cpu_80286 = 2,
cpu_80386 = 3, cpu_80386 = 3,
cpu_80387 = 4, cpu_80387 = 4,
cpu_80486 = 5, cpu_80486 = 5,
cpu_pentium = 6, cpu_pentium = 6,
cpu_pentiumpro = 7, cpu_pentiumpro = 7,
cpu_pentium2 = 8, cpu_pentium2 = 8,
cpu_pentium3 = 9, cpu_pentium3 = 9,
cpu_pentium4 = 10, cpu_pentium4 = 10,
cpu_k6 = 16, /* AMD */ cpu_k6 = 16, /* AMD */
cpu_k7 = 32, cpu_k7 = 32,
cpu_athlon = 48 cpu_athlon = 48
}; };
/* CPU ISA subsets: These are derived from the Instruction Groups in /* CPU ISA subsets: These are derived from the Instruction Groups in
@ -505,22 +528,22 @@ enum x86_insn_cpu {
* NOTE : These may not be accurate for all instructions; updates to the * NOTE : These may not be accurate for all instructions; updates to the
* opcode tables have not been completed. */ * opcode tables have not been completed. */
enum x86_insn_isa { enum x86_insn_isa {
isa_gp = 1, /* general purpose */ isa_gp = 1, /* general purpose */
isa_fp = 2, /* floating point */ isa_fp = 2, /* floating point */
isa_fpumgt = 3, /* FPU/SIMD management */ isa_fpumgt = 3, /* FPU/SIMD management */
isa_mmx = 4, /* Intel MMX */ isa_mmx = 4, /* Intel MMX */
isa_sse1 = 5, /* Intel SSE SIMD */ isa_sse1 = 5, /* Intel SSE SIMD */
isa_sse2 = 6, /* Intel SSE2 SIMD */ isa_sse2 = 6, /* Intel SSE2 SIMD */
isa_sse3 = 7, /* Intel SSE3 SIMD */ isa_sse3 = 7, /* Intel SSE3 SIMD */
isa_3dnow = 8, /* AMD 3DNow! SIMD */ isa_3dnow = 8, /* AMD 3DNow! SIMD */
isa_sys = 9 /* system instructions */ isa_sys = 9 /* system instructions */
}; };
enum x86_insn_prefix { enum x86_insn_prefix {
insn_no_prefix = 0, insn_no_prefix = 0,
insn_rep_zero = 1, /* REPZ and REPE */ insn_rep_zero = 1, /* REPZ and REPE */
insn_rep_notzero = 2, /* REPNZ and REPNZ */ insn_rep_notzero = 2, /* REPNZ and REPNZ */
insn_lock = 4 /* LOCK: */ insn_lock = 4 /* LOCK: */
}; };
@ -535,15 +558,15 @@ enum x86_insn_prefix {
* The "type" (implicit or explicit) and the access method can * The "type" (implicit or explicit) and the access method can
* be ORed together, e.g. op_wo | op_explicit */ * be ORed together, e.g. op_wo | op_explicit */
enum x86_op_foreach_type { enum x86_op_foreach_type {
op_any = 0, /* ALL operands (explicit, implicit, rwx) */ op_any = 0, /* ALL operands (explicit, implicit, rwx) */
op_dest = 1, /* operands with Write access */ op_dest = 1, /* operands with Write access */
op_src = 2, /* operands with Read access */ op_src = 2, /* operands with Read access */
op_ro = 3, /* operands with Read but not Write access */ op_ro = 3, /* operands with Read but not Write access */
op_wo = 4, /* operands with Write but not Read access */ op_wo = 4, /* operands with Write but not Read access */
op_xo = 5, /* operands with Execute access */ op_xo = 5, /* operands with Execute access */
op_rw = 6, /* operands with Read AND Write access */ op_rw = 6, /* operands with Read AND Write access */
op_implicit = 0x10, /* operands that are implied by the opcode */ op_implicit = 0x10, /* operands that are implied by the opcode */
op_explicit = 0x20 /* operands that are not side-effects */ op_explicit = 0x20 /* operands that are not side-effects */
}; };
/* Operand FOREACH callback: 'arg' is an abritrary parameter passed to the /* Operand FOREACH callback: 'arg' is an abritrary parameter passed to the
@ -684,9 +707,9 @@ public:
* (buf, buf_len, buf_rva, offset, len, insn, func, arg, resolve_func) * (buf, buf_len, buf_rva, offset, len, insn, func, arg, resolve_func)
* ...but of course all of these are not used at the same time. * ...but of course all of these are not used at the same time.
*/ */
class X86_Disasm class X86_Disasm
{ {
public: public:
/* Function prototype for caller-supplied callback routine /* Function prototype for caller-supplied callback routine
* These callbacks are intended to process 'insn' further, e.g. by * These callbacks are intended to process 'insn' further, e.g. by
* adding it to a linked list, database, etc */ * adding it to a linked list, database, etc */
@ -701,28 +724,28 @@ public:
* should return -1; in all other cases the RVA to be disassembled next * should return -1; in all other cases the RVA to be disassembled next
* should be returned. */ * should be returned. */
typedef int32_t (*DISASM_RESOLVER)( x86_op_t *op, x86_insn_t * current_insn, typedef int32_t (*DISASM_RESOLVER)( x86_op_t *op, x86_insn_t * current_insn,
void *arg ); void *arg );
protected: protected:
DISASM_REPORTER __x86_reporter_func; DISASM_REPORTER __x86_reporter_func;
void * __x86_reporter_arg; void * __x86_reporter_arg;
Ia32_Decoder m_decoder; Ia32_Decoder m_decoder;
public: public:
X86_Disasm( x86_options options=opt_none,DISASM_REPORTER reporter=0, void *arg=0 ) : X86_Disasm( x86_options options=opt_none,DISASM_REPORTER reporter=0, void *arg=0 ) :
__x86_reporter_func(reporter), __x86_reporter_func(reporter),
__x86_reporter_arg(arg) { __x86_reporter_arg(arg) {
x86_init( options,reporter,arg); x86_init( options,reporter,arg);
} }
/* management routines */ /* management routines */
/* 'arg' is caller-specific data which is passed as the first argument /* 'arg' is caller-specific data which is passed as the first argument
* to the reporter callback routine */ * to the reporter callback routine */
int x86_init( x86_options options, DISASM_REPORTER reporter, void *arg); int x86_init( x86_options options, DISASM_REPORTER reporter, void *arg);
void x86_set_reporter( DISASM_REPORTER reporter, void *arg); void x86_set_reporter( DISASM_REPORTER reporter, void *arg);
void x86_set_options( x86_options options ); void x86_set_options( x86_options options );
x86_options x86_get_options( void ); x86_options x86_get_options( void );
int x86_cleanup(void); int x86_cleanup(void);
/* x86_disasm: Disassemble a single instruction from a buffer of bytes. /* x86_disasm: Disassemble a single instruction from a buffer of bytes.
* Returns size of instruction in bytes. * Returns size of instruction in bytes.
* Caller is responsible for calling x86_oplist_free() on * Caller is responsible for calling x86_oplist_free() on
* a reused "insn" to avoid leaking memory when calling this * a reused "insn" to avoid leaking memory when calling this
@ -733,9 +756,9 @@ public:
* offset : Offset in buffer to disassemble * offset : Offset in buffer to disassemble
* insn : Structure to fill with disassembled instruction * insn : Structure to fill with disassembled instruction
*/ */
unsigned int x86_disasm( unsigned char *buf, unsigned int buf_len, unsigned int x86_disasm(const unsigned char *buf, unsigned int buf_len,
uint32_t buf_rva, unsigned int offset, uint32_t buf_rva, unsigned int offset,
x86_insn_t * insn ); x86_insn_t * insn );
/* x86_disasm_range: Sequential disassembly of a range of bytes in a buffer, /* x86_disasm_range: Sequential disassembly of a range of bytes in a buffer,
* invoking a callback function each time an instruction * invoking a callback function each time an instruction
* is successfully disassembled. The 'range' refers to the * is successfully disassembled. The 'range' refers to the
@ -794,7 +817,7 @@ public:
unsigned int x86_ip_reg(void); unsigned int x86_ip_reg(void);
unsigned int x86_flag_reg(void); unsigned int x86_flag_reg(void);
}; };
/* Instruction operands: these are stored as a list of explicit and /* Instruction operands: these are stored as a list of explicit and
* implicit operands. It is recommended that the 'foreach' routines * implicit operands. It is recommended that the 'foreach' routines
@ -843,24 +866,24 @@ public:
#define X86_WILDCARD_BYTE 0xF4 #define X86_WILDCARD_BYTE 0xF4
struct x86_invariant_op_t{ struct x86_invariant_op_t{
enum x86_op_type type; /* operand type */ enum x86_op_type type; /* operand type */
enum x86_op_datatype datatype; /* operand size */ enum x86_op_datatype datatype; /* operand size */
enum x86_op_access access; /* operand access [RWX] */ enum x86_op_access access; /* operand access [RWX] */
x86_op_flags flags; /* misc flags */ x86_op_flags flags; /* misc flags */
}; };
struct x86_invariant_t { struct x86_invariant_t {
unsigned char bytes[64]; /* invariant representation */ unsigned char bytes[64]; /* invariant representation */
unsigned int size; /* number of bytes in insn */ unsigned int size; /* number of bytes in insn */
x86_insn_t::x86_insn_group group; /* meta-type, e.g. INS_EXEC */ x86_insn_t::x86_insn_group group; /* meta-type, e.g. INS_EXEC */
enum x86_insn_type type; /* type, e.g. INS_BRANCH */ enum x86_insn_type type; /* type, e.g. INS_BRANCH */
x86_invariant_op_t operands[3]; /* operands: dest, src, imm */ x86_invariant_op_t operands[3]; /* operands: dest, src, imm */
} ; } ;
/* return a version of the instruction with the variant bytes masked out */ /* return a version of the instruction with the variant bytes masked out */
size_t x86_invariant_disasm( unsigned char *buf, int buf_len, size_t x86_invariant_disasm( unsigned char *buf, int buf_len,
x86_invariant_t *inv ); x86_invariant_t *inv );
/* return the size in bytes of the intruction pointed to by 'buf'; /* return the size in bytes of the intruction pointed to by 'buf';
* this used x86_invariant_disasm since it faster than x86_disasm */ * this used x86_invariant_disasm since it faster than x86_disasm */
size_t x86_size_disasm( unsigned char *buf, unsigned int buf_len ); size_t x86_size_disasm( unsigned char *buf, unsigned int buf_len );

View File

@ -21,7 +21,7 @@ void x86_insn_t::make_invalid(unsigned char *buf)
type = insn_invalid; type = insn_invalid;
memcpy( bytes, buf, 1 ); memcpy( bytes, buf, 1 );
} }
unsigned int X86_Disasm::x86_disasm( unsigned char *buf, unsigned int buf_len, unsigned int X86_Disasm::x86_disasm( const unsigned char *buf, unsigned int buf_len,
uint32_t buf_rva, unsigned int offset, uint32_t buf_rva, unsigned int offset,
x86_insn_t *insn ){ x86_insn_t *insn ){
int len, size; int len, size;

View File

@ -25,7 +25,7 @@ ENDIF()
ADD_SUBDIRECTORY(3rd_party) ADD_SUBDIRECTORY(3rd_party)
llvm_map_components_to_libraries(REQ_LLVM_LIBRARIES jit native mc support) llvm_map_components_to_libraries(REQ_LLVM_LIBRARIES jit native mc support tablegen)
INCLUDE_DIRECTORIES( INCLUDE_DIRECTORIES(
3rd_party/libdisasm 3rd_party/libdisasm
include include
@ -50,6 +50,7 @@ set(dcc_LIB_SOURCES
src/hltype.cpp src/hltype.cpp
src/machine_x86.cpp src/machine_x86.cpp
src/icode.cpp src/icode.cpp
src/RegisterNode
src/idioms.cpp src/idioms.cpp
src/idioms/idiom1.cpp src/idioms/idiom1.cpp
src/idioms/arith_idioms.cpp src/idioms/arith_idioms.cpp

View File

@ -3,4 +3,4 @@
#make -j5 #make -j5
#cd .. #cd ..
./test_use_base.sh ./test_use_base.sh
./regression_tester.rb ./dcc_original -s -c 2>stderr >stdout; diff tests/prev/ tests/outputs/ ./regression_tester.rb ./dcc_original -s -c 2>stderr >stdout; diff -wB tests/prev/ tests/outputs/

View File

@ -1,3 +1,3 @@
#!/bin/bash #!/bin/bash
./test_use_all.sh ./test_use_all.sh
./regression_tester.rb ./dcc_original -s -c 2>stderr >stdout; diff tests/prev/ tests/outputs/ ./regression_tester.rb ./dcc_original -s -c 2>stderr >stdout; diff -wB tests/prev/ tests/outputs/

View File

@ -15,6 +15,7 @@ struct PROG /* Loaded program image parameters */
uint16_t segMain; /* The segment of the main() proc */ uint16_t segMain; /* The segment of the main() proc */
bool bSigs; /* True if signatures loaded */ bool bSigs; /* True if signatures loaded */
int cbImage; /* Length of image in bytes */ int cbImage; /* Length of image in bytes */
uint8_t * Image; /* Allocated by loader to hold entire program image */ const uint8_t *image() const {return Imagez;}
uint8_t * Imagez; /* Allocated by loader to hold entire program image */
}; };

View File

@ -8,6 +8,7 @@ enum regType
}; };
enum condId enum condId
{ {
UNDEF=0,
GLOB_VAR, /* global variable */ GLOB_VAR, /* global variable */
REGISTER, /* register */ REGISTER, /* register */
LOCAL_VAR, /* negative disp */ LOCAL_VAR, /* negative disp */

View File

@ -2,32 +2,29 @@
#include "ast.h" #include "ast.h"
#include "types.h" #include "types.h"
#include "machine_x86.h" #include "machine_x86.h"
struct GlobalVariable;
struct AstIdent;
struct IDENTTYPE struct IDENTTYPE
{ {
friend struct GlobalVariable;
friend struct Constant;
friend struct AstIdent;
protected:
condId idType; condId idType;
regType regiType; /* for REGISTER only */ public:
condId type() {return idType;}
void type(condId t) {idType=t;}
union _idNode { union _idNode {
int regiIdx; /* index into localId, REGISTER */
int globIdx; /* index into symtab for GLOB_VAR */
int localIdx; /* idx into localId, LOCAL_VAR */ int localIdx; /* idx into localId, LOCAL_VAR */
int paramIdx; /* idx into args symtab, PARAMS */ int paramIdx; /* idx into args symtab, PARAMS */
int idxGlbIdx; /* idx into localId, GLOB_VAR_IDX */
struct _kte
{ /* for CONSTANT only */
uint32_t kte; /* value of the constant */
uint8_t size; /* #bytes size constant */
} kte;
uint32_t strIdx; /* idx into image, for STRING */ uint32_t strIdx; /* idx into image, for STRING */
int longIdx; /* idx into LOCAL_ID table, LONG_VAR*/ int longIdx; /* idx into LOCAL_ID table, LONG_VAR*/
struct _call { /* for FUNCTION only */
Function *proc;
STKFRAME *args;
} call;
struct { /* for OTHER; tmp struct */ struct { /* for OTHER; tmp struct */
eReg seg; /* segment */ eReg seg; /* segment */
eReg regi; /* index mode */ eReg regi; /* index mode */
int16_t off; /* offset */ int16_t off; /* offset */
} other; } other;
} idNode; } idNode;
IDENTTYPE() : idType(UNDEF)
{}
}; };

View File

@ -9,7 +9,7 @@
#include "StackFrame.h" #include "StackFrame.h"
/* PROCEDURE NODE */ /* PROCEDURE NODE */
struct CALL_GRAPH; struct CALL_GRAPH;
struct COND_EXPR; struct Expr;
struct Disassembler; struct Disassembler;
struct Function; struct Function;
struct CALL_GRAPH; struct CALL_GRAPH;
@ -74,8 +74,8 @@ struct FunctionType
}; };
struct Assignment struct Assignment
{ {
COND_EXPR *lhs; Expr *lhs;
COND_EXPR *rhs; Expr *rhs;
}; };
struct JumpTable struct JumpTable
{ {
@ -184,9 +184,11 @@ public:
void displayCFG(); void displayCFG();
void displayStats(); void displayStats();
void processHliCall(COND_EXPR *exp, iICODE picode); void processHliCall(Expr *exp, iICODE picode);
void preprocessReturnDU(LivenessSet &_liveOut); void preprocessReturnDU(LivenessSet &_liveOut);
Expr * adjustActArgType(Expr *_exp, hlType forType);
std::string writeCall(Function *tproc, STKFRAME &args, int *numLoc);
protected: protected:
void extractJumpTableRange(ICODE& pIcode, STATE *pstate, JumpTable &table); void extractJumpTableRange(ICODE& pIcode, STATE *pstate, JumpTable &table);
bool followAllTableEntries(JumpTable &table, uint32_t cs, ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate); bool followAllTableEntries(JumpTable &table, uint32_t cs, ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);

View File

@ -5,6 +5,7 @@
* (C) Cristina Cifuentes * (C) Cristina Cifuentes
*/ */
#pragma once #pragma once
#include <stdint.h>
#include <cstring> #include <cstring>
#include <list> #include <list>
#include <boost/range/iterator_range.hpp> #include <boost/range/iterator_range.hpp>
@ -34,37 +35,37 @@ typedef boost::iterator_range<iICODE> rICODE;
#include "IdentType.h" #include "IdentType.h"
/* Expression data type */ /* Expression data type */
struct COND_EXPR struct Expr
{ {
public: public:
condNodeType m_type; /* Conditional Expression Node Type */ condNodeType m_type; /* Conditional Expression Node Type */
public: public:
static bool insertSubTreeLongReg(COND_EXPR *exp, COND_EXPR *&tree, int longIdx); static bool insertSubTreeLongReg(Expr *exp, Expr *&tree, int longIdx);
static bool insertSubTreeReg(COND_EXPR *&tree, COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym); static bool insertSubTreeReg(Expr *&tree, Expr *_expr, eReg regi, const LOCAL_ID *locsym);
static bool insertSubTreeReg(AstIdent *&tree, COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym); static bool insertSubTreeReg(AstIdent *&tree, Expr *_expr, eReg regi, const LOCAL_ID *locsym);
public: public:
virtual COND_EXPR *clone() const;
void release(); virtual Expr *clone() const=0; //!< Makes a deep copy of the given expression
COND_EXPR(condNodeType t=UNKNOWN_OP) : m_type(t) Expr(condNodeType t=UNKNOWN_OP) : m_type(t)
{ {
} }
virtual ~COND_EXPR(); virtual ~Expr();
public: public:
virtual std::string walkCondExpr (Function * pProc, int* numLoc) const=0; virtual std::string walkCondExpr (Function * pProc, int* numLoc) const=0;
virtual COND_EXPR *inverse() const=0; // return new COND_EXPR that is invarse of this virtual Expr *inverse() const=0; // return new COND_EXPR that is invarse of this
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId)=0; virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId)=0;
virtual COND_EXPR *insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym)=0; virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym)=0;
virtual COND_EXPR *insertSubTreeLongReg(COND_EXPR *_expr, int longIdx)=0; virtual Expr *insertSubTreeLongReg(Expr *_expr, int longIdx)=0;
virtual hlType expType(Function *pproc) const; virtual hlType expType(Function *pproc) const=0;
virtual int hlTypeSize(Function *pproc) const=0; virtual int hlTypeSize(Function *pproc) const=0;
virtual void performLongRemoval(eReg regi, LOCAL_ID *locId) {} virtual Expr * performLongRemoval(eReg regi, LOCAL_ID *locId) { return this; }
}; };
struct UnaryOperator : public COND_EXPR struct UnaryOperator : public Expr
{ {
UnaryOperator(condNodeType t=UNKNOWN_OP) : COND_EXPR(t),unaryExp(nullptr) {} UnaryOperator(condNodeType t=UNKNOWN_OP) : Expr(t),unaryExp(nullptr) {}
COND_EXPR *unaryExp; Expr *unaryExp;
virtual COND_EXPR *inverse() const virtual Expr *inverse() const
{ {
if (m_type == NEGATION) //TODO: memleak here if (m_type == NEGATION) //TODO: memleak here
{ {
@ -72,14 +73,14 @@ struct UnaryOperator : public COND_EXPR
} }
return this->clone(); return this->clone();
} }
virtual COND_EXPR *clone() const virtual Expr *clone() const
{ {
UnaryOperator *newExp = new UnaryOperator(*this); UnaryOperator *newExp = new UnaryOperator(*this);
newExp->unaryExp = unaryExp->clone(); newExp->unaryExp = unaryExp->clone();
return newExp; return newExp;
} }
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs); virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs);
static UnaryOperator *Create(condNodeType t, COND_EXPR *sub_expr) static UnaryOperator *Create(condNodeType t, Expr *sub_expr)
{ {
UnaryOperator *newExp = new UnaryOperator(); UnaryOperator *newExp = new UnaryOperator();
newExp->m_type = t; newExp->m_type = t;
@ -94,22 +95,22 @@ struct UnaryOperator : public COND_EXPR
public: public:
int hlTypeSize(Function *pproc) const; int hlTypeSize(Function *pproc) const;
virtual std::string walkCondExpr(Function *pProc, int *numLoc) const; virtual std::string walkCondExpr(Function *pProc, int *numLoc) const;
virtual COND_EXPR *insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym); virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym);
virtual hlType expType(Function *pproc) const; virtual hlType expType(Function *pproc) const;
virtual COND_EXPR *insertSubTreeLongReg(COND_EXPR *_expr, int longIdx); virtual Expr *insertSubTreeLongReg(Expr *_expr, int longIdx);
}; };
struct BinaryOperator : public COND_EXPR struct BinaryOperator : public Expr
{ {
condOp m_op; condOp m_op;
COND_EXPR *m_lhs; Expr *m_lhs;
COND_EXPR *m_rhs; Expr *m_rhs;
BinaryOperator(condOp o) : COND_EXPR(BOOLEAN_OP) BinaryOperator(condOp o) : Expr(BOOLEAN_OP)
{ {
m_op = o; m_op = o;
m_lhs=m_rhs=nullptr; m_lhs=m_rhs=nullptr;
} }
BinaryOperator(condOp o,COND_EXPR *l,COND_EXPR *r) : COND_EXPR(BOOLEAN_OP) BinaryOperator(condOp o,Expr *l,Expr *r) : Expr(BOOLEAN_OP)
{ {
m_op = o; m_op = o;
m_lhs=l; m_lhs=l;
@ -121,51 +122,51 @@ struct BinaryOperator : public COND_EXPR
delete m_lhs; delete m_lhs;
delete m_rhs; delete m_rhs;
} }
static BinaryOperator *Create(condOp o,COND_EXPR *l,COND_EXPR *r) static BinaryOperator *Create(condOp o,Expr *l,Expr *r)
{ {
BinaryOperator *res = new BinaryOperator(o); BinaryOperator *res = new BinaryOperator(o);
res->m_lhs = l; res->m_lhs = l;
res->m_rhs = r; res->m_rhs = r;
return res; return res;
} }
static BinaryOperator *LogicAnd(COND_EXPR *l,COND_EXPR *r) static BinaryOperator *LogicAnd(Expr *l,Expr *r)
{ {
return new BinaryOperator(DBL_AND,l,r); return new BinaryOperator(DBL_AND,l,r);
} }
static BinaryOperator *And(COND_EXPR *l,COND_EXPR *r) static BinaryOperator *And(Expr *l,Expr *r)
{ {
return new BinaryOperator(AND,l,r); return new BinaryOperator(AND,l,r);
} }
static BinaryOperator *Or(COND_EXPR *l,COND_EXPR *r) static BinaryOperator *Or(Expr *l,Expr *r)
{ {
return new BinaryOperator(OR,l,r); return new BinaryOperator(OR,l,r);
} }
static BinaryOperator *LogicOr(COND_EXPR *l,COND_EXPR *r) static BinaryOperator *LogicOr(Expr *l,Expr *r)
{ {
return new BinaryOperator(DBL_OR,l,r); return new BinaryOperator(DBL_OR,l,r);
} }
static BinaryOperator *CreateAdd(COND_EXPR *l,COND_EXPR *r); static BinaryOperator *CreateAdd(Expr *l,Expr *r);
void changeBoolOp(condOp newOp); void changeBoolOp(condOp newOp);
virtual COND_EXPR *inverse() const; virtual Expr *inverse() const;
virtual COND_EXPR *clone() const; virtual Expr *clone() const;
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs); virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs);
virtual COND_EXPR *insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym); virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym);
virtual COND_EXPR *insertSubTreeLongReg(COND_EXPR *_expr, int longIdx); virtual Expr *insertSubTreeLongReg(Expr *_expr, int longIdx);
const COND_EXPR *lhs() const const Expr *lhs() const
{ {
return const_cast<const COND_EXPR *>(const_cast<BinaryOperator *>(this)->lhs()); return const_cast<const Expr *>(const_cast<BinaryOperator *>(this)->lhs());
} }
const COND_EXPR *rhs() const const Expr *rhs() const
{ {
return const_cast<const COND_EXPR *>(const_cast<BinaryOperator *>(this)->rhs()); return const_cast<const Expr *>(const_cast<BinaryOperator *>(this)->rhs());
} }
COND_EXPR *lhs() Expr *lhs()
{ {
assert(m_type==BOOLEAN_OP); assert(m_type==BOOLEAN_OP);
return m_lhs; return m_lhs;
} }
COND_EXPR *rhs() Expr *rhs()
{ {
assert(m_type==BOOLEAN_OP); assert(m_type==BOOLEAN_OP);
return m_rhs; return m_rhs;
@ -182,31 +183,27 @@ struct AstIdent : public UnaryOperator
{ {
AstIdent() : UnaryOperator(IDENTIFIER) AstIdent() : UnaryOperator(IDENTIFIER)
{ {
memset(&ident,0,sizeof(ident));
} }
virtual COND_EXPR *clone() const IDENTTYPE ident; /* for IDENTIFIER */
static AstIdent * Loc(int off, LOCAL_ID *localId);
static AstIdent * LongIdx(int idx);
static AstIdent * String(uint32_t idx);
static AstIdent * Other(eReg seg, eReg regi, int16_t off);
static AstIdent * Param(int off, const STKFRAME *argSymtab);
static AstIdent * Long(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset);
static AstIdent * idID(const ID *retVal, LOCAL_ID *locsym, iICODE ix_);
static Expr * id(const LLInst &ll_insn, opLoc sd, Function *pProc, iICODE ix_, ICODE &duIcode, operDu du);
virtual Expr *clone() const
{ {
return new AstIdent(*this); return new AstIdent(*this);
} }
IDENTTYPE ident; /* for IDENTIFIER */
static AstIdent * RegIdx(int idx, regType reg_type);
static AstIdent * Kte(uint32_t kte, uint8_t size);
static AstIdent * Loc(int off, LOCAL_ID *localId);
static AstIdent * Reg(eReg regi, uint32_t icodeFlg, LOCAL_ID *locsym);
static AstIdent * LongIdx(int idx);
static AstIdent * Other(eReg seg, eReg regi, int16_t off);
static AstIdent * idParam(int off, const STKFRAME *argSymtab);
static AstIdent * idLong(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset);
static AstIdent * idFunc(Function *pproc, STKFRAME *args);
static AstIdent * idID(const ID *retVal, LOCAL_ID *locsym, iICODE ix_);
static COND_EXPR * id(const LLInst &ll_insn, opLoc sd, Function *pProc, iICODE ix_, ICODE &duIcode, operDu du);
virtual int hlTypeSize(Function *pproc) const; virtual int hlTypeSize(Function *pproc) const;
virtual hlType expType(Function *pproc) const; virtual hlType expType(Function *pproc) const;
virtual void performLongRemoval(eReg regi, LOCAL_ID *locId); virtual Expr * performLongRemoval(eReg regi, LOCAL_ID *locId);
virtual std::string walkCondExpr(Function *pProc, int *numLoc) const; virtual std::string walkCondExpr(Function *pProc, int *numLoc) const;
virtual COND_EXPR *insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym); virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym);
virtual COND_EXPR *insertSubTreeLongReg(COND_EXPR *_expr, int longIdx); virtual Expr *insertSubTreeLongReg(Expr *_expr, int longIdx);
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId); virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId);
protected: protected:
eReg otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl); eReg otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl);
@ -214,7 +211,94 @@ protected:
}; };
struct GlobalVariable : public AstIdent struct GlobalVariable : public AstIdent
{ {
static AstIdent *Create(int16_t segValue, int16_t off); bool valid;
int globIdx;
virtual Expr *clone() const
{
return new GlobalVariable(*this);
}
GlobalVariable(int16_t segValue, int16_t off);
std::string walkCondExpr(Function *pProc, int *numLoc) const;
int hlTypeSize(Function *pproc) const;
hlType expType(Function *pproc) const;
};
struct GlobalVariableIdx : public AstIdent
{
bool valid;
int idxGlbIdx; /* idx into localId, GLOB_VAR_IDX */
virtual Expr *clone() const
{
return new GlobalVariableIdx(*this);
}
GlobalVariableIdx(int16_t segValue, int16_t off, uint8_t regi, const LOCAL_ID *locSym);
std::string walkCondExpr(Function *pProc, int *numLoc) const;
int hlTypeSize(Function *pproc) const;
hlType expType(Function *pproc) const;
};
struct Constant : public AstIdent
{
struct _kte
{ /* for CONSTANT only */
uint32_t kte; /* value of the constant */
uint8_t size; /* #bytes size constant */
} kte;
Constant(uint32_t _kte, uint8_t size)
{
ident.idType = CONSTANT;
kte.kte = _kte;
kte.size = size;
}
virtual Expr *clone() const
{
return new Constant(*this);
}
std::string walkCondExpr(Function *pProc, int *numLoc) const;
int hlTypeSize(Function *pproc) const;
hlType expType(Function *pproc) const;
};
struct FuncNode : public AstIdent
{
struct _call { /* for FUNCTION only */
Function *proc;
STKFRAME *args;
} call;
FuncNode(Function *pproc, STKFRAME *args)
{
call.proc = pproc;
call.args = args;
}
virtual Expr *clone() const
{
return new FuncNode(*this);
}
std::string walkCondExpr(Function *pProc, int *numLoc) const;
int hlTypeSize(Function *pproc) const;
hlType expType(Function *pproc) const;
};
struct RegisterNode : public AstIdent
{
regType regiType; /* for REGISTER only */
int regiIdx; /* index into localId, REGISTER */
virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym);
RegisterNode(int idx, regType reg_type)
{
ident.type(REGISTER);
regiType = reg_type;
regiIdx = idx;
}
RegisterNode(eReg regi, uint32_t icodeFlg, LOCAL_ID *locsym);
virtual Expr *clone() const
{
return new RegisterNode(*this);
}
std::string walkCondExpr(Function *pProc, int *numLoc) const;
int hlTypeSize(Function *) const;
hlType expType(Function *pproc) const;
bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId);
}; };
struct Constant : public COND_EXPR
{};

View File

@ -33,7 +33,7 @@ public:
int current_indent; int current_indent;
}; };
extern bundle cCode;
#define lineSize 360 /* 3 lines in the mean time */ #define lineSize 360 /* 3 lines in the mean time */
//void newBundle (bundle *procCode); //void newBundle (bundle *procCode);

View File

@ -37,9 +37,6 @@ public:
bool insertCallGraph(Function *caller, ilFunction callee); bool insertCallGraph(Function *caller, ilFunction callee);
void insertArc(ilFunction newProc); void insertArc(ilFunction newProc);
}; };
//#define NUM_PROCS_DELTA 5 /* delta # procs a proc invokes */
//extern std::list<Function> pProcList;
//extern FunctionListType pProcList;
//extern CALL_GRAPH * callGraph; /* Pointer to the head of the call graph */ //extern CALL_GRAPH * callGraph; /* Pointer to the head of the call graph */
extern bundle cCode; /* Output C procedure's declaration and code */ extern bundle cCode; /* Output C procedure's declaration and code */
@ -110,11 +107,11 @@ void udm(void); /* udm.c */
void freeCFG(BB * cfg); /* graph.c */ void freeCFG(BB * cfg); /* graph.c */
BB * newBB(BB *, int, int, uint8_t, int, Function *); /* graph.c */ BB * newBB(BB *, int, int, uint8_t, int, Function *); /* graph.c */
void BackEnd(char *filename, CALL_GRAPH *); /* backend.c */ void BackEnd(char *filename, CALL_GRAPH *); /* backend.c */
char *cChar(uint8_t c); /* backend.c */ extern char *cChar(uint8_t c); /* backend.c */
eErrorId scan(uint32_t ip, ICODE &p); /* scanner.c */ eErrorId scan(uint32_t ip, ICODE &p); /* scanner.c */
void parse (CALL_GRAPH * *); /* parser.c */ void parse (CALL_GRAPH * *); /* parser.c */
int strSize (uint8_t *, char); /* parser.c */ extern int strSize (const uint8_t *, char); /* parser.c */
//void disassem(int pass, Function * pProc); /* disassem.c */ //void disassem(int pass, Function * pProc); /* disassem.c */
void interactDis(Function *, int initIC); /* disassem.c */ void interactDis(Function *, int initIC); /* disassem.c */
bool JmpInst(llIcode opcode); /* idioms.c */ bool JmpInst(llIcode opcode); /* idioms.c */
@ -126,10 +123,8 @@ bool LibCheck(Function &p); /* chklib.c */
/* Exported functions from procs.c */ /* Exported functions from procs.c */
boolT insertCallGraph (CALL_GRAPH *, ilFunction, ilFunction); boolT insertCallGraph (CALL_GRAPH *, ilFunction, ilFunction);
void adjustActArgType (COND_EXPR *, hlType, Function *);
/* Exported functions from hlicode.c */ /* Exported functions from hlicode.c */
std::string writeCall (Function *, STKFRAME &, Function *, int *);
char *writeJcond (const HLTYPE &, Function *, int *); char *writeJcond (const HLTYPE &, Function *, int *);
char *writeJcondInv (HLTYPE, Function *, int *); char *writeJcondInv (HLTYPE, Function *, int *);

View File

@ -1,7 +1,10 @@
/***************************************************************************** /*
****************************************************************************
* Error codes * Error codes
* (C) Cristina Cifuentes * (C) Cristina Cifuentes
****************************************************************************/ ***************************************************************************
*/
#pragma once #pragma once
/* These definitions refer to errorMessage in error.c */ /* These definitions refer to errorMessage in error.c */

View File

@ -65,6 +65,8 @@ struct LivenessSet : public std::bitset<32>
{ {
return test(r-rAX); return test(r-rAX);
} }
public:
LivenessSet &clrReg(int r);
private: private:
void postProcessCompositeRegs(); void postProcessCompositeRegs();
}; };
@ -83,15 +85,16 @@ struct DU
#define MAX_REGS_DEF 4 /* 2 regs def'd for long-reg vars */ #define MAX_REGS_DEF 4 /* 2 regs def'd for long-reg vars */
struct COND_EXPR; struct Expr;
struct AstIdent; struct AstIdent;
struct UnaryOperator;
struct HlTypeSupport struct HlTypeSupport
{ {
//hlIcode opcode; /* hlIcode opcode */ //hlIcode opcode; /* hlIcode opcode */
virtual bool removeRegFromLong(eReg regi, LOCAL_ID *locId)=0; virtual bool removeRegFromLong(eReg regi, LOCAL_ID *locId)=0;
virtual std::string writeOut(Function *pProc, int *numLoc) const=0; virtual std::string writeOut(Function *pProc, int *numLoc) const=0;
protected: protected:
void performLongRemoval (eReg regi, LOCAL_ID *locId, COND_EXPR *tree); Expr * performLongRemoval (eReg regi, LOCAL_ID *locId, Expr *tree);
}; };
struct CallType : public HlTypeSupport struct CallType : public HlTypeSupport
@ -100,9 +103,9 @@ struct CallType : public HlTypeSupport
Function * proc; Function * proc;
STKFRAME * args; // actual arguments STKFRAME * args; // actual arguments
void allocStkArgs (int num); void allocStkArgs (int num);
bool newStkArg(COND_EXPR *exp, llIcode opcode, Function *pproc); bool newStkArg(Expr *exp, llIcode opcode, Function *pproc);
void placeStkArg(COND_EXPR *exp, int pos); void placeStkArg(Expr *exp, int pos);
virtual COND_EXPR * toId(); virtual Expr * toAst();
public: public:
bool removeRegFromLong(eReg /*regi*/, LOCAL_ID */*locId*/) bool removeRegFromLong(eReg /*regi*/, LOCAL_ID */*locId*/)
{ {
@ -114,20 +117,24 @@ public:
struct AssignType : public HlTypeSupport struct AssignType : public HlTypeSupport
{ {
/* for HLI_ASSIGN */ /* for HLI_ASSIGN */
COND_EXPR *lhs; protected:
COND_EXPR *rhs; public:
AssignType() : lhs(0),rhs(0) {} Expr *m_lhs;
Expr *rhs;
AssignType() {}
Expr *lhs() const {return m_lhs;}
void lhs(Expr *l);
bool removeRegFromLong(eReg regi, LOCAL_ID *locId); bool removeRegFromLong(eReg regi, LOCAL_ID *locId);
std::string writeOut(Function *pProc, int *numLoc) const; std::string writeOut(Function *pProc, int *numLoc) const;
}; };
struct ExpType : public HlTypeSupport struct ExpType : public HlTypeSupport
{ {
/* for HLI_JCOND, HLI_RET, HLI_PUSH, HLI_POP*/ /* for HLI_JCOND, HLI_RET, HLI_PUSH, HLI_POP*/
COND_EXPR *v; Expr *v;
ExpType() : v(0) {} ExpType() : v(0) {}
bool removeRegFromLong(eReg regi, LOCAL_ID *locId) bool removeRegFromLong(eReg regi, LOCAL_ID *locId)
{ {
performLongRemoval(regi,locId,v); v=performLongRemoval(regi,locId,v);
return true; return true;
} }
std::string writeOut(Function *pProc, int *numLoc) const; std::string writeOut(Function *pProc, int *numLoc) const;
@ -147,15 +154,21 @@ public:
return const_cast<const HlTypeSupport *>(const_cast<HLTYPE*>(this)->get()); return const_cast<const HlTypeSupport *>(const_cast<HLTYPE*>(this)->get());
} }
void expr(COND_EXPR *e) void expr(Expr *e)
{ {
assert(e); assert(e);
exp.v=e; exp.v=e;
} }
void replaceExpr(COND_EXPR *e); Expr *getMyExpr()
COND_EXPR * expr() { return exp.v;} {
const COND_EXPR * expr() const { return exp.v;} if(opcode==HLI_CALL)
void set(hlIcode i,COND_EXPR *e) return call.toAst();
return expr();
}
void replaceExpr(Expr *e);
Expr * expr() { return exp.v;}
const Expr * expr() const { return exp.v;}
void set(hlIcode i,Expr *e)
{ {
if(i!=HLI_RET) if(i!=HLI_RET)
assert(e); assert(e);
@ -163,7 +176,7 @@ public:
opcode=i; opcode=i;
exp.v=e; exp.v=e;
} }
void set(COND_EXPR *l,COND_EXPR *r); void set(Expr *l,Expr *r);
void setCall(Function *proc); void setCall(Function *proc);
HLTYPE(hlIcode op=HLI_INVALID) : opcode(op) HLTYPE(hlIcode op=HLI_INVALID) : opcode(op)
{} {}
@ -179,7 +192,7 @@ public:
} }
public: public:
std::string write1HlIcode(Function *pProc, int *numLoc) const; std::string write1HlIcode(Function *pProc, int *numLoc) const;
void setAsgn(COND_EXPR *lhs, COND_EXPR *rhs); void setAsgn(Expr *lhs, Expr *rhs);
} ; } ;
/* LOW_LEVEL icode operand record */ /* LOW_LEVEL icode operand record */
struct LLOperand struct LLOperand
@ -201,6 +214,16 @@ struct LLOperand
proc.proc=0; proc.proc=0;
proc.cb=0; proc.cb=0;
} }
bool operator==(const LLOperand &with) const
{
return (seg==with.seg) &&
(segOver==with.segOver) &&
(segValue==with.segValue) &&
(regi == with.regi) &&
(off == with.off) &&
(opz==with.opz) &&
(proc.proc==with.proc.proc);
}
int64_t getImm2() const {return opz;} int64_t getImm2() const {return opz;}
void SetImmediateOp(uint32_t dw) void SetImmediateOp(uint32_t dw)
{ {
@ -219,8 +242,6 @@ struct LLOperand
static LLOperand CreateReg2(unsigned Val) static LLOperand CreateReg2(unsigned Val)
{ {
LLOperand Op; LLOperand Op;
// Op.Kind = kRegister;
// Op.RegVal = Reg;
Op.regi = (eReg)Val; Op.regi = (eReg)Val;
return Op; return Op;
} }
@ -229,20 +250,15 @@ struct LLOperand
struct LLInst : public llvm::MCInst //: public llvm::ilist_node<LLInst> struct LLInst : public llvm::MCInst //: public llvm::ilist_node<LLInst>
{ {
protected: protected:
uint32_t flg; /* icode flags */ uint32_t flg; /* icode flags */
// LLOperand &get(int idx) LLOperand m_src; /* source operand */
// {
// assert(idx<size());
// return getOperand(idx);
// }
LLOperand m_src; /* source operand */
public: public:
int codeIdx; /* Index into cCode.code */ int codeIdx; /* Index into cCode.code */
uint8_t numBytes; /* Number of bytes this instr */ uint8_t numBytes; /* Number of bytes this instr */
uint32_t label; /* offset in image (20-bit adr) */ uint32_t label; /* offset in image (20-bit adr) */
LLOperand dst; /* destination operand */ LLOperand dst; /* destination operand */
DU flagDU; /* def/use of flags */ DU flagDU; /* def/use of flags */
int caseEntry; int caseEntry;
std::vector<uint32_t> caseTbl2; std::vector<uint32_t> caseTbl2;
int hllLabNum; /* label # for hll codegen */ int hllLabNum; /* label # for hll codegen */
bool conditionalJump() bool conditionalJump()
@ -260,9 +276,7 @@ public:
flg &= ~flag; flg &= ~flag;
} }
uint32_t getFlag() const {return flg;} uint32_t getFlag() const {return flg;}
//llIcode getOpcode() const { return opcode; } uint32_t GetLlLabel() const { return label;}
uint32_t GetLlLabel() const { return label;}
void SetImmediateOp(uint32_t dw) {m_src.SetImmediateOp(dw);} void SetImmediateOp(uint32_t dw) {m_src.SetImmediateOp(dw);}
@ -308,7 +322,6 @@ public:
void flops(std::ostringstream &out); void flops(std::ostringstream &out);
bool isJmpInst(); bool isJmpInst();
//HLTYPE toHighLevel(COND_EXPR *lhs, COND_EXPR *rhs, Function *func);
HLTYPE createCall(); HLTYPE createCall();
LLInst(ICODE *container) : flg(0),codeIdx(0),numBytes(0),m_link(container) LLInst(ICODE *container) : flg(0),codeIdx(0),numBytes(0),m_link(container)
{ {
@ -465,13 +478,13 @@ public:
condId idType(opLoc sd); condId idType(opLoc sd);
// HLL setting functions // HLL setting functions
// set this icode to be an assign // set this icode to be an assign
void setAsgn(COND_EXPR *lhs, COND_EXPR *rhs) void setAsgn(Expr *lhs, Expr *rhs)
{ {
type=HIGH_LEVEL; type=HIGH_LEVEL;
hlU()->setAsgn(lhs,rhs); hlU()->setAsgn(lhs,rhs);
} }
void setUnary(hlIcode op, COND_EXPR *_exp); void setUnary(hlIcode op, Expr *_exp);
void setJCond(COND_EXPR *cexp); void setJCond(Expr *cexp);
void emitGotoLabel(int indLevel); void emitGotoLabel(int indLevel);
void copyDU(const ICODE &duIcode, operDu _du, operDu duDu); void copyDU(const ICODE &duIcode, operDu _du, operDu duDu);
@ -480,7 +493,7 @@ public:
public: public:
bool removeDefRegi(eReg regi, int thisDefIdx, LOCAL_ID *locId); bool removeDefRegi(eReg regi, int thisDefIdx, LOCAL_ID *locId);
void checkHlCall(); void checkHlCall();
bool newStkArg(COND_EXPR *exp, llIcode opcode, Function *pproc) bool newStkArg(Expr *exp, llIcode opcode, Function *pproc)
{ {
return hlU()->call.newStkArg(exp,opcode,pproc); return hlU()->call.newStkArg(exp,opcode,pproc);
} }

View File

@ -18,7 +18,7 @@
/* Type definition */ /* Type definition */
// this array has to stay in-order of addition i.e. not std::set<iICODE,std::less<iICODE> > // this array has to stay in-order of addition i.e. not std::set<iICODE,std::less<iICODE> >
// TODO: why ? // TODO: why ?
struct COND_EXPR; struct Expr;
struct AstIdent; struct AstIdent;
struct ICODE; struct ICODE;
struct LLInst; struct LLInst;
@ -132,7 +132,7 @@ public:
size_t csym() const {return id_arr.size();} size_t csym() const {return id_arr.size();}
void newRegArg(iICODE picode, iICODE ticode) const; void newRegArg(iICODE picode, iICODE ticode) const;
void processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode, bool isLong) const; void processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode, bool isLong) const;
void forwardSubs(COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const; void forwardSubs(Expr *lhs, Expr *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const;
AstIdent *createId(const ID *retVal, iICODE ix_); AstIdent *createId(const ID *retVal, iICODE ix_);
}; };

View File

@ -30,6 +30,10 @@ struct STATE
memset(r,0,sizeof(int16_t)*INDEX_BX_SI); //TODO: move this to machine_x86 memset(r,0,sizeof(int16_t)*INDEX_BX_SI); //TODO: move this to machine_x86
memset(f,0,sizeof(uint8_t)*INDEX_BX_SI); memset(f,0,sizeof(uint8_t)*INDEX_BX_SI);
} }
void setMemoryByte(uint32_t addr,uint8_t val)
{
//TODO: make this into a full scale value tracking class !
};
}; };

View File

@ -7,7 +7,7 @@
#include <stdint.h> #include <stdint.h>
#include "Enums.h" #include "Enums.h"
#include "types.h" #include "types.h"
struct COND_EXPR; struct Expr;
struct AstIdent; struct AstIdent;
struct TypeContainer; struct TypeContainer;
/* * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * */
@ -36,7 +36,7 @@ struct SYM : public SymbolCommon
struct STKSYM : public SymbolCommon struct STKSYM : public SymbolCommon
{ {
typedef int16_t tLabel; typedef int16_t tLabel;
COND_EXPR *actual; /* Expression tree of actual parameter */ Expr *actual; /* Expression tree of actual parameter */
AstIdent *regs; /* For register arguments only */ AstIdent *regs; /* For register arguments only */
tLabel label; /* Immediate off from BP (+:args, -:params) */ tLabel label; /* Immediate off from BP (+:args, -:params) */
uint8_t regOff; /* Offset is a register (e.g. SI, DI) */ uint8_t regOff; /* Offset is a register (e.g. SI, DI) */

View File

@ -14,6 +14,7 @@ def perform_test(exepath,filepath,outname,args)
filepath=path_local(filepath) filepath=path_local(filepath)
joined_args = args.join(' ') joined_args = args.join(' ')
printf("calling:" + "#{exepath} -a1 #{joined_args} -o#{output_path}.a1 #{filepath}\n") printf("calling:" + "#{exepath} -a1 #{joined_args} -o#{output_path}.a1 #{filepath}\n")
STDERR << "Errors for : #{filepath}"
result = `#{exepath} -a1 -o#{output_path}.a1 #{filepath}` result = `#{exepath} -a1 -o#{output_path}.a1 #{filepath}`
result = `#{exepath} -a2 #{joined_args} -o#{output_path}.a2 #{filepath}` result = `#{exepath} -a2 #{joined_args} -o#{output_path}.a2 #{filepath}`
result = `#{exepath} #{joined_args} -o#{output_path} #{filepath}` result = `#{exepath} #{joined_args} -o#{output_path} #{filepath}`

View File

@ -408,7 +408,6 @@ ICODE &BB::back()
size_t BB::size() size_t BB::size()
{ {
return distance(instructions.begin(),instructions.end()); return distance(instructions.begin(),instructions.end());
} }

View File

@ -14,7 +14,7 @@ void JumpTable::pruneEntries(uint16_t cs)
PROG *prg(Project::get()->binary()); PROG *prg(Project::get()->binary());
for (uint32_t i = start; i < finish; i += 2) for (uint32_t i = start; i < finish; i += 2)
{ {
uint32_t target = cs + LH(&prg->Image[i]); uint32_t target = cs + LH(&prg->image()[i]);
if (target < finish && target >= start) if (target < finish && target >= start)
finish = target; finish = target;
else if (target >= (uint32_t)prg->cbImage) else if (target >= (uint32_t)prg->cbImage)
@ -23,9 +23,9 @@ void JumpTable::pruneEntries(uint16_t cs)
ICODE _Icode; // used as scan input ICODE _Icode; // used as scan input
for (uint32_t i = start; i < finish; i += 2) for (uint32_t i = start; i < finish; i += 2)
{ {
uint32_t target = cs + LH(&prg->Image[i]); uint32_t target = cs + LH(&prg->image()[i]);
/* Be wary of 00 00 as code - it's probably data */ /* Be wary of 00 00 as code - it's probably data */
if (! (prg->Image[target] || prg->Image[target+1]) || scan(target, _Icode)) if (! (prg->image()[target] || prg->image()[target+1]) || scan(target, _Icode))
finish = i; finish = i;
} }

View File

@ -9,11 +9,24 @@
#include <sstream> #include <sstream>
#include <iostream> #include <iostream>
#include <cassert> #include <cassert>
#include <boost/range.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/assign.hpp>
#include "types.h" #include "types.h"
#include "dcc.h" #include "ast.h"
#include "bundle.h"
#include "machine_x86.h" #include "machine_x86.h"
#include "project.h" #include "project.h"
using namespace std; using namespace std;
using namespace boost;
using namespace boost::adaptors;
extern int strSize (const uint8_t *, char);
extern char *cChar(uint8_t c);
// Conditional operator symbols in C. Index by condOp enumeration type // Conditional operator symbols in C. Index by condOp enumeration type
static const char * const condOpSym[] = { " <= ", " < ", " == ", " != ", " > ", " >= ", static const char * const condOpSym[] = { " <= ", " < ", " == ", " != ", " > ", " >= ",
" & ", " | ", " ^ ", " ~ ", " & ", " | ", " ^ ", " ~ ",
@ -97,61 +110,27 @@ void ICODE::copyDU(const ICODE &duIcode, operDu _du, operDu duDu)
/* Returns an identifier conditional expression node of type GLOB_VAR */ /* Returns an identifier conditional expression node of type GLOB_VAR */
AstIdent *GlobalVariable::Create(int16_t segValue, int16_t off) GlobalVariable::GlobalVariable(int16_t segValue, int16_t off)
{ {
AstIdent *newExp;
uint32_t adr; uint32_t adr;
valid = true;
newExp = new AstIdent(); ident.idType = GLOB_VAR;
newExp->ident.idType = GLOB_VAR;
adr = opAdr(segValue, off); adr = opAdr(segValue, off);
auto i=Project::get()->getSymIdxByAdd(adr); auto i=Project::get()->getSymIdxByAdd(adr);
if ( not Project::get()->validSymIdx(i) ) if ( not Project::get()->validSymIdx(i) )
{ {
printf ("Error, glob var not found in symtab\n"); printf ("Error, glob var not found in symtab\n");
delete newExp; valid = false;
return 0;
} }
newExp->ident.idNode.globIdx = i; globIdx = i;
return (newExp);
} }
string GlobalVariable::walkCondExpr(Function *, int *) const
/* Returns an identifier conditional expression node of type REGISTER */
AstIdent *AstIdent::Reg(eReg regi, uint32_t icodeFlg, LOCAL_ID *locsym)
{ {
AstIdent *newExp; if(valid)
return Project::get()->symtab[globIdx].name;
newExp = new AstIdent(); else
newExp->ident.idType = REGISTER; return "INVALID GlobalVariable";
hlType type_sel;
regType reg_type;
if ((icodeFlg & B) || (icodeFlg & SRC_B))
{
type_sel = TYPE_BYTE_SIGN;
reg_type = BYTE_REG;
}
else /* uint16_t */
{
type_sel = TYPE_WORD_SIGN;
reg_type = WORD_REG;
}
newExp->ident.idNode.regiIdx = locsym->newByteWordReg(type_sel, regi);
newExp->ident.regiType = reg_type;
return (newExp);
}
/* Returns an identifier conditional expression node of type REGISTER */
AstIdent *AstIdent::RegIdx(int idx, regType reg_type)
{
AstIdent *newExp;
newExp = new AstIdent();
newExp->ident.idType = REGISTER;
newExp->ident.regiType = reg_type;
newExp->ident.idNode.regiIdx = idx;
return (newExp);
} }
/* Returns an identifier conditional expression node of type LOCAL_VAR */ /* Returns an identifier conditional expression node of type LOCAL_VAR */
@ -177,7 +156,7 @@ AstIdent *AstIdent::Loc(int off, LOCAL_ID *localId)
/* Returns an identifier conditional expression node of type PARAM */ /* Returns an identifier conditional expression node of type PARAM */
AstIdent *AstIdent::idParam(int off, const STKFRAME * argSymtab) AstIdent *AstIdent::Param(int off, const STKFRAME * argSymtab)
{ {
AstIdent *newExp; AstIdent *newExp;
@ -193,11 +172,10 @@ AstIdent *AstIdent::idParam(int off, const STKFRAME * argSymtab)
/* Returns an identifier conditional expression node of type GLOB_VAR_IDX. /* Returns an identifier conditional expression node of type GLOB_VAR_IDX.
* This global variable is indexed by regi. */ * This global variable is indexed by regi. */
AstIdent *idCondExpIdxGlob (int16_t segValue, int16_t off, uint8_t regi, const LOCAL_ID *locSym) GlobalVariableIdx::GlobalVariableIdx (int16_t segValue, int16_t off, uint8_t regi, const LOCAL_ID *locSym)
{ {
size_t i; size_t i;
AstIdent *newExp = new AstIdent(); ident.type(GLOB_VAR_IDX);
newExp->ident.idType = GLOB_VAR_IDX;
for (i = 0; i < locSym->csym(); i++) for (i = 0; i < locSym->csym(); i++)
{ {
const BWGLB_TYPE &lID(locSym->id_arr[i].id.bwGlb); const BWGLB_TYPE &lID(locSym->id_arr[i].id.bwGlb);
@ -206,19 +184,14 @@ AstIdent *idCondExpIdxGlob (int16_t segValue, int16_t off, uint8_t regi, const L
} }
if (i == locSym->csym()) if (i == locSym->csym())
printf ("Error, indexed-glob var not found in local id table\n"); printf ("Error, indexed-glob var not found in local id table\n");
newExp->ident.idNode.idxGlbIdx = i; idxGlbIdx = i;
return (newExp);
} }
string GlobalVariableIdx::walkCondExpr(Function *pProc, int *) const
/* Returns an identifier conditional expression node of type CONSTANT */
AstIdent *AstIdent::Kte(uint32_t kte, uint8_t size)
{ {
AstIdent *newExp = new AstIdent(); ostringstream o;
newExp->ident.idType = CONSTANT; auto bwGlb = &pProc->localId.id_arr[idxGlbIdx].id.bwGlb;
newExp->ident.idNode.kte.kte = kte; o << (bwGlb->seg << 4) + bwGlb->off << "["<<Machine_X86::regName(bwGlb->regi)<<"]";
newExp->ident.idNode.kte.size = size; return o.str();
return (newExp);
} }
@ -232,27 +205,34 @@ AstIdent *AstIdent::LongIdx (int idx)
return (newExp); return (newExp);
} }
AstIdent *AstIdent::String(uint32_t idx)
{
AstIdent *newExp = new AstIdent;
newExp->ident.idNode.strIdx = idx;
newExp->ident.type(STRING);
return newExp;
}
/* Returns an identifier conditional expression node of type LONG_VAR */ /* Returns an identifier conditional expression node of type LONG_VAR */
AstIdent *AstIdent::idLong(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset) AstIdent *AstIdent::Long(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset)
{ {
int idx; int idx;
AstIdent *newExp = new AstIdent(); AstIdent *newExp;
/* Check for long constant and save it as a constant expression */ /* Check for long constant and save it as a constant expression */
if ((sd == SRC) && pIcode->ll()->testFlags(I)) /* constant */ if ((sd == SRC) && pIcode->ll()->testFlags(I)) /* constant */
{ {
newExp->ident.idType = CONSTANT;
int value; int value;
if (f == HIGH_FIRST) if (f == HIGH_FIRST)
value = (pIcode->ll()->src().getImm2() << 16) + atOffset.src().getImm2(); value = (pIcode->ll()->src().getImm2() << 16) + atOffset.src().getImm2();
else/* LOW_FIRST */ else/* LOW_FIRST */
value = (atOffset.src().getImm2() << 16)+ pIcode->ll()->src().getImm2(); value = (atOffset.src().getImm2() << 16)+ pIcode->ll()->src().getImm2();
newExp->ident.idNode.kte.kte = value; newExp = new Constant(value,4);
newExp->ident.idNode.kte.size = 4;
} }
/* Save it as a long expression (reg, stack or glob) */ /* Save it as a long expression (reg, stack or glob) */
else else
{ {
newExp = new AstIdent();
idx = localId->newLong(sd, pIcode, f, ix, du, atOffset); idx = localId->newLong(sd, pIcode, f, ix, du, atOffset);
newExp->ident.idType = LONG_VAR; newExp->ident.idType = LONG_VAR;
newExp->ident.idNode.longIdx = idx; newExp->ident.idNode.longIdx = idx;
@ -260,19 +240,6 @@ AstIdent *AstIdent::idLong(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f
return (newExp); return (newExp);
} }
/* Returns an identifier conditional expression node of type FUNCTION */
AstIdent *AstIdent::idFunc(Function * pproc, STKFRAME * args)
{
AstIdent *newExp = new AstIdent();
newExp->ident.idType = FUNCTION;
newExp->ident.idNode.call.proc = pproc;
newExp->ident.idNode.call.args = args;
return (newExp);
}
/* Returns an identifier conditional expression node of type OTHER. /* Returns an identifier conditional expression node of type OTHER.
* Temporary solution, should really be encoded as an indexed type (eg. * Temporary solution, should really be encoded as an indexed type (eg.
* arrays). */ * arrays). */
@ -291,20 +258,26 @@ AstIdent *AstIdent::Other(eReg seg, eReg regi, int16_t off)
* TYPE_WORD_SIGN */ * TYPE_WORD_SIGN */
AstIdent *AstIdent::idID (const ID *retVal, LOCAL_ID *locsym, iICODE ix_) AstIdent *AstIdent::idID (const ID *retVal, LOCAL_ID *locsym, iICODE ix_)
{ {
AstIdent *newExp = new AstIdent();
int idx; int idx;
AstIdent *newExp=nullptr;
if (retVal->type == TYPE_LONG_SIGN) switch(retVal->type)
{ {
idx = locsym->newLongReg (TYPE_LONG_SIGN, retVal->id.longId.h,retVal->id.longId.l, ix_); case TYPE_LONG_SIGN:
newExp->ident.idType = LONG_VAR; {
newExp->ident.idNode.longIdx = idx; newExp = new AstIdent();
} idx = locsym->newLongReg (TYPE_LONG_SIGN, retVal->id.longId.h,retVal->id.longId.l, ix_);
else if (retVal->type == TYPE_WORD_SIGN) newExp->ident.idType = LONG_VAR;
{ newExp->ident.idNode.longIdx = idx;
newExp->ident.idType = REGISTER; break;
newExp->ident.idNode.regiIdx = locsym->newByteWordReg(TYPE_WORD_SIGN, retVal->id.regi); }
newExp->ident.regiType = WORD_REG; case TYPE_WORD_SIGN:
newExp = new RegisterNode(locsym->newByteWordReg(retVal->type, retVal->id.regi),WORD_REG);
break;
case TYPE_BYTE_SIGN:
newExp = new RegisterNode(locsym->newByteWordReg(retVal->type, retVal->id.regi),BYTE_REG);
break;
default:
fprintf(stderr,"AstIdent::idID unhandled type %d\n",retVal->type);
} }
return (newExp); return (newExp);
} }
@ -315,9 +288,9 @@ AstIdent *AstIdent::idID (const ID *retVal, LOCAL_ID *locsym, iICODE ix_)
* Arguments: * Arguments:
* duIcode: icode instruction that needs the du set. * duIcode: icode instruction that needs the du set.
* du: operand is defined or used in current instruction. */ * du: operand is defined or used in current instruction. */
COND_EXPR *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_,ICODE &duIcode, operDu du) Expr *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_,ICODE &duIcode, operDu du)
{ {
COND_EXPR *newExp; Expr *newExp;
int idx; /* idx into pIcode->localId table */ int idx; /* idx into pIcode->localId table */
@ -335,35 +308,33 @@ COND_EXPR *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICOD
else if ((sd == DST) && ll_insn.testFlags(IM_TMP_DST)) else if ((sd == DST) && ll_insn.testFlags(IM_TMP_DST))
{ /* implicit tmp */ { /* implicit tmp */
newExp = AstIdent::Reg (rTMP, 0, &pProc->localId); newExp = new RegisterNode(rTMP, 0, &pProc->localId);
duIcode.setRegDU(rTMP, (operDu)eUSE); duIcode.setRegDU(rTMP, (operDu)eUSE);
} }
else if ((sd == SRC) && ll_insn.testFlags(I)) /* constant */ else if ((sd == SRC) && ll_insn.testFlags(I)) /* constant */
newExp = AstIdent::Kte (ll_insn.src().getImm2(), 2); newExp = new Constant(ll_insn.src().getImm2(), 2);
else if (pm.regi == rUNDEF) /* global variable */ else if (pm.regi == rUNDEF) /* global variable */
newExp = GlobalVariable::Create(pm.segValue, pm.off); newExp = new GlobalVariable(pm.segValue, pm.off);
else if ( pm.isReg() ) /* register */ else if ( pm.isReg() ) /* register */
{ {
newExp = AstIdent::Reg (pm.regi, (sd == SRC) ? ll_insn.getFlag() : newExp = new RegisterNode(pm.regi, (sd == SRC) ? ll_insn.getFlag() : ll_insn.getFlag() & NO_SRC_B, &pProc->localId);
ll_insn.getFlag() & NO_SRC_B,
&pProc->localId);
duIcode.setRegDU( pm.regi, du); duIcode.setRegDU( pm.regi, du);
} }
else if (pm.off) /* offset */ else if (pm.off) /* offset */
{ { // TODO: this is ABI specific, should be actually based on Function calling conv
if ((pm.seg == rSS) && (pm.regi == INDEX_BP)) /* idx on bp */ if ((pm.seg == rSS) && (pm.regi == INDEX_BP)) /* idx on bp */
{ {
if (pm.off >= 0) /* argument */ if (pm.off >= 0) /* argument */
newExp = AstIdent::idParam (pm.off, &pProc->args); newExp = AstIdent::Param (pm.off, &pProc->args);
else /* local variable */ else /* local variable */
newExp = AstIdent::Loc (pm.off, &pProc->localId); newExp = AstIdent::Loc (pm.off, &pProc->localId);
} }
else if ((pm.seg == rDS) && (pm.regi == INDEX_BX)) /* bx */ else if ((pm.seg == rDS) && (pm.regi == INDEX_BX)) /* bx */
{ {
if (pm.off > 0) /* global variable */ if (pm.off > 0) /* global variable */
newExp = idCondExpIdxGlob (pm.segValue, pm.off, rBX,&pProc->localId); newExp = new GlobalVariableIdx(pm.segValue, pm.off, rBX,&pProc->localId);
else else
newExp = AstIdent::Other (pm.seg, pm.regi, pm.off); newExp = AstIdent::Other (pm.seg, pm.regi, pm.off);
duIcode.setRegDU( rBX, eUSE); duIcode.setRegDU( rBX, eUSE);
@ -377,26 +348,18 @@ COND_EXPR *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICOD
{ {
if ((pm.seg == rDS) && (pm.regi > INDEX_BP_DI)) /* dereference */ if ((pm.seg == rDS) && (pm.regi > INDEX_BP_DI)) /* dereference */
{ {
eReg selected;
switch (pm.regi) { switch (pm.regi) {
case INDEX_SI: case INDEX_SI: selected = rSI; break;
newExp = AstIdent::Reg(rSI, 0, &pProc->localId); case INDEX_DI: selected = rDI; break;
duIcode.setRegDU( rSI, du); case INDEX_BP: selected = rBP; break;
break; case INDEX_BX: selected = rBX; break;
case INDEX_DI:
newExp = AstIdent::Reg(rDI, 0, &pProc->localId);
duIcode.setRegDU( rDI, du);
break;
case INDEX_BP:
newExp = AstIdent::Reg(rBP, 0, &pProc->localId);
break;
case INDEX_BX:
newExp = AstIdent::Reg(rBX, 0, &pProc->localId);
duIcode.setRegDU( rBX, du);
break;
default: default:
newExp = 0; newExp = 0;
assert(false); assert(false);
} }
newExp = new RegisterNode(selected, 0, &pProc->localId);
duIcode.setRegDU( selected, du);
newExp = UnaryOperator::Create(DEREFERENCE, newExp); newExp = UnaryOperator::Create(DEREFERENCE, newExp);
} }
else else
@ -433,30 +396,11 @@ condId LLInst::idType(opLoc sd) const
/* Size of hl types */ /* Size of hl types */
int hlSize[] = {2, 1, 1, 2, 2, 4, 4, 4, 2, 2, 1, 4, 4}; int hlSize[] = {2, 1, 1, 2, 2, 4, 4, 4, 2, 2, 1, 4, 4};
int COND_EXPR::hlTypeSize(Function * pproc) const int Expr::hlTypeSize(Function * pproc) const
{ {
if (this == NULL) if (this == NULL)
return (2); /* for TYPE_UNKNOWN */ return (2); /* for TYPE_UNKNOWN */
fprintf(stderr,"hlTypeSize queried for Unkown type %d \n",m_type);
switch (m_type) {
case BOOLEAN_OP:
assert(false);
return 0;
// return expr->hlTypeSize(pproc);
case NEGATION: case ADDRESSOF:
case POST_INC: case POST_DEC:
case PRE_INC: case PRE_DEC:
case DEREFERENCE:
assert(false);
return 0;
//return expr->hlTypeSize(pproc);
case IDENTIFIER:
assert(false);
return 0;
default:
fprintf(stderr,"hlTypeSize queried for Unkown type %d \n",m_type);
break;
}
return 2; // CC: is this correct? return 2; // CC: is this correct?
} }
@ -469,33 +413,35 @@ int UnaryOperator::hlTypeSize(Function *pproc) const
{ {
return (unaryExp->hlTypeSize (pproc)); return (unaryExp->hlTypeSize (pproc));
} }
int GlobalVariable::hlTypeSize(Function *pproc) const
{
return (Project::get()->symbolSize(globIdx));
}
int GlobalVariableIdx::hlTypeSize(Function *pproc) const
{
return (hlSize[pproc->localId.id_arr[idxGlbIdx].type]);
}
int AstIdent::hlTypeSize(Function *pproc) const int AstIdent::hlTypeSize(Function *pproc) const
{ {
switch (ident.idType) switch (ident.idType)
{ {
case GLOB_VAR: case GLOB_VAR:
return (Project::get()->symbolSize(ident.idNode.globIdx)); assert(false);
case REGISTER: return 1;
if (ident.regiType == BYTE_REG)
return (1);
else
return (2);
case LOCAL_VAR: case LOCAL_VAR:
return (hlSize[pproc->localId.id_arr[ident.idNode.localIdx].type]); return (hlSize[pproc->localId.id_arr[ident.idNode.localIdx].type]);
case PARAM: case PARAM:
return (hlSize[pproc->args[ident.idNode.paramIdx].type]); return (hlSize[pproc->args[ident.idNode.paramIdx].type]);
case GLOB_VAR_IDX:
return (hlSize[pproc->localId.id_arr[ident.idNode.idxGlbIdx].type]);
case CONSTANT:
return (ident.idNode.kte.size);
case STRING: case STRING:
return (2); return (2);
case LONG_VAR: case LONG_VAR:
return (4); return (4);
case FUNCTION:
return (hlSize[ident.idNode.call.proc->retVal.type]);
case OTHER: case OTHER:
return (2); return (2);
default:
assert(false);
return -1;
} /* eos */ } /* eos */
} }
hlType BinaryOperator::expType(Function *pproc) const hlType BinaryOperator::expType(Function *pproc) const
@ -516,70 +462,47 @@ hlType UnaryOperator::expType(Function *pproc) const
{ {
return unaryExp->expType (pproc); return unaryExp->expType (pproc);
} }
hlType GlobalVariable::expType(Function *pproc) const
{
return Project::get()->symbolType(globIdx);
}
hlType GlobalVariableIdx::expType(Function *pproc) const
{
return (pproc->localId.id_arr[idxGlbIdx].type);
}
hlType AstIdent::expType(Function *pproc) const hlType AstIdent::expType(Function *pproc) const
{ {
switch (ident.idType) switch (ident.idType)
{ {
case GLOB_VAR: case UNDEF:
return Project::get()->symbolType(ident.idNode.globIdx); case CONSTANT:
case FUNCTION:
case REGISTER: case REGISTER:
if (ident.regiType == BYTE_REG) case GLOB_VAR:
return (TYPE_BYTE_SIGN); case GLOB_VAR_IDX:
else assert(false);
return (TYPE_WORD_SIGN); return TYPE_UNKNOWN;
case LOCAL_VAR: case LOCAL_VAR:
return (pproc->localId.id_arr[ident.idNode.localIdx].type); return (pproc->localId.id_arr[ident.idNode.localIdx].type);
case PARAM: case PARAM:
return (pproc->args[ident.idNode.paramIdx].type); return (pproc->args[ident.idNode.paramIdx].type);
case GLOB_VAR_IDX:
return (pproc->localId.id_arr[ident.idNode.idxGlbIdx].type);
case CONSTANT:
return (TYPE_CONST);
case STRING: case STRING:
return (TYPE_STR); return (TYPE_STR);
case LONG_VAR: case LONG_VAR:
return (pproc->localId.id_arr[ident.idNode.longIdx].type); return (pproc->localId.id_arr[ident.idNode.longIdx].type);
case FUNCTION:
return (ident.idNode.call.proc->retVal.type);
default: default:
return (TYPE_UNKNOWN); return (TYPE_UNKNOWN);
} /* eos */ } /* eos */
return (TYPE_UNKNOWN); return (TYPE_UNKNOWN);
} }
/* Returns the type of the expression */ /* Returns the type of the expression */
hlType COND_EXPR::expType(Function * pproc) const
{
if (this == nullptr)
return (TYPE_UNKNOWN);
switch (m_type)
{
case BOOLEAN_OP:
assert(false);
return TYPE_UNKNOWN;
case POST_INC: case POST_DEC:
case PRE_INC: case PRE_DEC:
case NEGATION:
assert(false);
return TYPE_UNKNOWN;
case ADDRESSOF: return (TYPE_PTR); /***????****/
case DEREFERENCE: return (TYPE_PTR);
case IDENTIFIER:
assert(false);
return TYPE_UNKNOWN;
case UNKNOWN_OP:
assert(false);
return (TYPE_UNKNOWN);
}
return TYPE_UNKNOWN; // CC: Correct?
}
/* Removes the register from the tree. If the register was part of a long /* Removes the register from the tree. If the register was part of a long
* register (eg. dx:ax), the node gets transformed into an integer register * register (eg. dx:ax), the node gets transformed into an integer register
* node. */ * node. */
void HlTypeSupport::performLongRemoval (eReg regi, LOCAL_ID *locId, COND_EXPR *tree) Expr * HlTypeSupport::performLongRemoval (eReg regi, LOCAL_ID *locId, Expr *tree)
{ {
switch (tree->m_type) { switch (tree->m_type) {
case BOOLEAN_OP: case BOOLEAN_OP:
@ -588,12 +511,13 @@ void HlTypeSupport::performLongRemoval (eReg regi, LOCAL_ID *locId, COND_EXPR *t
case NEGATION: case ADDRESSOF: case NEGATION: case ADDRESSOF:
case DEREFERENCE: case DEREFERENCE:
case IDENTIFIER: case IDENTIFIER:
tree->performLongRemoval(regi,locId); return tree->performLongRemoval(regi,locId);
break; break;
default: default:
fprintf(stderr,"performLongRemoval attemped on %d\n",tree->m_type); fprintf(stderr,"performLongRemoval attemped on %d\n",tree->m_type);
break; break;
} }
return tree;
} }
/* Returns the string located in image, formatted in C format. */ /* Returns the string located in image, formatted in C format. */
@ -603,10 +527,10 @@ static std::string getString (int offset)
ostringstream o; ostringstream o;
int strLen, i; int strLen, i;
strLen = strSize (&prog.Image[offset], '\0'); strLen = strSize (&prog.image()[offset], '\0');
o << '"'; o << '"';
for (i = 0; i < strLen; i++) for (i = 0; i < strLen; i++)
o<<cChar(prog.Image[offset+i]); o<<cChar(prog.image()[offset+i]);
o << "\"\0"; o << "\"\0";
return (o.str()); return (o.str());
} }
@ -614,7 +538,11 @@ string BinaryOperator::walkCondExpr(Function * pProc, int* numLoc) const
{ {
std::ostringstream outStr; std::ostringstream outStr;
outStr << "("; outStr << "(";
outStr << lhs()->walkCondExpr(pProc, numLoc); if(m_op!=NOT)
{
outStr << lhs()->walkCondExpr(pProc, numLoc);
}
assert(rhs());
outStr << condOpSym[m_op]; outStr << condOpSym[m_op];
outStr << rhs()->walkCondExpr(pProc, numLoc); outStr << rhs()->walkCondExpr(pProc, numLoc);
outStr << ")"; outStr << ")";
@ -631,23 +559,6 @@ string AstIdent::walkCondExpr(Function *pProc, int *numLoc) const
std::ostringstream o; std::ostringstream o;
switch (ident.idType) switch (ident.idType)
{ {
case GLOB_VAR:
o << Project::get()->symtab[ident.idNode.globIdx].name;
break;
case REGISTER:
id = &pProc->localId.id_arr[ident.idNode.regiIdx];
if (id->name[0] == '\0') /* no name */
{
id->setLocalName(++(*numLoc));
codeOut <<TypeContainer::typeName(id->type)<< " "<<id->name<<"; ";
codeOut <<"/* "<<Machine_X86::regName(id->id.regi)<<" */\n";
}
if (id->hasMacro)
o << id->macro << "("<<id->name<<")";
else
o << id->name;
break;
case LOCAL_VAR: case LOCAL_VAR:
o << pProc->localId.id_arr[ident.idNode.localIdx].name; o << pProc->localId.id_arr[ident.idNode.localIdx].name;
break; break;
@ -659,19 +570,6 @@ string AstIdent::walkCondExpr(Function *pProc, int *numLoc) const
else else
o << psym->name; o << psym->name;
break; break;
case GLOB_VAR_IDX:
bwGlb = &pProc->localId.id_arr[ident.idNode.idxGlbIdx].id.bwGlb;
o << (bwGlb->seg << 4) + bwGlb->off << "["<<Machine_X86::regName(bwGlb->regi)<<"]";
break;
case CONSTANT:
if (ident.idNode.kte.kte < 1000)
o << ident.idNode.kte.kte;
else
o << "0x"<<std::hex << ident.idNode.kte.kte;
break;
case STRING: case STRING:
o << getString (ident.idNode.strIdx); o << getString (ident.idNode.strIdx);
break; break;
@ -697,11 +595,6 @@ string AstIdent::walkCondExpr(Function *pProc, int *numLoc) const
o << "[" << (id->id.longGlb.seg<<4) + id->id.longGlb.offH <<"][bx]"; o << "[" << (id->id.longGlb.seg<<4) + id->id.longGlb.offH <<"][bx]";
} }
break; break;
case FUNCTION:
o << writeCall (ident.idNode.call.proc,*ident.idNode.call.args, pProc, numLoc);
break;
case OTHER: case OTHER:
off = ident.idNode.other.off; off = ident.idNode.other.off;
o << Machine_X86::regName(ident.idNode.other.seg)<< "["; o << Machine_X86::regName(ident.idNode.other.seg)<< "[";
@ -711,6 +604,12 @@ string AstIdent::walkCondExpr(Function *pProc, int *numLoc) const
else if (off>0) else if (off>0)
o << "+"<< hexStr (off); o << "+"<< hexStr (off);
o << "]"; o << "]";
break;
default:
assert(false);
return "";
} /* eos */ } /* eos */
outStr << o.str(); outStr << o.str();
cCode.appendDecl(codeOut.str()); cCode.appendDecl(codeOut.str());
@ -783,35 +682,6 @@ string UnaryOperator::walkCondExpr(Function *pProc, int *numLoc) const
/* Makes a copy of the given expression. Allocates newExp storage for each
* node. Returns the copy. */
COND_EXPR *COND_EXPR::clone() const
{
COND_EXPR* newExp=nullptr; /* Expression node copy */
switch (m_type)
{
case BOOLEAN_OP:
assert(false);
break;
case NEGATION:
case ADDRESSOF:
case DEREFERENCE:
case PRE_DEC: case POST_DEC:
case PRE_INC: case POST_INC:
assert(false);
break;
case IDENTIFIER:
assert(false);
break;
default:
fprintf(stderr,"Clone attempt on unhandled type %d\n",m_type);
}
return (newExp);
}
/* Changes the boolean conditional operator at the root of this expression */ /* Changes the boolean conditional operator at the root of this expression */
@ -819,9 +689,9 @@ void BinaryOperator::changeBoolOp (condOp newOp)
{ {
m_op = newOp; m_op = newOp;
} }
bool COND_EXPR::insertSubTreeReg (AstIdent *&tree, COND_EXPR *_expr, eReg regi,const LOCAL_ID *locsym) bool Expr::insertSubTreeReg (AstIdent *&tree, Expr *_expr, eReg regi,const LOCAL_ID *locsym)
{ {
COND_EXPR *nd = tree; Expr *nd = tree;
bool res=insertSubTreeReg (nd, _expr, regi,locsym); bool res=insertSubTreeReg (nd, _expr, regi,locsym);
if(res) if(res)
{ {
@ -833,12 +703,12 @@ bool COND_EXPR::insertSubTreeReg (AstIdent *&tree, COND_EXPR *_expr, eReg regi,c
} }
/* Inserts the expression exp into the tree at the location specified by the /* Inserts the expression exp into the tree at the location specified by the
* register regi */ * register regi */
bool COND_EXPR::insertSubTreeReg (COND_EXPR *&tree, COND_EXPR *_expr, eReg regi,const LOCAL_ID *locsym) bool Expr::insertSubTreeReg (Expr *&tree, Expr *_expr, eReg regi,const LOCAL_ID *locsym)
{ {
if (tree == NULL) if (tree == NULL)
return false; return false;
COND_EXPR *temp=tree->insertSubTreeReg(_expr,regi,locsym); Expr *temp=tree->insertSubTreeReg(_expr,regi,locsym);
if(nullptr!=temp) if(nullptr!=temp)
{ {
tree=temp; tree=temp;
@ -847,11 +717,9 @@ bool COND_EXPR::insertSubTreeReg (COND_EXPR *&tree, COND_EXPR *_expr, eReg regi,
return false; return false;
} }
COND_EXPR *UnaryOperator::insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym) Expr *UnaryOperator::insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym)
{ {
Expr *temp;
eReg treeReg;
COND_EXPR *temp;
switch (m_type) { switch (m_type) {
case NEGATION: case NEGATION:
@ -869,9 +737,9 @@ COND_EXPR *UnaryOperator::insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LO
} }
return nullptr; return nullptr;
} }
COND_EXPR *BinaryOperator::insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym) Expr *BinaryOperator::insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym)
{ {
COND_EXPR *r; Expr *r;
if(this->op()!=NOT) if(this->op()!=NOT)
{ {
assert(m_lhs); assert(m_lhs);
@ -891,30 +759,21 @@ COND_EXPR *BinaryOperator::insertSubTreeReg(COND_EXPR *_expr, eReg regi, const L
} }
return nullptr; return nullptr;
} }
COND_EXPR *AstIdent::insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym) Expr *AstIdent::insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym)
{ {
eReg treeReg;
if (ident.idType == REGISTER) if (ident.idType == REGISTER)
{ {
treeReg = locsym->id_arr[ident.idNode.regiIdx].id.regi; assert(false);
if (treeReg == regi) /* uint16_t reg */
{
return _expr;
}
else if(Machine_X86::isSubRegisterOf(treeReg,regi)) /* uint16_t/uint8_t reg */
{
return _expr;
}
} }
return nullptr; return nullptr;
} }
/* Inserts the expression exp into the tree at the location specified by the /* Inserts the expression exp into the tree at the location specified by the
* long register index longIdx*/ * long register index longIdx*/
bool COND_EXPR::insertSubTreeLongReg(COND_EXPR *_expr, COND_EXPR *&tree, int longIdx) bool Expr::insertSubTreeLongReg(Expr *_expr, Expr *&tree, int longIdx)
{ {
if (tree == NULL) if (tree == NULL)
return false; return false;
COND_EXPR *temp=tree->insertSubTreeLongReg(_expr,longIdx); Expr *temp=tree->insertSubTreeLongReg(_expr,longIdx);
if(nullptr!=temp) if(nullptr!=temp)
{ {
tree=temp; tree=temp;
@ -922,9 +781,9 @@ bool COND_EXPR::insertSubTreeLongReg(COND_EXPR *_expr, COND_EXPR *&tree, int lon
} }
return false; return false;
} }
COND_EXPR *UnaryOperator::insertSubTreeLongReg(COND_EXPR *_expr, int longIdx) Expr *UnaryOperator::insertSubTreeLongReg(Expr *_expr, int longIdx)
{ {
COND_EXPR *temp = unaryExp->insertSubTreeLongReg(_expr,longIdx); Expr *temp = unaryExp->insertSubTreeLongReg(_expr,longIdx);
if (nullptr!=temp) if (nullptr!=temp)
{ {
unaryExp = temp; unaryExp = temp;
@ -932,9 +791,9 @@ COND_EXPR *UnaryOperator::insertSubTreeLongReg(COND_EXPR *_expr, int longIdx)
} }
return nullptr; return nullptr;
} }
COND_EXPR *BinaryOperator::insertSubTreeLongReg(COND_EXPR *_expr, int longIdx) Expr *BinaryOperator::insertSubTreeLongReg(Expr *_expr, int longIdx)
{ {
COND_EXPR *r; Expr *r;
if(m_op!=NOT) if(m_op!=NOT)
{ {
r=m_lhs->insertSubTreeLongReg(_expr,longIdx); r=m_lhs->insertSubTreeLongReg(_expr,longIdx);
@ -952,7 +811,7 @@ COND_EXPR *BinaryOperator::insertSubTreeLongReg(COND_EXPR *_expr, int longIdx)
} }
return nullptr; return nullptr;
} }
COND_EXPR *AstIdent::insertSubTreeLongReg(COND_EXPR *_expr, int longIdx) Expr *AstIdent::insertSubTreeLongReg(Expr *_expr, int longIdx)
{ {
if (ident.idNode.longIdx == longIdx) if (ident.idNode.longIdx == longIdx)
{ {
@ -962,24 +821,12 @@ COND_EXPR *AstIdent::insertSubTreeLongReg(COND_EXPR *_expr, int longIdx)
} }
/* Recursively deallocates the abstract syntax tree rooted at *exp */ /* Recursively deallocates the abstract syntax tree rooted at *exp */
COND_EXPR::~COND_EXPR() Expr::~Expr(){}
{
switch (m_type)
{
case BOOLEAN_OP:
case NEGATION:
case ADDRESSOF:
case DEREFERENCE:
case IDENTIFIER:
break;
default:
fprintf(stderr,"release attempt on unhandled type %d\n",m_type);
}
}
/* Makes a copy of the given expression. Allocates newExp storage for each /* Makes a copy of the given expression. Allocates newExp storage for each
* node. Returns the copy. */ * node. Returns the copy. */
COND_EXPR *BinaryOperator::clone() const Expr *BinaryOperator::clone() const
{ {
BinaryOperator* newExp=new BinaryOperator(m_op); /* Expression node copy */ BinaryOperator* newExp=new BinaryOperator(m_op); /* Expression node copy */
newExp->m_lhs = m_lhs->clone(); newExp->m_lhs = m_lhs->clone();
@ -987,7 +834,7 @@ COND_EXPR *BinaryOperator::clone() const
return newExp; return newExp;
} }
COND_EXPR *BinaryOperator::inverse() const Expr *BinaryOperator::inverse() const
{ {
static condOp invCondOp[] = {GREATER, GREATER_EQUAL, NOT_EQUAL, EQUAL, static condOp invCondOp[] = {GREATER, GREATER_EQUAL, NOT_EQUAL, EQUAL,
LESS_EQUAL, LESS, DUMMY,DUMMY,DUMMY,DUMMY, LESS_EQUAL, LESS, DUMMY,DUMMY,DUMMY,DUMMY,
@ -1017,18 +864,17 @@ COND_EXPR *BinaryOperator::inverse() const
return res; return res;
} }
void AstIdent::performLongRemoval(eReg regi, LOCAL_ID *locId) Expr *AstIdent::performLongRemoval(eReg regi, LOCAL_ID *locId)
{ {
eReg otherRegi; /* high or low part of long register */ eReg otherRegi; /* high or low part of long register */
IDENTTYPE* ident_2 = &ident; if (ident.idType == LONG_VAR)
if (ident_2->idType == LONG_VAR)
{ {
otherRegi = otherLongRegi (regi, ident_2->idNode.longIdx, locId); otherRegi = otherLongRegi (regi, ident.idNode.longIdx, locId);
ident_2->idType = REGISTER; delete this;
ident_2->regiType = WORD_REG; return new RegisterNode(locId->newByteWordReg(TYPE_WORD_SIGN,otherRegi),WORD_REG);
ident_2->idNode.regiIdx = locId->newByteWordReg(TYPE_WORD_SIGN,otherRegi);
} }
return this;
} }
eReg AstIdent::otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl) eReg AstIdent::otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl)
{ {
@ -1045,3 +891,42 @@ eReg AstIdent::otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl)
} }
return rUNDEF; // Cristina: please check this! return rUNDEF; // Cristina: please check this!
} }
string Constant::walkCondExpr(Function *, int *) const
{
ostringstream o;
if (kte.kte < 1000)
o << kte.kte;
else
o << "0x"<<std::hex << kte.kte;
return o.str();
}
int Constant::hlTypeSize(Function *) const
{
return kte.size;
}
hlType Constant::expType(Function *pproc) const
{
return TYPE_CONST;
}
string FuncNode::walkCondExpr(Function *pProc, int *numLoc) const
{
return pProc->writeCall(call.proc,*call.args, numLoc);
}
int FuncNode::hlTypeSize(Function *) const
{
return hlSize[call.proc->retVal.type];
}
hlType FuncNode::expType(Function *) const
{
return call.proc->retVal.type;
}

View File

@ -108,23 +108,23 @@ static void printGlobVar (std::ostream &ostr,SYM * psym)
switch (psym->size) switch (psym->size)
{ {
case 1: case 1:
ostr << "uint8_t\t"<<psym->name<<" = "<<prog.Image[relocOp]<<";\n"; ostr << "uint8_t\t"<<psym->name<<" = "<<prog.image()[relocOp]<<";\n";
break; break;
case 2: case 2:
ostr << "uint16_t\t"<<psym->name<<" = "<<LH(prog.Image+relocOp)<<";\n"; ostr << "uint16_t\t"<<psym->name<<" = "<<LH(prog.image()+relocOp)<<";\n";
break; break;
case 4: if (psym->type == TYPE_PTR) /* pointer */ case 4: if (psym->type == TYPE_PTR) /* pointer */
ostr << "uint16_t *\t"<<psym->name<<" = "<<LH(prog.Image+relocOp)<<";\n"; ostr << "uint16_t *\t"<<psym->name<<" = "<<LH(prog.image()+relocOp)<<";\n";
else /* char */ else /* char */
ostr << "char\t"<<psym->name<<"[4] = \""<< ostr << "char\t"<<psym->name<<"[4] = \""<<
prog.Image[relocOp]<<prog.Image[relocOp+1]<< prog.image()[relocOp]<<prog.image()[relocOp+1]<<
prog.Image[relocOp+2]<<prog.Image[relocOp+3]<<";\n"; prog.image()[relocOp+2]<<prog.image()[relocOp+3]<<";\n";
break; break;
default: default:
{ {
ostringstream strContents; ostringstream strContents;
for (j=0; j < psym->size; j++) for (j=0; j < psym->size; j++)
strContents << cChar(prog.Image[relocOp + j]); strContents << cChar(prog.image()[relocOp + j]);
ostr << "char\t*"<<psym->name<<" = \""<<strContents.str()<<"\";\n"; ostr << "char\t*"<<psym->name<<" = \""<<strContents.str()<<"\";\n";
} }
} }

View File

@ -74,7 +74,7 @@ void checkHeap(char *msg); /* For debugging */
void fixWildCards(uint8_t pat[]); /* In fixwild.c */ void fixWildCards(uint8_t pat[]); /* In fixwild.c */
static boolT locatePattern(uint8_t *source, int iMin, int iMax, uint8_t *pattern, static boolT locatePattern(const uint8_t *source, int iMin, int iMax, uint8_t *pattern,
int iPatLen, int *index); int iPatLen, int *index);
/* * * * * * * * * * * * * * * *\ /* * * * * * * * * * * * * * * *\
@ -457,8 +457,8 @@ bool LibCheck(Function & pProc)
pProc.name = "main"; pProc.name = "main";
return false; return false;
} }
memcpy(pat, &prog.Image[fileOffset], PATLEN); memcpy(pat, &prog.image()[fileOffset], PATLEN);
//memmove(pat, &prog.Image[fileOffset], PATLEN); //memmove(pat, &prog.image()[fileOffset], PATLEN);
fixWildCards(pat); /* Fix wild cards in the copy */ fixWildCards(pat); /* Fix wild cards in the copy */
h = g_pattern_hasher.hash(pat); /* Hash the found proc */ h = g_pattern_hasher.hash(pat); /* Hash the found proc */
/* We always have to compare keys, because the hash function will always return a valid index */ /* We always have to compare keys, because the hash function will always return a valid index */
@ -520,7 +520,7 @@ bool LibCheck(Function & pProc)
pProc.flg |= PROC_RUNTIME; /* => is a runtime routine */ pProc.flg |= PROC_RUNTIME; /* => is a runtime routine */
} }
} }
if (locatePattern(prog.Image, pProc.procEntry, if (locatePattern(prog.image(), pProc.procEntry,
pProc.procEntry+sizeof(pattMsChkstk), pProc.procEntry+sizeof(pattMsChkstk),
pattMsChkstk, sizeof(pattMsChkstk), &Idx)) pattMsChkstk, sizeof(pattMsChkstk), &Idx))
{ {
@ -587,11 +587,11 @@ void dispKey(int /*i*/)
iPatLen). The pattern can contain wild bytes; if you really want to match iPatLen). The pattern can contain wild bytes; if you really want to match
for the pattern that is used up by the WILD uint8_t, tough - it will match with for the pattern that is used up by the WILD uint8_t, tough - it will match with
everything else as well. */ everything else as well. */
static boolT locatePattern(uint8_t *source, int iMin, int iMax, uint8_t *pattern, int iPatLen, static boolT locatePattern(const uint8_t *source, int iMin, int iMax, uint8_t *pattern, int iPatLen,
int *index) int *index)
{ {
int i, j; int i, j;
uint8_t *pSrc; /* Pointer to start of considered source */ const uint8_t *pSrc; /* Pointer to start of considered source */
int iLast; int iLast;
iLast = iMax - iPatLen; /* Last source uint8_t to consider */ iLast = iMax - iPatLen; /* Last source uint8_t to consider */
@ -645,18 +645,18 @@ void STATE::checkStartup()
/* Check the Turbo Pascal signatures first, since they involve only the /* Check the Turbo Pascal signatures first, since they involve only the
first 3 bytes, and false positives may be founf with the others later */ first 3 bytes, and false positives may be founf with the others later */
if (locatePattern(prog.Image, startOff, startOff+5, pattBorl4on,sizeof(pattBorl4on), &i)) if (locatePattern(prog.image(), startOff, startOff+5, pattBorl4on,sizeof(pattBorl4on), &i))
{ {
/* The first 5 bytes are a far call. Follow that call and /* The first 5 bytes are a far call. Follow that call and
determine the version from that */ determine the version from that */
rel = LH(&prog.Image[startOff+1]); /* This is abs off of init */ rel = LH(&prog.image()[startOff+1]); /* This is abs off of init */
para= LH(&prog.Image[startOff+3]);/* This is abs seg of init */ para= LH(&prog.image()[startOff+3]);/* This is abs seg of init */
init = ((uint32_t)para << 4) + rel; init = ((uint32_t)para << 4) + rel;
if (locatePattern(prog.Image, init, init+26, pattBorl4Init, if (locatePattern(prog.image(), init, init+26, pattBorl4Init,
sizeof(pattBorl4Init), &i)) sizeof(pattBorl4Init), &i))
{ {
setState(rDS, LH(&prog.Image[i+1])); setState(rDS, LH(&prog.image()[i+1]));
printf("Borland Pascal v4 detected\n"); printf("Borland Pascal v4 detected\n");
chVendor = 't'; /* Trubo */ chVendor = 't'; /* Trubo */
chModel = 'p'; /* Pascal */ chModel = 'p'; /* Pascal */
@ -665,11 +665,11 @@ void STATE::checkStartup()
prog.segMain = prog.initCS; /* At the 5 uint8_t jump */ prog.segMain = prog.initCS; /* At the 5 uint8_t jump */
goto gotVendor; /* Already have vendor */ goto gotVendor; /* Already have vendor */
} }
else if (locatePattern(prog.Image, init, init+26, pattBorl5Init, else if (locatePattern(prog.image(), init, init+26, pattBorl5Init,
sizeof(pattBorl5Init), &i)) sizeof(pattBorl5Init), &i))
{ {
setState( rDS, LH(&prog.Image[i+1])); setState( rDS, LH(&prog.image()[i+1]));
printf("Borland Pascal v5.0 detected\n"); printf("Borland Pascal v5.0 detected\n");
chVendor = 't'; /* Trubo */ chVendor = 't'; /* Trubo */
chModel = 'p'; /* Pascal */ chModel = 'p'; /* Pascal */
@ -678,11 +678,11 @@ void STATE::checkStartup()
prog.segMain = prog.initCS; prog.segMain = prog.initCS;
goto gotVendor; /* Already have vendor */ goto gotVendor; /* Already have vendor */
} }
else if (locatePattern(prog.Image, init, init+26, pattBorl7Init, else if (locatePattern(prog.image(), init, init+26, pattBorl7Init,
sizeof(pattBorl7Init), &i)) sizeof(pattBorl7Init), &i))
{ {
setState( rDS, LH(&prog.Image[i+1])); setState( rDS, LH(&prog.image()[i+1]));
printf("Borland Pascal v7 detected\n"); printf("Borland Pascal v7 detected\n");
chVendor = 't'; /* Trubo */ chVendor = 't'; /* Trubo */
chModel = 'p'; /* Pascal */ chModel = 'p'; /* Pascal */
@ -701,43 +701,43 @@ void STATE::checkStartup()
as near data, just more pushes at the start. */ as near data, just more pushes at the start. */
if(prog.cbImage>int(startOff+0x180+sizeof(pattMainLarge))) if(prog.cbImage>int(startOff+0x180+sizeof(pattMainLarge)))
{ {
if (locatePattern(prog.Image, startOff, startOff+0x180, pattMainLarge,sizeof(pattMainLarge), &i)) if (locatePattern(prog.image(), startOff, startOff+0x180, pattMainLarge,sizeof(pattMainLarge), &i))
{ {
rel = LH(&prog.Image[i+OFFMAINLARGE]); /* This is abs off of main */ rel = LH(&prog.image()[i+OFFMAINLARGE]); /* This is abs off of main */
para= LH(&prog.Image[i+OFFMAINLARGE+2]);/* This is abs seg of main */ para= LH(&prog.image()[i+OFFMAINLARGE+2]);/* This is abs seg of main */
/* Save absolute image offset */ /* Save absolute image offset */
prog.offMain = ((uint32_t)para << 4) + rel; prog.offMain = ((uint32_t)para << 4) + rel;
prog.segMain = (uint16_t)para; prog.segMain = (uint16_t)para;
chModel = 'l'; /* Large model */ chModel = 'l'; /* Large model */
} }
else if (locatePattern(prog.Image, startOff, startOff+0x180, pattMainCompact, else if (locatePattern(prog.image(), startOff, startOff+0x180, pattMainCompact,
sizeof(pattMainCompact), &i)) sizeof(pattMainCompact), &i))
{ {
rel = LH_SIGNED(&prog.Image[i+OFFMAINCOMPACT]);/* This is the rel addr of main */ rel = LH_SIGNED(&prog.image()[i+OFFMAINCOMPACT]);/* This is the rel addr of main */
prog.offMain = i+OFFMAINCOMPACT+2+rel; /* Save absolute image offset */ prog.offMain = i+OFFMAINCOMPACT+2+rel; /* Save absolute image offset */
prog.segMain = prog.initCS; prog.segMain = prog.initCS;
chModel = 'c'; /* Compact model */ chModel = 'c'; /* Compact model */
} }
else if (locatePattern(prog.Image, startOff, startOff+0x180, pattMainMedium, else if (locatePattern(prog.image(), startOff, startOff+0x180, pattMainMedium,
sizeof(pattMainMedium), &i)) sizeof(pattMainMedium), &i))
{ {
rel = LH(&prog.Image[i+OFFMAINMEDIUM]); /* This is abs off of main */ rel = LH(&prog.image()[i+OFFMAINMEDIUM]); /* This is abs off of main */
para= LH(&prog.Image[i+OFFMAINMEDIUM+2]);/* This is abs seg of main */ para= LH(&prog.image()[i+OFFMAINMEDIUM+2]);/* This is abs seg of main */
prog.offMain = ((uint32_t)para << 4) + rel; prog.offMain = ((uint32_t)para << 4) + rel;
prog.segMain = (uint16_t)para; prog.segMain = (uint16_t)para;
chModel = 'm'; /* Medium model */ chModel = 'm'; /* Medium model */
} }
else if (locatePattern(prog.Image, startOff, startOff+0x180, pattMainSmall, else if (locatePattern(prog.image(), startOff, startOff+0x180, pattMainSmall,
sizeof(pattMainSmall), &i)) sizeof(pattMainSmall), &i))
{ {
rel = LH_SIGNED(&prog.Image[i+OFFMAINSMALL]); /* This is rel addr of main */ rel = LH_SIGNED(&prog.image()[i+OFFMAINSMALL]); /* This is rel addr of main */
prog.offMain = i+OFFMAINSMALL+2+rel; /* Save absolute image offset */ prog.offMain = i+OFFMAINSMALL+2+rel; /* Save absolute image offset */
prog.segMain = prog.initCS; prog.segMain = prog.initCS;
chModel = 's'; /* Small model */ chModel = 's'; /* Small model */
} }
else if (memcmp(&prog.Image[startOff], pattTPasStart, sizeof(pattTPasStart)) == 0) else if (memcmp(&prog.image()[startOff], pattTPasStart, sizeof(pattTPasStart)) == 0)
{ {
rel = LH_SIGNED(&prog.Image[startOff+1]); /* Get the jump offset */ rel = LH_SIGNED(&prog.image()[startOff+1]); /* Get the jump offset */
prog.offMain = rel+startOff+3; /* Save absolute image offset */ prog.offMain = rel+startOff+3; /* Save absolute image offset */
prog.offMain += 0x20; /* These first 32 bytes are setting up */ prog.offMain += 0x20; /* These first 32 bytes are setting up */
prog.segMain = prog.initCS; prog.segMain = prog.initCS;
@ -764,27 +764,27 @@ void STATE::checkStartup()
/* Now decide the compiler vendor and version number */ /* Now decide the compiler vendor and version number */
if (memcmp(&prog.Image[startOff], pattMsC5Start, sizeof(pattMsC5Start)) == 0) if (memcmp(&prog.image()[startOff], pattMsC5Start, sizeof(pattMsC5Start)) == 0)
{ {
/* Yes, this is Microsoft startup code. The DS is sitting right here /* Yes, this is Microsoft startup code. The DS is sitting right here
in the next 2 bytes */ in the next 2 bytes */
setState( rDS, LH(&prog.Image[startOff+sizeof(pattMsC5Start)])); setState( rDS, LH(&prog.image()[startOff+sizeof(pattMsC5Start)]));
chVendor = 'm'; /* Microsoft compiler */ chVendor = 'm'; /* Microsoft compiler */
chVersion = '5'; /* Version 5 */ chVersion = '5'; /* Version 5 */
printf("MSC 5 detected\n"); printf("MSC 5 detected\n");
} }
/* The C8 startup pattern is different from C5's */ /* The C8 startup pattern is different from C5's */
else if (memcmp(&prog.Image[startOff], pattMsC8Start, sizeof(pattMsC8Start)) == 0) else if (memcmp(&prog.image()[startOff], pattMsC8Start, sizeof(pattMsC8Start)) == 0)
{ {
setState( rDS, LH(&prog.Image[startOff+sizeof(pattMsC8Start)])); setState( rDS, LH(&prog.image()[startOff+sizeof(pattMsC8Start)]));
printf("MSC 8 detected\n"); printf("MSC 8 detected\n");
chVendor = 'm'; /* Microsoft compiler */ chVendor = 'm'; /* Microsoft compiler */
chVersion = '8'; /* Version 8 */ chVersion = '8'; /* Version 8 */
} }
/* The C8 .com startup pattern is different again! */ /* The C8 .com startup pattern is different again! */
else if (memcmp(&prog.Image[startOff], pattMsC8ComStart, else if (memcmp(&prog.image()[startOff], pattMsC8ComStart,
sizeof(pattMsC8ComStart)) == 0) sizeof(pattMsC8ComStart)) == 0)
{ {
printf("MSC 8 .com detected\n"); printf("MSC 8 .com detected\n");
@ -792,27 +792,27 @@ void STATE::checkStartup()
chVersion = '8'; /* Version 8 */ chVersion = '8'; /* Version 8 */
} }
else if (locatePattern(prog.Image, startOff, startOff+0x30, pattBorl2Start, else if (locatePattern(prog.image(), startOff, startOff+0x30, pattBorl2Start,
sizeof(pattBorl2Start), &i)) sizeof(pattBorl2Start), &i))
{ {
/* Borland startup. DS is at the second uint8_t (offset 1) */ /* Borland startup. DS is at the second uint8_t (offset 1) */
setState( rDS, LH(&prog.Image[i+1])); setState( rDS, LH(&prog.image()[i+1]));
printf("Borland v2 detected\n"); printf("Borland v2 detected\n");
chVendor = 'b'; /* Borland compiler */ chVendor = 'b'; /* Borland compiler */
chVersion = '2'; /* Version 2 */ chVersion = '2'; /* Version 2 */
} }
else if (locatePattern(prog.Image, startOff, startOff+0x30, pattBorl3Start, else if (locatePattern(prog.image(), startOff, startOff+0x30, pattBorl3Start,
sizeof(pattBorl3Start), &i)) sizeof(pattBorl3Start), &i))
{ {
/* Borland startup. DS is at the second uint8_t (offset 1) */ /* Borland startup. DS is at the second uint8_t (offset 1) */
setState( rDS, LH(&prog.Image[i+1])); setState( rDS, LH(&prog.image()[i+1]));
printf("Borland v3 detected\n"); printf("Borland v3 detected\n");
chVendor = 'b'; /* Borland compiler */ chVendor = 'b'; /* Borland compiler */
chVersion = '3'; /* Version 3 */ chVersion = '3'; /* Version 3 */
} }
else if (locatePattern(prog.Image, startOff, startOff+0x30, pattLogiStart, else if (locatePattern(prog.image(), startOff, startOff+0x30, pattLogiStart,
sizeof(pattLogiStart), &i)) sizeof(pattLogiStart), &i))
{ {
/* Logitech modula startup. DS is 0, despite appearances */ /* Logitech modula startup. DS is 0, despite appearances */

View File

@ -207,9 +207,9 @@ void Function::writeProcComments(std::ostream &ostr)
{ {
psym = &this->args[i]; psym = &this->args[i];
ostr << " * "<<psym->name<<" = "; ostr << " * "<<psym->name<<" = ";
if (psym->regs->ident.idType == REGISTER) if (psym->regs->ident.type() == REGISTER)
{ {
id = &this->localId.id_arr[psym->regs->ident.idNode.regiIdx]; id = &this->localId.id_arr[((RegisterNode *)psym->regs)->regiIdx];
ostr << Machine_X86::regName(id->id.regi); ostr << Machine_X86::regName(id->id.regi);
} }
else /* long register */ else /* long register */

View File

@ -529,9 +529,11 @@ bool Function::Case_X_and_Y(BB* pbb, BB* thenBB, BB* elseBB)
HLTYPE &hl1(*pbb->back().hlU()); HLTYPE &hl1(*pbb->back().hlU());
HLTYPE &hl2(*thenBB->back().hlU()); HLTYPE &hl2(*thenBB->back().hlU());
BB* obb = elseBB->edges[ELSE].BBptr; BB* obb = elseBB->edges[ELSE].BBptr;
Expr * hl2_expr = hl2.getMyExpr();
/* Construct compound DBL_AND expression */ /* Construct compound DBL_AND expression */
hl1.expr(BinaryOperator::Create(DBL_AND,hl1.expr(),hl2.expr())); assert(hl1.expr());
assert(hl2_expr);
hl1.expr(BinaryOperator::Create(DBL_AND,hl1.expr(),hl2_expr));
/* Replace in-edge to obb from e to pbb */ /* Replace in-edge to obb from e to pbb */
replaceInEdge(obb,elseBB,pbb); replaceInEdge(obb,elseBB,pbb);

View File

@ -20,12 +20,12 @@ using namespace boost;
using namespace boost::adaptors; using namespace boost::adaptors;
struct ExpStack struct ExpStack
{ {
typedef std::list<COND_EXPR *> EXP_STK; typedef std::list<Expr *> EXP_STK;
EXP_STK expStk; /* local expression stack */ EXP_STK expStk; /* local expression stack */
void init(); void init();
void push(COND_EXPR *); void push(Expr *);
COND_EXPR * pop(); Expr * pop();
int numElem(); int numElem();
boolT empty(); boolT empty();
void processExpPush(int &numHlIcodes, iICODE picode) void processExpPush(int &numHlIcodes, iICODE picode)
@ -48,7 +48,7 @@ void ExpStack::init()
} }
/* Pushes the given expression onto the local stack (expStk). */ /* Pushes the given expression onto the local stack (expStk). */
void ExpStack::push(COND_EXPR *expr) void ExpStack::push(Expr *expr)
{ {
expStk.push_back(expr); expStk.push_back(expr);
} }
@ -57,11 +57,11 @@ void ExpStack::push(COND_EXPR *expr)
/* Returns the element on the top of the local expression stack (expStk), /* Returns the element on the top of the local expression stack (expStk),
* and deallocates the space allocated by this node. * and deallocates the space allocated by this node.
* If there are no elements on the stack, returns NULL. */ * If there are no elements on the stack, returns NULL. */
COND_EXPR *ExpStack::pop() Expr *ExpStack::pop()
{ {
if(expStk.empty()) if(expStk.empty())
return 0; return 0;
COND_EXPR *topExp = expStk.back(); Expr *topExp = expStk.back();
expStk.pop_back(); expStk.pop_back();
return topExp; return topExp;
} }
@ -91,13 +91,13 @@ size_t STKFRAME::getLocVar(int off)
/* Returns a string with the source operand of Icode */ /* Returns a string with the source operand of Icode */
static COND_EXPR *srcIdent (const LLInst &ll_insn, Function * pProc, iICODE i, ICODE & duIcode, operDu du) static Expr *srcIdent (const LLInst &ll_insn, Function * pProc, iICODE i, ICODE & duIcode, operDu du)
{ {
if (ll_insn.testFlags(I)) /* immediate operand */ if (ll_insn.testFlags(I)) /* immediate operand */
{ {
if (ll_insn.testFlags(B)) if (ll_insn.testFlags(B))
return AstIdent::Kte (ll_insn.src().getImm2(), 1); return new Constant(ll_insn.src().getImm2(), 1);
return AstIdent::Kte (ll_insn.src().getImm2(), 2); return new Constant(ll_insn.src().getImm2(), 2);
} }
// otherwise // otherwise
return AstIdent::id (ll_insn, SRC, pProc, i, duIcode, du); return AstIdent::id (ll_insn, SRC, pProc, i, duIcode, du);
@ -105,9 +105,9 @@ static COND_EXPR *srcIdent (const LLInst &ll_insn, Function * pProc, iICODE i, I
/* Returns the destination operand */ /* Returns the destination operand */
static COND_EXPR *dstIdent (const LLInst & ll_insn, Function * pProc, iICODE i, ICODE & duIcode, operDu du) static Expr *dstIdent (const LLInst & ll_insn, Function * pProc, iICODE i, ICODE & duIcode, operDu du)
{ {
COND_EXPR *n; Expr *n;
n = AstIdent::id (ll_insn, DST, pProc, i, duIcode, du); n = AstIdent::id (ll_insn, DST, pProc, i, duIcode, du);
/** Is it needed? (pIcode->ll()->flg) & NO_SRC_B **/ /** Is it needed? (pIcode->ll()->flg) & NO_SRC_B **/
return (n); return (n);
@ -120,8 +120,8 @@ void Function::elimCondCodes ()
uint8_t use; /* Used flags bit vector */ uint8_t use; /* Used flags bit vector */
uint8_t def; /* Defined flags bit vector */ uint8_t def; /* Defined flags bit vector */
boolT notSup; /* Use/def combination not supported */ boolT notSup; /* Use/def combination not supported */
COND_EXPR *rhs; /* Source operand */ Expr *rhs; /* Source operand */
COND_EXPR *lhs; /* Destination operand */ Expr *lhs; /* Destination operand */
BinaryOperator *_expr; /* Boolean expression */ BinaryOperator *_expr; /* Boolean expression */
//BB * pBB; /* Pointer to BBs in dfs last ordering */ //BB * pBB; /* Pointer to BBs in dfs last ordering */
riICODE useAt; /* Instruction that used flag */ riICODE useAt; /* Instruction that used flag */
@ -159,12 +159,12 @@ void Function::elimCondCodes ()
break; break;
case iOR: case iOR:
lhs = defAt->hl()->asgn.lhs->clone(); lhs = defAt->hl()->asgn.lhs()->clone();
useAt->copyDU(*defAt, eUSE, eDEF); useAt->copyDU(*defAt, eUSE, eDEF);
if (defAt->ll()->testFlags(B)) if (defAt->ll()->testFlags(B))
rhs = AstIdent::Kte (0, 1); rhs = new Constant(0, 1);
else else
rhs = AstIdent::Kte (0, 2); rhs = new Constant(0, 2);
break; break;
case iTEST: case iTEST:
@ -172,18 +172,18 @@ void Function::elimCondCodes ()
lhs = dstIdent (*defAt->ll(),this, befDefAt,*useAt, eUSE); lhs = dstIdent (*defAt->ll(),this, befDefAt,*useAt, eUSE);
lhs = BinaryOperator::And(lhs, rhs); lhs = BinaryOperator::And(lhs, rhs);
if (defAt->ll()->testFlags(B)) if (defAt->ll()->testFlags(B))
rhs = AstIdent::Kte (0, 1); rhs = new Constant(0, 1);
else else
rhs = AstIdent::Kte (0, 2); rhs = new Constant(0, 2);
break; break;
case iINC: case iINC:
case iDEC: //WARNING: verbatim copy from iOR needs fixing ? case iDEC: //WARNING: verbatim copy from iOR needs fixing ?
lhs = defAt->hl()->asgn.lhs->clone(); lhs = defAt->hl()->asgn.lhs()->clone();
useAt->copyDU(*defAt, eUSE, eDEF); useAt->copyDU(*defAt, eUSE, eDEF);
if (defAt->ll()->testFlags(B)) if (defAt->ll()->testFlags(B))
rhs = AstIdent::Kte (0, 1); rhs = new Constant(0, 1);
else else
rhs = AstIdent::Kte (0, 2); rhs = new Constant(0, 2);
break; break;
default: default:
notSup = true; notSup = true;
@ -202,9 +202,9 @@ void Function::elimCondCodes ()
else if (useAtOp == iJCXZ) else if (useAtOp == iJCXZ)
{ {
lhs = AstIdent::Reg (rCX, 0, &localId); lhs = new RegisterNode(rCX, 0, &localId);
useAt->setRegDU (rCX, eUSE); useAt->setRegDU (rCX, eUSE);
rhs = AstIdent::Kte (0, 2); rhs = new Constant(0, 2);
_expr = BinaryOperator::Create(EQUAL,lhs,rhs); _expr = BinaryOperator::Create(EQUAL,lhs,rhs);
useAt->setJCond(_expr); useAt->setJCond(_expr);
} }
@ -319,7 +319,7 @@ void Function::liveRegAnalysis (LivenessSet &in_liveOut)
auto picode = pbb->rbegin(); /* icode of function return */ auto picode = pbb->rbegin(); /* icode of function return */
if (picode->hl()->opcode == HLI_RET) if (picode->hl()->opcode == HLI_RET)
{ {
picode->hlU()->expr(AstIdent::idID (&retVal, &localId, (++pbb->rbegin()).base())); picode->hlU()->expr(AstIdent::idID(&retVal, &localId, (++pbb->rbegin()).base()));
picode->du.use = in_liveOut; picode->du.use = in_liveOut;
} }
} }
@ -392,13 +392,13 @@ void Function::liveRegAnalysis (LivenessSet &in_liveOut)
/* Remove any references to register variables */ /* Remove any references to register variables */
if (flg & SI_REGVAR) if (flg & SI_REGVAR)
{ {
liveIn.set(rSI,0); liveIn.clrReg(rSI);
pbb->liveIn.set(rSI,0); pbb->liveIn.clrReg(rSI);
} }
if (flg & DI_REGVAR) if (flg & DI_REGVAR)
{ {
liveIn.set(rDI,0); liveIn.clrReg(rDI);
pbb->liveIn.set(rDI,0); pbb->liveIn.clrReg(rDI);
} }
} }
@ -555,23 +555,23 @@ void Function::genDU1 ()
} }
/* Substitutes the rhs (or lhs if rhs not possible) of ticode for the rhs of picode. */ /* Substitutes the rhs (or lhs if rhs not possible) of ticode for the rhs of picode. */
void LOCAL_ID::forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const void LOCAL_ID::forwardSubs (Expr *lhs, Expr *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const
{ {
bool res; bool res;
UnaryOperator *lhs_unary; UnaryOperator *lhs_unary;
while(lhs_unary = dynamic_cast<UnaryOperator *>(lhs)) while( (lhs_unary = dynamic_cast<UnaryOperator *>(lhs)) )
{ {
if(dynamic_cast<AstIdent *>(lhs_unary)) if(dynamic_cast<AstIdent *>(lhs_unary))
break; break;
lhs = lhs_unary->unaryExp; lhs = lhs_unary->unaryExp;
} }
AstIdent * lhs_id=dynamic_cast<AstIdent *>(lhs_unary); RegisterNode * lhs_reg=dynamic_cast<RegisterNode *>(lhs_unary);
assert(lhs_id); assert(lhs_reg);
if (rhs == NULL) /* In case expression popped is NULL */ if (rhs == NULL) /* In case expression popped is NULL */
return; return;
/* Insert on rhs of ticode, if possible */ /* Insert on rhs of ticode, if possible */
res = COND_EXPR::insertSubTreeReg (ticode->hlU()->asgn.rhs,rhs, id_arr[lhs_id->ident.idNode.regiIdx].id.regi, this); res = Expr::insertSubTreeReg (ticode->hlU()->asgn.rhs,rhs, id_arr[lhs_reg->regiIdx].id.regi, this);
if (res) if (res)
{ {
picode->invalidate(); picode->invalidate();
@ -580,7 +580,18 @@ void LOCAL_ID::forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, iICOD
else else
{ {
/* Try to insert it on lhs of ticode*/ /* Try to insert it on lhs of ticode*/
res = COND_EXPR::insertSubTreeReg (ticode->hlU()->asgn.lhs,rhs, id_arr[lhs_id->ident.idNode.regiIdx].id.regi, this); RegisterNode *op = dynamic_cast<RegisterNode *>(ticode->hlU()->asgn.m_lhs);
if(op)
{
eReg inserted = id_arr[lhs_reg->regiIdx].id.regi;
eReg lhsReg = id_arr[op->regiIdx].id.regi;
if((lhsReg==inserted)||Machine_X86::isSubRegisterOf(lhsReg,inserted))
{
// Do not replace ax = XYZ; given ax = H << P; with H << P =
return;
}
}
res = Expr::insertSubTreeReg (ticode->hlU()->asgn.m_lhs,rhs, id_arr[lhs_reg->regiIdx].id.regi, this);
if (res) if (res)
{ {
picode->invalidate(); picode->invalidate();
@ -591,7 +602,7 @@ void LOCAL_ID::forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, iICOD
/* Substitutes the rhs (or lhs if rhs not possible) of ticode for the expression exp given */ /* Substitutes the rhs (or lhs if rhs not possible) of ticode for the expression exp given */
static void forwardSubsLong (int longIdx, COND_EXPR *_exp, iICODE picode, iICODE ticode, int *numHlIcodes) static void forwardSubsLong (int longIdx, Expr *_exp, iICODE picode, iICODE ticode, int *numHlIcodes)
{ {
bool res; bool res;
@ -599,7 +610,7 @@ static void forwardSubsLong (int longIdx, COND_EXPR *_exp, iICODE picode, iICODE
return; return;
/* Insert on rhs of ticode, if possible */ /* Insert on rhs of ticode, if possible */
res = COND_EXPR::insertSubTreeLongReg (_exp, ticode->hlU()->asgn.rhs, longIdx); res = Expr::insertSubTreeLongReg (_exp, ticode->hlU()->asgn.rhs, longIdx);
if (res) if (res)
{ {
picode->invalidate(); picode->invalidate();
@ -608,7 +619,7 @@ static void forwardSubsLong (int longIdx, COND_EXPR *_exp, iICODE picode, iICODE
else else
{ {
/* Try to insert it on lhs of ticode*/ /* Try to insert it on lhs of ticode*/
res = COND_EXPR::insertSubTreeLongReg (_exp, ticode->hlU()->asgn.lhs, longIdx); res = Expr::insertSubTreeLongReg (_exp, ticode->hlU()->asgn.m_lhs, longIdx);
if (res) if (res)
{ {
picode->invalidate(); picode->invalidate();
@ -639,19 +650,9 @@ bool BinaryOperator::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCA
} }
bool AstIdent::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId) bool AstIdent::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId)
{ {
iICODE i;
uint8_t regi;
if (ident.idType == REGISTER) if (ident.idType == REGISTER)
{ {
regi= locId.id_arr[ident.idNode.regiIdx].id.regi; assert(false);
range_to_check.advance_begin(1);
auto all_valid_and_high_level_after_start = range_to_check | filtered(ICODE::select_valid_high_level);
for (ICODE &i : all_valid_and_high_level_after_start)
if ((i.du.def & duReg[regi]).any())
return false;
if (all_valid_and_high_level_after_start.end().base() != lastBBinst)
return true;
return false;
} }
else else
return true; return true;
@ -663,7 +664,7 @@ bool AstIdent::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &
/// @returns the type size of the stored Arg /// @returns the type size of the stored Arg
static int processCArg (Function * pp, Function * pProc, ICODE * picode, size_t numArgs) static int processCArg (Function * pp, Function * pProc, ICODE * picode, size_t numArgs)
{ {
COND_EXPR *_exp; Expr *_exp;
bool res; bool res;
/* if (numArgs == 0) /* if (numArgs == 0)
@ -677,10 +678,10 @@ static int processCArg (Function * pp, Function * pProc, ICODE * picode, size_t
if (pp->flg & PROC_VARARG) if (pp->flg & PROC_VARARG)
{ {
if (numArgs < pp->args.size()) if (numArgs < pp->args.size())
adjustActArgType (_exp, pp->args[numArgs].type, pProc); _exp = pProc->adjustActArgType (_exp, pp->args[numArgs].type);
} }
else else
adjustActArgType (_exp, pp->args[numArgs].type, pProc); _exp = pProc->adjustActArgType (_exp, pp->args[numArgs].type);
} }
} }
else /* user function */ else /* user function */
@ -714,14 +715,14 @@ void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode
boolT res; boolT res;
HLTYPE &p_hl(*picode->hlU()); HLTYPE &p_hl(*picode->hlU());
HLTYPE &t_hl(*ticode->hlU()); HLTYPE &t_hl(*ticode->hlU());
AstIdent *lhs_ident = dynamic_cast<AstIdent *>(p_hl.asgn.lhs);
AstIdent *lhs_ident = dynamic_cast<AstIdent *>(p_hl.asgn.lhs());
switch (t_hl.opcode) switch (t_hl.opcode)
{ {
case HLI_ASSIGN: case HLI_ASSIGN:
assert(lhs_ident);
if(isLong) if(isLong)
{ {
assert(lhs_ident);
forwardSubsLong (lhs_ident->ident.idNode.longIdx, forwardSubsLong (lhs_ident->ident.idNode.longIdx,
p_hl.asgn.rhs, picode,ticode, p_hl.asgn.rhs, picode,ticode,
&numHlIcodes); &numHlIcodes);
@ -734,18 +735,19 @@ void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode
if(isLong) if(isLong)
{ {
assert(lhs_ident); assert(lhs_ident);
res = COND_EXPR::insertSubTreeLongReg ( res = Expr::insertSubTreeLongReg (
p_hl.asgn.rhs, p_hl.asgn.rhs,
t_hl.exp.v, t_hl.exp.v,
lhs_ident->ident.idNode.longIdx); lhs_ident->ident.idNode.longIdx);
} }
else else
{ {
assert(lhs_ident); RegisterNode *lhs_reg = dynamic_cast<RegisterNode *>(p_hl.asgn.lhs());
res = COND_EXPR::insertSubTreeReg ( assert(lhs_reg);
res = Expr::insertSubTreeReg (
t_hl.exp.v, t_hl.exp.v,
p_hl.asgn.rhs, p_hl.asgn.rhs,
id_arr[lhs_ident->ident.idNode.regiIdx].id.regi, id_arr[lhs_reg->regiIdx].id.regi,
this); this);
} }
if (res) if (res)
@ -766,7 +768,7 @@ void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode
} }
} }
void Function::processHliCall(COND_EXPR *_exp, iICODE picode) void Function::processHliCall(Expr *_exp, iICODE picode)
{ {
Function * pp; Function * pp;
int cb, numArgs; int cb, numArgs;
@ -784,7 +786,7 @@ void Function::processHliCall(COND_EXPR *_exp, iICODE picode)
if (pp->flg & PROC_ISLIB) /* library function */ if (pp->flg & PROC_ISLIB) /* library function */
{ {
if (pp->args.numArgs > 0) if (pp->args.numArgs > 0)
adjustActArgType(_exp, pp->args[numArgs].type, this); _exp = adjustActArgType(_exp, pp->args[numArgs].type);
res = picode->newStkArg (_exp, (llIcode)picode->ll()->getOpcode(), this); res = picode->newStkArg (_exp, (llIcode)picode->ll()->getOpcode(), this);
} }
else /* user function */ else /* user function */
@ -834,8 +836,8 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
bool res; bool res;
ID *_retVal; // function return value ID *_retVal; // function return value
COND_EXPR *_exp, // expression pointer - for HLI_POP and HLI_CALL */ Expr *_exp; // expression pointer - for HLI_POP and HLI_CALL */
*lhs; // exp ptr for return value of a HLI_CALL */ //Expr *lhs; // exp ptr for return value of a HLI_CALL */
iICODE ticode; // Target icode */ iICODE ticode; // Target icode */
HLTYPE *ti_hl=0; HLTYPE *ti_hl=0;
uint8_t regi; uint8_t regi;
@ -897,11 +899,11 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
case HLI_JCOND: case HLI_PUSH: case HLI_RET: case HLI_JCOND: case HLI_PUSH: case HLI_RET:
{ {
AstIdent *v = dynamic_cast<AstIdent *>(_icHl.expr()); RegisterNode *v = dynamic_cast<RegisterNode *>(_icHl.expr());
assert(v); assert(v);
res = COND_EXPR::insertSubTreeReg (ti_hl->exp.v, res = Expr::insertSubTreeReg (ti_hl->exp.v,
_exp, _exp,
locals.id_arr[v->ident.idNode.regiIdx].id.regi, locals.id_arr[v->regiIdx].id.regi,
&locals); &locals);
if (res) if (res)
{ {
@ -930,24 +932,24 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
{ {
case HLI_ASSIGN: case HLI_ASSIGN:
assert(ti_hl->asgn.rhs); assert(ti_hl->asgn.rhs);
_exp = _icHl.call.toId(); _exp = _icHl.call.toAst();
res = COND_EXPR::insertSubTreeReg (ti_hl->asgn.rhs,_exp, _retVal->id.regi, &locals); res = Expr::insertSubTreeReg (ti_hl->asgn.rhs,_exp, _retVal->id.regi, &locals);
if (! res) if (! res)
COND_EXPR::insertSubTreeReg (ti_hl->asgn.lhs, _exp,_retVal->id.regi, &locals); Expr::insertSubTreeReg (ti_hl->asgn.m_lhs, _exp,_retVal->id.regi, &locals);
//TODO: HERE missing: 2 regs //TODO: HERE missing: 2 regs
picode->invalidate(); picode->invalidate();
numHlIcodes--; numHlIcodes--;
break; break;
case HLI_PUSH: case HLI_RET: case HLI_PUSH: case HLI_RET:
ti_hl->expr( _icHl.call.toId() ); ti_hl->expr( _icHl.call.toAst() );
picode->invalidate(); picode->invalidate();
numHlIcodes--; numHlIcodes--;
break; break;
case HLI_JCOND: case HLI_JCOND:
_exp = _icHl.call.toId(); _exp = _icHl.call.toAst();
res = COND_EXPR::insertSubTreeReg (ti_hl->exp.v, _exp, _retVal->id.regi, &locals); res = Expr::insertSubTreeReg (ti_hl->exp.v, _exp, _retVal->id.regi, &locals);
if (res) /* was substituted */ if (res) /* was substituted */
{ {
picode->invalidate(); picode->invalidate();
@ -1008,9 +1010,9 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
_exp, picode.base(), ticode, &numHlIcodes); _exp, picode.base(), ticode, &numHlIcodes);
break; break;
case HLI_JCOND: case HLI_PUSH: case HLI_JCOND: case HLI_PUSH:
res = COND_EXPR::insertSubTreeLongReg (_exp, res = Expr::insertSubTreeLongReg (_exp,
ticode->hlU()->exp.v, ticode->hlU()->exp.v,
dynamic_cast<AstIdent *>(_icHl.asgn.lhs)->ident.idNode.longIdx); dynamic_cast<AstIdent *>(_icHl.asgn.lhs())->ident.idNode.longIdx);
if (res) if (res)
{ {
picode->invalidate(); picode->invalidate();
@ -1030,26 +1032,26 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
switch (ticode->hl()->opcode) switch (ticode->hl()->opcode)
{ {
case HLI_ASSIGN: case HLI_ASSIGN:
_exp = _icHl.call.toId(); _exp = _icHl.call.toAst();
ticode->hlU()->asgn.lhs = ticode->hlU()->asgn.lhs(
AstIdent::idLong(&locals, DST, AstIdent::Long(&locals, DST,
ticode,HIGH_FIRST, picode.base(), ticode,HIGH_FIRST, picode.base(),
eDEF, *(++iICODE(ticode))->ll()); eDEF, *(++iICODE(ticode))->ll()));
ticode->hlU()->asgn.rhs = _exp; ticode->hlU()->asgn.rhs = _exp;
picode->invalidate(); picode->invalidate();
numHlIcodes--; numHlIcodes--;
break; break;
case HLI_PUSH: case HLI_RET: case HLI_PUSH: case HLI_RET:
ticode->hlU()->expr( _icHl.call.toId() ); ticode->hlU()->expr( _icHl.call.toAst() );
picode->invalidate(); picode->invalidate();
numHlIcodes--; numHlIcodes--;
break; break;
case HLI_JCOND: case HLI_JCOND:
_exp = _icHl.call.toId(); _exp = _icHl.call.toAst();
_retVal = &picode->hl()->call.proc->retVal; _retVal = &picode->hl()->call.proc->retVal;
res = COND_EXPR::insertSubTreeLongReg (_exp, res = Expr::insertSubTreeLongReg (_exp,
ticode->hlU()->exp.v, ticode->hlU()->exp.v,
locals.newLongReg ( _retVal->type, _retVal->id.longId.h, locals.newLongReg ( _retVal->type, _retVal->id.longId.h,
_retVal->id.longId.l, picode.base())); _retVal->id.longId.l, picode.base()));
@ -1098,7 +1100,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
* assign it to the corresponding registers */ * assign it to the corresponding registers */
if ( not _icHl.call.proc->isLibrary() and (not picode->du1.used(0)) and (picode->du1.numRegsDef > 0)) if ( not _icHl.call.proc->isLibrary() and (not picode->du1.used(0)) and (picode->du1.numRegsDef > 0))
{ {
_exp = AstIdent::idFunc (_icHl.call.proc, _icHl.call.args); _exp = new FuncNode(_icHl.call.proc, _icHl.call.args);
auto lhs = AstIdent::idID (&_icHl.call.proc->retVal, &locals, picode.base()); auto lhs = AstIdent::idID (&_icHl.call.proc->retVal, &locals, picode.base());
picode->setAsgn(lhs, _exp); picode->setAsgn(lhs, _exp);
} }
@ -1110,22 +1112,13 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
void Function::findExps() void Function::findExps()
{ {
//int i, numHlIcodes;
//STKFRAME * args; // pointer to arguments - for HLI_CALL */
/* Initialize expression stack */ /* Initialize expression stack */
g_exp_stk.init(); g_exp_stk.init();
/* Traverse tree in dfsLast order */ /* Traverse tree in dfsLast order */
// for (i = 0; i < numBBs; i++) for(BB *pbb : m_dfsLast | filtered(BB::ValidFunctor()))
for(BB *pbb : m_dfsLast)
{ {
/* Process one BB */ /* Process one valid BB */
// pbb = m_dfsLast[i];
if (not pbb->valid())
continue;
pbb->findBBExps( this->localId, this); pbb->findBBExps( this->localId, this);
} }
} }
@ -1135,6 +1128,16 @@ void Function::preprocessReturnDU(LivenessSet &_liveOut)
{ {
// int idx; // int idx;
bool isAx, isBx, isCx, isDx; bool isAx, isBx, isCx, isDx;
eReg bad_regs[] = {rES,rCS,rDS,rSS};
constexpr char * names[] ={"ES","CS","DS","SS"};
for(int i=0; i<4; ++i)
if(_liveOut.testReg(bad_regs[i]))
{
fprintf(stderr,"LivenessSet probably screwed up, %s register as an liveOut in preprocessReturnDU\n",names[i]);
_liveOut.clrReg(bad_regs[i]);
if(not _liveOut.any())
return;
}
flg |= PROC_IS_FUNC; flg |= PROC_IS_FUNC;
isAx = _liveOut.testReg(rAX); isAx = _liveOut.testReg(rAX);
isBx = _liveOut.testReg(rBX); isBx = _liveOut.testReg(rBX);
@ -1205,7 +1208,20 @@ void Function::preprocessReturnDU(LivenessSet &_liveOut)
else else
retVal.id.regi = rDL; retVal.id.regi = rDL;
/*idx = */localId.newByteWordReg(TYPE_BYTE_SIGN,retVal.id.regi); /*idx = */localId.newByteWordReg(TYPE_BYTE_SIGN,retVal.id.regi);
}
else if(isAH||isBH||isCH||isDH)
{
retVal.type = TYPE_BYTE_SIGN;
retVal.loc = REG_FRAME;
if (isAH)
retVal.id.regi = rAH;
else if (isBH)
retVal.id.regi = rBH;
else if (isCH)
retVal.id.regi = rCH;
else
retVal.id.regi = rDH;
/*idx = */localId.newByteWordReg(TYPE_BYTE_SIGN,retVal.id.regi);
} }
} }
} }
@ -1217,9 +1233,9 @@ void Function::dataFlow(LivenessSet &_liveOut)
/* Remove references to register variables */ /* Remove references to register variables */
if (flg & SI_REGVAR) if (flg & SI_REGVAR)
_liveOut.set(rSI,0); _liveOut.clrReg(rSI);
if (flg & DI_REGVAR) if (flg & DI_REGVAR)
_liveOut.set(rDI,0); _liveOut.clrReg(rDI);
/* Function - return value register(s) */ /* Function - return value register(s) */
preprocessReturnDU(_liveOut); preprocessReturnDU(_liveOut);
@ -1235,4 +1251,3 @@ void Function::dataFlow(LivenessSet &_liveOut)
findExps (); /* forward substitution algorithm */ findExps (); /* forward substitution algorithm */
} }
} }

View File

@ -4,9 +4,9 @@
* (C) Cristina Cifuentes * (C) Cristina Cifuentes
****************************************************************************/ ****************************************************************************/
#include <cstring>
#include "dcc.h" #include "dcc.h"
#include "project.h" #include "project.h"
#include <string.h>
/* Global variables - extern to other modules */ /* Global variables - extern to other modules */
extern char *asm1_name, *asm2_name; /* Assembler output filenames */ extern char *asm1_name, *asm2_name; /* Assembler output filenames */
@ -22,18 +22,102 @@ extern OPTION option; /* Command line options */
static char *initargs(int argc, char *argv[]); static char *initargs(int argc, char *argv[]);
static void displayTotalStats(void); static void displayTotalStats(void);
#include <llvm/Support/raw_os_ostream.h> #include <llvm/Support/raw_os_ostream.h>
#include <llvm/Support/CommandLine.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/TargetRegistry.h>
#include <llvm/Support/PrettyStackTrace.h>
#include <llvm/Support/Signals.h>
#include <llvm/Support/Host.h>
#include <llvm/Target/TargetMachine.h>
#include <llvm/Target/TargetInstrInfo.h>
#include <llvm/MC/MCAsmInfo.h>
#include <llvm/CodeGen/MachineInstrBuilder.h>
#include <llvm/TableGen/Main.h>
#include <llvm/TableGen/TableGenAction.h>
#include <llvm/TableGen/Record.h>
/**************************************************************************** /****************************************************************************
* main * main
***************************************************************************/ ***************************************************************************/
#include <iostream> #include <iostream>
int main(int argc, char *argv[]) using namespace llvm;
class TVisitor : public TableGenAction {
public:
virtual bool operator()(raw_ostream &OS, RecordKeeper &Records)
{
Record *rec = Records.getDef("ADD8i8");
if(rec)
{
if(not rec->getTemplateArgs().empty())
std::cout << "Has template args\n";
auto classes(rec->getSuperClasses());
for(auto val : rec->getSuperClasses())
std::cout << "Super "<<val->getName()<<"\n";
// DagInit * in = rec->getValueAsDag(val.getName());
// in->dump();
for(const RecordVal &val : rec->getValues())
{
// val.dump();
}
rec->dump();
}
// rec = Records.getDef("CCR");
// if(rec)
// rec->dump();
for(auto val : Records.getDefs())
{
//std::cout<< "Def "<<val.first<<"\n";
}
return false;
}
};
int testTblGen(int argc, char **argv)
{
using namespace llvm;
sys::PrintStackTraceOnErrorSignal();
PrettyStackTraceProgram(argc,argv);
cl::ParseCommandLineOptions(argc,argv);
TVisitor tz;
return llvm::TableGenMain(argv[0],tz);
InitializeNativeTarget();
Triple TheTriple;
std::string def = sys::getDefaultTargetTriple();
std::string MCPU="i386";
std::string MARCH="x86";
InitializeAllTargetInfos();
InitializeAllTargetMCs();
InitializeAllAsmPrinters();
InitializeAllAsmParsers();
InitializeAllDisassemblers();
std::string TargetTriple("i386-pc-linux-gnu");
TheTriple = Triple(Triple::normalize(TargetTriple));
MCOperand op=llvm::MCOperand::CreateImm(11);
MCAsmInfo info;
raw_os_ostream wrap(std::cerr);
op.print(wrap,&info);
wrap.flush();
std::cerr<<"\n";
std::string lookuperr;
TargetRegistry::printRegisteredTargetsForVersion();
const Target *t = TargetRegistry::lookupTarget(MARCH,TheTriple,lookuperr);
TargetOptions opts;
std::string Features;
opts.PrintMachineCode=1;
TargetMachine *tm = t->createTargetMachine(TheTriple.getTriple(),MCPU,Features,opts);
std::cerr<<tm->getInstrInfo()->getName(97)<<"\n";
const MCInstrDesc &ds(tm->getInstrInfo()->get(97));
const MCOperandInfo *op1=ds.OpInfo;
uint16_t impl_def = ds.getImplicitDefs()[0];
std::cerr<<lookuperr<<"\n";
exit(0);
}
int main(int argc, char **argv)
{ {
// llvm::MCOperand op=llvm::MCOperand::CreateImm(11);
// llvm::MCAsmInfo info;
// llvm::raw_os_ostream wrap(std::cerr);
// op.print(wrap,&info);
// wrap.flush();
/* Extract switches and filename */ /* Extract switches and filename */
strcpy(option.filename, initargs(argc, argv)); strcpy(option.filename, initargs(argc, argv));

View File

@ -247,7 +247,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
{ {
for (j = 0; j < cb; j++) for (j = 0; j < cb; j++)
{ {
hex_bytes << hex << setw(2) << setfill('0') << uint16_t(prog.Image[inst.label + j]); hex_bytes << hex << setw(2) << setfill('0') << uint16_t(prog.image()[inst.label + j]);
} }
hex_bytes << ' '; hex_bytes << ' ';
} }

View File

@ -139,7 +139,7 @@ static void displayLoadInfo(void)
printf("\nRelocation Table\n"); printf("\nRelocation Table\n");
for (i = 0; i < prog.cReloc; i++) for (i = 0; i < prog.cReloc; i++)
{ {
printf("%06X -> [%04X]\n", prog.relocTable[i],LH(prog.Image + prog.relocTable[i])); printf("%06X -> [%04X]\n", prog.relocTable[i],LH(prog.image() + prog.relocTable[i]));
} }
} }
printf("\n"); printf("\n");
@ -303,12 +303,12 @@ void DccFrontend::LoadImage(Project &proj)
/* Allocate a block of memory for the program. */ /* Allocate a block of memory for the program. */
prog.cbImage = cb + sizeof(PSP); prog.cbImage = cb + sizeof(PSP);
prog.Image = new uint8_t [prog.cbImage]; prog.Imagez = new uint8_t [prog.cbImage];
prog.Image[0] = 0xCD; /* Fill in PSP int 20h location */ prog.Imagez[0] = 0xCD; /* Fill in PSP int 20h location */
prog.Image[1] = 0x20; /* for termination checking */ prog.Imagez[1] = 0x20; /* for termination checking */
/* Read in the image past where a PSP would go */ /* Read in the image past where a PSP would go */
if (cb != (int)fread(prog.Image + sizeof(PSP), 1, (size_t)cb, fp)) if (cb != (int)fread(prog.Imagez + sizeof(PSP), 1, (size_t)cb, fp))
{ {
fatalError(CANNOT_READ, proj.binary_path().c_str()); fatalError(CANNOT_READ, proj.binary_path().c_str());
} }
@ -323,7 +323,7 @@ void DccFrontend::LoadImage(Project &proj)
{ {
for (i = 0; i < prog.cReloc; i++) for (i = 0; i < prog.cReloc; i++)
{ {
uint8_t *p = &prog.Image[prog.relocTable[i]]; uint8_t *p = &prog.Imagez[prog.relocTable[i]];
uint16_t w = (uint16_t)LH(p) + EXE_RELOCATION; uint16_t w = (uint16_t)LH(p) + EXE_RELOCATION;
*p++ = (uint8_t)(w & 0x00FF); *p++ = (uint8_t)(w & 0x00FF);
*p = (uint8_t)((w & 0xFF00) >> 8); *p = (uint8_t)((w & 0xFF00) >> 8);

View File

@ -11,7 +11,6 @@
#include "dcc.h" #include "dcc.h"
using namespace std; using namespace std;
/* Masks off bits set by duReg[] */ /* Masks off bits set by duReg[] */
LivenessSet maskDuReg[] = { 0x00, LivenessSet maskDuReg[] = { 0x00,
/* uint16_t regs */ /* uint16_t regs */
@ -38,7 +37,7 @@ static char buf[lineSize]; /* Line buffer for hl icode output */
/* Places the new HLI_ASSIGN high-level operand in the high-level icode array */ /* Places the new HLI_ASSIGN high-level operand in the high-level icode array */
void HLTYPE::setAsgn(COND_EXPR *lhs, COND_EXPR *rhs) void HLTYPE::setAsgn(Expr *lhs, Expr *rhs)
{ {
assert(lhs); assert(lhs);
set(lhs,rhs); set(lhs,rhs);
@ -68,7 +67,7 @@ void ICODE::newCallHl()
/* Places the new HLI_POP/HLI_PUSH/HLI_RET high-level operand in the high-level icode /* Places the new HLI_POP/HLI_PUSH/HLI_RET high-level operand in the high-level icode
* array */ * array */
void ICODE::setUnary(hlIcode op, COND_EXPR *_exp) void ICODE::setUnary(hlIcode op, Expr *_exp)
{ {
type = HIGH_LEVEL; type = HIGH_LEVEL;
hlU()->set(op,_exp); hlU()->set(op,_exp);
@ -76,7 +75,7 @@ void ICODE::setUnary(hlIcode op, COND_EXPR *_exp)
/* Places the new HLI_JCOND high-level operand in the high-level icode array */ /* Places the new HLI_JCOND high-level operand in the high-level icode array */
void ICODE::setJCond(COND_EXPR *cexp) void ICODE::setJCond(Expr *cexp)
{ {
type = HIGH_LEVEL; type = HIGH_LEVEL;
hlU()->set(HLI_JCOND,cexp); hlU()->set(HLI_JCOND,cexp);
@ -293,8 +292,8 @@ void Function::highLevelGen()
{ {
size_t numIcode; /* number of icode instructions */ size_t numIcode; /* number of icode instructions */
iICODE pIcode; /* ptr to current icode node */ iICODE pIcode; /* ptr to current icode node */
COND_EXPR *lhs; Expr *lhs;
COND_EXPR *rhs; /* left- and right-hand side of expression */ Expr *rhs; /* left- and right-hand side of expression */
uint32_t _flg; /* icode flags */ uint32_t _flg; /* icode flags */
numIcode = Icode.size(); numIcode = Icode.size();
for (iICODE i = Icode.begin(); i!=Icode.end() ; ++i) for (iICODE i = Icode.begin(); i!=Icode.end() ; ++i)
@ -333,8 +332,7 @@ void Function::highLevelGen()
break; break;
case iDEC: case iDEC:
rhs = AstIdent::Kte (1, 2); rhs = new BinaryOperator(SUB,lhs, new Constant(1, 2));
rhs = new BinaryOperator(SUB,lhs, rhs);
pIcode->setAsgn(lhs, rhs); pIcode->setAsgn(lhs, rhs);
break; break;
@ -343,12 +341,12 @@ void Function::highLevelGen()
rhs = new BinaryOperator(DIV,lhs, rhs); rhs = new BinaryOperator(DIV,lhs, rhs);
if ( ll->testFlags(B) ) if ( ll->testFlags(B) )
{ {
lhs = AstIdent::Reg (rAL, 0, &localId); lhs = new RegisterNode(rAL, 0, &localId);
pIcode->setRegDU( rAL, eDEF); pIcode->setRegDU( rAL, eDEF);
} }
else else
{ {
lhs = AstIdent::Reg (rAX, 0, &localId); lhs = new RegisterNode(rAX, 0, &localId);
pIcode->setRegDU( rAX, eDEF); pIcode->setRegDU( rAX, eDEF);
} }
pIcode->setAsgn(lhs, rhs); pIcode->setAsgn(lhs, rhs);
@ -361,8 +359,7 @@ void Function::highLevelGen()
break; break;
case iINC: case iINC:
rhs = AstIdent::Kte (1, 2); rhs = new BinaryOperator(ADD,lhs, new Constant(1, 2));
rhs = new BinaryOperator(ADD,lhs, rhs);
pIcode->setAsgn(lhs, rhs); pIcode->setAsgn(lhs, rhs);
break; break;
@ -373,16 +370,15 @@ void Function::highLevelGen()
case iMOD: case iMOD:
rhs = new BinaryOperator(MOD,lhs, rhs); rhs = new BinaryOperator(MOD,lhs, rhs);
eReg lhs_reg;
if ( ll->testFlags(B) ) if ( ll->testFlags(B) )
{ lhs_reg = rAH;
lhs = AstIdent::Reg (rAH, 0, &localId);
pIcode->setRegDU( rAH, eDEF);
}
else else
{ lhs_reg = rDX;
lhs = AstIdent::Reg (rDX, 0, &localId);
pIcode->setRegDU( rDX, eDEF); lhs = new RegisterNode(lhs_reg, 0, &localId);
} pIcode->setRegDU( lhs_reg, eDEF);
pIcode->setAsgn(lhs, rhs); pIcode->setAsgn(lhs, rhs);
break; break;
@ -462,7 +458,7 @@ void Function::highLevelGen()
/* Returns the string that represents the procedure call of tproc (ie. with /* Returns the string that represents the procedure call of tproc (ie. with
* actual parameters) */ * actual parameters) */
std::string writeCall (Function * tproc, STKFRAME & args, Function * pproc, int *numLoc) std::string Function::writeCall (Function * tproc, STKFRAME & args, int *numLoc)
{ {
//string condExp; //string condExp;
ostringstream ostr; ostringstream ostr;
@ -470,7 +466,7 @@ std::string writeCall (Function * tproc, STKFRAME & args, Function * pproc, int
for(const STKSYM &sym : args) for(const STKSYM &sym : args)
{ {
if(sym.actual) if(sym.actual)
ostr << sym.actual->walkCondExpr (pproc, numLoc); ostr << sym.actual->walkCondExpr (this, numLoc);
else else
ostr << ""; ostr << "";
if((&sym)!=&(args.back())) if((&sym)!=&(args.back()))
@ -484,11 +480,15 @@ std::string writeCall (Function * tproc, STKFRAME & args, Function * pproc, int
/* Displays the output of a HLI_JCOND icode. */ /* Displays the output of a HLI_JCOND icode. */
char *writeJcond (const HLTYPE &h, Function * pProc, int *numLoc) char *writeJcond (const HLTYPE &h, Function * pProc, int *numLoc)
{ {
assert(h.expr());
memset (buf, ' ', sizeof(buf)); memset (buf, ' ', sizeof(buf));
buf[0] = '\0'; buf[0] = '\0';
strcat (buf, "if "); strcat (buf, "if ");
COND_EXPR *inverted=h.expr()->inverse(); if(h.opcode==HLI_INVALID)
{
return "if (*HLI_INVALID*) {\n";
}
assert(h.expr());
Expr *inverted=h.expr()->inverse();
//inverseCondOp (&h.exp); //inverseCondOp (&h.exp);
std::string e = inverted->walkCondExpr (pProc, numLoc); std::string e = inverted->walkCondExpr (pProc, numLoc);
delete inverted; delete inverted;
@ -506,7 +506,12 @@ char *writeJcondInv (HLTYPE h, Function * pProc, int *numLoc)
memset (buf, ' ', sizeof(buf)); memset (buf, ' ', sizeof(buf));
buf[0] = '\0'; buf[0] = '\0';
strcat (buf, "if "); strcat (buf, "if ");
std::string e = h.expr()->walkCondExpr (pProc, numLoc); std::string e;
if(h.expr()==nullptr)
e = "( *failed condition recovery* )";
else
e = h.expr()->walkCondExpr (pProc, numLoc);
strcat (buf, e.c_str()); strcat (buf, e.c_str());
strcat (buf, " {\n"); strcat (buf, " {\n");
return (buf); return (buf);
@ -515,7 +520,7 @@ char *writeJcondInv (HLTYPE h, Function * pProc, int *numLoc)
string AssignType::writeOut(Function *pProc, int *numLoc) const string AssignType::writeOut(Function *pProc, int *numLoc) const
{ {
ostringstream ostr; ostringstream ostr;
ostr << lhs->walkCondExpr (pProc, numLoc); ostr << m_lhs->walkCondExpr (pProc, numLoc);
ostr << " = "; ostr << " = ";
ostr << rhs->walkCondExpr (pProc, numLoc); ostr << rhs->walkCondExpr (pProc, numLoc);
ostr << ";\n"; ostr << ";\n";
@ -524,7 +529,7 @@ string AssignType::writeOut(Function *pProc, int *numLoc) const
string CallType::writeOut(Function *pProc, int *numLoc) const string CallType::writeOut(Function *pProc, int *numLoc) const
{ {
ostringstream ostr; ostringstream ostr;
ostr << writeCall (proc, *args, pProc,numLoc); ostr << pProc->writeCall (proc, *args, numLoc);
ostr << ";\n"; ostr << ";\n";
return ostr.str(); return ostr.str();
} }
@ -535,13 +540,14 @@ string ExpType::writeOut(Function *pProc, int *numLoc) const
return v->walkCondExpr (pProc, numLoc); return v->walkCondExpr (pProc, numLoc);
} }
void HLTYPE::set(COND_EXPR *l, COND_EXPR *r) void HLTYPE::set(Expr *l, Expr *r)
{ {
assert(l); assert(l);
assert(r); assert(r);
opcode = HLI_ASSIGN; opcode = HLI_ASSIGN;
assert((asgn.lhs==0) and (asgn.rhs==0)); //prevent memory leaks //assert((asgn.lhs==0) and (asgn.rhs==0)); //prevent memory leaks
asgn.lhs=l; assert(dynamic_cast<UnaryOperator *>(l));
asgn.m_lhs=l;
asgn.rhs=r; asgn.rhs=r;
} }
/* Returns a string with the contents of the current high-level icode. /* Returns a string with the contents of the current high-level icode.

View File

@ -1,7 +1,7 @@
#include "icode.h" #include "icode.h"
#include "ast.h" #include "ast.h"
void HLTYPE::replaceExpr(COND_EXPR *e) void HLTYPE::replaceExpr(Expr *e)
{ {
assert(e); assert(e);
delete exp.v; delete exp.v;

View File

@ -103,6 +103,12 @@ void HLTYPE::setCall(Function *proc)
} }
bool AssignType::removeRegFromLong(eReg regi, LOCAL_ID *locId) bool AssignType::removeRegFromLong(eReg regi, LOCAL_ID *locId)
{ {
lhs->performLongRemoval(regi,locId); m_lhs=lhs()->performLongRemoval(regi,locId);
return true; return true;
} }
void AssignType::lhs(Expr *l)
{
assert(dynamic_cast<UnaryOperator *>(l));
m_lhs=l;
}

View File

@ -26,9 +26,9 @@ bool Idiom5::match(iICODE pIcode)
int Idiom5::action() int Idiom5::action()
{ {
AstIdent *rhs,*lhs; AstIdent *rhs,*lhs;
COND_EXPR *expr; Expr *expr;
lhs = AstIdent::idLong (&m_func->localId, DST, m_icodes[0], LOW_FIRST, m_icodes[0], USE_DEF, *m_icodes[1]->ll()); lhs = AstIdent::Long (&m_func->localId, DST, m_icodes[0], LOW_FIRST, m_icodes[0], USE_DEF, *m_icodes[1]->ll());
rhs = AstIdent::idLong (&m_func->localId, SRC, m_icodes[0], LOW_FIRST, m_icodes[0], eUSE, *m_icodes[1]->ll()); rhs = AstIdent::Long (&m_func->localId, SRC, m_icodes[0], LOW_FIRST, m_icodes[0], eUSE, *m_icodes[1]->ll());
expr = new BinaryOperator(ADD,lhs, rhs); expr = new BinaryOperator(ADD,lhs, rhs);
m_icodes[0]->setAsgn(lhs, expr); m_icodes[0]->setAsgn(lhs, expr);
m_icodes[1]->invalidate(); m_icodes[1]->invalidate();
@ -61,9 +61,9 @@ int Idiom6::action()
{ {
AstIdent *rhs,*lhs; AstIdent *rhs,*lhs;
COND_EXPR *expr; Expr *expr;
lhs = AstIdent::idLong (&m_func->localId, DST, m_icodes[0], LOW_FIRST, m_icodes[0], USE_DEF, *m_icodes[1]->ll()); lhs = AstIdent::Long (&m_func->localId, DST, m_icodes[0], LOW_FIRST, m_icodes[0], USE_DEF, *m_icodes[1]->ll());
rhs = AstIdent::idLong (&m_func->localId, SRC, m_icodes[0], LOW_FIRST, m_icodes[0], eUSE, *m_icodes[1]->ll()); rhs = AstIdent::Long (&m_func->localId, SRC, m_icodes[0], LOW_FIRST, m_icodes[0], eUSE, *m_icodes[1]->ll());
expr = new BinaryOperator(SUB,lhs, rhs); expr = new BinaryOperator(SUB,lhs, rhs);
m_icodes[0]->setAsgn(lhs, expr); m_icodes[0]->setAsgn(lhs, expr);
m_icodes[1]->invalidate(); m_icodes[1]->invalidate();
@ -102,7 +102,13 @@ bool Idiom18::match(iICODE picode)
m_is_dec = m_icodes[1]->ll()->match(iDEC); m_is_dec = m_icodes[1]->ll()->match(iDEC);
uint8_t regi; /* register of the MOV */ uint8_t regi; /* register of the MOV */
if(not (m_icodes[0]->ll()->match(iMOV) and m_icodes[0]->ll()->dst.isReg() ))
return false;
regi = m_icodes[0]->ll()->dst.regi;
if( not ( m_icodes[2]->ll()->match(iCMP) && (m_icodes[2]->ll()->dst.regi == regi) &&
m_icodes[3]->ll()->conditionalJump() ) )
return false;
// Simple matching finished, select apropriate matcher based on dst type
/* Get variable */ /* Get variable */
if (m_icodes[1]->ll()->dst.regi == 0) /* global variable */ if (m_icodes[1]->ll()->dst.regi == 0) /* global variable */
{ {
@ -111,10 +117,11 @@ bool Idiom18::match(iICODE picode)
} }
else if ( m_icodes[1]->ll()->dst.isReg() ) /* register */ else if ( m_icodes[1]->ll()->dst.isReg() ) /* register */
{ {
if ((m_icodes[1]->ll()->dst.regi == rSI) && (m_func->flg & SI_REGVAR)) m_idiom_type = 1;
m_idiom_type = 1; // if ((m_icodes[1]->ll()->dst.regi == rSI) && (m_func->flg & SI_REGVAR))
else if ((m_icodes[1]->ll()->dst.regi == rDI) && (m_func->flg & DI_REGVAR)) // m_idiom_type = 1;
m_idiom_type = 1; // else if ((m_icodes[1]->ll()->dst.regi == rDI) && (m_func->flg & DI_REGVAR))
// m_idiom_type = 1;
} }
else if (m_icodes[1]->ll()->dst.off) /* local variable */ else if (m_icodes[1]->ll()->dst.off) /* local variable */
m_idiom_type = 2; m_idiom_type = 2;
@ -134,31 +141,23 @@ bool Idiom18::match(iICODE picode)
break; break;
case 1: /* register variable */ case 1: /* register variable */
/* Check previous instruction for a MOV */ /* Check previous instruction for a MOV */
if (m_icodes[0]->ll()->match(iMOV) && (m_icodes[0]->ll()->src().regi == m_icodes[1]->ll()->dst.regi)) if ( (m_icodes[0]->ll()->src().regi == m_icodes[1]->ll()->dst.regi))
{ {
regi = m_icodes[0]->ll()->dst.regi; return true;
if ( m_icodes[0]->ll()->dst.isReg() )
{
if ( m_icodes[2]->ll()->match(iCMP) && (m_icodes[2]->ll()->dst.regi == regi) &&
m_icodes[3]->ll()->conditionalJump() )
return true;
}
} }
break; break;
case 2: /* local */ case 2: /* local */
if (m_icodes[0]->ll()->match(iMOV) && (m_icodes[0]->ll()->src().off == m_icodes[1]->ll()->dst.off)) if ((m_icodes[0]->ll()->src().off == m_icodes[1]->ll()->dst.off))
{ {
regi = m_icodes[0]->ll()->dst.regi; return true;
if ( m_icodes[0]->ll()->dst.isReg() )
{
if ( m_icodes[2]->ll()->match(iCMP) && (m_icodes[2]->ll()->dst.regi == regi) &&
m_icodes[3]->ll()->conditionalJump() )
return true;
}
} }
break; break;
case 3: // indexed case 3: // indexed
printf("Unsupported idiom18 type: indexed"); printf("Untested idiom18 type: indexed\n");
if ((m_icodes[0]->ll()->src() == m_icodes[1]->ll()->dst))
{
return true;
}
break; break;
} }
return false; return false;
@ -166,8 +165,8 @@ bool Idiom18::match(iICODE picode)
int Idiom18::action() // action length int Idiom18::action() // action length
{ {
COND_EXPR *rhs,*lhs;/* Pointers to left and right hand side exps */ Expr *rhs,*lhs;/* Pointers to left and right hand side exps */
COND_EXPR *expr; Expr *expr;
lhs = AstIdent::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[1], *m_icodes[1], eUSE); lhs = AstIdent::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[1], *m_icodes[1], eUSE);
lhs = UnaryOperator::Create(m_is_dec ? POST_DEC : POST_INC, lhs); lhs = UnaryOperator::Create(m_is_dec ? POST_DEC : POST_INC, lhs);
rhs = AstIdent::id (*m_icodes[2]->ll(), SRC, m_func, m_icodes[1], *m_icodes[3], eUSE); rhs = AstIdent::id (*m_icodes[2]->ll(), SRC, m_func, m_icodes[1], *m_icodes[3], eUSE);
@ -195,38 +194,40 @@ bool Idiom19::match(iICODE picode)
if(std::distance(picode,m_end)<2) if(std::distance(picode,m_end)<2)
return false; return false;
ICODE &ic(*picode); ICODE &ic(*picode);
int type;
for(int i=0; i<2; ++i) for(int i=0; i<2; ++i)
m_icodes[i] =picode++; m_icodes[i] =picode++;
m_is_dec = m_icodes[0]->ll()->match(iDEC); m_is_dec = m_icodes[0]->ll()->match(iDEC);
if ( not m_icodes[1]->ll()->conditionalJump() )
return false;
if (m_icodes[0]->ll()->dst.regi == 0) /* global variable */ if (m_icodes[0]->ll()->dst.regi == 0) /* global variable */
/* not supported yet */ ; /* not supported yet */ ;
else if ( m_icodes[0]->ll()->dst.isReg() ) /* register */ else if ( m_icodes[0]->ll()->dst.isReg() ) /* register */
{ {
// if (((picode->ll()->dst.regi == rSI) && (pproc->flg & SI_REGVAR)) || // if (((picode->ll()->dst.regi == rSI) && (pproc->flg & SI_REGVAR)) ||
// ((picode->ll()->dst.regi == rDI) && (pproc->flg & DI_REGVAR))) // ((picode->ll()->dst.regi == rDI) && (pproc->flg & DI_REGVAR)))
if (m_icodes[1]->ll()->conditionalJump()) return true;
return true;
} }
else if (m_icodes[0]->ll()->dst.off) /* stack variable */ else if (m_icodes[0]->ll()->dst.off) /* stack variable */
{ {
if ( m_icodes[1]->ll()->conditionalJump() ) return true;
return true;
} }
else /* indexed */ else /* indexed */
{ {
fprintf(stderr,"idiom19 : Untested type [indexed]\n");
return true;
/* not supported yet */ /* not supported yet */
} }
return false; return false;
} }
int Idiom19::action() int Idiom19::action()
{ {
COND_EXPR *lhs,*rhs,*expr; Expr *lhs,*expr;
ICODE &ic1(*m_icodes[1]);
lhs = AstIdent::id (*m_icodes[0]->ll(), DST, m_func, m_icodes[0], *m_icodes[1], eUSE); lhs = AstIdent::id (*m_icodes[0]->ll(), DST, m_func, m_icodes[0], *m_icodes[1], eUSE);
lhs = UnaryOperator::Create(m_is_dec ? PRE_DEC : PRE_INC, lhs); lhs = UnaryOperator::Create(m_is_dec ? PRE_DEC : PRE_INC, lhs);
rhs = AstIdent::Kte (0, 2); expr = new BinaryOperator(condOpJCond[m_icodes[1]->ll()->getOpcode() - iJB],lhs, new Constant(0, 2));
expr = new BinaryOperator(condOpJCond[m_icodes[1]->ll()->getOpcode() - iJB],lhs, rhs);
m_icodes[1]->setJCond(expr); m_icodes[1]->setJCond(expr);
m_icodes[0]->invalidate(); m_icodes[0]->invalidate();
return 2; return 2;
@ -255,6 +256,9 @@ bool Idiom20::match(iICODE picode)
return false; return false;
for(int i=0; i<4; ++i) for(int i=0; i<4; ++i)
m_icodes[i] =picode++; m_icodes[i] =picode++;
/* Check second instruction for a MOV */
if(not (m_icodes[1]->ll()->match(iMOV) && m_icodes[1]->ll()->dst.isReg()))
return false;
m_is_dec = m_icodes[0]->ll()->match(iDEC) ? PRE_DEC : PRE_INC; m_is_dec = m_icodes[0]->ll()->match(iDEC) ? PRE_DEC : PRE_INC;
@ -266,53 +270,52 @@ bool Idiom20::match(iICODE picode)
} }
else if ( ll_dest.isReg() ) /* register */ else if ( ll_dest.isReg() ) /* register */
{ {
if ((ll_dest.regi == rSI) && (m_func->flg & SI_REGVAR)) type = 1;
type = 1; // if ((ll_dest.regi == rSI) && (m_func->flg & SI_REGVAR))
else if ((ll_dest.regi == rDI) && (m_func->flg & DI_REGVAR)) // type = 1;
type = 1; // else if ((ll_dest.regi == rDI) && (m_func->flg & DI_REGVAR))
// type = 1;
} }
else if (ll_dest.off) /* local variable */ else if (ll_dest.off) /* local variable */
type = 2; type = 2;
else /* indexed */ else /* indexed */
{ {
printf("idiom20 : Unsupported type [indexed]\n"); printf("idiom20 : Untested type [indexed]\n");
type = 3;
/* not supported yet */ ; /* not supported yet */ ;
} }
regi = m_icodes[1]->ll()->dst.regi;
/* Check previous instruction for a MOV */ const LLOperand &mov_src(m_icodes[1]->ll()->src());
if (type == 1) /* register variable */ if (m_icodes[2]->ll()->match(iCMP,(eReg)regi) && m_icodes[3]->ll()->conditionalJump())
{ {
if (m_icodes[1]->ll()->match(iMOV) && switch(type)
(m_icodes[1]->ll()->src().regi == ll_dest.regi))
{ {
regi = m_icodes[1]->ll()->dst.regi; case 1: /* register variable */
if ( m_icodes[1]->ll()->dst.isReg() ) if ((mov_src.regi == ll_dest.regi))
{ {
if (m_icodes[2]->ll()->match(iCMP,(eReg)regi) &&
m_icodes[3]->ll()->conditionalJump())
return true; return true;
} }
} break;
} case 2: // local
else if (type == 2) /* local */ if ((mov_src.off == ll_dest.off))
{ {
if ( m_icodes[0]->ll()->match(iMOV) &&
(m_icodes[1]->ll()->src().off == ll_dest.off))
{
regi = m_icodes[1]->ll()->dst.regi;
if ( m_icodes[1]->ll()->dst.isReg() )
{
if (m_icodes[2]->ll()->match(iCMP,(eReg)regi) &&
m_icodes[3]->ll()->conditionalJump())
return true; return true;
} }
break;
case 3:
fprintf(stderr,"Test 3 ");
if ((mov_src == ll_dest))
{
return true;
}
break;
} }
} }
return false; return false;
} }
int Idiom20::action() int Idiom20::action()
{ {
COND_EXPR *lhs,*rhs,*expr; Expr *lhs,*rhs,*expr;
lhs = AstIdent::id (*m_icodes[1]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], eUSE); lhs = AstIdent::id (*m_icodes[1]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], eUSE);
lhs = UnaryOperator::Create(m_is_dec, lhs); lhs = UnaryOperator::Create(m_is_dec, lhs);
rhs = AstIdent::id (*m_icodes[2]->ll(), SRC, m_func, m_icodes[0], *m_icodes[3], eUSE); rhs = AstIdent::id (*m_icodes[2]->ll(), SRC, m_func, m_icodes[0], *m_icodes[3], eUSE);

View File

@ -50,7 +50,7 @@ int Idiom14::action()
{ {
int idx; int idx;
AstIdent *lhs; AstIdent *lhs;
COND_EXPR *rhs; Expr *rhs;
idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, m_regH, m_regL, m_icodes[0]); idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, m_regH, m_regL, m_icodes[0]);
lhs = AstIdent::LongIdx (idx); lhs = AstIdent::LongIdx (idx);
@ -101,8 +101,8 @@ bool Idiom13::match(iICODE pIcode)
int Idiom13::action() int Idiom13::action()
{ {
AstIdent *lhs; AstIdent *lhs;
COND_EXPR *rhs; Expr *rhs;
lhs = AstIdent::Reg (m_loaded_reg, 0, &m_func->localId); lhs = new RegisterNode(m_loaded_reg, 0, &m_func->localId);
m_icodes[0]->setRegDU( m_loaded_reg, eDEF); m_icodes[0]->setRegDU( m_loaded_reg, eDEF);
m_icodes[0]->du1.numRegsDef--; /* prev uint8_t reg def */ m_icodes[0]->du1.numRegsDef--; /* prev uint8_t reg def */
rhs = AstIdent::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], NONE); rhs = AstIdent::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], NONE);

View File

@ -53,8 +53,8 @@ bool Idiom11::match (iICODE picode)
int Idiom11::action() int Idiom11::action()
{ {
AstIdent *lhs; AstIdent *lhs;
COND_EXPR *rhs; Expr *rhs;
lhs = AstIdent::idLong (&m_func->localId, DST, m_icodes[0], HIGH_FIRST,m_icodes[0], USE_DEF, *m_icodes[1]->ll()); lhs = AstIdent::Long (&m_func->localId, DST, m_icodes[0], HIGH_FIRST,m_icodes[0], USE_DEF, *m_icodes[1]->ll());
rhs = UnaryOperator::Create(NEGATION, lhs); rhs = UnaryOperator::Create(NEGATION, lhs);
m_icodes[0]->setAsgn(lhs, rhs); m_icodes[0]->setAsgn(lhs, rhs);
m_icodes[1]->invalidate(); m_icodes[1]->invalidate();
@ -96,8 +96,8 @@ bool Idiom16::match (iICODE picode)
int Idiom16::action() int Idiom16::action()
{ {
AstIdent *lhs; AstIdent *lhs;
COND_EXPR *rhs; Expr *rhs;
lhs = AstIdent::Reg (m_icodes[0]->ll()->dst.regi, m_icodes[0]->ll()->getFlag(),&m_func->localId); lhs = new RegisterNode(m_icodes[0]->ll()->dst.regi, m_icodes[0]->ll()->getFlag(),&m_func->localId);
rhs = UnaryOperator::Create(NEGATION, lhs->clone()); rhs = UnaryOperator::Create(NEGATION, lhs->clone());
m_icodes[0]->setAsgn(lhs, rhs); m_icodes[0]->setAsgn(lhs, rhs);
m_icodes[1]->invalidate(); m_icodes[1]->invalidate();

View File

@ -29,7 +29,7 @@ int Idiom8::action()
{ {
int idx; int idx;
AstIdent *lhs; AstIdent *lhs;
COND_EXPR *rhs,*expr; Expr *expr;
eReg regH,regL; eReg regH,regL;
regH=m_icodes[0]->ll()->dst.regi; regH=m_icodes[0]->ll()->dst.regi;
regL=m_icodes[1]->ll()->dst.regi; regL=m_icodes[1]->ll()->dst.regi;
@ -37,8 +37,7 @@ int Idiom8::action()
lhs = AstIdent::LongIdx (idx); lhs = AstIdent::LongIdx (idx);
m_icodes[0]->setRegDU( regL, USE_DEF); m_icodes[0]->setRegDU( regL, USE_DEF);
rhs = AstIdent::Kte(1,2); expr = new BinaryOperator(SHR,lhs, new Constant(1, 2));
expr = new BinaryOperator(SHR,lhs, rhs);
m_icodes[0]->setAsgn(lhs, expr); m_icodes[0]->setAsgn(lhs, expr);
m_icodes[1]->invalidate(); m_icodes[1]->invalidate();
return 2; return 2;
@ -81,11 +80,11 @@ int Idiom15::action()
{ {
AstIdent *lhs; AstIdent *lhs;
COND_EXPR *rhs,*_exp; Expr *rhs,*_exp;
lhs = AstIdent::Reg (m_icodes[0]->ll()->dst.regi, lhs = new RegisterNode(m_icodes[0]->ll()->dst.regi,
m_icodes[0]->ll()->getFlag() & NO_SRC_B, m_icodes[0]->ll()->getFlag() & NO_SRC_B,
&m_func->localId); &m_func->localId);
rhs = AstIdent::Kte (m_icodes.size(), 2); rhs = new Constant(m_icodes.size(), 2);
_exp = new BinaryOperator(SHL,lhs, rhs); _exp = new BinaryOperator(SHL,lhs, rhs);
m_icodes[0]->setAsgn(lhs, _exp); m_icodes[0]->setAsgn(lhs, _exp);
for (size_t i=1; i<m_icodes.size()-1; ++i) for (size_t i=1; i<m_icodes.size()-1; ++i)
@ -119,7 +118,7 @@ bool Idiom12::match(iICODE pIcode)
int Idiom12::action() int Idiom12::action()
{ {
int idx; int idx;
COND_EXPR *rhs,*expr; Expr *expr;
AstIdent *lhs; AstIdent *lhs;
eReg regH,regL; eReg regH,regL;
@ -129,8 +128,7 @@ int Idiom12::action()
idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN, regH, regL,m_icodes[0]); idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN, regH, regL,m_icodes[0]);
lhs = AstIdent::LongIdx (idx); lhs = AstIdent::LongIdx (idx);
m_icodes[0]->setRegDU( regH, USE_DEF); m_icodes[0]->setRegDU( regH, USE_DEF);
rhs = AstIdent::Kte (1, 2); expr = new BinaryOperator(SHL,lhs, new Constant(1, 2));
expr = new BinaryOperator(SHL,lhs, rhs);
m_icodes[0]->setAsgn(lhs, expr); m_icodes[0]->setAsgn(lhs, expr);
m_icodes[1]->invalidate(); m_icodes[1]->invalidate();
return 2; return 2;
@ -161,15 +159,14 @@ int Idiom9::action()
{ {
int idx; int idx;
AstIdent *lhs; AstIdent *lhs;
COND_EXPR *rhs,*expr; Expr *rhs,*expr;
eReg regH,regL; eReg regH,regL;
regL=m_icodes[1]->ll()->dst.regi; regL=m_icodes[1]->ll()->dst.regi;
regH=m_icodes[0]->ll()->dst.regi; regH=m_icodes[0]->ll()->dst.regi;
idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN,regH,regL,m_icodes[0]); idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN,regH,regL,m_icodes[0]);
lhs = AstIdent::LongIdx (idx); lhs = AstIdent::LongIdx (idx);
m_icodes[0]->setRegDU(regL, USE_DEF); m_icodes[0]->setRegDU(regL, USE_DEF);
rhs = AstIdent::Kte (1, 2); expr = new BinaryOperator(SHR,lhs, new Constant(1, 2));
expr = new BinaryOperator(SHR,lhs, rhs);
m_icodes[0]->setAsgn(lhs, expr); m_icodes[0]->setAsgn(lhs, expr);
m_icodes[1]->invalidate(); m_icodes[1]->invalidate();
return 2; return 2;

View File

@ -39,11 +39,11 @@ bool Idiom21::match (iICODE picode)
} }
int Idiom21::action() int Idiom21::action()
{ {
COND_EXPR *rhs; Expr *rhs;
AstIdent *lhs; AstIdent *lhs;
lhs = AstIdent::idLong (&m_func->localId, DST, m_icodes[0],HIGH_FIRST, m_icodes[0], eDEF, *m_icodes[1]->ll()); lhs = AstIdent::Long (&m_func->localId, DST, m_icodes[0],HIGH_FIRST, m_icodes[0], eDEF, *m_icodes[1]->ll());
rhs = AstIdent::Kte (m_icodes[1]->ll()->src().getImm2() , 4); rhs = new Constant(m_icodes[1]->ll()->src().getImm2(), 4);
m_icodes[0]->setAsgn(lhs, rhs); m_icodes[0]->setAsgn(lhs, rhs);
m_icodes[0]->du.use = 0; /* clear register used in iXOR */ m_icodes[0]->du.use = 0; /* clear register used in iXOR */
m_icodes[1]->invalidate(); m_icodes[1]->invalidate();
@ -84,11 +84,9 @@ bool Idiom7::match(iICODE picode)
} }
int Idiom7::action() int Idiom7::action()
{ {
COND_EXPR *lhs; Expr *lhs;
COND_EXPR *rhs;
lhs = AstIdent::id (*m_icode->ll(), DST, m_func, m_icode, *m_icode, NONE); lhs = AstIdent::id (*m_icode->ll(), DST, m_func, m_icode, *m_icode, NONE);
rhs = AstIdent::Kte (0, 2); m_icode->setAsgn(dynamic_cast<AstIdent *>(lhs), new Constant(0, 2));
m_icode->setAsgn(dynamic_cast<AstIdent *>(lhs), rhs);
m_icode->du.use = 0; /* clear register used in iXOR */ m_icode->du.use = 0; /* clear register used in iXOR */
m_icode->ll()->setFlags(I); m_icode->ll()->setFlags(I);
return 1; return 1;

View File

@ -341,13 +341,13 @@ boolT checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pPro
if ( not pIcode->ll()->testFlags(NO_SRC) ) if ( not pIcode->ll()->testFlags(NO_SRC) )
{ {
asgn.rhs = AstIdent::idLong (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, atOffset); asgn.rhs = AstIdent::Long (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, atOffset);
} }
return true; return true;
} }
else if ((longId.offH == pmHsrc->off) && (longId.offL == pmLsrc->off)) else if ((longId.offH == pmHsrc->off) && (longId.offL == pmLsrc->off))
{ {
asgn.lhs = AstIdent::idLong (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode,eDEF, atOffset); asgn.lhs = AstIdent::Long (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode,eDEF, atOffset);
asgn.rhs = AstIdent::LongIdx (i); asgn.rhs = AstIdent::LongIdx (i);
return true; return true;
} }
@ -380,13 +380,13 @@ boolT checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, int i,
asgn.lhs = AstIdent::LongIdx (i); asgn.lhs = AstIdent::LongIdx (i);
if ( not pIcode->ll()->testFlags(NO_SRC) ) if ( not pIcode->ll()->testFlags(NO_SRC) )
{ {
asgn.rhs = AstIdent::idLong (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, atOffset); asgn.rhs = AstIdent::Long (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, atOffset);
} }
return true; return true;
} }
else if ((longId.h == pmHsrc->regi) && (longId.l == pmLsrc->regi)) else if ((longId.h == pmHsrc->regi) && (longId.l == pmLsrc->regi))
{ {
asgn.lhs = AstIdent::idLong (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode, eDEF, atOffset); asgn.lhs = AstIdent::Long (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode, eDEF, atOffset);
asgn.rhs = AstIdent::LongIdx (i); asgn.rhs = AstIdent::LongIdx (i);
return true; return true;
} }

View File

@ -81,11 +81,11 @@ void DccFrontend::parse(Project &proj)
/* Returns the size of the string pointed by sym and delimited by delim. /* Returns the size of the string pointed by sym and delimited by delim.
* Size includes delimiter. */ * Size includes delimiter. */
int strSize (uint8_t *sym, char delim) int strSize (const uint8_t *sym, char delim)
{ {
PROG &prog(Project::get()->prog); PROG &prog(Project::get()->prog);
int till_end = sym-prog.Image; int till_end = sym-prog.image();
uint8_t *end_ptr=std::find(sym,sym+(prog.cbImage-(till_end)),delim); const uint8_t *end_ptr=std::find(sym,sym+(prog.cbImage-(till_end)),delim);
return end_ptr-sym+1; return end_ptr-sym+1;
} }
Function *fakeproc=Function::Create(0,0,"fake"); Function *fakeproc=Function::Create(0,0,"fake");
@ -311,8 +311,8 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
operand = ((uint32_t)(uint16_t)pstate->r[rDS]<<4) + operand = ((uint32_t)(uint16_t)pstate->r[rDS]<<4) +
(uint32_t)(uint16_t)pstate->r[rDX]; (uint32_t)(uint16_t)pstate->r[rDX];
size = prog.fCOM ? size = prog.fCOM ?
strSize (&prog.Image[operand], '$') : strSize (&prog.image()[operand], '$') :
strSize (&prog.Image[operand], '$'); // + 0x100 strSize (&prog.image()[operand], '$'); // + 0x100
global_symbol_table.updateSymType (operand, TypeContainer(TYPE_STR, size)); global_symbol_table.updateSymType (operand, TypeContainer(TYPE_STR, size));
} }
} }
@ -355,9 +355,9 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
if ((psym = lookupAddr(&ll->src(), pstate, 4, eDuVal::USE)) if ((psym = lookupAddr(&ll->src(), pstate, 4, eDuVal::USE))
/* && (Icode.ll()->flg & SEG_IMMED) */ ) /* && (Icode.ll()->flg & SEG_IMMED) */ )
{ {
offset = LH(&prog.Image[psym->label]); offset = LH(&prog.image()[psym->label]);
pstate->setState( (ll->getOpcode() == iLDS)? rDS: rES, pstate->setState( (ll->getOpcode() == iLDS)? rDS: rES,
LH(&prog.Image[psym->label + 2])); LH(&prog.image()[psym->label + 2]));
pstate->setState( ll->dst.regi, (int16_t)offset); pstate->setState( ll->dst.regi, (int16_t)offset);
psym->type = TYPE_PTR; psym->type = TYPE_PTR;
} }
@ -370,7 +370,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
if (err == INVALID_386OP || err == INVALID_OPCODE) if (err == INVALID_386OP || err == INVALID_OPCODE)
{ {
fatalError(err, prog.Image[_Icode.ll()->label], _Icode.ll()->label); fatalError(err, prog.image()[_Icode.ll()->label], _Icode.ll()->label);
this->flg |= PROC_BADINST; this->flg |= PROC_BADINST;
} }
else if (err == IP_OUT_OF_RANGE) else if (err == IP_OUT_OF_RANGE)
@ -410,7 +410,7 @@ bool Function::followAllTableEntries(JumpTable &table, uint32_t cs, ICODE& pIcod
for (size_t i = table.start; i < table.finish; i += 2) for (size_t i = table.start; i < table.finish; i += 2)
{ {
StCopy = *pstate; StCopy = *pstate;
StCopy.IP = cs + LH(&prog.Image[i]); StCopy.IP = cs + LH(&prog.image()[i]);
iICODE last_current_insn = (++Icode.rbegin()).base(); iICODE last_current_insn = (++Icode.rbegin()).base();
FollowCtrl (pcallGraph, &StCopy); FollowCtrl (pcallGraph, &StCopy);
@ -434,7 +434,7 @@ bool Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGra
if (pIcode.ll()->testFlags(I)) if (pIcode.ll()->testFlags(I))
{ {
if (pIcode.ll()->getOpcode() == iJMPF) if (pIcode.ll()->getOpcode() == iJMPF)
pstate->setState( rCS, LH(prog.Image + pIcode.ll()->label + 3)); pstate->setState( rCS, LH(prog.image() + pIcode.ll()->label + 3));
pstate->IP = pIcode.ll()->src().getImm2(); pstate->IP = pIcode.ll()->src().getImm2();
int64_t i = pIcode.ll()->src().getImm2(); int64_t i = pIcode.ll()->src().getImm2();
if (i < 0) if (i < 0)
@ -483,7 +483,7 @@ bool Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGra
cs = (uint32_t)(uint16_t)pstate->r[rCS] << 4; cs = (uint32_t)(uint16_t)pstate->r[rCS] << 4;
for (i = offTable; i < endTable; i += 2) for (i = offTable; i < endTable; i += 2)
{ {
target = cs + LH(&prog.Image[i]); target = cs + LH(&prog.image()[i]);
if (target < endTable && target >= offTable) if (target < endTable && target >= offTable)
endTable = target; endTable = target;
else if (target >= (uint32_t)prog.cbImage) else if (target >= (uint32_t)prog.cbImage)
@ -492,9 +492,9 @@ bool Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGra
for (i = offTable; i < endTable; i += 2) for (i = offTable; i < endTable; i += 2)
{ {
target = cs + LH(&prog.Image[i]); target = cs + LH(&prog.image()[i]);
/* Be wary of 00 00 as code - it's probably data */ /* Be wary of 00 00 as code - it's probably data */
if (! (prog.Image[target] || prog.Image[target+1]) || if (! (prog.image()[target] || prog.image()[target+1]) ||
scan(target, _Icode)) scan(target, _Icode))
endTable = i; endTable = i;
} }
@ -516,7 +516,7 @@ bool Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGra
for (i = offTable, k = 0; i < endTable; i += 2) for (i = offTable, k = 0; i < endTable; i += 2)
{ {
StCopy = *pstate; StCopy = *pstate;
StCopy.IP = cs + LH(&prog.Image[i]); StCopy.IP = cs + LH(&prog.image()[i]);
iICODE last_current_insn = (++Icode.rbegin()).base(); iICODE last_current_insn = (++Icode.rbegin()).base();
//ip = Icode.size(); //ip = Icode.size();
@ -604,9 +604,9 @@ boolT Function::process_CALL (ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *ps
* previous offset into the program image */ * previous offset into the program image */
uint32_t tgtAddr=0; uint32_t tgtAddr=0;
if (pIcode.ll()->getOpcode() == iCALLF) if (pIcode.ll()->getOpcode() == iCALLF)
tgtAddr= LH(&prog.Image[off]) + ((uint32_t)(LH(&prog.Image[off+2])) << 4); tgtAddr= LH(&prog.image()[off]) + ((uint32_t)(LH(&prog.image()[off+2])) << 4);
else else
tgtAddr= LH(&prog.Image[off]) + ((uint32_t)(uint16_t)state.r[rCS] << 4); tgtAddr= LH(&prog.image()[off]) + ((uint32_t)(uint16_t)state.r[rCS] << 4);
pIcode.ll()->replaceSrc(LLOperand::CreateImm2( tgtAddr ) ); pIcode.ll()->replaceSrc(LLOperand::CreateImm2( tgtAddr ) );
pIcode.ll()->setFlags(I); pIcode.ll()->setFlags(I);
indirect = true; indirect = true;
@ -651,7 +651,7 @@ boolT Function::process_CALL (ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *ps
localState = *pstate; localState = *pstate;
pstate->IP = pIcode.ll()->src().getImm2(); pstate->IP = pIcode.ll()->src().getImm2();
if (pIcode.ll()->getOpcode() == iCALLF) if (pIcode.ll()->getOpcode() == iCALLF)
pstate->setState( rCS, LH(prog.Image + pIcode.ll()->label + 3)); pstate->setState( rCS, LH(prog.image() + pIcode.ll()->label + 3));
x.state = *pstate; x.state = *pstate;
/* Insert new procedure in call graph */ /* Insert new procedure in call graph */
@ -694,7 +694,7 @@ static void process_MOV(LLInst & ll, STATE * pstate)
{ {
psym = lookupAddr(&ll.src(), pstate, 2, eDuVal::USE); psym = lookupAddr(&ll.src(), pstate, 2, eDuVal::USE);
if (psym && ((psym->flg & SEG_IMMED) || psym->duVal.val)) if (psym && ((psym->flg & SEG_IMMED) || psym->duVal.val))
pstate->setState( dstReg, LH(&prog.Image[psym->label])); pstate->setState( dstReg, LH(&prog.image()[psym->label]));
} }
else if (srcReg < INDEX_BX_SI && pstate->f[srcReg]) /* reg */ else if (srcReg < INDEX_BX_SI && pstate->f[srcReg]) /* reg */
{ {
@ -714,9 +714,13 @@ static void process_MOV(LLInst & ll, STATE * pstate)
{ {
if (ll.testFlags(I)) /* immediate */ if (ll.testFlags(I)) /* immediate */
{ {
prog.Image[psym->label] = (uint8_t)ll.src().getImm2(); //prog.image()[psym->label] = (uint8_t)ll.src().getImm2();
pstate->setMemoryByte(psym->label,(uint8_t)ll.src().getImm2());
if(psym->size>1) if(psym->size>1)
prog.Image[psym->label+1] = (uint8_t)(ll.src().getImm2()>>8); {
pstate->setMemoryByte(psym->label+1,uint8_t(ll.src().getImm2()>>8));
//prog.image()[psym->label+1] = (uint8_t)(ll.src().getImm2()>>8);
}
psym->duVal.val = 1; psym->duVal.val = 1;
} }
else if (srcReg == 0) /* direct mem offset */ else if (srcReg == 0) /* direct mem offset */
@ -724,18 +728,26 @@ static void process_MOV(LLInst & ll, STATE * pstate)
psym2 = lookupAddr (&ll.src(), pstate, 2, eDuVal::USE); psym2 = lookupAddr (&ll.src(), pstate, 2, eDuVal::USE);
if (psym2 && ((psym->flg & SEG_IMMED) || (psym->duVal.val))) if (psym2 && ((psym->flg & SEG_IMMED) || (psym->duVal.val)))
{ {
prog.Image[psym->label] = (uint8_t)prog.Image[psym2->label]; //prog.image()[psym->label] = (uint8_t)prog.image()[psym2->label];
pstate->setMemoryByte(psym->label,(uint8_t)prog.image()[psym2->label]);
if(psym->size>1) if(psym->size>1)
prog.Image[psym->label+1] = prog.Image[psym2->label+1];//(uint8_t)(prog.Image[psym2->label+1] >> 8); {
pstate->setMemoryByte(psym->label+1,(uint8_t)prog.image()[psym2->label+1]);
//prog.image()[psym->label+1] = prog.image()[psym2->label+1];//(uint8_t)(prog.image()[psym2->label+1] >> 8);
}
psym->duVal.setFlags(eDuVal::DEF); psym->duVal.setFlags(eDuVal::DEF);
psym2->duVal.setFlags(eDuVal::USE); psym2->duVal.setFlags(eDuVal::USE);
} }
} }
else if (srcReg < INDEX_BX_SI && pstate->f[srcReg]) /* reg */ else if (srcReg < INDEX_BX_SI && pstate->f[srcReg]) /* reg */
{ {
prog.Image[psym->label] = (uint8_t)pstate->r[srcReg]; //prog.image()[psym->label] = (uint8_t)pstate->r[srcReg];
pstate->setMemoryByte(psym->label,(uint8_t)pstate->r[srcReg]);
if(psym->size>1) if(psym->size>1)
prog.Image[psym->label+1] = (uint8_t)(pstate->r[srcReg] >> 8); {
pstate->setMemoryByte(psym->label,(uint8_t)pstate->r[srcReg]>>8);
//prog.image()[psym->label+1] = (uint8_t)(pstate->r[srcReg] >> 8);
}
psym->duVal.setFlags(eDuVal::DEF); psym->duVal.setFlags(eDuVal::DEF);
} }
} }

View File

@ -94,7 +94,7 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
STKFRAME * call_args_stackframe, *target_stackframe; STKFRAME * call_args_stackframe, *target_stackframe;
const ID *id; const ID *id;
int tidx; int tidx;
boolT regExist; bool regExist=false;
condId type; condId type;
Function * tproc; Function * tproc;
eReg regL, regH; /* Registers involved in arguments */ eReg regL, regH; /* Registers involved in arguments */
@ -106,16 +106,29 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
/* Get registers and index into target procedure's local list */ /* Get registers and index into target procedure's local list */
call_args_stackframe = ticode->hl()->call.args; call_args_stackframe = ticode->hl()->call.args;
target_stackframe = &tproc->args; target_stackframe = &tproc->args;
lhs = dynamic_cast<AstIdent *>(picode->hl()->asgn.lhs); lhs = dynamic_cast<AstIdent *>(picode->hl()->asgn.lhs());
RegisterNode *lhs_reg = dynamic_cast<RegisterNode *>(lhs);
assert(lhs); assert(lhs);
type = lhs->ident.idType; type = lhs->ident.type();
if (type == REGISTER) if (lhs_reg)
{ {
regL = id_arr[lhs->ident.idNode.regiIdx].id.regi; regL = id_arr[lhs_reg->regiIdx].id.regi;
if (regL < rAL) if (regL < rAL)
tidx = tproc->localId.newByteWordReg(TYPE_WORD_SIGN, regL); tidx = tproc->localId.newByteWordReg(TYPE_WORD_SIGN, regL);
else else
tidx = tproc->localId.newByteWordReg(TYPE_BYTE_SIGN, regL); tidx = tproc->localId.newByteWordReg(TYPE_BYTE_SIGN, regL);
/* Check if register argument already on the formal argument list */
for(STKSYM &tgt_sym : *target_stackframe)
{
RegisterNode *tgt_sym_regs = dynamic_cast<RegisterNode *>(tgt_sym.regs);
if( tgt_sym_regs == NULL ) // both REGISTER and LONG_VAR require this precondition
continue;
if ( tgt_sym_regs->regiIdx == tidx )
{
regExist = true;
break;
}
}
} }
else if (type == LONG_VAR) else if (type == LONG_VAR)
{ {
@ -123,32 +136,20 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
regL = id_arr[longIdx].id.longId.l; regL = id_arr[longIdx].id.longId.l;
regH = id_arr[longIdx].id.longId.h; regH = id_arr[longIdx].id.longId.h;
tidx = tproc->localId.newLongReg(TYPE_LONG_SIGN, regH, regL, tproc->Icode.begin() /*0*/); tidx = tproc->localId.newLongReg(TYPE_LONG_SIGN, regH, regL, tproc->Icode.begin() /*0*/);
} /* Check if register argument already on the formal argument list */
for(STKSYM &tgt_sym : *target_stackframe)
/* Check if register argument already on the formal argument list */
regExist = false;
for(STKSYM &tgt_sym : *target_stackframe)
{
if( tgt_sym.regs == NULL ) // both REGISTER and LONG_VAR require this precondition
continue;
if (type == REGISTER)
{
if ( tgt_sym.regs->ident.idNode.regiIdx == tidx )
{
regExist = true;
}
}
else if (type == LONG_VAR)
{ {
if( tgt_sym.regs == NULL ) // both REGISTER and LONG_VAR require this precondition
continue;
if ( tgt_sym.regs->ident.idNode.longIdx == tidx ) if ( tgt_sym.regs->ident.idNode.longIdx == tidx )
{ {
regExist = true; regExist = true;
break;
} }
} }
if(regExist == true)
break;
} }
else
;//regExist = false;
/* Do ts (formal arguments) */ /* Do ts (formal arguments) */
if (regExist == false) if (regExist == false)
{ {
@ -161,12 +162,12 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
if (regL < rAL) if (regL < rAL)
{ {
newsym.type = TYPE_WORD_SIGN; newsym.type = TYPE_WORD_SIGN;
newsym.regs = AstIdent::RegIdx(tidx, WORD_REG); newsym.regs = new RegisterNode(tidx, WORD_REG);
} }
else else
{ {
newsym.type = TYPE_BYTE_SIGN; newsym.type = TYPE_BYTE_SIGN;
newsym.regs = AstIdent::RegIdx(tidx, BYTE_REG); newsym.regs = new RegisterNode(tidx, BYTE_REG);
} }
tproc->localId.id_arr[tidx].name = newsym.name; tproc->localId.id_arr[tidx].name = newsym.name;
} }
@ -189,7 +190,7 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
/* Mask off high and low register(s) in picode */ /* Mask off high and low register(s) in picode */
switch (type) { switch (type) {
case REGISTER: case REGISTER:
id = &id_arr[lhs->ident.idNode.regiIdx]; id = &id_arr[lhs_reg->regiIdx];
picode->du.def &= maskDuReg[id->id.regi]; picode->du.def &= maskDuReg[id->id.regi];
if (id->id.regi < rAL) if (id->id.regi < rAL)
newsym.type = TYPE_WORD_SIGN; newsym.type = TYPE_WORD_SIGN;
@ -215,9 +216,9 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
* @return true if it was a near call that made use of a segment register. * @return true if it was a near call that made use of a segment register.
* false elsewhere * false elsewhere
*/ */
bool CallType::newStkArg(COND_EXPR *exp, llIcode opcode, Function * pproc) bool CallType::newStkArg(Expr *exp, llIcode opcode, Function * pproc)
{ {
AstIdent *expr = dynamic_cast<AstIdent *>(exp); RegisterNode *expr = dynamic_cast<RegisterNode *>(exp);
uint8_t regi; uint8_t regi;
/* Check for far procedure call, in which case, references to segment /* Check for far procedure call, in which case, references to segment
@ -225,16 +226,13 @@ bool CallType::newStkArg(COND_EXPR *exp, llIcode opcode, Function * pproc)
* long references to another segment) */ * long references to another segment) */
if (expr) if (expr)
{ {
if (expr->ident.idType == REGISTER) regi = pproc->localId.id_arr[expr->regiIdx].id.regi;
if ((regi >= rES) && (regi <= rDS))
{ {
regi = pproc->localId.id_arr[expr->ident.idNode.regiIdx].id.regi; if (opcode == iCALLF)
if ((regi >= rES) && (regi <= rDS)) return false;
{ else
if (opcode == iCALLF) return true;
return false;
else
return true;
}
} }
} }
@ -249,22 +247,22 @@ bool CallType::newStkArg(COND_EXPR *exp, llIcode opcode, Function * pproc)
/* Places the actual argument exp in the position given by pos in the /* Places the actual argument exp in the position given by pos in the
* argument list of picode. */ * argument list of picode. */
void CallType::placeStkArg (COND_EXPR *exp, int pos) void CallType::placeStkArg (Expr *exp, int pos)
{ {
(*args)[pos].actual = exp; (*args)[pos].actual = exp;
(*args)[pos].setArgName(pos); (*args)[pos].setArgName(pos);
} }
COND_EXPR *CallType::toId() Expr *CallType::toAst()
{ {
return AstIdent::idFunc( proc, args); return new FuncNode( proc, args);
} }
/* Checks to determine whether the expression (actual argument) has the /* Checks to determine whether the expression (actual argument) has the
* same type as the given type (from the procedure's formal list). If not, * same type as the given type (from the procedure's formal list). If not,
* the actual argument gets modified */ * the actual argument gets modified */
void adjustActArgType (COND_EXPR *_exp, hlType forType, Function * pproc) Expr *Function::adjustActArgType (Expr *_exp, hlType forType)
{ {
AstIdent *expr = dynamic_cast<AstIdent *>(_exp); AstIdent *expr = dynamic_cast<AstIdent *>(_exp);
PROG &prog(Project::get()->prog); PROG &prog(Project::get()->prog);
@ -272,11 +270,11 @@ void adjustActArgType (COND_EXPR *_exp, hlType forType, Function * pproc)
int offset, offL; int offset, offL;
if (expr == NULL) if (expr == NULL)
return; return _exp;
actType = expr-> expType (pproc); actType = expr-> expType (this);
if (actType == forType) if (actType == forType)
return; return _exp;
switch (forType) switch (forType)
{ {
case TYPE_UNKNOWN: case TYPE_BYTE_SIGN: case TYPE_UNKNOWN: case TYPE_BYTE_SIGN:
@ -292,16 +290,20 @@ void adjustActArgType (COND_EXPR *_exp, hlType forType, Function * pproc)
case TYPE_STR: case TYPE_STR:
switch (actType) { switch (actType) {
case TYPE_CONST: case TYPE_CONST:
/* It's an offset into image where a string is /* It's an offset into image where a string is found. Point to the string. */
* found. Point to the string. */ {
offL = expr->ident.idNode.kte.kte; Constant *c=dynamic_cast<Constant *>(expr);
assert(c);
offL = c->kte.kte;
if (prog.fCOM) if (prog.fCOM)
offset = (pproc->state.r[rDS]<<4) + offL + 0x100; offset = (state.r[rDS]<<4) + offL + 0x100;
else else
offset = (pproc->state.r[rDS]<<4) + offL; offset = (state.r[rDS]<<4) + offL;
expr->ident.idNode.strIdx = offset; expr->ident.idNode.strIdx = offset;
expr->ident.idType = STRING; expr->ident.type(STRING);
break; delete c;
return AstIdent::String(offset);
}
case TYPE_PTR: case TYPE_PTR:
/* It's a pointer to a char rather than a pointer to /* It's a pointer to a char rather than a pointer to
@ -319,6 +321,7 @@ void adjustActArgType (COND_EXPR *_exp, hlType forType, Function * pproc)
default: default:
fprintf(stderr,"adjustForArgType unhandled forType %d \n",forType); fprintf(stderr,"adjustForArgType unhandled forType %d \n",forType);
} }
return _exp;
} }

View File

@ -336,7 +336,7 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be
localId.id_arr[loc_ident_idx].idx.push_back(pIcode);//idx-1//insert localId.id_arr[loc_ident_idx].idx.push_back(pIcode);//idx-1//insert
icode.setRegDU( pmL->regi, eDEF); icode.setRegDU( pmL->regi, eDEF);
asgn.lhs = AstIdent::LongIdx (loc_ident_idx); asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
asgn.rhs = AstIdent::idLong (&this->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, *next1->ll()); asgn.rhs = AstIdent::Long (&this->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, *next1->ll());
icode.setAsgn(asgn.lhs, asgn.rhs); icode.setAsgn(asgn.lhs, asgn.rhs);
next1->invalidate(); next1->invalidate();
forced_finish=true; /* to exit the loop */ forced_finish=true; /* to exit the loop */
@ -365,7 +365,7 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be
if ((pLocId.id.longId.h == pmH->regi) && (pLocId.id.longId.l == pmL->regi)) if ((pLocId.id.longId.h == pmH->regi) && (pLocId.id.longId.l == pmL->regi))
{ {
asgn.lhs = AstIdent::LongIdx (loc_ident_idx); asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
asgn.rhs = AstIdent::idLong (&this->localId, SRC, pIcode, LOW_FIRST, pIcode, eUSE, *next1->ll()); asgn.rhs = AstIdent::Long (&this->localId, SRC, pIcode, LOW_FIRST, pIcode, eUSE, *next1->ll());
icode.setRegDU( pmH->regi, USE_DEF); icode.setRegDU( pmH->regi, USE_DEF);
condOp toCreate=DUMMY; condOp toCreate=DUMMY;
switch (icode.ll()->getOpcode()) switch (icode.ll()->getOpcode())
@ -411,13 +411,13 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
const LLOperand &src_op1(pIcode->ll()->src()); const LLOperand &src_op1(pIcode->ll()->src());
const LLOperand &src_op2(next1->ll()->src()); const LLOperand &src_op2(next1->ll()->src());
eReg srcReg1=src_op1.getReg2(); eReg srcReg1=src_op1.getReg2();
eReg srcReg2=src_op2.getReg2(); eReg nextReg2=src_op2.getReg2();
if ((ref_long.h == srcReg1) && (ref_long.l == srcReg2)) if ((ref_long.h == srcReg1) && (ref_long.l == nextReg2))
{ {
pIcode->setRegDU( next1->ll()->src().getReg2(), eUSE); pIcode->setRegDU( nextReg2, eUSE);
asgn.rhs = AstIdent::LongIdx (loc_ident_idx); asgn.rhs = AstIdent::LongIdx (loc_ident_idx);
asgn.lhs = AstIdent::idLong (&this->localId, DST, pIcode,HIGH_FIRST, pIcode, eDEF, *next1->ll()); asgn.lhs = AstIdent::Long (&this->localId, DST, pIcode,HIGH_FIRST, pIcode, eDEF, *next1->ll());
pIcode->setAsgn(dynamic_cast<AstIdent *>(asgn.lhs), asgn.rhs); pIcode->setAsgn(dynamic_cast<AstIdent *>(asgn.lhs), asgn.rhs);
next1->invalidate(); next1->invalidate();
@ -453,7 +453,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
{ {
asgn.lhs = AstIdent::LongIdx (loc_ident_idx); asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
pIcode->setRegDU( pmH->regi, USE_DEF); pIcode->setRegDU( pmH->regi, USE_DEF);
asgn.rhs = AstIdent::idLong (&this->localId, SRC, pIcode, asgn.rhs = AstIdent::Long (&this->localId, SRC, pIcode,
LOW_FIRST, pIcode, eUSE, *next1->ll()); LOW_FIRST, pIcode, eUSE, *next1->ll());
condOp toCreate=DUMMY; condOp toCreate=DUMMY;
switch (pIcode->ll()->getOpcode()) { switch (pIcode->ll()->getOpcode()) {
@ -505,7 +505,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
if (pLocId.id.longId.srcDstRegMatch(pIcode,pIcode)) if (pLocId.id.longId.srcDstRegMatch(pIcode,pIcode))
{ {
asgn.lhs = AstIdent::LongIdx (loc_ident_idx); asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
asgn.rhs = AstIdent::Kte (0, 4); /* long 0 */ asgn.rhs = new Constant(0, 4); /* long 0 */
asgn.lhs = new BinaryOperator(condOpJCond[next1->ll()->getOpcode() - iJB],asgn.lhs, asgn.rhs); asgn.lhs = new BinaryOperator(condOpJCond[next1->ll()->getOpcode() - iJB],asgn.lhs, asgn.rhs);
next1->setJCond(asgn.lhs); next1->setJCond(asgn.lhs);
next1->copyDU(*pIcode, eUSE, eUSE); next1->copyDU(*pIcode, eUSE, eUSE);

View File

@ -314,14 +314,29 @@ static struct {
} ; } ;
static uint16_t SegPrefix, RepPrefix; static uint16_t SegPrefix, RepPrefix;
static uint8_t *pInst; /* Ptr. to current uint8_t of instruction */ static const uint8_t *pInst; /* Ptr. to current uint8_t of instruction */
static ICODE * pIcode; /* Ptr to Icode record filled in by scan() */ static ICODE * pIcode; /* Ptr to Icode record filled in by scan() */
/***************************************************************************** static void decodeBranchTgt(x86_insn_t &insn)
Scans one machine instruction at offset ip in prog.Image and returns error. {
At the same time, fill in low-level icode details for the scanned inst. x86_op_t *tgt_op = insn.x86_get_branch_target();
****************************************************************************/ if(tgt_op->type==op_expression)
return; // unhandled for now
if(tgt_op->type==op_register)
return; // unhandled for now
int32_t addr = tgt_op->getAddress();
if(tgt_op->is_relative())
{
addr += insn.addr+insn.size;
}
pIcode->ll()->replaceSrc((uint32_t)addr);
pIcode->ll()->setFlags(I);
// PROG &prog(Project::get()->prog);
// long off = (short)getWord(); /* Signed displacement */
// assert(addr==(uint32_t)(off + (unsigned)(pInst - prog.image())));
}
static void convertUsedFlags(x86_insn_t &from,ICODE &to) static void convertUsedFlags(x86_insn_t &from,ICODE &to)
{ {
@ -345,6 +360,13 @@ static void convertUsedFlags(x86_insn_t &from,ICODE &to)
if(from.containsFlag(insn_eflag_direction,from.flags_tested)) if(from.containsFlag(insn_eflag_direction,from.flags_tested))
to.ll()->flagDU.u |= Df; to.ll()->flagDU.u |= Df;
} }
static void convertPrefix(x86_insn_prefix prefix,ICODE &to)
{
if(prefix ==insn_no_prefix)
return;
// insn_lock - no need to handle
RepPrefix = (uint16_t)prefix & ~insn_lock;
}
/**************************************************************************** /****************************************************************************
Checks for int 34 to int 3B - if so, converts to ESC nn instruction Checks for int 34 to int 3B - if so, converts to ESC nn instruction
****************************************************************************/ ****************************************************************************/
@ -362,7 +384,7 @@ static void fixFloatEmulation(x86_insn_t &insn)
/* This is a Borland/Microsoft floating point emulation instruction. Treat as if it is an ESC opcode */ /* This is a Borland/Microsoft floating point emulation instruction. Treat as if it is an ESC opcode */
int actual_valid_bytes=std::min(16U,prog.cbImage-insn.offset); int actual_valid_bytes=std::min(16U,prog.cbImage-insn.offset);
memcpy(buf,prog.Image+insn.offset,actual_valid_bytes); memcpy(buf,prog.image()+insn.offset,actual_valid_bytes);
X86_Disasm ds(opt_16_bit); X86_Disasm ds(opt_16_bit);
x86_insn_t patched_insn; x86_insn_t patched_insn;
//patch actual instruction into buffer; //patch actual instruction into buffer;
@ -378,7 +400,7 @@ int disassembleOneLibDisasm(uint32_t ip,x86_insn_t &l)
{ {
PROG &prog(Project::get()->prog); PROG &prog(Project::get()->prog);
X86_Disasm ds(opt_16_bit); X86_Disasm ds(opt_16_bit);
int cnt=ds.x86_disasm(prog.Image,prog.cbImage,0,ip,&l); int cnt=ds.x86_disasm(prog.image(),prog.cbImage,0,ip,&l);
if(cnt && l.is_valid()) if(cnt && l.is_valid())
{ {
fixFloatEmulation(l); //can change 'l' fixFloatEmulation(l); //can change 'l'
@ -416,6 +438,11 @@ LLOperand convertOperand(const x86_op_t &from)
} }
return LLOperand::CreateImm2(0); return LLOperand::CreateImm2(0);
} }
/*****************************************************************************
Scans one machine instruction at offset ip in prog.Image and returns error.
At the same time, fill in low-level icode details for the scanned inst.
****************************************************************************/
eErrorId scan(uint32_t ip, ICODE &p) eErrorId scan(uint32_t ip, ICODE &p)
{ {
PROG &prog(Project::get()->prog); PROG &prog(Project::get()->prog);
@ -431,10 +458,12 @@ eErrorId scan(uint32_t ip, ICODE &p)
if(cnt) if(cnt)
{ {
convertUsedFlags(p.insn,p); convertUsedFlags(p.insn,p);
convertPrefix(p.insn.prefix,p);
} }
SegPrefix = RepPrefix = 0; SegPrefix = RepPrefix = 0;
pInst = prog.Image + ip; pInst = prog.image() + ip;
pIcode = &p; pIcode = &p;
do do
@ -446,12 +475,20 @@ eErrorId scan(uint32_t ip, ICODE &p)
(*stateTable[op].state2)(op); /* Third state */ (*stateTable[op].state2)(op); /* Third state */
} while (stateTable[op].state1 == prefix); /* Loop if prefix */ } while (stateTable[op].state1 == prefix); /* Loop if prefix */
if(p.insn.group == x86_insn_t::insn_controlflow)
{
if(p.insn.x86_get_branch_target())
decodeBranchTgt(p.insn);
}
// LLOperand conv = convertOperand(*p.insn.get_dest());
// assert(conv==p.ll()->dst);
if (p.ll()->getOpcode()) if (p.ll()->getOpcode())
{ {
/* Save bytes of image used */ /* Save bytes of image used */
p.ll()->numBytes = (uint8_t)((pInst - prog.Image) - ip); p.ll()->numBytes = (uint8_t)((pInst - prog.image()) - ip);
if(p.insn.is_valid()) if(p.insn.is_valid())
assert(p.ll()->numBytes == p.insn.size); assert(p.ll()->numBytes == p.insn.size);
p.ll()->numBytes = p.insn.size;
return ((SegPrefix)? FUNNY_SEGOVR: /* Seg. Override invalid */ return ((SegPrefix)? FUNNY_SEGOVR: /* Seg. Override invalid */
(RepPrefix ? FUNNY_REP: NO_ERR));/* REP prefix invalid */ (RepPrefix ? FUNNY_REP: NO_ERR));/* REP prefix invalid */
} }
@ -462,11 +499,11 @@ eErrorId scan(uint32_t ip, ICODE &p)
/*************************************************************************** /***************************************************************************
relocItem - returns true if uint16_t pointed at is in relocation table relocItem - returns true if uint16_t pointed at is in relocation table
**************************************************************************/ **************************************************************************/
static bool relocItem(uint8_t *p) static bool relocItem(const uint8_t *p)
{ {
PROG &prog(Project::get()->prog); PROG &prog(Project::get()->prog);
int i; int i;
uint32_t off = p - prog.Image; uint32_t off = p - prog.image();
for (i = 0; i < prog.cReloc; i++) for (i = 0; i < prog.cReloc; i++)
if (prog.relocTable[i] == off) if (prog.relocTable[i] == off)
@ -501,13 +538,13 @@ static int signex(uint8_t b)
* Note: fdst == true is for the r/m part of the field (dest, unless TO_REG) * Note: fdst == true is for the r/m part of the field (dest, unless TO_REG)
* fdst == false is for reg part of the field * fdst == false is for reg part of the field
***************************************************************************/ ***************************************************************************/
static void setAddress(int i, boolT fdst, uint16_t seg, int16_t reg, uint16_t off) static void setAddress(int i, bool fdst, uint16_t seg, int16_t reg, uint16_t off)
{ {
LLOperand *pm; LLOperand *pm;
/* If not to register (i.e. to r/m), and talking about r/m, then this is dest */ /* If not to register (i.e. to r/m), and talking about r/m, then this is dest */
pm = (!(stateTable[i].flg & TO_REG) == fdst) ? pm = (!(stateTable[i].flg & TO_REG) == fdst) ?
&pIcode->ll()->dst : &pIcode->ll()->src(); &pIcode->ll()->dst : &pIcode->ll()->src();
/* Set segment. A later procedure (lookupAddr in proclist.c) will /* Set segment. A later procedure (lookupAddr in proclist.c) will
* provide the value of this segment in the field segValue. */ * provide the value of this segment in the field segValue. */
@ -572,7 +609,7 @@ static void rm(int i)
setAddress(i, true, 0, rm + rAX, 0); setAddress(i, true, 0, rm + rAX, 0);
break; break;
} }
//pIcode->insn.get_dest()->
if ((stateTable[i].flg & NSP) && (pIcode->ll()->src().getReg2()==rSP || if ((stateTable[i].flg & NSP) && (pIcode->ll()->src().getReg2()==rSP ||
pIcode->ll()->dst.getReg2()==rSP)) pIcode->ll()->dst.getReg2()==rSP))
pIcode->ll()->setFlags(NOT_HLL); pIcode->ll()->setFlags(NOT_HLL);
@ -739,7 +776,7 @@ static void arith(int i)
uint8_t opcode; uint8_t opcode;
static llIcode arithTable[8] = static llIcode arithTable[8] =
{ {
iTEST , (llIcode)0, iNOT, iNEG, iTEST, (llIcode)0, iNOT, iNEG,
iMUL , iIMUL, iDIV, iIDIV iMUL , iIMUL, iDIV, iIDIV
}; };
opcode = arithTable[REG(*pInst)]; opcode = arithTable[REG(*pInst)];
@ -810,47 +847,40 @@ static void dispM(int i)
{ {
setAddress(i, false, SegPrefix, 0, getWord()); setAddress(i, false, SegPrefix, 0, getWord());
} }
/**************************************************************************** /****************************************************************************
dispN - 2 uint8_t disp as immed relative to ip dispN - 2 uint8_t disp as immed relative to ip
****************************************************************************/ ****************************************************************************/
static void dispN(int ) static void dispN(int )
{ {
PROG &prog(Project::get()->prog); //PROG &prog(Project::get()->prog);
long off = (short)getWord(); /* Signed displacement */ /*long off = (short)*/getWord(); /* Signed displacement */
/* Note: the result of the subtraction could be between 32k and 64k, and /* Note: the result of the subtraction could be between 32k and 64k, and
still be positive; it is an offset from prog.Image. So this must be still be positive; it is an offset from prog.Image. So this must be
treated as unsigned */ treated as unsigned */
pIcode->ll()->replaceSrc((uint32_t)(off + (unsigned)(pInst - prog.Image))); // decodeBranchTgt();
pIcode->ll()->setFlags(I);
} }
/*************************************************************************** /***************************************************************************
dispS - 1 uint8_t disp as immed relative to ip dispS - 1 byte disp as immed relative to ip
***************************************************************************/ ***************************************************************************/
static void dispS(int ) static void dispS(int )
{ {
PROG &prog(Project::get()->prog); /*long off =*/ signex(*pInst++); /* Signed displacement */
long off = signex(*pInst++); /* Signed displacement */
pIcode->ll()->replaceSrc((uint32_t)(off + (unsigned)(pInst - prog.Image))); // decodeBranchTgt();
pIcode->ll()->setFlags(I);
} }
/**************************************************************************** /****************************************************************************
dispF - 4 uint8_t disp as immed 20-bit target address dispF - 4 byte disp as immed 20-bit target address
***************************************************************************/ ***************************************************************************/
static void dispF(int ) static void dispF(int )
{ {
uint32_t off = (unsigned)getWord(); /*off = */(unsigned)getWord();
uint32_t seg = (unsigned)getWord(); /*seg = */(unsigned)getWord();
// decodeBranchTgt();
pIcode->ll()->replaceSrc(off + ((uint32_t)(unsigned)seg << 4));
pIcode->ll()->setFlags(I);
} }
@ -880,12 +910,19 @@ static void strop(int )
{ {
if (RepPrefix) if (RepPrefix)
{ {
// pIcode->ll()->getOpcode() += ((pIcode->ll()->getOpcode() == iCMPS || if ( pIcode->ll()->match(iCMPS) || pIcode->ll()->match(iSCAS) )
// pIcode->ll()->getOpcode() == iSCAS) {
// && RepPrefix == iREPE)? 2: 1; if(pIcode->insn.prefix & insn_rep_zero)
if ((pIcode->ll()->match(iCMPS) || pIcode->ll()->match(iSCAS) ) && RepPrefix == iREPE) {
BumpOpcode(*pIcode->ll()); // += 2 BumpOpcode(*pIcode->ll()); // iCMPS -> iREPE_CMPS
BumpOpcode(*pIcode->ll()); // else += 1 BumpOpcode(*pIcode->ll());
}
else if(pIcode->insn.prefix & insn_rep_notzero)
BumpOpcode(*pIcode->ll()); // iX -> iREPNE_X
}
else
if(pIcode->insn.prefix & insn_rep_zero)
BumpOpcode(*pIcode->ll()); // iX -> iREPE_X
if (pIcode->ll()->match(iREP_LODS) ) if (pIcode->ll()->match(iREP_LODS) )
pIcode->ll()->setFlags(NOT_HLL); pIcode->ll()->setFlags(NOT_HLL);
RepPrefix = 0; RepPrefix = 0;

View File

@ -13,16 +13,15 @@ int proc_2 (long arg0, long arg1)
*/ */
{ {
char loc1; /* al */ char loc1; /* al */
int loc2; /* al */ int loc2; /* bx */
int loc3; /* bx */
do { do {
arg0 = (arg0 + 1); arg0 = (arg0 + 1);
loc1 = es[bx]; loc1 = es[bx];
arg1 = (arg1 + 1); arg1 = (arg1 + 1);
es[bx] = loc1; es[bx] = loc1;
} while ((loc2 != 0)); } while ((loc1 != 0));
return (loc3); return (loc2);
} }
@ -35,7 +34,6 @@ int proc_3 (long arg0, long arg1)
int loc1; /* ax */ int loc1; /* ax */
while ((es[bx] == es[bx])) { while ((es[bx] == es[bx])) {
if (es[bx] == 0) { if (es[bx] == 0) {
loc1 = 0; loc1 = 0;
return (loc1); return (loc1);
@ -57,9 +55,9 @@ int proc_1 (int arg0, int arg1, int arg2, int arg3)
{ {
int loc1; /* si */ int loc1; /* si */
int loc2; /* di */ int loc2; /* di */
loc1 = 0; loc1 = 0;
loc2 = 0; loc2 = 0;
while ((loc1 < 0x2328)) { while ((loc1 < 0x2328)) {
proc_2 (arg1, arg0, 311); proc_2 (arg1, arg0, 311);
proc_2 (arg3, arg2, 328); proc_2 (arg3, arg2, 328);
@ -79,13 +77,12 @@ int loc1;
int loc2; int loc2;
int loc3; int loc3;
int loc4; int loc4;
loc3 = 0;
loc3 = 0;
while ((loc3 < 0x3e8)) { while ((loc3 < 0x3e8)) {
loc1 = 0; loc1 = 0;
loc4 = 0; loc4 = 0;
loc2 = 1; loc2 = 1;
while ((loc4 < 179)) { while ((loc4 < 179)) {
loc1 = (loc1 + loc2); loc1 = (loc1 + loc2);
loc2 = (loc2 + 2); loc2 = (loc2 + 2);
@ -105,8 +102,8 @@ int proc_5 (int arg0)
{ {
int loc1; /* si */ int loc1; /* si */
int loc2; /* ax */ int loc2; /* ax */
loc1 = arg0;
loc1 = arg0;
if (loc1 > 2) { if (loc1 > 2) {
loc2 = (proc_5 ((loc1 - 1)) + proc_5 ((loc1 + 0xfffe))); loc2 = (proc_5 ((loc1 - 1)) + proc_5 ((loc1 + 0xfffe)));
} }
@ -179,7 +176,7 @@ void proc_8 (int arg0)
} }
proc_7 (int arg0, int arg1, int arg2, int arg3) void proc_7 (int arg0, int arg1, int arg2, int arg3)
/* Takes 8 bytes of parameters. /* Takes 8 bytes of parameters.
* High-level language prologue code. * High-level language prologue code.
* Untranslatable routine. Assembler provided. * Untranslatable routine. Assembler provided.
@ -245,7 +242,7 @@ void proc_8 (int arg0)
} }
proc_9 (int arg0) void proc_9 (int arg0)
/* Takes 8 bytes of parameters. /* Takes 8 bytes of parameters.
* High-level language prologue code. * High-level language prologue code.
* C calling convention. * C calling convention.
@ -256,106 +253,62 @@ void proc_8 (int arg0)
int loc1; int loc1;
int loc2; int loc2;
int loc3; /* ax */ int loc3; /* ax */
loc2 = 100; loc2 = 100;
loc3 = loc2; loc3 = loc2;
loc2 = (loc2 - 1); loc2 = (loc2 - 1);
while (((loc3 | loc3) != 0)) { while (((loc3 | loc3) != 0)) {
loc3 = loc2; loc3 = loc2;
loc2 = (loc2 - 1); loc2 = (loc2 - 1);
} /* end of while */ } /* end of while */
return (var06278);
} }
int proc_10 () int proc_10 ()
/* Takes no parameters. /* Takes no parameters.
* High-level language prologue code. * High-level language prologue code.
* Untranslatable routine. Assembler provided.
* Return value in register ax.
* Contains instructions not normally used by compilers. * Contains instructions not normally used by compilers.
*/ */
{ {
PUSH bp int loc1;
MOV bp, sp int loc2;
SUB sp, 68h int loc3;
PUSH si int loc4;
PUSH di int loc5;
PUSH ds int loc6; /* bx */
MOV ax, 159h int loc7; /* dx */
PUSH ax int loc8; /* ax */
PUSH ss loc6 = proc_2 (&loc1, 345, , );
LEA ax, [bp-64h] fopen ("zyxw.vut", 368);
PUSH ax loc2 = loc7;
PUSH cs loc3 = loc8;
CALL near ptr proc_2
ADD sp, 8
PUSH ds
MOV ax, 170h
PUSH ax
PUSH ds
MOV ax, 167h
PUSH ax
CALL far ptr fopen
ADD sp, 8
MOV [bp-66h], dx
MOV [bp-68h], ax
OR dx, ax
JNE L1
PUSH ds
MOV ax, 172h
PUSH ax
CALL far ptr printf
POP cx
POP cx
MOV ax, 0FFFFh
PUSH ax
CALL far ptr exit
POP cx
L1: XOR di, 0 if ((loc7 | loc8) == 0) {
printf ("Cannot open file");
exit (0xffff);
}
l1:
if (++loc5 >= 0x3e8) {
fclose (loc3, loc2);
return (loc5);
}
else {
loc4 = 0;
L2: INC di while ((ss[bp+si-0x64] != 0)) {
MOV ax, di
CMP ax, 3E8h
JL L3
PUSH word ptr [bp-66h]
PUSH word ptr [bp-68h]
CALL far ptr fclose
POP cx
POP cx
MOV ax, di
POP di
POP si
MOV sp, bp
POP bp
RETF
L3: XOR si, 0 if (++es[bx] < 0) {
es[bx+0xc] = (es[bx+0xc] + 1);
L4: CMP byte ptr ss:[bp+si-64h], 0 loc6 = (loc6 - 1);
JNE L5 es[bx] = ss[bp+si-0x64];
}
L5: LES bx, dword ptr[bp-68h] else {
INC word ptr es:[bx] _fputc (ss[bp+si-0x64], loc3, loc2);
JGE L6 }
MOV al, ss:[bp+si-64h] loc4 = (loc4 + 1);
LES bx, dword ptr[bp-68h] } /* end of while */
INC word ptr es:[bx+0Ch] goto L1;
LES bx, dword ptres:[bx+0Ch] }
DEC bx
MOV es:[bx], al
MOV ah, 0
L7: INC si
JMP L4 ;Synthetic inst
L6: PUSH word ptr [bp-66h]
PUSH word ptr [bp-68h]
PUSH word ptr ss:[bp+si-64h]
CALL far ptr _fputc
ADD sp, 6
JMP L7 ;Synthetic inst
} }
@ -379,11 +332,11 @@ int loc10;
int loc11; int loc11;
int loc12; /* ax */ int loc12; /* ax */
int loc13; /* bx */ int loc13; /* bx */
printf ("Start...%c\n\n", 7);
loc11 = 0;
printf ("Start...%c\n\n", 7);
while ((loc11 < 6)) { while ((loc11 < 6)) {
loc12 = loc11; loc12 = loc11;
if (loc12 <= 5) { if (loc12 <= 5) {
loc13 = (loc12 << 1); loc13 = (loc12 << 1);
var06278 = proc_1 (&loc2, &loc1, , ); var06278 = proc_1 (&loc2, &loc1, , );

View File

@ -15,30 +15,32 @@ long LXMUL@ (long arg0, long arg1)
{ {
int loc1; int loc1;
int loc2; /* tmp */ int loc2; /* tmp */
loc2 = LO(arg0); loc2 = LO(arg0);
LO(arg0) = loc1; LO(arg0) = loc1;
loc1 = loc2; loc1 = loc2;
loc2 = LO(arg0); loc2 = LO(arg0);
LO(arg0) = HI(arg0); LO(arg0) = HI(arg0);
if ((LO(arg0) & LO(arg0)) != 0) { if ((LO(arg0) & LO(arg0)) != 0) {
LO(arg0) = (LO(arg0) * LO(arg1));
} }
loc2 = LO(arg0); loc2 = LO(arg0);
LO(arg0) = HI(arg1); LO(arg0) = HI(arg1);
HI(arg1) = loc2; HI(arg1) = loc2;
if ((LO(arg0) & LO(arg0)) != 0) { if ((LO(arg0) & LO(arg0)) != 0) {
LO(arg0) = (LO(arg0) * loc1); LO(arg0) = (LO(arg0) * loc1);
HI(arg1) = (HI(arg1) + LO(arg0)); HI(arg1) = (HI(arg1) + LO(arg0));
} }
loc2 = LO(arg0); loc2 = LO(arg0);
arg0 = (loc1 * LO(arg1)); LO(arg0) = loc1;
loc1 = loc2;
arg0 = (LO(arg0) * LO(arg1));
HI(arg0) = (HI(arg0) + HI(arg1)); HI(arg0) = (HI(arg0) + HI(arg1));
return (arg0); return (arg0);
} }
long LDIV@ (long arg0, int arg3) long LDIV@ (long arg0, long arg2)
/* Takes 8 bytes of parameters. /* Takes 8 bytes of parameters.
* Runtime support routine of the compiler. * Runtime support routine of the compiler.
* High-level language prologue code. * High-level language prologue code.
@ -131,7 +133,7 @@ long LDIV@ (long arg0, int arg3)
} }
long LMOD@ (long arg0, int arg3) long LMOD@ (long arg0, long arg2)
/* Takes 8 bytes of parameters. /* Takes 8 bytes of parameters.
* Runtime support routine of the compiler. * Runtime support routine of the compiler.
* High-level language prologue code. * High-level language prologue code.
@ -280,6 +282,7 @@ void main ()
{ {
long loc1; long loc1;
long loc2; long loc2;
loc2 = 255; loc2 = 255;
loc1 = 143; loc1 = 143;
loc1 = (loc2 + loc1); loc1 = (loc2 + loc1);

View File

@ -15,16 +15,14 @@ void proc_1 (int arg0, int arg1, int arg2)
int loc1; int loc1;
int loc2; int loc2;
int loc3; int loc3;
loc2 = 0;
loc2 = 0;
while ((loc2 < 5)) { while ((loc2 < 5)) {
loc3 = 0; loc3 = 0;
while ((loc3 < 4)) { while ((loc3 < 4)) {
loc1 = 0; loc1 = 0;
while ((loc1 < 4)) { while ((loc1 < 4)) {
*((((loc2 * 10) + arg2) + (loc3 << 1))) = ((*(((((loc2 << 3) << 1) + arg0) + (loc1 << 1))) * *((((loc1 * 10) + arg1) + (loc3 << 1)))) + *((((loc2 * 10) + arg2) + (loc3 << 1)))); *((((loc2 * 10) + arg2) + (loc3 << 1))) = ((*((((loc2 << 3) + arg0) + (loc1 << 1))) * *((((loc1 * 10) + arg1) + (loc3 << 1)))) + *((((loc2 * 10) + arg2) + (loc3 << 1))));
loc1 = (loc1 + 1); loc1 = (loc1 + 1);
} /* end of while */ } /* end of while */
loc3 = (loc3 + 1); loc3 = (loc3 + 1);
@ -42,6 +40,7 @@ void main ()
int loc1; int loc1;
int loc2; int loc2;
int loc3; int loc3;
proc_1 (&loc3, &loc2, &loc1); proc_1 (&loc3, &loc2, &loc1);
} }