Blame SOURCES/gdb-rhbz1187581-power8-regs-3of7.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:11:09 +0200
190f2a
Subject: gdb-rhbz1187581-power8-regs-3of7.patch
190f2a
190f2a
;; Add GDB support to access/display POWER8 registers (IBM, RH BZ 1187581).
190f2a
190f2a
commit 3df3a985a475db004706d64f83d9085f99053611
190f2a
Author: Pedro Franco de Carvalho <pedromfc@linux.ibm.com>
190f2a
Date:   Mon Aug 6 16:24:55 2018 -0300
190f2a
190f2a
    Use get_remote_packet_size in download_tracepoint
190f2a
190f2a
    This patch changes the remote target to use the remote packet size to
190f2a
    build QTDP packets, and to check if there is enough room for the
190f2a
    packet.
190f2a
190f2a
    I changed the function to raise an error if the packet is too small,
190f2a
    instead of aborting gdb (through xsnprintf).  It isn't clear if gdb
190f2a
    will be in a consistent state with respect to the stub after this,
190f2a
    since it's possible that some packets will be sent but not others, and
190f2a
    there could be an incomplete tracepoint on the stub.
190f2a
190f2a
    The char array used to build the packets is changed to a
190f2a
    gdb::char_vector and sized with the result from
190f2a
    get_remote_packet_size.
190f2a
190f2a
    When checking if the buffer is large enough to hold the tracepoint
190f2a
    condition agent expression, the length of the expression is multiplied
190f2a
    by two, since it is encoded with two hex digits per expression
190f2a
    byte.  For simplicity, I assume that the result won't overflow, which
190f2a
    can happen for very long condition expressions.
190f2a
190f2a
    gdb/ChangeLog:
190f2a
    2018-08-06  Pedro Franco de Carvalho  <pedromfc@linux.ibm.com>
190f2a
190f2a
            * remote.c (remote_target::download_tracepoint): Remove BUF_SIZE.
190f2a
            Replace array buf with gdb::char_vector buf, of size
190f2a
            get_remote_packet_size ().  Replace references to buf and
190f2a
            BUF_SIZE to buf.data () and buf.size ().  Replace strcpy, strcat
190f2a
            and xsnprintf with snprintf.  Raise errors if the buffer is too
190f2a
            small.
