public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM]  archer-sergiodj-stap-patch-split: Fixing s390 bugs
@ 2011-08-16 21:03 sergiodj
  0 siblings, 0 replies; only message in thread
From: sergiodj @ 2011-08-16 21:03 UTC (permalink / raw)
  To: archer-commits

The branch, archer-sergiodj-stap-patch-split has been updated
       via  88feabea63518c3787d961e540ed360ea08c9b65 (commit)
       via  00b2479c328bf123561481bbabf6539e592a4bc9 (commit)
       via  8d941663e93208d31ccaaa9cdf446e5c2736aabb (commit)
       via  77f3103d0850aee1b8c165158465b71616fd94bf (commit)
      from  3ff643cb982ccadefb22d016e6937d1df4cda677 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit 88feabea63518c3787d961e540ed360ea08c9b65
Author: Sergio Durigan Junior <sergiodj@redhat.com>
Date:   Tue Aug 16 18:02:53 2011 -0300

    Fixing s390 bugs

commit 00b2479c328bf123561481bbabf6539e592a4bc9
Author: Sergio Durigan Junior <sergiodj@redhat.com>
Date:   Mon Aug 15 20:03:09 2011 -0300

    Fixing s390 bugs

commit 8d941663e93208d31ccaaa9cdf446e5c2736aabb
Author: Sergio Durigan Junior <sergiodj@redhat.com>
Date:   Mon Aug 15 19:35:38 2011 -0300

    Fixing PPC evaluator.  Implementing s390 methods.

commit 77f3103d0850aee1b8c165158465b71616fd94bf
Author: Sergio Durigan Junior <sergiodj@redhat.com>
Date:   Sun Aug 14 23:14:43 2011 -0300

    Fixing bug by implementing the gdbarch-specific parsing and evaluation
    of probe args.

-----------------------------------------------------------------------

Summary of changes:
 gdb/amd64-linux-tdep.c |    8 +
 gdb/elfread.c          |    2 +
 gdb/gdbarch.c          |  132 ++++++++++++
 gdb/gdbarch.h          |   50 +++++
 gdb/gdbarch.sh         |   31 +++
 gdb/i386-linux-tdep.c  |    8 +
 gdb/i386-tdep.c        |  518 ++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/i386-tdep.h        |   17 ++
 gdb/ppc-linux-tdep.c   |  431 ++++++++++++++++++++++++++++++++++++++++
 gdb/s390-tdep.c        |  467 +++++++++++++++++++++++++++++++++++++++++++
 gdb/stap-probe.c       |  373 +++++++++++++++++++++++------------
 gdb/stap-probe.h       |   87 ++++++++-
 12 files changed, 1995 insertions(+), 129 deletions(-)

First 500 lines of diff:
diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c
index 0119838..4e7a123 100644
--- a/gdb/amd64-linux-tdep.c
+++ b/gdb/amd64-linux-tdep.c
@@ -1363,6 +1363,14 @@ amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_process_record (gdbarch, i386_process_record);
   set_gdbarch_process_record_signal (gdbarch, amd64_linux_record_signal);
 
+  /* SystemTap functions.  */
+  set_gdbarch_stap_parse_arg (gdbarch, i386_stap_parse_arg);
+  set_gdbarch_stap_is_single_operand (gdbarch, i386_stap_is_single_operand);
+  set_gdbarch_stap_evaluate_single_operand (gdbarch,
+					    i386_stap_evaluate_single_operand);
+  set_gdbarch_stap_fetch_register_value (gdbarch,
+					 i386_stap_fetch_register_value);
+
   /* Initialize the amd64_linux_record_tdep.  */
   /* These values are the size of the type that will be used in a system
      call.  They are obtained from Linux Kernel source.  */
