<bits/syscall.h>: Use an arch-independent system call list on Linux

Submitted by Florian Weimer on April 5, 2017, 7:40 p.m.

Details

Message ID 088c5f84-0665-4a49-6d2a-fe3402a227b4@redhat.com
State New
Headers show

Commit Message

Florian Weimer April 5, 2017, 7:40 p.m.
Downstream, we have the problem that we need to deliver our glibc 
packages before the kernel team finishes backporting system calls.  This 
means that the final glibc build before a release does not contain all 
the SYS_* macros supported by the kernel headers.

I would have liked to address this by phasing out the SYS_* macros, but 
this suggestion was not received favorably during a previous discussion.

An ideal solution would generate the SYS_* macros when the glibc 
development package is installed, based on the already-installed kernel 
headers.  Our RPM version does not support delayed script execution, so 
there is significant risk that we end up with a dependency loop, due to 
which the generation step could fail.

So I'm proposing the attached patch as an alternative.  It uses a list 
of system call names and generates a <bits/syscall.h> file from that 
which has items of the form

#ifdef __NR_write
# define SYS_write __NR_write
#endif

The idea is to define only those SYS_ macros which actually exist in the 
kernel headers as __NR_ macros.  Therefore, we only need a single system 
call list across all architectures, and the generated header file is no 
longer architecture-specific, either.  The -dM-based macro extraction 
remains as a (much simplified) test case.  It fails if the kernel 
headers contain __NR_ macros not currently listed in the glibc source tree.

I think the increased predictability of glibc builds might be worth it 
upstream as well.  The cost is that we now have to update the list 
periodically, but that can be done when the kernel version embedded in 
scripts/build-many-glibcs.py is increased.

The included list of system call names is based on the currently 
building build-many-glibcs.py targets (that is, hppa and coldfire are 
missing).  We can easily adjust it once we get more buildable architectures.

Comments?

Thanks,
Florian

Comments

Andreas Schwab April 6, 2017, 8 a.m.
On Apr 05 2017, Florian Weimer <fweimer@redhat.com> wrote:

> Downstream, we have the problem that we need to deliver our glibc packages
> before the kernel team finishes backporting system calls.  This means that
> the final glibc build before a release does not contain all the SYS_*
> macros supported by the kernel headers.

Why can't you just patch the kernel headers package?  With the uapi
separation the kernel headers are pretty much independent of the kernel.

Andreas.
Florian Weimer April 6, 2017, 8:52 a.m.
On 04/06/2017 10:00 AM, Andreas Schwab wrote:
> On Apr 05 2017, Florian Weimer <fweimer@redhat.com> wrote:
>
>> Downstream, we have the problem that we need to deliver our glibc packages
>> before the kernel team finishes backporting system calls.  This means that
>> the final glibc build before a release does not contain all the SYS_*
>> macros supported by the kernel headers.
>
> Why can't you just patch the kernel headers package?

Wasn't this rejected on this list because that would lead to a namespace 
violation?

> With the uapi
> separation the kernel headers are pretty much independent of the kernel.

The system call list is generated in an architecture-specific manner.  I 
looked into this, most architectures use some construct which is rather 
impenetrable.  It's also very brittle in the sense that you can easily 
change the userspace ABI by accident, and nothing in the kernel build 
will tell you that you just did.  It's also unclear how to convince 
kernel maintainers to accept such a change (and think you'll have to 
convince each architecture maintainer).

If the SYS_ macros come from the kernel side, we'd need some sort of 
two-way handshake anyway (glibc tells the kernel that it's prepared to 
accept SYS_ macros, the kernel tells glibc it has defined SYS_ macros, 
and which point glibc does not do its own thing with the SYS_ macros). 
So an incremental conversion looks possible.

I think that if we really need both sets of macros, the __NR_ and SYS_ 
macros should come from the same source.  But that seems to be difficult 
to achieve.

Thanks,
Florian
Andreas Schwab April 6, 2017, 9:03 a.m.
On Apr 06 2017, Florian Weimer <fweimer@redhat.com> wrote:

> On 04/06/2017 10:00 AM, Andreas Schwab wrote:
>> On Apr 05 2017, Florian Weimer <fweimer@redhat.com> wrote:
>>
>>> Downstream, we have the problem that we need to deliver our glibc packages
>>> before the kernel team finishes backporting system calls.  This means that
>>> the final glibc build before a release does not contain all the SYS_*
>>> macros supported by the kernel headers.
>>
>> Why can't you just patch the kernel headers package?
>
> Wasn't this rejected on this list because that would lead to a namespace
> violation?

I don't understand.  The kernel uapi headers fully respect namespace,
at least those used by glibc.

> The system call list is generated in an architecture-specific manner.

Sure, but the commits that add the syscalls are easily separable.  All
you need is to update the files underneath asm/unistd.h, which are
pretty regular.

> I looked into this, most architectures use some construct which is
> rather impenetrable.  It's also very brittle in the sense that you can
> easily change the userspace ABI by accident, and nothing in the kernel
> build will tell you that you just did.

You only need to patch the kernel headers package, which is hopefully
separate from the kernel.

Andreas.
Florian Weimer April 6, 2017, 9:47 a.m.
On 04/06/2017 11:03 AM, Andreas Schwab wrote:
> On Apr 06 2017, Florian Weimer <fweimer@redhat.com> wrote:
>
>> On 04/06/2017 10:00 AM, Andreas Schwab wrote:
>>> On Apr 05 2017, Florian Weimer <fweimer@redhat.com> wrote:
>>>
>>>> Downstream, we have the problem that we need to deliver our glibc packages
>>>> before the kernel team finishes backporting system calls.  This means that
>>>> the final glibc build before a release does not contain all the SYS_*
>>>> macros supported by the kernel headers.
>>>
>>> Why can't you just patch the kernel headers package?
>>
>> Wasn't this rejected on this list because that would lead to a namespace
>> violation?
>
> I don't understand.  The kernel uapi headers fully respect namespace,
> at least those used by glibc.

I think the argument was that __NR_* should come from the kernel, and 
SYS_* should come from glibc, and that the kernel has no business 
defining SYS_* macros, purely based on namespace concerns.

>> The system call list is generated in an architecture-specific manner.
>
> Sure, but the commits that add the syscalls are easily separable.  All
> you need is to update the files underneath asm/unistd.h, which are
> pretty regular.

Not sure if we are talking about the same thing.  Our kernel-headers 
package comes from the kernel sources, 3.10 era.  Maybe you have 
frozen/explicit <asm/unistd.h> header in the sources.  We don't, we only 
have what upstream offers, which is … quite dynamic and heavily 
automated on some architectures.

>> I looked into this, most architectures use some construct which is
>> rather impenetrable.  It's also very brittle in the sense that you can
>> easily change the userspace ABI by accident, and nothing in the kernel
>> build will tell you that you just did.
>
> You only need to patch the kernel headers package, which is hopefully
> separate from the kernel.

