diff mbox series

[14/25] Add bits/types/ wrappers for stddef.h and stdarg.h types.

Message ID 20190626175029.4699-5-zackw@panix.com
State New
Headers show
Series Public header file hygiene improvements for 2.30 | expand

Commit Message

Zack Weinberg June 26, 2019, 5:50 p.m. UTC
We rely on the compiler's stddef.h and stdarg.h to define size_t,
ptrdiff_t, wchar_t, NULL, and __gnuc_va_list, and to implement a
convention that allows us to request the definition of a specific one:
for instance

    #define __need_size_t
    #include <stddef.h>

is expected to define size_t but not any of the other things stddef.h
defines.

This patch hides that convention behind a set of bits/types/ headers,
which allows check-obsolete-constructs.py to verify that none of our
headers include these headers unconditionally.  (Both of them define
at least one item in the user namespace that no other header is
supposed to expose.)  It will also facilitate coping with compilers
that don’t implement the __need convention.  (That scenario is not
hypothetical, see the next patch.)

Only public headers use the new bits headers.  Non-public headers and
.c files in our codebase, that were formerly defining __need macros,
now just include stddef.h and/or stdarg.h without any __need macros.
A few files didn’t need to be including stddef.h / stdarg.h at all.

Uses of NULL in public headers that aren’t expected to define NULL
are changed to a bare 0.  bits/NULL.h is only used by headers that
are expected to define NULL.

malloc.h and printf.h were, in fact, including stddef.h and/or
stdarg.h unconditionally; they no longer do that.  This broke a few of
our test cases, which are fixed by adding appropriate inclusions to
the relevant .c files.

	* stdlib/bits/NULL.h
	* stdlib/bits/types/__va_list.h
	* stdlib/bits/types/ptrdiff_t.h
	* stdlib/bits/types/size_t.h
	* stdlib/bits/types/va_list.h
	* stdlib/bits/types/wchar_t.h:
	New headers defining a single type or macro each.
	* stdlib/Makefile: Install new headers.
	* include/bits/NULL.h
	* include/bits/types/__va_list.h
	* include/bits/types/ptrdiff_t.h
	* include/bits/types/size_t.h
	* include/bits/types/va_list.h
	* include/bits/types/wchar_t.h:
	New wrapper headers.

	* malloc/malloc.h: Don’t include stdio.h or stddef.h.
	Include bits/NULL.h, bits/types/size_t.h, bits/types/ptrdiff_t.h,
	and bits/types/FILE.h.
	* stdio-common/printf.h: Don’t include stddef.h or stdarg.h.
	Include bits/types/size_t.h, bits/types/wchar_t.h, and
	bits/types/__va_list.h.  Use __gnuc_va_list instead of va_list
	in prototypes.

	* libio/bits/types/struct_FILE.h: Include bits/types/size_t.h.
	* misc/sys/param.h: Include features.h.

	* sysvipc/sys/msg.h: Include bits/msq.h after all bits/types/ headers.
	* sysvipc/sys/sem.h: Include bits/sem.h after all bits/types/ headers.
	* sysvipc/sys/shm.h: Include bits/shm.h after all bits/types/ headers.

	* hurd/hurd/signal.h: Don’t use NULL.
	* hurd/hurd/ioctl.h: Don’t include stdarg.h.
	* hurd/hurd/userlink.h: Don’t include stddef.h.  Don’t use NULL.
	* intl/libintl.h: Don’t include stddef.h.  Don’t use NULL.

	* intl/gettext.c, intl/ngettext.c: Include stddef.h
	unconditionally.  Don’t define any __need macros first.
	Don’t include stdlib.h.

	* sysdeps/posix/sigignore.c:, sysdeps/posix/sigset.c:
	Don’t include errno.h or string.h.

	* malloc/tst-malloc-thread-fail.c: Include stddef.h.
	* malloc/tst-malloc_info.c: Include stdio.h.
	* stdio-common/tst-vfprintf-user-type.c: Include stdarg.h.
	* string/tst-cmp.c: Include stdio.h.

	* debug/wcpcpy_chk.c, iconv/loop.c, iconv/skeleton.c
	* signal/sighold.c, signal/sigrelse.c, stdio-common/tempname.c
	* sysdeps/generic/ldsodefs.h, sysdeps/nptl/libc-lock.h
	* sysdeps/nptl/libc-lockP.h, sysdeps/posix/waitid.c
	* wcsmbs/wcstol_l.c, wcsmbs/wcstoll_l.c, wcsmbs/wcstoul_l.c
	* wcsmbs/wcstoull_l.c, sysdeps/posix/sigignore.c
	* sysdeps/posix/sigset.c: Don’t define __need macros before
	including stddef.h.

	* bits/socket.h, bits/types/stack_t.h, dirent/dirent.h
	* dlfcn/dlfcn.h, gmon/sys/profil.h, grp/grp.h, gshadow/gshadow.h
        * hurd/hurd/signal.h, hurd/hurd/sigpreempt.h, iconv/gconv.h
        * include/set-hooks.h, include/stdio.h, inet/aliases.h
        * io/sys/sendfile.h, libio/stdio.h, misc/bits/types/struct_iovec.h
	* misc/search.h, misc/sys/mman.h, misc/syslog.h, posix/glob.h
	* posix/sched.h, posix/sys/types.h, posix/unistd.h
	* posix/wordexp.h, pwd/pwd.h, shadow/shadow.h, signal/signal.h
        * socket/sys/socket.h, stdlib/alloca.h, stdlib/monetary.h
	* stdlib/stdlib.h, stdlib/sys/random.h, string/string.h
	* string/strings.h, sunrpc/rpc/netdb.h
	* sysdeps/htl/bits/types/struct___pthread_attr.h
	* sysdeps/mach/hurd/bits/socket.h
	* sysdeps/unix/sysv/linux/bits/socket.h
	* sysdeps/unix/sysv/linux/bits/types/stack_t.h
	* sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h
	* sysdeps/unix/sysv/linux/mips/bits/types/stack_t.h
	* sysdeps/unix/sysv/linux/scsi/sg.h
	* sysdeps/unix/sysv/linux/sys/sysctl.h
	* sysvipc/sys/msg.h, sysvipc/sys/sem.h, sysvipc/sys/shm.h
        * time/time.h, wcsmbs/uchar.h, wcsmbs/wchar.h:
	Use bits/types/size_t.h instead of __need_size_t.

	* iconv/gconv.h, iconv/iconv.h, libio/libio.h
	* stdlib/inttypes.h, stdlib/stdlib.h, wcsmbs/wchar.h:
	Use bits/types/wchar_t.h instead of __need_wchar_t.

	* libio/stdio.h, locale/locale.h, misc/sys/param.h
	* posix/sched.h, posix/unistd.h, stdlib/stdlib.h
	* string/string.h, sysdeps/unix/sysv/linux/bits/sigcontext.h
	* time/time.h, wcsmbs/wchar.h: Use bits/NULL.h instead of __need_NULL.

	* libio/stdio.h, misc/err.h: Use bits/types/__va_list.h instead
	of __need___va_list.
	* libio/stdio.h: Use bits/types/va_list.h instead of manually
	defining va_list.

	* hurd/hurd/userlink.h, misc/sys/mman.h, posix/sched.h
	* sysdeps/mach/hurd/bits/socket.h
	* sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h
	* wcsmbs/wchar.h: Reorganize includes; no semantic effect.
	* stdlib/stdlib.h: Normalize format of multiple include guard.
	* sysdeps/unix/sysv/linux/bits/sigcontext.h: Annotate workarounds
	for kernel header bugs.

	* sysdeps/unix/sysv/linux/aarch64/sys/user.h
	* sysdeps/unix/sysv/linux/arm/sys/user.h
	* sysdeps/unix/sysv/linux/m68k/sys/user.h
	* sysdeps/unix/sysv/linux/microblaze/sys/user.h
	* sysdeps/unix/sysv/linux/nios2/sys/user.h
	* sysdeps/unix/sysv/linux/s390/sys/user.h
	* sysdeps/unix/sysv/linux/x86/sys/user.h
	Include features.h.

	* sysdeps/unix/sysv/linux/alpha/sys/user.h
	* sysdeps/unix/sysv/linux/ia64/sys/user.h
	* sysdeps/unix/sysv/linux/mips/sys/user.h
	* sysdeps/unix/sysv/linux/powerpc/sys/user.h
	* sysdeps/unix/sysv/linux/sh/sys/user.h
	* sysdeps/unix/sysv/linux/sparc/sys/user.h
	Include features.h and bits/types/size_t.h, in that order.
	Include kernel headers, if any, after those two.
	Don’t include stddef.h or sys/types.h.

	* scripts/check-obsolete-constructs.py
	(UNIVERSAL_ALLOWED_INCLUDES): Remove stddef.h and stdarg.h.
	(HEADER_ALLOWED_INCLUDES): Update.
