rtos: fix uninitialised variable warning
[fw/openocd] / src / rtos / rtos.c
index ed559c391b2f86b65e82913b72713dae8fd1bff2..cdd37608ed446156ca409fd61405b8427b170ab3 100644 (file)
@@ -15,7 +15,7 @@
  *   You should have received a copy of the GNU General Public License     *
  *   along with this program; if not, write to the                         *
  *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *
  ***************************************************************************/
 
 #ifdef HAVE_CONFIG_H
 #include "rtos.h"
 #include "target/target.h"
 #include "helper/log.h"
+#include "helper/binarybuffer.h"
 #include "server/gdb_server.h"
 
-static void hex_to_str(char *dst, char *hex_src);
-
 /* RTOSs */
 extern struct rtos_type FreeRTOS_rtos;
 extern struct rtos_type ThreadX_rtos;
 extern struct rtos_type eCos_rtos;
 extern struct rtos_type Linux_os;
+extern struct rtos_type ChibiOS_rtos;
+extern struct rtos_type embKernel_rtos;
 
 static struct rtos_type *rtos_types[] = {
        &ThreadX_rtos,
        &FreeRTOS_rtos,
        &eCos_rtos,
        &Linux_os,
+       &ChibiOS_rtos,
+       &embKernel_rtos,
        NULL
 };
 
@@ -186,7 +189,7 @@ static char *next_symbol(struct rtos *os, char *cur_symbol, uint64_t cur_addr)
 int rtos_qsymbol(struct connection *connection, char *packet, int packet_size)
 {
        int rtos_detected = 0;
-       uint64_t addr;
+       uint64_t addr = 0;
        size_t reply_len;
        char reply[GDB_BUFFER_SIZE], cur_sym[GDB_BUFFER_SIZE / 2] = "", *next_sym;
        struct target *target = get_target_from_connection(connection);
@@ -197,41 +200,54 @@ int rtos_qsymbol(struct connection *connection, char *packet, int packet_size)
        if (!os)
                goto done;
 
-       if (sscanf(packet, "qSymbol:%" SCNx64 ":", &addr))
-               hex_to_str(cur_sym, strchr(packet + 8, ':') + 1);
-       else if (target->rtos_auto_detect && !rtos_try_next(target))
-               goto done;
+       /* Decode any symbol name in the packet*/
+       int len = unhexify(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 found an address for a symbol */
+               /* 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';
+               }
+       }
        next_sym = next_symbol(os, cur_sym, addr);
+
        if (!next_sym) {
+               /* No more symbols need looking up */
+
                if (!target->rtos_auto_detect) {
                        rtos_detected = 1;
                        goto done;
                }
 
                if (os->type->detect_rtos(target)) {
-                       LOG_OUTPUT("Auto-detected RTOS: %s\r\n", os->type->name);
+                       LOG_INFO("Auto-detected RTOS: %s", os->type->name);
                        rtos_detected = 1;
                        goto done;
-               }
-
-               if (!rtos_try_next(target))
-                       goto done;
-
-               os->type->get_symbol_list_to_lookup(&os->symbols);
-
-               next_sym = os->symbols[0].symbol_name;
-               if (!next_sym)
+               } else {
+                       LOG_WARNING("No RTOS could be auto-detected!");
                        goto done;
+               }
        }
 
        if (8 + (strlen(next_sym) * 2) + 1 > sizeof(reply)) {
-               LOG_OUTPUT("ERROR: RTOS symbol '%s' name is too long for GDB!", next_sym);
+               LOG_ERROR("ERROR: RTOS symbol '%s' name is too long for GDB!", next_sym);
                goto done;
        }
 
-       reply_len = sprintf(reply, "qSymbol:");
-       reply_len += str_to_hex(reply + reply_len, next_sym);
+       reply_len = snprintf(reply, sizeof(reply), "qSymbol:");
+       reply_len += hexify(reply + reply_len, next_sym, 0, sizeof(reply) - reply_len);
 
 done:
        gdb_put_packet(connection, reply, reply_len);
