This is an automated email from Gerrit.

"Tim Newsome <t...@sifive.com>" just uploaded a new patch set to Gerrit, which 
you can find at https://review.openocd.org/c/openocd/+/6775

-- gerrit

commit 0c386059c1769c4be46c58449a5c9a04c6d4cb39
Author: Tim Newsome <t...@sifive.com>
Date:   Tue Nov 2 09:55:07 2021 -0700

    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 <t...@sifive.com>

diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c
index 407b7e279..c9840fe50 100644
--- a/src/target/riscv/riscv.c
+++ b/src/target/riscv/riscv.c
@@ -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;
diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h
index d0f4f6ec0..0ae8945da 100644
--- a/src/target/riscv/riscv.h
+++ b/src/target/riscv/riscv.h
@@ -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;

-- 

Reply via email to