diff mbox series

[v3,05/11] contrib/plugins/stoptrigger: fix 32-bit build

Message ID 20241217224306.2900490-6-pierrick.bouvier@linaro.org
State New
Headers show
Series Fix 32-bit build for plugins | expand

Commit Message

Pierrick Bouvier Dec. 17, 2024, 10:43 p.m. UTC
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
---
 contrib/plugins/stoptrigger.c | 48 ++++++++++++++++++++---------------
 1 file changed, 27 insertions(+), 21 deletions(-)

Comments

Richard Henderson Dec. 18, 2024, 4:57 p.m. UTC | #1
On 12/17/24 16:43, Pierrick Bouvier wrote:
> Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
> ---
>   contrib/plugins/stoptrigger.c | 48 ++++++++++++++++++++---------------
>   1 file changed, 27 insertions(+), 21 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

> 
> diff --git a/contrib/plugins/stoptrigger.c b/contrib/plugins/stoptrigger.c
> index 03ee22f4c6a..b3a6ed66a7b 100644
> --- a/contrib/plugins/stoptrigger.c
> +++ b/contrib/plugins/stoptrigger.c
> @@ -21,9 +21,11 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
>   /* Scoreboard to track executed instructions count */
>   typedef struct {
>       uint64_t insn_count;
> +    uint64_t current_pc;
>   } InstructionsCount;
>   static struct qemu_plugin_scoreboard *insn_count_sb;
>   static qemu_plugin_u64 insn_count;
> +static qemu_plugin_u64 current_pc;
>   
>   static uint64_t icount;
>   static int icount_exit_code;
> @@ -34,6 +36,11 @@ static bool exit_on_address;
>   /* Map trigger addresses to exit code */
>   static GHashTable *addrs_ht;
>   
> +typedef struct {
> +    uint64_t exit_addr;
> +    int exit_code;
> +} ExitInfo;
> +
>   static void exit_emulation(int return_code, char *message)
>   {
>       qemu_plugin_outs(message);
> @@ -43,23 +50,18 @@ static void exit_emulation(int return_code, char *message)
>   
>   static void exit_icount_reached(unsigned int cpu_index, void *udata)
>   {
> -    uint64_t insn_vaddr = GPOINTER_TO_UINT(udata);
> +    uint64_t insn_vaddr = qemu_plugin_u64_get(current_pc, cpu_index);
>       char *msg = g_strdup_printf("icount reached at 0x%" PRIx64 ", exiting\n",
>                                   insn_vaddr);
> -
>       exit_emulation(icount_exit_code, msg);
>   }
>   
>   static void exit_address_reached(unsigned int cpu_index, void *udata)
>   {
> -    uint64_t insn_vaddr = GPOINTER_TO_UINT(udata);
> -    char *msg = g_strdup_printf("0x%" PRIx64 " reached, exiting\n", insn_vaddr);
> -    int exit_code;
> -
> -    exit_code = GPOINTER_TO_INT(
> -        g_hash_table_lookup(addrs_ht, GUINT_TO_POINTER(insn_vaddr)));
> -
> -    exit_emulation(exit_code, msg);
> +    ExitInfo *ei = udata;
> +    g_assert(ei);
> +    char *msg = g_strdup_printf("0x%" PRIx64 " reached, exiting\n", ei->exit_addr);
> +    exit_emulation(ei->exit_code, msg);
>   }
>   
>   static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb)
> @@ -67,23 +69,25 @@ static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb)
>       size_t tb_n = qemu_plugin_tb_n_insns(tb);
>       for (size_t i = 0; i < tb_n; i++) {
>           struct qemu_plugin_insn *insn = qemu_plugin_tb_get_insn(tb, i);
> -        gpointer insn_vaddr = GUINT_TO_POINTER(qemu_plugin_insn_vaddr(insn));
> +        uint64_t insn_vaddr = qemu_plugin_insn_vaddr(insn);
>   
>           if (exit_on_icount) {
>               /* Increment and check scoreboard for each instruction */
>               qemu_plugin_register_vcpu_insn_exec_inline_per_vcpu(
>                   insn, QEMU_PLUGIN_INLINE_ADD_U64, insn_count, 1);
> +            qemu_plugin_register_vcpu_insn_exec_inline_per_vcpu(
> +                insn, QEMU_PLUGIN_INLINE_STORE_U64, current_pc, insn_vaddr);
>               qemu_plugin_register_vcpu_insn_exec_cond_cb(
>                   insn, exit_icount_reached, QEMU_PLUGIN_CB_NO_REGS,
> -                QEMU_PLUGIN_COND_EQ, insn_count, icount + 1, insn_vaddr);
> +                QEMU_PLUGIN_COND_EQ, insn_count, icount + 1, NULL);
>           }
>   
>           if (exit_on_address) {
> -            if (g_hash_table_contains(addrs_ht, insn_vaddr)) {
> +            ExitInfo *ei = g_hash_table_lookup(addrs_ht, &insn_vaddr);
> +            if (ei) {
>                   /* Exit triggered by address */
>                   qemu_plugin_register_vcpu_insn_exec_cb(
> -                    insn, exit_address_reached, QEMU_PLUGIN_CB_NO_REGS,
> -                    insn_vaddr);
> +                    insn, exit_address_reached, QEMU_PLUGIN_CB_NO_REGS, ei);
>               }
>           }
>       }
> @@ -99,11 +103,13 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
>                                              const qemu_info_t *info, int argc,
>                                              char **argv)
>   {
> -    addrs_ht = g_hash_table_new(NULL, g_direct_equal);
> +    addrs_ht = g_hash_table_new_full(g_int64_hash, g_int64_equal, NULL, g_free);
>   
>       insn_count_sb = qemu_plugin_scoreboard_new(sizeof(InstructionsCount));
>       insn_count = qemu_plugin_scoreboard_u64_in_struct(
>           insn_count_sb, InstructionsCount, insn_count);
> +    current_pc = qemu_plugin_scoreboard_u64_in_struct(
> +        insn_count_sb, InstructionsCount, current_pc);
>   
>       for (int i = 0; i < argc; i++) {
>           char *opt = argv[i];
> @@ -124,13 +130,13 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
>               exit_on_icount = true;
>           } else if (g_strcmp0(tokens[0], "addr") == 0) {
>               g_auto(GStrv) addr_tokens = g_strsplit(tokens[1], ":", 2);
> -            uint64_t exit_addr = g_ascii_strtoull(addr_tokens[0], NULL, 0);
> -            int exit_code = 0;
> +            ExitInfo *ei = g_malloc(sizeof(ExitInfo));
> +            ei->exit_addr = g_ascii_strtoull(addr_tokens[0], NULL, 0);
> +            ei->exit_code = 0;
>               if (addr_tokens[1]) {
> -                exit_code = g_ascii_strtoull(addr_tokens[1], NULL, 0);
> +                ei->exit_code = g_ascii_strtoull(addr_tokens[1], NULL, 0);
>               }
> -            g_hash_table_insert(addrs_ht, GUINT_TO_POINTER(exit_addr),
> -                                GINT_TO_POINTER(exit_code));
> +            g_hash_table_insert(addrs_ht, &ei->exit_addr, ei);
>               exit_on_address = true;
>           } else {
>               fprintf(stderr, "option parsing failed: %s\n", opt);
diff mbox series

Patch

diff --git a/contrib/plugins/stoptrigger.c b/contrib/plugins/stoptrigger.c
index 03ee22f4c6a..b3a6ed66a7b 100644
--- a/contrib/plugins/stoptrigger.c
+++ b/contrib/plugins/stoptrigger.c
@@ -21,9 +21,11 @@  QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
 /* Scoreboard to track executed instructions count */
 typedef struct {
     uint64_t insn_count;
+    uint64_t current_pc;
 } InstructionsCount;
 static struct qemu_plugin_scoreboard *insn_count_sb;
 static qemu_plugin_u64 insn_count;
+static qemu_plugin_u64 current_pc;
 
 static uint64_t icount;
 static int icount_exit_code;
@@ -34,6 +36,11 @@  static bool exit_on_address;
 /* Map trigger addresses to exit code */
 static GHashTable *addrs_ht;
 
+typedef struct {
+    uint64_t exit_addr;
+    int exit_code;
+} ExitInfo;
+
 static void exit_emulation(int return_code, char *message)
 {
     qemu_plugin_outs(message);
@@ -43,23 +50,18 @@  static void exit_emulation(int return_code, char *message)
 
 static void exit_icount_reached(unsigned int cpu_index, void *udata)
 {
-    uint64_t insn_vaddr = GPOINTER_TO_UINT(udata);
+    uint64_t insn_vaddr = qemu_plugin_u64_get(current_pc, cpu_index);
     char *msg = g_strdup_printf("icount reached at 0x%" PRIx64 ", exiting\n",
                                 insn_vaddr);
-
     exit_emulation(icount_exit_code, msg);
 }
 
 static void exit_address_reached(unsigned int cpu_index, void *udata)
 {
-    uint64_t insn_vaddr = GPOINTER_TO_UINT(udata);
-    char *msg = g_strdup_printf("0x%" PRIx64 " reached, exiting\n", insn_vaddr);
-    int exit_code;
-
-    exit_code = GPOINTER_TO_INT(
-        g_hash_table_lookup(addrs_ht, GUINT_TO_POINTER(insn_vaddr)));
-
-    exit_emulation(exit_code, msg);
+    ExitInfo *ei = udata;
+    g_assert(ei);
+    char *msg = g_strdup_printf("0x%" PRIx64 " reached, exiting\n", ei->exit_addr);
+    exit_emulation(ei->exit_code, msg);
 }
 
 static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb)
@@ -67,23 +69,25 @@  static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb)
     size_t tb_n = qemu_plugin_tb_n_insns(tb);
     for (size_t i = 0; i < tb_n; i++) {
         struct qemu_plugin_insn *insn = qemu_plugin_tb_get_insn(tb, i);
-        gpointer insn_vaddr = GUINT_TO_POINTER(qemu_plugin_insn_vaddr(insn));
+        uint64_t insn_vaddr = qemu_plugin_insn_vaddr(insn);
 
         if (exit_on_icount) {
             /* Increment and check scoreboard for each instruction */
             qemu_plugin_register_vcpu_insn_exec_inline_per_vcpu(
                 insn, QEMU_PLUGIN_INLINE_ADD_U64, insn_count, 1);
+            qemu_plugin_register_vcpu_insn_exec_inline_per_vcpu(
+                insn, QEMU_PLUGIN_INLINE_STORE_U64, current_pc, insn_vaddr);
             qemu_plugin_register_vcpu_insn_exec_cond_cb(
                 insn, exit_icount_reached, QEMU_PLUGIN_CB_NO_REGS,
-                QEMU_PLUGIN_COND_EQ, insn_count, icount + 1, insn_vaddr);
+                QEMU_PLUGIN_COND_EQ, insn_count, icount + 1, NULL);
         }
 
         if (exit_on_address) {
-            if (g_hash_table_contains(addrs_ht, insn_vaddr)) {
+            ExitInfo *ei = g_hash_table_lookup(addrs_ht, &insn_vaddr);
+            if (ei) {
                 /* Exit triggered by address */
                 qemu_plugin_register_vcpu_insn_exec_cb(
-                    insn, exit_address_reached, QEMU_PLUGIN_CB_NO_REGS,
-                    insn_vaddr);
+                    insn, exit_address_reached, QEMU_PLUGIN_CB_NO_REGS, ei);
             }
         }
     }
