Bug#1108322: gcc-14: Fix broken ada timespec record with -D_TIME_BITS=64 on 32-bit big-endian targets
John David Anglin <[email protected]> Wed, 25 Jun 2025 17:22:52 -0400
| Newsgroups | gmane.linux.debian.ports.hppa |
|---|---|
| Message-ID | <175088657232.30355.16314369854555370570.reportbug__29419.8387813353$1750886739$gmane$org@mx3210> |
Source: gcc-14 Severity: normal Tags: patch X-Debbugs-Cc: [email protected] User: [email protected] 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
ada-tv_nsec-size.diff
(text/plain, 778 B)
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");
}