1 /* radare - LGPL - Copyright 2009-2014 - pancake */
2 
3 #include <r_types.h>
4 #include <r_lib.h>
5 #include <r_asm.h>
6 #include <r_anal.h>
7 
8 // NOTE: buf should be at least 16 bytes!
9 // XXX addr should be off_t for 64 love
ppc_op(RAnal * anal,RAnalOp * op,ut64 addr,const ut8 * bytes,int len,RAnalOpMask mask)10 static int ppc_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *bytes, int len, RAnalOpMask mask) {
11 //int arch_ppc_op(ut64 addr, const u8 *bytes, struct op_t *op)
12 	// XXX hack
13 	int opcode = (bytes[0] & 0xf8) >> 3; // bytes 0-5
14 	short baddr = ((bytes[2]<<8) | (bytes[3]&0xfc));// 16-29
15 	int aa = bytes[3]&0x2;
16 	int lk = bytes[3]&0x1;
17 	//if (baddr>0x7fff)
18 	//      baddr = -baddr;
19 
20 	op->addr = addr;
21 	op->type = 0;
22 	op->size = 4;
23 
24 	//eprintf("OPCODE IS %08x : %02x (opcode=%d) baddr = %d\n", addr, bytes[0], opcode, baddr);
25 
26 	switch (opcode) {
27 //	case 0: // bl op->type = R_ANAL_OP_TYPE_NOP; break;
28 	case 11: // cmpi
29 		op->type = R_ANAL_OP_TYPE_CMP;
30 		break;
31 	case 9: // pure branch
32 		if (bytes[0] == 0x4e) {
33 			// bctr
34 		} else {
35 			op->jump = (aa)?(baddr):(addr+baddr);
36 			if (lk) {
37 				op->fail = addr + 4;
38 			}
39 		}
40 		op->eob = 1;
41 		break;
42 	case 6: // bc // conditional jump
43 		op->type = R_ANAL_OP_TYPE_JMP;
44 		op->jump = (aa)?(baddr):(addr+baddr+4);
45 		op->eob = 1;
46 		break;
47 #if 0
48 	case 7: // sc/svc
49 		op->type = R_ANAL_OP_TYPE_SWI;
50 		break;
51 #endif
52 #if 0
53 	case 15: // bl
54 		// OK
55 		op->type = R_ANAL_OP_TYPE_CJMP;
56 		op->jump = (aa)?(baddr):(addr+baddr);
57 		op->fail = addr+4;
58 		op->eob = 1;
59 		break;
60 #endif
61 	case 8: // bne i tal
62 		// OK
63 		op->type = R_ANAL_OP_TYPE_CJMP;
64 		op->jump = (aa)?(baddr):(addr+baddr+4);
65 		op->fail = addr+4;
66 		op->eob = 1;
67 		break;
68 	case 19: // bclr/bcr/bcctr/bcc
69 		op->type = R_ANAL_OP_TYPE_RET; // jump to LR
70 		if (lk) {
71 			op->jump = 0xFFFFFFFF; // LR ?!?
72 			op->fail = addr+4;
73 		}
74 		op->eob = 1;
75 		break;
76 	}
77 	op->size = 4;
78 	return op->size;
79 }
80 
set_reg_profile(RAnal * anal)81 static bool set_reg_profile(RAnal *anal) {
82     const char *p =
83 	"=PC	srr0\n"
84 	"=SR	srr1\n" // status register
85 	"=A0	r0\n"
86 	"=A1	r1\n"
87 	"=A2	r2\n"
88 	"=A3	r3\n"
89 #if 0
90 	"=a4	r4\n"
91 	"=a5	r5\n"
92 	"=a6	r6\n"
93 	"=a7	r7\n"
94 #endif
95 	"gpr	srr0	.32	0	0\n"
96 	"gpr	srr1	.32	4	0\n"
97 	"gpr	r0	.32	8	0\n"
98 	"gpr	r1	.32	12	0\n"
99 	"gpr	r2	.32	16	0\n"
100 	"gpr	r3	.32	20	0\n"
101 	"gpr	r4	.32	24	0\n"
102 	"gpr	r5	.32	28	0\n"
103 	"gpr	r6	.32	32	0\n"
104 	"gpr	r7	.32	36	0\n"
105 	"gpr	r8	.32	40	0\n"
106 	"gpr	r9	.32	44	0\n"
107 	"gpr	r10	.32	48	0\n"
108 	"gpr	r11	.32	52	0\n"
109 	"gpr	r12	.32	56	0\n"
110 	"gpr	r13	.32	60	0\n"
111 	"gpr	r14	.32	64	0\n"
112 	"gpr	r15	.32	68	0\n"
113 	"gpr	r16	.32	72	0\n"
114 	"gpr	r17	.32	76	0\n"
115 	"gpr	r18	.32	80	0\n"
116 	"gpr	r19	.32	84	0\n"
117 	"gpr	r20	.32	88	0\n"
118 	"gpr	r21	.32	92	0\n"
119 	"gpr	r22	.32	96	0\n"
120 
121 	"gpr	r23	.32	100	0\n"
122 	"gpr	r24	.32	104	0\n"
123 	"gpr	r25	.32	108	0\n"
124 	"gpr	r26	.32	112	0\n"
125 	"gpr	r27	.32	116	0\n"
126 	"gpr	r28	.32	120	0\n"
127 	"gpr	r29	.32	124	0\n"
128 	"gpr	r30	.32	128	0\n"
129 	"gpr	r31	.32	132	0\n"
130 	"gpr	cr	.32	136	0\n"
131 	"gpr	xer	.32	140	0\n"
132 	"gpr	lr	.32	144	0\n"
133 	"gpr	ctr	.32	148	0\n"
134 	"gpr	mq	.32	152	0\n"
135 	"gpr	vrsave	.32	156	0\n";
136 	return r_reg_set_profile_string (anal->reg, p);
137 }
138 
archinfo(RAnal * anal,int q)139 static int archinfo(RAnal *anal, int q) {
140 	return 4; /* :D */
141 }
142 
143 RAnalPlugin r_anal_plugin_ppc_gnu = {
144 	.name = "ppc.gnu",
145 	.desc = "PowerPC analysis plugin",
146 	.license = "LGPL3",
147 	.arch = "ppc",
148 	.archinfo = archinfo,
149 	.bits = 32|64,
150 	.op = &ppc_op,
151 	.set_reg_profile = &set_reg_profile,
152 };
153 
154 #ifndef R2_PLUGIN_INCORE
155 R_API RLibStruct radare_plugin = {
156 	.type = R_LIB_TYPE_ANAL,
157 	.data = &r_anal_plugin_ppc_gnu,
158 	.version = R2_VERSION
159 };
160 #endif
161 
162 #if 0
163 NOTES:
164 ======
165      10000
166      AA = absolute address
167      LK = link bit
168      BD = bits 16-19
169        address
170      if (AA) {
171        address = (int32) BD << 2
172      } else {
173        address += (int32) BD << 2
174      }
175     AA LK
176     30 31
177      0  0  bc
178      1  0  bca
179      0  1  bcl
180      1  1  bcla
181 
182      10011
183      BCCTR
184      LK = 31
185 
186      bclr or bcr (Branch Conditional Link Register) Instruction
187      10011
188 
189      6-29 -> LL (addr) ?
190      B  10010 -> branch
191      30 31
192      0  0   b
193      1  0   ba
194      0  1   bl
195      1  1   bla
196      SC SYSCALL 5 first bytes 10001
197      SVC SUPERVISORCALL
198      30 31
199      0  0  svc
200      0  1  svcl
201      1  0  svca
202      1  1  svcla
203 #endif
204