Well, I see how this can simplify things.  This is not the case for us. 
I don't know the rationale behind the tight integration with the kernel 
package.  I'll ask around.

Anyway, I think for those who don't have separately maintained uapi 
headers (because they are building from upstream kernel sources), I 
think the relaxing of the build order requirement my proposed patch 
provides is still valuable.

Thanks,
Florian
Andreas Schwab April 6, 2017, 10:07 a.m.
On Apr 06 2017, Florian Weimer <fweimer@redhat.com> wrote:

> I think the argument was that __NR_* should come from the kernel, and
> SYS_* should come from glibc, and that the kernel has no business defining
> SYS_* macros, purely based on namespace concerns.

I don't know why you are talking about SYS_.  All that the kernel
defines are __NR_.  The SYS_ defines are pure glibc stuff.

> Not sure if we are talking about the same thing.  Our kernel-headers
> package comes from the kernel sources, 3.10 era.

Consider splitting it out, they are really independent.  Then you can
update the kernel headers without touching the kernel.

Andreas.
Florian Weimer April 6, 2017, 10:12 a.m.
On 04/06/2017 12:07 PM, Andreas Schwab wrote:
> On Apr 06 2017, Florian Weimer <fweimer@redhat.com> wrote:
>
>> I think the argument was that __NR_* should come from the kernel, and
>> SYS_* should come from glibc, and that the kernel has no business defining
>> SYS_* macros, purely based on namespace concerns.
>
> I don't know why you are talking about SYS_.  All that the kernel
> defines are __NR_.  The SYS_ defines are pure glibc stuff.

The separation is what causes problems because there is no way to tell 
the C preprocessor to export all __NR_* macros as SYS_* macros, too.

As a result, current glibc has this elaborate dance at built where it 
runs “gcc -E -dM” (with varying additional parameters to get the 
lib/libx32/lib64 variants).  I want to get rid of that because it means 
that if you upgrade the kernel headers after building glibc, the SYS_* 
and __NR_* macros drift apart.

>> Not sure if we are talking about the same thing.  Our kernel-headers
>> package comes from the kernel sources, 3.10 era.
>
> Consider splitting it out, they are really independent.  Then you can
> update the kernel headers without touching the kernel.

But I'd still have the issue that the kernel headers contain only the 
__NR_* macros, not the SYS_* macros.

If you think that SYS_* macros should remain glibc business, then I 
think the patch I posted is the right approach to simplify independent 
kernel header updates (whether they come from a separate package, or 
directly from the upstream sources).

Thanks,
Florian
Andreas Schwab April 6, 2017, 12:29 p.m.
On Apr 06 2017, Florian Weimer <fweimer@redhat.com> wrote:

> As a result, current glibc has this elaborate dance at built where it runs
> “gcc -E -dM” (with varying additional parameters to get the
> lib/libx32/lib64 variants).  I want to get rid of that because it means
> that if you upgrade the kernel headers after building glibc, the SYS_* and
> __NR_* macros drift apart.

You have to rebuild glibc anyway if new syscalls come along, so there
isn't much difference.

Andreas.
Florian Weimer April 6, 2017, 12:32 p.m.
On 04/06/2017 02:29 PM, Andreas Schwab wrote:
> On Apr 06 2017, Florian Weimer <fweimer@redhat.com> wrote:
>
>> As a result, current glibc has this elaborate dance at built where it runs
>> “gcc -E -dM” (with varying additional parameters to get the
>> lib/libx32/lib64 variants).  I want to get rid of that because it means
>> that if you upgrade the kernel headers after building glibc, the SYS_* and
>> __NR_* macros drift apart.
>
> You have to rebuild glibc anyway if new syscalls come along, so there
> isn't much difference.

Yes, but if glibc carries an explicit list, we can schedule the glibc 
rebuild before the kernel build.  If we do that with a recent enough 
upstream kernel, we do not even need to know at that point which system 
calls will actually backported.  The required SYS_* macros will simply 
appear if the kernel headers add the __NR_* macro.

Thanks,
Florian
Andreas Schwab April 6, 2017, 12:49 p.m.
On Apr 06 2017, Florian Weimer <fweimer@redhat.com> wrote:

> Yes, but if glibc carries an explicit list, we can schedule the glibc
> rebuild before the kernel build.

You can do the same with an updated kernel headers package.

Andreas.
Florian Weimer April 6, 2017, 1:24 p.m.
On 04/06/2017 02:49 PM, Andreas Schwab wrote:
> On Apr 06 2017, Florian Weimer <fweimer@redhat.com> wrote:
>
>> Yes, but if glibc carries an explicit list, we can schedule the glibc
>> rebuild before the kernel build.
>
> You can do the same with an updated kernel headers package.

But the uapi kernel headers aren't separate upstream, and until they 
are, the proposed new approach to SYS_* generation may be superior.

Unless everyone else but us generates their own separate kernel-headers 
package, that is. :-/

Thanks,
Florian
Andreas Schwab April 6, 2017, 1:44 p.m.
On Apr 06 2017, Florian Weimer <fweimer@redhat.com> wrote:

> But the uapi kernel headers aren't separate upstream, and until they are,
> the proposed new approach to SYS_* generation may be superior.
>
> Unless everyone else but us generates their own separate kernel-headers
> package, that is. :-/

Here is a script that does that.  It basically just runs make
headers_install_all, and the result is put in a tarball.

https://build.opensuse.org/package/view_file/Base:System/linux-glibc-devel/install_all.sh?expand=1

Andreas.
Florian Weimer April 6, 2017, 2:22 p.m.
On 04/06/2017 03:44 PM, Andreas Schwab wrote:
> On Apr 06 2017, Florian Weimer <fweimer@redhat.com> wrote:
>
>> But the uapi kernel headers aren't separate upstream, and until they are,
>> the proposed new approach to SYS_* generation may be superior.
>>
>> Unless everyone else but us generates their own separate kernel-headers
>> package, that is. :-/
>
> Here is a script that does that.  It basically just runs make
> headers_install_all, and the result is put in a tarball.
>
> https://build.opensuse.org/package/view_file/Base:System/linux-glibc-devel/install_all.sh?expand=1

Thanks, I will take that under consideration.

Further comments from anyone else?

Florian
Dmitry V. Levin April 6, 2017, 2:37 p.m.
On Thu, Apr 06, 2017 at 04:22:40PM +0200, Florian Weimer wrote:
> On 04/06/2017 03:44 PM, Andreas Schwab wrote:
> > On Apr 06 2017, Florian Weimer <fweimer@redhat.com> wrote:
> >
> >> But the uapi kernel headers aren't separate upstream, and until they are,
> >> the proposed new approach to SYS_* generation may be superior.
> >>
> >> Unless everyone else but us generates their own separate kernel-headers
> >> package, that is. :-/
> >
> > Here is a script that does that.  It basically just runs make
> > headers_install_all, and the result is put in a tarball.
> >
> > https://build.opensuse.org/package/view_file/Base:System/linux-glibc-devel/install_all.sh?expand=1
> 
> Thanks, I will take that under consideration.
> 
> Further comments from anyone else?

