forked from rpms/glibc
import glibc-2.28-220.el8
This commit is contained in:
parent
ee9c4ccfc2
commit
cc1cae06b4
27
SOURCES/glibc-rh2109510-1.patch
Normal file
27
SOURCES/glibc-rh2109510-1.patch
Normal file
@ -0,0 +1,27 @@
|
||||
commit 97f8225d22ef727ae9935cc231643efdc430d530
|
||||
Author: Zack Weinberg <zackw@panix.com>
|
||||
Date: Thu Mar 14 09:44:22 2019 -0400
|
||||
|
||||
scripts/check-obsolete-constructs.py: Process all headers as UTF-8.
|
||||
|
||||
A few of our installed headers contain UTF-8 in comments.
|
||||
check-obsolete-constructs opened files without explicitly specifying
|
||||
their encoding, so it would barf on these headers if “make check” was
|
||||
run in a non-UTF-8 locale.
|
||||
|
||||
* scripts/check-obsolete-constructs.py (HeaderChecker.check):
|
||||
Specify encoding="utf-8" when opening headers to check.
|
||||
|
||||
diff --git a/scripts/check-obsolete-constructs.py b/scripts/check-obsolete-constructs.py
|
||||
index ce5c72251f4d7cc0..89d21dea6e788783 100755
|
||||
--- a/scripts/check-obsolete-constructs.py
|
||||
+++ b/scripts/check-obsolete-constructs.py
|
||||
@@ -437,7 +437,7 @@ class HeaderChecker:
|
||||
def check(self, fname):
|
||||
self.fname = fname
|
||||
try:
|
||||
- with open(fname, "rt") as fp:
|
||||
+ with open(fname, "rt", encoding="utf-8") as fp:
|
||||
contents = fp.read()
|
||||
except OSError as e:
|
||||
sys.stderr.write("{}: {}\n".format(fname, e.strerror))
|
1449
SOURCES/glibc-rh2109510-10.patch
Normal file
1449
SOURCES/glibc-rh2109510-10.patch
Normal file
File diff suppressed because it is too large
Load Diff
409
SOURCES/glibc-rh2109510-11.patch
Normal file
409
SOURCES/glibc-rh2109510-11.patch
Normal file
@ -0,0 +1,409 @@
|
||||
commit 198abcbb94618730dae1b3f4393efaa49e0ec8c7
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Apr 11 11:30:31 2022 +0200
|
||||
|
||||
Default to --with-default-link=no (bug 25812)
|
||||
|
||||
This is necessary to place the libio vtables into the RELRO segment.
|
||||
New tests elf/tst-relro-ldso and elf/tst-relro-libc are added to
|
||||
verify that this is what actually happens.
|
||||
|
||||
The new tests fail on ia64 due to lack of (default) RELRO support
|
||||
inbutils, so they are XFAILed there.
|
||||
|
||||
Conflicts:
|
||||
elf/Makefile
|
||||
(missing valgrind smoke test)
|
||||
|
||||
diff --git a/INSTALL b/INSTALL
|
||||
index b3a4370f592c5047..b69672b283c0b774 100644
|
||||
--- a/INSTALL
|
||||
+++ b/INSTALL
|
||||
@@ -90,6 +90,12 @@ if 'CFLAGS' is specified it must enable optimization. For example:
|
||||
library will still be usable, but functionality may be lost--for
|
||||
example, you can't build a shared libc with old binutils.
|
||||
|
||||
+'--with-default-link=FLAG'
|
||||
+ With '--with-default-link=yes', the build system does not use a
|
||||
+ custom linker script for linking shared objects. The default for
|
||||
+ FLAG is the opposite, 'no', because the custom linker script is
|
||||
+ needed for full RELRO protection.
|
||||
+
|
||||
'--with-nonshared-cflags=CFLAGS'
|
||||
Use additional compiler flags CFLAGS to build the parts of the
|
||||
library which are always statically linked into applications and
|
||||
diff --git a/configure b/configure
|
||||
index 8b3681d2e28310c8..c794cea4359b3da3 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -3339,7 +3339,7 @@ fi
|
||||
if test "${with_default_link+set}" = set; then :
|
||||
withval=$with_default_link; use_default_link=$withval
|
||||
else
|
||||
- use_default_link=default
|
||||
+ use_default_link=no
|
||||
fi
|
||||
|
||||
|
||||
@@ -5965,69 +5965,6 @@ fi
|
||||
$as_echo "$libc_cv_hashstyle" >&6; }
|
||||
|
||||
|
||||
-# The linker's default -shared behavior is good enough if it
|
||||
-# does these things that our custom linker scripts ensure that
|
||||
-# all allocated NOTE sections come first.
|
||||
-if test "$use_default_link" = default; then
|
||||
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sufficient default -shared layout" >&5
|
||||
-$as_echo_n "checking for sufficient default -shared layout... " >&6; }
|
||||
-if ${libc_cv_use_default_link+:} false; then :
|
||||
- $as_echo_n "(cached) " >&6
|
||||
-else
|
||||
- libc_cv_use_default_link=no
|
||||
- cat > conftest.s <<\EOF
|
||||
- .section .note.a,"a",%note
|
||||
- .balign 4
|
||||
- .long 4,4,9
|
||||
- .string "GNU"
|
||||
- .string "foo"
|
||||
- .section .note.b,"a",%note
|
||||
- .balign 4
|
||||
- .long 4,4,9
|
||||
- .string "GNU"
|
||||
- .string "bar"
|
||||
-EOF
|
||||
- if { ac_try=' ${CC-cc} $ASFLAGS -shared -o conftest.so conftest.s 1>&5'
|
||||
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
|
||||
- (eval $ac_try) 2>&5
|
||||
- ac_status=$?
|
||||
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
- test $ac_status = 0; }; } &&
|
||||
- ac_try=`$READELF -S conftest.so | sed -n \
|
||||
- '${x;p;}
|
||||
- s/^ *\[ *[1-9][0-9]*\] *\([^ ][^ ]*\) *\([^ ][^ ]*\) .*$/\2 \1/
|
||||
- t a
|
||||
- b
|
||||
- : a
|
||||
- H'`
|
||||
- then
|
||||
- libc_seen_a=no libc_seen_b=no
|
||||
- set -- $ac_try
|
||||
- while test $# -ge 2 -a "$1" = NOTE; do
|
||||
- case "$2" in
|
||||
- .note.a) libc_seen_a=yes ;;
|
||||
- .note.b) libc_seen_b=yes ;;
|
||||
- esac
|
||||
- shift 2
|
||||
- done
|
||||
- case "$libc_seen_a$libc_seen_b" in
|
||||
- yesyes)
|
||||
- libc_cv_use_default_link=yes
|
||||
- ;;
|
||||
- *)
|
||||
- echo >&5 "\
|
||||
-$libc_seen_a$libc_seen_b from:
|
||||
-$ac_try"
|
||||
- ;;
|
||||
- esac
|
||||
- fi
|
||||
- rm -f conftest*
|
||||
-fi
|
||||
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_use_default_link" >&5
|
||||
-$as_echo "$libc_cv_use_default_link" >&6; }
|
||||
- use_default_link=$libc_cv_use_default_link
|
||||
-fi
|
||||
-
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GLOB_DAT reloc" >&5
|
||||
$as_echo_n "checking for GLOB_DAT reloc... " >&6; }
|
||||
if ${libc_cv_has_glob_dat+:} false; then :
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 82d9ab2fb67145bb..52429d82344954b3 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -152,7 +152,7 @@ AC_ARG_WITH([default-link],
|
||||
AC_HELP_STRING([--with-default-link],
|
||||
[do not use explicit linker scripts]),
|
||||
[use_default_link=$withval],
|
||||
- [use_default_link=default])
|
||||
+ [use_default_link=no])
|
||||
|
||||
dnl Additional build flags injection.
|
||||
AC_ARG_WITH([nonshared-cflags],
|
||||
@@ -1352,59 +1352,6 @@ fi
|
||||
rm -f conftest*])
|
||||
AC_SUBST(libc_cv_hashstyle)
|
||||
|
||||
-# The linker's default -shared behavior is good enough if it
|
||||
-# does these things that our custom linker scripts ensure that
|
||||
-# all allocated NOTE sections come first.
|
||||
-if test "$use_default_link" = default; then
|
||||
- AC_CACHE_CHECK([for sufficient default -shared layout],
|
||||
- libc_cv_use_default_link, [dnl
|
||||
- libc_cv_use_default_link=no
|
||||
- cat > conftest.s <<\EOF
|
||||
- .section .note.a,"a",%note
|
||||
- .balign 4
|
||||
- .long 4,4,9
|
||||
- .string "GNU"
|
||||
- .string "foo"
|
||||
- .section .note.b,"a",%note
|
||||
- .balign 4
|
||||
- .long 4,4,9
|
||||
- .string "GNU"
|
||||
- .string "bar"
|
||||
-EOF
|
||||
- if AC_TRY_COMMAND([dnl
|
||||
- ${CC-cc} $ASFLAGS -shared -o conftest.so conftest.s 1>&AS_MESSAGE_LOG_FD]) &&
|
||||
- ac_try=`$READELF -S conftest.so | sed -n \
|
||||
- ['${x;p;}
|
||||
- s/^ *\[ *[1-9][0-9]*\] *\([^ ][^ ]*\) *\([^ ][^ ]*\) .*$/\2 \1/
|
||||
- t a
|
||||
- b
|
||||
- : a
|
||||
- H']`
|
||||
- then
|
||||
- libc_seen_a=no libc_seen_b=no
|
||||
- set -- $ac_try
|
||||
- while test $# -ge 2 -a "$1" = NOTE; do
|
||||
- case "$2" in
|
||||
- .note.a) libc_seen_a=yes ;;
|
||||
- .note.b) libc_seen_b=yes ;;
|
||||
- esac
|
||||
- shift 2
|
||||
- done
|
||||
- case "$libc_seen_a$libc_seen_b" in
|
||||
- yesyes)
|
||||
- libc_cv_use_default_link=yes
|
||||
- ;;
|
||||
- *)
|
||||
- echo >&AS_MESSAGE_LOG_FD "\
|
||||
-$libc_seen_a$libc_seen_b from:
|
||||
-$ac_try"
|
||||
- ;;
|
||||
- esac
|
||||
- fi
|
||||
- rm -f conftest*])
|
||||
- use_default_link=$libc_cv_use_default_link
|
||||
-fi
|
||||
-
|
||||
AC_CACHE_CHECK(for GLOB_DAT reloc,
|
||||
libc_cv_has_glob_dat, [dnl
|
||||
cat > conftest.c <<EOF
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 89ce4f5196e5eb39..1fdf40cbd49e233e 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -477,6 +477,40 @@ tests-execstack-yes = \
|
||||
# tests-execstack-yes
|
||||
endif
|
||||
endif
|
||||
+
|
||||
+tests-special += $(objpfx)tst-relro-ldso.out $(objpfx)tst-relro-libc.out
|
||||
+$(objpfx)tst-relro-ldso.out: tst-relro-symbols.py $(..)/scripts/glibcelf.py \
|
||||
+ $(objpfx)ld.so
|
||||
+ $(PYTHON) tst-relro-symbols.py $(objpfx)ld.so \
|
||||
+ --required=_rtld_global_ro \
|
||||
+ > $@ 2>&1; $(evaluate-test)
|
||||
+# The optional symbols are present in libc only if the architecture has
|
||||
+# the GLIBC_2.0 symbol set in libc.
|
||||
+$(objpfx)tst-relro-libc.out: tst-relro-symbols.py $(..)/scripts/glibcelf.py \
|
||||
+ $(common-objpfx)libc.so
|
||||
+ $(PYTHON) tst-relro-symbols.py $(common-objpfx)libc.so \
|
||||
+ --required=_IO_cookie_jumps \
|
||||
+ --required=_IO_file_jumps \
|
||||
+ --required=_IO_file_jumps_maybe_mmap \
|
||||
+ --required=_IO_file_jumps_mmap \
|
||||
+ --required=_IO_helper_jumps \
|
||||
+ --required=_IO_mem_jumps \
|
||||
+ --required=_IO_obstack_jumps \
|
||||
+ --required=_IO_proc_jumps \
|
||||
+ --required=_IO_str_chk_jumps \
|
||||
+ --required=_IO_str_jumps \
|
||||
+ --required=_IO_strn_jumps \
|
||||
+ --required=_IO_wfile_jumps \
|
||||
+ --required=_IO_wfile_jumps_maybe_mmap \
|
||||
+ --required=_IO_wfile_jumps_mmap \
|
||||
+ --required=_IO_wmem_jumps \
|
||||
+ --required=_IO_wstr_jumps \
|
||||
+ --required=_IO_wstrn_jumps \
|
||||
+ --optional=_IO_old_cookie_jumps \
|
||||
+ --optional=_IO_old_file_jumps \
|
||||
+ --optional=_IO_old_proc_jumps \
|
||||
+ > $@ 2>&1; $(evaluate-test)
|
||||
+
|
||||
tests += $(tests-execstack-$(have-z-execstack))
|
||||
ifeq ($(run-built-tests),yes)
|
||||
tests-special += \
|
||||
diff --git a/elf/tst-relro-symbols.py b/elf/tst-relro-symbols.py
|
||||
new file mode 100644
|
||||
index 0000000000000000..368ea3349f86bd81
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-relro-symbols.py
|
||||
@@ -0,0 +1,137 @@
|
||||
+#!/usr/bin/python3
|
||||
+# Verify that certain symbols are covered by RELRO.
|
||||
+# Copyright (C) 2022 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
|
||||
+# <https://www.gnu.org/licenses/>.
|
||||
+
|
||||
+"""Analyze a (shared) object to verify that certain symbols are
|
||||
+present and covered by the PT_GNU_RELRO segment.
|
||||
+
|
||||
+"""
|
||||
+
|
||||
+import argparse
|
||||
+import os.path
|
||||
+import sys
|
||||
+
|
||||
+# Make available glibc Python modules.
|
||||
+sys.path.append(os.path.join(
|
||||
+ os.path.dirname(os.path.realpath(__file__)), os.path.pardir, 'scripts'))
|
||||
+
|
||||
+import glibcelf
|
||||
+
|
||||
+def find_relro(path: str, img: glibcelf.Image) -> (int, int):
|
||||
+ """Discover the address range of the PT_GNU_RELRO segment."""
|
||||
+ for phdr in img.phdrs():
|
||||
+ if phdr.p_type == glibcelf.Pt.PT_GNU_RELRO:
|
||||
+ # The computation is not entirely accurate because
|
||||
+ # _dl_protect_relro in elf/dl-reloc.c rounds both the
|
||||
+ # start end and downwards using the run-time page size.
|
||||
+ return phdr.p_vaddr, phdr.p_vaddr + phdr.p_memsz
|
||||
+ sys.stdout.write('{}: error: no PT_GNU_RELRO segment\n'.format(path))
|
||||
+ sys.exit(1)
|
||||
+
|
||||
+def check_in_relro(kind, relro_begin, relro_end, name, start, size, error):
|
||||
+ """Check if a section or symbol falls within in the RELRO segment."""
|
||||
+ end = start + size - 1
|
||||
+ if not (relro_begin <= start < end < relro_end):
|
||||
+ error(
|
||||
+ '{} {!r} of size {} at 0x{:x} is not in RELRO range [0x{:x}, 0x{:x})'.format(
|
||||
+ kind, name.decode('UTF-8'), start, size,
|
||||
+ relro_begin, relro_end))
|
||||
+
|
||||
+def get_parser():
|
||||
+ """Return an argument parser for this script."""
|
||||
+ parser = argparse.ArgumentParser(description=__doc__)
|
||||
+ parser.add_argument('object', help='path to object file to check')
|
||||
+ parser.add_argument('--required', metavar='NAME', default=(),
|
||||
+ help='required symbol names', nargs='*')
|
||||
+ parser.add_argument('--optional', metavar='NAME', default=(),
|
||||
+ help='required symbol names', nargs='*')
|
||||
+ return parser
|
||||
+
|
||||
+def main(argv):
|
||||
+ """The main entry point."""
|
||||
+ parser = get_parser()
|
||||
+ opts = parser.parse_args(argv)
|
||||
+ img = glibcelf.Image.readfile(opts.object)
|
||||
+
|
||||
+ required_symbols = frozenset([sym.encode('UTF-8')
|
||||
+ for sym in opts.required])
|
||||
+ optional_symbols = frozenset([sym.encode('UTF-8')
|
||||
+ for sym in opts.optional])
|
||||
+ check_symbols = required_symbols | optional_symbols
|
||||
+
|
||||
+ # Tracks the symbols in check_symbols that have been found.
|
||||
+ symbols_found = set()
|
||||
+
|
||||
+ # Discover the extent of the RELRO segment.
|
||||
+ relro_begin, relro_end = find_relro(opts.object, img)
|
||||
+ symbol_table_found = False
|
||||
+
|
||||
+ errors = False
|
||||
+ def error(msg: str) -> None:
|
||||
+ """Record an error condition and write a message to standard output."""
|
||||
+ nonlocal errors
|
||||
+ errors = True
|
||||
+ sys.stdout.write('{}: error: {}\n'.format(opts.object, msg))
|
||||
+
|
||||
+ # Iterate over section headers to find the symbol table.
|
||||
+ for shdr in img.shdrs():
|
||||
+ if shdr.sh_type == glibcelf.Sht.SHT_SYMTAB:
|
||||
+ symbol_table_found = True
|
||||
+ for sym in img.syms(shdr):
|
||||
+ if sym.st_name in check_symbols:
|
||||
+ symbols_found.add(sym.st_name)
|
||||
+
|
||||
+ # Validate symbol type, section, and size.
|
||||
+ if sym.st_info.type != glibcelf.Stt.STT_OBJECT:
|
||||
+ error('symbol {!r} has wrong type {}'.format(
|
||||
+ sym.st_name.decode('UTF-8'), sym.st_info.type))
|
||||
+ if sym.st_shndx in glibcelf.Shn:
|
||||
+ error('symbol {!r} has reserved section {}'.format(
|
||||
+ sym.st_name.decode('UTF-8'), sym.st_shndx))
|
||||
+ continue
|
||||
+ if sym.st_size == 0:
|
||||
+ error('symbol {!r} has size zero'.format(
|
||||
+ sym.st_name.decode('UTF-8')))
|
||||
+ continue
|
||||
+
|
||||
+ check_in_relro('symbol', relro_begin, relro_end,
|
||||
+ sym.st_name, sym.st_value, sym.st_size,
|
||||
+ error)
|
||||
+ continue # SHT_SYMTAB
|
||||
+ if shdr.sh_name == b'.data.rel.ro' \
|
||||
+ or shdr.sh_name.startswith(b'.data.rel.ro.'):
|
||||
+ check_in_relro('section', relro_begin, relro_end,
|
||||
+ shdr.sh_name, shdr.sh_addr, shdr.sh_size,
|
||||
+ error)
|
||||
+ continue
|
||||
+
|
||||
+ if required_symbols - symbols_found:
|
||||
+ for sym in sorted(required_symbols - symbols_found):
|
||||
+ error('symbol {!r} not found'.format(sym.decode('UTF-8')))
|
||||
+
|
||||
+ if errors:
|
||||
+ sys.exit(1)
|
||||
+
|
||||
+ if not symbol_table_found:
|
||||
+ sys.stdout.write(
|
||||
+ '{}: warning: no symbol table found (stripped object)\n'.format(
|
||||
+ opts.object))
|
||||
+ sys.exit(77)
|
||||
+
|
||||
+if __name__ == '__main__':
|
||||
+ main(sys.argv[1:])
|
||||
diff --git a/manual/install.texi b/manual/install.texi
|
||||
index c262fd56d0cef67b..a2c43bd692de7825 100644
|
||||
--- a/manual/install.texi
|
||||
+++ b/manual/install.texi
|
||||
@@ -117,6 +117,12 @@ problem and suppress these constructs, so that the library will still be
|
||||
usable, but functionality may be lost---for example, you can't build a
|
||||
shared libc with old binutils.
|
||||
|
||||
+@item --with-default-link=@var{FLAG}
|
||||
+With @code{--with-default-link=yes}, the build system does not use a
|
||||
+custom linker script for linking shared objects. The default for
|
||||
+@var{FLAG} is the opposite, @samp{no}, because the custom linker script
|
||||
+is needed for full RELRO protection.
|
||||
+
|
||||
@item --with-nonshared-cflags=@var{cflags}
|
||||
Use additional compiler flags @var{cflags} to build the parts of the
|
||||
library which are always statically linked into applications and
|
||||
diff --git a/sysdeps/unix/sysv/linux/ia64/Makefile b/sysdeps/unix/sysv/linux/ia64/Makefile
|
||||
index 97fc7df0b122d6a0..b1ad1ab7b1efa34c 100644
|
||||
--- a/sysdeps/unix/sysv/linux/ia64/Makefile
|
||||
+++ b/sysdeps/unix/sysv/linux/ia64/Makefile
|
||||
@@ -1,3 +1,9 @@
|
||||
+ifeq ($(subdir),elf)
|
||||
+# ia64 does not support PT_GNU_RELRO.
|
||||
+test-xfail-tst-relro-ldso = yes
|
||||
+test-xfail-tst-relro-libc = yes
|
||||
+endif
|
||||
+
|
||||
ifeq ($(subdir),misc)
|
||||
sysdep_headers += sys/rse.h
|
||||
endif
|
26
SOURCES/glibc-rh2109510-12.patch
Normal file
26
SOURCES/glibc-rh2109510-12.patch
Normal file
@ -0,0 +1,26 @@
|
||||
commit b571f3adffdcbed23f35ea39b0ca43809dbb4f5b
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Apr 22 19:34:52 2022 +0200
|
||||
|
||||
scripts/glibcelf.py: Mark as UNSUPPORTED on Python 3.5 and earlier
|
||||
|
||||
enum.IntFlag and enum.EnumMeta._missing_ support are not part of
|
||||
earlier Python versions.
|
||||
|
||||
diff --git a/scripts/glibcelf.py b/scripts/glibcelf.py
|
||||
index 8f7d0ca184845714..da0d5380f33a195e 100644
|
||||
--- a/scripts/glibcelf.py
|
||||
+++ b/scripts/glibcelf.py
|
||||
@@ -28,6 +28,12 @@ import collections
|
||||
import enum
|
||||
import struct
|
||||
|
||||
+if not hasattr(enum, 'IntFlag'):
|
||||
+ import sys
|
||||
+ sys.stdout.write(
|
||||
+ 'warning: glibcelf.py needs Python 3.6 for enum support\n')
|
||||
+ sys.exit(77)
|
||||
+
|
||||
class _OpenIntEnum(enum.IntEnum):
|
||||
"""Integer enumeration that supports arbitrary int values."""
|
||||
@classmethod
|
30
SOURCES/glibc-rh2109510-13.patch
Normal file
30
SOURCES/glibc-rh2109510-13.patch
Normal file
@ -0,0 +1,30 @@
|
||||
Partial backport of the scripts/glibcelf.py part of:
|
||||
|
||||
commit 4610b24f5e4e6d2c4b769594efa6d460943163bb
|
||||
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||
Date: Tue Mar 29 14:08:54 2022 -0700
|
||||
|
||||
elf: Define DT_RELR related macros and types
|
||||
|
||||
diff --git a/scripts/glibcelf.py b/scripts/glibcelf.py
|
||||
index da0d5380f33a195e..f847b36c55c15b8a 100644
|
||||
--- a/scripts/glibcelf.py
|
||||
+++ b/scripts/glibcelf.py
|
||||
@@ -304,6 +304,7 @@ class Sht(_OpenIntEnum):
|
||||
SHT_PREINIT_ARRAY = 16
|
||||
SHT_GROUP = 17
|
||||
SHT_SYMTAB_SHNDX = 18
|
||||
+ SHT_RELR = 19
|
||||
SHT_GNU_ATTRIBUTES = 0x6ffffff5
|
||||
SHT_GNU_HASH = 0x6ffffff6
|
||||
SHT_GNU_LIBLIST = 0x6ffffff7
|
||||
@@ -593,6 +594,9 @@ class Dt(_OpenIntEnum):
|
||||
DT_PREINIT_ARRAY = 32
|
||||
DT_PREINIT_ARRAYSZ = 33
|
||||
DT_SYMTAB_SHNDX = 34
|
||||
+ DT_RELRSZ = 35
|
||||
+ DT_RELR = 36
|
||||
+ DT_RELRENT = 37
|
||||
DT_GNU_PRELINKED = 0x6ffffdf5
|
||||
DT_GNU_CONFLICTSZ = 0x6ffffdf6
|
||||
DT_GNU_LIBLISTSZ = 0x6ffffdf7
|
50
SOURCES/glibc-rh2109510-14.patch
Normal file
50
SOURCES/glibc-rh2109510-14.patch
Normal file
@ -0,0 +1,50 @@
|
||||
commit d055481ce39d03652ac60de5078889e15b6917ff
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon May 16 21:59:24 2022 +0200
|
||||
|
||||
scripts/glibcelf.py: Add *T_RISCV_* constants
|
||||
|
||||
SHT_RISCV_ATTRIBUTES, PT_RISCV_ATTRIBUTES, DT_RISCV_VARIANT_CC were
|
||||
added in commit 0b6c6750732483b4d59c2fcb45484079cd84157d
|
||||
("Update RISC-V specific ELF definitions"). This caused the
|
||||
elf/tst-glibcelf consistency check to fail.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/scripts/glibcelf.py b/scripts/glibcelf.py
|
||||
index f847b36c55c15b8a..07bef940433b4c99 100644
|
||||
--- a/scripts/glibcelf.py
|
||||
+++ b/scripts/glibcelf.py
|
||||
@@ -385,6 +385,10 @@ class ShtPARISC(enum.Enum):
|
||||
SHT_PARISC_UNWIND = 0x70000001
|
||||
SHT_PARISC_DOC = 0x70000002
|
||||
|
||||
+class ShtRISCV(enum.Enum):
|
||||
+ """Supplemental SHT_* constants for EM_RISCV."""
|
||||
+ SHT_RISCV_ATTRIBUTES = 0x70000003
|
||||
+
|
||||
class Pf(enum.IntFlag):
|
||||
"""Program header flags. Type of Phdr.p_flags values."""
|
||||
PF_X = 1
|
||||
@@ -558,6 +562,10 @@ class PtPARISC(enum.Enum):
|
||||
PT_PARISC_ARCHEXT = 0x70000000
|
||||
PT_PARISC_UNWIND = 0x70000001
|
||||
|
||||
+class PtRISCV(enum.Enum):
|
||||
+ """Supplemental PT_* constants for EM_RISCV."""
|
||||
+ PT_RISCV_ATTRIBUTES = 0x70000003
|
||||
+
|
||||
class Dt(_OpenIntEnum):
|
||||
"""ELF dynamic segment tags. Type of Dyn.d_val."""
|
||||
DT_NULL = 0
|
||||
@@ -710,6 +718,10 @@ class DtPPC64(enum.Enum):
|
||||
DT_PPC64_OPDSZ = 0x70000002
|
||||
DT_PPC64_OPT = 0x70000003
|
||||
|
||||
+class DtRISCV(enum.Enum):
|
||||
+ """Supplemental DT_* constants for EM_RISCV."""
|
||||
+ DT_RISCV_VARIANT_CC = 0x70000001
|
||||
+
|
||||
class DtSPARC(enum.Enum):
|
||||
"""Supplemental DT_* constants for EM_SPARC."""
|
||||
DT_SPARC_REGISTER = 0x70000001
|
26
SOURCES/glibc-rh2109510-15.patch
Normal file
26
SOURCES/glibc-rh2109510-15.patch
Normal file
@ -0,0 +1,26 @@
|
||||
commit 8521001731d6539382fa875f1cac9864c466ef27
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Mon Jun 6 14:41:24 2022 -0300
|
||||
|
||||
scripts/glibcelf.py: Add PT_AARCH64_MEMTAG_MTE constant
|
||||
|
||||
It was added in commit 603e5c8ba7257483c162cabb06eb6f79096429b6.
|
||||
This caused the elf/tst-glibcelf consistency check to fail.
|
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
diff --git a/scripts/glibcelf.py b/scripts/glibcelf.py
|
||||
index 07bef940433b4c99..47f95d07baefb4ae 100644
|
||||
--- a/scripts/glibcelf.py
|
||||
+++ b/scripts/glibcelf.py
|
||||
@@ -523,6 +523,10 @@ class Pt(_OpenIntEnum):
|
||||
PT_SUNWBSS = 0x6ffffffa
|
||||
PT_SUNWSTACK = 0x6ffffffb
|
||||
|
||||
+class PtAARCH64(enum.Enum):
|
||||
+ """Supplemental PT_* constants for EM_AARCH64."""
|
||||
+ PT_AARCH64_MEMTAG_MTE = 0x70000002
|
||||
+
|
||||
class PtARM(enum.Enum):
|
||||
"""Supplemental PT_* constants for EM_ARM."""
|
||||
PT_ARM_EXIDX = 0x70000001
|
22
SOURCES/glibc-rh2109510-16.patch
Normal file
22
SOURCES/glibc-rh2109510-16.patch
Normal file
@ -0,0 +1,22 @@
|
||||
Partial backport of the scripts/glibcelf.py part of:
|
||||
|
||||
commit 2d83247d90c9f0bfee7f3f2505bc1b13b6f36c04
|
||||
Author: caiyinyu <caiyinyu@loongson.cn>
|
||||
Date: Tue Jul 19 09:20:45 2022 +0800
|
||||
|
||||
LoongArch: Add relocations and ELF flags to elf.h and scripts/glibcelf.py
|
||||
|
||||
diff --git a/scripts/glibcelf.py b/scripts/glibcelf.py
|
||||
index 47f95d07baefb4ae..de0509130ed9ad47 100644
|
||||
--- a/scripts/glibcelf.py
|
||||
+++ b/scripts/glibcelf.py
|
||||
@@ -252,7 +252,8 @@ class Machine(_OpenIntEnum):
|
||||
EM_RISCV = 243
|
||||
EM_BPF = 247
|
||||
EM_CSKY = 252
|
||||
- EM_NUM = 253
|
||||
+ EM_LOONGARCH = 258
|
||||
+ EM_NUM = 259
|
||||
EM_ALPHA = 0x9026
|
||||
|
||||
class Et(_OpenIntEnum):
|
78
SOURCES/glibc-rh2109510-17.patch
Normal file
78
SOURCES/glibc-rh2109510-17.patch
Normal file
@ -0,0 +1,78 @@
|
||||
commit bd13cb19f5e15e9e9a92a536e755fd93a97a67f6
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Aug 19 11:16:32 2022 +0200
|
||||
|
||||
scripts/glibcelf.py: Add hashing support
|
||||
|
||||
ELF and GNU hashes can now be computed using the elf_hash and
|
||||
gnu_hash functions.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
Tested-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/elf/tst-glibcelf.py b/elf/tst-glibcelf.py
|
||||
index bf15a3bad4479e08..e5026e2289df206b 100644
|
||||
--- a/elf/tst-glibcelf.py
|
||||
+++ b/elf/tst-glibcelf.py
|
||||
@@ -240,6 +240,24 @@ def check_constant_values(cc):
|
||||
error('{}: glibcelf has {!r}, <elf.h> has {!r}'.format(
|
||||
name, glibcelf_value, elf_h_value))
|
||||
|
||||
+def check_hashes():
|
||||
+ for name, expected_elf, expected_gnu in (
|
||||
+ ('', 0, 0x1505),
|
||||
+ ('PPPPPPPPPPPP', 0, 0x9f105c45),
|
||||
+ ('GLIBC_2.0', 0xd696910, 0xf66c3dd5),
|
||||
+ ('GLIBC_2.34', 0x69691b4, 0xc3f3f90c),
|
||||
+ ('GLIBC_PRIVATE', 0x963cf85, 0x692a260)):
|
||||
+ for convert in (lambda x: x, lambda x: x.encode('UTF-8')):
|
||||
+ name = convert(name)
|
||||
+ actual_elf = glibcelf.elf_hash(name)
|
||||
+ if actual_elf != expected_elf:
|
||||
+ error('elf_hash({!r}): {:x} != 0x{:x}'.format(
|
||||
+ name, actual_elf, expected_elf))
|
||||
+ actual_gnu = glibcelf.gnu_hash(name)
|
||||
+ if actual_gnu != expected_gnu:
|
||||
+ error('gnu_hash({!r}): {:x} != 0x{:x}'.format(
|
||||
+ name, actual_gnu, expected_gnu))
|
||||
+
|
||||
def main():
|
||||
"""The main entry point."""
|
||||
parser = argparse.ArgumentParser(
|
||||
@@ -251,6 +269,7 @@ def main():
|
||||
check_duplicates()
|
||||
check_constant_prefixes()
|
||||
check_constant_values(cc=args.cc)
|
||||
+ check_hashes()
|
||||
|
||||
if errors_encountered > 0:
|
||||
print("note: errors encountered:", errors_encountered)
|
||||
diff --git a/scripts/glibcelf.py b/scripts/glibcelf.py
|
||||
index de0509130ed9ad47..5c8f46f590722384 100644
|
||||
--- a/scripts/glibcelf.py
|
||||
+++ b/scripts/glibcelf.py
|
||||
@@ -1158,5 +1158,24 @@ class Image:
|
||||
self._stringtab[sh_link] = strtab
|
||||
return strtab
|
||||
|
||||
+def elf_hash(s):
|
||||
+ """Computes the ELF hash of the string."""
|
||||
+ acc = 0
|
||||
+ for ch in s:
|
||||
+ if type(ch) is not int:
|
||||
+ ch = ord(ch)
|
||||
+ acc = ((acc << 4) + ch) & 0xffffffff
|
||||
+ top = acc & 0xf0000000
|
||||
+ acc = (acc ^ (top >> 24)) & ~top
|
||||
+ return acc
|
||||
+
|
||||
+def gnu_hash(s):
|
||||
+ """Computes the GNU hash of the string."""
|
||||
+ h = 5381
|
||||
+ for ch in s:
|
||||
+ if type(ch) is not int:
|
||||
+ ch = ord(ch)
|
||||
+ h = (h * 33 + ch) & 0xffffffff
|
||||
+ return h
|
||||
|
||||
__all__ = [name for name in dir() if name[0].isupper()]
|
439
SOURCES/glibc-rh2109510-18.patch
Normal file
439
SOURCES/glibc-rh2109510-18.patch
Normal file
@ -0,0 +1,439 @@
|
||||
commit f40c7887d3cc9bb0b56576ed9edbe505ff8058c0
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu Sep 22 12:10:41 2022 +0200
|
||||
|
||||
scripts: Extract glibcpp.py from check-obsolete-constructs.py
|
||||
|
||||
The C tokenizer is useful separately.
|
||||
|
||||
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
|
||||
diff --git a/scripts/check-obsolete-constructs.py b/scripts/check-obsolete-constructs.py
|
||||
index 89d21dea6e788783..7c7a092e440a3258 100755
|
||||
--- a/scripts/check-obsolete-constructs.py
|
||||
+++ b/scripts/check-obsolete-constructs.py
|
||||
@@ -24,193 +24,14 @@
|
||||
"""
|
||||
|
||||
import argparse
|
||||
-import collections
|
||||
+import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
-# Simplified lexical analyzer for C preprocessing tokens.
|
||||
-# Does not implement trigraphs.
|
||||
-# Does not implement backslash-newline in the middle of any lexical
|
||||
-# item other than a string literal.
|
||||
-# Does not implement universal-character-names in identifiers.
|
||||
-# Treats prefixed strings (e.g. L"...") as two tokens (L and "...")
|
||||
-# Accepts non-ASCII characters only within comments and strings.
|
||||
-
|
||||
-# Caution: The order of the outermost alternation matters.
|
||||
-# STRING must be before BAD_STRING, CHARCONST before BAD_CHARCONST,
|
||||
-# BLOCK_COMMENT before BAD_BLOCK_COM before PUNCTUATOR, and OTHER must
|
||||
-# be last.
|
||||
-# Caution: There should be no capturing groups other than the named
|
||||
-# captures in the outermost alternation.
|
||||
-
|
||||
-# For reference, these are all of the C punctuators as of C11:
|
||||
-# [ ] ( ) { } , ; ? ~
|
||||
-# ! != * *= / /= ^ ^= = ==
|
||||
-# # ##
|
||||
-# % %= %> %: %:%:
|
||||
-# & &= &&
|
||||
-# | |= ||
|
||||
-# + += ++
|
||||
-# - -= -- ->
|
||||
-# . ...
|
||||
-# : :>
|
||||
-# < <% <: << <<= <=
|
||||
-# > >= >> >>=
|
||||
-
|
||||
-# The BAD_* tokens are not part of the official definition of pp-tokens;
|
||||
-# they match unclosed strings, character constants, and block comments,
|
||||
-# so that the regex engine doesn't have to backtrack all the way to the
|
||||
-# beginning of a broken construct and then emit dozens of junk tokens.
|
||||
-
|
||||
-PP_TOKEN_RE_ = re.compile(r"""
|
||||
- (?P<STRING> \"(?:[^\"\\\r\n]|\\(?:[\r\n -~]|\r\n))*\")
|
||||
- |(?P<BAD_STRING> \"(?:[^\"\\\r\n]|\\[ -~])*)
|
||||
- |(?P<CHARCONST> \'(?:[^\'\\\r\n]|\\(?:[\r\n -~]|\r\n))*\')
|
||||
- |(?P<BAD_CHARCONST> \'(?:[^\'\\\r\n]|\\[ -~])*)
|
||||
- |(?P<BLOCK_COMMENT> /\*(?:\*(?!/)|[^*])*\*/)
|
||||
- |(?P<BAD_BLOCK_COM> /\*(?:\*(?!/)|[^*])*\*?)
|
||||
- |(?P<LINE_COMMENT> //[^\r\n]*)
|
||||
- |(?P<IDENT> [_a-zA-Z][_a-zA-Z0-9]*)
|
||||
- |(?P<PP_NUMBER> \.?[0-9](?:[0-9a-df-oq-zA-DF-OQ-Z_.]|[eEpP][+-]?)*)
|
||||
- |(?P<PUNCTUATOR>
|
||||
- [,;?~(){}\[\]]
|
||||
- | [!*/^=]=?
|
||||
- | \#\#?
|
||||
- | %(?:[=>]|:(?:%:)?)?
|
||||
- | &[=&]?
|
||||
- |\|[=|]?
|
||||
- |\+[=+]?
|
||||
- | -[=->]?
|
||||
- |\.(?:\.\.)?
|
||||
- | :>?
|
||||
- | <(?:[%:]|<(?:=|<=?)?)?
|
||||
- | >(?:=|>=?)?)
|
||||
- |(?P<ESCNL> \\(?:\r|\n|\r\n))
|
||||
- |(?P<WHITESPACE> [ \t\n\r\v\f]+)
|
||||
- |(?P<OTHER> .)
|
||||
-""", re.DOTALL | re.VERBOSE)
|
||||
-
|
||||
-HEADER_NAME_RE_ = re.compile(r"""
|
||||
- < [^>\r\n]+ >
|
||||
- | " [^"\r\n]+ "
|
||||
-""", re.DOTALL | re.VERBOSE)
|
||||
-
|
||||
-ENDLINE_RE_ = re.compile(r"""\r|\n|\r\n""")
|
||||
-
|
||||
-# based on the sample code in the Python re documentation
|
||||
-Token_ = collections.namedtuple("Token", (
|
||||
- "kind", "text", "line", "column", "context"))
|
||||
-Token_.__doc__ = """
|
||||
- One C preprocessing token, comment, or chunk of whitespace.
|
||||
- 'kind' identifies the token type, which will be one of:
|
||||
- STRING, CHARCONST, BLOCK_COMMENT, LINE_COMMENT, IDENT,
|
||||
- PP_NUMBER, PUNCTUATOR, ESCNL, WHITESPACE, HEADER_NAME,
|
||||
- or OTHER. The BAD_* alternatives in PP_TOKEN_RE_ are
|
||||
- handled within tokenize_c, below.
|
||||
-
|
||||
- 'text' is the sequence of source characters making up the token;
|
||||
- no decoding whatsoever is performed.
|
||||
-
|
||||
- 'line' and 'column' give the position of the first character of the
|
||||
- token within the source file. They are both 1-based.
|
||||
-
|
||||
- 'context' indicates whether or not this token occurred within a
|
||||
- preprocessing directive; it will be None for running text,
|
||||
- '<null>' for the leading '#' of a directive line (because '#'
|
||||
- all by itself on a line is a "null directive"), or the name of
|
||||
- the directive for tokens within a directive line, starting with
|
||||
- the IDENT for the name itself.
|
||||
-"""
|
||||
-
|
||||
-def tokenize_c(file_contents, reporter):
|
||||
- """Yield a series of Token objects, one for each preprocessing
|
||||
- token, comment, or chunk of whitespace within FILE_CONTENTS.
|
||||
- The REPORTER object is expected to have one method,
|
||||
- reporter.error(token, message), which will be called to
|
||||
- indicate a lexical error at the position of TOKEN.
|
||||
- If MESSAGE contains the four-character sequence '{!r}', that
|
||||
- is expected to be replaced by repr(token.text).
|
||||
- """
|
||||
+# Make available glibc Python modules.
|
||||
+sys.path.append(os.path.dirname(os.path.realpath(__file__)))
|
||||
|
||||
- Token = Token_
|
||||
- PP_TOKEN_RE = PP_TOKEN_RE_
|
||||
- ENDLINE_RE = ENDLINE_RE_
|
||||
- HEADER_NAME_RE = HEADER_NAME_RE_
|
||||
-
|
||||
- line_num = 1
|
||||
- line_start = 0
|
||||
- pos = 0
|
||||
- limit = len(file_contents)
|
||||
- directive = None
|
||||
- at_bol = True
|
||||
- while pos < limit:
|
||||
- if directive == "include":
|
||||
- mo = HEADER_NAME_RE.match(file_contents, pos)
|
||||
- if mo:
|
||||
- kind = "HEADER_NAME"
|
||||
- directive = "after_include"
|
||||
- else:
|
||||
- mo = PP_TOKEN_RE.match(file_contents, pos)
|
||||
- kind = mo.lastgroup
|
||||
- if kind != "WHITESPACE":
|
||||
- directive = "after_include"
|
||||
- else:
|
||||
- mo = PP_TOKEN_RE.match(file_contents, pos)
|
||||
- kind = mo.lastgroup
|
||||
-
|
||||
- text = mo.group()
|
||||
- line = line_num
|
||||
- column = mo.start() - line_start
|
||||
- adj_line_start = 0
|
||||
- # only these kinds can contain a newline
|
||||
- if kind in ("WHITESPACE", "BLOCK_COMMENT", "LINE_COMMENT",
|
||||
- "STRING", "CHARCONST", "BAD_BLOCK_COM", "ESCNL"):
|
||||
- for tmo in ENDLINE_RE.finditer(text):
|
||||
- line_num += 1
|
||||
- adj_line_start = tmo.end()
|
||||
- if adj_line_start:
|
||||
- line_start = mo.start() + adj_line_start
|
||||
-
|
||||
- # Track whether or not we are scanning a preprocessing directive.
|
||||
- if kind == "LINE_COMMENT" or (kind == "WHITESPACE" and adj_line_start):
|
||||
- at_bol = True
|
||||
- directive = None
|
||||
- else:
|
||||
- if kind == "PUNCTUATOR" and text == "#" and at_bol:
|
||||
- directive = "<null>"
|
||||
- elif kind == "IDENT" and directive == "<null>":
|
||||
- directive = text
|
||||
- at_bol = False
|
||||
-
|
||||
- # Report ill-formed tokens and rewrite them as their well-formed
|
||||
- # equivalents, so downstream processing doesn't have to know about them.
|
||||
- # (Rewriting instead of discarding provides better error recovery.)
|
||||
- if kind == "BAD_BLOCK_COM":
|
||||
- reporter.error(Token("BAD_BLOCK_COM", "", line, column+1, ""),
|
||||
- "unclosed block comment")
|
||||
- text += "*/"
|
||||
- kind = "BLOCK_COMMENT"
|
||||
- elif kind == "BAD_STRING":
|
||||
- reporter.error(Token("BAD_STRING", "", line, column+1, ""),
|
||||
- "unclosed string")
|
||||
- text += "\""
|
||||
- kind = "STRING"
|
||||
- elif kind == "BAD_CHARCONST":
|
||||
- reporter.error(Token("BAD_CHARCONST", "", line, column+1, ""),
|
||||
- "unclosed char constant")
|
||||
- text += "'"
|
||||
- kind = "CHARCONST"
|
||||
-
|
||||
- tok = Token(kind, text, line, column+1,
|
||||
- "include" if directive == "after_include" else directive)
|
||||
- # Do not complain about OTHER tokens inside macro definitions.
|
||||
- # $ and @ appear in macros defined by headers intended to be
|
||||
- # included from assembly language, e.g. sysdeps/mips/sys/asm.h.
|
||||
- if kind == "OTHER" and directive != "define":
|
||||
- self.error(tok, "stray {!r} in program")
|
||||
-
|
||||
- yield tok
|
||||
- pos = mo.end()
|
||||
+import glibcpp
|
||||
|
||||
#
|
||||
# Base and generic classes for individual checks.
|
||||
@@ -446,7 +267,7 @@ class HeaderChecker:
|
||||
|
||||
typedef_checker = ObsoleteTypedefChecker(self, self.fname)
|
||||
|
||||
- for tok in tokenize_c(contents, self):
|
||||
+ for tok in glibcpp.tokenize_c(contents, self):
|
||||
typedef_checker.examine(tok)
|
||||
|
||||
def main():
|
||||
diff --git a/scripts/glibcpp.py b/scripts/glibcpp.py
|
||||
new file mode 100644
|
||||
index 0000000000000000..b44c6a4392dde8ce
|
||||
--- /dev/null
|
||||
+++ b/scripts/glibcpp.py
|
||||
@@ -0,0 +1,212 @@
|
||||
+#! /usr/bin/python3
|
||||
+# Approximation to C preprocessing.
|
||||
+# Copyright (C) 2019-2022 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
|
||||
+# <https://www.gnu.org/licenses/>.
|
||||
+
|
||||
+"""
|
||||
+Simplified lexical analyzer for C preprocessing tokens.
|
||||
+
|
||||
+Does not implement trigraphs.
|
||||
+
|
||||
+Does not implement backslash-newline in the middle of any lexical
|
||||
+item other than a string literal.
|
||||
+
|
||||
+Does not implement universal-character-names in identifiers.
|
||||
+
|
||||
+Treats prefixed strings (e.g. L"...") as two tokens (L and "...").
|
||||
+
|
||||
+Accepts non-ASCII characters only within comments and strings.
|
||||
+"""
|
||||
+
|
||||
+import collections
|
||||
+import re
|
||||
+
|
||||
+# Caution: The order of the outermost alternation matters.
|
||||
+# STRING must be before BAD_STRING, CHARCONST before BAD_CHARCONST,
|
||||
+# BLOCK_COMMENT before BAD_BLOCK_COM before PUNCTUATOR, and OTHER must
|
||||
+# be last.
|
||||
+# Caution: There should be no capturing groups other than the named
|
||||
+# captures in the outermost alternation.
|
||||
+
|
||||
+# For reference, these are all of the C punctuators as of C11:
|
||||
+# [ ] ( ) { } , ; ? ~
|
||||
+# ! != * *= / /= ^ ^= = ==
|
||||
+# # ##
|
||||
+# % %= %> %: %:%:
|
||||
+# & &= &&
|
||||
+# | |= ||
|
||||
+# + += ++
|
||||
+# - -= -- ->
|
||||
+# . ...
|
||||
+# : :>
|
||||
+# < <% <: << <<= <=
|
||||
+# > >= >> >>=
|
||||
+
|
||||
+# The BAD_* tokens are not part of the official definition of pp-tokens;
|
||||
+# they match unclosed strings, character constants, and block comments,
|
||||
+# so that the regex engine doesn't have to backtrack all the way to the
|
||||
+# beginning of a broken construct and then emit dozens of junk tokens.
|
||||
+
|
||||
+PP_TOKEN_RE_ = re.compile(r"""
|
||||
+ (?P<STRING> \"(?:[^\"\\\r\n]|\\(?:[\r\n -~]|\r\n))*\")
|
||||
+ |(?P<BAD_STRING> \"(?:[^\"\\\r\n]|\\[ -~])*)
|
||||
+ |(?P<CHARCONST> \'(?:[^\'\\\r\n]|\\(?:[\r\n -~]|\r\n))*\')
|
||||
+ |(?P<BAD_CHARCONST> \'(?:[^\'\\\r\n]|\\[ -~])*)
|
||||
+ |(?P<BLOCK_COMMENT> /\*(?:\*(?!/)|[^*])*\*/)
|
||||
+ |(?P<BAD_BLOCK_COM> /\*(?:\*(?!/)|[^*])*\*?)
|
||||
+ |(?P<LINE_COMMENT> //[^\r\n]*)
|
||||
+ |(?P<IDENT> [_a-zA-Z][_a-zA-Z0-9]*)
|
||||
+ |(?P<PP_NUMBER> \.?[0-9](?:[0-9a-df-oq-zA-DF-OQ-Z_.]|[eEpP][+-]?)*)
|
||||
+ |(?P<PUNCTUATOR>
|
||||
+ [,;?~(){}\[\]]
|
||||
+ | [!*/^=]=?
|
||||
+ | \#\#?
|
||||
+ | %(?:[=>]|:(?:%:)?)?
|
||||
+ | &[=&]?
|
||||
+ |\|[=|]?
|
||||
+ |\+[=+]?
|
||||
+ | -[=->]?
|
||||
+ |\.(?:\.\.)?
|
||||
+ | :>?
|
||||
+ | <(?:[%:]|<(?:=|<=?)?)?
|
||||
+ | >(?:=|>=?)?)
|
||||
+ |(?P<ESCNL> \\(?:\r|\n|\r\n))
|
||||
+ |(?P<WHITESPACE> [ \t\n\r\v\f]+)
|
||||
+ |(?P<OTHER> .)
|
||||
+""", re.DOTALL | re.VERBOSE)
|
||||
+
|
||||
+HEADER_NAME_RE_ = re.compile(r"""
|
||||
+ < [^>\r\n]+ >
|
||||
+ | " [^"\r\n]+ "
|
||||
+""", re.DOTALL | re.VERBOSE)
|
||||
+
|
||||
+ENDLINE_RE_ = re.compile(r"""\r|\n|\r\n""")
|
||||
+
|
||||
+# based on the sample code in the Python re documentation
|
||||
+Token_ = collections.namedtuple("Token", (
|
||||
+ "kind", "text", "line", "column", "context"))
|
||||
+Token_.__doc__ = """
|
||||
+ One C preprocessing token, comment, or chunk of whitespace.
|
||||
+ 'kind' identifies the token type, which will be one of:
|
||||
+ STRING, CHARCONST, BLOCK_COMMENT, LINE_COMMENT, IDENT,
|
||||
+ PP_NUMBER, PUNCTUATOR, ESCNL, WHITESPACE, HEADER_NAME,
|
||||
+ or OTHER. The BAD_* alternatives in PP_TOKEN_RE_ are
|
||||
+ handled within tokenize_c, below.
|
||||
+
|
||||
+ 'text' is the sequence of source characters making up the token;
|
||||
+ no decoding whatsoever is performed.
|
||||
+
|
||||
+ 'line' and 'column' give the position of the first character of the
|
||||
+ token within the source file. They are both 1-based.
|
||||
+
|
||||
+ 'context' indicates whether or not this token occurred within a
|
||||
+ preprocessing directive; it will be None for running text,
|
||||
+ '<null>' for the leading '#' of a directive line (because '#'
|
||||
+ all by itself on a line is a "null directive"), or the name of
|
||||
+ the directive for tokens within a directive line, starting with
|
||||
+ the IDENT for the name itself.
|
||||
+"""
|
||||
+
|
||||
+def tokenize_c(file_contents, reporter):
|
||||
+ """Yield a series of Token objects, one for each preprocessing
|
||||
+ token, comment, or chunk of whitespace within FILE_CONTENTS.
|
||||
+ The REPORTER object is expected to have one method,
|
||||
+ reporter.error(token, message), which will be called to
|
||||
+ indicate a lexical error at the position of TOKEN.
|
||||
+ If MESSAGE contains the four-character sequence '{!r}', that
|
||||
+ is expected to be replaced by repr(token.text).
|
||||
+ """
|
||||
+
|
||||
+ Token = Token_
|
||||
+ PP_TOKEN_RE = PP_TOKEN_RE_
|
||||
+ ENDLINE_RE = ENDLINE_RE_
|
||||
+ HEADER_NAME_RE = HEADER_NAME_RE_
|
||||
+
|
||||
+ line_num = 1
|
||||
+ line_start = 0
|
||||
+ pos = 0
|
||||
+ limit = len(file_contents)
|
||||
+ directive = None
|
||||
+ at_bol = True
|
||||
+ while pos < limit:
|
||||
+ if directive == "include":
|
||||
+ mo = HEADER_NAME_RE.match(file_contents, pos)
|
||||
+ if mo:
|
||||
+ kind = "HEADER_NAME"
|
||||
+ directive = "after_include"
|
||||
+ else:
|
||||
+ mo = PP_TOKEN_RE.match(file_contents, pos)
|
||||
+ kind = mo.lastgroup
|
||||
+ if kind != "WHITESPACE":
|
||||
+ directive = "after_include"
|
||||
+ else:
|
||||
+ mo = PP_TOKEN_RE.match(file_contents, pos)
|
||||
+ kind = mo.lastgroup
|
||||
+
|
||||
+ text = mo.group()
|
||||
+ line = line_num
|
||||
+ column = mo.start() - line_start
|
||||
+ adj_line_start = 0
|
||||
+ # only these kinds can contain a newline
|
||||
+ if kind in ("WHITESPACE", "BLOCK_COMMENT", "LINE_COMMENT",
|
||||
+ "STRING", "CHARCONST", "BAD_BLOCK_COM", "ESCNL"):
|
||||
+ for tmo in ENDLINE_RE.finditer(text):
|
||||
+ line_num += 1
|
||||
+ adj_line_start = tmo.end()
|
||||
+ if adj_line_start:
|
||||
+ line_start = mo.start() + adj_line_start
|
||||
+
|
||||
+ # Track whether or not we are scanning a preprocessing directive.
|
||||
+ if kind == "LINE_COMMENT" or (kind == "WHITESPACE" and adj_line_start):
|
||||
+ at_bol = True
|
||||
+ directive = None
|
||||
+ else:
|
||||
+ if kind == "PUNCTUATOR" and text == "#" and at_bol:
|
||||
+ directive = "<null>"
|
||||
+ elif kind == "IDENT" and directive == "<null>":
|
||||
+ directive = text
|
||||
+ at_bol = False
|
||||
+
|
||||
+ # Report ill-formed tokens and rewrite them as their well-formed
|
||||
+ # equivalents, so downstream processing doesn't have to know about them.
|
||||
+ # (Rewriting instead of discarding provides better error recovery.)
|
||||
+ if kind == "BAD_BLOCK_COM":
|
||||
+ reporter.error(Token("BAD_BLOCK_COM", "", line, column+1, ""),
|
||||
+ "unclosed block comment")
|
||||
+ text += "*/"
|
||||
+ kind = "BLOCK_COMMENT"
|
||||
+ elif kind == "BAD_STRING":
|
||||
+ reporter.error(Token("BAD_STRING", "", line, column+1, ""),
|
||||
+ "unclosed string")
|
||||
+ text += "\""
|
||||
+ kind = "STRING"
|
||||
+ elif kind == "BAD_CHARCONST":
|
||||
+ reporter.error(Token("BAD_CHARCONST", "", line, column+1, ""),
|
||||
+ "unclosed char constant")
|
||||
+ text += "'"
|
||||
+ kind = "CHARCONST"
|
||||
+
|
||||
+ tok = Token(kind, text, line, column+1,
|
||||
+ "include" if directive == "after_include" else directive)
|
||||
+ # Do not complain about OTHER tokens inside macro definitions.
|
||||
+ # $ and @ appear in macros defined by headers intended to be
|
||||
+ # included from assembly language, e.g. sysdeps/mips/sys/asm.h.
|
||||
+ if kind == "OTHER" and directive != "define":
|
||||
+ self.error(tok, "stray {!r} in program")
|
||||
+
|
||||
+ yield tok
|
||||
+ pos = mo.end()
|
598
SOURCES/glibc-rh2109510-19.patch
Normal file
598
SOURCES/glibc-rh2109510-19.patch
Normal file
@ -0,0 +1,598 @@
|
||||
commit e6e6184bed490403811771fa527eb95b4ae53c7c
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu Sep 22 12:10:41 2022 +0200
|
||||
|
||||
scripts: Enhance glibcpp to do basic macro processing
|
||||
|
||||
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
|
||||
Conflicts:
|
||||
support/Makefile
|
||||
(spurious tests sorting change upstream)
|
||||
|
||||
diff --git a/scripts/glibcpp.py b/scripts/glibcpp.py
|
||||
index b44c6a4392dde8ce..455459a609eab120 100644
|
||||
--- a/scripts/glibcpp.py
|
||||
+++ b/scripts/glibcpp.py
|
||||
@@ -33,7 +33,9 @@ Accepts non-ASCII characters only within comments and strings.
|
||||
"""
|
||||
|
||||
import collections
|
||||
+import operator
|
||||
import re
|
||||
+import sys
|
||||
|
||||
# Caution: The order of the outermost alternation matters.
|
||||
# STRING must be before BAD_STRING, CHARCONST before BAD_CHARCONST,
|
||||
@@ -210,3 +212,318 @@ def tokenize_c(file_contents, reporter):
|
||||
|
||||
yield tok
|
||||
pos = mo.end()
|
||||
+
|
||||
+class MacroDefinition(collections.namedtuple('MacroDefinition',
|
||||
+ 'name_token args body error')):
|
||||
+ """A preprocessor macro definition.
|
||||
+
|
||||
+ name_token is the Token_ for the name.
|
||||
+
|
||||
+ args is None for a macro that is not function-like. Otherwise, it
|
||||
+ is a tuple that contains the macro argument name tokens.
|
||||
+
|
||||
+ body is a tuple that contains the tokens that constitue the body
|
||||
+ of the macro definition (excluding whitespace).
|
||||
+
|
||||
+ error is None if no error was detected, or otherwise a problem
|
||||
+ description associated with this macro definition.
|
||||
+
|
||||
+ """
|
||||
+
|
||||
+ @property
|
||||
+ def function(self):
|
||||
+ """Return true if the macro is function-like."""
|
||||
+ return self.args is not None
|
||||
+
|
||||
+ @property
|
||||
+ def name(self):
|
||||
+ """Return the name of the macro being defined."""
|
||||
+ return self.name_token.text
|
||||
+
|
||||
+ @property
|
||||
+ def line(self):
|
||||
+ """Return the line number of the macro defintion."""
|
||||
+ return self.name_token.line
|
||||
+
|
||||
+ @property
|
||||
+ def args_lowered(self):
|
||||
+ """Return the macro argument list as a list of strings"""
|
||||
+ if self.function:
|
||||
+ return [token.text for token in self.args]
|
||||
+ else:
|
||||
+ return None
|
||||
+
|
||||
+ @property
|
||||
+ def body_lowered(self):
|
||||
+ """Return the macro body as a list of strings."""
|
||||
+ return [token.text for token in self.body]
|
||||
+
|
||||
+def macro_definitions(tokens):
|
||||
+ """A generator for C macro definitions among tokens.
|
||||
+
|
||||
+ The generator yields MacroDefinition objects.
|
||||
+
|
||||
+ tokens must be iterable, yielding Token_ objects.
|
||||
+
|
||||
+ """
|
||||
+
|
||||
+ macro_name = None
|
||||
+ macro_start = False # Set to false after macro name and one otken.
|
||||
+ macro_args = None # Set to a list during the macro argument sequence.
|
||||
+ in_macro_args = False # True while processing macro identifier-list.
|
||||
+ error = None
|
||||
+ body = []
|
||||
+
|
||||
+ for token in tokens:
|
||||
+ if token.context == 'define' and macro_name is None \
|
||||
+ and token.kind == 'IDENT':
|
||||
+ # Starting up macro processing.
|
||||
+ if macro_start:
|
||||
+ # First identifier is the macro name.
|
||||
+ macro_name = token
|
||||
+ else:
|
||||
+ # Next token is the name.
|
||||
+ macro_start = True
|
||||
+ continue
|
||||
+
|
||||
+ if macro_name is None:
|
||||
+ # Drop tokens not in macro definitions.
|
||||
+ continue
|
||||
+
|
||||
+ if token.context != 'define':
|
||||
+ # End of the macro definition.
|
||||
+ if in_macro_args and error is None:
|
||||
+ error = 'macro definition ends in macro argument list'
|
||||
+ yield MacroDefinition(macro_name, macro_args, tuple(body), error)
|
||||
+ # No longer in a macro definition.
|
||||
+ macro_name = None
|
||||
+ macro_start = False
|
||||
+ macro_args = None
|
||||
+ in_macro_args = False
|
||||
+ error = None
|
||||
+ body.clear()
|
||||
+ continue
|
||||
+
|
||||
+ if macro_start:
|
||||
+ # First token after the macro name.
|
||||
+ macro_start = False
|
||||
+ if token.kind == 'PUNCTUATOR' and token.text == '(':
|
||||
+ macro_args = []
|
||||
+ in_macro_args = True
|
||||
+ continue
|
||||
+
|
||||
+ if in_macro_args:
|
||||
+ if token.kind == 'IDENT' \
|
||||
+ or (token.kind == 'PUNCTUATOR' and token.text == '...'):
|
||||
+ # Macro argument or ... placeholder.
|
||||
+ macro_args.append(token)
|
||||
+ if token.kind == 'PUNCTUATOR':
|
||||
+ if token.text == ')':
|
||||
+ macro_args = tuple(macro_args)
|
||||
+ in_macro_args = False
|
||||
+ elif token.text == ',':
|
||||
+ pass # Skip. Not a full syntax check.
|
||||
+ elif error is None:
|
||||
+ error = 'invalid punctuator in macro argument list: ' \
|
||||
+ + repr(token.text)
|
||||
+ elif error is None:
|
||||
+ error = 'invalid {} token in macro argument list'.format(
|
||||
+ token.kind)
|
||||
+ continue
|
||||
+
|
||||
+ if token.kind not in ('WHITESPACE', 'BLOCK_COMMENT'):
|
||||
+ body.append(token)
|
||||
+
|
||||
+ # Emit the macro in case the last line does not end with a newline.
|
||||
+ if macro_name is not None:
|
||||
+ if in_macro_args and error is None:
|
||||
+ error = 'macro definition ends in macro argument list'
|
||||
+ yield MacroDefinition(macro_name, macro_args, tuple(body), error)
|
||||
+
|
||||
+# Used to split UL etc. suffixes from numbers such as 123UL.
|
||||
+RE_SPLIT_INTEGER_SUFFIX = re.compile(r'([^ullULL]+)([ullULL]*)')
|
||||
+
|
||||
+BINARY_OPERATORS = {
|
||||
+ '+': operator.add,
|
||||
+ '<<': operator.lshift,
|
||||
+}
|
||||
+
|
||||
+# Use the general-purpose dict type if it is order-preserving.
|
||||
+if (sys.version_info[0], sys.version_info[1]) <= (3, 6):
|
||||
+ OrderedDict = collections.OrderedDict
|
||||
+else:
|
||||
+ OrderedDict = dict
|
||||
+
|
||||
+def macro_eval(macro_defs, reporter):
|
||||
+ """Compute macro values
|
||||
+
|
||||
+ macro_defs is the output from macro_definitions. reporter is an
|
||||
+ object that accepts reporter.error(line_number, message) and
|
||||
+ reporter.note(line_number, message) calls to report errors
|
||||
+ and error context invocations.
|
||||
+
|
||||
+ The returned dict contains the values of macros which are not
|
||||
+ function-like, pairing their names with their computed values.
|
||||
+
|
||||
+ The current implementation is incomplete. It is deliberately not
|
||||
+ entirely faithful to C, even in the implemented parts. It checks
|
||||
+ that macro replacements follow certain syntactic rules even if
|
||||
+ they are never evaluated.
|
||||
+
|
||||
+ """
|
||||
+
|
||||
+ # Unevaluated macro definitions by name.
|
||||
+ definitions = OrderedDict()
|
||||
+ for md in macro_defs:
|
||||
+ if md.name in definitions:
|
||||
+ reporter.error(md.line, 'macro {} redefined'.format(md.name))
|
||||
+ reporter.note(definitions[md.name].line,
|
||||
+ 'location of previous definition')
|
||||
+ else:
|
||||
+ definitions[md.name] = md
|
||||
+
|
||||
+ # String to value mappings for fully evaluated macros.
|
||||
+ evaluated = OrderedDict()
|
||||
+
|
||||
+ # String to macro definitions during evaluation. Nice error
|
||||
+ # reporting relies on determinstic iteration order.
|
||||
+ stack = OrderedDict()
|
||||
+
|
||||
+ def eval_token(current, token):
|
||||
+ """Evaluate one macro token.
|
||||
+
|
||||
+ Integers and strings are returned as such (the latter still
|
||||
+ quoted). Identifiers are expanded.
|
||||
+
|
||||
+ None indicates an empty expansion or an error.
|
||||
+
|
||||
+ """
|
||||
+
|
||||
+ if token.kind == 'PP_NUMBER':
|
||||
+ value = None
|
||||
+ m = RE_SPLIT_INTEGER_SUFFIX.match(token.text)
|
||||
+ if m:
|
||||
+ try:
|
||||
+ value = int(m.group(1), 0)
|
||||
+ except ValueError:
|
||||
+ pass
|
||||
+ if value is None:
|
||||
+ reporter.error(token.line,
|
||||
+ 'invalid number {!r} in definition of {}'.format(
|
||||
+ token.text, current.name))
|
||||
+ return value
|
||||
+
|
||||
+ if token.kind == 'STRING':
|
||||
+ return token.text
|
||||
+
|
||||
+ if token.kind == 'CHARCONST' and len(token.text) == 3:
|
||||
+ return ord(token.text[1])
|
||||
+
|
||||
+ if token.kind == 'IDENT':
|
||||
+ name = token.text
|
||||
+ result = eval1(current, name)
|
||||
+ if name not in evaluated:
|
||||
+ evaluated[name] = result
|
||||
+ return result
|
||||
+
|
||||
+ reporter.error(token.line,
|
||||
+ 'unrecognized {!r} in definition of {}'.format(
|
||||
+ token.text, current.name))
|
||||
+ return None
|
||||
+
|
||||
+
|
||||
+ def eval1(current, name):
|
||||
+ """Evaluate one name.
|
||||
+
|
||||
+ The name is looked up and the macro definition evaluated
|
||||
+ recursively if necessary. The current argument is the macro
|
||||
+ definition being evaluated.
|
||||
+
|
||||
+ None as a return value indicates an error.
|
||||
+
|
||||
+ """
|
||||
+
|
||||
+ # Fast path if the value has already been evaluated.
|
||||
+ if name in evaluated:
|
||||
+ return evaluated[name]
|
||||
+
|
||||
+ try:
|
||||
+ md = definitions[name]
|
||||
+ except KeyError:
|
||||
+ reporter.error(current.line,
|
||||
+ 'reference to undefined identifier {} in definition of {}'
|
||||
+ .format(name, current.name))
|
||||
+ return None
|
||||
+
|
||||
+ if md.name in stack:
|
||||
+ # Recursive macro definition.
|
||||
+ md = stack[name]
|
||||
+ reporter.error(md.line,
|
||||
+ 'macro definition {} refers to itself'.format(md.name))
|
||||
+ for md1 in reversed(list(stack.values())):
|
||||
+ if md1 is md:
|
||||
+ break
|
||||
+ reporter.note(md1.line,
|
||||
+ 'evaluated from {}'.format(md1.name))
|
||||
+ return None
|
||||
+
|
||||
+ stack[md.name] = md
|
||||
+ if md.function:
|
||||
+ reporter.error(current.line,
|
||||
+ 'attempt to evaluate function-like macro {}'.format(name))
|
||||
+ reporter.note(md.line, 'definition of {}'.format(md.name))
|
||||
+ return None
|
||||
+
|
||||
+ try:
|
||||
+ body = md.body
|
||||
+ if len(body) == 0:
|
||||
+ # Empty expansion.
|
||||
+ return None
|
||||
+
|
||||
+ # Remove surrounding ().
|
||||
+ if body[0].text == '(' and body[-1].text == ')':
|
||||
+ body = body[1:-1]
|
||||
+ had_parens = True
|
||||
+ else:
|
||||
+ had_parens = False
|
||||
+
|
||||
+ if len(body) == 1:
|
||||
+ return eval_token(md, body[0])
|
||||
+
|
||||
+ # Minimal expression evaluator for binary operators.
|
||||
+ op = body[1].text
|
||||
+ if len(body) == 3 and op in BINARY_OPERATORS:
|
||||
+ if not had_parens:
|
||||
+ reporter.error(body[1].line,
|
||||
+ 'missing parentheses around {} expression'.format(op))
|
||||
+ reporter.note(md.line,
|
||||
+ 'in definition of macro {}'.format(md.name))
|
||||
+
|
||||
+ left = eval_token(md, body[0])
|
||||
+ right = eval_token(md, body[2])
|
||||
+
|
||||
+ if type(left) != type(1):
|
||||
+ reporter.error(left.line,
|
||||
+ 'left operand of {} is not an integer'.format(op))
|
||||
+ reporter.note(md.line,
|
||||
+ 'in definition of macro {}'.format(md.name))
|
||||
+ if type(right) != type(1):
|
||||
+ reporter.error(left.line,
|
||||
+ 'right operand of {} is not an integer'.format(op))
|
||||
+ reporter.note(md.line,
|
||||
+ 'in definition of macro {}'.format(md.name))
|
||||
+ return BINARY_OPERATORS[op](left, right)
|
||||
+
|
||||
+ reporter.error(md.line,
|
||||
+ 'uninterpretable macro token sequence: {}'.format(
|
||||
+ ' '.join(md.body_lowered)))
|
||||
+ return None
|
||||
+ finally:
|
||||
+ del stack[md.name]
|
||||
+
|
||||
+ # Start of main body of macro_eval.
|
||||
+ for md in definitions.values():
|
||||
+ name = md.name
|
||||
+ if name not in evaluated and not md.function:
|
||||
+ evaluated[name] = eval1(md, name)
|
||||
+ return evaluated
|
||||
diff --git a/support/Makefile b/support/Makefile
|
||||
index 09b41b0d57e9239a..7749ac24f1ac3622 100644
|
||||
--- a/support/Makefile
|
||||
+++ b/support/Makefile
|
||||
@@ -223,11 +223,11 @@ $(objpfx)true-container : $(libsupport)
|
||||
tests = \
|
||||
README-testing \
|
||||
tst-support-namespace \
|
||||
+ tst-support-process_state \
|
||||
tst-support_blob_repeat \
|
||||
tst-support_capture_subprocess \
|
||||
tst-support_descriptors \
|
||||
tst-support_format_dns_packet \
|
||||
- tst-support-process_state \
|
||||
tst-support_quote_blob \
|
||||
tst-support_quote_string \
|
||||
tst-support_record_failure \
|
||||
@@ -248,6 +248,12 @@ $(objpfx)tst-support_record_failure-2.out: tst-support_record_failure-2.sh \
|
||||
$(evaluate-test)
|
||||
endif
|
||||
|
||||
+tests-special += $(objpfx)tst-glibcpp.out
|
||||
+
|
||||
+$(objpfx)tst-glibcpp.out: tst-glibcpp.py $(..)scripts/glibcpp.py
|
||||
+ PYTHONPATH=$(..)scripts $(PYTHON) tst-glibcpp.py > $@ 2>&1; \
|
||||
+ $(evaluate-test)
|
||||
+
|
||||
$(objpfx)tst-support_format_dns_packet: $(common-objpfx)resolv/libresolv.so
|
||||
|
||||
tst-support_capture_subprocess-ARGS = -- $(host-test-program-cmd)
|
||||
diff --git a/support/tst-glibcpp.py b/support/tst-glibcpp.py
|
||||
new file mode 100644
|
||||
index 0000000000000000..a2db1916ccfce3c3
|
||||
--- /dev/null
|
||||
+++ b/support/tst-glibcpp.py
|
||||
@@ -0,0 +1,217 @@
|
||||
+#! /usr/bin/python3
|
||||
+# Tests for scripts/glibcpp.py
|
||||
+# Copyright (C) 2022 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
|
||||
+# <https://www.gnu.org/licenses/>.
|
||||
+
|
||||
+import inspect
|
||||
+import sys
|
||||
+
|
||||
+import glibcpp
|
||||
+
|
||||
+# Error counter.
|
||||
+errors = 0
|
||||
+
|
||||
+class TokenizerErrors:
|
||||
+ """Used as the error reporter during tokenization."""
|
||||
+
|
||||
+ def __init__(self):
|
||||
+ self.errors = []
|
||||
+
|
||||
+ def error(self, token, message):
|
||||
+ self.errors.append((token, message))
|
||||
+
|
||||
+def check_macro_definitions(source, expected):
|
||||
+ reporter = TokenizerErrors()
|
||||
+ tokens = glibcpp.tokenize_c(source, reporter)
|
||||
+
|
||||
+ actual = []
|
||||
+ for md in glibcpp.macro_definitions(tokens):
|
||||
+ if md.function:
|
||||
+ md_name = '{}({})'.format(md.name, ','.join(md.args_lowered))
|
||||
+ else:
|
||||
+ md_name = md.name
|
||||
+ actual.append((md_name, md.body_lowered))
|
||||
+
|
||||
+ if actual != expected or reporter.errors:
|
||||
+ global errors
|
||||
+ errors += 1
|
||||
+ # Obtain python source line information.
|
||||
+ frame = inspect.stack(2)[1]
|
||||
+ print('{}:{}: error: macro definition mismatch, actual definitions:'
|
||||
+ .format(frame[1], frame[2]))
|
||||
+ for md in actual:
|
||||
+ print('note: {} {!r}'.format(md[0], md[1]))
|
||||
+
|
||||
+ if reporter.errors:
|
||||
+ for err in reporter.errors:
|
||||
+ print('note: tokenizer error: {}: {}'.format(
|
||||
+ err[0].line, err[1]))
|
||||
+
|
||||
+def check_macro_eval(source, expected, expected_errors=''):
|
||||
+ reporter = TokenizerErrors()
|
||||
+ tokens = list(glibcpp.tokenize_c(source, reporter))
|
||||
+
|
||||
+ if reporter.errors:
|
||||
+ # Obtain python source line information.
|
||||
+ frame = inspect.stack(2)[1]
|
||||
+ for err in reporter.errors:
|
||||
+ print('{}:{}: tokenizer error: {}: {}'.format(
|
||||
+ frame[1], frame[2], err[0].line, err[1]))
|
||||
+ return
|
||||
+
|
||||
+ class EvalReporter:
|
||||
+ """Used as the error reporter during evaluation."""
|
||||
+
|
||||
+ def __init__(self):
|
||||
+ self.lines = []
|
||||
+
|
||||
+ def error(self, line, message):
|
||||
+ self.lines.append('{}: error: {}\n'.format(line, message))
|
||||
+
|
||||
+ def note(self, line, message):
|
||||
+ self.lines.append('{}: note: {}\n'.format(line, message))
|
||||
+
|
||||
+ reporter = EvalReporter()
|
||||
+ actual = glibcpp.macro_eval(glibcpp.macro_definitions(tokens), reporter)
|
||||
+ actual_errors = ''.join(reporter.lines)
|
||||
+ if actual != expected or actual_errors != expected_errors:
|
||||
+ global errors
|
||||
+ errors += 1
|
||||
+ # Obtain python source line information.
|
||||
+ frame = inspect.stack(2)[1]
|
||||
+ print('{}:{}: error: macro evaluation mismatch, actual results:'
|
||||
+ .format(frame[1], frame[2]))
|
||||
+ for k, v in actual.items():
|
||||
+ print(' {}: {!r}'.format(k, v))
|
||||
+ for msg in reporter.lines:
|
||||
+ sys.stdout.write(' | ' + msg)
|
||||
+
|
||||
+# Individual test cases follow.
|
||||
+
|
||||
+check_macro_definitions('', [])
|
||||
+check_macro_definitions('int main()\n{\n{\n', [])
|
||||
+check_macro_definitions("""
|
||||
+#define A 1
|
||||
+#define B 2 /* ignored */
|
||||
+#define C 3 // also ignored
|
||||
+#define D \
|
||||
+ 4
|
||||
+#define STRING "string"
|
||||
+#define FUNCLIKE(a, b) (a + b)
|
||||
+#define FUNCLIKE2(a, b) (a + \
|
||||
+ b)
|
||||
+""", [('A', ['1']),
|
||||
+ ('B', ['2']),
|
||||
+ ('C', ['3']),
|
||||
+ ('D', ['4']),
|
||||
+ ('STRING', ['"string"']),
|
||||
+ ('FUNCLIKE(a,b)', list('(a+b)')),
|
||||
+ ('FUNCLIKE2(a,b)', list('(a+b)')),
|
||||
+ ])
|
||||
+check_macro_definitions('#define MACRO', [('MACRO', [])])
|
||||
+check_macro_definitions('#define MACRO\n', [('MACRO', [])])
|
||||
+check_macro_definitions('#define MACRO()', [('MACRO()', [])])
|
||||
+check_macro_definitions('#define MACRO()\n', [('MACRO()', [])])
|
||||
+
|
||||
+check_macro_eval('#define A 1', {'A': 1})
|
||||
+check_macro_eval('#define A (1)', {'A': 1})
|
||||
+check_macro_eval('#define A (1 + 1)', {'A': 2})
|
||||
+check_macro_eval('#define A (1U << 31)', {'A': 1 << 31})
|
||||
+check_macro_eval('''\
|
||||
+#define A (B + 1)
|
||||
+#define B 10
|
||||
+#define F(x) ignored
|
||||
+#define C "not ignored"
|
||||
+''', {
|
||||
+ 'A': 11,
|
||||
+ 'B': 10,
|
||||
+ 'C': '"not ignored"',
|
||||
+})
|
||||
+
|
||||
+# Checking for evaluation errors.
|
||||
+check_macro_eval('''\
|
||||
+#define A 1
|
||||
+#define A 2
|
||||
+''', {
|
||||
+ 'A': 1,
|
||||
+}, '''\
|
||||
+2: error: macro A redefined
|
||||
+1: note: location of previous definition
|
||||
+''')
|
||||
+
|
||||
+check_macro_eval('''\
|
||||
+#define A A
|
||||
+#define B 1
|
||||
+''', {
|
||||
+ 'A': None,
|
||||
+ 'B': 1,
|
||||
+}, '''\
|
||||
+1: error: macro definition A refers to itself
|
||||
+''')
|
||||
+
|
||||
+check_macro_eval('''\
|
||||
+#define A B
|
||||
+#define B A
|
||||
+''', {
|
||||
+ 'A': None,
|
||||
+ 'B': None,
|
||||
+}, '''\
|
||||
+1: error: macro definition A refers to itself
|
||||
+2: note: evaluated from B
|
||||
+''')
|
||||
+
|
||||
+check_macro_eval('''\
|
||||
+#define A B
|
||||
+#define B C
|
||||
+#define C A
|
||||
+''', {
|
||||
+ 'A': None,
|
||||
+ 'B': None,
|
||||
+ 'C': None,
|
||||
+}, '''\
|
||||
+1: error: macro definition A refers to itself
|
||||
+3: note: evaluated from C
|
||||
+2: note: evaluated from B
|
||||
+''')
|
||||
+
|
||||
+check_macro_eval('''\
|
||||
+#define A 1 +
|
||||
+''', {
|
||||
+ 'A': None,
|
||||
+}, '''\
|
||||
+1: error: uninterpretable macro token sequence: 1 +
|
||||
+''')
|
||||
+
|
||||
+check_macro_eval('''\
|
||||
+#define A 3*5
|
||||
+''', {
|
||||
+ 'A': None,
|
||||
+}, '''\
|
||||
+1: error: uninterpretable macro token sequence: 3 * 5
|
||||
+''')
|
||||
+
|
||||
+check_macro_eval('''\
|
||||
+#define A 3 + 5
|
||||
+''', {
|
||||
+ 'A': 8,
|
||||
+}, '''\
|
||||
+1: error: missing parentheses around + expression
|
||||
+1: note: in definition of macro A
|
||||
+''')
|
||||
+
|
||||
+if errors:
|
||||
+ sys.exit(1)
|
208
SOURCES/glibc-rh2109510-2.patch
Normal file
208
SOURCES/glibc-rh2109510-2.patch
Normal file
@ -0,0 +1,208 @@
|
||||
Partial backport of:
|
||||
|
||||
commit 7e1d42400c1b8f03316fe14176133c8853cd3bbe
|
||||
Author: Joseph Myers <joseph@codesourcery.com>
|
||||
Date: Fri Nov 30 15:20:41 2018 +0000
|
||||
|
||||
Replace gen-as-const.awk by gen-as-const.py.
|
||||
|
||||
This patch replaces gen-as-const.awk, and some fragments of the
|
||||
Makefile code that used it, by a Python script. The point is not such
|
||||
much that awk is problematic for this particular script, as that I'd
|
||||
like to build up a general Python infrastructure for extracting
|
||||
information from C headers, for use in writing tests of such headers.
|
||||
Thus, although this patch does not set up such infrastructure, the
|
||||
compute_c_consts function in gen-as-const.py might be moved to a
|
||||
separate Python module in a subsequent patch as a starting point for
|
||||
such infrastructure.
|
||||
|
||||
The general idea of the code is the same as in the awk version, but no
|
||||
attempt is made to make the output files textually identical. When
|
||||
generating a header, a dict of constant names and values is generated
|
||||
internally then defines are printed in sorted order (rather than the
|
||||
order in the .sym file, which would have been used before). When
|
||||
generating a test that the values computed match those from a normal
|
||||
header inclusion, the test code is made into a compilation test using
|
||||
_Static_assert, where previously the comparisons were done only when
|
||||
the test was executed. One fragment of test generation (converting
|
||||
the previously generated header to use asconst_* prefixes on its macro
|
||||
names) is still in awk code in the makefiles; only the .sym processing
|
||||
and subsequent execution of the compiler to extract constants have
|
||||
moved to the Python script.
|
||||
|
||||
Tested for x86_64, and with build-many-glibcs.py.
|
||||
|
||||
* scripts/gen-as-const.py: New file.
|
||||
* scripts/gen-as-const.awk: Remove.
|
||||
* Makerules ($(common-objpfx)%.h $(common-objpfx)%.h.d): Use
|
||||
gen-as-const.py.
|
||||
($(objpfx)test-as-const-%.c): Likewise.
|
||||
|
||||
In the downstream version, scripts/gen-as-const.awk is not removed and
|
||||
still used in Makerules.
|
||||
|
||||
diff --git a/scripts/gen-as-const.py b/scripts/gen-as-const.py
|
||||
new file mode 100644
|
||||
index 0000000000000000..b7a5744bb192dd67
|
||||
--- /dev/null
|
||||
+++ b/scripts/gen-as-const.py
|
||||
@@ -0,0 +1,159 @@
|
||||
+#!/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 os.path
|
||||
+import re
|
||||
+import subprocess
|
||||
+import tempfile
|
||||
+
|
||||
+
|
||||
+def compute_c_consts(sym_data, cc):
|
||||
+ """Compute the values of some C constants.
|
||||
+
|
||||
+ The first argument is a list whose elements are either strings
|
||||
+ (preprocessor directives) or pairs of strings (a name and a C
|
||||
+ expression for the corresponding value). Preprocessor directives
|
||||
+ in the middle of the list may be used to select which constants
|
||||
+ end up being evaluated using which expressions.
|
||||
+
|
||||
+ """
|
||||
+ out_lines = []
|
||||
+ started = False
|
||||
+ for arg in sym_data:
|
||||
+ if isinstance(arg, str):
|
||||
+ out_lines.append(arg)
|
||||
+ continue
|
||||
+ name = arg[0]
|
||||
+ value = arg[1]
|
||||
+ if not started:
|
||||
+ out_lines.append('void\ndummy (void)\n{')
|
||||
+ started = True
|
||||
+ out_lines.append('asm ("@@@name@@@%s@@@value@@@%%0@@@end@@@" '
|
||||
+ ': : \"i\" ((long int) (%s)));'
|
||||
+ % (name, value))
|
||||
+ if started:
|
||||
+ out_lines.append('}')
|
||||
+ out_lines.append('')
|
||||
+ out_text = '\n'.join(out_lines)
|
||||
+ with tempfile.TemporaryDirectory() as temp_dir:
|
||||
+ c_file_name = os.path.join(temp_dir, 'test.c')
|
||||
+ s_file_name = os.path.join(temp_dir, 'test.s')
|
||||
+ with open(c_file_name, 'w') as c_file:
|
||||
+ c_file.write(out_text)
|
||||
+ # Compilation has to be from stdin to avoid the temporary file
|
||||
+ # name being written into the generated dependencies.
|
||||
+ cmd = ('%s -S -o %s -x c - < %s' % (cc, s_file_name, c_file_name))
|
||||
+ subprocess.check_call(cmd, shell=True)
|
||||
+ consts = {}
|
||||
+ with open(s_file_name, 'r') as s_file:
|
||||
+ for line in s_file:
|
||||
+ match = re.search('@@@name@@@([^@]*)'
|
||||
+ '@@@value@@@[^0-9Xxa-fA-F-]*'
|
||||
+ '([0-9Xxa-fA-F-]+).*@@@end@@@', line)
|
||||
+ if match:
|
||||
+ if (match.group(1) in consts
|
||||
+ and match.group(2) != consts[match.group(1)]):
|
||||
+ raise ValueError('duplicate constant %s'
|
||||
+ % match.group(1))
|
||||
+ consts[match.group(1)] = match.group(2)
|
||||
+ return consts
|
||||
+
|
||||
+
|
||||
+def gen_test(sym_data):
|
||||
+ """Generate a test for the values of some C constants.
|
||||
+
|
||||
+ The first argument is as for compute_c_consts.
|
||||
+
|
||||
+ """
|
||||
+ out_lines = []
|
||||
+ started = False
|
||||
+ for arg in sym_data:
|
||||
+ if isinstance(arg, str):
|
||||
+ out_lines.append(arg)
|
||||
+ continue
|
||||
+ name = arg[0]
|
||||
+ value = arg[1]
|
||||
+ if not started:
|
||||
+ 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>')
|
||||
+ started = True
|
||||
+ 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('sym_file',
|
||||
+ help='.sym file to process')
|
||||
+ args = parser.parse_args()
|
||||
+ sym_data = []
|
||||
+ with open(args.sym_file, 'r') as sym_file:
|
||||
+ 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)
|
||||
+ # Separator.
|
||||
+ if words[0] == '--':
|
||||
+ continue
|
||||
+ name = words[0]
|
||||
+ value = words[1] if len(words) > 1 else words[0]
|
||||
+ sym_data.append((name, value))
|
||||
+ if args.test:
|
||||
+ print(gen_test(sym_data))
|
||||
+ else:
|
||||
+ consts = compute_c_consts(sym_data, args.cc)
|
||||
+ print('\n'.join('#define %s %s' % c for c in sorted(consts.items())))
|
||||
+
|
||||
+if __name__ == '__main__':
|
||||
+ main()
|
36
SOURCES/glibc-rh2109510-20.patch
Normal file
36
SOURCES/glibc-rh2109510-20.patch
Normal file
@ -0,0 +1,36 @@
|
||||
commit 29eb7961197bee68470730aecfdda4d0e206812e
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Sep 5 12:11:19 2022 +0200
|
||||
|
||||
elf.h: Remove duplicate definition of VER_FLG_WEAK
|
||||
|
||||
This did not cause a warning before because the token sequence for
|
||||
the two definitions was identical.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/elf/elf.h b/elf/elf.h
|
||||
index d6506ea1c7160dea..ec09040be639a52a 100644
|
||||
--- a/elf/elf.h
|
||||
+++ b/elf/elf.h
|
||||
@@ -1027,7 +1027,8 @@ typedef struct
|
||||
|
||||
/* Legal values for vd_flags (version information flags). */
|
||||
#define VER_FLG_BASE 0x1 /* Version definition of file itself */
|
||||
-#define VER_FLG_WEAK 0x2 /* Weak version identifier */
|
||||
+#define VER_FLG_WEAK 0x2 /* Weak version identifier. Also
|
||||
+ used by vna_flags below. */
|
||||
|
||||
/* Versym symbol index values. */
|
||||
#define VER_NDX_LOCAL 0 /* Symbol is local. */
|
||||
@@ -1105,10 +1106,6 @@ typedef struct
|
||||
} Elf64_Vernaux;
|
||||
|
||||
|
||||
-/* Legal values for vna_flags. */
|
||||
-#define VER_FLG_WEAK 0x2 /* Weak version identifier */
|
||||
-
|
||||
-
|
||||
/* Auxiliary vector. */
|
||||
|
||||
/* This vector is normally only used by the program interpreter. The
|
1295
SOURCES/glibc-rh2109510-21.patch
Normal file
1295
SOURCES/glibc-rh2109510-21.patch
Normal file
File diff suppressed because it is too large
Load Diff
34
SOURCES/glibc-rh2109510-22.patch
Normal file
34
SOURCES/glibc-rh2109510-22.patch
Normal file
@ -0,0 +1,34 @@
|
||||
commit d33705c0b020632274318323931695a99753b5be
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu Nov 3 12:24:17 2022 +0100
|
||||
|
||||
scripts/glibcelf.py: Properly report <elf.h> parsing failures
|
||||
|
||||
Without this change, parse failures result in an exception:
|
||||
|
||||
Traceback (most recent call last):
|
||||
File "tst-glibcelf.py", line 23, in <module>
|
||||
import glibcelf
|
||||
File "/path/to/git/scripts/glibcelf.py", line 226, in <module>
|
||||
_elf_h = _parse_elf_h()
|
||||
File "/path/to/git/scripts/glibcelf.py", line 221, in _parse_elf_h
|
||||
result = glibcpp.macro_eval(glibcpp.macro_definitions(tokens), reporter)
|
||||
File "/path/to/git/scripts/glibcpp.py", line 379, in macro_eval
|
||||
reporter.error(md.line, 'macro {} redefined'.format(md.name))
|
||||
File "/path/to/git/scripts/glibcelf.py", line 214, in error
|
||||
errors += 1
|
||||
UnboundLocalError: local variable 'errors' referenced before assignment
|
||||
|
||||
diff --git a/scripts/glibcelf.py b/scripts/glibcelf.py
|
||||
index 420cb21943b28bba..59aab56ecf9deb3e 100644
|
||||
--- a/scripts/glibcelf.py
|
||||
+++ b/scripts/glibcelf.py
|
||||
@@ -211,7 +211,7 @@ def _parse_elf_h():
|
||||
self.errors = 0
|
||||
|
||||
def error(self, line, message):
|
||||
- errors += 1
|
||||
+ self.errors += 1
|
||||
print('{}:{}: error: {}'.format(path, line, message))
|
||||
|
||||
def note(self, line, message):
|
108
SOURCES/glibc-rh2109510-23.patch
Normal file
108
SOURCES/glibc-rh2109510-23.patch
Normal file
@ -0,0 +1,108 @@
|
||||
Downstream-only adjustments to scripts/glibcelf.py. We do not have
|
||||
CSKY nor RISC-V constants in <elf.h>, so glibcelf cannot extract
|
||||
those. PT_AARCH64_* constants are missing as well.
|
||||
|
||||
Adjust elf/tst-glibcelf.py to use PT_MIPS_OPTIONS instead of
|
||||
PT_AARCH64_MEMTAG_MTE for testing. It has the same numeric value
|
||||
(0x70000002).
|
||||
|
||||
diff --git a/elf/tst-glibcelf.py b/elf/tst-glibcelf.py
|
||||
index a5bff45eae55edea..9cb0861589d6ae2e 100644
|
||||
--- a/elf/tst-glibcelf.py
|
||||
+++ b/elf/tst-glibcelf.py
|
||||
@@ -75,15 +75,17 @@ def check_basic():
|
||||
if repr(glibcelf.Pt(17609)) != 'Pt(17609)':
|
||||
error('repr(Pt(17609))')
|
||||
|
||||
- if glibcelf.Pt('PT_AARCH64_MEMTAG_MTE') \
|
||||
- is not glibcelf.Pt.PT_AARCH64_MEMTAG_MTE:
|
||||
- error('PT_AARCH64_MEMTAG_MTE identity')
|
||||
- if glibcelf.Pt(0x70000002) is glibcelf.Pt.PT_AARCH64_MEMTAG_MTE:
|
||||
+ # Note: Upstream uses PT_AARCH64_MEMTAG_MTE instead of PT_MIPS_OPTIONS.
|
||||
+ # PT_AARCH64_MEMTAG_MTE is not yet available downstream.
|
||||
+ if glibcelf.Pt('PT_MIPS_OPTIONS') \
|
||||
+ is not glibcelf.Pt.PT_MIPS_OPTIONS:
|
||||
+ error('PT_MIPS_OPTIONS identity')
|
||||
+ if glibcelf.Pt(0x70000002) is glibcelf.Pt.PT_MIPS_OPTIONS:
|
||||
error('Pt(0x70000002) identity')
|
||||
- if glibcelf.PtAARCH64(0x70000002) is not glibcelf.Pt.PT_AARCH64_MEMTAG_MTE:
|
||||
- error('PtAARCH64(0x70000002) identity')
|
||||
- if glibcelf.Pt.PT_AARCH64_MEMTAG_MTE.short_name != 'AARCH64_MEMTAG_MTE':
|
||||
- error('PT_AARCH64_MEMTAG_MTE short name')
|
||||
+ if glibcelf.PtMIPS(0x70000002) is not glibcelf.Pt.PT_MIPS_OPTIONS:
|
||||
+ error('PtMIPS(0x70000002) identity')
|
||||
+ if glibcelf.Pt.PT_MIPS_OPTIONS.short_name != 'MIPS_OPTIONS':
|
||||
+ error('PT_MIPS_OPTIONS short name')
|
||||
|
||||
# Special cases for int-like Shn.
|
||||
if glibcelf.Shn(32) == glibcelf.Shn.SHN_XINDEX:
|
||||
diff --git a/scripts/glibcelf.py b/scripts/glibcelf.py
|
||||
index 59aab56ecf9deb3e..5980d7cc906005e2 100644
|
||||
--- a/scripts/glibcelf.py
|
||||
+++ b/scripts/glibcelf.py
|
||||
@@ -306,23 +306,17 @@ class ShtALPHA(Sht):
|
||||
"""Supplemental SHT_* constants for EM_ALPHA."""
|
||||
class ShtARM(Sht):
|
||||
"""Supplemental SHT_* constants for EM_ARM."""
|
||||
-class ShtCSKY(Sht):
|
||||
- """Supplemental SHT_* constants for EM_CSKY."""
|
||||
class ShtIA_64(Sht):
|
||||
"""Supplemental SHT_* constants for EM_IA_64."""
|
||||
class ShtMIPS(Sht):
|
||||
"""Supplemental SHT_* constants for EM_MIPS."""
|
||||
class ShtPARISC(Sht):
|
||||
"""Supplemental SHT_* constants for EM_PARISC."""
|
||||
-class ShtRISCV(Sht):
|
||||
- """Supplemental SHT_* constants for EM_RISCV."""
|
||||
_register_elf_h(ShtALPHA, prefix='SHT_ALPHA_', parent=Sht)
|
||||
_register_elf_h(ShtARM, prefix='SHT_ARM_', parent=Sht)
|
||||
-_register_elf_h(ShtCSKY, prefix='SHT_CSKY_', parent=Sht)
|
||||
_register_elf_h(ShtIA_64, prefix='SHT_IA_64_', parent=Sht)
|
||||
_register_elf_h(ShtMIPS, prefix='SHT_MIPS_', parent=Sht)
|
||||
_register_elf_h(ShtPARISC, prefix='SHT_PARISC_', parent=Sht)
|
||||
-_register_elf_h(ShtRISCV, prefix='SHT_RISCV_', parent=Sht)
|
||||
_register_elf_h(Sht, ranges=True,
|
||||
skip='SHT_LOSUNW SHT_HISUNW SHT_LOUSER SHT_HIUSER'.split())
|
||||
|
||||
@@ -392,8 +386,6 @@ _register_elf_h(Stt, ranges=True)
|
||||
class Pt(_TypedConstant):
|
||||
"""ELF program header types. Type of Phdr.p_type."""
|
||||
prefix = 'PT_'
|
||||
-class PtAARCH64(Pt):
|
||||
- """Supplemental PT_* constants for EM_AARCH64."""
|
||||
class PtARM(Pt):
|
||||
"""Supplemental PT_* constants for EM_ARM."""
|
||||
class PtHP(Pt):
|
||||
@@ -404,15 +396,11 @@ class PtMIPS(Pt):
|
||||
"""Supplemental PT_* constants for EM_MIPS."""
|
||||
class PtPARISC(Pt):
|
||||
"""Supplemental PT_* constants for EM_PARISC."""
|
||||
-class PtRISCV(Pt):
|
||||
- """Supplemental PT_* constants for EM_RISCV."""
|
||||
-_register_elf_h(PtAARCH64, prefix='PT_AARCH64_', parent=Pt)
|
||||
_register_elf_h(PtARM, prefix='PT_ARM_', parent=Pt)
|
||||
_register_elf_h(PtHP, prefix='PT_HP_', parent=Pt)
|
||||
_register_elf_h(PtIA_64, prefix='PT_IA_64_', parent=Pt)
|
||||
_register_elf_h(PtMIPS, prefix='PT_MIPS_', parent=Pt)
|
||||
_register_elf_h(PtPARISC, prefix='PT_PARISC_', parent=Pt)
|
||||
-_register_elf_h(PtRISCV, prefix='PT_RISCV_', parent=Pt)
|
||||
_register_elf_h(Pt, skip='PT_LOSUNW PT_HISUNW'.split(), ranges=True)
|
||||
|
||||
class Dt(_TypedConstant):
|
||||
@@ -432,8 +420,6 @@ class DtPPC(Dt):
|
||||
"""Supplemental DT_* constants for EM_PPC."""
|
||||
class DtPPC64(Dt):
|
||||
"""Supplemental DT_* constants for EM_PPC64."""
|
||||
-class DtRISCV(Dt):
|
||||
- """Supplemental DT_* constants for EM_RISCV."""
|
||||
class DtSPARC(Dt):
|
||||
"""Supplemental DT_* constants for EM_SPARC."""
|
||||
_dt_skip = '''
|
||||
@@ -456,7 +442,6 @@ _register_elf_h(DtIA_64, prefix='DT_IA_64_', skip=_dt_skip, parent=Dt)
|
||||
_register_elf_h(DtMIPS, prefix='DT_MIPS_', skip=_dt_skip, parent=Dt)
|
||||
_register_elf_h(DtPPC, prefix='DT_PPC_', skip=_dt_skip, parent=Dt)
|
||||
_register_elf_h(DtPPC64, prefix='DT_PPC64_', skip=_dt_skip, parent=Dt)
|
||||
-_register_elf_h(DtRISCV, prefix='DT_RISCV_', skip=_dt_skip, parent=Dt)
|
||||
_register_elf_h(DtSPARC, prefix='DT_SPARC_', skip=_dt_skip, parent=Dt)
|
||||
_register_elf_h(Dt, skip=_dt_skip, ranges=True)
|
||||
del _dt_skip
|
32
SOURCES/glibc-rh2109510-3.patch
Normal file
32
SOURCES/glibc-rh2109510-3.patch
Normal file
@ -0,0 +1,32 @@
|
||||
commit 7b36d26b22d147ffc347f427f9fd584700578a94
|
||||
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
|
||||
Date: Mon Dec 3 14:40:48 2018 +0100
|
||||
|
||||
Fix test-as-const-jmp_buf-ssp.c generation on gnu-i386
|
||||
|
||||
hurd's jmp_buf-ssp.sym does not define any symbol.
|
||||
scripts/gen-as-const.py currently was emitting an empty line in that
|
||||
case, and the gawk invocation was prepending "asconst_" to it, ending up
|
||||
with:
|
||||
|
||||
.../build/glibc/setjmp/test-as-const-jmp_buf-ssp.c:1:2: error: expected « = », « , », « ; », « asm » or
|
||||
« __attribute__ » at end of input
|
||||
1 | asconst_
|
||||
| ^~~~~~~~
|
||||
|
||||
* scripts/gen-as-const.py (main): Avoid emitting empty line when
|
||||
there is no element in `consts'.
|
||||
|
||||
diff --git a/scripts/gen-as-const.py b/scripts/gen-as-const.py
|
||||
index b7a5744bb192dd67..cabf401ed15e8367 100644
|
||||
--- a/scripts/gen-as-const.py
|
||||
+++ b/scripts/gen-as-const.py
|
||||
@@ -153,7 +153,7 @@ def main():
|
||||
print(gen_test(sym_data))
|
||||
else:
|
||||
consts = compute_c_consts(sym_data, args.cc)
|
||||
- print('\n'.join('#define %s %s' % c for c in sorted(consts.items())))
|
||||
+ print(''.join('#define %s %s\n' % c for c in sorted(consts.items())), end='')
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
157
SOURCES/glibc-rh2109510-4.patch
Normal file
157
SOURCES/glibc-rh2109510-4.patch
Normal file
@ -0,0 +1,157 @@
|
||||
commit 477a02f63751c4b759ddd9454d17f2a7ad120ee3
|
||||
Author: Joseph Myers <joseph@codesourcery.com>
|
||||
Date: Mon Dec 3 22:08:50 2018 +0000
|
||||
|
||||
Make gen-as-const.py handle '--' consistently with awk script.
|
||||
|
||||
It was reported in
|
||||
<https://sourceware.org/ml/libc-alpha/2018-12/msg00045.html> that
|
||||
gen-as-const.py fails to generate test code in the case where a .sym
|
||||
file has no symbols in it, so resulting in a test failing to link for
|
||||
Hurd.
|
||||
|
||||
The relevant difference from the old awk script is that the old script
|
||||
treated '--' lines as indicating that the text to do at the start of
|
||||
the test (or file used to compute constants) should be output at that
|
||||
point if not already output, as well as treating lines with actual
|
||||
entries for constants like that. This patch changes gen-as-const.py
|
||||
accordingly, making it the sole responsibility of the code parsing
|
||||
.sym files to determine when such text should be output and ensuring
|
||||
it's always output at some point even if there are no symbols and no
|
||||
'--' lines, since not outputting it means the test fails to link.
|
||||
Handling '--' like that also avoids any problems that would arise if
|
||||
the first entry for a symbol were inside #ifdef (since the text in
|
||||
question must not be output inside #ifdef).
|
||||
|
||||
Tested for x86_64, and with build-many-glibcs.py for i686-gnu. Note
|
||||
that there are still compilation test failures for i686-gnu
|
||||
(linknamespace tests, possibly arising from recent posix_spawn-related
|
||||
changes).
|
||||
|
||||
* scripts/gen-as-const.py (compute_c_consts): Take an argument
|
||||
'START' to indicate that start text should be output.
|
||||
(gen_test): Likewise.
|
||||
(main): Generate 'START' for first symbol or '--' line, or at end
|
||||
of input if not previously generated.
|
||||
|
||||
diff --git a/scripts/gen-as-const.py b/scripts/gen-as-const.py
|
||||
index cabf401ed15e8367..eb85ef1aa0f4934d 100644
|
||||
--- a/scripts/gen-as-const.py
|
||||
+++ b/scripts/gen-as-const.py
|
||||
@@ -34,28 +34,28 @@ def compute_c_consts(sym_data, cc):
|
||||
"""Compute the values of some C constants.
|
||||
|
||||
The first argument is a list whose elements are either strings
|
||||
- (preprocessor directives) or pairs of strings (a name and a C
|
||||
+ (preprocessor directives, or the special string 'START' to
|
||||
+ indicate this function should insert its initial boilerplate text
|
||||
+ in the output there) or pairs of strings (a name and a C
|
||||
expression for the corresponding value). Preprocessor directives
|
||||
in the middle of the list may be used to select which constants
|
||||
end up being evaluated using which expressions.
|
||||
|
||||
"""
|
||||
out_lines = []
|
||||
- started = False
|
||||
for arg in sym_data:
|
||||
if isinstance(arg, str):
|
||||
- out_lines.append(arg)
|
||||
+ if arg == 'START':
|
||||
+ out_lines.append('void\ndummy (void)\n{')
|
||||
+ else:
|
||||
+ out_lines.append(arg)
|
||||
continue
|
||||
name = arg[0]
|
||||
value = arg[1]
|
||||
- if not started:
|
||||
- out_lines.append('void\ndummy (void)\n{')
|
||||
- started = True
|
||||
out_lines.append('asm ("@@@name@@@%s@@@value@@@%%0@@@end@@@" '
|
||||
': : \"i\" ((long int) (%s)));'
|
||||
% (name, value))
|
||||
- if started:
|
||||
- out_lines.append('}')
|
||||
+ out_lines.append('}')
|
||||
out_lines.append('')
|
||||
out_text = '\n'.join(out_lines)
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
@@ -89,32 +89,32 @@ def gen_test(sym_data):
|
||||
|
||||
"""
|
||||
out_lines = []
|
||||
- started = False
|
||||
for arg in sym_data:
|
||||
if isinstance(arg, str):
|
||||
- out_lines.append(arg)
|
||||
+ 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]
|
||||
- if not started:
|
||||
- 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>')
|
||||
- started = True
|
||||
out_lines.append('_Static_assert (U (asconst_%s) == (c_t) (%s), '
|
||||
'"value of %s");'
|
||||
% (name, value, name))
|
||||
@@ -134,6 +134,7 @@ def main():
|
||||
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 == '':
|
||||
@@ -143,12 +144,17 @@ def main():
|
||||
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))
|
||||
else:
|
483
SOURCES/glibc-rh2109510-5.patch
Normal file
483
SOURCES/glibc-rh2109510-5.patch
Normal file
@ -0,0 +1,483 @@
|
||||
commit a8110b727e508f7ddf34f940af622e6f95435201
|
||||
Author: Joseph Myers <joseph@codesourcery.com>
|
||||
Date: Mon Dec 10 22:27:13 2018 +0000
|
||||
|
||||
Move tst-signal-numbers to Python.
|
||||
|
||||
This patch converts the tst-signal-numbers test from shell + awk to
|
||||
Python.
|
||||
|
||||
As with gen-as-const, the point is not so much that shell and awk are
|
||||
problematic for this code, as that it's useful to build up general
|
||||
infrastructure in Python for use of a range of code involving
|
||||
extracting values from C headers. This patch moves some code from
|
||||
gen-as-const.py to a new glibcextract.py, which also gains functions
|
||||
relating to listing macros, and comparing the values of a set of
|
||||
macros from compiling two different pieces of code.
|
||||
|
||||
It's not just signal numbers that should have such tests; pretty much
|
||||
any case where glibc copies constants from Linux kernel headers should
|
||||
have such tests that the values and sets of constants agree except
|
||||
where differences are known to be OK. Much the same also applies to
|
||||
structure layouts (although testing those without hardcoding lists of
|
||||
fields to test will be more complicated).
|
||||
|
||||
Given this patch, another test for a set of macros would essentially
|
||||
be just a call to glibcextract.compare_macro_consts (plus boilerplate
|
||||
code - and we could move to having separate text files defining such
|
||||
tests, like the .sym inputs to gen-as-const, so that only a single
|
||||
Python script is needed for most such tests). Some such tests would
|
||||
of course need new features, e.g. where the set of macros changes in
|
||||
new kernel versions (so you need to allow new macro names on the
|
||||
kernel side if the kernel headers are newer than the version known to
|
||||
glibc, and extra macros on the glibc side if the kernel headers are
|
||||
older). tst-syscall-list.sh could become a Python script that uses
|
||||
common code to generate lists of macros but does other things with its
|
||||
own custom logic.
|
||||
|
||||
There are a few differences from the existing shell + awk test.
|
||||
Because the new test evaluates constants using the compiler, no
|
||||
special handling is needed any more for one signal name being defined
|
||||
to another. Because asm/signal.h now needs to pass through the
|
||||
compiler, not just the preprocessor, stddef.h is included as well
|
||||
(given the asm/signal.h issue that it requires an externally provided
|
||||
definition of size_t). The previous code defined __ASSEMBLER__ with
|
||||
asm/signal.h; this is removed (__ASSEMBLY__, a different macro,
|
||||
eliminates the requirement for stddef.h on some but not all
|
||||
architectures).
|
||||
|
||||
Tested for x86_64, and with build-many-glibcs.py.
|
||||
|
||||
* scripts/glibcextract.py: New file.
|
||||
* scripts/gen-as-const.py: Do not import os.path, re, subprocess
|
||||
or tempfile. Import glibcexctract.
|
||||
(compute_c_consts): Remove. Moved to glibcextract.py.
|
||||
(gen_test): Update reference to compute_c_consts.
|
||||
(main): Likewise.
|
||||
* sysdeps/unix/sysv/linux/tst-signal-numbers.py: New file.
|
||||
* sysdeps/unix/sysv/linux/tst-signal-numbers.sh: Remove.
|
||||
* sysdeps/unix/sysv/linux/Makefile
|
||||
($(objpfx)tst-signal-numbers.out): Use tst-signal-numbers.py.
|
||||
Redirect stderr as well as stdout.
|
||||
|
||||
diff --git a/scripts/gen-as-const.py b/scripts/gen-as-const.py
|
||||
index eb85ef1aa0f4934d..f85e359394acb1a4 100644
|
||||
--- a/scripts/gen-as-const.py
|
||||
+++ b/scripts/gen-as-const.py
|
||||
@@ -24,68 +24,14 @@
|
||||
# A line giving just a name implies an expression consisting of just that name.
|
||||
|
||||
import argparse
|
||||
-import os.path
|
||||
-import re
|
||||
-import subprocess
|
||||
-import tempfile
|
||||
|
||||
-
|
||||
-def compute_c_consts(sym_data, cc):
|
||||
- """Compute the values of some C constants.
|
||||
-
|
||||
- The first argument is a list whose elements are either strings
|
||||
- (preprocessor directives, or the special string 'START' to
|
||||
- indicate this function should insert its initial boilerplate text
|
||||
- in the output there) or pairs of strings (a name and a C
|
||||
- expression for the corresponding value). Preprocessor directives
|
||||
- in the middle of the list may be used to select which constants
|
||||
- end up being evaluated using which expressions.
|
||||
-
|
||||
- """
|
||||
- out_lines = []
|
||||
- for arg in sym_data:
|
||||
- if isinstance(arg, str):
|
||||
- if arg == 'START':
|
||||
- out_lines.append('void\ndummy (void)\n{')
|
||||
- else:
|
||||
- out_lines.append(arg)
|
||||
- continue
|
||||
- name = arg[0]
|
||||
- value = arg[1]
|
||||
- out_lines.append('asm ("@@@name@@@%s@@@value@@@%%0@@@end@@@" '
|
||||
- ': : \"i\" ((long int) (%s)));'
|
||||
- % (name, value))
|
||||
- out_lines.append('}')
|
||||
- out_lines.append('')
|
||||
- out_text = '\n'.join(out_lines)
|
||||
- with tempfile.TemporaryDirectory() as temp_dir:
|
||||
- c_file_name = os.path.join(temp_dir, 'test.c')
|
||||
- s_file_name = os.path.join(temp_dir, 'test.s')
|
||||
- with open(c_file_name, 'w') as c_file:
|
||||
- c_file.write(out_text)
|
||||
- # Compilation has to be from stdin to avoid the temporary file
|
||||
- # name being written into the generated dependencies.
|
||||
- cmd = ('%s -S -o %s -x c - < %s' % (cc, s_file_name, c_file_name))
|
||||
- subprocess.check_call(cmd, shell=True)
|
||||
- consts = {}
|
||||
- with open(s_file_name, 'r') as s_file:
|
||||
- for line in s_file:
|
||||
- match = re.search('@@@name@@@([^@]*)'
|
||||
- '@@@value@@@[^0-9Xxa-fA-F-]*'
|
||||
- '([0-9Xxa-fA-F-]+).*@@@end@@@', line)
|
||||
- if match:
|
||||
- if (match.group(1) in consts
|
||||
- and match.group(2) != consts[match.group(1)]):
|
||||
- raise ValueError('duplicate constant %s'
|
||||
- % match.group(1))
|
||||
- consts[match.group(1)] = match.group(2)
|
||||
- return consts
|
||||
+import glibcextract
|
||||
|
||||
|
||||
def gen_test(sym_data):
|
||||
"""Generate a test for the values of some C constants.
|
||||
|
||||
- The first argument is as for compute_c_consts.
|
||||
+ The first argument is as for glibcextract.compute_c_consts.
|
||||
|
||||
"""
|
||||
out_lines = []
|
||||
@@ -158,7 +104,7 @@ def main():
|
||||
if args.test:
|
||||
print(gen_test(sym_data))
|
||||
else:
|
||||
- consts = compute_c_consts(sym_data, args.cc)
|
||||
+ 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__':
|
||||
diff --git a/scripts/glibcextract.py b/scripts/glibcextract.py
|
||||
new file mode 100644
|
||||
index 0000000000000000..ecc4d5b6cc387c7d
|
||||
--- /dev/null
|
||||
+++ b/scripts/glibcextract.py
|
||||
@@ -0,0 +1,162 @@
|
||||
+#!/usr/bin/python3
|
||||
+# Extract information from C headers.
|
||||
+# 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/>.
|
||||
+
|
||||
+import os.path
|
||||
+import re
|
||||
+import subprocess
|
||||
+import tempfile
|
||||
+
|
||||
+
|
||||
+def compute_c_consts(sym_data, cc):
|
||||
+ """Compute the values of some C constants.
|
||||
+
|
||||
+ The first argument is a list whose elements are either strings
|
||||
+ (preprocessor directives, or the special string 'START' to
|
||||
+ indicate this function should insert its initial boilerplate text
|
||||
+ in the output there) or pairs of strings (a name and a C
|
||||
+ expression for the corresponding value). Preprocessor directives
|
||||
+ in the middle of the list may be used to select which constants
|
||||
+ end up being evaluated using which expressions.
|
||||
+
|
||||
+ """
|
||||
+ out_lines = []
|
||||
+ for arg in sym_data:
|
||||
+ if isinstance(arg, str):
|
||||
+ if arg == 'START':
|
||||
+ out_lines.append('void\ndummy (void)\n{')
|
||||
+ else:
|
||||
+ out_lines.append(arg)
|
||||
+ continue
|
||||
+ name = arg[0]
|
||||
+ value = arg[1]
|
||||
+ out_lines.append('asm ("@@@name@@@%s@@@value@@@%%0@@@end@@@" '
|
||||
+ ': : \"i\" ((long int) (%s)));'
|
||||
+ % (name, value))
|
||||
+ out_lines.append('}')
|
||||
+ out_lines.append('')
|
||||
+ out_text = '\n'.join(out_lines)
|
||||
+ with tempfile.TemporaryDirectory() as temp_dir:
|
||||
+ c_file_name = os.path.join(temp_dir, 'test.c')
|
||||
+ s_file_name = os.path.join(temp_dir, 'test.s')
|
||||
+ with open(c_file_name, 'w') as c_file:
|
||||
+ c_file.write(out_text)
|
||||
+ # Compilation has to be from stdin to avoid the temporary file
|
||||
+ # name being written into the generated dependencies.
|
||||
+ cmd = ('%s -S -o %s -x c - < %s' % (cc, s_file_name, c_file_name))
|
||||
+ subprocess.check_call(cmd, shell=True)
|
||||
+ consts = {}
|
||||
+ with open(s_file_name, 'r') as s_file:
|
||||
+ for line in s_file:
|
||||
+ match = re.search('@@@name@@@([^@]*)'
|
||||
+ '@@@value@@@[^0-9Xxa-fA-F-]*'
|
||||
+ '([0-9Xxa-fA-F-]+).*@@@end@@@', line)
|
||||
+ if match:
|
||||
+ if (match.group(1) in consts
|
||||
+ and match.group(2) != consts[match.group(1)]):
|
||||
+ raise ValueError('duplicate constant %s'
|
||||
+ % match.group(1))
|
||||
+ consts[match.group(1)] = match.group(2)
|
||||
+ return consts
|
||||
+
|
||||
+
|
||||
+def list_macros(source_text, cc):
|
||||
+ """List the preprocessor macros defined by the given source code.
|
||||
+
|
||||
+ The return value is a pair of dicts, the first one mapping macro
|
||||
+ names to their expansions and the second one mapping macro names
|
||||
+ to lists of their arguments, or to None for object-like macros.
|
||||
+
|
||||
+ """
|
||||
+ with tempfile.TemporaryDirectory() as temp_dir:
|
||||
+ c_file_name = os.path.join(temp_dir, 'test.c')
|
||||
+ i_file_name = os.path.join(temp_dir, 'test.i')
|
||||
+ with open(c_file_name, 'w') as c_file:
|
||||
+ c_file.write(source_text)
|
||||
+ cmd = ('%s -E -dM -o %s %s' % (cc, i_file_name, c_file_name))
|
||||
+ subprocess.check_call(cmd, shell=True)
|
||||
+ macros_exp = {}
|
||||
+ macros_args = {}
|
||||
+ with open(i_file_name, 'r') as i_file:
|
||||
+ for line in i_file:
|
||||
+ match = re.fullmatch('#define ([0-9A-Za-z_]+)(.*)\n', line)
|
||||
+ if not match:
|
||||
+ raise ValueError('bad -dM output line: %s' % line)
|
||||
+ name = match.group(1)
|
||||
+ value = match.group(2)
|
||||
+ if value.startswith(' '):
|
||||
+ value = value[1:]
|
||||
+ args = None
|
||||
+ elif value.startswith('('):
|
||||
+ match = re.fullmatch(r'\((.*?)\) (.*)', value)
|
||||
+ if not match:
|
||||
+ raise ValueError('bad -dM output line: %s' % line)
|
||||
+ args = match.group(1).split(',')
|
||||
+ value = match.group(2)
|
||||
+ else:
|
||||
+ raise ValueError('bad -dM output line: %s' % line)
|
||||
+ if name in macros_exp:
|
||||
+ raise ValueError('duplicate macro: %s' % line)
|
||||
+ macros_exp[name] = value
|
||||
+ macros_args[name] = args
|
||||
+ return macros_exp, macros_args
|
||||
+
|
||||
+
|
||||
+def compute_macro_consts(source_text, cc, macro_re, exclude_re=None):
|
||||
+ """Compute the integer constant values of macros defined by source_text.
|
||||
+
|
||||
+ Macros must match the regular expression macro_re, and if
|
||||
+ exclude_re is defined they must not match exclude_re. Values are
|
||||
+ computed with compute_c_consts.
|
||||
+
|
||||
+ """
|
||||
+ macros_exp, macros_args = list_macros(source_text, cc)
|
||||
+ macros_set = {m for m in macros_exp
|
||||
+ if (macros_args[m] is None
|
||||
+ and re.fullmatch(macro_re, m)
|
||||
+ and (exclude_re is None
|
||||
+ or not re.fullmatch(exclude_re, m)))}
|
||||
+ sym_data = [source_text, 'START']
|
||||
+ sym_data.extend(sorted((m, m) for m in macros_set))
|
||||
+ return compute_c_consts(sym_data, cc)
|
||||
+
|
||||
+
|
||||
+def compare_macro_consts(source_1, source_2, cc, macro_re, exclude_re=None):
|
||||
+ """Compare the values of macros defined by two different sources.
|
||||
+
|
||||
+ The sources would typically be includes of a glibc header and a
|
||||
+ kernel header. Return 1 if there were any differences, 0 if the
|
||||
+ macro values were the same.
|
||||
+
|
||||
+ """
|
||||
+ macros_1 = compute_macro_consts(source_1, cc, macro_re, exclude_re)
|
||||
+ macros_2 = compute_macro_consts(source_2, cc, macro_re, exclude_re)
|
||||
+ if macros_1 == macros_2:
|
||||
+ return 0
|
||||
+ print('First source:\n%s\n' % source_1)
|
||||
+ print('Second source:\n%s\n' % source_2)
|
||||
+ for name, value in sorted(macros_1.items()):
|
||||
+ if name not in macros_2:
|
||||
+ print('Only in first source: %s' % name)
|
||||
+ elif macros_1[name] != macros_2[name]:
|
||||
+ print('Different values for %s: %s != %s'
|
||||
+ % (name, macros_1[name], macros_2[name]))
|
||||
+ for name in sorted(macros_2.keys()):
|
||||
+ if name not in macros_1:
|
||||
+ print('Only in second source: %s' % name)
|
||||
+ return 1
|
||||
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
|
||||
index bb055f9d6b841ff5..9c10ee53b26e1b1b 100644
|
||||
--- a/sysdeps/unix/sysv/linux/Makefile
|
||||
+++ b/sysdeps/unix/sysv/linux/Makefile
|
||||
@@ -113,11 +113,14 @@ tests-special += $(objpfx)tst-signal-numbers.out
|
||||
# in this context, but signal.c includes signal.h and not much else so it'll
|
||||
# be conservatively correct.
|
||||
$(objpfx)tst-signal-numbers.out: \
|
||||
- ../sysdeps/unix/sysv/linux/tst-signal-numbers.sh \
|
||||
+ ../sysdeps/unix/sysv/linux/tst-signal-numbers.py \
|
||||
$(objpfx)signal.o*
|
||||
- AWK=$(AWK) $(SHELL) ../sysdeps/unix/sysv/linux/tst-signal-numbers.sh \
|
||||
- $(CC) $(patsubst -DMODULE_NAME=%,-DMODULE_NAME=testsuite,$(CPPFLAGS)) \
|
||||
- < /dev/null > $@; $(evaluate-test)
|
||||
+ PYTHONPATH=../scripts \
|
||||
+ $(PYTHON) ../sysdeps/unix/sysv/linux/tst-signal-numbers.py \
|
||||
+ --cc="$(CC) $(patsubst -DMODULE_NAME=%, \
|
||||
+ -DMODULE_NAME=testsuite, \
|
||||
+ $(CPPFLAGS))" \
|
||||
+ < /dev/null > $@ 2>&1; $(evaluate-test)
|
||||
endif
|
||||
|
||||
ifeq ($(subdir),socket)
|
||||
diff --git a/sysdeps/unix/sysv/linux/tst-signal-numbers.py b/sysdeps/unix/sysv/linux/tst-signal-numbers.py
|
||||
new file mode 100644
|
||||
index 0000000000000000..48c63d1218e8303d
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/unix/sysv/linux/tst-signal-numbers.py
|
||||
@@ -0,0 +1,48 @@
|
||||
+#!/usr/bin/python3
|
||||
+# Test that glibc's signal numbers match the kernel's.
|
||||
+# 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/>.
|
||||
+
|
||||
+import argparse
|
||||
+import sys
|
||||
+
|
||||
+import glibcextract
|
||||
+
|
||||
+
|
||||
+def main():
|
||||
+ """The main entry point."""
|
||||
+ parser = argparse.ArgumentParser(
|
||||
+ description="Test that glibc's signal numbers match the kernel's.")
|
||||
+ parser.add_argument('--cc', metavar='CC',
|
||||
+ help='C compiler (including options) to use')
|
||||
+ args = parser.parse_args()
|
||||
+ sys.exit(glibcextract.compare_macro_consts(
|
||||
+ '#define _GNU_SOURCE 1\n'
|
||||
+ '#include <signal.h>\n',
|
||||
+ '#define _GNU_SOURCE 1\n'
|
||||
+ '#include <stddef.h>\n'
|
||||
+ '#include <asm/signal.h>\n',
|
||||
+ args.cc,
|
||||
+ # Filter out constants that aren't signal numbers.
|
||||
+ 'SIG[A-Z]+',
|
||||
+ # Discard obsolete signal numbers and unrelated constants:
|
||||
+ # SIGCLD, SIGIOT, SIGSWI, SIGUNUSED.
|
||||
+ # SIGSTKSZ, SIGRTMIN, SIGRTMAX.
|
||||
+ 'SIG(CLD|IOT|RT(MIN|MAX)|STKSZ|SWI|UNUSED)'))
|
||||
+
|
||||
+if __name__ == '__main__':
|
||||
+ main()
|
||||
diff --git a/sysdeps/unix/sysv/linux/tst-signal-numbers.sh b/sysdeps/unix/sysv/linux/tst-signal-numbers.sh
|
||||
deleted file mode 100644
|
||||
index e1f7be0337c720a6..0000000000000000
|
||||
--- a/sysdeps/unix/sysv/linux/tst-signal-numbers.sh
|
||||
+++ /dev/null
|
||||
@@ -1,86 +0,0 @@
|
||||
-#! /bin/sh
|
||||
-# Test that glibc's signal numbers match the kernel's.
|
||||
-# Copyright (C) 2017-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/>.
|
||||
-
|
||||
-set -e
|
||||
-if [ -n "$BASH_VERSION" ]; then set -o pipefail; fi
|
||||
-LC_ALL=C; export LC_ALL
|
||||
-
|
||||
-# We cannot use Linux's asm/signal.h to define signal numbers, because
|
||||
-# it isn't sufficiently namespace-clean. Instead, this test checks
|
||||
-# that our signal numbers match the kernel's. This script expects
|
||||
-# "$@" to be $(CC) $(CPPFLAGS) as set by glibc's Makefiles, and $AWK
|
||||
-# to be set in the environment.
|
||||
-
|
||||
-# Before doing anything else, fail if the compiler doesn't work.
|
||||
-"$@" -E -xc -dM - < /dev/null > /dev/null
|
||||
-
|
||||
-tmpG=`mktemp -t signums_glibc.XXXXXXXXX`
|
||||
-tmpK=`mktemp -t signums_kernel.XXXXXXXXX`
|
||||
-trap "rm -f '$tmpG' '$tmpK'" 0
|
||||
-
|
||||
-# Filter out constants that aren't signal numbers.
|
||||
-# If SIGPOLL is defined as SIGIO, swap it around so SIGIO is defined as
|
||||
-# SIGPOLL. Similarly for SIGABRT and SIGIOT.
|
||||
-# Discard obsolete signal numbers and unrelated constants:
|
||||
-# SIGCLD, SIGIOT, SIGSWI, SIGUNUSED.
|
||||
-# SIGSTKSZ, SIGRTMIN, SIGRTMAX.
|
||||
-# Then sort the list.
|
||||
-filter_defines ()
|
||||
-{
|
||||
- $AWK '
|
||||
-/^#define SIG[A-Z]+ ([0-9]+|SIG[A-Z0-9]+)$/ { signals[$2] = $3 }
|
||||
-END {
|
||||
- if ("SIGPOLL" in signals && "SIGIO" in signals &&
|
||||
- signals["SIGPOLL"] == "SIGIO") {
|
||||
- signals["SIGPOLL"] = signals["SIGIO"]
|
||||
- signals["SIGIO"] = "SIGPOLL"
|
||||
- }
|
||||
- if ("SIGABRT" in signals && "SIGIOT" in signals &&
|
||||
- signals["SIGABRT"] == "SIGIOT") {
|
||||
- signals["SIGABRT"] = signals["SIGIOT"]
|
||||
- signals["SIGIOT"] = "SIGABRT"
|
||||
- }
|
||||
- for (sig in signals) {
|
||||
- if (sig !~ /^SIG(CLD|IOT|RT(MIN|MAX)|STKSZ|SWI|UNUSED)$/) {
|
||||
- printf("#define %s %s\n", sig, signals[sig])
|
||||
- }
|
||||
- }
|
||||
-}' | sort
|
||||
-}
|
||||
-
|
||||
-# $CC may contain command-line switches, so it should be word-split.
|
||||
-printf '%s' '#define _GNU_SOURCE 1
|
||||
-#include <signal.h>
|
||||
-' |
|
||||
- "$@" -E -xc -dM - |
|
||||
- filter_defines > "$tmpG"
|
||||
-
|
||||
-printf '%s' '#define _GNU_SOURCE 1
|
||||
-#define __ASSEMBLER__ 1
|
||||
-#include <asm/signal.h>
|
||||
-' |
|
||||
- "$@" -E -xc -dM - |
|
||||
- filter_defines > "$tmpK"
|
||||
-
|
||||
-if cmp -s "$tmpG" "$tmpK"; then
|
||||
- exit 0
|
||||
-else
|
||||
- diff -u "$tmpG" "$tmpK"
|
||||
- exit 1
|
||||
-fi
|
98
SOURCES/glibc-rh2109510-6.patch
Normal file
98
SOURCES/glibc-rh2109510-6.patch
Normal file
@ -0,0 +1,98 @@
|
||||
Partial backport of:
|
||||
|
||||
commit cb7be1590e9b18e272e72eb4e910a7ad06a53bd0
|
||||
Author: Joseph Myers <joseph@codesourcery.com>
|
||||
Date: Mon Dec 10 22:56:59 2018 +0000
|
||||
|
||||
Use gen-as-const.py to process .pysym files.
|
||||
|
||||
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.
|
||||
|
||||
Only the gen-as-const.py changes are included downstream. We keep using
|
||||
gen-py-const.awk for the build.
|
||||
|
||||
diff --git a/scripts/gen-as-const.py b/scripts/gen-as-const.py
|
||||
index f85e359394acb1a4..2f1dff092b98e044 100644
|
||||
--- a/scripts/gen-as-const.py
|
||||
+++ b/scripts/gen-as-const.py
|
||||
@@ -75,6 +75,8 @@ def main():
|
||||
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()
|
||||
@@ -103,6 +105,13 @@ def main():
|
||||
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='')
|
178
SOURCES/glibc-rh2109510-7.patch
Normal file
178
SOURCES/glibc-rh2109510-7.patch
Normal file
@ -0,0 +1,178 @@
|
||||
commit df648905e7d8340bb3e78813fd25e2077b9685d9
|
||||
Author: Joseph Myers <joseph@codesourcery.com>
|
||||
Date: Mon Dec 17 18:29:36 2018 +0000
|
||||
|
||||
Add test that MAP_* constants agree with kernel.
|
||||
|
||||
Continuing the process of building up and using Python infrastructure
|
||||
for extracting and using values in headers, this patch adds a test
|
||||
that MAP_* constants from sys/mman.h agree with those in the Linux
|
||||
kernel headers. (Other sys/mman.h constants could be added to the
|
||||
test separately.)
|
||||
|
||||
This set of constants has grown over time, so the generic code is
|
||||
enhanced to allow saying extra constants are OK on either side of the
|
||||
comparison (where the caller sets those parameters based on the Linux
|
||||
kernel headers version, compared with the version the headers were
|
||||
last updated from). Although the test is a custom Python file, my
|
||||
intention is to move in future to a single Python script for such
|
||||
tests and text files it takes as inputs, once there are enough
|
||||
examples to provide a guide to the common cases in such tests (I'd
|
||||
like to end up with most or all such sets of constants copied from
|
||||
kernel headers having such tests, and likewise for structure layouts
|
||||
from the kernel).
|
||||
|
||||
The Makefile code is essentially the same as for tst-signal-numbers,
|
||||
but I didn't try to find an object file to depend on to represent the
|
||||
dependency on the headers used by the test (the conform/ tests don't
|
||||
try to represent such header dependencies at all, for example).
|
||||
|
||||
Tested with build-many-glibcs.py, and also for x86_64 with older
|
||||
kernel headers.
|
||||
|
||||
* scripts/glibcextract.py (compare_macro_consts): Take parameters
|
||||
to allow extra macros from first or second sources.
|
||||
* sysdeps/unix/sysv/linux/tst-mman-consts.py: New file.
|
||||
* sysdeps/unix/sysv/linux/Makefile [$(subdir) = misc]
|
||||
(tests-special): Add $(objpfx)tst-mman-consts.out.
|
||||
($(objpfx)tst-mman-consts.out): New makefile target.
|
||||
|
||||
diff --git a/scripts/glibcextract.py b/scripts/glibcextract.py
|
||||
index ecc4d5b6cc387c7d..06f712ad115e0f9e 100644
|
||||
--- a/scripts/glibcextract.py
|
||||
+++ b/scripts/glibcextract.py
|
||||
@@ -136,12 +136,19 @@ def compute_macro_consts(source_text, cc, macro_re, exclude_re=None):
|
||||
return compute_c_consts(sym_data, cc)
|
||||
|
||||
|
||||
-def compare_macro_consts(source_1, source_2, cc, macro_re, exclude_re=None):
|
||||
+def compare_macro_consts(source_1, source_2, cc, macro_re, exclude_re=None,
|
||||
+ allow_extra_1=False, allow_extra_2=False):
|
||||
"""Compare the values of macros defined by two different sources.
|
||||
|
||||
The sources would typically be includes of a glibc header and a
|
||||
- kernel header. Return 1 if there were any differences, 0 if the
|
||||
- macro values were the same.
|
||||
+ kernel header. If allow_extra_1, the first source may define
|
||||
+ extra macros (typically if the kernel headers are older than the
|
||||
+ version glibc has taken definitions from); if allow_extra_2, the
|
||||
+ second source may define extra macros (typically if the kernel
|
||||
+ headers are newer than the version glibc has taken definitions
|
||||
+ from). Return 1 if there were any differences other than those
|
||||
+ allowed, 0 if the macro values were the same apart from any
|
||||
+ allowed differences.
|
||||
|
||||
"""
|
||||
macros_1 = compute_macro_consts(source_1, cc, macro_re, exclude_re)
|
||||
@@ -150,13 +157,19 @@ def compare_macro_consts(source_1, source_2, cc, macro_re, exclude_re=None):
|
||||
return 0
|
||||
print('First source:\n%s\n' % source_1)
|
||||
print('Second source:\n%s\n' % source_2)
|
||||
+ ret = 0
|
||||
for name, value in sorted(macros_1.items()):
|
||||
if name not in macros_2:
|
||||
print('Only in first source: %s' % name)
|
||||
+ if not allow_extra_1:
|
||||
+ ret = 1
|
||||
elif macros_1[name] != macros_2[name]:
|
||||
print('Different values for %s: %s != %s'
|
||||
% (name, macros_1[name], macros_2[name]))
|
||||
+ ret = 1
|
||||
for name in sorted(macros_2.keys()):
|
||||
if name not in macros_1:
|
||||
print('Only in second source: %s' % name)
|
||||
- return 1
|
||||
+ if not allow_extra_2:
|
||||
+ ret = 1
|
||||
+ return ret
|
||||
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
|
||||
index 9c10ee53b26e1b1b..863ed80c2a2713d3 100644
|
||||
--- a/sysdeps/unix/sysv/linux/Makefile
|
||||
+++ b/sysdeps/unix/sysv/linux/Makefile
|
||||
@@ -98,6 +98,15 @@ $(objpfx)tst-sysconf-iov_max: $(objpfx)tst-sysconf-iov_max-uapi.o
|
||||
|
||||
$(objpfx)tst-pkey: $(shared-thread-library)
|
||||
|
||||
+tests-special += $(objpfx)tst-mman-consts.out
|
||||
+$(objpfx)tst-mman-consts.out: ../sysdeps/unix/sysv/linux/tst-mman-consts.py
|
||||
+ PYTHONPATH=../scripts \
|
||||
+ $(PYTHON) ../sysdeps/unix/sysv/linux/tst-mman-consts.py \
|
||||
+ --cc="$(CC) $(patsubst -DMODULE_NAME=%, \
|
||||
+ -DMODULE_NAME=testsuite, \
|
||||
+ $(CPPFLAGS))" \
|
||||
+ < /dev/null > $@ 2>&1; $(evaluate-test)
|
||||
+
|
||||
endif # $(subdir) == misc
|
||||
|
||||
ifeq ($(subdir),time)
|
||||
diff --git a/sysdeps/unix/sysv/linux/tst-mman-consts.py b/sysdeps/unix/sysv/linux/tst-mman-consts.py
|
||||
new file mode 100644
|
||||
index 0000000000000000..1a613beec0da16fb
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/unix/sysv/linux/tst-mman-consts.py
|
||||
@@ -0,0 +1,65 @@
|
||||
+#!/usr/bin/python3
|
||||
+# Test that glibc's sys/mman.h constants match the kernel's.
|
||||
+# 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/>.
|
||||
+
|
||||
+import argparse
|
||||
+import sys
|
||||
+
|
||||
+import glibcextract
|
||||
+
|
||||
+
|
||||
+def linux_kernel_version(cc):
|
||||
+ """Return the (major, minor) version of the Linux kernel headers."""
|
||||
+ sym_data = ['#include <linux/version.h>', 'START',
|
||||
+ ('LINUX_VERSION_CODE', 'LINUX_VERSION_CODE')]
|
||||
+ val = glibcextract.compute_c_consts(sym_data, cc)['LINUX_VERSION_CODE']
|
||||
+ val = int(val)
|
||||
+ return ((val & 0xff0000) >> 16, (val & 0xff00) >> 8)
|
||||
+
|
||||
+
|
||||
+def main():
|
||||
+ """The main entry point."""
|
||||
+ parser = argparse.ArgumentParser(
|
||||
+ description="Test that glibc's sys/mman.h constants "
|
||||
+ "match the kernel's.")
|
||||
+ parser.add_argument('--cc', metavar='CC',
|
||||
+ help='C compiler (including options) to use')
|
||||
+ args = parser.parse_args()
|
||||
+ linux_version_headers = linux_kernel_version(args.cc)
|
||||
+ linux_version_glibc = (4, 19)
|
||||
+ sys.exit(glibcextract.compare_macro_consts(
|
||||
+ '#define _GNU_SOURCE 1\n'
|
||||
+ '#include <sys/mman.h>\n',
|
||||
+ '#define _GNU_SOURCE 1\n'
|
||||
+ '#include <linux/mman.h>\n',
|
||||
+ args.cc,
|
||||
+ 'MAP_.*',
|
||||
+ # A series of MAP_HUGE_<size> macros are defined by the kernel
|
||||
+ # but not by glibc. MAP_UNINITIALIZED is kernel-only.
|
||||
+ # MAP_FAILED is not a MAP_* flag and is glibc-only, as is the
|
||||
+ # MAP_ANON alias for MAP_ANONYMOUS. MAP_RENAME, MAP_AUTOGROW,
|
||||
+ # MAP_LOCAL and MAP_AUTORSRV are in the kernel header for
|
||||
+ # MIPS, marked as "not used by linux"; SPARC has MAP_INHERIT
|
||||
+ # in the kernel header, but does not use it.
|
||||
+ 'MAP_HUGE_[0-9].*|MAP_UNINITIALIZED|MAP_FAILED|MAP_ANON'
|
||||
+ '|MAP_RENAME|MAP_AUTOGROW|MAP_LOCAL|MAP_AUTORSRV|MAP_INHERIT',
|
||||
+ linux_version_glibc > linux_version_headers,
|
||||
+ linux_version_headers > linux_version_glibc))
|
||||
+
|
||||
+if __name__ == '__main__':
|
||||
+ main()
|
23
SOURCES/glibc-rh2109510-8.patch
Normal file
23
SOURCES/glibc-rh2109510-8.patch
Normal file
@ -0,0 +1,23 @@
|
||||
commit 46baeb61e16511f26db1b255e19dc9163f590367
|
||||
Author: Fangrui Song <maskray@google.com>
|
||||
Date: Tue Oct 19 09:58:16 2021 -0700
|
||||
|
||||
glibcextract.py: Place un-assemblable @@@ in a comment
|
||||
|
||||
Unlike GCC, Clang parses asm statements and verifies they are valid
|
||||
instructions/directives. Place the magic @@@ into a comment to avoid
|
||||
a parse error.
|
||||
|
||||
diff --git a/scripts/glibcextract.py b/scripts/glibcextract.py
|
||||
index 06f712ad115e0f9e..8f2246aae6a9dfb7 100644
|
||||
--- a/scripts/glibcextract.py
|
||||
+++ b/scripts/glibcextract.py
|
||||
@@ -45,7 +45,7 @@ def compute_c_consts(sym_data, cc):
|
||||
continue
|
||||
name = arg[0]
|
||||
value = arg[1]
|
||||
- out_lines.append('asm ("@@@name@@@%s@@@value@@@%%0@@@end@@@" '
|
||||
+ out_lines.append('asm ("/* @@@name@@@%s@@@value@@@%%0@@@end@@@ */" '
|
||||
': : \"i\" ((long int) (%s)));'
|
||||
% (name, value))
|
||||
out_lines.append('}')
|
45
SOURCES/glibc-rh2109510-9.patch
Normal file
45
SOURCES/glibc-rh2109510-9.patch
Normal file
@ -0,0 +1,45 @@
|
||||
commit 841afa116e32b3c7195475769c26bf46fd870d32
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Wed Aug 10 16:24:06 2022 -0300
|
||||
|
||||
glibcextract.py: Add compile_c_snippet
|
||||
|
||||
It might be used on tests to check if a snippet build with the provided
|
||||
compiler and flags.
|
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
diff --git a/scripts/glibcextract.py b/scripts/glibcextract.py
|
||||
index 8f2246aae6a9dfb7..0fb50dc8f9c4f7f9 100644
|
||||
--- a/scripts/glibcextract.py
|
||||
+++ b/scripts/glibcextract.py
|
||||
@@ -17,6 +17,7 @@
|
||||
# License along with the GNU C Library; if not, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
+import collections
|
||||
import os.path
|
||||
import re
|
||||
import subprocess
|
||||
@@ -173,3 +174,21 @@ def compare_macro_consts(source_1, source_2, cc, macro_re, exclude_re=None,
|
||||
if not allow_extra_2:
|
||||
ret = 1
|
||||
return ret
|
||||
+
|
||||
+CompileResult = collections.namedtuple("CompileResult", "returncode output")
|
||||
+
|
||||
+def compile_c_snippet(snippet, cc, extra_cc_args=''):
|
||||
+ """Compile and return whether the SNIPPET can be build with CC along
|
||||
+ EXTRA_CC_ARGS compiler flags. Return a CompileResult with RETURNCODE
|
||||
+ being 0 for success, or the failure value and the compiler output.
|
||||
+ """
|
||||
+ with tempfile.TemporaryDirectory() as temp_dir:
|
||||
+ c_file_name = os.path.join(temp_dir, 'test.c')
|
||||
+ obj_file_name = os.path.join(temp_dir, 'test.o')
|
||||
+ with open(c_file_name, 'w') as c_file:
|
||||
+ c_file.write(snippet + '\n')
|
||||
+ cmd = cc.split() + extra_cc_args.split() + ['-c', '-o', obj_file_name,
|
||||
+ c_file_name]
|
||||
+ r = subprocess.run(cmd, check=False, stdout=subprocess.PIPE,
|
||||
+ stderr=subprocess.STDOUT)
|
||||
+ return CompileResult(r.returncode, r.stdout)
|
32
SOURCES/glibc-rh2139875-1.patch
Normal file
32
SOURCES/glibc-rh2139875-1.patch
Normal file
@ -0,0 +1,32 @@
|
||||
commit acb55dcb892d4321ada6fd9b663b28fada432682
|
||||
Author: Joseph Myers <joseph@codesourcery.com>
|
||||
Date: Wed Jan 2 18:35:50 2019 +0000
|
||||
|
||||
Update Linux kernel version in tst-mman-consts.py.
|
||||
|
||||
This patch updates the Linux kernel version in tst-mman-consts.py to
|
||||
4.20 (meaning that's the version for which glibc is expected to have
|
||||
the same constants as the kernel, up to the exceptions listed in the
|
||||
test). (Once we have more such tests sharing common infrastructure, I
|
||||
expect the kernel version will be something set in the infrastructure
|
||||
shared by all such tests, rather than something needing updating
|
||||
separately for each test for each new kernel version.)
|
||||
|
||||
Tested with build-many-glibcs.py.
|
||||
|
||||
* sysdeps/unix/sysv/linux/tst-mman-consts.py (main): Expect
|
||||
constants to match with Linux 4.20.
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/tst-mman-consts.py b/sysdeps/unix/sysv/linux/tst-mman-consts.py
|
||||
index 1a613beec0da16fb..4a2ddd49c4c7282b 100644
|
||||
--- a/sysdeps/unix/sysv/linux/tst-mman-consts.py
|
||||
+++ b/sysdeps/unix/sysv/linux/tst-mman-consts.py
|
||||
@@ -41,7 +41,7 @@ def main():
|
||||
help='C compiler (including options) to use')
|
||||
args = parser.parse_args()
|
||||
linux_version_headers = linux_kernel_version(args.cc)
|
||||
- linux_version_glibc = (4, 19)
|
||||
+ linux_version_glibc = (4, 20)
|
||||
sys.exit(glibcextract.compare_macro_consts(
|
||||
'#define _GNU_SOURCE 1\n'
|
||||
'#include <sys/mman.h>\n',
|
31
SOURCES/glibc-rh2139875-2.patch
Normal file
31
SOURCES/glibc-rh2139875-2.patch
Normal file
@ -0,0 +1,31 @@
|
||||
commit c7a26cba2ab949216ac9ef245ca78696815ea4c4
|
||||
Author: Joseph Myers <joseph@codesourcery.com>
|
||||
Date: Fri Aug 2 11:36:07 2019 +0000
|
||||
|
||||
Update Linux kernel version number in tst-mman-consts.py to 5.2.
|
||||
|
||||
The tst-mman-consts.py test includes a kernel version number, to avoid
|
||||
failures because of newly added constants in the kernel (if kernel
|
||||
headers are newer than this version of glibc) or missing constants in
|
||||
the kernel (if kernel headers are older than this version of glibc).
|
||||
This patch updates it to 5.2 to reflect that the MAP_* constants in
|
||||
glibc are still current as of that kernel version.
|
||||
|
||||
Tested with build-many-glibcs.py.
|
||||
|
||||
* sysdeps/unix/sysv/linux/tst-mman-consts.py (main): Update Linux
|
||||
kernel version number to 5.2.
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/tst-mman-consts.py b/sysdeps/unix/sysv/linux/tst-mman-consts.py
|
||||
index 4a2ddd49c4c7282b..9e326b1f31799a72 100644
|
||||
--- a/sysdeps/unix/sysv/linux/tst-mman-consts.py
|
||||
+++ b/sysdeps/unix/sysv/linux/tst-mman-consts.py
|
||||
@@ -41,7 +41,7 @@ def main():
|
||||
help='C compiler (including options) to use')
|
||||
args = parser.parse_args()
|
||||
linux_version_headers = linux_kernel_version(args.cc)
|
||||
- linux_version_glibc = (4, 20)
|
||||
+ linux_version_glibc = (5, 2)
|
||||
sys.exit(glibcextract.compare_macro_consts(
|
||||
'#define _GNU_SOURCE 1\n'
|
||||
'#include <sys/mman.h>\n',
|
61
SOURCES/glibc-rh2139875-3.patch
Normal file
61
SOURCES/glibc-rh2139875-3.patch
Normal file
@ -0,0 +1,61 @@
|
||||
commit 71bdf29ac1de04efcce96bc5ce50af3263851ac7
|
||||
Author: Joseph Myers <joseph@codesourcery.com>
|
||||
Date: Mon Sep 30 15:49:25 2019 +0000
|
||||
|
||||
Update bits/mman.h constants and tst-mman-consts.py for Linux 5.3.
|
||||
|
||||
The Linux 5.3 uapi headers have some rearrangement relating to MAP_*
|
||||
constants, which includes the effect of adding definitions of MAP_SYNC
|
||||
on powerpc and sparc. This patch updates the corresponding glibc
|
||||
bits/mman.h headers accordingly, and updates the Linux kernel version
|
||||
number in tst-mman-consts.py to reflect that these constants are now
|
||||
current with that kernel version.
|
||||
|
||||
Tested with build-many-glibcs.py.
|
||||
|
||||
* sysdeps/unix/sysv/linux/powerpc/bits/mman.h [__USE_MISC]
|
||||
(MAP_SYNC): New macro.
|
||||
* sysdeps/unix/sysv/linux/sparc/bits/mman.h [__USE_MISC]
|
||||
(MAP_SYNC): Likewise.
|
||||
* sysdeps/unix/sysv/linux/tst-mman-consts.py (main): Update Linux
|
||||
kernel version number to 5.3.
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/mman.h b/sysdeps/unix/sysv/linux/powerpc/bits/mman.h
|
||||
index e652467c8c091381..0e7fa647793ed585 100644
|
||||
--- a/sysdeps/unix/sysv/linux/powerpc/bits/mman.h
|
||||
+++ b/sysdeps/unix/sysv/linux/powerpc/bits/mman.h
|
||||
@@ -36,6 +36,8 @@
|
||||
# define MAP_NONBLOCK 0x10000 /* Do not block on IO. */
|
||||
# define MAP_STACK 0x20000 /* Allocation is for a stack. */
|
||||
# define MAP_HUGETLB 0x40000 /* Create huge page mapping. */
|
||||
+# define MAP_SYNC 0x80000 /* Perform synchronous page
|
||||
+ faults for the mapping. */
|
||||
# define MAP_FIXED_NOREPLACE 0x100000 /* MAP_FIXED but do not unmap
|
||||
underlying mapping. */
|
||||
#endif
|
||||
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/mman.h b/sysdeps/unix/sysv/linux/sparc/bits/mman.h
|
||||
index 3a3ffb994631e2b6..03f6f732bb5efbe2 100644
|
||||
--- a/sysdeps/unix/sysv/linux/sparc/bits/mman.h
|
||||
+++ b/sysdeps/unix/sysv/linux/sparc/bits/mman.h
|
||||
@@ -36,6 +36,8 @@
|
||||
# define MAP_NONBLOCK 0x10000 /* Do not block on IO. */
|
||||
# define MAP_STACK 0x20000 /* Allocation is for a stack. */
|
||||
# define MAP_HUGETLB 0x40000 /* Create huge page mapping. */
|
||||
+# define MAP_SYNC 0x80000 /* Perform synchronous page
|
||||
+ faults for the mapping. */
|
||||
# define MAP_FIXED_NOREPLACE 0x100000 /* MAP_FIXED but do not unmap
|
||||
underlying mapping. */
|
||||
#endif
|
||||
diff --git a/sysdeps/unix/sysv/linux/tst-mman-consts.py b/sysdeps/unix/sysv/linux/tst-mman-consts.py
|
||||
index 9e326b1f31799a72..42914e4e0ba84712 100644
|
||||
--- a/sysdeps/unix/sysv/linux/tst-mman-consts.py
|
||||
+++ b/sysdeps/unix/sysv/linux/tst-mman-consts.py
|
||||
@@ -41,7 +41,7 @@ def main():
|
||||
help='C compiler (including options) to use')
|
||||
args = parser.parse_args()
|
||||
linux_version_headers = linux_kernel_version(args.cc)
|
||||
- linux_version_glibc = (5, 2)
|
||||
+ linux_version_glibc = (5, 3)
|
||||
sys.exit(glibcextract.compare_macro_consts(
|
||||
'#define _GNU_SOURCE 1\n'
|
||||
'#include <sys/mman.h>\n',
|
@ -1,6 +1,6 @@
|
||||
%define glibcsrcdir glibc-2.28
|
||||
%define glibcversion 2.28
|
||||
%define glibcrelease 219%{?dist}
|
||||
%define glibcrelease 220%{?dist}
|
||||
# Pre-release tarballs are pulled in from git using a command that is
|
||||
# effectively:
|
||||
#
|
||||
@ -986,6 +986,32 @@ Patch793: glibc-rh2122501-5.patch
|
||||
Patch794: glibc-rh2121746-1.patch
|
||||
Patch795: glibc-rh2121746-2.patch
|
||||
Patch796: glibc-rh2116938.patch
|
||||
Patch797: glibc-rh2109510-1.patch
|
||||
Patch798: glibc-rh2109510-2.patch
|
||||
Patch799: glibc-rh2109510-3.patch
|
||||
Patch800: glibc-rh2109510-4.patch
|
||||
Patch801: glibc-rh2109510-5.patch
|
||||
Patch802: glibc-rh2109510-6.patch
|
||||
Patch803: glibc-rh2109510-7.patch
|
||||
Patch804: glibc-rh2109510-8.patch
|
||||
Patch805: glibc-rh2109510-9.patch
|
||||
Patch806: glibc-rh2109510-10.patch
|
||||
Patch807: glibc-rh2109510-11.patch
|
||||
Patch808: glibc-rh2109510-12.patch
|
||||
Patch809: glibc-rh2109510-13.patch
|
||||
Patch810: glibc-rh2109510-14.patch
|
||||
Patch811: glibc-rh2109510-15.patch
|
||||
Patch812: glibc-rh2109510-16.patch
|
||||
Patch813: glibc-rh2109510-17.patch
|
||||
Patch814: glibc-rh2109510-18.patch
|
||||
Patch815: glibc-rh2109510-19.patch
|
||||
Patch816: glibc-rh2109510-20.patch
|
||||
Patch817: glibc-rh2109510-21.patch
|
||||
Patch818: glibc-rh2109510-22.patch
|
||||
Patch819: glibc-rh2109510-23.patch
|
||||
Patch820: glibc-rh2139875-1.patch
|
||||
Patch821: glibc-rh2139875-2.patch
|
||||
Patch822: glibc-rh2139875-3.patch
|
||||
|
||||
##############################################################################
|
||||
# Continued list of core "glibc" package information:
|
||||
@ -2816,6 +2842,10 @@ fi
|
||||
%files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared
|
||||
|
||||
%changelog
|
||||
* Thu Nov 3 2022 Florian Weimer <fweimer@redhat.com> - 2.28-220
|
||||
- Explicitly switch to --with-default-link=no (#2109510)
|
||||
- Define MAP_SYNC on ppc64le (#2139875)
|
||||
|
||||
* Mon Oct 24 2022 Arjun Shankar <arjun@redhat.com> - 2.28-219
|
||||
- Fix -Wstrict-overflow warning when using CMSG_NXTHDR macro (#2116938)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user