0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #include <linux/kernel.h>
0029 #include <linux/sched/signal.h>
0030 #include <linux/kgdb.h>
0031 #include <linux/kdb.h>
0032 #include <linux/serial_core.h>
0033 #include <linux/reboot.h>
0034 #include <linux/uaccess.h>
0035 #include <asm/cacheflush.h>
0036 #include <asm/unaligned.h>
0037 #include "debug_core.h"
0038
0039 #define KGDB_MAX_THREAD_QUERY 17
0040
0041
0042 static char remcom_in_buffer[BUFMAX];
0043 static char remcom_out_buffer[BUFMAX];
0044 static int gdbstub_use_prev_in_buf;
0045 static int gdbstub_prev_in_buf_pos;
0046
0047
0048 static unsigned long gdb_regs[(NUMREGBYTES +
0049 sizeof(unsigned long) - 1) /
0050 sizeof(unsigned long)];
0051
0052
0053
0054
0055
0056 #ifdef CONFIG_KGDB_KDB
0057 static int gdbstub_read_wait(void)
0058 {
0059 int ret = -1;
0060 int i;
0061
0062 if (unlikely(gdbstub_use_prev_in_buf)) {
0063 if (gdbstub_prev_in_buf_pos < gdbstub_use_prev_in_buf)
0064 return remcom_in_buffer[gdbstub_prev_in_buf_pos++];
0065 else
0066 gdbstub_use_prev_in_buf = 0;
0067 }
0068
0069
0070 while (ret < 0)
0071 for (i = 0; kdb_poll_funcs[i] != NULL; i++) {
0072 ret = kdb_poll_funcs[i]();
0073 if (ret > 0)
0074 break;
0075 }
0076 return ret;
0077 }
0078 #else
0079 static int gdbstub_read_wait(void)
0080 {
0081 int ret = dbg_io_ops->read_char();
0082 while (ret == NO_POLL_CHAR)
0083 ret = dbg_io_ops->read_char();
0084 return ret;
0085 }
0086 #endif
0087
0088 static void get_packet(char *buffer)
0089 {
0090 unsigned char checksum;
0091 unsigned char xmitcsum;
0092 int count;
0093 char ch;
0094
0095 do {
0096
0097
0098
0099
0100 while ((ch = (gdbstub_read_wait())) != '$')
0101 ;
0102
0103 kgdb_connected = 1;
0104 checksum = 0;
0105 xmitcsum = -1;
0106
0107 count = 0;
0108
0109
0110
0111
0112 while (count < (BUFMAX - 1)) {
0113 ch = gdbstub_read_wait();
0114 if (ch == '#')
0115 break;
0116 checksum = checksum + ch;
0117 buffer[count] = ch;
0118 count = count + 1;
0119 }
0120
0121 if (ch == '#') {
0122 xmitcsum = hex_to_bin(gdbstub_read_wait()) << 4;
0123 xmitcsum += hex_to_bin(gdbstub_read_wait());
0124
0125 if (checksum != xmitcsum)
0126
0127 dbg_io_ops->write_char('-');
0128 else
0129
0130 dbg_io_ops->write_char('+');
0131 if (dbg_io_ops->flush)
0132 dbg_io_ops->flush();
0133 }
0134 buffer[count] = 0;
0135 } while (checksum != xmitcsum);
0136 }
0137
0138
0139
0140
0141
0142 static void put_packet(char *buffer)
0143 {
0144 unsigned char checksum;
0145 int count;
0146 char ch;
0147
0148
0149
0150
0151 while (1) {
0152 dbg_io_ops->write_char('$');
0153 checksum = 0;
0154 count = 0;
0155
0156 while ((ch = buffer[count])) {
0157 dbg_io_ops->write_char(ch);
0158 checksum += ch;
0159 count++;
0160 }
0161
0162 dbg_io_ops->write_char('#');
0163 dbg_io_ops->write_char(hex_asc_hi(checksum));
0164 dbg_io_ops->write_char(hex_asc_lo(checksum));
0165 if (dbg_io_ops->flush)
0166 dbg_io_ops->flush();
0167
0168
0169 ch = gdbstub_read_wait();
0170
0171 if (ch == 3)
0172 ch = gdbstub_read_wait();
0173
0174
0175 if (ch == '+')
0176 return;
0177
0178
0179
0180
0181
0182
0183
0184 if (ch == '$') {
0185 dbg_io_ops->write_char('-');
0186 if (dbg_io_ops->flush)
0187 dbg_io_ops->flush();
0188 return;
0189 }
0190 }
0191 }
0192
0193 static char gdbmsgbuf[BUFMAX + 1];
0194
0195 void gdbstub_msg_write(const char *s, int len)
0196 {
0197 char *bufptr;
0198 int wcount;
0199 int i;
0200
0201 if (len == 0)
0202 len = strlen(s);
0203
0204
0205 gdbmsgbuf[0] = 'O';
0206
0207
0208 while (len > 0) {
0209 bufptr = gdbmsgbuf + 1;
0210
0211
0212 if ((len << 1) > (BUFMAX - 2))
0213 wcount = (BUFMAX - 2) >> 1;
0214 else
0215 wcount = len;
0216
0217
0218 for (i = 0; i < wcount; i++)
0219 bufptr = hex_byte_pack(bufptr, s[i]);
0220 *bufptr = '\0';
0221
0222
0223 s += wcount;
0224 len -= wcount;
0225
0226
0227 put_packet(gdbmsgbuf);
0228 }
0229 }
0230
0231
0232
0233
0234
0235
0236 char *kgdb_mem2hex(char *mem, char *buf, int count)
0237 {
0238 char *tmp;
0239 int err;
0240
0241
0242
0243
0244
0245 tmp = buf + count;
0246
0247 err = copy_from_kernel_nofault(tmp, mem, count);
0248 if (err)
0249 return NULL;
0250 while (count > 0) {
0251 buf = hex_byte_pack(buf, *tmp);
0252 tmp++;
0253 count--;
0254 }
0255 *buf = 0;
0256
0257 return buf;
0258 }
0259
0260
0261
0262
0263
0264
0265 int kgdb_hex2mem(char *buf, char *mem, int count)
0266 {
0267 char *tmp_raw;
0268 char *tmp_hex;
0269
0270
0271
0272
0273
0274 tmp_raw = buf + count * 2;
0275
0276 tmp_hex = tmp_raw - 1;
0277 while (tmp_hex >= buf) {
0278 tmp_raw--;
0279 *tmp_raw = hex_to_bin(*tmp_hex--);
0280 *tmp_raw |= hex_to_bin(*tmp_hex--) << 4;
0281 }
0282
0283 return copy_to_kernel_nofault(mem, tmp_raw, count);
0284 }
0285
0286
0287
0288
0289
0290 int kgdb_hex2long(char **ptr, unsigned long *long_val)
0291 {
0292 int hex_val;
0293 int num = 0;
0294 int negate = 0;
0295
0296 *long_val = 0;
0297
0298 if (**ptr == '-') {
0299 negate = 1;
0300 (*ptr)++;
0301 }
0302 while (**ptr) {
0303 hex_val = hex_to_bin(**ptr);
0304 if (hex_val < 0)
0305 break;
0306
0307 *long_val = (*long_val << 4) | hex_val;
0308 num++;
0309 (*ptr)++;
0310 }
0311
0312 if (negate)
0313 *long_val = -*long_val;
0314
0315 return num;
0316 }
0317
0318
0319
0320
0321
0322
0323 static int kgdb_ebin2mem(char *buf, char *mem, int count)
0324 {
0325 int size = 0;
0326 char *c = buf;
0327
0328 while (count-- > 0) {
0329 c[size] = *buf++;
0330 if (c[size] == 0x7d)
0331 c[size] = *buf++ ^ 0x20;
0332 size++;
0333 }
0334
0335 return copy_to_kernel_nofault(mem, c, size);
0336 }
0337
0338 #if DBG_MAX_REG_NUM > 0
0339 void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
0340 {
0341 int i;
0342 int idx = 0;
0343 char *ptr = (char *)gdb_regs;
0344
0345 for (i = 0; i < DBG_MAX_REG_NUM; i++) {
0346 dbg_get_reg(i, ptr + idx, regs);
0347 idx += dbg_reg_def[i].size;
0348 }
0349 }
0350
0351 void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
0352 {
0353 int i;
0354 int idx = 0;
0355 char *ptr = (char *)gdb_regs;
0356
0357 for (i = 0; i < DBG_MAX_REG_NUM; i++) {
0358 dbg_set_reg(i, ptr + idx, regs);
0359 idx += dbg_reg_def[i].size;
0360 }
0361 }
0362 #endif
0363
0364
0365 static int write_mem_msg(int binary)
0366 {
0367 char *ptr = &remcom_in_buffer[1];
0368 unsigned long addr;
0369 unsigned long length;
0370 int err;
0371
0372 if (kgdb_hex2long(&ptr, &addr) > 0 && *(ptr++) == ',' &&
0373 kgdb_hex2long(&ptr, &length) > 0 && *(ptr++) == ':') {
0374 if (binary)
0375 err = kgdb_ebin2mem(ptr, (char *)addr, length);
0376 else
0377 err = kgdb_hex2mem(ptr, (char *)addr, length);
0378 if (err)
0379 return err;
0380 if (CACHE_FLUSH_IS_SAFE)
0381 flush_icache_range(addr, addr + length);
0382 return 0;
0383 }
0384
0385 return -EINVAL;
0386 }
0387
0388 static void error_packet(char *pkt, int error)
0389 {
0390 error = -error;
0391 pkt[0] = 'E';
0392 pkt[1] = hex_asc[(error / 10)];
0393 pkt[2] = hex_asc[(error % 10)];
0394 pkt[3] = '\0';
0395 }
0396
0397
0398
0399
0400
0401
0402
0403 #define BUF_THREAD_ID_SIZE 8
0404
0405 static char *pack_threadid(char *pkt, unsigned char *id)
0406 {
0407 unsigned char *limit;
0408 int lzero = 1;
0409
0410 limit = id + (BUF_THREAD_ID_SIZE / 2);
0411 while (id < limit) {
0412 if (!lzero || *id != 0) {
0413 pkt = hex_byte_pack(pkt, *id);
0414 lzero = 0;
0415 }
0416 id++;
0417 }
0418
0419 if (lzero)
0420 pkt = hex_byte_pack(pkt, 0);
0421
0422 return pkt;
0423 }
0424
0425 static void int_to_threadref(unsigned char *id, int value)
0426 {
0427 put_unaligned_be32(value, id);
0428 }
0429
0430 static struct task_struct *getthread(struct pt_regs *regs, int tid)
0431 {
0432
0433
0434
0435 if (tid == 0 || tid == -1)
0436 tid = -atomic_read(&kgdb_active) - 2;
0437 if (tid < -1 && tid > -NR_CPUS - 2) {
0438 if (kgdb_info[-tid - 2].task)
0439 return kgdb_info[-tid - 2].task;
0440 else
0441 return idle_task(-tid - 2);
0442 }
0443 if (tid <= 0) {
0444 printk(KERN_ERR "KGDB: Internal thread select error\n");
0445 dump_stack();
0446 return NULL;
0447 }
0448
0449
0450
0451
0452
0453
0454 return find_task_by_pid_ns(tid, &init_pid_ns);
0455 }
0456
0457
0458
0459
0460
0461
0462 static inline int shadow_pid(int realpid)
0463 {
0464 if (realpid)
0465 return realpid;
0466
0467 return -raw_smp_processor_id() - 2;
0468 }
0469
0470
0471
0472
0473
0474
0475
0476
0477 static void gdb_cmd_status(struct kgdb_state *ks)
0478 {
0479
0480
0481
0482
0483
0484
0485 dbg_remove_all_break();
0486
0487 remcom_out_buffer[0] = 'S';
0488 hex_byte_pack(&remcom_out_buffer[1], ks->signo);
0489 }
0490
0491 static void gdb_get_regs_helper(struct kgdb_state *ks)
0492 {
0493 struct task_struct *thread;
0494 void *local_debuggerinfo;
0495 int i;
0496
0497 thread = kgdb_usethread;
0498 if (!thread) {
0499 thread = kgdb_info[ks->cpu].task;
0500 local_debuggerinfo = kgdb_info[ks->cpu].debuggerinfo;
0501 } else {
0502 local_debuggerinfo = NULL;
0503 for_each_online_cpu(i) {
0504
0505
0506
0507
0508
0509
0510 if (thread == kgdb_info[i].task)
0511 local_debuggerinfo = kgdb_info[i].debuggerinfo;
0512 }
0513 }
0514
0515
0516
0517
0518
0519
0520 if (local_debuggerinfo) {
0521 pt_regs_to_gdb_regs(gdb_regs, local_debuggerinfo);
0522 } else {
0523
0524
0525
0526
0527
0528
0529
0530 sleeping_thread_to_gdb_regs(gdb_regs, thread);
0531 }
0532 }
0533
0534
0535 static void gdb_cmd_getregs(struct kgdb_state *ks)
0536 {
0537 gdb_get_regs_helper(ks);
0538 kgdb_mem2hex((char *)gdb_regs, remcom_out_buffer, NUMREGBYTES);
0539 }
0540
0541
0542 static void gdb_cmd_setregs(struct kgdb_state *ks)
0543 {
0544 kgdb_hex2mem(&remcom_in_buffer[1], (char *)gdb_regs, NUMREGBYTES);
0545
0546 if (kgdb_usethread && kgdb_usethread != current) {
0547 error_packet(remcom_out_buffer, -EINVAL);
0548 } else {
0549 gdb_regs_to_pt_regs(gdb_regs, ks->linux_regs);
0550 strcpy(remcom_out_buffer, "OK");
0551 }
0552 }
0553
0554
0555 static void gdb_cmd_memread(struct kgdb_state *ks)
0556 {
0557 char *ptr = &remcom_in_buffer[1];
0558 unsigned long length;
0559 unsigned long addr;
0560 char *err;
0561
0562 if (kgdb_hex2long(&ptr, &addr) > 0 && *ptr++ == ',' &&
0563 kgdb_hex2long(&ptr, &length) > 0) {
0564 err = kgdb_mem2hex((char *)addr, remcom_out_buffer, length);
0565 if (!err)
0566 error_packet(remcom_out_buffer, -EINVAL);
0567 } else {
0568 error_packet(remcom_out_buffer, -EINVAL);
0569 }
0570 }
0571
0572
0573 static void gdb_cmd_memwrite(struct kgdb_state *ks)
0574 {
0575 int err = write_mem_msg(0);
0576
0577 if (err)
0578 error_packet(remcom_out_buffer, err);
0579 else
0580 strcpy(remcom_out_buffer, "OK");
0581 }
0582
0583 #if DBG_MAX_REG_NUM > 0
0584 static char *gdb_hex_reg_helper(int regnum, char *out)
0585 {
0586 int i;
0587 int offset = 0;
0588
0589 for (i = 0; i < regnum; i++)
0590 offset += dbg_reg_def[i].size;
0591 return kgdb_mem2hex((char *)gdb_regs + offset, out,
0592 dbg_reg_def[i].size);
0593 }
0594
0595
0596 static void gdb_cmd_reg_get(struct kgdb_state *ks)
0597 {
0598 unsigned long regnum;
0599 char *ptr = &remcom_in_buffer[1];
0600
0601 kgdb_hex2long(&ptr, ®num);
0602 if (regnum >= DBG_MAX_REG_NUM) {
0603 error_packet(remcom_out_buffer, -EINVAL);
0604 return;
0605 }
0606 gdb_get_regs_helper(ks);
0607 gdb_hex_reg_helper(regnum, remcom_out_buffer);
0608 }
0609
0610
0611 static void gdb_cmd_reg_set(struct kgdb_state *ks)
0612 {
0613 unsigned long regnum;
0614 char *ptr = &remcom_in_buffer[1];
0615 int i = 0;
0616
0617 kgdb_hex2long(&ptr, ®num);
0618 if (*ptr++ != '=' ||
0619 !(!kgdb_usethread || kgdb_usethread == current) ||
0620 !dbg_get_reg(regnum, gdb_regs, ks->linux_regs)) {
0621 error_packet(remcom_out_buffer, -EINVAL);
0622 return;
0623 }
0624 memset(gdb_regs, 0, sizeof(gdb_regs));
0625 while (i < sizeof(gdb_regs) * 2)
0626 if (hex_to_bin(ptr[i]) >= 0)
0627 i++;
0628 else
0629 break;
0630 i = i / 2;
0631 kgdb_hex2mem(ptr, (char *)gdb_regs, i);
0632 dbg_set_reg(regnum, gdb_regs, ks->linux_regs);
0633 strcpy(remcom_out_buffer, "OK");
0634 }
0635 #endif
0636
0637
0638 static void gdb_cmd_binwrite(struct kgdb_state *ks)
0639 {
0640 int err = write_mem_msg(1);
0641
0642 if (err)
0643 error_packet(remcom_out_buffer, err);
0644 else
0645 strcpy(remcom_out_buffer, "OK");
0646 }
0647
0648
0649 static void gdb_cmd_detachkill(struct kgdb_state *ks)
0650 {
0651 int error;
0652
0653
0654 if (remcom_in_buffer[0] == 'D') {
0655 error = dbg_remove_all_break();
0656 if (error < 0) {
0657 error_packet(remcom_out_buffer, error);
0658 } else {
0659 strcpy(remcom_out_buffer, "OK");
0660 kgdb_connected = 0;
0661 }
0662 put_packet(remcom_out_buffer);
0663 } else {
0664
0665
0666
0667
0668 dbg_remove_all_break();
0669 kgdb_connected = 0;
0670 }
0671 }
0672
0673
0674 static int gdb_cmd_reboot(struct kgdb_state *ks)
0675 {
0676
0677 if (strcmp(remcom_in_buffer, "R0") == 0) {
0678 printk(KERN_CRIT "Executing emergency reboot\n");
0679 strcpy(remcom_out_buffer, "OK");
0680 put_packet(remcom_out_buffer);
0681
0682
0683
0684
0685
0686 machine_emergency_restart();
0687 kgdb_connected = 0;
0688
0689 return 1;
0690 }
0691 return 0;
0692 }
0693
0694
0695 static void gdb_cmd_query(struct kgdb_state *ks)
0696 {
0697 struct task_struct *g;
0698 struct task_struct *p;
0699 unsigned char thref[BUF_THREAD_ID_SIZE];
0700 char *ptr;
0701 int i;
0702 int cpu;
0703 int finished = 0;
0704
0705 switch (remcom_in_buffer[1]) {
0706 case 's':
0707 case 'f':
0708 if (memcmp(remcom_in_buffer + 2, "ThreadInfo", 10))
0709 break;
0710
0711 i = 0;
0712 remcom_out_buffer[0] = 'm';
0713 ptr = remcom_out_buffer + 1;
0714 if (remcom_in_buffer[1] == 'f') {
0715
0716 for_each_online_cpu(cpu) {
0717 ks->thr_query = 0;
0718 int_to_threadref(thref, -cpu - 2);
0719 ptr = pack_threadid(ptr, thref);
0720 *(ptr++) = ',';
0721 i++;
0722 }
0723 }
0724
0725 for_each_process_thread(g, p) {
0726 if (i >= ks->thr_query && !finished) {
0727 int_to_threadref(thref, p->pid);
0728 ptr = pack_threadid(ptr, thref);
0729 *(ptr++) = ',';
0730 ks->thr_query++;
0731 if (ks->thr_query % KGDB_MAX_THREAD_QUERY == 0)
0732 finished = 1;
0733 }
0734 i++;
0735 }
0736
0737 *(--ptr) = '\0';
0738 break;
0739
0740 case 'C':
0741
0742 strcpy(remcom_out_buffer, "QC");
0743 ks->threadid = shadow_pid(current->pid);
0744 int_to_threadref(thref, ks->threadid);
0745 pack_threadid(remcom_out_buffer + 2, thref);
0746 break;
0747 case 'T':
0748 if (memcmp(remcom_in_buffer + 1, "ThreadExtraInfo,", 16))
0749 break;
0750
0751 ks->threadid = 0;
0752 ptr = remcom_in_buffer + 17;
0753 kgdb_hex2long(&ptr, &ks->threadid);
0754 if (!getthread(ks->linux_regs, ks->threadid)) {
0755 error_packet(remcom_out_buffer, -EINVAL);
0756 break;
0757 }
0758 if ((int)ks->threadid > 0) {
0759 kgdb_mem2hex(getthread(ks->linux_regs,
0760 ks->threadid)->comm,
0761 remcom_out_buffer, 16);
0762 } else {
0763 static char tmpstr[23 + BUF_THREAD_ID_SIZE];
0764
0765 sprintf(tmpstr, "shadowCPU%d",
0766 (int)(-ks->threadid - 2));
0767 kgdb_mem2hex(tmpstr, remcom_out_buffer, strlen(tmpstr));
0768 }
0769 break;
0770 #ifdef CONFIG_KGDB_KDB
0771 case 'R':
0772 if (strncmp(remcom_in_buffer, "qRcmd,", 6) == 0) {
0773 int len = strlen(remcom_in_buffer + 6);
0774
0775 if ((len % 2) != 0) {
0776 strcpy(remcom_out_buffer, "E01");
0777 break;
0778 }
0779 kgdb_hex2mem(remcom_in_buffer + 6,
0780 remcom_out_buffer, len);
0781 len = len / 2;
0782 remcom_out_buffer[len++] = 0;
0783
0784 kdb_common_init_state(ks);
0785 kdb_parse(remcom_out_buffer);
0786 kdb_common_deinit_state();
0787
0788 strcpy(remcom_out_buffer, "OK");
0789 }
0790 break;
0791 #endif
0792 #ifdef CONFIG_HAVE_ARCH_KGDB_QXFER_PKT
0793 case 'S':
0794 if (!strncmp(remcom_in_buffer, "qSupported:", 11))
0795 strcpy(remcom_out_buffer, kgdb_arch_gdb_stub_feature);
0796 break;
0797 case 'X':
0798 if (!strncmp(remcom_in_buffer, "qXfer:", 6))
0799 kgdb_arch_handle_qxfer_pkt(remcom_in_buffer,
0800 remcom_out_buffer);
0801 break;
0802 #endif
0803 default:
0804 break;
0805 }
0806 }
0807
0808
0809 static void gdb_cmd_task(struct kgdb_state *ks)
0810 {
0811 struct task_struct *thread;
0812 char *ptr;
0813
0814 switch (remcom_in_buffer[1]) {
0815 case 'g':
0816 ptr = &remcom_in_buffer[2];
0817 kgdb_hex2long(&ptr, &ks->threadid);
0818 thread = getthread(ks->linux_regs, ks->threadid);
0819 if (!thread && ks->threadid > 0) {
0820 error_packet(remcom_out_buffer, -EINVAL);
0821 break;
0822 }
0823 kgdb_usethread = thread;
0824 ks->kgdb_usethreadid = ks->threadid;
0825 strcpy(remcom_out_buffer, "OK");
0826 break;
0827 case 'c':
0828 ptr = &remcom_in_buffer[2];
0829 kgdb_hex2long(&ptr, &ks->threadid);
0830 if (!ks->threadid) {
0831 kgdb_contthread = NULL;
0832 } else {
0833 thread = getthread(ks->linux_regs, ks->threadid);
0834 if (!thread && ks->threadid > 0) {
0835 error_packet(remcom_out_buffer, -EINVAL);
0836 break;
0837 }
0838 kgdb_contthread = thread;
0839 }
0840 strcpy(remcom_out_buffer, "OK");
0841 break;
0842 }
0843 }
0844
0845
0846 static void gdb_cmd_thread(struct kgdb_state *ks)
0847 {
0848 char *ptr = &remcom_in_buffer[1];
0849 struct task_struct *thread;
0850
0851 kgdb_hex2long(&ptr, &ks->threadid);
0852 thread = getthread(ks->linux_regs, ks->threadid);
0853 if (thread)
0854 strcpy(remcom_out_buffer, "OK");
0855 else
0856 error_packet(remcom_out_buffer, -EINVAL);
0857 }
0858
0859
0860 static void gdb_cmd_break(struct kgdb_state *ks)
0861 {
0862
0863
0864
0865
0866 char *bpt_type = &remcom_in_buffer[1];
0867 char *ptr = &remcom_in_buffer[2];
0868 unsigned long addr;
0869 unsigned long length;
0870 int error = 0;
0871
0872 if (arch_kgdb_ops.set_hw_breakpoint && *bpt_type >= '1') {
0873
0874 if (*bpt_type > '4')
0875 return;
0876 } else {
0877 if (*bpt_type != '0' && *bpt_type != '1')
0878
0879 return;
0880 }
0881
0882
0883
0884
0885
0886 if (*bpt_type == '1' && !(arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT))
0887
0888 return;
0889
0890 if (*(ptr++) != ',') {
0891 error_packet(remcom_out_buffer, -EINVAL);
0892 return;
0893 }
0894 if (!kgdb_hex2long(&ptr, &addr)) {
0895 error_packet(remcom_out_buffer, -EINVAL);
0896 return;
0897 }
0898 if (*(ptr++) != ',' ||
0899 !kgdb_hex2long(&ptr, &length)) {
0900 error_packet(remcom_out_buffer, -EINVAL);
0901 return;
0902 }
0903
0904 if (remcom_in_buffer[0] == 'Z' && *bpt_type == '0')
0905 error = dbg_set_sw_break(addr);
0906 else if (remcom_in_buffer[0] == 'z' && *bpt_type == '0')
0907 error = dbg_remove_sw_break(addr);
0908 else if (remcom_in_buffer[0] == 'Z')
0909 error = arch_kgdb_ops.set_hw_breakpoint(addr,
0910 (int)length, *bpt_type - '0');
0911 else if (remcom_in_buffer[0] == 'z')
0912 error = arch_kgdb_ops.remove_hw_breakpoint(addr,
0913 (int) length, *bpt_type - '0');
0914
0915 if (error == 0)
0916 strcpy(remcom_out_buffer, "OK");
0917 else
0918 error_packet(remcom_out_buffer, error);
0919 }
0920
0921
0922 static int gdb_cmd_exception_pass(struct kgdb_state *ks)
0923 {
0924
0925
0926
0927 if (remcom_in_buffer[1] == '0' && remcom_in_buffer[2] == '9') {
0928
0929 ks->pass_exception = 1;
0930 remcom_in_buffer[0] = 'c';
0931
0932 } else if (remcom_in_buffer[1] == '1' && remcom_in_buffer[2] == '5') {
0933
0934 ks->pass_exception = 1;
0935 remcom_in_buffer[0] = 'D';
0936 dbg_remove_all_break();
0937 kgdb_connected = 0;
0938 return 1;
0939
0940 } else {
0941 gdbstub_msg_write("KGDB only knows signal 9 (pass)"
0942 " and 15 (pass and disconnect)\n"
0943 "Executing a continue without signal passing\n", 0);
0944 remcom_in_buffer[0] = 'c';
0945 }
0946
0947
0948 return -1;
0949 }
0950
0951
0952
0953
0954 int gdb_serial_stub(struct kgdb_state *ks)
0955 {
0956 int error = 0;
0957 int tmp;
0958
0959
0960 memset(remcom_out_buffer, 0, sizeof(remcom_out_buffer));
0961 kgdb_usethread = kgdb_info[ks->cpu].task;
0962 ks->kgdb_usethreadid = shadow_pid(kgdb_info[ks->cpu].task->pid);
0963 ks->pass_exception = 0;
0964
0965 if (kgdb_connected) {
0966 unsigned char thref[BUF_THREAD_ID_SIZE];
0967 char *ptr;
0968
0969
0970 ptr = remcom_out_buffer;
0971 *ptr++ = 'T';
0972 ptr = hex_byte_pack(ptr, ks->signo);
0973 ptr += strlen(strcpy(ptr, "thread:"));
0974 int_to_threadref(thref, shadow_pid(current->pid));
0975 ptr = pack_threadid(ptr, thref);
0976 *ptr++ = ';';
0977 put_packet(remcom_out_buffer);
0978 }
0979
0980 while (1) {
0981 error = 0;
0982
0983
0984 memset(remcom_out_buffer, 0, sizeof(remcom_out_buffer));
0985
0986 get_packet(remcom_in_buffer);
0987
0988 switch (remcom_in_buffer[0]) {
0989 case '?':
0990 gdb_cmd_status(ks);
0991 break;
0992 case 'g':
0993 gdb_cmd_getregs(ks);
0994 break;
0995 case 'G':
0996 gdb_cmd_setregs(ks);
0997 break;
0998 case 'm':
0999 gdb_cmd_memread(ks);
1000 break;
1001 case 'M':
1002 gdb_cmd_memwrite(ks);
1003 break;
1004 #if DBG_MAX_REG_NUM > 0
1005 case 'p':
1006 gdb_cmd_reg_get(ks);
1007 break;
1008 case 'P':
1009 gdb_cmd_reg_set(ks);
1010 break;
1011 #endif
1012 case 'X':
1013 gdb_cmd_binwrite(ks);
1014 break;
1015
1016
1017
1018 case 'D':
1019 case 'k':
1020 gdb_cmd_detachkill(ks);
1021 goto default_handle;
1022 case 'R':
1023 if (gdb_cmd_reboot(ks))
1024 goto default_handle;
1025 break;
1026 case 'q':
1027 gdb_cmd_query(ks);
1028 break;
1029 case 'H':
1030 gdb_cmd_task(ks);
1031 break;
1032 case 'T':
1033 gdb_cmd_thread(ks);
1034 break;
1035 case 'z':
1036 case 'Z':
1037 gdb_cmd_break(ks);
1038 break;
1039 #ifdef CONFIG_KGDB_KDB
1040 case '3':
1041 if (remcom_in_buffer[1] == '\0') {
1042 gdb_cmd_detachkill(ks);
1043 return DBG_PASS_EVENT;
1044 }
1045 fallthrough;
1046 #endif
1047 case 'C':
1048 tmp = gdb_cmd_exception_pass(ks);
1049 if (tmp > 0)
1050 goto default_handle;
1051 if (tmp == 0)
1052 break;
1053 fallthrough;
1054 case 'c':
1055 case 's':
1056 if (kgdb_contthread && kgdb_contthread != current) {
1057
1058 error_packet(remcom_out_buffer, -EINVAL);
1059 break;
1060 }
1061 fallthrough;
1062 default:
1063 default_handle:
1064 error = kgdb_arch_handle_exception(ks->ex_vector,
1065 ks->signo,
1066 ks->err_code,
1067 remcom_in_buffer,
1068 remcom_out_buffer,
1069 ks->linux_regs);
1070
1071
1072
1073
1074 if (error >= 0 || remcom_in_buffer[0] == 'D' ||
1075 remcom_in_buffer[0] == 'k') {
1076 error = 0;
1077 goto kgdb_exit;
1078 }
1079
1080 }
1081
1082
1083 put_packet(remcom_out_buffer);
1084 }
1085
1086 kgdb_exit:
1087 if (ks->pass_exception)
1088 error = 1;
1089 return error;
1090 }
1091
1092 int gdbstub_state(struct kgdb_state *ks, char *cmd)
1093 {
1094 int error;
1095
1096 switch (cmd[0]) {
1097 case 'e':
1098 error = kgdb_arch_handle_exception(ks->ex_vector,
1099 ks->signo,
1100 ks->err_code,
1101 remcom_in_buffer,
1102 remcom_out_buffer,
1103 ks->linux_regs);
1104 return error;
1105 case 's':
1106 case 'c':
1107 strscpy(remcom_in_buffer, cmd, sizeof(remcom_in_buffer));
1108 return 0;
1109 case '$':
1110 strscpy(remcom_in_buffer, cmd, sizeof(remcom_in_buffer));
1111 gdbstub_use_prev_in_buf = strlen(remcom_in_buffer);
1112 gdbstub_prev_in_buf_pos = 0;
1113 return 0;
1114 }
1115 dbg_io_ops->write_char('+');
1116 put_packet(remcom_out_buffer);
1117 return 0;
1118 }
1119
1120
1121
1122
1123
1124 void gdbstub_exit(int status)
1125 {
1126 unsigned char checksum, ch, buffer[3];
1127 int loop;
1128
1129 if (!kgdb_connected)
1130 return;
1131 kgdb_connected = 0;
1132
1133 if (!dbg_io_ops || dbg_kdb_mode)
1134 return;
1135
1136 buffer[0] = 'W';
1137 buffer[1] = hex_asc_hi(status);
1138 buffer[2] = hex_asc_lo(status);
1139
1140 dbg_io_ops->write_char('$');
1141 checksum = 0;
1142
1143 for (loop = 0; loop < 3; loop++) {
1144 ch = buffer[loop];
1145 checksum += ch;
1146 dbg_io_ops->write_char(ch);
1147 }
1148
1149 dbg_io_ops->write_char('#');
1150 dbg_io_ops->write_char(hex_asc_hi(checksum));
1151 dbg_io_ops->write_char(hex_asc_lo(checksum));
1152
1153
1154 if (dbg_io_ops->flush)
1155 dbg_io_ops->flush();
1156 }