undefined reference to __udivdi3 (gcc-4.3)
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 14 lines · Christian Kujau
Hi,
while trying to compile current -git or 2.6.25.1 with gcc (Debian 4.3.0-4) 4.3.1 20080501 (prerelease), the following error occurs during linking:
arch/x86/xen/built-in.o: In function `xen_timer_interrupt':
time.c:(.text+0x2992): undefined reference to__udivdi3' time.c:(.text+0x2a13): undefined reference to__udivdi3'
make: *** [.tmp_vmlinux1] Error 1Searching the archives brought up old issues with gcc-3.4 [0] and not so old posting from 01/2008 [1], but I could not find a solution (or a consense about (not to) include libgcc.a).
Full make.log and .config: http://nerdbynature.de/bits/2.6.25.1/xen/
Quoted 7 lines
Hints welcome :)
Thanks,
Christian.[0] http://gcc.gnu.org/ml/gcc/2004-01/msg01975.html
[1] http://www.nabble.com/gcc-4.3:-Kernel-build-fails-td15135607.html
I assume it's one or both of these loops in arch/x86/xen/time.c do_stolen_accounting() that are being optimized into a divide which generates a libgcc call:
while (stolen >= NS_PER_TICK) {
ticks++;
stolen -= NS_PER_TICK;
}or
while (blocked >= NS_PER_TICK) {
ticks++;
blocked -= NS_PER_TICK;
}I seem to recall in one previous case we added some dummy assembly code to stop gcc from doing this. Not sure if that is a sustainable fix, though..
Quoted 7 lines
I assume it's one or both of these loops in
arch/x86/xen/time.cdo_stolen_accounting()that are being optimized into a divide which generates a libgcc call:while (stolen >= NS_PER_TICK) { ticks++; stolen -= NS_PER_TICK; }
Quoted 6 lines
or
while (blocked >= NS_PER_TICK) { ticks++; blocked -= NS_PER_TICK; }
That looks plausible.
Quoted 1 line
I seem to recall in one previous case we added some dummy assembly code to stop gcc from doing this.
I think you refer to 38332cb9, "time: prevent the loop in timespec_add_ns() from being optimised away".
while(unlikely(ns >= NSEC_PER_SEC)) {+ /* The following asm() prevents the compiler from
+ * optimising this loop into a modulo operation. */
+ asm("" : "+r"(ns));
+
ns -= NSEC_PER_SEC;
a->tv_sec++;
}Quoted 1 line
Not sure if that is a sustainable fix, though..
It should be. The asm() arg tells GCC that the asm() could modify "ns" in some way, so GCC cannot optimise away the loop, since it doesn't have the required info about the induction variable to do that.
Segher
Quoted 7 lines · Segher Boessenkool
Quoted 7 lines
I assume it's one or both of these loops in
arch/x86/xen/time.cdo_stolen_accounting()that are being optimized into a divide which generates a libgcc call:while (stolen >= NS_PER_TICK) { ticks++; stolen -= NS_PER_TICK; }
Quoted 8 lines
Quoted 6 lines
or
while (blocked >= NS_PER_TICK) { ticks++; blocked -= NS_PER_TICK; }That looks plausible.
Yep. Probably both.
Quoted 6 lines
Quoted 1 line
Not sure if that is a sustainable fix, though..
It should be. The
asm()arg tells GCC that theasm()could modify "ns" in some way, so GCC cannot optimise away the loop, since it doesn't have the required info about the induction variable to do that.
Yep, it's guaranteed to work. But it's an ugly hack to work around an over-enthusiastic compiler, and so is an inherent maintainability burden.
I think the correct fix here is to introduce an iter_div_rem() function which contains this hack, so we can avoid scattering it all over the place. I'll cook up a patch.
J
PATCH 1/1 common implementation of iterative div/mod
We have a few instances of the open-coded iterative div/mod loop, used when we don't expcet the dividend to be much bigger than the divisor. Unfortunately modern gcc's have the tendency to strength "reduce" this into a full mod operation, which isn't necessarily any faster, and even if it were, doesn't exist if gcc implements it in libgcc.
The workaround is to put a dummy asm statement in the loop to prevent gcc from performing the transformation.
This patch creates a single implementation of this loop, and uses it to replace the open-coded versions I know about.
---
arch/x86/xen/time.c | 13 +++---------- include/linux/math64.h | 2 ++ include/linux/time.h | 11 ++--------- lib/div64.c | 23 +++++++++++++++++++++++ 4 files changed, 30 insertions(+), 19 deletions(-)
===================================================================
arch/x86/xen/time.c +0 -0
@@ -12,6 +12,7 @@
#include <linux/clocksource.h>
#include <linux/clockchips.h>
#include <linux/kernel_stat.h>
+#include <linux/math64.h>
#include <asm/xen/hypervisor.h>
#include <asm/xen/hypercall.h>
@@ -150,11 +151,7 @@ static void do_stolen_accounting(void)
if (stolen < 0) stolen = 0;
- ticks = 0;
- while (stolen >= NS_PER_TICK) {
- ticks++;
- stolen -= NS_PER_TICK;
- }
+ ticks = iter_div_u64_rem(stolen, NS_PER_TICK, &stolen); __get_cpu_var(residual_stolen) = stolen; account_steal_time(NULL, ticks);
@@ -166,11 +163,7 @@ static void do_stolen_accounting(void)
if (blocked < 0) blocked = 0;
- ticks = 0;
- while (blocked >= NS_PER_TICK) {
- ticks++;
- blocked -= NS_PER_TICK;
- }
+ ticks = iter_div_u64_rem(blocked, NS_PER_TICK, &blocked); __get_cpu_var(residual_blocked) = blocked; account_steal_time(idle_task(smp_processor_id()), ticks); }
===================================================================
include/linux/math64.h +0 -0
@@ -81,4 +81,6 @@ static inline s64 div_s64(s64 dividend, }
#endif
+unsigned iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder); +
#endif /* _LINUX_MATH64_H */
===================================================================
include/linux/time.h +0 -0
@@ -2,6 +2,7 @@
#define _LINUX_TIME_H
#include <linux/types.h>
+#include <linux/math64.h>
#ifdef __KERNEL__
# include <linux/cache.h>
@@ -172,15 +173,7 @@ extern struct timeval ns_to_timeval(cons
*/
static inline void timespec_add_ns(struct timespec *a, u64 ns)
{
- ns += a->tv_nsec;
- while(unlikely(ns >= NSEC_PER_SEC)) {
- /* The following asm() prevents the compiler from
- * optimising this loop into a modulo operation. */
- asm("" : "+r"(ns));
-
- ns -= NSEC_PER_SEC;
- a->tv_sec++;
- }
+ a->tv_sec += iter_div_u64_rem(a->tv_nsec + ns, NSEC_PER_SEC, &ns);
a->tv_nsec = ns;
}
#endif /* __KERNEL__ */
===================================================================
--- a/lib/div64.c
+++ b/lib/div64.c
@@ -98,3 +98,26 @@ EXPORT_SYMBOL(div64_u64);
#endif#endif /* BITS_PER_LONG == 32 */
+
+/*
+ * Iterative div/mod for use when dividend is not expected to be much
+ * bigger than divisor.
+ */
+unsigned iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder) +{
+ unsigned ret = 0;
+
+ while(dividend >= divisor) {
+ /* The following asm() prevents the compiler from
+ optimising this loop into a modulo operation. */
+ asm("" : "+rm"(dividend));
+
+ dividend -= divisor;
+ ret++;
+ }
+
+ *remainder = dividend;
+
+ return ret;
+}
+EXPORT_SYMBOL(iter_div_u64_rem);
Re: [PATCH] common implementation of iterative div/mod
Quoted 11 lines · On Thu, 08 May 2008 16:16:41 +0100 Jeremy Fitzhardinge <[email protected]> wrote:
We have a few instances of the open-coded iterative div/mod loop, used when we don't expcet the dividend to be much bigger than the divisor. Unfortunately modern gcc's have the tendency to strength "reduce" this into a full mod operation, which isn't necessarily any faster, and even if it were, doesn't exist if gcc implements it in libgcc.
The workaround is to put a dummy asm statement in the loop to prevent gcc from performing the transformation.
This patch creates a single implementation of this loop, and uses it to replace the open-coded versions I know about.
Fair enough. I'll plan on feeding this into 2.6.26 soon.
Quoted 15 lines
#endif /*
BITS_PER_LONG== 32 */(quoted diff) +13
-0+ +/* + * Iterative div/mod for use when dividend is not expected to be much + * bigger than divisor. + */ +unsigned iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder) +{ + unsigned ret = 0; + + while(dividend >= divisor) { + /* The following asm() prevents the compiler from + optimising this loop into a modulo operation. */ + asm("" : "+rm"(dividend));
Review
Quoted 10 lines
(quoted diff) +10
-0+ + dividend -= divisor; + ret++; + } + + *remainder = dividend; + + return ret; +} +EXPORT_SYMBOL(iter_div_u64_rem);
I think it would be better to do s/unsigned/u32/ here. It's cosmetic, but all this sort of code is pretty formal about the sizes of the types which it uses, and it sure needs to be.
Re: [PATCH] common implementation of iterative div/mod
Quoted 7 lines · Andrew Morton
Quoted 3 lines · On Thu, 08 May 2008 16:16:41 +0100 Jeremy Fitzhardinge <[email protected]> wrote:
We have a few instances of the open-coded iterative div/mod loop, used when we don't expcet the dividend to be much bigger than the divisor.
If you get a chance, could you fix the tpyo.
Quoted 36 lines
Quoted 10 lines
Unfortunately modern gcc's have the tendency to strength "reduce" this into a full mod operation, which isn't necessarily any faster, and even if it were, doesn't exist if gcc implements it in libgcc.
The workaround is to put a dummy asm statement in the loop to prevent gcc from performing the transformation.
This patch creates a single implementation of this loop, and uses it to replace the open-coded versions I know about.
Fair enough. I'll plan on feeding this into 2.6.26 soon.
Quoted 22 lines
#endif /*
BITS_PER_LONG== 32 */(quoted diff) +21
-0+ +/* + * Iterative div/mod for use when dividend is not expected to be much + * bigger than divisor. + */ +unsigned iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder) +{ + unsigned ret = 0; + + while(dividend >= divisor) { + /* The following asm() prevents the compiler from + optimising this loop into a modulo operation. */ + asm("" : "+rm"(dividend)); + + dividend -= divisor; + ret++; + } + + *remainder = dividend; + + return ret;
Quoted 9 lines
Review
Quoted 4 lines
(quoted diff) +2
-0+} +EXPORT_SYMBOL(iter_div_u64_rem);I think it would be better to do s/unsigned/u32/ here. It's cosmetic, but all this sort of code is pretty formal about the sizes of the types which it uses, and it sure needs to be.
OK.
J
Re: [PATCH] common implementation of iterative div/mod
In reply to Jeremy FitzhardingeQuoted 8 lines
We have a few instances of the open-coded iterative div/mod loop, used when we don't expcet the dividend to be much bigger than the divisor. Unfortunately modern gcc's have the tendency to strength "reduce" this into a full mod operation, which isn't necessarily any faster, and even if it were, doesn't exist if gcc implements it in libgcc.
The workaround is to put a dummy asm statement in the loop to prevent gcc from performing the transformation.
It's not a "dummy" asm, it actually does something: it tells the compiler that it has to iterate the loop exactly as written, and not do something else. I.e., exactly the behaviour we want here.
Review
Quoted 1 line
(quoted diff) +1
-0+ ticks = iter_div_u64_rem(blocked, NS_PER_TICK, &blocked);
What a terrible function name.
Quoted 12 lines
static inline void
timespec_add_ns(struct timespec *a, u64 ns){(quoted diff) +1
-9- ns += a->tv_nsec; - while(unlikely(ns >= NSEC_PER_SEC)) { - /* The following asm() prevents the compiler from - * optimising this loop into a modulo operation. */ - asm("" : "+r"(ns)); - - ns -= NSEC_PER_SEC; - a->tv_sec++; - } + a->tv_sec += iter_div_u64_rem(a->tv_nsec + ns, NSEC_PER_SEC, &ns);
Quoted 2 lines
a->tv_nsec = ns; }
...and now the "meat" of this function isn't inline anymore. If we cared about not doing a divide here, you'll have to explain why taking this trivial loop out of line is a good idea.
Review
Quoted 5 lines
(quoted diff) +5
-0+unsigned iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder) +{ + unsigned ret = 0; + + while(dividend >= divisor) {
You removed the unlikely() here. Why?
Review
Quoted 3 lines
(quoted diff) +3
-0+ /* The following asm() prevents the compiler from + optimising this loop into a modulo operation. */ + asm("" : "+rm"(dividend));
You changed "+r" to "+rm" here. Why? Also, "rm" is an x86-ism, and this is generic code (it does work here, but why is it better than "r"?)
Quoted 1 line
+EXPORT_SYMBOL(iter_div_u64_rem);
Does this need to be exported?
Can I suggest an alternative approach? Define a macro (with a good, descriptive name!) for just the asm("" : "+r"(x)), and use that. Much smaller patch, much clearer code, and doesn't result in different (and worse) code generation, so it's a much safer change.
Segher
Re: [PATCH] common implementation of iterative div/mod
Quoted 6 lines · Segher Boessenkool
Quoted 2 lines
The workaround is to put a dummy asm statement in the loop to prevent gcc from performing the transformation.
It's not a "dummy" asm, it actually does something: it tells the compiler that it has to iterate the loop exactly as written, and not do something else. I.e., exactly the behaviour we want here.
No, it has no function of its own. It's bullying gcc into not performing an optimisation by giving the impression its doing something.
Quoted 3 lines
Quoted 1 line
+ ticks =
iter_div_u64_rem(blocked, NS_PER_TICK, &blocked);What a terrible function name.
It's consistent with the other functions defined here. I agree it isn't pretty. If you have a better suggestion, I'm all ears.
Quoted 15 lines
Quoted 13 lines
static inline void
timespec_add_ns(struct timespec *a, u64 ns){(quoted diff) +1
-9- ns += a->tv_nsec; - while(unlikely(ns >= NSEC_PER_SEC)) { - /* The following asm() prevents the compiler from - * optimising this loop into a modulo operation. */ - asm("" : "+r"(ns)); - - ns -= NSEC_PER_SEC; - a->tv_sec++; - } + a->tv_sec += iter_div_u64_rem(a->tv_nsec + ns, NSEC_PER_SEC, &ns); a->tv_nsec = ns;Quoted 1 line
}
Quoted 3 lines
...and now the "meat" of this function isn't inline anymore. If we cared about not doing a divide here, you'll have to explain why taking this trivial loop out of line is a good idea.
On x86-32 it compiles to 26 instructions and 47 bytes of code. Admittedly it might be smaller inline - or on a 64-bit machine - but I seriously doubt its suffering a huge performance hit from being out of line. These days the inline threshold is very small - probably under 10 instructions. A direct call/return is essentially free, since it can be trivially prefetched.
Quoted 7 lines
Review
Quoted 5 lines
(quoted diff) +5
-0+unsigned iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder) +{ + unsigned ret = 0; + + while(dividend >= divisor) {You removed the
unlikely()here. Why?
Because it didn't seem all that unlikely. Besides, it makes not one bit of difference to the code generated by my compiler.
Quoted 7 lines
Review
Quoted 3 lines
(quoted diff) +3
-0+ /* The following asm() prevents the compiler from + optimising this loop into a modulo operation. */ + asm("" : "+rm"(dividend));You changed "+r" to "+rm" here. Why? Also, "rm" is an x86-ism, and this is generic code (it does work here, but why is it better than "r"?)
"rm" isn't x86-specific. I just wanted to give the compiler the freedom to put the value in either register or memory if it wanted to.
Quoted 3 lines
Quoted 1 line
+EXPORT_SYMBOL(iter_div_u64_rem);
Does this need to be exported?
Everything else in the file is exported.
Quoted 5 lines
Can I suggest an alternative approach? Define a macro (with a good, descriptive name!) for just the
asm("" : "+r"(x)), and use that. Much smaller patch, much clearer code, and doesn't result in different (and worse) code generation, so it's a much safer change.
Uh, could you suggest a name? Something along the lines of prevent_gcc_from_strength_reducing_this_subtraction_loop_into_a_modulo_operation_thanks_oh_and_remember_to_use_it_in_all_the_right_places() springs to mind.
Rather than putting this unsightly (though with a smear of lipstick) hack into every open-coded iterative div-mod loop, we may as well implement it once and just look out for places which should be using it.
I don't think the "worse" code generation is much of an issue, since it isn't used anywhere performance critical, and moving the code out of line means there should be an overall reduction in code size.
J
Re: [PATCH] common implementation of iterative div/mod
In reply to Jeremy FitzhardingeHi Jeremy,
Quoted 2 lines · Jeremy Fitzhardinge
This patch creates a single implementation of this loop, and uses it to replace the open-coded versions I know about.
Thanks for the patch. Applying to 2.6.26-rc1 allowed me to compile with gcc-4.3. Feel free to add a Tested-by :-)
Thanks,
Christian.
Signature · 3 lines
BOFH excuse #442: Trojan horse ran out of hay
Re: [PATCH] common implementation of iterative div/mod
In reply to Jeremy FitzhardingeQuoted 11 lines · On Thu, 08 May 2008 16:16:41 +0100 Jeremy Fitzhardinge <[email protected]> wrote:
We have a few instances of the open-coded iterative div/mod loop, used when we don't expcet the dividend to be much bigger than the divisor. Unfortunately modern gcc's have the tendency to strength "reduce" this into a full mod operation, which isn't necessarily any faster, and even if it were, doesn't exist if gcc implements it in libgcc.
The workaround is to put a dummy asm statement in the loop to prevent gcc from performing the transformation.
This patch creates a single implementation of this loop, and uses it to replace the open-coded versions I know about.
Believe it or not, this patch causes one of my test machines to fail to find its disk.
good dmesg: http://userweb.kernel.org/~akpm/dmesg-t61p.txt
bad dmesg: http://userweb.kernel.org/~akpm/dmesg-t61p-dead.txt
config: http://userweb.kernel.org/~akpm/config-t61p.txt
Re: [PATCH] common implementation of iterative div/mod
Quoted 16 lines · Andrew Morton
Quoted 6 lines · On Thu, 08 May 2008 16:16:41 +0100 Jeremy Fitzhardinge <[email protected]> wrote:
We have a few instances of the open-coded iterative div/mod loop, used when we don't expcet the dividend to be much bigger than the divisor. Unfortunately modern gcc's have the tendency to strength "reduce" this into a full mod operation, which isn't necessarily any faster, and even if it were, doesn't exist if gcc implements it in libgcc.
Quoted 6 lines
The workaround is to put a dummy asm statement in the loop to prevent gcc from performing the transformation.
This patch creates a single implementation of this loop, and uses it to replace the open-coded versions I know about.
Quoted 6 lines
Believe it or not, this patch causes one of my test machines to fail to find its disk.
good dmesg: http://userweb.kernel.org/~akpm/dmesg-t61p.txt
bad dmesg: http://userweb.kernel.org/~akpm/dmesg-t61p-dead.txt
config: http://userweb.kernel.org/~akpm/config-t61p.txt
Uh, OK. Do your other test machines work with it? Are there any relevant config differences (x86-64 vs 32?).
Hm, it's not that it can't find its disk, I think it's this:
init[1]: segfault at ffffffffff7008d2 ip ffffffffff7008d2 sp 7fff86e67488 error 14
init[1]: segfault at ffffffffff7008d2 ip 311ac07628 sp 7fff86e66cb0 error 4 in libgcc_s-4.1.2-20070925.so.1[311ac00000+d000]
Is it that the vsyscall page is trying to call into the kernel?
notrace static noinline int do_realtime(struct timespec *ts)
{
unsigned long seq, ns;
do {
seq = read_seqbegin(>od->lock);
ts->tv_sec = gtod->wall_time_sec;
ts->tv_nsec = gtod->wall_time_nsec;
ns = vgetns();
} while (unlikely(read_seqretry(>od->lock, seq)));
timespec_add_ns(ts, ns);
return 0;
}timespec_add_ns() used to be entirely inlined, but now it contains the call to iter_div_u64_rem().
arch/x86/vdso/vclock_gettime.c has its own copies of other kernel functions which it can't directly call. We could add timespec_add_ns()/iter_div_u64_rem() to that list, though its pretty hacky. Could we link lib/div64.o into the vdso?
J
Re: [PATCH] common implementation of iterative div/mod
Quoted 5 lines · Jeremy Fitzhardinge
arch/x86/vdso/vclock_gettime.chas its own copies of other kernel functions which it can't directly call. We could add timespec_add_ns()/iter_div_u64_rem() to that list, though its pretty hacky. Could we linklib/div64.ointo the vdso?
You would need to annotate it and have a separate object file for the different sections. Also it would need to be compiled PIC.
Inlining is better.
-Andi
Re: [PATCH] common implementation of iterative div/mod
Quoted 4 lines · Andi Kleen
You would need to annotate it and have a separate object file for the different sections. Also it would need to be compiled PIC.
Inlining is better.
BTW, I'm seeing the memcpy() in __vdso_gettimeofday() not being inlined.
J
Re: [PATCH] common implementation of iterative div/mod
Quoted 7 lines · Jeremy Fitzhardinge
Quoted 4 lines · Andi Kleen
You would need to annotate it and have a separate object file for the different sections. Also it would need to be compiled PIC.
Inlining is better.
BTW, I'm seeing the
memcpy()in__vdso_gettimeofday()not being inlined.
Hmm works here. What compiler do you use? Normally gcc should recognize the memcpy is just two constant stores and always inline even with -Os.
nm --dynamic arch/x86/vdso/vdso.so
0000000000000000 A LINUX_2.6ffffffffff7007e0 T __vdso_clock_gettimeffffffffff700820 T __vdso_getcpuffffffffff700750 T __vdso_gettimeofdayffffffffff7007e0 W clock_gettimeffffffffff700820 W getcpuffffffffff700750 W gettimeofday
Anyways if your compiler or config cannot get that right it would need to switch to __inline_memcpy(), but that would be slower or explicit copying field by field.
If it's a common problem we could also implement a build time check, but normally such problems should be already caught in code review.
-Andi
Re: [PATCH] common implementation of iterative div/mod
Quoted 7 lines · Andi Kleen
Quoted 5 lines · Jeremy Fitzhardinge
Quoted 3 lines · Andi Kleen
You would need to annotate it and have a separate object file for the different sections. Also it would need to be compiled PIC.
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
Inlining is better.
BTW, I'm seeing the
memcpy()in__vdso_gettimeofday()not being inlined.Hmm works here. What compiler do you use? Normally gcc should recognize the memcpy is just two constant stores and always inline even with -Os.
It's:
jeremy@cosworth:~/hg/xen/paravirt/linux-x86_64$ gcc -v Reading specs from /usr/lib/gcc/x86_64-linux/3.4.4/specs Configured with: ../src/configure -v --enable-languages=c,c++,java,f77,pascal,objc,ada,treelang --prefix=/usr --libexecdir=/usr/lib --with-gxx-include-dir=/usr/include/c++/3.4 --enable-shared --with-system-zlib --enable-nls --without-included-gettext --program-suffix=-3.4 --enable-__cxa_atexit --enable-libstdcxx-allocator=mt --enable-clocale=gnu --enable-libstdcxx-debug --enable-java-gc=boehm --enable-java-awt=gtk --disable-werror x86_64-linux Thread model: posix gcc version 3.4.4 20050314 (prerelease) (Debian 3.4.3-13)
I think this is still a supported compiler, isn't it?
J
Re: [PATCH] common implementation of iterative div/mod
Quoted 15 lines
It's:
jeremy@cosworth:~/hg/xen/paravirt/linux-x86_64$ gcc -v Reading specs from /usr/lib/gcc/x86_64-linux/3.4.4/specs Configured with: ../src/configure -v --enable-languages=c,c++,java,f77,pascal,objc,ada,treelang --prefix=/usr --libexecdir=/usr/lib --with-gxx-include-dir=/usr/include/c++/3.4 --enable-shared --with-system-zlib --enable-nls --without-included-gettext --program-suffix=-3.4 --enable-__cxa_atexit --enable-libstdcxx-allocator=mt --enable-clocale=gnu --enable-libstdcxx-debug --enable-java-gc=boehm --enable-java-awt=gtk --disable-werror x86_64-linux Thread model: posix gcc version 3.4.4 20050314 (prerelease) (Debian 3.4.3-13)
Quoted 1 line
I think this is still a supported compiler, isn't it?
Yes. Here's a patch. You probably didn't see problems because you either don't have a glibc that supports the vdso or none of your programs gets the timezone from gettimeofday() [that is very obscure obsolete functionality anyways, normally it should be gotten from the disk locales]
-Andi
Use explicit copy in vdso_gettimeofday()
Jeremy's gcc 3.4 seems to be unable to inline a 8 byte memcpy. But the vdso doesn't support external references. Copy the structure members of struct timezone explicitely instead.
arch/x86/vdso/vclock_gettime.c +3 -3
@@ -106,9 +106,9 @@ int __vdso_gettimeofday(struct timeval *do_realtime ((struct timespec *)tv); tv->tv_usec /=1000 ;if (tz !=NULL ) { -/* This relies on gcc inlining the memcpy. We'll notice -if it ever fails to do so. */ -memcpy (tz, >od->sys_tz,sizeof (struct timezone )); +/* Don't use memcpy. Some old compilers fail to inline it */ + tz->tz_minuteswest = gtod->sys_tz.tz_minuteswest; + tz->tz_dsttime = gtod->sys_tz.tz_dsttime; }return 0 ; }
Re: [PATCH] common implementation of iterative div/mod
Quoted 14 lines · Andi Kleen
Quoted 14 lines
It's:
jeremy@cosworth:~/hg/xen/paravirt/linux-x86_64$ gcc -v Reading specs from /usr/lib/gcc/x86_64-linux/3.4.4/specs Configured with: ../src/configure -v --enable-languages=c,c++,java,f77,pascal,objc,ada,treelang --prefix=/usr --libexecdir=/usr/lib --with-gxx-include-dir=/usr/include/c++/3.4 --enable-shared --with-system-zlib --enable-nls --without-included-gettext --program-suffix=-3.4 --enable-__cxa_atexit --enable-libstdcxx-allocator=mt --enable-clocale=gnu --enable-libstdcxx-debug --enable-java-gc=boehm --enable-java-awt=gtk --disable-werror x86_64-linux Thread model: posix gcc version 3.4.4 20050314 (prerelease) (Debian 3.4.3-13)
Quoted 8 lines
Quoted 2 lines
I think this is still a supported compiler, isn't it?
Yes. Here's a patch. You probably didn't see problems because you either don't have a glibc that supports the vdso or none of your programs gets the timezone from
gettimeofday()[that is very obscure obsolete functionality anyways, normally it should be gotten from the disk locales]
Patch looks fine to me. I just noticed the call to memcpy by inspection; I haven't tried to run this.
J