We also build kernel headers separately from the kernel, see
http://git.altlinux.org/gears/g/..git?p=glibc-kernheaders.git;a=blob;f=glibc-kernheaders.spec
Florian Weimer April 21, 2017, 10:06 a.m.
On 04/06/2017 04:37 PM, Dmitry V. Levin wrote:
> On Thu, Apr 06, 2017 at 04:22:40PM +0200, Florian Weimer wrote:
>> On 04/06/2017 03:44 PM, Andreas Schwab wrote:
>>> On Apr 06 2017, Florian Weimer <fweimer@redhat.com> wrote:
>>>
>>>> But the uapi kernel headers aren't separate upstream, and until they are,
>>>> the proposed new approach to SYS_* generation may be superior.
>>>>
>>>> Unless everyone else but us generates their own separate kernel-headers
>>>> package, that is. :-/
>>>
>>> Here is a script that does that.  It basically just runs make
>>> headers_install_all, and the result is put in a tarball.
>>>
>>> https://build.opensuse.org/package/view_file/Base:System/linux-glibc-devel/install_all.sh?expand=1
>>
>> Thanks, I will take that under consideration.
>>
>> Further comments from anyone else?
> 
> We also build kernel headers separately from the kernel, see
> http://git.altlinux.org/gears/g/..git?p=glibc-kernheaders.git;a=blob;f=glibc-kernheaders.spec

Do you (and other distributions) build applications against these 
headers as well, or are those only used for building glibc itself?

Thanks,
Florian
Andreas Schwab April 21, 2017, 12:26 p.m.
On Apr 21 2017, Florian Weimer <fweimer@redhat.com> wrote:

> Do you (and other distributions) build applications against these headers
> as well, or are those only used for building glibc itself?

These are the kernel UAPI headers, so of course they are used by
everything.

Andreas.
Florian Weimer April 21, 2017, 12:37 p.m.
On 04/21/2017 02:26 PM, Andreas Schwab wrote:
> On Apr 21 2017, Florian Weimer <fweimer@redhat.com> wrote:
> 
>> Do you (and other distributions) build applications against these headers
>> as well, or are those only used for building glibc itself?
> 
> These are the kernel UAPI headers, so of course they are used by
> everything.

Do you rebase the UAPI headers to the latest kernel release even after a 
release of the distribution, as part of regular maintenance?

If not, how do you get SYS_ macros for the system calls you backport 
into your stable kernel?

Thanks,
Florian
Carlos O'Donell April 21, 2017, 3:16 p.m.
On 04/21/2017 08:26 AM, Andreas Schwab wrote:
> On Apr 21 2017, Florian Weimer <fweimer@redhat.com> wrote:
> 
>> Do you (and other distributions) build applications against these headers
>> as well, or are those only used for building glibc itself?
> 
> These are the kernel UAPI headers, so of course they are used by
> everything.

TLDR; This introduces changes which can break developer applications,
and the only benefit is to glibc.

The benefit to rebasing the kernel UAPI headers is that glibc will have 
an accurate list of SYS_ macros.

The disbenefit of the new kernel UAPI headers package is that application 
developers building applications must bear potentially new integration 
costs and header conflicts with their own headers (assume glibc does 
better header inclusion testing, and I have some patches for that).

My opinion is that the upstream kernel UAPI headers continue to change
without good management of the changes. I have seen at least 3 changes
which break header inclusion ordering and that would have caused application
build problems. None of the authors of those changes came to talk to us
about adding the right guards in glibc to prevent breakage. Worse there
have been discussions about deleting existing guards, that change would
break header inclusion order in one of the two directions, just to 
simplify libc-compat.h in the kernel (avoiding needing any libc-specific
knowledge). This does not seem conservative enough to me.

Are these problems passed on for the users to fix in those distributions
that track upstream kernel headers?

In the future I will continue to build my own builds with kernel master to
try catch all such changes, and add more tests to glibc to catch them too.
Andreas Schwab April 21, 2017, 6:02 p.m.
On Apr 21 2017, Carlos O'Donell <carlos@redhat.com> wrote:

> TLDR; This introduces changes which can break developer applications,
> and the only benefit is to glibc.

I don't understand.  You cannot build anything without the kernel UAPI
headers.

Andreas.
Florian Weimer April 21, 2017, 6:46 p.m.
* Andreas Schwab:

> On Apr 21 2017, Carlos O'Donell <carlos@redhat.com> wrote:
>
>> TLDR; This introduces changes which can break developer applications,
>> and the only benefit is to glibc.
>
> I don't understand.  You cannot build anything without the kernel UAPI
> headers.

I think we have to freeze the kernel headers along a distribution
release branch, and update them only insofar we backport things to
this distribution release branch.

My proposal aims to avoid a build order depedency between the
backports landing in the distribution kernel, and a glibc rebuild.
For point releases, glibc and kernel may be developed on different
schedules, and if the glibc build uses my proposed patch, it can use
the upstream system call list as a superset of what's going to be
backportable for the next point release.
Andreas Schwab April 21, 2017, 7:07 p.m.
On Apr 21 2017, Florian Weimer <fw@deneb.enyo.de> wrote:

> My proposal aims to avoid a build order depedency between the
> backports landing in the distribution kernel, and a glibc rebuild.

What do you gain over a UAPI headers update in line with the glibc
rebuild?

Andreas.
Florian Weimer April 21, 2017, 7:15 p.m.
* Andreas Schwab:

> On Apr 21 2017, Florian Weimer <fw@deneb.enyo.de> wrote:
>
>> My proposal aims to avoid a build order depedency between the
>> backports landing in the distribution kernel, and a glibc rebuild.
>
> What do you gain over a UAPI headers update in line with the glibc
> rebuild?

We don't have to maintain a kernel package ourselves, or align our
delivery schedule with the kernel team.
Andreas Schwab April 21, 2017, 7:34 p.m.
On Apr 21 2017, Florian Weimer <fw@deneb.enyo.de> wrote:

> * Andreas Schwab:
>
>> On Apr 21 2017, Florian Weimer <fw@deneb.enyo.de> wrote:
>>
>>> My proposal aims to avoid a build order depedency between the
>>> backports landing in the distribution kernel, and a glibc rebuild.
>>
>> What do you gain over a UAPI headers update in line with the glibc
>> rebuild?
>
> We don't have to maintain a kernel package ourselves, or align our
> delivery schedule with the kernel team.

The kernel UAPI package is independent of the kernel.

Andreas.
Florian Weimer April 21, 2017, 7:37 p.m.
* Andreas Schwab:

