Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Wed, 7 May 2014 19:07:29 -0400
From: Rich Felker <dalias@...c.org>
To: musl@...ts.openwall.com
Cc: Pawel Dziepak <pdziepak@...rnos.org>
Subject: Re: [PATCH] add definition of max_align_t to stddef.h

On Wed, May 07, 2014 at 11:28:58AM +0200, Paweł Dziepak wrote:
> 2014-05-07 5:13 GMT+02:00 Rich Felker <dalias@...c.org>:
> > On Tue, May 06, 2014 at 12:35:55PM +0200, Paweł Dziepak wrote:
> >> >> would be a good thing to mach the definition gcc and clang use, i.e.
> >> >> something like that:
> >> >>
> >> >> union max_align_t {
> >> >>     alignas(long long) long long _ll;
> >> >>     alignas(long double) long double _ld;
> >> >> };
> >> >
> >> > This should not give results different from omitting the "alignas".
> >> > The only reason it does give different results is a bug in GCC, so we
> >> > should not be copying this confusing mess that's a no-op for a correct
> >> > compiler. (Applying alignas(T) to type T is always a no-op.)
> >>
> >> I should have checked whether GCC 4.9 has changed before sending that.
> >> As I said earlier, alignof in 4.9 seems to be fixed and on i386 for
> >> fundamental types values <=4 are returned. alignof(max_align_t)
> >> remains 8, though.
> >
> > Then GCC still has a bug. The above definition should give an
> > alignment of 4, not 8. Neither alignas(long long) nor alignas(long
> > double) should impose 8-byte alignment.
> 
> To clarify: GCC defines max_align_t so its alignment is 8. My original
> definition (without alignas) makes max_align_t 4-byte-aligned (both
> GCC 4.8.2 and 4.9). My second definition (with alignas) results in
> 8-byte-aligned max_align_t on GCC 4.8.2 and bug in GCC 4.9
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=61053
> 
> GCC uses its own __alignof__ to define max_align_t. __alignof__
> returns the recommended alignment (as oposed to minimal in case of
> alignof), which in case of long long is 8.

That's very confusing, so thanks for clarifying.

BTW, is __alignof__(long double) really giving 8? If so that's utter
nonsense. sizeof(long double) is 12, and alignment must always divide
the size of the type...

> >> However, while 4, undobtedly, is the expected value of
> >> alignof(max_align_t) I don't think that 8 is really wrong (well, from
> >> the C11 point of view). The standard is not very specific about what
> >> max_align_t really should be and if the compiler supports larger
> >> alignment in all contexts there is no reason that alignof(max_align_t)
> >> cannot be larger than alignof() of the type with the strictest
> >> alignment requirements.
> >> Obviously, since max_align_t is the part of ABI it is not like the
> >> implementation can set alignof(max_align_t) to any value or it would
> >> risk compatibility problems with binaries compiled with different
> >> max_align_t. Since both GCC and Clang already define max_align_t so
> >> that its alignment is 8 on i386 I think that Musl should do the same.
> >
> > If we want to achieve an alignment of 8, the above definition is
> > wrong; it will no longer have alignment 8 once the bug is fixed.
> > However I'm not convinced it's the right thing to do. Defining it as 8
> > is tightening malloc's contract to always return 8-byte-aligned memory
> > (note that it presently returns at least 16-byte alignment anyway, but
> > this is an implementation detail that's not meant to be observable,
> > not part of the interface contract).
> 
> I've mentioned earlier that it seems that the only option is to use
> GCC extensions (i.e. __alignof__) to match their definition of
> max_align_t, just like it is done in this patch:
> http://www.openwall.com/lists/musl/2014/04/28/3
> It is not nice that GCC forces malloc to support "extended" alignment
> but I don't think there is much that can be done about it.

I don't see how GCC "forces" this. The definition of max_align_t from
glibc's stddef.h, which we do not use, is what forces it.

As I see it, we have a choice whether to use the "8" definition on
i386 or use the natural definition, which would yield "4" on i386.
This is not an ABI issue (it does not affect the ability to use
glibc-built object files/binaries/shared libraries with musl, nor the
C++ name mangling ABI) but an API issue.

Moreover, I can't see any easy way that code assuming GCC's definition
could cause breakage on musl if we went with the other definition. The
x86 instructions that require additional alignment require at least
16-byte alignment, not 8-byte, so aligning as max_align_t will not
produce objects that can be used with sse instructions directly.

Rich

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.