gdb: Potential rounding error in reg_packet_size gdb_get_registers_packet
[fw/openocd] / src / server / gdb_server.c
index b29ee4f84f3fd090251a62defe4582cc0485d05d..4dd9bd10aec81edf3b90ccdefd0b102df76fc6f1 100644 (file)
@@ -944,8 +944,9 @@ static void gdb_send_error(struct connection *connection, uint8_t the_error)
 }
 
 static int gdb_last_signal_packet(struct connection *connection,
-               struct target *target, char* packet, int packet_size)
+               char* packet, int packet_size)
 {
+       struct target *target = get_target_from_connection(connection);
        char sig_reply[4];
        int signal_var;
 
@@ -1029,8 +1030,9 @@ static void gdb_target_to_reg(struct target *target,
 }
 
 static int gdb_get_registers_packet(struct connection *connection,
-               struct target *target, char* packet, int packet_size)
+               char* packet, int packet_size)
 {
+       struct target *target = get_target_from_connection(connection);
        struct reg **reg_list;
        int reg_list_size;
        int retval;
@@ -1044,7 +1046,7 @@ static int gdb_get_registers_packet(struct connection *connection,
 #endif
 
        if ( ( target->rtos != NULL ) &&
-                ( ERROR_FAIL != rtos_get_gdb_reg_list( connection, target, &reg_list, &reg_list_size) ) )
+                ( ERROR_FAIL != rtos_get_gdb_reg_list( connection, &reg_list, &reg_list_size) ) )
        {
                return ERROR_OK;
        }
@@ -1056,10 +1058,12 @@ static int gdb_get_registers_packet(struct connection *connection,
 
        for (i = 0; i < reg_list_size; i++)
        {
-               reg_packet_size += reg_list[i]->size;
+               reg_packet_size += DIV_ROUND_UP(reg_list[i]->size, 8) * 2;
        }
 
-       reg_packet = malloc(DIV_ROUND_UP(reg_packet_size, 8) * 2);
+       assert(reg_packet_size > 0);
+
+       reg_packet = malloc(reg_packet_size);
        reg_packet_p = reg_packet;
 
        for (i = 0; i < reg_list_size; i++)
@@ -1073,13 +1077,13 @@ static int gdb_get_registers_packet(struct connection *connection,
 #ifdef _DEBUG_GDB_IO_
        {
                char *reg_packet_p;
-               reg_packet_p = strndup(reg_packet, DIV_ROUND_UP(reg_packet_size, 8) * 2);
+               reg_packet_p = strndup(reg_packet, reg_packet_size);
                LOG_DEBUG("reg_packet: %s", reg_packet_p);
                free(reg_packet_p);
        }
 #endif
 
-       gdb_put_packet(connection, reg_packet, DIV_ROUND_UP(reg_packet_size, 8) * 2);
+       gdb_put_packet(connection, reg_packet, reg_packet_size);
        free(reg_packet);
 
        free(reg_list);
@@ -1088,8 +1092,9 @@ static int gdb_get_registers_packet(struct connection *connection,
 }
 
 static int gdb_set_registers_packet(struct connection *connection,
-               struct target *target, char *packet, int packet_size)
+               char *packet, int packet_size)
 {
+       struct target *target = get_target_from_connection(connection);
        int i;
        struct reg **reg_list;
        int reg_list_size;
@@ -1147,8 +1152,9 @@ static int gdb_set_registers_packet(struct connection *connection,
 }
 
 static int gdb_get_register_packet(struct connection *connection,
-               struct target *target, char *packet, int packet_size)
+               char *packet, int packet_size)
 {
+       struct target *target = get_target_from_connection(connection);
        char *reg_packet;
        int reg_num = strtoul(packet + 1, NULL, 16);
        struct reg **reg_list;
@@ -1186,8 +1192,9 @@ static int gdb_get_register_packet(struct connection *connection,
 }
 
 static int gdb_set_register_packet(struct connection *connection,
-               struct target *target, char *packet, int packet_size)
+               char *packet, int packet_size)
 {
+       struct target *target = get_target_from_connection(connection);
        char *separator;
        uint8_t *bin_buf;
        int reg_num = strtoul(packet + 1, &separator, 16);
@@ -1249,8 +1256,9 @@ static int gdb_error(struct connection *connection, int retval)
  * 8191 bytes by the looks of it. Why 8191 bytes instead of 8192?????
  */
 static int gdb_read_memory_packet(struct connection *connection,
-               struct target *target, char *packet, int packet_size)
+               char *packet, int packet_size)
 {
+       struct target *target = get_target_from_connection(connection);
        char *separator;
        uint32_t addr = 0;
        uint32_t len = 0;
@@ -1324,8 +1332,9 @@ static int gdb_read_memory_packet(struct connection *connection,
 }
 
 static int gdb_write_memory_packet(struct connection *connection,
-               struct target *target, char *packet, int packet_size)
+               char *packet, int packet_size)
 {
+       struct target *target = get_target_from_connection(connection);
        char *separator;
        uint32_t addr = 0;
        uint32_t len = 0;
@@ -1382,8 +1391,9 @@ static int gdb_write_memory_packet(struct connection *connection,
 }
 
 static int gdb_write_memory_binary_packet(struct connection *connection,
-               struct target *target, char *packet, int packet_size)
+               char *packet, int packet_size)
 {
+       struct target *target = get_target_from_connection(connection);
        char *separator;
        uint32_t addr = 0;
        uint32_t len = 0;
@@ -1446,8 +1456,9 @@ static int gdb_write_memory_binary_packet(struct connection *connection,
 }
 
 static int gdb_step_continue_packet(struct connection *connection,
-               struct target *target, char *packet, int packet_size)
+               char *packet, int packet_size)
 {
+       struct target *target = get_target_from_connection(connection);
        int current = 0;
        uint32_t address = 0x0;
        int retval = ERROR_OK;
@@ -1480,8 +1491,9 @@ static int gdb_step_continue_packet(struct connection *connection,
 }
 
 static int gdb_breakpoint_watchpoint_packet(struct connection *connection,
-               struct target *target, char *packet, int packet_size)
+               char *packet, int packet_size)
 {
+       struct target *target = get_target_from_connection(connection);
        int type;
        enum breakpoint_type bp_type = BKPT_SOFT /* dummy init to avoid warning */;
        enum watchpoint_rw wp_type = WPT_READ /* dummy init to avoid warning */;
@@ -1674,7 +1686,7 @@ static int compare_bank (const void * a, const void * b)
 }
 
 static int gdb_memory_map(struct connection *connection,
-               struct target *target, char *packet, int packet_size)
+               char *packet, int packet_size)
 {
        /* We get away with only specifying flash here. Regions that are not
         * specified are treated as if we provided no memory map(if not we
@@ -1683,6 +1695,7 @@ static int gdb_memory_map(struct connection *connection,
         * have to regenerate it a couple of times.
         */
 
+       struct target *target = get_target_from_connection(connection);
        struct flash_bank *p;
        char *xml = NULL;
        int size = 0;
@@ -1728,14 +1741,13 @@ static int gdb_memory_map(struct connection *connection,
        qsort(banks, target_flash_banks, sizeof(struct flash_bank *),
                        compare_bank);
 
-       for (i = 0; i < flash_get_bank_count(); i++) {
+       for (i = 0; i < target_flash_banks; i++) {
                int j;
                unsigned sector_size = 0;
-               uint32_t start, end;
+               uint32_t start;
 
                p = banks[i];
                start = p->base;
-               end = p->base + p->size;
 
                if (ram_start < p->base)
                        xml_printf(&retval, &xml, &pos, &size,
@@ -1819,10 +1831,11 @@ static int gdb_memory_map(struct connection *connection,
 }
 
 static int gdb_query_packet(struct connection *connection,
-       struct target *target, char *packet, int packet_size)
+               char *packet, int packet_size)
 {
        struct command_context *cmd_ctx = connection->cmd_ctx;
        struct gdb_connection *gdb_connection = connection->priv;
+       struct target *target = get_target_from_connection(connection);
 
        if (strstr(packet, "qRcmd,"))
        {
@@ -1920,7 +1933,7 @@ static int gdb_query_packet(struct connection *connection,
        }
        else if (strstr(packet, "qXfer:memory-map:read::")
                        && (flash_get_bank_count() > 0))
-               return gdb_memory_map(connection, target, packet, packet_size);
+               return gdb_memory_map(connection, packet, packet_size);
        else if (strstr(packet, "qXfer:features:read:"))
        {
                char *xml = NULL;
@@ -1973,7 +1986,7 @@ static int gdb_query_packet(struct connection *connection,
 }
 
 static int gdb_v_packet(struct connection *connection,
-               struct target *target, char *packet, int packet_size)
+               char *packet, int packet_size)
 {
        struct gdb_connection *gdb_connection = connection->priv;
        struct gdb_service *gdb_service = connection->service->priv;
@@ -2120,7 +2133,7 @@ static int gdb_v_packet(struct connection *connection,
        return ERROR_OK;
 }
 
-static int gdb_detach(struct connection *connection, struct target *target)
+static int gdb_detach(struct connection *connection)
 {
        struct gdb_service *gdb_service = connection->service->priv;
 
@@ -2208,61 +2221,43 @@ static int gdb_input_inner(struct connection *connection)
                        switch (packet[0])
                        {
                            case 'T': // Is thread alive?
-                               gdb_thread_packet(connection, target, packet, packet_size);
+                               gdb_thread_packet(connection, packet, packet_size);
                                break;
                            case 'H': // Set current thread ( 'c' for step and continue, 'g' for all other operations )
-                               gdb_thread_packet(connection, target, packet, packet_size);
+                               gdb_thread_packet(connection, packet, packet_size);
                                break;
                                case 'q':
                                case 'Q':
-                                       retval = gdb_thread_packet(connection,
-                                                                                               target, packet,
-                                                                                               packet_size);
+                                       retval = gdb_thread_packet(connection, packet, packet_size);
                                        if ( retval == GDB_THREAD_PACKET_NOT_CONSUMED )
                                        {
-                                               retval = gdb_query_packet(connection,
-                                                               target, packet,
-                                                               packet_size);
+                                               retval = gdb_query_packet(connection, packet, packet_size);
                                        }
                                        break;
                                case 'g':
-                                       retval = gdb_get_registers_packet(
-                                                       connection, target,
-                                                       packet, packet_size);
+                                       retval = gdb_get_registers_packet(connection, packet, packet_size);
                                        break;
                                case 'G':
-                                       retval = gdb_set_registers_packet(
-                                                       connection, target,
-                                                       packet, packet_size);
+                                       retval = gdb_set_registers_packet(connection, packet, packet_size);
                                        break;
                                case 'p':
-                                       retval = gdb_get_register_packet(
-                                                       connection, target,
-                                                       packet, packet_size);
+                                       retval = gdb_get_register_packet(connection, packet, packet_size);
                                        break;
                                case 'P':
-                                       retval = gdb_set_register_packet(
-                                                       connection, target,
-                                                       packet, packet_size);
+                                       retval = gdb_set_register_packet(connection, packet, packet_size);
                                        break;
                                case 'm':
-                                       retval = gdb_read_memory_packet(
-                                                       connection, target,
-                                                       packet, packet_size);
+                                       retval = gdb_read_memory_packet(connection, packet, packet_size);
                                        break;
                                case 'M':
-                                       retval = gdb_write_memory_packet(
-                                                       connection, target,
-                                                       packet, packet_size);
+                                       retval = gdb_write_memory_packet(connection, packet, packet_size);
                                        break;
                                case 'z':
                                case 'Z':
-                                       retval = gdb_breakpoint_watchpoint_packet(connection, target, packet, packet_size);
+                                       retval = gdb_breakpoint_watchpoint_packet(connection, packet, packet_size);
                                        break;
                                case '?':
-                                       gdb_last_signal_packet(
-                                                       connection, target,
-                                                       packet, packet_size);
+                                       gdb_last_signal_packet(connection, packet, packet_size);
                                        break;
                                case 'c':
                                case 's':
@@ -2325,7 +2320,7 @@ static int gdb_input_inner(struct connection *connection)
                                                        {
                                                                /* Here we don't want packet processing to stop even if this fails,
                                                                 * so we use a local variable instead of retval. */
-                                                               retval = gdb_step_continue_packet(connection, target, packet, packet_size);
+                                                               retval = gdb_step_continue_packet(connection, packet, packet_size);
                                                                if (retval != ERROR_OK)
                                                                {
                                                                        /* we'll never receive a halted condition... issue a false one.. */
@@ -2336,18 +2331,14 @@ static int gdb_input_inner(struct connection *connection)
                                        }
                                        break;
                                case 'v':
-                                       retval = gdb_v_packet(
-                                                       connection, target,
-                                                       packet, packet_size);
+                                       retval = gdb_v_packet(connection, packet, packet_size);
                                        break;
                                case 'D':
-                                       retval = gdb_detach(connection, target);
+                                       retval = gdb_detach(connection);
                                        extended_protocol = 0;
                                        break;
                                case 'X':
-                                       retval = gdb_write_memory_binary_packet(
-                                                       connection, target,
-                                                       packet, packet_size);
+                                       retval = gdb_write_memory_binary_packet(connection, packet, packet_size);
                                        if (retval != ERROR_OK)
                                                return retval;
                                        break;
@@ -2374,18 +2365,14 @@ static int gdb_input_inner(struct connection *connection)
                                case 'j':
                                    /*  packet supported only by smp target i.e cortex_a.c*/
                                        /* handle smp packet replying coreid played to gbd */
-                                       gdb_read_smp_packet(
-                                                       connection, target,
-                                                       packet, packet_size);
+                                       gdb_read_smp_packet(connection, packet, packet_size);
                                        break;
 
                                case 'J':
                                        /*  packet supported only by smp target i.e cortex_a.c */
                                        /*  handle smp packet setting coreid to be played at next
                                         *  resume to gdb */
-                                       gdb_write_smp_packet(
-                                                       connection, target,
-                                                       packet, packet_size);
+                                       gdb_write_smp_packet(connection, packet, packet_size);
                                        break;
 
                                default:
@@ -2464,7 +2451,7 @@ static int gdb_target_start(struct target *target, const char *port)
                {
                        curr = head->target;
                        if (curr != target) curr->gdb_service = gdb_service;
-                       head = head->next;      
+                       head = head->next;
                }
        }
        return ret;
@@ -2475,7 +2462,7 @@ static int gdb_target_add_one(struct target *target)
        /*  one gdb instance per smp list */
        if ((target->smp) && (target->gdb_service)) return ERROR_OK;
        int retval = gdb_target_start(target, gdb_port_next);
-       if (retval == ERROR_OK) 
+       if (retval == ERROR_OK)
        {
                long portnumber;
                /* If we can parse the port number