Blame SOURCES/gdb-rhbz1187581-power8-regs-4of7.patch

190f2a
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
190f2a
From: Jan Kratochvil <jan.kratochvil@redhat.com>
190f2a
Date: Thu, 9 Aug 2018 17:17:16 +0200
190f2a
Subject: gdb-rhbz1187581-power8-regs-4of7.patch
190f2a
190f2a
;; Add GDB support to access/display POWER8 registers (IBM, RH BZ 1187581).
190f2a
190f2a
commit 4277c4b87addb5354cc47b98d7a73e44cfaf22c2
190f2a
Author: Pedro Franco de Carvalho <pedromfc@linux.ibm.com>
190f2a
Date:   Mon Aug 6 16:24:55 2018 -0300
190f2a
190f2a
    Use remote register numbers in tracepoint mask
190f2a
190f2a
    Currently, tracepoint register masks in the QTDP packets include both
190f2a
    internal and remote register numbers, as well as pseudo-register
190f2a
    numbers.
190f2a
190f2a
    This patch changes this so that the mask only includes remote register
190f2a
    numbers.
190f2a
190f2a
    Register numbers from agent expressions are already set in the mask
190f2a
    using remote numbers.  Other tracepoint actions used internal numbers,
190f2a
    e.g. "collect $regs" or "collect $<pseudoreg>".  To handle pseudoreg
190f2a
    numbers, an empty agent expression is created and ax_reg_mask is
190f2a
    called for this expression and the pseudoreg.  This will cause the ax
190f2a
    to set its mask with the corresponding remote raw register
190f2a
    numbers (using ax_regs_mask, which calls
190f2a
    gdbarch_ax_pseudo_register_collect).
190f2a
190f2a
    If ax_regs_mask and gdbarch_ax_pseudo_register_collect also generate
190f2a
    more ax bytecode, the ax is also appended to the collection list.  It
190f2a
    isn't clear that this was the original intent for
190f2a
    gdbarch_ax_pseudo_register_collect, and none of the arches seem to do
190f2a
    this, but if this changes in the future, it should work.
190f2a
190f2a
    The patch also refactors the code used by validate_action line to
190f2a
    validate axs into a function that is now called from every place that
190f2a
    generates axs.  Previously, some parts of tracepoint.c that generated
190f2a
    axs didn't check if the ax length was greater than MAX_AGENT_EXPR_LEN.
190f2a
190f2a
    gdb/ChangeLog:
190f2a
    2018-08-06  Pedro Franco de Carvalho  <pedromfc@linux.ibm.com>
190f2a
190f2a
            * tracepoint.h (class collection_list) <add_register>: Remove.
190f2a
            <add_remote_register, add_ax_registers, add_local_register>:
190f2a
            Declare.
190f2a
            <add_memrange>: Add scope parameter.
190f2a
            * tracepoint.c (encode_actions_1): Likewise.
190f2a
            (collection_list::add_register): Rename to ...
190f2a
            (collection_list::add_remote_register): ... this.  Update
190f2a
            comment.
190f2a
            (collection_list::add_ax_registers, add_local_register): New
190f2a
            methods.
190f2a
            (collection_list::add_memrange): Add scope parameter.  Call
190f2a
            add_local_register instead of add_register.
190f2a
            (finalize_tracepoint_aexpr): New function.
190f2a
            (collection_list::collect_symbol): Update calls to add_memrange.
190f2a
            Call add_local_register instead of add_register.  Call
190f2a
            add_ax_registers.  Call finalize_tracepoint_aexpr.
190f2a
            (encode_actions_1): Get remote regnos for $reg action.  Call
190f2a
            add_remote_register, add_ax_registers, and add_local_register.
190f2a
            Update call to add_memrange.  Call finalize_tracepoint_aexpr.
190f2a
            (validate_actionline): Call finalize_tracepoint_aexpr.
