[05/10] Remove __need macros from errno.h (__need_Emath, __need_error_t).

Message ID 20170509154103.11973-6-zackw@panix.com
State Superseded
Headers

Commit Message

Zack Weinberg May 9, 2017, 3:40 p.m. UTC
  This is fairly complicated, not because the users of __need_Emath and
__need_error_t have complicated requirements, but because the core
changes had a lot of fallout.

__need_Emath is defined only by .S files; what they _really_ need is
for errno.h to avoid declaring anything other than the E-constants
(e.g. 'extern int __errno_location(void);' is a syntax error in
assembly language). This is replaced with a check for __ASSEMBLER__ in
errno.h, plus a carefully documented requirement for bits/errno.h not
to define anything other than macros.  That in turn has the
consequence that bits/errno.h must not define errno - fortunately,
there were only two versions of the definition in a live port, so I
moved them to errno.h and added a new __GLIBC_USE macro to choose
between them.  As a consequence of *that*, attribute_tls_model_ie
needed to move to sys/cdefs.h and be renamed __attribute_tls_model_ie__.

__need_error_t exists for gnulib compatibility in argz.h and argp.h.
error_t itself is a slightly-too-clever Hurdism, an enum containing
all the E-constants, so you can do 'p (error_t) errno' in gdb and get
a symbolic value.  argz.h and argp.h want to fall back to 'int' when
that's not available.  Also, to comply with the rule that bits/errno.h
may only define macros anymore, the definition of error_t had to be
removed from sysdeps/mach/hurd/bits/errno.h somehow.  I have elected
to move error_t to a file generated at build time and make it
available for all supported hosts, not just Hurd.  This allows
creation of a generic bits/types/error_t.h.  However, the price is
that the new definition requires a GCC >=4.5 feature - otherwise it
falls back to 'int'.  And you may regret reading the generated
bits/errno-enum.h.

	* stdlib/errno.h: Remove __need_Emath and __need_error_t logic.
        Include bits/types/error_t.h for error_t.  Declare errno here,
	using either __thread or __errno_location, as directed by
	bits/errno.h.  When __ASSEMBLER__ is defined, provide only the
	E* constants, as macros.  Reorganize file.
	* stdlib/bits/types/error_t.h: New file.
	* include/bits/types/error_t.h: New wrapper.
	* scripts/make-errno-enum.sh: New file.
	* Makeconfig: Add rules to generate bits/errno-enum.h.
	(common-generated): Add bits/errno-enum.h and bits/errno-enum.h.stmp.
	Also add dl-tunable-list.h and dl-tunable-list.stmp, missed in a
	previous patch.
	(dl-tunable-list.h): Generate using a stamp file.
	* stdlib/Makefile: Install bits/types/error_t.h and bits/errno-enum.h.

	* bits/errno.h: Remove logic for __need_Emath.  Document
	requirements for a port-specific bits/errno.h.

	* include/errno.h: Change conditional for exposing internal
	declarations to (not _ISOMAC and not __ASSEMBLER__).
	* include/features.h (__GLIBC_USE_TLS_ERRNO): New feature
	selection macro, defaults to 0.

	* sysdeps/mach/hurd/errnos.awk
	* sysdeps/nacl/errnos.awk
	* sysdeps/unix/sysv/linux/bits/errno.h
	* sysdeps/unix/sysv/linux/alpha/bits/errno.h
	* sysdeps/unix/sysv/linux/hppa/bits/errno.h
	* sysdeps/unix/sysv/linux/mips/bits/errno.h
	* sysdeps/unix/sysv/linux/sparc/bits/errno.h:
	Add multiple-include guard and check against improper inclusion.
	Remove __need_Emath logic. Don't declare errno here. Ensure all
	constants are defined as simple integer literals.  Redefine
	__GLIBC_USE_TLS_ERRNO to 1 if appropriate.  Consistent formatting.
	* sysdeps/mach/hurd/bits/errno.h: Regenerate.

	* argp/argp.h, string/argz.h: Include bits/types/error_t.h for error_t.

	* sysdeps/i386/i686/fpu/multiarch/s_cosf-sse2.S
	* sysdeps/i386/i686/fpu/multiarch/s_sincosf-sse2.S
	* sysdeps/i386/i686/fpu/multiarch/s_sinf-sse2.S
	* sysdeps/x86_64/fpu/s_cosf.S
	* sysdeps/x86_64/fpu/s_sincosf.S
	* sysdeps/x86_64/fpu/s_sinf.S
	Just include errno.h; don't define __need_Emath or include
	bits/errno.h directly.

	* include/libc-symbols.h (attribute_tls_model_ie): Remove.
	* misc/sys/cdefs.h (__attribute_tls_model_ie__): New.
	* elf/dl-error-skeleton.c, include/errno.h, include/netdb.h
	* include/resolv.h, locale/localeinfo.h, malloc/arena.c
	* sunrpc/rpc_thread.c, sysdeps/generic/libc-tsd.h
	* sysdeps/ieee754/ldbl-opt/math_ldbl_opt.c
	* sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h
	* sysdeps/powerpc/nofpu/soft-supp.h
	* sysdeps/powerpc/soft-fp/sfp-machine.h
	Use __attribute_tls_model_ie__ and/or __attribute_const__.
---
 Makeconfig                                       |  26 +-
 argp/argp.h                                      |   8 +-
 bits/errno.h                                     |  43 +-
 elf/dl-error-skeleton.c                          |   2 +-
 include/bits/types/error_t.h                     |   1 +
 include/errno.h                                  |  15 +-
 include/features.h                               |   6 +
 include/libc-symbols.h                           |   2 -
 include/netdb.h                                  |   2 +-
 include/resolv.h                                 |   2 +-
 locale/localeinfo.h                              |   2 +-
 malloc/arena.c                                   |   2 +-
 misc/sys/cdefs.h                                 |   7 +
 scripts/make-errno-enum.sh                       |  67 +++
 stdlib/Makefile                                  |   3 +-
 stdlib/bits/types/error_t.h                      |  14 +
 stdlib/errno.h                                   |  60 ++-
 string/argz.h                                    |   9 +-
 sunrpc/rpc_thread.c                              |   2 +-
 sysdeps/generic/libc-tsd.h                       |   2 +-
 sysdeps/i386/i686/fpu/multiarch/s_cosf-sse2.S    |   3 +-
 sysdeps/i386/i686/fpu/multiarch/s_sincosf-sse2.S |   3 +-
 sysdeps/i386/i686/fpu/multiarch/s_sinf-sse2.S    |   3 +-
 sysdeps/ieee754/ldbl-opt/math_ldbl_opt.c         |   2 +-
 sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h         |   3 +-
 sysdeps/mach/hurd/bits/errno.h                   | 503 +++++++++--------------
 sysdeps/mach/hurd/errnos.awk                     |  89 ++--
 sysdeps/nacl/errnos.awk                          |  23 +-
 sysdeps/powerpc/nofpu/soft-supp.h                |   6 +-
 sysdeps/powerpc/soft-fp/sfp-machine.h            |   6 +-
 sysdeps/unix/sysv/linux/alpha/bits/errno.h       |  46 +--
 sysdeps/unix/sysv/linux/bits/errno.h             |  47 +--
 sysdeps/unix/sysv/linux/hppa/bits/errno.h        |  39 +-
 sysdeps/unix/sysv/linux/mips/bits/errno.h        |  45 +-
 sysdeps/unix/sysv/linux/sparc/bits/errno.h       |  46 +--
 sysdeps/x86_64/fpu/s_cosf.S                      |   3 +-
 sysdeps/x86_64/fpu/s_sincosf.S                   |   3 +-
 sysdeps/x86_64/fpu/s_sinf.S                      |   3 +-
 38 files changed, 501 insertions(+), 647 deletions(-)
 create mode 100644 include/bits/types/error_t.h
 create mode 100644 scripts/make-errno-enum.sh
 create mode 100644 stdlib/bits/types/error_t.h
  

Comments

Joseph Myers May 9, 2017, 9:38 p.m. UTC | #1
On Tue, 9 May 2017, Zack Weinberg wrote:

> diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
> index 74f9a49b05..075c996f28 100644
> --- a/misc/sys/cdefs.h
> +++ b/misc/sys/cdefs.h
> @@ -326,6 +326,13 @@
>  # define __attribute_artificial__ /* Ignore */
>  #endif
>  
> +/* Force use of the initial-exec TLS model.  */
> +#if __GNUC_PREREQ (3,3)
> +# define __attribute_tls_model_ie__ __attribute__ ((tls_model ("initial-exec")))

This is not namespace-clean for an installed header (needs to be 
__tls_model__).

This is not a review of the rest of this patch.
  
Florian Weimer May 10, 2017, 7:30 a.m. UTC | #2
On 05/09/2017 11:38 PM, Joseph Myers wrote:
> On Tue, 9 May 2017, Zack Weinberg wrote:
> 
>> diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
>> index 74f9a49b05..075c996f28 100644
>> --- a/misc/sys/cdefs.h
>> +++ b/misc/sys/cdefs.h
>> @@ -326,6 +326,13 @@
>>   # define __attribute_artificial__ /* Ignore */
>>   #endif
>>   
>> +/* Force use of the initial-exec TLS model.  */
>> +#if __GNUC_PREREQ (3,3)
>> +# define __attribute_tls_model_ie__ __attribute__ ((tls_model ("initial-exec")))
> 
> This is not namespace-clean for an installed header (needs to be
> __tls_model__).

The larger problem is that we need to error out if __GLIBC_USE 
(TLS_ERRNO) and the compiler does not support the initial-exec TLS model 
because it cannot produce the required ABI for the errno symbol.

In my opinion, we could just decide that the NaCl port, if resurrected, 
needs to implement __errno_location like the other ports.  Then you 
could drop the __GLIBC_USE (TLS_ERRNO) logic entirely, and you don't 
need __attribute_tls_model_ie__, either.

Thanks,
Florian
  
Joseph Myers May 10, 2017, 11:47 a.m. UTC | #3
On Wed, 10 May 2017, Florian Weimer wrote:

> On 05/09/2017 11:38 PM, Joseph Myers wrote:
> > On Tue, 9 May 2017, Zack Weinberg wrote:
> > 
> > > diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
> > > index 74f9a49b05..075c996f28 100644
> > > --- a/misc/sys/cdefs.h
> > > +++ b/misc/sys/cdefs.h
> > > @@ -326,6 +326,13 @@
> > >   # define __attribute_artificial__ /* Ignore */
> > >   #endif
> > >   +/* Force use of the initial-exec TLS model.  */
> > > +#if __GNUC_PREREQ (3,3)
> > > +# define __attribute_tls_model_ie__ __attribute__ ((tls_model
> > > ("initial-exec")))
> > 
> > This is not namespace-clean for an installed header (needs to be
> > __tls_model__).
> 
> The larger problem is that we need to error out if __GLIBC_USE (TLS_ERRNO) and
> the compiler does not support the initial-exec TLS model because it cannot
> produce the required ABI for the errno symbol.

You don't need initial-exec TLS for errno.  If a port wishes to export TLS 
errno directly, it's perfectly valid for the headers to do

extern _Thread_local int errno;
#define errno errno

with any C11 compiler, and if the compiler only supports GD model TLS, 
that's fine for accessing an IE variable (it may or may not get optimized 
to IE by the linker).  Declaring the TLS model is simply an optimization.

(This is not an assertion about the relative efficiency of a GD access to 
errno versus calling __errno_location which in turn does an IE access.)
  
Florian Weimer May 10, 2017, 12:03 p.m. UTC | #4
On 05/10/2017 01:47 PM, Joseph Myers wrote:
> On Wed, 10 May 2017, Florian Weimer wrote:
> 
>> On 05/09/2017 11:38 PM, Joseph Myers wrote:
>>> On Tue, 9 May 2017, Zack Weinberg wrote:
>>>
>>>> diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
>>>> index 74f9a49b05..075c996f28 100644
>>>> --- a/misc/sys/cdefs.h
>>>> +++ b/misc/sys/cdefs.h
>>>> @@ -326,6 +326,13 @@
>>>>    # define __attribute_artificial__ /* Ignore */
>>>>    #endif
>>>>    +/* Force use of the initial-exec TLS model.  */
>>>> +#if __GNUC_PREREQ (3,3)
>>>> +# define __attribute_tls_model_ie__ __attribute__ ((tls_model
>>>> ("initial-exec")))
>>>
>>> This is not namespace-clean for an installed header (needs to be
>>> __tls_model__).
>>
>> The larger problem is that we need to error out if __GLIBC_USE (TLS_ERRNO) and
>> the compiler does not support the initial-exec TLS model because it cannot
>> produce the required ABI for the errno symbol.
> 
> You don't need initial-exec TLS for errno.  If a port wishes to export TLS
> errno directly, it's perfectly valid for the headers to do
> 
> extern _Thread_local int errno;
> #define errno errno
> 
> with any C11 compiler, and if the compiler only supports GD model TLS,
> that's fine for accessing an IE variable (it may or may not get optimized
> to IE by the linker).  Declaring the TLS model is simply an optimization.

That's true if we want to create a port which is effectively C11-only. 
(The NaCl header generator uses __thread, though, so it's still 
non-standard.)

However, I still think that the NaCl port should be aligned with the 
rest of glibc in this regard, and that Zack's cleanup should not 
introduce a new extension point for it.  Particularly since we don't 
have a working port right now which would exercise this functionality, 
so it's likely to be broken anyway.

Thanks,
Florian
  
Zack Weinberg May 11, 2017, 12:15 p.m. UTC | #5
On Wed, May 10, 2017 at 8:03 AM, Florian Weimer <fweimer@redhat.com> wrote:
> However, I still think that the NaCl port should be aligned with the rest of
> glibc in this regard, and that Zack's cleanup should not introduce a new
> extension point for it.  Particularly since we don't have a working port
> right now which would exercise this functionality, so it's likely to be
> broken anyway.

What would you have me do with sysdeps/nacl/errnos.awk, then?

(If the NaCl port doesn't work, should we just discard it altogether?
I see value in keeping a non-Linux port around, but there are rumors
to the effect that Google has abandoned NaCl[1] so maybe not _this_
one...)

zw

[1] https://bugs.chromium.org/p/chromium/issues/detail?id=239656#c160
"Pepper and NaCl are destaffed."
  
Joseph Myers May 11, 2017, 2:30 p.m. UTC | #6
On Thu, 11 May 2017, Zack Weinberg wrote:

