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]

[PATCH] Improve readability of x86's SystemTap SDT probe support & fix bug & add testcase


Hi,

This patch reorganizes code on gdb/i386-tdep.c's SystemTap SDT probe
support functions.  Before it, the code to parse special operands on x86
lived in a single, big function.  This patch creates 2 new functions
that makes the code more organized and removes a few indentation levels
(which is always good IMO).

While I was making the patch, I decided to create some testcases for it
(by tweaking the probe's asm generated by GCC), and found a bug on the
parsing code for the triplet displacement operand (i.e., things like
"-4+8-20(%rbp)").  Well, since I was already at it, I created some
testcases for the two kinds of special operands handled by the code (the
triplet displacement mentioned above, and the three-argument
displacement like "(%rbx,%ebx,-8)").  This code is target-dependent so I
created it under gdb.arch/.

Comments?  OK to apply?

Thanks,

-- 
Sergio

gdb/ChangeLog
2013-12-27  Sergio Durigan Junior  <sergiodj@redhat.com>

	* i386-tdep.c (i386_stap_parse_special_token_triplet): New
	function, with code from i386_stap_parse_special_token.  Fix bug
	with the parsing of triplet displacement.
	(i386_stap_parse_special_token_three_arg_disp): New function, with
	code from i386_stap_parse_special_token.
	(i386_stap_parse_special_token): Move code to the two functions
	created above.

gdb/testsuite/ChangeLog
2013-12-27  Sergio Durigan Junior  <sergiodj@redhat.com>

	* gdb.arch/amd64-stap-special-operands.exp: New file.
	* gdb.arch/amd64-stap-three-arg-disp.S: Likewise.
	* gdb.arch/amd64-stap-three-arg-disp.c: Likewise.
	* gdb.arch/amd64-stap-triplet.S: Likewise.
	* gdb.arch/amd64-stap-triplet.c: Likewise.

diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 4f86f0c..a4f5dbe 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -3605,311 +3605,334 @@ i386_stap_is_single_operand (struct gdbarch *gdbarch, const char *s)
 	  || (*s == '%' && isalpha (s[1]))); /* Register access.  */
 }
 
-/* Implementation of `gdbarch_stap_parse_special_token', as defined in
-   gdbarch.h.  */
+/* Helper function for i386_stap_parse_special_token.
 
-int
-i386_stap_parse_special_token (struct gdbarch *gdbarch,
-			       struct stap_parse_info *p)
+   This function parses operands of the form `-8+3+1(%rbp)', which
+   must be interpreted as `*(-8 + 3 - 1 + (void *) $eax)'.
+
+   Return 1 if the operand was parsed successfully, zero
+   otherwise.  */
+
+static int
+i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch,
+				       struct stap_parse_info *p)
 {
-  /* In order to parse special tokens, we use a state-machine that go
-     through every known token and try to get a match.  */
-  enum
+  int got_minus[3];
+  int i;
+  LONGEST displacements[3];
+  const char *start;
+  char *regname;
+  int len;
+  struct stoken str;
+  char *endp;
+  const char *s = p->arg;
+
+  /* If we are not dealing with a digit, then just return 0.  */
+  if (!isdigit (*s) && *s != '-' && *s != '+')
+    return 0;
+
+  got_minus[0] = 0;
+  if (*s == '+')
+    ++s;
+  else if (*s == '-')
     {
-      TRIPLET,
-      THREE_ARG_DISPLACEMENT,
-      DONE
-    } current_state;
+      ++s;
+      got_minus[0] = 1;
+    }
 
-  current_state = TRIPLET;
+  if (!isdigit (*s))
+    return 0;
 
-  /* The special tokens to be parsed here are:
+  displacements[0] = strtol (s, &endp, 10);
+  s = endp;
 
-     - `register base + (register index * size) + offset', as represented
-     in `(%rcx,%rax,8)', or `[OFFSET](BASE_REG,INDEX_REG[,SIZE])'.
+  if (*s != '+' && *s != '-')
+    {
+      /* We are not dealing with a triplet.  */
+      return 0;
+    }
 
-     - Operands of the form `-8+3+1(%rbp)', which must be interpreted as
-     `*(-8 + 3 - 1 + (void *) $eax)'.  */
+  got_minus[1] = 0;
+  if (*s == '+')
+    ++s;
+  else
+    {
+      ++s;
+      got_minus[1] = 1;
+    }
 