> On Apr 21 2017, Florian Weimer <fw@deneb.enyo.de> wrote:
>
>> * Andreas Schwab:
>>
>>> On Apr 21 2017, Florian Weimer <fw@deneb.enyo.de> wrote:
>>>
>>>> My proposal aims to avoid a build order depedency between the
>>>> backports landing in the distribution kernel, and a glibc rebuild.
>>>
>>> What do you gain over a UAPI headers update in line with the glibc
>>> rebuild?
>>
>> We don't have to maintain a kernel package ourselves, or align our
>> delivery schedule with the kernel team.
>
> The kernel UAPI package is independent of the kernel.

Well, yes, but that's another kernel package to maintain.

And we don't want to push an UAPI headers update in a point release,
so we wouldn't want to replace the other UAPI header package anyway.
The latter would still be used to build applications.
Andreas Schwab April 21, 2017, 7:40 p.m.
On Apr 21 2017, Florian Weimer <fw@deneb.enyo.de> wrote:

> And we don't want to push an UAPI headers update in a point release,
> so we wouldn't want to replace the other UAPI header package anyway.

Don't do that then.

Andreas.
Florian Weimer April 21, 2017, 7:57 p.m.
* Andreas Schwab:

> On Apr 21 2017, Florian Weimer <fw@deneb.enyo.de> wrote:
>
>> And we don't want to push an UAPI headers update in a point release,
>> so we wouldn't want to replace the other UAPI header package anyway.
>
> Don't do that then.

What do you propose, then?  Build a custom UAPI header package with
the most recent upstream system call list, but otherwise with the
contents for the kernel version for the distribution release branch?

The downside is that you get SYS_ macros for system calls which are
not implemented in the distribution kernel.  (Quite a few, arguably
broken, applications use #ifdefs instead of run-time checking.)
Andreas Schwab April 22, 2017, 9:38 a.m.
On Apr 21 2017, Florian Weimer <fw@deneb.enyo.de> wrote:

> The downside is that you get SYS_ macros for system calls which are
> not implemented in the distribution kernel. 

I don't understand.  Didn't you say the system call has been backported?

Andreas.
Florian Weimer April 22, 2017, 11:59 a.m.
* Andreas Schwab:

> On Apr 21 2017, Florian Weimer <fw@deneb.enyo.de> wrote:
>
>> The downside is that you get SYS_ macros for system calls which are
>> not implemented in the distribution kernel. 
>
> I don't understand.  Didn't you say the system call has been backported?

Yes, we seem to have a misunderstanding.  If I understand you, you say
some distributions are doing this on a stable branch:

  * Backport a system call to the actual kernel package.
  * Backport the system call addition to the kernel headers package.
    (changing the UAPI headers used by glibc and applications).
  * Rebuild glibc to generate the SYS_ macro list.

This does not work for some distributions because the order is like
this:

  * Rebuild glibc for a point release.
  * Backport a system call to the actual kernel package.
 (* Backport the system call addition to the kernel headers package.)

Whether the last step happens or not is immaterial in this context.
You won't get the SYS_ macro with this build order.

What could work is this:

 (* Backport system calls to the kernel package.)
  * Rebase the kernel headers package to the latest upstream version
    (changing the UAPI headers used by glibc and applications).
 (* Backport more system calls to the kernel package.)
  * Rebuild glibc to generate SYS_ macro list.
 (* Backport even more system calls to the kernel package.)

This way, the glibc build would provide a full SYS_ macro list,
assuming that the kernel backporting does not overtake upstream (which
seems unlikely).  However, some of the SYS_ macros will not work
because the distribution kernel will lake the correspondign __NR_
macros.
Andreas Schwab April 22, 2017, 1:45 p.m.
On Apr 22 2017, Florian Weimer <fw@deneb.enyo.de> wrote:

> This does not work for some distributions because the order is like
> this:
>
>   * Rebuild glibc for a point release.
>   * Backport a system call to the actual kernel package.
>  (* Backport the system call addition to the kernel headers package.)
>
> Whether the last step happens or not is immaterial in this context.
> You won't get the SYS_ macro with this build order.

Which your patch won't rectify.

> What could work is this:
>
>  (* Backport system calls to the kernel package.)
>   * Rebase the kernel headers package to the latest upstream version
>     (changing the UAPI headers used by glibc and applications).
>  (* Backport more system calls to the kernel package.)
>   * Rebuild glibc to generate SYS_ macro list.
>  (* Backport even more system calls to the kernel package.)
>
> This way, the glibc build would provide a full SYS_ macro list,
> assuming that the kernel backporting does not overtake upstream (which
> seems unlikely).  However, some of the SYS_ macros will not work
> because the distribution kernel will lake the correspondign __NR_
> macros.

In which way does the macro not work?

Andreas.
Florian Weimer April 22, 2017, 2:22 p.m.
* Andreas Schwab:

> On Apr 22 2017, Florian Weimer <fw@deneb.enyo.de> wrote:
>
>> This does not work for some distributions because the order is like
>> this:
>>
>>   * Rebuild glibc for a point release.
>>   * Backport a system call to the actual kernel package.
>>  (* Backport the system call addition to the kernel headers package.)
>>
>> Whether the last step happens or not is immaterial in this context.
>> You won't get the SYS_ macro with this build order.
>
> Which your patch won't rectify.

It does, if we pick up the upstream (rc) system call list at the time
we build glibc for the point release.  At that point, we have all
potential system calls to backport.

>> What could work is this:
>>
>>  (* Backport system calls to the kernel package.)
>>   * Rebase the kernel headers package to the latest upstream version
>>     (changing the UAPI headers used by glibc and applications).
>>  (* Backport more system calls to the kernel package.)
>>   * Rebuild glibc to generate SYS_ macro list.
>>  (* Backport even more system calls to the kernel package.)
>>
>> This way, the glibc build would provide a full SYS_ macro list,
>> assuming that the kernel backporting does not overtake upstream (which
>> seems unlikely).  However, some of the SYS_ macros will not work
>> because the distribution kernel will lake the correspondign __NR_
>> macros.
>
> In which way does the macro not work?

I was mistaken.  As described, it will work.  But if we only backport
the the system call additions to the UAPI headers used by the
applications, this

#ifdef SYS_getrandom
  return syscall (SYS_getrandom, buf, len, 0);
#else
  errno = ENOSYS;
  return -1;
#endif

could fail with an error that __NR_getrandom is undefined.

I was confused because I find the notion to rebase to the upstream
kernel headers in a point release a bit preposterous.
Andreas Schwab April 22, 2017, 3:08 p.m.
On Apr 22 2017, Florian Weimer <fw@deneb.enyo.de> wrote:

> I was mistaken.  As described, it will work.  But if we only backport
> the the system call additions to the UAPI headers used by the
> applications, this
>
> #ifdef SYS_getrandom
>   return syscall (SYS_getrandom, buf, len, 0);
> #else
>   errno = ENOSYS;
>   return -1;
> #endif
>
> could fail with an error that __NR_getrandom is undefined.

Why?  That's defined by the UAPI headers.

Andreas.
Florian Weimer April 22, 2017, 3:27 p.m.
* Andreas Schwab:

> On Apr 22 2017, Florian Weimer <fw@deneb.enyo.de> wrote:
>
>> I was mistaken.  As described, it will work.  But if we only backport
>> the the system call additions to the UAPI headers used by the
>> applications, this
>>
>> #ifdef SYS_getrandom
>>   return syscall (SYS_getrandom, buf, len, 0);
>> #else
>>   errno = ENOSYS;
>>   return -1;
>> #endif
>>
>> could fail with an error that __NR_getrandom is undefined.
>
> Why?  That's defined by the UAPI headers.

I meant: If we do not rebase the UAPI headers (but backport changes as
needed), while still building glibc against the current upstream
headers (to get a complete SYS_ macro list before the backporting
happens).
Andreas Schwab April 22, 2017, 3:37 p.m.
On Apr 22 2017, Florian Weimer <fw@deneb.enyo.de> wrote:

> I meant: If we do not rebase the UAPI headers (but backport changes as
> needed), while still building glibc against the current upstream
> headers (to get a complete SYS_ macro list before the backporting
> happens).

Why would you want to build a package against something that isn't part
of the distribution?

Andreas.
Florian Weimer April 22, 2017, 3:51 p.m.
* Andreas Schwab:

> On Apr 22 2017, Florian Weimer <fw@deneb.enyo.de> wrote:
>
>> I meant: If we do not rebase the UAPI headers (but backport changes as
>> needed), while still building glibc against the current upstream
>> headers (to get a complete SYS_ macro list before the backporting
>> happens).
>
> Why would you want to build a package against something that isn't part
> of the distribution?

I don't follow.  It would be an internal build dependency, like LLVM
for Mesa (in some distributions).  It would be shipped like any other
build dependency.

I have these two constraints:

a) I need to build glibc before the kernel backporting finishes.
b) I can't rebase UAPI headers to the latest upstream.

