mirror of
https://github.com/radareorg/radare2.git
synced 2024-12-12 15:38:09 +00:00
206 lines
4.1 KiB
C
206 lines
4.1 KiB
C
/* radare - LGPL - Copyright 2009-2012 pancake<nopcode.org> */
|
|
|
|
#include <r_types.h>
|
|
#include <r_lib.h>
|
|
#include <r_asm.h>
|
|
#include <r_anal.h>
|
|
|
|
// NOTE: buf should be at least 16 bytes!
|
|
// XXX addr should be off_t for 64 love
|
|
static int ppc_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *_bytes, int len) {
|
|
//int arch_ppc_op(ut64 addr, const u8 *bytes, struct op_t *op)
|
|
// TODO swap endian here??
|
|
char bytes[1024];
|
|
r_mem_copyendian ((ut8*)bytes, _bytes, 4, 1);
|
|
// XXX hack
|
|
int opcode = (bytes[0] & 0xf8) >> 3; // bytes 0-5
|
|
short baddr = ((bytes[2]<<8) | (bytes[3]&0xfc));// 16-29
|
|
int aa = bytes[3]&0x2;
|
|
int lk = bytes[3]&0x1;
|
|
//if (baddr>0x7fff)
|
|
// baddr = -baddr;
|
|
|
|
memset (op, '\0', sizeof (RAnalOp));
|
|
op->addr = addr;
|
|
op->type = 0;
|
|
op->size = 4;
|
|
|
|
//eprintf("OPCODE IS %08x : %02x (opcode=%d) baddr = %d\n", addr, bytes[0], opcode, baddr);
|
|
|
|
switch (opcode) {
|
|
// case 0: // bl op->type = R_ANAL_OP_TYPE_NOP; break;
|
|
case 11: // cmpi
|
|
op->type = R_ANAL_OP_TYPE_CMP;
|
|
break;
|
|
case 9: // pure branch
|
|
if (bytes[0] == 0x4e) {
|
|
// bctr
|
|
} else {
|
|
op->jump = (aa)?(baddr):(addr+baddr);
|
|
if (lk) op->fail = addr+4;
|
|
}
|
|
op->eob = 1;
|
|
break;
|
|
case 6: // bc // conditional jump
|
|
op->type = R_ANAL_OP_TYPE_JMP;
|
|
op->jump = (aa)?(baddr):(addr+baddr+4);
|
|
op->eob = 1;
|
|
break;
|
|
#if 0
|
|
case 7: // sc/svc
|
|
op->type = R_ANAL_OP_TYPE_SWI;
|
|
break;
|
|
#endif
|
|
#if 0
|
|
case 15: // bl
|
|
// OK
|
|
op->type = R_ANAL_OP_TYPE_CJMP;
|
|
op->jump = (aa)?(baddr):(addr+baddr);
|
|
op->fail = addr+4;
|
|
op->eob = 1;
|
|
break;
|
|
#endif
|
|
case 8: // bne i tal
|
|
// OK
|
|
op->type = R_ANAL_OP_TYPE_CJMP;
|
|
op->jump = (aa)?(baddr):(addr+baddr+4);
|
|
op->fail = addr+4;
|
|
op->eob = 1;
|
|
break;
|
|
case 19: // bclr/bcr/bcctr/bcc
|
|
op->type = R_ANAL_OP_TYPE_RET; // jump to LR
|
|
if (lk) {
|
|
op->jump = 0xFFFFFFFF; // LR ?!?
|
|
op->fail = addr+4;
|
|
}
|
|
op->eob = 1;
|
|
break;
|
|
}
|
|
op->size = 4;
|
|
return op->size;
|
|
}
|
|
|
|
static int set_reg_profile(RAnal *anal) {
|
|
const char *p = "=pc srr0\n"
|
|
"=sr srr1\n" // status register
|
|
"=a0 r0\n"
|
|
"=a1 r1\n"
|
|
"=a2 r2\n"
|
|
"=a3 r3\n"
|
|
#if 0
|
|
"=a4 r4\n"
|
|
"=a5 r5\n"
|
|
"=a6 r6\n"
|
|
"=a7 r7\n"
|
|
#endif
|
|
"gpr srr0 .32 0 0\n"
|
|
"gpr srr1 .32 4 0\n"
|
|
"gpr r0 .32 8 0\n"
|
|
"gpr r1 .32 12 0\n"
|
|
"gpr r2 .32 16 0\n"
|
|
"gpr r3 .32 20 0\n"
|
|
"gpr r4 .32 24 0\n"
|
|
"gpr r5 .32 28 0\n"
|
|
"gpr r6 .32 32 0\n"
|
|
"gpr r7 .32 36 0\n"
|
|
"gpr r8 .32 40 0\n"
|
|
"gpr r9 .32 44 0\n"
|
|
"gpr r10 .32 48 0\n"
|
|
"gpr r11 .32 52 0\n"
|
|
"gpr r12 .32 56 0\n"
|
|
"gpr r13 .32 60 0\n"
|
|
"gpr r14 .32 64 0\n"
|
|
"gpr r15 .32 68 0\n"
|
|
"gpr r16 .32 72 0\n"
|
|
"gpr r17 .32 76 0\n"
|
|
"gpr r18 .32 80 0\n"
|
|
"gpr r19 .32 84 0\n"
|
|
"gpr r20 .32 88 0\n"
|
|
"gpr r21 .32 92 0\n"
|
|
"gpr r22 .32 96 0\n"
|
|
|
|
"gpr r23 .32 100 0\n"
|
|
"gpr r24 .32 104 0\n"
|
|
"gpr r25 .32 108 0\n"
|
|
"gpr r26 .32 112 0\n"
|
|
"gpr r27 .32 116 0\n"
|
|
"gpr r28 .32 120 0\n"
|
|
"gpr r29 .32 124 0\n"
|
|
"gpr r30 .32 128 0\n"
|
|
"gpr r31 .32 132 0\n"
|
|
"gpr cr .32 136 0\n"
|
|
"gpr xer .32 140 0\n"
|
|
"gpr lr .32 144 0\n"
|
|
"gpr ctr .32 148 0\n"
|
|
"gpr mq .32 152 0\n"
|
|
"gpr vrsave .32 156 0\n";
|
|
return r_reg_set_profile_string (anal->reg, p);
|
|
}
|
|
|
|
struct r_anal_plugin_t r_anal_plugin_ppc = {
|
|
.name = "ppc",
|
|
.desc = "PowerPC analysis plugin",
|
|
.license = "LGPL3",
|
|
.arch = R_SYS_ARCH_PPC,
|
|
.bits = 32|64,
|
|
.init = NULL,
|
|
.fini = NULL,
|
|
.op = &ppc_op,
|
|
.set_reg_profile = &set_reg_profile,
|
|
.fingerprint_bb = NULL,
|
|
.fingerprint_fcn = NULL,
|
|
.diff_bb = NULL,
|
|
.diff_fcn = NULL,
|
|
.diff_eval = NULL
|
|
};
|
|
|
|
#ifndef CORELIB
|
|
struct r_lib_struct_t radare_plugin = {
|
|
.type = R_LIB_TYPE_ANAL,
|
|
.data = &r_anal_plugin_ppc
|
|
};
|
|
#endif
|
|
|
|
#if 0
|
|
NOTES:
|
|
======
|
|
10000
|
|
AA = absolute address
|
|
LK = link bit
|
|
BD = bits 16-19
|
|
address
|
|
if (AA) {
|
|
address = (int32) BD << 2
|
|
} else {
|
|
address += (int32) BD << 2
|
|
}
|
|
AA LK
|
|
30 31
|
|
0 0 bc
|
|
1 0 bca
|
|
0 1 bcl
|
|
1 1 bcla
|
|
|
|
10011
|
|
BCCTR
|
|
LK = 31
|
|
|
|
bclr or bcr (Branch Conditional Link Register) Instruction
|
|
10011
|
|
|
|
6-29 -> LL (addr) ?
|
|
B 10010 -> branch
|
|
30 31
|
|
0 0 b
|
|
1 0 ba
|
|
0 1 bl
|
|
1 1 bla
|
|
SC SYSCALL 5 first bytes 10001
|
|
SVC SUPERVISORCALL
|
|
30 31
|
|
0 0 svc
|
|
0 1 svcl
|
|
1 0 svca
|
|
1 1 svcla
|
|
#endif
|