190f2a
190f2a
+2018-08-06  Pedro Franco de Carvalho  <pedromfc@linux.ibm.com>
190f2a
+
190f2a
+	* tracepoint.h (class collection_list) <add_register>: Remove.
190f2a
+	<add_remote_register, add_ax_registers, add_local_register>:
190f2a
+	Declare.
190f2a
+	<add_memrange>: Add scope parameter.
190f2a
+	* tracepoint.c (encode_actions_1): Likewise.
190f2a
+	(collection_list::add_register): Rename to ...
190f2a
+	(collection_list::add_remote_register): ... this.  Update
190f2a
+	comment.
190f2a
+	(collection_list::add_ax_registers, add_local_register): New
190f2a
+	methods.
190f2a
+	(collection_list::add_memrange): Add scope parameter.  Call
190f2a
+	add_local_register instead of add_register.
190f2a
+	(finalize_tracepoint_aexpr): New function.
190f2a
+	(collection_list::collect_symbol): Update calls to add_memrange.
190f2a
+	Call add_local_register instead of add_register.  Call
190f2a
+	add_ax_registers.  Call finalize_tracepoint_aexpr.
190f2a
+	(encode_actions_1): Get remote regnos for $reg action.  Call
190f2a
+	add_remote_register, add_ax_registers, and add_local_register.
190f2a
+	Update call to add_memrange.  Call finalize_tracepoint_aexpr.
190f2a
+	(validate_actionline): Call finalize_tracepoint_aexpr.
190f2a
+
190f2a
 2018-08-06  Pedro Franco de Carvalho  <pedromfc@linux.ibm.com>
190f2a
190f2a
 	* remote.c (remote_target::download_tracepoint): Remove BUF_SIZE.
190f2a
190f2a
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
190f2a
--- a/gdb/tracepoint.c
190f2a
+++ b/gdb/tracepoint.c
190f2a
@@ -615,6 +615,19 @@ report_agent_reqs_errors (struct agent_expr *aexpr)
190f2a
     error (_("Expression is too complicated."));
190f2a
 }
190f2a
 
190f2a
+/* Call ax_reqs on AEXPR and raise an error if something is wrong.  */
190f2a
+
190f2a
+static void
190f2a
+finalize_tracepoint_aexpr (struct agent_expr *aexpr)
190f2a
+{
190f2a
+  ax_reqs (aexpr);
190f2a
+
190f2a
+  if (aexpr->len > MAX_AGENT_EXPR_LEN)
190f2a
+    error (_("Expression is too complicated."));
190f2a
+
190f2a
+  report_agent_reqs_errors (aexpr);
190f2a
+}
190f2a
+
190f2a
 /* worker function */
190f2a
 void
190f2a
 validate_actionline (const char *line, struct breakpoint *b)
190f2a
@@ -699,12 +712,7 @@ validate_actionline (const char *line, struct breakpoint *b)
190f2a
 							exp.get (),
190f2a
 							trace_string);
190f2a
 
190f2a
-	      if (aexpr->len > MAX_AGENT_EXPR_LEN)
190f2a
-		error (_("Expression is too complicated."));
190f2a
-
190f2a
-	      ax_reqs (aexpr.get ());
190f2a
-
190f2a
-	      report_agent_reqs_errors (aexpr.get ());
190f2a
+	      finalize_tracepoint_aexpr (aexpr.get ());
190f2a
 	    }
190f2a
 	}
190f2a
       while (p && *p++ == ',');
190f2a
@@ -731,11 +739,7 @@ validate_actionline (const char *line, struct breakpoint *b)
190f2a
 		 long.  */
190f2a
 	      agent_expr_up aexpr = gen_eval_for_expr (loc->address, exp.get ());
190f2a
 
190f2a
-	      if (aexpr->len > MAX_AGENT_EXPR_LEN)
190f2a
-		error (_("Expression is too complicated."));
190f2a
-
190f2a
-	      ax_reqs (aexpr.get ());
190f2a
-	      report_agent_reqs_errors (aexpr.get ());
190f2a
+	      finalize_tracepoint_aexpr (aexpr.get ());
190f2a
 	    }
190f2a
 	}
190f2a
       while (p && *p++ == ',');
190f2a
@@ -811,10 +815,10 @@ memrange_sortmerge (std::vector<memrange> &memranges)
190f2a
     }