---
 bits/socket.h                                 |  4 +---
 bits/types/stack_t.h                          |  3 +--
 debug/wcpcpy_chk.c                            |  2 --
 dirent/dirent.h                               |  3 +--
 dlfcn/dlfcn.h                                 |  4 ++--
 grp/grp.h                                     |  7 +-----
 gshadow/gshadow.h                             |  4 +---
 hurd/hurd/ioctl.h                             |  2 --
 hurd/hurd/signal.h                            | 15 +++++--------
 hurd/hurd/sigpreempt.h                        |  3 +--
 hurd/hurd/userlink.h                          | 18 ++++++---------
 iconv/gconv.h                                 |  6 ++---
 iconv/iconv.h                                 |  3 +--
 iconv/loop.c                                  |  1 -
 iconv/skeleton.c                              |  2 --
 include/bits/NULL.h                           |  1 +
 include/bits/types/__va_list.h                |  1 +
 include/bits/types/ptrdiff_t.h                |  1 +
 include/bits/types/size_t.h                   |  1 +
 include/bits/types/va_list.h                  |  1 +
 include/bits/types/wchar_t.h                  |  1 +
 include/set-hooks.h                           |  3 +--
 include/stdio.h                               |  4 +---
 intl/gettext.c                                |  7 +-----
 intl/libintl.h                                |  8 ++-----
 intl/ngettext.c                               |  7 +-----
 libio/bits/types/struct_FILE.h                |  1 +
 libio/libio.h                                 |  4 +---
 libio/stdio.h                                 | 19 ++++------------
 locale/locale.h                               |  3 +--
 malloc/malloc.h                               |  7 ++++--
 malloc/tst-malloc-thread-fail.c               |  1 +
 malloc/tst-malloc_info.c                      |  1 +
 misc/bits/types/struct_iovec.h                |  3 +--
 misc/err.h                                    |  6 +----
 misc/search.h                                 |  3 +--
 misc/sys/mman.h                               |  8 +++----
 misc/sys/param.h                              |  4 ++--
 misc/syslog.h                                 |  3 +--
 posix/glob.h                                  |  3 +--
 posix/sched.h                                 |  9 +++-----
 posix/sys/types.h                             |  4 +---
 posix/unistd.h                                |  6 ++---
 posix/wordexp.h                               |  3 +--
 pwd/pwd.h                                     |  4 +---
 scripts/check-obsolete-constructs.py          | 17 ++++++--------
 shadow/shadow.h                               |  4 +---
 signal/sighold.c                              |  1 -
 signal/signal.h                               |  4 +---
 signal/sigrelse.c                             |  1 -
 socket/sys/socket.h                           |  3 +--
 stdio-common/printf.h                         | 11 ++++------
 stdio-common/tempname.c                       |  1 -
 stdio-common/tst-vfprintf-user-type.c         |  1 +
 stdlib/Makefile                               |  4 +++-
 stdlib/alloca.h                               |  3 +--
 stdlib/bits/NULL.h                            |  8 +++++++
 stdlib/bits/types/__va_list.h                 |  9 ++++++++
 stdlib/bits/types/ptrdiff_t.h                 |  9 ++++++++
 stdlib/bits/types/size_t.h                    |  9 ++++++++
 stdlib/bits/types/va_list.h                   | 15 +++++++++++++
 stdlib/bits/types/wchar_t.h                   |  9 ++++++++
 stdlib/inttypes.h                             |  3 +--
 stdlib/monetary.h                             |  3 +--
 stdlib/stdlib.h                               | 11 ++++------
 string/string.h                               |  6 ++---
 string/strings.h                              |  3 +--
 string/tst-cmp.c                              |  1 +
 sunrpc/rpc/netdb.h                            |  3 +--
 sysdeps/generic/ldsodefs.h                    |  2 --
 .../htl/bits/types/struct___pthread_attr.h    |  4 +---
 sysdeps/mach/hurd/bits/socket.h               |  5 ++---
 sysdeps/nptl/libc-lock.h                      |  1 -
 sysdeps/nptl/libc-lockP.h                     |  1 -
 sysdeps/posix/sigignore.c                     |  3 ---
 sysdeps/posix/sigset.c                        |  3 ---
 sysdeps/posix/waitid.c                        |  1 -
 sysdeps/unix/sysv/linux/aarch64/sys/user.h    |  2 ++
 sysdeps/unix/sysv/linux/alpha/sys/user.h      |  8 ++++---
 sysdeps/unix/sysv/linux/arm/sys/user.h        |  2 ++
 sysdeps/unix/sysv/linux/bits/sigcontext.h     | 11 ++++++----
 sysdeps/unix/sysv/linux/bits/socket.h         |  3 +--
 sysdeps/unix/sysv/linux/bits/types/stack_t.h  |  3 +--
 .../unix/sysv/linux/ia64/bits/sigcontext.h    |  5 ++---
 sysdeps/unix/sysv/linux/ia64/sys/user.h       |  2 +-
 sysdeps/unix/sysv/linux/m68k/sys/user.h       |  2 ++
 sysdeps/unix/sysv/linux/microblaze/sys/user.h |  2 ++
 .../unix/sysv/linux/mips/bits/types/stack_t.h |  3 +--
 sysdeps/unix/sysv/linux/mips/sys/user.h       |  4 +++-
 sysdeps/unix/sysv/linux/nios2/sys/user.h      |  2 ++
 sysdeps/unix/sysv/linux/powerpc/sys/user.h    |  4 ++--
 sysdeps/unix/sysv/linux/s390/sys/user.h       |  2 ++
 sysdeps/unix/sysv/linux/scsi/sg.h             |  4 +---
 sysdeps/unix/sysv/linux/sh/sys/user.h         |  5 ++++-
 sysdeps/unix/sysv/linux/sparc/sys/user.h      |  3 ++-
 sysdeps/unix/sysv/linux/sys/sysctl.h          |  4 ++--
 sysdeps/unix/sysv/linux/x86/sys/user.h        |  2 ++
 sysvipc/sys/msg.h                             | 10 ++++-----
 sysvipc/sys/sem.h                             | 11 +++++-----
 sysvipc/sys/shm.h                             | 10 ++++-----
 time/time.h                                   | 10 ++++-----
 wcsmbs/uchar.h                                |  4 +---
 wcsmbs/wchar.h                                | 22 ++++++++-----------
 wcsmbs/wcstol_l.c                             |  1 -
 wcsmbs/wcstoll_l.c                            |  1 -
 wcsmbs/wcstoul_l.c                            |  1 -
 wcsmbs/wcstoull_l.c                           |  1 -
 107 files changed, 233 insertions(+), 274 deletions(-)
 create mode 100644 include/bits/NULL.h
 create mode 100644 include/bits/types/__va_list.h
 create mode 100644 include/bits/types/ptrdiff_t.h
 create mode 100644 include/bits/types/size_t.h
 create mode 100644 include/bits/types/va_list.h
 create mode 100644 include/bits/types/wchar_t.h
 create mode 100644 stdlib/bits/NULL.h
 create mode 100644 stdlib/bits/types/__va_list.h
 create mode 100644 stdlib/bits/types/ptrdiff_t.h
 create mode 100644 stdlib/bits/types/size_t.h
 create mode 100644 stdlib/bits/types/va_list.h
 create mode 100644 stdlib/bits/types/wchar_t.h
diff mbox series

Patch

diff --git a/bits/socket.h b/bits/socket.h
index 6687a47740..8f5b85fa98 100644
--- a/bits/socket.h
+++ b/bits/socket.h
@@ -23,11 +23,9 @@ 
 # error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
 #endif
 
-#define	__need_size_t
-#include <stddef.h>
-
 #include <bits/wordsize.h>
 #include <bits/types.h>
+#include <bits/types/size_t.h>
 #include <bits/types/socklen_t.h>
 
 /* Types of sockets.  */
diff --git a/bits/types/stack_t.h b/bits/types/stack_t.h
index c9df26c931..5427cb98a0 100644
--- a/bits/types/stack_t.h
+++ b/bits/types/stack_t.h
@@ -19,8 +19,7 @@ 
 #ifndef __stack_t_defined
 #define __stack_t_defined 1
 
-#define __need_size_t
-#include <stddef.h>
+#include <bits/types/size_t.h>
 
 /* Structure describing a signal stack.  */
 typedef struct
diff --git a/debug/wcpcpy_chk.c b/debug/wcpcpy_chk.c
index 0dd62560f2..2be0e2c7f4 100644
--- a/debug/wcpcpy_chk.c
+++ b/debug/wcpcpy_chk.c
@@ -17,8 +17,6 @@ 
    <http://www.gnu.org/licenses/>.  */
 
 #include <wchar.h>
-
-#define __need_ptrdiff_t
 #include <stddef.h>
 
 
diff --git a/dirent/dirent.h b/dirent/dirent.h
index 9639ae96d4..3602ed8d40 100644
--- a/dirent/dirent.h
+++ b/dirent/dirent.h
@@ -233,8 +233,7 @@  extern int dirfd (DIR *__dirp) __THROW __nonnull ((1));
 #  endif
 # endif
 
-# define __need_size_t
-# include <stddef.h>
+# include <bits/types/size_t.h>
 
 /* Scan the directory DIR, calling SELECTOR on each directory entry.
    Entries for which SELECT returns nonzero are individually malloc'd,
diff --git a/dlfcn/dlfcn.h b/dlfcn/dlfcn.h
index c550371999..877ec340a2 100644
--- a/dlfcn/dlfcn.h
+++ b/dlfcn/dlfcn.h
@@ -20,8 +20,8 @@ 
 #define	_DLFCN_H 1
 
 #include <features.h>
-#define __need_size_t
-#include <stddef.h>
+
+#include <bits/types/size_t.h>
 
 /* Collect various system dependent definitions and declarations.  */
 #include <bits/dlfcn.h>
diff --git a/grp/grp.h b/grp/grp.h
index d8f7683d1f..95d7414a80 100644
--- a/grp/grp.h
+++ b/grp/grp.h
@@ -27,9 +27,7 @@ 
 __BEGIN_DECLS
 
 #include <bits/types.h>
-
-#define __need_size_t
-#include <stddef.h>
+#include <bits/types/size_t.h>
 
 /* For the Single Unix specification we must define this type here.  */
 #if defined __USE_XOPEN || defined __USE_XOPEN2K
