summaryrefslogtreecommitdiff
path: root/gnu
diff options
context:
space:
mode:
authorYelninei <yelninei@tutamail.com>2025-09-14 18:34:47 +0000
committerLudovic Courtès <ludo@gnu.org>2025-09-17 11:55:13 +0200
commit64c35295f5bcdd1305a78a907573ab4be169cebe (patch)
tree71e66c62108c6d124937bd81fba20a47929f4ea0 /gnu
parent19b98ac19e79e0ab136a31f68d552796865130aa (diff)
gnu: libfaketime: Fix 64-bit time_t on 32-bit platforms.
Fixes guix/guix#2633. * gnu/packages/patches/libfaketime-32bit.patch : New patch. * gnu/packages/check.scm (libfaketime)[#:phases]: Remove 'switch-libc-call phase and add phase applying the patch. In 'pre-check don't skip any tests. Change-Id: I86410d0cc8ef270c967ba880b10d4ae14181d783 Signed-off-by: Ludovic Courtès <ludo@gnu.org>
Diffstat (limited to 'gnu')
-rw-r--r--gnu/packages/check.scm33
-rw-r--r--gnu/packages/patches/libfaketime-32bit.patch241
2 files changed, 246 insertions, 28 deletions
diff --git a/gnu/packages/check.scm b/gnu/packages/check.scm
index 0b9e563f3bd..cfe6e6ba88d 100644
--- a/gnu/packages/check.scm
+++ b/gnu/packages/check.scm
@@ -3721,28 +3721,11 @@ portable to just about any platform.")
3721 3721
3722 #$@(if (target-64bit?) 3722 #$@(if (target-64bit?)
3723 #~() 3723 #~()
3724 #~((add-after 'unpack 'switch-libc-call 3724 #~((add-after 'unpack 'apply-32bit-patch
3725 (lambda _ 3725 (lambda _
3726 (substitute* "src/libfaketime.c" 3726 (let ((patch #$(local-file
3727 (("#define _GNU_SOURCE") 3727 (search-patch "libfaketime-32bit.patch"))))
3728 ;; Make sure to use the 64-bit 'struct timespec' in 3728 (invoke "patch" "--force" "-p1" "-i" patch))))))
3729 ;; replacement functions.
3730 (string-append "#define _GNU_SOURCE\n"
3731 "#define _FILE_OFFSET_BITS 64\n"
3732 "#define _TIME_BITS 64\n"))
3733 (("\"__clock_gettime\"")
3734 ;; Replace '__clock_gettime64' rather than
3735 ;; '__clock_gettime64' since this is what
3736 ;; newly-built applications use.
3737 "\"__clock_gettime64\""))
3738
3739 ;; XXX: Turn off 'pthread_cond_timedwait' etc.: tests
3740 ;; related to this are failing and this feature is
3741 ;; probably not useful for the purposes of running
3742 ;; code at a fixed date.
3743 (substitute* "src/Makefile"
3744 (("-DFAKE_PTHREAD")
3745 ""))))))
3746 3729
3747 (replace 'configure 3730 (replace 'configure
3748 (lambda* (#:key outputs #:allow-other-keys) 3731 (lambda* (#:key outputs #:allow-other-keys)
@@ -3762,13 +3745,7 @@ portable to just about any platform.")
3762 (add-before 'check 'pre-check 3745 (add-before 'check 'pre-check
3763 (lambda _ 3746 (lambda _
3764 (substitute* "test/functests/test_exclude_mono.sh" 3747 (substitute* "test/functests/test_exclude_mono.sh"
3765 (("/bin/bash") (which "bash"))) 3748 (("/bin/bash") (which "bash"))))))))
3766 #$@(if (target-64bit?)
3767 #~()
3768 ;; XXX: This test uses Perl to call 'clock_gettime' and
3769 ;; fails for unclear reasons on i686-linux.
3770 #~((delete-file
3771 "test/functests/test_exclude_mono.sh"))))))))
3772 (native-inputs (list perl)) ;for tests 3749 (native-inputs (list perl)) ;for tests
3773 (inputs (list coreutils-minimal)) 3750 (inputs (list coreutils-minimal))
3774 (synopsis "Fake the system time for single applications") 3751 (synopsis "Fake the system time for single applications")
diff --git a/gnu/packages/patches/libfaketime-32bit.patch b/gnu/packages/patches/libfaketime-32bit.patch
new file mode 100644
index 00000000000..b8ef2d0af01
--- /dev/null
+++ b/gnu/packages/patches/libfaketime-32bit.patch
@@ -0,0 +1,241 @@
1Taken from https://github.com/wolfcw/libfaketime/pull/487
2Rebased onto v0.9.10
3
4From 86e067a01a7882d2140adcf085509e5d72ac3daa Mon Sep 17 00:00:00 2001
5From: Helge Deller <deller@gmx.de>
6Date: Sun, 12 Jan 2025 22:23:16 +0000
7Subject: [PATCH 1/4] Interpose clock_gettime64
8
9Since debian generally added 64-bit time support on 32-bit
10arches, now glibc sometimes calls the clock_gettime64 syscall
11(and library wrapper). This function was missing, and is added here.
12
13Patch originally supplied here
14 https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1064555
15---
16 src/libfaketime.c | 24 ++++++++++++++++++++++++
17 test/Makefile | 2 +-
18 2 files changed, 25 insertions(+), 1 deletion(-)
19
20diff --git a/src/libfaketime.c b/src/libfaketime.c
21index e632395..b9d3d8d 100644
22--- a/src/libfaketime.c
23+++ b/src/libfaketime.c
24@@ -159,6 +159,13 @@ struct utimbuf {
25 #include <sys/random.h>
26 #endif
27
28+/* __timespec64 is needed for clock_gettime64 on 32-bit architectures */
29+struct __timespec64
30+{
31+ uint64_t tv_sec; /* Seconds */
32+ uint64_t tv_nsec; /* Nanoseconds */
33+};
34+
35 /*
36 * Per thread variable, which we turn on inside real_* calls to avoid modifying
37 * time multiple times of for the whole process to prevent faking time
38@@ -193,6 +200,7 @@ static time_t (*real_time) (time_t *);
39 static int (*real_ftime) (struct timeb *);
40 static int (*real_gettimeofday) (struct timeval *, void *);
41 static int (*real_clock_gettime) (clockid_t clk_id, struct timespec *tp);
42+static int (*real_clock_gettime64) (clockid_t clk_id, struct __timespec64 *tp);
43 static int (*real_timespec_get) (struct timespec *ts, int base);
44 #ifdef FAKE_INTERNAL_CALLS
45 static int (*real___ftime) (struct timeb *);
46@@ -2319,6 +2327,17 @@ int clock_gettime(clockid_t clk_id, struct timespec *tp)
47 return result;
48 }
49
50+/* this is used by 32-bit architectures only */
51+int __clock_gettime64(clockid_t clk_id, struct __timespec64 *tp64)
52+{
53+ struct timespec tp;
54+ int result;
55+
56+ result = clock_gettime(clk_id, &tp);
57+ tp64->tv_sec = tp.tv_sec;
58+ tp64->tv_nsec = tp.tv_nsec;
59+ return result;
60+}
61
62 #ifdef MACOS_DYLD_INTERPOSE
63 int macos_timespec_get(struct timespec *ts, int base)
64@@ -2652,6 +2671,11 @@ static void ftpl_init(void)
65 {
66 real_clock_gettime = dlsym(RTLD_NEXT, "clock_gettime");
67 }
68+ real_clock_gettime64 = dlsym(RTLD_NEXT, "clock_gettime64");
69+ if (NULL == real_clock_gettime64)
70+ {
71+ real_clock_gettime64 = dlsym(RTLD_NEXT, "__clock_gettime64");
72+ }
73 #ifdef FAKE_TIMERS
74 #if defined(__sun)
75 real_timer_gettime_233 = dlsym(RTLD_NEXT, "timer_gettime");
76diff --git a/test/Makefile b/test/Makefile
77index 1b2a4aa..093d639 100644
78--- a/test/Makefile
79+++ b/test/Makefile
80@@ -1,6 +1,6 @@
81 CC = gcc
82
83-CFLAGS += -std=gnu99 -Wall -DFAKE_STAT -Werror -Wextra $(FAKETIME_COMPILE_CFLAGS)
84+CFLAGS += -std=gnu99 -Wall -DFAKE_STAT -Werror -Wextra $(FAKETIME_COMPILE_CFLAGS) -U_FILE_OFFSET_BITS -U_TIME_BITS
85 LDFLAGS += -lrt -lpthread
86
87 SRC = timetest.c
88--
892.51.0
90
91From 1e2626e62e7f3fa3266fbdb93b69bc08a649feaa Mon Sep 17 00:00:00 2001
92From: Ian Jackson <ijackson@chiark.greenend.org.uk>
93Date: Fri, 17 Jan 2025 12:05:09 +0000
94Subject: [PATCH 2/4] Fix interposition of clock_gettime64
95
96timespec.tv_nsec is 32-bit, even though timeval.tv_usec is
9764-bit (weirdly). This doesn't matter very much in practice because
98 * on little endian architectures (which is all our 32-bit release
99 arches) writing to a too big integer ends up writing the
100 desired value in the desired location, and
101 * it doesn't affect the overall struct size on any of our actual
102 architectures (which align the uint64_t to 8 so must make the
103 whole struct 16 not 12), so the write overflow is harmless.
104
105> #include <time.h>
106> #include <sys/time.h>
107> #include <stdio.h>
108> struct timeval tv;
109> struct timespec ts;
110> int main(void) {
111> printf("time_t %lld\n", (unsigned long long) sizeof(time_t));
112> printf("timeval %lld %lld %lld\n",
113> (unsigned long long) sizeof(tv),
114> (unsigned long long) sizeof(tv.tv_sec),
115> (unsigned long long) sizeof(tv.tv_usec)
116> );
117> printf("timespec %lld %lld %lld\n",
118> (unsigned long long) sizeof(ts),
119> (unsigned long long) sizeof(ts.tv_sec),
120> (unsigned long long) sizeof(ts.tv_nsec)
121> );
122> }
123> (sid_armhf-dchroot)iwj@amdahl:~/Faketime/test$ gcc t.c
124> (sid_armhf-dchroot)iwj@amdahl:~/Faketime/test$ ./a.out
125> time_t 8
126> timeval 16 8 8
127> timespec 16 8 4
128> (sid_armhf-dchroot)iwj@amdahl:~/Faketime/test$
129---
130 src/libfaketime.c | 2 +-
131 1 file changed, 1 insertion(+), 1 deletion(-)
132
133diff --git a/src/libfaketime.c b/src/libfaketime.c
134index b9d3d8d..6d9ec1c 100644
135--- a/src/libfaketime.c
136+++ b/src/libfaketime.c
137@@ -163,7 +163,7 @@ struct utimbuf {
138 struct __timespec64
139 {
140 uint64_t tv_sec; /* Seconds */
141- uint64_t tv_nsec; /* Nanoseconds */
142+ uint32_t tv_nsec; /* this is 32-bit, apparently! */
143 };
144
145 /*
146--
1472.51.0
148
149From a2d1dce073b7ffe50009584c89d0b7b061066d53 Mon Sep 17 00:00:00 2001
150From: Ian Jackson <ijackson@chiark.greenend.org.uk>
151Date: Fri, 17 Jan 2025 09:03:21 +0000
152Subject: [PATCH 3/4] Interpose __time64
153
154---
155 src/libfaketime.c | 21 +++++++++++++++++++++
156 1 file changed, 21 insertions(+)
157
158diff --git a/src/libfaketime.c b/src/libfaketime.c
159index 6d9ec1c..f3706a3 100644
160--- a/src/libfaketime.c
161+++ b/src/libfaketime.c
162@@ -2339,6 +2339,27 @@ int __clock_gettime64(clockid_t clk_id, struct __timespec64 *tp64)
163 return result;
164 }
165
166+/* this is used by 32-bit architectures only */
167+uint64_t __time64(uint64_t *write_out)
168+{
169+ struct timespec tp;
170+ uint64_t output;
171+ int error;
172+
173+ error = clock_gettime(CLOCK_REALTIME, &tp);
174+ if (error == -1)
175+ {
176+ return (uint64_t)error;
177+ }
178+ output = tp.tv_sec;
179+
180+ if (write_out)
181+ {
182+ *write_out = output;
183+ }
184+ return output;
185+}
186+
187 #ifdef MACOS_DYLD_INTERPOSE
188 int macos_timespec_get(struct timespec *ts, int base)
189 #else
190--
1912.51.0
192
193From dfc04d2e0b11903a9db1e0b9d435b4c58c4b27ef Mon Sep 17 00:00:00 2001
194From: Ian Jackson <ijackson@chiark.greenend.org.uk>
195Date: Fri, 17 Jan 2025 12:08:23 +0000
196Subject: [PATCH 4/4] Interpose gettimeofday64
197
198---
199 src/libfaketime.c | 19 +++++++++++++++++++
200 1 file changed, 19 insertions(+)
201
202diff --git a/src/libfaketime.c b/src/libfaketime.c
203index f3706a3..0270f93 100644
204--- a/src/libfaketime.c
205+++ b/src/libfaketime.c
206@@ -166,6 +166,13 @@ struct __timespec64
207 uint32_t tv_nsec; /* this is 32-bit, apparently! */
208 };
209
210+/* __timespec64 is needed for clock_gettime64 on 32-bit architectures */
211+struct __timeval64
212+{
213+ uint64_t tv_sec; /* Seconds */
214+ uint64_t tv_usec; /* this is 64-bit, apparently! */
215+};
216+
217 /*
218 * Per thread variable, which we turn on inside real_* calls to avoid modifying
219 * time multiple times of for the whole process to prevent faking time
220@@ -2339,6 +2346,18 @@ int __clock_gettime64(clockid_t clk_id, struct __timespec64 *tp64)
221 return result;
222 }
223
224+/* this is used by 32-bit architectures only */
225+int __gettimeofday64(struct __timeval64 *tv64, void *tz)
226+{
227+ struct timeval tv;
228+ int result;
229+
230+ result = gettimeofday(&tv, tz);
231+ tv64->tv_sec = tv.tv_sec;
232+ tv64->tv_usec = tv.tv_usec;
233+ return result;
234+}
235+
236 /* this is used by 32-bit architectures only */
237 uint64_t __time64(uint64_t *write_out)
238 {
239--
2402.51.0
241