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