Repository URL to install this package:
Version:
9.0~241217-2.fc42 ▾
|
/*
* Interactive disassembler (IDA).
* Copyright (c) 1990-99 by Ilfak Guilfanov.
* ALL RIGHTS RESERVED.
* E-mail: ig@datarescue.com
*
*
*/
#ifndef _H8_HPP
#define _H8_HPP
#include "../idaidp.hpp"
#include <diskio.hpp>
#include "ins.hpp"
#include "../iohandler.hpp"
#define PROCMOD_NAME h8
#define PROCMOD_NODE_NAME "$ h8"
//------------------------------------------------------------------
// processor types
typedef uint16 proctype_t;
static const proctype_t none = 0;
static const proctype_t P300 = 0x0001; // H8/300, H8/300H
static const proctype_t P2000 = 0x0002; // H8S/2000
static const proctype_t P2600 = 0x0004; // H8S/2600
static const proctype_t PSX = 0x0008; // H8SX
// assume 'Normal mode' as the default
static const proctype_t MODE_MASK= 0xF000;
static const proctype_t MODE_MID = 0x1000; // H8SX
static const proctype_t MODE_ADV = 0x2000; // H8/300H (!), H8S, H8SX
static const proctype_t MODE_MAX = 0x3000; // H8SX
// submodel
static const proctype_t SUBM_MASK= 0x0F00;
static const proctype_t SUBM_TINY= 0x0100; // H8/300H Tiny model
// full insn set and normal mode
static const proctype_t P30A = P300 | MODE_ADV;
static const proctype_t P26A = P2600 | MODE_ADV;
//------------------------------------------------------------------
#ifdef _MSC_VER
#define ENUM8BIT : uint8
#else
#define ENUM8BIT
#endif
enum regnum_t ENUM8BIT
{
R0, R1, R2, R3, R4, R5, R6, R7, SP=R7,
E0, E1, E2, E3, E4, E5, E6, E7,
R0H, R1H, R2H, R3H, R4H, R5H, R6H, R7H,
R0L, R1L, R2L, R3L, R4L, R5L, R6L, R7L,
ER0, ER1, ER2, ER3, ER4, ER5, ER6, ER7,
// don't change registers order above this line
MACL, MACH,
PC,
CCR, EXR,
rVcs, rVds, // virtual registers for code and data segments
VBR, SBR, // base or segment registers
};
//---------------------------------
// Operand types:
/*
o_reg 1 Register direct
Rn
x.reg
o_phrase 2 Register indirect
@ERn
x.phrase contains register number
x.phtype contains phrase type (normal, post, pre)
o_displ 3 Register indirect with displacement
@(d:2,ERn)/@(d:16,ERn)/@(d:32,ERn)
x.reg, x.addr, disp_16, disp_32, disp_2
o_displ 4 Index register indirect with displacement
@(d:16, RnL.B)/@(d:16,Rn.W)/@(d:16,ERn.L)
@(d:32, RnL.B)/@(d:32,Rn.W)/@(d:32,ERn.L)
x.displtype = dt_regidx,
x.reg,
x.addr - disp_16, disp_32, idx_byte/word/long
o_phrase 5 Register indirect with post-inc/pre-dec/pre-inc/post-dec
@ERn+/@-ERn/@+ERn/@ERn-
o_mem 6 Absolute address
@aa:8/@aa:16/@aa:24/@aa:32
x.memtype = @aa:8 ? mem_sbr : mem_direct
x.addr
o_imm 7 Immediate
#x:2/#xx:3/#xx:4/#xx:5/#xx:8/#xx:16/#xx:32
#1/#2/#4/#8/#16
x.value
o_near 8 Program-counter relative
@(d:8,PC)/@(d:16,PC)
o_pcidx 9 Program-counter relative with index register
@(RnL.B,PC)/@(Rn.W,PC)/@(ERn.L,PC)
x.reg
o_mem 10 Memory indirect
@@aa:8
x.memtype = mem_ind
x.addr
o_mem 11 Extended memory indirect
@@vec:7
x.memtype = mem_vec7
x.addr
o_reglist Register list
x.reg, x.nregs
o_displ first operand of MOVA insn
@(d16,<EA>.[BW])/@(d32:<EA>.[BW])
x.displtype = dt_movaop1,
x.addr,
x.szfl - disp_16/disp_32/idx_byte/idx_word
x.idxt - <EA> type
<EA> type:
o_reg - x.reg EQ to o_regidx
o_phrase - x.phrase,x.idxdt
o_displ - x.reg,x.value,x.idxsz,x.idxdt
o_regidx - x.reg,x.value,x.idxsz,x.idxdt
o_mem - x.value,x.idsz,x.idxdt
*/
#define o_reglist o_idpspec0
#define o_pcidx o_idpspec1
#define phtype specflag1 // phrase type:
const int ph_normal = 0; // just simple indirection
const int ph_pre_dec = 0x10; // -@Rn ^ 3 -> @Rn+
const int ph_post_inc = 0x13; // @Rn+
const int ph_pre_inc = 0x11; // +@ERn
const int ph_post_dec = 0x12; // @ERn-
#define displtype specflag1 // displ type:
const int dt_normal = 0; // Register indirect with displacement
const int dt_regidx = 1; // Index register indirect with displacement
const int dt_movaop1 = 2; // first operand of MOVA insn
#define szfl specflag2 // various operand size flags
// index target
const int idx_byte = 0x01; // .b
const int idx_word = 0x02; // .w
const int idx_long = 0x04; // .l
// size of operand displ
const int disp_16 = 0x10; // 16bit displacement
const int disp_24 = 0x20; // 24bit displacement
const int disp_32 = 0x40; // 32bit displacement
const int disp_2 = 0x80; // 2bit displacement
#define memtype specflag1 // mem type:
const int mem_direct = 0; // x.addr - direct memory ref
const int mem_sbr = 1; // SBR based @aa:8
const int mem_vec7 = 2; // @@vec:7
const int mem_ind = 3; // @@aa:8
#define nregs specflag1 // o_reglist: number of registers
// MOVA Op1 store
#define idxt specflag3 // MOVA: optype_t of index
#define idxsz specflag4 // MOVA: size of index
#define idxdt specval // MOVA: index phtype,displtype,memtype
//------------------------------------------------------------------
const uint16 aux_none = 0; // no postfix
const uint16 aux_byte = 1; // .b postfix
const uint16 aux_word = 2; // .w postfix
const uint16 aux_long = 3; // .l postfix
//------------------------------------------------------------------
#define UAS_HEW 0x0001 // HEW assembler
//------------------------------------------------------------------
ea_t calc_mem(const insn_t &insn, ea_t ea); // map virtual to physical ea
ea_t calc_mem_sbr_based(const insn_t &insn, ea_t ea); // map virtual @aa:8 physical ea
void idaapi h8_segend(outctx_t &ctx, segment_t *seg);
int idaapi h8_is_align_insn(ea_t ea);
bool idaapi create_func_frame(func_t *pfn);
int idaapi is_sp_based(const insn_t &insn, const op_t &x);
bool idaapi is_return_insn(const insn_t &insn);
int is_jump_func(const func_t *pfn, ea_t *jump_target);
int may_be_func(const insn_t &insn); // can a function start here?
int is_sane_insn(const insn_t &insn, int nocrefs);
bool idaapi h8_is_switch(switch_info_t *si, const insn_t &insn);
//------------------------------------------------------------------
struct h8_iohandler_t : public iohandler_t
{
h8_iohandler_t(netnode &nn) : iohandler_t(nn) {}
virtual void get_cfg_filename(char *buf, size_t bufsize) override;
};
struct h8_t : public procmod_t
{
netnode helper;
h8_iohandler_t ioh = h8_iohandler_t(helper);
proctype_t ptype = none; // contains all bits which correspond
// to the supported processors set
char show_sizer = -1;
uchar code = 0;
uchar code3 = 0;
bool flow = false;
virtual ssize_t idaapi on_event(ssize_t msgid, va_list va) override;
inline bool advanced(void) { return (ptype & MODE_MASK) != 0; }
inline bool is_h8s(void) { return (ptype & (P2000|P2600)) != 0; }
inline bool is_h8sx(void) { return (ptype & PSX) != 0; }
inline bool is_tiny(void) { return (ptype & SUBM_TINY) != 0; }
inline regnum_t r0(void) { return advanced() ? ER0 : R0; }
inline bool is_hew_asm(void) const
{
return (ash.uflag & UAS_HEW) != 0;
}
void load_symbols(void);
const char *find_sym(ea_t address);
const char *set_idp_options(
const char *keyword,
int /*value_type*/,
const void * /*value*/,
bool /*idb_loaded*/);
void set_cpu(int cpuno);
int get_displ_outf(const op_t &x, flags64_t F);
ea_t trim_ea_branch(ea_t ea) const; // trim address according to proc mode
void h8_header(outctx_t &ctx);
void trimaddr(op_t &x);
void opatHL(op_t &x, op_dtype_t dtyp);
void opdsp16(insn_t &insn, op_t &x, op_dtype_t dtyp);
void opdsp32(insn_t &insn, op_t &x, op_dtype_t dtyp);
bool read_operand(insn_t &insn, op_t &x, ushort flags);
bool map014(insn_t &insn);
bool map4(insn_t &insn);
int ana(insn_t *pinsn);
int exit_40(insn_t &insn);
int exit_54_56(insn_t &insn, uint8 rts, uint8 rtsl);
int exit_59_5D(insn_t &insn, uint16 jump, uint16 branch);
int exit_7B(insn_t &insn);
int h8sx_03(insn_t &insn);
int h8sx_0A(insn_t &insn);
int h8sx_1A(insn_t &insn);
int h8sx_6A(insn_t &insn);
void handle_operand(const insn_t &insn, const op_t &x, bool is_forced, bool isload);
int h8sx_6B(insn_t &insn);
int h8sx_78(insn_t &insn);
int h8sx_79(insn_t &insn);
int h8sx_7A(insn_t &insn);
bool h8sx_010D(insn_t &insn);
bool h8sx_010E(insn_t &insn);
bool insn_ldc(insn_t &insn, uint8 byte2, regnum_t reg);
bool h8sx_01_exr(insn_t &insn);
bool insn_mova(insn_t &insn);
int insn_mova_reg(insn_t &insn, uint8 opcode, uint8 rs, bool is_reg_equal);
bool h8sx_01_other(insn_t &insn);
bool insn_addx_imm(insn_t &insn, op_t &x, uint8 byte2, uint8 byte3, uint16 mask, bool check_byte3);
bool insn_bra(insn_t &insn, uint8 byte2, uint8 byte3);
bool insn_bfld_bfst(insn_t &insn, uint8 byte2, uint8 byte3, bool is_bfld);
bool use_leaf_map(insn_t &insn, const struct map_t *m, uint8 idx);
bool op_from_byte(insn_t &insn, op_t &x, uint8 byte2);
bool read_1st_op(insn_t &insn, uint8 byte2, uint8 byte3_hiNi);
bool op_phrase(const insn_t &insn, op_t &x, uint8 reg, int pht, op_dtype_t dtype=dt_byte);
bool op_displ_regidx(insn_t &insn, op_t &x, uint8 selector, bool is_32, uint8 reg);
int emu(const insn_t &insn);
int h8_get_frame_retsize(const func_t *);
int h8sx_7C(insn_t &insn);
int h8sx_7D(insn_t &insn);
bool h8sx_010_01dd(insn_t &insn, uint16 postfix);
bool h8sx_ldm(insn_t &insn);
bool insn_mac(insn_t &insn);
bool insn_tas(insn_t &insn);
bool op_phrase_prepost(const insn_t &insn, op_t &x, uint8 reg, uint8 selector);
bool op_phrase_displ2(const insn_t &insn, op_t &x, uint8 reg, uint8 displ);
int h8sx_01(insn_t &insn);
bool h8sx_010_00dd(insn_t &insn);
int h8sx_7E(insn_t &insn);
int h8sx_7F(insn_t &insn);
int unpack_8bit_shift(const map_t *m, insn_t &insn, uint16 itype, uint16 itype2);
int h8sx_10(insn_t &insn);
int h8sx_11(insn_t &insn);
bool h8sx_0108(insn_t &insn);
bool h8sx_0109_010A(insn_t &insn,op_t ®op, op_t &genop);
int h8sx_0F(insn_t &insn);
int h8sx_1F(insn_t &insn);
void add_code_xref(const insn_t &insn, const op_t &x, ea_t ea);
void h8_assumes(outctx_t &ctx);
void trace_sp(const insn_t &insn) const;
bool get_op_value(uval_t *value, const insn_t &_insn, const op_t &x) const;
bool spoils(const insn_t &insn, int reg) const;
void check_base_reg_change_value(const insn_t &insn) const;
void h8_segstart(outctx_t &ctx, segment_t *Srange) const;
void h8_gen_stkvar_def(outctx_t &ctx, const udm_t *stkvar, sval_t v) const;
void h8_footer(outctx_t &ctx) const;
void load_from_idb();
};
extern int data_id;
#endif // _H8_HPP