target: Correct profiling calculation
[fw/openocd] / src / target / target.c
index b8e4c2ff9ed937dc0720b2f98634a3c6923aa074..1ea1a61668c9d059299e6225778138ba92b2f8c8 100644 (file)
@@ -36,7 +36,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 "image.h"
 #include "rtos/rtos.h"
 
+/* default halt wait timeout (ms) */
+#define DEFAULT_HALT_TIMEOUT 5000
+
 static int target_read_buffer_default(struct target *target, uint32_t address,
-               uint32_t size, uint8_t *buffer);
+               uint32_t count, uint8_t *buffer);
 static int target_write_buffer_default(struct target *target, uint32_t address,
-               uint32_t size, const uint8_t *buffer);
+               uint32_t count, const uint8_t *buffer);
 static int target_array2mem(Jim_Interp *interp, struct target *target,
                int argc, Jim_Obj * const *argv);
 static int target_mem2array(Jim_Interp *interp, struct target *target,
                int argc, Jim_Obj * const *argv);
 static int target_register_user_commands(struct command_context *cmd_ctx);
+static int target_get_gdb_fileio_info_default(struct target *target,
+               struct gdb_fileio_info *fileio_info);
+static int target_gdb_fileio_end_default(struct target *target, int retcode,
+               int fileio_errno, bool ctrl_c);
 
 /* targets */
 extern struct target_type arm7tdmi_target;
@@ -80,6 +87,7 @@ extern struct target_type dragonite_target;
 extern struct target_type xscale_target;
 extern struct target_type cortexm3_target;
 extern struct target_type cortexa8_target;
+extern struct target_type cortexr4_target;
 extern struct target_type arm11_target;
 extern struct target_type mips_m4k_target;
 extern struct target_type avr_target;
@@ -87,7 +95,10 @@ extern struct target_type dsp563xx_target;
 extern struct target_type dsp5680xx_target;
 extern struct target_type testee_target;
 extern struct target_type avr32_ap7k_target;
-extern struct target_type stm32_stlink_target;
+extern struct target_type hla_target;
+extern struct target_type nds32_v2_target;
+extern struct target_type nds32_v3_target;
+extern struct target_type nds32_v3m_target;
 
 static struct target_type *target_types[] = {
        &arm7tdmi_target,
@@ -103,6 +114,7 @@ static struct target_type *target_types[] = {
        &xscale_target,
        &cortexm3_target,
        &cortexa8_target,
+       &cortexr4_target,
        &arm11_target,
        &mips_m4k_target,
        &avr_target,
@@ -110,7 +122,10 @@ static struct target_type *target_types[] = {
        &dsp5680xx_target,
        &testee_target,
        &avr32_ap7k_target,
-       &stm32_stlink_target,
+       &hla_target,
+       &nds32_v2_target,
+       &nds32_v3_target,
+       &nds32_v3m_target,
        NULL,
 };
 
@@ -213,6 +228,7 @@ static const Jim_Nvp nvp_target_debug_reason[] = {
        { .name = "watchpoint-and-breakpoint", .value = DBG_REASON_WPTANDBKPT },
        { .name = "single-step"              , .value = DBG_REASON_SINGLESTEP },
        { .name = "target-not-halted"        , .value = DBG_REASON_NOTHALTED  },
+       { .name = "program-exit"             , .value = DBG_REASON_EXIT },
        { .name = "undefined"                , .value = DBG_REASON_UNDEFINED },
        { .name = NULL, .value = -1 },
 };
@@ -379,9 +395,9 @@ struct target *get_target(const char *id)
 
        /* try as tcltarget name */
        for (target = all_targets; target; target = target->next) {
-               if (target->cmd_name == NULL)
+               if (target_name(target) == NULL)
                        continue;
-               if (strcmp(id, target->cmd_name) == 0)
+               if (strcmp(id, target_name(target)) == 0)
                        return target;
        }
 
@@ -395,7 +411,7 @@ struct target *get_target(const char *id)
        for (target = all_targets; target; target = target->next) {
                if (target->target_number == (int)num) {
                        LOG_WARNING("use '%s' as target identifier, not '%u'",
-                                       target->cmd_name, num);
+                                       target_name(target), num);
                        return target;
                }
        }
@@ -448,7 +464,7 @@ int target_poll(struct target *target)
                        target->halt_issued = false;
                else {
                        long long t = timeval_ms() - target->halt_issued_time;
-                       if (t > 1000) {
+                       if (t > DEFAULT_HALT_TIMEOUT) {
                                target->halt_issued = false;
                                LOG_INFO("Halt timed out, wake up GDB.");
                                target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT);
@@ -567,8 +583,10 @@ static int target_process_reset(struct command_context *cmd_ctx, enum target_res
        retval = target_call_timer_callbacks_now();
 
        struct target *target;
-       for (target = all_targets; target; target = target->next)
+       for (target = all_targets; target; target = target->next) {
                target->type->check_reset(target);
+               target->running_alg = false;
+       }
 
        return retval;
 }
@@ -657,38 +675,18 @@ const char *target_type_name(struct target *target)
        return target->type->name;
 }
 
-static int target_write_memory_imp(struct target *target, uint32_t address,
-               uint32_t size, uint32_t count, const uint8_t *buffer)
-{
-       if (!target_was_examined(target)) {
-               LOG_ERROR("Target not examined yet");
-               return ERROR_FAIL;
-       }
-       return target->type->write_memory_imp(target, address, size, count, buffer);
-}
-
-static int target_read_memory_imp(struct target *target, uint32_t address,
-               uint32_t size, uint32_t count, uint8_t *buffer)
-{
-       if (!target_was_examined(target)) {
-               LOG_ERROR("Target not examined yet");
-               return ERROR_FAIL;
-       }
-       return target->type->read_memory_imp(target, address, size, count, buffer);
-}
-
-static int target_soft_reset_halt_imp(struct target *target)
+static int target_soft_reset_halt(struct target *target)
 {
        if (!target_was_examined(target)) {
                LOG_ERROR("Target not examined yet");
                return ERROR_FAIL;
        }
-       if (!target->type->soft_reset_halt_imp) {
+       if (!target->type->soft_reset_halt) {
                LOG_ERROR("Target %s does not support soft_reset_halt",
                                target_name(target));
                return ERROR_FAIL;
        }
-       return target->type->soft_reset_halt_imp(target);
+       return target->type->soft_reset_halt(target);
 }
 
 /**
@@ -822,6 +820,7 @@ int target_run_flash_async_algorithm(struct target *target,
                uint32_t entry_point, uint32_t exit_point, void *arch_info)
 {
        int retval;
+       int timeout = 0;
 
        /* Set up working area. First word is write pointer, second word is read pointer,
         * rest is fifo data area. */
@@ -893,9 +892,19 @@ int target_run_flash_async_algorithm(struct target *target,
                         * less than buffer size / flash speed. This is very unlikely to
                         * run when using high latency connections such as USB. */
                        alive_sleep(10);
+
+                       /* to stop an infinite loop on some targets check and increment a timeout
+                        * this issue was observed on a stellaris using the new ICDI interface */
+                       if (timeout++ >= 500) {
+                               LOG_ERROR("timeout waiting for algorithm, a target reset is recommended");
+                               return ERROR_FLASH_OPERATION_FAILED;
+                       }
                        continue;
                }
 
+               /* reset our timeout */
+               timeout = 0;
+
                /* Limit to the amount of data we actually want to write */
                if (thisrun_bytes > count * block_size)
                        thisrun_bytes = count * block_size;
@@ -940,38 +949,48 @@ int target_run_flash_async_algorithm(struct target *target,
 int target_read_memory(struct target *target,
                uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
 {
+       if (!target_was_examined(target)) {
+               LOG_ERROR("Target not examined yet");
+               return ERROR_FAIL;
+       }
        return target->type->read_memory(target, address, size, count, buffer);
 }
 
-static int target_read_phys_memory(struct target *target,
+int target_read_phys_memory(struct target *target,
                uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
 {
+       if (!target_was_examined(target)) {
+               LOG_ERROR("Target not examined yet");
+               return ERROR_FAIL;
+       }
        return target->type->read_phys_memory(target, address, size, count, buffer);
 }
 
 int target_write_memory(struct target *target,
                uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer)
 {
+       if (!target_was_examined(target)) {
+               LOG_ERROR("Target not examined yet");
+               return ERROR_FAIL;
+       }
        return target->type->write_memory(target, address, size, count, buffer);
 }
 
-static int target_write_phys_memory(struct target *target,
+int target_write_phys_memory(struct target *target,
                uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer)
 {
+       if (!target_was_examined(target)) {
+               LOG_ERROR("Target not examined yet");
+               return ERROR_FAIL;
+       }
        return target->type->write_phys_memory(target, address, size, count, buffer);
 }
 
-int target_bulk_write_memory(struct target *target,
-               uint32_t address, uint32_t count, const uint8_t *buffer)
-{
-       return target->type->bulk_write_memory(target, address, count, buffer);
-}
-
 int target_add_breakpoint(struct target *target,
                struct breakpoint *breakpoint)
 {
        if ((target->state != TARGET_HALTED) && (breakpoint->type != BKPT_HARD)) {
-               LOG_WARNING("target %s is not halted", target->cmd_name);
+               LOG_WARNING("target %s is not halted", target_name(target));
                return ERROR_TARGET_NOT_HALTED;
        }
        return target->type->add_breakpoint(target, breakpoint);
@@ -981,7 +1000,7 @@ int target_add_context_breakpoint(struct target *target,
                struct breakpoint *breakpoint)
 {
        if (target->state != TARGET_HALTED) {
-               LOG_WARNING("target %s is not halted", target->cmd_name);
+               LOG_WARNING("target %s is not halted", target_name(target));
                return ERROR_TARGET_NOT_HALTED;
        }
        return target->type->add_context_breakpoint(target, breakpoint);
@@ -991,7 +1010,7 @@ int target_add_hybrid_breakpoint(struct target *target,
                struct breakpoint *breakpoint)
 {
        if (target->state != TARGET_HALTED) {
-               LOG_WARNING("target %s is not halted", target->cmd_name);
+               LOG_WARNING("target %s is not halted", target_name(target));
                return ERROR_TARGET_NOT_HALTED;
        }
        return target->type->add_hybrid_breakpoint(target, breakpoint);
@@ -1007,7 +1026,7 @@ int target_add_watchpoint(struct target *target,
                struct watchpoint *watchpoint)
 {
        if (target->state != TARGET_HALTED) {
-               LOG_WARNING("target %s is not halted", target->cmd_name);
+               LOG_WARNING("target %s is not halted", target_name(target));
                return ERROR_TARGET_NOT_HALTED;
        }
        return target->type->add_watchpoint(target, watchpoint);
@@ -1017,11 +1036,29 @@ int target_remove_watchpoint(struct target *target,
 {
        return target->type->remove_watchpoint(target, watchpoint);
 }
+int target_hit_watchpoint(struct target *target,
+               struct watchpoint **hit_watchpoint)
+{
+       if (target->state != TARGET_HALTED) {
+               LOG_WARNING("target %s is not halted", target->cmd_name);
+               return ERROR_TARGET_NOT_HALTED;
+       }
+
+       if (target->type->hit_watchpoint == NULL) {
+               /* For backward compatible, if hit_watchpoint is not implemented,
+                * return ERROR_FAIL such that gdb_server will not take the nonsense
+                * information. */
+               return ERROR_FAIL;
+       }
+
+       return target->type->hit_watchpoint(target, hit_watchpoint);
+}
 
 int target_get_gdb_reg_list(struct target *target,
-               struct reg **reg_list[], int *reg_list_size)
+               struct reg **reg_list[], int *reg_list_size,
+               enum target_register_class reg_class)
 {
-       return target->type->get_gdb_reg_list(target, reg_list, reg_list_size);
+       return target->type->get_gdb_reg_list(target, reg_list, reg_list_size, reg_class);
 }
 int target_step(struct target *target,
                int current, uint32_t address, int handle_breakpoints)
@@ -1029,6 +1066,24 @@ int target_step(struct target *target,
        return target->type->step(target, current, address, handle_breakpoints);
 }
 
+int target_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fileio_info)
+{
+       if (target->state != TARGET_HALTED) {
+               LOG_WARNING("target %s is not halted", target->cmd_name);
+               return ERROR_TARGET_NOT_HALTED;
+       }
+       return target->type->get_gdb_fileio_info(target, fileio_info);
+}
+
+int target_gdb_fileio_end(struct target *target, int retcode, int fileio_errno, bool ctrl_c)
+{
+       if (target->state != TARGET_HALTED) {
+               LOG_WARNING("target %s is not halted", target->cmd_name);
+               return ERROR_TARGET_NOT_HALTED;
+       }
+       return target->type->gdb_fileio_end(target, retcode, fileio_errno, ctrl_c);
+}
+
 /**
  * Reset the @c examined flag for the given target.
  * Pure paranoia -- targets are zeroed on allocation.
@@ -1074,23 +1129,6 @@ static int target_init_one(struct command_context *cmd_ctx,
                return retval;
        }
 
-       /**
-        * @todo get rid of those *memory_imp() methods, now that all
-        * callers are using target_*_memory() accessors ... and make
-        * sure the "physical" paths handle the same issues.
-        */
-       /* a non-invasive way(in terms of patches) to add some code that
-        * runs before the type->write/read_memory implementation
-        */
-       type->write_memory_imp = target->type->write_memory;
-       type->write_memory = target_write_memory_imp;
-
-       type->read_memory_imp = target->type->read_memory;
-       type->read_memory = target_read_memory_imp;
-
-       type->soft_reset_halt_imp = target->type->soft_reset_halt;
-       type->soft_reset_halt = target_soft_reset_halt_imp;
-
        /* Sanity-check MMU support ... stub in what we must, to help
         * implement it in stages, but warn if we need to do so.
         */
@@ -1129,6 +1167,12 @@ static int target_init_one(struct command_context *cmd_ctx,
        if (target->type->write_buffer == NULL)
                target->type->write_buffer = target_write_buffer_default;
 
+       if (target->type->get_gdb_fileio_info == NULL)
+               target->type->get_gdb_fileio_info = target_get_gdb_fileio_info_default;
+
+       if (target->type->gdb_fileio_end == NULL)
+               target->type->gdb_fileio_end = target_gdb_fileio_end_default;
+
        return ERROR_OK;
 }
 
@@ -1678,6 +1722,22 @@ int target_arch_state(struct target *target)
        return retval;
 }
 
+static int target_get_gdb_fileio_info_default(struct target *target,
+               struct gdb_fileio_info *fileio_info)
+{
+       /* If target does not support semi-hosting function, target
+          has no need to provide .get_gdb_fileio_info callback.
+          It just return ERROR_FAIL and gdb_server will return "Txx"
+          as target halted every time.  */
+       return ERROR_FAIL;
+}
+
+static int target_gdb_fileio_end_default(struct target *target,
+               int retcode, int fileio_errno, bool ctrl_c)
+{
+       return ERROR_OK;
+}
+
 /* Single aligned words are guaranteed to use 16 or 32 bit access
  * mode respectively, otherwise data is handled as quickly as
  * possible
@@ -1706,57 +1766,37 @@ int target_write_buffer(struct target *target, uint32_t address, uint32_t size,
        return target->type->write_buffer(target, address, size, buffer);
 }
 
-static int target_write_buffer_default(struct target *target, uint32_t address, uint32_t size, const uint8_t *buffer)
+static int target_write_buffer_default(struct target *target, uint32_t address, uint32_t count, const uint8_t *buffer)
 {
-       int retval = ERROR_OK;
-
-       if (((address % 2) == 0) && (size == 2))
-               return target_write_memory(target, address, 2, 1, buffer);
-
-       /* handle unaligned head bytes */
-       if (address % 4) {
-               uint32_t unaligned = 4 - (address % 4);
-
-               if (unaligned > size)
-                       unaligned = size;
+       uint32_t size;
 
-               retval = target_write_memory(target, address, 1, unaligned, buffer);
-               if (retval != ERROR_OK)
-                       return retval;
-
-               buffer += unaligned;
-               address += unaligned;
-               size -= unaligned;
-       }
-
-       /* handle aligned words */
-       if (size >= 4) {
-               int aligned = size - (size % 4);
-
-               /* use bulk writes above a certain limit. This may have to be changed */
-               if (aligned > 128) {
-                       retval = target->type->bulk_write_memory(target, address, aligned / 4, buffer);
-                       if (retval != ERROR_OK)
-                               return retval;
-               } else {
-                       retval = target_write_memory(target, address, 4, aligned / 4, buffer);
+       /* Align up to maximum 4 bytes. The loop condition makes sure the next pass
+        * will have something to do with the size we leave to it. */
+       for (size = 1; size < 4 && count >= size * 2 + (address & size); size *= 2) {
+               if (address & size) {
+                       int retval = target_write_memory(target, address, size, 1, buffer);
                        if (retval != ERROR_OK)
                                return retval;
+                       address += size;
+                       count -= size;
+                       buffer += size;
                }
-
-               buffer += aligned;
-               address += aligned;
-               size -= aligned;
        }
 
-       /* handle tail writes of less than 4 bytes */
-       if (size > 0) {
-               retval = target_write_memory(target, address, 1, size, buffer);
-               if (retval != ERROR_OK)
-                       return retval;
+       /* Write the data with as large access size as possible. */
+       for (; size > 0; size /= 2) {
+               uint32_t aligned = count - count % size;
+               if (aligned > 0) {
+                       int retval = target_write_memory(target, address, size, aligned / size, buffer);
+                       if (retval != ERROR_OK)
+                               return retval;
+                       address += aligned;
+                       count -= aligned;
+                       buffer += aligned;
+               }
        }
 
-       return retval;
+       return ERROR_OK;
 }
 
 /* Single aligned words are guaranteed to use 16 or 32 bit access
@@ -1787,58 +1827,34 @@ int target_read_buffer(struct target *target, uint32_t address, uint32_t size, u
        return target->type->read_buffer(target, address, size, buffer);
 }
 
-static int target_read_buffer_default(struct target *target, uint32_t address, uint32_t size, uint8_t *buffer)
+static int target_read_buffer_default(struct target *target, uint32_t address, uint32_t count, uint8_t *buffer)
 {
-       int retval = ERROR_OK;
+       uint32_t size;
 
-       if (((address % 2) == 0) && (size == 2))
-               return target_read_memory(target, address, 2, 1, buffer);
-
-       /* handle unaligned head bytes */
-       if (address % 4) {
-               uint32_t unaligned = 4 - (address % 4);
-
-               if (unaligned > size)
-                       unaligned = size;
-
-               retval = target_read_memory(target, address, 1, unaligned, buffer);
-               if (retval != ERROR_OK)
-                       return retval;
-
-               buffer += unaligned;
-               address += unaligned;
-               size -= unaligned;
-       }
-
-       /* handle aligned words */
-       if (size >= 4) {
-               int aligned = size - (size % 4);
-
-               retval = target_read_memory(target, address, 4, aligned / 4, buffer);
-               if (retval != ERROR_OK)
-                       return retval;
-
-               buffer += aligned;
-               address += aligned;
-               size -= aligned;
+       /* Align up to maximum 4 bytes. The loop condition makes sure the next pass
+        * will have something to do with the size we leave to it. */
+       for (size = 1; size < 4 && count >= size * 2 + (address & size); size *= 2) {
+               if (address & size) {
+                       int retval = target_read_memory(target, address, size, 1, buffer);
+                       if (retval != ERROR_OK)
+                               return retval;
+                       address += size;
+                       count -= size;
+                       buffer += size;
+               }
        }
 
-       /*prevent byte access when possible (avoid AHB access limitations in some cases)*/
-       if (size        >= 2) {
-               int aligned = size - (size % 2);
-               retval = target_read_memory(target, address, 2, aligned / 2, buffer);
-               if (retval != ERROR_OK)
-                       return retval;
-
-               buffer += aligned;
-               address += aligned;
-               size -= aligned;
-       }
-       /* handle tail writes of less than 4 bytes */
-       if (size > 0) {
-               retval = target_read_memory(target, address, 1, size, buffer);
-               if (retval != ERROR_OK)
-                       return retval;
+       /* Read the data with as large access size as possible. */
+       for (; size > 0; size /= 2) {
+               uint32_t aligned = count - count % size;
+               if (aligned > 0) {
+                       int retval = target_read_memory(target, address, size, aligned / size, buffer);
+                       if (retval != ERROR_OK)
+                               return retval;
+                       address += aligned;
+                       count -= aligned;
+                       buffer += aligned;
+               }
        }
 
        return ERROR_OK;
@@ -2153,9 +2169,6 @@ static int sense_handler(void)
        return ERROR_OK;
 }
 
-static int backoff_times;
-static int backoff_count;
-
 /* process target state changes */
 static int handle_target(void *priv)
 {
@@ -2211,13 +2224,6 @@ static int handle_target(void *priv)
                recursive = 0;
        }
 
-       if (backoff_times > backoff_count) {
-               /* do not poll this time as we failed previously */
-               backoff_count++;
-               return ERROR_OK;
-       }
-       backoff_count = 0;
-
        /* Poll targets for state changes unless that's globally disabled.
         * Skip targets that are currently disabled.
         */
@@ -2227,18 +2233,26 @@ static int handle_target(void *priv)
                if (!target->tap->enabled)
                        continue;
 
+               if (target->backoff.times > target->backoff.count) {
+                       /* do not poll this time as we failed previously */
+                       target->backoff.count++;
+                       continue;
+               }
+               target->backoff.count = 0;
+
                /* only poll target if we've got power and srst isn't asserted */
                if (!powerDropout && !srstAsserted) {
                        /* polling may fail silently until the target has been examined */
                        retval = target_poll(target);
                        if (retval != ERROR_OK) {
                                /* 100ms polling interval. Increase interval between polling up to 5000ms */
-                               if (backoff_times * polling_interval < 5000) {
-                                       backoff_times *= 2;
-                                       backoff_times++;
+                               if (target->backoff.times * polling_interval < 5000) {
+                                       target->backoff.times *= 2;
+                                       target->backoff.times++;
                                }
-                               LOG_USER("Polling target failed, GDB will be halted. Polling again in %dms",
-                                               backoff_times * polling_interval);
+                               LOG_USER("Polling target %s failed, GDB will be halted. Polling again in %dms",
+                                               target_name(target),
+                                               target->backoff.times * polling_interval);
 
                                /* Tell GDB to halt the debugger. This allows the user to
                                 * run monitor commands to handle the situation.
@@ -2247,9 +2261,9 @@ static int handle_target(void *priv)
                                return retval;
                        }
                        /* Since we succeeded, we reset backoff count */
-                       if (backoff_times > 0)
-                               LOG_USER("Polling succeeded again");
-                       backoff_times = 0;
+                       if (target->backoff.times > 0)
+                               LOG_USER("Polling target %s succeeded again", target_name(target));
+                       target->backoff.times = 0;
                }
        }
 
@@ -2410,13 +2424,11 @@ COMMAND_HANDLER(handle_wait_halt_command)
        if (CMD_ARGC > 1)
                return ERROR_COMMAND_SYNTAX_ERROR;
 
-       unsigned ms = 5000;
+       unsigned ms = DEFAULT_HALT_TIMEOUT;
        if (1 == CMD_ARGC) {
                int retval = parse_uint(CMD_ARGV[0], &ms);
                if (ERROR_OK != retval)
                        return ERROR_COMMAND_SYNTAX_ERROR;
-               /* convert seconds (given) to milliseconds (needed) */
-               ms *= 1000;
        }
 
        struct target *target = get_current_target(CMD_CTX);
@@ -2489,7 +2501,7 @@ COMMAND_HANDLER(handle_soft_reset_halt_command)
 
        LOG_USER("requesting target halt and executing a soft reset");
 
-       target->type->soft_reset_halt(target);
+       target_soft_reset_halt(target);
 
        return ERROR_OK;
 }
@@ -3375,24 +3387,28 @@ static void writeGmon(uint32_t *samples, uint32_t sampleNum, const char *filenam
                        max = samples[i];
        }
 
-       int addressSpace = (max - min + 1);
+       /* max should be (largest sample + 1)
+        * Refer to binutils/gprof/hist.c (find_histogram_for_pc) */
+       max++;
+
+       int addressSpace = max - min;
        assert(addressSpace >= 2);
 
        static const uint32_t maxBuckets = 16 * 1024; /* maximum buckets. */
-       uint32_t length = addressSpace;
-       if (length > maxBuckets)
-               length = maxBuckets;
-       int *buckets = malloc(sizeof(int)*length);
+       uint32_t numBuckets = addressSpace;
+       if (numBuckets > maxBuckets)
+               numBuckets = maxBuckets;
+       int *buckets = malloc(sizeof(int) * numBuckets);
        if (buckets == NULL) {
                fclose(f);
                return;
        }
-       memset(buckets, 0, sizeof(int) * length);
+       memset(buckets, 0, sizeof(int) * numBuckets);
        for (i = 0; i < sampleNum; i++) {
                uint32_t address = samples[i];
                long long a = address - min;
-               long long b = length - 1;
-               long long c = addressSpace - 1;
+               long long b = numBuckets;
+               long long c = addressSpace;
                int index_t = (a * b) / c; /* danger!!!! int32 overflows */
                buckets[index_t]++;
        }
@@ -3400,7 +3416,7 @@ static void writeGmon(uint32_t *samples, uint32_t sampleNum, const char *filenam
        /* append binary memory gmon.out &profile_hist_hdr ((char*)&profile_hist_hdr + sizeof(struct gmon_hist_hdr)) */
        writeLong(f, min);                      /* low_pc */
        writeLong(f, max);                      /* high_pc */
-       writeLong(f, length);           /* # of samples */
+       writeLong(f, numBuckets);       /* # of buckets */
        writeLong(f, 100);                      /* KLUDGE! We lie, ca. 100Hz best case. */
        writeString(f, "seconds");
        for (i = 0; i < (15-strlen("seconds")); i++)
@@ -3409,9 +3425,9 @@ static void writeGmon(uint32_t *samples, uint32_t sampleNum, const char *filenam
 
        /*append binary memory gmon.out profile_hist_data (profile_hist_data + profile_hist_hdr.hist_size) */
 
-       char *data = malloc(2 * length);
+       char *data = malloc(2 * numBuckets);
        if (data != NULL) {
-               for (i = 0; i < length; i++) {
+               for (i = 0; i < numBuckets; i++) {
                        int val;
                        val = buckets[i];
                        if (val > 65535)
@@ -3420,7 +3436,7 @@ static void writeGmon(uint32_t *samples, uint32_t sampleNum, const char *filenam
                        data[i * 2 + 1] = (val >> 8) & 0xff;
                }
                free(buckets);
-               writeData(f, data, length * 2);
+               writeData(f, data, numBuckets * 2);
                free(data);
        } else
                free(buckets);
@@ -4898,6 +4914,15 @@ static int target_create(Jim_GetOptInfo *goi)
                        /* found */
                        break;
                }
+
+               /* check for deprecated name */
+               if (target_types[x]->deprecated_name) {
+                       if (0 == strcmp(cp, target_types[x]->deprecated_name)) {
+                               /* found */
+                               LOG_WARNING("target name is deprecated use: \'%s\'", target_types[x]->name);
+                               break;
+                       }
+               }
        }
        if (target_types[x] == NULL) {
                Jim_SetResultFormatted(goi->interp, "Unknown target type %s, try one of ", cp);
@@ -5014,7 +5039,7 @@ static int target_create(Jim_GetOptInfo *goi)
        }
 
        /* now - create the new target name command */
-       const const struct command_registration target_subcommands[] = {
+       const struct command_registration target_subcommands[] = {
                {
                        .chain = target_instance_command_handlers,
                },
@@ -5023,7 +5048,7 @@ static int target_create(Jim_GetOptInfo *goi)
                },
                COMMAND_REGISTRATION_DONE
        };
-       const const struct command_registration target_commands[] = {
+       const struct command_registration target_commands[] = {
                {
                        .name = cp,
                        .mode = COMMAND_ANY,
@@ -5053,7 +5078,7 @@ static int jim_target_current(Jim_Interp *interp, int argc, Jim_Obj *const *argv
        struct command_context *cmd_ctx = current_command_context(interp);
        assert(cmd_ctx != NULL);
 
-       Jim_SetResultString(interp, get_current_target(cmd_ctx)->cmd_name, -1);
+       Jim_SetResultString(interp, target_name(get_current_target(cmd_ctx)), -1);
        return JIM_OK;
 }
 
@@ -5527,7 +5552,7 @@ static const struct command_registration target_exec_command_handlers[] = {
                .handler = handle_wait_halt_command,
                .mode = COMMAND_EXEC,
                .help = "wait up to the specified number of milliseconds "
-                       "(default 5) for a previously requested halt",
+                       "(default 5000) for a previously requested halt",
                .usage = "[milliseconds]",
        },
        {
@@ -5535,7 +5560,7 @@ static const struct command_registration target_exec_command_handlers[] = {
                .handler = handle_halt_command,
                .mode = COMMAND_EXEC,
                .help = "request target to halt, then wait up to the specified"
-                       "number of milliseconds (default 5) for it to complete",
+                       "number of milliseconds (default 5000) for it to complete",
                .usage = "[milliseconds]",
        },
        {