This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC] allow ravenscar thread support on multiple architectures


Hello,

I would like to allow the ravenscar-thread module to be able to
support multiple architectures. The difference in terms of support
for each arch consists entirely of one struct:

    struct ravenscar_arch_ops
    {
      void (*to_fetch_registers) (struct regcache *, int);
      void (*to_store_registers) (struct regcache *, int);
      void (*to_prepare_to_store) (struct regcache *);
    };

Eventually, I'd like to have one for sparc, and two for powerpc
(there are multiple layouts depending on the processor type).

I think that the right place to put this information is in the
gdbarch, hence the attached prototype.  I thought I had two
options: Either add each function in the gdbarch vector, or
add the ravenscar_arch_ops vector instead.

It seemed slightly more logical to keep everything together
(ie - if you set one method, you should set the others), so
I opted for the second option.

gdb/ChangeLog:

        * gdbarch.sh (ravenscar_ops): New gdbarch variable.
        * gdbarch.h, gdbarch.c: Regenerate.
        * ravenscar-thread.c (current_arch_ops): Delete.
        (ravenscar_fetch_registers, ravenscar_store_registers)
        (ravenscar_prepare_to_store): Get ravenscar_arch_ops
        from the regcache's gdbarch.
        (ravenscar_inferior_created): Add check for gdbarch ravenscar
        arch ops.
        (ravenscar_register_arch_ops): Delete.
        * ravenscar-sparc-thread.h: New file.
        * ravenscar-sparc-thread.c: #include "ravenscar-sparc-thread.h".
        (ravenscar_sparc_ops): Remove declaration.  Define statically.
        (_initialize_ravenscar_sparc): Delete.
        (register_sparc_ravenscar_ops): New function.
        * sparc-tdep.c: #include "ravenscar-sparc-thread.h".
        (sparc32_gdbarch_init): Add call to register_sparc_ravenscar_ops.

Does this look reasonable to you, before I go any further?

Thanks!

---
 gdb/gdbarch.c                |   24 ++++++++++++++++++++++++
 gdb/gdbarch.h                |    6 ++++++
 gdb/gdbarch.sh               |    3 +++
 gdb/ravenscar-sparc-thread.c |   18 +++++++++---------
 gdb/ravenscar-sparc-thread.h |    7 +++++++
 gdb/ravenscar-thread.c       |   41 +++++++++++++++++++++++------------------
 gdb/ravenscar-thread.h       |    9 ---------
 gdb/sparc-tdep.c             |    3 +++
 8 files changed, 75 insertions(+), 36 deletions(-)
 create mode 100644 gdb/ravenscar-sparc-thread.h

diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index 887552e..4028e21 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -955,6 +955,8 @@ M:void:info_proc:char *args, enum info_proc_what what:args, what
 # inspected when the symbol search was requested.
 m:void:iterate_over_objfiles_in_search_order:iterate_over_objfiles_in_search_order_cb_ftype *cb, void *cb_data, struct objfile *current_objfile:cb, cb_data, current_objfile:0:default_iterate_over_objfiles_in_search_order::0
 
+# Ravenscar arch-dependent ops.
+v:struct ravenscar_arch_ops *:ravenscar_ops:::NULL:NULL::0:host_address_to_string (gdbarch->ravenscar_ops)
 EOF
 }
 
@@ -1072,6 +1074,7 @@ struct syscall;
 struct agent_expr;
 struct axs_value;
 struct stap_parse_info;