@@ -242,7 +258,7 @@ int rtos_thread_packet(struct connection *connection, char *packet, int packet_s
 {
        struct target *target = get_target_from_connection(connection);
 
-       if (strstr(packet, "qThreadExtraInfo,")) {
+       if (strncmp(packet, "qThreadExtraInfo,", 17) == 0) {
                if ((target->rtos != NULL) && (target->rtos->thread_details != NULL) &&
                                (target->rtos->thread_count != 0)) {
                        threadid_t threadid = 0;
@@ -293,10 +309,10 @@ int rtos_thread_packet(struct connection *connection, char *packet, int packet_s
                        assert(strlen(tmp_str) ==
                                (size_t) (tmp_str_ptr - tmp_str));
 
-                       char *hex_str = (char *) malloc(strlen(tmp_str)*2 + 1);
-                       str_to_hex(hex_str, tmp_str);
+                       char *hex_str = (char *) malloc(strlen(tmp_str) * 2 + 1);
+                       int pkt_len = hexify(hex_str, tmp_str, 0, strlen(tmp_str) * 2 + 1);
 
-                       gdb_put_packet(connection, hex_str, strlen(hex_str));
+                       gdb_put_packet(connection, hex_str, pkt_len);
                        free(hex_str);
                        free(tmp_str);
                        return ERROR_OK;
@@ -304,47 +320,52 @@ int rtos_thread_packet(struct connection *connection, char *packet, int packet_s
                }
                gdb_put_packet(connection, "", 0);
                return ERROR_OK;
-       } else if (strstr(packet, "qSymbol")) {
+       } else if (strncmp(packet, "qSymbol", 7) == 0) {
                if (rtos_qsymbol(connection, packet, packet_size) == 1) {
                        target->rtos_auto_detect = false;
                        target->rtos->type->create(target);
                        target->rtos->type->update_threads(target->rtos);
                }
                return ERROR_OK;
-       } else if (strstr(packet, "qfThreadInfo")) {
+       } else if (strncmp(packet, "qfThreadInfo", 12) == 0) {
                int i;
-               if ((target->rtos != NULL) && (target->rtos->thread_count != 0)) {
-
-                       char *out_str = (char *) malloc(17 * target->rtos->thread_count + 5);
-                       char *tmp_str = out_str;
-                       tmp_str += sprintf(tmp_str, "m");
-                       for (i = 0; i < target->rtos->thread_count; i++) {
-                               if (i != 0)
-                                       tmp_str += sprintf(tmp_str, ",");
-                               tmp_str += sprintf(tmp_str, "%016" PRIx64,
-                                               target->rtos->thread_details[i].threadid);
+               if (target->rtos != NULL) {
+                       if (target->rtos->thread_count == 0) {
+                               gdb_put_packet(connection, "l", 1);
+                       } else {
+                               /*thread id are 16 char +1 for ',' */
+                               char *out_str = (char *) malloc(17 * target->rtos->thread_count + 1);
+                               char *tmp_str = out_str;
+                               for (i = 0; i < target->rtos->thread_count; i++) {
+                                       tmp_str += sprintf(tmp_str, "%c%016" PRIx64, i == 0 ? 'm' : ',',
+                                                                               target->rtos->thread_details[i].threadid);
+                               }
+                               gdb_put_packet(connection, out_str, strlen(out_str));
+                               free(out_str);
                        }
-                       tmp_str[0] = 0;
-                       gdb_put_packet(connection, out_str, strlen(out_str));
                } else
                        gdb_put_packet(connection, "", 0);
 
                return ERROR_OK;
-       } else if (strstr(packet, "qsThreadInfo")) {
+       } else if (strncmp(packet, "qsThreadInfo", 12) == 0) {
                gdb_put_packet(connection, "l", 1);
                return ERROR_OK;
-       } else if (strstr(packet, "qAttached")) {
+       } else if (strncmp(packet, "qAttached", 9) == 0) {
                gdb_put_packet(connection, "1", 1);
                return ERROR_OK;
-       } else if (strstr(packet, "qOffsets")) {
+       } else if (strncmp(packet, "qOffsets", 8) == 0) {
                char offsets[] = "Text=0;Data=0;Bss=0";
                gdb_put_packet(connection, offsets, sizeof(offsets)-1);
                return ERROR_OK;
-       } else if (strstr(packet, "qC")) {
+       } else if (strncmp(packet, "qCRC:", 5) == 0) {
+               /* make sure we check this before "qC" packet below
+                * otherwise it gets incorrectly handled */
+               return GDB_THREAD_PACKET_NOT_CONSUMED;
+       } else if (strncmp(packet, "qC", 2) == 0) {
                if (target->rtos != NULL) {
-                       char buffer[15];
+                       char buffer[19];
                        int size;
-                       size = snprintf(buffer, 15, "QC%08X", (int)target->rtos->current_thread);
+                       size = snprintf(buffer, 19, "QC%016" PRIx64, target->rtos->current_thread);
                        gdb_put_packet(connection, buffer, size);
                } else
                        gdb_put_packet(connection, "QC0", 3);
@@ -412,7 +433,7 @@ int rtos_generic_stack_read(struct target *target,
        int retval;
 
        if (stack_ptr == 0) {
-               LOG_OUTPUT("Error: null stack pointer in thread\r\n");
+               LOG_ERROR("Error: null stack pointer in thread");
                return -5;
        }
        /* Read the stack */
@@ -423,7 +444,8 @@ int rtos_generic_stack_read(struct target *target,
                address -= stacking->stack_registers_size;
        retval = target_read_buffer(target, address, stacking->stack_registers_size, stack_data);
        if (retval != ERROR_OK) {
-               LOG_OUTPUT("Error reading stack frame from FreeRTOS thread\r\n");
+               free(stack_data);
+               LOG_ERROR("Error reading stack frame from thread");
                return retval;
        }
 #if 0
@@ -457,6 +479,7 @@ int rtos_generic_stack_read(struct target *target,
                                                stack_data[stacking->register_offsets[i].offset + j]);
                }
        }
+       free(stack_data);
 /*     LOG_OUTPUT("Output register string: %s\r\n", *hex_reg_list); */
        return ERROR_OK;
 }
@@ -484,39 +507,6 @@ int rtos_try_next(struct target *target)
        return 1;
 }
 
-static void hex_to_str(char *dst, char *hex_src)
-{
-       int src_pos = 0;
-       int dst_pos = 0;
-
-       while (hex_src[src_pos] != '\x00') {
-               char hex_char = hex_src[src_pos];
-               char hex_digit_val =
-                       (hex_char >=
-                        'a') ? hex_char-'a'+
-                       10 : (hex_char >= 'A') ? hex_char-'A'+10 : hex_char-'0';
-               if (0 == (src_pos & 0x01)) {
-                       dst[dst_pos] = hex_digit_val;
-                       dst[dst_pos+1] = 0;
-               } else {
-                       ((unsigned char *)dst)[dst_pos] <<= 4;
-                       ((unsigned char *)dst)[dst_pos] += hex_digit_val;
-                       dst_pos++;
-               }
-               src_pos++;
-       }
-
-}
-
-int str_to_hex(char *hex_dst, char *src)
-{
-       char *posptr = hex_dst;
-       unsigned i;
-       for (i = 0; i < strlen(src); i++)
-               posptr += sprintf(posptr, "%02x", (unsigned char)src[i]);
-       return posptr - hex_dst;
-}
-
 int rtos_update_threads(struct target *target)
 {
        if ((target->rtos != NULL) && (target->rtos->type != NULL))