Please do not reply to this email- if you want to comment on the bug, go to the URL shown below and enter your comments there.
Changed by [EMAIL PROTECTED] http://bugzilla.ximian.com/show_bug.cgi?id=76192 --- shadow/76192 2005-09-23 18:03:57.000000000 -0400 +++ shadow/76192.tmp.7376 2005-09-23 18:11:57.000000000 -0400 @@ -98,6 +98,49 @@ unsigned. ------- Additional Comments From [EMAIL PROTECTED] 2005-09-23 18:03 ------- Created an attachment (id=15787) Cleaned up version of little C demo program + +------- Additional Comments From [EMAIL PROTECTED] 2005-09-23 18:11 ------- +Ok... now my brain hurts. ;) + +If I'm reading that explanation correctly, and if I'm understanding +how this works, I *think* my patched version will give correct results +but it's uglier than it needs to be. + +The problem in the original is the sign extension in this bit: +(unsigned long)movedistance. + +That works on x86 because a long is 32 bits; it just makes it +unsigned, and it gets promoted to 64-bits in the | expression. On +x86_64 a long is 64 bits, and so the promotion performs sign extension +from 32 to 64 bits -- those extra sign bits then stomp all over the +upper 32 bits if you had an offset in the 2gb-4gb range. + +It needs to be converted first to unsigned and _then_ promoted to 64 +bits. Just changing (unsigned long) to (guint32) seems to do it: + +offset=((gint64) *highmovedistance << 32) | (guint32)movedistance; + +I've attached an updated little C program demoing it. A negative +offset appears to work the same as the original code, while a positive +offset in 2gb-3gb range fails with the original code on 64-bit and +works with the new code: + +Running on x86: +$ gcc -o try `pkg-config --cflags glib-2.0` try.c && ./try +off_t is 8 bytes +offset 3145728000 highmovedistance 0 distance -1149239296 +offset 3145728000 highmovedistance 0 distance -1149239296 +offset -65536 highmovedistance -1 distance -65536 +offset -65536 highmovedistance -1 distance -65536 + +Running on x86_64: +$ gcc -o try `pkg-config --cflags glib-2.0` try.c && ./try +off_t is 8 bytes +offset -1149239296 highmovedistance 0 distance -1149239296 +offset 3145728000 highmovedistance 0 distance -1149239296 +offset -65536 highmovedistance -1 distance -65536 +offset -65536 highmovedistance -1 distance -65536 + _______________________________________________ mono-bugs maillist - [email protected] http://lists.ximian.com/mailman/listinfo/mono-bugs