190f2a
190f2a
diff --git a/gdb/remote.c b/gdb/remote.c
190f2a
--- a/gdb/remote.c
190f2a
+++ b/gdb/remote.c
190f2a
@@ -12799,26 +12799,35 @@ remote_target::remote_download_command_source (int num, ULONGEST addr,
190f2a
 void
190f2a
 remote_target::download_tracepoint (struct bp_location *loc)
190f2a
 {
190f2a
-#define BUF_SIZE 2048
190f2a
-
190f2a
   CORE_ADDR tpaddr;
190f2a
   char addrbuf[40];
190f2a
-  char buf[BUF_SIZE];
190f2a
   std::vector<std::string> tdp_actions;
190f2a
   std::vector<std::string> stepping_actions;
190f2a
   char *pkt;
190f2a
   struct breakpoint *b = loc->owner;
190f2a
   struct tracepoint *t = (struct tracepoint *) b;
190f2a
   struct remote_state *rs = get_remote_state ();
190f2a
+  int ret;
190f2a
+  char *err_msg = _("Tracepoint packet too large for target.");
190f2a
+  size_t size_left;
190f2a
+
190f2a
+  /* We use a buffer other than rs->buf because we'll build strings
190f2a
+     across multiple statements, and other statements in between could
190f2a
+     modify rs->buf.  */
190f2a
+  gdb::char_vector buf (get_remote_packet_size ());
190f2a
 
190f2a
   encode_actions_rsp (loc, &tdp_actions, &stepping_actions);
190f2a
 
190f2a
   tpaddr = loc->address;
190f2a
   sprintf_vma (addrbuf, tpaddr);
190f2a
-  xsnprintf (buf, BUF_SIZE, "QTDP:%x:%s:%c:%lx:%x", b->number,
190f2a
-	     addrbuf, /* address */
190f2a
-	     (b->enable_state == bp_enabled ? 'E' : 'D'),
190f2a
-	     t->step_count, t->pass_count);
190f2a
+  ret = snprintf (buf.data (), buf.size (), "QTDP:%x:%s:%c:%lx:%x",
190f2a
+		  b->number, addrbuf, /* address */
190f2a
+		  (b->enable_state == bp_enabled ? 'E' : 'D'),
190f2a
+		  t->step_count, t->pass_count);
190f2a
+
190f2a
+  if (ret < 0 || ret >= buf.size ())
190f2a
+    error (err_msg);
190f2a
+
190f2a
   /* Fast tracepoints are mostly handled by the target, but we can
190f2a
      tell the target how big of an instruction block should be moved
190f2a
      around.  */
190f2a
@@ -12830,8 +12839,15 @@ remote_target::download_tracepoint (struct bp_location *loc)
190f2a
 	{
190f2a
 	  if (gdbarch_fast_tracepoint_valid_at (loc->gdbarch, tpaddr,
190f2a
 						NULL))
190f2a
-	    xsnprintf (buf + strlen (buf), BUF_SIZE - strlen (buf), ":F%x",
190f2a
-		       gdb_insn_length (loc->gdbarch, tpaddr));
190f2a
+	    {
190f2a
+	      size_left = buf.size () - strlen (buf.data ());
190f2a
+	      ret = snprintf (buf.data () + strlen (buf.data ()),
190f2a
+			      size_left, ":F%x",
190f2a
+			      gdb_insn_length (loc->gdbarch, tpaddr));
190f2a
+
190f2a
+	      if (ret < 0 || ret >= size_left)
190f2a
+		error (err_msg);
190f2a
+	    }
190f2a
 	  else
190f2a
 	    /* If it passed validation at definition but fails now,
190f2a
 	       something is very wrong.  */
190f2a
@@ -12855,7 +12871,14 @@ remote_target::download_tracepoint (struct bp_location *loc)
190f2a
 	  struct static_tracepoint_marker marker;
190f2a
 
190f2a
 	  if (target_static_tracepoint_marker_at (tpaddr, &marker))
190f2a
-	    strcat (buf, ":S");
190f2a
+	    {
190f2a
+	      size_left = buf.size () - strlen (buf.data ());
190f2a
+	      ret = snprintf (buf.data () + strlen (buf.data ()),
190f2a
+			      size_left, ":S");
190f2a
+
190f2a
+	      if (ret < 0 || ret >= size_left)
190f2a
+		error (err_msg);
190f2a
+	    }
190f2a
 	  else
190f2a
 	    error (_("Static tracepoint not valid during download"));
190f2a
 	}
190f2a
@@ -12873,10 +12896,26 @@ remote_target::download_tracepoint (struct bp_location *loc)
190f2a
 	 capabilities at definition time.  */
190f2a
       if (remote_supports_cond_tracepoints ())
190f2a
 	{
190f2a
-	  agent_expr_up aexpr = gen_eval_for_expr (tpaddr, loc->cond.get ());
190f2a
-	  xsnprintf (buf + strlen (buf), BUF_SIZE - strlen (buf), ":X%x,",
190f2a
-		     aexpr->len);
190f2a
-	  pkt = buf + strlen (buf);
190f2a
+	  agent_expr_up aexpr = gen_eval_for_expr (tpaddr,
190f2a
+						   loc->cond.get ());
190f2a
+
190f2a
+	  size_left = buf.size () - strlen (buf.data ());
190f2a
+
190f2a
+	  ret = snprintf (buf.data () + strlen (buf.data ()),
190f2a
+			  size_left, ":X%x,", aexpr->len);
190f2a
+
190f2a
+	  if (ret < 0 || ret >= size_left)
190f2a
+	    error (err_msg);
190f2a
+
190f2a
+	  size_left = buf.size () - strlen (buf.data ());
190f2a
+
190f2a
+	  /* Two bytes to encode each aexpr byte, plus the terminating
190f2a
+	     null byte.  */
190f2a
+	  if (aexpr->len * 2 + 1 > size_left)
190f2a
+	    error (err_msg);
190f2a
+
190f2a
+	  pkt = buf.data () + strlen (buf.data ());
190f2a
+
190f2a
 	  for (int ndx = 0; ndx < aexpr->len; ++ndx)
190f2a
 	    pkt = pack_hex_byte (pkt, aexpr->buf[ndx]);
190f2a
 	  *pkt = '\0';
190f2a
@@ -12887,8 +12926,17 @@ remote_target::download_tracepoint (struct bp_location *loc)
190f2a
     }
190f2a
 
190f2a
   if (b->commands || *default_collect)
190f2a
-    strcat (buf, "-");
190f2a
-  putpkt (buf);
190f2a
+    {
190f2a
+      size_left = buf.size () - strlen (buf.data ());
190f2a
+
190f2a
+      ret = snprintf (buf.data () + strlen (buf.data ()),
190f2a
+		      size_left, "-");
190f2a
+
190f2a
+      if (ret < 0 || ret >= size_left)
190f2a
+	error (err_msg);
190f2a
+    }
190f2a
+
190f2a
+  putpkt (buf.data ());
190f2a
   remote_get_noisy_reply ();
190f2a
   if (strcmp (rs->buf, "OK"))
190f2a
     error (_("Target does not support tracepoints."));
190f2a
@@ -12902,11 +12950,15 @@ remote_target::download_tracepoint (struct bp_location *loc)
190f2a
       bool has_more = ((action_it + 1) != tdp_actions.end ()
190f2a
 		       || !stepping_actions.empty ());
190f2a
 
190f2a
-      xsnprintf (buf, BUF_SIZE, "QTDP:-%x:%s:%s%c",
190f2a
-		 b->number, addrbuf, /* address */
190f2a
-		 action_it->c_str (),
190f2a
-		 has_more ? '-' : 0);
190f2a
-      putpkt (buf);
190f2a
+      ret = snprintf (buf.data (), buf.size (), "QTDP:-%x:%s:%s%c",
190f2a
+		      b->number, addrbuf, /* address */
190f2a
+		      action_it->c_str (),
190f2a
+		      has_more ? '-' : 0);
190f2a
+
190f2a
+      if (ret < 0 || ret >= buf.size ())
190f2a
+	error (err_msg);
190f2a
+
190f2a
+      putpkt (buf.data ());
190f2a
       remote_get_noisy_reply ();
190f2a
       if (strcmp (rs->buf, "OK"))
190f2a
 	error (_("Error on target while setting tracepoints."));
190f2a
@@ -12920,12 +12972,16 @@ remote_target::download_tracepoint (struct bp_location *loc)
190f2a
       bool is_first = action_it == stepping_actions.begin ();
190f2a
       bool has_more = (action_it + 1) != stepping_actions.end ();
190f2a
 
190f2a
-      xsnprintf (buf, BUF_SIZE, "QTDP:-%x:%s:%s%s%s",
190f2a
-		 b->number, addrbuf, /* address */
190f2a
-		 is_first ? "S" : "",
190f2a
-		 action_it->c_str (),
190f2a
-		 has_more ? "-" : "");
190f2a
-      putpkt (buf);
190f2a
+      ret = snprintf (buf.data (), buf.size (), "QTDP:-%x:%s:%s%s%s",
190f2a
+		      b->number, addrbuf, /* address */
190f2a
+		      is_first ? "S" : "",
190f2a
+		      action_it->c_str (),
190f2a
+		      has_more ? "-" : "");
190f2a
+
190f2a
+      if (ret < 0 || ret >= buf.size ())
190f2a
+	error (err_msg);
190f2a
+
190f2a
+      putpkt (buf.data ());
190f2a
       remote_get_noisy_reply ();
190f2a
       if (strcmp (rs->buf, "OK"))
190f2a
 	error (_("Error on target while setting tracepoints."));
190f2a
@@ -12935,22 +12991,32 @@ remote_target::download_tracepoint (struct bp_location *loc)
190f2a
     {
190f2a
       if (b->location != NULL)
190f2a
 	{
190f2a
-	  strcpy (buf, "QTDPsrc:");
190f2a
+	  ret = snprintf (buf.data (), buf.size (), "QTDPsrc:");
190f2a
+
190f2a
+	  if (ret < 0 || ret >= buf.size ())
190f2a
+	    error (err_msg);
190f2a
+
190f2a
 	  encode_source_string (b->number, loc->address, "at",
190f2a
 				event_location_to_string (b->location.get ()),
190f2a
-				buf + strlen (buf), 2048 - strlen (buf));
190f2a
-	  putpkt (buf);
190f2a
+				buf.data () + strlen (buf.data ()),
190f2a
+				buf.size () - strlen (buf.data ()));
190f2a
+	  putpkt (buf.data ());
190f2a
 	  remote_get_noisy_reply ();
190f2a
 	  if (strcmp (rs->buf, "OK"))
190f2a
 	    warning (_("Target does not support source download."));
190f2a
 	}
190f2a
       if (b->cond_string)
190f2a
 	{
190f2a
-	  strcpy (buf, "QTDPsrc:");
190f2a
+	  ret = snprintf (buf.data (), buf.size (), "QTDPsrc:");
190f2a
+
190f2a
+	  if (ret < 0 || ret >= buf.size ())
190f2a
+	    error (err_msg);
190f2a
+
190f2a
 	  encode_source_string (b->number, loc->address,
190f2a
-				"cond", b->cond_string, buf + strlen (buf),
190f2a
-				2048 - strlen (buf));
190f2a
-	  putpkt (buf);
190f2a
+				"cond", b->cond_string,
190f2a
+				buf.data () + strlen (buf.data ()),
190f2a
+				buf.size () - strlen (buf.data ()));
190f2a
+	  putpkt (buf.data ());
190f2a
 	  remote_get_noisy_reply ();
190f2a
 	  if (strcmp (rs->buf, "OK"))
190f2a
 	    warning (_("Target does not support source download."));