Toshaan Bharvani
3 years ago
commit
9be22cb468
169 changed files with 40070 additions and 0 deletions
@ -0,0 +1,77 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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,21 @@
@@ -0,0 +1,21 @@
|
||||
Short description: Fedora-specific glibc install locale changes. |
||||
Author(s): Fedora glibc team <glibc@lists.fedoraproject.org> |
||||
Origin: PATCH |
||||
Upstream status: not-needed |
||||
|
||||
The Fedora glibc build and install does not need the normal install |
||||
behaviour which updates the locale archive. The Fedora install phase |
||||
in the spec file of the rpm will handle this manually. |
||||
|
||||
diff --git a/localedata/Makefile b/localedata/Makefile |
||||
index 0eea396ad86da956..54caabda33728207 100644 |
||||
--- a/localedata/Makefile |
||||
+++ b/localedata/Makefile |
||||
@@ -413,6 +413,7 @@ define build-one-locale |
||||
echo -n '...'; \ |
||||
input=`echo $$locale | sed 's/\([^.]*\)[^@]*\(.*\)/\1\2/'`; \ |
||||
$(LOCALEDEF) $$flags --alias-file=../intl/locale.alias \ |
||||
+ --no-archive \ |
||||
-i locales/$$input -f charmaps/$$charset \ |
||||
$(addprefix --prefix=,$(install_root)) $$locale \ |
||||
&& echo ' done'; |
@ -0,0 +1,31 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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,296 @@
@@ -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 @@
@@ -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 @@
@@ -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,37 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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,62 @@
@@ -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,117 @@
@@ -0,0 +1,117 @@
|
||||
commit addc9d62d61eea790a35328cbfce53333a07bd3e |
||||
Author: Florian Weimer <fweimer@redhat.com> |
||||
Date: Mon Aug 30 13:43:56 2021 +0200 |
||||
|
||||
support: Add support_wait_for_thread_exit |
||||
|
||||
(cherry picked from commit 032d74eaf6179100048a5bf0ce942e97dc8b9a60) |
||||
|
||||
diff --git a/support/Makefile b/support/Makefile |
||||
index a462781718426d35..ef2b1a980a407f8f 100644 |
||||
--- a/support/Makefile |
||||
+++ b/support/Makefile |
||||
@@ -82,9 +82,10 @@ libsupport-routines = \ |
||||
support_test_compare_blob \ |
||||
support_test_compare_failure \ |
||||
support_test_compare_string \ |
||||
- support_write_file_string \ |
||||
support_test_main \ |
||||
support_test_verify_impl \ |
||||
+ support_wait_for_thread_exit \ |
||||
+ support_write_file_string \ |
||||
temp_file \ |
||||
timespec \ |
||||
timespec-time64 \ |
||||
diff --git a/support/support.h b/support/support.h |
||||
index 834dba909770a992..a5978b939af2fb41 100644 |
||||
--- a/support/support.h |
||||
+++ b/support/support.h |
||||
@@ -174,6 +174,10 @@ timer_t support_create_timer (uint64_t sec, long int nsec, bool repeat, |
||||
/* Disable the timer TIMER. */ |
||||
void support_delete_timer (timer_t timer); |
||||
|
||||
+/* Wait until all threads except the current thread have exited (as |
||||
+ far as the kernel is concerned). */ |
||||
+void support_wait_for_thread_exit (void); |
||||
+ |
||||
struct support_stack |
||||
{ |
||||
void *stack; |
||||
diff --git a/support/support_wait_for_thread_exit.c b/support/support_wait_for_thread_exit.c |
||||
new file mode 100644 |
||||
index 0000000000000000..658a81381006ea62 |
||||
--- /dev/null |
||||
+++ b/support/support_wait_for_thread_exit.c |
||||
@@ -0,0 +1,72 @@ |
||||
+/* Wait until all threads except the current thread has exited. |
||||
+ 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 <dirent.h> |
||||
+#include <errno.h> |
||||
+#include <string.h> |
||||
+#include <support/check.h> |
||||
+#include <support/support.h> |
||||
+#include <unistd.h> |
||||
+ |
||||
+void |
||||
+support_wait_for_thread_exit (void) |
||||
+{ |
||||
+#ifdef __linux__ |
||||
+ DIR *proc_self_task = opendir ("/proc/self/task"); |
||||
+ TEST_VERIFY_EXIT (proc_self_task != NULL); |
||||
+ |
||||
+ while (true) |
||||
+ { |
||||
+ errno = 0; |
||||
+ struct dirent *e = readdir (proc_self_task); |
||||
+ if (e == NULL && errno != 0) |
||||
+ FAIL_EXIT1 ("readdir: %m"); |
||||
+ if (e == NULL) |
||||
+ { |
||||
+ /* Only the main thread remains. Testing may continue. */ |
||||
+ closedir (proc_self_task); |
||||
+ return; |
||||
+ } |
||||
+ |
||||
+ if (strcmp (e->d_name, ".") == 0 || strcmp (e->d_name, "..") == 0) |
||||
+ continue; |
||||
+ |
||||
+ int task_tid = atoi (e->d_name); |
||||
+ if (task_tid <= 0) |
||||
+ FAIL_EXIT1 ("Invalid /proc/self/task entry: %s", e->d_name); |
||||
+ |
||||
+ if (task_tid == gettid ()) |
||||
+ /* The current thread. Keep scanning for other |
||||
+ threads. */ |
||||
+ continue; |
||||
+ |
||||
+ /* task_tid does not refer to this thread here, i.e., there is |
||||
+ another running thread. */ |
||||
+ |
||||
+ /* Small timeout to give the thread a chance to exit. */ |
||||
+ usleep (50 * 1000); |
||||
+ |
||||
+ /* Start scanning the directory from the start. */ |
||||
+ rewinddir (proc_self_task); |
||||
+ } |
||||
+#else |
||||
+ /* Use a large timeout because we cannot verify that the thread has |
||||
+ exited. */ |
||||
+ usleep (5 * 1000 * 1000); |
||||
+#endif |
||||
+} |
@ -0,0 +1,279 @@
@@ -0,0 +1,279 @@
|
||||
commit 3abf3bd4edc86fb28c099cc85203cb46a811e0b8 |
||||
Author: Florian Weimer <fweimer@redhat.com> |
||||
Date: Mon Sep 13 11:06:08 2021 +0200 |
||||
|
||||
nptl: pthread_kill, pthread_cancel should not fail after exit (bug 19193) |
||||
|
||||
This closes one remaining race condition related to bug 12889: if |
||||
the thread already exited on the kernel side, returning ESRCH |
||||
is not correct because that error is reserved for the thread IDs |
||||
(pthread_t values) whose lifetime has ended. In case of a |
||||
kernel-side exit and a valid thread ID, no signal needs to be sent |
||||
and cancellation does not have an effect, so just return 0. |
||||
|
||||
sysdeps/pthread/tst-kill4.c triggers undefined behavior and is |
||||
removed with this commit. |
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org> |
||||
(cherry picked from commit 8af8456004edbab71f8903a60a3cae442cf6fe69) |
||||
|
||||
diff --git a/nptl/pthread_cancel.c b/nptl/pthread_cancel.c |
||||
index cc25ff21f364e8a4..9bac6e3b76a20312 100644 |
||||
--- a/nptl/pthread_cancel.c |
||||
+++ b/nptl/pthread_cancel.c |
||||
@@ -62,10 +62,11 @@ __pthread_cancel (pthread_t th) |
||||
{ |
||||
volatile struct pthread *pd = (volatile struct pthread *) th; |
||||
|
||||
- /* Make sure the descriptor is valid. */ |
||||
- if (INVALID_TD_P (pd)) |
||||
- /* Not a valid thread handle. */ |
||||
- return ESRCH; |
||||
+ if (pd->tid == 0) |
||||
+ /* The thread has already exited on the kernel side. Its outcome |
||||
+ (regular exit, other cancelation) has already been |
||||
+ determined. */ |
||||
+ return 0; |
||||
|
||||
static int init_sigcancel = 0; |
||||
if (atomic_load_relaxed (&init_sigcancel) == 0) |
||||
diff --git a/nptl/pthread_kill.c b/nptl/pthread_kill.c |
||||
index f79a2b26fc7f72e5..5d4c86f9205a6fb5 100644 |
||||
--- a/nptl/pthread_kill.c |
||||
+++ b/nptl/pthread_kill.c |
||||
@@ -46,7 +46,12 @@ __pthread_kill_internal (pthread_t threadid, int signo) |
||||
? INTERNAL_SYSCALL_ERRNO (val) : 0); |
||||
} |
||||
else |
||||
- val = ESRCH; |
||||
+ /* The kernel reports that the thread has exited. POSIX specifies |
||||
+ the ESRCH error only for the case when the lifetime of a thread |
||||
+ ID has ended, but calling pthread_kill on such a thread ID is |
||||
+ undefined in glibc. Therefore, do not treat kernel thread exit |
||||
+ as an error. */ |
||||
+ val = 0; |
||||
|
||||
return val; |
||||
} |
||||
diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile |
||||
index 42f9fc507263657d..dedfa0d290da4949 100644 |
||||
--- a/sysdeps/pthread/Makefile |
||||
+++ b/sysdeps/pthread/Makefile |
||||
@@ -89,7 +89,7 @@ tests += tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \ |
||||
tst-join8 tst-join9 tst-join10 tst-join11 tst-join12 tst-join13 \ |
||||
tst-join14 tst-join15 \ |
||||
tst-key1 tst-key2 tst-key3 tst-key4 \ |
||||
- tst-kill1 tst-kill2 tst-kill3 tst-kill4 tst-kill5 tst-kill6 \ |
||||
+ tst-kill1 tst-kill2 tst-kill3 tst-kill5 tst-kill6 \ |
||||
tst-locale1 tst-locale2 \ |
||||
tst-memstream \ |
||||
tst-mutex-errorcheck tst-mutex1 tst-mutex2 tst-mutex3 tst-mutex4 \ |
||||
@@ -118,6 +118,9 @@ tests += tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \ |
||||
tst-unload \ |
||||
tst-unwind-thread \ |
||||
tst-pt-vfork1 tst-pt-vfork2 tst-vfork1x tst-vfork2x \ |
||||
+ tst-pthread_cancel-exited \ |
||||
+ tst-pthread_kill-exited \ |
||||
+ # tests |
||||
|
||||
tests-time64 := \ |
||||
tst-abstime-time64 \ |
||||
diff --git a/sysdeps/pthread/tst-kill4.c b/sysdeps/pthread/tst-kill4.c |
||||
deleted file mode 100644 |
||||
index 9563939792b96ebd..0000000000000000 |
||||
--- a/sysdeps/pthread/tst-kill4.c |
||||
+++ /dev/null |
||||
@@ -1,90 +0,0 @@ |
||||
-/* Copyright (C) 2003-2021 Free Software Foundation, Inc. |
||||
- This file is part of the GNU C Library. |
||||
- Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. |
||||
- |
||||
- 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 <pthread.h> |
||||
-#include <signal.h> |
||||
-#include <stdio.h> |
||||
-#include <stdlib.h> |
||||
-#include <unistd.h> |
||||
- |
||||
- |
||||
-static void * |
||||
-tf (void *a) |
||||
-{ |
||||
- return NULL; |
||||
-} |
||||
- |
||||
- |
||||
-int |
||||
-do_test (void) |
||||
-{ |
||||
- pthread_attr_t at; |
||||
- if (pthread_attr_init (&at) != 0) |
||||
- { |
||||
- puts ("attr_create failed"); |
||||
- exit (1); |
||||
- } |
||||
- |
||||
- /* Limit thread stack size, because if it is too large, pthread_join |
||||
- will free it immediately rather than put it into stack cache. */ |
||||
- if (pthread_attr_setstacksize (&at, 2 * 1024 * 1024) != 0) |
||||
- { |
||||
- puts ("setstacksize failed"); |
||||
- exit (1); |
||||
- } |
||||
- |
||||
- pthread_t th; |
||||
- if (pthread_create (&th, &at, tf, NULL) != 0) |
||||
- { |
||||
- puts ("create failed"); |
||||
- exit (1); |
||||
- } |
||||
- |
||||
- pthread_attr_destroy (&at); |
||||
- |
||||
- if (pthread_join (th, NULL) != 0) |
||||
- { |
||||
- puts ("join failed"); |
||||
- exit (1); |
||||
- } |
||||
- |
||||
- /* The following only works because we assume here something about |
||||
- the implementation. Namely, that the memory allocated for the |
||||
- thread descriptor is not going away, that the TID field is |
||||
- cleared and therefore the signal is sent to process 0, and that |
||||
- we can savely assume there is no other process with this ID at |
||||
- that time. */ |
||||
- int e = pthread_kill (th, 0); |
||||
- if (e == 0) |
||||
- { |
||||
- puts ("pthread_kill succeeded"); |
||||
- exit (1); |
||||
- } |
||||
- if (e != ESRCH) |
||||
- { |
||||
- puts ("pthread_kill didn't return ESRCH"); |
||||
- exit (1); |
||||
- } |
||||
- |
||||
- return 0; |
||||
-} |
||||
- |
||||
- |
||||
-#define TEST_FUNCTION do_test () |
||||
-#include "../test-skeleton.c" |
||||
diff --git a/sysdeps/pthread/tst-pthread_cancel-exited.c b/sysdeps/pthread/tst-pthread_cancel-exited.c |
||||
new file mode 100644 |
||||
index 0000000000000000..811c9bee07ab2638 |
||||
--- /dev/null |
||||
+++ b/sysdeps/pthread/tst-pthread_cancel-exited.c |
||||
@@ -0,0 +1,45 @@ |
||||
+/* Test that pthread_kill succeeds for an exited thread. |
||||
+ 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/>. */ |
||||
+ |
||||
+/* This test verifies that pthread_kill returns 0 (and not ESRCH) for |
||||
+ a thread that has exited on the kernel side. */ |
||||
+ |
||||
+#include <stddef.h> |
||||
+#include <support/support.h> |
||||
+#include <support/xthread.h> |
||||
+ |
||||
+static void * |
||||
+noop_thread (void *closure) |
||||
+{ |
||||
+ return NULL; |
||||
+} |
||||
+ |
||||
+static int |
||||
+do_test (void) |
||||
+{ |
||||
+ pthread_t thr = xpthread_create (NULL, noop_thread, NULL); |
||||
+ |
||||
+ support_wait_for_thread_exit (); |
||||
+ |
||||
+ xpthread_cancel (thr); |
||||
+ xpthread_join (thr); |
||||
+ |
||||
+ return 0; |
||||
+} |
||||
+ |
||||
+#include <support/test-driver.c> |
||||
diff --git a/sysdeps/pthread/tst-pthread_kill-exited.c b/sysdeps/pthread/tst-pthread_kill-exited.c |
||||
new file mode 100644 |
||||
index 0000000000000000..7575fb6d58cae99c |
||||
--- /dev/null |
||||
+++ b/sysdeps/pthread/tst-pthread_kill-exited.c |
||||
@@ -0,0 +1,46 @@ |
||||
+/* Test that pthread_kill succeeds for an exited thread. |
||||
+ 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/>. */ |
||||
+ |
||||
+/* This test verifies that pthread_kill returns 0 (and not ESRCH) for |
||||
+ a thread that has exited on the kernel side. */ |
||||
+ |
||||
+#include <signal.h> |
||||
+#include <stddef.h> |
||||
+#include <support/support.h> |
||||
+#include <support/xthread.h> |
||||
+ |
||||
+static void * |
||||
+noop_thread (void *closure) |
||||
+{ |
||||
+ return NULL; |
||||
+} |
||||
+ |
||||
+static int |
||||
+do_test (void) |
||||
+{ |
||||
+ pthread_t thr = xpthread_create (NULL, noop_thread, NULL); |
||||
+ |
||||
+ support_wait_for_thread_exit (); |
||||
+ |
||||
+ xpthread_kill (thr, SIGUSR1); |
||||
+ xpthread_join (thr); |
||||
+ |
||||
+ return 0; |
||||
+} |
||||
+ |
||||
+#include <support/test-driver.c> |
@ -0,0 +1,411 @@
@@ -0,0 +1,411 @@
|
||||
commit a8ac8c4725ddb1119764126a8674a04c9dd5aea8 |
||||
Author: Florian Weimer <fweimer@redhat.com> |
||||
Date: Mon Sep 13 11:06:08 2021 +0200 |
||||
|
||||
nptl: Fix race between pthread_kill and thread exit (bug 12889) |
||||
|
||||
A new thread exit lock and flag are introduced. They are used to |
||||
detect that the thread is about to exit or has exited in |
||||
__pthread_kill_internal, and the signal is not sent in this case. |
||||
|
||||
The test sysdeps/pthread/tst-pthread_cancel-select-loop.c is derived |
||||
from a downstream test originally written by Marek Polacek. |
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org> |
||||
(cherry picked from commit 526c3cf11ee9367344b6b15d669e4c3cb461a2be) |
||||
|
||||
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c |
||||
index cfe37a3443b69454..50065bc9bd8a28e5 100644 |
||||
--- a/nptl/allocatestack.c |
||||
+++ b/nptl/allocatestack.c |
||||
@@ -32,6 +32,7 @@ |
||||
#include <futex-internal.h> |
||||
#include <kernel-features.h> |
||||
#include <nptl-stack.h> |
||||
+#include <libc-lock.h> |
||||
|
||||
/* Default alignment of stack. */ |
||||
#ifndef STACK_ALIGN |
||||
@@ -127,6 +128,8 @@ get_cached_stack (size_t *sizep, void **memp) |
||||
/* No pending event. */ |
||||
result->nextevent = NULL; |
||||
|
||||
+ result->exiting = false; |
||||
+ __libc_lock_init (result->exit_lock); |
||||
result->tls_state = (struct tls_internal_t) { 0 }; |
||||
|
||||
/* Clear the DTV. */ |
||||
diff --git a/nptl/descr.h b/nptl/descr.h |
||||
index c85778d44941a42f..4de84138fb960fa4 100644 |
||||
--- a/nptl/descr.h |
||||
+++ b/nptl/descr.h |
||||
@@ -396,6 +396,12 @@ struct pthread |
||||
PTHREAD_CANCEL_ASYNCHRONOUS). */ |
||||
unsigned char canceltype; |
||||
|
||||
+ /* Used in __pthread_kill_internal to detected a thread that has |
||||
+ exited or is about to exit. exit_lock must only be acquired |
||||
+ after blocking signals. */ |
||||
+ bool exiting; |
||||
+ int exit_lock; /* A low-level lock (for use with __libc_lock_init etc). */ |
||||
+ |
||||
/* Used on strsignal. */ |
||||
struct tls_internal_t tls_state; |
||||
|
||||
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c |
||||
index d8ec299cb1661e82..33b426fc682300dc 100644 |
||||
--- a/nptl/pthread_create.c |
||||
+++ b/nptl/pthread_create.c |
||||
@@ -37,6 +37,7 @@ |
||||
#include <sys/single_threaded.h> |
||||
#include <version.h> |
||||
#include <clone_internal.h> |
||||
+#include <futex-internal.h> |
||||
|
||||
#include <shlib-compat.h> |
||||
|
||||
@@ -485,6 +486,19 @@ start_thread (void *arg) |
||||
/* This was the last thread. */ |
||||
exit (0); |
||||
|
||||
+ /* This prevents sending a signal from this thread to itself during |
||||
+ its final stages. This must come after the exit call above |
||||
+ because atexit handlers must not run with signals blocked. */ |
||||
+ __libc_signal_block_all (NULL); |
||||
+ |
||||
+ /* Tell __pthread_kill_internal that this thread is about to exit. |
||||
+ If there is a __pthread_kill_internal in progress, this delays |
||||
+ the thread exit until the signal has been queued by the kernel |
||||
+ (so that the TID used to send it remains valid). */ |
||||
+ __libc_lock_lock (pd->exit_lock); |
||||
+ pd->exiting = true; |
||||
+ __libc_lock_unlock (pd->exit_lock); |
||||
+ |
||||
#ifndef __ASSUME_SET_ROBUST_LIST |
||||
/* If this thread has any robust mutexes locked, handle them now. */ |
||||
# if __PTHREAD_MUTEX_HAVE_PREV |
||||
diff --git a/nptl/pthread_kill.c b/nptl/pthread_kill.c |
||||
index 5d4c86f9205a6fb5..fb7862eff787a94f 100644 |
||||
--- a/nptl/pthread_kill.c |
||||
+++ b/nptl/pthread_kill.c |
||||
@@ -16,6 +16,7 @@ |
||||
License along with the GNU C Library; if not, see |
||||
<https://www.gnu.org/licenses/>. */ |
||||
|
||||
+#include <libc-lock.h> |
||||
#include <unistd.h> |
||||
#include <pthreadP.h> |
||||
#include <shlib-compat.h> |
||||
@@ -23,37 +24,51 @@ |
||||
int |
||||
__pthread_kill_internal (pthread_t threadid, int signo) |
||||
{ |
||||
- pid_t tid; |
||||
struct pthread *pd = (struct pthread *) threadid; |
||||
- |
||||
if (pd == THREAD_SELF) |
||||
- /* It is a special case to handle raise() implementation after a vfork |
||||
- call (which does not update the PD tid field). */ |
||||
- tid = INLINE_SYSCALL_CALL (gettid); |
||||
- else |
||||
- /* Force load of pd->tid into local variable or register. Otherwise |
||||
- if a thread exits between ESRCH test and tgkill, we might return |
||||
- EINVAL, because pd->tid would be cleared by the kernel. */ |
||||
- tid = atomic_forced_read (pd->tid); |
||||
- |
||||
- int val; |
||||
- if (__glibc_likely (tid > 0)) |
||||
{ |
||||
- pid_t pid = __getpid (); |
||||
- |
||||
- val = INTERNAL_SYSCALL_CALL (tgkill, pid, tid, signo); |
||||
- val = (INTERNAL_SYSCALL_ERROR_P (val) |
||||
- ? INTERNAL_SYSCALL_ERRNO (val) : 0); |
||||
+ /* Use the actual TID from the kernel, so that it refers to the |
||||
+ current thread even if called after vfork. There is no |
||||
+ signal blocking in this case, so that the signal is delivered |
||||
+ immediately, before __pthread_kill_internal returns: a signal |
||||
+ sent to the thread itself needs to be delivered |
||||
+ synchronously. (It is unclear if Linux guarantees the |
||||
+ delivery of all pending signals after unblocking in the code |
||||
+ below. POSIX only guarantees delivery of a single signal, |
||||
+ which may not be the right one.) */ |
||||
+ pid_t tid = INTERNAL_SYSCALL_CALL (gettid); |
||||
+ int ret = INTERNAL_SYSCALL_CALL (kill, tid, signo); |
||||
+ return INTERNAL_SYSCALL_ERROR_P (ret) ? INTERNAL_SYSCALL_ERRNO (ret) : 0; |
||||
} |
||||
+ |
||||
+ /* Block all signals, as required by pd->exit_lock. */ |
||||
+ sigset_t old_mask; |
||||
+ __libc_signal_block_all (&old_mask); |
||||
+ __libc_lock_lock (pd->exit_lock); |
||||
+ |
||||
+ int ret; |
||||
+ if (pd->exiting) |
||||
+ /* The thread is about to exit (or has exited). Sending the |
||||
+ signal is either not observable (the target thread has already |
||||
+ blocked signals at this point), or it will fail, or it might be |
||||
+ delivered to a new, unrelated thread that has reused the TID. |
||||
+ So do not actually send the signal. Do not report an error |
||||
+ because the threadid argument is still valid (the thread ID |
||||
+ lifetime has not ended), and ESRCH (for example) would be |
||||
+ misleading. */ |
||||
+ ret = 0; |
||||
else |
||||
- /* The kernel reports that the thread has exited. POSIX specifies |
||||
- the ESRCH error only for the case when the lifetime of a thread |
||||
- ID has ended, but calling pthread_kill on such a thread ID is |
||||
- undefined in glibc. Therefore, do not treat kernel thread exit |
||||
- as an error. */ |
||||
- val = 0; |
||||
+ { |
||||
+ /* Using tgkill is a safety measure. pd->exit_lock ensures that |
||||
+ the target thread cannot exit. */ |
||||
+ ret = INTERNAL_SYSCALL_CALL (tgkill, __getpid (), pd->tid, signo); |
||||
+ ret = INTERNAL_SYSCALL_ERROR_P (ret) ? INTERNAL_SYSCALL_ERRNO (ret) : 0; |
||||
+ } |
||||
+ |
||||
+ __libc_lock_unlock (pd->exit_lock); |
||||
+ __libc_signal_restore_set (&old_mask); |
||||
|
||||
- return val; |
||||
+ return ret; |
||||
} |
||||
|
||||
int |
||||
diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile |
||||
index dedfa0d290da4949..48dba717a1cdc20a 100644 |
||||
--- a/sysdeps/pthread/Makefile |
||||
+++ b/sysdeps/pthread/Makefile |
||||
@@ -119,7 +119,9 @@ tests += tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \ |
||||
tst-unwind-thread \ |
||||
tst-pt-vfork1 tst-pt-vfork2 tst-vfork1x tst-vfork2x \ |
||||
tst-pthread_cancel-exited \ |
||||
+ tst-pthread_cancel-select-loop \ |
||||
tst-pthread_kill-exited \ |
||||
+ tst-pthread_kill-exiting \ |
||||
# tests |
||||
|
||||
tests-time64 := \ |
||||
diff --git a/sysdeps/pthread/tst-pthread_cancel-select-loop.c b/sysdeps/pthread/tst-pthread_cancel-select-loop.c |
||||
new file mode 100644 |
||||
index 0000000000000000..a62087589cee24b5 |
||||
--- /dev/null |
||||
+++ b/sysdeps/pthread/tst-pthread_cancel-select-loop.c |
||||
@@ -0,0 +1,87 @@ |
||||
+/* Test that pthread_cancel succeeds during thread exit. |
||||
+ 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/>. */ |
||||
+ |
||||
+/* This test tries to trigger an internal race condition in |
||||
+ pthread_cancel, where the cancellation signal is sent after the |
||||
+ thread has begun the cancellation process. This can result in a |
||||
+ spurious ESRCH error. For the original bug 12889, the window is |
||||
+ quite small, so the bug was not reproduced in every run. */ |
||||
+ |
||||
+#include <stdbool.h> |
||||
+#include <stddef.h> |
||||
+#include <support/check.h> |
||||
+#include <support/xthread.h> |
||||
+#include <support/xunistd.h> |
||||
+#include <sys/select.h> |
||||
+#include <unistd.h> |
||||
+ |
||||
+/* Set to true by timeout_thread_function when the test should |
||||
+ terminate. */ |
||||
+static bool timeout; |
||||
+ |
||||
+static void * |
||||
+timeout_thread_function (void *unused) |
||||
+{ |
||||
+ usleep (5 * 1000 * 1000); |
||||
+ __atomic_store_n (&timeout, true, __ATOMIC_RELAXED); |
||||
+ return NULL; |
||||
+} |
||||
+ |
||||
+/* Used for blocking the select function below. */ |
||||
+static int pipe_fds[2]; |
||||
+ |
||||
+static void * |
||||
+canceled_thread_function (void *unused) |
||||
+{ |
||||
+ while (true) |
||||
+ { |
||||
+ fd_set rfs; |
||||
+ fd_set wfs; |
||||
+ fd_set efs; |
||||
+ FD_ZERO (&rfs); |
||||
+ FD_ZERO (&wfs); |
||||
+ FD_ZERO (&efs); |
||||
+ FD_SET (pipe_fds[0], &rfs); |
||||
+ |
||||
+ /* If the cancellation request is recognized early, the thread |
||||
+ begins exiting while the cancellation signal arrives. */ |
||||
+ select (FD_SETSIZE, &rfs, &wfs, &efs, NULL); |
||||
+ } |
||||
+ return NULL; |
||||
+} |
||||
+ |
||||
+static int |
||||
+do_test (void) |
||||
+{ |
||||
+ xpipe (pipe_fds); |
||||
+ pthread_t thr_timeout = xpthread_create (NULL, timeout_thread_function, NULL); |
||||
+ |
||||
+ while (!__atomic_load_n (&timeout, __ATOMIC_RELAXED)) |
||||
+ { |
||||
+ pthread_t thr = xpthread_create (NULL, canceled_thread_function, NULL); |
||||
+ xpthread_cancel (thr); |
||||
+ TEST_VERIFY (xpthread_join (thr) == PTHREAD_CANCELED); |
||||
+ } |
||||
+ |
||||
+ xpthread_join (thr_timeout); |
||||
+ xclose (pipe_fds[0]); |
||||
+ xclose (pipe_fds[1]); |
||||
+ return 0; |
||||
+} |
||||
+ |
||||
+#include <support/test-driver.c> |
||||
diff --git a/sysdeps/pthread/tst-pthread_kill-exiting.c b/sysdeps/pthread/tst-pthread_kill-exiting.c |
||||
new file mode 100644 |
||||
index 0000000000000000..f803e94f1195f204 |
||||
--- /dev/null |
||||
+++ b/sysdeps/pthread/tst-pthread_kill-exiting.c |
||||
@@ -0,0 +1,123 @@ |
||||
+/* Test that pthread_kill succeeds during thread exit. |
||||
+ 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/>. */ |
||||
+ |
||||
+/* This test verifies that pthread_kill for a thread that is exiting |
||||
+ succeeds (with or without actually delivering the signal). */ |
||||
+ |
||||
+#include <array_length.h> |
||||
+#include <stdbool.h> |
||||
+#include <stddef.h> |
||||
+#include <support/xsignal.h> |
||||
+#include <support/xthread.h> |
||||
+#include <unistd.h> |
||||
+ |
||||
+/* Set to true by timeout_thread_function when the test should |
||||
+ terminate. */ |
||||
+static bool timeout; |
||||
+ |
||||
+static void * |
||||
+timeout_thread_function (void *unused) |
||||
+{ |
||||
+ usleep (1000 * 1000); |
||||
+ __atomic_store_n (&timeout, true, __ATOMIC_RELAXED); |
||||
+ return NULL; |
||||
+} |
||||
+ |
||||
+/* Used to synchronize the sending threads with the target thread and |
||||
+ main thread. */ |
||||
+static pthread_barrier_t barrier_1; |
||||
+static pthread_barrier_t barrier_2; |
||||
+ |
||||
+/* The target thread to which signals are to be sent. */ |
||||
+static pthread_t target_thread; |
||||
+ |
||||
+/* Set by the main thread to true after timeout has been set to |
||||
+ true. */ |
||||
+static bool exiting; |
||||
+ |
||||
+static void * |
||||
+sender_thread_function (void *unused) |
||||
+{ |
||||
+ while (true) |
||||
+ { |
||||
+ /* Wait until target_thread has been initialized. The target |
||||
+ thread and main thread participate in this barrier. */ |
||||
+ xpthread_barrier_wait (&barrier_1); |
||||
+ |
||||
+ if (exiting) |
||||
+ break; |
||||
+ |
||||
+ xpthread_kill (target_thread, SIGUSR1); |
||||
+ |
||||
+ /* Communicate that the signal has been sent. The main thread |
||||
+ participates in this barrier. */ |
||||
+ xpthread_barrier_wait (&barrier_2); |
||||
+ } |
||||
+ return NULL; |
||||
+} |
||||
+ |
||||
+static void * |
||||
+target_thread_function (void *unused) |
||||
+{ |
||||
+ target_thread = pthread_self (); |
||||
+ xpthread_barrier_wait (&barrier_1); |
||||
+ return NULL; |
||||
+} |
||||
+ |
||||
+static int |
||||
+do_test (void) |
||||
+{ |
||||
+ xsignal (SIGUSR1, SIG_IGN); |
||||
+ |
||||
+ pthread_t thr_timeout = xpthread_create (NULL, timeout_thread_function, NULL); |
||||
+ |
||||
+ pthread_t threads[4]; |
||||
+ xpthread_barrier_init (&barrier_1, NULL, array_length (threads) + 2); |
||||
+ xpthread_barrier_init (&barrier_2, NULL, array_length (threads) + 1); |
||||
+ |
||||
+ for (int i = 0; i < array_length (threads); ++i) |
||||
+ threads[i] = xpthread_create (NULL, sender_thread_function, NULL); |
||||
+ |
||||
+ while (!__atomic_load_n (&timeout, __ATOMIC_RELAXED)) |
||||
+ { |
||||
+ xpthread_create (NULL, target_thread_function, NULL); |
||||
+ |
||||
+ /* Wait for the target thread to be set up and signal sending to |
||||
+ start. */ |
||||
+ xpthread_barrier_wait (&barrier_1); |
||||
+ |
||||
+ /* Wait for signal sending to complete. */ |
||||
+ xpthread_barrier_wait (&barrier_2); |
||||
+ |
||||
+ xpthread_join (target_thread); |
||||
+ } |
||||
+ |
||||
+ exiting = true; |
||||
+ |
||||
+ /* Signal the sending threads to exit. */ |
||||
+ xpthread_create (NULL, target_thread_function, NULL); |
||||
+ xpthread_barrier_wait (&barrier_1); |
||||
+ |
||||
+ for (int i = 0; i < array_length (threads); ++i) |
||||
+ xpthread_join (threads[i]); |
||||
+ xpthread_join (thr_timeout); |
||||
+ |
||||
+ return 0; |
||||
+} |
||||
+ |
||||
+#include <support/test-driver.c> |
@ -0,0 +1,117 @@
@@ -0,0 +1,117 @@
|
||||
commit 3fc51f35b4f32e1bb99d85c1578e930e725ff929 |
||||
Author: Siddhesh Poyarekar <siddhesh@sourceware.org> |
||||
Date: Mon Sep 13 20:48:35 2021 +0530 |
||||
|
||||
iconvconfig: Fix behaviour with --prefix [BZ #28199] |
||||
|
||||
The consolidation of configuration parsing broke behaviour with |
||||
--prefix, where the prefix bled into the modules cache. Accept a |
||||
prefix which, when non-NULL, is prepended to the path when looking for |
||||
configuration files but only the original directory is added to the |
||||
modules cache. |
||||
|
||||
This has no effect on the codegen of gconv_conf since it passes NULL. |
||||
|
||||
Reported-by: Patrick McCarty <patrick.mccarty@intel.com> |
||||
Reported-by: Michael Hudson-Doyle <michael.hudson@canonical.com> |
||||
Reviewed-by: Andreas Schwab <schwab@linux-m68k.org> |
||||
(cherry picked from commit 43cea6d5652b6b9e61ac6ecc69419c909b504f47) |
||||
|
||||
diff --git a/iconv/gconv_conf.c b/iconv/gconv_conf.c |
||||
index 62bee28769deb979..cc391d8f936687f3 100644 |
||||
--- a/iconv/gconv_conf.c |
||||
+++ b/iconv/gconv_conf.c |
||||
@@ -478,7 +478,7 @@ __gconv_read_conf (void) |
||||
__gconv_get_path (); |
||||
|
||||
for (cnt = 0; __gconv_path_elem[cnt].name != NULL; ++cnt) |
||||
- gconv_parseconfdir (__gconv_path_elem[cnt].name, |
||||
+ gconv_parseconfdir (NULL, __gconv_path_elem[cnt].name, |
||||
__gconv_path_elem[cnt].len); |
||||
#endif |
||||
|
||||
diff --git a/iconv/gconv_parseconfdir.h b/iconv/gconv_parseconfdir.h |
||||
index 2f062689ecc72749..a586268abc103abd 100644 |
||||
--- a/iconv/gconv_parseconfdir.h |
||||
+++ b/iconv/gconv_parseconfdir.h |
||||
@@ -39,7 +39,6 @@ |
||||
/* Name of the file containing the module information in the directories |
||||
along the path. */ |
||||
static const char gconv_conf_filename[] = "gconv-modules"; |
||||
-static const char gconv_conf_dirname[] = "gconv-modules.d"; |
||||
|
||||
static void add_alias (char *); |
||||
static void add_module (char *, const char *, size_t, int); |
||||
@@ -110,19 +109,28 @@ read_conf_file (const char *filename, const char *directory, size_t dir_len) |
||||
return true; |
||||
} |
||||
|
||||
+/* Prefix DIR (with length DIR_LEN) with PREFIX if the latter is non-NULL and |
||||
+ parse configuration in it. */ |
||||
+ |
||||
static __always_inline bool |
||||
-gconv_parseconfdir (const char *dir, size_t dir_len) |
||||
+gconv_parseconfdir (const char *prefix, const char *dir, size_t dir_len) |
||||
{ |
||||
- /* No slash needs to be inserted between dir and gconv_conf_filename; |
||||
- dir already ends in a slash. */ |
||||
- char *buf = malloc (dir_len + sizeof (gconv_conf_dirname)); |
||||
+ /* No slash needs to be inserted between dir and gconv_conf_filename; dir |
||||
+ already ends in a slash. The additional 2 is to accommodate the ".d" |
||||
+ when looking for configuration files in gconv-modules.d. */ |
||||
+ size_t buflen = dir_len + sizeof (gconv_conf_filename) + 2; |
||||
+ char *buf = malloc (buflen + (prefix != NULL ? strlen (prefix) : 0)); |
||||
+ char *cp = buf; |
||||
bool found = false; |
||||
|
||||
if (buf == NULL) |
||||
return false; |
||||
|
||||
- char *cp = mempcpy (mempcpy (buf, dir, dir_len), gconv_conf_filename, |
||||
- sizeof (gconv_conf_filename)); |
||||
+ if (prefix != NULL) |
||||
+ cp = stpcpy (cp, prefix); |
||||
+ |
||||
+ cp = mempcpy (mempcpy (cp, dir, dir_len), gconv_conf_filename, |
||||
+ sizeof (gconv_conf_filename)); |
||||
|
||||
/* Read the gconv-modules configuration file first. */ |
||||
found = read_conf_file (buf, dir, dir_len); |
||||
diff --git a/iconv/iconvconfig.c b/iconv/iconvconfig.c |
||||
index 783b2bbdbb684ac6..273a71f67315f670 100644 |
||||
--- a/iconv/iconvconfig.c |
||||
+++ b/iconv/iconvconfig.c |
||||
@@ -653,13 +653,21 @@ add_module (char *rp, const char *directory, |
||||
static int |
||||
handle_dir (const char *dir) |
||||
{ |
||||
+ char *newp = NULL; |
||||
size_t dirlen = strlen (dir); |
||||
bool found = false; |
||||
|
||||
- char *fulldir = xasprintf ("%s%s%s", dir[0] == '/' ? prefix : "", |
||||
- dir, dir[dirlen - 1] != '/' ? "/" : ""); |
||||
+ /* End directory path with a '/' if it doesn't already. */ |
||||
+ if (dir[dirlen - 1] != '/') |
||||
+ { |
||||
+ newp = xmalloc (dirlen + 2); |
||||
+ memcpy (newp, dir, dirlen); |
||||
+ newp[dirlen++] = '/'; |
||||
+ newp[dirlen] = '\0'; |
||||
+ dir = newp; |
||||
+ } |
||||
|
||||
- found = gconv_parseconfdir (fulldir, strlen (fulldir)); |
||||
+ found = gconv_parseconfdir (dir[0] == '/' ? prefix : NULL, dir, dirlen); |
||||
|
||||
if (!found) |
||||
{ |
||||
@@ -671,7 +679,7 @@ handle_dir (const char *dir) |
||||
"configuration files with names ending in .conf."); |
||||
} |
||||
|
||||
- free (fulldir); |
||||
+ free (newp); |
||||
|
||||
return found ? 0 : 1; |
||||
} |
@ -0,0 +1,31 @@
@@ -0,0 +1,31 @@
|
||||
commit ae925404a10bf0ea63d6e8d41e3821f68b4d776c |
||||
Author: Aurelien Jarno <aurelien@aurel32.net> |
||||
Date: Fri Sep 3 00:28:14 2021 +0200 |
||||
|
||||
Fix failing nss/tst-nss-files-hosts-long with local resolver |
||||
|
||||
When a local resolver like unbound is listening on the IPv4 loopback |
||||
address 127.0.0.1, the nss/tst-nss-files-hosts-long test fails. This is |
||||
due to: |
||||
- the default resolver in the absence of resolv.conf being 127.0.0.1 |
||||
- the default DNS NSS database configuration in the absence of |
||||
nsswitch.conf being 'hosts: dns [!UNAVAIL=return] file' |
||||
|
||||
This causes the requests for 'test4' and 'test6' to first be sent to the |
||||
local resolver, which responds with NXDOMAIN in the likely case those |
||||
records do no exist. In turn that causes the access to /etc/hosts to be |
||||
skipped, which is the purpose of that test. |
||||
|
||||
Fix that by providing a simple nsswitch.conf file forcing access to |
||||
/etc/hosts for that test. I have tested that the only changed result in |
||||
the testsuite is that test. |
||||
|
||||
(cherry picked from commit 2738480a4b0866723fb8c633f36bdd34a8767581) |
||||
|
||||
diff --git a/nss/tst-nss-files-hosts-long.root/etc/nsswitch.conf b/nss/tst-nss-files-hosts-long.root/etc/nsswitch.conf |
||||
new file mode 100644 |
||||
index 0000000000000000..5b0c6a419937a013 |
||||
--- /dev/null |
||||
+++ b/nss/tst-nss-files-hosts-long.root/etc/nsswitch.conf |
||||
@@ -0,0 +1 @@ |
||||
+hosts: files |
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
commit 007d699d0e0d0957eead78ad252ad592656284de |
||||
Author: Joseph Myers <joseph@codesourcery.com> |
||||
Date: Tue Sep 7 13:08:38 2021 +0000 |
||||
|
||||
Use Linux 5.14 in build-many-glibcs.py |
||||
|
||||
This patch makes build-many-glibcs.py use Linux 5.14. |
||||
|
||||
Tested with build-many-glibcs.py (host-libraries, compilers and glibcs |
||||
builds). |
||||
|
||||
(cherry picked from commit 4e04a47208e1712fcf202a6d9831f0900d575225) |
||||
|
||||
diff --git a/scripts/build-many-glibcs.py b/scripts/build-many-glibcs.py |
||||
index 5a77af90a6b49909..86537fa8005cfd3d 100755 |
||||
--- a/scripts/build-many-glibcs.py |
||||
+++ b/scripts/build-many-glibcs.py |
||||
@@ -782,7 +782,7 @@ class Context(object): |
||||
'gcc': 'vcs-11', |
||||
'glibc': 'vcs-mainline', |
||||
'gmp': '6.2.1', |
||||
- 'linux': '5.13', |
||||
+ 'linux': '5.14', |
||||
'mpc': '1.2.1', |
||||
'mpfr': '4.1.0', |
||||
'mig': 'vcs-mainline', |
@ -0,0 +1,377 @@
@@ -0,0 +1,377 @@
|
||||
commit 005bafcf5b8a85d4c82831401f052747e160a7e8 |
||||
Author: Joseph Myers <joseph@codesourcery.com> |
||||
Date: Wed Sep 8 12:42:06 2021 +0000 |
||||
|
||||
Update syscall lists for Linux 5.14 |
||||
|
||||
Linux 5.14 has two new syscalls, memfd_secret (on some architectures |
||||
only) and quotactl_fd. Update syscall-names.list and regenerate the |
||||
arch-syscall.h headers with build-many-glibcs.py update-syscalls. |
||||
|
||||
Tested with build-many-glibcs.py. |
||||
|
||||
(cherry picked from commit 89dc0372a9055e7ef86fe19be6201fa0b16b2f0e) |
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h |
||||
index e9eb707d0ac022ed..bedab1abbac7f6c1 100644 |
||||
--- a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h |
||||
+++ b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h |
||||
@@ -126,6 +126,7 @@ |
||||
#define __NR_mbind 235 |
||||
#define __NR_membarrier 283 |
||||
#define __NR_memfd_create 279 |
||||
+#define __NR_memfd_secret 447 |
||||
#define __NR_migrate_pages 238 |
||||
#define __NR_mincore 232 |
||||
#define __NR_mkdirat 34 |
||||
@@ -187,6 +188,7 @@ |
||||
#define __NR_pwritev 70 |
||||
#define __NR_pwritev2 287 |
||||
#define __NR_quotactl 60 |
||||
+#define __NR_quotactl_fd 443 |
||||
#define __NR_read 63 |
||||
#define __NR_readahead 213 |
||||
#define __NR_readlinkat 78 |
||||
diff --git a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h |
||||
index bd6b7d4003a252be..91354ed9e29b8d15 100644 |
||||
--- a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h |
||||
+++ b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h |
||||
@@ -337,6 +337,7 @@ |
||||
#define __NR_pwritev2 521 |
||||
#define __NR_query_module 347 |
||||
#define __NR_quotactl 148 |
||||
+#define __NR_quotactl_fd 553 |
||||
#define __NR_read 3 |
||||
#define __NR_readahead 379 |
||||
#define __NR_readlink 58 |
||||
diff --git a/sysdeps/unix/sysv/linux/arc/arch-syscall.h b/sysdeps/unix/sysv/linux/arc/arch-syscall.h |
||||
index 10650549c1dcd100..ff5c7eb36db89494 100644 |
||||
--- a/sysdeps/unix/sysv/linux/arc/arch-syscall.h |
||||
+++ b/sysdeps/unix/sysv/linux/arc/arch-syscall.h |
||||
@@ -190,6 +190,7 @@ |
||||
#define __NR_pwritev 70 |
||||
#define __NR_pwritev2 287 |
||||
#define __NR_quotactl 60 |
||||
+#define __NR_quotactl_fd 443 |
||||
#define __NR_read 63 |
||||
#define __NR_readahead 213 |
||||
#define __NR_readlinkat 78 |
||||
diff --git a/sysdeps/unix/sysv/linux/arm/arch-syscall.h b/sysdeps/unix/sysv/linux/arm/arch-syscall.h |
||||
index 85c9b236ce7862b6..5772333ceef6ce59 100644 |
||||
--- a/sysdeps/unix/sysv/linux/arm/arch-syscall.h |
||||
+++ b/sysdeps/unix/sysv/linux/arm/arch-syscall.h |
||||
@@ -244,6 +244,7 @@ |
||||
#define __NR_pwritev 362 |
||||
#define __NR_pwritev2 393 |
||||
#define __NR_quotactl 131 |
||||
+#define __NR_quotactl_fd 443 |
||||
#define __NR_read 3 |
||||
#define __NR_readahead 225 |
||||
#define __NR_readlink 85 |
||||
diff --git a/sysdeps/unix/sysv/linux/csky/arch-syscall.h b/sysdeps/unix/sysv/linux/csky/arch-syscall.h |
||||
index 24b0d1f94e5f99da..4af6d6202f6df7ae 100644 |
||||
--- a/sysdeps/unix/sysv/linux/csky/arch-syscall.h |
||||
+++ b/sysdeps/unix/sysv/linux/csky/arch-syscall.h |
||||
@@ -199,6 +199,7 @@ |
||||
#define __NR_pwritev 70 |
||||
#define __NR_pwritev2 287 |
||||
#define __NR_quotactl 60 |
||||
+#define __NR_quotactl_fd 443 |
||||
#define __NR_read 63 |
||||
#define __NR_readahead 213 |
||||
#define __NR_readlinkat 78 |
||||
diff --git a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h |
||||
index feb70abc3e1eb486..b07fc8549de34157 100644 |
||||
--- a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h |
||||
+++ b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h |
||||
@@ -231,6 +231,7 @@ |
||||
#define __NR_pwritev 316 |
||||
#define __NR_pwritev2 348 |
||||
#define __NR_quotactl 131 |
||||
+#define __NR_quotactl_fd 443 |
||||
#define __NR_read 3 |
||||
#define __NR_readahead 207 |
||||
#define __NR_readlink 85 |
||||
diff --git a/sysdeps/unix/sysv/linux/i386/arch-syscall.h b/sysdeps/unix/sysv/linux/i386/arch-syscall.h |
||||
index 3b1894a79b6fcfaf..6e4264698b5ce480 100644 |
||||
--- a/sysdeps/unix/sysv/linux/i386/arch-syscall.h |
||||
+++ b/sysdeps/unix/sysv/linux/i386/arch-syscall.h |
||||
@@ -183,6 +183,7 @@ |
||||
#define __NR_mbind 274 |
||||
#define __NR_membarrier 375 |
||||
#define __NR_memfd_create 356 |
||||
+#define __NR_memfd_secret 447 |
||||
#define __NR_migrate_pages 294 |
||||
#define __NR_mincore 218 |
||||
#define __NR_mkdir 39 |
||||
@@ -266,6 +267,7 @@ |
||||
#define __NR_pwritev2 379 |
||||
#define __NR_query_module 167 |
||||
#define __NR_quotactl 131 |
||||
+#define __NR_quotactl_fd 443 |
||||
#define __NR_read 3 |
||||
#define __NR_readahead 225 |
||||
#define __NR_readdir 89 |
||||
diff --git a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h |
||||
index fb388a5fa4e9b28e..1ca706d7216a3902 100644 |
||||
--- a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h |
||||
+++ b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h |
||||
@@ -218,6 +218,7 @@ |
||||
#define __NR_pwritev 1320 |
||||
#define __NR_pwritev2 1349 |
||||
#define __NR_quotactl 1137 |
||||
+#define __NR_quotactl_fd 1467 |
||||
#define __NR_read 1026 |
||||
#define __NR_readahead 1216 |
||||
#define __NR_readlink 1092 |
||||
diff --git a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h |
||||
index 7bc8c4af92cf2bd3..2f10f71f90d225ff 100644 |
||||
--- a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h |
||||
+++ b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h |
||||
@@ -254,6 +254,7 @@ |
||||
#define __NR_pwritev2 378 |
||||
#define __NR_query_module 167 |
||||
#define __NR_quotactl 131 |
||||
+#define __NR_quotactl_fd 443 |
||||
#define __NR_read 3 |
||||
#define __NR_readahead 240 |
||||
#define __NR_readdir 89 |
||||
diff --git a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h |
||||
index cf560d3af47f19c5..0607a4dfa6adaa23 100644 |
||||
--- a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h |
||||
+++ b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h |
||||
@@ -266,6 +266,7 @@ |
||||
#define __NR_pwritev2 394 |
||||
#define __NR_query_module 167 |
||||
#define __NR_quotactl 131 |
||||
+#define __NR_quotactl_fd 443 |
||||
#define __NR_read 3 |
||||
#define __NR_readahead 225 |
||||
#define __NR_readdir 89 |
||||
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h |
||||
index f346460f4880f10e..0055eec0b169ba96 100644 |
||||
--- a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h |
||||
+++ b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h |
||||
@@ -251,6 +251,7 @@ |
||||
#define __NR_pwritev2 4362 |
||||
#define __NR_query_module 4187 |
||||
#define __NR_quotactl 4131 |
||||
+#define __NR_quotactl_fd 4443 |
||||
#define __NR_read 4003 |
||||
#define __NR_readahead 4223 |
||||
#define __NR_readdir 4089 |
||||
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h |
||||
index 38ed84997a2fa3d1..8e8e9f91ccfebfab 100644 |
||||
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h |
||||
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h |
||||
@@ -232,6 +232,7 @@ |
||||
#define __NR_pwritev2 6326 |
||||
#define __NR_query_module 6171 |
||||
#define __NR_quotactl 6172 |
||||
+#define __NR_quotactl_fd 6443 |
||||
#define __NR_read 6000 |
||||
#define __NR_readahead 6179 |
||||
#define __NR_readlink 6087 |
||||
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h |
||||
index e6a10c842178168c..ebd1545f806564bb 100644 |
||||
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h |
||||
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h |
||||
@@ -219,6 +219,7 @@ |
||||
#define __NR_pwritev2 5322 |
||||
#define __NR_query_module 5171 |
||||
#define __NR_quotactl 5172 |
||||
+#define __NR_quotactl_fd 5443 |
||||
#define __NR_read 5000 |
||||
#define __NR_readahead 5179 |
||||
#define __NR_readlink 5087 |
||||
diff --git a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h |
||||
index 5314890289a1723f..2b530b1f88e4c52a 100644 |
||||
--- a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h |
||||
+++ b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h |
||||
@@ -198,6 +198,7 @@ |
||||
#define __NR_pwritev 70 |
||||
#define __NR_pwritev2 287 |
||||
#define __NR_quotactl 60 |
||||
+#define __NR_quotactl_fd 443 |
||||
#define __NR_read 63 |
||||
#define __NR_readahead 213 |
||||
#define __NR_readlinkat 78 |
||||
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h |
||||
index b5b075853297cf2e..a32984a9c17315ee 100644 |
||||
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h |
||||
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h |
||||
@@ -260,6 +260,7 @@ |
||||
#define __NR_pwritev2 381 |
||||
#define __NR_query_module 166 |
||||
#define __NR_quotactl 131 |
||||
+#define __NR_quotactl_fd 443 |
||||
#define __NR_read 3 |
||||
#define __NR_readahead 191 |
||||
#define __NR_readdir 89 |
||||
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h |
||||
index c77435ca61aba109..b01e464fb906d632 100644 |
||||
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h |
||||
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h |
||||
@@ -243,6 +243,7 @@ |
||||
#define __NR_pwritev2 381 |
||||
#define __NR_query_module 166 |
||||
#define __NR_quotactl 131 |
||||
+#define __NR_quotactl_fd 443 |
||||
#define __NR_read 3 |
||||
#define __NR_readahead 191 |
||||
#define __NR_readdir 89 |
||||
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h |
||||
index 70854bb9e360b40a..24d0a2c455caa630 100644 |
||||
--- a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h |
||||
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h |
||||
@@ -179,6 +179,7 @@ |
||||
#define __NR_pwritev 70 |
||||
#define __NR_pwritev2 287 |
||||
#define __NR_quotactl 60 |
||||
+#define __NR_quotactl_fd 443 |
||||
#define __NR_read 63 |
||||
#define __NR_readahead 213 |
||||
#define __NR_readlinkat 78 |
||||
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h |
||||
index 83b9f31abaee9d52..e526c89ae7b285cc 100644 |
||||
--- a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h |
||||
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h |
||||
@@ -187,6 +187,7 @@ |
||||
#define __NR_pwritev 70 |
||||
#define __NR_pwritev2 287 |
||||
#define __NR_quotactl 60 |
||||
+#define __NR_quotactl_fd 443 |
||||
#define __NR_read 63 |
||||
#define __NR_readahead 213 |
||||
#define __NR_readlinkat 78 |
||||
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h |
||||
index b224c4aad4c9b1b1..d4c7b101b64c010f 100644 |
||||
--- a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h |
||||
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h |
||||
@@ -251,6 +251,7 @@ |
||||
#define __NR_pwritev2 377 |
||||
#define __NR_query_module 167 |
||||
#define __NR_quotactl 131 |
||||
+#define __NR_quotactl_fd 443 |
||||
#define __NR_read 3 |
||||
#define __NR_readahead 222 |
||||
#define __NR_readdir 89 |
||||
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h |
||||
index 59864af125b437e4..bd8c78d7059a0f31 100644 |
||||
--- a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h |
||||
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h |
||||
@@ -221,6 +221,7 @@ |
||||
#define __NR_pwritev2 377 |
||||
#define __NR_query_module 167 |
||||
#define __NR_quotactl 131 |
||||
+#define __NR_quotactl_fd 443 |
||||
#define __NR_read 3 |
||||
#define __NR_readahead 222 |
||||
#define __NR_readdir 89 |
||||
diff --git a/sysdeps/unix/sysv/linux/sh/arch-syscall.h b/sysdeps/unix/sysv/linux/sh/arch-syscall.h |
||||
index 23612c9092b9c2ee..3b6ac3d084d74638 100644 |
||||
--- a/sysdeps/unix/sysv/linux/sh/arch-syscall.h |
||||
+++ b/sysdeps/unix/sysv/linux/sh/arch-syscall.h |
||||
@@ -246,6 +246,7 @@ |
||||
#define __NR_pwritev 334 |
||||
#define __NR_pwritev2 382 |
||||
#define __NR_quotactl 131 |
||||
+#define __NR_quotactl_fd 443 |
||||
#define __NR_read 3 |
||||
#define __NR_readahead 225 |
||||
#define __NR_readdir 89 |
||||
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h |
||||
index 380cddb2d8f9f443..35221a707e4d4a7c 100644 |
||||
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h |
||||
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h |
||||
@@ -252,6 +252,7 @@ |
||||
#define __NR_pwritev2 359 |
||||
#define __NR_query_module 184 |
||||
#define __NR_quotactl 165 |
||||
+#define __NR_quotactl_fd 443 |
||||
#define __NR_read 3 |
||||
#define __NR_readahead 205 |
||||
#define __NR_readdir 204 |
||||
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h |
||||
index 2175eeb6edcf7c34..5ba2b2050924df1c 100644 |
||||
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h |
||||
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h |
||||
@@ -231,6 +231,7 @@ |
||||
#define __NR_pwritev2 359 |
||||
#define __NR_query_module 184 |
||||
#define __NR_quotactl 165 |
||||
+#define __NR_quotactl_fd 443 |
||||
#define __NR_read 3 |
||||
#define __NR_readahead 205 |
||||
#define __NR_readdir 204 |
||||
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list |
||||
index 89c5895b9b6845ff..fd98893b0e44a606 100644 |
||||
--- a/sysdeps/unix/sysv/linux/syscall-names.list |
||||
+++ b/sysdeps/unix/sysv/linux/syscall-names.list |
||||
@@ -21,8 +21,8 @@ |
||||
# This file can list all potential system calls. The names are only |
||||
# used if the installed kernel headers also provide them. |
||||
|
||||
-# The list of system calls is current as of Linux 5.13. |
||||
-kernel 5.13 |
||||
+# The list of system calls is current as of Linux 5.14. |
||||
+kernel 5.14 |
||||
|
||||
FAST_atomic_update |
||||
FAST_cmpxchg |
||||
@@ -247,6 +247,7 @@ madvise |
||||
mbind |
||||
membarrier |
||||
memfd_create |
||||
+memfd_secret |
||||
memory_ordering |
||||
migrate_pages |
||||
mincore |
||||
@@ -452,6 +453,7 @@ pwritev |
||||
pwritev2 |
||||
query_module |
||||
quotactl |
||||
+quotactl_fd |
||||
read |
||||
readahead |
||||
readdir |
||||
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h |
||||
index 8e028eb62be2041d..26d6ac68a651ec98 100644 |
||||
--- a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h |
||||
+++ b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h |
||||
@@ -154,6 +154,7 @@ |
||||
#define __NR_mbind 237 |
||||
#define __NR_membarrier 324 |
||||
#define __NR_memfd_create 319 |
||||
+#define __NR_memfd_secret 447 |
||||
#define __NR_migrate_pages 256 |
||||
#define __NR_mincore 27 |
||||
#define __NR_mkdir 83 |
||||
@@ -224,6 +225,7 @@ |
||||
#define __NR_pwritev2 328 |
||||
#define __NR_query_module 178 |
||||
#define __NR_quotactl 179 |
||||
+#define __NR_quotactl_fd 443 |
||||
#define __NR_read 0 |
||||
#define __NR_readahead 187 |
||||
#define __NR_readlink 89 |
||||
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h |
||||
index 004feb53f1f38ced..36847783f6b91d5e 100644 |
||||
--- a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h |
||||
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h |
||||
@@ -148,6 +148,7 @@ |
||||
#define __NR_mbind 1073742061 |
||||
#define __NR_membarrier 1073742148 |
||||
#define __NR_memfd_create 1073742143 |
||||
+#define __NR_memfd_secret 1073742271 |
||||
#define __NR_migrate_pages 1073742080 |
||||
#define __NR_mincore 1073741851 |
||||
#define __NR_mkdir 1073741907 |
||||
@@ -216,6 +217,7 @@ |
||||
#define __NR_pwritev 1073742359 |
||||
#define __NR_pwritev2 1073742371 |
||||
#define __NR_quotactl 1073742003 |
||||
+#define __NR_quotactl_fd 1073742267 |
||||
#define __NR_read 1073741824 |
||||
#define __NR_readahead 1073742011 |
||||
#define __NR_readlink 1073741913 |
@ -0,0 +1,27 @@
@@ -0,0 +1,27 @@
|
||||
commit 114581bf53864aaee562ee237461fc394bc61963 |
||||
Author: Joseph Myers <joseph@codesourcery.com> |
||||
Date: Tue Sep 14 13:51:58 2021 +0000 |
||||
|
||||
Update kernel version to 5.14 in tst-mman-consts.py |
||||
|
||||
This patch updates the kernel version in the test tst-mman-consts.py |
||||
to 5.14. (There are no new MAP_* constants covered by this test in |
||||
5.14 that need any other header changes.) |
||||
|
||||
Tested with build-many-glibcs.py. |
||||
|
||||
(cherry picked from commit 4b39e3498324d1aea802fea8d4b8764f5ddb4fd1) |
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/tst-mman-consts.py b/sysdeps/unix/sysv/linux/tst-mman-consts.py |
||||
index ee5b13ee1232fdf5..810433c238f31c25 100644 |
||||
--- a/sysdeps/unix/sysv/linux/tst-mman-consts.py |
||||
+++ b/sysdeps/unix/sysv/linux/tst-mman-consts.py |
||||
@@ -33,7 +33,7 @@ def main(): |
||||
help='C compiler (including options) to use') |
||||
args = parser.parse_args() |
||||
linux_version_headers = glibcsyscalls.linux_kernel_version(args.cc) |
||||
- linux_version_glibc = (5, 13) |
||||
+ linux_version_glibc = (5, 14) |
||||
sys.exit(glibcextract.compare_macro_consts( |
||||
'#define _GNU_SOURCE 1\n' |
||||
'#include <sys/mman.h>\n', |
@ -0,0 +1,33 @@
@@ -0,0 +1,33 @@
|
||||
commit 3a48da47a91ccc6f5de260574809e7a44551b876 |
||||
Author: Siddhesh Poyarekar <siddhesh@sourceware.org> |
||||
Date: Tue Aug 3 21:10:20 2021 +0530 |
||||
|
||||
gconv_parseconfdir: Fix memory leak |
||||
|
||||
The allocated `conf` would leak if we have to skip over the file due |
||||
to the underlying filesystem not supporting dt_type. |
||||
|
||||
Reviewed-by: Arjun Shankar <arjun@redhat.com> |
||||
(cherry picked from commit 5f9b78fe35d08739b6da1e5b356786d41116c108) |
||||
|
||||
diff --git a/iconv/gconv_parseconfdir.h b/iconv/gconv_parseconfdir.h |
||||
index a4153e54c6d43797..2f062689ecc72749 100644 |
||||
--- a/iconv/gconv_parseconfdir.h |
||||
+++ b/iconv/gconv_parseconfdir.h |
||||
@@ -153,12 +153,11 @@ gconv_parseconfdir (const char *dir, size_t dir_len) |
||||
struct stat64 st; |
||||
if (asprintf (&conf, "%s/%s", buf, ent->d_name) < 0) |
||||
continue; |
||||
- if (ent->d_type == DT_UNKNOWN |
||||
- && (lstat64 (conf, &st) == -1 |
||||
- || !S_ISREG (st.st_mode))) |
||||
- continue; |
||||
|
||||
- found |= read_conf_file (conf, dir, dir_len); |
||||
+ if (ent->d_type != DT_UNKNOWN |
||||
+ || (lstat64 (conf, &st) != -1 && S_ISREG (st.st_mode))) |
||||
+ found |= read_conf_file (conf, dir, dir_len); |
||||
+ |
||||
free (conf); |
||||
} |
||||
} |
@ -0,0 +1,29 @@
@@ -0,0 +1,29 @@
|
||||
commit 4ed990e5b97a61f29f929bdeb36c5b2abb547a64 |
||||
Author: Joseph Myers <joseph@codesourcery.com> |
||||
Date: Tue Sep 14 14:19:24 2021 +0000 |
||||
|
||||
Add MADV_POPULATE_READ and MADV_POPULATE_WRITE from Linux 5.14 to bits/mman-linux.h |
||||
|
||||
Linux 5.14 adds constants MADV_POPULATE_READ and MADV_POPULATE_WRITE |
||||
(with the same values on all architectures). Add these to glibc's |
||||
bits/mman-linux.h. |
||||
|
||||
Tested for x86_64. |
||||
|
||||
(cherry picked from commit 3561106278cddd2f007bd27fd4c3e90caaf14b43) |
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/bits/mman-linux.h b/sysdeps/unix/sysv/linux/bits/mman-linux.h |
||||
index 3b1ae418e073c122..31451c28d93f9f72 100644 |
||||
--- a/sysdeps/unix/sysv/linux/bits/mman-linux.h |
||||
+++ b/sysdeps/unix/sysv/linux/bits/mman-linux.h |
||||
@@ -89,6 +89,10 @@ |
||||
# define MADV_KEEPONFORK 19 /* Undo MADV_WIPEONFORK. */ |
||||
# define MADV_COLD 20 /* Deactivate these pages. */ |
||||
# define MADV_PAGEOUT 21 /* Reclaim these pages. */ |
||||
+# define MADV_POPULATE_READ 22 /* Populate (prefault) page tables |
||||
+ readable. */ |
||||
+# define MADV_POPULATE_WRITE 23 /* Populate (prefault) page tables |
||||
+ writable. */ |
||||
# define MADV_HWPOISON 100 /* Poison a page for testing. */ |
||||
#endif |
||||
|
@ -0,0 +1,44 @@
@@ -0,0 +1,44 @@
|
||||
commit 433ec4f14a5753c7689c83c20c9972915c53c204 |
||||
Author: Aurelien Jarno <aurelien@aurel32.net> |
||||
Date: Fri Sep 10 19:39:35 2021 +0200 |
||||
|
||||
posix: Fix attribute access mode on getcwd [BZ #27476] |
||||
|
||||
There is a GNU extension that allows to call getcwd(NULL, >0). It is |
||||
described in the documentation, but also directly in the unistd.h |
||||
header, just above the declaration. |
||||
|
||||
Therefore the attribute access mode added in commit 06febd8c6705 |
||||
is not correct. Drop it. |
||||
|
||||
diff --git a/posix/bits/unistd.h b/posix/bits/unistd.h |
||||
index f0831386c7ddb574..622adeb2b28ed298 100644 |
||||
--- a/posix/bits/unistd.h |
||||
+++ b/posix/bits/unistd.h |
||||
@@ -199,10 +199,9 @@ __NTH (readlinkat (int __fd, const char *__restrict __path, |
||||
#endif |
||||
|
||||
extern char *__getcwd_chk (char *__buf, size_t __size, size_t __buflen) |
||||
- __THROW __wur __attr_access ((__write_only__, 1, 2)); |
||||
+ __THROW __wur; |
||||
extern char *__REDIRECT_NTH (__getcwd_alias, |
||||
- (char *__buf, size_t __size), getcwd) |
||||
- __wur __attr_access ((__write_only__, 1, 2)); |
||||
+ (char *__buf, size_t __size), getcwd) __wur; |
||||
extern char *__REDIRECT_NTH (__getcwd_chk_warn, |
||||
(char *__buf, size_t __size, size_t __buflen), |
||||
__getcwd_chk) |
||||
diff --git a/posix/unistd.h b/posix/unistd.h |
||||
index 3dca65732fdde52f..8224c5fbc956306f 100644 |
||||
--- a/posix/unistd.h |
||||
+++ b/posix/unistd.h |
||||
@@ -528,8 +528,7 @@ extern int fchdir (int __fd) __THROW __wur; |
||||
an array is allocated with `malloc'; the array is SIZE |
||||
bytes long, unless SIZE == 0, in which case it is as |
||||
big as necessary. */ |
||||
-extern char *getcwd (char *__buf, size_t __size) __THROW __wur |
||||
- __attr_access ((__write_only__, 1, 2)); |
||||
+extern char *getcwd (char *__buf, size_t __size) __THROW __wur; |
||||
|
||||
#ifdef __USE_GNU |
||||
/* Return a malloc'd string containing the current directory name. |
@ -0,0 +1,137 @@
@@ -0,0 +1,137 @@
|
||||
commit 73c7f5a87971de2797f261e1a447f68dce09284b |
||||
Author: Florian Weimer <fweimer@redhat.com> |
||||
Date: Mon Sep 20 14:56:08 2021 +0200 |
||||
|
||||
nptl: pthread_kill needs to return ESRCH for old programs (bug 19193) |
||||
|
||||
The fix for bug 19193 breaks some old applications which appear |
||||
to use pthread_kill to probe if a thread is still running, something |
||||
that is not supported by POSIX. |
||||
|
||||
(cherry picked from commit 95dba35bf05e4a5d69dfae5e9c9d4df3646a7f93) |
||||
|
||||
diff --git a/nptl/pthread_kill.c b/nptl/pthread_kill.c |
||||
index fb7862eff787a94f..a44dc8f2d9baa925 100644 |
||||
--- a/nptl/pthread_kill.c |
||||
+++ b/nptl/pthread_kill.c |
||||
@@ -21,8 +21,11 @@ |
||||
#include <pthreadP.h> |
||||
#include <shlib-compat.h> |
||||
|
||||
-int |
||||
-__pthread_kill_internal (pthread_t threadid, int signo) |
||||
+/* Sends SIGNO to THREADID. If the thread is about to exit or has |
||||
+ already exited on the kernel side, return NO_TID. Otherwise return |
||||
+ 0 or an error code. */ |
||||
+static int |
||||
+__pthread_kill_implementation (pthread_t threadid, int signo, int no_tid) |
||||
{ |
||||
struct pthread *pd = (struct pthread *) threadid; |
||||
if (pd == THREAD_SELF) |
||||
@@ -52,11 +55,8 @@ __pthread_kill_internal (pthread_t threadid, int signo) |
||||
signal is either not observable (the target thread has already |
||||
blocked signals at this point), or it will fail, or it might be |
||||
delivered to a new, unrelated thread that has reused the TID. |
||||
- So do not actually send the signal. Do not report an error |
||||
- because the threadid argument is still valid (the thread ID |
||||
- lifetime has not ended), and ESRCH (for example) would be |
||||
- misleading. */ |
||||
- ret = 0; |
||||
+ So do not actually send the signal. */ |
||||
+ ret = no_tid; |
||||
else |
||||
{ |
||||
/* Using tgkill is a safety measure. pd->exit_lock ensures that |
||||
@@ -71,6 +71,15 @@ __pthread_kill_internal (pthread_t threadid, int signo) |
||||
return ret; |
||||
} |
||||
|
||||
+int |
||||
+__pthread_kill_internal (pthread_t threadid, int signo) |
||||
+{ |
||||
+ /* Do not report an error in the no-tid case because the threadid |
||||
+ argument is still valid (the thread ID lifetime has not ended), |
||||
+ and ESRCH (for example) would be misleading. */ |
||||
+ return __pthread_kill_implementation (threadid, signo, 0); |
||||
+} |
||||
+ |
||||
int |
||||
__pthread_kill (pthread_t threadid, int signo) |
||||
{ |
||||
@@ -81,6 +90,7 @@ __pthread_kill (pthread_t threadid, int signo) |
||||
|
||||
return __pthread_kill_internal (threadid, signo); |
||||
} |
||||
+ |
||||
/* Some architectures (for instance arm) might pull raise through libgcc, so |
||||
avoid the symbol version if it ends up being used on ld.so. */ |
||||
#if !IS_IN(rtld) |
||||
@@ -88,6 +98,17 @@ libc_hidden_def (__pthread_kill) |
||||
versioned_symbol (libc, __pthread_kill, pthread_kill, GLIBC_2_34); |
||||
|
||||
# if OTHER_SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_34) |
||||
-compat_symbol (libc, __pthread_kill, pthread_kill, GLIBC_2_0); |
||||
+/* Variant which returns ESRCH in the no-TID case, for backwards |
||||
+ compatibility. */ |
||||
+int |
||||
+attribute_compat_text_section |
||||
+__pthread_kill_esrch (pthread_t threadid, int signo) |
||||
+{ |
||||
+ if (__is_internal_signal (signo)) |
||||
+ return EINVAL; |
||||
+ |
||||
+ return __pthread_kill_implementation (threadid, signo, ESRCH); |
||||
+} |
||||
+compat_symbol (libc, __pthread_kill_esrch, pthread_kill, GLIBC_2_0); |
||||
# endif |
||||
#endif |
||||
diff --git a/sysdeps/pthread/tst-pthread_kill-exited.c b/sysdeps/pthread/tst-pthread_kill-exited.c |
||||
index 7575fb6d58cae99c..a2fddad526666c8c 100644 |
||||
--- a/sysdeps/pthread/tst-pthread_kill-exited.c |
||||
+++ b/sysdeps/pthread/tst-pthread_kill-exited.c |
||||
@@ -16,11 +16,15 @@ |
||||
License along with the GNU C Library; if not, see |
||||
<https://www.gnu.org/licenses/>. */ |
||||
|
||||
-/* This test verifies that pthread_kill returns 0 (and not ESRCH) for |
||||
- a thread that has exited on the kernel side. */ |
||||
+/* This test verifies that the default pthread_kill returns 0 (and not |
||||
+ ESRCH) for a thread that has exited on the kernel side. */ |
||||
|
||||
+#include <errno.h> |
||||
+#include <pthread.h> |
||||
+#include <shlib-compat.h> |
||||
#include <signal.h> |
||||
#include <stddef.h> |
||||
+#include <support/check.h> |
||||
#include <support/support.h> |
||||
#include <support/xthread.h> |
||||
|
||||
@@ -30,6 +34,12 @@ noop_thread (void *closure) |
||||
return NULL; |
||||
} |
||||
|
||||
+#if TEST_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_34) && PTHREAD_IN_LIBC |
||||
+extern __typeof (pthread_kill) compat_pthread_kill; |
||||
+compat_symbol_reference (libpthread, compat_pthread_kill, pthread_kill, |
||||
+ GLIBC_2_0); |
||||
+#endif |
||||
+ |
||||
static int |
||||
do_test (void) |
||||
{ |
||||
@@ -37,7 +47,14 @@ do_test (void) |
||||
|
||||
support_wait_for_thread_exit (); |
||||
|
||||
+ /* NB: Always uses the default symbol due to separate compilation. */ |
||||
xpthread_kill (thr, SIGUSR1); |
||||
+ |
||||
+#if TEST_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_34) && PTHREAD_IN_LIBC |
||||
+ /* Old binaries need the non-conforming ESRCH error code. */ |
||||
+ TEST_COMPARE (compat_pthread_kill (thr, SIGUSR1), ESRCH); |
||||
+#endif |
||||
+ |
||||
xpthread_join (thr); |
||||
|
||||
return 0; |
@ -0,0 +1,32 @@
@@ -0,0 +1,32 @@
|
||||
commit 8b8a1d0b7375c547ae905917a03743ed6759c5bc |
||||
Author: Florian Weimer <fweimer@redhat.com> |
||||
Date: Tue Sep 21 07:12:56 2021 +0200 |
||||
|
||||
nptl: Fix type of pthread_mutexattr_getrobust_np, pthread_mutexattr_setrobust_np (bug 28036) |
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com> |
||||
Tested-by: Carlos O'Donell <carlos@redhat.com> |
||||
(cherry picked from commit f3e664563361dc17530113b3205998d1f19dc4d9) |
||||
|
||||
diff --git a/sysdeps/nptl/pthread.h b/sysdeps/nptl/pthread.h |
||||
index f1b7f2bdc6062c3e..43146e91c9d9579b 100644 |
||||
--- a/sysdeps/nptl/pthread.h |
||||
+++ b/sysdeps/nptl/pthread.h |
||||
@@ -933,7 +933,7 @@ extern int pthread_mutexattr_getrobust (const pthread_mutexattr_t *__attr, |
||||
# ifdef __USE_GNU |
||||
# ifdef __REDIRECT_NTH |
||||
extern int __REDIRECT_NTH (pthread_mutexattr_getrobust_np, |
||||
- (pthread_mutex_t *, int *), |
||||
+ (pthread_mutexattr_t *, int *), |
||||
pthread_mutexattr_getrobust) __nonnull ((1)) |
||||
__attribute_deprecated_msg__ ("\ |
||||
pthread_mutexattr_getrobust_np is deprecated, use pthread_mutexattr_getrobust"); |
||||
@@ -949,7 +949,7 @@ extern int pthread_mutexattr_setrobust (pthread_mutexattr_t *__attr, |
||||
# ifdef __USE_GNU |
||||
# ifdef __REDIRECT_NTH |
||||
extern int __REDIRECT_NTH (pthread_mutexattr_setrobust_np, |
||||
- (pthread_mutex_t *, int), |
||||
+ (pthread_mutexattr_t *, int), |
||||
pthread_mutexattr_setrobust) __nonnull ((1)) |
||||
__attribute_deprecated_msg__ ("\ |
||||
pthread_mutexattr_setrobust_np is deprecated, use pthread_mutexattr_setrobust"); |
@ -0,0 +1,355 @@
@@ -0,0 +1,355 @@
|
||||
commit 5ad589d63bc2d9b1fc3d9f32144acaebb85e0803 |
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org> |
||||
Date: Tue Aug 24 16:12:24 2021 -0300 |
||||
|
||||
support: Add support_open_dev_null_range |
||||
|
||||
It returns a range of file descriptor referring to the '/dev/null' |
||||
pathname. The function takes care of restarting the open range |
||||
if a file descriptor is found within the specified range and |
||||
also increases RLIMIT_NOFILE if required. |
||||
|
||||
Checked on x86_64-linux-gnu. |
||||
|
||||
(cherry picked from commit e814f4b04ee413a7bb3dfa43e74c8fb4abf58359) |
||||
|
||||
diff --git a/support/Makefile b/support/Makefile |
||||
index ef2b1a980a407f8f..2a0731796fdb3f2d 100644 |
||||
--- a/support/Makefile |
||||
+++ b/support/Makefile |
||||
@@ -66,6 +66,7 @@ libsupport-routines = \ |
||||
support_path_support_time64 \ |
||||
support_process_state \ |
||||
support_ptrace \ |
||||
+ support-open-dev-null-range \ |
||||
support_openpty \ |
||||
support_paths \ |
||||
support_quote_blob \ |
||||
@@ -265,6 +266,7 @@ tests = \ |
||||
tst-support_capture_subprocess \ |
||||
tst-support_descriptors \ |
||||
tst-support_format_dns_packet \ |
||||
+ tst-support-open-dev-null-range \ |
||||
tst-support-process_state \ |
||||
tst-support_quote_blob \ |
||||
tst-support_quote_string \ |
||||
diff --git a/support/support-open-dev-null-range.c b/support/support-open-dev-null-range.c |
||||
new file mode 100644 |
||||
index 0000000000000000..80d9dba50402ce12 |
||||
--- /dev/null |
||||
+++ b/support/support-open-dev-null-range.c |
||||
@@ -0,0 +1,134 @@ |
||||
+/* Return a range of open file descriptors. |
||||
+ 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> |
||||
+#include <fcntl.h> |
||||
+#include <support/support.h> |
||||
+#include <support/check.h> |
||||
+#include <support/xunistd.h> |
||||
+#include <stdlib.h> |
||||
+#include <sys/resource.h> |
||||
+ |
||||
+static void |
||||
+increase_nofile (void) |
||||
+{ |
||||
+ struct rlimit rl; |
||||
+ if (getrlimit (RLIMIT_NOFILE, &rl) == -1) |
||||
+ FAIL_EXIT1 ("getrlimit (RLIMIT_NOFILE): %m"); |
||||
+ |
||||
+ rl.rlim_cur += 128; |
||||
+ |
||||
+ if (setrlimit (RLIMIT_NOFILE, &rl) == 1) |
||||
+ FAIL_EXIT1 ("setrlimit (RLIMIT_NOFILE): %m"); |
||||
+} |
||||
+ |
||||
+static int |
||||
+open_dev_null (int flags, mode_t mode) |
||||
+{ |
||||
+ int fd = open64 ("/dev/null", flags, mode); |
||||
+ if (fd > 0) |
||||
+ return fd; |
||||
+ |
||||
+ if (fd < 0 && errno != EMFILE) |
||||
+ FAIL_EXIT1 ("open64 (\"/dev/null\", 0x%x, 0%o): %m", flags, mode); |
||||
+ |
||||
+ increase_nofile (); |
||||
+ |
||||
+ return xopen ("/dev/null", flags, mode); |
||||
+} |
||||
+ |
||||
+struct range |
||||
+{ |
||||
+ int lowfd; |
||||
+ size_t len; |
||||
+}; |
||||
+ |
||||
+struct range_list |
||||
+{ |
||||
+ size_t total; |
||||
+ size_t used; |
||||
+ struct range *ranges; |
||||
+}; |
||||
+ |
||||
+static void |
||||
+range_init (struct range_list *r) |
||||
+{ |
||||
+ r->total = 8; |
||||
+ r->used = 0; |
||||
+ r->ranges = xmalloc (r->total * sizeof (struct range)); |
||||
+} |
||||
+ |
||||
+static void |
||||
+range_add (struct range_list *r, int lowfd, size_t len) |
||||
+{ |
||||
+ if (r->used == r->total) |
||||
+ { |
||||
+ r->total *= 2; |
||||
+ r->ranges = xrealloc (r->ranges, r->total * sizeof (struct range)); |
||||
+ } |
||||
+ r->ranges[r->used].lowfd = lowfd; |
||||
+ r->ranges[r->used].len = len; |
||||
+ r->used++; |
||||
+} |
||||
+ |
||||
+static void |
||||
+range_close (struct range_list *r) |
||||
+{ |
||||
+ for (size_t i = 0; i < r->used; i++) |
||||
+ { |
||||
+ int minfd = r->ranges[i].lowfd; |
||||
+ int maxfd = r->ranges[i].lowfd + r->ranges[i].len; |
||||
+ for (int fd = minfd; fd < maxfd; fd++) |
||||
+ xclose (fd); |
||||
+ } |
||||
+ free (r->ranges); |
||||
+} |
||||
+ |
||||
+int |
||||
+support_open_dev_null_range (int num, int flags, mode_t mode) |
||||
+{ |
||||
+ /* We keep track of the ranges that hit an already opened descriptor, so |
||||
+ we close them after we get a working range. */ |
||||
+ struct range_list rl; |
||||
+ range_init (&rl); |
||||
+ |
||||
+ int lowfd = open_dev_null (flags, mode); |
||||
+ int prevfd = lowfd; |
||||
+ while (true) |
||||
+ { |
||||
+ int i = 1; |
||||
+ for (; i < num; i++) |
||||
+ { |
||||
+ int fd = open_dev_null (flags, mode); |
||||
+ if (fd != lowfd + i) |
||||
+ { |
||||
+ range_add (&rl, lowfd, prevfd - lowfd + 1); |
||||
+ |
||||
+ prevfd = lowfd = fd; |
||||
+ break; |
||||
+ } |
||||
+ prevfd = fd; |
||||
+ } |
||||
+ if (i == num) |
||||
+ break; |
||||
+ } |
||||
+ |
||||
+ range_close (&rl); |
||||
+ |
||||
+ return lowfd; |
||||
+} |
||||
diff --git a/support/support.h b/support/support.h |
||||
index a5978b939af2fb41..c219e0d9d1aef046 100644 |
||||
--- a/support/support.h |
||||
+++ b/support/support.h |
||||
@@ -197,6 +197,14 @@ struct support_stack support_stack_alloc (size_t size); |
||||
/* Deallocate the STACK. */ |
||||
void support_stack_free (struct support_stack *stack); |
||||
|
||||
+ |
||||
+/* Create a range of NUM opened '/dev/null' file descriptors using FLAGS and |
||||
+ MODE. The function takes care of restarting the open range if a file |
||||
+ descriptor is found within the specified range and also increases |
||||
+ RLIMIT_NOFILE if required. |
||||
+ The returned value is the lowest file descriptor number. */ |
||||
+int support_open_dev_null_range (int num, int flags, mode_t mode); |
||||
+ |
||||
__END_DECLS |
||||
|
||||
#endif /* SUPPORT_H */ |
||||
diff --git a/support/tst-support-open-dev-null-range.c b/support/tst-support-open-dev-null-range.c |
||||
new file mode 100644 |
||||
index 0000000000000000..8e29def1ce780629 |
||||
--- /dev/null |
||||
+++ b/support/tst-support-open-dev-null-range.c |
||||
@@ -0,0 +1,155 @@ |
||||
+/* Tests for support_open_dev_null_range. |
||||
+ 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> |
||||
+#include <dirent.h> |
||||
+#include <fcntl.h> |
||||
+#include <limits.h> |
||||
+#include <support/check.h> |
||||
+#include <support/support.h> |
||||
+#include <support/xunistd.h> |
||||
+#include <sys/resource.h> |
||||
+#include <stdlib.h> |
||||
+ |
||||
+#ifndef PATH_MAX |
||||
+# define PATH_MAX 1024 |
||||
+#endif |
||||
+ |
||||
+#include <stdio.h> |
||||
+ |
||||
+static void |
||||
+check_path (int fd) |
||||
+{ |
||||
+ char *proc_fd_path = xasprintf ("/proc/self/fd/%d", fd); |
||||
+ char file_path[PATH_MAX]; |
||||
+ ssize_t file_path_length |
||||
+ = readlink (proc_fd_path, file_path, sizeof (file_path)); |
||||
+ free (proc_fd_path); |
||||
+ if (file_path_length < 0) |
||||
+ FAIL_EXIT1 ("readlink (%s, %p, %zu)", proc_fd_path, file_path, |
||||
+ sizeof (file_path)); |
||||
+ file_path[file_path_length] = '\0'; |
||||
+ TEST_COMPARE_STRING (file_path, "/dev/null"); |
||||
+} |
||||
+ |
||||
+static int |
||||
+number_of_opened_files (void) |
||||
+{ |
||||
+ DIR *fds = opendir ("/proc/self/fd"); |
||||
+ if (fds == NULL) |
||||
+ FAIL_EXIT1 ("opendir (\"/proc/self/fd\"): %m"); |
||||
+ |
||||
+ int r = 0; |
||||
+ while (true) |
||||
+ { |
||||
+ errno = 0; |
||||
+ struct dirent64 *e = readdir64 (fds); |
||||
+ if (e == NULL) |
||||
+ { |
||||
+ if (errno != 0) |
||||
+ FAIL_EXIT1 ("readdir: %m"); |
||||
+ break; |
||||
+ } |
||||
+ |
||||
+ if (e->d_name[0] == '.') |
||||
+ continue; |
||||
+ |
||||
+ char *endptr; |
||||
+ long int fd = strtol (e->d_name, &endptr, 10); |
||||
+ if (*endptr != '\0' || fd < 0 || fd > INT_MAX) |
||||
+ FAIL_EXIT1 ("readdir: invalid file descriptor name: /proc/self/fd/%s", |
||||
+ e->d_name); |
||||
+ |
||||
+ /* Skip the descriptor which is used to enumerate the |
||||
+ descriptors. */ |
||||
+ if (fd == dirfd (fds)) |
||||
+ continue; |
||||
+ |
||||
+ r = r + 1; |
||||
+ } |
||||
+ |
||||
+ closedir (fds); |
||||
+ |
||||
+ return r; |
||||
+} |
||||
+ |
||||
+static int |
||||
+do_test (void) |
||||
+{ |
||||
+ const int nfds1 = 8; |
||||
+ int lowfd = support_open_dev_null_range (nfds1, O_RDONLY, 0600); |
||||
+ for (int i = 0; i < nfds1; i++) |
||||
+ { |
||||
+ TEST_VERIFY (fcntl (lowfd + i, F_GETFL) > -1); |
||||
+ check_path (lowfd + i); |
||||
+ } |
||||
+ |
||||
+ /* create some gaps. */ |
||||
+ xclose (lowfd + 1); |
||||
+ xclose (lowfd + 5); |
||||
+ xclose (lowfd + 6); |
||||
+ |
||||
+ const int nfds2 = 16; |
||||
+ int lowfd2 = support_open_dev_null_range (nfds2, O_RDONLY, 0600); |
||||
+ for (int i = 0; i < nfds2; i++) |
||||
+ { |
||||
+ TEST_VERIFY (fcntl (lowfd2 + i, F_GETFL) > -1); |
||||
+ check_path (lowfd2 + i); |
||||
+ } |
||||
+ |
||||
+ /* Decrease the maximum number of files. */ |
||||
+ { |
||||
+ struct rlimit rl; |
||||
+ if (getrlimit (RLIMIT_NOFILE, &rl) == -1) |
||||
+ FAIL_EXIT1 ("getrlimit (RLIMIT_NOFILE): %m"); |
||||
+ |
||||
+ rl.rlim_cur = number_of_opened_files (); |
||||
+ |
||||
+ if (setrlimit (RLIMIT_NOFILE, &rl) == 1) |
||||
+ FAIL_EXIT1 ("setrlimit (RLIMIT_NOFILE): %m"); |
||||
+ } |
||||
+ |
||||
+ const int nfds3 = 16; |
||||
+ int lowfd3 = support_open_dev_null_range (nfds3, O_RDONLY, 0600); |
||||
+ for (int i = 0; i < nfds3; i++) |
||||
+ { |
||||
+ TEST_VERIFY (fcntl (lowfd3 + i, F_GETFL) > -1); |
||||
+ check_path (lowfd3 + i); |
||||
+ } |
||||
+ |
||||
+ /* create a lot of gaps to trigger the range extension. */ |
||||
+ xclose (lowfd3 + 1); |
||||
+ xclose (lowfd3 + 3); |
||||
+ xclose (lowfd3 + 5); |
||||
+ xclose (lowfd3 + 7); |
||||
+ xclose (lowfd3 + 9); |
||||
+ xclose (lowfd3 + 11); |
||||
+ xclose (lowfd3 + 13); |
||||
+ |
||||
+ const int nfds4 = 16; |
||||
+ int lowfd4 = support_open_dev_null_range (nfds4, O_RDONLY, 0600); |
||||
+ for (int i = 0; i < nfds4; i++) |
||||
+ { |
||||
+ TEST_VERIFY (fcntl (lowfd4 + i, F_GETFL) > -1); |
||||
+ check_path (lowfd4 + i); |
||||
+ } |
||||
+ |
||||
+ return 0; |
||||
+} |
||||
+ |
||||
+#include <support/test-driver.c> |
@ -0,0 +1,204 @@
@@ -0,0 +1,204 @@
|
||||
commit 772e33411bc730f832f415f93eb3e7c67e4d5488 |
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org> |
||||
Date: Tue Aug 24 16:15:50 2021 -0300 |
||||
|
||||
Use support_open_dev_null_range io/tst-closefrom, misc/tst-close_range, and posix/tst-spawn5 (BZ #28260) |
||||
|
||||
It ensures a continuous range of file descriptor and avoid hitting |
||||
the RLIMIT_NOFILE. |
||||
|
||||
Checked on x86_64-linux-gnu. |
||||
|
||||
(cherry picked from commit 6b20880b22d1d0fce7e9f506baa6fe2d5c7fcfdc) |
||||
|
||||
diff --git a/io/tst-closefrom.c b/io/tst-closefrom.c |
||||
index d4c187073c7280e9..395ec0d894101a47 100644 |
||||
--- a/io/tst-closefrom.c |
||||
+++ b/io/tst-closefrom.c |
||||
@@ -24,31 +24,22 @@ |
||||
#include <support/check.h> |
||||
#include <support/descriptors.h> |
||||
#include <support/xunistd.h> |
||||
+#include <support/support.h> |
||||
|
||||
#include <array_length.h> |
||||
|
||||
#define NFDS 100 |
||||
|
||||
-static int |
||||
-open_multiple_temp_files (void) |
||||
-{ |
||||
- /* Check if the temporary file descriptor has no no gaps. */ |
||||
- int lowfd = xopen ("/dev/null", O_RDONLY, 0600); |
||||
- for (int i = 1; i <= NFDS; i++) |
||||
- TEST_COMPARE (xopen ("/dev/null", O_RDONLY, 0600), lowfd + i); |
||||
- return lowfd; |
||||
-} |
||||
- |
||||
static int |
||||
closefrom_test (void) |
||||
{ |
||||
struct support_descriptors *descrs = support_descriptors_list (); |
||||
|
||||
- int lowfd = open_multiple_temp_files (); |
||||
+ int lowfd = support_open_dev_null_range (NFDS, O_RDONLY, 0600); |
||||
|
||||
- const int maximum_fd = lowfd + NFDS; |
||||
+ const int maximum_fd = lowfd + NFDS - 1; |
||||
const int half_fd = lowfd + NFDS / 2; |
||||
- const int gap = maximum_fd / 4; |
||||
+ const int gap = lowfd + NFDS / 4; |
||||
|
||||
/* Close half of the descriptors and check result. */ |
||||
closefrom (half_fd); |
||||
@@ -58,7 +49,7 @@ closefrom_test (void) |
||||
TEST_COMPARE (fcntl (i, F_GETFL), -1); |
||||
TEST_COMPARE (errno, EBADF); |
||||
} |
||||
- for (int i = 0; i < half_fd; i++) |
||||
+ for (int i = lowfd; i < half_fd; i++) |
||||
TEST_VERIFY (fcntl (i, F_GETFL) > -1); |
||||
|
||||
/* Create some gaps, close up to a threshold, and check result. */ |
||||
@@ -74,7 +65,7 @@ closefrom_test (void) |
||||
TEST_COMPARE (fcntl (i, F_GETFL), -1); |
||||
TEST_COMPARE (errno, EBADF); |
||||
} |
||||
- for (int i = 0; i < gap; i++) |
||||
+ for (int i = lowfd; i < gap; i++) |
||||
TEST_VERIFY (fcntl (i, F_GETFL) > -1); |
||||
|
||||
/* Close the remmaining but the last one. */ |
||||
diff --git a/posix/tst-spawn5.c b/posix/tst-spawn5.c |
||||
index ac6673800464ce72..a95199af6b3b7c9a 100644 |
||||
--- a/posix/tst-spawn5.c |
||||
+++ b/posix/tst-spawn5.c |
||||
@@ -47,17 +47,6 @@ static int initial_argv_count; |
||||
|
||||
#define NFDS 100 |
||||
|
||||
-static int |
||||
-open_multiple_temp_files (void) |
||||
-{ |
||||
- /* Check if the temporary file descriptor has no no gaps. */ |
||||
- int lowfd = xopen ("/dev/null", O_RDONLY, 0600); |
||||
- for (int i = 1; i <= NFDS; i++) |
||||
- TEST_COMPARE (xopen ("/dev/null", O_RDONLY, 0600), |
||||
- lowfd + i); |
||||
- return lowfd; |
||||
-} |
||||
- |
||||
static int |
||||
parse_fd (const char *str) |
||||
{ |
||||
@@ -185,7 +174,7 @@ spawn_closefrom_test (posix_spawn_file_actions_t *fa, int lowfd, int highfd, |
||||
static void |
||||
do_test_closefrom (void) |
||||
{ |
||||
- int lowfd = open_multiple_temp_files (); |
||||
+ int lowfd = support_open_dev_null_range (NFDS, O_RDONLY, 0600); |
||||
const int half_fd = lowfd + NFDS / 2; |
||||
|
||||
/* Close half of the descriptors and check result. */ |
||||
diff --git a/sysdeps/unix/sysv/linux/tst-close_range.c b/sysdeps/unix/sysv/linux/tst-close_range.c |
||||
index dccb6189c53fcb90..f5069d1b8a067241 100644 |
||||
--- a/sysdeps/unix/sysv/linux/tst-close_range.c |
||||
+++ b/sysdeps/unix/sysv/linux/tst-close_range.c |
||||
@@ -36,23 +36,12 @@ |
||||
|
||||
#define NFDS 100 |
||||
|
||||
-static int |
||||
-open_multiple_temp_files (void) |
||||
-{ |
||||
- /* Check if the temporary file descriptor has no no gaps. */ |
||||
- int lowfd = xopen ("/dev/null", O_RDONLY, 0600); |
||||
- for (int i = 1; i <= NFDS; i++) |
||||
- TEST_COMPARE (xopen ("/dev/null", O_RDONLY, 0600), |
||||
- lowfd + i); |
||||
- return lowfd; |
||||
-} |
||||
- |
||||
static void |
||||
close_range_test_max_upper_limit (void) |
||||
{ |
||||
struct support_descriptors *descrs = support_descriptors_list (); |
||||
|
||||
- int lowfd = open_multiple_temp_files (); |
||||
+ int lowfd = support_open_dev_null_range (NFDS, O_RDONLY, 0600); |
||||
|
||||
{ |
||||
int r = close_range (lowfd, ~0U, 0); |
||||
@@ -68,7 +57,7 @@ close_range_test_max_upper_limit (void) |
||||
static void |
||||
close_range_test_common (int lowfd, unsigned int flags) |
||||
{ |
||||
- const int maximum_fd = lowfd + NFDS; |
||||
+ const int maximum_fd = lowfd + NFDS - 1; |
||||
const int half_fd = lowfd + NFDS / 2; |
||||
const int gap_1 = maximum_fd - 8; |
||||
|
||||
@@ -121,7 +110,7 @@ close_range_test (void) |
||||
struct support_descriptors *descrs = support_descriptors_list (); |
||||
|
||||
/* Check if the temporary file descriptor has no no gaps. */ |
||||
- int lowfd = open_multiple_temp_files (); |
||||
+ int lowfd = support_open_dev_null_range (NFDS, O_RDONLY, 0600); |
||||
|
||||
close_range_test_common (lowfd, 0); |
||||
|
||||
@@ -146,7 +135,7 @@ close_range_test_subprocess (void) |
||||
struct support_descriptors *descrs = support_descriptors_list (); |
||||
|
||||
/* Check if the temporary file descriptor has no no gaps. */ |
||||
- int lowfd = open_multiple_temp_files (); |
||||
+ int lowfd = support_open_dev_null_range (NFDS, O_RDONLY, 0600); |
||||
|
||||
struct support_stack stack = support_stack_alloc (4096); |
||||
|
||||
@@ -184,7 +173,7 @@ close_range_unshare_test (void) |
||||
struct support_descriptors *descrs1 = support_descriptors_list (); |
||||
|
||||
/* Check if the temporary file descriptor has no no gaps. */ |
||||
- int lowfd = open_multiple_temp_files (); |
||||
+ int lowfd = support_open_dev_null_range (NFDS, O_RDONLY, 0600); |
||||
|
||||
struct support_descriptors *descrs2 = support_descriptors_list (); |
||||
|
||||
@@ -200,7 +189,7 @@ close_range_unshare_test (void) |
||||
|
||||
support_stack_free (&stack); |
||||
|
||||
- for (int i = 0; i < NFDS; i++) |
||||
+ for (int i = lowfd; i < lowfd + NFDS; i++) |
||||
TEST_VERIFY (fcntl (i, F_GETFL) > -1); |
||||
|
||||
support_descriptors_check (descrs2); |
||||
@@ -226,9 +215,9 @@ static void |
||||
close_range_cloexec_test (void) |
||||
{ |
||||
/* Check if the temporary file descriptor has no no gaps. */ |
||||
- const int lowfd = open_multiple_temp_files (); |
||||
+ int lowfd = support_open_dev_null_range (NFDS, O_RDONLY, 0600); |
||||
|
||||
- const int maximum_fd = lowfd + NFDS; |
||||
+ const int maximum_fd = lowfd + NFDS - 1; |
||||
const int half_fd = lowfd + NFDS / 2; |
||||
const int gap_1 = maximum_fd - 8; |
||||
|
||||
@@ -251,13 +240,13 @@ close_range_cloexec_test (void) |
||||
/* Create some gaps, close up to a threshold, and check result. */ |
||||
static int gap_close[] = { 57, 78, 81, 82, 84, 90 }; |
||||
for (int i = 0; i < array_length (gap_close); i++) |
||||
- xclose (gap_close[i]); |
||||
+ xclose (lowfd + gap_close[i]); |
||||
|
||||
TEST_COMPARE (close_range (half_fd + 1, gap_1, CLOSE_RANGE_CLOEXEC), 0); |
||||
for (int i = half_fd + 1; i < gap_1; i++) |
||||
{ |
||||
int flags = fcntl (i, F_GETFD); |
||||
- if (is_in_array (gap_close, array_length (gap_close), i)) |
||||
+ if (is_in_array (gap_close, array_length (gap_close), i - lowfd)) |
||||
TEST_COMPARE (flags, -1); |
||||
else |
||||
{ |
@ -0,0 +1,129 @@
@@ -0,0 +1,129 @@
|
||||
commit 33adeaa3e2b9143c38884bc5aa65ded222ed274e |
||||
Author: Florian Weimer <fweimer@redhat.com> |
||||
Date: Thu Sep 23 09:55:54 2021 +0200 |
||||
|
||||
nptl: Avoid setxid deadlock with blocked signals in thread exit [BZ #28361] |
||||
|
||||
As part of the fix for bug 12889, signals are blocked during |
||||
thread exit, so that application code cannot run on the thread that |
||||
is about to exit. This would cause problems if the application |
||||
expected signals to be delivered after the signal handler revealed |
||||
the thread to still exist, despite pthread_kill can no longer be used |
||||
to send signals to it. However, glibc internally uses the SIGSETXID |
||||
signal in a way that is incompatible with signal blocking, due to the |
||||
way the setxid handshake delays thread exit until the setxid operation |
||||
has completed. With a blocked SIGSETXID, the handshake can never |
||||
complete, causing a deadlock. |
||||
|
||||
As a band-aid, restore the previous handshake protocol by not blocking |
||||
SIGSETXID during thread exit. |
||||
|
||||
The new test sysdeps/pthread/tst-pthread-setuid-loop.c is based on |
||||
a downstream test by Martin Osvald. |
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com> |
||||
Tested-by: Carlos O'Donell <carlos@redhat.com> |
||||
(cherry picked from commit 2849e2f53311b66853cb5159b64cba2bddbfb854) |
||||
|
||||
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c |
||||
index 33b426fc682300dc..bc213f0bc4e948bd 100644 |
||||
--- a/nptl/pthread_create.c |
||||
+++ b/nptl/pthread_create.c |
||||
@@ -488,8 +488,16 @@ start_thread (void *arg) |
||||
|
||||
/* This prevents sending a signal from this thread to itself during |
||||
its final stages. This must come after the exit call above |
||||
- because atexit handlers must not run with signals blocked. */ |
||||
- __libc_signal_block_all (NULL); |
||||
+ because atexit handlers must not run with signals blocked. |
||||
+ |
||||
+ Do not block SIGSETXID. The setxid handshake below expects the |
||||
+ signal to be delivered. (SIGSETXID cannot run application code, |
||||
+ nor does it use pthread_kill.) Reuse the pd->sigmask space for |
||||
+ computing the signal mask, to save stack space. */ |
||||
+ __sigfillset (&pd->sigmask); |
||||
+ __sigdelset (&pd->sigmask, SIGSETXID); |
||||
+ INTERNAL_SYSCALL_CALL (rt_sigprocmask, SIG_BLOCK, &pd->sigmask, NULL, |
||||
+ __NSIG_BYTES); |
||||
|
||||
/* Tell __pthread_kill_internal that this thread is about to exit. |
||||
If there is a __pthread_kill_internal in progress, this delays |
||||
diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile |
||||
index 48dba717a1cdc20a..d4bd2d4e3ee6a496 100644 |
||||
--- a/sysdeps/pthread/Makefile |
||||
+++ b/sysdeps/pthread/Makefile |
||||
@@ -118,6 +118,7 @@ tests += tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \ |
||||
tst-unload \ |
||||
tst-unwind-thread \ |
||||
tst-pt-vfork1 tst-pt-vfork2 tst-vfork1x tst-vfork2x \ |
||||
+ tst-pthread-setuid-loop \ |
||||
tst-pthread_cancel-exited \ |
||||
tst-pthread_cancel-select-loop \ |
||||
tst-pthread_kill-exited \ |
||||
diff --git a/sysdeps/pthread/tst-pthread-setuid-loop.c b/sysdeps/pthread/tst-pthread-setuid-loop.c |
||||
new file mode 100644 |
||||
index 0000000000000000..fda2a49b7f0ccf81 |
||||
--- /dev/null |
||||
+++ b/sysdeps/pthread/tst-pthread-setuid-loop.c |
||||
@@ -0,0 +1,61 @@ |
||||
+/* Test that setuid, pthread_create, thread exit do not deadlock (bug 28361). |
||||
+ 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/xthread.h> |
||||
+#include <unistd.h> |
||||
+ |
||||
+/* How many threads to launch during each iteration. */ |
||||
+enum { threads = 4 }; |
||||
+ |
||||
+/* How many iterations to perform. This value seems to reproduce |
||||
+ bug 28361 in a bout one in three runs. */ |
||||
+enum { iterations = 5000 }; |
||||
+ |
||||
+/* Cache of the real user ID used by setuid_thread. */ |
||||
+static uid_t uid; |
||||
+ |
||||
+/* Start routine for the threads. */ |
||||
+static void * |
||||
+setuid_thread (void *closure) |
||||
+{ |
||||
+ TEST_COMPARE (setuid (uid), 0); |
||||
+ return NULL; |
||||
+} |
||||
+ |
||||
+static int |
||||
+do_test (void) |
||||
+{ |
||||
+ /* The setxid machinery is still invoked even if the UID is |
||||
+ unchanged. (The kernel might reset other credentials as part of |
||||
+ the system call.) */ |
||||
+ uid = getuid (); |
||||
+ |
||||
+ for (int i = 0; i < iterations; ++i) |
||||
+ { |
||||
+ pthread_t thread_ids[threads]; |
||||
+ for (int j = 0; j < threads; ++j) |
||||
+ thread_ids[j] = xpthread_create (NULL, setuid_thread, NULL); |
||||
+ for (int j = 0; j < threads; ++j) |
||||
+ xpthread_join (thread_ids[j]); |
||||
+ } |
||||
+ |
||||
+ return 0; |
||||
+} |
||||
+ |
||||
+#include <support/test-driver.c> |
@ -0,0 +1,37 @@
@@ -0,0 +1,37 @@
|
||||
commit 4bf72519987ebc2be4a2058c670379040fae90ea |
||||
Author: Florian Weimer <fweimer@redhat.com> |
||||
Date: Fri Oct 1 18:16:41 2021 +0200 |
||||
|
||||
support: Add check for TID zero in support_wait_for_thread_exit |
||||
|
||||
Some kernel versions (observed with kernel 5.14 and earlier) can list |
||||
"0" entries in /proc/self/task. This happens when a thread exits |
||||
while the task list is being constructed. Treat this entry as not |
||||
present, like the proposed kernel patch does: |
||||
|
||||
[PATCH] procfs: Do not list TID 0 in /proc/<pid>/task |
||||
<https://lore.kernel.org/all/8735pn5dx7.fsf@oldenburg.str.redhat.com/> |
||||
|
||||
Fixes commit 032d74eaf6179100048a5bf0ce942e97dc8b9a60 ("support: Add |
||||
support_wait_for_thread_exit"). |
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com> |
||||
Tested-by: Carlos O'Donell <carlos@redhat.com> |
||||
(cherry picked from commit 176c88f5214d8107d330971cbbfbbba5186a111f) |
||||
|
||||
diff --git a/support/support_wait_for_thread_exit.c b/support/support_wait_for_thread_exit.c |
||||
index 658a81381006ea62..5e3be421a78a4c78 100644 |
||||
--- a/support/support_wait_for_thread_exit.c |
||||
+++ b/support/support_wait_for_thread_exit.c |
||||
@@ -43,7 +43,10 @@ support_wait_for_thread_exit (void) |
||||
return; |
||||
} |
||||
|
||||
- if (strcmp (e->d_name, ".") == 0 || strcmp (e->d_name, "..") == 0) |
||||
+ /* In some kernels, "0" entries denote a thread that has just |
||||
+ exited. */ |
||||
+ if (strcmp (e->d_name, ".") == 0 || strcmp (e->d_name, "..") == 0 |
||||
+ || strcmp (e->d_name, "0") == 0) |
||||
continue; |
||||
|
||||
int task_tid = atoi (e->d_name); |
@ -0,0 +1,154 @@
@@ -0,0 +1,154 @@
|
||||
commit 40bade26d5bcbda3d21fb598c5063d9df62de966 |
||||
Author: Florian Weimer <fweimer@redhat.com> |
||||
Date: Fri Oct 1 18:16:41 2021 +0200 |
||||
|
||||
nptl: pthread_kill must send signals to a specific thread [BZ #28407] |
||||
|
||||
The choice between the kill vs tgkill system calls is not just about |
||||
the TID reuse race, but also about whether the signal is sent to the |
||||
whole process (and any thread in it) or to a specific thread. |
||||
|
||||
This was caught by the openposix test suite: |
||||
|
||||
LTP: openposix test suite - FAIL: SIGUSR1 is member of new thread pendingset. |
||||
<https://gitlab.com/cki-project/kernel-tests/-/issues/764> |
||||
|
||||
Fixes commit 526c3cf11ee9367344b6b15d669e4c3cb461a2be ("nptl: Fix race |
||||
between pthread_kill and thread exit (bug 12889)"). |
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com> |
||||
Tested-by: Carlos O'Donell <carlos@redhat.com> |
||||
(cherry picked from commit eae81d70574e923ce3c59078b8df857ae192efa6) |
||||
|
||||
diff --git a/nptl/pthread_kill.c b/nptl/pthread_kill.c |
||||
index a44dc8f2d9baa925..35bf1f973eaeda90 100644 |
||||
--- a/nptl/pthread_kill.c |
||||
+++ b/nptl/pthread_kill.c |
||||
@@ -40,7 +40,7 @@ __pthread_kill_implementation (pthread_t threadid, int signo, int no_tid) |
||||
below. POSIX only guarantees delivery of a single signal, |
||||
which may not be the right one.) */ |
||||
pid_t tid = INTERNAL_SYSCALL_CALL (gettid); |
||||
- int ret = INTERNAL_SYSCALL_CALL (kill, tid, signo); |
||||
+ int ret = INTERNAL_SYSCALL_CALL (tgkill, __getpid (), tid, signo); |
||||
return INTERNAL_SYSCALL_ERROR_P (ret) ? INTERNAL_SYSCALL_ERRNO (ret) : 0; |
||||
} |
||||
|
||||
@@ -59,8 +59,6 @@ __pthread_kill_implementation (pthread_t threadid, int signo, int no_tid) |
||||
ret = no_tid; |
||||
else |
||||
{ |
||||
- /* Using tgkill is a safety measure. pd->exit_lock ensures that |
||||
- the target thread cannot exit. */ |
||||
ret = INTERNAL_SYSCALL_CALL (tgkill, __getpid (), pd->tid, signo); |
||||
ret = INTERNAL_SYSCALL_ERROR_P (ret) ? INTERNAL_SYSCALL_ERRNO (ret) : 0; |
||||
} |
||||
diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile |
||||
index d4bd2d4e3ee6a496..0af9c59b425aefb1 100644 |
||||
--- a/sysdeps/pthread/Makefile |
||||
+++ b/sysdeps/pthread/Makefile |
||||
@@ -121,6 +121,7 @@ tests += tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \ |
||||
tst-pthread-setuid-loop \ |
||||
tst-pthread_cancel-exited \ |
||||
tst-pthread_cancel-select-loop \ |
||||
+ tst-pthread-raise-blocked-self \ |
||||
tst-pthread_kill-exited \ |
||||
tst-pthread_kill-exiting \ |
||||
# tests |
||||
diff --git a/sysdeps/pthread/tst-pthread-raise-blocked-self.c b/sysdeps/pthread/tst-pthread-raise-blocked-self.c |
||||
new file mode 100644 |
||||
index 0000000000000000..128e1a6071c0b15f |
||||
--- /dev/null |
||||
+++ b/sysdeps/pthread/tst-pthread-raise-blocked-self.c |
||||
@@ -0,0 +1,92 @@ |
||||
+/* Test that raise sends signal to current thread even if blocked. |
||||
+ 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 <signal.h> |
||||
+#include <support/check.h> |
||||
+#include <support/xsignal.h> |
||||
+#include <support/xthread.h> |
||||
+#include <pthread.h> |
||||
+#include <unistd.h> |
||||
+ |
||||
+/* Used to create a dummy thread ID distinct from all other thread |
||||
+ IDs. */ |
||||
+static void * |
||||
+noop (void *ignored) |
||||
+{ |
||||
+ return NULL; |
||||
+} |
||||
+ |
||||
+static volatile pthread_t signal_thread; |
||||
+ |
||||
+static void |
||||
+signal_handler (int signo) |
||||
+{ |
||||
+ signal_thread = pthread_self (); |
||||
+} |
||||
+ |
||||
+/* Used to ensure that waiting_thread has launched and can accept |
||||
+ signals. */ |
||||
+static pthread_barrier_t barrier; |
||||
+ |
||||
+static void * |
||||
+waiting_thread (void *ignored) |
||||
+{ |
||||
+ xpthread_barrier_wait (&barrier); |
||||
+ pause (); |
||||
+ return NULL; |
||||
+} |
||||
+ |
||||
+static int |
||||
+do_test (void) |
||||
+{ |
||||
+ xsignal (SIGUSR1, signal_handler); |
||||
+ xpthread_barrier_init (&barrier, NULL, 2); |
||||
+ |
||||
+ /* Distinct thread ID value to */ |
||||
+ pthread_t dummy = xpthread_create (NULL, noop, NULL); |
||||
+ signal_thread = dummy; |
||||
+ |
||||
+ pthread_t helper = xpthread_create (NULL, waiting_thread, NULL); |
||||
+ |
||||
+ /* Make sure that the thread is running. */ |
||||
+ xpthread_barrier_wait (&barrier); |
||||
+ |
||||
+ /* Block signals on this thread. */ |
||||
+ sigset_t set; |
||||
+ sigfillset (&set); |
||||
+ xpthread_sigmask (SIG_BLOCK, &set, NULL); |
||||
+ |
||||
+ /* Send the signal to this thread. It must not be delivered. */ |
||||
+ raise (SIGUSR1); |
||||
+ TEST_VERIFY (signal_thread == dummy); |
||||
+ |
||||
+ /* Wait a bit to give a chance for signal delivery (increases |
||||
+ chances of failure with bug 28407). */ |
||||
+ usleep (50 * 1000); |
||||
+ |
||||
+ /* Unblocking should cause synchronous delivery of the signal. */ |
||||
+ xpthread_sigmask (SIG_UNBLOCK, &set, NULL); |
||||
+ TEST_VERIFY (signal_thread == pthread_self ()); |
||||
+ |
||||
+ xpthread_cancel (helper); |
||||
+ xpthread_join (helper); |
||||
+ xpthread_join (dummy); |
||||
+ return 0; |
||||
+} |
||||
+ |
||||
+#include <support/test-driver.c> |
@ -0,0 +1,101 @@
@@ -0,0 +1,101 @@
|
||||
commit e870aac8974cda746157a5a3c9f452ccd70da29b |
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org> |
||||
Date: Mon Sep 6 12:22:54 2021 -0300 |
||||
|
||||
misc: Add __get_nprocs_sched |
||||
|
||||
This is an internal function meant to return the number of avaliable |
||||
processor where the process can scheduled, different than the |
||||
__get_nprocs which returns a the system available online CPU. |
||||
|
||||
The Linux implementation currently only calls __get_nprocs(), which |
||||
in tuns calls sched_getaffinity. |
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com> |
||||
(cherry picked from commit 11a02b035b464ab6813676adfd19c4a59c36d907) |
||||
|
||||
diff --git a/include/sys/sysinfo.h b/include/sys/sysinfo.h |
||||
index 7388356a19269335..c490561581733038 100644 |
||||
--- a/include/sys/sysinfo.h |
||||
+++ b/include/sys/sysinfo.h |
||||
@@ -9,10 +9,15 @@ |
||||
extern int __get_nprocs_conf (void); |
||||
libc_hidden_proto (__get_nprocs_conf) |
||||
|
||||
-/* Return number of available processors. */ |
||||
+/* Return number of available processors (not all of them will be |
||||
+ available to the caller process). */ |
||||
extern int __get_nprocs (void); |
||||
libc_hidden_proto (__get_nprocs) |
||||
|
||||
+/* Return the number of available processors which the process can |
||||
+ be scheduled. */ |
||||
+extern int __get_nprocs_sched (void) attribute_hidden; |
||||
+ |
||||
/* Return number of physical pages of memory in the system. */ |
||||
extern long int __get_phys_pages (void); |
||||
libc_hidden_proto (__get_phys_pages) |
||||
diff --git a/malloc/arena.c b/malloc/arena.c |
||||
index 667484630ed0afa5..f1f0af86489d0063 100644 |
||||
--- a/malloc/arena.c |
||||
+++ b/malloc/arena.c |
||||
@@ -879,7 +879,7 @@ arena_get2 (size_t size, mstate avoid_arena) |
||||
narenas_limit = mp_.arena_max; |
||||
else if (narenas > mp_.arena_test) |
||||
{ |
||||
- int n = __get_nprocs (); |
||||
+ int n = __get_nprocs_sched (); |
||||
|
||||
if (n >= 1) |
||||
narenas_limit = NARENAS_FROM_NCORES (n); |
||||
diff --git a/misc/getsysstats.c b/misc/getsysstats.c |
||||
index 0eedface6d2b0f75..57d93601e21265d7 100644 |
||||
--- a/misc/getsysstats.c |
||||
+++ b/misc/getsysstats.c |
||||
@@ -45,6 +45,12 @@ weak_alias (__get_nprocs, get_nprocs) |
||||
link_warning (get_nprocs, "warning: get_nprocs will always return 1") |
||||
|
||||
|
||||
+int |
||||
+__get_nprocs_sched (void) |
||||
+{ |
||||
+ return 1; |
||||
+} |
||||
+ |
||||
long int |
||||
__get_phys_pages (void) |
||||
{ |
||||
diff --git a/sysdeps/mach/getsysstats.c b/sysdeps/mach/getsysstats.c |
||||
index 1267f39da26aee38..cc8023f979bf6f74 100644 |
||||
--- a/sysdeps/mach/getsysstats.c |
||||
+++ b/sysdeps/mach/getsysstats.c |
||||
@@ -62,6 +62,12 @@ __get_nprocs (void) |
||||
libc_hidden_def (__get_nprocs) |
||||
weak_alias (__get_nprocs, get_nprocs) |
||||
|
||||
+int |
||||
+__get_nprocs_sched (void) |
||||
+{ |
||||
+ return __get_nprocs (); |
||||
+} |
||||
+ |
||||
/* Return the number of physical pages on the system. */ |
||||
long int |
||||
__get_phys_pages (void) |
||||
diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c |
||||
index 1391e360b8f8e86c..120ce1bb756b09cc 100644 |
||||
--- a/sysdeps/unix/sysv/linux/getsysstats.c |
||||
+++ b/sysdeps/unix/sysv/linux/getsysstats.c |
||||
@@ -88,6 +88,12 @@ __get_nprocs (void) |
||||
libc_hidden_def (__get_nprocs) |
||||
weak_alias (__get_nprocs, get_nprocs) |
||||
|
||||
+int |
||||
+__get_nprocs_sched (void) |
||||
+{ |
||||
+ return __get_nprocs (); |
||||
+} |
||||
+ |
||||
|
||||
/* On some architectures it is possible to distinguish between configured |
||||
and active cpus. */ |
@ -0,0 +1,32 @@
@@ -0,0 +1,32 @@
|
||||
commit a5bd2e10e0c25b80286dc36068e22a4cb4893af0 |
||||
Author: Siddhesh Poyarekar <siddhesh@sourceware.org> |
||||
Date: Tue Aug 3 21:11:03 2021 +0530 |
||||
|
||||
gaiconf_init: Avoid double-free in label and precedence lists |
||||
|
||||
labellist and precedencelist could get freed a second time if there |
||||
are allocation failures, so set them to NULL to avoid a double-free. |
||||
|
||||
Reviewed-by: Arjun Shankar <arjun@redhat.com> |
||||
(cherry picked from commit 77a34079d8f3d63b61543bf3af93043f8674e4c4) |
||||
|
||||
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c |
||||
index 838a68f0229b5aa8..43dfc6739e350a58 100644 |
||||
--- a/sysdeps/posix/getaddrinfo.c |
||||
+++ b/sysdeps/posix/getaddrinfo.c |
||||
@@ -2008,6 +2008,7 @@ gaiconf_init (void) |
||||
l = l->next; |
||||
} |
||||
free_prefixlist (labellist); |
||||
+ labellist = NULL; |
||||
|
||||
/* Sort the entries so that the most specific ones are at |
||||
the beginning. */ |
||||
@@ -2046,6 +2047,7 @@ gaiconf_init (void) |
||||
l = l->next; |
||||
} |
||||
free_prefixlist (precedencelist); |
||||
+ precedencelist = NULL; |
||||
|
||||
/* Sort the entries so that the most specific ones are at |
||||
the beginning. */ |
@ -0,0 +1,208 @@
@@ -0,0 +1,208 @@
|
||||
commit cda99af14e82b4bb6abaecd717ebe3b57c0aa534 |
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org> |
||||
Date: Mon Sep 6 12:28:24 2021 -0300 |
||||
|
||||
linux: Simplify get_nprocs |
||||
|
||||
This patch simplifies the memory allocation code and uses the sched |
||||
routines instead of reimplement it. This still uses a stack |
||||
allocation buffer, so it can be used on malloc initialization code. |
||||
|
||||
Linux currently supports at maximum of 4096 cpus for most architectures: |
||||
|
||||
$ find -iname Kconfig | xargs git grep -A10 -w NR_CPUS | grep -w range |
||||
arch/alpha/Kconfig- range 2 32 |
||||
arch/arc/Kconfig- range 2 4096 |
||||
arch/arm/Kconfig- range 2 16 if DEBUG_KMAP_LOCAL |
||||
arch/arm/Kconfig- range 2 32 if !DEBUG_KMAP_LOCAL |
||||
arch/arm64/Kconfig- range 2 4096 |
||||
arch/csky/Kconfig- range 2 32 |
||||
arch/hexagon/Kconfig- range 2 6 if SMP |
||||
arch/ia64/Kconfig- range 2 4096 |
||||
arch/mips/Kconfig- range 2 256 |
||||
arch/openrisc/Kconfig- range 2 32 |
||||
arch/parisc/Kconfig- range 2 32 |
||||
arch/riscv/Kconfig- range 2 32 |
||||
arch/s390/Kconfig- range 2 512 |
||||
arch/sh/Kconfig- range 2 32 |
||||
arch/sparc/Kconfig- range 2 32 if SPARC32 |
||||
arch/sparc/Kconfig- range 2 4096 if SPARC64 |
||||
arch/um/Kconfig- range 1 1 |
||||
arch/x86/Kconfig-# [NR_CPUS_RANGE_BEGIN ... NR_CPUS_RANGE_END] range. |
||||
arch/x86/Kconfig- range NR_CPUS_RANGE_BEGIN NR_CPUS_RANGE_END |
||||
arch/xtensa/Kconfig- range 2 32 |
||||
|
||||
With x86 supporting 8192: |
||||
|
||||
arch/x86/Kconfig |
||||
976 config NR_CPUS_RANGE_END |
||||
977 int |
||||
978 depends on X86_64 |
||||
979 default 8192 if SMP && CPUMASK_OFFSTACK |
||||
980 default 512 if SMP && !CPUMASK_OFFSTACK |
||||
981 default 1 if !SMP |
||||
|
||||
So using a maximum of 32k cpu should cover all cases (and I would |
||||
expect once we start to have many more CPUs that Linux would provide |
||||
a more straightforward way to query for such information). |
||||
|
||||
A test is added to check if sched_getaffinity can successfully return |
||||
with large buffers. |
||||
|
||||
Checked on x86_64-linux-gnu and i686-linux-gnu. |
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com> |
||||
(cherry picked from commit 33099d72e41cf8a129b362e9709eb2be9372d844) |
||||
|
||||
diff --git a/posix/Makefile b/posix/Makefile |
||||
index a5229777eeb0e067..61fcdf015b4ec83b 100644 |
||||
--- a/posix/Makefile |
||||
+++ b/posix/Makefile |
||||
@@ -107,7 +107,8 @@ tests := test-errno tstgetopt testfnm runtests runptests \ |
||||
tst-sysconf-empty-chroot tst-glob_symlinks tst-fexecve \ |
||||
tst-glob-tilde test-ssize-max tst-spawn4 bug-regex37 \ |
||||
bug-regex38 tst-regcomp-truncated tst-spawn-chdir \ |
||||
- tst-wordexp-nocmd tst-execveat tst-spawn5 |
||||
+ tst-wordexp-nocmd tst-execveat tst-spawn5 \ |
||||
+ tst-sched_getaffinity |
||||
|
||||
# Test for the glob symbol version that was replaced in glibc 2.27. |
||||
ifeq ($(have-GLIBC_2.26)$(build-shared),yesyes) |
||||
diff --git a/posix/tst-sched_getaffinity.c b/posix/tst-sched_getaffinity.c |
||||
new file mode 100644 |
||||
index 0000000000000000..db9d517a96fdd99e |
||||
--- /dev/null |
||||
+++ b/posix/tst-sched_getaffinity.c |
||||
@@ -0,0 +1,48 @@ |
||||
+/* Tests for sched_getaffinity with large buffers. |
||||
+ 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 <array_length.h> |
||||
+#include <sched.h> |
||||
+#include <support/check.h> |
||||
+ |
||||
+/* NB: this test may fail on system with more than 32k cpus. */ |
||||
+ |
||||
+static int |
||||
+do_test (void) |
||||
+{ |
||||
+ /* The values are larger than the default cpu_set_t. */ |
||||
+ const int bufsize[] = { 1<<11, 1<<12, 1<<13, 1<<14, 1<<15, 1<<16, 1<<17 }; |
||||
+ int cpucount[array_length (bufsize)]; |
||||
+ |
||||
+ for (int i = 0; i < array_length (bufsize); i++) |
||||
+ { |
||||
+ cpu_set_t *cpuset = CPU_ALLOC (bufsize[i]); |
||||
+ TEST_VERIFY (cpuset != NULL); |
||||
+ size_t size = CPU_ALLOC_SIZE (bufsize[i]); |
||||
+ TEST_COMPARE (sched_getaffinity (0, size, cpuset), 0); |
||||
+ cpucount[i] = CPU_COUNT_S (size, cpuset); |
||||
+ CPU_FREE (cpuset); |
||||
+ } |
||||
+ |
||||
+ for (int i = 0; i < array_length (cpucount) - 1; i++) |
||||
+ TEST_COMPARE (cpucount[i], cpucount[i + 1]); |
||||
+ |
||||
+ return 0; |
||||
+} |
||||
+ |
||||
+#include <support/test-driver.c> |
||||
diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c |
||||
index 120ce1bb756b09cc..61d20e7bab8640f2 100644 |
||||
--- a/sysdeps/unix/sysv/linux/getsysstats.c |
||||
+++ b/sysdeps/unix/sysv/linux/getsysstats.c |
||||
@@ -29,61 +29,29 @@ |
||||
#include <sys/sysinfo.h> |
||||
#include <sysdep.h> |
||||
|
||||
-/* Compute the population count of the entire array. */ |
||||
-static int |
||||
-__get_nprocs_count (const unsigned long int *array, size_t length) |
||||
-{ |
||||
- int count = 0; |
||||
- for (size_t i = 0; i < length; ++i) |
||||
- if (__builtin_add_overflow (count, __builtin_popcountl (array[i]), |
||||
- &count)) |
||||
- return INT_MAX; |
||||
- return count; |
||||
-} |
||||
- |
||||
-/* __get_nprocs with a large buffer. */ |
||||
-static int |
||||
-__get_nprocs_large (void) |
||||
-{ |
||||
- /* This code cannot use scratch_buffer because it is used during |
||||
- malloc initialization. */ |
||||
- size_t pagesize = GLRO (dl_pagesize); |
||||
- unsigned long int *page = __mmap (0, pagesize, PROT_READ | PROT_WRITE, |
||||
- MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); |
||||
- if (page == MAP_FAILED) |
||||
- return 2; |
||||
- int r = INTERNAL_SYSCALL_CALL (sched_getaffinity, 0, pagesize, page); |
||||
- int count; |
||||
- if (r > 0) |
||||
- count = __get_nprocs_count (page, pagesize / sizeof (unsigned long int)); |
||||
- else if (r == -EINVAL) |
||||
- /* One page is still not enough to store the bits. A more-or-less |
||||
- arbitrary value. This assumes t hat such large systems never |
||||
- happen in practice. */ |
||||
- count = GLRO (dl_pagesize) * CHAR_BIT; |
||||
- else |
||||
- count = 2; |
||||
- __munmap (page, GLRO (dl_pagesize)); |
||||
- return count; |
||||
-} |
||||
- |
||||
int |
||||
__get_nprocs (void) |
||||
{ |
||||
- /* Fast path for most systems. The kernel expects a buffer size |
||||
- that is a multiple of 8. */ |
||||
- unsigned long int small_buffer[1024 / CHAR_BIT / sizeof (unsigned long int)]; |
||||
- int r = INTERNAL_SYSCALL_CALL (sched_getaffinity, 0, |
||||
- sizeof (small_buffer), small_buffer); |
||||
+ enum |
||||
+ { |
||||
+ max_num_cpus = 32768, |
||||
+ cpu_bits_size = CPU_ALLOC_SIZE (32768) |
||||
+ }; |
||||
+ |
||||
+ /* This cannot use malloc because it is used on malloc initialization. */ |
||||
+ __cpu_mask cpu_bits[cpu_bits_size / sizeof (__cpu_mask)]; |
||||
+ int r = INTERNAL_SYSCALL_CALL (sched_getaffinity, 0, cpu_bits_size, |
||||
+ cpu_bits); |
||||
if (r > 0) |
||||
- return __get_nprocs_count (small_buffer, r / sizeof (unsigned long int)); |
||||
+ return CPU_COUNT_S (cpu_bits_size, (cpu_set_t*) cpu_bits); |
||||
else if (r == -EINVAL) |
||||
- /* The kernel requests a larger buffer to store the data. */ |
||||
- return __get_nprocs_large (); |
||||
- else |
||||
- /* Some other error. 2 is conservative (not a uniprocessor |
||||
- system, so atomics are needed). */ |
||||
- return 2; |
||||
+ /* 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 |
||||
+ is no offline cpus. */ |
||||
+ return max_num_cpus; |
||||
+ /* Some other error. 2 is conservative (not a uniprocessor system, so |
||||
+ atomics are needed). */ |
||||
+ return 2; |
||||
} |
||||
libc_hidden_def (__get_nprocs) |
||||
weak_alias (__get_nprocs, get_nprocs) |
@ -0,0 +1,201 @@
@@ -0,0 +1,201 @@
|
||||
commit 822662cf2a4b170ade4c5342f035d68815a03276 |
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org> |
||||
Date: Mon Sep 6 14:19:51 2021 -0300 |
||||
|
||||
linux: Revert the use of sched_getaffinity on get_nproc (BZ #28310) |
||||
|
||||
The use of sched_getaffinity on get_nproc and |
||||
sysconf (_SC_NPROCESSORS_ONLN) done in 903bc7dcc2acafc40 (BZ #27645) |
||||
breaks the top command in common hypervisor configurations and also |
||||
other monitoring tools. |
||||
|
||||
The main issue using sched_getaffinity changed the symbols semantic |
||||
from system-wide scope of online CPUs to per-process one (which can |
||||
be changed with kernel cpusets or book parameters in VM). |
||||
|
||||
This patch reverts mostly of the 903bc7dcc2acafc40, with the |
||||
exceptions: |
||||
|
||||
* No more cached values and atomic updates, since they are inherent |
||||
racy. |
||||
|
||||
* No /proc/cpuinfo fallback, since /proc/stat is already used and |
||||
it would require to revert more arch-specific code. |
||||
|
||||
* The alloca is replace with a static buffer of 1024 bytes. |
||||
|
||||
So the implementation first consult the sysfs, and fallbacks to procfs. |
||||
|
||||
Checked on x86_64-linux-gnu. |
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com> |
||||
(cherry picked from commit 342298278eabc75baabcaced110a11a02c3d3580) |
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c |
||||
index 61d20e7bab8640f2..d70ed9586950615c 100644 |
||||
--- a/sysdeps/unix/sysv/linux/getsysstats.c |
||||
+++ b/sysdeps/unix/sysv/linux/getsysstats.c |
||||
@@ -18,6 +18,8 @@ |
||||
<https://www.gnu.org/licenses/>. */ |
||||
|
||||
#include <array_length.h> |
||||
+#include <assert.h> |
||||
+#include <ctype.h> |
||||
#include <dirent.h> |
||||
#include <errno.h> |
||||
#include <ldsodefs.h> |
||||
@@ -30,7 +32,7 @@ |
||||
#include <sysdep.h> |
||||
|
||||
int |
||||
-__get_nprocs (void) |
||||
+__get_nprocs_sched (void) |
||||
{ |
||||
enum |
||||
{ |
||||
@@ -53,14 +55,141 @@ __get_nprocs (void) |
||||
atomics are needed). */ |
||||
return 2; |
||||
} |
||||
-libc_hidden_def (__get_nprocs) |
||||
-weak_alias (__get_nprocs, get_nprocs) |
||||
+ |
||||
+static char * |
||||
+next_line (int fd, char *const buffer, char **cp, char **re, |
||||
+ char *const buffer_end) |
||||
+{ |
||||
+ char *res = *cp; |
||||
+ char *nl = memchr (*cp, '\n', *re - *cp); |
||||
+ if (nl == NULL) |
||||
+ { |
||||
+ if (*cp != buffer) |
||||
+ { |
||||
+ if (*re == buffer_end) |
||||
+ { |
||||
+ memmove (buffer, *cp, *re - *cp); |
||||
+ *re = buffer + (*re - *cp); |
||||
+ *cp = buffer; |
||||
+ |
||||
+ ssize_t n = __read_nocancel (fd, *re, buffer_end - *re); |
||||
+ if (n < 0) |
||||
+ return NULL; |
||||
+ |
||||
+ *re += n; |
||||
+ |
||||
+ nl = memchr (*cp, '\n', *re - *cp); |
||||
+ while (nl == NULL && *re == buffer_end) |
||||
+ { |
||||
+ /* Truncate too long lines. */ |
||||
+ *re = buffer + 3 * (buffer_end - buffer) / 4; |
||||
+ n = __read_nocancel (fd, *re, buffer_end - *re); |
||||
+ if (n < 0) |
||||
+ return NULL; |
||||
+ |
||||
+ nl = memchr (*re, '\n', n); |
||||
+ **re = '\n'; |
||||
+ *re += n; |
||||
+ } |
||||
+ } |
||||
+ else |
||||
+ nl = memchr (*cp, '\n', *re - *cp); |
||||
+ |
||||
+ res = *cp; |
||||
+ } |
||||
+ |
||||
+ if (nl == NULL) |
||||
+ nl = *re - 1; |
||||
+ } |
||||
+ |
||||
+ *cp = nl + 1; |
||||
+ assert (*cp <= *re); |
||||
+ |
||||
+ return res == *re ? NULL : res; |
||||
+} |
||||
+ |
||||
|
||||
int |
||||
-__get_nprocs_sched (void) |
||||
+__get_nprocs (void) |
||||
{ |
||||
- return __get_nprocs (); |
||||
+ enum { buffer_size = 1024 }; |
||||
+ char buffer[buffer_size]; |
||||
+ char *buffer_end = buffer + buffer_size; |
||||
+ char *cp = buffer_end; |
||||
+ char *re = buffer_end; |
||||
+ |
||||
+ const int flags = O_RDONLY | O_CLOEXEC; |
||||
+ /* This file contains comma-separated ranges. */ |
||||
+ int fd = __open_nocancel ("/sys/devices/system/cpu/online", flags); |
||||
+ char *l; |
||||
+ int result = 0; |
||||
+ if (fd != -1) |
||||
+ { |
||||
+ l = next_line (fd, buffer, &cp, &re, buffer_end); |
||||
+ if (l != NULL) |
||||
+ do |
||||
+ { |
||||
+ char *endp; |
||||
+ unsigned long int n = strtoul (l, &endp, 10); |
||||
+ if (l == endp) |
||||
+ { |
||||
+ result = 0; |
||||
+ break; |
||||
+ } |
||||
+ |
||||
+ unsigned long int m = n; |
||||
+ if (*endp == '-') |
||||
+ { |
||||
+ l = endp + 1; |
||||
+ m = strtoul (l, &endp, 10); |
||||
+ if (l == endp) |
||||
+ { |
||||
+ result = 0; |
||||
+ break; |
||||
+ } |
||||
+ } |
||||
+ |
||||
+ result += m - n + 1; |
||||
+ |
||||
+ l = endp; |
||||
+ if (l < re && *l == ',') |
||||
+ ++l; |
||||
+ } |
||||
+ while (l < re && *l != '\n'); |
||||
+ |
||||
+ __close_nocancel_nostatus (fd); |
||||
+ |
||||
+ if (result > 0) |
||||
+ return result; |
||||
+ } |
||||
+ |
||||
+ cp = buffer_end; |
||||
+ re = buffer_end; |
||||
+ |
||||
+ /* Default to an SMP system in case we cannot obtain an accurate |
||||
+ number. */ |
||||
+ result = 2; |
||||
+ |
||||
+ fd = __open_nocancel ("/proc/stat", flags); |
||||
+ if (fd != -1) |
||||
+ { |
||||
+ result = 0; |
||||
+ |
||||
+ while ((l = next_line (fd, buffer, &cp, &re, buffer_end)) != NULL) |
||||
+ /* The current format of /proc/stat has all the cpu* entries |
||||
+ at the front. We assume here that stays this way. */ |
||||
+ if (strncmp (l, "cpu", 3) != 0) |
||||
+ break; |
||||
+ else if (isdigit (l[3])) |
||||
+ ++result; |
||||
+ |
||||
+ __close_nocancel_nostatus (fd); |
||||
+ } |
||||
+ |
||||
+ return result; |
||||
} |
||||
+libc_hidden_def (__get_nprocs) |
||||
+weak_alias (__get_nprocs, get_nprocs) |
||||
|
||||
|
||||
/* On some architectures it is possible to distinguish between configured |
@ -0,0 +1,42 @@
@@ -0,0 +1,42 @@
|
||||
commit 80a009119ba2330768120476aaad63767b81d543 |
||||
Author: Jonathan Wakely <jwakely@redhat.com> |
||||
Date: Wed May 19 16:48:19 2021 +0100 |
||||
|
||||
Suppress -Wcast-qual warnings in bsearch |
||||
|
||||
The first cast to (void *) is redundant but should be (const void *) |
||||
anyway, because that's the type of the lvalue being assigned to. |
||||
|
||||
The second cast is necessary and intentionally not const-correct, so |
||||
tell the compiler not to warn about it. |
||||
|
||||
Reviewed-by: Florian Weimer <fweimer@redhat.com> |
||||
(cherry picked from commit a725ff1de965f4cc4f36a7e8ae795d40ca0350d7) |
||||
|
||||
diff --git a/bits/stdlib-bsearch.h b/bits/stdlib-bsearch.h |
||||
index 4132dc6af0077f31..d688ed2e15678e9c 100644 |
||||
--- a/bits/stdlib-bsearch.h |
||||
+++ b/bits/stdlib-bsearch.h |
||||
@@ -29,14 +29,21 @@ bsearch (const void *__key, const void *__base, size_t __nmemb, size_t __size, |
||||
while (__l < __u) |
||||
{ |
||||
__idx = (__l + __u) / 2; |
||||
- __p = (void *) (((const char *) __base) + (__idx * __size)); |
||||
+ __p = (const void *) (((const char *) __base) + (__idx * __size)); |
||||
__comparison = (*__compar) (__key, __p); |
||||
if (__comparison < 0) |
||||
__u = __idx; |
||||
else if (__comparison > 0) |
||||
__l = __idx + 1; |
||||
else |
||||
+#if __GNUC_PREREQ(4, 6) |
||||
+# pragma GCC diagnostic push |
||||
+# pragma GCC diagnostic ignored "-Wcast-qual" |
||||
+#endif |
||||
return (void *) __p; |
||||
+#if __GNUC_PREREQ(4, 6) |
||||
+# pragma GCC diagnostic pop |
||||
+#endif |
||||
} |
||||
|
||||
return NULL; |
@ -0,0 +1,37 @@
@@ -0,0 +1,37 @@
|
||||
commit a996d13b8a2e101bedbb1bdaa7ffcfea3b959bb2 |
||||
Author: Florian Weimer <fweimer@redhat.com> |
||||
Date: Thu Sep 30 18:44:06 2021 +0200 |
||||
|
||||
Add missing braces to bsearch inline implementation [BZ #28400] |
||||
|
||||
GCC treats the pragma as a statement, so that the else branch only |
||||
consists of the pragma, not the return statement. |
||||
|
||||
Fixes commit a725ff1de965f4cc4f36a7e8ae795d40ca0350d7 ("Suppress |
||||
-Wcast-qual warnings in bsearch"). |
||||
|
||||
Reviewed-by: H.J. Lu <hjl.tools@gmail.com> |
||||
(cherry picked from commit 32b96d0dec0294465d2221a8f049703599d9d8e4) |
||||
|
||||
diff --git a/bits/stdlib-bsearch.h b/bits/stdlib-bsearch.h |
||||
index d688ed2e15678e9c..e2fcea6e172af72c 100644 |
||||
--- a/bits/stdlib-bsearch.h |
||||
+++ b/bits/stdlib-bsearch.h |
||||
@@ -36,14 +36,16 @@ bsearch (const void *__key, const void *__base, size_t __nmemb, size_t __size, |
||||
else if (__comparison > 0) |
||||
__l = __idx + 1; |
||||
else |
||||
+ { |
||||
#if __GNUC_PREREQ(4, 6) |
||||
# pragma GCC diagnostic push |
||||
# pragma GCC diagnostic ignored "-Wcast-qual" |
||||
#endif |
||||
- return (void *) __p; |
||||
+ return (void *) __p; |
||||
#if __GNUC_PREREQ(4, 6) |
||||
# pragma GCC diagnostic pop |
||||
#endif |
||||
+ } |
||||
} |
||||
|
||||
return NULL; |
@ -0,0 +1,41 @@
@@ -0,0 +1,41 @@
|
||||
commit 558168c78ea1eb8efb33959c1da9d6b5a997fd7b |
||||
Author: Siddhesh Poyarekar <siddhesh@sourceware.org> |
||||
Date: Wed Oct 6 21:48:35 2021 +0530 |
||||
|
||||
support: Also return fd when it is 0 |
||||
|
||||
The fd validity check in open_dev_null checks if fd > 0, which would |
||||
lead to a leaked fd if it is == 0. |
||||
|
||||
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org> |
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org> |
||||
(cherry picked from commit 27b6edbb090f736b101f569620d8ad0e7217ddf8) |
||||
|
||||
diff --git a/support/support-open-dev-null-range.c b/support/support-open-dev-null-range.c |
||||
index 80d9dba50402ce12..66a850410557351b 100644 |
||||
--- a/support/support-open-dev-null-range.c |
||||
+++ b/support/support-open-dev-null-range.c |
||||
@@ -40,16 +40,16 @@ increase_nofile (void) |
||||
static int |
||||
open_dev_null (int flags, mode_t mode) |
||||
{ |
||||
- int fd = open64 ("/dev/null", flags, mode); |
||||
- if (fd > 0) |
||||
- return fd; |
||||
+ int fd = open64 ("/dev/null", flags, mode); |
||||
+ if (fd >= 0) |
||||
+ return fd; |
||||
|
||||
- if (fd < 0 && errno != EMFILE) |
||||
- FAIL_EXIT1 ("open64 (\"/dev/null\", 0x%x, 0%o): %m", flags, mode); |
||||
+ if (fd < 0 && errno != EMFILE) |
||||
+ FAIL_EXIT1 ("open64 (\"/dev/null\", 0x%x, 0%o): %m", flags, mode); |
||||
|
||||
- increase_nofile (); |
||||
+ increase_nofile (); |
||||
|
||||
- return xopen ("/dev/null", flags, mode); |
||||
+ return xopen ("/dev/null", flags, mode); |
||||
} |
||||
|
||||
struct range |
@ -0,0 +1,83 @@
@@ -0,0 +1,83 @@
|
||||
commit cb44a620ef2336449af60694b6696efced161774 |
||||
Author: Stefan Liebler <stli@linux.ibm.com> |
||||
Date: Tue Oct 5 16:14:10 2021 +0200 |
||||
|
||||
S390: Add PCI_MIO and SIE HWCAPs |
||||
|
||||
Both new HWCAPs were introduced in these kernel commits: |
||||
- 7e8403ecaf884f307b627f3c371475913dd29292 |
||||
"s390: add HWCAP_S390_PCI_MIO to ELF hwcaps" |
||||
- 7e82523f2583e9813e4109df3656707162541297 |
||||
"s390/hwcaps: make sie capability regular hwcap" |
||||
|
||||
Also note that the kernel commit 511ad531afd4090625def4d9aba1f5227bd44b8e |
||||
"s390/hwcaps: shorten HWCAP defines" has shortened the prefix of the macros |
||||
from "HWCAP_S390_" to "HWCAP_". For compatibility reasons, we do not |
||||
change the prefix in public glibc header file. |
||||
|
||||
(cherry picked from commit f2e06656d04a9fcb0603802a4f8ce7aa3a1f055e) |
||||
|
||||
diff --git a/sysdeps/s390/dl-procinfo.c b/sysdeps/s390/dl-procinfo.c |
||||
index c174e27b3559c57c..155f0bd99eccb3f9 100644 |
||||
--- a/sysdeps/s390/dl-procinfo.c |
||||
+++ b/sysdeps/s390/dl-procinfo.c |
||||
@@ -46,13 +46,13 @@ |
||||
#if !defined PROCINFO_DECL && defined SHARED |
||||
._dl_s390_cap_flags |
||||
#else |
||||
-PROCINFO_CLASS const char _dl_s390_cap_flags[21][9] |
||||
+PROCINFO_CLASS const char _dl_s390_cap_flags[23][9] |
||||
#endif |
||||
#ifndef PROCINFO_DECL |
||||
= { |
||||
"esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", "edat", "etf3eh", |
||||
"highgprs", "te", "vx", "vxd", "vxe", "gs", "vxe2", "vxp", "sort", "dflt", |
||||
- "vxp2", "nnpa" |
||||
+ "vxp2", "nnpa", "pcimio", "sie" |
||||
} |
||||
#endif |
||||
#if !defined SHARED || defined PROCINFO_DECL |
||||
diff --git a/sysdeps/s390/dl-procinfo.h b/sysdeps/s390/dl-procinfo.h |
||||
index 2d9c3058083e5dda..e4e3e334a5b3d47c 100644 |
||||
--- a/sysdeps/s390/dl-procinfo.h |
||||
+++ b/sysdeps/s390/dl-procinfo.h |
||||
@@ -21,7 +21,7 @@ |
||||
#define _DL_PROCINFO_H 1 |
||||
#include <ldsodefs.h> |
||||
|
||||
-#define _DL_HWCAP_COUNT 21 |
||||
+#define _DL_HWCAP_COUNT 23 |
||||
|
||||
#define _DL_PLATFORMS_COUNT 10 |
||||
|
||||
@@ -63,6 +63,8 @@ enum |
||||
HWCAP_S390_DFLT = 1 << 18, |
||||
HWCAP_S390_VXRS_PDE2 = 1 << 19, |
||||
HWCAP_S390_NNPA = 1 << 20, |
||||
+ HWCAP_S390_PCI_MIO = 1 << 21, |
||||
+ HWCAP_S390_SIE = 1 << 22, |
||||
}; |
||||
|
||||
#define HWCAP_IMPORTANT (HWCAP_S390_ZARCH | HWCAP_S390_LDISP \ |
||||
diff --git a/sysdeps/unix/sysv/linux/s390/bits/hwcap.h b/sysdeps/unix/sysv/linux/s390/bits/hwcap.h |
||||
index e9bd3684db862d1b..00e73a3e3bfdb711 100644 |
||||
--- a/sysdeps/unix/sysv/linux/s390/bits/hwcap.h |
||||
+++ b/sysdeps/unix/sysv/linux/s390/bits/hwcap.h |
||||
@@ -22,6 +22,11 @@ |
||||
|
||||
/* |
||||
* The following must match the kernels asm/elf.h. |
||||
+ * Note: The kernel commit 511ad531afd4090625def4d9aba1f5227bd44b8e |
||||
+ * "s390/hwcaps: shorten HWCAP defines" has shortened the prefix of the macros |
||||
+ * from "HWCAP_S390_" to "HWCAP_". For compatibility reasons, we do not |
||||
+ * change the prefix in public glibc header file. |
||||
+ * |
||||
* Note that these are *not* the same as the STORE FACILITY LIST bits. |
||||
*/ |
||||
#define HWCAP_S390_ESAN3 1 |
||||
@@ -48,3 +53,5 @@ |
||||
#define HWCAP_S390_DFLT 262144 |
||||
#define HWCAP_S390_VXRS_PDE2 524288 |
||||
#define HWCAP_S390_NNPA 1048576 |
||||
+#define HWCAP_S390_PCI_MIO 2097152 |
||||
+#define HWCAP_S390_SIE 4194304 |
@ -0,0 +1,47 @@
@@ -0,0 +1,47 @@
|
||||
commit 79528414dc1578800cbf1fba2fbdb6335f4f39bf |
||||
Author: H.J. Lu <hjl.tools@gmail.com> |
||||
Date: Thu Sep 30 10:29:17 2021 -0700 |
||||
|
||||
elf: Replace nsid with args.nsid [BZ #27609] |
||||
|
||||
commit ec935dea6332cb22f9881cd1162bad156173f4b0 |
||||
Author: Florian Weimer <fweimer@redhat.com> |
||||
Date: Fri Apr 24 22:31:15 2020 +0200 |
||||
|
||||
elf: Implement __libc_early_init |
||||
|
||||
has |
||||
|
||||
@@ -856,6 +876,11 @@ no more namespaces available for dlmopen()")); |
||||
/* See if an error occurred during loading. */ |
||||
if (__glibc_unlikely (exception.errstring != NULL)) |
||||
{ |
||||
+ /* Avoid keeping around a dangling reference to the libc.so link |
||||
+ map in case it has been cached in libc_map. */ |
||||
+ if (!args.libc_already_loaded) |
||||
+ GL(dl_ns)[nsid].libc_map = NULL; |
||||
+ |
||||
|
||||
do_dlopen calls _dl_open with nsid == __LM_ID_CALLER (-2), which calls |
||||
dl_open_worker with args.nsid = nsid. dl_open_worker updates args.nsid |
||||
if it is __LM_ID_CALLER. After dl_open_worker returns, it is wrong to |
||||
use nsid. |
||||
|
||||
Replace nsid with args.nsid after dl_open_worker returns. This fixes |
||||
BZ #27609. |
||||
|
||||
(cherry picked from commit 1e1ecea62e899acb58c3fdf3b320a0833ddd0dff) |
||||
|
||||
diff --git a/elf/dl-open.c b/elf/dl-open.c |
||||
index ec386626f96e17f7..41c7250bf630f978 100644 |
||||
--- a/elf/dl-open.c |
||||
+++ b/elf/dl-open.c |
||||
@@ -886,7 +886,7 @@ no more namespaces available for dlmopen()")); |
||||
/* Avoid keeping around a dangling reference to the libc.so link |
||||
map in case it has been cached in libc_map. */ |
||||
if (!args.libc_already_loaded) |
||||
- GL(dl_ns)[nsid].libc_map = NULL; |
||||
+ GL(dl_ns)[args.nsid].libc_map = NULL; |
||||
|
||||
/* Remove the object from memory. It may be in an inconsistent |
||||
state if relocation failed, for example. */ |
@ -0,0 +1,137 @@
@@ -0,0 +1,137 @@
|
||||
commit 76843f3b3ecb886b8d300220e6ec378e0fd09a8b |
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org> |
||||
Date: Wed Oct 6 08:10:13 2021 -0300 |
||||
|
||||
y2038: Use a common definition for stat for sparc32 |
||||
|
||||
The sparc32 misses support for support done by 4e8521333bea6. |
||||
|
||||
Checked on sparcv9-linux-gnu. |
||||
|
||||
(cherry picked from commit d2b1254db208b35ff060f00a15f22a1eed5306d2) |
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/struct_stat.h b/sysdeps/unix/sysv/linux/sparc/bits/struct_stat.h |
||||
index b481b4f9f80a94f4..45db6b6ffbb19b8b 100644 |
||||
--- a/sysdeps/unix/sysv/linux/sparc/bits/struct_stat.h |
||||
+++ b/sysdeps/unix/sysv/linux/sparc/bits/struct_stat.h |
||||
@@ -28,32 +28,35 @@ |
||||
|
||||
struct stat |
||||
{ |
||||
+#ifdef __USE_TIME_BITS64 |
||||
+# include <bits/struct_stat_time64_helper.h> |
||||
+#else |
||||
__dev_t st_dev; /* Device. */ |
||||
-#if __WORDSIZE == 64 || !defined __USE_FILE_OFFSET64 |
||||
+# if __WORDSIZE == 64 || !defined __USE_FILE_OFFSET64 |
||||
unsigned short int __pad1; |
||||
__ino_t st_ino; /* File serial number. */ |
||||
-#else |
||||
+# else |
||||
__ino64_t st_ino; /* File serial number. */ |
||||
-#endif |
||||
+# endif |
||||
__mode_t st_mode; /* File mode. */ |
||||
__nlink_t st_nlink; /* Link count. */ |
||||
__uid_t st_uid; /* User ID of the file's owner. */ |
||||
__gid_t st_gid; /* Group ID of the file's group.*/ |
||||
__dev_t st_rdev; /* Device number, if device. */ |
||||
unsigned short int __pad2; |
||||
-#ifndef __USE_FILE_OFFSET64 |
||||
+# ifndef __USE_FILE_OFFSET64 |
||||
__off_t st_size; /* Size of file, in bytes. */ |
||||
-#else |
||||
+# else |
||||
__off64_t st_size; /* Size of file, in bytes. */ |
||||
-#endif |
||||
+# endif |
||||
__blksize_t st_blksize; /* Optimal block size for I/O. */ |
||||
|
||||
-#ifndef __USE_FILE_OFFSET64 |
||||
+# ifndef __USE_FILE_OFFSET64 |
||||
__blkcnt_t st_blocks; /* Number 512-byte blocks allocated. */ |
||||
-#else |
||||
+# else |
||||
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ |
||||
-#endif |
||||
-#ifdef __USE_XOPEN2K8 |
||||
+# endif |
||||
+# ifdef __USE_XOPEN2K8 |
||||
/* Nanosecond resolution timestamps are stored in a format |
||||
equivalent to 'struct timespec'. This is the type used |
||||
whenever possible but the Unix namespace rules do not allow the |
||||
@@ -63,28 +66,32 @@ struct stat |
||||
struct timespec st_atim; /* Time of last access. */ |
||||
struct timespec st_mtim; /* Time of last modification. */ |
||||
struct timespec st_ctim; /* Time of last status change. */ |
||||
-# define st_atime st_atim.tv_sec /* Backward compatibility. */ |
||||
-# define st_mtime st_mtim.tv_sec |
||||
-# define st_ctime st_ctim.tv_sec |
||||
-#else |
||||
+# define st_atime st_atim.tv_sec /* Backward compatibility. */ |
||||
+# define st_mtime st_mtim.tv_sec |
||||
+# define st_ctime st_ctim.tv_sec |
||||
+# else |
||||
__time_t st_atime; /* Time of last access. */ |
||||
unsigned long int st_atimensec; /* Nscecs of last access. */ |
||||
__time_t st_mtime; /* Time of last modification. */ |
||||
unsigned long int st_mtimensec; /* Nsecs of last modification. */ |
||||
__time_t st_ctime; /* Time of last status change. */ |
||||
unsigned long int st_ctimensec; /* Nsecs of last status change. */ |
||||
-#endif |
||||
+# endif |
||||
unsigned long int __glibc_reserved4; |
||||
unsigned long int __glibc_reserved5; |
||||
+#endif /* __USE_TIME_BITS64 */ |
||||
}; |
||||
|
||||
#ifdef __USE_LARGEFILE64 |
||||
struct stat64 |
||||
{ |
||||
+# ifdef __USE_TIME_BITS64 |
||||
+# include <bits/struct_stat_time64_helper.h> |
||||
+# else |
||||
__dev_t st_dev; /* Device. */ |
||||
-# if __WORDSIZE == 64 |
||||
+# if __WORDSIZE == 64 |
||||
unsigned short int __pad1; |
||||
-# endif |
||||
+# endif |
||||
__ino64_t st_ino; /* File serial number. */ |
||||
__mode_t st_mode; /* File mode. */ |
||||
__nlink_t st_nlink; /* Link count. */ |
||||
@@ -96,7 +103,7 @@ struct stat64 |
||||
__blksize_t st_blksize; /* Optimal block size for I/O. */ |
||||
|
||||
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ |
||||
-# ifdef __USE_XOPEN2K8 |
||||
+# ifdef __USE_XOPEN2K8 |
||||
/* Nanosecond resolution timestamps are stored in a format |
||||
equivalent to 'struct timespec'. This is the type used |
||||
whenever possible but the Unix namespace rules do not allow the |
||||
@@ -106,19 +113,20 @@ struct stat64 |
||||
struct timespec st_atim; /* Time of last access. */ |
||||
struct timespec st_mtim; /* Time of last modification. */ |
||||
struct timespec st_ctim; /* Time of last status change. */ |
||||
-# define st_atime st_atim.tv_sec /* Backward compatibility. */ |
||||
-# define st_mtime st_mtim.tv_sec |
||||
-# define st_ctime st_ctim.tv_sec |
||||
-# else |
||||
+# define st_atime st_atim.tv_sec /* Backward compatibility. */ |
||||
+# define st_mtime st_mtim.tv_sec |
||||
+# define st_ctime st_ctim.tv_sec |
||||
+# else |
||||
__time_t st_atime; /* Time of last access. */ |
||||
unsigned long int st_atimensec; /* Nscecs of last access. */ |
||||
__time_t st_mtime; /* Time of last modification. */ |
||||
unsigned long int st_mtimensec; /* Nsecs of last modification. */ |
||||
__time_t st_ctime; /* Time of last status change. */ |
||||
unsigned long int st_ctimensec; /* Nsecs of last status change. */ |
||||
-# endif |
||||
+# endif |
||||
unsigned long int __glibc_reserved4; |
||||
unsigned long int __glibc_reserved5; |
||||
+# endif /* __USE_TIME_BITS64 */ |
||||
}; |
||||
#endif |
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue