mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-29 05:51:10 +00:00
cb7be1590e
This patch eliminates the gen-py-const.awk variant of gen-as-const, switching to use of gnu-as-const.py (with a new --python option) to process .pysym files (i.e., to generate nptl_lock_constants.py), as the syntax of those files is identical to that of .sym files. Note that the generated nptl_lock_constants.py is *not* identical to the version generated by the awk script. Apart from the trivial changes (comment referencing the new script, and output being sorted), the constant FUTEX_WAITERS, PTHREAD_MUTEXATTR_FLAG_BITS, PTHREAD_MUTEXATTR_FLAG_PSHARED and PTHREAD_MUTEX_PRIO_CEILING_MASK are now output as positive rather than negative constants (on x86_64 anyway; maybe not necessarily on 32-bit systems): < FUTEX_WAITERS = -2147483648 --- > FUTEX_WAITERS = 2147483648 < PTHREAD_MUTEXATTR_FLAG_BITS = -251662336 < PTHREAD_MUTEXATTR_FLAG_PSHARED = -2147483648 --- > PTHREAD_MUTEXATTR_FLAG_BITS = 4043304960 > PTHREAD_MUTEXATTR_FLAG_PSHARED = 2147483648 < PTHREAD_MUTEX_PRIO_CEILING_MASK = -524288 --- > PTHREAD_MUTEX_PRIO_CEILING_MASK = 4294443008 This is because gen-as-const has a cast of the constant value to long int, which gen-py-const lacks. I think the positive values are more logically correct, since the constants in question are in fact unsigned in C. But to reliably produce gen-as-const.py output for constants that always (in C and Python) reflects the signedness of values with the high bit of "long int" set would mean more complicated logic needs to be used in computing values. The more correct positive values by themselves produce a failure of nptl/test-mutexattr-printers, because masking with ~PTHREAD_MUTEXATTR_FLAG_BITS & ~PTHREAD_MUTEX_NO_ELISION_NP now leaves a bit -1 << 32 in the Python value, resulting in a KeyError exception. To avoid that, places masking with ~ of one of the constants in question are changed to mask with 0xffffffff as well (this reflects how ~ in Python applies to an infinite-precision integer whereas ~ in C does not do any promotions beyond the width of int). Tested for x86_64. * scripts/gen-as-const.py (main): Handle --python option. * scripts/gen-py-const.awk: Remove. * Makerules (py-const-script): Use gen-as-const.py. ($(py-const)): Likewise. * nptl/nptl-printers.py (MutexPrinter.read_status_no_robust): Mask with 0xffffffff together with ~(PTHREAD_MUTEX_PRIO_CEILING_MASK). (MutexAttributesPrinter.read_values): Mask with 0xffffffff together with ~PTHREAD_MUTEXATTR_FLAG_BITS and ~PTHREAD_MUTEX_NO_ELISION_NP. * manual/README.pretty-printers: Update reference to gen-py-const.awk.
121 lines
4.5 KiB
Python
121 lines
4.5 KiB
Python
#!/usr/bin/python3
|
|
# Produce headers of assembly constants from C expressions.
|
|
# Copyright (C) 2018 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/>.
|
|
|
|
# The input to this script looks like:
|
|
# #cpp-directive ...
|
|
# NAME1
|
|
# NAME2 expression ...
|
|
# A line giving just a name implies an expression consisting of just that name.
|
|
|
|
import argparse
|
|
|
|
import glibcextract
|
|
|
|
|
|
def gen_test(sym_data):
|
|
"""Generate a test for the values of some C constants.
|
|
|
|
The first argument is as for glibcextract.compute_c_consts.
|
|
|
|
"""
|
|
out_lines = []
|
|
for arg in sym_data:
|
|
if isinstance(arg, str):
|
|
if arg == 'START':
|
|
out_lines.append('#include <stdint.h>\n'
|
|
'#include <stdio.h>\n'
|
|
'#include <bits/wordsize.h>\n'
|
|
'#if __WORDSIZE == 64\n'
|
|
'typedef uint64_t c_t;\n'
|
|
'# define U(n) UINT64_C (n)\n'
|
|
'#else\n'
|
|
'typedef uint32_t c_t;\n'
|
|
'# define U(n) UINT32_C (n)\n'
|
|
'#endif\n'
|
|
'static int\n'
|
|
'do_test (void)\n'
|
|
'{\n'
|
|
# Compilation test only, using static
|
|
# assertions.
|
|
' return 0;\n'
|
|
'}\n'
|
|
'#include <support/test-driver.c>')
|
|
else:
|
|
out_lines.append(arg)
|
|
continue
|
|
name = arg[0]
|
|
value = arg[1]
|
|
out_lines.append('_Static_assert (U (asconst_%s) == (c_t) (%s), '
|
|
'"value of %s");'
|
|
% (name, value, name))
|
|
return '\n'.join(out_lines)
|
|
|
|
|
|
def main():
|
|
"""The main entry point."""
|
|
parser = argparse.ArgumentParser(
|
|
description='Produce headers of assembly constants.')
|
|
parser.add_argument('--cc', metavar='CC',
|
|
help='C compiler (including options) to use')
|
|
parser.add_argument('--test', action='store_true',
|
|
help='Generate test case instead of header')
|
|
parser.add_argument('--python', action='store_true',
|
|
help='Generate Python file instead of header')
|
|
parser.add_argument('sym_file',
|
|
help='.sym file to process')
|
|
args = parser.parse_args()
|
|
sym_data = []
|
|
with open(args.sym_file, 'r') as sym_file:
|
|
started = False
|
|
for line in sym_file:
|
|
line = line.strip()
|
|
if line == '':
|
|
continue
|
|
# Pass preprocessor directives through.
|
|
if line.startswith('#'):
|
|
sym_data.append(line)
|
|
continue
|
|
words = line.split(maxsplit=1)
|
|
if not started:
|
|
sym_data.append('START')
|
|
started = True
|
|
# Separator.
|
|
if words[0] == '--':
|
|
continue
|
|
name = words[0]
|
|
value = words[1] if len(words) > 1 else words[0]
|
|
sym_data.append((name, value))
|
|
if not started:
|
|
sym_data.append('START')
|
|
if args.test:
|
|
print(gen_test(sym_data))
|
|
elif args.python:
|
|
consts = glibcextract.compute_c_consts(sym_data, args.cc)
|
|
print('# GENERATED FILE\n'
|
|
'\n'
|
|
'# Constant definitions.\n'
|
|
'# See gen-as-const.py for details.\n')
|
|
print(''.join('%s = %s\n' % c for c in sorted(consts.items())), end='')
|
|
else:
|
|
consts = glibcextract.compute_c_consts(sym_data, args.cc)
|
|
print(''.join('#define %s %s\n' % c for c in sorted(consts.items())), end='')
|
|
|
|
if __name__ == '__main__':
|
|
main()
|