1
0

gdb_stub.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005
  1. /*
  2. * GDB stub.
  3. *
  4. * Migarte form linux to rt-thread by Wzyy2
  5. * Original edition : KGDB stub
  6. *
  7. * File : gdb_stub.c
  8. * This file is part of RT-Thread RTOS
  9. * COPYRIGHT (C) 2006, RT-Thread Develop Team
  10. *
  11. * The license and distribution terms for this file may be
  12. * found in the file LICENSE in this distribution or at
  13. * http://www.rt-thread.org/license/LICENSE
  14. *
  15. * Change Logs:
  16. * Date Author Notes
  17. * 2014-07-04 Wzyy2 first version
  18. *
  19. * This file incorporates work covered by the following copyright and
  20. * permission notice:
  21. *
  22. * KGDB stub.
  23. *
  24. * Maintainer: Jason Wessel <jason.wessel@windriver.com>
  25. *
  26. * Copyright (C) 2000-2001 VERITAS Software Corporation.
  27. * Copyright (C) 2002-2004 Timesys Corporation
  28. * Copyright (C) 2003-2004 Amit S. Kale <amitkale@linsyssoft.com>
  29. * Copyright (C) 2004 Pavel Machek <pavel@suse.cz>
  30. * Copyright (C) 2004-2006 Tom Rini <trini@kernel.crashing.org>
  31. * Copyright (C) 2004-2006 LinSysSoft Technologies Pvt. Ltd.
  32. * Copyright (C) 2005-2008 Wind River Systems, Inc.
  33. * Copyright (C) 2007 MontaVista Software, Inc.
  34. * Copyright (C) 2008 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
  35. *
  36. * Contributors at various stages not listed above:
  37. * Jason Wessel ( jason.wessel@windriver.com )
  38. * George Anzinger <george@mvista.com>
  39. * Anurekh Saxena (anurekh.saxena@timesys.com)
  40. * Lake Stevens Instrument Division (Glenn Engel)
  41. * Jim Kingdon, Cygnus Support.
  42. *
  43. * Original KGDB stub: David Grothe <dave@gcom.com>,
  44. * Tigran Aivazian <tigran@sco.com>
  45. *
  46. * This file is licensed under the terms of the GNU General Public License
  47. * version 2. This program is licensed "as is" without any warranty of any
  48. * kind, whether express or implied.
  49. */
  50. #include <rtthread.h>
  51. #include <rthw.h>
  52. #include <string.h>
  53. #include "gdb_stub.h"
  54. struct gdb_state {
  55. int signo;
  56. int pass_exception;
  57. }gs;
  58. /**
  59. * gdb_connected - Is a host GDB connected to us?
  60. */
  61. int gdb_connected;
  62. /*
  63. * Holds information about breakpoints in a kernel. These breakpoints are
  64. * added and removed by gdb.
  65. */
  66. #if RT_GDB_HAVE_SWBP
  67. static struct gdb_bkpt gdb_break[GDB_MAX_BREAKPOINTS] = {
  68. [0 ... GDB_MAX_BREAKPOINTS-1] = { .state = BP_UNDEFINED }
  69. };
  70. #endif
  71. /* Storage for the registers, in GDB format. */
  72. static unsigned long gdb_regs[(NUMREGBYTES +
  73. sizeof(unsigned long) - 1) /
  74. sizeof(unsigned long)];
  75. char remcom_in_buffer[BUFMAX];
  76. char remcom_out_buffer[BUFMAX];
  77. static const char hexchars[] = "0123456789abcdef";
  78. //to call that there has been an error
  79. void* volatile gdb_mem_fault_handler = (void *)0;
  80. static long probe_kernel_write(void *dst, void *src, size_t size)
  81. {
  82. int i = 0;
  83. char *dst_ptr = (char *)dst;
  84. char *src_ptr = (char *)src;
  85. gdb_mem_fault_handler = &&err;
  86. for (i = 0; i<size; i++) {
  87. *(dst_ptr++) = *(src_ptr++);
  88. }
  89. gdb_mem_fault_handler = (void *)0;
  90. return 0;
  91. err:
  92. gdb_mem_fault_handler = (void *)0;
  93. return -1;
  94. }
  95. /*
  96. * GDB remote protocol parser:
  97. */
  98. static int hex(char ch)
  99. {
  100. if ((ch >= 'a') && (ch <= 'f'))
  101. return ch - 'a' + 10;
  102. if ((ch >= '0') && (ch <= '9'))
  103. return ch - '0';
  104. if ((ch >= 'A') && (ch <= 'F'))
  105. return ch - 'A' + 10;
  106. return -1;
  107. }
  108. static char tohex(char c)
  109. {
  110. return hexchars[c & 15];
  111. }
  112. /*
  113. * Copy the binary array pointed to by buf into mem. Fix $, #, and
  114. * 0x7d escaped with 0x7d. Return a pointer to the character after
  115. * the last byte written.
  116. */
  117. int gdb_ebin2mem(char *buf, char *mem, int count)
  118. {
  119. int err = 0;
  120. char c;
  121. while (count-- > 0) {
  122. c = *buf++;
  123. if (c == 0x7d)
  124. c = *buf++ ^ 0x20;
  125. err = probe_kernel_write(mem, &c, 1);
  126. if (err)
  127. break;
  128. mem++;
  129. }
  130. return err;
  131. }
  132. /*
  133. * Convert the hex array pointed to by buf into binary to be placed in mem.
  134. * Return a pointer to the character AFTER the last byte written.
  135. * May return an error.
  136. */
  137. int gdb_hex2mem(char *buf, char *mem, int count)
  138. {
  139. char *tmp_raw;
  140. char *tmp_hex;
  141. tmp_raw = buf + count * 2;
  142. tmp_hex = tmp_raw - 1;
  143. while (tmp_hex >= buf) {
  144. tmp_raw--;
  145. *tmp_raw = hex(*tmp_hex--);
  146. *tmp_raw |= hex(*tmp_hex--) << 4;
  147. }
  148. return probe_kernel_write(mem, tmp_raw, count);
  149. }
  150. /*
  151. * Convert the memory pointed to by mem into hex, placing result in buf.
  152. * Return a pointer to the last char put in buf (null). May return an error.
  153. */
  154. int gdb_mem2hex(char *mem, char *buf, int count)
  155. {
  156. char *tmp = mem;
  157. char ch;
  158. gdb_mem_fault_handler = &&err;
  159. while (count > 0) {
  160. ch = *(tmp++);
  161. *(buf++) = tohex((ch >> 4) & 0xf);
  162. *(buf++) = tohex(ch & 0xf);
  163. count--;
  164. }
  165. *buf = 0;
  166. gdb_mem_fault_handler = (void *)0;
  167. return 0;
  168. err:
  169. gdb_mem_fault_handler = (void *)0;
  170. return -1;
  171. }
  172. /*
  173. * While we find nice hex chars, build a long_val.
  174. * Return number of chars processed.
  175. */
  176. int gdb_hex2long(char **ptr, unsigned long *long_val)
  177. {
  178. int hex_val;
  179. int num = 0;
  180. int negate = 0;
  181. *long_val = 0;
  182. if (**ptr == '-') {
  183. negate = 1;
  184. (*ptr)++;
  185. }
  186. while (**ptr) {
  187. hex_val = hex(**ptr);
  188. if (hex_val < 0)
  189. break;
  190. *long_val = (*long_val << 4) | hex_val;
  191. num++;
  192. (*ptr)++;
  193. }
  194. if (negate)
  195. *long_val = -*long_val;
  196. return num;
  197. }
  198. /* Write memory due to an 'M' or 'X' packet. */
  199. static int write_mem_msg(int binary)
  200. {
  201. char *ptr = &remcom_in_buffer[1];
  202. unsigned long addr;
  203. unsigned long length;
  204. int err;
  205. if (gdb_hex2long(&ptr, &addr) > 0 && *(ptr++) == ',' &&
  206. gdb_hex2long(&ptr, &length) > 0 && *(ptr++) == ':') {
  207. #ifdef GDB_DATA_ACCESS
  208. //accesses to areas not backed can cause error
  209. if (gdb_permit_data_access(addr, length))
  210. return -1;
  211. #endif
  212. if (binary)
  213. err = gdb_ebin2mem(ptr, (char *)addr, length);
  214. else
  215. err = gdb_hex2mem(ptr, (char *)addr, length);
  216. if (err)
  217. return err;
  218. #ifdef RT_GDB_ICACHE
  219. if (CACHE_FLUSH_IS_SAFE)
  220. gdb_flush_icache_range(addr, addr + length);
  221. #endif
  222. return 0;
  223. }
  224. return -1;
  225. }
  226. /*
  227. * Send the packet in buffer.
  228. * Check for gdb connection if asked for.
  229. */
  230. static void put_packet(char *buffer)
  231. {
  232. unsigned char checksum;
  233. int count;
  234. char ch;
  235. /*
  236. * $<packet info>#<checksum>.
  237. */
  238. while (1) {
  239. gdb_io_ops.write_char('$');
  240. checksum = 0;
  241. count = 0;
  242. while ((ch = buffer[count])) {
  243. gdb_io_ops.write_char(ch);
  244. checksum += ch;
  245. count++;
  246. }
  247. gdb_io_ops.write_char('#');
  248. gdb_io_ops.write_char(tohex((checksum >> 4) & 0xf));
  249. gdb_io_ops.write_char(tohex(checksum & 0xf));
  250. /* Now see what we get in reply. */
  251. ch = gdb_io_ops.read_char();
  252. /* If we get an ACK, we are done. */
  253. if (ch == '+')
  254. return;
  255. /*
  256. * If we get the start of another packet, this means
  257. * that GDB is attempting to reconnect. We will NAK
  258. * the packet being sent, and stop trying to send this
  259. * packet.
  260. */
  261. if (ch == '$') {
  262. gdb_io_ops.write_char('-');
  263. if (gdb_io_ops.flush)
  264. gdb_io_ops.flush();
  265. return;
  266. }
  267. }
  268. }
  269. /* scan for the sequence $<data>#<checksum> */
  270. static void get_packet(char *buffer)
  271. {
  272. unsigned char checksum;
  273. unsigned char xmitcsum;
  274. int count;
  275. char ch;
  276. do {
  277. /*
  278. * Spin and wait around for the start character, ignore all
  279. * other characters:
  280. */
  281. while ((ch = (gdb_io_ops.read_char())) != '$')
  282. /* nothing */;
  283. gdb_connected = 1;
  284. checksum = 0;
  285. xmitcsum = -1;
  286. count = 0;
  287. /*
  288. * now, read until a # or end of buffer is found:
  289. */
  290. while (count < (BUFMAX - 1)) {
  291. ch = gdb_io_ops.read_char();
  292. if (ch == '#')
  293. break;
  294. checksum = checksum + ch;
  295. buffer[count] = ch;
  296. count = count + 1;
  297. }
  298. buffer[count] = 0;
  299. if (ch == '#') {
  300. xmitcsum = hex(gdb_io_ops.read_char()) << 4;
  301. xmitcsum += hex(gdb_io_ops.read_char());
  302. if (checksum != xmitcsum)
  303. /* failed checksum */
  304. gdb_io_ops.write_char('-');
  305. else
  306. /* successful transfer */
  307. gdb_io_ops.write_char('+');
  308. if (gdb_io_ops.flush)
  309. gdb_io_ops.flush();
  310. }
  311. } while (checksum != xmitcsum);
  312. }
  313. static void error_packet(char *pkt, int error)
  314. {
  315. error = -error;
  316. pkt[0] = 'E';
  317. pkt[1] = tohex((error / 10));
  318. pkt[2] = tohex((error % 10));
  319. pkt[3] = '\0';
  320. }
  321. #if RT_GDB_HAVE_SWBP
  322. static int gdb_arch_set_breakpoint(unsigned long addr, char *saved_instr)
  323. {
  324. int err;
  325. err = probe_kernel_write((void *)saved_instr, (void *)addr, BREAK_INSTR_SIZE);
  326. if (err)
  327. return err;
  328. return probe_kernel_write((void *)addr, (void *)arch_gdb_ops.gdb_bpt_instr,
  329. BREAK_INSTR_SIZE);
  330. }
  331. static int gdb_arch_remove_breakpoint(unsigned long addr, char *bundle)
  332. {
  333. return probe_kernel_write((void *)addr,
  334. (void *)bundle, BREAK_INSTR_SIZE);
  335. }
  336. static int gdb_validate_break_address(unsigned long addr)
  337. {
  338. char tmp_variable[BREAK_INSTR_SIZE];
  339. int err;
  340. /* Validate setting the breakpoint and then removing it. In the
  341. * remove fails, the kernel needs to emit a bad message because we
  342. * are deep trouble not being able to put things back the way we
  343. * found them.
  344. */
  345. err = gdb_arch_set_breakpoint(addr, tmp_variable);
  346. if (err)
  347. return err;
  348. err = gdb_arch_remove_breakpoint(addr, tmp_variable);
  349. if (err)
  350. rt_kprintf("GDB: Critical breakpoint error,memory destroyed at: %08x \n", addr);
  351. return err;
  352. }
  353. /*
  354. * Some architectures need cache flushes when we set/clear a
  355. * breakpoint:
  356. */
  357. static void gdb_flush_swbreak_addr(unsigned long addr)
  358. {
  359. if (!CACHE_FLUSH_IS_SAFE)
  360. return;
  361. /* Force flush instruction cache if it was outside the mm */
  362. gdb_flush_icache_range(addr, addr + BREAK_INSTR_SIZE);
  363. }
  364. /*
  365. * SW breakpoint management:
  366. */
  367. static int gdb_activate_sw_breakpoints(void)
  368. {
  369. unsigned long addr;
  370. int error = 0;
  371. int i;
  372. for (i = 0; i < GDB_MAX_BREAKPOINTS; i++) {
  373. if (gdb_break[i].state != BP_SET)
  374. continue;
  375. addr = gdb_break[i].bpt_addr;
  376. error = gdb_arch_set_breakpoint(addr,
  377. (char *)(gdb_break[i].saved_instr));
  378. if (error)
  379. return error;
  380. gdb_flush_swbreak_addr(addr);
  381. gdb_break[i].state = BP_ACTIVE;
  382. }
  383. return 0;
  384. }
  385. int gdb_set_sw_break(unsigned long addr)
  386. {
  387. int err = gdb_validate_break_address(addr);
  388. int breakno = -1;
  389. int i;
  390. if (err)
  391. return err;
  392. for (i = 0; i < GDB_MAX_BREAKPOINTS; i++) {
  393. if ((gdb_break[i].state == BP_SET) &&
  394. (gdb_break[i].bpt_addr == addr))
  395. return -1;
  396. }
  397. for (i = 0; i < GDB_MAX_BREAKPOINTS; i++) {
  398. if (gdb_break[i].state == BP_REMOVED) {
  399. breakno = i;
  400. break;
  401. }
  402. }
  403. if (breakno == -1) {
  404. for (i = 0; i < GDB_MAX_BREAKPOINTS; i++) {
  405. if (gdb_break[i].state == BP_UNDEFINED) {
  406. breakno = i;
  407. break;
  408. }
  409. }
  410. }
  411. if (breakno == -1)
  412. return -1;
  413. gdb_break[breakno].state = BP_SET;
  414. gdb_break[breakno].type = BP_BREAKPOINT;
  415. gdb_break[breakno].bpt_addr = addr;
  416. return 0;
  417. }
  418. static int gdb_deactivate_sw_breakpoints(void)
  419. {
  420. unsigned long addr;
  421. int error = 0;
  422. int i;
  423. for (i = 0; i < GDB_MAX_BREAKPOINTS; i++) {
  424. if (gdb_break[i].state != BP_ACTIVE)
  425. continue;
  426. addr = gdb_break[i].bpt_addr;
  427. error = gdb_arch_remove_breakpoint(addr,
  428. (char *)(gdb_break[i].saved_instr));
  429. if (error)
  430. return error;
  431. gdb_flush_swbreak_addr(addr);
  432. gdb_break[i].state = BP_SET;
  433. }
  434. return 0;
  435. }
  436. int gdb_remove_sw_break(unsigned long addr)
  437. {
  438. int i;
  439. for (i = 0; i < GDB_MAX_BREAKPOINTS; i++) {
  440. if ((gdb_break[i].state == BP_SET) &&
  441. (gdb_break[i].bpt_addr == addr)) {
  442. gdb_break[i].state = BP_REMOVED;
  443. return 0;
  444. }
  445. }
  446. return -1;
  447. }
  448. int gdb_isremovedbreak(unsigned long addr)
  449. {
  450. int i;
  451. for (i = 0; i < GDB_MAX_BREAKPOINTS; i++) {
  452. if ((gdb_break[i].state == BP_REMOVED) &&
  453. (gdb_break[i].bpt_addr == addr))
  454. return 1;
  455. }
  456. return 0;
  457. }
  458. #endif
  459. static int remove_all_break()
  460. {
  461. #if RT_GDB_HAVE_SWBP
  462. unsigned long addr;
  463. int error=0;
  464. int i;
  465. /* Clear memory breakpoints. */
  466. for (i = 0; i < GDB_MAX_BREAKPOINTS; i++) {
  467. if (gdb_break[i].state != BP_ACTIVE)
  468. goto setundefined;
  469. addr = gdb_break[i].bpt_addr;
  470. error = gdb_arch_remove_breakpoint(addr,
  471. (char *)gdb_break[i].saved_instr);
  472. if (error)
  473. rt_kprintf("GDB: breakpoint remove failed: %lx\n",
  474. addr);
  475. setundefined:
  476. gdb_break[i].state = BP_UNDEFINED;
  477. }
  478. #endif
  479. #if RT_GDB_HAVE_HWBP
  480. /* Clear hardware breakpoints. */
  481. arch_gdb_ops.remove_all_hw_break();
  482. #endif
  483. return 0;
  484. }
  485. static char gdbmsgbuf[BUFMAX + 1];
  486. static void gdb_msg_write(const char *s, int len)
  487. {
  488. char *bufptr;
  489. int wcount;
  490. int i;
  491. /* 'O'utput */
  492. gdbmsgbuf[0] = 'O';
  493. /* Fill and send buffers... */
  494. while (len > 0) {
  495. bufptr = gdbmsgbuf + 1;
  496. /* Calculate how many this time */
  497. if ((len << 1) > (BUFMAX - 2))
  498. wcount = (BUFMAX - 2) >> 1;
  499. else
  500. wcount = len;
  501. /* Pack in hex chars */
  502. for (i = 0; i < wcount; i++) {
  503. *(bufptr++) = tohex((s[i] >> 4) & 0xf);
  504. *(bufptr++) = tohex(s[i] & 0xf);
  505. }
  506. *bufptr = '\0';
  507. /* Move up */
  508. s += wcount;
  509. len -= wcount;
  510. /* Write packet */
  511. put_packet(gdbmsgbuf);
  512. }
  513. }
  514. /*
  515. * Return true if there is a valid gdb I/O module. Also if no
  516. * debugger is attached a message can be printed to the console about
  517. * waiting for the debugger to attach.
  518. *
  519. * The print_wait argument is only to be true when called from inside
  520. * the core gdb_handle_exception, because it will wait for the
  521. * debugger to attach.
  522. */
  523. static int gdb_io_ready(int print_wait)
  524. {
  525. if (!gdb_dev)
  526. return 0;
  527. if (gdb_connected)
  528. return 1;
  529. if (print_wait)
  530. rt_kprintf("GDB: Waiting for remote debugger\n");
  531. return 1;
  532. }
  533. /* Handle the '?' status packets */
  534. static void gdb_cmd_status(struct gdb_state *gs)
  535. {
  536. /*
  537. * We know that this packet is only sent
  538. * during initial connect. So to be safe,
  539. * we clear out our breakpoints now in case
  540. * GDB is reconnecting.
  541. */
  542. remove_all_break();
  543. remcom_out_buffer[0] = 'S';
  544. remcom_out_buffer[1] = tohex((gs->signo >> 4) &0xf);
  545. remcom_out_buffer[2] = tohex(gs->signo & 0xf);
  546. remcom_out_buffer[3] = 0;
  547. }
  548. /* Handle the 'm' memory read bytes */
  549. static void gdb_cmd_memread(struct gdb_state *gs)
  550. {
  551. char *ptr = &remcom_in_buffer[1];
  552. unsigned long length;
  553. unsigned long addr;
  554. int err;
  555. if (gdb_hex2long(&ptr, &addr) > 0 && *ptr++ == ',' &&
  556. gdb_hex2long(&ptr, &length) > 0) {
  557. #ifdef GDB_DATA_ACCESS
  558. //accesses to areas not backed can cause error
  559. if (gdb_permit_data_access(addr, length))
  560. return ;
  561. #endif
  562. err = gdb_mem2hex((char *)addr, remcom_out_buffer, length);
  563. if (err)
  564. error_packet(remcom_out_buffer, err);
  565. } else {
  566. error_packet(remcom_out_buffer, -1);
  567. }
  568. }
  569. /* Handle the 'M' memory write bytes */
  570. static void gdb_cmd_memwrite(struct gdb_state *gs)
  571. {
  572. int err = write_mem_msg(0);
  573. if (err)
  574. error_packet(remcom_out_buffer, err);
  575. else
  576. strcpy(remcom_out_buffer, "OK");
  577. }
  578. /* Handle the 'X' memory binary write bytes */
  579. static void gdb_cmd_binwrite(struct gdb_state *gs)
  580. {
  581. int err = write_mem_msg(1);
  582. if (err)
  583. error_packet(remcom_out_buffer, err);
  584. else
  585. strcpy(remcom_out_buffer, "OK");
  586. }
  587. /* Handle the 'q' query packets */
  588. static void gdb_cmd_query(struct gdb_state *gs)
  589. {
  590. /* nothing,because we have no thread support */
  591. }
  592. /* Handle the 'g' or 'p' get registers request */
  593. static void gdb_cmd_getregs(struct gdb_state *gs)
  594. {
  595. char len = sizeof(long);
  596. gdb_get_register((unsigned long *)gdb_regs);
  597. /*get one registers*/
  598. if (remcom_in_buffer[0] == 'p'){
  599. char *p = &remcom_in_buffer[1];
  600. unsigned long regno = 0;
  601. if (gdb_hex2long(&p, &regno)){
  602. gdb_mem2hex(((char *)gdb_regs) + regno * len, remcom_out_buffer, len);
  603. return;
  604. } else {
  605. strcpy(remcom_out_buffer, "INVALID");
  606. return;
  607. }
  608. }
  609. gdb_mem2hex((char *)gdb_regs, remcom_out_buffer, NUMREGBYTES);
  610. }
  611. /* Handle the 'G' or 'P' set registers request */
  612. static void gdb_cmd_setregs(struct gdb_state *gs)
  613. {
  614. char len = sizeof(long);
  615. /*set one registers*/
  616. if (remcom_in_buffer[0] == 'P'){
  617. char *p = &remcom_in_buffer[1];
  618. unsigned long regno = 0;
  619. if (gdb_hex2long(&p, &regno) && *p++ == '='){
  620. gdb_get_register((unsigned long *)gdb_regs);
  621. gdb_hex2mem(p, ((char *)gdb_regs) + regno * len, len);
  622. gdb_put_register(gdb_regs);
  623. strcpy(remcom_out_buffer, "OK");
  624. }
  625. return;
  626. }
  627. gdb_hex2mem(&remcom_in_buffer[1], (char *)gdb_regs, NUMREGBYTES);
  628. gdb_put_register(gdb_regs);
  629. strcpy(remcom_out_buffer, "OK");
  630. }
  631. /* Handle the 'D' or 'k', detach or kill packets */
  632. static void gdb_cmd_detachkill(struct gdb_state *gs)
  633. {
  634. int error;
  635. /* The detach case */
  636. if (remcom_in_buffer[0] == 'D') {
  637. error = remove_all_break();
  638. if (error < 0) {
  639. error_packet(remcom_out_buffer, error);
  640. } else {
  641. strcpy(remcom_out_buffer, "OK");
  642. gdb_connected = 0;
  643. }
  644. put_packet(remcom_out_buffer);
  645. } else {
  646. /*
  647. * Assume the kill case, with no exit code checking,
  648. * trying to force detach the debugger:
  649. */
  650. remove_all_break();
  651. gdb_connected = 0;
  652. }
  653. }
  654. /* Handle the 'z' or 'Z' breakpoint remove or set packets */
  655. static void gdb_cmd_break(struct gdb_state *gs)
  656. {
  657. /*
  658. * Since GDB-5.3, it's been drafted that '0' is a software
  659. * breakpoint, '1' is a hardware breakpoint, so let's do that.
  660. */
  661. char *bpt_type = &remcom_in_buffer[1];
  662. char *ptr = &remcom_in_buffer[2];
  663. unsigned long addr;
  664. unsigned long length;
  665. int error = 0;
  666. if (arch_gdb_ops.set_hw_breakpoint && *bpt_type >= '1') {
  667. /* Unsupported */
  668. if (*bpt_type > '4')
  669. return;
  670. }
  671. /*
  672. * Test if this is a hardware breakpoint, and
  673. * if we support it:
  674. */
  675. if (*bpt_type == '1' && !(arch_gdb_ops.flags)) {
  676. /* Unsupported. */
  677. return;
  678. }
  679. if (*(ptr++) != ',') {
  680. error_packet(remcom_out_buffer, -1);
  681. return;
  682. }
  683. if (!gdb_hex2long(&ptr, &addr)) {
  684. error_packet(remcom_out_buffer, -1);
  685. return;
  686. }
  687. if (*(ptr++) != ',' ||
  688. !gdb_hex2long(&ptr, &length)) {
  689. error_packet(remcom_out_buffer, -1);
  690. return;
  691. }
  692. #if RT_GDB_HAVE_SWBP
  693. if (remcom_in_buffer[0] == 'Z' && *bpt_type == '0')
  694. error = gdb_set_sw_break(addr);
  695. else if (remcom_in_buffer[0] == 'z' && *bpt_type == '0')
  696. error = gdb_remove_sw_break(addr);
  697. #else
  698. if (remcom_in_buffer[0] == 'Z' && *bpt_type == '0')
  699. error = arch_gdb_ops.set_hw_breakpoint(addr,
  700. (int)length, BP_HARDWARE_BREAKPOINT);
  701. else if (remcom_in_buffer[0] == 'z' && *bpt_type == '0')
  702. error = arch_gdb_ops.remove_hw_breakpoint(addr,
  703. (int) length, BP_HARDWARE_BREAKPOINT);
  704. #endif
  705. else if (remcom_in_buffer[0] == 'Z')
  706. error = arch_gdb_ops.set_hw_breakpoint(addr,
  707. (int)length, *bpt_type - '0');
  708. else if (remcom_in_buffer[0] == 'z')
  709. error = arch_gdb_ops.remove_hw_breakpoint(addr,
  710. (int) length, *bpt_type - '0');
  711. if (error == 0)
  712. strcpy(remcom_out_buffer, "OK");
  713. else
  714. error_packet(remcom_out_buffer, error);
  715. }
  716. /* Handle the 'C' signal / exception passing packets */
  717. static int gdb_cmd_exception_pass(struct gdb_state *gs)
  718. {
  719. /* C09 == pass exception
  720. * C15 == detach gdb, pass exception
  721. */
  722. if (remcom_in_buffer[1] == '0' && remcom_in_buffer[2] == '9') {
  723. gs->pass_exception = 1;
  724. remcom_in_buffer[0] = 'c';
  725. } else if (remcom_in_buffer[1] == '1' && remcom_in_buffer[2] == '5') {
  726. gs->pass_exception = 1;
  727. remcom_in_buffer[0] = 'D';
  728. remove_all_break();
  729. gdb_connected = 0;
  730. return 1;
  731. } else {
  732. error_packet(remcom_out_buffer, -1);
  733. return 0;
  734. }
  735. /* Indicate fall through */
  736. return -1;
  737. }
  738. /*more about packet in https://www.sourceware.org/gdb/current/onlinedocs/gdb/Packets.html#Packets*/
  739. static int process_packet(char *pkt)
  740. {
  741. int status = 0;
  742. int tmp;
  743. status = gdb_arch_handle_exception(remcom_in_buffer,
  744. remcom_out_buffer);
  745. remcom_out_buffer[0] = 0;
  746. switch (pkt[0]) {
  747. case '?':/* gdbserial status */
  748. gdb_cmd_status(&gs);
  749. break;
  750. case 'q':/* query command */
  751. gdb_cmd_query(&gs);
  752. break;
  753. case 'p': /* return the value of a single CPU register */
  754. case 'g': /* return the value of the CPU registers */
  755. gdb_cmd_getregs(&gs);
  756. break;
  757. case 'P': /* set the value of a single CPU registers - return OK */
  758. case 'G': /* set the value of the CPU registers - return OK */
  759. gdb_cmd_setregs(&gs);
  760. break;
  761. case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
  762. gdb_cmd_memread(&gs);
  763. break;
  764. case 'X':/* XAA..AA,LLLL: Write LLLL escaped binary bytes at address AA.AA*/
  765. gdb_cmd_binwrite(&gs);
  766. break;
  767. case 'M':/* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
  768. gdb_cmd_memwrite(&gs);
  769. break;
  770. case 'D': /* Debugger detach */
  771. case 'k': /* Debugger detach via kill */
  772. gdb_cmd_detachkill(&gs);
  773. break;
  774. case 'C':/* Exception passing */
  775. tmp = gdb_cmd_exception_pass(&gs);
  776. if (tmp > 0)
  777. process_packet(remcom_in_buffer);
  778. if (tmp == 0)
  779. break;
  780. case 'z':/* Break point remove */
  781. case 'Z':/* Break point set */
  782. gdb_cmd_break(&gs);
  783. break;
  784. case 'H':/* task related */
  785. break;
  786. case 'T':/* Query thread status */
  787. break;
  788. case 'b': /* bBB... Set baud rate to BB... */
  789. break;
  790. case 's': /* sAA..AA step form address AA..AA (optional) */
  791. case 'c': /* cAA..AA Continue at address AA..AA (optional) */
  792. #if RT_GDB_HAVE_SWBP
  793. gdb_activate_sw_breakpoints();
  794. #endif
  795. break;
  796. }
  797. if (!status)
  798. return -1;
  799. exit:
  800. put_packet(remcom_out_buffer);
  801. return 0;
  802. }
  803. /*
  804. * This function does all command procesing for interfacing to gdb.
  805. */
  806. int gdb_process_exception()
  807. {
  808. int status;
  809. do {
  810. get_packet(remcom_in_buffer);
  811. status = process_packet(remcom_in_buffer);
  812. } while (status == 0);
  813. if (status < 0)
  814. return 0;
  815. else
  816. return 1;
  817. }
  818. int gdb_handle_exception(int signo, void *regs)
  819. {
  820. int error;
  821. gs.signo = signo;
  822. if (!gdb_io_ready(1)) {
  823. error = 1;
  824. return error; /* No I/O connection, so resume the system */
  825. }
  826. #if RT_GDB_HAVE_SWBP
  827. gdb_deactivate_sw_breakpoints();
  828. #endif
  829. gdb_set_register(regs);
  830. /* Clear the out buffer. */
  831. memset(remcom_out_buffer, 0, sizeof(remcom_out_buffer));
  832. if (gdb_connected) {
  833. char *ptr;
  834. gdb_io_ops.write_char('\n');
  835. /* Reply to host that an exception has occurred */
  836. ptr = remcom_out_buffer;
  837. *ptr++ = 'T';
  838. *ptr++ = tohex((gs.signo >> 4) &0xf);
  839. *ptr++ = tohex(gs.signo & 0xf);
  840. /*ptr += strlen(strcpy(ptr, "thread:"));*/
  841. /**ptr++ = ';';*/
  842. put_packet(remcom_out_buffer);
  843. }
  844. gs.pass_exception = 0;
  845. while (gdb_process_exception());
  846. error = gs.pass_exception;
  847. return error;
  848. }
  849. void gdb_console_write(const char *s, unsigned count)
  850. {
  851. /* If we're debugging, or GDB has not connected, don't try
  852. * and print. */
  853. if (!gdb_connected)
  854. return;
  855. gdb_msg_write(s, count);
  856. }