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