+struct ravenscar_arch_ops;
 
 /* The architecture associated with the inferior through the
    connection to the target.
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index 3d9dc79..f0bef30 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -57,6 +57,7 @@ struct syscall;
 struct agent_expr;
 struct axs_value;
 struct stap_parse_info;
+struct ravenscar_arch_ops;
 
 /* The architecture associated with the inferior through the
    connection to the target.
@@ -1211,6 +1212,11 @@ typedef void (gdbarch_iterate_over_objfiles_in_search_order_ftype) (struct gdbar
 extern void gdbarch_iterate_over_objfiles_in_search_order (struct gdbarch *gdbarch, iterate_over_objfiles_in_search_order_cb_ftype *cb, void *cb_data, struct objfile *current_objfile);
 extern void set_gdbarch_iterate_over_objfiles_in_search_order (struct gdbarch *gdbarch, gdbarch_iterate_over_objfiles_in_search_order_ftype *iterate_over_objfiles_in_search_order);
 
+/* Ravenscar arch-dependent ops. */
+
+extern struct ravenscar_arch_ops * gdbarch_ravenscar_ops (struct gdbarch *gdbarch);
+extern void set_gdbarch_ravenscar_ops (struct gdbarch *gdbarch, struct ravenscar_arch_ops * ravenscar_ops);
+
 /* Definition for an unknown syscall, used basically in error-cases.  */
 #define UNKNOWN_SYSCALL (-1)
 
diff --git a/gdb/ravenscar-thread.h b/gdb/ravenscar-thread.h
index 5eeab38..9edc9d7 100644
--- a/gdb/ravenscar-thread.h
+++ b/gdb/ravenscar-thread.h
@@ -29,13 +29,4 @@ struct ravenscar_arch_ops
   void (*to_prepare_to_store) (struct regcache *);
 };
 
-/* Register implementations for target ops to_store_registers,
-   to_prepare_to_store and to_fetch_registers when the inferior_ptid
-   is different from the running thread.  In that case, the registers
-   are saved in a architecture-specific location.  */
-/* FIXME: only one architecture can be registered for now.  See
-   implementation.  */
-
-extern void ravenscar_register_arch_ops (struct ravenscar_arch_ops *ops);
-
 #endif /* !defined (RAVENSCAR_THREAD_H) */
diff --git a/gdb/ravenscar-thread.c b/gdb/ravenscar-thread.c
index 0f9380b..064da7e 100644
--- a/gdb/ravenscar-thread.c
+++ b/gdb/ravenscar-thread.c
@@ -58,9 +58,6 @@ static const char ravenscar_runtime_initializer[] =
 
 static struct observer *update_target_observer = NULL;
 
-/* Architecture-specific hooks.  */
-static struct ravenscar_arch_ops* current_arch_ops;
-
 static void ravenscar_find_new_threads (struct target_ops *ops);
 static ptid_t ravenscar_running_thread (void);
 static char *ravenscar_extra_thread_info (struct thread_info *tp);
@@ -287,7 +284,13 @@ ravenscar_fetch_registers (struct target_ops *ops,
       || ptid_equal (inferior_ptid, ravenscar_running_thread ()))
     beneath->to_fetch_registers (beneath, regcache, regnum);
   else
-    current_arch_ops->to_fetch_registers (regcache, regnum);
+    {
+      struct gdbarch *gdbarch = get_regcache_arch (regcache);
+      struct ravenscar_arch_ops *arch_ops =
+	gdbarch_ravenscar_ops (gdbarch);
+
+      arch_ops->to_fetch_registers (regcache, regnum);
+    }
 }
 
 static void
@@ -301,7 +304,13 @@ ravenscar_store_registers (struct target_ops *ops,
       || ptid_equal (inferior_ptid, ravenscar_running_thread ()))
     beneath->to_store_registers (beneath, regcache, regnum);
   else
-    current_arch_ops->to_store_registers (regcache, regnum);
+    {
+      struct gdbarch *gdbarch = get_regcache_arch (regcache);
+      struct ravenscar_arch_ops *arch_ops =
+	gdbarch_ravenscar_ops (gdbarch);
+
+      arch_ops->to_store_registers (regcache, regnum);
+    }
 }
 
 static void
@@ -314,7 +323,13 @@ ravenscar_prepare_to_store (struct regcache *regcache)
       || ptid_equal (inferior_ptid, ravenscar_running_thread ()))
     beneath->to_prepare_to_store (regcache);
   else
-    current_arch_ops->to_prepare_to_store (regcache);
+    {
+      struct gdbarch *gdbarch = get_regcache_arch (regcache);
+      struct ravenscar_arch_ops *arch_ops =
+	gdbarch_ravenscar_ops (gdbarch);
+
+      arch_ops->to_prepare_to_store (regcache);
+    }
 }
 
 static void
