This is the mail archive of the
cygwin-apps
mailing list for the Cygwin project.
Re: [64bit] openldap compilation doesn't produce shared libraries
- From: Corinna Vinschen <corinna-cygwin at cygwin dot com>
- To: cygwin-apps at cygwin dot com
- Date: Wed, 19 Jun 2013 11:42:01 +0200
- Subject: Re: [64bit] openldap compilation doesn't produce shared libraries
- References: <87sj13i801 dot fsf at oracle dot com> <51A8D6C0 dot 3060507 at users dot sourceforge dot net> <51B1945E dot 6060002 at users dot sourceforge dot net> <87obbil3hb dot fsf at VZELL-LAP dot de dot oracle dot com> <87wqq2cotj dot fsf at oracle dot com> <20130610095305 dot GA32691 at calimero dot vinschen dot de> <87bo7ekuaz dot fsf at VZELL-LAP dot de dot oracle dot com> <51B925EC dot 1090706 at users dot sourceforge dot net> <20130613081928 dot GA15436 at calimero dot vinschen dot de>
- Reply-to: cygwin-apps at cygwin dot com
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