[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