190f2a
 }
190f2a
 
190f2a
-/* Add a register to a collection list.  */
190f2a
+/* Add remote register number REGNO to the collection list mask.  */
190f2a
 
190f2a
 void
190f2a
-collection_list::add_register (unsigned int regno)
190f2a
+collection_list::add_remote_register (unsigned int regno)
190f2a
 {
190f2a
   if (info_verbose)
190f2a
     printf_filtered ("collect register %d\n", regno);
190f2a
@@ -824,12 +828,74 @@ collection_list::add_register (unsigned int regno)
190f2a
   m_regs_mask[regno / 8] |= 1 << (regno % 8);
190f2a
 }
190f2a
 
190f2a
+/* Add all the registers from the mask in AEXPR to the mask in the
190f2a
+   collection list.  Registers in the AEXPR mask are already remote
190f2a
+   register numbers.  */
190f2a
+
190f2a
+void
190f2a
+collection_list::add_ax_registers (struct agent_expr *aexpr)
190f2a
+{
190f2a
+  if (aexpr->reg_mask_len > 0)
190f2a
+    {
190f2a
+      for (int ndx1 = 0; ndx1 < aexpr->reg_mask_len; ndx1++)
190f2a
+	{
190f2a
+	  QUIT;	/* Allow user to bail out with ^C.  */
190f2a
+	  if (aexpr->reg_mask[ndx1] != 0)
190f2a
+	    {
190f2a
+	      /* Assume chars have 8 bits.  */
190f2a
+	      for (int ndx2 = 0; ndx2 < 8; ndx2++)
190f2a
+		if (aexpr->reg_mask[ndx1] & (1 << ndx2))
190f2a
+		  /* It's used -- record it.  */
190f2a
+		  add_remote_register (ndx1 * 8 + ndx2);
190f2a
+	    }
190f2a
+	}
190f2a
+    }
190f2a
+}
190f2a
+
190f2a
+/* If REGNO is raw, add its corresponding remote register number to
190f2a
+   the mask.  If REGNO is a pseudo-register, figure out the necessary
190f2a
+   registers using a temporary agent expression, and add it to the
190f2a
+   list if it needs more than just a mask.  */
190f2a
+
190f2a
+void
190f2a
+collection_list::add_local_register (struct gdbarch *gdbarch,
190f2a
+				     unsigned int regno,
190f2a
+				     CORE_ADDR scope)
190f2a
+{
190f2a
+  if (regno < gdbarch_num_regs (gdbarch))
190f2a
+    {
190f2a
+      int remote_regno = gdbarch_remote_register_number (gdbarch, regno);
190f2a
+
190f2a
+      if (remote_regno < 0)
190f2a
+	error (_("Can't collect register %d"), regno);
190f2a
+
190f2a
+      add_remote_register (remote_regno);
190f2a
+    }
190f2a
+  else
190f2a
+    {
190f2a
+      agent_expr_up aexpr (new agent_expr (gdbarch, scope));
190f2a
+
190f2a
+      ax_reg_mask (aexpr.get (), regno);
190f2a
+
190f2a
+      finalize_tracepoint_aexpr (aexpr.get ());
190f2a
+
190f2a
+      add_ax_registers (aexpr.get ());
190f2a
+
190f2a
+      /* Usually ax_reg_mask for a pseudo-regiser only sets the
190f2a
+	 corresponding raw registers in the ax mask, but if this isn't
190f2a
+	 the case add the expression that is generated to the
190f2a
+	 collection list.  */
190f2a
+      if (aexpr->len > 0)
190f2a
+	add_aexpr (std::move (aexpr));
190f2a
+    }
190f2a
+}
190f2a
+
190f2a
 /* Add a memrange to a collection list.  */
190f2a
 
190f2a
 void
