mirror of
https://github.com/radareorg/radare2.git
synced 2025-03-01 18:57:20 +00:00
Initial 8051 disasm and ihex:// io plugin
This commit is contained in:
parent
93f9d519cf
commit
189e5553cc
232
libr/asm/arch/8051/8051.c
Normal file
232
libr/asm/arch/8051/8051.c
Normal file
@ -0,0 +1,232 @@
|
||||
#if 0
|
||||
|
||||
http://www.keil.com/support/man/docs/is51/is51_instructions.htm
|
||||
http://www.keil.com/support/man/docs/is51/is51_opcodes.htm
|
||||
|
||||
// TODO: extend support for 251
|
||||
|
||||
The classic 8051 provides 4 register banks of 8 registers each.
|
||||
These register banks are mapped into the DATA memory area at
|
||||
address 0 – 0x1F. In addition the CPU provides a 8-bit A
|
||||
(accumulator) and B register and a 16-bit DPTR (data pointer)
|
||||
for addressing XDATA and CODE memory. These registers are also
|
||||
mapped into the SFR space as special function registers.
|
||||
|
||||
|-----------------------|
|
||||
r0 r1 r2 r3 r4 r5 r6 r7 0x00
|
||||
r0 r1 r2 r3 r4 r5 r6 r7 0x08
|
||||
r0 r1 r2 r3 r4 r5 r6 r7 0x10
|
||||
r0 r1 r2 r3 r4 r5 r6 r7 0x18
|
||||
|
||||
A = acumulator
|
||||
B = general purpose
|
||||
DPTR = 16 bit pointer to data
|
||||
|
||||
PSW1 - status word register
|
||||
|
||||
Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
|
||||
CY AC N RS1 RS0 OV Z —
|
||||
|
||||
The following table describes the status bits in the PSW:
|
||||
|
||||
RS1 RS0 Working Register Bank and Address
|
||||
0 0 Bank0 (D:0x00 - D:0x07)
|
||||
0 1 Bank1 (D:0x08 - D:0x0F)
|
||||
1 0 Bank2 (D:0x10 - D:0x17)
|
||||
1 1 Bank3 (D:0x18H - D:0x1F)
|
||||
|
||||
#endif
|
||||
|
||||
#include <r_types.h>
|
||||
|
||||
typedef struct op {
|
||||
const char *name;
|
||||
int length;
|
||||
int operand;
|
||||
ut32 addr;
|
||||
const char *arg;
|
||||
const ut8 *buf;
|
||||
} Op8051;
|
||||
|
||||
enum {
|
||||
NONE = 0,
|
||||
ADDR11, // 8 bits from argument + 3 high bits from opcode
|
||||
ADDR16, // A 16-bit address destination. Used by LCALL and LJMP
|
||||
DIRECT, // An internal data RAM location (0-127) or SFR (128-255).
|
||||
OFFSET, // same as direct?
|
||||
ARG, // register
|
||||
};
|
||||
|
||||
#undef _
|
||||
#define _ (Op8051)
|
||||
#define _ARG(x) ARG, 0, x, buf
|
||||
#define _ADDR11(x) ADDR11, ((x[1])+((x[0]>>5)<<8)), NULL, buf
|
||||
#define _ADDR16(x) ADDR16, ((x[1])<<8)+((x[2])), NULL, buf
|
||||
#define _OFFSET(x) OFFSET, ((x[1])), NULL, buf
|
||||
#define _DIRECT(x) DIRECT, (x[1]), NULL, x
|
||||
|
||||
static const char *arg[] = { "#immed", "direct", "@r0", "@r1", "r0",
|
||||
"r1", "r1", "r2", "r3", "r4", "r5", "r6", "r7" };
|
||||
static const char *ops[] = {
|
||||
"inc", // 0. 04 : immed=a
|
||||
"dec", // 1. 14 : immed=a
|
||||
"add a,", // 2.
|
||||
"addc a,", // 3.
|
||||
"orl a,", // 4.
|
||||
"anl a,", // 5.
|
||||
"xrl a,", // 6.
|
||||
"+#immed;mov", // 7. 74 == immed=a
|
||||
"mov direct,", // 8. 84 == DIV AB
|
||||
"subb a,", // 9.
|
||||
"+direct;mov", // A. A4 == MUL AB
|
||||
"+, $1, $2;cjne",
|
||||
// B4, B4 = {cjne a, {#immed,direct}, offset}
|
||||
// cjne arg, #immed, offset
|
||||
"xch a,", // C. C4 == SWAP A
|
||||
"+offset;djnz", // D. D4 = DA
|
||||
// D5 = DJNZ d,off
|
||||
// D6,7 = XCHD A, r0,1
|
||||
"mov a,", // E. E4 == CLR A
|
||||
"+, a;mov" // F. F4 == CPL A
|
||||
};
|
||||
|
||||
Op8051 do8051struct(const ut8 *buf, int len) {
|
||||
ut8 op = buf[0];
|
||||
if (!op) return _{ "nop", 1, NONE, 0 };
|
||||
if ((op&0xf)==1)
|
||||
return _{((op>>4)%2)? "acall": "ajmp", 2, _ADDR11(buf)};
|
||||
switch (op) {
|
||||
case 0x10: return _{ "jbc bit,", 3, _ADDR16(buf) };
|
||||
case 0x20: return _{ "jb bit,", 3, _ADDR16(buf) };
|
||||
case 0x30: return _{ "jnb bit,", 3, _ADDR16(buf) };
|
||||
case 0x40: return _{ "jc", 2, _OFFSET(buf) };
|
||||
case 0x50: return _{ "jnc", 2, _OFFSET(buf) };
|
||||
case 0x60: return _{ "jz", 2, _OFFSET(buf) };
|
||||
case 0x70: return _{ "jnz", 2, _OFFSET(buf) };
|
||||
case 0x80: return _{ "sjmp", 2, _OFFSET(buf) };
|
||||
|
||||
case 0x90: return _{ "mov dptr, #immed", 3, _ADDR16(buf) }; // XXX
|
||||
case 0xa0: return _{ "orl c, /bin", 2, NONE };
|
||||
case 0xb0: return _{ "anl c, /bin", 2, NONE };
|
||||
|
||||
case 0xc0: return _{ "push direct", 2, NONE };
|
||||
case 0xd0: return _{ "pop direct", 2, NONE };
|
||||
|
||||
case 0x02: return _{ "ljmp", 3, _ADDR16(buf) };
|
||||
case 0x12: return _{ "lcall", 3, _ADDR16(buf) };
|
||||
case 0x22: return _{ "ret", 1, NONE };
|
||||
case 0x32: return _{ "reti", 1, NONE };
|
||||
case 0x42: return _{ "orl direct, a", 2, _DIRECT (buf)};
|
||||
case 0x92: return _{ "+, c;mov", 2, _DIRECT (buf) };
|
||||
case 0xc2: return _{ "clr c", 1, _DIRECT (buf) };
|
||||
case 0xd2: return _{ "setb", 2, _DIRECT (buf) };
|
||||
case 0xa2: return _{ "mov c,", 2, _DIRECT (buf) };
|
||||
|
||||
case 0x03: return _{ "rr a", 1, NONE };
|
||||
case 0x13: return _{ "rrc a", 1, NONE };
|
||||
case 0x23: return _{ "rl a", 1, NONE };
|
||||
case 0x33: return _{ "rlc a", 1, NONE };
|
||||
case 0x43: return _{ "orl direct, #imm", 3, NONE };
|
||||
case 0x73: return _{ "jmp @a+dptr", 1, NONE };
|
||||
case 0x83: return _{ "movc a, @a+pc", 1, NONE };
|
||||
case 0x93: return _{ "movc a, @a+dptr", 1, NONE };
|
||||
case 0xa3: return _{ "inc dptr", 1, NONE };
|
||||
case 0xb3: return _{ "cpl c", 1, NONE };
|
||||
case 0xc3: return _{ "clr c", 1, NONE };
|
||||
case 0xd3: return _{ "setb c", 1, NONE };
|
||||
|
||||
case 0xe0: return _{ "movx a, @dptr", 1, NONE };
|
||||
case 0xe2: return _{ "movx a, @r0", 1, NONE };
|
||||
case 0xe3: return _{ "movx a, @r1", 1, NONE };
|
||||
case 0xf0: return _{ "movx @dptr, a", 1, NONE };
|
||||
case 0xf2: return _{ "movx @r0, a", 1, NONE };
|
||||
case 0xf3: return _{ "movx @r1, a", 1, NONE };
|
||||
}
|
||||
// general opcodes
|
||||
if ((op&0xf)>=4) {
|
||||
int opidx = (op>>4);
|
||||
int argidx = (op&0xf)-4;
|
||||
const char *opstr = ops[opidx];
|
||||
const char *argstr = arg[argidx];
|
||||
int length = ((op&0xf)<6)? 2: 1;
|
||||
/* exceptions */
|
||||
switch (op) {
|
||||
case 0x04: length = 1; opstr = "inc a"; break;
|
||||
case 0x14: length = 1; opstr = "dec a"; break;
|
||||
case 0x74: opstr = "mov a,"; break;
|
||||
case 0xa4: opstr = "mul ab"; break;
|
||||
case 0xa5: opstr = "reserved"; break;
|
||||
case 0x75: length = 3; break;
|
||||
case 0xc4: opstr = "swap a"; break;
|
||||
case 0xd4: opstr = "da a"; break;
|
||||
case 0xd5: opstr = "djnz d, "; break;
|
||||
case 0xd6: opstr = "xchd a, r0"; break;
|
||||
case 0xd7: opstr = "xchd a, r1"; break;
|
||||
case 0xe4: opstr = "clr a"; break;
|
||||
case 0xf4: opstr = "cpl a"; break;
|
||||
}
|
||||
/* exceptions */
|
||||
if (op==0x06) length = 2;
|
||||
else if (op==0x84) length = 1;
|
||||
else if (op==0x85) length = 3;
|
||||
else if (op==0x85) length = 3;
|
||||
return _{ opstr, length, _ARG (argstr) };
|
||||
}
|
||||
return _{ "xxx", 0 }; // XXX
|
||||
}
|
||||
|
||||
static char *strdup_filter (const char *str, const ut8 *buf) {
|
||||
int i, j, len = strlen (str);
|
||||
char *o = malloc (1+len*4);
|
||||
for (i=j=0; i<len; i++) {
|
||||
if (str[i] == '$') {
|
||||
int n = str[i+1];
|
||||
if (n>='0' && n<='9') {
|
||||
n -= '0';
|
||||
i++;
|
||||
j += sprintf (o+j, "0x%02x", buf[n]);
|
||||
} else eprintf ("strdup_filter: Internal bug\n");
|
||||
} else o[j++] = str[i];
|
||||
}
|
||||
o[j] = 0;
|
||||
return o;
|
||||
}
|
||||
|
||||
char *do8051disasm(Op8051 op, char *str, int len) {
|
||||
char *tmp, *eof, *out = str? str: malloc ((len=32));
|
||||
switch (op.operand) {
|
||||
case NONE: strcpy (out, op.name); break;
|
||||
case ARG: snprintf (out, len, "%s %s", op.name, op.arg); break;
|
||||
case ADDR11:
|
||||
case ADDR16: snprintf (out, len, "%s %d", op.name, op.addr); break;
|
||||
}
|
||||
if (*out == '+') {
|
||||
eof = strchr (out+1, ';');
|
||||
if (eof) {
|
||||
*eof = 0;
|
||||
tmp = strdup_filter (out+1, (const ut8*)op.buf);
|
||||
strcpy (out, eof+1);
|
||||
strcat (out, tmp);
|
||||
free (tmp);
|
||||
} else eprintf ("do8051disasm: Internal bug\n");
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
Op8051 do8051assemble(const char *str) {
|
||||
return _{"TODO"};
|
||||
}
|
||||
|
||||
#if MAIN
|
||||
|
||||
int main() {
|
||||
char *str;
|
||||
ut8 buf[3] = {0xb3, 0x11, 0x22};
|
||||
Op8051 op = do8051struct (buf, sizeof (buf));
|
||||
str = do8051disasm (op, NULL, 0);
|
||||
eprintf ("%s\n", str);
|
||||
free (str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
5
libr/asm/arch/8051/Makefile
Normal file
5
libr/asm/arch/8051/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
all:
|
||||
gcc -DMAIN 8051.c `pkg-config --cflags r_util`
|
||||
|
||||
clean:
|
||||
rm -f a.out
|
10
libr/asm/p/8051.mk
Normal file
10
libr/asm/p/8051.mk
Normal file
@ -0,0 +1,10 @@
|
||||
OBJ_8051=asm_8051.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_8051}
|
||||
TARGET_8051=asm_8051.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_8051}
|
||||
|
||||
${TARGET_8051}: ${OBJ_8051}
|
||||
${CC} $(call libname,asm_8051) ${LDFLAGS} ${CFLAGS} \
|
||||
-o asm_8051.${EXT_SO} ${OBJ_8051}
|
36
libr/asm/p/asm_8051.c
Normal file
36
libr/asm/p/asm_8051.c
Normal file
@ -0,0 +1,36 @@
|
||||
/* radare2 - LGPL - Copyright 2013 - pancake */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <r_types.h>
|
||||
#include <r_util.h>
|
||||
#include <r_lib.h>
|
||||
#include <r_asm.h>
|
||||
#include "../arch/8051/8051.c"
|
||||
|
||||
// ut64 for length here is overkill!
|
||||
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, ut64 len) {
|
||||
Op8051 o = do8051struct (buf, len);
|
||||
if (!o.name) return 0; // invalid instruction
|
||||
do8051disasm (o, op->buf_asm, sizeof (op->buf_asm));
|
||||
return (op->inst_len = o.length);
|
||||
}
|
||||
|
||||
RAsmPlugin r_asm_plugin_8051 = {
|
||||
.name = "8051",
|
||||
.arch = "8051",
|
||||
.bits = (int[]){ 16, 0 },
|
||||
.desc = "8051 assembler/disassembler",
|
||||
.init = NULL,
|
||||
.fini = NULL,
|
||||
.disassemble = &disassemble,
|
||||
.assemble = NULL
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
struct r_lib_struct_t radare_plugin = {
|
||||
.type = R_LIB_TYPE_ASM,
|
||||
.data = &r_asm_plugin_8051
|
||||
};
|
||||
#endif
|
@ -170,6 +170,7 @@ extern RAsmPlugin r_asm_plugin_m68k;
|
||||
extern RAsmPlugin r_asm_plugin_arc;
|
||||
extern RAsmPlugin r_asm_plugin_rar;
|
||||
extern RAsmPlugin r_asm_plugin_dcpu16;
|
||||
extern RAsmPlugin r_asm_plugin_8051;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -347,6 +347,7 @@ extern RIOPlugin r_io_plugin_w32;
|
||||
extern RIOPlugin r_io_plugin_ewf;
|
||||
extern RIOPlugin r_io_plugin_zip;
|
||||
extern RIOPlugin r_io_plugin_mmap;
|
||||
extern RIOPlugin r_io_plugin_ihex;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
18
libr/io/p/ihex.mk
Normal file
18
libr/io/p/ihex.mk
Normal file
@ -0,0 +1,18 @@
|
||||
OBJ_IHEX=io_ihex.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_IHEX}
|
||||
TARGET_IHEX=io_ihex.${EXT_SO}
|
||||
ALL_TARGETS+=${TARGET_IHEX}
|
||||
|
||||
ifeq (${WITHPIC},0)
|
||||
LINKFLAGS+=../../util/libr_util.a
|
||||
LINKFLAGS+=../../lib/libr_lib.a
|
||||
LINKFLAGS+=../../io/libr_io.a
|
||||
else
|
||||
LINKFLAGS+=-L../../lib -lr_lib
|
||||
LINKFLAGS+=-L../../util -lr_util
|
||||
LINKFLAGS+=-L.. -L../../lib -lr_lib -lr_io
|
||||
endif
|
||||
|
||||
${TARGET_IHEX}: ${OBJ_IHEX}
|
||||
${CC_LIB} $(call libname,io_hex) ${CFLAGS} -o ${TARGET_IHEX} ${OBJ_IHEX} ${LINKFLAGS}
|
211
libr/io/p/io_ihex.c
Normal file
211
libr/io/p/io_ihex.c
Normal file
@ -0,0 +1,211 @@
|
||||
/* radare - LGPL - Copyright 2013 - pancake */
|
||||
|
||||
#include "r_io.h"
|
||||
#include "r_lib.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#define MEMSIZE 0x10000
|
||||
|
||||
typedef struct {
|
||||
int fd;
|
||||
ut8 *buf;
|
||||
ut32 size;
|
||||
} RIOMalloc;
|
||||
|
||||
#define RIOHEX_FD(x) (((RIOMalloc*)x->data)->fd)
|
||||
#define RIOHEX_SZ(x) (((RIOMalloc*)x->data)->size)
|
||||
#define RIOHEX_BUF(x) (((RIOMalloc*)x->data)->buf)
|
||||
|
||||
static int __write(RIO *io, RIODesc *fd, const ut8 *buf, int count) {
|
||||
const char *ffffuuuu = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
|
||||
"\xff\xff\xff\xff\xff\xff";
|
||||
const char *pathname;
|
||||
const ut8 *b;
|
||||
ut8 cksum;
|
||||
FILE *out;
|
||||
int i, j;
|
||||
if (fd == NULL || fd->data == NULL)
|
||||
return -1;
|
||||
pathname = fd->name + 7;
|
||||
out = fopen (pathname, "w");
|
||||
if (!out) {
|
||||
eprintf ("Cannot open '%s' for writing\n", pathname);
|
||||
return -1;
|
||||
}
|
||||
/* mem write */
|
||||
if (io->off+count > RIOHEX_SZ (fd))
|
||||
count -= (io->off+count-(RIOHEX_SZ (fd)));
|
||||
if (count>0)
|
||||
memcpy (RIOHEX_BUF (fd)+io->off, buf, count);
|
||||
/* disk write */
|
||||
for (i=0; i<MEMSIZE; i+=0x10) {
|
||||
b = RIOHEX_BUF (fd)+i;
|
||||
if (memcmp (ffffuuuu, b, 0x10)) {
|
||||
cksum = 0x10;
|
||||
cksum += i>>8;
|
||||
cksum += i;
|
||||
for (j=0; j<0x10; j++) cksum += b[j];
|
||||
cksum = 0-cksum;
|
||||
fprintf (out, ":10%04x00%02x%02x%02x%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
|
||||
i, b[0], b[1], b[2], b[3], b[4], b[5], b[6],
|
||||
b[7], b[8], b[9], b[10], b[11], b[12], b[13],
|
||||
b[14], b[15], cksum);
|
||||
}
|
||||
}
|
||||
fprintf (out, ":00000001FF\n");
|
||||
fclose (out);
|
||||
return count;
|
||||
}
|
||||
|
||||
static int __read(RIO *io, RIODesc *fd, ut8 *buf, int count) {
|
||||
memset (buf, 0xff, count);
|
||||
if (fd == NULL || fd->data == NULL)
|
||||
return -1;
|
||||
if (io->off>= RIOHEX_SZ (fd))
|
||||
return -1;
|
||||
if (io->off+count >= RIOHEX_SZ (fd))
|
||||
count = RIOHEX_SZ (fd) - io->off;
|
||||
memcpy (buf, RIOHEX_BUF (fd)+io->off, count);
|
||||
return count;
|
||||
}
|
||||
|
||||
static int __close(RIODesc *fd) {
|
||||
RIOMalloc *riom;
|
||||
if (fd == NULL || fd->data == NULL)
|
||||
return -1;
|
||||
riom = fd->data;
|
||||
free (riom->buf);
|
||||
riom->buf = NULL;
|
||||
free (fd->data);
|
||||
fd->data = NULL;
|
||||
fd->state = R_IO_DESC_TYPE_CLOSED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ut64 __lseek(struct r_io_t *io, RIODesc *fd, ut64 offset, int whence) {
|
||||
switch (whence) {
|
||||
case SEEK_SET: return offset;
|
||||
case SEEK_CUR: return io->off + offset;
|
||||
case SEEK_END: return RIOHEX_SZ (fd);
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int __plugin_open(RIO *io, const char *pathname) {
|
||||
return (!memcmp (pathname, "ihex://", 7));
|
||||
}
|
||||
|
||||
#if 0
|
||||
:10010000214601360121470136007EFE09D2190140
|
||||
:100110002146017EB7C20001FF5F16002148011988
|
||||
:10012000194E79234623965778239EDA3F01B2CAA7
|
||||
:100130003F0156702B5E712B722B732146013421C7
|
||||
:00000001FF
|
||||
|
||||
: Start code
|
||||
1 Byte count
|
||||
2 byte Address
|
||||
1 byte Record type (00 data 01 eof)
|
||||
N byets Data
|
||||
1 byte Checksum (sum 00)
|
||||
#endif
|
||||
|
||||
// TODO: implement bin2ihex function
|
||||
static int ihex2bin(ut8 *mem, char *str) {
|
||||
ut32 addr = 0;
|
||||
char *eol, *ptr = str;
|
||||
ut8 cksum, *memptr;
|
||||
int bc, type, byte, i, l, blen = 0;
|
||||
do {
|
||||
l = sscanf (ptr, ":%02x%04x%02x", &bc, &addr, &type);
|
||||
if (l != 3) {
|
||||
eprintf ("Invalid data in ihex file (%s)\n", ptr);
|
||||
break;
|
||||
}
|
||||
l = 1+ (l*2);
|
||||
switch (type) {
|
||||
case 0: // DATA
|
||||
eol = strchr (ptr+1, ':');
|
||||
if (eol) *eol = 0;
|
||||
cksum = bc;
|
||||
cksum += addr>>8;
|
||||
cksum += addr&0xff;
|
||||
cksum += type;
|
||||
memptr = mem + addr;
|
||||
if ((addr+bc)>MEMSIZE)
|
||||
bc = MEMSIZE-addr;
|
||||
for (i=0; i<bc; i++) {
|
||||
sscanf (ptr+9+ (i*2), "%02x", &byte);
|
||||
memptr[i] = byte;
|
||||
cksum += byte;
|
||||
}
|
||||
if (eol) {
|
||||
// checksum
|
||||
sscanf (ptr+9+(i*2), "%02x", &byte);
|
||||
cksum += byte;
|
||||
if (cksum != 0) {
|
||||
ut8 fixedcksum = 0-(cksum-byte);
|
||||
eprintf ("Checksum failed %02x (got %02x expected %02x)\n",
|
||||
cksum, byte, fixedcksum);
|
||||
}
|
||||
*eol = ':';
|
||||
}
|
||||
ptr = eol;
|
||||
break;
|
||||
case 1: // EOF
|
||||
ptr = NULL;
|
||||
}
|
||||
} while (ptr);
|
||||
|
||||
return blen;
|
||||
}
|
||||
|
||||
static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) {
|
||||
int ret;
|
||||
RIOMalloc *mal;
|
||||
char *str;
|
||||
if (__plugin_open (io, pathname)) {
|
||||
mal->fd = -1; /* causes r_io_desc_new() to set the correct fd */
|
||||
str = r_file_slurp (pathname+7, NULL);
|
||||
if (!str) return NULL;
|
||||
mal = R_NEW (RIOMalloc);
|
||||
if (!mal) {
|
||||
free (str);
|
||||
return NULL;
|
||||
}
|
||||
mal->buf = malloc (MEMSIZE);
|
||||
if (!mal->buf) {
|
||||
free (str);
|
||||
free (mal);
|
||||
return NULL;
|
||||
}
|
||||
mal->size = MEMSIZE;
|
||||
memset (mal->buf, 0xff, mal->size);
|
||||
ret = ihex2bin (mal->buf, str);
|
||||
if (ret) eprintf ("ihex: checksum issues?\n");
|
||||
return r_io_desc_new (&r_io_plugin_ihex,
|
||||
mal->fd, pathname, rw, mode, mal);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RIOPlugin r_io_plugin_ihex = {
|
||||
.name = "ihex",
|
||||
.desc = "Intel HEX file (ihex://eeproms.hex)",
|
||||
.open = __open,
|
||||
.close = __close,
|
||||
.read = __read,
|
||||
.plugin_open = __plugin_open,
|
||||
.lseek = __lseek,
|
||||
.write = __write,
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
struct r_lib_struct_t radare_plugin = {
|
||||
.type = R_LIB_TYPE_IO,
|
||||
.data = &r_io_plugin_hex
|
||||
};
|
||||
#endif
|
@ -26,6 +26,7 @@ asm.x86_olly
|
||||
asm.x86_nz
|
||||
asm.z80
|
||||
asm.i8080
|
||||
asm.8051
|
||||
asm.msil
|
||||
anal.sh
|
||||
anal.x86_im
|
||||
@ -103,6 +104,7 @@ io.mach
|
||||
io.w32
|
||||
io.w32dbg
|
||||
io.malloc
|
||||
io.ihex
|
||||
io.ptrace
|
||||
io.procpid
|
||||
io.shm
|
||||
|
Loading…
x
Reference in New Issue
Block a user