[Mono-bugs] [Bug 76192][Nor] Changed - Can't write files past 2gb
on AMD64 (x86_64)
bugzilla-daemon at bugzilla.ximian.com
bugzilla-daemon at bugzilla.ximian.com
Fri Sep 23 18:11:57 EDT 2005
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 brion at pobox.com.
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 brion at pobox.com 2005-09-23 18:03 -------
Created an attachment (id=15787)
Cleaned up version of little C demo program
+
+------- Additional Comments From brion at pobox.com 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
+
More information about the mono-bugs
mailing list