X-Recipient: archive-cygwin AT delorie DOT com DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:from:to:subject:message-id:reply-to :references:mime-version:content-type:in-reply-to; q=dns; s= default; b=TrXpWWc+jjcJT17aCXysQ9WQevqrTECv6YN5GB+7IgMmC2YLi3rNu 4YNaLLy5AXNnKEjP1rkUwgan7gipsTeFTR1JXNiObpWrfvE6OOqMLYREcxoUagD+ WQLYQ4KruLiIfvFC0yIBqUBi35f903/qeE6Dlg7FUKk5bqQ8jbXltk= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:from:to:subject:message-id:reply-to :references:mime-version:content-type:in-reply-to; s=default; bh=rKtQiELycaHh1iSFMAQWiNvAxyI=; b=prJOTUsx5iwKz8nI9hLeSIp82aMZ nNfBclTTKQN6bQI1grpYBgZREJKoE3ZpCmFep5x15YTaduCRwGhOZSiwIst5JxnP 1dDr3b/+DSDiRI/5Ep7sT/8VZ+NKm7s9gALCeb2DMJhfadiOOwaL6xC/0jruqgNi rv/xpxew/HE+2SM= Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.3.1 Date: Wed, 24 Apr 2013 15:47:49 +0200 From: Corinna Vinschen To: cygwin AT cygwin DOT com Subject: Porting to 64 bit Cygwin (was Re: Difference in 32/64-bit curl.) Message-ID: <20130424134749.GR26397@calimero.vinschen.de> Reply-To: cygwin AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com References: <51766C22 DOT 10702 AT bahnhof DOT se> <51770372 DOT 4070408 AT t-online DOT de> <20130424125930 DOT GQ26397 AT calimero DOT vinschen DOT de> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <20130424125930.GQ26397@calimero.vinschen.de> User-Agent: Mutt/1.5.21 (2010-09-15) On Apr 24 14:59, Corinna Vinschen wrote: > On Apr 23 23:56, Christian Franke wrote: > > Possibly a __builtin_va_list related gcc bug. > > This is rather unlikely. That code is shared between Cygwin and > Mingw, and chances are that the bug would have been found already. > > What about a type issue? int vs. long? For clearness I decided to add a quick lecture. Hope that's ok. The Cygwin x86_64 toolchain is using the LP64(*) data model. That means, in contrast to Windows, which uses an LLP64(*) data model, sizeof(long) != sizeof(int), just as on Linux. For comparison: Cygwin Windows Cygwin Linux x86_64 Linux Windows x86_64 i686 sizeof(int) 4 4 4 sizeof(long) 4 4 8 sizeof(size_t) 4 8 8 sizeof(void*) 4 8 8 This difference can result in interesting problems, especially when using Win32 functions, especially when using pointers to Windows datatypes like LONG, ULONG, DWORD. Given that Windows is LLP64, all of these are 4 byte in size, while `long' on Cygwin is 8 bytes. Take the example ReadFile: ReadFile (HANDLE, LPVOID, DWORD, LPDWORD, LPOVERLAPPED); In the 32 bit Cygwin and Mingw environments, as well as in the 64 bit Mingw environment, it is no problem to substitute DWORD with unsigned long: unsigned long number_of_bytes_read; [...] ReadFile (fhdl, buf, buflen, &number_of_bytes_read, NULL); However, in 64 bit Cygwin, using LP64, number_of_bytes_read is 8 bytes in size. But ReadFile expects a pointer to a 4 byte type. So the function will only change the lower 4 bytes of number_of_bytes_read, while the content of the upper 4 bytes is undefined. Here are a few donts which may help porting applications from the ILP32 to the new LP64 data model. Note that this is not a Cygwin-only problem. Many Linux applications suffered the same somewhat liberal handling of datatypes when x86_64 was new. - DON'T mix up int and long in printf/scanf. This: int i; long l; printf ("%d %ld\n", l, i); may not print what you think it should. - DON'T mix int and long pointers. int *ip = (int *) &my_long; /* Uh oh! */ - DON'T mix int and pointers at all! THis will NOT work as expected anymore: void *ptr; printf ("Pointer value is %x\n", (int) ptr); - DON'T use functions returning pointers without declaration. For instance printf ("Error message is: %s\n", strerror (errno)); This code will CRASH, unless you included string.h. The implicit rule in C is that an undeclared function is of type int. But int is 4 byte and pointers are 8 byte, so the string pointer given to printf is missing the upper 4 bytes. Hilarity ensues ;) - DON'T use C base types together with Win32 functions. Keep in mind that DWORD, LONG, ULONG are *not* the same as long and unsigned long. Try to use only Win32 datatypes in conjunction with Win32 API function calls to avoid type problems. - DON'T mix Windows dataypes with POSIX type-specific MIN/MAX values. unsigned long l_max = ULONG_MAX; /* That's right. */ ULONG w32_biggest = ULONG_MAX; /* Hey, wait! What? */ ULONG w32_biggest = UINT_MAX; /* Ok. */ Always keep in mind that ULONG (or DWORD) != unsigned long but rather == unsigned int now. HTH, Corinna (*) http://en.wikipedia.org/wiki/LLP64#64-bit_data_models -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Maintainer cygwin AT cygwin DOT com Red Hat -- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple