Re: svn commit: r283671 - head/sys/sys

2015-05-29 Thread Bruce Evans

On Fri, 29 May 2015, Brooks Davis wrote:


On Fri, May 29, 2015 at 05:40:16PM +1000, Bruce Evans wrote:

On Thu, 28 May 2015, Brooks Davis wrote:


Log:
 Revert r102953

 The bitfile padding was always unallocated on real-world FreeBSD systems and
 depended on the assumption that (abs(sizeof(long) - sizeof(char*)) <= 32).


Actually, it was bit-field padding that depended  on the assumption  that
(abs(sizeof(long) - sizeof(char*)) <= CHAR_BIT * sizeof(int).

It did work under this assumption, and was needed on non-real-world FreeBSD
systems with correctly-sized longs.  Why break it?


Actually, it only worked under the assumption that
sizeof(long) >= sizeof(char *) && .  It was nonsense when
sizeof(char *) > sizeof(long).  Then there is no way to unpad the char
* field to reduce the size, and no need for any padding or unpadding
to change the size since the char * field has the same size as the
union (under additional assumptions about alignment).  The nonsense
actually negatived the (negative) unpadding to get positive padding
that compiled.


It doesn't work on CHERI where pointers are 64, 128 or 256 bits
depending on the compilation mode and hardware type (in the latter two
cases they are not arithmetic types).


That was a nonsense case.  If you just fix the old code to use the
correct padding of 0 in this case, CHERI wouldn't notice the problem.


If this was something we were worried about in practice, forcing the
alignment of n_name and n_type to max(sizeof(long), sizeof(char *))
would accomplish the padding in a way that works for any compiler we
care about and irrespective of size.


This would defeat care taken elsewhere to use only C90 features in
headers.  But __aligned() is already used a lot.  Since it affects
semantics, it is correctly not defined as nothing, except in the
broken lint case.

Newer arches probably shouldn't support aout.  Then it is another
bug to include aout headers.  But the nlist_aout.h header is really
common for elf and aout -- the only aout-only part of it is the
union half of the ifdef.  It is in much better shape than the
documentation for nlist(3) -- nlist() is now used mainly for elf,
but is only documented for aout.

Bruce
___
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"


Re: svn commit: r283671 - head/sys/sys

2015-05-29 Thread Brooks Davis
On Fri, May 29, 2015 at 05:40:16PM +1000, Bruce Evans wrote:
> On Thu, 28 May 2015, Brooks Davis wrote:
> 
> > Log:
> >  Revert r102953
> >
> >  The bitfile padding was always unallocated on real-world FreeBSD systems 
> > and
> >  depended on the assumption that (abs(sizeof(long) - sizeof(char*)) <= 32).
> 
> Actually, it was bit-field padding that depended  on the assumption  that
> (abs(sizeof(long) - sizeof(char*)) <= CHAR_BIT * sizeof(int).
> 
> It did work under this assumption, and was needed on non-real-world FreeBSD
> systems with correctly-sized longs.  Why break it?

It doesn't work on CHERI where pointers are 64, 128 or 256 bits
depending on the compilation mode and hardware type (in the latter two
cases they are not arithmetic types).

If this was something we were worried about in practice, forcing the
alignment of n_name and n_type to max(sizeof(long), sizeof(char *))
would accomplish the padding in a way that works for any compiler we
care about and irrespective of size.

-- Brooks


pgpqhhPE8mdFc.pgp
Description: PGP signature


Re: svn commit: r283671 - head/sys/sys

2015-05-29 Thread Bruce Evans

On Thu, 28 May 2015, Brooks Davis wrote:


Log:
 Revert r102953

 The bitfile padding was always unallocated on real-world FreeBSD systems and
 depended on the assumption that (abs(sizeof(long) - sizeof(char*)) <= 32).


Actually, it was bit-field padding that depended  on the assumption  that
(abs(sizeof(long) - sizeof(char*)) <= CHAR_BIT * sizeof(int).

It did work under this assumption, and was needed on non-real-world FreeBSD
systems with correctly-sized longs.  Why break it?

A correctly-sized long is twice as large as a machine register, so it is 64
bits on i386 and 128 bits on amd64.  The 32 bits extra for this on i386 was
supported by the padding, but the 64-bits extra for this on amd64 is too
many.

Compilers now support an __int128_t type on amd64.  This is the correctly-
sized long for amd64.  But it is too difficult to use since it is not
spelled "long".  There is null support for printing this type, and it
being even longer than intmax_t must cause problems (e.g., casting it to
intmax_t for printing it doesn't work).  This is unusable, and not permitted
by standardards (intmax_t is specified to be capable of representing any
value of _any_ signed integer type, although it is not required to have
rank >= that of any signed integer type).  Expanding intmax_t to 128 bits
to support this type would cause larger problems since it would break
all ABIs that use intmax_t and pessimize most internal uses of intmax_t.

Similar bit-field padding in  is more important and depends
on even more relationships between type sizes, but handles up to 64 bits
of padding using 2 bit-fields.

BTW, someone broke namespaces in .  Old versions were careful
to use struct __timespec in the !__BSD_VISIBLE case.  Some time after 2001,
POSIX itself was broken to allow (but not require)  to declare
struct timespec.  FreeBSD was changed to take advantage of this
simplification, but by declaring and using struct timespec unconditionaly
it broke support for older versions of POSIX that don't allow this, and
turned its delicately layered includes into nonsense instead of over-
engineering.

Breaking  removed just 1 set of delicate bit-field padding.
Many cases were handled by ignoring the problem and/or living with
historical behaviour: from sys/stat.h:

X #if __BSD_VISIBLE
X   struct  timespec st_atimespec;  /* time of last access */
X   struct  timespec st_mtimespec;  /* time of last data modification */
X   struct  timespec st_ctimespec;  /* time of last file status change */
X #else
X   time_tst_atime; /* time of last access */
X   long  st_atimensec; /* nsec of last access */
X   time_tst_mtime; /* time of last data modification */
X   long  st_mtimensec; /* nsec of last data modification */
X   time_tst_ctime; /* time of last file status change */
X   long  st_ctimensec; /* nsec of last file status change */
X #endif

Here the nsec fields aren't really usable in the !__BSD_VISIBLE case.
They are essentially just sloppy padding using longs.  This happens to
work on all supported arches.  If time_t is 64 bits and long is 32 bits,
or vice versa, there may be padding from 96 total bits to 128, but it is
consistent.

X   off_t st_size;  /* file size, in bytes */
X   __int64_t st_blocks;/* blocks allocated for file */
X   __uint32_t st_blksize;  /* optimal blocksize for I/O */
X   fflags_t  st_flags; /* user defined flags for file */
X   __uint32_t st_gen;  /* file generation number */
X   __int32_t st_lspare;
X #if __BSD_VISIBLE
X   struct timespec st_birthtimespec; /* time of file creation */
X   /*
X* Explicitly pad st_birthtimespec to 16 bytes so that the size of
X* struct stat is backwards compatible.  We use bitfields instead
X* of an array of chars so that this doesn't require a C99 compiler
X* to compile if the size of the padding is 0.  We use 2 bitfields
X* to cover up to 64 bits on 32-bit machines.  We assume that
X* CHAR_BIT is 8...
X*/
X   unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec));
X   unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec));
X #else
X   time_tst_birthtime; /* time of file creation */
X   long  st_birthtimensec; /* nsec of file creation */
X   unsigned int :(8 / 2) * (16 - (int)sizeof(struct __timespec));
X   unsigned int :(8 / 2) * (16 - (int)sizeof(struct __timespec));
X #endif

