[1/2] gdb, gdbarch, infcall: Add value_arg_coerce method to gdbarch.

Message ID 20230322171352.9087-2-mohamed.bouhaouel@intel.com
State New
Headers
Series Add more flexibility to inferior call |

Commit Message

Bouhaouel, Mohamed March 22, 2023, 5:13 p.m. UTC
  Change the 'value_arg_coerce' function from a static common method to a
target-dependent method.

Signed-off-by: Mohamed Bouhaouel <mohamed.bouhaouel@intel.com>
---
 gdb/gdbarch-gen.h         |  7 +++++++
 gdb/gdbarch.c             | 22 ++++++++++++++++++++++
 gdb/gdbarch.h             |  1 +
 gdb/gdbarch_components.py | 16 ++++++++++++++++
 gdb/infcall.c             | 16 ++++++----------
 gdb/infcall.h             |  8 ++++++++
 6 files changed, 60 insertions(+), 10 deletions(-)
  

Comments

Simon Marchi March 22, 2023, 7:18 p.m. UTC | #1
On 3/22/23 13:13, Mohamed Bouhaouel via Gdb-patches wrote:
> Change the 'value_arg_coerce' function from a static common method to a
> target-dependent method.

Just a note to use "arch" instead of target.  Target, inside GDB,
usually means target_ops.  Using the right term will avoid confusion.

Simon
  

Patch