I'm under the impression you are suggesting to build glibc against a
special set of UAPI headers which aren't used by the application.
That will lead to the too aggressive SYS_ macro generation.
Andreas Schwab April 22, 2017, 5:27 p.m.
On Apr 22 2017, Florian Weimer <fw@deneb.enyo.de> wrote:

> I have these two constraints:
>
> a) I need to build glibc before the kernel backporting finishes.
> b) I can't rebase UAPI headers to the latest upstream.

Just add the patches you need and you are done.

Andreas.
Dmitry V. Levin April 23, 2017, 12:35 a.m.
On Fri, Apr 21, 2017 at 11:16:26AM -0400, Carlos O'Donell wrote:
> My opinion is that the upstream kernel UAPI headers continue to change
> without good management of the changes. I have seen at least 3 changes
> which break header inclusion ordering and that would have caused application
> build problems. None of the authors of those changes came to talk to us
> about adding the right guards in glibc to prevent breakage. Worse there
> have been discussions about deleting existing guards, that change would
> break header inclusion order in one of the two directions, just to 
> simplify libc-compat.h in the kernel (avoiding needing any libc-specific
> knowledge). This does not seem conservative enough to me.

Unfortunately, there seems to be no good working synchronization mechanism
proposed yet.  The procedure described in
https://sourceware.org/glibc/wiki/Synchronizing_Headers has severe
problems on the kernel side.  Even with headers that were synchronized
several years ago we have unsolved inclusion issues like this:

$ gcc -xc -c -o/dev/null - <<EOF
#include <linux/in.h>
#include <netinet/in.h>
#include <linux/in6.h> 
EOF

or this:

$ gcc -xc -c -o/dev/null - <<EOF
#include <linux/xattr.h>
#include <netinet/in.h>
#include <linux/in6.h> 
EOF

See also https://sourceware.org/ml/libc-alpha/2017-04/msg00157.html

It's hard to expect that kernel folks would be adding new guards
if already added guards are so fragile.

Patch hide | download patch | download mbox

<bits/syscall.h>: Use an arch-independent system call list on Linux

This commit changes the way the list of SYS_* system call macros
is created on Linux.  glibc now contains a list of all known system
calls, and the generated <bits/syscall.h> file defines the SYS_
macro only if the correspnding __NR_ macro is defined by the kernel
headers.

As a result, there glibc does not have to be rebuilt to pick up
system calls if the glibc sources already know about them.  This
means that glibc can be built with older kernel headers, and if
the installed kernel headers are upgraded afterwards, additional
SYS_ macros become available as long as glibc has a record for
those system calls.

2017-04-05  Florian Weimer  <fweimer@redhat.com>

	Store supported list of SYS_* system calls in the source tree.
	* sysdeps/unix/sysv/linux/Makefile (bits/syscall.h): Generate from
	list file.
	[$(subdir) = misc] (tests): Add tst-syscall-list.
	[$(subdir) = misc] (tests-special): Add tst-syscall-list.out
	[$(subdir) = misc] (tst-syscall-list-macros.list)
	(tst-syscall-list-nr.list, tst-syscall-list-sys.list): Helper
	targets for new tst-syscall-list test.
	(tst-syscall-list.out): Run test script tst-syscall-list.sh.
	* sysdeps/unix/sysv/linux/syscall-names.list: New file.
	* sysdeps/unix/sysv/linux/gen-syscall-h.awk: Likewise.
	* sysdeps/unix/sysv/linux/filter-nr-syscalls.awk: Likewise.
	* sysdeps/unix/sysv/linux/tst-syscall-list.sh: Likewise.

diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 1872cdb..5573c4e 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -45,75 +45,46 @@  sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
 tests += tst-clone tst-clone2 tst-fanotify tst-personality tst-quota \
 	 tst-sync_file_range test-errno-linux
 
-# Generate the list of SYS_* macros for the system calls (__NR_* macros).
+# Generate the list of SYS_* macros for the system calls (__NR_*
+# macros).  The file syscall-names.list contains all possible system
+# call names, and the generated header file produces SYS_* macros for
+# the __NR_* macros which are actually defined.
 
-# If there is more than one syscall list for different architecture
-# variants, the CPU/Makefile defines abi-variants to be a list of names
-# for those variants (e.g. 32 64), and, for each variant, defines
-# abi-$(variant)-options to be compiler options to cause <asm/unistd.h>
-# to define the desired list of syscalls and abi-$(variant)-condition to
-# be the condition for those options to use in a C #if condition.
-# abi-includes may be defined to a list of headers to include
-# in the generated header, if the default does not suffice.
-#
-# The generated header is compiled with `-ffreestanding' to avoid any
-# circular dependencies against the installed implementation headers.
-# Such a dependency would require the implementation header to be
-# installed before the generated header could be built (See bug 15711).
-# In current practice the generated header dependencies do not include
-# any of the implementation headers removed by the use of `-ffreestanding'.
-
-$(objpfx)bits/syscall%h $(objpfx)bits/syscall%d: ../sysdeps/unix/sysv/linux/sys/syscall.h
+generated += bits/syscall.h
+$(objpfx)bits/syscall.h: \
+  ../sysdeps/unix/sysv/linux/gen-syscall-h.awk \
+  ../sysdeps/unix/sysv/linux/syscall-names.list
 	$(make-target-directory)
