This is the mail archive of the cygwin-apps mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [64bit] openldap compilation doesn't produce shared libraries


On Jun 13 10:19, Corinna Vinschen wrote:
> On Jun 12 20:52, Yaakov (Cygwin/X) wrote:
> > That is where it is crashing, but after some debugging, AFAICS the
> > real culprit is the call to ber_scanf() in ldap_get_attribute_ber().
> > Presumably because this is a varargs function, the compiler wasn't
> > able to handle the necessary type promotion automatically (ber_len_t
> > is an unsigned long); so b->off was showing here as 0x600000000,
> > taking line 414 off to la-la land.  Patch attached and pushed to
> > Ports git.
> 
> Too bad.  This is a typical problem of projects which have been ported
> to 64 bit, but only to SYSV ABI, not to MS ABI.  The problem never shows
> up in the SYSV ABI (Linux, Solaris, etc), because arguments < 64 bit are
> zero extended when pushed on the stack.  Unfortunately, in the MS ABI,
> parameters < 64 bit are not zero extended so the higher bits can contain
> any random value.  Here, the uncasted 0 is int, so it's pushed on the
> stack with the higher 32 bit set to any garbage this stack address
> contains at the time.
> 
> Given our LP64-ness, I'm wondering if we couldn't tweak gcc to zero
> extend arguments as well, even when otherwise using the MS ABI...

Just for the records, this is utter nonsense.  That's apparently based
on a misunderstanding of the below mentioned Wikipedia article(*).  Note
to myself: First test, then speak.

In fact, apart from difference in layout and number of argument registers,
the SYSV ABI and MS ABI behave exactly the same.  See this example:

=== SNIP ===
#include <stdio.h>

int main ()
{
  fprintf (stderr, "%lx %lx %lx %lx %lx %lx\n", 0x1111111111111111,
                                                0x2222222222222222,
                                                0x3333333333333333,
                                                0x4444444444444444,
                                                0x5555555555555555,
                                                0x6666666666666666);
  fprintf (stdout, "%lx\n%lx\n%lx\n%lx\n%lx\n%lx\n", 1, 2, 3, 4, 5, 6);
  fprintf (stderr, "%lx %lx %lx %lx %lx %lx\n", 0x1111111111111111,
                                                0x2222222222222222,
                                                0x3333333333333333,
                                                0x4444444444444444,
                                                0x5555555555555555,
                                                0x6666666666666666);
  fprintf (stdout, "%lx\n%lx\n%lx\n%lx\n%lx\n%lx\n", -1, -2, -3, -4, -5, -6);
}
=== SNAP ===

The first and third fprintf are used to prime the stack with reproducible
values.  The second and forth fprintf will reuse the same stack slots.
Keep in mind that SYSV ABI uses 6 argument registeres, MS ABI only 4.
The first to registers are taken by the file pointer and format string,
so the first 4 printed args are in registers when using SYSV ABI, only
2 when using MS ABI:

  cygwin$ ./gcc-prop-sample 2> /dev/null
  1
  2
  3333333300000003
  4444444400000004
  5555555500000005
  6666666600000006

  ffffffff
  fffffffe
  33333333fffffffd
  44444444fffffffc
  55555555fffffffb
  66666666fffffffa

  linux$ ./gcc-prop-sample 2> /dev/null
  1
  2
  3
  4
  5555555500000005
  6666666600000006

  ffffffff
  fffffffe
  fffffffd
  fffffffc
  55555555fffffffb
  66666666fffffffa

As you can see, there's not the faintest difference.  The register
content is based on the AMD64 behaviour to clear the upper 32 bits
when using a 32 bit register write.  The upper 32 bits on the stack
are never overwritten when pushing 32 bit arguments on the stack,
in neither of the ABIs.

Therefore, the openldap problem is still a bug in openlap on 64 bit
LP64 targets.  It has not been registered by the devs because the 0
value was assigned to a register in SYSV ABI (and benfitting from the
aforementioned register write behaviour on AMD64), and the bug just
shows up in Cygwin because the argument is assigned to a stack slot in
MS ABI due to the lower number of arg registers.


Corinna

(*) http://en.wikipedia.org/wiki/X86_calling_convention#x86-64_calling_conventions


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]