@@ -99,11 +103,13 @@  QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
                                            const qemu_info_t *info, int argc,
                                            char **argv)
 {
-    addrs_ht = g_hash_table_new(NULL, g_direct_equal);
+    addrs_ht = g_hash_table_new_full(g_int64_hash, g_int64_equal, NULL, g_free);
 
     insn_count_sb = qemu_plugin_scoreboard_new(sizeof(InstructionsCount));
     insn_count = qemu_plugin_scoreboard_u64_in_struct(
         insn_count_sb, InstructionsCount, insn_count);
+    current_pc = qemu_plugin_scoreboard_u64_in_struct(
+        insn_count_sb, InstructionsCount, current_pc);
 
     for (int i = 0; i < argc; i++) {
         char *opt = argv[i];
@@ -124,13 +130,13 @@  QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
             exit_on_icount = true;
         } else if (g_strcmp0(tokens[0], "addr") == 0) {
             g_auto(GStrv) addr_tokens = g_strsplit(tokens[1], ":", 2);
-            uint64_t exit_addr = g_ascii_strtoull(addr_tokens[0], NULL, 0);
-            int exit_code = 0;
+            ExitInfo *ei = g_malloc(sizeof(ExitInfo));
+            ei->exit_addr = g_ascii_strtoull(addr_tokens[0], NULL, 0);
+            ei->exit_code = 0;
             if (addr_tokens[1]) {
-                exit_code = g_ascii_strtoull(addr_tokens[1], NULL, 0);
+                ei->exit_code = g_ascii_strtoull(addr_tokens[1], NULL, 0);
             }
-            g_hash_table_insert(addrs_ht, GUINT_TO_POINTER(exit_addr),
-                                GINT_TO_POINTER(exit_code));
+            g_hash_table_insert(addrs_ht, &ei->exit_addr, ei);
             exit_on_address = true;
         } else {
             fprintf(stderr, "option parsing failed: %s\n", opt);