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