#include "cli/cli-decode.h"
#include "cli/cli-setshow.h"
#include "target-descriptions.h"
+#include "gdb_bfd.h"
#include <ctype.h>
#include <sys/time.h>
#include "tracepoint.h"
#include "ax.h"
#include "ax-gdb.h"
+#include "agent.h"
/* Temp hacks for tracepoint encoding migration. */
static char *target_buf;
static int remote_supports_cond_breakpoints (void);
+static int remote_can_run_breakpoint_commands (void);
+
/* The non-stop remote protocol provisions for one pending stop reply.
This is where we keep it until it is acknowledged. */
char *buf;
long buf_size;
+ /* True if we're going through initial connection setup (finding out
+ about the remote side's threads, relocating symbols, etc.). */
+ int starting_up;
+
/* If we negotiated packet size explicitly (and thus can bypass
heuristics for the largest packet size that will not overflow
a buffer in the stub), this will be set to that packet size.
conditions. */
int cond_breakpoints;
+ /* True if the stub reports support for target-side breakpoint
+ commands. */
+ int breakpoint_commands;
+
/* True if the stub reports support for fast tracepoints. */
int fast_tracepoints;
{
adjusted_size = to - org_to;
- sprintf (buf, "qRelocInsn:%x", adjusted_size);
+ xsnprintf (buf, *sizeof_buf, "qRelocInsn:%x", adjusted_size);
putpkt (buf);
}
else if (ex.reason < 0 && ex.error == MEMORY_ERROR)
PACKET_qXfer_threads,
PACKET_qXfer_statictrace_read,
PACKET_qXfer_traceframe_info,
+ PACKET_qXfer_uib,
PACKET_qGetTIBAddr,
PACKET_qGetTLSAddr,
PACKET_qSupported,
PACKET_QPassSignals,
+ PACKET_QProgramSignals,
PACKET_qSearch_memory,
PACKET_vAttach,
PACKET_vRun,
PACKET_qAttached,
PACKET_ConditionalTracepoints,
PACKET_ConditionalBreakpoints,
+ PACKET_BreakpointCommands,
PACKET_FastTracepoints,
PACKET_StaticTracepoints,
PACKET_InstallInTrace,
PACKET_QAllow,
PACKET_qXfer_fdpic,
PACKET_QDisableRandomization,
+ PACKET_QAgent,
PACKET_MAX
};
static ptid_t general_thread;
static ptid_t continue_thread;
-/* This the traceframe which we last selected on the remote system.
+/* This is the traceframe which we last selected on the remote system.
It will be -1 if no traceframe is selected. */
static int remote_traceframe_number = -1;
remote_query_attached (int pid)
{
struct remote_state *rs = get_remote_state ();
+ size_t size = get_remote_packet_size ();
if (remote_protocol_packets[PACKET_qAttached].support == PACKET_DISABLE)
return 0;
if (remote_multi_process_p (rs))
- sprintf (rs->buf, "qAttached:%x", pid);
+ xsnprintf (rs->buf, size, "qAttached:%x", pid);
else
- sprintf (rs->buf, "qAttached");
+ xsnprintf (rs->buf, size, "qAttached");
putpkt (rs->buf);
getpkt (&rs->buf, &rs->buf_size, 0);
}
}
+/* The last QProgramSignals packet sent to the target. We bypass
+ sending a new program signals list down to the target if the new
+ packet is exactly the same as the last we sent. IOW, we only let
+ the target know about program signals list changes. */
+
+static char *last_program_signals_packet;
+
+/* If 'QProgramSignals' is supported, tell the remote stub what
+ signals it should pass through to the inferior when detaching. */
+
+static void
+remote_program_signals (int numsigs, unsigned char *signals)
+{
+ if (remote_protocol_packets[PACKET_QProgramSignals].support != PACKET_DISABLE)
+ {
+ char *packet, *p;
+ int count = 0, i;
+
+ gdb_assert (numsigs < 256);
+ for (i = 0; i < numsigs; i++)
+ {
+ if (signals[i])
+ count++;
+ }
+ packet = xmalloc (count * 3 + strlen ("QProgramSignals:") + 1);
+ strcpy (packet, "QProgramSignals:");
+ p = packet + strlen (packet);
+ for (i = 0; i < numsigs; i++)
+ {
+ if (signal_pass_state (i))
+ {
+ if (i >= 16)
+ *p++ = tohex (i >> 4);
+ *p++ = tohex (i & 15);
+ if (count)
+ *p++ = ';';
+ else
+ break;
+ count--;
+ }
+ }
+ *p = 0;
+ if (!last_program_signals_packet
+ || strcmp (last_program_signals_packet, packet) != 0)
+ {
+ struct remote_state *rs = get_remote_state ();
+ char *buf = rs->buf;
+
+ putpkt (packet);
+ getpkt (&rs->buf, &rs->buf_size, 0);
+ packet_ok (buf, &remote_protocol_packets[PACKET_QProgramSignals]);
+ xfree (last_program_signals_packet);
+ last_program_signals_packet = packet;
+ }
+ else
+ xfree (packet);
+ }
+}
+
/* If PTID is MAGIC_NULL_PTID, don't set any thread. If PTID is
MINUS_ONE_PTID, set the thread to -1, so the stub returns the
thread. If GEN is set, set the general thread, if not, then set
struct remote_state *rs = get_remote_state ();
char *p = rs->buf;
- sprintf (p, "qTSTMat:");
+ xsnprintf (p, get_remote_packet_size (), "qTSTMat:");
p += strlen (p);
p += hexnumstr (p, addr);
putpkt (rs->buf);
return 0;
}
-static void
-free_current_marker (void *arg)
-{
- struct static_tracepoint_marker **marker_p = arg;
-
- if (*marker_p != NULL)
- {
- release_static_tracepoint_marker (*marker_p);
- xfree (*marker_p);
- }
- else
- *marker_p = NULL;
-}
-
static VEC(static_tracepoint_marker_p) *
remote_static_tracepoint_markers_by_strid (const char *strid)
{
char *wait_status = NULL;
immediate_quit++; /* Allow user to interrupt it. */
+ QUIT;
if (interrupt_on_connect)
send_interrupt_sequence ();
/* Ack any packet which the remote side has already sent. */
serial_write (remote_desc, "+", 1);
+ /* Signal other parts that we're going through the initial setup,
+ and so things may not be stable yet. */
+ rs->starting_up = 1;
+
/* The first packet we send to the target is the optional "supported
packets" request. If the target can answer this, it will tell us
which later probes to skip. */
getpkt (&rs->buf, &rs->buf_size, 0);
}
+ /* Let the target know which signals it is allowed to pass down to
+ the program. */
+ update_signals_program_target ();
+
/* Next, if the target can specify a description, read it. We do
this before anything involving memory or registers. */
target_find_description ();
/* We're connected, but not running. Drop out before we
call start_remote. */
+ rs->starting_up = 0;
return;
}
else
/* We're connected, but not running. Drop out before we
call start_remote. */
+ rs->starting_up = 0;
return;
}
merge_uploaded_tracepoints (&uploaded_tps);
}
+ /* The thread and inferior lists are now synchronized with the
+ target, our symbols have been relocated, and we're merged the
+ target's tracepoints with ours. We're done with basic start
+ up. */
+ rs->starting_up = 0;
+
/* If breakpoints are global, insert them now. */
if (gdbarch_has_global_breakpoints (target_gdbarch)
&& breakpoints_always_inserted_mode ())
{
struct remote_state *rs = get_remote_state ();
- sprintf (rs->buf, "QAllow:"
- "WriteReg:%x;WriteMem:%x;"
- "InsertBreak:%x;InsertTrace:%x;"
- "InsertFastTrace:%x;Stop:%x",
- may_write_registers, may_write_memory,
- may_insert_breakpoints, may_insert_tracepoints,
- may_insert_fast_tracepoints, may_stop);
+ xsnprintf (rs->buf, get_remote_packet_size (), "QAllow:"
+ "WriteReg:%x;WriteMem:%x;"
+ "InsertBreak:%x;InsertTrace:%x;"
+ "InsertFastTrace:%x;Stop:%x",
+ may_write_registers, may_write_memory,
+ may_insert_breakpoints, may_insert_tracepoints,
+ may_insert_fast_tracepoints, may_stop);
putpkt (rs->buf);
getpkt (&rs->buf, &rs->buf_size, 0);
rs->cond_breakpoints = (support == PACKET_ENABLE);
}
+static void
+remote_breakpoint_commands_feature (const struct protocol_feature *feature,
+ enum packet_support support,
+ const char *value)
+{
+ struct remote_state *rs = get_remote_state ();
+
+ rs->breakpoint_commands = (support == PACKET_ENABLE);
+}
+
static void
remote_fast_tracepoint_feature (const struct protocol_feature *feature,
enum packet_support support,
PACKET_qXfer_traceframe_info },
{ "QPassSignals", PACKET_DISABLE, remote_supported_packet,
PACKET_QPassSignals },
+ { "QProgramSignals", PACKET_DISABLE, remote_supported_packet,
+ PACKET_QProgramSignals },
{ "QStartNoAckMode", PACKET_DISABLE, remote_supported_packet,
PACKET_QStartNoAckMode },
{ "multiprocess", PACKET_DISABLE, remote_multi_process_feature, -1 },
PACKET_ConditionalTracepoints },
{ "ConditionalBreakpoints", PACKET_DISABLE, remote_cond_breakpoint_feature,
PACKET_ConditionalBreakpoints },
+ { "BreakpointCommands", PACKET_DISABLE, remote_breakpoint_commands_feature,
+ PACKET_BreakpointCommands },
{ "FastTracepoints", PACKET_DISABLE, remote_fast_tracepoint_feature,
PACKET_FastTracepoints },
{ "StaticTracepoints", PACKET_DISABLE, remote_static_tracepoint_feature,
remote_enable_disable_tracepoint_feature, -1 },
{ "qXfer:fdpic:read", PACKET_DISABLE, remote_supported_packet,
PACKET_qXfer_fdpic },
+ { "qXfer:uib:read", PACKET_DISABLE, remote_supported_packet,
+ PACKET_qXfer_uib },
{ "QDisableRandomization", PACKET_DISABLE, remote_supported_packet,
PACKET_QDisableRandomization },
+ { "QAgent", PACKET_DISABLE, remote_supported_packet, PACKET_QAgent},
{ "tracenz", PACKET_DISABLE,
remote_string_tracing_feature, -1 },
};
xfree (last_pass_packet);
last_pass_packet = NULL;
+ /* Make sure we send the program signals list the next time we
+ resume. */
+ xfree (last_program_signals_packet);
+ last_program_signals_packet = NULL;
+
remote_fileio_reset ();
reopen_exec_file ();
reread_symbols ();
/* Tell the remote target to detach. */
if (remote_multi_process_p (rs))
- sprintf (rs->buf, "D;%x", pid);
+ xsnprintf (rs->buf, get_remote_packet_size (), "D;%x", pid);
else
strcpy (rs->buf, "D");
gdb_flush (gdb_stdout);
}
- sprintf (rs->buf, "vAttach;%x", pid);
+ xsnprintf (rs->buf, get_remote_packet_size (), "vAttach;%x", pid);
putpkt (rs->buf);
getpkt (&rs->buf, &rs->buf_size, 0);
static char *
append_resumption (char *p, char *endp,
- ptid_t ptid, int step, enum target_signal siggnal)
+ ptid_t ptid, int step, enum gdb_signal siggnal)
{
struct remote_state *rs = get_remote_state ();
- if (step && siggnal != TARGET_SIGNAL_0)
+ if (step && siggnal != GDB_SIGNAL_0)
p += xsnprintf (p, endp - p, ";S%02x", siggnal);
else if (step)
p += xsnprintf (p, endp - p, ";s");
- else if (siggnal != TARGET_SIGNAL_0)
+ else if (siggnal != GDB_SIGNAL_0)
p += xsnprintf (p, endp - p, ";C%02x", siggnal);
else
p += xsnprintf (p, endp - p, ";c");
return p;
}
+/* Append a vCont continue-with-signal action for threads that have a
+ non-zero stop signal. */
+
+static char *
+append_pending_thread_resumptions (char *p, char *endp, ptid_t ptid)
+{
+ struct thread_info *thread;
+
+ ALL_THREADS (thread)
+ if (ptid_match (thread->ptid, ptid)
+ && !ptid_equal (inferior_ptid, thread->ptid)
+ && thread->suspend.stop_signal != GDB_SIGNAL_0
+ && signal_pass_state (thread->suspend.stop_signal))
+ {
+ p = append_resumption (p, endp, thread->ptid,
+ 0, thread->suspend.stop_signal);
+ thread->suspend.stop_signal = GDB_SIGNAL_0;
+ }
+
+ return p;
+}
+
/* Resume the remote inferior by using a "vCont" packet. The thread
to be resumed is PTID; STEP and SIGGNAL indicate whether the
resumed thread should be single-stepped and/or signalled. If PTID
moment. */
static int
-remote_vcont_resume (ptid_t ptid, int step, enum target_signal siggnal)
+remote_vcont_resume (ptid_t ptid, int step, enum gdb_signal siggnal)
{
struct remote_state *rs = get_remote_state ();
char *p;
process), with preference for INFERIOR_PTID. This assumes
inferior_ptid belongs to the set of all threads we are about
to resume. */
- if (step || siggnal != TARGET_SIGNAL_0)
+ if (step || siggnal != GDB_SIGNAL_0)
{
/* Step inferior_ptid, with or without signal. */
p = append_resumption (p, endp, inferior_ptid, step, siggnal);
}
+ /* Also pass down any pending signaled resumption for other
+ threads not the current. */
+ p = append_pending_thread_resumptions (p, endp, ptid);
+
/* And continue others without a signal. */
- append_resumption (p, endp, ptid, /*step=*/ 0, TARGET_SIGNAL_0);
+ append_resumption (p, endp, ptid, /*step=*/ 0, GDB_SIGNAL_0);
}
else
{
/* Tell the remote machine to resume. */
-static enum target_signal last_sent_signal = TARGET_SIGNAL_0;
+static enum gdb_signal last_sent_signal = GDB_SIGNAL_0;
static int last_sent_step;
static void
remote_resume (struct target_ops *ops,
- ptid_t ptid, int step, enum target_signal siggnal)
+ ptid_t ptid, int step, enum gdb_signal siggnal)
{
struct remote_state *rs = get_remote_state ();
char *buf;
if (execution_direction == EXEC_REVERSE)
{
/* We don't pass signals to the target in reverse exec mode. */
- if (info_verbose && siggnal != TARGET_SIGNAL_0)
+ if (info_verbose && siggnal != GDB_SIGNAL_0)
warning (_(" - Can't pass signal %d to target in reverse: ignored."),
siggnal);
strcpy (buf, step ? "bs" : "bc");
}
- else if (siggnal != TARGET_SIGNAL_0)
+ else if (siggnal != GDB_SIGNAL_0)
{
buf[0] = step ? 'S' : 'C';
buf[1] = tohex (((int) siggnal >> 4) & 0xf);
async_remote_interrupt (gdb_client_data arg)
{
if (remote_debug)
- fprintf_unfiltered (gdb_stdlog, "remote_interrupt called\n");
+ fprintf_unfiltered (gdb_stdlog, "async_remote_interrupt called\n");
target_stop (inferior_ptid);
}
async_remote_interrupt_twice (gdb_client_data arg)
{
if (remote_debug)
- fprintf_unfiltered (gdb_stdlog, "remote_interrupt_twice called\n");
+ fprintf_unfiltered (gdb_stdlog, "async_remote_interrupt_twice called\n");
interrupt_query ();
}
else
{
event->ws.kind = TARGET_WAITKIND_STOPPED;
- event->ws.value.sig = (enum target_signal)
+ event->ws.value.sig = (enum gdb_signal)
(((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
}
break;
{
/* The remote process exited with a signal. */
event->ws.kind = TARGET_WAITKIND_SIGNALLED;
- event->ws.value.sig = (enum target_signal) value;
+ event->ws.value.sig = (enum gdb_signal) value;
}
/* If no process is specified, assume inferior_ptid. */
ofunc = signal (SIGINT, remote_interrupt);
/* If the user hit C-c before this packet, or between packets,
pretend that it was hit right here. */
- if (quit_flag)
+ if (check_quit_flag ())
{
- quit_flag = 0;
+ clear_quit_flag ();
remote_interrupt (SIGINT);
}
}
not? Not is more likely, so report a stop. */
warning (_("Remote failure reply: %s"), buf);
status->kind = TARGET_WAITKIND_STOPPED;
- status->value.sig = TARGET_SIGNAL_0;
+ status->value.sig = GDB_SIGNAL_0;
break;
case 'F': /* File-I/O request. */
remote_fileio_request (buf, rs->ctrlc_pending_p);
break;
case '\0':
- if (last_sent_signal != TARGET_SIGNAL_0)
+ if (last_sent_signal != GDB_SIGNAL_0)
{
/* Zero length reply means that we tried 'S' or 'C' and the
remote system doesn't support it. */
target_terminal_ours_for_output ();
printf_filtered
("Can't send signals to this remote system. %s not sent.\n",
- target_signal_to_name (last_sent_signal));
- last_sent_signal = TARGET_SIGNAL_0;
+ gdb_signal_to_name (last_sent_signal));
+ last_sent_signal = GDB_SIGNAL_0;
target_terminal_inferior ();
strcpy ((char *) buf, last_sent_step ? "s" : "c");
struct remote_state *rs = get_remote_state ();
int buf_len;
- sprintf (rs->buf, "g");
+ xsnprintf (rs->buf, get_remote_packet_size (), "g");
remote_send (&rs->buf, &rs->buf_size);
/* We can get out of synch in various cases. If the first character
static int
remote_write_bytes_aux (const char *header, CORE_ADDR memaddr,
- const gdb_byte *myaddr, int len,
+ const gdb_byte *myaddr, ssize_t len,
char packet_format, int use_length)
{
struct remote_state *rs = get_remote_state ();
error. Only transfer a single packet. */
static int
-remote_write_bytes (CORE_ADDR memaddr, const gdb_byte *myaddr, int len)
+remote_write_bytes (CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len)
{
char *packet_format = 0;
/* Remote notification handler. */
static void
-handle_notification (char *buf, size_t length)
+handle_notification (char *buf)
{
if (strncmp (buf, "Stop:", 5) == 0)
{
str);
do_cleanups (old_chain);
}
- handle_notification (rs->buf, val);
+ handle_notification (rs->buf);
/* We're in sync now, rewait for the ack. */
tcount = 0;
}
do_cleanups (old_chain);
}
- handle_notification (*buf, val);
+ handle_notification (*buf);
/* Notifications require no acknowledgement. */
return -1;
/* Tell the remote target to detach. */
- sprintf (rs->buf, "vKill;%x", pid);
+ xsnprintf (rs->buf, get_remote_packet_size (), "vKill;%x", pid);
putpkt (rs->buf);
getpkt (&rs->buf, &rs->buf_size, 0);
struct remote_state *rs = get_remote_state ();
char *reply;
- sprintf (rs->buf, "QDisableRandomization:%x", val);
+ xsnprintf (rs->buf, get_remote_packet_size (), "QDisableRandomization:%x",
+ val);
putpkt (rs->buf);
reply = remote_get_noisy_reply (&target_buf, &target_buf_size);
if (*reply == '\0')
/* Given a location's target info BP_TGT and the packet buffer BUF, output
the list of conditions (in agent expression bytecode format), if any, the
target needs to evaluate. The output is placed into the packet buffer
- BUF. */
+ started from BUF and ended at BUF_END. */
static int
remote_add_target_side_condition (struct gdbarch *gdbarch,
- struct bp_target_info *bp_tgt, char *buf)
+ struct bp_target_info *bp_tgt, char *buf,
+ char *buf_end)
{
struct agent_expr *aexpr = NULL;
int i, ix;
return 0;
buf += strlen (buf);
- sprintf (buf, "%s", ";");
+ xsnprintf (buf, buf_end - buf, "%s", ";");
buf++;
/* Send conditions to the target and free the vector. */
VEC_iterate (agent_expr_p, bp_tgt->conditions, ix, aexpr);
ix++)
{
- sprintf (buf, "X%x,", aexpr->len);
+ xsnprintf (buf, buf_end - buf, "X%x,", aexpr->len);
buf += strlen (buf);
for (i = 0; i < aexpr->len; ++i)
buf = pack_hex_byte (buf, aexpr->buf[i]);
return 0;
}
+static void
+remote_add_target_side_commands (struct gdbarch *gdbarch,
+ struct bp_target_info *bp_tgt, char *buf)
+{
+ struct agent_expr *aexpr = NULL;
+ int i, ix;
+
+ if (VEC_empty (agent_expr_p, bp_tgt->tcommands))
+ return;
+
+ buf += strlen (buf);
+
+ sprintf (buf, ";cmds:%x,", bp_tgt->persist);
+ buf += strlen (buf);
+
+ /* Concatenate all the agent expressions that are commands into the
+ cmds parameter. */
+ for (ix = 0;
+ VEC_iterate (agent_expr_p, bp_tgt->tcommands, ix, aexpr);
+ ix++)
+ {
+ sprintf (buf, "X%x,", aexpr->len);
+ buf += strlen (buf);
+ for (i = 0; i < aexpr->len; ++i)
+ buf = pack_hex_byte (buf, aexpr->buf[i]);
+ *buf = '\0';
+ }
+
+ VEC_free (agent_expr_p, bp_tgt->tcommands);
+}
+
/* Insert a breakpoint. On targets that have software breakpoint
support, we ask the remote target to do the work; on targets
which don't, we insert a traditional memory breakpoint. */
{
CORE_ADDR addr = bp_tgt->placed_address;
struct remote_state *rs;
- char *p;
+ char *p, *endbuf;
int bpsize;
struct condition_list *cond = NULL;
rs = get_remote_state ();
p = rs->buf;
+ endbuf = rs->buf + get_remote_packet_size ();
*(p++) = 'Z';
*(p++) = '0';
*(p++) = ',';
addr = (ULONGEST) remote_address_masked (addr);
p += hexnumstr (p, addr);
- sprintf (p, ",%d", bpsize);
+ xsnprintf (p, endbuf - p, ",%d", bpsize);
if (remote_supports_cond_breakpoints ())
- remote_add_target_side_condition (gdbarch, bp_tgt, p);
+ remote_add_target_side_condition (gdbarch, bp_tgt, p, endbuf);
+
+ if (remote_can_run_breakpoint_commands ())
+ remote_add_target_side_commands (gdbarch, bp_tgt, p);
putpkt (rs->buf);
getpkt (&rs->buf, &rs->buf_size, 0);
if (remote_protocol_packets[PACKET_Z0].support != PACKET_DISABLE)
{
char *p = rs->buf;
+ char *endbuf = rs->buf + get_remote_packet_size ();
*(p++) = 'z';
*(p++) = '0';
addr = (ULONGEST) remote_address_masked (bp_tgt->placed_address);
p += hexnumstr (p, addr);
- sprintf (p, ",%d", bp_tgt->placed_size);
+ xsnprintf (p, endbuf - p, ",%d", bp_tgt->placed_size);
putpkt (rs->buf);
getpkt (&rs->buf, &rs->buf_size, 0);
struct expression *cond)
{
struct remote_state *rs = get_remote_state ();
+ char *endbuf = rs->buf + get_remote_packet_size ();
char *p;
enum Z_packet_type packet = watchpoint_to_Z_packet (type);
if (remote_protocol_packets[PACKET_Z0 + packet].support == PACKET_DISABLE)
return 1;
- sprintf (rs->buf, "Z%x,", packet);
+ xsnprintf (rs->buf, endbuf - rs->buf, "Z%x,", packet);
p = strchr (rs->buf, '\0');
addr = remote_address_masked (addr);
p += hexnumstr (p, (ULONGEST) addr);
- sprintf (p, ",%x", len);
+ xsnprintf (p, endbuf - p, ",%x", len);
putpkt (rs->buf);
getpkt (&rs->buf, &rs->buf_size, 0);
struct expression *cond)
{
struct remote_state *rs = get_remote_state ();
+ char *endbuf = rs->buf + get_remote_packet_size ();
char *p;
enum Z_packet_type packet = watchpoint_to_Z_packet (type);
if (remote_protocol_packets[PACKET_Z0 + packet].support == PACKET_DISABLE)
return -1;
- sprintf (rs->buf, "z%x,", packet);
+ xsnprintf (rs->buf, endbuf - rs->buf, "z%x,", packet);
p = strchr (rs->buf, '\0');
addr = remote_address_masked (addr);
p += hexnumstr (p, (ULONGEST) addr);
- sprintf (p, ",%x", len);
+ xsnprintf (p, endbuf - p, ",%x", len);
putpkt (rs->buf);
getpkt (&rs->buf, &rs->buf_size, 0);
{
CORE_ADDR addr;
struct remote_state *rs;
- char *p;
+ char *p, *endbuf;
/* The length field should be set to the size of a breakpoint
instruction, even though we aren't inserting one ourselves. */
rs = get_remote_state ();
p = rs->buf;
+ endbuf = rs->buf + get_remote_packet_size ();
*(p++) = 'Z';
*(p++) = '1';
addr = remote_address_masked (bp_tgt->placed_address);
p += hexnumstr (p, (ULONGEST) addr);
- sprintf (p, ",%x", bp_tgt->placed_size);
+ xsnprintf (p, endbuf - p, ",%x", bp_tgt->placed_size);
if (remote_supports_cond_breakpoints ())
- remote_add_target_side_condition (gdbarch, bp_tgt, p);
+ remote_add_target_side_condition (gdbarch, bp_tgt, p, endbuf);
+
+ if (remote_can_run_breakpoint_commands ())
+ remote_add_target_side_commands (gdbarch, bp_tgt, p);
putpkt (rs->buf);
getpkt (&rs->buf, &rs->buf_size, 0);
CORE_ADDR addr;
struct remote_state *rs = get_remote_state ();
char *p = rs->buf;
+ char *endbuf = rs->buf + get_remote_packet_size ();
if (remote_protocol_packets[PACKET_Z1].support == PACKET_DISABLE)
return -1;
addr = remote_address_masked (bp_tgt->placed_address);
p += hexnumstr (p, (ULONGEST) addr);
- sprintf (p, ",%x", bp_tgt->placed_size);
+ xsnprintf (p, endbuf - p, ",%x", bp_tgt->placed_size);
putpkt (rs->buf);
getpkt (&rs->buf, &rs->buf_size, 0);
case TARGET_OBJECT_FDPIC:
return remote_read_qxfer (ops, "fdpic", annex, readbuf, offset, len,
&remote_protocol_packets[PACKET_qXfer_fdpic]);
+
+ case TARGET_OBJECT_OPENVMS_UIB:
+ return remote_read_qxfer (ops, "uib", annex, readbuf, offset, len,
+ &remote_protocol_packets[PACKET_qXfer_uib]);
+
default:
return -1;
}
bfd *
remote_bfd_open (const char *remote_file, const char *target)
{
- return bfd_openr_iovec (remote_file, target,
- remote_bfd_iovec_open, NULL,
- remote_bfd_iovec_pread,
- remote_bfd_iovec_close,
- remote_bfd_iovec_stat);
+ bfd *abfd = gdb_bfd_openr_iovec (remote_file, target,
+ remote_bfd_iovec_open, NULL,
+ remote_bfd_iovec_pread,
+ remote_bfd_iovec_close,
+ remote_bfd_iovec_stat);
+
+ return abfd;
}
void
return rs->string_tracing;
}
+static int
+remote_can_run_breakpoint_commands (void)
+{
+ struct remote_state *rs = get_remote_state ();
+
+ return rs->breakpoint_commands;
+}
+
static void
remote_trace_init (void)
{
static void
remote_download_tracepoint (struct bp_location *loc)
{
+#define BUF_SIZE 2048
CORE_ADDR tpaddr;
char addrbuf[40];
- char buf[2048];
+ char buf[BUF_SIZE];
char **tdp_actions;
char **stepping_actions;
int ndx;
tpaddr = loc->address;
sprintf_vma (addrbuf, tpaddr);
- sprintf (buf, "QTDP:%x:%s:%c:%lx:%x", b->number,
- addrbuf, /* address */
- (b->enable_state == bp_enabled ? 'E' : 'D'),
- t->step_count, t->pass_count);
+ xsnprintf (buf, BUF_SIZE, "QTDP:%x:%s:%c:%lx:%x", b->number,
+ addrbuf, /* address */
+ (b->enable_state == bp_enabled ? 'E' : 'D'),
+ t->step_count, t->pass_count);
/* Fast tracepoints are mostly handled by the target, but we can
tell the target how big of an instruction block should be moved
around. */
if (gdbarch_fast_tracepoint_valid_at (target_gdbarch,
tpaddr, &isize, NULL))
- sprintf (buf + strlen (buf), ":F%x", isize);
+ xsnprintf (buf + strlen (buf), BUF_SIZE - strlen (buf), ":F%x",
+ isize);
else
/* If it passed validation at definition but fails now,
something is very wrong. */
{
aexpr = gen_eval_for_expr (tpaddr, loc->cond);
aexpr_chain = make_cleanup_free_agent_expr (aexpr);
- sprintf (buf + strlen (buf), ":X%x,", aexpr->len);
+ xsnprintf (buf + strlen (buf), BUF_SIZE - strlen (buf), ":X%x,",
+ aexpr->len);
pkt = buf + strlen (buf);
for (ndx = 0; ndx < aexpr->len; ++ndx)
pkt = pack_hex_byte (pkt, aexpr->buf[ndx]);
for (ndx = 0; tdp_actions[ndx]; ndx++)
{
QUIT; /* Allow user to bail out with ^C. */
- sprintf (buf, "QTDP:-%x:%s:%s%c",
- b->number, addrbuf, /* address */
- tdp_actions[ndx],
- ((tdp_actions[ndx + 1] || stepping_actions)
- ? '-' : 0));
+ xsnprintf (buf, BUF_SIZE, "QTDP:-%x:%s:%s%c",
+ b->number, addrbuf, /* address */
+ tdp_actions[ndx],
+ ((tdp_actions[ndx + 1] || stepping_actions)
+ ? '-' : 0));
putpkt (buf);
remote_get_noisy_reply (&target_buf,
&target_buf_size);
for (ndx = 0; stepping_actions[ndx]; ndx++)
{
QUIT; /* Allow user to bail out with ^C. */
- sprintf (buf, "QTDP:-%x:%s:%s%s%s",
- b->number, addrbuf, /* address */
- ((ndx == 0) ? "S" : ""),
- stepping_actions[ndx],
- (stepping_actions[ndx + 1] ? "-" : ""));
+ xsnprintf (buf, BUF_SIZE, "QTDP:-%x:%s:%s%s%s",
+ b->number, addrbuf, /* address */
+ ((ndx == 0) ? "S" : ""),
+ stepping_actions[ndx],
+ (stepping_actions[ndx + 1] ? "-" : ""));
putpkt (buf);
remote_get_noisy_reply (&target_buf,
&target_buf_size);
static int
remote_can_download_tracepoint (void)
{
- struct trace_status *ts = current_trace_status ();
- int status = remote_get_trace_status (ts);
+ struct remote_state *rs = get_remote_state ();
+ struct trace_status *ts;
+ int status;
+
+ /* Don't try to install tracepoints until we've relocated our
+ symbols, and fetched and merged the target's tracepoint list with
+ ours. */
+ if (rs->starting_up)
+ return 0;
+
+ ts = current_trace_status ();
+ status = remote_get_trace_status (ts);
if (status == -1 || !ts->running_known || !ts->running)
return 0;
struct remote_state *rs = get_remote_state ();
char *p;
- sprintf (rs->buf, "QTDV:%x:%s:%x:",
- tsv->number, phex ((ULONGEST) tsv->initial_value, 8), tsv->builtin);
+ xsnprintf (rs->buf, get_remote_packet_size (), "QTDV:%x:%s:%x:",
+ tsv->number, phex ((ULONGEST) tsv->initial_value, 8),
+ tsv->builtin);
p = rs->buf + strlen (rs->buf);
if ((p - rs->buf) + strlen (tsv->name) * 2 >= get_remote_packet_size ())
error (_("Trace state variable name too long for tsv definition packet"));
char addr_buf[40];
sprintf_vma (addr_buf, location->address);
- sprintf (rs->buf, "QTEnable:%x:%s", location->owner->number, addr_buf);
+ xsnprintf (rs->buf, get_remote_packet_size (), "QTEnable:%x:%s",
+ location->owner->number, addr_buf);
putpkt (rs->buf);
remote_get_noisy_reply (&rs->buf, &rs->buf_size);
if (*rs->buf == '\0')
char addr_buf[40];
sprintf_vma (addr_buf, location->address);
- sprintf (rs->buf, "QTDisable:%x:%s", location->owner->number, addr_buf);
+ xsnprintf (rs->buf, get_remote_packet_size (), "QTDisable:%x:%s",
+ location->owner->number, addr_buf);
putpkt (rs->buf);
remote_get_noisy_reply (&rs->buf, &rs->buf_size);
if (*rs->buf == '\0')
remote_trace_set_readonly_regions (void)
{
asection *s;
+ bfd *abfd = NULL;
bfd_size_type size;
bfd_vma vma;
int anysecs = 0;
continue;
anysecs = 1;
- vma = bfd_get_section_vma (,s);
+ vma = bfd_get_section_vma (abfd, s);
size = bfd_get_section_size (s);
sprintf_vma (tmp1, vma);
sprintf_vma (tmp2, vma + size);
Too many sections for read-only sections definition packet."));
break;
}
- sprintf (target_buf + offset, ":%s,%s", tmp1, tmp2);
+ xsnprintf (target_buf + offset, target_buf_size - offset, ":%s,%s",
+ tmp1, tmp2);
offset += sec_length;
}
if (anysecs)
char *reply;
struct bp_location *loc;
struct tracepoint *tp = (struct tracepoint *) bp;
+ size_t size = get_remote_packet_size ();
if (tp)
{
any status. */
if (tp->number_on_target == 0)
continue;
- sprintf (rs->buf, "qTP:%x:%s", tp->number_on_target,
- phex_nz (loc->address, 0));
+ xsnprintf (rs->buf, size, "qTP:%x:%s", tp->number_on_target,
+ phex_nz (loc->address, 0));
putpkt (rs->buf);
reply = remote_get_noisy_reply (&target_buf, &target_buf_size);
if (reply && *reply)
{
utp->hit_count = 0;
utp->traceframe_usage = 0;
- sprintf (rs->buf, "qTP:%x:%s", utp->number, phex_nz (utp->addr, 0));
+ xsnprintf (rs->buf, size, "qTP:%x:%s", utp->number,
+ phex_nz (utp->addr, 0));
putpkt (rs->buf);
reply = remote_get_noisy_reply (&target_buf, &target_buf_size);
if (reply && *reply)
int *tpp)
{
struct remote_state *rs = get_remote_state ();
+ char *endbuf = rs->buf + get_remote_packet_size ();
char *p, *reply;
int target_frameno = -1, target_tracept = -1;
switch (type)
{
case tfind_number:
- sprintf (p, "%x", num);
+ xsnprintf (p, endbuf - p, "%x", num);
break;
case tfind_pc:
- sprintf (p, "pc:%s", phex_nz (addr1, 0));
+ xsnprintf (p, endbuf - p, "pc:%s", phex_nz (addr1, 0));
break;
case tfind_tp:
- sprintf (p, "tdp:%x", num);
+ xsnprintf (p, endbuf - p, "tdp:%x", num);
break;
case tfind_range:
- sprintf (p, "range:%s:%s", phex_nz (addr1, 0), phex_nz (addr2, 0));
+ xsnprintf (p, endbuf - p, "range:%s:%s", phex_nz (addr1, 0),
+ phex_nz (addr2, 0));
break;
case tfind_outside:
- sprintf (p, "outside:%s:%s", phex_nz (addr1, 0), phex_nz (addr2, 0));
+ xsnprintf (p, endbuf - p, "outside:%s:%s", phex_nz (addr1, 0),
+ phex_nz (addr2, 0));
break;
default:
error (_("Unknown trace find type %d"), type);
set_remote_traceframe ();
- sprintf (rs->buf, "qTV:%x", tsvnum);
+ xsnprintf (rs->buf, get_remote_packet_size (), "qTV:%x", tsvnum);
putpkt (rs->buf);
reply = remote_get_noisy_reply (&target_buf, &target_buf_size);
if (reply && *reply)
{
char *reply;
- sprintf (rs->buf, "QTDisconnected:%x", val);
+ xsnprintf (rs->buf, get_remote_packet_size (), "QTDisconnected:%x", val);
putpkt (rs->buf);
reply = remote_get_noisy_reply (&target_buf, &target_buf_size);
if (*reply == '\0')
struct remote_state *rs = get_remote_state ();
char *reply;
- sprintf (rs->buf, "QTBuffer:circular:%x", val);
+ xsnprintf (rs->buf, get_remote_packet_size (), "QTBuffer:circular:%x", val);
putpkt (rs->buf);
reply = remote_get_noisy_reply (&target_buf, &target_buf_size);
if (*reply == '\0')
/* Make sure the remote is pointing at the right process. */
set_general_process ();
- sprintf (rs->buf, "qTMinFTPILen");
+ xsnprintf (rs->buf, get_remote_packet_size (), "qTMinFTPILen");
putpkt (rs->buf);
reply = remote_get_noisy_reply (&target_buf, &target_buf_size);
if (*reply == '\0')
return 1;
}
+static int
+remote_use_agent (int use)
+{
+ if (remote_protocol_packets[PACKET_QAgent].support != PACKET_DISABLE)
+ {
+ struct remote_state *rs = get_remote_state ();
+
+ /* If the stub supports QAgent. */
+ xsnprintf (rs->buf, get_remote_packet_size (), "QAgent:%d", use);
+ putpkt (rs->buf);
+ getpkt (&rs->buf, &rs->buf_size, 0);
+
+ if (strcmp (rs->buf, "OK") == 0)
+ {
+ use_agent = use;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int
+remote_can_use_agent (void)
+{
+ return (remote_protocol_packets[PACKET_QAgent].support != PACKET_DISABLE);
+}
+
static void
init_remote_ops (void)
{
remote_ops.to_load = generic_load;
remote_ops.to_mourn_inferior = remote_mourn;
remote_ops.to_pass_signals = remote_pass_signals;
+ remote_ops.to_program_signals = remote_program_signals;
remote_ops.to_thread_alive = remote_thread_alive;
remote_ops.to_find_new_threads = remote_threads_info;
remote_ops.to_pid_to_str = remote_pid_to_str;
remote_ops.to_supports_enable_disable_tracepoint = remote_supports_enable_disable_tracepoint;
remote_ops.to_supports_string_tracing = remote_supports_string_tracing;
remote_ops.to_supports_evaluation_of_breakpoint_conditions = remote_supports_cond_breakpoints;
+ remote_ops.to_can_run_breakpoint_commands = remote_can_run_breakpoint_commands;
remote_ops.to_trace_init = remote_trace_init;
remote_ops.to_download_tracepoint = remote_download_tracepoint;
remote_ops.to_can_download_tracepoint = remote_can_download_tracepoint;
remote_ops.to_static_tracepoint_markers_by_strid
= remote_static_tracepoint_markers_by_strid;
remote_ops.to_traceframe_info = remote_traceframe_info;
+ remote_ops.to_use_agent = remote_use_agent;
+ remote_ops.to_can_use_agent = remote_can_use_agent;
}
/* Set up the extended remote vector by making a copy of the standard
ui_out_field_string (uiout, "name", list->name);
ui_out_text (uiout, ": ");
if (list->type == show_cmd)
- do_setshow_command ((char *) NULL, from_tty, list);
+ do_show_command ((char *) NULL, from_tty, list);
else
cmd_func (list, NULL, from_tty);
/* Close the tuple. */
add_packet_config_cmd (&remote_protocol_packets[PACKET_QPassSignals],
"QPassSignals", "pass-signals", 0);
+ add_packet_config_cmd (&remote_protocol_packets[PACKET_QProgramSignals],
+ "QProgramSignals", "program-signals", 0);
+
add_packet_config_cmd (&remote_protocol_packets[PACKET_qSymbol],
"qSymbol", "symbol-lookup", 0);
(&remote_protocol_packets[PACKET_qXfer_traceframe_info],
"qXfer:trace-frame-info:read", "traceframe-info", 0);
+ add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_uib],
+ "qXfer:uib:read", "unwind-info-block", 0);
+
add_packet_config_cmd (&remote_protocol_packets[PACKET_qGetTLSAddr],
"qGetTLSAddr", "get-thread-local-storage-address",
0);
"ConditionalBreakpoints",
"conditional-breakpoints", 0);
+ add_packet_config_cmd (&remote_protocol_packets[PACKET_BreakpointCommands],
+ "BreakpointCommands",
+ "breakpoint-commands", 0);
+
add_packet_config_cmd (&remote_protocol_packets[PACKET_FastTracepoints],
"FastTracepoints", "fast-tracepoints", 0);
add_packet_config_cmd (&remote_protocol_packets[PACKET_QDisableRandomization],
"QDisableRandomization", "disable-randomization", 0);
+ add_packet_config_cmd (&remote_protocol_packets[PACKET_QAgent],
+ "QAgent", "agent", 0);
+
/* Keep the old ``set remote Z-packet ...'' working. Each individual
Z sub-packet has its own set and show commands, but users may
have sets to this variable in their .gdbinit files (or in their