commit
e763638f91
@ -0,0 +1 @@
|
||||
SOURCES/glibc-2.34.tar.xz
|
@ -0,0 +1 @@
|
||||
7c3b8890a6346793b6334cc5f2fea5d437d307b8 SOURCES/glibc-2.34.tar.xz
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,77 @@
|
||||
objpfx = $(prefix)/$(ver)/usr/libexec/glibc-benchtests/
|
||||
|
||||
bench-math := acos acosh asin asinh atan atanh cos cosh exp exp2 ffs ffsll \
|
||||
log log2 modf pow rint sin sincos sinh sqrt tan tanh
|
||||
|
||||
bench-pthread := pthread_once
|
||||
|
||||
bench := $(bench-math) $(bench-pthread)
|
||||
|
||||
run-bench := $(prefix)/$(ver)/lib64/ld-linux-x86-64.so.2 --library-path $(prefix)/$(ver)/lib64 $${run}
|
||||
|
||||
# String function benchmarks.
|
||||
string-bench := bcopy bzero memccpy memchr memcmp memcpy memmem memmove \
|
||||
mempcpy memset rawmemchr stpcpy stpncpy strcasecmp strcasestr \
|
||||
strcat strchr strchrnul strcmp strcpy strcspn strlen \
|
||||
strncasecmp strncat strncmp strncpy strnlen strpbrk strrchr \
|
||||
strspn strstr strcpy_chk stpcpy_chk memrchr strsep strtok
|
||||
string-bench-all := $(string-bench)
|
||||
|
||||
stdlib-bench := strtod
|
||||
|
||||
benchset := $(string-bench-all) $(stdlib-bench)
|
||||
|
||||
bench-malloc := malloc-thread
|
||||
|
||||
binaries-bench := $(addprefix $(objpfx)bench-,$(bench))
|
||||
binaries-benchset := $(addprefix $(objpfx)bench-,$(benchset))
|
||||
binaries-bench-malloc := $(addprefix $(objpfx)bench-,$(bench-malloc))
|
||||
|
||||
DETAILED_OPT :=
|
||||
|
||||
ifdef DETAILED
|
||||
DETAILED_OPT := -d
|
||||
endif
|
||||
|
||||
bench: bench-set bench-func bench-malloc
|
||||
|
||||
bench-set: $(binaries-benchset)
|
||||
for run in $^; do \
|
||||
outfile=$(prefix)/$$(basename $${run}.$(ver).out); \
|
||||
echo "Running $${run}"; \
|
||||
$(run-bench) > $${outfile}.tmp; \
|
||||
mv $${outfile}{.tmp,}; \
|
||||
done
|
||||
|
||||
bench-malloc: $(binaries-bench-malloc)
|
||||
run=$(objpfx)bench-malloc-thread; \
|
||||
outfile=$(prefix)/$$(basename $${run}.$(ver).out); \
|
||||
for thr in 1 8 16 32; do \
|
||||
echo "Running $${run} $${thr}"; \
|
||||
$(run-bench) $${thr} > $${outfile}.tmp; \
|
||||
mv $${outfile}{.tmp,}; \
|
||||
done
|
||||
|
||||
# Build and execute the benchmark functions. This target generates JSON
|
||||
# formatted bench.out. Each of the programs produce independent JSON output,
|
||||
# so one could even execute them individually and process it using any JSON
|
||||
# capable language or tool.
|
||||
bench-func: $(binaries-bench)
|
||||
{ echo "{\"timing_type\": \"hp-timing\","; \
|
||||
echo " \"functions\": {"; \
|
||||
for run in $^; do \
|
||||
if ! [ "x$${run}" = "x$<" ]; then \
|
||||
echo ","; \
|
||||
fi; \
|
||||
echo "Running $${run}" >&2; \
|
||||
$(run-bench) $(DETAILED_OPT); \
|
||||
done; \
|
||||
echo; \
|
||||
echo " }"; \
|
||||
echo "}"; } > $(prefix)/bench.$(ver).out-tmp; \
|
||||
if [ -f $(prefix)/bench.$(ver).out ]; then \
|
||||
mv -f $(prefix)/bench.$(ver).out{,.old}; \
|
||||
fi; \
|
||||
mv -f $(prefix)/bench.$(ver).out{-tmp,}
|
||||
# scripts/validate_benchout.py bench.out \
|
||||
# scripts/benchout.schema.json
|
@ -0,0 +1,153 @@
|
||||
#!/usr/bin/bash
|
||||
# This script can be invoked as follows:
|
||||
#
|
||||
# glibc-bench-compare [options] <BUILD> [BUILD]
|
||||
#
|
||||
# Options may be one of the following:
|
||||
#
|
||||
# -t The BUILD arguments are task ids and not a version-release string
|
||||
# -a ARCH Do comparison for ARCH architecture
|
||||
#
|
||||
# If any of the above options are given, both BUILD arguments must be given.
|
||||
# Otherwise, if only one BUILD is specified, then it is compared against the
|
||||
# installed glibc.
|
||||
|
||||
# Silence the pushd/popd messages
|
||||
pushd() {
|
||||
command pushd "$@" > /dev/null 2>&1
|
||||
}
|
||||
|
||||
popd() {
|
||||
command popd "$@" > /dev/null 2>&1
|
||||
}
|
||||
|
||||
# Clean up any downloaded files before we exit
|
||||
trap "rm -rf /tmp/glibc-bench-compare.$BASHPID.*" EXIT
|
||||
|
||||
task=0
|
||||
arch=$(uname -i)
|
||||
options=0
|
||||
path=0
|
||||
installed=
|
||||
|
||||
# Look for any commandline options
|
||||
while getopts ":tpa:" opt; do
|
||||
case $opt in
|
||||
p)
|
||||
path=1
|
||||
;;
|
||||
t)
|
||||
task=1
|
||||
options=1
|
||||
echo "Not implemented."
|
||||
exit 1
|
||||
;;
|
||||
a)
|
||||
arch=$OPTARG
|
||||
options=1
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Done, now shift all option arguments out.
|
||||
shift $((OPTIND-1))
|
||||
|
||||
if [ $# -gt 2 ] || [ $# -eq 0 ] || [ $# -lt 2 -a $options -eq 1 ]; then
|
||||
echo "Usage: $0 [OPTIONS] <old> [new]"
|
||||
echo
|
||||
echo "OPTIONS:"
|
||||
echo -e "\t-t\tCompare two brew tasks"
|
||||
echo -e "\t-a ARCH\tGet rpms for the ARCH architecture"
|
||||
echo -e "\t-p\tCompare built rpms in two paths."
|
||||
echo -e "\t\tThis minimally needs glibc, glibc-common and glibc-benchtests"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z $2 ]; then
|
||||
new="$1"
|
||||
old=$(rpm --queryformat "%{VERSION}-%{RELEASE}\n" -q glibc | head -1)
|
||||
installed=$old
|
||||
else
|
||||
new="$2"
|
||||
old="$1"
|
||||
fi
|
||||
|
||||
decompress_rpms() {
|
||||
# We were given a path to the rpms. Figure out the version-release and
|
||||
# decompress the rpms.
|
||||
if [ -n $1 ]; then
|
||||
vr=$(rpm --queryformat="%{VERSION}-%{RELEASE}" -qp $1/glibc-2*.rpm | head -1)
|
||||
mkdir $vr && pushd $vr
|
||||
fi
|
||||
|
||||
for r in $1*.rpm; do
|
||||
( rpm2cpio $r | cpio -di ) > /dev/null
|
||||
done
|
||||
|
||||
if [ -n $1 ]; then
|
||||
popd
|
||||
echo $vr
|
||||
fi
|
||||
}
|
||||
|
||||
# Get rpms for a build and decompress them
|
||||
get_build() {
|
||||
echo "Processing build $1"
|
||||
mkdir $1 && pushd $1
|
||||
brew buildinfo "glibc-$1" |
|
||||
sed -n -e "s|/mnt/koji\(.\+$arch.\+\)|http://kojipkgs.fedoraproject.org\1|p" |
|
||||
while read url; do
|
||||
echo "Downloading $url"
|
||||
wget -q $url
|
||||
done
|
||||
decompress_rpms
|
||||
|
||||
echo "Removing rpms"
|
||||
rm -f $1/*.rpm
|
||||
|
||||
popd
|
||||
}
|
||||
|
||||
# Run benchmarks for a build
|
||||
run_bench() {
|
||||
if [ -z $1 ]; then
|
||||
make DETAILED=1 ver=$installed prefix= -f /usr/libexec/glibc-benchtests/bench.mk bench
|
||||
else
|
||||
make DETAILED=1 ver=$1 prefix=$PWD -f $1/usr/libexec/glibc-benchtests/bench.mk bench
|
||||
fi
|
||||
}
|
||||
|
||||
# Get absolute paths if needed, since we will change into the working directory
|
||||
# next.
|
||||
if [ $path -eq 1 ]; then
|
||||
old_path=$(realpath $old)/
|
||||
new_path=$(realpath $new)/
|
||||
fi
|
||||
|
||||
tmpdir=$(mktemp -p /tmp -d glibc-bench-compare.$$.XXXX)
|
||||
pushd $tmpdir
|
||||
|
||||
# Get both builds.
|
||||
if [ $path -eq 0 ]; then
|
||||
if [ -z $installed ]; then
|
||||
get_build $old
|
||||
fi
|
||||
get_build $new
|
||||
else
|
||||
old=$(decompress_rpms $old_path)
|
||||
new=$(decompress_rpms $new_path)
|
||||
fi
|
||||
|
||||
# make bench for each of those.
|
||||
if [ -z $installed ]; then
|
||||
run_bench $old
|
||||
else
|
||||
run_bench
|
||||
fi
|
||||
run_bench $new
|
||||
|
||||
# Now run the comparison script.
|
||||
$old/usr/libexec/glibc-benchtests/compare_bench.py $old/usr/libexec/glibc-benchtests/benchout.schema.json \
|
||||
bench.$old.out bench.$new.out
|
@ -0,0 +1,980 @@
|
||||
commit f5117c6504888fab5423282a4607c552b90fd3f9
|
||||
Author: Carlos O'Donell <carlos@redhat.com>
|
||||
Date: Thu Jul 29 22:45:39 2021 -0400
|
||||
|
||||
Add 'codepoint_collation' support for LC_COLLATE.
|
||||
|
||||
Support a new directive 'codepoint_collation' in the LC_COLLATE
|
||||
section of a locale source file. This new directive causes all
|
||||
collation rules to be dropped and instead STRCMP (strcmp or
|
||||
wcscmp) is used for collation of the input character set. This
|
||||
is required to allow for a C.UTF-8 that contains zero collation
|
||||
rules (minimal size) and sorts using code point sorting.
|
||||
|
||||
To date the only implementation of a locale with zero collation
|
||||
rules is the C/POSIX locale. The C/POSIX locale provides
|
||||
identity tables for _NL_COLLATE_COLLSEQMB and
|
||||
_NL_COLLATE_COLLSEQWC that map to ASCII even though it has zero
|
||||
rules. This has lead to existing fnmatch, regexec, and regcomp
|
||||
implementations that require these tables. It is not correct
|
||||
to use these tables when nrules == 0, but the conservative fix
|
||||
is to provide these tables when nrules == 0. This assures that
|
||||
existing static applications using a new C.UTF-8 locale with
|
||||
'codepoint_collation' at least have functional range expressions
|
||||
with ASCII e.g. [0-9] or [a-z]. Such static applications would
|
||||
not have the fixes to fnmatch, regexec and regcomp that avoid
|
||||
the use of the tables when nrules == 0. Future fixes to fnmatch,
|
||||
regexec, and regcomp would allow range expressions to use the
|
||||
full set of code points for such ranges.
|
||||
|
||||
Tested on x86_64 and i686 without regression.
|
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
diff --git a/locale/C-collate-seq.c b/locale/C-collate-seq.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..4fb82cb8357936b6
|
||||
--- /dev/null
|
||||
+++ b/locale/C-collate-seq.c
|
||||
@@ -0,0 +1,100 @@
|
||||
+/* Copyright (C) 1995-2021 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/>. */
|
||||
+
|
||||
+#include <stdint.h>
|
||||
+
|
||||
+static const char collseqmb[] =
|
||||
+{
|
||||
+ '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
|
||||
+ '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f',
|
||||
+ '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17',
|
||||
+ '\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f',
|
||||
+ '\x20', '\x21', '\x22', '\x23', '\x24', '\x25', '\x26', '\x27',
|
||||
+ '\x28', '\x29', '\x2a', '\x2b', '\x2c', '\x2d', '\x2e', '\x2f',
|
||||
+ '\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37',
|
||||
+ '\x38', '\x39', '\x3a', '\x3b', '\x3c', '\x3d', '\x3e', '\x3f',
|
||||
+ '\x40', '\x41', '\x42', '\x43', '\x44', '\x45', '\x46', '\x47',
|
||||
+ '\x48', '\x49', '\x4a', '\x4b', '\x4c', '\x4d', '\x4e', '\x4f',
|
||||
+ '\x50', '\x51', '\x52', '\x53', '\x54', '\x55', '\x56', '\x57',
|
||||
+ '\x58', '\x59', '\x5a', '\x5b', '\x5c', '\x5d', '\x5e', '\x5f',
|
||||
+ '\x60', '\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67',
|
||||
+ '\x68', '\x69', '\x6a', '\x6b', '\x6c', '\x6d', '\x6e', '\x6f',
|
||||
+ '\x70', '\x71', '\x72', '\x73', '\x74', '\x75', '\x76', '\x77',
|
||||
+ '\x78', '\x79', '\x7a', '\x7b', '\x7c', '\x7d', '\x7e', '\x7f',
|
||||
+ '\x80', '\x81', '\x82', '\x83', '\x84', '\x85', '\x86', '\x87',
|
||||
+ '\x88', '\x89', '\x8a', '\x8b', '\x8c', '\x8d', '\x8e', '\x8f',
|
||||
+ '\x90', '\x91', '\x92', '\x93', '\x94', '\x95', '\x96', '\x97',
|
||||
+ '\x98', '\x99', '\x9a', '\x9b', '\x9c', '\x9d', '\x9e', '\x9f',
|
||||
+ '\xa0', '\xa1', '\xa2', '\xa3', '\xa4', '\xa5', '\xa6', '\xa7',
|
||||
+ '\xa8', '\xa9', '\xaa', '\xab', '\xac', '\xad', '\xae', '\xaf',
|
||||
+ '\xb0', '\xb1', '\xb2', '\xb3', '\xb4', '\xb5', '\xb6', '\xb7',
|
||||
+ '\xb8', '\xb9', '\xba', '\xbb', '\xbc', '\xbd', '\xbe', '\xbf',
|
||||
+ '\xc0', '\xc1', '\xc2', '\xc3', '\xc4', '\xc5', '\xc6', '\xc7',
|
||||
+ '\xc8', '\xc9', '\xca', '\xcb', '\xcc', '\xcd', '\xce', '\xcf',
|
||||
+ '\xd0', '\xd1', '\xd2', '\xd3', '\xd4', '\xd5', '\xd6', '\xd7',
|
||||
+ '\xd8', '\xd9', '\xda', '\xdb', '\xdc', '\xdd', '\xde', '\xdf',
|
||||
+ '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7',
|
||||
+ '\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', '\xef',
|
||||
+ '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xf7',
|
||||
+ '\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff'
|
||||
+};
|
||||
+
|
||||
+/* This table must be 256 bytes in size. We index bytes into the
|
||||
+ table to find the collation sequence. */
|
||||
+_Static_assert (sizeof (collseqmb) == 256);
|
||||
+
|
||||
+static const uint32_t collseqwc[] =
|
||||
+{
|
||||
+ 8, 1, 8, 0x0, 0xff,
|
||||
+ /* 1st-level table */
|
||||
+ 6 * sizeof (uint32_t),
|
||||
+ /* 2nd-level table */
|
||||
+ 7 * sizeof (uint32_t),
|
||||
+ /* 3rd-level table */
|
||||
+ L'\x00', L'\x01', L'\x02', L'\x03', L'\x04', L'\x05', L'\x06', L'\x07',
|
||||
+ L'\x08', L'\x09', L'\x0a', L'\x0b', L'\x0c', L'\x0d', L'\x0e', L'\x0f',
|
||||
+ L'\x10', L'\x11', L'\x12', L'\x13', L'\x14', L'\x15', L'\x16', L'\x17',
|
||||
+ L'\x18', L'\x19', L'\x1a', L'\x1b', L'\x1c', L'\x1d', L'\x1e', L'\x1f',
|
||||
+ L'\x20', L'\x21', L'\x22', L'\x23', L'\x24', L'\x25', L'\x26', L'\x27',
|
||||
+ L'\x28', L'\x29', L'\x2a', L'\x2b', L'\x2c', L'\x2d', L'\x2e', L'\x2f',
|
||||
+ L'\x30', L'\x31', L'\x32', L'\x33', L'\x34', L'\x35', L'\x36', L'\x37',
|
||||
+ L'\x38', L'\x39', L'\x3a', L'\x3b', L'\x3c', L'\x3d', L'\x3e', L'\x3f',
|
||||
+ L'\x40', L'\x41', L'\x42', L'\x43', L'\x44', L'\x45', L'\x46', L'\x47',
|
||||
+ L'\x48', L'\x49', L'\x4a', L'\x4b', L'\x4c', L'\x4d', L'\x4e', L'\x4f',
|
||||
+ L'\x50', L'\x51', L'\x52', L'\x53', L'\x54', L'\x55', L'\x56', L'\x57',
|
||||
+ L'\x58', L'\x59', L'\x5a', L'\x5b', L'\x5c', L'\x5d', L'\x5e', L'\x5f',
|
||||
+ L'\x60', L'\x61', L'\x62', L'\x63', L'\x64', L'\x65', L'\x66', L'\x67',
|
||||
+ L'\x68', L'\x69', L'\x6a', L'\x6b', L'\x6c', L'\x6d', L'\x6e', L'\x6f',
|
||||
+ L'\x70', L'\x71', L'\x72', L'\x73', L'\x74', L'\x75', L'\x76', L'\x77',
|
||||
+ L'\x78', L'\x79', L'\x7a', L'\x7b', L'\x7c', L'\x7d', L'\x7e', L'\x7f',
|
||||
+ L'\x80', L'\x81', L'\x82', L'\x83', L'\x84', L'\x85', L'\x86', L'\x87',
|
||||
+ L'\x88', L'\x89', L'\x8a', L'\x8b', L'\x8c', L'\x8d', L'\x8e', L'\x8f',
|
||||
+ L'\x90', L'\x91', L'\x92', L'\x93', L'\x94', L'\x95', L'\x96', L'\x97',
|
||||
+ L'\x98', L'\x99', L'\x9a', L'\x9b', L'\x9c', L'\x9d', L'\x9e', L'\x9f',
|
||||
+ L'\xa0', L'\xa1', L'\xa2', L'\xa3', L'\xa4', L'\xa5', L'\xa6', L'\xa7',
|
||||
+ L'\xa8', L'\xa9', L'\xaa', L'\xab', L'\xac', L'\xad', L'\xae', L'\xaf',
|
||||
+ L'\xb0', L'\xb1', L'\xb2', L'\xb3', L'\xb4', L'\xb5', L'\xb6', L'\xb7',
|
||||
+ L'\xb8', L'\xb9', L'\xba', L'\xbb', L'\xbc', L'\xbd', L'\xbe', L'\xbf',
|
||||
+ L'\xc0', L'\xc1', L'\xc2', L'\xc3', L'\xc4', L'\xc5', L'\xc6', L'\xc7',
|
||||
+ L'\xc8', L'\xc9', L'\xca', L'\xcb', L'\xcc', L'\xcd', L'\xce', L'\xcf',
|
||||
+ L'\xd0', L'\xd1', L'\xd2', L'\xd3', L'\xd4', L'\xd5', L'\xd6', L'\xd7',
|
||||
+ L'\xd8', L'\xd9', L'\xda', L'\xdb', L'\xdc', L'\xdd', L'\xde', L'\xdf',
|
||||
+ L'\xe0', L'\xe1', L'\xe2', L'\xe3', L'\xe4', L'\xe5', L'\xe6', L'\xe7',
|
||||
+ L'\xe8', L'\xe9', L'\xea', L'\xeb', L'\xec', L'\xed', L'\xee', L'\xef',
|
||||
+ L'\xf0', L'\xf1', L'\xf2', L'\xf3', L'\xf4', L'\xf5', L'\xf6', L'\xf7',
|
||||
+ L'\xf8', L'\xf9', L'\xfa', L'\xfb', L'\xfc', L'\xfd', L'\xfe', L'\xff'
|
||||
+};
|
||||
diff --git a/locale/C-collate.c b/locale/C-collate.c
|
||||
index 76d9373683314943..120ce0a40aeb9a0f 100644
|
||||
--- a/locale/C-collate.c
|
||||
+++ b/locale/C-collate.c
|
||||
@@ -20,83 +20,7 @@
|
||||
#include <stdint.h>
|
||||
#include "localeinfo.h"
|
||||
|
||||
-static const char collseqmb[] =
|
||||
-{
|
||||
- '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
|
||||
- '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f',
|
||||
- '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17',
|
||||
- '\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f',
|
||||
- '\x20', '\x21', '\x22', '\x23', '\x24', '\x25', '\x26', '\x27',
|
||||
- '\x28', '\x29', '\x2a', '\x2b', '\x2c', '\x2d', '\x2e', '\x2f',
|
||||
- '\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37',
|
||||
- '\x38', '\x39', '\x3a', '\x3b', '\x3c', '\x3d', '\x3e', '\x3f',
|
||||
- '\x40', '\x41', '\x42', '\x43', '\x44', '\x45', '\x46', '\x47',
|
||||
- '\x48', '\x49', '\x4a', '\x4b', '\x4c', '\x4d', '\x4e', '\x4f',
|
||||
- '\x50', '\x51', '\x52', '\x53', '\x54', '\x55', '\x56', '\x57',
|
||||
- '\x58', '\x59', '\x5a', '\x5b', '\x5c', '\x5d', '\x5e', '\x5f',
|
||||
- '\x60', '\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67',
|
||||
- '\x68', '\x69', '\x6a', '\x6b', '\x6c', '\x6d', '\x6e', '\x6f',
|
||||
- '\x70', '\x71', '\x72', '\x73', '\x74', '\x75', '\x76', '\x77',
|
||||
- '\x78', '\x79', '\x7a', '\x7b', '\x7c', '\x7d', '\x7e', '\x7f',
|
||||
- '\x80', '\x81', '\x82', '\x83', '\x84', '\x85', '\x86', '\x87',
|
||||
- '\x88', '\x89', '\x8a', '\x8b', '\x8c', '\x8d', '\x8e', '\x8f',
|
||||
- '\x90', '\x91', '\x92', '\x93', '\x94', '\x95', '\x96', '\x97',
|
||||
- '\x98', '\x99', '\x9a', '\x9b', '\x9c', '\x9d', '\x9e', '\x9f',
|
||||
- '\xa0', '\xa1', '\xa2', '\xa3', '\xa4', '\xa5', '\xa6', '\xa7',
|
||||
- '\xa8', '\xa9', '\xaa', '\xab', '\xac', '\xad', '\xae', '\xaf',
|
||||
- '\xb0', '\xb1', '\xb2', '\xb3', '\xb4', '\xb5', '\xb6', '\xb7',
|
||||
- '\xb8', '\xb9', '\xba', '\xbb', '\xbc', '\xbd', '\xbe', '\xbf',
|
||||
- '\xc0', '\xc1', '\xc2', '\xc3', '\xc4', '\xc5', '\xc6', '\xc7',
|
||||
- '\xc8', '\xc9', '\xca', '\xcb', '\xcc', '\xcd', '\xce', '\xcf',
|
||||
- '\xd0', '\xd1', '\xd2', '\xd3', '\xd4', '\xd5', '\xd6', '\xd7',
|
||||
- '\xd8', '\xd9', '\xda', '\xdb', '\xdc', '\xdd', '\xde', '\xdf',
|
||||
- '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7',
|
||||
- '\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', '\xef',
|
||||
- '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xf7',
|
||||
- '\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff'
|
||||
-};
|
||||
-
|
||||
-static const uint32_t collseqwc[] =
|
||||
-{
|
||||
- 8, 1, 8, 0x0, 0xff,
|
||||
- /* 1st-level table */
|
||||
- 6 * sizeof (uint32_t),
|
||||
- /* 2nd-level table */
|
||||
- 7 * sizeof (uint32_t),
|
||||
- /* 3rd-level table */
|
||||
- L'\x00', L'\x01', L'\x02', L'\x03', L'\x04', L'\x05', L'\x06', L'\x07',
|
||||
- L'\x08', L'\x09', L'\x0a', L'\x0b', L'\x0c', L'\x0d', L'\x0e', L'\x0f',
|
||||
- L'\x10', L'\x11', L'\x12', L'\x13', L'\x14', L'\x15', L'\x16', L'\x17',
|
||||
- L'\x18', L'\x19', L'\x1a', L'\x1b', L'\x1c', L'\x1d', L'\x1e', L'\x1f',
|
||||
- L'\x20', L'\x21', L'\x22', L'\x23', L'\x24', L'\x25', L'\x26', L'\x27',
|
||||
- L'\x28', L'\x29', L'\x2a', L'\x2b', L'\x2c', L'\x2d', L'\x2e', L'\x2f',
|
||||
- L'\x30', L'\x31', L'\x32', L'\x33', L'\x34', L'\x35', L'\x36', L'\x37',
|
||||
- L'\x38', L'\x39', L'\x3a', L'\x3b', L'\x3c', L'\x3d', L'\x3e', L'\x3f',
|
||||
- L'\x40', L'\x41', L'\x42', L'\x43', L'\x44', L'\x45', L'\x46', L'\x47',
|
||||
- L'\x48', L'\x49', L'\x4a', L'\x4b', L'\x4c', L'\x4d', L'\x4e', L'\x4f',
|
||||
- L'\x50', L'\x51', L'\x52', L'\x53', L'\x54', L'\x55', L'\x56', L'\x57',
|
||||
- L'\x58', L'\x59', L'\x5a', L'\x5b', L'\x5c', L'\x5d', L'\x5e', L'\x5f',
|
||||
- L'\x60', L'\x61', L'\x62', L'\x63', L'\x64', L'\x65', L'\x66', L'\x67',
|
||||
- L'\x68', L'\x69', L'\x6a', L'\x6b', L'\x6c', L'\x6d', L'\x6e', L'\x6f',
|
||||
- L'\x70', L'\x71', L'\x72', L'\x73', L'\x74', L'\x75', L'\x76', L'\x77',
|
||||
- L'\x78', L'\x79', L'\x7a', L'\x7b', L'\x7c', L'\x7d', L'\x7e', L'\x7f',
|
||||
- L'\x80', L'\x81', L'\x82', L'\x83', L'\x84', L'\x85', L'\x86', L'\x87',
|
||||
- L'\x88', L'\x89', L'\x8a', L'\x8b', L'\x8c', L'\x8d', L'\x8e', L'\x8f',
|
||||
- L'\x90', L'\x91', L'\x92', L'\x93', L'\x94', L'\x95', L'\x96', L'\x97',
|
||||
- L'\x98', L'\x99', L'\x9a', L'\x9b', L'\x9c', L'\x9d', L'\x9e', L'\x9f',
|
||||
- L'\xa0', L'\xa1', L'\xa2', L'\xa3', L'\xa4', L'\xa5', L'\xa6', L'\xa7',
|
||||
- L'\xa8', L'\xa9', L'\xaa', L'\xab', L'\xac', L'\xad', L'\xae', L'\xaf',
|
||||
- L'\xb0', L'\xb1', L'\xb2', L'\xb3', L'\xb4', L'\xb5', L'\xb6', L'\xb7',
|
||||
- L'\xb8', L'\xb9', L'\xba', L'\xbb', L'\xbc', L'\xbd', L'\xbe', L'\xbf',
|
||||
- L'\xc0', L'\xc1', L'\xc2', L'\xc3', L'\xc4', L'\xc5', L'\xc6', L'\xc7',
|
||||
- L'\xc8', L'\xc9', L'\xca', L'\xcb', L'\xcc', L'\xcd', L'\xce', L'\xcf',
|
||||
- L'\xd0', L'\xd1', L'\xd2', L'\xd3', L'\xd4', L'\xd5', L'\xd6', L'\xd7',
|
||||
- L'\xd8', L'\xd9', L'\xda', L'\xdb', L'\xdc', L'\xdd', L'\xde', L'\xdf',
|
||||
- L'\xe0', L'\xe1', L'\xe2', L'\xe3', L'\xe4', L'\xe5', L'\xe6', L'\xe7',
|
||||
- L'\xe8', L'\xe9', L'\xea', L'\xeb', L'\xec', L'\xed', L'\xee', L'\xef',
|
||||
- L'\xf0', L'\xf1', L'\xf2', L'\xf3', L'\xf4', L'\xf5', L'\xf6', L'\xf7',
|
||||
- L'\xf8', L'\xf9', L'\xfa', L'\xfb', L'\xfc', L'\xfd', L'\xfe', L'\xff'
|
||||
-};
|
||||
+#include "C-collate-seq.c"
|
||||
|
||||
const struct __locale_data _nl_C_LC_COLLATE attribute_hidden =
|
||||
{
|
||||
diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c
|
||||
index b6406b775d3a81ad..0f314e40c4305dea 100644
|
||||
--- a/locale/programs/ld-collate.c
|
||||
+++ b/locale/programs/ld-collate.c
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <wchar.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/param.h>
|
||||
+#include <array_length.h>
|
||||
|
||||
#include "localedef.h"
|
||||
#include "charmap.h"
|
||||
@@ -195,6 +196,9 @@ struct name_list
|
||||
/* The real definition of the struct for the LC_COLLATE locale. */
|
||||
struct locale_collate_t
|
||||
{
|
||||
+ /* Does the locale use code points to compare the encoding? */
|
||||
+ bool codepoint_collation;
|
||||
+
|
||||
int col_weight_max;
|
||||
int cur_weight_max;
|
||||
|
||||
@@ -1510,6 +1514,7 @@ collate_startup (struct linereader *ldfile, struct localedef_t *locale,
|
||||
obstack_init (&collate->mempool);
|
||||
|
||||
collate->col_weight_max = -1;
|
||||
+ collate->codepoint_collation = false;
|
||||
}
|
||||
else
|
||||
/* Reuse the copy_locale's data structures. */
|
||||
@@ -1568,6 +1573,10 @@ collate_finish (struct localedef_t *locale, const struct charmap_t *charmap)
|
||||
return;
|
||||
}
|
||||
|
||||
+ /* No data required. */
|
||||
+ if (collate->codepoint_collation)
|
||||
+ return;
|
||||
+
|
||||
/* If this assertion is hit change the type in `element_t'. */
|
||||
assert (nrules <= sizeof (runp->used_in_level) * 8);
|
||||
|
||||
@@ -2092,6 +2101,10 @@ add_to_tablewc (uint32_t ch, struct element_t *runp)
|
||||
}
|
||||
}
|
||||
|
||||
+/* Include the C locale identity tables for _NL_COLLATE_COLLSEQMB and
|
||||
+ _NL_COLLATE_COLLSEQWC. */
|
||||
+#include "C-collate-seq.c"
|
||||
+
|
||||
void
|
||||
collate_output (struct localedef_t *locale, const struct charmap_t *charmap,
|
||||
const char *output_path)
|
||||
@@ -2115,7 +2128,7 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap,
|
||||
add_locale_uint32 (&file, nrules);
|
||||
|
||||
/* If we have no LC_COLLATE data emit only the number of rules as zero. */
|
||||
- if (collate == NULL)
|
||||
+ if (collate == NULL || collate->codepoint_collation)
|
||||
{
|
||||
size_t idx;
|
||||
for (idx = 1; idx < nelems; idx++)
|
||||
@@ -2123,6 +2136,17 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap,
|
||||
/* The words have to be handled specially. */
|
||||
if (idx == _NL_ITEM_INDEX (_NL_COLLATE_SYMB_HASH_SIZEMB))
|
||||
add_locale_uint32 (&file, 0);
|
||||
+ else if (idx == _NL_ITEM_INDEX (_NL_COLLATE_CODESET)
|
||||
+ && collate != NULL)
|
||||
+ /* A valid LC_COLLATE must have a code set name. */
|
||||
+ add_locale_string (&file, charmap->code_set_name);
|
||||
+ else if (idx == _NL_ITEM_INDEX (_NL_COLLATE_COLLSEQMB)
|
||||
+ && collate != NULL)
|
||||
+ add_locale_raw_data (&file, collseqmb, sizeof (collseqmb));
|
||||
+ else if (idx == _NL_ITEM_INDEX (_NL_COLLATE_COLLSEQWC)
|
||||
+ && collate != NULL)
|
||||
+ add_locale_uint32_array (&file, collseqwc,
|
||||
+ array_length (collseqwc));
|
||||
else
|
||||
add_locale_empty (&file);
|
||||
}
|
||||
@@ -2672,6 +2696,10 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
|
||||
|
||||
switch (nowtok)
|
||||
{
|
||||
+ case tok_codepoint_collation:
|
||||
+ collate->codepoint_collation = true;
|
||||
+ break;
|
||||
+
|
||||
case tok_copy:
|
||||
/* Allow copying other locales. */
|
||||
now = lr_token (ldfile, charmap, result, NULL, verbose);
|
||||
@@ -3742,9 +3770,11 @@ error while adding equivalent collating symbol"));
|
||||
/* Next we assume `LC_COLLATE'. */
|
||||
if (!ignore_content)
|
||||
{
|
||||
- if (state == 0 && copy_locale == NULL)
|
||||
+ if (state == 0
|
||||
+ && copy_locale == NULL
|
||||
+ && !collate->codepoint_collation)
|
||||
/* We must either see a copy statement or have
|
||||
- ordering values. */
|
||||
+ ordering values, or codepoint_collation. */
|
||||
lr_error (ldfile,
|
||||
_("%s: empty category description not allowed"),
|
||||
"LC_COLLATE");
|
||||
diff --git a/locale/programs/locfile-kw.gperf b/locale/programs/locfile-kw.gperf
|
||||
index bcded15ddb4c44bb..2e59eb9ac014134b 100644
|
||||
--- a/locale/programs/locfile-kw.gperf
|
||||
+++ b/locale/programs/locfile-kw.gperf
|
||||
@@ -54,6 +54,7 @@ translit_end, tok_translit_end, 0
|
||||
translit_ignore, tok_translit_ignore, 0
|
||||
default_missing, tok_default_missing, 0
|
||||
LC_COLLATE, tok_lc_collate, 0
|
||||
+codepoint_collation, tok_codepoint_collation, 0
|
||||
coll_weight_max, tok_coll_weight_max, 0
|
||||
section-symbol, tok_section_symbol, 0
|
||||
collating-element, tok_collating_element, 0
|
||||
diff --git a/locale/programs/locfile-kw.h b/locale/programs/locfile-kw.h
|
||||
index bc1cb8f0845852ad..fe6335692bd422cd 100644
|
||||
--- a/locale/programs/locfile-kw.h
|
||||
+++ b/locale/programs/locfile-kw.h
|
||||
@@ -54,7 +54,7 @@
|
||||
#line 24 "locfile-kw.gperf"
|
||||
struct keyword_t ;
|
||||
|
||||
-#define TOTAL_KEYWORDS 178
|
||||
+#define TOTAL_KEYWORDS 179
|
||||
#define MIN_WORD_LENGTH 3
|
||||
#define MAX_WORD_LENGTH 22
|
||||
#define MIN_HASH_VALUE 3
|
||||
@@ -134,92 +134,92 @@ locfile_hash (register const char *str, register size_t len)
|
||||
#line 31 "locfile-kw.gperf"
|
||||
{"END", tok_end, 0},
|
||||
{""}, {""},
|
||||
-#line 70 "locfile-kw.gperf"
|
||||
+#line 71 "locfile-kw.gperf"
|
||||
{"IGNORE", tok_ignore, 0},
|
||||
-#line 129 "locfile-kw.gperf"
|
||||
+#line 130 "locfile-kw.gperf"
|
||||
{"LC_TIME", tok_lc_time, 0},
|
||||
#line 30 "locfile-kw.gperf"
|
||||
{"LC_CTYPE", tok_lc_ctype, 0},
|
||||
{""},
|
||||
-#line 168 "locfile-kw.gperf"
|
||||
+#line 169 "locfile-kw.gperf"
|
||||
{"LC_ADDRESS", tok_lc_address, 0},
|
||||
-#line 153 "locfile-kw.gperf"
|
||||
+#line 154 "locfile-kw.gperf"
|
||||
{"LC_MESSAGES", tok_lc_messages, 0},
|
||||
-#line 161 "locfile-kw.gperf"
|
||||
+#line 162 "locfile-kw.gperf"
|
||||
{"LC_NAME", tok_lc_name, 0},
|
||||
-#line 158 "locfile-kw.gperf"
|
||||
+#line 159 "locfile-kw.gperf"
|
||||
{"LC_PAPER", tok_lc_paper, 0},
|
||||
-#line 186 "locfile-kw.gperf"
|
||||
+#line 187 "locfile-kw.gperf"
|
||||
{"LC_MEASUREMENT", tok_lc_measurement, 0},
|
||||
#line 56 "locfile-kw.gperf"
|
||||
{"LC_COLLATE", tok_lc_collate, 0},
|
||||
{""},
|
||||
-#line 188 "locfile-kw.gperf"
|
||||
+#line 189 "locfile-kw.gperf"
|
||||
{"LC_IDENTIFICATION", tok_lc_identification, 0},
|
||||
-#line 201 "locfile-kw.gperf"
|
||||
+#line 202 "locfile-kw.gperf"
|
||||
{"revision", tok_revision, 0},
|
||||
-#line 69 "locfile-kw.gperf"
|
||||
+#line 70 "locfile-kw.gperf"
|
||||
{"UNDEFINED", tok_undefined, 0},
|
||||
-#line 125 "locfile-kw.gperf"
|
||||
+#line 126 "locfile-kw.gperf"
|
||||
{"LC_NUMERIC", tok_lc_numeric, 0},
|
||||
-#line 82 "locfile-kw.gperf"
|
||||
+#line 83 "locfile-kw.gperf"
|
||||
{"LC_MONETARY", tok_lc_monetary, 0},
|
||||
-#line 181 "locfile-kw.gperf"
|
||||
+#line 182 "locfile-kw.gperf"
|
||||
{"LC_TELEPHONE", tok_lc_telephone, 0},
|
||||
{""}, {""}, {""},
|
||||
-#line 75 "locfile-kw.gperf"
|
||||
+#line 76 "locfile-kw.gperf"
|
||||
{"define", tok_define, 0},
|
||||
-#line 154 "locfile-kw.gperf"
|
||||
+#line 155 "locfile-kw.gperf"
|
||||
{"yesexpr", tok_yesexpr, 0},
|
||||
-#line 141 "locfile-kw.gperf"
|
||||
+#line 142 "locfile-kw.gperf"
|
||||
{"era_year", tok_era_year, 0},
|
||||
{""},
|
||||
#line 54 "locfile-kw.gperf"
|
||||
{"translit_ignore", tok_translit_ignore, 0},
|
||||
-#line 156 "locfile-kw.gperf"
|
||||
+#line 157 "locfile-kw.gperf"
|
||||
{"yesstr", tok_yesstr, 0},
|
||||
{""},
|
||||
-#line 89 "locfile-kw.gperf"
|
||||
+#line 90 "locfile-kw.gperf"
|
||||
{"negative_sign", tok_negative_sign, 0},
|
||||
{""},
|
||||
-#line 137 "locfile-kw.gperf"
|
||||
+#line 138 "locfile-kw.gperf"
|
||||
{"t_fmt", tok_t_fmt, 0},
|
||||
-#line 159 "locfile-kw.gperf"
|
||||
+#line 160 "locfile-kw.gperf"
|
||||
{"height", tok_height, 0},
|
||||
{""}, {""},
|
||||
#line 52 "locfile-kw.gperf"
|
||||
{"translit_start", tok_translit_start, 0},
|
||||
-#line 136 "locfile-kw.gperf"
|
||||
+#line 137 "locfile-kw.gperf"
|
||||
{"d_fmt", tok_d_fmt, 0},
|
||||
{""},
|
||||
#line 53 "locfile-kw.gperf"
|
||||
{"translit_end", tok_translit_end, 0},
|
||||
-#line 94 "locfile-kw.gperf"
|
||||
+#line 95 "locfile-kw.gperf"
|
||||
{"n_cs_precedes", tok_n_cs_precedes, 0},
|
||||
-#line 144 "locfile-kw.gperf"
|
||||
+#line 145 "locfile-kw.gperf"
|
||||
{"era_t_fmt", tok_era_t_fmt, 0},
|
||||
#line 39 "locfile-kw.gperf"
|
||||
{"space", tok_space, 0},
|
||||
-#line 72 "locfile-kw.gperf"
|
||||
- {"reorder-end", tok_reorder_end, 0},
|
||||
#line 73 "locfile-kw.gperf"
|
||||
+ {"reorder-end", tok_reorder_end, 0},
|
||||
+#line 74 "locfile-kw.gperf"
|
||||
{"reorder-sections-after", tok_reorder_sections_after, 0},
|
||||
{""},
|
||||
-#line 142 "locfile-kw.gperf"
|
||||
+#line 143 "locfile-kw.gperf"
|
||||
{"era_d_fmt", tok_era_d_fmt, 0},
|
||||
-#line 189 "locfile-kw.gperf"
|
||||
+#line 190 "locfile-kw.gperf"
|
||||
{"title", tok_title, 0},
|
||||
{""}, {""},
|
||||
-#line 149 "locfile-kw.gperf"
|
||||
+#line 150 "locfile-kw.gperf"
|
||||
{"timezone", tok_timezone, 0},
|
||||
{""},
|
||||
-#line 74 "locfile-kw.gperf"
|
||||
+#line 75 "locfile-kw.gperf"
|
||||
{"reorder-sections-end", tok_reorder_sections_end, 0},
|
||||
{""}, {""}, {""},
|
||||
-#line 95 "locfile-kw.gperf"
|
||||
+#line 96 "locfile-kw.gperf"
|
||||
{"n_sep_by_space", tok_n_sep_by_space, 0},
|
||||
{""}, {""},
|
||||
-#line 100 "locfile-kw.gperf"
|
||||
+#line 101 "locfile-kw.gperf"
|
||||
{"int_n_cs_precedes", tok_int_n_cs_precedes, 0},
|
||||
{""}, {""}, {""},
|
||||
#line 26 "locfile-kw.gperf"
|
||||
@@ -233,147 +233,147 @@ locfile_hash (register const char *str, register size_t len)
|
||||
{"print", tok_print, 0},
|
||||
#line 44 "locfile-kw.gperf"
|
||||
{"xdigit", tok_xdigit, 0},
|
||||
-#line 110 "locfile-kw.gperf"
|
||||
+#line 111 "locfile-kw.gperf"
|
||||
{"duo_n_cs_precedes", tok_duo_n_cs_precedes, 0},
|
||||
-#line 127 "locfile-kw.gperf"
|
||||
+#line 128 "locfile-kw.gperf"
|
||||
{"thousands_sep", tok_thousands_sep, 0},
|
||||
-#line 197 "locfile-kw.gperf"
|
||||
+#line 198 "locfile-kw.gperf"
|
||||
{"territory", tok_territory, 0},
|
||||
#line 36 "locfile-kw.gperf"
|
||||
{"digit", tok_digit, 0},
|
||||
{""}, {""},
|
||||
-#line 92 "locfile-kw.gperf"
|
||||
+#line 93 "locfile-kw.gperf"
|
||||
{"p_cs_precedes", tok_p_cs_precedes, 0},
|
||||
{""}, {""},
|
||||
-#line 62 "locfile-kw.gperf"
|
||||
+#line 63 "locfile-kw.gperf"
|
||||
{"script", tok_script, 0},
|
||||
#line 29 "locfile-kw.gperf"
|
||||
{"include", tok_include, 0},
|
||||
{""},
|
||||
-#line 78 "locfile-kw.gperf"
|
||||
+#line 79 "locfile-kw.gperf"
|
||||
{"else", tok_else, 0},
|
||||
-#line 184 "locfile-kw.gperf"
|
||||
+#line 185 "locfile-kw.gperf"
|
||||
{"int_select", tok_int_select, 0},
|
||||
{""}, {""}, {""},
|
||||
-#line 132 "locfile-kw.gperf"
|
||||
+#line 133 "locfile-kw.gperf"
|
||||
{"week", tok_week, 0},
|
||||
#line 33 "locfile-kw.gperf"
|
||||
{"upper", tok_upper, 0},
|
||||
{""}, {""},
|
||||
-#line 194 "locfile-kw.gperf"
|
||||
+#line 195 "locfile-kw.gperf"
|
||||
{"tel", tok_tel, 0},
|
||||
-#line 93 "locfile-kw.gperf"
|
||||
+#line 94 "locfile-kw.gperf"
|
||||
{"p_sep_by_space", tok_p_sep_by_space, 0},
|
||||
-#line 160 "locfile-kw.gperf"
|
||||
+#line 161 "locfile-kw.gperf"
|
||||
{"width", tok_width, 0},
|
||||
{""},
|
||||
-#line 98 "locfile-kw.gperf"
|
||||
+#line 99 "locfile-kw.gperf"
|
||||
{"int_p_cs_precedes", tok_int_p_cs_precedes, 0},
|
||||
{""}, {""},
|
||||
#line 41 "locfile-kw.gperf"
|
||||
{"punct", tok_punct, 0},
|
||||
{""}, {""},
|
||||
-#line 101 "locfile-kw.gperf"
|
||||
+#line 102 "locfile-kw.gperf"
|
||||
{"int_n_sep_by_space", tok_int_n_sep_by_space, 0},
|
||||
{""}, {""}, {""},
|
||||
-#line 108 "locfile-kw.gperf"
|
||||
+#line 109 "locfile-kw.gperf"
|
||||
{"duo_p_cs_precedes", tok_duo_p_cs_precedes, 0},
|
||||
#line 48 "locfile-kw.gperf"
|
||||
{"charconv", tok_charconv, 0},
|
||||
{""},
|
||||
#line 47 "locfile-kw.gperf"
|
||||
{"class", tok_class, 0},
|
||||
-#line 114 "locfile-kw.gperf"
|
||||
- {"duo_int_n_cs_precedes", tok_duo_int_n_cs_precedes, 0},
|
||||
#line 115 "locfile-kw.gperf"
|
||||
+ {"duo_int_n_cs_precedes", tok_duo_int_n_cs_precedes, 0},
|
||||
+#line 116 "locfile-kw.gperf"
|
||||
{"duo_int_n_sep_by_space", tok_duo_int_n_sep_by_space, 0},
|
||||
-#line 111 "locfile-kw.gperf"
|
||||
+#line 112 "locfile-kw.gperf"
|
||||
{"duo_n_sep_by_space", tok_duo_n_sep_by_space, 0},
|
||||
-#line 119 "locfile-kw.gperf"
|
||||
+#line 120 "locfile-kw.gperf"
|
||||
{"duo_int_n_sign_posn", tok_duo_int_n_sign_posn, 0},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
{""}, {""}, {""}, {""}, {""},
|
||||
-#line 58 "locfile-kw.gperf"
|
||||
+#line 59 "locfile-kw.gperf"
|
||||
{"section-symbol", tok_section_symbol, 0},
|
||||
-#line 185 "locfile-kw.gperf"
|
||||
+#line 186 "locfile-kw.gperf"
|
||||
{"int_prefix", tok_int_prefix, 0},
|
||||
{""}, {""}, {""}, {""},
|
||||
#line 42 "locfile-kw.gperf"
|
||||
{"graph", tok_graph, 0},
|
||||
{""}, {""},
|
||||
-#line 99 "locfile-kw.gperf"
|
||||
+#line 100 "locfile-kw.gperf"
|
||||
{"int_p_sep_by_space", tok_int_p_sep_by_space, 0},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
-#line 112 "locfile-kw.gperf"
|
||||
- {"duo_int_p_cs_precedes", tok_duo_int_p_cs_precedes, 0},
|
||||
#line 113 "locfile-kw.gperf"
|
||||
+ {"duo_int_p_cs_precedes", tok_duo_int_p_cs_precedes, 0},
|
||||
+#line 114 "locfile-kw.gperf"
|
||||
{"duo_int_p_sep_by_space", tok_duo_int_p_sep_by_space, 0},
|
||||
-#line 109 "locfile-kw.gperf"
|
||||
+#line 110 "locfile-kw.gperf"
|
||||
{"duo_p_sep_by_space", tok_duo_p_sep_by_space, 0},
|
||||
-#line 118 "locfile-kw.gperf"
|
||||
+#line 119 "locfile-kw.gperf"
|
||||
{"duo_int_p_sign_posn", tok_duo_int_p_sign_posn, 0},
|
||||
-#line 157 "locfile-kw.gperf"
|
||||
+#line 158 "locfile-kw.gperf"
|
||||
{"nostr", tok_nostr, 0},
|
||||
{""}, {""},
|
||||
-#line 140 "locfile-kw.gperf"
|
||||
+#line 141 "locfile-kw.gperf"
|
||||
{"era", tok_era, 0},
|
||||
{""},
|
||||
-#line 84 "locfile-kw.gperf"
|
||||
+#line 85 "locfile-kw.gperf"
|
||||
{"currency_symbol", tok_currency_symbol, 0},
|
||||
{""},
|
||||
-#line 167 "locfile-kw.gperf"
|
||||
+#line 168 "locfile-kw.gperf"
|
||||
{"name_ms", tok_name_ms, 0},
|
||||
-#line 165 "locfile-kw.gperf"
|
||||
- {"name_mrs", tok_name_mrs, 0},
|
||||
#line 166 "locfile-kw.gperf"
|
||||
+ {"name_mrs", tok_name_mrs, 0},
|
||||
+#line 167 "locfile-kw.gperf"
|
||||
{"name_miss", tok_name_miss, 0},
|
||||
-#line 83 "locfile-kw.gperf"
|
||||
+#line 84 "locfile-kw.gperf"
|
||||
{"int_curr_symbol", tok_int_curr_symbol, 0},
|
||||
-#line 190 "locfile-kw.gperf"
|
||||
+#line 191 "locfile-kw.gperf"
|
||||
{"source", tok_source, 0},
|
||||
-#line 164 "locfile-kw.gperf"
|
||||
+#line 165 "locfile-kw.gperf"
|
||||
{"name_mr", tok_name_mr, 0},
|
||||
-#line 163 "locfile-kw.gperf"
|
||||
+#line 164 "locfile-kw.gperf"
|
||||
{"name_gen", tok_name_gen, 0},
|
||||
-#line 202 "locfile-kw.gperf"
|
||||
+#line 203 "locfile-kw.gperf"
|
||||
{"date", tok_date, 0},
|
||||
{""}, {""},
|
||||
-#line 191 "locfile-kw.gperf"
|
||||
+#line 192 "locfile-kw.gperf"
|
||||
{"address", tok_address, 0},
|
||||
-#line 162 "locfile-kw.gperf"
|
||||
+#line 163 "locfile-kw.gperf"
|
||||
{"name_fmt", tok_name_fmt, 0},
|
||||
#line 32 "locfile-kw.gperf"
|
||||
{"copy", tok_copy, 0},
|
||||
-#line 103 "locfile-kw.gperf"
|
||||
+#line 104 "locfile-kw.gperf"
|
||||
{"int_n_sign_posn", tok_int_n_sign_posn, 0},
|
||||
{""}, {""},
|
||||
-#line 131 "locfile-kw.gperf"
|
||||
+#line 132 "locfile-kw.gperf"
|
||||
{"day", tok_day, 0},
|
||||
-#line 105 "locfile-kw.gperf"
|
||||
+#line 106 "locfile-kw.gperf"
|
||||
{"duo_currency_symbol", tok_duo_currency_symbol, 0},
|
||||
{""}, {""}, {""},
|
||||
-#line 150 "locfile-kw.gperf"
|
||||
+#line 151 "locfile-kw.gperf"
|
||||
{"date_fmt", tok_date_fmt, 0},
|
||||
-#line 64 "locfile-kw.gperf"
|
||||
+#line 65 "locfile-kw.gperf"
|
||||
{"order_end", tok_order_end, 0},
|
||||
-#line 117 "locfile-kw.gperf"
|
||||
+#line 118 "locfile-kw.gperf"
|
||||
{"duo_n_sign_posn", tok_duo_n_sign_posn, 0},
|
||||
{""},
|
||||
-#line 170 "locfile-kw.gperf"
|
||||
+#line 171 "locfile-kw.gperf"
|
||||
{"country_name", tok_country_name, 0},
|
||||
-#line 71 "locfile-kw.gperf"
|
||||
+#line 72 "locfile-kw.gperf"
|
||||
{"reorder-after", tok_reorder_after, 0},
|
||||
{""}, {""},
|
||||
-#line 155 "locfile-kw.gperf"
|
||||
+#line 156 "locfile-kw.gperf"
|
||||
{"noexpr", tok_noexpr, 0},
|
||||
#line 50 "locfile-kw.gperf"
|
||||
{"tolower", tok_tolower, 0},
|
||||
-#line 198 "locfile-kw.gperf"
|
||||
+#line 199 "locfile-kw.gperf"
|
||||
{"audience", tok_audience, 0},
|
||||
{""}, {""}, {""},
|
||||
#line 49 "locfile-kw.gperf"
|
||||
{"toupper", tok_toupper, 0},
|
||||
-#line 68 "locfile-kw.gperf"
|
||||
+#line 69 "locfile-kw.gperf"
|
||||
{"position", tok_position, 0},
|
||||
{""},
|
||||
#line 40 "locfile-kw.gperf"
|
||||
@@ -381,196 +381,197 @@ locfile_hash (register const char *str, register size_t len)
|
||||
{""},
|
||||
#line 27 "locfile-kw.gperf"
|
||||
{"comment_char", tok_comment_char, 0},
|
||||
-#line 88 "locfile-kw.gperf"
|
||||
+#line 89 "locfile-kw.gperf"
|
||||
{"positive_sign", tok_positive_sign, 0},
|
||||
{""}, {""}, {""}, {""},
|
||||
-#line 61 "locfile-kw.gperf"
|
||||
+#line 62 "locfile-kw.gperf"
|
||||
{"symbol-equivalence", tok_symbol_equivalence, 0},
|
||||
{""},
|
||||
-#line 102 "locfile-kw.gperf"
|
||||
+#line 103 "locfile-kw.gperf"
|
||||
{"int_p_sign_posn", tok_int_p_sign_posn, 0},
|
||||
-#line 175 "locfile-kw.gperf"
|
||||
+#line 176 "locfile-kw.gperf"
|
||||
{"country_car", tok_country_car, 0},
|
||||
{""}, {""},
|
||||
-#line 104 "locfile-kw.gperf"
|
||||
+#line 105 "locfile-kw.gperf"
|
||||
{"duo_int_curr_symbol", tok_duo_int_curr_symbol, 0},
|
||||
{""}, {""},
|
||||
-#line 135 "locfile-kw.gperf"
|
||||
+#line 136 "locfile-kw.gperf"
|
||||
{"d_t_fmt", tok_d_t_fmt, 0},
|
||||
{""}, {""},
|
||||
-#line 116 "locfile-kw.gperf"
|
||||
+#line 117 "locfile-kw.gperf"
|
||||
{"duo_p_sign_posn", tok_duo_p_sign_posn, 0},
|
||||
-#line 187 "locfile-kw.gperf"
|
||||
+#line 188 "locfile-kw.gperf"
|
||||
{"measurement", tok_measurement, 0},
|
||||
-#line 176 "locfile-kw.gperf"
|
||||
+#line 177 "locfile-kw.gperf"
|
||||
{"country_isbn", tok_country_isbn, 0},
|
||||
#line 37 "locfile-kw.gperf"
|
||||
{"outdigit", tok_outdigit, 0},
|
||||
{""}, {""},
|
||||
-#line 143 "locfile-kw.gperf"
|
||||
+#line 144 "locfile-kw.gperf"
|
||||
{"era_d_t_fmt", tok_era_d_t_fmt, 0},
|
||||
{""}, {""}, {""},
|
||||
#line 34 "locfile-kw.gperf"
|
||||
{"lower", tok_lower, 0},
|
||||
-#line 183 "locfile-kw.gperf"
|
||||
+#line 184 "locfile-kw.gperf"
|
||||
{"tel_dom_fmt", tok_tel_dom_fmt, 0},
|
||||
-#line 171 "locfile-kw.gperf"
|
||||
+#line 172 "locfile-kw.gperf"
|
||||
{"country_post", tok_country_post, 0},
|
||||
-#line 148 "locfile-kw.gperf"
|
||||
+#line 149 "locfile-kw.gperf"
|
||||
{"cal_direction", tok_cal_direction, 0},
|
||||
- {""},
|
||||
-#line 139 "locfile-kw.gperf"
|
||||
+#line 57 "locfile-kw.gperf"
|
||||
+ {"codepoint_collation", tok_codepoint_collation, 0},
|
||||
+#line 140 "locfile-kw.gperf"
|
||||
{"t_fmt_ampm", tok_t_fmt_ampm, 0},
|
||||
-#line 91 "locfile-kw.gperf"
|
||||
+#line 92 "locfile-kw.gperf"
|
||||
{"frac_digits", tok_frac_digits, 0},
|
||||
{""}, {""},
|
||||
-#line 177 "locfile-kw.gperf"
|
||||
+#line 178 "locfile-kw.gperf"
|
||||
{"lang_name", tok_lang_name, 0},
|
||||
-#line 90 "locfile-kw.gperf"
|
||||
+#line 91 "locfile-kw.gperf"
|
||||
{"int_frac_digits", tok_int_frac_digits, 0},
|
||||
{""},
|
||||
-#line 121 "locfile-kw.gperf"
|
||||
+#line 122 "locfile-kw.gperf"
|
||||
{"uno_valid_to", tok_uno_valid_to, 0},
|
||||
-#line 126 "locfile-kw.gperf"
|
||||
+#line 127 "locfile-kw.gperf"
|
||||
{"decimal_point", tok_decimal_point, 0},
|
||||
{""},
|
||||
-#line 133 "locfile-kw.gperf"
|
||||
+#line 134 "locfile-kw.gperf"
|
||||
{"abmon", tok_abmon, 0},
|
||||
{""}, {""}, {""}, {""},
|
||||
-#line 107 "locfile-kw.gperf"
|
||||
+#line 108 "locfile-kw.gperf"
|
||||
{"duo_frac_digits", tok_duo_frac_digits, 0},
|
||||
-#line 182 "locfile-kw.gperf"
|
||||
+#line 183 "locfile-kw.gperf"
|
||||
{"tel_int_fmt", tok_tel_int_fmt, 0},
|
||||
-#line 123 "locfile-kw.gperf"
|
||||
+#line 124 "locfile-kw.gperf"
|
||||
{"duo_valid_to", tok_duo_valid_to, 0},
|
||||
-#line 146 "locfile-kw.gperf"
|
||||
+#line 147 "locfile-kw.gperf"
|
||||
{"first_weekday", tok_first_weekday, 0},
|
||||
{""},
|
||||
-#line 130 "locfile-kw.gperf"
|
||||
+#line 131 "locfile-kw.gperf"
|
||||
{"abday", tok_abday, 0},
|
||||
{""},
|
||||
-#line 200 "locfile-kw.gperf"
|
||||
+#line 201 "locfile-kw.gperf"
|
||||
{"abbreviation", tok_abbreviation, 0},
|
||||
-#line 147 "locfile-kw.gperf"
|
||||
+#line 148 "locfile-kw.gperf"
|
||||
{"first_workday", tok_first_workday, 0},
|
||||
{""}, {""},
|
||||
-#line 97 "locfile-kw.gperf"
|
||||
+#line 98 "locfile-kw.gperf"
|
||||
{"n_sign_posn", tok_n_sign_posn, 0},
|
||||
{""}, {""}, {""},
|
||||
-#line 145 "locfile-kw.gperf"
|
||||
+#line 146 "locfile-kw.gperf"
|
||||
{"alt_digits", tok_alt_digits, 0},
|
||||
{""}, {""},
|
||||
-#line 128 "locfile-kw.gperf"
|
||||
+#line 129 "locfile-kw.gperf"
|
||||
{"grouping", tok_grouping, 0},
|
||||
{""},
|
||||
#line 45 "locfile-kw.gperf"
|
||||
{"blank", tok_blank, 0},
|
||||
{""}, {""},
|
||||
-#line 196 "locfile-kw.gperf"
|
||||
+#line 197 "locfile-kw.gperf"
|
||||
{"language", tok_language, 0},
|
||||
-#line 120 "locfile-kw.gperf"
|
||||
+#line 121 "locfile-kw.gperf"
|
||||
{"uno_valid_from", tok_uno_valid_from, 0},
|
||||
{""},
|
||||
-#line 199 "locfile-kw.gperf"
|
||||
+#line 200 "locfile-kw.gperf"
|
||||
{"application", tok_application, 0},
|
||||
{""},
|
||||
-#line 80 "locfile-kw.gperf"
|
||||
+#line 81 "locfile-kw.gperf"
|
||||
{"elifndef", tok_elifndef, 0},
|
||||
{""}, {""}, {""}, {""}, {""},
|
||||
-#line 122 "locfile-kw.gperf"
|
||||
+#line 123 "locfile-kw.gperf"
|
||||
{"duo_valid_from", tok_duo_valid_from, 0},
|
||||
-#line 57 "locfile-kw.gperf"
|
||||
+#line 58 "locfile-kw.gperf"
|
||||
{"coll_weight_max", tok_coll_weight_max, 0},
|
||||
{""},
|
||||
-#line 79 "locfile-kw.gperf"
|
||||
+#line 80 "locfile-kw.gperf"
|
||||
{"elifdef", tok_elifdef, 0},
|
||||
-#line 67 "locfile-kw.gperf"
|
||||
+#line 68 "locfile-kw.gperf"
|
||||
{"backward", tok_backward, 0},
|
||||
-#line 106 "locfile-kw.gperf"
|
||||
+#line 107 "locfile-kw.gperf"
|
||||
{"duo_int_frac_digits", tok_duo_int_frac_digits, 0},
|
||||
{""}, {""}, {""}, {""}, {""}, {""},
|
||||
-#line 96 "locfile-kw.gperf"
|
||||
+#line 97 "locfile-kw.gperf"
|
||||
{"p_sign_posn", tok_p_sign_posn, 0},
|
||||
{""},
|
||||
-#line 203 "locfile-kw.gperf"
|
||||
+#line 204 "locfile-kw.gperf"
|
||||
{"category", tok_category, 0},
|
||||
{""}, {""}, {""}, {""},
|
||||
-#line 134 "locfile-kw.gperf"
|
||||
+#line 135 "locfile-kw.gperf"
|
||||
{"mon", tok_mon, 0},
|
||||
{""},
|
||||
-#line 124 "locfile-kw.gperf"
|
||||
+#line 125 "locfile-kw.gperf"
|
||||
{"conversion_rate", tok_conversion_rate, 0},
|
||||
{""}, {""}, {""}, {""}, {""},
|
||||
-#line 63 "locfile-kw.gperf"
|
||||
+#line 64 "locfile-kw.gperf"
|
||||
{"order_start", tok_order_start, 0},
|
||||
{""}, {""}, {""}, {""}, {""},
|
||||
-#line 178 "locfile-kw.gperf"
|
||||
+#line 179 "locfile-kw.gperf"
|
||||
{"lang_ab", tok_lang_ab, 0},
|
||||
-#line 180 "locfile-kw.gperf"
|
||||
+#line 181 "locfile-kw.gperf"
|
||||
{"lang_lib", tok_lang_lib, 0},
|
||||
{""}, {""}, {""},
|
||||
-#line 192 "locfile-kw.gperf"
|
||||
+#line 193 "locfile-kw.gperf"
|
||||
{"contact", tok_contact, 0},
|
||||
{""}, {""}, {""},
|
||||
-#line 173 "locfile-kw.gperf"
|
||||
+#line 174 "locfile-kw.gperf"
|
||||
{"country_ab3", tok_country_ab3, 0},
|
||||
{""}, {""}, {""},
|
||||
-#line 193 "locfile-kw.gperf"
|
||||
+#line 194 "locfile-kw.gperf"
|
||||
{"email", tok_email, 0},
|
||||
-#line 172 "locfile-kw.gperf"
|
||||
+#line 173 "locfile-kw.gperf"
|
||||
{"country_ab2", tok_country_ab2, 0},
|
||||
{""}, {""}, {""},
|
||||
#line 55 "locfile-kw.gperf"
|
||||
{"default_missing", tok_default_missing, 0},
|
||||
{""}, {""},
|
||||
-#line 195 "locfile-kw.gperf"
|
||||
+#line 196 "locfile-kw.gperf"
|
||||
{"fax", tok_fax, 0},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
-#line 174 "locfile-kw.gperf"
|
||||
+#line 175 "locfile-kw.gperf"
|
||||
{"country_num", tok_country_num, 0},
|
||||
{""}, {""}, {""}, {""}, {""}, {""},
|
||||
#line 51 "locfile-kw.gperf"
|
||||
{"map", tok_map, 0},
|
||||
-#line 65 "locfile-kw.gperf"
|
||||
+#line 66 "locfile-kw.gperf"
|
||||
{"from", tok_from, 0},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
-#line 86 "locfile-kw.gperf"
|
||||
+#line 87 "locfile-kw.gperf"
|
||||
{"mon_thousands_sep", tok_mon_thousands_sep, 0},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
{""}, {""}, {""},
|
||||
-#line 81 "locfile-kw.gperf"
|
||||
+#line 82 "locfile-kw.gperf"
|
||||
{"endif", tok_endif, 0},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
-#line 151 "locfile-kw.gperf"
|
||||
+#line 152 "locfile-kw.gperf"
|
||||
{"alt_mon", tok_alt_mon, 0},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
-#line 76 "locfile-kw.gperf"
|
||||
+#line 77 "locfile-kw.gperf"
|
||||
{"undef", tok_undef, 0},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
-#line 59 "locfile-kw.gperf"
|
||||
+#line 60 "locfile-kw.gperf"
|
||||
{"collating-element", tok_collating_element, 0},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
-#line 152 "locfile-kw.gperf"
|
||||
+#line 153 "locfile-kw.gperf"
|
||||
{"ab_alt_mon", tok_ab_alt_mon, 0},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
-#line 66 "locfile-kw.gperf"
|
||||
+#line 67 "locfile-kw.gperf"
|
||||
{"forward", tok_forward, 0},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
{""}, {""}, {""}, {""}, {""},
|
||||
-#line 85 "locfile-kw.gperf"
|
||||
+#line 86 "locfile-kw.gperf"
|
||||
{"mon_decimal_point", tok_mon_decimal_point, 0},
|
||||
{""}, {""},
|
||||
-#line 169 "locfile-kw.gperf"
|
||||
+#line 170 "locfile-kw.gperf"
|
||||
{"postal_fmt", tok_postal_fmt, 0},
|
||||
{""}, {""}, {""}, {""}, {""},
|
||||
-#line 60 "locfile-kw.gperf"
|
||||
+#line 61 "locfile-kw.gperf"
|
||||
{"collating-symbol", tok_collating_symbol, 0},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
@@ -583,15 +584,15 @@ locfile_hash (register const char *str, register size_t len)
|
||||
#line 38 "locfile-kw.gperf"
|
||||
{"alnum", tok_alnum, 0},
|
||||
{""},
|
||||
-#line 87 "locfile-kw.gperf"
|
||||
+#line 88 "locfile-kw.gperf"
|
||||
{"mon_grouping", tok_mon_grouping, 0},
|
||||
{""},
|
||||
-#line 179 "locfile-kw.gperf"
|
||||
+#line 180 "locfile-kw.gperf"
|
||||
{"lang_term", tok_lang_term, 0},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
-#line 77 "locfile-kw.gperf"
|
||||
+#line 78 "locfile-kw.gperf"
|
||||
{"ifdef", tok_ifdef, 0},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
@@ -599,7 +600,7 @@ locfile_hash (register const char *str, register size_t len)
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
{""}, {""}, {""}, {""},
|
||||
-#line 138 "locfile-kw.gperf"
|
||||
+#line 139 "locfile-kw.gperf"
|
||||
{"am_pm", tok_am_pm, 0}
|
||||
};
|
||||
|
||||
diff --git a/locale/programs/locfile-token.h b/locale/programs/locfile-token.h
|
||||
index 414ad3076223e971..f57d594e8d25c06f 100644
|
||||
--- a/locale/programs/locfile-token.h
|
||||
+++ b/locale/programs/locfile-token.h
|
||||
@@ -91,6 +91,7 @@ enum token_t
|
||||
tok_translit_ignore,
|
||||
tok_default_missing,
|
||||
tok_lc_collate,
|
||||
+ tok_codepoint_collation,
|
||||
tok_coll_weight_max,
|
||||
tok_section_symbol,
|
||||
tok_collating_element,
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,65 @@
|
||||
commit 1d8e3a2c6636cf0b1b8fa2f869cef6ec10726933
|
||||
Author: Carlos O'Donell <carlos@redhat.com>
|
||||
Date: Mon Jan 31 00:34:41 2022 -0500
|
||||
|
||||
localedef: Fix handling of empty mon_decimal_point (Bug 28847)
|
||||
|
||||
The handling of mon_decimal_point is incorrect when it comes to
|
||||
handling the empty "" value. The existing parser in monetary_read()
|
||||
will correctly handle setting the non-wide-character value and the
|
||||
wide-character value e.g. STR_ELEM_WC(mon_decimal_point) if they are
|
||||
set in the locale definition. However, in monetary_finish() we have
|
||||
conflicting TEST_ELEM() which sets a default value (if the locale
|
||||
definition doesn't include one), and subsequent code which looks for
|
||||
mon_decimal_point to be NULL to issue a specific error message and set
|
||||
the defaults. The latter is unused because TEST_ELEM() always sets a
|
||||
default. The simplest solution is to remove the TEST_ELEM() check,
|
||||
and allow the existing check to look to see if mon_decimal_point is
|
||||
NULL and set an appropriate default. The final fix is to move the
|
||||
setting of mon_decimal_point_wc so it occurs only when
|
||||
mon_decimal_point is being set to a default, keeping both values
|
||||
consistent. There is no way to tell the difference between
|
||||
mon_decimal_point_wc having been set to the empty string and not
|
||||
having been defined at all, for that distinction we must use
|
||||
mon_decimal_point being NULL or "", and so we must logically set
|
||||
the default together with mon_decimal_point.
|
||||
|
||||
Lastly, there are more fixes similar to this that could be made to
|
||||
ld-monetary.c, but we avoid that in order to fix just the code
|
||||
required for mon_decimal_point, which impacts the ability for C.UTF-8
|
||||
to set mon_decimal_point to "", since without this fix we end up with
|
||||
an inconsistent setting of mon_decimal_point set to "", but
|
||||
mon_decimal_point_wc set to "." which is incorrect.
|
||||
|
||||
Tested on x86_64 and i686 without regression.
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
diff --git a/locale/programs/ld-monetary.c b/locale/programs/ld-monetary.c
|
||||
index e1e45a3409123bf4..9b9a55bb4766dfcf 100644
|
||||
--- a/locale/programs/ld-monetary.c
|
||||
+++ b/locale/programs/ld-monetary.c
|
||||
@@ -208,7 +208,6 @@ No definition for %s category found"), "LC_MONETARY");
|
||||
|
||||
TEST_ELEM (int_curr_symbol, "");
|
||||
TEST_ELEM (currency_symbol, "");
|
||||
- TEST_ELEM (mon_decimal_point, ".");
|
||||
TEST_ELEM (mon_thousands_sep, "");
|
||||
TEST_ELEM (positive_sign, "");
|
||||
TEST_ELEM (negative_sign, "");
|
||||
@@ -258,6 +257,7 @@ not correspond to a valid name in ISO 4217 [--no-warnings=intcurrsym]"),
|
||||
record_error (0, 0, _("%s: field `%s' not defined"),
|
||||
"LC_MONETARY", "mon_decimal_point");
|
||||
monetary->mon_decimal_point = ".";
|
||||
+ monetary->mon_decimal_point_wc = L'.';
|
||||
}
|
||||
else if (monetary->mon_decimal_point[0] == '\0' && ! be_quiet && ! nothing)
|
||||
{
|
||||
@@ -265,8 +265,6 @@ not correspond to a valid name in ISO 4217 [--no-warnings=intcurrsym]"),
|
||||
%s: value for field `%s' must not be an empty string"),
|
||||
"LC_MONETARY", "mon_decimal_point");
|
||||
}
|
||||
- if (monetary->mon_decimal_point_wc == L'\0')
|
||||
- monetary->mon_decimal_point_wc = L'.';
|
||||
|
||||
if (monetary->mon_grouping_len == 0)
|
||||
{
|
@ -0,0 +1,734 @@
|
||||
commit de82cb0da4b8fa5b3d56c457438d2568c67ab1b1
|
||||
Author: Joseph Myers <joseph@codesourcery.com>
|
||||
Date: Tue Oct 12 13:48:39 2021 +0000
|
||||
|
||||
Add TEST_COMPARE_STRING_WIDE to support/check.h
|
||||
|
||||
I'd like to be able to test narrow and wide string interfaces, with
|
||||
the narrow string tests using TEST_COMPARE_STRING and the wide string
|
||||
tests using something analogous (possibly generated using macros from
|
||||
a common test template for both the narrow and wide string tests where
|
||||
appropriate).
|
||||
|
||||
Add such a TEST_COMPARE_STRING_WIDE, along with functions
|
||||
support_quote_blob_wide and support_test_compare_string_wide that it
|
||||
builds on. Those functions are built using macros from common
|
||||
templates shared by the narrow and wide string implementations, though
|
||||
I didn't do that for the tests of test functions. In
|
||||
support_quote_blob_wide, I chose to use the \x{} delimited escape
|
||||
sequence syntax proposed for C2X in N2785, rather than e.g. trying to
|
||||
generate the end of a string and the start of a new string when
|
||||
ambiguity would result from undelimited \x (when the next character
|
||||
after such an escape sequence is valid hex) or forcing an escape
|
||||
sequence to be used for the next character in the case of such
|
||||
ambiguity.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
diff --git a/support/Makefile b/support/Makefile
|
||||
index 75bad6715ac3d08c..3c941e1ba9e29aa4 100644
|
||||
--- a/support/Makefile
|
||||
+++ b/support/Makefile
|
||||
@@ -70,6 +70,7 @@ libsupport-routines = \
|
||||
support_openpty \
|
||||
support_paths \
|
||||
support_quote_blob \
|
||||
+ support_quote_blob_wide \
|
||||
support_quote_string \
|
||||
support_record_failure \
|
||||
support_run_diff \
|
||||
@@ -83,6 +84,7 @@ libsupport-routines = \
|
||||
support_test_compare_blob \
|
||||
support_test_compare_failure \
|
||||
support_test_compare_string \
|
||||
+ support_test_compare_string_wide \
|
||||
support_test_main \
|
||||
support_test_verify_impl \
|
||||
support_wait_for_thread_exit \
|
||||
@@ -275,11 +277,13 @@ tests = \
|
||||
tst-support-open-dev-null-range \
|
||||
tst-support-process_state \
|
||||
tst-support_quote_blob \
|
||||
+ tst-support_quote_blob_wide \
|
||||
tst-support_quote_string \
|
||||
tst-support_record_failure \
|
||||
tst-test_compare \
|
||||
tst-test_compare_blob \
|
||||
tst-test_compare_string \
|
||||
+ tst-test_compare_string_wide \
|
||||
tst-timespec \
|
||||
tst-xreadlink \
|
||||
tst-xsigstack \
|
||||
diff --git a/support/check.h b/support/check.h
|
||||
index 83662b2d10c8cf58..9b1844352f32513a 100644
|
||||
--- a/support/check.h
|
||||
+++ b/support/check.h
|
||||
@@ -20,6 +20,7 @@
|
||||
#define SUPPORT_CHECK_H
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
+#include <stddef.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
@@ -171,11 +172,25 @@ void support_test_compare_blob (const void *left,
|
||||
(support_test_compare_string (left, right, __FILE__, __LINE__, \
|
||||
#left, #right))
|
||||
|
||||
+/* Compare the wide strings LEFT and RIGHT and report a test failure
|
||||
+ if they are different. Also report failure if one of the arguments
|
||||
+ is a null pointer and the other is not. The strings should be
|
||||
+ reasonably short because on mismatch, both are printed. */
|
||||
+#define TEST_COMPARE_STRING_WIDE(left, right) \
|
||||
+ (support_test_compare_string_wide (left, right, __FILE__, __LINE__, \
|
||||
+ #left, #right))
|
||||
+
|
||||
void support_test_compare_string (const char *left, const char *right,
|
||||
const char *file, int line,
|
||||
const char *left_expr,
|
||||
const char *right_expr);
|
||||
|
||||
+void support_test_compare_string_wide (const wchar_t *left,
|
||||
+ const wchar_t *right,
|
||||
+ const char *file, int line,
|
||||
+ const char *left_expr,
|
||||
+ const char *right_expr);
|
||||
+
|
||||
/* Internal function called by the test driver. */
|
||||
int support_report_failure (int status)
|
||||
__attribute__ ((weak, warn_unused_result));
|
||||
diff --git a/support/support.h b/support/support.h
|
||||
index c219e0d9d1aef046..29d56c7c891ee34b 100644
|
||||
--- a/support/support.h
|
||||
+++ b/support/support.h
|
||||
@@ -73,6 +73,12 @@ void support_write_file_string (const char *path, const char *contents);
|
||||
the result). */
|
||||
char *support_quote_blob (const void *blob, size_t length);
|
||||
|
||||
+/* Quote the contents of the wide character array starting at BLOB, of
|
||||
+ LENGTH wide characters, in such a way that the result string can be
|
||||
+ included in a C wide string literal (in single/double quotes,
|
||||
+ without putting the quotes into the result). */
|
||||
+char *support_quote_blob_wide (const void *blob, size_t length);
|
||||
+
|
||||
/* Quote the contents of the string, in such a way that the result
|
||||
string can be included in a C literal (in single/double quotes,
|
||||
without putting the quotes into the result). */
|
||||
diff --git a/support/support_quote_blob.c b/support/support_quote_blob.c
|
||||
index b5e70125f13eb081..611980c9a2108670 100644
|
||||
--- a/support/support_quote_blob.c
|
||||
+++ b/support/support_quote_blob.c
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* Quote a blob so that it can be used in C literals.
|
||||
+/* Quote a narrow string blob so that it can be used in C literals.
|
||||
Copyright (C) 2018-2021 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
@@ -16,68 +16,9 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
-#include <support/support.h>
|
||||
-#include <support/xmemstream.h>
|
||||
+#define CHAR unsigned char
|
||||
+#define L_(C) C
|
||||
+#define SUPPORT_QUOTE_BLOB support_quote_blob
|
||||
+#define WIDE 0
|
||||
|
||||
-char *
|
||||
-support_quote_blob (const void *blob, size_t length)
|
||||
-{
|
||||
- struct xmemstream out;
|
||||
- xopen_memstream (&out);
|
||||
-
|
||||
- const unsigned char *p = blob;
|
||||
- for (size_t i = 0; i < length; ++i)
|
||||
- {
|
||||
- unsigned char ch = p[i];
|
||||
-
|
||||
- /* Use C backslash escapes for those control characters for
|
||||
- which they are defined. */
|
||||
- switch (ch)
|
||||
- {
|
||||
- case '\a':
|
||||
- putc_unlocked ('\\', out.out);
|
||||
- putc_unlocked ('a', out.out);
|
||||
- break;
|
||||
- case '\b':
|
||||
- putc_unlocked ('\\', out.out);
|
||||
- putc_unlocked ('b', out.out);
|
||||
- break;
|
||||
- case '\f':
|
||||
- putc_unlocked ('\\', out.out);
|
||||
- putc_unlocked ('f', out.out);
|
||||
- break;
|
||||
- case '\n':
|
||||
- putc_unlocked ('\\', out.out);
|
||||
- putc_unlocked ('n', out.out);
|
||||
- break;
|
||||
- case '\r':
|
||||
- putc_unlocked ('\\', out.out);
|
||||
- putc_unlocked ('r', out.out);
|
||||
- break;
|
||||
- case '\t':
|
||||
- putc_unlocked ('\\', out.out);
|
||||
- putc_unlocked ('t', out.out);
|
||||
- break;
|
||||
- case '\v':
|
||||
- putc_unlocked ('\\', out.out);
|
||||
- putc_unlocked ('v', out.out);
|
||||
- break;
|
||||
- case '\\':
|
||||
- case '\'':
|
||||
- case '\"':
|
||||
- putc_unlocked ('\\', out.out);
|
||||
- putc_unlocked (ch, out.out);
|
||||
- break;
|
||||
- default:
|
||||
- if (ch < ' ' || ch > '~')
|
||||
- /* Use octal sequences because they are fixed width,
|
||||
- unlike hexadecimal sequences. */
|
||||
- fprintf (out.out, "\\%03o", ch);
|
||||
- else
|
||||
- putc_unlocked (ch, out.out);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- xfclose_memstream (&out);
|
||||
- return out.buffer;
|
||||
-}
|
||||
+#include "support_quote_blob_main.c"
|
||||
diff --git a/support/support_quote_blob_main.c b/support/support_quote_blob_main.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..19ccfad59311bfee
|
||||
--- /dev/null
|
||||
+++ b/support/support_quote_blob_main.c
|
||||
@@ -0,0 +1,88 @@
|
||||
+/* Quote a blob so that it can be used in C literals.
|
||||
+ Copyright (C) 2018-2021 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/>. */
|
||||
+
|
||||
+#include <support/support.h>
|
||||
+#include <support/xmemstream.h>
|
||||
+
|
||||
+char *
|
||||
+SUPPORT_QUOTE_BLOB (const void *blob, size_t length)
|
||||
+{
|
||||
+ struct xmemstream out;
|
||||
+ xopen_memstream (&out);
|
||||
+
|
||||
+ const CHAR *p = blob;
|
||||
+ for (size_t i = 0; i < length; ++i)
|
||||
+ {
|
||||
+ CHAR ch = p[i];
|
||||
+
|
||||
+ /* Use C backslash escapes for those control characters for
|
||||
+ which they are defined. */
|
||||
+ switch (ch)
|
||||
+ {
|
||||
+ case L_('\a'):
|
||||
+ putc_unlocked ('\\', out.out);
|
||||
+ putc_unlocked ('a', out.out);
|
||||
+ break;
|
||||
+ case L_('\b'):
|
||||
+ putc_unlocked ('\\', out.out);
|
||||
+ putc_unlocked ('b', out.out);
|
||||
+ break;
|
||||
+ case L_('\f'):
|
||||
+ putc_unlocked ('\\', out.out);
|
||||
+ putc_unlocked ('f', out.out);
|
||||
+ break;
|
||||
+ case L_('\n'):
|
||||
+ putc_unlocked ('\\', out.out);
|
||||
+ putc_unlocked ('n', out.out);
|
||||
+ break;
|
||||
+ case L_('\r'):
|
||||
+ putc_unlocked ('\\', out.out);
|
||||
+ putc_unlocked ('r', out.out);
|
||||
+ break;
|
||||
+ case L_('\t'):
|
||||
+ putc_unlocked ('\\', out.out);
|
||||
+ putc_unlocked ('t', out.out);
|
||||
+ break;
|
||||
+ case L_('\v'):
|
||||
+ putc_unlocked ('\\', out.out);
|
||||
+ putc_unlocked ('v', out.out);
|
||||
+ break;
|
||||
+ case L_('\\'):
|
||||
+ case L_('\''):
|
||||
+ case L_('\"'):
|
||||
+ putc_unlocked ('\\', out.out);
|
||||
+ putc_unlocked (ch, out.out);
|
||||
+ break;
|
||||
+ default:
|
||||
+ if (ch < L_(' ') || ch > L_('~'))
|
||||
+ /* For narrow characters, use octal sequences because they
|
||||
+ are fixed width, unlike hexadecimal sequences. For
|
||||
+ wide characters, use N2785 delimited escape
|
||||
+ sequences. */
|
||||
+ if (WIDE)
|
||||
+ fprintf (out.out, "\\x{%x}", (unsigned int) ch);
|
||||
+ else
|
||||
+ fprintf (out.out, "\\%03o", (unsigned int) ch);
|
||||
+ else
|
||||
+ putc_unlocked (ch, out.out);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ xfclose_memstream (&out);
|
||||
+ return out.buffer;
|
||||
+}
|
||||
diff --git a/support/support_quote_blob_wide.c b/support/support_quote_blob_wide.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..c451ed889c21c626
|
||||
--- /dev/null
|
||||
+++ b/support/support_quote_blob_wide.c
|
||||
@@ -0,0 +1,24 @@
|
||||
+/* Quote a wide string blob so that it can be used in C literals.
|
||||
+ Copyright (C) 2018-2021 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/>. */
|
||||
+
|
||||
+#define CHAR wchar_t
|
||||
+#define L_(C) L ## C
|
||||
+#define SUPPORT_QUOTE_BLOB support_quote_blob_wide
|
||||
+#define WIDE 1
|
||||
+
|
||||
+#include "support_quote_blob_main.c"
|
||||
diff --git a/support/support_test_compare_string.c b/support/support_test_compare_string.c
|
||||
index cbeaf7b1eeea8ca8..12bafe43d44ae3d7 100644
|
||||
--- a/support/support_test_compare_string.c
|
||||
+++ b/support/support_test_compare_string.c
|
||||
@@ -16,76 +16,13 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
-#include <stdio.h>
|
||||
-#include <stdlib.h>
|
||||
-#include <string.h>
|
||||
-#include <support/check.h>
|
||||
-#include <support/support.h>
|
||||
-#include <support/xmemstream.h>
|
||||
-
|
||||
-static void
|
||||
-report_length (const char *what, const char *str, size_t length)
|
||||
-{
|
||||
- if (str == NULL)
|
||||
- printf (" %s string: NULL\n", what);
|
||||
- else
|
||||
- printf (" %s string: %zu bytes\n", what, length);
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-report_string (const char *what, const unsigned char *blob,
|
||||
- size_t length, const char *expr)
|
||||
-{
|
||||
- if (length > 0)
|
||||
- {
|
||||
- printf (" %s (evaluated from %s):\n", what, expr);
|
||||
- char *quoted = support_quote_blob (blob, length);
|
||||
- printf (" \"%s\"\n", quoted);
|
||||
- free (quoted);
|
||||
-
|
||||
- fputs (" ", stdout);
|
||||
- for (size_t i = 0; i < length; ++i)
|
||||
- printf (" %02X", blob[i]);
|
||||
- putc ('\n', stdout);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-static size_t
|
||||
-string_length_or_zero (const char *str)
|
||||
-{
|
||||
- if (str == NULL)
|
||||
- return 0;
|
||||
- else
|
||||
- return strlen (str);
|
||||
-}
|
||||
-
|
||||
-void
|
||||
-support_test_compare_string (const char *left, const char *right,
|
||||
- const char *file, int line,
|
||||
- const char *left_expr, const char *right_expr)
|
||||
-{
|
||||
- /* Two null pointers are accepted. */
|
||||
- if (left == NULL && right == NULL)
|
||||
- return;
|
||||
-
|
||||
- size_t left_length = string_length_or_zero (left);
|
||||
- size_t right_length = string_length_or_zero (right);
|
||||
-
|
||||
- if (left_length != right_length || left == NULL || right == NULL
|
||||
- || memcmp (left, right, left_length) != 0)
|
||||
- {
|
||||
- support_record_failure ();
|
||||
- printf ("%s:%d: error: string comparison failed\n", file, line);
|
||||
- if (left_length == right_length && right != NULL && left != NULL)
|
||||
- printf (" string length: %zu bytes\n", left_length);
|
||||
- else
|
||||
- {
|
||||
- report_length ("left", left, left_length);
|
||||
- report_length ("right", right, right_length);
|
||||
- }
|
||||
- report_string ("left", (const unsigned char *) left,
|
||||
- left_length, left_expr);
|
||||
- report_string ("right", (const unsigned char *) right,
|
||||
- right_length, right_expr);
|
||||
- }
|
||||
-}
|
||||
+#define CHAR char
|
||||
+#define UCHAR unsigned char
|
||||
+#define LPREFIX ""
|
||||
+#define STRLEN strlen
|
||||
+#define MEMCMP memcmp
|
||||
+#define SUPPORT_QUOTE_BLOB support_quote_blob
|
||||
+#define SUPPORT_TEST_COMPARE_STRING support_test_compare_string
|
||||
+#define WIDE 0
|
||||
+
|
||||
+#include "support_test_compare_string_main.c"
|
||||
diff --git a/support/support_test_compare_string_main.c b/support/support_test_compare_string_main.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..0edc0ca97d79d71e
|
||||
--- /dev/null
|
||||
+++ b/support/support_test_compare_string_main.c
|
||||
@@ -0,0 +1,94 @@
|
||||
+/* Check two strings for equality.
|
||||
+ Copyright (C) 2018-2021 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/>. */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <wchar.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/support.h>
|
||||
+#include <support/xmemstream.h>
|
||||
+
|
||||
+static void
|
||||
+report_length (const char *what, const CHAR *str, size_t length)
|
||||
+{
|
||||
+ if (str == NULL)
|
||||
+ printf (" %s string: NULL\n", what);
|
||||
+ else
|
||||
+ printf (" %s string: %zu %s\n", what, length,
|
||||
+ WIDE ? "wide characters" : "bytes");
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+report_string (const char *what, const UCHAR *blob,
|
||||
+ size_t length, const char *expr)
|
||||
+{
|
||||
+ if (length > 0)
|
||||
+ {
|
||||
+ printf (" %s (evaluated from %s):\n", what, expr);
|
||||
+ char *quoted = SUPPORT_QUOTE_BLOB (blob, length);
|
||||
+ printf (" %s\"%s\"\n", LPREFIX, quoted);
|
||||
+ free (quoted);
|
||||
+
|
||||
+ fputs (" ", stdout);
|
||||
+ for (size_t i = 0; i < length; ++i)
|
||||
+ printf (" %02X", (unsigned int) blob[i]);
|
||||
+ putc ('\n', stdout);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static size_t
|
||||
+string_length_or_zero (const CHAR *str)
|
||||
+{
|
||||
+ if (str == NULL)
|
||||
+ return 0;
|
||||
+ else
|
||||
+ return STRLEN (str);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+SUPPORT_TEST_COMPARE_STRING (const CHAR *left, const CHAR *right,
|
||||
+ const char *file, int line,
|
||||
+ const char *left_expr, const char *right_expr)
|
||||
+{
|
||||
+ /* Two null pointers are accepted. */
|
||||
+ if (left == NULL && right == NULL)
|
||||
+ return;
|
||||
+
|
||||
+ size_t left_length = string_length_or_zero (left);
|
||||
+ size_t right_length = string_length_or_zero (right);
|
||||
+
|
||||
+ if (left_length != right_length || left == NULL || right == NULL
|
||||
+ || MEMCMP (left, right, left_length) != 0)
|
||||
+ {
|
||||
+ support_record_failure ();
|
||||
+ printf ("%s:%d: error: string comparison failed\n", file, line);
|
||||
+ if (left_length == right_length && right != NULL && left != NULL)
|
||||
+ printf (" string length: %zu %s\n", left_length,
|
||||
+ WIDE ? "wide characters" : "bytes");
|
||||
+ else
|
||||
+ {
|
||||
+ report_length ("left", left, left_length);
|
||||
+ report_length ("right", right, right_length);
|
||||
+ }
|
||||
+ report_string ("left", (const UCHAR *) left,
|
||||
+ left_length, left_expr);
|
||||
+ report_string ("right", (const UCHAR *) right,
|
||||
+ right_length, right_expr);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/support/support_test_compare_string_wide.c b/support/support_test_compare_string_wide.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..88b560b142a3c356
|
||||
--- /dev/null
|
||||
+++ b/support/support_test_compare_string_wide.c
|
||||
@@ -0,0 +1,28 @@
|
||||
+/* Check two wide strings for equality.
|
||||
+ Copyright (C) 2018-2021 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/>. */
|
||||
+
|
||||
+#define CHAR wchar_t
|
||||
+#define UCHAR wchar_t
|
||||
+#define LPREFIX "L"
|
||||
+#define STRLEN wcslen
|
||||
+#define MEMCMP wmemcmp
|
||||
+#define SUPPORT_QUOTE_BLOB support_quote_blob_wide
|
||||
+#define SUPPORT_TEST_COMPARE_STRING support_test_compare_string_wide
|
||||
+#define WIDE 1
|
||||
+
|
||||
+#include "support_test_compare_string_main.c"
|
||||
diff --git a/support/tst-support_quote_blob_wide.c b/support/tst-support_quote_blob_wide.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..ea71a1f7f873b23a
|
||||
--- /dev/null
|
||||
+++ b/support/tst-support_quote_blob_wide.c
|
||||
@@ -0,0 +1,66 @@
|
||||
+/* Test the support_quote_blob_wide function.
|
||||
+ Copyright (C) 2018-2021 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/>. */
|
||||
+
|
||||
+#include <support/check.h>
|
||||
+#include <support/support.h>
|
||||
+#include <string.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ /* Check handling of the empty blob, both with and without trailing
|
||||
+ NUL byte. */
|
||||
+ char *p = support_quote_blob_wide (L"", 0);
|
||||
+ TEST_COMPARE (strlen (p), 0);
|
||||
+ free (p);
|
||||
+ p = support_quote_blob_wide (L"X", 0);
|
||||
+ TEST_COMPARE (strlen (p), 0);
|
||||
+ free (p);
|
||||
+
|
||||
+ /* Check escaping of backslash-escaped characters, and lack of
|
||||
+ escaping for other shell meta-characters. */
|
||||
+ p = support_quote_blob_wide (L"$()*?`@[]{}~\'\"X", 14);
|
||||
+ TEST_COMPARE (strcmp (p, "$()*?`@[]{}~\\'\\\""), 0);
|
||||
+ free (p);
|
||||
+
|
||||
+ /* Check lack of escaping for letters and digits. */
|
||||
+#define LETTERS_AND_DIGTS \
|
||||
+ "abcdefghijklmnopqrstuvwxyz" \
|
||||
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
|
||||
+ "0123456789"
|
||||
+#define CONCATX(X, Y) X ## Y
|
||||
+#define CONCAT(X, Y) CONCATX (X, Y)
|
||||
+#define WLETTERS_AND_DIGTS CONCAT (L, LETTERS_AND_DIGTS)
|
||||
+ p = support_quote_blob_wide (WLETTERS_AND_DIGTS "@", 2 * 26 + 10);
|
||||
+ TEST_COMPARE (strcmp (p, LETTERS_AND_DIGTS), 0);
|
||||
+ free (p);
|
||||
+
|
||||
+ /* Check escaping of control characters and other non-printable
|
||||
+ characters. */
|
||||
+ p = support_quote_blob_wide (L"\r\n\t\a\b\f\v\1\177\200\377"
|
||||
+ "\x123\x76543210\xfedcba98\0@", 17);
|
||||
+ TEST_COMPARE (strcmp (p, "\\r\\n\\t\\a\\b\\f\\v\\x{1}"
|
||||
+ "\\x{7f}\\x{80}\\x{ff}\\x{123}\\x{76543210}"
|
||||
+ "\\x{fedcba98}\\x{0}@\\x{0}"), 0);
|
||||
+ free (p);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/support/tst-test_compare_string_wide.c b/support/tst-test_compare_string_wide.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..548f7dcdc60b82d8
|
||||
--- /dev/null
|
||||
+++ b/support/tst-test_compare_string_wide.c
|
||||
@@ -0,0 +1,107 @@
|
||||
+/* Basic test for the TEST_COMPARE_STRING_WIDE macro.
|
||||
+ Copyright (C) 2018-2021 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/>. */
|
||||
+
|
||||
+#include <string.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/capture_subprocess.h>
|
||||
+
|
||||
+static void
|
||||
+subprocess (void *closure)
|
||||
+{
|
||||
+ /* These tests should fail. They were chosen to cover differences
|
||||
+ in length (with the same contents), single-bit mismatches, and
|
||||
+ mismatching null pointers. */
|
||||
+ TEST_COMPARE_STRING_WIDE (L"", NULL); /* Line 29. */
|
||||
+ TEST_COMPARE_STRING_WIDE (L"X", L""); /* Line 30. */
|
||||
+ TEST_COMPARE_STRING_WIDE (NULL, L"X"); /* Line 31. */
|
||||
+ TEST_COMPARE_STRING_WIDE (L"abcd", L"abcD"); /* Line 32. */
|
||||
+ TEST_COMPARE_STRING_WIDE (L"abcd", NULL); /* Line 33. */
|
||||
+ TEST_COMPARE_STRING_WIDE (NULL, L"abcd"); /* Line 34. */
|
||||
+}
|
||||
+
|
||||
+/* Same contents, different addresses. */
|
||||
+wchar_t buffer_abc_1[] = L"abc";
|
||||
+wchar_t buffer_abc_2[] = L"abc";
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ /* This should succeed. Even if the pointers and array contents are
|
||||
+ different, zero-length inputs are not different. */
|
||||
+ TEST_COMPARE_STRING_WIDE (NULL, NULL);
|
||||
+ TEST_COMPARE_STRING_WIDE (L"", L"");
|
||||
+ TEST_COMPARE_STRING_WIDE (buffer_abc_1, buffer_abc_2);
|
||||
+ TEST_COMPARE_STRING_WIDE (buffer_abc_1, L"abc");
|
||||
+
|
||||
+ struct support_capture_subprocess proc = support_capture_subprocess
|
||||
+ (&subprocess, NULL);
|
||||
+
|
||||
+ /* Discard the reported error. */
|
||||
+ support_record_failure_reset ();
|
||||
+
|
||||
+ puts ("info: *** subprocess output starts ***");
|
||||
+ fputs (proc.out.buffer, stdout);
|
||||
+ puts ("info: *** subprocess output ends ***");
|
||||
+
|
||||
+ TEST_VERIFY
|
||||
+ (strcmp (proc.out.buffer,
|
||||
+"tst-test_compare_string_wide.c:29: error: string comparison failed\n"
|
||||
+" left string: 0 wide characters\n"
|
||||
+" right string: NULL\n"
|
||||
+"tst-test_compare_string_wide.c:30: error: string comparison failed\n"
|
||||
+" left string: 1 wide characters\n"
|
||||
+" right string: 0 wide characters\n"
|
||||
+" left (evaluated from L\"X\"):\n"
|
||||
+" L\"X\"\n"
|
||||
+" 58\n"
|
||||
+"tst-test_compare_string_wide.c:31: error: string comparison failed\n"
|
||||
+" left string: NULL\n"
|
||||
+" right string: 1 wide characters\n"
|
||||
+" right (evaluated from L\"X\"):\n"
|
||||
+" L\"X\"\n"
|
||||
+" 58\n"
|
||||
+"tst-test_compare_string_wide.c:32: error: string comparison failed\n"
|
||||
+" string length: 4 wide characters\n"
|
||||
+" left (evaluated from L\"abcd\"):\n"
|
||||
+" L\"abcd\"\n"
|
||||
+" 61 62 63 64\n"
|
||||
+" right (evaluated from L\"abcD\"):\n"
|
||||
+" L\"abcD\"\n"
|
||||
+" 61 62 63 44\n"
|
||||
+"tst-test_compare_string_wide.c:33: error: string comparison failed\n"
|
||||
+" left string: 4 wide characters\n"
|
||||
+" right string: NULL\n"
|
||||
+" left (evaluated from L\"abcd\"):\n"
|
||||
+" L\"abcd\"\n"
|
||||
+" 61 62 63 64\n"
|
||||
+"tst-test_compare_string_wide.c:34: error: string comparison failed\n"
|
||||
+" left string: NULL\n"
|
||||
+" right string: 4 wide characters\n"
|
||||
+" right (evaluated from L\"abcd\"):\n"
|
||||
+" L\"abcd\"\n"
|
||||
+" 61 62 63 64\n"
|
||||
+ ) == 0);
|
||||
+
|
||||
+ /* Check that there is no output on standard error. */
|
||||
+ support_capture_subprocess_check (&proc, "TEST_COMPARE_STRING_WIDE",
|
||||
+ 0, sc_allow_stdout);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
@ -0,0 +1,691 @@
|
||||
commit 7e0ad15c0fbfe25435c1acd0ed3e9cedfbff2488
|
||||
Author: Carlos O'Donell <carlos@redhat.com>
|
||||
Date: Mon Jan 31 00:34:42 2022 -0500
|
||||
|
||||
localedata: Adjust C.UTF-8 to align with C/POSIX.
|
||||
|
||||
We have had one downstream report from Canonical [1] that
|
||||
an rrdtool test was broken by the differences in LC_TIME
|
||||
that we had in the non-builtin C locale (C.UTF-8). If one
|
||||
application has an issue there are going to be others, and
|
||||
so with this commit we review and fix all the issues that
|
||||
cause the builtin C locale to be different from C.UTF-8,
|
||||
which includes:
|
||||
* mon_decimal_point should be empty e.g. ""
|
||||
- Depends on mon_decimal_point_wc fix.
|
||||
* negative_sign should be empty e.g. ""
|
||||
* week should be aligned with the builtin C/POSIX locale
|
||||
* d_fmt corrected with escaped slashes e.g. "%m//%d//%y"
|
||||
* yesstr and nostr should be empty e.g. ""
|
||||
* country_ab2 and country_ab3 should be empty e.g. ""
|
||||
|
||||
We bump LC_IDENTIFICATION version and adjust the date to
|
||||
indicate the change in the locale.
|
||||
|
||||
A new tst-c-utf8-consistency test is added to ensure
|
||||
consistency between C/POSIX and C.UTF-8.
|
||||
|
||||
Tested on x86_64 and i686 without regression.
|
||||
|
||||
[1] https://sourceware.org/pipermail/libc-alpha/2022-January/135703.html
|
||||
|
||||
Co-authored-by: Florian Weimer <fweimer@redhat.com>
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
diff --git a/localedata/Makefile b/localedata/Makefile
|
||||
index c9dd5a954e8194cc..5830b9d05141cccd 100644
|
||||
--- a/localedata/Makefile
|
||||
+++ b/localedata/Makefile
|
||||
@@ -155,11 +155,31 @@ locale_test_suite := tst_iswalnum tst_iswalpha tst_iswcntrl \
|
||||
tst_wcsxfrm tst_wctob tst_wctomb tst_wctrans \
|
||||
tst_wctype tst_wcwidth
|
||||
|
||||
-tests = $(locale_test_suite) tst-digits tst-setlocale bug-iconv-trans \
|
||||
- tst-leaks tst-mbswcs1 tst-mbswcs2 tst-mbswcs3 tst-mbswcs4 tst-mbswcs5 \
|
||||
- tst-mbswcs6 tst-xlocale1 tst-xlocale2 bug-usesetlocale \
|
||||
- tst-strfmon1 tst-sscanf bug-setlocale1 tst-setlocale2 tst-setlocale3 \
|
||||
- tst-wctype tst-iconv-math-trans
|
||||
+tests = \
|
||||
+ $(locale_test_suite) \
|
||||
+ bug-iconv-trans \
|
||||
+ bug-setlocale1 \
|
||||
+ bug-usesetlocale \
|
||||
+ tst-c-utf8-consistency \
|
||||
+ tst-digits \
|
||||
+ tst-iconv-math-trans \
|
||||
+ tst-leaks \
|
||||
+ tst-mbswcs1 \
|
||||
+ tst-mbswcs2 \
|
||||
+ tst-mbswcs3 \
|
||||
+ tst-mbswcs4 \
|
||||
+ tst-mbswcs5 \
|
||||
+ tst-mbswcs6 \
|
||||
+ tst-setlocale \
|
||||
+ tst-setlocale2 \
|
||||
+ tst-setlocale3 \
|
||||
+ tst-sscanf \
|
||||
+ tst-strfmon1 \
|
||||
+ tst-wctype \
|
||||
+ tst-xlocale1 \
|
||||
+ tst-xlocale2 \
|
||||
+ # tests
|
||||
+
|
||||
tests-static = bug-setlocale1-static
|
||||
tests += $(tests-static)
|
||||
ifeq (yes,$(build-shared))
|
||||
diff --git a/localedata/locales/C b/localedata/locales/C
|
||||
index ca801c79cf7e953e..fc0614e551519c6b 100644
|
||||
--- a/localedata/locales/C
|
||||
+++ b/localedata/locales/C
|
||||
@@ -12,8 +12,8 @@ tel ""
|
||||
fax ""
|
||||
language ""
|
||||
territory ""
|
||||
-revision "2.0"
|
||||
-date "2020-06-28"
|
||||
+revision "2.1"
|
||||
+date "2022-01-30"
|
||||
category "i18n:2012";LC_IDENTIFICATION
|
||||
category "i18n:2012";LC_CTYPE
|
||||
category "i18n:2012";LC_COLLATE
|
||||
@@ -68,11 +68,11 @@ LC_MONETARY
|
||||
% glibc/locale/C-monetary.c.).
|
||||
int_curr_symbol ""
|
||||
currency_symbol ""
|
||||
-mon_decimal_point "."
|
||||
+mon_decimal_point ""
|
||||
mon_thousands_sep ""
|
||||
mon_grouping -1
|
||||
positive_sign ""
|
||||
-negative_sign "-"
|
||||
+negative_sign ""
|
||||
int_frac_digits -1
|
||||
frac_digits -1
|
||||
p_cs_precedes -1
|
||||
@@ -121,7 +121,9 @@ mon "January";"February";"March";"April";"May";"June";"July";/
|
||||
%
|
||||
% ISO 8601 conforming applications should use the values 7, 19971201 (a
|
||||
% Monday), and 4 (Thursday), respectively.
|
||||
-week 7;19971201;4
|
||||
+%
|
||||
+% This field is consciously aligned with the builtin C/POSIX locale.
|
||||
+week 7;19971130;4
|
||||
first_weekday 1
|
||||
first_workday 2
|
||||
|
||||
@@ -129,7 +131,7 @@ first_workday 2
|
||||
d_t_fmt "%a %b %e %H:%M:%S %Y"
|
||||
|
||||
% Appropriate date representation (%x)
|
||||
-d_fmt "%m/%d/%y"
|
||||
+d_fmt "%m//%d//%y"
|
||||
|
||||
% Appropriate time representation (%X)
|
||||
t_fmt "%H:%M:%S"
|
||||
@@ -150,8 +152,8 @@ LC_MESSAGES
|
||||
%
|
||||
yesexpr "^[yY]"
|
||||
noexpr "^[nN]"
|
||||
-yesstr "Yes"
|
||||
-nostr "No"
|
||||
+yesstr ""
|
||||
+nostr ""
|
||||
END LC_MESSAGES
|
||||
|
||||
LC_PAPER
|
||||
@@ -175,6 +177,10 @@ LC_ADDRESS
|
||||
% the LC_ADDRESS category.
|
||||
% (also used in the built in C/POSIX locale in glibc/locale/C-address.c)
|
||||
postal_fmt "%a%N%f%N%d%N%b%N%s %h %e %r%N%C-%z %T%N%c%N"
|
||||
+% The abbreviated 2 char and 3 char should be set to empty strings to
|
||||
+% match the C/POSIX locale.
|
||||
+country_ab2 ""
|
||||
+country_ab3 ""
|
||||
END LC_ADDRESS
|
||||
|
||||
LC_TELEPHONE
|
||||
diff --git a/localedata/tst-c-utf8-consistency.c b/localedata/tst-c-utf8-consistency.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..50feed3090df0ff1
|
||||
--- /dev/null
|
||||
+++ b/localedata/tst-c-utf8-consistency.c
|
||||
@@ -0,0 +1,539 @@
|
||||
+/* Test that C/POSIX and C.UTF-8 are consistent.
|
||||
+ 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/>. */
|
||||
+
|
||||
+#include <langinfo.h>
|
||||
+#include <locale.h>
|
||||
+#include <stdbool.h>
|
||||
+#include <stdio.h>
|
||||
+#include <support/check.h>
|
||||
+
|
||||
+/* Initialized by do_test using newlocale. */
|
||||
+static locale_t c_utf8;
|
||||
+
|
||||
+/* Set to true for second pass. */
|
||||
+static bool use_nl_langinfo_l;
|
||||
+
|
||||
+static void
|
||||
+switch_to_c (void)
|
||||
+{
|
||||
+ if (setlocale (LC_ALL, "C") == NULL)
|
||||
+ FAIL_EXIT1 ("setlocale (LC_ALL, \"C\")");
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+switch_to_c_utf8 (void)
|
||||
+{
|
||||
+ if (setlocale (LC_ALL, "C.UTF-8") == NULL)
|
||||
+ FAIL_EXIT1 ("setlocale (LC_ALL, \"C.UTF-8\")");
|
||||
+}
|
||||
+
|
||||
+static char *
|
||||
+str (nl_item item)
|
||||
+{
|
||||
+ if (!use_nl_langinfo_l)
|
||||
+ switch_to_c ();
|
||||
+ return nl_langinfo (item);
|
||||
+}
|
||||
+
|
||||
+static char *
|
||||
+str_utf8 (nl_item item)
|
||||
+{
|
||||
+ if (use_nl_langinfo_l)
|
||||
+ return nl_langinfo_l (item, c_utf8);
|
||||
+ else
|
||||
+ {
|
||||
+ switch_to_c_utf8 ();
|
||||
+ return nl_langinfo (item);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static wchar_t *
|
||||
+wstr (nl_item item)
|
||||
+{
|
||||
+ return (wchar_t *) str (item);
|
||||
+}
|
||||
+
|
||||
+static wchar_t *
|
||||
+wstr_utf8 (nl_item item)
|
||||
+{
|
||||
+ return (wchar_t *) str_utf8 (item);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+byte (nl_item item)
|
||||
+{
|
||||
+ return (signed char) *str (item);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+byte_utf8 (nl_item item)
|
||||
+{
|
||||
+ return (signed char) *str_utf8 (item);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+word (nl_item item)
|
||||
+{
|
||||
+ union
|
||||
+ {
|
||||
+ char *ptr;
|
||||
+ int word;
|
||||
+ } u;
|
||||
+ u.ptr = str (item);
|
||||
+ return u.word;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+word_utf8 (nl_item item)
|
||||
+{
|
||||
+ union
|
||||
+ {
|
||||
+ char *ptr;
|
||||
+ int word;
|
||||
+ } u;
|
||||
+ u.ptr = str_utf8 (item);
|
||||
+ return u.word;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+one_pass (void)
|
||||
+{
|
||||
+ /* LC_TIME. */
|
||||
+ TEST_COMPARE_STRING (str (ABDAY_1), str_utf8 (ABDAY_1));
|
||||
+ TEST_COMPARE_STRING (str (ABDAY_2), str_utf8 (ABDAY_2));
|
||||
+ TEST_COMPARE_STRING (str (ABDAY_3), str_utf8 (ABDAY_3));
|
||||
+ TEST_COMPARE_STRING (str (ABDAY_4), str_utf8 (ABDAY_4));
|
||||
+ TEST_COMPARE_STRING (str (ABDAY_5), str_utf8 (ABDAY_5));
|
||||
+ TEST_COMPARE_STRING (str (ABDAY_6), str_utf8 (ABDAY_6));
|
||||
+ TEST_COMPARE_STRING (str (ABDAY_7), str_utf8 (ABDAY_7));
|
||||
+
|
||||
+ TEST_COMPARE_STRING (str (DAY_1), str_utf8 (DAY_1));
|
||||
+ TEST_COMPARE_STRING (str (DAY_2), str_utf8 (DAY_2));
|
||||
+ TEST_COMPARE_STRING (str (DAY_3), str_utf8 (DAY_3));
|
||||
+ TEST_COMPARE_STRING (str (DAY_4), str_utf8 (DAY_4));
|
||||
+ TEST_COMPARE_STRING (str (DAY_5), str_utf8 (DAY_5));
|
||||
+ TEST_COMPARE_STRING (str (DAY_6), str_utf8 (DAY_6));
|
||||
+ TEST_COMPARE_STRING (str (DAY_7), str_utf8 (DAY_7));
|
||||
+
|
||||
+ TEST_COMPARE_STRING (str (ABMON_1), str_utf8 (ABMON_1));
|
||||
+ TEST_COMPARE_STRING (str (ABMON_2), str_utf8 (ABMON_2));
|
||||
+ TEST_COMPARE_STRING (str (ABMON_3), str_utf8 (ABMON_3));
|
||||
+ TEST_COMPARE_STRING (str (ABMON_4), str_utf8 (ABMON_4));
|
||||
+ TEST_COMPARE_STRING (str (ABMON_5), str_utf8 (ABMON_5));
|
||||
+ TEST_COMPARE_STRING (str (ABMON_6), str_utf8 (ABMON_6));
|
||||
+ TEST_COMPARE_STRING (str (ABMON_7), str_utf8 (ABMON_7));
|
||||
+ TEST_COMPARE_STRING (str (ABMON_8), str_utf8 (ABMON_8));
|
||||
+ TEST_COMPARE_STRING (str (ABMON_9), str_utf8 (ABMON_9));
|
||||
+ TEST_COMPARE_STRING (str (ABMON_10), str_utf8 (ABMON_10));
|
||||
+ TEST_COMPARE_STRING (str (ABMON_11), str_utf8 (ABMON_11));
|
||||
+ TEST_COMPARE_STRING (str (ABMON_12), str_utf8 (ABMON_12));
|
||||
+
|
||||
+ TEST_COMPARE_STRING (str (MON_1), str_utf8 (MON_1));
|
||||
+ TEST_COMPARE_STRING (str (MON_2), str_utf8 (MON_2));
|
||||
+ TEST_COMPARE_STRING (str (MON_3), str_utf8 (MON_3));
|
||||
+ TEST_COMPARE_STRING (str (MON_4), str_utf8 (MON_4));
|
||||
+ TEST_COMPARE_STRING (str (MON_5), str_utf8 (MON_5));
|
||||
+ TEST_COMPARE_STRING (str (MON_6), str_utf8 (MON_6));
|
||||
+ TEST_COMPARE_STRING (str (MON_7), str_utf8 (MON_7));
|
||||
+ TEST_COMPARE_STRING (str (MON_8), str_utf8 (MON_8));
|
||||
+ TEST_COMPARE_STRING (str (MON_9), str_utf8 (MON_9));
|
||||
+ TEST_COMPARE_STRING (str (MON_10), str_utf8 (MON_10));
|
||||
+ TEST_COMPARE_STRING (str (MON_11), str_utf8 (MON_11));
|
||||
+ TEST_COMPARE_STRING (str (MON_12), str_utf8 (MON_12));
|
||||
+
|
||||
+ TEST_COMPARE_STRING (str (AM_STR), str_utf8 (AM_STR));
|
||||
+ TEST_COMPARE_STRING (str (PM_STR), str_utf8 (PM_STR));
|
||||
+
|
||||
+ TEST_COMPARE_STRING (str (D_T_FMT), str_utf8 (D_T_FMT));
|
||||
+ TEST_COMPARE_STRING (str (D_FMT), str_utf8 (D_FMT));
|
||||
+ TEST_COMPARE_STRING (str (T_FMT), str_utf8 (T_FMT));
|
||||
+ TEST_COMPARE_STRING (str (T_FMT_AMPM),
|
||||
+ str_utf8 (T_FMT_AMPM));
|
||||
+
|
||||
+ TEST_COMPARE_STRING (str (ERA), str_utf8 (ERA));
|
||||
+ TEST_COMPARE_STRING (str (ERA_YEAR), str_utf8 (ERA_YEAR));
|
||||
+ TEST_COMPARE_STRING (str (ERA_D_FMT), str_utf8 (ERA_D_FMT));
|
||||
+ TEST_COMPARE_STRING (str (ALT_DIGITS), str_utf8 (ALT_DIGITS));
|
||||
+ TEST_COMPARE_STRING (str (ERA_D_T_FMT), str_utf8 (ERA_D_T_FMT));
|
||||
+ TEST_COMPARE_STRING (str (ERA_T_FMT), str_utf8 (ERA_T_FMT));
|
||||
+ TEST_COMPARE (word (_NL_TIME_ERA_NUM_ENTRIES),
|
||||
+ word_utf8 (_NL_TIME_ERA_NUM_ENTRIES));
|
||||
+ /* No array elements, so nothing to compare for _NL_TIME_ERA_ENTRIES. */
|
||||
+ TEST_COMPARE (word (_NL_TIME_ERA_NUM_ENTRIES), 0);
|
||||
+
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABDAY_1), wstr_utf8 (_NL_WABDAY_1));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABDAY_2), wstr_utf8 (_NL_WABDAY_2));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABDAY_3), wstr_utf8 (_NL_WABDAY_3));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABDAY_4), wstr_utf8 (_NL_WABDAY_4));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABDAY_5), wstr_utf8 (_NL_WABDAY_5));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABDAY_6), wstr_utf8 (_NL_WABDAY_6));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABDAY_7), wstr_utf8 (_NL_WABDAY_7));
|
||||
+
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WDAY_1), wstr_utf8 (_NL_WDAY_1));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WDAY_2), wstr_utf8 (_NL_WDAY_2));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WDAY_3), wstr_utf8 (_NL_WDAY_3));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WDAY_4), wstr_utf8 (_NL_WDAY_4));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WDAY_5), wstr_utf8 (_NL_WDAY_5));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WDAY_6), wstr_utf8 (_NL_WDAY_6));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WDAY_7), wstr_utf8 (_NL_WDAY_7));
|
||||
+
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_1), wstr_utf8 (_NL_WABMON_1));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_2), wstr_utf8 (_NL_WABMON_2));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_3), wstr_utf8 (_NL_WABMON_3));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_4), wstr_utf8 (_NL_WABMON_4));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_5), wstr_utf8 (_NL_WABMON_5));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_6), wstr_utf8 (_NL_WABMON_6));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_7), wstr_utf8 (_NL_WABMON_7));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_8), wstr_utf8 (_NL_WABMON_8));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_9), wstr_utf8 (_NL_WABMON_9));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_10), wstr_utf8 (_NL_WABMON_10));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_11), wstr_utf8 (_NL_WABMON_11));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABMON_12), wstr_utf8 (_NL_WABMON_12));
|
||||
+
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_1), wstr_utf8 (_NL_WMON_1));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_2), wstr_utf8 (_NL_WMON_2));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_3), wstr_utf8 (_NL_WMON_3));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_4), wstr_utf8 (_NL_WMON_4));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_5), wstr_utf8 (_NL_WMON_5));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_6), wstr_utf8 (_NL_WMON_6));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_7), wstr_utf8 (_NL_WMON_7));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_8), wstr_utf8 (_NL_WMON_8));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_9), wstr_utf8 (_NL_WMON_9));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_10), wstr_utf8 (_NL_WMON_10));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_11), wstr_utf8 (_NL_WMON_11));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WMON_12), wstr_utf8 (_NL_WMON_12));
|
||||
+
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WAM_STR), wstr_utf8 (_NL_WAM_STR));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WPM_STR), wstr_utf8 (_NL_WPM_STR));
|
||||
+
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WD_T_FMT), wstr_utf8 (_NL_WD_T_FMT));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WD_FMT), wstr_utf8 (_NL_WD_FMT));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WT_FMT), wstr_utf8 (_NL_WT_FMT));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WT_FMT_AMPM),
|
||||
+ wstr_utf8 (_NL_WT_FMT_AMPM));
|
||||
+
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WERA_YEAR), wstr_utf8 (_NL_WERA_YEAR));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WERA_D_FMT), wstr_utf8 (_NL_WERA_D_FMT));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALT_DIGITS),
|
||||
+ wstr_utf8 (_NL_WALT_DIGITS));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WERA_D_T_FMT),
|
||||
+ wstr_utf8 (_NL_WERA_D_T_FMT));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WERA_T_FMT), wstr_utf8 (_NL_WERA_T_FMT));
|
||||
+
|
||||
+ /* This is somewhat inconsistent, but see locale/categories.def. */
|
||||
+ TEST_COMPARE (byte (_NL_TIME_WEEK_NDAYS), byte_utf8 (_NL_TIME_WEEK_NDAYS));
|
||||
+ TEST_COMPARE (word (_NL_TIME_WEEK_1STDAY),
|
||||
+ word_utf8 (_NL_TIME_WEEK_1STDAY));
|
||||
+ TEST_COMPARE (byte (_NL_TIME_WEEK_1STWEEK),
|
||||
+ byte_utf8 (_NL_TIME_WEEK_1STWEEK));
|
||||
+ TEST_COMPARE (byte (_NL_TIME_FIRST_WEEKDAY),
|
||||
+ byte_utf8 (_NL_TIME_FIRST_WEEKDAY));
|
||||
+ TEST_COMPARE (byte (_NL_TIME_FIRST_WORKDAY),
|
||||
+ byte_utf8 (_NL_TIME_FIRST_WORKDAY));
|
||||
+ TEST_COMPARE (byte (_NL_TIME_CAL_DIRECTION),
|
||||
+ byte_utf8 (_NL_TIME_CAL_DIRECTION));
|
||||
+ TEST_COMPARE_STRING (str (_NL_TIME_TIMEZONE), str_utf8 (_NL_TIME_TIMEZONE));
|
||||
+
|
||||
+ TEST_COMPARE_STRING (str (_DATE_FMT), str_utf8 (_DATE_FMT));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_W_DATE_FMT), wstr_utf8 (_NL_W_DATE_FMT));
|
||||
+
|
||||
+ /* Expected difference. */
|
||||
+ TEST_COMPARE_STRING (str (_NL_TIME_CODESET), "ANSI_X3.4-1968");
|
||||
+ TEST_COMPARE_STRING (str_utf8 (_NL_TIME_CODESET), "UTF-8");
|
||||
+
|
||||
+ TEST_COMPARE_STRING (str (ALTMON_1), str_utf8 (ALTMON_1));
|
||||
+ TEST_COMPARE_STRING (str (ALTMON_2), str_utf8 (ALTMON_2));
|
||||
+ TEST_COMPARE_STRING (str (ALTMON_3), str_utf8 (ALTMON_3));
|
||||
+ TEST_COMPARE_STRING (str (ALTMON_4), str_utf8 (ALTMON_4));
|
||||
+ TEST_COMPARE_STRING (str (ALTMON_5), str_utf8 (ALTMON_5));
|
||||
+ TEST_COMPARE_STRING (str (ALTMON_6), str_utf8 (ALTMON_6));
|
||||
+ TEST_COMPARE_STRING (str (ALTMON_7), str_utf8 (ALTMON_7));
|
||||
+ TEST_COMPARE_STRING (str (ALTMON_8), str_utf8 (ALTMON_8));
|
||||
+ TEST_COMPARE_STRING (str (ALTMON_9), str_utf8 (ALTMON_9));
|
||||
+ TEST_COMPARE_STRING (str (ALTMON_10), str_utf8 (ALTMON_10));
|
||||
+ TEST_COMPARE_STRING (str (ALTMON_11), str_utf8 (ALTMON_11));
|
||||
+ TEST_COMPARE_STRING (str (ALTMON_12), str_utf8 (ALTMON_12));
|
||||
+
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_1), wstr_utf8 (_NL_WALTMON_1));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_2), wstr_utf8 (_NL_WALTMON_2));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_3), wstr_utf8 (_NL_WALTMON_3));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_4), wstr_utf8 (_NL_WALTMON_4));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_5), wstr_utf8 (_NL_WALTMON_5));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_6), wstr_utf8 (_NL_WALTMON_6));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_7), wstr_utf8 (_NL_WALTMON_7));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_8), wstr_utf8 (_NL_WALTMON_8));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_9), wstr_utf8 (_NL_WALTMON_9));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_10), wstr_utf8 (_NL_WALTMON_10));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_11), wstr_utf8 (_NL_WALTMON_11));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WALTMON_12), wstr_utf8 (_NL_WALTMON_12));
|
||||
+
|
||||
+ TEST_COMPARE_STRING (str (_NL_ABALTMON_1), str_utf8 (_NL_ABALTMON_1));
|
||||
+ TEST_COMPARE_STRING (str (_NL_ABALTMON_2), str_utf8 (_NL_ABALTMON_2));
|
||||
+ TEST_COMPARE_STRING (str (_NL_ABALTMON_3), str_utf8 (_NL_ABALTMON_3));
|
||||
+ TEST_COMPARE_STRING (str (_NL_ABALTMON_4), str_utf8 (_NL_ABALTMON_4));
|
||||
+ TEST_COMPARE_STRING (str (_NL_ABALTMON_5), str_utf8 (_NL_ABALTMON_5));
|
||||
+ TEST_COMPARE_STRING (str (_NL_ABALTMON_6), str_utf8 (_NL_ABALTMON_6));
|
||||
+ TEST_COMPARE_STRING (str (_NL_ABALTMON_7), str_utf8 (_NL_ABALTMON_7));
|
||||
+ TEST_COMPARE_STRING (str (_NL_ABALTMON_8), str_utf8 (_NL_ABALTMON_8));
|
||||
+ TEST_COMPARE_STRING (str (_NL_ABALTMON_9), str_utf8 (_NL_ABALTMON_9));
|
||||
+ TEST_COMPARE_STRING (str (_NL_ABALTMON_10), str_utf8 (_NL_ABALTMON_10));
|
||||
+ TEST_COMPARE_STRING (str (_NL_ABALTMON_11), str_utf8 (_NL_ABALTMON_11));
|
||||
+ TEST_COMPARE_STRING (str (_NL_ABALTMON_12), str_utf8 (_NL_ABALTMON_12));
|
||||
+
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_1),
|
||||
+ wstr_utf8 (_NL_WABALTMON_1));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_2),
|
||||
+ wstr_utf8 (_NL_WABALTMON_2));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_3),
|
||||
+ wstr_utf8 (_NL_WABALTMON_3));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_4),
|
||||
+ wstr_utf8 (_NL_WABALTMON_4));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_5),
|
||||
+ wstr_utf8 (_NL_WABALTMON_5));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_6),
|
||||
+ wstr_utf8 (_NL_WABALTMON_6));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_7),
|
||||
+ wstr_utf8 (_NL_WABALTMON_7));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_8),
|
||||
+ wstr_utf8 (_NL_WABALTMON_8));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_9),
|
||||
+ wstr_utf8 (_NL_WABALTMON_9));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_10),
|
||||
+ wstr_utf8 (_NL_WABALTMON_10));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_11),
|
||||
+ wstr_utf8 (_NL_WABALTMON_11));
|
||||
+ TEST_COMPARE_STRING_WIDE (wstr (_NL_WABALTMON_12),
|
||||
+ wstr_utf8 (_NL_WABALTMON_12));
|
||||
+
|
||||
+ /* LC_COLLATE. Mostly untested, only expected differences. */
|
||||
+ TEST_COMPARE_STRING (str (_NL_COLLATE_CODESET), "ANSI_X3.4-1968");
|
||||
+ TEST_COMPARE_STRING (str_utf8 (_NL_COLLATE_CODESET), "UTF-8");
|
||||
+
|
||||
+ /* LC_CTYPE. Mostly untested, only expected differences. */
|
||||
+ TEST_COMPARE_STRING (str (CODESET), "ANSI_X3.4-1968");
|
||||
+ TEST_COMPARE_STRING (str_utf8 (CODESET), "UTF-8");
|
||||
+
|
||||
+ /* LC_MONETARY. */
|
||||
+ TEST_COMPARE_STRING (str (INT_CURR_SYMBOL), str_utf8 (INT_CURR_SYMBOL));
|
||||
+ TEST_COMPARE_STRING (str (CURRENCY_SYMBOL), str_utf8 (CURRENCY_SYMBOL));
|
||||
+ TEST_COMPARE_STRING (str (MON_DECIMAL_POINT), str_utf8 (MON_DECIMAL_POINT));
|
||||
+ TEST_COMPARE_STRING (str (MON_THOUSANDS_SEP), str_utf8 (MON_THOUSANDS_SEP));
|
||||
+ TEST_COMPARE_STRING (str (MON_GROUPING), str_utf8 (MON_GROUPING));
|
||||
+ TEST_COMPARE_STRING (str (POSITIVE_SIGN), str_utf8 (POSITIVE_SIGN));
|
||||
+ TEST_COMPARE_STRING (str (NEGATIVE_SIGN), str_utf8 (NEGATIVE_SIGN));
|
||||
+ TEST_COMPARE (byte (INT_FRAC_DIGITS), byte_utf8 (INT_FRAC_DIGITS));
|
||||
+ TEST_COMPARE (byte (FRAC_DIGITS), byte_utf8 (FRAC_DIGITS));
|
||||
+ TEST_COMPARE (byte (P_CS_PRECEDES), byte_utf8 (P_CS_PRECEDES));
|
||||
+ TEST_COMPARE (byte (P_SEP_BY_SPACE), byte_utf8 (P_SEP_BY_SPACE));
|
||||
+ TEST_COMPARE (byte (N_CS_PRECEDES), byte_utf8 (N_CS_PRECEDES));
|
||||
+ TEST_COMPARE (byte (N_SEP_BY_SPACE), byte_utf8 (N_SEP_BY_SPACE));
|
||||
+ TEST_COMPARE (byte (P_SIGN_POSN), byte_utf8 (P_SIGN_POSN));
|
||||
+ TEST_COMPARE (byte (N_SIGN_POSN), byte_utf8 (N_SIGN_POSN));
|
||||
+ TEST_COMPARE_STRING (str (CRNCYSTR), str_utf8 (CRNCYSTR));
|
||||
+ TEST_COMPARE (byte (INT_P_CS_PRECEDES), byte_utf8 (INT_P_CS_PRECEDES));
|
||||
+ TEST_COMPARE (byte (INT_P_SEP_BY_SPACE), byte_utf8 (INT_P_SEP_BY_SPACE));
|
||||
+ TEST_COMPARE (byte (INT_N_CS_PRECEDES), byte_utf8 (INT_N_CS_PRECEDES));
|
||||
+ TEST_COMPARE (byte (INT_N_SEP_BY_SPACE), byte_utf8 (INT_N_SEP_BY_SPACE));
|
||||
+ TEST_COMPARE (byte (INT_P_SIGN_POSN), byte_utf8 (INT_P_SIGN_POSN));
|
||||
+ TEST_COMPARE (byte (INT_N_SIGN_POSN), byte_utf8 (INT_N_SIGN_POSN));
|
||||
+ TEST_COMPARE_STRING (str (_NL_MONETARY_DUO_INT_CURR_SYMBOL),
|
||||
+ str_utf8 (_NL_MONETARY_DUO_INT_CURR_SYMBOL));
|
||||
+ TEST_COMPARE_STRING (str (_NL_MONETARY_DUO_CURRENCY_SYMBOL),
|
||||
+ str_utf8 (_NL_MONETARY_DUO_CURRENCY_SYMBOL));
|
||||
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_INT_FRAC_DIGITS),
|
||||
+ byte_utf8 (_NL_MONETARY_DUO_INT_FRAC_DIGITS));
|
||||
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_FRAC_DIGITS),
|
||||
+ byte_utf8 (_NL_MONETARY_DUO_FRAC_DIGITS));
|
||||
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_P_CS_PRECEDES),
|
||||
+ byte_utf8 (_NL_MONETARY_DUO_P_CS_PRECEDES));
|
||||
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_P_SEP_BY_SPACE),
|
||||
+ byte_utf8 (_NL_MONETARY_DUO_P_SEP_BY_SPACE));
|
||||
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_N_CS_PRECEDES),
|
||||
+ byte_utf8 (_NL_MONETARY_DUO_N_CS_PRECEDES));
|
||||
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_N_SEP_BY_SPACE),
|
||||
+ byte_utf8 (_NL_MONETARY_DUO_N_SEP_BY_SPACE));
|
||||
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_INT_P_CS_PRECEDES),
|
||||
+ byte_utf8 (_NL_MONETARY_DUO_INT_P_CS_PRECEDES));
|
||||
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_INT_P_SEP_BY_SPACE),
|
||||
+ byte_utf8 (_NL_MONETARY_DUO_INT_P_SEP_BY_SPACE));
|
||||
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_INT_N_CS_PRECEDES),
|
||||
+ byte_utf8 (_NL_MONETARY_DUO_INT_N_CS_PRECEDES));
|
||||
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_INT_N_SEP_BY_SPACE),
|
||||
+ byte_utf8 (_NL_MONETARY_DUO_INT_N_SEP_BY_SPACE));
|
||||
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_INT_P_SIGN_POSN),
|
||||
+ byte_utf8 (_NL_MONETARY_DUO_INT_P_SIGN_POSN));
|
||||
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_INT_N_SIGN_POSN),
|
||||
+ byte_utf8 (_NL_MONETARY_DUO_INT_N_SIGN_POSN));
|
||||
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_P_SIGN_POSN),
|
||||
+ byte_utf8 (_NL_MONETARY_DUO_P_SIGN_POSN));
|
||||
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_N_SIGN_POSN),
|
||||
+ byte_utf8 (_NL_MONETARY_DUO_N_SIGN_POSN));
|
||||
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_INT_P_SIGN_POSN),
|
||||
+ byte_utf8 (_NL_MONETARY_DUO_INT_P_SIGN_POSN));
|
||||
+ TEST_COMPARE (byte (_NL_MONETARY_DUO_INT_N_SIGN_POSN),
|
||||
+ byte_utf8 (_NL_MONETARY_DUO_INT_N_SIGN_POSN));
|
||||
+ TEST_COMPARE (word (_NL_MONETARY_UNO_VALID_FROM),
|
||||
+ word_utf8 (_NL_MONETARY_UNO_VALID_FROM));
|
||||
+ TEST_COMPARE (word (_NL_MONETARY_UNO_VALID_TO),
|
||||
+ word_utf8 (_NL_MONETARY_UNO_VALID_TO));
|
||||
+ TEST_COMPARE (word (_NL_MONETARY_DUO_VALID_FROM),
|
||||
+ word_utf8 (_NL_MONETARY_DUO_VALID_FROM));
|
||||
+ TEST_COMPARE (word (_NL_MONETARY_DUO_VALID_TO),
|
||||
+ word_utf8 (_NL_MONETARY_DUO_VALID_TO));
|
||||
+ /* _NL_MONETARY_CONVERSION_RATE cannot be tested (word array). */
|
||||
+ TEST_COMPARE (word (_NL_MONETARY_DECIMAL_POINT_WC),
|
||||
+ word_utf8 (_NL_MONETARY_DECIMAL_POINT_WC));
|
||||
+ TEST_COMPARE (word (_NL_MONETARY_THOUSANDS_SEP_WC),
|
||||
+ word_utf8 (_NL_MONETARY_THOUSANDS_SEP_WC));
|
||||
+ /* Expected difference. */
|
||||
+ TEST_COMPARE_STRING (str (_NL_MONETARY_CODESET), "ANSI_X3.4-1968");
|
||||
+ TEST_COMPARE_STRING (str_utf8 (_NL_MONETARY_CODESET), "UTF-8");
|
||||
+
|
||||
+ /* LC_NUMERIC. */
|
||||
+
|
||||
+ TEST_COMPARE_STRING (str (DECIMAL_POINT), str_utf8 (DECIMAL_POINT));
|
||||
+ TEST_COMPARE_STRING (str (RADIXCHAR), str_utf8 (RADIXCHAR));
|
||||
+ TEST_COMPARE_STRING (str (THOUSANDS_SEP), str_utf8 (THOUSANDS_SEP));
|
||||
+ TEST_COMPARE_STRING (str (THOUSEP), str_utf8 (THOUSEP));
|
||||
+ TEST_COMPARE_STRING (str (GROUPING), str_utf8 (GROUPING));
|
||||
+ TEST_COMPARE (word (_NL_NUMERIC_DECIMAL_POINT_WC),
|
||||
+ word_utf8 (_NL_NUMERIC_DECIMAL_POINT_WC));
|
||||
+ TEST_COMPARE (word (_NL_NUMERIC_THOUSANDS_SEP_WC),
|
||||
+ word_utf8 (_NL_NUMERIC_THOUSANDS_SEP_WC));
|
||||
+ /* Expected difference. */
|
||||
+ TEST_COMPARE_STRING (str (_NL_NUMERIC_CODESET), "ANSI_X3.4-1968");
|
||||
+ TEST_COMPARE_STRING (str_utf8 (_NL_NUMERIC_CODESET), "UTF-8");
|
||||
+
|
||||
+ /* LC_MESSAGES. */
|
||||
+
|
||||
+ TEST_COMPARE_STRING (str (YESEXPR), str_utf8 (YESEXPR));
|
||||
+ TEST_COMPARE_STRING (str (NOEXPR), str_utf8 (NOEXPR));
|
||||
+ TEST_COMPARE_STRING (str (YESSTR), str_utf8 (YESSTR));
|
||||
+ TEST_COMPARE_STRING (str (NOSTR), str_utf8 (NOSTR));
|
||||
+ /* Expected difference. */
|
||||
+ TEST_COMPARE_STRING (str (_NL_MESSAGES_CODESET), "ANSI_X3.4-1968");
|
||||
+ TEST_COMPARE_STRING (str_utf8 (_NL_MESSAGES_CODESET), "UTF-8");
|
||||
+
|
||||
+ /* LC_PAPER. */
|
||||
+
|
||||
+ TEST_COMPARE (word (_NL_PAPER_HEIGHT), word_utf8 (_NL_PAPER_HEIGHT));
|
||||
+ TEST_COMPARE (word (_NL_PAPER_WIDTH), word_utf8 (_NL_PAPER_WIDTH));
|
||||
+ /* Expected difference. */
|
||||
+ TEST_COMPARE_STRING (str (_NL_PAPER_CODESET), "ANSI_X3.4-1968");
|
||||
+ TEST_COMPARE_STRING (str_utf8 (_NL_PAPER_CODESET), "UTF-8");
|
||||
+
|
||||
+ /* LC_NAME. */
|
||||
+
|
||||
+ TEST_COMPARE_STRING (str (_NL_NAME_NAME_FMT),
|
||||
+ str_utf8 (_NL_NAME_NAME_FMT));
|
||||
+ TEST_COMPARE_STRING (str (_NL_NAME_NAME_GEN),
|
||||
+ str_utf8 (_NL_NAME_NAME_GEN));
|
||||
+ TEST_COMPARE_STRING (str (_NL_NAME_NAME_MR),
|
||||
+ str_utf8 (_NL_NAME_NAME_MR));
|
||||
+ TEST_COMPARE_STRING (str (_NL_NAME_NAME_MRS),
|
||||
+ str_utf8 (_NL_NAME_NAME_MRS));
|
||||
+ TEST_COMPARE_STRING (str (_NL_NAME_NAME_MISS),
|
||||
+ str_utf8 (_NL_NAME_NAME_MISS));
|
||||
+ TEST_COMPARE_STRING (str (_NL_NAME_NAME_MS),
|
||||
+ str_utf8 (_NL_NAME_NAME_MS));
|
||||
+ /* Expected difference. */
|
||||
+ TEST_COMPARE_STRING (str (_NL_NAME_CODESET), "ANSI_X3.4-1968");
|
||||
+ TEST_COMPARE_STRING (str_utf8 (_NL_NAME_CODESET), "UTF-8");
|
||||
+
|
||||
+ /* LC_ADDRESS. */
|
||||
+
|
||||
+ TEST_COMPARE_STRING (str (_NL_ADDRESS_POSTAL_FMT),
|
||||
+ str_utf8 (_NL_ADDRESS_POSTAL_FMT));
|
||||
+ TEST_COMPARE_STRING (str (_NL_ADDRESS_COUNTRY_NAME),
|
||||
+ str_utf8 (_NL_ADDRESS_COUNTRY_NAME));
|
||||
+ TEST_COMPARE_STRING (str (_NL_ADDRESS_COUNTRY_POST),
|
||||
+ str_utf8 (_NL_ADDRESS_COUNTRY_POST));
|
||||
+ TEST_COMPARE_STRING (str (_NL_ADDRESS_COUNTRY_AB2),
|
||||
+ str_utf8 (_NL_ADDRESS_COUNTRY_AB2));
|
||||
+ TEST_COMPARE_STRING (str (_NL_ADDRESS_COUNTRY_AB3),
|
||||
+ str_utf8 (_NL_ADDRESS_COUNTRY_AB3));
|
||||
+ TEST_COMPARE_STRING (str (_NL_ADDRESS_COUNTRY_CAR),
|
||||
+ str_utf8 (_NL_ADDRESS_COUNTRY_CAR));
|
||||
+ TEST_COMPARE (word (_NL_ADDRESS_COUNTRY_NUM),
|
||||
+ word_utf8 (_NL_ADDRESS_COUNTRY_NUM));
|
||||
+ TEST_COMPARE_STRING (str (_NL_ADDRESS_COUNTRY_ISBN),
|
||||
+ str_utf8 (_NL_ADDRESS_COUNTRY_ISBN));
|
||||
+ TEST_COMPARE_STRING (str (_NL_ADDRESS_LANG_NAME),
|
||||
+ str_utf8 (_NL_ADDRESS_LANG_NAME));
|
||||
+ TEST_COMPARE_STRING (str (_NL_ADDRESS_LANG_AB),
|
||||
+ str_utf8 (_NL_ADDRESS_LANG_AB));
|
||||
+ TEST_COMPARE_STRING (str (_NL_ADDRESS_LANG_TERM),
|
||||
+ str_utf8 (_NL_ADDRESS_LANG_TERM));
|
||||
+ TEST_COMPARE_STRING (str (_NL_ADDRESS_LANG_LIB),
|
||||
+ str_utf8 (_NL_ADDRESS_LANG_LIB));
|
||||
+ /* Expected difference. */
|
||||
+ TEST_COMPARE_STRING (str (_NL_ADDRESS_CODESET), "ANSI_X3.4-1968");
|
||||
+ TEST_COMPARE_STRING (str_utf8 (_NL_ADDRESS_CODESET), "UTF-8");
|
||||
+
|
||||
+ /* LC_TELEPHONE. */
|
||||
+
|
||||
+ TEST_COMPARE_STRING (str (_NL_TELEPHONE_TEL_INT_FMT),
|
||||
+ str_utf8 (_NL_TELEPHONE_TEL_INT_FMT));
|
||||
+ TEST_COMPARE_STRING (str (_NL_TELEPHONE_TEL_DOM_FMT),
|
||||
+ str_utf8 (_NL_TELEPHONE_TEL_DOM_FMT));
|
||||
+ TEST_COMPARE_STRING (str (_NL_TELEPHONE_INT_SELECT),
|
||||
+ str_utf8 (_NL_TELEPHONE_INT_SELECT));
|
||||
+ TEST_COMPARE_STRING (str (_NL_TELEPHONE_INT_PREFIX),
|
||||
+ str_utf8 (_NL_TELEPHONE_INT_PREFIX));
|
||||
+ /* Expected difference. */
|
||||
+ TEST_COMPARE_STRING (str (_NL_TELEPHONE_CODESET), "ANSI_X3.4-1968");
|
||||
+ TEST_COMPARE_STRING (str_utf8 (_NL_TELEPHONE_CODESET), "UTF-8");
|
||||
+
|
||||
+ /* LC_MEASUREMENT. */
|
||||
+
|
||||
+ TEST_COMPARE (byte (_NL_MEASUREMENT_MEASUREMENT),
|
||||
+ byte_utf8 (_NL_MEASUREMENT_MEASUREMENT));
|
||||
+ /* Expected difference. */
|
||||
+ TEST_COMPARE_STRING (str (_NL_MEASUREMENT_CODESET), "ANSI_X3.4-1968");
|
||||
+ TEST_COMPARE_STRING (str_utf8 (_NL_MEASUREMENT_CODESET), "UTF-8");
|
||||
+
|
||||
+ /* LC_IDENTIFICATION is skipped since C.UTF-8 is distinct from C. */
|
||||
+
|
||||
+ /* _NL_IDENTIFICATION_CATEGORY cannot be tested because it is a
|
||||
+ string array. */
|
||||
+ /* Expected difference. */
|
||||
+ TEST_COMPARE_STRING (str (_NL_IDENTIFICATION_CODESET), "ANSI_X3.4-1968");
|
||||
+ TEST_COMPARE_STRING (str_utf8 (_NL_IDENTIFICATION_CODESET), "UTF-8");
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ puts ("info: using setlocale and nl_langinfo");
|
||||
+ one_pass ();
|
||||
+
|
||||
+ puts ("info: using nl_langinfo_l");
|
||||
+
|
||||
+ c_utf8 = newlocale (LC_ALL_MASK, "C.UTF-8", (locale_t) 0);
|
||||
+ TEST_VERIFY_EXIT (c_utf8 != (locale_t) 0);
|
||||
+
|
||||
+ switch_to_c ();
|
||||
+ use_nl_langinfo_l = true;
|
||||
+ one_pass ();
|
||||
+
|
||||
+ freelocale (c_utf8);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
@ -0,0 +1,44 @@
|
||||
Short description: Adjust CS_PATH and the test container layout.
|
||||
Author(s): Fedora glibc team <glibc@lists.fedoraproject.org>
|
||||
Origin: PATCH
|
||||
Upstream status: not-needed
|
||||
|
||||
In Fedora we should return only /usr/bin as CS_PATH because /bin is just
|
||||
a symlink to /usr/bin after MoveToUsr transition (which glibc has not
|
||||
really completed).
|
||||
|
||||
We also create /{bin,lib,lib64,sbin} in the test container as symbolic
|
||||
links. This brings the test container in line with Fedora's filesystem
|
||||
layout and avoids some test failures. For example, because Fedora's
|
||||
CS_PATH is /usr/bin, tst-vfork3 will try to execute /usr/bin/echo in the
|
||||
container. Without this change the container installs `echo' in /bin
|
||||
not /usr/bin, causing the test to fail.
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index a49870d3d1e636a9..feb2599203b10098 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -598,9 +598,13 @@ $(tests-container) $(addsuffix /tests,$(subdirs)) : \
|
||||
$(objpfx)testroot.pristine/install.stamp :
|
||||
test -d $(objpfx)testroot.pristine || \
|
||||
mkdir $(objpfx)testroot.pristine
|
||||
- # We need a working /bin/sh for some of the tests.
|
||||
- test -d $(objpfx)testroot.pristine/bin || \
|
||||
- mkdir $(objpfx)testroot.pristine/bin
|
||||
+ # Set up symlinks to directories whose contents got moved to /usr
|
||||
+ for moved in bin lib lib64 sbin; do \
|
||||
+ test -d $(objpfx)testroot.pristine/usr/$$moved || \
|
||||
+ mkdir -p $(objpfx)testroot.pristine/usr/$$moved ;\
|
||||
+ test -e $(objpfx)testroot.pristine/$$moved || \
|
||||
+ ln -s usr/$$moved $(objpfx)testroot.pristine/$$moved ;\
|
||||
+ done
|
||||
# We need the compiled locale dir for localedef tests.
|
||||
test -d $(objpfx)testroot.pristine/$(complocaledir) || \
|
||||
mkdir -p $(objpfx)testroot.pristine/$(complocaledir)
|
||||
diff --git a/sysdeps/unix/confstr.h b/sysdeps/unix/confstr.h
|
||||
index 15859c3b2759878e..9b63b7f8069866fd 100644
|
||||
--- a/sysdeps/unix/confstr.h
|
||||
+++ b/sysdeps/unix/confstr.h
|
||||
@@ -1 +1 @@
|
||||
-#define CS_PATH "/bin:/usr/bin"
|
||||
+#define CS_PATH "/usr/bin"
|
@ -0,0 +1,20 @@
|
||||
This is necessary to get things building again after libselinux changes.
|
||||
A proper fix is under discussion upstream:
|
||||
|
||||
<https://sourceware.org/pipermail/libc-alpha/2020-July/116504.html>
|
||||
|
||||
diff --git a/nss/makedb.c b/nss/makedb.c
|
||||
index 8e389a1683747cf1..9d81aed57d384a22 100644
|
||||
--- a/nss/makedb.c
|
||||
+++ b/nss/makedb.c
|
||||
@@ -17,6 +17,10 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
+/* This file uses deprecated declarations from libselinux. */
|
||||
+#include <libc-diag.h>
|
||||
+DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wdeprecated-declarations");
|
||||
+
|
||||
#include <argp.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
@ -0,0 +1,17 @@
|
||||
This patch works around deprecated libselinux features used by nscd.
|
||||
|
||||
diff --git a/nscd/selinux.c b/nscd/selinux.c
|
||||
index a4ea8008e201b939..0acca4639202a75a 100644
|
||||
--- a/nscd/selinux.c
|
||||
+++ b/nscd/selinux.c
|
||||
@@ -17,6 +17,10 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
+/* This file uses deprecated declarations from libselinux. */
|
||||
+#include <libc-diag.h>
|
||||
+DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wdeprecated-declarations");
|
||||
+
|
||||
#include "config.h"
|
||||
#include <error.h>
|
||||
#include <errno.h>
|
@ -0,0 +1,61 @@
|
||||
Short description: Fedora-specific workaround for kernel pty bug.
|
||||
Author(s): Fedora glibc team <glibc@lists.fedoraproject.org>
|
||||
Origin: PATCH
|
||||
Upstream status: not-submitted
|
||||
|
||||
This is a Fedora-specific workaround for a kernel bug where calling
|
||||
ioctl on a pty will silently ignore the invalid c_cflag. The
|
||||
workaround is to use TCGETS to verify the setting matches. This is
|
||||
not upstream and needs to either be removed or submitted upstream
|
||||
after analysis.
|
||||
|
||||
Index: b/sysdeps/unix/sysv/linux/tcsetattr.c
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/tcsetattr.c
|
||||
+++ b/sysdeps/unix/sysv/linux/tcsetattr.c
|
||||
@@ -45,6 +45,7 @@ __tcsetattr (int fd, int optional_action
|
||||
{
|
||||
struct __kernel_termios k_termios;
|
||||
unsigned long int cmd;
|
||||
+ int retval;
|
||||
|
||||
switch (optional_actions)
|
||||
{
|
||||
@@ -75,7 +76,36 @@ __tcsetattr (int fd, int optional_action
|
||||
memcpy (&k_termios.c_cc[0], &termios_p->c_cc[0],
|
||||
__KERNEL_NCCS * sizeof (cc_t));
|
||||
|
||||
- return INLINE_SYSCALL (ioctl, 3, fd, cmd, &k_termios);
|
||||
+ retval = INLINE_SYSCALL (ioctl, 3, fd, cmd, &k_termios);
|
||||
+
|
||||
+ if (retval == 0 && cmd == TCSETS)
|
||||
+ {
|
||||
+ /* The Linux kernel has a bug which silently ignore the invalid
|
||||
+ c_cflag on pty. We have to check it here. */
|
||||
+ int save = errno;
|
||||
+ retval = INLINE_SYSCALL (ioctl, 3, fd, TCGETS, &k_termios);
|
||||
+ if (retval)
|
||||
+ {
|
||||
+ /* We cannot verify if the setting is ok. We don't return
|
||||
+ an error (?). */
|
||||
+ __set_errno (save);
|
||||
+ retval = 0;
|
||||
+ }
|
||||
+ else if ((termios_p->c_cflag & (PARENB | CREAD))
|
||||
+ != (k_termios.c_cflag & (PARENB | CREAD))
|
||||
+ || ((termios_p->c_cflag & CSIZE)
|
||||
+ && ((termios_p->c_cflag & CSIZE)
|
||||
+ != (k_termios.c_cflag & CSIZE))))
|
||||
+ {
|
||||
+ /* It looks like the Linux kernel silently changed the
|
||||
+ PARENB/CREAD/CSIZE bits in c_cflag. Report it as an
|
||||
+ error. */
|
||||
+ __set_errno (EINVAL);
|
||||
+ retval = -1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return retval;
|
||||
}
|
||||
weak_alias (__tcsetattr, tcsetattr)
|
||||
libc_hidden_def (tcsetattr)
|
@ -0,0 +1,49 @@
|
||||
Short description: Add 4 ISO-8859-15 locales to SUPPORTED for Euro symbol.
|
||||
Author(s): Fedora glibc team <glibc@lists.fedoraproject.org>
|
||||
Origin: PATCH
|
||||
Bug-RHEL: #61908
|
||||
Upstream status: not-needed
|
||||
|
||||
Very early RHL 7.3 requirement to add these locales so users can
|
||||
get access to Euro symbol. We should review this bug and decide if
|
||||
the UTF-8 locales are now serving the same purpose and drop the
|
||||
additional locales.
|
||||
|
||||
* Tue Mar 26 2002 Jakub Jelinek <jakub@redhat.com> 2.2.5-28
|
||||
- add a couple of .ISO-8859-15 locales (#61908)
|
||||
|
||||
diff -Nrup a/localedata/SUPPORTED b/localedata/SUPPORTED
|
||||
--- a/localedata/SUPPORTED 2012-11-25 12:59:31.000000000 -0700
|
||||
+++ b/localedata/SUPPORTED 2012-11-26 12:58:43.298223018 -0700
|
||||
@@ -89,6 +89,7 @@ cy_GB.UTF-8/UTF-8 \
|
||||
cy_GB/ISO-8859-14 \
|
||||
da_DK.UTF-8/UTF-8 \
|
||||
da_DK/ISO-8859-1 \
|
||||
+da_DK.ISO-8859-15/ISO-8859-15 \
|
||||
de_AT.UTF-8/UTF-8 \
|
||||
de_AT/ISO-8859-1 \
|
||||
de_AT@euro/ISO-8859-15 \
|
||||
@@ -121,6 +122,7 @@ en_DK.UTF-8/UTF-8 \
|
||||
en_DK/ISO-8859-1 \
|
||||
en_GB.UTF-8/UTF-8 \
|
||||
en_GB/ISO-8859-1 \
|
||||
+en_GB.ISO-8859-15/ISO-8859-15 \
|
||||
en_HK.UTF-8/UTF-8 \
|
||||
en_HK/ISO-8859-1 \
|
||||
en_IE.UTF-8/UTF-8 \
|
||||
@@ -136,6 +138,7 @@ en_SG.UTF-8/UTF-8 \
|
||||
en_SG/ISO-8859-1 \
|
||||
en_US.UTF-8/UTF-8 \
|
||||
en_US/ISO-8859-1 \
|
||||
+en_US.ISO-8859-15/ISO-8859-15 \
|
||||
en_ZA.UTF-8/UTF-8 \
|
||||
en_ZA/ISO-8859-1 \
|
||||
en_ZM/UTF-8 \
|
||||
@@ -385,6 +388,7 @@ sv_FI/ISO-8859-1 \
|
||||
sv_FI@euro/ISO-8859-15 \
|
||||
sv_SE.UTF-8/UTF-8 \
|
||||
sv_SE/ISO-8859-1 \
|
||||
+sv_SE.ISO-8859-15/ISO-8859-15 \
|
||||
sw_KE/UTF-8 \
|
||||
sw_TZ/UTF-8 \
|
||||
szl_PL/UTF-8 \
|
@ -0,0 +1,31 @@
|
||||
Short description: Place glibc info into "Libraries" category.
|
||||
Author(s): Fedora glibc team <glibc@lists.fedoraproject.org>
|
||||
Origin: PATCH
|
||||
Upstream status: not-needed
|
||||
|
||||
The category names for libraries is completely random including
|
||||
"Libraries", "GNU Libraries", "GNU libraries", and "Software libraries."
|
||||
In the GNU info manual the "Software libraries" category is given as an
|
||||
example, but really we need to standardize on a category for upstream.
|
||||
I suggest we drop this change after some upstream discussion.
|
||||
|
||||
From 4820b9175535e13df79ce816106016040014916e Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Jelinek <jakub@redhat.com>
|
||||
Date: Fri, 3 Nov 2006 16:31:21 +0000
|
||||
Subject: [PATCH] Change @dircategory.
|
||||
|
||||
---
|
||||
manual/libc.texinfo | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
--- a/manual/libc.texinfo
|
||||
+++ b/manual/libc.texinfo
|
||||
@@ -7,7 +7,7 @@
|
||||
@include macros.texi
|
||||
|
||||
@comment Tell install-info what to do.
|
||||
-@dircategory Software libraries
|
||||
+@dircategory Libraries
|
||||
@direntry
|
||||
* Libc: (libc). C library.
|
||||
@end direntry
|
@ -0,0 +1,20 @@
|
||||
Short description: NSCD must use nscd user.
|
||||
Author(s): Fedora glibc team <glibc@lists.fedoraproject.org>
|
||||
Origin: PATCH
|
||||
Upstream status: not-needed
|
||||
|
||||
Fedora-specific configuration adjustment to introduce the nscd user.
|
||||
(Upstream does not assume this user exists.)
|
||||
|
||||
diff -Nrup a/nscd/nscd.conf b/nscd/nscd.conf
|
||||
--- a/nscd/nscd.conf 2012-06-05 07:42:49.000000000 -0600
|
||||
+++ b/nscd/nscd.conf 2012-06-07 12:15:21.818318670 -0600
|
||||
@@ -33,7 +33,7 @@
|
||||
# logfile /var/log/nscd.log
|
||||
# threads 4
|
||||
# max-threads 32
|
||||
-# server-user nobody
|
||||
+ server-user nscd
|
||||
# stat-user somebody
|
||||
debug-level 0
|
||||
# reload-count 5
|
@ -0,0 +1,46 @@
|
||||
The Fedora /etc/nsswitch.conf is based largely on the upstream
|
||||
version with minor downstream distribution modifications for
|
||||
use with SSSD and systemd.
|
||||
|
||||
diff --git a/nss/nsswitch.conf b/nss/nsswitch.conf
|
||||
index 4a6bcb1f7bc0b1f4..980a68e32e6a04b8 100644
|
||||
--- a/nss/nsswitch.conf
|
||||
+++ b/nss/nsswitch.conf
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# /etc/nsswitch.conf
|
||||
#
|
||||
-# An example Name Service Switch config file. This file should be
|
||||
+# Name Service Switch config file. This file should be
|
||||
# sorted with the most-used services at the beginning.
|
||||
#
|
||||
# Valid databases are: aliases, ethers, group, gshadow, hosts,
|
||||
@@ -52,19 +52,21 @@
|
||||
# shadow: db files
|
||||
# group: db files
|
||||
|
||||
-# In alphabetical order. Re-order as required to optimize peformance.
|
||||
+# In order of likelihood of use to accelerate lookup.
|
||||
+passwd: sss files
|
||||
+shadow: files
|
||||
+group: sss files
|
||||
+hosts: files dns myhostname
|
||||
+services: files sss
|
||||
+netgroup: sss
|
||||
+automount: files sss
|
||||
+
|
||||
aliases: files
|
||||
ethers: files
|
||||
-group: files
|
||||
gshadow: files
|
||||
-hosts: files dns
|
||||
# Allow initgroups to default to the setting for group.
|
||||
# initgroups: files
|
||||
-netgroup: files
|
||||
networks: files dns
|
||||
-passwd: files
|
||||
protocols: files
|
||||
publickey: files
|
||||
rpc: files
|
||||
-shadow: files
|
||||
-services: files
|
@ -0,0 +1,21 @@
|
||||
Short description: Provide options to nscd startup.
|
||||
Author(s): Fedora glibc team <glibc@lists.fedoraproject.org>
|
||||
Origin: PATCH
|
||||
Upstream status: not-needed
|
||||
|
||||
Fedora-specific nscd startup configuration file.
|
||||
|
||||
diff --git a/nscd/nscd.service b/nscd/nscd.service
|
||||
index b7428a3..19ba185 100644
|
||||
--- a/nscd/nscd.service
|
||||
+++ b/nscd/nscd.service
|
||||
@@ -5,7 +5,8 @@ Description=Name Service Cache Daemon
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
-ExecStart=/usr/sbin/nscd
|
||||
+EnvironmentFile=-/etc/sysconfig/nscd
|
||||
+ExecStart=/usr/sbin/nscd $NSCD_OPTIONS
|
||||
ExecStop=/usr/sbin/nscd --shutdown
|
||||
ExecReload=/usr/sbin/nscd -i passwd
|
||||
ExecReload=/usr/sbin/nscd -i group
|
@ -0,0 +1,30 @@
|
||||
Use python3 for installed executable python scripts.
|
||||
|
||||
Fedora is a Python3-only distribution:
|
||||
https://fedoraproject.org/wiki/FinalizingFedoraSwitchtoPython3
|
||||
|
||||
This fixes build failures where builders may strictly enforce only
|
||||
python3 during a transitional phase.
|
||||
|
||||
Author: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/benchtests/scripts/compare_bench.py b/benchtests/scripts/compare_bench.py
|
||||
index 6fcbd0803808e5ca..d43db393d63433bc 100755
|
||||
--- a/benchtests/scripts/compare_bench.py
|
||||
+++ b/benchtests/scripts/compare_bench.py
|
||||
@@ -1,4 +1,4 @@
|
||||
-#!/usr/bin/python
|
||||
+#!/usr/bin/python3
|
||||
# Copyright (C) 2015-2021 Free Software Foundation, Inc.
|
||||
# This file is part of the GNU C Library.
|
||||
#
|
||||
diff --git a/benchtests/scripts/import_bench.py b/benchtests/scripts/import_bench.py
|
||||
index a799b4e1b7dc6f30..3286e267168e83bf 100644
|
||||
--- a/benchtests/scripts/import_bench.py
|
||||
+++ b/benchtests/scripts/import_bench.py
|
||||
@@ -1,4 +1,4 @@
|
||||
-#!/usr/bin/python
|
||||
+#!/usr/bin/python3
|
||||
# Copyright (C) 2015-2021 Free Software Foundation, Inc.
|
||||
# This file is part of the GNU C Library.
|
||||
#
|
@ -0,0 +1,38 @@
|
||||
Short description: Add syslog.target dependency.
|
||||
Author(s): Fedora glibc team <glibc@lists.fedoraproject.org>
|
||||
Origin: PATCH
|
||||
Bug-Fedora: #1070416
|
||||
Upstream status: not-needed
|
||||
|
||||
Fedora-specific changes to the nscd.service file.
|
||||
See also: glibc-nscd-sysconfig.patch.
|
||||
|
||||
--- a/nscd/nscd.service
|
||||
+++ b/nscd/nscd.service
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
[Unit]
|
||||
Description=Name Service Cache Daemon
|
||||
+After=syslog.target
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
@@ -17,3 +18,4 @@
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
+Also=nscd.socket
|
||||
diff --git a/nscd/nscd.socket b/nscd/nscd.socket
|
||||
new file mode 100644
|
||||
index 0000000..7e512d5
|
||||
--- /dev/null
|
||||
+++ b/nscd/nscd.socket
|
||||
@@ -0,0 +1,8 @@
|
||||
+[Unit]
|
||||
+Description=Name Service Cache Daemon Socket
|
||||
+
|
||||
+[Socket]
|
||||
+ListenDatagram=/var/run/nscd/socket
|
||||
+
|
||||
+[Install]
|
||||
+WantedBy=sockets.target
|
@ -0,0 +1,619 @@
|
||||
commit 23645707f12f2dd9d80b51effb2d9618a7b65565
|
||||
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Date: Wed Dec 8 11:21:26 2021 +0530
|
||||
|
||||
Replace --enable-static-pie with --disable-default-pie
|
||||
|
||||
Build glibc programs and tests as PIE by default and enable static-pie
|
||||
automatically if the architecture and toolchain supports it.
|
||||
|
||||
Also add a new configuration option --disable-default-pie to prevent
|
||||
building programs as PIE.
|
||||
|
||||
Only the following architectures now have PIE disabled by default
|
||||
because they do not work at the moment. hppa, ia64, alpha and csky
|
||||
don't work because the linker is unable to handle a pcrel relocation
|
||||
generated from PIE objects. The microblaze compiler is currently
|
||||
failing with an ICE. GNU hurd tries to enable static-pie, which does
|
||||
not work and hence fails. All these targets have default PIE disabled
|
||||
at the moment and I have left it to the target maintainers to enable PIE
|
||||
on their targets.
|
||||
|
||||
build-many-glibcs runs clean for all targets. I also tested x86_64 on
|
||||
Fedora and Ubuntu, to verify that the default build as well as
|
||||
--disable-default-pie work as expected with both system toolchains.
|
||||
|
||||
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/INSTALL b/INSTALL
|
||||
index 02dcf6b1ca3a4c43..d6d93ec9be4262d7 100644
|
||||
--- a/INSTALL
|
||||
+++ b/INSTALL
|
||||
@@ -111,16 +111,14 @@ if 'CFLAGS' is specified it must enable optimization. For example:
|
||||
systems support shared libraries; you need ELF support and
|
||||
(currently) the GNU linker.
|
||||
|
||||
-'--enable-static-pie'
|
||||
- Enable static position independent executable (static PIE) support.
|
||||
- Static PIE is similar to static executable, but can be loaded at
|
||||
- any address without help from a dynamic linker. All static
|
||||
- programs as well as static tests are built as static PIE, except
|
||||
- for those marked with no-pie. The resulting glibc can be used with
|
||||
- the GCC option, -static-pie, which is available with GCC 8 or
|
||||
- above, to create static PIE. This option also implies that glibc
|
||||
- programs and tests are created as dynamic position independent
|
||||
- executables (PIE) by default.
|
||||
+'--disable-default-pie'
|
||||
+ Don't build glibc programs and the testsuite as position
|
||||
+ independent executables (PIE). By default, glibc programs and tests
|
||||
+ are created as position independent executables on targets that
|
||||
+ support it. If the toolchain and architecture support it, static
|
||||
+ executables are built as static PIE and the resulting glibc can be
|
||||
+ used with the GCC option, -static-pie, which is available with GCC
|
||||
+ 8 or above, to create static PIE.
|
||||
|
||||
'--enable-cet'
|
||||
'--enable-cet=permissive'
|
||||
diff --git a/Makeconfig b/Makeconfig
|
||||
index 2fa0884b4eee5e53..8bc5540292c7b6fa 100644
|
||||
--- a/Makeconfig
|
||||
+++ b/Makeconfig
|
||||
@@ -1,4 +1,5 @@
|
||||
# Copyright (C) 1991-2021 Free Software Foundation, Inc.
|
||||
+# Copyright (C) The GNU Toolchain Authors.
|
||||
# This file is part of the GNU C Library.
|
||||
|
||||
# The GNU C Library is free software; you can redistribute it and/or
|
||||
@@ -376,19 +377,24 @@ LDFLAGS.so += $(hashstyle-LDFLAGS)
|
||||
LDFLAGS-rtld += $(hashstyle-LDFLAGS)
|
||||
endif
|
||||
|
||||
-ifeq (yes,$(enable-static-pie))
|
||||
+ifeq (no,$(build-pie-default))
|
||||
+pie-default = $(no-pie-ccflag)
|
||||
+else # build-pie-default
|
||||
pic-default = -DPIC
|
||||
# Compile libc.a and libc_p.a with -fPIE/-fpie for static PIE.
|
||||
pie-default = $(pie-ccflag)
|
||||
+
|
||||
+ifeq (yes,$(enable-static-pie))
|
||||
ifeq (yes,$(have-static-pie))
|
||||
-default-pie-ldflag = -static-pie
|
||||
+static-pie-ldflag = -static-pie
|
||||
else
|
||||
# Static PIE can't have dynamic relocations in read-only segments since
|
||||
# static PIE is mapped into memory by kernel. --eh-frame-hdr is needed
|
||||
# for PIE to support exception.
|
||||
-default-pie-ldflag = -Wl,-pie,--no-dynamic-linker,--eh-frame-hdr,-z,text
|
||||
-endif
|
||||
-endif
|
||||
+static-pie-ldflag = -Wl,-pie,--no-dynamic-linker,--eh-frame-hdr,-z,text
|
||||
+endif # have-static-pie
|
||||
+endif # enable-static-pie
|
||||
+endif # build-pie-default
|
||||
|
||||
# If lazy relocations are disabled, add the -z now flag. Use
|
||||
# LDFLAGS-lib.so instead of LDFLAGS.so, to avoid adding the flag to
|
||||
@@ -444,7 +450,7 @@ endif
|
||||
# Command for statically linking programs with the C library.
|
||||
ifndef +link-static
|
||||
+link-static-before-inputs = -nostdlib -nostartfiles -static \
|
||||
- $(if $($(@F)-no-pie),$(no-pie-ldflag),$(default-pie-ldflag)) \
|
||||
+ $(if $($(@F)-no-pie),$(no-pie-ldflag),$(static-pie-ldflag)) \
|
||||
$(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \
|
||||
$(firstword $(CRT-$(@F)) $(csu-objpfx)$(real-static-start-installed-name)) \
|
||||
$(+preinit) $(+prectorT)
|
||||
@@ -479,7 +485,7 @@ ifeq (yes,$(build-pie-default))
|
||||
+link-tests-after-inputs = $(link-libc-tests) $(+link-pie-after-libc)
|
||||
+link-printers-tests = $(+link-pie-printers-tests)
|
||||
else # not build-pie-default
|
||||
-+link-before-inputs = -nostdlib -nostartfiles \
|
||||
++link-before-inputs = -nostdlib -nostartfiles $(no-pie-ldflag) \
|
||||
$(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \
|
||||
$(combreloc-LDFLAGS) $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \
|
||||
$(firstword $(CRT-$(@F)) $(csu-objpfx)$(start-installed-name)) \
|
||||
@@ -1047,6 +1053,7 @@ PIC-ccflag = -fPIC
|
||||
endif
|
||||
# This can be changed by a sysdep makefile
|
||||
pie-ccflag = -fpie
|
||||
+no-pie-ccflag = -fno-pie
|
||||
# This one should always stay like this unless there is a very good reason.
|
||||
PIE-ccflag = -fPIE
|
||||
ifeq (yes,$(build-profile))
|
||||
diff --git a/config.h.in b/config.h.in
|
||||
index 8b45a3a61d774714..458342887e4e9380 100644
|
||||
--- a/config.h.in
|
||||
+++ b/config.h.in
|
||||
@@ -277,6 +277,9 @@
|
||||
/* Build glibc with tunables support. */
|
||||
#define HAVE_TUNABLES 0
|
||||
|
||||
+/* Define if PIE is unsupported. */
|
||||
+#undef PIE_UNSUPPORTED
|
||||
+
|
||||
/* Define if static PIE is supported. */
|
||||
#undef SUPPORT_STATIC_PIE
|
||||
|
||||
diff --git a/config.make.in b/config.make.in
|
||||
index cbf59114b0b9ae4f..e8630a8d0ccf874d 100644
|
||||
--- a/config.make.in
|
||||
+++ b/config.make.in
|
||||
@@ -90,9 +90,6 @@ static-nss-crypt = @libc_cv_static_nss_crypt@
|
||||
|
||||
# Configuration options.
|
||||
build-shared = @shared@
|
||||
-build-pic-default= @libc_cv_pic_default@
|
||||
-build-pie-default= @libc_cv_pie_default@
|
||||
-cc-pie-default= @libc_cv_cc_pie_default@
|
||||
build-profile = @profile@
|
||||
build-static-nss = @static_nss@
|
||||
cross-compiling = @cross_compiling@
|
||||
diff --git a/configure b/configure
|
||||
index 9619c10991d04362..e9d2b1f398c4dba0 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -596,9 +596,6 @@ DEFINES
|
||||
static_nss
|
||||
profile
|
||||
libc_cv_multidir
|
||||
-libc_cv_pie_default
|
||||
-libc_cv_cc_pie_default
|
||||
-libc_cv_pic_default
|
||||
shared
|
||||
static
|
||||
ldd_rewrite_script
|
||||
@@ -767,7 +764,7 @@ with_nonshared_cflags
|
||||
enable_sanity_checks
|
||||
enable_shared
|
||||
enable_profile
|
||||
-enable_static_pie
|
||||
+enable_default_pie
|
||||
enable_timezone_tools
|
||||
enable_hardcoded_path_in_tests
|
||||
enable_hidden_plt
|
||||
@@ -1423,8 +1420,8 @@ Optional Features:
|
||||
in special situations) [default=yes]
|
||||
--enable-shared build shared library [default=yes if GNU ld]
|
||||
--enable-profile build profiled library [default=no]
|
||||
- --enable-static-pie enable static PIE support and use it in the
|
||||
- testsuite [default=no]
|
||||
+ --disable-default-pie Do not build glibc programs and the testsuite as PIE
|
||||
+ [default=no]
|
||||
--disable-timezone-tools
|
||||
do not install timezone tools [default=install]
|
||||
--enable-hardcoded-path-in-tests
|
||||
@@ -3408,11 +3405,11 @@ else
|
||||
profile=no
|
||||
fi
|
||||
|
||||
-# Check whether --enable-static-pie was given.
|
||||
-if test "${enable_static_pie+set}" = set; then :
|
||||
- enableval=$enable_static_pie; static_pie=$enableval
|
||||
+# Check whether --enable-default-pie was given.
|
||||
+if test "${enable_default_pie+set}" = set; then :
|
||||
+ enableval=$enable_default_pie; default_pie=$enableval
|
||||
else
|
||||
- static_pie=no
|
||||
+ default_pie=yes
|
||||
fi
|
||||
|
||||
# Check whether --enable-timezone-tools was given.
|
||||
@@ -6912,7 +6909,8 @@ rm -f conftest.*
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_pic_default" >&5
|
||||
$as_echo "$libc_cv_pic_default" >&6; }
|
||||
-
|
||||
+config_vars="$config_vars
|
||||
+build-pic-default = $libc_cv_pic_default"
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -fPIE is default" >&5
|
||||
$as_echo_n "checking whether -fPIE is default... " >&6; }
|
||||
@@ -6932,17 +6930,37 @@ rm -f conftest.*
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_cc_pie_default" >&5
|
||||
$as_echo "$libc_cv_cc_pie_default" >&6; }
|
||||
-libc_cv_pie_default=$libc_cv_cc_pie_default
|
||||
-
|
||||
-
|
||||
-
|
||||
-# Set the `multidir' variable by grabbing the variable from the compiler.
|
||||
-# We do it once and save the result in a generated makefile.
|
||||
-libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory`
|
||||
-
|
||||
+config_vars="$config_vars
|
||||
+cc-pie-default = $libc_cv_cc_pie_default"
|
||||
|
||||
-if test "$static_pie" = yes; then
|
||||
- # Check target support for static PIE
|
||||
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can build programs as PIE" >&5
|
||||
+$as_echo_n "checking if we can build programs as PIE... " >&6; }
|
||||
+if test "x$default_pie" != xno; then
|
||||
+ # Disable build-pie-default if target does not support it.
|
||||
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
+/* end confdefs.h. */
|
||||
+#ifdef PIE_UNSUPPORTED
|
||||
+# error PIE is not supported
|
||||
+#endif
|
||||
+_ACEOF
|
||||
+if ac_fn_c_try_compile "$LINENO"; then :
|
||||
+ libc_cv_pie_default=yes
|
||||
+else
|
||||
+ libc_cv_pie_default=no
|
||||
+fi
|
||||
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
+fi
|
||||
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_pie_default" >&5
|
||||
+$as_echo "$libc_cv_pie_default" >&6; }
|
||||
+config_vars="$config_vars
|
||||
+build-pie-default = $libc_cv_pie_default"
|
||||
+
|
||||
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can build static PIE programs" >&5
|
||||
+$as_echo_n "checking if we can build static PIE programs... " >&6; }
|
||||
+libc_cv_static_pie=$libc_cv_pie_default
|
||||
+if test "x$libc_cv_pie_default" != xno \
|
||||
+ -a "$libc_cv_no_dynamic_linker" = yes; then
|
||||
+ # Enable static-pie if available
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#ifndef SUPPORT_STATIC_PIE
|
||||
@@ -6950,22 +6968,25 @@ if test "$static_pie" = yes; then
|
||||
#endif
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
-
|
||||
+ libc_cv_static_pie=yes
|
||||
else
|
||||
- as_fn_error $? "the architecture does not support static PIE" "$LINENO" 5
|
||||
+ libc_cv_static_pie=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
- # The linker must support --no-dynamic-linker.
|
||||
- if test "$libc_cv_no_dynamic_linker" != yes; then
|
||||
- as_fn_error $? "linker support for --no-dynamic-linker needed" "$LINENO" 5
|
||||
- fi
|
||||
- # Default to PIE.
|
||||
- libc_cv_pie_default=yes
|
||||
- $as_echo "#define ENABLE_STATIC_PIE 1" >>confdefs.h
|
||||
+ if test "$libc_cv_static_pie" = "yes"; then
|
||||
+ $as_echo "#define ENABLE_STATIC_PIE 1" >>confdefs.h
|
||||
|
||||
+ fi
|
||||
fi
|
||||
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_static_pie" >&5
|
||||
+$as_echo "$libc_cv_static_pie" >&6; }
|
||||
config_vars="$config_vars
|
||||
-enable-static-pie = $static_pie"
|
||||
+enable-static-pie = $libc_cv_static_pie"
|
||||
+
|
||||
+# Set the `multidir' variable by grabbing the variable from the compiler.
|
||||
+# We do it once and save the result in a generated makefile.
|
||||
+libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory`
|
||||
+
|
||||
|
||||
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 34ecbba540546337..79f6822d29ce21cf 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -179,11 +179,11 @@ AC_ARG_ENABLE([profile],
|
||||
[build profiled library @<:@default=no@:>@]),
|
||||
[profile=$enableval],
|
||||
[profile=no])
|
||||
-AC_ARG_ENABLE([static-pie],
|
||||
- AS_HELP_STRING([--enable-static-pie],
|
||||
- [enable static PIE support and use it in the testsuite @<:@default=no@:>@]),
|
||||
- [static_pie=$enableval],
|
||||
- [static_pie=no])
|
||||
+AC_ARG_ENABLE([default-pie],
|
||||
+ AS_HELP_STRING([--disable-default-pie],
|
||||
+ [Do not build glibc programs and the testsuite as PIE @<:@default=no@:>@]),
|
||||
+ [default_pie=$enableval],
|
||||
+ [default_pie=yes])
|
||||
AC_ARG_ENABLE([timezone-tools],
|
||||
AS_HELP_STRING([--disable-timezone-tools],
|
||||
[do not install timezone tools @<:@default=install@:>@]),
|
||||
@@ -1856,7 +1856,7 @@ if eval "${CC-cc} -S conftest.c 2>&AS_MESSAGE_LOG_FD 1>&AS_MESSAGE_LOG_FD"; then
|
||||
libc_cv_pic_default=no
|
||||
fi
|
||||
rm -f conftest.*])
|
||||
-AC_SUBST(libc_cv_pic_default)
|
||||
+LIBC_CONFIG_VAR([build-pic-default], [$libc_cv_pic_default])
|
||||
|
||||
AC_CACHE_CHECK([whether -fPIE is default], libc_cv_cc_pie_default,
|
||||
[libc_cv_cc_pie_default=yes
|
||||
@@ -1869,30 +1869,38 @@ if eval "${CC-cc} -S conftest.c 2>&AS_MESSAGE_LOG_FD 1>&AS_MESSAGE_LOG_FD"; then
|
||||
libc_cv_cc_pie_default=no
|
||||
fi
|
||||
rm -f conftest.*])
|
||||
-libc_cv_pie_default=$libc_cv_cc_pie_default
|
||||
-AC_SUBST(libc_cv_cc_pie_default)
|
||||
-AC_SUBST(libc_cv_pie_default)
|
||||
+LIBC_CONFIG_VAR([cc-pie-default], [$libc_cv_cc_pie_default])
|
||||
+
|
||||
+AC_MSG_CHECKING(if we can build programs as PIE)
|
||||
+if test "x$default_pie" != xno; then
|
||||
+ # Disable build-pie-default if target does not support it.
|
||||
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#ifdef PIE_UNSUPPORTED
|
||||
+# error PIE is not supported
|
||||
+#endif]])], [libc_cv_pie_default=yes], [libc_cv_pie_default=no])
|
||||
+fi
|
||||
+AC_MSG_RESULT($libc_cv_pie_default)
|
||||
+LIBC_CONFIG_VAR([build-pie-default], [$libc_cv_pie_default])
|
||||
+
|
||||
+AC_MSG_CHECKING(if we can build static PIE programs)
|
||||
+libc_cv_static_pie=$libc_cv_pie_default
|
||||
+if test "x$libc_cv_pie_default" != xno \
|
||||
+ -a "$libc_cv_no_dynamic_linker" = yes; then
|
||||
+ # Enable static-pie if available
|
||||
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#ifndef SUPPORT_STATIC_PIE
|
||||
+# error static PIE is not supported
|
||||
+#endif]])], [libc_cv_static_pie=yes], [libc_cv_static_pie=no])
|
||||
+ if test "$libc_cv_static_pie" = "yes"; then
|
||||
+ AC_DEFINE(ENABLE_STATIC_PIE)
|
||||
+ fi
|
||||
+fi
|
||||
+AC_MSG_RESULT($libc_cv_static_pie)
|
||||
+LIBC_CONFIG_VAR([enable-static-pie], [$libc_cv_static_pie])
|
||||
|
||||
# Set the `multidir' variable by grabbing the variable from the compiler.
|
||||
# We do it once and save the result in a generated makefile.
|
||||
libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory`
|
||||
AC_SUBST(libc_cv_multidir)
|
||||
|
||||
-if test "$static_pie" = yes; then
|
||||
- # Check target support for static PIE
|
||||
- AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#ifndef SUPPORT_STATIC_PIE
|
||||
-# error static PIE is not supported
|
||||
-#endif]])], , AC_MSG_ERROR([the architecture does not support static PIE]))
|
||||
- # The linker must support --no-dynamic-linker.
|
||||
- if test "$libc_cv_no_dynamic_linker" != yes; then
|
||||
- AC_MSG_ERROR([linker support for --no-dynamic-linker needed])
|
||||
- fi
|
||||
- # Default to PIE.
|
||||
- libc_cv_pie_default=yes
|
||||
- AC_DEFINE(ENABLE_STATIC_PIE)
|
||||
-fi
|
||||
-LIBC_CONFIG_VAR([enable-static-pie], [$static_pie])
|
||||
-
|
||||
AC_SUBST(profile)
|
||||
AC_SUBST(static_nss)
|
||||
|
||||
diff --git a/manual/install.texi b/manual/install.texi
|
||||
index 46f73b538d3fee6f..1320ac69b3c645f2 100644
|
||||
--- a/manual/install.texi
|
||||
+++ b/manual/install.texi
|
||||
@@ -141,15 +141,13 @@ Don't build shared libraries even if it is possible. Not all systems
|
||||
support shared libraries; you need ELF support and (currently) the GNU
|
||||
linker.
|
||||
|
||||
-@item --enable-static-pie
|
||||
-Enable static position independent executable (static PIE) support.
|
||||
-Static PIE is similar to static executable, but can be loaded at any
|
||||
-address without help from a dynamic linker. All static programs as
|
||||
-well as static tests are built as static PIE, except for those marked
|
||||
-with no-pie. The resulting glibc can be used with the GCC option,
|
||||
--static-pie, which is available with GCC 8 or above, to create static
|
||||
-PIE. This option also implies that glibc programs and tests are created
|
||||
-as dynamic position independent executables (PIE) by default.
|
||||
+@item --disable-default-pie
|
||||
+Don't build glibc programs and the testsuite as position independent
|
||||
+executables (PIE). By default, glibc programs and tests are created as
|
||||
+position independent executables on targets that support it. If the toolchain
|
||||
+and architecture support it, static executables are built as static PIE and the
|
||||
+resulting glibc can be used with the GCC option, -static-pie, which is
|
||||
+available with GCC 8 or above, to create static PIE.
|
||||
|
||||
@item --enable-cet
|
||||
@itemx --enable-cet=permissive
|
||||
diff --git a/scripts/build-many-glibcs.py b/scripts/build-many-glibcs.py
|
||||
index 86537fa8005cfd3d..2fd82a5d054c51ca 100755
|
||||
--- a/scripts/build-many-glibcs.py
|
||||
+++ b/scripts/build-many-glibcs.py
|
||||
@@ -1,6 +1,7 @@
|
||||
#!/usr/bin/python3
|
||||
# Build many configurations of glibc.
|
||||
# Copyright (C) 2016-2021 Free Software Foundation, Inc.
|
||||
+# Copyright (C) The GNU Toolchain Authors.
|
||||
# This file is part of the GNU C Library.
|
||||
#
|
||||
# The GNU C Library is free software; you can redistribute it and/or
|
||||
@@ -435,15 +436,15 @@ class Context(object):
|
||||
'--disable-experimental-malloc',
|
||||
'--disable-build-nscd',
|
||||
'--disable-nscd']},
|
||||
- {'variant': 'static-pie',
|
||||
- 'cfg': ['--enable-static-pie']},
|
||||
- {'variant': 'x32-static-pie',
|
||||
+ {'variant': 'no-pie',
|
||||
+ 'cfg': ['--disable-default-pie']},
|
||||
+ {'variant': 'x32-no-pie',
|
||||
'ccopts': '-mx32',
|
||||
- 'cfg': ['--enable-static-pie']},
|
||||
- {'variant': 'static-pie',
|
||||
+ 'cfg': ['--disable-default-pie']},
|
||||
+ {'variant': 'no-pie',
|
||||
'arch': 'i686',
|
||||
'ccopts': '-m32 -march=i686',
|
||||
- 'cfg': ['--enable-static-pie']},
|
||||
+ 'cfg': ['--disable-default-pie']},
|
||||
{'variant': 'disable-multi-arch',
|
||||
'arch': 'i686',
|
||||
'ccopts': '-m32 -march=i686',
|
||||
diff --git a/sysdeps/alpha/configure b/sysdeps/alpha/configure
|
||||
index 464b5965276dca19..3d665d96f2b40c4e 100644
|
||||
--- a/sysdeps/alpha/configure
|
||||
+++ b/sysdeps/alpha/configure
|
||||
@@ -5,4 +5,9 @@
|
||||
# symbols in a position independent way.
|
||||
$as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h
|
||||
|
||||
+
|
||||
+# PIE builds fail on binutils 2.37 and earlier, see:
|
||||
+# https://sourceware.org/bugzilla/show_bug.cgi?id=28672
|
||||
+$as_echo "#define PIE_UNSUPPORTED 1" >>confdefs.h
|
||||
+
|
||||
# work around problem with autoconf and empty lines at the end of files
|
||||
diff --git a/sysdeps/alpha/configure.ac b/sysdeps/alpha/configure.ac
|
||||
index 38e52e71ac2a5bc0..8f9a39ed2e4a29cb 100644
|
||||
--- a/sysdeps/alpha/configure.ac
|
||||
+++ b/sysdeps/alpha/configure.ac
|
||||
@@ -4,4 +4,8 @@ GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
|
||||
# With required gcc+binutils, we can always access static and hidden
|
||||
# symbols in a position independent way.
|
||||
AC_DEFINE(PI_STATIC_AND_HIDDEN)
|
||||
+
|
||||
+# PIE builds fail on binutils 2.37 and earlier, see:
|
||||
+# https://sourceware.org/bugzilla/show_bug.cgi?id=28672
|
||||
+AC_DEFINE(PIE_UNSUPPORTED)
|
||||
# work around problem with autoconf and empty lines at the end of files
|
||||
diff --git a/sysdeps/csky/configure b/sysdeps/csky/configure
|
||||
index 19acb084fb43d9ea..27464eb707ebd6c6 100644
|
||||
--- a/sysdeps/csky/configure
|
||||
+++ b/sysdeps/csky/configure
|
||||
@@ -2,3 +2,10 @@
|
||||
# Local configure fragment for sysdeps/csky.
|
||||
|
||||
$as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h
|
||||
+
|
||||
+
|
||||
+# PIE builds fail on binutils 2.37 and earlier, see:
|
||||
+# https://sourceware.org/bugzilla/show_bug.cgi?id=28672
|
||||
+$as_echo "#define PIE_UNSUPPORTED 1" >>confdefs.h
|
||||
+
|
||||
+# work around problem with autoconf and empty lines at the end of files
|
||||
diff --git a/sysdeps/csky/configure.ac b/sysdeps/csky/configure.ac
|
||||
index 5656b665da698d05..8e008249094d9e5a 100644
|
||||
--- a/sysdeps/csky/configure.ac
|
||||
+++ b/sysdeps/csky/configure.ac
|
||||
@@ -2,3 +2,8 @@ GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
|
||||
# Local configure fragment for sysdeps/csky.
|
||||
|
||||
AC_DEFINE(PI_STATIC_AND_HIDDEN)
|
||||
+
|
||||
+# PIE builds fail on binutils 2.37 and earlier, see:
|
||||
+# https://sourceware.org/bugzilla/show_bug.cgi?id=28672
|
||||
+AC_DEFINE(PIE_UNSUPPORTED)
|
||||
+# work around problem with autoconf and empty lines at the end of files
|
||||
diff --git a/sysdeps/hppa/configure b/sysdeps/hppa/configure
|
||||
index 2cfe6cbea14549d0..cf5acf966dad67ba 100644
|
||||
--- a/sysdeps/hppa/configure
|
||||
+++ b/sysdeps/hppa/configure
|
||||
@@ -30,3 +30,10 @@ $as_echo "$libc_cv_asm_line_sep" >&6; }
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define ASM_LINE_SEP $libc_cv_asm_line_sep
|
||||
_ACEOF
|
||||
+
|
||||
+
|
||||
+# PIE builds fail on binutils 2.37 and earlier, see:
|
||||
+# https://sourceware.org/bugzilla/show_bug.cgi?id=28672
|
||||
+$as_echo "#define PIE_UNSUPPORTED 1" >>confdefs.h
|
||||
+
|
||||
+# work around problem with autoconf and empty lines at the end of files
|
||||
diff --git a/sysdeps/hppa/configure.ac b/sysdeps/hppa/configure.ac
|
||||
index 1ec417b9474c3382..3e1c35bbd992f548 100644
|
||||
--- a/sysdeps/hppa/configure.ac
|
||||
+++ b/sysdeps/hppa/configure.ac
|
||||
@@ -19,3 +19,8 @@ else
|
||||
fi
|
||||
rm -f conftest*])
|
||||
AC_DEFINE_UNQUOTED(ASM_LINE_SEP, $libc_cv_asm_line_sep)
|
||||
+
|
||||
+# PIE builds fail on binutils 2.37 and earlier, see:
|
||||
+# https://sourceware.org/bugzilla/show_bug.cgi?id=28672
|
||||
+AC_DEFINE(PIE_UNSUPPORTED)
|
||||
+# work around problem with autoconf and empty lines at the end of files
|
||||
diff --git a/sysdeps/ia64/configure b/sysdeps/ia64/configure
|
||||
index 1ef70921bc5266db..748cb526012adeb8 100644
|
||||
--- a/sysdeps/ia64/configure
|
||||
+++ b/sysdeps/ia64/configure
|
||||
@@ -3,4 +3,9 @@
|
||||
|
||||
$as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h
|
||||
|
||||
+
|
||||
+# PIE builds fail on binutils 2.37 and earlier, see:
|
||||
+# https://sourceware.org/bugzilla/show_bug.cgi?id=28672
|
||||
+$as_echo "#define PIE_UNSUPPORTED 1" >>confdefs.h
|
||||
+
|
||||
# work around problem with autoconf and empty lines at the end of files
|
||||
diff --git a/sysdeps/ia64/configure.ac b/sysdeps/ia64/configure.ac
|
||||
index 3bae9fc5e1a3ff45..8e5fba32c3ec8bfc 100644
|
||||
--- a/sysdeps/ia64/configure.ac
|
||||
+++ b/sysdeps/ia64/configure.ac
|
||||
@@ -4,4 +4,8 @@ GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
|
||||
dnl It is always possible to access static and hidden symbols in an
|
||||
dnl position independent way.
|
||||
AC_DEFINE(PI_STATIC_AND_HIDDEN)
|
||||
+
|
||||
+# PIE builds fail on binutils 2.37 and earlier, see:
|
||||
+# https://sourceware.org/bugzilla/show_bug.cgi?id=28672
|
||||
+AC_DEFINE(PIE_UNSUPPORTED)
|
||||
# work around problem with autoconf and empty lines at the end of files
|
||||
diff --git a/sysdeps/mach/hurd/configure b/sysdeps/mach/hurd/configure
|
||||
index 8d0702ad438d1c0a..3303e5dff8ef5ecf 100644
|
||||
--- a/sysdeps/mach/hurd/configure
|
||||
+++ b/sysdeps/mach/hurd/configure
|
||||
@@ -49,3 +49,9 @@ fi
|
||||
|
||||
# Hurd has libpthread as a separate library.
|
||||
pthread_in_libc=no
|
||||
+
|
||||
+# Hurd build needs to be updated to support static pie, see:
|
||||
+# https://sourceware.org/bugzilla/show_bug.cgi?id=28671
|
||||
+$as_echo "#define PIE_UNSUPPORTED 1" >>confdefs.h
|
||||
+
|
||||
+# work around problem with autoconf and empty lines at the end of files
|
||||
diff --git a/sysdeps/mach/hurd/configure.ac b/sysdeps/mach/hurd/configure.ac
|
||||
index 82d085af33701aa2..022c2eff79fc0d08 100644
|
||||
--- a/sysdeps/mach/hurd/configure.ac
|
||||
+++ b/sysdeps/mach/hurd/configure.ac
|
||||
@@ -29,3 +29,8 @@ fi
|
||||
|
||||
# Hurd has libpthread as a separate library.
|
||||
pthread_in_libc=no
|
||||
+
|
||||
+# Hurd build needs to be updated to support static pie, see:
|
||||
+# https://sourceware.org/bugzilla/show_bug.cgi?id=28671
|
||||
+AC_DEFINE(PIE_UNSUPPORTED)
|
||||
+# work around problem with autoconf and empty lines at the end of files
|
||||
diff --git a/sysdeps/microblaze/configure b/sysdeps/microblaze/configure
|
||||
new file mode 100755
|
||||
index 0000000000000000..e6652562d212b688
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/microblaze/configure
|
||||
@@ -0,0 +1,8 @@
|
||||
+# This file is generated from configure.ac by Autoconf. DO NOT EDIT!
|
||||
+ # Local configure fragment for sysdeps/microblaze.
|
||||
+
|
||||
+# gcc 11.2.1 and earlier crash with an internal compiler error, see:
|
||||
+# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103613
|
||||
+$as_echo "#define PIE_UNSUPPORTED 1" >>confdefs.h
|
||||
+
|
||||
+# work around problem with autoconf and empty lines at the end of files
|
||||
diff --git a/sysdeps/microblaze/configure.ac b/sysdeps/microblaze/configure.ac
|
||||
new file mode 100644
|
||||
index 0000000000000000..1c58f70a7bdfebcb
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/microblaze/configure.ac
|
||||
@@ -0,0 +1,7 @@
|
||||
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
|
||||
+# Local configure fragment for sysdeps/microblaze.
|
||||
+
|
||||
+# gcc 11.2.1 and earlier crash with an internal compiler error, see:
|
||||
+# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103613
|
||||
+AC_DEFINE(PIE_UNSUPPORTED)
|
||||
+# work around problem with autoconf and empty lines at the end of files
|
||||
diff --git a/sysdeps/sparc/Makefile b/sysdeps/sparc/Makefile
|
||||
index 1be9a3db2ca12216..12c2c1b085fd4ae2 100644
|
||||
--- a/sysdeps/sparc/Makefile
|
||||
+++ b/sysdeps/sparc/Makefile
|
||||
@@ -2,6 +2,7 @@
|
||||
long-double-fcts = yes
|
||||
|
||||
pie-ccflag = -fPIE
|
||||
+no-pie-ccflag = -fno-PIE
|
||||
|
||||
ifeq ($(subdir),gmon)
|
||||
sysdep_routines += sparc-mcount
|
@ -0,0 +1,250 @@
|
||||
commit c1cb2deeca1a85c6fc5bd41b90816d48a95bc434
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Sun Dec 5 11:28:34 2021 +0100
|
||||
|
||||
elf: execve statically linked programs instead of crashing [BZ #28648]
|
||||
|
||||
Programs without dynamic dependencies and without a program
|
||||
interpreter are now run via execve.
|
||||
|
||||
Previously, the dynamic linker either crashed while attempting to
|
||||
read a non-existing dynamic segment (looking for DT_AUDIT/DT_DEPAUDIT
|
||||
data), or the self-relocated in the static PIE executable crashed
|
||||
because the outer dynamic linker had already applied RELRO protection.
|
||||
|
||||
<dl-execve.h> is needed because execve is not available in the
|
||||
dynamic loader on Hurd.
|
||||
|
||||
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
||||
|
||||
Conflicts:
|
||||
elf/Makefile
|
||||
(usual test differences)
|
||||
elf/rtld.c
|
||||
(missing ld.so self-relocation cleanup downstream)
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 118d579c42c38110..7696aa1324919a80 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -224,7 +224,8 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \
|
||||
tst-tls-ie tst-tls-ie-dlmopen argv0test \
|
||||
tst-glibc-hwcaps tst-glibc-hwcaps-prepend tst-glibc-hwcaps-mask \
|
||||
tst-tls20 tst-tls21 tst-dlmopen-dlerror tst-dlmopen-gethostbyname \
|
||||
- tst-dl-is_dso tst-ro-dynamic
|
||||
+ tst-dl-is_dso tst-ro-dynamic \
|
||||
+ tst-rtld-run-static \
|
||||
# reldep9
|
||||
tests-internal += loadtest unload unload2 circleload1 \
|
||||
neededtest neededtest2 neededtest3 neededtest4 \
|
||||
@@ -1914,3 +1915,5 @@ $(objpfx)tst-ro-dynamic-mod.so: $(objpfx)tst-ro-dynamic-mod.os \
|
||||
$(LINK.o) -nostdlib -nostartfiles -shared -o $@ \
|
||||
-Wl,--script=tst-ro-dynamic-mod.map \
|
||||
$(objpfx)tst-ro-dynamic-mod.os
|
||||
+
|
||||
+$(objpfx)tst-rtld-run-static.out: $(objpfx)/ldconfig
|
||||
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||
index d83ac1bdc40a6081..6b0d6107801b2f44 100644
|
||||
--- a/elf/rtld.c
|
||||
+++ b/elf/rtld.c
|
||||
@@ -50,6 +50,7 @@
|
||||
#include <dl-main.h>
|
||||
#include <gnu/lib-names.h>
|
||||
#include <dl-tunables.h>
|
||||
+#include <dl-execve.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
@@ -1106,6 +1107,45 @@ load_audit_modules (struct link_map *main_map, struct audit_list *audit_list)
|
||||
}
|
||||
}
|
||||
|
||||
+/* Check if the executable is not actualy dynamically linked, and
|
||||
+ invoke it directly in that case. */
|
||||
+static void
|
||||
+rtld_chain_load (struct link_map *main_map, char *argv0)
|
||||
+{
|
||||
+ /* The dynamic loader run against itself. */
|
||||
+ const char *rtld_soname
|
||||
+ = ((const char *) D_PTR (&GL(dl_rtld_map), l_info[DT_STRTAB])
|
||||
+ + GL(dl_rtld_map).l_info[DT_SONAME]->d_un.d_val);
|
||||
+ if (main_map->l_info[DT_SONAME] != NULL
|
||||
+ && strcmp (rtld_soname,
|
||||
+ ((const char *) D_PTR (main_map, l_info[DT_STRTAB])
|
||||
+ + main_map->l_info[DT_SONAME]->d_un.d_val)) == 0)
|
||||
+ _dl_fatal_printf ("%s: loader cannot load itself\n", rtld_soname);
|
||||
+
|
||||
+ /* With DT_NEEDED dependencies, the executable is dynamically
|
||||
+ linked. */
|
||||
+ if (__glibc_unlikely (main_map->l_info[DT_NEEDED] != NULL))
|
||||
+ return;
|
||||
+
|
||||
+ /* If the executable has program interpreter, it is dynamically
|
||||
+ linked. */
|
||||
+ for (size_t i = 0; i < main_map->l_phnum; ++i)
|
||||
+ if (main_map->l_phdr[i].p_type == PT_INTERP)
|
||||
+ return;
|
||||
+
|
||||
+ const char *pathname = _dl_argv[0];
|
||||
+ if (argv0 != NULL)
|
||||
+ _dl_argv[0] = argv0;
|
||||
+ int errcode = __rtld_execve (pathname, _dl_argv, _environ);
|
||||
+ const char *errname = strerrorname_np (errcode);
|
||||
+ if (errname != NULL)
|
||||
+ _dl_fatal_printf("%s: cannot execute %s: %s\n",
|
||||
+ rtld_soname, pathname, errname);
|
||||
+ else
|
||||
+ _dl_fatal_printf("%s: cannot execute %s: %d\n",
|
||||
+ rtld_soname, pathname, errno);
|
||||
+}
|
||||
+
|
||||
static void
|
||||
dl_main (const ElfW(Phdr) *phdr,
|
||||
ElfW(Word) phnum,
|
||||
@@ -1374,14 +1414,8 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||
/* Now the map for the main executable is available. */
|
||||
main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
|
||||
|
||||
- if (__glibc_likely (state.mode == rtld_mode_normal)
|
||||
- && GL(dl_rtld_map).l_info[DT_SONAME] != NULL
|
||||
- && main_map->l_info[DT_SONAME] != NULL
|
||||
- && strcmp ((const char *) D_PTR (&GL(dl_rtld_map), l_info[DT_STRTAB])
|
||||
- + GL(dl_rtld_map).l_info[DT_SONAME]->d_un.d_val,
|
||||
- (const char *) D_PTR (main_map, l_info[DT_STRTAB])
|
||||
- + main_map->l_info[DT_SONAME]->d_un.d_val) == 0)
|
||||
- _dl_fatal_printf ("loader cannot load itself\n");
|
||||
+ if (__glibc_likely (state.mode == rtld_mode_normal))
|
||||
+ rtld_chain_load (main_map, argv0);
|
||||
|
||||
phdr = main_map->l_phdr;
|
||||
phnum = main_map->l_phnum;
|
||||
diff --git a/elf/tst-rtld-run-static.c b/elf/tst-rtld-run-static.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..7281093504b675c4
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-rtld-run-static.c
|
||||
@@ -0,0 +1,62 @@
|
||||
+/* Test running statically linked programs using ld.so.
|
||||
+ Copyright (C) 2021 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/>. */
|
||||
+
|
||||
+#include <support/check.h>
|
||||
+#include <support/support.h>
|
||||
+#include <support/capture_subprocess.h>
|
||||
+#include <string.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ char *ldconfig_path = xasprintf ("%s/elf/ldconfig", support_objdir_root);
|
||||
+
|
||||
+ {
|
||||
+ char *argv[] = { (char *) "ld.so", ldconfig_path, (char *) "--help", NULL };
|
||||
+ struct support_capture_subprocess cap
|
||||
+ = support_capture_subprogram (support_objdir_elf_ldso, argv);
|
||||
+ support_capture_subprocess_check (&cap, "no --argv0", 0, sc_allow_stdout);
|
||||
+ puts ("info: output without --argv0:");
|
||||
+ puts (cap.out.buffer);
|
||||
+ TEST_VERIFY (strstr (cap.out.buffer, "Usage: ldconfig [OPTION...]\n")
|
||||
+ == cap.out.buffer);
|
||||
+ support_capture_subprocess_free (&cap);
|
||||
+ }
|
||||
+
|
||||
+ {
|
||||
+ char *argv[] =
|
||||
+ {
|
||||
+ (char *) "ld.so", (char *) "--argv0", (char *) "ldconfig-argv0",
|
||||
+ ldconfig_path, (char *) "--help", NULL
|
||||
+ };
|
||||
+ struct support_capture_subprocess cap
|
||||
+ = support_capture_subprogram (support_objdir_elf_ldso, argv);
|
||||
+ support_capture_subprocess_check (&cap, "with --argv0", 0, sc_allow_stdout);
|
||||
+ puts ("info: output with --argv0:");
|
||||
+ puts (cap.out.buffer);
|
||||
+ TEST_VERIFY (strstr (cap.out.buffer, "Usage: ldconfig-argv0 [OPTION...]\n")
|
||||
+ == cap.out.buffer);
|
||||
+ support_capture_subprocess_free (&cap);
|
||||
+ }
|
||||
+
|
||||
+ free (ldconfig_path);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/sysdeps/generic/dl-execve.h b/sysdeps/generic/dl-execve.h
|
||||
new file mode 100644
|
||||
index 0000000000000000..5fd097df69e1770c
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/generic/dl-execve.h
|
||||
@@ -0,0 +1,25 @@
|
||||
+/* execve for the dynamic linker. Generic stub version.
|
||||
+ Copyright (C) 2021 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/>. */
|
||||
+
|
||||
+#include <errno.h>
|
||||
+
|
||||
+static int
|
||||
+__rtld_execve (const char *path, char *const *argv, char *const *envp)
|
||||
+{
|
||||
+ return ENOSYS;
|
||||
+}
|
||||
diff --git a/sysdeps/unix/sysv/linux/dl-execve.h b/sysdeps/unix/sysv/linux/dl-execve.h
|
||||
new file mode 100644
|
||||
index 0000000000000000..ead3e1c28da34363
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/unix/sysv/linux/dl-execve.h
|
||||
@@ -0,0 +1,25 @@
|
||||
+/* execve for the dynamic linker. Linux version.
|
||||
+ Copyright (C) 2021 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/>. */
|
||||
+
|
||||
+#include <errno.h>
|
||||
+
|
||||
+static inline int
|
||||
+__rtld_execve (const char *path, char *const *argv, char *const *envp)
|
||||
+{
|
||||
+ return -INTERNAL_SYSCALL_CALL (execve, path, argv, envp);
|
||||
+}
|
@ -0,0 +1,37 @@
|
||||
commit 2e75604f8337fa4332977f72a8f6726309679edf
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Dec 10 16:06:36 2021 +0100
|
||||
|
||||
elf: Install a symbolic link to ld.so as /usr/bin/ld.so
|
||||
|
||||
This makes ld.so features such as --preload, --audit,
|
||||
and --list-diagnostics more accessible to end users because they
|
||||
do not need to know the ABI name of the dynamic loader.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 7696aa1324919a80..3e7debdd81baafe0 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -104,7 +104,7 @@ endif
|
||||
ifeq (yes,$(build-shared))
|
||||
extra-objs = $(all-rtld-routines:%=%.os) sofini.os interp.os
|
||||
generated += librtld.os dl-allobjs.os ld.so ldd
|
||||
-install-others = $(inst_rtlddir)/$(rtld-installed-name)
|
||||
+install-others = $(inst_rtlddir)/$(rtld-installed-name) $(inst_bindir)/ld.so
|
||||
install-bin-script = ldd
|
||||
endif
|
||||
|
||||
@@ -645,6 +645,11 @@ $(inst_rtlddir)/$(rtld-installed-name): $(objpfx)ld.so $(+force)
|
||||
$(make-target-directory)
|
||||
$(do-install-program)
|
||||
|
||||
+# Creates the relative /usr/bin/ld.so symbolic link.
|
||||
+$(inst_bindir)/ld.so: $(inst_rtlddir)/$(rtld-installed-name)
|
||||
+ $(make-target-directory)
|
||||
+ $(make-link)
|
||||
+
|
||||
# Special target called by parent to install just the dynamic linker.
|
||||
.PHONY: ldso_install
|
||||
ldso_install: $(inst_rtlddir)/$(rtld-installed-name)
|
@ -0,0 +1,19 @@
|
||||
commit f1eeef945d49c72eb13654bd30b5904e89b4626f
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Dec 10 21:34:30 2021 +0100
|
||||
|
||||
elf: Use errcode instead of (unset) errno in rtld_chain_load
|
||||
|
||||
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||
index 6b0d6107801b2f44..6bbb373c5743cb99 100644
|
||||
--- a/elf/rtld.c
|
||||
+++ b/elf/rtld.c
|
||||
@@ -1143,7 +1143,7 @@ rtld_chain_load (struct link_map *main_map, char *argv0)
|
||||
rtld_soname, pathname, errname);
|
||||
else
|
||||
_dl_fatal_printf("%s: cannot execute %s: %d\n",
|
||||
- rtld_soname, pathname, errno);
|
||||
+ rtld_soname, pathname, errcode);
|
||||
}
|
||||
|
||||
static void
|
@ -0,0 +1,98 @@
|
||||
commit 84a7eb1f87c1d01b58ad887a0ab5d87abbc1c772
|
||||
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||
Date: Fri Jul 30 19:07:30 2021 -0700
|
||||
|
||||
Use __executable_start as the lowest address for profiling [BZ #28153]
|
||||
|
||||
Glibc assumes that ENTRY_POINT is the lowest address for which we need
|
||||
to keep profiling records and BFD linker uses a linker script to place
|
||||
the input sections.
|
||||
|
||||
Starting from GCC 4.6, the main function is placed in .text.startup
|
||||
section and starting from binutils 2.22, BFD linker with
|
||||
|
||||
commit add44f8d5c5c05e08b11e033127a744d61c26aee
|
||||
Author: Alan Modra <amodra@gmail.com>
|
||||
Date: Thu Nov 25 03:03:02 2010 +0000
|
||||
|
||||
* scripttempl/elf.sc: Group .text.exit, text.startup and .text.hot
|
||||
sections.
|
||||
|
||||
places .text.startup section before .text section, which leave the main
|
||||
function out of profiling records.
|
||||
|
||||
Starting from binutils 2.15, linker provides __executable_start to mark
|
||||
the lowest address of the executable. Use __executable_start as the
|
||||
lowest address to keep the main function in profiling records. This fixes
|
||||
[BZ #28153].
|
||||
|
||||
Tested on Linux/x86-64, Linux/x32 and Linux/i686 as well as with
|
||||
build-many-glibcs.py.
|
||||
|
||||
diff --git a/csu/gmon-start.c b/csu/gmon-start.c
|
||||
index b3432885b39071cc..344606a676c188d4 100644
|
||||
--- a/csu/gmon-start.c
|
||||
+++ b/csu/gmon-start.c
|
||||
@@ -52,6 +52,11 @@ extern char ENTRY_POINT[];
|
||||
#endif
|
||||
extern char etext[];
|
||||
|
||||
+/* Use __executable_start as the lowest address to keep profiling records
|
||||
+ if it provided by the linker. */
|
||||
+extern const char executable_start[] asm ("__executable_start")
|
||||
+ __attribute__ ((weak, visibility ("hidden")));
|
||||
+
|
||||
#ifndef TEXT_START
|
||||
# ifdef ENTRY_POINT_DECL
|
||||
# define TEXT_START ENTRY_POINT
|
||||
@@ -92,7 +97,10 @@ __gmon_start__ (void)
|
||||
called = 1;
|
||||
|
||||
/* Start keeping profiling records. */
|
||||
- __monstartup ((u_long) TEXT_START, (u_long) &etext);
|
||||
+ if (&executable_start != NULL)
|
||||
+ __monstartup ((u_long) &executable_start, (u_long) &etext);
|
||||
+ else
|
||||
+ __monstartup ((u_long) TEXT_START, (u_long) &etext);
|
||||
|
||||
/* Call _mcleanup before exiting; it will write out gmon.out from the
|
||||
collected data. */
|
||||
diff --git a/gmon/tst-gmon-gprof.sh b/gmon/tst-gmon-gprof.sh
|
||||
index 9d371582b99677fa..dc0be021104f725d 100644
|
||||
--- a/gmon/tst-gmon-gprof.sh
|
||||
+++ b/gmon/tst-gmon-gprof.sh
|
||||
@@ -39,12 +39,14 @@ trap cleanup 0
|
||||
cat > "$expected" <<EOF
|
||||
f1 2000
|
||||
f2 1000
|
||||
+f3 1
|
||||
EOF
|
||||
|
||||
# Special version for powerpc with function descriptors.
|
||||
cat > "$expected_dot" <<EOF
|
||||
.f1 2000
|
||||
.f2 1000
|
||||
+.f3 1
|
||||
EOF
|
||||
|
||||
"$GPROF" -C "$program" "$data" \
|
||||
diff --git a/gmon/tst-gmon-static-gprof.sh b/gmon/tst-gmon-static-gprof.sh
|
||||
index 79218df967f9387f..4cc99c80d0115271 100644
|
||||
--- a/gmon/tst-gmon-static-gprof.sh
|
||||
+++ b/gmon/tst-gmon-static-gprof.sh
|
||||
@@ -39,6 +39,7 @@ trap cleanup 0
|
||||
cat > "$expected" <<EOF
|
||||
f1 2000
|
||||
f2 1000
|
||||
+f3 1
|
||||
main 1
|
||||
EOF
|
||||
|
||||
@@ -46,6 +47,7 @@ EOF
|
||||
cat > "$expected_dot" <<EOF
|
||||
.f1 2000
|
||||
.f2 1000
|
||||
+.f3 1
|
||||
.main 1
|
||||
EOF
|
||||
|
@ -0,0 +1,74 @@
|
||||
Downstream adjustment: Change return type of
|
||||
rseq_register_current_thread to bool. Upstream, this was part of the
|
||||
commit that introduced the ABI symbols.
|
||||
|
||||
commit a41c8e92350e744a4bc639df5025153d05263e7f
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu Dec 9 09:49:32 2021 +0100
|
||||
|
||||
nptl: rseq failure after registration on main thread is fatal
|
||||
|
||||
This simplifies the application programming model.
|
||||
|
||||
Browser sandboxes have already been fixed:
|
||||
|
||||
Sandbox is incompatible with rseq registration
|
||||
<https://bugzilla.mozilla.org/show_bug.cgi?id=1651701>
|
||||
|
||||
Allow rseq in the Linux sandboxes. r=gcp
|
||||
<https://hg.mozilla.org/mozilla-central/rev/042425712eb1>
|
||||
|
||||
Sandbox needs to support rseq system call
|
||||
<https://bugs.chromium.org/p/chromium/issues/detail?id=1104160>
|
||||
|
||||
Linux sandbox: Allow rseq(2)
|
||||
<https://chromium.googlesource.com/chromium/src.git/+/230675d9ac8f1>
|
||||
|
||||
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||
|
||||
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
|
||||
index f405fa356c2955ce..109c5e3dc78c9aa2 100644
|
||||
--- a/nptl/pthread_create.c
|
||||
+++ b/nptl/pthread_create.c
|
||||
@@ -371,7 +371,8 @@ start_thread (void *arg)
|
||||
/* Register rseq TLS to the kernel. */
|
||||
{
|
||||
bool do_rseq = THREAD_GETMEM (pd, flags) & ATTR_FLAG_DO_RSEQ;
|
||||
- rseq_register_current_thread (pd, do_rseq);
|
||||
+ if (!rseq_register_current_thread (pd, do_rseq) && do_rseq)
|
||||
+ __libc_fatal ("Fatal glibc error: rseq registration failed\n");
|
||||
}
|
||||
|
||||
#ifndef __ASSUME_SET_ROBUST_LIST
|
||||
diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h
|
||||
index 15bc7ffd6eda632d..6a3441f2cc49e7c4 100644
|
||||
--- a/sysdeps/unix/sysv/linux/rseq-internal.h
|
||||
+++ b/sysdeps/unix/sysv/linux/rseq-internal.h
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <sys/rseq.h>
|
||||
|
||||
#ifdef RSEQ_SIG
|
||||
-static inline void
|
||||
+static inline bool
|
||||
rseq_register_current_thread (struct pthread *self, bool do_rseq)
|
||||
{
|
||||
if (do_rseq)
|
||||
@@ -35,15 +35,17 @@ rseq_register_current_thread (struct pthread *self, bool do_rseq)
|
||||
sizeof (self->rseq_area),
|
||||
0, RSEQ_SIG);
|
||||
if (!INTERNAL_SYSCALL_ERROR_P (ret))
|
||||
- return;
|
||||
+ return true;
|
||||
}
|
||||
THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED);
|
||||
+ return false;
|
||||
}
|
||||
#else /* RSEQ_SIG */
|
||||
static inline void
|
||||
rseq_register_current_thread (struct pthread *self, bool do_rseq)
|
||||
{
|
||||
THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED);
|
||||
+ return false;
|
||||
}
|
||||
#endif /* RSEQ_SIG */
|
||||
|
@ -0,0 +1,592 @@
|
||||
commit 627f5ede70d70c77bdaf857db07404e8bf7f60af
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu Dec 9 17:57:11 2021 +0100
|
||||
|
||||
Remove TLS_TCB_ALIGN and TLS_INIT_TCB_ALIGN
|
||||
|
||||
TLS_INIT_TCB_ALIGN is not actually used. TLS_TCB_ALIGN was likely
|
||||
introduced to support a configuration where the thread pointer
|
||||
has not the same alignment as THREAD_SELF. Only ia64 seems to use
|
||||
that, but for the stack/pointer guard, not for storing tcbhead_t.
|
||||
Some ports use TLS_TCB_OFFSET and TLS_PRE_TCB_SIZE to shift
|
||||
the thread pointer, potentially landing in a different residue class
|
||||
modulo the alignment, but the changes should not impact that.
|
||||
|
||||
In general, given that TLS variables have their own alignment
|
||||
requirements, having different alignment for the (unshifted) thread
|
||||
pointer and struct pthread would potentially result in dynamic
|
||||
offsets, leading to more complexity.
|
||||
|
||||
hppa had different values before: __alignof__ (tcbhead_t), which
|
||||
seems to be 4, and __alignof__ (struct pthread), which was 8
|
||||
(old default) and is now 32. However, it defines THREAD_SELF as:
|
||||
|
||||
/* Return the thread descriptor for the current thread. */
|
||||
# define THREAD_SELF \
|
||||
({ struct pthread *__self; \
|
||||
__self = __get_cr27(); \
|
||||
__self - 1; \
|
||||
})
|
||||
|
||||
So the thread pointer points after struct pthread (hence __self - 1),
|
||||
and they have to have the same alignment on hppa as well.
|
||||
|
||||
Similarly, on ia64, the definitions were different. We have:
|
||||
|
||||
# define TLS_PRE_TCB_SIZE \
|
||||
(sizeof (struct pthread) \
|
||||
+ (PTHREAD_STRUCT_END_PADDING < 2 * sizeof (uintptr_t) \
|
||||
? ((2 * sizeof (uintptr_t) + __alignof__ (struct pthread) - 1) \
|
||||
& ~(__alignof__ (struct pthread) - 1)) \
|
||||
: 0))
|
||||
# define THREAD_SELF \
|
||||
((struct pthread *) ((char *) __thread_self - TLS_PRE_TCB_SIZE))
|
||||
|
||||
And TLS_PRE_TCB_SIZE is a multiple of the struct pthread alignment
|
||||
(confirmed by the new _Static_assert in sysdeps/ia64/libc-tls.c).
|
||||
|
||||
On m68k, we have a larger gap between tcbhead_t and struct pthread.
|
||||
But as far as I can tell, the port is fine with that. The definition
|
||||
of TCB_OFFSET is sufficient to handle the shifted TCB scenario.
|
||||
|
||||
This fixes commit 23c77f60181eb549f11ec2f913b4270af29eee38
|
||||
("nptl: Increase default TCB alignment to 32").
|
||||
|
||||
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
||||
|
||||
diff --git a/csu/libc-tls.c b/csu/libc-tls.c
|
||||
index 5515204863218163..d83e69f6257ae981 100644
|
||||
--- a/csu/libc-tls.c
|
||||
+++ b/csu/libc-tls.c
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/param.h>
|
||||
#include <array_length.h>
|
||||
+#include <pthreadP.h>
|
||||
|
||||
#ifdef SHARED
|
||||
#error makefile bug, this file is for static only
|
||||
@@ -89,7 +90,7 @@ init_static_tls (size_t memsz, size_t align)
|
||||
{
|
||||
/* That is the size of the TLS memory for this object. */
|
||||
GL(dl_tls_static_size) = roundup (memsz + GLRO(dl_tls_static_surplus),
|
||||
- TLS_TCB_ALIGN);
|
||||
+ TCB_ALIGNMENT);
|
||||
#if TLS_TCB_AT_TP
|
||||
GL(dl_tls_static_size) += TLS_TCB_SIZE;
|
||||
#endif
|
||||
@@ -214,5 +215,5 @@ __libc_setup_tls (void)
|
||||
memsz += tcb_offset;
|
||||
#endif
|
||||
|
||||
- init_static_tls (memsz, MAX (TLS_TCB_ALIGN, max_align));
|
||||
+ init_static_tls (memsz, MAX (TCB_ALIGNMENT, max_align));
|
||||
}
|
||||
diff --git a/elf/dl-tls.c b/elf/dl-tls.c
|
||||
index 40263cf586e74c64..e2012d0cd515103b 100644
|
||||
--- a/elf/dl-tls.c
|
||||
+++ b/elf/dl-tls.c
|
||||
@@ -219,7 +219,7 @@ _dl_count_modids (void)
|
||||
void
|
||||
_dl_determine_tlsoffset (void)
|
||||
{
|
||||
- size_t max_align = TLS_TCB_ALIGN;
|
||||
+ size_t max_align = TCB_ALIGNMENT;
|
||||
size_t freetop = 0;
|
||||
size_t freebottom = 0;
|
||||
|
||||
@@ -350,7 +350,7 @@ _dl_determine_tlsoffset (void)
|
||||
|
||||
GL(dl_tls_static_used) = offset;
|
||||
GLRO (dl_tls_static_size) = roundup (offset + GLRO(dl_tls_static_surplus),
|
||||
- TLS_TCB_ALIGN);
|
||||
+ TCB_ALIGNMENT);
|
||||
#else
|
||||
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
|
||||
#endif
|
||||
diff --git a/sysdeps/aarch64/nptl/tls.h b/sysdeps/aarch64/nptl/tls.h
|
||||
index cd9abb5d1d073593..75c469d51b532a89 100644
|
||||
--- a/sysdeps/aarch64/nptl/tls.h
|
||||
+++ b/sysdeps/aarch64/nptl/tls.h
|
||||
@@ -52,18 +52,12 @@ typedef struct
|
||||
/* This is the size of the initial TCB. */
|
||||
# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
|
||||
|
||||
-/* Alignment requirements for the initial TCB. */
|
||||
-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
|
||||
-
|
||||
/* This is the size of the TCB. */
|
||||
# define TLS_TCB_SIZE sizeof (tcbhead_t)
|
||||
|
||||
/* This is the size we need before TCB. */
|
||||
# define TLS_PRE_TCB_SIZE sizeof (struct pthread)
|
||||
|
||||
-/* Alignment requirements for the TCB. */
|
||||
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
|
||||
-
|
||||
/* Install the dtv pointer. The pointer passed is to the element with
|
||||
index -1 which contain the length. */
|
||||
# define INSTALL_DTV(tcbp, dtvp) \
|
||||
diff --git a/sysdeps/alpha/nptl/tls.h b/sysdeps/alpha/nptl/tls.h
|
||||
index 5f4843b28e7f1ad1..c0b6c93891546480 100644
|
||||
--- a/sysdeps/alpha/nptl/tls.h
|
||||
+++ b/sysdeps/alpha/nptl/tls.h
|
||||
@@ -46,18 +46,12 @@ typedef struct
|
||||
/* This is the size of the initial TCB. */
|
||||
# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
|
||||
|
||||
-/* Alignment requirements for the initial TCB. */
|
||||
-# define TLS_INIT_TCB_ALIGN 16
|
||||
-
|
||||
/* This is the size of the TCB. */
|
||||
# define TLS_TCB_SIZE sizeof (tcbhead_t)
|
||||
|
||||
/* This is the size we need before TCB. */
|
||||
# define TLS_PRE_TCB_SIZE sizeof (struct pthread)
|
||||
|
||||
-/* Alignment requirements for the TCB. */
|
||||
-# define TLS_TCB_ALIGN 16
|
||||
-
|
||||
/* Install the dtv pointer. The pointer passed is to the element with
|
||||
index -1 which contain the length. */
|
||||
# define INSTALL_DTV(tcbp, dtvp) \
|
||||
diff --git a/sysdeps/arc/nptl/tls.h b/sysdeps/arc/nptl/tls.h
|
||||
index d9ada2f38089e6cd..d5d282297d12ec98 100644
|
||||
--- a/sysdeps/arc/nptl/tls.h
|
||||
+++ b/sysdeps/arc/nptl/tls.h
|
||||
@@ -48,17 +48,11 @@ typedef struct
|
||||
/* This is the size of the initial TCB. */
|
||||
# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
|
||||
|
||||
-/* Alignment requirements for the initial TCB. */
|
||||
-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
|
||||
-
|
||||
/* This is the size of the TCB. */
|
||||
#ifndef TLS_TCB_SIZE
|
||||
# define TLS_TCB_SIZE sizeof (tcbhead_t)
|
||||
#endif
|
||||
|
||||
-/* Alignment requirements for the TCB. */
|
||||
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
|
||||
-
|
||||
/* This is the size we need before TCB. */
|
||||
# define TLS_PRE_TCB_SIZE sizeof (struct pthread)
|
||||
|
||||
diff --git a/sysdeps/arm/nptl/tls.h b/sysdeps/arm/nptl/tls.h
|
||||
index 354aae3318291395..8475c66588f99cae 100644
|
||||
--- a/sysdeps/arm/nptl/tls.h
|
||||
+++ b/sysdeps/arm/nptl/tls.h
|
||||
@@ -50,18 +50,12 @@ typedef struct
|
||||
/* This is the size of the initial TCB. */
|
||||
# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
|
||||
|
||||
-/* Alignment requirements for the initial TCB. */
|
||||
-# define TLS_INIT_TCB_ALIGN 16
|
||||
-
|
||||
/* This is the size of the TCB. */
|
||||
# define TLS_TCB_SIZE sizeof (tcbhead_t)
|
||||
|
||||
/* This is the size we need before TCB. */
|
||||
# define TLS_PRE_TCB_SIZE sizeof (struct pthread)
|
||||
|
||||
-/* Alignment requirements for the TCB. */
|
||||
-# define TLS_TCB_ALIGN 16
|
||||
-
|
||||
/* Install the dtv pointer. The pointer passed is to the element with
|
||||
index -1 which contain the length. */
|
||||
# define INSTALL_DTV(tcbp, dtvp) \
|
||||
diff --git a/sysdeps/csky/nptl/tls.h b/sysdeps/csky/nptl/tls.h
|
||||
index f3fa3fcb02748776..e81d4552d27e0378 100644
|
||||
--- a/sysdeps/csky/nptl/tls.h
|
||||
+++ b/sysdeps/csky/nptl/tls.h
|
||||
@@ -61,15 +61,9 @@ typedef struct
|
||||
/* This is the size of the initial TCB. */
|
||||
# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
|
||||
|
||||
-/* Alignment requirements for the initial TCB. */
|
||||
-# define TLS_INIT_TCB_ALIGN 8
|
||||
-
|
||||
/* This is the size of the TCB. */
|
||||
# define TLS_TCB_SIZE sizeof (tcbhead_t)
|
||||
|
||||
-/* Alignment requirements for the TCB. */
|
||||
-# define TLS_TCB_ALIGN 8
|
||||
-
|
||||
/* This is the size we need before TCB. */
|
||||
# define TLS_PRE_TCB_SIZE sizeof (struct pthread)
|
||||
|
||||
diff --git a/sysdeps/generic/tls.h b/sysdeps/generic/tls.h
|
||||
index e86d70e6cebba5c8..9214ed39b6383e8c 100644
|
||||
--- a/sysdeps/generic/tls.h
|
||||
+++ b/sysdeps/generic/tls.h
|
||||
@@ -19,6 +19,11 @@
|
||||
/* An architecture-specific version of this file has to defined a
|
||||
number of symbols:
|
||||
|
||||
+ TCB_ALIGNMENT
|
||||
+
|
||||
+ Alignment of THREAD_SELF (struct pthread *) and the thread
|
||||
+ pointer.
|
||||
+
|
||||
TLS_TCB_AT_TP or TLS_DTV_AT_TP
|
||||
|
||||
The presence of one of these symbols signals which variant of
|
||||
@@ -43,15 +48,6 @@
|
||||
dynamic linker itself. There are no threads in use at that time.
|
||||
|
||||
|
||||
- TLS_TCB_ALIGN
|
||||
-
|
||||
- Alignment requirements for the TCB structure.
|
||||
-
|
||||
- TLS_INIT_TCB_ALIGN
|
||||
-
|
||||
- Similarly, but for the structure used at startup time.
|
||||
-
|
||||
-
|
||||
INSTALL_DTV(tcb, init_dtv)
|
||||
|
||||
This macro must install the given initial DTV into the thread control
|
||||
diff --git a/sysdeps/hppa/nptl/tls.h b/sysdeps/hppa/nptl/tls.h
|
||||
index f0e274c45fb5e91e..88a6b902c0b7e2fd 100644
|
||||
--- a/sysdeps/hppa/nptl/tls.h
|
||||
+++ b/sysdeps/hppa/nptl/tls.h
|
||||
@@ -52,15 +52,9 @@ typedef struct
|
||||
/* This is the size of the initial TCB. */
|
||||
# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
|
||||
|
||||
-/* Alignment requirements for the initial TCB. */
|
||||
-# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
|
||||
-
|
||||
/* This is the size of the TCB. */
|
||||
# define TLS_TCB_SIZE sizeof (tcbhead_t)
|
||||
|
||||
-/* Alignment requirements for the TCB. */
|
||||
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
|
||||
-
|
||||
/* This is the size we need before TCB */
|
||||
# define TLS_PRE_TCB_SIZE sizeof (struct pthread)
|
||||
|
||||
diff --git a/sysdeps/i386/nptl/tls.h b/sysdeps/i386/nptl/tls.h
|
||||
index 111c9ee59df30bc3..06ab9784a5358b0b 100644
|
||||
--- a/sysdeps/i386/nptl/tls.h
|
||||
+++ b/sysdeps/i386/nptl/tls.h
|
||||
@@ -102,15 +102,9 @@ union user_desc_init
|
||||
struct pthread even when not linked with -lpthread. */
|
||||
# define TLS_INIT_TCB_SIZE sizeof (struct pthread)
|
||||
|
||||
-/* Alignment requirements for the initial TCB. */
|
||||
-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
|
||||
-
|
||||
/* This is the size of the TCB. */
|
||||
# define TLS_TCB_SIZE sizeof (struct pthread)
|
||||
|
||||
-/* Alignment requirements for the TCB. */
|
||||
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
|
||||
-
|
||||
/* The TCB can have any size and the memory following the address the
|
||||
thread pointer points to is unspecified. Allocate the TCB there. */
|
||||
# define TLS_TCB_AT_TP 1
|
||||
diff --git a/sysdeps/ia64/libc-tls.c b/sysdeps/ia64/libc-tls.c
|
||||
index a01edceab36d375e..ede1e8f463b135b4 100644
|
||||
--- a/sysdeps/ia64/libc-tls.c
|
||||
+++ b/sysdeps/ia64/libc-tls.c
|
||||
@@ -18,6 +18,9 @@
|
||||
|
||||
#include <csu/libc-tls.c>
|
||||
|
||||
+_Static_assert (TLS_PRE_TCB_SIZE % __alignof (struct pthread) == 0,
|
||||
+ "__thread_self and THREAD_SELF have same alignment");
|
||||
+
|
||||
/* On IA-64, as it lacks linker optimizations, __tls_get_addr can be
|
||||
called even in statically linked binaries.
|
||||
In this case module must be always 1 and PT_TLS segment
|
||||
diff --git a/sysdeps/ia64/nptl/tls.h b/sysdeps/ia64/nptl/tls.h
|
||||
index 26fe555cb4b5e164..ca8f1280aeeed3d5 100644
|
||||
--- a/sysdeps/ia64/nptl/tls.h
|
||||
+++ b/sysdeps/ia64/nptl/tls.h
|
||||
@@ -53,9 +53,6 @@ register struct pthread *__thread_self __asm__("r13");
|
||||
/* This is the size of the initial TCB. */
|
||||
# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
|
||||
|
||||
-/* Alignment requirements for the initial TCB. */
|
||||
-# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
|
||||
-
|
||||
/* This is the size of the TCB. */
|
||||
# define TLS_TCB_SIZE sizeof (tcbhead_t)
|
||||
|
||||
@@ -70,9 +67,6 @@ register struct pthread *__thread_self __asm__("r13");
|
||||
& ~(__alignof__ (struct pthread) - 1)) \
|
||||
: 0))
|
||||
|
||||
-/* Alignment requirements for the TCB. */
|
||||
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
|
||||
-
|
||||
/* The DTV is allocated at the TP; the TCB is placed elsewhere. */
|
||||
# define TLS_DTV_AT_TP 1
|
||||
# define TLS_TCB_AT_TP 0
|
||||
diff --git a/sysdeps/m68k/nptl/tls.h b/sysdeps/m68k/nptl/tls.h
|
||||
index 9f562c38288df200..b88ef0c9c74ae0b0 100644
|
||||
--- a/sysdeps/m68k/nptl/tls.h
|
||||
+++ b/sysdeps/m68k/nptl/tls.h
|
||||
@@ -54,20 +54,15 @@ typedef struct
|
||||
pointer, we don't need this. */
|
||||
# define TLS_INIT_TCB_SIZE 0
|
||||
|
||||
-/* Alignment requirements for the initial TCB. */
|
||||
-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
|
||||
-
|
||||
/* This is the size of the TCB. Because our TCB is before the thread
|
||||
pointer, we don't need this. */
|
||||
# define TLS_TCB_SIZE 0
|
||||
|
||||
-/* Alignment requirements for the TCB. */
|
||||
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
|
||||
-
|
||||
/* This is the size we need before TCB - actually, it includes the TCB. */
|
||||
# define TLS_PRE_TCB_SIZE \
|
||||
(sizeof (struct pthread) \
|
||||
- + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1)))
|
||||
+ + ((sizeof (tcbhead_t) + __alignof (struct pthread) - 1) \
|
||||
+ & ~(__alignof (struct pthread) - 1)))
|
||||
|
||||
/* The thread pointer (TP) points to the end of the
|
||||
TCB + 0x7000, as for PowerPC and MIPS. This implies that TCB address is
|
||||
diff --git a/sysdeps/mach/hurd/tls.h b/sysdeps/mach/hurd/tls.h
|
||||
index f83956d3d7ca4f9f..773a2a0c36d5d57d 100644
|
||||
--- a/sysdeps/mach/hurd/tls.h
|
||||
+++ b/sysdeps/mach/hurd/tls.h
|
||||
@@ -29,20 +29,12 @@
|
||||
# include <mach.h>
|
||||
# include <atomic.h>
|
||||
|
||||
-
|
||||
/* This is the size of the initial TCB. */
|
||||
# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
|
||||
|
||||
-/* Alignment requirements for the initial TCB. */
|
||||
-# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
|
||||
-
|
||||
/* This is the size of the TCB. */
|
||||
# define TLS_TCB_SIZE TLS_INIT_TCB_SIZE /* XXX */
|
||||
|
||||
-/* Alignment requirements for the TCB. */
|
||||
-# define TLS_TCB_ALIGN TLS_INIT_TCB_ALIGN /* XXX */
|
||||
-
|
||||
-
|
||||
/* Install the dtv pointer. The pointer passed is to the element with
|
||||
index -1 which contain the length. */
|
||||
# define INSTALL_DTV(descr, dtvp) \
|
||||
diff --git a/sysdeps/microblaze/nptl/tls.h b/sysdeps/microblaze/nptl/tls.h
|
||||
index bfa6efa78049bb2d..b69d7b4f28f3b757 100644
|
||||
--- a/sysdeps/microblaze/nptl/tls.h
|
||||
+++ b/sysdeps/microblaze/nptl/tls.h
|
||||
@@ -56,18 +56,12 @@ typedef struct
|
||||
/* This is the size of the initial TCB. */
|
||||
# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
|
||||
|
||||
-/* Alignment requirements for the initial TCB. */
|
||||
-# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
|
||||
-
|
||||
/* This is the size of the TCB. */
|
||||
# define TLS_TCB_SIZE sizeof (tcbhead_t)
|
||||
|
||||
/* This is the size we need before TCB. */
|
||||
# define TLS_PRE_TCB_SIZE sizeof (struct pthread)
|
||||
|
||||
-/* Alignment requirements for the TCB. */
|
||||
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
|
||||
-
|
||||
/* Install the dtv pointer. The pointer passed is to the element with
|
||||
index -1 which contain the length. */
|
||||
# define INSTALL_DTV(tcbp, dtvp) \
|
||||
diff --git a/sysdeps/mips/nptl/tls.h b/sysdeps/mips/nptl/tls.h
|
||||
index ef99aa646c898e76..6ccaf9804a68634a 100644
|
||||
--- a/sysdeps/mips/nptl/tls.h
|
||||
+++ b/sysdeps/mips/nptl/tls.h
|
||||
@@ -83,20 +83,15 @@ typedef struct
|
||||
pointer, we don't need this. */
|
||||
# define TLS_INIT_TCB_SIZE 0
|
||||
|
||||
-/* Alignment requirements for the initial TCB. */
|
||||
-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
|
||||
-
|
||||
/* This is the size of the TCB. Because our TCB is before the thread
|
||||
pointer, we don't need this. */
|
||||
# define TLS_TCB_SIZE 0
|
||||
|
||||
-/* Alignment requirements for the TCB. */
|
||||
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
|
||||
-
|
||||
/* This is the size we need before TCB - actually, it includes the TCB. */
|
||||
# define TLS_PRE_TCB_SIZE \
|
||||
(sizeof (struct pthread) \
|
||||
- + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1)))
|
||||
+ + ((sizeof (tcbhead_t) + __alignof (struct pthread) - 1) \
|
||||
+ & ~(__alignof (struct pthread) - 1)))
|
||||
|
||||
/* The thread pointer (in hardware register $29) points to the end of
|
||||
the TCB + 0x7000, as for PowerPC. The pthread_descr structure is
|
||||
diff --git a/sysdeps/nios2/nptl/tls.h b/sysdeps/nios2/nptl/tls.h
|
||||
index 7110cfccad7131f4..6ab6bd27b00a70ee 100644
|
||||
--- a/sysdeps/nios2/nptl/tls.h
|
||||
+++ b/sysdeps/nios2/nptl/tls.h
|
||||
@@ -59,20 +59,15 @@ register struct pthread *__thread_self __asm__("r23");
|
||||
pointer, we don't need this. */
|
||||
# define TLS_INIT_TCB_SIZE 0
|
||||
|
||||
-/* Alignment requirements for the initial TCB. */
|
||||
-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
|
||||
-
|
||||
/* This is the size of the TCB. Because our TCB is before the thread
|
||||
pointer, we don't need this. */
|
||||
# define TLS_TCB_SIZE 0
|
||||
|
||||
-/* Alignment requirements for the TCB. */
|
||||
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
|
||||
-
|
||||
/* This is the size we need before TCB - actually, it includes the TCB. */
|
||||
# define TLS_PRE_TCB_SIZE \
|
||||
(sizeof (struct pthread) \
|
||||
- + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1)))
|
||||
+ + ((sizeof (tcbhead_t) + __alignof (struct pthread) - 1) \
|
||||
+ & ~(__alignof (struct pthread) - 1)))
|
||||
|
||||
/* The thread pointer (in hardware register r23) points to the end of
|
||||
the TCB + 0x7000, as for PowerPC and MIPS. */
|
||||
diff --git a/sysdeps/powerpc/nptl/tls.h b/sysdeps/powerpc/nptl/tls.h
|
||||
index 110d085d30c86302..e194b334216eaa02 100644
|
||||
--- a/sysdeps/powerpc/nptl/tls.h
|
||||
+++ b/sysdeps/powerpc/nptl/tls.h
|
||||
@@ -108,19 +108,14 @@ typedef struct
|
||||
/* This is the size of the initial TCB. */
|
||||
# define TLS_INIT_TCB_SIZE 0
|
||||
|
||||
-/* Alignment requirements for the initial TCB. */
|
||||
-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
|
||||
-
|
||||
/* This is the size of the TCB. */
|
||||
# define TLS_TCB_SIZE 0
|
||||
|
||||
-/* Alignment requirements for the TCB. */
|
||||
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
|
||||
-
|
||||
/* This is the size we need before TCB. */
|
||||
# define TLS_PRE_TCB_SIZE \
|
||||
(sizeof (struct pthread) \
|
||||
- + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1)))
|
||||
+ + ((sizeof (tcbhead_t) + __alignof (struct pthread) - 1) \
|
||||
+ & ~(__alignof (struct pthread) - 1)))
|
||||
|
||||
/* The following assumes that TP (R2 or R13) points to the end of the
|
||||
TCB + 0x7000 (per the ABI). This implies that TCB address is
|
||||
diff --git a/sysdeps/riscv/nptl/tls.h b/sysdeps/riscv/nptl/tls.h
|
||||
index bdc0a3a6f91b51e8..8c12d8f971adeddb 100644
|
||||
--- a/sysdeps/riscv/nptl/tls.h
|
||||
+++ b/sysdeps/riscv/nptl/tls.h
|
||||
@@ -50,20 +50,15 @@ typedef struct
|
||||
pointer, we don't need this. */
|
||||
# define TLS_INIT_TCB_SIZE 0
|
||||
|
||||
-/* Alignment requirements for the initial TCB. */
|
||||
-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
|
||||
-
|
||||
/* This is the size of the TCB. Because our TCB is before the thread
|
||||
pointer, we don't need this. */
|
||||
# define TLS_TCB_SIZE 0
|
||||
|
||||
-/* Alignment requirements for the TCB. */
|
||||
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
|
||||
-
|
||||
/* This is the size we need before TCB - actually, it includes the TCB. */
|
||||
# define TLS_PRE_TCB_SIZE \
|
||||
(sizeof (struct pthread) \
|
||||
- + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1)))
|
||||
+ + ((sizeof (tcbhead_t) + __alignof (struct pthread) - 1) \
|
||||
+ & ~(__alignof (struct pthread) - 1)))
|
||||
|
||||
/* The thread pointer tp points to the end of the TCB.
|
||||
The pthread_descr structure is immediately in front of the TCB. */
|
||||
diff --git a/sysdeps/s390/nptl/tls.h b/sysdeps/s390/nptl/tls.h
|
||||
index 2cdd18eb2907c060..3b4c0ab32a9439a3 100644
|
||||
--- a/sysdeps/s390/nptl/tls.h
|
||||
+++ b/sysdeps/s390/nptl/tls.h
|
||||
@@ -66,15 +66,9 @@ typedef struct
|
||||
struct pthread even when not linked with -lpthread. */
|
||||
# define TLS_INIT_TCB_SIZE sizeof (struct pthread)
|
||||
|
||||
-/* Alignment requirements for the initial TCB. */
|
||||
-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
|
||||
-
|
||||
/* This is the size of the TCB. */
|
||||
# define TLS_TCB_SIZE sizeof (struct pthread)
|
||||
|
||||
-/* Alignment requirements for the TCB. */
|
||||
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
|
||||
-
|
||||
/* The TCB can have any size and the memory following the address the
|
||||
thread pointer points to is unspecified. Allocate the TCB there. */
|
||||
# define TLS_TCB_AT_TP 1
|
||||
diff --git a/sysdeps/sh/nptl/tls.h b/sysdeps/sh/nptl/tls.h
|
||||
index 390640020e45f716..3e4d480b35951253 100644
|
||||
--- a/sysdeps/sh/nptl/tls.h
|
||||
+++ b/sysdeps/sh/nptl/tls.h
|
||||
@@ -51,18 +51,12 @@ typedef struct
|
||||
/* This is the size of the initial TCB. */
|
||||
# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
|
||||
|
||||
-/* Alignment requirements for the initial TCB. */
|
||||
-# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
|
||||
-
|
||||
/* This is the size of the TCB. */
|
||||
# define TLS_TCB_SIZE sizeof (tcbhead_t)
|
||||
|
||||
/* This is the size we need before TCB. */
|
||||
# define TLS_PRE_TCB_SIZE sizeof (struct pthread)
|
||||
|
||||
-/* Alignment requirements for the TCB. */
|
||||
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
|
||||
-
|
||||
/* The TLS blocks start right after the TCB. */
|
||||
# define TLS_DTV_AT_TP 1
|
||||
# define TLS_TCB_AT_TP 0
|
||||
diff --git a/sysdeps/sparc/nptl/tls.h b/sysdeps/sparc/nptl/tls.h
|
||||
index 376d729989e35660..3fb4ce6e6dacf28c 100644
|
||||
--- a/sysdeps/sparc/nptl/tls.h
|
||||
+++ b/sysdeps/sparc/nptl/tls.h
|
||||
@@ -63,15 +63,9 @@ register struct pthread *__thread_self __asm__("%g7");
|
||||
struct pthread even when not linked with -lpthread. */
|
||||
# define TLS_INIT_TCB_SIZE sizeof (struct pthread)
|
||||
|
||||
-/* Alignment requirements for the initial TCB. */
|
||||
-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
|
||||
-
|
||||
/* This is the size of the TCB. */
|
||||
# define TLS_TCB_SIZE sizeof (struct pthread)
|
||||
|
||||
-/* Alignment requirements for the TCB. */
|
||||
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
|
||||
-
|
||||
/* The TCB can have any size and the memory following the address the
|
||||
thread pointer points to is unspecified. Allocate the TCB there. */
|
||||
# define TLS_TCB_AT_TP 1
|
||||
diff --git a/sysdeps/x86_64/nptl/tls.h b/sysdeps/x86_64/nptl/tls.h
|
||||
index 3af1836e28b26fdb..50f7e8b544f9e6fc 100644
|
||||
--- a/sysdeps/x86_64/nptl/tls.h
|
||||
+++ b/sysdeps/x86_64/nptl/tls.h
|
||||
@@ -106,15 +106,9 @@ _Static_assert (offsetof (tcbhead_t, __glibc_unused2) == 0x80,
|
||||
struct pthread even when not linked with -lpthread. */
|
||||
# define TLS_INIT_TCB_SIZE sizeof (struct pthread)
|
||||
|
||||
-/* Alignment requirements for the initial TCB. */
|
||||
-# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
|
||||
-
|
||||
/* This is the size of the TCB. */
|
||||
# define TLS_TCB_SIZE sizeof (struct pthread)
|
||||
|
||||
-/* Alignment requirements for the TCB. */
|
||||
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
|
||||
-
|
||||
/* The TCB can have any size and the memory following the address the
|
||||
thread pointer points to is unspecified. Allocate the TCB there. */
|
||||
# define TLS_TCB_AT_TP 1
|
@ -0,0 +1,73 @@
|
||||
commit cb976fba4c51ede7bf8cee5035888527c308dfbc
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Wed Dec 15 16:06:25 2021 +0100
|
||||
|
||||
powerpc: Use global register variable in <thread_pointer.h>
|
||||
|
||||
A local register variable is merely a compiler hint, and so not
|
||||
appropriate in this context. Move the global register variable into
|
||||
<thread_pointer.h> and include it from <tls.h>, as there can only
|
||||
be one global definition for one particular register.
|
||||
|
||||
Fixes commit 8dbeb0561eeb876f557ac9eef5721912ec074ea5
|
||||
("nptl: Add <thread_pointer.h> for defining __thread_pointer").
|
||||
|
||||
Reported-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
Reviewed-by: Raphael M Zinsly <rzinsly@linux.ibm.com>
|
||||
|
||||
diff --git a/sysdeps/powerpc/nptl/thread_pointer.h b/sysdeps/powerpc/nptl/thread_pointer.h
|
||||
index 8fd5ba671f6f5e64..4feba5961062cfaf 100644
|
||||
--- a/sysdeps/powerpc/nptl/thread_pointer.h
|
||||
+++ b/sysdeps/powerpc/nptl/thread_pointer.h
|
||||
@@ -19,15 +19,16 @@
|
||||
#ifndef _SYS_THREAD_POINTER_H
|
||||
#define _SYS_THREAD_POINTER_H
|
||||
|
||||
-static inline void *
|
||||
-__thread_pointer (void)
|
||||
-{
|
||||
#ifdef __powerpc64__
|
||||
- register void *__result asm ("r13");
|
||||
+register void *__thread_register asm ("r13");
|
||||
#else
|
||||
- register void *__result asm ("r2");
|
||||
+register void *__thread_register asm ("r2");
|
||||
#endif
|
||||
- return __result;
|
||||
+
|
||||
+static inline void *
|
||||
+__thread_pointer (void)
|
||||
+{
|
||||
+ return __thread_register;
|
||||
}
|
||||
|
||||
#endif /* _SYS_THREAD_POINTER_H */
|
||||
diff --git a/sysdeps/powerpc/nptl/tls.h b/sysdeps/powerpc/nptl/tls.h
|
||||
index e194b334216eaa02..050beb06a8f7de65 100644
|
||||
--- a/sysdeps/powerpc/nptl/tls.h
|
||||
+++ b/sysdeps/powerpc/nptl/tls.h
|
||||
@@ -26,6 +26,7 @@
|
||||
# include <stddef.h>
|
||||
# include <stdint.h>
|
||||
# include <dl-dtv.h>
|
||||
+# include <thread_pointer.h>
|
||||
|
||||
#else /* __ASSEMBLER__ */
|
||||
# include <tcb-offsets.h>
|
||||
@@ -36,16 +37,10 @@
|
||||
#ifndef __powerpc64__
|
||||
/* Register r2 (tp) is reserved by the ABI as "thread pointer". */
|
||||
# define PT_THREAD_POINTER PT_R2
|
||||
-# ifndef __ASSEMBLER__
|
||||
-register void *__thread_register __asm__ ("r2");
|
||||
-# endif
|
||||
|
||||
#else /* __powerpc64__ */
|
||||
/* Register r13 (tp) is reserved by the ABI as "thread pointer". */
|
||||
# define PT_THREAD_POINTER PT_R13
|
||||
-# ifndef __ASSEMBLER__
|
||||
-register void *__thread_register __asm__ ("r13");
|
||||
-# endif
|
||||
#endif /* __powerpc64__ */
|
||||
|
||||
#ifndef __ASSEMBLER__
|
@ -0,0 +1,42 @@
|
||||
Downstream-only patch to disable rseq by default. This is necessary
|
||||
because CRIU does not yet support rseq:
|
||||
|
||||
criu: Implement rseq support
|
||||
<https://bugzilla.redhat.com/show_bug.cgi?id=2033446>
|
||||
|
||||
diff --git a/manual/tunables.texi b/manual/tunables.texi
|
||||
index 28ff502990c2a10f..f559c44dcec4624b 100644
|
||||
--- a/manual/tunables.texi
|
||||
+++ b/manual/tunables.texi
|
||||
@@ -425,11 +425,13 @@ The value is measured in bytes. The default is @samp{41943040}
|
||||
@end deftp
|
||||
|
||||
@deftp Tunable glibc.pthread.rseq
|
||||
-The @code{glibc.pthread.rseq} tunable can be set to @samp{0}, to disable
|
||||
-restartable sequences support in @theglibc{}. This enables applications
|
||||
-to perform direct restartable sequence registration with the kernel.
|
||||
-The default is @samp{1}, which means that @theglibc{} performs
|
||||
-registration on behalf of the application.
|
||||
+The @code{glibc.pthread.rseq} tunable can be set to @samp{1}, to enable
|
||||
+restartable sequences support. @Theglibc{} uses this to optimize the
|
||||
+@code{sched_getcpu} function.
|
||||
+
|
||||
+The default is @samp{0}, which means that applications can perform
|
||||
+restartable sequences registration, but @code{sched_getcpu} is not
|
||||
+accelerated.
|
||||
|
||||
Restartable sequences are a Linux-specific extension.
|
||||
@end deftp
|
||||
diff --git a/sysdeps/nptl/dl-tunables.list b/sysdeps/nptl/dl-tunables.list
|
||||
index d24f4be0d08ba407..df2a39ce01858d3b 100644
|
||||
--- a/sysdeps/nptl/dl-tunables.list
|
||||
+++ b/sysdeps/nptl/dl-tunables.list
|
||||
@@ -31,7 +31,7 @@ glibc {
|
||||
type: INT_32
|
||||
minval: 0
|
||||
maxval: 1
|
||||
- default: 1
|
||||
+ default: 0
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,259 @@
|
||||
commit 23c77f60181eb549f11ec2f913b4270af29eee38
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Dec 3 16:28:07 2021 +0100
|
||||
|
||||
nptl: Increase default TCB alignment to 32
|
||||
|
||||
rseq support will use a 32-byte aligned field in struct pthread,
|
||||
so the whole struct needs to have at least that alignment.
|
||||
|
||||
nptl/tst-tls3mod.c uses TCB_ALIGNMENT, therefore include <descr.h>
|
||||
to obtain the fallback definition.
|
||||
|
||||
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
||||
|
||||
diff --git a/nptl/descr.h b/nptl/descr.h
|
||||
index 4de84138fb960fa4..57be5b4fef564b36 100644
|
||||
--- a/nptl/descr.h
|
||||
+++ b/nptl/descr.h
|
||||
@@ -37,7 +37,9 @@
|
||||
#include <tls-internal-struct.h>
|
||||
|
||||
#ifndef TCB_ALIGNMENT
|
||||
-# define TCB_ALIGNMENT sizeof (double)
|
||||
+# define TCB_ALIGNMENT 32
|
||||
+#elif TCB_ALIGNMENT < 32
|
||||
+# error TCB_ALIGNMENT must be at least 32
|
||||
#endif
|
||||
|
||||
|
||||
diff --git a/nptl/tst-tls3mod.c b/nptl/tst-tls3mod.c
|
||||
index cfd13aace1affcd5..77dcc550fc3b5017 100644
|
||||
--- a/nptl/tst-tls3mod.c
|
||||
+++ b/nptl/tst-tls3mod.c
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <pthreaddef.h>
|
||||
+#include <descr.h>
|
||||
|
||||
|
||||
extern pthread_barrier_t b;
|
||||
diff --git a/sysdeps/aarch64/nptl/pthreaddef.h b/sysdeps/aarch64/nptl/pthreaddef.h
|
||||
index 4d5ecf6661fd0fe6..8d9a10622d132a7a 100644
|
||||
--- a/sysdeps/aarch64/nptl/pthreaddef.h
|
||||
+++ b/sysdeps/aarch64/nptl/pthreaddef.h
|
||||
@@ -28,8 +28,5 @@
|
||||
/* Minimal stack size after allocating thread descriptor and guard size. */
|
||||
#define MINIMAL_REST_STACK 2048
|
||||
|
||||
-/* Alignment requirement for TCB. */
|
||||
-#define TCB_ALIGNMENT 16
|
||||
-
|
||||
/* Location of current stack frame. */
|
||||
#define CURRENT_STACK_FRAME __builtin_frame_address (0)
|
||||
diff --git a/sysdeps/alpha/nptl/pthreaddef.h b/sysdeps/alpha/nptl/pthreaddef.h
|
||||
index 25edb5093e095548..660e5694a25ec60f 100644
|
||||
--- a/sysdeps/alpha/nptl/pthreaddef.h
|
||||
+++ b/sysdeps/alpha/nptl/pthreaddef.h
|
||||
@@ -27,8 +27,5 @@
|
||||
/* Minimal stack size after allocating thread descriptor and guard size. */
|
||||
#define MINIMAL_REST_STACK 4096
|
||||
|
||||
-/* Alignment requirement for TCB. */
|
||||
-#define TCB_ALIGNMENT 16
|
||||
-
|
||||
/* Location of current stack frame. */
|
||||
#define CURRENT_STACK_FRAME __builtin_frame_address (0)
|
||||
diff --git a/sysdeps/arc/nptl/pthreaddef.h b/sysdeps/arc/nptl/pthreaddef.h
|
||||
index 873b9d149ac46a62..d4dbe9e079445353 100644
|
||||
--- a/sysdeps/arc/nptl/pthreaddef.h
|
||||
+++ b/sysdeps/arc/nptl/pthreaddef.h
|
||||
@@ -28,8 +28,5 @@
|
||||
/* Minimal stack size after allocating thread descriptor and guard size. */
|
||||
#define MINIMAL_REST_STACK 2048
|
||||
|
||||
-/* Alignment requirement for TCB. */
|
||||
-#define TCB_ALIGNMENT 4
|
||||
-
|
||||
/* Location of current stack frame. */
|
||||
#define CURRENT_STACK_FRAME __builtin_frame_address (0)
|
||||
diff --git a/sysdeps/arm/nptl/pthreaddef.h b/sysdeps/arm/nptl/pthreaddef.h
|
||||
index 332f4079c4c3f2bf..13769f5ae270b0ca 100644
|
||||
--- a/sysdeps/arm/nptl/pthreaddef.h
|
||||
+++ b/sysdeps/arm/nptl/pthreaddef.h
|
||||
@@ -28,9 +28,6 @@
|
||||
/* Minimal stack size after allocating thread descriptor and guard size. */
|
||||
#define MINIMAL_REST_STACK 2048
|
||||
|
||||
-/* Alignment requirement for TCB. */
|
||||
-#define TCB_ALIGNMENT 16
|
||||
-
|
||||
|
||||
/* Location of current stack frame.
|
||||
|
||||
diff --git a/sysdeps/csky/nptl/pthreaddef.h b/sysdeps/csky/nptl/pthreaddef.h
|
||||
index e78bc0016b43b450..7dde9131b9b1a6b0 100644
|
||||
--- a/sysdeps/csky/nptl/pthreaddef.h
|
||||
+++ b/sysdeps/csky/nptl/pthreaddef.h
|
||||
@@ -28,8 +28,5 @@
|
||||
/* Minimal stack size after allocating thread descriptor and guard size. */
|
||||
#define MINIMAL_REST_STACK 2048
|
||||
|
||||
-/* Alignment requirement for TCB. */
|
||||
-#define TCB_ALIGNMENT 8
|
||||
-
|
||||
/* Location of current stack frame. */
|
||||
#define CURRENT_STACK_FRAME __builtin_frame_address (0)
|
||||
diff --git a/sysdeps/ia64/nptl/pthreaddef.h b/sysdeps/ia64/nptl/pthreaddef.h
|
||||
index 3a0f6daf9ad871aa..c7420fd1e4ee6081 100644
|
||||
--- a/sysdeps/ia64/nptl/pthreaddef.h
|
||||
+++ b/sysdeps/ia64/nptl/pthreaddef.h
|
||||
@@ -30,9 +30,6 @@
|
||||
/* Minimal stack size after allocating thread descriptor and guard size. */
|
||||
#define MINIMAL_REST_STACK 16384
|
||||
|
||||
-/* Alignment requirement for TCB. */
|
||||
-#define TCB_ALIGNMENT 16
|
||||
-
|
||||
|
||||
/* Location of current stack frame. */
|
||||
#define CURRENT_STACK_FRAME __stack_pointer
|
||||
diff --git a/sysdeps/m68k/nptl/pthreaddef.h b/sysdeps/m68k/nptl/pthreaddef.h
|
||||
index 13e785a86bbf47b4..ce9511cb02da69fd 100644
|
||||
--- a/sysdeps/m68k/nptl/pthreaddef.h
|
||||
+++ b/sysdeps/m68k/nptl/pthreaddef.h
|
||||
@@ -28,9 +28,6 @@
|
||||
/* Minimal stack size after allocating thread descriptor and guard size. */
|
||||
#define MINIMAL_REST_STACK 2048
|
||||
|
||||
-/* Alignment requirement for TCB. */
|
||||
-#define TCB_ALIGNMENT 16
|
||||
-
|
||||
|
||||
/* Location of current stack frame. */
|
||||
#define CURRENT_STACK_FRAME __builtin_frame_address (0)
|
||||
diff --git a/sysdeps/microblaze/nptl/pthreaddef.h b/sysdeps/microblaze/nptl/pthreaddef.h
|
||||
index 517157444da556ad..19d7235782afde53 100644
|
||||
--- a/sysdeps/microblaze/nptl/pthreaddef.h
|
||||
+++ b/sysdeps/microblaze/nptl/pthreaddef.h
|
||||
@@ -31,8 +31,5 @@
|
||||
/* Minimal stack size after allocating thread descriptor and guard size. */
|
||||
#define MINIMAL_REST_STACK 2048
|
||||
|
||||
-/* Alignment requirement for TCB. */
|
||||
-#define TCB_ALIGNMENT 16
|
||||
-
|
||||
/* Location of current stack frame. */
|
||||
#define CURRENT_STACK_FRAME __builtin_frame_address (0)
|
||||
diff --git a/sysdeps/mips/nptl/pthreaddef.h b/sysdeps/mips/nptl/pthreaddef.h
|
||||
index a7bccef6e512438f..322591c293ce5e15 100644
|
||||
--- a/sysdeps/mips/nptl/pthreaddef.h
|
||||
+++ b/sysdeps/mips/nptl/pthreaddef.h
|
||||
@@ -27,9 +27,6 @@
|
||||
/* Minimal stack size after allocating thread descriptor and guard size. */
|
||||
#define MINIMAL_REST_STACK 2048
|
||||
|
||||
-/* Alignment requirement for TCB. */
|
||||
-#define TCB_ALIGNMENT 16
|
||||
-
|
||||
|
||||
/* Location of current stack frame. */
|
||||
#define CURRENT_STACK_FRAME __builtin_frame_address (0)
|
||||
diff --git a/sysdeps/nios2/nptl/pthreaddef.h b/sysdeps/nios2/nptl/pthreaddef.h
|
||||
index e01a0e6df72c089a..aa0709d0dc69f251 100644
|
||||
--- a/sysdeps/nios2/nptl/pthreaddef.h
|
||||
+++ b/sysdeps/nios2/nptl/pthreaddef.h
|
||||
@@ -28,8 +28,5 @@
|
||||
/* Minimal stack size after allocating thread descriptor and guard size. */
|
||||
#define MINIMAL_REST_STACK 2048
|
||||
|
||||
-/* Alignment requirement for TCB. */
|
||||
-#define TCB_ALIGNMENT 4
|
||||
-
|
||||
/* Location of current stack frame. */
|
||||
#define CURRENT_STACK_FRAME __builtin_frame_address (0)
|
||||
diff --git a/sysdeps/powerpc/nptl/pthreaddef.h b/sysdeps/powerpc/nptl/pthreaddef.h
|
||||
index ef5310e6315fde2c..117c35229ea68f48 100644
|
||||
--- a/sysdeps/powerpc/nptl/pthreaddef.h
|
||||
+++ b/sysdeps/powerpc/nptl/pthreaddef.h
|
||||
@@ -28,9 +28,6 @@
|
||||
/* Minimal stack size after allocating thread descriptor and guard size. */
|
||||
#define MINIMAL_REST_STACK 4096
|
||||
|
||||
-/* Alignment requirement for TCB. */
|
||||
-#define TCB_ALIGNMENT 16
|
||||
-
|
||||
|
||||
/* Location of current stack frame. */
|
||||
#define CURRENT_STACK_FRAME __builtin_frame_address (0)
|
||||
diff --git a/sysdeps/riscv/nptl/pthreaddef.h b/sysdeps/riscv/nptl/pthreaddef.h
|
||||
index 7bf93d6a63fdecd2..0f33cc48fe4fc728 100644
|
||||
--- a/sysdeps/riscv/nptl/pthreaddef.h
|
||||
+++ b/sysdeps/riscv/nptl/pthreaddef.h
|
||||
@@ -28,8 +28,5 @@
|
||||
/* Minimal stack size after allocating thread descriptor and guard size. */
|
||||
#define MINIMAL_REST_STACK 2048
|
||||
|
||||
-/* Alignment requirement for TCB. */
|
||||
-#define TCB_ALIGNMENT 16
|
||||
-
|
||||
/* Location of current stack frame. */
|
||||
#define CURRENT_STACK_FRAME __builtin_frame_address (0)
|
||||
diff --git a/sysdeps/s390/nptl/pthreaddef.h b/sysdeps/s390/nptl/pthreaddef.h
|
||||
index 091f82df24a4024c..0e32bd862f7fea48 100644
|
||||
--- a/sysdeps/s390/nptl/pthreaddef.h
|
||||
+++ b/sysdeps/s390/nptl/pthreaddef.h
|
||||
@@ -28,9 +28,6 @@
|
||||
/* Minimal stack size after allocating thread descriptor and guard size. */
|
||||
#define MINIMAL_REST_STACK 2048
|
||||
|
||||
-/* Alignment requirement for TCB. */
|
||||
-#define TCB_ALIGNMENT 16
|
||||
-
|
||||
|
||||
/* Location of current stack frame. */
|
||||
#define CURRENT_STACK_FRAME __builtin_frame_address (0)
|
||||
diff --git a/sysdeps/sh/nptl/pthreaddef.h b/sysdeps/sh/nptl/pthreaddef.h
|
||||
index 3fa3d189ef969c90..f4e3a290df4ee6e6 100644
|
||||
--- a/sysdeps/sh/nptl/pthreaddef.h
|
||||
+++ b/sysdeps/sh/nptl/pthreaddef.h
|
||||
@@ -29,9 +29,6 @@
|
||||
/* Minimal stack size after allocating thread descriptor and guard size. */
|
||||
#define MINIMAL_REST_STACK 2048
|
||||
|
||||
-/* Alignment requirement for TCB. */
|
||||
-#define TCB_ALIGNMENT 8
|
||||
-
|
||||
|
||||
/* Location of current stack frame. */
|
||||
#define CURRENT_STACK_FRAME __builtin_frame_address (0)
|
||||
diff --git a/sysdeps/sparc/sparc32/pthreaddef.h b/sysdeps/sparc/sparc32/pthreaddef.h
|
||||
index 6526fb3d6e7e1448..7a0a04789dac478e 100644
|
||||
--- a/sysdeps/sparc/sparc32/pthreaddef.h
|
||||
+++ b/sysdeps/sparc/sparc32/pthreaddef.h
|
||||
@@ -27,9 +27,6 @@
|
||||
/* Minimal stack size after allocating thread descriptor and guard size. */
|
||||
#define MINIMAL_REST_STACK 2048
|
||||
|
||||
-/* Alignment requirement for TCB. */
|
||||
-#define TCB_ALIGNMENT 16
|
||||
-
|
||||
|
||||
/* Location of current stack frame. */
|
||||
#define CURRENT_STACK_FRAME (stack_pointer + (2 * 64))
|
||||
diff --git a/sysdeps/sparc/sparc64/pthreaddef.h b/sysdeps/sparc/sparc64/pthreaddef.h
|
||||
index 3da9d7afc8054598..103842856d40432b 100644
|
||||
--- a/sysdeps/sparc/sparc64/pthreaddef.h
|
||||
+++ b/sysdeps/sparc/sparc64/pthreaddef.h
|
||||
@@ -27,10 +27,6 @@
|
||||
/* Minimal stack size after allocating thread descriptor and guard size. */
|
||||
#define MINIMAL_REST_STACK 4096
|
||||
|
||||
-/* Alignment requirement for TCB. */
|
||||
-#define TCB_ALIGNMENT 16
|
||||
-
|
||||
-
|
||||
/* Location of current stack frame. */
|
||||
#define CURRENT_STACK_FRAME (stack_pointer + (2 * 128))
|
||||
register char *stack_pointer __asm__("%sp");
|
@ -0,0 +1,150 @@
|
||||
commit 4fb4e7e821e36180835bf88e363f9f13b5797e3a
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Sun Dec 5 13:50:17 2021 +0100
|
||||
|
||||
csu: Always use __executable_start in gmon-start.c
|
||||
|
||||
Current binutils defines __executable_start as the lowest text
|
||||
address, so using the entry point address as a fallback is no
|
||||
longer necessary. As a result, overriding <entry.h> is only
|
||||
necessary if the entry point is not called _start.
|
||||
|
||||
The previous approach to define __ASSEMBLY__ to suppress the
|
||||
declaration breaks if headers included by <entry.h> are not
|
||||
compatible with __ASSEMBLY__. This happens with rseq integration
|
||||
because it is necessary to include kernel headers in more places.
|
||||
|
||||
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
||||
|
||||
diff --git a/csu/gmon-start.c b/csu/gmon-start.c
|
||||
index 344606a676c188d4..260c7613e291a32d 100644
|
||||
--- a/csu/gmon-start.c
|
||||
+++ b/csu/gmon-start.c
|
||||
@@ -38,32 +38,12 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <elf-initfini.h>
|
||||
-#define __ASSEMBLY__
|
||||
-#include <entry.h>
|
||||
-
|
||||
-/* Beginning and end of our code segment. We cannot declare them
|
||||
- as the external functions since we want the addresses of those
|
||||
- labels. Taking the address of a function may have different
|
||||
- meanings on different platforms. */
|
||||
-#ifdef ENTRY_POINT_DECL
|
||||
-ENTRY_POINT_DECL(extern)
|
||||
-#else
|
||||
-extern char ENTRY_POINT[];
|
||||
-#endif
|
||||
-extern char etext[];
|
||||
|
||||
/* Use __executable_start as the lowest address to keep profiling records
|
||||
if it provided by the linker. */
|
||||
-extern const char executable_start[] asm ("__executable_start")
|
||||
- __attribute__ ((weak, visibility ("hidden")));
|
||||
+extern const char __executable_start[] __attribute__ ((visibility ("hidden")));
|
||||
|
||||
-#ifndef TEXT_START
|
||||
-# ifdef ENTRY_POINT_DECL
|
||||
-# define TEXT_START ENTRY_POINT
|
||||
-# else
|
||||
-# define TEXT_START &ENTRY_POINT
|
||||
-# endif
|
||||
-#endif
|
||||
+extern char etext[];
|
||||
|
||||
#if !ELF_INITFINI
|
||||
/* Instead of defining __gmon_start__ globally in gcrt1.o, we make it
|
||||
@@ -97,10 +77,7 @@ __gmon_start__ (void)
|
||||
called = 1;
|
||||
|
||||
/* Start keeping profiling records. */
|
||||
- if (&executable_start != NULL)
|
||||
- __monstartup ((u_long) &executable_start, (u_long) &etext);
|
||||
- else
|
||||
- __monstartup ((u_long) TEXT_START, (u_long) &etext);
|
||||
+ __monstartup ((u_long) &__executable_start, (u_long) &etext);
|
||||
|
||||
/* Call _mcleanup before exiting; it will write out gmon.out from the
|
||||
collected data. */
|
||||
diff --git a/sysdeps/hppa/entry.h b/sysdeps/hppa/entry.h
|
||||
deleted file mode 100644
|
||||
index 5ea5b47448ceb2e7..0000000000000000
|
||||
--- a/sysdeps/hppa/entry.h
|
||||
+++ /dev/null
|
||||
@@ -1,13 +0,0 @@
|
||||
-#ifndef __ASSEMBLY__
|
||||
-extern void _start (void);
|
||||
-#endif
|
||||
-
|
||||
-/* Lives in libgcc.so and canonicalizes function pointers for comparison. */
|
||||
-extern unsigned int __canonicalize_funcptr_for_compare (unsigned int fptr);
|
||||
-
|
||||
-/* The function's entry point is stored in the first word of the
|
||||
- function descriptor (plabel) of _start(). */
|
||||
-#define ENTRY_POINT __canonicalize_funcptr_for_compare((unsigned int)_start)
|
||||
-
|
||||
-/* We have to provide a special declaration. */
|
||||
-#define ENTRY_POINT_DECL(class) class void _start (void);
|
||||
diff --git a/sysdeps/ia64/entry.h b/sysdeps/ia64/entry.h
|
||||
deleted file mode 100644
|
||||
index e11b49fc53602eb8..0000000000000000
|
||||
--- a/sysdeps/ia64/entry.h
|
||||
+++ /dev/null
|
||||
@@ -1,13 +0,0 @@
|
||||
-#include <link.h>
|
||||
-#include <dl-fptr.h>
|
||||
-
|
||||
-#ifndef __ASSEMBLY__
|
||||
-extern void _start (void);
|
||||
-#endif
|
||||
-
|
||||
-/* The function's entry point is stored in the first word of the
|
||||
- function descriptor (plabel) of _start(). */
|
||||
-#define ENTRY_POINT ELF_PTR_TO_FDESC (_start)->ip
|
||||
-
|
||||
-/* We have to provide a special declaration. */
|
||||
-#define ENTRY_POINT_DECL(class) class void _start (void);
|
||||
diff --git a/sysdeps/powerpc/powerpc64/entry.h b/sysdeps/powerpc/powerpc64/entry.h
|
||||
deleted file mode 100644
|
||||
index 99c81cb9820d188d..0000000000000000
|
||||
--- a/sysdeps/powerpc/powerpc64/entry.h
|
||||
+++ /dev/null
|
||||
@@ -1,37 +0,0 @@
|
||||
-/* Finding the entry point and start of text. PowerPC64 version.
|
||||
- Copyright (C) 2002-2021 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/>. */
|
||||
-
|
||||
-
|
||||
-#ifndef __ASSEMBLY__
|
||||
-extern void _start (void);
|
||||
-#endif
|
||||
-
|
||||
-#define ENTRY_POINT _start
|
||||
-
|
||||
-#if _CALL_ELF != 2
|
||||
-/* We have to provide a special declaration. */
|
||||
-#define ENTRY_POINT_DECL(class) class void _start (void);
|
||||
-
|
||||
-/* Use the address of ._start as the lowest address for which we need
|
||||
- to keep profiling records. We can't copy the ia64 scheme as our
|
||||
- entry poiny address is really the address of the function
|
||||
- descriptor, not the actual function entry. */
|
||||
-#define TEXT_START \
|
||||
- ({ extern unsigned long int _start_as_data[] asm ("_start"); \
|
||||
- _start_as_data[0]; })
|
||||
-#endif
|
@ -0,0 +1,130 @@
|
||||
commit 8dbeb0561eeb876f557ac9eef5721912ec074ea5
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu Dec 9 09:49:32 2021 +0100
|
||||
|
||||
nptl: Add <thread_pointer.h> for defining __thread_pointer
|
||||
|
||||
<tls.h> already contains a definition that is quite similar,
|
||||
but it is not consistent across architectures.
|
||||
|
||||
Only architectures for which rseq support is added are covered.
|
||||
|
||||
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||
|
||||
diff --git a/sysdeps/nptl/thread_pointer.h b/sysdeps/nptl/thread_pointer.h
|
||||
new file mode 100644
|
||||
index 0000000000000000..92f2f3093eba55bb
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/nptl/thread_pointer.h
|
||||
@@ -0,0 +1,28 @@
|
||||
+/* __thread_pointer definition. Generic version.
|
||||
+ Copyright (C) 2021 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/>. */
|
||||
+
|
||||
+#ifndef _SYS_THREAD_POINTER_H
|
||||
+#define _SYS_THREAD_POINTER_H
|
||||
+
|
||||
+static inline void *
|
||||
+__thread_pointer (void)
|
||||
+{
|
||||
+ return __builtin_thread_pointer ();
|
||||
+}
|
||||
+
|
||||
+#endif /* _SYS_THREAD_POINTER_H */
|
||||
diff --git a/sysdeps/powerpc/nptl/thread_pointer.h b/sysdeps/powerpc/nptl/thread_pointer.h
|
||||
new file mode 100644
|
||||
index 0000000000000000..8fd5ba671f6f5e64
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/powerpc/nptl/thread_pointer.h
|
||||
@@ -0,0 +1,33 @@
|
||||
+/* __thread_pointer definition. powerpc version.
|
||||
+ Copyright (C) 2021 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/>. */
|
||||
+
|
||||
+#ifndef _SYS_THREAD_POINTER_H
|
||||
+#define _SYS_THREAD_POINTER_H
|
||||
+
|
||||
+static inline void *
|
||||
+__thread_pointer (void)
|
||||
+{
|
||||
+#ifdef __powerpc64__
|
||||
+ register void *__result asm ("r13");
|
||||
+#else
|
||||
+ register void *__result asm ("r2");
|
||||
+#endif
|
||||
+ return __result;
|
||||
+}
|
||||
+
|
||||
+#endif /* _SYS_THREAD_POINTER_H */
|
||||
diff --git a/sysdeps/x86/nptl/thread_pointer.h b/sysdeps/x86/nptl/thread_pointer.h
|
||||
new file mode 100644
|
||||
index 0000000000000000..6b71b6f7e1401e4c
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/x86/nptl/thread_pointer.h
|
||||
@@ -0,0 +1,38 @@
|
||||
+/* __thread_pointer definition. x86 version.
|
||||
+ Copyright (C) 2021 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/>. */
|
||||
+
|
||||
+#ifndef _SYS_THREAD_POINTER_H
|
||||
+#define _SYS_THREAD_POINTER_H
|
||||
+
|
||||
+static inline void *
|
||||
+__thread_pointer (void)
|
||||
+{
|
||||
+#if __GNUC_PREREQ (11, 1)
|
||||
+ return __builtin_thread_pointer ();
|
||||
+#else
|
||||
+ void *__result;
|
||||
+# ifdef __x86_64__
|
||||
+ __asm__ ("mov %%fs:0, %0" : "=r" (__result));
|
||||
+# else
|
||||
+ __asm__ ("mov %%gs:0, %0" : "=r" (__result));
|
||||
+# endif
|
||||
+ return __result;
|
||||
+#endif /* !GCC 11 */
|
||||
+}
|
||||
+
|
||||
+#endif /* _SYS_THREAD_POINTER_H */
|
@ -0,0 +1,904 @@
|
||||
commit ce2248ab91b2ea09a378f85012f251f31ac65e31
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu Dec 9 09:49:32 2021 +0100
|
||||
|
||||
nptl: Introduce <tcb-access.h> for THREAD_* accessors
|
||||
|
||||
These are common between most architectures. Only the x86 targets
|
||||
are outliers.
|
||||
|
||||
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||
|
||||
diff --git a/sysdeps/aarch64/nptl/tls.h b/sysdeps/aarch64/nptl/tls.h
|
||||
index 6e896207a659514f..cd9abb5d1d073593 100644
|
||||
--- a/sysdeps/aarch64/nptl/tls.h
|
||||
+++ b/sysdeps/aarch64/nptl/tls.h
|
||||
@@ -98,15 +98,7 @@ typedef struct
|
||||
# define DB_THREAD_SELF \
|
||||
CONST_THREAD_AREA (64, sizeof (struct pthread))
|
||||
|
||||
-/* Access to data in the thread descriptor is easy. */
|
||||
-# define THREAD_GETMEM(descr, member) \
|
||||
- descr->member
|
||||
-# define THREAD_GETMEM_NC(descr, member, idx) \
|
||||
- descr->member[idx]
|
||||
-# define THREAD_SETMEM(descr, member, value) \
|
||||
- descr->member = (value)
|
||||
-# define THREAD_SETMEM_NC(descr, member, idx, value) \
|
||||
- descr->member[idx] = (value)
|
||||
+# include <tcb-access.h>
|
||||
|
||||
/* Get and set the global scope generation counter in struct pthread. */
|
||||
# define THREAD_GSCOPE_IN_TCB 1
|
||||
diff --git a/sysdeps/alpha/nptl/tls.h b/sysdeps/alpha/nptl/tls.h
|
||||
index 4dbccc5249539325..5f4843b28e7f1ad1 100644
|
||||
--- a/sysdeps/alpha/nptl/tls.h
|
||||
+++ b/sysdeps/alpha/nptl/tls.h
|
||||
@@ -92,15 +92,7 @@ typedef struct
|
||||
# define DB_THREAD_SELF \
|
||||
REGISTER (64, 64, 32 * 8, -sizeof (struct pthread))
|
||||
|
||||
-/* Access to data in the thread descriptor is easy. */
|
||||
-#define THREAD_GETMEM(descr, member) \
|
||||
- descr->member
|
||||
-#define THREAD_GETMEM_NC(descr, member, idx) \
|
||||
- descr->member[idx]
|
||||
-#define THREAD_SETMEM(descr, member, value) \
|
||||
- descr->member = (value)
|
||||
-#define THREAD_SETMEM_NC(descr, member, idx, value) \
|
||||
- descr->member[idx] = (value)
|
||||
+# include <tcb-access.h>
|
||||
|
||||
/* Get and set the global scope generation counter in struct pthread. */
|
||||
#define THREAD_GSCOPE_IN_TCB 1
|
||||
diff --git a/sysdeps/arc/nptl/tls.h b/sysdeps/arc/nptl/tls.h
|
||||
index 95300fdd2159dc53..d9ada2f38089e6cd 100644
|
||||
--- a/sysdeps/arc/nptl/tls.h
|
||||
+++ b/sysdeps/arc/nptl/tls.h
|
||||
@@ -100,15 +100,7 @@ typedef struct
|
||||
# define DB_THREAD_SELF \
|
||||
CONST_THREAD_AREA (32, sizeof (struct pthread))
|
||||
|
||||
-/* Access to data in the thread descriptor is easy. */
|
||||
-# define THREAD_GETMEM(descr, member) \
|
||||
- descr->member
|
||||
-# define THREAD_GETMEM_NC(descr, member, idx) \
|
||||
- descr->member[idx]
|
||||
-# define THREAD_SETMEM(descr, member, value) \
|
||||
- descr->member = (value)
|
||||
-# define THREAD_SETMEM_NC(descr, member, idx, value) \
|
||||
- descr->member[idx] = (value)
|
||||
+# include <tcb-access.h>
|
||||
|
||||
/* Get and set the global scope generation counter in struct pthread. */
|
||||
#define THREAD_GSCOPE_IN_TCB 1
|
||||
diff --git a/sysdeps/arm/nptl/tls.h b/sysdeps/arm/nptl/tls.h
|
||||
index 1bd11307ce0a7f0a..354aae3318291395 100644
|
||||
--- a/sysdeps/arm/nptl/tls.h
|
||||
+++ b/sysdeps/arm/nptl/tls.h
|
||||
@@ -89,15 +89,7 @@ typedef struct
|
||||
# define DB_THREAD_SELF \
|
||||
CONST_THREAD_AREA (32, sizeof (struct pthread))
|
||||
|
||||
-/* Access to data in the thread descriptor is easy. */
|
||||
-#define THREAD_GETMEM(descr, member) \
|
||||
- descr->member
|
||||
-#define THREAD_GETMEM_NC(descr, member, idx) \
|
||||
- descr->member[idx]
|
||||
-#define THREAD_SETMEM(descr, member, value) \
|
||||
- descr->member = (value)
|
||||
-#define THREAD_SETMEM_NC(descr, member, idx, value) \
|
||||
- descr->member[idx] = (value)
|
||||
+# include <tcb-access.h>
|
||||
|
||||
/* Get and set the global scope generation counter in struct pthread. */
|
||||
#define THREAD_GSCOPE_IN_TCB 1
|
||||
diff --git a/sysdeps/csky/nptl/tls.h b/sysdeps/csky/nptl/tls.h
|
||||
index 7a234041ed0bff39..f3fa3fcb02748776 100644
|
||||
--- a/sysdeps/csky/nptl/tls.h
|
||||
+++ b/sysdeps/csky/nptl/tls.h
|
||||
@@ -116,15 +116,7 @@ typedef struct
|
||||
# define DB_THREAD_SELF \
|
||||
CONST_THREAD_AREA (32, sizeof (struct pthread))
|
||||
|
||||
-/* Access to data in the thread descriptor is easy. */
|
||||
-# define THREAD_GETMEM(descr, member) \
|
||||
- descr->member
|
||||
-# define THREAD_GETMEM_NC(descr, member, idx) \
|
||||
- descr->member[idx]
|
||||
-# define THREAD_SETMEM(descr, member, value) \
|
||||
- descr->member = (value)
|
||||
-# define THREAD_SETMEM_NC(descr, member, idx, value) \
|
||||
- descr->member[idx] = (value)
|
||||
+# include <tcb-access.h>
|
||||
|
||||
/* Get and set the global scope generation counter in struct pthread. */
|
||||
# define THREAD_GSCOPE_IN_TCB 1
|
||||
diff --git a/sysdeps/hppa/nptl/tls.h b/sysdeps/hppa/nptl/tls.h
|
||||
index 857003a7d35073eb..f0e274c45fb5e91e 100644
|
||||
--- a/sysdeps/hppa/nptl/tls.h
|
||||
+++ b/sysdeps/hppa/nptl/tls.h
|
||||
@@ -107,15 +107,7 @@ typedef struct
|
||||
# define DB_THREAD_SELF \
|
||||
REGISTER (32, 32, 53 * 4, -sizeof (struct pthread))
|
||||
|
||||
-/* Access to data in the thread descriptor is easy. */
|
||||
-# define THREAD_GETMEM(descr, member) \
|
||||
- descr->member
|
||||
-# define THREAD_GETMEM_NC(descr, member, idx) \
|
||||
- descr->member[idx]
|
||||
-# define THREAD_SETMEM(descr, member, value) \
|
||||
- descr->member = (value)
|
||||
-# define THREAD_SETMEM_NC(descr, member, idx, value) \
|
||||
- descr->member[idx] = (value)
|
||||
+# include <tcb-access.h>
|
||||
|
||||
static inline struct pthread *__get_cr27(void)
|
||||
{
|
||||
diff --git a/sysdeps/i386/nptl/tcb-access.h b/sysdeps/i386/nptl/tcb-access.h
|
||||
new file mode 100644
|
||||
index 0000000000000000..6c6d561e394817c7
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/i386/nptl/tcb-access.h
|
||||
@@ -0,0 +1,123 @@
|
||||
+/* THREAD_* accessors. i386 version.
|
||||
+ Copyright (C) 2002-2021 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/>. */
|
||||
+
|
||||
+/* Read member of the thread descriptor directly. */
|
||||
+#define THREAD_GETMEM(descr, member) \
|
||||
+ ({ __typeof (descr->member) __value; \
|
||||
+ _Static_assert (sizeof (__value) == 1 \
|
||||
+ || sizeof (__value) == 4 \
|
||||
+ || sizeof (__value) == 8, \
|
||||
+ "size of per-thread data"); \
|
||||
+ if (sizeof (__value) == 1) \
|
||||
+ asm volatile ("movb %%gs:%P2,%b0" \
|
||||
+ : "=q" (__value) \
|
||||
+ : "0" (0), "i" (offsetof (struct pthread, member))); \
|
||||
+ else if (sizeof (__value) == 4) \
|
||||
+ asm volatile ("movl %%gs:%P1,%0" \
|
||||
+ : "=r" (__value) \
|
||||
+ : "i" (offsetof (struct pthread, member))); \
|
||||
+ else /* 8 */ \
|
||||
+ { \
|
||||
+ asm volatile ("movl %%gs:%P1,%%eax\n\t" \
|
||||
+ "movl %%gs:%P2,%%edx" \
|
||||
+ : "=A" (__value) \
|
||||
+ : "i" (offsetof (struct pthread, member)), \
|
||||
+ "i" (offsetof (struct pthread, member) + 4)); \
|
||||
+ } \
|
||||
+ __value; })
|
||||
+
|
||||
+
|
||||
+/* Same as THREAD_GETMEM, but the member offset can be non-constant. */
|
||||
+#define THREAD_GETMEM_NC(descr, member, idx) \
|
||||
+ ({ __typeof (descr->member[0]) __value; \
|
||||
+ _Static_assert (sizeof (__value) == 1 \
|
||||
+ || sizeof (__value) == 4 \
|
||||
+ || sizeof (__value) == 8, \
|
||||
+ "size of per-thread data"); \
|
||||
+ if (sizeof (__value) == 1) \
|
||||
+ asm volatile ("movb %%gs:%P2(%3),%b0" \
|
||||
+ : "=q" (__value) \
|
||||
+ : "0" (0), "i" (offsetof (struct pthread, member[0])), \
|
||||
+ "r" (idx)); \
|
||||
+ else if (sizeof (__value) == 4) \
|
||||
+ asm volatile ("movl %%gs:%P1(,%2,4),%0" \
|
||||
+ : "=r" (__value) \
|
||||
+ : "i" (offsetof (struct pthread, member[0])), \
|
||||
+ "r" (idx)); \
|
||||
+ else /* 8 */ \
|
||||
+ { \
|
||||
+ asm volatile ("movl %%gs:%P1(,%2,8),%%eax\n\t" \
|
||||
+ "movl %%gs:4+%P1(,%2,8),%%edx" \
|
||||
+ : "=&A" (__value) \
|
||||
+ : "i" (offsetof (struct pthread, member[0])), \
|
||||
+ "r" (idx)); \
|
||||
+ } \
|
||||
+ __value; })
|
||||
+
|
||||
+
|
||||
+
|
||||
+/* Set member of the thread descriptor directly. */
|
||||
+#define THREAD_SETMEM(descr, member, value) \
|
||||
+ ({ \
|
||||
+ _Static_assert (sizeof (descr->member) == 1 \
|
||||
+ || sizeof (descr->member) == 4 \
|
||||
+ || sizeof (descr->member) == 8, \
|
||||
+ "size of per-thread data"); \
|
||||
+ if (sizeof (descr->member) == 1) \
|
||||
+ asm volatile ("movb %b0,%%gs:%P1" : \
|
||||
+ : "iq" (value), \
|
||||
+ "i" (offsetof (struct pthread, member))); \
|
||||
+ else if (sizeof (descr->member) == 4) \
|
||||
+ asm volatile ("movl %0,%%gs:%P1" : \
|
||||
+ : "ir" (value), \
|
||||
+ "i" (offsetof (struct pthread, member))); \
|
||||
+ else /* 8 */ \
|
||||
+ { \
|
||||
+ asm volatile ("movl %%eax,%%gs:%P1\n\t" \
|
||||
+ "movl %%edx,%%gs:%P2" : \
|
||||
+ : "A" ((uint64_t) cast_to_integer (value)), \
|
||||
+ "i" (offsetof (struct pthread, member)), \
|
||||
+ "i" (offsetof (struct pthread, member) + 4)); \
|
||||
+ }})
|
||||
+
|
||||
+
|
||||
+/* Same as THREAD_SETMEM, but the member offset can be non-constant. */
|
||||
+#define THREAD_SETMEM_NC(descr, member, idx, value) \
|
||||
+ ({ \
|
||||
+ _Static_assert (sizeof (descr->member[0]) == 1 \
|
||||
+ || sizeof (descr->member[0]) == 4 \
|
||||
+ || sizeof (descr->member[0]) == 8, \
|
||||
+ "size of per-thread data"); \
|
||||
+ if (sizeof (descr->member[0]) == 1) \
|
||||
+ asm volatile ("movb %b0,%%gs:%P1(%2)" : \
|
||||
+ : "iq" (value), \
|
||||
+ "i" (offsetof (struct pthread, member)), \
|
||||
+ "r" (idx)); \
|
||||
+ else if (sizeof (descr->member[0]) == 4) \
|
||||
+ asm volatile ("movl %0,%%gs:%P1(,%2,4)" : \
|
||||
+ : "ir" (value), \
|
||||
+ "i" (offsetof (struct pthread, member)), \
|
||||
+ "r" (idx)); \
|
||||
+ else /* 8 */ \
|
||||
+ { \
|
||||
+ asm volatile ("movl %%eax,%%gs:%P1(,%2,8)\n\t" \
|
||||
+ "movl %%edx,%%gs:4+%P1(,%2,8)" : \
|
||||
+ : "A" ((uint64_t) cast_to_integer (value)), \
|
||||
+ "i" (offsetof (struct pthread, member)), \
|
||||
+ "r" (idx)); \
|
||||
+ }})
|
||||
diff --git a/sysdeps/i386/nptl/tls.h b/sysdeps/i386/nptl/tls.h
|
||||
index 86ee1ef30270f960..111c9ee59df30bc3 100644
|
||||
--- a/sysdeps/i386/nptl/tls.h
|
||||
+++ b/sysdeps/i386/nptl/tls.h
|
||||
@@ -250,113 +250,7 @@ tls_fill_user_desc (union user_desc_init *desc,
|
||||
REGISTER_THREAD_AREA (32, offsetof (struct user_regs_struct, xgs), 3) \
|
||||
REGISTER_THREAD_AREA (64, 26 * 8, 3) /* x86-64's user_regs_struct->gs */
|
||||
|
||||
-
|
||||
-/* Read member of the thread descriptor directly. */
|
||||
-# define THREAD_GETMEM(descr, member) \
|
||||
- ({ __typeof (descr->member) __value; \
|
||||
- _Static_assert (sizeof (__value) == 1 \
|
||||
- || sizeof (__value) == 4 \
|
||||
- || sizeof (__value) == 8, \
|
||||
- "size of per-thread data"); \
|
||||
- if (sizeof (__value) == 1) \
|
||||
- asm volatile ("movb %%gs:%P2,%b0" \
|
||||
- : "=q" (__value) \
|
||||
- : "0" (0), "i" (offsetof (struct pthread, member))); \
|
||||
- else if (sizeof (__value) == 4) \
|
||||
- asm volatile ("movl %%gs:%P1,%0" \
|
||||
- : "=r" (__value) \
|
||||
- : "i" (offsetof (struct pthread, member))); \
|
||||
- else /* 8 */ \
|
||||
- { \
|
||||
- asm volatile ("movl %%gs:%P1,%%eax\n\t" \
|
||||
- "movl %%gs:%P2,%%edx" \
|
||||
- : "=A" (__value) \
|
||||
- : "i" (offsetof (struct pthread, member)), \
|
||||
- "i" (offsetof (struct pthread, member) + 4)); \
|
||||
- } \
|
||||
- __value; })
|
||||
-
|
||||
-
|
||||
-/* Same as THREAD_GETMEM, but the member offset can be non-constant. */
|
||||
-# define THREAD_GETMEM_NC(descr, member, idx) \
|
||||
- ({ __typeof (descr->member[0]) __value; \
|
||||
- _Static_assert (sizeof (__value) == 1 \
|
||||
- || sizeof (__value) == 4 \
|
||||
- || sizeof (__value) == 8, \
|
||||
- "size of per-thread data"); \
|
||||
- if (sizeof (__value) == 1) \
|
||||
- asm volatile ("movb %%gs:%P2(%3),%b0" \
|
||||
- : "=q" (__value) \
|
||||
- : "0" (0), "i" (offsetof (struct pthread, member[0])), \
|
||||
- "r" (idx)); \
|
||||
- else if (sizeof (__value) == 4) \
|
||||
- asm volatile ("movl %%gs:%P1(,%2,4),%0" \
|
||||
- : "=r" (__value) \
|
||||
- : "i" (offsetof (struct pthread, member[0])), \
|
||||
- "r" (idx)); \
|
||||
- else /* 8 */ \
|
||||
- { \
|
||||
- asm volatile ("movl %%gs:%P1(,%2,8),%%eax\n\t" \
|
||||
- "movl %%gs:4+%P1(,%2,8),%%edx" \
|
||||
- : "=&A" (__value) \
|
||||
- : "i" (offsetof (struct pthread, member[0])), \
|
||||
- "r" (idx)); \
|
||||
- } \
|
||||
- __value; })
|
||||
-
|
||||
-
|
||||
-
|
||||
-/* Set member of the thread descriptor directly. */
|
||||
-# define THREAD_SETMEM(descr, member, value) \
|
||||
- ({ \
|
||||
- _Static_assert (sizeof (descr->member) == 1 \
|
||||
- || sizeof (descr->member) == 4 \
|
||||
- || sizeof (descr->member) == 8, \
|
||||
- "size of per-thread data"); \
|
||||
- if (sizeof (descr->member) == 1) \
|
||||
- asm volatile ("movb %b0,%%gs:%P1" : \
|
||||
- : "iq" (value), \
|
||||
- "i" (offsetof (struct pthread, member))); \
|
||||
- else if (sizeof (descr->member) == 4) \
|
||||
- asm volatile ("movl %0,%%gs:%P1" : \
|
||||
- : "ir" (value), \
|
||||
- "i" (offsetof (struct pthread, member))); \
|
||||
- else /* 8 */ \
|
||||
- { \
|
||||
- asm volatile ("movl %%eax,%%gs:%P1\n\t" \
|
||||
- "movl %%edx,%%gs:%P2" : \
|
||||
- : "A" ((uint64_t) cast_to_integer (value)), \
|
||||
- "i" (offsetof (struct pthread, member)), \
|
||||
- "i" (offsetof (struct pthread, member) + 4)); \
|
||||
- }})
|
||||
-
|
||||
-
|
||||
-/* Same as THREAD_SETMEM, but the member offset can be non-constant. */
|
||||
-# define THREAD_SETMEM_NC(descr, member, idx, value) \
|
||||
- ({ \
|
||||
- _Static_assert (sizeof (descr->member[0]) == 1 \
|
||||
- || sizeof (descr->member[0]) == 4 \
|
||||
- || sizeof (descr->member[0]) == 8, \
|
||||
- "size of per-thread data"); \
|
||||
- if (sizeof (descr->member[0]) == 1) \
|
||||
- asm volatile ("movb %b0,%%gs:%P1(%2)" : \
|
||||
- : "iq" (value), \
|
||||
- "i" (offsetof (struct pthread, member)), \
|
||||
- "r" (idx)); \
|
||||
- else if (sizeof (descr->member[0]) == 4) \
|
||||
- asm volatile ("movl %0,%%gs:%P1(,%2,4)" : \
|
||||
- : "ir" (value), \
|
||||
- "i" (offsetof (struct pthread, member)), \
|
||||
- "r" (idx)); \
|
||||
- else /* 8 */ \
|
||||
- { \
|
||||
- asm volatile ("movl %%eax,%%gs:%P1(,%2,8)\n\t" \
|
||||
- "movl %%edx,%%gs:4+%P1(,%2,8)" : \
|
||||
- : "A" ((uint64_t) cast_to_integer (value)), \
|
||||
- "i" (offsetof (struct pthread, member)), \
|
||||
- "r" (idx)); \
|
||||
- }})
|
||||
-
|
||||
+# include <tcb-access.h>
|
||||
|
||||
/* Set the stack guard field in TCB head. */
|
||||
#define THREAD_SET_STACK_GUARD(value) \
|
||||
diff --git a/sysdeps/ia64/nptl/tls.h b/sysdeps/ia64/nptl/tls.h
|
||||
index 66d9bf3189f0b727..26fe555cb4b5e164 100644
|
||||
--- a/sysdeps/ia64/nptl/tls.h
|
||||
+++ b/sysdeps/ia64/nptl/tls.h
|
||||
@@ -128,15 +128,7 @@ register struct pthread *__thread_self __asm__("r13");
|
||||
/* Magic for libthread_db to know how to do THREAD_SELF. */
|
||||
# define DB_THREAD_SELF REGISTER (64, 64, 13 * 8, -TLS_PRE_TCB_SIZE)
|
||||
|
||||
-/* Access to data in the thread descriptor is easy. */
|
||||
-#define THREAD_GETMEM(descr, member) \
|
||||
- descr->member
|
||||
-#define THREAD_GETMEM_NC(descr, member, idx) \
|
||||
- descr->member[idx]
|
||||
-#define THREAD_SETMEM(descr, member, value) \
|
||||
- descr->member = (value)
|
||||
-#define THREAD_SETMEM_NC(descr, member, idx, value) \
|
||||
- descr->member[idx] = (value)
|
||||
+# include <tcb-access.h>
|
||||
|
||||
/* Set the stack guard field in TCB head. */
|
||||
#define THREAD_SET_STACK_GUARD(value) \
|
||||
diff --git a/sysdeps/m68k/nptl/tls.h b/sysdeps/m68k/nptl/tls.h
|
||||
index cfcd6d2b7b59321c..9f562c38288df200 100644
|
||||
--- a/sysdeps/m68k/nptl/tls.h
|
||||
+++ b/sysdeps/m68k/nptl/tls.h
|
||||
@@ -118,15 +118,7 @@ extern void * __m68k_read_tp (void);
|
||||
# define DB_THREAD_SELF \
|
||||
CONST_THREAD_AREA (32, TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE)
|
||||
|
||||
-/* Access to data in the thread descriptor is easy. */
|
||||
-# define THREAD_GETMEM(descr, member) \
|
||||
- descr->member
|
||||
-# define THREAD_GETMEM_NC(descr, member, idx) \
|
||||
- descr->member[idx]
|
||||
-# define THREAD_SETMEM(descr, member, value) \
|
||||
- descr->member = (value)
|
||||
-# define THREAD_SETMEM_NC(descr, member, idx, value) \
|
||||
- descr->member[idx] = (value)
|
||||
+# include <tcb-access.h>
|
||||
|
||||
/* l_tls_offset == 0 is perfectly valid on M68K, so we have to use some
|
||||
different value to mean unset l_tls_offset. */
|
||||
diff --git a/sysdeps/microblaze/nptl/tls.h b/sysdeps/microblaze/nptl/tls.h
|
||||
index c93d90b11bfe4c74..bfa6efa78049bb2d 100644
|
||||
--- a/sysdeps/microblaze/nptl/tls.h
|
||||
+++ b/sysdeps/microblaze/nptl/tls.h
|
||||
@@ -100,20 +100,7 @@ typedef struct
|
||||
# define DB_THREAD_SELF \
|
||||
CONST_THREAD_AREA (32, sizeof (struct pthread))
|
||||
|
||||
-/* Read member of the thread descriptor directly. */
|
||||
-# define THREAD_GETMEM(descr, member) (descr->member)
|
||||
-
|
||||
-/* Same as THREAD_GETMEM, but the member offset can be non-constant. */
|
||||
-# define THREAD_GETMEM_NC(descr, member, idx) \
|
||||
- (descr->member[idx])
|
||||
-
|
||||
-/* Set member of the thread descriptor directly. */
|
||||
-# define THREAD_SETMEM(descr, member, value) \
|
||||
- (descr->member = (value))
|
||||
-
|
||||
-/* Same as THREAD_SETMEM, but the member offset can be non-constant. */
|
||||
-# define THREAD_SETMEM_NC(descr, member, idx, value) \
|
||||
- (descr->member[idx] = (value))
|
||||
+# include <tcb-access.h>
|
||||
|
||||
/* Get and set the global scope generation counter in struct pthread. */
|
||||
# define THREAD_GSCOPE_IN_TCB 1
|
||||
diff --git a/sysdeps/mips/nptl/tls.h b/sysdeps/mips/nptl/tls.h
|
||||
index c09f49071cf3b5b9..ef99aa646c898e76 100644
|
||||
--- a/sysdeps/mips/nptl/tls.h
|
||||
+++ b/sysdeps/mips/nptl/tls.h
|
||||
@@ -144,14 +144,7 @@ typedef struct
|
||||
CONST_THREAD_AREA (32, TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE)
|
||||
|
||||
/* Access to data in the thread descriptor is easy. */
|
||||
-# define THREAD_GETMEM(descr, member) \
|
||||
- descr->member
|
||||
-# define THREAD_GETMEM_NC(descr, member, idx) \
|
||||
- descr->member[idx]
|
||||
-# define THREAD_SETMEM(descr, member, value) \
|
||||
- descr->member = (value)
|
||||
-# define THREAD_SETMEM_NC(descr, member, idx, value) \
|
||||
- descr->member[idx] = (value)
|
||||
+# include <tcb-access.h>
|
||||
|
||||
/* l_tls_offset == 0 is perfectly valid on MIPS, so we have to use some
|
||||
different value to mean unset l_tls_offset. */
|
||||
diff --git a/sysdeps/nios2/nptl/tls.h b/sysdeps/nios2/nptl/tls.h
|
||||
index 02a05b4e741092bf..7110cfccad7131f4 100644
|
||||
--- a/sysdeps/nios2/nptl/tls.h
|
||||
+++ b/sysdeps/nios2/nptl/tls.h
|
||||
@@ -112,15 +112,7 @@ register struct pthread *__thread_self __asm__("r23");
|
||||
# define DB_THREAD_SELF \
|
||||
REGISTER (32, 32, 23 * 4, -TLS_PRE_TCB_SIZE - TLS_TCB_OFFSET)
|
||||
|
||||
-/* Access to data in the thread descriptor is easy. */
|
||||
-# define THREAD_GETMEM(descr, member) \
|
||||
- descr->member
|
||||
-# define THREAD_GETMEM_NC(descr, member, idx) \
|
||||
- descr->member[idx]
|
||||
-# define THREAD_SETMEM(descr, member, value) \
|
||||
- descr->member = (value)
|
||||
-# define THREAD_SETMEM_NC(descr, member, idx, value) \
|
||||
- descr->member[idx] = (value)
|
||||
+# include <tcb-access.h>
|
||||
|
||||
# define THREAD_GET_POINTER_GUARD() \
|
||||
(((tcbhead_t *) (READ_THREAD_POINTER () \
|
||||
diff --git a/sysdeps/nptl/tcb-access.h b/sysdeps/nptl/tcb-access.h
|
||||
new file mode 100644
|
||||
index 0000000000000000..b4137b8ab8067915
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/nptl/tcb-access.h
|
||||
@@ -0,0 +1,30 @@
|
||||
+/* THREAD_* accessors. Generic version based on struct pthread pointers.
|
||||
+ Copyright (C) 2002-2021 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/>. */
|
||||
+
|
||||
+/* Note: These are for accessing the TCB of the *current* thread.
|
||||
+ descr can be disregarded on some targets as an optimization. See
|
||||
+ i386 for an example. */
|
||||
+
|
||||
+#define THREAD_GETMEM(descr, member) \
|
||||
+ descr->member
|
||||
+#define THREAD_GETMEM_NC(descr, member, idx) \
|
||||
+ descr->member[idx]
|
||||
+#define THREAD_SETMEM(descr, member, value) \
|
||||
+ descr->member = (value)
|
||||
+#define THREAD_SETMEM_NC(descr, member, idx, value) \
|
||||
+ descr->member[idx] = (value)
|
||||
diff --git a/sysdeps/powerpc/nptl/tls.h b/sysdeps/powerpc/nptl/tls.h
|
||||
index 6c779b6609147d54..110d085d30c86302 100644
|
||||
--- a/sysdeps/powerpc/nptl/tls.h
|
||||
+++ b/sysdeps/powerpc/nptl/tls.h
|
||||
@@ -176,20 +176,7 @@ typedef struct
|
||||
REGISTER (64, 64, PT_THREAD_POINTER * 8, \
|
||||
- TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE)
|
||||
|
||||
-/* Read member of the thread descriptor directly. */
|
||||
-# define THREAD_GETMEM(descr, member) ((void)(descr), (THREAD_SELF)->member)
|
||||
-
|
||||
-/* Same as THREAD_GETMEM, but the member offset can be non-constant. */
|
||||
-# define THREAD_GETMEM_NC(descr, member, idx) \
|
||||
- ((void)(descr), (THREAD_SELF)->member[idx])
|
||||
-
|
||||
-/* Set member of the thread descriptor directly. */
|
||||
-# define THREAD_SETMEM(descr, member, value) \
|
||||
- ((void)(descr), (THREAD_SELF)->member = (value))
|
||||
-
|
||||
-/* Same as THREAD_SETMEM, but the member offset can be non-constant. */
|
||||
-# define THREAD_SETMEM_NC(descr, member, idx, value) \
|
||||
- ((void)(descr), (THREAD_SELF)->member[idx] = (value))
|
||||
+# include <tcb-access.h>
|
||||
|
||||
/* Set the stack guard field in TCB head. */
|
||||
# define THREAD_SET_STACK_GUARD(value) \
|
||||
diff --git a/sysdeps/riscv/nptl/tls.h b/sysdeps/riscv/nptl/tls.h
|
||||
index 5350bcc0498bab69..bdc0a3a6f91b51e8 100644
|
||||
--- a/sysdeps/riscv/nptl/tls.h
|
||||
+++ b/sysdeps/riscv/nptl/tls.h
|
||||
@@ -105,14 +105,7 @@ typedef struct
|
||||
REGISTER (64, 64, 4 * 8, - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE)
|
||||
|
||||
/* Access to data in the thread descriptor is easy. */
|
||||
-# define THREAD_GETMEM(descr, member) \
|
||||
- descr->member
|
||||
-# define THREAD_GETMEM_NC(descr, member, idx) \
|
||||
- descr->member[idx]
|
||||
-# define THREAD_SETMEM(descr, member, value) \
|
||||
- descr->member = (value)
|
||||
-# define THREAD_SETMEM_NC(descr, member, idx, value) \
|
||||
- descr->member[idx] = (value)
|
||||
+# include <tcb-access.h>
|
||||
|
||||
/* l_tls_offset == 0 is perfectly valid, so we have to use some different
|
||||
value to mean unset l_tls_offset. */
|
||||
diff --git a/sysdeps/s390/nptl/tls.h b/sysdeps/s390/nptl/tls.h
|
||||
index efb52515e05c06a9..2cdd18eb2907c060 100644
|
||||
--- a/sysdeps/s390/nptl/tls.h
|
||||
+++ b/sysdeps/s390/nptl/tls.h
|
||||
@@ -135,15 +135,7 @@ typedef struct
|
||||
# define DB_THREAD_SELF REGISTER (32, 32, 18 * 4, 0) \
|
||||
REGISTER (64, __WORDSIZE, 18 * 8, 0)
|
||||
|
||||
-/* Access to data in the thread descriptor is easy. */
|
||||
-#define THREAD_GETMEM(descr, member) \
|
||||
- descr->member
|
||||
-#define THREAD_GETMEM_NC(descr, member, idx) \
|
||||
- descr->member[idx]
|
||||
-#define THREAD_SETMEM(descr, member, value) \
|
||||
- descr->member = (value)
|
||||
-#define THREAD_SETMEM_NC(descr, member, idx, value) \
|
||||
- descr->member[idx] = (value)
|
||||
+# include <tcb-access.h>
|
||||
|
||||
/* Set the stack guard field in TCB head. */
|
||||
#define THREAD_SET_STACK_GUARD(value) \
|
||||
diff --git a/sysdeps/sh/nptl/tls.h b/sysdeps/sh/nptl/tls.h
|
||||
index ac3c9a9e856ee686..390640020e45f716 100644
|
||||
--- a/sysdeps/sh/nptl/tls.h
|
||||
+++ b/sysdeps/sh/nptl/tls.h
|
||||
@@ -113,19 +113,7 @@ typedef struct
|
||||
# define DB_THREAD_SELF \
|
||||
REGISTER (32, 32, REG_GBR * 4, -sizeof (struct pthread))
|
||||
|
||||
-/* Read member of the thread descriptor directly. */
|
||||
-# define THREAD_GETMEM(descr, member) (descr->member)
|
||||
-
|
||||
-/* Same as THREAD_GETMEM, but the member offset can be non-constant. */
|
||||
-# define THREAD_GETMEM_NC(descr, member, idx) (descr->member[idx])
|
||||
-
|
||||
-/* Set member of the thread descriptor directly. */
|
||||
-# define THREAD_SETMEM(descr, member, value) \
|
||||
- descr->member = (value)
|
||||
-
|
||||
-/* Same as THREAD_SETMEM, but the member offset can be non-constant. */
|
||||
-# define THREAD_SETMEM_NC(descr, member, idx, value) \
|
||||
- descr->member[idx] = (value)
|
||||
+# include <tcb-access.h>
|
||||
|
||||
#define THREAD_GET_POINTER_GUARD() \
|
||||
({ tcbhead_t *__tcbp; \
|
||||
diff --git a/sysdeps/sparc/nptl/tls.h b/sysdeps/sparc/nptl/tls.h
|
||||
index dd1eb82a595619a9..376d729989e35660 100644
|
||||
--- a/sysdeps/sparc/nptl/tls.h
|
||||
+++ b/sysdeps/sparc/nptl/tls.h
|
||||
@@ -112,15 +112,7 @@ register struct pthread *__thread_self __asm__("%g7");
|
||||
REGISTER (32, 32, 10 * 4, 0) \
|
||||
REGISTER (64, __WORDSIZE, (6 * 8) + (__WORDSIZE==64?0:4), 0)
|
||||
|
||||
-/* Access to data in the thread descriptor is easy. */
|
||||
-#define THREAD_GETMEM(descr, member) \
|
||||
- descr->member
|
||||
-#define THREAD_GETMEM_NC(descr, member, idx) \
|
||||
- descr->member[idx]
|
||||
-#define THREAD_SETMEM(descr, member, value) \
|
||||
- descr->member = (value)
|
||||
-#define THREAD_SETMEM_NC(descr, member, idx, value) \
|
||||
- descr->member[idx] = (value)
|
||||
+# include <tcb-access.h>
|
||||
|
||||
/* Set the stack guard field in TCB head. */
|
||||
#define THREAD_SET_STACK_GUARD(value) \
|
||||
diff --git a/sysdeps/x86_64/nptl/tcb-access.h b/sysdeps/x86_64/nptl/tcb-access.h
|
||||
new file mode 100644
|
||||
index 0000000000000000..18848a729d16a4f5
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/x86_64/nptl/tcb-access.h
|
||||
@@ -0,0 +1,130 @@
|
||||
+/* THREAD_* accessors. x86_64 version.
|
||||
+ Copyright (C) 2002-2021 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/>. */
|
||||
+
|
||||
+/* Read member of the thread descriptor directly. */
|
||||
+# define THREAD_GETMEM(descr, member) \
|
||||
+ ({ __typeof (descr->member) __value; \
|
||||
+ _Static_assert (sizeof (__value) == 1 \
|
||||
+ || sizeof (__value) == 4 \
|
||||
+ || sizeof (__value) == 8, \
|
||||
+ "size of per-thread data"); \
|
||||
+ if (sizeof (__value) == 1) \
|
||||
+ asm volatile ("movb %%fs:%P2,%b0" \
|
||||
+ : "=q" (__value) \
|
||||
+ : "0" (0), "i" (offsetof (struct pthread, member))); \
|
||||
+ else if (sizeof (__value) == 4) \
|
||||
+ asm volatile ("movl %%fs:%P1,%0" \
|
||||
+ : "=r" (__value) \
|
||||
+ : "i" (offsetof (struct pthread, member))); \
|
||||
+ else /* 8 */ \
|
||||
+ { \
|
||||
+ asm volatile ("movq %%fs:%P1,%q0" \
|
||||
+ : "=r" (__value) \
|
||||
+ : "i" (offsetof (struct pthread, member))); \
|
||||
+ } \
|
||||
+ __value; })
|
||||
+
|
||||
+
|
||||
+/* Same as THREAD_GETMEM, but the member offset can be non-constant. */
|
||||
+# define THREAD_GETMEM_NC(descr, member, idx) \
|
||||
+ ({ __typeof (descr->member[0]) __value; \
|
||||
+ _Static_assert (sizeof (__value) == 1 \
|
||||
+ || sizeof (__value) == 4 \
|
||||
+ || sizeof (__value) == 8, \
|
||||
+ "size of per-thread data"); \
|
||||
+ if (sizeof (__value) == 1) \
|
||||
+ asm volatile ("movb %%fs:%P2(%q3),%b0" \
|
||||
+ : "=q" (__value) \
|
||||
+ : "0" (0), "i" (offsetof (struct pthread, member[0])), \
|
||||
+ "r" (idx)); \
|
||||
+ else if (sizeof (__value) == 4) \
|
||||
+ asm volatile ("movl %%fs:%P1(,%q2,4),%0" \
|
||||
+ : "=r" (__value) \
|
||||
+ : "i" (offsetof (struct pthread, member[0])), "r" (idx));\
|
||||
+ else /* 8 */ \
|
||||
+ { \
|
||||
+ asm volatile ("movq %%fs:%P1(,%q2,8),%q0" \
|
||||
+ : "=r" (__value) \
|
||||
+ : "i" (offsetof (struct pthread, member[0])), \
|
||||
+ "r" (idx)); \
|
||||
+ } \
|
||||
+ __value; })
|
||||
+
|
||||
+
|
||||
+/* Loading addresses of objects on x86-64 needs to be treated special
|
||||
+ when generating PIC code. */
|
||||
+#ifdef __pic__
|
||||
+# define IMM_MODE "nr"
|
||||
+#else
|
||||
+# define IMM_MODE "ir"
|
||||
+#endif
|
||||
+
|
||||
+
|
||||
+/* Set member of the thread descriptor directly. */
|
||||
+# define THREAD_SETMEM(descr, member, value) \
|
||||
+ ({ \
|
||||
+ _Static_assert (sizeof (descr->member) == 1 \
|
||||
+ || sizeof (descr->member) == 4 \
|
||||
+ || sizeof (descr->member) == 8, \
|
||||
+ "size of per-thread data"); \
|
||||
+ if (sizeof (descr->member) == 1) \
|
||||
+ asm volatile ("movb %b0,%%fs:%P1" : \
|
||||
+ : "iq" (value), \
|
||||
+ "i" (offsetof (struct pthread, member))); \
|
||||
+ else if (sizeof (descr->member) == 4) \
|
||||
+ asm volatile ("movl %0,%%fs:%P1" : \
|
||||
+ : IMM_MODE (value), \
|
||||
+ "i" (offsetof (struct pthread, member))); \
|
||||
+ else /* 8 */ \
|
||||
+ { \
|
||||
+ /* Since movq takes a signed 32-bit immediate or a register source \
|
||||
+ operand, use "er" constraint for 32-bit signed integer constant \
|
||||
+ or register. */ \
|
||||
+ asm volatile ("movq %q0,%%fs:%P1" : \
|
||||
+ : "er" ((uint64_t) cast_to_integer (value)), \
|
||||
+ "i" (offsetof (struct pthread, member))); \
|
||||
+ }})
|
||||
+
|
||||
+
|
||||
+/* Same as THREAD_SETMEM, but the member offset can be non-constant. */
|
||||
+# define THREAD_SETMEM_NC(descr, member, idx, value) \
|
||||
+ ({ \
|
||||
+ _Static_assert (sizeof (descr->member[0]) == 1 \
|
||||
+ || sizeof (descr->member[0]) == 4 \
|
||||
+ || sizeof (descr->member[0]) == 8, \
|
||||
+ "size of per-thread data"); \
|
||||
+ if (sizeof (descr->member[0]) == 1) \
|
||||
+ asm volatile ("movb %b0,%%fs:%P1(%q2)" : \
|
||||
+ : "iq" (value), \
|
||||
+ "i" (offsetof (struct pthread, member[0])), \
|
||||
+ "r" (idx)); \
|
||||
+ else if (sizeof (descr->member[0]) == 4) \
|
||||
+ asm volatile ("movl %0,%%fs:%P1(,%q2,4)" : \
|
||||
+ : IMM_MODE (value), \
|
||||
+ "i" (offsetof (struct pthread, member[0])), \
|
||||
+ "r" (idx)); \
|
||||
+ else /* 8 */ \
|
||||
+ { \
|
||||
+ /* Since movq takes a signed 32-bit immediate or a register source \
|
||||
+ operand, use "er" constraint for 32-bit signed integer constant \
|
||||
+ or register. */ \
|
||||
+ asm volatile ("movq %q0,%%fs:%P1(,%q2,8)" : \
|
||||
+ : "er" ((uint64_t) cast_to_integer (value)), \
|
||||
+ "i" (offsetof (struct pthread, member[0])), \
|
||||
+ "r" (idx)); \
|
||||
+ }})
|
||||
diff --git a/sysdeps/x86_64/nptl/tls.h b/sysdeps/x86_64/nptl/tls.h
|
||||
index a78c4f4d016002fa..3af1836e28b26fdb 100644
|
||||
--- a/sysdeps/x86_64/nptl/tls.h
|
||||
+++ b/sysdeps/x86_64/nptl/tls.h
|
||||
@@ -195,119 +195,7 @@ _Static_assert (offsetof (tcbhead_t, __glibc_unused2) == 0x80,
|
||||
# define DB_THREAD_SELF_INCLUDE <sys/reg.h> /* For the FS constant. */
|
||||
# define DB_THREAD_SELF CONST_THREAD_AREA (64, FS)
|
||||
|
||||
-/* Read member of the thread descriptor directly. */
|
||||
-# define THREAD_GETMEM(descr, member) \
|
||||
- ({ __typeof (descr->member) __value; \
|
||||
- _Static_assert (sizeof (__value) == 1 \
|
||||
- || sizeof (__value) == 4 \
|
||||
- || sizeof (__value) == 8, \
|
||||
- "size of per-thread data"); \
|
||||
- if (sizeof (__value) == 1) \
|
||||
- asm volatile ("movb %%fs:%P2,%b0" \
|
||||
- : "=q" (__value) \
|
||||
- : "0" (0), "i" (offsetof (struct pthread, member))); \
|
||||
- else if (sizeof (__value) == 4) \
|
||||
- asm volatile ("movl %%fs:%P1,%0" \
|
||||
- : "=r" (__value) \
|
||||
- : "i" (offsetof (struct pthread, member))); \
|
||||
- else /* 8 */ \
|
||||
- { \
|
||||
- asm volatile ("movq %%fs:%P1,%q0" \
|
||||
- : "=r" (__value) \
|
||||
- : "i" (offsetof (struct pthread, member))); \
|
||||
- } \
|
||||
- __value; })
|
||||
-
|
||||
-
|
||||
-/* Same as THREAD_GETMEM, but the member offset can be non-constant. */
|
||||
-# define THREAD_GETMEM_NC(descr, member, idx) \
|
||||
- ({ __typeof (descr->member[0]) __value; \
|
||||
- _Static_assert (sizeof (__value) == 1 \
|
||||
- || sizeof (__value) == 4 \
|
||||
- || sizeof (__value) == 8, \
|
||||
- "size of per-thread data"); \
|
||||
- if (sizeof (__value) == 1) \
|
||||
- asm volatile ("movb %%fs:%P2(%q3),%b0" \
|
||||
- : "=q" (__value) \
|
||||
- : "0" (0), "i" (offsetof (struct pthread, member[0])), \
|
||||
- "r" (idx)); \
|
||||
- else if (sizeof (__value) == 4) \
|
||||
- asm volatile ("movl %%fs:%P1(,%q2,4),%0" \
|
||||
- : "=r" (__value) \
|
||||
- : "i" (offsetof (struct pthread, member[0])), "r" (idx));\
|
||||
- else /* 8 */ \
|
||||
- { \
|
||||
- asm volatile ("movq %%fs:%P1(,%q2,8),%q0" \
|
||||
- : "=r" (__value) \
|
||||
- : "i" (offsetof (struct pthread, member[0])), \
|
||||
- "r" (idx)); \
|
||||
- } \
|
||||
- __value; })
|
||||
-
|
||||
-
|
||||
-/* Loading addresses of objects on x86-64 needs to be treated special
|
||||
- when generating PIC code. */
|
||||
-#ifdef __pic__
|
||||
-# define IMM_MODE "nr"
|
||||
-#else
|
||||
-# define IMM_MODE "ir"
|
||||
-#endif
|
||||
-
|
||||
-
|
||||
-/* Set member of the thread descriptor directly. */
|
||||
-# define THREAD_SETMEM(descr, member, value) \
|
||||
- ({ \
|
||||
- _Static_assert (sizeof (descr->member) == 1 \
|
||||
- || sizeof (descr->member) == 4 \
|
||||
- || sizeof (descr->member) == 8, \
|
||||
- "size of per-thread data"); \
|
||||
- if (sizeof (descr->member) == 1) \
|
||||
- asm volatile ("movb %b0,%%fs:%P1" : \
|
||||
- : "iq" (value), \
|
||||
- "i" (offsetof (struct pthread, member))); \
|
||||
- else if (sizeof (descr->member) == 4) \
|
||||
- asm volatile ("movl %0,%%fs:%P1" : \
|
||||
- : IMM_MODE (value), \
|
||||
- "i" (offsetof (struct pthread, member))); \
|
||||
- else /* 8 */ \
|
||||
- { \
|
||||
- /* Since movq takes a signed 32-bit immediate or a register source \
|
||||
- operand, use "er" constraint for 32-bit signed integer constant \
|
||||
- or register. */ \
|
||||
- asm volatile ("movq %q0,%%fs:%P1" : \
|
||||
- : "er" ((uint64_t) cast_to_integer (value)), \
|
||||
- "i" (offsetof (struct pthread, member))); \
|
||||
- }})
|
||||
-
|
||||
-
|
||||
-/* Same as THREAD_SETMEM, but the member offset can be non-constant. */
|
||||
-# define THREAD_SETMEM_NC(descr, member, idx, value) \
|
||||
- ({ \
|
||||
- _Static_assert (sizeof (descr->member[0]) == 1 \
|
||||
- || sizeof (descr->member[0]) == 4 \
|
||||
- || sizeof (descr->member[0]) == 8, \
|
||||
- "size of per-thread data"); \
|
||||
- if (sizeof (descr->member[0]) == 1) \
|
||||
- asm volatile ("movb %b0,%%fs:%P1(%q2)" : \
|
||||
- : "iq" (value), \
|
||||
- "i" (offsetof (struct pthread, member[0])), \
|
||||
- "r" (idx)); \
|
||||
- else if (sizeof (descr->member[0]) == 4) \
|
||||
- asm volatile ("movl %0,%%fs:%P1(,%q2,4)" : \
|
||||
- : IMM_MODE (value), \
|
||||
- "i" (offsetof (struct pthread, member[0])), \
|
||||
- "r" (idx)); \
|
||||
- else /* 8 */ \
|
||||
- { \
|
||||
- /* Since movq takes a signed 32-bit immediate or a register source \
|
||||
- operand, use "er" constraint for 32-bit signed integer constant \
|
||||
- or register. */ \
|
||||
- asm volatile ("movq %q0,%%fs:%P1(,%q2,8)" : \
|
||||
- : "er" ((uint64_t) cast_to_integer (value)), \
|
||||
- "i" (offsetof (struct pthread, member[0])), \
|
||||
- "r" (idx)); \
|
||||
- }})
|
||||
-
|
||||
+# include <tcb-access.h>
|
||||
|
||||
/* Set the stack guard field in TCB head. */
|
||||
# define THREAD_SET_STACK_GUARD(value) \
|
@ -0,0 +1,49 @@
|
||||
commit 8d1927d8dc5aad0f01c929123086be3a5b799d18
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu Dec 9 09:49:32 2021 +0100
|
||||
|
||||
nptl: Introduce THREAD_GETMEM_VOLATILE
|
||||
|
||||
This will be needed for rseq TCB access.
|
||||
|
||||
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||
|
||||
diff --git a/sysdeps/i386/nptl/tcb-access.h b/sysdeps/i386/nptl/tcb-access.h
|
||||
index 6c6d561e394817c7..5ddd83224bc8eb77 100644
|
||||
--- a/sysdeps/i386/nptl/tcb-access.h
|
||||
+++ b/sysdeps/i386/nptl/tcb-access.h
|
||||
@@ -41,6 +41,8 @@
|
||||
} \
|
||||
__value; })
|
||||
|
||||
+/* THREAD_GETMEM already forces a read. */
|
||||
+#define THREAD_GETMEM_VOLATILE(descr, member) THREAD_GETMEM (descr, member)
|
||||
|
||||
/* Same as THREAD_GETMEM, but the member offset can be non-constant. */
|
||||
#define THREAD_GETMEM_NC(descr, member, idx) \
|
||||
diff --git a/sysdeps/nptl/tcb-access.h b/sysdeps/nptl/tcb-access.h
|
||||
index b4137b8ab8067915..bbe20b7225b060fd 100644
|
||||
--- a/sysdeps/nptl/tcb-access.h
|
||||
+++ b/sysdeps/nptl/tcb-access.h
|
||||
@@ -22,6 +22,8 @@
|
||||
|
||||
#define THREAD_GETMEM(descr, member) \
|
||||
descr->member
|
||||
+#define THREAD_GETMEM_VOLATILE(descr, member) \
|
||||
+ (*(volatile __typeof (descr->member) *)&descr->member)
|
||||
#define THREAD_GETMEM_NC(descr, member, idx) \
|
||||
descr->member[idx]
|
||||
#define THREAD_SETMEM(descr, member, value) \
|
||||
diff --git a/sysdeps/x86_64/nptl/tcb-access.h b/sysdeps/x86_64/nptl/tcb-access.h
|
||||
index 18848a729d16a4f5..e4d2d07a9b218025 100644
|
||||
--- a/sysdeps/x86_64/nptl/tcb-access.h
|
||||
+++ b/sysdeps/x86_64/nptl/tcb-access.h
|
||||
@@ -39,6 +39,8 @@
|
||||
} \
|
||||
__value; })
|
||||
|
||||
+/* THREAD_GETMEM already forces a read. */
|
||||
+#define THREAD_GETMEM_VOLATILE(descr, member) THREAD_GETMEM (descr, member)
|
||||
|
||||
/* Same as THREAD_GETMEM, but the member offset can be non-constant. */
|
||||
# define THREAD_GETMEM_NC(descr, member, idx) \
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,43 @@
|
||||
commit 1d350aa06091211863e41169729cee1bca39f72f
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu Dec 9 09:49:32 2021 +0100
|
||||
|
||||
Linux: Use rseq to accelerate sched_getcpu
|
||||
|
||||
Co-Authored-By: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/sched_getcpu.c b/sysdeps/unix/sysv/linux/sched_getcpu.c
|
||||
index c41e986f2cab5e42..6f78edaea1495342 100644
|
||||
--- a/sysdeps/unix/sysv/linux/sched_getcpu.c
|
||||
+++ b/sysdeps/unix/sysv/linux/sched_getcpu.c
|
||||
@@ -20,8 +20,8 @@
|
||||
#include <sysdep.h>
|
||||
#include <sysdep-vdso.h>
|
||||
|
||||
-int
|
||||
-sched_getcpu (void)
|
||||
+static int
|
||||
+vsyscall_sched_getcpu (void)
|
||||
{
|
||||
unsigned int cpu;
|
||||
int r = -1;
|
||||
@@ -32,3 +32,18 @@ sched_getcpu (void)
|
||||
#endif
|
||||
return r == -1 ? r : cpu;
|
||||
}
|
||||
+
|
||||
+#ifdef RSEQ_SIG
|
||||
+int
|
||||
+sched_getcpu (void)
|
||||
+{
|
||||
+ int cpu_id = THREAD_GETMEM_VOLATILE (THREAD_SELF, rseq_area.cpu_id);
|
||||
+ return __glibc_likely (cpu_id >= 0) ? cpu_id : vsyscall_sched_getcpu ();
|
||||
+}
|
||||
+#else /* RSEQ_SIG */
|
||||
+int
|
||||
+sched_getcpu (void)
|
||||
+{
|
||||
+ return vsyscall_sched_getcpu ();
|
||||
+}
|
||||
+#endif /* RSEQ_SIG */
|
@ -0,0 +1,278 @@
|
||||
commit e3e589829d16af9f7e73c7b70f74f3c5d5003e45
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu Dec 9 09:49:32 2021 +0100
|
||||
|
||||
nptl: Add glibc.pthread.rseq tunable to control rseq registration
|
||||
|
||||
This tunable allows applications to register the rseq area instead
|
||||
of glibc.
|
||||
|
||||
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
|
||||
diff --git a/manual/tunables.texi b/manual/tunables.texi
|
||||
index 658547c6137bf177..1f5c410288eeecec 100644
|
||||
--- a/manual/tunables.texi
|
||||
+++ b/manual/tunables.texi
|
||||
@@ -413,6 +413,16 @@ The value is measured in bytes. The default is @samp{41943040}
|
||||
(fourty mibibytes).
|
||||
@end deftp
|
||||
|
||||
+@deftp Tunable glibc.pthread.rseq
|
||||
+The @code{glibc.pthread.rseq} tunable can be set to @samp{0}, to disable
|
||||
+restartable sequences support in @theglibc{}. This enables applications
|
||||
+to perform direct restartable sequence registration with the kernel.
|
||||
+The default is @samp{1}, which means that @theglibc{} performs
|
||||
+registration on behalf of the application.
|
||||
+
|
||||
+Restartable sequences are a Linux-specific extension.
|
||||
+@end deftp
|
||||
+
|
||||
@node Hardware Capability Tunables
|
||||
@section Hardware Capability Tunables
|
||||
@cindex hardware capability tunables
|
||||
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
|
||||
index d2b40924dafad316..f405fa356c2955ce 100644
|
||||
--- a/nptl/pthread_create.c
|
||||
+++ b/nptl/pthread_create.c
|
||||
@@ -369,7 +369,10 @@ start_thread (void *arg)
|
||||
__ctype_init ();
|
||||
|
||||
/* Register rseq TLS to the kernel. */
|
||||
- rseq_register_current_thread (pd);
|
||||
+ {
|
||||
+ bool do_rseq = THREAD_GETMEM (pd, flags) & ATTR_FLAG_DO_RSEQ;
|
||||
+ rseq_register_current_thread (pd, do_rseq);
|
||||
+ }
|
||||
|
||||
#ifndef __ASSUME_SET_ROBUST_LIST
|
||||
if (__nptl_set_robust_list_avail)
|
||||
@@ -678,6 +681,11 @@ __pthread_create_2_1 (pthread_t *newthread, const pthread_attr_t *attr,
|
||||
pd->flags = ((iattr->flags & ~(ATTR_FLAG_SCHED_SET | ATTR_FLAG_POLICY_SET))
|
||||
| (self->flags & (ATTR_FLAG_SCHED_SET | ATTR_FLAG_POLICY_SET)));
|
||||
|
||||
+ /* Inherit rseq registration state. Without seccomp filters, rseq
|
||||
+ registration will either always fail or always succeed. */
|
||||
+ if ((int) THREAD_GETMEM_VOLATILE (self, rseq_area.cpu_id) >= 0)
|
||||
+ pd->flags |= ATTR_FLAG_DO_RSEQ;
|
||||
+
|
||||
/* Initialize the field for the ID of the thread which is waiting
|
||||
for us. This is a self-reference in case the thread is created
|
||||
detached. */
|
||||
diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c
|
||||
index fedb876fdb2642d2..b39dfbff2c6678d5 100644
|
||||
--- a/sysdeps/nptl/dl-tls_init_tp.c
|
||||
+++ b/sysdeps/nptl/dl-tls_init_tp.c
|
||||
@@ -23,6 +23,9 @@
|
||||
#include <tls.h>
|
||||
#include <rseq-internal.h>
|
||||
|
||||
+#define TUNABLE_NAMESPACE pthread
|
||||
+#include <dl-tunables.h>
|
||||
+
|
||||
#ifndef __ASSUME_SET_ROBUST_LIST
|
||||
bool __nptl_set_robust_list_avail;
|
||||
rtld_hidden_data_def (__nptl_set_robust_list_avail)
|
||||
@@ -92,7 +95,13 @@ __tls_init_tp (void)
|
||||
}
|
||||
}
|
||||
|
||||
- rseq_register_current_thread (pd);
|
||||
+ {
|
||||
+ bool do_rseq = true;
|
||||
+#if HAVE_TUNABLES
|
||||
+ do_rseq = TUNABLE_GET (rseq, int, NULL);
|
||||
+#endif
|
||||
+ rseq_register_current_thread (pd, do_rseq);
|
||||
+ }
|
||||
|
||||
/* Set initial thread's stack block from 0 up to __libc_stack_end.
|
||||
It will be bigger than it actually is, but for unwind.c/pt-longjmp.c
|
||||
diff --git a/sysdeps/nptl/dl-tunables.list b/sysdeps/nptl/dl-tunables.list
|
||||
index ac5d053298725468..d24f4be0d08ba407 100644
|
||||
--- a/sysdeps/nptl/dl-tunables.list
|
||||
+++ b/sysdeps/nptl/dl-tunables.list
|
||||
@@ -27,5 +27,11 @@ glibc {
|
||||
type: SIZE_T
|
||||
default: 41943040
|
||||
}
|
||||
+ rseq {
|
||||
+ type: INT_32
|
||||
+ minval: 0
|
||||
+ maxval: 1
|
||||
+ default: 1
|
||||
+ }
|
||||
}
|
||||
}
|
||||
diff --git a/sysdeps/nptl/internaltypes.h b/sysdeps/nptl/internaltypes.h
|
||||
index 50a2ad19ae7210ae..8205c6d15a918952 100644
|
||||
--- a/sysdeps/nptl/internaltypes.h
|
||||
+++ b/sysdeps/nptl/internaltypes.h
|
||||
@@ -49,6 +49,7 @@ struct pthread_attr
|
||||
#define ATTR_FLAG_OLDATTR 0x0010
|
||||
#define ATTR_FLAG_SCHED_SET 0x0020
|
||||
#define ATTR_FLAG_POLICY_SET 0x0040
|
||||
+#define ATTR_FLAG_DO_RSEQ 0x0080
|
||||
|
||||
/* Used to allocate a pthread_attr_t object which is also accessed
|
||||
internally. */
|
||||
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
|
||||
index f84ccd6bbb3b16ad..d30d21898b402d1e 100644
|
||||
--- a/sysdeps/unix/sysv/linux/Makefile
|
||||
+++ b/sysdeps/unix/sysv/linux/Makefile
|
||||
@@ -135,6 +135,12 @@ tests-internal += \
|
||||
tst-sigcontext-get_pc \
|
||||
# tests-internal
|
||||
|
||||
+ifneq (no,$(have-tunables))
|
||||
+tests-internal += \
|
||||
+ tst-rseq-disable \
|
||||
+ # tests-internal $(have-tunables)
|
||||
+endif
|
||||
+
|
||||
tests-time64 += \
|
||||
tst-adjtimex-time64 \
|
||||
tst-clock_adjtime-time64 \
|
||||
@@ -226,6 +232,8 @@ $(objpfx)tst-mman-consts.out: ../sysdeps/unix/sysv/linux/tst-mman-consts.py
|
||||
< /dev/null > $@ 2>&1; $(evaluate-test)
|
||||
$(objpfx)tst-mman-consts.out: $(sysdeps-linux-python-deps)
|
||||
|
||||
+tst-rseq-disable-ENV = GLIBC_TUNABLES=glibc.pthread.rseq=0
|
||||
+
|
||||
endif # $(subdir) == misc
|
||||
|
||||
ifeq ($(subdir),time)
|
||||
diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h
|
||||
index 909f5478251d3d13..15bc7ffd6eda632d 100644
|
||||
--- a/sysdeps/unix/sysv/linux/rseq-internal.h
|
||||
+++ b/sysdeps/unix/sysv/linux/rseq-internal.h
|
||||
@@ -21,22 +21,27 @@
|
||||
#include <sysdep.h>
|
||||
#include <errno.h>
|
||||
#include <kernel-features.h>
|
||||
+#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/rseq.h>
|
||||
|
||||
#ifdef RSEQ_SIG
|
||||
static inline void
|
||||
-rseq_register_current_thread (struct pthread *self)
|
||||
+rseq_register_current_thread (struct pthread *self, bool do_rseq)
|
||||
{
|
||||
- int ret = INTERNAL_SYSCALL_CALL (rseq,
|
||||
- &self->rseq_area, sizeof (self->rseq_area),
|
||||
- 0, RSEQ_SIG);
|
||||
- if (INTERNAL_SYSCALL_ERROR_P (ret))
|
||||
- THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED);
|
||||
+ if (do_rseq)
|
||||
+ {
|
||||
+ int ret = INTERNAL_SYSCALL_CALL (rseq, &self->rseq_area,
|
||||
+ sizeof (self->rseq_area),
|
||||
+ 0, RSEQ_SIG);
|
||||
+ if (!INTERNAL_SYSCALL_ERROR_P (ret))
|
||||
+ return;
|
||||
+ }
|
||||
+ THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED);
|
||||
}
|
||||
#else /* RSEQ_SIG */
|
||||
static inline void
|
||||
-rseq_register_current_thread (struct pthread *self)
|
||||
+rseq_register_current_thread (struct pthread *self, bool do_rseq)
|
||||
{
|
||||
THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED);
|
||||
}
|
||||
diff --git a/sysdeps/unix/sysv/linux/tst-rseq-disable.c b/sysdeps/unix/sysv/linux/tst-rseq-disable.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..000e351872fc2f76
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/unix/sysv/linux/tst-rseq-disable.c
|
||||
@@ -0,0 +1,89 @@
|
||||
+/* Test disabling of rseq registration via tunable.
|
||||
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <stdio.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/namespace.h>
|
||||
+#include <support/xthread.h>
|
||||
+#include <sysdep.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+#ifdef RSEQ_SIG
|
||||
+
|
||||
+/* Check that rseq can be registered and has not been taken by glibc. */
|
||||
+static void
|
||||
+check_rseq_disabled (void)
|
||||
+{
|
||||
+ struct pthread *pd = THREAD_SELF;
|
||||
+ TEST_COMPARE ((int) pd->rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED);
|
||||
+
|
||||
+ int ret = syscall (__NR_rseq, &pd->rseq_area, sizeof (pd->rseq_area),
|
||||
+ 0, RSEQ_SIG);
|
||||
+ if (ret == 0)
|
||||
+ {
|
||||
+ ret = syscall (__NR_rseq, &pd->rseq_area, sizeof (pd->rseq_area),
|
||||
+ RSEQ_FLAG_UNREGISTER, RSEQ_SIG);
|
||||
+ TEST_COMPARE (ret, 0);
|
||||
+ pd->rseq_area.cpu_id = RSEQ_CPU_ID_REGISTRATION_FAILED;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ TEST_VERIFY (errno != -EINVAL);
|
||||
+ TEST_VERIFY (errno != -EBUSY);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void *
|
||||
+thread_func (void *ignored)
|
||||
+{
|
||||
+ check_rseq_disabled ();
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+proc_func (void *ignored)
|
||||
+{
|
||||
+ check_rseq_disabled ();
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ puts ("info: checking main thread");
|
||||
+ check_rseq_disabled ();
|
||||
+
|
||||
+ puts ("info: checking main thread (2)");
|
||||
+ check_rseq_disabled ();
|
||||
+
|
||||
+ puts ("info: checking new thread");
|
||||
+ xpthread_join (xpthread_create (NULL, thread_func, NULL));
|
||||
+
|
||||
+ puts ("info: checking subprocess");
|
||||
+ support_isolate_in_subprocess (proc_func, NULL);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+#else /* !RSEQ_SIG */
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ FAIL_UNSUPPORTED ("glibc does not define RSEQ_SIG, skipping test");
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+#include <support/test-driver.c>
|
@ -0,0 +1,23 @@
|
||||
Downstream-only patch from Mark Wielaard <mjw@redhat.com> to avoid a
|
||||
crash in backtrace if the vDSO is not available.
|
||||
|
||||
Upstream, this code was removed in commit 82fd7314c7df8c5555dce02
|
||||
("powerpc: Remove backtrace implementation"), so patch is not needed
|
||||
there.
|
||||
|
||||
diff --git a/sysdeps/powerpc/powerpc64/backtrace.c b/sysdeps/powerpc/powerpc64/backtrace.c
|
||||
index 37de9b5bdd73c316..0ffa7509dfa4862a 100644
|
||||
--- a/sysdeps/powerpc/powerpc64/backtrace.c
|
||||
+++ b/sysdeps/powerpc/powerpc64/backtrace.c
|
||||
@@ -68,8 +68,9 @@ static inline bool
|
||||
is_sigtramp_address (void *nip)
|
||||
{
|
||||
#ifdef HAVE_SIGTRAMP_RT64
|
||||
- if (nip == GLRO (dl_vdso_sigtramp_rt64) ||
|
||||
- nip == GLRO (dl_vdso_sigtramp_rt64) + 4)
|
||||
+ if ((nip == GLRO (dl_vdso_sigtramp_rt64) ||
|
||||
+ nip == GLRO (dl_vdso_sigtramp_rt64) + 4)
|
||||
+ && nip != NULL)
|
||||
return true;
|
||||
#endif
|
||||
return false;
|
@ -0,0 +1,143 @@
|
||||
commit ea5814467a02c9d2d7608b6445c5d60e2a81d3ee
|
||||
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||
Date: Fri Dec 10 13:00:09 2021 -0800
|
||||
|
||||
x86-64: Remove LD_PREFER_MAP_32BIT_EXEC support [BZ #28656]
|
||||
|
||||
Remove the LD_PREFER_MAP_32BIT_EXEC environment variable support since
|
||||
the first PT_LOAD segment is no longer executable due to defaulting to
|
||||
-z separate-code.
|
||||
|
||||
This fixes [BZ #28656].
|
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h b/sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h
|
||||
deleted file mode 100644
|
||||
index 5b9696e2de8e5482..0000000000000000
|
||||
--- a/sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h
|
||||
+++ /dev/null
|
||||
@@ -1,45 +0,0 @@
|
||||
-/* Optional code to distinguish library flavours. x86-64 version.
|
||||
- Copyright (C) 2015-2021 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/>. */
|
||||
-
|
||||
-#ifndef _DL_LIBRECON_H
|
||||
-
|
||||
-#include <sysdeps/unix/sysv/linux/dl-librecon.h>
|
||||
-
|
||||
-/* Recognizing extra environment variables. For 64-bit applications,
|
||||
- branch prediction performance may be negatively impacted when the
|
||||
- target of a branch is more than 4GB away from the branch. Add the
|
||||
- Prefer_MAP_32BIT_EXEC bit so that mmap will try to map executable
|
||||
- pages with MAP_32BIT first. NB: MAP_32BIT will map to lower 2GB,
|
||||
- not lower 4GB, address. Prefer_MAP_32BIT_EXEC reduces bits available
|
||||
- for address space layout randomization (ASLR). Prefer_MAP_32BIT_EXEC
|
||||
- is always disabled for SUID programs and can be enabled by setting
|
||||
- environment variable, LD_PREFER_MAP_32BIT_EXEC. */
|
||||
-#define EXTRA_LD_ENVVARS \
|
||||
- case 21: \
|
||||
- if (!__libc_enable_secure \
|
||||
- && memcmp (envline, "PREFER_MAP_32BIT_EXEC", 21) == 0) \
|
||||
- GLRO(dl_x86_cpu_features).preferred[index_arch_Prefer_MAP_32BIT_EXEC] \
|
||||
- |= bit_arch_Prefer_MAP_32BIT_EXEC; \
|
||||
- break;
|
||||
-
|
||||
-/* Extra unsecure variables. The names are all stuffed in a single
|
||||
- string which means they have to be terminated with a '\0' explicitly. */
|
||||
-#define EXTRA_UNSECURE_ENVVARS \
|
||||
- "LD_PREFER_MAP_32BIT_EXEC\0"
|
||||
-
|
||||
-#endif /* dl-librecon.h */
|
||||
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/mmap_internal.h b/sysdeps/unix/sysv/linux/x86_64/64/mmap_internal.h
|
||||
deleted file mode 100644
|
||||
index 18177d2cb3ae645f..0000000000000000
|
||||
--- a/sysdeps/unix/sysv/linux/x86_64/64/mmap_internal.h
|
||||
+++ /dev/null
|
||||
@@ -1,42 +0,0 @@
|
||||
-/* Linux mmap system call. x86-64 version.
|
||||
- Copyright (C) 2015-2021 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/>. */
|
||||
-
|
||||
-#ifndef MMAP_X86_64_INTERNAL_H
|
||||
-#define MMAP_X86_64_INTERNAL_H
|
||||
-
|
||||
-#include <ldsodefs.h>
|
||||
-
|
||||
-/* If the Prefer_MAP_32BIT_EXEC bit is set, try to map executable pages
|
||||
- with MAP_32BIT first. */
|
||||
-#define MMAP_PREPARE(addr, len, prot, flags, fd, offset) \
|
||||
- if ((addr) == NULL \
|
||||
- && ((prot) & PROT_EXEC) != 0 \
|
||||
- && HAS_ARCH_FEATURE (Prefer_MAP_32BIT_EXEC)) \
|
||||
- { \
|
||||
- void *ret = (void*) INLINE_SYSCALL_CALL (mmap, (addr), (len), \
|
||||
- (prot), \
|
||||
- (flags) | MAP_32BIT, \
|
||||
- (fd), (offset)); \
|
||||
- if (ret != MAP_FAILED) \
|
||||
- return ret; \
|
||||
- }
|
||||
-
|
||||
-#include_next <mmap_internal.h>
|
||||
-
|
||||
-#endif
|
||||
diff --git a/sysdeps/x86/cpu-tunables.c b/sysdeps/x86/cpu-tunables.c
|
||||
index 00fe5045eb56eb07..58f2fad4323d5d91 100644
|
||||
--- a/sysdeps/x86/cpu-tunables.c
|
||||
+++ b/sysdeps/x86/cpu-tunables.c
|
||||
@@ -260,13 +260,6 @@ TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp)
|
||||
20);
|
||||
}
|
||||
break;
|
||||
- case 21:
|
||||
- {
|
||||
- CHECK_GLIBC_IFUNC_PREFERRED_BOTH (n, cpu_features,
|
||||
- Prefer_MAP_32BIT_EXEC,
|
||||
- disable, 21);
|
||||
- }
|
||||
- break;
|
||||
case 23:
|
||||
{
|
||||
CHECK_GLIBC_IFUNC_PREFERRED_NEED_BOTH
|
||||
diff --git a/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def b/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def
|
||||
index d7c93f00c5928a30..3bdc76cf71007948 100644
|
||||
--- a/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def
|
||||
+++ b/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def
|
||||
@@ -26,7 +26,6 @@ BIT (I586)
|
||||
BIT (I686)
|
||||
BIT (Slow_SSE4_2)
|
||||
BIT (AVX_Fast_Unaligned_Load)
|
||||
-BIT (Prefer_MAP_32BIT_EXEC)
|
||||
BIT (Prefer_No_VZEROUPPER)
|
||||
BIT (Prefer_ERMS)
|
||||
BIT (Prefer_No_AVX512)
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,585 @@
|
||||
commit 15a0c5730d1d5aeb95f50c9ec7470640084feae8
|
||||
Author: Chung-Lin Tang <cltang@codesourcery.com>
|
||||
Date: Thu Oct 21 21:41:22 2021 +0800
|
||||
|
||||
elf: Fix slow DSO sorting behavior in dynamic loader (BZ #17645)
|
||||
|
||||
This second patch contains the actual implementation of a new sorting algorithm
|
||||
for shared objects in the dynamic loader, which solves the slow behavior that
|
||||
the current "old" algorithm falls into when the DSO set contains circular
|
||||
dependencies.
|
||||
|
||||
The new algorithm implemented here is simply depth-first search (DFS) to obtain
|
||||
the Reverse-Post Order (RPO) sequence, a topological sort. A new l_visited:1
|
||||
bitfield is added to struct link_map to more elegantly facilitate such a search.
|
||||
|
||||
The DFS algorithm is applied to the input maps[nmap-1] backwards towards
|
||||
maps[0]. This has the effect of a more "shallow" recursion depth in general
|
||||
since the input is in BFS. Also, when combined with the natural order of
|
||||
processing l_initfini[] at each node, this creates a resulting output sorting
|
||||
closer to the intuitive "left-to-right" order in most cases.
|
||||
|
||||
Another notable implementation adjustment related to this _dl_sort_maps change
|
||||
is the removing of two char arrays 'used' and 'done' in _dl_close_worker to
|
||||
represent two per-map attributes. This has been changed to simply use two new
|
||||
bit-fields l_map_used:1, l_map_done:1 added to struct link_map. This also allows
|
||||
discarding the clunky 'used' array sorting that _dl_sort_maps had to sometimes
|
||||
do along the way.
|
||||
|
||||
Tunable support for switching between different sorting algorithms at runtime is
|
||||
also added. A new tunable 'glibc.rtld.dynamic_sort' with current valid values 1
|
||||
(old algorithm) and 2 (new DFS algorithm) has been added. At time of commit
|
||||
of this patch, the default setting is 1 (old algorithm).
|
||||
|
||||
Signed-off-by: Chung-Lin Tang <cltang@codesourcery.com>
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/elf/dl-close.c b/elf/dl-close.c
|
||||
index cd7b9c9fe83a1a44..f6fbf9de7d78555b 100644
|
||||
--- a/elf/dl-close.c
|
||||
+++ b/elf/dl-close.c
|
||||
@@ -167,8 +167,6 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
|
||||
bool any_tls = false;
|
||||
const unsigned int nloaded = ns->_ns_nloaded;
|
||||
- char used[nloaded];
|
||||
- char done[nloaded];
|
||||
struct link_map *maps[nloaded];
|
||||
|
||||
/* Run over the list and assign indexes to the link maps and enter
|
||||
@@ -176,24 +174,21 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
int idx = 0;
|
||||
for (struct link_map *l = ns->_ns_loaded; l != NULL; l = l->l_next)
|
||||
{
|
||||
+ l->l_map_used = 0;
|
||||
+ l->l_map_done = 0;
|
||||
l->l_idx = idx;
|
||||
maps[idx] = l;
|
||||
++idx;
|
||||
-
|
||||
}
|
||||
assert (idx == nloaded);
|
||||
|
||||
- /* Prepare the bitmaps. */
|
||||
- memset (used, '\0', sizeof (used));
|
||||
- memset (done, '\0', sizeof (done));
|
||||
-
|
||||
/* Keep track of the lowest index link map we have covered already. */
|
||||
int done_index = -1;
|
||||
while (++done_index < nloaded)
|
||||
{
|
||||
struct link_map *l = maps[done_index];
|
||||
|
||||
- if (done[done_index])
|
||||
+ if (l->l_map_done)
|
||||
/* Already handled. */
|
||||
continue;
|
||||
|
||||
@@ -204,12 +199,12 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
/* See CONCURRENCY NOTES in cxa_thread_atexit_impl.c to know why
|
||||
acquire is sufficient and correct. */
|
||||
&& atomic_load_acquire (&l->l_tls_dtor_count) == 0
|
||||
- && !used[done_index])
|
||||
+ && !l->l_map_used)
|
||||
continue;
|
||||
|
||||
/* We need this object and we handle it now. */
|
||||
- done[done_index] = 1;
|
||||
- used[done_index] = 1;
|
||||
+ l->l_map_used = 1;
|
||||
+ l->l_map_done = 1;
|
||||
/* Signal the object is still needed. */
|
||||
l->l_idx = IDX_STILL_USED;
|
||||
|
||||
@@ -225,9 +220,9 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
{
|
||||
assert ((*lp)->l_idx >= 0 && (*lp)->l_idx < nloaded);
|
||||
|
||||
- if (!used[(*lp)->l_idx])
|
||||
+ if (!(*lp)->l_map_used)
|
||||
{
|
||||
- used[(*lp)->l_idx] = 1;
|
||||
+ (*lp)->l_map_used = 1;
|
||||
/* If we marked a new object as used, and we've
|
||||
already processed it, then we need to go back
|
||||
and process again from that point forward to
|
||||
@@ -250,9 +245,9 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
{
|
||||
assert (jmap->l_idx >= 0 && jmap->l_idx < nloaded);
|
||||
|
||||
- if (!used[jmap->l_idx])
|
||||
+ if (!jmap->l_map_used)
|
||||
{
|
||||
- used[jmap->l_idx] = 1;
|
||||
+ jmap->l_map_used = 1;
|
||||
if (jmap->l_idx - 1 < done_index)
|
||||
done_index = jmap->l_idx - 1;
|
||||
}
|
||||
@@ -262,8 +257,7 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
|
||||
/* Sort the entries. We can skip looking for the binary itself which is
|
||||
at the front of the search list for the main namespace. */
|
||||
- _dl_sort_maps (maps + (nsid == LM_ID_BASE), nloaded - (nsid == LM_ID_BASE),
|
||||
- used + (nsid == LM_ID_BASE), true);
|
||||
+ _dl_sort_maps (maps, nloaded, (nsid == LM_ID_BASE), true);
|
||||
|
||||
/* Call all termination functions at once. */
|
||||
#ifdef SHARED
|
||||
@@ -280,7 +274,7 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
/* All elements must be in the same namespace. */
|
||||
assert (imap->l_ns == nsid);
|
||||
|
||||
- if (!used[i])
|
||||
+ if (!imap->l_map_used)
|
||||
{
|
||||
assert (imap->l_type == lt_loaded && !imap->l_nodelete_active);
|
||||
|
||||
@@ -333,7 +327,7 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
if (i < first_loaded)
|
||||
first_loaded = i;
|
||||
}
|
||||
- /* Else used[i]. */
|
||||
+ /* Else imap->l_map_used. */
|
||||
else if (imap->l_type == lt_loaded)
|
||||
{
|
||||
struct r_scope_elem *new_list = NULL;
|
||||
@@ -560,7 +554,7 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
for (unsigned int i = first_loaded; i < nloaded; ++i)
|
||||
{
|
||||
struct link_map *imap = maps[i];
|
||||
- if (!used[i])
|
||||
+ if (!imap->l_map_used)
|
||||
{
|
||||
assert (imap->l_type == lt_loaded);
|
||||
|
||||
diff --git a/elf/dl-deps.c b/elf/dl-deps.c
|
||||
index 087a49b212a96920..237d9636c5be780c 100644
|
||||
--- a/elf/dl-deps.c
|
||||
+++ b/elf/dl-deps.c
|
||||
@@ -613,10 +613,9 @@ Filters not supported with LD_TRACE_PRELINKING"));
|
||||
|
||||
/* If libc.so.6 is the main map, it participates in the sort, so
|
||||
that the relocation order is correct regarding libc.so.6. */
|
||||
- if (l_initfini[0] == GL (dl_ns)[l_initfini[0]->l_ns].libc_map)
|
||||
- _dl_sort_maps (l_initfini, nlist, NULL, false);
|
||||
- else
|
||||
- _dl_sort_maps (&l_initfini[1], nlist - 1, NULL, false);
|
||||
+ _dl_sort_maps (l_initfini, nlist,
|
||||
+ (l_initfini[0] != GL (dl_ns)[l_initfini[0]->l_ns].libc_map),
|
||||
+ false);
|
||||
|
||||
/* Terminate the list of dependencies. */
|
||||
l_initfini[nlist] = NULL;
|
||||
diff --git a/elf/dl-fini.c b/elf/dl-fini.c
|
||||
index 6dbdfe4b3ebbeb89..c683884c355dfd52 100644
|
||||
--- a/elf/dl-fini.c
|
||||
+++ b/elf/dl-fini.c
|
||||
@@ -92,8 +92,7 @@ _dl_fini (void)
|
||||
/* Now we have to do the sorting. We can skip looking for the
|
||||
binary itself which is at the front of the search list for
|
||||
the main namespace. */
|
||||
- _dl_sort_maps (maps + (ns == LM_ID_BASE), nmaps - (ns == LM_ID_BASE),
|
||||
- NULL, true);
|
||||
+ _dl_sort_maps (maps, nmaps, (ns == LM_ID_BASE), true);
|
||||
|
||||
/* We do not rely on the linked list of loaded object anymore
|
||||
from this point on. We have our own list here (maps). The
|
||||
diff --git a/elf/dl-sort-maps.c b/elf/dl-sort-maps.c
|
||||
index d21770267a37e128..a274ed66cc987735 100644
|
||||
--- a/elf/dl-sort-maps.c
|
||||
+++ b/elf/dl-sort-maps.c
|
||||
@@ -16,16 +16,24 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
+#include <assert.h>
|
||||
#include <ldsodefs.h>
|
||||
+#include <elf/dl-tunables.h>
|
||||
|
||||
+/* Note: this is the older, "original" sorting algorithm, being used as
|
||||
+ default up to 2.35.
|
||||
|
||||
-/* Sort array MAPS according to dependencies of the contained objects.
|
||||
- Array USED, if non-NULL, is permutated along MAPS. If FOR_FINI this is
|
||||
- called for finishing an object. */
|
||||
-void
|
||||
-_dl_sort_maps (struct link_map **maps, unsigned int nmaps, char *used,
|
||||
- bool for_fini)
|
||||
+ Sort array MAPS according to dependencies of the contained objects.
|
||||
+ If FOR_FINI is true, this is called for finishing an object. */
|
||||
+static void
|
||||
+_dl_sort_maps_original (struct link_map **maps, unsigned int nmaps,
|
||||
+ unsigned int skip, bool for_fini)
|
||||
{
|
||||
+ /* Allows caller to do the common optimization of skipping the first map,
|
||||
+ usually the main binary. */
|
||||
+ maps += skip;
|
||||
+ nmaps -= skip;
|
||||
+
|
||||
/* A list of one element need not be sorted. */
|
||||
if (nmaps <= 1)
|
||||
return;
|
||||
@@ -66,14 +74,6 @@ _dl_sort_maps (struct link_map **maps, unsigned int nmaps, char *used,
|
||||
(k - i) * sizeof (maps[0]));
|
||||
maps[k] = thisp;
|
||||
|
||||
- if (used != NULL)
|
||||
- {
|
||||
- char here_used = used[i];
|
||||
- memmove (&used[i], &used[i + 1],
|
||||
- (k - i) * sizeof (used[0]));
|
||||
- used[k] = here_used;
|
||||
- }
|
||||
-
|
||||
if (seen[i + 1] > nmaps - i)
|
||||
{
|
||||
++i;
|
||||
@@ -120,3 +120,183 @@ _dl_sort_maps (struct link_map **maps, unsigned int nmaps, char *used,
|
||||
next:;
|
||||
}
|
||||
}
|
||||
+
|
||||
+#if !HAVE_TUNABLES
|
||||
+/* In this case, just default to the original algorithm. */
|
||||
+strong_alias (_dl_sort_maps_original, _dl_sort_maps);
|
||||
+#else
|
||||
+
|
||||
+/* We use a recursive function due to its better clarity and ease of
|
||||
+ implementation, as well as faster execution speed. We already use
|
||||
+ alloca() for list allocation during the breadth-first search of
|
||||
+ dependencies in _dl_map_object_deps(), and this should be on the
|
||||
+ same order of worst-case stack usage.
|
||||
+
|
||||
+ Note: the '*rpo' parameter is supposed to point to one past the
|
||||
+ last element of the array where we save the sort results, and is
|
||||
+ decremented before storing the current map at each level. */
|
||||
+
|
||||
+static void
|
||||
+dfs_traversal (struct link_map ***rpo, struct link_map *map,
|
||||
+ bool *do_reldeps)
|
||||
+{
|
||||
+ if (map->l_visited)
|
||||
+ return;
|
||||
+
|
||||
+ map->l_visited = 1;
|
||||
+
|
||||
+ if (map->l_initfini)
|
||||
+ {
|
||||
+ for (int i = 0; map->l_initfini[i] != NULL; i++)
|
||||
+ {
|
||||
+ struct link_map *dep = map->l_initfini[i];
|
||||
+ if (dep->l_visited == 0
|
||||
+ && dep->l_main_map == 0)
|
||||
+ dfs_traversal (rpo, dep, do_reldeps);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (__glibc_unlikely (do_reldeps != NULL && map->l_reldeps != NULL))
|
||||
+ {
|
||||
+ /* Indicate that we encountered relocation dependencies during
|
||||
+ traversal. */
|
||||
+ *do_reldeps = true;
|
||||
+
|
||||
+ for (int m = map->l_reldeps->act - 1; m >= 0; m--)
|
||||
+ {
|
||||
+ struct link_map *dep = map->l_reldeps->list[m];
|
||||
+ if (dep->l_visited == 0
|
||||
+ && dep->l_main_map == 0)
|
||||
+ dfs_traversal (rpo, dep, do_reldeps);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ *rpo -= 1;
|
||||
+ **rpo = map;
|
||||
+}
|
||||
+
|
||||
+/* Topologically sort array MAPS according to dependencies of the contained
|
||||
+ objects. */
|
||||
+
|
||||
+static void
|
||||
+_dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps,
|
||||
+ unsigned int skip __attribute__ ((unused)), bool for_fini)
|
||||
+{
|
||||
+ for (int i = nmaps - 1; i >= 0; i--)
|
||||
+ maps[i]->l_visited = 0;
|
||||
+
|
||||
+ /* We apply DFS traversal for each of maps[i] until the whole total order
|
||||
+ is found and we're at the start of the Reverse-Postorder (RPO) sequence,
|
||||
+ which is a topological sort.
|
||||
+
|
||||
+ We go from maps[nmaps - 1] backwards towards maps[0] at this level.
|
||||
+ Due to the breadth-first search (BFS) ordering we receive, going
|
||||
+ backwards usually gives a more shallow depth-first recursion depth,
|
||||
+ adding more stack usage safety. Also, combined with the natural
|
||||
+ processing order of l_initfini[] at each node during DFS, this maintains
|
||||
+ an ordering closer to the original link ordering in the sorting results
|
||||
+ under most simpler cases.
|
||||
+
|
||||
+ Another reason we order the top level backwards, it that maps[0] is
|
||||
+ usually exactly the main object of which we're in the midst of
|
||||
+ _dl_map_object_deps() processing, and maps[0]->l_initfini[] is still
|
||||
+ blank. If we start the traversal from maps[0], since having no
|
||||
+ dependencies yet filled in, maps[0] will always be immediately
|
||||
+ incorrectly placed at the last place in the order (first in reverse).
|
||||
+ Adjusting the order so that maps[0] is last traversed naturally avoids
|
||||
+ this problem.
|
||||
+
|
||||
+ Further, the old "optimization" of skipping the main object at maps[0]
|
||||
+ from the call-site (i.e. _dl_sort_maps(maps+1,nmaps-1)) is in general
|
||||
+ no longer valid, since traversing along object dependency-links
|
||||
+ may "find" the main object even when it is not included in the initial
|
||||
+ order (e.g. a dlopen()'ed shared object can have circular dependencies
|
||||
+ linked back to itself). In such a case, traversing N-1 objects will
|
||||
+ create a N-object result, and raise problems.
|
||||
+
|
||||
+ To summarize, just passing in the full list, and iterating from back
|
||||
+ to front makes things much more straightforward. */
|
||||
+
|
||||
+ /* Array to hold RPO sorting results, before we copy back to maps[]. */
|
||||
+ struct link_map *rpo[nmaps];
|
||||
+
|
||||
+ /* The 'head' position during each DFS iteration. Note that we start at
|
||||
+ one past the last element due to first-decrement-then-store (see the
|
||||
+ bottom of above dfs_traversal() routine). */
|
||||
+ struct link_map **rpo_head = &rpo[nmaps];
|
||||
+
|
||||
+ bool do_reldeps = false;
|
||||
+ bool *do_reldeps_ref = (for_fini ? &do_reldeps : NULL);
|
||||
+
|
||||
+ for (int i = nmaps - 1; i >= 0; i--)
|
||||
+ {
|
||||
+ dfs_traversal (&rpo_head, maps[i], do_reldeps_ref);
|
||||
+
|
||||
+ /* We can break early if all objects are already placed. */
|
||||
+ if (rpo_head == rpo)
|
||||
+ goto end;
|
||||
+ }
|
||||
+ assert (rpo_head == rpo);
|
||||
+
|
||||
+ end:
|
||||
+ /* Here we may do a second pass of sorting, using only l_initfini[]
|
||||
+ static dependency links. This is avoided if !FOR_FINI or if we didn't
|
||||
+ find any reldeps in the first DFS traversal.
|
||||
+
|
||||
+ The reason we do this is: while it is unspecified how circular
|
||||
+ dependencies should be handled, the presumed reasonable behavior is to
|
||||
+ have destructors to respect static dependency links as much as possible,
|
||||
+ overriding reldeps if needed. And the first sorting pass, which takes
|
||||
+ l_initfini/l_reldeps links equally, may not preserve this priority.
|
||||
+
|
||||
+ Hence we do a 2nd sorting pass, taking only DT_NEEDED links into account
|
||||
+ (see how the do_reldeps argument to dfs_traversal() is NULL below). */
|
||||
+ if (do_reldeps)
|
||||
+ {
|
||||
+ for (int i = nmaps - 1; i >= 0; i--)
|
||||
+ rpo[i]->l_visited = 0;
|
||||
+
|
||||
+ struct link_map **maps_head = &maps[nmaps];
|
||||
+ for (int i = nmaps - 1; i >= 0; i--)
|
||||
+ {
|
||||
+ dfs_traversal (&maps_head, rpo[i], NULL);
|
||||
+
|
||||
+ /* We can break early if all objects are already placed.
|
||||
+ The below memcpy is not needed in the do_reldeps case here,
|
||||
+ since we wrote back to maps[] during DFS traversal. */
|
||||
+ if (maps_head == maps)
|
||||
+ return;
|
||||
+ }
|
||||
+ assert (maps_head == maps);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ memcpy (maps, rpo, sizeof (struct link_map *) * nmaps);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+_dl_sort_maps_init (void)
|
||||
+{
|
||||
+ int32_t algorithm = TUNABLE_GET (glibc, rtld, dynamic_sort, int32_t, NULL);
|
||||
+ GLRO(dl_dso_sort_algo) = algorithm == 1 ? dso_sort_algorithm_original
|
||||
+ : dso_sort_algorithm_dfs;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+_dl_sort_maps (struct link_map **maps, unsigned int nmaps,
|
||||
+ unsigned int skip, bool for_fini)
|
||||
+{
|
||||
+ /* It can be tempting to use a static function pointer to store and call
|
||||
+ the current selected sorting algorithm routine, but experimentation
|
||||
+ shows that current processors still do not handle indirect branches
|
||||
+ that efficiently, plus a static function pointer will involve
|
||||
+ PTR_MANGLE/DEMANGLE, further impairing performance of small, common
|
||||
+ input cases. A simple if-case with direct function calls appears to
|
||||
+ be the fastest. */
|
||||
+ if (__glibc_likely (GLRO(dl_dso_sort_algo) == dso_sort_algorithm_original))
|
||||
+ _dl_sort_maps_original (maps, nmaps, skip, for_fini);
|
||||
+ else
|
||||
+ _dl_sort_maps_dfs (maps, nmaps, skip, for_fini);
|
||||
+}
|
||||
+
|
||||
+#endif /* HAVE_TUNABLES. */
|
||||
diff --git a/elf/dl-support.c b/elf/dl-support.c
|
||||
index d8c06ba7eb4c76ea..c5ee5d33aa7e1d65 100644
|
||||
--- a/elf/dl-support.c
|
||||
+++ b/elf/dl-support.c
|
||||
@@ -166,6 +166,8 @@ size_t _dl_phnum;
|
||||
uint64_t _dl_hwcap;
|
||||
uint64_t _dl_hwcap2;
|
||||
|
||||
+enum dso_sort_algorithm _dl_dso_sort_algo;
|
||||
+
|
||||
/* The value of the FPU control word the kernel will preset in hardware. */
|
||||
fpu_control_t _dl_fpu_control = _FPU_DEFAULT;
|
||||
|
||||
diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c
|
||||
index 2c684c2db2a1f59b..4dc366eea445e974 100644
|
||||
--- a/elf/dl-sysdep.c
|
||||
+++ b/elf/dl-sysdep.c
|
||||
@@ -231,6 +231,9 @@ _dl_sysdep_start (void **start_argptr,
|
||||
|
||||
__tunables_init (_environ);
|
||||
|
||||
+ /* Initialize DSO sorting algorithm after tunables. */
|
||||
+ _dl_sort_maps_init ();
|
||||
+
|
||||
#ifdef DL_SYSDEP_INIT
|
||||
DL_SYSDEP_INIT;
|
||||
#endif
|
||||
diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list
|
||||
index 8ddd4a23142a941b..46ffb2378416f90f 100644
|
||||
--- a/elf/dl-tunables.list
|
||||
+++ b/elf/dl-tunables.list
|
||||
@@ -156,4 +156,13 @@ glibc {
|
||||
security_level: SXID_IGNORE
|
||||
}
|
||||
}
|
||||
+
|
||||
+ rtld {
|
||||
+ dynamic_sort {
|
||||
+ type: INT_32
|
||||
+ minval: 1
|
||||
+ maxval: 2
|
||||
+ default: 1
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
diff --git a/elf/dso-sort-tests-1.def b/elf/dso-sort-tests-1.def
|
||||
index 873ddf55d91155c6..5f7f18ef270bc12d 100644
|
||||
--- a/elf/dso-sort-tests-1.def
|
||||
+++ b/elf/dso-sort-tests-1.def
|
||||
@@ -62,5 +62,5 @@ output: b>a>{}<a<b
|
||||
# The below expected outputs are what the two algorithms currently produce
|
||||
# respectively, for regression testing purposes.
|
||||
tst-bz15311: {+a;+e;+f;+g;+d;%d;-d;-g;-f;-e;-a};a->b->c->d;d=>[ba];c=>a;b=>e=>a;c=>f=>b;d=>g=>c
|
||||
-xfail_output(glibc.rtld.dynamic_sort=1): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<a<c<d<g<f<b<e];}
|
||||
+output(glibc.rtld.dynamic_sort=1): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<a<c<d<g<f<b<e];}
|
||||
output(glibc.rtld.dynamic_sort=2): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<g<f<a<b<c<d<e];}
|
||||
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||
index 6bbb373c5743cb99..84eac9a8df7125a6 100644
|
||||
--- a/elf/rtld.c
|
||||
+++ b/elf/rtld.c
|
||||
@@ -1426,6 +1426,9 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||
main_map->l_name = (char *) "";
|
||||
*user_entry = main_map->l_entry;
|
||||
|
||||
+ /* Set bit indicating this is the main program map. */
|
||||
+ main_map->l_main_map = 1;
|
||||
+
|
||||
#ifdef HAVE_AUX_VECTOR
|
||||
/* Adjust the on-stack auxiliary vector so that it looks like the
|
||||
binary was executed directly. */
|
||||
diff --git a/elf/tst-rtld-list-tunables.exp b/elf/tst-rtld-list-tunables.exp
|
||||
index 9f66c528855fb21d..9bf572715f996ca6 100644
|
||||
--- a/elf/tst-rtld-list-tunables.exp
|
||||
+++ b/elf/tst-rtld-list-tunables.exp
|
||||
@@ -10,5 +10,6 @@ glibc.malloc.tcache_max: 0x0 (min: 0x0, max: 0x[f]+)
|
||||
glibc.malloc.tcache_unsorted_limit: 0x0 (min: 0x0, max: 0x[f]+)
|
||||
glibc.malloc.top_pad: 0x0 (min: 0x0, max: 0x[f]+)
|
||||
glibc.malloc.trim_threshold: 0x0 (min: 0x0, max: 0x[f]+)
|
||||
+glibc.rtld.dynamic_sort: 1 (min: 1, max: 2)
|
||||
glibc.rtld.nns: 0x4 (min: 0x1, max: 0x10)
|
||||
glibc.rtld.optional_static_tls: 0x200 (min: 0x0, max: 0x[f]+)
|
||||
diff --git a/include/link.h b/include/link.h
|
||||
index c46aced9f7b43ba0..4dcf01d8aea90bc2 100644
|
||||
--- a/include/link.h
|
||||
+++ b/include/link.h
|
||||
@@ -181,6 +181,11 @@ struct link_map
|
||||
unsigned int l_init_called:1; /* Nonzero if DT_INIT function called. */
|
||||
unsigned int l_global:1; /* Nonzero if object in _dl_global_scope. */
|
||||
unsigned int l_reserved:2; /* Reserved for internal use. */
|
||||
+ unsigned int l_main_map:1; /* Nonzero for the map of the main program. */
|
||||
+ unsigned int l_visited:1; /* Used internally for map dependency
|
||||
+ graph traversal. */
|
||||
+ unsigned int l_map_used:1; /* These two bits are used during traversal */
|
||||
+ unsigned int l_map_done:1; /* of maps in _dl_close_worker. */
|
||||
unsigned int l_phdr_allocated:1; /* Nonzero if the data structure pointed
|
||||
to by `l_phdr' is allocated. */
|
||||
unsigned int l_soname_added:1; /* Nonzero if the SONAME is for sure in
|
||||
diff --git a/manual/tunables.texi b/manual/tunables.texi
|
||||
index 658547c6137bf177..10f4d75993f9940f 100644
|
||||
--- a/manual/tunables.texi
|
||||
+++ b/manual/tunables.texi
|
||||
@@ -309,6 +309,17 @@ changed once allocated at process startup. The default allocation of
|
||||
optional static TLS is 512 bytes and is allocated in every thread.
|
||||
@end deftp
|
||||
|
||||
+@deftp Tunable glibc.rtld.dynamic_sort
|
||||
+Sets the algorithm to use for DSO sorting, valid values are @samp{1} and
|
||||
+@samp{2}. For value of @samp{1}, an older O(n^3) algorithm is used, which is
|
||||
+long time tested, but may have performance issues when dependencies between
|
||||
+shared objects contain cycles due to circular dependencies. When set to the
|
||||
+value of @samp{2}, a different algorithm is used, which implements a
|
||||
+topological sort through depth-first search, and does not exhibit the
|
||||
+performance issues of @samp{1}.
|
||||
+
|
||||
+The default value of this tunable is @samp{1}.
|
||||
+@end deftp
|
||||
|
||||
@node Elision Tunables
|
||||
@section Elision Tunables
|
||||
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||
index fcbbf6974827cdf1..bcf1f199c5985c65 100644
|
||||
--- a/sysdeps/generic/ldsodefs.h
|
||||
+++ b/sysdeps/generic/ldsodefs.h
|
||||
@@ -245,6 +245,13 @@ enum allowmask
|
||||
};
|
||||
|
||||
|
||||
+/* DSO sort algorithm to use (check dl-sort-maps.c). */
|
||||
+enum dso_sort_algorithm
|
||||
+ {
|
||||
+ dso_sort_algorithm_original,
|
||||
+ dso_sort_algorithm_dfs
|
||||
+ };
|
||||
+
|
||||
struct audit_ifaces
|
||||
{
|
||||
void (*activity) (uintptr_t *, unsigned int);
|
||||
@@ -672,6 +679,8 @@ struct rtld_global_ro
|
||||
platforms. */
|
||||
EXTERN uint64_t _dl_hwcap2;
|
||||
|
||||
+ EXTERN enum dso_sort_algorithm _dl_dso_sort_algo;
|
||||
+
|
||||
#ifdef SHARED
|
||||
/* We add a function table to _rtld_global which is then used to
|
||||
call the function instead of going through the PLT. The result
|
||||
@@ -1098,7 +1107,7 @@ extern void _dl_fini (void) attribute_hidden;
|
||||
|
||||
/* Sort array MAPS according to dependencies of the contained objects. */
|
||||
extern void _dl_sort_maps (struct link_map **maps, unsigned int nmaps,
|
||||
- char *used, bool for_fini) attribute_hidden;
|
||||
+ unsigned int skip, bool for_fini) attribute_hidden;
|
||||
|
||||
/* The dynamic linker calls this function before and having changing
|
||||
any shared object mappings. The `r_state' member of `struct r_debug'
|
||||
@@ -1225,6 +1234,9 @@ extern struct link_map * _dl_get_dl_main_map (void)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
+/* Initialize the DSO sort algorithm to use. */
|
||||
+extern void _dl_sort_maps_init (void) attribute_hidden;
|
||||
+
|
||||
/* Initialization of libpthread for statically linked applications.
|
||||
If libpthread is not linked in, this is an empty function. */
|
||||
void __pthread_initialize_minimal (void) weak_function;
|
@ -0,0 +1,25 @@
|
||||
commit d3bf2f5927d51258a51ac7fde04f4805f8ee294a
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Wed Nov 3 09:19:30 2021 -0300
|
||||
|
||||
elf: Do not run DSO sorting if tunables is not enabled
|
||||
|
||||
Since the argorithm selection requires tunables.
|
||||
|
||||
Checked on x86_64-linux-gnu with --enable-tunables=no.
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 8dd2b24328113536..02ee834fdaf00a26 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -483,8 +483,10 @@ include $(objpfx)$(1).generated-makefile
|
||||
endef
|
||||
|
||||
# Generate from each testcase description file
|
||||
+ifeq (yes,$(have-tunables))
|
||||
$(eval $(call include_dsosort_tests,dso-sort-tests-1.def))
|
||||
$(eval $(call include_dsosort_tests,dso-sort-tests-2.def))
|
||||
+endif
|
||||
|
||||
check-abi: $(objpfx)check-abi-ld.out
|
||||
tests-special += $(objpfx)check-abi-ld.out
|
@ -0,0 +1,189 @@
|
||||
commit b4bbedb1e75737a80bcc3d53d6eef1fbe0b5f4d5
|
||||
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||
Date: Sat Nov 6 14:13:27 2021 -0700
|
||||
|
||||
dso-ordering-test.py: Put all sources in one directory [BZ #28550]
|
||||
|
||||
Put all sources for DSO sorting tests in the dso-sort-tests-src directory
|
||||
and compile test relocatable objects with
|
||||
|
||||
$(objpfx)tst-dso-ordering1-dir/tst-dso-ordering1-a.os: $(objpfx)dso-sort-tests-src/tst-dso-ordering1-a.c
|
||||
$(compile.c) $(OUTPUT_OPTION)
|
||||
|
||||
to avoid random $< values from $(before-compile) when compiling test
|
||||
relocatable objects with
|
||||
|
||||
$(objpfx)%$o: $(objpfx)%.c $(before-compile); $$(compile-command.c)
|
||||
compile-command.c = $(compile.c) $(OUTPUT_OPTION) $(compile-mkdep-flags)
|
||||
compile.c = $(CC) $< -c $(CFLAGS) $(CPPFLAGS)
|
||||
|
||||
for 3 "make -j 28" parallel builds on a machine with 112 cores at the
|
||||
same time.
|
||||
|
||||
This partially fixes BZ #28550.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/scripts/dso-ordering-test.py b/scripts/dso-ordering-test.py
|
||||
index 944ee740527d60fd..bde0406be9da14fc 100644
|
||||
--- a/scripts/dso-ordering-test.py
|
||||
+++ b/scripts/dso-ordering-test.py
|
||||
@@ -526,9 +526,13 @@ def process_testcase(t):
|
||||
base_test_name = t.test_name
|
||||
test_subdir = base_test_name + "-dir"
|
||||
testpfx = objpfx + test_subdir + "/"
|
||||
+ test_srcdir = "dso-sort-tests-src/"
|
||||
+ testpfx_src = objpfx + test_srcdir
|
||||
|
||||
if not os.path.exists(testpfx):
|
||||
os.mkdir(testpfx)
|
||||
+ if not os.path.exists(testpfx_src):
|
||||
+ os.mkdir(testpfx_src)
|
||||
|
||||
def find_objs_not_depended_on(t):
|
||||
objs_not_depended_on = []
|
||||
@@ -595,6 +599,11 @@ def process_testcase(t):
|
||||
# Print out needed Makefile fragments for use in glibc/elf/Makefile.
|
||||
module_names = ""
|
||||
for o in test_descr.objs:
|
||||
+ rule = ("$(objpfx)" + test_subdir + "/" + test_name
|
||||
+ + "-" + o + ".os: $(objpfx)" + test_srcdir
|
||||
+ + test_name + "-" + o + ".c\n"
|
||||
+ "\t$(compile.c) $(OUTPUT_OPTION)\n")
|
||||
+ makefile.write (rule)
|
||||
module_names += " " + test_subdir + "/" + test_name + "-" + o
|
||||
makefile.write("modules-names +=%s\n" % (module_names))
|
||||
|
||||
@@ -637,7 +646,7 @@ def process_testcase(t):
|
||||
# object. This only needs to be done at most once for
|
||||
# an object name.
|
||||
if not dep in fake_created:
|
||||
- f = open(testpfx + test_name + "-" + dep
|
||||
+ f = open(testpfx_src + test_name + "-" + dep
|
||||
+ ".FAKE.c", "w")
|
||||
f.write(" \n")
|
||||
f.close()
|
||||
@@ -648,6 +657,12 @@ def process_testcase(t):
|
||||
% (test_name + "-" + dep + ".FAKE.so",
|
||||
("$(objpfx)" + test_subdir + "/"
|
||||
+ test_name + "-" + dep + ".so")))
|
||||
+ rule = ("$(objpfx)" + test_subdir + "/"
|
||||
+ + test_name + "-" + dep + ".FAKE.os: "
|
||||
+ "$(objpfx)" + test_srcdir
|
||||
+ + test_name + "-" + dep + ".FAKE.c\n"
|
||||
+ "\t$(compile.c) $(OUTPUT_OPTION)\n")
|
||||
+ makefile.write (rule)
|
||||
makefile.write \
|
||||
("modules-names += %s\n"
|
||||
% (test_subdir + "/"
|
||||
@@ -687,6 +702,10 @@ def process_testcase(t):
|
||||
+ test_descr.soname_map['#'] + ".so")
|
||||
ldflags += (" -Wl,-soname=" + soname)
|
||||
makefile.write("LDFLAGS-%s = %s\n" % (test_name, ldflags))
|
||||
+ rule = ("$(objpfx)" + test_subdir + "/" + test_name + ".o: "
|
||||
+ "$(objpfx)" + test_srcdir + test_name + ".c\n"
|
||||
+ "\t$(compile.c) $(OUTPUT_OPTION)\n")
|
||||
+ makefile.write (rule)
|
||||
|
||||
not_depended_objs = find_objs_not_depended_on(test_descr)
|
||||
if not_depended_objs:
|
||||
@@ -745,7 +764,7 @@ def process_testcase(t):
|
||||
" something_failed=true\n"
|
||||
"else\n"
|
||||
" diff -wu ${common_objpfx}elf/%s/%s%s.output \\\n"
|
||||
- " ${common_objpfx}elf/%s/%s%s.exp\n"
|
||||
+ " ${common_objpfx}elf/%s%s%s.exp\n"
|
||||
" if [ $? -ne 0 ]; then\n"
|
||||
" echo '%sFAIL: %s%s expected output comparison'\n"
|
||||
" something_failed=true\n"
|
||||
@@ -753,14 +772,14 @@ def process_testcase(t):
|
||||
"fi\n"
|
||||
% (("X" if xfail else ""), test_name, tunable_descr,
|
||||
test_subdir, test_name, tunable_sfx,
|
||||
- test_subdir, base_test_name, exp_tunable_sfx,
|
||||
+ test_srcdir, base_test_name, exp_tunable_sfx,
|
||||
("X" if xfail else ""), test_name, tunable_descr))
|
||||
|
||||
# Generate C files according to dependency and calling relations from
|
||||
# description string.
|
||||
for obj in test_descr.objs:
|
||||
src_name = test_name + "-" + obj + ".c"
|
||||
- f = open(testpfx + src_name, "w")
|
||||
+ f = open(testpfx_src + src_name, "w")
|
||||
if obj in test_descr.callrefs:
|
||||
called_objs = test_descr.callrefs[obj]
|
||||
for callee in called_objs:
|
||||
@@ -804,7 +823,7 @@ def process_testcase(t):
|
||||
f.close()
|
||||
|
||||
# Open C file for writing main program
|
||||
- f = open(testpfx + test_name + ".c", "w")
|
||||
+ f = open(testpfx_src + test_name + ".c", "w")
|
||||
|
||||
# if there are some operations in main(), it means we need -ldl
|
||||
f.write("#include <stdio.h>\n")
|
||||
@@ -885,7 +904,7 @@ def process_testcase(t):
|
||||
for obj in test_descr.objs:
|
||||
src_name = test_name + "-" + obj + ".c"
|
||||
obj_name = test_name + "-" + obj + ".os"
|
||||
- run_cmd([build_gcc, "-c", "-fPIC", testpfx + src_name,
|
||||
+ run_cmd([build_gcc, "-c", "-fPIC", testpfx_src + src_name,
|
||||
"-o", testpfx + obj_name])
|
||||
|
||||
obj_processed = {}
|
||||
@@ -903,10 +922,12 @@ def process_testcase(t):
|
||||
deps.append(dep + ".FAKE")
|
||||
if not dep in fake_created:
|
||||
base_name = testpfx + test_name + "-" + dep
|
||||
+ src_base_name = (testpfx_src + test_name
|
||||
+ + "-" + dep)
|
||||
cmd = [build_gcc, "-Wl,--no-as-needed",
|
||||
("-Wl,-soname=" + base_name + ".so"),
|
||||
"-shared", base_name + ".FAKE.c",
|
||||
- "-o", base_name + ".FAKE.so"]
|
||||
+ "-o", src_base_name + ".FAKE.so"]
|
||||
run_cmd(cmd)
|
||||
fake_created[dep] = True
|
||||
dso_deps = map(lambda d: testpfx + test_name + "-" + d + ".so",
|
||||
@@ -932,7 +953,7 @@ def process_testcase(t):
|
||||
main_deps = map(lambda d: testpfx + test_name + "-" + d + ".so",
|
||||
deps)
|
||||
cmd = [build_gcc, "-Wl,--no-as-needed", "-o", testpfx + test_name,
|
||||
- testpfx + test_name + ".c", "-L%s" % (os.getcwd()),
|
||||
+ testpfx_src + test_name + ".c", "-L%s" % (os.getcwd()),
|
||||
"-Wl,-rpath-link=%s" % (os.getcwd())]
|
||||
if '#' in test_descr.soname_map:
|
||||
soname = ("-Wl,-soname=" + testpfx + test_name + "-"
|
||||
@@ -987,14 +1008,14 @@ def process_testcase(t):
|
||||
sfx = ""
|
||||
if r[0] != "":
|
||||
sfx = "-" + r[0].replace("=","_")
|
||||
- f = open(testpfx + t.test_name + sfx + ".exp", "w")
|
||||
+ f = open(testpfx_src + t.test_name + sfx + ".exp", "w")
|
||||
(output, xfail) = r[1]
|
||||
f.write('%s' % output)
|
||||
f.close()
|
||||
|
||||
# Create header part of top-level testcase shell script, to wrap execution
|
||||
# and output comparison together.
|
||||
- t.sh = open(testpfx + t.test_name + ".sh", "w")
|
||||
+ t.sh = open(testpfx_src + t.test_name + ".sh", "w")
|
||||
t.sh.write("#!/bin/sh\n")
|
||||
t.sh.write("# Test driver for %s, generated by "
|
||||
"dso-ordering-test.py\n" % (t.test_name))
|
||||
@@ -1022,12 +1043,12 @@ def process_testcase(t):
|
||||
sfx = ""
|
||||
if r[0] != "":
|
||||
sfx = "-" + r[0].replace("=","_")
|
||||
- expected_output_files += " $(objpfx)%s/%s%s.exp" % (test_subdir,
|
||||
+ expected_output_files += " $(objpfx)%s%s%s.exp" % (test_srcdir,
|
||||
t.test_name, sfx)
|
||||
makefile.write \
|
||||
- ("$(objpfx)%s.out: $(objpfx)%s/%s.sh%s "
|
||||
+ ("$(objpfx)%s.out: $(objpfx)%s%s.sh%s "
|
||||
"$(common-objpfx)support/test-run-command\n"
|
||||
- % (t.test_name, test_subdir, t.test_name,
|
||||
+ % (t.test_name, test_srcdir, t.test_name,
|
||||
expected_output_files))
|
||||
makefile.write("\t$(SHELL) $< $(common-objpfx) '$(test-wrapper-env)' "
|
||||
"'$(run-program-env)' > $@; $(evaluate-test)\n")
|
@ -0,0 +1,45 @@
|
||||
commit 1f67d8286b5da9266a138198ef1f15c27cbb0010
|
||||
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||
Date: Mon Nov 15 16:28:39 2021 -0800
|
||||
|
||||
elf: Use a temporary file to generate Makefile fragments [BZ #28550]
|
||||
|
||||
1. Use a temporary file to generate Makefile fragments for DSO sorting
|
||||
tests and use -include on them.
|
||||
2. Add Makefile fragments to postclean-generated so that a "make clean"
|
||||
removes the autogenerated fragments and a subsequent "make" regenerates
|
||||
them.
|
||||
|
||||
This partially fixes BZ #28550.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 02ee834fdaf00a26..535ba4260fb98e64 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -471,6 +471,7 @@ tests-special += $(objpfx)order-cmp.out $(objpfx)tst-array1-cmp.out \
|
||||
$(objpfx)tst-unused-dep-cmp.out
|
||||
endif
|
||||
|
||||
+ifndef avoid-generated
|
||||
# DSO sorting tests:
|
||||
# The dso-ordering-test.py script generates testcase source files in $(objpfx),
|
||||
# creating a $(objpfx)<testcase-name>-dir for each testcase, and creates a
|
||||
@@ -478,9 +479,14 @@ endif
|
||||
define include_dsosort_tests
|
||||
$(objpfx)$(1).generated-makefile: $(1)
|
||||
$(PYTHON) $(..)scripts/dso-ordering-test.py \
|
||||
- --description-file $$< --objpfx $(objpfx) --output-makefile $$@
|
||||
-include $(objpfx)$(1).generated-makefile
|
||||
+ --description-file $$< --objpfx $(objpfx) --output-makefile $$@T
|
||||
+ mv $$@T $$@
|
||||
+-include $(objpfx)$(1).generated-makefile
|
||||
endef
|
||||
+endif
|
||||
+
|
||||
+postclean-generated += $(objpfx)/dso-sort-tests-2.generated-makefile \
|
||||
+ $(objpfx)/dso-sort-tests-2.generated-makefile
|
||||
|
||||
# Generate from each testcase description file
|
||||
ifeq (yes,$(have-tunables))
|
@ -0,0 +1,49 @@
|
||||
commit 0884724a95b60452ad483dbe086d237d02ba624d
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Dec 14 12:37:44 2021 +0100
|
||||
|
||||
elf: Use new dependency sorting algorithm by default
|
||||
|
||||
The default has to change eventually, and there are no known failures
|
||||
that require a delay.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list
|
||||
index 46ffb2378416f90f..ffcd7f18d4fafb91 100644
|
||||
--- a/elf/dl-tunables.list
|
||||
+++ b/elf/dl-tunables.list
|
||||
@@ -162,7 +162,7 @@ glibc {
|
||||
type: INT_32
|
||||
minval: 1
|
||||
maxval: 2
|
||||
- default: 1
|
||||
+ default: 2
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/elf/tst-rtld-list-tunables.exp b/elf/tst-rtld-list-tunables.exp
|
||||
index 9bf572715f996ca6..44e4834cfb431633 100644
|
||||
--- a/elf/tst-rtld-list-tunables.exp
|
||||
+++ b/elf/tst-rtld-list-tunables.exp
|
||||
@@ -10,6 +10,6 @@ glibc.malloc.tcache_max: 0x0 (min: 0x0, max: 0x[f]+)
|
||||
glibc.malloc.tcache_unsorted_limit: 0x0 (min: 0x0, max: 0x[f]+)
|
||||
glibc.malloc.top_pad: 0x0 (min: 0x0, max: 0x[f]+)
|
||||
glibc.malloc.trim_threshold: 0x0 (min: 0x0, max: 0x[f]+)
|
||||
-glibc.rtld.dynamic_sort: 1 (min: 1, max: 2)
|
||||
+glibc.rtld.dynamic_sort: 2 (min: 1, max: 2)
|
||||
glibc.rtld.nns: 0x4 (min: 0x1, max: 0x10)
|
||||
glibc.rtld.optional_static_tls: 0x200 (min: 0x0, max: 0x[f]+)
|
||||
diff --git a/manual/tunables.texi b/manual/tunables.texi
|
||||
index 10f4d75993f9940f..7c3b28d029410a6f 100644
|
||||
--- a/manual/tunables.texi
|
||||
+++ b/manual/tunables.texi
|
||||
@@ -318,7 +318,7 @@ value of @samp{2}, a different algorithm is used, which implements a
|
||||
topological sort through depth-first search, and does not exhibit the
|
||||
performance issues of @samp{1}.
|
||||
|
||||
-The default value of this tunable is @samp{1}.
|
||||
+The default value of this tunable is @samp{2}.
|
||||
@end deftp
|
||||
|
||||
@node Elision Tunables
|
@ -0,0 +1,547 @@
|
||||
commit 28713c06129f8f64f88c423266e6ff2880216509
|
||||
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||
Date: Mon Dec 13 09:43:52 2021 -0800
|
||||
|
||||
elf: Sort tests and modules-names
|
||||
|
||||
Sort tests and modules-names to reduce future conflicts.
|
||||
|
||||
Conflicts:
|
||||
elf/Makefile
|
||||
(Usual backport differences. Recreated tests and module-names
|
||||
from scratch. Note that the upstream sort order is difficult
|
||||
to fathom.)
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 535ba4260fb98e64..33df5b4714176adc 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -193,40 +193,134 @@ static-dlopen-environment = \
|
||||
tst-tls9-static-ENV = $(static-dlopen-environment)
|
||||
tst-single_threaded-static-dlopen-ENV = $(static-dlopen-environment)
|
||||
|
||||
-tests += restest1 preloadtest loadfail multiload origtest resolvfail \
|
||||
- constload1 order noload filter \
|
||||
- reldep reldep2 reldep3 reldep4 nodelete nodelete2 \
|
||||
- nodlopen nodlopen2 lateglobal initfirst global \
|
||||
- restest2 next dblload dblunload reldep5 reldep6 reldep7 reldep8 \
|
||||
- tst-tls4 tst-tls5 \
|
||||
- tst-tls10 tst-tls11 tst-tls12 tst-tls13 tst-tls14 tst-tls15 \
|
||||
- tst-tls16 tst-tls17 tst-tls18 tst-tls19 tst-tls-dlinfo \
|
||||
- tst-align tst-align2 \
|
||||
- tst-dlmodcount tst-dlopenrpath tst-deep1 \
|
||||
- tst-dlmopen1 tst-dlmopen3 \
|
||||
- unload3 unload4 unload5 unload6 unload7 unload8 tst-global1 order2 \
|
||||
- tst-audit1 tst-audit2 tst-audit8 tst-audit9 \
|
||||
- tst-addr1 tst-thrlock \
|
||||
- tst-unique1 tst-unique2 $(if $(CXX),tst-unique3 tst-unique4 \
|
||||
- tst-nodelete tst-dlopen-nodelete-reloc) \
|
||||
- tst-initorder tst-initorder2 tst-relsort1 tst-null-argv \
|
||||
- tst-tlsalign tst-tlsalign-extern tst-nodelete-opened \
|
||||
- tst-nodelete2 tst-audit11 tst-audit12 tst-dlsym-error tst-noload \
|
||||
- tst-latepthread tst-tls-manydynamic tst-nodelete-dlclose \
|
||||
- tst-debug1 tst-main1 tst-absolute-sym tst-absolute-zero tst-big-note \
|
||||
- tst-unwind-ctor tst-unwind-main tst-audit13 \
|
||||
- tst-sonamemove-link tst-sonamemove-dlopen tst-dlopen-tlsmodid \
|
||||
- tst-dlopen-self tst-auditmany tst-initfinilazyfail tst-dlopenfail \
|
||||
- tst-dlopenfail-2 \
|
||||
- tst-filterobj tst-filterobj-dlopen tst-auxobj tst-auxobj-dlopen \
|
||||
- tst-audit14 tst-audit15 tst-audit16 tst-audit17 \
|
||||
- tst-single_threaded tst-single_threaded-pthread \
|
||||
- tst-tls-ie tst-tls-ie-dlmopen argv0test \
|
||||
- tst-glibc-hwcaps tst-glibc-hwcaps-prepend tst-glibc-hwcaps-mask \
|
||||
- tst-tls20 tst-tls21 tst-dlmopen-dlerror tst-dlmopen-gethostbyname \
|
||||
- tst-dl-is_dso tst-ro-dynamic \
|
||||
- tst-rtld-run-static \
|
||||
+tests += \
|
||||
+ argv0test \
|
||||
+ constload1 \
|
||||
+ dblload \
|
||||
+ dblunload \
|
||||
+ filter \
|
||||
+ global \
|
||||
+ initfirst \
|
||||
+ lateglobal \
|
||||
+ loadfail \
|
||||
+ multiload \
|
||||
+ next \
|
||||
+ nodelete \
|
||||
+ nodelete2 \
|
||||
+ nodlopen \
|
||||
+ nodlopen2 \
|
||||
+ noload \
|
||||
+ order \
|
||||
+ order2 \
|
||||
+ origtest \
|
||||
+ preloadtest \
|
||||
+ reldep \
|
||||
+ reldep2 \
|
||||
+ reldep3 \
|
||||
+ reldep4 \
|
||||
+ reldep5 \
|
||||
+ reldep6 \
|
||||
+ reldep7 \
|
||||
+ reldep8 \
|
||||
+ resolvfail \
|
||||
+ restest1 \
|
||||
+ restest2 \
|
||||
+ tst-absolute-sym \
|
||||
+ tst-absolute-zero \
|
||||
+ tst-addr1 \
|
||||
+ tst-align \
|
||||
+ tst-align2 \
|
||||
+ tst-audit1 \
|
||||
+ tst-audit2 \
|
||||
+ tst-audit8 \
|
||||
+ tst-audit9 \
|
||||
+ tst-audit11 \
|
||||
+ tst-audit12 \
|
||||
+ tst-audit13 \
|
||||
+ tst-audit14 \
|
||||
+ tst-audit15 \
|
||||
+ tst-audit16 \
|
||||
+ tst-audit17 \
|
||||
+ tst-auditmany \
|
||||
+ tst-auxobj \
|
||||
+ tst-auxobj-dlopen \
|
||||
+ tst-big-note \
|
||||
+ tst-debug1 \
|
||||
+ tst-deep1 \
|
||||
+ tst-dl-is_dso \
|
||||
+ tst-dlmodcount \
|
||||
+ tst-dlmopen1 \
|
||||
+ tst-dlmopen3 \
|
||||
+ tst-dlmopen-dlerror \
|
||||
+ tst-dlmopen-gethostbyname \
|
||||
+ tst-dlopenfail \
|
||||
+ tst-dlopenfail-2 \
|
||||
+ tst-dlopenrpath \
|
||||
+ tst-dlopen-self \
|
||||
+ tst-dlopen-tlsmodid \
|
||||
+ tst-dlsym-error \
|
||||
+ tst-filterobj \
|
||||
+ tst-filterobj-dlopen \
|
||||
+ tst-glibc-hwcaps \
|
||||
+ tst-glibc-hwcaps-mask \
|
||||
+ tst-glibc-hwcaps-prepend \
|
||||
+ tst-global1 \
|
||||
+ tst-initfinilazyfail \
|
||||
+ tst-initorder \
|
||||
+ tst-initorder2 \
|
||||
+ tst-latepthread \
|
||||
+ tst-main1 \
|
||||
+ tst-nodelete2 \
|
||||
+ tst-nodelete-dlclose \
|
||||
+ tst-nodelete-opened \
|
||||
+ tst-noload \
|
||||
+ tst-null-argv \
|
||||
+ tst-relsort1 \
|
||||
+ tst-ro-dynamic \
|
||||
+ tst-rtld-run-static \
|
||||
+ tst-single_threaded \
|
||||
+ tst-single_threaded-pthread \
|
||||
+ tst-sonamemove-dlopen \
|
||||
+ tst-sonamemove-link \
|
||||
+ tst-thrlock \
|
||||
+ tst-tls10 \
|
||||
+ tst-tls11 \
|
||||
+ tst-tls12 \
|
||||
+ tst-tls13 \
|
||||
+ tst-tls14 \
|
||||
+ tst-tls15 \
|
||||
+ tst-tls16 \
|
||||
+ tst-tls17 \
|
||||
+ tst-tls18 \
|
||||
+ tst-tls19 \
|
||||
+ tst-tls20 \
|
||||
+ tst-tls21 \
|
||||
+ tst-tls4 \
|
||||
+ tst-tls5 \
|
||||
+ tst-tlsalign \
|
||||
+ tst-tlsalign-extern \
|
||||
+ tst-tls-dlinfo \
|
||||
+ tst-tls-ie \
|
||||
+ tst-tls-ie-dlmopen \
|
||||
+ tst-tls-manydynamic \
|
||||
+ tst-unique1 \
|
||||
+ tst-unique2 \
|
||||
+ tst-unwind-ctor \
|
||||
+ tst-unwind-main \
|
||||
+ unload3 \
|
||||
+ unload4 \
|
||||
+ unload5 \
|
||||
+ unload6 \
|
||||
+ unload7 \
|
||||
+ unload8 \
|
||||
# reldep9
|
||||
+tests-cxx = \
|
||||
+ tst-dlopen-nodelete-reloc \
|
||||
+ tst-nodelete \
|
||||
+ tst-unique3 \
|
||||
+ tst-unique4 \
|
||||
+
|
||||
+tests += $(if $(CXX),$(tests-cxx))
|
||||
tests-internal += loadtest unload unload2 circleload1 \
|
||||
neededtest neededtest2 neededtest3 neededtest4 \
|
||||
tst-tls3 tst-tls6 tst-tls7 tst-tls8 tst-dlmopen2 \
|
||||
@@ -264,101 +358,265 @@ tst-tls-many-dynamic-modules-dep-bad = \
|
||||
extra-test-objs += $(tlsmod17a-modules:=.os) $(tlsmod18a-modules:=.os) \
|
||||
tst-tlsalign-vars.o
|
||||
test-extras += tst-tlsmod17a tst-tlsmod18a tst-tlsalign-vars
|
||||
-modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
|
||||
- testobj1_1 failobj constload2 constload3 unloadmod \
|
||||
- dep1 dep2 dep3 dep4 vismod1 vismod2 vismod3 \
|
||||
- nodelmod1 nodelmod2 nodelmod3 nodelmod4 \
|
||||
- nodel2mod1 nodel2mod2 nodel2mod3 \
|
||||
- nodlopenmod nodlopenmod2 filtmod1 filtmod2 \
|
||||
- reldepmod1 reldepmod2 reldepmod3 reldepmod4 nextmod1 nextmod2 \
|
||||
- reldep4mod1 reldep4mod2 reldep4mod3 reldep4mod4 \
|
||||
- neededobj1 neededobj2 neededobj3 neededobj4 \
|
||||
- neededobj5 neededobj6 firstobj globalmod1 \
|
||||
- unload2mod unload2dep ltglobmod1 ltglobmod2 pathoptobj \
|
||||
- dblloadmod1 dblloadmod2 dblloadmod3 reldepmod5 reldepmod6 \
|
||||
- reldep6mod0 reldep6mod1 reldep6mod2 reldep6mod3 reldep6mod4 \
|
||||
- reldep7mod1 reldep7mod2 \
|
||||
- tst-tlsmod1 tst-tlsmod2 tst-tlsmod3 tst-tlsmod4 \
|
||||
- tst-tlsmod5 tst-tlsmod6 tst-tlsmod7 tst-tlsmod8 \
|
||||
- tst-tlsmod9 tst-tlsmod10 tst-tlsmod11 tst-tlsmod12 \
|
||||
- tst-tlsmod13 tst-tlsmod13a tst-tlsmod14a tst-tlsmod14b \
|
||||
- tst-tlsmod15a tst-tlsmod15b tst-tlsmod16a tst-tlsmod16b \
|
||||
- $(tlsmod17a-modules) tst-tlsmod17b $(tlsmod18a-modules) \
|
||||
- tst-tls19mod1 tst-tls19mod2 tst-tls19mod3 \
|
||||
- circlemod1 circlemod1a circlemod2 circlemod2a \
|
||||
- circlemod3 circlemod3a \
|
||||
- reldep8mod1 reldep8mod2 reldep8mod3 \
|
||||
- reldep9mod1 reldep9mod2 reldep9mod3 \
|
||||
- tst-alignmod tst-alignmod2 \
|
||||
- $(modules-execstack-$(have-z-execstack)) \
|
||||
- tst-dlopenrpathmod tst-deep1mod1 tst-deep1mod2 tst-deep1mod3 \
|
||||
- tst-dlmopen1mod tst-auditmod1 \
|
||||
- unload3mod1 unload3mod2 unload3mod3 unload3mod4 \
|
||||
- unload4mod1 unload4mod2 unload4mod3 unload4mod4 \
|
||||
- unload6mod1 unload6mod2 unload6mod3 \
|
||||
- unload7mod1 unload7mod2 \
|
||||
- unload8mod1 unload8mod1x unload8mod2 unload8mod3 \
|
||||
- order2mod1 order2mod2 order2mod3 order2mod4 \
|
||||
- tst-unique1mod1 tst-unique1mod2 \
|
||||
- tst-unique2mod1 tst-unique2mod2 \
|
||||
- tst-auditmod9a tst-auditmod9b \
|
||||
- $(if $(CXX),tst-unique3lib tst-unique3lib2 tst-unique4lib \
|
||||
- tst-nodelete-uniquemod tst-nodelete-rtldmod \
|
||||
- tst-nodelete-zmod \
|
||||
- tst-dlopen-nodelete-reloc-mod1 \
|
||||
- tst-dlopen-nodelete-reloc-mod2 \
|
||||
- tst-dlopen-nodelete-reloc-mod3 \
|
||||
- tst-dlopen-nodelete-reloc-mod4 \
|
||||
- tst-dlopen-nodelete-reloc-mod5 \
|
||||
- tst-dlopen-nodelete-reloc-mod6 \
|
||||
- tst-dlopen-nodelete-reloc-mod7 \
|
||||
- tst-dlopen-nodelete-reloc-mod8 \
|
||||
- tst-dlopen-nodelete-reloc-mod9 \
|
||||
- tst-dlopen-nodelete-reloc-mod10 \
|
||||
- tst-dlopen-nodelete-reloc-mod11 \
|
||||
- tst-dlopen-nodelete-reloc-mod12 \
|
||||
- tst-dlopen-nodelete-reloc-mod13 \
|
||||
- tst-dlopen-nodelete-reloc-mod14 \
|
||||
- tst-dlopen-nodelete-reloc-mod15 \
|
||||
- tst-dlopen-nodelete-reloc-mod16 \
|
||||
- tst-dlopen-nodelete-reloc-mod17) \
|
||||
- tst-initordera1 tst-initorderb1 \
|
||||
- tst-initordera2 tst-initorderb2 \
|
||||
- tst-initordera3 tst-initordera4 \
|
||||
- tst-initorder2a tst-initorder2b tst-initorder2c \
|
||||
- tst-initorder2d \
|
||||
- tst-relsort1mod1 tst-relsort1mod2 tst-array2dep \
|
||||
- tst-array5dep tst-null-argv-lib \
|
||||
- tst-tlsalign-lib tst-nodelete-opened-lib tst-nodelete2mod \
|
||||
- tst-audit11mod1 tst-audit11mod2 tst-auditmod11 \
|
||||
- tst-audit12mod1 tst-audit12mod2 tst-audit12mod3 tst-auditmod12 \
|
||||
- tst-latepthreadmod $(tst-tls-many-dynamic-modules) \
|
||||
- $(tst-tls-many-dynamic-modules-dep) \
|
||||
- $(tst-tls-many-dynamic-modules-dep-bad) \
|
||||
- tst-nodelete-dlclose-dso tst-nodelete-dlclose-plugin \
|
||||
- tst-main1mod tst-absolute-sym-lib \
|
||||
- tst-absolute-zero-lib tst-big-note-lib tst-unwind-ctor-lib \
|
||||
- tst-audit13mod1 tst-sonamemove-linkmod1 \
|
||||
- tst-sonamemove-runmod1 tst-sonamemove-runmod2 \
|
||||
- tst-auditmanymod1 tst-auditmanymod2 tst-auditmanymod3 \
|
||||
- tst-auditmanymod4 tst-auditmanymod5 tst-auditmanymod6 \
|
||||
- tst-auditmanymod7 tst-auditmanymod8 tst-auditmanymod9 \
|
||||
- tst-initlazyfailmod tst-finilazyfailmod \
|
||||
- tst-dlopenfailmod1 tst-dlopenfaillinkmod tst-dlopenfailmod2 \
|
||||
- tst-dlopenfailmod3 tst-dlopenfailnodelmod tst-ldconfig-ld-mod \
|
||||
- tst-filterobj-flt tst-filterobj-aux tst-filterobj-filtee \
|
||||
- tst-auditlogmod-1 tst-auditlogmod-2 tst-auditlogmod-3 \
|
||||
- tst-single_threaded-mod1 tst-single_threaded-mod2 \
|
||||
- tst-single_threaded-mod3 tst-single_threaded-mod4 \
|
||||
- tst-tls-ie-mod0 tst-tls-ie-mod1 tst-tls-ie-mod2 \
|
||||
- tst-tls-ie-mod3 tst-tls-ie-mod4 tst-tls-ie-mod5 \
|
||||
- tst-tls-ie-mod6 libmarkermod1-1 libmarkermod1-2 libmarkermod1-3 \
|
||||
- libmarkermod2-1 libmarkermod2-2 \
|
||||
- libmarkermod3-1 libmarkermod3-2 libmarkermod3-3 \
|
||||
- libmarkermod4-1 libmarkermod4-2 libmarkermod4-3 libmarkermod4-4 \
|
||||
- tst-tls20mod-bad tst-tls21mod tst-dlmopen-dlerror-mod \
|
||||
- tst-auxvalmod \
|
||||
- tst-dlmopen-gethostbyname-mod tst-ro-dynamic-mod \
|
||||
+modules-names = \
|
||||
+ circlemod1 \
|
||||
+ circlemod1a \
|
||||
+ circlemod2 \
|
||||
+ circlemod2a \
|
||||
+ circlemod3 \
|
||||
+ circlemod3a \
|
||||
+ constload2 \
|
||||
+ constload3 \
|
||||
+ dblloadmod1 \
|
||||
+ dblloadmod2 \
|
||||
+ dblloadmod3 \
|
||||
+ dep1 \
|
||||
+ dep2 \
|
||||
+ dep3 \
|
||||
+ dep4 \
|
||||
+ failobj \
|
||||
+ filtmod1 \
|
||||
+ filtmod2 \
|
||||
+ firstobj \
|
||||
+ globalmod1 \
|
||||
+ libmarkermod1-1 \
|
||||
+ libmarkermod1-2 \
|
||||
+ libmarkermod1-3 \
|
||||
+ libmarkermod2-1 \
|
||||
+ libmarkermod2-2 \
|
||||
+ libmarkermod3-1 \
|
||||
+ libmarkermod3-2 \
|
||||
+ libmarkermod3-3 \
|
||||
+ libmarkermod4-1 \
|
||||
+ libmarkermod4-2 \
|
||||
+ libmarkermod4-3 \
|
||||
+ libmarkermod4-4 \
|
||||
+ ltglobmod1 \
|
||||
+ ltglobmod2 \
|
||||
+ neededobj1 \
|
||||
+ neededobj2 \
|
||||
+ neededobj3 \
|
||||
+ neededobj4 \
|
||||
+ neededobj5 \
|
||||
+ neededobj6 \
|
||||
+ nextmod1 \
|
||||
+ nextmod2 \
|
||||
+ nodel2mod1 \
|
||||
+ nodel2mod2 \
|
||||
+ nodel2mod3 \
|
||||
+ nodelmod1 \
|
||||
+ nodelmod2 \
|
||||
+ nodelmod3 \
|
||||
+ nodelmod4 \
|
||||
+ nodlopenmod \
|
||||
+ nodlopenmod2 \
|
||||
+ order2mod1 \
|
||||
+ order2mod2 \
|
||||
+ order2mod3 \
|
||||
+ order2mod4 \
|
||||
+ pathoptobj \
|
||||
+ reldep4mod1 \
|
||||
+ reldep4mod2 \
|
||||
+ reldep4mod3 \
|
||||
+ reldep4mod4 \
|
||||
+ reldep6mod0 \
|
||||
+ reldep6mod1 \
|
||||
+ reldep6mod2 \
|
||||
+ reldep6mod3 \
|
||||
+ reldep6mod4 \
|
||||
+ reldep7mod1 \
|
||||
+ reldep7mod2 \
|
||||
+ reldep8mod1 \
|
||||
+ reldep8mod2 \
|
||||
+ reldep8mod3 \
|
||||
+ reldep9mod1 \
|
||||
+ reldep9mod2 \
|
||||
+ reldep9mod3 \
|
||||
+ reldepmod1 \
|
||||
+ reldepmod2 \
|
||||
+ reldepmod3 \
|
||||
+ reldepmod4 \
|
||||
+ reldepmod5 \
|
||||
+ reldepmod6 \
|
||||
+ testobj1 \
|
||||
+ testobj1_1 \
|
||||
+ testobj2 \
|
||||
+ testobj3 \
|
||||
+ testobj4 \
|
||||
+ testobj5 \
|
||||
+ testobj6 \
|
||||
+ tst-absolute-sym-lib \
|
||||
+ tst-absolute-zero-lib \
|
||||
+ tst-alignmod \
|
||||
+ tst-alignmod2 \
|
||||
+ tst-array2dep \
|
||||
+ tst-array5dep \
|
||||
+ tst-audit11mod1 \
|
||||
+ tst-audit11mod2 \
|
||||
+ tst-audit12mod1 \
|
||||
+ tst-audit12mod2 \
|
||||
+ tst-audit12mod3 \
|
||||
+ tst-audit13mod1 \
|
||||
+ tst-auditlogmod-1 \
|
||||
+ tst-auditlogmod-2 \
|
||||
+ tst-auditlogmod-3 \
|
||||
+ tst-auditmanymod1 \
|
||||
+ tst-auditmanymod2 \
|
||||
+ tst-auditmanymod3 \
|
||||
+ tst-auditmanymod4 \
|
||||
+ tst-auditmanymod5 \
|
||||
+ tst-auditmanymod6 \
|
||||
+ tst-auditmanymod7 \
|
||||
+ tst-auditmanymod8 \
|
||||
+ tst-auditmanymod9 \
|
||||
+ tst-auditmod1 \
|
||||
+ tst-auditmod9a \
|
||||
+ tst-auditmod9b \
|
||||
+ tst-auditmod11 \
|
||||
+ tst-auditmod12 \
|
||||
+ tst-auxvalmod \
|
||||
+ tst-big-note-lib \
|
||||
+ tst-deep1mod1 \
|
||||
+ tst-deep1mod2 \
|
||||
+ tst-deep1mod3 \
|
||||
+ tst-dlmopen1mod \
|
||||
+ tst-dlmopen-dlerror-mod \
|
||||
+ tst-dlmopen-gethostbyname-mod \
|
||||
+ tst-dlopenfaillinkmod \
|
||||
+ tst-dlopenfailmod1 \
|
||||
+ tst-dlopenfailmod2 \
|
||||
+ tst-dlopenfailmod3 \
|
||||
+ tst-dlopenfailnodelmod \
|
||||
+ tst-dlopenrpathmod \
|
||||
+ tst-filterobj-aux \
|
||||
+ tst-filterobj-filtee \
|
||||
+ tst-filterobj-flt \
|
||||
+ tst-finilazyfailmod \
|
||||
+ tst-initlazyfailmod \
|
||||
+ tst-initorder2a \
|
||||
+ tst-initorder2b \
|
||||
+ tst-initorder2c \
|
||||
+ tst-initorder2d \
|
||||
+ tst-initordera1 \
|
||||
+ tst-initordera2 \
|
||||
+ tst-initordera3 \
|
||||
+ tst-initordera4 \
|
||||
+ tst-initorderb1 \
|
||||
+ tst-initorderb2 \
|
||||
+ tst-latepthreadmod \
|
||||
+ tst-ldconfig-ld-mod \
|
||||
+ tst-main1mod \
|
||||
+ tst-nodelete2mod \
|
||||
+ tst-nodelete-dlclose-dso \
|
||||
+ tst-nodelete-dlclose-plugin \
|
||||
+ tst-nodelete-opened-lib \
|
||||
+ tst-null-argv-lib \
|
||||
+ tst-relsort1mod1 \
|
||||
+ tst-relsort1mod2 \
|
||||
+ tst-ro-dynamic-mod \
|
||||
+ tst-single_threaded-mod1 \
|
||||
+ tst-single_threaded-mod2 \
|
||||
+ tst-single_threaded-mod3 \
|
||||
+ tst-single_threaded-mod4 \
|
||||
+ tst-sonamemove-linkmod1 \
|
||||
+ tst-sonamemove-runmod1 \
|
||||
+ tst-sonamemove-runmod2 \
|
||||
+ tst-tls19mod1 \
|
||||
+ tst-tls19mod2 \
|
||||
+ tst-tls19mod3 \
|
||||
+ tst-tls20mod-bad \
|
||||
+ tst-tls21mod \
|
||||
+ tst-tlsalign-lib \
|
||||
+ tst-tls-ie-mod0 \
|
||||
+ tst-tls-ie-mod1 \
|
||||
+ tst-tls-ie-mod2 \
|
||||
+ tst-tls-ie-mod3 \
|
||||
+ tst-tls-ie-mod4 \
|
||||
+ tst-tls-ie-mod5 \
|
||||
+ tst-tls-ie-mod6 \
|
||||
+ tst-tlsmod1 \
|
||||
+ tst-tlsmod10 \
|
||||
+ tst-tlsmod11 \
|
||||
+ tst-tlsmod12 \
|
||||
+ tst-tlsmod13 \
|
||||
+ tst-tlsmod13a \
|
||||
+ tst-tlsmod14a \
|
||||
+ tst-tlsmod14b \
|
||||
+ tst-tlsmod15a \
|
||||
+ tst-tlsmod15b \
|
||||
+ tst-tlsmod16a \
|
||||
+ tst-tlsmod16b \
|
||||
+ tst-tlsmod17b \
|
||||
+ tst-tlsmod2 \
|
||||
+ tst-tlsmod3 \
|
||||
+ tst-tlsmod4 \
|
||||
+ tst-tlsmod5 \
|
||||
+ tst-tlsmod6 \
|
||||
+ tst-tlsmod7 \
|
||||
+ tst-tlsmod8 \
|
||||
+ tst-tlsmod9 \
|
||||
+ tst-unique1mod1 \
|
||||
+ tst-unique1mod2 \
|
||||
+ tst-unique2mod1 \
|
||||
+ tst-unique2mod2 \
|
||||
+ tst-unwind-ctor-lib \
|
||||
+ unload2dep \
|
||||
+ unload2mod \
|
||||
+ unload3mod1 \
|
||||
+ unload3mod2 \
|
||||
+ unload3mod3 \
|
||||
+ unload3mod4 \
|
||||
+ unload4mod1 \
|
||||
+ unload4mod2 \
|
||||
+ unload4mod3 \
|
||||
+ unload4mod4 \
|
||||
+ unload6mod1 \
|
||||
+ unload6mod2 \
|
||||
+ unload6mod3 \
|
||||
+ unload7mod1 \
|
||||
+ unload7mod2 \
|
||||
+ unload8mod1 \
|
||||
+ unload8mod1x \
|
||||
+ unload8mod2 \
|
||||
+ unload8mod3 \
|
||||
+ unloadmod \
|
||||
+ vismod1 \
|
||||
+ vismod2 \
|
||||
+ vismod3 \
|
||||
+
|
||||
+modules-names-cxx = \
|
||||
+ tst-dlopen-nodelete-reloc-mod1 \
|
||||
+ tst-dlopen-nodelete-reloc-mod10 \
|
||||
+ tst-dlopen-nodelete-reloc-mod11 \
|
||||
+ tst-dlopen-nodelete-reloc-mod12 \
|
||||
+ tst-dlopen-nodelete-reloc-mod13 \
|
||||
+ tst-dlopen-nodelete-reloc-mod14 \
|
||||
+ tst-dlopen-nodelete-reloc-mod15 \
|
||||
+ tst-dlopen-nodelete-reloc-mod16 \
|
||||
+ tst-dlopen-nodelete-reloc-mod17 \
|
||||
+ tst-dlopen-nodelete-reloc-mod2 \
|
||||
+ tst-dlopen-nodelete-reloc-mod3 \
|
||||
+ tst-dlopen-nodelete-reloc-mod4 \
|
||||
+ tst-dlopen-nodelete-reloc-mod5 \
|
||||
+ tst-dlopen-nodelete-reloc-mod6 \
|
||||
+ tst-dlopen-nodelete-reloc-mod7 \
|
||||
+ tst-dlopen-nodelete-reloc-mod8 \
|
||||
+ tst-dlopen-nodelete-reloc-mod9 \
|
||||
+ tst-nodelete-rtldmod \
|
||||
+ tst-nodelete-uniquemod \
|
||||
+ tst-nodelete-zmod \
|
||||
+ tst-unique3lib \
|
||||
+ tst-unique3lib2 \
|
||||
+ tst-unique4lib \
|
||||
+
|
||||
+modules-names += \
|
||||
+ $(if $(CXX),$(modules-names-cxx)) \
|
||||
+ $(modules-execstack-$(have-z-execstack)) \
|
||||
+ $(tst-tls-many-dynamic-modules) \
|
||||
+ $(tst-tls-many-dynamic-modules-dep) \
|
||||
+ $(tst-tls-many-dynamic-modules-dep-bad) \
|
||||
+ $(tlsmod17a-modules) \
|
||||
+ $(tlsmod18a-modules) \
|
||||
|
||||
# Most modules build with _ISOMAC defined, but those filtered out
|
||||
# depend on internal headers.
|
@ -0,0 +1,73 @@
|
||||
commit 990c953bce06d77360d2e933faa9a008e2c55405
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Jan 14 20:16:05 2022 +0100
|
||||
|
||||
x86: Add x86-64-vN check to early startup
|
||||
|
||||
This ISA level covers the glibc build itself. <dl-hwcap-check.h>
|
||||
cannot be used because this check (by design) happens before
|
||||
DL_PLATFORM_INIT and the x86 CPU flags initialization.
|
||||
|
||||
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
||||
|
||||
diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile
|
||||
index 5ee06f94735e5189..36ca1a7126047b86 100644
|
||||
--- a/sysdeps/x86/Makefile
|
||||
+++ b/sysdeps/x86/Makefile
|
||||
@@ -7,6 +7,7 @@ sysdep_routines += get-cpuid-feature-leaf
|
||||
sysdep-dl-routines += dl-get-cpu-features
|
||||
sysdep_headers += sys/platform/x86.h bits/platform/x86.h
|
||||
|
||||
+CFLAGS-dl-get-cpu-features.os += $(rtld-early-cflags)
|
||||
CFLAGS-get-cpuid-feature-leaf.o += $(no-stack-protector)
|
||||
|
||||
tests += tst-get-cpu-features tst-get-cpu-features-static \
|
||||
diff --git a/sysdeps/x86/dl-get-cpu-features.c b/sysdeps/x86/dl-get-cpu-features.c
|
||||
index 839803c746f408ed..6ccde4404b13a725 100644
|
||||
--- a/sysdeps/x86/dl-get-cpu-features.c
|
||||
+++ b/sysdeps/x86/dl-get-cpu-features.c
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#ifdef SHARED
|
||||
# include <cpu-features.c>
|
||||
+# include <gcc-macros.h>
|
||||
|
||||
/* NB: Normally, DL_PLATFORM_INIT calls init_cpu_features to initialize
|
||||
CPU features in dynamic executable. But when loading ld.so inside of
|
||||
@@ -36,7 +37,35 @@ _dl_x86_init_cpu_features (void)
|
||||
{
|
||||
struct cpu_features *cpu_features = __get_cpu_features ();
|
||||
if (cpu_features->basic.kind == arch_kind_unknown)
|
||||
- init_cpu_features (cpu_features);
|
||||
+ {
|
||||
+ init_cpu_features (cpu_features);
|
||||
+
|
||||
+# if IS_IN (rtld)
|
||||
+ /* See isa-level.c. */
|
||||
+# if defined GCCMACRO__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 \
|
||||
+ && defined HAVE_X86_LAHF_SAHF && defined GCCMACRO__POPCNT__ \
|
||||
+ && defined GCCMACRO__SSE3__ && defined GCCMACRO__SSSE3__ \
|
||||
+ && defined GCCMACRO__SSE4_1__ && defined GCCMACRO__SSE4_2__
|
||||
+ if (!(cpu_features->isa_1 & GNU_PROPERTY_X86_ISA_1_V2))
|
||||
+ _dl_fatal_printf ("\
|
||||
+Fatal glibc error: CPU does not support x86-64-v%d\n", 2);
|
||||
+# if defined GCCMACRO__AVX__ && defined GCCMACRO__AVX2__ \
|
||||
+ && defined GCCMACRO__F16C__ && defined GCCMACRO__FMA__ \
|
||||
+ && defined GCCMACRO__LZCNT__ && defined HAVE_X86_MOVBE
|
||||
+ if (!(cpu_features->isa_1 & GNU_PROPERTY_X86_ISA_1_V3))
|
||||
+ _dl_fatal_printf ("\
|
||||
+Fatal glibc error: CPU does not support x86-64-v%d\n", 3);
|
||||
+# if defined GCCMACRO__AVX512F__ && defined GCCMACRO__AVX512BW__ \
|
||||
+ && defined GCCMACRO__AVX512CD__ && defined GCCMACRO__AVX512DQ__ \
|
||||
+ && defined GCCMACRO__AVX512VL__
|
||||
+ if (!(cpu_features->isa_1 & GNU_PROPERTY_X86_ISA_1_V4))
|
||||
+ _dl_fatal_printf ("\
|
||||
+Fatal glibc error: CPU does not support x86-64-v%d\n", 4);
|
||||
+# endif /* ISA level 4 */
|
||||
+# endif /* ISA level 3 */
|
||||
+# endif /* ISA level 2 */
|
||||
+# endif /* IS_IN (rtld) */
|
||||
+ }
|
||||
}
|
||||
|
||||
__ifunc (__x86_cpu_features, __x86_cpu_features, NULL, void,
|
@ -0,0 +1,37 @@
|
||||
commit f01d482f0355a7029d0715ace0ccf3323e7e94bc
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Jan 14 20:16:05 2022 +0100
|
||||
|
||||
s390x: Use <gcc-macros.h> in early HWCAP check
|
||||
|
||||
This is required so that the checks still work if $(early-cflags)
|
||||
selects a different ISA level.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
Tested-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/sysdeps/s390/s390-64/dl-hwcap-check.h b/sysdeps/s390/s390-64/dl-hwcap-check.h
|
||||
index 87e18be6bd0c512b..27f7e245b1d1a9e9 100644
|
||||
--- a/sysdeps/s390/s390-64/dl-hwcap-check.h
|
||||
+++ b/sysdeps/s390/s390-64/dl-hwcap-check.h
|
||||
@@ -19,17 +19,18 @@
|
||||
#ifndef _DL_HWCAP_CHECK_H
|
||||
#define _DL_HWCAP_CHECK_H
|
||||
|
||||
+#include <gcc-macros.h>
|
||||
#include <ldsodefs.h>
|
||||
|
||||
static inline void
|
||||
dl_hwcap_check (void)
|
||||
{
|
||||
#if defined __ARCH__
|
||||
-# if __ARCH__ >= 13
|
||||
+# if GCCMACRO__ARCH__ >= 13
|
||||
if (!(GLRO(dl_hwcap) & HWCAP_S390_VXRS_EXT2))
|
||||
_dl_fatal_printf ("\
|
||||
Fatal glibc error: CPU lacks VXRS_EXT2 support (z15 or later required)\n");
|
||||
-# elif __ARCH__ >= 12
|
||||
+# elif GCCMACRO__ARCH__ >= 12
|
||||
if (!(GLRO(dl_hwcap) & HWCAP_S390_VXE))
|
||||
_dl_fatal_printf ("\
|
||||
Fatal glibc error: CPU lacks VXE support (z14 or later required)\n");
|
@ -0,0 +1,158 @@
|
||||
commit c90363403b57b3b7919061851cb3e6d9c85e784a
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Jan 18 13:53:11 2022 +0100
|
||||
|
||||
elf: Move _dl_setup_hash to its own file
|
||||
|
||||
And compile it with the early CFLAGS. _dl_setup_hash is called
|
||||
very early for the ld.so link map, so it should be compiled
|
||||
differently.
|
||||
|
||||
Reviewed-by: Stefan Liebler <stli@linux.ibm.com>
|
||||
Tested-by: Stefan Liebler <stli@linux.ibm.com>
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 778e393395fc5248..948296dc2437e9a1 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -69,6 +69,7 @@ dl-routines = \
|
||||
dl-reloc \
|
||||
dl-runtime \
|
||||
dl-scope \
|
||||
+ dl-setup_hash \
|
||||
dl-sort-maps \
|
||||
dl-thread_gscope_wait \
|
||||
dl-tls \
|
||||
@@ -154,6 +155,7 @@ CFLAGS-.os += $(call elide-stack-protector,.os,$(all-rtld-routines))
|
||||
|
||||
# Add the requested compiler flags to the early startup code.
|
||||
CFLAGS-dl-printf.os += $(rtld-early-cflags)
|
||||
+CFLAGS-dl-setup_hash.os += $(rtld-early-cflags)
|
||||
CFLAGS-dl-sysdep.os += $(rtld-early-cflags)
|
||||
CFLAGS-dl-tunables.os += $(rtld-early-cflags)
|
||||
CFLAGS-dl-write.os += $(rtld-early-cflags)
|
||||
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
|
||||
index eea217eb2833164c..3391a990c8d288e5 100644
|
||||
--- a/elf/dl-lookup.c
|
||||
+++ b/elf/dl-lookup.c
|
||||
@@ -948,51 +948,6 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
|
||||
}
|
||||
|
||||
|
||||
-/* Cache the location of MAP's hash table. */
|
||||
-
|
||||
-void
|
||||
-_dl_setup_hash (struct link_map *map)
|
||||
-{
|
||||
- Elf_Symndx *hash;
|
||||
-
|
||||
- if (__glibc_likely (map->l_info[ELF_MACHINE_GNU_HASH_ADDRIDX] != NULL))
|
||||
- {
|
||||
- Elf32_Word *hash32
|
||||
- = (void *) D_PTR (map, l_info[ELF_MACHINE_GNU_HASH_ADDRIDX]);
|
||||
- map->l_nbuckets = *hash32++;
|
||||
- Elf32_Word symbias = *hash32++;
|
||||
- Elf32_Word bitmask_nwords = *hash32++;
|
||||
- /* Must be a power of two. */
|
||||
- assert ((bitmask_nwords & (bitmask_nwords - 1)) == 0);
|
||||
- map->l_gnu_bitmask_idxbits = bitmask_nwords - 1;
|
||||
- map->l_gnu_shift = *hash32++;
|
||||
-
|
||||
- map->l_gnu_bitmask = (ElfW(Addr) *) hash32;
|
||||
- hash32 += __ELF_NATIVE_CLASS / 32 * bitmask_nwords;
|
||||
-
|
||||
- map->l_gnu_buckets = hash32;
|
||||
- hash32 += map->l_nbuckets;
|
||||
- map->l_gnu_chain_zero = hash32 - symbias;
|
||||
-
|
||||
- /* Initialize MIPS xhash translation table. */
|
||||
- ELF_MACHINE_XHASH_SETUP (hash32, symbias, map);
|
||||
-
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- if (!map->l_info[DT_HASH])
|
||||
- return;
|
||||
- hash = (void *) D_PTR (map, l_info[DT_HASH]);
|
||||
-
|
||||
- map->l_nbuckets = *hash++;
|
||||
- /* Skip nchain. */
|
||||
- hash++;
|
||||
- map->l_buckets = hash;
|
||||
- hash += map->l_nbuckets;
|
||||
- map->l_chain = hash;
|
||||
-}
|
||||
-
|
||||
-
|
||||
static void
|
||||
_dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
|
||||
const ElfW(Sym) **ref, struct sym_val *value,
|
||||
diff --git a/elf/dl-setup_hash.c b/elf/dl-setup_hash.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..6dd57c5c94e541c2
|
||||
--- /dev/null
|
||||
+++ b/elf/dl-setup_hash.c
|
||||
@@ -0,0 +1,63 @@
|
||||
+/* Cache the location of a link map hash table.
|
||||
+ Copyright (C) 1995-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/>. */
|
||||
+
|
||||
+#include <assert.h>
|
||||
+#include <link.h>
|
||||
+#include <ldsodefs.h>
|
||||
+
|
||||
+void
|
||||
+_dl_setup_hash (struct link_map *map)
|
||||
+{
|
||||
+ Elf_Symndx *hash;
|
||||
+
|
||||
+ if (__glibc_likely (map->l_info[ELF_MACHINE_GNU_HASH_ADDRIDX] != NULL))
|
||||
+ {
|
||||
+ Elf32_Word *hash32
|
||||
+ = (void *) D_PTR (map, l_info[ELF_MACHINE_GNU_HASH_ADDRIDX]);
|
||||
+ map->l_nbuckets = *hash32++;
|
||||
+ Elf32_Word symbias = *hash32++;
|
||||
+ Elf32_Word bitmask_nwords = *hash32++;
|
||||
+ /* Must be a power of two. */
|
||||
+ assert ((bitmask_nwords & (bitmask_nwords - 1)) == 0);
|
||||
+ map->l_gnu_bitmask_idxbits = bitmask_nwords - 1;
|
||||
+ map->l_gnu_shift = *hash32++;
|
||||
+
|
||||
+ map->l_gnu_bitmask = (ElfW(Addr) *) hash32;
|
||||
+ hash32 += __ELF_NATIVE_CLASS / 32 * bitmask_nwords;
|
||||
+
|
||||
+ map->l_gnu_buckets = hash32;
|
||||
+ hash32 += map->l_nbuckets;
|
||||
+ map->l_gnu_chain_zero = hash32 - symbias;
|
||||
+
|
||||
+ /* Initialize MIPS xhash translation table. */
|
||||
+ ELF_MACHINE_XHASH_SETUP (hash32, symbias, map);
|
||||
+
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (!map->l_info[DT_HASH])
|
||||
+ return;
|
||||
+ hash = (void *) D_PTR (map, l_info[DT_HASH]);
|
||||
+
|
||||
+ map->l_nbuckets = *hash++;
|
||||
+ /* Skip nchain. */
|
||||
+ hash++;
|
||||
+ map->l_buckets = hash;
|
||||
+ hash += map->l_nbuckets;
|
||||
+ map->l_chain = hash;
|
||||
+}
|
@ -0,0 +1,42 @@
|
||||
commit f4f70c2895e3d325188a42c10eb7bb4335be6773
|
||||
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||
Date: Tue Jan 4 06:58:34 2022 -0800
|
||||
|
||||
elf: Add a comment after trailing backslashes
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 0cfcf0a61a442c9f..5b9c36bc6f0a3ee5 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -319,6 +319,7 @@ tests-cxx = \
|
||||
tst-nodelete \
|
||||
tst-unique3 \
|
||||
tst-unique4 \
|
||||
+# tests-cxx
|
||||
|
||||
tests += $(if $(CXX),$(tests-cxx))
|
||||
tests-internal += loadtest unload unload2 circleload1 \
|
||||
@@ -583,6 +584,7 @@ modules-names = \
|
||||
vismod1 \
|
||||
vismod2 \
|
||||
vismod3 \
|
||||
+# modules-names
|
||||
|
||||
modules-names-cxx = \
|
||||
tst-dlopen-nodelete-reloc-mod1 \
|
||||
@@ -608,6 +610,7 @@ modules-names-cxx = \
|
||||
tst-unique3lib \
|
||||
tst-unique3lib2 \
|
||||
tst-unique4lib \
|
||||
+# modules-names-cxx
|
||||
|
||||
modules-names += \
|
||||
$(if $(CXX),$(modules-names-cxx)) \
|
||||
@@ -617,6 +620,7 @@ modules-names += \
|
||||
$(tst-tls-many-dynamic-modules-dep-bad) \
|
||||
$(tlsmod17a-modules) \
|
||||
$(tlsmod18a-modules) \
|
||||
+# modules-names
|
||||
|
||||
# Most modules build with _ISOMAC defined, but those filtered out
|
||||
# depend on internal headers.
|
@ -0,0 +1,171 @@
|
||||
commit 0835c0f0bad351117154b815f34f8af19ea7e325
|
||||
Author: Matt Whitlock <sourceware@mattwhitlock.name>
|
||||
Date: Wed Jun 16 23:40:47 2021 -0400
|
||||
|
||||
x86: fix Autoconf caching of instruction support checks [BZ #27991]
|
||||
|
||||
The Autoconf documentation for the AC_CACHE_CHECK macro states:
|
||||
|
||||
The commands-to-set-it must have no side effects except for setting
|
||||
the variable cache-id, see below.
|
||||
|
||||
However, the tests for support of -msahf and -mmovbe were embedded in
|
||||
the commands-to-set-it for lib_cv_include_x86_isa_level. This had the
|
||||
consequence that libc_cv_have_x86_lahf_sahf and libc_cv_have_x86_movbe
|
||||
were not defined whenever lib_cv_include_x86_isa_level was read from
|
||||
cache. These variables' being undefined meant that their unquoted use
|
||||
in later test expressions led to the 'test' built-in's misparsing its
|
||||
arguments and emitting errors like "test: =: unexpected operator" or
|
||||
"test: =: unary operator expected", depending on the particular shell.
|
||||
|
||||
This commit refactors the tests for LAHF/SAHF and MOVBE instruction
|
||||
support into their own AC_CACHE_CHECK macro invocations to obey the
|
||||
rule that the commands-to-set-it must have no side effects other than
|
||||
setting the variable named by cache-id.
|
||||
|
||||
Signed-off-by: Matt Whitlock <sourceware@mattwhitlock.name>
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/sysdeps/x86/configure b/sysdeps/x86/configure
|
||||
index ead1295c38cf5f4e..62676bb686850938 100644
|
||||
--- a/sysdeps/x86/configure
|
||||
+++ b/sysdeps/x86/configure
|
||||
@@ -126,8 +126,6 @@ cat > conftest2.S <<EOF
|
||||
4:
|
||||
EOF
|
||||
libc_cv_include_x86_isa_level=no
|
||||
-libc_cv_have_x86_lahf_sahf=no
|
||||
-libc_cv_have_x86_movbe=no
|
||||
if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -nostartfiles -nostdlib -r -o conftest conftest1.S conftest2.S'
|
||||
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
|
||||
(eval $ac_try) 2>&5
|
||||
@@ -137,9 +135,22 @@ if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -nostartfiles -nostdlib -r -o conftest c
|
||||
count=`LC_ALL=C $READELF -n conftest | grep NT_GNU_PROPERTY_TYPE_0 | wc -l`
|
||||
if test "$count" = 1; then
|
||||
libc_cv_include_x86_isa_level=yes
|
||||
- cat > conftest.c <<EOF
|
||||
-EOF
|
||||
- if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - conftest.c'
|
||||
+ fi
|
||||
+fi
|
||||
+rm -f conftest*
|
||||
+fi
|
||||
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_include_x86_isa_level" >&5
|
||||
+$as_echo "$libc_cv_include_x86_isa_level" >&6; }
|
||||
+if test $libc_cv_include_x86_isa_level = yes; then
|
||||
+ $as_echo "#define INCLUDE_X86_ISA_LEVEL 1" >>confdefs.h
|
||||
+
|
||||
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LAHF/SAHF instruction support" >&5
|
||||
+$as_echo_n "checking for LAHF/SAHF instruction support... " >&6; }
|
||||
+if ${libc_cv_have_x86_lahf_sahf+:} false; then :
|
||||
+ $as_echo_n "(cached) " >&6
|
||||
+else
|
||||
+ libc_cv_have_x86_lahf_sahf=no
|
||||
+ if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - -x c /dev/null'
|
||||
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
@@ -147,7 +158,20 @@ EOF
|
||||
test $ac_status = 0; }; } | grep -q "\-msahf"; then
|
||||
libc_cv_have_x86_lahf_sahf=yes
|
||||
fi
|
||||
- if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - conftest.c'
|
||||
+fi
|
||||
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_have_x86_lahf_sahf" >&5
|
||||
+$as_echo "$libc_cv_have_x86_lahf_sahf" >&6; }
|
||||
+ if test $libc_cv_have_x86_lahf_sahf = yes; then
|
||||
+ $as_echo "#define HAVE_X86_LAHF_SAHF 1" >>confdefs.h
|
||||
+
|
||||
+ fi
|
||||
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for MOVBE instruction support" >&5
|
||||
+$as_echo_n "checking for MOVBE instruction support... " >&6; }
|
||||
+if ${libc_cv_have_x86_movbe+:} false; then :
|
||||
+ $as_echo_n "(cached) " >&6
|
||||
+else
|
||||
+ libc_cv_have_x86_movbe=no
|
||||
+ if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - -x c /dev/null'
|
||||
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
@@ -155,23 +179,13 @@ EOF
|
||||
test $ac_status = 0; }; } | grep -q "\-mmovbe"; then
|
||||
libc_cv_have_x86_movbe=yes
|
||||
fi
|
||||
- fi
|
||||
-fi
|
||||
-rm -f conftest*
|
||||
-fi
|
||||
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_include_x86_isa_level" >&5
|
||||
-$as_echo "$libc_cv_include_x86_isa_level" >&6; }
|
||||
-if test $libc_cv_include_x86_isa_level = yes; then
|
||||
- $as_echo "#define INCLUDE_X86_ISA_LEVEL 1" >>confdefs.h
|
||||
-
|
||||
fi
|
||||
-if test $libc_cv_have_x86_lahf_sahf = yes; then
|
||||
- $as_echo "#define HAVE_X86_LAHF_SAHF 1" >>confdefs.h
|
||||
-
|
||||
-fi
|
||||
-if test $libc_cv_have_x86_movbe = yes; then
|
||||
- $as_echo "#define HAVE_X86_MOVBE 1" >>confdefs.h
|
||||
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_have_x86_movbe" >&5
|
||||
+$as_echo "$libc_cv_have_x86_movbe" >&6; }
|
||||
+ if test $libc_cv_have_x86_movbe = yes; then
|
||||
+ $as_echo "#define HAVE_X86_MOVBE 1" >>confdefs.h
|
||||
|
||||
+ fi
|
||||
fi
|
||||
config_vars="$config_vars
|
||||
enable-x86-isa-level = $libc_cv_include_x86_isa_level"
|
||||
diff --git a/sysdeps/x86/configure.ac b/sysdeps/x86/configure.ac
|
||||
index bca97fdc2f1ac1a7..04a12ab68048cd66 100644
|
||||
--- a/sysdeps/x86/configure.ac
|
||||
+++ b/sysdeps/x86/configure.ac
|
||||
@@ -98,30 +98,32 @@ cat > conftest2.S <<EOF
|
||||
4:
|
||||
EOF
|
||||
libc_cv_include_x86_isa_level=no
|
||||
-libc_cv_have_x86_lahf_sahf=no
|
||||
-libc_cv_have_x86_movbe=no
|
||||
if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -nostartfiles -nostdlib -r -o conftest conftest1.S conftest2.S); then
|
||||
count=`LC_ALL=C $READELF -n conftest | grep NT_GNU_PROPERTY_TYPE_0 | wc -l`
|
||||
if test "$count" = 1; then
|
||||
libc_cv_include_x86_isa_level=yes
|
||||
- cat > conftest.c <<EOF
|
||||
-EOF
|
||||
- if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - conftest.c) | grep -q "\-msahf"; then
|
||||
- libc_cv_have_x86_lahf_sahf=yes
|
||||
- fi
|
||||
- if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - conftest.c) | grep -q "\-mmovbe"; then
|
||||
- libc_cv_have_x86_movbe=yes
|
||||
- fi
|
||||
fi
|
||||
fi
|
||||
rm -f conftest*])
|
||||
if test $libc_cv_include_x86_isa_level = yes; then
|
||||
AC_DEFINE(INCLUDE_X86_ISA_LEVEL)
|
||||
-fi
|
||||
-if test $libc_cv_have_x86_lahf_sahf = yes; then
|
||||
- AC_DEFINE(HAVE_X86_LAHF_SAHF)
|
||||
-fi
|
||||
-if test $libc_cv_have_x86_movbe = yes; then
|
||||
- AC_DEFINE(HAVE_X86_MOVBE)
|
||||
+ AC_CACHE_CHECK([for LAHF/SAHF instruction support],
|
||||
+ libc_cv_have_x86_lahf_sahf, [dnl
|
||||
+ libc_cv_have_x86_lahf_sahf=no
|
||||
+ if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - -x c /dev/null) | grep -q "\-msahf"; then
|
||||
+ libc_cv_have_x86_lahf_sahf=yes
|
||||
+ fi])
|
||||
+ if test $libc_cv_have_x86_lahf_sahf = yes; then
|
||||
+ AC_DEFINE(HAVE_X86_LAHF_SAHF)
|
||||
+ fi
|
||||
+ AC_CACHE_CHECK([for MOVBE instruction support],
|
||||
+ libc_cv_have_x86_movbe, [dnl
|
||||
+ libc_cv_have_x86_movbe=no
|
||||
+ if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - -x c /dev/null) | grep -q "\-mmovbe"; then
|
||||
+ libc_cv_have_x86_movbe=yes
|
||||
+ fi])
|
||||
+ if test $libc_cv_have_x86_movbe = yes; then
|
||||
+ AC_DEFINE(HAVE_X86_MOVBE)
|
||||
+ fi
|
||||
fi
|
||||
LIBC_CONFIG_VAR([enable-x86-isa-level], [$libc_cv_include_x86_isa_level])
|
@ -0,0 +1,58 @@
|
||||
commit 5732a881aad24fac876f5505a212395048a7a483
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Jan 14 16:09:20 2022 +0100
|
||||
|
||||
x86: HAVE_X86_LAHF_SAHF, HAVE_X86_MOVBE and -march=x86-64-vN (bug 28782)
|
||||
|
||||
HAVE_X86_LAHF_SAHF is implied by x86-64-v2, and HAVE_X86_MOVBE by
|
||||
x86-64-v3.
|
||||
|
||||
The individual flag does not appear in -fverbose-asm flag output
|
||||
even if the ISA level implies it.
|
||||
|
||||
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
||||
|
||||
diff --git a/sysdeps/x86/configure b/sysdeps/x86/configure
|
||||
index 62676bb686850938..7bdbfdc6dc2ad38f 100644
|
||||
--- a/sysdeps/x86/configure
|
||||
+++ b/sysdeps/x86/configure
|
||||
@@ -155,7 +155,7 @@ else
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
- test $ac_status = 0; }; } | grep -q "\-msahf"; then
|
||||
+ test $ac_status = 0; }; } | grep -qE '(-msahf\b|-march=x86-64-v)'; then
|
||||
libc_cv_have_x86_lahf_sahf=yes
|
||||
fi
|
||||
fi
|
||||
@@ -176,7 +176,7 @@ else
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
- test $ac_status = 0; }; } | grep -q "\-mmovbe"; then
|
||||
+ test $ac_status = 0; }; } | grep -qE '(-mmovbe\b|-march=x86-64-v([3-9]|[1-9][0-9]))'; then
|
||||
libc_cv_have_x86_movbe=yes
|
||||
fi
|
||||
fi
|
||||
diff --git a/sysdeps/x86/configure.ac b/sysdeps/x86/configure.ac
|
||||
index 04a12ab68048cd66..10d5c2e0e555fc79 100644
|
||||
--- a/sysdeps/x86/configure.ac
|
||||
+++ b/sysdeps/x86/configure.ac
|
||||
@@ -110,7 +110,7 @@ if test $libc_cv_include_x86_isa_level = yes; then
|
||||
AC_CACHE_CHECK([for LAHF/SAHF instruction support],
|
||||
libc_cv_have_x86_lahf_sahf, [dnl
|
||||
libc_cv_have_x86_lahf_sahf=no
|
||||
- if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - -x c /dev/null) | grep -q "\-msahf"; then
|
||||
+ if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - -x c /dev/null) | grep -qE '(-msahf\b|-march=x86-64-v)'; then
|
||||
libc_cv_have_x86_lahf_sahf=yes
|
||||
fi])
|
||||
if test $libc_cv_have_x86_lahf_sahf = yes; then
|
||||
@@ -119,7 +119,7 @@ if test $libc_cv_include_x86_isa_level = yes; then
|
||||
AC_CACHE_CHECK([for MOVBE instruction support],
|
||||
libc_cv_have_x86_movbe, [dnl
|
||||
libc_cv_have_x86_movbe=no
|
||||
- if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - -x c /dev/null) | grep -q "\-mmovbe"; then
|
||||
+ if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - -x c /dev/null) | grep -qE '(-mmovbe\b|-march=x86-64-v(@<:@3-9@:>@|@<:@1-9@:>@@<:@0-9@:>@))'; then
|
||||
libc_cv_have_x86_movbe=yes
|
||||
fi])
|
||||
if test $libc_cv_have_x86_movbe = yes; then
|
@ -0,0 +1,32 @@
|
||||
commit ef7c6d42fe163a5e49a478c43e655ce4633fa5ba
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Jan 14 16:09:20 2022 +0100
|
||||
|
||||
Generate gcc-macros.h
|
||||
|
||||
The file can be used to check the effect of the default compiler
|
||||
flags on code generation even in areas of the build that uses
|
||||
non-default compiler flags.
|
||||
|
||||
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
||||
|
||||
diff --git a/Makeconfig b/Makeconfig
|
||||
index 8bc5540292c7b6fa..99898a632a64be91 100644
|
||||
--- a/Makeconfig
|
||||
+++ b/Makeconfig
|
||||
@@ -1202,6 +1202,15 @@ $(common-objpfx)dl-tunable-list.stmp: \
|
||||
touch $@
|
||||
endif
|
||||
|
||||
+# Dump the GCC macros used by the default compiler flags to a header
|
||||
+# file, so that they can be inspected when using different compiler
|
||||
+# flags. Add the GCCMACRO prefix to make these macro names unique.
|
||||
+$(common-objpfx)gcc-macros.h.in: $(common-objpfx)config.status
|
||||
+ $(CC) $(CFLAGS) $(CPPFLAGS) -E -dM -x c -o $@ /dev/null
|
||||
+$(common-objpfx)gcc-macros.h: $(common-objpfx)gcc-macros.h.in
|
||||
+ sed 's/^#define /#define GCCMACRO/' < $< > $@
|
||||
+before-compile += $(common-objpfx)gcc-macros.h
|
||||
+
|
||||
# Generate version maps, but wait until sysdep-subdirs is known
|
||||
ifeq ($(sysd-sorted-done),t)
|
||||
ifeq ($(build-shared),yes)
|
@ -0,0 +1,549 @@
|
||||
commit 7de01e60c200c431d3469deb784da8fd4508fc15
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Jan 14 20:16:05 2022 +0100
|
||||
|
||||
elf/Makefile: Reflow and sort most variable assignments
|
||||
|
||||
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
||||
|
||||
Conflicts:
|
||||
elf/Makefile
|
||||
(Usual backporting differences. LLD support is missing
|
||||
downstream.)
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 5b9c36bc6f0a3ee5..124905f96c88ab53 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -21,21 +21,62 @@ subdir := elf
|
||||
|
||||
include ../Makeconfig
|
||||
|
||||
-headers = elf.h bits/elfclass.h link.h bits/link.h
|
||||
-routines = $(all-dl-routines) dl-support dl-iteratephdr \
|
||||
- dl-addr dl-addr-obj enbl-secure dl-profstub \
|
||||
- dl-origin dl-libc dl-sym dl-sysdep dl-error \
|
||||
- dl-reloc-static-pie libc_early_init rtld_static_init
|
||||
+headers = \
|
||||
+ bits/elfclass.h \
|
||||
+ bits/link.h \
|
||||
+ elf.h \
|
||||
+ link.h \
|
||||
+ # headers
|
||||
+
|
||||
+routines = \
|
||||
+ $(all-dl-routines) \
|
||||
+ dl-addr \
|
||||
+ dl-addr-obj \
|
||||
+ dl-error \
|
||||
+ dl-iteratephdr \
|
||||
+ dl-libc \
|
||||
+ dl-origin \
|
||||
+ dl-profstub \
|
||||
+ dl-reloc-static-pie \
|
||||
+ dl-support \
|
||||
+ dl-sym \
|
||||
+ dl-sysdep \
|
||||
+ enbl-secure \
|
||||
+ libc_early_init \
|
||||
+ rtld_static_init \
|
||||
+ # routines
|
||||
|
||||
# The core dynamic linking functions are in libc for the static and
|
||||
# profiled libraries.
|
||||
-dl-routines = $(addprefix dl-,load lookup object reloc deps \
|
||||
- runtime init fini debug misc \
|
||||
- version profile tls origin scope \
|
||||
- execstack open close trampoline \
|
||||
- exception sort-maps lookup-direct \
|
||||
- call-libc-early-init write \
|
||||
- thread_gscope_wait tls_init_tp)
|
||||
+dl-routines = \
|
||||
+ dl-call-libc-early-init \
|
||||
+ dl-close \
|
||||
+ dl-debug \
|
||||
+ dl-deps \
|
||||
+ dl-exception \
|
||||
+ dl-execstack \
|
||||
+ dl-fini \
|
||||
+ dl-init \
|
||||
+ dl-load \
|
||||
+ dl-lookup \
|
||||
+ dl-lookup-direct \
|
||||
+ dl-misc \
|
||||
+ dl-object \
|
||||
+ dl-open \
|
||||
+ dl-origin \
|
||||
+ dl-profile \
|
||||
+ dl-reloc \
|
||||
+ dl-runtime \
|
||||
+ dl-scope \
|
||||
+ dl-sort-maps \
|
||||
+ dl-thread_gscope_wait \
|
||||
+ dl-tls \
|
||||
+ dl-tls_init_tp \
|
||||
+ dl-trampoline \
|
||||
+ dl-version \
|
||||
+ dl-write \
|
||||
+ # dl-routines
|
||||
+
|
||||
ifeq (yes,$(use-ldconfig))
|
||||
dl-routines += dl-cache
|
||||
endif
|
||||
@@ -58,16 +99,38 @@ endif
|
||||
|
||||
all-dl-routines = $(dl-routines) $(sysdep-dl-routines)
|
||||
# But they are absent from the shared libc, because that code is in ld.so.
|
||||
-elide-routines.os = $(all-dl-routines) dl-support enbl-secure dl-origin \
|
||||
- dl-sysdep dl-exception dl-reloc-static-pie \
|
||||
- thread_gscope_wait rtld_static_init
|
||||
+elide-routines.os = \
|
||||
+ $(all-dl-routines) \
|
||||
+ dl-exception \
|
||||
+ dl-origin \
|
||||
+ dl-reloc-static-pie \
|
||||
+ dl-support \
|
||||
+ dl-sysdep \
|
||||
+ enbl-secure \
|
||||
+ rtld_static_init \
|
||||
+ thread_gscope_wait \
|
||||
+ # elide-routines.os
|
||||
|
||||
# ld.so uses those routines, plus some special stuff for being the program
|
||||
# interpreter and operating independent of libc.
|
||||
-rtld-routines = rtld $(all-dl-routines) dl-sysdep dl-environ dl-minimal \
|
||||
- dl-error-minimal dl-conflict dl-hwcaps dl-hwcaps_split dl-hwcaps-subdirs \
|
||||
- dl-usage dl-diagnostics dl-diagnostics-kernel dl-diagnostics-cpu \
|
||||
- dl-mutex
|
||||
+rtld-routines = \
|
||||
+ $(all-dl-routines) \
|
||||
+ dl-conflict \
|
||||
+ dl-diagnostics \
|
||||
+ dl-diagnostics-cpu \
|
||||
+ dl-diagnostics-kernel \
|
||||
+ dl-environ \
|
||||
+ dl-error-minimal \
|
||||
+ dl-hwcaps \
|
||||
+ dl-hwcaps-subdirs \
|
||||
+ dl-hwcaps_split \
|
||||
+ dl-minimal \
|
||||
+ dl-mutex \
|
||||
+ dl-sysdep \
|
||||
+ dl-usage \
|
||||
+ rtld \
|
||||
+ # rtld-routines
|
||||
+
|
||||
all-rtld-routines = $(rtld-routines) $(sysdep-rtld-routines)
|
||||
|
||||
CFLAGS-dl-runtime.c += -fexceptions -fasynchronous-unwind-tables
|
||||
@@ -102,8 +165,16 @@ ld-map = $(common-objpfx)ld.map
|
||||
endif
|
||||
|
||||
ifeq (yes,$(build-shared))
|
||||
-extra-objs = $(all-rtld-routines:%=%.os) sofini.os interp.os
|
||||
-generated += librtld.os dl-allobjs.os ld.so ldd
|
||||
+extra-objs = \
|
||||
+ $(all-rtld-routines:%=%.os) \
|
||||
+ sofini.os \
|
||||
+ interp.os \
|
||||
+ # extra-objs
|
||||
+generated += \
|
||||
+ dl-allobjs.os \
|
||||
+ ld.so ldd \
|
||||
+ librtld.os \
|
||||
+ # generated
|
||||
install-others = $(inst_rtlddir)/$(rtld-installed-name) $(inst_bindir)/ld.so
|
||||
install-bin-script = ldd
|
||||
endif
|
||||
@@ -121,8 +192,15 @@ others-static += ldconfig
|
||||
others += ldconfig
|
||||
install-rootsbin += ldconfig
|
||||
|
||||
-ldconfig-modules := cache readlib xmalloc xstrdup chroot_canon static-stubs \
|
||||
- stringtable
|
||||
+ldconfig-modules := \
|
||||
+ cache \
|
||||
+ chroot_canon \
|
||||
+ readlib \
|
||||
+ static-stubs \
|
||||
+ stringtable \
|
||||
+ xmalloc \
|
||||
+ xstrdup \
|
||||
+ # ldconfig-modules
|
||||
extra-objs += $(ldconfig-modules:=.o)
|
||||
others-extras = $(ldconfig-modules)
|
||||
endif
|
||||
@@ -156,23 +234,36 @@ $(inst_auditdir)/sotruss-lib.so: $(objpfx)sotruss-lib.so $(+force)
|
||||
$(do-install-program)
|
||||
endif
|
||||
|
||||
-tests-static-normal := tst-array1-static tst-array5-static \
|
||||
- tst-dl-iter-static \
|
||||
- tst-tlsalign-static tst-tlsalign-extern-static \
|
||||
- tst-linkall-static tst-env-setuid tst-env-setuid-tunables \
|
||||
- tst-single_threaded-static tst-single_threaded-pthread-static \
|
||||
- tst-dst-static tst-getauxval-static
|
||||
-
|
||||
-tests-static-internal := tst-tls1-static tst-tls2-static \
|
||||
- tst-ptrguard1-static tst-stackguard1-static \
|
||||
- tst-tls1-static-non-pie
|
||||
+tests-static-normal := \
|
||||
+ tst-array1-static \
|
||||
+ tst-array5-static \
|
||||
+ tst-dl-iter-static \
|
||||
+ tst-dst-static \
|
||||
+ tst-env-setuid \
|
||||
+ tst-env-setuid-tunables \
|
||||
+ tst-getauxval-static \
|
||||
+ tst-linkall-static \
|
||||
+ tst-single_threaded-pthread-static \
|
||||
+ tst-single_threaded-static \
|
||||
+ tst-tlsalign-extern-static \
|
||||
+ tst-tlsalign-static \
|
||||
+ # tests-static-normal
|
||||
+
|
||||
+tests-static-internal := \
|
||||
+ tst-ptrguard1-static \
|
||||
+ tst-stackguard1-static \
|
||||
+ tst-tls1-static \
|
||||
+ tst-tls2-static \
|
||||
+ tst-tls1-static-non-pie \
|
||||
+ # tests-static-internal
|
||||
|
||||
CRT-tst-tls1-static-non-pie := $(csu-objpfx)crt1.o
|
||||
tst-tls1-static-non-pie-no-pie = yes
|
||||
|
||||
tests-container := \
|
||||
- tst-ldconfig-bad-aux-cache \
|
||||
- tst-ldconfig-ld_so_conf-update
|
||||
+ tst-ldconfig-bad-aux-cache \
|
||||
+ tst-ldconfig-ld_so_conf-update \
|
||||
+ # tests-container
|
||||
|
||||
ifeq (no,$(build-hardcoded-path-in-tests))
|
||||
# This is an ld.so.cache test, and RPATH/RUNPATH in the executable
|
||||
@@ -180,14 +271,32 @@ ifeq (no,$(build-hardcoded-path-in-tests))
|
||||
tests-container += tst-glibc-hwcaps-prepend-cache
|
||||
endif
|
||||
|
||||
-tests := tst-tls9 tst-leaks1 \
|
||||
- tst-array1 tst-array2 tst-array3 tst-array4 tst-array5 \
|
||||
- tst-auxv tst-stringtable
|
||||
-tests-internal := tst-tls1 tst-tls2 $(tests-static-internal)
|
||||
+tests := \
|
||||
+ tst-array1 \
|
||||
+ tst-array2 \
|
||||
+ tst-array3 \
|
||||
+ tst-array4 \
|
||||
+ tst-array5 \
|
||||
+ tst-auxv \
|
||||
+ tst-leaks1 \
|
||||
+ tst-stringtable \
|
||||
+ tst-tls9 \
|
||||
+ # tests
|
||||
+
|
||||
+tests-internal := \
|
||||
+ $(tests-static-internal) \
|
||||
+ tst-tls1 \
|
||||
+ tst-tls2 \
|
||||
+ # tests-internal
|
||||
+
|
||||
tests-static := $(tests-static-normal) $(tests-static-internal)
|
||||
|
||||
ifeq (yes,$(build-shared))
|
||||
-tests-static += tst-tls9-static tst-single_threaded-static-dlopen
|
||||
+tests-static += \
|
||||
+ tst-single_threaded-static-dlopen \
|
||||
+ tst-tls9-static \
|
||||
+ # tests-static
|
||||
+
|
||||
static-dlopen-environment = \
|
||||
LD_LIBRARY_PATH=$(ld-library-path):$(common-objpfx)dlfcn
|
||||
tst-tls9-static-ENV = $(static-dlopen-environment)
|
||||
@@ -313,33 +422,69 @@ tests += \
|
||||
unload6 \
|
||||
unload7 \
|
||||
unload8 \
|
||||
-# reldep9
|
||||
+ # tests
|
||||
tests-cxx = \
|
||||
tst-dlopen-nodelete-reloc \
|
||||
tst-nodelete \
|
||||
tst-unique3 \
|
||||
tst-unique4 \
|
||||
-# tests-cxx
|
||||
+ # tests-cxx
|
||||
|
||||
tests += $(if $(CXX),$(tests-cxx))
|
||||
-tests-internal += loadtest unload unload2 circleload1 \
|
||||
- neededtest neededtest2 neededtest3 neededtest4 \
|
||||
- tst-tls3 tst-tls6 tst-tls7 tst-tls8 tst-dlmopen2 \
|
||||
- tst-ptrguard1 tst-stackguard1 \
|
||||
- tst-create_format1 tst-tls-surplus tst-dl-hwcaps_split
|
||||
-tests-container += tst-pldd tst-dlopen-tlsmodid-container \
|
||||
- tst-dlopen-self-container tst-preload-pthread-libc
|
||||
-test-srcs = tst-pathopt
|
||||
+
|
||||
+tests-internal += \
|
||||
+ circleload1 \
|
||||
+ loadtest \
|
||||
+ neededtest \
|
||||
+ neededtest2 \
|
||||
+ neededtest3 \
|
||||
+ neededtest4 \
|
||||
+ tst-create_format1 \
|
||||
+ tst-dl-hwcaps_split \
|
||||
+ tst-dlmopen2 \
|
||||
+ tst-ptrguard1 \
|
||||
+ tst-stackguard1 \
|
||||
+ tst-tls-surplus \
|
||||
+ tst-tls3 \
|
||||
+ tst-tls6 \
|
||||
+ tst-tls7 \
|
||||
+ tst-tls8 \
|
||||
+ unload \
|
||||
+ unload2 \
|
||||
+ # tests-internal
|
||||
+
|
||||
+tests-container += \
|
||||
+ tst-dlopen-self-container \
|
||||
+ tst-dlopen-tlsmodid-container \
|
||||
+ tst-pldd \
|
||||
+ tst-preload-pthread-libc \
|
||||
+ # tests-container
|
||||
+
|
||||
+test-srcs = \
|
||||
+ tst-pathopt \
|
||||
+ # tests-srcs
|
||||
+
|
||||
+ifeq (yes,$(have-fpie))
|
||||
+tests-pie += tst-align3
|
||||
+endif
|
||||
selinux-enabled := $(shell cat /selinux/enforce 2> /dev/null)
|
||||
+
|
||||
ifneq ($(selinux-enabled),1)
|
||||
-tests-execstack-yes = tst-execstack tst-execstack-needed tst-execstack-prog
|
||||
+tests-execstack-yes = \
|
||||
+ tst-execstack \
|
||||
+ tst-execstack-needed \
|
||||
+ tst-execstack-prog \
|
||||
+ # tests-execstack-yes
|
||||
endif
|
||||
endif
|
||||
tests += $(tests-execstack-$(have-z-execstack))
|
||||
ifeq ($(run-built-tests),yes)
|
||||
-tests-special += $(objpfx)tst-leaks1-mem.out \
|
||||
- $(objpfx)noload-mem.out \
|
||||
- $(objpfx)tst-ldconfig-X.out $(objpfx)tst-rtld-help.out
|
||||
+tests-special += \
|
||||
+ $(objpfx)noload-mem.out \
|
||||
+ $(objpfx)tst-ldconfig-X.out \
|
||||
+ $(objpfx)tst-leaks1-mem.out \
|
||||
+ $(objpfx)tst-rtld-help.out \
|
||||
+ # tests-special
|
||||
endif
|
||||
tlsmod17a-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
||||
tlsmod18a-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
||||
@@ -356,9 +501,16 @@ tst-tls-many-dynamic-modules-dep = \
|
||||
tst-tls-many-dynamic-modules-dep-bad-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
||||
tst-tls-many-dynamic-modules-dep-bad = \
|
||||
$(foreach n,$(tst-tls-many-dynamic-modules-dep-bad-suffixes),tst-tls-manydynamic$(n)mod-dep-bad)
|
||||
-extra-test-objs += $(tlsmod17a-modules:=.os) $(tlsmod18a-modules:=.os) \
|
||||
- tst-tlsalign-vars.o
|
||||
-test-extras += tst-tlsmod17a tst-tlsmod18a tst-tlsalign-vars
|
||||
+extra-test-objs += \
|
||||
+ $(tlsmod17a-modules:=.os) \
|
||||
+ $(tlsmod18a-modules:=.os) \
|
||||
+ tst-tlsalign-vars.o \
|
||||
+ # extra-test-objs
|
||||
+test-extras += \
|
||||
+ tst-tlsalign-vars \
|
||||
+ tst-tlsmod17a \
|
||||
+ tst-tlsmod18a \
|
||||
+ # test-extras
|
||||
modules-names = \
|
||||
circlemod1 \
|
||||
circlemod1a \
|
||||
@@ -610,17 +762,17 @@ modules-names-cxx = \
|
||||
tst-unique3lib \
|
||||
tst-unique3lib2 \
|
||||
tst-unique4lib \
|
||||
-# modules-names-cxx
|
||||
+ # modules-names-cxx
|
||||
|
||||
modules-names += \
|
||||
$(if $(CXX),$(modules-names-cxx)) \
|
||||
$(modules-execstack-$(have-z-execstack)) \
|
||||
+ $(tlsmod17a-modules) \
|
||||
+ $(tlsmod18a-modules) \
|
||||
$(tst-tls-many-dynamic-modules) \
|
||||
$(tst-tls-many-dynamic-modules-dep) \
|
||||
$(tst-tls-many-dynamic-modules-dep-bad) \
|
||||
- $(tlsmod17a-modules) \
|
||||
- $(tlsmod18a-modules) \
|
||||
-# modules-names
|
||||
+ # modules-names
|
||||
|
||||
# Most modules build with _ISOMAC defined, but those filtered out
|
||||
# depend on internal headers.
|
||||
@@ -669,35 +821,70 @@ modules-names-nobuild := filtmod1 tst-big-note-lib tst-ro-dynamic-mod
|
||||
tests += $(tests-static)
|
||||
|
||||
ifeq (yes,$(have-ifunc))
|
||||
-tests-ifuncstatic := ifuncmain1static ifuncmain1picstatic \
|
||||
- ifuncmain2static ifuncmain2picstatic \
|
||||
- ifuncmain4static ifuncmain4picstatic \
|
||||
- ifuncmain5static ifuncmain5picstatic \
|
||||
- ifuncmain7static ifuncmain7picstatic
|
||||
+tests-ifuncstatic := \
|
||||
+ ifuncmain1static \
|
||||
+ ifuncmain1picstatic \
|
||||
+ ifuncmain2static \
|
||||
+ ifuncmain2picstatic \
|
||||
+ ifuncmain4static \
|
||||
+ ifuncmain4picstatic \
|
||||
+ ifuncmain5static \
|
||||
+ ifuncmain5picstatic \
|
||||
+ ifuncmain7static \
|
||||
+ ifuncmain7picstatic \
|
||||
+ # tests-ifuncstatic
|
||||
ifeq (yes,$(have-gcc-ifunc))
|
||||
tests-ifuncstatic += ifuncmain9static ifuncmain9picstatic
|
||||
endif
|
||||
tests-static += $(tests-ifuncstatic)
|
||||
tests-internal += $(tests-ifuncstatic)
|
||||
ifeq (yes,$(build-shared))
|
||||
-tests += tst-ifunc-fault-lazy tst-ifunc-fault-bindnow
|
||||
+tests += \
|
||||
+ tst-ifunc-fault-bindnow \
|
||||
+ tst-ifunc-fault-lazy \
|
||||
+ # tests
|
||||
# Note: sysdeps/x86_64/ifuncmain8.c uses ifuncmain8.
|
||||
tests-internal += \
|
||||
- ifuncmain1 ifuncmain1pic ifuncmain1vis ifuncmain1vispic \
|
||||
- ifuncmain1staticpic \
|
||||
- ifuncmain2 ifuncmain2pic ifuncmain3 ifuncmain4 \
|
||||
- ifuncmain5 ifuncmain5pic ifuncmain5staticpic \
|
||||
- ifuncmain7 ifuncmain7pic
|
||||
+ ifuncmain1 \
|
||||
+ ifuncmain1pic \
|
||||
+ ifuncmain1staticpic \
|
||||
+ ifuncmain1vis \
|
||||
+ ifuncmain1vispic \
|
||||
+ ifuncmain2 \
|
||||
+ ifuncmain2pic \
|
||||
+ ifuncmain3 \
|
||||
+ ifuncmain4 \
|
||||
+ ifuncmain5 \
|
||||
+ ifuncmain5pic \
|
||||
+ ifuncmain5staticpic \
|
||||
+ ifuncmain7 \
|
||||
+ ifuncmain7pic \
|
||||
+ # tests-internal
|
||||
ifeq (yes,$(have-gcc-ifunc))
|
||||
-tests-internal += ifuncmain9 ifuncmain9pic
|
||||
+tests-internal += \
|
||||
+ ifuncmain9 \
|
||||
+ ifuncmain9pic \
|
||||
+ # tests-internal
|
||||
endif
|
||||
-ifunc-test-modules = ifuncdep1 ifuncdep1pic ifuncdep2 ifuncdep2pic \
|
||||
- ifuncdep5 ifuncdep5pic
|
||||
+ifunc-test-modules = \
|
||||
+ ifuncdep1 \
|
||||
+ ifuncdep1pic \
|
||||
+ ifuncdep2 \
|
||||
+ ifuncdep2pic \
|
||||
+ ifuncdep5 \
|
||||
+ ifuncdep5pic \
|
||||
+ # ifunc-test-modules
|
||||
extra-test-objs += $(ifunc-test-modules:=.o)
|
||||
test-internal-extras += $(ifunc-test-modules)
|
||||
ifeq (yes,$(have-fpie))
|
||||
-ifunc-pie-tests = ifuncmain1pie ifuncmain1vispie ifuncmain1staticpie \
|
||||
- ifuncmain5pie ifuncmain6pie ifuncmain7pie
|
||||
+ifunc-pie-tests = \
|
||||
+ ifuncmain1pie \
|
||||
+ ifuncmain1staticpie \
|
||||
+ ifuncmain1vispie \
|
||||
+ ifuncmain5pie \
|
||||
+ ifuncmain6pie \
|
||||
+ ifuncmain7pie \
|
||||
+ # ifunc-pie-tests
|
||||
ifeq (yes,$(have-gcc-ifunc))
|
||||
ifunc-pie-tests += ifuncmain9pie
|
||||
endif
|
||||
@@ -707,30 +894,50 @@ endif
|
||||
tests-internal += $(ifunc-pie-tests)
|
||||
tests-pie += $(ifunc-pie-tests)
|
||||
endif
|
||||
-modules-names += ifuncmod1 ifuncmod3 ifuncmod5 ifuncmod6
|
||||
+modules-names += \
|
||||
+ ifuncmod1 \
|
||||
+ ifuncmod3 \
|
||||
+ ifuncmod5 \
|
||||
+ ifuncmod6 \
|
||||
+ # module-names
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq (yes,$(build-shared))
|
||||
ifeq ($(run-built-tests),yes)
|
||||
-tests-special += $(objpfx)tst-pathopt.out $(objpfx)tst-rtld-load-self.out \
|
||||
- $(objpfx)tst-rtld-preload.out $(objpfx)argv0test.out \
|
||||
- $(objpfx)tst-rtld-help.out
|
||||
+tests-special += \
|
||||
+ $(objpfx)argv0test.out \
|
||||
+ $(objpfx)tst-pathopt.out \
|
||||
+ $(objpfx)tst-rtld-help.out \
|
||||
+ $(objpfx)tst-rtld-load-self.out \
|
||||
+ $(objpfx)tst-rtld-preload.out \
|
||||
+ # tests-special
|
||||
endif
|
||||
-tests-special += $(objpfx)check-textrel.out $(objpfx)check-execstack.out \
|
||||
- $(objpfx)check-wx-segment.out \
|
||||
- $(objpfx)check-localplt.out $(objpfx)check-initfini.out
|
||||
+tests-special += \
|
||||
+ $(objpfx)check-execstack.out \
|
||||
+ $(objpfx)check-initfini.out \
|
||||
+ $(objpfx)check-localplt.out \
|
||||
+ $(objpfx)check-textrel.out \
|
||||
+ $(objpfx)check-wx-segment.out \
|
||||
+ # tests-special
|
||||
endif
|
||||
|
||||
ifeq ($(run-built-tests),yes)
|
||||
-tests-special += $(objpfx)order-cmp.out $(objpfx)tst-array1-cmp.out \
|
||||
- $(objpfx)tst-array1-static-cmp.out \
|
||||
- $(objpfx)tst-array2-cmp.out $(objpfx)tst-array3-cmp.out \
|
||||
- $(objpfx)tst-array4-cmp.out $(objpfx)tst-array5-cmp.out \
|
||||
- $(objpfx)tst-array5-static-cmp.out $(objpfx)order2-cmp.out \
|
||||
- $(objpfx)tst-initorder-cmp.out \
|
||||
- $(objpfx)tst-initorder2-cmp.out $(objpfx)tst-unused-dep.out \
|
||||
- $(objpfx)tst-unused-dep-cmp.out
|
||||
+tests-special += \
|
||||
+ $(objpfx)order-cmp.out \
|
||||
+ $(objpfx)order2-cmp.out \
|
||||
+ $(objpfx)tst-array1-cmp.out \
|
||||
+ $(objpfx)tst-array1-static-cmp.out \
|
||||
+ $(objpfx)tst-array2-cmp.out \
|
||||
+ $(objpfx)tst-array3-cmp.out \
|
||||
+ $(objpfx)tst-array4-cmp.out \
|
||||
+ $(objpfx)tst-array5-cmp.out \
|
||||
+ $(objpfx)tst-array5-static-cmp.out \
|
||||
+ $(objpfx)tst-initorder-cmp.out \
|
||||
+ $(objpfx)tst-initorder2-cmp.out \
|
||||
+ $(objpfx)tst-unused-dep-cmp.out \
|
||||
+ $(objpfx)tst-unused-dep.out \
|
||||
+ # tests-special
|
||||
endif
|
||||
|
||||
ifndef avoid-generated
|
||||
@@ -835,6 +1042,7 @@ rtld-stubbed-symbols = \
|
||||
free \
|
||||
malloc \
|
||||
realloc \
|
||||
+ # rtld-stubbed-symbols
|
||||
|
||||
ifeq ($(have-ssp),yes)
|
||||
# rtld is not built with the stack protector, so these references will
|
@ -0,0 +1,633 @@
|
||||
commit b693d75f0c611bce9b0ad984bad306121d42c535
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Jan 14 20:16:05 2022 +0100
|
||||
|
||||
elf: Split dl-printf.c from dl-misc.c
|
||||
|
||||
This allows to use different compiler flags for the diagnostics
|
||||
code.
|
||||
|
||||
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 124905f96c88ab53..52aafc89cec835ab 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -64,6 +64,7 @@ dl-routines = \
|
||||
dl-object \
|
||||
dl-open \
|
||||
dl-origin \
|
||||
+ dl-printf \
|
||||
dl-profile \
|
||||
dl-reloc \
|
||||
dl-runtime \
|
||||
diff --git a/elf/dl-misc.c b/elf/dl-misc.c
|
||||
index b256d792c6198683..f17140b129343f7b 100644
|
||||
--- a/elf/dl-misc.c
|
||||
+++ b/elf/dl-misc.c
|
||||
@@ -16,24 +16,16 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
-#include <assert.h>
|
||||
+#include <_itoa.h>
|
||||
#include <fcntl.h>
|
||||
#include <ldsodefs.h>
|
||||
-#include <limits.h>
|
||||
#include <link.h>
|
||||
-#include <stdarg.h>
|
||||
-#include <stdlib.h>
|
||||
-#include <string.h>
|
||||
-#include <unistd.h>
|
||||
+#include <not-cancel.h>
|
||||
#include <stdint.h>
|
||||
+#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
-#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
-#include <sys/uio.h>
|
||||
-#include <sysdep.h>
|
||||
-#include <_itoa.h>
|
||||
-#include <dl-writev.h>
|
||||
-#include <not-cancel.h>
|
||||
+#include <unistd.h>
|
||||
|
||||
/* Read the whole contents of FILE into new mmap'd space with given
|
||||
protections. *SIZEP gets the size of the file. On error MAP_FAILED
|
||||
@@ -70,270 +62,6 @@ _dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot)
|
||||
return result;
|
||||
}
|
||||
|
||||
-
|
||||
-/* Bare-bones printf implementation. This function only knows about
|
||||
- the formats and flags needed and can handle only up to 64 stripes in
|
||||
- the output. */
|
||||
-static void
|
||||
-_dl_debug_vdprintf (int fd, int tag_p, const char *fmt, va_list arg)
|
||||
-{
|
||||
-# define NIOVMAX 64
|
||||
- struct iovec iov[NIOVMAX];
|
||||
- int niov = 0;
|
||||
- pid_t pid = 0;
|
||||
- char pidbuf[12];
|
||||
-
|
||||
- while (*fmt != '\0')
|
||||
- {
|
||||
- const char *startp = fmt;
|
||||
-
|
||||
- if (tag_p > 0)
|
||||
- {
|
||||
- /* Generate the tag line once. It consists of the PID and a
|
||||
- colon followed by a tab. */
|
||||
- if (pid == 0)
|
||||
- {
|
||||
- char *p;
|
||||
- pid = __getpid ();
|
||||
- assert (pid >= 0 && sizeof (pid_t) <= 4);
|
||||
- p = _itoa (pid, &pidbuf[10], 10, 0);
|
||||
- while (p > pidbuf)
|
||||
- *--p = ' ';
|
||||
- pidbuf[10] = ':';
|
||||
- pidbuf[11] = '\t';
|
||||
- }
|
||||
-
|
||||
- /* Append to the output. */
|
||||
- assert (niov < NIOVMAX);
|
||||
- iov[niov].iov_len = 12;
|
||||
- iov[niov++].iov_base = pidbuf;
|
||||
-
|
||||
- /* No more tags until we see the next newline. */
|
||||
- tag_p = -1;
|
||||
- }
|
||||
-
|
||||
- /* Skip everything except % and \n (if tags are needed). */
|
||||
- while (*fmt != '\0' && *fmt != '%' && (! tag_p || *fmt != '\n'))
|
||||
- ++fmt;
|
||||
-
|
||||
- /* Append constant string. */
|
||||
- assert (niov < NIOVMAX);
|
||||
- if ((iov[niov].iov_len = fmt - startp) != 0)
|
||||
- iov[niov++].iov_base = (char *) startp;
|
||||
-
|
||||
- if (*fmt == '%')
|
||||
- {
|
||||
- /* It is a format specifier. */
|
||||
- char fill = ' ';
|
||||
- int width = -1;
|
||||
- int prec = -1;
|
||||
-#if LONG_MAX != INT_MAX
|
||||
- int long_mod = 0;
|
||||
-#endif
|
||||
-
|
||||
- /* Recognize zero-digit fill flag. */
|
||||
- if (*++fmt == '0')
|
||||
- {
|
||||
- fill = '0';
|
||||
- ++fmt;
|
||||
- }
|
||||
-
|
||||
- /* See whether with comes from a parameter. Note that no other
|
||||
- way to specify the width is implemented. */
|
||||
- if (*fmt == '*')
|
||||
- {
|
||||
- width = va_arg (arg, int);
|
||||
- ++fmt;
|
||||
- }
|
||||
-
|
||||
- /* Handle precision. */
|
||||
- if (*fmt == '.' && fmt[1] == '*')
|
||||
- {
|
||||
- prec = va_arg (arg, int);
|
||||
- fmt += 2;
|
||||
- }
|
||||
-
|
||||
- /* Recognize the l modifier. It is only important on some
|
||||
- platforms where long and int have a different size. We
|
||||
- can use the same code for size_t. */
|
||||
- if (*fmt == 'l' || *fmt == 'Z')
|
||||
- {
|
||||
-#if LONG_MAX != INT_MAX
|
||||
- long_mod = 1;
|
||||
-#endif
|
||||
- ++fmt;
|
||||
- }
|
||||
-
|
||||
- switch (*fmt)
|
||||
- {
|
||||
- /* Integer formatting. */
|
||||
- case 'd':
|
||||
- case 'u':
|
||||
- case 'x':
|
||||
- {
|
||||
- /* We have to make a difference if long and int have a
|
||||
- different size. */
|
||||
-#if LONG_MAX != INT_MAX
|
||||
- unsigned long int num = (long_mod
|
||||
- ? va_arg (arg, unsigned long int)
|
||||
- : va_arg (arg, unsigned int));
|
||||
-#else
|
||||
- unsigned long int num = va_arg (arg, unsigned int);
|
||||
-#endif
|
||||
- bool negative = false;
|
||||
- if (*fmt == 'd')
|
||||
- {
|
||||
-#if LONG_MAX != INT_MAX
|
||||
- if (long_mod)
|
||||
- {
|
||||
- if ((long int) num < 0)
|
||||
- negative = true;
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- if ((int) num < 0)
|
||||
- {
|
||||
- num = (unsigned int) num;
|
||||
- negative = true;
|
||||
- }
|
||||
- }
|
||||
-#else
|
||||
- if ((int) num < 0)
|
||||
- negative = true;
|
||||
-#endif
|
||||
- }
|
||||
-
|
||||
- /* We use alloca() to allocate the buffer with the most
|
||||
- pessimistic guess for the size. Using alloca() allows
|
||||
- having more than one integer formatting in a call. */
|
||||
- char *buf = (char *) alloca (1 + 3 * sizeof (unsigned long int));
|
||||
- char *endp = &buf[1 + 3 * sizeof (unsigned long int)];
|
||||
- char *cp = _itoa (num, endp, *fmt == 'x' ? 16 : 10, 0);
|
||||
-
|
||||
- /* Pad to the width the user specified. */
|
||||
- if (width != -1)
|
||||
- while (endp - cp < width)
|
||||
- *--cp = fill;
|
||||
-
|
||||
- if (negative)
|
||||
- *--cp = '-';
|
||||
-
|
||||
- iov[niov].iov_base = cp;
|
||||
- iov[niov].iov_len = endp - cp;
|
||||
- ++niov;
|
||||
- }
|
||||
- break;
|
||||
-
|
||||
- case 's':
|
||||
- /* Get the string argument. */
|
||||
- iov[niov].iov_base = va_arg (arg, char *);
|
||||
- iov[niov].iov_len = strlen (iov[niov].iov_base);
|
||||
- if (prec != -1)
|
||||
- iov[niov].iov_len = MIN ((size_t) prec, iov[niov].iov_len);
|
||||
- ++niov;
|
||||
- break;
|
||||
-
|
||||
- case '%':
|
||||
- iov[niov].iov_base = (void *) fmt;
|
||||
- iov[niov].iov_len = 1;
|
||||
- ++niov;
|
||||
- break;
|
||||
-
|
||||
- default:
|
||||
- assert (! "invalid format specifier");
|
||||
- }
|
||||
- ++fmt;
|
||||
- }
|
||||
- else if (*fmt == '\n')
|
||||
- {
|
||||
- /* See whether we have to print a single newline character. */
|
||||
- if (fmt == startp)
|
||||
- {
|
||||
- iov[niov].iov_base = (char *) startp;
|
||||
- iov[niov++].iov_len = 1;
|
||||
- }
|
||||
- else
|
||||
- /* No, just add it to the rest of the string. */
|
||||
- ++iov[niov - 1].iov_len;
|
||||
-
|
||||
- /* Next line, print a tag again. */
|
||||
- tag_p = 1;
|
||||
- ++fmt;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /* Finally write the result. */
|
||||
- _dl_writev (fd, iov, niov);
|
||||
-}
|
||||
-
|
||||
-
|
||||
-/* Write to debug file. */
|
||||
-void
|
||||
-_dl_debug_printf (const char *fmt, ...)
|
||||
-{
|
||||
- va_list arg;
|
||||
-
|
||||
- va_start (arg, fmt);
|
||||
- _dl_debug_vdprintf (GLRO(dl_debug_fd), 1, fmt, arg);
|
||||
- va_end (arg);
|
||||
-}
|
||||
-
|
||||
-
|
||||
-/* Write to debug file but don't start with a tag. */
|
||||
-void
|
||||
-_dl_debug_printf_c (const char *fmt, ...)
|
||||
-{
|
||||
- va_list arg;
|
||||
-
|
||||
- va_start (arg, fmt);
|
||||
- _dl_debug_vdprintf (GLRO(dl_debug_fd), -1, fmt, arg);
|
||||
- va_end (arg);
|
||||
-}
|
||||
-
|
||||
-
|
||||
-/* Write the given file descriptor. */
|
||||
-void
|
||||
-_dl_dprintf (int fd, const char *fmt, ...)
|
||||
-{
|
||||
- va_list arg;
|
||||
-
|
||||
- va_start (arg, fmt);
|
||||
- _dl_debug_vdprintf (fd, 0, fmt, arg);
|
||||
- va_end (arg);
|
||||
-}
|
||||
-
|
||||
-void
|
||||
-_dl_printf (const char *fmt, ...)
|
||||
-{
|
||||
- va_list arg;
|
||||
-
|
||||
- va_start (arg, fmt);
|
||||
- _dl_debug_vdprintf (STDOUT_FILENO, 0, fmt, arg);
|
||||
- va_end (arg);
|
||||
-}
|
||||
-
|
||||
-void
|
||||
-_dl_error_printf (const char *fmt, ...)
|
||||
-{
|
||||
- va_list arg;
|
||||
-
|
||||
- va_start (arg, fmt);
|
||||
- _dl_debug_vdprintf (STDERR_FILENO, 0, fmt, arg);
|
||||
- va_end (arg);
|
||||
-}
|
||||
-
|
||||
-void
|
||||
-_dl_fatal_printf (const char *fmt, ...)
|
||||
-{
|
||||
- va_list arg;
|
||||
-
|
||||
- va_start (arg, fmt);
|
||||
- _dl_debug_vdprintf (STDERR_FILENO, 0, fmt, arg);
|
||||
- va_end (arg);
|
||||
- _exit (127);
|
||||
-}
|
||||
-rtld_hidden_def (_dl_fatal_printf)
|
||||
-
|
||||
/* Test whether given NAME matches any of the names of the given object. */
|
||||
int
|
||||
_dl_name_match_p (const char *name, const struct link_map *map)
|
||||
@@ -354,7 +82,6 @@ _dl_name_match_p (const char *name, const struct link_map *map)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-
|
||||
unsigned long int
|
||||
_dl_higher_prime_number (unsigned long int n)
|
||||
{
|
||||
diff --git a/elf/dl-printf.c b/elf/dl-printf.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..d3264ba96cd959bf
|
||||
--- /dev/null
|
||||
+++ b/elf/dl-printf.c
|
||||
@@ -0,0 +1,292 @@
|
||||
+/* printf implementation for the dynamic loader.
|
||||
+ Copyright (C) 1997-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/>. */
|
||||
+
|
||||
+#include <_itoa.h>
|
||||
+#include <assert.h>
|
||||
+#include <dl-writev.h>
|
||||
+#include <ldsodefs.h>
|
||||
+#include <limits.h>
|
||||
+#include <stdarg.h>
|
||||
+#include <stdint.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <sys/uio.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+/* Bare-bones printf implementation. This function only knows about
|
||||
+ the formats and flags needed and can handle only up to 64 stripes in
|
||||
+ the output. */
|
||||
+static void
|
||||
+_dl_debug_vdprintf (int fd, int tag_p, const char *fmt, va_list arg)
|
||||
+{
|
||||
+# define NIOVMAX 64
|
||||
+ struct iovec iov[NIOVMAX];
|
||||
+ int niov = 0;
|
||||
+ pid_t pid = 0;
|
||||
+ char pidbuf[12];
|
||||
+
|
||||
+ while (*fmt != '\0')
|
||||
+ {
|
||||
+ const char *startp = fmt;
|
||||
+
|
||||
+ if (tag_p > 0)
|
||||
+ {
|
||||
+ /* Generate the tag line once. It consists of the PID and a
|
||||
+ colon followed by a tab. */
|
||||
+ if (pid == 0)
|
||||
+ {
|
||||
+ char *p;
|
||||
+ pid = __getpid ();
|
||||
+ assert (pid >= 0 && sizeof (pid_t) <= 4);
|
||||
+ p = _itoa (pid, &pidbuf[10], 10, 0);
|
||||
+ while (p > pidbuf)
|
||||
+ *--p = ' ';
|
||||
+ pidbuf[10] = ':';
|
||||
+ pidbuf[11] = '\t';
|
||||
+ }
|
||||
+
|
||||
+ /* Append to the output. */
|
||||
+ assert (niov < NIOVMAX);
|
||||
+ iov[niov].iov_len = 12;
|
||||
+ iov[niov++].iov_base = pidbuf;
|
||||
+
|
||||
+ /* No more tags until we see the next newline. */
|
||||
+ tag_p = -1;
|
||||
+ }
|
||||
+
|
||||
+ /* Skip everything except % and \n (if tags are needed). */
|
||||
+ while (*fmt != '\0' && *fmt != '%' && (! tag_p || *fmt != '\n'))
|
||||
+ ++fmt;
|
||||
+
|
||||
+ /* Append constant string. */
|
||||
+ assert (niov < NIOVMAX);
|
||||
+ if ((iov[niov].iov_len = fmt - startp) != 0)
|
||||
+ iov[niov++].iov_base = (char *) startp;
|
||||
+
|
||||
+ if (*fmt == '%')
|
||||
+ {
|
||||
+ /* It is a format specifier. */
|
||||
+ char fill = ' ';
|
||||
+ int width = -1;
|
||||
+ int prec = -1;
|
||||
+#if LONG_MAX != INT_MAX
|
||||
+ int long_mod = 0;
|
||||
+#endif
|
||||
+
|
||||
+ /* Recognize zero-digit fill flag. */
|
||||
+ if (*++fmt == '0')
|
||||
+ {
|
||||
+ fill = '0';
|
||||
+ ++fmt;
|
||||
+ }
|
||||
+
|
||||
+ /* See whether with comes from a parameter. Note that no other
|
||||
+ way to specify the width is implemented. */
|
||||
+ if (*fmt == '*')
|
||||
+ {
|
||||
+ width = va_arg (arg, int);
|
||||
+ ++fmt;
|
||||
+ }
|
||||
+
|
||||
+ /* Handle precision. */
|
||||
+ if (*fmt == '.' && fmt[1] == '*')
|
||||
+ {
|
||||
+ prec = va_arg (arg, int);
|
||||
+ fmt += 2;
|
||||
+ }
|
||||
+
|
||||
+ /* Recognize the l modifier. It is only important on some
|
||||
+ platforms where long and int have a different size. We
|
||||
+ can use the same code for size_t. */
|
||||
+ if (*fmt == 'l' || *fmt == 'Z')
|
||||
+ {
|
||||
+#if LONG_MAX != INT_MAX
|
||||
+ long_mod = 1;
|
||||
+#endif
|
||||
+ ++fmt;
|
||||
+ }
|
||||
+
|
||||
+ switch (*fmt)
|
||||
+ {
|
||||
+ /* Integer formatting. */
|
||||
+ case 'd':
|
||||
+ case 'u':
|
||||
+ case 'x':
|
||||
+ {
|
||||
+ /* We have to make a difference if long and int have a
|
||||
+ different size. */
|
||||
+#if LONG_MAX != INT_MAX
|
||||
+ unsigned long int num = (long_mod
|
||||
+ ? va_arg (arg, unsigned long int)
|
||||
+ : va_arg (arg, unsigned int));
|
||||
+#else
|
||||
+ unsigned long int num = va_arg (arg, unsigned int);
|
||||
+#endif
|
||||
+ bool negative = false;
|
||||
+ if (*fmt == 'd')
|
||||
+ {
|
||||
+#if LONG_MAX != INT_MAX
|
||||
+ if (long_mod)
|
||||
+ {
|
||||
+ if ((long int) num < 0)
|
||||
+ negative = true;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if ((int) num < 0)
|
||||
+ {
|
||||
+ num = (unsigned int) num;
|
||||
+ negative = true;
|
||||
+ }
|
||||
+ }
|
||||
+#else
|
||||
+ if ((int) num < 0)
|
||||
+ negative = true;
|
||||
+#endif
|
||||
+ }
|
||||
+
|
||||
+ /* We use alloca() to allocate the buffer with the most
|
||||
+ pessimistic guess for the size. Using alloca() allows
|
||||
+ having more than one integer formatting in a call. */
|
||||
+ char *buf = (char *) alloca (1 + 3 * sizeof (unsigned long int));
|
||||
+ char *endp = &buf[1 + 3 * sizeof (unsigned long int)];
|
||||
+ char *cp = _itoa (num, endp, *fmt == 'x' ? 16 : 10, 0);
|
||||
+
|
||||
+ /* Pad to the width the user specified. */
|
||||
+ if (width != -1)
|
||||
+ while (endp - cp < width)
|
||||
+ *--cp = fill;
|
||||
+
|
||||
+ if (negative)
|
||||
+ *--cp = '-';
|
||||
+
|
||||
+ iov[niov].iov_base = cp;
|
||||
+ iov[niov].iov_len = endp - cp;
|
||||
+ ++niov;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case 's':
|
||||
+ /* Get the string argument. */
|
||||
+ iov[niov].iov_base = va_arg (arg, char *);
|
||||
+ iov[niov].iov_len = strlen (iov[niov].iov_base);
|
||||
+ if (prec != -1)
|
||||
+ iov[niov].iov_len = MIN ((size_t) prec, iov[niov].iov_len);
|
||||
+ ++niov;
|
||||
+ break;
|
||||
+
|
||||
+ case '%':
|
||||
+ iov[niov].iov_base = (void *) fmt;
|
||||
+ iov[niov].iov_len = 1;
|
||||
+ ++niov;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ assert (! "invalid format specifier");
|
||||
+ }
|
||||
+ ++fmt;
|
||||
+ }
|
||||
+ else if (*fmt == '\n')
|
||||
+ {
|
||||
+ /* See whether we have to print a single newline character. */
|
||||
+ if (fmt == startp)
|
||||
+ {
|
||||
+ iov[niov].iov_base = (char *) startp;
|
||||
+ iov[niov++].iov_len = 1;
|
||||
+ }
|
||||
+ else
|
||||
+ /* No, just add it to the rest of the string. */
|
||||
+ ++iov[niov - 1].iov_len;
|
||||
+
|
||||
+ /* Next line, print a tag again. */
|
||||
+ tag_p = 1;
|
||||
+ ++fmt;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Finally write the result. */
|
||||
+ _dl_writev (fd, iov, niov);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* Write to debug file. */
|
||||
+void
|
||||
+_dl_debug_printf (const char *fmt, ...)
|
||||
+{
|
||||
+ va_list arg;
|
||||
+
|
||||
+ va_start (arg, fmt);
|
||||
+ _dl_debug_vdprintf (GLRO(dl_debug_fd), 1, fmt, arg);
|
||||
+ va_end (arg);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* Write to debug file but don't start with a tag. */
|
||||
+void
|
||||
+_dl_debug_printf_c (const char *fmt, ...)
|
||||
+{
|
||||
+ va_list arg;
|
||||
+
|
||||
+ va_start (arg, fmt);
|
||||
+ _dl_debug_vdprintf (GLRO(dl_debug_fd), -1, fmt, arg);
|
||||
+ va_end (arg);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* Write the given file descriptor. */
|
||||
+void
|
||||
+_dl_dprintf (int fd, const char *fmt, ...)
|
||||
+{
|
||||
+ va_list arg;
|
||||
+
|
||||
+ va_start (arg, fmt);
|
||||
+ _dl_debug_vdprintf (fd, 0, fmt, arg);
|
||||
+ va_end (arg);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+_dl_printf (const char *fmt, ...)
|
||||
+{
|
||||
+ va_list arg;
|
||||
+
|
||||
+ va_start (arg, fmt);
|
||||
+ _dl_debug_vdprintf (STDOUT_FILENO, 0, fmt, arg);
|
||||
+ va_end (arg);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+_dl_error_printf (const char *fmt, ...)
|
||||
+{
|
||||
+ va_list arg;
|
||||
+
|
||||
+ va_start (arg, fmt);
|
||||
+ _dl_debug_vdprintf (STDERR_FILENO, 0, fmt, arg);
|
||||
+ va_end (arg);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+_dl_fatal_printf (const char *fmt, ...)
|
||||
+{
|
||||
+ va_list arg;
|
||||
+
|
||||
+ va_start (arg, fmt);
|
||||
+ _dl_debug_vdprintf (STDERR_FILENO, 0, fmt, arg);
|
||||
+ va_end (arg);
|
||||
+ _exit (127);
|
||||
+}
|
||||
+rtld_hidden_def (_dl_fatal_printf)
|
@ -0,0 +1,146 @@
|
||||
commit 9ba202c78f0aa39f49929eee63c367847da72ee4
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Jan 14 20:16:05 2022 +0100
|
||||
|
||||
Add --with-rtld-early-cflags configure option
|
||||
|
||||
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
Conflicts:
|
||||
INSTALL
|
||||
configure
|
||||
manual/install.texi
|
||||
(Missing --with-timeout-factor downstream.)
|
||||
|
||||
diff --git a/INSTALL b/INSTALL
|
||||
index d6d93ec9be4262d7..d8d4e9f155f56616 100644
|
||||
--- a/INSTALL
|
||||
+++ b/INSTALL
|
||||
@@ -106,6 +106,14 @@ if 'CFLAGS' is specified it must enable optimization. For example:
|
||||
particular case and potentially change debugging information and
|
||||
metadata only).
|
||||
|
||||
+'--with-rtld-early-cflags=CFLAGS'
|
||||
+ Use additional compiler flags CFLAGS to build the early startup
|
||||
+ code of the dynamic linker. These flags can be used to enable
|
||||
+ early dynamic linker diagnostics to run on CPUs which are not
|
||||
+ compatible with the rest of the GNU C Library, for example, due to
|
||||
+ compiler flags which target a later instruction set architecture
|
||||
+ (ISA).
|
||||
+
|
||||
'--disable-shared'
|
||||
Don't build shared libraries even if it is possible. Not all
|
||||
systems support shared libraries; you need ELF support and
|
||||
diff --git a/config.make.in b/config.make.in
|
||||
index e8630a8d0ccf874d..6d43e691f7823262 100644
|
||||
--- a/config.make.in
|
||||
+++ b/config.make.in
|
||||
@@ -110,6 +110,7 @@ CFLAGS = @CFLAGS@
|
||||
CPPFLAGS-config = @CPPFLAGS@
|
||||
CPPUNDEFS = @CPPUNDEFS@
|
||||
extra-nonshared-cflags = @extra_nonshared_cflags@
|
||||
+rtld-early-cflags = @rtld_early_cflags@
|
||||
ASFLAGS-config = @ASFLAGS_config@
|
||||
AR = @AR@
|
||||
NM = @NM@
|
||||
diff --git a/configure b/configure
|
||||
index e9d2b1f398c4dba0..03f4e59e754b5463 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -681,6 +681,7 @@ force_install
|
||||
bindnow
|
||||
hardcoded_path_in_tests
|
||||
enable_timezone_tools
|
||||
+rtld_early_cflags
|
||||
extra_nonshared_cflags
|
||||
use_default_link
|
||||
sysheaders
|
||||
@@ -761,6 +762,7 @@ with_selinux
|
||||
with_headers
|
||||
with_default_link
|
||||
with_nonshared_cflags
|
||||
+with_rtld_early_cflags
|
||||
enable_sanity_checks
|
||||
enable_shared
|
||||
enable_profile
|
||||
@@ -1479,6 +1481,8 @@ Optional Packages:
|
||||
--with-default-link do not use explicit linker scripts
|
||||
--with-nonshared-cflags=CFLAGS
|
||||
build nonshared libraries with additional CFLAGS
|
||||
+ --with-rtld-early-cflags=CFLAGS
|
||||
+ build early initialization with additional CFLAGS
|
||||
--with-cpu=CPU select code for CPU variant
|
||||
|
||||
Some influential environment variables:
|
||||
@@ -3383,6 +3387,16 @@ fi
|
||||
|
||||
|
||||
|
||||
+# Check whether --with-rtld-early-cflags was given.
|
||||
+if test "${with_rtld_early_cflags+set}" = set; then :
|
||||
+ withval=$with_rtld_early_cflags; rtld_early_cflags=$withval
|
||||
+else
|
||||
+ rtld_early_cflags=
|
||||
+fi
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
# Check whether --enable-sanity-checks was given.
|
||||
if test "${enable_sanity_checks+set}" = set; then :
|
||||
enableval=$enable_sanity_checks; enable_sanity=$enableval
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 79f6822d29ce21cf..eb9431875fae1b0e 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -162,6 +162,12 @@ AC_ARG_WITH([nonshared-cflags],
|
||||
[extra_nonshared_cflags=$withval],
|
||||
[extra_nonshared_cflags=])
|
||||
AC_SUBST(extra_nonshared_cflags)
|
||||
+AC_ARG_WITH([rtld-early-cflags],
|
||||
+ AS_HELP_STRING([--with-rtld-early-cflags=CFLAGS],
|
||||
+ [build early initialization with additional CFLAGS]),
|
||||
+ [rtld_early_cflags=$withval],
|
||||
+ [rtld_early_cflags=])
|
||||
+AC_SUBST(rtld_early_cflags)
|
||||
|
||||
AC_ARG_ENABLE([sanity-checks],
|
||||
AS_HELP_STRING([--disable-sanity-checks],
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 52aafc89cec835ab..778e393395fc5248 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -152,6 +152,14 @@ CFLAGS-.o += $(call elide-stack-protector,.o,$(elide-routines.os))
|
||||
CFLAGS-.op += $(call elide-stack-protector,.op,$(elide-routines.os))
|
||||
CFLAGS-.os += $(call elide-stack-protector,.os,$(all-rtld-routines))
|
||||
|
||||
+# Add the requested compiler flags to the early startup code.
|
||||
+CFLAGS-dl-printf.os += $(rtld-early-cflags)
|
||||
+CFLAGS-dl-sysdep.os += $(rtld-early-cflags)
|
||||
+CFLAGS-dl-tunables.os += $(rtld-early-cflags)
|
||||
+CFLAGS-dl-write.os += $(rtld-early-cflags)
|
||||
+CFLAGS-dl-writev.os += $(rtld-early-cflags)
|
||||
+CFLAGS-rtld.os += $(rtld-early-cflags)
|
||||
+
|
||||
ifeq ($(unwind-find-fde),yes)
|
||||
routines += unwind-dw2-fde-glibc
|
||||
shared-only-routines += unwind-dw2-fde-glibc
|
||||
diff --git a/manual/install.texi b/manual/install.texi
|
||||
index 1320ac69b3c645f2..816b77a0a25a88a7 100644
|
||||
--- a/manual/install.texi
|
||||
+++ b/manual/install.texi
|
||||
@@ -131,6 +131,13 @@ that the objects in @file{libc_nonshared.a} are compiled with this flag
|
||||
(although this will not affect the generated code in this particular
|
||||
case and potentially change debugging information and metadata only).
|
||||
|
||||
+@item --with-rtld-early-cflags=@var{cflags}
|
||||
+Use additional compiler flags @var{cflags} to build the early startup
|
||||
+code of the dynamic linker. These flags can be used to enable early
|
||||
+dynamic linker diagnostics to run on CPUs which are not compatible with
|
||||
+the rest of @theglibc{}, for example, due to compiler flags which target
|
||||
+a later instruction set architecture (ISA).
|
||||
+
|
||||
@c disable static doesn't work currently
|
||||
@c @item --disable-static
|
||||
@c Don't build static libraries. Static libraries aren't that useful these
|
@ -0,0 +1,52 @@
|
||||
commit 550116486692efc394d03befee19f7e9c17d5044
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Jan 14 20:16:05 2022 +0100
|
||||
|
||||
powerpc64le: Use <gcc-macros.h> in early HWCAP check
|
||||
|
||||
This is required so that the checks still work if $(early-cflags)
|
||||
selects a different ISA level.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
Tested-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/sysdeps/powerpc/powerpc64/le/dl-hwcap-check.h b/sysdeps/powerpc/powerpc64/le/dl-hwcap-check.h
|
||||
index 0437ae4d522fb36d..899c74f880e6f5f0 100644
|
||||
--- a/sysdeps/powerpc/powerpc64/le/dl-hwcap-check.h
|
||||
+++ b/sysdeps/powerpc/powerpc64/le/dl-hwcap-check.h
|
||||
@@ -19,17 +19,18 @@
|
||||
#ifndef _DL_HWCAP_CHECK_H
|
||||
#define _DL_HWCAP_CHECK_H
|
||||
|
||||
+#include <gcc-macros.h>
|
||||
#include <ldsodefs.h>
|
||||
|
||||
static inline void
|
||||
dl_hwcap_check (void)
|
||||
{
|
||||
-#ifdef _ARCH_PWR9
|
||||
+#ifdef GCCMACRO_ARCH_PWR9
|
||||
if ((GLRO (dl_hwcap2) & PPC_FEATURE2_ARCH_3_00) == 0)
|
||||
_dl_fatal_printf ("\
|
||||
Fatal glibc error: CPU lacks ISA 3.00 support (POWER9 or later required)\n");
|
||||
#endif
|
||||
-#ifdef __FLOAT128_HARDWARE__
|
||||
+#ifdef GCCMACRO__FLOAT128_HARDWARE__
|
||||
if ((GLRO (dl_hwcap2) & PPC_FEATURE2_HAS_IEEE128) == 0)
|
||||
_dl_fatal_printf ("\
|
||||
Fatal glibc error: CPU lacks float128 support (POWER 9 or later required)\n");
|
||||
@@ -37,12 +38,12 @@ Fatal glibc error: CPU lacks float128 support (POWER 9 or later required)\n");
|
||||
/* This check is not actually reached when building for POWER10 and
|
||||
running on POWER9 because there are faulting PCREL instructions
|
||||
before this point. */
|
||||
-#if defined _ARCH_PWR10 || defined __PCREL__
|
||||
+#if defined GCCMACRO_ARCH_PWR10 || defined GCCMACRO__PCREL__
|
||||
if ((GLRO (dl_hwcap2) & PPC_FEATURE2_ARCH_3_1) == 0)
|
||||
_dl_fatal_printf ("\
|
||||
Fatal glibc error: CPU lacks ISA 3.10 support (POWER10 or later required)\n");
|
||||
#endif
|
||||
-#ifdef __MMA__
|
||||
+#ifdef GCCMACRO__MMA__
|
||||
if ((GLRO (dl_hwcap2) & PPC_FEATURE2_MMA) == 0)
|
||||
_dl_fatal_printf ("\
|
||||
Fatal glibc error: CPU lacks MMA support (POWER10 or later required)\n");
|
@ -0,0 +1,27 @@
|
||||
commit ea89d5bbd9e5e514b606045d909e6ab87d851c88
|
||||
Author: Arjun Shankar <arjun@redhat.com>
|
||||
Date: Thu Feb 24 21:43:09 2022 +0100
|
||||
|
||||
localedef: Handle symbolic links when generating locale-archive
|
||||
|
||||
Whenever locale data for any locale included symbolic links, localedef
|
||||
would throw the error "incomplete set of locale files" and exclude it
|
||||
from the generated locale archive. This commit fixes that.
|
||||
|
||||
Co-authored-by: Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/locale/programs/locarchive.c b/locale/programs/locarchive.c
|
||||
index f38e835c52e4a967..d79278b6ed7340bf 100644
|
||||
--- a/locale/programs/locarchive.c
|
||||
+++ b/locale/programs/locarchive.c
|
||||
@@ -1391,7 +1391,7 @@ add_locales_to_archive (size_t nlist, char *list[], bool replace)
|
||||
{
|
||||
char fullname[fnamelen + 2 * strlen (d->d_name) + 7];
|
||||
|
||||
- if (d_type == DT_UNKNOWN)
|
||||
+ if (d_type == DT_UNKNOWN || d_type == DT_LNK)
|
||||
{
|
||||
strcpy (stpcpy (stpcpy (fullname, fname), "/"),
|
||||
d->d_name);
|
@ -0,0 +1,296 @@
|
||||
commit 2ab8b74567dc0a9a3c98696e6444881997dd6c49
|
||||
Author: Carlos O'Donell <carlos@redhat.com>
|
||||
Date: Thu Feb 3 16:51:59 2022 -0500
|
||||
|
||||
localedef: Update LC_MONETARY handling (Bug 28845)
|
||||
|
||||
ISO C17, POSIX Issue 7, and ISO 30112 all allow the char*
|
||||
types to be empty strings i.e. "", integer or char values to
|
||||
be -1 or CHAR_MAX respectively, with the exception of
|
||||
decimal_point which must be non-empty in ISO C. Note that
|
||||
the defaults for mon_grouping vary, but are functionaly
|
||||
equivalent e.g. "\177" (no further grouping reuqired) vs.
|
||||
"" (no grouping defined for all groups).
|
||||
|
||||
We include a broad comment talking about harmonizing ISO C,
|
||||
POSIX, ISO 30112, and the default C/POSIX locale for glibc.
|
||||
|
||||
We reorder all setting based on locale/categories.def order.
|
||||
|
||||
We soften all missing definitions from errors to warnings when
|
||||
defaults exist.
|
||||
|
||||
Given that ISO C, POSIX and ISO 30112 allow the empty string
|
||||
we change LC_MONETARY handling of mon_decimal_point to allow
|
||||
the empty string. If mon_decimal_point is not defined at all
|
||||
then we pick the existing legacy glibc default value of
|
||||
<U002E> i.e. ".".
|
||||
|
||||
We also set the default for mon_thousands_sep_wc at the
|
||||
same time as mon_thousands_sep, but this is not a change in
|
||||
behaviour, it is always either a matching value or L'\0',
|
||||
but if in the future we change the default to a non-empty
|
||||
string we would need to update both at the same time.
|
||||
|
||||
Tested on x86_64 and i686 without regressions.
|
||||
Tested with install-locale-archive target.
|
||||
Tested with install-locale-files target.
|
||||
|
||||
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||
|
||||
diff --git a/locale/programs/ld-monetary.c b/locale/programs/ld-monetary.c
|
||||
index 9b9a55bb4766dfcf..17a972e1a7516aa5 100644
|
||||
--- a/locale/programs/ld-monetary.c
|
||||
+++ b/locale/programs/ld-monetary.c
|
||||
@@ -197,21 +197,105 @@ No definition for %s category found"), "LC_MONETARY");
|
||||
}
|
||||
}
|
||||
|
||||
+ /* Generally speaking there are 3 standards the define the default,
|
||||
+ warning, and error behaviour of LC_MONETARY. They are ISO/IEC TR 30112,
|
||||
+ ISO/IEC 9899:2018 (ISO C17), and POSIX.1-2017. Within 30112 we have the
|
||||
+ definition of a standard i18n FDCC-set, which for LC_MONETARY has the
|
||||
+ following default values:
|
||||
+ int_curr_symbol ""
|
||||
+ currency_symbol ""
|
||||
+ mon_decimal_point "<U002C>" i.e. ","
|
||||
+ mon_thousand_sep ""
|
||||
+ mon_grouping "\177" i.e. CHAR_MAX
|
||||
+ positive_sign ""
|
||||
+ negative_sign "<U002E>" i.e. "."
|
||||
+ int_frac_digits -1
|
||||
+ frac_digits -1
|
||||
+ p_cs_precedes -1
|
||||
+ p_sep_by_space -1
|
||||
+ n_cs_precedes -1
|
||||
+ n_sep_by_space -1
|
||||
+ p_sign_posn -1
|
||||
+ n_sign_posn -1
|
||||
+ Under 30112 a keyword that is not provided implies an empty string ""
|
||||
+ for string values or a -1 for integer values, and indicates the value
|
||||
+ is unspecified with no default implied. No errors are considered.
|
||||
+ The exception is mon_grouping which is a string with a terminating
|
||||
+ CHAR_MAX.
|
||||
+ For POSIX Issue 7 we have:
|
||||
+ https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html
|
||||
+ and again values not provided default to "" or -1, and indicate the value
|
||||
+ is not available to the locale. The exception is mon_grouping which is
|
||||
+ a string with a terminating CHAR_MAX. For the POSIX locale the values of
|
||||
+ LC_MONETARY should be:
|
||||
+ int_curr_symbol ""
|
||||
+ currency_symbol ""
|
||||
+ mon_decimal_point ""
|
||||
+ mon_thousands_sep ""
|
||||
+ mon_grouping "\177" i.e. CHAR_MAX
|
||||
+ positive_sign ""
|
||||
+ negative_sign ""
|
||||
+ int_frac_digits -1
|
||||
+ frac_digits -1
|
||||
+ p_cs_precedes -1
|
||||
+ p_sep_by_space -1
|
||||
+ n_cs_precedes -1
|
||||
+ n_sep_by_space -1
|
||||
+ p_sign_posn -1
|
||||
+ n_sign_posn -1
|
||||
+ int_p_cs_precedes -1
|
||||
+ int_p_sep_by_space -1
|
||||
+ int_n_cs_precedes -1
|
||||
+ int_n_sep_by_space -1
|
||||
+ int_p_sign_posn -1
|
||||
+ int_n_sign_posn -1
|
||||
+ Like with 30112, POSIX also considers no error if the keywords are
|
||||
+ missing, only that if the cateory as a whole is missing the referencing
|
||||
+ of the category results in unspecified behaviour.
|
||||
+ For ISO C17 there is no default value provided, but the localeconv
|
||||
+ specification in 7.11.2.1 admits that members of char * type may point
|
||||
+ to "" to indicate a value is not available or is of length zero.
|
||||
+ The exception is decimal_point (not mon_decimal_point) which must be a
|
||||
+ defined non-empty string. The values of char, which are generally
|
||||
+ mapped to integer values in 30112 and POSIX, must be non-negative
|
||||
+ numbers that map to CHAR_MAX when a value is not available in the
|
||||
+ locale.
|
||||
+ In ISO C17 for the "C" locale all values are empty strings "", or
|
||||
+ CHAR_MAX, with the exception of decimal_point which is "." (defined
|
||||
+ in LC_NUMERIC). ISO C17 makes no exception for mon_grouping like
|
||||
+ 30112 and POSIX, but a value of "" is functionally equivalent to
|
||||
+ "\177" since neither defines a grouping (though the latter terminates
|
||||
+ the grouping).
|
||||
+
|
||||
+ Lastly, we must consider the legacy C/POSIX locale that implemented
|
||||
+ as a builtin in glibc and wether a default value mapping to the
|
||||
+ C/POSIX locale may benefit the user from a compatibility perspective.
|
||||
+
|
||||
+ Thus given 30112, POSIX, ISO C, and the builtin C/POSIX locale we
|
||||
+ need to pick appropriate defaults below. */
|
||||
+
|
||||
+ /* The members of LC_MONETARY are handled in the order of their definition
|
||||
+ in locale/categories.def. Please keep them in that order. */
|
||||
+
|
||||
+ /* The purpose of TEST_ELEM is to define a default value for the fields
|
||||
+ in the category if the field was not defined in the cateory. If the
|
||||
+ category was present but we didn't see a definition for the field then
|
||||
+ we also issue a warning, otherwise the only warning you get is the one
|
||||
+ earlier when a default category is created (completely missing category).
|
||||
+ This missing field warning is glibc-specific since no standard requires
|
||||
+ this warning, but we consider it valuable to print a warning for all
|
||||
+ missing fields in the category. */
|
||||
#define TEST_ELEM(cat, initval) \
|
||||
if (monetary->cat == NULL) \
|
||||
{ \
|
||||
if (! nothing) \
|
||||
- record_error (0, 0, _("%s: field `%s' not defined"), \
|
||||
- "LC_MONETARY", #cat); \
|
||||
+ record_warning (_("%s: field `%s' not defined"), \
|
||||
+ "LC_MONETARY", #cat); \
|
||||
monetary->cat = initval; \
|
||||
}
|
||||
|
||||
+ /* Keyword: int_curr_symbol. */
|
||||
TEST_ELEM (int_curr_symbol, "");
|
||||
- TEST_ELEM (currency_symbol, "");
|
||||
- TEST_ELEM (mon_thousands_sep, "");
|
||||
- TEST_ELEM (positive_sign, "");
|
||||
- TEST_ELEM (negative_sign, "");
|
||||
-
|
||||
/* The international currency symbol must come from ISO 4217. */
|
||||
if (monetary->int_curr_symbol != NULL)
|
||||
{
|
||||
@@ -248,41 +332,63 @@ not correspond to a valid name in ISO 4217 [--no-warnings=intcurrsym]"),
|
||||
}
|
||||
}
|
||||
|
||||
- /* The decimal point must not be empty. This is not said explicitly
|
||||
- in POSIX but ANSI C (ISO/IEC 9899) says in 4.4.2.1 it has to be
|
||||
- != "". */
|
||||
+ /* Keyword: currency_symbol */
|
||||
+ TEST_ELEM (currency_symbol, "");
|
||||
+
|
||||
+ /* Keyword: mon_decimal_point */
|
||||
+ /* ISO C17 7.11.2.1.3 explicitly allows mon_decimal_point to be the
|
||||
+ empty string e.g. "". This indicates the value is not available in the
|
||||
+ current locale or is of zero length. However, if the value was never
|
||||
+ defined then we issue a warning and use a glibc-specific default. ISO
|
||||
+ 30112 in the i18n FDCC-Set uses <U002C> ",", and POSIX Issue 7 in the
|
||||
+ POSIX locale uses "". It is specific to glibc that the default is <U002E>
|
||||
+ "."; we retain this existing behaviour for backwards compatibility. */
|
||||
if (monetary->mon_decimal_point == NULL)
|
||||
{
|
||||
if (! nothing)
|
||||
- record_error (0, 0, _("%s: field `%s' not defined"),
|
||||
- "LC_MONETARY", "mon_decimal_point");
|
||||
+ record_warning (_("%s: field `%s' not defined, using defaults"),
|
||||
+ "LC_MONETARY", "mon_decimal_point");
|
||||
monetary->mon_decimal_point = ".";
|
||||
monetary->mon_decimal_point_wc = L'.';
|
||||
}
|
||||
- else if (monetary->mon_decimal_point[0] == '\0' && ! be_quiet && ! nothing)
|
||||
+
|
||||
+ /* Keyword: mon_thousands_sep */
|
||||
+ if (monetary->mon_thousands_sep == NULL)
|
||||
{
|
||||
- record_error (0, 0, _("\
|
||||
-%s: value for field `%s' must not be an empty string"),
|
||||
- "LC_MONETARY", "mon_decimal_point");
|
||||
+ if (! nothing)
|
||||
+ record_warning (_("%s: field `%s' not defined, using defaults"),
|
||||
+ "LC_MONETARY", "mon_thousands_sep");
|
||||
+ monetary->mon_thousands_sep = "";
|
||||
+ monetary->mon_thousands_sep_wc = L'\0';
|
||||
}
|
||||
|
||||
+ /* Keyword: mon_grouping */
|
||||
if (monetary->mon_grouping_len == 0)
|
||||
{
|
||||
if (! nothing)
|
||||
- record_error (0, 0, _("%s: field `%s' not defined"),
|
||||
- "LC_MONETARY", "mon_grouping");
|
||||
-
|
||||
+ record_warning (_("%s: field `%s' not defined"),
|
||||
+ "LC_MONETARY", "mon_grouping");
|
||||
+ /* Missing entries are given 1 element in their bytearray with
|
||||
+ a value of CHAR_MAX which indicates that "No further grouping
|
||||
+ is to be performed" (functionally equivalent to ISO C's "C"
|
||||
+ locale default of ""). */
|
||||
monetary->mon_grouping = (char *) "\177";
|
||||
monetary->mon_grouping_len = 1;
|
||||
}
|
||||
|
||||
+ /* Keyword: positive_sign */
|
||||
+ TEST_ELEM (positive_sign, "");
|
||||
+
|
||||
+ /* Keyword: negative_sign */
|
||||
+ TEST_ELEM (negative_sign, "");
|
||||
+
|
||||
#undef TEST_ELEM
|
||||
#define TEST_ELEM(cat, min, max, initval) \
|
||||
if (monetary->cat == -2) \
|
||||
{ \
|
||||
if (! nothing) \
|
||||
- record_error (0, 0, _("%s: field `%s' not defined"), \
|
||||
- "LC_MONETARY", #cat); \
|
||||
+ record_warning (_("%s: field `%s' not defined"), \
|
||||
+ "LC_MONETARY", #cat); \
|
||||
monetary->cat = initval; \
|
||||
} \
|
||||
else if ((monetary->cat < min || monetary->cat > max) \
|
||||
@@ -301,16 +407,11 @@ not correspond to a valid name in ISO 4217 [--no-warnings=intcurrsym]"),
|
||||
TEST_ELEM (p_sign_posn, -1, 4, -1);
|
||||
TEST_ELEM (n_sign_posn, -1, 4, -1);
|
||||
|
||||
- /* The non-POSIX.2 extensions are optional. */
|
||||
- if (monetary->duo_int_curr_symbol == NULL)
|
||||
- monetary->duo_int_curr_symbol = monetary->int_curr_symbol;
|
||||
- if (monetary->duo_currency_symbol == NULL)
|
||||
- monetary->duo_currency_symbol = monetary->currency_symbol;
|
||||
-
|
||||
- if (monetary->duo_int_frac_digits == -2)
|
||||
- monetary->duo_int_frac_digits = monetary->int_frac_digits;
|
||||
- if (monetary->duo_frac_digits == -2)
|
||||
- monetary->duo_frac_digits = monetary->frac_digits;
|
||||
+ /* Keyword: crncystr */
|
||||
+ monetary->crncystr = (char *) xmalloc (strlen (monetary->currency_symbol)
|
||||
+ + 2);
|
||||
+ monetary->crncystr[0] = monetary->p_cs_precedes ? '-' : '+';
|
||||
+ strcpy (&monetary->crncystr[1], monetary->currency_symbol);
|
||||
|
||||
#undef TEST_ELEM
|
||||
#define TEST_ELEM(cat, alt, min, max) \
|
||||
@@ -328,6 +429,17 @@ not correspond to a valid name in ISO 4217 [--no-warnings=intcurrsym]"),
|
||||
TEST_ELEM (int_p_sign_posn, p_sign_posn, -1, 4);
|
||||
TEST_ELEM (int_n_sign_posn, n_sign_posn, -1, 4);
|
||||
|
||||
+ /* The non-POSIX.2 extensions are optional. */
|
||||
+ if (monetary->duo_int_curr_symbol == NULL)
|
||||
+ monetary->duo_int_curr_symbol = monetary->int_curr_symbol;
|
||||
+ if (monetary->duo_currency_symbol == NULL)
|
||||
+ monetary->duo_currency_symbol = monetary->currency_symbol;
|
||||
+
|
||||
+ if (monetary->duo_int_frac_digits == -2)
|
||||
+ monetary->duo_int_frac_digits = monetary->int_frac_digits;
|
||||
+ if (monetary->duo_frac_digits == -2)
|
||||
+ monetary->duo_frac_digits = monetary->frac_digits;
|
||||
+
|
||||
TEST_ELEM (duo_p_cs_precedes, p_cs_precedes, -1, 1);
|
||||
TEST_ELEM (duo_p_sep_by_space, p_sep_by_space, -1, 2);
|
||||
TEST_ELEM (duo_n_cs_precedes, n_cs_precedes, -1, 1);
|
||||
@@ -350,17 +462,15 @@ not correspond to a valid name in ISO 4217 [--no-warnings=intcurrsym]"),
|
||||
if (monetary->duo_valid_to == 0)
|
||||
monetary->duo_valid_to = 99991231;
|
||||
|
||||
+ /* Keyword: conversion_rate */
|
||||
if (monetary->conversion_rate[0] == 0)
|
||||
{
|
||||
monetary->conversion_rate[0] = 1;
|
||||
monetary->conversion_rate[1] = 1;
|
||||
}
|
||||
|
||||
- /* Create the crncystr entry. */
|
||||
- monetary->crncystr = (char *) xmalloc (strlen (monetary->currency_symbol)
|
||||
- + 2);
|
||||
- monetary->crncystr[0] = monetary->p_cs_precedes ? '-' : '+';
|
||||
- strcpy (&monetary->crncystr[1], monetary->currency_symbol);
|
||||
+ /* A value for monetary-decimal-point-wc was set when
|
||||
+ monetary_decimal_point was set, likewise for monetary-thousands-sep-wc. */
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,62 @@
|
||||
commit 1c7a34567d21fbd3b706c77cd794956b43daefe7
|
||||
Author: Carlos O'Donell <carlos@redhat.com>
|
||||
Date: Thu Feb 3 16:01:52 2022 -0500
|
||||
|
||||
localedata: Do not generate output if warnings were present.
|
||||
|
||||
With LC_MONETARY parsing fixed we can now generate locales
|
||||
without forcing output with '-c'.
|
||||
|
||||
Removing '-c' from localedef invocation is the equivalent of
|
||||
using -Werror for localedef. The glibc locale sources should
|
||||
always be clean and free from warnings.
|
||||
|
||||
We remove '-c' from both test locale generation and the targets
|
||||
used for installing locales e.g. install-locale-archive, and
|
||||
install-locale-files.
|
||||
|
||||
Tested on x86_64 and i686 without regressions.
|
||||
Tested with install-locale-archive target.
|
||||
Tested with install-locale-files target.
|
||||
|
||||
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||
|
||||
diff --git a/localedata/Makefile b/localedata/Makefile
|
||||
index 5830b9d05141cccd..a46da8a9311b00b0 100644
|
||||
--- a/localedata/Makefile
|
||||
+++ b/localedata/Makefile
|
||||
@@ -469,11 +469,11 @@ define build-one-locale
|
||||
endef
|
||||
|
||||
$(INSTALL-SUPPORTED-LOCALE-ARCHIVE): install-locales-dir
|
||||
- @flags="-c"; \
|
||||
+ @flags=""; \
|
||||
$(build-one-locale)
|
||||
|
||||
$(INSTALL-SUPPORTED-LOCALE-FILES): install-locales-dir
|
||||
- @flags="-c --no-archive --no-hard-links"; \
|
||||
+ @flags="--no-archive --no-hard-links"; \
|
||||
$(build-one-locale)
|
||||
|
||||
tst-setlocale-ENV = LC_ALL=ja_JP.EUC-JP
|
||||
diff --git a/localedata/gen-locale.sh b/localedata/gen-locale.sh
|
||||
index c7e2e160ae1506f8..a25d27f3e6986675 100644
|
||||
--- a/localedata/gen-locale.sh
|
||||
+++ b/localedata/gen-locale.sh
|
||||
@@ -54,8 +54,14 @@ modifier=`echo $locfile|sed 's|[^.]*[.]\([^@ ]*\)\(@[^ ]*\)\?/LC_CTYPE|\2|'`
|
||||
|
||||
echo "Generating locale $locale.$charmap: this might take a while..."
|
||||
|
||||
-# Run quietly and force output.
|
||||
-flags="--quiet -c"
|
||||
+# Do not force output with '-c', all locales should compile without
|
||||
+# warning or errors. There is likewise no need to run quietly with
|
||||
+# '--quiet' since all locales should compile without additional
|
||||
+# diagnostics. If there are messages printed then we want to see
|
||||
+# them, fix them, and the associated error or warning. During
|
||||
+# development it may be beneficialy to put '--quiet -c' here to allow
|
||||
+# you to develop in-progress locales.
|
||||
+flags=""
|
||||
|
||||
# For SJIS the charmap is SHIFT_JIS. We just want the locale to have
|
||||
# a slightly nicer name instead of using "*.SHIFT_SJIS", but that
|
@ -0,0 +1,37 @@
|
||||
Early backport of upstream patch under discussion:
|
||||
|
||||
[PATCH v3] elf: Fix DFS sorting algorithm for LD_TRACE_LOADED_OBJECTS
|
||||
with missing libraries (BZ #28868)
|
||||
<https://sourceware.org/pipermail/libc-alpha/2022-February/136641.html>
|
||||
|
||||
The tests are still being discussed upstream and are not backported
|
||||
here.
|
||||
|
||||
diff --git a/elf/dl-deps.c b/elf/dl-deps.c
|
||||
index 237d9636c5be780c..9e30c6c3f6c58783 100644
|
||||
--- a/elf/dl-deps.c
|
||||
+++ b/elf/dl-deps.c
|
||||
@@ -489,6 +489,8 @@ _dl_map_object_deps (struct link_map *map,
|
||||
|
||||
for (nlist = 0, runp = known; runp; runp = runp->next)
|
||||
{
|
||||
+ /* _dl_sort_maps ignores l_faked object, so it is save to not considere
|
||||
+ them for nlist. */
|
||||
if (__builtin_expect (trace_mode, 0) && runp->map->l_faked)
|
||||
/* This can happen when we trace the loading. */
|
||||
--map->l_searchlist.r_nlist;
|
||||
diff --git a/elf/dl-sort-maps.c b/elf/dl-sort-maps.c
|
||||
index a274ed66cc987735..72f4ff0e6eda3377 100644
|
||||
--- a/elf/dl-sort-maps.c
|
||||
+++ b/elf/dl-sort-maps.c
|
||||
@@ -140,7 +140,9 @@ static void
|
||||
dfs_traversal (struct link_map ***rpo, struct link_map *map,
|
||||
bool *do_reldeps)
|
||||
{
|
||||
- if (map->l_visited)
|
||||
+ /* _dl_map_object_deps filter l_faked objects when calculating the
|
||||
+ number of maps before calling _dl_sort_maps, ignore them as well. */
|
||||
+ if (map->l_visited || map->l_faked)
|
||||
return;
|
||||
|
||||
map->l_visited = 1;
|
@ -0,0 +1,605 @@
|
||||
commit c901c3e764d7c7079f006b4e21e877d5036eb4f5
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu Dec 9 09:49:32 2021 +0100
|
||||
|
||||
nptl: Add public rseq symbols and <sys/rseq.h>
|
||||
|
||||
The relationship between the thread pointer and the rseq area
|
||||
is made explicit. The constant offset can be used by JIT compilers
|
||||
to optimize rseq access (e.g., for really fast sched_getcpu).
|
||||
|
||||
Extensibility is provided through __rseq_size and __rseq_flags.
|
||||
(In the future, the kernel could request a different rseq size
|
||||
via the auxiliary vector.)
|
||||
|
||||
Co-Authored-By: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||
|
||||
diff --git a/manual/threads.texi b/manual/threads.texi
|
||||
index 7f166bfa87e88c36..4869f69d2ceed255 100644
|
||||
--- a/manual/threads.texi
|
||||
+++ b/manual/threads.texi
|
||||
@@ -629,6 +629,8 @@ the standard.
|
||||
* Waiting with Explicit Clocks:: Functions for waiting with an
|
||||
explicit clock specification.
|
||||
* Single-Threaded:: Detecting single-threaded execution.
|
||||
+* Restartable Sequences:: Linux-specific restartable sequences
|
||||
+ integration.
|
||||
@end menu
|
||||
|
||||
@node Default Thread Attributes
|
||||
@@ -958,6 +960,85 @@ application-created thread because future versions of @theglibc{} may
|
||||
create background threads after the first thread has been created, and
|
||||
the application has no way of knowning that these threads are present.
|
||||
|
||||
+@node Restartable Sequences
|
||||
+@subsubsection Restartable Sequences
|
||||
+
|
||||
+This section describes restartable sequences integration for
|
||||
+@theglibc{}. This functionality is only available on Linux.
|
||||
+
|
||||
+@deftp {Data Type} {struct rseq}
|
||||
+@standards{Linux, sys/rseq.h}
|
||||
+The type of the restartable sequences area. Future versions
|
||||
+of Linux may add additional fields to the end of this structure.
|
||||
+
|
||||
+
|
||||
+Users need to obtain the address of the restartable sequences area using
|
||||
+the thread pointer and the @code{__rseq_offset} variable, described
|
||||
+below.
|
||||
+
|
||||
+One use of the restartable sequences area is to read the current CPU
|
||||
+number from its @code{cpu_id} field, as an inline version of
|
||||
+@code{sched_getcpu}. @Theglibc{} sets the @code{cpu_id} field to
|
||||
+@code{RSEQ_CPU_ID_REGISTRATION_FAILED} if registration failed or was
|
||||
+explicitly disabled.
|
||||
+
|
||||
+Furthermore, users can store the address of a @code{struct rseq_cs}
|
||||
+object into the @code{rseq_cs} field of @code{struct rseq}, thus
|
||||
+informing the kernel that the thread enters a restartable sequence
|
||||
+critical section. This pointer and the code areas it itself points to
|
||||
+must not be left pointing to memory areas which are freed or re-used.
|
||||
+Several approaches can guarantee this. If the application or library
|
||||
+can guarantee that the memory used to hold the @code{struct rseq_cs} and
|
||||
+the code areas it refers to are never freed or re-used, no special
|
||||
+action must be taken. Else, before that memory is re-used of freed, the
|
||||
+application is responsible for setting the @code{rseq_cs} field to
|
||||
+@code{NULL} in each thread's restartable sequence area to guarantee that
|
||||
+it does not leak dangling references. Because the application does not
|
||||
+typically have knowledge of libraries' use of restartable sequences, it
|
||||
+is recommended that libraries using restartable sequences which may end
|
||||
+up freeing or re-using their memory set the @code{rseq_cs} field to
|
||||
+@code{NULL} before returning from library functions which use
|
||||
+restartable sequences.
|
||||
+
|
||||
+The manual for the @code{rseq} system call can be found
|
||||
+at @uref{https://git.kernel.org/pub/scm/libs/librseq/librseq.git/tree/doc/man/rseq.2}.
|
||||
+@end deftp
|
||||
+
|
||||
+@deftypevar {int} __rseq_offset
|
||||
+@standards{Linux, sys/rseq.h}
|
||||
+This variable contains the offset between the thread pointer (as defined
|
||||
+by @code{__builtin_thread_pointer} or the thread pointer register for
|
||||
+the architecture) and the restartable sequences area. This value is the
|
||||
+same for all threads in the process. If the restartable sequences area
|
||||
+is located at a lower address than the location to which the thread
|
||||
+pointer points, the value is negative.
|
||||
+@end deftypevar
|
||||
+
|
||||
+@deftypevar {unsigned int} __rseq_size
|
||||
+@standards{Linux, sys/rseq.h}
|
||||
+This variable is either zero (if restartable sequence registration
|
||||
+failed or has been disabled) or the size of the restartable sequence
|
||||
+registration. This can be different from the size of @code{struct rseq}
|
||||
+if the kernel has extended the size of the registration. If
|
||||
+registration is successful, @code{__rseq_size} is at least 32 (the
|
||||
+initial size of @code{struct rseq}).
|
||||
+@end deftypevar
|
||||
+
|
||||
+@deftypevar {unsigned int} __rseq_flags
|
||||
+@standards{Linux, sys/rseq.h}
|
||||
+The flags used during restartable sequence registration with the kernel.
|
||||
+Currently zero.
|
||||
+@end deftypevar
|
||||
+
|
||||
+@deftypevr Macro int RSEQ_SIG
|
||||
+@standards{Linux, sys/rseq.h}
|
||||
+Each supported architecture provides a @code{RSEQ_SIG} macro in
|
||||
+@file{sys/rseq.h} which contains a signature. That signature is
|
||||
+expected to be present in the code before each restartable sequences
|
||||
+abort handler. Failure to provide the expected signature may terminate
|
||||
+the process with a segmentation fault.
|
||||
+@end deftypevr
|
||||
+
|
||||
@c FIXME these are undocumented:
|
||||
@c pthread_atfork
|
||||
@c pthread_attr_destroy
|
||||
diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c
|
||||
index 23aa4cfc0b784dfc..0f5280a75d546d2f 100644
|
||||
--- a/sysdeps/nptl/dl-tls_init_tp.c
|
||||
+++ b/sysdeps/nptl/dl-tls_init_tp.c
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <pthreadP.h>
|
||||
#include <tls.h>
|
||||
#include <rseq-internal.h>
|
||||
+#include <thread_pointer.h>
|
||||
|
||||
#define TUNABLE_NAMESPACE pthread
|
||||
#include <dl-tunables.h>
|
||||
@@ -43,6 +44,10 @@ rtld_mutex_dummy (pthread_mutex_t *lock)
|
||||
}
|
||||
#endif
|
||||
|
||||
+const unsigned int __rseq_flags;
|
||||
+const unsigned int __rseq_size attribute_relro;
|
||||
+const int __rseq_offset attribute_relro;
|
||||
+
|
||||
void
|
||||
__tls_pre_init_tp (void)
|
||||
{
|
||||
@@ -100,7 +105,23 @@ __tls_init_tp (void)
|
||||
#if HAVE_TUNABLES
|
||||
do_rseq = TUNABLE_GET (rseq, int, NULL);
|
||||
#endif
|
||||
- rseq_register_current_thread (pd, do_rseq);
|
||||
+ if (rseq_register_current_thread (pd, do_rseq))
|
||||
+ {
|
||||
+ /* We need a writable view of the variables. They are in
|
||||
+ .data.relro and are not yet write-protected. */
|
||||
+ extern unsigned int size __asm__ ("__rseq_size");
|
||||
+ size = sizeof (pd->rseq_area);
|
||||
+ }
|
||||
+
|
||||
+#ifdef RSEQ_SIG
|
||||
+ /* This should be a compile-time constant, but the current
|
||||
+ infrastructure makes it difficult to determine its value. Not
|
||||
+ all targets support __thread_pointer, so set __rseq_offset only
|
||||
+ if thre rseq registration may have happened because RSEQ_SIG is
|
||||
+ defined. */
|
||||
+ extern int offset __asm__ ("__rseq_offset");
|
||||
+ offset = (char *) &pd->rseq_area - (char *) __thread_pointer ();
|
||||
+#endif
|
||||
}
|
||||
|
||||
/* Set initial thread's stack block from 0 up to __libc_stack_end.
|
||||
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
|
||||
index 5c772f69d1b1f1f1..9b7e214219943531 100644
|
||||
--- a/sysdeps/unix/sysv/linux/Makefile
|
||||
+++ b/sysdeps/unix/sysv/linux/Makefile
|
||||
@@ -110,7 +110,8 @@ sysdep_headers += sys/mount.h sys/acct.h \
|
||||
bits/types/struct_semid64_ds_helper.h \
|
||||
bits/types/struct_shmid64_ds.h \
|
||||
bits/types/struct_shmid64_ds_helper.h \
|
||||
- bits/pthread_stack_min.h bits/pthread_stack_min-dynamic.h
|
||||
+ bits/pthread_stack_min.h bits/pthread_stack_min-dynamic.h \
|
||||
+ sys/rseq.h bits/rseq.h
|
||||
|
||||
tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
|
||||
tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \
|
||||
diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
|
||||
index 26452f3f17b5421d..3f8809a1581f27d0 100644
|
||||
--- a/sysdeps/unix/sysv/linux/Versions
|
||||
+++ b/sysdeps/unix/sysv/linux/Versions
|
||||
@@ -316,6 +316,11 @@ librt {
|
||||
}
|
||||
|
||||
ld {
|
||||
+ GLIBC_2.35 {
|
||||
+ __rseq_flags;
|
||||
+ __rseq_offset;
|
||||
+ __rseq_size;
|
||||
+ }
|
||||
GLIBC_PRIVATE {
|
||||
__nptl_change_stack_perm;
|
||||
}
|
||||
diff --git a/sysdeps/unix/sysv/linux/aarch64/ld.abilist b/sysdeps/unix/sysv/linux/aarch64/ld.abilist
|
||||
index b7196a80e2df8efc..bf4d4f9b6f2ddf97 100644
|
||||
--- a/sysdeps/unix/sysv/linux/aarch64/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/aarch64/ld.abilist
|
||||
@@ -4,3 +4,6 @@ GLIBC_2.17 __tls_get_addr F
|
||||
GLIBC_2.17 _dl_mcount F
|
||||
GLIBC_2.17 _r_debug D 0x28
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
+GLIBC_2.35 __rseq_flags D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_size D 0x4
|
||||
diff --git a/sysdeps/unix/sysv/linux/alpha/ld.abilist b/sysdeps/unix/sysv/linux/alpha/ld.abilist
|
||||
index 13f7fc74af62941d..a23325a566419b41 100644
|
||||
--- a/sysdeps/unix/sysv/linux/alpha/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/alpha/ld.abilist
|
||||
@@ -3,4 +3,7 @@ GLIBC_2.1 __libc_stack_end D 0x8
|
||||
GLIBC_2.1 _dl_mcount F
|
||||
GLIBC_2.3 __tls_get_addr F
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
+GLIBC_2.35 __rseq_flags D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_size D 0x4
|
||||
GLIBC_2.4 __stack_chk_guard D 0x8
|
||||
diff --git a/sysdeps/unix/sysv/linux/arc/ld.abilist b/sysdeps/unix/sysv/linux/arc/ld.abilist
|
||||
index 7284383a6bea8e64..55f0c2ab9c6f7d91 100644
|
||||
--- a/sysdeps/unix/sysv/linux/arc/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/arc/ld.abilist
|
||||
@@ -4,3 +4,6 @@ GLIBC_2.32 __tls_get_addr F
|
||||
GLIBC_2.32 _dl_mcount F
|
||||
GLIBC_2.32 _r_debug D 0x14
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
+GLIBC_2.35 __rseq_flags D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_size D 0x4
|
||||
diff --git a/sysdeps/unix/sysv/linux/arm/be/ld.abilist b/sysdeps/unix/sysv/linux/arm/be/ld.abilist
|
||||
index 7987bbae1112aa3d..f1da2c636ddb359d 100644
|
||||
--- a/sysdeps/unix/sysv/linux/arm/be/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/arm/be/ld.abilist
|
||||
@@ -1,4 +1,7 @@
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
+GLIBC_2.35 __rseq_flags D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_size D 0x4
|
||||
GLIBC_2.4 __libc_stack_end D 0x4
|
||||
GLIBC_2.4 __stack_chk_guard D 0x4
|
||||
GLIBC_2.4 __tls_get_addr F
|
||||
diff --git a/sysdeps/unix/sysv/linux/arm/le/ld.abilist b/sysdeps/unix/sysv/linux/arm/le/ld.abilist
|
||||
index 7987bbae1112aa3d..f1da2c636ddb359d 100644
|
||||
--- a/sysdeps/unix/sysv/linux/arm/le/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/arm/le/ld.abilist
|
||||
@@ -1,4 +1,7 @@
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
+GLIBC_2.35 __rseq_flags D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_size D 0x4
|
||||
GLIBC_2.4 __libc_stack_end D 0x4
|
||||
GLIBC_2.4 __stack_chk_guard D 0x4
|
||||
GLIBC_2.4 __tls_get_addr F
|
||||
diff --git a/sysdeps/unix/sysv/linux/csky/ld.abilist b/sysdeps/unix/sysv/linux/csky/ld.abilist
|
||||
index 4939b20631dc6c54..7f482276ed8df1d5 100644
|
||||
--- a/sysdeps/unix/sysv/linux/csky/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/csky/ld.abilist
|
||||
@@ -4,3 +4,6 @@ GLIBC_2.29 __tls_get_addr F
|
||||
GLIBC_2.29 _dl_mcount F
|
||||
GLIBC_2.29 _r_debug D 0x14
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
+GLIBC_2.35 __rseq_flags D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_size D 0x4
|
||||
diff --git a/sysdeps/unix/sysv/linux/hppa/ld.abilist b/sysdeps/unix/sysv/linux/hppa/ld.abilist
|
||||
index 7cc9ebd792c2aadc..7f5527fb301b913c 100644
|
||||
--- a/sysdeps/unix/sysv/linux/hppa/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/hppa/ld.abilist
|
||||
@@ -3,4 +3,7 @@ GLIBC_2.2 _dl_mcount F
|
||||
GLIBC_2.2 _r_debug D 0x14
|
||||
GLIBC_2.3 __tls_get_addr F
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
+GLIBC_2.35 __rseq_flags D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_size D 0x4
|
||||
GLIBC_2.4 __stack_chk_guard D 0x4
|
||||
diff --git a/sysdeps/unix/sysv/linux/i386/ld.abilist b/sysdeps/unix/sysv/linux/i386/ld.abilist
|
||||
index e8d187b14d722a64..9c4a45d8dc525e52 100644
|
||||
--- a/sysdeps/unix/sysv/linux/i386/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/i386/ld.abilist
|
||||
@@ -4,3 +4,6 @@ GLIBC_2.1 _dl_mcount F
|
||||
GLIBC_2.3 ___tls_get_addr F
|
||||
GLIBC_2.3 __tls_get_addr F
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
+GLIBC_2.35 __rseq_flags D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_size D 0x4
|
||||
diff --git a/sysdeps/unix/sysv/linux/ia64/ld.abilist b/sysdeps/unix/sysv/linux/ia64/ld.abilist
|
||||
index be5122650ae2b327..8ccb5be911e0e9a2 100644
|
||||
--- a/sysdeps/unix/sysv/linux/ia64/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/ia64/ld.abilist
|
||||
@@ -3,3 +3,6 @@ GLIBC_2.2 _dl_mcount F
|
||||
GLIBC_2.2 _r_debug D 0x28
|
||||
GLIBC_2.3 __tls_get_addr F
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
+GLIBC_2.35 __rseq_flags D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_size D 0x4
|
||||
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/ld.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/ld.abilist
|
||||
index 7987bbae1112aa3d..f1da2c636ddb359d 100644
|
||||
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/ld.abilist
|
||||
@@ -1,4 +1,7 @@
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
+GLIBC_2.35 __rseq_flags D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_size D 0x4
|
||||
GLIBC_2.4 __libc_stack_end D 0x4
|
||||
GLIBC_2.4 __stack_chk_guard D 0x4
|
||||
GLIBC_2.4 __tls_get_addr F
|
||||
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/ld.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/ld.abilist
|
||||
index 4f2854edf7746958..dadbf852d0522e77 100644
|
||||
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/ld.abilist
|
||||
@@ -3,4 +3,7 @@ GLIBC_2.1 __libc_stack_end D 0x4
|
||||
GLIBC_2.1 _dl_mcount F
|
||||
GLIBC_2.3 __tls_get_addr F
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
+GLIBC_2.35 __rseq_flags D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_size D 0x4
|
||||
GLIBC_2.4 __stack_chk_guard D 0x4
|
||||
diff --git a/sysdeps/unix/sysv/linux/microblaze/ld.abilist b/sysdeps/unix/sysv/linux/microblaze/ld.abilist
|
||||
index 9f0fdeca38890a34..89a0b7e4fd5a95fa 100644
|
||||
--- a/sysdeps/unix/sysv/linux/microblaze/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/microblaze/ld.abilist
|
||||
@@ -4,3 +4,6 @@ GLIBC_2.18 __tls_get_addr F
|
||||
GLIBC_2.18 _dl_mcount F
|
||||
GLIBC_2.18 _r_debug D 0x14
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
+GLIBC_2.35 __rseq_flags D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_size D 0x4
|
||||
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/ld.abilist b/sysdeps/unix/sysv/linux/mips/mips32/ld.abilist
|
||||
index f750067d5c34bf42..e304d1bb464b28f4 100644
|
||||
--- a/sysdeps/unix/sysv/linux/mips/mips32/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/mips/mips32/ld.abilist
|
||||
@@ -3,4 +3,7 @@ GLIBC_2.2 __libc_stack_end D 0x4
|
||||
GLIBC_2.2 _dl_mcount F
|
||||
GLIBC_2.3 __tls_get_addr F
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
+GLIBC_2.35 __rseq_flags D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_size D 0x4
|
||||
GLIBC_2.4 __stack_chk_guard D 0x4
|
||||
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/ld.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/ld.abilist
|
||||
index f750067d5c34bf42..e304d1bb464b28f4 100644
|
||||
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/ld.abilist
|
||||
@@ -3,4 +3,7 @@ GLIBC_2.2 __libc_stack_end D 0x4
|
||||
GLIBC_2.2 _dl_mcount F
|
||||
GLIBC_2.3 __tls_get_addr F
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
+GLIBC_2.35 __rseq_flags D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_size D 0x4
|
||||
GLIBC_2.4 __stack_chk_guard D 0x4
|
||||
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist
|
||||
index 2fba6a9b6ec92e47..37a47ebc0a0d16c8 100644
|
||||
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist
|
||||
@@ -3,4 +3,7 @@ GLIBC_2.2 __libc_stack_end D 0x8
|
||||
GLIBC_2.2 _dl_mcount F
|
||||
GLIBC_2.3 __tls_get_addr F
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
+GLIBC_2.35 __rseq_flags D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_size D 0x4
|
||||
GLIBC_2.4 __stack_chk_guard D 0x8
|
||||
diff --git a/sysdeps/unix/sysv/linux/nios2/ld.abilist b/sysdeps/unix/sysv/linux/nios2/ld.abilist
|
||||
index 57dfad5a53b739e8..811ae9da2fa85399 100644
|
||||
--- a/sysdeps/unix/sysv/linux/nios2/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/nios2/ld.abilist
|
||||
@@ -4,3 +4,6 @@ GLIBC_2.21 __tls_get_addr F
|
||||
GLIBC_2.21 _dl_mcount F
|
||||
GLIBC_2.21 _r_debug D 0x14
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
+GLIBC_2.35 __rseq_flags D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_size D 0x4
|
||||
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/ld.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/ld.abilist
|
||||
index e89660739262c6ab..5a68aeb9eed33844 100644
|
||||
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/ld.abilist
|
||||
@@ -5,3 +5,6 @@ GLIBC_2.22 __tls_get_addr_opt F
|
||||
GLIBC_2.23 __parse_hwcap_and_convert_at_platform F
|
||||
GLIBC_2.3 __tls_get_addr F
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
+GLIBC_2.35 __rseq_flags D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_size D 0x4
|
||||
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist
|
||||
index ce0bc639597c4bd9..da24dc7fb52ad2d4 100644
|
||||
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist
|
||||
@@ -5,3 +5,6 @@ GLIBC_2.3 __tls_get_addr F
|
||||
GLIBC_2.3 _dl_mcount F
|
||||
GLIBC_2.3 _r_debug D 0x28
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
+GLIBC_2.35 __rseq_flags D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_size D 0x4
|
||||
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist
|
||||
index 65b22674d2462e96..b9ae89ae8d90ed9e 100644
|
||||
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist
|
||||
@@ -5,3 +5,6 @@ GLIBC_2.17 _r_debug D 0x28
|
||||
GLIBC_2.22 __tls_get_addr_opt F
|
||||
GLIBC_2.23 __parse_hwcap_and_convert_at_platform F
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
+GLIBC_2.35 __rseq_flags D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_size D 0x4
|
||||
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist
|
||||
index 5ad4c81d12d7a612..068368878eb2406e 100644
|
||||
--- a/sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist
|
||||
@@ -4,3 +4,6 @@ GLIBC_2.33 __tls_get_addr F
|
||||
GLIBC_2.33 _dl_mcount F
|
||||
GLIBC_2.33 _r_debug D 0x14
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
+GLIBC_2.35 __rseq_flags D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_size D 0x4
|
||||
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist
|
||||
index 479efdea9bb654bb..48431c91a9fd16b0 100644
|
||||
--- a/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist
|
||||
@@ -4,3 +4,6 @@ GLIBC_2.27 __tls_get_addr F
|
||||
GLIBC_2.27 _dl_mcount F
|
||||
GLIBC_2.27 _r_debug D 0x28
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
+GLIBC_2.35 __rseq_flags D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_size D 0x4
|
||||
diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h
|
||||
index 6a3441f2cc49e7c4..9e8f99fd51a063b1 100644
|
||||
--- a/sysdeps/unix/sysv/linux/rseq-internal.h
|
||||
+++ b/sysdeps/unix/sysv/linux/rseq-internal.h
|
||||
@@ -41,7 +41,7 @@ rseq_register_current_thread (struct pthread *self, bool do_rseq)
|
||||
return false;
|
||||
}
|
||||
#else /* RSEQ_SIG */
|
||||
-static inline void
|
||||
+static inline bool
|
||||
rseq_register_current_thread (struct pthread *self, bool do_rseq)
|
||||
{
|
||||
THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED);
|
||||
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/ld.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/ld.abilist
|
||||
index d5ecb636bb792bdf..c15288394a232a8c 100644
|
||||
--- a/sysdeps/unix/sysv/linux/s390/s390-32/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/ld.abilist
|
||||
@@ -3,3 +3,6 @@ GLIBC_2.1 __libc_stack_end D 0x4
|
||||
GLIBC_2.1 _dl_mcount F
|
||||
GLIBC_2.3 __tls_get_offset F
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
+GLIBC_2.35 __rseq_flags D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_size D 0x4
|
||||
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist
|
||||
index 62a5e1d99a2e6f42..117d1430a4c6272e 100644
|
||||
--- a/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist
|
||||
@@ -3,3 +3,6 @@ GLIBC_2.2 _dl_mcount F
|
||||
GLIBC_2.2 _r_debug D 0x28
|
||||
GLIBC_2.3 __tls_get_offset F
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
+GLIBC_2.35 __rseq_flags D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_size D 0x4
|
||||
diff --git a/sysdeps/unix/sysv/linux/sh/be/ld.abilist b/sysdeps/unix/sysv/linux/sh/be/ld.abilist
|
||||
index 7cc9ebd792c2aadc..7f5527fb301b913c 100644
|
||||
--- a/sysdeps/unix/sysv/linux/sh/be/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/sh/be/ld.abilist
|
||||
@@ -3,4 +3,7 @@ GLIBC_2.2 _dl_mcount F
|
||||
GLIBC_2.2 _r_debug D 0x14
|
||||
GLIBC_2.3 __tls_get_addr F
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
+GLIBC_2.35 __rseq_flags D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_size D 0x4
|
||||
GLIBC_2.4 __stack_chk_guard D 0x4
|
||||
diff --git a/sysdeps/unix/sysv/linux/sh/le/ld.abilist b/sysdeps/unix/sysv/linux/sh/le/ld.abilist
|
||||
index 7cc9ebd792c2aadc..7f5527fb301b913c 100644
|
||||
--- a/sysdeps/unix/sysv/linux/sh/le/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/sh/le/ld.abilist
|
||||
@@ -3,4 +3,7 @@ GLIBC_2.2 _dl_mcount F
|
||||
GLIBC_2.2 _r_debug D 0x14
|
||||
GLIBC_2.3 __tls_get_addr F
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
+GLIBC_2.35 __rseq_flags D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_size D 0x4
|
||||
GLIBC_2.4 __stack_chk_guard D 0x4
|
||||
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/ld.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/ld.abilist
|
||||
index 2e6054349871e7d5..3aac73f3df646cb6 100644
|
||||
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/ld.abilist
|
||||
@@ -3,3 +3,6 @@ GLIBC_2.1 __libc_stack_end D 0x4
|
||||
GLIBC_2.1 _dl_mcount F
|
||||
GLIBC_2.3 __tls_get_addr F
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
+GLIBC_2.35 __rseq_flags D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_size D 0x4
|
||||
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist
|
||||
index be5122650ae2b327..8ccb5be911e0e9a2 100644
|
||||
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist
|
||||
@@ -3,3 +3,6 @@ GLIBC_2.2 _dl_mcount F
|
||||
GLIBC_2.2 _r_debug D 0x28
|
||||
GLIBC_2.3 __tls_get_addr F
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
+GLIBC_2.35 __rseq_flags D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_size D 0x4
|
||||
diff --git a/sysdeps/unix/sysv/linux/sys/rseq.h b/sysdeps/unix/sysv/linux/sys/rseq.h
|
||||
index c8edff50d40e29b6..1215b5d086b8852b 100644
|
||||
--- a/sysdeps/unix/sysv/linux/sys/rseq.h
|
||||
+++ b/sysdeps/unix/sysv/linux/sys/rseq.h
|
||||
@@ -171,4 +171,14 @@ struct rseq
|
||||
|
||||
#endif /* __GLIBC_HAVE_KERNEL_RSEQ */
|
||||
|
||||
+/* Offset from the thread pointer to the rseq area. */
|
||||
+extern const int __rseq_offset;
|
||||
+
|
||||
+/* Size of the registered rseq area. 0 if the registration was
|
||||
+ unsuccessful. */
|
||||
+extern const unsigned int __rseq_size;
|
||||
+
|
||||
+/* Flags used during rseq registration. */
|
||||
+extern const unsigned int __rseq_flags;
|
||||
+
|
||||
#endif /* sys/rseq.h */
|
||||
diff --git a/sysdeps/unix/sysv/linux/tst-rseq-disable.c b/sysdeps/unix/sysv/linux/tst-rseq-disable.c
|
||||
index 000e351872fc2f76..6d73f77e9621da42 100644
|
||||
--- a/sysdeps/unix/sysv/linux/tst-rseq-disable.c
|
||||
+++ b/sysdeps/unix/sysv/linux/tst-rseq-disable.c
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <support/namespace.h>
|
||||
#include <support/xthread.h>
|
||||
#include <sysdep.h>
|
||||
+#include <thread_pointer.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef RSEQ_SIG
|
||||
@@ -30,6 +31,11 @@ static void
|
||||
check_rseq_disabled (void)
|
||||
{
|
||||
struct pthread *pd = THREAD_SELF;
|
||||
+
|
||||
+ TEST_COMPARE (__rseq_flags, 0);
|
||||
+ TEST_VERIFY ((char *) __thread_pointer () + __rseq_offset
|
||||
+ == (char *) &pd->rseq_area);
|
||||
+ TEST_COMPARE (__rseq_size, 0);
|
||||
TEST_COMPARE ((int) pd->rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED);
|
||||
|
||||
int ret = syscall (__NR_rseq, &pd->rseq_area, sizeof (pd->rseq_area),
|
||||
diff --git a/sysdeps/unix/sysv/linux/tst-rseq.c b/sysdeps/unix/sysv/linux/tst-rseq.c
|
||||
index 926376b6a5446ece..572c11166f8b6533 100644
|
||||
--- a/sysdeps/unix/sysv/linux/tst-rseq.c
|
||||
+++ b/sysdeps/unix/sysv/linux/tst-rseq.c
|
||||
@@ -29,12 +29,20 @@
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <syscall.h>
|
||||
+# include <thread_pointer.h>
|
||||
+# include <tls.h>
|
||||
# include "tst-rseq.h"
|
||||
|
||||
static void
|
||||
do_rseq_main_test (void)
|
||||
{
|
||||
+ struct pthread *pd = THREAD_SELF;
|
||||
+
|
||||
TEST_VERIFY_EXIT (rseq_thread_registered ());
|
||||
+ TEST_COMPARE (__rseq_flags, 0);
|
||||
+ TEST_VERIFY ((char *) __thread_pointer () + __rseq_offset
|
||||
+ == (char *) &pd->rseq_area);
|
||||
+ TEST_COMPARE (__rseq_size, sizeof (pd->rseq_area));
|
||||
}
|
||||
|
||||
static void
|
||||
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist b/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist
|
||||
index afddaec57c11f837..ae622bdf9710bdbd 100644
|
||||
--- a/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist
|
||||
@@ -3,3 +3,6 @@ GLIBC_2.2.5 _dl_mcount F
|
||||
GLIBC_2.2.5 _r_debug D 0x28
|
||||
GLIBC_2.3 __tls_get_addr F
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
+GLIBC_2.35 __rseq_flags D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_size D 0x4
|
||||
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist
|
||||
index defc488d137c61c3..e17496d124b0c7b7 100644
|
||||
--- a/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist
|
||||
@@ -3,3 +3,6 @@ GLIBC_2.16 __tls_get_addr F
|
||||
GLIBC_2.16 _dl_mcount F
|
||||
GLIBC_2.16 _r_debug D 0x14
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
+GLIBC_2.35 __rseq_flags D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_size D 0x4
|
@ -0,0 +1,180 @@
|
||||
commit 6c33b018438ee799c29486f21d43d8100bdbd597
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Wed Feb 2 22:37:20 2022 +0100
|
||||
|
||||
Linux: Use ptrdiff_t for __rseq_offset
|
||||
|
||||
This matches the data size initial-exec relocations use on most
|
||||
targets.
|
||||
|
||||
Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/manual/threads.texi b/manual/threads.texi
|
||||
index 4869f69d2ceed255..48fd562923800b34 100644
|
||||
--- a/manual/threads.texi
|
||||
+++ b/manual/threads.texi
|
||||
@@ -1004,7 +1004,7 @@ The manual for the @code{rseq} system call can be found
|
||||
at @uref{https://git.kernel.org/pub/scm/libs/librseq/librseq.git/tree/doc/man/rseq.2}.
|
||||
@end deftp
|
||||
|
||||
-@deftypevar {int} __rseq_offset
|
||||
+@deftypevar {ptrdiff_t} __rseq_offset
|
||||
@standards{Linux, sys/rseq.h}
|
||||
This variable contains the offset between the thread pointer (as defined
|
||||
by @code{__builtin_thread_pointer} or the thread pointer register for
|
||||
diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c
|
||||
index 0f5280a75d546d2f..d5f2587f1348441c 100644
|
||||
--- a/sysdeps/nptl/dl-tls_init_tp.c
|
||||
+++ b/sysdeps/nptl/dl-tls_init_tp.c
|
||||
@@ -46,7 +46,7 @@ rtld_mutex_dummy (pthread_mutex_t *lock)
|
||||
|
||||
const unsigned int __rseq_flags;
|
||||
const unsigned int __rseq_size attribute_relro;
|
||||
-const int __rseq_offset attribute_relro;
|
||||
+const ptrdiff_t __rseq_offset attribute_relro;
|
||||
|
||||
void
|
||||
__tls_pre_init_tp (void)
|
||||
@@ -119,7 +119,7 @@ __tls_init_tp (void)
|
||||
all targets support __thread_pointer, so set __rseq_offset only
|
||||
if thre rseq registration may have happened because RSEQ_SIG is
|
||||
defined. */
|
||||
- extern int offset __asm__ ("__rseq_offset");
|
||||
+ extern ptrdiff_t offset __asm__ ("__rseq_offset");
|
||||
offset = (char *) &pd->rseq_area - (char *) __thread_pointer ();
|
||||
#endif
|
||||
}
|
||||
diff --git a/sysdeps/unix/sysv/linux/aarch64/ld.abilist b/sysdeps/unix/sysv/linux/aarch64/ld.abilist
|
||||
index bf4d4f9b6f2ddf97..5151c0781de01bf1 100644
|
||||
--- a/sysdeps/unix/sysv/linux/aarch64/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/aarch64/ld.abilist
|
||||
@@ -5,5 +5,5 @@ GLIBC_2.17 _dl_mcount F
|
||||
GLIBC_2.17 _r_debug D 0x28
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
GLIBC_2.35 __rseq_flags D 0x4
|
||||
-GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x8
|
||||
GLIBC_2.35 __rseq_size D 0x4
|
||||
diff --git a/sysdeps/unix/sysv/linux/alpha/ld.abilist b/sysdeps/unix/sysv/linux/alpha/ld.abilist
|
||||
index a23325a566419b41..3e296c547314f6c2 100644
|
||||
--- a/sysdeps/unix/sysv/linux/alpha/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/alpha/ld.abilist
|
||||
@@ -4,6 +4,6 @@ GLIBC_2.1 _dl_mcount F
|
||||
GLIBC_2.3 __tls_get_addr F
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
GLIBC_2.35 __rseq_flags D 0x4
|
||||
-GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x8
|
||||
GLIBC_2.35 __rseq_size D 0x4
|
||||
GLIBC_2.4 __stack_chk_guard D 0x8
|
||||
diff --git a/sysdeps/unix/sysv/linux/ia64/ld.abilist b/sysdeps/unix/sysv/linux/ia64/ld.abilist
|
||||
index 8ccb5be911e0e9a2..5471b24d59a7527a 100644
|
||||
--- a/sysdeps/unix/sysv/linux/ia64/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/ia64/ld.abilist
|
||||
@@ -4,5 +4,5 @@ GLIBC_2.2 _r_debug D 0x28
|
||||
GLIBC_2.3 __tls_get_addr F
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
GLIBC_2.35 __rseq_flags D 0x4
|
||||
-GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x8
|
||||
GLIBC_2.35 __rseq_size D 0x4
|
||||
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist
|
||||
index 37a47ebc0a0d16c8..f26e594a139f0058 100644
|
||||
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist
|
||||
@@ -4,6 +4,6 @@ GLIBC_2.2 _dl_mcount F
|
||||
GLIBC_2.3 __tls_get_addr F
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
GLIBC_2.35 __rseq_flags D 0x4
|
||||
-GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x8
|
||||
GLIBC_2.35 __rseq_size D 0x4
|
||||
GLIBC_2.4 __stack_chk_guard D 0x8
|
||||
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist
|
||||
index da24dc7fb52ad2d4..21f472e674299ab7 100644
|
||||
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist
|
||||
@@ -6,5 +6,5 @@ GLIBC_2.3 _dl_mcount F
|
||||
GLIBC_2.3 _r_debug D 0x28
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
GLIBC_2.35 __rseq_flags D 0x4
|
||||
-GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x8
|
||||
GLIBC_2.35 __rseq_size D 0x4
|
||||
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist
|
||||
index b9ae89ae8d90ed9e..9c9c40450d651880 100644
|
||||
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist
|
||||
@@ -6,5 +6,5 @@ GLIBC_2.22 __tls_get_addr_opt F
|
||||
GLIBC_2.23 __parse_hwcap_and_convert_at_platform F
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
GLIBC_2.35 __rseq_flags D 0x4
|
||||
-GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x8
|
||||
GLIBC_2.35 __rseq_size D 0x4
|
||||
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist
|
||||
index 48431c91a9fd16b0..a7758a0e52fc8cc8 100644
|
||||
--- a/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist
|
||||
@@ -5,5 +5,5 @@ GLIBC_2.27 _dl_mcount F
|
||||
GLIBC_2.27 _r_debug D 0x28
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
GLIBC_2.35 __rseq_flags D 0x4
|
||||
-GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x8
|
||||
GLIBC_2.35 __rseq_size D 0x4
|
||||
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist
|
||||
index 117d1430a4c6272e..78d071600b1f3431 100644
|
||||
--- a/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist
|
||||
@@ -4,5 +4,5 @@ GLIBC_2.2 _r_debug D 0x28
|
||||
GLIBC_2.3 __tls_get_offset F
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
GLIBC_2.35 __rseq_flags D 0x4
|
||||
-GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x8
|
||||
GLIBC_2.35 __rseq_size D 0x4
|
||||
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist
|
||||
index 8ccb5be911e0e9a2..5471b24d59a7527a 100644
|
||||
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist
|
||||
@@ -4,5 +4,5 @@ GLIBC_2.2 _r_debug D 0x28
|
||||
GLIBC_2.3 __tls_get_addr F
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
GLIBC_2.35 __rseq_flags D 0x4
|
||||
-GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x8
|
||||
GLIBC_2.35 __rseq_size D 0x4
|
||||
diff --git a/sysdeps/unix/sysv/linux/sys/rseq.h b/sysdeps/unix/sysv/linux/sys/rseq.h
|
||||
index 1215b5d086b8852b..791ed83176b61fe4 100644
|
||||
--- a/sysdeps/unix/sysv/linux/sys/rseq.h
|
||||
+++ b/sysdeps/unix/sysv/linux/sys/rseq.h
|
||||
@@ -21,6 +21,7 @@
|
||||
/* Architecture-specific rseq signature. */
|
||||
#include <bits/rseq.h>
|
||||
|
||||
+#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <bits/endian.h>
|
||||
@@ -172,7 +173,7 @@ struct rseq
|
||||
#endif /* __GLIBC_HAVE_KERNEL_RSEQ */
|
||||
|
||||
/* Offset from the thread pointer to the rseq area. */
|
||||
-extern const int __rseq_offset;
|
||||
+extern const ptrdiff_t __rseq_offset;
|
||||
|
||||
/* Size of the registered rseq area. 0 if the registration was
|
||||
unsuccessful. */
|
||||
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist b/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist
|
||||
index ae622bdf9710bdbd..5a8bd322cdc95d5b 100644
|
||||
--- a/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist
|
||||
+++ b/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist
|
||||
@@ -4,5 +4,5 @@ GLIBC_2.2.5 _r_debug D 0x28
|
||||
GLIBC_2.3 __tls_get_addr F
|
||||
GLIBC_2.34 __rtld_version_placeholder F
|
||||
GLIBC_2.35 __rseq_flags D 0x4
|
||||
-GLIBC_2.35 __rseq_offset D 0x4
|
||||
+GLIBC_2.35 __rseq_offset D 0x8
|
||||
GLIBC_2.35 __rseq_size D 0x4
|
@ -0,0 +1,59 @@
|
||||
commit 4b527650e0d559a5f693275c598667e06cd6455c
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu Jun 2 16:29:55 2022 +0200
|
||||
|
||||
Linux: Adjust struct rseq definition to current kernel version
|
||||
|
||||
This definition is only used as a fallback with old kernel headers.
|
||||
The change follows kernel commit bfdf4e6208051ed7165b2e92035b4bf11
|
||||
("rseq: Remove broken uapi field layout on 32-bit little endian").
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/sys/rseq.h b/sysdeps/unix/sysv/linux/sys/rseq.h
|
||||
index 791ed83176b61fe4..56550329db962cc8 100644
|
||||
--- a/sysdeps/unix/sysv/linux/sys/rseq.h
|
||||
+++ b/sysdeps/unix/sysv/linux/sys/rseq.h
|
||||
@@ -24,7 +24,6 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/cdefs.h>
|
||||
-#include <bits/endian.h>
|
||||
|
||||
#ifdef __has_include
|
||||
# if __has_include ("linux/rseq.h")
|
||||
@@ -129,28 +128,13 @@ struct rseq
|
||||
targeted by the rseq_cs. Also needs to be set to NULL by user-space
|
||||
before reclaiming memory that contains the targeted struct rseq_cs.
|
||||
|
||||
- Read and set by the kernel. Set by user-space with single-copy
|
||||
- atomicity semantics. This field should only be updated by the
|
||||
- thread which registered this data structure. Aligned on 64-bit. */
|
||||
- union
|
||||
- {
|
||||
- uint64_t ptr64;
|
||||
-# ifdef __LP64__
|
||||
- uint64_t ptr;
|
||||
-# else /* __LP64__ */
|
||||
- struct
|
||||
- {
|
||||
-#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
- uint32_t padding; /* Initialized to zero. */
|
||||
- uint32_t ptr32;
|
||||
-# else /* LITTLE */
|
||||
- uint32_t ptr32;
|
||||
- uint32_t padding; /* Initialized to zero. */
|
||||
-# endif /* ENDIAN */
|
||||
- } ptr;
|
||||
-# endif /* __LP64__ */
|
||||
- } rseq_cs;
|
||||
+ Read and set by the kernel. Set by user-space with single-copy
|
||||
+ atomicity semantics. This field should only be updated by the
|
||||
+ thread which registered this data structure. Aligned on 64-bit.
|
||||
|
||||
+ 32-bit architectures should update the low order bits of the
|
||||
+ rseq_cs field, leaving the high order bits initialized to 0. */
|
||||
+ uint64_t rseq_cs;
|
||||
/* Restartable sequences flags field.
|
||||
|
||||
This field should only be updated by the thread which
|
@ -0,0 +1,38 @@
|
||||
Revert glibc-rh2024347-13.patch. Enable rseq by default.
|
||||
|
||||
diff --git a/manual/tunables.texi b/manual/tunables.texi
|
||||
index f559c44dcec4624b..28ff502990c2a10f 100644
|
||||
--- a/manual/tunables.texi
|
||||
+++ b/manual/tunables.texi
|
||||
@@ -425,13 +425,11 @@ The value is measured in bytes. The default is @samp{41943040}
|
||||
@end deftp
|
||||
|
||||
@deftp Tunable glibc.pthread.rseq
|
||||
-The @code{glibc.pthread.rseq} tunable can be set to @samp{1}, to enable
|
||||
-restartable sequences support. @Theglibc{} uses this to optimize the
|
||||
-@code{sched_getcpu} function.
|
||||
-
|
||||
-The default is @samp{0}, which means that applications can perform
|
||||
-restartable sequences registration, but @code{sched_getcpu} is not
|
||||
-accelerated.
|
||||
+The @code{glibc.pthread.rseq} tunable can be set to @samp{0}, to disable
|
||||
+restartable sequences support in @theglibc{}. This enables applications
|
||||
+to perform direct restartable sequence registration with the kernel.
|
||||
+The default is @samp{1}, which means that @theglibc{} performs
|
||||
+registration on behalf of the application.
|
||||
|
||||
Restartable sequences are a Linux-specific extension.
|
||||
@end deftp
|
||||
diff --git a/sysdeps/nptl/dl-tunables.list b/sysdeps/nptl/dl-tunables.list
|
||||
index df2a39ce01858d3b..d24f4be0d08ba407 100644
|
||||
--- a/sysdeps/nptl/dl-tunables.list
|
||||
+++ b/sysdeps/nptl/dl-tunables.list
|
||||
@@ -31,7 +31,7 @@ glibc {
|
||||
type: INT_32
|
||||
minval: 0
|
||||
maxval: 1
|
||||
- default: 0
|
||||
+ default: 1
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
commit 62a321b12d0e397af88fa422db65079332f971dc
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Jun 24 18:16:41 2022 +0200
|
||||
|
||||
support: Change non-address output format of support_format_dns_packet
|
||||
|
||||
It makes sense to include the owner name (LHS) and record type in the
|
||||
output, so that they can be checked for correctness.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/support/support_format_dns_packet.c b/support/support_format_dns_packet.c
|
||||
index 1f8e9ca172a06f4f..c3dff0e019801904 100644
|
||||
--- a/support/support_format_dns_packet.c
|
||||
+++ b/support/support_format_dns_packet.c
|
||||
@@ -101,6 +101,17 @@ extract_name (struct in_buffer full, struct in_buffer *in, struct dname *value)
|
||||
return true;
|
||||
}
|
||||
|
||||
+static void
|
||||
+extract_name_data (struct in_buffer full, struct in_buffer *rdata,
|
||||
+ const struct dname *owner, const char *typename, FILE *out)
|
||||
+{
|
||||
+ struct dname name;
|
||||
+ if (extract_name (full, rdata, &name))
|
||||
+ fprintf (out, "data: %s %s %s\n", owner->name, typename, name.name);
|
||||
+ else
|
||||
+ fprintf (out, "error: malformed CNAME/PTR record\n");
|
||||
+}
|
||||
+
|
||||
char *
|
||||
support_format_dns_packet (const unsigned char *buffer, size_t length)
|
||||
{
|
||||
@@ -206,14 +217,11 @@ support_format_dns_packet (const unsigned char *buffer, size_t length)
|
||||
}
|
||||
break;
|
||||
case T_CNAME:
|
||||
+ extract_name_data (full, &rdata, &rname, "CNAME", mem.out);
|
||||
+ break;
|
||||
case T_PTR:
|
||||
- {
|
||||
- struct dname name;
|
||||
- if (extract_name (full, &rdata, &name))
|
||||
- fprintf (mem.out, "name: %s\n", name.name);
|
||||
- else
|
||||
- fprintf (mem.out, "error: malformed CNAME/PTR record\n");
|
||||
- }
|
||||
+ extract_name_data (full, &rdata, &rname, "PTR", mem.out);
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/support/tst-support_format_dns_packet.c b/support/tst-support_format_dns_packet.c
|
||||
index 03ff59457e3bdde8..5596db1785009557 100644
|
||||
--- a/support/tst-support_format_dns_packet.c
|
||||
+++ b/support/tst-support_format_dns_packet.c
|
||||
@@ -85,8 +85,8 @@ test_multiple_cnames (void)
|
||||
"\xc0\x00\x02\x01";
|
||||
check_packet (packet, sizeof (packet) - 1, __func__,
|
||||
"name: www.example\n"
|
||||
- "name: www1.example\n"
|
||||
- "name: www2.example\n"
|
||||
+ "data: www.example CNAME www1.example\n"
|
||||
+ "data: www1.example CNAME www2.example\n"
|
||||
"address: 192.0.2.1\n");
|
||||
}
|
||||
|
@ -0,0 +1,941 @@
|
||||
commit f282cdbe7f436c75864e5640a409a10485e9abb2
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Jun 24 18:16:41 2022 +0200
|
||||
|
||||
resolv: Implement no-aaaa stub resolver option
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/resolv/Makefile b/resolv/Makefile
|
||||
index 59e599535c7aa6eb..e8269dcb5bcf216b 100644
|
||||
--- a/resolv/Makefile
|
||||
+++ b/resolv/Makefile
|
||||
@@ -51,6 +51,7 @@ routines := \
|
||||
nss_dns_functions \
|
||||
res-close \
|
||||
res-name-checking \
|
||||
+ res-noaaaa \
|
||||
res-state \
|
||||
res_context_hostalias \
|
||||
res_enable_icmp \
|
||||
@@ -93,6 +94,7 @@ tests += \
|
||||
tst-resolv-binary \
|
||||
tst-resolv-edns \
|
||||
tst-resolv-network \
|
||||
+ tst-resolv-noaaaa \
|
||||
tst-resolv-nondecimal \
|
||||
tst-resolv-res_init-multi \
|
||||
tst-resolv-search \
|
||||
@@ -256,6 +258,7 @@ $(objpfx)tst-resolv-res_init-multi: $(objpfx)libresolv.so \
|
||||
$(shared-thread-library)
|
||||
$(objpfx)tst-resolv-res_init-thread: $(objpfx)libresolv.so \
|
||||
$(shared-thread-library)
|
||||
+$(objpfx)tst-resolv-noaaaa: $(objpfx)libresolv.so $(shared-thread-library)
|
||||
$(objpfx)tst-resolv-nondecimal: $(objpfx)libresolv.so $(shared-thread-library)
|
||||
$(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library)
|
||||
$(objpfx)tst-resolv-rotate: $(objpfx)libresolv.so $(shared-thread-library)
|
||||
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
|
||||
index 7248ade18db5ba47..6e83fca1c5b1f98c 100644
|
||||
--- a/resolv/nss_dns/dns-host.c
|
||||
+++ b/resolv/nss_dns/dns-host.c
|
||||
@@ -125,6 +125,14 @@ static enum nss_status gaih_getanswer (const querybuf *answer1, int anslen1,
|
||||
char *buffer, size_t buflen,
|
||||
int *errnop, int *h_errnop,
|
||||
int32_t *ttlp);
|
||||
+static enum nss_status gaih_getanswer_noaaaa (const querybuf *answer1,
|
||||
+ int anslen1,
|
||||
+ const char *qname,
|
||||
+ struct gaih_addrtuple **pat,
|
||||
+ char *buffer, size_t buflen,
|
||||
+ int *errnop, int *h_errnop,
|
||||
+ int32_t *ttlp);
|
||||
+
|
||||
|
||||
static enum nss_status gethostbyname3_context (struct resolv_context *ctx,
|
||||
const char *name, int af,
|
||||
@@ -370,17 +378,31 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
|
||||
int resplen2 = 0;
|
||||
int ans2p_malloced = 0;
|
||||
|
||||
+
|
||||
int olderr = errno;
|
||||
- int n = __res_context_search (ctx, name, C_IN, T_QUERY_A_AND_AAAA,
|
||||
+ int n;
|
||||
+
|
||||
+ if ((ctx->resp->options & RES_NOAAAA) == 0)
|
||||
+ {
|
||||
+ n = __res_context_search (ctx, name, C_IN, T_QUERY_A_AND_AAAA,
|
||||
host_buffer.buf->buf, 2048, &host_buffer.ptr,
|
||||
&ans2p, &nans2p, &resplen2, &ans2p_malloced);
|
||||
- if (n >= 0)
|
||||
- {
|
||||
- status = gaih_getanswer (host_buffer.buf, n, (const querybuf *) ans2p,
|
||||
- resplen2, name, pat, buffer, buflen,
|
||||
- errnop, herrnop, ttlp);
|
||||
+ if (n >= 0)
|
||||
+ status = gaih_getanswer (host_buffer.buf, n, (const querybuf *) ans2p,
|
||||
+ resplen2, name, pat, buffer, buflen,
|
||||
+ errnop, herrnop, ttlp);
|
||||
}
|
||||
else
|
||||
+ {
|
||||
+ n = __res_context_search (ctx, name, C_IN, T_A,
|
||||
+ host_buffer.buf->buf, 2048, NULL,
|
||||
+ NULL, NULL, NULL, NULL);
|
||||
+ if (n >= 0)
|
||||
+ status = gaih_getanswer_noaaaa (host_buffer.buf, n,
|
||||
+ name, pat, buffer, buflen,
|
||||
+ errnop, herrnop, ttlp);
|
||||
+ }
|
||||
+ if (n < 0)
|
||||
{
|
||||
switch (errno)
|
||||
{
|
||||
@@ -1388,3 +1410,21 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2,
|
||||
|
||||
return status;
|
||||
}
|
||||
+
|
||||
+/* Variant of gaih_getanswer without a second (AAAA) response. */
|
||||
+static enum nss_status
|
||||
+gaih_getanswer_noaaaa (const querybuf *answer1, int anslen1, const char *qname,
|
||||
+ struct gaih_addrtuple **pat,
|
||||
+ char *buffer, size_t buflen,
|
||||
+ int *errnop, int *h_errnop, int32_t *ttlp)
|
||||
+{
|
||||
+ int first = 1;
|
||||
+
|
||||
+ enum nss_status status = NSS_STATUS_NOTFOUND;
|
||||
+ if (anslen1 > 0)
|
||||
+ status = gaih_getanswer_slice (answer1, anslen1, qname,
|
||||
+ &pat, &buffer, &buflen,
|
||||
+ errnop, h_errnop, ttlp,
|
||||
+ &first);
|
||||
+ return status;
|
||||
+}
|
||||
diff --git a/resolv/res-noaaaa.c b/resolv/res-noaaaa.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..4ba197664a86aed7
|
||||
--- /dev/null
|
||||
+++ b/resolv/res-noaaaa.c
|
||||
@@ -0,0 +1,143 @@
|
||||
+/* Implement suppression of AAAA queries.
|
||||
+ 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/>. */
|
||||
+
|
||||
+#include <resolv.h>
|
||||
+#include <string.h>
|
||||
+#include <resolv-internal.h>
|
||||
+#include <resolv_context.h>
|
||||
+#include <arpa/nameser.h>
|
||||
+
|
||||
+/* Returns true if the question type at P matches EXPECTED, and the
|
||||
+ class is IN. */
|
||||
+static bool
|
||||
+qtype_matches (const unsigned char *p, int expected)
|
||||
+{
|
||||
+ /* This assumes that T_A/C_IN constants are less than 256, which
|
||||
+ they are. */
|
||||
+ return p[0] == 0 && p[1] == expected && p[2] == 0 && p[3] == C_IN;
|
||||
+}
|
||||
+
|
||||
+/* Handle RES_NOAAAA translation of AAAA queries. To produce a Name
|
||||
+ Error (NXDOMAIN) repsonse for domain names that do not exist, it is
|
||||
+ still necessary to send a query. Using question type A is a
|
||||
+ conservative choice. In the returned answer, it is necessary to
|
||||
+ switch back the question type to AAAA. */
|
||||
+bool
|
||||
+__res_handle_no_aaaa (struct resolv_context *ctx,
|
||||
+ const unsigned char *buf, int buflen,
|
||||
+ unsigned char *ans, int anssiz, int *result)
|
||||
+{
|
||||
+ /* AAAA mode is not active, or the query looks invalid (will not be
|
||||
+ able to be parsed). */
|
||||
+ if ((ctx->resp->options & RES_NOAAAA) == 0
|
||||
+ || buflen <= sizeof (HEADER))
|
||||
+ return false;
|
||||
+
|
||||
+ /* The replacement A query is produced here. */
|
||||
+ struct
|
||||
+ {
|
||||
+ HEADER header;
|
||||
+ unsigned char question[NS_MAXCDNAME + 4];
|
||||
+ } replacement;
|
||||
+ memcpy (&replacement.header, buf, sizeof (replacement.header));
|
||||
+
|
||||
+ if (replacement.header.qr
|
||||
+ || replacement.header.opcode != 0
|
||||
+ || replacement.header.rcode != 0
|
||||
+ || ntohs (replacement.header.qdcount) != 1
|
||||
+ || ntohs (replacement.header.ancount) != 0
|
||||
+ || ntohs (replacement.header.nscount) != 0)
|
||||
+ /* Not a well-formed question. Let the core resolver code produce
|
||||
+ the proper error. */
|
||||
+ return false;
|
||||
+
|
||||
+ /* Disable EDNS0. */
|
||||
+ replacement.header.arcount = htons (0);
|
||||
+
|
||||
+ /* Extract the QNAME. */
|
||||
+ int ret = __ns_name_unpack (buf, buf + buflen, buf + sizeof (HEADER),
|
||||
+ replacement.question, NS_MAXCDNAME);
|
||||
+ if (ret < 0)
|
||||
+ /* Format error. */
|
||||
+ return false;
|
||||
+
|
||||
+ /* Compute the end of the question name. */
|
||||
+ const unsigned char *after_question = buf + sizeof (HEADER) + ret;
|
||||
+
|
||||
+ /* Check that we are dealing with an AAAA query. */
|
||||
+ if (buf + buflen - after_question < 4
|
||||
+ || !qtype_matches (after_question, T_AAAA))
|
||||
+ return false;
|
||||
+
|
||||
+ /* Find the place to store the type/class data in the replacement
|
||||
+ query. */
|
||||
+ after_question = replacement.question;
|
||||
+ /* This cannot fail because __ns_name_unpack above produced a valid
|
||||
+ domain name. */
|
||||
+ (void) __ns_name_skip (&after_question, &replacement.question[NS_MAXCDNAME]);
|
||||
+ unsigned char *start_of_query = (unsigned char *) &replacement;
|
||||
+ const unsigned char *end_of_query = after_question + 4;
|
||||
+
|
||||
+ /* Produce an A/IN query. */
|
||||
+ {
|
||||
+ unsigned char *p = (unsigned char *) after_question;
|
||||
+ p[0] = 0;
|
||||
+ p[1] = T_A;
|
||||
+ p[2] = 0;
|
||||
+ p[3] = C_IN;
|
||||
+ }
|
||||
+
|
||||
+ /* Clear the output buffer, to avoid reading undefined data when
|
||||
+ rewriting the result from A to AAAA. */
|
||||
+ memset (ans, 0, anssiz);
|
||||
+
|
||||
+ /* Always perform the message translation, independent of the error
|
||||
+ code. */
|
||||
+ ret = __res_context_send (ctx,
|
||||
+ start_of_query, end_of_query - start_of_query,
|
||||
+ NULL, 0, ans, anssiz,
|
||||
+ NULL, NULL, NULL, NULL, NULL);
|
||||
+
|
||||
+ /* Patch in the AAAA question type if there is room and the A query
|
||||
+ type was received. */
|
||||
+ after_question = ans + sizeof (HEADER);
|
||||
+ if (__ns_name_skip (&after_question, ans + anssiz) == 0
|
||||
+ && ans + anssiz - after_question >= 4
|
||||
+ && qtype_matches (after_question, T_A))
|
||||
+ {
|
||||
+ ((unsigned char *) after_question)[1] = T_AAAA;
|
||||
+
|
||||
+ /* Create an aligned copy of the header. Hide all data except
|
||||
+ the question from the response. Put back the header. There is
|
||||
+ no need to change the response code. The zero answer count turns
|
||||
+ a positive response with data into a no-data response. */
|
||||
+ memcpy (&replacement.header, ans, sizeof (replacement.header));
|
||||
+ replacement.header.ancount = htons (0);
|
||||
+ replacement.header.nscount = htons (0);
|
||||
+ replacement.header.arcount = htons (0);
|
||||
+ memcpy (ans, &replacement.header, sizeof (replacement.header));
|
||||
+
|
||||
+ /* Truncate the reply. */
|
||||
+ if (ret <= 0)
|
||||
+ *result = ret;
|
||||
+ else
|
||||
+ *result = after_question - ans + 4;
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
diff --git a/resolv/res_debug.c b/resolv/res_debug.c
|
||||
index 030df0aa90c9f34f..b0fe69b1aa5186a0 100644
|
||||
--- a/resolv/res_debug.c
|
||||
+++ b/resolv/res_debug.c
|
||||
@@ -613,6 +613,7 @@ p_option(u_long option) {
|
||||
case RES_NOTLDQUERY: return "no-tld-query";
|
||||
case RES_NORELOAD: return "no-reload";
|
||||
case RES_TRUSTAD: return "trust-ad";
|
||||
+ case RES_NOAAAA: return "no-aaaa";
|
||||
/* XXX nonreentrant */
|
||||
default: sprintf(nbuf, "?0x%lx?", (u_long)option);
|
||||
return (nbuf);
|
||||
diff --git a/resolv/res_init.c b/resolv/res_init.c
|
||||
index 6b2936eda9618ac9..8bde915903565f60 100644
|
||||
--- a/resolv/res_init.c
|
||||
+++ b/resolv/res_init.c
|
||||
@@ -695,6 +695,7 @@ res_setoptions (struct resolv_conf_parser *parser, const char *options)
|
||||
{ STRnLEN ("no-reload"), 0, RES_NORELOAD },
|
||||
{ STRnLEN ("use-vc"), 0, RES_USEVC },
|
||||
{ STRnLEN ("trust-ad"), 0, RES_TRUSTAD },
|
||||
+ { STRnLEN ("no-aaaa"), 0, RES_NOAAAA },
|
||||
};
|
||||
#define noptions (sizeof (options) / sizeof (options[0]))
|
||||
for (int i = 0; i < noptions; ++i)
|
||||
diff --git a/resolv/res_query.c b/resolv/res_query.c
|
||||
index 75b0e5f2f7b51eb2..2f3c28cfc8c0d832 100644
|
||||
--- a/resolv/res_query.c
|
||||
+++ b/resolv/res_query.c
|
||||
@@ -204,10 +204,26 @@ __res_context_query (struct resolv_context *ctx, const char *name,
|
||||
free (buf);
|
||||
return (n);
|
||||
}
|
||||
- assert (answerp == NULL || (void *) *answerp == (void *) answer);
|
||||
- n = __res_context_send (ctx, query1, nquery1, query2, nquery2, answer,
|
||||
- anslen, answerp, answerp2, nanswerp2, resplen2,
|
||||
- answerp2_malloced);
|
||||
+
|
||||
+ /* Suppress AAAA lookups if required. __res_handle_no_aaaa
|
||||
+ checks RES_NOAAAA first, so avoids parsing the
|
||||
+ just-generated query packet in most cases. nss_dns avoids
|
||||
+ using T_QUERY_A_AND_AAAA in RES_NOAAAA mode, so there is no
|
||||
+ need to handle it here. */
|
||||
+ if (type == T_AAAA && __res_handle_no_aaaa (ctx, query1, nquery1,
|
||||
+ answer, anslen, &n))
|
||||
+ /* There must be no second query for AAAA queries. The code
|
||||
+ below is still needed to translate NODATA responses. */
|
||||
+ assert (query2 == NULL);
|
||||
+ else
|
||||
+ {
|
||||
+ assert (answerp == NULL || (void *) *answerp == (void *) answer);
|
||||
+ n = __res_context_send (ctx, query1, nquery1, query2, nquery2,
|
||||
+ answer, anslen,
|
||||
+ answerp, answerp2, nanswerp2, resplen2,
|
||||
+ answerp2_malloced);
|
||||
+ }
|
||||
+
|
||||
if (use_malloc)
|
||||
free (buf);
|
||||
if (n < 0) {
|
||||
diff --git a/resolv/res_send.c b/resolv/res_send.c
|
||||
index 9f86f5fe47194887..8ac6a307b40fa2ca 100644
|
||||
--- a/resolv/res_send.c
|
||||
+++ b/resolv/res_send.c
|
||||
@@ -438,8 +438,13 @@ context_send_common (struct resolv_context *ctx,
|
||||
RES_SET_H_ERRNO (&_res, NETDB_INTERNAL);
|
||||
return -1;
|
||||
}
|
||||
- int result = __res_context_send (ctx, buf, buflen, NULL, 0, ans, anssiz,
|
||||
- NULL, NULL, NULL, NULL, NULL);
|
||||
+
|
||||
+ int result;
|
||||
+ if (__res_handle_no_aaaa (ctx, buf, buflen, ans, anssiz, &result))
|
||||
+ return result;
|
||||
+
|
||||
+ result = __res_context_send (ctx, buf, buflen, NULL, 0, ans, anssiz,
|
||||
+ NULL, NULL, NULL, NULL, NULL);
|
||||
__resolv_context_put (ctx);
|
||||
return result;
|
||||
}
|
||||
diff --git a/resolv/resolv-internal.h b/resolv/resolv-internal.h
|
||||
index 216e47ed42076b72..8ab02fc9e648d30f 100644
|
||||
--- a/resolv/resolv-internal.h
|
||||
+++ b/resolv/resolv-internal.h
|
||||
@@ -78,6 +78,14 @@ int __res_context_send (struct resolv_context *, const unsigned char *, int,
|
||||
int *, int *, int *);
|
||||
libc_hidden_proto (__res_context_send)
|
||||
|
||||
+/* Return true if the query has been handled in RES_NOAAAA mode. For
|
||||
+ that, RES_NOAAAA must be active, and the question type must be AAAA.
|
||||
+ The caller is expected to return *RESULT as the return value. */
|
||||
+bool __res_handle_no_aaaa (struct resolv_context *ctx,
|
||||
+ const unsigned char *buf, int buflen,
|
||||
+ unsigned char *ans, int anssiz, int *result)
|
||||
+ attribute_hidden;
|
||||
+
|
||||
/* Internal function similar to res_hostalias. */
|
||||
const char *__res_context_hostalias (struct resolv_context *,
|
||||
const char *, char *, size_t);
|
||||
diff --git a/resolv/resolv.h b/resolv/resolv.h
|
||||
index e7c8d44645912ddf..3a79ffea57a6916f 100644
|
||||
--- a/resolv/resolv.h
|
||||
+++ b/resolv/resolv.h
|
||||
@@ -132,6 +132,7 @@ struct res_sym {
|
||||
as a TLD. */
|
||||
#define RES_NORELOAD 0x02000000 /* No automatic configuration reload. */
|
||||
#define RES_TRUSTAD 0x04000000 /* Request AD bit, keep it in responses. */
|
||||
+#define RES_NOAAAA 0x08000000 /* Suppress AAAA queries. */
|
||||
|
||||
#define RES_DEFAULT (RES_RECURSE|RES_DEFNAMES|RES_DNSRCH)
|
||||
|
||||
diff --git a/resolv/tst-resolv-noaaaa.c b/resolv/tst-resolv-noaaaa.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..56b25f88a58ad286
|
||||
--- /dev/null
|
||||
+++ b/resolv/tst-resolv-noaaaa.c
|
||||
@@ -0,0 +1,533 @@
|
||||
+/* Test the RES_NOAAAA resolver option.
|
||||
+ 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/>. */
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <netdb.h>
|
||||
+#include <resolv.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/check_nss.h>
|
||||
+#include <support/resolv_test.h>
|
||||
+#include <support/support.h>
|
||||
+
|
||||
+/* Used to keep track of the number of queries. */
|
||||
+static volatile unsigned int queries;
|
||||
+
|
||||
+static void
|
||||
+response (const struct resolv_response_context *ctx,
|
||||
+ struct resolv_response_builder *b,
|
||||
+ const char *qname, uint16_t qclass, uint16_t qtype)
|
||||
+{
|
||||
+ /* Each test should only send one query. */
|
||||
+ ++queries;
|
||||
+ TEST_COMPARE (queries, 1);
|
||||
+
|
||||
+ /* AAAA queries are supposed to be disabled. */
|
||||
+ TEST_VERIFY (qtype != T_AAAA);
|
||||
+ TEST_COMPARE (qclass, C_IN);
|
||||
+
|
||||
+ /* The only other query type besides A is PTR. */
|
||||
+ if (qtype != T_A)
|
||||
+ TEST_COMPARE (qtype, T_PTR);
|
||||
+
|
||||
+ int an, ns, ar;
|
||||
+ char *tail;
|
||||
+ if (sscanf (qname, "an%d.ns%d.ar%d.%ms", &an, &ns, &ar, &tail) != 4)
|
||||
+ FAIL_EXIT1 ("invalid QNAME: %s\n", qname);
|
||||
+ TEST_COMPARE_STRING (tail, "example");
|
||||
+ free (tail);
|
||||
+
|
||||
+ if (an < 0 || ns < 0 || ar < 0)
|
||||
+ {
|
||||
+ struct resolv_response_flags flags = { .rcode = NXDOMAIN, };
|
||||
+ resolv_response_init (b, flags);
|
||||
+ resolv_response_add_question (b, qname, qclass, qtype);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ struct resolv_response_flags flags = {};
|
||||
+ resolv_response_init (b, flags);
|
||||
+ resolv_response_add_question (b, qname, qclass, qtype);
|
||||
+
|
||||
+ resolv_response_section (b, ns_s_an);
|
||||
+ for (int i = 0; i < an; ++i)
|
||||
+ {
|
||||
+ resolv_response_open_record (b, qname, qclass, qtype, 60);
|
||||
+ switch (qtype)
|
||||
+ {
|
||||
+ case T_A:
|
||||
+ char ipv4[4] = {192, 0, 2, i + 1};
|
||||
+ resolv_response_add_data (b, &ipv4, sizeof (ipv4));
|
||||
+ break;
|
||||
+
|
||||
+ case T_PTR:
|
||||
+ char *name = xasprintf ("ptr-%d", i);
|
||||
+ resolv_response_add_name (b, name);
|
||||
+ free (name);
|
||||
+ break;
|
||||
+ }
|
||||
+ resolv_response_close_record (b);
|
||||
+ }
|
||||
+
|
||||
+ resolv_response_section (b, ns_s_ns);
|
||||
+ for (int i = 0; i < ns; ++i)
|
||||
+ {
|
||||
+ resolv_response_open_record (b, qname, qclass, T_NS, 60);
|
||||
+ char *name = xasprintf ("ns%d.example.net", i);
|
||||
+ resolv_response_add_name (b, name);
|
||||
+ free (name);
|
||||
+ resolv_response_close_record (b);
|
||||
+ }
|
||||
+
|
||||
+ resolv_response_section (b, ns_s_ar);
|
||||
+ int addr = 1;
|
||||
+ for (int i = 0; i < ns; ++i)
|
||||
+ {
|
||||
+ char *name = xasprintf ("ns%d.example.net", i);
|
||||
+ for (int j = 0; j < ar; ++j)
|
||||
+ {
|
||||
+ resolv_response_open_record (b, name, qclass, T_A, 60);
|
||||
+ char ipv4[4] = {192, 0, 2, addr};
|
||||
+ resolv_response_add_data (b, &ipv4, sizeof (ipv4));
|
||||
+ resolv_response_close_record (b);
|
||||
+
|
||||
+ resolv_response_open_record (b, name, qclass, T_AAAA, 60);
|
||||
+ char ipv6[16]
|
||||
+ = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, addr};
|
||||
+ resolv_response_add_data (b, &ipv6, sizeof (ipv6));
|
||||
+ resolv_response_close_record (b);
|
||||
+
|
||||
+ ++addr;
|
||||
+ }
|
||||
+ free (name);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* Number of modes. Lowest bit encodes *n* function vs implicit _res
|
||||
+ argument. The mode numbers themselves are arbitrary. */
|
||||
+enum { mode_count = 8 };
|
||||
+
|
||||
+/* res_send-like modes do not perform error translation. */
|
||||
+enum { first_send_mode = 6 };
|
||||
+
|
||||
+static int
|
||||
+libresolv_query (unsigned int mode, const char *qname, uint16_t qtype,
|
||||
+ unsigned char *buf, size_t buflen)
|
||||
+{
|
||||
+ int saved_errno = errno;
|
||||
+
|
||||
+ TEST_VERIFY_EXIT (mode < mode_count);
|
||||
+
|
||||
+ switch (mode)
|
||||
+ {
|
||||
+ case 0:
|
||||
+ return res_query (qname, C_IN, qtype, buf, buflen);
|
||||
+ case 1:
|
||||
+ return res_nquery (&_res, qname, C_IN, qtype, buf, buflen);
|
||||
+ case 2:
|
||||
+ return res_search (qname, C_IN, qtype, buf, buflen);
|
||||
+ case 3:
|
||||
+ return res_nsearch (&_res, qname, C_IN, qtype, buf, buflen);
|
||||
+ case 4:
|
||||
+ return res_querydomain (qname, "", C_IN, qtype, buf, buflen);
|
||||
+ case 5:
|
||||
+ return res_nquerydomain (&_res, qname, "", C_IN, qtype, buf, buflen);
|
||||
+ case 6:
|
||||
+ {
|
||||
+ unsigned char querybuf[512];
|
||||
+ int ret = res_mkquery (QUERY, qname, C_IN, qtype,
|
||||
+ NULL, 0, NULL, querybuf, sizeof (querybuf));
|
||||
+ TEST_VERIFY_EXIT (ret > 0);
|
||||
+ errno = saved_errno;
|
||||
+ return res_send (querybuf, ret, buf, buflen);
|
||||
+ }
|
||||
+ case 7:
|
||||
+ {
|
||||
+ unsigned char querybuf[512];
|
||||
+ int ret = res_nmkquery (&_res, QUERY, qname, C_IN, qtype,
|
||||
+ NULL, 0, NULL, querybuf, sizeof (querybuf));
|
||||
+ TEST_VERIFY_EXIT (ret > 0);
|
||||
+ errno = saved_errno;
|
||||
+ return res_nsend (&_res, querybuf, ret, buf, buflen);
|
||||
+ }
|
||||
+ }
|
||||
+ __builtin_unreachable ();
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ struct resolv_test *obj = resolv_test_start
|
||||
+ ((struct resolv_redirect_config)
|
||||
+ {
|
||||
+ .response_callback = response
|
||||
+ });
|
||||
+
|
||||
+ _res.options |= RES_NOAAAA;
|
||||
+
|
||||
+ check_hostent ("an1.ns2.ar1.example",
|
||||
+ gethostbyname ("an1.ns2.ar1.example"),
|
||||
+ "name: an1.ns2.ar1.example\n"
|
||||
+ "address: 192.0.2.1\n");
|
||||
+ queries = 0;
|
||||
+ check_hostent ("an0.ns2.ar1.example",
|
||||
+ gethostbyname ("an0.ns2.ar1.example"),
|
||||
+ "error: NO_ADDRESS\n");
|
||||
+ queries = 0;
|
||||
+ check_hostent ("an-1.ns2.ar1.example",
|
||||
+ gethostbyname ("an-1.ns2.ar1.example"),
|
||||
+ "error: HOST_NOT_FOUND\n");
|
||||
+ queries = 0;
|
||||
+
|
||||
+ check_hostent ("an1.ns2.ar1.example AF_INET",
|
||||
+ gethostbyname2 ("an1.ns2.ar1.example", AF_INET),
|
||||
+ "name: an1.ns2.ar1.example\n"
|
||||
+ "address: 192.0.2.1\n");
|
||||
+ queries = 0;
|
||||
+ check_hostent ("an0.ns2.ar1.example AF_INET",
|
||||
+ gethostbyname2 ("an0.ns2.ar1.example", AF_INET),
|
||||
+ "error: NO_ADDRESS\n");
|
||||
+ queries = 0;
|
||||
+ check_hostent ("an-1.ns2.ar1.example AF_INET",
|
||||
+ gethostbyname2 ("an-1.ns2.ar1.example", AF_INET),
|
||||
+ "error: HOST_NOT_FOUND\n");
|
||||
+ queries = 0;
|
||||
+
|
||||
+ check_hostent ("an1.ns2.ar1.example AF_INET6",
|
||||
+ gethostbyname2 ("an1.ns2.ar1.example", AF_INET6),
|
||||
+ "error: NO_ADDRESS\n");
|
||||
+ queries = 0;
|
||||
+ check_hostent ("an0.ns2.ar1.example AF_INET6",
|
||||
+ gethostbyname2 ("an0.ns2.ar1.example", AF_INET6),
|
||||
+ "error: NO_ADDRESS\n");
|
||||
+ queries = 0;
|
||||
+ check_hostent ("an-1.ns2.ar1.example AF_INET6",
|
||||
+ gethostbyname2 ("an-1.ns2.ar1.example", AF_INET6),
|
||||
+ "error: HOST_NOT_FOUND\n");
|
||||
+ queries = 0;
|
||||
+
|
||||
+ /* Multiple addresses. */
|
||||
+ check_hostent ("an2.ns0.ar0.example",
|
||||
+ gethostbyname ("an2.ns0.ar0.example"),
|
||||
+ "name: an2.ns0.ar0.example\n"
|
||||
+ "address: 192.0.2.1\n"
|
||||
+ "address: 192.0.2.2\n");
|
||||
+ queries = 0;
|
||||
+ check_hostent ("an2.ns0.ar0.example AF_INET6",
|
||||
+ gethostbyname2 ("an2.ns0.ar0.example", AF_INET6),
|
||||
+ "error: NO_ADDRESS\n");
|
||||
+ queries = 0;
|
||||
+
|
||||
+ /* getaddrinfo checks with one address. */
|
||||
+ struct addrinfo *ai;
|
||||
+ int ret;
|
||||
+ ret = getaddrinfo ("an1.ns2.ar1.example", "80",
|
||||
+ &(struct addrinfo)
|
||||
+ {
|
||||
+ .ai_family = AF_INET,
|
||||
+ .ai_socktype = SOCK_STREAM,
|
||||
+ }, &ai);
|
||||
+ check_addrinfo ("an1.ns2.ar1.example (AF_INET)", ai, ret,
|
||||
+ "address: STREAM/TCP 192.0.2.1 80\n");
|
||||
+ freeaddrinfo (ai);
|
||||
+ queries = 0;
|
||||
+ ret = getaddrinfo ("an1.ns2.ar1.example", "80",
|
||||
+ &(struct addrinfo)
|
||||
+ {
|
||||
+ .ai_family = AF_INET6,
|
||||
+ .ai_socktype = SOCK_STREAM,
|
||||
+ }, &ai);
|
||||
+ check_addrinfo ("an1.ns2.ar1.example (AF_INET6)", ai, ret,
|
||||
+ "error: No address associated with hostname\n");
|
||||
+ queries = 0;
|
||||
+ ret = getaddrinfo ("an1.ns2.ar1.example", "80",
|
||||
+ &(struct addrinfo)
|
||||
+ {
|
||||
+ .ai_family = AF_UNSPEC,
|
||||
+ .ai_socktype = SOCK_STREAM,
|
||||
+ }, &ai);
|
||||
+ check_addrinfo ("an1.ns2.ar1.example (AF_UNSPEC)", ai, ret,
|
||||
+ "address: STREAM/TCP 192.0.2.1 80\n");
|
||||
+ freeaddrinfo (ai);
|
||||
+ queries = 0;
|
||||
+
|
||||
+ /* getaddrinfo checks with three addresses. */
|
||||
+ ret = getaddrinfo ("an3.ns2.ar1.example", "80",
|
||||
+ &(struct addrinfo)
|
||||
+ {
|
||||
+ .ai_family = AF_INET,
|
||||
+ .ai_socktype = SOCK_STREAM,
|
||||
+ }, &ai);
|
||||
+ check_addrinfo ("an3.ns2.ar1.example (AF_INET)", ai, ret,
|
||||
+ "address: STREAM/TCP 192.0.2.1 80\n"
|
||||
+ "address: STREAM/TCP 192.0.2.2 80\n"
|
||||
+ "address: STREAM/TCP 192.0.2.3 80\n");
|
||||
+ freeaddrinfo (ai);
|
||||
+ queries = 0;
|
||||
+ ret = getaddrinfo ("an3.ns2.ar1.example", "80",
|
||||
+ &(struct addrinfo)
|
||||
+ {
|
||||
+ .ai_family = AF_INET6,
|
||||
+ .ai_socktype = SOCK_STREAM,
|
||||
+ }, &ai);
|
||||
+ check_addrinfo ("an3.ns2.ar1.example (AF_INET6)", ai, ret,
|
||||
+ "error: No address associated with hostname\n");
|
||||
+ queries = 0;
|
||||
+ ret = getaddrinfo ("an3.ns2.ar1.example", "80",
|
||||
+ &(struct addrinfo)
|
||||
+ {
|
||||
+ .ai_family = AF_UNSPEC,
|
||||
+ .ai_socktype = SOCK_STREAM,
|
||||
+ }, &ai);
|
||||
+ check_addrinfo ("an3.ns2.ar1.example (AF_UNSPEC)", ai, ret,
|
||||
+ "address: STREAM/TCP 192.0.2.1 80\n"
|
||||
+ "address: STREAM/TCP 192.0.2.2 80\n"
|
||||
+ "address: STREAM/TCP 192.0.2.3 80\n");
|
||||
+ freeaddrinfo (ai);
|
||||
+ queries = 0;
|
||||
+
|
||||
+ /* getaddrinfo checks with no address. */
|
||||
+ ret = getaddrinfo ("an0.ns2.ar1.example", "80",
|
||||
+ &(struct addrinfo)
|
||||
+ {
|
||||
+ .ai_family = AF_INET,
|
||||
+ .ai_socktype = SOCK_STREAM,
|
||||
+ }, &ai);
|
||||
+ check_addrinfo ("an0.ns2.ar1.example (AF_INET)", ai, ret,
|
||||
+ "error: No address associated with hostname\n");
|
||||
+ queries = 0;
|
||||
+ ret = getaddrinfo ("an0.ns2.ar1.example", "80",
|
||||
+ &(struct addrinfo)
|
||||
+ {
|
||||
+ .ai_family = AF_INET6,
|
||||
+ .ai_socktype = SOCK_STREAM,
|
||||
+ }, &ai);
|
||||
+ check_addrinfo ("an0.ns2.ar1.example (AF_INET6)", ai, ret,
|
||||
+ "error: No address associated with hostname\n");
|
||||
+ queries = 0;
|
||||
+ ret = getaddrinfo ("an0.ns2.ar1.example", "80",
|
||||
+ &(struct addrinfo)
|
||||
+ {
|
||||
+ .ai_family = AF_UNSPEC,
|
||||
+ .ai_socktype = SOCK_STREAM,
|
||||
+ }, &ai);
|
||||
+ check_addrinfo ("an-1.ns2.ar1.example (AF_UNSPEC)", ai, ret,
|
||||
+ "error: No address associated with hostname\n");
|
||||
+ queries = 0;
|
||||
+
|
||||
+ /* getaddrinfo checks with NXDOMAIN. */
|
||||
+ ret = getaddrinfo ("an-1.ns2.ar1.example", "80",
|
||||
+ &(struct addrinfo)
|
||||
+ {
|
||||
+ .ai_family = AF_INET,
|
||||
+ .ai_socktype = SOCK_STREAM,
|
||||
+ }, &ai);
|
||||
+ check_addrinfo ("an-1.ns2.ar1.example (AF_INET)", ai, ret,
|
||||
+ "error: Name or service not known\n");
|
||||
+ queries = 0;
|
||||
+ ret = getaddrinfo ("an-1.ns2.ar1.example", "80",
|
||||
+ &(struct addrinfo)
|
||||
+ {
|
||||
+ .ai_family = AF_INET6,
|
||||
+ .ai_socktype = SOCK_STREAM,
|
||||
+ }, &ai);
|
||||
+ check_addrinfo ("an-1.ns2.ar1.example (AF_INET6)", ai, ret,
|
||||
+ "error: Name or service not known\n");
|
||||
+ queries = 0;
|
||||
+ ret = getaddrinfo ("an-1.ns2.ar1.example", "80",
|
||||
+ &(struct addrinfo)
|
||||
+ {
|
||||
+ .ai_family = AF_UNSPEC,
|
||||
+ .ai_socktype = SOCK_STREAM,
|
||||
+ }, &ai);
|
||||
+ check_addrinfo ("an-1.ns2.ar1.example (AF_UNSPEC)", ai, ret,
|
||||
+ "error: Name or service not known\n");
|
||||
+ queries = 0;
|
||||
+
|
||||
+ for (unsigned int mode = 0; mode < mode_count; ++mode)
|
||||
+ {
|
||||
+ unsigned char *buf;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Response for A. */
|
||||
+ buf = malloc (512);
|
||||
+ ret = libresolv_query (mode, "an1.ns2.ar1.example", T_A, buf, 512);
|
||||
+ TEST_VERIFY_EXIT (ret > 0);
|
||||
+ check_dns_packet ("an1.ns2.ar1.example A", buf, ret,
|
||||
+ "name: an1.ns2.ar1.example\n"
|
||||
+ "address: 192.0.2.1\n");
|
||||
+ free (buf);
|
||||
+ queries = 0;
|
||||
+
|
||||
+ /* NODATA response for A. */
|
||||
+ buf = malloc (512);
|
||||
+ errno = 0;
|
||||
+ ret = libresolv_query (mode, "an0.ns2.ar1.example", T_A, buf, 512);
|
||||
+ if (mode < first_send_mode)
|
||||
+ {
|
||||
+ TEST_COMPARE (ret, -1);
|
||||
+ TEST_COMPARE (errno, 0);
|
||||
+ TEST_COMPARE (h_errno, NO_ADDRESS);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ TEST_VERIFY_EXIT (ret > 0);
|
||||
+ TEST_COMPARE (((HEADER *)buf)->rcode, 0);
|
||||
+ check_dns_packet ("an1.ns2.ar1.example A", buf, ret,
|
||||
+ "name: an0.ns2.ar1.example\n");
|
||||
+ }
|
||||
+ free (buf);
|
||||
+ queries = 0;
|
||||
+
|
||||
+ /* NXDOMAIN response for A. */
|
||||
+ buf = malloc (512);
|
||||
+ errno = 0;
|
||||
+ ret = libresolv_query (mode, "an-1.ns2.ar1.example", T_A, buf, 512);
|
||||
+ if (mode < first_send_mode)
|
||||
+ {
|
||||
+ TEST_COMPARE (ret, -1);
|
||||
+ TEST_COMPARE (errno, 0);
|
||||
+ TEST_COMPARE (h_errno, HOST_NOT_FOUND);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ TEST_VERIFY_EXIT (ret > 0);
|
||||
+ TEST_COMPARE (((HEADER *)buf)->rcode, NXDOMAIN);
|
||||
+ check_dns_packet ("an1.ns2.ar1.example A", buf, ret,
|
||||
+ "name: an-1.ns2.ar1.example\n");
|
||||
+ }
|
||||
+ free (buf);
|
||||
+ queries = 0;
|
||||
+
|
||||
+ /* Response for PTR. */
|
||||
+ buf = malloc (512);
|
||||
+ ret = libresolv_query (mode, "an1.ns2.ar1.example", T_PTR, buf, 512);
|
||||
+ TEST_VERIFY_EXIT (ret > 0);
|
||||
+ check_dns_packet ("an1.ns2.ar1.example PTR", buf, ret,
|
||||
+ "name: an1.ns2.ar1.example\n"
|
||||
+ "data: an1.ns2.ar1.example PTR ptr-0\n");
|
||||
+ free (buf);
|
||||
+ queries = 0;
|
||||
+
|
||||
+ /* NODATA response for PTR. */
|
||||
+ buf = malloc (512);
|
||||
+ errno = 0;
|
||||
+ ret = libresolv_query (mode, "an0.ns2.ar1.example", T_PTR, buf, 512);
|
||||
+ if (mode < first_send_mode)
|
||||
+ {
|
||||
+ TEST_COMPARE (ret, -1);
|
||||
+ TEST_COMPARE (errno, 0);
|
||||
+ TEST_COMPARE (h_errno, NO_ADDRESS);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ TEST_VERIFY_EXIT (ret > 0);
|
||||
+ TEST_COMPARE (((HEADER *)buf)->rcode, 0);
|
||||
+ check_dns_packet ("an1.ns2.ar1.example PTR", buf, ret,
|
||||
+ "name: an0.ns2.ar1.example\n");
|
||||
+ }
|
||||
+ free (buf);
|
||||
+ queries = 0;
|
||||
+
|
||||
+ /* NXDOMAIN response for PTR. */
|
||||
+ buf = malloc (512);
|
||||
+ errno = 0;
|
||||
+ ret = libresolv_query (mode, "an-1.ns2.ar1.example", T_PTR, buf, 512);
|
||||
+ if (mode < first_send_mode)
|
||||
+ {
|
||||
+ TEST_COMPARE (ret, -1);
|
||||
+ TEST_COMPARE (errno, 0);
|
||||
+ TEST_COMPARE (h_errno, HOST_NOT_FOUND);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ TEST_VERIFY_EXIT (ret > 0);
|
||||
+ TEST_COMPARE (((HEADER *)buf)->rcode, NXDOMAIN);
|
||||
+ check_dns_packet ("an1.ns2.ar1.example PTR", buf, ret,
|
||||
+ "name: an-1.ns2.ar1.example\n");
|
||||
+ }
|
||||
+ free (buf);
|
||||
+ queries = 0;
|
||||
+
|
||||
+ /* NODATA response for AAAA. */
|
||||
+ buf = malloc (512);
|
||||
+ errno = 0;
|
||||
+ ret = libresolv_query (mode, "an1.ns2.ar1.example", T_AAAA, buf, 512);
|
||||
+ if (mode < first_send_mode)
|
||||
+ {
|
||||
+ TEST_COMPARE (ret, -1);
|
||||
+ TEST_COMPARE (errno, 0);
|
||||
+ TEST_COMPARE (h_errno, NO_ADDRESS);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ TEST_VERIFY_EXIT (ret > 0);
|
||||
+ TEST_COMPARE (((HEADER *)buf)->rcode, 0);
|
||||
+ check_dns_packet ("an1.ns2.ar1.example A", buf, ret,
|
||||
+ "name: an1.ns2.ar1.example\n");
|
||||
+ }
|
||||
+ free (buf);
|
||||
+ queries = 0;
|
||||
+
|
||||
+ /* NODATA response for AAAA (original is already NODATA). */
|
||||
+ buf = malloc (512);
|
||||
+ errno = 0;
|
||||
+ ret = libresolv_query (mode, "an0.ns2.ar1.example", T_AAAA, buf, 512);
|
||||
+ if (mode < first_send_mode)
|
||||
+ {
|
||||
+ TEST_COMPARE (ret, -1);
|
||||
+ TEST_COMPARE (errno, 0);
|
||||
+ TEST_COMPARE (h_errno, NO_ADDRESS);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ TEST_VERIFY_EXIT (ret > 0);
|
||||
+ TEST_COMPARE (((HEADER *)buf)->rcode, 0);
|
||||
+ check_dns_packet ("an0.ns2.ar1.example A", buf, ret,
|
||||
+ "name: an0.ns2.ar1.example\n");
|
||||
+ }
|
||||
+ free (buf);
|
||||
+ queries = 0;
|
||||
+
|
||||
+ /* NXDOMAIN response. */
|
||||
+ buf = malloc (512);
|
||||
+ errno = 0;
|
||||
+ ret = libresolv_query (mode, "an-1.ns2.ar1.example", T_AAAA, buf, 512);
|
||||
+ if (mode < first_send_mode)
|
||||
+ {
|
||||
+ TEST_COMPARE (ret, -1);
|
||||
+ TEST_COMPARE (errno, 0);
|
||||
+ TEST_COMPARE (h_errno, HOST_NOT_FOUND);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ TEST_VERIFY_EXIT (ret > 0);
|
||||
+ TEST_COMPARE (((HEADER *)buf)->rcode, NXDOMAIN);
|
||||
+ check_dns_packet ("an-1.ns2.ar1.example A", buf, ret,
|
||||
+ "name: an-1.ns2.ar1.example\n");
|
||||
+ }
|
||||
+ free (buf);
|
||||
+ queries = 0;
|
||||
+ }
|
||||
+
|
||||
+ resolv_test_end (obj);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/resolv/tst-resolv-res_init-skeleton.c b/resolv/tst-resolv-res_init-skeleton.c
|
||||
index c87596762fcb23b1..28ed9c2eb150532d 100644
|
||||
--- a/resolv/tst-resolv-res_init-skeleton.c
|
||||
+++ b/resolv/tst-resolv-res_init-skeleton.c
|
||||
@@ -128,6 +128,7 @@ print_resp (FILE *fp, res_state resp)
|
||||
print_option_flag (fp, &options, RES_NOTLDQUERY, "no-tld-query");
|
||||
print_option_flag (fp, &options, RES_NORELOAD, "no-reload");
|
||||
print_option_flag (fp, &options, RES_TRUSTAD, "trust-ad");
|
||||
+ print_option_flag (fp, &options, RES_NOAAAA, "no-aaaa");
|
||||
fputc ('\n', fp);
|
||||
if (options != 0)
|
||||
fprintf (fp, "; error: unresolved option bits: 0x%x\n", options);
|
||||
@@ -721,6 +722,15 @@ struct test_case test_cases[] =
|
||||
"nameserver 192.0.2.1\n"
|
||||
"; nameserver[0]: [192.0.2.1]:53\n"
|
||||
},
|
||||
+ {.name = "no-aaaa flag",
|
||||
+ .conf = "options no-aaaa\n"
|
||||
+ "nameserver 192.0.2.1\n",
|
||||
+ .expected = "options no-aaaa\n"
|
||||
+ "search example.com\n"
|
||||
+ "; search[0]: example.com\n"
|
||||
+ "nameserver 192.0.2.1\n"
|
||||
+ "; nameserver[0]: [192.0.2.1]:53\n"
|
||||
+ },
|
||||
{ NULL }
|
||||
};
|
||||
|
@ -0,0 +1,154 @@
|
||||
commit cca9684f2d7a74fc0b28bfb1859955e0e28d7b4b
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Wed Aug 3 11:41:53 2022 +0200
|
||||
|
||||
stdio: Clean up __libc_message after unconditional abort
|
||||
|
||||
Since commit ec2c1fcefb200c6cb7e09553f3c6af8815013d83 ("malloc:
|
||||
Abort on heap corruption, without a backtrace [BZ #21754]"),
|
||||
__libc_message always terminates the process. Since commit
|
||||
a289ea09ea843ced6e5277c2f2e63c357bc7f9a3 ("Do not print backtraces
|
||||
on fatal glibc errors"), the backtrace facility has been removed.
|
||||
Therefore, remove enum __libc_message_action and the action
|
||||
argument of __libc_message, and mark __libc_message as _No_return.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/debug/fortify_fail.c b/debug/fortify_fail.c
|
||||
index 9fa07af4867c2bd1..1b490d9da78b8d0d 100644
|
||||
--- a/debug/fortify_fail.c
|
||||
+++ b/debug/fortify_fail.c
|
||||
@@ -21,8 +21,6 @@ void
|
||||
__attribute__ ((noreturn))
|
||||
__fortify_fail (const char *msg)
|
||||
{
|
||||
- /* The loop is added only to keep gcc happy. */
|
||||
- while (1)
|
||||
- __libc_message (do_abort, "*** %s ***: terminated\n", msg);
|
||||
+ __libc_message ("*** %s ***: terminated\n", msg);
|
||||
}
|
||||
libc_hidden_def (__fortify_fail)
|
||||
diff --git a/include/stdio.h b/include/stdio.h
|
||||
index 23b7fd288cdaba66..3d4544575318a934 100644
|
||||
--- a/include/stdio.h
|
||||
+++ b/include/stdio.h
|
||||
@@ -143,18 +143,11 @@ extern int __gen_tempname (char *__tmpl, int __suffixlen, int __flags,
|
||||
# define __GT_DIR 1 /* create a directory */
|
||||
# define __GT_NOCREATE 2 /* just find a name not currently in use */
|
||||
|
||||
-enum __libc_message_action
|
||||
-{
|
||||
- do_message = 0, /* Print message. */
|
||||
- do_abort = 1 << 0, /* Abort. */
|
||||
-};
|
||||
-
|
||||
/* Print out MESSAGE (which should end with a newline) on the error output
|
||||
and abort. */
|
||||
extern void __libc_fatal (const char *__message)
|
||||
__attribute__ ((__noreturn__));
|
||||
-extern void __libc_message (enum __libc_message_action action,
|
||||
- const char *__fnt, ...) attribute_hidden;
|
||||
+_Noreturn void __libc_message (const char *__fnt, ...) attribute_hidden;
|
||||
extern void __fortify_fail (const char *msg) __attribute__ ((__noreturn__));
|
||||
libc_hidden_proto (__fortify_fail)
|
||||
|
||||
diff --git a/malloc/malloc.c b/malloc/malloc.c
|
||||
index d31e985ecce968fe..918e7936f1983437 100644
|
||||
--- a/malloc/malloc.c
|
||||
+++ b/malloc/malloc.c
|
||||
@@ -298,8 +298,7 @@ _Noreturn static void
|
||||
__malloc_assert (const char *assertion, const char *file, unsigned int line,
|
||||
const char *function)
|
||||
{
|
||||
- __libc_message (do_abort, "\
|
||||
-Fatal glibc error: malloc assertion failure in %s: %s\n",
|
||||
+ __libc_message ("Fatal glibc error: malloc assertion failure in %s: %s\n",
|
||||
function, assertion);
|
||||
__builtin_unreachable ();
|
||||
}
|
||||
@@ -5528,7 +5527,7 @@ static void
|
||||
malloc_printerr (const char *str)
|
||||
{
|
||||
#if IS_IN (libc)
|
||||
- __libc_message (do_abort, "%s\n", str);
|
||||
+ __libc_message ("%s\n", str);
|
||||
#else
|
||||
__libc_fatal (str);
|
||||
#endif
|
||||
diff --git a/sysdeps/posix/libc_fatal.c b/sysdeps/posix/libc_fatal.c
|
||||
index 6d24bee6134856d1..1feacfbeba765035 100644
|
||||
--- a/sysdeps/posix/libc_fatal.c
|
||||
+++ b/sysdeps/posix/libc_fatal.c
|
||||
@@ -54,7 +54,7 @@ struct str_list
|
||||
|
||||
/* Abort with an error message. */
|
||||
void
|
||||
-__libc_message (enum __libc_message_action action, const char *fmt, ...)
|
||||
+__libc_message (const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int fd = -1;
|
||||
@@ -123,36 +123,31 @@ __libc_message (enum __libc_message_action action, const char *fmt, ...)
|
||||
|
||||
WRITEV_FOR_FATAL (fd, iov, nlist, total);
|
||||
|
||||
- if ((action & do_abort))
|
||||
+ total = (total + 1 + GLRO(dl_pagesize) - 1) & ~(GLRO(dl_pagesize) - 1);
|
||||
+ struct abort_msg_s *buf = __mmap (NULL, total,
|
||||
+ PROT_READ | PROT_WRITE,
|
||||
+ MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
+ if (__glibc_likely (buf != MAP_FAILED))
|
||||
{
|
||||
- total = ((total + 1 + GLRO(dl_pagesize) - 1)
|
||||
- & ~(GLRO(dl_pagesize) - 1));
|
||||
- struct abort_msg_s *buf = __mmap (NULL, total,
|
||||
- PROT_READ | PROT_WRITE,
|
||||
- MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
- if (__glibc_likely (buf != MAP_FAILED))
|
||||
- {
|
||||
- buf->size = total;
|
||||
- char *wp = buf->msg;
|
||||
- for (int cnt = 0; cnt < nlist; ++cnt)
|
||||
- wp = mempcpy (wp, iov[cnt].iov_base, iov[cnt].iov_len);
|
||||
- *wp = '\0';
|
||||
-
|
||||
- /* We have to free the old buffer since the application might
|
||||
- catch the SIGABRT signal. */
|
||||
- struct abort_msg_s *old = atomic_exchange_acq (&__abort_msg,
|
||||
- buf);
|
||||
- if (old != NULL)
|
||||
- __munmap (old, old->size);
|
||||
- }
|
||||
+ buf->size = total;
|
||||
+ char *wp = buf->msg;
|
||||
+ for (int cnt = 0; cnt < nlist; ++cnt)
|
||||
+ wp = mempcpy (wp, iov[cnt].iov_base, iov[cnt].iov_len);
|
||||
+ *wp = '\0';
|
||||
+
|
||||
+ /* We have to free the old buffer since the application might
|
||||
+ catch the SIGABRT signal. */
|
||||
+ struct abort_msg_s *old = atomic_exchange_acq (&__abort_msg,
|
||||
+ buf);
|
||||
+ if (old != NULL)
|
||||
+ __munmap (old, old->size);
|
||||
}
|
||||
}
|
||||
|
||||
va_end (ap);
|
||||
|
||||
- if ((action & do_abort))
|
||||
- /* Kill the application. */
|
||||
- abort ();
|
||||
+ /* Kill the application. */
|
||||
+ abort ();
|
||||
}
|
||||
|
||||
|
||||
@@ -161,6 +156,6 @@ __libc_fatal (const char *message)
|
||||
{
|
||||
/* The loop is added only to keep gcc happy. */
|
||||
while (1)
|
||||
- __libc_message (do_abort, "%s", message);
|
||||
+ __libc_message ("%s", message);
|
||||
}
|
||||
libc_hidden_def (__libc_fatal)
|
@ -0,0 +1,45 @@
|
||||
commit 68e036f27f31c3378201702e182246504fb00f87
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Wed Aug 3 11:41:53 2022 +0200
|
||||
|
||||
nptl: Remove uses of assert_perror
|
||||
|
||||
__pthread_sigmask cannot actually fail with valid pointer arguments
|
||||
(it would need a really broken seccomp filter), and we do not check
|
||||
for errors elsewhere.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/sysdeps/nptl/gai_misc.h b/sysdeps/nptl/gai_misc.h
|
||||
index 261e24dae62d7871..700fd5c46b4b7c82 100644
|
||||
--- a/sysdeps/nptl/gai_misc.h
|
||||
+++ b/sysdeps/nptl/gai_misc.h
|
||||
@@ -81,9 +81,7 @@ __gai_start_notify_thread (void)
|
||||
{
|
||||
sigset_t ss;
|
||||
sigemptyset (&ss);
|
||||
- int sigerr __attribute__ ((unused));
|
||||
- sigerr = __pthread_sigmask (SIG_SETMASK, &ss, NULL);
|
||||
- assert_perror (sigerr);
|
||||
+ (void) __pthread_sigmask (SIG_SETMASK, &ss, NULL);
|
||||
}
|
||||
|
||||
extern inline int
|
||||
@@ -106,15 +104,12 @@ __gai_create_helper_thread (pthread_t *threadp, void *(*tf) (void *),
|
||||
sigset_t ss;
|
||||
sigset_t oss;
|
||||
sigfillset (&ss);
|
||||
- int sigerr __attribute__ ((unused));
|
||||
- sigerr = __pthread_sigmask (SIG_SETMASK, &ss, &oss);
|
||||
- assert_perror (sigerr);
|
||||
+ (void) __pthread_sigmask (SIG_SETMASK, &ss, &oss);
|
||||
|
||||
int ret = __pthread_create (threadp, &attr, tf, arg);
|
||||
|
||||
/* Restore the signal mask. */
|
||||
- sigerr = __pthread_sigmask (SIG_SETMASK, &oss, NULL);
|
||||
- assert_perror (sigerr);
|
||||
+ (void) __pthread_sigmask (SIG_SETMASK, &oss, NULL);
|
||||
|
||||
(void) __pthread_attr_destroy (&attr);
|
||||
return ret;
|
@ -0,0 +1,164 @@
|
||||
commit 9001cb1102cddba54f0e84e147dfbb0356067356
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Wed Aug 3 11:41:53 2022 +0200
|
||||
|
||||
assert: Do not use stderr in libc-internal assert
|
||||
|
||||
Redirect internal assertion failures to __libc_assert_fail, based on
|
||||
based on __libc_message, which writes directly to STDERR_FILENO
|
||||
and calls abort. Also disable message translation and reword the
|
||||
error message slightly (adjusting stdlib/tst-bz20544 accordingly).
|
||||
|
||||
As a result of these changes, malloc no longer needs its own
|
||||
redefinition of __assert_fail.
|
||||
|
||||
__libc_assert_fail needs to be stubbed out during rtld dependency
|
||||
analysis because the rtld rebuilds turn __libc_assert_fail into
|
||||
__assert_fail, which is unconditionally provided by elf/dl-minimal.c.
|
||||
|
||||
This change is not possible for the public assert macro and its
|
||||
__assert_fail function because POSIX requires that the diagnostic
|
||||
is written to stderr.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/assert/Makefile b/assert/Makefile
|
||||
index 0008de34cb484a13..2bc9e2214e3e9a8b 100644
|
||||
--- a/assert/Makefile
|
||||
+++ b/assert/Makefile
|
||||
@@ -24,7 +24,12 @@ include ../Makeconfig
|
||||
|
||||
headers := assert.h
|
||||
|
||||
-routines := assert assert-perr __assert
|
||||
+routines := \
|
||||
+ __assert \
|
||||
+ __libc_assert_fail \
|
||||
+ assert \
|
||||
+ assert-perr \
|
||||
+ # routines
|
||||
tests := test-assert test-assert-perr tst-assert-c++ tst-assert-g++
|
||||
|
||||
ifeq ($(have-cxx-thread_local),yes)
|
||||
diff --git a/assert/__libc_assert_fail.c b/assert/__libc_assert_fail.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..149d5feae12f4af8
|
||||
--- /dev/null
|
||||
+++ b/assert/__libc_assert_fail.c
|
||||
@@ -0,0 +1,33 @@
|
||||
+/* libc-internal assert that calls __libc_message.
|
||||
+ 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/>. */
|
||||
+
|
||||
+#include <_itoa.h>
|
||||
+#include <array_length.h>
|
||||
+#include <intprops.h>
|
||||
+#include <stdio.h>
|
||||
+
|
||||
+void
|
||||
+__libc_assert_fail (const char *assertion, const char *file, unsigned int line,
|
||||
+ const char *function)
|
||||
+{
|
||||
+ char linebuf[INT_BUFSIZE_BOUND (unsigned int)];
|
||||
+ array_end (linebuf)[-1] = '\0';
|
||||
+ char *linestr = _itoa_word (line, array_end (linebuf) - 1, 10, 0);
|
||||
+ __libc_message ("Fatal glibc error: %s:%s (%s): assertion failed: %s\n",
|
||||
+ file, linestr, function, assertion);
|
||||
+}
|
||||
diff --git a/assert/assert.c b/assert/assert.c
|
||||
index 8a277dce008b3495..989126c7e5b6b265 100644
|
||||
--- a/assert/assert.c
|
||||
+++ b/assert/assert.c
|
||||
@@ -101,4 +101,3 @@ __assert_fail (const char *assertion, const char *file, unsigned int line,
|
||||
__assert_fail_base (_("%s%s%s:%u: %s%sAssertion `%s' failed.\n%n"),
|
||||
assertion, file, line, function);
|
||||
}
|
||||
-hidden_def(__assert_fail)
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 613d244e7781d479..2b547d5b58f1759b 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -1158,6 +1158,7 @@ $(objpfx)dl-allobjs.os: $(all-rtld-routines:%=$(objpfx)%.os)
|
||||
rtld-stubbed-symbols = \
|
||||
__GI___pthread_disable_asynccancel \
|
||||
__GI___pthread_enable_asynccancel \
|
||||
+ __libc_assert_fail \
|
||||
__pthread_disable_asynccancel \
|
||||
__pthread_enable_asynccancel \
|
||||
calloc \
|
||||
diff --git a/include/assert.h b/include/assert.h
|
||||
index 61cc8aa22ff4b913..c812808f9b767964 100644
|
||||
--- a/include/assert.h
|
||||
+++ b/include/assert.h
|
||||
@@ -20,8 +20,14 @@ extern void __assert_fail_base (const char *fmt, const char *assertion,
|
||||
const char *function)
|
||||
__THROW __attribute__ ((__noreturn__)) attribute_hidden;
|
||||
|
||||
-# if IS_IN (libc) || (IS_IN (rtld) && !defined NO_RTLD_HIDDEN)
|
||||
-hidden_proto (__assert_fail)
|
||||
-hidden_proto (__assert_perror_fail)
|
||||
+rtld_hidden_proto (__assert_fail)
|
||||
+rtld_hidden_proto (__assert_perror_fail)
|
||||
+libc_hidden_proto (__assert_perror_fail)
|
||||
+
|
||||
+
|
||||
+# if IS_IN (libc)
|
||||
+/* Redirect to the internal version which does not use stderr. */
|
||||
+extern _Noreturn __typeof (__assert_fail) __libc_assert_fail attribute_hidden;
|
||||
+# define __assert_fail __libc_assert_fail
|
||||
# endif
|
||||
#endif
|
||||
diff --git a/malloc/malloc.c b/malloc/malloc.c
|
||||
index 918e7936f1983437..2edb469d5dbf1203 100644
|
||||
--- a/malloc/malloc.c
|
||||
+++ b/malloc/malloc.c
|
||||
@@ -289,22 +289,6 @@
|
||||
#define MALLOC_DEBUG 0
|
||||
#endif
|
||||
|
||||
-#if IS_IN (libc)
|
||||
-#ifndef NDEBUG
|
||||
-# define __assert_fail(assertion, file, line, function) \
|
||||
- __malloc_assert(assertion, file, line, function)
|
||||
-
|
||||
-_Noreturn static void
|
||||
-__malloc_assert (const char *assertion, const char *file, unsigned int line,
|
||||
- const char *function)
|
||||
-{
|
||||
- __libc_message ("Fatal glibc error: malloc assertion failure in %s: %s\n",
|
||||
- function, assertion);
|
||||
- __builtin_unreachable ();
|
||||
-}
|
||||
-#endif
|
||||
-#endif
|
||||
-
|
||||
#if USE_TCACHE
|
||||
/* We want 64 entries. This is an arbitrary limit, which tunables can reduce. */
|
||||
# define TCACHE_MAX_BINS 64
|
||||
diff --git a/stdlib/tst-bz20544.c b/stdlib/tst-bz20544.c
|
||||
index 4aa5793b8994d1f6..1337a3952c30e517 100644
|
||||
--- a/stdlib/tst-bz20544.c
|
||||
+++ b/stdlib/tst-bz20544.c
|
||||
@@ -78,7 +78,7 @@ test_bz20544_cxa_at_quick_exit (void *closure)
|
||||
static void
|
||||
test_one_fn (void (*test_fn) (void *))
|
||||
{
|
||||
- const char expected_error[] = "Assertion `func != NULL' failed.\n";
|
||||
+ const char expected_error[] = "assertion failed: func != NULL\n";
|
||||
struct support_capture_subprocess result;
|
||||
result = support_capture_subprocess (test_fn, NULL);
|
||||
support_capture_subprocess_check (&result, "bz20544", -SIGABRT,
|
@ -0,0 +1,22 @@
|
||||
commit 8fabe0e632bd441c760f878d1022c378f04f8497
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu Aug 4 06:17:50 2022 +0200
|
||||
|
||||
Linux: Remove exit system call from _exit
|
||||
|
||||
exit only terminates the current thread, not the whole process, so it
|
||||
is the wrong fallback system call in this context. All supported
|
||||
Linux versions implement the exit_group system call anyway.
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/_exit.c b/sysdeps/unix/sysv/linux/_exit.c
|
||||
index 2f0ec35459f25314..cd1270ac9b2b5b2b 100644
|
||||
--- a/sysdeps/unix/sysv/linux/_exit.c
|
||||
+++ b/sysdeps/unix/sysv/linux/_exit.c
|
||||
@@ -28,7 +28,6 @@ _exit (int status)
|
||||
while (1)
|
||||
{
|
||||
INLINE_SYSCALL (exit_group, 1, status);
|
||||
- INLINE_SYSCALL (exit, 1, status);
|
||||
|
||||
#ifdef ABORT_INSTRUCTION
|
||||
ABORT_INSTRUCTION;
|
@ -0,0 +1,69 @@
|
||||
Very limited backport of the following upstream commit, to obtain
|
||||
the definition of __getrandom_nocancel.
|
||||
|
||||
commit 6f4e0fcfa2d2b0915816a3a3a1d48b4763a7dee2
|
||||
Author: Adhemerval Zanella Netto <adhemerval.zanella@linaro.org>
|
||||
Date: Thu Jul 21 10:04:59 2022 -0300
|
||||
|
||||
stdlib: Add arc4random, arc4random_buf, and arc4random_uniform (BZ #4417)
|
||||
|
||||
With the INTERNAL_SYSCALL_CALL change from this patch already applied:
|
||||
|
||||
commit 609c9d0951da387cd523b5db42a82d38dabc37c4
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Thu Sep 29 16:18:06 2022 -0300
|
||||
|
||||
malloc: Do not clobber errno on __getrandom_nocancel (BZ #29624)
|
||||
|
||||
Use INTERNAL_SYSCALL_CALL instead of INLINE_SYSCALL_CALL. This
|
||||
requires emulate the semantic for hurd call (so __arc4random_buf
|
||||
uses the fallback).
|
||||
|
||||
Checked on x86_64-linux-gnu.
|
||||
|
||||
Reviewed-by: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
|
||||
|
||||
diff --git a/sysdeps/generic/not-cancel.h b/sysdeps/generic/not-cancel.h
|
||||
index 8a3772a1fe66271e..14188041c2c0ad57 100644
|
||||
--- a/sysdeps/generic/not-cancel.h
|
||||
+++ b/sysdeps/generic/not-cancel.h
|
||||
@@ -49,5 +49,7 @@
|
||||
(void) __writev (fd, iov, n)
|
||||
#define __fcntl64_nocancel(fd, cmd, ...) \
|
||||
__fcntl64 (fd, cmd, __VA_ARGS__)
|
||||
+#define __getrandom_nocancel(buf, size, flags) \
|
||||
+ __getrandom (buf, size, flags)
|
||||
|
||||
#endif /* NOT_CANCEL_H */
|
||||
diff --git a/sysdeps/mach/hurd/not-cancel.h b/sysdeps/mach/hurd/not-cancel.h
|
||||
index cd320cb721e6ff7e..7a3d2cc3532cf866 100644
|
||||
--- a/sysdeps/mach/hurd/not-cancel.h
|
||||
+++ b/sysdeps/mach/hurd/not-cancel.h
|
||||
@@ -75,6 +75,9 @@ __typeof (__fcntl) __fcntl_nocancel;
|
||||
#define __fcntl64_nocancel(...) \
|
||||
__fcntl_nocancel (__VA_ARGS__)
|
||||
|
||||
+#define __getrandom_nocancel(buf, size, flags) \
|
||||
+ __getrandom (buf, size, flags)
|
||||
+
|
||||
#if IS_IN (libc)
|
||||
hidden_proto (__close_nocancel)
|
||||
hidden_proto (__close_nocancel_nostatus)
|
||||
diff --git a/sysdeps/unix/sysv/linux/not-cancel.h b/sysdeps/unix/sysv/linux/not-cancel.h
|
||||
index f06d57426a40227e..d2bb59acddbcfee0 100644
|
||||
--- a/sysdeps/unix/sysv/linux/not-cancel.h
|
||||
+++ b/sysdeps/unix/sysv/linux/not-cancel.h
|
||||
@@ -68,6 +68,13 @@ __writev_nocancel_nostatus (int fd, const struct iovec *iov, int iovcnt)
|
||||
INTERNAL_SYSCALL_CALL (writev, fd, iov, iovcnt);
|
||||
}
|
||||
|
||||
+static inline int
|
||||
+__getrandom_nocancel (void *buf, size_t buflen, unsigned int flags)
|
||||
+{
|
||||
+ return INTERNAL_SYSCALL_CALL (getrandom, buf, buflen, flags);
|
||||
+}
|
||||
+
|
||||
+
|
||||
/* Uncancelable fcntl. */
|
||||
__typeof (__fcntl) __fcntl64_nocancel;
|
||||
|
@ -0,0 +1,35 @@
|
||||
commit 7187efd0aa270c83c428ea6cd0e1cffc34b41a74
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Aug 1 15:49:07 2022 +0200
|
||||
|
||||
malloc: Use __getrandom_nocancel during tcache initiailization
|
||||
|
||||
Cancellation currently cannot happen at this point because dlopen
|
||||
as used by the unwind link always performs additional allocations
|
||||
for libgcc_s.so.1, even if it has been loaded already as a dependency
|
||||
of the main executable. But it seems prudent not to rely on this
|
||||
quirk.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/malloc/malloc.c b/malloc/malloc.c
|
||||
index 2edb469d5dbf1203..375f50f5db13e234 100644
|
||||
--- a/malloc/malloc.c
|
||||
+++ b/malloc/malloc.c
|
||||
@@ -256,6 +256,7 @@
|
||||
/* For tcache double-free check. */
|
||||
#include <random-bits.h>
|
||||
#include <sys/random.h>
|
||||
+#include <not-cancel.h>
|
||||
|
||||
/*
|
||||
Debugging:
|
||||
@@ -3025,7 +3026,7 @@ static uintptr_t tcache_key;
|
||||
static void
|
||||
tcache_key_initialize (void)
|
||||
{
|
||||
- if (__getrandom (&tcache_key, sizeof(tcache_key), GRND_NONBLOCK)
|
||||
+ if (__getrandom_nocancel (&tcache_key, sizeof(tcache_key), GRND_NONBLOCK)
|
||||
!= sizeof (tcache_key))
|
||||
{
|
||||
tcache_key = random_bits ();
|
@ -0,0 +1,94 @@
|
||||
commit dd2315a866a4ac2b838ea1cb10c5ea1c35d51a2f
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Aug 16 08:27:50 2022 +0200
|
||||
|
||||
elf: Run tst-audit-tlsdesc, tst-audit-tlsdesc-dlopen everywhere
|
||||
|
||||
The test is valid for all TLS models, but we want to make a reasonable
|
||||
effort to test the GNU2 model specifically. For example, aarch64
|
||||
defaults to GNU2, but does not have -mtls-dialect=gnu2, and the test
|
||||
was not run there.
|
||||
|
||||
Suggested-by: Martin Coufal <mcoufal@redhat.com>
|
||||
|
||||
Conflicts:
|
||||
elf/Makefile
|
||||
(missing tst-align3 test downstream)
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index ea1512549be3f628..613d244e7781d479 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -361,6 +361,8 @@ tests += \
|
||||
tst-addr1 \
|
||||
tst-align \
|
||||
tst-align2 \
|
||||
+ tst-audit-tlsdesc \
|
||||
+ tst-audit-tlsdesc-dlopen \
|
||||
tst-audit1 \
|
||||
tst-audit2 \
|
||||
tst-audit8 \
|
||||
@@ -679,6 +681,8 @@ modules-names = \
|
||||
tst-alignmod2 \
|
||||
tst-array2dep \
|
||||
tst-array5dep \
|
||||
+ tst-audit-tlsdesc-mod1 \
|
||||
+ tst-audit-tlsdesc-mod2 \
|
||||
tst-audit11mod1 \
|
||||
tst-audit11mod2 \
|
||||
tst-audit12mod1 \
|
||||
@@ -712,6 +716,7 @@ modules-names = \
|
||||
tst-auditmanymod7 \
|
||||
tst-auditmanymod8 \
|
||||
tst-auditmanymod9 \
|
||||
+ tst-auditmod-tlsdesc \
|
||||
tst-auditmod1 \
|
||||
tst-auditmod9a \
|
||||
tst-auditmod9b \
|
||||
@@ -889,23 +894,8 @@ modules-names += tst-gnu2-tls1mod
|
||||
$(objpfx)tst-gnu2-tls1: $(objpfx)tst-gnu2-tls1mod.so
|
||||
tst-gnu2-tls1mod.so-no-z-defs = yes
|
||||
CFLAGS-tst-gnu2-tls1mod.c += -mtls-dialect=gnu2
|
||||
+endif # $(have-mtls-dialect-gnu2)
|
||||
|
||||
-tests += tst-audit-tlsdesc tst-audit-tlsdesc-dlopen
|
||||
-modules-names += tst-audit-tlsdesc-mod1 tst-audit-tlsdesc-mod2 tst-auditmod-tlsdesc
|
||||
-$(objpfx)tst-audit-tlsdesc: $(objpfx)tst-audit-tlsdesc-mod1.so \
|
||||
- $(objpfx)tst-audit-tlsdesc-mod2.so \
|
||||
- $(shared-thread-library)
|
||||
-CFLAGS-tst-audit-tlsdesc-mod1.c += -mtls-dialect=gnu2
|
||||
-CFLAGS-tst-audit-tlsdesc-mod2.c += -mtls-dialect=gnu2
|
||||
-$(objpfx)tst-audit-tlsdesc-dlopen: $(shared-thread-library)
|
||||
-$(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-audit-tlsdesc-mod1.so \
|
||||
- $(objpfx)tst-audit-tlsdesc-mod2.so
|
||||
-$(objpfx)tst-audit-tlsdesc-mod1.so: $(objpfx)tst-audit-tlsdesc-mod2.so
|
||||
-$(objpfx)tst-audit-tlsdesc.out: $(objpfx)tst-auditmod-tlsdesc.so
|
||||
-tst-audit-tlsdesc-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so
|
||||
-$(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-auditmod-tlsdesc.so
|
||||
-tst-audit-tlsdesc-dlopen-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so
|
||||
-endif
|
||||
ifeq (yes,$(have-protected-data))
|
||||
modules-names += tst-protected1moda tst-protected1modb
|
||||
tests += tst-protected1a tst-protected1b
|
||||
@@ -2656,3 +2646,21 @@ $(objpfx)tst-tls-allocation-failure-static-patched.out: \
|
||||
grep -q '^Fatal glibc error: Cannot allocate TLS block$$' $@ \
|
||||
&& grep -q '^status: 127$$' $@; \
|
||||
$(evaluate-test)
|
||||
+
|
||||
+$(objpfx)tst-audit-tlsdesc: $(objpfx)tst-audit-tlsdesc-mod1.so \
|
||||
+ $(objpfx)tst-audit-tlsdesc-mod2.so \
|
||||
+ $(shared-thread-library)
|
||||
+ifeq (yes,$(have-mtls-dialect-gnu2))
|
||||
+# The test is valid for all TLS types, but we want to exercise GNU2
|
||||
+# TLS if possible.
|
||||
+CFLAGS-tst-audit-tlsdesc-mod1.c += -mtls-dialect=gnu2
|
||||
+CFLAGS-tst-audit-tlsdesc-mod2.c += -mtls-dialect=gnu2
|
||||
+endif
|
||||
+$(objpfx)tst-audit-tlsdesc-dlopen: $(shared-thread-library)
|
||||
+$(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-audit-tlsdesc-mod1.so \
|
||||
+ $(objpfx)tst-audit-tlsdesc-mod2.so
|
||||
+$(objpfx)tst-audit-tlsdesc-mod1.so: $(objpfx)tst-audit-tlsdesc-mod2.so
|
||||
+$(objpfx)tst-audit-tlsdesc.out: $(objpfx)tst-auditmod-tlsdesc.so
|
||||
+tst-audit-tlsdesc-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so
|
||||
+$(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-auditmod-tlsdesc.so
|
||||
+tst-audit-tlsdesc-dlopen-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so
|
@ -0,0 +1,37 @@
|
||||
commit 183d99737298bb3200f0610fdcd1c7549c8ed560
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Sep 6 07:38:10 2022 +0200
|
||||
|
||||
scripts/dso-ordering-test.py: Generate program run-time dependencies
|
||||
|
||||
The main program needs to depend on all shared objects, even objects
|
||||
that have link-time dependencies among shared objects. Filtering
|
||||
out shared objects that already have an link-time dependencies is not
|
||||
necessary here; make will do this automatically.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/scripts/dso-ordering-test.py b/scripts/dso-ordering-test.py
|
||||
index bde0406be9da14fc..4ffcff6136145ef1 100644
|
||||
--- a/scripts/dso-ordering-test.py
|
||||
+++ b/scripts/dso-ordering-test.py
|
||||
@@ -707,13 +707,12 @@ def process_testcase(t):
|
||||
"\t$(compile.c) $(OUTPUT_OPTION)\n")
|
||||
makefile.write (rule)
|
||||
|
||||
- not_depended_objs = find_objs_not_depended_on(test_descr)
|
||||
- if not_depended_objs:
|
||||
- depstr = ""
|
||||
- for dep in not_depended_objs:
|
||||
- depstr += (" $(objpfx)" + test_subdir + "/"
|
||||
- + test_name + "-" + dep + ".so")
|
||||
- makefile.write("$(objpfx)%s.out:%s\n" % (base_test_name, depstr))
|
||||
+ # Ensure that all shared objects are built before running the
|
||||
+ # test, whether there link-time dependencies or not.
|
||||
+ depobjs = ["$(objpfx){}/{}-{}.so".format(test_subdir, test_name, dep)
|
||||
+ for dep in test_descr.objs]
|
||||
+ makefile.write("$(objpfx){}.out: {}\n".format(
|
||||
+ base_test_name, " ".join(depobjs)))
|
||||
|
||||
# Add main executable to test-srcs
|
||||
makefile.write("test-srcs += %s/%s\n" % (test_subdir, test_name))
|
@ -0,0 +1,79 @@
|
||||
commit dbb75513f5cf9285c77c9e55777c5c35b653f890
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Sep 6 07:38:10 2022 +0200
|
||||
|
||||
elf: Rename _dl_sort_maps parameter from skip to force_first
|
||||
|
||||
The new implementation will not be able to skip an arbitrary number
|
||||
of objects.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/elf/dl-sort-maps.c b/elf/dl-sort-maps.c
|
||||
index 72f4ff0e6eda3377..7c614bca5d8115c6 100644
|
||||
--- a/elf/dl-sort-maps.c
|
||||
+++ b/elf/dl-sort-maps.c
|
||||
@@ -27,12 +27,12 @@
|
||||
If FOR_FINI is true, this is called for finishing an object. */
|
||||
static void
|
||||
_dl_sort_maps_original (struct link_map **maps, unsigned int nmaps,
|
||||
- unsigned int skip, bool for_fini)
|
||||
+ bool force_first, bool for_fini)
|
||||
{
|
||||
/* Allows caller to do the common optimization of skipping the first map,
|
||||
usually the main binary. */
|
||||
- maps += skip;
|
||||
- nmaps -= skip;
|
||||
+ maps += force_first;
|
||||
+ nmaps -= force_first;
|
||||
|
||||
/* A list of one element need not be sorted. */
|
||||
if (nmaps <= 1)
|
||||
@@ -182,7 +182,7 @@ dfs_traversal (struct link_map ***rpo, struct link_map *map,
|
||||
|
||||
static void
|
||||
_dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps,
|
||||
- unsigned int skip __attribute__ ((unused)), bool for_fini)
|
||||
+ bool force_first __attribute__ ((unused)), bool for_fini)
|
||||
{
|
||||
for (int i = nmaps - 1; i >= 0; i--)
|
||||
maps[i]->l_visited = 0;
|
||||
@@ -286,7 +286,7 @@ _dl_sort_maps_init (void)
|
||||
|
||||
void
|
||||
_dl_sort_maps (struct link_map **maps, unsigned int nmaps,
|
||||
- unsigned int skip, bool for_fini)
|
||||
+ bool force_first, bool for_fini)
|
||||
{
|
||||
/* It can be tempting to use a static function pointer to store and call
|
||||
the current selected sorting algorithm routine, but experimentation
|
||||
@@ -296,9 +296,9 @@ _dl_sort_maps (struct link_map **maps, unsigned int nmaps,
|
||||
input cases. A simple if-case with direct function calls appears to
|
||||
be the fastest. */
|
||||
if (__glibc_likely (GLRO(dl_dso_sort_algo) == dso_sort_algorithm_original))
|
||||
- _dl_sort_maps_original (maps, nmaps, skip, for_fini);
|
||||
+ _dl_sort_maps_original (maps, nmaps, force_first, for_fini);
|
||||
else
|
||||
- _dl_sort_maps_dfs (maps, nmaps, skip, for_fini);
|
||||
+ _dl_sort_maps_dfs (maps, nmaps, force_first, for_fini);
|
||||
}
|
||||
|
||||
#endif /* HAVE_TUNABLES. */
|
||||
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||
index 87ad2f3f4d89eb7d..8c0fe98f69a88f1e 100644
|
||||
--- a/sysdeps/generic/ldsodefs.h
|
||||
+++ b/sysdeps/generic/ldsodefs.h
|
||||
@@ -1106,9 +1106,11 @@ extern void _dl_init (struct link_map *main_map, int argc, char **argv,
|
||||
initializer functions have completed. */
|
||||
extern void _dl_fini (void) attribute_hidden;
|
||||
|
||||
-/* Sort array MAPS according to dependencies of the contained objects. */
|
||||
+/* Sort array MAPS according to dependencies of the contained objects.
|
||||
+ If FORCE_FIRST, MAPS[0] keeps its place even if the dependencies
|
||||
+ say otherwise. */
|
||||
extern void _dl_sort_maps (struct link_map **maps, unsigned int nmaps,
|
||||
- unsigned int skip, bool for_fini) attribute_hidden;
|
||||
+ bool force_first, bool for_fini) attribute_hidden;
|
||||
|
||||
/* The dynamic linker calls this function before and having changing
|
||||
any shared object mappings. The `r_state' member of `struct r_debug'
|
@ -0,0 +1,90 @@
|
||||
commit 1df71d32fe5f5905ffd5d100e5e9ca8ad6210891
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Sep 20 11:00:42 2022 +0200
|
||||
|
||||
elf: Implement force_first handling in _dl_sort_maps_dfs (bug 28937)
|
||||
|
||||
The implementation in _dl_close_worker requires that the first
|
||||
element of l_initfini is always this very map (“We are always the
|
||||
zeroth entry, and since we don't include ourselves in the
|
||||
dependency analysis start at 1.”). Rather than fixing that
|
||||
assumption, this commit adds an implementation of the force_first
|
||||
argument to the new dependency sorting algorithm. This also means
|
||||
that the directly dlopen'ed shared object is always initialized last,
|
||||
which is the least surprising behavior in the presence of cycles.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/elf/dl-sort-maps.c b/elf/dl-sort-maps.c
|
||||
index 7c614bca5d8115c6..e8ef5e8b3588ab53 100644
|
||||
--- a/elf/dl-sort-maps.c
|
||||
+++ b/elf/dl-sort-maps.c
|
||||
@@ -182,8 +182,9 @@ dfs_traversal (struct link_map ***rpo, struct link_map *map,
|
||||
|
||||
static void
|
||||
_dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps,
|
||||
- bool force_first __attribute__ ((unused)), bool for_fini)
|
||||
+ bool force_first, bool for_fini)
|
||||
{
|
||||
+ struct link_map *first_map = maps[0];
|
||||
for (int i = nmaps - 1; i >= 0; i--)
|
||||
maps[i]->l_visited = 0;
|
||||
|
||||
@@ -208,14 +209,6 @@ _dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps,
|
||||
Adjusting the order so that maps[0] is last traversed naturally avoids
|
||||
this problem.
|
||||
|
||||
- Further, the old "optimization" of skipping the main object at maps[0]
|
||||
- from the call-site (i.e. _dl_sort_maps(maps+1,nmaps-1)) is in general
|
||||
- no longer valid, since traversing along object dependency-links
|
||||
- may "find" the main object even when it is not included in the initial
|
||||
- order (e.g. a dlopen()'ed shared object can have circular dependencies
|
||||
- linked back to itself). In such a case, traversing N-1 objects will
|
||||
- create a N-object result, and raise problems.
|
||||
-
|
||||
To summarize, just passing in the full list, and iterating from back
|
||||
to front makes things much more straightforward. */
|
||||
|
||||
@@ -274,6 +267,27 @@ _dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps,
|
||||
}
|
||||
|
||||
memcpy (maps, rpo, sizeof (struct link_map *) * nmaps);
|
||||
+
|
||||
+ /* Skipping the first object at maps[0] is not valid in general,
|
||||
+ since traversing along object dependency-links may "find" that
|
||||
+ first object even when it is not included in the initial order
|
||||
+ (e.g., a dlopen'ed shared object can have circular dependencies
|
||||
+ linked back to itself). In such a case, traversing N-1 objects
|
||||
+ will create a N-object result, and raise problems. Instead,
|
||||
+ force the object back into first place after sorting. This naive
|
||||
+ approach may introduce further dependency ordering violations
|
||||
+ compared to rotating the cycle until the first map is again in
|
||||
+ the first position, but as there is a cycle, at least one
|
||||
+ violation is already present. */
|
||||
+ if (force_first && maps[0] != first_map)
|
||||
+ {
|
||||
+ int i;
|
||||
+ for (i = 0; maps[i] != first_map; ++i)
|
||||
+ ;
|
||||
+ assert (i < nmaps);
|
||||
+ memmove (&maps[1], maps, i * sizeof (maps[0]));
|
||||
+ maps[0] = first_map;
|
||||
+ }
|
||||
}
|
||||
|
||||
void
|
||||
diff --git a/elf/dso-sort-tests-1.def b/elf/dso-sort-tests-1.def
|
||||
index 5f7f18ef270bc12d..4bf9052db16fb352 100644
|
||||
--- a/elf/dso-sort-tests-1.def
|
||||
+++ b/elf/dso-sort-tests-1.def
|
||||
@@ -64,3 +64,10 @@ output: b>a>{}<a<b
|
||||
tst-bz15311: {+a;+e;+f;+g;+d;%d;-d;-g;-f;-e;-a};a->b->c->d;d=>[ba];c=>a;b=>e=>a;c=>f=>b;d=>g=>c
|
||||
output(glibc.rtld.dynamic_sort=1): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<a<c<d<g<f<b<e];}
|
||||
output(glibc.rtld.dynamic_sort=2): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<g<f<a<b<c<d<e];}
|
||||
+
|
||||
+# Test that even in the presence of dependency loops involving dlopen'ed
|
||||
+# object, that object is initialized last (and not unloaded prematurely).
|
||||
+# Final destructor order is indeterminate due to the cycle.
|
||||
+tst-bz28937: {+a;+b;-b;+c;%c};a->a1;a->a2;a2->a;b->b1;c->a1;c=>a1
|
||||
+output(glibc.rtld.dynamic_sort=1): {+a[a2>a1>a>];+b[b1>b>];-b[<b<b1];+c[c>];%c(a1());}<a<a2<c<a1
|
||||
+output(glibc.rtld.dynamic_sort=2): {+a[a2>a1>a>];+b[b1>b>];-b[<b<b1];+c[c>];%c(a1());}<a2<a<c<a1
|
@ -0,0 +1,589 @@
|
||||
commit 1d495912a746e2a1ffb780c9a81fd234ec2464e8
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Aug 30 10:02:49 2022 +0200
|
||||
|
||||
nss_dns: Rewrite _nss_dns_gethostbyname4_r using current interfaces
|
||||
|
||||
Introduce struct alloc_buffer to this function, and use it and
|
||||
struct ns_rr_cursor in gaih_getanswer_slice. Adjust gaih_getanswer
|
||||
and gaih_getanswer_noaaaa accordingly.
|
||||
|
||||
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
|
||||
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
|
||||
index 1cb3be71f04d98eb..36789965c06757d0 100644
|
||||
--- a/resolv/nss_dns/dns-host.c
|
||||
+++ b/resolv/nss_dns/dns-host.c
|
||||
@@ -101,13 +101,6 @@
|
||||
#endif
|
||||
#define MAXHOSTNAMELEN 256
|
||||
|
||||
-/* We need this time later. */
|
||||
-typedef union querybuf
|
||||
-{
|
||||
- HEADER hdr;
|
||||
- u_char buf[MAXPACKET];
|
||||
-} querybuf;
|
||||
-
|
||||
/* For historic reasons, pointers to IP addresses are char *, so use a
|
||||
single list type for addresses and host names. */
|
||||
#define DYNARRAY_STRUCT ptrlist
|
||||
@@ -126,18 +119,18 @@ static enum nss_status getanswer_ptr (unsigned char *packet, size_t packetlen,
|
||||
char **hnamep, int *errnop,
|
||||
int *h_errnop, int32_t *ttlp);
|
||||
|
||||
-static enum nss_status gaih_getanswer (const querybuf *answer1, int anslen1,
|
||||
- const querybuf *answer2, int anslen2,
|
||||
- const char *qname,
|
||||
+static enum nss_status gaih_getanswer (unsigned char *packet1,
|
||||
+ size_t packet1len,
|
||||
+ unsigned char *packet2,
|
||||
+ size_t packet2len,
|
||||
+ struct alloc_buffer *abuf,
|
||||
struct gaih_addrtuple **pat,
|
||||
- char *buffer, size_t buflen,
|
||||
int *errnop, int *h_errnop,
|
||||
int32_t *ttlp);
|
||||
-static enum nss_status gaih_getanswer_noaaaa (const querybuf *answer1,
|
||||
- int anslen1,
|
||||
- const char *qname,
|
||||
+static enum nss_status gaih_getanswer_noaaaa (unsigned char *packet,
|
||||
+ size_t packetlen,
|
||||
+ struct alloc_buffer *abuf,
|
||||
struct gaih_addrtuple **pat,
|
||||
- char *buffer, size_t buflen,
|
||||
int *errnop, int *h_errnop,
|
||||
int32_t *ttlp);
|
||||
|
||||
@@ -409,17 +402,13 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
|
||||
name = cp;
|
||||
}
|
||||
|
||||
- union
|
||||
- {
|
||||
- querybuf *buf;
|
||||
- u_char *ptr;
|
||||
- } host_buffer;
|
||||
- querybuf *orig_host_buffer;
|
||||
- host_buffer.buf = orig_host_buffer = (querybuf *) alloca (2048);
|
||||
+ unsigned char dns_packet_buffer[2048];
|
||||
+ unsigned char *alt_dns_packet_buffer = dns_packet_buffer;
|
||||
u_char *ans2p = NULL;
|
||||
int nans2p = 0;
|
||||
int resplen2 = 0;
|
||||
int ans2p_malloced = 0;
|
||||
+ struct alloc_buffer abuf = alloc_buffer_create (buffer, buflen);
|
||||
|
||||
|
||||
int olderr = errno;
|
||||
@@ -428,22 +417,21 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
|
||||
if ((ctx->resp->options & RES_NOAAAA) == 0)
|
||||
{
|
||||
n = __res_context_search (ctx, name, C_IN, T_QUERY_A_AND_AAAA,
|
||||
- host_buffer.buf->buf, 2048, &host_buffer.ptr,
|
||||
- &ans2p, &nans2p, &resplen2, &ans2p_malloced);
|
||||
+ dns_packet_buffer, sizeof (dns_packet_buffer),
|
||||
+ &alt_dns_packet_buffer, &ans2p, &nans2p,
|
||||
+ &resplen2, &ans2p_malloced);
|
||||
if (n >= 0)
|
||||
- status = gaih_getanswer (host_buffer.buf, n, (const querybuf *) ans2p,
|
||||
- resplen2, name, pat, buffer, buflen,
|
||||
- errnop, herrnop, ttlp);
|
||||
+ status = gaih_getanswer (alt_dns_packet_buffer, n, ans2p, resplen2,
|
||||
+ &abuf, pat, errnop, herrnop, ttlp);
|
||||
}
|
||||
else
|
||||
{
|
||||
n = __res_context_search (ctx, name, C_IN, T_A,
|
||||
- host_buffer.buf->buf, 2048, NULL,
|
||||
- NULL, NULL, NULL, NULL);
|
||||
+ dns_packet_buffer, sizeof (dns_packet_buffer),
|
||||
+ NULL, NULL, NULL, NULL, NULL);
|
||||
if (n >= 0)
|
||||
- status = gaih_getanswer_noaaaa (host_buffer.buf, n,
|
||||
- name, pat, buffer, buflen,
|
||||
- errnop, herrnop, ttlp);
|
||||
+ status = gaih_getanswer_noaaaa (alt_dns_packet_buffer, n,
|
||||
+ &abuf, pat, errnop, herrnop, ttlp);
|
||||
}
|
||||
if (n < 0)
|
||||
{
|
||||
@@ -474,12 +462,20 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
|
||||
__set_errno (olderr);
|
||||
}
|
||||
|
||||
+ /* Implement the buffer resizing protocol. */
|
||||
+ if (alloc_buffer_has_failed (&abuf))
|
||||
+ {
|
||||
+ *errnop = ERANGE;
|
||||
+ *herrnop = NETDB_INTERNAL;
|
||||
+ status = NSS_STATUS_TRYAGAIN;
|
||||
+ }
|
||||
+
|
||||
/* Check whether ans2p was separately allocated. */
|
||||
if (ans2p_malloced)
|
||||
free (ans2p);
|
||||
|
||||
- if (host_buffer.buf != orig_host_buffer)
|
||||
- free (host_buffer.buf);
|
||||
+ if (alt_dns_packet_buffer != dns_packet_buffer)
|
||||
+ free (alt_dns_packet_buffer);
|
||||
|
||||
__resolv_context_put (ctx);
|
||||
return status;
|
||||
@@ -893,259 +889,152 @@ getanswer_ptr (unsigned char *packet, size_t packetlen,
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
+/* Parses DNS data found in PACKETLEN bytes at PACKET in struct
|
||||
+ gaih_addrtuple address tuples. The new address tuples are linked
|
||||
+ from **TAILP, with backing store allocated from ABUF, and *TAILP is
|
||||
+ updated to point where the next tuple pointer should be stored. If
|
||||
+ TTLP is not null, *TTLP is updated to reflect the minimum TTL. If
|
||||
+ STORE_CANON is true, the canonical name is stored as part of the
|
||||
+ first address tuple being written. */
|
||||
static enum nss_status
|
||||
-gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
|
||||
- struct gaih_addrtuple ***patp,
|
||||
- char **bufferp, size_t *buflenp,
|
||||
- int *errnop, int *h_errnop, int32_t *ttlp, int *firstp)
|
||||
+gaih_getanswer_slice (unsigned char *packet, size_t packetlen,
|
||||
+ struct alloc_buffer *abuf,
|
||||
+ struct gaih_addrtuple ***tailp,
|
||||
+ int *errnop, int *h_errnop, int32_t *ttlp,
|
||||
+ bool store_canon)
|
||||
{
|
||||
- char *buffer = *bufferp;
|
||||
- size_t buflen = *buflenp;
|
||||
-
|
||||
- struct gaih_addrtuple **pat = *patp;
|
||||
- const HEADER *hp = &answer->hdr;
|
||||
- int ancount = ntohs (hp->ancount);
|
||||
- int qdcount = ntohs (hp->qdcount);
|
||||
- const u_char *cp = answer->buf + HFIXEDSZ;
|
||||
- const u_char *end_of_message = answer->buf + anslen;
|
||||
- if (__glibc_unlikely (qdcount != 1))
|
||||
- {
|
||||
- *h_errnop = NO_RECOVERY;
|
||||
- return NSS_STATUS_UNAVAIL;
|
||||
- }
|
||||
-
|
||||
- u_char packtmp[NS_MAXCDNAME];
|
||||
- int n = __ns_name_unpack (answer->buf, end_of_message, cp,
|
||||
- packtmp, sizeof packtmp);
|
||||
- /* We unpack the name to check it for validity. But we do not need
|
||||
- it later. */
|
||||
- if (n != -1 && __ns_name_ntop (packtmp, buffer, buflen) == -1)
|
||||
- {
|
||||
- if (__glibc_unlikely (errno == EMSGSIZE))
|
||||
- {
|
||||
- too_small:
|
||||
- *errnop = ERANGE;
|
||||
- *h_errnop = NETDB_INTERNAL;
|
||||
- return NSS_STATUS_TRYAGAIN;
|
||||
- }
|
||||
-
|
||||
- n = -1;
|
||||
- }
|
||||
-
|
||||
- if (__glibc_unlikely (n < 0))
|
||||
- {
|
||||
- *errnop = errno;
|
||||
- *h_errnop = NO_RECOVERY;
|
||||
- return NSS_STATUS_UNAVAIL;
|
||||
- }
|
||||
- if (__glibc_unlikely (__libc_res_hnok (buffer) == 0))
|
||||
+ struct ns_rr_cursor c;
|
||||
+ if (!__ns_rr_cursor_init (&c, packet, packetlen))
|
||||
{
|
||||
- errno = EBADMSG;
|
||||
- *errnop = EBADMSG;
|
||||
+ /* This should not happen because __res_context_query already
|
||||
+ perfroms response validation. */
|
||||
*h_errnop = NO_RECOVERY;
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
- cp += n + QFIXEDSZ;
|
||||
+ bool haveanswer = false; /* Set to true if at least one address. */
|
||||
+ uint16_t qtype = ns_rr_cursor_qtype (&c);
|
||||
+ int ancount = ns_rr_cursor_ancount (&c);
|
||||
+ const unsigned char *expected_name = ns_rr_cursor_qname (&c);
|
||||
+ /* expected_name may be updated to point into this buffer. */
|
||||
+ unsigned char name_buffer[NS_MAXCDNAME];
|
||||
|
||||
- int haveanswer = 0;
|
||||
- int had_error = 0;
|
||||
- char *canon = NULL;
|
||||
- char *h_name = NULL;
|
||||
- int h_namelen = 0;
|
||||
+ /* This is a pointer to a possibly-compressed name in the packet.
|
||||
+ Eventually it is equivalent to the canonical name. If needed, it
|
||||
+ is uncompressed and translated to text form when the first
|
||||
+ address tuple is encountered. */
|
||||
+ const unsigned char *compressed_alias_name = expected_name;
|
||||
|
||||
- if (ancount == 0)
|
||||
+ if (ancount == 0 || !__res_binary_hnok (compressed_alias_name))
|
||||
{
|
||||
*h_errnop = HOST_NOT_FOUND;
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
|
||||
- while (ancount-- > 0 && cp < end_of_message && had_error == 0)
|
||||
+ for (; ancount > -0; --ancount)
|
||||
{
|
||||
- n = __ns_name_unpack (answer->buf, end_of_message, cp,
|
||||
- packtmp, sizeof packtmp);
|
||||
- if (n != -1 &&
|
||||
- (h_namelen = __ns_name_ntop (packtmp, buffer, buflen)) == -1)
|
||||
- {
|
||||
- if (__glibc_unlikely (errno == EMSGSIZE))
|
||||
- goto too_small;
|
||||
-
|
||||
- n = -1;
|
||||
- }
|
||||
- if (__glibc_unlikely (n < 0))
|
||||
- {
|
||||
- ++had_error;
|
||||
- continue;
|
||||
- }
|
||||
- if (*firstp && canon == NULL && __libc_res_hnok (buffer))
|
||||
- {
|
||||
- h_name = buffer;
|
||||
- buffer += h_namelen;
|
||||
- buflen -= h_namelen;
|
||||
- }
|
||||
-
|
||||
- cp += n; /* name */
|
||||
-
|
||||
- if (__glibc_unlikely (cp + 10 > end_of_message))
|
||||
- {
|
||||
- ++had_error;
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- uint16_t type;
|
||||
- NS_GET16 (type, cp);
|
||||
- uint16_t class;
|
||||
- NS_GET16 (class, cp);
|
||||
- int32_t ttl;
|
||||
- NS_GET32 (ttl, cp);
|
||||
- NS_GET16 (n, cp); /* RDATA length. */
|
||||
-
|
||||
- if (end_of_message - cp < n)
|
||||
+ struct ns_rr_wire rr;
|
||||
+ if (!__ns_rr_cursor_next (&c, &rr))
|
||||
{
|
||||
- /* RDATA extends beyond the end of the packet. */
|
||||
- ++had_error;
|
||||
- continue;
|
||||
+ *h_errnop = NO_RECOVERY;
|
||||
+ return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
- if (class != C_IN)
|
||||
- {
|
||||
- cp += n;
|
||||
- continue;
|
||||
- }
|
||||
+ /* Update TTL for known record types. */
|
||||
+ if ((rr.rtype == T_CNAME || rr.rtype == qtype)
|
||||
+ && ttlp != NULL && *ttlp > rr.ttl)
|
||||
+ *ttlp = rr.ttl;
|
||||
|
||||
- if (type == T_CNAME)
|
||||
+ if (rr.rtype == T_CNAME)
|
||||
{
|
||||
- char tbuf[MAXDNAME];
|
||||
-
|
||||
- /* A CNAME could also have a TTL entry. */
|
||||
- if (ttlp != NULL && ttl < *ttlp)
|
||||
- *ttlp = ttl;
|
||||
-
|
||||
- n = __libc_dn_expand (answer->buf, end_of_message, cp,
|
||||
- tbuf, sizeof tbuf);
|
||||
- if (__glibc_unlikely (n < 0))
|
||||
- {
|
||||
- ++had_error;
|
||||
- continue;
|
||||
- }
|
||||
- cp += n;
|
||||
-
|
||||
- if (*firstp && __libc_res_hnok (tbuf))
|
||||
+ /* NB: No check for owner name match, based on historic
|
||||
+ precedent. Record the CNAME target as the new expected
|
||||
+ name. */
|
||||
+ int n = __ns_name_unpack (c.begin, c.end, rr.rdata,
|
||||
+ name_buffer, sizeof (name_buffer));
|
||||
+ if (n < 0)
|
||||
{
|
||||
- /* Reclaim buffer space. */
|
||||
- if (h_name + h_namelen == buffer)
|
||||
- {
|
||||
- buffer = h_name;
|
||||
- buflen += h_namelen;
|
||||
- }
|
||||
-
|
||||
- n = strlen (tbuf) + 1;
|
||||
- if (__glibc_unlikely (n > buflen))
|
||||
- goto too_small;
|
||||
- if (__glibc_unlikely (n >= MAXHOSTNAMELEN))
|
||||
- {
|
||||
- ++had_error;
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- canon = buffer;
|
||||
- buffer = __mempcpy (buffer, tbuf, n);
|
||||
- buflen -= n;
|
||||
- h_namelen = 0;
|
||||
+ *h_errnop = NO_RECOVERY;
|
||||
+ return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
- continue;
|
||||
+ expected_name = name_buffer;
|
||||
+ if (store_canon && __res_binary_hnok (name_buffer))
|
||||
+ /* This name can be used as a canonical name. Do not
|
||||
+ translate to text form here to conserve buffer space.
|
||||
+ Point to the compressed name because name_buffer can be
|
||||
+ overwritten with an unusable name later. */
|
||||
+ compressed_alias_name = rr.rdata;
|
||||
}
|
||||
-
|
||||
- /* Stop parsing if we encounter a record with incorrect RDATA
|
||||
- length. */
|
||||
- if (type == T_A || type == T_AAAA)
|
||||
+ else if (rr.rtype == qtype
|
||||
+ && __ns_samebinaryname (rr.rname, expected_name)
|
||||
+ && rr.rdlength == rrtype_to_rdata_length (qtype))
|
||||
{
|
||||
- if (n != rrtype_to_rdata_length (type))
|
||||
+ struct gaih_addrtuple *ntup
|
||||
+ = alloc_buffer_alloc (abuf, struct gaih_addrtuple);
|
||||
+ /* Delay error reporting to the callers (they implement the
|
||||
+ ERANGE buffer resizing handshake). */
|
||||
+ if (ntup != NULL)
|
||||
{
|
||||
- ++had_error;
|
||||
- continue;
|
||||
+ ntup->next = NULL;
|
||||
+ if (store_canon && compressed_alias_name != NULL)
|
||||
+ {
|
||||
+ /* This assumes that all the CNAME records come
|
||||
+ first. Use MAXHOSTNAMELEN instead of
|
||||
+ NS_MAXCDNAME for additional length checking.
|
||||
+ However, these checks are not expected to fail
|
||||
+ because all size NS_MAXCDNAME names should into
|
||||
+ the hname buffer because no escaping is
|
||||
+ needed. */
|
||||
+ char unsigned nbuf[NS_MAXCDNAME];
|
||||
+ char hname[MAXHOSTNAMELEN + 1];
|
||||
+ if (__ns_name_unpack (c.begin, c.end,
|
||||
+ compressed_alias_name,
|
||||
+ nbuf, sizeof (nbuf)) >= 0
|
||||
+ && __ns_name_ntop (nbuf, hname, sizeof (hname)) >= 0)
|
||||
+ /* Space checking is performed by the callers. */
|
||||
+ ntup->name = alloc_buffer_copy_string (abuf, hname);
|
||||
+ store_canon = false;
|
||||
+ }
|
||||
+ else
|
||||
+ ntup->name = NULL;
|
||||
+ if (rr.rdlength == 4)
|
||||
+ ntup->family = AF_INET;
|
||||
+ else
|
||||
+ ntup->family = AF_INET6;
|
||||
+ memcpy (ntup->addr, rr.rdata, rr.rdlength);
|
||||
+ ntup->scopeid = 0;
|
||||
+
|
||||
+ /* Link in the new tuple, and update the tail pointer to
|
||||
+ point to its next field. */
|
||||
+ **tailp = ntup;
|
||||
+ *tailp = &ntup->next;
|
||||
+
|
||||
+ haveanswer = true;
|
||||
}
|
||||
}
|
||||
- else
|
||||
- {
|
||||
- /* Skip unknown records. */
|
||||
- cp += n;
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- assert (type == T_A || type == T_AAAA);
|
||||
- if (*pat == NULL)
|
||||
- {
|
||||
- uintptr_t pad = (-(uintptr_t) buffer
|
||||
- % __alignof__ (struct gaih_addrtuple));
|
||||
- buffer += pad;
|
||||
- buflen = buflen > pad ? buflen - pad : 0;
|
||||
-
|
||||
- if (__glibc_unlikely (buflen < sizeof (struct gaih_addrtuple)))
|
||||
- goto too_small;
|
||||
-
|
||||
- *pat = (struct gaih_addrtuple *) buffer;
|
||||
- buffer += sizeof (struct gaih_addrtuple);
|
||||
- buflen -= sizeof (struct gaih_addrtuple);
|
||||
- }
|
||||
-
|
||||
- (*pat)->name = NULL;
|
||||
- (*pat)->next = NULL;
|
||||
-
|
||||
- if (*firstp)
|
||||
- {
|
||||
- /* We compose a single hostent out of the entire chain of
|
||||
- entries, so the TTL of the hostent is essentially the lowest
|
||||
- TTL in the chain. */
|
||||
- if (ttlp != NULL && ttl < *ttlp)
|
||||
- *ttlp = ttl;
|
||||
-
|
||||
- (*pat)->name = canon ?: h_name;
|
||||
-
|
||||
- *firstp = 0;
|
||||
- }
|
||||
-
|
||||
- (*pat)->family = type == T_A ? AF_INET : AF_INET6;
|
||||
- memcpy ((*pat)->addr, cp, n);
|
||||
- cp += n;
|
||||
- (*pat)->scopeid = 0;
|
||||
-
|
||||
- pat = &((*pat)->next);
|
||||
-
|
||||
- haveanswer = 1;
|
||||
}
|
||||
|
||||
if (haveanswer)
|
||||
{
|
||||
- *patp = pat;
|
||||
- *bufferp = buffer;
|
||||
- *buflenp = buflen;
|
||||
-
|
||||
*h_errnop = NETDB_SUCCESS;
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
-
|
||||
- /* Special case here: if the resolver sent a result but it only
|
||||
- contains a CNAME while we are looking for a T_A or T_AAAA record,
|
||||
- we fail with NOTFOUND instead of TRYAGAIN. */
|
||||
- if (canon != NULL)
|
||||
+ else
|
||||
{
|
||||
+ /* Special case here: if the resolver sent a result but it only
|
||||
+ contains a CNAME while we are looking for a T_A or T_AAAA
|
||||
+ record, we fail with NOTFOUND. */
|
||||
*h_errnop = HOST_NOT_FOUND;
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
-
|
||||
- *h_errnop = NETDB_INTERNAL;
|
||||
- return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
|
||||
static enum nss_status
|
||||
-gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2,
|
||||
- int anslen2, const char *qname,
|
||||
- struct gaih_addrtuple **pat, char *buffer, size_t buflen,
|
||||
+gaih_getanswer (unsigned char *packet1, size_t packet1len,
|
||||
+ unsigned char *packet2, size_t packet2len,
|
||||
+ struct alloc_buffer *abuf, struct gaih_addrtuple **pat,
|
||||
int *errnop, int *h_errnop, int32_t *ttlp)
|
||||
{
|
||||
- int first = 1;
|
||||
-
|
||||
enum nss_status status = NSS_STATUS_NOTFOUND;
|
||||
|
||||
/* Combining the NSS status of two distinct queries requires some
|
||||
@@ -1157,7 +1046,10 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2,
|
||||
between TRYAGAIN (recoverable) and TRYAGAIN' (not-recoverable).
|
||||
A recoverable TRYAGAIN is almost always due to buffer size issues
|
||||
and returns ERANGE in errno and the caller is expected to retry
|
||||
- with a larger buffer.
|
||||
+ with a larger buffer. (The caller, _nss_dns_gethostbyname4_r,
|
||||
+ ignores the return status if it detects that the result buffer
|
||||
+ has been exhausted and generates a TRYAGAIN failure with an
|
||||
+ ERANGE code.)
|
||||
|
||||
Lastly, you may be tempted to make significant changes to the
|
||||
conditions in this code to bring about symmetry between responses.
|
||||
@@ -1237,36 +1129,30 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2,
|
||||
is a recoverable error we now return TRYAGIN even if the first
|
||||
response was SUCCESS. */
|
||||
|
||||
- if (anslen1 > 0)
|
||||
- status = gaih_getanswer_slice(answer1, anslen1, qname,
|
||||
- &pat, &buffer, &buflen,
|
||||
- errnop, h_errnop, ttlp,
|
||||
- &first);
|
||||
-
|
||||
- if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND
|
||||
- || (status == NSS_STATUS_TRYAGAIN
|
||||
- /* We want to look at the second answer in case of an
|
||||
- NSS_STATUS_TRYAGAIN only if the error is non-recoverable, i.e.
|
||||
- *h_errnop is NO_RECOVERY. If not, and if the failure was due to
|
||||
- an insufficient buffer (ERANGE), then we need to drop the results
|
||||
- and pass on the NSS_STATUS_TRYAGAIN to the caller so that it can
|
||||
- repeat the query with a larger buffer. */
|
||||
- && (*errnop != ERANGE || *h_errnop == NO_RECOVERY)))
|
||||
- && answer2 != NULL && anslen2 > 0)
|
||||
+ if (packet1len > 0)
|
||||
{
|
||||
- enum nss_status status2 = gaih_getanswer_slice(answer2, anslen2, qname,
|
||||
- &pat, &buffer, &buflen,
|
||||
- errnop, h_errnop, ttlp,
|
||||
- &first);
|
||||
+ status = gaih_getanswer_slice (packet1, packet1len,
|
||||
+ abuf, &pat, errnop, h_errnop, ttlp, true);
|
||||
+ if (alloc_buffer_has_failed (abuf))
|
||||
+ /* Do not try parsing the second packet if a larger result
|
||||
+ buffer is needed. The caller implements the resizing
|
||||
+ protocol because *abuf has been exhausted. */
|
||||
+ return NSS_STATUS_TRYAGAIN; /* Ignored by the caller. */
|
||||
+ }
|
||||
+
|
||||
+ if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND)
|
||||
+ && packet2 != NULL && packet2len > 0)
|
||||
+ {
|
||||
+ enum nss_status status2
|
||||
+ = gaih_getanswer_slice (packet2, packet2len,
|
||||
+ abuf, &pat, errnop, h_errnop, ttlp,
|
||||
+ /* Success means that data with a
|
||||
+ canonical name has already been
|
||||
+ stored. Do not store the name again. */
|
||||
+ status != NSS_STATUS_SUCCESS);
|
||||
/* Use the second response status in some cases. */
|
||||
if (status != NSS_STATUS_SUCCESS && status2 != NSS_STATUS_NOTFOUND)
|
||||
status = status2;
|
||||
- /* Do not return a truncated second response (unless it was
|
||||
- unavoidable e.g. unrecoverable TRYAGAIN). */
|
||||
- if (status == NSS_STATUS_SUCCESS
|
||||
- && (status2 == NSS_STATUS_TRYAGAIN
|
||||
- && *errnop == ERANGE && *h_errnop != NO_RECOVERY))
|
||||
- status = NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
return status;
|
||||
@@ -1274,18 +1160,13 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2,
|
||||
|
||||
/* Variant of gaih_getanswer without a second (AAAA) response. */
|
||||
static enum nss_status
|
||||
-gaih_getanswer_noaaaa (const querybuf *answer1, int anslen1, const char *qname,
|
||||
- struct gaih_addrtuple **pat,
|
||||
- char *buffer, size_t buflen,
|
||||
+gaih_getanswer_noaaaa (unsigned char *packet, size_t packetlen,
|
||||
+ struct alloc_buffer *abuf, struct gaih_addrtuple **pat,
|
||||
int *errnop, int *h_errnop, int32_t *ttlp)
|
||||
{
|
||||
- int first = 1;
|
||||
-
|
||||
enum nss_status status = NSS_STATUS_NOTFOUND;
|
||||
- if (anslen1 > 0)
|
||||
- status = gaih_getanswer_slice (answer1, anslen1, qname,
|
||||
- &pat, &buffer, &buflen,
|
||||
- errnop, h_errnop, ttlp,
|
||||
- &first);
|
||||
+ if (packetlen > 0)
|
||||
+ status = gaih_getanswer_slice (packet, packetlen,
|
||||
+ abuf, &pat, errnop, h_errnop, ttlp, true);
|
||||
return status;
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
commit b8c6166b1b75036ab3e4127a1c0aacf52ca93651
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Sep 6 19:43:37 2021 +0200
|
||||
|
||||
locale: Add missing second argument to _Static_assert in C-collate-seq.c
|
||||
|
||||
diff --git a/locale/C-collate-seq.c b/locale/C-collate-seq.c
|
||||
index 4fb82cb8357936b6..40b17f4f90313144 100644
|
||||
--- a/locale/C-collate-seq.c
|
||||
+++ b/locale/C-collate-seq.c
|
||||
@@ -55,7 +55,7 @@ static const char collseqmb[] =
|
||||
|
||||
/* This table must be 256 bytes in size. We index bytes into the
|
||||
table to find the collation sequence. */
|
||||
-_Static_assert (sizeof (collseqmb) == 256);
|
||||
+_Static_assert (sizeof (collseqmb) == 256, "sizeof (collseqmb)");
|
||||
|
||||
static const uint32_t collseqwc[] =
|
||||
{
|
@ -0,0 +1,306 @@
|
||||
Maintain an explicit order of tunables, so that the tunable_list
|
||||
array and the tunable_id_t constant can remain consistent over time.
|
||||
|
||||
Related to this upstream bug:
|
||||
|
||||
Internal tunables ABI depends on awk array iteration order
|
||||
<https://sourceware.org/bugzilla/show_bug.cgi?id=30027>
|
||||
|
||||
The new dl-tunables.list files are already on the sysdeps search
|
||||
path, which is why the existing Makeconfig rule picks them up.
|
||||
The files for RHEL 9.1z were created by applying the gen-tunables.awk
|
||||
part of this patch to RHEL 9.1.0 (glibc-2.34-40.el9_2.1, to be
|
||||
precise). The sysdeps/unix/sysv/linux/**/dl-tunables.list files were
|
||||
created based on the generated error message during the RHEL 9.1.z
|
||||
build.
|
||||
|
||||
Going forward, new tunables will have to be added manually to the end
|
||||
of those files. Existing tunables should not be deleted. For
|
||||
deletion, the script would have to be extended to be able to create
|
||||
gaps in the tunable_list array.
|
||||
|
||||
diff --git a/scripts/gen-tunables.awk b/scripts/gen-tunables.awk
|
||||
index fa63e86d1a51fe61..c5445e95f9fc36e7 100644
|
||||
--- a/scripts/gen-tunables.awk
|
||||
+++ b/scripts/gen-tunables.awk
|
||||
@@ -14,6 +14,7 @@ BEGIN {
|
||||
top_ns=""
|
||||
max_name_len=0
|
||||
max_alias_len=0
|
||||
+ tunable_order_count = 0
|
||||
}
|
||||
|
||||
# Skip over blank lines and comments.
|
||||
@@ -83,6 +84,37 @@ $1 == "}" {
|
||||
next
|
||||
}
|
||||
|
||||
+$1 == "@order" {
|
||||
+ if (top_ns != "") {
|
||||
+ printf("%s:%d: error: invalid @order directive inside namespace %s\n",
|
||||
+ FILENAME, FNR, top_ns) > "/dev/stderr"
|
||||
+ exit 1
|
||||
+ }
|
||||
+ if (NF != 2) {
|
||||
+ printf("%s:%d: error: invalid argument count in @order directive\n",
|
||||
+ FILENAME, FNR) > "/dev/stderr"
|
||||
+ exit 1
|
||||
+ }
|
||||
+ order_arg = $2
|
||||
+ if (split(order_arg, indices, /\./) != 3) {
|
||||
+ printf("%s:%d: error: invalid tunable syntax in @order directive\n",
|
||||
+ FILENAME, FNR) > "/dev/stderr"
|
||||
+ exit 1
|
||||
+ }
|
||||
+ t = indices[1]
|
||||
+ n = indices[2]
|
||||
+ m = indices[3]
|
||||
+ if ((t, n, m) in tunable_order) {
|
||||
+ printf("%s:%d: error: duplicate\"@order %s\"\n" \
|
||||
+ FILENAME, FNR, order_arg) > "/dev/stderr"
|
||||
+ exit 1
|
||||
+ }
|
||||
+ ++tunable_order_count
|
||||
+ tunable_order[t,n,m] = tunable_order_count
|
||||
+ tunable_order_list[tunable_order_count] = t SUBSEP n SUBSEP m
|
||||
+ next
|
||||
+}
|
||||
+
|
||||
# Everything else, which could either be a tunable without any attributes or a
|
||||
# tunable attribute.
|
||||
{
|
||||
@@ -145,6 +177,31 @@ END {
|
||||
exit 1
|
||||
}
|
||||
|
||||
+ missing_order = 0
|
||||
+ for (tnm in types) {
|
||||
+ if (!(tnm in tunable_order)) {
|
||||
+ if (!missing_order) {
|
||||
+ print "error: Missing @order directives:" > "/dev/stderr"
|
||||
+ missing_order = 1
|
||||
+ }
|
||||
+ split(tnm, indices, SUBSEP)
|
||||
+ printf("@order %s.%s.%s\n", indices[1], indices[2], indices[3]) \
|
||||
+ > "/dev/stderr"
|
||||
+ }
|
||||
+ }
|
||||
+ for (i = 1; i <= tunable_order_count; ++i) {
|
||||
+ tnm = tunable_order_list[i]
|
||||
+ if (!(tnm in types)) {
|
||||
+ split(tnm, indices, SUBSEP)
|
||||
+ printf("error: tunable in \"@order %s.%s.%s\" not known\n", \
|
||||
+ indices[1], indices[2], indices[3]) > "/dev/stderr"
|
||||
+ missing_order = 1
|
||||
+ }
|
||||
+ }
|
||||
+ if (missing_order) {
|
||||
+ exit 1
|
||||
+ }
|
||||
+
|
||||
print "/* AUTOGENERATED by gen-tunables.awk. */"
|
||||
print "#ifndef _TUNABLES_H_"
|
||||
print "# error \"Do not include this file directly.\""
|
||||
@@ -155,7 +212,8 @@ END {
|
||||
# Now, the enum names
|
||||
print "\ntypedef enum"
|
||||
print "{"
|
||||
- for (tnm in types) {
|
||||
+ for (i = 1; i <= tunable_order_count; ++i) {
|
||||
+ tnm = tunable_order_list[i]
|
||||
split (tnm, indices, SUBSEP);
|
||||
t = indices[1];
|
||||
n = indices[2];
|
||||
@@ -171,7 +229,8 @@ END {
|
||||
print "# include \"dl-tunable-types.h\""
|
||||
# Finally, the tunable list.
|
||||
print "static tunable_t tunable_list[] attribute_relro = {"
|
||||
- for (tnm in types) {
|
||||
+ for (i = 1; i <= tunable_order_count; ++i) {
|
||||
+ tnm = tunable_order_list[i]
|
||||
split (tnm, indices, SUBSEP);
|
||||
t = indices[1];
|
||||
n = indices[2];
|
||||
diff --git a/sysdeps/unix/sysv/linux/aarch64/dl-tunables.list b/sysdeps/unix/sysv/linux/aarch64/dl-tunables.list
|
||||
new file mode 100644
|
||||
index 0000000000000000..d9d62499be4d67cb
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/unix/sysv/linux/aarch64/dl-tunables.list
|
||||
@@ -0,0 +1,28 @@
|
||||
+# Order of tunables in RHEL 9.1.z.
|
||||
+@order glibc.rtld.nns
|
||||
+@order glibc.elision.skip_lock_after_retries
|
||||
+@order glibc.malloc.trim_threshold
|
||||
+@order glibc.malloc.perturb
|
||||
+@order glibc.pthread.rseq
|
||||
+@order glibc.cpu.name
|
||||
+@order glibc.mem.tagging
|
||||
+@order glibc.elision.tries
|
||||
+@order glibc.elision.enable
|
||||
+@order glibc.malloc.mxfast
|
||||
+@order glibc.rtld.dynamic_sort
|
||||
+@order glibc.elision.skip_lock_busy
|
||||
+@order glibc.malloc.top_pad
|
||||
+@order glibc.pthread.stack_cache_size
|
||||
+@order glibc.cpu.hwcap_mask
|
||||
+@order glibc.malloc.mmap_max
|
||||
+@order glibc.elision.skip_trylock_internal_abort
|
||||
+@order glibc.malloc.tcache_unsorted_limit
|
||||
+@order glibc.elision.skip_lock_internal_abort
|
||||
+@order glibc.malloc.arena_max
|
||||
+@order glibc.malloc.mmap_threshold
|
||||
+@order glibc.malloc.tcache_count
|
||||
+@order glibc.malloc.arena_test
|
||||
+@order glibc.pthread.mutex_spin_count
|
||||
+@order glibc.rtld.optional_static_tls
|
||||
+@order glibc.malloc.tcache_max
|
||||
+@order glibc.malloc.check
|
||||
diff --git a/sysdeps/unix/sysv/linux/i386/dl-tunables.list b/sysdeps/unix/sysv/linux/i386/dl-tunables.list
|
||||
new file mode 100644
|
||||
index 0000000000000000..e83962ec3af11691
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/unix/sysv/linux/i386/dl-tunables.list
|
||||
@@ -0,0 +1,35 @@
|
||||
+# Order of tunables in RHEL 9.1.z.
|
||||
+@order glibc.rtld.nns
|
||||
+@order glibc.elision.skip_lock_after_retries
|
||||
+@order glibc.malloc.trim_threshold
|
||||
+@order glibc.malloc.perturb
|
||||
+@order glibc.cpu.x86_shared_cache_size
|
||||
+@order glibc.pthread.rseq
|
||||
+@order glibc.mem.tagging
|
||||
+@order glibc.elision.tries
|
||||
+@order glibc.elision.enable
|
||||
+@order glibc.cpu.x86_rep_movsb_threshold
|
||||
+@order glibc.malloc.mxfast
|
||||
+@order glibc.rtld.dynamic_sort
|
||||
+@order glibc.elision.skip_lock_busy
|
||||
+@order glibc.malloc.top_pad
|
||||
+@order glibc.cpu.x86_rep_stosb_threshold
|
||||
+@order glibc.cpu.x86_non_temporal_threshold
|
||||
+@order glibc.cpu.x86_shstk
|
||||
+@order glibc.pthread.stack_cache_size
|
||||
+@order glibc.cpu.hwcap_mask
|
||||
+@order glibc.malloc.mmap_max
|
||||
+@order glibc.elision.skip_trylock_internal_abort
|
||||
+@order glibc.malloc.tcache_unsorted_limit
|
||||
+@order glibc.cpu.x86_ibt
|
||||
+@order glibc.cpu.hwcaps
|
||||
+@order glibc.elision.skip_lock_internal_abort
|
||||
+@order glibc.malloc.arena_max
|
||||
+@order glibc.malloc.mmap_threshold
|
||||
+@order glibc.cpu.x86_data_cache_size
|
||||
+@order glibc.malloc.tcache_count
|
||||
+@order glibc.malloc.arena_test
|
||||
+@order glibc.pthread.mutex_spin_count
|
||||
+@order glibc.rtld.optional_static_tls
|
||||
+@order glibc.malloc.tcache_max
|
||||
+@order glibc.malloc.check
|
||||
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/dl-tunables.list b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/dl-tunables.list
|
||||
new file mode 100644
|
||||
index 0000000000000000..8f01840ef57874e7
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/dl-tunables.list
|
||||
@@ -0,0 +1,28 @@
|
||||
+# Order of tunables in RHEL 9.1.z.
|
||||
+@order glibc.rtld.nns
|
||||
+@order glibc.elision.skip_lock_after_retries
|
||||
+@order glibc.malloc.trim_threshold
|
||||
+@order glibc.malloc.perturb
|
||||
+@order glibc.pthread.rseq
|
||||
+@order glibc.mem.tagging
|
||||
+@order glibc.elision.tries
|
||||
+@order glibc.elision.enable
|
||||
+@order glibc.malloc.mxfast
|
||||
+@order glibc.rtld.dynamic_sort
|
||||
+@order glibc.elision.skip_lock_busy
|
||||
+@order glibc.malloc.top_pad
|
||||
+@order glibc.pthread.stack_cache_size
|
||||
+@order glibc.cpu.hwcap_mask
|
||||
+@order glibc.malloc.mmap_max
|
||||
+@order glibc.elision.skip_trylock_internal_abort
|
||||
+@order glibc.malloc.tcache_unsorted_limit
|
||||
+@order glibc.elision.skip_lock_internal_abort
|
||||
+@order glibc.malloc.arena_max
|
||||
+@order glibc.malloc.mmap_threshold
|
||||
+@order glibc.cpu.cached_memopt
|
||||
+@order glibc.malloc.tcache_count
|
||||
+@order glibc.malloc.arena_test
|
||||
+@order glibc.pthread.mutex_spin_count
|
||||
+@order glibc.rtld.optional_static_tls
|
||||
+@order glibc.malloc.tcache_max
|
||||
+@order glibc.malloc.check
|
||||
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/dl-tunables.list b/sysdeps/unix/sysv/linux/s390/s390-64/dl-tunables.list
|
||||
new file mode 100644
|
||||
index 0000000000000000..c3bc83f33910af22
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/dl-tunables.list
|
||||
@@ -0,0 +1,27 @@
|
||||
+# Order of tunables in RHEL 9.1.z.
|
||||
+@order glibc.rtld.nns
|
||||
+@order glibc.elision.skip_lock_after_retries
|
||||
+@order glibc.malloc.trim_threshold
|
||||
+@order glibc.malloc.perturb
|
||||
+@order glibc.pthread.rseq
|
||||
+@order glibc.mem.tagging
|
||||
+@order glibc.elision.tries
|
||||
+@order glibc.elision.enable
|
||||
+@order glibc.malloc.mxfast
|
||||
+@order glibc.rtld.dynamic_sort
|
||||
+@order glibc.elision.skip_lock_busy
|
||||
+@order glibc.malloc.top_pad
|
||||
+@order glibc.pthread.stack_cache_size
|
||||
+@order glibc.cpu.hwcap_mask
|
||||
+@order glibc.malloc.mmap_max
|
||||
+@order glibc.elision.skip_trylock_internal_abort
|
||||
+@order glibc.malloc.tcache_unsorted_limit
|
||||
+@order glibc.elision.skip_lock_internal_abort
|
||||
+@order glibc.malloc.arena_max
|
||||
+@order glibc.malloc.mmap_threshold
|
||||
+@order glibc.malloc.tcache_count
|
||||
+@order glibc.malloc.arena_test
|
||||
+@order glibc.pthread.mutex_spin_count
|
||||
+@order glibc.rtld.optional_static_tls
|
||||
+@order glibc.malloc.tcache_max
|
||||
+@order glibc.malloc.check
|
||||
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/dl-tunables.list b/sysdeps/unix/sysv/linux/x86_64/64/dl-tunables.list
|
||||
new file mode 100644
|
||||
index 0000000000000000..e83962ec3af11691
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/unix/sysv/linux/x86_64/64/dl-tunables.list
|
||||
@@ -0,0 +1,35 @@
|
||||
+# Order of tunables in RHEL 9.1.z.
|
||||
+@order glibc.rtld.nns
|
||||
+@order glibc.elision.skip_lock_after_retries
|
||||
+@order glibc.malloc.trim_threshold
|
||||
+@order glibc.malloc.perturb
|
||||
+@order glibc.cpu.x86_shared_cache_size
|
||||
+@order glibc.pthread.rseq
|
||||
+@order glibc.mem.tagging
|
||||
+@order glibc.elision.tries
|
||||
+@order glibc.elision.enable
|
||||
+@order glibc.cpu.x86_rep_movsb_threshold
|
||||
+@order glibc.malloc.mxfast
|
||||
+@order glibc.rtld.dynamic_sort
|
||||
+@order glibc.elision.skip_lock_busy
|
||||
+@order glibc.malloc.top_pad
|
||||
+@order glibc.cpu.x86_rep_stosb_threshold
|
||||
+@order glibc.cpu.x86_non_temporal_threshold
|
||||
+@order glibc.cpu.x86_shstk
|
||||
+@order glibc.pthread.stack_cache_size
|
||||
+@order glibc.cpu.hwcap_mask
|
||||
+@order glibc.malloc.mmap_max
|
||||
+@order glibc.elision.skip_trylock_internal_abort
|
||||
+@order glibc.malloc.tcache_unsorted_limit
|
||||
+@order glibc.cpu.x86_ibt
|
||||
+@order glibc.cpu.hwcaps
|
||||
+@order glibc.elision.skip_lock_internal_abort
|
||||
+@order glibc.malloc.arena_max
|
||||
+@order glibc.malloc.mmap_threshold
|
||||
+@order glibc.cpu.x86_data_cache_size
|
||||
+@order glibc.malloc.tcache_count
|
||||
+@order glibc.malloc.arena_test
|
||||
+@order glibc.pthread.mutex_spin_count
|
||||
+@order glibc.rtld.optional_static_tls
|
||||
+@order glibc.malloc.tcache_max
|
||||
+@order glibc.malloc.check
|
@ -0,0 +1,37 @@
|
||||
Short description: Fix newlocale error return.
|
||||
Author(s): Fedora glibc team <glibc@lists.fedoraproject.org>
|
||||
Origin: PATCH
|
||||
Bug-RHEL: #832516
|
||||
Bug-Fedora: #827510
|
||||
Bug-Upstream: #14247
|
||||
Upstream status: not-submitted
|
||||
|
||||
This needs to go upstream right away to fix the error case for
|
||||
newlocale not correctly returning an error.
|
||||
|
||||
2012-06-14 Jeff Law <law@redhat.com>
|
||||
|
||||
* locale/loadlocale.c (_nl_load_locale): Delay setting
|
||||
file->decided until we have successfully loaded the file's
|
||||
data.
|
||||
|
||||
diff --git a/locale/loadlocale.c b/locale/loadlocale.c
|
||||
index e3fa187..9fd9216 100644
|
||||
--- a/locale/loadlocale.c
|
||||
+++ b/locale/loadlocale.c
|
||||
@@ -169,7 +169,6 @@ _nl_load_locale (struct loaded_l10nfile *file, int category)
|
||||
int save_err;
|
||||
int alloc = ld_mapped;
|
||||
|
||||
- file->decided = 1;
|
||||
file->data = NULL;
|
||||
|
||||
fd = __open_nocancel (file->filename, O_RDONLY | O_CLOEXEC);
|
||||
@@ -278,6 +277,7 @@ _nl_load_locale (struct loaded_l10nfile *file, int category)
|
||||
newdata->alloc = alloc;
|
||||
|
||||
file->data = newdata;
|
||||
+ file->decided = 1;
|
||||
}
|
||||
|
||||
void
|
@ -0,0 +1,26 @@
|
||||
commit 0b03996304f86d6dba8f0d4b7048b9bb7186f17d
|
||||
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Date: Tue Aug 3 21:10:10 2021 +0530
|
||||
|
||||
ldconfig: avoid leak on empty paths in config file
|
||||
|
||||
Reviewed-by: Arjun Shankar <arjun@redhat.com>
|
||||
(cherry picked from commit b0234d79e7d82475d1666f25326ec045c045b3ed)
|
||||
|
||||
diff --git a/elf/ldconfig.c b/elf/ldconfig.c
|
||||
index 1037e8d0cf8d28b6..b8893637f8aaea8d 100644
|
||||
--- a/elf/ldconfig.c
|
||||
+++ b/elf/ldconfig.c
|
||||
@@ -503,7 +503,11 @@ add_dir_1 (const char *line, const char *from_file, int from_line)
|
||||
entry->path[--i] = '\0';
|
||||
|
||||
if (i == 0)
|
||||
- return;
|
||||
+ {
|
||||
+ free (entry->path);
|
||||
+ free (entry);
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
char *path = entry->path;
|
||||
if (opt_chroot != NULL)
|
@ -0,0 +1,34 @@
|
||||
commit f2413f2710d5d5cc884b413b83fcf8198e3717fa
|
||||
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||
Date: Sat Aug 28 06:10:38 2021 -0700
|
||||
|
||||
x86-64: Use testl to check __x86_string_control
|
||||
|
||||
Use testl, instead of andl, to check __x86_string_control to avoid
|
||||
updating __x86_string_control.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
(cherry picked from commit 3c8b9879cab6d41787bc5b14c1748f62fd6d0e5f)
|
||||
|
||||
diff --git a/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S b/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S
|
||||
index 9f02624375c07b26..abde8438d41f2320 100644
|
||||
--- a/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S
|
||||
+++ b/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S
|
||||
@@ -325,7 +325,7 @@ L(movsb):
|
||||
/* Avoid slow backward REP MOVSB. */
|
||||
jb L(more_8x_vec_backward)
|
||||
# if AVOID_SHORT_DISTANCE_REP_MOVSB
|
||||
- andl $X86_STRING_CONTROL_AVOID_SHORT_DISTANCE_REP_MOVSB, __x86_string_control(%rip)
|
||||
+ testl $X86_STRING_CONTROL_AVOID_SHORT_DISTANCE_REP_MOVSB, __x86_string_control(%rip)
|
||||
jz 3f
|
||||
movq %rdi, %rcx
|
||||
subq %rsi, %rcx
|
||||
@@ -333,7 +333,7 @@ L(movsb):
|
||||
# endif
|
||||
1:
|
||||
# if AVOID_SHORT_DISTANCE_REP_MOVSB
|
||||
- andl $X86_STRING_CONTROL_AVOID_SHORT_DISTANCE_REP_MOVSB, __x86_string_control(%rip)
|
||||
+ testl $X86_STRING_CONTROL_AVOID_SHORT_DISTANCE_REP_MOVSB, __x86_string_control(%rip)
|
||||
jz 3f
|
||||
movq %rsi, %rcx
|
||||
subq %rdi, %rcx
|
@ -0,0 +1,95 @@
|
||||
commit e09e7b1492b2d5c2f68ddf81f8f58e093dd4df6d
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Mon Dec 13 11:36:42 2021 -0300
|
||||
|
||||
support: Add support_socket_so_timestamp_time64
|
||||
|
||||
Check if the socket support 64-bit network packages timestamps
|
||||
(SO_TIMESTAMP and SO_TIMESTAMPNS). This will be used on recvmsg
|
||||
and recvmmsg tests to check if the timestamp should be generated.
|
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
(cherry picked from 38bc0f4e78934aab455b31af05cefcbf3c22bece)
|
||||
|
||||
diff --git a/support/Makefile b/support/Makefile
|
||||
index 3c941e1ba9e29aa4..6a5fc9faf2ca2e2d 100644
|
||||
--- a/support/Makefile
|
||||
+++ b/support/Makefile
|
||||
@@ -79,6 +79,7 @@ libsupport-routines = \
|
||||
support_set_small_thread_stack_size \
|
||||
support_shared_allocate \
|
||||
support_small_stack_thread_attribute \
|
||||
+ support_socket_so_timestamp_time64 \
|
||||
support_stat_nanoseconds \
|
||||
support_subprocess \
|
||||
support_test_compare_blob \
|
||||
diff --git a/support/support.h b/support/support.h
|
||||
index 29d56c7c891ee34b..ecfc9a336d272a30 100644
|
||||
--- a/support/support.h
|
||||
+++ b/support/support.h
|
||||
@@ -170,6 +170,10 @@ extern bool support_select_modifies_timeout (void);
|
||||
tv_usec larger than 1000000. */
|
||||
extern bool support_select_normalizes_timeout (void);
|
||||
|
||||
+/* Return true if socket FD supports 64-bit timestamps with the SOL_SOCKET
|
||||
+ and SO_TIMESTAMP/SO_TIMESTAMPNS. */
|
||||
+extern bool support_socket_so_timestamp_time64 (int fd);
|
||||
+
|
||||
/* Create a timer that trigger after SEC seconds and NSEC nanoseconds. If
|
||||
REPEAT is true the timer will repeat indefinitely. If CALLBACK is not
|
||||
NULL, the function will be called when the timer expires; otherwise a
|
||||
diff --git a/support/support_socket_so_timestamp_time64.c b/support/support_socket_so_timestamp_time64.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..54bf3f42724566f5
|
||||
--- /dev/null
|
||||
+++ b/support/support_socket_so_timestamp_time64.c
|
||||
@@ -0,0 +1,48 @@
|
||||
+/* Return whether socket supports 64-bit timestamps.
|
||||
+ 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/>. */
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <unistd.h>
|
||||
+#include <sys/syscall.h>
|
||||
+#include <sys/socket.h>
|
||||
+#include <support/support.h>
|
||||
+#ifdef __linux__
|
||||
+# include <socket-constants-time64.h>
|
||||
+#endif
|
||||
+
|
||||
+bool
|
||||
+support_socket_so_timestamp_time64 (int fd)
|
||||
+{
|
||||
+#ifdef __linux__
|
||||
+# if __LINUX_KERNEL_VERSION >= 0x050100 \
|
||||
+ || __WORDSIZE == 64 \
|
||||
+ || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64)
|
||||
+ return true;
|
||||
+# else
|
||||
+ int level = SOL_SOCKET;
|
||||
+ int optname = COMPAT_SO_TIMESTAMP_NEW;
|
||||
+ int optval;
|
||||
+ socklen_t len = sizeof (optval);
|
||||
+
|
||||
+ int r = syscall (__NR_getsockopt, fd, level, optname, &optval, &len);
|
||||
+ return r != -1;
|
||||
+# endif
|
||||
+#else
|
||||
+ return false;
|
||||
+#endif
|
||||
+}
|
@ -0,0 +1,431 @@
|
||||
commit e098446037da532d4a250efac9a813bc22f3669f
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Mon Jan 24 08:55:53 2022 -0300
|
||||
|
||||
linux: Fix ancillary 64-bit time timestamp conversion (BZ #28349, BZ#28350)
|
||||
|
||||
The __convert_scm_timestamps only updates the control message last
|
||||
pointer for SOL_SOCKET type, so if the message control buffer contains
|
||||
multiple ancillary message types the converted timestamp one might
|
||||
overwrite a valid message.
|
||||
|
||||
The test checks if the extra ancillary space is correctly handled
|
||||
by recvmsg/recvmmsg, where if there is no extra space for the 64-bit
|
||||
time_t converted message the control buffer should be marked with
|
||||
MSG_TRUNC. It also check if recvmsg/recvmmsg handle correctly multiple
|
||||
ancillary data.
|
||||
|
||||
Checked on x86_64-linux and on i686-linux-gnu on both 5.11 and
|
||||
4.15 kernel.
|
||||
|
||||
Co-authored-by: Fabian Vogt <fvogt@suse.de>
|
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
(cherry picked from commit 8fba672472ae0055387e9315fc2eddfa6775ca79)
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
|
||||
index cdc01a3f023ec09a..7c75e22c6d0e9ff5 100644
|
||||
--- a/sysdeps/unix/sysv/linux/Makefile
|
||||
+++ b/sysdeps/unix/sysv/linux/Makefile
|
||||
@@ -273,6 +273,9 @@ sysdep_routines += cmsg_nxthdr
|
||||
CFLAGS-recvmmsg.c = -fexceptions -fasynchronous-unwind-tables
|
||||
CFLAGS-sendmmsg.c = -fexceptions -fasynchronous-unwind-tables
|
||||
|
||||
+tests += tst-socket-timestamp
|
||||
+tests-time64 += tst-socket-timestamp-time64
|
||||
+
|
||||
tests-special += $(objpfx)tst-socket-consts.out
|
||||
$(objpfx)tst-socket-consts.out: ../sysdeps/unix/sysv/linux/tst-socket-consts.py
|
||||
PYTHONPATH=../scripts \
|
||||
diff --git a/sysdeps/unix/sysv/linux/convert_scm_timestamps.c b/sysdeps/unix/sysv/linux/convert_scm_timestamps.c
|
||||
index 00c934c4135f0d42..5d3c4199e0b32944 100644
|
||||
--- a/sysdeps/unix/sysv/linux/convert_scm_timestamps.c
|
||||
+++ b/sysdeps/unix/sysv/linux/convert_scm_timestamps.c
|
||||
@@ -54,6 +54,8 @@ __convert_scm_timestamps (struct msghdr *msg, socklen_t msgsize)
|
||||
cmsg != NULL;
|
||||
cmsg = CMSG_NXTHDR (msg, cmsg))
|
||||
{
|
||||
+ last = cmsg;
|
||||
+
|
||||
if (cmsg->cmsg_level != SOL_SOCKET)
|
||||
continue;
|
||||
|
||||
@@ -75,11 +77,9 @@ __convert_scm_timestamps (struct msghdr *msg, socklen_t msgsize)
|
||||
tvts[1] = tmp[1];
|
||||
break;
|
||||
}
|
||||
-
|
||||
- last = cmsg;
|
||||
}
|
||||
|
||||
- if (last == NULL || type == 0)
|
||||
+ if (type == 0)
|
||||
return;
|
||||
|
||||
if (CMSG_SPACE (sizeof tvts) > msgsize - msg->msg_controllen)
|
||||
@@ -88,10 +88,12 @@ __convert_scm_timestamps (struct msghdr *msg, socklen_t msgsize)
|
||||
return;
|
||||
}
|
||||
|
||||
+ /* Zero memory for the new cmsghdr, so reading cmsg_len field
|
||||
+ by CMSG_NXTHDR does not trigger UB. */
|
||||
+ memset (msg->msg_control + msg->msg_controllen, 0,
|
||||
+ CMSG_SPACE (sizeof tvts));
|
||||
msg->msg_controllen += CMSG_SPACE (sizeof tvts);
|
||||
- cmsg = CMSG_NXTHDR(msg, last);
|
||||
- if (cmsg == NULL)
|
||||
- return;
|
||||
+ cmsg = CMSG_NXTHDR (msg, last);
|
||||
cmsg->cmsg_level = SOL_SOCKET;
|
||||
cmsg->cmsg_type = type;
|
||||
cmsg->cmsg_len = CMSG_LEN (sizeof tvts);
|
||||
diff --git a/sysdeps/unix/sysv/linux/tst-socket-timestamp-time64.c b/sysdeps/unix/sysv/linux/tst-socket-timestamp-time64.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..ae424c2a70026cf5
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/unix/sysv/linux/tst-socket-timestamp-time64.c
|
||||
@@ -0,0 +1 @@
|
||||
+#include "tst-socket-timestamp.c"
|
||||
diff --git a/sysdeps/unix/sysv/linux/tst-socket-timestamp.c b/sysdeps/unix/sysv/linux/tst-socket-timestamp.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..9c2e76f7e27bd312
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/unix/sysv/linux/tst-socket-timestamp.c
|
||||
@@ -0,0 +1,336 @@
|
||||
+/* Check recvmsg/recvmmsg 64-bit timestamp support.
|
||||
+ 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/>. */
|
||||
+
|
||||
+#include <array_length.h>
|
||||
+#include <arpa/inet.h>
|
||||
+#include <errno.h>
|
||||
+#include <string.h>
|
||||
+#include <stdio.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/next_to_fault.h>
|
||||
+#include <support/support.h>
|
||||
+#include <support/test-driver.h>
|
||||
+#include <support/xunistd.h>
|
||||
+#include <support/xsocket.h>
|
||||
+#include <sys/mman.h>
|
||||
+
|
||||
+/* Some extra space added for ancillary data, it might be used to convert
|
||||
+ 32-bit timestamp to 64-bit for _TIME_BITS=64. */
|
||||
+enum { slack_max_size = 64 };
|
||||
+static const int slack[] = { 0, 4, 8, 16, 32, slack_max_size };
|
||||
+
|
||||
+static bool support_64_timestamp;
|
||||
+/* AF_INET socket and address used to receive data. */
|
||||
+static int srv;
|
||||
+static struct sockaddr_in srv_addr;
|
||||
+
|
||||
+static int
|
||||
+do_sendto (const struct sockaddr_in *addr, int nmsgs)
|
||||
+{
|
||||
+ int s = xsocket (AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
|
||||
+ xconnect (s, (const struct sockaddr *) addr, sizeof (*addr));
|
||||
+
|
||||
+ for (int i = 0; i < nmsgs; i++)
|
||||
+ xsendto (s, &i, sizeof (i), 0, (const struct sockaddr *) addr,
|
||||
+ sizeof (*addr));
|
||||
+
|
||||
+ xclose (s);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+do_recvmsg_slack_ancillary (bool use_multi_call, int s, void *cmsg,
|
||||
+ size_t slack, size_t tsize, int exp_payload)
|
||||
+{
|
||||
+ int payload;
|
||||
+ struct iovec iov =
|
||||
+ {
|
||||
+ .iov_base = &payload,
|
||||
+ .iov_len = sizeof (payload)
|
||||
+ };
|
||||
+ size_t msg_controllen = CMSG_SPACE (tsize) + slack;
|
||||
+ char *msg_control = cmsg - msg_controllen;
|
||||
+ memset (msg_control, 0x55, msg_controllen);
|
||||
+ struct mmsghdr mmhdr =
|
||||
+ {
|
||||
+ .msg_hdr =
|
||||
+ {
|
||||
+ .msg_name = NULL,
|
||||
+ .msg_namelen = 0,
|
||||
+ .msg_iov = &iov,
|
||||
+ .msg_iovlen = 1,
|
||||
+ .msg_control = msg_control,
|
||||
+ .msg_controllen = msg_controllen
|
||||
+ },
|
||||
+ };
|
||||
+
|
||||
+ int r;
|
||||
+ if (use_multi_call)
|
||||
+ {
|
||||
+ r = recvmmsg (s, &mmhdr, 1, 0, NULL);
|
||||
+ if (r >= 0)
|
||||
+ r = mmhdr.msg_len;
|
||||
+ }
|
||||
+ else
|
||||
+ r = recvmsg (s, &mmhdr.msg_hdr, 0);
|
||||
+ TEST_COMPARE (r, sizeof (int));
|
||||
+ TEST_COMPARE (payload, exp_payload);
|
||||
+
|
||||
+ if (cmsg == NULL)
|
||||
+ return;
|
||||
+
|
||||
+ /* A timestamp is expected if 32-bit timestamp are used (support in every
|
||||
+ configuration) or if underlying kernel support 64-bit timestamps.
|
||||
+ Otherwise recvmsg will need extra space do add the 64-bit timestamp. */
|
||||
+ bool exp_timestamp;
|
||||
+ if (sizeof (time_t) == 4 || support_64_timestamp)
|
||||
+ exp_timestamp = true;
|
||||
+ else
|
||||
+ exp_timestamp = slack >= CMSG_SPACE (tsize);
|
||||
+
|
||||
+ bool timestamp = false;
|
||||
+ for (struct cmsghdr *cmsg = CMSG_FIRSTHDR (&mmhdr.msg_hdr);
|
||||
+ cmsg != NULL;
|
||||
+ cmsg = CMSG_NXTHDR (&mmhdr.msg_hdr, cmsg))
|
||||
+ {
|
||||
+ if (cmsg->cmsg_level != SOL_SOCKET)
|
||||
+ continue;
|
||||
+ if (cmsg->cmsg_type == SCM_TIMESTAMP
|
||||
+ && cmsg->cmsg_len == CMSG_LEN (sizeof (struct timeval)))
|
||||
+ {
|
||||
+ struct timeval tv;
|
||||
+ memcpy (&tv, CMSG_DATA (cmsg), sizeof (tv));
|
||||
+ if (test_verbose)
|
||||
+ printf ("SCM_TIMESTAMP: {%jd, %jd}\n", (intmax_t)tv.tv_sec,
|
||||
+ (intmax_t)tv.tv_usec);
|
||||
+ timestamp = true;
|
||||
+ }
|
||||
+ else if (cmsg->cmsg_type == SCM_TIMESTAMPNS
|
||||
+ && cmsg->cmsg_len == CMSG_LEN (sizeof (struct timespec)))
|
||||
+ {
|
||||
+ struct timespec ts;
|
||||
+ memcpy (&ts, CMSG_DATA (cmsg), sizeof (ts));
|
||||
+ if (test_verbose)
|
||||
+ printf ("SCM_TIMESTAMPNS: {%jd, %jd}\n", (intmax_t)ts.tv_sec,
|
||||
+ (intmax_t)ts.tv_nsec);
|
||||
+ timestamp = true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ TEST_COMPARE (timestamp, exp_timestamp);
|
||||
+}
|
||||
+
|
||||
+/* Check if the extra ancillary space is correctly handled by recvmsg and
|
||||
+ recvmmsg with different extra space for the ancillaty buffer. */
|
||||
+static void
|
||||
+do_test_slack_space (void)
|
||||
+{
|
||||
+ /* Setup the ancillary data buffer with an extra page with PROT_NONE to
|
||||
+ check the possible timestamp conversion on some systems. */
|
||||
+ struct support_next_to_fault nf =
|
||||
+ support_next_to_fault_allocate (slack_max_size);
|
||||
+ void *msgbuf = nf.buffer + slack_max_size;
|
||||
+
|
||||
+ /* Enable the timestamp using struct timeval precision. */
|
||||
+ {
|
||||
+ int r = setsockopt (srv, SOL_SOCKET, SO_TIMESTAMP, &(int){1},
|
||||
+ sizeof (int));
|
||||
+ TEST_VERIFY_EXIT (r != -1);
|
||||
+ }
|
||||
+ /* Check recvmsg. */
|
||||
+ do_sendto (&srv_addr, array_length (slack));
|
||||
+ for (int s = 0; s < array_length (slack); s++)
|
||||
+ {
|
||||
+ memset (nf.buffer, 0x55, nf.length);
|
||||
+ do_recvmsg_slack_ancillary (false, srv, msgbuf, slack[s],
|
||||
+ sizeof (struct timeval), s);
|
||||
+ }
|
||||
+ /* Check recvmmsg. */
|
||||
+ do_sendto (&srv_addr, array_length (slack));
|
||||
+ for (int s = 0; s < array_length (slack); s++)
|
||||
+ {
|
||||
+ memset (nf.buffer, 0x55, nf.length);
|
||||
+ do_recvmsg_slack_ancillary (true, srv, msgbuf, slack[s],
|
||||
+ sizeof (struct timeval), s);
|
||||
+ }
|
||||
+
|
||||
+ /* Now enable timestamp using a higher precision, it overwrites the previous
|
||||
+ precision. */
|
||||
+ {
|
||||
+ int r = setsockopt (srv, SOL_SOCKET, SO_TIMESTAMPNS, &(int){1},
|
||||
+ sizeof (int));
|
||||
+ TEST_VERIFY_EXIT (r != -1);
|
||||
+ }
|
||||
+ /* Check recvmsg. */
|
||||
+ do_sendto (&srv_addr, array_length (slack));
|
||||
+ for (int s = 0; s < array_length (slack); s++)
|
||||
+ do_recvmsg_slack_ancillary (false, srv, msgbuf, slack[s],
|
||||
+ sizeof (struct timespec), s);
|
||||
+ /* Check recvmmsg. */
|
||||
+ do_sendto (&srv_addr, array_length (slack));
|
||||
+ for (int s = 0; s < array_length (slack); s++)
|
||||
+ do_recvmsg_slack_ancillary (true, srv, msgbuf, slack[s],
|
||||
+ sizeof (struct timespec), s);
|
||||
+
|
||||
+ support_next_to_fault_free (&nf);
|
||||
+}
|
||||
+
|
||||
+/* Check if the converted 64-bit timestamp is correctly appended when there
|
||||
+ are multiple ancillary messages. */
|
||||
+static void
|
||||
+do_recvmsg_multiple_ancillary (bool use_multi_call, int s, void *cmsg,
|
||||
+ size_t cmsgsize, int exp_msg)
|
||||
+{
|
||||
+ int msg;
|
||||
+ struct iovec iov =
|
||||
+ {
|
||||
+ .iov_base = &msg,
|
||||
+ .iov_len = sizeof (msg)
|
||||
+ };
|
||||
+ size_t msgs = cmsgsize;
|
||||
+ struct mmsghdr mmhdr =
|
||||
+ {
|
||||
+ .msg_hdr =
|
||||
+ {
|
||||
+ .msg_name = NULL,
|
||||
+ .msg_namelen = 0,
|
||||
+ .msg_iov = &iov,
|
||||
+ .msg_iovlen = 1,
|
||||
+ .msg_controllen = msgs,
|
||||
+ .msg_control = cmsg,
|
||||
+ },
|
||||
+ };
|
||||
+
|
||||
+ int r;
|
||||
+ if (use_multi_call)
|
||||
+ {
|
||||
+ r = recvmmsg (s, &mmhdr, 1, 0, NULL);
|
||||
+ if (r >= 0)
|
||||
+ r = mmhdr.msg_len;
|
||||
+ }
|
||||
+ else
|
||||
+ r = recvmsg (s, &mmhdr.msg_hdr, 0);
|
||||
+ TEST_COMPARE (r, sizeof (int));
|
||||
+ TEST_COMPARE (msg, exp_msg);
|
||||
+
|
||||
+ if (cmsg == NULL)
|
||||
+ return;
|
||||
+
|
||||
+ bool timestamp = false;
|
||||
+ bool origdstaddr = false;
|
||||
+ for (struct cmsghdr *cmsg = CMSG_FIRSTHDR (&mmhdr.msg_hdr);
|
||||
+ cmsg != NULL;
|
||||
+ cmsg = CMSG_NXTHDR (&mmhdr.msg_hdr, cmsg))
|
||||
+ {
|
||||
+ if (cmsg->cmsg_level == SOL_IP
|
||||
+ && cmsg->cmsg_type == IP_ORIGDSTADDR
|
||||
+ && cmsg->cmsg_len >= CMSG_LEN (sizeof (struct sockaddr_in)))
|
||||
+ {
|
||||
+ struct sockaddr_in sa;
|
||||
+ memcpy (&sa, CMSG_DATA (cmsg), sizeof (sa));
|
||||
+ if (test_verbose)
|
||||
+ {
|
||||
+ char str[INET_ADDRSTRLEN];
|
||||
+ inet_ntop (AF_INET, &sa.sin_addr, str, INET_ADDRSTRLEN);
|
||||
+ printf ("IP_ORIGDSTADDR: %s:%d\n", str, ntohs (sa.sin_port));
|
||||
+ }
|
||||
+ origdstaddr = sa.sin_addr.s_addr == srv_addr.sin_addr.s_addr
|
||||
+ && sa.sin_port == srv_addr.sin_port;
|
||||
+ }
|
||||
+ if (cmsg->cmsg_level == SOL_SOCKET
|
||||
+ && cmsg->cmsg_type == SCM_TIMESTAMP
|
||||
+ && cmsg->cmsg_len >= CMSG_LEN (sizeof (struct timeval)))
|
||||
+ {
|
||||
+ struct timeval tv;
|
||||
+ memcpy (&tv, CMSG_DATA (cmsg), sizeof (tv));
|
||||
+ if (test_verbose)
|
||||
+ printf ("SCM_TIMESTAMP: {%jd, %jd}\n", (intmax_t)tv.tv_sec,
|
||||
+ (intmax_t)tv.tv_usec);
|
||||
+ timestamp = true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ TEST_COMPARE (timestamp, true);
|
||||
+ TEST_COMPARE (origdstaddr, true);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+do_test_multiple_ancillary (void)
|
||||
+{
|
||||
+ {
|
||||
+ int r = setsockopt (srv, SOL_SOCKET, SO_TIMESTAMP, &(int){1},
|
||||
+ sizeof (int));
|
||||
+ TEST_VERIFY_EXIT (r != -1);
|
||||
+ }
|
||||
+ {
|
||||
+ int r = setsockopt (srv, IPPROTO_IP, IP_RECVORIGDSTADDR, &(int){1},
|
||||
+ sizeof (int));
|
||||
+ TEST_VERIFY_EXIT (r != -1);
|
||||
+ }
|
||||
+
|
||||
+ /* Enougth data for default SO_TIMESTAMP, the IP_RECVORIGDSTADDR, and the
|
||||
+ extra 64-bit SO_TIMESTAMP. */
|
||||
+ enum { msgbuflen = CMSG_SPACE (2 * sizeof (uint64_t))
|
||||
+ + CMSG_SPACE (sizeof (struct sockaddr_in))
|
||||
+ + CMSG_SPACE (2 * sizeof (uint64_t)) };
|
||||
+ char msgbuf[msgbuflen];
|
||||
+
|
||||
+ enum { nmsgs = 8 };
|
||||
+ /* Check recvmsg. */
|
||||
+ do_sendto (&srv_addr, nmsgs);
|
||||
+ for (int s = 0; s < nmsgs; s++)
|
||||
+ do_recvmsg_multiple_ancillary (false, srv, msgbuf, msgbuflen, s);
|
||||
+ /* Check recvmmsg. */
|
||||
+ do_sendto (&srv_addr, nmsgs);
|
||||
+ for (int s = 0; s < nmsgs; s++)
|
||||
+ do_recvmsg_multiple_ancillary (true, srv, msgbuf, msgbuflen, s);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ srv = xsocket (AF_INET, SOCK_DGRAM, 0);
|
||||
+ srv_addr = (struct sockaddr_in) {
|
||||
+ .sin_family = AF_INET,
|
||||
+ .sin_addr = {.s_addr = htonl (INADDR_LOOPBACK) },
|
||||
+ };
|
||||
+ xbind (srv, (struct sockaddr *) &srv_addr, sizeof (srv_addr));
|
||||
+ {
|
||||
+ socklen_t sa_len = sizeof (srv_addr);
|
||||
+ xgetsockname (srv, (struct sockaddr *) &srv_addr, &sa_len);
|
||||
+ TEST_VERIFY (sa_len == sizeof (srv_addr));
|
||||
+ }
|
||||
+
|
||||
+ TEST_COMPARE (recvmsg (-1, NULL, 0), -1);
|
||||
+ TEST_COMPARE (errno, EBADF);
|
||||
+ TEST_COMPARE (recvmmsg (-1, NULL, 0, 0, NULL), -1);
|
||||
+ TEST_COMPARE (errno, EBADF);
|
||||
+
|
||||
+ /* If underlying kernel does not support */
|
||||
+ support_64_timestamp = support_socket_so_timestamp_time64 (srv);
|
||||
+
|
||||
+ do_test_slack_space ();
|
||||
+ do_test_multiple_ancillary ();
|
||||
+
|
||||
+ xclose (srv);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
@ -0,0 +1,485 @@
|
||||
commit 489d0b8b32548bc569cd3067aebf98b030720753
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Thu Jan 27 16:45:18 2022 -0300
|
||||
|
||||
Linux: Only generate 64 bit timestamps for 64 bit time_t recvmsg/recvmmsg
|
||||
|
||||
The timestamps created by __convert_scm_timestamps only make sense for
|
||||
64 bit time_t programs, 32 bit time_t programs will ignore 64 bit time_t
|
||||
timestamps since SO_TIMESTAMP will be defined to old values (either by
|
||||
glibc or kernel headers).
|
||||
|
||||
Worse, if the buffer is not suffice MSG_CTRUNC is set to indicate it
|
||||
(which breaks some programs [1]).
|
||||
|
||||
This patch makes only 64 bit time_t recvmsg and recvmmsg to call
|
||||
__convert_scm_timestamps. Also, the assumption to called it is changed
|
||||
from __ASSUME_TIME64_SYSCALLS to __TIMESIZE != 64 since the setsockopt
|
||||
might be called by libraries built without __TIME_BITS=64. The
|
||||
MSG_CTRUNC is only set for the 64 bit symbols, it should happen only
|
||||
if 64 bit time_t programs run older kernels.
|
||||
|
||||
Checked on x86_64-linux-gnu and i686-linux-gnu.
|
||||
|
||||
[1] https://github.com/systemd/systemd/pull/20567
|
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
(cherry picked from commit 948ce73b31fdb0860bcec4b8e62b14e88234f98a)
|
||||
|
||||
diff --git a/include/sys/socket.h b/include/sys/socket.h
|
||||
index a1d749f9fa7b9257..6e4cf5077fb885a9 100644
|
||||
--- a/include/sys/socket.h
|
||||
+++ b/include/sys/socket.h
|
||||
@@ -98,15 +98,21 @@ extern int __sendmmsg (int __fd, struct mmsghdr *__vmessages,
|
||||
libc_hidden_proto (__sendmmsg)
|
||||
#endif
|
||||
|
||||
-/* Receive a message as described by MESSAGE from socket FD.
|
||||
- Returns the number of bytes read or -1 for errors. */
|
||||
extern ssize_t __libc_recvmsg (int __fd, struct msghdr *__message,
|
||||
int __flags);
|
||||
extern ssize_t __recvmsg (int __fd, struct msghdr *__message,
|
||||
int __flags) attribute_hidden;
|
||||
#if __TIMESIZE == 64
|
||||
+# define __libc_recvmsg64 __libc_recvmsg
|
||||
+# define __recvmsg64 __recvmsg
|
||||
# define __recvmmsg64 __recvmmsg
|
||||
#else
|
||||
+extern ssize_t __libc_recvmsg64 (int __fd, struct msghdr *__message,
|
||||
+ int __flags);
|
||||
+extern ssize_t __recvmsg64 (int __fd, struct msghdr *__message,
|
||||
+ int __flags);
|
||||
+/* Receive a message as described by MESSAGE from socket FD.
|
||||
+ Returns the number of bytes read or -1 for errors. */
|
||||
extern int __recvmmsg64 (int __fd, struct mmsghdr *vmessages,
|
||||
unsigned int vlen, int flags,
|
||||
struct __timespec64 *timeout);
|
||||
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
|
||||
index 7c75e22c6d0e9ff5..0657f4003e7116c6 100644
|
||||
--- a/sysdeps/unix/sysv/linux/Makefile
|
||||
+++ b/sysdeps/unix/sysv/linux/Makefile
|
||||
@@ -273,8 +273,14 @@ sysdep_routines += cmsg_nxthdr
|
||||
CFLAGS-recvmmsg.c = -fexceptions -fasynchronous-unwind-tables
|
||||
CFLAGS-sendmmsg.c = -fexceptions -fasynchronous-unwind-tables
|
||||
|
||||
-tests += tst-socket-timestamp
|
||||
-tests-time64 += tst-socket-timestamp-time64
|
||||
+tests += \
|
||||
+ tst-socket-timestamp \
|
||||
+ tst-socket-timestamp-compat \
|
||||
+ # tests
|
||||
+tests-time64 += \
|
||||
+ tst-socket-timestamp-time64 \
|
||||
+ tst-socket-timestamp-compat-time64
|
||||
+ # tests-time64
|
||||
|
||||
tests-special += $(objpfx)tst-socket-consts.out
|
||||
$(objpfx)tst-socket-consts.out: ../sysdeps/unix/sysv/linux/tst-socket-consts.py
|
||||
diff --git a/sysdeps/unix/sysv/linux/recvmmsg.c b/sysdeps/unix/sysv/linux/recvmmsg.c
|
||||
index 5cd107ffa9be0699..fca9f6582db67fd7 100644
|
||||
--- a/sysdeps/unix/sysv/linux/recvmmsg.c
|
||||
+++ b/sysdeps/unix/sysv/linux/recvmmsg.c
|
||||
@@ -20,9 +20,9 @@
|
||||
#include <sysdep.h>
|
||||
#include <socketcall.h>
|
||||
|
||||
-int
|
||||
-__recvmmsg64 (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
|
||||
- struct __timespec64 *timeout)
|
||||
+static int
|
||||
+recvmmsg_syscall (int fd, struct mmsghdr *vmessages, unsigned int vlen,
|
||||
+ int flags, struct __timespec64 *timeout)
|
||||
{
|
||||
#ifndef __NR_recvmmsg_time64
|
||||
# define __NR_recvmmsg_time64 __NR_recvmmsg
|
||||
@@ -45,12 +45,6 @@ __recvmmsg64 (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
|
||||
pts32 = &ts32;
|
||||
}
|
||||
|
||||
- socklen_t csize[IOV_MAX];
|
||||
- if (vlen > IOV_MAX)
|
||||
- vlen = IOV_MAX;
|
||||
- for (int i = 0; i < vlen; i++)
|
||||
- csize[i] = vmessages[i].msg_hdr.msg_controllen;
|
||||
-
|
||||
# ifdef __ASSUME_RECVMMSG_SYSCALL
|
||||
r = SYSCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, pts32);
|
||||
# else
|
||||
@@ -60,11 +54,31 @@ __recvmmsg64 (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
|
||||
{
|
||||
if (timeout != NULL)
|
||||
*timeout = valid_timespec_to_timespec64 (ts32);
|
||||
+ }
|
||||
+#endif
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+__recvmmsg64 (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
|
||||
+ struct __timespec64 *timeout)
|
||||
+{
|
||||
+#if __TIMESIZE != 64
|
||||
+ socklen_t csize[IOV_MAX];
|
||||
+ if (vlen > IOV_MAX)
|
||||
+ vlen = IOV_MAX;
|
||||
+ for (int i = 0; i < vlen; i++)
|
||||
+ csize[i] = vmessages[i].msg_hdr.msg_controllen;
|
||||
+#endif
|
||||
|
||||
+ int r = recvmmsg_syscall (fd, vmessages, vlen, flags, timeout);
|
||||
+#if __TIMESIZE != 64
|
||||
+ if (r > 0)
|
||||
+ {
|
||||
for (int i=0; i < r; i++)
|
||||
__convert_scm_timestamps (&vmessages[i].msg_hdr, csize[i]);
|
||||
}
|
||||
-#endif /* __ASSUME_TIME64_SYSCALLS */
|
||||
+#endif
|
||||
return r;
|
||||
}
|
||||
#if __TIMESIZE != 64
|
||||
@@ -80,7 +94,7 @@ __recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
|
||||
ts64 = valid_timespec_to_timespec64 (*timeout);
|
||||
pts64 = &ts64;
|
||||
}
|
||||
- int r = __recvmmsg64 (fd, vmessages, vlen, flags, pts64);
|
||||
+ int r = recvmmsg_syscall (fd, vmessages, vlen, flags, pts64);
|
||||
if (r >= 0 && timeout != NULL)
|
||||
/* The remanining timeout will be always less the input TIMEOUT. */
|
||||
*timeout = valid_timespec64_to_timespec (ts64);
|
||||
diff --git a/sysdeps/unix/sysv/linux/recvmsg.c b/sysdeps/unix/sysv/linux/recvmsg.c
|
||||
index 07212f7c8641a921..c4b4704fd65d80c1 100644
|
||||
--- a/sysdeps/unix/sysv/linux/recvmsg.c
|
||||
+++ b/sysdeps/unix/sysv/linux/recvmsg.c
|
||||
@@ -20,29 +20,41 @@
|
||||
#include <sysdep-cancel.h>
|
||||
#include <socketcall.h>
|
||||
|
||||
+static int
|
||||
+__recvmsg_syscall (int fd, struct msghdr *msg, int flags)
|
||||
+{
|
||||
+#ifdef __ASSUME_RECVMSG_SYSCALL
|
||||
+ return SYSCALL_CANCEL (recvmsg, fd, msg, flags);
|
||||
+#else
|
||||
+ return SOCKETCALL_CANCEL (recvmsg, fd, msg, flags);
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
ssize_t
|
||||
-__libc_recvmsg (int fd, struct msghdr *msg, int flags)
|
||||
+__libc_recvmsg64 (int fd, struct msghdr *msg, int flags)
|
||||
{
|
||||
ssize_t r;
|
||||
-#ifndef __ASSUME_TIME64_SYSCALLS
|
||||
+#if __TIMESIZE != 64
|
||||
socklen_t orig_controllen = msg != NULL ? msg->msg_controllen : 0;
|
||||
#endif
|
||||
|
||||
-#ifdef __ASSUME_RECVMSG_SYSCALL
|
||||
- r = SYSCALL_CANCEL (recvmsg, fd, msg, flags);
|
||||
-#else
|
||||
- r = SOCKETCALL_CANCEL (recvmsg, fd, msg, flags);
|
||||
-#endif
|
||||
+ r = __recvmsg_syscall (fd, msg, flags);
|
||||
|
||||
-#ifndef __ASSUME_TIME64_SYSCALLS
|
||||
+#if __TIMESIZE != 64
|
||||
if (r >= 0 && orig_controllen != 0)
|
||||
__convert_scm_timestamps (msg, orig_controllen);
|
||||
#endif
|
||||
|
||||
return r;
|
||||
}
|
||||
-weak_alias (__libc_recvmsg, recvmsg)
|
||||
-weak_alias (__libc_recvmsg, __recvmsg)
|
||||
#if __TIMESIZE != 64
|
||||
-weak_alias (__recvmsg, __recvmsg64)
|
||||
+weak_alias (__libc_recvmsg64, __recvmsg64)
|
||||
+
|
||||
+ssize_t
|
||||
+__libc_recvmsg (int fd, struct msghdr *msg, int flags)
|
||||
+{
|
||||
+ return __recvmsg_syscall (fd, msg, flags);
|
||||
+}
|
||||
#endif
|
||||
+weak_alias (__libc_recvmsg, recvmsg)
|
||||
+weak_alias (__libc_recvmsg, __recvmsg)
|
||||
diff --git a/sysdeps/unix/sysv/linux/tst-socket-timestamp-compat-time64.c b/sysdeps/unix/sysv/linux/tst-socket-timestamp-compat-time64.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..96a0bef0bf4a908b
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/unix/sysv/linux/tst-socket-timestamp-compat-time64.c
|
||||
@@ -0,0 +1 @@
|
||||
+#include "tst-socket-timestamp-compat.c"
|
||||
diff --git a/sysdeps/unix/sysv/linux/tst-socket-timestamp-compat.c b/sysdeps/unix/sysv/linux/tst-socket-timestamp-compat.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..de261dae5a6385cf
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/unix/sysv/linux/tst-socket-timestamp-compat.c
|
||||
@@ -0,0 +1,265 @@
|
||||
+/* Check recvmsg/recvmmsg 64-bit timestamp support.
|
||||
+ 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/>. */
|
||||
+
|
||||
+#include <arpa/inet.h>
|
||||
+#include <string.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/xsocket.h>
|
||||
+#include <support/xunistd.h>
|
||||
+#include <stdbool.h>
|
||||
+
|
||||
+/* AF_INET socket and address used to receive data. */
|
||||
+static int srv;
|
||||
+static struct sockaddr_in srv_addr;
|
||||
+
|
||||
+static int
|
||||
+do_sendto (const struct sockaddr_in *addr, int payload)
|
||||
+{
|
||||
+ int s = xsocket (AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
|
||||
+ xconnect (s, (const struct sockaddr *) addr, sizeof (*addr));
|
||||
+
|
||||
+ xsendto (s, &payload, sizeof (payload), 0, (const struct sockaddr *) addr,
|
||||
+ sizeof (*addr));
|
||||
+
|
||||
+ xclose (s);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+do_recvmsg_ancillary (bool use_multi_call, struct mmsghdr *mmhdr,
|
||||
+ void *msgbuf, size_t msgbuflen, int exp_payload)
|
||||
+{
|
||||
+ int payload;
|
||||
+ struct iovec iov =
|
||||
+ {
|
||||
+ .iov_base = &payload,
|
||||
+ .iov_len = sizeof (payload)
|
||||
+ };
|
||||
+ mmhdr->msg_hdr.msg_name = NULL;
|
||||
+ mmhdr->msg_hdr.msg_iov = &iov;
|
||||
+ mmhdr->msg_hdr.msg_iovlen = 1;
|
||||
+ mmhdr->msg_hdr.msg_control = msgbuf;
|
||||
+ mmhdr->msg_hdr.msg_controllen = msgbuflen;
|
||||
+
|
||||
+ int r;
|
||||
+ if (use_multi_call)
|
||||
+ {
|
||||
+ r = recvmmsg (srv, mmhdr, 1, 0, NULL);
|
||||
+ if (r >= 0)
|
||||
+ r = mmhdr->msg_len;
|
||||
+ }
|
||||
+ else
|
||||
+ r = recvmsg (srv, &mmhdr->msg_hdr, 0);
|
||||
+ TEST_COMPARE (r, sizeof (int));
|
||||
+ TEST_COMPARE (payload, exp_payload);
|
||||
+}
|
||||
+
|
||||
+/* Check if recvmsg create the additional 64 bit timestamp if only 32 bit
|
||||
+ is enabled for 64 bit recvmsg symbol. */
|
||||
+static void
|
||||
+do_test_large_buffer (bool mc)
|
||||
+{
|
||||
+ struct mmsghdr mmhdr = { 0 };
|
||||
+ /* It should be large enought for either timeval/timespec and the
|
||||
+ 64 time type as well. */
|
||||
+
|
||||
+ union
|
||||
+ {
|
||||
+ struct cmsghdr cmsghdr;
|
||||
+ char msgbuf[512];
|
||||
+ } control;
|
||||
+
|
||||
+ /* Enable 32 bit timeval precision and check if no 64 bit timeval stamp
|
||||
+ is created. */
|
||||
+ {
|
||||
+ int r = setsockopt (srv, SOL_SOCKET, SO_TIMESTAMP_OLD, &(int){1},
|
||||
+ sizeof (int));
|
||||
+ TEST_VERIFY_EXIT (r != -1);
|
||||
+
|
||||
+ do_sendto (&srv_addr, 42);
|
||||
+ do_recvmsg_ancillary (mc, &mmhdr, &control, sizeof control, 42);
|
||||
+
|
||||
+ bool found_timestamp = false;
|
||||
+ for (struct cmsghdr *cmsg = CMSG_FIRSTHDR (&mmhdr.msg_hdr);
|
||||
+ cmsg != NULL;
|
||||
+ cmsg = CMSG_NXTHDR (&mmhdr.msg_hdr, cmsg))
|
||||
+ {
|
||||
+ if (cmsg->cmsg_level != SOL_SOCKET)
|
||||
+ continue;
|
||||
+
|
||||
+ if (sizeof (time_t) > 4 && cmsg->cmsg_type == SO_TIMESTAMP_NEW)
|
||||
+ found_timestamp = true;
|
||||
+ else
|
||||
+ TEST_VERIFY (cmsg->cmsg_type != SO_TIMESTAMP_NEW);
|
||||
+ }
|
||||
+
|
||||
+ TEST_COMPARE (found_timestamp, sizeof (time_t) > 4);
|
||||
+ }
|
||||
+
|
||||
+ /* Same as before, but for timespec. */
|
||||
+ {
|
||||
+ int r = setsockopt (srv, SOL_SOCKET, SO_TIMESTAMPNS_OLD, &(int){1},
|
||||
+ sizeof (int));
|
||||
+ TEST_VERIFY_EXIT (r != -1);
|
||||
+
|
||||
+ do_sendto (&srv_addr, 42);
|
||||
+ do_recvmsg_ancillary (mc, &mmhdr, &control, sizeof control, 42);
|
||||
+
|
||||
+ bool found_timestamp = false;
|
||||
+ for (struct cmsghdr *cmsg = CMSG_FIRSTHDR (&mmhdr.msg_hdr);
|
||||
+ cmsg != NULL;
|
||||
+ cmsg = CMSG_NXTHDR (&mmhdr.msg_hdr, cmsg))
|
||||
+ {
|
||||
+ if (cmsg->cmsg_level != SOL_SOCKET)
|
||||
+ continue;
|
||||
+
|
||||
+ if (sizeof (time_t) > 4 && cmsg->cmsg_type == SO_TIMESTAMPNS_NEW)
|
||||
+ found_timestamp = true;
|
||||
+ else
|
||||
+ TEST_VERIFY (cmsg->cmsg_type != SO_TIMESTAMPNS_NEW);
|
||||
+ }
|
||||
+
|
||||
+ TEST_COMPARE (found_timestamp, sizeof (time_t) > 4);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* Check if recvmsg does not create the additional 64 bit timestamp if
|
||||
+ only 32 bit timestamp is enabled if the ancillary buffer is not large
|
||||
+ enought. Also checks if MSG_CTRUNC is set iff for 64 bit recvmsg
|
||||
+ symbol. */
|
||||
+static void
|
||||
+do_test_small_buffer (bool mc)
|
||||
+{
|
||||
+ struct mmsghdr mmhdr = { 0 };
|
||||
+
|
||||
+ /* Enable 32 bit timeval precision and check if no 64 bit timeval stamp
|
||||
+ is created. */
|
||||
+ {
|
||||
+ int r = setsockopt (srv, SOL_SOCKET, SO_TIMESTAMP_OLD, &(int){1},
|
||||
+ sizeof (int));
|
||||
+ TEST_VERIFY_EXIT (r != -1);
|
||||
+
|
||||
+ union
|
||||
+ {
|
||||
+ struct cmsghdr cmsghdr;
|
||||
+ char msgbuf[CMSG_SPACE (sizeof (struct timeval))];
|
||||
+ } control;
|
||||
+
|
||||
+ do_sendto (&srv_addr, 42);
|
||||
+ do_recvmsg_ancillary (mc, &mmhdr, &control, sizeof control, 42);
|
||||
+
|
||||
+ bool found_timestamp = false;
|
||||
+ for (struct cmsghdr *cmsg = CMSG_FIRSTHDR (&mmhdr.msg_hdr);
|
||||
+ cmsg != NULL;
|
||||
+ cmsg = CMSG_NXTHDR (&mmhdr.msg_hdr, cmsg))
|
||||
+ {
|
||||
+ if (cmsg->cmsg_level != SOL_SOCKET)
|
||||
+ continue;
|
||||
+
|
||||
+ if (sizeof (time_t) > 4 && cmsg->cmsg_type == SO_TIMESTAMP_NEW)
|
||||
+ found_timestamp = true;
|
||||
+ else
|
||||
+ TEST_VERIFY (cmsg->cmsg_type != SO_TIMESTAMP_NEW);
|
||||
+ }
|
||||
+
|
||||
+ if (sizeof (time_t) > 4)
|
||||
+ {
|
||||
+ TEST_VERIFY ((mmhdr.msg_hdr.msg_flags & MSG_CTRUNC));
|
||||
+ TEST_COMPARE (found_timestamp, 0);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ TEST_VERIFY (!(mmhdr.msg_hdr.msg_flags & MSG_CTRUNC));
|
||||
+ TEST_COMPARE (found_timestamp, 0);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Same as before, but for timespec. */
|
||||
+ {
|
||||
+ int r = setsockopt (srv, SOL_SOCKET, SO_TIMESTAMPNS_OLD, &(int){1},
|
||||
+ sizeof (int));
|
||||
+ TEST_VERIFY_EXIT (r != -1);
|
||||
+
|
||||
+ union
|
||||
+ {
|
||||
+ struct cmsghdr cmsghdr;
|
||||
+ char msgbuf[CMSG_SPACE (sizeof (struct timespec))];
|
||||
+ } control;
|
||||
+
|
||||
+ do_sendto (&srv_addr, 42);
|
||||
+ do_recvmsg_ancillary (mc, &mmhdr, &control, sizeof control, 42);
|
||||
+
|
||||
+ bool found_timestamp = false;
|
||||
+ for (struct cmsghdr *cmsg = CMSG_FIRSTHDR (&mmhdr.msg_hdr);
|
||||
+ cmsg != NULL;
|
||||
+ cmsg = CMSG_NXTHDR (&mmhdr.msg_hdr, cmsg))
|
||||
+ {
|
||||
+ if (cmsg->cmsg_level != SOL_SOCKET)
|
||||
+ continue;
|
||||
+
|
||||
+ if (sizeof (time_t) > 4 && cmsg->cmsg_type == SO_TIMESTAMPNS_NEW)
|
||||
+ found_timestamp = true;
|
||||
+ else
|
||||
+ TEST_VERIFY (cmsg->cmsg_type != SO_TIMESTAMPNS_NEW);
|
||||
+ }
|
||||
+
|
||||
+ if (sizeof (time_t) > 4)
|
||||
+ {
|
||||
+ TEST_VERIFY ((mmhdr.msg_hdr.msg_flags & MSG_CTRUNC));
|
||||
+ TEST_COMPARE (found_timestamp, 0);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ TEST_VERIFY ((mmhdr.msg_hdr.msg_flags & MSG_CTRUNC) == 0);
|
||||
+ TEST_COMPARE (found_timestamp, 0);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ /* This test only make sense for ABIs that support 32 bit time_t socket
|
||||
+ timestampss. */
|
||||
+ if (sizeof (time_t) > 4 && __WORDSIZE == 64)
|
||||
+ return 0;
|
||||
+
|
||||
+ srv = xsocket (AF_INET, SOCK_DGRAM, 0);
|
||||
+ srv_addr = (struct sockaddr_in) {
|
||||
+ .sin_family = AF_INET,
|
||||
+ .sin_addr = {.s_addr = htonl (INADDR_LOOPBACK) },
|
||||
+ };
|
||||
+ xbind (srv, (struct sockaddr *) &srv_addr, sizeof (srv_addr));
|
||||
+ {
|
||||
+ socklen_t sa_len = sizeof (srv_addr);
|
||||
+ xgetsockname (srv, (struct sockaddr *) &srv_addr, &sa_len);
|
||||
+ TEST_VERIFY (sa_len == sizeof (srv_addr));
|
||||
+ }
|
||||
+
|
||||
+ /* Check recvmsg; */
|
||||
+ do_test_large_buffer (false);
|
||||
+ do_test_small_buffer (false);
|
||||
+ /* Check recvmmsg. */
|
||||
+ do_test_large_buffer (true);
|
||||
+ do_test_small_buffer (true);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
@ -0,0 +1,24 @@
|
||||
commit 008003dc6e83439c5e04a744b7fd8197df19096e
|
||||
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||
Date: Sat Jan 29 05:22:31 2022 -0800
|
||||
|
||||
tst-socket-timestamp-compat.c: Check __TIMESIZE [BZ #28837]
|
||||
|
||||
time_t size is defined by __TIMESIZE, not __WORDSIZE. Check __TIMESIZE,
|
||||
instead of __WORDSIZE, for time_t size. This fixes BZ #28837.
|
||||
|
||||
(cherry pick from commit 77a602ebb0769e7ccc5f9f8e06f7fffe66f69dfc)
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/tst-socket-timestamp-compat.c b/sysdeps/unix/sysv/linux/tst-socket-timestamp-compat.c
|
||||
index de261dae5a6385cf..0ff1a214e605105b 100644
|
||||
--- a/sysdeps/unix/sysv/linux/tst-socket-timestamp-compat.c
|
||||
+++ b/sysdeps/unix/sysv/linux/tst-socket-timestamp-compat.c
|
||||
@@ -237,7 +237,7 @@ do_test (void)
|
||||
{
|
||||
/* This test only make sense for ABIs that support 32 bit time_t socket
|
||||
timestampss. */
|
||||
- if (sizeof (time_t) > 4 && __WORDSIZE == 64)
|
||||
+ if (sizeof (time_t) > 4 && __TIMESIZE == 64)
|
||||
return 0;
|
||||
|
||||
srv = xsocket (AF_INET, SOCK_DGRAM, 0);
|
@ -0,0 +1,26 @@
|
||||
commit 05c83ccaf50aef2dd30d92cbb814383f6bddea2c
|
||||
Author: Gleb Fotengauer-Malinovskiy <glebfm@altlinux.org>
|
||||
Date: Tue Feb 1 22:39:02 2022 +0000
|
||||
|
||||
linux: __get_nprocs_sched: do not feed CPU_COUNT_S with garbage [BZ #28850]
|
||||
|
||||
Pass the actual number of bytes returned by the kernel.
|
||||
|
||||
Fixes: 33099d72e41c ("linux: Simplify get_nprocs")
|
||||
Reviewed-by: Dmitry V. Levin <ldv@altlinux.org>
|
||||
|
||||
(cherry picked from commit 97ba273b505763325efd802dc3a9562dbba79579)
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c
|
||||
index 7fc6521942e87293..7babd947aa902e77 100644
|
||||
--- a/sysdeps/unix/sysv/linux/getsysstats.c
|
||||
+++ b/sysdeps/unix/sysv/linux/getsysstats.c
|
||||
@@ -45,7 +45,7 @@ __get_nprocs_sched (void)
|
||||
int r = INTERNAL_SYSCALL_CALL (sched_getaffinity, 0, cpu_bits_size,
|
||||
cpu_bits);
|
||||
if (r > 0)
|
||||
- return CPU_COUNT_S (cpu_bits_size, (cpu_set_t*) cpu_bits);
|
||||
+ return CPU_COUNT_S (r, (cpu_set_t*) cpu_bits);
|
||||
else if (r == -EINVAL)
|
||||
/* The input buffer is still not enough to store the number of cpus. This
|
||||
is an arbitrary values assuming such systems should be rare and there
|
@ -0,0 +1,234 @@
|
||||
commit ad615b59c78d6d37fee921fb2b2ae6b72c930625
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Sep 28 18:55:49 2021 +0200
|
||||
|
||||
Linux: Simplify __opensock and fix race condition [BZ #28353]
|
||||
|
||||
AF_NETLINK support is not quite optional on modern Linux systems
|
||||
anymore, so it is likely that the first attempt will always succeed.
|
||||
Consequently, there is no need to cache the result. Keep AF_UNIX
|
||||
and the Internet address families as a fallback, for the rare case
|
||||
that AF_NETLINK is missing. The other address families previously
|
||||
probed are totally obsolete be now, so remove them.
|
||||
|
||||
Use this simplified version as the generic implementation, disabling
|
||||
Netlink support as needed.
|
||||
|
||||
(cherry picked from commit 5bf07e1b3a74232bfb8332275110be1a5da50f83)
|
||||
|
||||
diff --git a/socket/opensock.c b/socket/opensock.c
|
||||
index 37148d4743343ff4..ff94d27a61bd3889 100644
|
||||
--- a/socket/opensock.c
|
||||
+++ b/socket/opensock.c
|
||||
@@ -1,4 +1,5 @@
|
||||
-/* Copyright (C) 1999-2021 Free Software Foundation, Inc.
|
||||
+/* Create socket with an unspecified address family for use with ioctl.
|
||||
+ Copyright (C) 1999-2021 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
|
||||
@@ -15,56 +16,34 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
-#include <stdio.h>
|
||||
+#include <errno.h>
|
||||
#include <sys/socket.h>
|
||||
-#include <libc-lock.h>
|
||||
|
||||
/* Return a socket of any type. The socket can be used in subsequent
|
||||
ioctl calls to talk to the kernel. */
|
||||
int
|
||||
__opensock (void)
|
||||
{
|
||||
- /* Cache the last AF that worked, to avoid many redundant calls to
|
||||
- socket(). */
|
||||
- static int sock_af = -1;
|
||||
- int fd = -1;
|
||||
- __libc_lock_define_initialized (static, lock);
|
||||
-
|
||||
- if (sock_af != -1)
|
||||
- {
|
||||
- fd = __socket (sock_af, SOCK_DGRAM, 0);
|
||||
- if (fd != -1)
|
||||
- return fd;
|
||||
- }
|
||||
-
|
||||
- __libc_lock_lock (lock);
|
||||
-
|
||||
- if (sock_af != -1)
|
||||
- fd = __socket (sock_af, SOCK_DGRAM, 0);
|
||||
-
|
||||
- if (fd == -1)
|
||||
- {
|
||||
-#ifdef AF_INET
|
||||
- fd = __socket (sock_af = AF_INET, SOCK_DGRAM, 0);
|
||||
-#endif
|
||||
-#ifdef AF_INET6
|
||||
- if (fd < 0)
|
||||
- fd = __socket (sock_af = AF_INET6, SOCK_DGRAM, 0);
|
||||
-#endif
|
||||
-#ifdef AF_IPX
|
||||
- if (fd < 0)
|
||||
- fd = __socket (sock_af = AF_IPX, SOCK_DGRAM, 0);
|
||||
-#endif
|
||||
-#ifdef AF_AX25
|
||||
- if (fd < 0)
|
||||
- fd = __socket (sock_af = AF_AX25, SOCK_DGRAM, 0);
|
||||
-#endif
|
||||
-#ifdef AF_APPLETALK
|
||||
- if (fd < 0)
|
||||
- fd = __socket (sock_af = AF_APPLETALK, SOCK_DGRAM, 0);
|
||||
+ /* SOCK_DGRAM is supported by all address families. (Netlink does
|
||||
+ not support SOCK_STREAM.) */
|
||||
+ int type = SOCK_DGRAM | SOCK_CLOEXEC;
|
||||
+ int fd;
|
||||
+
|
||||
+#ifdef AF_NETLINK
|
||||
+ fd = __socket (AF_NETLINK, type, 0);
|
||||
+ if (fd >= 0)
|
||||
+ return fd;
|
||||
#endif
|
||||
- }
|
||||
|
||||
- __libc_lock_unlock (lock);
|
||||
+ fd = __socket (AF_UNIX, type, 0);
|
||||
+ if (fd >= 0)
|
||||
+ return fd;
|
||||
+ fd = __socket (AF_INET, type, 0);
|
||||
+ if (fd >= 0)
|
||||
+ return fd;
|
||||
+ fd = __socket (AF_INET6, type, 0);
|
||||
+ if (fd >= 0)
|
||||
+ return fd;
|
||||
+ __set_errno (ENOENT);
|
||||
return fd;
|
||||
}
|
||||
diff --git a/sysdeps/unix/sysv/linux/opensock.c b/sysdeps/unix/sysv/linux/opensock.c
|
||||
deleted file mode 100644
|
||||
index e87d6e58b0b84f82..0000000000000000
|
||||
--- a/sysdeps/unix/sysv/linux/opensock.c
|
||||
+++ /dev/null
|
||||
@@ -1,114 +0,0 @@
|
||||
-/* Copyright (C) 1999-2021 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/>. */
|
||||
-
|
||||
-#include <assert.h>
|
||||
-#include <errno.h>
|
||||
-#include <stdio.h>
|
||||
-#include <string.h>
|
||||
-#include <unistd.h>
|
||||
-#include <sys/socket.h>
|
||||
-
|
||||
-/* Return a socket of any type. The socket can be used in subsequent
|
||||
- ioctl calls to talk to the kernel. */
|
||||
-int
|
||||
-__opensock (void)
|
||||
-{
|
||||
- static int last_family; /* Available socket family we will use. */
|
||||
- static int last_type;
|
||||
- static const struct
|
||||
- {
|
||||
- int family;
|
||||
- const char procname[15];
|
||||
- } afs[] =
|
||||
- {
|
||||
- { AF_UNIX, "net/unix" },
|
||||
- { AF_INET, "" },
|
||||
- { AF_INET6, "net/if_inet6" },
|
||||
- { AF_AX25, "net/ax25" },
|
||||
- { AF_NETROM, "net/nr" },
|
||||
- { AF_ROSE, "net/rose" },
|
||||
- { AF_IPX, "net/ipx" },
|
||||
- { AF_APPLETALK, "net/appletalk" },
|
||||
- { AF_ECONET, "sys/net/econet" },
|
||||
- { AF_ASH, "sys/net/ash" },
|
||||
- { AF_X25, "net/x25" },
|
||||
-#ifdef NEED_AF_IUCV
|
||||
- { AF_IUCV, "net/iucv" }
|
||||
-#endif
|
||||
- };
|
||||
-#define nafs (sizeof (afs) / sizeof (afs[0]))
|
||||
- char fname[sizeof "/proc/" + 14];
|
||||
- int result;
|
||||
- int has_proc;
|
||||
- size_t cnt;
|
||||
-
|
||||
- /* We already know which family to use from the last call. Use it
|
||||
- again. */
|
||||
- if (last_family != 0)
|
||||
- {
|
||||
- assert (last_type != 0);
|
||||
-
|
||||
- result = __socket (last_family, last_type | SOCK_CLOEXEC, 0);
|
||||
- if (result != -1 || errno != EAFNOSUPPORT)
|
||||
- /* Maybe the socket type isn't supported anymore (module is
|
||||
- unloaded). In this case again try to find the type. */
|
||||
- return result;
|
||||
-
|
||||
- /* Reset the values. They seem not valid anymore. */
|
||||
- last_family = 0;
|
||||
- last_type = 0;
|
||||
- }
|
||||
-
|
||||
- /* Check whether the /proc filesystem is available. */
|
||||
- has_proc = __access ("/proc/net", R_OK) != -1;
|
||||
- strcpy (fname, "/proc/");
|
||||
-
|
||||
- /* Iterate over the interface families and find one which is
|
||||
- available. */
|
||||
- for (cnt = 0; cnt < nafs; ++cnt)
|
||||
- {
|
||||
- int type = SOCK_DGRAM;
|
||||
-
|
||||
- if (has_proc && afs[cnt].procname[0] != '\0')
|
||||
- {
|
||||
- strcpy (fname + 6, afs[cnt].procname);
|
||||
- if (__access (fname, R_OK) == -1)
|
||||
- /* The /proc entry is not available. I.e., we cannot
|
||||
- create a socket of this type (without loading the
|
||||
- module). Don't look for it since this might trigger
|
||||
- loading the module. */
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- if (afs[cnt].family == AF_NETROM || afs[cnt].family == AF_X25)
|
||||
- type = SOCK_SEQPACKET;
|
||||
-
|
||||
- result = __socket (afs[cnt].family, type | SOCK_CLOEXEC, 0);
|
||||
- if (result != -1)
|
||||
- {
|
||||
- /* Found an available family. */
|
||||
- last_type = type;
|
||||
- last_family = afs[cnt].family;
|
||||
- return result;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /* None of the protocol families is available. It is unclear what kind
|
||||
- of error is returned. ENOENT seems like a reasonable choice. */
|
||||
- __set_errno (ENOENT);
|
||||
- return -1;
|
||||
-}
|
||||
diff --git a/sysdeps/unix/sysv/linux/s390/opensock.c b/sysdeps/unix/sysv/linux/s390/opensock.c
|
||||
deleted file mode 100644
|
||||
index f099d651ff04d211..0000000000000000
|
||||
--- a/sysdeps/unix/sysv/linux/s390/opensock.c
|
||||
+++ /dev/null
|
||||
@@ -1,2 +0,0 @@
|
||||
-#define NEED_AF_IUCV 1
|
||||
-#include "../opensock.c"
|
@ -0,0 +1,44 @@
|
||||
commit d8302ba2da1e5ac59a1c4dc1c1207a10fdafdb08
|
||||
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
|
||||
Date: Mon Oct 18 01:39:02 2021 +0200
|
||||
|
||||
hurd if_index: Explicitly use AF_INET for if index discovery
|
||||
|
||||
5bf07e1b3a74 ("Linux: Simplify __opensock and fix race condition [BZ #28353]")
|
||||
made __opensock try NETLINK then UNIX then INET. On the Hurd, only INET
|
||||
knows about network interfaces, so better actually specify that in
|
||||
if_index.
|
||||
|
||||
(cherry picked from commit 1d3decee997ba2fc24af81803299b2f4f3c47063)
|
||||
|
||||
diff --git a/sysdeps/mach/hurd/if_index.c b/sysdeps/mach/hurd/if_index.c
|
||||
index 0eab510453c9e861..e785ac15aa6a1002 100644
|
||||
--- a/sysdeps/mach/hurd/if_index.c
|
||||
+++ b/sysdeps/mach/hurd/if_index.c
|
||||
@@ -32,7 +32,7 @@ unsigned int
|
||||
__if_nametoindex (const char *ifname)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
- int fd = __opensock ();
|
||||
+ int fd = __socket (AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
if (fd < 0)
|
||||
return 0;
|
||||
@@ -84,7 +84,7 @@ __if_nameindex (void)
|
||||
error_t err = 0;
|
||||
char data[2048];
|
||||
file_t server;
|
||||
- int fd = __opensock ();
|
||||
+ int fd = __socket (AF_INET, SOCK_DGRAM, 0);
|
||||
struct ifconf ifc;
|
||||
unsigned int nifs, i;
|
||||
struct if_nameindex *idx = NULL;
|
||||
@@ -169,7 +169,7 @@ char *
|
||||
__if_indextoname (unsigned int ifindex, char ifname[IF_NAMESIZE])
|
||||
{
|
||||
struct ifreq ifr;
|
||||
- int fd = __opensock ();
|
||||
+ int fd = __socket (AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
if (fd < 0)
|
||||
return NULL;
|
@ -0,0 +1,35 @@
|
||||
commit 6eaf10cbb78d22eae7999d9de55f6b93999e0860
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Nov 22 14:41:14 2021 +0100
|
||||
|
||||
socket: Do not use AF_NETLINK in __opensock
|
||||
|
||||
It is not possible to use interface ioctls with netlink sockets
|
||||
on all Linux kernels.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
(cherry picked from commit 3d981795cd00cc9b73c3ee5087c308361acd62e5)
|
||||
|
||||
diff --git a/socket/opensock.c b/socket/opensock.c
|
||||
index ff94d27a61bd3889..3e35821f91643456 100644
|
||||
--- a/socket/opensock.c
|
||||
+++ b/socket/opensock.c
|
||||
@@ -24,17 +24,10 @@
|
||||
int
|
||||
__opensock (void)
|
||||
{
|
||||
- /* SOCK_DGRAM is supported by all address families. (Netlink does
|
||||
- not support SOCK_STREAM.) */
|
||||
+ /* SOCK_DGRAM is supported by all address families. */
|
||||
int type = SOCK_DGRAM | SOCK_CLOEXEC;
|
||||
int fd;
|
||||
|
||||
-#ifdef AF_NETLINK
|
||||
- fd = __socket (AF_NETLINK, type, 0);
|
||||
- if (fd >= 0)
|
||||
- return fd;
|
||||
-#endif
|
||||
-
|
||||
fd = __socket (AF_UNIX, type, 0);
|
||||
if (fd >= 0)
|
||||
return fd;
|
@ -0,0 +1,32 @@
|
||||
commit 0351c75c5f94134fcec0e778e8cf86d149f8bbfb
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Thu Feb 3 16:52:52 2022 -0300
|
||||
|
||||
linux: Fix missing __convert_scm_timestamps (BZ #28860)
|
||||
|
||||
Commit 948ce73b31 made recvmsg/recvmmsg to always call
|
||||
__convert_scm_timestamps for 64 bit time_t symbol, so adjust it to
|
||||
always build it for __TIMESIZE != 64.
|
||||
|
||||
It fixes build for architecture with 32 bit time_t support when
|
||||
configured with minimum kernel of 5.1.
|
||||
|
||||
(cherry-picked from 798d716df71fb23dc89d1d5dba1fc26a1b5c0024)
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/convert_scm_timestamps.c b/sysdeps/unix/sysv/linux/convert_scm_timestamps.c
|
||||
index 5d3c4199e0b32944..953ce97bd2e03849 100644
|
||||
--- a/sysdeps/unix/sysv/linux/convert_scm_timestamps.c
|
||||
+++ b/sysdeps/unix/sysv/linux/convert_scm_timestamps.c
|
||||
@@ -16,9 +16,10 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
-#include <kernel-features.h>
|
||||
+#include <bits/wordsize.h>
|
||||
+#include <bits/timesize.h>
|
||||
|
||||
-#ifndef __ASSUME_TIME64_SYSCALLS
|
||||
+#if __TIMESIZE != 64
|
||||
# include <stdint.h>
|
||||
# include <string.h>
|
||||
# include <sys/socket.h>
|
@ -0,0 +1,62 @@
|
||||
commit 52d0119743180164d1664b6773ac5d873f224608
|
||||
Author: Jiaxun Yang <jiaxun.yang@flygoat.com>
|
||||
Date: Tue Sep 7 13:31:42 2021 +0800
|
||||
|
||||
MIPS: Setup errno for {f,l,}xstat
|
||||
|
||||
{f,l,}xstat stub for MIPS is using INTERNAL_SYSCALL
|
||||
to do xstat syscall for glibc ver, However it leaves
|
||||
errno untouched and thus giving bad errno output.
|
||||
|
||||
Setup errno properly when syscall returns non-zero.
|
||||
|
||||
Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
(cherry picked from commit 66016ec8aeefd40e016d7040d966484c764b0e9c)
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/mips/fxstat.c b/sysdeps/unix/sysv/linux/mips/fxstat.c
|
||||
index 11511d30b38708ce..4a6016ff123e8dd9 100644
|
||||
--- a/sysdeps/unix/sysv/linux/mips/fxstat.c
|
||||
+++ b/sysdeps/unix/sysv/linux/mips/fxstat.c
|
||||
@@ -35,7 +35,9 @@ __fxstat (int vers, int fd, struct stat *buf)
|
||||
{
|
||||
struct kernel_stat kbuf;
|
||||
int r = INTERNAL_SYSCALL_CALL (fstat, fd, &kbuf);
|
||||
- return r ?: __xstat_conv (vers, &kbuf, buf);
|
||||
+ if (r == 0)
|
||||
+ return __xstat_conv (vers, &kbuf, buf);
|
||||
+ return INLINE_SYSCALL_ERROR_RETURN_VALUE (-r);
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/sysdeps/unix/sysv/linux/mips/lxstat.c b/sysdeps/unix/sysv/linux/mips/lxstat.c
|
||||
index 871fb6c6c5886665..54f990a250677091 100644
|
||||
--- a/sysdeps/unix/sysv/linux/mips/lxstat.c
|
||||
+++ b/sysdeps/unix/sysv/linux/mips/lxstat.c
|
||||
@@ -35,7 +35,9 @@ __lxstat (int vers, const char *name, struct stat *buf)
|
||||
{
|
||||
struct kernel_stat kbuf;
|
||||
int r = INTERNAL_SYSCALL_CALL (lstat, name, &kbuf);
|
||||
- return r ?: __xstat_conv (vers, &kbuf, buf);
|
||||
+ if (r == 0)
|
||||
+ return __xstat_conv (vers, &kbuf, buf);
|
||||
+ return INLINE_SYSCALL_ERROR_RETURN_VALUE (-r);
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/sysdeps/unix/sysv/linux/mips/xstat.c b/sysdeps/unix/sysv/linux/mips/xstat.c
|
||||
index 9d810b6f653b964b..86f4dc31a82ff1bb 100644
|
||||
--- a/sysdeps/unix/sysv/linux/mips/xstat.c
|
||||
+++ b/sysdeps/unix/sysv/linux/mips/xstat.c
|
||||
@@ -35,7 +35,9 @@ __xstat (int vers, const char *name, struct stat *buf)
|
||||
{
|
||||
struct kernel_stat kbuf;
|
||||
int r = INTERNAL_SYSCALL_CALL (stat, name, &kbuf);
|
||||
- return r ?: __xstat_conv (vers, &kbuf, buf);
|
||||
+ if (r == 0)
|
||||
+ return __xstat_conv (vers, &kbuf, buf);
|
||||
+ return INLINE_SYSCALL_ERROR_RETURN_VALUE (-r);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,192 @@
|
||||
commit 007e054d786be340699c634e3a3b30ab1fde1a7a
|
||||
Author: Dmitry V. Levin <ldv@altlinux.org>
|
||||
Date: Sat Feb 5 08:00:00 2022 +0000
|
||||
|
||||
linux: fix accuracy of get_nprocs and get_nprocs_conf [BZ #28865]
|
||||
|
||||
get_nprocs() and get_nprocs_conf() use various methods to obtain an
|
||||
accurate number of processors. Re-introduce __get_nprocs_sched() as
|
||||
a source of information, and fix the order in which these methods are
|
||||
used to return the most accurate information. The primary source of
|
||||
information used in both functions remains unchanged.
|
||||
|
||||
This also changes __get_nprocs_sched() error return value from 2 to 0,
|
||||
but all its users are already prepared to handle that.
|
||||
|
||||
Old fallback order:
|
||||
get_nprocs:
|
||||
/sys/devices/system/cpu/online -> /proc/stat -> 2
|
||||
get_nprocs_conf:
|
||||
/sys/devices/system/cpu/ -> /proc/stat -> 2
|
||||
|
||||
New fallback order:
|
||||
get_nprocs:
|
||||
/sys/devices/system/cpu/online -> /proc/stat -> sched_getaffinity -> 2
|
||||
get_nprocs_conf:
|
||||
/sys/devices/system/cpu/ -> /proc/stat -> sched_getaffinity -> 2
|
||||
|
||||
Fixes: 342298278e ("linux: Revert the use of sched_getaffinity on get_nproc")
|
||||
Closes: BZ #28865
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
(cherry picked from commit e1d32b836410767270a3adf1f82b1a47e6e4cd51)
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c
|
||||
index 7babd947aa902e77..327802b14c7326a3 100644
|
||||
--- a/sysdeps/unix/sysv/linux/getsysstats.c
|
||||
+++ b/sysdeps/unix/sysv/linux/getsysstats.c
|
||||
@@ -51,9 +51,8 @@ __get_nprocs_sched (void)
|
||||
is an arbitrary values assuming such systems should be rare and there
|
||||
is no offline cpus. */
|
||||
return max_num_cpus;
|
||||
- /* Some other error. 2 is conservative (not a uniprocessor system, so
|
||||
- atomics are needed). */
|
||||
- return 2;
|
||||
+ /* Some other error. */
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
@@ -109,22 +108,19 @@ next_line (int fd, char *const buffer, char **cp, char **re,
|
||||
}
|
||||
|
||||
static int
|
||||
-get_nproc_stat (char *buffer, size_t buffer_size)
|
||||
+get_nproc_stat (void)
|
||||
{
|
||||
+ enum { buffer_size = 1024 };
|
||||
+ char buffer[buffer_size];
|
||||
char *buffer_end = buffer + buffer_size;
|
||||
char *cp = buffer_end;
|
||||
char *re = buffer_end;
|
||||
-
|
||||
- /* Default to an SMP system in case we cannot obtain an accurate
|
||||
- number. */
|
||||
- int result = 2;
|
||||
+ int result = 0;
|
||||
|
||||
const int flags = O_RDONLY | O_CLOEXEC;
|
||||
int fd = __open_nocancel ("/proc/stat", flags);
|
||||
if (fd != -1)
|
||||
{
|
||||
- result = 0;
|
||||
-
|
||||
char *l;
|
||||
while ((l = next_line (fd, buffer, &cp, &re, buffer_end)) != NULL)
|
||||
/* The current format of /proc/stat has all the cpu* entries
|
||||
@@ -140,8 +136,8 @@ get_nproc_stat (char *buffer, size_t buffer_size)
|
||||
return result;
|
||||
}
|
||||
|
||||
-int
|
||||
-__get_nprocs (void)
|
||||
+static int
|
||||
+get_nprocs_cpu_online (void)
|
||||
{
|
||||
enum { buffer_size = 1024 };
|
||||
char buffer[buffer_size];
|
||||
@@ -180,7 +176,8 @@ __get_nprocs (void)
|
||||
}
|
||||
}
|
||||
|
||||
- result += m - n + 1;
|
||||
+ if (m >= n)
|
||||
+ result += m - n + 1;
|
||||
|
||||
l = endp;
|
||||
if (l < re && *l == ',')
|
||||
@@ -189,28 +186,18 @@ __get_nprocs (void)
|
||||
while (l < re && *l != '\n');
|
||||
|
||||
__close_nocancel_nostatus (fd);
|
||||
-
|
||||
- if (result > 0)
|
||||
- return result;
|
||||
}
|
||||
|
||||
- return get_nproc_stat (buffer, buffer_size);
|
||||
+ return result;
|
||||
}
|
||||
-libc_hidden_def (__get_nprocs)
|
||||
-weak_alias (__get_nprocs, get_nprocs)
|
||||
-
|
||||
|
||||
-/* On some architectures it is possible to distinguish between configured
|
||||
- and active cpus. */
|
||||
-int
|
||||
-__get_nprocs_conf (void)
|
||||
+static int
|
||||
+get_nprocs_cpu (void)
|
||||
{
|
||||
- /* Try to use the sysfs filesystem. It has actual information about
|
||||
- online processors. */
|
||||
+ int count = 0;
|
||||
DIR *dir = __opendir ("/sys/devices/system/cpu");
|
||||
if (dir != NULL)
|
||||
{
|
||||
- int count = 0;
|
||||
struct dirent64 *d;
|
||||
|
||||
while ((d = __readdir64 (dir)) != NULL)
|
||||
@@ -225,12 +212,57 @@ __get_nprocs_conf (void)
|
||||
|
||||
__closedir (dir);
|
||||
|
||||
- return count;
|
||||
}
|
||||
+ return count;
|
||||
+}
|
||||
|
||||
- enum { buffer_size = 1024 };
|
||||
- char buffer[buffer_size];
|
||||
- return get_nproc_stat (buffer, buffer_size);
|
||||
+static int
|
||||
+get_nprocs_fallback (void)
|
||||
+{
|
||||
+ int result;
|
||||
+
|
||||
+ /* Try /proc/stat first. */
|
||||
+ result = get_nproc_stat ();
|
||||
+ if (result != 0)
|
||||
+ return result;
|
||||
+
|
||||
+ /* Try sched_getaffinity. */
|
||||
+ result = __get_nprocs_sched ();
|
||||
+ if (result != 0)
|
||||
+ return result;
|
||||
+
|
||||
+ /* We failed to obtain an accurate number. Be conservative: return
|
||||
+ the smallest number meaning that this is not a uniprocessor system,
|
||||
+ so atomics are needed. */
|
||||
+ return 2;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+__get_nprocs (void)
|
||||
+{
|
||||
+ /* Try /sys/devices/system/cpu/online first. */
|
||||
+ int result = get_nprocs_cpu_online ();
|
||||
+ if (result != 0)
|
||||
+ return result;
|
||||
+
|
||||
+ /* Fall back to /proc/stat and sched_getaffinity. */
|
||||
+ return get_nprocs_fallback ();
|
||||
+}
|
||||
+libc_hidden_def (__get_nprocs)
|
||||
+weak_alias (__get_nprocs, get_nprocs)
|
||||
+
|
||||
+/* On some architectures it is possible to distinguish between configured
|
||||
+ and active cpus. */
|
||||
+int
|
||||
+__get_nprocs_conf (void)
|
||||
+{
|
||||
+ /* Try /sys/devices/system/cpu/ first. */
|
||||
+ int result = get_nprocs_cpu ();
|
||||
+ if (result != 0)
|
||||
+ return result;
|
||||
+
|
||||
+ /* Fall back to /proc/stat and sched_getaffinity. */
|
||||
+ return get_nprocs_fallback ();
|
||||
}
|
||||
libc_hidden_def (__get_nprocs_conf)
|
||||
weak_alias (__get_nprocs_conf, get_nprocs_conf)
|
@ -0,0 +1,60 @@
|
||||
commit 04d60ce0f21ffe2a4add148cb37a1942dbad64e2
|
||||
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||
Date: Thu Feb 17 08:10:35 2022 -0800
|
||||
|
||||
string: Add a testcase for wcsncmp with SIZE_MAX [BZ #28755]
|
||||
|
||||
Verify that wcsncmp (L("abc"), L("abd"), SIZE_MAX) == 0. The new test
|
||||
fails without
|
||||
|
||||
commit ddf0992cf57a93200e0c782e2a94d0733a5a0b87
|
||||
Author: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||
Date: Sun Jan 9 16:02:21 2022 -0600
|
||||
|
||||
x86: Fix __wcsncmp_avx2 in strcmp-avx2.S [BZ# 28755]
|
||||
|
||||
and
|
||||
|
||||
commit 7e08db3359c86c94918feb33a1182cd0ff3bb10b
|
||||
Author: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||
Date: Sun Jan 9 16:02:28 2022 -0600
|
||||
|
||||
x86: Fix __wcsncmp_evex in strcmp-evex.S [BZ# 28755]
|
||||
|
||||
This is for BZ #28755.
|
||||
|
||||
Reviewed-by: Sunil K Pandey <skpgkp2@gmail.com>
|
||||
|
||||
(cherry picked from commit aa5a720056d37cf24924c138a3dbe6dace98e97c)
|
||||
|
||||
diff --git a/string/test-strncmp.c b/string/test-strncmp.c
|
||||
index 10b34de8d2acb2a1..97e831d88fd24316 100644
|
||||
--- a/string/test-strncmp.c
|
||||
+++ b/string/test-strncmp.c
|
||||
@@ -435,6 +435,18 @@ check3 (void)
|
||||
}
|
||||
}
|
||||
|
||||
+static void
|
||||
+check4 (void)
|
||||
+{
|
||||
+ const CHAR *s1 = L ("abc");
|
||||
+ CHAR *s2 = STRDUP (s1);
|
||||
+
|
||||
+ FOR_EACH_IMPL (impl, 0)
|
||||
+ check_result (impl, s1, s2, SIZE_MAX, 0);
|
||||
+
|
||||
+ free (s2);
|
||||
+}
|
||||
+
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
@@ -445,6 +457,7 @@ test_main (void)
|
||||
check1 ();
|
||||
check2 ();
|
||||
check3 ();
|
||||
+ check4 ();
|
||||
|
||||
printf ("%23s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
@ -0,0 +1,120 @@
|
||||
commit 38e0d2479413ccdbc02b4c9e9e246eca31e956c9
|
||||
Author: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||
Date: Tue Feb 15 08:18:15 2022 -0600
|
||||
|
||||
x86: Fallback {str|wcs}cmp RTM in the ncmp overflow case [BZ #28896]
|
||||
|
||||
In the overflow fallback strncmp-avx2-rtm and wcsncmp-avx2-rtm would
|
||||
call strcmp-avx2 and wcscmp-avx2 respectively. This would have
|
||||
not checks around vzeroupper and would trigger spurious
|
||||
aborts. This commit fixes that.
|
||||
|
||||
test-strcmp, test-strncmp, test-wcscmp, and test-wcsncmp all pass on
|
||||
AVX2 machines with and without RTM.
|
||||
|
||||
Co-authored-by: H.J. Lu <hjl.tools@gmail.com>
|
||||
|
||||
(cherry picked from commit c6272098323153db373f2986c67786ea8c85f1cf)
|
||||
|
||||
diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile
|
||||
index 36ca1a7126047b86..af934d6ccf1fa337 100644
|
||||
--- a/sysdeps/x86/Makefile
|
||||
+++ b/sysdeps/x86/Makefile
|
||||
@@ -105,7 +105,7 @@ CFLAGS-tst-memset-rtm.c += -mrtm
|
||||
CFLAGS-tst-strchr-rtm.c += -mrtm
|
||||
CFLAGS-tst-strcpy-rtm.c += -mrtm
|
||||
CFLAGS-tst-strlen-rtm.c += -mrtm
|
||||
-CFLAGS-tst-strncmp-rtm.c += -mrtm
|
||||
+CFLAGS-tst-strncmp-rtm.c += -mrtm -Wno-error
|
||||
CFLAGS-tst-strrchr-rtm.c += -mrtm
|
||||
endif
|
||||
|
||||
diff --git a/sysdeps/x86/tst-strncmp-rtm.c b/sysdeps/x86/tst-strncmp-rtm.c
|
||||
index 236ad951b5b59cd1..4d0004b58aae428d 100644
|
||||
--- a/sysdeps/x86/tst-strncmp-rtm.c
|
||||
+++ b/sysdeps/x86/tst-strncmp-rtm.c
|
||||
@@ -16,6 +16,7 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
+#include <stdint.h>
|
||||
#include <tst-string-rtm.h>
|
||||
|
||||
#define LOOP 3000
|
||||
@@ -45,8 +46,22 @@ function (void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
+__attribute__ ((noinline, noclone))
|
||||
+static int
|
||||
+function_overflow (void)
|
||||
+{
|
||||
+ if (strncmp (string1, string2, SIZE_MAX) == 0)
|
||||
+ return 0;
|
||||
+ else
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
- return do_test_1 ("strncmp", LOOP, prepare, function);
|
||||
+ int status = do_test_1 ("strncmp", LOOP, prepare, function);
|
||||
+ if (status != EXIT_SUCCESS)
|
||||
+ return status;
|
||||
+ status = do_test_1 ("strncmp", LOOP, prepare, function_overflow);
|
||||
+ return status;
|
||||
}
|
||||
diff --git a/sysdeps/x86_64/multiarch/strcmp-avx2.S b/sysdeps/x86_64/multiarch/strcmp-avx2.S
|
||||
index 3dfcb1bf803cf9ec..fa70c994fc25dfd8 100644
|
||||
--- a/sysdeps/x86_64/multiarch/strcmp-avx2.S
|
||||
+++ b/sysdeps/x86_64/multiarch/strcmp-avx2.S
|
||||
@@ -95,7 +95,7 @@ ENTRY (STRCMP)
|
||||
length to bound a valid memory region. In these cases just use
|
||||
'wcscmp'. */
|
||||
shrq $56, %rcx
|
||||
- jnz __wcscmp_avx2
|
||||
+ jnz OVERFLOW_STRCMP
|
||||
# endif
|
||||
/* Convert units: from wide to byte char. */
|
||||
shl $2, %RDX_LP
|
||||
diff --git a/sysdeps/x86_64/multiarch/strncmp-avx2-rtm.S b/sysdeps/x86_64/multiarch/strncmp-avx2-rtm.S
|
||||
index 37d1224bb9b7056b..68bad365ba728eec 100644
|
||||
--- a/sysdeps/x86_64/multiarch/strncmp-avx2-rtm.S
|
||||
+++ b/sysdeps/x86_64/multiarch/strncmp-avx2-rtm.S
|
||||
@@ -1,3 +1,4 @@
|
||||
#define STRCMP __strncmp_avx2_rtm
|
||||
#define USE_AS_STRNCMP 1
|
||||
+#define OVERFLOW_STRCMP __strcmp_avx2_rtm
|
||||
#include "strcmp-avx2-rtm.S"
|
||||
diff --git a/sysdeps/x86_64/multiarch/strncmp-avx2.S b/sysdeps/x86_64/multiarch/strncmp-avx2.S
|
||||
index 1678bcc235a4bc6a..f138e9f1fdcf277c 100644
|
||||
--- a/sysdeps/x86_64/multiarch/strncmp-avx2.S
|
||||
+++ b/sysdeps/x86_64/multiarch/strncmp-avx2.S
|
||||
@@ -1,3 +1,4 @@
|
||||
#define STRCMP __strncmp_avx2
|
||||
#define USE_AS_STRNCMP 1
|
||||
+#define OVERFLOW_STRCMP __strcmp_avx2
|
||||
#include "strcmp-avx2.S"
|
||||
diff --git a/sysdeps/x86_64/multiarch/wcsncmp-avx2-rtm.S b/sysdeps/x86_64/multiarch/wcsncmp-avx2-rtm.S
|
||||
index 4e88c70cc696b82d..f467582cbedd4535 100644
|
||||
--- a/sysdeps/x86_64/multiarch/wcsncmp-avx2-rtm.S
|
||||
+++ b/sysdeps/x86_64/multiarch/wcsncmp-avx2-rtm.S
|
||||
@@ -1,5 +1,5 @@
|
||||
#define STRCMP __wcsncmp_avx2_rtm
|
||||
#define USE_AS_STRNCMP 1
|
||||
#define USE_AS_WCSCMP 1
|
||||
-
|
||||
+#define OVERFLOW_STRCMP __wcscmp_avx2_rtm
|
||||
#include "strcmp-avx2-rtm.S"
|
||||
diff --git a/sysdeps/x86_64/multiarch/wcsncmp-avx2.S b/sysdeps/x86_64/multiarch/wcsncmp-avx2.S
|
||||
index 4fa1de4d3f1f97ff..e9ede522b8bde27d 100644
|
||||
--- a/sysdeps/x86_64/multiarch/wcsncmp-avx2.S
|
||||
+++ b/sysdeps/x86_64/multiarch/wcsncmp-avx2.S
|
||||
@@ -1,5 +1,5 @@
|
||||
#define STRCMP __wcsncmp_avx2
|
||||
#define USE_AS_STRNCMP 1
|
||||
#define USE_AS_WCSCMP 1
|
||||
-
|
||||
+#define OVERFLOW_STRCMP __wcscmp_avx2
|
||||
#include "strcmp-avx2.S"
|
@ -0,0 +1,139 @@
|
||||
commit d093b677c36ef4b360bf30483b68b95d9f0ad1d2
|
||||
Author: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||
Date: Fri Feb 18 14:19:15 2022 -0600
|
||||
|
||||
x86: Test wcscmp RTM in the wcsncmp overflow case [BZ #28896]
|
||||
|
||||
In the overflow fallback strncmp-avx2-rtm and wcsncmp-avx2-rtm would
|
||||
call strcmp-avx2 and wcscmp-avx2 respectively. This would have
|
||||
not checks around vzeroupper and would trigger spurious
|
||||
aborts. This commit fixes that.
|
||||
|
||||
test-strcmp, test-strncmp, test-wcscmp, and test-wcsncmp all pass on
|
||||
AVX2 machines with and without RTM.
|
||||
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
||||
|
||||
(cherry picked from commit 7835d611af0854e69a0c71e3806f8fe379282d6f)
|
||||
|
||||
diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile
|
||||
index af934d6ccf1fa337..cd94e683afd5b4a4 100644
|
||||
--- a/sysdeps/x86/Makefile
|
||||
+++ b/sysdeps/x86/Makefile
|
||||
@@ -95,7 +95,9 @@ tests += \
|
||||
tst-strcpy-rtm \
|
||||
tst-strlen-rtm \
|
||||
tst-strncmp-rtm \
|
||||
- tst-strrchr-rtm
|
||||
+ tst-strrchr-rtm \
|
||||
+ tst-wcsncmp-rtm \
|
||||
+# tests
|
||||
|
||||
CFLAGS-tst-memchr-rtm.c += -mrtm
|
||||
CFLAGS-tst-memcmp-rtm.c += -mrtm
|
||||
@@ -107,6 +109,7 @@ CFLAGS-tst-strcpy-rtm.c += -mrtm
|
||||
CFLAGS-tst-strlen-rtm.c += -mrtm
|
||||
CFLAGS-tst-strncmp-rtm.c += -mrtm -Wno-error
|
||||
CFLAGS-tst-strrchr-rtm.c += -mrtm
|
||||
+CFLAGS-tst-wcsncmp-rtm.c += -mrtm -Wno-error
|
||||
endif
|
||||
|
||||
ifneq ($(enable-cet),no)
|
||||
diff --git a/sysdeps/x86/tst-strncmp-rtm.c b/sysdeps/x86/tst-strncmp-rtm.c
|
||||
index 4d0004b58aae428d..4e9f094f39c72f67 100644
|
||||
--- a/sysdeps/x86/tst-strncmp-rtm.c
|
||||
+++ b/sysdeps/x86/tst-strncmp-rtm.c
|
||||
@@ -19,18 +19,32 @@
|
||||
#include <stdint.h>
|
||||
#include <tst-string-rtm.h>
|
||||
|
||||
+#ifdef WIDE
|
||||
+# define CHAR wchar_t
|
||||
+# define MEMSET wmemset
|
||||
+# define STRNCMP wcsncmp
|
||||
+# define TEST_NAME wcsncmp
|
||||
+#else /* !WIDE */
|
||||
+# define CHAR char
|
||||
+# define MEMSET memset
|
||||
+# define STRNCMP strncmp
|
||||
+# define TEST_NAME strncmp
|
||||
+#endif /* !WIDE */
|
||||
+
|
||||
+
|
||||
+
|
||||
#define LOOP 3000
|
||||
#define STRING_SIZE 1024
|
||||
-char string1[STRING_SIZE];
|
||||
-char string2[STRING_SIZE];
|
||||
+CHAR string1[STRING_SIZE];
|
||||
+CHAR string2[STRING_SIZE];
|
||||
|
||||
__attribute__ ((noinline, noclone))
|
||||
static int
|
||||
prepare (void)
|
||||
{
|
||||
- memset (string1, 'a', STRING_SIZE - 1);
|
||||
- memset (string2, 'a', STRING_SIZE - 1);
|
||||
- if (strncmp (string1, string2, STRING_SIZE) == 0)
|
||||
+ MEMSET (string1, 'a', STRING_SIZE - 1);
|
||||
+ MEMSET (string2, 'a', STRING_SIZE - 1);
|
||||
+ if (STRNCMP (string1, string2, STRING_SIZE) == 0)
|
||||
return EXIT_SUCCESS;
|
||||
else
|
||||
return EXIT_FAILURE;
|
||||
@@ -40,7 +54,7 @@ __attribute__ ((noinline, noclone))
|
||||
static int
|
||||
function (void)
|
||||
{
|
||||
- if (strncmp (string1, string2, STRING_SIZE) == 0)
|
||||
+ if (STRNCMP (string1, string2, STRING_SIZE) == 0)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
@@ -50,7 +64,7 @@ __attribute__ ((noinline, noclone))
|
||||
static int
|
||||
function_overflow (void)
|
||||
{
|
||||
- if (strncmp (string1, string2, SIZE_MAX) == 0)
|
||||
+ if (STRNCMP (string1, string2, SIZE_MAX) == 0)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
@@ -59,9 +73,9 @@ function_overflow (void)
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
- int status = do_test_1 ("strncmp", LOOP, prepare, function);
|
||||
+ int status = do_test_1 (TEST_NAME, LOOP, prepare, function);
|
||||
if (status != EXIT_SUCCESS)
|
||||
return status;
|
||||
- status = do_test_1 ("strncmp", LOOP, prepare, function_overflow);
|
||||
+ status = do_test_1 (TEST_NAME, LOOP, prepare, function_overflow);
|
||||
return status;
|
||||
}
|
||||
diff --git a/sysdeps/x86/tst-wcsncmp-rtm.c b/sysdeps/x86/tst-wcsncmp-rtm.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..bad3b863782c5e56
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/x86/tst-wcsncmp-rtm.c
|
||||
@@ -0,0 +1,21 @@
|
||||
+/* Test case for wcsncmp inside a transactionally executing RTM region.
|
||||
+ 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/>. */
|
||||
+
|
||||
+#define WIDE 1
|
||||
+#include <wchar.h>
|
||||
+#include "tst-strncmp-rtm.c"
|
@ -0,0 +1,32 @@
|
||||
commit 15b00d2af0e56dcc8c244a36d6872d301b0c7185
|
||||
Author: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||
Date: Fri Feb 18 17:00:25 2022 -0600
|
||||
|
||||
x86: Fix TEST_NAME to make it a string in tst-strncmp-rtm.c
|
||||
|
||||
Previously TEST_NAME was passing a function pointer. This didn't fail
|
||||
because of the -Wno-error flag (to allow for overflow sizes passed
|
||||
to strncmp/wcsncmp)
|
||||
|
||||
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
||||
(cherry picked from commit b98d0bbf747f39770e0caba7e984ce9f8f900330)
|
||||
|
||||
diff --git a/sysdeps/x86/tst-strncmp-rtm.c b/sysdeps/x86/tst-strncmp-rtm.c
|
||||
index 4e9f094f39c72f67..aef9866cf2fbe774 100644
|
||||
--- a/sysdeps/x86/tst-strncmp-rtm.c
|
||||
+++ b/sysdeps/x86/tst-strncmp-rtm.c
|
||||
@@ -23,12 +23,12 @@
|
||||
# define CHAR wchar_t
|
||||
# define MEMSET wmemset
|
||||
# define STRNCMP wcsncmp
|
||||
-# define TEST_NAME wcsncmp
|
||||
+# define TEST_NAME "wcsncmp"
|
||||
#else /* !WIDE */
|
||||
# define CHAR char
|
||||
# define MEMSET memset
|
||||
# define STRNCMP strncmp
|
||||
-# define TEST_NAME strncmp
|
||||
+# define TEST_NAME "strncmp"
|
||||
#endif /* !WIDE */
|
||||
|
||||
|
@ -0,0 +1,104 @@
|
||||
commit 3be79b72d556e3ac37075ad6b99eb5eac18e1402
|
||||
Author: John David Anglin <danglin@gcc.gnu.org>
|
||||
Date: Sun Mar 6 15:56:57 2022 +0000
|
||||
|
||||
Fix elf/tst-audit2 on hppa
|
||||
|
||||
The test elf/tst-audit2 fails on hppa with a segmentation fault in the
|
||||
long branch stub used to call malloc from calloc. This occurs because
|
||||
the test is not a PIC executable and calloc is called from the dynamic
|
||||
linker before the dp register is initialized in _dl_start_user.
|
||||
|
||||
The fix is to move the dp register initialization into
|
||||
elf_machine_runtime_setup. Since the address of $global$ can't be
|
||||
loaded directly, we continue to use the DT_PLTGOT value from the
|
||||
the main_map to initialize dp. Since l_main_map is not available
|
||||
in v2.34 and earlier, we use a new function, elf_machine_main_map,
|
||||
to find the main map.
|
||||
|
||||
diff --git a/sysdeps/hppa/dl-machine.h b/sysdeps/hppa/dl-machine.h
|
||||
index f048fd20728ccde6..24f0f47d8f1e25cd 100644
|
||||
--- a/sysdeps/hppa/dl-machine.h
|
||||
+++ b/sysdeps/hppa/dl-machine.h
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <string.h>
|
||||
#include <link.h>
|
||||
#include <errno.h>
|
||||
+#include <ldsodefs.h>
|
||||
#include <dl-fptr.h>
|
||||
#include <abort-instr.h>
|
||||
#include <tls.h>
|
||||
@@ -159,6 +160,24 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
|
||||
return (struct fdesc) { value.ip + reloc->r_addend, value.gp };
|
||||
}
|
||||
|
||||
+static inline struct link_map *
|
||||
+elf_machine_main_map (void)
|
||||
+{
|
||||
+ struct link_map *main_map;
|
||||
+
|
||||
+#if defined SHARED && IS_IN (rtld)
|
||||
+ asm (
|
||||
+" bl 1f,%0\n"
|
||||
+" addil L'_rtld_local - ($PIC_pcrel$0 - 1),%0\n"
|
||||
+"1: ldw R'_rtld_local - ($PIC_pcrel$0 - 5)(%%r1),%0\n"
|
||||
+ : "=r" (main_map) : : "r1");
|
||||
+#else
|
||||
+ main_map = NULL;
|
||||
+#endif
|
||||
+
|
||||
+ return main_map;
|
||||
+}
|
||||
+
|
||||
/* Set up the loaded object described by L so its unrelocated PLT
|
||||
entries will jump to the on-demand fixup code in dl-runtime.c. */
|
||||
|
||||
@@ -174,6 +193,15 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
||||
Elf32_Addr i[2];
|
||||
} sig = {{0x00,0xc0,0xff,0xee, 0xde,0xad,0xbe,0xef}};
|
||||
|
||||
+ /* Initialize dp register for main executable. */
|
||||
+ if (l == elf_machine_main_map ())
|
||||
+ {
|
||||
+ register Elf32_Addr dp asm ("%r27");
|
||||
+
|
||||
+ dp = D_PTR (l, l_info[DT_PLTGOT]);
|
||||
+ asm volatile ("" : : "r" (dp));
|
||||
+ }
|
||||
+
|
||||
/* If we don't have a PLT we can just skip all this... */
|
||||
if (__builtin_expect (l->l_info[DT_JMPREL] == NULL,0))
|
||||
return lazy;
|
||||
@@ -336,16 +364,6 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
||||
its return value is the user program's entry point. */
|
||||
|
||||
#define RTLD_START \
|
||||
-/* Set up dp for any non-PIC lib constructors that may be called. */ \
|
||||
-static struct link_map * __attribute__((used)) \
|
||||
-set_dp (struct link_map *map) \
|
||||
-{ \
|
||||
- register Elf32_Addr dp asm ("%r27"); \
|
||||
- dp = D_PTR (map, l_info[DT_PLTGOT]); \
|
||||
- asm volatile ("" : : "r" (dp)); \
|
||||
- return map; \
|
||||
-} \
|
||||
- \
|
||||
asm ( \
|
||||
" .text\n" \
|
||||
" .globl _start\n" \
|
||||
@@ -445,14 +463,11 @@ asm ( \
|
||||
" stw %r24,-44(%sp)\n" \
|
||||
\
|
||||
".Lnofix:\n" \
|
||||
+ /* Call _dl_init(main_map, argc, argv, envp). */ \
|
||||
" addil LT'_rtld_local,%r19\n" \
|
||||
" ldw RT'_rtld_local(%r1),%r26\n" \
|
||||
-" bl set_dp, %r2\n" \
|
||||
" ldw 0(%r26),%r26\n" \
|
||||
\
|
||||
- /* Call _dl_init(_dl_loaded, argc, argv, envp). */ \
|
||||
-" copy %r28,%r26\n" \
|
||||
- \
|
||||
/* envp = argv + argc + 1 */ \
|
||||
" sh2add %r25,%r24,%r23\n" \
|
||||
" bl _dl_init,%r2\n" \
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue