public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
From: Corinna Vinschen <corinna-cygwin@cygwin.com>
To: cygwin@cygwin.com
Subject: Re: Threads
Date: Tue, 21 Oct 2014 11:17:00 -0000	[thread overview]
Message-ID: <20141021111724.GA12476@calimero.vinschen.de> (raw)
In-Reply-To: <54456964.4090007@cornell.edu>

[-- Attachment #1: Type: text/plain, Size: 2969 bytes --]

On Oct 20 15:58, Ken Brown wrote:
> On 10/20/2014 3:03 PM, Corinna Vinschen wrote:
> >One of the headaches when porting is sometimes the ABI.  While on Linux
> >the first 6 arguments to a function are given in registers, on Windows
> >only 4 args are in registers.  This can result in bugs when calling
> >functions with more than 4 parameters, which are invisible on Linux, due
> >to the way 32 bit parameter are stored in registers on x86_64.  This
> >happened to us already for at least one package.
> 
> Am I right in thinking this can only be an issue if the source includes
> assembler code?

No.  This can be easily trigger by a bug in C code.  What happens is
this:

The 64 bit ABI is defined so that the first function args are passed
to the called functions via CPU registers.  On Windows the ABI uses 4
such registers(*), on Linux 6(**).  All following arguments are passed
on the stack.

The AMD64 CPUs introduced the following behaviour:  If a 32 bit value
(for instance, an int in C) is written to a register, the CPU
automatically clears the upper 32 bits of the register.  For instance:

  %rdx == 0x0123456789abcdef

  mov.l $0x42,%edx		<- This is a 32 bit mov!

  ==> %rdx == 0x0000000000000042

  No sign extension:

  mov.l $0xffffffff,%edx

  ==> %rdx == 0x00000000ffffffff

Now consider what happens if, for instance, the 5th argument to a
stdargs function is expecting a pointer value.  The caller calls the
function like this:

  foo (a, b, c, d, 0);

The 0 is int, it's not extendend to 64 bit.  On Linux, nothing bad
happens, because the 0 will be passed over to foo via register R8,
so the upper 32 bits are cleared.  On Cygwin, the 5th parameter is
passed via the stack, 64 bit aligned.  The upper 32 bits will not
be explicitely written.  They will contain random bytes.  foo doesn't
get a NULL pointer, but something like 0xdeadbeef00000000.  Here's
an example:

  $ cat > p.c <<EOF
  #include <stdio.h>

  int
  main ()
  {
    printf ("prepare stack:\n%p\n%p\n%p\n%p\n%p\n%p\n",
	    0x1111111111111111UL, 0x2222222222222222UL, 0x3333333333333333UL,
	    0x4444444444444444UL, 0x5555555555555555UL, 0x6666666666666666UL);
    printf ("\nprint null ptr:\n%p\n%p\n%p\n%p\n%p\n%p\n", 0, 0, 0, 0, 0, 0);
  }
  EOF
  $ gcc -g -o p p.c
  $ ./p

The same problem might occur if some code uses a function unprototyped.
My favorite example:

  /* Don't include string,h */
  printf ("Error message is: %s\n", strerror (errno));

Long story short, I have no idea if that's your problem at all, but I
thought I should at least mention it.


Corinna

(*) http://en.wikipedia.org/wiki/X86_calling_conventions#Microsoft_x64_calling_convention
(**) http://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI


-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

  reply	other threads:[~2014-10-21 11:17 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-10-20 13:04 Threads Ken Brown
2014-10-20 16:43 ` Threads Corinna Vinschen
2014-10-20 19:03   ` Threads Corinna Vinschen
2014-10-20 19:58     ` Threads Ken Brown
2014-10-21 11:17       ` Corinna Vinschen [this message]
2014-10-21 12:27         ` Threads Ken Brown
2014-10-23 11:31 ` Threads Jon TURNEY
2014-10-23 12:04   ` Threads Ken Brown
2014-10-23 15:37     ` Threads Corinna Vinschen
2014-10-23 18:07       ` Threads Achim Gratz
2014-10-23 20:32       ` Threads Ken Brown
2014-10-24  1:07         ` Threads Ken Brown
2014-10-24  9:46           ` Threads Corinna Vinschen
2014-10-24 11:05       ` Threads Jon TURNEY
2014-10-24 12:54         ` Threads Corinna Vinschen
2014-10-24 13:52           ` Threads Corinna Vinschen
2014-10-26 11:58             ` Threads Ken Brown
2014-10-28 10:44             ` Threads Jon TURNEY
2014-10-28 11:40               ` Threads Corinna Vinschen
2014-10-28 13:47                 ` Threads Ken Brown
2014-10-28 14:19                   ` [GOLDSTARS] Threads Corinna Vinschen
2014-10-28 17:39                     ` Andrew Schulman
2014-10-29 10:00                       ` Corinna Vinschen
  -- strict thread matches above, loose matches on Subject: below --
2014-10-26 13:20 Threads Angelo Graziosi
2014-10-26 21:38 ` Threads Ken Brown
2014-10-27 10:21   ` Threads Corinna Vinschen
2000-02-04  6:32 Threads M Dipperstein
2000-02-04  8:06 ` Threads Mumit Khan
1997-03-19 10:28 Threads Davind Maharaj

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20141021111724.GA12476@calimero.vinschen.de \
    --to=corinna-cygwin@cygwin.com \
    --cc=cygwin@cygwin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).