target/riscv: calloc() memory per register.
This replaces a static array with 8 bytes per register. When there are vector registers larger than 8 bytes, they would end up clobbering each other's values. I can't believe I didn't catch this earlier. See https://github.com/riscv/riscv-openocd/pull/658 Change-Id: I9df4eaf05617a2c8df3140fff9fe53f61ab2b261 Signed-off-by: Tim Newsome <tim@sifive.com> Reviewed-on: https://review.openocd.org/c/openocd/+/6775 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
This commit is contained in:
parent
9828c0a440
commit
3ba21e5f00
|
@ -476,6 +476,8 @@ static void riscv_free_registers(struct target *target)
|
|||
/* Free the ones we allocated separately. */
|
||||
for (unsigned i = GDB_REGNO_COUNT; i < target->reg_cache->num_regs; i++)
|
||||
free(target->reg_cache->reg_list[i].arch_info);
|
||||
for (unsigned int i = 0; i < target->reg_cache->num_regs; i++)
|
||||
free(target->reg_cache->reg_list[i].value);
|
||||
free(target->reg_cache->reg_list);
|
||||
}
|
||||
free(target->reg_cache);
|
||||
|
@ -1749,8 +1751,8 @@ static int riscv_get_gdb_reg_list_internal(struct target *target,
|
|||
enum target_register_class reg_class, bool read)
|
||||
{
|
||||
RISCV_INFO(r);
|
||||
LOG_DEBUG("current_hartid=%d, reg_class=%d, read=%d",
|
||||
r->current_hartid, reg_class, read);
|
||||
LOG_DEBUG("[%s] {%d} reg_class=%d, read=%d",
|
||||
target_name(target), r->current_hartid, reg_class, read);
|
||||
|
||||
if (!target->reg_cache) {
|
||||
LOG_ERROR("Target not initialized. Return ERROR_FAIL.");
|
||||
|
@ -4479,7 +4481,7 @@ int riscv_init_registers(struct target *target)
|
|||
assert(reg_name < info->reg_names + target->reg_cache->num_regs *
|
||||
max_reg_name_len);
|
||||
}
|
||||
r->value = info->reg_cache_values[number];
|
||||
r->value = calloc(1, DIV_ROUND_UP(r->size, 8));
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
|
|
|
@ -96,11 +96,6 @@ typedef struct {
|
|||
* every function than an actual */
|
||||
int current_hartid;
|
||||
|
||||
/* OpenOCD's register cache points into here. This is not per-hart because
|
||||
* we just invalidate the entire cache when we change which hart is
|
||||
* selected. Use an array of 8 uint8_t per register. */
|
||||
uint8_t reg_cache_values[RISCV_MAX_REGISTERS][8];
|
||||
|
||||
/* Single buffer that contains all register names, instead of calling
|
||||
* malloc for each register. Needs to be freed when reg_list is freed. */
|
||||
char *reg_names;
|
||||
|
|
Loading…
Reference in New Issue