-	{ \
-	 echo '/* Generated at libc build time from kernel syscall list.  */';\
-	 echo ''; \
-	 echo '#ifndef _SYSCALL_H'; \
-	 echo '# error "Never use <bits/syscall.h> directly; include <sys/syscall.h> instead."'; \
-	 echo '#endif'; \
-	 echo ''; \
-	 $(foreach h,$(abi-includes), echo '#include <$(h)>';) \
-	 echo ''; \
-	 $(if $(abi-variants), \
-	 $(foreach v,$(abi-variants),\
-	 $(CC) -ffreestanding -E -MD -MP -MF $(@:.h=.d)-t$(v) -MT '$(@:.d=.h) $(@:.h=.d)' \
-	       -x c $(sysincludes) $< $(abi-$(v)-options) \
-	       -D_LIBC -dM | \
-	 sed -n 's@^#define __NR_\([^ ]*\) .*$$@#define SYS_\1 __NR_\1@p' | \
-	 LC_ALL=C sort > $(@:.d=.h).new$(v); \
-	 $(if $(abi-$(v)-condition),\
-	 echo '#if $(abi-$(v)-condition)';) \
-	 cat $(@:.d=.h).new$(v); \
-	 $(if $(abi-$(v)-condition),echo '#endif';) \
-	 rm -f $(@:.d=.h).new$(v); \
-	 ), \
-	 $(CC) -ffreestanding -E -MD -MP -MF $(@:.h=.d)-t$(v) -MT '$(@:.d=.h) $(@:.h=.d)' \
-	       -x c $(sysincludes) $< \
-	       -D_LIBC -dM | \
-	 sed -n 's@^#define __NR_\([^ ]*\) .*$$@#define SYS_\1 __NR_\1@p' | \
-	 LC_ALL=C sort;) \
-	} > $(@:.d=.h).new
-	mv -f $(@:.d=.h).new $(@:.d=.h)
-ifdef abi-variants
-ifneq (,$(objpfx))
-	sed $(sed-remove-objpfx) \
-	 $(foreach v,$(abi-variants),$(@:.h=.d)-t$(v)) > $(@:.h=.d)-t3
-else
-	cat $(foreach v,$(abi-variants),$(@:.h=.d)-t$(v)) \
-	 > $(@:.h=.d)-t3
-endif
-	rm -f $(foreach v,$(abi-variants),$(@:.h=.d)-t$(v))
-	mv -f $(@:.h=.d)-t3 $(@:.h=.d)
-else
-	mv -f $(@:.h=.d)-t $(@:.h=.d)
-endif
+	$(AWK) -f $^ > $@-tmp
+	$(move-if-change) $@-tmp $@
 
-ifndef no_deps
-# Get the generated list of dependencies (probably /usr/include/asm/unistd.h).
--include $(objpfx)bits/syscall.d
-endif
-generated += bits/syscall.h bits/syscall.d
-endif
+# All macros defined by <sys/syscall.h>.  Include <bits/syscall.h>
+# explicitly because <sys/sycall.h> skips it if _LIBC is defined.
+$(objpfx)tst-syscall-list-macros.list: \
+  $(objpfx)bits/syscall.h ../sysdeps/unix/sysv/linux/sys/syscall.h
+	printf '#include <sys/syscall.h>\n#include <bits/syscall.h>\n' | \
+	  $(CC) -E -o $@-tmp $(CFLAGS) $(CPPFLAGS) -x c - -dM
+	$(move-if-change) $@-tmp $@
+
+# __NR_* system call names.  Used by the test below.
+$(objpfx)tst-syscall-list-nr.list: \
+  ../sysdeps/unix/sysv/linux/filter-nr-syscalls.awk \
+  $(objpfx)tst-syscall-list-macros.list
+	$(AWK) -f $^ > $@-tmp
+	$(move-if-change) $@-tmp $@
+
+# SYS_* system call names.  Used by the test below.
+$(objpfx)tst-syscall-list-sys.list: $(objpfx)tst-syscall-list-macros.list
+	$(AWK) '/^#define SYS_/ { print substr($$2, 5) }' $< > $@-tmp
+	$(move-if-change) $@-tmp $@
+
+tests-special += $(objpfx)tst-syscall-list.out
+$(objpfx)tst-syscall-list.out: \
+  ../sysdeps/unix/sysv/linux/tst-syscall-list.sh \
+  $(objpfx)tst-syscall-list-nr.list $(objpfx)tst-syscall-list-sys.list
+	$(BASH) $^ > $@; $(evaluate-test)
+
+endif # $(subdir) == misc
 
 ifeq ($(subdir),time)
 sysdep_headers += sys/timex.h bits/timex.h
