1 /* radare - LGPL - Copyright 2009-2016 - pancake, defragger, madprogrammer */
2
3 #include <r_asm.h>
4 #include <r_debug.h>
5 #include <libqnxr.h>
6
7 /* HACK_FOR_PLUGIN_LINKAGE */
__r_debug_pid_new(const char * path,int pid,char status,ut64 pc)8 R_API RDebugPid *__r_debug_pid_new(const char *path, int pid, char status, ut64 pc) {
9 RDebugPid *p = R_NEW0 (RDebugPid);
10 if (!p) {
11 return NULL;
12 }
13 p->path = strdup (path);
14 p->pid = pid;
15 p->status = status;
16 p->runnable = true;
17 p->pc = pc;
18 return p;
19 }
__r_debug_pid_free(RDebugPid * pid)20 R_API void *__r_debug_pid_free(RDebugPid *pid) {
21 free (pid->path);
22 free (pid);
23 return NULL;
24 }
25 /* ------------------- */
26
27 typedef struct {
28 libqnxr_t desc;
29 } RIOQnx;
30
31 static libqnxr_t *desc = NULL;
32 static ut8 *reg_buf = NULL;
33 static int buf_size = 0;
34
pidlist_cb(void * ctx,pid_t pid,char * name)35 static void pidlist_cb (void *ctx, pid_t pid, char *name) {
36 RList *list = ctx;
37 r_list_append (list, __r_debug_pid_new (name, pid, 's', 0));
38 }
39
r_debug_qnx_select(RDebug * dbg,int pid,int tid)40 static int r_debug_qnx_select (RDebug *dbg, int pid, int tid) {
41 return qnxr_select (desc, pid, tid);
42 }
43
r_debug_qnx_tids(RDebug * dbg,int pid)44 static RList *r_debug_qnx_tids (RDebug *dbg, int pid) {
45 eprintf ("%s: TODO: Threads\n", __func__);
46 return NULL;
47 }
48
49
r_debug_qnx_pids(RDebug * dbg,int pid)50 static RList *r_debug_qnx_pids (RDebug *dbg, int pid) {
51 RList *list = r_list_new ();
52 if (!list) {
53 return NULL;
54 }
55 list->free = (RListFree)&__r_debug_pid_free;
56
57 /* TODO */
58 if (pid) {
59 r_list_append (list, __r_debug_pid_new ("(current)", pid, 's', 0));
60 } else {
61 qnxr_pidlist (desc, list, &pidlist_cb);
62 }
63
64 return list;
65 }
66
r_debug_qnx_reg_read(RDebug * dbg,int type,ut8 * buf,int size)67 static int r_debug_qnx_reg_read (RDebug *dbg, int type, ut8 *buf, int size) {
68 int copy_size;
69 int buflen = 0;
70 if (!desc) {
71 return -1;
72 }
73 int len = qnxr_read_registers (desc);
74 if (len <= 0) {
75 return -1;
76 }
77 // read the len of the current area
78 free (r_reg_get_bytes (dbg->reg, type, &buflen));
79 if (size < len) {
80 eprintf ("r_debug_qnx_reg_read: small buffer %d vs %d\n",
81 (int)size, (int)len);
82 }
83 copy_size = R_MIN (len, size);
84 buflen = R_MAX (len, buflen);
85 if (reg_buf) {
86 if (buf_size < copy_size) {
87 ut8 *new_buf = realloc (reg_buf, copy_size);
88 if (!new_buf) {
89 return -1;
90 }
91 reg_buf = new_buf;
92 buflen = copy_size;
93 buf_size = len;
94 }
95 } else {
96 reg_buf = calloc (buflen, 1);
97 if (!reg_buf) {
98 return -1;
99 }
100 buf_size = buflen;
101 }
102 memset ((void *)(volatile void *) buf, 0, size);
103 memcpy ((void *)(volatile void *) buf, desc->recv.data, copy_size);
104 memset ((void *)(volatile void *) reg_buf, 0, buflen);
105 memcpy ((void *)(volatile void *) reg_buf, desc->recv.data, copy_size);
106
107 return len;
108 }
109
r_debug_qnx_map_get(RDebug * dbg)110 static RList *r_debug_qnx_map_get (RDebug *dbg) {
111 return NULL;
112 }
113
r_debug_qnx_reg_write(RDebug * dbg,int type,const ut8 * buf,int size)114 static int r_debug_qnx_reg_write (RDebug *dbg, int type, const ut8 *buf, int size) {
115 int buflen = 0;
116 int bits = dbg->anal->bits;
117 const char *pcname = r_reg_get_name (dbg->anal->reg, R_REG_NAME_PC);
118 RRegItem *reg = r_reg_get (dbg->anal->reg, pcname, 0);
119 if (!reg_buf) {
120 // we cannot write registers before we once read them
121 return -1;
122 }
123 if (reg) {
124 if (dbg->anal->bits != reg->size) {
125 bits = reg->size;
126 }
127 }
128 free (r_reg_get_bytes (dbg->reg, type, &buflen));
129 // some implementations of the gdb protocol are acting weird.
130 // so winedbg is not able to write registers through the <G> packet
131 // and also it does not return the whole gdb register profile after
132 // calling <g>
133 // so this workaround resizes the small register profile buffer
134 // to the whole set and fills the rest with 0
135 if (buf_size < buflen) {
136 ut8 *new_buf = realloc (reg_buf, buflen * sizeof (ut8));
137 if (!new_buf) {
138 return -1;
139 }
140 reg_buf = new_buf;
141 memset (new_buf + buf_size, 0, buflen - buf_size);
142 }
143
144 RRegItem *current = NULL;
145 for (;;) {
146 current = r_reg_next_diff (dbg->reg, type, reg_buf, buflen, current, bits);
147 if (!current) {
148 break;
149 }
150 ut64 val = r_reg_get_value (dbg->reg, current);
151 int bytes = bits / 8;
152 qnxr_write_reg (desc, current->name, (char *)&val, bytes);
153 }
154 return true;
155 }
156
r_debug_qnx_continue(RDebug * dbg,int pid,int tid,int sig)157 static int r_debug_qnx_continue (RDebug *dbg, int pid, int tid, int sig) {
158 qnxr_continue (desc, -1);
159 return true;
160 }
161
r_debug_qnx_step(RDebug * dbg)162 static int r_debug_qnx_step (RDebug *dbg) {
163 qnxr_step (desc, -1);
164 return true;
165 }
166
r_debug_qnx_wait(RDebug * dbg,int pid)167 static int r_debug_qnx_wait (RDebug *dbg, int pid) {
168 ptid_t ptid = qnxr_wait (desc, pid);
169 if (!ptid_equal (ptid, null_ptid)) {
170 dbg->reason.signum = desc->signal;
171 return desc->notify_type;
172 }
173 return 0;
174 }
175
r_debug_qnx_stop(RDebug * dbg)176 static int r_debug_qnx_stop (RDebug *dbg) {
177 qnxr_stop (desc);
178 return true;
179 }
180
r_debug_qnx_attach(RDebug * dbg,int pid)181 static int r_debug_qnx_attach (RDebug *dbg, int pid) {
182 RIODesc *d = dbg->iob.io->desc;
183 dbg->swstep = false;
184
185 if (d && d->plugin && d->plugin->name && d->data) {
186 if (!strcmp ("qnx", d->plugin->name)) {
187 RIOQnx *g = d->data;
188 int arch = r_sys_arch_id (dbg->arch);
189 int bits = dbg->anal->bits;
190 if ((desc = &g->desc)) {
191 switch (arch) {
192 case R_SYS_ARCH_X86:
193 if (bits == 16 || bits == 32) {
194 qnxr_set_architecture (&g->desc, X86_32);
195 } else {
196 eprintf ("Not supported register %s %d profile\n", dbg->arch, bits);
197 return false;
198 }
199 break;
200 case R_SYS_ARCH_ARM:
201 if (bits == 16 || bits == 32) {
202 qnxr_set_architecture (&g->desc, ARM_32);
203 } else {
204 eprintf ("Not supported register %s %d profile\n", dbg->arch, bits);
205 return false;
206 }
207 break;
208 }
209 }
210 if (pid) {
211 qnxr_attach (desc, pid);
212 }
213 } else {
214 eprintf ("%s: error: underlying IO descriptor isn't a QNX one\n", __func__);
215 return false;
216 }
217 }
218
219 dbg->pid = 0;
220 return true;
221 }
222
r_debug_qnx_detach(RDebug * dbg,int pid)223 static int r_debug_qnx_detach (RDebug *dbg, int pid) {
224 qnxr_disconnect (desc);
225 free (reg_buf);
226 return true;
227 }
228
r_debug_qnx_reg_profile(RDebug * dbg)229 static const char *r_debug_qnx_reg_profile (RDebug *dbg) {
230 int arch = r_sys_arch_id (dbg->arch);
231 int bits = dbg->anal->bits;
232 switch (arch) {
233 case R_SYS_ARCH_X86:
234 return strdup (
235 "=PC eip\n"
236 "=SP esp\n"
237 "=BP ebp\n"
238 "=A0 eax\n"
239 "=A1 ebx\n"
240 "=A2 ecx\n"
241 "=A3 edi\n"
242 "gpr eax .32 0 0\n"
243 "gpr ecx .32 4 0\n"
244 "gpr edx .32 8 0\n"
245 "gpr ebx .32 12 0\n"
246 "gpr esp .32 16 0\n"
247 "gpr ebp .32 20 0\n"
248 "gpr esi .32 24 0\n"
249 "gpr edi .32 28 0\n"
250 "gpr eip .32 32 0\n"
251 "gpr eflags .32 36 0\n"
252 "seg cs .32 40 0\n"
253 "seg ss .32 44 0\n"
254 #if 0
255 "seg ds .32 48 0\n"
256 "seg es .32 52 0\n"
257 "seg fs .32 56 0\n"
258 "seg gs .32 60 0\n"
259 #endif
260 );
261 case R_SYS_ARCH_ARM:
262 if (bits == 32) {
263 return strdup (
264 "=PC r15\n"
265 "=SP r14\n" // XXX
266 "=A0 r0\n"
267 "=A1 r1\n"
268 "=A2 r2\n"
269 "=A3 r3\n"
270 "gpr r0 .32 0 0\n"
271 "gpr r1 .32 4 0\n"
272 "gpr r2 .32 8 0\n"
273 "gpr r3 .32 12 0\n"
274 "gpr r4 .32 16 0\n"
275 "gpr r5 .32 20 0\n"
276 "gpr r6 .32 24 0\n"
277 "gpr r7 .32 28 0\n"
278 "gpr r8 .32 32 0\n"
279 "gpr r9 .32 36 0\n"
280 "gpr r10 .32 40 0\n"
281 "gpr r11 .32 44 0\n"
282 "gpr r12 .32 48 0\n"
283 "gpr sp .32 52 0\n" // r13
284 "gpr lr .32 56 0\n" // r14
285 "gpr pc .32 60 0\n" // r15
286 "gpr r13 .32 52 0\n"
287 "gpr r14 .32 56 0\n"
288 "gpr r15 .32 60 0\n"
289 "gpr cpsr .96 64 0\n"
290 "mmx d0 .64 68 0\n" // neon
291 "mmx d1 .64 76 0\n" // neon
292 "mmx d2 .64 84 0\n" // neon
293 "mmx d3 .64 92 0\n" // neon
294 "mmx d4 .64 100 0\n" // neon
295 "mmx d5 .64 108 0\n" // neon
296 "mmx d6 .64 116 0\n" // neon
297 "mmx d7 .64 124 0\n" // neon
298 "mmx d8 .64 132 0\n" // neon
299 "mmx d9 .64 140 0\n" // neon
300 "mmx d10 .64 148 0\n" // neon
301 "mmx d11 .64 156 0\n" // neon
302 "mmx d12 .64 164 0\n" // neon
303 "mmx d13 .64 172 0\n" // neon
304 "mmx d14 .64 180 0\n" // neon
305 "mmx d15 .64 188 0\n" // neon
306 "mmx d16 .64 196 0\n" // neon
307 "mmx d17 .64 204 0\n" // neon
308 "mmx d18 .64 212 0\n" // neon
309 "mmx d19 .64 220 0\n" // neon
310 "mmx d20 .64 228 0\n" // neon
311 "mmx d21 .64 236 0\n" // neon
312 "mmx d22 .64 244 0\n" // neon
313 "mmx d23 .64 252 0\n" // neon
314 "mmx d24 .64 260 0\n" // neon
315 "mmx d25 .64 268 0\n" // neon
316 "mmx d26 .64 276 0\n" // neon
317 "mmx d27 .64 284 0\n" // neon
318 "mmx d28 .64 292 0\n" // neon
319 "mmx d29 .64 300 0\n" // neon
320 "mmx d30 .64 308 0\n" // neon
321 "mmx d31 .64 316 0\n" // neon
322 "mmx fpscr .32 324 0\n" // neon
323 );
324 }
325 }
326 return NULL;
327 }
328
r_debug_qnx_breakpoint(RBreakpoint * bp,RBreakpointItem * b,bool set)329 static int r_debug_qnx_breakpoint (RBreakpoint *bp, RBreakpointItem *b, bool set) {
330 if (!b) {
331 return false;
332 }
333 int ret = set
334 ? b->hw
335 ? qnxr_set_hwbp (desc, b->addr, "")
336 : qnxr_set_bp (desc, b->addr, "")
337 : b->hw
338 ? qnxr_remove_hwbp (desc, b->addr)
339 : qnxr_remove_bp (desc, b->addr);
340 return !ret;
341 }
342
343 RDebugPlugin r_debug_plugin_qnx = {
344 .name = "qnx",
345 .license = "LGPL3",
346 .arch = "x86,arm",
347 .bits = R_SYS_BITS_32,
348 .step = r_debug_qnx_step,
349 .cont = r_debug_qnx_continue,
350 .attach = &r_debug_qnx_attach,
351 .detach = &r_debug_qnx_detach,
352 .pids = &r_debug_qnx_pids,
353 .tids = &r_debug_qnx_tids,
354 .select = &r_debug_qnx_select,
355 .stop = &r_debug_qnx_stop,
356 .canstep = 1,
357 .wait = &r_debug_qnx_wait,
358 .map_get = r_debug_qnx_map_get,
359 .breakpoint = r_debug_qnx_breakpoint,
360 .reg_read = &r_debug_qnx_reg_read,
361 .reg_write = &r_debug_qnx_reg_write,
362 .reg_profile = (void *)r_debug_qnx_reg_profile,
363 };
364
365 #ifndef R2_PLUGIN_INCORE
366 R_API RLibStruct radare_plugin = {
367 .type = R_LIB_TYPE_DBG,
368 .data = &r_debug_plugin_qnx,
369 .version = R2_VERSION};
370 #endif
371