[PATCH 3/4] Explicit fixed-width integral File I/O protocol types

Julio Guerra
2018-04-28T01:19:51Z

The File I/O extension defines portable types of there host-specific
counterparts, such as `struct stat` and `struct timeval`. This patch improves
these type definitions in `include/gdb/fileio.h` to make possible sharing them
with target programs, and avoid redefining them by being able to include this
header, even with cross-compiled programs.

The patch thus removes several drawbacks:
- avoid implicit pointers when defining fixed-width integers as array typedefs.
- explicitly state the sizes of fixed-width integers (e.g. fio_ulong_t becomes
fio_uint64_t).
It also renames a few misnamed conversion functions with the convention
`host_to_fileio_*` used everywhere else.

Note that fixed-width integer types are defined using GCC's preprocessor builtin
macros to avoid using the libc's stdint.h which might not be available on the
target compiler. Therefore, `include/gdb/fileio.h` is standalone.

Tested with https://github.com/farjump/raspberry-pi/blob/ea31c48d7c7eed27d39fb1bec2d3a1d308cb8ae7/sdk/libalpha/include/alpha/fileio.h#L13

2018-04-28 Julio Guerra <julio@farjump.io>

* include/gdb/fileio.h: explicit fixed-width integral File I/O protocol types.
* gdb/common/fileio.c: explicit fixed-width integral File I/O protocol types.
* gdb/common/fileio.h: explicit fixed-width integral File I/O protocol types.
* gdb/remote-fileio.c: explicit fixed-width integral File I/O protocol types.

Signed-off-by: Julio Guerra <julio@farjump.io>
---
gdb/ChangeLog | 7 ++++++
gdb/common/fileio.c | 39 +++++++++++++++--------------
gdb/common/fileio.h | 8 +++---
gdb/remote-fileio.c | 26 ++++++++++----------
include/gdb/fileio.h | 58 +++++++++++++++-----------------------------
5 files changed, 63 insertions(+), 75 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 6986798f08..dc7f7cd8ac 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,10 @@
+2018-04-28 Julio Guerra <julio@farjump.io>
+
+ * include/gdb/fileio.h: explicit fixed-width integral File I/O protocol types.
+ * gdb/common/fileio.c: explicit fixed-width integral File I/O protocol types.
+ * gdb/common/fileio.h: explicit fixed-width integral File I/O protocol types.
+ * gdb/remote-fileio.c: explicit fixed-width integral File I/O protocol types.
+
2018-04-28 Julio Guerra <julio@farjump.io>

* gdb/remote-fileio.c: do not clear the value of st_dev in File I/O's stat().
diff --git a/gdb/common/fileio.c b/gdb/common/fileio.c
index 912a7ede3c..71b2745434 100644
--- a/gdb/common/fileio.c
+++ b/gdb/common/fileio.c
@@ -205,17 +205,17 @@ fileio_mode_pack (mode_t mode)
/* Pack a host-format mode_t into an fio_mode_t. */

static void
-host_to_fileio_mode (mode_t num, fio_mode_t fnum)
+host_to_fileio_mode (mode_t num, fio_mode_t *fnum)
{
- host_to_bigendian (fileio_mode_pack (num), (char *) fnum, 4);
+ host_to_bigendian (fileio_mode_pack (num), (char *) fnum, sizeof (fio_mode_t));
}

/* Pack a host-format integer into an fio_ulong_t. */

static void
-host_to_fileio_ulong (LONGEST num, fio_ulong_t fnum)
+host_to_fileio_uint64 (LONGEST num, fio_uint64_t* fnum)
{
- host_to_bigendian (num, (char *) fnum, 8);
+ host_to_bigendian (num, (char *) fnum, sizeof (fio_uint64_t));
}

/* See fileio.h. */
@@ -225,31 +225,30 @@ host_to_fileio_stat (struct stat *st, struct fio_stat *fst)
{
LONGEST blksize;

- host_to_fileio_uint ((long) st->st_dev, fst->fst_dev);
- host_to_fileio_uint ((long) st->st_ino, fst->fst_ino);
- host_to_fileio_mode (st->st_mode, fst->fst_mode);
- host_to_fileio_uint ((long) st->st_nlink, fst->fst_nlink);
- host_to_fileio_uint ((long) st->st_uid, fst->fst_uid);
- host_to_fileio_uint ((long) st->st_gid, fst->fst_gid);
- host_to_fileio_uint ((long) st->st_rdev, fst->fst_rdev);
- host_to_fileio_ulong ((LONGEST) st->st_size, fst->fst_size);
+ host_to_fileio_uint32 ((long) st->st_dev, &fst->fst_dev);
+ host_to_fileio_uint32 ((long) st->st_ino, &fst->fst_ino);
+ host_to_fileio_mode (st->st_mode, &fst->fst_mode);
+ host_to_fileio_uint32 ((long) st->st_nlink, &fst->fst_nlink);
+ host_to_fileio_uint32 ((long) st->st_uid, &fst->fst_uid);
+ host_to_fileio_uint32 ((long) st->st_gid, &fst->fst_gid);
+ host_to_fileio_uint32 ((long) st->st_rdev, &fst->fst_rdev);
+ host_to_fileio_uint64 ((LONGEST) st->st_size, &fst->fst_size);
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
blksize = st->st_blksize;
#else
blksize = 512;
#endif
- host_to_fileio_ulong (blksize, fst->fst_blksize);
+ host_to_fileio_uint64 ((LONGEST) blksize, &fst->fst_blksize);
#if HAVE_STRUCT_STAT_ST_BLOCKS
- host_to_fileio_ulong ((LONGEST) st->st_blocks, fst->fst_blocks);
+ host_to_fileio_uint64 ((LONGEST) st->st_blocks, &fst->fst_blocks);
#else
/* FIXME: This is correct for DJGPP, but other systems that don't
have st_blocks, if any, might prefer 512 instead of st_blksize.
(eliz, 30-12-2003) */
- host_to_fileio_ulong (((LONGEST) st->st_size + blksize - 1)
- / blksize,
- fst->fst_blocks);
+ host_to_fileio_uint64 (((LONGEST) st->st_size + blksize - 1) / blksize,
+ &fst->fst_blocks);
#endif
- host_to_fileio_time (st->st_atime, fst->fst_atime);
- host_to_fileio_time (st->st_mtime, fst->fst_mtime);
- host_to_fileio_time (st->st_ctime, fst->fst_ctime);
+ host_to_fileio_time (st->st_atime, &fst->fst_atime);
+ host_to_fileio_time (st->st_mtime, &fst->fst_mtime);
+ host_to_fileio_time (st->st_ctime, &fst->fst_ctime);
}
diff --git a/gdb/common/fileio.h b/gdb/common/fileio.h
index 92d26742a7..85155ccf9a 100644
--- a/gdb/common/fileio.h
+++ b/gdb/common/fileio.h
@@ -53,17 +53,17 @@ host_to_bigendian (LONGEST num, char *buf, int bytes)
/* Pack a host-format integer into an fio_uint_t. */

static inline void
-host_to_fileio_uint (long num, fio_uint_t fnum)
+host_to_fileio_uint32 (long num, fio_uint32_t *fnum)
{
- host_to_bigendian ((LONGEST) num, (char *) fnum, 4);
+ host_to_bigendian ((LONGEST) num, (char *) fnum, sizeof (fio_uint32_t));
}

/* Pack a host-format time_t into an fio_time_t. */

static inline void
-host_to_fileio_time (time_t num, fio_time_t fnum)
+host_to_fileio_time (time_t num, fio_time_t *fnum)
{
- host_to_bigendian ((LONGEST) num, (char *) fnum, 4);
+ host_to_bigendian ((LONGEST) num, (char *) fnum, sizeof (fio_time_t));
}

/* Pack a host-format struct stat into a struct fio_stat. */
diff --git a/gdb/remote-fileio.c b/gdb/remote-fileio.c
index e855c682a0..2237787f72 100644
--- a/gdb/remote-fileio.c
+++ b/gdb/remote-fileio.c
@@ -286,16 +286,16 @@ remote_fileio_extract_ptr_w_len (char **buf, CORE_ADDR *ptrval, int *length)
}

static void
-remote_fileio_to_fio_long (LONGEST num, fio_long_t fnum)
+host_to_fileio_int64 (LONGEST num, fio_int64_t *fnum)
{
- host_to_bigendian (num, (char *) fnum, 8);
+ host_to_bigendian (num, (char *) fnum, sizeof (fio_int64_t));
}

static void
-remote_fileio_to_fio_timeval (struct timeval *tv, struct fio_timeval *ftv)
+host_to_fileio_timeval (struct timeval *tv, struct fio_timeval *ftv)
{
- host_to_fileio_time (tv->tv_sec, ftv->ftv_sec);
- remote_fileio_to_fio_long (tv->tv_usec, ftv->ftv_usec);
+ host_to_fileio_time (tv->tv_sec, &ftv->ftv_sec);
+ host_to_fileio_int64 (tv->tv_usec, &ftv->ftv_usec);
}

/* The quit handler originally installed. */
@@ -914,7 +914,7 @@ remote_fileio_func_fstat (char *buf)

if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
{
- host_to_fileio_uint (1, fst.fst_dev);
+ host_to_fileio_uint32 (1, &fst.fst_dev);
memset (&st, 0, sizeof (st));
st.st_mode = S_IFCHR | (fd == FIO_FD_CONSOLE_IN ? S_IRUSR : S_IWUSR);
st.st_nlink = 1;
@@ -997,7 +997,7 @@ remote_fileio_func_gettimeofday (char *buf)

if (ptrval)
{
- remote_fileio_to_fio_timeval (&tv, &ftv);
+ host_to_fileio_timeval (&tv, &ftv);

errno = target_write_memory (ptrval, (gdb_byte *) &ftv, sizeof ftv);
if (errno != 0)
@@ -1178,21 +1178,21 @@ remote_fileio_request (char *buf, int ctrlc_pending_p)
}
\f

-/* Unpack an fio_uint_t. */
+/* Unpack an fio_uint32_t. */

static unsigned int
-remote_fileio_to_host_uint (fio_uint_t fnum)
+remote_fileio_to_host_uint (fio_uint32_t fnum)
{
- return extract_unsigned_integer ((gdb_byte *) fnum, 4,
+ return extract_unsigned_integer ((gdb_byte *) &fnum, 4,
BFD_ENDIAN_BIG);
}

-/* Unpack an fio_ulong_t. */
+/* Unpack an fio_uint64_t. */

static ULONGEST
-remote_fileio_to_host_ulong (fio_ulong_t fnum)
+remote_fileio_to_host_ulong (fio_uint64_t fnum)
{
- return extract_unsigned_integer ((gdb_byte *) fnum, 8,
+ return extract_unsigned_integer ((gdb_byte *) &fnum, 8,
BFD_ENDIAN_BIG);
}

diff --git a/include/gdb/fileio.h b/include/gdb/fileio.h
index 7bb55f579f..8b37df4dfe 100644
--- a/include/gdb/fileio.h
+++ b/include/gdb/fileio.h
@@ -95,50 +95,32 @@
#define FILEIO_ULONG_MAX 18446744073709551615ULL

/* Integral types as used in protocol. */
-#if 0
-typedef __int32_t fio_int_t;
-typedef __uint32_t fio_uint_t, fio_mode_t, fio_time_t;
-typedef __int64_t fio_long_t;
-typedef __uint64_t fio_ulong_t;
-#endif
-
-#define FIO_INT_LEN 4
-#define FIO_UINT_LEN 4
-#define FIO_MODE_LEN 4
-#define FIO_TIME_LEN 4
-#define FIO_LONG_LEN 8
-#define FIO_ULONG_LEN 8
-
-typedef char fio_int_t[FIO_INT_LEN];
-typedef char fio_uint_t[FIO_UINT_LEN];
-typedef char fio_mode_t[FIO_MODE_LEN];
-typedef char fio_time_t[FIO_TIME_LEN];
-typedef char fio_long_t[FIO_LONG_LEN];
-typedef char fio_ulong_t[FIO_ULONG_LEN];
-
-/* Struct stat as used in protocol. For complete independence
- of host/target systems, it's defined as an array with offsets
- to the members. */
+typedef __INT32_TYPE__ fio_int32_t;
+typedef __UINT32_TYPE__ fio_uint32_t, fio_mode_t, fio_time_t;
+typedef __INT64_TYPE__ fio_int64_t;
+typedef __UINT64_TYPE__ fio_uint64_t;

+/* Struct stat as used in protocol. */
struct fio_stat {
- fio_uint_t fst_dev;
- fio_uint_t fst_ino;
- fio_mode_t fst_mode;
- fio_uint_t fst_nlink;
- fio_uint_t fst_uid;
- fio_uint_t fst_gid;
- fio_uint_t fst_rdev;
- fio_ulong_t fst_size;
- fio_ulong_t fst_blksize;
- fio_ulong_t fst_blocks;
- fio_time_t fst_atime;
- fio_time_t fst_mtime;
- fio_time_t fst_ctime;
+ fio_uint32_t fst_dev;
+ fio_uint32_t fst_ino;
+ fio_mode_t fst_mode;
+ fio_uint32_t fst_nlink;
+ fio_uint32_t fst_uid;
+ fio_uint32_t fst_gid;
+ fio_uint32_t fst_rdev;
+ fio_uint64_t fst_size;
+ fio_uint64_t fst_blksize;
+ fio_uint64_t fst_blocks;
+ fio_time_t fst_atime;
+ fio_time_t fst_mtime;
+ fio_time_t fst_ctime;
};

+/* Struct timeval as used in protocol. */
struct fio_timeval {
fio_time_t ftv_sec;
- fio_long_t ftv_usec;
+ fio_int64_t ftv_usec;
};

#endif /* GDB_FILEIO_H_ */
--
2.17.0