diff --git a/gdb/gdbarch-gen.h b/gdb/gdbarch-gen.h
index 76d12a15317..a9b0fe26837 100644
--- a/gdb/gdbarch-gen.h
+++ b/gdb/gdbarch-gen.h
@@ -319,6 +319,13 @@  typedef struct frame_id (gdbarch_dummy_id_ftype) (struct gdbarch *gdbarch, frame
 extern struct frame_id gdbarch_dummy_id (struct gdbarch *gdbarch, frame_info_ptr this_frame);
 extern void set_gdbarch_dummy_id (struct gdbarch *gdbarch, gdbarch_dummy_id_ftype *dummy_id);
 
+/* Perform the standard coercions that are specified for arguments to
+   be passed to C, Ada or Fortran functions. */
+
+typedef value * (gdbarch_value_arg_coerce_ftype) (struct gdbarch *gdbarch, value *arg, type *param_type, int is_prototyped);
+extern value * gdbarch_value_arg_coerce (struct gdbarch *gdbarch, value *arg, type *param_type, int is_prototyped);
+extern void set_gdbarch_value_arg_coerce (struct gdbarch *gdbarch, gdbarch_value_arg_coerce_ftype *value_arg_coerce);
+
 /* Implement DUMMY_ID and PUSH_DUMMY_CALL, then delete
    deprecated_fp_regnum. */
 
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index b4763aa6bf4..a411e5bbac7 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -91,6 +91,7 @@  struct gdbarch
   gdbarch_register_name_ftype *register_name = nullptr;
   gdbarch_register_type_ftype *register_type = nullptr;
   gdbarch_dummy_id_ftype *dummy_id = default_dummy_id;
+  gdbarch_value_arg_coerce_ftype *value_arg_coerce = default_value_arg_coerce;
   int deprecated_fp_regnum = -1;
   gdbarch_push_dummy_call_ftype *push_dummy_call = nullptr;
   enum call_dummy_location_type call_dummy_location = AT_ENTRY_POINT;
@@ -346,6 +347,7 @@  verify_gdbarch (struct gdbarch *gdbarch)
   if (gdbarch->register_type == 0)
     log.puts ("\n\tregister_type");
   /* Skip verify of dummy_id, invalid_p == 0 */
+  /* Skip verify of value_arg_coerce, invalid_p == 0 */
   /* Skip verify of deprecated_fp_regnum, invalid_p == 0 */
   /* Skip verify of push_dummy_call, has predicate.  */
   /* Skip verify of call_dummy_location, invalid_p == 0 */
@@ -703,6 +705,9 @@  gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
   gdb_printf (file,
 	      "gdbarch_dump: dummy_id = <%s>\n",
 	      host_address_to_string (gdbarch->dummy_id));
+  gdb_printf (file,
+	      "gdbarch_dump: value_arg_coerce = <%s>\n",
+	      host_address_to_string (gdbarch->value_arg_coerce));
   gdb_printf (file,
 	      "gdbarch_dump: deprecated_fp_regnum = %s\n",
 	      plongest (gdbarch->deprecated_fp_regnum));
@@ -2203,6 +2208,23 @@  set_gdbarch_dummy_id (struct gdbarch *gdbarch,
   gdbarch->dummy_id = dummy_id;
 }
 
+value *
+gdbarch_value_arg_coerce (struct gdbarch *gdbarch, value *arg, type *param_type, int is_prototyped)
+{
+  gdb_assert (gdbarch != NULL);
+  gdb_assert (gdbarch->value_arg_coerce != NULL);
+  if (gdbarch_debug >= 2)
+    gdb_printf (gdb_stdlog, "gdbarch_value_arg_coerce called\n");
+  return gdbarch->value_arg_coerce (gdbarch, arg, param_type, is_prototyped);
+}
+
+void
+set_gdbarch_value_arg_coerce (struct gdbarch *gdbarch,
+			      gdbarch_value_arg_coerce_ftype value_arg_coerce)
+{
+  gdbarch->value_arg_coerce = value_arg_coerce;
+}
+
 int
 gdbarch_deprecated_fp_regnum (struct gdbarch *gdbarch)
 {
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index f0399c2fa88..cd0bcd1a6fe 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -25,6 +25,7 @@ 
 #include "frame.h"
 #include "dis-asm.h"
 #include "gdbsupport/gdb_obstack.h"
+#include "infcall.h"
 #include "infrun.h"
 #include "osabi.h"
 #include "displaced-stepping.h"
diff --git a/gdb/gdbarch_components.py b/gdb/gdbarch_components.py
index 92c501d2a72..10e8c2d52c8 100644
--- a/gdb/gdbarch_components.py
+++ b/gdb/gdbarch_components.py
@@ -606,6 +606,22 @@  frame.
     invalid=False,
 )
 
+Method(
+    comment="""
+Perform the standard coercions that are specified for arguments to
+be passed to C, Ada or Fortran functions.
+""",
+    type="value *",
+    name="value_arg_coerce",
+    params=[
+        ("value *", "arg"),
+        ("type *", "param_type"),
+        ("int", "is_prototyped")
+    ],
+    predefault="default_value_arg_coerce",
+    invalid=False,
+)
+
 Value(
     comment="""
 Implement DUMMY_ID and PUSH_DUMMY_CALL, then delete
diff --git a/gdb/infcall.c b/gdb/infcall.c
index 9ed17bf4f8b..b945adebc93 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -170,15 +170,11 @@  show_unwind_on_terminating_exception_p (struct ui_file *file, int from_tty,
 	      value);
 }
 
-/* Perform the standard coercions that are specified
-   for arguments to be passed to C, Ada or Fortran functions.
-
-   If PARAM_TYPE is non-NULL, it is the expected parameter type.
-   IS_PROTOTYPED is non-zero if the function declaration is prototyped.  */
+/* See infcall.h.  */
 
-static struct value *
-value_arg_coerce (struct gdbarch *gdbarch, struct value *arg,
-		  struct type *param_type, int is_prototyped)
+value *
+default_value_arg_coerce (gdbarch *gdbarch, value *arg,
+			  type *param_type, int is_prototyped)
 {
   const struct builtin_type *builtin = builtin_type (gdbarch);
   struct type *arg_type = check_typedef (arg->type ());
@@ -1099,8 +1095,8 @@  call_function_by_hand_dummy (struct value *function,
 	param_type = NULL;
 
       value *original_arg = args[i];
-      args[i] = value_arg_coerce (gdbarch, args[i],
-				  param_type, prototyped);
+      args[i] = gdbarch_value_arg_coerce (gdbarch, args[i],
+					  param_type, prototyped);
 
       if (param_type == NULL)
 	continue;
diff --git a/gdb/infcall.h b/gdb/infcall.h
index 81b0c8d3433..af3dd49220a 100644
--- a/gdb/infcall.h
+++ b/gdb/infcall.h
@@ -71,4 +71,12 @@  extern struct value *
 
 extern void error_call_unknown_return_type (const char *func_name);
 
+/* Perform the standard coercions that are specified
+   for arguments to be passed to C, Ada or Fortran functions.
+
+   If PARAM_TYPE is non-NULL, it is the expected parameter type.
+   IS_PROTOTYPED is non-zero if the function declaration is prototyped.  */
+
+extern value *default_value_arg_coerce (gdbarch *gdbarch, value *arg,
+					type *param_type, int is_prototyped);
 #endif