-  while (current_state != DONE)
+  displacements[1] = strtol (s, &endp, 10);
+  s = endp;
+
+  if (*s != '+' && *s != '-')
     {
-      const char *s = p->arg;
+      /* We are not dealing with a triplet.  */
+      return 0;
+    }
 
-      switch (current_state)
-	{
-	case TRIPLET:
-	    {
-	      if (isdigit (*s) || *s == '-' || *s == '+')
-		{
-		  int got_minus[3];
-		  int i;
-		  long displacements[3];
-		  const char *start;
-		  char *regname;
-		  int len;
-		  struct stoken str;
-		  char *endp;
-
-		  got_minus[0] = 0;
-		  if (*s == '+')
-		    ++s;
-		  else if (*s == '-')
-		    {
-		      ++s;
-		      got_minus[0] = 1;
-		    }
+  got_minus[2] = 0;
+  if (*s == '+')
+    ++s;
+  else
+    {
+      ++s;
+      got_minus[2] = 1;
+    }
 
-		  displacements[0] = strtol (s, &endp, 10);
-		  s = endp;
+  displacements[2] = strtol (s, &endp, 10);
+  s = endp;
 
-		  if (*s != '+' && *s != '-')
-		    {
-		      /* We are not dealing with a triplet.  */
-		      break;
-		    }
+  if (*s != '(' || s[1] != '%')
+    return 0;
 
-		  got_minus[1] = 0;
-		  if (*s == '+')
-		    ++s;
-		  else
-		    {
-		      ++s;
-		      got_minus[1] = 1;
-		    }
+  s += 2;
+  start = s;
 
-		  displacements[1] = strtol (s, &endp, 10);
-		  s = endp;
+  while (isalnum (*s))
+    ++s;
 
-		  if (*s != '+' && *s != '-')
-		    {
-		      /* We are not dealing with a triplet.  */
-		      break;
-		    }
+  if (*s++ != ')')
+    return 0;
 
-		  got_minus[2] = 0;
-		  if (*s == '+')
-		    ++s;
-		  else
-		    {
-		      ++s;
-		      got_minus[2] = 1;
-		    }
+  len = s - start - 1;
+  regname = alloca (len + 1);
 
-		  displacements[2] = strtol (s, &endp, 10);
-		  s = endp;
+  strncpy (regname, start, len);
+  regname[len] = '\0';
 
-		  if (*s != '(' || s[1] != '%')
-		    break;
+  if (user_reg_map_name_to_regnum (gdbarch, regname, len) == -1)
+    error (_("Invalid register name `%s' on expression `%s'."),
+	   regname, p->saved_arg);
 
-		  s += 2;
-		  start = s;
+  for (i = 0; i < 3; i++)
+    {
+      write_exp_elt_opcode (OP_LONG);
+      write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
+      write_exp_elt_longcst (displacements[i]);
+      write_exp_elt_opcode (OP_LONG);
+      if (got_minus[i])
+	write_exp_elt_opcode (UNOP_NEG);
+    }
 
-		  while (isalnum (*s))
-		    ++s;
+  write_exp_elt_opcode (OP_REGISTER);
+  str.ptr = regname;
+  str.length = len;
+  write_exp_string (str);
+  write_exp_elt_opcode (OP_REGISTER);
 
-		  if (*s++ != ')')
-		    break;
+  write_exp_elt_opcode (UNOP_CAST);
+  write_exp_elt_type (builtin_type (gdbarch)->builtin_data_ptr);
+  write_exp_elt_opcode (UNOP_CAST);
 
-		  len = s - start;
-		  regname = alloca (len + 1);
+  write_exp_elt_opcode (BINOP_ADD);
+  write_exp_elt_opcode (BINOP_ADD);
+  write_exp_elt_opcode (BINOP_ADD);
 
-		  strncpy (regname, start, len);
-		  regname[len] = '\0';
+  write_exp_elt_opcode (UNOP_CAST);
+  write_exp_elt_type (lookup_pointer_type (p->arg_type));
+  write_exp_elt_opcode (UNOP_CAST);
 
-		  if (user_reg_map_name_to_regnum (gdbarch,
-						   regname, len) == -1)
-		    error (_("Invalid register name `%s' "
-			     "on expression `%s'."),
-			   regname, p->saved_arg);
+  write_exp_elt_opcode (UNOP_IND);
 
-		  for (i = 0; i < 3; i++)
-		    {
-		      write_exp_elt_opcode (OP_LONG);
-		      write_exp_elt_type
-			(builtin_type (gdbarch)->builtin_long);
-		      write_exp_elt_longcst (displacements[i]);
-		      write_exp_elt_opcode (OP_LONG);
-		      if (got_minus[i])
-			write_exp_elt_opcode (UNOP_NEG);
-		    }
+  p->arg = s;
 
-		  write_exp_elt_opcode (OP_REGISTER);
-		  str.ptr = regname;
-		  str.length = len;
-		  write_exp_string (str);
-		  write_exp_elt_opcode (OP_REGISTER);
+  return 1;
+}
 
-		  write_exp_elt_opcode (UNOP_CAST);
-		  write_exp_elt_type (builtin_type (gdbarch)->builtin_data_ptr);
-		  write_exp_elt_opcode (UNOP_CAST);
+/* Helper function for i386_stap_parse_special_token.
 
-		  write_exp_elt_opcode (BINOP_ADD);
-		  write_exp_elt_opcode (BINOP_ADD);
-		  write_exp_elt_opcode (BINOP_ADD);
+   This function parses operands of the form `register base +
+   (register index * size) + offset', as represented in
+   `(%rcx,%rax,8)', or `[OFFSET](BASE_REG,INDEX_REG[,SIZE])'.
 
-		  write_exp_elt_opcode (UNOP_CAST);
-		  write_exp_elt_type (lookup_pointer_type (p->arg_type));
-		  write_exp_elt_opcode (UNOP_CAST);
+   Return 1 if the operand was parsed successfully, zero
+   otherwise.  */
 
-		  write_exp_elt_opcode (UNOP_IND);
+static int
+i386_stap_parse_special_token_three_arg_disp (struct gdbarch *gdbarch,
+					      struct stap_parse_info *p)
+{
+  int offset_minus = 0;
+  long offset = 0;
+  int size_minus = 0;
+  long size = 0;
+  const char *start;
+  char *base;
+  int len_base;
+  char *index;
+  int len_index;
+  struct stoken base_token, index_token;
+  const char *s = p->arg;
+
+  if (!isdigit (*s) && *s != '(' && *s != '-' && *s != '+')
+    return 0;
 
-		  p->arg = s;
+  if (*s == '+')
+    ++s;
+  else if (*s == '-')
+    {
+      ++s;
+      offset_minus = 1;
+    }
 
-		  return 1;
-		}
-	      break;
-	    }
-	case THREE_ARG_DISPLACEMENT:
-	    {
-	      if (isdigit (*s) || *s == '(' || *s == '-' || *s == '+')
-		{
-		  int offset_minus = 0;
-		  long offset = 0;
-		  int size_minus = 0;
-		  long size = 0;
-		  const char *start;
-		  char *base;
-		  int len_base;
-		  char *index;
-		  int len_index;
-		  struct stoken base_token, index_token;
-
-		  if (*s == '+')
-		    ++s;
-		  else if (*s == '-')
-		    {
-		      ++s;
-		      offset_minus = 1;
-		    }
+  if (offset_minus && !isdigit (*s))
+    return 0;
 
-		  if (offset_minus && !isdigit (*s))
-		    break;
+  if (isdigit (*s))
+    {
+      char *endp;
 
-		  if (isdigit (*s))
-		    {
-		      char *endp;
+      offset = strtol (s, &endp, 10);
+      s = endp;
+    }
 
-		      offset = strtol (s, &endp, 10);
-		      s = endp;
-		    }
+  if (*s != '(' || s[1] != '%')
+    return 0;
 
-		  if (*s != '(' || s[1] != '%')
-		    break;
+  s += 2;
+  start = s;
 
-		  s += 2;
-		  start = s;
+  while (isalnum (*s))
+    ++s;
 
-		  while (isalnum (*s))
-		    ++s;
+  if (*s != ',' || s[1] != '%')
+    return 0;
 
-		  if (*s != ',' || s[1] != '%')
-		    break;
+  len_base = s - start;
+  base = alloca (len_base + 1);
+  strncpy (base, start, len_base);
+  base[len_base] = '\0';
 
-		  len_base = s - start;
-		  base = alloca (len_base + 1);
-		  strncpy (base, start, len_base);
-		  base[len_base] = '\0';
+  if (user_reg_map_name_to_regnum (gdbarch, base, len_base) == -1)
+    error (_("Invalid register name `%s' on expression `%s'."),
+	   base, p->saved_arg);
 
-		  if (user_reg_map_name_to_regnum (gdbarch,
-						   base, len_base) == -1)
-		    error (_("Invalid register name `%s' "
-			     "on expression `%s'."),
-			   base, p->saved_arg);
+  s += 2;
+  start = s;
 
-		  s += 2;
-		  start = s;
+  while (isalnum (*s))
+    ++s;
 
-		  while (isalnum (*s))
-		    ++s;
+  len_index = s - start;
+  index = alloca (len_index + 1);
+  strncpy (index, start, len_index);
+  index[len_index] = '\0';
 
-		  len_index = s - start;
-		  index = alloca (len_index + 1);
-		  strncpy (index, start, len_index);
-		  index[len_index] = '\0';
+  if (user_reg_map_name_to_regnum (gdbarch, index, len_index) == -1)
+    error (_("Invalid register name `%s' on expression `%s'."),
+	   index, p->saved_arg);
 
-		  if (user_reg_map_name_to_regnum (gdbarch,
-						   index, len_index) == -1)
-		    error (_("Invalid register name `%s' "
-			     "on expression `%s'."),
-			   index, p->saved_arg);
+  if (*s != ',' && *s != ')')
+    return 0;
 
-		  if (*s != ',' && *s != ')')
-		    break;
+  if (*s == ',')
+    {
+      char *endp;
 
-		  if (*s == ',')
-		    {
-		      char *endp;
+      ++s;
+      if (*s == '+')
+	++s;
+      else if (*s == '-')
+	{
+	  ++s;
+	  size_minus = 1;
+	}
 
-		      ++s;
-		      if (*s == '+')
-			++s;
-		      else if (*s == '-')
-			{
-			  ++s;
-			  size_minus = 1;
-			}
+      size = strtol (s, &endp, 10);
+      s = endp;
 
-		      size = strtol (s, &endp, 10);
-		      s = endp;
+      if (*s != ')')
+	return 0;
+    }
 
-		      if (*s != ')')
-			break;
-		    }
+  ++s;
 
-		  ++s;
+  if (offset)
+    {
+      write_exp_elt_opcode (OP_LONG);
+      write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
+      write_exp_elt_longcst (offset);
+      write_exp_elt_opcode (OP_LONG);
+      if (offset_minus)
+	write_exp_elt_opcode (UNOP_NEG);
+    }
 
-		  if (offset)
-		    {
-		      write_exp_elt_opcode (OP_LONG);
-		      write_exp_elt_type
-			(builtin_type (gdbarch)->builtin_long);
-		      write_exp_elt_longcst (offset);
-		      write_exp_elt_opcode (OP_LONG);
-		      if (offset_minus)
-			write_exp_elt_opcode (UNOP_NEG);
-		    }
+  write_exp_elt_opcode (OP_REGISTER);
+  base_token.ptr = base;
+  base_token.length = len_base;
+  write_exp_string (base_token);
+  write_exp_elt_opcode (OP_REGISTER);
 
-		  write_exp_elt_opcode (OP_REGISTER);
-		  base_token.ptr = base;
-		  base_token.length = len_base;
-		  write_exp_string (base_token);
-		  write_exp_elt_opcode (OP_REGISTER);
+  if (offset)
+    write_exp_elt_opcode (BINOP_ADD);
 
-		  if (offset)
-		    write_exp_elt_opcode (BINOP_ADD);
+  write_exp_elt_opcode (OP_REGISTER);
+  index_token.ptr = index;
+  index_token.length = len_index;
+  write_exp_string (index_token);
+  write_exp_elt_opcode (OP_REGISTER);
 
-		  write_exp_elt_opcode (OP_REGISTER);
-		  index_token.ptr = index;
-		  index_token.length = len_index;
-		  write_exp_string (index_token);
-		  write_exp_elt_opcode (OP_REGISTER);
+  if (size)
+    {
+      write_exp_elt_opcode (OP_LONG);
+      write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
+      write_exp_elt_longcst (size);
+      write_exp_elt_opcode (OP_LONG);
+      if (size_minus)
+	write_exp_elt_opcode (UNOP_NEG);
+      write_exp_elt_opcode (BINOP_MUL);
+    }
 
-		  if (size)
-		    {
-		      write_exp_elt_opcode (OP_LONG);
-		      write_exp_elt_type
-			(builtin_type (gdbarch)->builtin_long);
-		      write_exp_elt_longcst (size);
-		      write_exp_elt_opcode (OP_LONG);
-		      if (size_minus)
-			write_exp_elt_opcode (UNOP_NEG);
-		      write_exp_elt_opcode (BINOP_MUL);
-		    }
+  write_exp_elt_opcode (BINOP_ADD);
 
-		  write_exp_elt_opcode (BINOP_ADD);
+  write_exp_elt_opcode (UNOP_CAST);
+  write_exp_elt_type (lookup_pointer_type (p->arg_type));
+  write_exp_elt_opcode (UNOP_CAST);
 
-		  write_exp_elt_opcode (UNOP_CAST);
-		  write_exp_elt_type (lookup_pointer_type (p->arg_type));
-		  write_exp_elt_opcode (UNOP_CAST);
+  write_exp_elt_opcode (UNOP_IND);
 
-		  write_exp_elt_opcode (UNOP_IND);
+  p->arg = s;
 
-		  p->arg = s;
+  return 1;
+}
 
-		  return 1;
-		}
-	      break;
-	    }
+/* Implementation of `gdbarch_stap_parse_special_token', as defined in
+   gdbarch.h.  */
+
+int
+i386_stap_parse_special_token (struct gdbarch *gdbarch,
+			       struct stap_parse_info *p)
+{
+  /* In order to parse special tokens, we use a state-machine that go
+     through every known token and try to get a match.  */
+  enum
+    {
+      TRIPLET,
+      THREE_ARG_DISPLACEMENT,
+      DONE
+    } current_state;
+
+  current_state = TRIPLET;
+
+  while (current_state != DONE)
+    {
+      switch (current_state)
+	{
+	case TRIPLET:
+	  {
+	    if (i386_stap_parse_special_token_triplet (gdbarch, p))
+	      return 1;
+
+	    break;
+	  }
+
+	case THREE_ARG_DISPLACEMENT:
+	  {
+	    if (i386_stap_parse_special_token_three_arg_disp (gdbarch, p))
+	      return 1;
+
+	    break;
+	  }
 	}
 
       /* Advancing to the next state.  */
diff --git a/gdb/testsuite/gdb.arch/amd64-stap-special-operands.exp b/gdb/testsuite/gdb.arch/amd64-stap-special-operands.exp
new file mode 100644
index 0000000..a6ce7f5
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/amd64-stap-special-operands.exp
@@ -0,0 +1,47 @@
+# Copyright 2013 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+if { ![istarget "x86_64-*-*"] && ![istarget "i?86-*-*"] } {
+    verbose "Skipping amd64-stap-special-operands.exp"
+    return
+}
+
+proc test_probe { probe_name } {
+    if { ![runto "-pstap $probe_name"] } {
+	fail "run to probe $probe_name"
+	return
+    }
+
+    gdb_test "print \$_probe_argc" " = 1"
+    gdb_test "print \$_probe_arg0" " = 10"
+}
+
+standard_testfile amd64-stap-triplet.S
+
+if { [prepare_for_testing $testfile.exp $testfile $srcfile] } {
+    untested amd64-stap-special-operands.exp
+    return -1
+}
+
+test_probe "triplet"
+
+standard_testfile amd64-stap-three-arg-disp.S
+
+if { [prepare_for_testing $testfile.exp $testfile $srcfile] } {
+    untested amd64-stap-special-operands.exp
+    return -1
+}
+
+test_probe "three_arg"
diff --git a/gdb/testsuite/gdb.arch/amd64-stap-three-arg-disp.S b/gdb/testsuite/gdb.arch/amd64-stap-three-arg-disp.S
new file mode 100644
index 0000000..cf3856f
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/amd64-stap-three-arg-disp.S
@@ -0,0 +1,58 @@
+	.file	"amd64-stap-three-arg-disp.c"
+	.text
+	.globl	main
+	.type	main, @function
+main:
+.LFB0:
+	.cfi_startproc
+# BLOCK 2 seq:0
+# PRED: ENTRY (fallthru)
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset 6, -16
+	movq	%rsp, %rbp
+	.cfi_def_cfa_register 6
+	movl	%edi, -20(%rbp)
+	movq	%rsi, -32(%rbp)
+	movl	$10, -4(%rbp)
+#APP
+# 8 "amd64-stap-three-arg-disp.c" 1
+	990: nop
+.pushsection .note.stapsdt,"?","note"
+.balign 4
+.4byte 992f-991f,994f-993f,3
+991: .asciz "stapsdt"
+992: .balign 4
+993: .8byte 990b
+.8byte _.stapsdt.base
+.8byte 0
+.asciz "test"
+.asciz "three_arg"
+.asciz "-4@-4(%rbp,%ebx,0)"
+994: .balign 4
+.popsection
+
+# 0 "" 2
+# 8 "amd64-stap-three-arg-disp.c" 1
+	.ifndef _.stapsdt.base
+.pushsection .stapsdt.base,"aG","progbits",.stapsdt.base,comdat
+.weak _.stapsdt.base
+.hidden _.stapsdt.base
+_.stapsdt.base: .space 1
+.size _.stapsdt.base,1
+.popsection
+.endif
+
+# 0 "" 2
+#NO_APP
+	movl	$0, %eax
+	movl	$0, %ebx
+	popq	%rbp
+	.cfi_def_cfa 7, 8
+# SUCC: EXIT [100.0%] 
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	main, .-main
+	.ident	"GCC: (GNU) 4.7.2 20120921 (Red Hat 4.7.2-2)"
+	.section	.note.GNU-stack,"",@progbits
diff --git a/gdb/testsuite/gdb.arch/amd64-stap-three-arg-disp.c b/gdb/testsuite/gdb.arch/amd64-stap-three-arg-disp.c
new file mode 100644
index 0000000..f32d495
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/amd64-stap-three-arg-disp.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 2013 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+   This file is not used directly.  Please, see the equivalent .S file
+   for more details.  */
+
+#include <sys/sdt.h>
+
+int
+main (int argc, char *argv[])
+{
+  int a = 10;
+
+  STAP_PROBE1 (test, three_arg, a);
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.arch/amd64-stap-triplet.S b/gdb/testsuite/gdb.arch/amd64-stap-triplet.S
new file mode 100644
index 0000000..f3a6bf7
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/amd64-stap-triplet.S
@@ -0,0 +1,88 @@
+/* Copyright (C) 2013 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+   This file was generated from the equivalent .c file using the
+   following command:
+
+     #> gcc -S amd64-stap-triplet.c -o amd64-stap-triplet.S
+
+   Then, the SystemTap SDT probe definition below was tweaked.  See below
+   for more details.  */
+
+	.file	"amd64-stap-triplet.c"
+	.text
+	.globl	main
+	.type	main, @function
+main:
+.LFB0:
+	.cfi_startproc
+# BLOCK 2 seq:0
+# PRED: ENTRY (fallthru)
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset 6, -16
+	movq	%rsp, %rbp
+	.cfi_def_cfa_register 6
+	movl	%edi, -20(%rbp)
+	movq	%rsi, -32(%rbp)
+	movl	$10, -4(%rbp)
+#APP
+# 8 "amd64-stap-triplet.c" 1
+	990: nop
+.pushsection .note.stapsdt,"?","note"
+.balign 4
+.4byte 992f-991f,994f-993f,3
+991: .asciz "stapsdt"
+992: .balign 4
+993: .8byte 990b
+.8byte _.stapsdt.base
+.8byte 0
+.asciz "test"
+.asciz "triplet"
+/* The probe's argument definition below was tweaked in order to mimic a
+   triplet displacement in x86 asm.  The original probe argument was:
+
+     -4@-4(%rbp)
+
+   The argument below is equivalent to that.  */
+.asciz "-4@-4+16-16(%rbp)"
+994: .balign 4
+.popsection
+
+# 0 "" 2
+# 8 "amd64-stap-triplet.c" 1
+	.ifndef _.stapsdt.base
+.pushsection .stapsdt.base,"aG","progbits",.stapsdt.base,comdat
+.weak _.stapsdt.base
+.hidden _.stapsdt.base
+_.stapsdt.base: .space 1
+.size _.stapsdt.base,1
+.popsection
+.endif
+
+# 0 "" 2
+#NO_APP
+	movl	$0, %eax
+	popq	%rbp
+	.cfi_def_cfa 7, 8
+# SUCC: EXIT [100.0%] 
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	main, .-main
+	.ident	"GCC: (GNU) 4.7.2 20120921 (Red Hat 4.7.2-2)"
+	.section	.note.GNU-stack,"",@progbits
diff --git a/gdb/testsuite/gdb.arch/amd64-stap-triplet.c b/gdb/testsuite/gdb.arch/amd64-stap-triplet.c
new file mode 100644
index 0000000..7ca64bf
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/amd64-stap-triplet.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 2013 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+   This file is not used directly.  Please, see the equivalent .S file
+   for more details.  */
+
+#include <sys/sdt.h>
+
+int
+main (int argc, char *argv[])
+{
+  int a = 10;
+
+  STAP_PROBE1 (test, triplet, a);
+
+  return 0;
+}


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