- if (mode & TAG_EXISTS) {
- sprintf(thread_str, "%08" PRIx32 "08%08" PRIx32, TAG_EXISTS, (detail->exists==true)?1:0);
- }
- if (mode & TAG_DISPLAY) {
- sprintf(thread_str, "%08" PRIx32 "%02x%s", TAG_DISPLAY, (unsigned char)strlen(detail->display_str), detail->display_str );
- }
- if (mode & TAG_MOREDISPLAY) {
- sprintf(thread_str, "%08" PRIx32 "%02x%s", TAG_MOREDISPLAY, (unsigned char)strlen(detail->extra_info_str), detail->extra_info_str );
+
+ return NULL;
+}
+
+/* searches for 'symbol' in the lookup table for 'os' and returns TRUE,
+ * if 'symbol' is not declared optional */
+static bool is_symbol_mandatory(const struct rtos *os, const char *symbol)
+{
+ for (struct symbol_table_elem *s = os->symbols; s->symbol_name; ++s) {
+ if (!strcmp(s->symbol_name, symbol))
+ return !s->optional;
+ }
+ return false;
+}
+
+/* rtos_qsymbol() processes and replies to all qSymbol packets from GDB.
+ *
+ * GDB sends a qSymbol:: packet (empty address, empty name) to notify
+ * that it can now answer qSymbol::hexcodedname queries, to look up symbols.
+ *
+ * If the qSymbol packet has no address that means GDB did not find the
+ * symbol, in which case auto-detect will move on to try the next RTOS.
+ *
+ * rtos_qsymbol() then calls the next_symbol() helper function, which
+ * iterates over symbol names for the current RTOS until it finds the
+ * symbol in the received GDB packet, and then returns the next entry
+ * in the list of symbols.
+ *
+ * If GDB replied about the last symbol for the RTOS and the RTOS was
+ * specified explicitly, then no further symbol lookup is done. When
+ * auto-detecting, the RTOS driver _detect() function must return success.
+ *
+ * rtos_qsymbol() returns 1 if an RTOS has been detected, or 0 otherwise.
+ */
+int rtos_qsymbol(struct connection *connection, char const *packet, int packet_size)
+{
+ int rtos_detected = 0;
+ uint64_t addr = 0;
+ size_t reply_len;
+ char reply[GDB_BUFFER_SIZE + 1], cur_sym[GDB_BUFFER_SIZE / 2 + 1] = ""; /* Extra byte for null-termination */
+ struct symbol_table_elem *next_sym = NULL;
+ struct target *target = get_target_from_connection(connection);
+ struct rtos *os = target->rtos;
+
+ reply_len = sprintf(reply, "OK");
+
+ if (!os)
+ goto done;
+
+ /* Decode any symbol name in the packet*/
+ size_t len = unhexify((uint8_t *)cur_sym, strchr(packet + 8, ':') + 1, strlen(strchr(packet + 8, ':') + 1));
+ cur_sym[len] = 0;
+
+ if ((strcmp(packet, "qSymbol::") != 0) && /* GDB is not offering symbol lookup for the first time */
+ (!sscanf(packet, "qSymbol:%" SCNx64 ":", &addr)) && /* GDB did not find an address for a symbol */
+ is_symbol_mandatory(os, cur_sym)) { /* the symbol is mandatory for this RTOS */
+
+ /* GDB could not find an address for the previous symbol */
+ if (!target->rtos_auto_detect) {
+ LOG_WARNING("RTOS %s not detected. (GDB could not find symbol \'%s\')", os->type->name, cur_sym);
+ goto done;
+ } else {
+ /* Autodetecting RTOS - try next RTOS */
+ if (!rtos_try_next(target)) {
+ LOG_WARNING("No RTOS could be auto-detected!");
+ goto done;
+ }
+
+ /* Next RTOS selected - invalidate current symbol */
+ cur_sym[0] = '\x00';