| 1 | Taken from https://github.com/wolfcw/libfaketime/pull/487
|
| 2 | Rebased onto v0.9.10
|
| 3 |
|
| 4 | From 86e067a01a7882d2140adcf085509e5d72ac3daa Mon Sep 17 00:00:00 2001
|
| 5 | From: Helge Deller <[email protected]>
|
| 6 | Date: Sun, 12 Jan 2025 22:23:16 +0000
|
| 7 | Subject: [PATCH 1/4] Interpose clock_gettime64
|
| 8 |
|
| 9 | Since debian generally added 64-bit time support on 32-bit
|
| 10 | arches, now glibc sometimes calls the clock_gettime64 syscall
|
| 11 | (and library wrapper). This function was missing, and is added here.
|
| 12 |
|
| 13 | Patch 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 |
|
| 20 | diff --git a/src/libfaketime.c b/src/libfaketime.c
|
| 21 | index e632395..b9d3d8d 100644
|
| 22 | |
| 23 | |
| 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");
|
| 76 | diff --git a/test/Makefile b/test/Makefile
|
| 77 | index 1b2a4aa..093d639 100644
|
| 78 | |
| 79 | |
| 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 | --
|
| 89 | 2.51.0
|
| 90 |
|
| 91 | From 1e2626e62e7f3fa3266fbdb93b69bc08a649feaa Mon Sep 17 00:00:00 2001
|
| 92 | From: Ian Jackson <[email protected]>
|
| 93 | Date: Fri, 17 Jan 2025 12:05:09 +0000
|
| 94 | Subject: [PATCH 2/4] Fix interposition of clock_gettime64
|
| 95 |
|
| 96 | timespec.tv_nsec is 32-bit, even though timeval.tv_usec is
|
| 97 | 64-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 |
|
| 133 | diff --git a/src/libfaketime.c b/src/libfaketime.c
|
| 134 | index b9d3d8d..6d9ec1c 100644
|
| 135 | |
| 136 | |
| 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 | --
|
| 147 | 2.51.0
|
| 148 |
|
| 149 | From a2d1dce073b7ffe50009584c89d0b7b061066d53 Mon Sep 17 00:00:00 2001
|
| 150 | From: Ian Jackson <[email protected]>
|
| 151 | Date: Fri, 17 Jan 2025 09:03:21 +0000
|
| 152 | Subject: [PATCH 3/4] Interpose __time64
|
| 153 |
|
| 154 | ---
|
| 155 | src/libfaketime.c | 21 +++++++++++++++++++++
|
| 156 | 1 file changed, 21 insertions(+)
|
| 157 |
|
| 158 | diff --git a/src/libfaketime.c b/src/libfaketime.c
|
| 159 | index 6d9ec1c..f3706a3 100644
|
| 160 | |
| 161 | |
| 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 | --
|
| 191 | 2.51.0
|
| 192 |
|
| 193 | From dfc04d2e0b11903a9db1e0b9d435b4c58c4b27ef Mon Sep 17 00:00:00 2001
|
| 194 | From: Ian Jackson <[email protected]>
|
| 195 | Date: Fri, 17 Jan 2025 12:08:23 +0000
|
| 196 | Subject: [PATCH 4/4] Interpose gettimeofday64
|
| 197 |
|
| 198 | ---
|
| 199 | src/libfaketime.c | 19 +++++++++++++++++++
|
| 200 | 1 file changed, 19 insertions(+)
|
| 201 |
|
| 202 | diff --git a/src/libfaketime.c b/src/libfaketime.c
|
| 203 | index f3706a3..0270f93 100644
|
| 204 | |
| 205 | |
| 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 | --
|
| 240 | 2.51.0
|
| 241 |
|