[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1108322: gcc-14: Fix broken ada timespec record with -D_TIME_BITS=64 on 32-bit big-endian targets



Source: gcc-14
Severity: normal
Tags: patch
X-Debbugs-Cc: debian-hppa@lists.debian.org
User: debian-hppa@lists.debian.org
Usertags: hppa

Dear Maintainer,

The gnat patches applied to gcc-14 to support building with -D_TIME_BITS=64
-D_FILE_OFFSET_BITS=64 broke numerous tests in the gnat testsuite.

Analysis of the array39 test showed that the ada timespec record was
not correctly layed out.  See:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114065

In s-c_time.ads, we have

   type timespec is record
      tv_sec  : time_t range 0 .. OS_Constants.MAX_tv_sec;  --  seconds
      tv_nsec : nsec_t range 0 .. 999_999_999;              --  nanoseconds
   end record

but the struct __timespec64 is defined as follows:

#if __TIMESIZE == 64
# define __timespec64 timespec
#else
#include <endian.h>
/* The glibc Y2038-proof struct __timespec64 structure for a time value.
   To keep things Posix-ish, we keep the nanoseconds field a 32-bit
   signed long, but since the Linux field is a 64-bit signed int, we
   pad our tv_nsec with a 32-bit unnamed bit-field padding.

   As a general rule the Linux kernel is ignoring upper 32 bits of
   tv_nsec field.  */
struct __timespec64
{
  __time64_t tv_sec;         /* Seconds */
# if BYTE_ORDER == BIG_ENDIAN
  __int32_t :32;             /* Padding */
  __int32_t tv_nsec;         /* Nanoseconds */
# else
  __int32_t tv_nsec;         /* Nanoseconds */
  __int32_t :32;             /* Padding */
# endif
};
#endif

The nsec_t is currently defined using the size of the tv_nsec in
the __timespec 64 struct  but this ignores the padding on big-endian
targets.

The attached patch fixes this issue.

Regards,
Dave Anglin

-- System Information:
Debian Release: 13.0
  APT prefers unreleased
  APT policy: (500, 'unreleased'), (500, 'unstable')
Architecture: hppa (parisc64)

Kernel: Linux 6.12.33-dirty (SMP w/4 CPU threads)
Kernel taint flags: TAINT_WARN
Locale: LANG=en_CA.UTF-8, LC_CTYPE=en_CA.UTF-8 (charmap=UTF-8), LANGUAGE=en_CA:en
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)

-- no debconf information
Index: gcc-14-14.2.0/src/gcc/ada/s-oscons-tmplt.c
===================================================================
--- gcc-14-14.2.0.orig/src/gcc/ada/s-oscons-tmplt.c
+++ gcc-14-14.2.0/src/gcc/ada/s-oscons-tmplt.c
@@ -1769,9 +1769,12 @@ CNS(MAX_tv_sec, "")
   struct timespec ts;
 /*
    --  Sizes (in bytes) of the components of struct timespec.
-   --  The tv_sec field is the same than in struct timeval.
+   --  The tv_sec component is the same size as in struct timeval.
+   --  In order to avoid the endian issues in the glibc __timespec64
+   --  struct, we use the same size for the tv_nsec component as the
+   --  tv_sec component.
 */
-#define SIZEOF_tv_nsec (sizeof (ts.tv_nsec))
+#define SIZEOF_tv_nsec (sizeof (ts.tv_sec))
 CND(SIZEOF_tv_nsec, "tv_nsec");
 }
 

Reply to: