Compare commits
No commits in common. 'i9c-beta' and 'c9' have entirely different histories.
@ -1 +1,3 @@
|
|||||||
SOURCES/glibc-2.34.tar.xz
|
SOURCES/glibc-2.34.tar.xz
|
||||||
|
SOURCES/glibc-c-utf8-locale-2.patch
|
||||||
|
SOURCES/glibc-upstream-2.34-373.patch
|
||||||
|
@ -1 +1,3 @@
|
|||||||
7c3b8890a6346793b6334cc5f2fea5d437d307b8 SOURCES/glibc-2.34.tar.xz
|
7c3b8890a6346793b6334cc5f2fea5d437d307b8 SOURCES/glibc-2.34.tar.xz
|
||||||
|
47cf1a27ae2e86b37e44c49f6bf4630a1adabd9a SOURCES/glibc-c-utf8-locale-2.patch
|
||||||
|
6022f103e5596ad229f22bc966327d71208f7016 SOURCES/glibc-upstream-2.34-373.patch
|
||||||
|
@ -0,0 +1,83 @@
|
|||||||
|
From a65ff76c9a1811dd2396ab45563f645579c0e687 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Thu, 27 Oct 2022 11:36:44 +0200
|
||||||
|
Subject: ld.so: Export tls_init_tp_called as __rtld_tls_init_tp_called
|
||||||
|
|
||||||
|
This allows the rest of dynamic loader to check whether the TCB
|
||||||
|
has been set up (and THREAD_GETMEM and THREAD_SETMEM will work).
|
||||||
|
|
||||||
|
Reviewed-by: Siddhesh Poyarekar <siddhesh@gotplt.org>
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
Regenerated for context changes.
|
||||||
|
|
||||||
|
diff -rup a/elf/rtld.c b/elf/rtld.c
|
||||||
|
--- a/elf/rtld.c 2024-08-22 17:57:02.000830481 -0400
|
||||||
|
+++ b/elf/rtld.c 2024-08-22 17:59:30.666562835 -0400
|
||||||
|
@@ -740,7 +740,7 @@ match_version (const char *string, struc
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static bool tls_init_tp_called;
|
||||||
|
+bool __rtld_tls_init_tp_called;
|
||||||
|
|
||||||
|
static void *
|
||||||
|
init_tls (size_t naudit)
|
||||||
|
@@ -812,7 +812,7 @@ cannot allocate TLS data structures for
|
||||||
|
if (__glibc_unlikely (lossage != NULL))
|
||||||
|
_dl_fatal_printf ("cannot set up thread-local storage: %s\n", lossage);
|
||||||
|
__tls_init_tp ();
|
||||||
|
- tls_init_tp_called = true;
|
||||||
|
+ __rtld_tls_init_tp_called = true;
|
||||||
|
|
||||||
|
return tcbp;
|
||||||
|
}
|
||||||
|
@@ -2057,7 +2057,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||||
|
an old kernel that can't perform TLS_INIT_TP, even if no TLS is ever
|
||||||
|
used. Trying to do it lazily is too hairy to try when there could be
|
||||||
|
multiple threads (from a non-TLS-using libpthread). */
|
||||||
|
- bool was_tls_init_tp_called = tls_init_tp_called;
|
||||||
|
+ bool was_tls_init_tp_called = __rtld_tls_init_tp_called;
|
||||||
|
if (tcbp == NULL)
|
||||||
|
tcbp = init_tls (0);
|
||||||
|
|
||||||
|
@@ -2411,7 +2411,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||||
|
_dl_protect_relro (l);
|
||||||
|
|
||||||
|
/* Add object to slot information data if necessasy. */
|
||||||
|
- if (l->l_tls_blocksize != 0 && tls_init_tp_called)
|
||||||
|
+ if (l->l_tls_blocksize != 0 && __rtld_tls_init_tp_called)
|
||||||
|
_dl_add_to_slotinfo (l, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -2462,7 +2462,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||||
|
consider_profiling);
|
||||||
|
|
||||||
|
/* Add object to slot information data if necessasy. */
|
||||||
|
- if (l->l_tls_blocksize != 0 && tls_init_tp_called)
|
||||||
|
+ if (l->l_tls_blocksize != 0 && __rtld_tls_init_tp_called)
|
||||||
|
_dl_add_to_slotinfo (l, true);
|
||||||
|
}
|
||||||
|
rtld_timer_stop (&relocate_time, start);
|
||||||
|
@@ -2488,7 +2488,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||||
|
_dl_allocate_tls_init (tcbp, true);
|
||||||
|
|
||||||
|
/* And finally install it for the main thread. */
|
||||||
|
- if (! tls_init_tp_called)
|
||||||
|
+ if (! __rtld_tls_init_tp_called)
|
||||||
|
{
|
||||||
|
const char *lossage = TLS_INIT_TP (tcbp);
|
||||||
|
if (__glibc_unlikely (lossage != NULL))
|
||||||
|
diff -rup a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||||
|
--- a/sysdeps/generic/ldsodefs.h 2024-08-22 17:57:02.011830906 -0400
|
||||||
|
+++ b/sysdeps/generic/ldsodefs.h 2024-08-22 17:58:10.900487160 -0400
|
||||||
|
@@ -1262,6 +1262,9 @@ extern void *_dl_allocate_tls_storage (v
|
||||||
|
extern void *_dl_allocate_tls_init (void *result, bool main_thread);
|
||||||
|
rtld_hidden_proto (_dl_allocate_tls_init)
|
||||||
|
|
||||||
|
+/* True if the TCB has been set up. */
|
||||||
|
+extern bool __rtld_tls_init_tp_called attribute_hidden;
|
||||||
|
+
|
||||||
|
/* Deallocate memory allocated with _dl_allocate_tls. */
|
||||||
|
extern void _dl_deallocate_tls (void *tcb, bool dealloc_tcb);
|
||||||
|
rtld_hidden_proto (_dl_deallocate_tls)
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,82 @@
|
|||||||
|
Extra changes needed for backport:
|
||||||
|
|
||||||
|
* rename field "rtld_catch" to "rtld_catch_f" to avoid conflict
|
||||||
|
between "struct rtld-catch" and rtld_catch macro
|
||||||
|
|
||||||
|
* move rtld_catch into one of the unused padding fields to preserve
|
||||||
|
ABI
|
||||||
|
|
||||||
|
* Validate that the padding fields used don't overlap other fields.
|
||||||
|
|
||||||
|
diff -rup a/elf/dl-catch.c b/elf/dl-catch.c
|
||||||
|
--- a/elf/dl-catch.c 2024-09-04 16:30:02.086402568 -0400
|
||||||
|
+++ b/elf/dl-catch.c 2024-09-04 16:55:01.933440181 -0400
|
||||||
|
@@ -59,7 +59,7 @@ get_catch (void)
|
||||||
|
return rtld_catch_notls;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
- return THREAD_GETMEM (THREAD_SELF, rtld_catch);
|
||||||
|
+ return THREAD_GETMEM (THREAD_SELF, rtld_catch_f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
@@ -70,7 +70,7 @@ set_catch (struct rtld_catch *catch)
|
||||||
|
rtld_catch_notls = catch;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
- THREAD_SETMEM (THREAD_SELF, rtld_catch, catch);
|
||||||
|
+ THREAD_SETMEM (THREAD_SELF, rtld_catch_f, catch);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lossage while resolving the program's own symbols is always fatal. */
|
||||||
|
diff -rup a/nptl/descr.h b/nptl/descr.h
|
||||||
|
--- a/nptl/descr.h 2024-08-29 11:29:16.801811033 -0400
|
||||||
|
+++ b/nptl/descr.h 2024-08-29 11:48:56.547644398 -0400
|
||||||
|
@@ -164,6 +164,12 @@ struct pthread
|
||||||
|
void *__padding[24];
|
||||||
|
};
|
||||||
|
|
||||||
|
+#ifdef __x86_64__
|
||||||
|
+#define rtld_catch_f header.__padding[7]
|
||||||
|
+#else
|
||||||
|
+#define rtld_catch_f __padding[23]
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/* This descriptor's link on the GL (dl_stack_used) or
|
||||||
|
GL (dl_stack_user) list. */
|
||||||
|
list_t list;
|
||||||
|
@@ -396,9 +402,6 @@ struct pthread
|
||||||
|
masked.) */
|
||||||
|
sigset_t sigmask;
|
||||||
|
|
||||||
|
- /* Used by the exception handling implementation in the dynamic loader. */
|
||||||
|
- struct rtld_catch *rtld_catch;
|
||||||
|
-
|
||||||
|
/* Indicates whether is a C11 thread created by thrd_creat. */
|
||||||
|
bool c11;
|
||||||
|
|
||||||
|
@@ -432,6 +435,12 @@ struct pthread
|
||||||
|
+ sizeof ((struct pthread) {}.rseq_area))
|
||||||
|
} __attribute ((aligned (TCB_ALIGNMENT)));
|
||||||
|
|
||||||
|
+#ifdef __x86_64__
|
||||||
|
+_Static_assert (sizeof ((*(struct pthread *)0).header) > sizeof ((*(struct pthread *)0).__padding), "rtld_catch");
|
||||||
|
+#else
|
||||||
|
+_Static_assert (sizeof ((*(struct pthread *)0).header) < sizeof ((*(struct pthread *)0).__padding), "rtld_catch");
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
static inline bool
|
||||||
|
cancel_enabled_and_canceled (int value)
|
||||||
|
{
|
||||||
|
diff -rup a/sysdeps/mach/hurd/i386/tls.h b/sysdeps/mach/hurd/i386/tls.h
|
||||||
|
--- a/sysdeps/mach/hurd/i386/tls.h 2024-08-29 11:29:16.810811382 -0400
|
||||||
|
+++ b/sysdeps/mach/hurd/i386/tls.h 2024-08-29 11:35:45.262899113 -0400
|
||||||
|
@@ -50,7 +50,7 @@ typedef struct
|
||||||
|
struct hurd_sigstate *_hurd_sigstate;
|
||||||
|
|
||||||
|
/* Used by the exception handling implementation in the dynamic loader. */
|
||||||
|
- struct rtld_catch *rtld_catch;
|
||||||
|
+ struct rtld_catch *rtld_catch_f;
|
||||||
|
} tcbhead_t;
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,79 @@
|
|||||||
|
New test case to verify padding usage.
|
||||||
|
|
||||||
|
diff --git a/nptl/Makefile b/nptl/Makefile
|
||||||
|
index ff4d590f11c38277..9a56d34313d06444 100644
|
||||||
|
--- a/nptl/Makefile
|
||||||
|
+++ b/nptl/Makefile
|
||||||
|
@@ -319,6 +319,8 @@ tests-internal := tst-robustpi8 tst-rwlock19 tst-rwlock20 \
|
||||||
|
tst-barrier5 tst-signal7 tst-mutex8 tst-mutex8-static \
|
||||||
|
tst-mutexpi8 tst-mutexpi8-static \
|
||||||
|
tst-setgetname \
|
||||||
|
+ tst-nptl-padding \
|
||||||
|
+ # tests-internal
|
||||||
|
|
||||||
|
xtests = tst-setuid1 tst-setuid1-static tst-setuid2 \
|
||||||
|
tst-mutexpp1 tst-mutexpp6 tst-mutexpp10 tst-setgroups \
|
||||||
|
diff --git a/nptl/tst-nptl-padding.c b/nptl/tst-nptl-padding.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..5bb64f4a54335e36
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/nptl/tst-nptl-padding.c
|
||||||
|
@@ -0,0 +1,57 @@
|
||||||
|
+/* Downstream-only test for verifying that fields that have been
|
||||||
|
+ relocated into struct pthread padding actually use the padding.
|
||||||
|
+
|
||||||
|
+ At present, only rtld_catch (downstream: rtld_catch_f) has been
|
||||||
|
+ placed into padding. */
|
||||||
|
+
|
||||||
|
+#include <descr.h>
|
||||||
|
+#include <stddef.h>
|
||||||
|
+#include <stdint.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ struct pthread descr;
|
||||||
|
+
|
||||||
|
+ /* Mark the entire descriptor as used. */
|
||||||
|
+ memset (&descr, 0xff, sizeof (descr));
|
||||||
|
+
|
||||||
|
+ /* Mark the padding as unused. */
|
||||||
|
+#ifdef __x86_64__
|
||||||
|
+ /* Special case: Usable padding is in the header. */
|
||||||
|
+ memset (&descr.header.__padding, 0, sizeof (descr.header.__padding));
|
||||||
|
+#else
|
||||||
|
+ /* The padding should be directly adjacent to the first real
|
||||||
|
+ struct field. */
|
||||||
|
+ TEST_COMPARE (sizeof (descr.__padding), offsetof (struct pthread, list));
|
||||||
|
+
|
||||||
|
+ /* Clear the unused tail of the padding. */
|
||||||
|
+ {
|
||||||
|
+ char *base = (char *) &descr;
|
||||||
|
+ char *end_of_header = base + sizeof (descr.header);
|
||||||
|
+ char *end_of_padding = base + sizeof (descr.__padding);
|
||||||
|
+ memset (end_of_header, 0, end_of_padding - end_of_header);
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ /* These fields are not in padding and should remain marked as used. */
|
||||||
|
+ TEST_COMPARE (descr.header.gscope_flag, -1);
|
||||||
|
+ TEST_COMPARE ((intptr_t) descr.list.next, -1);
|
||||||
|
+ TEST_COMPARE ((intptr_t) descr.list.prev, -1);
|
||||||
|
+
|
||||||
|
+ /* But this field remains in padding. */
|
||||||
|
+ TEST_COMPARE ((intptr_t) descr.rtld_catch_f, 0);
|
||||||
|
+
|
||||||
|
+ /* Write to all padding-relocated fields below to show that they
|
||||||
|
+ have independent locations. */
|
||||||
|
+ struct rtld_catch *rtld_catch_dummy = (void *) "rtld_catch_dummy";
|
||||||
|
+ descr.rtld_catch_f = rtld_catch_dummy;
|
||||||
|
+
|
||||||
|
+ TEST_VERIFY (descr.rtld_catch_f == rtld_catch_dummy);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
|
@ -0,0 +1,51 @@
|
|||||||
|
commit 9b7651410375ec8848a1944992d663d514db4ba7
|
||||||
|
Author: Stefan Liebler <stli@linux.ibm.com>
|
||||||
|
Date: Thu Jul 11 11:28:53 2024 +0200
|
||||||
|
|
||||||
|
s390x: Fix segfault in wcsncmp [BZ #31934]
|
||||||
|
|
||||||
|
The z13/vector-optimized wcsncmp implementation segfaults if n=1
|
||||||
|
and there is only one character (equal on both strings) before
|
||||||
|
the page end. Then it loads and compares one character and misses
|
||||||
|
to check n again. The following load fails.
|
||||||
|
|
||||||
|
This patch removes the extra load and compare of the first character
|
||||||
|
and just start with the loop which uses vector-load-to-block-boundary.
|
||||||
|
This code-path also checks n.
|
||||||
|
|
||||||
|
With this patch both tests are passing:
|
||||||
|
- the simplified one mentioned in the bugzilla 31934
|
||||||
|
- the full one in Florian Weimer's patch:
|
||||||
|
"manual: Document a GNU extension for strncmp/wcsncmp"
|
||||||
|
(https://patchwork.sourceware.org/project/glibc/patch/874j9eml6y.fsf@oldenburg.str.redhat.com/):
|
||||||
|
On s390x-linux-gnu (z16), the new wcsncmp test fails due to bug 31934.
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/sysdeps/s390/wcsncmp-vx.S b/sysdeps/s390/wcsncmp-vx.S
|
||||||
|
index bf6dfa6bc2..8b081567a2 100644
|
||||||
|
--- a/sysdeps/s390/wcsncmp-vx.S
|
||||||
|
+++ b/sysdeps/s390/wcsncmp-vx.S
|
||||||
|
@@ -59,14 +59,7 @@ ENTRY(WCSNCMP_Z13)
|
||||||
|
sllg %r4,%r4,2 /* Convert character-count to byte-count. */
|
||||||
|
locgrne %r4,%r1 /* Use max byte-count, if bit 0/1 was one. */
|
||||||
|
|
||||||
|
- /* Check first character without vector load. */
|
||||||
|
- lghi %r5,4 /* current_len = 4 bytes. */
|
||||||
|
- /* Check s1/2[0]. */
|
||||||
|
- lt %r0,0(%r2)
|
||||||
|
- l %r1,0(%r3)
|
||||||
|
- je .Lend_cmp_one_char
|
||||||
|
- crjne %r0,%r1,.Lend_cmp_one_char
|
||||||
|
-
|
||||||
|
+ lghi %r5,0 /* current_len = 0 bytes. */
|
||||||
|
.Lloop:
|
||||||
|
vlbb %v17,0(%r5,%r3),6 /* Load s2 to block boundary. */
|
||||||
|
vlbb %v16,0(%r5,%r2),6 /* Load s1 to block boundary. */
|
||||||
|
@@ -167,7 +160,6 @@ ENTRY(WCSNCMP_Z13)
|
||||||
|
srl %r4,2 /* And convert it to character-index. */
|
||||||
|
vlgvf %r0,%v16,0(%r4) /* Load character-values. */
|
||||||
|
vlgvf %r1,%v17,0(%r4)
|
||||||
|
-.Lend_cmp_one_char:
|
||||||
|
cr %r0,%r1
|
||||||
|
je .Lend_equal
|
||||||
|
lghi %r2,1
|
@ -0,0 +1,248 @@
|
|||||||
|
commit 54252394c25ddf0062e288d4a6ab7a885f8ae009
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Thu Jun 27 16:26:56 2024 +0200
|
||||||
|
|
||||||
|
Enhanced test coverage for strncmp, wcsncmp
|
||||||
|
|
||||||
|
Add string/test-strncmp-nonarray and
|
||||||
|
wcsmbs/test-wcsncmp-nonarray.
|
||||||
|
|
||||||
|
This is the test that uncovered bug 31934. Test run time
|
||||||
|
is more than one minute on a fairly current system, so turn
|
||||||
|
these into xtests that do not run automatically.
|
||||||
|
|
||||||
|
Reviewed-by: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||||
|
|
||||||
|
diff -Nrup a/string/Makefile b/string/Makefile
|
||||||
|
--- a/string/Makefile 2024-09-03 11:42:30.396319962 -0400
|
||||||
|
+++ b/string/Makefile 2024-09-03 11:52:17.707438963 -0400
|
||||||
|
@@ -76,7 +76,10 @@ tests-unsupported += $(tests-translation
|
||||||
|
endif
|
||||||
|
|
||||||
|
# This test allocates a lot of memory and can run for a long time.
|
||||||
|
-xtests = tst-strcoll-overflow
|
||||||
|
+xtests += tst-strcoll-overflow
|
||||||
|
+
|
||||||
|
+# This test runs for a long time.
|
||||||
|
+xtests += test-strncmp-nonarray
|
||||||
|
|
||||||
|
# This test needs libdl.
|
||||||
|
ifeq (yes,$(build-shared))
|
||||||
|
diff -Nrup a/string/test-Xncmp-nonarray.c b/string/test-Xncmp-nonarray.c
|
||||||
|
--- a/string/test-Xncmp-nonarray.c 1969-12-31 19:00:00.000000000 -0500
|
||||||
|
+++ b/string/test-Xncmp-nonarray.c 2024-09-03 11:52:17.707438963 -0400
|
||||||
|
@@ -0,0 +1,183 @@
|
||||||
|
+/* Test non-array inputs to string comparison functions.
|
||||||
|
+ Copyright (C) 2024 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 skeleton file is included from string/test-strncmp-nonarray.c and
|
||||||
|
+ wcsmbs/test-wcsncmp-nonarray.c to test that reading of the arrays stops
|
||||||
|
+ at the first null character.
|
||||||
|
+
|
||||||
|
+ TEST_IDENTIFIER must be the test function identifier. TEST_NAME is
|
||||||
|
+ the same as a string.
|
||||||
|
+
|
||||||
|
+ CHAR must be defined as the character type. */
|
||||||
|
+
|
||||||
|
+#include <array_length.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/next_to_fault.h>
|
||||||
|
+#include <support/test-driver.h>
|
||||||
|
+#include <sys/param.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+
|
||||||
|
+/* Much shorter than test-Xnlen-nonarray.c because of deeply nested loops. */
|
||||||
|
+enum { buffer_length = 80 };
|
||||||
|
+
|
||||||
|
+/* The test buffer layout follows what is described test-Xnlen-nonarray.c,
|
||||||
|
+ except that there two buffers, left and right. The variables
|
||||||
|
+ a_count, zero_count, start_offset are all duplicated. */
|
||||||
|
+
|
||||||
|
+/* Return the maximum string length for a string that starts at
|
||||||
|
+ start_offset. */
|
||||||
|
+static int
|
||||||
|
+string_length (int a_count, int start_offset)
|
||||||
|
+{
|
||||||
|
+ if (start_offset == buffer_length || start_offset >= a_count)
|
||||||
|
+ return 0;
|
||||||
|
+ else
|
||||||
|
+ return a_count - start_offset;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* This is the valid maximum length argument computation for
|
||||||
|
+ strnlen/wcsnlen. See text-Xnlen-nonarray.c. */
|
||||||
|
+static int
|
||||||
|
+maximum_length (int start_offset, int zero_count)
|
||||||
|
+{
|
||||||
|
+ if (start_offset == buffer_length)
|
||||||
|
+ return 0;
|
||||||
|
+ else if (zero_count > 0)
|
||||||
|
+ /* Effectively unbounded, but we need to stop fairly low,
|
||||||
|
+ otherwise testing takes too long. */
|
||||||
|
+ return buffer_length + 32;
|
||||||
|
+ else
|
||||||
|
+ return buffer_length - start_offset;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+typedef __typeof (TEST_IDENTIFIER) *proto_t;
|
||||||
|
+
|
||||||
|
+#define TEST_MAIN
|
||||||
|
+#include "test-string.h"
|
||||||
|
+
|
||||||
|
+IMPL (TEST_IDENTIFIER, 1)
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+test_main (void)
|
||||||
|
+{
|
||||||
|
+ TEST_VERIFY_EXIT (sysconf (_SC_PAGESIZE) >= buffer_length);
|
||||||
|
+ test_init ();
|
||||||
|
+
|
||||||
|
+ struct support_next_to_fault left_ntf
|
||||||
|
+ = support_next_to_fault_allocate (buffer_length * sizeof (CHAR));
|
||||||
|
+ CHAR *left_buffer = (CHAR *) left_ntf.buffer;
|
||||||
|
+ struct support_next_to_fault right_ntf
|
||||||
|
+ = support_next_to_fault_allocate (buffer_length * sizeof (CHAR));
|
||||||
|
+ CHAR *right_buffer = (CHAR *) right_ntf.buffer;
|
||||||
|
+
|
||||||
|
+ FOR_EACH_IMPL (impl, 0)
|
||||||
|
+ {
|
||||||
|
+ printf ("info: testing %s\n", impl->name);
|
||||||
|
+ for (size_t i = 0; i < buffer_length; ++i)
|
||||||
|
+ left_buffer[i] = 'A';
|
||||||
|
+
|
||||||
|
+ for (int left_zero_count = 0; left_zero_count <= buffer_length;
|
||||||
|
+ ++left_zero_count)
|
||||||
|
+ {
|
||||||
|
+ if (left_zero_count > 0)
|
||||||
|
+ left_buffer[buffer_length - left_zero_count] = 0;
|
||||||
|
+ int left_a_count = buffer_length - left_zero_count;
|
||||||
|
+ for (size_t i = 0; i < buffer_length; ++i)
|
||||||
|
+ right_buffer[i] = 'A';
|
||||||
|
+ for (int right_zero_count = 0; right_zero_count <= buffer_length;
|
||||||
|
+ ++right_zero_count)
|
||||||
|
+ {
|
||||||
|
+ if (right_zero_count > 0)
|
||||||
|
+ right_buffer[buffer_length - right_zero_count] = 0;
|
||||||
|
+ int right_a_count = buffer_length - right_zero_count;
|
||||||
|
+ for (int left_start_offset = 0;
|
||||||
|
+ left_start_offset <= buffer_length;
|
||||||
|
+ ++left_start_offset)
|
||||||
|
+ {
|
||||||
|
+ CHAR *left_start_pointer = left_buffer + left_start_offset;
|
||||||
|
+ int left_maxlen
|
||||||
|
+ = maximum_length (left_start_offset, left_zero_count);
|
||||||
|
+ int left_length
|
||||||
|
+ = string_length (left_a_count, left_start_offset);
|
||||||
|
+ for (int right_start_offset = 0;
|
||||||
|
+ right_start_offset <= buffer_length;
|
||||||
|
+ ++right_start_offset)
|
||||||
|
+ {
|
||||||
|
+ CHAR *right_start_pointer
|
||||||
|
+ = right_buffer + right_start_offset;
|
||||||
|
+ int right_maxlen
|
||||||
|
+ = maximum_length (right_start_offset, right_zero_count);
|
||||||
|
+ int right_length
|
||||||
|
+ = string_length (right_a_count, right_start_offset);
|
||||||
|
+
|
||||||
|
+ /* Maximum length is modelled after strnlen/wcsnlen,
|
||||||
|
+ and must be valid for both pointer arguments at
|
||||||
|
+ the same time. */
|
||||||
|
+ int maxlen = MIN (left_maxlen, right_maxlen);
|
||||||
|
+
|
||||||
|
+ for (int length_argument = 0; length_argument <= maxlen;
|
||||||
|
+ ++length_argument)
|
||||||
|
+ {
|
||||||
|
+ if (test_verbose)
|
||||||
|
+ {
|
||||||
|
+ printf ("left: zero_count=%d"
|
||||||
|
+ " a_count=%d start_offset=%d\n",
|
||||||
|
+ left_zero_count, left_a_count,
|
||||||
|
+ left_start_offset);
|
||||||
|
+ printf ("right: zero_count=%d"
|
||||||
|
+ " a_count=%d start_offset=%d\n",
|
||||||
|
+ right_zero_count, right_a_count,
|
||||||
|
+ right_start_offset);
|
||||||
|
+ printf ("length argument: %d\n",
|
||||||
|
+ length_argument);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Effective lengths bounded by length argument.
|
||||||
|
+ The effective length determines the
|
||||||
|
+ outcome of the comparison. */
|
||||||
|
+ int left_effective
|
||||||
|
+ = MIN (left_length, length_argument);
|
||||||
|
+ int right_effective
|
||||||
|
+ = MIN (right_length, length_argument);
|
||||||
|
+ if (left_effective == right_effective)
|
||||||
|
+ TEST_COMPARE (CALL (impl,
|
||||||
|
+ left_start_pointer,
|
||||||
|
+ right_start_pointer,
|
||||||
|
+ length_argument), 0);
|
||||||
|
+ else if (left_effective < right_effective)
|
||||||
|
+ TEST_COMPARE (CALL (impl,
|
||||||
|
+ left_start_pointer,
|
||||||
|
+ right_start_pointer,
|
||||||
|
+ length_argument) < 0, 1);
|
||||||
|
+ else
|
||||||
|
+ TEST_COMPARE (CALL (impl,
|
||||||
|
+ left_start_pointer,
|
||||||
|
+ right_start_pointer,
|
||||||
|
+ length_argument) > 0, 1);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff -Nrup a/string/test-strncmp-nonarray.c b/string/test-strncmp-nonarray.c
|
||||||
|
--- a/string/test-strncmp-nonarray.c 1969-12-31 19:00:00.000000000 -0500
|
||||||
|
+++ b/string/test-strncmp-nonarray.c 2024-09-03 11:52:17.707438963 -0400
|
||||||
|
@@ -0,0 +1,4 @@
|
||||||
|
+#define TEST_IDENTIFIER strncmp
|
||||||
|
+#define TEST_NAME "strncmp"
|
||||||
|
+typedef char CHAR;
|
||||||
|
+#include "test-Xncmp-nonarray.c"
|
||||||
|
diff -Nrup a/wcsmbs/Makefile b/wcsmbs/Makefile
|
||||||
|
--- a/wcsmbs/Makefile 2024-09-03 11:42:30.398319976 -0400
|
||||||
|
+++ b/wcsmbs/Makefile 2024-09-03 11:53:44.806049806 -0400
|
||||||
|
@@ -56,6 +56,10 @@ tests := tst-wcstof wcsmbs-tst1 tst-wcsn
|
||||||
|
$(addprefix test-,$(strop-tests)) tst-mbstowcs \
|
||||||
|
test-wcsdup
|
||||||
|
|
||||||
|
+# This test runs for a long time.
|
||||||
|
+xtests += test-wcsncmp-nonarray
|
||||||
|
+
|
||||||
|
+
|
||||||
|
include ../Rules
|
||||||
|
|
||||||
|
ifeq ($(run-built-tests),yes)
|
||||||
|
diff -Nrup a/wcsmbs/test-wcsncmp-nonarray.c b/wcsmbs/test-wcsncmp-nonarray.c
|
||||||
|
--- a/wcsmbs/test-wcsncmp-nonarray.c 1969-12-31 19:00:00.000000000 -0500
|
||||||
|
+++ b/wcsmbs/test-wcsncmp-nonarray.c 2024-09-03 11:52:17.708438970 -0400
|
||||||
|
@@ -0,0 +1,5 @@
|
||||||
|
+#include <wchar.h>
|
||||||
|
+#define TEST_IDENTIFIER wcsncmp
|
||||||
|
+#define TEST_NAME "wcsncmp"
|
||||||
|
+typedef wchar_t CHAR;
|
||||||
|
+#include "../string/test-Xncmp-nonarray.c"
|
@ -0,0 +1,327 @@
|
|||||||
|
commit 2f47198b04a02097f438ecb765306fa39568a006
|
||||||
|
Author: Rajalakshmi Srinivasaraghavan <rajis@linux.ibm.com>
|
||||||
|
Date: Fri Dec 2 14:26:41 2022 -0600
|
||||||
|
|
||||||
|
powerpc64: Remove old strncmp optimization
|
||||||
|
|
||||||
|
This patch cleans up the power4 strncmp optimization for powerpc64 which
|
||||||
|
is unlikely to be used anywhere.
|
||||||
|
|
||||||
|
Tested on ppc64le with and without --disable-multi-arch flag.
|
||||||
|
|
||||||
|
Reviewed-by: Paul E. Murphy <murphyp@linux.ibm.com>
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
sysdeps/powerpc/powerpc64/multiarch/strncmp-power4.S
|
||||||
|
sysdeps/powerpc/powerpc64/power4/strncmp.S
|
||||||
|
(copyright year changes upstream)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
|
||||||
|
index 626845a43c4e8ded..5b20dab108de14ab 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
|
||||||
|
@@ -12,8 +12,7 @@ sysdep_routines += memcpy-power8-cached memcpy-power7 memcpy-a2 memcpy-power6 \
|
||||||
|
strnlen-power8 strnlen-power7 strnlen-ppc64 \
|
||||||
|
strcasecmp-power7 strcasecmp_l-power7 \
|
||||||
|
strncase-power7 strncase_l-power7 \
|
||||||
|
- strncmp-power8 strncmp-power7 \
|
||||||
|
- strncmp-power4 strncmp-ppc64 \
|
||||||
|
+ strncmp-power8 strncmp-power7 strncmp-ppc64 \
|
||||||
|
strchr-power8 strchr-power7 strchr-ppc64 \
|
||||||
|
strchrnul-power8 strchrnul-power7 strchrnul-ppc64 \
|
||||||
|
strcpy-power8 strcpy-power7 strcpy-ppc64 stpcpy-power8 \
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
|
||||||
|
index 7b83aa7b8ff28bb7..914e7d5e28a98b5d 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
|
||||||
|
@@ -177,8 +177,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
__strncmp_power8)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strncmp, hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
__strncmp_power7)
|
||||||
|
- IFUNC_IMPL_ADD (array, i, strncmp, hwcap & PPC_FEATURE_POWER4,
|
||||||
|
- __strncmp_power4)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strncmp, 1,
|
||||||
|
__strncmp_ppc))
|
||||||
|
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncmp-power4.S b/sysdeps/powerpc/powerpc64/multiarch/strncmp-power4.S
|
||||||
|
deleted file mode 100644
|
||||||
|
index 6ead3b6374749e6a..0000000000000000
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strncmp-power4.S
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,23 +0,0 @@
|
||||||
|
-/* Copyright (C) 2013-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 STRNCMP __strncmp_power4
|
||||||
|
-
|
||||||
|
-#undef libc_hidden_builtin_def
|
||||||
|
-#define libc_hidden_builtin_def(name)
|
||||||
|
-
|
||||||
|
-#include <sysdeps/powerpc/powerpc64/power4/strncmp.S>
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncmp.c b/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
|
||||||
|
index 2d2112285445a450..275a558e4afa7d61 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
|
||||||
|
@@ -26,7 +26,6 @@
|
||||||
|
# include "init-arch.h"
|
||||||
|
|
||||||
|
extern __typeof (strncmp) __strncmp_ppc attribute_hidden;
|
||||||
|
-extern __typeof (strncmp) __strncmp_power4 attribute_hidden;
|
||||||
|
extern __typeof (strncmp) __strncmp_power7 attribute_hidden;
|
||||||
|
extern __typeof (strncmp) __strncmp_power8 attribute_hidden;
|
||||||
|
# ifdef __LITTLE_ENDIAN__
|
||||||
|
@@ -46,7 +45,5 @@ libc_ifunc_redirected (__redirect_strncmp, strncmp,
|
||||||
|
? __strncmp_power8
|
||||||
|
: (hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
? __strncmp_power7
|
||||||
|
- : (hwcap & PPC_FEATURE_POWER4)
|
||||||
|
- ? __strncmp_power4
|
||||||
|
- : __strncmp_ppc);
|
||||||
|
+ : __strncmp_ppc);
|
||||||
|
#endif
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/power4/strncmp.S b/sysdeps/powerpc/powerpc64/power4/strncmp.S
|
||||||
|
deleted file mode 100644
|
||||||
|
index cf5f4e5fb8fb2522..0000000000000000
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/power4/strncmp.S
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,225 +0,0 @@
|
||||||
|
-/* Optimized strcmp implementation for PowerPC64.
|
||||||
|
- Copyright (C) 2003-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 <sysdep.h>
|
||||||
|
-
|
||||||
|
-#ifndef STRNCMP
|
||||||
|
-# define STRNCMP strncmp
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
-/* See strlen.s for comments on how the end-of-string testing works. */
|
||||||
|
-
|
||||||
|
-/* int [r3] strncmp (const char *s1 [r3], const char *s2 [r4], size_t size [r5]) */
|
||||||
|
-
|
||||||
|
-ENTRY_TOCLESS (STRNCMP, 4)
|
||||||
|
- CALL_MCOUNT 3
|
||||||
|
-
|
||||||
|
-#define rTMP2 r0
|
||||||
|
-#define rRTN r3
|
||||||
|
-#define rSTR1 r3 /* first string arg */
|
||||||
|
-#define rSTR2 r4 /* second string arg */
|
||||||
|
-#define rN r5 /* max string length */
|
||||||
|
-#define rWORD1 r6 /* current word in s1 */
|
||||||
|
-#define rWORD2 r7 /* current word in s2 */
|
||||||
|
-#define rWORD3 r10
|
||||||
|
-#define rWORD4 r11
|
||||||
|
-#define rFEFE r8 /* constant 0xfefefefefefefeff (-0x0101010101010101) */
|
||||||
|
-#define r7F7F r9 /* constant 0x7f7f7f7f7f7f7f7f */
|
||||||
|
-#define rNEG r10 /* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */
|
||||||
|
-#define rBITDIF r11 /* bits that differ in s1 & s2 words */
|
||||||
|
-#define rTMP r12
|
||||||
|
-
|
||||||
|
- dcbt 0,rSTR1
|
||||||
|
- or rTMP, rSTR2, rSTR1
|
||||||
|
- lis r7F7F, 0x7f7f
|
||||||
|
- dcbt 0,rSTR2
|
||||||
|
- clrldi. rTMP, rTMP, 61
|
||||||
|
- cmpldi cr1, rN, 0
|
||||||
|
- lis rFEFE, -0x101
|
||||||
|
- bne L(unaligned)
|
||||||
|
-/* We are doubleword aligned so set up for two loops. first a double word
|
||||||
|
- loop, then fall into the byte loop if any residual. */
|
||||||
|
- srdi. rTMP, rN, 3
|
||||||
|
- clrldi rN, rN, 61
|
||||||
|
- addi rFEFE, rFEFE, -0x101
|
||||||
|
- addi r7F7F, r7F7F, 0x7f7f
|
||||||
|
- cmpldi cr1, rN, 0
|
||||||
|
- beq L(unaligned)
|
||||||
|
-
|
||||||
|
- mtctr rTMP /* Power4 wants mtctr 1st in dispatch group. */
|
||||||
|
- ld rWORD1, 0(rSTR1)
|
||||||
|
- ld rWORD2, 0(rSTR2)
|
||||||
|
- sldi rTMP, rFEFE, 32
|
||||||
|
- insrdi r7F7F, r7F7F, 32, 0
|
||||||
|
- add rFEFE, rFEFE, rTMP
|
||||||
|
- b L(g1)
|
||||||
|
-
|
||||||
|
-L(g0):
|
||||||
|
- ldu rWORD1, 8(rSTR1)
|
||||||
|
- bne- cr1, L(different)
|
||||||
|
- ldu rWORD2, 8(rSTR2)
|
||||||
|
-L(g1): add rTMP, rFEFE, rWORD1
|
||||||
|
- nor rNEG, r7F7F, rWORD1
|
||||||
|
- bdz L(tail)
|
||||||
|
- and. rTMP, rTMP, rNEG
|
||||||
|
- cmpd cr1, rWORD1, rWORD2
|
||||||
|
- beq+ L(g0)
|
||||||
|
-
|
||||||
|
-/* OK. We've hit the end of the string. We need to be careful that
|
||||||
|
- we don't compare two strings as different because of gunk beyond
|
||||||
|
- the end of the strings... */
|
||||||
|
-
|
||||||
|
-#ifdef __LITTLE_ENDIAN__
|
||||||
|
-L(endstring):
|
||||||
|
- addi rTMP2, rTMP, -1
|
||||||
|
- beq cr1, L(equal)
|
||||||
|
- andc rTMP2, rTMP2, rTMP
|
||||||
|
- rldimi rTMP2, rTMP2, 1, 0
|
||||||
|
- and rWORD2, rWORD2, rTMP2 /* Mask off gunk. */
|
||||||
|
- and rWORD1, rWORD1, rTMP2
|
||||||
|
- cmpd cr1, rWORD1, rWORD2
|
||||||
|
- beq cr1, L(equal)
|
||||||
|
- xor rBITDIF, rWORD1, rWORD2 /* rBITDIF has bits that differ. */
|
||||||
|
- neg rNEG, rBITDIF
|
||||||
|
- and rNEG, rNEG, rBITDIF /* rNEG has LS bit that differs. */
|
||||||
|
- cntlzd rNEG, rNEG /* bitcount of the bit. */
|
||||||
|
- andi. rNEG, rNEG, 56 /* bitcount to LS byte that differs. */
|
||||||
|
- sld rWORD1, rWORD1, rNEG /* shift left to clear MS bytes. */
|
||||||
|
- sld rWORD2, rWORD2, rNEG
|
||||||
|
- xor. rBITDIF, rWORD1, rWORD2
|
||||||
|
- sub rRTN, rWORD1, rWORD2
|
||||||
|
- blt- L(highbit)
|
||||||
|
- sradi rRTN, rRTN, 63 /* must return an int. */
|
||||||
|
- ori rRTN, rRTN, 1
|
||||||
|
- blr
|
||||||
|
-L(equal):
|
||||||
|
- li rRTN, 0
|
||||||
|
- blr
|
||||||
|
-
|
||||||
|
-L(different):
|
||||||
|
- ld rWORD1, -8(rSTR1)
|
||||||
|
- xor rBITDIF, rWORD1, rWORD2 /* rBITDIF has bits that differ. */
|
||||||
|
- neg rNEG, rBITDIF
|
||||||
|
- and rNEG, rNEG, rBITDIF /* rNEG has LS bit that differs. */
|
||||||
|
- cntlzd rNEG, rNEG /* bitcount of the bit. */
|
||||||
|
- andi. rNEG, rNEG, 56 /* bitcount to LS byte that differs. */
|
||||||
|
- sld rWORD1, rWORD1, rNEG /* shift left to clear MS bytes. */
|
||||||
|
- sld rWORD2, rWORD2, rNEG
|
||||||
|
- xor. rBITDIF, rWORD1, rWORD2
|
||||||
|
- sub rRTN, rWORD1, rWORD2
|
||||||
|
- blt- L(highbit)
|
||||||
|
- sradi rRTN, rRTN, 63
|
||||||
|
- ori rRTN, rRTN, 1
|
||||||
|
- blr
|
||||||
|
-L(highbit):
|
||||||
|
- sradi rRTN, rWORD2, 63
|
||||||
|
- ori rRTN, rRTN, 1
|
||||||
|
- blr
|
||||||
|
-
|
||||||
|
-#else
|
||||||
|
-L(endstring):
|
||||||
|
- and rTMP, r7F7F, rWORD1
|
||||||
|
- beq cr1, L(equal)
|
||||||
|
- add rTMP, rTMP, r7F7F
|
||||||
|
- xor. rBITDIF, rWORD1, rWORD2
|
||||||
|
- andc rNEG, rNEG, rTMP
|
||||||
|
- blt- L(highbit)
|
||||||
|
- cntlzd rBITDIF, rBITDIF
|
||||||
|
- cntlzd rNEG, rNEG
|
||||||
|
- addi rNEG, rNEG, 7
|
||||||
|
- cmpd cr1, rNEG, rBITDIF
|
||||||
|
- sub rRTN, rWORD1, rWORD2
|
||||||
|
- blt- cr1, L(equal)
|
||||||
|
- sradi rRTN, rRTN, 63 /* must return an int. */
|
||||||
|
- ori rRTN, rRTN, 1
|
||||||
|
- blr
|
||||||
|
-L(equal):
|
||||||
|
- li rRTN, 0
|
||||||
|
- blr
|
||||||
|
-
|
||||||
|
-L(different):
|
||||||
|
- ld rWORD1, -8(rSTR1)
|
||||||
|
- xor. rBITDIF, rWORD1, rWORD2
|
||||||
|
- sub rRTN, rWORD1, rWORD2
|
||||||
|
- blt- L(highbit)
|
||||||
|
- sradi rRTN, rRTN, 63
|
||||||
|
- ori rRTN, rRTN, 1
|
||||||
|
- blr
|
||||||
|
-L(highbit):
|
||||||
|
- sradi rRTN, rWORD2, 63
|
||||||
|
- ori rRTN, rRTN, 1
|
||||||
|
- blr
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
-/* Oh well. In this case, we just do a byte-by-byte comparison. */
|
||||||
|
- .align 4
|
||||||
|
-L(tail):
|
||||||
|
- and. rTMP, rTMP, rNEG
|
||||||
|
- cmpd cr1, rWORD1, rWORD2
|
||||||
|
- bne- L(endstring)
|
||||||
|
- addi rSTR1, rSTR1, 8
|
||||||
|
- bne- cr1, L(different)
|
||||||
|
- addi rSTR2, rSTR2, 8
|
||||||
|
- cmpldi cr1, rN, 0
|
||||||
|
-L(unaligned):
|
||||||
|
- mtctr rN /* Power4 wants mtctr 1st in dispatch group */
|
||||||
|
- ble cr1, L(ux)
|
||||||
|
-L(uz):
|
||||||
|
- lbz rWORD1, 0(rSTR1)
|
||||||
|
- lbz rWORD2, 0(rSTR2)
|
||||||
|
- .align 4
|
||||||
|
-L(u1):
|
||||||
|
- cmpdi cr1, rWORD1, 0
|
||||||
|
- bdz L(u4)
|
||||||
|
- cmpd rWORD1, rWORD2
|
||||||
|
- beq- cr1, L(u4)
|
||||||
|
- bne- L(u4)
|
||||||
|
- lbzu rWORD3, 1(rSTR1)
|
||||||
|
- lbzu rWORD4, 1(rSTR2)
|
||||||
|
- cmpdi cr1, rWORD3, 0
|
||||||
|
- bdz L(u3)
|
||||||
|
- cmpd rWORD3, rWORD4
|
||||||
|
- beq- cr1, L(u3)
|
||||||
|
- bne- L(u3)
|
||||||
|
- lbzu rWORD1, 1(rSTR1)
|
||||||
|
- lbzu rWORD2, 1(rSTR2)
|
||||||
|
- cmpdi cr1, rWORD1, 0
|
||||||
|
- bdz L(u4)
|
||||||
|
- cmpd rWORD1, rWORD2
|
||||||
|
- beq- cr1, L(u4)
|
||||||
|
- bne- L(u4)
|
||||||
|
- lbzu rWORD3, 1(rSTR1)
|
||||||
|
- lbzu rWORD4, 1(rSTR2)
|
||||||
|
- cmpdi cr1, rWORD3, 0
|
||||||
|
- bdz L(u3)
|
||||||
|
- cmpd rWORD3, rWORD4
|
||||||
|
- beq- cr1, L(u3)
|
||||||
|
- bne- L(u3)
|
||||||
|
- lbzu rWORD1, 1(rSTR1)
|
||||||
|
- lbzu rWORD2, 1(rSTR2)
|
||||||
|
- b L(u1)
|
||||||
|
-
|
||||||
|
-L(u3): sub rRTN, rWORD3, rWORD4
|
||||||
|
- blr
|
||||||
|
-L(u4): sub rRTN, rWORD1, rWORD2
|
||||||
|
- blr
|
||||||
|
-L(ux):
|
||||||
|
- li rRTN, 0
|
||||||
|
- blr
|
||||||
|
-END (STRNCMP)
|
||||||
|
-libc_hidden_builtin_def (strncmp)
|
@ -0,0 +1,595 @@
|
|||||||
|
commit 92fdb11ae7aa1ab6b18622670ea702205cd6fdc5
|
||||||
|
Author: Adhemerval Zanella Netto <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Tue Feb 28 14:23:59 2023 -0300
|
||||||
|
|
||||||
|
powerpc: Remove powerpc64 strncmp variants
|
||||||
|
|
||||||
|
The default, and power7 implementation just adds word aligned
|
||||||
|
access when inputs have the same aligment. The unaligned case
|
||||||
|
is still done by byte operations.
|
||||||
|
|
||||||
|
This is already covered by the generic implementation, which also add
|
||||||
|
the unaligned input optimization.
|
||||||
|
|
||||||
|
Checked on powerpc64-linux-gnu built without multi-arch for powerpc64,
|
||||||
|
power7, power8, and power9 (build for le).
|
||||||
|
Reviewed-by: Rajalakshmi Srinivasaraghavan <rajis@linux.ibm.com>
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
sysdeps/powerpc/powerpc64/multiarch/strncmp-power7.S
|
||||||
|
sysdeps/powerpc/powerpc64/multiarch/strncmp-ppc64.S
|
||||||
|
sysdeps/powerpc/powerpc64/power7/strncmp.S
|
||||||
|
sysdeps/powerpc/powerpc64/strncmp.S
|
||||||
|
(copyright year changes upstream)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
|
||||||
|
index 5b20dab108de14ab..0ee7ce39d6470d80 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
|
||||||
|
@@ -12,7 +12,7 @@ sysdep_routines += memcpy-power8-cached memcpy-power7 memcpy-a2 memcpy-power6 \
|
||||||
|
strnlen-power8 strnlen-power7 strnlen-ppc64 \
|
||||||
|
strcasecmp-power7 strcasecmp_l-power7 \
|
||||||
|
strncase-power7 strncase_l-power7 \
|
||||||
|
- strncmp-power8 strncmp-power7 strncmp-ppc64 \
|
||||||
|
+ strncmp-power8 strncmp-ppc64 \
|
||||||
|
strchr-power8 strchr-power7 strchr-ppc64 \
|
||||||
|
strchrnul-power8 strchrnul-power7 strchrnul-ppc64 \
|
||||||
|
strcpy-power8 strcpy-power7 strcpy-ppc64 stpcpy-power8 \
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
|
||||||
|
index 914e7d5e28a98b5d..2c84d287ee76a7ea 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
|
||||||
|
@@ -175,8 +175,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
|
||||||
|
#endif
|
||||||
|
IFUNC_IMPL_ADD (array, i, strncmp, hwcap2 & PPC_FEATURE2_ARCH_2_07,
|
||||||
|
__strncmp_power8)
|
||||||
|
- IFUNC_IMPL_ADD (array, i, strncmp, hwcap & PPC_FEATURE_ARCH_2_06,
|
||||||
|
- __strncmp_power7)
|
||||||
|
IFUNC_IMPL_ADD (array, i, strncmp, 1,
|
||||||
|
__strncmp_ppc))
|
||||||
|
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncmp-power7.S b/sysdeps/powerpc/powerpc64/multiarch/strncmp-power7.S
|
||||||
|
deleted file mode 100644
|
||||||
|
index 8282ff076c9e00ce..0000000000000000
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strncmp-power7.S
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,23 +0,0 @@
|
||||||
|
-/* Copyright (C) 2013-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 STRNCMP __strncmp_power7
|
||||||
|
-
|
||||||
|
-#undef libc_hidden_builtin_def
|
||||||
|
-#define libc_hidden_builtin_def(name)
|
||||||
|
-
|
||||||
|
-#include <sysdeps/powerpc/powerpc64/power7/strncmp.S>
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncmp-ppc64.S b/sysdeps/powerpc/powerpc64/multiarch/strncmp-ppc64.S
|
||||||
|
deleted file mode 100644
|
||||||
|
index c6f325650c9ace3b..0000000000000000
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strncmp-ppc64.S
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,26 +0,0 @@
|
||||||
|
-/* Copyright (C) 2013-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/>. */
|
||||||
|
-
|
||||||
|
-#if defined SHARED && IS_IN (libc)
|
||||||
|
-# define STRNCMP __strncmp_ppc
|
||||||
|
-
|
||||||
|
-# undef libc_hidden_builtin_def
|
||||||
|
-# define libc_hidden_builtin_def(name) \
|
||||||
|
- .globl __GI_strncmp; __GI_strncmp = __strncmp_ppc
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
-#include <sysdeps/powerpc/powerpc64/strncmp.S>
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncmp-ppc64.c b/sysdeps/powerpc/powerpc64/multiarch/strncmp-ppc64.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..09cc009a913ed169
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strncmp-ppc64.c
|
||||||
|
@@ -0,0 +1,7 @@
|
||||||
|
+#if defined SHARED && IS_IN (libc)
|
||||||
|
+# define STRNCMP __strncmp_ppc
|
||||||
|
+# undef libc_hidden_builtin_def
|
||||||
|
+# define libc_hidden_builtin_def(name) \
|
||||||
|
+ __hidden_ver1 (__strncmp_ppc, __GI_strncmp, __strncmp_ppc);
|
||||||
|
+#endif
|
||||||
|
+#include <string/strncmp.c>
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncmp.c b/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
|
||||||
|
index 275a558e4afa7d61..df2c0707a919ad79 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
|
||||||
|
@@ -26,7 +26,6 @@
|
||||||
|
# include "init-arch.h"
|
||||||
|
|
||||||
|
extern __typeof (strncmp) __strncmp_ppc attribute_hidden;
|
||||||
|
-extern __typeof (strncmp) __strncmp_power7 attribute_hidden;
|
||||||
|
extern __typeof (strncmp) __strncmp_power8 attribute_hidden;
|
||||||
|
# ifdef __LITTLE_ENDIAN__
|
||||||
|
extern __typeof (strncmp) __strncmp_power9 attribute_hidden;
|
||||||
|
@@ -43,7 +42,5 @@ libc_ifunc_redirected (__redirect_strncmp, strncmp,
|
||||||
|
# endif
|
||||||
|
(hwcap2 & PPC_FEATURE2_ARCH_2_07)
|
||||||
|
? __strncmp_power8
|
||||||
|
- : (hwcap & PPC_FEATURE_ARCH_2_06)
|
||||||
|
- ? __strncmp_power7
|
||||||
|
- : __strncmp_ppc);
|
||||||
|
+ : __strncmp_ppc);
|
||||||
|
#endif
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/power7/strncmp.S b/sysdeps/powerpc/powerpc64/power7/strncmp.S
|
||||||
|
deleted file mode 100644
|
||||||
|
index d91aeb6077a558f2..0000000000000000
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/power7/strncmp.S
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,228 +0,0 @@
|
||||||
|
-/* Optimized strcmp implementation for POWER7/PowerPC64.
|
||||||
|
- Copyright (C) 2010-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 <sysdep.h>
|
||||||
|
-
|
||||||
|
-#ifndef STRNCMP
|
||||||
|
-# define STRNCMP strncmp
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
-/* See strlen.s for comments on how the end-of-string testing works. */
|
||||||
|
-
|
||||||
|
-/* int [r3] strncmp (const char *s1 [r3],
|
||||||
|
- const char *s2 [r4],
|
||||||
|
- size_t size [r5]) */
|
||||||
|
-
|
||||||
|
- .machine power7
|
||||||
|
-ENTRY_TOCLESS (STRNCMP, 5)
|
||||||
|
- CALL_MCOUNT 3
|
||||||
|
-
|
||||||
|
-#define rTMP2 r0
|
||||||
|
-#define rRTN r3
|
||||||
|
-#define rSTR1 r3 /* first string arg */
|
||||||
|
-#define rSTR2 r4 /* second string arg */
|
||||||
|
-#define rN r5 /* max string length */
|
||||||
|
-#define rWORD1 r6 /* current word in s1 */
|
||||||
|
-#define rWORD2 r7 /* current word in s2 */
|
||||||
|
-#define rWORD3 r10
|
||||||
|
-#define rWORD4 r11
|
||||||
|
-#define rFEFE r8 /* constant 0xfefefefefefefeff (-0x0101010101010101) */
|
||||||
|
-#define r7F7F r9 /* constant 0x7f7f7f7f7f7f7f7f */
|
||||||
|
-#define rNEG r10 /* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */
|
||||||
|
-#define rBITDIF r11 /* bits that differ in s1 & s2 words */
|
||||||
|
-#define rTMP r12
|
||||||
|
-
|
||||||
|
- dcbt 0,rSTR1
|
||||||
|
- nop
|
||||||
|
- or rTMP,rSTR2,rSTR1
|
||||||
|
- lis r7F7F,0x7f7f
|
||||||
|
- dcbt 0,rSTR2
|
||||||
|
- nop
|
||||||
|
- clrldi. rTMP,rTMP,61
|
||||||
|
- cmpldi cr1,rN,0
|
||||||
|
- lis rFEFE,-0x101
|
||||||
|
- bne L(unaligned)
|
||||||
|
-/* We are doubleword aligned so set up for two loops. first a double word
|
||||||
|
- loop, then fall into the byte loop if any residual. */
|
||||||
|
- srdi. rTMP,rN,3
|
||||||
|
- clrldi rN,rN,61
|
||||||
|
- addi rFEFE,rFEFE,-0x101
|
||||||
|
- addi r7F7F,r7F7F,0x7f7f
|
||||||
|
- cmpldi cr1,rN,0
|
||||||
|
- beq L(unaligned)
|
||||||
|
-
|
||||||
|
- mtctr rTMP
|
||||||
|
- ld rWORD1,0(rSTR1)
|
||||||
|
- ld rWORD2,0(rSTR2)
|
||||||
|
- sldi rTMP,rFEFE,32
|
||||||
|
- insrdi r7F7F,r7F7F,32,0
|
||||||
|
- add rFEFE,rFEFE,rTMP
|
||||||
|
- b L(g1)
|
||||||
|
-
|
||||||
|
-L(g0):
|
||||||
|
- ldu rWORD1,8(rSTR1)
|
||||||
|
- bne cr1,L(different)
|
||||||
|
- ldu rWORD2,8(rSTR2)
|
||||||
|
-L(g1): add rTMP,rFEFE,rWORD1
|
||||||
|
- nor rNEG,r7F7F,rWORD1
|
||||||
|
- bdz L(tail)
|
||||||
|
- and. rTMP,rTMP,rNEG
|
||||||
|
- cmpd cr1,rWORD1,rWORD2
|
||||||
|
- beq L(g0)
|
||||||
|
-
|
||||||
|
-/* OK. We've hit the end of the string. We need to be careful that
|
||||||
|
- we don't compare two strings as different because of gunk beyond
|
||||||
|
- the end of the strings... */
|
||||||
|
-
|
||||||
|
-#ifdef __LITTLE_ENDIAN__
|
||||||
|
-L(endstring):
|
||||||
|
- addi rTMP2, rTMP, -1
|
||||||
|
- beq cr1, L(equal)
|
||||||
|
- andc rTMP2, rTMP2, rTMP
|
||||||
|
- rldimi rTMP2, rTMP2, 1, 0
|
||||||
|
- and rWORD2, rWORD2, rTMP2 /* Mask off gunk. */
|
||||||
|
- and rWORD1, rWORD1, rTMP2
|
||||||
|
- cmpd cr1, rWORD1, rWORD2
|
||||||
|
- beq cr1, L(equal)
|
||||||
|
- cmpb rBITDIF, rWORD1, rWORD2 /* 0xff on equal bytes. */
|
||||||
|
- addi rNEG, rBITDIF, 1
|
||||||
|
- orc rNEG, rNEG, rBITDIF /* 0's below LS differing byte. */
|
||||||
|
- sldi rNEG, rNEG, 8 /* 1's above LS differing byte. */
|
||||||
|
- andc rWORD1, rWORD1, rNEG /* mask off MS bytes. */
|
||||||
|
- andc rWORD2, rWORD2, rNEG
|
||||||
|
- xor. rBITDIF, rWORD1, rWORD2
|
||||||
|
- sub rRTN, rWORD1, rWORD2
|
||||||
|
- blt L(highbit)
|
||||||
|
- sradi rRTN, rRTN, 63 /* must return an int. */
|
||||||
|
- ori rRTN, rRTN, 1
|
||||||
|
- blr
|
||||||
|
-L(equal):
|
||||||
|
- li rRTN, 0
|
||||||
|
- blr
|
||||||
|
-
|
||||||
|
-L(different):
|
||||||
|
- ld rWORD1, -8(rSTR1)
|
||||||
|
- cmpb rBITDIF, rWORD1, rWORD2 /* 0xff on equal bytes. */
|
||||||
|
- addi rNEG, rBITDIF, 1
|
||||||
|
- orc rNEG, rNEG, rBITDIF /* 0's below LS differing byte. */
|
||||||
|
- sldi rNEG, rNEG, 8 /* 1's above LS differing byte. */
|
||||||
|
- andc rWORD1, rWORD1, rNEG /* mask off MS bytes. */
|
||||||
|
- andc rWORD2, rWORD2, rNEG
|
||||||
|
- xor. rBITDIF, rWORD1, rWORD2
|
||||||
|
- sub rRTN, rWORD1, rWORD2
|
||||||
|
- blt L(highbit)
|
||||||
|
- sradi rRTN, rRTN, 63
|
||||||
|
- ori rRTN, rRTN, 1
|
||||||
|
- blr
|
||||||
|
-L(highbit):
|
||||||
|
- sradi rRTN, rWORD2, 63
|
||||||
|
- ori rRTN, rRTN, 1
|
||||||
|
- blr
|
||||||
|
-
|
||||||
|
-#else
|
||||||
|
-L(endstring):
|
||||||
|
- and rTMP,r7F7F,rWORD1
|
||||||
|
- beq cr1,L(equal)
|
||||||
|
- add rTMP,rTMP,r7F7F
|
||||||
|
- xor. rBITDIF,rWORD1,rWORD2
|
||||||
|
- andc rNEG,rNEG,rTMP
|
||||||
|
- blt L(highbit)
|
||||||
|
- cntlzd rBITDIF,rBITDIF
|
||||||
|
- cntlzd rNEG,rNEG
|
||||||
|
- addi rNEG,rNEG,7
|
||||||
|
- cmpd cr1,rNEG,rBITDIF
|
||||||
|
- sub rRTN,rWORD1,rWORD2
|
||||||
|
- blt cr1,L(equal)
|
||||||
|
- sradi rRTN,rRTN,63 /* must return an int. */
|
||||||
|
- ori rRTN,rRTN,1
|
||||||
|
- blr
|
||||||
|
-L(equal):
|
||||||
|
- li rRTN,0
|
||||||
|
- blr
|
||||||
|
-
|
||||||
|
-L(different):
|
||||||
|
- ld rWORD1,-8(rSTR1)
|
||||||
|
- xor. rBITDIF,rWORD1,rWORD2
|
||||||
|
- sub rRTN,rWORD1,rWORD2
|
||||||
|
- blt L(highbit)
|
||||||
|
- sradi rRTN,rRTN,63
|
||||||
|
- ori rRTN,rRTN,1
|
||||||
|
- blr
|
||||||
|
-L(highbit):
|
||||||
|
- sradi rRTN,rWORD2,63
|
||||||
|
- ori rRTN,rRTN,1
|
||||||
|
- blr
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
-/* Oh well. In this case, we just do a byte-by-byte comparison. */
|
||||||
|
- .align 4
|
||||||
|
-L(tail):
|
||||||
|
- and. rTMP,rTMP,rNEG
|
||||||
|
- cmpd cr1,rWORD1,rWORD2
|
||||||
|
- bne L(endstring)
|
||||||
|
- addi rSTR1,rSTR1,8
|
||||||
|
- bne cr1,L(different)
|
||||||
|
- addi rSTR2,rSTR2,8
|
||||||
|
- cmpldi cr1,rN,0
|
||||||
|
-L(unaligned):
|
||||||
|
- mtctr rN
|
||||||
|
- ble cr1,L(ux)
|
||||||
|
-L(uz):
|
||||||
|
- lbz rWORD1,0(rSTR1)
|
||||||
|
- lbz rWORD2,0(rSTR2)
|
||||||
|
- .align 4
|
||||||
|
-L(u1):
|
||||||
|
- cmpdi cr1,rWORD1,0
|
||||||
|
- bdz L(u4)
|
||||||
|
- cmpd rWORD1,rWORD2
|
||||||
|
- beq cr1,L(u4)
|
||||||
|
- bne L(u4)
|
||||||
|
- lbzu rWORD3,1(rSTR1)
|
||||||
|
- lbzu rWORD4,1(rSTR2)
|
||||||
|
- cmpdi cr1,rWORD3,0
|
||||||
|
- bdz L(u3)
|
||||||
|
- cmpd rWORD3,rWORD4
|
||||||
|
- beq cr1,L(u3)
|
||||||
|
- bne L(u3)
|
||||||
|
- lbzu rWORD1,1(rSTR1)
|
||||||
|
- lbzu rWORD2,1(rSTR2)
|
||||||
|
- cmpdi cr1,rWORD1,0
|
||||||
|
- bdz L(u4)
|
||||||
|
- cmpd rWORD1,rWORD2
|
||||||
|
- beq cr1,L(u4)
|
||||||
|
- bne L(u4)
|
||||||
|
- lbzu rWORD3,1(rSTR1)
|
||||||
|
- lbzu rWORD4,1(rSTR2)
|
||||||
|
- cmpdi cr1,rWORD3,0
|
||||||
|
- bdz L(u3)
|
||||||
|
- cmpd rWORD3,rWORD4
|
||||||
|
- beq cr1,L(u3)
|
||||||
|
- bne L(u3)
|
||||||
|
- lbzu rWORD1,1(rSTR1)
|
||||||
|
- lbzu rWORD2,1(rSTR2)
|
||||||
|
- b L(u1)
|
||||||
|
-
|
||||||
|
-L(u3): sub rRTN,rWORD3,rWORD4
|
||||||
|
- blr
|
||||||
|
-L(u4): sub rRTN,rWORD1,rWORD2
|
||||||
|
- blr
|
||||||
|
-L(ux):
|
||||||
|
- li rRTN,0
|
||||||
|
- blr
|
||||||
|
-END (STRNCMP)
|
||||||
|
-libc_hidden_builtin_def (strncmp)
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/strncmp.S b/sysdeps/powerpc/powerpc64/strncmp.S
|
||||||
|
deleted file mode 100644
|
||||||
|
index 40a230242cbdf733..0000000000000000
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/strncmp.S
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,210 +0,0 @@
|
||||||
|
-/* Optimized strcmp implementation for PowerPC64.
|
||||||
|
- Copyright (C) 2003-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 <sysdep.h>
|
||||||
|
-
|
||||||
|
-/* See strlen.s for comments on how the end-of-string testing works. */
|
||||||
|
-
|
||||||
|
-/* int [r3] strncmp (const char *s1 [r3], const char *s2 [r4], size_t size [r5]) */
|
||||||
|
-
|
||||||
|
-#ifndef STRNCMP
|
||||||
|
-# define STRNCMP strncmp
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
-ENTRY_TOCLESS (STRNCMP, 4)
|
||||||
|
- CALL_MCOUNT 3
|
||||||
|
-
|
||||||
|
-#define rTMP2 r0
|
||||||
|
-#define rRTN r3
|
||||||
|
-#define rSTR1 r3 /* first string arg */
|
||||||
|
-#define rSTR2 r4 /* second string arg */
|
||||||
|
-#define rN r5 /* max string length */
|
||||||
|
-#define rWORD1 r6 /* current word in s1 */
|
||||||
|
-#define rWORD2 r7 /* current word in s2 */
|
||||||
|
-#define rFEFE r8 /* constant 0xfefefefefefefeff (-0x0101010101010101) */
|
||||||
|
-#define r7F7F r9 /* constant 0x7f7f7f7f7f7f7f7f */
|
||||||
|
-#define rNEG r10 /* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */
|
||||||
|
-#define rBITDIF r11 /* bits that differ in s1 & s2 words */
|
||||||
|
-#define rTMP r12
|
||||||
|
-
|
||||||
|
- dcbt 0,rSTR1
|
||||||
|
- or rTMP, rSTR2, rSTR1
|
||||||
|
- lis r7F7F, 0x7f7f
|
||||||
|
- dcbt 0,rSTR2
|
||||||
|
- clrldi. rTMP, rTMP, 61
|
||||||
|
- cmpldi cr1, rN, 0
|
||||||
|
- lis rFEFE, -0x101
|
||||||
|
- bne L(unaligned)
|
||||||
|
-/* We are doubleword aligned so set up for two loops. first a double word
|
||||||
|
- loop, then fall into the byte loop if any residual. */
|
||||||
|
- srdi. rTMP, rN, 3
|
||||||
|
- clrldi rN, rN, 61
|
||||||
|
- addi rFEFE, rFEFE, -0x101
|
||||||
|
- addi r7F7F, r7F7F, 0x7f7f
|
||||||
|
- cmpldi cr1, rN, 0
|
||||||
|
- beq L(unaligned)
|
||||||
|
-
|
||||||
|
- mtctr rTMP /* Power4 wants mtctr 1st in dispatch group. */
|
||||||
|
- ld rWORD1, 0(rSTR1)
|
||||||
|
- ld rWORD2, 0(rSTR2)
|
||||||
|
- sldi rTMP, rFEFE, 32
|
||||||
|
- insrdi r7F7F, r7F7F, 32, 0
|
||||||
|
- add rFEFE, rFEFE, rTMP
|
||||||
|
- b L(g1)
|
||||||
|
-
|
||||||
|
-L(g0):
|
||||||
|
- ldu rWORD1, 8(rSTR1)
|
||||||
|
- bne- cr1, L(different)
|
||||||
|
- ldu rWORD2, 8(rSTR2)
|
||||||
|
-L(g1): add rTMP, rFEFE, rWORD1
|
||||||
|
- nor rNEG, r7F7F, rWORD1
|
||||||
|
- bdz L(tail)
|
||||||
|
- and. rTMP, rTMP, rNEG
|
||||||
|
- cmpd cr1, rWORD1, rWORD2
|
||||||
|
- beq+ L(g0)
|
||||||
|
-
|
||||||
|
-/* OK. We've hit the end of the string. We need to be careful that
|
||||||
|
- we don't compare two strings as different because of gunk beyond
|
||||||
|
- the end of the strings... */
|
||||||
|
-
|
||||||
|
-#ifdef __LITTLE_ENDIAN__
|
||||||
|
-L(endstring):
|
||||||
|
- addi rTMP2, rTMP, -1
|
||||||
|
- beq cr1, L(equal)
|
||||||
|
- andc rTMP2, rTMP2, rTMP
|
||||||
|
- rldimi rTMP2, rTMP2, 1, 0
|
||||||
|
- and rWORD2, rWORD2, rTMP2 /* Mask off gunk. */
|
||||||
|
- and rWORD1, rWORD1, rTMP2
|
||||||
|
- cmpd cr1, rWORD1, rWORD2
|
||||||
|
- beq cr1, L(equal)
|
||||||
|
- xor rBITDIF, rWORD1, rWORD2 /* rBITDIF has bits that differ. */
|
||||||
|
- neg rNEG, rBITDIF
|
||||||
|
- and rNEG, rNEG, rBITDIF /* rNEG has LS bit that differs. */
|
||||||
|
- cntlzd rNEG, rNEG /* bitcount of the bit. */
|
||||||
|
- andi. rNEG, rNEG, 56 /* bitcount to LS byte that differs. */
|
||||||
|
- sld rWORD1, rWORD1, rNEG /* shift left to clear MS bytes. */
|
||||||
|
- sld rWORD2, rWORD2, rNEG
|
||||||
|
- xor. rBITDIF, rWORD1, rWORD2
|
||||||
|
- sub rRTN, rWORD1, rWORD2
|
||||||
|
- blt- L(highbit)
|
||||||
|
- sradi rRTN, rRTN, 63 /* must return an int. */
|
||||||
|
- ori rRTN, rRTN, 1
|
||||||
|
- blr
|
||||||
|
-L(equal):
|
||||||
|
- li rRTN, 0
|
||||||
|
- blr
|
||||||
|
-
|
||||||
|
-L(different):
|
||||||
|
- ld rWORD1, -8(rSTR1)
|
||||||
|
- xor rBITDIF, rWORD1, rWORD2 /* rBITDIF has bits that differ. */
|
||||||
|
- neg rNEG, rBITDIF
|
||||||
|
- and rNEG, rNEG, rBITDIF /* rNEG has LS bit that differs. */
|
||||||
|
- cntlzd rNEG, rNEG /* bitcount of the bit. */
|
||||||
|
- andi. rNEG, rNEG, 56 /* bitcount to LS byte that differs. */
|
||||||
|
- sld rWORD1, rWORD1, rNEG /* shift left to clear MS bytes. */
|
||||||
|
- sld rWORD2, rWORD2, rNEG
|
||||||
|
- xor. rBITDIF, rWORD1, rWORD2
|
||||||
|
- sub rRTN, rWORD1, rWORD2
|
||||||
|
- blt- L(highbit)
|
||||||
|
- sradi rRTN, rRTN, 63
|
||||||
|
- ori rRTN, rRTN, 1
|
||||||
|
- blr
|
||||||
|
-L(highbit):
|
||||||
|
- sradi rRTN, rWORD2, 63
|
||||||
|
- ori rRTN, rRTN, 1
|
||||||
|
- blr
|
||||||
|
-
|
||||||
|
-#else
|
||||||
|
-L(endstring):
|
||||||
|
- and rTMP, r7F7F, rWORD1
|
||||||
|
- beq cr1, L(equal)
|
||||||
|
- add rTMP, rTMP, r7F7F
|
||||||
|
- xor. rBITDIF, rWORD1, rWORD2
|
||||||
|
- andc rNEG, rNEG, rTMP
|
||||||
|
- blt- L(highbit)
|
||||||
|
- cntlzd rBITDIF, rBITDIF
|
||||||
|
- cntlzd rNEG, rNEG
|
||||||
|
- addi rNEG, rNEG, 7
|
||||||
|
- cmpd cr1, rNEG, rBITDIF
|
||||||
|
- sub rRTN, rWORD1, rWORD2
|
||||||
|
- blt- cr1, L(equal)
|
||||||
|
- sradi rRTN, rRTN, 63 /* must return an int. */
|
||||||
|
- ori rRTN, rRTN, 1
|
||||||
|
- blr
|
||||||
|
-L(equal):
|
||||||
|
- li rRTN, 0
|
||||||
|
- blr
|
||||||
|
-
|
||||||
|
-L(different):
|
||||||
|
- ld rWORD1, -8(rSTR1)
|
||||||
|
- xor. rBITDIF, rWORD1, rWORD2
|
||||||
|
- sub rRTN, rWORD1, rWORD2
|
||||||
|
- blt- L(highbit)
|
||||||
|
- sradi rRTN, rRTN, 63
|
||||||
|
- ori rRTN, rRTN, 1
|
||||||
|
- blr
|
||||||
|
-L(highbit):
|
||||||
|
- sradi rRTN, rWORD2, 63
|
||||||
|
- ori rRTN, rRTN, 1
|
||||||
|
- blr
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
-/* Oh well. In this case, we just do a byte-by-byte comparison. */
|
||||||
|
- .align 4
|
||||||
|
-L(tail):
|
||||||
|
- and. rTMP, rTMP, rNEG
|
||||||
|
- cmpd cr1, rWORD1, rWORD2
|
||||||
|
- bne- L(endstring)
|
||||||
|
- addi rSTR1, rSTR1, 8
|
||||||
|
- bne- cr1, L(different)
|
||||||
|
- addi rSTR2, rSTR2, 8
|
||||||
|
- cmpldi cr1, rN, 0
|
||||||
|
-L(unaligned):
|
||||||
|
- mtctr rN /* Power4 wants mtctr 1st in dispatch group */
|
||||||
|
- bgt cr1, L(uz)
|
||||||
|
-L(ux):
|
||||||
|
- li rRTN, 0
|
||||||
|
- blr
|
||||||
|
- .align 4
|
||||||
|
-L(uz):
|
||||||
|
- lbz rWORD1, 0(rSTR1)
|
||||||
|
- lbz rWORD2, 0(rSTR2)
|
||||||
|
- nop
|
||||||
|
- b L(u1)
|
||||||
|
-L(u0):
|
||||||
|
- lbzu rWORD2, 1(rSTR2)
|
||||||
|
-L(u1):
|
||||||
|
- bdz L(u3)
|
||||||
|
- cmpdi cr1, rWORD1, 0
|
||||||
|
- cmpd rWORD1, rWORD2
|
||||||
|
- beq- cr1, L(u3)
|
||||||
|
- lbzu rWORD1, 1(rSTR1)
|
||||||
|
- bne- L(u2)
|
||||||
|
- lbzu rWORD2, 1(rSTR2)
|
||||||
|
- bdz L(u3)
|
||||||
|
- cmpdi cr1, rWORD1, 0
|
||||||
|
- cmpd rWORD1, rWORD2
|
||||||
|
- bne- L(u3)
|
||||||
|
- lbzu rWORD1, 1(rSTR1)
|
||||||
|
- bne+ cr1, L(u0)
|
||||||
|
-
|
||||||
|
-L(u2): lbzu rWORD1, -1(rSTR1)
|
||||||
|
-L(u3): sub rRTN, rWORD1, rWORD2
|
||||||
|
- blr
|
||||||
|
-END (STRNCMP)
|
||||||
|
-libc_hidden_builtin_def (strncmp)
|
@ -0,0 +1,331 @@
|
|||||||
|
commit 5456af201d4c0a2950200ba756e5f8314ddbbccd
|
||||||
|
Author: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
Date: Thu May 11 14:00:41 2023 -0400
|
||||||
|
|
||||||
|
stdio-common: Reformat Makefile.
|
||||||
|
|
||||||
|
Reflow Makefile.
|
||||||
|
Sort using scripts/sort-makefile-lines.py.
|
||||||
|
|
||||||
|
Code generation is changed as routines are linked in sorted order
|
||||||
|
as expected.
|
||||||
|
|
||||||
|
No regressions on x86_64 and i686.
|
||||||
|
|
||||||
|
(cherry picked from commit c3004417afc98585089a9282d1d4d60cdef5317a)
|
||||||
|
(cherry picked from commit 5b4e90230b8147e273585bf296bf1a9fb6e2b4c2)
|
||||||
|
|
||||||
|
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
|
||||||
|
index 803f16dae030cb72..76d1d0a1193aa109 100644
|
||||||
|
--- a/stdio-common/Makefile
|
||||||
|
+++ b/stdio-common/Makefile
|
||||||
|
@@ -22,82 +22,241 @@ subdir := stdio-common
|
||||||
|
|
||||||
|
include ../Makeconfig
|
||||||
|
|
||||||
|
-headers := stdio_ext.h printf.h bits/printf-ldbl.h bits/stdio_lim.h
|
||||||
|
-
|
||||||
|
-routines := \
|
||||||
|
- ctermid cuserid \
|
||||||
|
- _itoa _itowa itoa-digits itoa-udigits itowa-digits \
|
||||||
|
- vfprintf vprintf printf_fp reg-printf printf-prs printf_fphex \
|
||||||
|
- reg-modifier reg-type \
|
||||||
|
- printf_size fprintf printf snprintf sprintf asprintf dprintf \
|
||||||
|
- vfwprintf vfscanf vfwscanf \
|
||||||
|
- fscanf scanf sscanf \
|
||||||
|
- perror psignal \
|
||||||
|
- tmpfile tmpfile64 tmpnam tmpnam_r tempnam tempname \
|
||||||
|
- getline getw putw \
|
||||||
|
- remove rename renameat renameat2 \
|
||||||
|
- flockfile ftrylockfile funlockfile \
|
||||||
|
- isoc99_scanf isoc99_vscanf isoc99_fscanf isoc99_vfscanf isoc99_sscanf \
|
||||||
|
- isoc99_vsscanf \
|
||||||
|
- psiginfo gentempfd \
|
||||||
|
- vfscanf-internal vfwscanf-internal iovfscanf \
|
||||||
|
- vfprintf-internal vfwprintf-internal
|
||||||
|
-
|
||||||
|
-aux := errlist siglist printf-parsemb printf-parsewc fxprintf
|
||||||
|
-
|
||||||
|
-tests := tstscanf test_rdwr test-popen tstgetln test-fseek \
|
||||||
|
- temptest tst-fileno test-fwrite tst-ungetc tst-ferror \
|
||||||
|
- xbug errnobug \
|
||||||
|
- bug1 bug2 bug3 bug4 bug5 bug6 bug7 bug8 bug9 bug10 bug11 bug12 bug13 \
|
||||||
|
- tfformat tiformat tllformat tstdiomisc tst-printfsz tst-wc-printf \
|
||||||
|
- scanf1 scanf2 scanf3 scanf4 scanf5 scanf7 scanf8 scanf9 scanf10 \
|
||||||
|
- scanf11 scanf12 tst-tmpnam tst-cookie tst-obprintf tst-sscanf \
|
||||||
|
- tst-swprintf tst-fseek tst-fmemopen test-vfprintf tst-gets \
|
||||||
|
- tst-perror tst-sprintf tst-rndseek tst-fdopen tst-fphex bug14 \
|
||||||
|
- tst-popen tst-unlockedio tst-fmemopen2 tst-put-error tst-fgets \
|
||||||
|
- tst-fwrite bug16 bug17 tst-swscanf tst-sprintf2 bug18 bug18a \
|
||||||
|
- bug19 bug19a tst-popen2 scanf13 scanf14 scanf15 bug20 bug21 bug22 \
|
||||||
|
- scanf16 scanf17 tst-setvbuf1 tst-grouping bug23 bug24 \
|
||||||
|
- bug-vfprintf-nargs tst-long-dbl-fphex tst-fphex-wide tst-sprintf3 \
|
||||||
|
- bug25 tst-printf-round bug23-2 bug23-3 bug23-4 bug26 tst-fmemopen3 \
|
||||||
|
- tst-printf-bz18872 tst-vfprintf-width-prec tst-fmemopen4 \
|
||||||
|
- tst-vfprintf-user-type \
|
||||||
|
- tst-vfprintf-mbs-prec \
|
||||||
|
- tst-scanf-round \
|
||||||
|
- tst-renameat2 tst-bz11319 tst-bz11319-fortify2 \
|
||||||
|
- scanf14a scanf16a \
|
||||||
|
- tst-printf-bz25691 \
|
||||||
|
- tst-vfprintf-width-prec-alloc \
|
||||||
|
- tst-printf-fp-free \
|
||||||
|
- tst-printf-fp-leak \
|
||||||
|
- test-strerr
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-test-srcs = tst-unbputc tst-printf tst-printfsz-islongdouble
|
||||||
|
+headers := \
|
||||||
|
+ bits/printf-ldbl.h \
|
||||||
|
+ bits/stdio_lim.h \
|
||||||
|
+ printf.h \
|
||||||
|
+ stdio_ext.h \
|
||||||
|
+ # headers
|
||||||
|
+
|
||||||
|
+routines := \
|
||||||
|
+ _itoa \
|
||||||
|
+ _itowa \
|
||||||
|
+ asprintf \
|
||||||
|
+ ctermid \
|
||||||
|
+ cuserid \
|
||||||
|
+ dprintf \
|
||||||
|
+ flockfile \
|
||||||
|
+ fprintf \
|
||||||
|
+ fscanf \
|
||||||
|
+ ftrylockfile \
|
||||||
|
+ funlockfile \
|
||||||
|
+ gentempfd \
|
||||||
|
+ getline \
|
||||||
|
+ getw \
|
||||||
|
+ iovfscanf \
|
||||||
|
+ isoc99_fscanf \
|
||||||
|
+ isoc99_scanf \
|
||||||
|
+ isoc99_sscanf \
|
||||||
|
+ isoc99_vfscanf \
|
||||||
|
+ isoc99_vscanf \
|
||||||
|
+ isoc99_vsscanf \
|
||||||
|
+ itoa-digits \
|
||||||
|
+ itoa-udigits \
|
||||||
|
+ itowa-digits \
|
||||||
|
+ perror \
|
||||||
|
+ printf \
|
||||||
|
+ printf-prs \
|
||||||
|
+ printf_fp \
|
||||||
|
+ printf_fphex \
|
||||||
|
+ printf_size \
|
||||||
|
+ psiginfo \
|
||||||
|
+ psignal \
|
||||||
|
+ putw \
|
||||||
|
+ reg-modifier \
|
||||||
|
+ reg-printf \
|
||||||
|
+ reg-type \
|
||||||
|
+ remove \
|
||||||
|
+ rename \
|
||||||
|
+ renameat \
|
||||||
|
+ renameat2 \
|
||||||
|
+ scanf \
|
||||||
|
+ snprintf \
|
||||||
|
+ sprintf \
|
||||||
|
+ sscanf \
|
||||||
|
+ tempnam \
|
||||||
|
+ tempname \
|
||||||
|
+ tmpfile \
|
||||||
|
+ tmpfile64 tmpnam \
|
||||||
|
+ tmpnam_r \
|
||||||
|
+ vfprintf \
|
||||||
|
+ vfprintf-internal \
|
||||||
|
+ vfscanf \
|
||||||
|
+ vfscanf-internal \
|
||||||
|
+ vfwprintf \
|
||||||
|
+ vfwprintf-internal \
|
||||||
|
+ vfwscanf \
|
||||||
|
+ vfwscanf-internal \
|
||||||
|
+ vprintf \
|
||||||
|
+ # routines
|
||||||
|
+
|
||||||
|
+aux := \
|
||||||
|
+ errlist \
|
||||||
|
+ fxprintf \
|
||||||
|
+ printf-parsemb \
|
||||||
|
+ printf-parsewc \
|
||||||
|
+ siglist \
|
||||||
|
+ # aux
|
||||||
|
+
|
||||||
|
+tests := \
|
||||||
|
+ bug-vfprintf-nargs \
|
||||||
|
+ bug1 \
|
||||||
|
+ bug10 \
|
||||||
|
+ bug11 \
|
||||||
|
+ bug12 \
|
||||||
|
+ bug13 \
|
||||||
|
+ bug14 \
|
||||||
|
+ bug16 \
|
||||||
|
+ bug17 \
|
||||||
|
+ bug18 \
|
||||||
|
+ bug18a \
|
||||||
|
+ bug19 \
|
||||||
|
+ bug19a \
|
||||||
|
+ bug2 \
|
||||||
|
+ bug20 \
|
||||||
|
+ bug21 \
|
||||||
|
+ bug22 \
|
||||||
|
+ bug23 \
|
||||||
|
+ bug23-2 \
|
||||||
|
+ bug23-3 \
|
||||||
|
+ bug23-4 \
|
||||||
|
+ bug24 \
|
||||||
|
+ bug25 \
|
||||||
|
+ bug26 \
|
||||||
|
+ bug3 \
|
||||||
|
+ bug4 \
|
||||||
|
+ bug5 \
|
||||||
|
+ bug6 \
|
||||||
|
+ bug7 \
|
||||||
|
+ bug8 \
|
||||||
|
+ bug9 \
|
||||||
|
+ errnobug \
|
||||||
|
+ scanf1 \
|
||||||
|
+ scanf10 \
|
||||||
|
+ scanf11 \
|
||||||
|
+ scanf12 \
|
||||||
|
+ scanf13 \
|
||||||
|
+ scanf14 \
|
||||||
|
+ scanf14a \
|
||||||
|
+ scanf15 \
|
||||||
|
+ scanf16 \
|
||||||
|
+ scanf16a \
|
||||||
|
+ scanf17 \
|
||||||
|
+ scanf2 \
|
||||||
|
+ scanf3 \
|
||||||
|
+ scanf4 \
|
||||||
|
+ scanf5 \
|
||||||
|
+ scanf7 \
|
||||||
|
+ scanf8 \
|
||||||
|
+ scanf9 \
|
||||||
|
+ temptest \
|
||||||
|
+ test-fseek \
|
||||||
|
+ test-fwrite \
|
||||||
|
+ test-popen \
|
||||||
|
+ test-strerr \
|
||||||
|
+ test-vfprintf \
|
||||||
|
+ test_rdwr \
|
||||||
|
+ tfformat \
|
||||||
|
+ tiformat \
|
||||||
|
+ tllformat \
|
||||||
|
+ tst-bz11319 \
|
||||||
|
+ tst-bz11319-fortify2 \
|
||||||
|
+ tst-cookie \
|
||||||
|
+ tst-fdopen \
|
||||||
|
+ tst-ferror \
|
||||||
|
+ tst-fgets \
|
||||||
|
+ tst-fileno \
|
||||||
|
+ tst-fmemopen \
|
||||||
|
+ tst-fmemopen2 \
|
||||||
|
+ tst-fmemopen3 \
|
||||||
|
+ tst-fmemopen4 \
|
||||||
|
+ tst-fphex \
|
||||||
|
+ tst-fphex-wide \
|
||||||
|
+ tst-fseek \
|
||||||
|
+ tst-fwrite \
|
||||||
|
+ tst-gets \
|
||||||
|
+ tst-grouping \
|
||||||
|
+ tst-long-dbl-fphex \
|
||||||
|
+ tst-obprintf \
|
||||||
|
+ tst-perror \
|
||||||
|
+ tst-popen \
|
||||||
|
+ tst-popen2 \
|
||||||
|
+ tst-printf-bz18872 \
|
||||||
|
+ tst-printf-bz25691 \
|
||||||
|
+ tst-printf-fp-free \
|
||||||
|
+ tst-printf-fp-leak \
|
||||||
|
+ tst-printf-round \
|
||||||
|
+ tst-printfsz \
|
||||||
|
+ tst-put-error \
|
||||||
|
+ tst-renameat2 \
|
||||||
|
+ tst-rndseek \
|
||||||
|
+ tst-scanf-round \
|
||||||
|
+ tst-setvbuf1 \
|
||||||
|
+ tst-sprintf \
|
||||||
|
+ tst-sprintf2 \
|
||||||
|
+ tst-sprintf3 \
|
||||||
|
+ tst-sscanf \
|
||||||
|
+ tst-swprintf \
|
||||||
|
+ tst-swscanf \
|
||||||
|
+ tst-tmpnam \
|
||||||
|
+ tst-ungetc \
|
||||||
|
+ tst-unlockedio \
|
||||||
|
+ tst-vfprintf-mbs-prec \
|
||||||
|
+ tst-vfprintf-user-type \
|
||||||
|
+ tst-vfprintf-width-prec \
|
||||||
|
+ tst-vfprintf-width-prec-alloc \
|
||||||
|
+ tst-wc-printf \
|
||||||
|
+ tstdiomisc \
|
||||||
|
+ tstgetln \
|
||||||
|
+ tstscanf \
|
||||||
|
+ xbug \
|
||||||
|
+ # tests
|
||||||
|
+
|
||||||
|
+test-srcs = \
|
||||||
|
+ tst-printf \
|
||||||
|
+ tst-printfsz-islongdouble \
|
||||||
|
+ tst-unbputc \
|
||||||
|
+ # test-srcs
|
||||||
|
|
||||||
|
ifeq ($(run-built-tests),yes)
|
||||||
|
-tests-special += $(objpfx)tst-unbputc.out $(objpfx)tst-printf.out \
|
||||||
|
- $(objpfx)tst-printf-bz18872-mem.out \
|
||||||
|
- $(objpfx)tst-setvbuf1-cmp.out \
|
||||||
|
- $(objpfx)tst-vfprintf-width-prec-mem.out \
|
||||||
|
- $(objpfx)tst-printfsz-islongdouble.out \
|
||||||
|
- $(objpfx)tst-printf-bz25691-mem.out \
|
||||||
|
- $(objpfx)tst-printf-fp-free-mem.out \
|
||||||
|
- $(objpfx)tst-printf-fp-leak-mem.out
|
||||||
|
-generated += tst-printf-bz18872.c tst-printf-bz18872.mtrace \
|
||||||
|
- tst-printf-bz18872-mem.out \
|
||||||
|
- tst-vfprintf-width-prec.mtrace tst-vfprintf-width-prec-mem.out \
|
||||||
|
- tst-printf-bz25691.mtrace tst-printf-bz25691-mem.out \
|
||||||
|
- tst-printf-fp-free.mtrace tst-printf-fp-free-mem.out \
|
||||||
|
- tst-printf-fp-leak.mtrace tst-printf-fp-leak-mem.out
|
||||||
|
-endif
|
||||||
|
+tests-special += \
|
||||||
|
+ $(objpfx)tst-printf-bz18872-mem.out \
|
||||||
|
+ $(objpfx)tst-printf-bz25691-mem.out \
|
||||||
|
+ $(objpfx)tst-printf-fp-free-mem.out \
|
||||||
|
+ $(objpfx)tst-printf-fp-leak-mem.out \
|
||||||
|
+ $(objpfx)tst-printf.out \
|
||||||
|
+ $(objpfx)tst-printfsz-islongdouble.out \
|
||||||
|
+ $(objpfx)tst-setvbuf1-cmp.out \
|
||||||
|
+ $(objpfx)tst-unbputc.out \
|
||||||
|
+ $(objpfx)tst-vfprintf-width-prec-mem.out \
|
||||||
|
+ # tests-special
|
||||||
|
+
|
||||||
|
+generated += \
|
||||||
|
+ tst-printf-bz18872-mem.out \
|
||||||
|
+ tst-printf-bz18872.c \
|
||||||
|
+ tst-printf-bz18872.mtrace \
|
||||||
|
+ tst-printf-bz25691-mem.out \
|
||||||
|
+ tst-printf-bz25691.mtrace \
|
||||||
|
+ tst-printf-fp-free-mem.out \
|
||||||
|
+ tst-printf-fp-free.mtrace \
|
||||||
|
+ tst-printf-fp-leak-mem.out \
|
||||||
|
+ tst-printf-fp-leak.mtrace \
|
||||||
|
+ tst-vfprintf-width-prec-mem.out \
|
||||||
|
+ tst-vfprintf-width-prec.mtrace \
|
||||||
|
+ # generated
|
||||||
|
+endif # $(run-built-tests)
|
||||||
|
|
||||||
|
tests-special += $(objpfx)tst-errno-manual.out
|
||||||
|
|
||||||
|
include ../Rules
|
||||||
|
|
||||||
|
ifeq ($(run-built-tests),yes)
|
||||||
|
-LOCALES := de_DE.ISO-8859-1 de_DE.UTF-8 en_US.ISO-8859-1 ja_JP.EUC-JP
|
||||||
|
+LOCALES := \
|
||||||
|
+ de_DE.ISO-8859-1 \
|
||||||
|
+ de_DE.UTF-8 \
|
||||||
|
+ en_US.ISO-8859-1 \
|
||||||
|
+ ja_JP.EUC-JP \
|
||||||
|
+ # LOCALES
|
||||||
|
include ../gen-locales.mk
|
||||||
|
|
||||||
|
$(objpfx)bug14.out: $(gen-locales)
|
@ -0,0 +1,201 @@
|
|||||||
|
commit 9556acd249687ac562deb6309503165d66eb06fa
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Thu Dec 21 15:59:15 2023 -0300
|
||||||
|
|
||||||
|
debug: Adapt fortify tests to libsupport
|
||||||
|
|
||||||
|
Checked on aarch64, armhf, x86_64, and i686.
|
||||||
|
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
|
||||||
|
diff --git a/debug/test-stpcpy_chk.c b/debug/test-stpcpy_chk.c
|
||||||
|
index 96ad600bc2760cbd..c3cb52d987f9db4f 100644
|
||||||
|
--- a/debug/test-stpcpy_chk.c
|
||||||
|
+++ b/debug/test-stpcpy_chk.c
|
||||||
|
@@ -20,7 +20,7 @@
|
||||||
|
#define STRCPY_RESULT(dst, len) ((dst) + (len))
|
||||||
|
#define TEST_MAIN
|
||||||
|
#define TEST_NAME "stpcpy_chk"
|
||||||
|
-#include "../string/test-string.h"
|
||||||
|
+#include <string/test-string.h>
|
||||||
|
|
||||||
|
extern void __attribute__ ((noreturn)) __chk_fail (void);
|
||||||
|
char *simple_stpcpy_chk (char *, const char *, size_t);
|
||||||
|
diff --git a/debug/test-strcpy_chk.c b/debug/test-strcpy_chk.c
|
||||||
|
index 80c07482aaa54e3b..bb89e342caef470b 100644
|
||||||
|
--- a/debug/test-strcpy_chk.c
|
||||||
|
+++ b/debug/test-strcpy_chk.c
|
||||||
|
@@ -21,7 +21,7 @@
|
||||||
|
# define STRCPY_RESULT(dst, len) dst
|
||||||
|
# define TEST_MAIN
|
||||||
|
# define TEST_NAME "strcpy_chk"
|
||||||
|
-# include "../string/test-string.h"
|
||||||
|
+# include <string/test-string.h>
|
||||||
|
|
||||||
|
/* This test case implicitly tests the availability of the __chk_fail
|
||||||
|
symbol, which is part of the public ABI and may be used
|
||||||
|
diff --git a/debug/tst-fortify.c b/debug/tst-fortify.c
|
||||||
|
index fb02452f5993c594..01a8703de1e6e09a 100644
|
||||||
|
--- a/debug/tst-fortify.c
|
||||||
|
+++ b/debug/tst-fortify.c
|
||||||
|
@@ -24,6 +24,7 @@
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
+#include <limits.h>
|
||||||
|
#include <locale.h>
|
||||||
|
#include <obstack.h>
|
||||||
|
#include <setjmp.h>
|
||||||
|
@@ -37,6 +38,10 @@
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
+#include <paths.h>
|
||||||
|
+
|
||||||
|
+#include <support/temp_file.h>
|
||||||
|
+#include <support/support.h>
|
||||||
|
|
||||||
|
#ifndef _GNU_SOURCE
|
||||||
|
# define MEMPCPY memcpy
|
||||||
|
@@ -53,15 +58,10 @@
|
||||||
|
#define obstack_chunk_alloc malloc
|
||||||
|
#define obstack_chunk_free free
|
||||||
|
|
||||||
|
-char *temp_filename;
|
||||||
|
-static void do_prepare (void);
|
||||||
|
-static int do_test (void);
|
||||||
|
-#define PREPARE(argc, argv) do_prepare ()
|
||||||
|
-#define TEST_FUNCTION do_test ()
|
||||||
|
-#include "../test-skeleton.c"
|
||||||
|
+static char *temp_filename;
|
||||||
|
|
||||||
|
static void
|
||||||
|
-do_prepare (void)
|
||||||
|
+do_prepare (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int temp_fd = create_temp_file ("tst-chk1.", &temp_filename);
|
||||||
|
if (temp_fd == -1)
|
||||||
|
@@ -78,10 +78,11 @@ do_prepare (void)
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+#define PREPARE do_prepare
|
||||||
|
|
||||||
|
-volatile int chk_fail_ok;
|
||||||
|
-volatile int ret;
|
||||||
|
-jmp_buf chk_fail_buf;
|
||||||
|
+static volatile int chk_fail_ok;
|
||||||
|
+static volatile int ret;
|
||||||
|
+static jmp_buf chk_fail_buf;
|
||||||
|
|
||||||
|
static void
|
||||||
|
handler (int sig)
|
||||||
|
@@ -103,22 +104,22 @@ wchar_t wbuf[10];
|
||||||
|
#define buf_size sizeof (buf)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-volatile size_t l0;
|
||||||
|
-volatile char *p;
|
||||||
|
-volatile wchar_t *wp;
|
||||||
|
-const char *str1 = "JIHGFEDCBA";
|
||||||
|
-const char *str2 = "F";
|
||||||
|
-const char *str3 = "%s%n%s%n";
|
||||||
|
-const char *str4 = "Hello, ";
|
||||||
|
-const char *str5 = "World!\n";
|
||||||
|
-const wchar_t *wstr1 = L"JIHGFEDCBA";
|
||||||
|
-const wchar_t *wstr2 = L"F";
|
||||||
|
-const wchar_t *wstr3 = L"%s%n%s%n";
|
||||||
|
-const wchar_t *wstr4 = L"Hello, ";
|
||||||
|
-const wchar_t *wstr5 = L"World!\n";
|
||||||
|
-char buf2[10] = "%s";
|
||||||
|
-int num1 = 67;
|
||||||
|
-int num2 = 987654;
|
||||||
|
+static volatile size_t l0;
|
||||||
|
+static volatile char *p;
|
||||||
|
+static volatile wchar_t *wp;
|
||||||
|
+static const char *str1 = "JIHGFEDCBA";
|
||||||
|
+static const char *str2 = "F";
|
||||||
|
+static const char *str3 = "%s%n%s%n";
|
||||||
|
+static const char *str4 = "Hello, ";
|
||||||
|
+static const char *str5 = "World!\n";
|
||||||
|
+static const wchar_t *wstr1 = L"JIHGFEDCBA";
|
||||||
|
+static const wchar_t *wstr2 = L"F";
|
||||||
|
+static const wchar_t *wstr3 = L"%s%n%s%n";
|
||||||
|
+static const wchar_t *wstr4 = L"Hello, ";
|
||||||
|
+static const wchar_t *wstr5 = L"World!\n";
|
||||||
|
+static char buf2[10] = "%s";
|
||||||
|
+static int num1 = 67;
|
||||||
|
+static int num2 = 987654;
|
||||||
|
|
||||||
|
#define FAIL() \
|
||||||
|
do { printf ("Failure on line %d\n", __LINE__); ret = 1; } while (0)
|
||||||
|
@@ -1763,3 +1764,5 @@ do_test (void)
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/debug/tst-longjmp_chk.c b/debug/tst-longjmp_chk.c
|
||||||
|
index e4e93d2a36b537d9..37f858606be4c4a2 100644
|
||||||
|
--- a/debug/tst-longjmp_chk.c
|
||||||
|
+++ b/debug/tst-longjmp_chk.c
|
||||||
|
@@ -10,11 +10,7 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
-
|
||||||
|
-static int do_test(void);
|
||||||
|
-#define TEST_FUNCTION do_test ()
|
||||||
|
-#include "../test-skeleton.c"
|
||||||
|
-
|
||||||
|
+#include <support/support.h>
|
||||||
|
|
||||||
|
static jmp_buf b;
|
||||||
|
|
||||||
|
@@ -76,3 +72,5 @@ do_test (void)
|
||||||
|
puts ("second longjmp returned");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/debug/tst-longjmp_chk2.c b/debug/tst-longjmp_chk2.c
|
||||||
|
index 23d3436d1d26d2d1..69c1ab9db73f14ae 100644
|
||||||
|
--- a/debug/tst-longjmp_chk2.c
|
||||||
|
+++ b/debug/tst-longjmp_chk2.c
|
||||||
|
@@ -12,9 +12,7 @@
|
||||||
|
#include <sys/resource.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
-static int do_test (void);
|
||||||
|
-#define TEST_FUNCTION do_test ()
|
||||||
|
-#include "../test-skeleton.c"
|
||||||
|
+#include <support/support.h>
|
||||||
|
|
||||||
|
static jmp_buf mainloop;
|
||||||
|
static sigset_t mainsigset;
|
||||||
|
@@ -128,3 +126,5 @@ do_test (void)
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/debug/tst-longjmp_chk3.c b/debug/tst-longjmp_chk3.c
|
||||||
|
index 3155c7769fcbd83f..4434937c597dbe10 100644
|
||||||
|
--- a/debug/tst-longjmp_chk3.c
|
||||||
|
+++ b/debug/tst-longjmp_chk3.c
|
||||||
|
@@ -20,10 +20,6 @@
|
||||||
|
#include <signal.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
-static int do_test (void);
|
||||||
|
-#define TEST_FUNCTION do_test ()
|
||||||
|
-#include "../test-skeleton.c"
|
||||||
|
-
|
||||||
|
static char buf[SIGSTKSZ * 4];
|
||||||
|
static jmp_buf jb;
|
||||||
|
|
||||||
|
@@ -83,3 +79,5 @@ do_test (void)
|
||||||
|
puts ("longjmp returned and shouldn't");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
@ -0,0 +1,195 @@
|
|||||||
|
commit 388c9d7294e5ee3b741aef2e8af63eb1f76ace86
|
||||||
|
Author: Maciej W. Rozycki <macro@redhat.com>
|
||||||
|
Date: Fri Jul 26 13:21:34 2024 +0100
|
||||||
|
|
||||||
|
support: Add FAIL test failure helper
|
||||||
|
|
||||||
|
Add a FAIL test failure helper analogous to FAIL_RET, that does not
|
||||||
|
cause the current function to return, providing a standardized way to
|
||||||
|
report a test failure with a message supplied while permitting the
|
||||||
|
caller to continue executing, for further reporting, cleaning up, etc.
|
||||||
|
|
||||||
|
Update existing test cases that provide a conflicting definition of FAIL
|
||||||
|
by removing the local FAIL definition and then as follows:
|
||||||
|
|
||||||
|
- tst-fortify-syslog: provide a meaningful message in addition to the
|
||||||
|
file name already added by <support/check.h>; 'support_record_failure'
|
||||||
|
is already called by 'support_print_failure_impl' invoked by the new
|
||||||
|
FAIL test failure helper.
|
||||||
|
|
||||||
|
- tst-ctype: no update to FAIL calls required, with the name of the file
|
||||||
|
and the line number within of the failure site additionally included
|
||||||
|
by the new FAIL test failure helper, and error counting plus count
|
||||||
|
reporting upon test program termination also already provided by
|
||||||
|
'support_record_failure' and 'support_report_failure' respectively,
|
||||||
|
called by 'support_print_failure_impl' and 'adjust_exit_status' also
|
||||||
|
respectively. However in a number of places 'printf' is called and
|
||||||
|
the error count adjusted by hand, so update these places to make use
|
||||||
|
of FAIL instead. And last but not least adjust the final summary just
|
||||||
|
to report completion, with any error count following as reported by
|
||||||
|
the test driver.
|
||||||
|
|
||||||
|
- test-tgmath2: no update to FAIL calls required, with the name of the
|
||||||
|
file of the failure site additionally included by the new FAIL test
|
||||||
|
failure helper. Also there is no need to track the return status by
|
||||||
|
hand as any call to FAIL will eventually cause the test case to return
|
||||||
|
an unsuccesful exit status regardless of the return status from the
|
||||||
|
test function, via a call to 'adjust_exit_status' made by the test
|
||||||
|
driver.
|
||||||
|
|
||||||
|
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||||
|
(cherry picked from commit 1b97a9f23bf605ca608162089c94187573fb2a9e)
|
||||||
|
(cherry picked from commit 28f358bc4209ab0425170cdccf65bb1fe861148f)
|
||||||
|
|
||||||
|
diff --git a/localedata/tst-ctype.c b/localedata/tst-ctype.c
|
||||||
|
index 1e4fa132bb4e17c6..f8645e31db8a1691 100644
|
||||||
|
--- a/localedata/tst-ctype.c
|
||||||
|
+++ b/localedata/tst-ctype.c
|
||||||
|
@@ -22,6 +22,8 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
+#include <support/check.h>
|
||||||
|
+
|
||||||
|
|
||||||
|
static const char lower[] = "abcdefghijklmnopqrstuvwxyz";
|
||||||
|
static const char upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
@@ -54,19 +56,11 @@ static struct classes
|
||||||
|
#define nclasses (sizeof (classes) / sizeof (classes[0]))
|
||||||
|
|
||||||
|
|
||||||
|
-#define FAIL(str, args...) \
|
||||||
|
- { \
|
||||||
|
- printf (" " str "\n", ##args); \
|
||||||
|
- ++errors; \
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
-
|
||||||
|
static int
|
||||||
|
do_test (void)
|
||||||
|
{
|
||||||
|
const char *cp;
|
||||||
|
const char *cp2;
|
||||||
|
- int errors = 0;
|
||||||
|
char *inpline = NULL;
|
||||||
|
size_t inplinelen = 0;
|
||||||
|
char *resline = NULL;
|
||||||
|
@@ -395,11 +389,8 @@ punct = %04x alnum = %04x\n",
|
||||||
|
{
|
||||||
|
if (((__ctype_b[(unsigned int) *inp] & classes[n].mask) != 0)
|
||||||
|
!= (*resp != '0'))
|
||||||
|
- {
|
||||||
|
- printf (" is%s('%c' = '\\x%02x') %s true\n", inpline,
|
||||||
|
- *inp, *inp, *resp == '1' ? "not" : "is");
|
||||||
|
- ++errors;
|
||||||
|
- }
|
||||||
|
+ FAIL (" is%s('%c' = '\\x%02x') %s true\n", inpline,
|
||||||
|
+ *inp, *inp, *resp == '1' ? "not" : "is");
|
||||||
|
++inp;
|
||||||
|
++resp;
|
||||||
|
}
|
||||||
|
@@ -409,11 +400,8 @@ punct = %04x alnum = %04x\n",
|
||||||
|
while (*inp != '\0')
|
||||||
|
{
|
||||||
|
if (tolower (*inp) != *resp)
|
||||||
|
- {
|
||||||
|
- printf (" tolower('%c' = '\\x%02x') != '%c'\n",
|
||||||
|
- *inp, *inp, *resp);
|
||||||
|
- ++errors;
|
||||||
|
- }
|
||||||
|
+ FAIL (" tolower('%c' = '\\x%02x') != '%c'\n",
|
||||||
|
+ *inp, *inp, *resp);
|
||||||
|
++inp;
|
||||||
|
++resp;
|
||||||
|
}
|
||||||
|
@@ -423,11 +411,8 @@ punct = %04x alnum = %04x\n",
|
||||||
|
while (*inp != '\0')
|
||||||
|
{
|
||||||
|
if (toupper (*inp) != *resp)
|
||||||
|
- {
|
||||||
|
- printf (" toupper('%c' = '\\x%02x') != '%c'\n",
|
||||||
|
- *inp, *inp, *resp);
|
||||||
|
- ++errors;
|
||||||
|
- }
|
||||||
|
+ FAIL (" toupper('%c' = '\\x%02x') != '%c'\n",
|
||||||
|
+ *inp, *inp, *resp);
|
||||||
|
++inp;
|
||||||
|
++resp;
|
||||||
|
}
|
||||||
|
@@ -437,14 +422,7 @@ punct = %04x alnum = %04x\n",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- if (errors != 0)
|
||||||
|
- {
|
||||||
|
- printf (" %d error%s for `%s' locale\n\n\n", errors,
|
||||||
|
- errors == 1 ? "" : "s", setlocale (LC_ALL, NULL));
|
||||||
|
- return 1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- printf (" No errors for `%s' locale\n\n\n", setlocale (LC_ALL, NULL));
|
||||||
|
+ printf ("Completed testing for `%s' locale\n\n\n", setlocale (LC_ALL, NULL));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/math/test-tgmath2.c b/math/test-tgmath2.c
|
||||||
|
index b8fb00c566439ab0..e3b7a3a3615e083a 100644
|
||||||
|
--- a/math/test-tgmath2.c
|
||||||
|
+++ b/math/test-tgmath2.c
|
||||||
|
@@ -25,6 +25,8 @@
|
||||||
|
#include <string.h>
|
||||||
|
#include <tgmath.h>
|
||||||
|
|
||||||
|
+#include <support/check.h>
|
||||||
|
+
|
||||||
|
//#define DEBUG
|
||||||
|
|
||||||
|
typedef complex float cfloat;
|
||||||
|
@@ -88,13 +90,6 @@ enum
|
||||||
|
int count;
|
||||||
|
int counts[Tlast][C_last];
|
||||||
|
|
||||||
|
-#define FAIL(str) \
|
||||||
|
- do \
|
||||||
|
- { \
|
||||||
|
- printf ("%s failure on line %d\n", (str), __LINE__); \
|
||||||
|
- result = 1; \
|
||||||
|
- } \
|
||||||
|
- while (0)
|
||||||
|
#define TEST_TYPE_ONLY(expr, rettype) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
@@ -134,8 +129,6 @@ int counts[Tlast][C_last];
|
||||||
|
int
|
||||||
|
test_cos (const int Vint4, const long long int Vllong4)
|
||||||
|
{
|
||||||
|
- int result = 0;
|
||||||
|
-
|
||||||
|
TEST (cos (vfloat1), float, cos);
|
||||||
|
TEST (cos (vdouble1), double, cos);
|
||||||
|
TEST (cos (vldouble1), ldouble, cos);
|
||||||
|
@@ -153,7 +146,7 @@ test_cos (const int Vint4, const long long int Vllong4)
|
||||||
|
TEST (cos (Vcdouble1), cdouble, cos);
|
||||||
|
TEST (cos (Vcldouble1), cldouble, cos);
|
||||||
|
|
||||||
|
- return result;
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
diff --git a/support/check.h b/support/check.h
|
||||||
|
index 9b1844352f32513a..8e045dd9c0c36b4c 100644
|
||||||
|
--- a/support/check.h
|
||||||
|
+++ b/support/check.h
|
||||||
|
@@ -24,6 +24,11 @@
|
||||||
|
|
||||||
|
__BEGIN_DECLS
|
||||||
|
|
||||||
|
+/* Record a test failure, print the failure message to standard output
|
||||||
|
+ and pass the result of 1 through. */
|
||||||
|
+#define FAIL(...) \
|
||||||
|
+ support_print_failure_impl (__FILE__, __LINE__, __VA_ARGS__)
|
||||||
|
+
|
||||||
|
/* Record a test failure, print the failure message to standard output
|
||||||
|
and return 1. */
|
||||||
|
#define FAIL_RET(...) \
|
@ -0,0 +1,169 @@
|
|||||||
|
commit 86f5cfe77d60ca4f78f270adc7ae2c15a1d8d4bc
|
||||||
|
Author: Maciej W. Rozycki <macro@redhat.com>
|
||||||
|
Date: Fri Jul 26 13:21:34 2024 +0100
|
||||||
|
|
||||||
|
stdio-common: Add test for vfscanf with matches longer than INT_MAX [BZ #27650]
|
||||||
|
|
||||||
|
Complement commit b03e4d7bd25b ("stdio: fix vfscanf with matches longer
|
||||||
|
than INT_MAX (bug 27650)") and add a test case for the issue, inspired
|
||||||
|
by the reproducer provided with the bug report.
|
||||||
|
|
||||||
|
This has been verified to succeed as from the commit referred and fail
|
||||||
|
beforehand.
|
||||||
|
|
||||||
|
As the test requires 2GiB of data to be passed around its performance
|
||||||
|
has been evaluated using a choice of systems and the execution time
|
||||||
|
determined to be respectively in the range of 9s for POWER9@2.166GHz,
|
||||||
|
24s for FU740@1.2GHz, and 40s for 74Kf@950MHz. As this is on the verge
|
||||||
|
of and beyond the default timeout it has been increased by the factor of
|
||||||
|
8. Regardless, following recent practice the test has been added to the
|
||||||
|
standard rather than extended set.
|
||||||
|
|
||||||
|
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||||
|
(cherry picked from commit 89cddc8a7096f3d9225868304d2bc0a1aaf07d63)
|
||||||
|
(cherry picked from commit 99ffa84bdcdc3d81e82f448279f0c8278dd30964)
|
||||||
|
|
||||||
|
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
|
||||||
|
index 76d1d0a1193aa109..08bedd01be61a55d 100644
|
||||||
|
--- a/stdio-common/Makefile
|
||||||
|
+++ b/stdio-common/Makefile
|
||||||
|
@@ -190,6 +190,7 @@ tests := \
|
||||||
|
tst-put-error \
|
||||||
|
tst-renameat2 \
|
||||||
|
tst-rndseek \
|
||||||
|
+ tst-scanf-bz27650 \
|
||||||
|
tst-scanf-round \
|
||||||
|
tst-setvbuf1 \
|
||||||
|
tst-sprintf \
|
||||||
|
@@ -241,6 +242,7 @@ generated += \
|
||||||
|
tst-printf-fp-free.mtrace \
|
||||||
|
tst-printf-fp-leak-mem.out \
|
||||||
|
tst-printf-fp-leak.mtrace \
|
||||||
|
+ tst-scanf-bz27650.mtrace \
|
||||||
|
tst-vfprintf-width-prec-mem.out \
|
||||||
|
tst-vfprintf-width-prec.mtrace \
|
||||||
|
# generated
|
||||||
|
@@ -283,6 +285,9 @@ tst-printf-fp-free-ENV = \
|
||||||
|
tst-printf-fp-leak-ENV = \
|
||||||
|
MALLOC_TRACE=$(objpfx)tst-printf-fp-leak.mtrace \
|
||||||
|
LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
|
||||||
|
+tst-scanf-bz27650-ENV = \
|
||||||
|
+ MALLOC_TRACE=$(objpfx)tst-scanf-bz27650.mtrace \
|
||||||
|
+ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
|
||||||
|
|
||||||
|
$(objpfx)tst-unbputc.out: tst-unbputc.sh $(objpfx)tst-unbputc
|
||||||
|
$(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \
|
||||||
|
diff --git a/stdio-common/tst-scanf-bz27650.c b/stdio-common/tst-scanf-bz27650.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..3a742bc86556908c
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/stdio-common/tst-scanf-bz27650.c
|
||||||
|
@@ -0,0 +1,108 @@
|
||||||
|
+/* Test for BZ #27650, formatted input matching beyond INT_MAX.
|
||||||
|
+ Copyright (C) 2024 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 <error.h>
|
||||||
|
+#include <errno.h>
|
||||||
|
+#include <limits.h>
|
||||||
|
+#include <mcheck.h>
|
||||||
|
+#include <stddef.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+
|
||||||
|
+#include <sys/types.h>
|
||||||
|
+
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/test-driver.h>
|
||||||
|
+
|
||||||
|
+/* Produce a stream of more than INT_MAX characters via buffer BUF of
|
||||||
|
+ size SIZE according to bookkeeping in COOKIE and then return EOF. */
|
||||||
|
+
|
||||||
|
+static ssize_t
|
||||||
|
+io_read (void *cookie, char *buf, size_t size)
|
||||||
|
+{
|
||||||
|
+ unsigned int *written = cookie;
|
||||||
|
+ unsigned int w = *written;
|
||||||
|
+
|
||||||
|
+ if (w > INT_MAX)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ memset (buf, 'a', size);
|
||||||
|
+ *written = w + size;
|
||||||
|
+ return size;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Consume a stream of more than INT_MAX characters from an artificial
|
||||||
|
+ input stream of which none is the new line character. The call to
|
||||||
|
+ fscanf is supposed to complete upon the EOF condition of input,
|
||||||
|
+ however in the presence of BZ #27650 it will terminate prematurely
|
||||||
|
+ with characters still outstanding in input. Diagnose the condition
|
||||||
|
+ and return status accordingly. */
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ static cookie_io_functions_t io_funcs = { .read = io_read };
|
||||||
|
+ unsigned int written = 0;
|
||||||
|
+ FILE *in;
|
||||||
|
+ int v;
|
||||||
|
+
|
||||||
|
+ mtrace ();
|
||||||
|
+
|
||||||
|
+ in = fopencookie (&written, "r", io_funcs);
|
||||||
|
+ if (in == NULL)
|
||||||
|
+ {
|
||||||
|
+ FAIL ("fopencookie: %m");
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ v = fscanf (in, "%*[^\n]");
|
||||||
|
+ if (ferror (in))
|
||||||
|
+ {
|
||||||
|
+ FAIL ("fscanf: input failure, at %u: %m", written);
|
||||||
|
+ goto out_close;
|
||||||
|
+ }
|
||||||
|
+ else if (v == EOF)
|
||||||
|
+ {
|
||||||
|
+ FAIL ("fscanf: unexpected end of file, at %u", written);
|
||||||
|
+ goto out_close;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!feof (in))
|
||||||
|
+ {
|
||||||
|
+ v = fgetc (in);
|
||||||
|
+ if (ferror (in))
|
||||||
|
+ FAIL ("fgetc: input failure: %m");
|
||||||
|
+ else if (v == EOF)
|
||||||
|
+ FAIL ("fgetc: unexpected end of file after missing end of file");
|
||||||
|
+ else if (v == '\n')
|
||||||
|
+ FAIL ("unexpected new line character received");
|
||||||
|
+ else
|
||||||
|
+ FAIL ("character received after end of file expected: \\x%02x", v);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+out_close:
|
||||||
|
+ if (fclose (in) != 0)
|
||||||
|
+ FAIL ("fclose: %m");
|
||||||
|
+
|
||||||
|
+out:
|
||||||
|
+ return EXIT_SUCCESS;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#define TIMEOUT (DEFAULT_TIMEOUT * 8)
|
||||||
|
+#include <support/test-driver.c>
|
@ -0,0 +1,143 @@
|
|||||||
|
commit af68f0f6755c3b82ecef6dd67079df64eee8d946
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Wed Aug 14 19:20:04 2024 -0400
|
||||||
|
|
||||||
|
Make tst-ungetc use libsupport
|
||||||
|
|
||||||
|
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
(cherry picked from commit 3f7df7e757f4efec38e45d4068e5492efcac4856)
|
||||||
|
(cherry picked from commit 87a1968a72e4b4e5436f3e2be1ed8a8d5a5862c7)
|
||||||
|
|
||||||
|
diff --git a/stdio-common/tst-ungetc.c b/stdio-common/tst-ungetc.c
|
||||||
|
index 1344b2b591e3d6b1..5c808f073419f00b 100644
|
||||||
|
--- a/stdio-common/tst-ungetc.c
|
||||||
|
+++ b/stdio-common/tst-ungetc.c
|
||||||
|
@@ -1,70 +1,72 @@
|
||||||
|
-/* Test for ungetc bugs. */
|
||||||
|
+/* Test for ungetc bugs.
|
||||||
|
+ Copyright (C) 1996-2024 Free Software Foundation, Inc.
|
||||||
|
+ Copyright 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
|
||||||
|
+ 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 <unistd.h>
|
||||||
|
-
|
||||||
|
-#undef assert
|
||||||
|
-#define assert(x) \
|
||||||
|
- if (!(x)) \
|
||||||
|
- { \
|
||||||
|
- fputs ("test failed: " #x "\n", stderr); \
|
||||||
|
- retval = 1; \
|
||||||
|
- goto the_end; \
|
||||||
|
- }
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/support.h>
|
||||||
|
+#include <support/temp_file.h>
|
||||||
|
+#include <support/xstdio.h>
|
||||||
|
+#include <support/xunistd.h>
|
||||||
|
|
||||||
|
-int
|
||||||
|
-main (int argc, char *argv[])
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
{
|
||||||
|
- char name[] = "/tmp/tst-ungetc.XXXXXX";
|
||||||
|
+ char *name = NULL;
|
||||||
|
FILE *fp = NULL;
|
||||||
|
- int retval = 0;
|
||||||
|
int c;
|
||||||
|
char buffer[64];
|
||||||
|
|
||||||
|
- int fd = mkstemp (name);
|
||||||
|
+ int fd = create_temp_file ("tst-ungetc.", &name);
|
||||||
|
if (fd == -1)
|
||||||
|
- {
|
||||||
|
- printf ("mkstemp failed: %m\n");
|
||||||
|
- return 1;
|
||||||
|
- }
|
||||||
|
- close (fd);
|
||||||
|
- fp = fopen (name, "w");
|
||||||
|
- assert (fp != NULL)
|
||||||
|
- fputs ("bla", fp);
|
||||||
|
- fclose (fp);
|
||||||
|
- fp = NULL;
|
||||||
|
+ FAIL_EXIT1 ("cannot create temporary file: %m");
|
||||||
|
+ xclose (fd);
|
||||||
|
|
||||||
|
- fp = fopen (name, "r");
|
||||||
|
- assert (fp != NULL);
|
||||||
|
- assert (ungetc ('z', fp) == 'z');
|
||||||
|
- assert (getc (fp) == 'z');
|
||||||
|
- assert (getc (fp) == 'b');
|
||||||
|
- assert (getc (fp) == 'l');
|
||||||
|
- assert (ungetc ('m', fp) == 'm');
|
||||||
|
- assert (getc (fp) == 'm');
|
||||||
|
- assert ((c = getc (fp)) == 'a');
|
||||||
|
- assert (getc (fp) == EOF);
|
||||||
|
- assert (ungetc (c, fp) == c);
|
||||||
|
- assert (feof (fp) == 0);
|
||||||
|
- assert (getc (fp) == c);
|
||||||
|
- assert (getc (fp) == EOF);
|
||||||
|
- fclose (fp);
|
||||||
|
- fp = NULL;
|
||||||
|
+ fp = xfopen (name, "w");
|
||||||
|
+ fputs ("bla", fp);
|
||||||
|
+ xfclose (fp);
|
||||||
|
|
||||||
|
- fp = fopen (name, "r");
|
||||||
|
- assert (fp != NULL);
|
||||||
|
- assert (getc (fp) == 'b');
|
||||||
|
- assert (getc (fp) == 'l');
|
||||||
|
- assert (ungetc ('b', fp) == 'b');
|
||||||
|
- assert (fread (buffer, 1, 64, fp) == 2);
|
||||||
|
- assert (buffer[0] == 'b');
|
||||||
|
- assert (buffer[1] == 'a');
|
||||||
|
+ fp = xfopen (name, "r");
|
||||||
|
+ TEST_VERIFY_EXIT (ungetc ('z', fp) == 'z');
|
||||||
|
+ TEST_VERIFY_EXIT (getc (fp) == 'z');
|
||||||
|
+ TEST_VERIFY_EXIT (getc (fp) == 'b');
|
||||||
|
+ TEST_VERIFY_EXIT (getc (fp) == 'l');
|
||||||
|
+ TEST_VERIFY_EXIT (ungetc ('m', fp) == 'm');
|
||||||
|
+ TEST_VERIFY_EXIT (getc (fp) == 'm');
|
||||||
|
+ TEST_VERIFY_EXIT ((c = getc (fp)) == 'a');
|
||||||
|
+ TEST_VERIFY_EXIT (getc (fp) == EOF);
|
||||||
|
+ TEST_VERIFY_EXIT (ungetc (c, fp) == c);
|
||||||
|
+ TEST_VERIFY_EXIT (feof (fp) == 0);
|
||||||
|
+ TEST_VERIFY_EXIT (getc (fp) == c);
|
||||||
|
+ TEST_VERIFY_EXIT (getc (fp) == EOF);
|
||||||
|
+ xfclose (fp);
|
||||||
|
|
||||||
|
-the_end:
|
||||||
|
- if (fp != NULL)
|
||||||
|
- fclose (fp);
|
||||||
|
- unlink (name);
|
||||||
|
+ fp = xfopen (name, "r");
|
||||||
|
+ TEST_VERIFY_EXIT (getc (fp) == 'b');
|
||||||
|
+ TEST_VERIFY_EXIT (getc (fp) == 'l');
|
||||||
|
+ TEST_VERIFY_EXIT (ungetc ('b', fp) == 'b');
|
||||||
|
+ TEST_VERIFY_EXIT (fread (buffer, 1, 64, fp) == 2);
|
||||||
|
+ TEST_VERIFY_EXIT (buffer[0] == 'b');
|
||||||
|
+ TEST_VERIFY_EXIT (buffer[1] == 'a');
|
||||||
|
+ xfclose (fp);
|
||||||
|
|
||||||
|
- return retval;
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
@ -0,0 +1,71 @@
|
|||||||
|
commit 01a731da41a6d47cdd6b90f0da1d89dd8cf2b9cd
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Tue Aug 13 21:00:06 2024 -0400
|
||||||
|
|
||||||
|
ungetc: Fix uninitialized read when putting into unused streams [BZ #27821]
|
||||||
|
|
||||||
|
When ungetc is called on an unused stream, the backup buffer is
|
||||||
|
allocated without the main get area being present. This results in
|
||||||
|
every subsequent ungetc (as the stream remains in the backup area)
|
||||||
|
checking uninitialized memory in the backup buffer when trying to put a
|
||||||
|
character back into the stream.
|
||||||
|
|
||||||
|
Avoid comparing the input character with buffer contents when in backup
|
||||||
|
to avoid this uninitialized read. The uninitialized read is harmless in
|
||||||
|
this context since the location is promptly overwritten with the input
|
||||||
|
character, thus fulfilling ungetc functionality.
|
||||||
|
|
||||||
|
Also adjust wording in the manual to drop the paragraph that says glibc
|
||||||
|
cannot do multiple ungetc back to back since with this change, ungetc
|
||||||
|
can actually do this.
|
||||||
|
|
||||||
|
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
(cherry picked from commit cdf0f88f97b0aaceb894cc02b21159d148d7065c)
|
||||||
|
(cherry picked from commit 804d3c8db79db204154dcf5e11a76f14fdddc570)
|
||||||
|
|
||||||
|
diff --git a/libio/genops.c b/libio/genops.c
|
||||||
|
index fa509f6219abaf23..a5dd6a06d9e259d8 100644
|
||||||
|
--- a/libio/genops.c
|
||||||
|
+++ b/libio/genops.c
|
||||||
|
@@ -635,7 +635,7 @@ _IO_sputbackc (FILE *fp, int c)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
- if (fp->_IO_read_ptr > fp->_IO_read_base
|
||||||
|
+ if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp)
|
||||||
|
&& (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
|
||||||
|
{
|
||||||
|
fp->_IO_read_ptr--;
|
||||||
|
diff --git a/manual/stdio.texi b/manual/stdio.texi
|
||||||
|
index d3d855fc62b8768b..60ab7e7a5d505bb6 100644
|
||||||
|
--- a/manual/stdio.texi
|
||||||
|
+++ b/manual/stdio.texi
|
||||||
|
@@ -1467,11 +1467,9 @@ program; usually @code{ungetc} is used only to unread a character that
|
||||||
|
was just read from the same stream. @Theglibc{} supports this
|
||||||
|
even on files opened in binary mode, but other systems might not.
|
||||||
|
|
||||||
|
-@Theglibc{} only supports one character of pushback---in other
|
||||||
|
-words, it does not work to call @code{ungetc} twice without doing input
|
||||||
|
-in between. Other systems might let you push back multiple characters;
|
||||||
|
-then reading from the stream retrieves the characters in the reverse
|
||||||
|
-order that they were pushed.
|
||||||
|
+@Theglibc{} supports pushing back multiple characters; subsequently
|
||||||
|
+reading from the stream retrieves the characters in the reverse order
|
||||||
|
+that they were pushed.
|
||||||
|
|
||||||
|
Pushing back characters doesn't alter the file; only the internal
|
||||||
|
buffering for the stream is affected. If a file positioning function
|
||||||
|
diff --git a/stdio-common/tst-ungetc.c b/stdio-common/tst-ungetc.c
|
||||||
|
index 5c808f073419f00b..388b202493ddd586 100644
|
||||||
|
--- a/stdio-common/tst-ungetc.c
|
||||||
|
+++ b/stdio-common/tst-ungetc.c
|
||||||
|
@@ -48,6 +48,8 @@ do_test (void)
|
||||||
|
TEST_VERIFY_EXIT (getc (fp) == 'b');
|
||||||
|
TEST_VERIFY_EXIT (getc (fp) == 'l');
|
||||||
|
TEST_VERIFY_EXIT (ungetc ('m', fp) == 'm');
|
||||||
|
+ TEST_VERIFY_EXIT (ungetc ('n', fp) == 'n');
|
||||||
|
+ TEST_VERIFY_EXIT (getc (fp) == 'n');
|
||||||
|
TEST_VERIFY_EXIT (getc (fp) == 'm');
|
||||||
|
TEST_VERIFY_EXIT ((c = getc (fp)) == 'a');
|
||||||
|
TEST_VERIFY_EXIT (getc (fp) == EOF);
|
@ -0,0 +1,136 @@
|
|||||||
|
commit a5cd39541396b91d90cc611858ee7b3355fcfe47
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Tue Aug 13 21:08:49 2024 -0400
|
||||||
|
|
||||||
|
ungetc: Fix backup buffer leak on program exit [BZ #27821]
|
||||||
|
|
||||||
|
If a file descriptor is left unclosed and is cleaned up by _IO_cleanup
|
||||||
|
on exit, its backup buffer remains unfreed, registering as a leak in
|
||||||
|
valgrind. This is not strictly an issue since (1) the program should
|
||||||
|
ideally be closing the stream once it's not in use and (2) the program
|
||||||
|
is about to exit anyway, so keeping the backup buffer around a wee bit
|
||||||
|
longer isn't a real problem. Free it anyway to keep valgrind happy
|
||||||
|
when the streams in question are the standard ones, i.e. stdout, stdin
|
||||||
|
or stderr.
|
||||||
|
|
||||||
|
Also, the _IO_have_backup macro checks for _IO_save_base,
|
||||||
|
which is a roundabout way to check for a backup buffer instead of
|
||||||
|
directly looking for _IO_backup_base. The roundabout check breaks when
|
||||||
|
the main get area has not been used and user pushes a char into the
|
||||||
|
backup buffer with ungetc. Fix this to use the _IO_backup_base
|
||||||
|
directly.
|
||||||
|
|
||||||
|
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
(cherry picked from commit 3e1d8d1d1dca24ae90df2ea826a8916896fc7e77)
|
||||||
|
(cherry picked from commit b9f72bd5de931eac39219018c2fa319a449bb2cf)
|
||||||
|
|
||||||
|
diff --git a/libio/genops.c b/libio/genops.c
|
||||||
|
index a5dd6a06d9e259d8..b5fc53fd1ef6e911 100644
|
||||||
|
--- a/libio/genops.c
|
||||||
|
+++ b/libio/genops.c
|
||||||
|
@@ -796,6 +796,12 @@ _IO_unbuffer_all (void)
|
||||||
|
legacy = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+ /* Free up the backup area if it was ever allocated. */
|
||||||
|
+ if (_IO_have_backup (fp))
|
||||||
|
+ _IO_free_backup_area (fp);
|
||||||
|
+ if (fp->_mode > 0 && _IO_have_wbackup (fp))
|
||||||
|
+ _IO_free_wbackup_area (fp);
|
||||||
|
+
|
||||||
|
if (! (fp->_flags & _IO_UNBUFFERED)
|
||||||
|
/* Iff stream is un-orientated, it wasn't used. */
|
||||||
|
&& (legacy || fp->_mode != 0))
|
||||||
|
diff --git a/libio/libioP.h b/libio/libioP.h
|
||||||
|
index dc9a2ce9c8d7744c..bab5f3770f0760c4 100644
|
||||||
|
--- a/libio/libioP.h
|
||||||
|
+++ b/libio/libioP.h
|
||||||
|
@@ -529,8 +529,8 @@ extern void _IO_old_init (FILE *fp, int flags) __THROW;
|
||||||
|
((__fp)->_wide_data->_IO_write_base \
|
||||||
|
= (__fp)->_wide_data->_IO_write_ptr = __p, \
|
||||||
|
(__fp)->_wide_data->_IO_write_end = (__ep))
|
||||||
|
-#define _IO_have_backup(fp) ((fp)->_IO_save_base != NULL)
|
||||||
|
-#define _IO_have_wbackup(fp) ((fp)->_wide_data->_IO_save_base != NULL)
|
||||||
|
+#define _IO_have_backup(fp) ((fp)->_IO_backup_base != NULL)
|
||||||
|
+#define _IO_have_wbackup(fp) ((fp)->_wide_data->_IO_backup_base != NULL)
|
||||||
|
#define _IO_in_backup(fp) ((fp)->_flags & _IO_IN_BACKUP)
|
||||||
|
#define _IO_have_markers(fp) ((fp)->_markers != NULL)
|
||||||
|
#define _IO_blen(fp) ((fp)->_IO_buf_end - (fp)->_IO_buf_base)
|
||||||
|
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
|
||||||
|
index 08bedd01be61a55d..f10bf28878e0aebc 100644
|
||||||
|
--- a/stdio-common/Makefile
|
||||||
|
+++ b/stdio-common/Makefile
|
||||||
|
@@ -201,6 +201,7 @@ tests := \
|
||||||
|
tst-swscanf \
|
||||||
|
tst-tmpnam \
|
||||||
|
tst-ungetc \
|
||||||
|
+ tst-ungetc-leak \
|
||||||
|
tst-unlockedio \
|
||||||
|
tst-vfprintf-mbs-prec \
|
||||||
|
tst-vfprintf-user-type \
|
||||||
|
@@ -229,6 +230,7 @@ tests-special += \
|
||||||
|
$(objpfx)tst-printfsz-islongdouble.out \
|
||||||
|
$(objpfx)tst-setvbuf1-cmp.out \
|
||||||
|
$(objpfx)tst-unbputc.out \
|
||||||
|
+ $(objpfx)tst-ungetc-leak-mem.out \
|
||||||
|
$(objpfx)tst-vfprintf-width-prec-mem.out \
|
||||||
|
# tests-special
|
||||||
|
|
||||||
|
@@ -243,6 +245,8 @@ generated += \
|
||||||
|
tst-printf-fp-leak-mem.out \
|
||||||
|
tst-printf-fp-leak.mtrace \
|
||||||
|
tst-scanf-bz27650.mtrace \
|
||||||
|
+ tst-ungetc-leak-mem.out \
|
||||||
|
+ tst-ungetc-leak.mtrace \
|
||||||
|
tst-vfprintf-width-prec-mem.out \
|
||||||
|
tst-vfprintf-width-prec.mtrace \
|
||||||
|
# generated
|
||||||
|
@@ -288,6 +292,9 @@ tst-printf-fp-leak-ENV = \
|
||||||
|
tst-scanf-bz27650-ENV = \
|
||||||
|
MALLOC_TRACE=$(objpfx)tst-scanf-bz27650.mtrace \
|
||||||
|
LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
|
||||||
|
+tst-ungetc-leak-ENV = \
|
||||||
|
+ MALLOC_TRACE=$(objpfx)tst-ungetc-leak.mtrace \
|
||||||
|
+ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
|
||||||
|
|
||||||
|
$(objpfx)tst-unbputc.out: tst-unbputc.sh $(objpfx)tst-unbputc
|
||||||
|
$(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \
|
||||||
|
diff --git a/stdio-common/tst-ungetc-leak.c b/stdio-common/tst-ungetc-leak.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..6c5152b43f80b217
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/stdio-common/tst-ungetc-leak.c
|
||||||
|
@@ -0,0 +1,32 @@
|
||||||
|
+/* Test for memory leak with ungetc when stream is unused.
|
||||||
|
+ Copyright 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
|
||||||
|
+ 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 <mcheck.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/support.h>
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ mtrace ();
|
||||||
|
+ TEST_COMPARE (ungetc('y', stdin), 'y');
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
@ -0,0 +1,83 @@
|
|||||||
|
commit 9d26e50364def249e483b1601beb6ecf9141ecc7
|
||||||
|
Author: Maciej W. Rozycki <macro@redhat.com>
|
||||||
|
Date: Fri Jul 26 13:21:34 2024 +0100
|
||||||
|
|
||||||
|
posix: Use <support/check.h> facilities in tst-truncate and tst-truncate64
|
||||||
|
|
||||||
|
Remove local FAIL macro in favor to FAIL_RET from <support/check.h>,
|
||||||
|
which provides equivalent reporting, with the name of the file of the
|
||||||
|
failure site additionally included, for the tst-truncate-common core
|
||||||
|
shared between the tst-truncate and tst-truncate64 tests.
|
||||||
|
|
||||||
|
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||||
|
(cherry picked from commit fe47595504a55e7bb992f8928533df154b510383)
|
||||||
|
|
||||||
|
diff --git a/posix/tst-truncate-common.c b/posix/tst-truncate-common.c
|
||||||
|
index 00c999d372693bfa..1f6c4bd256a638f9 100644
|
||||||
|
--- a/posix/tst-truncate-common.c
|
||||||
|
+++ b/posix/tst-truncate-common.c
|
||||||
|
@@ -21,6 +21,8 @@
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
+#include <support/check.h>
|
||||||
|
+
|
||||||
|
static void do_prepare (void);
|
||||||
|
#define PREPARE(argc, argv) do_prepare ()
|
||||||
|
static int do_test (void);
|
||||||
|
@@ -42,9 +44,6 @@ do_prepare (void)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-#define FAIL(str) \
|
||||||
|
- do { printf ("error: %s (line %d)\n", str, __LINE__); return 1; } while (0)
|
||||||
|
-
|
||||||
|
static int
|
||||||
|
do_test_with_offset (off_t offset)
|
||||||
|
{
|
||||||
|
@@ -54,35 +53,35 @@ do_test_with_offset (off_t offset)
|
||||||
|
memset (buf, 0xcf, sizeof (buf));
|
||||||
|
|
||||||
|
if (pwrite (temp_fd, buf, sizeof (buf), offset) != sizeof (buf))
|
||||||
|
- FAIL ("write failed");
|
||||||
|
+ FAIL_RET ("write failed");
|
||||||
|
if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + sizeof (buf)))
|
||||||
|
- FAIL ("initial size wrong");
|
||||||
|
+ FAIL_RET ("initial size wrong");
|
||||||
|
|
||||||
|
if (ftruncate (temp_fd, offset + 800) < 0)
|
||||||
|
- FAIL ("size reduction with ftruncate failed");
|
||||||
|
+ FAIL_RET ("size reduction with ftruncate failed");
|
||||||
|
if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + 800))
|
||||||
|
- FAIL ("size after reduction with ftruncate is incorrect");
|
||||||
|
+ FAIL_RET ("size after reduction with ftruncate is incorrect");
|
||||||
|
|
||||||
|
/* The following test covers more than POSIX. POSIX does not require
|
||||||
|
that ftruncate() can increase the file size. But we are testing
|
||||||
|
Unix systems. */
|
||||||
|
if (ftruncate (temp_fd, offset + 1200) < 0)
|
||||||
|
- FAIL ("size increate with ftruncate failed");
|
||||||
|
+ FAIL_RET ("size increate with ftruncate failed");
|
||||||
|
if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + 1200))
|
||||||
|
- FAIL ("size after increase is incorrect");
|
||||||
|
+ FAIL_RET ("size after increase is incorrect");
|
||||||
|
|
||||||
|
if (truncate (temp_filename, offset + 800) < 0)
|
||||||
|
- FAIL ("size reduction with truncate failed");
|
||||||
|
+ FAIL_RET ("size reduction with truncate failed");
|
||||||
|
if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + 800))
|
||||||
|
- FAIL ("size after reduction with truncate incorrect");
|
||||||
|
+ FAIL_RET ("size after reduction with truncate incorrect");
|
||||||
|
|
||||||
|
/* The following test covers more than POSIX. POSIX does not require
|
||||||
|
that truncate() can increase the file size. But we are testing
|
||||||
|
Unix systems. */
|
||||||
|
if (truncate (temp_filename, (offset + 1200)) < 0)
|
||||||
|
- FAIL ("size increase with truncate failed");
|
||||||
|
+ FAIL_RET ("size increase with truncate failed");
|
||||||
|
if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + 1200))
|
||||||
|
- FAIL ("size increase with truncate is incorrect");
|
||||||
|
+ FAIL_RET ("size increase with truncate is incorrect");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,129 @@
|
|||||||
|
commit c21ca2a696c03ff3f3931768a3ada234eebf6337
|
||||||
|
Author: Maciej W. Rozycki <macro@redhat.com>
|
||||||
|
Date: Fri Jul 26 13:21:34 2024 +0100
|
||||||
|
|
||||||
|
nptl: Use <support/check.h> facilities in tst-setuid3
|
||||||
|
|
||||||
|
Remove local FAIL macro in favor to FAIL_EXIT1 from <support/check.h>,
|
||||||
|
which provides equivalent reporting, with the name of the file and the
|
||||||
|
line number within of the failure site additionally included. Remove
|
||||||
|
FAIL_ERR altogether and include ": %m" explicitly with the format string
|
||||||
|
supplied to FAIL_EXIT1 as there seems little value to have a separate
|
||||||
|
macro just for this.
|
||||||
|
|
||||||
|
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||||
|
(cherry picked from commit 8c98195af6e6f1ce21743fc26c723e0f7e45bcf2)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/pthread/tst-setuid3.c b/sysdeps/pthread/tst-setuid3.c
|
||||||
|
index 254555960e1ffe74..88a2a3ef20e273f7 100644
|
||||||
|
--- a/sysdeps/pthread/tst-setuid3.c
|
||||||
|
+++ b/sysdeps/pthread/tst-setuid3.c
|
||||||
|
@@ -15,24 +15,19 @@
|
||||||
|
License along with the GNU C Library; if not, see
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
-#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
+#include <support/check.h>
|
||||||
|
+
|
||||||
|
/* The test must run under a non-privileged user ID. */
|
||||||
|
static const uid_t test_uid = 1;
|
||||||
|
|
||||||
|
static pthread_barrier_t barrier1;
|
||||||
|
static pthread_barrier_t barrier2;
|
||||||
|
|
||||||
|
-#define FAIL(fmt, ...) \
|
||||||
|
- do { printf ("FAIL: " fmt "\n", __VA_ARGS__); _exit (1); } while (0)
|
||||||
|
-
|
||||||
|
-#define FAIL_ERR(fmt, ...) \
|
||||||
|
- do { printf ("FAIL: " fmt ": %m\n", __VA_ARGS__); _exit (1); } while (0)
|
||||||
|
-
|
||||||
|
/* True if x is not a successful return code from pthread_barrier_wait. */
|
||||||
|
static inline bool
|
||||||
|
is_invalid_barrier_ret (int x)
|
||||||
|
@@ -45,10 +40,10 @@ thread_func (void *ctx __attribute__ ((unused)))
|
||||||
|
{
|
||||||
|
int ret = pthread_barrier_wait (&barrier1);
|
||||||
|
if (is_invalid_barrier_ret (ret))
|
||||||
|
- FAIL ("pthread_barrier_wait (barrier1) (on thread): %d", ret);
|
||||||
|
+ FAIL_EXIT1 ("pthread_barrier_wait (barrier1) (on thread): %d", ret);
|
||||||
|
ret = pthread_barrier_wait (&barrier2);
|
||||||
|
if (is_invalid_barrier_ret (ret))
|
||||||
|
- FAIL ("pthread_barrier_wait (barrier2) (on thread): %d", ret);
|
||||||
|
+ FAIL_EXIT1 ("pthread_barrier_wait (barrier2) (on thread): %d", ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -59,13 +54,13 @@ setuid_failure (int phase)
|
||||||
|
switch (ret)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
- FAIL ("setuid succeeded unexpectedly in phase %d", phase);
|
||||||
|
+ FAIL_EXIT1 ("setuid succeeded unexpectedly in phase %d", phase);
|
||||||
|
case -1:
|
||||||
|
if (errno != EPERM)
|
||||||
|
- FAIL_ERR ("setuid phase %d", phase);
|
||||||
|
+ FAIL_EXIT1 ("setuid phase %d: %m", phase);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
- FAIL ("invalid setuid return value in phase %d: %d", phase, ret);
|
||||||
|
+ FAIL_EXIT1 ("invalid setuid return value in phase %d: %d", phase, ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -74,42 +69,42 @@ do_test (void)
|
||||||
|
{
|
||||||
|
if (getuid () == 0)
|
||||||
|
if (setuid (test_uid) != 0)
|
||||||
|
- FAIL_ERR ("setuid (%u)", (unsigned) test_uid);
|
||||||
|
+ FAIL_EXIT1 ("setuid (%u): %m", (unsigned) test_uid);
|
||||||
|
if (setuid (getuid ()))
|
||||||
|
- FAIL_ERR ("setuid (%s)", "getuid ()");
|
||||||
|
+ FAIL_EXIT1 ("setuid (%s): %m", "getuid ()");
|
||||||
|
setuid_failure (1);
|
||||||
|
|
||||||
|
int ret = pthread_barrier_init (&barrier1, NULL, 2);
|
||||||
|
if (ret != 0)
|
||||||
|
- FAIL ("pthread_barrier_init (barrier1): %d", ret);
|
||||||
|
+ FAIL_EXIT1 ("pthread_barrier_init (barrier1): %d", ret);
|
||||||
|
ret = pthread_barrier_init (&barrier2, NULL, 2);
|
||||||
|
if (ret != 0)
|
||||||
|
- FAIL ("pthread_barrier_init (barrier2): %d", ret);
|
||||||
|
+ FAIL_EXIT1 ("pthread_barrier_init (barrier2): %d", ret);
|
||||||
|
|
||||||
|
pthread_t thread;
|
||||||
|
ret = pthread_create (&thread, NULL, thread_func, NULL);
|
||||||
|
if (ret != 0)
|
||||||
|
- FAIL ("pthread_create: %d", ret);
|
||||||
|
+ FAIL_EXIT1 ("pthread_create: %d", ret);
|
||||||
|
|
||||||
|
/* Ensure that the thread is running properly. */
|
||||||
|
ret = pthread_barrier_wait (&barrier1);
|
||||||
|
if (is_invalid_barrier_ret (ret))
|
||||||
|
- FAIL ("pthread_barrier_wait (barrier1): %d", ret);
|
||||||
|
+ FAIL_EXIT1 ("pthread_barrier_wait (barrier1): %d", ret);
|
||||||
|
|
||||||
|
setuid_failure (2);
|
||||||
|
|
||||||
|
/* Check success case. */
|
||||||
|
if (setuid (getuid ()) != 0)
|
||||||
|
- FAIL_ERR ("setuid (%s)", "getuid ()");
|
||||||
|
+ FAIL_EXIT1 ("setuid (%s): %m", "getuid ()");
|
||||||
|
|
||||||
|
/* Shutdown. */
|
||||||
|
ret = pthread_barrier_wait (&barrier2);
|
||||||
|
if (is_invalid_barrier_ret (ret))
|
||||||
|
- FAIL ("pthread_barrier_wait (barrier2): %d", ret);
|
||||||
|
+ FAIL_EXIT1 ("pthread_barrier_wait (barrier2): %d", ret);
|
||||||
|
|
||||||
|
ret = pthread_join (thread, NULL);
|
||||||
|
if (ret != 0)
|
||||||
|
- FAIL ("pthread_join: %d", ret);
|
||||||
|
+ FAIL_EXIT1 ("pthread_join: %d", ret);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
commit ae4d44b1d501421ad9a3af95279b8f4d1546f1ce
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Tue Sep 3 14:58:33 2024 -0400
|
||||||
|
|
||||||
|
libio: Attempt wide backup free only for non-legacy code
|
||||||
|
|
||||||
|
_wide_data and _mode are not available in legacy code, so do not attempt
|
||||||
|
to free the wide backup buffer in legacy code.
|
||||||
|
|
||||||
|
Resolves: BZ #32137 and BZ #27821
|
||||||
|
|
||||||
|
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/libio/genops.c b/libio/genops.c
|
||||||
|
index b5fc53fd1ef6e911..99ef9d03505f3238 100644
|
||||||
|
--- a/libio/genops.c
|
||||||
|
+++ b/libio/genops.c
|
||||||
|
@@ -799,7 +799,7 @@ _IO_unbuffer_all (void)
|
||||||
|
/* Free up the backup area if it was ever allocated. */
|
||||||
|
if (_IO_have_backup (fp))
|
||||||
|
_IO_free_backup_area (fp);
|
||||||
|
- if (fp->_mode > 0 && _IO_have_wbackup (fp))
|
||||||
|
+ if (!legacy && fp->_mode > 0 && _IO_have_wbackup (fp))
|
||||||
|
_IO_free_wbackup_area (fp);
|
||||||
|
|
||||||
|
if (! (fp->_flags & _IO_UNBUFFERED)
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Loading…
Reference in new issue