190f2a
 collection_list::add_memrange (struct gdbarch *gdbarch,
190f2a
 			       int type, bfd_signed_vma base,
190f2a
-			       ULONGEST len)
190f2a
+			       ULONGEST len, CORE_ADDR scope)
190f2a
 {
190f2a
   if (info_verbose)
190f2a
     printf_filtered ("(%d,%s,%s)\n", type, paddress (gdbarch, base), pulongest (len));
190f2a
@@ -840,7 +906,7 @@ collection_list::add_memrange (struct gdbarch *gdbarch,
190f2a
   m_memranges.emplace_back (type, base, base + len);
190f2a
 
190f2a
   if (type != memrange_absolute)    /* Better collect the base register!  */
190f2a
-    add_register (type);
190f2a
+    add_local_register (gdbarch, type, scope);
190f2a
 }
190f2a
 
190f2a
 /* Add a symbol to a collection list.  */
190f2a
@@ -882,19 +948,19 @@ collection_list::collect_symbol (struct symbol *sym,
190f2a
       if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT)
190f2a
 	treat_as_expr = 1;
190f2a
       else
190f2a
-	add_memrange (gdbarch, memrange_absolute, offset, len);
190f2a
+	add_memrange (gdbarch, memrange_absolute, offset, len, scope);
190f2a
       break;
190f2a
     case LOC_REGISTER:
190f2a
       reg = SYMBOL_REGISTER_OPS (sym)->register_number (sym, gdbarch);
190f2a
       if (info_verbose)
190f2a
 	printf_filtered ("LOC_REG[parm] %s: ", 
190f2a
 			 SYMBOL_PRINT_NAME (sym));
190f2a
-      add_register (reg);
190f2a
+      add_local_register (gdbarch, reg, scope);
190f2a
       /* Check for doubles stored in two registers.  */
190f2a
       /* FIXME: how about larger types stored in 3 or more regs?  */
190f2a
       if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FLT &&
190f2a
 	  len > register_size (gdbarch, reg))
190f2a
-	add_register (reg + 1);
190f2a
+	add_local_register (gdbarch, reg + 1, scope);
190f2a
       break;
190f2a
     case LOC_REF_ARG:
190f2a
       printf_filtered ("Sorry, don't know how to do LOC_REF_ARG yet.\n");
190f2a
@@ -911,7 +977,7 @@ collection_list::collect_symbol (struct symbol *sym,
190f2a
 			   SYMBOL_PRINT_NAME (sym), pulongest (len),
190f2a
 			   paddress (gdbarch, offset), reg);
190f2a
 	}
190f2a
-      add_memrange (gdbarch, reg, offset, len);
190f2a
+      add_memrange (gdbarch, reg, offset, len, scope);
190f2a
       break;
190f2a
     case LOC_REGPARM_ADDR:
190f2a
       reg = SYMBOL_VALUE (sym);
190f2a
@@ -923,7 +989,7 @@ collection_list::collect_symbol (struct symbol *sym,
190f2a
 			   SYMBOL_PRINT_NAME (sym), pulongest (len),
190f2a
 			   paddress (gdbarch, offset), reg);
190f2a
 	}
190f2a
-      add_memrange (gdbarch, reg, offset, len);
190f2a
+      add_memrange (gdbarch, reg, offset, len, scope);
190f2a
       break;
190f2a
     case LOC_LOCAL:
190f2a
       reg = frame_regno;
190f2a
@@ -935,7 +1001,7 @@ collection_list::collect_symbol (struct symbol *sym,
190f2a
 			   SYMBOL_PRINT_NAME (sym), pulongest (len),
190f2a
 			   paddress (gdbarch, offset), reg);
190f2a
 	}
190f2a
-      add_memrange (gdbarch, reg, offset, len);
190f2a
+      add_memrange (gdbarch, reg, offset, len, scope);
190f2a
       break;
190f2a
 
190f2a
     case LOC_UNRESOLVED:
190f2a
@@ -968,26 +1034,10 @@ collection_list::collect_symbol (struct symbol *sym,
190f2a
 	  return;
190f2a
 	}
190f2a
 
190f2a
-      ax_reqs (aexpr.get ());
190f2a
-
190f2a
-      report_agent_reqs_errors (aexpr.get ());
190f2a
+      finalize_tracepoint_aexpr (aexpr.get ());
190f2a
 
190f2a
       /* Take care of the registers.  */
190f2a
-      if (aexpr->reg_mask_len > 0)
190f2a
-	{
190f2a
-	  for (int ndx1 = 0; ndx1 < aexpr->reg_mask_len; ndx1++)
190f2a
-	    {
190f2a
-	      QUIT;	/* Allow user to bail out with ^C.  */
190f2a
-	      if (aexpr->reg_mask[ndx1] != 0)
190f2a
-		{
190f2a
-		  /* Assume chars have 8 bits.  */
190f2a
-		  for (int ndx2 = 0; ndx2 < 8; ndx2++)
190f2a
-		    if (aexpr->reg_mask[ndx1] & (1 << ndx2))
190f2a
-		      /* It's used -- record it.  */
190f2a
-		      add_register (ndx1 * 8 + ndx2);
190f2a
-		}
190f2a
-	    }
190f2a
-	}
190f2a
+      add_ax_registers (aexpr.get ());
190f2a
 
190f2a
       add_aexpr (std::move (aexpr));
190f2a
     }
190f2a
@@ -1257,8 +1307,18 @@ encode_actions_1 (struct command_line *action,
190f2a
 
190f2a
 	      if (0 == strncasecmp ("$reg", action_exp, 4))
190f2a
 		{
190f2a
-		  for (i = 0; i < gdbarch_num_regs (target_gdbarch ()); i++)
190f2a
-		    collect->add_register (i);
190f2a
+		  for (i = 0; i < gdbarch_num_regs (target_gdbarch ());
190f2a
+		       i++)
190f2a
+		    {
190f2a
+		      int remote_regno = (gdbarch_remote_register_number
190f2a
+					  (target_gdbarch (), i));
190f2a
+
190f2a
+		      /* Ignore arch regnos without a corresponding
190f2a
+			 remote regno.  This can happen for regnos not
190f2a
+			 in the tdesc.  */
190f2a
+		      if (remote_regno >= 0)
190f2a
+			collect->add_remote_register (remote_regno);
190f2a
+		    }
190f2a
 		  action_exp = strchr (action_exp, ',');	/* more? */
190f2a
 		}
190f2a
 	      else if (0 == strncasecmp ("$arg", action_exp, 4))
190f2a
@@ -1288,27 +1348,10 @@ encode_actions_1 (struct command_line *action,
190f2a
 						    target_gdbarch (),
190f2a
 						    trace_string);
190f2a
 
190f2a
-		  ax_reqs (aexpr.get ());
190f2a
-		  report_agent_reqs_errors (aexpr.get ());
190f2a
+		  finalize_tracepoint_aexpr (aexpr.get ());
190f2a
 
190f2a
 		  /* take care of the registers */
190f2a
-		  if (aexpr->reg_mask_len > 0)
190f2a
-		    {
190f2a
-		      for (int ndx1 = 0; ndx1 < aexpr->reg_mask_len; ndx1++)
190f2a
-			{
190f2a
-			  QUIT;	/* allow user to bail out with ^C */
190f2a
-			  if (aexpr->reg_mask[ndx1] != 0)
190f2a
-			    {
190f2a
-			      /* assume chars have 8 bits */
190f2a
-			      for (int ndx2 = 0; ndx2 < 8; ndx2++)
190f2a
-				if (aexpr->reg_mask[ndx1] & (1 << ndx2))
190f2a
-				  {
190f2a
-				    /* It's used -- record it.  */
190f2a
-				    collect->add_register (ndx1 * 8 + ndx2);
190f2a
-				  }
190f2a
-			    }
190f2a
-			}
190f2a
-		    }
190f2a
+		  collect->add_ax_registers (aexpr.get ());
190f2a
 
190f2a
 		  collect->add_aexpr (std::move (aexpr));
190f2a
 		  action_exp = strchr (action_exp, ',');	/* more? */
190f2a
@@ -1340,7 +1383,8 @@ encode_actions_1 (struct command_line *action,
190f2a
 					  name);
190f2a
 			if (info_verbose)
190f2a
 			  printf_filtered ("OP_REGISTER: ");
190f2a
-			collect->add_register (i);
190f2a
+			collect->add_local_register (target_gdbarch (),
190f2a
+						     i, tloc->address);
190f2a
 			break;
190f2a
 		      }