diff --git a/sysdeps/unix/sysv/linux/filter-nr-syscalls.awk b/sysdeps/unix/sysv/linux/filter-nr-syscalls.awk
new file mode 100644
index 0000000..15b052a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/filter-nr-syscalls.awk
@@ -0,0 +1,35 @@ 
+# Filter preprocessor __NR_* macros and extract system call names.
+# 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/>.
+
+# Skip reserved system calls.
+/^#define __NR_(unused|reserved)[0-9]+ / {
+    next;
+}
+
+# Skip pseudo-system calls which describe ranges.
+/^#define __NR_(syscalls|arch_specific_syscall|(OABI_)?SYSCALL_BASE) / {
+    next;
+}
+/^#define __NR_(|64_|[NO]32_)Linux(_syscalls)? / {
+    next;
+}
+
+# Print the remaining _NR_* macros as system call names.
+/^#define __NR_/ {
+    print substr($2, 6);
+}
diff --git a/sysdeps/unix/sysv/linux/gen-syscall-h.awk b/sysdeps/unix/sysv/linux/gen-syscall-h.awk
new file mode 100644
index 0000000..0a27b3c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/gen-syscall-h.awk
@@ -0,0 +1,75 @@ 
+# Generate SYS_* macros from a list in a text file.
+# 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/>.
+
+# Emit a conditional definition for SYS_NAME.
+function emit(name) {
+    print "#ifdef __NR_" name;
+    print "# define SYS_" name " __NR_" name;
+    print "#endif";
+    print "";
+}
+
+# Bail out with an error.
+function fatal(message) {
+    print FILENAME ":" FNR ": " message > "/dev/stderr";
+    exit 1;
+}
+
+BEGIN {
+    name = "";
+    kernel = "";
+}
+
+# Skip empty lines and comments.
+/^\s*(|#.*)$/ {
+    next;
+}
+
+# Kernel version.  Used for documentation purposes only.
+/^kernel [0-9.]+$/ {
+    if (kernel != "") {
+        fatal("duplicate kernel directive");
+    }
+    kernel = $2;
+    print "/* Generated at libc build time from syscall list.  */";
+    print "/* The system call list corresponds to kernel " kernel ".  */";
+    print "";
+    print "#ifndef _SYSCALL_H"
+    print "# error \"Never use <bits/syscall.h> directly; include <sys/syscall.h> instead.\"";
+    print "#endif";
+    print "";
+    next;
+}
+
+# If there is just one word, it is a system call.
+/^[a-zA-Z_][a-zA-Z0-9_]+$/ {
+    if (kernel == "") {
+        fatal("expected kernel directive before this line");
+    }
+    if ($1 <= name) {
+        fatal("name " name " violates ordering");
+    }
+    emit($1);
+    name = $1;
+    next;
+}
+
+# The rest has to be syntax errors.
+// {
+    fatal("unrecognized syntax");
+}
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
new file mode 100644
index 0000000..9a47755
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
@@ -0,0 +1,594 @@ 
+# List of all known Linux system calls.
+# 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 file contains the list of system call names names.  It has to
+# remain in alphabetica order.  Lines which start with # are treated
+# as comments.  This file can list all potential system calls.  The
+# names are only used if the installed kernel headers also provide
+# them.
+
+# The list of system calls is current as of Linux 4.10.
+kernel 4.10
+
+FAST_atomic_update
+FAST_cmpxchg
+FAST_cmpxchg64
+_llseek
+_newselect
+_sysctl
+accept
+accept4
+access
+acct
+add_key
+adjtimex
+afs_syscall
+alarm
+arch_prctl
+arm_fadvise64_64
+arm_sync_file_range
+atomic_barrier
+atomic_cmpxchg_32
+bdflush
+bind
+bpf
+break
+brk
+cachectl
+cacheflush
+capget
+capset
+chdir
+chmod
+chown
+chown32
+chroot
+clock_adjtime
+clock_getres
+clock_gettime
+clock_nanosleep
+clock_settime
+clone
+clone2
+close
+cmpxchg_badaddr
+connect
+copy_file_range
+creat
+create_module
+delete_module
+dipc
+dup
+dup2
+dup3
+epoll_create
+epoll_create1
+epoll_ctl
+epoll_ctl_old
+epoll_pwait
+epoll_wait
+epoll_wait_old
+eventfd
+eventfd2
+exec_with_loader
+execv
+execve
+execveat
+exit
+exit_group
+faccessat
+fadvise64
+fadvise64_64
+fallocate
+fanotify_init
+fanotify_mark
+fchdir
+fchmod
+fchmodat
+fchown
+fchown32
+fchownat
+fcntl
+fcntl64
+fdatasync
+fgetxattr
+finit_module
+flistxattr
+flock
+fork
+fremovexattr
+fsetxattr
+fstat
+fstat64
+fstatat64
+fstatfs
+fstatfs64
+fsync
+ftime
+ftruncate
+ftruncate64
+futex
+futimesat
+get_kernel_syms
+get_mempolicy
+get_robust_list
+get_thread_area
+getcpu
+getcwd
+getdents
+getdents64
+getdomainname
+getdtablesize
+getegid
+getegid32
+geteuid
+geteuid32
+getgid
+getgid32
+getgroups
+getgroups32
+gethostname
+getitimer
+getpagesize
+getpeername
+getpgid
+getpgrp
+getpid
+getpmsg
+getppid
+getpriority
+getrandom
+getresgid
+getresgid32
+getresuid
+getresuid32
+getrlimit
+getrusage
+getsid
+getsockname
+getsockopt
+gettid
+gettimeofday
+getuid
+getuid32
+getunwind
+getxattr
+getxgid
+getxpid
+getxuid
+gtty
+idle
+init_module
+inotify_add_watch
+inotify_init
+inotify_init1
+inotify_rm_watch
+io_cancel
+io_destroy
+io_getevents
+io_setup
+io_submit
+ioctl
+ioperm
+iopl
+ioprio_get
+ioprio_set
+ipc
+kcmp
+kern_features
+kexec_file_load
+kexec_load
+keyctl
+kill
+lchown
+lchown32
+lgetxattr
+link
+linkat
+listen
+listxattr
+llistxattr
+llseek
+lock
+lookup_dcookie
+lremovexattr
+lseek
+lsetxattr
+lstat
+lstat64
+madvise
+mbind
+membarrier
+memfd_create
+memory_ordering
+migrate_pages
+mincore
+mkdir
+mkdirat
+mknod
+mknodat
+mlock
+mlock2
+mlockall
+mmap
+mmap2
+modify_ldt
+mount
+move_pages
+mprotect
+mpx
+mq_getsetattr
+mq_notify
+mq_open
+mq_timedreceive
+mq_timedsend
+mq_unlink
+mremap
+msgctl
+msgget
+msgrcv
+msgsnd
+msync
+multiplexer
+munlock
+munlockall
+munmap
+name_to_handle_at
+nanosleep
+newfstatat
+nfsservctl
+ni_syscall
+nice
+old_adjtimex
+oldfstat
+oldlstat
+oldolduname
+oldstat
+oldumount
+olduname
+open
+open_by_handle_at
+openat
+osf_adjtime
+osf_afs_syscall
+osf_alt_plock
+osf_alt_setsid
+osf_alt_sigpending
+osf_asynch_daemon
+osf_audcntl
+osf_audgen
+osf_chflags
+osf_execve
+osf_exportfs
+osf_fchflags
+osf_fdatasync
+osf_fpathconf
+osf_fstat
+osf_fstatfs
+osf_fstatfs64
+osf_fuser
+osf_getaddressconf
+osf_getdirentries
+osf_getdomainname
+osf_getfh
+osf_getfsstat
+osf_gethostid
+osf_getitimer
+osf_getlogin
+osf_getmnt
+osf_getrusage
+osf_getsysinfo
+osf_gettimeofday
+osf_kloadcall
+osf_kmodcall
+osf_lstat
+osf_memcntl
+osf_mincore
+osf_mount
+osf_mremap
+osf_msfs_syscall
+osf_msleep
+osf_mvalid
+osf_mwakeup
+osf_naccept
+osf_nfssvc
+osf_ngetpeername
+osf_ngetsockname
+osf_nrecvfrom
+osf_nrecvmsg
+osf_nsendmsg
+osf_ntp_adjtime
+osf_ntp_gettime
+osf_old_creat
+osf_old_fstat
+osf_old_getpgrp
+osf_old_killpg
+osf_old_lstat
+osf_old_open
+osf_old_sigaction
+osf_old_sigblock
+osf_old_sigreturn
+osf_old_sigsetmask
+osf_old_sigvec
+osf_old_stat
+osf_old_vadvise
+osf_old_vtrace
+osf_old_wait
+osf_oldquota
+osf_pathconf
+osf_pid_block
+osf_pid_unblock
+osf_plock
+osf_priocntlset
+osf_profil
+osf_proplist_syscall
+osf_reboot
+osf_revoke
+osf_sbrk
+osf_security
+osf_select
+osf_set_program_attributes
+osf_set_speculative
+osf_sethostid
+osf_setitimer
+osf_setlogin
+osf_setsysinfo
+osf_settimeofday
+osf_shmat
+osf_signal
+osf_sigprocmask
+osf_sigsendset
+osf_sigstack
+osf_sigwaitprim
+osf_sstk
+osf_stat
+osf_statfs
+osf_statfs64
+osf_subsys_info
+osf_swapctl
+osf_swapon
+osf_syscall
+osf_sysinfo
+osf_table
+osf_uadmin
+osf_usleep_thread
+osf_uswitch
+osf_utc_adjtime
+osf_utc_gettime
+osf_utimes
+osf_utsname
+osf_wait4
+osf_waitid
+pause
+pciconfig_iobase
+pciconfig_read
+pciconfig_write
+perf_event_open
+perfctr
+perfmonctl
+personality
+pipe
+pipe2
+pivot_root
+pkey_alloc
+pkey_free
+pkey_mprotect
+poll
+ppoll
+prctl
+pread64
+preadv
+preadv2
+prlimit64
+process_vm_readv
+process_vm_writev
+prof
+profil
+pselect6
+ptrace
+putpmsg
+pwrite64
+pwritev
+pwritev2
+query_module
+quotactl
+read
+readahead
+readdir
+readlink
+readlinkat
+readv
+reboot
+recv
+recvfrom
+recvmmsg
+recvmsg
+remap_file_pages
+removexattr
+rename
+renameat
+renameat2
+request_key
+restart_syscall
+rmdir
+rt_sigaction
+rt_sigpending
+rt_sigprocmask
+rt_sigqueueinfo
+rt_sigreturn
+rt_sigsuspend
+rt_sigtimedwait
+rt_tgsigqueueinfo
+rtas
+s390_pci_mmio_read
+s390_pci_mmio_write
+s390_runtime_instr
+sched_get_affinity
+sched_get_priority_max
+sched_get_priority_min
+sched_getaffinity
+sched_getattr
+sched_getparam
+sched_getscheduler
+sched_rr_get_interval
+sched_set_affinity
+sched_setaffinity
+sched_setattr
+sched_setparam
+sched_setscheduler
+sched_yield
+seccomp
+security
+select
+semctl
+semget
+semop
+semtimedop
+send
+sendfile
+sendfile64
+sendmmsg
+sendmsg
+sendto
+set_mempolicy
+set_robust_list
+set_thread_area
+set_tid_address
+setdomainname
+setfsgid
+setfsgid32
+setfsuid
+setfsuid32
+setgid
+setgid32
+setgroups
+setgroups32
+sethae
+sethostname
+setitimer
+setns
+setpgid
+setpgrp
+setpriority
+setregid
+setregid32
+setresgid
+setresgid32
+setresuid
+setresuid32
+setreuid
+setreuid32
+setrlimit
+setsid
+setsockopt
+settimeofday
+setuid
+setuid32
+setxattr
+sgetmask
+shmat
+shmctl
+shmdt
+shmget
+shutdown
+sigaction
+sigaltstack
+signal
+signalfd
+signalfd4
+sigpending
+sigprocmask
+sigreturn
+sigsuspend
+socket
+socketcall
+socketpair
+splice
+spu_create
+spu_run
+ssetmask
+stat
+stat64
+statfs
+statfs64
+stime
+stty
+subpage_prot
+swapcontext
+swapoff
+swapon
+switch_endian
+symlink
+symlinkat
+sync
+sync_file_range
+sync_file_range2
+syncfs
+sys_debug_setcontext
+sys_epoll_create
+sys_epoll_ctl
+sys_epoll_wait
+syscall
+sysfs
+sysinfo
+syslog
+sysmips
+tee
+tgkill
+time
+timer_create
+timer_delete
+timer_getoverrun
+timer_gettime
+timer_settime
+timerfd
+timerfd_create
+timerfd_gettime
+timerfd_settime
+times
+tkill
+truncate
+truncate64
+tuxcall
+ugetrlimit
+ulimit
+umask
+umount
+umount2
+uname
+unlink
+unlinkat
+unshare
+uselib
+userfaultfd
+ustat
+utime
+utimensat
+utimes
+utrap_install
+vfork
+vhangup
+vm86
+vm86old
+vmsplice
+vserver
+wait4
+waitid
+waitpid
+write
+writev
diff --git a/sysdeps/unix/sysv/linux/tst-syscall-list.sh b/sysdeps/unix/sysv/linux/tst-syscall-list.sh
new file mode 100644
index 0000000..f48b7cd
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-syscall-list.sh
@@ -0,0 +1,72 @@ 
+#!/bin/bash
+# Consistency checks for the system call list
+# 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/>.
+
+export LC_ALL=C
+set -e
+set -o pipefail
+
+if test $# != 2 ; then
+    echo "error: wrong number of arguments: $#"
+    exit 1
+fi
+
+list_nr="$1"
+list_sys="$2"
+
+errors=0
+
+# Use getpid as a system call which is expected to be always defined.
+# alpha uses getxpid instead, so it is permitted as an alternative.
+if ! grep -E -q '^getx?pid$' -- "$list_nr" ; then
+    echo "error: __NR_getpid not defined"
+    errors=1
+fi
+if ! grep -E -q '^getx?pid$' -- "$list_sys" ; then
+    echo "error: SYS_getpid not defined"
+    errors=1
+fi
+
+comm_1="$(mktemp)"
+comm_2="$(mktemp)"
+comm_result="$(mktemp)"
+cleanup () {
+    rm -f -- "$comm_1" "$comm_2" "$comm_result"
+}
+trap cleanup 0
+
+sort -o "$comm_1" -- "$list_nr"
+sort -o "$comm_2" -- "$list_sys"
+
+# Check for missing SYS_* macros.
+comm --check-order -2 -3 -- "$comm_1" "$comm_2" > "$comm_result"
+if test -s "$comm_result"; then
+    echo "error: These system calls need to be added to syscall-names.list:"
+    cat -- "$comm_result"
+    errors=1
+fi
+
+# Check for additional SYS_* macros.
+comm --check-order -1 -3 -- "$comm_1" "$comm_2" > "$comm_result"
+if test -s "$comm_result"; then
+    echo "error: The following system calls have unexpected SYS_* macros:"
+    cat -- "$comm_result"
+    errors=1
+fi
+
+exit "$errors"