From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS31976 209.132.180.0/23 X-Spam-Status: No, score=-4.1 required=3.0 tests=AWL,BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL,SPF_HELO_PASS,SPF_PASS,WEIRD_QUOTING shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dcvr.yhbt.net (Postfix) with ESMTPS id 71A541F463 for ; Sat, 28 Dec 2019 12:40:28 +0000 (UTC) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:to:references:from:message-id:date :mime-version:in-reply-to:content-type :content-transfer-encoding; q=dns; s=default; b=UfEXwSD0zG0CAQ/K dCrufsAP70GBrMHb0G7h4n/B73+bDdiJke6MsZSHRGUsuogPKTI5ExXSwCFq903i RjteymcqDuqPNjHE1e2sLvEOARjhdU5RINeUGryAOXeB8sDwHhAjX43apDG2kltl q59Gpj5LPah4ove3YjUfzxAYMbs= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:to:references:from:message-id:date :mime-version:in-reply-to:content-type :content-transfer-encoding; s=default; bh=0H/G05FD+Br8vq3GEY1B88 IbgTk=; b=dTRuZzK+i/YRvBV2N0xI0yWY1NLnroI/nGsYK6RXZZZuiAGqPyU12n 2XtSYKpOtf7LpEVOrvJ75uCBY4dqmjq4l/GNH5jdSXrcm3ePpRdy7kbNLyfnEmNv lnEH3JaSRM2284XRwLSYSu8MGyvbTaMah3BkItlCrTcgteHkCkZnM= Received: (qmail 70569 invoked by alias); 28 Dec 2019 12:40:14 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Received: (qmail 70478 invoked by uid 89); 28 Dec 2019 12:40:13 -0000 Authentication-Results: sourceware.org; auth=none X-HELO: dragonfly.birch.relay.mailchannels.net X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|siddhesh@gotplt.org X-MailChannels-Auth-Id: dreamhost X-Society-Company: 467c5cc623a0a61e_1577536806097_2520809971 X-MC-Loop-Signature: 1577536806097:449888657 X-MC-Ingress-Time: 1577536806097 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gotplt.org; h=subject:to :references:from:message-id:date:mime-version:in-reply-to :content-type:content-transfer-encoding; s=gotplt.org; bh=0H/G05 FD+Br8vq3GEY1B88IbgTk=; b=mruYY5Ik8ytkyjscPboq6mRBmiJS7V9kviUGbx UPuD0Mn7H7UMOGdS+z2isFl56/hxFx/RCoLXkxVRY6s+TgW0PhcDMRTzWbCbWwm/ PY4UXYkmOABqMnwwtV9sjtdD5ebeVwTW3V/ljriNFDRUyrOIalY20hqpTdpvhuQ7 Ucfn4= Subject: Re: [PATCH 1/5] Linux: Add tables with system call numbers To: Florian Weimer , libc-alpha@sourceware.org References: X-DH-BACKEND: pdx1-sub0-mail-a21 From: Siddhesh Poyarekar Message-ID: <56247f60-bee7-9624-37bf-1453c06c7088@gotplt.org> Date: Sat, 28 Dec 2019 18:09:55 +0530 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.3.1 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 X-VR-OUT-STATUS: OK X-VR-OUT-SCORE: -100 X-VR-OUT-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedufedrvdeftddggeefucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuggftfghnshhusghstghrihgsvgdpffftgfetoffjqffuvfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhepuffvfhfhkffffgggjggtgfesthekredttdefjeenucfhrhhomhepufhiugguhhgvshhhucfrohihrghrvghkrghruceoshhiugguhhgvshhhsehgohhtphhlthdrohhrgheqnecuffhomhgrihhnpehgnhhurdhorhhgnecukfhppedutdefrddvudelrdeitddrudeifeenucfrrghrrghmpehmohguvgepshhmthhppdhhvghloheplgduledvrdduieekrddvrdegngdpihhnvghtpedutdefrddvudelrdeitddrudeifedprhgvthhurhhnqdhprghthhepufhiugguhhgvshhhucfrohihrghrvghkrghruceoshhiugguhhgvshhhsehgohhtphhlthdrohhrgheqpdhmrghilhhfrhhomhepshhiugguhhgvshhhsehgohhtphhlthdrohhrghdpnhhrtghpthhtohepfhifvghimhgvrhesrhgvughhrghtrdgtohhmnecuvehluhhsthgvrhfuihiivgeptd Content-Transfer-Encoding: quoted-printable Overall there are some nits and one issue to fix before this is good to go. The one issue is to write the results over the new file only if the script is successful. You could do the whole thing in python, but perhaps the least fussy way would be to write to stdout and use the Makefile target to write the result similar to other scripts. On 17/12/19 8:00 pm, Florian Weimer wrote: > The new tables are currently only used for consistency checks > with the installed kernel headers and the architecture-independent > system call names table. They are based on Linux 5.4. >=20 > The goal is to use these architecture-specific tables to ensure > that system call wrappers are available irrespective of the version > of the installed kernel headers. >=20 > The tables are formatted in the form of C header files so that they > can be used directly in an #include directive, without external > preprocessing. (External preprocessing of a plain table file > would introduce cross-subdirectory dependency issues.) However, > the intent is that they can still be treated as tables and can be > processed by simple tools. >=20 > The irregular system call names on 32-bit arm add a complication. > The header is introduced to work around that, > and the system calls are listed under regular names in the > file. >=20 > A make target, update-syscalls-list, is added to patch the glibc > sources with data from the current kernel headers. > diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux= /Makefile > index 07776d28ea..502589c330 100644 > --- a/sysdeps/unix/sysv/linux/Makefile > +++ b/sysdeps/unix/sysv/linux/Makefile > @@ -1,3 +1,41 @@ > +# Option to pass to Python scripts to set the C compiler. Rewriting > +# MODULE_NAME is required to enable the _ISOMAC verbatim header > +# environment. > +sysdeps-linux-python-cc =3D \ > + --cc=3D"$(CC) $(patsubst -DMODULE_NAME=3D%,-DMODULE_NAME=3Dtestsuite= ,$(CPPFLAGS))" > + > +# Additional dependencies for Python scripts. > +sysdeps-linux-python-deps =3D \ > + $(..)sysdeps/unix/sysv/linux/glibcsyscalls.py \ > + $(..)scripts/glibcextract.py > + > +# Invocation of the Python interpreter with the Python search path. > +sysdeps-linux-python =3D \ > + PYTHONPATH=3D$(..)scripts:$(..)sysdeps/unix/sysv/linux $(PYTHON) > + > +ifndef subdir > +# This target performs two actions: > +# > +# Replace with a file generated from kernel headers > +# and . Both files are located via the sysdeps > +# override search path. > +# > +# Update sysdeps/unix/sysv/linux/syscall-names.list with additional > +# names found in the generated file, so that the > +# global system call names list is a superset of the > +# architecture-specific system call names. > +# > +# To bootstrap a new architecture, create an empty file in the right > +# place and run =E2=80=9Cmake update-arch-syscall=E2=80=9D from the to= p-level of a > +# configured, but not-yet-built glibc tree. > +.PHONY: update-syscall-lists > +update-syscall-lists: arch-syscall.h > + $(sysdeps-linux-python) \ > + sysdeps/unix/sysv/linux/update-syscall-lists.py \ > + $(sysdeps-linux-python-cc) $< \ > + sysdeps/unix/sysv/linux/syscall-names.list > +endif > + OK. > ifeq ($(subdir),csu) > sysdep_routines +=3D errno-loc > endif > @@ -103,6 +141,19 @@ $(objpfx)tst-syscall-list.out: \ > $(objpfx)tst-syscall-list-sys.list > $(BASH) $^ $(AWK) > $@; $(evaluate-test) > =20 > +tests-special +=3D $(objpfx)tst-glibcsyscalls.out > +# arch-syscall.h is located via the sysdeps override search path. > +$(objpfx)tst-glibcsyscalls.out: arch-syscall.h \ > + ../sysdeps/unix/sysv/linux/syscall-names.list > + $(sysdeps-linux-python) \ > + ../sysdeps/unix/sysv/linux/tst-glibcsyscalls.py \ > + $(sysdeps-linux-python-cc) $< \ > + ../sysdeps/unix/sysv/linux/syscall-names.list \ > + < /dev/null > $@ 2>&1; $(evaluate-test) > +$(objpfx)tst-glibcsyscalls.out: \ > + ../sysdeps/unix/sysv/linux/tst-glibcsyscalls.py \ > + $(sysdeps-linux-python-deps) > + > # Separate object file for access to the constant from the UAPI header= . > $(objpfx)tst-sysconf-iov_max: $(objpfx)tst-sysconf-iov_max-uapi.o > =20 > @@ -110,12 +161,11 @@ $(objpfx)tst-pkey: $(shared-thread-library) > =20 > tests-special +=3D $(objpfx)tst-mman-consts.out > $(objpfx)tst-mman-consts.out: ../sysdeps/unix/sysv/linux/tst-mman-cons= ts.py > - PYTHONPATH=3D../scripts \ > - $(PYTHON) ../sysdeps/unix/sysv/linux/tst-mman-consts.py \ > - --cc=3D"$(CC) $(patsubst -DMODULE_NAME=3D%, \ > - -DMODULE_NAME=3Dtestsuite, \ > - $(CPPFLAGS))" \ > - < /dev/null > $@ 2>&1; $(evaluate-test) > + $(sysdeps-linux-python) \ > + ../sysdeps/unix/sysv/linux/tst-mman-consts.py \ > + $(sysdeps-linux-python-cc) \ > + < /dev/null > $@ 2>&1; $(evaluate-test) > +$(objpfx)tst-mman-consts.out: $(sysdeps-linux-python-deps) > =20 > $(objpfx)tst-gettid: $(shared-thread-library) > $(objpfx)tst-gettid-kill: $(shared-thread-library) > @@ -138,12 +188,11 @@ tests-special +=3D $(objpfx)tst-signal-numbers.ou= t > $(objpfx)tst-signal-numbers.out: \ > ../sysdeps/unix/sysv/linux/tst-signal-numbers.py \ > $(objpfx)signal.o* > - PYTHONPATH=3D../scripts \ > - $(PYTHON) ../sysdeps/unix/sysv/linux/tst-signal-numbers.py \ > - --cc=3D"$(CC) $(patsubst -DMODULE_NAME=3D%, \ > - -DMODULE_NAME=3Dtestsuite, \ > - $(CPPFLAGS))" \ > - < /dev/null > $@ 2>&1; $(evaluate-test) > + $(sysdeps-linux-python) \ > + ../sysdeps/unix/sysv/linux/tst-signal-numbers.py \ > + $(sysdeps-linux-python-cc) \ > + < /dev/null > $@ 2>&1; $(evaluate-test) > +$(objpfx)tst-signal-numbers.out: $(sysdeps-linux-python-deps) > endif > =20 > ifeq ($(subdir),socket) > diff --git a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h b/sysdeps/u= nix/sysv/linux/aarch64/arch-syscall.h > new file mode 100644 > index 0000000000..163f618499 > --- /dev/null > +++ b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h Prefix the auto-generated files with a comment header like so: /* AUTOGENERATED by update-syscall-lists.py. DO NOT EDIT. */ > @@ -0,0 +1,290 @@ > +#define __NR_accept 202 > +#define __NR_accept4 242 > +#define __NR_acct 89 > +#define __NR_add_key 217 > +#define __NR_adjtimex 171 ... > diff --git a/sysdeps/unix/sysv/linux/arm/fixup-asm-unistd.h b/sysdeps/u= nix/sysv/linux/arm/fixup-asm-unistd.h > new file mode 100644 > index 0000000000..6f236462a8 > --- /dev/null > +++ b/sysdeps/unix/sysv/linux/arm/fixup-asm-unistd.h > @@ -0,0 +1,24 @@ > +/* Regularize definitions. Arm version. > + Copyright (C) 2019 Free Software Foundation, Inc. > + > + 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 > + . */ > + > +/* These system calls have iregular names and are used by glibc. */ > +#ifndef __NR_cacheflush > +# define __NR_cacheflush __ARM_NR_cacheflush > +#endif > +#ifndef __NR_set_tls > +# define __NR_set_tls __ARM_NR_set_tls > +#endif OK. > diff --git a/sysdeps/unix/sysv/linux/csky/arch-syscall.h b/sysdeps/unix= /sysv/linux/csky/arch-syscall.h > new file mode 100644 > index 0000000000..60a626660e > --- /dev/null > +++ b/sysdeps/unix/sysv/linux/csky/arch-syscall.h > diff --git a/sysdeps/unix/sysv/linux/fixup-asm-unistd.h b/sysdeps/unix/sysv/linux/fixup-asm-unistd.h > new file mode 100644 > index 0000000000..a5bd9822b7 > --- /dev/null > +++ b/sysdeps/unix/sysv/linux/fixup-asm-unistd.h > @@ -0,0 +1,28 @@ > +/* Regularize definitions. Default version. > + Copyright (C) 2019 Free Software Foundation, Inc. > + > + 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 > + . */ > + > +/* Some architectures have irregular system call names in > + . glibc assumes that system call numbers start with > + __NR_* and lists the system calls under proper names in > + . > + > + During consistency tests, is included after > + the kernel's , to introduce aliases as necessary to > + match the glibc definitions in . > + > + Most architectures do not need these fixups, so the default header > + is empty. */ OK. > diff --git a/sysdeps/unix/sysv/linux/glibcsyscalls.py b/sysdeps/unix/sy= sv/linux/glibcsyscalls.py > new file mode 100644 > index 0000000000..b968229a48 > --- /dev/null > +++ b/sysdeps/unix/sysv/linux/glibcsyscalls.py > @@ -0,0 +1,165 @@ > +#!/usr/bin/python3 > +# Helpers for glibc system call list processing. > +# Copyright (C) 2018-2019 Free Software Foundation, Inc. It's a new file in glibc, so only 2019. > +# 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 > +# . > + > +import re > + > +import glibcextract > + > +def extract_system_call_name(macro): > + """Convert the macro name (with __NR_) to a system call name.""" > + prefix =3D '__NR_' > + if macro.startswith(prefix): > + return macro[len(prefix):] > + else: > + raise ValueError('invalid system call name: {!r}'.format(macro= )) > + > +# Matches macros for systme call names. > +RE_SYSCALL =3D re.compile('__NR_.*') > + > +# Some __NR_ constants are not real > +RE_PSEUDO_SYSCALL =3D re.compile(r"""__NR_( > + # Reserved system call. > + (unused|reserved)[0-9]+ > + > + # Pseudo-system call which describes a range. > + |(syscalls|arch_specific_syscall|(OABI_)?SYSCALL_BASE) > + |(|64_|[NO]32_)Linux(_syscalls)? > + )""", re.X) > + > +def kernel_constants(cc): > + """Return a dictionary with the kernel-defined system call numbers= . > + > + This come from . comes. > + > + """ > + return {extract_system_call_name(name) : int(value) > + for name, value in glibcextract.compute_macro_consts( > + '#include \n' > + # Regularlize the kernel definitions if necessary. > + '#include ', > + cc, macro_re=3DRE_SYSCALL, exclude_re=3DRE_PSEUDO_= SYSCALL) > + .items()} > + > +class SyscallNamesList: > + """The list of known system call names. > + > + glibc keeps a list of system call names. The > + header needs to provide a SYS_ name for each __NR_ macro, > + and the generated header uses an > + architecture-independent list, so that there is a chance that > + system calls arriving late on certain architectures will automatic= ally > + get the expected SYS_ macro. > + > + syscalls: list of strings with system call names > + kernel_version: tuple of integers; the kernel version given in the= file > + > + """ > + def __init__(self, lines): > + self.syscalls =3D [] > + old_name =3D None > + self.kernel_version =3D None > + self.__lines =3D tuple(lines) > + for line in self.__lines: > + line =3D line.strip() > + if (not line) or line[0] =3D=3D '#': > + continue > + comps =3D line.split() > + if len(comps) =3D=3D 1: > + self.syscalls.append(comps[0]) > + if old_name is not None: > + if comps[0] < old_name: > + raise ValueError( > + 'name list is not sorted: {!r} < {!r}'.for= mat( > + comps[0], old_name)) > + old_name =3D comps[0] > + continue > + if len(comps) =3D=3D 2 and comps[0] =3D=3D "kernel": > + if self.kernel_version is not None: > + raise ValueError( > + "multiple kernel versions: {!r} and !{r}".form= at( > + kernel_version, comps[1])) > + self.kernel_version =3D tuple(map(int, comps[1].split(= "."))) > + continue > + raise ValueError("invalid line: !r".format(line)) > + if self.kernel_version is None: > + raise ValueError("missing kernel version") > + > + def merge(self, names): > + """Merge sequence NAMES and return the lines of the new file."= "" > + names =3D list(set(names) - set(self.syscalls)) > + names.sort() > + names.reverse() > + result =3D [] > + def emit_name(): > + result.append(names[-1] + "\n") > + del names[-1] > + > + for line in self.__lines: > + comps =3D line.strip().split() > + if len(comps) =3D=3D 1 and not comps[0].startswith("#"): > + # File has a system call at this position. Insert all > + # the names that come before the name in the file > + # lexicographically. > + while names and names[-1] < comps[0]: > + emit_name() > + result.append(line) > + while names: > + emit_name() > + > + return result > + > +def load_arch_syscall_header(path): > + """"Load the system call header form the file PATH. > + > + The file must consist of lines of this form: > + > + #define __NR_exit 1 > + > + The file is parsed verbatim, without running it through a C > + preprocessor or parser. The intent is that the file can be > + readily processed by tools. > + > + """ > + with open(path) as inp: > + result =3D {} > + old_name =3D None > + for line in inp: > + line =3D line.strip() > + define, name, number =3D line.split(' ', 2) > + if define !=3D '#define': > + raise ValueError("invalid syscall header line: {!r}".f= ormat( > + line)) > + result[extract_system_call_name(name)] =3D int(number) > + > + # Check list order. > + if old_name is not None: > + if name < old_name: > + raise ValueError( > + 'system call list is not sorted: {!r} < {!r}'.= format( > + name, old_name)) > + old_name =3D name > + return result > + > +def linux_kernel_version(cc): > + """Return the (major, minor) version of the Linux kernel headers."= "" > + sym_data =3D ['#include ', 'START', > + ('LINUX_VERSION_CODE', 'LINUX_VERSION_CODE')] > + val =3D glibcextract.compute_c_consts(sym_data, cc)['LINUX_VERSION= _CODE'] > + val =3D int(val) > + return ((val & 0xff0000) >> 16, (val & 0xff00) >> 8) > diff --git a/sysdeps/unix/sysv/linux/tst-glibcsyscalls.py b/sysdeps/uni= x/sysv/linux/tst-glibcsyscalls.py > new file mode 100644 > index 0000000000..5ef0d3420d > --- /dev/null > +++ b/sysdeps/unix/sysv/linux/tst-glibcsyscalls.py > @@ -0,0 +1,88 @@ > +#!/usr/bin/python3 > +# Consistency checks for glibc system call lists. > +# Copyright (C) 2019 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 > +# . > + > +import argparse > +import sys > + > +import glibcextract > +import glibcsyscalls > + > +def main(): > + """The main entry point.""" > + parser =3D argparse.ArgumentParser( > + description=3D"System call list consistency checks") > + parser.add_argument('--cc', metavar=3D'CC', required=3DTrue, > + help=3D'C compiler (including options) to use'= ) > + parser.add_argument('syscall_numbers_list', metavar=3D'PATH', > + help=3D'Path to the list of system call number= s') > + parser.add_argument('syscall_names_list', metavar=3D'PATH', > + help=3D'Path to the list of system call names'= ) > + > + args =3D parser.parse_args() > + > + glibc_constants =3D glibcsyscalls.load_arch_syscall_header( > + args.syscall_numbers_list) > + with open(args.syscall_names_list) as inp: > + glibc_names =3D glibcsyscalls.SyscallNamesList(inp) > + kernel_constants =3D glibcsyscalls.kernel_constants(args.cc) > + kernel_version =3D glibcsyscalls.linux_kernel_version(args.cc) > + > + errors =3D 0 > + warnings =3D False > + for name in glibc_constants.keys() & kernel_constants.keys(): > + if glibc_constants[name] !=3D kernel_constants[name]: > + print("error: syscall {!r} number mismatch: glibc=3D{!r} k= ernel=3D{!r}" > + .format(name, glibc_constants[name], kernel_constant= s[name])) > + errors =3D 1 > + > + # The architecture-specific list in the glibc tree must be a > + # subset of the global list of system call names. > + for name in glibc_constants.keys() - set(glibc_names.syscalls): > + print("error: architecture syscall {!r} missing from global na= mes list" > + .format(name)) > + errors =3D 1 > + > + for name in glibc_constants.keys() - kernel_constants.keys(): > + print("info: glibc syscall {!r} not known to kernel".format(na= me)) > + warnings =3D True > + > + # If the glibc-recorded kernel version is not older than the > + # installed kernel headers, the glibc system call set must be a > + # superset of the kernel system call set. > + if glibc_names.kernel_version >=3D kernel_version: > + for name in kernel_constants.keys() - glibc_constants.keys(): > + print("error: kernel syscall {!r} ({}) not known to glibc" > + .format(name, kernel_constants[name])) > + errors =3D 1 > + else: > + for name in kernel_constants.keys() - glibc_constants.keys(): > + print("warning: kernel syscall {!r} ({}) not known to glib= c" > + .format(name, kernel_constants[name])) > + warnings =3D True > + > + if errors > 0 or warnings: > + print("info: glibc tables are based on kernel version {}".form= at( > + ".".join(map(str, glibc_names.kernel_version)))) > + print("info: installed kernel headers are version {}".format( > + ".".join(map(str, kernel_version)))) > + > + sys.exit(errors) > + > +if __name__ =3D=3D '__main__': > + main() OK. > diff --git a/sysdeps/unix/sysv/linux/tst-mman-consts.py b/sysdeps/unix/= sysv/linux/tst-mman-consts.py > index 3aaf2218f5..17e90ee8dc 100644 > --- a/sysdeps/unix/sysv/linux/tst-mman-consts.py > +++ b/sysdeps/unix/sysv/linux/tst-mman-consts.py > @@ -21,15 +21,7 @@ import argparse > import sys > =20 > import glibcextract > - > - > -def linux_kernel_version(cc): > - """Return the (major, minor) version of the Linux kernel headers."= "" > - sym_data =3D ['#include ', 'START', > - ('LINUX_VERSION_CODE', 'LINUX_VERSION_CODE')] > - val =3D glibcextract.compute_c_consts(sym_data, cc)['LINUX_VERSION= _CODE'] > - val =3D int(val) > - return ((val & 0xff0000) >> 16, (val & 0xff00) >> 8) > +import glibcsyscalls > =20 > =20 > def main(): > @@ -40,7 +32,7 @@ def main(): > parser.add_argument('--cc', metavar=3D'CC', > help=3D'C compiler (including options) to use'= ) > args =3D parser.parse_args() > - linux_version_headers =3D linux_kernel_version(args.cc) > + linux_version_headers =3D glibcsyscalls.linux_kernel_version(args.= cc) > linux_version_glibc =3D (5, 4) > sys.exit(glibcextract.compare_macro_consts( > '#define _GNU_SOURCE 1\n' OK. > diff --git a/sysdeps/unix/sysv/linux/update-syscall-lists.py b/sysdeps/= unix/sysv/linux/update-syscall-lists.py > new file mode 100644 > index 0000000000..6695583276 > --- /dev/null > +++ b/sysdeps/unix/sysv/linux/update-syscall-lists.py > @@ -0,0 +1,66 @@ > +#!/usr/bin/python3 > +# Recreate and update syscall-names.list. s/Recreate/Regenerate/ > +# Copyright (C) 2019 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 > +# . > + > +import argparse > +import os > +import sys > + > +import glibcextract > +import glibcsyscalls > + > +def main(): > + """The main entry point.""" > + parser =3D argparse.ArgumentParser( > + description=3D"System call list consistency checks") > + parser.add_argument('--cc', metavar=3D'CC', required=3DTrue, > + help=3D'C compiler (including options) to use'= ) > + parser.add_argument('arch_syscall', metavar=3D'ARCH-SYSCALL-H', > + help=3D'The file to update') > + parser.add_argument('names_list', metavar=3D'SYSCALL-NAMES-LIST', > + help=3D'The syscall name list to update ') > + > + args =3D parser.parse_args() > + > + kernel_constants =3D glibcsyscalls.kernel_constants(args.cc) > + > + # Replace with data derived from kernel headers. > + # No merging is necessary here. Arch-specific changes should go > + # into . > + with open(args.arch_syscall, "r+") as out: > + os.lockf(out.fileno(), os.F_LOCK, 0) > + out.truncate() > + for name, value in sorted(kernel_constants.items()): > + out.write("#define __NR_{} {}\n".format(name, value)) > + > + # Merge the architecture-specific system call names into the > + # global names list, syscall-names.list. This file contains names > + # from other architectures (and comments), so it is necessary to > + # merge the existing files with the names obtained from the > + # kernel. > + with open(args.names_list, "r+") as list_file: > + os.lockf(list_file.fileno(), os.F_LOCK, 0) > + names_list =3D glibcsyscalls.SyscallNamesList(list_file) > + merged =3D names_list.merge(kernel_constants.keys()) > + list_file.truncate() > + list_file.seek(0) > + for line in merged: > + list_file.write(line) I think the cleaner way would be to write out the output as a temp first and then rename over the old file. This ought to replicate what we do in Makefiles. > + > +if __name__ =3D=3D '__main__': > + main() Siddhesh