You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

560 lines
17 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2011 by Broadcom Corporation *
  3. * Evan Hunter - ehunter@broadcom.com *
  4. * *
  5. * This program is free software; you can redistribute it and/or modify *
  6. * it under the terms of the GNU General Public License as published by *
  7. * the Free Software Foundation; either version 2 of the License, or *
  8. * (at your option) any later version. *
  9. * *
  10. * This program is distributed in the hope that it will be useful, *
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  13. * GNU General Public License for more details. *
  14. * *
  15. * You should have received a copy of the GNU General Public License *
  16. * along with this program; if not, write to the *
  17. * Free Software Foundation, Inc., *
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
  19. ***************************************************************************/
  20. #ifdef HAVE_CONFIG_H
  21. #include "config.h"
  22. #endif
  23. #include "rtos.h"
  24. #include "target/target.h"
  25. #include "helper/log.h"
  26. #include "helper/binarybuffer.h"
  27. #include "server/gdb_server.h"
  28. /* RTOSs */
  29. extern struct rtos_type FreeRTOS_rtos;
  30. extern struct rtos_type ThreadX_rtos;
  31. extern struct rtos_type eCos_rtos;
  32. extern struct rtos_type Linux_os;
  33. extern struct rtos_type ChibiOS_rtos;
  34. extern struct rtos_type embKernel_rtos;
  35. extern struct rtos_type mqx_rtos;
  36. static struct rtos_type *rtos_types[] = {
  37. &ThreadX_rtos,
  38. &FreeRTOS_rtos,
  39. &eCos_rtos,
  40. &Linux_os,
  41. &ChibiOS_rtos,
  42. &embKernel_rtos,
  43. &mqx_rtos,
  44. NULL
  45. };
  46. int rtos_thread_packet(struct connection *connection, const char *packet, int packet_size);
  47. int rtos_smp_init(struct target *target)
  48. {
  49. if (target->rtos->type->smp_init)
  50. return target->rtos->type->smp_init(target);
  51. return ERROR_TARGET_INIT_FAILED;
  52. }
  53. static int os_alloc(struct target *target, struct rtos_type *ostype)
  54. {
  55. struct rtos *os = target->rtos = calloc(1, sizeof(struct rtos));
  56. if (!os)
  57. return JIM_ERR;
  58. os->type = ostype;
  59. os->current_threadid = -1;
  60. os->current_thread = 0;
  61. os->symbols = NULL;
  62. os->target = target;
  63. /* RTOS drivers can override the packet handler in _create(). */
  64. os->gdb_thread_packet = rtos_thread_packet;
  65. return JIM_OK;
  66. }
  67. static void os_free(struct target *target)
  68. {
  69. if (!target->rtos)
  70. return;
  71. if (target->rtos->symbols)
  72. free(target->rtos->symbols);
  73. free(target->rtos);
  74. target->rtos = NULL;
  75. }
  76. static int os_alloc_create(struct target *target, struct rtos_type *ostype)
  77. {
  78. int ret = os_alloc(target, ostype);
  79. if (JIM_OK == ret) {
  80. ret = target->rtos->type->create(target);
  81. if (ret != JIM_OK)
  82. os_free(target);
  83. }
  84. return ret;
  85. }
  86. int rtos_create(Jim_GetOptInfo *goi, struct target *target)
  87. {
  88. int x;
  89. char *cp;
  90. struct Jim_Obj *res;
  91. if (!goi->isconfigure && goi->argc != 0) {
  92. Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "NO PARAMS");
  93. return JIM_ERR;
  94. }
  95. os_free(target);
  96. Jim_GetOpt_String(goi, &cp, NULL);
  97. if (0 == strcmp(cp, "auto")) {
  98. /* Auto detect tries to look up all symbols for each RTOS,
  99. * and runs the RTOS driver's _detect() function when GDB
  100. * finds all symbols for any RTOS. See rtos_qsymbol(). */
  101. target->rtos_auto_detect = true;
  102. /* rtos_qsymbol() will iterate over all RTOSes. Allocate
  103. * target->rtos here, and set it to the first RTOS type. */
  104. return os_alloc(target, rtos_types[0]);
  105. }
  106. for (x = 0; rtos_types[x]; x++)
  107. if (0 == strcmp(cp, rtos_types[x]->name))
  108. return os_alloc_create(target, rtos_types[x]);
  109. Jim_SetResultFormatted(goi->interp, "Unknown RTOS type %s, try one of: ", cp);
  110. res = Jim_GetResult(goi->interp);
  111. for (x = 0; rtos_types[x]; x++)
  112. Jim_AppendStrings(goi->interp, res, rtos_types[x]->name, ", ", NULL);
  113. Jim_AppendStrings(goi->interp, res, " or auto", NULL);
  114. return JIM_ERR;
  115. }
  116. int gdb_thread_packet(struct connection *connection, char const *packet, int packet_size)
  117. {
  118. struct target *target = get_target_from_connection(connection);
  119. if (target->rtos == NULL)
  120. return rtos_thread_packet(connection, packet, packet_size); /* thread not
  121. *found*/
  122. return target->rtos->gdb_thread_packet(connection, packet, packet_size);
  123. }
  124. static symbol_table_elem_t *next_symbol(struct rtos *os, char *cur_symbol, uint64_t cur_addr)
  125. {
  126. symbol_table_elem_t *s;
  127. if (!os->symbols)
  128. os->type->get_symbol_list_to_lookup(&os->symbols);
  129. if (!cur_symbol[0])
  130. return &os->symbols[0];
  131. for (s = os->symbols; s->symbol_name; s++)
  132. if (!strcmp(s->symbol_name, cur_symbol)) {
  133. s->address = cur_addr;
  134. s++;
  135. return s;
  136. }
  137. return NULL;
  138. }
  139. /* searches for 'symbol' in the lookup table for 'os' and returns TRUE,
  140. * if 'symbol' is not declared optional */
  141. static bool is_symbol_mandatory(const struct rtos *os, const char *symbol)
  142. {
  143. for (symbol_table_elem_t *s = os->symbols; s->symbol_name; ++s) {
  144. if (!strcmp(s->symbol_name, symbol))
  145. return !s->optional;
  146. }
  147. return false;
  148. }
  149. /* rtos_qsymbol() processes and replies to all qSymbol packets from GDB.
  150. *
  151. * GDB sends a qSymbol:: packet (empty address, empty name) to notify
  152. * that it can now answer qSymbol::hexcodedname queries, to look up symbols.
  153. *
  154. * If the qSymbol packet has no address that means GDB did not find the
  155. * symbol, in which case auto-detect will move on to try the next RTOS.
  156. *
  157. * rtos_qsymbol() then calls the next_symbol() helper function, which
  158. * iterates over symbol names for the current RTOS until it finds the
  159. * symbol in the received GDB packet, and then returns the next entry
  160. * in the list of symbols.
  161. *
  162. * If GDB replied about the last symbol for the RTOS and the RTOS was
  163. * specified explicitly, then no further symbol lookup is done. When
  164. * auto-detecting, the RTOS driver _detect() function must return success.
  165. *
  166. * rtos_qsymbol() returns 1 if an RTOS has been detected, or 0 otherwise.
  167. */
  168. int rtos_qsymbol(struct connection *connection, char const *packet, int packet_size)
  169. {
  170. int rtos_detected = 0;
  171. uint64_t addr = 0;
  172. size_t reply_len;
  173. char reply[GDB_BUFFER_SIZE], cur_sym[GDB_BUFFER_SIZE / 2] = "";
  174. symbol_table_elem_t *next_sym = NULL;
  175. struct target *target = get_target_from_connection(connection);
  176. struct rtos *os = target->rtos;
  177. reply_len = sprintf(reply, "OK");
  178. if (!os)
  179. goto done;
  180. /* Decode any symbol name in the packet*/
  181. int len = unhexify(cur_sym, strchr(packet + 8, ':') + 1, strlen(strchr(packet + 8, ':') + 1));
  182. cur_sym[len] = 0;
  183. if ((strcmp(packet, "qSymbol::") != 0) && /* GDB is not offering symbol lookup for the first time */
  184. (!sscanf(packet, "qSymbol:%" SCNx64 ":", &addr)) && /* GDB did not find an address for a symbol */
  185. is_symbol_mandatory(os, cur_sym)) { /* the symbol is mandatory for this RTOS */
  186. /* GDB could not find an address for the previous symbol */
  187. if (!target->rtos_auto_detect) {
  188. LOG_WARNING("RTOS %s not detected. (GDB could not find symbol \'%s\')", os->type->name, cur_sym);
  189. goto done;
  190. } else {
  191. /* Autodetecting RTOS - try next RTOS */
  192. if (!rtos_try_next(target)) {
  193. LOG_WARNING("No RTOS could be auto-detected!");
  194. goto done;
  195. }
  196. /* Next RTOS selected - invalidate current symbol */
  197. cur_sym[0] = '\x00';
  198. }
  199. }
  200. next_sym = next_symbol(os, cur_sym, addr);
  201. if (!next_sym->symbol_name) {
  202. /* No more symbols need looking up */
  203. if (!target->rtos_auto_detect) {
  204. rtos_detected = 1;
  205. goto done;
  206. }
  207. if (os->type->detect_rtos(target)) {
  208. LOG_INFO("Auto-detected RTOS: %s", os->type->name);
  209. rtos_detected = 1;
  210. goto done;
  211. } else {
  212. LOG_WARNING("No RTOS could be auto-detected!");
  213. goto done;
  214. }
  215. }
  216. if (8 + (strlen(next_sym->symbol_name) * 2) + 1 > sizeof(reply)) {
  217. LOG_ERROR("ERROR: RTOS symbol '%s' name is too long for GDB!", next_sym->symbol_name);
  218. goto done;
  219. }
  220. reply_len = snprintf(reply, sizeof(reply), "qSymbol:");
  221. reply_len += hexify(reply + reply_len, next_sym->symbol_name, 0, sizeof(reply) - reply_len);
  222. done:
  223. gdb_put_packet(connection, reply, reply_len);
  224. return rtos_detected;
  225. }
  226. int rtos_thread_packet(struct connection *connection, char const *packet, int packet_size)
  227. {
  228. struct target *target = get_target_from_connection(connection);
  229. if (strncmp(packet, "qThreadExtraInfo,", 17) == 0) {
  230. if ((target->rtos != NULL) && (target->rtos->thread_details != NULL) &&
  231. (target->rtos->thread_count != 0)) {
  232. threadid_t threadid = 0;
  233. int found = -1;
  234. sscanf(packet, "qThreadExtraInfo,%" SCNx64, &threadid);
  235. if ((target->rtos != NULL) && (target->rtos->thread_details != NULL)) {
  236. int thread_num;
  237. for (thread_num = 0; thread_num < target->rtos->thread_count; thread_num++) {
  238. if (target->rtos->thread_details[thread_num].threadid == threadid) {
  239. if (target->rtos->thread_details[thread_num].exists)
  240. found = thread_num;
  241. }
  242. }
  243. }
  244. if (found == -1) {
  245. gdb_put_packet(connection, "E01", 3); /* thread not found */
  246. return ERROR_OK;
  247. }
  248. struct thread_detail *detail = &target->rtos->thread_details[found];
  249. int str_size = 0;
  250. if (detail->display_str != NULL)
  251. str_size += strlen(detail->display_str);
  252. if (detail->thread_name_str != NULL)
  253. str_size += strlen(detail->thread_name_str);
  254. if (detail->extra_info_str != NULL)
  255. str_size += strlen(detail->extra_info_str);
  256. char *tmp_str = calloc(str_size + 7, sizeof(char));
  257. char *tmp_str_ptr = tmp_str;
  258. if (detail->display_str != NULL)
  259. tmp_str_ptr += sprintf(tmp_str_ptr, "%s", detail->display_str);
  260. if (detail->thread_name_str != NULL) {
  261. if (tmp_str_ptr != tmp_str)
  262. tmp_str_ptr += sprintf(tmp_str_ptr, " : ");
  263. tmp_str_ptr += sprintf(tmp_str_ptr, "%s", detail->thread_name_str);
  264. }
  265. if (detail->extra_info_str != NULL) {
  266. if (tmp_str_ptr != tmp_str)
  267. tmp_str_ptr += sprintf(tmp_str_ptr, " : ");
  268. tmp_str_ptr +=
  269. sprintf(tmp_str_ptr, " : %s", detail->extra_info_str);
  270. }
  271. assert(strlen(tmp_str) ==
  272. (size_t) (tmp_str_ptr - tmp_str));
  273. char *hex_str = malloc(strlen(tmp_str) * 2 + 1);
  274. int pkt_len = hexify(hex_str, tmp_str, 0, strlen(tmp_str) * 2 + 1);
  275. gdb_put_packet(connection, hex_str, pkt_len);
  276. free(hex_str);
  277. free(tmp_str);
  278. return ERROR_OK;
  279. }
  280. gdb_put_packet(connection, "", 0);
  281. return ERROR_OK;
  282. } else if (strncmp(packet, "qSymbol", 7) == 0) {
  283. if (rtos_qsymbol(connection, packet, packet_size) == 1) {
  284. target->rtos_auto_detect = false;
  285. target->rtos->type->create(target);
  286. target->rtos->type->update_threads(target->rtos);
  287. }
  288. return ERROR_OK;
  289. } else if (strncmp(packet, "qfThreadInfo", 12) == 0) {
  290. int i;
  291. if (target->rtos != NULL) {
  292. if (target->rtos->thread_count == 0) {
  293. gdb_put_packet(connection, "l", 1);
  294. } else {
  295. /*thread id are 16 char +1 for ',' */
  296. char *out_str = malloc(17 * target->rtos->thread_count + 1);
  297. char *tmp_str = out_str;
  298. for (i = 0; i < target->rtos->thread_count; i++) {
  299. tmp_str += sprintf(tmp_str, "%c%016" PRIx64, i == 0 ? 'm' : ',',
  300. target->rtos->thread_details[i].threadid);
  301. }
  302. gdb_put_packet(connection, out_str, strlen(out_str));
  303. free(out_str);
  304. }
  305. } else
  306. gdb_put_packet(connection, "l", 1);
  307. return ERROR_OK;
  308. } else if (strncmp(packet, "qsThreadInfo", 12) == 0) {
  309. gdb_put_packet(connection, "l", 1);
  310. return ERROR_OK;
  311. } else if (strncmp(packet, "qAttached", 9) == 0) {
  312. gdb_put_packet(connection, "1", 1);
  313. return ERROR_OK;
  314. } else if (strncmp(packet, "qOffsets", 8) == 0) {
  315. char offsets[] = "Text=0;Data=0;Bss=0";
  316. gdb_put_packet(connection, offsets, sizeof(offsets)-1);
  317. return ERROR_OK;
  318. } else if (strncmp(packet, "qCRC:", 5) == 0) {
  319. /* make sure we check this before "qC" packet below
  320. * otherwise it gets incorrectly handled */
  321. return GDB_THREAD_PACKET_NOT_CONSUMED;
  322. } else if (strncmp(packet, "qC", 2) == 0) {
  323. if (target->rtos != NULL) {
  324. char buffer[19];
  325. int size;
  326. size = snprintf(buffer, 19, "QC%016" PRIx64, target->rtos->current_thread);
  327. gdb_put_packet(connection, buffer, size);
  328. } else
  329. gdb_put_packet(connection, "QC0", 3);
  330. return ERROR_OK;
  331. } else if (packet[0] == 'T') { /* Is thread alive? */
  332. threadid_t threadid;
  333. int found = -1;
  334. sscanf(packet, "T%" SCNx64, &threadid);
  335. if ((target->rtos != NULL) && (target->rtos->thread_details != NULL)) {
  336. int thread_num;
  337. for (thread_num = 0; thread_num < target->rtos->thread_count; thread_num++) {
  338. if (target->rtos->thread_details[thread_num].threadid == threadid) {
  339. if (target->rtos->thread_details[thread_num].exists)
  340. found = thread_num;
  341. }
  342. }
  343. }
  344. if (found != -1)
  345. gdb_put_packet(connection, "OK", 2); /* thread alive */
  346. else
  347. gdb_put_packet(connection, "E01", 3); /* thread not found */
  348. return ERROR_OK;
  349. } else if (packet[0] == 'H') { /* Set current thread ( 'c' for step and continue, 'g' for
  350. * all other operations ) */
  351. if ((packet[1] == 'g') && (target->rtos != NULL)) {
  352. sscanf(packet, "Hg%16" SCNx64, &target->rtos->current_threadid);
  353. LOG_DEBUG("RTOS: GDB requested to set current thread to 0x%" PRIx64 "\r\n",
  354. target->rtos->current_threadid);
  355. }
  356. gdb_put_packet(connection, "OK", 2);
  357. return ERROR_OK;
  358. }
  359. return GDB_THREAD_PACKET_NOT_CONSUMED;
  360. }
  361. int rtos_get_gdb_reg_list(struct connection *connection)
  362. {
  363. struct target *target = get_target_from_connection(connection);
  364. int64_t current_threadid = target->rtos->current_threadid;
  365. if ((target->rtos != NULL) && (current_threadid != -1) &&
  366. (current_threadid != 0) &&
  367. ((current_threadid != target->rtos->current_thread) ||
  368. (target->smp))) { /* in smp several current thread are possible */
  369. char *hex_reg_list;
  370. LOG_DEBUG("RTOS: getting register list for thread 0x%" PRIx64
  371. ", target->rtos->current_thread=0x%" PRIx64 "\r\n",
  372. current_threadid,
  373. target->rtos->current_thread);
  374. target->rtos->type->get_thread_reg_list(target->rtos,
  375. current_threadid,
  376. &hex_reg_list);
  377. if (hex_reg_list != NULL) {
  378. gdb_put_packet(connection, hex_reg_list, strlen(hex_reg_list));
  379. free(hex_reg_list);
  380. return ERROR_OK;
  381. }
  382. }
  383. return ERROR_FAIL;
  384. }
  385. int rtos_generic_stack_read(struct target *target,
  386. const struct rtos_register_stacking *stacking,
  387. int64_t stack_ptr,
  388. char **hex_reg_list)
  389. {
  390. int list_size = 0;
  391. char *tmp_str_ptr;
  392. int64_t new_stack_ptr;
  393. int i;
  394. int retval;
  395. if (stack_ptr == 0) {
  396. LOG_ERROR("Error: null stack pointer in thread");
  397. return -5;
  398. }
  399. /* Read the stack */
  400. uint8_t *stack_data = malloc(stacking->stack_registers_size);
  401. uint32_t address = stack_ptr;
  402. if (stacking->stack_growth_direction == 1)
  403. address -= stacking->stack_registers_size;
  404. retval = target_read_buffer(target, address, stacking->stack_registers_size, stack_data);
  405. if (retval != ERROR_OK) {
  406. free(stack_data);
  407. LOG_ERROR("Error reading stack frame from thread");
  408. return retval;
  409. }
  410. LOG_DEBUG("RTOS: Read stack frame at 0x%x\r\n", address);
  411. #if 0
  412. LOG_OUTPUT("Stack Data :");
  413. for (i = 0; i < stacking->stack_registers_size; i++)
  414. LOG_OUTPUT("%02X", stack_data[i]);
  415. LOG_OUTPUT("\r\n");
  416. #endif
  417. for (i = 0; i < stacking->num_output_registers; i++)
  418. list_size += stacking->register_offsets[i].width_bits/8;
  419. *hex_reg_list = malloc(list_size*2 + 1);
  420. tmp_str_ptr = *hex_reg_list;
  421. new_stack_ptr = stack_ptr - stacking->stack_growth_direction *
  422. stacking->stack_registers_size;
  423. if (stacking->stack_alignment != 0) {
  424. /* Align new stack pointer to x byte boundary */
  425. new_stack_ptr =
  426. (new_stack_ptr & (~((int64_t) stacking->stack_alignment - 1))) +
  427. ((stacking->stack_growth_direction == -1) ? stacking->stack_alignment : 0);
  428. }
  429. for (i = 0; i < stacking->num_output_registers; i++) {
  430. int j;
  431. for (j = 0; j < stacking->register_offsets[i].width_bits/8; j++) {
  432. if (stacking->register_offsets[i].offset == -1)
  433. tmp_str_ptr += sprintf(tmp_str_ptr, "%02x", 0);
  434. else if (stacking->register_offsets[i].offset == -2)
  435. tmp_str_ptr += sprintf(tmp_str_ptr, "%02x",
  436. ((uint8_t *)&new_stack_ptr)[j]);
  437. else
  438. tmp_str_ptr += sprintf(tmp_str_ptr, "%02x",
  439. stack_data[stacking->register_offsets[i].offset + j]);
  440. }
  441. }
  442. free(stack_data);
  443. /* LOG_OUTPUT("Output register string: %s\r\n", *hex_reg_list); */
  444. return ERROR_OK;
  445. }
  446. int rtos_try_next(struct target *target)
  447. {
  448. struct rtos *os = target->rtos;
  449. struct rtos_type **type = rtos_types;
  450. if (!os)
  451. return 0;
  452. while (*type && os->type != *type)
  453. type++;
  454. if (!*type || !*(++type))
  455. return 0;
  456. os->type = *type;
  457. if (os->symbols) {
  458. free(os->symbols);
  459. os->symbols = NULL;
  460. }
  461. return 1;
  462. }
  463. int rtos_update_threads(struct target *target)
  464. {
  465. if ((target->rtos != NULL) && (target->rtos->type != NULL))
  466. target->rtos->type->update_threads(target->rtos);
  467. return ERROR_OK;
  468. }
  469. void rtos_free_threadlist(struct rtos *rtos)
  470. {
  471. if (rtos->thread_details) {
  472. int j;
  473. for (j = 0; j < rtos->thread_count; j++) {
  474. struct thread_detail *current_thread = &rtos->thread_details[j];
  475. free(current_thread->display_str);
  476. free(current_thread->thread_name_str);
  477. free(current_thread->extra_info_str);
  478. }
  479. free(rtos->thread_details);
  480. rtos->thread_details = NULL;
  481. rtos->thread_count = 0;
  482. }
  483. }