@@ -167,9 +165,6 @@  extern int fgetgrent_r (FILE *__restrict __stream,
 
 #ifdef	__USE_MISC
 
-# define __need_size_t
-# include <stddef.h>
-
 /* Set the group set for the current user to GROUPS (N of them).  */
 extern int setgroups (size_t __n, const __gid_t *__groups) __THROW;
 
diff --git a/gshadow/gshadow.h b/gshadow/gshadow.h
index c1998083e6..695469ff80 100644
--- a/gshadow/gshadow.h
+++ b/gshadow/gshadow.h
@@ -23,9 +23,7 @@ 
 #include <features.h>
 #include <paths.h>
 #include <bits/types/FILE.h>
-
-#define __need_size_t
-#include <stddef.h>
+#include <bits/types/size_t.h>
 
 /* Path to the user database files.  */
 #define	GSHADOW _PATH_GSHADOW
diff --git a/hurd/hurd/ioctl.h b/hurd/hurd/ioctl.h
index aea2fec1aa..7b5f211d56 100644
--- a/hurd/hurd/ioctl.h
+++ b/hurd/hurd/ioctl.h
@@ -19,8 +19,6 @@ 
 #ifndef	_HURD_IOCTL_H
 #define	_HURD_IOCTL_H	1
 
-#define	__need___va_list
-#include <stdarg.h>
 #include <bits/ioctls.h>
 #include <mach/port.h>
 
diff --git a/hurd/hurd/signal.h b/hurd/hurd/signal.h
index 308124c90b..73de52dfc3 100644
--- a/hurd/hurd/signal.h
+++ b/hurd/hurd/signal.h
@@ -21,10 +21,6 @@ 
 #define	_HURD_SIGNAL_H	1
 #include <features.h>
 
-#define __need_size_t
-#define __need_NULL
-#include <stddef.h>
-
 #include <mach/mach_types.h>
 #include <mach/port.h>
 #include <mach/message.h>
@@ -34,6 +30,7 @@ 
 #include <bits/types/error_t.h>
 #include <bits/types/stack_t.h>
 #include <bits/types/sigset_t.h>
+#include <bits/types/size_t.h>
 #include <bits/sigaction.h>
 #include <hurd/msg.h>
 
@@ -138,7 +135,7 @@  extern struct hurd_sigstate *_hurd_self_sigstate (void)
 _HURD_SIGNAL_H_EXTERN_INLINE struct hurd_sigstate *
 _hurd_self_sigstate (void)
 {
-  if (THREAD_SELF->_hurd_sigstate == NULL)
+  if (! THREAD_SELF->_hurd_sigstate)
     THREAD_SELF->_hurd_sigstate = _hurd_thread_sigstate (__mach_thread_self ());
   return THREAD_SELF->_hurd_sigstate;
 }
@@ -187,11 +184,11 @@  _hurd_critical_section_lock (void)
 #ifdef __LIBC_NO_TLS
   if (__LIBC_NO_TLS ())
     /* TLS is currently initializing, no need to enter critical section.  */
-    return NULL;
+    return 0;
 #endif
 
   ss = THREAD_SELF->_hurd_sigstate;
-  if (ss == NULL)
+  if (! ss)
     {
       /* The thread variable is unset; this must be the first time we've
 	 asked for it.  In this case, the critical section flag cannot
@@ -202,7 +199,7 @@  _hurd_critical_section_lock (void)
 
   if (! __spin_try_lock (&ss->critical_section_lock))
     /* We are already in a critical section, so do nothing.  */
-    return NULL;
+    return 0;
 
   /* With the critical section lock held no signal handler will run.
      Return our sigstate pointer; this will be passed to
@@ -219,7 +216,7 @@  extern void _hurd_critical_section_unlock (void *our_lock);
 _HURD_SIGNAL_H_EXTERN_INLINE void
 _hurd_critical_section_unlock (void *our_lock)
 {
-  if (our_lock == NULL)
+  if (! our_lock)
     /* The critical section lock was held when we began.  Do nothing.  */
     return;
   else
diff --git a/hurd/hurd/sigpreempt.h b/hurd/hurd/sigpreempt.h
index 44eb614e13..aa61ad9b87 100644
--- a/hurd/hurd/sigpreempt.h
+++ b/hurd/hurd/sigpreempt.h
@@ -19,8 +19,7 @@ 
 #ifndef	_HURD_SIGPREEMPT_H
 
 #define	_HURD_SIGPREEMPT_H	1
-#define __need_size_t
-#include <stddef.h>
+#include <bits/types/size_t.h>
 #include <errno.h>
 #include <bits/types/error_t.h>
 #include <signal.h>		/* For sighandler_t, SIG_ERR.  */
diff --git a/hurd/hurd/userlink.h b/hurd/hurd/userlink.h
index d70438a48f..0fde97e84b 100644
--- a/hurd/hurd/userlink.h
+++ b/hurd/hurd/userlink.h
@@ -17,20 +17,16 @@ 
    <http://www.gnu.org/licenses/>.  */
 
 #ifndef	_HURD_USERLINK_H
-
 #define	_HURD_USERLINK_H	1
-#include <features.h>
 
-#define __need_NULL
-#include <stddef.h>
+#include <features.h>
+#include <setjmp.h>
 
 #if defined __USE_EXTERN_INLINES && defined _LIBC
 # if IS_IN (libc)
 #  include <hurd/signal.h>
 # endif
 #endif
-#include <setjmp.h>
-
 
 /* This structure records a link in two doubly-linked lists.
    We call these the per-resource user list and the per-thread
@@ -156,11 +152,11 @@  _hurd_userlink_move (struct hurd_userlink *new_link,
 {
   *new_link = *link;
 
-  if (new_link->resource.next != NULL)
+  if (new_link->resource.next)
     new_link->resource.next->resource.prevp = &new_link->resource.next;
   *new_link->resource.prevp = new_link;
 
-  if (new_link->thread.next != NULL)
+  if (new_link->thread.next)
     new_link->thread.next->thread.prevp = &new_link->thread.next;
   *new_link->thread.prevp = new_link;
 }
@@ -180,13 +176,13 @@  extern int _hurd_userlink_clear (struct hurd_userlink **chainp);
 _HURD_USERLINK_H_EXTERN_INLINE int
 _hurd_userlink_clear (struct hurd_userlink **chainp)
 {
-  if (*chainp == NULL)
+  if (! *chainp)
     return 1;
 
   /* Detach the chain of current users from the cell.  The last user to
      remove his link from that chain will deallocate the old resource.  */
-  (*chainp)->resource.prevp = NULL;
-  *chainp = NULL;
+  (*chainp)->resource.prevp = 0;
+  *chainp = 0;
   return 0;
 }
 # endif
diff --git a/iconv/gconv.h b/iconv/gconv.h
index 7ce79bcbf6..05746e4707 100644
--- a/iconv/gconv.h
+++ b/iconv/gconv.h
@@ -24,12 +24,10 @@ 
 
 #include <features.h>
 #include <bits/types/__mbstate_t.h>
+#include <bits/types/size_t.h>
+#include <bits/types/wchar_t.h>
 #include <bits/types/wint_t.h>
 
-#define __need_size_t
-#define __need_wchar_t
-#include <stddef.h>
-
 /* ISO 10646 value used to signal invalid value.  */
 #define __UNKNOWN_10646_CHAR	((wchar_t) 0xfffd)
 
diff --git a/iconv/iconv.h b/iconv/iconv.h
index 9585ec268e..dded7ef45b 100644
--- a/iconv/iconv.h
+++ b/iconv/iconv.h
@@ -19,8 +19,7 @@ 
 #define _ICONV_H	1
 
 #include <features.h>
-#define __need_size_t
-#include <stddef.h>
+#include <bits/types/size_t.h>
 
 
 __BEGIN_DECLS
diff --git a/iconv/loop.c b/iconv/loop.c
index fa98c1a521..e9cea355e5 100644
--- a/iconv/loop.c
+++ b/iconv/loop.c
@@ -54,7 +54,6 @@ 
 #include <string.h>
 #include <wchar.h>
 #include <sys/param.h>		/* For MIN.  */
-#define __need_size_t
 #include <stddef.h>
 #include <libc-diag.h>
 
diff --git a/iconv/skeleton.c b/iconv/skeleton.c
index 7c12975de3..c5447708ec 100644
--- a/iconv/skeleton.c
+++ b/iconv/skeleton.c
@@ -140,8 +140,6 @@ 
 #include <assert.h>
 #include <iconv/gconv_int.h>
 #include <string.h>
-#define __need_size_t
-#define __need_NULL
 #include <stddef.h>
 
 #ifndef STATIC_GCONV
diff --git a/include/bits/NULL.h b/include/bits/NULL.h
new file mode 100644
index 0000000000..0584572ed3
--- /dev/null
+++ b/include/bits/NULL.h
@@ -0,0 +1 @@ 
+#include <stdlib/bits/NULL.h>
diff --git a/include/bits/types/__va_list.h b/include/bits/types/__va_list.h
new file mode 100644
index 0000000000..436e6ed823
--- /dev/null
+++ b/include/bits/types/__va_list.h
@@ -0,0 +1 @@ 
+#include <stdlib/bits/types/__va_list.h>
diff --git a/include/bits/types/ptrdiff_t.h b/include/bits/types/ptrdiff_t.h
new file mode 100644
index 0000000000..d16c0d3c2b
--- /dev/null
+++ b/include/bits/types/ptrdiff_t.h
@@ -0,0 +1 @@ 
+#include <stdlib/bits/types/ptrdiff_t.h>
diff --git a/include/bits/types/size_t.h b/include/bits/types/size_t.h
new file mode 100644
index 0000000000..feaa04363f
--- /dev/null
+++ b/include/bits/types/size_t.h
@@ -0,0 +1 @@ 
+#include <stdlib/bits/types/size_t.h>
diff --git a/include/bits/types/va_list.h b/include/bits/types/va_list.h
new file mode 100644
index 0000000000..dbc749a752
--- /dev/null
+++ b/include/bits/types/va_list.h
@@ -0,0 +1 @@ 
+#include <stdlib/bits/types/va_list.h>
diff --git a/include/bits/types/wchar_t.h b/include/bits/types/wchar_t.h
new file mode 100644
index 0000000000..343bd5855d
--- /dev/null
+++ b/include/bits/types/wchar_t.h
@@ -0,0 +1 @@ 
+#include <stdlib/bits/types/wchar_t.h>
diff --git a/include/set-hooks.h b/include/set-hooks.h
index a0c5101e2d..da24c28435 100644
--- a/include/set-hooks.h
+++ b/include/set-hooks.h
@@ -19,8 +19,7 @@ 
 #ifndef _SET_HOOKS_H
 #define _SET_HOOKS_H 1
 
-#define __need_size_t
-#include <stddef.h>
+#include <bits/types/size_t.h>
 #include <sys/cdefs.h>
 #include <libc-symbols.h>
 
diff --git a/include/stdio.h b/include/stdio.h
index 5302e61024..c72d410013 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -81,9 +81,7 @@  libc_hidden_proto (__isoc99_vfscanf)
 extern FILE *__new_tmpfile (void);
 extern FILE *__old_tmpfile (void);
 
-#  define __need_size_t
-#  include <stddef.h>
-
+#  include <bits/types/size_t.h>
 #  include <bits/types/wint_t.h>
 
 /* Generate a unique file name (and possibly open it).  */
diff --git a/intl/gettext.c b/intl/gettext.c
index 5217a589fc..a8240cfb71 100644
--- a/intl/gettext.c
+++ b/intl/gettext.c
@@ -18,12 +18,7 @@ 
 # include <config.h>
 #endif
 
-#ifdef _LIBC
-# define __need_NULL
-# include <stddef.h>
-#else
-# include <stdlib.h>		/* Just for NULL.  */
-#endif
+#include <stddef.h>		/* Just for NULL.  */
 
 #include "gettextP.h"
 #ifdef _LIBC
diff --git a/intl/libintl.h b/intl/libintl.h
index f03eda0b6f..95cbe2bdbe 100644
--- a/intl/libintl.h
+++ b/intl/libintl.h
@@ -95,10 +95,6 @@  extern char *bind_textdomain_codeset (const char *__domainname,
 /* Optimized version of the function above.  */
 #if defined __OPTIMIZE__ && !defined __cplusplus
 
-/* We need NULL for `gettext'.  */
-# define __need_NULL
-# include <stddef.h>
-
 /* We need LC_MESSAGES for `dgettext'.  */
 # include <locale.h>
 
@@ -106,12 +102,12 @@  extern char *bind_textdomain_codeset (const char *__domainname,
    `__builtin_constant_p' predicate in dcgettext would always return
    false.  */
 
-# define gettext(msgid) dgettext (NULL, msgid)
+# define gettext(msgid) dgettext (0, msgid)
 
 # define dgettext(domainname, msgid) \
   dcgettext (domainname, msgid, LC_MESSAGES)
 
-# define ngettext(msgid1, msgid2, n) dngettext (NULL, msgid1, msgid2, n)
+# define ngettext(msgid1, msgid2, n) dngettext (0, msgid1, msgid2, n)
 
 # define dngettext(domainname, msgid1, msgid2, n) \
   dcngettext (domainname, msgid1, msgid2, n, LC_MESSAGES)
diff --git a/intl/ngettext.c b/intl/ngettext.c
index 98aa2c90b0..ffd99f6604 100644
--- a/intl/ngettext.c
+++ b/intl/ngettext.c
@@ -18,12 +18,7 @@ 
 # include <config.h>
 #endif
 
-#ifdef _LIBC
-# define __need_NULL
-# include <stddef.h>
-#else
-# include <stdlib.h>		/* Just for NULL.  */
-#endif
+#include <stddef.h>		/* Just for NULL.  */
 
 #include "gettextP.h"
 #ifdef _LIBC
diff --git a/libio/bits/types/struct_FILE.h b/libio/bits/types/struct_FILE.h
index b725459e58..6b7faf8f56 100644
--- a/libio/bits/types/struct_FILE.h
+++ b/libio/bits/types/struct_FILE.h
@@ -31,6 +31,7 @@ 
 #endif
 
 #include <bits/types.h>
+#include <bits/types/size_t.h>
 
 struct _IO_FILE;
 struct _IO_marker;
diff --git a/libio/libio.h b/libio/libio.h
index b985c386a2..96fa1062f2 100644
--- a/libio/libio.h
+++ b/libio/libio.h
@@ -41,10 +41,8 @@ 
 # error "Someone forgot to include stdio-lock.h"
 #endif
 
-#define __need_wchar_t
-#include <stddef.h>
-
 #include <bits/types/__mbstate_t.h>
+#include <bits/types/wchar_t.h>
 #include <bits/types/wint_t.h>
 #include <gconv.h>
 
diff --git a/libio/stdio.h b/libio/stdio.h
index 6fabdbedc2..275091e416 100644
--- a/libio/stdio.h
+++ b/libio/stdio.h
@@ -28,33 +28,22 @@ 
 
 __BEGIN_DECLS
 
-#define __need_size_t
-#define __need_NULL
-#include <stddef.h>
-
-#define __need___va_list
-#include <stdarg.h>
-
 #include <bits/types.h>
 #include <bits/types/__fpos_t.h>
 #include <bits/types/__fpos64_t.h>
 #include <bits/types/__FILE.h>
+#include <bits/types/__va_list.h>
 #include <bits/types/FILE.h>
 #include <bits/types/struct_FILE.h>
+#include <bits/types/size_t.h>
+#include <bits/NULL.h>
 
 #ifdef __USE_GNU
 # include <bits/types/cookie_io_functions_t.h>
 #endif
 
 #if defined __USE_XOPEN || defined __USE_XOPEN2K8
-# ifdef __GNUC__
-#  ifndef _VA_LIST_DEFINED
-typedef __gnuc_va_list va_list;
-#   define _VA_LIST_DEFINED
-#  endif
-# else
-#  include <stdarg.h>
-# endif
+# include <bits/types/va_list.h>
 #endif
 
 #if defined __USE_UNIX98 || defined __USE_XOPEN2K
diff --git a/locale/locale.h b/locale/locale.h
index 7d8a435fe3..61b904f7b4 100644
--- a/locale/locale.h
+++ b/locale/locale.h
@@ -24,9 +24,8 @@ 
 
 #include <features.h>
 
-#define __need_NULL
-#include <stddef.h>
 #include <bits/locale.h>
+#include <bits/NULL.h>
 
 __BEGIN_DECLS
 
diff --git a/malloc/malloc.h b/malloc/malloc.h
index 523f1b1af5..be5b2f0e5e 100644
--- a/malloc/malloc.h
+++ b/malloc/malloc.h
@@ -20,8 +20,11 @@ 
 #define _MALLOC_H 1
 
 #include <features.h>
-#include <stddef.h>
-#include <stdio.h>
+
+#include <bits/NULL.h>
+#include <bits/types/size_t.h>
+#include <bits/types/ptrdiff_t.h>
+#include <bits/types/FILE.h>
 
 #ifdef _LIBC
 # define __MALLOC_HOOK_VOLATILE
diff --git a/malloc/tst-malloc-thread-fail.c b/malloc/tst-malloc-thread-fail.c
index 2ffe848107..50a9aee68d 100644
--- a/malloc/tst-malloc-thread-fail.c
+++ b/malloc/tst-malloc-thread-fail.c
@@ -20,6 +20,7 @@ 
    related to allocation failures, notably switching to a different
    arena, and falling back to mmap (via sysmalloc).  */
 
+#include <stddef.h>
 #include <errno.h>
 #include <malloc.h>
 #include <pthread.h>
diff --git a/malloc/tst-malloc_info.c b/malloc/tst-malloc_info.c
index d4bbd5c88d..ca886ec7d6 100644
--- a/malloc/tst-malloc_info.c
+++ b/malloc/tst-malloc_info.c
@@ -22,6 +22,7 @@ 
 #include <array_length.h>
 #include <malloc.h>
 #include <stdlib.h>
+#include <stdio.h>
 #include <support/support.h>
 #include <support/xthread.h>
 
diff --git a/misc/bits/types/struct_iovec.h b/misc/bits/types/struct_iovec.h
index 58261ba27f..01a9bc5881 100644
--- a/misc/bits/types/struct_iovec.h
+++ b/misc/bits/types/struct_iovec.h
@@ -19,8 +19,7 @@ 
 #ifndef __iovec_defined
 #define __iovec_defined 1
 
-#define __need_size_t
-#include <stddef.h>
+#include <bits/types/size_t.h>
 
 /* Structure for scatter/gather I/O.  */
 struct iovec
diff --git a/misc/err.h b/misc/err.h
index 4dfd9a6f5d..2d12cbe68c 100644
--- a/misc/err.h
+++ b/misc/err.h
@@ -21,11 +21,7 @@ 
 
 #include <features.h>
 
-#define	__need___va_list
-#include <stdarg.h>
-#ifndef	__GNUC_VA_LIST
-# define __gnuc_va_list	void *
-#endif
+#include <bits/types/__va_list.h>
 
 __BEGIN_DECLS
 
diff --git a/misc/search.h b/misc/search.h
index 4659c59877..771b4626f8 100644
--- a/misc/search.h
+++ b/misc/search.h
@@ -21,8 +21,7 @@ 
 
 #include <features.h>
 
-#define __need_size_t
-#include <stddef.h>
+#include <bits/types/size_t.h>
 
 __BEGIN_DECLS
 
diff --git a/misc/sys/mman.h b/misc/sys/mman.h
index 43552c3dfa..41e66a4b77 100644
--- a/misc/sys/mman.h
+++ b/misc/sys/mman.h
@@ -20,13 +20,11 @@ 
 #define	_SYS_MMAN_H	1
 
 #include <features.h>
+
 #include <bits/types.h>
-
-#define __need_size_t
-#include <stddef.h>
-
-#include <bits/types/off_t.h>
 #include <bits/types/mode_t.h>
+#include <bits/types/off_t.h>
+#include <bits/types/size_t.h>
 
 #include <bits/mman.h>
 
diff --git a/misc/sys/param.h b/misc/sys/param.h
index bf988a9769..bb6478f79b 100644
--- a/misc/sys/param.h
+++ b/misc/sys/param.h
@@ -19,13 +19,13 @@ 
 #ifndef _SYS_PARAM_H
 #define _SYS_PARAM_H    1
 
-#define __need_NULL
-#include <stddef.h>
+#include <features.h>
 
 #include <sys/types.h>
 #include <limits.h>
 #include <endian.h>                     /* Define BYTE_ORDER et al.  */
 #include <signal.h>                     /* Define NSIG.  */
+#include <bits/NULL.h>
 
 /* This file defines some things in system-specific ways.  */
 #include <bits/param.h>
diff --git a/misc/syslog.h b/misc/syslog.h
index 406133ba71..f7b7a6743f 100644
--- a/misc/syslog.h
+++ b/misc/syslog.h
@@ -33,8 +33,7 @@ 
 #define _SYSLOG_H 1
 
 #include <features.h>
-#define __need___va_list
-#include <stdarg.h>
+#include <bits/types/__va_list.h>
 
 /* This file defines _PATH_LOG.  */
 #include <bits/syslog-path.h>
diff --git a/posix/glob.h b/posix/glob.h
index e49e6c000d..3b1535e374 100644
--- a/posix/glob.h
+++ b/posix/glob.h
@@ -29,8 +29,7 @@  __BEGIN_DECLS
    a different purpose.  */
 
 #if defined __USE_XOPEN || defined __USE_XOPEN2K8
-# define __need_size_t
-# include <stddef.h>
+#include <bits/types/size_t.h>
 typedef size_t __gsize_t;
 #elif defined __SIZE_TYPE__
 typedef __SIZE_TYPE__ __gsize_t;
diff --git a/posix/sched.h b/posix/sched.h
index 56c1470521..dfcf84da1f 100644
--- a/posix/sched.h
+++ b/posix/sched.h
@@ -22,18 +22,15 @@ 
 #include <features.h>
 
 /* Get type definitions.  */
+#include <bits/NULL.h>
 #include <bits/types.h>
-
-#define __need_size_t
-#define __need_NULL
-#include <stddef.h>
-
+#include <bits/types/pid_t.h>
+#include <bits/types/size_t.h>
 #include <bits/types/time_t.h>
 #include <bits/types/struct_timespec.h>
 #ifndef __USE_XOPEN2K
 # include <time.h>
 #endif
-#include <bits/types/pid_t.h>
 
 /* Get system specific constant and data structure definitions.  */
 #include <bits/sched.h>
diff --git a/posix/sys/types.h b/posix/sys/types.h
index 8f6d328692..08305cf812 100644
--- a/posix/sys/types.h
+++ b/posix/sys/types.h
@@ -28,9 +28,6 @@  __BEGIN_DECLS
 
 #include <bits/types.h>
 
-#define __need_size_t
-#include <stddef.h>
-
 #include <bits/types/blkcnt_t.h>
 #include <bits/types/clockid_t.h>
 #include <bits/types/dev_t.h>
@@ -42,6 +39,7 @@  __BEGIN_DECLS
 #include <bits/types/nlink_t.h>
 #include <bits/types/off_t.h>
 #include <bits/types/pid_t.h>
+#include <bits/types/size_t.h>
 #include <bits/types/ssize_t.h>
 #include <bits/types/time_t.h>
 #include <bits/types/timer_t.h>
diff --git a/posix/unistd.h b/posix/unistd.h
index 407f2fee5f..1d4c70f897 100644
--- a/posix/unistd.h
+++ b/posix/unistd.h
@@ -214,13 +214,11 @@  __BEGIN_DECLS
 
 /* All functions that are not declared anywhere else.  */
 
+#include <bits/NULL.h>
 #include <bits/types.h>
+#include <bits/types/size_t.h>
 #include <bits/types/ssize_t.h>
 
-#define	__need_size_t
-#define __need_NULL
-#include <stddef.h>
-
 #if defined __USE_XOPEN || defined __USE_XOPEN2K
 /* The Single Unix specification says that some more types are
    available here.  */
diff --git a/posix/wordexp.h b/posix/wordexp.h
index 060f13fe49..f69d143693 100644
--- a/posix/wordexp.h
+++ b/posix/wordexp.h
@@ -19,8 +19,7 @@ 
 #define	_WORDEXP_H	1
 
 #include <features.h>
-#define __need_size_t
-#include <stddef.h>
+#include <bits/types/size_t.h>
 
 __BEGIN_DECLS
 
diff --git a/pwd/pwd.h b/pwd/pwd.h
index ccb3bc0ff8..75a598e0db 100644
--- a/pwd/pwd.h
+++ b/pwd/pwd.h
@@ -27,9 +27,7 @@ 
 __BEGIN_DECLS
 
 #include <bits/types.h>
-
-#define __need_size_t
-#include <stddef.h>
+#include <bits/types/size_t.h>
 
 #if defined __USE_XOPEN || defined __USE_XOPEN2K
 /* The Single Unix specification says that some more types are
diff --git a/scripts/check-obsolete-constructs.py b/scripts/check-obsolete-constructs.py
index 4ef5775932..5cd3867be1 100755
--- a/scripts/check-obsolete-constructs.py
+++ b/scripts/check-obsolete-constructs.py
@@ -491,14 +491,6 @@  def ObsoleteTypedefChecker(reporter, fname):
 # but we are not ready to enforce that yet.
 UNIVERSAL_ALLOWED_INCLUDES = {
     "features.h",
-
-    # Technically these should only ever be included with __need
-    # macros active, but some headers deliberately break this rule
-    # when they think they're dealing with freestanding headers from a
-    # non-GNU compiler, so enforcing it would be more trouble than
-    # it's worth.
-    "stddef.h",
-    "stdarg.h",
 }
 
 # Specific headers are allowed to include specific other headers.
@@ -575,7 +567,7 @@  HEADER_ALLOWED_INCLUDES = {
     "link.h":                      [ "dlfcn.h", "elf.h", "sys/types.h" ],
     "mntent.h":                    [ "paths.h" ],
     "nss.h":                       [ "stdint.h" ],
-    "obstack.h":                   [ "string.h" ],
+    "obstack.h":                   [ "stddef.h", "string.h" ],
     "proc_service.h":              [ "sys/procfs.h" ],
     "pty.h":                       [ "sys/ioctl.h", "termios.h" ],
     "sgtty.h":                     [ "sys/ioctl.h" ],
@@ -619,7 +611,6 @@  HEADER_ALLOWED_INCLUDES = {
     "sys/timex.h":                 [ "sys/time.h" ],
     "sys/ttychars.h":              [ "sys/ttydefaults.h" ],
     "sys/ucontext.h":              [ "sys/procfs.h" ],
-    "sys/user.h":                  [ "sys/types.h" ],
     "sys/vfs.h":                   [ "sys/statfs.h" ],
     "sys/xattr.h":                 [ "sys/types.h" ],
 
@@ -696,6 +687,12 @@  HEADER_ALLOWED_INCLUDES = {
     "bits/types/res_state.h":      [ "netinet/in.h", "sys/types.h" ],
     "bits/utmp.h":                 [ "paths.h", "sys/time.h", "sys/types.h" ],
     "bits/utmpx.h":                [ "paths.h", "sys/time.h" ],
+
+    "bits/types/__va_list.h":      [ "stdarg.h" ],
+    "bits/types/ptrdiff_t.h":      [ "stddef.h" ],
+    "bits/types/size_t.h":         [ "stddef.h" ],
+    "bits/types/wchar_t.h":        [ "stddef.h" ],
+    "bits/NULL.h":                 [ "stddef.h" ],
 }
 
 # As above, but each group of whitelist entries is only used for
diff --git a/shadow/shadow.h b/shadow/shadow.h
index d8635db0b1..b36b0c323c 100644
--- a/shadow/shadow.h
+++ b/shadow/shadow.h
@@ -28,10 +28,8 @@ 
 
 #include <paths.h>
 
-#define __need_size_t
-#include <stddef.h>
-
 #include <bits/types/FILE.h>
+#include <bits/types/size_t.h>
 
 /* Paths to the user database files.  */
 #define	SHADOW _PATH_SHADOW
diff --git a/signal/sighold.c b/signal/sighold.c
index 8154143b36..27add40850 100644
--- a/signal/sighold.c
+++ b/signal/sighold.c
@@ -17,7 +17,6 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#define __need_NULL
 #include <stddef.h>
 #include <signal.h>
 
diff --git a/signal/signal.h b/signal/signal.h
index ec701012e1..2c52466791 100644
--- a/signal/signal.h
+++ b/signal/signal.h
@@ -289,9 +289,7 @@  extern int sigreturn (struct sigcontext *__scp) __THROW;
 
 
 #if defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K8
-# define __need_size_t
-# include <stddef.h>
-
+# include <bits/types/size_t.h>
 # include <bits/types/stack_t.h>
 # if defined __USE_XOPEN || defined __USE_XOPEN2K8
 /* This will define `ucontext_t' and `mcontext_t'.  */
diff --git a/signal/sigrelse.c b/signal/sigrelse.c
index 433a258dee..8fc657a1cd 100644
--- a/signal/sigrelse.c
+++ b/signal/sigrelse.c
@@ -17,7 +17,6 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#define __need_NULL
 #include <stddef.h>
 #include <signal.h>
 
diff --git a/socket/sys/socket.h b/socket/sys/socket.h
index 6f242d088b..1bb90ed67c 100644
--- a/socket/sys/socket.h
+++ b/socket/sys/socket.h
@@ -23,9 +23,8 @@ 
 
 __BEGIN_DECLS
 
+#include <bits/types/size_t.h>
 #include <bits/types/struct_iovec.h>
-#define	__need_size_t
-#include <stddef.h>
 
 /* This operating system-specific header file defines the SOCK_*, PF_*,
    AF_*, MSG_*, SOL_*, and SO_* constants, and the `struct sockaddr',
diff --git a/stdio-common/printf.h b/stdio-common/printf.h
index 0172b234f1..69c9691720 100644
--- a/stdio-common/printf.h
+++ b/stdio-common/printf.h
@@ -23,12 +23,9 @@ 
 __BEGIN_DECLS
 
 #include <bits/types/FILE.h>
-
-#define	__need_size_t
-#define __need_wchar_t
-#include <stddef.h>
-
-#include <stdarg.h>
+#include <bits/types/size_t.h>
+#include <bits/types/wchar_t.h>
+#include <bits/types/__va_list.h>
 
 
 struct printf_info
@@ -89,7 +86,7 @@  typedef int printf_arginfo_function (const struct printf_info *__info,
 
 /* Type of a function to get a value of a user-defined from the
    variable argument list.  */
-typedef void printf_va_arg_function (void *__mem, va_list *__ap);
+typedef void printf_va_arg_function (void *__mem, __gnuc_va_list *__ap);
 
 
 /* Register FUNC to be called to format SPEC specifiers; ARGINFO must be
diff --git a/stdio-common/tempname.c b/stdio-common/tempname.c
index 54c97bf149..b00c14f9df 100644
--- a/stdio-common/tempname.c
+++ b/stdio-common/tempname.c
@@ -15,7 +15,6 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#define __need_size_t
 #include <stddef.h>
 #include <stdio.h>
 #include <errno.h>
diff --git a/stdio-common/tst-vfprintf-user-type.c b/stdio-common/tst-vfprintf-user-type.c
index fed17e4131..8f63e65d6e 100644
--- a/stdio-common/tst-vfprintf-user-type.c
+++ b/stdio-common/tst-vfprintf-user-type.c
@@ -23,6 +23,7 @@ 
 
 #include <locale.h>
 #include <printf.h>
+#include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
diff --git a/stdlib/Makefile b/stdlib/Makefile
index 32f6050ecc..fbf1b84a4b 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -29,7 +29,9 @@  headers	:= stdlib.h bits/stdlib.h bits/stdlib-ldbl.h bits/stdlib-float.h      \
 	   ucontext.h sys/ucontext.h bits/indirect-return.h		      \
 	   alloca.h fmtmsg.h						      \
 	   bits/stdlib-bsearch.h sys/random.h bits/stdint-intn.h	      \
-	   bits/stdint-uintn.h bits/time64.h				      \
+	   bits/stdint-uintn.h bits/time64.h bits/NULL.h		      \
+	   bits/types/ptrdiff_t.h bits/types/size_t.h bits/types/wchar_t.h    \
+	   bits/types/__va_list.h bits/types/va_list.h
 
 routines	:=							      \
 	atof atoi atol atoll						      \
diff --git a/stdlib/alloca.h b/stdlib/alloca.h
index ff85901357..908f966e53 100644
--- a/stdlib/alloca.h
+++ b/stdlib/alloca.h
@@ -20,8 +20,7 @@ 
 
 #include <features.h>
 
-#define	__need_size_t
-#include <stddef.h>
+#include <bits/types/size_t.h>
 
 __BEGIN_DECLS
 
diff --git a/stdlib/bits/NULL.h b/stdlib/bits/NULL.h
new file mode 100644
index 0000000000..79285bd7b2
--- /dev/null
+++ b/stdlib/bits/NULL.h
@@ -0,0 +1,8 @@ 
+#ifndef _BITS_NULL_H
+#define _BITS_NULL_H 1
+
+/* We rely on the compiler's stddef.h to define NULL for us.  */
+#define __need_NULL
+#include <stddef.h>
+
+#endif
diff --git a/stdlib/bits/types/__va_list.h b/stdlib/bits/types/__va_list.h
new file mode 100644
index 0000000000..e3c53c3e05
--- /dev/null
+++ b/stdlib/bits/types/__va_list.h
@@ -0,0 +1,9 @@ 
+#ifndef ____va_list_defined
+#define ____va_list_defined 1
+
+/* We rely on the compiler's stdarg.h to define __gnuc_va_list for us.  */
+#define __need___va_list
+#include <stdarg.h>
+#undef __need___va_list
+
+#endif
diff --git a/stdlib/bits/types/ptrdiff_t.h b/stdlib/bits/types/ptrdiff_t.h
new file mode 100644
index 0000000000..23a8b986d5
--- /dev/null
+++ b/stdlib/bits/types/ptrdiff_t.h
@@ -0,0 +1,9 @@ 
+#ifndef __ptrdiff_t_defined
+#define __ptrdiff_t_defined 1
+
+/* We rely on the compiler's stddef.h to define ptrdiff_t for us.  */
+#define __need_ptrdiff_t
+#include <stddef.h>
+#undef __need_ptrdiff_t
+
+#endif
diff --git a/stdlib/bits/types/size_t.h b/stdlib/bits/types/size_t.h
new file mode 100644
index 0000000000..e151458eb3
--- /dev/null
+++ b/stdlib/bits/types/size_t.h
@@ -0,0 +1,9 @@ 
+#ifndef __size_t_defined
+#define __size_t_defined 1
+
+/* We rely on the compiler's stddef.h to define size_t for us.  */
+#define __need_size_t
+#include <stddef.h>
+#undef __need_size_t
+
+#endif
diff --git a/stdlib/bits/types/va_list.h b/stdlib/bits/types/va_list.h
new file mode 100644
index 0000000000..6f3acac379
--- /dev/null
+++ b/stdlib/bits/types/va_list.h
@@ -0,0 +1,15 @@ 
+/* This guard macro needs to match the one used by at least gcc and
+   clang's stdarg.h to indicate that va_list, specifically, has been
+   defined.  */
+#ifndef _VA_LIST
+
+#include <bits/types/__va_list.h>
+
+/* Check again, __va_list.h may not have been able to avoid including
+   all of stdarg.h.  */
+# ifndef _VA_LIST
+typedef __gnuc_va_list va_list;
+# endif
+# define _VA_LIST
+
+#endif
diff --git a/stdlib/bits/types/wchar_t.h b/stdlib/bits/types/wchar_t.h
new file mode 100644
index 0000000000..1e44e157cc
--- /dev/null
+++ b/stdlib/bits/types/wchar_t.h
@@ -0,0 +1,9 @@ 
+#ifndef __wchar_t_defined
+#define __wchar_t_defined 1
+
+/* We rely on the compiler's stddef.h to define wchar_t for us.  */
+#define __need_wchar_t
+#include <stddef.h>
+#undef __need_wchar_t
+
+#endif
diff --git a/stdlib/inttypes.h b/stdlib/inttypes.h
index c5fb12056e..30c9e84cd3 100644
--- a/stdlib/inttypes.h
+++ b/stdlib/inttypes.h
@@ -32,8 +32,7 @@ 
 #elif defined __WCHAR_TYPE__
 typedef __WCHAR_TYPE__ __gwchar_t;
 #else
-# define __need_wchar_t
-# include <stddef.h>
+#include <bits/types/wchar_t.h>
 typedef wchar_t __gwchar_t;
 #endif
 
diff --git a/stdlib/monetary.h b/stdlib/monetary.h
index 1f3347a6ec..1150f11486 100644
--- a/stdlib/monetary.h
+++ b/stdlib/monetary.h
@@ -22,9 +22,8 @@ 
 #include <features.h>
 
 /* Get needed types.  */
-#define __need_size_t
-#include <stddef.h>
 #include <bits/types.h>
+#include <bits/types/size_t.h>
 #include <bits/types/ssize_t.h>
 
 __BEGIN_DECLS
diff --git a/stdlib/stdlib.h b/stdlib/stdlib.h
index 34996e3ee7..1f26f3639e 100644
--- a/stdlib/stdlib.h
+++ b/stdlib/stdlib.h
@@ -20,20 +20,17 @@ 
  */
 
 #ifndef	_STDLIB_H
+#define	_STDLIB_H	1
 
 #define __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION
 #include <bits/libc-header-start.h>
 
-/* Get size_t, wchar_t and NULL from <stddef.h>.  */
-#define __need_size_t
-#define __need_wchar_t
-#define __need_NULL
-#include <stddef.h>
+#include <bits/types/size_t.h>
+#include <bits/types/wchar_t.h>
+#include <bits/NULL.h>
 
 __BEGIN_DECLS
 
-#define	_STDLIB_H	1
-
 #if (defined __USE_XOPEN || defined __USE_XOPEN2K8) && !defined _SYS_WAIT_H
 /* XPG requires a few symbols from <sys/wait.h> being defined.  */
 # include <bits/waitflags.h>
diff --git a/string/string.h b/string/string.h
index c38eea971f..2cc4f50090 100644
--- a/string/string.h
+++ b/string/string.h
@@ -27,10 +27,8 @@ 
 
 __BEGIN_DECLS
 
-/* Get size_t and NULL from <stddef.h>.  */
-#define	__need_size_t
-#define	__need_NULL
-#include <stddef.h>
+#include <bits/types/size_t.h>
+#include <bits/NULL.h>
 
 /* Tell the caller that we provide correct C++ prototypes.  */
 #if defined __cplusplus && __GNUC_PREREQ (4, 4)
diff --git a/string/strings.h b/string/strings.h
index 5428bc4feb..17e1bf737f 100644
--- a/string/strings.h
+++ b/string/strings.h
@@ -19,8 +19,7 @@ 
 #define	_STRINGS_H	1
 
 #include <features.h>
-#define __need_size_t
-#include <stddef.h>
+#include <bits/types/size_t.h>
 
 /* Tell the caller that we provide correct C++ prototypes.  */
 #if defined __cplusplus && __GNUC_PREREQ (4, 4)
diff --git a/string/tst-cmp.c b/string/tst-cmp.c
index 939cf28275..ccdd1e3cec 100644
--- a/string/tst-cmp.c
+++ b/string/tst-cmp.c
@@ -23,6 +23,7 @@ 
 #include <limits.h>
 #include <malloc.h>
 #include <stdbool.h>
+#include <stdio.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
diff --git a/sunrpc/rpc/netdb.h b/sunrpc/rpc/netdb.h
index 529a4ada21..a5aa340e1a 100644
--- a/sunrpc/rpc/netdb.h
+++ b/sunrpc/rpc/netdb.h
@@ -38,8 +38,7 @@ 
 
 #include <features.h>
 
-#define __need_size_t
-#include <stddef.h>
+#include <bits/types/size_t.h>
 
 __BEGIN_DECLS
 
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index b1fc5c31f9..88fc64df63 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -22,8 +22,6 @@ 
 #include <features.h>
 
 #include <stdbool.h>
-#define __need_size_t
-#define __need_NULL
 #include <stddef.h>
 #include <string.h>
 #include <stdint.h>
diff --git a/sysdeps/htl/bits/types/struct___pthread_attr.h b/sysdeps/htl/bits/types/struct___pthread_attr.h
index b2c5c63f27..25cf45ecdb 100644
--- a/sysdeps/htl/bits/types/struct___pthread_attr.h
+++ b/sysdeps/htl/bits/types/struct___pthread_attr.h
@@ -19,11 +19,9 @@ 
 #ifndef _BITS_TYPES_STRUCT___PTHREAD_ATTR
 #define _BITS_TYPES_STRUCT___PTHREAD_ATTR	1
 
+#include <bits/types/size_t.h>
 #include <bits/types/struct_sched_param.h>
 
-#define __need_size_t
-#include <stddef.h>
-
 enum __pthread_detachstate;
 enum __pthread_inheritsched;
 enum __pthread_contentionscope;
diff --git a/sysdeps/mach/hurd/bits/socket.h b/sysdeps/mach/hurd/bits/socket.h
index 429e66c56a..ad590af3f6 100644
--- a/sysdeps/mach/hurd/bits/socket.h
+++ b/sysdeps/mach/hurd/bits/socket.h
@@ -24,12 +24,11 @@ 
 # error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
 #endif
 
-#define	__need_size_t
-#include <stddef.h>
 
-#include <bits/wordsize.h>
 #include <sys/types.h>
+#include <bits/types/size_t.h>
 #include <bits/types/socklen_t.h>
+#include <bits/wordsize.h>
 
 /* Types of sockets.  */
 enum __socket_type
diff --git a/sysdeps/nptl/libc-lock.h b/sysdeps/nptl/libc-lock.h
index a1fe9a766b..3840cc7eda 100644
--- a/sysdeps/nptl/libc-lock.h
+++ b/sysdeps/nptl/libc-lock.h
@@ -20,7 +20,6 @@ 
 #define _LIBC_LOCK_H 1
 
 #include <pthread.h>
-#define __need_NULL
 #include <stddef.h>
 
 
diff --git a/sysdeps/nptl/libc-lockP.h b/sysdeps/nptl/libc-lockP.h
index 07d583f11a..1e7d95ca60 100644
--- a/sysdeps/nptl/libc-lockP.h
+++ b/sysdeps/nptl/libc-lockP.h
@@ -20,7 +20,6 @@ 
 #define _LIBC_LOCKP_H 1
 
 #include <pthread.h>
-#define __need_NULL
 #include <stddef.h>
 
 
diff --git a/sysdeps/posix/sigignore.c b/sysdeps/posix/sigignore.c
index 46748fd0ab..8b1fa3ae16 100644
--- a/sysdeps/posix/sigignore.c
+++ b/sysdeps/posix/sigignore.c
@@ -17,11 +17,8 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
-#define __need_NULL
 #include <stddef.h>
 #include <signal.h>
-#include <string.h>	/* For the real memset prototype.  */
 #include <sigsetops.h>
 
 int
diff --git a/sysdeps/posix/sigset.c b/sysdeps/posix/sigset.c
index dfc0b35b65..4142a500fa 100644
--- a/sysdeps/posix/sigset.c
+++ b/sysdeps/posix/sigset.c
@@ -15,11 +15,8 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
-#define __need_NULL
 #include <stddef.h>
 #include <signal.h>
-#include <string.h>	/* For the real memset prototype.  */
 #include <sigsetops.h>
 
 /* Set the disposition for SIG.  */
diff --git a/sysdeps/posix/waitid.c b/sysdeps/posix/waitid.c
index d49a2f7883..5cd1352ef0 100644
--- a/sysdeps/posix/waitid.c
+++ b/sysdeps/posix/waitid.c
@@ -20,7 +20,6 @@ 
 #include <assert.h>
 #include <errno.h>
 #include <signal.h>
-#define __need_NULL
 #include <stddef.h>
 #include <sys/wait.h>
 #include <sys/types.h>
diff --git a/sysdeps/unix/sysv/linux/aarch64/sys/user.h b/sysdeps/unix/sysv/linux/aarch64/sys/user.h
index 7f6d8bea89..949484a533 100644
--- a/sysdeps/unix/sysv/linux/aarch64/sys/user.h
+++ b/sysdeps/unix/sysv/linux/aarch64/sys/user.h
@@ -19,6 +19,8 @@ 
 #ifndef _SYS_USER_H
 #define _SYS_USER_H	1
 
+#include <features.h>
+
 struct user_regs_struct
 {
   unsigned long long regs[31];
diff --git a/sysdeps/unix/sysv/linux/alpha/sys/user.h b/sysdeps/unix/sysv/linux/alpha/sys/user.h
index 38fcb51c9a..52bc3a287c 100644
--- a/sysdeps/unix/sysv/linux/alpha/sys/user.h
+++ b/sysdeps/unix/sysv/linux/alpha/sys/user.h
@@ -18,13 +18,15 @@ 
 #ifndef _SYS_USER_H
 #define _SYS_USER_H	1
 
+#include <features.h>
+#include <bits/types/size_t.h>
+
+#include <asm/reg.h>
+
 /* The whole purpose of this file is for gdb/strace and gdb/strace
    only. Don't read too much into it. Don't use it for anything other
    than gdb/strace unless you know what you are doing. */
 
-#include <asm/reg.h>
-#include <stddef.h>
-
 struct user
 {
   unsigned long	int regs[EF_SIZE / 8 + 32];	/* integer and fp regs */
diff --git a/sysdeps/unix/sysv/linux/arm/sys/user.h b/sysdeps/unix/sysv/linux/arm/sys/user.h
index aae8a99e56..55db6ca181 100644
--- a/sysdeps/unix/sysv/linux/arm/sys/user.h
+++ b/sysdeps/unix/sysv/linux/arm/sys/user.h
@@ -18,6 +18,8 @@ 
 #ifndef _SYS_USER_H
 #define _SYS_USER_H	1
 
+#include <features.h>
+
 /* The whole purpose of this file is for GDB and GDB only.  Don't read
    too much into it.  Don't use it for anything other than GDB unless
    you know what you are doing.  */
diff --git a/sysdeps/unix/sysv/linux/bits/sigcontext.h b/sysdeps/unix/sysv/linux/bits/sigcontext.h
index bd33c42a49..a420e20792 100644
--- a/sysdeps/unix/sysv/linux/bits/sigcontext.h
+++ b/sysdeps/unix/sysv/linux/bits/sigcontext.h
@@ -24,14 +24,17 @@ 
 
 #ifndef sigcontext_struct
 /* Kernel headers before 2.1.1 define a struct sigcontext_struct, but
-   we need sigcontext.  */
+   we need sigcontext.  FIXME: Is this workaround still necessary?
+   2.1.1 was many years ago.  */
 # define sigcontext_struct sigcontext
 
 # include <asm/sigcontext.h>
 
-/* The Linux kernel headers redefine NULL wrongly, so cleanup afterwards.  */
-# define __need_NULL
-# include <stddef.h>
+/* The Linux kernel headers redefine NULL wrongly, so cleanup afterwards.
+   FIXME: This won't work if bits/NULL.h or stddef.h has already been
+   included.  Is this workaround still necessary?  Current (4.19) uapi
+   headers do not redefine NULL.  */
+#include <bits/NULL.h>
 #endif
 
 #endif /* bits/sigcontext.h */
diff --git a/sysdeps/unix/sysv/linux/bits/socket.h b/sysdeps/unix/sysv/linux/bits/socket.h
index cf3c03a9ec..19e664842f 100644
--- a/sysdeps/unix/sysv/linux/bits/socket.h
+++ b/sysdeps/unix/sysv/linux/bits/socket.h
@@ -23,10 +23,9 @@ 
 # error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
 #endif
 
-#define __need_size_t
-#include <stddef.h>
 
 #include <sys/types.h>
+#include <bits/types/size_t.h>
 #include <bits/types/socklen_t.h>
 
 /* Get the architecture-dependent definition of enum __socket_type.  */
diff --git a/sysdeps/unix/sysv/linux/bits/types/stack_t.h b/sysdeps/unix/sysv/linux/bits/types/stack_t.h
index 5af7a91df0..4c1828ea90 100644
--- a/sysdeps/unix/sysv/linux/bits/types/stack_t.h
+++ b/sysdeps/unix/sysv/linux/bits/types/stack_t.h
@@ -19,8 +19,7 @@ 
 #ifndef __stack_t_defined
 #define __stack_t_defined 1
 
-#define __need_size_t
-#include <stddef.h>
+#include <bits/types/size_t.h>
 
 /* Structure describing a signal stack.  */
 typedef struct
diff --git a/sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h b/sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h
index 8dba935b15..b1b45ee5de 100644
--- a/sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h
+++ b/sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h
@@ -23,11 +23,10 @@ 
 # error "Never use <bits/sigcontext.h> directly; include <signal.h> instead."
 #endif
 
-#define __need_size_t
-#include <stddef.h>
-#include <bits/sigstack.h>
+#include <bits/types/size_t.h>
 #include <bits/types/struct_sigstack.h>
 #include <bits/types/stack_t.h>
+#include <bits/sigstack.h>
 #include <bits/ss_flags.h>
 
 struct __ia64_fpreg
diff --git a/sysdeps/unix/sysv/linux/ia64/sys/user.h b/sysdeps/unix/sysv/linux/ia64/sys/user.h
index f409e237c9..4e4aae5120 100644
--- a/sysdeps/unix/sysv/linux/ia64/sys/user.h
+++ b/sysdeps/unix/sysv/linux/ia64/sys/user.h
@@ -19,7 +19,7 @@ 
 #define _SYS_USER_H	1
 
 #include <features.h>
-#include <sys/types.h>
+#include <bits/types/size_t.h>
 
 /* This definition comes directly from the kernel headers.  If
    anything changes in them this header has to be changed, too.  */
diff --git a/sysdeps/unix/sysv/linux/m68k/sys/user.h b/sysdeps/unix/sysv/linux/m68k/sys/user.h
index 210d88f901..e8cdf8b35f 100644
--- a/sysdeps/unix/sysv/linux/m68k/sys/user.h
+++ b/sysdeps/unix/sysv/linux/m68k/sys/user.h
@@ -18,6 +18,8 @@ 
 #ifndef _SYS_USER_H
 #define _SYS_USER_H	1
 
+#include <features.h>
+
 /* The whole purpose of this file is for GDB and GDB only.  Don't read
    too much into it.  Don't use it for anything other than GDB unless
    you know what you are doing.  */
diff --git a/sysdeps/unix/sysv/linux/microblaze/sys/user.h b/sysdeps/unix/sysv/linux/microblaze/sys/user.h
index adf08ca275..baf6a28247 100644
--- a/sysdeps/unix/sysv/linux/microblaze/sys/user.h
+++ b/sysdeps/unix/sysv/linux/microblaze/sys/user.h
@@ -19,6 +19,8 @@ 
 #ifndef _SYS_USER_H
 # define _SYS_USER_H	1
 
+#include <features.h>
+
 /* The whole purpose of this file is for GDB and GDB only.  Don't read
    too much into it.  Don't use it for anything other than GDB unless
    you know what you are doing.  */
diff --git a/sysdeps/unix/sysv/linux/mips/bits/types/stack_t.h b/sysdeps/unix/sysv/linux/mips/bits/types/stack_t.h
index 4424398528..ad9bd9056f 100644
--- a/sysdeps/unix/sysv/linux/mips/bits/types/stack_t.h
+++ b/sysdeps/unix/sysv/linux/mips/bits/types/stack_t.h
@@ -19,8 +19,7 @@ 
 #ifndef __stack_t_defined
 #define __stack_t_defined 1
 
-#define __need_size_t
-#include <stddef.h>
+#include <bits/types/size_t.h>
 
 /* Structure describing a signal stack.  */
 typedef struct
diff --git a/sysdeps/unix/sysv/linux/mips/sys/user.h b/sysdeps/unix/sysv/linux/mips/sys/user.h
index 29a6c36785..8ed0df7aad 100644
--- a/sysdeps/unix/sysv/linux/mips/sys/user.h
+++ b/sysdeps/unix/sysv/linux/mips/sys/user.h
@@ -18,8 +18,10 @@ 
 #ifndef _SYS_USER_H
 #define _SYS_USER_H	1
 
+#include <features.h>
+#include <bits/types/size_t.h>
+
 #include <sgidefs.h>
-#include <stddef.h>
 
 /* The whole purpose of this file is for GDB and GDB only.  Don't read
    too much into it.  Don't use it for anything other than GDB unless
diff --git a/sysdeps/unix/sysv/linux/nios2/sys/user.h b/sysdeps/unix/sysv/linux/nios2/sys/user.h
index 8670f77b45..4adb789004 100644
--- a/sysdeps/unix/sysv/linux/nios2/sys/user.h
+++ b/sysdeps/unix/sysv/linux/nios2/sys/user.h
@@ -19,6 +19,8 @@ 
 #ifndef _SYS_USER_H
 #define _SYS_USER_H	1
 
+#include <features.h>
+
 /* The whole purpose of this file is for GDB and GDB only.  Don't read
    too much into it.  Don't use it for anything other than GDB unless
    you know what you are doing.  */
diff --git a/sysdeps/unix/sysv/linux/powerpc/sys/user.h b/sysdeps/unix/sysv/linux/powerpc/sys/user.h
index c6f36d79b8..2d90235a14 100644
--- a/sysdeps/unix/sysv/linux/powerpc/sys/user.h
+++ b/sysdeps/unix/sysv/linux/powerpc/sys/user.h
@@ -16,10 +16,10 @@ 
    <http://www.gnu.org/licenses/>.  */
 
 #ifndef _SYS_USER_H
-
 #define _SYS_USER_H	1
-#include <stddef.h>
+
 #include <features.h>
+#include <bits/types/size_t.h>
 
 #include <asm/ptrace.h>
 
diff --git a/sysdeps/unix/sysv/linux/s390/sys/user.h b/sysdeps/unix/sysv/linux/s390/sys/user.h
index ab56f513c4..3fc03f3171 100644
--- a/sysdeps/unix/sysv/linux/s390/sys/user.h
+++ b/sysdeps/unix/sysv/linux/s390/sys/user.h
@@ -18,6 +18,8 @@ 
 #ifndef _SYS_USER_H
 #define _SYS_USER_H	1
 
+#include <features.h>
+
 /* The whole purpose of this file is for GDB and GDB only.  Don't read
    too much into it.  Don't use it for anything other than GDB unless
    you know what you are doing.  */
diff --git a/sysdeps/unix/sysv/linux/scsi/sg.h b/sysdeps/unix/sysv/linux/scsi/sg.h
index 1f0b5a156a..9a250a9d7e 100644
--- a/sysdeps/unix/sysv/linux/scsi/sg.h
+++ b/sysdeps/unix/sysv/linux/scsi/sg.h
@@ -26,9 +26,7 @@ 
 #define _SCSI_SG_H	1
 
 #include <features.h>
-#define __need_size_t
-#include <stddef.h>
-
+#include <bits/types/size_t.h>
 
 /* New interface introduced in the 3.x SG drivers follows */
 
diff --git a/sysdeps/unix/sysv/linux/sh/sys/user.h b/sysdeps/unix/sysv/linux/sh/sys/user.h
index 54d3d701eb..37d0c0eb5e 100644
--- a/sysdeps/unix/sysv/linux/sh/sys/user.h
+++ b/sysdeps/unix/sysv/linux/sh/sys/user.h
@@ -18,8 +18,11 @@ 
 #ifndef _SYS_USER_H
 #define _SYS_USER_H	1
 
+#include <features.h>
+#include <bits/types/size_t.h>
+
 #include <asm/ptrace.h>
-#include <stddef.h>
+
 
 /* asm/ptrace.h polutes the namespace.  */
 #undef PTRACE_GETREGS
diff --git a/sysdeps/unix/sysv/linux/sparc/sys/user.h b/sysdeps/unix/sysv/linux/sparc/sys/user.h
index c9c486a7d7..9e3057af93 100644
--- a/sysdeps/unix/sysv/linux/sparc/sys/user.h
+++ b/sysdeps/unix/sysv/linux/sparc/sys/user.h
@@ -18,7 +18,8 @@ 
 #ifndef _SYS_USER_H
 #define _SYS_USER_H	1
 
-#include <stddef.h>
+#include <features.h>
+#include <bits/types/size_t.h>
 
 struct sunos_regs
 {
diff --git a/sysdeps/unix/sysv/linux/sys/sysctl.h b/sysdeps/unix/sysv/linux/sys/sysctl.h
index be34555668..6ca4aaa488 100644
--- a/sysdeps/unix/sysv/linux/sys/sysctl.h
+++ b/sysdeps/unix/sysv/linux/sys/sysctl.h
@@ -21,8 +21,8 @@ 
 #warning "The <sys/sysctl.h> header is deprecated and will be removed."
 
 #include <features.h>
-#define __need_size_t
-#include <stddef.h>
+#include <bits/types/size_t.h>
+
 /* Prevent more kernel headers than necessary to be included.  */
 #ifndef _LINUX_KERNEL_H
 # define _LINUX_KERNEL_H	1
diff --git a/sysdeps/unix/sysv/linux/x86/sys/user.h b/sysdeps/unix/sysv/linux/x86/sys/user.h
index b462a00e57..9de2572dac 100644
--- a/sysdeps/unix/sysv/linux/x86/sys/user.h
+++ b/sysdeps/unix/sysv/linux/x86/sys/user.h
@@ -18,6 +18,8 @@ 
 #ifndef _SYS_USER_H
 #define _SYS_USER_H	1
 
+#include <features.h>
+
 /* The whole purpose of this file is for GDB and GDB only.  Don't read
    too much into it.  Don't use it for anything other than GDB unless
    you know what you are doing.  */
diff --git a/sysvipc/sys/msg.h b/sysvipc/sys/msg.h
index f2f18f4dc5..d6d0610dff 100644
--- a/sysvipc/sys/msg.h
+++ b/sysvipc/sys/msg.h
@@ -20,20 +20,18 @@ 
 
 #include <features.h>
 
-#define __need_size_t
-#include <stddef.h>
-
 /* Get common definition of System V style IPC.  */
 #include <sys/ipc.h>
 
-/* Get system dependent definition of `struct msqid_ds' and more.  */
-#include <bits/msq.h>
-
 /* Define types required by the standard.  */
 #include <bits/types/time_t.h>
 #include <bits/types/pid_t.h>
+#include <bits/types/size_t.h>
 #include <bits/types/ssize_t.h>
 
+/* Get system dependent definition of `struct msqid_ds' and more.  */
+#include <bits/msq.h>
+
 /* The following System V style IPC functions implement a message queue
    system.  The definition is found in XPG2.  */
 
diff --git a/sysvipc/sys/sem.h b/sysvipc/sys/sem.h
index ea9b66e1ee..6b5d43d71c 100644
--- a/sysvipc/sys/sem.h
+++ b/sysvipc/sys/sem.h
@@ -20,19 +20,18 @@ 
 
 #include <features.h>
 
-#define __need_size_t
-#include <stddef.h>
-
 /* Get common definition of System V style IPC.  */
 #include <sys/ipc.h>
 
-/* Get system dependent definition of `struct semid_ds' and more.  */
-#include <bits/sem.h>
-
+/* Define types required by the standard.  */
+#include <bits/types/size_t.h>
 #ifdef __USE_GNU
 # include <bits/types/struct_timespec.h>
 #endif
 
+/* Get system dependent definition of `struct semid_ds' and more.  */
+#include <bits/sem.h>
+
 /* The following System V style IPC functions implement a semaphore
    handling.  The definition is found in XPG2.  */
 
diff --git a/sysvipc/sys/shm.h b/sysvipc/sys/shm.h
index bf836a75f1..b935f2789e 100644
--- a/sysvipc/sys/shm.h
+++ b/sysvipc/sys/shm.h
@@ -20,21 +20,19 @@ 
 
 #include <features.h>
 
-#define __need_size_t
-#include <stddef.h>
-
 /* Get common definition of System V style IPC.  */
 #include <sys/ipc.h>
 
-/* Get system dependent definition of `struct shmid_ds' and more.  */
-#include <bits/shm.h>
-
 /* Define types required by the standard.  */
+#include <bits/types/size_t.h>
 #include <bits/types/time_t.h>
 #ifdef __USE_XOPEN
 # include <bits/types/pid_t.h>
 #endif
 
+/* Get system dependent definition of `struct shmid_ds' and more.  */
+#include <bits/shm.h>
+
 __BEGIN_DECLS
 
 /* The following System V style IPC functions implement a shared memory
diff --git a/time/time.h b/time/time.h
index 232531c6f0..45a02589ec 100644
--- a/time/time.h
+++ b/time/time.h
@@ -24,17 +24,15 @@ 
 
 #include <features.h>
 
-#define __need_size_t
-#define __need_NULL
-#include <stddef.h>
-
 /* This defines CLOCKS_PER_SEC, which is the number of processor clock
    ticks per second, and possibly a number of other constants.   */
 #include <bits/time.h>
 
-/* Many of the typedefs and structs whose official home is this header
-   may also need to be defined by other headers.  */
+/* Typedefs and structs required to be defined by this header.
+   Many are also defined by other headers.  */
+#include <bits/NULL.h>
 #include <bits/types/clock_t.h>
+#include <bits/types/size_t.h>
 #include <bits/types/time_t.h>
 #include <bits/types/struct_tm.h>
 
diff --git a/wcsmbs/uchar.h b/wcsmbs/uchar.h
index 315a01540f..690a25d7cf 100644
--- a/wcsmbs/uchar.h
+++ b/wcsmbs/uchar.h
@@ -25,10 +25,8 @@ 
 
 #include <features.h>
 
-#define __need_size_t
-#include <stddef.h>
-
 #include <bits/types.h>
+#include <bits/types/size_t.h>
 #include <bits/types/mbstate_t.h>
 
 #ifndef __USE_ISOCXX11
diff --git a/wcsmbs/wchar.h b/wcsmbs/wchar.h
index 20deca90bf..ceb72b340c 100644
--- a/wcsmbs/wchar.h
+++ b/wcsmbs/wchar.h
@@ -27,20 +27,16 @@ 
 #include <bits/libc-header-start.h>
 
 /* Gather machine dependent type support.  */
-#include <bits/floatn.h>
-
-#define __need_size_t
-#define __need_wchar_t
-#define __need_NULL
-#include <stddef.h>
-
-#define __need___va_list
-#include <stdarg.h>
-
-#include <bits/wchar.h>
-#include <bits/types/wint_t.h>
-#include <bits/types/mbstate_t.h>
 #include <bits/types/__FILE.h>
+#include <bits/types/__va_list.h>
+#include <bits/types/mbstate_t.h>
+#include <bits/types/size_t.h>
+#include <bits/types/wchar_t.h>
+#include <bits/types/wint_t.h>
+
+#include <bits/NULL.h>
+#include <bits/floatn.h>
+#include <bits/wchar.h>
 
 #if defined __USE_UNIX98 || defined __USE_XOPEN2K
 # include <bits/types/FILE.h>
diff --git a/wcsmbs/wcstol_l.c b/wcsmbs/wcstol_l.c
index 71e9cd4e90..219381d1f7 100644
--- a/wcsmbs/wcstol_l.c
+++ b/wcsmbs/wcstol_l.c
@@ -17,7 +17,6 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#define __need_wchar_t
 #include <stddef.h>
 #include <locale.h>
 
diff --git a/wcsmbs/wcstoll_l.c b/wcsmbs/wcstoll_l.c
index aba48ffcae..9bea4afc7c 100644
--- a/wcsmbs/wcstoll_l.c
+++ b/wcsmbs/wcstoll_l.c
@@ -17,7 +17,6 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#define __need_wchar_t
 #include <stddef.h>
 #include <locale.h>
 
diff --git a/wcsmbs/wcstoul_l.c b/wcsmbs/wcstoul_l.c
index 07d2e18a05..1811cbfafe 100644
--- a/wcsmbs/wcstoul_l.c
+++ b/wcsmbs/wcstoul_l.c
@@ -17,7 +17,6 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#define __need_wchar_t
 #include <stddef.h>
 #include <locale.h>
 
diff --git a/wcsmbs/wcstoull_l.c b/wcsmbs/wcstoull_l.c
index 179771e24c..cd0ef9c955 100644
--- a/wcsmbs/wcstoull_l.c
+++ b/wcsmbs/wcstoull_l.c
@@ -17,7 +17,6 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#define __need_wchar_t
 #include <stddef.h>
 #include <locale.h>