long regnum; /* GDB's internal register number. */
LONGEST pnum; /* Remote protocol register number. */
int in_g_packet; /* Always part of G packet. */
- /* long size in bytes; == register_size (target_gdbarch (), regnum);
+ /* long size in bytes; == register_size (arch, regnum);
at present. */
- /* char *name; == gdbarch_register_name (target_gdbarch (), regnum);
+ /* char *name; == gdbarch_register_name (arch, regnum);
at present. */
};
/* Get the remote arch state for GDBARCH. */
struct remote_arch_state *get_remote_arch_state (struct gdbarch *gdbarch);
+ void create_async_event_handler ()
+ {
+ gdb_assert (m_async_event_handler_token == nullptr);
+ m_async_event_handler_token
+ = ::create_async_event_handler ([] (gdb_client_data data)
+ {
+ inferior_event_handler (INF_REG_EVENT);
+ },
+ nullptr, "remote");
+ }
+
+ void mark_async_event_handler ()
+ {
+ gdb_assert (this->is_async_p ());
+ ::mark_async_event_handler (m_async_event_handler_token);
+ }
+
+ void clear_async_event_handler ()
+ { ::clear_async_event_handler (m_async_event_handler_token); }
+
+ bool async_event_handler_marked () const
+ { return ::async_event_handler_marked (m_async_event_handler_token); }
+
+ void delete_async_event_handler ()
+ {
+ if (m_async_event_handler_token != nullptr)
+ ::delete_async_event_handler (&m_async_event_handler_token);
+ }
+
+ bool is_async_p () const
+ {
+ /* We're async whenever the serial device is. */
+ gdb_assert (this->remote_desc != nullptr);
+ return serial_is_async_p (this->remote_desc);
+ }
+
+ bool can_async_p () const
+ {
+ /* We can async whenever the serial device can. */
+ gdb_assert (this->remote_desc != nullptr);
+ return serial_can_async_p (this->remote_desc);
+ }
+
public: /* data */
/* A buffer to use for incoming packets, and its current size. The
immediately, so queue is not needed for them. */
std::vector<stop_reply_up> stop_reply_queue;
- /* Asynchronous signal handle registered as event loop source for
- when we have pending events ready to be passed to the core. */
- struct async_event_handler *remote_async_inferior_event_token = nullptr;
-
/* FIXME: cagney/1999-09-23: Even though getpkt was called with
``forever'' still use the normal timeout mechanism. This is
currently used by the ASYNC code to guarentee that target reads
modified to return a timeout indication and, in turn
remote_wait()/wait_for_inferior() have gained a timeout parameter
this can go away. */
- int wait_forever_enabled_p = 1;
+ bool wait_forever_enabled_p = true;
private:
+ /* Asynchronous signal handle registered as event loop source for
+ when we have pending events ready to be passed to the core. */
+ async_event_handler *m_async_event_handler_token = nullptr;
+
/* Mapping of remote protocol data for each gdbarch. Usually there
is only one entry here, though we may see more with stubs that
support multi-process. */
int get_trace_status (struct trace_status *ts) override;
- void get_tracepoint_status (struct breakpoint *tp, struct uploaded_tp *utp)
+ void get_tracepoint_status (tracepoint *tp, struct uploaded_tp *utp)
override;
void trace_stop () override;
void skip_frame ();
long read_frame (gdb::char_vector *buf_p);
- int getpkt_or_notif_sane_1 (gdb::char_vector *buf, int forever,
- int expecting_notif, int *is_notif);
- int getpkt (gdb::char_vector *buf, int forever);
- int getpkt_or_notif_sane (gdb::char_vector *buf, int forever,
- int *is_notif);
+ int getpkt (gdb::char_vector *buf, bool forever = false,
+ bool *is_notif = nullptr);
int remote_vkill (int pid);
void remote_kill_k ();
/* The variable registered as the control variable used by the
remote exec-file commands. While the remote exec-file setting is
- per-program-space, the set/show machinery uses this as the
+ per-program-space, the set/show machinery uses this as the
location of the remote exec-file value. */
static std::string remote_exec_file_var;
static ptid_t read_ptid (const char *buf, const char **obuf);
-static void remote_async_inferior_event_handler (gdb_client_data);
-
static bool remote_read_description_p (struct target_ops *target);
static void remote_console_output (const char *msg);
char *buf;
QUIT; /* Allow user to bail out with ^C. */
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
buf = rs->buf.data ();
if (buf[0] == 'E')
trace_error (buf);
try
{
- gdbarch_relocate_instruction (target_gdbarch (), &to, from);
+ gdbarch_relocate_instruction (current_inferior ()->arch (),
+ &to, from);
relocated = 1;
}
catch (const gdb_exception &ex)
function which calls getpkt also needs to be mindful of changes
to rs->buf, but this call limits the number of places which run
into trouble. */
- m_remote_state.get_remote_arch_state (target_gdbarch ());
+ m_remote_state.get_remote_arch_state (current_inferior ()->arch ());
return &m_remote_state;
}
remote_target::get_remote_packet_size ()
{
struct remote_state *rs = get_remote_state ();
- remote_arch_state *rsa = rs->get_remote_arch_state (target_gdbarch ());
+ remote_arch_state *rsa
+ = rs->get_remote_arch_state (current_inferior ()->arch ());
if (rs->explicit_packet_size)
return rs->explicit_packet_size;
remote_target::get_memory_packet_size (struct memory_packet_config *config)
{
struct remote_state *rs = get_remote_state ();
- remote_arch_state *rsa = rs->get_remote_arch_state (target_gdbarch ());
+ remote_arch_state *rsa
+ = rs->get_remote_arch_state (current_inferior ()->arch ());
long what_they_get;
if (config->fixed_p)
xsnprintf (rs->buf.data (), size, "qAttached");
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
switch (m_features.packet_ok (rs->buf, PACKET_qAttached))
{
if (attached == -1)
attached = remote_query_attached (pid);
- if (gdbarch_has_global_solist (target_gdbarch ()))
+ if (gdbarch_has_global_solist (current_inferior ()->arch ()))
{
/* If the target shares code across all inferiors, then every
attach adds a new inferior. */
if (!rs->last_pass_packet || strcmp (rs->last_pass_packet, pass_packet))
{
putpkt (pass_packet);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
m_features.packet_ok (rs->buf, PACKET_QPassSignals);
xfree (rs->last_pass_packet);
rs->last_pass_packet = pass_packet;
struct remote_state *rs = get_remote_state ();
putpkt (catch_packet);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
result = m_features.packet_ok (rs->buf, PACKET_QCatchSyscalls);
if (result == PACKET_OK)
return 0;
|| strcmp (rs->last_program_signals_packet, packet) != 0)
{
putpkt (packet);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
m_features.packet_ok (rs->buf, PACKET_QProgramSignals);
xfree (rs->last_program_signals_packet);
rs->last_program_signals_packet = packet;
else
write_ptid (buf, endbuf, ptid);
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
if (gen)
rs->general_thread = ptid;
else
write_ptid (p, endp, ptid);
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
return (rs->buf[0] == 'O' && rs->buf[1] == 'K');
}
pack_threadinfo_request (rs->buf.data (), fieldset, threadid);
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
if (rs->buf[0] == '\0')
return 0;
pack_threadlist_request (rs->buf.data (), startflag, result_limit,
nextthread);
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
if (rs->buf[0] == '\0')
{
/* Packet not supported. */
struct remote_state *rs = get_remote_state ();
putpkt ("qC");
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
if (rs->buf[0] == 'Q' && rs->buf[1] == 'C')
{
const char *obuf;
const char *bufp;
putpkt ("qfThreadInfo");
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
bufp = rs->buf.data ();
if (bufp[0] != '\0') /* q packet recognized */
{
}
while (*bufp++ == ','); /* comma-separated list */
putpkt ("qsThreadInfo");
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
bufp = rs->buf.data ();
}
return 1;
write_ptid (b, endb, tp->ptid);
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
if (rs->buf[0] != 0)
{
extra.resize (strlen (rs->buf.data ()) / 2);
p += strlen (p);
p += hexnumstr (p, addr);
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
p = rs->buf.data ();
if (*p == 'E')
/* Ask for a first packet of static tracepoint marker
definition. */
putpkt ("qTfSTM");
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
p = rs->buf.data ();
if (*p == 'E')
error (_("Remote failure reply: %s"), p);
while (*p++ == ','); /* comma-separated list */
/* Ask for another packet of static tracepoint definition. */
putpkt ("qTsSTM");
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
p = rs->buf.data ();
}
everything of this target. */
discard_pending_stop_replies_in_queue ();
- if (rs->remote_async_inferior_event_token)
- delete_async_event_handler (&rs->remote_async_inferior_event_token);
+ rs->delete_async_event_handler ();
delete rs->notif_state;
}
return;
putpkt ("qOffsets");
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
buf = rs->buf.data ();
if (buf[0] == '\000')
const char v_mustreplyempty[] = "vMustReplyEmpty";
putpkt (v_mustreplyempty);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
if (strcmp (rs->buf.data (), "OK") == 0)
{
m_features.m_protocol_packets[PACKET_vFile_setfs].support
if (m_features.packet_support (PACKET_QStartNoAckMode) != PACKET_DISABLE)
{
putpkt ("QStartNoAckMode");
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
if (m_features.packet_ok (rs->buf, PACKET_QStartNoAckMode) == PACKET_OK)
rs->noack_mode = 1;
}
{
/* Tell the remote that we are using the extended protocol. */
putpkt ("!");
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
}
/* Let the target know which signals it is allowed to pass down to
/* On OSs where the list of libraries is global to all
processes, we fetch them early. */
- if (gdbarch_has_global_solist (target_gdbarch ()))
+ if (gdbarch_has_global_solist (current_inferior ()->arch ()))
solib_add (NULL, from_tty, auto_solib_add);
if (target_is_non_stop_p ())
"does not support non-stop"));
putpkt ("QNonStop:1");
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
if (strcmp (rs->buf.data (), "OK") != 0)
error (_("Remote refused setting non-stop mode with: %s"),
/* Don't assume that the stub can operate in all-stop mode.
Request it explicitly. */
putpkt ("QNonStop:0");
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
if (strcmp (rs->buf.data (), "OK") != 0)
error (_("Remote refused setting all-stop mode with: %s"),
/* Check whether the target is running now. */
putpkt ("?");
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
if (!target_is_non_stop_p ())
{
supported for non-stop; it could be, but it is tricky if
there are no stopped threads when we connect. */
if (remote_read_description_p (this)
- && gdbarch_target_desc (target_gdbarch ()) == NULL)
+ && gdbarch_target_desc (current_inferior ()->arch ()) == NULL)
{
target_clear_description ();
target_find_description ();
/* Invite target to request symbol lookups. */
putpkt ("qSymbol::");
- getpkt (&reply, 0);
+ getpkt (&reply);
m_features.packet_ok (reply, PACKET_qSymbol);
while (startswith (reply.data (), "qSymbol:"))
&reply[8]);
else
{
- int addr_size = gdbarch_addr_bit (target_gdbarch ()) / 8;
+ int addr_size = gdbarch_addr_bit (current_inferior ()->arch ()) / 8;
CORE_ADDR sym_addr = sym.value_address ();
/* If this is a function address, return the start of code
instead of any data function descriptor. */
sym_addr = gdbarch_convert_from_func_ptr_addr
- (target_gdbarch (), sym_addr, current_inferior ()->top_target ());
+ (current_inferior ()->arch (), sym_addr,
+ current_inferior ()->top_target ());
xsnprintf (msg.data (), get_remote_packet_size (), "qSymbol:%s:%s",
phex_nz (sym_addr, addr_size), &reply[8]);
}
putpkt (msg.data ());
- getpkt (&reply, 0);
+ getpkt (&reply);
}
}
may_insert_breakpoints, may_insert_tracepoints,
may_insert_fast_tracepoints, may_stop);
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
/* If the target didn't like the packet, warn the user. Do not try
to undo the user's settings, that would just be maddening. */
q = "qSupported:" + q;
putpkt (q.c_str ());
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
/* If an error occurred, warn, but do not return - just reset the
buffer to empty and go on to disable features. */
/* See FIXME above. */
if (!target_async_permitted)
- rs->wait_forever_enabled_p = 1;
+ rs->wait_forever_enabled_p = true;
rs->remote_desc = remote_serial_open (name);
if (!rs->remote_desc)
current_inferior ()->push_target (std::move (target_holder));
/* Register extra event sources in the event loop. */
- rs->remote_async_inferior_event_token
- = create_async_event_handler (remote_async_inferior_event_handler, nullptr,
- "remote");
+ rs->create_async_event_handler ();
+
rs->notif_state = remote_notif_state_allocate (remote);
/* Reset the target state; these things will be queried either by
around this. Eventually a mechanism that allows
wait_for_inferior() to expect/get timeouts will be
implemented. */
- rs->wait_forever_enabled_p = 0;
+ rs->wait_forever_enabled_p = false;
}
/* First delete any symbols previously loaded from shared libraries. */
remote_btrace_reset (rs);
if (target_async_permitted)
- rs->wait_forever_enabled_p = 1;
+ rs->wait_forever_enabled_p = true;
}
/* Determine if WS represents a fork status. */
strcpy (rs->buf.data (), "D");
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
if (rs->buf[0] == 'O' && rs->buf[1] == 'K')
;
target_announce_detach (from_tty);
- if (!gdbarch_has_global_breakpoints (target_gdbarch ()))
+ if (!gdbarch_has_global_breakpoints (current_inferior ()->arch ()))
{
/* If we're in breakpoints-always-inserted mode, or the inferior
is running, we have to remove breakpoints before detaching.
xsnprintf (rs->buf.data (), get_remote_packet_size (), "vAttach;%x", pid);
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
switch (m_features.packet_ok (rs->buf, PACKET_vAttach))
{
strcpy (rs->buf.data (), "vCont?");
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
buf = rs->buf.data ();
/* Make sure that the features we assume are supported. */
if (tp->control.may_range_step)
{
- int addr_size = gdbarch_addr_bit (target_gdbarch ()) / 8;
+ int addr_size = gdbarch_addr_bit (current_inferior ()->arch ()) / 8;
p += xsnprintf (p, endp - p, ";r%s,%s",
phex_nz (tp->control.step_range_start,
/* In non-stop, the stub replies to vCont with "OK". The stop
reply will be reported asynchronously by means of a `%Stop'
notification. */
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
if (strcmp (rs->buf.data (), "OK") != 0)
error (_("Unexpected vCont reply in non-stop mode: %s"),
rs->buf.data ());
rs = m_remote->get_remote_state ();
m_remote->putpkt (rs->buf);
- m_remote->getpkt (&rs->buf, 0);
+ m_remote->getpkt (&rs->buf);
if (strcmp (rs->buf.data (), "OK") != 0)
error (_("Unexpected vCont reply in non-stop mode: %s"), rs->buf.data ());
}
{
remote_state *rs = get_remote_state ();
- if (async_event_handler_marked (rs->remote_async_inferior_event_token))
+ if (rs->async_event_handler_marked ())
return true;
/* Note that BUFCNT can be negative, indicating sticky
sr->ptid = tp->ptid;
sr->rs = rs;
sr->ws.set_stopped (GDB_SIGNAL_0);
- sr->arch = tp->inf->gdbarch;
+ sr->arch = tp->inf->arch ();
sr->stop_reason = TARGET_STOPPED_BY_NO_REASON;
sr->watch_data_address = 0;
sr->core = 0;
/* In non-stop, we get an immediate OK reply. The stop reply will
come in asynchronously by notification. */
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
if (strcmp (rs->buf.data (), "OK") != 0)
error (_("Stopping %s failed: %s"), target_pid_to_str (ptid).c_str (),
rs->buf.data ());
/* In non-stop, we get an immediate OK reply. The stop reply will
come in asynchronously by notification. */
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
switch (m_features.packet_ok (rs->buf, PACKET_vCtrlC))
{
may exit and we have no chance to process them back in
remote_wait_ns. */
remote_state *rs = remote->get_remote_state ();
- mark_async_event_handler (rs->remote_async_inferior_event_token);
+ rs->mark_async_event_handler ();
return 0;
}
if (!rs->stop_reply_queue.empty () && target_can_async_p ())
{
/* There's still at least an event left. */
- mark_async_event_handler (rs->remote_async_inferior_event_token);
+ rs->mark_async_event_handler ();
}
return r;
enabled, and there are events in this queue, we will mark the event
token at that point, see remote_target::async. */
if (target_is_async_p ())
- mark_async_event_handler (rs->remote_async_inferior_event_token);
+ rs->mark_async_event_handler ();
}
/* Returns true if we have a stop reply for PTID. */
continue;
}
- event->arch = inf->gdbarch;
+ event->arch = inf->arch ();
rsa = event->rs->get_remote_arch_state (event->arch);
}
while (1)
{
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
if (strcmp (rs->buf.data (), "OK") == 0)
break;
else
struct remote_state *rs = get_remote_state ();
struct stop_reply *stop_reply;
int ret;
- int is_notif = 0;
+ bool is_notif = false;
/* If in non-stop mode, get out of getpkt even if a
notification is received. */
- ret = getpkt_or_notif_sane (&rs->buf, 0 /* forever */, &is_notif);
+ ret = getpkt (&rs->buf, false /* forever */, &is_notif);
while (1)
{
if (ret != -1 && !is_notif)
}
/* Otherwise do a blocking wait. */
- ret = getpkt_or_notif_sane (&rs->buf, 1 /* forever */, &is_notif);
+ ret = getpkt (&rs->buf, true /* forever */, &is_notif);
}
}
}
else
{
- int forever = ((options & TARGET_WNOHANG) == 0
- && rs->wait_forever_enabled_p);
+ bool forever = ((options & TARGET_WNOHANG) == 0
+ && rs->wait_forever_enabled_p);
if (!rs->waiting_for_stop_reply)
{
_never_ wait for ever -> test on target_is_async_p().
However, before we do that we need to ensure that the caller
knows how to take the target into/out of async mode. */
- int is_notif;
- int ret = getpkt_or_notif_sane (&rs->buf, forever, &is_notif);
+ bool is_notif;
+ int ret = getpkt (&rs->buf, forever, &is_notif);
/* GDB gets a notification. Return to core as this event is
not interesting. */
we'll mark it again at the end if needed. If the target is not in
async mode then the async token should not be marked. */
if (target_is_async_p ())
- clear_async_event_handler (rs->remote_async_inferior_event_token);
+ rs->clear_async_event_handler ();
else
- gdb_assert (!async_event_handler_marked
- (rs->remote_async_inferior_event_token));
+ gdb_assert (!rs->async_event_handler_marked ());
ptid_t event_ptid;
notifications, then tell the event loop to call us again. */
if (!rs->stop_reply_queue.empty ()
|| rs->notif_state->pending_event[notif_client_stop.id] != nullptr)
- mark_async_event_handler (rs->remote_async_inferior_event_token);
+ rs->mark_async_event_handler ();
}
return event_ptid;
p += hexnumstr (p, reg->pnum);
*p++ = '\0';
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
buf = rs->buf.data ();
return 0;
case PACKET_ERROR:
error (_("Could not fetch register \"%s\"; remote failure reply '%s'"),
- gdbarch_register_name (regcache->arch (),
- reg->regnum),
+ gdbarch_register_name (regcache->arch (), reg->regnum),
buf);
}
xsnprintf (rs->buf.data (), get_remote_packet_size (), "g");
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
if (packet_check_result (rs->buf) == PACKET_ERROR)
error (_("Could not read registers; remote failure reply '%s'"),
rs->buf.data ());
&& rs->buf[0] != 'x') /* New: unavailable register value. */
{
remote_debug_printf ("Bad register packet; fetching a new packet");
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
}
buf_len = strlen (rs->buf.data ());
regcache->raw_collect (reg->regnum, regp);
bin2hex (regp, p, register_size (gdbarch, reg->regnum));
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
switch (m_features.packet_ok (rs->buf, PACKET_P))
{
*p++ = 'G';
bin2hex (regs, p, rsa->sizeof_g_packet);
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
if (packet_check_result (rs->buf) == PACKET_ERROR)
- error (_("Could not write registers; remote failure reply '%s'"),
+ error (_("Could not write registers; remote failure reply '%s'"),
rs->buf.data ());
}
/* If "remoteaddresssize" was not set, default to target address size. */
if (!address_size)
- address_size = gdbarch_addr_bit (target_gdbarch ());
+ address_size = gdbarch_addr_bit (current_inferior ()->arch ());
if (address_size > 0
&& address_size < (sizeof (ULONGEST) * 8))
*p = '\0';
putpkt_binary (rs->buf.data (), (int) (p - rs->buf.data ()));
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
if (rs->buf[0] == '\0')
{
}
putpkt_binary (rs->buf.data (), (int) (p - rs->buf.data ()));
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
if (rs->buf[0] == 'E')
return TARGET_XFER_E_IO;
p += hexnumstr (p, (ULONGEST) todo_units);
*p = '\0';
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
if (rs->buf[0] == 'E'
&& isxdigit (rs->buf[1]) && isxdigit (rs->buf[2])
&& rs->buf[3] == '\0')
{
ULONGEST memend = memaddr + len;
- const target_section_table *table = target_get_section_table (this);
+ const std::vector<target_section> *table
+ = target_get_section_table (this);
for (const target_section &p : *table)
{
if (memaddr >= p.addr)
error (_("Communication problem with target."));
rs->buf[0] = '\0';
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
return packet_check_result (rs->buf);
}
void
remote_target::flash_erase (ULONGEST address, LONGEST length)
{
- int addr_size = gdbarch_addr_bit (target_gdbarch ()) / 8;
+ int addr_size = gdbarch_addr_bit (current_inferior ()->arch ()) / 8;
enum packet_result ret;
scoped_restore restore_timeout
= make_scoped_restore (&remote_timeout, remote_flash_timeout);
store it in *BUF. Resize *BUF if necessary to hold the result. If
FOREVER, wait forever rather than timing out; this is used (in
synchronous mode) to wait for a target that is is executing user
- code to stop. If FOREVER == 0, this function is allowed to time
+ code to stop. If FOREVER == false, this function is allowed to time
out gracefully and return an indication of this to the caller.
- Otherwise return the number of bytes read. If EXPECTING_NOTIF,
- consider receiving a notification enough reason to return to the
- caller. *IS_NOTIF is an output boolean that indicates whether *BUF
- holds a notification or not (a regular packet). */
+ Otherwise return the number of bytes read. If IS_NOTIF is not
+ NULL, then consider receiving a notification enough reason to
+ return to the caller. In this case, *IS_NOTIF is an output boolean
+ that indicates whether *BUF holds a notification or not (a regular
+ packet). */
int
-remote_target::getpkt_or_notif_sane_1 (gdb::char_vector *buf,
- int forever, int expecting_notif,
- int *is_notif)
+remote_target::getpkt (gdb::char_vector *buf, bool forever, bool *is_notif)
{
struct remote_state *rs = get_remote_state ();
int c;
if (forever)
timeout = watchdog > 0 ? watchdog : -1;
- else if (expecting_notif)
+ else if (is_notif != nullptr)
timeout = 0; /* There should already be a char in the buffer. If
not, bail out. */
else
if (c == SERIAL_TIMEOUT)
{
- if (expecting_notif)
+ if (is_notif != nullptr)
return -1; /* Don't complain, it's normal to not get
anything in this case. */
if (!rs->noack_mode)
remote_serial_write ("+", 1);
if (is_notif != NULL)
- *is_notif = 0;
+ *is_notif = false;
return val;
}
escape_buffer (buf->data (), val).c_str ());
if (is_notif != NULL)
- *is_notif = 1;
+ *is_notif = true;
handle_notification (rs->notif_state, buf->data ());
/* Notifications require no acknowledgement. */
- if (expecting_notif)
+ if (is_notif != nullptr)
return val;
}
}
}
-/* Read a packet from the remote machine, with error checking, and
- store it in *BUF. Resize *BUF if necessary to hold the result. If
- FOREVER, wait forever rather than timing out; this is used (in
- synchronous mode) to wait for a target that is is executing user
- code to stop. */
-
-int
-remote_target::getpkt (gdb::char_vector *buf, int forever)
-{
- return getpkt_or_notif_sane_1 (buf, forever, 0, NULL);
-}
-
-int
-remote_target::getpkt_or_notif_sane (gdb::char_vector *buf, int forever,
- int *is_notif)
-{
- return getpkt_or_notif_sane_1 (buf, forever, 1, is_notif);
-}
-
/* Kill any new fork children of inferior INF that haven't been
processed by follow_fork. */
/* Tell the remote target to detach. */
xsnprintf (rs->buf.data (), get_remote_packet_size (), "vKill;%x", pid);
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
switch (m_features.packet_ok (rs->buf, PACKET_vKill))
{
rs->buf[len++] = '\0';
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
switch (m_features.packet_ok (rs->buf, PACKET_vRun))
{
"%s:%s", packet, encoded_value.c_str ());
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
if (strcmp (rs->buf.data (), "OK") != 0)
warning (_("Unable to %s environment variable '%s' on remote."),
action, value);
if (m_features.packet_support (PACKET_QEnvironmentReset) != PACKET_DISABLE)
{
putpkt ("QEnvironmentReset");
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
if (strcmp (rs->buf.data (), "OK") != 0)
warning (_("Unable to reset environment on remote."));
}
}
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
if (m_features.packet_ok (rs->buf, PACKET_QSetWorkingDir) != PACKET_OK)
error (_("\
Remote replied unexpectedly while setting the inferior's working\n\
xsnprintf (rs->buf.data (), get_remote_packet_size (),
"QStartupWithShell:%d", startup_with_shell ? 1 : 0);
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
if (strcmp (rs->buf.data (), "OK") != 0)
error (_("\
Remote replied unexpectedly while setting startup-with-shell: %s"),
/* Make sure the remote is pointing at the right process, if
necessary. */
- if (!gdbarch_has_global_breakpoints (target_gdbarch ()))
+ if (!gdbarch_has_global_breakpoints (current_inferior ()->arch ()))
set_general_process ();
rs = get_remote_state ();
remote_add_target_side_commands (gdbarch, bp_tgt, p);
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
switch (m_features.packet_ok (rs->buf, PACKET_Z0))
{
/* Make sure the remote is pointing at the right process, if
necessary. */
- if (!gdbarch_has_global_breakpoints (target_gdbarch ()))
+ if (!gdbarch_has_global_breakpoints (current_inferior ()->arch ()))
set_general_process ();
*(p++) = 'z';
xsnprintf (p, endbuf - p, ",%d", bp_tgt->kind);
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
return (rs->buf[0] == 'E');
}
/* Make sure the remote is pointing at the right process, if
necessary. */
- if (!gdbarch_has_global_breakpoints (target_gdbarch ()))
+ if (!gdbarch_has_global_breakpoints (current_inferior ()->arch ()))
set_general_process ();
xsnprintf (rs->buf.data (), endbuf - rs->buf.data (), "Z%x,", packet);
xsnprintf (p, endbuf - p, ",%x", len);
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
switch (m_features.packet_ok (rs->buf, (to_underlying (PACKET_Z0)
+ to_underlying (packet))))
/* Make sure the remote is pointing at the right process, if
necessary. */
- if (!gdbarch_has_global_breakpoints (target_gdbarch ()))
+ if (!gdbarch_has_global_breakpoints (current_inferior ()->arch ()))
set_general_process ();
xsnprintf (rs->buf.data (), endbuf - rs->buf.data (), "z%x,", packet);
p += hexnumstr (p, (ULONGEST) addr);
xsnprintf (p, endbuf - p, ",%x", len);
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
switch (m_features.packet_ok (rs->buf, (to_underlying (PACKET_Z0)
+ to_underlying (packet))))
/* Make sure the remote is pointing at the right process, if
necessary. */
- if (!gdbarch_has_global_breakpoints (target_gdbarch ()))
+ if (!gdbarch_has_global_breakpoints (current_inferior ()->arch ()))
set_general_process ();
rs = get_remote_state ();
remote_add_target_side_commands (gdbarch, bp_tgt, p);
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
switch (m_features.packet_ok (rs->buf, PACKET_Z1))
{
/* Make sure the remote is pointing at the right process, if
necessary. */
- if (!gdbarch_has_global_breakpoints (target_gdbarch ()))
+ if (!gdbarch_has_global_breakpoints (current_inferior ()->arch ()))
set_general_process ();
*(p++) = 'z';
xsnprintf (p, endbuf - p, ",%x", bp_tgt->kind);
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
switch (m_features.packet_ok (rs->buf, PACKET_Z1))
{
reply. */
host_crc = xcrc32 (data, size, 0xffffffff);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
result = m_features.packet_ok (rs->buf, PACKET_qCRC);
if (result == PACKET_ERROR)
if (res == -1)
error (_("target memory fault, section %s, range %s -- %s"), sectname,
- paddress (target_gdbarch (), lma),
- paddress (target_gdbarch (), lma + size));
+ paddress (current_inferior ()->arch (), lma),
+ paddress (current_inferior ()->arch (), lma + size));
gdb_printf ("Section %s, range %s -- %s: ", sectname,
- paddress (target_gdbarch (), lma),
- paddress (target_gdbarch (), lma + size));
+ paddress (current_inferior ()->arch (), lma),
+ paddress (current_inferior ()->arch (), lma + size));
if (res)
gdb_printf ("matched.\n");
else
int i, buf_len;
ULONGEST n;
struct remote_state *rs = get_remote_state ();
- int max_size = get_memory_write_packet_size ();
+ int max_size = get_memory_write_packet_size ();
if (m_features.packet_support (which_packet) == PACKET_DISABLE)
return TARGET_XFER_E_IO;
/* Insert header. */
- i = snprintf (rs->buf.data (), max_size,
+ i = snprintf (rs->buf.data (), max_size,
"qXfer:%s:write:%s:%s:",
object_name, annex ? annex : "",
phex_nz (offset, sizeof offset));
max_size -= (i + 1);
/* Escape as much data as fits into rs->buf. */
- buf_len = remote_escape_output
+ buf_len = remote_escape_output
(writebuf, len, 1, (gdb_byte *) rs->buf.data () + i, &max_size, max_size);
if (putpkt_binary (rs->buf.data (), i + buf_len) < 0
- || getpkt (&rs->buf, 0) < 0
+ || getpkt (&rs->buf) < 0
|| m_features.packet_ok (rs->buf, which_packet) != PACKET_OK)
return TARGET_XFER_E_IO;
return TARGET_XFER_E_IO;
rs->buf[0] = '\0';
- packet_len = getpkt (&rs->buf, 0);
+ packet_len = getpkt (&rs->buf);
if (packet_len < 0
|| m_features.packet_ok (rs->buf, which_packet) != PACKET_OK)
return TARGET_XFER_E_IO;
int i;
char *p2;
char query_type;
- int unit_size = gdbarch_addressable_memory_unit_size (target_gdbarch ());
+ int unit_size
+ = gdbarch_addressable_memory_unit_size (current_inferior ()->arch ());
set_remote_traceframe ();
set_general_thread (inferior_ptid);
if (i < 0)
return TARGET_XFER_E_IO;
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
strcpy ((char *) readbuf, rs->buf.data ());
*xfered_len = strlen ((char *) readbuf);
const gdb_byte *pattern, ULONGEST pattern_len,
CORE_ADDR *found_addrp)
{
- int addr_size = gdbarch_addr_bit (target_gdbarch ()) / 8;
+ int addr_size = gdbarch_addr_bit (current_inferior ()->arch ()) / 8;
struct remote_state *rs = get_remote_state ();
int max_size = get_memory_write_packet_size ();
set_general_process ();
/* Insert header. */
- i = snprintf (rs->buf.data (), max_size,
+ i = snprintf (rs->buf.data (), max_size,
"qSearch:memory:%s;%s;",
phex_nz (start_addr, addr_size),
phex_nz (search_space_len, sizeof (search_space_len)));
error (_("Pattern is too large to transmit to remote target."));
if (putpkt_binary (rs->buf.data (), i + escaped_pattern_len) < 0
- || getpkt (&rs->buf, 0) < 0
+ || getpkt (&rs->buf) < 0
|| m_features.packet_ok (rs->buf, PACKET_qSearch_memory) != PACKET_OK)
{
/* The request may not have worked because the command is not
/* XXX - see also remote_get_noisy_reply(). */
QUIT; /* Allow user to bail out with ^C. */
rs->buf[0] = '\0';
- if (getpkt (&rs->buf, 0) == -1)
- {
+ if (getpkt (&rs->buf) == -1)
+ {
/* Timeout. Continue to (try to) read responses.
This is better than stopping with an error, assuming the stub
is still executing the (long) monitor command.
remote->putpkt_binary (buf.data (), buf.size ());
remote_state *rs = remote->get_remote_state ();
- int bytes = remote->getpkt (&rs->buf, 0);
+ int bytes = remote->getpkt (&rs->buf);
if (bytes < 0)
error (_("error while fetching packet from remote target"));
*p++ = '\0';
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
result = m_features.packet_ok (rs->buf, PACKET_qGetTLSAddr);
if (result == PACKET_OK)
{
*p++ = '\0';
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
result = m_features.packet_ok (rs->buf, PACKET_qGetTIBAddr);
if (result == PACKET_OK)
{
static bool
remote_read_description_p (struct target_ops *target)
{
- struct remote_g_packet_data *data = get_g_packet_data (target_gdbarch ());
+ remote_g_packet_data *data = get_g_packet_data (current_inferior ()->arch ());
return !data->guesses.empty ();
}
const struct target_desc *
remote_target::read_description ()
{
- struct remote_g_packet_data *data = get_g_packet_data (target_gdbarch ());
+ remote_g_packet_data *data = get_g_packet_data (current_inferior ()->arch ());
/* Do not try this during initial connection, when we do not know
whether there is a running but stopped thread. */
}
putpkt_binary (rs->buf.data (), command_bytes);
- bytes_read = getpkt (&rs->buf, 0);
+ bytes_read = getpkt (&rs->buf);
/* If it timed out, something is wrong. Don't try to parse the
buffer. */
std::vector<std::string> stepping_actions;
char *pkt;
struct breakpoint *b = loc->owner;
- struct tracepoint *t = (struct tracepoint *) b;
+ tracepoint *t = gdb::checked_static_cast<tracepoint *> (b);
struct remote_state *rs = get_remote_state ();
int ret;
const char *err_msg = _("Tracepoint packet too large for target.");
if (anysecs)
{
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
}
}
/* FIXME we need to get register block size some other way. */
trace_regblock_size
- = rs->get_remote_arch_state (target_gdbarch ())->sizeof_g_packet;
+ = rs->get_remote_arch_state (current_inferior ()->arch ())->sizeof_g_packet;
putpkt ("qTStatus");
}
void
-remote_target::get_tracepoint_status (struct breakpoint *bp,
+remote_target::get_tracepoint_status (tracepoint *tp,
struct uploaded_tp *utp)
{
struct remote_state *rs = get_remote_state ();
char *reply;
- struct tracepoint *tp = (struct tracepoint *) bp;
size_t size = get_remote_packet_size ();
if (tp)
if (reply && *reply)
{
if (*reply == 'V')
- parse_tracepoint_status (reply + 1, bp, utp);
+ parse_tracepoint_status (reply + 1, tp, utp);
}
}
}
if (reply && *reply)
{
if (*reply == 'V')
- parse_tracepoint_status (reply + 1, bp, utp);
+ parse_tracepoint_status (reply + 1, tp, utp);
}
}
}
/* If the stub supports QAgent. */
xsnprintf (rs->buf.data (), get_remote_packet_size (), "QAgent:%d", use);
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
if (strcmp (rs->buf.data (), "OK") == 0)
{
return (m_features.packet_support (PACKET_QAgent) != PACKET_DISABLE);
}
-struct btrace_target_info
+#if defined (HAVE_LIBEXPAT)
+
+/* Check the btrace document version. */
+
+static void
+check_xml_btrace_version (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data,
+ std::vector<gdb_xml_value> &attributes)
{
- /* The ptid of the traced thread. */
- ptid_t ptid;
+ const char *version
+ = (const char *) xml_find_attribute (attributes, "version")->value.get ();
+
+ if (strcmp (version, "1.0") != 0)
+ gdb_xml_error (parser, _("Unsupported btrace version: \"%s\""), version);
+}
+
+/* Parse a btrace "block" xml record. */
+
+static void
+parse_xml_btrace_block (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data,
+ std::vector<gdb_xml_value> &attributes)
+{
+ struct btrace_data *btrace;
+ ULONGEST *begin, *end;
+
+ btrace = (struct btrace_data *) user_data;
+
+ switch (btrace->format)
+ {
+ case BTRACE_FORMAT_BTS:
+ break;
+
+ case BTRACE_FORMAT_NONE:
+ btrace->format = BTRACE_FORMAT_BTS;
+ btrace->variant.bts.blocks = new std::vector<btrace_block>;
+ break;
+
+ default:
+ gdb_xml_error (parser, _("Btrace format error."));
+ }
+
+ begin = (ULONGEST *) xml_find_attribute (attributes, "begin")->value.get ();
+ end = (ULONGEST *) xml_find_attribute (attributes, "end")->value.get ();
+ btrace->variant.bts.blocks->emplace_back (*begin, *end);
+}
+
+/* Parse a "raw" xml record. */
+
+static void
+parse_xml_raw (struct gdb_xml_parser *parser, const char *body_text,
+ gdb_byte **pdata, size_t *psize)
+{
+ gdb_byte *bin;
+ size_t len, size;
+
+ len = strlen (body_text);
+ if (len % 2 != 0)
+ gdb_xml_error (parser, _("Bad raw data size."));
+
+ size = len / 2;
+
+ gdb::unique_xmalloc_ptr<gdb_byte> data ((gdb_byte *) xmalloc (size));
+ bin = data.get ();
+
+ /* We use hex encoding - see gdbsupport/rsp-low.h. */
+ while (len > 0)
+ {
+ char hi, lo;
+
+ hi = *body_text++;
+ lo = *body_text++;
+
+ if (hi == 0 || lo == 0)
+ gdb_xml_error (parser, _("Bad hex encoding."));
+
+ *bin++ = fromhex (hi) * 16 + fromhex (lo);
+ len -= 2;
+ }
+
+ *pdata = data.release ();
+ *psize = size;
+}
+
+/* Parse a btrace pt-config "cpu" xml record. */
+
+static void
+parse_xml_btrace_pt_config_cpu (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data,
+ std::vector<gdb_xml_value> &attributes)
+{
+ struct btrace_data *btrace;
+ const char *vendor;
+ ULONGEST *family, *model, *stepping;
+
+ vendor
+ = (const char *) xml_find_attribute (attributes, "vendor")->value.get ();
+ family
+ = (ULONGEST *) xml_find_attribute (attributes, "family")->value.get ();
+ model
+ = (ULONGEST *) xml_find_attribute (attributes, "model")->value.get ();
+ stepping
+ = (ULONGEST *) xml_find_attribute (attributes, "stepping")->value.get ();
+
+ btrace = (struct btrace_data *) user_data;
+
+ if (strcmp (vendor, "GenuineIntel") == 0)
+ btrace->variant.pt.config.cpu.vendor = CV_INTEL;
+
+ btrace->variant.pt.config.cpu.family = *family;
+ btrace->variant.pt.config.cpu.model = *model;
+ btrace->variant.pt.config.cpu.stepping = *stepping;
+}
+
+/* Parse a btrace pt "raw" xml record. */
+
+static void
+parse_xml_btrace_pt_raw (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data, const char *body_text)
+{
+ struct btrace_data *btrace;
+
+ btrace = (struct btrace_data *) user_data;
+ parse_xml_raw (parser, body_text, &btrace->variant.pt.data,
+ &btrace->variant.pt.size);
+}
+
+/* Parse a btrace "pt" xml record. */
+
+static void
+parse_xml_btrace_pt (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data,
+ std::vector<gdb_xml_value> &attributes)
+{
+ struct btrace_data *btrace;
- /* The obtained branch trace configuration. */
- struct btrace_config conf;
+ btrace = (struct btrace_data *) user_data;
+ btrace->format = BTRACE_FORMAT_PT;
+ btrace->variant.pt.config.cpu.vendor = CV_UNKNOWN;
+ btrace->variant.pt.data = NULL;
+ btrace->variant.pt.size = 0;
+}
+
+static const struct gdb_xml_attribute block_attributes[] = {
+ { "begin", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+ { "end", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+ { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_attribute btrace_pt_config_cpu_attributes[] = {
+ { "vendor", GDB_XML_AF_NONE, NULL, NULL },
+ { "family", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+ { "model", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+ { "stepping", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+ { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element btrace_pt_config_children[] = {
+ { "cpu", btrace_pt_config_cpu_attributes, NULL, GDB_XML_EF_OPTIONAL,
+ parse_xml_btrace_pt_config_cpu, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element btrace_pt_children[] = {
+ { "pt-config", NULL, btrace_pt_config_children, GDB_XML_EF_OPTIONAL, NULL,
+ NULL },
+ { "raw", NULL, NULL, GDB_XML_EF_OPTIONAL, NULL, parse_xml_btrace_pt_raw },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_attribute btrace_attributes[] = {
+ { "version", GDB_XML_AF_NONE, NULL, NULL },
+ { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element btrace_children[] = {
+ { "block", block_attributes, NULL,
+ GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL, parse_xml_btrace_block, NULL },
+ { "pt", NULL, btrace_pt_children, GDB_XML_EF_OPTIONAL, parse_xml_btrace_pt,
+ NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element btrace_elements[] = {
+ { "btrace", btrace_attributes, btrace_children, GDB_XML_EF_NONE,
+ check_xml_btrace_version, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+#endif /* defined (HAVE_LIBEXPAT) */
+
+/* Parse a branch trace xml document XML into DATA. */
+
+static void
+parse_xml_btrace (struct btrace_data *btrace, const char *buffer)
+{
+#if defined (HAVE_LIBEXPAT)
+
+ int errcode;
+ btrace_data result;
+ result.format = BTRACE_FORMAT_NONE;
+
+ errcode = gdb_xml_parse_quick (_("btrace"), "btrace.dtd", btrace_elements,
+ buffer, &result);
+ if (errcode != 0)
+ error (_("Error parsing branch trace."));
+
+ /* Keep parse results. */
+ *btrace = std::move (result);
+
+#else /* !defined (HAVE_LIBEXPAT) */
+
+ error (_("Cannot process branch trace. XML support was disabled at "
+ "compile time."));
+
+#endif /* !defined (HAVE_LIBEXPAT) */
+}
+
+#if defined (HAVE_LIBEXPAT)
+
+/* Parse a btrace-conf "bts" xml record. */
+
+static void
+parse_xml_btrace_conf_bts (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data,
+ std::vector<gdb_xml_value> &attributes)
+{
+ struct btrace_config *conf;
+ struct gdb_xml_value *size;
+
+ conf = (struct btrace_config *) user_data;
+ conf->format = BTRACE_FORMAT_BTS;
+ conf->bts.size = 0;
+
+ size = xml_find_attribute (attributes, "size");
+ if (size != NULL)
+ conf->bts.size = (unsigned int) *(ULONGEST *) size->value.get ();
+}
+
+/* Parse a btrace-conf "pt" xml record. */
+
+static void
+parse_xml_btrace_conf_pt (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data,
+ std::vector<gdb_xml_value> &attributes)
+{
+ struct btrace_config *conf;
+ struct gdb_xml_value *size;
+
+ conf = (struct btrace_config *) user_data;
+ conf->format = BTRACE_FORMAT_PT;
+ conf->pt.size = 0;
+
+ size = xml_find_attribute (attributes, "size");
+ if (size != NULL)
+ conf->pt.size = (unsigned int) *(ULONGEST *) size->value.get ();
+}
+
+static const struct gdb_xml_attribute btrace_conf_pt_attributes[] = {
+ { "size", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL },
+ { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_attribute btrace_conf_bts_attributes[] = {
+ { "size", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL },
+ { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element btrace_conf_children[] = {
+ { "bts", btrace_conf_bts_attributes, NULL, GDB_XML_EF_OPTIONAL,
+ parse_xml_btrace_conf_bts, NULL },
+ { "pt", btrace_conf_pt_attributes, NULL, GDB_XML_EF_OPTIONAL,
+ parse_xml_btrace_conf_pt, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_attribute btrace_conf_attributes[] = {
+ { "version", GDB_XML_AF_NONE, NULL, NULL },
+ { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element btrace_conf_elements[] = {
+ { "btrace-conf", btrace_conf_attributes, btrace_conf_children,
+ GDB_XML_EF_NONE, NULL, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
};
+#endif /* defined (HAVE_LIBEXPAT) */
+
+/* Parse a branch trace configuration xml document XML into CONF. */
+
+static void
+parse_xml_btrace_conf (struct btrace_config *conf, const char *xml)
+{
+#if defined (HAVE_LIBEXPAT)
+
+ int errcode;
+ errcode = gdb_xml_parse_quick (_("btrace-conf"), "btrace-conf.dtd",
+ btrace_conf_elements, xml, conf);
+ if (errcode != 0)
+ error (_("Error parsing branch trace configuration."));
+
+#else /* !defined (HAVE_LIBEXPAT) */
+
+ error (_("Cannot process the branch trace configuration. XML support "
+ "was disabled at compile time."));
+
+#endif /* !defined (HAVE_LIBEXPAT) */
+}
+
/* Reset our idea of our target's btrace configuration. */
static void
conf->bts.size);
putpkt (buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
if (m_features.packet_ok (buf, PACKET_Qbtrace_conf_bts_size)
== PACKET_ERROR)
conf->pt.size);
putpkt (buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
if (m_features.packet_ok (buf, PACKET_Qbtrace_conf_pt_size)
== PACKET_ERROR)
/* Read TP's btrace configuration from the target and store it into CONF. */
static void
-btrace_read_config (thread_info *tp, struct btrace_config *conf)
+btrace_read_config (thread_info *tp, btrace_config *conf)
{
/* target_read_stralloc relies on INFERIOR_PTID. */
scoped_restore_current_thread restore_thread;
btrace_format_string (rs->btrace_config.format));
}
- tp->btrace.target = XCNEW (struct btrace_target_info);
- tp->btrace.target->ptid = tp->ptid;
- tp->btrace.target->conf = rs->btrace_config;
+ tp->btrace.target
+ = new btrace_target_info { tp->ptid, rs->btrace_config };
}
}
remote_target::enable_btrace (thread_info *tp,
const struct btrace_config *conf)
{
- struct btrace_target_info *tinfo = NULL;
struct packet_config *packet = NULL;
struct remote_state *rs = get_remote_state ();
char *buf = rs->buf.data ();
buf += xsnprintf (buf, endbuf - buf, "%s",
packets_descriptions[which_packet].name);
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
if (m_features.packet_ok (rs->buf, which_packet) == PACKET_ERROR)
{
target_pid_to_str (ptid).c_str ());
}
- tinfo = XCNEW (struct btrace_target_info);
- tinfo->ptid = ptid;
+ btrace_target_info *tinfo = new btrace_target_info { ptid };
/* If we fail to read the configuration, we lose some information, but the
tracing itself is not impacted. */
buf += xsnprintf (buf, endbuf - buf, "%s",
packets_descriptions[PACKET_Qbtrace_off].name);
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
if (m_features.packet_ok (rs->buf, PACKET_Qbtrace_off) == PACKET_ERROR)
{
target_pid_to_str (tinfo->ptid).c_str ());
}
- xfree (tinfo);
+ delete tinfo;
}
/* Teardown branch tracing. */
remote_target::teardown_btrace (struct btrace_target_info *tinfo)
{
/* We must not talk to the target during teardown. */
- xfree (tinfo);
+ delete tinfo;
}
/* Read the branch trace. */
gdb_assert (target_async_permitted);
/* We're async whenever the serial device can. */
- struct remote_state *rs = get_remote_state ();
- return serial_can_async_p (rs->remote_desc);
+ return get_remote_state ()->can_async_p ();
}
bool
remote_target::is_async_p ()
{
/* We're async whenever the serial device is. */
- struct remote_state *rs = get_remote_state ();
- return serial_is_async_p (rs->remote_desc);
+ return get_remote_state ()->is_async_p ();
}
/* Pass the SERIAL event on and up to the client. One day this code
inferior_event_handler (INF_REG_EVENT);
}
-static void
-remote_async_inferior_event_handler (gdb_client_data data)
-{
- inferior_event_handler (INF_REG_EVENT);
-}
-
int
remote_target::async_wait_fd ()
{
/* If there are pending events in the stop reply queue tell the
event loop to process them. */
if (!rs->stop_reply_queue.empty ())
- mark_async_event_handler (rs->remote_async_inferior_event_token);
+ rs->mark_async_event_handler ();
+
/* For simplicity, below we clear the pending events token
without remembering whether it is marked, so here we always
mark it. If there's actually no pending notification to
/* If the core is disabling async, it doesn't want to be
disturbed with target events. Clear all async event sources
too. */
- clear_async_event_handler (rs->remote_async_inferior_event_token);
+ rs->clear_async_event_handler ();
+
if (target_is_non_stop_p ())
clear_async_event_handler (rs->notif_state->get_pending_events_token);
}
xsnprintf (rs->buf.data (), size, "QThreadEvents:%x", enable ? 1 : 0);
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
switch (m_features.packet_ok (rs->buf, PACKET_QThreadEvents))
{
}
}
+/* Some change happened in PSPACE's objfile list (obfiles added or removed),
+ offer all inferiors using that program space a change to look up symbols. */
-/* Function to be called whenever a new objfile (shlib) is detected. */
static void
-remote_new_objfile (struct objfile *objfile)
+remote_objfile_changed_check_symbols (program_space *pspace)
{
- /* The objfile change happened in that program space. */
- program_space *pspace = current_program_space;
-
/* The affected program space is possibly shared by multiple inferiors.
Consider sending a qSymbol packet for each of the inferiors using that
program space. */
}
}
+/* Function to be called whenever a new objfile (shlib) is detected. */
+
+static void
+remote_new_objfile (struct objfile *objfile)
+{
+ remote_objfile_changed_check_symbols (objfile->pspace);
+}
+
/* Pull all the tracepoints defined on the target and create local
data structures representing them. We don't want to create real
tracepoints yet, we don't want to mess up the user's existing
collection. */
-
+
int
remote_target::upload_tracepoints (struct uploaded_tp **utpp)
{
/* Ask for a first packet of tracepoint definition. */
putpkt ("qTfP");
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
p = rs->buf.data ();
while (*p && *p != 'l')
{
parse_tracepoint_definition (p, utpp);
/* Ask for another packet of tracepoint definition. */
putpkt ("qTsP");
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
p = rs->buf.data ();
}
return 0;
/* Ask for a first packet of variable definition. */
putpkt ("qTfV");
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
p = rs->buf.data ();
while (*p && *p != 'l')
{
parse_tsv_definition (p, utsvp);
/* Ask for another packet of variable definition. */
putpkt ("qTsV");
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
p = rs->buf.data ();
}
return 0;
create_fetch_memtags_request (gdb::char_vector &packet, CORE_ADDR address,
size_t len, int type)
{
- int addr_size = gdbarch_addr_bit (target_gdbarch ()) / 8;
+ int addr_size = gdbarch_addr_bit (current_inferior ()->arch ()) / 8;
std::string request = string_printf ("qMemTags:%s,%s:%s",
phex_nz (address, addr_size),
size_t len, int type,
const gdb::byte_vector &tags)
{
- int addr_size = gdbarch_addr_bit (target_gdbarch ()) / 8;
+ int addr_size = gdbarch_addr_bit (current_inferior ()->arch ()) / 8;
/* Put together the main packet, address and length. */
std::string request = string_printf ("QMemTags:%s,%s:%s:",
create_fetch_memtags_request (rs->buf, address, len, type);
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
return parse_fetch_memtags_reply (rs->buf, tags);
}
create_store_memtags_request (rs->buf, address, len, type, tags);
putpkt (rs->buf);
- getpkt (&rs->buf, 0);
+ getpkt (&rs->buf);
/* Verify if the request was successful. */
return packet_check_result (rs->buf.data ()) == PACKET_OK;
/* Hook into new objfile notification. */
gdb::observers::new_objfile.attach (remote_new_objfile, "remote");
+ gdb::observers::all_objfiles_removed.attach
+ (remote_objfile_changed_check_symbols, "remote");
#if 0
init_remote_threadtests ();