aboutsummaryrefslogtreecommitdiff
path: root/gdbserver
diff options
context:
space:
mode:
Diffstat (limited to 'gdbserver')
-rw-r--r--gdbserver/hostio.cc62
-rw-r--r--gdbserver/linux-low.cc10
-rw-r--r--gdbserver/linux-low.h2
-rw-r--r--gdbserver/server.cc5
-rw-r--r--gdbserver/target.cc9
-rw-r--r--gdbserver/target.h7
-rw-r--r--gdbserver/tracepoint.cc6
-rw-r--r--gdbserver/utils.cc2
8 files changed, 89 insertions, 14 deletions
diff --git a/gdbserver/hostio.cc b/gdbserver/hostio.cc
index 17b6179..69729a8 100644
--- a/gdbserver/hostio.cc
+++ b/gdbserver/hostio.cc
@@ -89,12 +89,18 @@ require_filename (char **pp, char *filename)
return 0;
}
+template <typename T>
static int
-require_int (char **pp, int *value)
+require_int (char **pp, T *value)
{
+ constexpr bool is_signed = std::is_signed<T>::value;
+
char *p;
int count, firstdigit;
+ /* Max count of hexadecimal digits in T (1 hex digit is 4 bits). */
+ int max_count = sizeof (T) * CHAR_BIT / 4;
+
p = *pp;
*value = 0;
count = 0;
@@ -111,7 +117,8 @@ require_int (char **pp, int *value)
firstdigit = nib;
/* Don't allow overflow. */
- if (count >= 8 || (count == 7 && firstdigit >= 0x8))
+ if (count >= max_count
+ || (is_signed && count == (max_count - 1) && firstdigit >= 0x8))
return -1;
*value = *value * 16 + nib;
@@ -343,7 +350,8 @@ handle_open (char *own_buf)
static void
handle_pread (char *own_buf, int *new_packet_len)
{
- int fd, ret, len, offset, bytes_sent;
+ int fd, ret, len, bytes_sent;
+ off_t offset;
char *p, *data;
static int max_reply_size = -1;
@@ -410,7 +418,8 @@ handle_pread (char *own_buf, int *new_packet_len)
static void
handle_pwrite (char *own_buf, int packet_len)
{
- int fd, ret, len, offset;
+ int fd, ret, len;
+ off_t offset;
char *p, *data;
p = own_buf + strlen ("vFile:pwrite:");
@@ -504,7 +513,48 @@ handle_stat (char *own_buf, int *new_packet_len)
return;
}
- if (lstat (filename, &st) == -1)
+ if (stat (filename, &st) == -1)
+ {
+ hostio_error (own_buf);
+ return;
+ }
+
+ host_to_fileio_stat (&st, &fst);
+
+ bytes_sent = hostio_reply_with_data (own_buf,
+ (char *) &fst, sizeof (fst),
+ new_packet_len);
+
+ /* If the response does not fit into a single packet, do not attempt
+ to return a partial response, but simply fail. */
+ if (bytes_sent < sizeof (fst))
+ write_enn (own_buf);
+}
+
+static void
+handle_lstat (char *own_buf, int *new_packet_len)
+{
+ int ret, bytes_sent;
+ char *p;
+ struct stat st;
+ struct fio_stat fst;
+ char filename[HOSTIO_PATH_MAX];
+
+ p = own_buf + strlen ("vFile:lstat:");
+
+ if (require_filename (&p, filename)
+ || require_end (p))
+ {
+ hostio_packet_error (own_buf);
+ return;
+ }
+
+ if (hostio_fs_pid != 0)
+ ret = the_target->multifs_lstat (hostio_fs_pid, filename, &st);
+ else
+ ret = lstat (filename, &st);
+
+ if (ret == -1)
{
hostio_error (own_buf);
return;
@@ -641,6 +691,8 @@ handle_vFile (char *own_buf, int packet_len, int *new_packet_len)
handle_fstat (own_buf, new_packet_len);
else if (startswith (own_buf, "vFile:stat:"))
handle_stat (own_buf, new_packet_len);
+ else if (startswith (own_buf, "vFile:lstat:"))
+ handle_lstat (own_buf, new_packet_len);
else if (startswith (own_buf, "vFile:close:"))
handle_close (own_buf);
else if (startswith (own_buf, "vFile:unlink:"))
diff --git a/gdbserver/linux-low.cc b/gdbserver/linux-low.cc
index 1d223c1..3964270 100644
--- a/gdbserver/linux-low.cc
+++ b/gdbserver/linux-low.cc
@@ -751,7 +751,7 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp,
/* Set the event status. */
event_lwp->waitstatus.set_execd
(make_unique_xstrdup
- (linux_proc_pid_to_exec_file (event_thr->id.lwp ())));
+ (pid_to_exec_file (event_thr->id.lwp ())));
/* Mark the exec status as pending. */
event_lwp->stopped = 1;
@@ -6033,7 +6033,7 @@ linux_process_target::supports_pid_to_exec_file ()
const char *
linux_process_target::pid_to_exec_file (int pid)
{
- return linux_proc_pid_to_exec_file (pid);
+ return linux_proc_pid_to_exec_file (pid, linux_ns_same (pid, LINUX_NS_MNT));
}
bool
@@ -6050,6 +6050,12 @@ linux_process_target::multifs_open (int pid, const char *filename,
}
int
+linux_process_target::multifs_lstat (int pid, const char *filename, struct stat *sb)
+{
+ return linux_mntns_lstat (pid, filename, sb);
+}
+
+int
linux_process_target::multifs_unlink (int pid, const char *filename)
{
return linux_mntns_unlink (pid, filename);
diff --git a/gdbserver/linux-low.h b/gdbserver/linux-low.h
index 7d3e35f..e1c88ee 100644
--- a/gdbserver/linux-low.h
+++ b/gdbserver/linux-low.h
@@ -304,6 +304,8 @@ public:
int multifs_open (int pid, const char *filename, int flags,
mode_t mode) override;
+ int multifs_lstat (int pid, const char *filename, struct stat *st) override;
+
int multifs_unlink (int pid, const char *filename) override;
ssize_t multifs_readlink (int pid, const char *filename, char *buf,
diff --git a/gdbserver/server.cc b/gdbserver/server.cc
index 0ce40ee..ab69400 100644
--- a/gdbserver/server.cc
+++ b/gdbserver/server.cc
@@ -51,6 +51,7 @@
#include "gdbsupport/scoped_restore.h"
#include "gdbsupport/search.h"
#include "gdbsupport/gdb_argv_vec.h"
+#include "gdbsupport/remote-args.h"
/* PBUFSIZ must also be at least as big as IPA_CMD_BUF_SIZE, because
the client state data is passed directly to some agent
@@ -2863,7 +2864,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
{
char *end_buf = own_buf + strlen (own_buf);
sprintf (end_buf, ";QThreadOptions=%s",
- phex_nz (supported_options, sizeof (supported_options)));
+ phex_nz (supported_options));
}
strcat (own_buf, ";QThreadEvents+");
@@ -3465,7 +3466,7 @@ handle_v_run (char *own_buf)
else
program_path.set (new_program_name.get ());
- program_args = construct_inferior_arguments (new_argv.get (), true);
+ program_args = gdb::remote_args::join (new_argv.get ());
try
{
diff --git a/gdbserver/target.cc b/gdbserver/target.cc
index 4838b39..c400174c 100644
--- a/gdbserver/target.cc
+++ b/gdbserver/target.cc
@@ -258,7 +258,7 @@ target_pid_to_str (ptid_t ptid)
else if (ptid.tid () != 0)
return string_printf("Thread %d.0x%s",
ptid.pid (),
- phex_nz (ptid.tid (), sizeof (ULONGEST)));
+ phex_nz (ptid.tid ()));
else if (ptid.lwp () != 0)
return string_printf("LWP %d.%ld",
ptid.pid (), ptid.lwp ());
@@ -773,6 +773,13 @@ process_stratum_target::multifs_open (int pid, const char *filename,
}
int
+process_stratum_target::multifs_lstat (int pid, const char *filename,
+ struct stat *sb)
+{
+ return lstat (filename, sb);
+}
+
+int
process_stratum_target::multifs_unlink (int pid, const char *filename)
{
return unlink (filename);
diff --git a/gdbserver/target.h b/gdbserver/target.h
index af788e2..66ca72f 100644
--- a/gdbserver/target.h
+++ b/gdbserver/target.h
@@ -31,6 +31,7 @@
#include "gdbsupport/btrace-common.h"
#include <vector>
#include "gdbsupport/byte-vector.h"
+#include <sys/stat.h>
struct emit_ops;
struct process_info;
@@ -441,6 +442,12 @@ public:
virtual int multifs_open (int pid, const char *filename,
int flags, mode_t mode);
+ /* Multiple-filesystem-aware lstat. Like lstat(2), but operating in
+ the filesystem as it appears to process PID. Systems where all
+ processes share a common filesystem should not override this.
+ The default behavior is to use lstat(2). */
+ virtual int multifs_lstat (int pid, const char *filename, struct stat *sb);
+
/* Multiple-filesystem-aware unlink. Like unlink(2), but operates
in the filesystem as it appears to process PID. Systems where
all processes share a common filesystem should not override this.
diff --git a/gdbserver/tracepoint.cc b/gdbserver/tracepoint.cc
index 715cc63..b308c82 100644
--- a/gdbserver/tracepoint.cc
+++ b/gdbserver/tracepoint.cc
@@ -3461,8 +3461,8 @@ cmd_qtstatus (char *packet)
free_space (), phex_nz (trace_buffer_hi - trace_buffer_lo, 0),
circular_trace_buffer,
disconnected_tracing,
- phex_nz (tracing_start_time, sizeof (tracing_start_time)),
- phex_nz (tracing_stop_time, sizeof (tracing_stop_time)),
+ phex_nz (tracing_start_time),
+ phex_nz (tracing_stop_time),
buf1, buf2);
}
@@ -4990,7 +4990,7 @@ build_traceframe_info_xml (char blocktype, unsigned char *dataptr, void *data)
dataptr += sizeof (mlen);
string_xml_appendf (*buffer,
"<memory start=\"0x%s\" length=\"0x%s\"/>\n",
- paddress (maddr), phex_nz (mlen, sizeof (mlen)));
+ paddress (maddr), phex_nz (mlen));
break;
}
case 'V':
diff --git a/gdbserver/utils.cc b/gdbserver/utils.cc
index 092fe47..a86405e 100644
--- a/gdbserver/utils.cc
+++ b/gdbserver/utils.cc
@@ -102,5 +102,5 @@ internal_vwarning (const char *file, int line, const char *fmt, va_list args)
const char *
paddress (CORE_ADDR addr)
{
- return phex_nz (addr, sizeof (CORE_ADDR));
+ return phex_nz (addr);
}