1 /* libqnxr - GPL - Copyright 2016 - defragger, madprogrammer, FSF Inc */
2
3 #include <errno.h>
4 #include <r_debug.h>
5 #include "libqnxr.h"
6 #include "core.h"
7 #include "signal.h"
8 #include "sigutil.h"
9 #include "packet.h"
10
11 #define MAX_TRAN_TRIES 3
12 #define HOST_QNX_PROTOVER_MAJOR 0
13 #define HOST_QNX_PROTOVER_MINOR 3
14
15 ptid_t null_ptid = {0, 0};
16
17 void nto_send_init (libqnxr_t *g, ut32 cmd, ut32 subcmd, ut32 chan);
18
19 ptid_t nto_parse_notify (libqnxr_t *g);
20 int nto_send_env (libqnxr_t *g, const char *env);
21 int nto_send_arg (libqnxr_t *g, const char *arg);
22 int nto_send (libqnxr_t *g, ut32 len, int report_errors);
23
24 static registers_t x86_32[] = {
25 {"eax", 0, 4},
26 {"ecx", 4, 4},
27 {"edx", 8, 4},
28 {"ebx", 12, 4},
29 {"esp", 16, 4},
30 {"ebp", 20, 4},
31 {"esi", 24, 4},
32 {"edi", 28, 4},
33 {"eip", 32, 4},
34 {"eflags", 36, 4},
35 {"cs", 40, 4},
36 {"ss", 44, 4},
37 #if 0
38 {"ds", 48, 4},
39 {"es", 52, 4},
40 {"fs", 56, 4},
41 {"gs", 60, 4},
42 {"st0", 64, 10},
43 {"st1", 74, 10},
44 {"st2", 84, 10},
45 {"st3", 94, 10},
46 {"st4", 104, 10},
47 {"st5", 114, 10},
48 {"st6", 124, 10},
49 {"st7", 134, 10},
50 {"fctrl", 144, 4},
51 {"fstat", 148, 4},
52 {"ftag", 152, 4},
53 {"fiseg", 156, 4},
54 {"fioff", 160, 4},
55 {"foseg", 164, 4},
56 {"fooff", 168, 4},
57 {"fop", 172, 4},
58 {"xmm0", 176, 16},
59 {"xmm1", 192, 16},
60 {"xmm2", 208, 16},
61 {"xmm3", 224, 16},
62 {"xmm4", 240, 16},
63 {"xmm5", 256, 16},
64 {"xmm6", 272, 16},
65 {"xmm7", 288, 16},
66 {"mxcsr", 304, 4},
67 #endif
68 {"", 0, 0}};
69
70 static registers_t arm32[] = {
71 {"r0", 0, 4},
72 {"r1", 4, 4},
73 {"r2", 8, 4},
74 {"r3", 12, 4},
75 {"r4", 16, 4},
76 {"r5", 20, 4},
77 {"r6", 24, 4},
78 {"r7", 28, 4},
79 {"r8", 32, 4},
80 {"r9", 36, 4},
81 {"r10", 40, 4},
82 {"r11", 44, 4},
83 {"r12", 48, 4},
84 {"sp", 52, 4},
85 {"lr", 56, 4},
86 {"pc", 60, 4},
87 {"f0", 64, 12},
88 {"f1", 76, 12},
89 {"f2", 88, 12},
90 {"f3", 100, 12},
91 {"f4", 112, 12},
92 {"f5", 124, 12},
93 {"f6", 136, 12},
94 {"f7", 148, 12},
95 {"fps", 160, 12},
96 {"cpsr", 172, 4},
97 {"", 0, 0}};
98
qnxr_init(libqnxr_t * g)99 int qnxr_init (libqnxr_t *g) {
100 if (!g) return -1;
101 memset (g, 0, sizeof (libqnxr_t));
102 g->send_len = 0;
103 g->send_buff = (char *)calloc (DS_DATA_MAX_SIZE * 2, 1);
104 if (!g->send_buff)
105 return -1;
106 g->read_buff = (char *)calloc (DS_DATA_MAX_SIZE * 2, 1);
107 if (!g->read_buff) {
108 R_FREE (g->send_buff);
109 return -1;
110 }
111 g->registers = x86_32;
112 return 0;
113 }
114
qnxr_set_architecture(libqnxr_t * g,ut8 architecture)115 int qnxr_set_architecture (libqnxr_t *g, ut8 architecture) {
116 if (!g) return -1;
117 g->architecture = architecture;
118 switch (architecture) {
119 case ARCH_X86_32:
120 g->registers = x86_32;
121 break;
122 case ARCH_ARM_32:
123 g->registers = arm32;
124 break;
125 default:
126 eprintf ("Error unknown architecture set\n");
127 }
128 return 0;
129 }
130
qnxr_cleanup(libqnxr_t * g)131 int qnxr_cleanup (libqnxr_t *g) {
132 if (!g) return -1;
133 free (g->send_buff);
134 g->send_len = 0;
135 free (g->read_buff);
136 return 0;
137 }
138
qnxr_connect(libqnxr_t * g,const char * host,int port)139 int qnxr_connect (libqnxr_t *g, const char *host, int port) {
140 char tmp[255];
141 int ret;
142 if (!g || !host || g->connected) return -1;
143
144 g->data_len = 0;
145 g->read_len = 0;
146 g->read_ptr = 0;
147 g->sock = r_socket_new (0);
148 g->connected = 0;
149 g->mid = 0;
150
151
152 memmove (g->host, host, strlen (host) + 1);
153 g->port = port;
154
155 ret = snprintf (tmp, sizeof (tmp) - 1, "%d", port);
156 if (!ret) return -1;
157 ret = r_socket_connect_tcp (g->sock, host, tmp, 200);
158 if (!ret) return -1;
159 g->connected = 1;
160
161 qnxr_send_ch_reset (g);
162 nto_send_init (g, DStMsg_connect, 0, SET_CHANNEL_DEBUG);
163 g->tran.pkt.connect.major = HOST_QNX_PROTOVER_MAJOR;
164 g->tran.pkt.connect.minor = HOST_QNX_PROTOVER_MINOR;
165 nto_send (g, sizeof (g->tran.pkt.connect), 0);
166
167 if (g->recv.pkt.hdr.cmd == DSrMsg_err) {
168 eprintf ("%s: connection failed: %lld\n", __func__,
169 EXTRACT_SIGNED_INTEGER (&g->recv.pkt.err.err, 4));
170 return -1;
171 }
172
173 /* Try to query pdebug for their version of the protocol */
174 nto_send_init (g, DStMsg_protover, 0, SET_CHANNEL_DEBUG);
175 g->tran.pkt.protover.major = HOST_QNX_PROTOVER_MAJOR;
176 g->tran.pkt.protover.minor = HOST_QNX_PROTOVER_MINOR;
177 nto_send (g, sizeof (g->tran.pkt.protover), 0);
178
179 if ((g->recv.pkt.hdr.cmd == DSrMsg_err) && (EXTRACT_SIGNED_INTEGER (&g->recv.pkt.err.err, 4) == EINVAL)) {
180 g->target_proto_major = 0;
181 g->target_proto_minor = 0;
182 } else if (g->recv.pkt.hdr.cmd == DSrMsg_okstatus) {
183 g->target_proto_major = EXTRACT_SIGNED_INTEGER (&g->recv.pkt.okstatus.status, 4);
184 g->target_proto_minor = EXTRACT_SIGNED_INTEGER (&g->recv.pkt.okstatus.status, 4);
185 g->target_proto_major = (g->target_proto_major >> 8) & DSMSG_PROTOVER_MAJOR;
186 g->target_proto_minor = g->target_proto_minor & DSMSG_PROTOVER_MINOR;
187 } else {
188 eprintf ("Connection failed (Protocol Version Query): %lld\n",
189 EXTRACT_SIGNED_INTEGER (&g->recv.pkt.err.err, 4));
190 return -1;
191 }
192
193 return 0;
194 }
195
qnxr_disconnect(libqnxr_t * g)196 int qnxr_disconnect (libqnxr_t *g) {
197 if (!g) return -1;
198
199 if (g->connected) {
200 nto_send_init (g, DStMsg_disconnect, 0, SET_CHANNEL_DEBUG);
201 nto_send (g, sizeof (g->tran.pkt.disconnect), 0);
202 g->connected = 0;
203 g->inferior_ptid = null_ptid;
204
205 if (!r_socket_close (g->sock))
206 return -1;
207 }
208
209 return 0;
210 }
211
qnxr_attach(libqnxr_t * g,pid_t pid)212 ptid_t qnxr_attach (libqnxr_t *g, pid_t pid) {
213
214 if (g->inferior_ptid.pid != pid) {
215 qnxr_disconnect (g);
216 r_sys_sleep (1);
217 qnxr_connect (g, g->host, g->port);
218 }
219
220 nto_send_init (g, DStMsg_attach, 0, SET_CHANNEL_DEBUG);
221 g->tran.pkt.attach.pid = pid;
222 g->tran.pkt.attach.pid = EXTRACT_SIGNED_INTEGER (&g->tran.pkt.attach.pid, 4);
223
224 nto_send (g, sizeof (g->tran.pkt.attach), 0);
225 if (g->recv.pkt.hdr.cmd != DSrMsg_okdata) {
226 eprintf ("%s: failed to attach to %d\n", __func__, pid);
227 return null_ptid;
228 }
229
230 g->inferior_ptid = ptid_build (
231 EXTRACT_SIGNED_INTEGER (&g->recv.pkt.notify.pid, 4),
232 EXTRACT_SIGNED_INTEGER (&g->recv.pkt.notify.tid, 4));
233
234 return g->inferior_ptid;
235 }
236
qnxr_run(libqnxr_t * g,const char * file,char ** args,char ** env)237 ptid_t qnxr_run (libqnxr_t *g, const char *file, char **args, char **env) {
238 ut32 argc = 0;
239 ut32 envc = 0;
240
241 char **argv, *p;
242 int errors = 0;
243
244 if (!g) return null_ptid;
245
246 nto_send_init (g, DStMsg_env, DSMSG_ENV_CLEARENV, SET_CHANNEL_DEBUG);
247 nto_send (g, sizeof (DStMsg_env_t), 1);
248
249 for (envc = 0; *env; env++, envc++)
250 errors += !nto_send_env (g, *env);
251
252 if (errors) {
253 eprintf ("%s: error(s) occurred while sending environment\n", __func__);
254 }
255
256 nto_send_init (g, DStMsg_env, DSMSG_ENV_CLEARARGV, SET_CHANNEL_DEBUG);
257 nto_send (g, sizeof (DStMsg_env_t), 1);
258
259 if (file != NULL) {
260 errors = !nto_send_arg (g, file);
261 if (!errors)
262 errors = !nto_send_arg (g, file);
263
264 if (errors) {
265 eprintf ("%s: failed to send executable file name\n", __func__);
266 return null_ptid;
267 }
268
269 errors = 0;
270 for (argv = args; *argv && **argv; argv++, argc++)
271 errors |= !nto_send_arg (g, *argv);
272
273 if (errors) {
274 eprintf ("%s: error(s) occurred while sending args\n", __func__);
275 }
276 }
277
278 if (errors) {
279 return null_ptid;
280 }
281
282 nto_send_init (g, DStMsg_load, DSMSG_LOAD_DEBUG, SET_CHANNEL_DEBUG);
283 p = g->tran.pkt.load.cmdline;
284
285 g->tran.pkt.load.envc = 0;
286 g->tran.pkt.load.argc = 0;
287
288 if (file) {
289 strncpy (p, file, sizeof (g->tran.pkt.load.cmdline) - 8);
290 p += strlen (p);
291 }
292 *p++ = '\0';
293
294 *p++ = '\0'; // stdin
295 *p++ = '\0'; // stdout
296 *p++ = '\0'; // stderr
297
298 nto_send (g, offsetof (DStMsg_load_t, cmdline) + p - g->tran.pkt.load.cmdline + 1, 1);
299
300 if (g->recv.pkt.hdr.cmd == DSrMsg_okdata) {
301 ptid_t ptid = nto_parse_notify (g);
302 eprintf ("%s: inferior pid: %d\n", __func__, ptid.pid);
303 g->inferior_ptid = ptid;
304
305 return ptid;
306 }
307
308 return null_ptid;
309 }
310
qnxr_read_registers(libqnxr_t * g)311 int qnxr_read_registers (libqnxr_t *g) {
312 int i = 0;
313 int len, rlen, regset;
314 int n = 0;
315 ut32 off;
316 char buf[DS_DATA_MAX_SIZE];
317
318 if (!g) return -1;
319
320 while (g->registers[i].size > 0) {
321 regset = i386nto_regset_id (i);
322 len = i386nto_register_area (i, regset, &off);
323 if (len < 1) {
324 eprintf ("%s: unknown register %d\n", __func__, i);
325 len = g->registers[i].size;
326 }
327 nto_send_init (g, DStMsg_regrd, regset, SET_CHANNEL_DEBUG);
328 g->tran.pkt.regrd.offset = EXTRACT_SIGNED_INTEGER (&off, 2);
329 g->tran.pkt.regrd.size = EXTRACT_SIGNED_INTEGER (&len, 2);
330 rlen = nto_send (g, sizeof (g->tran.pkt.regrd), 1);
331
332 if (rlen > 0) {
333 if (g->recv.pkt.hdr.cmd == DSrMsg_okdata) {
334 memcpy (buf + g->registers[i].offset,
335 g->recv.pkt.okdata.data, len);
336 n += len;
337 } else {
338 memset (buf + g->registers[i].offset,
339 0, len);
340 }
341 } else {
342 eprintf ("%s: couldn't read register %d\n", __func__, i);
343 return -1;
344 }
345 i++;
346 }
347
348 memcpy (g->recv.data, buf, n);
349 return n;
350 }
351
qnxr_read_memory(libqnxr_t * g,ut64 address,ut8 * data,ut64 len)352 int qnxr_read_memory (libqnxr_t *g, ut64 address, ut8 *data, ut64 len) {
353 int rcv_len, tot_len, ask_len;
354 ut64 addr;
355
356 if (!g || !data) return -1;
357
358 tot_len = rcv_len = ask_len = 0;
359
360 do {
361 nto_send_init (g, DStMsg_memrd, 0, SET_CHANNEL_DEBUG);
362 addr = address + tot_len;
363 g->tran.pkt.memrd.addr = EXTRACT_UNSIGNED_INTEGER (&addr, 8);
364 ask_len = ((len - tot_len) > DS_DATA_MAX_SIZE) ?
365 DS_DATA_MAX_SIZE :
366 (len - tot_len);
367
368 g->tran.pkt.memrd.size = EXTRACT_SIGNED_INTEGER (&ask_len, 2);
369 rcv_len = nto_send (g, sizeof (g->tran.pkt.memrd), 0) -
370 sizeof (g->recv.pkt.hdr);
371 if (rcv_len <= 0) break;
372 if (g->recv.pkt.hdr.cmd == DSrMsg_okdata) {
373 memcpy (data + tot_len, g->recv.pkt.okdata.data, rcv_len);
374 tot_len += rcv_len;
375 } else
376 break;
377 } while (tot_len != len);
378
379 return tot_len;
380 }
381
qnxr_write_memory(libqnxr_t * g,ut64 address,const ut8 * data,ut64 len)382 int qnxr_write_memory (libqnxr_t *g, ut64 address, const ut8 *data, ut64 len) {
383 ut64 addr;
384
385 if (!g || !data) return -1;
386
387 nto_send_init (g, DStMsg_memwr, 0, SET_CHANNEL_DEBUG);
388 addr = address;
389 g->tran.pkt.memwr.addr = EXTRACT_UNSIGNED_INTEGER (&addr, 8);
390 memcpy (g->tran.pkt.memwr.data, data, len);
391 nto_send (g, offsetof (DStMsg_memwr_t, data) + len, 0);
392
393 switch (g->recv.pkt.hdr.cmd) {
394 case DSrMsg_ok:
395 return len;
396 case DSrMsg_okstatus:
397 return EXTRACT_SIGNED_INTEGER (&g->recv.pkt.okstatus.status, 4);
398 }
399
400 return 0;
401 }
402
qnxr_pidlist(libqnxr_t * g,void * ctx,pidlist_cb_t * cb)403 void qnxr_pidlist (libqnxr_t *g, void *ctx, pidlist_cb_t *cb) {
404 struct dspidlist *pidlist = (void *)g->recv.pkt.okdata.data;
405 pid_t pid, start_tid;
406 char subcmd;
407
408 if (!g) return;
409
410 start_tid = 1;
411 pid = 1;
412 subcmd = DSMSG_PIDLIST_BEGIN;
413
414 while (1) {
415 nto_send_init (g, DStMsg_pidlist, subcmd, SET_CHANNEL_DEBUG);
416 g->tran.pkt.pidlist.pid = EXTRACT_SIGNED_INTEGER (&pid, 4);
417 g->tran.pkt.pidlist.tid = EXTRACT_SIGNED_INTEGER (&start_tid, 4);
418 nto_send (g, sizeof (g->tran.pkt.pidlist), 0);
419
420 if (g->recv.pkt.hdr.cmd == DSrMsg_err || g->recv.pkt.hdr.cmd != DSrMsg_okdata)
421 return;
422
423 pid = EXTRACT_SIGNED_INTEGER (&pidlist->pid, 4);
424 if (cb != NULL)
425 cb (ctx, pid, pidlist->name);
426 subcmd = DSMSG_PIDLIST_NEXT;
427 }
428 }
429
qnxr_select(libqnxr_t * g,pid_t pid,int tid)430 int qnxr_select (libqnxr_t *g, pid_t pid, int tid) {
431 if (!g) return 0;
432
433 /* TODO */
434 tid = 1;
435
436 nto_send_init (g, DStMsg_select, DSMSG_SELECT_SET, SET_CHANNEL_DEBUG);
437 g->tran.pkt.select.pid = pid;
438 g->tran.pkt.select.pid = EXTRACT_SIGNED_INTEGER (&g->tran.pkt.select.pid, 4);
439 g->tran.pkt.select.tid = EXTRACT_SIGNED_INTEGER (&tid, 4);
440 nto_send (g, sizeof (g->tran.pkt.select), 1);
441
442 if (g->recv.pkt.hdr.cmd == DSrMsg_err) {
443 eprintf ("%s: failed to select %d\n", __func__, pid);
444 return 0;
445 }
446
447 return 1;
448 }
449
qnxr_step(libqnxr_t * g,int thread_id)450 int qnxr_step (libqnxr_t *g, int thread_id) {
451 return qnxr_send_vcont (g, 1, thread_id);
452 }
453
qnxr_continue(libqnxr_t * g,int thread_id)454 int qnxr_continue (libqnxr_t *g, int thread_id) {
455 return qnxr_send_vcont (g, 0, thread_id);
456 }
457
qnxr_write_register(libqnxr_t * g,int index,char * value,int len)458 int qnxr_write_register (libqnxr_t *g, int index, char *value, int len) {
459 int tdep_len, regset;
460 ut32 off;
461
462 if (!g) return -1;
463
464 regset = i386nto_regset_id (index);
465 tdep_len = i386nto_register_area (index, regset, &off);
466 if (len < 0 || tdep_len != len) {
467 eprintf ("%s: invalid length\n", __func__);
468 return -1;
469 }
470
471 nto_send_init (g, DStMsg_regwr, regset, SET_CHANNEL_DEBUG);
472 g->tran.pkt.regwr.offset = EXTRACT_SIGNED_INTEGER (&off, 2);
473 memcpy (g->tran.pkt.regwr.data, value, len);
474 nto_send (g, offsetof (DStMsg_regwr_t, data) + len, 1);
475
476 return 0;
477 }
478
qnxr_write_reg(libqnxr_t * g,const char * name,char * value,int len)479 int qnxr_write_reg (libqnxr_t *g, const char *name, char *value, int len) {
480 int i = 0;
481
482 if (!g) return -1;
483
484 while (g->registers[i].size > 0) {
485 if (!strcmp (g->registers[i].name, name)) {
486 break;
487 }
488 i++;
489 }
490 if (g->registers[i].size == 0) {
491 eprintf ("Error registername <%s> not found in profile\n", name);
492 return -1;
493 }
494 qnxr_write_register (g, i, value, len);
495
496 return 0;
497 }
498
qnxr_send_vcont(libqnxr_t * g,int step,int thread_id)499 int qnxr_send_vcont (libqnxr_t *g, int step, int thread_id) {
500 if (!g) return -1;
501
502 nto_send_init (g, DStMsg_run, step ? DSMSG_RUN_COUNT : DSMSG_RUN,
503 SET_CHANNEL_DEBUG);
504 g->tran.pkt.run.step.count = 1;
505 nto_send (g, sizeof (g->tran.pkt.run), 1);
506 return 0;
507 }
508
qnxr_stop(libqnxr_t * g)509 int qnxr_stop (libqnxr_t *g) {
510 if (!g) return 0;
511
512 eprintf ("%s: waiting for stop\n", __func__);
513 g->waiting_for_stop = 1;
514 nto_send_init (g, DStMsg_stop, DSMSG_STOP_PIDS, SET_CHANNEL_DEBUG);
515
516 g->send_len = sizeof (g->tran.pkt.stop);
517 qnxr_send_packet (g);
518
519 return 1;
520 }
521
qnxr_wait(libqnxr_t * g,pid_t pid)522 ptid_t qnxr_wait (libqnxr_t *g, pid_t pid) {
523 if (!g || pid < 0) {
524 return null_ptid;
525 }
526 ptid_t returned_ptid = g->inferior_ptid;
527 if (g->inferior_ptid.pid != pid) {
528 return null_ptid;
529 }
530 if (g->recv.pkt.hdr.cmd != DShMsg_notify) {
531 int rlen;
532 char waiting_for_notify = 1;
533
534 eprintf ("%s: waiting for inferior\n", __func__);
535
536 while (1) {
537 rlen = qnxr_read_packet (g);
538 if (rlen == -1) {
539 if (g->waiting_for_stop) {
540 eprintf ("%s: read eror while waiting for stop\n",
541 __func__);
542 continue;
543 } else {
544 eprintf ("%s: read packet error or NAK\n", __func__);
545 return null_ptid;
546 }
547 }
548 if (g->channelrd == SET_CHANNEL_TEXT) {
549 // TODO nto_incoming_text
550 } else {
551 g->recv.pkt.hdr.cmd &= ~DSHDR_MSG_BIG_ENDIAN;
552 if (g->waiting_for_stop && g->recv.pkt.hdr.cmd == DSrMsg_ok) {
553 g->waiting_for_stop = 0;
554 eprintf ("%s: got stop response\n", __func__);
555 if (!waiting_for_notify)
556 break;
557 } else if (g->recv.pkt.hdr.cmd == DShMsg_notify) {
558 // acknowledge the notify
559 g->tran.pkt.hdr.cmd = DSrMsg_ok;
560 g->tran.pkt.hdr.channel = SET_CHANNEL_DEBUG;
561 g->tran.pkt.hdr.mid = g->recv.pkt.hdr.mid;
562 qnxr_send_ch_debug (g);
563
564 g->send_len = sizeof (g->tran.pkt.ok);
565 qnxr_send_packet (g);
566
567 returned_ptid = nto_parse_notify (g);
568 break;
569 }
570 }
571 }
572 }
573
574 /* to make us wait the next time */
575 g->recv.pkt.hdr.cmd = DSrMsg_ok;
576 return returned_ptid;
577 }
578
qnxr_set_bp(libqnxr_t * g,ut64 address,const char * conditions)579 int qnxr_set_bp (libqnxr_t *g, ut64 address, const char *conditions) {
580 return _qnxr_set_bp (g, address, conditions, BREAKPOINT);
581 }
582
qnxr_set_hwbp(libqnxr_t * g,ut64 address,const char * conditions)583 int qnxr_set_hwbp (libqnxr_t *g, ut64 address, const char *conditions) {
584 return _qnxr_set_bp (g, address, conditions, HARDWARE_BREAKPOINT);
585 }
586
qnxr_remove_bp(libqnxr_t * g,ut64 address)587 int qnxr_remove_bp (libqnxr_t *g, ut64 address) {
588 return _qnxr_remove_bp (g, address, BREAKPOINT);
589 }
590
qnxr_remove_hwbp(libqnxr_t * g,ut64 address)591 int qnxr_remove_hwbp (libqnxr_t *g, ut64 address) {
592 return _qnxr_remove_bp (g, address, HARDWARE_BREAKPOINT);
593 }
594
_qnxr_set_bp(libqnxr_t * g,ut64 address,const char * conditions,enum Breakpoint type)595 int _qnxr_set_bp (libqnxr_t *g, ut64 address, const char *conditions, enum Breakpoint type) {
596 if (!g) return -1;
597
598 nto_send_init (g, DStMsg_brk, DSMSG_BRK_EXEC, SET_CHANNEL_DEBUG);
599 g->tran.pkt.brk.addr = EXTRACT_UNSIGNED_INTEGER (&address, 4);
600 g->tran.pkt.brk.size = 0;
601 nto_send (g, sizeof (g->tran.pkt.brk), 0);
602
603 if (g->recv.pkt.hdr.cmd == DSrMsg_err)
604 return -1;
605 return 0;
606 }
607
_qnxr_remove_bp(libqnxr_t * g,ut64 address,enum Breakpoint type)608 int _qnxr_remove_bp (libqnxr_t *g, ut64 address, enum Breakpoint type) {
609 if (!g) return -1;
610
611 nto_send_init (g, DStMsg_brk, DSMSG_BRK_EXEC, SET_CHANNEL_DEBUG);
612 g->tran.pkt.brk.addr = EXTRACT_UNSIGNED_INTEGER (&address, 4);
613 g->tran.pkt.brk.size = -1;
614 nto_send (g, sizeof (g->tran.pkt.brk), 0);
615
616 if (g->recv.pkt.hdr.cmd == DSrMsg_err)
617 return -1;
618 return 0;
619 }
620
nto_send_init(libqnxr_t * g,ut32 cmd,ut32 subcmd,ut32 chan)621 void nto_send_init (libqnxr_t *g, ut32 cmd, ut32 subcmd, ut32 chan) {
622 g->tran.pkt.hdr.cmd = cmd;
623 g->tran.pkt.hdr.subcmd = subcmd;
624 g->tran.pkt.hdr.mid = ((chan == SET_CHANNEL_DEBUG) ? g->mid++ : 0);
625 g->tran.pkt.hdr.channel = chan;
626 }
627
nto_parse_notify(libqnxr_t * g)628 ptid_t nto_parse_notify (libqnxr_t *g) {
629 pid_t pid, tid;
630
631 pid = EXTRACT_SIGNED_INTEGER (&g->recv.pkt.notify.pid, 4);
632 tid = EXTRACT_SIGNED_INTEGER (&g->recv.pkt.notify.tid, 4);
633
634 if (tid == 0) tid = 1;
635 eprintf ("%s: parse notify %d\n", __func__, g->recv.pkt.hdr.subcmd);
636
637 switch (g->recv.pkt.hdr.subcmd) {
638 case DSMSG_NOTIFY_PIDUNLOAD:
639 g->notify_type = R_DEBUG_REASON_DEAD;
640 break;
641 case DSMSG_NOTIFY_BRK:
642 g->stop_flags = EXTRACT_UNSIGNED_INTEGER (&g->recv.pkt.notify.un.brk.flags, 4);
643 g->stop_pc = EXTRACT_UNSIGNED_INTEGER (&g->recv.pkt.notify.un.brk.ip, 4);
644 g->notify_type = R_DEBUG_REASON_BREAKPOINT;
645 break;
646 case DSMSG_NOTIFY_STEP:
647 g->notify_type = R_DEBUG_REASON_STEP;
648 break;
649 case DSMSG_NOTIFY_SIGEV:
650 g->notify_type = R_DEBUG_REASON_SIGNAL;
651 g->signal = host_signal_from_nto (EXTRACT_SIGNED_INTEGER (&g->recv.pkt.notify.un.sigev.signo, 4));
652 break;
653 case DSMSG_NOTIFY_PIDLOAD:
654 eprintf ("%s: notify type DSMSG_NOTIFY_PIDLOAD\n", __func__);
655 g->notify_type = R_DEBUG_REASON_UNKNOWN;
656 break;
657 case DSMSG_NOTIFY_DLLLOAD:
658 case DSMSG_NOTIFY_TIDLOAD:
659 case DSMSG_NOTIFY_TIDUNLOAD:
660 case DSMSG_NOTIFY_DLLUNLOAD:
661 eprintf ("%s: notify type DSMSG_NOTIFY_DLLTID\n", __func__);
662 g->notify_type = R_DEBUG_REASON_UNKNOWN;
663 break;
664 case DSMSG_NOTIFY_STOPPED:
665 g->notify_type = R_DEBUG_REASON_SWI;
666 break;
667 default:
668 eprintf ("%s: Unexpected notify type %d\n", __func__,
669 g->recv.pkt.hdr.subcmd);
670 g->notify_type = R_DEBUG_REASON_UNKNOWN;
671 }
672
673 return ptid_build (pid, tid);
674 }
675
nto_send_env(libqnxr_t * g,const char * env)676 int nto_send_env (libqnxr_t *g, const char *env) {
677 int len; /* Length including zero terminating char. */
678 int totlen = 0;
679
680 if (!g) return 0;
681
682 len = strlen (env) + 1;
683 if (g->target_proto_minor >= 2) {
684 while (len > DS_DATA_MAX_SIZE) {
685 nto_send_init (g, DStMsg_env, DSMSG_ENV_SETENV_MORE,
686 SET_CHANNEL_DEBUG);
687 memcpy (g->tran.pkt.env.data, env + totlen,
688 DS_DATA_MAX_SIZE);
689 if (!nto_send (g, offsetof (DStMsg_env_t, data) +
690 DS_DATA_MAX_SIZE,
691 1)) {
692 /* An error occurred. */
693 return 0;
694 }
695 len -= DS_DATA_MAX_SIZE;
696 totlen += DS_DATA_MAX_SIZE;
697 }
698 } else if (len > DS_DATA_MAX_SIZE) {
699 /* Not supported by this protocol version. */
700 eprintf ("Protovers < 0.2 do not handle env vars longer than %d\n",
701 DS_DATA_MAX_SIZE - 1);
702 return 0;
703 }
704 nto_send_init (g, DStMsg_env, DSMSG_ENV_SETENV, SET_CHANNEL_DEBUG);
705 memcpy (g->tran.pkt.env.data, env + totlen, len);
706 return nto_send (g, offsetof (DStMsg_env_t, data) + len, 1);
707 }
708
nto_send_arg(libqnxr_t * g,const char * arg)709 int nto_send_arg (libqnxr_t *g, const char *arg) {
710 int len;
711
712 if (!g) return 0;
713
714 len = strlen (arg) + 1;
715 if (len > DS_DATA_MAX_SIZE - 4) {
716 eprintf ("Argument too long: %.40s...\n", arg);
717 return 0;
718 }
719 nto_send_init (g, DStMsg_env, DSMSG_ENV_ADDARG, SET_CHANNEL_DEBUG);
720 memcpy (g->tran.pkt.env.data, arg, len);
721 return nto_send (g, offsetof (DStMsg_env_t, data) + len, 1);
722 }
723
nto_send(libqnxr_t * g,ut32 len,st32 report_errors)724 int nto_send (libqnxr_t *g, ut32 len, st32 report_errors) {
725 int rlen;
726 ut8 tries = 0;
727
728 if (!g || g->connected == 0) {
729 return -1;
730 }
731 g->send_len = len;
732 for (tries = 0;; tries++) {
733 if (tries >= MAX_TRAN_TRIES) {
734 eprintf ("%s: Remote exhausted %d retries.\n", __func__, tries);
735 return -1;
736 }
737 qnxr_send_packet (g);
738 for (;;) {
739 rlen = qnxr_read_packet (g);
740 if ((g->channelrd != SET_CHANNEL_TEXT) || (rlen == -1))
741 break;
742 //nto_incoming_text (rlen); TODO
743 }
744 if (rlen == -1) {
745 eprintf ("%s: NAK received - resending\n", __func__);
746 continue;
747 }
748 if ((rlen >= 0) && (g->recv.pkt.hdr.mid == g->tran.pkt.hdr.mid))
749 break;
750 eprintf ("%s: mid mismatch: %d/%d\n", __func__, g->recv.pkt.hdr.mid,
751 g->tran.pkt.hdr.mid);
752 }
753
754 switch (g->channelrd) {
755 case SET_CHANNEL_DEBUG:
756 g->recv.pkt.hdr.cmd &= ~DSHDR_MSG_BIG_ENDIAN;
757 if (g->recv.pkt.hdr.cmd == DSrMsg_err) {
758 if (report_errors) {
759 int nerrno = errnoconvert (
760 EXTRACT_SIGNED_INTEGER (&g->recv.pkt.err.err, 4));
761 switch (g->recv.pkt.hdr.subcmd) {
762 case PDEBUG_ENOERR:
763 eprintf ("remote: error packet with errno %d\n", nerrno);
764 break;
765 case PDEBUG_ENOPTY:
766 eprintf ("remote: no ptys available\n");
767 break;
768 case PDEBUG_ETHREAD:
769 eprintf ("remote: thread start error\n");
770 break;
771 case PDEBUG_ECONINV:
772 eprintf ("remote: invalid console number\n");
773 break;
774 case PDEBUG_ESPAWN:
775 eprintf ("Remote (spawn error)\n");
776 break;
777 case PDEBUG_EPROCFS:
778 eprintf ("Remote (procfs [/proc] error)\n");
779 break;
780 case PDEBUG_EPROCSTOP:
781 eprintf ("Remote (devctl PROC_STOP error)\n");
782 break;
783 case PDEBUG_EQPSINFO:
784 eprintf ("Remote (psinfo error)\n");
785 break;
786 case PDEBUG_EQMEMMODEL:
787 eprintf ("Remote (invalid memory model [not flat])\n");
788 break;
789 case PDEBUG_EQPROXY:
790 eprintf ("Remote (proxy error)\n");
791 break;
792 case PDEBUG_EQDBG:
793 eprintf ("Remote (__nto_debug_* error)\n");
794 break;
795 default:
796 eprintf ("Remote error\n");
797 }
798 }
799 }
800 break;
801 case SET_CHANNEL_TEXT:
802 case SET_CHANNEL_RESET:
803 break;
804 }
805 return rlen;
806 }
807