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

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