mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-11-16 04:24:43 +00:00
gdb: implement linux namespace support for fileio_lstat and vFile::lstat
The new algorithm to look for a build-id-based debug file
(introduced by commit 22836ca885)
makes use of fileio_lstat. As lstat was not supported by
linux-namespace.c, all lstat calls would be performed on the host
and not inside the namespace. Fixed by adding namespace lstat
support.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32956
Approved-By: Andrew Burgess <aburgess@redhat.com>
This commit is contained in:
committed by
Andrew Burgess
parent
c29a37f741
commit
bd389c9515
@@ -4585,6 +4585,20 @@ linux_nat_target::fileio_open (struct inferior *inf, const char *filename,
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* Implementation of to_fileio_lstat. */
|
||||
|
||||
int
|
||||
linux_nat_target::fileio_lstat (struct inferior *inf, const char *filename,
|
||||
struct stat *sb, fileio_error *target_errno)
|
||||
{
|
||||
int r = linux_mntns_lstat (linux_nat_fileio_pid_of (inf), filename, sb);
|
||||
|
||||
if (r == -1)
|
||||
*target_errno = host_to_fileio_error (errno);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Implementation of to_fileio_readlink. */
|
||||
|
||||
std::optional<std::string>
|
||||
|
||||
@@ -108,6 +108,9 @@ public:
|
||||
const char *filename,
|
||||
fileio_error *target_errno) override;
|
||||
|
||||
int fileio_lstat (struct inferior *inf, const char *filename,
|
||||
struct stat *sb, fileio_error *target_errno) override;
|
||||
|
||||
int fileio_unlink (struct inferior *inf,
|
||||
const char *filename,
|
||||
fileio_error *target_errno) override;
|
||||
|
||||
@@ -233,6 +233,12 @@ enum mnsh_msg_type
|
||||
MNSH_RET_INT. */
|
||||
MNSH_REQ_SETNS,
|
||||
|
||||
/* A request that the helper call lstat. The single
|
||||
argument (the filename) should be passed in BUF, and
|
||||
should include a terminating NUL character. The helper
|
||||
should respond with a MNSH_RET_INTSTR. */
|
||||
MNSH_REQ_LSTAT,
|
||||
|
||||
/* A request that the helper call open. Arguments should
|
||||
be passed in BUF, INT1 and INT2. The filename (in BUF)
|
||||
should include a terminating NUL character. The helper
|
||||
@@ -284,6 +290,10 @@ mnsh_debug_print_message (enum mnsh_msg_type type,
|
||||
res += "ERROR";
|
||||
break;
|
||||
|
||||
case MNSH_REQ_LSTAT:
|
||||
res += "LSTAT";
|
||||
break;
|
||||
|
||||
case MNSH_REQ_SETNS:
|
||||
res += "SETNS";
|
||||
break;
|
||||
@@ -511,6 +521,20 @@ mnsh_handle_setns (int sock, int fd, int nstype)
|
||||
return mnsh_return_int (sock, result, errno);
|
||||
}
|
||||
|
||||
|
||||
/* Handle a MNSH_REQ_LSTAT message. Must be async-signal-safe. */
|
||||
|
||||
static ssize_t
|
||||
mnsh_handle_lstat (int sock, const char *filename)
|
||||
{
|
||||
struct stat sb;
|
||||
int stat_ok = lstat (filename, &sb);
|
||||
|
||||
return mnsh_return_intstr (sock, stat_ok, &sb,
|
||||
stat_ok == -1 ? 0 : sizeof (sb),
|
||||
errno);
|
||||
}
|
||||
|
||||
/* Handle a MNSH_REQ_OPEN message. Must be async-signal-safe. */
|
||||
|
||||
static ssize_t
|
||||
@@ -571,6 +595,11 @@ mnsh_main (int sock)
|
||||
response = mnsh_handle_setns (sock, fd, int1);
|
||||
break;
|
||||
|
||||
case MNSH_REQ_LSTAT:
|
||||
if (size > 0 && buf[size - 1] == '\0')
|
||||
response = mnsh_handle_lstat (sock, buf);
|
||||
break;
|
||||
|
||||
case MNSH_REQ_OPEN:
|
||||
if (size > 0 && buf[size - 1] == '\0')
|
||||
response = mnsh_handle_open (sock, buf, int1, int2);
|
||||
@@ -761,6 +790,10 @@ mnsh_maybe_mourn_peer (void)
|
||||
mnsh_send_message (helper->sock, MNSH_REQ_OPEN, -1, flags, mode, \
|
||||
filename, strlen (filename) + 1)
|
||||
|
||||
#define mnsh_send_lstat(helper, filename) \
|
||||
mnsh_send_message (helper->sock, MNSH_REQ_LSTAT, -1, 0, 0, \
|
||||
filename, strlen (filename) + 1)
|
||||
|
||||
#define mnsh_send_unlink(helper, filename) \
|
||||
mnsh_send_message (helper->sock, MNSH_REQ_UNLINK, -1, 0, 0, \
|
||||
filename, strlen (filename) + 1)
|
||||
@@ -943,6 +976,42 @@ linux_mntns_access_fs (pid_t pid)
|
||||
|
||||
/* See nat/linux-namespaces.h. */
|
||||
|
||||
int
|
||||
linux_mntns_lstat (pid_t pid, const char *filename,
|
||||
struct stat *sb)
|
||||
{
|
||||
enum mnsh_fs_code access = linux_mntns_access_fs (pid);
|
||||
|
||||
if (access == MNSH_FS_ERROR)
|
||||
return -1;
|
||||
|
||||
if (access == MNSH_FS_DIRECT)
|
||||
return lstat (filename, sb);
|
||||
|
||||
gdb_assert (access == MNSH_FS_HELPER);
|
||||
|
||||
struct linux_mnsh *helper = linux_mntns_get_helper ();
|
||||
|
||||
ssize_t size = mnsh_send_lstat (helper, filename);
|
||||
if (size < 0)
|
||||
return -1;
|
||||
|
||||
int stat_ok, error;
|
||||
size = mnsh_recv_intstr (helper, &stat_ok, &error, sb, sizeof (*sb));
|
||||
|
||||
if (size < 0)
|
||||
{
|
||||
stat_ok = -1;
|
||||
errno = error;
|
||||
}
|
||||
else
|
||||
gdb_assert (stat_ok == -1 || size == sizeof (*sb));
|
||||
|
||||
return stat_ok;
|
||||
}
|
||||
|
||||
/* See nat/linux-namespaces.h. */
|
||||
|
||||
int
|
||||
linux_mntns_open_cloexec (pid_t pid, const char *filename,
|
||||
int flags, mode_t mode)
|
||||
|
||||
@@ -64,6 +64,11 @@ enum linux_ns_type
|
||||
|
||||
extern int linux_ns_same (pid_t pid, enum linux_ns_type type);
|
||||
|
||||
/* Like lstat(2), but in the mount namespace of process PID. */
|
||||
|
||||
extern int linux_mntns_lstat (pid_t pid, const char *filename,
|
||||
struct stat *sb);
|
||||
|
||||
/* Like gdb_open_cloexec, but in the mount namespace of process
|
||||
PID. */
|
||||
|
||||
|
||||
@@ -525,7 +525,7 @@ handle_stat (char *own_buf, int *new_packet_len)
|
||||
static void
|
||||
handle_lstat (char *own_buf, int *new_packet_len)
|
||||
{
|
||||
int bytes_sent;
|
||||
int ret, bytes_sent;
|
||||
char *p;
|
||||
struct stat st;
|
||||
struct fio_stat fst;
|
||||
@@ -540,7 +540,12 @@ handle_lstat (char *own_buf, int *new_packet_len)
|
||||
return;
|
||||
}
|
||||
|
||||
if (lstat (filename, &st) == -1)
|
||||
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;
|
||||
|
||||
@@ -6049,6 +6049,12 @@ linux_process_target::multifs_open (int pid, const char *filename,
|
||||
return linux_mntns_open_cloexec (pid, filename, flags, mode);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -772,6 +772,13 @@ process_stratum_target::multifs_open (int pid, const char *filename,
|
||||
return open (filename, flags, mode);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -441,6 +441,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.
|
||||
|
||||
Reference in New Issue
Block a user