@@ -333,21 +348,11 @@ static void
 ravenscar_inferior_created (struct target_ops *target, int from_tty)
 {
   if (ravenscar_task_support
-      && has_ravenscar_runtime ())
+      && has_ravenscar_runtime ()
+      && gdbarch_ravenscar_ops (current_inferior()->gdbarch) != NULL)
     ravenscar_initialize (NULL, 0);
 }
 
-void
-ravenscar_register_arch_ops (struct ravenscar_arch_ops *ops)
-{
-  /* FIXME: To be clean, we would need to handle a list of
-     architectures, just like in remote-wtx-hw.c.  However, for now the
-     only Ravenscar run-time for bare board that is implemented in
-     GNAT is for only one architecture: erc32-elf.  So no need to care about
-     that for now...  */
-  current_arch_ops = ops;
-}
-
 /* Initialize Ravenscar support.  */
 
 static void
diff --git a/gdb/ravenscar-sparc-thread.h b/gdb/ravenscar-sparc-thread.h
new file mode 100644
index 0000000..dce7c4d
--- /dev/null
+++ b/gdb/ravenscar-sparc-thread.h
@@ -0,0 +1,7 @@
+#ifndef RAVENSCAR_SPARC_THREAD_H
+#define RAVENSCAR_SPARC_THREAD_H
+
+struct gdbarch;
+
+extern void register_sparc_ravenscar_ops (struct gdbarch *gdbarch);
+#endif
diff --git a/gdb/ravenscar-sparc-thread.c b/gdb/ravenscar-sparc-thread.c
index 2a27a63..b7d6aac 100644
--- a/gdb/ravenscar-sparc-thread.c
+++ b/gdb/ravenscar-sparc-thread.c
@@ -23,8 +23,7 @@
 #include "sparc-tdep.h"
 #include "inferior.h"
 #include "ravenscar-thread.h"
-
-static struct ravenscar_arch_ops ravenscar_sparc_ops;
+#include "ravenscar-sparc-thread.h"
 
 static void ravenscar_sparc_fetch_registers (struct regcache *regcache,
                                              int regnum);
@@ -179,14 +178,15 @@ ravenscar_sparc_store_registers (struct regcache *regcache, int regnum)
                 buf_size);
 }
 
-/* Provide a prototype to silence -Wmissing-prototypes.  */
-extern void _initialize_ravenscar_sparc (void);
+static struct ravenscar_arch_ops ravenscar_sparc_ops =
+{
+  ravenscar_sparc_fetch_registers,
+  ravenscar_sparc_store_registers,
+  ravenscar_sparc_prepare_to_store
+};
 
 void
-_initialize_ravenscar_sparc (void)
+register_sparc_ravenscar_ops (struct gdbarch *gdbarch)
 {
-  ravenscar_sparc_ops.to_fetch_registers = ravenscar_sparc_fetch_registers;
-  ravenscar_sparc_ops.to_store_registers = ravenscar_sparc_store_registers;
-  ravenscar_sparc_ops.to_prepare_to_store = ravenscar_sparc_prepare_to_store;
-  ravenscar_register_arch_ops (&ravenscar_sparc_ops);
+  set_gdbarch_ravenscar_ops (gdbarch, &ravenscar_sparc_ops);
 }
diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c
index 3164ed3..7dfa7da 100644
--- a/gdb/sparc-tdep.c
+++ b/gdb/sparc-tdep.c
@@ -39,6 +39,7 @@
 #include "gdb_string.h"
 
 #include "sparc-tdep.h"
+#include "ravenscar-sparc-thread.h"
 
 struct regset;
 
@@ -1683,6 +1684,8 @@ sparc32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     set_gdbarch_regset_from_core_section (gdbarch,
 					  sparc_regset_from_core_section);
 
+  register_sparc_ravenscar_ops (gdbarch);
+
   return gdbarch;
 }
 
-- 
1.7.10.4


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]