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.
 
 
 
 
 
 

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