#include "common/scoped_restore.h"
#include "environ.h"
#include "common/byte-vector.h"
+#include <unordered_map>
/* The remote target. */
static int stop_reply_queue_length (void);
-static void readahead_cache_invalidate (void);
-
static void remote_unpush_and_throw (void);
static struct remote_state *get_remote_state (void);
struct vCont_action_support
{
/* vCont;t */
- int t;
+ bool t = false;
/* vCont;r */
- int r;
+ bool r = false;
/* vCont;s */
- int s;
+ bool s = false;
/* vCont;S */
- int S;
+ bool S = false;
};
/* Controls whether GDB is willing to use range stepping. */
struct readahead_cache
{
+ /* Invalidate the readahead cache. */
+ void invalidate ();
+
+ /* Invalidate the readahead cache if it is holding data for FD. */
+ void invalidate_fd (int fd);
+
+ /* Serve pread from the readahead cache. Returns number of bytes
+ read, or 0 if the request can't be served from the cache. */
+ int pread (int fd, gdb_byte *read_buf, size_t len, ULONGEST offset);
+
/* The file descriptor for the file that is being cached. -1 if the
cache is invalid. */
- int fd;
+ int fd = -1;
/* The offset into the file that the cache buffer corresponds
to. */
- ULONGEST offset;
+ ULONGEST offset = 0;
/* The buffer holding the cache contents. */
- gdb_byte *buf;
+ gdb_byte *buf = nullptr;
/* The buffer's size. We try to read as much as fits into a packet
at a time. */
- size_t bufsize;
+ size_t bufsize = 0;
/* Cache hit and miss counters. */
- ULONGEST hit_count;
- ULONGEST miss_count;
+ ULONGEST hit_count = 0;
+ ULONGEST miss_count = 0;
+};
+
+/* Description of the remote protocol for a given architecture. */
+
+struct packet_reg
+{
+ long offset; /* Offset into G packet. */
+ 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);
+ at present. */
+ /* char *name; == gdbarch_register_name (target_gdbarch (), regnum);
+ at present. */
+};
+
+struct remote_arch_state
+{
+ explicit remote_arch_state (struct gdbarch *gdbarch);
+
+ /* Description of the remote protocol registers. */
+ long sizeof_g_packet;
+
+ /* Description of the remote protocol registers indexed by REGNUM
+ (making an array gdbarch_num_regs in size). */
+ std::unique_ptr<packet_reg[]> regs;
+
+ /* This is the size (in chars) of the first response to the ``g''
+ packet. It is used as a heuristic when determining the maximum
+ size of memory-read and memory-write packets. A target will
+ typically only reserve a buffer large enough to hold the ``g''
+ packet. The size does not include packet overhead (headers and
+ trailers). */
+ long actual_register_packet_size;
+
+ /* This is the maximum size (in chars) of a non read/write packet.
+ It is also used as a cap on the size of read/write packets. */
+ long remote_packet_size;
};
/* Description of the remote protocol state for the currently
connected target. This is per-target state, and independent of the
selected architecture. */
-struct remote_state
+class remote_state
{
+public:
+
+ remote_state ();
+ ~remote_state ();
+
+ /* Get the remote arch state for GDBARCH. */
+ struct remote_arch_state *get_remote_arch_state (struct gdbarch *gdbarch);
+
+public: /* data */
+
/* A buffer to use for incoming packets, and its current size. The
buffer is grown dynamically for larger incoming packets.
Outgoing packets may also be constructed in this buffer.
/* True if we're going through initial connection setup (finding out
about the remote side's threads, relocating symbols, etc.). */
- int starting_up;
+ bool starting_up = false;
/* 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.
Otherwise zero, meaning to use the guessed size. */
- long explicit_packet_size;
+ long explicit_packet_size = 0;
/* remote_wait is normally called when the target is running and
waits for a stop reply packet. But sometimes we need to call it
the response, we can stash it in BUF and tell remote_wait to
skip calling getpkt. This flag is set when BUF contains a
stop reply packet and the target is not waiting. */
- int cached_wait_status;
+ int cached_wait_status = 0;
/* True, if in no ack mode. That is, neither GDB nor the stub will
expect acks from each other. The connection is assumed to be
reliable. */
- int noack_mode;
+ bool noack_mode = false;
/* True if we're connected in extended remote mode. */
- int extended;
+ bool extended = false;
/* True if we resumed the target and we're waiting for the target to
stop. In the mean time, we can't start another command/query.
timeout waiting for a reply that would never come and eventually
we'd close the connection. This can happen in asynchronous mode
because we allow GDB commands while the target is running. */
- int waiting_for_stop_reply;
+ bool waiting_for_stop_reply = false;
/* The status of the stub support for the various vCont actions. */
- struct vCont_action_support supports_vCont;
+ vCont_action_support supports_vCont;
- /* Nonzero if the user has pressed Ctrl-C, but the target hasn't
+ /* True if the user has pressed Ctrl-C, but the target hasn't
responded to that. */
- int ctrlc_pending_p;
+ bool ctrlc_pending_p = false;
/* True if we saw a Ctrl-C while reading or writing from/to the
remote descriptor. At that point it is not safe to send a remote
process it once we're done with sending/receiving the current
packet, which should be shortly. If however that takes too long,
and the user presses Ctrl-C again, we offer to disconnect. */
- int got_ctrlc_during_io;
+ bool got_ctrlc_during_io = false;
/* Descriptor for I/O to remote machine. Initialize it to NULL so that
remote_open knows that we don't have a file open when the program
starts. */
- struct serial *remote_desc;
+ struct serial *remote_desc = nullptr;
/* These are the threads which we last sent to the remote system. The
TID member will be -1 for all or -2 for not sent yet. */
- ptid_t general_thread;
- ptid_t continue_thread;
+ ptid_t general_thread = null_ptid;
+ ptid_t continue_thread = null_ptid;
/* This is the traceframe which we last selected on the remote system.
It will be -1 if no traceframe is selected. */
- int remote_traceframe_number;
+ int remote_traceframe_number = -1;
- char *last_pass_packet;
+ char *last_pass_packet = nullptr;
/* 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. */
- char *last_program_signals_packet;
+ char *last_program_signals_packet = nullptr;
- enum gdb_signal last_sent_signal;
+ gdb_signal last_sent_signal = GDB_SIGNAL_0;
- int last_sent_step;
+ bool last_sent_step = false;
/* The execution direction of the last resume we got. */
- enum exec_direction_kind last_resume_exec_dir;
+ exec_direction_kind last_resume_exec_dir = EXEC_FORWARD;
- char *finished_object;
- char *finished_annex;
- ULONGEST finished_offset;
+ char *finished_object = nullptr;
+ char *finished_annex = nullptr;
+ ULONGEST finished_offset = 0;
/* Should we try the 'ThreadInfo' query packet?
query or the older, more complex syntax for thread queries.
This is an auto-detect variable (set to true at each connect,
and set to false when the target fails to recognize it). */
- int use_threadinfo_query;
- int use_threadextra_query;
+ bool use_threadinfo_query = false;
+ bool use_threadextra_query = false;
- threadref echo_nextthread;
- threadref nextthread;
- threadref resultthreadlist[MAXTHREADLISTRESULTS];
+ threadref echo_nextthread {};
+ threadref nextthread {};
+ threadref resultthreadlist[MAXTHREADLISTRESULTS] {};
/* The state of remote notification. */
- struct remote_notif_state *notif_state;
+ struct remote_notif_state *notif_state = nullptr;
/* The branch trace configuration. */
- struct btrace_config btrace_config;
+ struct btrace_config btrace_config {};
/* The argument to the last "vFile:setfs:" packet we sent, used
to avoid sending repeated unnecessary "vFile:setfs:" packets.
Initialized to -1 to indicate that no "vFile:setfs:" packet
has yet been sent. */
- int fs_pid;
+ int fs_pid = -1;
/* A readahead cache for vFile:pread. Often, reading a binary
involves a sequence of small reads. E.g., when parsing an ELF
request/reply nature of the RSP. We only cache data for a single
file descriptor at a time. */
struct readahead_cache readahead_cache;
+
+private:
+ /* 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. */
+ std::unordered_map<struct gdbarch *, remote_arch_state>
+ m_arch_states;
};
/* Private data that we'll store in (struct thread_info)->priv. */
int vcont_resumed = 0;
};
+remote_state::remote_state ()
+{
+ /* The default buffer size is unimportant; it will be expanded
+ whenever a larger buffer is needed. */
+ this->buf_size = 400;
+ this->buf = (char *) xmalloc (this->buf_size);
+}
+
+remote_state::~remote_state ()
+{
+ xfree (this->last_pass_packet);
+ xfree (this->last_program_signals_packet);
+ xfree (this->buf);
+ xfree (this->finished_object);
+ xfree (this->finished_annex);
+}
+
/* This data could be associated with a target, but we do not always
have access to the current target when we need it, so for now it is
static. This will be fine for as long as only one target is in use
return remote_state;
}
-/* Allocate a new struct remote_state with xmalloc, initialize it, and
- return it. */
-
-static struct remote_state *
-new_remote_state (void)
-{
- struct remote_state *result = XCNEW (struct remote_state);
-
- /* The default buffer size is unimportant; it will be expanded
- whenever a larger buffer is needed. */
- result->buf_size = 400;
- result->buf = (char *) xmalloc (result->buf_size);
- result->remote_traceframe_number = -1;
- result->last_sent_signal = GDB_SIGNAL_0;
- result->last_resume_exec_dir = EXEC_FORWARD;
- result->fs_pid = -1;
-
- return result;
-}
-
-/* Description of the remote protocol for a given architecture. */
-
-struct packet_reg
-{
- long offset; /* Offset into G packet. */
- 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);
- at present. */
- /* char *name; == gdbarch_register_name (target_gdbarch (), regnum);
- at present. */
-};
-
-struct remote_arch_state
-{
- /* Description of the remote protocol registers. */
- long sizeof_g_packet;
-
- /* Description of the remote protocol registers indexed by REGNUM
- (making an array gdbarch_num_regs in size). */
- struct packet_reg *regs;
-
- /* This is the size (in chars) of the first response to the ``g''
- packet. It is used as a heuristic when determining the maximum
- size of memory-read and memory-write packets. A target will
- typically only reserve a buffer large enough to hold the ``g''
- packet. The size does not include packet overhead (headers and
- trailers). */
- long actual_register_packet_size;
-
- /* This is the maximum size (in chars) of a non read/write packet.
- It is also used as a cap on the size of read/write packets. */
- long remote_packet_size;
-};
-
/* Utility: generate error from an incoming stub packet. */
static void
trace_error (char *buf)
while (1);
}
-/* Handle for retreving the remote protocol data from gdbarch. */
-static struct gdbarch_data *remote_gdbarch_data_handle;
-
-static struct remote_arch_state *
-get_remote_arch_state (struct gdbarch *gdbarch)
+struct remote_arch_state *
+remote_state::get_remote_arch_state (struct gdbarch *gdbarch)
{
- gdb_assert (gdbarch != NULL);
- return ((struct remote_arch_state *)
- gdbarch_data (gdbarch, remote_gdbarch_data_handle));
+ remote_arch_state *rsa;
+
+ auto it = this->m_arch_states.find (gdbarch);
+ if (it == this->m_arch_states.end ())
+ {
+ auto p = this->m_arch_states.emplace (std::piecewise_construct,
+ std::forward_as_tuple (gdbarch),
+ std::forward_as_tuple (gdbarch));
+ rsa = &p.first->second;
+
+ /* Make sure that the packet buffer is plenty big enough for
+ this architecture. */
+ if (this->buf_size < rsa->remote_packet_size)
+ {
+ this->buf_size = 2 * rsa->remote_packet_size;
+ this->buf = (char *) xrealloc (this->buf, this->buf_size);
+ }
+ }
+ else
+ rsa = &it->second;
+
+ return rsa;
}
/* Fetch the global remote target state. */
static struct remote_state *
get_remote_state (void)
{
+ struct remote_state *rs = get_remote_state_raw ();
+
/* Make sure that the remote architecture state has been
initialized, because doing so might reallocate rs->buf. Any
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. */
- get_remote_arch_state (target_gdbarch ());
+ rs->get_remote_arch_state (target_gdbarch ());
- return get_remote_state_raw ();
+ return rs;
}
/* Cleanup routine for the remote module's pspace data. */
return *pnum != -1;
}
-static void *
-init_remote_state (struct gdbarch *gdbarch)
+remote_arch_state::remote_arch_state (struct gdbarch *gdbarch)
{
- struct remote_state *rs = get_remote_state_raw ();
- struct remote_arch_state *rsa;
-
- rsa = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct remote_arch_state);
-
/* Use the architecture to build a regnum<->pnum table, which will be
1:1 unless a feature set specifies otherwise. */
- rsa->regs = GDBARCH_OBSTACK_CALLOC (gdbarch,
- gdbarch_num_regs (gdbarch),
- struct packet_reg);
+ this->regs.reset (new packet_reg [gdbarch_num_regs (gdbarch)] ());
/* Record the maximum possible size of the g packet - it may turn out
to be smaller. */
- rsa->sizeof_g_packet = map_regcache_remote_table (gdbarch, rsa->regs);
+ this->sizeof_g_packet
+ = map_regcache_remote_table (gdbarch, this->regs.get ());
/* Default maximum number of characters in a packet body. Many
remote stubs have a hardwired buffer size of 400 bytes
NUL character can always fit in the buffer. This stops GDB
trashing stubs that try to squeeze an extra NUL into what is
already a full buffer (As of 1999-12-04 that was most stubs). */
- rsa->remote_packet_size = 400 - 1;
+ this->remote_packet_size = 400 - 1;
/* This one is filled in when a ``g'' packet is received. */
- rsa->actual_register_packet_size = 0;
+ this->actual_register_packet_size = 0;
/* Should rsa->sizeof_g_packet needs more space than the
default, adjust the size accordingly. Remember that each byte is
header / footer. NOTE: cagney/1999-10-26: I suspect that 8
(``$NN:G...#NN'') is a better guess, the below has been padded a
little. */
- if (rsa->sizeof_g_packet > ((rsa->remote_packet_size - 32) / 2))
- rsa->remote_packet_size = (rsa->sizeof_g_packet * 2 + 32);
-
- /* Make sure that the packet buffer is plenty big enough for
- this architecture. */
- if (rs->buf_size < rsa->remote_packet_size)
- {
- rs->buf_size = 2 * rsa->remote_packet_size;
- rs->buf = (char *) xrealloc (rs->buf, rs->buf_size);
- }
-
- return rsa;
+ if (this->sizeof_g_packet > ((this->remote_packet_size - 32) / 2))
+ this->remote_packet_size = (this->sizeof_g_packet * 2 + 32);
}
/* Return the current allowed size of a remote packet. This is
get_remote_packet_size (void)
{
struct remote_state *rs = get_remote_state ();
- remote_arch_state *rsa = get_remote_arch_state (target_gdbarch ());
+ remote_arch_state *rsa = rs->get_remote_arch_state (target_gdbarch ());
if (rs->explicit_packet_size)
return rs->explicit_packet_size;
get_memory_packet_size (struct memory_packet_config *config)
{
struct remote_state *rs = get_remote_state ();
- remote_arch_state *rsa = get_remote_arch_state (target_gdbarch ());
+ remote_arch_state *rsa = rs->get_remote_arch_state (target_gdbarch ());
long what_they_get;
if (config->fixed_p)
rs->use_threadinfo_query = 1;
rs->use_threadextra_query = 1;
- readahead_cache_invalidate ();
+ rs->readahead_cache.invalidate ();
if (target_async_permitted)
{
}
event->arch = inf->gdbarch;
- rsa = get_remote_arch_state (event->arch);
+ rsa = event->rs->get_remote_arch_state (event->arch);
}
packet_reg *reg
putpkt (buf);
break;
}
- /* else fallthrough */
+ /* fallthrough */
default:
warning (_("Invalid remote reply: %s"), buf);
break;
{
struct gdbarch *gdbarch = regcache->arch ();
struct remote_state *rs = get_remote_state ();
- remote_arch_state *rsa = get_remote_arch_state (gdbarch);
+ remote_arch_state *rsa = rs->get_remote_arch_state (gdbarch);
int i, buf_len;
char *p;
char *regs;
remote_target::fetch_registers (struct regcache *regcache, int regnum)
{
struct gdbarch *gdbarch = regcache->arch ();
- remote_arch_state *rsa = get_remote_arch_state (gdbarch);
+ struct remote_state *rs = get_remote_state ();
+ remote_arch_state *rsa = rs->get_remote_arch_state (gdbarch);
int i;
set_remote_traceframe ();
void
remote_target::prepare_to_store (struct regcache *regcache)
{
- remote_arch_state *rsa = get_remote_arch_state (regcache->arch ());
+ struct remote_state *rs = get_remote_state ();
+ remote_arch_state *rsa = rs->get_remote_arch_state (regcache->arch ());
int i;
/* Make sure the entire registers array is valid. */
store_registers_using_G (const struct regcache *regcache)
{
struct remote_state *rs = get_remote_state ();
- remote_arch_state *rsa = get_remote_arch_state (regcache->arch ());
+ remote_arch_state *rsa = rs->get_remote_arch_state (regcache->arch ());
gdb_byte *regs;
char *p;
remote_target::store_registers (struct regcache *regcache, int regnum)
{
struct gdbarch *gdbarch = regcache->arch ();
- remote_arch_state *rsa = get_remote_arch_state (gdbarch);
+ struct remote_state *rs = get_remote_state ();
+ remote_arch_state *rsa = rs->get_remote_arch_state (gdbarch);
int i;
set_remote_traceframe ();
{
struct remote_state *rs = get_remote_state ();
+ /* We're no longer interested in notification events of an inferior
+ that exited or was killed/detached. */
+ discard_pending_stop_replies (current_inferior ());
+
/* In 'target remote' mode with one inferior, we close the connection. */
if (!rs->extended && number_of_live_inferiors () <= 1)
{
if (!exec_bfd)
error (_("command cannot be used without an exec file"));
- /* Make sure the remote is pointing at the right process. */
- set_general_process ();
-
if (args != NULL && strcmp (args, "-r") == 0)
{
read_only = 1;
return ret;
}
-/* Invalidate the readahead cache. */
+/* See declaration.h. */
-static void
-readahead_cache_invalidate (void)
+void
+readahead_cache::invalidate ()
{
- struct remote_state *rs = get_remote_state ();
-
- rs->readahead_cache.fd = -1;
+ this->fd = -1;
}
-/* Invalidate the readahead cache if it is holding data for FD. */
+/* See declaration.h. */
-static void
-readahead_cache_invalidate_fd (int fd)
+void
+readahead_cache::invalidate_fd (int fd)
{
- struct remote_state *rs = get_remote_state ();
-
- if (rs->readahead_cache.fd == fd)
- rs->readahead_cache.fd = -1;
+ if (this->fd == fd)
+ this->fd = -1;
}
/* Set the filesystem remote_hostio functions that take FILENAME
int left = get_remote_packet_size ();
int out_len;
- readahead_cache_invalidate_fd (fd);
+ rs->readahead_cache.invalidate_fd (fd);
remote_buffer_add_string (&p, &left, "vFile:pwrite:");
return ret;
}
-/* Serve pread from the readahead cache. Returns number of bytes
- read, or 0 if the request can't be served from the cache. */
+/* See declaration.h. */
-static int
-remote_hostio_pread_from_cache (struct remote_state *rs,
- int fd, gdb_byte *read_buf, size_t len,
- ULONGEST offset)
+int
+readahead_cache::pread (int fd, gdb_byte *read_buf, size_t len,
+ ULONGEST offset)
{
- struct readahead_cache *cache = &rs->readahead_cache;
-
- if (cache->fd == fd
- && cache->offset <= offset
- && offset < cache->offset + cache->bufsize)
+ if (this->fd == fd
+ && this->offset <= offset
+ && offset < this->offset + this->bufsize)
{
- ULONGEST max = cache->offset + cache->bufsize;
+ ULONGEST max = this->offset + this->bufsize;
if (offset + len > max)
len = max - offset;
- memcpy (read_buf, cache->buf + offset - cache->offset, len);
+ memcpy (read_buf, this->buf + offset - this->offset, len);
return len;
}
{
int ret;
struct remote_state *rs = get_remote_state ();
- struct readahead_cache *cache = &rs->readahead_cache;
+ readahead_cache *cache = &rs->readahead_cache;
- ret = remote_hostio_pread_from_cache (rs, fd, read_buf, len, offset);
+ ret = cache->pread (fd, read_buf, len, offset);
if (ret > 0)
{
cache->hit_count++;
cache->offset, remote_errno);
if (ret <= 0)
{
- readahead_cache_invalidate_fd (fd);
+ cache->invalidate_fd (fd);
return ret;
}
cache->bufsize = ret;
- return remote_hostio_pread_from_cache (rs, fd, read_buf, len, offset);
+ return cache->pread (fd, read_buf, len, offset);
}
int
char *p = rs->buf;
int left = get_remote_packet_size () - 1;
- readahead_cache_invalidate_fd (fd);
+ rs->readahead_cache.invalidate_fd (fd);
remote_buffer_add_string (&p, &left, "vFile:close:");
error (_("Remote I/O error: %s"), safe_strerror (host_error));
}
-static void
-remote_hostio_close_cleanup (void *opaque)
+/* A RAII wrapper around a remote file descriptor. */
+
+class scoped_remote_fd
{
- int fd = *(int *) opaque;
- int remote_errno;
+public:
+ explicit scoped_remote_fd (int fd)
+ : m_fd (fd)
+ {
+ }
- remote_hostio_close (find_target_at (process_stratum), fd, &remote_errno);
-}
+ ~scoped_remote_fd ()
+ {
+ if (m_fd != -1)
+ {
+ try
+ {
+ int remote_errno;
+ remote_hostio_close (find_target_at (process_stratum),
+ m_fd, &remote_errno);
+ }
+ catch (...)
+ {
+ /* Swallow exception before it escapes the dtor. If
+ something goes wrong, likely the connection is gone,
+ and there's nothing else that can be done. */
+ }
+ }
+ }
+
+ DISABLE_COPY_AND_ASSIGN (scoped_remote_fd);
+
+ /* Release ownership of the file descriptor, and return it. */
+ int release () noexcept
+ {
+ int fd = m_fd;
+ m_fd = -1;
+ return fd;
+ }
+
+ /* Return the owned file descriptor. */
+ int get () const noexcept
+ {
+ return m_fd;
+ }
+
+private:
+ /* The owned remote I/O file descriptor. */
+ int m_fd;
+};
void
remote_file_put (const char *local_file, const char *remote_file, int from_tty)
{
- struct cleanup *back_to, *close_cleanup;
- int retcode, fd, remote_errno, bytes, io_size;
+ struct cleanup *back_to;
+ int retcode, remote_errno, bytes, io_size;
gdb_byte *buffer;
int bytes_in_buffer;
int saw_eof;
if (file == NULL)
perror_with_name (local_file);
- fd = remote_hostio_open (find_target_at (process_stratum), NULL,
- remote_file, (FILEIO_O_WRONLY | FILEIO_O_CREAT
- | FILEIO_O_TRUNC),
- 0700, 0, &remote_errno);
- if (fd == -1)
+ scoped_remote_fd fd
+ (remote_hostio_open (find_target_at (process_stratum), NULL,
+ remote_file, (FILEIO_O_WRONLY | FILEIO_O_CREAT
+ | FILEIO_O_TRUNC),
+ 0700, 0, &remote_errno));
+ if (fd.get () == -1)
remote_hostio_error (remote_errno);
/* Send up to this many bytes at once. They won't all fit in the
buffer = (gdb_byte *) xmalloc (io_size);
back_to = make_cleanup (xfree, buffer);
- close_cleanup = make_cleanup (remote_hostio_close_cleanup, &fd);
-
bytes_in_buffer = 0;
saw_eof = 0;
offset = 0;
bytes_in_buffer = 0;
retcode = remote_hostio_pwrite (find_target_at (process_stratum),
- fd, buffer, bytes,
+ fd.get (), buffer, bytes,
offset, &remote_errno);
if (retcode < 0)
offset += retcode;
}
- discard_cleanups (close_cleanup);
- if (remote_hostio_close (find_target_at (process_stratum), fd, &remote_errno))
+ if (remote_hostio_close (find_target_at (process_stratum),
+ fd.release (), &remote_errno))
remote_hostio_error (remote_errno);
if (from_tty)
void
remote_file_get (const char *remote_file, const char *local_file, int from_tty)
{
- struct cleanup *back_to, *close_cleanup;
- int fd, remote_errno, bytes, io_size;
+ struct cleanup *back_to;
+ int remote_errno, bytes, io_size;
gdb_byte *buffer;
ULONGEST offset;
struct remote_state *rs = get_remote_state ();
if (!rs->remote_desc)
error (_("command can only be used with remote target"));
- fd = remote_hostio_open (find_target_at (process_stratum), NULL,
- remote_file, FILEIO_O_RDONLY, 0, 0,
- &remote_errno);
- if (fd == -1)
+ scoped_remote_fd fd
+ (remote_hostio_open (find_target_at (process_stratum), NULL,
+ remote_file, FILEIO_O_RDONLY, 0, 0,
+ &remote_errno));
+ if (fd.get () == -1)
remote_hostio_error (remote_errno);
gdb_file_up file = gdb_fopen_cloexec (local_file, "wb");
buffer = (gdb_byte *) xmalloc (io_size);
back_to = make_cleanup (xfree, buffer);
- close_cleanup = make_cleanup (remote_hostio_close_cleanup, &fd);
-
offset = 0;
while (1)
{
bytes = remote_hostio_pread (find_target_at (process_stratum),
- fd, buffer, io_size, offset, &remote_errno);
+ fd.get (), buffer, io_size, offset,
+ &remote_errno);
if (bytes == 0)
/* Success, but no bytes, means end-of-file. */
break;
perror_with_name (local_file);
}
- discard_cleanups (close_cleanup);
- if (remote_hostio_close (find_target_at (process_stratum), fd, &remote_errno))
+ if (remote_hostio_close (find_target_at (process_stratum),
+ fd.release (), &remote_errno))
remote_hostio_error (remote_errno);
if (from_tty)
return -1;
trace_regblock_size
- = get_remote_arch_state (target_gdbarch ())->sizeof_g_packet;
+ = rs->get_remote_arch_state (target_gdbarch ())->sizeof_g_packet;
putpkt ("qTStatus");
const char *cmd_name;
/* architecture specific data */
- remote_gdbarch_data_handle =
- gdbarch_data_register_post_init (init_remote_state);
remote_g_packet_data_handle =
gdbarch_data_register_pre_init (remote_g_packet_data_init);
/* Initialize the per-target state. At the moment there is only one
of these, not one per target. Only one target is active at a
time. */
- remote_state = new_remote_state ();
+ remote_state = new struct remote_state ();
add_target (remote_target_info, remote_target::open);
add_target (extended_remote_target_info, extended_remote_target::open);
/* Hook into new objfile notification. */
gdb::observers::new_objfile.attach (remote_new_objfile);
- /* We're no longer interested in notification events of an inferior
- when it exits. */
- gdb::observers::inferior_exit.attach (discard_pending_stop_replies);
#if 0
init_remote_threadtests ();