> On Wed, May 10, 2017 at 8:03 AM, Florian Weimer <fweimer@redhat.com> wrote:
> > However, I still think that the NaCl port should be aligned with the rest of
> > glibc in this regard, and that Zack's cleanup should not introduce a new
> > extension point for it.  Particularly since we don't have a working port
> > right now which would exercise this functionality, so it's likely to be
> > broken anyway.
> 
> What would you have me do with sysdeps/nacl/errnos.awk, then?
> 
> (If the NaCl port doesn't work, should we just discard it altogether?
> I see value in keeping a non-Linux port around, but there are rumors
> to the effect that Google has abandoned NaCl[1] so maybe not _this_
> one...)

Well, we need such a port that works in current glibc sources (used 
together with upstream sources of other toolchain components), and where 
build-many-glibcs.py knows how and where to check out any OS-specific 
components (analogous to Linux kernel headers, for example) needed and how 
to build a cross toolchain for that target.  Neither NaCl nor Hurd meets 
those criteria at present; either could be made to meet them, if someone 
sufficiently familiar with building toolchains and glibc for that OS does 
the work required.

Otherwise, I'm not sure if anyone is currently working on the GNU/kFreeBSD 
port of glibc, but it's not upstream.  (And as a system with Unix-like 
syscalls, it would be less different from the Linux ports than NaCl or 
Hurd.)  And there's the WebAssembly port 
<https://github.com/pipcet/glibc>, also not (yet) upstream (neither is the 
GCC port, though at least some binutils support is upstream).
  
Zack Weinberg May 11, 2017, 2:46 p.m. UTC | #7
On Thu, May 11, 2017 at 10:30 AM, Joseph Myers <joseph@codesourcery.com> wrote:
> On Thu, 11 May 2017, Zack Weinberg wrote:
>>
>> If the NaCl port doesn't work, should we just discard it altogether?
>> I see value in keeping a non-Linux port around, but there are rumors
>> to the effect that Google has abandoned NaCl[1] so maybe not _this_
>> one...
>
> Well, we need such a port that works in current glibc sources (used
> together with upstream sources of other toolchain components), and where
> build-many-glibcs.py knows how and where to check out any OS-specific
> components (analogous to Linux kernel headers, for example) needed and how
> to build a cross toolchain for that target.  Neither NaCl nor Hurd meets
> those criteria at present; either could be made to meet them, if someone
> sufficiently familiar with building toolchains and glibc for that OS does
> the work required.
>
> Otherwise, I'm not sure if anyone is currently working on the GNU/kFreeBSD
> port of glibc, but it's not upstream.  (And as a system with Unix-like
> syscalls, it would be less different from the Linux ports than NaCl or
> Hurd.)  And there's the WebAssembly port
> <https://github.com/pipcet/glibc>, also not (yet) upstream (neither is the
> GCC port, though at least some binutils support is upstream).

None of that answers the immediate question, which is, given that the
NaCl port *currently in glibc* can't be built by build-many-glibcs and
is said to be at least somewhat broken, should it be deleted?

zw
  
Florian Weimer May 11, 2017, 2:48 p.m. UTC | #8
On 05/11/2017 02:15 PM, Zack Weinberg wrote:
> On Wed, May 10, 2017 at 8:03 AM, Florian Weimer <fweimer@redhat.com> wrote:
>> However, I still think that the NaCl port should be aligned with the rest of
>> glibc in this regard, and that Zack's cleanup should not introduce a new
>> extension point for it.  Particularly since we don't have a working port
>> right now which would exercise this functionality, so it's likely to be
>> broken anyway.
> 
> What would you have me do with sysdeps/nacl/errnos.awk, then?

Maybe add a comment that this needs adjustment?

I expect that there is probably similar bit rot within the NaCl port 
elsewhere.

> (If the NaCl port doesn't work, should we just discard it altogether?
> I see value in keeping a non-Linux port around, but there are rumors
> to the effect that Google has abandoned NaCl[1] so maybe not _this_
> one...)
> [1] https://bugs.chromium.org/p/chromium/issues/detail?id=239656#c160
> "Pepper and NaCl are destaffed."

They still ship a NaCl SDK for Chrome, but it's Clang-based now, so it 
can't be used to compile glibc.  The NaCl GCC port has never been 
upstreamed.  There are patches somewhere for GCC versions otherwise 
supported to build glibc (late GCC 4.x versions), but if we probably 
should move to GCC 5 as a minimum version soon (because the 4.x branches 
are all dead upstream), and then there wouldn't be a NaCl GCC left.

Florian
  
Florian Weimer May 11, 2017, 2:53 p.m. UTC | #9
On 05/11/2017 04:46 PM, Zack Weinberg wrote:
> None of that answers the immediate question, which is, given that the
> NaCl port*currently in glibc*  can't be built by build-many-glibcs and
> is said to be at least somewhat broken, should it be deleted?

We recently had a discussion about this:

   https://sourceware.org/ml/libc-alpha/2017-04/msg00238.html

I eventually argued away the need for SOCK_CLOEXEC etc. support, so I 
didn't press the issue at the time.  Feel free to revive the thread.  We 
probably should involve the official stewards before a final decision to 
remove it.

In any case, the conclusion from related issues was that global cleanups 
should not be blocked by non-buildable ports.  NaCl would be reasonably 
easy to fix up by adding an exported definition of __errno_location, so 
that the generic header works again.  But I think the consensus was that 
you don't have to do this if you don't want to.

Thanks,
Florian
  
Joseph Myers May 11, 2017, 3:26 p.m. UTC | #10
On Thu, 11 May 2017, Florian Weimer wrote:

> They still ship a NaCl SDK for Chrome, but it's Clang-based now, so it can't
> be used to compile glibc.  The NaCl GCC port has never been upstreamed.  There
> are patches somewhere for GCC versions otherwise supported to build glibc
> (late GCC 4.x versions), but if we probably should move to GCC 5 as a minimum
> version soon (because the 4.x branches are all dead upstream), and then there
> wouldn't be a NaCl GCC left.

I'd be fine with all of:

* Removing the NaCl port (on the understanding that the initial removal 
patch does not need to remove the ARM_SFI_MACROS code in the ARM port, and 
anything else NaCl-specific in non-NaCl-specific files, but such removal 
would be desirable over time).

