From bbcf669cc919d49c89d047a82cef4f6ceeb5d899 Mon Sep 17 00:00:00 2001 From: billow Date: Sat, 9 Mar 2024 15:14:41 +0800 Subject: [PATCH] PIC: fixes --- librz/analysis/meson.build | 0 .../isa}/pic/pic16f_memmaps/memmaps.h | 0 .../isa}/pic/pic16f_memmaps/pic16f882.h | 0 .../isa}/pic/pic16f_memmaps/pic16f883_4.h | 0 .../isa}/pic/pic16f_memmaps/pic16f886_7.h | 0 .../isa}/pic/pic16f_memmaps/regtypes.h | 0 .../arch => arch/isa}/pic/pic18_analysis.inc | 9 +- .../arch => arch/isa}/pic/pic18_esil.inc | 0 librz/arch/isa/pic/pic18_il.inc | 5 + librz/arch/isa/pic/pic_baseline.c | 2 +- librz/arch/isa/pic/pic_baseline.h | 2 +- .../{analysis/arch => arch/isa}/pic/pic_il.h | 2 +- librz/arch/isa/pic/pic_midrange.c | 2 +- librz/arch/isa/pic/pic_midrange.h | 2 +- .../isa}/pic/pic_midrange_analysis.inc | 2 +- .../isa}/pic/pic_midrange_esil.inc | 0 .../isa/pic/pic_midrange_il.inc} | 2 +- librz/arch/isa/pic/pic_pic18.c | 11 +- librz/arch/isa/pic/pic_pic18.h | 5 +- librz/arch/p/analysis/analysis_pic.c | 685 +----------------- librz/arch/p/asm/asm_pic.c | 6 +- 21 files changed, 34 insertions(+), 701 deletions(-) delete mode 100644 librz/analysis/meson.build rename librz/{analysis/arch => arch/isa}/pic/pic16f_memmaps/memmaps.h (100%) rename librz/{analysis/arch => arch/isa}/pic/pic16f_memmaps/pic16f882.h (100%) rename librz/{analysis/arch => arch/isa}/pic/pic16f_memmaps/pic16f883_4.h (100%) rename librz/{analysis/arch => arch/isa}/pic/pic16f_memmaps/pic16f886_7.h (100%) rename librz/{analysis/arch => arch/isa}/pic/pic16f_memmaps/regtypes.h (100%) rename librz/{analysis/arch => arch/isa}/pic/pic18_analysis.inc (98%) rename librz/{analysis/arch => arch/isa}/pic/pic18_esil.inc (100%) create mode 100644 librz/arch/isa/pic/pic18_il.inc rename librz/{analysis/arch => arch/isa}/pic/pic_il.h (98%) rename librz/{analysis/arch => arch/isa}/pic/pic_midrange_analysis.inc (99%) rename librz/{analysis/arch => arch/isa}/pic/pic_midrange_esil.inc (100%) rename librz/{analysis/arch/pic/pic_midrange_il.c => arch/isa/pic/pic_midrange_il.inc} (99%) diff --git a/librz/analysis/meson.build b/librz/analysis/meson.build deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/librz/analysis/arch/pic/pic16f_memmaps/memmaps.h b/librz/arch/isa/pic/pic16f_memmaps/memmaps.h similarity index 100% rename from librz/analysis/arch/pic/pic16f_memmaps/memmaps.h rename to librz/arch/isa/pic/pic16f_memmaps/memmaps.h diff --git a/librz/analysis/arch/pic/pic16f_memmaps/pic16f882.h b/librz/arch/isa/pic/pic16f_memmaps/pic16f882.h similarity index 100% rename from librz/analysis/arch/pic/pic16f_memmaps/pic16f882.h rename to librz/arch/isa/pic/pic16f_memmaps/pic16f882.h diff --git a/librz/analysis/arch/pic/pic16f_memmaps/pic16f883_4.h b/librz/arch/isa/pic/pic16f_memmaps/pic16f883_4.h similarity index 100% rename from librz/analysis/arch/pic/pic16f_memmaps/pic16f883_4.h rename to librz/arch/isa/pic/pic16f_memmaps/pic16f883_4.h diff --git a/librz/analysis/arch/pic/pic16f_memmaps/pic16f886_7.h b/librz/arch/isa/pic/pic16f_memmaps/pic16f886_7.h similarity index 100% rename from librz/analysis/arch/pic/pic16f_memmaps/pic16f886_7.h rename to librz/arch/isa/pic/pic16f_memmaps/pic16f886_7.h diff --git a/librz/analysis/arch/pic/pic16f_memmaps/regtypes.h b/librz/arch/isa/pic/pic16f_memmaps/regtypes.h similarity index 100% rename from librz/analysis/arch/pic/pic16f_memmaps/regtypes.h rename to librz/arch/isa/pic/pic16f_memmaps/regtypes.h diff --git a/librz/analysis/arch/pic/pic18_analysis.inc b/librz/arch/isa/pic/pic18_analysis.inc similarity index 98% rename from librz/analysis/arch/pic/pic18_analysis.inc rename to librz/arch/isa/pic/pic18_analysis.inc index f0747c72fab..288b708c076 100644 --- a/librz/analysis/arch/pic/pic18_analysis.inc +++ b/librz/arch/isa/pic/pic18_analysis.inc @@ -3,8 +3,9 @@ // SPDX-FileCopyrightText: 2015-2018 courk // SPDX-License-Identifier: LGPL-3.0-only -#include "../asm/arch/pic/pic_pic18.h" +#include "pic_pic18.h" #include "pic18_esil.inc" +#include "pic18_il.inc" static void pic18_cond_branch(RzAnalysisOp *aop, ut64 addr, const ut8 *buf) { aop->type = RZ_ANALYSIS_OP_TYPE_CJMP; @@ -19,7 +20,7 @@ static int analysis_pic_pic18_op( aop->size = 2; Pic18Op op = { 0 }; - if (!pic18_disasm_op(&op, buf, len)) { + if (!pic18_disasm_op(&op, addr, buf, len)) { goto err; } aop->size = op.size; @@ -219,6 +220,10 @@ static int analysis_pic_pic18_op( pic18_esil(aop, &op, addr, buf); } + if (mask & RZ_ANALYSIS_OP_MASK_IL) { + aop->il_op = pic18_il(&op); + } + return aop->size; err: aop->type = RZ_ANALYSIS_OP_TYPE_ILL; diff --git a/librz/analysis/arch/pic/pic18_esil.inc b/librz/arch/isa/pic/pic18_esil.inc similarity index 100% rename from librz/analysis/arch/pic/pic18_esil.inc rename to librz/arch/isa/pic/pic18_esil.inc diff --git a/librz/arch/isa/pic/pic18_il.inc b/librz/arch/isa/pic/pic18_il.inc new file mode 100644 index 00000000000..9359c6078a2 --- /dev/null +++ b/librz/arch/isa/pic/pic18_il.inc @@ -0,0 +1,5 @@ +#include + +static RzILOpEffect *pic18_il(Pic18Op *op) { + return NULL; +} diff --git a/librz/arch/isa/pic/pic_baseline.c b/librz/arch/isa/pic/pic_baseline.c index 49bb05bb502..b57751bb6b1 100644 --- a/librz/arch/isa/pic/pic_baseline.c +++ b/librz/arch/isa/pic/pic_baseline.c @@ -197,7 +197,7 @@ const PicBaselineOpInfo *pic_baseline_get_op_info(PicBaselineOpcode opcode) { return &pic_baseline_op_info[opcode]; } -int pic_baseline_disassemble(RzAsmOp *op, const ut8 *b, int l) { +int pic_baseline_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *b, int l) { #define EMIT_INVALID \ { \ op->size = 1; \ diff --git a/librz/arch/isa/pic/pic_baseline.h b/librz/arch/isa/pic/pic_baseline.h index af5abc5783f..4d7d4fc4900 100644 --- a/librz/arch/isa/pic/pic_baseline.h +++ b/librz/arch/isa/pic/pic_baseline.h @@ -78,6 +78,6 @@ typedef enum { PicBaselineOpcode pic_baseline_get_opcode(ut16 instr); PicBaselineOpArgs pic_baseline_get_opargs(PicBaselineOpcode opcode); const PicBaselineOpInfo *pic_baseline_get_op_info(PicBaselineOpcode opcode); -int pic_baseline_disassemble(RzAsmOp *op, const ut8 *b, int l); +int pic_baseline_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *b, int l); #endif // PIC_BASELINE_H diff --git a/librz/analysis/arch/pic/pic_il.h b/librz/arch/isa/pic/pic_il.h similarity index 98% rename from librz/analysis/arch/pic/pic_il.h rename to librz/arch/isa/pic/pic_il.h index 59138e1ec4c..4bab3a7fc46 100644 --- a/librz/analysis/arch/pic/pic_il.h +++ b/librz/arch/isa/pic/pic_il.h @@ -70,6 +70,6 @@ RZ_IPI RzAnalysisILConfig *rz_midrange_il_vm_config(RZ_NONNULL RzAnalysis *analy // TODO: Add support for PIC18F & other device families -#include "pic_midrange_il.c" +#include "pic_midrange_il.inc" #endif // PIC_IL_H_ diff --git a/librz/arch/isa/pic/pic_midrange.c b/librz/arch/isa/pic/pic_midrange.c index fbece0c8757..4b3050e2f20 100644 --- a/librz/arch/isa/pic/pic_midrange.c +++ b/librz/arch/isa/pic/pic_midrange.c @@ -180,7 +180,7 @@ const PicMidrangeOpAsmInfo *pic_midrange_get_op_info(PicMidrangeOpcode opcode) { * * \return Number of decoded bytes (2 on success, 1 on failure). * */ -int pic_midrange_disassemble(RzAsmOp *op, const ut8 *b, int l) { +int pic_midrange_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *b, int l) { char fsr_op[6]; st16 branch; diff --git a/librz/arch/isa/pic/pic_midrange.h b/librz/arch/isa/pic/pic_midrange.h index 225d3f5a5cf..09f588b2ac2 100644 --- a/librz/arch/isa/pic/pic_midrange.h +++ b/librz/arch/isa/pic/pic_midrange.h @@ -118,6 +118,6 @@ typedef enum { PicMidrangeOpcode pic_midrange_get_opcode(ut16 instr); PicMidrangeOpArgs pic_midrange_get_opargs(PicMidrangeOpcode opcode); const PicMidrangeOpAsmInfo *pic_midrange_get_op_info(PicMidrangeOpcode opcode); -int pic_midrange_disassemble(RzAsmOp *op, const ut8 *b, int l); +int pic_midrange_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *b, int l); #endif // PIC_MIDRANGE_H diff --git a/librz/analysis/arch/pic/pic_midrange_analysis.inc b/librz/arch/isa/pic/pic_midrange_analysis.inc similarity index 99% rename from librz/analysis/arch/pic/pic_midrange_analysis.inc rename to librz/arch/isa/pic/pic_midrange_analysis.inc index f238adf45bf..e68ac01a028 100644 --- a/librz/analysis/arch/pic/pic_midrange_analysis.inc +++ b/librz/arch/isa/pic/pic_midrange_analysis.inc @@ -4,7 +4,7 @@ // SPDX-License-Identifier: LGPL-3.0-only #include "pic_il.h" -#include "../../asm/arch/pic/pic_midrange.h" +#include "pic_midrange.h" typedef void (*pic_midrange_inst_handler_t)(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, diff --git a/librz/analysis/arch/pic/pic_midrange_esil.inc b/librz/arch/isa/pic/pic_midrange_esil.inc similarity index 100% rename from librz/analysis/arch/pic/pic_midrange_esil.inc rename to librz/arch/isa/pic/pic_midrange_esil.inc diff --git a/librz/analysis/arch/pic/pic_midrange_il.c b/librz/arch/isa/pic/pic_midrange_il.inc similarity index 99% rename from librz/analysis/arch/pic/pic_midrange_il.c rename to librz/arch/isa/pic/pic_midrange_il.inc index d1e199e3ec2..c0a855b126f 100644 --- a/librz/analysis/arch/pic/pic_midrange_il.c +++ b/librz/arch/isa/pic/pic_midrange_il.inc @@ -6,7 +6,7 @@ #include #include "pic_il.h" -#include "../../asm/arch/pic/pic_midrange.h" +#include "pic_midrange.h" #include diff --git a/librz/arch/isa/pic/pic_pic18.c b/librz/arch/isa/pic/pic_pic18.c index cb8ace453c6..66def615c0c 100644 --- a/librz/arch/isa/pic/pic_pic18.c +++ b/librz/arch/isa/pic/pic_pic18.c @@ -101,7 +101,7 @@ static const Pic18OpDesc ops[] = { { PIC18_OPCODE_INVALID, 0x0, 0xffff, "invalid", NO_ARG }, }; -bool pic18_disasm_op(Pic18Op *op, const ut8 *buff, ut64 len) { +bool pic18_disasm_op(Pic18Op *op, ut64 addr, const ut8 *buff, ut64 len) { #define check_len(x) \ if (len < x) { \ op->code = PIC18_OPCODE_INVALID; \ @@ -109,6 +109,7 @@ bool pic18_disasm_op(Pic18Op *op, const ut8 *buff, ut64 len) { } \ op->size = x; + op->addr = addr; check_len(2); ut16 word = rz_read_le16(buff); Pic18OpDesc *desc = (Pic18OpDesc *)ops; @@ -185,15 +186,15 @@ bool pic18_disasm_op(Pic18Op *op, const ut8 *buff, ut64 len) { return true; } -int pic_pic18_disassemble(RzAsmOp *asm_op, const ut8 *b, int blen) { +int pic_pic18_disassemble(RzAsm *a, RzAsmOp *asm_op, const ut8 *b, int blen) { asm_op->size = 2; Pic18Op op = { 0 }; - pic18_disasm_op(&op, b, blen); - - if (op.code == PIC18_OPCODE_INVALID) { + if (!pic18_disasm_op(&op, a->pc, b, blen) || + op.code == PIC18_OPCODE_INVALID) { rz_asm_op_set_asm(asm_op, op.mnemonic); return -1; } + asm_op->size = op.size; switch (op.args_kind) { case NO_ARG: rz_asm_op_set_asm(asm_op, op.mnemonic); diff --git a/librz/arch/isa/pic/pic_pic18.h b/librz/arch/isa/pic/pic_pic18.h index 450f3a87eab..15caa270213 100644 --- a/librz/arch/isa/pic/pic_pic18.h +++ b/librz/arch/isa/pic/pic_pic18.h @@ -103,6 +103,7 @@ typedef enum { } Pic18ArgsKind; typedef struct { + ut64 addr; Pic18Opcode code; const char *mnemonic; ut8 size; @@ -118,7 +119,7 @@ typedef struct { }; } Pic18Op; -bool pic18_disasm_op(Pic18Op *op, const ut8 *buff, ut64 len); -int pic_pic18_disassemble(RzAsmOp *asm_op, const ut8 *b, int l); +bool pic18_disasm_op(Pic18Op *op, ut64 addr, const ut8 *buff, ut64 len); +int pic_pic18_disassemble(RzAsm *a, RzAsmOp *asm_op, const ut8 *b, int l); #endif // PIC_PIC18_H diff --git a/librz/arch/p/analysis/analysis_pic.c b/librz/arch/p/analysis/analysis_pic.c index 686206884c5..0446b8633e8 100644 --- a/librz/arch/p/analysis/analysis_pic.c +++ b/librz/arch/p/analysis/analysis_pic.c @@ -6,694 +6,12 @@ #include #include -#include "pic/pic_midrange.h" -#include "pic/pic_il.h" - -typedef struct _pic_midrange_op_args_val { - ut16 f; - ut16 k; - ut8 d; - ut8 m; - ut8 n; - ut8 b; -} PicMidrangeOpArgsVal; - -typedef void (*pic_midrange_inst_handler_t)(RzAnalysis *analysis, RzAnalysisOp *op, - ut64 addr, - PicMidrangeOpArgsVal *args); - -typedef struct _pic_midrange_op_analysis_info { - PicMidrangeOpcode opcode; - PicMidrangeOpArgs args; - pic_midrange_inst_handler_t handler; - pic_midrange_il_handler il_handler; -} PicMidrangeOpAnalysisInfo; - -#define INST_HANDLER(OPCODE_NAME) \ - static void _inst__##OPCODE_NAME(RzAnalysis *analysis, RzAnalysisOp *op, \ - ut64 addr, \ - PicMidrangeOpArgsVal *args) -#define INST_DECL(NAME, ARGS) \ - [PIC_MIDRANGE_OPCODE_##NAME] = { \ - PIC_MIDRANGE_OPCODE_##NAME, PIC_MIDRANGE_OP_ARGS_##ARGS, \ - _inst__##NAME, IL_LIFTER(NAME) \ - } - -#define e(frag) rz_strbuf_append(&op->esil, frag) -#define ef(frag, ...) rz_strbuf_appendf(&op->esil, frag, __VA_ARGS__) - -#define PIC_MIDRANGE_ESIL_SRAM_START (1 << 16) -#define PIC_MIDRANGE_ESIL_CSTACK_TOP ((1 << 16) + (1 << 12)) - -#define PIC_MIDRANGE_ESIL_BSR_ADDR "bsr,0x80,*,0x%x,+,_sram,+" - -#define PIC_MIDRANGE_ESIL_OPTION_ADDR "0x95,_sram,+" - -#define PIC_MIDRANGE_ESIL_UPDATE_FLAGS \ - "$z,z,:=," \ - "7,$c,c,:=," \ - "4,$c,dc,:=," - -#define PIC_MIDRANGE_ESIL_LW_OP(O) \ - "0x%x,wreg," #O "=," PIC_MIDRANGE_ESIL_UPDATE_FLAGS - -#define PIC_MIDRANGE_ESIL_FWF_OP(O) \ - "wreg," PIC_MIDRANGE_ESIL_BSR_ADDR "," #O \ - "=[1]," PIC_MIDRANGE_ESIL_UPDATE_FLAGS - -#define PIC_MIDRANGE_ESIL_WWF_OP(O) \ - PIC_MIDRANGE_ESIL_BSR_ADDR \ - ",[1]," \ - "wreg," #O "=," PIC_MIDRANGE_ESIL_UPDATE_FLAGS - -#define PIC_MIDRANGE_ESIL_FWF_OP_C(O) \ - "c,wreg," \ - "+," PIC_MIDRANGE_ESIL_BSR_ADDR "," #O \ - "=[1]," PIC_MIDRANGE_ESIL_UPDATE_FLAGS - -#define PIC_MIDRANGE_ESIL_WWF_OP_C(O) \ - "c," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1]," #O "," \ - "wreg," #O "=," PIC_MIDRANGE_ESIL_UPDATE_FLAGS - -INST_HANDLER(NOP) {} - -INST_HANDLER(RETFIE) { - op->type = RZ_ANALYSIS_OP_TYPE_RET; -} - -INST_HANDLER(OPTION) { - op->type = RZ_ANALYSIS_OP_TYPE_STORE; -} - -INST_HANDLER(TRIS) { - op->type = RZ_ANALYSIS_OP_TYPE_STORE; -} - -INST_HANDLER(RETURN) { - op->type = RZ_ANALYSIS_OP_TYPE_RET; - e("0x1f,stkptr,==,$z,?{,BREAK,},"); - e("_stack,stkptr,2,*,+,[2],2,*,pc,=,"); - e("0x01,stkptr,-=,"); - e("0xff,stkptr,==,$z,?{,0x1f,stkptr,=,},"); -} - -INST_HANDLER(CALL) { - ut64 pclath; - op->type = RZ_ANALYSIS_OP_TYPE_CALL; - rz_analysis_esil_reg_read(analysis->esil, "pclath", &pclath, NULL); - op->jump = 2 * (((pclath & 0x78) << 8) + args->k); - ef("8,pclath,0x78,&,<<,0x%x,+,2,*,pc,=,", args->k); - e("0x1f,stkptr,==,$z,?{,0xff,stkptr,=,},"); - e("0x0f,stkptr,==,$z,?{,0xff,stkptr,=,},"); - e("0x01,stkptr,+=,"); - ef("0x%" PFMT64x ",_stack,stkptr,2,*,+,=[2],", (addr + 2) / 2); -} - -INST_HANDLER(GOTO) { - ut64 pclath; - op->type = RZ_ANALYSIS_OP_TYPE_JMP; - rz_analysis_esil_reg_read(analysis->esil, "pclath", &pclath, NULL); - op->jump = 2 * (((pclath & 0x78) << 8) + args->k); - ef("8,pclath,0x78,&,<<,0x%x,+,2,*,pc,=,", args->k); -} - -INST_HANDLER(BCF) { - ut8 mask = ~(1 << args->b); - ef(PIC_MIDRANGE_ESIL_BSR_ADDR - ",[1],0x%x,&," PIC_MIDRANGE_ESIL_BSR_ADDR ",=[1],", - args->f, mask, args->f); -} - -INST_HANDLER(BSF) { - ut8 mask = (1 << args->b); - ef(PIC_MIDRANGE_ESIL_BSR_ADDR - ",[1],0x%x,|," PIC_MIDRANGE_ESIL_BSR_ADDR ",=[1],", - args->f, mask, args->f); -} - -INST_HANDLER(BTFSC) { - ut8 mask = (1 << args->b); - op->type = RZ_ANALYSIS_OP_TYPE_CJMP; - op->jump = addr + 4; - op->fail = addr + 2; - ef(PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],0x%x,&,!,?{,0x%" PFMT64x ",pc,=,},", - args->f, mask, op->jump); -} - -INST_HANDLER(BTFSS) { - ut8 mask = (1 << args->b); - op->type = RZ_ANALYSIS_OP_TYPE_CJMP; - op->jump = addr + 4; - op->fail = addr + 2; - ef(PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],0x%x,&,?{,0x%" PFMT64x ",pc,=,},", args->f, - mask, op->jump); -} - -INST_HANDLER(BRA) { - st16 branch = args->k; - op->type = RZ_ANALYSIS_OP_TYPE_JMP; - branch |= ((branch & 0x100) ? 0xfe00 : 0); - op->jump = addr + 2 * (branch + 1); - ef("%s0x%x,1,+,2,*,pc,+=,", branch < 0 ? "-" : "", - branch < 0 ? -branch : branch); -} - -INST_HANDLER(BRW) { - ut64 wreg; - op->type = RZ_ANALYSIS_OP_TYPE_UJMP; - rz_analysis_esil_reg_read(analysis->esil, "wreg", &wreg, NULL); - op->jump = addr + 2 * (wreg + 1); - e("wreg,1,+,2,*,pc,+=,"); -} - -INST_HANDLER(CLR) { - if (args->d) { - ef("0x00," PIC_MIDRANGE_ESIL_BSR_ADDR ",=[1],", args->f); - } else { - e("0x00,wreg,=,"); - } - e("1,z,=,"); -} - -INST_HANDLER(SUBWF) { - op->type = RZ_ANALYSIS_OP_TYPE_SUB; - if (args->d) { - ef(PIC_MIDRANGE_ESIL_FWF_OP(-), args->f); - } else { - ef(PIC_MIDRANGE_ESIL_WWF_OP(-), args->f); - e("wreg,0x00,-,wreg,=,c,!=,dc,!=,"); - } -} - -INST_HANDLER(DECFSZ) { - op->type = RZ_ANALYSIS_OP_TYPE_CJMP; - op->jump = addr + 4; - op->fail = addr + 2; - if (args->d) { - ef("0x01," PIC_MIDRANGE_ESIL_BSR_ADDR ",-=[1],", args->f); - } else { - ef("0x01," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],-,wreg,=,", - args->f); - } - ef(PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],!,?{,0x%" PFMT64x ",pc,=,},", args->f, - op->jump); -} - -INST_HANDLER(INCFSZ) { - op->type = RZ_ANALYSIS_OP_TYPE_CJMP; - op->jump = addr + 4; - op->fail = addr + 2; - if (args->d) { - ef("0x01," PIC_MIDRANGE_ESIL_BSR_ADDR ",+=[1],", args->f); - } else { - ef("0x01," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],+,wreg,=,", - args->f); - } - ef(PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],!,?{,0x%" PFMT64x ",pc,=,},", args->f, - op->jump); -} - -INST_HANDLER(INCF) { - op->type = RZ_ANALYSIS_OP_TYPE_ADD; - if (args->d) { - ef("0x01," PIC_MIDRANGE_ESIL_BSR_ADDR ",+=[1],", args->f); - } else { - ef("0x01," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],+,wreg,=,", - args->f); - } - e("$z,z,:=,"); -} - -INST_HANDLER(DECF) { - op->type = RZ_ANALYSIS_OP_TYPE_SUB; - if (args->d) { - ef("0x01," PIC_MIDRANGE_ESIL_BSR_ADDR ",-=[1],", args->f); - } else { - ef("0x01," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],-,wreg,=,", - args->f); - } - e("$z,z,:=,"); -} - -INST_HANDLER(IORWF) { - op->type = RZ_ANALYSIS_OP_TYPE_OR; - if (args->d) { - ef(PIC_MIDRANGE_ESIL_FWF_OP(|), args->f); - } else { - ef(PIC_MIDRANGE_ESIL_WWF_OP(|), args->f); - } -} - -INST_HANDLER(ANDWF) { - op->type = RZ_ANALYSIS_OP_TYPE_AND; - if (args->d) { - ef(PIC_MIDRANGE_ESIL_FWF_OP(&), args->f); - } else { - ef(PIC_MIDRANGE_ESIL_WWF_OP(&), args->f); - } -} - -INST_HANDLER(XORWF) { - op->type = RZ_ANALYSIS_OP_TYPE_XOR; - if (args->d) { - ef(PIC_MIDRANGE_ESIL_FWF_OP(^), args->f); - } else { - ef(PIC_MIDRANGE_ESIL_WWF_OP(^), args->f); - } -} - -INST_HANDLER(ADDWF) { - op->type = RZ_ANALYSIS_OP_TYPE_ADD; - if (args->d) { - ef(PIC_MIDRANGE_ESIL_FWF_OP(+), args->f); - } else { - ef(PIC_MIDRANGE_ESIL_WWF_OP(+), args->f); - } -} - -INST_HANDLER(SUBLW) { - op->type = RZ_ANALYSIS_OP_TYPE_SUB; - ef(PIC_MIDRANGE_ESIL_LW_OP(-), args->k); -} - -INST_HANDLER(ADDLW) { - op->type = RZ_ANALYSIS_OP_TYPE_ADD; - ef(PIC_MIDRANGE_ESIL_LW_OP(+), args->k); -} - -INST_HANDLER(IORLW) { - op->type = RZ_ANALYSIS_OP_TYPE_OR; - ef(PIC_MIDRANGE_ESIL_LW_OP(|), args->k); -} - -INST_HANDLER(ANDLW) { - op->type = RZ_ANALYSIS_OP_TYPE_AND; - ef(PIC_MIDRANGE_ESIL_LW_OP(&), args->k); -} - -INST_HANDLER(XORLW) { - op->type = RZ_ANALYSIS_OP_TYPE_XOR; - ef(PIC_MIDRANGE_ESIL_LW_OP(^), args->k); -} - -INST_HANDLER(MOVLW) { - op->type = RZ_ANALYSIS_OP_TYPE_LOAD; - ef("0x%x,wreg,=,", args->k); -} - -INST_HANDLER(RETLW) { - op->type = RZ_ANALYSIS_OP_TYPE_RET; - ef("0x%x,wreg,=,", args->k); - e("0x1f,stkptr,==,$z,?{,BREAK,},"); - e("_stack,stkptr,2,*,+,[2],2,*,pc,=,"); - e("0x01,stkptr,-=,"); - e("0xff,stkptr,==,$z,?{,0x1f,stkptr,=,},"); -} - -INST_HANDLER(MOVLP) { - op->type = RZ_ANALYSIS_OP_TYPE_LOAD; - ef("0x%x,pclath,=,", args->f); -} - -INST_HANDLER(MOVLB) { - op->type = RZ_ANALYSIS_OP_TYPE_LOAD; - ef("0x%x,bsr,=,", args->k); -} - -INST_HANDLER(CALLW) { - op->type = RZ_ANALYSIS_OP_TYPE_UCALL; - e("8,pclath,<<,0x%x,+,wreg,2,*,pc,=,"); - e("0x1f,stkptr,==,$z,?{,0xff,stkptr,=,},"); - e("0x0f,stkptr,==,$z,?{,0xff,stkptr,=,},"); - e("0x01,stkptr,+=,"); - ef("0x%" PFMT64x ",_stack,stkptr,2,*,+,=[2],", (addr + 2) / 2); -} - -INST_HANDLER(MOVWF) { - op->type = RZ_ANALYSIS_OP_TYPE_STORE; - ef("wreg," PIC_MIDRANGE_ESIL_BSR_ADDR ",=[1],", args->f); -} - -INST_HANDLER(MOVF) { - op->type = RZ_ANALYSIS_OP_TYPE_LOAD; - if (args->d) { - ef(PIC_MIDRANGE_ESIL_BSR_ADDR - ",[1]," PIC_MIDRANGE_ESIL_BSR_ADDR ",=[1],", - args->f, args->f); - } else { - ef(PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],wreg,=,", args->f); - } - e("$z,z,:=,"); -} - -INST_HANDLER(SWAPF) { - ef("4," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],>>,0x0f,&,", args->f); - ef("4," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],<<,0xf0,&,", args->f); - e("|,"); - ef(PIC_MIDRANGE_ESIL_BSR_ADDR ",=[1],", args->f); -} - -INST_HANDLER(LSLF) { - op->type = RZ_ANALYSIS_OP_TYPE_SHL; - ef("7," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],>>,c,=,", args->f); - if (args->d) { - ef("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",<<=[1],", args->f); - } else { - ef("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],<<,wreg,=,", - args->f); - } - e("$z,z,:=,"); -} - -INST_HANDLER(LSRF) { - op->type = RZ_ANALYSIS_OP_TYPE_SHR; - ef("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],&,c,=,", args->f); - if (args->d) { - ef("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",>>=[1],", args->f); - } else { - ef("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],>>,wreg,=,", - args->f); - } - e("$z,z,:=,"); -} - -INST_HANDLER(ASRF) { - op->type = RZ_ANALYSIS_OP_TYPE_SHR; - ef("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],&,c,=,", args->f); - ef("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],>>,", args->f); - ef("0x80," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],&,", args->f); - if (args->d) { - ef("|," PIC_MIDRANGE_ESIL_BSR_ADDR ",=[1],", args->f); - } else { - e("|,wreg,=,"); - } - e("$z,z,:=,"); -} - -INST_HANDLER(RRF) { - op->type = RZ_ANALYSIS_OP_TYPE_ROR; - ef("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],&,", args->f); - if (args->d) { - ef("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",>>=[1]," - "c," PIC_MIDRANGE_ESIL_BSR_ADDR ",|=[1],", - args->f, args->f); - } else { - ef("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],>>,wreg,=," - "c,wreg,|=[1],", - args->f); - } - e("c,=,"); -} - -INST_HANDLER(RLF) { - op->type = RZ_ANALYSIS_OP_TYPE_ROL; - ef("7," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],>>,", args->f); - if (args->d) { - ef("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",<<=[1]," - "c," PIC_MIDRANGE_ESIL_BSR_ADDR ",|=[1],", - args->f, args->f); - } else { - ef("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],<<,wreg,=," - "c,wreg,|=[1],", - args->f); - } - e("c,=,"); -} - -INST_HANDLER(COMF) { - if (args->d) { - ef("0xff," PIC_MIDRANGE_ESIL_BSR_ADDR ",^=[1],", args->f); - } else { - ef("0xff," PIC_MIDRANGE_ESIL_BSR_ADDR ",^,wreg,=,", args->f); - } - e("$z,z,:=,"); -} - -INST_HANDLER(RESET) { - op->type = RZ_ANALYSIS_OP_TYPE_JMP; - op->jump = 0; - e("0x0,pc,=,"); - e("0x1f,stkptr,=,"); -} - -INST_HANDLER(ADDFSR) { - op->type = RZ_ANALYSIS_OP_TYPE_ADD; - if (args->n == 0) { - ef("0x%x,fsr0l,+=,", args->k); - e("7,$c,?{,0x01,fsr0h,+=,},"); - } else { - ef("0x%x,fsr1l,+=,", args->k); - e("7,$c,?{,0x01,fsr1h,+=,},"); - } -} - -INST_HANDLER(CLRWDT) { - e("1,to,=,"); - e("1,pd,=,"); -} - -INST_HANDLER(SLEEP) { - e("1,to,=,"); - e("0,pd,=,"); -} - -INST_HANDLER(SUBWFB) { - op->type = RZ_ANALYSIS_OP_TYPE_SUB; - e("c,!=,"); - if (args->d) { - ef(PIC_MIDRANGE_ESIL_FWF_OP_C(-), args->f); - } else { - ef(PIC_MIDRANGE_ESIL_WWF_OP_C(-), args->f); - e("wreg,0x00,-,wreg,=,c,!=,dc,!=,"); - } -} - -INST_HANDLER(ADDWFC) { - op->type = RZ_ANALYSIS_OP_TYPE_ADD; - if (args->d) { - ef(PIC_MIDRANGE_ESIL_FWF_OP_C(+), args->f); - } else { - ef(PIC_MIDRANGE_ESIL_WWF_OP_C(+), args->f); - } -} - -INST_HANDLER(MOVIW_1) { - if (args->n == 0) { - if (!(args->m & 2)) { - ef("1,fsr0l,%s=,", (args->m & 1) ? "-" : "+"); - ef("7,$c%s,fsr0h,%s,", (args->m & 1) ? ",!" : "", - (args->m & 1) ? "-" : "+"); - } - e("indf0,wreg,=,"); - e("$z,z,:=,"); - if (args->m & 2) { - ef("1,fsr0l,%s=,", (args->m & 1) ? "-" : "+"); - ef("7,$c%s,fsr0h,%s,", (args->m & 1) ? ",!" : "", - (args->m & 1) ? "-" : "+"); - } - } else { - if (!(args->m & 2)) { - ef("1,fsr1l,%s=,", (args->m & 1) ? "-" : "+"); - ef("7,$c%s,fsr1h,%s,", (args->m & 1) ? ",!" : "", - (args->m & 1) ? "-" : "+"); - } - e("indf1,wreg,=,"); - e("$z,z,:=,"); - if (args->m & 2) { - ef("1,fsr1l,%s=,", (args->m & 1) ? "-" : "+"); - ef("7,$c%s,fsr1h,%s,", (args->m & 1) ? ",!" : "", - (args->m & 1) ? "-" : "+"); - } - } -} - -INST_HANDLER(MOVWI_1) { - if (args->n == 0) { - if (!(args->m & 2)) { - ef("1,fsr0l,%s=,", (args->m & 1) ? "-" : "+"); - ef("$c7%s,fsr0h,%s,", (args->m & 1) ? ",!" : "", - (args->m & 1) ? "-" : "+"); - } - e("wreg,indf0=,"); - e("$z,z,:=,"); - if (args->m & 2) { - ef("1,fsr0l,%s=,", (args->m & 1) ? "-" : "+"); - ef("$c7%s,fsr0h,%s,", (args->m & 1) ? ",!" : "", - (args->m & 1) ? "-" : "+"); - } - } else { - if (!(args->m & 2)) { - ef("1,fsr1l,%s=,", (args->m & 1) ? "-" : "+"); - ef("$c7,fsr1h,%s,", (args->m & 1) ? ",!" : ""); - } - e("wreg,indf1=,"); - e("$z,z,:=,"); - if (args->m & 2) { - ef("1,fsr1l,%s=,", (args->m & 1) ? "-" : "+"); - ef("$c7%s,fsr1h,%s,", (args->m & 1) ? ",!" : "", - (args->m & 1) ? "-" : "+"); - } - } -} - -INST_HANDLER(MOVIW_2) { - if (args->n == 0) { - e("fsr0l,8,fsr0h,<<,+,"); - } else { - e("fsr1l,8,fsr1h,<<,+,"); - } - ef("0x%x,+,[1],wreg,=,", args->k); -} - -INST_HANDLER(MOVWI_2) { - e("wreg,"); - if (args->n == 0) { - e("fsr0l,8,fsr0h,<<,+,"); - } else { - e("fsr1l,8,fsr1h,<<,+,"); - } - e("=[1],"); -} - -INST_HANDLER(CLRF) {} - -static const PicMidrangeOpAnalysisInfo pic_midrange_op_analysis_info[] = { - INST_DECL(NOP, NONE), - INST_DECL(RETURN, NONE), - INST_DECL(RETFIE, NONE), - INST_DECL(OPTION, NONE), - INST_DECL(SLEEP, NONE), - INST_DECL(CLRWDT, NONE), - INST_DECL(TRIS, 2F), - INST_DECL(MOVWF, 7F), - INST_DECL(CLR, 1D_7F), - INST_DECL(SUBWF, 1D_7F), - INST_DECL(DECF, 1D_7F), - INST_DECL(IORWF, 1D_7F), - INST_DECL(ANDWF, 1D_7F), - INST_DECL(XORWF, 1D_7F), - INST_DECL(ADDWF, 1D_7F), - INST_DECL(MOVF, 1D_7F), - INST_DECL(COMF, 1D_7F), - INST_DECL(INCF, 1D_7F), - INST_DECL(DECFSZ, 1D_7F), - INST_DECL(RRF, 1D_7F), - INST_DECL(RLF, 1D_7F), - INST_DECL(SWAPF, 1D_7F), - INST_DECL(INCFSZ, 1D_7F), - INST_DECL(BCF, 3B_7F), - INST_DECL(BSF, 3B_7F), - INST_DECL(BTFSC, 3B_7F), - INST_DECL(BTFSS, 3B_7F), - INST_DECL(CALL, 11K), - INST_DECL(GOTO, 11K), - INST_DECL(MOVLW, 8K), - INST_DECL(RETLW, 8K), - INST_DECL(IORLW, 8K), - INST_DECL(ANDLW, 8K), - INST_DECL(XORLW, 8K), - INST_DECL(SUBLW, 8K), - INST_DECL(ADDLW, 8K), - INST_DECL(RESET, NONE), - INST_DECL(CALLW, NONE), - INST_DECL(BRW, NONE), - INST_DECL(MOVIW_1, 1N_2M), - INST_DECL(MOVWI_1, 1N_2M), - INST_DECL(MOVLB, 4K), - INST_DECL(LSLF, 1D_7F), - INST_DECL(LSRF, 1D_7F), - INST_DECL(ASRF, 1D_7F), - INST_DECL(SUBWFB, 1D_7F), - INST_DECL(ADDWFC, 1D_7F), - INST_DECL(ADDFSR, 1N_6K), - INST_DECL(MOVLP, 7F), - INST_DECL(BRA, 9K), - INST_DECL(MOVIW_2, 1N_6K), - INST_DECL(MOVWI_2, 1N_6K), - INST_DECL(CLRF, 7F), -}; - -static void analysis_pic_midrange_extract_args(ut16 instr, - PicMidrangeOpArgs args, - PicMidrangeOpArgsVal *args_val) { - - memset(args_val, 0, sizeof(PicMidrangeOpArgsVal)); - - switch (args) { - case PIC_MIDRANGE_OP_ARGS_NONE: return; - case PIC_MIDRANGE_OP_ARGS_2F: - args_val->f = instr & PIC_MIDRANGE_OP_ARGS_2F_MASK_F; - return; - case PIC_MIDRANGE_OP_ARGS_7F: - args_val->f = instr & PIC_MIDRANGE_OP_ARGS_7F_MASK_F; - return; - case PIC_MIDRANGE_OP_ARGS_1D_7F: - args_val->f = instr & PIC_MIDRANGE_OP_ARGS_1D_7F_MASK_F; - args_val->d = - (instr & PIC_MIDRANGE_OP_ARGS_1D_7F_MASK_D) >> 7; - return; - case PIC_MIDRANGE_OP_ARGS_1N_6K: - args_val->n = - (instr & PIC_MIDRANGE_OP_ARGS_1N_6K_MASK_N) >> 6; - args_val->k = instr & PIC_MIDRANGE_OP_ARGS_1N_6K_MASK_K; - return; - case PIC_MIDRANGE_OP_ARGS_3B_7F: - args_val->b = - (instr & PIC_MIDRANGE_OP_ARGS_3B_7F_MASK_B) >> 7; - args_val->f = instr & PIC_MIDRANGE_OP_ARGS_3B_7F_MASK_F; - return; - case PIC_MIDRANGE_OP_ARGS_4K: - args_val->k = instr & PIC_MIDRANGE_OP_ARGS_4K_MASK_K; - return; - case PIC_MIDRANGE_OP_ARGS_8K: - args_val->k = instr & PIC_MIDRANGE_OP_ARGS_8K_MASK_K; - return; - case PIC_MIDRANGE_OP_ARGS_9K: - args_val->k = instr & PIC_MIDRANGE_OP_ARGS_9K_MASK_K; - return; - case PIC_MIDRANGE_OP_ARGS_11K: - args_val->k = instr & PIC_MIDRANGE_OP_ARGS_11K_MASK_K; - return; - case PIC_MIDRANGE_OP_ARGS_1N_2M: - args_val->n = - (instr & PIC_MIDRANGE_OP_ARGS_1N_2M_MASK_N) >> 2; - args_val->m = instr & PIC_MIDRANGE_OP_ARGS_1N_2M_MASK_M; - return; - } -} - -static RzIODesc *cpu_memory_map(RzIOBind *iob, RzIODesc *desc, ut32 addr, - ut32 size) { - char mstr[16]; - rz_strf(mstr, "malloc://%d", size); - if (desc && iob->fd_get_name(iob->io, desc->fd)) { - iob->fd_remap(iob->io, desc->fd, addr); - } else { - desc = iob->open_at(iob->io, mstr, RZ_PERM_RW, 0, addr, NULL); - } - return desc; -} - -static bool pic_midrange_reg_write(RzReg *reg, const char *regname, ut32 num) { - if (reg) { - RzRegItem *item = rz_reg_get(reg, regname, RZ_REG_TYPE_GPR); - if (item) { - rz_reg_set_value(reg, item, num); - return true; - } - } - return false; -} - typedef struct { RzIODesc *mem_sram; RzIODesc *mem_stack; bool init_done; } PicContext; -#include "../arch/pic/pic_midrange_analysis.inc" -#include "../arch/pic/pic18_analysis.inc" - static bool pic_init(void **user) { PicContext *ctx = RZ_NEW0(PicContext); if (!ctx) { @@ -712,6 +30,9 @@ static bool pic_fini(void *user) { return true; } +#include "pic/pic_midrange_analysis.inc" +#include "pic/pic18_analysis.inc" + static int analysis_pic_op( RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, RzAnalysisOpMask mask) { diff --git a/librz/arch/p/asm/asm_pic.c b/librz/arch/p/asm/asm_pic.c index ffe38be12d1..815ae36271a 100644 --- a/librz/arch/p/asm/asm_pic.c +++ b/librz/arch/p/asm/asm_pic.c @@ -12,11 +12,11 @@ static int asm_pic_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *b, int l) { int res = -1; if (a->cpu && strcasecmp(a->cpu, "baseline") == 0) { - res = pic_baseline_disassemble(op, b, l); + res = pic_baseline_disassemble(a, op, b, l); } else if (a->cpu && strcasecmp(a->cpu, "midrange") == 0) { - res = pic_midrange_disassemble(op, b, l); + res = pic_midrange_disassemble(a, op, b, l); } else if (a->cpu && strcasecmp(a->cpu, "pic18") == 0) { - res = pic_pic18_disassemble(op, b, l); + res = pic_pic18_disassemble(a, op, b, l); } return op->size = res; }