diff --git a/gdb/elfread.c b/gdb/elfread.c
index e9fb66f..b9cdc66 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -1600,6 +1600,8 @@ handle_probe (struct objfile *objfile, struct sdt_note *el,
   struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
   CORE_ADDR base_ref;
 
+  ret->gdbarch = gdbarch;
+
   /* Provider and the name of the probe.  */
   ret->provider = (const char *) &el->data[3 * size];
   ret->name = memchr (ret->provider, '\0',
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index 600cce6..cf02481 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -262,6 +262,10 @@ struct gdbarch
   gdbarch_get_siginfo_type_ftype *get_siginfo_type;
   gdbarch_record_special_symbol_ftype *record_special_symbol;
   gdbarch_get_syscall_number_ftype *get_syscall_number;
+  gdbarch_stap_parse_arg_ftype *stap_parse_arg;
+  gdbarch_stap_is_single_operand_ftype *stap_is_single_operand;
+  gdbarch_stap_evaluate_single_operand_ftype *stap_evaluate_single_operand;
+  gdbarch_stap_fetch_register_value_ftype *stap_fetch_register_value;
   int has_global_solist;
   int has_global_breakpoints;
   gdbarch_has_shared_address_space_ftype *has_shared_address_space;
@@ -415,6 +419,10 @@ struct gdbarch startup_gdbarch =
   0,  /* get_siginfo_type */
   0,  /* record_special_symbol */
   0,  /* get_syscall_number */
+  0,  /* stap_parse_arg */
+  0,  /* stap_is_single_operand */
+  0,  /* stap_evaluate_single_operand */
+  0,  /* stap_fetch_register_value */
   0,  /* has_global_solist */
   0,  /* has_global_breakpoints */
   default_has_shared_address_space,  /* has_shared_address_space */
@@ -700,6 +708,10 @@ verify_gdbarch (struct gdbarch *gdbarch)
   /* Skip verify of get_siginfo_type, has predicate.  */
   /* Skip verify of record_special_symbol, has predicate.  */
   /* Skip verify of get_syscall_number, has predicate.  */
+  /* Skip verify of stap_parse_arg, has predicate.  */
+  /* Skip verify of stap_is_single_operand, has predicate.  */
+  /* Skip verify of stap_evaluate_single_operand, has predicate.  */
+  /* Skip verify of stap_fetch_register_value, has predicate.  */
   /* Skip verify of has_global_solist, invalid_p == 0 */
   /* Skip verify of has_global_breakpoints, invalid_p == 0 */
   /* Skip verify of has_shared_address_space, invalid_p == 0 */
@@ -1226,6 +1238,30 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
                       "gdbarch_dump: stabs_argument_has_addr = <%s>\n",
                       host_address_to_string (gdbarch->stabs_argument_has_addr));
   fprintf_unfiltered (file,
+                      "gdbarch_dump: gdbarch_stap_evaluate_single_operand_p() = %d\n",
+                      gdbarch_stap_evaluate_single_operand_p (gdbarch));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: stap_evaluate_single_operand = <%s>\n",
+                      host_address_to_string (gdbarch->stap_evaluate_single_operand));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: gdbarch_stap_fetch_register_value_p() = %d\n",
+                      gdbarch_stap_fetch_register_value_p (gdbarch));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: stap_fetch_register_value = <%s>\n",
+                      host_address_to_string (gdbarch->stap_fetch_register_value));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: gdbarch_stap_is_single_operand_p() = %d\n",
+                      gdbarch_stap_is_single_operand_p (gdbarch));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: stap_is_single_operand = <%s>\n",
+                      host_address_to_string (gdbarch->stap_is_single_operand));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: gdbarch_stap_parse_arg_p() = %d\n",
+                      gdbarch_stap_parse_arg_p (gdbarch));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: stap_parse_arg = <%s>\n",
+                      host_address_to_string (gdbarch->stap_parse_arg));
+  fprintf_unfiltered (file,
                       "gdbarch_dump: gdbarch_static_transform_name_p() = %d\n",
                       gdbarch_static_transform_name_p (gdbarch));
   fprintf_unfiltered (file,
@@ -3729,6 +3765,102 @@ set_gdbarch_get_syscall_number (struct gdbarch *gdbarch,
 }
 
 int
+gdbarch_stap_parse_arg_p (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  return gdbarch->stap_parse_arg != NULL;
+}
+
+int
+gdbarch_stap_parse_arg (struct gdbarch *gdbarch, const char **arg)
+{
+  gdb_assert (gdbarch != NULL);
+  gdb_assert (gdbarch->stap_parse_arg != NULL);
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_parse_arg called\n");
+  return gdbarch->stap_parse_arg (gdbarch, arg);
+}
+
+void
+set_gdbarch_stap_parse_arg (struct gdbarch *gdbarch,
+                            gdbarch_stap_parse_arg_ftype stap_parse_arg)
+{
+  gdbarch->stap_parse_arg = stap_parse_arg;
+}
+
+int
+gdbarch_stap_is_single_operand_p (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  return gdbarch->stap_is_single_operand != NULL;
+}
+
+int
+gdbarch_stap_is_single_operand (struct gdbarch *gdbarch, const char *s)
+{
+  gdb_assert (gdbarch != NULL);
+  gdb_assert (gdbarch->stap_is_single_operand != NULL);
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_is_single_operand called\n");
+  return gdbarch->stap_is_single_operand (gdbarch, s);
+}
+
+void
+set_gdbarch_stap_is_single_operand (struct gdbarch *gdbarch,
+                                    gdbarch_stap_is_single_operand_ftype stap_is_single_operand)
+{
+  gdbarch->stap_is_single_operand = stap_is_single_operand;
+}
+
+int
+gdbarch_stap_evaluate_single_operand_p (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  return gdbarch->stap_evaluate_single_operand != NULL;
+}
+
+struct value *
+gdbarch_stap_evaluate_single_operand (struct gdbarch *gdbarch, struct stap_evaluation_info *eval_info)
+{
+  gdb_assert (gdbarch != NULL);
+  gdb_assert (gdbarch->stap_evaluate_single_operand != NULL);
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_evaluate_single_operand called\n");
+  return gdbarch->stap_evaluate_single_operand (gdbarch, eval_info);
+}
+
+void
+set_gdbarch_stap_evaluate_single_operand (struct gdbarch *gdbarch,
+                                          gdbarch_stap_evaluate_single_operand_ftype stap_evaluate_single_operand)
+{
+  gdbarch->stap_evaluate_single_operand = stap_evaluate_single_operand;
+}
+
+int
+gdbarch_stap_fetch_register_value_p (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  return gdbarch->stap_fetch_register_value != NULL;
+}
+
+struct value *
+gdbarch_stap_fetch_register_value (struct gdbarch *gdbarch, struct stap_evaluation_info *eval_info, int displacement_p, int *indirect_p)
+{
+  gdb_assert (gdbarch != NULL);
+  gdb_assert (gdbarch->stap_fetch_register_value != NULL);
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_fetch_register_value called\n");
+  return gdbarch->stap_fetch_register_value (gdbarch, eval_info, displacement_p, indirect_p);
+}
+
+void
+set_gdbarch_stap_fetch_register_value (struct gdbarch *gdbarch,
+                                       gdbarch_stap_fetch_register_value_ftype stap_fetch_register_value)
+{
+  gdbarch->stap_fetch_register_value = stap_fetch_register_value;
+}
+
+int
 gdbarch_has_global_solist (struct gdbarch *gdbarch)
 {
   gdb_assert (gdbarch != NULL);
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index 7619581..2aff78d 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -54,6 +54,7 @@ struct displaced_step_closure;
 struct core_regset_section;
 struct syscall;
 struct agent_expr;
+struct stap_evaluation_info;
 
 /* The architecture associated with the connection to the target.
  
@@ -956,6 +957,55 @@ typedef LONGEST (gdbarch_get_syscall_number_ftype) (struct gdbarch *gdbarch, pti
 extern LONGEST gdbarch_get_syscall_number (struct gdbarch *gdbarch, ptid_t ptid);
 extern void set_gdbarch_get_syscall_number (struct gdbarch *gdbarch, gdbarch_get_syscall_number_ftype *get_syscall_number);
 
+/* SystemTap related functions.
+   Parse a SystemTap probe's argument. */
+
+extern int gdbarch_stap_parse_arg_p (struct gdbarch *gdbarch);
+
+typedef int (gdbarch_stap_parse_arg_ftype) (struct gdbarch *gdbarch, const char **arg);
+extern int gdbarch_stap_parse_arg (struct gdbarch *gdbarch, const char **arg);
+extern void set_gdbarch_stap_parse_arg (struct gdbarch *gdbarch, gdbarch_stap_parse_arg_ftype *stap_parse_arg);
+
+/* Check if S is a single operand.
+  
+   Single operands can be:
+    - Literal integers, e.g. `$10' on x86
+    - Register access, e.g. `%eax' on x86
+    - Register indirection, e.g. `(%eax)' on x86
+    - Register displacement, e.g. `4(%eax)' on x86
+  
+   This function should check for these patterns on the string
+   and return 1 if some were found, or zero otherwise. */
+
+extern int gdbarch_stap_is_single_operand_p (struct gdbarch *gdbarch);
+
+typedef int (gdbarch_stap_is_single_operand_ftype) (struct gdbarch *gdbarch, const char *s);
+extern int gdbarch_stap_is_single_operand (struct gdbarch *gdbarch, const char *s);
+extern void set_gdbarch_stap_is_single_operand (struct gdbarch *gdbarch, gdbarch_stap_is_single_operand_ftype *stap_is_single_operand);
+
+/* Evaluate a single operand.
+  
+   Single operands can be:
+  
+    - unary operators `-' and `~'
+    - integer constants
+    - register access, with or without displacement and indirection */
+
+extern int gdbarch_stap_evaluate_single_operand_p (struct gdbarch *gdbarch);
+
+typedef struct value * (gdbarch_stap_evaluate_single_operand_ftype) (struct gdbarch *gdbarch, struct stap_evaluation_info *eval_info);
+extern struct value * gdbarch_stap_evaluate_single_operand (struct gdbarch *gdbarch, struct stap_evaluation_info *eval_info);
+extern void set_gdbarch_stap_evaluate_single_operand (struct gdbarch *gdbarch, gdbarch_stap_evaluate_single_operand_ftype *stap_evaluate_single_operand);
+
+/* Fetch the value of the register whose name starts in the expression
+   buffer. */
+
+extern int gdbarch_stap_fetch_register_value_p (struct gdbarch *gdbarch);
+
+typedef struct value * (gdbarch_stap_fetch_register_value_ftype) (struct gdbarch *gdbarch, struct stap_evaluation_info *eval_info, int displacement_p, int *indirect_p);
+extern struct value * gdbarch_stap_fetch_register_value (struct gdbarch *gdbarch, struct stap_evaluation_info *eval_info, int displacement_p, int *indirect_p);
+extern void set_gdbarch_stap_fetch_register_value (struct gdbarch *gdbarch, gdbarch_stap_fetch_register_value_ftype *stap_fetch_register_value);
+
 /* True if the list of shared libraries is one and only for all
    processes, as opposed to a list of shared libraries per inferior.
    This usually means that all processes, although may or may not share
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index 61094fb..60b6c25 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -784,6 +784,36 @@ M:void:record_special_symbol:struct objfile *objfile, asymbol *sym:objfile, sym
 # Get architecture-specific system calls information from registers.
 M:LONGEST:get_syscall_number:ptid_t ptid:ptid
 
+# SystemTap related functions.
+
+# Parse a SystemTap probe's argument.
+M:int:stap_parse_arg:const char **arg:arg
+
+# Check if S is a single operand.
+#
+# Single operands can be:
+#  \- Literal integers, e.g. \`\$10\' on x86
+#  \- Register access, e.g. \`\%eax\' on x86
+#  \- Register indirection, e.g. \`\(\%eax\)\' on x86
+#  \- Register displacement, e.g. \`4\(\%eax\)\' on x86
+#
+# This function should check for these patterns on the string
+# and return 1 if some were found, or zero otherwise.
+M:int:stap_is_single_operand:const char *s:s
+
+# Evaluate a single operand.
+#
+# Single operands can be:
+#
+#  \- unary operators \`\-\' and \`\~\'
+#  \- integer constants
+#  \- register access, with or without displacement and indirection
+M:struct value *:stap_evaluate_single_operand:struct stap_evaluation_info *eval_info:eval_info
+
+# Fetch the value of the register whose name starts in the expression
+# buffer.
+M:struct value *:stap_fetch_register_value:struct stap_evaluation_info *eval_info, int displacement_p, int *indirect_p:eval_info, displacement_p, indirect_p
+
 # True if the list of shared libraries is one and only for all
 # processes, as opposed to a list of shared libraries per inferior.
 # This usually means that all processes, although may or may not share
@@ -934,6 +964,7 @@ struct displaced_step_closure;
 struct core_regset_section;
 struct syscall;
 struct agent_expr;
+struct stap_evaluation_info;
 
 /* The architecture associated with the connection to the target.
  
diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c
index 7c3962e..0193346 100644
--- a/gdb/i386-linux-tdep.c
+++ b/gdb/i386-linux-tdep.c
@@ -904,6 +904,14 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
                                   i386_linux_get_syscall_number);
 
   set_gdbarch_get_siginfo_type (gdbarch, linux_get_siginfo_type);
+
+  /* SystemTap functions.  */
+  set_gdbarch_stap_parse_arg (gdbarch, i386_stap_parse_arg);
+  set_gdbarch_stap_is_single_operand (gdbarch, i386_stap_is_single_operand);
+  set_gdbarch_stap_evaluate_single_operand (gdbarch,
+					    i386_stap_evaluate_single_operand);
+  set_gdbarch_stap_fetch_register_value (gdbarch,
+					 i386_stap_fetch_register_value);
 }
 
 /* Provide a prototype to silence -Wmissing-prototypes.  */
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 5fb2efb..5f64519 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -60,6 +60,13 @@
 #include "features/i386/i386-avx.c"
 #include "features/i386/i386-mmx.c"
 
+#include "stap-probe.h"
+#include "ax.h"
+#include "ax-gdb.h"
+#include "user-regs.h"
+#include "cli/cli-utils.h"
+#include <ctype.h>
+
 /* Register names.  */
 
 static const char *i386_register_names[] =
@@ -7196,6 +7203,517 @@ i386_validate_tdesc_p (struct gdbarch_tdep *tdep,
   return valid_p;
 }
 
+/* Parse SystemTap probe's argument.  */
+
+int
+i386_stap_parse_arg (struct gdbarch *gdbarch, const char **arg)
+{
+  char *cur = (char *) *arg;
+  int done = 0;
+  int paren_open = 0;
+
+  while (!done)
+    {
+      switch (*cur)
+	{
+	case ' ': case '\0':
+	  /* If we're here, then we have already parsed everything
+	     from this argument.  */
+	  if (paren_open)
+	    return 0;
+	  done = 1;
+	  break;
+
+	case '(':
+	  ++paren_open;
+	  ++cur;
+	  cur = skip_spaces (cur);
+	  break;
+
+	case ')':
+	  if (!paren_open)
+	    return 0;
+
+	  --paren_open;
+	  ++cur;
+	  if (paren_open)
+	    cur = skip_spaces (cur);
+	  break;
+
+	case '[':
+	case 'i':
+	  /* Invalid char.  */
+	  return 0;
+
+	case '+': case '-':
+	case '*': case '/':
+	case '>': case '<':
+	case '|': case '&':
+	case '^': case '!':
+	    {
+	      char c = *cur;
+
+	      ++cur;
+	      switch (*cur)
+		{
+		case '>':
+		  if (c != '<' && c != '>')
+		    return 0;
+
+		  ++cur;
+		  break;
+
+		case '<':
+		  if (c != '<')
+		    return 0;
+
+		  ++cur;
+		  break;
+
+		case '=':
+		  if (c != '=' && c != '<' && c != '>' && c != '!')
+		    return 0;
+
+		  ++cur;
+		  break;
+
+		case '|':
+		  if (c != '|')
+		    return 0;
+
+		  ++cur;
+		  break;
+
+		case '&':
+		  if (c != '&')
+		    return 0;
+
+		  ++cur;
+		  break;
+
+		default:
+		  break;
+		}
+	      /* Infix operators take two arguments, one on either
+		 side.  Skipping the whitespaces that may happen on the
+		 right side.  */
+	      if (paren_open)
+		cur = skip_spaces (cur);
+	    }
+	  break;
+
+	case '%':
+	    {
+	      ++cur;
+	      if (*cur >= 'a' && *cur <= 'z')
+		{
+		  /* We're dealing with a register name, x86{,_64}.  */
+		  while (isalnum (*cur))
+		    ++cur;
+
+		  /* Some registers (e.g. floating-point register stack
+		     registers on Intel i386) have the following syntax:
+
+		     `%st(0)', `%st(1)', and so on.
+
+		     So it's ok to expect parenthesis here.  */
+		  if (*cur == '(')
+		    {
+		      ++cur;
+		      cur = skip_spaces (cur);
+
+		      if (!isdigit (*cur))
+			/* This is an error, since we only expect numbers
+			   inside this parenthesis.  */
+			return 0;
+		      ++cur;
+
+		      cur = skip_spaces (cur);
+
+		      /* We only expect one number.  */
+		      if (*cur++ != ')')
+			return 0;
+
+		      if (paren_open)
+			cur = skip_spaces (cur);
+		    }
+		}
+	    }
+	  break;
+
+	case '$':


hooks/post-receive
--
Repository for Project Archer.


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2011-08-16 21:03 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-16 21:03 [SCM] archer-sergiodj-stap-patch-split: Fixing s390 bugs sergiodj

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).