summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2020-01-20 15:39:31 +0000
committerPedro Alves <palves@redhat.com>2020-01-20 15:39:31 +0000
commit36dc9e24472d1a5a3a3e08ecd139afbd3b0cf02b (patch)
treed0998e579cf50d2a6ffcdd466c0cf4d8cf1c8996
parent67b10306d19bd16ec9f3ca73b14aa82c789436e1 (diff)
downloadbinutils-gdb-36dc9e24472d1a5a3a3e08ecd139afbd3b0cf02b.tar.gz
Handle different "struct stat" between GDB and BFD
-rw-r--r--gdb/defs.h1
-rw-r--r--gdb/gdb_bfd.c45
-rw-r--r--gdb/gdb_bfd.h2
-rw-r--r--gdb/jit.c4
-rw-r--r--gdb/symfile.c2
-rw-r--r--gdbsupport/common-types.h13
6 files changed, 58 insertions, 9 deletions
diff --git a/gdb/defs.h b/gdb/defs.h
index 1ad52feb1f8..f38b9dc6ff5 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -34,7 +34,6 @@
#undef PACKAGE_TARNAME
#include <config.h>
-#include "bfd.h"
#include <sys/types.h>
#include <limits.h>
diff --git a/gdb/gdb_bfd.c b/gdb/gdb_bfd.c
index 5a6dee2d51a..82b6a6bbaa2 100644
--- a/gdb/gdb_bfd.c
+++ b/gdb/gdb_bfd.c
@@ -66,7 +66,7 @@ struct gdb_bfd_data
needs_relocations (0),
crc_computed (0)
{
- struct stat buf;
+ sys_stat buf;
if (bfd_stat (abfd, &buf) == 0)
{
@@ -355,24 +355,61 @@ gdb_bfd_iovec_fileio_close (struct bfd *abfd, void *stream)
return 0;
}
+/* Convert between a struct stat (potentially a gnulib replacement)
+ and a sys_stat (the system's struct stat). */
+
+static sys_stat
+to_sys_stat (struct stat *st)
+{
+ sys_stat sst {};
+
+#define COPY(FIELD) \
+ sst.FIELD = st->FIELD
+
+ COPY (st_dev);
+ COPY (st_ino);
+ COPY (st_mode);
+ COPY (st_nlink);
+ COPY (st_uid);
+ COPY (st_gid);
+ COPY (st_rdev);
+
+ /* Check for overflow? */
+ COPY (st_size);
+
+ // Should probably check _GL_WINDOWS_STAT_TIMESPEC and refer to
+ // st_atim, etc. instead.
+ COPY (st_atime);
+ COPY (st_mtime);
+ COPY (st_ctime);
+
+#undef COPY
+
+ return sst;
+}
+
/* Wrapper for target_fileio_fstat suitable for passing as the
STAT_FUNC argument to gdb_bfd_openr_iovec. */
static int
gdb_bfd_iovec_fileio_fstat (struct bfd *abfd, void *stream,
- struct stat *sb)
+ sys_stat *sb)
{
int fd = *(int *) stream;
int target_errno;
int result;
- result = target_fileio_fstat (fd, sb, &target_errno);
+ struct stat st;
+
+ result = target_fileio_fstat (fd, &st, &target_errno);
if (result == -1)
{
errno = fileio_errno_to_host (target_errno);
bfd_set_error (bfd_error_system_call);
}
+ *sb = to_sys_stat (&st);
+
return result;
}
@@ -818,7 +855,7 @@ gdb_bfd_openr_iovec (const char *filename, const char *target,
void *stream),
int (*stat_func) (struct bfd *abfd,
void *stream,
- struct stat *sb))
+ sys_stat *sb))
{
bfd *result = bfd_openr_iovec (filename, target,
open_func, open_closure,
diff --git a/gdb/gdb_bfd.h b/gdb/gdb_bfd.h
index 9b1e292bf18..f0ad4814a80 100644
--- a/gdb/gdb_bfd.h
+++ b/gdb/gdb_bfd.h
@@ -154,7 +154,7 @@ gdb_bfd_ref_ptr gdb_bfd_openr_iovec (const char *filename, const char *target,
void *stream),
int (*stat_func) (struct bfd *abfd,
void *stream,
- struct stat *sb));
+ sys_stat *sb));
/* A wrapper for bfd_openr_next_archived_file that initializes the
gdb-specific reference count. */
diff --git a/gdb/jit.c b/gdb/jit.c
index eeaab70bfe0..976f8555250 100644
--- a/gdb/jit.c
+++ b/gdb/jit.c
@@ -124,11 +124,11 @@ mem_bfd_iovec_pread (struct bfd *abfd, void *stream, void *buf,
/* For statting the file, we only support the st_size attribute. */
static int
-mem_bfd_iovec_stat (struct bfd *abfd, void *stream, struct stat *sb)
+mem_bfd_iovec_stat (struct bfd *abfd, void *stream, sys_stat *sb)
{
struct target_buffer *buffer = (struct target_buffer*) stream;
- memset (sb, 0, sizeof (struct stat));
+ memset (sb, 0, sizeof (sys_stat));
sb->st_size = buffer->size;
return 0;
}
diff --git a/gdb/symfile.c b/gdb/symfile.c
index f7bada75f35..65d342a53dd 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -1260,7 +1260,7 @@ separate_debug_file_exists (const std::string &name, unsigned long crc,
{
unsigned long file_crc;
int file_crc_p;
- struct stat parent_stat, abfd_stat;
+ sys_stat parent_stat, abfd_stat;
int verified_as_different;
/* Find a separate debug info file as if symbols would be present in
diff --git a/gdbsupport/common-types.h b/gdbsupport/common-types.h
index 61099b4e25d..8c136212c80 100644
--- a/gdbsupport/common-types.h
+++ b/gdbsupport/common-types.h
@@ -32,8 +32,21 @@ typedef unsigned long long ULONGEST;
#else /* GDBSERVER */
+/* Gnulib may replace struct stat with its own version. Bfd does not
+ use gnulib, so when we call into bfd, we must use the system struct
+ stat. */
+#define __need_system_sys_stat_h 1
+
+#include <sys/stat.h>
+
#include "bfd.h"
+typedef struct stat sys_stat;
+
+#undef __need_system_sys_stat_h
+
+#include <sys/stat.h>
+
/* * A byte from the program being debugged. */
typedef bfd_byte gdb_byte;