* Requiring GCC 5 as minimum GCC version for building glibc on the basis 
of what's maintained upstream (though that's more aggressive than we've 
previously been on increasing GCC version requirements).  (Versions before 
4.9 don't work with build-many-glibcs.py anyway.)

* Requiring a binutils version of similar vintage to GCC 5 as minimum 
binutils version for building glibc, maybe 2.25.  (Basing things on what 
binutils versions distributions with GCC 5 have may be sensible there.  I 
don't think binutils really maintains past release branches once there's 
been a release from a new branch, so basing on what's maintained would be 
too aggressive.)

Note: the i686 and x86_64 buildbot slaves have (from the configure logs) 
binutils 2.24.  They appear (from the paths in the logs) to be running 
Ubuntu 14.04, so have GCC 4.8, and would need either local build tools, or 
an OS upgrade, to continue operating after such an increase in required 
versions.  I don't know whether any other buildbot slaves would also be 
affected by such increased requirements.  But since the i686 buildbot has 
tests failing with "/usr/bin/ld: BFD (GNU Binutils for Ubuntu) 2.24 
assertion fail ../../bfd/elf32-i386.c:4016" linking 
elf/tst-gnu2-tls1mod.so, it's already in practice the case that 2.24 is 
not a suitable binutils version for building/testing glibc on that 
platform.
  
Andreas Schwab May 11, 2017, 3:42 p.m. UTC | #11
On Mai 11 2017, Joseph Myers <joseph@codesourcery.com> wrote:

> * Requiring GCC 5 as minimum GCC version for building glibc on the basis 
> of what's maintained upstream (though that's more aggressive than we've 
> previously been on increasing GCC version requirements).  (Versions before 
> 4.9 don't work with build-many-glibcs.py anyway.)

openSUSE Leap 42.2 (aka SLE 12) has gcc 4.8 as the system compiler.

Andreas.
  
Joseph Myers May 11, 2017, 4:10 p.m. UTC | #12
On Thu, 11 May 2017, Andreas Schwab wrote:

> On Mai 11 2017, Joseph Myers <joseph@codesourcery.com> wrote:
> 
> > * Requiring GCC 5 as minimum GCC version for building glibc on the basis 
> > of what's maintained upstream (though that's more aggressive than we've 
> > previously been on increasing GCC version requirements).  (Versions before 
> > 4.9 don't work with build-many-glibcs.py anyway.)
> 
> openSUSE Leap 42.2 (aka SLE 12) has gcc 4.8 as the system compiler.

And what binutils version?  (Given the evidence that 2.24 is already too 
old.)

I think there are plausible arguments for requiring 4.8 with 4.9 required 
for glibc 2.27 (consistent with the times when we introduced 4.6 and 4.7 
requirements); 4.9 now (a bit more aggressive on requiring new versions, 
and minimum for use with build-many-glibcs.py; supports _Atomic and 
stdatomic.h, which would allow conform/ expectations to be added for 
stdatomic.h without XFAILs for them, even though we should avoid libatomic 
dependencies in glibc); 5 now (oldest version currently maintained).

I think there is a clear argument for requiring binutils 2.25 or later, 
given those x86 internal linker errors.

I think there is a clear argument for removing the NaCl port (and 
generally saying that while there isn't a particular order in which 
toolchain components have to go upstream, to accept a glibc port the GCC 
port should be upstream not long after the glibc port is in).
  
Florian Weimer May 11, 2017, 4:19 p.m. UTC | #13
On 05/11/2017 05:42 PM, Andreas Schwab wrote:
> On Mai 11 2017, Joseph Myers <joseph@codesourcery.com> wrote:
> 
>> * Requiring GCC 5 as minimum GCC version for building glibc on the basis
>> of what's maintained upstream (though that's more aggressive than we've
>> previously been on increasing GCC version requirements).  (Versions before
>> 4.9 don't work with build-many-glibcs.py anyway.)
> 
> openSUSE Leap 42.2 (aka SLE 12) has gcc 4.8 as the system compiler.

Is it possible to use the Toolchain Module to get a newer GCC version?

On our side, we have Developer Toolset (DTS) with newer GCC and binutils 
versions.  Red Hat Enterprise Linux 7 is at GCC 4.8, too, but enabling 
DTS wouldn't be too cumbersome, I think.

Thanks,
Florian
  
Andreas Schwab May 11, 2017, 5:20 p.m. UTC | #14
On Mai 11 2017, Joseph Myers <joseph@codesourcery.com> wrote:

> On Thu, 11 May 2017, Andreas Schwab wrote:
>
>> On Mai 11 2017, Joseph Myers <joseph@codesourcery.com> wrote:
>> 
>> > * Requiring GCC 5 as minimum GCC version for building glibc on the basis 
>> > of what's maintained upstream (though that's more aggressive than we've 
>> > previously been on increasing GCC version requirements).  (Versions before 
>> > 4.9 don't work with build-many-glibcs.py anyway.)
>> 
>> openSUSE Leap 42.2 (aka SLE 12) has gcc 4.8 as the system compiler.
>
> And what binutils version?

2.26.1 (it is easier to update binutils than the compiler).

Andreas.
  
Andreas Schwab May 11, 2017, 5:25 p.m. UTC | #15
On Mai 11 2017, Florian Weimer <fweimer@redhat.com> wrote:

> On 05/11/2017 05:42 PM, Andreas Schwab wrote:
>> On Mai 11 2017, Joseph Myers <joseph@codesourcery.com> wrote:
>>
>>> * Requiring GCC 5 as minimum GCC version for building glibc on the basis
>>> of what's maintained upstream (though that's more aggressive than we've
>>> previously been on increasing GCC version requirements).  (Versions before
>>> 4.9 don't work with build-many-glibcs.py anyway.)
>>
>> openSUSE Leap 42.2 (aka SLE 12) has gcc 4.8 as the system compiler.
>
> Is it possible to use the Toolchain Module to get a newer GCC version?

Both Leap and the toolchain module offer gcc5 and gcc6.  But what you
call as gcc will remain 4.8.

Andreas.
  
Florian Weimer May 12, 2017, 6:23 a.m. UTC | #16
On 05/11/2017 07:25 PM, Andreas Schwab wrote:
> On Mai 11 2017, Florian Weimer <fweimer@redhat.com> wrote:
> 
>> On 05/11/2017 05:42 PM, Andreas Schwab wrote:
>>> On Mai 11 2017, Joseph Myers <joseph@codesourcery.com> wrote:
>>>
>>>> * Requiring GCC 5 as minimum GCC version for building glibc on the basis
>>>> of what's maintained upstream (though that's more aggressive than we've
>>>> previously been on increasing GCC version requirements).  (Versions before
>>>> 4.9 don't work with build-many-glibcs.py anyway.)
>>>
>>> openSUSE Leap 42.2 (aka SLE 12) has gcc 4.8 as the system compiler.
>>
>> Is it possible to use the Toolchain Module to get a newer GCC version?
> 
> Both Leap and the toolchain module offer gcc5 and gcc6.  But what you
> call as gcc will remain 4.8.

Do you think that results in a major inconvenience?

Thanks,
Florian
  
Andreas Schwab May 15, 2017, 8:11 a.m. UTC | #17
On Mai 12 2017, Florian Weimer <fweimer@redhat.com> wrote:

> On 05/11/2017 07:25 PM, Andreas Schwab wrote:
>> On Mai 11 2017, Florian Weimer <fweimer@redhat.com> wrote:
>>
>>> On 05/11/2017 05:42 PM, Andreas Schwab wrote:
>>>> On Mai 11 2017, Joseph Myers <joseph@codesourcery.com> wrote:
>>>>
>>>>> * Requiring GCC 5 as minimum GCC version for building glibc on the basis
>>>>> of what's maintained upstream (though that's more aggressive than we've
>>>>> previously been on increasing GCC version requirements).  (Versions before
>>>>> 4.9 don't work with build-many-glibcs.py anyway.)
>>>>
>>>> openSUSE Leap 42.2 (aka SLE 12) has gcc 4.8 as the system compiler.
>>>
>>> Is it possible to use the Toolchain Module to get a newer GCC version?
>>
>> Both Leap and the toolchain module offer gcc5 and gcc6.  But what you
>> call as gcc will remain 4.8.
>
> Do you think that results in a major inconvenience?

You have to remember to point both CC and CXX to the newer compiler.

Andreas.
  
Florian Weimer May 15, 2017, 8:13 a.m. UTC | #18
On 05/15/2017 10:11 AM, Andreas Schwab wrote:
> On Mai 12 2017, Florian Weimer <fweimer@redhat.com> wrote:
> 
>> On 05/11/2017 07:25 PM, Andreas Schwab wrote:
>>> On Mai 11 2017, Florian Weimer <fweimer@redhat.com> wrote:
>>>
>>>> On 05/11/2017 05:42 PM, Andreas Schwab wrote:
>>>>> On Mai 11 2017, Joseph Myers <joseph@codesourcery.com> wrote:
>>>>>
>>>>>> * Requiring GCC 5 as minimum GCC version for building glibc on the basis
>>>>>> of what's maintained upstream (though that's more aggressive than we've
>>>>>> previously been on increasing GCC version requirements).  (Versions before
>>>>>> 4.9 don't work with build-many-glibcs.py anyway.)
>>>>>
>>>>> openSUSE Leap 42.2 (aka SLE 12) has gcc 4.8 as the system compiler.
>>>>
>>>> Is it possible to use the Toolchain Module to get a newer GCC version?
>>>
>>> Both Leap and the toolchain module offer gcc5 and gcc6.  But what you
>>> call as gcc will remain 4.8.
>>
>> Do you think that results in a major inconvenience?
> 
> You have to remember to point both CC and CXX to the newer compiler.

Sure, but that doesn't answer my question.  I think it's just a minor 
burden which isn't much of a problem and should not block bumping the 
minimum GCC requirement.

Do you agree?

Is the toolchain module GCC available on PATH?  Maybe we could add some 
fallback detection logic for a suitable compiler, similar to how a 
Bourne shell is located on Solaris.

Thanks,
Florian
  
Andreas Schwab May 15, 2017, 8:24 a.m. UTC | #19
On Mai 15 2017, Florian Weimer <fweimer@redhat.com> wrote:

> Is the toolchain module GCC available on PATH?

Yes, just under a different name (with the major version appended).

Andreas.
  
Florian Weimer May 15, 2017, 9:08 a.m. UTC | #20
On 05/15/2017 10:24 AM, Andreas Schwab wrote:
> On Mai 15 2017, Florian Weimer <fweimer@redhat.com> wrote:
> 
>> Is the toolchain module GCC available on PATH?
> 
> Yes, just under a different name (with the major version appended).

Okay, then we should a configure detection logic for that.

Red Hat Developer Toolset is different in this regard, either you get 
the newer GCC on the PATH as a substitute for “gcc”, or you run gcc with 
an absolute path.  I suppose those who regularly build upstream sources 
could add a symlink from /opt/rh/…/gcc to ~/bin/gcc5, where the patched 
configure script would pick it up (assuming that they do not want to 
enable DTS unconditionally).

Thanks,
Florian
  

Patch

diff --git a/Makeconfig b/Makeconfig
index b494b82b40..0e7777fe57 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -1107,6 +1107,7 @@  postclean-generated += soversions.mk soversions.i \
 		       shlib-versions.v shlib-versions.v.i
 
 before-compile += $(common-objpfx)libc-modules.h
+common-generated += libc-modules.h libc-modules.stmp
 ifeq ($(soversions.mk-done),t)
 # Generate a header with macro definitions for use with the IS_IN macro.
 # These are the possible values for the MODULE_NAME macro defined when building
@@ -1125,14 +1126,29 @@  endif
 # glibc.
 ifneq (no,$(have-tunables))
 before-compile += $(common-objpfx)dl-tunable-list.h
+common-generated += dl-tunable-list.h dl-tunable-list.stmp \
+
+$(common-objpfx)dl-tunable-list.h: $(common-objpfx)dl-tunable-list.stmp; @:
+$(common-objpfx)dl-tunable-list.stmp: $(..)scripts/gen-tunables.awk \
+				      $(..)elf/dl-tunables.list
+	$(AWK) -f $^ > ${@:stmp=T}
+	$(move-if-change) ${@:stmp=T} ${@:stmp=h}
+	touch $@
 
-$(common-objpfx)dl-tunable-list.h: $(..)scripts/gen-tunables.awk \
-				   $(..)elf/dl-tunables.list
-	$(AWK) -f $^ > $@.tmp
-	mv $@.tmp $@
 endif
 
-common-generated += libc-modules.h libc-modules.stmp
+# Build errno-enum.h early, ditto.
+before-compile += $(common-objpfx)bits/errno-enum.h
+common-generated += bits/error_t.h bits/errno-enum.stmp
+$(common-objpfx)bits/errno-enum.h: $(common-objpfx)bits/errno-enum.stmp; @:
+$(common-objpfx)bits/errno-enum.stmp: $(..)scripts/make-errno-enum.sh \
+				      bits/errno.h
+	[ -d $(common-objpfx)bits ] || mkdir $(common-objpfx)bits
+	CC="$(CC)" AWK="$(AWK)" \
+	    $(SHELL) $(..)scripts/make-errno-enum.sh $(+includes) \
+	    > ${@:stmp=T}
+	$(move-if-change) ${@:stmp=T} ${@:stmp=h}
+	touch $@
 
 # The name under which the run-time dynamic linker is installed.
 # We are currently going for the convention that `/lib/ld.so.1'
diff --git a/argp/argp.h b/argp/argp.h
index 86b8e5a1e9..f48c007554 100644
--- a/argp/argp.h
+++ b/argp/argp.h
@@ -24,15 +24,9 @@ 
 #include <ctype.h>
 #include <getopt.h>
 #include <limits.h>
-
-#define __need_error_t
 #include <errno.h>
+#include <bits/types/error_t.h>
 
-#ifndef __error_t_defined
-typedef int error_t;
-# define __error_t_defined
-#endif
-
 __BEGIN_DECLS
 
 /* A description of a particular option.  A pointer to an array of
diff --git a/bits/errno.h b/bits/errno.h
index cd4fcfa428..398766afff 100644
--- a/bits/errno.h
+++ b/bits/errno.h
@@ -15,20 +15,37 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-/* This file defines the `errno' constants.  */
+/* This file defines the errno constants.  */
 
-#if !defined __Emath_defined && (defined _ERRNO_H || defined __need_Emath)
-#undef	__need_Emath
-#define	__Emath_defined	1
+#ifndef _BITS_ERRNO_H
+#define _BITS_ERRNO_H 1
 
-# define EDOM	XXX	<--- fill in what is actually needed
-# define EILSEQ	XXX	<--- fill in what is actually needed
-# define ERANGE	XXX	<--- fill in what is actually needed
+#if !defined _ERRNO_H && !defined _BITS_ERRNO_ENUM_H
+#error "Never include <bits/errno.h> directly; use <errno.h> instead."
 #endif
 
-#ifdef	_ERRNO_H
-# error "Define here all the missing error messages for the port.  These"
-# error "must match the numbers of the kernel."
-# define Exxxx	XXX
-...
-#endif
+#error "Generic bits/errno.h included -- port is incomplete."
+
+/* Authors of new ports of the GNU C Library must override this file
+   with their own bits/errno.h in an appropriate subdirectory of
+   sysdeps/.  Its function is to define all of the error constants
+   from C2011 and POSIX.1-2008, with values appropriate to the operating
+   system, and any additional OS-specific error constants.
+
+   Also, if you want your port to expose errno as a thread-local
+   variable instead of using the older __errno_location mechanism,
+   this file should undefine __USE_TLS_ERRNO and redefine it with the
+   value 1.  (features.h provides the default value of 0.)
+
+   C2011 requires all error constants to be object-like macros that
+   expand to "integer constant expressions with type int, positive
+   values, and suitable for use in #if directives".  Moreover, all
+   of their names must begin with a capital E, followed immediately
+   by either another capital letter, or a digit.
+
+   errno.h is sometimes included from assembly language, so
+   bits/errno.h may only define macros; it may not make any other kind
+   of C declaration or definition.  It is OK to define macros that are
+   not E-constants, but only in the implementation namespace.  */
+
+#endif /* bits/errno.h.  */
diff --git a/elf/dl-error-skeleton.c b/elf/dl-error-skeleton.c
index 8e5888d4bd..b2d8de0877 100644
--- a/elf/dl-error-skeleton.c
+++ b/elf/dl-error-skeleton.c
@@ -53,7 +53,7 @@  struct catch
    Therefore we have to be prepared to save the state in thread-local
    memory.  */
 #if !DL_ERROR_BOOTSTRAP
-static __thread struct catch *catch_hook attribute_tls_model_ie;
+static __thread struct catch *catch_hook __attribute_tls_model_ie__;
 #else
 /* The version of this code in ld.so cannot use thread-local variables
    and is used during bootstrap only.  */
diff --git a/include/bits/types/error_t.h b/include/bits/types/error_t.h
new file mode 100644
index 0000000000..1ce1f79202
--- /dev/null
+++ b/include/bits/types/error_t.h
@@ -0,0 +1 @@ 
+#include <stdlib/bits/types/error_t.h>
diff --git a/include/errno.h b/include/errno.h
index 73fc32e5e0..2b54a8e7da 100644
--- a/include/errno.h
+++ b/include/errno.h
@@ -1,8 +1,6 @@ 
 #ifndef _ERRNO_H
-
 #include <stdlib/errno.h>
-
-#if defined _ERRNO_H && !defined _ISOMAC
+#if !defined _ISOMAC && !defined __ASSEMBLER__
 
 # if IS_IN (rtld)
 #  include <dl-sysdep.h>
@@ -32,21 +30,18 @@  extern int rtld_errno attribute_hidden;
 #  else
 #   define errno errno		/* For #ifndef errno tests.  */
 #  endif
-extern __thread int errno attribute_tls_model_ie;
+extern __thread int errno __attribute_tls_model_ie__;
 
 # endif	/* IS_IN_LIB */
 
 # define __set_errno(val) (errno = (val))
 
-# ifndef __ASSEMBLER__
-extern int *__errno_location (void) __THROW __attribute__ ((__const__))
+extern int *__errno_location (void) __THROW __attribute_const__
 #  if RTLD_PRIVATE_ERRNO
      attribute_hidden
 #  endif
 ;
 libc_hidden_proto (__errno_location)
-# endif
 
-#endif /* _ERRNO_H */
-
-#endif /* ! _ERRNO_H */
+#endif /* !_ISOMAC && !__ASSEMBLER__ */
+#endif /* !_ERRNO_H */
diff --git a/include/features.h b/include/features.h
index 7de4089ed3..19458d1fe4 100644
--- a/include/features.h
+++ b/include/features.h
@@ -137,6 +137,7 @@ 
 #undef	__USE_FORTIFY_LEVEL
 #undef	__KERNEL_STRICT_NAMES
 #undef	__GLIBC_USE_DEPRECATED_GETS
+#undef  __GLIBC_USE_TLS_ERRNO
 
 /* Suppress kernel-name space pollution unless user expressedly asks
    for it.  */
@@ -394,6 +395,11 @@ 
 # define __GLIBC_USE_DEPRECATED_GETS 1
 #endif
 
+/* Whether errno should be declared as a thread-local variable, or
+   as a macro that calls __errno_location.  This is the default;
+   bits/errno.h may override.  */
+#define __GLIBC_USE_TLS_ERRNO 0
+
 /* Get definitions of __STDC_* predefined macros, if the compiler has
    not preincluded this header automatically.  */
 #include <stdc-predef.h>
diff --git a/include/libc-symbols.h b/include/libc-symbols.h
index 3310e3a678..a72a099739 100644
--- a/include/libc-symbols.h
+++ b/include/libc-symbols.h
@@ -361,8 +361,6 @@  for linking")
 # define attribute_hidden
 #endif
 
-#define attribute_tls_model_ie __attribute__ ((tls_model ("initial-exec")))
-
 #define attribute_relro __attribute__ ((section (".data.rel.ro")))
 
 
diff --git a/include/netdb.h b/include/netdb.h
index d425a64506..aedc9dfed7 100644
--- a/include/netdb.h
+++ b/include/netdb.h
@@ -11,7 +11,7 @@ 
 #  else
 #   define h_errno __h_errno
 #  endif
-extern __thread int h_errno attribute_tls_model_ie;
+extern __thread int h_errno __attribute_tls_model_ie__;
 # endif /* IS_IN_LIB */
 # define __set_h_errno(x) (h_errno = (x))
 
diff --git a/include/resolv.h b/include/resolv.h
index e8f477cd86..a50ea607ed 100644
--- a/include/resolv.h
+++ b/include/resolv.h
@@ -18,7 +18,7 @@ 
 # if IS_IN (libc)
 #  define __resp __libc_resp
 # endif
-extern __thread struct __res_state *__resp attribute_tls_model_ie;
+extern __thread struct __res_state *__resp __attribute_tls_model_ie__;
 # undef _res
 # define _res (*__resp)
 
diff --git a/locale/localeinfo.h b/locale/localeinfo.h
index f0694dc84e..734c4022cf 100644
--- a/locale/localeinfo.h
+++ b/locale/localeinfo.h
@@ -241,7 +241,7 @@  __libc_tsd_define (extern, __locale_t, LOCALE)
    associated with this category.  */
 #define DEFINE_CATEGORY(category, category_name, items, a) \
 extern __thread struct __locale_data *const *_nl_current_##category \
-  attribute_hidden attribute_tls_model_ie;
+  attribute_hidden __attribute_tls_model_ie__;
 #include "categories.def"
 #undef	DEFINE_CATEGORY
 
diff --git a/malloc/arena.c b/malloc/arena.c
index d49e4a21c8..a38dce578d 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -71,7 +71,7 @@  extern int sanity_check_heap_info_alignment[(sizeof (heap_info)
 
 /* Thread specific data.  */
 
-static __thread mstate thread_arena attribute_tls_model_ie;
+static __thread mstate thread_arena __attribute_tls_model_ie__;
 
 /* Arena free list.  free_list_lock synchronizes access to the
    free_list variable below, and the next_free and attached_threads
diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
index 74f9a49b05..075c996f28 100644
--- a/misc/sys/cdefs.h
+++ b/misc/sys/cdefs.h
@@ -326,6 +326,13 @@ 
 # define __attribute_artificial__ /* Ignore */
 #endif
 
+/* Force use of the initial-exec TLS model.  */
+#if __GNUC_PREREQ (3,3)
+# define __attribute_tls_model_ie__ __attribute__ ((tls_model ("initial-exec")))
+#else
+# define __attribute_tls_model_ie__ /* ignore */
+#endif
+
 /* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99
    inline semantics, unless -fgnu89-inline is used.  Using __GNUC_STDC_INLINE__
    or __GNUC_GNU_INLINE is not a good enough check for gcc because gcc versions
diff --git a/scripts/make-errno-enum.sh b/scripts/make-errno-enum.sh
new file mode 100644
index 0000000000..99a07d3f29
--- /dev/null
+++ b/scripts/make-errno-enum.sh
@@ -0,0 +1,67 @@ 
+#! /bin/sh
+# Script to produce bits/error_t.h.
+
+# Copyright (C) 2017 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+# This script is invoked with no input.
+# AWK and CC are expected to be set in the environment.
+# "$@" is expected to be a sequence of -I switches to pass to the compiler.
+# The generated error_t.h is written to stdout.
+
+set -e
+
+# Note: the steps below that may fail under normal circumstances are
+# carefully arranged to be at the ends of pipelines.
+tmp1=`mktemp -t me1.XXXXXXXXX`
+tmp2=`mktemp -t me2.XXXXXXXXX`
+trap "rm -f '$tmp1' '$tmp2'" 0
+
+printf '#include <features.h>\n#include <bits/errno.h>\n' |
+    "$CC" -E -dM -xc -D_GNU_SOURCE -D_ERRNO_H "$@" - > "$tmp1"
+
+LC_ALL=C sort < "$tmp1" | "$AWK" > "$tmp2" '
+  /^#define E[A-Z0-9]/ {
+    name = $2;
+    printf("\n#ifdef %s\n# pragma push_macro (\"%s\")\n# undef %s\n  %s =\n",
+           name, name, name, name);
+    printf("# pragma pop_macro (\"%s\")\n    %s,\n#endif\n",
+           name, name);
+  }
+'
+
+echo '/* Errno codes as enum constants.'
+echo '   This file was generated by make-errno-enum.sh from bits/errno.h.  */'
+echo
+echo '#ifndef _BITS_ERRNO_ENUM_H'
+echo '#define _BITS_ERRNO_ENUM_H 1'
+echo
+echo '#include <bits/errno.h>'
+echo
+echo 'enum __error_t_codes'
+echo '{'
+echo '  /* Force the enum to be a signed type.  */'
+echo '  __FORCE_ERROR_T_CODES_SIGNED = -1,'
+echo
+echo '  /* Zero indicates success.  Including this entry may prevent'
+echo '     warnings from some compilers if "case 0" appears in a switch'
+echo '     statement over an error_t value.  */'
+echo '  ESUCCESS = 0,'
+cat "$tmp2"
+echo '};'
+echo
+echo '#endif /* bits/errno-enum.h */'
diff --git a/stdlib/Makefile b/stdlib/Makefile
index 9b0acce8cc..770dedfa02 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -25,7 +25,8 @@  include ../Makeconfig
 headers	:= stdlib.h bits/stdlib.h bits/stdlib-ldbl.h bits/stdlib-float.h      \
 	   monetary.h bits/monetary-ldbl.h				      \
 	   inttypes.h stdint.h bits/wordsize.h				      \
-	   errno.h sys/errno.h bits/errno.h				      \
+	   errno.h sys/errno.h bits/errno.h bits/errno-enum.h		      \
+	   bits/types/error_t.h						      \
 	   ucontext.h sys/ucontext.h					      \
 	   alloca.h fmtmsg.h						      \
 	   bits/stdlib-bsearch.h sys/random.h bits/stdint-intn.h	      \
diff --git a/stdlib/bits/types/error_t.h b/stdlib/bits/types/error_t.h
new file mode 100644
index 0000000000..2b6197c84c
--- /dev/null
+++ b/stdlib/bits/types/error_t.h
@@ -0,0 +1,14 @@ 
+#ifndef __error_t_defined
+#define __error_t_defined 1
+
+/* The type error_t, a debugging aid.  With sufficiently new compilers
+   you can type 'p (error_t) errno' in GDB and see the symbolic name
+   of the errno value.  */
+#if __GNUC_PREREQ (4, 5)
+# include <bits/errno-enum.h>
+typedef enum __error_t_codes error_t;
+# else
+typedef int error_t;
+# endif
+
+#endif
diff --git a/stdlib/errno.h b/stdlib/errno.h
index 65f2f4570c..b085891b14 100644
--- a/stdlib/errno.h
+++ b/stdlib/errno.h
@@ -20,53 +20,41 @@ 
  */
 
 #ifndef	_ERRNO_H
+#define _ERRNO_H 1
 
-/* The includer defined __need_Emath if he wants only the definitions
-   of EDOM and ERANGE, and not everything else.  */
-#ifndef	__need_Emath
-# define _ERRNO_H	1
 # include <features.h>
-#endif
+
+/* The system-specific definitions of the E* constants, as macros.  */
+# include <bits/errno.h>
+
+/* When included from assembly language, this header only provides the
+   E* constants.  */
+# ifndef __ASSEMBLER__
 
 __BEGIN_DECLS
 
-/* Get the error number constants from the system-specific file.
-   This file will test __need_Emath and _ERRNO_H.  */
-#include <bits/errno.h>
-#undef	__need_Emath
+/* The error code set by various library functions.  */
+#  if __GLIBC_USE (TLS_ERRNO)
+extern __thread int errno __attribute_tls_model_ie__;
+#   define errno errno
+#  else
+extern int *__errno_location (void) __THROW __attribute_const__;
+#   define errno (*__errno_location ())
+#  endif
 
-#ifdef	_ERRNO_H
+#  ifdef __USE_GNU
 
-/* Declare the `errno' variable, unless it's defined as a macro by
-   bits/errno.h.  This is the case in GNU, where it is a per-thread
-   variable.  This redeclaration using the macro still works, but it
-   will be a function declaration without a prototype and may trigger
-   a -Wstrict-prototypes warning.  */
-#ifndef	errno
-extern int errno;
-#endif
-
-#ifdef __USE_GNU
+#include <bits/types/error_t.h>
 
 /* The full and simple forms of the name with which the program was
    invoked.  These variables are set up automatically at startup based on
    the value of ARGV[0] (this works only if you use GNU ld).  */
-extern char *program_invocation_name, *program_invocation_short_name;
-#endif /* __USE_GNU */
-#endif /* _ERRNO_H */
+extern char *program_invocation_name;
+extern char *program_invocation_short_name;
+
+#  endif /* __USE_GNU */
 
 __END_DECLS
 
-#endif /* _ERRNO_H */
-
-/* The Hurd <bits/errno.h> defines `error_t' as an enumerated type so
-   that printing `error_t' values in the debugger shows the names.  We
-   might need this definition sometimes even if this file was included
-   before.  */
-#if defined __USE_GNU || defined __need_error_t
-# ifndef __error_t_defined
-typedef int error_t;
-#  define __error_t_defined	1
-# endif
-# undef __need_error_t
-#endif
+# endif /* !__ASSEMBLER__ */
+#endif /* errno.h */
diff --git a/string/argz.h b/string/argz.h
index f9d0ac9950..58fcbd04de 100644
--- a/string/argz.h
+++ b/string/argz.h
@@ -20,15 +20,8 @@ 
 #define _ARGZ_H	1
 
 #include <features.h>
-
-#define __need_error_t
-#include <errno.h>
 #include <string.h>		/* Need size_t, and strchr is called below.  */
-
-#ifndef __error_t_defined
-typedef int error_t;
-#endif
-
+#include <bits/types/error_t.h>
 
 __BEGIN_DECLS
 
diff --git a/sunrpc/rpc_thread.c b/sunrpc/rpc_thread.c
index e5225c5caf..e4d96f5bde 100644
--- a/sunrpc/rpc_thread.c
+++ b/sunrpc/rpc_thread.c
@@ -11,7 +11,7 @@ 
 /* Variable used in non-threaded applications or for the first thread.  */
 static struct rpc_thread_variables __libc_tsd_RPC_VARS_mem;
 static __thread struct rpc_thread_variables *thread_rpc_vars
-        attribute_tls_model_ie;
+        __attribute_tls_model_ie__;
 
 /*
  * Task-variable destructor
diff --git a/sysdeps/generic/libc-tsd.h b/sysdeps/generic/libc-tsd.h
index cd04e02050..da19bf0fc8 100644
--- a/sysdeps/generic/libc-tsd.h
+++ b/sysdeps/generic/libc-tsd.h
@@ -51,7 +51,7 @@ 
    translate directly into variables by macro magic.  */
 
 #define __libc_tsd_define(CLASS, TYPE, KEY)	\
-  CLASS __thread TYPE __libc_tsd_##KEY attribute_tls_model_ie;
+  CLASS __thread TYPE __libc_tsd_##KEY __attribute_tls_model_ie__;
 
 #define __libc_tsd_address(TYPE, KEY)		(&__libc_tsd_##KEY)
 #define __libc_tsd_get(TYPE, KEY)		(__libc_tsd_##KEY)
diff --git a/sysdeps/i386/i686/fpu/multiarch/s_cosf-sse2.S b/sysdeps/i386/i686/fpu/multiarch/s_cosf-sse2.S
index f37850d0b3..a5b76e9fb2 100644
--- a/sysdeps/i386/i686/fpu/multiarch/s_cosf-sse2.S
+++ b/sysdeps/i386/i686/fpu/multiarch/s_cosf-sse2.S
@@ -17,8 +17,7 @@ 
    <http://www.gnu.org/licenses/>.  */
 
 #include <sysdep.h>
-#define __need_Emath
-#include <bits/errno.h>
+#include <errno.h>
 
 /* Short algorithm description:
  *
diff --git a/sysdeps/i386/i686/fpu/multiarch/s_sincosf-sse2.S b/sysdeps/i386/i686/fpu/multiarch/s_sincosf-sse2.S
index f31a925522..1e99ee6416 100644
--- a/sysdeps/i386/i686/fpu/multiarch/s_sincosf-sse2.S
+++ b/sysdeps/i386/i686/fpu/multiarch/s_sincosf-sse2.S
@@ -17,8 +17,7 @@ 
    <http://www.gnu.org/licenses/>.  */
 
 #include <sysdep.h>
-#define __need_Emath
-#include <bits/errno.h>
+#include <errno.h>
 
 /* Short algorithm description:
  *
diff --git a/sysdeps/i386/i686/fpu/multiarch/s_sinf-sse2.S b/sysdeps/i386/i686/fpu/multiarch/s_sinf-sse2.S
index ee96018061..03b925491e 100644
--- a/sysdeps/i386/i686/fpu/multiarch/s_sinf-sse2.S
+++ b/sysdeps/i386/i686/fpu/multiarch/s_sinf-sse2.S
@@ -17,8 +17,7 @@ 
    <http://www.gnu.org/licenses/>.  */
 
 #include <sysdep.h>
-#define __need_Emath
-#include <bits/errno.h>
+#include <errno.h>
 
 /* Short algorithm description:
  *
diff --git a/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.c b/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.c
index 49c5c1249b..b08404315b 100644
--- a/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.c
+++ b/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.c
@@ -1,3 +1,3 @@ 
 /* Set temporarily to non-zero if long double should be considered
    the same as double.  */
-__thread int __no_long_double attribute_tls_model_ie attribute_hidden;
+__thread int __no_long_double __attribute_tls_model_ie__ attribute_hidden;
diff --git a/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h b/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h
index af861c11ea..6c54dca0e5 100644
--- a/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h
+++ b/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h
@@ -41,6 +41,7 @@ 
 
 /* Set temporarily to non-zero if long double should be considered
    the same as double.  */
-extern __thread int __no_long_double attribute_tls_model_ie attribute_hidden;
+extern __thread int __no_long_double
+  __attribute_tls_model_ie__ attribute_hidden;
 # define __ldbl_is_dbl __builtin_expect (__no_long_double, 0)
 #endif
diff --git a/sysdeps/mach/hurd/bits/errno.h b/sysdeps/mach/hurd/bits/errno.h
index d20ffe654a..de49025ded 100644
--- a/sysdeps/mach/hurd/bits/errno.h
+++ b/sysdeps/mach/hurd/bits/errno.h
@@ -1,329 +1,196 @@ 
 /* This file generated by errnos.awk.  */
 
-/* The Hurd uses Mach error system 0x10, currently only subsystem 0. */
-#ifndef _HURD_ERRNO
-#define _HURD_ERRNO(n)	((0x10 << 26) | ((n) & 0x3fff))
+#ifndef _BITS_ERRNO_H
+#define _BITS_ERRNO_H 1
+
+#if !defined _ERRNO_H && !defined _BITS_ERRNO_ENUM_H
+#error "Never include <bits/errno.h> directly; use <errno.h> instead."
 #endif
 
-#ifdef _ERRNO_H
+/* The Hurd uses Mach error system 0x10, currently only subsystem 0. */
+#define EPERM                          0x40000001 /* Operation not permitted */
+#define ENOENT                         0x40000002 /* No such file or directory */
+#define ESRCH                          0x40000003 /* No such process */
+#define EINTR                          0x40000004 /* Interrupted system call */
+#define EIO                            0x40000005 /* Input/output error */
+#define ENXIO                          0x40000006 /* No such device or address */
+#define E2BIG                          0x40000007 /* Argument list too long */
+#define ENOEXEC                        0x40000008 /* Exec format error */
+#define EBADF                          0x40000009 /* Bad file descriptor */
+#define ECHILD                         0x4000000a /* No child processes */
+#define EDEADLK                        0x4000000b /* Resource deadlock avoided */
+#define ENOMEM                         0x4000000c /* Cannot allocate memory */
+#define EACCES                         0x4000000d /* Permission denied */
+#define EFAULT                         0x4000000e /* Bad address */
+#define ENOTBLK                        0x4000000f /* Block device required */
+#define EBUSY                          0x40000010 /* Device or resource busy */
+#define EEXIST                         0x40000011 /* File exists */
+#define EXDEV                          0x40000012 /* Invalid cross-device link */
+#define ENODEV                         0x40000013 /* No such device */
+#define ENOTDIR                        0x40000014 /* Not a directory */
+#define EISDIR                         0x40000015 /* Is a directory */
+#define EINVAL                         0x40000016 /* Invalid argument */
+#define EMFILE                         0x40000018 /* Too many open files */
+#define ENFILE                         0x40000017 /* Too many open files in system */
+#define ENOTTY                         0x40000019 /* Inappropriate ioctl for device */
+#define ETXTBSY                        0x4000001a /* Text file busy */
+#define EFBIG                          0x4000001b /* File too large */
+#define ENOSPC                         0x4000001c /* No space left on device */
+#define ESPIPE                         0x4000001d /* Illegal seek */
+#define EROFS                          0x4000001e /* Read-only file system */
+#define EMLINK                         0x4000001f /* Too many links */
+#define EPIPE                          0x40000020 /* Broken pipe */
+#define EDOM                           0x40000021 /* Numerical argument out of domain */
+#define ERANGE                         0x40000022 /* Numerical result out of range */
+#define EAGAIN                         0x40000023 /* Resource temporarily unavailable */
+#define EWOULDBLOCK                    EAGAIN     /* Operation would block */
+#define EINPROGRESS                    0x40000024 /* Operation now in progress */
+#define EALREADY                       0x40000025 /* Operation already in progress */
+#define ENOTSOCK                       0x40000026 /* Socket operation on non-socket */
+#define EMSGSIZE                       0x40000028 /* Message too long */
+#define EPROTOTYPE                     0x40000029 /* Protocol wrong type for socket */
+#define ENOPROTOOPT                    0x4000002a /* Protocol not available */
+#define EPROTONOSUPPORT                0x4000002b /* Protocol not supported */
+#define ESOCKTNOSUPPORT                0x4000002c /* Socket type not supported */
+#define EOPNOTSUPP                     0x4000002d /* Operation not supported */
+#define EPFNOSUPPORT                   0x4000002e /* Protocol family not supported */
+#define EAFNOSUPPORT                   0x4000002f /* Address family not supported by protocol */
+#define EADDRINUSE                     0x40000030 /* Address already in use */
+#define EADDRNOTAVAIL                  0x40000031 /* Cannot assign requested address */
+#define ENETDOWN                       0x40000032 /* Network is down */
+#define ENETUNREACH                    0x40000033 /* Network is unreachable */
+#define ENETRESET                      0x40000034 /* Network dropped connection on reset */
+#define ECONNABORTED                   0x40000035 /* Software caused connection abort */
+#define ECONNRESET                     0x40000036 /* Connection reset by peer */
+#define ENOBUFS                        0x40000037 /* No buffer space available */
+#define EISCONN                        0x40000038 /* Transport endpoint is already connected */
+#define ENOTCONN                       0x40000039 /* Transport endpoint is not connected */
+#define EDESTADDRREQ                   0x40000027 /* Destination address required */
+#define ESHUTDOWN                      0x4000003a /* Cannot send after transport endpoint shutdown */
+#define ETOOMANYREFS                   0x4000003b /* Too many references: cannot splice */
+#define ETIMEDOUT                      0x4000003c /* Connection timed out */
+#define ECONNREFUSED                   0x4000003d /* Connection refused */
+#define ELOOP                          0x4000003e /* Too many levels of symbolic links */
+#define ENAMETOOLONG                   0x4000003f /* File name too long */
+#define EHOSTDOWN                      0x40000040 /* Host is down */
+#define EHOSTUNREACH                   0x40000041 /* No route to host */
+#define ENOTEMPTY                      0x40000042 /* Directory not empty */
+#define EPROCLIM                       0x40000043 /* Too many processes */
+#define EUSERS                         0x40000044 /* Too many users */
+#define EDQUOT                         0x40000045 /* Disk quota exceeded */
+#define ESTALE                         0x40000046 /* Stale file handle */
+#define EREMOTE                        0x40000047 /* Object is remote */
+#define EBADRPC                        0x40000048 /* RPC struct is bad */
+#define ERPCMISMATCH                   0x40000049 /* RPC version wrong */
+#define EPROGUNAVAIL                   0x4000004a /* RPC program not available */
+#define EPROGMISMATCH                  0x4000004b /* RPC program version wrong */
+#define EPROCUNAVAIL                   0x4000004c /* RPC bad procedure for program */
+#define ENOLCK                         0x4000004d /* No locks available */
+#define EFTYPE                         0x4000004f /* Inappropriate file type or format */
+#define EAUTH                          0x40000050 /* Authentication error */
+#define ENEEDAUTH                      0x40000051 /* Need authenticator */
+#define ENOSYS                         0x4000004e /* Function not implemented */
+#define ENOTSUP                        0x40000076 /* Not supported */
+#define EILSEQ                         0x4000006a /* Invalid or incomplete multibyte or wide character */
+#define EBACKGROUND                    0x40000064 /* Inappropriate operation for background process */
+#define EDIED                          0x40000065 /* Translator died */
+#define ED                             0x40000066 /* ? */
+#define EGREGIOUS                      0x40000067 /* You really blew it this time */
+#define EIEIO                          0x40000068 /* Computer bought the farm */
+#define EGRATUITOUS                    0x40000069 /* Gratuitous error */
+#define EBADMSG                        0x4000006b /* Bad message */
+#define EIDRM                          0x4000006c /* Identifier removed */
+#define EMULTIHOP                      0x4000006d /* Multihop attempted */
+#define ENODATA                        0x4000006e /* No data available */
+#define ENOLINK                        0x4000006f /* Link has been severed */
+#define ENOMSG                         0x40000070 /* No message of desired type */
+#define ENOSR                          0x40000071 /* Out of streams resources */
+#define ENOSTR                         0x40000072 /* Device not a stream */
+#define EOVERFLOW                      0x40000073 /* Value too large for defined data type */
+#define EPROTO                         0x40000074 /* Protocol error */
+#define ETIME                          0x40000075 /* Timer expired */
+#define ECANCELED                      0x40000077 /* Operation canceled */
 
-enum __error_t_codes
-{
-	/* The value zero always means success and it is perfectly fine for
-	   code to use 0 explicitly (or implicitly, e.g. via Boolean coercion).
-	   Having an enum entry for zero both makes the debugger print the name
-	   for error_t-typed zero values, and prevents the compiler from
-	   issuing warnings about 'case 0:' in a switch on an error_t-typed
-	   value.  */
-	ESUCCESS = 0,
+/* Errors from <mach/message.h>.  */
+#define EMACH_SEND_IN_PROGRESS         0x10000001
+#define EMACH_SEND_INVALID_DATA        0x10000002
+#define EMACH_SEND_INVALID_DEST        0x10000003
+#define EMACH_SEND_TIMED_OUT           0x10000004
+#define EMACH_SEND_WILL_NOTIFY         0x10000005
+#define EMACH_SEND_NOTIFY_IN_PROGRESS  0x10000006
+#define EMACH_SEND_INTERRUPTED         0x10000007
+#define EMACH_SEND_MSG_TOO_SMALL       0x10000008
+#define EMACH_SEND_INVALID_REPLY       0x10000009
+#define EMACH_SEND_INVALID_RIGHT       0x1000000a
+#define EMACH_SEND_INVALID_NOTIFY      0x1000000b
+#define EMACH_SEND_INVALID_MEMORY      0x1000000c
+#define EMACH_SEND_NO_BUFFER           0x1000000d
+#define EMACH_SEND_NO_NOTIFY           0x1000000e
+#define EMACH_SEND_INVALID_TYPE        0x1000000f
+#define EMACH_SEND_INVALID_HEADER      0x10000010
+#define EMACH_RCV_IN_PROGRESS          0x10004001
+#define EMACH_RCV_INVALID_NAME         0x10004002
+#define EMACH_RCV_TIMED_OUT            0x10004003
+#define EMACH_RCV_TOO_LARGE            0x10004004
+#define EMACH_RCV_INTERRUPTED          0x10004005
+#define EMACH_RCV_PORT_CHANGED         0x10004006
+#define EMACH_RCV_INVALID_NOTIFY       0x10004007
+#define EMACH_RCV_INVALID_DATA         0x10004008
+#define EMACH_RCV_PORT_DIED            0x10004009
+#define EMACH_RCV_IN_SET               0x1000400a
+#define EMACH_RCV_HEADER_ERROR         0x1000400b
+#define EMACH_RCV_BODY_ERROR           0x1000400c
 
-#undef EDOM
-#undef ERANGE
-	EPERM           = _HURD_ERRNO (1),
-#define	EPERM           _HURD_ERRNO (1) /* Operation not permitted */
-	ENOENT          = _HURD_ERRNO (2),
-#define	ENOENT          _HURD_ERRNO (2) /* No such file or directory */
-	ESRCH           = _HURD_ERRNO (3),
-#define	ESRCH           _HURD_ERRNO (3) /* No such process */
-	EINTR           = _HURD_ERRNO (4),
-#define	EINTR           _HURD_ERRNO (4) /* Interrupted system call */
-	EIO             = _HURD_ERRNO (5),
-#define	EIO             _HURD_ERRNO (5) /* Input/output error */
-	ENXIO           = _HURD_ERRNO (6),
-#define	ENXIO           _HURD_ERRNO (6) /* No such device or address */
-	E2BIG           = _HURD_ERRNO (7),
-#define	E2BIG           _HURD_ERRNO (7) /* Argument list too long */
-	ENOEXEC         = _HURD_ERRNO (8),
-#define	ENOEXEC         _HURD_ERRNO (8) /* Exec format error */
-	EBADF           = _HURD_ERRNO (9),
-#define	EBADF           _HURD_ERRNO (9) /* Bad file descriptor */
-	ECHILD          = _HURD_ERRNO (10),
-#define	ECHILD          _HURD_ERRNO (10)/* No child processes */
-	EDEADLK         = _HURD_ERRNO (11),
-#define	EDEADLK         _HURD_ERRNO (11)/* Resource deadlock avoided */
-	ENOMEM          = _HURD_ERRNO (12),
-#define	ENOMEM          _HURD_ERRNO (12)/* Cannot allocate memory */
-	EACCES          = _HURD_ERRNO (13),
-#define	EACCES          _HURD_ERRNO (13)/* Permission denied */
-	EFAULT          = _HURD_ERRNO (14),
-#define	EFAULT          _HURD_ERRNO (14)/* Bad address */
-	ENOTBLK         = _HURD_ERRNO (15),
-#define	ENOTBLK         _HURD_ERRNO (15)/* Block device required */
-	EBUSY           = _HURD_ERRNO (16),
-#define	EBUSY           _HURD_ERRNO (16)/* Device or resource busy */
-	EEXIST          = _HURD_ERRNO (17),
-#define	EEXIST          _HURD_ERRNO (17)/* File exists */
-	EXDEV           = _HURD_ERRNO (18),
-#define	EXDEV           _HURD_ERRNO (18)/* Invalid cross-device link */
-	ENODEV          = _HURD_ERRNO (19),
-#define	ENODEV          _HURD_ERRNO (19)/* No such device */
-	ENOTDIR         = _HURD_ERRNO (20),
-#define	ENOTDIR         _HURD_ERRNO (20)/* Not a directory */
-	EISDIR          = _HURD_ERRNO (21),
-#define	EISDIR          _HURD_ERRNO (21)/* Is a directory */
-	EINVAL          = _HURD_ERRNO (22),
-#define	EINVAL          _HURD_ERRNO (22)/* Invalid argument */
-	EMFILE          = _HURD_ERRNO (24),
-#define	EMFILE          _HURD_ERRNO (24)/* Too many open files */
-	ENFILE          = _HURD_ERRNO (23),
-#define	ENFILE          _HURD_ERRNO (23)/* Too many open files in system */
-	ENOTTY          = _HURD_ERRNO (25),
-#define	ENOTTY          _HURD_ERRNO (25)/* Inappropriate ioctl for device */
-	ETXTBSY         = _HURD_ERRNO (26),
-#define	ETXTBSY         _HURD_ERRNO (26)/* Text file busy */
-	EFBIG           = _HURD_ERRNO (27),
-#define	EFBIG           _HURD_ERRNO (27)/* File too large */
-	ENOSPC          = _HURD_ERRNO (28),
-#define	ENOSPC          _HURD_ERRNO (28)/* No space left on device */
-	ESPIPE          = _HURD_ERRNO (29),
-#define	ESPIPE          _HURD_ERRNO (29)/* Illegal seek */
-	EROFS           = _HURD_ERRNO (30),
-#define	EROFS           _HURD_ERRNO (30)/* Read-only file system */
-	EMLINK          = _HURD_ERRNO (31),
-#define	EMLINK          _HURD_ERRNO (31)/* Too many links */
-	EPIPE           = _HURD_ERRNO (32),
-#define	EPIPE           _HURD_ERRNO (32)/* Broken pipe */
-	EDOM            = _HURD_ERRNO (33),
-#define	EDOM            _HURD_ERRNO (33)/* Numerical argument out of domain */
-	ERANGE          = _HURD_ERRNO (34),
-#define	ERANGE          _HURD_ERRNO (34)/* Numerical result out of range */
-	EAGAIN          = _HURD_ERRNO (35),
-#define	EAGAIN          _HURD_ERRNO (35)/* Resource temporarily unavailable */
-#define EWOULDBLOCK EAGAIN /* Operation would block */
-	EINPROGRESS     = _HURD_ERRNO (36),
-#define	EINPROGRESS     _HURD_ERRNO (36)/* Operation now in progress */
-	EALREADY        = _HURD_ERRNO (37),
-#define	EALREADY        _HURD_ERRNO (37)/* Operation already in progress */
-	ENOTSOCK        = _HURD_ERRNO (38),
-#define	ENOTSOCK        _HURD_ERRNO (38)/* Socket operation on non-socket */
-	EMSGSIZE        = _HURD_ERRNO (40),
-#define	EMSGSIZE        _HURD_ERRNO (40)/* Message too long */
-	EPROTOTYPE      = _HURD_ERRNO (41),
-#define	EPROTOTYPE      _HURD_ERRNO (41)/* Protocol wrong type for socket */
-	ENOPROTOOPT     = _HURD_ERRNO (42),
-#define	ENOPROTOOPT     _HURD_ERRNO (42)/* Protocol not available */
-	EPROTONOSUPPORT = _HURD_ERRNO (43),
-#define	EPROTONOSUPPORT _HURD_ERRNO (43)/* Protocol not supported */
-	ESOCKTNOSUPPORT = _HURD_ERRNO (44),
-#define	ESOCKTNOSUPPORT _HURD_ERRNO (44)/* Socket type not supported */
-	EOPNOTSUPP      = _HURD_ERRNO (45),
-#define	EOPNOTSUPP      _HURD_ERRNO (45)/* Operation not supported */
-	EPFNOSUPPORT    = _HURD_ERRNO (46),
-#define	EPFNOSUPPORT    _HURD_ERRNO (46)/* Protocol family not supported */
-	EAFNOSUPPORT    = _HURD_ERRNO (47),
-#define	EAFNOSUPPORT    _HURD_ERRNO (47)/* Address family not supported by protocol */
-	EADDRINUSE      = _HURD_ERRNO (48),
-#define	EADDRINUSE      _HURD_ERRNO (48)/* Address already in use */
-	EADDRNOTAVAIL   = _HURD_ERRNO (49),
-#define	EADDRNOTAVAIL   _HURD_ERRNO (49)/* Cannot assign requested address */
-	ENETDOWN        = _HURD_ERRNO (50),
-#define	ENETDOWN        _HURD_ERRNO (50)/* Network is down */
-	ENETUNREACH     = _HURD_ERRNO (51),
-#define	ENETUNREACH     _HURD_ERRNO (51)/* Network is unreachable */
-	ENETRESET       = _HURD_ERRNO (52),
-#define	ENETRESET       _HURD_ERRNO (52)/* Network dropped connection on reset */
-	ECONNABORTED    = _HURD_ERRNO (53),
-#define	ECONNABORTED    _HURD_ERRNO (53)/* Software caused connection abort */
-	ECONNRESET      = _HURD_ERRNO (54),
-#define	ECONNRESET      _HURD_ERRNO (54)/* Connection reset by peer */
-	ENOBUFS         = _HURD_ERRNO (55),
-#define	ENOBUFS         _HURD_ERRNO (55)/* No buffer space available */
-	EISCONN         = _HURD_ERRNO (56),
-#define	EISCONN         _HURD_ERRNO (56)/* Transport endpoint is already connected */
-	ENOTCONN        = _HURD_ERRNO (57),
-#define	ENOTCONN        _HURD_ERRNO (57)/* Transport endpoint is not connected */
-	EDESTADDRREQ    = _HURD_ERRNO (39),
-#define	EDESTADDRREQ    _HURD_ERRNO (39)/* Destination address required */
-	ESHUTDOWN       = _HURD_ERRNO (58),
-#define	ESHUTDOWN       _HURD_ERRNO (58)/* Cannot send after transport endpoint shutdown */
-	ETOOMANYREFS    = _HURD_ERRNO (59),
-#define	ETOOMANYREFS    _HURD_ERRNO (59)/* Too many references: cannot splice */
-	ETIMEDOUT       = _HURD_ERRNO (60),
-#define	ETIMEDOUT       _HURD_ERRNO (60)/* Connection timed out */
-	ECONNREFUSED    = _HURD_ERRNO (61),
-#define	ECONNREFUSED    _HURD_ERRNO (61)/* Connection refused */
-	ELOOP           = _HURD_ERRNO (62),
-#define	ELOOP           _HURD_ERRNO (62)/* Too many levels of symbolic links */
-	ENAMETOOLONG    = _HURD_ERRNO (63),
-#define	ENAMETOOLONG    _HURD_ERRNO (63)/* File name too long */
-	EHOSTDOWN       = _HURD_ERRNO (64),
-#define	EHOSTDOWN       _HURD_ERRNO (64)/* Host is down */
-	EHOSTUNREACH    = _HURD_ERRNO (65),
-#define	EHOSTUNREACH    _HURD_ERRNO (65)/* No route to host */
-	ENOTEMPTY       = _HURD_ERRNO (66),
-#define	ENOTEMPTY       _HURD_ERRNO (66)/* Directory not empty */
-	EPROCLIM        = _HURD_ERRNO (67),
-#define	EPROCLIM        _HURD_ERRNO (67)/* Too many processes */
-	EUSERS          = _HURD_ERRNO (68),
-#define	EUSERS          _HURD_ERRNO (68)/* Too many users */
-	EDQUOT          = _HURD_ERRNO (69),
-#define	EDQUOT          _HURD_ERRNO (69)/* Disk quota exceeded */
-	ESTALE          = _HURD_ERRNO (70),
-#define	ESTALE          _HURD_ERRNO (70)/* Stale file handle */
-	EREMOTE         = _HURD_ERRNO (71),
-#define	EREMOTE         _HURD_ERRNO (71)/* Object is remote */
-	EBADRPC         = _HURD_ERRNO (72),
-#define	EBADRPC         _HURD_ERRNO (72)/* RPC struct is bad */
-	ERPCMISMATCH    = _HURD_ERRNO (73),
-#define	ERPCMISMATCH    _HURD_ERRNO (73)/* RPC version wrong */
-	EPROGUNAVAIL    = _HURD_ERRNO (74),
-#define	EPROGUNAVAIL    _HURD_ERRNO (74)/* RPC program not available */
-	EPROGMISMATCH   = _HURD_ERRNO (75),
-#define	EPROGMISMATCH   _HURD_ERRNO (75)/* RPC program version wrong */
-	EPROCUNAVAIL    = _HURD_ERRNO (76),
-#define	EPROCUNAVAIL    _HURD_ERRNO (76)/* RPC bad procedure for program */
-	ENOLCK          = _HURD_ERRNO (77),
-#define	ENOLCK          _HURD_ERRNO (77)/* No locks available */
-	EFTYPE          = _HURD_ERRNO (79),
-#define	EFTYPE          _HURD_ERRNO (79)/* Inappropriate file type or format */
-	EAUTH           = _HURD_ERRNO (80),
-#define	EAUTH           _HURD_ERRNO (80)/* Authentication error */
-	ENEEDAUTH       = _HURD_ERRNO (81),
-#define	ENEEDAUTH       _HURD_ERRNO (81)/* Need authenticator */
-	ENOSYS          = _HURD_ERRNO (78),
-#define	ENOSYS          _HURD_ERRNO (78)/* Function not implemented */
-	ENOTSUP         = _HURD_ERRNO (118),
-#define	ENOTSUP         _HURD_ERRNO (118)/* Not supported */
-	EILSEQ          = _HURD_ERRNO (106),
-#define	EILSEQ          _HURD_ERRNO (106)/* Invalid or incomplete multibyte or wide character */
-	EBACKGROUND     = _HURD_ERRNO (100),
-#define	EBACKGROUND     _HURD_ERRNO (100)/* Inappropriate operation for background process */
-	EDIED           = _HURD_ERRNO (101),
-#define	EDIED           _HURD_ERRNO (101)/* Translator died */
-	ED              = _HURD_ERRNO (102),
-#define	ED              _HURD_ERRNO (102)/* ? */
-	EGREGIOUS       = _HURD_ERRNO (103),
-#define	EGREGIOUS       _HURD_ERRNO (103)/* You really blew it this time */
-	EIEIO           = _HURD_ERRNO (104),
-#define	EIEIO           _HURD_ERRNO (104)/* Computer bought the farm */
-	EGRATUITOUS     = _HURD_ERRNO (105),
-#define	EGRATUITOUS     _HURD_ERRNO (105)/* Gratuitous error */
-	EBADMSG         = _HURD_ERRNO (107),
-#define	EBADMSG         _HURD_ERRNO (107)/* Bad message */
-	EIDRM           = _HURD_ERRNO (108),
-#define	EIDRM           _HURD_ERRNO (108)/* Identifier removed */
-	EMULTIHOP       = _HURD_ERRNO (109),
-#define	EMULTIHOP       _HURD_ERRNO (109)/* Multihop attempted */
-	ENODATA         = _HURD_ERRNO (110),
-#define	ENODATA         _HURD_ERRNO (110)/* No data available */
-	ENOLINK         = _HURD_ERRNO (111),
-#define	ENOLINK         _HURD_ERRNO (111)/* Link has been severed */
-	ENOMSG          = _HURD_ERRNO (112),
-#define	ENOMSG          _HURD_ERRNO (112)/* No message of desired type */
-	ENOSR           = _HURD_ERRNO (113),
-#define	ENOSR           _HURD_ERRNO (113)/* Out of streams resources */
-	ENOSTR          = _HURD_ERRNO (114),
-#define	ENOSTR          _HURD_ERRNO (114)/* Device not a stream */
-	EOVERFLOW       = _HURD_ERRNO (115),
-#define	EOVERFLOW       _HURD_ERRNO (115)/* Value too large for defined data type */
-	EPROTO          = _HURD_ERRNO (116),
-#define	EPROTO          _HURD_ERRNO (116)/* Protocol error */
-	ETIME           = _HURD_ERRNO (117),
-#define	ETIME           _HURD_ERRNO (117)/* Timer expired */
-	ECANCELED       = _HURD_ERRNO (119),
-#define	ECANCELED       _HURD_ERRNO (119)/* Operation canceled */
+/* Errors from <mach/kern_return.h>.  */
+#define EKERN_INVALID_ADDRESS          1
+#define EKERN_PROTECTION_FAILURE       2
+#define EKERN_NO_SPACE                 3
+#define EKERN_INVALID_ARGUMENT         4
+#define EKERN_FAILURE                  5
+#define EKERN_RESOURCE_SHORTAGE        6
+#define EKERN_NOT_RECEIVER             7
+#define EKERN_NO_ACCESS                8
+#define EKERN_MEMORY_FAILURE           9
+#define EKERN_MEMORY_ERROR             10
+#define EKERN_NOT_IN_SET               12
+#define EKERN_NAME_EXISTS              13
+#define EKERN_ABORTED                  14
+#define EKERN_INVALID_NAME             15
+#define EKERN_INVALID_TASK             16
+#define EKERN_INVALID_RIGHT            17
+#define EKERN_INVALID_VALUE            18
+#define EKERN_UREFS_OVERFLOW           19
+#define EKERN_INVALID_CAPABILITY       20
+#define EKERN_RIGHT_EXISTS             21
+#define EKERN_INVALID_HOST             22
+#define EKERN_MEMORY_PRESENT           23
+#define EKERN_WRITE_PROTECTION_FAILURE 24
+#define EKERN_TERMINATED               26
 
-	/* Errors from <mach/message.h>.  */
-	EMACH_SEND_IN_PROGRESS          = 0x10000001,
-	EMACH_SEND_INVALID_DATA         = 0x10000002,
-	EMACH_SEND_INVALID_DEST         = 0x10000003,
-	EMACH_SEND_TIMED_OUT            = 0x10000004,
-	EMACH_SEND_WILL_NOTIFY          = 0x10000005,
-	EMACH_SEND_NOTIFY_IN_PROGRESS   = 0x10000006,
-	EMACH_SEND_INTERRUPTED          = 0x10000007,
-	EMACH_SEND_MSG_TOO_SMALL        = 0x10000008,
-	EMACH_SEND_INVALID_REPLY        = 0x10000009,
-	EMACH_SEND_INVALID_RIGHT        = 0x1000000a,
-	EMACH_SEND_INVALID_NOTIFY       = 0x1000000b,
-	EMACH_SEND_INVALID_MEMORY       = 0x1000000c,
-	EMACH_SEND_NO_BUFFER            = 0x1000000d,
-	EMACH_SEND_NO_NOTIFY            = 0x1000000e,
-	EMACH_SEND_INVALID_TYPE         = 0x1000000f,
-	EMACH_SEND_INVALID_HEADER       = 0x10000010,
-	EMACH_RCV_IN_PROGRESS           = 0x10004001,
-	EMACH_RCV_INVALID_NAME          = 0x10004002,
-	EMACH_RCV_TIMED_OUT             = 0x10004003,
-	EMACH_RCV_TOO_LARGE             = 0x10004004,
-	EMACH_RCV_INTERRUPTED           = 0x10004005,
-	EMACH_RCV_PORT_CHANGED          = 0x10004006,
-	EMACH_RCV_INVALID_NOTIFY        = 0x10004007,
-	EMACH_RCV_INVALID_DATA          = 0x10004008,
-	EMACH_RCV_PORT_DIED             = 0x10004009,
-	EMACH_RCV_IN_SET                = 0x1000400a,
-	EMACH_RCV_HEADER_ERROR          = 0x1000400b,
-	EMACH_RCV_BODY_ERROR            = 0x1000400c,
+/* Errors from <mach/mig_errors.h>.  */
+#define EMIG_TYPE_ERROR                (-300) /* client type check failure */
+#define EMIG_REPLY_MISMATCH            (-301) /* wrong reply message ID */
+#define EMIG_REMOTE_ERROR              (-302) /* server detected error */
+#define EMIG_BAD_ID                    (-303) /* bad request message ID */
+#define EMIG_BAD_ARGUMENTS             (-304) /* server type check failure */
+#define EMIG_NO_REPLY                  (-305) /* no reply should be sent */
+#define EMIG_EXCEPTION                 (-306) /* server raised exception */
+#define EMIG_ARRAY_TOO_LARGE           (-307) /* array not large enough */
+#define EMIG_SERVER_DIED               (-308) /* server died */
+#define EMIG_DESTROY_REQUEST           (-309) /* destroy request with no reply */
 
-	/* Errors from <mach/kern_return.h>.  */
-	EKERN_INVALID_ADDRESS           = 1,
-	EKERN_PROTECTION_FAILURE        = 2,
-	EKERN_NO_SPACE                  = 3,
-	EKERN_INVALID_ARGUMENT          = 4,
-	EKERN_FAILURE                   = 5,
-	EKERN_RESOURCE_SHORTAGE         = 6,
-	EKERN_NOT_RECEIVER              = 7,
-	EKERN_NO_ACCESS                 = 8,
-	EKERN_MEMORY_FAILURE            = 9,
-	EKERN_MEMORY_ERROR              = 10,
-	EKERN_NOT_IN_SET                = 12,
-	EKERN_NAME_EXISTS               = 13,
-	EKERN_ABORTED                   = 14,
-	EKERN_INVALID_NAME              = 15,
-	EKERN_INVALID_TASK              = 16,
-	EKERN_INVALID_RIGHT             = 17,
-	EKERN_INVALID_VALUE             = 18,
-	EKERN_UREFS_OVERFLOW            = 19,
-	EKERN_INVALID_CAPABILITY        = 20,
-	EKERN_RIGHT_EXISTS              = 21,
-	EKERN_INVALID_HOST              = 22,
-	EKERN_MEMORY_PRESENT            = 23,
-	EKERN_WRITE_PROTECTION_FAILURE  = 24,
-	EKERN_TERMINATED                = 26,
-
-	/* Errors from <mach/mig_errors.h>.  */
-	EMIG_TYPE_ERROR         = -300  /* client type check failure */,
-	EMIG_REPLY_MISMATCH     = -301  /* wrong reply message ID */,
-	EMIG_REMOTE_ERROR       = -302  /* server detected error */,
-	EMIG_BAD_ID             = -303  /* bad request message ID */,
-	EMIG_BAD_ARGUMENTS      = -304  /* server type check failure */,
-	EMIG_NO_REPLY           = -305  /* no reply should be sent */,
-	EMIG_EXCEPTION          = -306  /* server raised exception */,
-	EMIG_ARRAY_TOO_LARGE    = -307  /* array not large enough */,
-	EMIG_SERVER_DIED        = -308  /* server died */,
-	EMIG_DESTROY_REQUEST    = -309  /* destroy request with no reply */,
-
-	/* Errors from <device/device_types.h>.  */
-	ED_IO_ERROR             = 2500  /* hardware IO error */,
-	ED_WOULD_BLOCK          = 2501  /* would block, but D_NOWAIT set */,
-	ED_NO_SUCH_DEVICE       = 2502  /* no such device */,
-	ED_ALREADY_OPEN         = 2503  /* exclusive-use device already open */,
-	ED_DEVICE_DOWN          = 2504  /* device has been shut down */,
-	ED_INVALID_OPERATION    = 2505  /* bad operation for device */,
-	ED_INVALID_RECNUM       = 2506  /* invalid record (block) number */,
-	ED_INVALID_SIZE         = 2507  /* invalid IO size */,
-	ED_NO_MEMORY            = 2508  /* memory allocation failure */,
-	ED_READ_ONLY            = 2509  /* device cannot be written to */
-
-};
+/* Errors from <device/device_types.h>.  */
+#define ED_IO_ERROR                      2500 /* hardware IO error */
+#define ED_WOULD_BLOCK                   2501 /* would block, but D_NOWAIT set */
+#define ED_NO_SUCH_DEVICE                2502 /* no such device */
+#define ED_ALREADY_OPEN                  2503 /* exclusive-use device already open */
+#define ED_DEVICE_DOWN                   2504 /* device has been shut down */
+#define ED_INVALID_OPERATION             2505 /* bad operation for device */
+#define ED_INVALID_RECNUM                2506 /* invalid record (block) number */
+#define ED_INVALID_SIZE                  2507 /* invalid IO size */
+#define ED_NO_MEMORY                     2508 /* memory allocation failure */
+#define ED_READ_ONLY                     2509 /* device cannot be written to */
 
 #define	_HURD_ERRNOS	120
 
-/* User-visible type of error codes.  It is ok to use `int' or
-   `kern_return_t' for these, but with `error_t' the debugger prints
-   symbolic values.  */
-#ifdef __USE_GNU
-typedef enum __error_t_codes error_t;
-#define __error_t_defined	1
-#endif
-
-/* Return the current thread's location for `errno'.
-   The syntax of this function allows redeclarations like `int errno'.  */
-extern int *__errno_location (void) __THROW __attribute__ ((__const__));
-
-#define errno			(*__errno_location ())
-
-#endif /* <errno.h> included.  */
-
-#if !defined (_ERRNO_H) && defined (__need_Emath)
-#define	EDOM            _HURD_ERRNO (33)/* Numerical argument out of domain */
-#define	ERANGE          _HURD_ERRNO (34)/* Numerical result out of range */
-#endif /* <errno.h> not included and need math error codes.  */
+#endif /* bits/errno.h.  */
diff --git a/sysdeps/mach/hurd/errnos.awk b/sysdeps/mach/hurd/errnos.awk
index a20815fa17..ed6dfc9b54 100644
--- a/sysdeps/mach/hurd/errnos.awk
+++ b/sysdeps/mach/hurd/errnos.awk
@@ -24,27 +24,18 @@ 
 BEGIN {
     print "/* This file generated by errnos.awk.  */";
     print "";
-    print "/* The Hurd uses Mach error system 0x10, currently only subsystem 0. */";
-    print "#ifndef _HURD_ERRNO";
-    print "#define _HURD_ERRNO(n)\t((0x10 << 26) | ((n) & 0x3fff))";
+    print "#ifndef _BITS_ERRNO_H";
+    print "#define _BITS_ERRNO_H 1";
+    print "";
+    print "#if !defined _ERRNO_H && !defined _BITS_ERRNO_ENUM_H";
+    print "#error \"Never include <bits/errno.h> directly; use <errno.h> instead.\"";
     print "#endif";
     print "";
-    print "#ifdef _ERRNO_H\n";
-    print "enum __error_t_codes\n{";
-    print "\t/* The value zero always means success and it is perfectly fine for";
-    print "\t   code to use 0 explicitly (or implicitly, e.g. via Boolean coercion).";
-    print "\t   Having an enum entry for zero both makes the debugger print the name";
-    print "\t   for error_t-typed zero values, and prevents the compiler from";
-    print "\t   issuing warnings about 'case 0:' in a switch on an error_t-typed";
-    print "\t   value.  */";
-    print "\tESUCCESS = 0,"
-    print "";
+    print "/* The Hurd uses Mach error system 0x10, currently only subsystem 0. */";
     errnoh = 0;
     maxerrno = 0;
     in_mach_errors = "";
     in_math = 0;
-    edom = erange = "";
-    print "#undef EDOM\n#undef ERANGE";
     lno = 0;
   }
 
@@ -64,23 +55,21 @@  errnoh == 2 && $1 == "@deftypevr"  && $2 == "Macro" && $3 == "int" \
 errnoh == 3 && $1 == "@comment" && $2 == "errno" {
     if (e == "EWOULDBLOCK")
       {
-	lines[lno++]="#define EWOULDBLOCK EAGAIN /* Operation would block */";
+        printf ("#define %-30s %-10s /* Operation would block */\n",
+                "EWOULDBLOCK", "EAGAIN");
 	next;
       }
     errno = $3 + 0;
     if (errno == 0)
       next;
+    if (errno > 0x3fff) {
+      printf("%s:%d: errno value %d too large for the Hurd\n",
+             FILENAME, NR, errno) >> "/dev/stderr";
+      exit 1;
+    }
     if (errno > maxerrno) maxerrno = errno;
-    x = sprintf ("%-40s/*%s */", sprintf ("%-24s%s", "#define\t" e,
-					  "_HURD_ERRNO (" errno ")"),
-		 etext);
-    if (e == "EDOM")
-      edom = x;
-    else if (e == "ERANGE")
-      erange = x;
-    comma[lno] = 1;
-    lines[lno++] = sprintf("\t%-16s= _HURD_ERRNO (%d)", e, errno);
-    lines[lno++] = x;
+    printf ("#define %-30s 0x%08x /*%s */\n",
+            e, 0x40000000 + errno, etext);
     next;
   }
 { errnoh=0 }
@@ -88,12 +77,12 @@  errnoh == 3 && $1 == "@comment" && $2 == "errno" {
 NF == 3 && $1 == "#define" && $2 == "MACH_SEND_IN_PROGRESS" \
   {
     in_mach_errors = FILENAME;
-    lines[lno++] = "\n\t/* Errors from <mach/message.h>.  */";
+    print "\n/* Errors from <mach/message.h>.  */";
   }
 NF == 3 && $1 == "#define" && $2 == "KERN_SUCCESS" \
   {
     in_mach_errors = FILENAME;
-    lines[lno++] = "\n\t/* Errors from <mach/kern_return.h>.  */";
+    print "\n/* Errors from <mach/kern_return.h>.  */";
     next;
   }
 
@@ -104,14 +93,13 @@  in_mach_errors != "" && $2 == "MACH_IPC_COMPAT" \
 
 in_mach_errors == FILENAME && NF == 3 && $1 == "#define" \
   {
-    comma[lno] = 1;
-    lines[lno++] = sprintf("\t%-32s= %s", "E" $2, $3);
+    printf("#define %-30s %s\n", "E" $2, $3);
   }
 
 $1 == "#define" && $2 == "_MACH_MIG_ERRORS_H_" \
   {
     in_mig_errors = 1;
-    lines[lno++] = "\n\t/* Errors from <mach/mig_errors.h>.  */";
+    print "\n/* Errors from <mach/mig_errors.h>.  */";
     next;
   }
 in_mig_errors && $1 == "#endif" && $3 == "_MACH_MIG_ERRORS_H_" \
@@ -125,14 +113,17 @@  in_mig_errors && $1 == "#endif" && $3 == "_MACH_MIG_ERRORS_H_" \
     comment = "";
     for (i = 4; i <= NF; ++i)
       comment = comment " " $i;
-    comma[lno] = 1;
-    lines[lno++] = sprintf("%-32s", sprintf ("\t%-24s= %s", "E" $2, $3)) comment;
+    if ($3 < 0)
+        val = "(" $3 ")";
+    else
+        val = $3;
+    printf("#define %-30s %6s%s\n", "E" $2, val, comment);
   }
 
 $1 == "#define" && $2 == "D_SUCCESS" \
   {
     in_device_errors = 1;
-    lines[lno++] = "\n\t/* Errors from <device/device_types.h>.  */";
+    print "\n/* Errors from <device/device_types.h>.  */";
     next;
   }
 in_device_errors && $1 == "#endif" \
@@ -141,35 +132,9 @@  in_device_errors && $1 == "#endif" \
   }
 
 
-END \
-  {
-    for (i = 0; i < lno - 1; ++i)
-      printf "%s%s\n", lines[i], (comma[i] ? "," : "");
-    print lines[i];
-    print "";
-    print "};";
+END {
     print "";
     printf "#define\t_HURD_ERRNOS\t%d\n", maxerrno+1;
     print "";
-    print "\
-/* User-visible type of error codes.  It is ok to use `int' or\n\
-   `kern_return_t' for these, but with `error_t' the debugger prints\n\
-   symbolic values.  */";
-    print "#ifdef __USE_GNU";
-    print "typedef enum __error_t_codes error_t;"
-    print "#define __error_t_defined\t1"
-    print "#endif";
-    print "";
-    print "\
-/* Return the current thread's location for `errno'.\n\
-   The syntax of this function allows redeclarations like `int errno'.  */\n\
-extern int *__errno_location (void) __THROW __attribute__ ((__const__));\n\
-\n\
-#define errno			(*__errno_location ())\n\
-";
-    print "#endif /* <errno.h> included.  */";
-    print "";
-    print "#if !defined (_ERRNO_H) && defined (__need_Emath)";
-    print edom; print erange;
-    print "#endif /* <errno.h> not included and need math error codes.  */";
+    print "#endif /* bits/errno.h.  */";
   }
diff --git a/sysdeps/nacl/errnos.awk b/sysdeps/nacl/errnos.awk
index 926d595a73..bab8588ed7 100644
--- a/sysdeps/nacl/errnos.awk
+++ b/sysdeps/nacl/errnos.awk
@@ -59,19 +59,12 @@  END {
   print "\
 /* This file generated by errnos.awk.  */\n\
 \n\
-#if !defined __Emath_defined && (defined _ERRNO_H || defined __need_Emath)\n\
-#undef	__need_Emath\n\
-#define	__Emath_defined	1";
-  emath["EDOM"] = emath["EILSEQ"] = emath["ERANGE"] = 1;
-  for (ename in emath) {
-    errno = errnos_by_name[ename];
-    define_errno(errno, ename);
-    delete errnos[errno];
-  }
-  print "\
-#endif\n\
+#ifndef _BITS_ERRNO_H\n\
+#define _BITS_ERRNO_H 1\n\
 \n\
-#ifdef _ERRNO_H\n";
+#if !defined _ERRNO_H && !defined _BITS_ERRNO_ENUM_H\n\
+#error \"Never include <bits/errno.h> directly; use <errno.h> instead.\"\n\
+#endif\n"
 
   for (i = 1; i <= maxerrno; ++i)
     if (i in errnos) define_errno(i, errnos[i]);
@@ -80,8 +73,8 @@  END {
 #define	EWOULDBLOCK	EAGAIN\n\
 #define	ENOTSUP		EOPNOTSUPP\n\
 \n\
-extern __thread int errno __attribute__ ((__tls_model__ (\"initial-exec\")));\n\
-#define errno errno\n\
+#undef __USE_TLS_ERRNO\n\
+#define __USE_TLS_ERRNO 1\n\
 \n\
-#endif";
+#endif /* bits/errno.h.  */";
 }
diff --git a/sysdeps/powerpc/nofpu/soft-supp.h b/sysdeps/powerpc/nofpu/soft-supp.h
index f66d9573fa..e329f43d16 100644
--- a/sysdeps/powerpc/nofpu/soft-supp.h
+++ b/sysdeps/powerpc/nofpu/soft-supp.h
@@ -33,12 +33,12 @@  typedef union
 
 #endif
 
-extern __thread int __sim_exceptions_thread attribute_tls_model_ie;
+extern __thread int __sim_exceptions_thread __attribute_tls_model_ie__;
 libc_hidden_tls_proto (__sim_exceptions_thread, tls_model ("initial-exec"));
-extern __thread int __sim_disabled_exceptions_thread attribute_tls_model_ie;
+extern __thread int __sim_disabled_exceptions_thread __attribute_tls_model_ie__;
 libc_hidden_tls_proto (__sim_disabled_exceptions_thread,
 		       tls_model ("initial-exec"));
-extern __thread int __sim_round_mode_thread attribute_tls_model_ie;
+extern __thread int __sim_round_mode_thread __attribute_tls_model_ie__;
 libc_hidden_tls_proto (__sim_round_mode_thread, tls_model ("initial-exec"));
 
 /* These variables were formerly global, so there are compat symbols
diff --git a/sysdeps/powerpc/soft-fp/sfp-machine.h b/sysdeps/powerpc/soft-fp/sfp-machine.h
index d92a90e3e2..1ff116ad41 100644
--- a/sysdeps/powerpc/soft-fp/sfp-machine.h
+++ b/sysdeps/powerpc/soft-fp/sfp-machine.h
@@ -103,12 +103,12 @@  libc_hidden_proto (__feraiseexcept_soft)
 
 #endif
 
-extern __thread int __sim_exceptions_thread attribute_tls_model_ie;
+extern __thread int __sim_exceptions_thread __attribute_tls_model_ie__;
 libc_hidden_tls_proto (__sim_exceptions_thread, tls_model ("initial-exec"));
-extern __thread int __sim_disabled_exceptions_thread attribute_tls_model_ie;
+extern __thread int __sim_disabled_exceptions_thread __attribute_tls_model_ie__;
 libc_hidden_tls_proto (__sim_disabled_exceptions_thread,
 		       tls_model ("initial-exec"));
-extern __thread int __sim_round_mode_thread attribute_tls_model_ie;
+extern __thread int __sim_round_mode_thread __attribute_tls_model_ie__;
 libc_hidden_tls_proto (__sim_round_mode_thread, tls_model ("initial-exec"));
 
 extern void __simulate_exceptions (int x) attribute_hidden;
diff --git a/sysdeps/unix/sysv/linux/alpha/bits/errno.h b/sysdeps/unix/sysv/linux/alpha/bits/errno.h
index 3338621710..bcab228eda 100644
--- a/sysdeps/unix/sysv/linux/alpha/bits/errno.h
+++ b/sysdeps/unix/sysv/linux/alpha/bits/errno.h
@@ -16,23 +16,29 @@ 
    License along with the GNU C Library.  If not, see
    <http://www.gnu.org/licenses/>.  */
 
-#ifdef _ERRNO_H
+#ifndef _BITS_ERRNO_H
+#define _BITS_ERRNO_H 1
+
+#if !defined _ERRNO_H && !defined _BITS_ERRNO_ENUM_H
+#error "Never include <bits/errno.h> directly; use <errno.h> instead."
+#endif
 
-# undef EDOM
-# undef EILSEQ
-# undef ERANGE
 # include <linux/errno.h>
 
-/* Linux has no ENOTSUP error code.  */
-# define ENOTSUP EOPNOTSUPP
-
-# ifndef ECANCELED
-#  define ECANCELED	131
+/* Older Linux headers do not define these constants.  */
+# ifndef ENOTSUP
+#  define ENOTSUP		EOPNOTSUPP
+# endif
+
+# ifndef ECANCELED
+#  define ECANCELED		131
 # endif
 
-/* Support for error codes to support robust mutexes was added later, too.  */
 # ifndef EOWNERDEAD
 #  define EOWNERDEAD		136
+# endif
+
+# ifndef ENOTRECOVERABLE
 #  define ENOTRECOVERABLE	137
 # endif
 
@@ -44,22 +50,4 @@ 
 #  define EHWPOISON		139
 # endif
 
-# ifndef __ASSEMBLER__
-/* Function to get address of global `errno' variable.  */
-extern int *__errno_location (void) __THROW __attribute__ ((__const__));
-
-#  if !defined _LIBC || defined _LIBC_REENTRANT
-/* When using threads, errno is a per-thread value.  */
-#   define errno (*__errno_location ())
-#  endif
-# endif /* !__ASSEMBLER__ */
-#endif /* _ERRNO_H */
-
-#if !defined _ERRNO_H && defined __need_Emath
-/* This is ugly but the kernel header is not clean enough.  We must
-   define only the values EDOM, EILSEQ and ERANGE in case __need_Emath is
-   defined.  */
-# define EDOM	33	/* Math argument out of domain of function.  */
-# define EILSEQ	116	/* Illegal byte sequence.  */
-# define ERANGE	34	/* Math result not representable.  */
-#endif /* !_ERRNO_H && __need_Emath */
+#endif /* bits/errno.h.  */
diff --git a/sysdeps/unix/sysv/linux/bits/errno.h b/sysdeps/unix/sysv/linux/bits/errno.h
index c0f4d20fe7..38019b76be 100644
--- a/sysdeps/unix/sysv/linux/bits/errno.h
+++ b/sysdeps/unix/sysv/linux/bits/errno.h
@@ -16,24 +16,29 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#ifdef _ERRNO_H
+#ifndef _BITS_ERRNO_H
+#define _BITS_ERRNO_H 1
+
+#if !defined _ERRNO_H && !defined _BITS_ERRNO_ENUM_H
+#error "Never include <bits/errno.h> directly; use <errno.h> instead."
+#endif
 
-# undef EDOM
-# undef EILSEQ
-# undef ERANGE
 # include <linux/errno.h>
 
-/* Linux has no ENOTSUP error code.  */
-# define ENOTSUP EOPNOTSUPP
-
-/* Older Linux versions also had no ECANCELED error code.  */
-# ifndef ECANCELED
-#  define ECANCELED	125
+/* Older Linux headers do not define these constants.  */
+# ifndef ENOTSUP
+#  define ENOTSUP		EOPNOTSUPP
+# endif
+
+# ifndef ECANCELED
+#  define ECANCELED		125
 # endif
 
-/* Support for error codes to support robust mutexes was added later, too.  */
 # ifndef EOWNERDEAD
 #  define EOWNERDEAD		130
+# endif
+
+#ifndef ENOTRECOVERABLE
 #  define ENOTRECOVERABLE	131
 # endif
 
@@ -45,22 +50,4 @@ 
 #  define EHWPOISON		133
 # endif
 
-# ifndef __ASSEMBLER__
-/* Function to get address of global `errno' variable.  */
-extern int *__errno_location (void) __THROW __attribute__ ((__const__));
-
-#  if !defined _LIBC || defined _LIBC_REENTRANT
-/* When using threads, errno is a per-thread value.  */
-#   define errno (*__errno_location ())
-#  endif
-# endif /* !__ASSEMBLER__ */
-#endif /* _ERRNO_H */
-
-#if !defined _ERRNO_H && defined __need_Emath
-/* This is ugly but the kernel header is not clean enough.  We must
-   define only the values EDOM, EILSEQ and ERANGE in case __need_Emath is
-   defined.  */
-# define EDOM	33	/* Math argument out of domain of function.  */
-# define EILSEQ	84	/* Illegal byte sequence.  */
-# define ERANGE	34	/* Math result not representable.  */
-#endif /* !_ERRNO_H && __need_Emath */
+#endif /* bits/errno.h.  */
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/errno.h b/sysdeps/unix/sysv/linux/hppa/bits/errno.h
index ce6bebe8b0..241b6966a8 100644
--- a/sysdeps/unix/sysv/linux/hppa/bits/errno.h
+++ b/sysdeps/unix/sysv/linux/hppa/bits/errno.h
@@ -16,17 +16,22 @@ 
    License along with the GNU C Library.  If not, see
    <http://www.gnu.org/licenses/>.  */
 
-#ifdef _ERRNO_H
+#ifndef _BITS_ERRNO_H
+#define _BITS_ERRNO_H 1
+
+#if !defined _ERRNO_H && !defined _BITS_ERRNO_ENUM_H
+#error "Never include <bits/errno.h> directly; use <errno.h> instead."
+#endif
 
-# undef EDOM
-# undef EILSEQ
-# undef ERANGE
 # include <linux/errno.h>
 
-/* Linux also has no ECANCELED error code.  Since it is not used here
-   we define it to an invalid value.  */
+/* Older Linux headers do not define these constants.  */
+# ifndef ENOTSUP
+#  define ENOTSUP		EOPNOTSUPP
+# endif
+
 # ifndef ECANCELED
-#  define ECANCELED	ECANCELLED
+#  define ECANCELED		253
 # endif
 
 # ifndef EOWNERDEAD
@@ -45,22 +50,4 @@ 
 #  define EHWPOISON		257
 # endif
 
-# ifndef __ASSEMBLER__
-/* Function to get address of global `errno' variable.  */
-extern int *__errno_location (void) __THROW __attribute__ ((__const__));
-
-#  if !defined _LIBC || defined _LIBC_REENTRANT
-/* When using threads, errno is a per-thread value.  */
-#   define errno (*__errno_location ())
-#  endif
-# endif /* !__ASSEMBLER__ */
-#endif /* _ERRNO_H */
-
-#if !defined _ERRNO_H && defined __need_Emath
-/* This is ugly but the kernel header is not clean enough.  We must
-   define only the values EDOM, EILSEQ and ERANGE in case __need_Emath is
-   defined.  */
-# define EDOM	33	/* Math argument out of domain of function.  */
-# define EILSEQ	47	/* Illegal byte sequence.  */
-# define ERANGE	34	/* Math result not representable.  */
-#endif /* !_ERRNO_H && __need_Emath */
+#endif /* bits/errno.h.  */
diff --git a/sysdeps/unix/sysv/linux/mips/bits/errno.h b/sysdeps/unix/sysv/linux/mips/bits/errno.h
index fa62e1fc83..55df83d038 100644
--- a/sysdeps/unix/sysv/linux/mips/bits/errno.h
+++ b/sysdeps/unix/sysv/linux/mips/bits/errno.h
@@ -16,23 +16,28 @@ 
    License along with the GNU C Library.  If not, see
    <http://www.gnu.org/licenses/>.  */
 
-#ifdef _ERRNO_H
+#ifndef _BITS_ERRNO_H
+
+#if !defined _ERRNO_H && !defined _BITS_ERRNO_ENUM_H
+#error "Never include <bits/errno.h> directly; use <errno.h> instead."
+#endif
 
-# undef EDOM
-# undef EILSEQ
-# undef ERANGE
 # include <linux/errno.h>
 
-/* Linux has no ENOTSUP error code.  */
-# define ENOTSUP EOPNOTSUPP
-
-# ifndef ECANCELED
-#  define ECANCELED	158
+/* Older Linux headers do not define these constants.  */
+# ifndef ENOTSUP
+#  define ENOTSUP		EOPNOTSUPP
+# endif
+
+# ifndef ECANCELED
+#  define ECANCELED		158
 # endif
 
-/* Support for error codes to support robust mutexes was added later, too.  */
 # ifndef EOWNERDEAD
 #  define EOWNERDEAD		165
+# endif
+
+# ifndef ENOTRECOVERABLE
 #  define ENOTRECOVERABLE	166
 # endif
 
@@ -44,22 +49,4 @@ 
 #  define EHWPOISON		168
 # endif
 
-# ifndef __ASSEMBLER__
-/* Function to get address of global `errno' variable.  */
-extern int *__errno_location (void) __THROW __attribute__ ((__const__));
-
-#  if !defined _LIBC || defined _LIBC_REENTRANT
-/* When using threads, errno is a per-thread value.  */
-#   define errno (*__errno_location ())
-#  endif
-# endif /* !__ASSEMBLER__ */
-#endif /* _ERRNO_H */
-
-#if !defined _ERRNO_H && defined __need_Emath
-/* This is ugly but the kernel header is not clean enough.  We must
-   define only the values EDOM, EILSEQ and ERANGE in case __need_Emath is
-   defined.  */
-# define EDOM	33	/* Math argument out of domain of function.  */
-# define EILSEQ	88	/* Illegal byte sequence.  */
-# define ERANGE	34	/* Math result not representable.  */
-#endif /* !_ERRNO_H && __need_Emath */
+#endif /* bits/errno.h.  */
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/errno.h b/sysdeps/unix/sysv/linux/sparc/bits/errno.h
index 4a8d8a0879..9e13e663af 100644
--- a/sysdeps/unix/sysv/linux/sparc/bits/errno.h
+++ b/sysdeps/unix/sysv/linux/sparc/bits/errno.h
@@ -16,23 +16,29 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#ifdef _ERRNO_H
+#ifndef _BITS_ERRNO_H
+#define _BITS_ERRNO_H 1
+
+#if !defined _ERRNO_H && !defined _BITS_ERRNO_ENUM_H
+#error "Never include <bits/errno.h> directly; use <errno.h> instead."
+#endif
 
-# undef EDOM
-# undef EILSEQ
-# undef ERANGE
 # include <linux/errno.h>
 
-/* Linux has no ENOTSUP error code.  */
-# define ENOTSUP EOPNOTSUPP
-
-# ifndef ECANCELED
-#  define ECANCELED	127
+/* Older Linux headers do not define these constants.  */
+# ifndef ENOTSUP
+#  define ENOTSUP		EOPNOTSUPP
+# endif
+
+# ifndef ECANCELED
+#  define ECANCELED		127
 # endif
 
-/* Support for error codes to support robust mutexes was added later, too.  */
 # ifndef EOWNERDEAD
 #  define EOWNERDEAD		132
+# endif
+
+# ifndef ENOTRECOVERABLE
 #  define ENOTRECOVERABLE	133
 # endif
 
@@ -44,22 +50,4 @@ 
 #  define EHWPOISON		135
 # endif
 
-# ifndef __ASSEMBLER__
-/* Function to get address of global `errno' variable.  */
-extern int *__errno_location (void) __THROW __attribute__ ((__const__));
-
-#  if !defined _LIBC || defined _LIBC_REENTRANT
-/* When using threads, errno is a per-thread value.  */
-#   define errno (*__errno_location ())
-#  endif
-# endif /* !__ASSEMBLER__ */
-#endif /* _ERRNO_H */
-
-#if !defined _ERRNO_H && defined __need_Emath
-/* This is ugly but the kernel header is not clean enough.  We must
-   define only the values EDOM, EILSEQ and ERANGE in case __need_Emath is
-   defined.  */
-# define EDOM	33	/* Math argument out of domain of function.  */
-# define EILSEQ	122	/* Illegal byte sequence.  */
-# define ERANGE	34	/* Math result not representable.  */
-#endif /* !_ERRNO_H && __need_Emath */
+#endif /* bits/errno.h.  */
diff --git a/sysdeps/x86_64/fpu/s_cosf.S b/sysdeps/x86_64/fpu/s_cosf.S
index e9fdc7e56e..7acafcd1be 100644
--- a/sysdeps/x86_64/fpu/s_cosf.S
+++ b/sysdeps/x86_64/fpu/s_cosf.S
@@ -17,8 +17,7 @@ 
    <http://www.gnu.org/licenses/>.  */
 
 #include <sysdep.h>
-#define __need_Emath
-#include <bits/errno.h>
+#include <errno.h>
 
 /* Short algorithm description:
  *
diff --git a/sysdeps/x86_64/fpu/s_sincosf.S b/sysdeps/x86_64/fpu/s_sincosf.S
index e6ed81ed91..fd35a3153b 100644
--- a/sysdeps/x86_64/fpu/s_sincosf.S
+++ b/sysdeps/x86_64/fpu/s_sincosf.S
@@ -17,8 +17,7 @@ 
    <http://www.gnu.org/licenses/>.  */
 
 #include <sysdep.h>
-#define __need_Emath
-#include <bits/errno.h>
+#include <errno.h>
 
 /* Short algorithm description:
  *
diff --git a/sysdeps/x86_64/fpu/s_sinf.S b/sysdeps/x86_64/fpu/s_sinf.S
index 0aa5d43d8c..253ba7d6f0 100644
--- a/sysdeps/x86_64/fpu/s_sinf.S
+++ b/sysdeps/x86_64/fpu/s_sinf.S
@@ -17,8 +17,7 @@ 
    <http://www.gnu.org/licenses/>.  */
 
 #include <sysdep.h>
-#define __need_Emath
-#include <bits/errno.h>
+#include <errno.h>
 
 /* Short algorithm description:
  *