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