Breaking the ifdef removed the second set of padding, but birthtimes
still need explicit padding in the struct case here and in struct
nstat (BTW, struct nstat is garbage.  It has something to do with
NetBSD compatibility, but with no other support for NetBSD compatibility
struct nstat is unsable and unused).

Someone, probably me, was more careful here than in nlist_aout.h.
Apparently the padd

svn commit: r283671 - head/sys/sys

2015-05-28 Thread Brooks Davis
Author: brooks
Date: Thu May 28 22:06:05 2015
New Revision: 283671
URL: https://svnweb.freebsd.org/changeset/base/283671

Log:
  Revert r102953
  
  The bitfile padding was always unallocated on real-world FreeBSD systems and
  depended on the assumption that (abs(sizeof(long) - sizeof(char*)) <= 32).
  
  Differential Revision:https://reviews.freebsd.org/D2667
  Reviewed by:  eadler
  Sponsored by: DARPA, AFRL

Modified:
  head/sys/sys/nlist_aout.h

Modified: head/sys/sys/nlist_aout.h
==
--- head/sys/sys/nlist_aout.h   Thu May 28 22:01:50 2015(r283670)
+++ head/sys/sys/nlist_aout.h   Thu May 28 22:06:05 2015(r283671)
@@ -56,8 +56,6 @@ struct nlist {
} n_un;
 #else
const char *n_name; /* symbol name (in memory) */
-   int : 8 * (sizeof(long) > sizeof(char *) ?
-   sizeof(long) - sizeof(char *) : sizeof(char *) - sizeof(long));
 #endif
unsigned char n_type;   /* type defines */
char n_other;   /* ".type" and binding information */
___
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"