190f2a
 
190f2a
@@ -1352,7 +1396,8 @@ encode_actions_1 (struct command_line *action,
190f2a
 		      check_typedef (exp->elts[1].type);
190f2a
 		      collect->add_memrange (target_gdbarch (),
190f2a
 					     memrange_absolute, addr,
190f2a
-					     TYPE_LENGTH (exp->elts[1].type));
190f2a
+					     TYPE_LENGTH (exp->elts[1].type),
190f2a
+					     tloc->address);
190f2a
 		      collect->append_exp (exp.get ());
190f2a
 		      break;
190f2a
 
190f2a
@@ -1376,28 +1421,10 @@ encode_actions_1 (struct command_line *action,
190f2a
 								exp.get (),
190f2a
 								trace_string);
190f2a
 
190f2a
-		      ax_reqs (aexpr.get ());
190f2a
-
190f2a
-		      report_agent_reqs_errors (aexpr.get ());
190f2a
+		      finalize_tracepoint_aexpr (aexpr.get ());
190f2a
 
190f2a
 		      /* Take care of the registers.  */
190f2a
-		      if (aexpr->reg_mask_len > 0)
190f2a
-			{
190f2a
-			  for (int ndx1 = 0; ndx1 < aexpr->reg_mask_len; ndx1++)
190f2a
-			    {
190f2a
-			      QUIT;	/* Allow user to bail out with ^C.  */
190f2a
-			      if (aexpr->reg_mask[ndx1] != 0)
190f2a
-				{
190f2a
-				  /* Assume chars have 8 bits.  */
190f2a
-				  for (int ndx2 = 0; ndx2 < 8; ndx2++)
190f2a
-				    if (aexpr->reg_mask[ndx1] & (1 << ndx2))
190f2a
-				      {
190f2a
-					/* It's used -- record it.  */
190f2a
-					collect->add_register (ndx1 * 8 + ndx2);
190f2a
-				      }
190f2a
-				}
190f2a
-			    }
190f2a
-			}
190f2a
+		      collect->add_ax_registers (aexpr.get ());
190f2a
 
190f2a
 		      collect->add_aexpr (std::move (aexpr));
190f2a
 		      collect->append_exp (exp.get ());
190f2a
@@ -1422,8 +1449,7 @@ encode_actions_1 (struct command_line *action,
190f2a
 		  agent_expr_up aexpr = gen_eval_for_expr (tloc->address,
190f2a
 							   exp.get ());
190f2a
 
190f2a
-		  ax_reqs (aexpr.get ());
190f2a
-		  report_agent_reqs_errors (aexpr.get ());
190f2a
+		  finalize_tracepoint_aexpr (aexpr.get ());
190f2a
 
190f2a
 		  /* Even though we're not officially collecting, add
190f2a
 		     to the collect list anyway.  */
190f2a
diff --git a/gdb/tracepoint.h b/gdb/tracepoint.h
190f2a
--- a/gdb/tracepoint.h
190f2a
+++ b/gdb/tracepoint.h
190f2a
@@ -263,9 +263,14 @@ public:
190f2a
   void add_aexpr (agent_expr_up aexpr);
190f2a
 
190f2a
   void add_register (unsigned int regno);
190f2a
+  void add_remote_register (unsigned int regno);
190f2a
+  void add_ax_registers (struct agent_expr *aexpr);
190f2a
+  void add_local_register (struct gdbarch *gdbarch,
190f2a
+			   unsigned int regno,
190f2a
+			   CORE_ADDR scope);
190f2a
   void add_memrange (struct gdbarch *gdbarch,
190f2a
 		     int type, bfd_signed_vma base,
190f2a
-		     ULONGEST len);
190f2a
+		     ULONGEST len, CORE_ADDR scope);
190f2a
   void collect_symbol (struct symbol *sym,
190f2a
 		       struct gdbarch *gdbarch,
190f2a
 		       long frame_regno, long frame_offset,