forked from rpms/glibc
Import glibc-2.34-32.fc35 from f35
* Thu Apr 28 2022 Carlos O'Donell <carlos@redhat.com> - 2.34-32 - Sync with upstream branch release/2.34/master, commit c66c92181ddbd82306537a608e8c0282587131de: - posix/glob.c: update from gnulib (BZ#25659) - linux: Fix fchmodat with AT_SYMLINK_NOFOLLOW for 64 bit time_t (BZ#29097) * Wed Apr 27 2022 Carlos O'Donell <carlos@redhat.com> - 2.34-31 - Sync with upstream branch release/2.34/master, commit 55640ed3fde48360a8e8083be4843bd2dc7cecfe: - i386: Regenerate ulps - linux: Fix missing internal 64 bit time_t stat usage - x86: Optimize L(less_vec) case in memcmp-evex-movbe.S - x86: Don't set Prefer_No_AVX512 for processors with AVX512 and AVX-VNNI - x86-64: Use notl in EVEX strcmp [BZ #28646] - x86: Shrink memcmp-sse4.S code size - x86: Double size of ERMS rep_movsb_threshold in dl-cacheinfo.h - x86: Optimize memmove-vec-unaligned-erms.S - x86-64: Replace movzx with movzbl - x86-64: Remove Prefer_AVX2_STRCMP - x86-64: Improve EVEX strcmp with masked load - x86: Replace sse2 instructions with avx in memcmp-evex-movbe.S - x86: Optimize memset-vec-unaligned-erms.S - x86: Optimize memcmp-evex-movbe.S for frontend behavior and size - x86: Modify ENTRY in sysdep.h so that p2align can be specified - x86-64: Optimize load of all bits set into ZMM register [BZ #28252] - scripts/glibcelf.py: Mark as UNSUPPORTED on Python 3.5 and earlier - dlfcn: Do not use rtld_active () to determine ld.so state (bug 29078) - INSTALL: Rephrase -with-default-link documentation - misc: Fix rare fortify crash on wchar funcs. [BZ 29030] - Default to --with-default-link=no (bug 25812) - scripts: Add glibcelf.py module * Thu Apr 21 2022 Carlos O'Donell <carlos@redhat.com> - 2.34-30 - Sync with upstream branch release/2.34/master, commit 71326f1f2fd09dafb9c34404765fb88129e94237: - nptl: Fix pthread_cancel cancelhandling atomic operations - mips: Fix mips64n32 64 bit time_t stat support (BZ#29069) - hurd: Fix arbitrary error code - nptl: Handle spurious EINTR when thread cancellation is disabled (BZ#29029) - S390: Add new s390 platform z16. - NEWS: Update fixed bug list for LD_AUDIT backports. - hppa: Fix bind-now audit (BZ #28857) - elf: Replace tst-audit24bmod2.so with tst-audit24bmod2 - Fix elf/tst-audit25a with default bind now toolchains - elf: Fix runtime linker auditing on aarch64 (BZ #26643) - elf: Issue la_symbind for bind-now (BZ #23734) - elf: Fix initial-exec TLS access on audit modules (BZ #28096) - elf: Add la_activity during application exit - elf: Do not fail for failed dlmopen on audit modules (BZ #28061) - elf: Issue audit la_objopen for vDSO - elf: Add audit tests for modules with TLSDESC - elf: Avoid unnecessary slowdown from profiling with audit (BZ#15533) - elf: Add _dl_audit_pltexit - elf: Add _dl_audit_pltenter - elf: Add _dl_audit_preinit - elf: Add _dl_audit_symbind_alt and _dl_audit_symbind - elf: Add _dl_audit_objclose - elf: Add _dl_audit_objsearch - elf: Add _dl_audit_activity_map and _dl_audit_activity_nsid - elf: Add _dl_audit_objopen - elf: Move la_activity (LA_ACT_ADD) after _dl_add_to_namespace_list() (BZ #28062) - elf: Move LAV_CURRENT to link_lavcurrent.h - elf: Fix elf_get_dynamic_info() for bootstrap - elf: Fix dynamic-link.h usage on rtld.c - elf: Fix elf_get_dynamic_info definition - elf: Avoid nested functions in the loader [BZ #27220] - powerpc: Delete unneeded ELF_MACHINE_BEFORE_RTLD_RELOC - hppa: Use END instead of PSEUDO_END in swapcontext.S - hppa: Implement swapcontext in assembler (bug 28960) Resolves: #2003291 Resolves: #2064181 Resolves: #2072328 Resolves: #2075713 Resolves: #2077838
This commit is contained in:
parent
42eb238e49
commit
73667d0be6
178
glibc-upstream-2.34-133.patch
Normal file
178
glibc-upstream-2.34-133.patch
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
commit 738ee53f0ce5e39b9b7a6777f5d3057afbaac498
|
||||||
|
Author: John David Anglin <danglin@gcc.gnu.org>
|
||||||
|
Date: Tue Mar 15 23:12:37 2022 +0000
|
||||||
|
|
||||||
|
hppa: Implement swapcontext in assembler (bug 28960)
|
||||||
|
|
||||||
|
When swapcontext.c is compiled without -g, the following error occurs:
|
||||||
|
Error: CFI instruction used without previous .cfi_startproc
|
||||||
|
|
||||||
|
Fix by converting swapcontext routine to assembler.
|
||||||
|
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/hppa/swapcontext.S b/sysdeps/unix/sysv/linux/hppa/swapcontext.S
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..94b164dc6375563e
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/hppa/swapcontext.S
|
||||||
|
@@ -0,0 +1,72 @@
|
||||||
|
+/* Swap to new context.
|
||||||
|
+ Copyright (C) 2008-2022 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library. If not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <sysdep.h>
|
||||||
|
+#include "ucontext_i.h"
|
||||||
|
+
|
||||||
|
+ .text
|
||||||
|
+ENTRY(__swapcontext)
|
||||||
|
+
|
||||||
|
+ /* Copy rp to ret0 (r28). */
|
||||||
|
+ copy %rp,%ret0
|
||||||
|
+
|
||||||
|
+ /* Create a frame. */
|
||||||
|
+ ldo 64(%sp),%sp
|
||||||
|
+ .cfi_def_cfa_offset -64
|
||||||
|
+
|
||||||
|
+ /* Save the current machine context to oucp. */
|
||||||
|
+ bl __getcontext,%rp
|
||||||
|
+
|
||||||
|
+ /* Copy oucp to register ret1 (r29). __getcontext saves and
|
||||||
|
+ restores it on a normal return. It is restored from oR29
|
||||||
|
+ on reactivation. */
|
||||||
|
+ copy %r26,%ret1
|
||||||
|
+
|
||||||
|
+ /* Pop frame. */
|
||||||
|
+ ldo -64(%sp),%sp
|
||||||
|
+ .cfi_def_cfa_offset 0
|
||||||
|
+
|
||||||
|
+ /* Load return pointer from oR28. */
|
||||||
|
+ ldw oR28(%ret1),%rp
|
||||||
|
+
|
||||||
|
+ /* Return if error. */
|
||||||
|
+ or,= %r0,%ret0,%r0
|
||||||
|
+ bv,n %r0(%rp)
|
||||||
|
+
|
||||||
|
+ /* Load sc_sar flag. */
|
||||||
|
+ ldb oSAR(%ret1),%r20
|
||||||
|
+
|
||||||
|
+ /* Return if oucp context has been reactivated. */
|
||||||
|
+ or,= %r0,%r20,%r0
|
||||||
|
+ bv,n %r0(%rp)
|
||||||
|
+
|
||||||
|
+ /* Mark sc_sar flag. */
|
||||||
|
+ ldi 1,%r20
|
||||||
|
+ stb %r20,oSAR(%ret1)
|
||||||
|
+
|
||||||
|
+ /* Activate the machine context in ucp. */
|
||||||
|
+ bl __setcontext,%rp
|
||||||
|
+ ldw oR25(%ret1),%r26
|
||||||
|
+
|
||||||
|
+ /* Load return pointer. */
|
||||||
|
+ ldw oR28(%ret1),%rp
|
||||||
|
+ bv,n %r0(%rp)
|
||||||
|
+
|
||||||
|
+PSEUDO_END(__swapcontext)
|
||||||
|
+
|
||||||
|
+weak_alias (__swapcontext, swapcontext)
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/hppa/swapcontext.c b/sysdeps/unix/sysv/linux/hppa/swapcontext.c
|
||||||
|
deleted file mode 100644
|
||||||
|
index 1664f68c7b9982e8..0000000000000000
|
||||||
|
--- a/sysdeps/unix/sysv/linux/hppa/swapcontext.c
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,83 +0,0 @@
|
||||||
|
-/* Swap to new context.
|
||||||
|
- Copyright (C) 2008-2021 Free Software Foundation, Inc.
|
||||||
|
- This file is part of the GNU C Library.
|
||||||
|
- Contributed by Helge Deller <deller@gmx.de>, 2008.
|
||||||
|
-
|
||||||
|
- 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 <ucontext.h>
|
||||||
|
-#include "ucontext_i.h"
|
||||||
|
-
|
||||||
|
-extern int __getcontext (ucontext_t *ucp);
|
||||||
|
-extern int __setcontext (const ucontext_t *ucp);
|
||||||
|
-
|
||||||
|
-int
|
||||||
|
-__swapcontext (ucontext_t *oucp, const ucontext_t *ucp)
|
||||||
|
-{
|
||||||
|
- /* Save rp for debugger. */
|
||||||
|
- asm ("stw %rp,-20(%sp)");
|
||||||
|
- asm (".cfi_offset 2, -20");
|
||||||
|
-
|
||||||
|
- /* Copy rp to ret0 (r28). */
|
||||||
|
- asm ("copy %rp,%ret0");
|
||||||
|
-
|
||||||
|
- /* Create a frame. */
|
||||||
|
- asm ("ldo 64(%sp),%sp");
|
||||||
|
- asm (".cfi_def_cfa_offset -64");
|
||||||
|
-
|
||||||
|
- /* Save the current machine context to oucp. */
|
||||||
|
- asm ("bl __getcontext,%rp");
|
||||||
|
-
|
||||||
|
- /* Copy oucp to register ret1 (r29). __getcontext saves and restores it
|
||||||
|
- on a normal return. It is restored from oR29 on reactivation. */
|
||||||
|
- asm ("copy %r26,%ret1");
|
||||||
|
-
|
||||||
|
- /* Pop frame. */
|
||||||
|
- asm ("ldo -64(%sp),%sp");
|
||||||
|
- asm (".cfi_def_cfa_offset 0");
|
||||||
|
-
|
||||||
|
- /* Load return pointer from oR28. */
|
||||||
|
- asm ("ldw %0(%%ret1),%%rp" : : "i" (oR28));
|
||||||
|
-
|
||||||
|
- /* Return if error. */
|
||||||
|
- asm ("or,= %r0,%ret0,%r0");
|
||||||
|
- asm ("bv,n %r0(%rp)");
|
||||||
|
-
|
||||||
|
- /* Load sc_sar flag. */
|
||||||
|
- asm ("ldb %0(%%ret1),%%r20" : : "i" (oSAR));
|
||||||
|
-
|
||||||
|
- /* Return if oucp context has been reactivated. */
|
||||||
|
- asm ("or,= %r0,%r20,%r0");
|
||||||
|
- asm ("bv,n %r0(%rp)");
|
||||||
|
-
|
||||||
|
- /* Mark sc_sar flag. */
|
||||||
|
- asm ("1: ldi 1,%r20");
|
||||||
|
- asm ("stb %%r20,%0(%%ret1)" : : "i" (oSAR));
|
||||||
|
-
|
||||||
|
- /* Activate the machine context in ucp. */
|
||||||
|
- asm ("bl __setcontext,%rp");
|
||||||
|
- asm ("ldw %0(%%ret1),%%r26" : : "i" (oR25));
|
||||||
|
-
|
||||||
|
- /* Load return pointer. */
|
||||||
|
- asm ("ldw %0(%%ret1),%%rp" : : "i" (oR28));
|
||||||
|
-
|
||||||
|
- /* A successful call to setcontext does not return. */
|
||||||
|
- asm ("bv,n %r0(%rp)");
|
||||||
|
-
|
||||||
|
- /* Make gcc happy. */
|
||||||
|
- return 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-weak_alias (__swapcontext, swapcontext)
|
20
glibc-upstream-2.34-134.patch
Normal file
20
glibc-upstream-2.34-134.patch
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
commit d53b9cc391c72a1011ea8fe7a9f70dc5060a0db2
|
||||||
|
Author: John David Anglin <danglin@gcc.gnu.org>
|
||||||
|
Date: Tue Mar 15 23:04:39 2022 +0000
|
||||||
|
|
||||||
|
hppa: Use END instead of PSEUDO_END in swapcontext.S
|
||||||
|
|
||||||
|
(cherry picked from commit 7a5c440102d4ec7fafd9bbd98eca9bd90ecaaafd)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/hppa/swapcontext.S b/sysdeps/unix/sysv/linux/hppa/swapcontext.S
|
||||||
|
index 94b164dc6375563e..fbc22586d1195a0d 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/hppa/swapcontext.S
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/hppa/swapcontext.S
|
||||||
|
@@ -67,6 +67,6 @@ ENTRY(__swapcontext)
|
||||||
|
ldw oR28(%ret1),%rp
|
||||||
|
bv,n %r0(%rp)
|
||||||
|
|
||||||
|
-PSEUDO_END(__swapcontext)
|
||||||
|
+END(__swapcontext)
|
||||||
|
|
||||||
|
weak_alias (__swapcontext, swapcontext)
|
35
glibc-upstream-2.34-135.patch
Normal file
35
glibc-upstream-2.34-135.patch
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
commit 4b5b8a1cdf39bed02b8b973717796eccde455ed6
|
||||||
|
Author: Fangrui Song <maskray@google.com>
|
||||||
|
Date: Mon Sep 27 10:12:50 2021 -0700
|
||||||
|
|
||||||
|
powerpc: Delete unneeded ELF_MACHINE_BEFORE_RTLD_RELOC
|
||||||
|
|
||||||
|
Reviewed-by: Raphael M Zinsly <rzinsly@linux.ibm.com>
|
||||||
|
(cherry picked from commit 8e2557a2b85b2eb0ed50a9016a4ffc6b859b97e6)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc32/dl-machine.h b/sysdeps/powerpc/powerpc32/dl-machine.h
|
||||||
|
index ced3a7b659cfcff1..b93cf486b6cda5fd 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc32/dl-machine.h
|
||||||
|
+++ b/sysdeps/powerpc/powerpc32/dl-machine.h
|
||||||
|
@@ -109,8 +109,6 @@ elf_machine_load_address (void)
|
||||||
|
return runtime_dynamic - elf_machine_dynamic ();
|
||||||
|
}
|
||||||
|
|
||||||
|
-#define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info) /* nothing */
|
||||||
|
-
|
||||||
|
/* The PLT uses Elf32_Rela relocs. */
|
||||||
|
#define elf_machine_relplt elf_machine_rela
|
||||||
|
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h
|
||||||
|
index b90f407119efd431..b3f3352bcf5a52b0 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/dl-machine.h
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/dl-machine.h
|
||||||
|
@@ -116,8 +116,6 @@ elf_machine_dynamic (void)
|
||||||
|
return runtime_dynamic - elf_machine_load_address() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
-#define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info) /* nothing */
|
||||||
|
-
|
||||||
|
/* The PLT uses Elf64_Rela relocs. */
|
||||||
|
#define elf_machine_relplt elf_machine_rela
|
||||||
|
|
2020
glibc-upstream-2.34-136.patch
Normal file
2020
glibc-upstream-2.34-136.patch
Normal file
File diff suppressed because it is too large
Load Diff
241
glibc-upstream-2.34-137.patch
Normal file
241
glibc-upstream-2.34-137.patch
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
commit c6df39a0bd2aafd2a4280a0000ef201f30273bee
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Mon Oct 11 16:01:49 2021 -0300
|
||||||
|
|
||||||
|
elf: Fix elf_get_dynamic_info definition
|
||||||
|
|
||||||
|
Before to 490e6c62aa31a8a ('elf: Avoid nested functions in the loader
|
||||||
|
[BZ #27220]'), elf_get_dynamic_info() was defined twice on rtld.c: on
|
||||||
|
the first dynamic-link.h include and later within _dl_start(). The
|
||||||
|
former definition did not define DONT_USE_BOOTSTRAP_MAP and it is used
|
||||||
|
on setup_vdso() (since it is a global definition), while the former does
|
||||||
|
define DONT_USE_BOOTSTRAP_MAP and it is used on loader self-relocation.
|
||||||
|
|
||||||
|
With the commit change, the function is now included and defined once
|
||||||
|
instead of defined as a nested function. So rtld.c defines without
|
||||||
|
defining RTLD_BOOTSTRAP and it brokes at least powerpc32.
|
||||||
|
|
||||||
|
This patch fixes by moving the get-dynamic-info.h include out of
|
||||||
|
dynamic-link.h, which then the caller can corirectly set the expected
|
||||||
|
semantic by defining STATIC_PIE_BOOTSTRAP, RTLD_BOOTSTRAP, and/or
|
||||||
|
RESOLVE_MAP.
|
||||||
|
|
||||||
|
It also required to enable some asserts only for the loader bootstrap
|
||||||
|
to avoid issues when called from setup_vdso().
|
||||||
|
|
||||||
|
As a side note, this is another issues with nested functions: it is
|
||||||
|
not clear from pre-processed output (-E -dD) how the function will
|
||||||
|
be build and its semantic (since nested function will be local and
|
||||||
|
extra C defines may change it).
|
||||||
|
|
||||||
|
I checked on x86_64-linux-gnu (w/o --enable-static-pie),
|
||||||
|
i686-linux-gnu, powerpc64-linux-gnu, powerpc-linux-gnu-power4,
|
||||||
|
aarch64-linux-gnu, arm-linux-gnu, sparc64-linux-gnu, and
|
||||||
|
s390x-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Fangrui Song <maskray@google.com>
|
||||||
|
(cherry picked from commit 4af6982e4c9fc465ffb7a54b794aaaa134241f05)
|
||||||
|
|
||||||
|
Resolved conflicts:
|
||||||
|
elf/rtld.c
|
||||||
|
|
||||||
|
diff --git a/elf/dl-conflict.c b/elf/dl-conflict.c
|
||||||
|
index 5c8e51d19ae095d6..d54356dee3f86ae0 100644
|
||||||
|
--- a/elf/dl-conflict.c
|
||||||
|
+++ b/elf/dl-conflict.c
|
||||||
|
@@ -17,6 +17,7 @@
|
||||||
|
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||||
|
not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
+#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <libintl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
diff --git a/elf/dl-load.c b/elf/dl-load.c
|
||||||
|
index 0976977fbdf21902..eea06629a978aaf3 100644
|
||||||
|
--- a/elf/dl-load.c
|
||||||
|
+++ b/elf/dl-load.c
|
||||||
|
@@ -58,6 +58,7 @@ struct filebuf
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "dynamic-link.h"
|
||||||
|
+#include "get-dynamic-info.h"
|
||||||
|
#include <abi-tag.h>
|
||||||
|
#include <stackinfo.h>
|
||||||
|
#include <sysdep.h>
|
||||||
|
@@ -1295,7 +1296,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
|
||||||
|
if (l->l_ld != 0)
|
||||||
|
l->l_ld = (ElfW(Dyn) *) ((ElfW(Addr)) l->l_ld + l->l_addr);
|
||||||
|
|
||||||
|
- elf_get_dynamic_info (l);
|
||||||
|
+ elf_get_dynamic_info (l, false);
|
||||||
|
|
||||||
|
/* Make sure we are not dlopen'ing an object that has the
|
||||||
|
DF_1_NOOPEN flag set, or a PIE object. */
|
||||||
|
diff --git a/elf/dl-reloc-static-pie.c b/elf/dl-reloc-static-pie.c
|
||||||
|
index a52ba8aeb8b573cb..f323b4dd0d5ba279 100644
|
||||||
|
--- a/elf/dl-reloc-static-pie.c
|
||||||
|
+++ b/elf/dl-reloc-static-pie.c
|
||||||
|
@@ -28,6 +28,7 @@
|
||||||
|
#define STATIC_PIE_BOOTSTRAP
|
||||||
|
#define RESOLVE_MAP(map, scope, sym, version, flags) map
|
||||||
|
#include "dynamic-link.h"
|
||||||
|
+#include "get-dynamic-info.h"
|
||||||
|
|
||||||
|
/* Relocate static executable with PIE. */
|
||||||
|
|
||||||
|
@@ -51,7 +52,7 @@ _dl_relocate_static_pie (void)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- elf_get_dynamic_info (main_map);
|
||||||
|
+ elf_get_dynamic_info (main_map, false);
|
||||||
|
|
||||||
|
# ifdef ELF_MACHINE_BEFORE_RTLD_RELOC
|
||||||
|
ELF_MACHINE_BEFORE_RTLD_RELOC (main_map, main_map->l_info);
|
||||||
|
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
|
||||||
|
index 9d0d941000f6114f..61c260ddb81b586c 100644
|
||||||
|
--- a/elf/dl-runtime.c
|
||||||
|
+++ b/elf/dl-runtime.c
|
||||||
|
@@ -19,6 +19,7 @@
|
||||||
|
#define IN_DL_RUNTIME 1 /* This can be tested in dl-machine.h. */
|
||||||
|
|
||||||
|
#include <alloca.h>
|
||||||
|
+#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h
|
||||||
|
index 7cc30211649d3820..21cdfc88bbfb89ea 100644
|
||||||
|
--- a/elf/dynamic-link.h
|
||||||
|
+++ b/elf/dynamic-link.h
|
||||||
|
@@ -93,7 +93,6 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
|
||||||
|
|
||||||
|
#include <dl-machine.h>
|
||||||
|
|
||||||
|
-#include "get-dynamic-info.h"
|
||||||
|
|
||||||
|
#ifdef RESOLVE_MAP
|
||||||
|
|
||||||
|
diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h
|
||||||
|
index 15c316b38c05a90c..d169099fbc9897cf 100644
|
||||||
|
--- a/elf/get-dynamic-info.h
|
||||||
|
+++ b/elf/get-dynamic-info.h
|
||||||
|
@@ -25,7 +25,7 @@
|
||||||
|
#include <libc-diag.h>
|
||||||
|
|
||||||
|
static inline void __attribute__ ((unused, always_inline))
|
||||||
|
-elf_get_dynamic_info (struct link_map *l)
|
||||||
|
+elf_get_dynamic_info (struct link_map *l, bool check)
|
||||||
|
{
|
||||||
|
#if __ELF_NATIVE_CLASS == 32
|
||||||
|
typedef Elf32_Word d_tag_utype;
|
||||||
|
@@ -112,16 +112,19 @@ elf_get_dynamic_info (struct link_map *l)
|
||||||
|
assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel)));
|
||||||
|
#endif
|
||||||
|
#ifdef RTLD_BOOTSTRAP
|
||||||
|
- /* Only the bind now flags are allowed. */
|
||||||
|
- assert (info[VERSYMIDX (DT_FLAGS_1)] == NULL
|
||||||
|
- || (info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val & ~DF_1_NOW) == 0);
|
||||||
|
- /* Flags must not be set for ld.so. */
|
||||||
|
- assert (info[DT_FLAGS] == NULL
|
||||||
|
- || (info[DT_FLAGS]->d_un.d_val & ~DF_BIND_NOW) == 0);
|
||||||
|
-#endif
|
||||||
|
-#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
|
||||||
|
- assert (info[DT_RUNPATH] == NULL);
|
||||||
|
- assert (info[DT_RPATH] == NULL);
|
||||||
|
+ if (check)
|
||||||
|
+ {
|
||||||
|
+ /* Only the bind now flags are allowed. */
|
||||||
|
+ assert (info[VERSYMIDX (DT_FLAGS_1)] == NULL
|
||||||
|
+ || (info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val & ~DF_1_NOW) == 0);
|
||||||
|
+ /* Flags must not be set for ld.so. */
|
||||||
|
+ assert (info[DT_FLAGS] == NULL
|
||||||
|
+ || (info[DT_FLAGS]->d_un.d_val & ~DF_BIND_NOW) == 0);
|
||||||
|
+# ifdef STATIC_PIE_BOOTSTRAP
|
||||||
|
+ assert (info[DT_RUNPATH] == NULL);
|
||||||
|
+ assert (info[DT_RPATH] == NULL);
|
||||||
|
+# endif
|
||||||
|
+ }
|
||||||
|
#else
|
||||||
|
if (info[DT_FLAGS] != NULL)
|
||||||
|
{
|
||||||
|
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||||
|
index ee45657aeac14f3c..352d596dedb42e79 100644
|
||||||
|
--- a/elf/rtld.c
|
||||||
|
+++ b/elf/rtld.c
|
||||||
|
@@ -514,6 +514,7 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
|
||||||
|
is trivial: always the map of ld.so itself. */
|
||||||
|
#define RTLD_BOOTSTRAP
|
||||||
|
#define RESOLVE_MAP(map, scope, sym, version, flags) map
|
||||||
|
+#include "get-dynamic-info.h"
|
||||||
|
#include "dynamic-link.h"
|
||||||
|
|
||||||
|
static ElfW(Addr) __attribute_used__
|
||||||
|
@@ -549,7 +550,7 @@ _dl_start (void *arg)
|
||||||
|
/* Read our own dynamic section and fill in the info array. */
|
||||||
|
bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic ();
|
||||||
|
bootstrap_map.l_ld_readonly = DL_RO_DYN_SECTION;
|
||||||
|
- elf_get_dynamic_info (&bootstrap_map);
|
||||||
|
+ elf_get_dynamic_info (&bootstrap_map, true);
|
||||||
|
|
||||||
|
#if NO_TLS_OFFSET != 0
|
||||||
|
bootstrap_map.l_tls_offset = NO_TLS_OFFSET;
|
||||||
|
@@ -1653,7 +1654,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||||
|
if (! rtld_is_main)
|
||||||
|
{
|
||||||
|
/* Extract the contents of the dynamic section for easy access. */
|
||||||
|
- elf_get_dynamic_info (main_map);
|
||||||
|
+ elf_get_dynamic_info (main_map, false);
|
||||||
|
|
||||||
|
/* If the main map is libc.so, update the base namespace to
|
||||||
|
refer to this map. If libc.so is loaded later, this happens
|
||||||
|
diff --git a/elf/setup-vdso.h b/elf/setup-vdso.h
|
||||||
|
index f44748bc9858e5fd..6fdffafcca5e9916 100644
|
||||||
|
--- a/elf/setup-vdso.h
|
||||||
|
+++ b/elf/setup-vdso.h
|
||||||
|
@@ -64,7 +64,7 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
|
||||||
|
l->l_map_end += l->l_addr;
|
||||||
|
l->l_text_end += l->l_addr;
|
||||||
|
l->l_ld = (void *) ((ElfW(Addr)) l->l_ld + l->l_addr);
|
||||||
|
- elf_get_dynamic_info (l);
|
||||||
|
+ elf_get_dynamic_info (l, false);
|
||||||
|
_dl_setup_hash (l);
|
||||||
|
l->l_relocated = 1;
|
||||||
|
|
||||||
|
diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h
|
||||||
|
index 7e6761bbe87540d5..86f866ca7c17bd9b 100644
|
||||||
|
--- a/sysdeps/arm/dl-machine.h
|
||||||
|
+++ b/sysdeps/arm/dl-machine.h
|
||||||
|
@@ -21,6 +21,7 @@
|
||||||
|
|
||||||
|
#define ELF_MACHINE_NAME "ARM"
|
||||||
|
|
||||||
|
+#include <assert.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <tls.h>
|
||||||
|
#include <dl-tlsdesc.h>
|
||||||
|
diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h
|
||||||
|
index 78ce890c0ff333ca..fa902612ca8557f9 100644
|
||||||
|
--- a/sysdeps/i386/dl-machine.h
|
||||||
|
+++ b/sysdeps/i386/dl-machine.h
|
||||||
|
@@ -21,6 +21,7 @@
|
||||||
|
|
||||||
|
#define ELF_MACHINE_NAME "i386"
|
||||||
|
|
||||||
|
+#include <assert.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sysdep.h>
|
||||||
|
#include <tls.h>
|
||||||
|
diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
|
||||||
|
index d3fcbb37bf1f4f7c..90c77cfea1de8d63 100644
|
||||||
|
--- a/sysdeps/x86_64/dl-machine.h
|
||||||
|
+++ b/sysdeps/x86_64/dl-machine.h
|
||||||
|
@@ -22,6 +22,7 @@
|
||||||
|
|
||||||
|
#define ELF_MACHINE_NAME "x86_64"
|
||||||
|
|
||||||
|
+#include <assert.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sysdep.h>
|
||||||
|
#include <tls.h>
|
1115
glibc-upstream-2.34-138.patch
Normal file
1115
glibc-upstream-2.34-138.patch
Normal file
File diff suppressed because it is too large
Load Diff
221
glibc-upstream-2.34-139.patch
Normal file
221
glibc-upstream-2.34-139.patch
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
commit f6a54a304223666ea4af73260c99c830d7726eca
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Fri Oct 15 14:35:31 2021 -0300
|
||||||
|
|
||||||
|
elf: Fix elf_get_dynamic_info() for bootstrap
|
||||||
|
|
||||||
|
THe d6d89608ac8c broke powerpc for --enable-bind-now because it turned
|
||||||
|
out that different than patch assumption rtld elf_get_dynamic_info()
|
||||||
|
does require to handle RTLD_BOOTSTRAP to avoid DT_FLAGS and
|
||||||
|
DT_RUNPATH (more specially the GLRO usage which is not reallocate
|
||||||
|
yet).
|
||||||
|
|
||||||
|
This patch fixes by passing two arguments to elf_get_dynamic_info()
|
||||||
|
to inform that by rtld (bootstrap) or static pie initialization
|
||||||
|
(static_pie_bootstrap). I think using explicit argument is way more
|
||||||
|
clear and burried C preprocessor, and compiler should remove the
|
||||||
|
dead code.
|
||||||
|
|
||||||
|
I checked on x86_64 and i686 with default options, --enable-bind-now,
|
||||||
|
and --enable-bind-now and --enable--static-pie. I also check on
|
||||||
|
aarch64, armhf, powerpc64, and powerpc with default and
|
||||||
|
--enable-bind-now.
|
||||||
|
|
||||||
|
(cherry picked from commit 5118dcac68c4eadfd6304bb33adde63d062dc07f)
|
||||||
|
|
||||||
|
Resolved conflicts:
|
||||||
|
elf/rtld.c - Manual merge.
|
||||||
|
|
||||||
|
diff --git a/elf/dl-load.c b/elf/dl-load.c
|
||||||
|
index fb3da5aa565908a6..a920b12a906a9dec 100644
|
||||||
|
--- a/elf/dl-load.c
|
||||||
|
+++ b/elf/dl-load.c
|
||||||
|
@@ -1296,7 +1296,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
|
||||||
|
if (l->l_ld != 0)
|
||||||
|
l->l_ld = (ElfW(Dyn) *) ((ElfW(Addr)) l->l_ld + l->l_addr);
|
||||||
|
|
||||||
|
- elf_get_dynamic_info (l);
|
||||||
|
+ elf_get_dynamic_info (l, false, false);
|
||||||
|
|
||||||
|
/* Make sure we are not dlopen'ing an object that has the
|
||||||
|
DF_1_NOOPEN flag set, or a PIE object. */
|
||||||
|
diff --git a/elf/dl-reloc-static-pie.c b/elf/dl-reloc-static-pie.c
|
||||||
|
index ababafcf98f9945d..757205affe65d9e1 100644
|
||||||
|
--- a/elf/dl-reloc-static-pie.c
|
||||||
|
+++ b/elf/dl-reloc-static-pie.c
|
||||||
|
@@ -25,7 +25,6 @@
|
||||||
|
|
||||||
|
#include <dl-machine.h>
|
||||||
|
|
||||||
|
-#define STATIC_PIE_BOOTSTRAP
|
||||||
|
#define RESOLVE_MAP(map, scope, sym, version, flags) map
|
||||||
|
#include "dynamic-link.h"
|
||||||
|
#include "get-dynamic-info.h"
|
||||||
|
@@ -52,7 +51,7 @@ _dl_relocate_static_pie (void)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- elf_get_dynamic_info (main_map);
|
||||||
|
+ elf_get_dynamic_info (main_map, false, true);
|
||||||
|
|
||||||
|
# ifdef ELF_MACHINE_BEFORE_RTLD_RELOC
|
||||||
|
ELF_MACHINE_BEFORE_RTLD_RELOC (main_map, main_map->l_info);
|
||||||
|
diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h
|
||||||
|
index 1ac0663d1ff5de24..f63e07dc6d2cd5e6 100644
|
||||||
|
--- a/elf/get-dynamic-info.h
|
||||||
|
+++ b/elf/get-dynamic-info.h
|
||||||
|
@@ -26,7 +26,8 @@
|
||||||
|
#include <libc-diag.h>
|
||||||
|
|
||||||
|
static inline void __attribute__ ((unused, always_inline))
|
||||||
|
-elf_get_dynamic_info (struct link_map *l)
|
||||||
|
+elf_get_dynamic_info (struct link_map *l, bool bootstrap,
|
||||||
|
+ bool static_pie_bootstrap)
|
||||||
|
{
|
||||||
|
#if __ELF_NATIVE_CLASS == 32
|
||||||
|
typedef Elf32_Word d_tag_utype;
|
||||||
|
@@ -35,7 +36,7 @@ elf_get_dynamic_info (struct link_map *l)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef STATIC_PIE_BOOTSTRAP
|
||||||
|
- if (l->l_ld == NULL)
|
||||||
|
+ if (!bootstrap && l->l_ld == NULL)
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@@ -112,47 +113,63 @@ elf_get_dynamic_info (struct link_map *l)
|
||||||
|
if (info[DT_REL] != NULL)
|
||||||
|
assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel)));
|
||||||
|
#endif
|
||||||
|
-#ifdef STATIC_PIE_BOOTSTRAP
|
||||||
|
- assert (info[DT_RUNPATH] == NULL);
|
||||||
|
- assert (info[DT_RPATH] == NULL);
|
||||||
|
-#endif
|
||||||
|
- if (info[DT_FLAGS] != NULL)
|
||||||
|
+ if (bootstrap || static_pie_bootstrap)
|
||||||
|
{
|
||||||
|
- /* Flags are used. Translate to the old form where available.
|
||||||
|
- Since these l_info entries are only tested for NULL pointers it
|
||||||
|
- is ok if they point to the DT_FLAGS entry. */
|
||||||
|
- l->l_flags = info[DT_FLAGS]->d_un.d_val;
|
||||||
|
-
|
||||||
|
- if (l->l_flags & DF_SYMBOLIC)
|
||||||
|
- info[DT_SYMBOLIC] = info[DT_FLAGS];
|
||||||
|
- if (l->l_flags & DF_TEXTREL)
|
||||||
|
- info[DT_TEXTREL] = info[DT_FLAGS];
|
||||||
|
- if (l->l_flags & DF_BIND_NOW)
|
||||||
|
- info[DT_BIND_NOW] = info[DT_FLAGS];
|
||||||
|
+ assert (info[DT_RUNPATH] == NULL);
|
||||||
|
+ assert (info[DT_RPATH] == NULL);
|
||||||
|
}
|
||||||
|
- if (info[VERSYMIDX (DT_FLAGS_1)] != NULL)
|
||||||
|
+ if (bootstrap)
|
||||||
|
{
|
||||||
|
- l->l_flags_1 = info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val;
|
||||||
|
- if (l->l_flags_1 & DF_1_NODELETE)
|
||||||
|
- l->l_nodelete_pending = true;
|
||||||
|
-
|
||||||
|
- /* Only DT_1_SUPPORTED_MASK bits are supported, and we would like
|
||||||
|
- to assert this, but we can't. Users have been setting
|
||||||
|
- unsupported DF_1_* flags for a long time and glibc has ignored
|
||||||
|
- them. Therefore to avoid breaking existing applications the
|
||||||
|
- best we can do is add a warning during debugging with the
|
||||||
|
- intent of notifying the user of the problem. */
|
||||||
|
- if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0)
|
||||||
|
- && l->l_flags_1 & ~DT_1_SUPPORTED_MASK)
|
||||||
|
- _dl_debug_printf ("\nWARNING: Unsupported flag value(s) of 0x%x in DT_FLAGS_1.\n",
|
||||||
|
- l->l_flags_1 & ~DT_1_SUPPORTED_MASK);
|
||||||
|
-
|
||||||
|
- if (l->l_flags_1 & DF_1_NOW)
|
||||||
|
- info[DT_BIND_NOW] = info[VERSYMIDX (DT_FLAGS_1)];
|
||||||
|
+ /* Only the bind now flags are allowed. */
|
||||||
|
+ assert (info[VERSYMIDX (DT_FLAGS_1)] == NULL
|
||||||
|
+ || (info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val & ~DF_1_NOW) == 0);
|
||||||
|
+ /* Flags must not be set for ld.so. */
|
||||||
|
+ assert (info[DT_FLAGS] == NULL
|
||||||
|
+ || (info[DT_FLAGS]->d_un.d_val & ~DF_BIND_NOW) == 0);
|
||||||
|
}
|
||||||
|
- if (info[DT_RUNPATH] != NULL)
|
||||||
|
- /* If both RUNPATH and RPATH are given, the latter is ignored. */
|
||||||
|
- info[DT_RPATH] = NULL;
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ if (info[DT_FLAGS] != NULL)
|
||||||
|
+ {
|
||||||
|
+ /* Flags are used. Translate to the old form where available.
|
||||||
|
+ Since these l_info entries are only tested for NULL pointers it
|
||||||
|
+ is ok if they point to the DT_FLAGS entry. */
|
||||||
|
+ l->l_flags = info[DT_FLAGS]->d_un.d_val;
|
||||||
|
+
|
||||||
|
+ if (l->l_flags & DF_SYMBOLIC)
|
||||||
|
+ info[DT_SYMBOLIC] = info[DT_FLAGS];
|
||||||
|
+ if (l->l_flags & DF_TEXTREL)
|
||||||
|
+ info[DT_TEXTREL] = info[DT_FLAGS];
|
||||||
|
+ if (l->l_flags & DF_BIND_NOW)
|
||||||
|
+ info[DT_BIND_NOW] = info[DT_FLAGS];
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (info[VERSYMIDX (DT_FLAGS_1)] != NULL)
|
||||||
|
+ {
|
||||||
|
+ l->l_flags_1 = info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val;
|
||||||
|
+ if (l->l_flags_1 & DF_1_NODELETE)
|
||||||
|
+ l->l_nodelete_pending = true;
|
||||||
|
+
|
||||||
|
+ /* Only DT_1_SUPPORTED_MASK bits are supported, and we would like
|
||||||
|
+ to assert this, but we can't. Users have been setting
|
||||||
|
+ unsupported DF_1_* flags for a long time and glibc has ignored
|
||||||
|
+ them. Therefore to avoid breaking existing applications the
|
||||||
|
+ best we can do is add a warning during debugging with the
|
||||||
|
+ intent of notifying the user of the problem. */
|
||||||
|
+ if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0)
|
||||||
|
+ && l->l_flags_1 & ~DT_1_SUPPORTED_MASK)
|
||||||
|
+ _dl_debug_printf ("\nWARNING: Unsupported flag value(s) of 0x%x "
|
||||||
|
+ "in DT_FLAGS_1.\n",
|
||||||
|
+ l->l_flags_1 & ~DT_1_SUPPORTED_MASK);
|
||||||
|
+
|
||||||
|
+ if (l->l_flags_1 & DF_1_NOW)
|
||||||
|
+ info[DT_BIND_NOW] = info[VERSYMIDX (DT_FLAGS_1)];
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (info[DT_RUNPATH] != NULL)
|
||||||
|
+ /* If both RUNPATH and RPATH are given, the latter is ignored. */
|
||||||
|
+ info[DT_RPATH] = NULL;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||||
|
index 37d28d5a66d7b5d6..ad5ddb2a0ab94e7f 100644
|
||||||
|
--- a/elf/rtld.c
|
||||||
|
+++ b/elf/rtld.c
|
||||||
|
@@ -549,7 +549,7 @@ _dl_start (void *arg)
|
||||||
|
/* Read our own dynamic section and fill in the info array. */
|
||||||
|
bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic ();
|
||||||
|
bootstrap_map.l_ld_readonly = DL_RO_DYN_SECTION;
|
||||||
|
- elf_get_dynamic_info (&bootstrap_map);
|
||||||
|
+ elf_get_dynamic_info (&bootstrap_map, true, false);
|
||||||
|
|
||||||
|
#if NO_TLS_OFFSET != 0
|
||||||
|
bootstrap_map.l_tls_offset = NO_TLS_OFFSET;
|
||||||
|
@@ -1653,7 +1653,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||||
|
if (! rtld_is_main)
|
||||||
|
{
|
||||||
|
/* Extract the contents of the dynamic section for easy access. */
|
||||||
|
- elf_get_dynamic_info (main_map);
|
||||||
|
+ elf_get_dynamic_info (main_map, false, false);
|
||||||
|
|
||||||
|
/* If the main map is libc.so, update the base namespace to
|
||||||
|
refer to this map. If libc.so is loaded later, this happens
|
||||||
|
diff --git a/elf/setup-vdso.h b/elf/setup-vdso.h
|
||||||
|
index f44748bc9858e5fd..3f20578046de76ed 100644
|
||||||
|
--- a/elf/setup-vdso.h
|
||||||
|
+++ b/elf/setup-vdso.h
|
||||||
|
@@ -64,7 +64,7 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
|
||||||
|
l->l_map_end += l->l_addr;
|
||||||
|
l->l_text_end += l->l_addr;
|
||||||
|
l->l_ld = (void *) ((ElfW(Addr)) l->l_ld + l->l_addr);
|
||||||
|
- elf_get_dynamic_info (l);
|
||||||
|
+ elf_get_dynamic_info (l, false, false);
|
||||||
|
_dl_setup_hash (l);
|
||||||
|
l->l_relocated = 1;
|
||||||
|
|
69
glibc-upstream-2.34-140.patch
Normal file
69
glibc-upstream-2.34-140.patch
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
commit a31bbe3242266aaea423e5879f38aed69aea1d5e
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Thu Jul 29 11:13:57 2021 -0300
|
||||||
|
|
||||||
|
elf: Move LAV_CURRENT to link_lavcurrent.h
|
||||||
|
|
||||||
|
No functional change.
|
||||||
|
|
||||||
|
(cherry picked from commit 54816ae98d57930b7c945f17485714a5574bfe47)
|
||||||
|
|
||||||
|
Resolved conflicts:
|
||||||
|
elf/Makefile
|
||||||
|
|
||||||
|
diff --git a/bits/link_lavcurrent.h b/bits/link_lavcurrent.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..44fbea1e8060997f
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/bits/link_lavcurrent.h
|
||||||
|
@@ -0,0 +1,25 @@
|
||||||
|
+/* Data structure for communication from the run-time dynamic linker for
|
||||||
|
+ loaded ELF shared objects. LAV_CURRENT definition.
|
||||||
|
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#ifndef _LINK_H
|
||||||
|
+# error "Never include <bits/link_lavcurrent.h> directly; use <link.h> instead."
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+/* Version numbers for la_version handshake interface. */
|
||||||
|
+#define LAV_CURRENT 1
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index cd8725c76f4cfb48..7fa80946ff3aae42 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -24,6 +24,7 @@ include ../Makeconfig
|
||||||
|
headers = \
|
||||||
|
bits/elfclass.h \
|
||||||
|
bits/link.h \
|
||||||
|
+ bits/link_lavcurrent.h \
|
||||||
|
elf.h \
|
||||||
|
link.h \
|
||||||
|
# headers
|
||||||
|
diff --git a/elf/link.h b/elf/link.h
|
||||||
|
index ff3a85c847930b9b..21a351686b9bf7c8 100644
|
||||||
|
--- a/elf/link.h
|
||||||
|
+++ b/elf/link.h
|
||||||
|
@@ -96,7 +96,7 @@ struct link_map
|
||||||
|
#ifdef __USE_GNU
|
||||||
|
|
||||||
|
/* Version numbers for la_version handshake interface. */
|
||||||
|
-#define LAV_CURRENT 1
|
||||||
|
+#include <bits/link_lavcurrent.h>
|
||||||
|
|
||||||
|
/* Activity types signaled through la_activity. */
|
||||||
|
enum
|
390
glibc-upstream-2.34-141.patch
Normal file
390
glibc-upstream-2.34-141.patch
Normal file
@ -0,0 +1,390 @@
|
|||||||
|
commit e25fe992132c460fecc1ab9fade185d5dd3f91ff
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Thu Nov 11 09:28:21 2021 -0300
|
||||||
|
|
||||||
|
elf: Move la_activity (LA_ACT_ADD) after _dl_add_to_namespace_list() (BZ #28062)
|
||||||
|
|
||||||
|
It ensures that the the namespace is guaranteed to not be empty.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
(cherry picked from commit ed3ce71f5c64c5f07cbde0ef03554ea8950d8f2c)
|
||||||
|
|
||||||
|
Resolved conflicts:
|
||||||
|
elf/Makefile
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index 7fa80946ff3aae42..bf6da98bdd15a18d 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -363,6 +363,7 @@ tests += \
|
||||||
|
tst-audit15 \
|
||||||
|
tst-audit16 \
|
||||||
|
tst-audit17 \
|
||||||
|
+ tst-audit18 \
|
||||||
|
tst-auditmany \
|
||||||
|
tst-auxobj \
|
||||||
|
tst-auxobj-dlopen \
|
||||||
|
@@ -623,6 +624,7 @@ modules-names = \
|
||||||
|
tst-audit12mod2 \
|
||||||
|
tst-audit12mod3 \
|
||||||
|
tst-audit13mod1 \
|
||||||
|
+ tst-audit18mod \
|
||||||
|
tst-auditlogmod-1 \
|
||||||
|
tst-auditlogmod-2 \
|
||||||
|
tst-auditlogmod-3 \
|
||||||
|
@@ -640,6 +642,7 @@ modules-names = \
|
||||||
|
tst-auditmod9b \
|
||||||
|
tst-auditmod11 \
|
||||||
|
tst-auditmod12 \
|
||||||
|
+ tst-auditmod18 \
|
||||||
|
tst-auxvalmod \
|
||||||
|
tst-big-note-lib \
|
||||||
|
tst-deep1mod1 \
|
||||||
|
@@ -1999,6 +2002,10 @@ $(objpfx)tst-auditmod17.so: $(objpfx)tst-auditmod17.os
|
||||||
|
CFLAGS-.os += $(call elide-stack-protector,.os,tst-auditmod17)
|
||||||
|
tst-audit17-ENV = LD_AUDIT=$(objpfx)tst-auditmod17.so
|
||||||
|
|
||||||
|
+$(objpfx)tst-audit18.out: $(objpfx)tst-auditmod18.so \
|
||||||
|
+ $(objpfx)tst-audit18mod.so
|
||||||
|
+tst-audit18-ARGS = -- $(host-test-program-cmd)
|
||||||
|
+
|
||||||
|
# tst-sonamemove links against an older implementation of the library.
|
||||||
|
LDFLAGS-tst-sonamemove-linkmod1.so = \
|
||||||
|
-Wl,--version-script=tst-sonamemove-linkmod1.map \
|
||||||
|
diff --git a/elf/dl-load.c b/elf/dl-load.c
|
||||||
|
index a920b12a906a9dec..a8c6df3959f2b331 100644
|
||||||
|
--- a/elf/dl-load.c
|
||||||
|
+++ b/elf/dl-load.c
|
||||||
|
@@ -1054,42 +1054,6 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
|
||||||
|
/* This is the ELF header. We read it in `open_verify'. */
|
||||||
|
header = (void *) fbp->buf;
|
||||||
|
|
||||||
|
- /* Signal that we are going to add new objects. */
|
||||||
|
- if (r->r_state == RT_CONSISTENT)
|
||||||
|
- {
|
||||||
|
-#ifdef SHARED
|
||||||
|
- /* Auditing checkpoint: we are going to add new objects. */
|
||||||
|
- if ((mode & __RTLD_AUDIT) == 0
|
||||||
|
- && __glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||||
|
- {
|
||||||
|
- struct link_map *head = GL(dl_ns)[nsid]._ns_loaded;
|
||||||
|
- /* Do not call the functions for any auditing object. */
|
||||||
|
- if (head->l_auditing == 0)
|
||||||
|
- {
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- if (afct->activity != NULL)
|
||||||
|
- afct->activity (&link_map_audit_state (head, cnt)->cookie,
|
||||||
|
- LA_ACT_ADD);
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
- /* Notify the debugger we have added some objects. We need to
|
||||||
|
- call _dl_debug_initialize in a static program in case dynamic
|
||||||
|
- linking has not been used before. */
|
||||||
|
- r->r_state = RT_ADD;
|
||||||
|
- _dl_debug_state ();
|
||||||
|
- LIBC_PROBE (map_start, 2, nsid, r);
|
||||||
|
- make_consistent = true;
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- assert (r->r_state == RT_ADD);
|
||||||
|
-
|
||||||
|
/* Enter the new object in the list of loaded objects. */
|
||||||
|
l = _dl_new_object (realname, name, l_type, loader, mode, nsid);
|
||||||
|
if (__glibc_unlikely (l == NULL))
|
||||||
|
@@ -1511,6 +1475,44 @@ cannot enable executable stack as shared object requires");
|
||||||
|
/* Now that the object is fully initialized add it to the object list. */
|
||||||
|
_dl_add_to_namespace_list (l, nsid);
|
||||||
|
|
||||||
|
+ /* Signal that we are going to add new objects. */
|
||||||
|
+ if (r->r_state == RT_CONSISTENT)
|
||||||
|
+ {
|
||||||
|
+#ifdef SHARED
|
||||||
|
+ /* Auditing checkpoint: we are going to add new objects. Since this
|
||||||
|
+ is called after _dl_add_to_namespace_list the namespace is guaranteed
|
||||||
|
+ to not be empty. */
|
||||||
|
+ if ((mode & __RTLD_AUDIT) == 0
|
||||||
|
+ && __glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||||
|
+ {
|
||||||
|
+ struct link_map *head = GL(dl_ns)[nsid]._ns_loaded;
|
||||||
|
+ /* Do not call the functions for any auditing object. */
|
||||||
|
+ if (head->l_auditing == 0)
|
||||||
|
+ {
|
||||||
|
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
+ {
|
||||||
|
+ if (afct->activity != NULL)
|
||||||
|
+ afct->activity (&link_map_audit_state (head, cnt)->cookie,
|
||||||
|
+ LA_ACT_ADD);
|
||||||
|
+
|
||||||
|
+ afct = afct->next;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ /* Notify the debugger we have added some objects. We need to
|
||||||
|
+ call _dl_debug_initialize in a static program in case dynamic
|
||||||
|
+ linking has not been used before. */
|
||||||
|
+ r->r_state = RT_ADD;
|
||||||
|
+ _dl_debug_state ();
|
||||||
|
+ LIBC_PROBE (map_start, 2, nsid, r);
|
||||||
|
+ make_consistent = true;
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ assert (r->r_state == RT_ADD);
|
||||||
|
+
|
||||||
|
#ifdef SHARED
|
||||||
|
/* Auditing checkpoint: we have a new object. */
|
||||||
|
if (__glibc_unlikely (GLRO(dl_naudit) > 0)
|
||||||
|
diff --git a/elf/tst-audit18.c b/elf/tst-audit18.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..ef784908f60d50aa
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit18.c
|
||||||
|
@@ -0,0 +1,129 @@
|
||||||
|
+/* Check DT_AUDIT with dlmopen.
|
||||||
|
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <array_length.h>
|
||||||
|
+#include <getopt.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+#include <gnu/lib-names.h>
|
||||||
|
+#include <support/capture_subprocess.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/xdlfcn.h>
|
||||||
|
+#include <support/xstdio.h>
|
||||||
|
+#include <support/support.h>
|
||||||
|
+
|
||||||
|
+static int restart;
|
||||||
|
+#define CMDLINE_OPTIONS \
|
||||||
|
+ { "restart", no_argument, &restart, 1 },
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+handle_restart (void)
|
||||||
|
+{
|
||||||
|
+ {
|
||||||
|
+ void *h = xdlmopen (LM_ID_NEWLM, LIBC_SO, RTLD_NOW);
|
||||||
|
+
|
||||||
|
+ pid_t (*s) (void) = xdlsym (h, "getpid");
|
||||||
|
+ TEST_COMPARE (s (), getpid ());
|
||||||
|
+
|
||||||
|
+ xdlclose (h);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ {
|
||||||
|
+ void *h = xdlmopen (LM_ID_NEWLM, "tst-audit18mod.so", RTLD_NOW);
|
||||||
|
+
|
||||||
|
+ int (*foo) (void) = xdlsym (h, "foo");
|
||||||
|
+ TEST_COMPARE (foo (), 10);
|
||||||
|
+
|
||||||
|
+ xdlclose (h);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (int argc, char *argv[])
|
||||||
|
+{
|
||||||
|
+ /* We must have either:
|
||||||
|
+ - One our fource parameters left if called initially:
|
||||||
|
+ + path to ld.so optional
|
||||||
|
+ + "--library-path" optional
|
||||||
|
+ + the library path optional
|
||||||
|
+ + the application name */
|
||||||
|
+
|
||||||
|
+ if (restart)
|
||||||
|
+ return handle_restart ();
|
||||||
|
+
|
||||||
|
+ char *spargv[9];
|
||||||
|
+ int i = 0;
|
||||||
|
+ for (; i < argc - 1; i++)
|
||||||
|
+ spargv[i] = argv[i + 1];
|
||||||
|
+ spargv[i++] = (char *) "--direct";
|
||||||
|
+ spargv[i++] = (char *) "--restart";
|
||||||
|
+ spargv[i] = NULL;
|
||||||
|
+
|
||||||
|
+ setenv ("LD_AUDIT", "tst-auditmod18.so", 0);
|
||||||
|
+ struct support_capture_subprocess result
|
||||||
|
+ = support_capture_subprogram (spargv[0], spargv);
|
||||||
|
+ support_capture_subprocess_check (&result, "tst-audit18", 0, sc_allow_stderr);
|
||||||
|
+
|
||||||
|
+ struct
|
||||||
|
+ {
|
||||||
|
+ const char *name;
|
||||||
|
+ bool found;
|
||||||
|
+ } audit_iface[] =
|
||||||
|
+ {
|
||||||
|
+ { "la_version", false },
|
||||||
|
+ { "la_objsearch", false },
|
||||||
|
+ { "la_activity", false },
|
||||||
|
+ { "la_objopen", false },
|
||||||
|
+ { "la_objclose", false },
|
||||||
|
+ { "la_preinit", false },
|
||||||
|
+#if __WORDSIZE == 32
|
||||||
|
+ { "la_symbind32", false },
|
||||||
|
+#elif __WORDSIZE == 64
|
||||||
|
+ { "la_symbind64", false },
|
||||||
|
+#endif
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ /* Some hooks are called more than once but the test only check if any
|
||||||
|
+ is called at least once. */
|
||||||
|
+ FILE *out = fmemopen (result.err.buffer, result.err.length, "r");
|
||||||
|
+ TEST_VERIFY (out != NULL);
|
||||||
|
+ char *buffer = NULL;
|
||||||
|
+ size_t buffer_length = 0;
|
||||||
|
+ while (xgetline (&buffer, &buffer_length, out))
|
||||||
|
+ {
|
||||||
|
+ for (int i = 0; i < array_length (audit_iface); i++)
|
||||||
|
+ if (strncmp (buffer, audit_iface[i].name,
|
||||||
|
+ strlen (audit_iface[i].name)) == 0)
|
||||||
|
+ audit_iface[i].found = true;
|
||||||
|
+ }
|
||||||
|
+ free (buffer);
|
||||||
|
+ xfclose (out);
|
||||||
|
+
|
||||||
|
+ for (int i = 0; i < array_length (audit_iface); i++)
|
||||||
|
+ TEST_COMPARE (audit_iface[i].found, true);
|
||||||
|
+
|
||||||
|
+ support_capture_subprocess_free (&result);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#define TEST_FUNCTION_ARGV do_test
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/elf/tst-audit18mod.c b/elf/tst-audit18mod.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..096a9167c9f8353f
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit18mod.c
|
||||||
|
@@ -0,0 +1,23 @@
|
||||||
|
+/* Check DT_AUDIT with dlmopen.
|
||||||
|
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+foo (void)
|
||||||
|
+{
|
||||||
|
+ return 10;
|
||||||
|
+}
|
||||||
|
diff --git a/elf/tst-auditmod18.c b/elf/tst-auditmod18.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..182992e9fdb1620c
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-auditmod18.c
|
||||||
|
@@ -0,0 +1,73 @@
|
||||||
|
+/* Check DT_AUDIT with dlmopen.
|
||||||
|
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <link.h>
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_version (unsigned int version)
|
||||||
|
+{
|
||||||
|
+ fprintf (stderr, "%s\n", __func__);
|
||||||
|
+ return LAV_CURRENT;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+char *
|
||||||
|
+la_objsearch (const char *name, uintptr_t *cookie, unsigned int flag)
|
||||||
|
+{
|
||||||
|
+ fprintf (stderr, "%s\n", __func__);
|
||||||
|
+ return (char *) name;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+la_activity (uintptr_t *cookie, unsigned int flag)
|
||||||
|
+{
|
||||||
|
+ fprintf (stderr, "%s\n", __func__);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
|
||||||
|
+{
|
||||||
|
+ fprintf (stderr, "%s\n", __func__);
|
||||||
|
+ return LA_FLG_BINDTO | LA_FLG_BINDFROM;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_objclose (uintptr_t *cookie)
|
||||||
|
+{
|
||||||
|
+ fprintf (stderr, "%s\n", __func__);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+la_preinit (uintptr_t *cookie)
|
||||||
|
+{
|
||||||
|
+ fprintf (stderr, "%s\n", __func__);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+uintptr_t
|
||||||
|
+#if __ELF_NATIVE_CLASS == 32
|
||||||
|
+la_symbind32 (Elf32_Sym *sym, unsigned int ndx, uintptr_t *refcook,
|
||||||
|
+ uintptr_t *defcook, unsigned int *flags, const char *symname)
|
||||||
|
+#else
|
||||||
|
+la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook,
|
||||||
|
+ uintptr_t *defcook, unsigned int *flags, const char *symname)
|
||||||
|
+#endif
|
||||||
|
+{
|
||||||
|
+ fprintf (stderr, "%s\n", __func__);
|
||||||
|
+ return sym->st_value;
|
||||||
|
+}
|
159
glibc-upstream-2.34-142.patch
Normal file
159
glibc-upstream-2.34-142.patch
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
commit ce0cb6d1d2daac2d58006a41c3d19c551b86f255
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Mon Jul 19 15:47:51 2021 -0300
|
||||||
|
|
||||||
|
elf: Add _dl_audit_objopen
|
||||||
|
|
||||||
|
It consolidates the code required to call la_objopen audit callback.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
(cherry picked from commit aee6e90f93e285016b6cd9c8bd00402c19ba271b)
|
||||||
|
|
||||||
|
Resolved conflicts:
|
||||||
|
elf/Makefile
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index bf6da98bdd15a18d..85165c0591412a45 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -118,6 +118,7 @@ elide-routines.os = \
|
||||||
|
# interpreter and operating independent of libc.
|
||||||
|
rtld-routines = \
|
||||||
|
$(all-dl-routines) \
|
||||||
|
+ dl-audit \
|
||||||
|
dl-compat \
|
||||||
|
dl-conflict \
|
||||||
|
dl-diagnostics \
|
||||||
|
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..4066dfe85146b9d4
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/dl-audit.c
|
||||||
|
@@ -0,0 +1,39 @@
|
||||||
|
+/* Audit common functions.
|
||||||
|
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <ldsodefs.h>
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+_dl_audit_objopen (struct link_map *l, Lmid_t nsid)
|
||||||
|
+{
|
||||||
|
+ if (__glibc_likely (GLRO(dl_naudit) == 0))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
+ {
|
||||||
|
+ if (afct->objopen != NULL)
|
||||||
|
+ {
|
||||||
|
+ struct auditstate *state = link_map_audit_state (l, cnt);
|
||||||
|
+ state->bindflags = afct->objopen (l, nsid, &state->cookie);
|
||||||
|
+ l->l_audit_any_plt |= state->bindflags != 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ afct = afct->next;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/elf/dl-load.c b/elf/dl-load.c
|
||||||
|
index a8c6df3959f2b331..a2d73d025c65cd79 100644
|
||||||
|
--- a/elf/dl-load.c
|
||||||
|
+++ b/elf/dl-load.c
|
||||||
|
@@ -1515,22 +1515,8 @@ cannot enable executable stack as shared object requires");
|
||||||
|
|
||||||
|
#ifdef SHARED
|
||||||
|
/* Auditing checkpoint: we have a new object. */
|
||||||
|
- if (__glibc_unlikely (GLRO(dl_naudit) > 0)
|
||||||
|
- && !GL(dl_ns)[l->l_ns]._ns_loaded->l_auditing)
|
||||||
|
- {
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- if (afct->objopen != NULL)
|
||||||
|
- {
|
||||||
|
- struct auditstate *state = link_map_audit_state (l, cnt);
|
||||||
|
- state->bindflags = afct->objopen (l, nsid, &state->cookie);
|
||||||
|
- l->l_audit_any_plt |= state->bindflags != 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ if (!GL(dl_ns)[l->l_ns]._ns_loaded->l_auditing)
|
||||||
|
+ _dl_audit_objopen (l, nsid);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return l;
|
||||||
|
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||||
|
index ad5ddb2a0ab94e7f..45fec0df3043b90a 100644
|
||||||
|
--- a/elf/rtld.c
|
||||||
|
+++ b/elf/rtld.c
|
||||||
|
@@ -1064,25 +1064,6 @@ ERROR: audit interface '%s' requires version %d (maximum supported version %d);
|
||||||
|
dlmargs.map->l_auditing = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
-/* Notify the the audit modules that the object MAP has already been
|
||||||
|
- loaded. */
|
||||||
|
-static void
|
||||||
|
-notify_audit_modules_of_loaded_object (struct link_map *map)
|
||||||
|
-{
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- if (afct->objopen != NULL)
|
||||||
|
- {
|
||||||
|
- struct auditstate *state = link_map_audit_state (map, cnt);
|
||||||
|
- state->bindflags = afct->objopen (map, LM_ID_BASE, &state->cookie);
|
||||||
|
- map->l_audit_any_plt |= state->bindflags != 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
/* Load all audit modules. */
|
||||||
|
static void
|
||||||
|
load_audit_modules (struct link_map *main_map, struct audit_list *audit_list)
|
||||||
|
@@ -1101,8 +1082,8 @@ load_audit_modules (struct link_map *main_map, struct audit_list *audit_list)
|
||||||
|
program and the dynamic linker itself). */
|
||||||
|
if (GLRO(dl_naudit) > 0)
|
||||||
|
{
|
||||||
|
- notify_audit_modules_of_loaded_object (main_map);
|
||||||
|
- notify_audit_modules_of_loaded_object (&GL(dl_rtld_map));
|
||||||
|
+ _dl_audit_objopen (main_map, LM_ID_BASE);
|
||||||
|
+ _dl_audit_objopen (&GL(dl_rtld_map), LM_ID_BASE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||||
|
index bcf1f199c5985c65..5709e4e48dff4355 100644
|
||||||
|
--- a/sysdeps/generic/ldsodefs.h
|
||||||
|
+++ b/sysdeps/generic/ldsodefs.h
|
||||||
|
@@ -1372,6 +1372,11 @@ link_map_audit_state (struct link_map *l, size_t index)
|
||||||
|
return &base[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+/* Call the la_objopen from the audit modules for the link_map L on the
|
||||||
|
+ namespace identification NSID. */
|
||||||
|
+void _dl_audit_objopen (struct link_map *l, Lmid_t nsid)
|
||||||
|
+ attribute_hidden;
|
||||||
|
#endif /* SHARED */
|
||||||
|
|
||||||
|
#if PTHREAD_IN_LIBC && defined SHARED
|
254
glibc-upstream-2.34-143.patch
Normal file
254
glibc-upstream-2.34-143.patch
Normal file
@ -0,0 +1,254 @@
|
|||||||
|
commit 66e9d27a090874ab93030a908eb86fc29f856151
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Tue Jul 20 11:03:34 2021 -0300
|
||||||
|
|
||||||
|
elf: Add _dl_audit_activity_map and _dl_audit_activity_nsid
|
||||||
|
|
||||||
|
It consolidates the code required to call la_activity audit
|
||||||
|
callback.
|
||||||
|
|
||||||
|
Also for a new Lmid_t the namespace link_map list are empty, so it
|
||||||
|
requires to check if before using it. This can happen for when audit
|
||||||
|
module is used along with dlmopen.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
(cherry picked from commit 3dac3959a5cb585b065cef2cb8a8d909c907e202)
|
||||||
|
|
||||||
|
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
|
||||||
|
index 4066dfe85146b9d4..74b87f4b39be75e1 100644
|
||||||
|
--- a/elf/dl-audit.c
|
||||||
|
+++ b/elf/dl-audit.c
|
||||||
|
@@ -18,6 +18,32 @@
|
||||||
|
|
||||||
|
#include <ldsodefs.h>
|
||||||
|
|
||||||
|
+void
|
||||||
|
+_dl_audit_activity_map (struct link_map *l, int action)
|
||||||
|
+{
|
||||||
|
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
+ {
|
||||||
|
+ if (afct->activity != NULL)
|
||||||
|
+ afct->activity (&link_map_audit_state (l, cnt)->cookie, action);
|
||||||
|
+ afct = afct->next;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+_dl_audit_activity_nsid (Lmid_t nsid, int action)
|
||||||
|
+{
|
||||||
|
+ /* If head is NULL, the namespace has become empty, and the audit interface
|
||||||
|
+ does not give us a way to signal LA_ACT_CONSISTENT for it because the
|
||||||
|
+ first loaded module is used to identify the namespace. */
|
||||||
|
+ struct link_map *head = GL(dl_ns)[nsid]._ns_loaded;
|
||||||
|
+ if (__glibc_likely (GLRO(dl_naudit) == 0)
|
||||||
|
+ || head == NULL || head->l_auditing)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ _dl_audit_activity_map (head, action);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
_dl_audit_objopen (struct link_map *l, Lmid_t nsid)
|
||||||
|
{
|
||||||
|
diff --git a/elf/dl-close.c b/elf/dl-close.c
|
||||||
|
index f6fbf9de7d78555b..5a8cc9e7cb5186cc 100644
|
||||||
|
--- a/elf/dl-close.c
|
||||||
|
+++ b/elf/dl-close.c
|
||||||
|
@@ -472,25 +472,7 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||||
|
|
||||||
|
#ifdef SHARED
|
||||||
|
/* Auditing checkpoint: we will start deleting objects. */
|
||||||
|
- if (__glibc_unlikely (do_audit))
|
||||||
|
- {
|
||||||
|
- struct link_map *head = ns->_ns_loaded;
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- /* Do not call the functions for any auditing object. */
|
||||||
|
- if (head->l_auditing == 0)
|
||||||
|
- {
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- if (afct->activity != NULL)
|
||||||
|
- {
|
||||||
|
- struct auditstate *state = link_map_audit_state (head, cnt);
|
||||||
|
- afct->activity (&state->cookie, LA_ACT_DELETE);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ _dl_audit_activity_nsid (nsid, LA_ACT_DELETE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Notify the debugger we are about to remove some loaded objects. */
|
||||||
|
@@ -785,32 +767,9 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||||
|
__rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
|
||||||
|
|
||||||
|
#ifdef SHARED
|
||||||
|
- /* Auditing checkpoint: we have deleted all objects. */
|
||||||
|
- if (__glibc_unlikely (do_audit))
|
||||||
|
- {
|
||||||
|
- struct link_map *head = ns->_ns_loaded;
|
||||||
|
- /* If head is NULL, the namespace has become empty, and the
|
||||||
|
- audit interface does not give us a way to signal
|
||||||
|
- LA_ACT_CONSISTENT for it because the first loaded module is
|
||||||
|
- used to identify the namespace.
|
||||||
|
-
|
||||||
|
- Furthermore, do not notify auditors of the cleanup of a
|
||||||
|
- failed audit module loading attempt. */
|
||||||
|
- if (head != NULL && head->l_auditing == 0)
|
||||||
|
- {
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- if (afct->activity != NULL)
|
||||||
|
- {
|
||||||
|
- struct auditstate *state = link_map_audit_state (head, cnt);
|
||||||
|
- afct->activity (&state->cookie, LA_ACT_CONSISTENT);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ /* Auditing checkpoint: we have deleted all objects. Also, do not notify
|
||||||
|
+ auditors of the cleanup of a failed audit module loading attempt. */
|
||||||
|
+ _dl_audit_activity_nsid (nsid, LA_ACT_CONSISTENT);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (__builtin_expect (ns->_ns_loaded == NULL, 0)
|
||||||
|
diff --git a/elf/dl-load.c b/elf/dl-load.c
|
||||||
|
index a2d73d025c65cd79..baf0a926053deaed 100644
|
||||||
|
--- a/elf/dl-load.c
|
||||||
|
+++ b/elf/dl-load.c
|
||||||
|
@@ -1482,24 +1482,8 @@ cannot enable executable stack as shared object requires");
|
||||||
|
/* Auditing checkpoint: we are going to add new objects. Since this
|
||||||
|
is called after _dl_add_to_namespace_list the namespace is guaranteed
|
||||||
|
to not be empty. */
|
||||||
|
- if ((mode & __RTLD_AUDIT) == 0
|
||||||
|
- && __glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||||
|
- {
|
||||||
|
- struct link_map *head = GL(dl_ns)[nsid]._ns_loaded;
|
||||||
|
- /* Do not call the functions for any auditing object. */
|
||||||
|
- if (head->l_auditing == 0)
|
||||||
|
- {
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- if (afct->activity != NULL)
|
||||||
|
- afct->activity (&link_map_audit_state (head, cnt)->cookie,
|
||||||
|
- LA_ACT_ADD);
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ if ((mode & __RTLD_AUDIT) == 0)
|
||||||
|
+ _dl_audit_activity_nsid (nsid, LA_ACT_ADD);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Notify the debugger we have added some objects. We need to
|
||||||
|
diff --git a/elf/dl-open.c b/elf/dl-open.c
|
||||||
|
index bc68e2c376debd71..3f01aa480730da13 100644
|
||||||
|
--- a/elf/dl-open.c
|
||||||
|
+++ b/elf/dl-open.c
|
||||||
|
@@ -611,25 +611,7 @@ dl_open_worker_begin (void *a)
|
||||||
|
|
||||||
|
#ifdef SHARED
|
||||||
|
/* Auditing checkpoint: we have added all objects. */
|
||||||
|
- if (__glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||||
|
- {
|
||||||
|
- struct link_map *head = GL(dl_ns)[new->l_ns]._ns_loaded;
|
||||||
|
- /* Do not call the functions for any auditing object. */
|
||||||
|
- if (head->l_auditing == 0)
|
||||||
|
- {
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- if (afct->activity != NULL)
|
||||||
|
- {
|
||||||
|
- struct auditstate *state = link_map_audit_state (head, cnt);
|
||||||
|
- afct->activity (&state->cookie, LA_ACT_CONSISTENT);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ _dl_audit_activity_nsid (new->l_ns, LA_ACT_CONSISTENT);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Notify the debugger all new objects are now ready to go. */
|
||||||
|
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||||
|
index 45fec0df3043b90a..b6bb46ca97b7972f 100644
|
||||||
|
--- a/elf/rtld.c
|
||||||
|
+++ b/elf/rtld.c
|
||||||
|
@@ -1804,18 +1804,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||||
|
|
||||||
|
/* Auditing checkpoint: we are ready to signal that the initial map
|
||||||
|
is being constructed. */
|
||||||
|
- if (__glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||||
|
- {
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- if (afct->activity != NULL)
|
||||||
|
- afct->activity (&link_map_audit_state (main_map, cnt)->cookie,
|
||||||
|
- LA_ACT_ADD);
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ _dl_audit_activity_map (main_map, LA_ACT_ADD);
|
||||||
|
|
||||||
|
/* We have two ways to specify objects to preload: via environment
|
||||||
|
variable and via the file /etc/ld.so.preload. The latter can also
|
||||||
|
@@ -2496,23 +2485,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||||
|
|
||||||
|
#ifdef SHARED
|
||||||
|
/* Auditing checkpoint: we have added all objects. */
|
||||||
|
- if (__glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||||
|
- {
|
||||||
|
- struct link_map *head = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
|
||||||
|
- /* Do not call the functions for any auditing object. */
|
||||||
|
- if (head->l_auditing == 0)
|
||||||
|
- {
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- if (afct->activity != NULL)
|
||||||
|
- afct->activity (&link_map_audit_state (head, cnt)->cookie,
|
||||||
|
- LA_ACT_CONSISTENT);
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ _dl_audit_activity_nsid (LM_ID_BASE, LA_ACT_CONSISTENT);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Notify the debugger all new objects are now ready to go. We must re-get
|
||||||
|
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||||
|
index 5709e4e48dff4355..7384abcf5e0e8e24 100644
|
||||||
|
--- a/sysdeps/generic/ldsodefs.h
|
||||||
|
+++ b/sysdeps/generic/ldsodefs.h
|
||||||
|
@@ -1373,6 +1373,16 @@ link_map_audit_state (struct link_map *l, size_t index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Call the la_activity from the audit modules from the link map L and issues
|
||||||
|
+ the ACTION argument. */
|
||||||
|
+void _dl_audit_activity_map (struct link_map *l, int action)
|
||||||
|
+ attribute_hidden;
|
||||||
|
+
|
||||||
|
+/* Call the la_activity from the audit modules from the link map from the
|
||||||
|
+ namespace NSID and issues the ACTION argument. */
|
||||||
|
+void _dl_audit_activity_nsid (Lmid_t nsid, int action)
|
||||||
|
+ attribute_hidden;
|
||||||
|
+
|
||||||
|
/* Call the la_objopen from the audit modules for the link_map L on the
|
||||||
|
namespace identification NSID. */
|
||||||
|
void _dl_audit_objopen (struct link_map *l, Lmid_t nsid)
|
157
glibc-upstream-2.34-144.patch
Normal file
157
glibc-upstream-2.34-144.patch
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
commit ec0fc2a15358dc5f7191f9994f04b1385d14377d
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Tue Jul 20 13:47:36 2021 -0300
|
||||||
|
|
||||||
|
elf: Add _dl_audit_objsearch
|
||||||
|
|
||||||
|
It consolidates the code required to call la_objsearch audit
|
||||||
|
callback.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
(cherry picked from commit c91008d3490e4e3ce29520068405f081f0d368ca)
|
||||||
|
|
||||||
|
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
|
||||||
|
index 74b87f4b39be75e1..5682427220569d90 100644
|
||||||
|
--- a/elf/dl-audit.c
|
||||||
|
+++ b/elf/dl-audit.c
|
||||||
|
@@ -44,6 +44,28 @@ _dl_audit_activity_nsid (Lmid_t nsid, int action)
|
||||||
|
_dl_audit_activity_map (head, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
+const char *
|
||||||
|
+_dl_audit_objsearch (const char *name, struct link_map *l, unsigned int code)
|
||||||
|
+{
|
||||||
|
+ if (l == NULL || l->l_auditing || code == 0)
|
||||||
|
+ return name;
|
||||||
|
+
|
||||||
|
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
+ {
|
||||||
|
+ if (afct->objsearch != NULL)
|
||||||
|
+ {
|
||||||
|
+ struct auditstate *state = link_map_audit_state (l, cnt);
|
||||||
|
+ name = afct->objsearch (name, &state->cookie, code);
|
||||||
|
+ if (name == NULL)
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+ afct = afct->next;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return name;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
_dl_audit_objopen (struct link_map *l, Lmid_t nsid)
|
||||||
|
{
|
||||||
|
diff --git a/elf/dl-load.c b/elf/dl-load.c
|
||||||
|
index baf0a926053deaed..eb6b658b698f5694 100644
|
||||||
|
--- a/elf/dl-load.c
|
||||||
|
+++ b/elf/dl-load.c
|
||||||
|
@@ -1596,32 +1596,20 @@ open_verify (const char *name, int fd,
|
||||||
|
|
||||||
|
#ifdef SHARED
|
||||||
|
/* Give the auditing libraries a chance. */
|
||||||
|
- if (__glibc_unlikely (GLRO(dl_naudit) > 0) && whatcode != 0
|
||||||
|
- && loader->l_auditing == 0)
|
||||||
|
+ if (__glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||||
|
{
|
||||||
|
const char *original_name = name;
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- if (afct->objsearch != NULL)
|
||||||
|
- {
|
||||||
|
- struct auditstate *state = link_map_audit_state (loader, cnt);
|
||||||
|
- name = afct->objsearch (name, &state->cookie, whatcode);
|
||||||
|
- if (name == NULL)
|
||||||
|
- /* Ignore the path. */
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
+ name = _dl_audit_objsearch (name, loader, whatcode);
|
||||||
|
+ if (name == NULL)
|
||||||
|
+ return -1;
|
||||||
|
|
||||||
|
if (fd != -1 && name != original_name && strcmp (name, original_name))
|
||||||
|
- {
|
||||||
|
- /* An audit library changed what we're supposed to open,
|
||||||
|
- so FD no longer matches it. */
|
||||||
|
- __close_nocancel (fd);
|
||||||
|
- fd = -1;
|
||||||
|
- }
|
||||||
|
+ {
|
||||||
|
+ /* An audit library changed what we're supposed to open,
|
||||||
|
+ so FD no longer matches it. */
|
||||||
|
+ __close_nocancel (fd);
|
||||||
|
+ fd = -1;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@@ -2060,36 +2048,17 @@ _dl_map_object (struct link_map *loader, const char *name,
|
||||||
|
#ifdef SHARED
|
||||||
|
/* Give the auditing libraries a chance to change the name before we
|
||||||
|
try anything. */
|
||||||
|
- if (__glibc_unlikely (GLRO(dl_naudit) > 0)
|
||||||
|
- && (loader == NULL || loader->l_auditing == 0))
|
||||||
|
+ if (__glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||||
|
{
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
+ const char *before = name;
|
||||||
|
+ name = _dl_audit_objsearch (name, loader, LA_SER_ORIG);
|
||||||
|
+ if (name == NULL)
|
||||||
|
{
|
||||||
|
- if (afct->objsearch != NULL)
|
||||||
|
- {
|
||||||
|
- const char *before = name;
|
||||||
|
- struct auditstate *state = link_map_audit_state (loader, cnt);
|
||||||
|
- name = afct->objsearch (name, &state->cookie, LA_SER_ORIG);
|
||||||
|
- if (name == NULL)
|
||||||
|
- {
|
||||||
|
- /* Do not try anything further. */
|
||||||
|
- fd = -1;
|
||||||
|
- goto no_file;
|
||||||
|
- }
|
||||||
|
- if (before != name && strcmp (before, name) != 0)
|
||||||
|
- {
|
||||||
|
- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
|
||||||
|
- _dl_debug_printf ("audit changed filename %s -> %s\n",
|
||||||
|
- before, name);
|
||||||
|
-
|
||||||
|
- if (origname == NULL)
|
||||||
|
- origname = before;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
+ fd = -1;
|
||||||
|
+ goto no_file;
|
||||||
|
}
|
||||||
|
+ if (before != name && strcmp (before, name) != 0)
|
||||||
|
+ origname = before;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||||
|
index 7384abcf5e0e8e24..1f212a18d7bfc440 100644
|
||||||
|
--- a/sysdeps/generic/ldsodefs.h
|
||||||
|
+++ b/sysdeps/generic/ldsodefs.h
|
||||||
|
@@ -1373,6 +1373,13 @@ link_map_audit_state (struct link_map *l, size_t index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Call the la_objsearch from the audit modules from the link map L. If
|
||||||
|
+ ORIGNAME is non NULL, it is updated with the revious name prior calling
|
||||||
|
+ la_objsearch. */
|
||||||
|
+const char *_dl_audit_objsearch (const char *name, struct link_map *l,
|
||||||
|
+ unsigned int code)
|
||||||
|
+ attribute_hidden;
|
||||||
|
+
|
||||||
|
/* Call the la_activity from the audit modules from the link map L and issues
|
||||||
|
the ACTION argument. */
|
||||||
|
void _dl_audit_activity_map (struct link_map *l, int action)
|
123
glibc-upstream-2.34-145.patch
Normal file
123
glibc-upstream-2.34-145.patch
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
commit 198660741b23ec9defb19e22951d4a721de603c8
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Tue Jul 20 14:04:51 2021 -0300
|
||||||
|
|
||||||
|
elf: Add _dl_audit_objclose
|
||||||
|
|
||||||
|
It consolidates the code required to call la_objclose audit
|
||||||
|
callback.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
(cherry picked from commit 311c9ee54ea963ff69bd3a2e6981c37e893b4c3e)
|
||||||
|
|
||||||
|
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
|
||||||
|
index 5682427220569d90..cb1c3de93cba447b 100644
|
||||||
|
--- a/elf/dl-audit.c
|
||||||
|
+++ b/elf/dl-audit.c
|
||||||
|
@@ -85,3 +85,24 @@ _dl_audit_objopen (struct link_map *l, Lmid_t nsid)
|
||||||
|
afct = afct->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+_dl_audit_objclose (struct link_map *l)
|
||||||
|
+{
|
||||||
|
+ if (__glibc_likely (GLRO(dl_naudit) == 0)
|
||||||
|
+ || GL(dl_ns)[l->l_ns]._ns_loaded->l_auditing)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
+ {
|
||||||
|
+ if (afct->objclose != NULL)
|
||||||
|
+ {
|
||||||
|
+ struct auditstate *state= link_map_audit_state (l, cnt);
|
||||||
|
+ /* Return value is ignored. */
|
||||||
|
+ afct->objclose (&state->cookie);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ afct = afct->next;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/elf/dl-close.c b/elf/dl-close.c
|
||||||
|
index 5a8cc9e7cb5186cc..985cd4e2821436af 100644
|
||||||
|
--- a/elf/dl-close.c
|
||||||
|
+++ b/elf/dl-close.c
|
||||||
|
@@ -260,9 +260,6 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||||
|
_dl_sort_maps (maps, nloaded, (nsid == LM_ID_BASE), true);
|
||||||
|
|
||||||
|
/* Call all termination functions at once. */
|
||||||
|
-#ifdef SHARED
|
||||||
|
- bool do_audit = GLRO(dl_naudit) > 0 && !ns->_ns_loaded->l_auditing;
|
||||||
|
-#endif
|
||||||
|
bool unload_any = false;
|
||||||
|
bool scope_mem_left = false;
|
||||||
|
unsigned int unload_global = 0;
|
||||||
|
@@ -296,22 +293,7 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||||
|
|
||||||
|
#ifdef SHARED
|
||||||
|
/* Auditing checkpoint: we remove an object. */
|
||||||
|
- if (__glibc_unlikely (do_audit))
|
||||||
|
- {
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- if (afct->objclose != NULL)
|
||||||
|
- {
|
||||||
|
- struct auditstate *state
|
||||||
|
- = link_map_audit_state (imap, cnt);
|
||||||
|
- /* Return value is ignored. */
|
||||||
|
- (void) afct->objclose (&state->cookie);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ _dl_audit_objclose (imap);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This object must not be used anymore. */
|
||||||
|
diff --git a/elf/dl-fini.c b/elf/dl-fini.c
|
||||||
|
index c683884c355dfd52..b789cfb9f2ac6c85 100644
|
||||||
|
--- a/elf/dl-fini.c
|
||||||
|
+++ b/elf/dl-fini.c
|
||||||
|
@@ -146,21 +146,7 @@ _dl_fini (void)
|
||||||
|
|
||||||
|
#ifdef SHARED
|
||||||
|
/* Auditing checkpoint: another object closed. */
|
||||||
|
- if (!do_audit && __builtin_expect (GLRO(dl_naudit) > 0, 0))
|
||||||
|
- {
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- if (afct->objclose != NULL)
|
||||||
|
- {
|
||||||
|
- struct auditstate *state
|
||||||
|
- = link_map_audit_state (l, cnt);
|
||||||
|
- /* Return value is ignored. */
|
||||||
|
- (void) afct->objclose (&state->cookie);
|
||||||
|
- }
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ _dl_audit_objclose (l);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||||
|
index 1f212a18d7bfc440..982f23c0287955fe 100644
|
||||||
|
--- a/sysdeps/generic/ldsodefs.h
|
||||||
|
+++ b/sysdeps/generic/ldsodefs.h
|
||||||
|
@@ -1394,6 +1394,10 @@ void _dl_audit_activity_nsid (Lmid_t nsid, int action)
|
||||||
|
namespace identification NSID. */
|
||||||
|
void _dl_audit_objopen (struct link_map *l, Lmid_t nsid)
|
||||||
|
attribute_hidden;
|
||||||
|
+
|
||||||
|
+/* Call the la_objclose from the audit modules for the link_map L. */
|
||||||
|
+void _dl_audit_objclose (struct link_map *l)
|
||||||
|
+ attribute_hidden;
|
||||||
|
#endif /* SHARED */
|
||||||
|
|
||||||
|
#if PTHREAD_IN_LIBC && defined SHARED
|
334
glibc-upstream-2.34-146.patch
Normal file
334
glibc-upstream-2.34-146.patch
Normal file
@ -0,0 +1,334 @@
|
|||||||
|
commit b2d99731b6d27c719a30b8ffa931e91c73a6bb4b
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Tue Jul 20 15:58:35 2021 -0300
|
||||||
|
|
||||||
|
elf: Add _dl_audit_symbind_alt and _dl_audit_symbind
|
||||||
|
|
||||||
|
It consolidates the code required to call la_symbind{32,64} audit
|
||||||
|
callback.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
(cherry picked from commit cda4f265c65fb6c4ce38ca1cf0a7e527c5e77cd5)
|
||||||
|
|
||||||
|
diff --git a/elf/Versions b/elf/Versions
|
||||||
|
index 2af210b8f771c950..164682eaeaa9a1da 100644
|
||||||
|
--- a/elf/Versions
|
||||||
|
+++ b/elf/Versions
|
||||||
|
@@ -58,6 +58,7 @@ ld {
|
||||||
|
_dl_argv; _dl_find_dso_for_object; _dl_get_tls_static_info;
|
||||||
|
_dl_deallocate_tls; _dl_make_stack_executable;
|
||||||
|
_dl_rtld_di_serinfo; _dl_starting_up; _dl_fatal_printf;
|
||||||
|
+ _dl_audit_symbind_alt;
|
||||||
|
_rtld_global; _rtld_global_ro;
|
||||||
|
|
||||||
|
# Only here for gdb while a better method is developed.
|
||||||
|
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
|
||||||
|
index cb1c3de93cba447b..a21530f30bc5524b 100644
|
||||||
|
--- a/elf/dl-audit.c
|
||||||
|
+++ b/elf/dl-audit.c
|
||||||
|
@@ -16,6 +16,7 @@
|
||||||
|
License along with the GNU C Library; if not, see
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
+#include <assert.h>
|
||||||
|
#include <ldsodefs.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
@@ -106,3 +107,124 @@ _dl_audit_objclose (struct link_map *l)
|
||||||
|
afct = afct->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+_dl_audit_symbind_alt (struct link_map *l, const ElfW(Sym) *ref, void **value,
|
||||||
|
+ lookup_t result)
|
||||||
|
+{
|
||||||
|
+ if ((l->l_audit_any_plt | result->l_audit_any_plt) == 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ const char *strtab = (const char *) D_PTR (result, l_info[DT_STRTAB]);
|
||||||
|
+ /* Compute index of the symbol entry in the symbol table of the DSO with
|
||||||
|
+ the definition. */
|
||||||
|
+ unsigned int ndx = (ref - (ElfW(Sym) *) D_PTR (result, l_info[DT_SYMTAB]));
|
||||||
|
+
|
||||||
|
+ unsigned int altvalue = 0;
|
||||||
|
+ /* Synthesize a symbol record where the st_value field is the result. */
|
||||||
|
+ ElfW(Sym) sym = *ref;
|
||||||
|
+ sym.st_value = (ElfW(Addr)) *value;
|
||||||
|
+
|
||||||
|
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
+ {
|
||||||
|
+ struct auditstate *match_audit = link_map_audit_state (l, cnt);
|
||||||
|
+ struct auditstate *result_audit = link_map_audit_state (result, cnt);
|
||||||
|
+ if (afct->symbind != NULL
|
||||||
|
+ && ((match_audit->bindflags & LA_FLG_BINDFROM) != 0
|
||||||
|
+ || ((result_audit->bindflags & LA_FLG_BINDTO)
|
||||||
|
+ != 0)))
|
||||||
|
+ {
|
||||||
|
+ unsigned int flags = altvalue | LA_SYMB_DLSYM;
|
||||||
|
+ uintptr_t new_value = afct->symbind (&sym, ndx,
|
||||||
|
+ &match_audit->cookie,
|
||||||
|
+ &result_audit->cookie,
|
||||||
|
+ &flags, strtab + ref->st_name);
|
||||||
|
+ if (new_value != (uintptr_t) sym.st_value)
|
||||||
|
+ {
|
||||||
|
+ altvalue = LA_SYMB_ALTVALUE;
|
||||||
|
+ sym.st_value = new_value;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ afct = afct->next;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *value = (void *) sym.st_value;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+rtld_hidden_def (_dl_audit_symbind_alt)
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+_dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
|
||||||
|
+ const ElfW(Sym) *defsym, DL_FIXUP_VALUE_TYPE *value,
|
||||||
|
+ lookup_t result)
|
||||||
|
+{
|
||||||
|
+ reloc_result->bound = result;
|
||||||
|
+ /* Compute index of the symbol entry in the symbol table of the DSO with the
|
||||||
|
+ definition. */
|
||||||
|
+ reloc_result->boundndx = (defsym - (ElfW(Sym) *) D_PTR (result,
|
||||||
|
+ l_info[DT_SYMTAB]));
|
||||||
|
+
|
||||||
|
+ if ((l->l_audit_any_plt | result->l_audit_any_plt) == 0)
|
||||||
|
+ {
|
||||||
|
+ /* Set all bits since this symbol binding is not interesting. */
|
||||||
|
+ reloc_result->enterexit = (1u << DL_NNS) - 1;
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Synthesize a symbol record where the st_value field is the result. */
|
||||||
|
+ ElfW(Sym) sym = *defsym;
|
||||||
|
+ sym.st_value = DL_FIXUP_VALUE_ADDR (*value);
|
||||||
|
+
|
||||||
|
+ /* Keep track whether there is any interest in tracing the call in the lower
|
||||||
|
+ two bits. */
|
||||||
|
+ assert (DL_NNS * 2 <= sizeof (reloc_result->flags) * 8);
|
||||||
|
+ assert ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) == 3);
|
||||||
|
+ reloc_result->enterexit = LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT;
|
||||||
|
+
|
||||||
|
+ const char *strtab2 = (const void *) D_PTR (result, l_info[DT_STRTAB]);
|
||||||
|
+
|
||||||
|
+ unsigned int flags = 0;
|
||||||
|
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
+ {
|
||||||
|
+ /* XXX Check whether both DSOs must request action or only one */
|
||||||
|
+ struct auditstate *l_state = link_map_audit_state (l, cnt);
|
||||||
|
+ struct auditstate *result_state = link_map_audit_state (result, cnt);
|
||||||
|
+ if ((l_state->bindflags & LA_FLG_BINDFROM) != 0
|
||||||
|
+ && (result_state->bindflags & LA_FLG_BINDTO) != 0)
|
||||||
|
+ {
|
||||||
|
+ if (afct->symbind != NULL)
|
||||||
|
+ {
|
||||||
|
+ uintptr_t new_value = afct->symbind (&sym,
|
||||||
|
+ reloc_result->boundndx,
|
||||||
|
+ &l_state->cookie,
|
||||||
|
+ &result_state->cookie,
|
||||||
|
+ &flags,
|
||||||
|
+ strtab2 + defsym->st_name);
|
||||||
|
+ if (new_value != (uintptr_t) sym.st_value)
|
||||||
|
+ {
|
||||||
|
+ flags |= LA_SYMB_ALTVALUE;
|
||||||
|
+ sym.st_value = new_value;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Remember the results for every audit library and store a summary
|
||||||
|
+ in the first two bits. */
|
||||||
|
+ reloc_result->enterexit &= flags & (LA_SYMB_NOPLTENTER
|
||||||
|
+ | LA_SYMB_NOPLTEXIT);
|
||||||
|
+ reloc_result->enterexit |= ((flags & (LA_SYMB_NOPLTENTER
|
||||||
|
+ | LA_SYMB_NOPLTEXIT))
|
||||||
|
+ << ((cnt + 1) * 2));
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ /* If the bind flags say this auditor is not interested, set the bits
|
||||||
|
+ manually. */
|
||||||
|
+ reloc_result->enterexit |= ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)
|
||||||
|
+ << ((cnt + 1) * 2));
|
||||||
|
+ afct = afct->next;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ reloc_result->flags = flags;
|
||||||
|
+ *value = DL_FIXUP_ADDR_VALUE (sym.st_value);
|
||||||
|
+}
|
||||||
|
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
|
||||||
|
index 61c260ddb81b586c..c4413c9165cec8cb 100644
|
||||||
|
--- a/elf/dl-runtime.c
|
||||||
|
+++ b/elf/dl-runtime.c
|
||||||
|
@@ -297,84 +297,7 @@ _dl_profile_fixup (
|
||||||
|
auditing libraries the possibility to change the value and
|
||||||
|
tell us whether further auditing is wanted. */
|
||||||
|
if (defsym != NULL && GLRO(dl_naudit) > 0)
|
||||||
|
- {
|
||||||
|
- reloc_result->bound = result;
|
||||||
|
- /* Compute index of the symbol entry in the symbol table of
|
||||||
|
- the DSO with the definition. */
|
||||||
|
- reloc_result->boundndx = (defsym
|
||||||
|
- - (ElfW(Sym) *) D_PTR (result,
|
||||||
|
- l_info[DT_SYMTAB]));
|
||||||
|
-
|
||||||
|
- /* Determine whether any of the two participating DSOs is
|
||||||
|
- interested in auditing. */
|
||||||
|
- if ((l->l_audit_any_plt | result->l_audit_any_plt) != 0)
|
||||||
|
- {
|
||||||
|
- unsigned int flags = 0;
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- /* Synthesize a symbol record where the st_value field is
|
||||||
|
- the result. */
|
||||||
|
- ElfW(Sym) sym = *defsym;
|
||||||
|
- sym.st_value = DL_FIXUP_VALUE_ADDR (value);
|
||||||
|
-
|
||||||
|
- /* Keep track whether there is any interest in tracing
|
||||||
|
- the call in the lower two bits. */
|
||||||
|
- assert (DL_NNS * 2 <= sizeof (reloc_result->flags) * 8);
|
||||||
|
- assert ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) == 3);
|
||||||
|
- reloc_result->enterexit = LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT;
|
||||||
|
-
|
||||||
|
- const char *strtab2 = (const void *) D_PTR (result,
|
||||||
|
- l_info[DT_STRTAB]);
|
||||||
|
-
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- /* XXX Check whether both DSOs must request action or
|
||||||
|
- only one */
|
||||||
|
- struct auditstate *l_state = link_map_audit_state (l, cnt);
|
||||||
|
- struct auditstate *result_state
|
||||||
|
- = link_map_audit_state (result, cnt);
|
||||||
|
- if ((l_state->bindflags & LA_FLG_BINDFROM) != 0
|
||||||
|
- && (result_state->bindflags & LA_FLG_BINDTO) != 0)
|
||||||
|
- {
|
||||||
|
- if (afct->symbind != NULL)
|
||||||
|
- {
|
||||||
|
- uintptr_t new_value
|
||||||
|
- = afct->symbind (&sym, reloc_result->boundndx,
|
||||||
|
- &l_state->cookie,
|
||||||
|
- &result_state->cookie,
|
||||||
|
- &flags,
|
||||||
|
- strtab2 + defsym->st_name);
|
||||||
|
- if (new_value != (uintptr_t) sym.st_value)
|
||||||
|
- {
|
||||||
|
- flags |= LA_SYMB_ALTVALUE;
|
||||||
|
- sym.st_value = new_value;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* Remember the results for every audit library and
|
||||||
|
- store a summary in the first two bits. */
|
||||||
|
- reloc_result->enterexit
|
||||||
|
- &= flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT);
|
||||||
|
- reloc_result->enterexit
|
||||||
|
- |= ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT))
|
||||||
|
- << ((cnt + 1) * 2));
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- /* If the bind flags say this auditor is not interested,
|
||||||
|
- set the bits manually. */
|
||||||
|
- reloc_result->enterexit
|
||||||
|
- |= ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)
|
||||||
|
- << ((cnt + 1) * 2));
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- reloc_result->flags = flags;
|
||||||
|
- value = DL_FIXUP_ADDR_VALUE (sym.st_value);
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- /* Set all bits since this symbol binding is not interesting. */
|
||||||
|
- reloc_result->enterexit = (1u << DL_NNS) - 1;
|
||||||
|
- }
|
||||||
|
+ _dl_audit_symbind (l, reloc_result, defsym, &value, result);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Store the result for later runs. */
|
||||||
|
diff --git a/elf/dl-sym-post.h b/elf/dl-sym-post.h
|
||||||
|
index d68c2d2b1cd43c9b..a11095d3e8c3c937 100644
|
||||||
|
--- a/elf/dl-sym-post.h
|
||||||
|
+++ b/elf/dl-sym-post.h
|
||||||
|
@@ -52,54 +52,9 @@ _dl_sym_post (lookup_t result, const ElfW(Sym) *ref, void *value,
|
||||||
|
tell us whether further auditing is wanted. */
|
||||||
|
if (__glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||||
|
{
|
||||||
|
- const char *strtab = (const char *) D_PTR (result,
|
||||||
|
- l_info[DT_STRTAB]);
|
||||||
|
- /* Compute index of the symbol entry in the symbol table of
|
||||||
|
- the DSO with the definition. */
|
||||||
|
- unsigned int ndx = (ref - (ElfW(Sym) *) D_PTR (result,
|
||||||
|
- l_info[DT_SYMTAB]));
|
||||||
|
-
|
||||||
|
if (match == NULL)
|
||||||
|
match = _dl_sym_find_caller_link_map (caller);
|
||||||
|
-
|
||||||
|
- if ((match->l_audit_any_plt | result->l_audit_any_plt) != 0)
|
||||||
|
- {
|
||||||
|
- unsigned int altvalue = 0;
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- /* Synthesize a symbol record where the st_value field is
|
||||||
|
- the result. */
|
||||||
|
- ElfW(Sym) sym = *ref;
|
||||||
|
- sym.st_value = (ElfW(Addr)) value;
|
||||||
|
-
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- struct auditstate *match_audit
|
||||||
|
- = link_map_audit_state (match, cnt);
|
||||||
|
- struct auditstate *result_audit
|
||||||
|
- = link_map_audit_state (result, cnt);
|
||||||
|
- if (afct->symbind != NULL
|
||||||
|
- && ((match_audit->bindflags & LA_FLG_BINDFROM) != 0
|
||||||
|
- || ((result_audit->bindflags & LA_FLG_BINDTO)
|
||||||
|
- != 0)))
|
||||||
|
- {
|
||||||
|
- unsigned int flags = altvalue | LA_SYMB_DLSYM;
|
||||||
|
- uintptr_t new_value
|
||||||
|
- = afct->symbind (&sym, ndx,
|
||||||
|
- &match_audit->cookie,
|
||||||
|
- &result_audit->cookie,
|
||||||
|
- &flags, strtab + ref->st_name);
|
||||||
|
- if (new_value != (uintptr_t) sym.st_value)
|
||||||
|
- {
|
||||||
|
- altvalue = LA_SYMB_ALTVALUE;
|
||||||
|
- sym.st_value = new_value;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- value = (void *) sym.st_value;
|
||||||
|
- }
|
||||||
|
+ _dl_audit_symbind_alt (match, ref, &value, result);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return value;
|
||||||
|
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||||
|
index 982f23c0287955fe..61f1dfb3f79a613a 100644
|
||||||
|
--- a/sysdeps/generic/ldsodefs.h
|
||||||
|
+++ b/sysdeps/generic/ldsodefs.h
|
||||||
|
@@ -1398,6 +1398,16 @@ void _dl_audit_objopen (struct link_map *l, Lmid_t nsid)
|
||||||
|
/* Call the la_objclose from the audit modules for the link_map L. */
|
||||||
|
void _dl_audit_objclose (struct link_map *l)
|
||||||
|
attribute_hidden;
|
||||||
|
+
|
||||||
|
+/* Call the la_symbind{32,64} from the audit modules for the link_map L. */
|
||||||
|
+void _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
|
||||||
|
+ const ElfW(Sym) *defsym, DL_FIXUP_VALUE_TYPE *value,
|
||||||
|
+ lookup_t result)
|
||||||
|
+ attribute_hidden;
|
||||||
|
+/* Same as _dl_audit_symbind, but also sets LA_SYMB_DLSYM flag. */
|
||||||
|
+void _dl_audit_symbind_alt (struct link_map *l, const ElfW(Sym) *ref,
|
||||||
|
+ void **value, lookup_t result);
|
||||||
|
+rtld_hidden_proto (_dl_audit_symbind_alt)
|
||||||
|
#endif /* SHARED */
|
||||||
|
|
||||||
|
#if PTHREAD_IN_LIBC && defined SHARED
|
107
glibc-upstream-2.34-147.patch
Normal file
107
glibc-upstream-2.34-147.patch
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
commit 31473c273be14270f8eef68e35c03fd2305eb2c3
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Thu Jul 22 17:10:57 2021 -0300
|
||||||
|
|
||||||
|
elf: Add _dl_audit_preinit
|
||||||
|
|
||||||
|
It consolidates the code required to call la_preinit audit
|
||||||
|
callback.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
(cherry picked from commit 0b98a8748759e88b58927882a8714109abe0a2d6)
|
||||||
|
|
||||||
|
diff --git a/csu/libc-start.c b/csu/libc-start.c
|
||||||
|
index 0350b006fdcc22d2..d01e57ea59ceb880 100644
|
||||||
|
--- a/csu/libc-start.c
|
||||||
|
+++ b/csu/libc-start.c
|
||||||
|
@@ -377,32 +377,15 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
|
||||||
|
/* This is a current program. Use the dynamic segment to find
|
||||||
|
constructors. */
|
||||||
|
call_init (argc, argv, __environ);
|
||||||
|
-#else /* !SHARED */
|
||||||
|
- call_init (argc, argv, __environ);
|
||||||
|
-#endif /* SHARED */
|
||||||
|
|
||||||
|
-#ifdef SHARED
|
||||||
|
/* Auditing checkpoint: we have a new object. */
|
||||||
|
- if (__glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||||
|
- {
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- struct link_map *head = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- if (afct->preinit != NULL)
|
||||||
|
- afct->preinit (&link_map_audit_state (head, cnt)->cookie);
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-#endif
|
||||||
|
+ _dl_audit_preinit (GL(dl_ns)[LM_ID_BASE]._ns_loaded);
|
||||||
|
|
||||||
|
-#ifdef SHARED
|
||||||
|
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS))
|
||||||
|
GLRO(dl_debug_printf) ("\ntransferring control: %s\n\n", argv[0]);
|
||||||
|
-#endif
|
||||||
|
+#else /* !SHARED */
|
||||||
|
+ call_init (argc, argv, __environ);
|
||||||
|
|
||||||
|
-#ifndef SHARED
|
||||||
|
_dl_debug_initialize (0, LM_ID_BASE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
diff --git a/elf/Versions b/elf/Versions
|
||||||
|
index 164682eaeaa9a1da..bb6697647b397772 100644
|
||||||
|
--- a/elf/Versions
|
||||||
|
+++ b/elf/Versions
|
||||||
|
@@ -58,7 +58,7 @@ ld {
|
||||||
|
_dl_argv; _dl_find_dso_for_object; _dl_get_tls_static_info;
|
||||||
|
_dl_deallocate_tls; _dl_make_stack_executable;
|
||||||
|
_dl_rtld_di_serinfo; _dl_starting_up; _dl_fatal_printf;
|
||||||
|
- _dl_audit_symbind_alt;
|
||||||
|
+ _dl_audit_symbind_alt; _dl_audit_preinit;
|
||||||
|
_rtld_global; _rtld_global_ro;
|
||||||
|
|
||||||
|
# Only here for gdb while a better method is developed.
|
||||||
|
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
|
||||||
|
index a21530f30bc5524b..0b6fac8e48877c93 100644
|
||||||
|
--- a/elf/dl-audit.c
|
||||||
|
+++ b/elf/dl-audit.c
|
||||||
|
@@ -108,6 +108,21 @@ _dl_audit_objclose (struct link_map *l)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+_dl_audit_preinit (struct link_map *l)
|
||||||
|
+{
|
||||||
|
+ if (__glibc_likely (GLRO(dl_naudit) == 0))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
+ {
|
||||||
|
+ if (afct->preinit != NULL)
|
||||||
|
+ afct->preinit (&link_map_audit_state (l, cnt)->cookie);
|
||||||
|
+ afct = afct->next;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
_dl_audit_symbind_alt (struct link_map *l, const ElfW(Sym) *ref, void **value,
|
||||||
|
lookup_t result)
|
||||||
|
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||||
|
index 61f1dfb3f79a613a..91193a036fc5c6ef 100644
|
||||||
|
--- a/sysdeps/generic/ldsodefs.h
|
||||||
|
+++ b/sysdeps/generic/ldsodefs.h
|
||||||
|
@@ -1399,6 +1399,9 @@ void _dl_audit_objopen (struct link_map *l, Lmid_t nsid)
|
||||||
|
void _dl_audit_objclose (struct link_map *l)
|
||||||
|
attribute_hidden;
|
||||||
|
|
||||||
|
+/* Call the la_preinit from the audit modules for the link_map L. */
|
||||||
|
+void _dl_audit_preinit (struct link_map *l);
|
||||||
|
+
|
||||||
|
/* Call the la_symbind{32,64} from the audit modules for the link_map L. */
|
||||||
|
void _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
|
||||||
|
const ElfW(Sym) *defsym, DL_FIXUP_VALUE_TYPE *value,
|
206
glibc-upstream-2.34-148.patch
Normal file
206
glibc-upstream-2.34-148.patch
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
commit fd9c4e8a1b72fa1372855051217f9480680d882a
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Thu Jul 22 17:45:33 2021 -0300
|
||||||
|
|
||||||
|
elf: Add _dl_audit_pltenter
|
||||||
|
|
||||||
|
It consolidates the code required to call la_pltenter audit
|
||||||
|
callback.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
(cherry picked from commit eff687e8462b0eaf65992a6031b54a4b1cd16796)
|
||||||
|
|
||||||
|
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
|
||||||
|
index 0b6fac8e48877c93..15250c67e8ac1658 100644
|
||||||
|
--- a/elf/dl-audit.c
|
||||||
|
+++ b/elf/dl-audit.c
|
||||||
|
@@ -17,7 +17,9 @@
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
+#include <link.h>
|
||||||
|
#include <ldsodefs.h>
|
||||||
|
+#include <dl-machine.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
_dl_audit_activity_map (struct link_map *l, int action)
|
||||||
|
@@ -243,3 +245,78 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
|
||||||
|
reloc_result->flags = flags;
|
||||||
|
*value = DL_FIXUP_ADDR_VALUE (sym.st_value);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+_dl_audit_pltenter (struct link_map *l, struct reloc_result *reloc_result,
|
||||||
|
+ DL_FIXUP_VALUE_TYPE *value, void *regs, long int *framesize)
|
||||||
|
+{
|
||||||
|
+ /* Don't do anything if no auditor wants to intercept this call. */
|
||||||
|
+ if (GLRO(dl_naudit) == 0
|
||||||
|
+ || (reloc_result->enterexit & LA_SYMB_NOPLTENTER))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ /* Sanity check: DL_FIXUP_VALUE_CODE_ADDR (value) should have been
|
||||||
|
+ initialized earlier in this function or in another thread. */
|
||||||
|
+ assert (DL_FIXUP_VALUE_CODE_ADDR (*value) != 0);
|
||||||
|
+ ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
|
||||||
|
+ l_info[DT_SYMTAB])
|
||||||
|
+ + reloc_result->boundndx);
|
||||||
|
+
|
||||||
|
+ /* Set up the sym parameter. */
|
||||||
|
+ ElfW(Sym) sym = *defsym;
|
||||||
|
+ sym.st_value = DL_FIXUP_VALUE_ADDR (*value);
|
||||||
|
+
|
||||||
|
+ /* Get the symbol name. */
|
||||||
|
+ const char *strtab = (const void *) D_PTR (reloc_result->bound,
|
||||||
|
+ l_info[DT_STRTAB]);
|
||||||
|
+ const char *symname = strtab + sym.st_name;
|
||||||
|
+
|
||||||
|
+ /* Keep track of overwritten addresses. */
|
||||||
|
+ unsigned int flags = reloc_result->flags;
|
||||||
|
+
|
||||||
|
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
+ {
|
||||||
|
+ if (afct->ARCH_LA_PLTENTER != NULL
|
||||||
|
+ && (reloc_result->enterexit
|
||||||
|
+ & (LA_SYMB_NOPLTENTER << (2 * (cnt + 1)))) == 0)
|
||||||
|
+ {
|
||||||
|
+ long int new_framesize = -1;
|
||||||
|
+ struct auditstate *l_state = link_map_audit_state (l, cnt);
|
||||||
|
+ struct auditstate *bound_state
|
||||||
|
+ = link_map_audit_state (reloc_result->bound, cnt);
|
||||||
|
+ uintptr_t new_value
|
||||||
|
+ = afct->ARCH_LA_PLTENTER (&sym, reloc_result->boundndx,
|
||||||
|
+ &l_state->cookie, &bound_state->cookie,
|
||||||
|
+ regs, &flags, symname, &new_framesize);
|
||||||
|
+ if (new_value != (uintptr_t) sym.st_value)
|
||||||
|
+ {
|
||||||
|
+ flags |= LA_SYMB_ALTVALUE;
|
||||||
|
+ sym.st_value = new_value;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Remember the results for every audit library and store a summary
|
||||||
|
+ in the first two bits. */
|
||||||
|
+ reloc_result->enterexit |= ((flags & (LA_SYMB_NOPLTENTER
|
||||||
|
+ | LA_SYMB_NOPLTEXIT))
|
||||||
|
+ << (2 * (cnt + 1)));
|
||||||
|
+
|
||||||
|
+ if ((reloc_result->enterexit & (LA_SYMB_NOPLTEXIT
|
||||||
|
+ << (2 * (cnt + 1))))
|
||||||
|
+ == 0 && new_framesize != -1 && *framesize != -2)
|
||||||
|
+ {
|
||||||
|
+ /* If this is the first call providing information, use it. */
|
||||||
|
+ if (*framesize == -1)
|
||||||
|
+ *framesize = new_framesize;
|
||||||
|
+ /* If two pltenter calls provide conflicting information, use
|
||||||
|
+ the larger value. */
|
||||||
|
+ else if (new_framesize != *framesize)
|
||||||
|
+ *framesize = MAX (new_framesize, *framesize);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ afct = afct->next;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *value = DL_FIXUP_ADDR_VALUE (sym.st_value);
|
||||||
|
+}
|
||||||
|
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
|
||||||
|
index c4413c9165cec8cb..dfedeaf2dd1c7253 100644
|
||||||
|
--- a/elf/dl-runtime.c
|
||||||
|
+++ b/elf/dl-runtime.c
|
||||||
|
@@ -320,78 +320,7 @@ _dl_profile_fixup (
|
||||||
|
#ifdef SHARED
|
||||||
|
/* Auditing checkpoint: report the PLT entering and allow the
|
||||||
|
auditors to change the value. */
|
||||||
|
- if (GLRO(dl_naudit) > 0
|
||||||
|
- /* Don't do anything if no auditor wants to intercept this call. */
|
||||||
|
- && (reloc_result->enterexit & LA_SYMB_NOPLTENTER) == 0)
|
||||||
|
- {
|
||||||
|
- /* Sanity check: DL_FIXUP_VALUE_CODE_ADDR (value) should have been
|
||||||
|
- initialized earlier in this function or in another thread. */
|
||||||
|
- assert (DL_FIXUP_VALUE_CODE_ADDR (value) != 0);
|
||||||
|
- ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
|
||||||
|
- l_info[DT_SYMTAB])
|
||||||
|
- + reloc_result->boundndx);
|
||||||
|
-
|
||||||
|
- /* Set up the sym parameter. */
|
||||||
|
- ElfW(Sym) sym = *defsym;
|
||||||
|
- sym.st_value = DL_FIXUP_VALUE_ADDR (value);
|
||||||
|
-
|
||||||
|
- /* Get the symbol name. */
|
||||||
|
- const char *strtab = (const void *) D_PTR (reloc_result->bound,
|
||||||
|
- l_info[DT_STRTAB]);
|
||||||
|
- const char *symname = strtab + sym.st_name;
|
||||||
|
-
|
||||||
|
- /* Keep track of overwritten addresses. */
|
||||||
|
- unsigned int flags = reloc_result->flags;
|
||||||
|
-
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- if (afct->ARCH_LA_PLTENTER != NULL
|
||||||
|
- && (reloc_result->enterexit
|
||||||
|
- & (LA_SYMB_NOPLTENTER << (2 * (cnt + 1)))) == 0)
|
||||||
|
- {
|
||||||
|
- long int new_framesize = -1;
|
||||||
|
- struct auditstate *l_state = link_map_audit_state (l, cnt);
|
||||||
|
- struct auditstate *bound_state
|
||||||
|
- = link_map_audit_state (reloc_result->bound, cnt);
|
||||||
|
- uintptr_t new_value
|
||||||
|
- = afct->ARCH_LA_PLTENTER (&sym, reloc_result->boundndx,
|
||||||
|
- &l_state->cookie,
|
||||||
|
- &bound_state->cookie,
|
||||||
|
- regs, &flags, symname,
|
||||||
|
- &new_framesize);
|
||||||
|
- if (new_value != (uintptr_t) sym.st_value)
|
||||||
|
- {
|
||||||
|
- flags |= LA_SYMB_ALTVALUE;
|
||||||
|
- sym.st_value = new_value;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* Remember the results for every audit library and
|
||||||
|
- store a summary in the first two bits. */
|
||||||
|
- reloc_result->enterexit
|
||||||
|
- |= ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT))
|
||||||
|
- << (2 * (cnt + 1)));
|
||||||
|
-
|
||||||
|
- if ((reloc_result->enterexit & (LA_SYMB_NOPLTEXIT
|
||||||
|
- << (2 * (cnt + 1))))
|
||||||
|
- == 0 && new_framesize != -1 && framesize != -2)
|
||||||
|
- {
|
||||||
|
- /* If this is the first call providing information,
|
||||||
|
- use it. */
|
||||||
|
- if (framesize == -1)
|
||||||
|
- framesize = new_framesize;
|
||||||
|
- /* If two pltenter calls provide conflicting information,
|
||||||
|
- use the larger value. */
|
||||||
|
- else if (new_framesize != framesize)
|
||||||
|
- framesize = MAX (new_framesize, framesize);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- value = DL_FIXUP_ADDR_VALUE (sym.st_value);
|
||||||
|
- }
|
||||||
|
+ _dl_audit_pltenter (l, reloc_result, &value, regs, &framesize);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Store the frame size information. */
|
||||||
|
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||||
|
index 91193a036fc5c6ef..ea187dd266f14e06 100644
|
||||||
|
--- a/sysdeps/generic/ldsodefs.h
|
||||||
|
+++ b/sysdeps/generic/ldsodefs.h
|
||||||
|
@@ -1411,6 +1411,10 @@ void _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
|
||||||
|
void _dl_audit_symbind_alt (struct link_map *l, const ElfW(Sym) *ref,
|
||||||
|
void **value, lookup_t result);
|
||||||
|
rtld_hidden_proto (_dl_audit_symbind_alt)
|
||||||
|
+void _dl_audit_pltenter (struct link_map *l, struct reloc_result *reloc_result,
|
||||||
|
+ DL_FIXUP_VALUE_TYPE *value, void *regs,
|
||||||
|
+ long int *framesize)
|
||||||
|
+ attribute_hidden;
|
||||||
|
#endif /* SHARED */
|
||||||
|
|
||||||
|
#if PTHREAD_IN_LIBC && defined SHARED
|
715
glibc-upstream-2.34-149.patch
Normal file
715
glibc-upstream-2.34-149.patch
Normal file
@ -0,0 +1,715 @@
|
|||||||
|
commit a8e211daea6bdb505b10319ed3492e7d871c1e75
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Thu Jul 22 18:02:42 2021 -0300
|
||||||
|
|
||||||
|
elf: Add _dl_audit_pltexit
|
||||||
|
|
||||||
|
It consolidates the code required to call la_pltexit audit
|
||||||
|
callback.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
(cherry picked from commit 8c0664e2b861fd3789602cc0b0b1922b0e20cb3a)
|
||||||
|
|
||||||
|
Resolved conflicts:
|
||||||
|
sysdeps/hppa/dl-runtime.c
|
||||||
|
|
||||||
|
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
|
||||||
|
index 15250c67e8ac1658..152712b12fed6de2 100644
|
||||||
|
--- a/elf/dl-audit.c
|
||||||
|
+++ b/elf/dl-audit.c
|
||||||
|
@@ -20,6 +20,8 @@
|
||||||
|
#include <link.h>
|
||||||
|
#include <ldsodefs.h>
|
||||||
|
#include <dl-machine.h>
|
||||||
|
+#include <dl-runtime.h>
|
||||||
|
+#include <dl-fixup-attribute.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
_dl_audit_activity_map (struct link_map *l, int action)
|
||||||
|
@@ -320,3 +322,48 @@ _dl_audit_pltenter (struct link_map *l, struct reloc_result *reloc_result,
|
||||||
|
|
||||||
|
*value = DL_FIXUP_ADDR_VALUE (sym.st_value);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+DL_ARCH_FIXUP_ATTRIBUTE
|
||||||
|
+_dl_audit_pltexit (struct link_map *l, ElfW(Word) reloc_arg,
|
||||||
|
+ const void *inregs, void *outregs)
|
||||||
|
+{
|
||||||
|
+ const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]);
|
||||||
|
+
|
||||||
|
+ /* This is the address in the array where we store the result of previous
|
||||||
|
+ relocations. */
|
||||||
|
+ // XXX Maybe the bound information must be stored on the stack since
|
||||||
|
+ // XXX with bind_not a new value could have been stored in the meantime.
|
||||||
|
+ struct reloc_result *reloc_result =
|
||||||
|
+ &l->l_reloc_result[reloc_index (pltgot, reloc_arg, sizeof (PLTREL))];
|
||||||
|
+ ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
|
||||||
|
+ l_info[DT_SYMTAB])
|
||||||
|
+ + reloc_result->boundndx);
|
||||||
|
+
|
||||||
|
+ /* Set up the sym parameter. */
|
||||||
|
+ ElfW(Sym) sym = *defsym;
|
||||||
|
+ sym.st_value = DL_FIXUP_VALUE_ADDR (reloc_result->addr);
|
||||||
|
+
|
||||||
|
+ /* Get the symbol name. */
|
||||||
|
+ const char *strtab = (const void *) D_PTR (reloc_result->bound,
|
||||||
|
+ l_info[DT_STRTAB]);
|
||||||
|
+ const char *symname = strtab + sym.st_name;
|
||||||
|
+
|
||||||
|
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
+ {
|
||||||
|
+ if (afct->ARCH_LA_PLTEXIT != NULL
|
||||||
|
+ && (reloc_result->enterexit
|
||||||
|
+ & (LA_SYMB_NOPLTEXIT >> (2 * cnt))) == 0)
|
||||||
|
+ {
|
||||||
|
+ struct auditstate *l_state = link_map_audit_state (l, cnt);
|
||||||
|
+ struct auditstate *bound_state
|
||||||
|
+ = link_map_audit_state (reloc_result->bound, cnt);
|
||||||
|
+ afct->ARCH_LA_PLTEXIT (&sym, reloc_result->boundndx,
|
||||||
|
+ &l_state->cookie, &bound_state->cookie,
|
||||||
|
+ inregs, outregs, symname);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ afct = afct->next;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
|
||||||
|
index dfedeaf2dd1c7253..e42f6e8b8dfca08e 100644
|
||||||
|
--- a/elf/dl-runtime.c
|
||||||
|
+++ b/elf/dl-runtime.c
|
||||||
|
@@ -16,8 +16,6 @@
|
||||||
|
License along with the GNU C Library; if not, see
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
-#define IN_DL_RUNTIME 1 /* This can be tested in dl-machine.h. */
|
||||||
|
-
|
||||||
|
#include <alloca.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
@@ -31,19 +29,6 @@
|
||||||
|
#include <dl-runtime.h>
|
||||||
|
|
||||||
|
|
||||||
|
-#if (!ELF_MACHINE_NO_RELA && !defined ELF_MACHINE_PLT_REL) \
|
||||||
|
- || ELF_MACHINE_NO_REL
|
||||||
|
-# define PLTREL ElfW(Rela)
|
||||||
|
-#else
|
||||||
|
-# define PLTREL ElfW(Rel)
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
-/* The fixup functions might have need special attributes. If none
|
||||||
|
- are provided define the macro as empty. */
|
||||||
|
-#ifndef ARCH_FIXUP_ATTRIBUTE
|
||||||
|
-# define ARCH_FIXUP_ATTRIBUTE
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
/* This function is called through a special trampoline from the PLT the
|
||||||
|
first time each PLT entry is called. We must perform the relocation
|
||||||
|
specified in the PLT of the given shared object, and return the resolved
|
||||||
|
@@ -52,7 +37,7 @@
|
||||||
|
function. */
|
||||||
|
|
||||||
|
DL_FIXUP_VALUE_TYPE
|
||||||
|
-attribute_hidden __attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE
|
||||||
|
+attribute_hidden __attribute ((noinline)) DL_ARCH_FIXUP_ATTRIBUTE
|
||||||
|
_dl_fixup (
|
||||||
|
# ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
|
||||||
|
ELF_MACHINE_RUNTIME_FIXUP_ARGS,
|
||||||
|
@@ -148,7 +133,8 @@ _dl_fixup (
|
||||||
|
|
||||||
|
#ifndef PROF
|
||||||
|
DL_FIXUP_VALUE_TYPE
|
||||||
|
-__attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE
|
||||||
|
+__attribute ((noinline))
|
||||||
|
+DL_ARCH_FIXUP_ATTRIBUTE
|
||||||
|
_dl_profile_fixup (
|
||||||
|
#ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
|
||||||
|
ELF_MACHINE_RUNTIME_FIXUP_ARGS,
|
||||||
|
@@ -332,52 +318,3 @@ _dl_profile_fixup (
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* PROF */
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-#include <stdio.h>
|
||||||
|
-void
|
||||||
|
-ARCH_FIXUP_ATTRIBUTE
|
||||||
|
-_dl_call_pltexit (struct link_map *l, ElfW(Word) reloc_arg,
|
||||||
|
- const void *inregs, void *outregs)
|
||||||
|
-{
|
||||||
|
-#ifdef SHARED
|
||||||
|
- const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]);
|
||||||
|
-
|
||||||
|
- /* This is the address in the array where we store the result of previous
|
||||||
|
- relocations. */
|
||||||
|
- // XXX Maybe the bound information must be stored on the stack since
|
||||||
|
- // XXX with bind_not a new value could have been stored in the meantime.
|
||||||
|
- struct reloc_result *reloc_result =
|
||||||
|
- &l->l_reloc_result[reloc_index (pltgot, reloc_arg, sizeof (PLTREL))];
|
||||||
|
- ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
|
||||||
|
- l_info[DT_SYMTAB])
|
||||||
|
- + reloc_result->boundndx);
|
||||||
|
-
|
||||||
|
- /* Set up the sym parameter. */
|
||||||
|
- ElfW(Sym) sym = *defsym;
|
||||||
|
- sym.st_value = DL_FIXUP_VALUE_ADDR (reloc_result->addr);
|
||||||
|
-
|
||||||
|
- /* Get the symbol name. */
|
||||||
|
- const char *strtab = (const void *) D_PTR (reloc_result->bound,
|
||||||
|
- l_info[DT_STRTAB]);
|
||||||
|
- const char *symname = strtab + sym.st_name;
|
||||||
|
-
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- if (afct->ARCH_LA_PLTEXIT != NULL
|
||||||
|
- && (reloc_result->enterexit
|
||||||
|
- & (LA_SYMB_NOPLTEXIT >> (2 * cnt))) == 0)
|
||||||
|
- {
|
||||||
|
- struct auditstate *l_state = link_map_audit_state (l, cnt);
|
||||||
|
- struct auditstate *bound_state
|
||||||
|
- = link_map_audit_state (reloc_result->bound, cnt);
|
||||||
|
- afct->ARCH_LA_PLTEXIT (&sym, reloc_result->boundndx,
|
||||||
|
- &l_state->cookie, &bound_state->cookie,
|
||||||
|
- inregs, outregs, symname);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
-#endif
|
||||||
|
-}
|
||||||
|
diff --git a/elf/dl-support.c b/elf/dl-support.c
|
||||||
|
index c5ee5d33aa7e1d65..f29dc965f4d10648 100644
|
||||||
|
--- a/elf/dl-support.c
|
||||||
|
+++ b/elf/dl-support.c
|
||||||
|
@@ -437,3 +437,11 @@ _dl_get_dl_main_map (void)
|
||||||
|
return &_dl_main_map;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
+
|
||||||
|
+/* This is used by _dl_runtime_profile, not used on static code. */
|
||||||
|
+void
|
||||||
|
+DL_ARCH_FIXUP_ATTRIBUTE
|
||||||
|
+_dl_audit_pltexit (struct link_map *l, ElfW(Word) reloc_arg,
|
||||||
|
+ const void *inregs, void *outregs)
|
||||||
|
+{
|
||||||
|
+}
|
||||||
|
diff --git a/sysdeps/aarch64/dl-trampoline.S b/sysdeps/aarch64/dl-trampoline.S
|
||||||
|
index a7e9267c1c6a4863..9b352b1d0f7d62e7 100644
|
||||||
|
--- a/sysdeps/aarch64/dl-trampoline.S
|
||||||
|
+++ b/sysdeps/aarch64/dl-trampoline.S
|
||||||
|
@@ -293,7 +293,7 @@ _dl_runtime_profile:
|
||||||
|
ldp x0, x1, [x29, #OFFSET_SAVED_CALL_X0]
|
||||||
|
add x2, x29, #OFFSET_RG
|
||||||
|
add x3, x29, #OFFSET_RV
|
||||||
|
- bl _dl_call_pltexit
|
||||||
|
+ bl _dl_audit_pltexit
|
||||||
|
|
||||||
|
ldp x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0]
|
||||||
|
ldp d0, d1, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*0]
|
||||||
|
diff --git a/sysdeps/alpha/dl-trampoline.S b/sysdeps/alpha/dl-trampoline.S
|
||||||
|
index 9dfce5b0839dc122..55380d48ad8536ee 100644
|
||||||
|
--- a/sysdeps/alpha/dl-trampoline.S
|
||||||
|
+++ b/sysdeps/alpha/dl-trampoline.S
|
||||||
|
@@ -187,7 +187,7 @@ _dl_runtime_profile_new:
|
||||||
|
jsr $26, ($27), 0
|
||||||
|
ldgp $29, 0($26)
|
||||||
|
|
||||||
|
- /* Set up for call to _dl_call_pltexit. */
|
||||||
|
+ /* Set up for call to _dl_audit_pltexit. */
|
||||||
|
ldq $16, 16*8($15)
|
||||||
|
ldq $17, 17*8($15)
|
||||||
|
stq $0, 16*8($15)
|
||||||
|
@@ -196,7 +196,7 @@ _dl_runtime_profile_new:
|
||||||
|
lda $19, 16*8($15)
|
||||||
|
stt $f0, 18*8($15)
|
||||||
|
stt $f1, 19*8($15)
|
||||||
|
- bsr $26, _dl_call_pltexit !samegp
|
||||||
|
+ bsr $26, _dl_audit_pltexit !samegp
|
||||||
|
|
||||||
|
mov $15, $30
|
||||||
|
cfi_def_cfa_register (30)
|
||||||
|
@@ -518,7 +518,7 @@ _dl_runtime_profile_old:
|
||||||
|
jsr $26, ($27), 0
|
||||||
|
ldgp $29, 0($26)
|
||||||
|
|
||||||
|
- /* Set up for call to _dl_call_pltexit. */
|
||||||
|
+ /* Set up for call to _dl_audit_pltexit. */
|
||||||
|
ldq $16, 48*8($15)
|
||||||
|
ldq $17, 49*8($15)
|
||||||
|
stq $0, 46*8($15)
|
||||||
|
@@ -527,7 +527,7 @@ _dl_runtime_profile_old:
|
||||||
|
lda $19, 46*8($15)
|
||||||
|
stt $f0, 48*8($15)
|
||||||
|
stt $f1, 49*8($15)
|
||||||
|
- bsr $26, _dl_call_pltexit !samegp
|
||||||
|
+ bsr $26, _dl_audit_pltexit !samegp
|
||||||
|
|
||||||
|
mov $15, $30
|
||||||
|
cfi_def_cfa_register (30)
|
||||||
|
diff --git a/sysdeps/arm/dl-machine-rel.h b/sysdeps/arm/dl-machine-rel.h
|
||||||
|
index bec114706cd027a4..a9ee25a6b1d381ac 100644
|
||||||
|
--- a/sysdeps/arm/dl-machine-rel.h
|
||||||
|
+++ b/sysdeps/arm/dl-machine-rel.h
|
||||||
|
@@ -28,4 +28,6 @@
|
||||||
|
Prelinked libraries may use Elf32_Rela though. */
|
||||||
|
#define ELF_MACHINE_PLT_REL 1
|
||||||
|
|
||||||
|
+#define PLTREL ElfW(Rel)
|
||||||
|
+
|
||||||
|
#endif
|
||||||
|
diff --git a/sysdeps/arm/dl-trampoline.S b/sysdeps/arm/dl-trampoline.S
|
||||||
|
index 70105308ca7df934..a2d322706db77981 100644
|
||||||
|
--- a/sysdeps/arm/dl-trampoline.S
|
||||||
|
+++ b/sysdeps/arm/dl-trampoline.S
|
||||||
|
@@ -194,7 +194,7 @@ _dl_runtime_profile:
|
||||||
|
ldmia ip, {r0,r1}
|
||||||
|
add r2, r7, #72
|
||||||
|
add r3, r7, #0
|
||||||
|
- bl _dl_call_pltexit
|
||||||
|
+ bl _dl_audit_pltexit
|
||||||
|
|
||||||
|
@ Return to caller.
|
||||||
|
ldmia r7, {r0-r3}
|
||||||
|
diff --git a/sysdeps/generic/dl-fixup-attribute.h b/sysdeps/generic/dl-fixup-attribute.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..aa92169b709b3fea
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/sysdeps/generic/dl-fixup-attribute.h
|
||||||
|
@@ -0,0 +1,24 @@
|
||||||
|
+/* ABI specifics for lazy resolution functions.
|
||||||
|
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#ifndef _DL_FIXUP_ATTRIBUTE_H
|
||||||
|
+#define _DL_FIXUP_ATTRIBUTE_H
|
||||||
|
+
|
||||||
|
+#define DL_ARCH_FIXUP_ATTRIBUTE
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
diff --git a/sysdeps/generic/dl-machine-rel.h b/sysdeps/generic/dl-machine-rel.h
|
||||||
|
index 9167a1dffc715704..9d5b7bb749e69e63 100644
|
||||||
|
--- a/sysdeps/generic/dl-machine-rel.h
|
||||||
|
+++ b/sysdeps/generic/dl-machine-rel.h
|
||||||
|
@@ -23,5 +23,7 @@
|
||||||
|
#define ELF_MACHINE_NO_REL 1
|
||||||
|
/* Defined if the architecture supports Elf{32,64}_Rela relocations. */
|
||||||
|
#define ELF_MACHINE_NO_RELA 0
|
||||||
|
+/* Used to calculate the index of link_map l_reloc_result. */
|
||||||
|
+#define PLTREL ElfW(Rela)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||||
|
index ea187dd266f14e06..686f0a7b9709eb10 100644
|
||||||
|
--- a/sysdeps/generic/ldsodefs.h
|
||||||
|
+++ b/sysdeps/generic/ldsodefs.h
|
||||||
|
@@ -35,6 +35,7 @@
|
||||||
|
#include <link.h>
|
||||||
|
#include <dl-lookupcfg.h>
|
||||||
|
#include <dl-sysdep.h>
|
||||||
|
+#include <dl-fixup-attribute.h>
|
||||||
|
#include <libc-lock.h>
|
||||||
|
#include <hp-timing.h>
|
||||||
|
#include <tls.h>
|
||||||
|
@@ -1415,6 +1416,11 @@ void _dl_audit_pltenter (struct link_map *l, struct reloc_result *reloc_result,
|
||||||
|
DL_FIXUP_VALUE_TYPE *value, void *regs,
|
||||||
|
long int *framesize)
|
||||||
|
attribute_hidden;
|
||||||
|
+void DL_ARCH_FIXUP_ATTRIBUTE _dl_audit_pltexit (struct link_map *l,
|
||||||
|
+ ElfW(Word) reloc_arg,
|
||||||
|
+ const void *inregs,
|
||||||
|
+ void *outregs)
|
||||||
|
+ attribute_hidden;
|
||||||
|
#endif /* SHARED */
|
||||||
|
|
||||||
|
#if PTHREAD_IN_LIBC && defined SHARED
|
||||||
|
diff --git a/sysdeps/hppa/dl-runtime.c b/sysdeps/hppa/dl-runtime.c
|
||||||
|
index a71b5b2013abf723..8699171930f51489 100644
|
||||||
|
--- a/sysdeps/hppa/dl-runtime.c
|
||||||
|
+++ b/sysdeps/hppa/dl-runtime.c
|
||||||
|
@@ -25,7 +25,7 @@
|
||||||
|
return that to the caller. The caller will continue on to call
|
||||||
|
_dl_fixup with the relocation offset. */
|
||||||
|
|
||||||
|
-ElfW(Word) __attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE
|
||||||
|
+ElfW(Word) __attribute ((noinline)) DL_ARCH_FIXUP_ATTRIBUTE
|
||||||
|
_dl_fix_reloc_arg (struct fdesc *fptr, struct link_map *l)
|
||||||
|
{
|
||||||
|
Elf32_Addr l_addr, iplt, jmprel, end_jmprel, r_type;
|
||||||
|
diff --git a/sysdeps/hppa/dl-trampoline.S b/sysdeps/hppa/dl-trampoline.S
|
||||||
|
index cb18ea7eabba41ed..c54879bae0148012 100644
|
||||||
|
--- a/sysdeps/hppa/dl-trampoline.S
|
||||||
|
+++ b/sysdeps/hppa/dl-trampoline.S
|
||||||
|
@@ -300,7 +300,7 @@ L(cont):
|
||||||
|
ldw -4(%sp),%r1
|
||||||
|
copy %r1, %sp
|
||||||
|
|
||||||
|
- /* Arguments to _dl_call_pltexit */
|
||||||
|
+ /* Arguments to _dl_audit_pltexit */
|
||||||
|
ldw -116(%sp), %r26 /* (1) got[1] == struct link_map */
|
||||||
|
ldw -120(%sp), %r25 /* (2) reloc offsets */
|
||||||
|
ldo -56(%sp), %r24 /* (3) *La_hppa_regs */
|
||||||
|
@@ -312,8 +312,8 @@ L(cont):
|
||||||
|
ldo -128(%sp), %r1
|
||||||
|
fstd %fr4,0(%r1)
|
||||||
|
|
||||||
|
- /* Call _dl_call_pltexit */
|
||||||
|
- bl _dl_call_pltexit,%rp
|
||||||
|
+ /* Call _dl_audit_pltexit */
|
||||||
|
+ bl _dl_audit_pltexit,%rp
|
||||||
|
nop
|
||||||
|
|
||||||
|
/* Restore *La_hppa_retval */
|
||||||
|
diff --git a/sysdeps/i386/dl-fixup-attribute.h b/sysdeps/i386/dl-fixup-attribute.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..c10e9936f4db7254
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/sysdeps/i386/dl-fixup-attribute.h
|
||||||
|
@@ -0,0 +1,30 @@
|
||||||
|
+/* ABI specifics for lazy resolution functions. i386 version.
|
||||||
|
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#ifndef _DL_FIXUP_ATTRIBUTE_H
|
||||||
|
+#define _DL_FIXUP_ATTRIBUTE_H
|
||||||
|
+
|
||||||
|
+/* We cannot use this scheme for profiling because the _mcount call destroys
|
||||||
|
+ the passed register information. */
|
||||||
|
+#ifndef PROF
|
||||||
|
+# define DL_ARCH_FIXUP_ATTRIBUTE __attribute__ ((regparm (3), stdcall, unused))
|
||||||
|
+#else
|
||||||
|
+# define DL_ARCH_FIXUP_ATTRIBUTE
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
diff --git a/sysdeps/i386/dl-machine-rel.h b/sysdeps/i386/dl-machine-rel.h
|
||||||
|
index 7ac46f78a69fbf98..bb3480d45415d761 100644
|
||||||
|
--- a/sysdeps/i386/dl-machine-rel.h
|
||||||
|
+++ b/sysdeps/i386/dl-machine-rel.h
|
||||||
|
@@ -28,4 +28,6 @@
|
||||||
|
Prelinked libraries may use Elf32_Rela though. */
|
||||||
|
#define ELF_MACHINE_PLT_REL 1
|
||||||
|
|
||||||
|
+#define PLTREL ElfW(Rel)
|
||||||
|
+
|
||||||
|
#endif
|
||||||
|
diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h
|
||||||
|
index c55c9a3d64bed1f2..5483e903d81e85c6 100644
|
||||||
|
--- a/sysdeps/i386/dl-machine.h
|
||||||
|
+++ b/sysdeps/i386/dl-machine.h
|
||||||
|
@@ -122,29 +122,6 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
|
||||||
|
return lazy;
|
||||||
|
}
|
||||||
|
|
||||||
|
-#ifdef IN_DL_RUNTIME
|
||||||
|
-
|
||||||
|
-# ifndef PROF
|
||||||
|
-/* We add a declaration of this function here so that in dl-runtime.c
|
||||||
|
- the ELF_MACHINE_RUNTIME_TRAMPOLINE macro really can pass the parameters
|
||||||
|
- in registers.
|
||||||
|
-
|
||||||
|
- We cannot use this scheme for profiling because the _mcount call
|
||||||
|
- destroys the passed register information. */
|
||||||
|
-#define ARCH_FIXUP_ATTRIBUTE __attribute__ ((regparm (3), stdcall, unused))
|
||||||
|
-
|
||||||
|
-extern ElfW(Addr) _dl_fixup (struct link_map *l,
|
||||||
|
- ElfW(Word) reloc_offset)
|
||||||
|
- ARCH_FIXUP_ATTRIBUTE;
|
||||||
|
-extern ElfW(Addr) _dl_profile_fixup (struct link_map *l,
|
||||||
|
- ElfW(Word) reloc_offset,
|
||||||
|
- ElfW(Addr) retaddr, void *regs,
|
||||||
|
- long int *framesizep)
|
||||||
|
- ARCH_FIXUP_ATTRIBUTE;
|
||||||
|
-# endif
|
||||||
|
-
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
/* Mask identifying addresses reserved for the user program,
|
||||||
|
where the dynamic linker should not map anything. */
|
||||||
|
#define ELF_MACHINE_USER_ADDRESS_MASK 0xf0000000UL
|
||||||
|
diff --git a/sysdeps/i386/dl-trampoline.S b/sysdeps/i386/dl-trampoline.S
|
||||||
|
index b5ec0326df94f0fd..3a33051c52da9cde 100644
|
||||||
|
--- a/sysdeps/i386/dl-trampoline.S
|
||||||
|
+++ b/sysdeps/i386/dl-trampoline.S
|
||||||
|
@@ -265,7 +265,7 @@ _dl_runtime_profile:
|
||||||
|
movl (LRV_SIZE + 4 + LR_SIZE)(%esp), %eax
|
||||||
|
# PLT1
|
||||||
|
movl (LRV_SIZE + 4 + LR_SIZE + 4)(%esp), %edx
|
||||||
|
- call _dl_call_pltexit
|
||||||
|
+ call _dl_audit_pltexit
|
||||||
|
movl LRV_EAX_OFFSET(%esp), %eax
|
||||||
|
movl LRV_EDX_OFFSET(%esp), %edx
|
||||||
|
fldt LRV_ST1_OFFSET(%esp)
|
||||||
|
diff --git a/sysdeps/ia64/dl-trampoline.S b/sysdeps/ia64/dl-trampoline.S
|
||||||
|
index 3053405a3a21d62e..11e86932c75d5b6b 100644
|
||||||
|
--- a/sysdeps/ia64/dl-trampoline.S
|
||||||
|
+++ b/sysdeps/ia64/dl-trampoline.S
|
||||||
|
@@ -133,7 +133,7 @@ END(_dl_runtime_resolve)
|
||||||
|
|
||||||
|
|
||||||
|
/* The fourth argument to _dl_profile_fixup and the third one to
|
||||||
|
- _dl_call_pltexit are a pointer to La_ia64_regs:
|
||||||
|
+ _dl_audit_pltexit are a pointer to La_ia64_regs:
|
||||||
|
|
||||||
|
8byte r8
|
||||||
|
8byte r9
|
||||||
|
@@ -159,7 +159,7 @@ END(_dl_runtime_resolve)
|
||||||
|
8byte sp
|
||||||
|
|
||||||
|
The fifth argument to _dl_profile_fixup is a pointer to long int.
|
||||||
|
- The fourth argument to _dl_call_pltexit is a pointer to
|
||||||
|
+ The fourth argument to _dl_audit_pltexit is a pointer to
|
||||||
|
La_ia64_retval:
|
||||||
|
|
||||||
|
8byte r8
|
||||||
|
@@ -261,7 +261,7 @@ ENTRY(_dl_runtime_profile)
|
||||||
|
}
|
||||||
|
{ .mii
|
||||||
|
mov r18 = ar.unat /* save it in La_ia64_regs */
|
||||||
|
- mov loc7 = out3 /* save it for _dl_call_pltexit */
|
||||||
|
+ mov loc7 = out3 /* save it for _dl_audit_pltexit */
|
||||||
|
mov loc5 = r11 /* preserve language specific register */
|
||||||
|
}
|
||||||
|
{ .mmi
|
||||||
|
@@ -272,7 +272,7 @@ ENTRY(_dl_runtime_profile)
|
||||||
|
}
|
||||||
|
{ .mii
|
||||||
|
mov ar.unat = r17 /* restore it for function call */
|
||||||
|
- mov loc8 = r16 /* save it for _dl_call_pltexit */
|
||||||
|
+ mov loc8 = r16 /* save it for _dl_audit_pltexit */
|
||||||
|
nop.i 0x0
|
||||||
|
}
|
||||||
|
{ .mmi
|
||||||
|
@@ -291,7 +291,7 @@ ENTRY(_dl_runtime_profile)
|
||||||
|
{ .mmi
|
||||||
|
stf.spill [r2] = f14, 32
|
||||||
|
stf.spill [r3] = f15, 24
|
||||||
|
- mov loc9 = out1 /* save it for _dl_call_pltexit */
|
||||||
|
+ mov loc9 = out1 /* save it for _dl_audit_pltexit */
|
||||||
|
;;
|
||||||
|
}
|
||||||
|
{ .mmb
|
||||||
|
@@ -426,7 +426,7 @@ ENTRY(_dl_runtime_profile)
|
||||||
|
br.call.sptk.many b0 = b6
|
||||||
|
}
|
||||||
|
{ .mii
|
||||||
|
- /* Prepare stack for _dl_call_pltexit. Loc10 has the original
|
||||||
|
+ /* Prepare stack for _dl_audit_pltexit. Loc10 has the original
|
||||||
|
stack pointer. */
|
||||||
|
adds r12 = -PLTEXIT_FRAME_SIZE, loc10
|
||||||
|
adds r2 = -(PLTEXIT_FRAME_SIZE - 16), loc10
|
||||||
|
@@ -461,14 +461,14 @@ ENTRY(_dl_runtime_profile)
|
||||||
|
{ .mmi
|
||||||
|
stf.spill [r2] = f12, 32
|
||||||
|
stf.spill [r3] = f13, 32
|
||||||
|
- /* We need to restore gp for _dl_call_pltexit. */
|
||||||
|
+ /* We need to restore gp for _dl_audit_pltexit. */
|
||||||
|
mov gp = loc11
|
||||||
|
;;
|
||||||
|
}
|
||||||
|
{ .mmb
|
||||||
|
stf.spill [r2] = f14
|
||||||
|
stf.spill [r3] = f15
|
||||||
|
- br.call.sptk.many b0 = _dl_call_pltexit
|
||||||
|
+ br.call.sptk.many b0 = _dl_audit_pltexit
|
||||||
|
}
|
||||||
|
{ .mmi
|
||||||
|
/* Load all the non-floating and floating return values. Skip
|
||||||
|
diff --git a/sysdeps/m68k/dl-trampoline.S b/sysdeps/m68k/dl-trampoline.S
|
||||||
|
index a51a5f7f573c6330..72bde664c31c4256 100644
|
||||||
|
--- a/sysdeps/m68k/dl-trampoline.S
|
||||||
|
+++ b/sysdeps/m68k/dl-trampoline.S
|
||||||
|
@@ -202,7 +202,7 @@ _dl_runtime_profile:
|
||||||
|
cfi_adjust_cfa_offset (4)
|
||||||
|
move.l (32+FPSPACE)(%sp), -(%sp)
|
||||||
|
cfi_adjust_cfa_offset (4)
|
||||||
|
- jbsr _dl_call_pltexit
|
||||||
|
+ jbsr _dl_audit_pltexit
|
||||||
|
lea 16(%sp), %sp
|
||||||
|
cfi_adjust_cfa_offset (-16)
|
||||||
|
move.l (%sp)+, %d0
|
||||||
|
diff --git a/sysdeps/mips/dl-machine-rel.h b/sysdeps/mips/dl-machine-rel.h
|
||||||
|
index ed396180412bc723..3d0dfec01f6b193e 100644
|
||||||
|
--- a/sysdeps/mips/dl-machine-rel.h
|
||||||
|
+++ b/sysdeps/mips/dl-machine-rel.h
|
||||||
|
@@ -22,5 +22,6 @@
|
||||||
|
#define ELF_MACHINE_PLT_REL 1
|
||||||
|
#define ELF_MACHINE_NO_REL 0
|
||||||
|
#define ELF_MACHINE_NO_RELA 0
|
||||||
|
+#define PLTREL ElfW(Rel)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/dl-trampoline.S b/sysdeps/powerpc/powerpc64/dl-trampoline.S
|
||||||
|
index 61bd8571fcc93caa..97f0105ce780514e 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/dl-trampoline.S
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/dl-trampoline.S
|
||||||
|
@@ -197,7 +197,7 @@ END(_dl_runtime_resolve)
|
||||||
|
#ifndef PROF
|
||||||
|
ENTRY (_dl_profile_resolve, 4)
|
||||||
|
/* Spill r30, r31 to preserve the link_map* and reloc_addr, in case we
|
||||||
|
- need to call _dl_call_pltexit. */
|
||||||
|
+ need to call _dl_audit_pltexit. */
|
||||||
|
std r31,-8(r1)
|
||||||
|
std r30,-16(r1)
|
||||||
|
/* We need to save the registers used to pass parameters, ie. r3 thru
|
||||||
|
@@ -452,7 +452,7 @@ L(restoreFXR2):
|
||||||
|
L(callpltexit):
|
||||||
|
addi r5,r1,INT_PARMS
|
||||||
|
addi r6,r1,INT_RTN
|
||||||
|
- bl JUMPTARGET(_dl_call_pltexit)
|
||||||
|
+ bl JUMPTARGET(_dl_audit_pltexit)
|
||||||
|
#ifndef SHARED
|
||||||
|
nop
|
||||||
|
#endif
|
||||||
|
diff --git a/sysdeps/s390/s390-32/dl-trampoline.h b/sysdeps/s390/s390-32/dl-trampoline.h
|
||||||
|
index c224a2b92832af9b..9e4cd1055fe6ab20 100644
|
||||||
|
--- a/sysdeps/s390/s390-32/dl-trampoline.h
|
||||||
|
+++ b/sysdeps/s390/s390-32/dl-trampoline.h
|
||||||
|
@@ -282,7 +282,7 @@ _dl_runtime_profile:
|
||||||
|
basr %r1,0
|
||||||
|
5: l %r14,7f-5b(%r1)
|
||||||
|
la %r5,CFA_OFF+RETVAL_OFF(%r12) # struct La_s390_32_retval *
|
||||||
|
- bas %r14,0(%r14,%r1) # call _dl_call_pltexit
|
||||||
|
+ bas %r14,0(%r14,%r1) # call _dl_audit_pltexit
|
||||||
|
|
||||||
|
lr %r15,%r12 # remove stack frame
|
||||||
|
# undef FRAME_SIZE
|
||||||
|
@@ -301,7 +301,7 @@ _dl_runtime_profile:
|
||||||
|
br %r14
|
||||||
|
|
||||||
|
6: .long _dl_profile_fixup - 0b
|
||||||
|
-7: .long _dl_call_pltexit - 5b
|
||||||
|
+7: .long _dl_audit_pltexit - 5b
|
||||||
|
cfi_endproc
|
||||||
|
.size _dl_runtime_profile, .-_dl_runtime_profile
|
||||||
|
# undef SIZEOF_STRUCT_LA_S390_32_REGS
|
||||||
|
diff --git a/sysdeps/s390/s390-64/dl-trampoline.h b/sysdeps/s390/s390-64/dl-trampoline.h
|
||||||
|
index ae741a3bad5ec77e..6e5bad40459ec765 100644
|
||||||
|
--- a/sysdeps/s390/s390-64/dl-trampoline.h
|
||||||
|
+++ b/sysdeps/s390/s390-64/dl-trampoline.h
|
||||||
|
@@ -284,7 +284,7 @@ _dl_runtime_profile:
|
||||||
|
lmg %r2,%r4,CFA_OFF+PLT1_OFF(%r12) # r2, r3: args saved by PLT
|
||||||
|
# r4: struct La_s390_64_regs *
|
||||||
|
la %r5,CFA_OFF+RETVAL_OFF(%r12) # struct La_s390_64_retval *
|
||||||
|
- brasl %r14,_dl_call_pltexit
|
||||||
|
+ brasl %r14,_dl_audit_pltexit
|
||||||
|
|
||||||
|
lgr %r15,%r12 # remove stack frame
|
||||||
|
# undef FRAME_SIZE
|
||||||
|
diff --git a/sysdeps/sh/dl-trampoline.S b/sysdeps/sh/dl-trampoline.S
|
||||||
|
index 824ac84ba1830ce5..f9038cd10ed5286f 100644
|
||||||
|
--- a/sysdeps/sh/dl-trampoline.S
|
||||||
|
+++ b/sysdeps/sh/dl-trampoline.S
|
||||||
|
@@ -423,8 +423,8 @@ _dl_runtime_profile:
|
||||||
|
.align 2
|
||||||
|
#ifdef SHARED
|
||||||
|
7: .long _GLOBAL_OFFSET_TABLE_
|
||||||
|
-8: .long _dl_call_pltexit@GOTOFF
|
||||||
|
+8: .long _dl_audit_pltexit@GOTOFF
|
||||||
|
#else
|
||||||
|
-8: .long _dl_call_pltexit
|
||||||
|
+8: .long _dl_audit_pltexit
|
||||||
|
#endif
|
||||||
|
.size _dl_runtime_profile, .-_dl_runtime_profile
|
||||||
|
diff --git a/sysdeps/sparc/sparc32/dl-trampoline.S b/sysdeps/sparc/sparc32/dl-trampoline.S
|
||||||
|
index 426f90c99a7ed369..2f64809731c865a2 100644
|
||||||
|
--- a/sysdeps/sparc/sparc32/dl-trampoline.S
|
||||||
|
+++ b/sysdeps/sparc/sparc32/dl-trampoline.S
|
||||||
|
@@ -127,7 +127,7 @@ _dl_profile_invoke:
|
||||||
|
mov %l5, %o0
|
||||||
|
mov %l6, %o1
|
||||||
|
add %sp, (11 * 8), %o2
|
||||||
|
- call _dl_call_pltexit
|
||||||
|
+ call _dl_audit_pltexit
|
||||||
|
add %sp, ( 9 * 8), %o3
|
||||||
|
|
||||||
|
ldd [%sp + ( 9 * 8)], %i0
|
||||||
|
diff --git a/sysdeps/sparc/sparc64/dl-trampoline.S b/sysdeps/sparc/sparc64/dl-trampoline.S
|
||||||
|
index 8d59fa67209cd8ab..86605e37acd929fd 100644
|
||||||
|
--- a/sysdeps/sparc/sparc64/dl-trampoline.S
|
||||||
|
+++ b/sysdeps/sparc/sparc64/dl-trampoline.S
|
||||||
|
@@ -196,7 +196,7 @@ _dl_profile_invoke:
|
||||||
|
mov %l5, %o0
|
||||||
|
mov %l6, %o1
|
||||||
|
add %sp, STACK_BIAS + (24 * 8), %o2
|
||||||
|
- call _dl_call_pltexit
|
||||||
|
+ call _dl_audit_pltexit
|
||||||
|
add %sp, STACK_BIAS + (16 * 8), %o3
|
||||||
|
|
||||||
|
ldx [%sp + STACK_BIAS + (16 * 8)], %i0
|
||||||
|
diff --git a/sysdeps/x86_64/dl-runtime.h b/sysdeps/x86_64/dl-runtime.h
|
||||||
|
index 9c8d3977eee27069..19ba33ef30970c20 100644
|
||||||
|
--- a/sysdeps/x86_64/dl-runtime.h
|
||||||
|
+++ b/sysdeps/x86_64/dl-runtime.h
|
||||||
|
@@ -18,7 +18,7 @@
|
||||||
|
02111-1307 USA. */
|
||||||
|
|
||||||
|
/* The ABI calls for the PLT stubs to pass the index of the relocation
|
||||||
|
- and not its offset. In _dl_profile_fixup and _dl_call_pltexit we
|
||||||
|
+ and not its offset. In _dl_profile_fixup and _dl_audit_pltexit we
|
||||||
|
also use the index. Therefore it is wasteful to compute the offset
|
||||||
|
in the trampoline just to reverse the operation immediately
|
||||||
|
afterwards. */
|
||||||
|
diff --git a/sysdeps/x86_64/dl-trampoline.h b/sysdeps/x86_64/dl-trampoline.h
|
||||||
|
index b9a12970cd6206ee..b5de7efff778559e 100644
|
||||||
|
--- a/sysdeps/x86_64/dl-trampoline.h
|
||||||
|
+++ b/sysdeps/x86_64/dl-trampoline.h
|
||||||
|
@@ -388,7 +388,7 @@ _dl_runtime_profile:
|
||||||
|
jns 3f
|
||||||
|
|
||||||
|
/* There's nothing in the frame size, so there
|
||||||
|
- will be no call to the _dl_call_pltexit. */
|
||||||
|
+ will be no call to the _dl_audit_pltexit. */
|
||||||
|
|
||||||
|
/* Get back registers content. */
|
||||||
|
movq LR_RCX_OFFSET(%rsp), %rcx
|
||||||
|
@@ -436,7 +436,7 @@ _dl_runtime_profile:
|
||||||
|
mov 24(%rbx), %RSP_LP # Drop the copied stack content
|
||||||
|
|
||||||
|
/* Now we have to prepare the La_x86_64_retval structure for the
|
||||||
|
- _dl_call_pltexit. The La_x86_64_regs is being pointed by rsp now,
|
||||||
|
+ _dl_audit_pltexit. The La_x86_64_regs is being pointed by rsp now,
|
||||||
|
so we just need to allocate the sizeof(La_x86_64_retval) space on
|
||||||
|
the stack, since the alignment has already been taken care of. */
|
||||||
|
# ifdef RESTORE_AVX
|
||||||
|
@@ -491,7 +491,7 @@ _dl_runtime_profile:
|
||||||
|
movq 24(%rbx), %rdx # La_x86_64_regs argument to %rdx.
|
||||||
|
movq 40(%rbx), %rsi # Copy args pushed by PLT in register.
|
||||||
|
movq 32(%rbx), %rdi # %rdi: link_map, %rsi: reloc_index
|
||||||
|
- call _dl_call_pltexit
|
||||||
|
+ call _dl_audit_pltexit
|
||||||
|
|
||||||
|
/* Restore return registers. */
|
||||||
|
movq LRV_RAX_OFFSET(%rsp), %rax
|
454
glibc-upstream-2.34-150.patch
Normal file
454
glibc-upstream-2.34-150.patch
Normal file
@ -0,0 +1,454 @@
|
|||||||
|
commit 29496b3103ff13aa3c1d8b62552a98f39da0fe59
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Wed Jun 30 10:24:09 2021 -0300
|
||||||
|
|
||||||
|
elf: Avoid unnecessary slowdown from profiling with audit (BZ#15533)
|
||||||
|
|
||||||
|
The rtld-audit interfaces introduces a slowdown due to enabling
|
||||||
|
profiling instrumentation (as if LD_AUDIT implied LD_PROFILE).
|
||||||
|
However, instrumenting is only necessary if one of audit libraries
|
||||||
|
provides PLT callbacks (la_pltenter or la_pltexit symbols). Otherwise,
|
||||||
|
the slowdown can be avoided.
|
||||||
|
|
||||||
|
The following patch adjusts the logic that enables profiling to iterate
|
||||||
|
over all audit modules and check if any of those provides a PLT hook.
|
||||||
|
To keep la_symbind to work even without PLT callbacks, _dl_fixup now
|
||||||
|
calls the audit callback if the modules implements it.
|
||||||
|
|
||||||
|
Co-authored-by: Alexander Monakov <amonakov@ispras.ru>
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
(cherry picked from commit 063f9ba220f434c7f30dd65c4cff17c0c458a7cf)
|
||||||
|
|
||||||
|
Resolved conflicts:
|
||||||
|
NEWS
|
||||||
|
elf/Makefile
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index 85165c0591412a45..eab9d46b6165e6be 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -365,6 +365,7 @@ tests += \
|
||||||
|
tst-audit16 \
|
||||||
|
tst-audit17 \
|
||||||
|
tst-audit18 \
|
||||||
|
+ tst-audit19b \
|
||||||
|
tst-auditmany \
|
||||||
|
tst-auxobj \
|
||||||
|
tst-auxobj-dlopen \
|
||||||
|
@@ -454,6 +455,7 @@ tests-internal += \
|
||||||
|
neededtest2 \
|
||||||
|
neededtest3 \
|
||||||
|
neededtest4 \
|
||||||
|
+ tst-audit19a \
|
||||||
|
tst-create_format1 \
|
||||||
|
tst-dl-hwcaps_split \
|
||||||
|
tst-dlmopen2 \
|
||||||
|
@@ -626,6 +628,7 @@ modules-names = \
|
||||||
|
tst-audit12mod3 \
|
||||||
|
tst-audit13mod1 \
|
||||||
|
tst-audit18mod \
|
||||||
|
+ tst-audit19bmod \
|
||||||
|
tst-auditlogmod-1 \
|
||||||
|
tst-auditlogmod-2 \
|
||||||
|
tst-auditlogmod-3 \
|
||||||
|
@@ -644,6 +647,8 @@ modules-names = \
|
||||||
|
tst-auditmod11 \
|
||||||
|
tst-auditmod12 \
|
||||||
|
tst-auditmod18 \
|
||||||
|
+ tst-auditmod19a \
|
||||||
|
+ tst-auditmod19b \
|
||||||
|
tst-auxvalmod \
|
||||||
|
tst-big-note-lib \
|
||||||
|
tst-deep1mod1 \
|
||||||
|
@@ -2007,6 +2012,13 @@ $(objpfx)tst-audit18.out: $(objpfx)tst-auditmod18.so \
|
||||||
|
$(objpfx)tst-audit18mod.so
|
||||||
|
tst-audit18-ARGS = -- $(host-test-program-cmd)
|
||||||
|
|
||||||
|
+$(objpfx)tst-audit19a.out: $(objpfx)tst-auditmod19a.so
|
||||||
|
+tst-audit19a-ENV = LD_AUDIT=$(objpfx)tst-auditmod19a.so
|
||||||
|
+
|
||||||
|
+$(objpfx)tst-audit19b.out: $(objpfx)tst-auditmod19b.so
|
||||||
|
+$(objpfx)tst-audit19b: $(objpfx)tst-audit19bmod.so
|
||||||
|
+tst-audit19b-ARGS = -- $(host-test-program-cmd)
|
||||||
|
+
|
||||||
|
# tst-sonamemove links against an older implementation of the library.
|
||||||
|
LDFLAGS-tst-sonamemove-linkmod1.so = \
|
||||||
|
-Wl,--version-script=tst-sonamemove-linkmod1.map \
|
||||||
|
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
|
||||||
|
index 3447de7f3536cd70..5b69321bda1f2b27 100644
|
||||||
|
--- a/elf/dl-reloc.c
|
||||||
|
+++ b/elf/dl-reloc.c
|
||||||
|
@@ -205,12 +205,28 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
|
||||||
|
int skip_ifunc = reloc_mode & __RTLD_NOIFUNC;
|
||||||
|
|
||||||
|
#ifdef SHARED
|
||||||
|
+ bool consider_symbind = false;
|
||||||
|
/* If we are auditing, install the same handlers we need for profiling. */
|
||||||
|
if ((reloc_mode & __RTLD_AUDIT) == 0)
|
||||||
|
- consider_profiling |= GLRO(dl_audit) != NULL;
|
||||||
|
+ {
|
||||||
|
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
+ {
|
||||||
|
+ /* Profiling is needed only if PLT hooks are provided. */
|
||||||
|
+ if (afct->ARCH_LA_PLTENTER != NULL
|
||||||
|
+ || afct->ARCH_LA_PLTEXIT != NULL)
|
||||||
|
+ consider_profiling = 1;
|
||||||
|
+ if (afct->symbind != NULL)
|
||||||
|
+ consider_symbind = true;
|
||||||
|
+
|
||||||
|
+ afct = afct->next;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
#elif defined PROF
|
||||||
|
/* Never use dynamic linker profiling for gprof profiling code. */
|
||||||
|
# define consider_profiling 0
|
||||||
|
+#else
|
||||||
|
+# define consider_symbind 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (l->l_relocated)
|
||||||
|
@@ -272,7 +288,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
|
||||||
|
ELF_DYNAMIC_RELOCATE (l, scope, lazy, consider_profiling, skip_ifunc);
|
||||||
|
|
||||||
|
#ifndef PROF
|
||||||
|
- if (__glibc_unlikely (consider_profiling)
|
||||||
|
+ if ((consider_profiling || consider_symbind)
|
||||||
|
&& l->l_info[DT_PLTRELSZ] != NULL)
|
||||||
|
{
|
||||||
|
/* Allocate the array which will contain the already found
|
||||||
|
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
|
||||||
|
index e42f6e8b8dfca08e..77a5cccdcbcb9293 100644
|
||||||
|
--- a/elf/dl-runtime.c
|
||||||
|
+++ b/elf/dl-runtime.c
|
||||||
|
@@ -124,6 +124,37 @@ _dl_fixup (
|
||||||
|
&& __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0))
|
||||||
|
value = elf_ifunc_invoke (DL_FIXUP_VALUE_ADDR (value));
|
||||||
|
|
||||||
|
+#ifdef SHARED
|
||||||
|
+ /* Auditing checkpoint: we have a new binding. Provide the auditing
|
||||||
|
+ libraries the possibility to change the value and tell us whether further
|
||||||
|
+ auditing is wanted.
|
||||||
|
+ The l_reloc_result is only allocated if there is an audit module which
|
||||||
|
+ provides a la_symbind. */
|
||||||
|
+ if (l->l_reloc_result != NULL)
|
||||||
|
+ {
|
||||||
|
+ /* This is the address in the array where we store the result of previous
|
||||||
|
+ relocations. */
|
||||||
|
+ struct reloc_result *reloc_result
|
||||||
|
+ = &l->l_reloc_result[reloc_index (pltgot, reloc_arg, sizeof (PLTREL))];
|
||||||
|
+ unsigned int init = atomic_load_acquire (&reloc_result->init);
|
||||||
|
+ if (init == 0)
|
||||||
|
+ {
|
||||||
|
+ _dl_audit_symbind (l, reloc_result, sym, &value, result);
|
||||||
|
+
|
||||||
|
+ /* Store the result for later runs. */
|
||||||
|
+ if (__glibc_likely (! GLRO(dl_bind_not)))
|
||||||
|
+ {
|
||||||
|
+ reloc_result->addr = value;
|
||||||
|
+ /* Guarantee all previous writes complete before init is
|
||||||
|
+ updated. See CONCURRENCY NOTES below. */
|
||||||
|
+ atomic_store_release (&reloc_result->init, 1);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ value = reloc_result->addr;
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/* Finally, fix up the plt itself. */
|
||||||
|
if (__glibc_unlikely (GLRO(dl_bind_not)))
|
||||||
|
return value;
|
||||||
|
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||||
|
index b6bb46ca97b7972f..f632a767d7a269ef 100644
|
||||||
|
--- a/elf/rtld.c
|
||||||
|
+++ b/elf/rtld.c
|
||||||
|
@@ -1016,13 +1016,7 @@ ERROR: audit interface '%s' requires version %d (maximum supported version %d);
|
||||||
|
"la_objsearch\0"
|
||||||
|
"la_objopen\0"
|
||||||
|
"la_preinit\0"
|
||||||
|
-#if __ELF_NATIVE_CLASS == 32
|
||||||
|
- "la_symbind32\0"
|
||||||
|
-#elif __ELF_NATIVE_CLASS == 64
|
||||||
|
- "la_symbind64\0"
|
||||||
|
-#else
|
||||||
|
-# error "__ELF_NATIVE_CLASS must be defined"
|
||||||
|
-#endif
|
||||||
|
+ LA_SYMBIND "\0"
|
||||||
|
#define STRING(s) __STRING (s)
|
||||||
|
"la_" STRING (ARCH_LA_PLTENTER) "\0"
|
||||||
|
"la_" STRING (ARCH_LA_PLTEXIT) "\0"
|
||||||
|
diff --git a/elf/tst-audit19a.c b/elf/tst-audit19a.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..035cde9351c2711b
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit19a.c
|
||||||
|
@@ -0,0 +1,38 @@
|
||||||
|
+/* Check if DT_AUDIT a module without la_plt{enter,exit} symbols does not incur
|
||||||
|
+ in profiling (BZ#15533).
|
||||||
|
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <link.h>
|
||||||
|
+#include <support/xdlfcn.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ void *h = xdlopen ("tst-auditmod19a.so", RTLD_NOW);
|
||||||
|
+
|
||||||
|
+ struct link_map *lmap;
|
||||||
|
+ TEST_VERIFY_EXIT (dlinfo (h, RTLD_DI_LINKMAP, &lmap) == 0);
|
||||||
|
+
|
||||||
|
+ /* The internal array is only allocated if profiling is enabled. */
|
||||||
|
+ TEST_VERIFY (lmap->l_reloc_result == NULL);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/elf/tst-audit19b.c b/elf/tst-audit19b.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..da015734f24e0d79
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit19b.c
|
||||||
|
@@ -0,0 +1,94 @@
|
||||||
|
+/* Check if DT_AUDIT a module with la_plt{enter,exit} call la_symbind
|
||||||
|
+ for lazy resolution.
|
||||||
|
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <getopt.h>
|
||||||
|
+#include <support/capture_subprocess.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/xstdio.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <stdbool.h>
|
||||||
|
+
|
||||||
|
+static int restart;
|
||||||
|
+#define CMDLINE_OPTIONS \
|
||||||
|
+ { "restart", no_argument, &restart, 1 },
|
||||||
|
+
|
||||||
|
+int tst_audit18bmod1_func (void);
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+handle_restart (void)
|
||||||
|
+{
|
||||||
|
+ TEST_COMPARE (tst_audit18bmod1_func (), 10);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline bool
|
||||||
|
+startswith (const char *str, const char *pre)
|
||||||
|
+{
|
||||||
|
+ size_t lenpre = strlen (pre);
|
||||||
|
+ size_t lenstr = strlen (str);
|
||||||
|
+ return lenstr < lenpre ? false : memcmp (pre, str, lenpre) == 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (int argc, char *argv[])
|
||||||
|
+{
|
||||||
|
+ /* We must have either:
|
||||||
|
+ - One our fource parameters left if called initially:
|
||||||
|
+ + path to ld.so optional
|
||||||
|
+ + "--library-path" optional
|
||||||
|
+ + the library path optional
|
||||||
|
+ + the application name */
|
||||||
|
+
|
||||||
|
+ if (restart)
|
||||||
|
+ return handle_restart ();
|
||||||
|
+
|
||||||
|
+ char *spargv[9];
|
||||||
|
+ int i = 0;
|
||||||
|
+ for (; i < argc - 1; i++)
|
||||||
|
+ spargv[i] = argv[i + 1];
|
||||||
|
+ spargv[i++] = (char *) "--direct";
|
||||||
|
+ spargv[i++] = (char *) "--restart";
|
||||||
|
+ spargv[i] = NULL;
|
||||||
|
+
|
||||||
|
+ setenv ("LD_AUDIT", "tst-auditmod18b.so", 0);
|
||||||
|
+ struct support_capture_subprocess result
|
||||||
|
+ = support_capture_subprogram (spargv[0], spargv);
|
||||||
|
+ support_capture_subprocess_check (&result, "tst-audit18b", 0, sc_allow_stderr);
|
||||||
|
+
|
||||||
|
+ bool find_symbind = false;
|
||||||
|
+
|
||||||
|
+ FILE *out = fmemopen (result.err.buffer, result.err.length, "r");
|
||||||
|
+ TEST_VERIFY (out != NULL);
|
||||||
|
+ char *buffer = NULL;
|
||||||
|
+ size_t buffer_length = 0;
|
||||||
|
+ while (xgetline (&buffer, &buffer_length, out))
|
||||||
|
+ if (startswith (buffer, "la_symbind: tst_audit18bmod1_func") == 0)
|
||||||
|
+ find_symbind = true;
|
||||||
|
+
|
||||||
|
+ TEST_COMPARE (find_symbind, true);
|
||||||
|
+
|
||||||
|
+ free (buffer);
|
||||||
|
+ xfclose (out);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#define TEST_FUNCTION_ARGV do_test
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/elf/tst-audit19bmod.c b/elf/tst-audit19bmod.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..9ffdcd8f3ffbc38e
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit19bmod.c
|
||||||
|
@@ -0,0 +1,23 @@
|
||||||
|
+/* Extra module for tst-audit18b.
|
||||||
|
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+tst_audit18bmod1_func (void)
|
||||||
|
+{
|
||||||
|
+ return 10;
|
||||||
|
+}
|
||||||
|
diff --git a/elf/tst-auditmod19a.c b/elf/tst-auditmod19a.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..f58204099457743d
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-auditmod19a.c
|
||||||
|
@@ -0,0 +1,25 @@
|
||||||
|
+/* Audit module for tst-audit18a.
|
||||||
|
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <link.h>
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_version (unsigned int version)
|
||||||
|
+{
|
||||||
|
+ return LAV_CURRENT;
|
||||||
|
+}
|
||||||
|
diff --git a/elf/tst-auditmod19b.c b/elf/tst-auditmod19b.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..e2248b2a75946746
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-auditmod19b.c
|
||||||
|
@@ -0,0 +1,46 @@
|
||||||
|
+/* Audit module for tst-audit18b.
|
||||||
|
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <link.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_version (unsigned int version)
|
||||||
|
+{
|
||||||
|
+ return LAV_CURRENT;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
|
||||||
|
+{
|
||||||
|
+ return LA_FLG_BINDTO | LA_FLG_BINDFROM;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+uintptr_t
|
||||||
|
+#if __ELF_NATIVE_CLASS == 32
|
||||||
|
+la_symbind32 (Elf32_Sym *sym, unsigned int ndx, uintptr_t *refcook,
|
||||||
|
+ uintptr_t *defcook, unsigned int *flags, const char *symname)
|
||||||
|
+#else
|
||||||
|
+la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook,
|
||||||
|
+ uintptr_t *defcook, unsigned int *flags, const char *symname)
|
||||||
|
+#endif
|
||||||
|
+{
|
||||||
|
+ fprintf (stderr, "la_symbind: %s\n", symname);
|
||||||
|
+ return sym->st_value;
|
||||||
|
+}
|
||||||
|
diff --git a/include/link.h b/include/link.h
|
||||||
|
index 4dcf01d8aea90bc2..b3f160c278222b3c 100644
|
||||||
|
--- a/include/link.h
|
||||||
|
+++ b/include/link.h
|
||||||
|
@@ -363,8 +363,10 @@ struct auditstate
|
||||||
|
|
||||||
|
#if __ELF_NATIVE_CLASS == 32
|
||||||
|
# define symbind symbind32
|
||||||
|
+# define LA_SYMBIND "la_symbind32"
|
||||||
|
#elif __ELF_NATIVE_CLASS == 64
|
||||||
|
# define symbind symbind64
|
||||||
|
+# define LA_SYMBIND "la_symbind64"
|
||||||
|
#else
|
||||||
|
# error "__ELF_NATIVE_CLASS must be defined"
|
||||||
|
#endif
|
294
glibc-upstream-2.34-151.patch
Normal file
294
glibc-upstream-2.34-151.patch
Normal file
@ -0,0 +1,294 @@
|
|||||||
|
commit 02c6a3d35316d360ae08623f617b1873d2f6159a
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Wed Jun 30 15:51:31 2021 -0300
|
||||||
|
|
||||||
|
elf: Add audit tests for modules with TLSDESC
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
(cherry picked from commit d1b38173c9255b1a4ae00018ad9b35404a7c74d0)
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index eab9d46b6165e6be..29f545d2272bf6e2 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -807,6 +807,22 @@ modules-names += tst-gnu2-tls1mod
|
||||||
|
$(objpfx)tst-gnu2-tls1: $(objpfx)tst-gnu2-tls1mod.so
|
||||||
|
tst-gnu2-tls1mod.so-no-z-defs = yes
|
||||||
|
CFLAGS-tst-gnu2-tls1mod.c += -mtls-dialect=gnu2
|
||||||
|
+
|
||||||
|
+tests += tst-audit-tlsdesc tst-audit-tlsdesc-dlopen
|
||||||
|
+modules-names += tst-audit-tlsdesc-mod1 tst-audit-tlsdesc-mod2 tst-auditmod-tlsdesc
|
||||||
|
+$(objpfx)tst-audit-tlsdesc: $(objpfx)tst-audit-tlsdesc-mod1.so \
|
||||||
|
+ $(objpfx)tst-audit-tlsdesc-mod2.so \
|
||||||
|
+ $(shared-thread-library)
|
||||||
|
+CFLAGS-tst-audit-tlsdesc-mod1.c += -mtls-dialect=gnu2
|
||||||
|
+CFLAGS-tst-audit-tlsdesc-mod2.c += -mtls-dialect=gnu2
|
||||||
|
+$(objpfx)tst-audit-tlsdesc-dlopen: $(shared-thread-library)
|
||||||
|
+$(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-audit-tlsdesc-mod1.so \
|
||||||
|
+ $(objpfx)tst-audit-tlsdesc-mod2.so
|
||||||
|
+$(objpfx)tst-audit-tlsdesc-mod1.so: $(objpfx)tst-audit-tlsdesc-mod2.so
|
||||||
|
+$(objpfx)tst-audit-tlsdesc.out: $(objpfx)tst-auditmod-tlsdesc.so
|
||||||
|
+tst-audit-tlsdesc-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so
|
||||||
|
+$(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-auditmod-tlsdesc.so
|
||||||
|
+tst-audit-tlsdesc-dlopen-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so
|
||||||
|
endif
|
||||||
|
ifeq (yes,$(have-protected-data))
|
||||||
|
modules-names += tst-protected1moda tst-protected1modb
|
||||||
|
diff --git a/elf/tst-audit-tlsdesc-dlopen.c b/elf/tst-audit-tlsdesc-dlopen.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..9c16bb087aca1b77
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit-tlsdesc-dlopen.c
|
||||||
|
@@ -0,0 +1,67 @@
|
||||||
|
+/* DT_AUDIT with modules with TLSDESC.
|
||||||
|
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/xthread.h>
|
||||||
|
+#include <support/xdlfcn.h>
|
||||||
|
+
|
||||||
|
+static void *
|
||||||
|
+thr_func (void *mod)
|
||||||
|
+{
|
||||||
|
+ int* (*get_global1)(void) = xdlsym (mod, "get_global1");
|
||||||
|
+ int* (*get_global2)(void) = xdlsym (mod, "get_global2");
|
||||||
|
+ void (*set_global2)(int) = xdlsym (mod, "set_global2");
|
||||||
|
+ int* (*get_local1)(void) = xdlsym (mod, "get_local1");
|
||||||
|
+ int* (*get_local2)(void) = xdlsym (mod, "get_local2");
|
||||||
|
+
|
||||||
|
+ int *global1 = get_global1 ();
|
||||||
|
+ TEST_COMPARE (*global1, 0);
|
||||||
|
+ ++*global1;
|
||||||
|
+
|
||||||
|
+ int *global2 = get_global2 ();
|
||||||
|
+ TEST_COMPARE (*global2, 0);
|
||||||
|
+ ++*global2;
|
||||||
|
+ TEST_COMPARE (*global2, 1);
|
||||||
|
+
|
||||||
|
+ set_global2 (10);
|
||||||
|
+ TEST_COMPARE (*global2, 10);
|
||||||
|
+
|
||||||
|
+ int *local1 = get_local1 ();
|
||||||
|
+ TEST_COMPARE (*local1, 0);
|
||||||
|
+ ++*local1;
|
||||||
|
+
|
||||||
|
+ int *local2 = get_local2 ();
|
||||||
|
+ TEST_COMPARE (*local2, 0);
|
||||||
|
+ ++*local2;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ void *mod = xdlopen ("tst-audit-tlsdesc-mod1.so", RTLD_LAZY);
|
||||||
|
+
|
||||||
|
+ pthread_t thr = xpthread_create (NULL, thr_func, mod);
|
||||||
|
+ void *r = xpthread_join (thr);
|
||||||
|
+ TEST_VERIFY (r == NULL);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/elf/tst-audit-tlsdesc-mod1.c b/elf/tst-audit-tlsdesc-mod1.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..61c7dd99a2fb5e28
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit-tlsdesc-mod1.c
|
||||||
|
@@ -0,0 +1,41 @@
|
||||||
|
+/* DT_AUDIT with modules with TLSDESC.
|
||||||
|
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+__thread int global1;
|
||||||
|
+
|
||||||
|
+int *
|
||||||
|
+get_global1 (void)
|
||||||
|
+{
|
||||||
|
+ return &global1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static __thread int local1;
|
||||||
|
+
|
||||||
|
+void *
|
||||||
|
+get_local1 (void)
|
||||||
|
+{
|
||||||
|
+ return &local1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+extern __thread int global2;
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+set_global2 (int v)
|
||||||
|
+{
|
||||||
|
+ global2 = v;
|
||||||
|
+}
|
||||||
|
diff --git a/elf/tst-audit-tlsdesc-mod2.c b/elf/tst-audit-tlsdesc-mod2.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..28aef635f688ee03
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit-tlsdesc-mod2.c
|
||||||
|
@@ -0,0 +1,33 @@
|
||||||
|
+/* DT_AUDIT with modules with TLSDESC.
|
||||||
|
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+__thread int global2;
|
||||||
|
+
|
||||||
|
+int *
|
||||||
|
+get_global2 (void)
|
||||||
|
+{
|
||||||
|
+ return &global2;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static __thread int local2;
|
||||||
|
+
|
||||||
|
+void *
|
||||||
|
+get_local2 (void)
|
||||||
|
+{
|
||||||
|
+ return &local2;
|
||||||
|
+}
|
||||||
|
diff --git a/elf/tst-audit-tlsdesc.c b/elf/tst-audit-tlsdesc.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..3c8be81c95528f47
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit-tlsdesc.c
|
||||||
|
@@ -0,0 +1,60 @@
|
||||||
|
+/* DT_AUDIT with modules with TLSDESC.
|
||||||
|
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/xthread.h>
|
||||||
|
+
|
||||||
|
+extern __thread int global1;
|
||||||
|
+extern __thread int global2;
|
||||||
|
+void *get_local1 (void);
|
||||||
|
+void set_global2 (int v);
|
||||||
|
+void *get_local2 (void);
|
||||||
|
+
|
||||||
|
+static void *
|
||||||
|
+thr_func (void *clousure)
|
||||||
|
+{
|
||||||
|
+ TEST_COMPARE (global1, 0);
|
||||||
|
+ ++global1;
|
||||||
|
+ TEST_COMPARE (global2, 0);
|
||||||
|
+ ++global2;
|
||||||
|
+ TEST_COMPARE (global2, 1);
|
||||||
|
+
|
||||||
|
+ set_global2 (10);
|
||||||
|
+ TEST_COMPARE (global2, 10);
|
||||||
|
+
|
||||||
|
+ int *local1 = get_local1 ();
|
||||||
|
+ TEST_COMPARE (*local1, 0);
|
||||||
|
+ ++*local1;
|
||||||
|
+
|
||||||
|
+ int *local2 = get_local2 ();
|
||||||
|
+ TEST_COMPARE (*local2, 0);
|
||||||
|
+ ++*local2;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ pthread_t thr = xpthread_create (NULL, thr_func, NULL);
|
||||||
|
+ void *r = xpthread_join (thr);
|
||||||
|
+ TEST_VERIFY (r == NULL);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/elf/tst-auditmod-tlsdesc.c b/elf/tst-auditmod-tlsdesc.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..e4b835d1f1fb6f73
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-auditmod-tlsdesc.c
|
||||||
|
@@ -0,0 +1,25 @@
|
||||||
|
+/* DT_AUDIT with modules with TLSDESC.
|
||||||
|
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <link.h>
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_version (unsigned int version)
|
||||||
|
+{
|
||||||
|
+ return LAV_CURRENT;
|
||||||
|
+}
|
314
glibc-upstream-2.34-152.patch
Normal file
314
glibc-upstream-2.34-152.patch
Normal file
@ -0,0 +1,314 @@
|
|||||||
|
commit d1b9bee29a1c4e0b80db53f228e22550c3604894
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Mon Jul 19 18:42:26 2021 -0300
|
||||||
|
|
||||||
|
elf: Issue audit la_objopen for vDSO
|
||||||
|
|
||||||
|
The vDSO is is listed in the link_map chain, but is never the subject of
|
||||||
|
an la_objopen call. A new internal flag __RTLD_VDSO is added that
|
||||||
|
acts as __RTLD_OPENEXEC to allocate the required 'struct auditstate'
|
||||||
|
extra space for the 'struct link_map'.
|
||||||
|
|
||||||
|
The return value from the callback is currently ignored, since there
|
||||||
|
is no PLT call involved by glibc when using the vDSO, neither the vDSO
|
||||||
|
are exported directly.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
(cherry picked from commit f0e23d34a7bdf6b90fba954ee741419171ac41b2)
|
||||||
|
|
||||||
|
Resolved conflicts:
|
||||||
|
elf/Makefile
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index 29f545d2272bf6e2..465442bf59fa9794 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -366,6 +366,7 @@ tests += \
|
||||||
|
tst-audit17 \
|
||||||
|
tst-audit18 \
|
||||||
|
tst-audit19b \
|
||||||
|
+ tst-audit22 \
|
||||||
|
tst-auditmany \
|
||||||
|
tst-auxobj \
|
||||||
|
tst-auxobj-dlopen \
|
||||||
|
@@ -649,6 +650,7 @@ modules-names = \
|
||||||
|
tst-auditmod18 \
|
||||||
|
tst-auditmod19a \
|
||||||
|
tst-auditmod19b \
|
||||||
|
+ tst-auditmod22 \
|
||||||
|
tst-auxvalmod \
|
||||||
|
tst-big-note-lib \
|
||||||
|
tst-deep1mod1 \
|
||||||
|
@@ -2035,6 +2037,9 @@ $(objpfx)tst-audit19b.out: $(objpfx)tst-auditmod19b.so
|
||||||
|
$(objpfx)tst-audit19b: $(objpfx)tst-audit19bmod.so
|
||||||
|
tst-audit19b-ARGS = -- $(host-test-program-cmd)
|
||||||
|
|
||||||
|
+$(objpfx)tst-audit22.out: $(objpfx)tst-auditmod22.so
|
||||||
|
+tst-audit22-ARGS = -- $(host-test-program-cmd)
|
||||||
|
+
|
||||||
|
# tst-sonamemove links against an older implementation of the library.
|
||||||
|
LDFLAGS-tst-sonamemove-linkmod1.so = \
|
||||||
|
-Wl,--version-script=tst-sonamemove-linkmod1.map \
|
||||||
|
diff --git a/elf/dl-object.c b/elf/dl-object.c
|
||||||
|
index 1875599eb274dc35..dee49a32d4fdf07d 100644
|
||||||
|
--- a/elf/dl-object.c
|
||||||
|
+++ b/elf/dl-object.c
|
||||||
|
@@ -59,16 +59,19 @@ _dl_new_object (char *realname, const char *libname, int type,
|
||||||
|
{
|
||||||
|
#ifdef SHARED
|
||||||
|
unsigned int naudit;
|
||||||
|
- if (__glibc_unlikely ((mode & __RTLD_OPENEXEC) != 0))
|
||||||
|
+ if (__glibc_unlikely ((mode & (__RTLD_OPENEXEC | __RTLD_VDSO)) != 0))
|
||||||
|
{
|
||||||
|
- assert (type == lt_executable);
|
||||||
|
- assert (nsid == LM_ID_BASE);
|
||||||
|
+ if (mode & __RTLD_OPENEXEC)
|
||||||
|
+ {
|
||||||
|
+ assert (type == lt_executable);
|
||||||
|
+ assert (nsid == LM_ID_BASE);
|
||||||
|
|
||||||
|
- /* Ignore the specified libname for the main executable. It is
|
||||||
|
- only known with an explicit loader invocation. */
|
||||||
|
- libname = "";
|
||||||
|
+ /* Ignore the specified libname for the main executable. It is
|
||||||
|
+ only known with an explicit loader invocation. */
|
||||||
|
+ libname = "";
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- /* We create the map for the executable before we know whether
|
||||||
|
+ /* We create the map for the executable and vDSO before we know whether
|
||||||
|
we have auditing libraries and if yes, how many. Assume the
|
||||||
|
worst. */
|
||||||
|
naudit = DL_NNS;
|
||||||
|
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||||
|
index f632a767d7a269ef..b089e5cf4740443e 100644
|
||||||
|
--- a/elf/rtld.c
|
||||||
|
+++ b/elf/rtld.c
|
||||||
|
@@ -1922,6 +1922,12 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||||
|
assert (i == npreloads);
|
||||||
|
}
|
||||||
|
|
||||||
|
+#ifdef NEED_DL_SYSINFO_DSO
|
||||||
|
+ /* Now that the audit modules are opened, call la_objopen for the vDSO. */
|
||||||
|
+ if (GLRO(dl_sysinfo_map) != NULL)
|
||||||
|
+ _dl_audit_objopen (GLRO(dl_sysinfo_map), LM_ID_BASE);
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/* Load all the libraries specified by DT_NEEDED entries. If LD_PRELOAD
|
||||||
|
specified some libraries to load, these are inserted before the actual
|
||||||
|
dependencies in the executable's searchlist for symbol resolution. */
|
||||||
|
diff --git a/elf/setup-vdso.h b/elf/setup-vdso.h
|
||||||
|
index 3f20578046de76ed..2b013d974a377a83 100644
|
||||||
|
--- a/elf/setup-vdso.h
|
||||||
|
+++ b/elf/setup-vdso.h
|
||||||
|
@@ -30,7 +30,7 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
|
||||||
|
We just want our data structures to describe it as if we had just
|
||||||
|
mapped and relocated it normally. */
|
||||||
|
struct link_map *l = _dl_new_object ((char *) "", "", lt_library, NULL,
|
||||||
|
- 0, LM_ID_BASE);
|
||||||
|
+ __RTLD_VDSO, LM_ID_BASE);
|
||||||
|
if (__glibc_likely (l != NULL))
|
||||||
|
{
|
||||||
|
l->l_phdr = ((const void *) GLRO(dl_sysinfo_dso)
|
||||||
|
diff --git a/elf/tst-audit22.c b/elf/tst-audit22.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..18fd22a760ddc3d8
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit22.c
|
||||||
|
@@ -0,0 +1,124 @@
|
||||||
|
+/* Check DTAUDIT and vDSO interaction.
|
||||||
|
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <errno.h>
|
||||||
|
+#include <getopt.h>
|
||||||
|
+#include <limits.h>
|
||||||
|
+#include <inttypes.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <support/capture_subprocess.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/xstdio.h>
|
||||||
|
+#include <support/support.h>
|
||||||
|
+#include <sys/auxv.h>
|
||||||
|
+
|
||||||
|
+static int restart;
|
||||||
|
+#define CMDLINE_OPTIONS \
|
||||||
|
+ { "restart", no_argument, &restart, 1 },
|
||||||
|
+
|
||||||
|
+static uintptr_t vdso_addr;
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+handle_restart (void)
|
||||||
|
+{
|
||||||
|
+ fprintf (stderr, "vdso: %p\n", (void*) vdso_addr);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static uintptr_t
|
||||||
|
+parse_address (const char *str)
|
||||||
|
+{
|
||||||
|
+ void *r;
|
||||||
|
+ TEST_COMPARE (sscanf (str, "%p\n", &r), 1);
|
||||||
|
+ return (uintptr_t) r;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline bool
|
||||||
|
+startswith (const char *str, const char *pre)
|
||||||
|
+{
|
||||||
|
+ size_t lenpre = strlen (pre);
|
||||||
|
+ size_t lenstr = strlen (str);
|
||||||
|
+ return lenstr >= lenpre && memcmp (pre, str, lenpre) == 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (int argc, char *argv[])
|
||||||
|
+{
|
||||||
|
+ vdso_addr = getauxval (AT_SYSINFO_EHDR);
|
||||||
|
+ if (vdso_addr == 0)
|
||||||
|
+ FAIL_UNSUPPORTED ("getauxval (AT_SYSINFO_EHDR) returned 0");
|
||||||
|
+
|
||||||
|
+ /* We must have either:
|
||||||
|
+ - One our fource parameters left if called initially:
|
||||||
|
+ + path to ld.so optional
|
||||||
|
+ + "--library-path" optional
|
||||||
|
+ + the library path optional
|
||||||
|
+ + the application name */
|
||||||
|
+ if (restart)
|
||||||
|
+ return handle_restart ();
|
||||||
|
+
|
||||||
|
+ char *spargv[9];
|
||||||
|
+ int i = 0;
|
||||||
|
+ for (; i < argc - 1; i++)
|
||||||
|
+ spargv[i] = argv[i + 1];
|
||||||
|
+ spargv[i++] = (char *) "--direct";
|
||||||
|
+ spargv[i++] = (char *) "--restart";
|
||||||
|
+ spargv[i] = NULL;
|
||||||
|
+
|
||||||
|
+ setenv ("LD_AUDIT", "tst-auditmod22.so", 0);
|
||||||
|
+ struct support_capture_subprocess result
|
||||||
|
+ = support_capture_subprogram (spargv[0], spargv);
|
||||||
|
+ support_capture_subprocess_check (&result, "tst-audit22", 0, sc_allow_stderr);
|
||||||
|
+
|
||||||
|
+ /* The respawned process should always print the vDSO address (otherwise it
|
||||||
|
+ will fails as unsupported). However, on some architectures the audit
|
||||||
|
+ module might see the vDSO with l_addr being 0, meaning a fixed mapping
|
||||||
|
+ (linux-gate.so). In this case we don't check its value against
|
||||||
|
+ AT_SYSINFO_EHDR one. */
|
||||||
|
+ uintptr_t vdso_process = 0;
|
||||||
|
+ bool vdso_audit_found = false;
|
||||||
|
+ uintptr_t vdso_audit = 0;
|
||||||
|
+
|
||||||
|
+ FILE *out = fmemopen (result.err.buffer, result.err.length, "r");
|
||||||
|
+ TEST_VERIFY (out != NULL);
|
||||||
|
+ char *buffer = NULL;
|
||||||
|
+ size_t buffer_length = 0;
|
||||||
|
+ while (xgetline (&buffer, &buffer_length, out))
|
||||||
|
+ {
|
||||||
|
+ if (startswith (buffer, "vdso: "))
|
||||||
|
+ vdso_process = parse_address (buffer + strlen ("vdso: "));
|
||||||
|
+ else if (startswith (buffer, "vdso found: "))
|
||||||
|
+ {
|
||||||
|
+ vdso_audit = parse_address (buffer + strlen ("vdso found: "));
|
||||||
|
+ vdso_audit_found = true;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ TEST_COMPARE (vdso_audit_found, true);
|
||||||
|
+ if (vdso_audit != 0)
|
||||||
|
+ TEST_COMPARE (vdso_process, vdso_audit);
|
||||||
|
+
|
||||||
|
+ free (buffer);
|
||||||
|
+ xfclose (out);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#define TEST_FUNCTION_ARGV do_test
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/elf/tst-auditmod22.c b/elf/tst-auditmod22.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..8e05ce8cbb215dd5
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-auditmod22.c
|
||||||
|
@@ -0,0 +1,51 @@
|
||||||
|
+/* Check DTAUDIT and vDSO interaction.
|
||||||
|
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <link.h>
|
||||||
|
+#include <inttypes.h>
|
||||||
|
+#include <stdbool.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <sys/auxv.h>
|
||||||
|
+
|
||||||
|
+static inline bool
|
||||||
|
+startswith (const char *str, const char *pre)
|
||||||
|
+{
|
||||||
|
+ size_t lenpre = strlen (pre);
|
||||||
|
+ size_t lenstr = strlen (str);
|
||||||
|
+ return lenstr < lenpre ? false : memcmp (pre, str, lenpre) == 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_version (unsigned int version)
|
||||||
|
+{
|
||||||
|
+ return LAV_CURRENT;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
|
||||||
|
+{
|
||||||
|
+ /* The linux-gate.so is placed at a fixed address, thus l_addr being 0,
|
||||||
|
+ and it might be the value reported as the AT_SYSINFO_EHDR. */
|
||||||
|
+ if (map->l_addr == 0 && startswith (map->l_name, "linux-gate.so"))
|
||||||
|
+ fprintf (stderr, "vdso found: %p\n", NULL);
|
||||||
|
+ else if (map->l_addr == getauxval (AT_SYSINFO_EHDR))
|
||||||
|
+ fprintf (stderr, "vdso found: %p\n", (void*) map->l_addr);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
diff --git a/include/dlfcn.h b/include/dlfcn.h
|
||||||
|
index a4c283728f94deb4..e73294b0af587913 100644
|
||||||
|
--- a/include/dlfcn.h
|
||||||
|
+++ b/include/dlfcn.h
|
||||||
|
@@ -12,6 +12,8 @@
|
||||||
|
#define __RTLD_AUDIT 0x08000000
|
||||||
|
#define __RTLD_SECURE 0x04000000 /* Apply additional security checks. */
|
||||||
|
#define __RTLD_NOIFUNC 0x02000000 /* Suppress calling ifunc functions. */
|
||||||
|
+#define __RTLD_VDSO 0x01000000 /* Tell _dl_new_object the object is
|
||||||
|
+ system-loaded. */
|
||||||
|
|
||||||
|
#define __LM_ID_CALLER -2
|
||||||
|
|
167
glibc-upstream-2.34-153.patch
Normal file
167
glibc-upstream-2.34-153.patch
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
commit 2255621f0e2cd07f7a6147928ce644e13526ffb6
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Wed Jun 30 17:33:57 2021 -0300
|
||||||
|
|
||||||
|
elf: Do not fail for failed dlmopen on audit modules (BZ #28061)
|
||||||
|
|
||||||
|
The dl_main sets the LM_ID_BASE to RT_ADD just before starting to
|
||||||
|
add load new shared objects. The state is set to RT_CONSISTENT just
|
||||||
|
after all objects are loaded.
|
||||||
|
|
||||||
|
However if a audit modules tries to dlmopen an inexistent module,
|
||||||
|
the _dl_open will assert that the namespace is in an inconsistent
|
||||||
|
state.
|
||||||
|
|
||||||
|
This is different than dlopen, since first it will not use
|
||||||
|
LM_ID_BASE and second _dl_map_object_from_fd is the sole responsible
|
||||||
|
to set and reset the r_state value.
|
||||||
|
|
||||||
|
So the assert on _dl_open can not really be seen if the state is
|
||||||
|
consistent, since _dt_main resets it. This patch removes the assert.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
(cherry picked from commit 484e672ddabe0a919a692520e6ac8f2580866235)
|
||||||
|
|
||||||
|
Resolved conflicts:
|
||||||
|
elf/Makefile
|
||||||
|
elf/dl-open.c
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index 465442bf59fa9794..91b2269257523a64 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -366,6 +366,7 @@ tests += \
|
||||||
|
tst-audit17 \
|
||||||
|
tst-audit18 \
|
||||||
|
tst-audit19b \
|
||||||
|
+ tst-audit20 \
|
||||||
|
tst-audit22 \
|
||||||
|
tst-auditmany \
|
||||||
|
tst-auxobj \
|
||||||
|
@@ -650,6 +651,7 @@ modules-names = \
|
||||||
|
tst-auditmod18 \
|
||||||
|
tst-auditmod19a \
|
||||||
|
tst-auditmod19b \
|
||||||
|
+ tst-auditmod20 \
|
||||||
|
tst-auditmod22 \
|
||||||
|
tst-auxvalmod \
|
||||||
|
tst-big-note-lib \
|
||||||
|
@@ -2037,6 +2039,9 @@ $(objpfx)tst-audit19b.out: $(objpfx)tst-auditmod19b.so
|
||||||
|
$(objpfx)tst-audit19b: $(objpfx)tst-audit19bmod.so
|
||||||
|
tst-audit19b-ARGS = -- $(host-test-program-cmd)
|
||||||
|
|
||||||
|
+$(objpfx)tst-audit20.out: $(objpfx)tst-auditmod20.so
|
||||||
|
+tst-audit20-ENV = LD_AUDIT=$(objpfx)tst-auditmod20.so
|
||||||
|
+
|
||||||
|
$(objpfx)tst-audit22.out: $(objpfx)tst-auditmod22.so
|
||||||
|
tst-audit22-ARGS = -- $(host-test-program-cmd)
|
||||||
|
|
||||||
|
diff --git a/elf/dl-open.c b/elf/dl-open.c
|
||||||
|
index 3f01aa480730da13..bc6872632880634e 100644
|
||||||
|
--- a/elf/dl-open.c
|
||||||
|
+++ b/elf/dl-open.c
|
||||||
|
@@ -914,8 +914,6 @@ no more namespaces available for dlmopen()"));
|
||||||
|
the flag here. */
|
||||||
|
}
|
||||||
|
|
||||||
|
- assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT);
|
||||||
|
-
|
||||||
|
/* Release the lock. */
|
||||||
|
__rtld_lock_unlock_recursive (GL(dl_load_lock));
|
||||||
|
|
||||||
|
diff --git a/elf/tst-audit20.c b/elf/tst-audit20.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..6f39ccee865b012b
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit20.c
|
||||||
|
@@ -0,0 +1,25 @@
|
||||||
|
+/* Check dlopen failure on audit modules.
|
||||||
|
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/elf/tst-auditmod20.c b/elf/tst-auditmod20.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..c57e50ee4e88dd6b
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-auditmod20.c
|
||||||
|
@@ -0,0 +1,57 @@
|
||||||
|
+/* Check dlopen failure on audit modules.
|
||||||
|
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <dlfcn.h>
|
||||||
|
+#include <link.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_version (unsigned int v)
|
||||||
|
+{
|
||||||
|
+ return LAV_CURRENT;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+check (void)
|
||||||
|
+{
|
||||||
|
+ {
|
||||||
|
+ void *mod = dlopen ("nonexistent.so", RTLD_NOW);
|
||||||
|
+ if (mod != NULL)
|
||||||
|
+ abort ();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ {
|
||||||
|
+ void *mod = dlmopen (LM_ID_BASE, "nonexistent.so", RTLD_NOW);
|
||||||
|
+ if (mod != NULL)
|
||||||
|
+ abort ();
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+la_activity (uintptr_t *cookie, unsigned int flag)
|
||||||
|
+{
|
||||||
|
+ if (flag != LA_ACT_CONSISTENT)
|
||||||
|
+ return;
|
||||||
|
+ check ();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+la_preinit (uintptr_t *cookie)
|
||||||
|
+{
|
||||||
|
+ check ();
|
||||||
|
+}
|
434
glibc-upstream-2.34-154.patch
Normal file
434
glibc-upstream-2.34-154.patch
Normal file
@ -0,0 +1,434 @@
|
|||||||
|
commit 98047ba95caf9ed596908ca73a22070c5e27597b
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Mon Jan 24 10:46:15 2022 -0300
|
||||||
|
|
||||||
|
elf: Add la_activity during application exit
|
||||||
|
|
||||||
|
la_activity is not called during application exit, even though
|
||||||
|
la_objclose is.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
Tested-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
(cherry picked from commit 5fa11a2bc94c912c3b25860065086902674537ba)
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index 91b2269257523a64..407aaeaeb8c84020 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -368,6 +368,7 @@ tests += \
|
||||||
|
tst-audit19b \
|
||||||
|
tst-audit20 \
|
||||||
|
tst-audit22 \
|
||||||
|
+ tst-audit23 \
|
||||||
|
tst-auditmany \
|
||||||
|
tst-auxobj \
|
||||||
|
tst-auxobj-dlopen \
|
||||||
|
@@ -631,6 +632,7 @@ modules-names = \
|
||||||
|
tst-audit13mod1 \
|
||||||
|
tst-audit18mod \
|
||||||
|
tst-audit19bmod \
|
||||||
|
+ tst-audit23mod \
|
||||||
|
tst-auditlogmod-1 \
|
||||||
|
tst-auditlogmod-2 \
|
||||||
|
tst-auditlogmod-3 \
|
||||||
|
@@ -653,6 +655,7 @@ modules-names = \
|
||||||
|
tst-auditmod19b \
|
||||||
|
tst-auditmod20 \
|
||||||
|
tst-auditmod22 \
|
||||||
|
+ tst-auditmod23 \
|
||||||
|
tst-auxvalmod \
|
||||||
|
tst-big-note-lib \
|
||||||
|
tst-deep1mod1 \
|
||||||
|
@@ -2045,6 +2048,10 @@ tst-audit20-ENV = LD_AUDIT=$(objpfx)tst-auditmod20.so
|
||||||
|
$(objpfx)tst-audit22.out: $(objpfx)tst-auditmod22.so
|
||||||
|
tst-audit22-ARGS = -- $(host-test-program-cmd)
|
||||||
|
|
||||||
|
+$(objpfx)tst-audit23.out: $(objpfx)tst-auditmod23.so \
|
||||||
|
+ $(objpfx)tst-audit23mod.so
|
||||||
|
+tst-audit23-ARGS = -- $(host-test-program-cmd)
|
||||||
|
+
|
||||||
|
# tst-sonamemove links against an older implementation of the library.
|
||||||
|
LDFLAGS-tst-sonamemove-linkmod1.so = \
|
||||||
|
-Wl,--version-script=tst-sonamemove-linkmod1.map \
|
||||||
|
diff --git a/elf/dl-fini.c b/elf/dl-fini.c
|
||||||
|
index b789cfb9f2ac6c85..fa876da0ffa1cf97 100644
|
||||||
|
--- a/elf/dl-fini.c
|
||||||
|
+++ b/elf/dl-fini.c
|
||||||
|
@@ -64,6 +64,10 @@ _dl_fini (void)
|
||||||
|
__rtld_lock_unlock_recursive (GL(dl_load_lock));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
+#ifdef SHARED
|
||||||
|
+ _dl_audit_activity_nsid (ns, LA_ACT_DELETE);
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/* Now we can allocate an array to hold all the pointers and
|
||||||
|
copy the pointers in. */
|
||||||
|
struct link_map *maps[nloaded];
|
||||||
|
@@ -153,6 +157,10 @@ _dl_fini (void)
|
||||||
|
/* Correct the previous increment. */
|
||||||
|
--l->l_direct_opencount;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+#ifdef SHARED
|
||||||
|
+ _dl_audit_activity_nsid (ns, LA_ACT_CONSISTENT);
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/elf/tst-audit23.c b/elf/tst-audit23.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..4904cf1340a97ee1
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit23.c
|
||||||
|
@@ -0,0 +1,239 @@
|
||||||
|
+/* Check for expected la_objopen and la_objeclose for all objects.
|
||||||
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <array_length.h>
|
||||||
|
+#include <errno.h>
|
||||||
|
+#include <getopt.h>
|
||||||
|
+#include <link.h>
|
||||||
|
+#include <limits.h>
|
||||||
|
+#include <inttypes.h>
|
||||||
|
+#include <gnu/lib-names.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <support/capture_subprocess.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/xstdio.h>
|
||||||
|
+#include <support/xdlfcn.h>
|
||||||
|
+#include <support/support.h>
|
||||||
|
+
|
||||||
|
+static int restart;
|
||||||
|
+#define CMDLINE_OPTIONS \
|
||||||
|
+ { "restart", no_argument, &restart, 1 },
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+handle_restart (void)
|
||||||
|
+{
|
||||||
|
+ xdlopen ("tst-audit23mod.so", RTLD_NOW);
|
||||||
|
+ xdlmopen (LM_ID_NEWLM, LIBC_SO, RTLD_NOW);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline bool
|
||||||
|
+startswith (const char *str, const char *pre)
|
||||||
|
+{
|
||||||
|
+ size_t lenpre = strlen (pre);
|
||||||
|
+ size_t lenstr = strlen (str);
|
||||||
|
+ return lenstr >= lenpre && memcmp (pre, str, lenpre) == 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline bool
|
||||||
|
+is_vdso (const char *str)
|
||||||
|
+{
|
||||||
|
+ return startswith (str, "linux-gate")
|
||||||
|
+ || startswith (str, "linux-vdso");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (int argc, char *argv[])
|
||||||
|
+{
|
||||||
|
+ /* We must have either:
|
||||||
|
+ - One or four parameters left if called initially:
|
||||||
|
+ + path to ld.so optional
|
||||||
|
+ + "--library-path" optional
|
||||||
|
+ + the library path optional
|
||||||
|
+ + the application name */
|
||||||
|
+ if (restart)
|
||||||
|
+ return handle_restart ();
|
||||||
|
+
|
||||||
|
+ char *spargv[9];
|
||||||
|
+ TEST_VERIFY_EXIT (((argc - 1) + 3) < array_length (spargv));
|
||||||
|
+ int i = 0;
|
||||||
|
+ for (; i < argc - 1; i++)
|
||||||
|
+ spargv[i] = argv[i + 1];
|
||||||
|
+ spargv[i++] = (char *) "--direct";
|
||||||
|
+ spargv[i++] = (char *) "--restart";
|
||||||
|
+ spargv[i] = NULL;
|
||||||
|
+
|
||||||
|
+ setenv ("LD_AUDIT", "tst-auditmod23.so", 0);
|
||||||
|
+ struct support_capture_subprocess result
|
||||||
|
+ = support_capture_subprogram (spargv[0], spargv);
|
||||||
|
+ support_capture_subprocess_check (&result, "tst-audit22", 0, sc_allow_stderr);
|
||||||
|
+
|
||||||
|
+ /* The expected la_objopen/la_objclose:
|
||||||
|
+ 1. executable
|
||||||
|
+ 2. loader
|
||||||
|
+ 3. libc.so
|
||||||
|
+ 4. tst-audit23mod.so
|
||||||
|
+ 5. libc.so (LM_ID_NEWLM).
|
||||||
|
+ 6. vdso (optional and ignored). */
|
||||||
|
+ enum { max_objs = 6 };
|
||||||
|
+ struct la_obj_t
|
||||||
|
+ {
|
||||||
|
+ char *lname;
|
||||||
|
+ uintptr_t laddr;
|
||||||
|
+ Lmid_t lmid;
|
||||||
|
+ bool closed;
|
||||||
|
+ } objs[max_objs] = { [0 ... max_objs-1] = { .closed = false } };
|
||||||
|
+ size_t nobjs = 0;
|
||||||
|
+
|
||||||
|
+ /* The expected namespaces are one for the audit module, one for the
|
||||||
|
+ application, and another for the dlmopen on handle_restart. */
|
||||||
|
+ enum { max_ns = 3 };
|
||||||
|
+ uintptr_t acts[max_ns] = { 0 };
|
||||||
|
+ size_t nacts = 0;
|
||||||
|
+ int last_act = -1;
|
||||||
|
+ uintptr_t last_act_cookie = -1;
|
||||||
|
+ bool seen_first_objclose = false;
|
||||||
|
+
|
||||||
|
+ FILE *out = fmemopen (result.err.buffer, result.err.length, "r");
|
||||||
|
+ TEST_VERIFY (out != NULL);
|
||||||
|
+ char *buffer = NULL;
|
||||||
|
+ size_t buffer_length = 0;
|
||||||
|
+ while (xgetline (&buffer, &buffer_length, out))
|
||||||
|
+ {
|
||||||
|
+ if (startswith (buffer, "la_activity: "))
|
||||||
|
+ {
|
||||||
|
+ uintptr_t cookie;
|
||||||
|
+ int this_act;
|
||||||
|
+ int r = sscanf (buffer, "la_activity: %d %"SCNxPTR"", &this_act,
|
||||||
|
+ &cookie);
|
||||||
|
+ TEST_COMPARE (r, 2);
|
||||||
|
+
|
||||||
|
+ /* The cookie identifies the object at the head of the link map,
|
||||||
|
+ so we only add a new namespace if it changes from the previous
|
||||||
|
+ one. This works since dlmopen is the last in the test body. */
|
||||||
|
+ if (cookie != last_act_cookie && last_act_cookie != -1)
|
||||||
|
+ TEST_COMPARE (last_act, LA_ACT_CONSISTENT);
|
||||||
|
+
|
||||||
|
+ if (this_act == LA_ACT_ADD && acts[nacts] != cookie)
|
||||||
|
+ {
|
||||||
|
+ acts[nacts++] = cookie;
|
||||||
|
+ last_act_cookie = cookie;
|
||||||
|
+ }
|
||||||
|
+ /* The LA_ACT_DELETE is called in the reverse order of LA_ACT_ADD
|
||||||
|
+ at program termination (if the tests adds a dlclose or a library
|
||||||
|
+ with extra dependencies this will need to be adapted). */
|
||||||
|
+ else if (this_act == LA_ACT_DELETE)
|
||||||
|
+ {
|
||||||
|
+ last_act_cookie = acts[--nacts];
|
||||||
|
+ TEST_COMPARE (acts[nacts], cookie);
|
||||||
|
+ acts[nacts] = 0;
|
||||||
|
+ }
|
||||||
|
+ else if (this_act == LA_ACT_CONSISTENT)
|
||||||
|
+ {
|
||||||
|
+ TEST_COMPARE (cookie, last_act_cookie);
|
||||||
|
+
|
||||||
|
+ /* LA_ACT_DELETE must always be followed by an la_objclose. */
|
||||||
|
+ if (last_act == LA_ACT_DELETE)
|
||||||
|
+ TEST_COMPARE (seen_first_objclose, true);
|
||||||
|
+ else
|
||||||
|
+ TEST_COMPARE (last_act, LA_ACT_ADD);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ last_act = this_act;
|
||||||
|
+ seen_first_objclose = false;
|
||||||
|
+ }
|
||||||
|
+ else if (startswith (buffer, "la_objopen: "))
|
||||||
|
+ {
|
||||||
|
+ char *lname;
|
||||||
|
+ uintptr_t laddr;
|
||||||
|
+ Lmid_t lmid;
|
||||||
|
+ uintptr_t cookie;
|
||||||
|
+ int r = sscanf (buffer, "la_objopen: %"SCNxPTR" %ms %"SCNxPTR" %ld",
|
||||||
|
+ &cookie, &lname, &laddr, &lmid);
|
||||||
|
+ TEST_COMPARE (r, 4);
|
||||||
|
+
|
||||||
|
+ /* la_objclose is not triggered by vDSO because glibc does not
|
||||||
|
+ unload it. */
|
||||||
|
+ if (is_vdso (lname))
|
||||||
|
+ continue;
|
||||||
|
+ if (nobjs == max_objs)
|
||||||
|
+ FAIL_EXIT1 ("non expected la_objopen: %s %"PRIxPTR" %ld",
|
||||||
|
+ lname, laddr, lmid);
|
||||||
|
+ objs[nobjs].lname = lname;
|
||||||
|
+ objs[nobjs].laddr = laddr;
|
||||||
|
+ objs[nobjs].lmid = lmid;
|
||||||
|
+ objs[nobjs].closed = false;
|
||||||
|
+ nobjs++;
|
||||||
|
+
|
||||||
|
+ /* This indirectly checks that la_objopen always comes before
|
||||||
|
+ la_objclose btween la_activity calls. */
|
||||||
|
+ seen_first_objclose = false;
|
||||||
|
+ }
|
||||||
|
+ else if (startswith (buffer, "la_objclose: "))
|
||||||
|
+ {
|
||||||
|
+ char *lname;
|
||||||
|
+ uintptr_t laddr;
|
||||||
|
+ Lmid_t lmid;
|
||||||
|
+ uintptr_t cookie;
|
||||||
|
+ int r = sscanf (buffer, "la_objclose: %"SCNxPTR" %ms %"SCNxPTR" %ld",
|
||||||
|
+ &cookie, &lname, &laddr, &lmid);
|
||||||
|
+ TEST_COMPARE (r, 4);
|
||||||
|
+
|
||||||
|
+ for (size_t i = 0; i < nobjs; i++)
|
||||||
|
+ {
|
||||||
|
+ if (strcmp (lname, objs[i].lname) == 0 && lmid == objs[i].lmid)
|
||||||
|
+ {
|
||||||
|
+ TEST_COMPARE (objs[i].closed, false);
|
||||||
|
+ objs[i].closed = true;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* la_objclose should be called after la_activity(LA_ACT_DELETE) for
|
||||||
|
+ the closed object's namespace. */
|
||||||
|
+ TEST_COMPARE (last_act, LA_ACT_DELETE);
|
||||||
|
+ if (!seen_first_objclose)
|
||||||
|
+ {
|
||||||
|
+ TEST_COMPARE (last_act_cookie, cookie);
|
||||||
|
+ seen_first_objclose = true;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (size_t i = 0; i < nobjs; i++)
|
||||||
|
+ {
|
||||||
|
+ TEST_COMPARE (objs[i].closed, true);
|
||||||
|
+ free (objs[i].lname);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* la_activity(LA_ACT_CONSISTENT) should be the last callback received.
|
||||||
|
+ Since only one link map may be not-CONSISTENT at a time, this also
|
||||||
|
+ ensures la_activity(LA_ACT_CONSISTENT) is the last callback received
|
||||||
|
+ for every namespace. */
|
||||||
|
+ TEST_COMPARE (last_act, LA_ACT_CONSISTENT);
|
||||||
|
+
|
||||||
|
+ free (buffer);
|
||||||
|
+ xfclose (out);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#define TEST_FUNCTION_ARGV do_test
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/elf/tst-audit23mod.c b/elf/tst-audit23mod.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..30315687037d25e8
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit23mod.c
|
||||||
|
@@ -0,0 +1,23 @@
|
||||||
|
+/* Extra module for tst-audit23
|
||||||
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+foo (void)
|
||||||
|
+{
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
diff --git a/elf/tst-auditmod23.c b/elf/tst-auditmod23.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..d7c60d7a5cbc4f8a
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-auditmod23.c
|
||||||
|
@@ -0,0 +1,74 @@
|
||||||
|
+/* Audit module loaded by tst-audit23.
|
||||||
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <link.h>
|
||||||
|
+#include <inttypes.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <sys/auxv.h>
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_version (unsigned int version)
|
||||||
|
+{
|
||||||
|
+ return LAV_CURRENT;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+struct map_desc_t
|
||||||
|
+{
|
||||||
|
+ char *lname;
|
||||||
|
+ uintptr_t laddr;
|
||||||
|
+ Lmid_t lmid;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+la_activity (uintptr_t *cookie, unsigned int flag)
|
||||||
|
+{
|
||||||
|
+ fprintf (stderr, "%s: %d %"PRIxPTR"\n", __func__, flag, (uintptr_t) cookie);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
|
||||||
|
+{
|
||||||
|
+ const char *l_name = map->l_name[0] == '\0' ? "mainapp" : map->l_name;
|
||||||
|
+ fprintf (stderr, "%s: %"PRIxPTR" %s %"PRIxPTR" %ld\n", __func__,
|
||||||
|
+ (uintptr_t) cookie, l_name, map->l_addr, lmid);
|
||||||
|
+
|
||||||
|
+ struct map_desc_t *map_desc = malloc (sizeof (struct map_desc_t));
|
||||||
|
+ if (map_desc == NULL)
|
||||||
|
+ abort ();
|
||||||
|
+
|
||||||
|
+ map_desc->lname = strdup (l_name);
|
||||||
|
+ map_desc->laddr = map->l_addr;
|
||||||
|
+ map_desc->lmid = lmid;
|
||||||
|
+
|
||||||
|
+ *cookie = (uintptr_t) map_desc;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_objclose (uintptr_t *cookie)
|
||||||
|
+{
|
||||||
|
+ struct map_desc_t *map_desc = (struct map_desc_t *) *cookie;
|
||||||
|
+ fprintf (stderr, "%s: %"PRIxPTR" %s %"PRIxPTR" %ld\n", __func__,
|
||||||
|
+ (uintptr_t) cookie, map_desc->lname, map_desc->laddr,
|
||||||
|
+ map_desc->lmid);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
299
glibc-upstream-2.34-155.patch
Normal file
299
glibc-upstream-2.34-155.patch
Normal file
@ -0,0 +1,299 @@
|
|||||||
|
commit efb21b5fb27fbad447d9f242436fb591870f0045
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Mon Jan 24 10:46:16 2022 -0300
|
||||||
|
|
||||||
|
elf: Fix initial-exec TLS access on audit modules (BZ #28096)
|
||||||
|
|
||||||
|
For audit modules and dependencies with initial-exec TLS, we can not
|
||||||
|
set the initial TLS image on default loader initialization because it
|
||||||
|
would already be set by the audit setup. However, subsequent thread
|
||||||
|
creation would need to follow the default behaviour.
|
||||||
|
|
||||||
|
This patch fixes it by setting l_auditing link_map field not only
|
||||||
|
for the audit modules, but also for all its dependencies. This is
|
||||||
|
used on _dl_allocate_tls_init to avoid the static TLS initialization
|
||||||
|
at load time.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
Tested-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
(cherry picked from commit 254d3d5aef2fd8430c469e1938209ac100ebf132)
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index 407aaeaeb8c84020..3ccf78f62985e2d0 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -367,6 +367,7 @@ tests += \
|
||||||
|
tst-audit18 \
|
||||||
|
tst-audit19b \
|
||||||
|
tst-audit20 \
|
||||||
|
+ tst-audit21 \
|
||||||
|
tst-audit22 \
|
||||||
|
tst-audit23 \
|
||||||
|
tst-auditmany \
|
||||||
|
@@ -654,6 +655,8 @@ modules-names = \
|
||||||
|
tst-auditmod19a \
|
||||||
|
tst-auditmod19b \
|
||||||
|
tst-auditmod20 \
|
||||||
|
+ tst-auditmod21a \
|
||||||
|
+ tst-auditmod21b \
|
||||||
|
tst-auditmod22 \
|
||||||
|
tst-auditmod23 \
|
||||||
|
tst-auxvalmod \
|
||||||
|
@@ -2045,6 +2048,11 @@ tst-audit19b-ARGS = -- $(host-test-program-cmd)
|
||||||
|
$(objpfx)tst-audit20.out: $(objpfx)tst-auditmod20.so
|
||||||
|
tst-audit20-ENV = LD_AUDIT=$(objpfx)tst-auditmod20.so
|
||||||
|
|
||||||
|
+$(objpfx)tst-audit21: $(shared-thread-library)
|
||||||
|
+$(objpfx)tst-audit21.out: $(objpfx)tst-auditmod21a.so
|
||||||
|
+$(objpfx)tst-auditmod21a.so: $(objpfx)tst-auditmod21b.so
|
||||||
|
+tst-audit21-ENV = LD_AUDIT=$(objpfx)tst-auditmod21a.so
|
||||||
|
+
|
||||||
|
$(objpfx)tst-audit22.out: $(objpfx)tst-auditmod22.so
|
||||||
|
tst-audit22-ARGS = -- $(host-test-program-cmd)
|
||||||
|
|
||||||
|
diff --git a/elf/dl-tls.c b/elf/dl-tls.c
|
||||||
|
index e2012d0cd515103b..fab6546e2d31edd4 100644
|
||||||
|
--- a/elf/dl-tls.c
|
||||||
|
+++ b/elf/dl-tls.c
|
||||||
|
@@ -519,8 +519,12 @@ _dl_resize_dtv (dtv_t *dtv, size_t max_modid)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
+/* Allocate initial TLS. RESULT should be a non-NULL pointer to storage
|
||||||
|
+ for the TLS space. The DTV may be resized, and so this function may
|
||||||
|
+ call malloc to allocate that space. The loader's GL(dl_load_tls_lock)
|
||||||
|
+ is taken when manipulating global TLS-related data in the loader. */
|
||||||
|
void *
|
||||||
|
-_dl_allocate_tls_init (void *result)
|
||||||
|
+_dl_allocate_tls_init (void *result, bool init_tls)
|
||||||
|
{
|
||||||
|
if (result == NULL)
|
||||||
|
/* The memory allocation failed. */
|
||||||
|
@@ -593,7 +597,14 @@ _dl_allocate_tls_init (void *result)
|
||||||
|
some platforms use in static programs requires it. */
|
||||||
|
dtv[map->l_tls_modid].pointer.val = dest;
|
||||||
|
|
||||||
|
- /* Copy the initialization image and clear the BSS part. */
|
||||||
|
+ /* Copy the initialization image and clear the BSS part. For
|
||||||
|
+ audit modules or dependencies with initial-exec TLS, we can not
|
||||||
|
+ set the initial TLS image on default loader initialization
|
||||||
|
+ because it would already be set by the audit setup. However,
|
||||||
|
+ subsequent thread creation would need to follow the default
|
||||||
|
+ behaviour. */
|
||||||
|
+ if (map->l_ns != LM_ID_BASE && !init_tls)
|
||||||
|
+ continue;
|
||||||
|
memset (__mempcpy (dest, map->l_tls_initimage,
|
||||||
|
map->l_tls_initimage_size), '\0',
|
||||||
|
map->l_tls_blocksize - map->l_tls_initimage_size);
|
||||||
|
@@ -620,7 +631,7 @@ _dl_allocate_tls (void *mem)
|
||||||
|
{
|
||||||
|
return _dl_allocate_tls_init (mem == NULL
|
||||||
|
? _dl_allocate_tls_storage ()
|
||||||
|
- : allocate_dtv (mem));
|
||||||
|
+ : allocate_dtv (mem), true);
|
||||||
|
}
|
||||||
|
rtld_hidden_def (_dl_allocate_tls)
|
||||||
|
|
||||||
|
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||||
|
index b089e5cf4740443e..26c6fb6479c9008c 100644
|
||||||
|
--- a/elf/rtld.c
|
||||||
|
+++ b/elf/rtld.c
|
||||||
|
@@ -2429,7 +2429,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||||
|
into the main thread's TLS area, which we allocated above.
|
||||||
|
Note: thread-local variables must only be accessed after completing
|
||||||
|
the next step. */
|
||||||
|
- _dl_allocate_tls_init (tcbp);
|
||||||
|
+ _dl_allocate_tls_init (tcbp, false);
|
||||||
|
|
||||||
|
/* And finally install it for the main thread. */
|
||||||
|
if (! tls_init_tp_called)
|
||||||
|
diff --git a/elf/tst-audit21.c b/elf/tst-audit21.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..3a47ab64d44421ee
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit21.c
|
||||||
|
@@ -0,0 +1,42 @@
|
||||||
|
+/* Check LD_AUDIT with static TLS.
|
||||||
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <ctype.h>
|
||||||
|
+#include <support/xthread.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+
|
||||||
|
+static volatile __thread int out __attribute__ ((tls_model ("initial-exec")));
|
||||||
|
+
|
||||||
|
+static void *
|
||||||
|
+tf (void *arg)
|
||||||
|
+{
|
||||||
|
+ TEST_COMPARE (out, 0);
|
||||||
|
+ out = isspace (' ');
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int main (int argc, char *argv[])
|
||||||
|
+{
|
||||||
|
+ TEST_COMPARE (out, 0);
|
||||||
|
+ out = isspace (' ');
|
||||||
|
+
|
||||||
|
+ pthread_t t = xpthread_create (NULL, tf, NULL);
|
||||||
|
+ xpthread_join (t);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
diff --git a/elf/tst-auditmod21a.c b/elf/tst-auditmod21a.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..f6d51b5c0531c49d
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-auditmod21a.c
|
||||||
|
@@ -0,0 +1,80 @@
|
||||||
|
+/* Check LD_AUDIT with static TLS.
|
||||||
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <ctype.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <link.h>
|
||||||
|
+
|
||||||
|
+#define tls_ie __attribute__ ((tls_model ("initial-exec")))
|
||||||
|
+
|
||||||
|
+__thread int tls_var0 tls_ie;
|
||||||
|
+__thread int tls_var1 tls_ie = 0x10;
|
||||||
|
+
|
||||||
|
+/* Defined at tst-auditmod21b.so */
|
||||||
|
+extern __thread int tls_var2;
|
||||||
|
+extern __thread int tls_var3;
|
||||||
|
+
|
||||||
|
+static volatile int out;
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+call_libc (void)
|
||||||
|
+{
|
||||||
|
+ /* isspace accesses the initial-exec glibc TLS variables, which are
|
||||||
|
+ setup in glibc initialization. */
|
||||||
|
+ out = isspace (' ');
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_version (unsigned int v)
|
||||||
|
+{
|
||||||
|
+ tls_var0 = 0x1;
|
||||||
|
+ if (tls_var1 != 0x10)
|
||||||
|
+ abort ();
|
||||||
|
+ tls_var1 = 0x20;
|
||||||
|
+
|
||||||
|
+ tls_var2 = 0x2;
|
||||||
|
+ if (tls_var3 != 0x20)
|
||||||
|
+ abort ();
|
||||||
|
+ tls_var3 = 0x40;
|
||||||
|
+
|
||||||
|
+ call_libc ();
|
||||||
|
+
|
||||||
|
+ return LAV_CURRENT;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_objopen (struct link_map* map, Lmid_t lmid, uintptr_t* cookie)
|
||||||
|
+{
|
||||||
|
+ call_libc ();
|
||||||
|
+ *cookie = (uintptr_t) map;
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+la_activity (uintptr_t* cookie, unsigned int flag)
|
||||||
|
+{
|
||||||
|
+ if (tls_var0 != 0x1 || tls_var1 != 0x20)
|
||||||
|
+ abort ();
|
||||||
|
+ call_libc ();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+la_preinit (uintptr_t* cookie)
|
||||||
|
+{
|
||||||
|
+ call_libc ();
|
||||||
|
+}
|
||||||
|
diff --git a/elf/tst-auditmod21b.c b/elf/tst-auditmod21b.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..6ba5335b7514c674
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-auditmod21b.c
|
||||||
|
@@ -0,0 +1,22 @@
|
||||||
|
+/* Check LD_AUDIT with static TLS.
|
||||||
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#define tls_ie __attribute__ ((tls_model ("initial-exec")))
|
||||||
|
+
|
||||||
|
+__thread int tls_var2 tls_ie;
|
||||||
|
+__thread int tls_var3 tls_ie = 0x20;
|
||||||
|
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
|
||||||
|
index 50065bc9bd8a28e5..554a721f814b53c4 100644
|
||||||
|
--- a/nptl/allocatestack.c
|
||||||
|
+++ b/nptl/allocatestack.c
|
||||||
|
@@ -139,7 +139,7 @@ get_cached_stack (size_t *sizep, void **memp)
|
||||||
|
memset (dtv, '\0', (dtv[-1].counter + 1) * sizeof (dtv_t));
|
||||||
|
|
||||||
|
/* Re-initialize the TLS. */
|
||||||
|
- _dl_allocate_tls_init (TLS_TPADJ (result));
|
||||||
|
+ _dl_allocate_tls_init (TLS_TPADJ (result), true);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||||
|
index 686f0a7b9709eb10..a56060d0204cc453 100644
|
||||||
|
--- a/sysdeps/generic/ldsodefs.h
|
||||||
|
+++ b/sysdeps/generic/ldsodefs.h
|
||||||
|
@@ -1254,7 +1254,7 @@ extern void _dl_allocate_static_tls (struct link_map *map) attribute_hidden;
|
||||||
|
/* These are internal entry points to the two halves of _dl_allocate_tls,
|
||||||
|
only used within rtld.c itself at startup time. */
|
||||||
|
extern void *_dl_allocate_tls_storage (void) attribute_hidden;
|
||||||
|
-extern void *_dl_allocate_tls_init (void *);
|
||||||
|
+extern void *_dl_allocate_tls_init (void *, bool);
|
||||||
|
rtld_hidden_proto (_dl_allocate_tls_init)
|
||||||
|
|
||||||
|
/* Deallocate memory allocated with _dl_allocate_tls. */
|
1778
glibc-upstream-2.34-156.patch
Normal file
1778
glibc-upstream-2.34-156.patch
Normal file
File diff suppressed because it is too large
Load Diff
1042
glibc-upstream-2.34-157.patch
Normal file
1042
glibc-upstream-2.34-157.patch
Normal file
File diff suppressed because it is too large
Load Diff
23
glibc-upstream-2.34-158.patch
Normal file
23
glibc-upstream-2.34-158.patch
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
commit 165e7ad459fbba2f89708fba04a55bb3981e884c
|
||||||
|
Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||||
|
Date: Wed Feb 2 14:03:58 2022 +0000
|
||||||
|
|
||||||
|
Fix elf/tst-audit25a with default bind now toolchains
|
||||||
|
|
||||||
|
This test relies on lazy binding for the executable so request that
|
||||||
|
explicitly in case the toolchain defaults to bind now.
|
||||||
|
|
||||||
|
(cherry picked from commit 80a08d0faa9b224019f895800c4d97de4e23e1aa)
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index 0ab3e885f5e35671..9e4e056938a75ddb 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -2133,6 +2133,7 @@ $(objpfx)tst-audit25a: $(objpfx)tst-audit25mod1.so \
|
||||||
|
$(objpfx)tst-audit25mod2.so \
|
||||||
|
$(objpfx)tst-audit25mod3.so \
|
||||||
|
$(objpfx)tst-audit25mod4.so
|
||||||
|
+LDFLAGS-tst-audit25a = -Wl,-z,lazy
|
||||||
|
$(objpfx)tst-audit25mod1.so: $(objpfx)tst-audit25mod3.so
|
||||||
|
LDFLAGS-tst-audit25mod1.so = -Wl,-z,now
|
||||||
|
$(objpfx)tst-audit25mod2.so: $(objpfx)tst-audit25mod4.so
|
27
glibc-upstream-2.34-159.patch
Normal file
27
glibc-upstream-2.34-159.patch
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
commit aabdad371f44defc6046aabdc96af7782a2e94be
|
||||||
|
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||||
|
Date: Sun Feb 6 11:12:24 2022 -0800
|
||||||
|
|
||||||
|
elf: Replace tst-audit24bmod2.so with tst-audit24bmod2
|
||||||
|
|
||||||
|
Replace tst-audit24bmod2.so with tst-audit24bmod2 to silence:
|
||||||
|
|
||||||
|
make[2]: Entering directory '/export/gnu/import/git/gitlab/x86-glibc/elf'
|
||||||
|
Makefile:2201: warning: overriding recipe for target '/export/build/gnu/tools-build/glibc-gitlab/build-x86_64-linux/elf/tst-audit24bmod2.so'
|
||||||
|
../Makerules:765: warning: ignoring old recipe for target '/export/build/gnu/tools-build/glibc-gitlab/build-x86_64-linux/elf/tst-audit24bmod2.so'
|
||||||
|
|
||||||
|
(cherry picked from commit fa7ad1df1915c8a62f50e3a5b7e10f9c7118cd7f)
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index 9e4e056938a75ddb..57059293d0bc86cb 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -888,7 +888,7 @@ extra-test-objs += $(addsuffix .os,$(strip $(modules-names)))
|
||||||
|
# filtmod1.so, tst-big-note-lib.so, tst-ro-dynamic-mod.so have special
|
||||||
|
# rules.
|
||||||
|
modules-names-nobuild := filtmod1 tst-big-note-lib tst-ro-dynamic-mod \
|
||||||
|
- tst-audit24bmod1 tst-audit24bmod2.so
|
||||||
|
+ tst-audit24bmod1 tst-audit24bmod2
|
||||||
|
|
||||||
|
tests += $(tests-static)
|
||||||
|
|
114
glibc-upstream-2.34-160.patch
Normal file
114
glibc-upstream-2.34-160.patch
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
commit 4dca2d3a7b43bf99bd6a567870a3144af4e763ef
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Fri Feb 4 15:54:59 2022 -0300
|
||||||
|
|
||||||
|
hppa: Fix bind-now audit (BZ #28857)
|
||||||
|
|
||||||
|
On hppa, a function pointer returned by la_symbind is actually a function
|
||||||
|
descriptor has the plabel bit set (bit 30). This must be cleared to get
|
||||||
|
the actual address of the descriptor. If the descriptor has been bound,
|
||||||
|
the first word of the descriptor is the physical address of theA function,
|
||||||
|
otherwise, the first word of the descriptor points to a trampoline in the
|
||||||
|
PLT.
|
||||||
|
|
||||||
|
This patch also adds a workaround on tests because on hppa (and it seems
|
||||||
|
to be the only ABI I have see it), some shared library adds a dynamic PLT
|
||||||
|
relocation to am empty symbol name:
|
||||||
|
|
||||||
|
$ readelf -r elf/tst-audit25mod1.so
|
||||||
|
[...]
|
||||||
|
Relocation section '.rela.plt' at offset 0x464 contains 6 entries:
|
||||||
|
Offset Info Type Sym.Value Sym. Name + Addend
|
||||||
|
00002008 00000081 R_PARISC_IPLT 508
|
||||||
|
[...]
|
||||||
|
|
||||||
|
It breaks some assumptions on the test, where a symbol with an empty
|
||||||
|
name ("") is passed on la_symbind.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu and hppa-linux-gnu.
|
||||||
|
|
||||||
|
(cherry picked from commit 9e94f57484a2aba0fe67ea2059b5843f651887c2)
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index 57059293d0bc86cb..3e17a0706f5ec2df 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -2116,7 +2116,7 @@ $(objpfx)tst-audit24c.out: $(objpfx)tst-auditmod24c.so
|
||||||
|
$(objpfx)tst-audit24c: $(objpfx)tst-audit24amod1.so \
|
||||||
|
$(objpfx)tst-audit24amod2.so
|
||||||
|
tst-audit24c-ENV = LD_BIND_NOW=1 LD_AUDIT=$(objpfx)tst-auditmod24c.so
|
||||||
|
-LDFLAGS-tst-audit24b = -Wl,-z,lazy
|
||||||
|
+LDFLAGS-tst-audit24c = -Wl,-z,lazy
|
||||||
|
|
||||||
|
$(objpfx)tst-audit24d.out: $(objpfx)tst-auditmod24d.so
|
||||||
|
$(objpfx)tst-audit24d: $(objpfx)tst-audit24dmod1.so \
|
||||||
|
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
|
||||||
|
index 72a50717ef60a357..ec9b032eae37c103 100644
|
||||||
|
--- a/elf/dl-audit.c
|
||||||
|
+++ b/elf/dl-audit.c
|
||||||
|
@@ -257,7 +257,8 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
|
||||||
|
reloc_result->flags = flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
- DL_FIXUP_BINDNOW_RELOC (value, new_value, sym.st_value);
|
||||||
|
+ if (flags & LA_SYMB_ALTVALUE)
|
||||||
|
+ DL_FIXUP_BINDNOW_RELOC (value, new_value, sym.st_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
diff --git a/elf/tst-auditmod24a.c b/elf/tst-auditmod24a.c
|
||||||
|
index d8e88f3984af1707..3075dfae2fd3d288 100644
|
||||||
|
--- a/elf/tst-auditmod24a.c
|
||||||
|
+++ b/elf/tst-auditmod24a.c
|
||||||
|
@@ -110,5 +110,7 @@ la_symbind32 (Elf32_Sym *sym, unsigned int ndx,
|
||||||
|
return sym->st_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
- abort ();
|
||||||
|
+ if (symname[0] != '\0')
|
||||||
|
+ abort ();
|
||||||
|
+ return sym->st_value;
|
||||||
|
}
|
||||||
|
diff --git a/elf/tst-auditmod24d.c b/elf/tst-auditmod24d.c
|
||||||
|
index 8c803ecc0a48f21b..badc6be451ee0357 100644
|
||||||
|
--- a/elf/tst-auditmod24d.c
|
||||||
|
+++ b/elf/tst-auditmod24d.c
|
||||||
|
@@ -116,5 +116,7 @@ la_symbind32 (Elf32_Sym *sym, unsigned int ndx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- abort ();
|
||||||
|
+ if (symname[0] != '\0')
|
||||||
|
+ abort ();
|
||||||
|
+ return sym->st_value;
|
||||||
|
}
|
||||||
|
diff --git a/elf/tst-auditmod25.c b/elf/tst-auditmod25.c
|
||||||
|
index 526f5c54bc2c3b8c..20640a8daf346b5f 100644
|
||||||
|
--- a/elf/tst-auditmod25.c
|
||||||
|
+++ b/elf/tst-auditmod25.c
|
||||||
|
@@ -72,7 +72,7 @@ la_symbind32 (Elf32_Sym *sym, unsigned int ndx,
|
||||||
|
unsigned int *flags, const char *symname)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
- if (*refcook != -1 && *defcook != -1)
|
||||||
|
+ if (*refcook != -1 && *defcook != -1 && symname[0] != '\0')
|
||||||
|
fprintf (stderr, "la_symbind: %s %u\n", symname,
|
||||||
|
*flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) ? 1 : 0);
|
||||||
|
return sym->st_value;
|
||||||
|
diff --git a/sysdeps/hppa/dl-lookupcfg.h b/sysdeps/hppa/dl-lookupcfg.h
|
||||||
|
index f4f00714fa158e18..92fd0b7c844713ce 100644
|
||||||
|
--- a/sysdeps/hppa/dl-lookupcfg.h
|
||||||
|
+++ b/sysdeps/hppa/dl-lookupcfg.h
|
||||||
|
@@ -80,7 +80,9 @@ void attribute_hidden _dl_unmap (struct link_map *map);
|
||||||
|
/* Extract the code address from a fixup value */
|
||||||
|
#define DL_FIXUP_VALUE_CODE_ADDR(value) ((value).ip)
|
||||||
|
#define DL_FIXUP_VALUE_ADDR(value) ((uintptr_t) &(value))
|
||||||
|
-#define DL_FIXUP_ADDR_VALUE(addr) (*(struct fdesc *) (addr))
|
||||||
|
+/* Clear the plabel bit to get the actual address of the descriptor. */
|
||||||
|
+#define DL_FIXUP_ADDR_VALUE(addr) \
|
||||||
|
+ (*(DL_FIXUP_VALUE_TYPE *) ((uintptr_t) (addr) & ~2))
|
||||||
|
#define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr)
|
||||||
|
-#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \
|
||||||
|
- (*value) = *(struct fdesc *) (st_value)
|
||||||
|
+#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \
|
||||||
|
+ *(value) = *(DL_FIXUP_VALUE_TYPE *) ((uintptr_t) (new_value) & ~2)
|
242
glibc-upstream-2.34-162.patch
Normal file
242
glibc-upstream-2.34-162.patch
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
commit 0c03cb54c808173d8e7ba96f6152dfcf627ac496
|
||||||
|
Author: Stefan Liebler <stli@linux.ibm.com>
|
||||||
|
Date: Wed Apr 13 14:36:09 2022 +0200
|
||||||
|
|
||||||
|
S390: Add new s390 platform z16.
|
||||||
|
|
||||||
|
The new IBM z16 is added to platform string array.
|
||||||
|
The macro _DL_PLATFORMS_COUNT is incremented.
|
||||||
|
|
||||||
|
_dl_hwcaps_subdir is extended by "z16" if HWCAP_S390_VXRS_PDE2
|
||||||
|
is set. HWCAP_S390_NNPA is not tested in _dl_hwcaps_subdirs_active
|
||||||
|
as those instructions may be replaced or removed in future.
|
||||||
|
|
||||||
|
tst-glibc-hwcaps.c is extended in order to test z16 via new marker5.
|
||||||
|
|
||||||
|
A fatal glibc error is dumped if glibc was build with architecture
|
||||||
|
level set for z16, but run on an older machine. (See dl-hwcap-check.h)
|
||||||
|
|
||||||
|
(cherry picked from commit 2376944b9e5c0364b9fb473e4d8dabca31b57167)
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
sysdeps/s390/s390-64/dl-hwcap-check.h - Use GCCMACRO__ARCH__.
|
||||||
|
- Backported f01d482f0355a7029d0715ace0ccf3323e7e94bc requires it.
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index 3e17a0706f5ec2df..8e2dd91c583f9a62 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -571,6 +571,11 @@ modules-names = \
|
||||||
|
libmarkermod4-2 \
|
||||||
|
libmarkermod4-3 \
|
||||||
|
libmarkermod4-4 \
|
||||||
|
+ libmarkermod5-1 \
|
||||||
|
+ libmarkermod5-2 \
|
||||||
|
+ libmarkermod5-3 \
|
||||||
|
+ libmarkermod5-4 \
|
||||||
|
+ libmarkermod5-5 \
|
||||||
|
ltglobmod1 \
|
||||||
|
ltglobmod2 \
|
||||||
|
neededobj1 \
|
||||||
|
@@ -2412,6 +2417,7 @@ LDFLAGS-libmarkermod1-1.so += -Wl,-soname,libmarkermod1.so
|
||||||
|
LDFLAGS-libmarkermod2-1.so += -Wl,-soname,libmarkermod2.so
|
||||||
|
LDFLAGS-libmarkermod3-1.so += -Wl,-soname,libmarkermod3.so
|
||||||
|
LDFLAGS-libmarkermod4-1.so += -Wl,-soname,libmarkermod4.so
|
||||||
|
+LDFLAGS-libmarkermod5-1.so += -Wl,-soname,libmarkermod5.so
|
||||||
|
$(objpfx)libmarkermod%.os : markermodMARKER-VALUE.c
|
||||||
|
$(compile-command.c) \
|
||||||
|
-DMARKER=marker$(firstword $(subst -, ,$*)) \
|
||||||
|
@@ -2424,6 +2430,8 @@ $(objpfx)libmarkermod3.so: $(objpfx)libmarkermod3-1.so
|
||||||
|
cp $< $@
|
||||||
|
$(objpfx)libmarkermod4.so: $(objpfx)libmarkermod4-1.so
|
||||||
|
cp $< $@
|
||||||
|
+$(objpfx)libmarkermod5.so: $(objpfx)libmarkermod5-1.so
|
||||||
|
+ cp $< $@
|
||||||
|
|
||||||
|
# tst-glibc-hwcaps-prepend checks that --glibc-hwcaps-prepend is
|
||||||
|
# preferred over auto-detected subdirectories.
|
||||||
|
diff --git a/elf/tst-glibc-hwcaps-cache.script b/elf/tst-glibc-hwcaps-cache.script
|
||||||
|
index c3271f61f9e50f2e..d58fc8c5de3c5198 100644
|
||||||
|
--- a/elf/tst-glibc-hwcaps-cache.script
|
||||||
|
+++ b/elf/tst-glibc-hwcaps-cache.script
|
||||||
|
@@ -4,6 +4,7 @@
|
||||||
|
cp $B/elf/libmarkermod2-1.so $L/libmarkermod2.so
|
||||||
|
cp $B/elf/libmarkermod3-1.so $L/libmarkermod3.so
|
||||||
|
cp $B/elf/libmarkermod4-1.so $L/libmarkermod4.so
|
||||||
|
+cp $B/elf/libmarkermod5-1.so $L/libmarkermod5.so
|
||||||
|
|
||||||
|
mkdirp 0770 $L/glibc-hwcaps/power9
|
||||||
|
cp $B/elf/libmarkermod2-2.so $L/glibc-hwcaps/power9/libmarkermod2.so
|
||||||
|
@@ -20,6 +21,11 @@ mkdirp 0770 $L/glibc-hwcaps/z15
|
||||||
|
cp $B/elf/libmarkermod4-2.so $L/glibc-hwcaps/z13/libmarkermod4.so
|
||||||
|
cp $B/elf/libmarkermod4-3.so $L/glibc-hwcaps/z14/libmarkermod4.so
|
||||||
|
cp $B/elf/libmarkermod4-4.so $L/glibc-hwcaps/z15/libmarkermod4.so
|
||||||
|
+mkdirp 0770 $L/glibc-hwcaps/z16
|
||||||
|
+cp $B/elf/libmarkermod5-2.so $L/glibc-hwcaps/z13/libmarkermod5.so
|
||||||
|
+cp $B/elf/libmarkermod5-3.so $L/glibc-hwcaps/z14/libmarkermod5.so
|
||||||
|
+cp $B/elf/libmarkermod5-4.so $L/glibc-hwcaps/z15/libmarkermod5.so
|
||||||
|
+cp $B/elf/libmarkermod5-5.so $L/glibc-hwcaps/z16/libmarkermod5.so
|
||||||
|
|
||||||
|
mkdirp 0770 $L/glibc-hwcaps/x86-64-v2
|
||||||
|
cp $B/elf/libmarkermod2-2.so $L/glibc-hwcaps/x86-64-v2/libmarkermod2.so
|
||||||
|
diff --git a/sysdeps/s390/dl-procinfo.c b/sysdeps/s390/dl-procinfo.c
|
||||||
|
index 155f0bd99eccb3f9..755b54ff13a0fa2f 100644
|
||||||
|
--- a/sysdeps/s390/dl-procinfo.c
|
||||||
|
+++ b/sysdeps/s390/dl-procinfo.c
|
||||||
|
@@ -64,11 +64,12 @@ PROCINFO_CLASS const char _dl_s390_cap_flags[23][9]
|
||||||
|
#if !defined PROCINFO_DECL && defined SHARED
|
||||||
|
._dl_s390_platforms
|
||||||
|
#else
|
||||||
|
-PROCINFO_CLASS const char _dl_s390_platforms[10][7]
|
||||||
|
+PROCINFO_CLASS const char _dl_s390_platforms[11][7]
|
||||||
|
#endif
|
||||||
|
#ifndef PROCINFO_DECL
|
||||||
|
= {
|
||||||
|
- "g5", "z900", "z990", "z9-109", "z10", "z196", "zEC12", "z13", "z14", "z15"
|
||||||
|
+ "g5", "z900", "z990", "z9-109", "z10", "z196", "zEC12", "z13", "z14", "z15",
|
||||||
|
+ "z16"
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if !defined SHARED || defined PROCINFO_DECL
|
||||||
|
diff --git a/sysdeps/s390/dl-procinfo.h b/sysdeps/s390/dl-procinfo.h
|
||||||
|
index e4e3e334a5b3d47c..d44e1dd97441bd90 100644
|
||||||
|
--- a/sysdeps/s390/dl-procinfo.h
|
||||||
|
+++ b/sysdeps/s390/dl-procinfo.h
|
||||||
|
@@ -23,7 +23,7 @@
|
||||||
|
|
||||||
|
#define _DL_HWCAP_COUNT 23
|
||||||
|
|
||||||
|
-#define _DL_PLATFORMS_COUNT 10
|
||||||
|
+#define _DL_PLATFORMS_COUNT 11
|
||||||
|
|
||||||
|
/* The kernel provides up to 32 capability bits with elf_hwcap. */
|
||||||
|
#define _DL_FIRST_PLATFORM 32
|
||||||
|
diff --git a/sysdeps/s390/s390-64/Makefile b/sysdeps/s390/s390-64/Makefile
|
||||||
|
index e5da26871c862e63..66ed844e68df5159 100644
|
||||||
|
--- a/sysdeps/s390/s390-64/Makefile
|
||||||
|
+++ b/sysdeps/s390/s390-64/Makefile
|
||||||
|
@@ -7,8 +7,11 @@ CFLAGS-rtld.c += -Wno-uninitialized -Wno-unused
|
||||||
|
CFLAGS-dl-load.c += -Wno-unused
|
||||||
|
CFLAGS-dl-reloc.c += -Wno-unused
|
||||||
|
|
||||||
|
-$(objpfx)tst-glibc-hwcaps: $(objpfx)libmarkermod2-1.so \
|
||||||
|
- $(objpfx)libmarkermod3-1.so $(objpfx)libmarkermod4-1.so
|
||||||
|
+$(objpfx)tst-glibc-hwcaps: \
|
||||||
|
+ $(objpfx)libmarkermod2-1.so \
|
||||||
|
+ $(objpfx)libmarkermod3-1.so \
|
||||||
|
+ $(objpfx)libmarkermod4-1.so \
|
||||||
|
+ $(objpfx)libmarkermod5-1.so
|
||||||
|
$(objpfx)tst-glibc-hwcaps.out: \
|
||||||
|
$(objpfx)libmarkermod2.so \
|
||||||
|
$(objpfx)glibc-hwcaps/z13/libmarkermod2.so \
|
||||||
|
@@ -19,6 +22,11 @@ $(objpfx)tst-glibc-hwcaps.out: \
|
||||||
|
$(objpfx)glibc-hwcaps/z13/libmarkermod4.so \
|
||||||
|
$(objpfx)glibc-hwcaps/z14/libmarkermod4.so \
|
||||||
|
$(objpfx)glibc-hwcaps/z15/libmarkermod4.so \
|
||||||
|
+ $(objpfx)libmarkermod5.so \
|
||||||
|
+ $(objpfx)glibc-hwcaps/z13/libmarkermod5.so \
|
||||||
|
+ $(objpfx)glibc-hwcaps/z14/libmarkermod5.so \
|
||||||
|
+ $(objpfx)glibc-hwcaps/z15/libmarkermod5.so \
|
||||||
|
+ $(objpfx)glibc-hwcaps/z16/libmarkermod5.so
|
||||||
|
|
||||||
|
$(objpfx)glibc-hwcaps/z13/libmarkermod2.so: $(objpfx)libmarkermod2-2.so
|
||||||
|
$(make-target-directory)
|
||||||
|
@@ -38,6 +46,19 @@ $(objpfx)glibc-hwcaps/z14/libmarkermod4.so: $(objpfx)libmarkermod4-3.so
|
||||||
|
$(objpfx)glibc-hwcaps/z15/libmarkermod4.so: $(objpfx)libmarkermod4-4.so
|
||||||
|
$(make-target-directory)
|
||||||
|
cp $< $@
|
||||||
|
+$(objpfx)glibc-hwcaps/z13/libmarkermod5.so: $(objpfx)libmarkermod5-2.so
|
||||||
|
+ $(make-target-directory)
|
||||||
|
+ cp $< $@
|
||||||
|
+$(objpfx)glibc-hwcaps/z14/libmarkermod5.so: $(objpfx)libmarkermod5-3.so
|
||||||
|
+ $(make-target-directory)
|
||||||
|
+ cp $< $@
|
||||||
|
+$(objpfx)glibc-hwcaps/z15/libmarkermod5.so: $(objpfx)libmarkermod5-4.so
|
||||||
|
+ $(make-target-directory)
|
||||||
|
+ cp $< $@
|
||||||
|
+$(objpfx)glibc-hwcaps/z16/libmarkermod5.so: $(objpfx)libmarkermod5-5.so
|
||||||
|
+ $(make-target-directory)
|
||||||
|
+ cp $< $@
|
||||||
|
+
|
||||||
|
|
||||||
|
ifeq (no,$(build-hardcoded-path-in-tests))
|
||||||
|
# This is an ld.so.cache test, and RPATH/RUNPATH in the executable
|
||||||
|
diff --git a/sysdeps/s390/s390-64/dl-hwcap-check.h b/sysdeps/s390/s390-64/dl-hwcap-check.h
|
||||||
|
index 27f7e245b1d1a9e9..52c609571b32f4ab 100644
|
||||||
|
--- a/sysdeps/s390/s390-64/dl-hwcap-check.h
|
||||||
|
+++ b/sysdeps/s390/s390-64/dl-hwcap-check.h
|
||||||
|
@@ -26,7 +26,11 @@ static inline void
|
||||||
|
dl_hwcap_check (void)
|
||||||
|
{
|
||||||
|
#if defined __ARCH__
|
||||||
|
-# if GCCMACRO__ARCH__ >= 13
|
||||||
|
+# if GCCMACRO__ARCH__ >= 14
|
||||||
|
+ if (!(GLRO(dl_hwcap) & HWCAP_S390_VXRS_PDE2))
|
||||||
|
+ _dl_fatal_printf ("\
|
||||||
|
+Fatal glibc error: CPU lacks VXRS_PDE2 support (z16 or later required)\n");
|
||||||
|
+# elif GCCMACRO__ARCH__ >= 13
|
||||||
|
if (!(GLRO(dl_hwcap) & HWCAP_S390_VXRS_EXT2))
|
||||||
|
_dl_fatal_printf ("\
|
||||||
|
Fatal glibc error: CPU lacks VXRS_EXT2 support (z15 or later required)\n");
|
||||||
|
diff --git a/sysdeps/s390/s390-64/dl-hwcaps-subdirs.c b/sysdeps/s390/s390-64/dl-hwcaps-subdirs.c
|
||||||
|
index b9d094f3d73c2d7a..187d732d560c4a62 100644
|
||||||
|
--- a/sysdeps/s390/s390-64/dl-hwcaps-subdirs.c
|
||||||
|
+++ b/sysdeps/s390/s390-64/dl-hwcaps-subdirs.c
|
||||||
|
@@ -19,8 +19,8 @@
|
||||||
|
#include <dl-hwcaps.h>
|
||||||
|
#include <ldsodefs.h>
|
||||||
|
|
||||||
|
-const char _dl_hwcaps_subdirs[] = "z15:z14:z13";
|
||||||
|
-enum { subdirs_count = 3 }; /* Number of components in _dl_hwcaps_subdirs. */
|
||||||
|
+const char _dl_hwcaps_subdirs[] = "z16:z15:z14:z13";
|
||||||
|
+enum { subdirs_count = 4 }; /* Number of components in _dl_hwcaps_subdirs. */
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
_dl_hwcaps_subdirs_active (void)
|
||||||
|
@@ -50,5 +50,12 @@ _dl_hwcaps_subdirs_active (void)
|
||||||
|
return _dl_hwcaps_subdirs_build_bitmask (subdirs_count, active);
|
||||||
|
++active;
|
||||||
|
|
||||||
|
+ /* z16.
|
||||||
|
+ Note: We do not list HWCAP_S390_NNPA here as, according to the Principles of
|
||||||
|
+ Operation, those instructions may be replaced or removed in future. */
|
||||||
|
+ if (!(GLRO (dl_hwcap) & HWCAP_S390_VXRS_PDE2))
|
||||||
|
+ return _dl_hwcaps_subdirs_build_bitmask (subdirs_count, active);
|
||||||
|
+ ++active;
|
||||||
|
+
|
||||||
|
return _dl_hwcaps_subdirs_build_bitmask (subdirs_count, active);
|
||||||
|
}
|
||||||
|
diff --git a/sysdeps/s390/s390-64/tst-glibc-hwcaps.c b/sysdeps/s390/s390-64/tst-glibc-hwcaps.c
|
||||||
|
index 02397a478c552516..f3b8ef3dec80d2d1 100644
|
||||||
|
--- a/sysdeps/s390/s390-64/tst-glibc-hwcaps.c
|
||||||
|
+++ b/sysdeps/s390/s390-64/tst-glibc-hwcaps.c
|
||||||
|
@@ -25,6 +25,7 @@
|
||||||
|
extern int marker2 (void);
|
||||||
|
extern int marker3 (void);
|
||||||
|
extern int marker4 (void);
|
||||||
|
+extern int marker5 (void);
|
||||||
|
|
||||||
|
/* Return the arch level, 10 for the baseline libmarkermod*.so's. */
|
||||||
|
static int
|
||||||
|
@@ -63,9 +64,11 @@ compute_level (void)
|
||||||
|
return 12;
|
||||||
|
if (strcmp (platform, "z15") == 0)
|
||||||
|
return 13;
|
||||||
|
+ if (strcmp (platform, "z16") == 0)
|
||||||
|
+ return 14;
|
||||||
|
printf ("warning: unrecognized AT_PLATFORM value: %s\n", platform);
|
||||||
|
- /* Assume that the new platform supports z15. */
|
||||||
|
- return 13;
|
||||||
|
+ /* Assume that the new platform supports z16. */
|
||||||
|
+ return 14;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
@@ -76,6 +79,7 @@ do_test (void)
|
||||||
|
TEST_COMPARE (marker2 (), MIN (level - 9, 2));
|
||||||
|
TEST_COMPARE (marker3 (), MIN (level - 9, 3));
|
||||||
|
TEST_COMPARE (marker4 (), MIN (level - 9, 4));
|
||||||
|
+ TEST_COMPARE (marker5 (), MIN (level - 9, 5));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
834
glibc-upstream-2.34-163.patch
Normal file
834
glibc-upstream-2.34-163.patch
Normal file
@ -0,0 +1,834 @@
|
|||||||
|
commit 290db09546b260a30137d03ce97a857e6f15b648
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Wed Apr 6 12:24:42 2022 -0300
|
||||||
|
|
||||||
|
nptl: Handle spurious EINTR when thread cancellation is disabled (BZ#29029)
|
||||||
|
|
||||||
|
Some Linux interfaces never restart after being interrupted by a signal
|
||||||
|
handler, regardless of the use of SA_RESTART [1]. It means that for
|
||||||
|
pthread cancellation, if the target thread disables cancellation with
|
||||||
|
pthread_setcancelstate and calls such interfaces (like poll or select),
|
||||||
|
it should not see spurious EINTR failures due the internal SIGCANCEL.
|
||||||
|
|
||||||
|
However recent changes made pthread_cancel to always sent the internal
|
||||||
|
signal, regardless of the target thread cancellation status or type.
|
||||||
|
To fix it, the previous semantic is restored, where the cancel signal
|
||||||
|
is only sent if the target thread has cancelation enabled in
|
||||||
|
asynchronous mode.
|
||||||
|
|
||||||
|
The cancel state and cancel type is moved back to cancelhandling
|
||||||
|
and atomic operation are used to synchronize between threads. The
|
||||||
|
patch essentially revert the following commits:
|
||||||
|
|
||||||
|
8c1c0aae20 nptl: Move cancel type out of cancelhandling
|
||||||
|
2b51742531 nptl: Move cancel state out of cancelhandling
|
||||||
|
26cfbb7162 nptl: Remove CANCELING_BITMASK
|
||||||
|
|
||||||
|
However I changed the atomic operation to follow the internal C11
|
||||||
|
semantic and removed the MACRO usage, it simplifies a bit the
|
||||||
|
resulting code (and removes another usage of the old atomic macros).
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu, i686-linux-gnu, aarch64-linux-gnu,
|
||||||
|
and powerpc64-linux-gnu.
|
||||||
|
|
||||||
|
[1] https://man7.org/linux/man-pages/man7/signal.7.html
|
||||||
|
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Tested-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||||
|
|
||||||
|
(cherry-picked from commit 404656009b459658138ed1bd18f3c6cf3863e6a6)
|
||||||
|
|
||||||
|
diff --git a/manual/process.texi b/manual/process.texi
|
||||||
|
index 28c9531f4294f56e..9307379194c6f666 100644
|
||||||
|
--- a/manual/process.texi
|
||||||
|
+++ b/manual/process.texi
|
||||||
|
@@ -68,8 +68,7 @@ until the subprogram terminates before you can do anything else.
|
||||||
|
@c CLEANUP_HANDLER @ascuplugin @ascuheap @acsmem
|
||||||
|
@c libc_cleanup_region_start @ascuplugin @ascuheap @acsmem
|
||||||
|
@c pthread_cleanup_push_defer @ascuplugin @ascuheap @acsmem
|
||||||
|
-@c __pthread_testcancel @ascuplugin @ascuheap @acsmem
|
||||||
|
-@c CANCEL_ENABLED_AND_CANCELED ok
|
||||||
|
+@c cancel_enabled_and_canceled @ascuplugin @ascuheap @acsmem
|
||||||
|
@c do_cancel @ascuplugin @ascuheap @acsmem
|
||||||
|
@c cancel_handler ok
|
||||||
|
@c kill syscall ok
|
||||||
|
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
|
||||||
|
index 554a721f814b53c4..96101753ec2f4323 100644
|
||||||
|
--- a/nptl/allocatestack.c
|
||||||
|
+++ b/nptl/allocatestack.c
|
||||||
|
@@ -120,8 +120,6 @@ get_cached_stack (size_t *sizep, void **memp)
|
||||||
|
|
||||||
|
/* Cancellation handling is back to the default. */
|
||||||
|
result->cancelhandling = 0;
|
||||||
|
- result->cancelstate = PTHREAD_CANCEL_ENABLE;
|
||||||
|
- result->canceltype = PTHREAD_CANCEL_DEFERRED;
|
||||||
|
result->cleanup = NULL;
|
||||||
|
result->setup_failed = 0;
|
||||||
|
|
||||||
|
diff --git a/nptl/cancellation.c b/nptl/cancellation.c
|
||||||
|
index 05962784d51fb98b..e97d56f97d7a5698 100644
|
||||||
|
--- a/nptl/cancellation.c
|
||||||
|
+++ b/nptl/cancellation.c
|
||||||
|
@@ -31,19 +31,26 @@ int
|
||||||
|
__pthread_enable_asynccancel (void)
|
||||||
|
{
|
||||||
|
struct pthread *self = THREAD_SELF;
|
||||||
|
+ int oldval = atomic_load_relaxed (&self->cancelhandling);
|
||||||
|
|
||||||
|
- int oldval = THREAD_GETMEM (self, canceltype);
|
||||||
|
- THREAD_SETMEM (self, canceltype, PTHREAD_CANCEL_ASYNCHRONOUS);
|
||||||
|
+ while (1)
|
||||||
|
+ {
|
||||||
|
+ int newval = oldval | CANCELTYPE_BITMASK;
|
||||||
|
|
||||||
|
- int ch = THREAD_GETMEM (self, cancelhandling);
|
||||||
|
+ if (newval == oldval)
|
||||||
|
+ break;
|
||||||
|
|
||||||
|
- if (self->cancelstate == PTHREAD_CANCEL_ENABLE
|
||||||
|
- && (ch & CANCELED_BITMASK)
|
||||||
|
- && !(ch & EXITING_BITMASK)
|
||||||
|
- && !(ch & TERMINATED_BITMASK))
|
||||||
|
- {
|
||||||
|
- THREAD_SETMEM (self, result, PTHREAD_CANCELED);
|
||||||
|
- __do_cancel ();
|
||||||
|
+ if (atomic_compare_exchange_weak_acquire (&self->cancelhandling,
|
||||||
|
+ &oldval, newval))
|
||||||
|
+ {
|
||||||
|
+ if (cancel_enabled_and_canceled_and_async (newval))
|
||||||
|
+ {
|
||||||
|
+ self->result = PTHREAD_CANCELED;
|
||||||
|
+ __do_cancel ();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
return oldval;
|
||||||
|
@@ -57,10 +64,29 @@ __pthread_disable_asynccancel (int oldtype)
|
||||||
|
{
|
||||||
|
/* If asynchronous cancellation was enabled before we do not have
|
||||||
|
anything to do. */
|
||||||
|
- if (oldtype == PTHREAD_CANCEL_ASYNCHRONOUS)
|
||||||
|
+ if (oldtype & CANCELTYPE_BITMASK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
struct pthread *self = THREAD_SELF;
|
||||||
|
- self->canceltype = PTHREAD_CANCEL_DEFERRED;
|
||||||
|
+ int newval;
|
||||||
|
+ int oldval = atomic_load_relaxed (&self->cancelhandling);
|
||||||
|
+ do
|
||||||
|
+ {
|
||||||
|
+ newval = oldval & ~CANCELTYPE_BITMASK;
|
||||||
|
+ }
|
||||||
|
+ while (!atomic_compare_exchange_weak_acquire (&self->cancelhandling,
|
||||||
|
+ &oldval, newval));
|
||||||
|
+
|
||||||
|
+ /* We cannot return when we are being canceled. Upon return the
|
||||||
|
+ thread might be things which would have to be undone. The
|
||||||
|
+ following loop should loop until the cancellation signal is
|
||||||
|
+ delivered. */
|
||||||
|
+ while (__glibc_unlikely ((newval & (CANCELING_BITMASK | CANCELED_BITMASK))
|
||||||
|
+ == CANCELING_BITMASK))
|
||||||
|
+ {
|
||||||
|
+ futex_wait_simple ((unsigned int *) &self->cancelhandling, newval,
|
||||||
|
+ FUTEX_PRIVATE);
|
||||||
|
+ newval = atomic_load_relaxed (&self->cancelhandling);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
libc_hidden_def (__pthread_disable_asynccancel)
|
||||||
|
diff --git a/nptl/cleanup_defer.c b/nptl/cleanup_defer.c
|
||||||
|
index 7e858d0df068276b..35ba40fb0247c7cc 100644
|
||||||
|
--- a/nptl/cleanup_defer.c
|
||||||
|
+++ b/nptl/cleanup_defer.c
|
||||||
|
@@ -31,9 +31,22 @@ ___pthread_register_cancel_defer (__pthread_unwind_buf_t *buf)
|
||||||
|
ibuf->priv.data.prev = THREAD_GETMEM (self, cleanup_jmp_buf);
|
||||||
|
ibuf->priv.data.cleanup = THREAD_GETMEM (self, cleanup);
|
||||||
|
|
||||||
|
- /* Disable asynchronous cancellation for now. */
|
||||||
|
- ibuf->priv.data.canceltype = THREAD_GETMEM (self, canceltype);
|
||||||
|
- THREAD_SETMEM (self, canceltype, PTHREAD_CANCEL_DEFERRED);
|
||||||
|
+ int cancelhandling = atomic_load_relaxed (&self->cancelhandling);
|
||||||
|
+ if (__glibc_unlikely (cancelhandling & CANCELTYPE_BITMASK))
|
||||||
|
+ {
|
||||||
|
+ int newval;
|
||||||
|
+ do
|
||||||
|
+ {
|
||||||
|
+ newval = cancelhandling & ~CANCELTYPE_BITMASK;
|
||||||
|
+ }
|
||||||
|
+ while (!atomic_compare_exchange_weak_acquire (&self->cancelhandling,
|
||||||
|
+ &cancelhandling,
|
||||||
|
+ newval));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ibuf->priv.data.canceltype = (cancelhandling & CANCELTYPE_BITMASK
|
||||||
|
+ ? PTHREAD_CANCEL_ASYNCHRONOUS
|
||||||
|
+ : PTHREAD_CANCEL_DEFERRED);
|
||||||
|
|
||||||
|
/* Store the new cleanup handler info. */
|
||||||
|
THREAD_SETMEM (self, cleanup_jmp_buf, (struct pthread_unwind_buf *) buf);
|
||||||
|
@@ -55,9 +68,26 @@ ___pthread_unregister_cancel_restore (__pthread_unwind_buf_t *buf)
|
||||||
|
|
||||||
|
THREAD_SETMEM (self, cleanup_jmp_buf, ibuf->priv.data.prev);
|
||||||
|
|
||||||
|
- THREAD_SETMEM (self, canceltype, ibuf->priv.data.canceltype);
|
||||||
|
- if (ibuf->priv.data.canceltype == PTHREAD_CANCEL_ASYNCHRONOUS)
|
||||||
|
- __pthread_testcancel ();
|
||||||
|
+ if (ibuf->priv.data.canceltype == PTHREAD_CANCEL_DEFERRED)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ int cancelhandling = atomic_load_relaxed (&self->cancelhandling);
|
||||||
|
+ if (cancelhandling & CANCELTYPE_BITMASK)
|
||||||
|
+ {
|
||||||
|
+ int newval;
|
||||||
|
+ do
|
||||||
|
+ {
|
||||||
|
+ newval = cancelhandling | CANCELTYPE_BITMASK;
|
||||||
|
+ }
|
||||||
|
+ while (!atomic_compare_exchange_weak_acquire (&self->cancelhandling,
|
||||||
|
+ &cancelhandling, newval));
|
||||||
|
+
|
||||||
|
+ if (cancel_enabled_and_canceled (cancelhandling))
|
||||||
|
+ {
|
||||||
|
+ self->result = PTHREAD_CANCELED;
|
||||||
|
+ __do_cancel ();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
versioned_symbol (libc, ___pthread_unregister_cancel_restore,
|
||||||
|
__pthread_unregister_cancel_restore, GLIBC_2_34);
|
||||||
|
diff --git a/nptl/descr.h b/nptl/descr.h
|
||||||
|
index dabf980e29615db3..dfef9c4bda075d13 100644
|
||||||
|
--- a/nptl/descr.h
|
||||||
|
+++ b/nptl/descr.h
|
||||||
|
@@ -280,18 +280,27 @@ struct pthread
|
||||||
|
|
||||||
|
/* Flags determining processing of cancellation. */
|
||||||
|
int cancelhandling;
|
||||||
|
+ /* Bit set if cancellation is disabled. */
|
||||||
|
+#define CANCELSTATE_BIT 0
|
||||||
|
+#define CANCELSTATE_BITMASK (1 << CANCELSTATE_BIT)
|
||||||
|
+ /* Bit set if asynchronous cancellation mode is selected. */
|
||||||
|
+#define CANCELTYPE_BIT 1
|
||||||
|
+#define CANCELTYPE_BITMASK (1 << CANCELTYPE_BIT)
|
||||||
|
+ /* Bit set if canceling has been initiated. */
|
||||||
|
+#define CANCELING_BIT 2
|
||||||
|
+#define CANCELING_BITMASK (1 << CANCELING_BIT)
|
||||||
|
/* Bit set if canceled. */
|
||||||
|
#define CANCELED_BIT 3
|
||||||
|
-#define CANCELED_BITMASK (0x01 << CANCELED_BIT)
|
||||||
|
+#define CANCELED_BITMASK (1 << CANCELED_BIT)
|
||||||
|
/* Bit set if thread is exiting. */
|
||||||
|
#define EXITING_BIT 4
|
||||||
|
-#define EXITING_BITMASK (0x01 << EXITING_BIT)
|
||||||
|
+#define EXITING_BITMASK (1 << EXITING_BIT)
|
||||||
|
/* Bit set if thread terminated and TCB is freed. */
|
||||||
|
#define TERMINATED_BIT 5
|
||||||
|
-#define TERMINATED_BITMASK (0x01 << TERMINATED_BIT)
|
||||||
|
+#define TERMINATED_BITMASK (1 << TERMINATED_BIT)
|
||||||
|
/* Bit set if thread is supposed to change XID. */
|
||||||
|
#define SETXID_BIT 6
|
||||||
|
-#define SETXID_BITMASK (0x01 << SETXID_BIT)
|
||||||
|
+#define SETXID_BITMASK (1 << SETXID_BIT)
|
||||||
|
|
||||||
|
/* Flags. Including those copied from the thread attribute. */
|
||||||
|
int flags;
|
||||||
|
@@ -391,14 +400,6 @@ struct pthread
|
||||||
|
/* Indicates whether is a C11 thread created by thrd_creat. */
|
||||||
|
bool c11;
|
||||||
|
|
||||||
|
- /* Thread cancel state (PTHREAD_CANCEL_ENABLE or
|
||||||
|
- PTHREAD_CANCEL_DISABLE). */
|
||||||
|
- unsigned char cancelstate;
|
||||||
|
-
|
||||||
|
- /* Thread cancel type (PTHREAD_CANCEL_DEFERRED or
|
||||||
|
- PTHREAD_CANCEL_ASYNCHRONOUS). */
|
||||||
|
- unsigned char canceltype;
|
||||||
|
-
|
||||||
|
/* Used in __pthread_kill_internal to detected a thread that has
|
||||||
|
exited or is about to exit. exit_lock must only be acquired
|
||||||
|
after blocking signals. */
|
||||||
|
@@ -418,6 +419,22 @@ struct pthread
|
||||||
|
(sizeof (struct pthread) - offsetof (struct pthread, end_padding))
|
||||||
|
} __attribute ((aligned (TCB_ALIGNMENT)));
|
||||||
|
|
||||||
|
+static inline bool
|
||||||
|
+cancel_enabled_and_canceled (int value)
|
||||||
|
+{
|
||||||
|
+ return (value & (CANCELSTATE_BITMASK | CANCELED_BITMASK | EXITING_BITMASK
|
||||||
|
+ | TERMINATED_BITMASK))
|
||||||
|
+ == CANCELED_BITMASK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline bool
|
||||||
|
+cancel_enabled_and_canceled_and_async (int value)
|
||||||
|
+{
|
||||||
|
+ return ((value) & (CANCELSTATE_BITMASK | CANCELTYPE_BITMASK | CANCELED_BITMASK
|
||||||
|
+ | EXITING_BITMASK | TERMINATED_BITMASK))
|
||||||
|
+ == (CANCELTYPE_BITMASK | CANCELED_BITMASK);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* This yields the pointer that TLS support code calls the thread pointer. */
|
||||||
|
#if TLS_TCB_AT_TP
|
||||||
|
# define TLS_TPADJ(pd) (pd)
|
||||||
|
diff --git a/nptl/libc-cleanup.c b/nptl/libc-cleanup.c
|
||||||
|
index 180d15bc9e9a8368..fccb1abe69aa693c 100644
|
||||||
|
--- a/nptl/libc-cleanup.c
|
||||||
|
+++ b/nptl/libc-cleanup.c
|
||||||
|
@@ -27,9 +27,24 @@ __libc_cleanup_push_defer (struct _pthread_cleanup_buffer *buffer)
|
||||||
|
|
||||||
|
buffer->__prev = THREAD_GETMEM (self, cleanup);
|
||||||
|
|
||||||
|
+ int cancelhandling = atomic_load_relaxed (&self->cancelhandling);
|
||||||
|
+
|
||||||
|
/* Disable asynchronous cancellation for now. */
|
||||||
|
- buffer->__canceltype = THREAD_GETMEM (self, canceltype);
|
||||||
|
- THREAD_SETMEM (self, canceltype, PTHREAD_CANCEL_DEFERRED);
|
||||||
|
+ if (__glibc_unlikely (cancelhandling & CANCELTYPE_BITMASK))
|
||||||
|
+ {
|
||||||
|
+ int newval;
|
||||||
|
+ do
|
||||||
|
+ {
|
||||||
|
+ newval = cancelhandling & ~CANCELTYPE_BITMASK;
|
||||||
|
+ }
|
||||||
|
+ while (!atomic_compare_exchange_weak_acquire (&self->cancelhandling,
|
||||||
|
+ &cancelhandling,
|
||||||
|
+ newval));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ buffer->__canceltype = (cancelhandling & CANCELTYPE_BITMASK
|
||||||
|
+ ? PTHREAD_CANCEL_ASYNCHRONOUS
|
||||||
|
+ : PTHREAD_CANCEL_DEFERRED);
|
||||||
|
|
||||||
|
THREAD_SETMEM (self, cleanup, buffer);
|
||||||
|
}
|
||||||
|
@@ -42,8 +57,22 @@ __libc_cleanup_pop_restore (struct _pthread_cleanup_buffer *buffer)
|
||||||
|
|
||||||
|
THREAD_SETMEM (self, cleanup, buffer->__prev);
|
||||||
|
|
||||||
|
- THREAD_SETMEM (self, canceltype, buffer->__canceltype);
|
||||||
|
- if (buffer->__canceltype == PTHREAD_CANCEL_ASYNCHRONOUS)
|
||||||
|
- __pthread_testcancel ();
|
||||||
|
+ int cancelhandling = atomic_load_relaxed (&self->cancelhandling);
|
||||||
|
+ if (cancelhandling & CANCELTYPE_BITMASK)
|
||||||
|
+ {
|
||||||
|
+ int newval;
|
||||||
|
+ do
|
||||||
|
+ {
|
||||||
|
+ newval = cancelhandling | CANCELTYPE_BITMASK;
|
||||||
|
+ }
|
||||||
|
+ while (!atomic_compare_exchange_weak_acquire (&self->cancelhandling,
|
||||||
|
+ &cancelhandling, newval));
|
||||||
|
+
|
||||||
|
+ if (cancel_enabled_and_canceled (cancelhandling))
|
||||||
|
+ {
|
||||||
|
+ self->result = PTHREAD_CANCELED;
|
||||||
|
+ __do_cancel ();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
libc_hidden_def (__libc_cleanup_pop_restore)
|
||||||
|
diff --git a/nptl/pthread_cancel.c b/nptl/pthread_cancel.c
|
||||||
|
index 9bac6e3b76a20312..2680b55586e035fe 100644
|
||||||
|
--- a/nptl/pthread_cancel.c
|
||||||
|
+++ b/nptl/pthread_cancel.c
|
||||||
|
@@ -43,18 +43,29 @@ sigcancel_handler (int sig, siginfo_t *si, void *ctx)
|
||||||
|
|
||||||
|
struct pthread *self = THREAD_SELF;
|
||||||
|
|
||||||
|
- int ch = atomic_load_relaxed (&self->cancelhandling);
|
||||||
|
- /* Cancelation not enabled, not cancelled, or already exitting. */
|
||||||
|
- if (self->cancelstate == PTHREAD_CANCEL_DISABLE
|
||||||
|
- || (ch & CANCELED_BITMASK) == 0
|
||||||
|
- || (ch & EXITING_BITMASK) != 0)
|
||||||
|
- return;
|
||||||
|
-
|
||||||
|
- /* Set the return value. */
|
||||||
|
- THREAD_SETMEM (self, result, PTHREAD_CANCELED);
|
||||||
|
- /* Make sure asynchronous cancellation is still enabled. */
|
||||||
|
- if (self->canceltype == PTHREAD_CANCEL_ASYNCHRONOUS)
|
||||||
|
- __do_cancel ();
|
||||||
|
+ int oldval = atomic_load_relaxed (&self->cancelhandling);
|
||||||
|
+ while (1)
|
||||||
|
+ {
|
||||||
|
+ /* We are canceled now. When canceled by another thread this flag
|
||||||
|
+ is already set but if the signal is directly send (internally or
|
||||||
|
+ from another process) is has to be done here. */
|
||||||
|
+ int newval = oldval | CANCELING_BITMASK | CANCELED_BITMASK;
|
||||||
|
+
|
||||||
|
+ if (oldval == newval || (oldval & EXITING_BITMASK) != 0)
|
||||||
|
+ /* Already canceled or exiting. */
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ if (atomic_compare_exchange_weak_acquire (&self->cancelhandling,
|
||||||
|
+ &oldval, newval))
|
||||||
|
+ {
|
||||||
|
+ self->result = PTHREAD_CANCELED;
|
||||||
|
+
|
||||||
|
+ /* Make sure asynchronous cancellation is still enabled. */
|
||||||
|
+ if ((oldval & CANCELTYPE_BITMASK) != 0)
|
||||||
|
+ /* Run the registered destructors and terminate the thread. */
|
||||||
|
+ __do_cancel ();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
@@ -93,29 +104,70 @@ __pthread_cancel (pthread_t th)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
- int oldch = atomic_fetch_or_acquire (&pd->cancelhandling, CANCELED_BITMASK);
|
||||||
|
- if ((oldch & CANCELED_BITMASK) != 0)
|
||||||
|
- return 0;
|
||||||
|
-
|
||||||
|
- if (pd == THREAD_SELF)
|
||||||
|
+ /* Some syscalls are never restarted after being interrupted by a signal
|
||||||
|
+ handler, regardless of the use of SA_RESTART (they always fail with
|
||||||
|
+ EINTR). So pthread_cancel cannot send SIGCANCEL unless the cancellation
|
||||||
|
+ is enabled and set as asynchronous (in this case the cancellation will
|
||||||
|
+ be acted in the cancellation handler instead by the syscall wrapper).
|
||||||
|
+ Otherwise the target thread is set as 'cancelling' (CANCELING_BITMASK)
|
||||||
|
+ by atomically setting 'cancelhandling' and the cancelation will be acted
|
||||||
|
+ upon on next cancellation entrypoing in the target thread.
|
||||||
|
+
|
||||||
|
+ It also requires to atomically check if cancellation is enabled and
|
||||||
|
+ asynchronous, so both cancellation state and type are tracked on
|
||||||
|
+ 'cancelhandling'. */
|
||||||
|
+
|
||||||
|
+ int result = 0;
|
||||||
|
+ int oldval = atomic_load_relaxed (&pd->cancelhandling);
|
||||||
|
+ int newval;
|
||||||
|
+ do
|
||||||
|
{
|
||||||
|
- /* A single-threaded process should be able to kill itself, since there
|
||||||
|
- is nothing in the POSIX specification that says that it cannot. So
|
||||||
|
- we set multiple_threads to true so that cancellation points get
|
||||||
|
- executed. */
|
||||||
|
- THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1);
|
||||||
|
+ newval = oldval | CANCELING_BITMASK | CANCELED_BITMASK;
|
||||||
|
+ if (oldval == newval)
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ /* If the cancellation is handled asynchronously just send a
|
||||||
|
+ signal. We avoid this if possible since it's more
|
||||||
|
+ expensive. */
|
||||||
|
+ if (cancel_enabled_and_canceled_and_async (newval))
|
||||||
|
+ {
|
||||||
|
+ /* Mark the cancellation as "in progress". */
|
||||||
|
+ int newval2 = oldval | CANCELING_BITMASK;
|
||||||
|
+ if (!atomic_compare_exchange_weak_acquire (&pd->cancelhandling,
|
||||||
|
+ &oldval, newval2))
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ if (pd == THREAD_SELF)
|
||||||
|
+ /* This is not merely an optimization: An application may
|
||||||
|
+ call pthread_cancel (pthread_self ()) without calling
|
||||||
|
+ pthread_create, so the signal handler may not have been
|
||||||
|
+ set up for a self-cancel. */
|
||||||
|
+ {
|
||||||
|
+ pd->result = PTHREAD_CANCELED;
|
||||||
|
+ if ((newval & CANCELTYPE_BITMASK) != 0)
|
||||||
|
+ __do_cancel ();
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ /* The cancellation handler will take care of marking the
|
||||||
|
+ thread as canceled. */
|
||||||
|
+ result = __pthread_kill_internal (th, SIGCANCEL);
|
||||||
|
+
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* A single-threaded process should be able to kill itself, since
|
||||||
|
+ there is nothing in the POSIX specification that says that it
|
||||||
|
+ cannot. So we set multiple_threads to true so that cancellation
|
||||||
|
+ points get executed. */
|
||||||
|
+ THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1);
|
||||||
|
#ifndef TLS_MULTIPLE_THREADS_IN_TCB
|
||||||
|
__libc_multiple_threads = 1;
|
||||||
|
#endif
|
||||||
|
-
|
||||||
|
- THREAD_SETMEM (pd, result, PTHREAD_CANCELED);
|
||||||
|
- if (pd->cancelstate == PTHREAD_CANCEL_ENABLE
|
||||||
|
- && pd->canceltype == PTHREAD_CANCEL_ASYNCHRONOUS)
|
||||||
|
- __do_cancel ();
|
||||||
|
- return 0;
|
||||||
|
}
|
||||||
|
+ while (!atomic_compare_exchange_weak_acquire (&pd->cancelhandling, &oldval,
|
||||||
|
+ newval));
|
||||||
|
|
||||||
|
- return __pthread_kill_internal (th, SIGCANCEL);
|
||||||
|
+ return result;
|
||||||
|
}
|
||||||
|
versioned_symbol (libc, __pthread_cancel, pthread_cancel, GLIBC_2_34);
|
||||||
|
|
||||||
|
diff --git a/nptl/pthread_join_common.c b/nptl/pthread_join_common.c
|
||||||
|
index 7303069316caef13..617056ef10671607 100644
|
||||||
|
--- a/nptl/pthread_join_common.c
|
||||||
|
+++ b/nptl/pthread_join_common.c
|
||||||
|
@@ -57,12 +57,9 @@ __pthread_clockjoin_ex (pthread_t threadid, void **thread_return,
|
||||||
|
if ((pd == self
|
||||||
|
|| (self->joinid == pd
|
||||||
|
&& (pd->cancelhandling
|
||||||
|
- & (CANCELED_BITMASK | EXITING_BITMASK
|
||||||
|
+ & (CANCELING_BITMASK | CANCELED_BITMASK | EXITING_BITMASK
|
||||||
|
| TERMINATED_BITMASK)) == 0))
|
||||||
|
- && !(self->cancelstate == PTHREAD_CANCEL_ENABLE
|
||||||
|
- && (pd->cancelhandling & (CANCELED_BITMASK | EXITING_BITMASK
|
||||||
|
- | TERMINATED_BITMASK))
|
||||||
|
- == CANCELED_BITMASK))
|
||||||
|
+ && !cancel_enabled_and_canceled (self->cancelhandling))
|
||||||
|
/* This is a deadlock situation. The threads are waiting for each
|
||||||
|
other to finish. Note that this is a "may" error. To be 100%
|
||||||
|
sure we catch this error we would have to lock the data
|
||||||
|
diff --git a/nptl/pthread_setcancelstate.c b/nptl/pthread_setcancelstate.c
|
||||||
|
index 7e2b6e4974bd58bd..cb567be5926816f1 100644
|
||||||
|
--- a/nptl/pthread_setcancelstate.c
|
||||||
|
+++ b/nptl/pthread_setcancelstate.c
|
||||||
|
@@ -31,9 +31,29 @@ __pthread_setcancelstate (int state, int *oldstate)
|
||||||
|
|
||||||
|
self = THREAD_SELF;
|
||||||
|
|
||||||
|
- if (oldstate != NULL)
|
||||||
|
- *oldstate = self->cancelstate;
|
||||||
|
- self->cancelstate = state;
|
||||||
|
+ int oldval = atomic_load_relaxed (&self->cancelhandling);
|
||||||
|
+ while (1)
|
||||||
|
+ {
|
||||||
|
+ int newval = (state == PTHREAD_CANCEL_DISABLE
|
||||||
|
+ ? oldval | CANCELSTATE_BITMASK
|
||||||
|
+ : oldval & ~CANCELSTATE_BITMASK);
|
||||||
|
+
|
||||||
|
+ if (oldstate != NULL)
|
||||||
|
+ *oldstate = ((oldval & CANCELSTATE_BITMASK)
|
||||||
|
+ ? PTHREAD_CANCEL_DISABLE : PTHREAD_CANCEL_ENABLE);
|
||||||
|
+
|
||||||
|
+ if (oldval == newval)
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ if (atomic_compare_exchange_weak_acquire (&self->cancelhandling,
|
||||||
|
+ &oldval, newval))
|
||||||
|
+ {
|
||||||
|
+ if (cancel_enabled_and_canceled_and_async (newval))
|
||||||
|
+ __do_cancel ();
|
||||||
|
+
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
diff --git a/nptl/pthread_setcanceltype.c b/nptl/pthread_setcanceltype.c
|
||||||
|
index e7b24ae733dcc0f2..e08ff7b141f904f1 100644
|
||||||
|
--- a/nptl/pthread_setcanceltype.c
|
||||||
|
+++ b/nptl/pthread_setcanceltype.c
|
||||||
|
@@ -29,11 +29,32 @@ __pthread_setcanceltype (int type, int *oldtype)
|
||||||
|
|
||||||
|
volatile struct pthread *self = THREAD_SELF;
|
||||||
|
|
||||||
|
- if (oldtype != NULL)
|
||||||
|
- *oldtype = self->canceltype;
|
||||||
|
- self->canceltype = type;
|
||||||
|
- if (type == PTHREAD_CANCEL_ASYNCHRONOUS)
|
||||||
|
- __pthread_testcancel ();
|
||||||
|
+ int oldval = atomic_load_relaxed (&self->cancelhandling);
|
||||||
|
+ while (1)
|
||||||
|
+ {
|
||||||
|
+ int newval = (type == PTHREAD_CANCEL_ASYNCHRONOUS
|
||||||
|
+ ? oldval | CANCELTYPE_BITMASK
|
||||||
|
+ : oldval & ~CANCELTYPE_BITMASK);
|
||||||
|
+
|
||||||
|
+ if (oldtype != NULL)
|
||||||
|
+ *oldtype = ((oldval & CANCELTYPE_BITMASK)
|
||||||
|
+ ? PTHREAD_CANCEL_ASYNCHRONOUS : PTHREAD_CANCEL_DEFERRED);
|
||||||
|
+
|
||||||
|
+ if (oldval == newval)
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ if (atomic_compare_exchange_weak_acquire (&self->cancelhandling,
|
||||||
|
+ &oldval, newval))
|
||||||
|
+ {
|
||||||
|
+ if (cancel_enabled_and_canceled_and_async (newval))
|
||||||
|
+ {
|
||||||
|
+ THREAD_SETMEM (self, result, PTHREAD_CANCELED);
|
||||||
|
+ __do_cancel ();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
diff --git a/nptl/pthread_testcancel.c b/nptl/pthread_testcancel.c
|
||||||
|
index 31185d89f2ab84c6..25230215fd607e8b 100644
|
||||||
|
--- a/nptl/pthread_testcancel.c
|
||||||
|
+++ b/nptl/pthread_testcancel.c
|
||||||
|
@@ -24,13 +24,10 @@ void
|
||||||
|
___pthread_testcancel (void)
|
||||||
|
{
|
||||||
|
struct pthread *self = THREAD_SELF;
|
||||||
|
- int cancelhandling = THREAD_GETMEM (self, cancelhandling);
|
||||||
|
- if (self->cancelstate == PTHREAD_CANCEL_ENABLE
|
||||||
|
- && (cancelhandling & CANCELED_BITMASK)
|
||||||
|
- && !(cancelhandling & EXITING_BITMASK)
|
||||||
|
- && !(cancelhandling & TERMINATED_BITMASK))
|
||||||
|
+ int cancelhandling = atomic_load_relaxed (&self->cancelhandling);
|
||||||
|
+ if (cancel_enabled_and_canceled (cancelhandling))
|
||||||
|
{
|
||||||
|
- THREAD_SETMEM (self, result, PTHREAD_CANCELED);
|
||||||
|
+ self->result = PTHREAD_CANCELED;
|
||||||
|
__do_cancel ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c
|
||||||
|
index b39dfbff2c6678d5..23aa4cfc0b784dfc 100644
|
||||||
|
--- a/sysdeps/nptl/dl-tls_init_tp.c
|
||||||
|
+++ b/sysdeps/nptl/dl-tls_init_tp.c
|
||||||
|
@@ -107,7 +107,4 @@ __tls_init_tp (void)
|
||||||
|
It will be bigger than it actually is, but for unwind.c/pt-longjmp.c
|
||||||
|
purposes this is good enough. */
|
||||||
|
THREAD_SETMEM (pd, stackblock_size, (size_t) __libc_stack_end);
|
||||||
|
-
|
||||||
|
- THREAD_SETMEM (pd, cancelstate, PTHREAD_CANCEL_ENABLE);
|
||||||
|
- THREAD_SETMEM (pd, canceltype, PTHREAD_CANCEL_DEFERRED);
|
||||||
|
}
|
||||||
|
diff --git a/sysdeps/nptl/pthreadP.h b/sysdeps/nptl/pthreadP.h
|
||||||
|
index 374657a2fd0ee19a..b968afc4c6b61b92 100644
|
||||||
|
--- a/sysdeps/nptl/pthreadP.h
|
||||||
|
+++ b/sysdeps/nptl/pthreadP.h
|
||||||
|
@@ -276,7 +276,7 @@ __do_cancel (void)
|
||||||
|
struct pthread *self = THREAD_SELF;
|
||||||
|
|
||||||
|
/* Make sure we get no more cancellations. */
|
||||||
|
- THREAD_ATOMIC_BIT_SET (self, cancelhandling, EXITING_BIT);
|
||||||
|
+ atomic_bit_set (&self->cancelhandling, EXITING_BIT);
|
||||||
|
|
||||||
|
__pthread_unwind ((__pthread_unwind_buf_t *)
|
||||||
|
THREAD_GETMEM (self, cleanup_jmp_buf));
|
||||||
|
diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile
|
||||||
|
index c65710169697ad95..00419c4d199df912 100644
|
||||||
|
--- a/sysdeps/pthread/Makefile
|
||||||
|
+++ b/sysdeps/pthread/Makefile
|
||||||
|
@@ -69,6 +69,7 @@ tests += tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \
|
||||||
|
tst-cancel12 tst-cancel13 tst-cancel14 tst-cancel15 tst-cancel16 \
|
||||||
|
tst-cancel18 tst-cancel19 tst-cancel20 tst-cancel21 \
|
||||||
|
tst-cancel22 tst-cancel23 tst-cancel26 tst-cancel27 tst-cancel28 \
|
||||||
|
+ tst-cancel29 \
|
||||||
|
tst-cleanup0 tst-cleanup1 tst-cleanup2 tst-cleanup3 \
|
||||||
|
tst-clock1 \
|
||||||
|
tst-cond-except \
|
||||||
|
diff --git a/sysdeps/pthread/tst-cancel29.c b/sysdeps/pthread/tst-cancel29.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..4f0d99e002883be4
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/sysdeps/pthread/tst-cancel29.c
|
||||||
|
@@ -0,0 +1,207 @@
|
||||||
|
+/* Check if a thread that disables cancellation and which call functions
|
||||||
|
+ that might be interrupted by a signal do not see the internal SIGCANCEL.
|
||||||
|
+
|
||||||
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <array_length.h>
|
||||||
|
+#include <errno.h>
|
||||||
|
+#include <inttypes.h>
|
||||||
|
+#include <poll.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/support.h>
|
||||||
|
+#include <support/temp_file.h>
|
||||||
|
+#include <support/xthread.h>
|
||||||
|
+#include <sys/socket.h>
|
||||||
|
+#include <signal.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+
|
||||||
|
+/* On Linux some interfaces are never restarted after being interrupted by
|
||||||
|
+ a signal handler, regardless of the use of SA_RESTART. It means that
|
||||||
|
+ if asynchronous cancellation is not enabled, the pthread_cancel can not
|
||||||
|
+ set the internal SIGCANCEL otherwise the interface might see a spurious
|
||||||
|
+ EINTR failure. */
|
||||||
|
+
|
||||||
|
+static pthread_barrier_t b;
|
||||||
|
+
|
||||||
|
+/* Cleanup handling test. */
|
||||||
|
+static int cl_called;
|
||||||
|
+static void
|
||||||
|
+cl (void *arg)
|
||||||
|
+{
|
||||||
|
+ ++cl_called;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void *
|
||||||
|
+tf_sigtimedwait (void *arg)
|
||||||
|
+{
|
||||||
|
+ pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL);
|
||||||
|
+ xpthread_barrier_wait (&b);
|
||||||
|
+
|
||||||
|
+ int r;
|
||||||
|
+ pthread_cleanup_push (cl, NULL);
|
||||||
|
+
|
||||||
|
+ sigset_t mask;
|
||||||
|
+ sigemptyset (&mask);
|
||||||
|
+ r = sigtimedwait (&mask, NULL, &(struct timespec) { 0, 250000000 });
|
||||||
|
+ if (r != -1)
|
||||||
|
+ return (void*) -1;
|
||||||
|
+ if (errno != EAGAIN)
|
||||||
|
+ return (void*) -2;
|
||||||
|
+
|
||||||
|
+ pthread_cleanup_pop (0);
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void *
|
||||||
|
+tf_poll (void *arg)
|
||||||
|
+{
|
||||||
|
+ pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL);
|
||||||
|
+ xpthread_barrier_wait (&b);
|
||||||
|
+
|
||||||
|
+ int r;
|
||||||
|
+ pthread_cleanup_push (cl, NULL);
|
||||||
|
+
|
||||||
|
+ r = poll (NULL, 0, 250);
|
||||||
|
+ if (r != 0)
|
||||||
|
+ return (void*) -1;
|
||||||
|
+
|
||||||
|
+ pthread_cleanup_pop (0);
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void *
|
||||||
|
+tf_ppoll (void *arg)
|
||||||
|
+{
|
||||||
|
+ pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL);
|
||||||
|
+
|
||||||
|
+ xpthread_barrier_wait (&b);
|
||||||
|
+
|
||||||
|
+ int r;
|
||||||
|
+ pthread_cleanup_push (cl, NULL);
|
||||||
|
+
|
||||||
|
+ r = ppoll (NULL, 0, &(struct timespec) { 0, 250000000 }, NULL);
|
||||||
|
+ if (r != 0)
|
||||||
|
+ return (void*) -1;
|
||||||
|
+
|
||||||
|
+ pthread_cleanup_pop (0);
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void *
|
||||||
|
+tf_select (void *arg)
|
||||||
|
+{
|
||||||
|
+ pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL);
|
||||||
|
+ xpthread_barrier_wait (&b);
|
||||||
|
+
|
||||||
|
+ int r;
|
||||||
|
+ pthread_cleanup_push (cl, NULL);
|
||||||
|
+
|
||||||
|
+ r = select (0, NULL, NULL, NULL, &(struct timeval) { 0, 250000 });
|
||||||
|
+ if (r != 0)
|
||||||
|
+ return (void*) -1;
|
||||||
|
+
|
||||||
|
+ pthread_cleanup_pop (0);
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void *
|
||||||
|
+tf_pselect (void *arg)
|
||||||
|
+{
|
||||||
|
+ pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL);
|
||||||
|
+ xpthread_barrier_wait (&b);
|
||||||
|
+
|
||||||
|
+ int r;
|
||||||
|
+ pthread_cleanup_push (cl, NULL);
|
||||||
|
+
|
||||||
|
+ r = pselect (0, NULL, NULL, NULL, &(struct timespec) { 0, 250000000 }, NULL);
|
||||||
|
+ if (r != 0)
|
||||||
|
+ return (void*) -1;
|
||||||
|
+
|
||||||
|
+ pthread_cleanup_pop (0);
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void *
|
||||||
|
+tf_clock_nanosleep (void *arg)
|
||||||
|
+{
|
||||||
|
+ pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL);
|
||||||
|
+ xpthread_barrier_wait (&b);
|
||||||
|
+
|
||||||
|
+ int r;
|
||||||
|
+ pthread_cleanup_push (cl, NULL);
|
||||||
|
+
|
||||||
|
+ r = clock_nanosleep (CLOCK_REALTIME, 0, &(struct timespec) { 0, 250000000 },
|
||||||
|
+ NULL);
|
||||||
|
+ if (r != 0)
|
||||||
|
+ return (void*) -1;
|
||||||
|
+
|
||||||
|
+ pthread_cleanup_pop (0);
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+struct cancel_test_t
|
||||||
|
+{
|
||||||
|
+ const char *name;
|
||||||
|
+ void * (*cf) (void *);
|
||||||
|
+} tests[] =
|
||||||
|
+{
|
||||||
|
+ { "sigtimedwait", tf_sigtimedwait, },
|
||||||
|
+ { "poll", tf_poll, },
|
||||||
|
+ { "ppoll", tf_ppoll, },
|
||||||
|
+ { "select", tf_select, },
|
||||||
|
+ { "pselect", tf_pselect , },
|
||||||
|
+ { "clock_nanosleep", tf_clock_nanosleep, },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ for (int i = 0; i < array_length (tests); i++)
|
||||||
|
+ {
|
||||||
|
+ xpthread_barrier_init (&b, NULL, 2);
|
||||||
|
+
|
||||||
|
+ cl_called = 0;
|
||||||
|
+
|
||||||
|
+ pthread_t th = xpthread_create (NULL, tests[i].cf, NULL);
|
||||||
|
+
|
||||||
|
+ xpthread_barrier_wait (&b);
|
||||||
|
+
|
||||||
|
+ struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 };
|
||||||
|
+ while (nanosleep (&ts, &ts) != 0)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ xpthread_cancel (th);
|
||||||
|
+
|
||||||
|
+ void *status = xpthread_join (th);
|
||||||
|
+ if (status != NULL)
|
||||||
|
+ printf ("test '%s' failed: %" PRIdPTR "\n", tests[i].name,
|
||||||
|
+ (intptr_t) status);
|
||||||
|
+ TEST_VERIFY (status == NULL);
|
||||||
|
+
|
||||||
|
+ xpthread_barrier_destroy (&b);
|
||||||
|
+
|
||||||
|
+ TEST_COMPARE (cl_called, 0);
|
||||||
|
+
|
||||||
|
+ printf ("in-time cancel test of '%s' successful\n", tests[i].name);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
23
glibc-upstream-2.34-164.patch
Normal file
23
glibc-upstream-2.34-164.patch
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
commit 5d8c7776343b3f1b96ef7777e4504378f23c041a
|
||||||
|
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
|
||||||
|
Date: Tue Apr 12 22:14:34 2022 +0200
|
||||||
|
|
||||||
|
hurd: Fix arbitrary error code
|
||||||
|
|
||||||
|
ELIBBAD is Linux-specific.
|
||||||
|
|
||||||
|
(cherry picked from commit 67ab66541dc1164540abda284645e38be90b5119)
|
||||||
|
|
||||||
|
diff --git a/nss/nss_test_errno.c b/nss/nss_test_errno.c
|
||||||
|
index 680f8a07b97fe263..59a5c717bebd296f 100644
|
||||||
|
--- a/nss/nss_test_errno.c
|
||||||
|
+++ b/nss/nss_test_errno.c
|
||||||
|
@@ -28,7 +28,7 @@ static void __attribute__ ((constructor))
|
||||||
|
init (void)
|
||||||
|
{
|
||||||
|
/* An arbitrary error code which is otherwise not used. */
|
||||||
|
- errno = ELIBBAD;
|
||||||
|
+ errno = -1009;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lookup functions for pwd follow that do not return any data. */
|
104
glibc-upstream-2.34-165.patch
Normal file
104
glibc-upstream-2.34-165.patch
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
commit b87b697f15d6bf7e576a2eeadc1f740172f9d013
|
||||||
|
Author: =Joshua Kinard <kumba@gentoo.org>
|
||||||
|
Date: Mon Apr 18 09:55:08 2022 -0300
|
||||||
|
|
||||||
|
mips: Fix mips64n32 64 bit time_t stat support (BZ#29069)
|
||||||
|
|
||||||
|
Add missing support initially added by 4e8521333bea6e89fcef1020
|
||||||
|
(which missed n32 stat).
|
||||||
|
|
||||||
|
(cherry picked from commit 78fb88827362fbd2cc8aa32892ae5b015106e25c)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h b/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h
|
||||||
|
index ab9f474cbc271b7c..ed5b1bc00ba52406 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h
|
||||||
|
@@ -131,27 +131,30 @@ struct stat64
|
||||||
|
|
||||||
|
struct stat
|
||||||
|
{
|
||||||
|
+# ifdef __USE_TIME_BITS64
|
||||||
|
+# include <bits/struct_stat_time64_helper.h>
|
||||||
|
+# else
|
||||||
|
__dev_t st_dev;
|
||||||
|
int st_pad1[3]; /* Reserved for st_dev expansion */
|
||||||
|
-# ifndef __USE_FILE_OFFSET64
|
||||||
|
+# ifndef __USE_FILE_OFFSET64
|
||||||
|
__ino_t st_ino;
|
||||||
|
-# else
|
||||||
|
+# else
|
||||||
|
__ino64_t st_ino;
|
||||||
|
-# endif
|
||||||
|
+# endif
|
||||||
|
__mode_t st_mode;
|
||||||
|
__nlink_t st_nlink;
|
||||||
|
__uid_t st_uid;
|
||||||
|
__gid_t st_gid;
|
||||||
|
__dev_t st_rdev;
|
||||||
|
-# if !defined __USE_FILE_OFFSET64
|
||||||
|
+# if !defined __USE_FILE_OFFSET64
|
||||||
|
unsigned int st_pad2[2]; /* Reserved for st_rdev expansion */
|
||||||
|
__off_t st_size;
|
||||||
|
int st_pad3;
|
||||||
|
-# else
|
||||||
|
+# else
|
||||||
|
unsigned int st_pad2[3]; /* Reserved for st_rdev expansion */
|
||||||
|
__off64_t st_size;
|
||||||
|
-# endif
|
||||||
|
-# ifdef __USE_XOPEN2K8
|
||||||
|
+# endif
|
||||||
|
+# ifdef __USE_XOPEN2K8
|
||||||
|
/* Nanosecond resolution timestamps are stored in a format
|
||||||
|
equivalent to 'struct timespec'. This is the type used
|
||||||
|
whenever possible but the Unix namespace rules do not allow the
|
||||||
|
@@ -161,30 +164,34 @@ struct stat
|
||||||
|
struct timespec st_atim; /* Time of last access. */
|
||||||
|
struct timespec st_mtim; /* Time of last modification. */
|
||||||
|
struct timespec st_ctim; /* Time of last status change. */
|
||||||
|
-# define st_atime st_atim.tv_sec /* Backward compatibility. */
|
||||||
|
-# define st_mtime st_mtim.tv_sec
|
||||||
|
-# define st_ctime st_ctim.tv_sec
|
||||||
|
-# else
|
||||||
|
+# define st_atime st_atim.tv_sec /* Backward compatibility. */
|
||||||
|
+# define st_mtime st_mtim.tv_sec
|
||||||
|
+# define st_ctime st_ctim.tv_sec
|
||||||
|
+# else
|
||||||
|
__time_t st_atime; /* Time of last access. */
|
||||||
|
unsigned long int st_atimensec; /* Nscecs of last access. */
|
||||||
|
__time_t st_mtime; /* Time of last modification. */
|
||||||
|
unsigned long int st_mtimensec; /* Nsecs of last modification. */
|
||||||
|
__time_t st_ctime; /* Time of last status change. */
|
||||||
|
unsigned long int st_ctimensec; /* Nsecs of last status change. */
|
||||||
|
-# endif
|
||||||
|
+# endif
|
||||||
|
__blksize_t st_blksize;
|
||||||
|
unsigned int st_pad4;
|
||||||
|
-# ifndef __USE_FILE_OFFSET64
|
||||||
|
+# ifndef __USE_FILE_OFFSET64
|
||||||
|
__blkcnt_t st_blocks;
|
||||||
|
-# else
|
||||||
|
+# else
|
||||||
|
__blkcnt64_t st_blocks;
|
||||||
|
-# endif
|
||||||
|
+# endif
|
||||||
|
int st_pad5[14];
|
||||||
|
+# endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __USE_LARGEFILE64
|
||||||
|
struct stat64
|
||||||
|
{
|
||||||
|
+# ifdef __USE_TIME_BITS64
|
||||||
|
+# include <bits/struct_stat_time64_helper.h>
|
||||||
|
+# else
|
||||||
|
__dev_t st_dev;
|
||||||
|
unsigned int st_pad1[3]; /* Reserved for st_dev expansion */
|
||||||
|
__ino64_t st_ino;
|
||||||
|
@@ -217,6 +224,7 @@ struct stat64
|
||||||
|
unsigned int st_pad3;
|
||||||
|
__blkcnt64_t st_blocks;
|
||||||
|
int st_pad4[14];
|
||||||
|
+# endif /* __USE_TIME_BITS64 */
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
35
glibc-upstream-2.34-166.patch
Normal file
35
glibc-upstream-2.34-166.patch
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
commit 71326f1f2fd09dafb9c34404765fb88129e94237
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Wed Apr 20 12:01:43 2022 -0300
|
||||||
|
|
||||||
|
nptl: Fix pthread_cancel cancelhandling atomic operations
|
||||||
|
|
||||||
|
The 404656009b reversion did not setup the atomic loop to set the
|
||||||
|
cancel bits correctly. The fix is essentially what pthread_cancel
|
||||||
|
did prior 26cfbb7162ad.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu and aarch64-linux-gnu.
|
||||||
|
|
||||||
|
(cherry picked from commit 62be9681677e7ce820db721c126909979382d379)
|
||||||
|
|
||||||
|
diff --git a/nptl/pthread_cancel.c b/nptl/pthread_cancel.c
|
||||||
|
index 2680b55586e035fe..64fd183fde59907b 100644
|
||||||
|
--- a/nptl/pthread_cancel.c
|
||||||
|
+++ b/nptl/pthread_cancel.c
|
||||||
|
@@ -122,6 +122,7 @@ __pthread_cancel (pthread_t th)
|
||||||
|
int newval;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
+ again:
|
||||||
|
newval = oldval | CANCELING_BITMASK | CANCELED_BITMASK;
|
||||||
|
if (oldval == newval)
|
||||||
|
break;
|
||||||
|
@@ -135,7 +136,7 @@ __pthread_cancel (pthread_t th)
|
||||||
|
int newval2 = oldval | CANCELING_BITMASK;
|
||||||
|
if (!atomic_compare_exchange_weak_acquire (&pd->cancelhandling,
|
||||||
|
&oldval, newval2))
|
||||||
|
- continue;
|
||||||
|
+ goto again;
|
||||||
|
|
||||||
|
if (pd == THREAD_SELF)
|
||||||
|
/* This is not merely an optimization: An application may
|
1446
glibc-upstream-2.34-167.patch
Normal file
1446
glibc-upstream-2.34-167.patch
Normal file
File diff suppressed because it is too large
Load Diff
407
glibc-upstream-2.34-168.patch
Normal file
407
glibc-upstream-2.34-168.patch
Normal file
@ -0,0 +1,407 @@
|
|||||||
|
commit f0c71b34f96c816292c49122d50da3a511b67bf2
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Mon Apr 11 11:30:31 2022 +0200
|
||||||
|
|
||||||
|
Default to --with-default-link=no (bug 25812)
|
||||||
|
|
||||||
|
This is necessary to place the libio vtables into the RELRO segment.
|
||||||
|
New tests elf/tst-relro-ldso and elf/tst-relro-libc are added to
|
||||||
|
verify that this is what actually happens.
|
||||||
|
|
||||||
|
The new tests fail on ia64 due to lack of (default) RELRO support
|
||||||
|
inbutils, so they are XFAILed there.
|
||||||
|
|
||||||
|
(cherry picked from commit 198abcbb94618730dae1b3f4393efaa49e0ec8c7)
|
||||||
|
|
||||||
|
diff --git a/INSTALL b/INSTALL
|
||||||
|
index d8d4e9f155f56616..60d01568d77645c7 100644
|
||||||
|
--- a/INSTALL
|
||||||
|
+++ b/INSTALL
|
||||||
|
@@ -90,6 +90,12 @@ if 'CFLAGS' is specified it must enable optimization. For example:
|
||||||
|
library will still be usable, but functionality may be lost--for
|
||||||
|
example, you can't build a shared libc with old binutils.
|
||||||
|
|
||||||
|
+'--with-default-link=FLAG'
|
||||||
|
+ With '--with-default-link=yes', the build system does not use a
|
||||||
|
+ custom linker script for linking shared objects. The default for
|
||||||
|
+ FLAG is the opposite, 'no', because the custom linker script is
|
||||||
|
+ needed for full RELRO protection.
|
||||||
|
+
|
||||||
|
'--with-nonshared-cflags=CFLAGS'
|
||||||
|
Use additional compiler flags CFLAGS to build the parts of the
|
||||||
|
library which are always statically linked into applications and
|
||||||
|
diff --git a/configure b/configure
|
||||||
|
index 03f4e59e754b5463..34c64f8de44e3086 100755
|
||||||
|
--- a/configure
|
||||||
|
+++ b/configure
|
||||||
|
@@ -3373,7 +3373,7 @@ fi
|
||||||
|
if test "${with_default_link+set}" = set; then :
|
||||||
|
withval=$with_default_link; use_default_link=$withval
|
||||||
|
else
|
||||||
|
- use_default_link=default
|
||||||
|
+ use_default_link=no
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
@@ -6085,69 +6085,6 @@ fi
|
||||||
|
$as_echo "$libc_cv_hashstyle" >&6; }
|
||||||
|
|
||||||
|
|
||||||
|
-# The linker's default -shared behavior is good enough if it
|
||||||
|
-# does these things that our custom linker scripts ensure that
|
||||||
|
-# all allocated NOTE sections come first.
|
||||||
|
-if test "$use_default_link" = default; then
|
||||||
|
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sufficient default -shared layout" >&5
|
||||||
|
-$as_echo_n "checking for sufficient default -shared layout... " >&6; }
|
||||||
|
-if ${libc_cv_use_default_link+:} false; then :
|
||||||
|
- $as_echo_n "(cached) " >&6
|
||||||
|
-else
|
||||||
|
- libc_cv_use_default_link=no
|
||||||
|
- cat > conftest.s <<\EOF
|
||||||
|
- .section .note.a,"a",%note
|
||||||
|
- .balign 4
|
||||||
|
- .long 4,4,9
|
||||||
|
- .string "GNU"
|
||||||
|
- .string "foo"
|
||||||
|
- .section .note.b,"a",%note
|
||||||
|
- .balign 4
|
||||||
|
- .long 4,4,9
|
||||||
|
- .string "GNU"
|
||||||
|
- .string "bar"
|
||||||
|
-EOF
|
||||||
|
- if { ac_try=' ${CC-cc} $ASFLAGS -shared -o conftest.so conftest.s 1>&5'
|
||||||
|
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
|
||||||
|
- (eval $ac_try) 2>&5
|
||||||
|
- ac_status=$?
|
||||||
|
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||||
|
- test $ac_status = 0; }; } &&
|
||||||
|
- ac_try=`$READELF -S conftest.so | sed -n \
|
||||||
|
- '${x;p;}
|
||||||
|
- s/^ *\[ *[1-9][0-9]*\] *\([^ ][^ ]*\) *\([^ ][^ ]*\) .*$/\2 \1/
|
||||||
|
- t a
|
||||||
|
- b
|
||||||
|
- : a
|
||||||
|
- H'`
|
||||||
|
- then
|
||||||
|
- libc_seen_a=no libc_seen_b=no
|
||||||
|
- set -- $ac_try
|
||||||
|
- while test $# -ge 2 -a "$1" = NOTE; do
|
||||||
|
- case "$2" in
|
||||||
|
- .note.a) libc_seen_a=yes ;;
|
||||||
|
- .note.b) libc_seen_b=yes ;;
|
||||||
|
- esac
|
||||||
|
- shift 2
|
||||||
|
- done
|
||||||
|
- case "$libc_seen_a$libc_seen_b" in
|
||||||
|
- yesyes)
|
||||||
|
- libc_cv_use_default_link=yes
|
||||||
|
- ;;
|
||||||
|
- *)
|
||||||
|
- echo >&5 "\
|
||||||
|
-$libc_seen_a$libc_seen_b from:
|
||||||
|
-$ac_try"
|
||||||
|
- ;;
|
||||||
|
- esac
|
||||||
|
- fi
|
||||||
|
- rm -f conftest*
|
||||||
|
-fi
|
||||||
|
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_use_default_link" >&5
|
||||||
|
-$as_echo "$libc_cv_use_default_link" >&6; }
|
||||||
|
- use_default_link=$libc_cv_use_default_link
|
||||||
|
-fi
|
||||||
|
-
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GLOB_DAT reloc" >&5
|
||||||
|
$as_echo_n "checking for GLOB_DAT reloc... " >&6; }
|
||||||
|
if ${libc_cv_has_glob_dat+:} false; then :
|
||||||
|
diff --git a/configure.ac b/configure.ac
|
||||||
|
index eb9431875fae1b0e..2c69af0807266e7e 100644
|
||||||
|
--- a/configure.ac
|
||||||
|
+++ b/configure.ac
|
||||||
|
@@ -153,7 +153,7 @@ AC_ARG_WITH([default-link],
|
||||||
|
AS_HELP_STRING([--with-default-link],
|
||||||
|
[do not use explicit linker scripts]),
|
||||||
|
[use_default_link=$withval],
|
||||||
|
- [use_default_link=default])
|
||||||
|
+ [use_default_link=no])
|
||||||
|
|
||||||
|
dnl Additional build flags injection.
|
||||||
|
AC_ARG_WITH([nonshared-cflags],
|
||||||
|
@@ -1378,59 +1378,6 @@ fi
|
||||||
|
rm -f conftest*])
|
||||||
|
AC_SUBST(libc_cv_hashstyle)
|
||||||
|
|
||||||
|
-# The linker's default -shared behavior is good enough if it
|
||||||
|
-# does these things that our custom linker scripts ensure that
|
||||||
|
-# all allocated NOTE sections come first.
|
||||||
|
-if test "$use_default_link" = default; then
|
||||||
|
- AC_CACHE_CHECK([for sufficient default -shared layout],
|
||||||
|
- libc_cv_use_default_link, [dnl
|
||||||
|
- libc_cv_use_default_link=no
|
||||||
|
- cat > conftest.s <<\EOF
|
||||||
|
- .section .note.a,"a",%note
|
||||||
|
- .balign 4
|
||||||
|
- .long 4,4,9
|
||||||
|
- .string "GNU"
|
||||||
|
- .string "foo"
|
||||||
|
- .section .note.b,"a",%note
|
||||||
|
- .balign 4
|
||||||
|
- .long 4,4,9
|
||||||
|
- .string "GNU"
|
||||||
|
- .string "bar"
|
||||||
|
-EOF
|
||||||
|
- if AC_TRY_COMMAND([dnl
|
||||||
|
- ${CC-cc} $ASFLAGS -shared -o conftest.so conftest.s 1>&AS_MESSAGE_LOG_FD]) &&
|
||||||
|
- ac_try=`$READELF -S conftest.so | sed -n \
|
||||||
|
- ['${x;p;}
|
||||||
|
- s/^ *\[ *[1-9][0-9]*\] *\([^ ][^ ]*\) *\([^ ][^ ]*\) .*$/\2 \1/
|
||||||
|
- t a
|
||||||
|
- b
|
||||||
|
- : a
|
||||||
|
- H']`
|
||||||
|
- then
|
||||||
|
- libc_seen_a=no libc_seen_b=no
|
||||||
|
- set -- $ac_try
|
||||||
|
- while test $# -ge 2 -a "$1" = NOTE; do
|
||||||
|
- case "$2" in
|
||||||
|
- .note.a) libc_seen_a=yes ;;
|
||||||
|
- .note.b) libc_seen_b=yes ;;
|
||||||
|
- esac
|
||||||
|
- shift 2
|
||||||
|
- done
|
||||||
|
- case "$libc_seen_a$libc_seen_b" in
|
||||||
|
- yesyes)
|
||||||
|
- libc_cv_use_default_link=yes
|
||||||
|
- ;;
|
||||||
|
- *)
|
||||||
|
- echo >&AS_MESSAGE_LOG_FD "\
|
||||||
|
-$libc_seen_a$libc_seen_b from:
|
||||||
|
-$ac_try"
|
||||||
|
- ;;
|
||||||
|
- esac
|
||||||
|
- fi
|
||||||
|
- rm -f conftest*])
|
||||||
|
- use_default_link=$libc_cv_use_default_link
|
||||||
|
-fi
|
||||||
|
-
|
||||||
|
AC_CACHE_CHECK(for GLOB_DAT reloc,
|
||||||
|
libc_cv_has_glob_dat, [dnl
|
||||||
|
cat > conftest.c <<EOF
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index 8afbe3f6ab259331..fec6e23b5b625e3b 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -504,6 +504,40 @@ tests-execstack-yes = \
|
||||||
|
# tests-execstack-yes
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
+
|
||||||
|
+tests-special += $(objpfx)tst-relro-ldso.out $(objpfx)tst-relro-libc.out
|
||||||
|
+$(objpfx)tst-relro-ldso.out: tst-relro-symbols.py $(..)/scripts/glibcelf.py \
|
||||||
|
+ $(objpfx)ld.so
|
||||||
|
+ $(PYTHON) tst-relro-symbols.py $(objpfx)ld.so \
|
||||||
|
+ --required=_rtld_global_ro \
|
||||||
|
+ > $@ 2>&1; $(evaluate-test)
|
||||||
|
+# The optional symbols are present in libc only if the architecture has
|
||||||
|
+# the GLIBC_2.0 symbol set in libc.
|
||||||
|
+$(objpfx)tst-relro-libc.out: tst-relro-symbols.py $(..)/scripts/glibcelf.py \
|
||||||
|
+ $(common-objpfx)libc.so
|
||||||
|
+ $(PYTHON) tst-relro-symbols.py $(common-objpfx)libc.so \
|
||||||
|
+ --required=_IO_cookie_jumps \
|
||||||
|
+ --required=_IO_file_jumps \
|
||||||
|
+ --required=_IO_file_jumps_maybe_mmap \
|
||||||
|
+ --required=_IO_file_jumps_mmap \
|
||||||
|
+ --required=_IO_helper_jumps \
|
||||||
|
+ --required=_IO_mem_jumps \
|
||||||
|
+ --required=_IO_obstack_jumps \
|
||||||
|
+ --required=_IO_proc_jumps \
|
||||||
|
+ --required=_IO_str_chk_jumps \
|
||||||
|
+ --required=_IO_str_jumps \
|
||||||
|
+ --required=_IO_strn_jumps \
|
||||||
|
+ --required=_IO_wfile_jumps \
|
||||||
|
+ --required=_IO_wfile_jumps_maybe_mmap \
|
||||||
|
+ --required=_IO_wfile_jumps_mmap \
|
||||||
|
+ --required=_IO_wmem_jumps \
|
||||||
|
+ --required=_IO_wstr_jumps \
|
||||||
|
+ --required=_IO_wstrn_jumps \
|
||||||
|
+ --optional=_IO_old_cookie_jumps \
|
||||||
|
+ --optional=_IO_old_file_jumps \
|
||||||
|
+ --optional=_IO_old_proc_jumps \
|
||||||
|
+ > $@ 2>&1; $(evaluate-test)
|
||||||
|
+
|
||||||
|
tests += $(tests-execstack-$(have-z-execstack))
|
||||||
|
ifeq ($(run-built-tests),yes)
|
||||||
|
tests-special += \
|
||||||
|
diff --git a/elf/tst-relro-symbols.py b/elf/tst-relro-symbols.py
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..368ea3349f86bd81
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-relro-symbols.py
|
||||||
|
@@ -0,0 +1,137 @@
|
||||||
|
+#!/usr/bin/python3
|
||||||
|
+# Verify that certain symbols are covered by RELRO.
|
||||||
|
+# Copyright (C) 2022 Free Software Foundation, Inc.
|
||||||
|
+# This file is part of the GNU C Library.
|
||||||
|
+#
|
||||||
|
+# The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+# modify it under the terms of the GNU Lesser General Public
|
||||||
|
+# License as published by the Free Software Foundation; either
|
||||||
|
+# version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+#
|
||||||
|
+# The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+# Lesser General Public License for more details.
|
||||||
|
+#
|
||||||
|
+# You should have received a copy of the GNU Lesser General Public
|
||||||
|
+# License along with the GNU C Library; if not, see
|
||||||
|
+# <https://www.gnu.org/licenses/>.
|
||||||
|
+
|
||||||
|
+"""Analyze a (shared) object to verify that certain symbols are
|
||||||
|
+present and covered by the PT_GNU_RELRO segment.
|
||||||
|
+
|
||||||
|
+"""
|
||||||
|
+
|
||||||
|
+import argparse
|
||||||
|
+import os.path
|
||||||
|
+import sys
|
||||||
|
+
|
||||||
|
+# Make available glibc Python modules.
|
||||||
|
+sys.path.append(os.path.join(
|
||||||
|
+ os.path.dirname(os.path.realpath(__file__)), os.path.pardir, 'scripts'))
|
||||||
|
+
|
||||||
|
+import glibcelf
|
||||||
|
+
|
||||||
|
+def find_relro(path: str, img: glibcelf.Image) -> (int, int):
|
||||||
|
+ """Discover the address range of the PT_GNU_RELRO segment."""
|
||||||
|
+ for phdr in img.phdrs():
|
||||||
|
+ if phdr.p_type == glibcelf.Pt.PT_GNU_RELRO:
|
||||||
|
+ # The computation is not entirely accurate because
|
||||||
|
+ # _dl_protect_relro in elf/dl-reloc.c rounds both the
|
||||||
|
+ # start end and downwards using the run-time page size.
|
||||||
|
+ return phdr.p_vaddr, phdr.p_vaddr + phdr.p_memsz
|
||||||
|
+ sys.stdout.write('{}: error: no PT_GNU_RELRO segment\n'.format(path))
|
||||||
|
+ sys.exit(1)
|
||||||
|
+
|
||||||
|
+def check_in_relro(kind, relro_begin, relro_end, name, start, size, error):
|
||||||
|
+ """Check if a section or symbol falls within in the RELRO segment."""
|
||||||
|
+ end = start + size - 1
|
||||||
|
+ if not (relro_begin <= start < end < relro_end):
|
||||||
|
+ error(
|
||||||
|
+ '{} {!r} of size {} at 0x{:x} is not in RELRO range [0x{:x}, 0x{:x})'.format(
|
||||||
|
+ kind, name.decode('UTF-8'), start, size,
|
||||||
|
+ relro_begin, relro_end))
|
||||||
|
+
|
||||||
|
+def get_parser():
|
||||||
|
+ """Return an argument parser for this script."""
|
||||||
|
+ parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
+ parser.add_argument('object', help='path to object file to check')
|
||||||
|
+ parser.add_argument('--required', metavar='NAME', default=(),
|
||||||
|
+ help='required symbol names', nargs='*')
|
||||||
|
+ parser.add_argument('--optional', metavar='NAME', default=(),
|
||||||
|
+ help='required symbol names', nargs='*')
|
||||||
|
+ return parser
|
||||||
|
+
|
||||||
|
+def main(argv):
|
||||||
|
+ """The main entry point."""
|
||||||
|
+ parser = get_parser()
|
||||||
|
+ opts = parser.parse_args(argv)
|
||||||
|
+ img = glibcelf.Image.readfile(opts.object)
|
||||||
|
+
|
||||||
|
+ required_symbols = frozenset([sym.encode('UTF-8')
|
||||||
|
+ for sym in opts.required])
|
||||||
|
+ optional_symbols = frozenset([sym.encode('UTF-8')
|
||||||
|
+ for sym in opts.optional])
|
||||||
|
+ check_symbols = required_symbols | optional_symbols
|
||||||
|
+
|
||||||
|
+ # Tracks the symbols in check_symbols that have been found.
|
||||||
|
+ symbols_found = set()
|
||||||
|
+
|
||||||
|
+ # Discover the extent of the RELRO segment.
|
||||||
|
+ relro_begin, relro_end = find_relro(opts.object, img)
|
||||||
|
+ symbol_table_found = False
|
||||||
|
+
|
||||||
|
+ errors = False
|
||||||
|
+ def error(msg: str) -> None:
|
||||||
|
+ """Record an error condition and write a message to standard output."""
|
||||||
|
+ nonlocal errors
|
||||||
|
+ errors = True
|
||||||
|
+ sys.stdout.write('{}: error: {}\n'.format(opts.object, msg))
|
||||||
|
+
|
||||||
|
+ # Iterate over section headers to find the symbol table.
|
||||||
|
+ for shdr in img.shdrs():
|
||||||
|
+ if shdr.sh_type == glibcelf.Sht.SHT_SYMTAB:
|
||||||
|
+ symbol_table_found = True
|
||||||
|
+ for sym in img.syms(shdr):
|
||||||
|
+ if sym.st_name in check_symbols:
|
||||||
|
+ symbols_found.add(sym.st_name)
|
||||||
|
+
|
||||||
|
+ # Validate symbol type, section, and size.
|
||||||
|
+ if sym.st_info.type != glibcelf.Stt.STT_OBJECT:
|
||||||
|
+ error('symbol {!r} has wrong type {}'.format(
|
||||||
|
+ sym.st_name.decode('UTF-8'), sym.st_info.type))
|
||||||
|
+ if sym.st_shndx in glibcelf.Shn:
|
||||||
|
+ error('symbol {!r} has reserved section {}'.format(
|
||||||
|
+ sym.st_name.decode('UTF-8'), sym.st_shndx))
|
||||||
|
+ continue
|
||||||
|
+ if sym.st_size == 0:
|
||||||
|
+ error('symbol {!r} has size zero'.format(
|
||||||
|
+ sym.st_name.decode('UTF-8')))
|
||||||
|
+ continue
|
||||||
|
+
|
||||||
|
+ check_in_relro('symbol', relro_begin, relro_end,
|
||||||
|
+ sym.st_name, sym.st_value, sym.st_size,
|
||||||
|
+ error)
|
||||||
|
+ continue # SHT_SYMTAB
|
||||||
|
+ if shdr.sh_name == b'.data.rel.ro' \
|
||||||
|
+ or shdr.sh_name.startswith(b'.data.rel.ro.'):
|
||||||
|
+ check_in_relro('section', relro_begin, relro_end,
|
||||||
|
+ shdr.sh_name, shdr.sh_addr, shdr.sh_size,
|
||||||
|
+ error)
|
||||||
|
+ continue
|
||||||
|
+
|
||||||
|
+ if required_symbols - symbols_found:
|
||||||
|
+ for sym in sorted(required_symbols - symbols_found):
|
||||||
|
+ error('symbol {!r} not found'.format(sym.decode('UTF-8')))
|
||||||
|
+
|
||||||
|
+ if errors:
|
||||||
|
+ sys.exit(1)
|
||||||
|
+
|
||||||
|
+ if not symbol_table_found:
|
||||||
|
+ sys.stdout.write(
|
||||||
|
+ '{}: warning: no symbol table found (stripped object)\n'.format(
|
||||||
|
+ opts.object))
|
||||||
|
+ sys.exit(77)
|
||||||
|
+
|
||||||
|
+if __name__ == '__main__':
|
||||||
|
+ main(sys.argv[1:])
|
||||||
|
diff --git a/manual/install.texi b/manual/install.texi
|
||||||
|
index 816b77a0a25a88a7..36a5af62bc5722b0 100644
|
||||||
|
--- a/manual/install.texi
|
||||||
|
+++ b/manual/install.texi
|
||||||
|
@@ -117,6 +117,12 @@ problem and suppress these constructs, so that the library will still be
|
||||||
|
usable, but functionality may be lost---for example, you can't build a
|
||||||
|
shared libc with old binutils.
|
||||||
|
|
||||||
|
+@item --with-default-link=@var{FLAG}
|
||||||
|
+With @code{--with-default-link=yes}, the build system does not use a
|
||||||
|
+custom linker script for linking shared objects. The default for
|
||||||
|
+@var{FLAG} is the opposite, @samp{no}, because the custom linker script
|
||||||
|
+is needed for full RELRO protection.
|
||||||
|
+
|
||||||
|
@item --with-nonshared-cflags=@var{cflags}
|
||||||
|
Use additional compiler flags @var{cflags} to build the parts of the
|
||||||
|
library which are always statically linked into applications and
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/ia64/Makefile b/sysdeps/unix/sysv/linux/ia64/Makefile
|
||||||
|
index da85ba43e2d0ddef..c5cc41b3677d4a2a 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/ia64/Makefile
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/ia64/Makefile
|
||||||
|
@@ -1,3 +1,9 @@
|
||||||
|
+ifeq ($(subdir),elf)
|
||||||
|
+# ia64 does not support PT_GNU_RELRO.
|
||||||
|
+test-xfail-tst-relro-ldso = yes
|
||||||
|
+test-xfail-tst-relro-libc = yes
|
||||||
|
+endif
|
||||||
|
+
|
||||||
|
ifeq ($(subdir),misc)
|
||||||
|
sysdep_headers += sys/rse.h
|
||||||
|
endif
|
87
glibc-upstream-2.34-169.patch
Normal file
87
glibc-upstream-2.34-169.patch
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
commit ca0faa140ff8cebe4c041d935f0f5eb480873d99
|
||||||
|
Author: Joan Bruguera <joanbrugueram@gmail.com>
|
||||||
|
Date: Mon Apr 11 19:49:56 2022 +0200
|
||||||
|
|
||||||
|
misc: Fix rare fortify crash on wchar funcs. [BZ 29030]
|
||||||
|
|
||||||
|
If `__glibc_objsize (__o) == (size_t) -1` (i.e. `__o` is unknown size), fortify
|
||||||
|
checks should pass, and `__whatever_alias` should be called.
|
||||||
|
|
||||||
|
Previously, `__glibc_objsize (__o) == (size_t) -1` was explicitly checked, but
|
||||||
|
on commit a643f60c53876b, this was moved into `__glibc_safe_or_unknown_len`.
|
||||||
|
|
||||||
|
A comment says the -1 case should work as: "The -1 check is redundant because
|
||||||
|
since it implies that __glibc_safe_len_cond is true.". But this fails when:
|
||||||
|
* `__s > 1`
|
||||||
|
* `__osz == -1` (i.e. unknown size at compile time)
|
||||||
|
* `__l` is big enough
|
||||||
|
* `__l * __s <= __osz` can be folded to a constant
|
||||||
|
(I only found this to be true for `mbsrtowcs` and other functions in wchar2.h)
|
||||||
|
|
||||||
|
In this case `__l * __s <= __osz` is false, and `__whatever_chk_warn` will be
|
||||||
|
called by `__glibc_fortify` or `__glibc_fortify_n` and crash the program.
|
||||||
|
|
||||||
|
This commit adds the explicit `__osz == -1` check again.
|
||||||
|
moc crashes on startup due to this, see: https://bugs.archlinux.org/task/74041
|
||||||
|
|
||||||
|
Minimal test case (test.c):
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
const char *hw = "HelloWorld";
|
||||||
|
mbsrtowcs (NULL, &hw, (size_t)-1, NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Build with:
|
||||||
|
gcc -O2 -Wp,-D_FORTIFY_SOURCE=2 test.c -o test && ./test
|
||||||
|
|
||||||
|
Output:
|
||||||
|
*** buffer overflow detected ***: terminated
|
||||||
|
|
||||||
|
Fixes: BZ #29030
|
||||||
|
Signed-off-by: Joan Bruguera <joanbrugueram@gmail.com>
|
||||||
|
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
(cherry picked from commit 33e03f9cd2be4f2cd62f93fda539cc07d9c8130e)
|
||||||
|
|
||||||
|
diff --git a/debug/tst-fortify.c b/debug/tst-fortify.c
|
||||||
|
index 8b5902423cf0ad88..fb02452f5993c594 100644
|
||||||
|
--- a/debug/tst-fortify.c
|
||||||
|
+++ b/debug/tst-fortify.c
|
||||||
|
@@ -1505,6 +1505,11 @@ do_test (void)
|
||||||
|
CHK_FAIL_END
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+ /* Bug 29030 regresion check */
|
||||||
|
+ cp = "HelloWorld";
|
||||||
|
+ if (mbsrtowcs (NULL, &cp, (size_t)-1, &s) != 10)
|
||||||
|
+ FAIL ();
|
||||||
|
+
|
||||||
|
cp = "A";
|
||||||
|
if (mbstowcs (wenough, cp, 10) != 1
|
||||||
|
|| wcscmp (wenough, L"A") != 0)
|
||||||
|
diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
|
||||||
|
index 515fb681a0547217..b36013b9a6b4d9c3 100644
|
||||||
|
--- a/misc/sys/cdefs.h
|
||||||
|
+++ b/misc/sys/cdefs.h
|
||||||
|
@@ -161,13 +161,13 @@
|
||||||
|
|| (__builtin_constant_p (__l) && (__l) > 0))
|
||||||
|
|
||||||
|
/* Length is known to be safe at compile time if the __L * __S <= __OBJSZ
|
||||||
|
- condition can be folded to a constant and if it is true. The -1 check is
|
||||||
|
- redundant because since it implies that __glibc_safe_len_cond is true. */
|
||||||
|
+ condition can be folded to a constant and if it is true, or unknown (-1) */
|
||||||
|
#define __glibc_safe_or_unknown_len(__l, __s, __osz) \
|
||||||
|
- (__glibc_unsigned_or_positive (__l) \
|
||||||
|
- && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), \
|
||||||
|
- __s, __osz)) \
|
||||||
|
- && __glibc_safe_len_cond ((__SIZE_TYPE__) (__l), __s, __osz))
|
||||||
|
+ ((__osz) == (__SIZE_TYPE__) -1 \
|
||||||
|
+ || (__glibc_unsigned_or_positive (__l) \
|
||||||
|
+ && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), \
|
||||||
|
+ (__s), (__osz))) \
|
||||||
|
+ && __glibc_safe_len_cond ((__SIZE_TYPE__) (__l), (__s), (__osz))))
|
||||||
|
|
||||||
|
/* Conversely, we know at compile time that the length is unsafe if the
|
||||||
|
__L * __S <= __OBJSZ condition can be folded to a constant and if it is
|
49
glibc-upstream-2.34-170.patch
Normal file
49
glibc-upstream-2.34-170.patch
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
commit 0d477e92c49db2906b32e44135b98746ccc73c7b
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Tue Apr 26 14:22:10 2022 +0200
|
||||||
|
|
||||||
|
INSTALL: Rephrase -with-default-link documentation
|
||||||
|
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
(cherry picked from commit c935789bdf40ba22b5698da869d3a4789797e09f)
|
||||||
|
|
||||||
|
diff --git a/INSTALL b/INSTALL
|
||||||
|
index 60d01568d77645c7..10a3dcdc0a8db665 100644
|
||||||
|
--- a/INSTALL
|
||||||
|
+++ b/INSTALL
|
||||||
|
@@ -90,10 +90,10 @@ if 'CFLAGS' is specified it must enable optimization. For example:
|
||||||
|
library will still be usable, but functionality may be lost--for
|
||||||
|
example, you can't build a shared libc with old binutils.
|
||||||
|
|
||||||
|
-'--with-default-link=FLAG'
|
||||||
|
- With '--with-default-link=yes', the build system does not use a
|
||||||
|
- custom linker script for linking shared objects. The default for
|
||||||
|
- FLAG is the opposite, 'no', because the custom linker script is
|
||||||
|
+'--with-default-link'
|
||||||
|
+ With '--with-default-link', the build system does not use a custom
|
||||||
|
+ linker script for linking shared objects. The default is
|
||||||
|
+ '--without-default-link', because the custom linker script is
|
||||||
|
needed for full RELRO protection.
|
||||||
|
|
||||||
|
'--with-nonshared-cflags=CFLAGS'
|
||||||
|
diff --git a/manual/install.texi b/manual/install.texi
|
||||||
|
index 36a5af62bc5722b0..8e34ff7e1847f3ae 100644
|
||||||
|
--- a/manual/install.texi
|
||||||
|
+++ b/manual/install.texi
|
||||||
|
@@ -117,11 +117,11 @@ problem and suppress these constructs, so that the library will still be
|
||||||
|
usable, but functionality may be lost---for example, you can't build a
|
||||||
|
shared libc with old binutils.
|
||||||
|
|
||||||
|
-@item --with-default-link=@var{FLAG}
|
||||||
|
-With @code{--with-default-link=yes}, the build system does not use a
|
||||||
|
-custom linker script for linking shared objects. The default for
|
||||||
|
-@var{FLAG} is the opposite, @samp{no}, because the custom linker script
|
||||||
|
-is needed for full RELRO protection.
|
||||||
|
+@item --with-default-link
|
||||||
|
+With @code{--with-default-link}, the build system does not use a custom
|
||||||
|
+linker script for linking shared objects. The default is
|
||||||
|
+@code{--without-default-link}, because the custom linker script is
|
||||||
|
+needed for full RELRO protection.
|
||||||
|
|
||||||
|
@item --with-nonshared-cflags=@var{cflags}
|
||||||
|
Use additional compiler flags @var{cflags} to build the parts of the
|
377
glibc-upstream-2.34-171.patch
Normal file
377
glibc-upstream-2.34-171.patch
Normal file
@ -0,0 +1,377 @@
|
|||||||
|
commit bc56ab1f4aa937665034373d3e320d0779a839aa
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Tue Apr 26 14:23:02 2022 +0200
|
||||||
|
|
||||||
|
dlfcn: Do not use rtld_active () to determine ld.so state (bug 29078)
|
||||||
|
|
||||||
|
When audit modules are loaded, ld.so initialization is not yet
|
||||||
|
complete, and rtld_active () returns false even though ld.so is
|
||||||
|
mostly working. Instead, the static dlopen hook is used, but that
|
||||||
|
does not work at all because this is not a static dlopen situation.
|
||||||
|
|
||||||
|
Commit 466c1ea15f461edb8e3ffaf5d86d708876343bbf ("dlfcn: Rework
|
||||||
|
static dlopen hooks") moved the hook pointer into _rtld_global_ro,
|
||||||
|
which means that separate protection is not needed anymore and the
|
||||||
|
hook pointer can be checked directly.
|
||||||
|
|
||||||
|
The guard for disabling libio vtable hardening in _IO_vtable_check
|
||||||
|
should stay for now.
|
||||||
|
|
||||||
|
Fixes commit 8e1472d2c1e25e6eabc2059170731365f6d5b3d1 ("ld.so:
|
||||||
|
Examine GLRO to detect inactive loader [BZ #20204]").
|
||||||
|
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
(cherry picked from commit 8dcb6d0af07fda3607b541857e4f3970a74ed55b)
|
||||||
|
|
||||||
|
diff --git a/dlfcn/dladdr.c b/dlfcn/dladdr.c
|
||||||
|
index 1cc305f0c46e7c3b..0d07ae1cd4dbb7a2 100644
|
||||||
|
--- a/dlfcn/dladdr.c
|
||||||
|
+++ b/dlfcn/dladdr.c
|
||||||
|
@@ -24,7 +24,7 @@ int
|
||||||
|
__dladdr (const void *address, Dl_info *info)
|
||||||
|
{
|
||||||
|
#ifdef SHARED
|
||||||
|
- if (!rtld_active ())
|
||||||
|
+ if (GLRO (dl_dlfcn_hook) != NULL)
|
||||||
|
return GLRO (dl_dlfcn_hook)->dladdr (address, info);
|
||||||
|
#endif
|
||||||
|
return _dl_addr (address, info, NULL, NULL);
|
||||||
|
diff --git a/dlfcn/dladdr1.c b/dlfcn/dladdr1.c
|
||||||
|
index 78560dbac208c316..93ce68c1d6067fe2 100644
|
||||||
|
--- a/dlfcn/dladdr1.c
|
||||||
|
+++ b/dlfcn/dladdr1.c
|
||||||
|
@@ -24,7 +24,7 @@ int
|
||||||
|
__dladdr1 (const void *address, Dl_info *info, void **extra, int flags)
|
||||||
|
{
|
||||||
|
#ifdef SHARED
|
||||||
|
- if (!rtld_active ())
|
||||||
|
+ if (GLRO (dl_dlfcn_hook) != NULL)
|
||||||
|
return GLRO (dl_dlfcn_hook)->dladdr1 (address, info, extra, flags);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
diff --git a/dlfcn/dlclose.c b/dlfcn/dlclose.c
|
||||||
|
index 6a013a81bb648191..07ecb21bf7d43be4 100644
|
||||||
|
--- a/dlfcn/dlclose.c
|
||||||
|
+++ b/dlfcn/dlclose.c
|
||||||
|
@@ -24,7 +24,7 @@ int
|
||||||
|
__dlclose (void *handle)
|
||||||
|
{
|
||||||
|
#ifdef SHARED
|
||||||
|
- if (!rtld_active ())
|
||||||
|
+ if (GLRO (dl_dlfcn_hook) != NULL)
|
||||||
|
return GLRO (dl_dlfcn_hook)->dlclose (handle);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
diff --git a/dlfcn/dlerror.c b/dlfcn/dlerror.c
|
||||||
|
index 5047b140662bc33e..63da79c63000eef0 100644
|
||||||
|
--- a/dlfcn/dlerror.c
|
||||||
|
+++ b/dlfcn/dlerror.c
|
||||||
|
@@ -32,7 +32,7 @@ char *
|
||||||
|
__dlerror (void)
|
||||||
|
{
|
||||||
|
# ifdef SHARED
|
||||||
|
- if (!rtld_active ())
|
||||||
|
+ if (GLRO (dl_dlfcn_hook) != NULL)
|
||||||
|
return GLRO (dl_dlfcn_hook)->dlerror ();
|
||||||
|
# endif
|
||||||
|
|
||||||
|
diff --git a/dlfcn/dlinfo.c b/dlfcn/dlinfo.c
|
||||||
|
index c6f9a1da09ff8622..47d2daa96fa5986f 100644
|
||||||
|
--- a/dlfcn/dlinfo.c
|
||||||
|
+++ b/dlfcn/dlinfo.c
|
||||||
|
@@ -89,7 +89,7 @@ dlinfo_implementation (void *handle, int request, void *arg)
|
||||||
|
int
|
||||||
|
___dlinfo (void *handle, int request, void *arg)
|
||||||
|
{
|
||||||
|
- if (!rtld_active ())
|
||||||
|
+ if (GLRO (dl_dlfcn_hook) != NULL)
|
||||||
|
return GLRO (dl_dlfcn_hook)->dlinfo (handle, request, arg);
|
||||||
|
else
|
||||||
|
return dlinfo_implementation (handle, request, arg);
|
||||||
|
diff --git a/dlfcn/dlmopen.c b/dlfcn/dlmopen.c
|
||||||
|
index c171c8953da20fc7..2309224eb8484b1a 100644
|
||||||
|
--- a/dlfcn/dlmopen.c
|
||||||
|
+++ b/dlfcn/dlmopen.c
|
||||||
|
@@ -80,7 +80,7 @@ dlmopen_implementation (Lmid_t nsid, const char *file, int mode,
|
||||||
|
void *
|
||||||
|
___dlmopen (Lmid_t nsid, const char *file, int mode)
|
||||||
|
{
|
||||||
|
- if (!rtld_active ())
|
||||||
|
+ if (GLRO (dl_dlfcn_hook) != NULL)
|
||||||
|
return GLRO (dl_dlfcn_hook)->dlmopen (nsid, file, mode, RETURN_ADDRESS (0));
|
||||||
|
else
|
||||||
|
return dlmopen_implementation (nsid, file, mode, RETURN_ADDRESS (0));
|
||||||
|
diff --git a/dlfcn/dlopen.c b/dlfcn/dlopen.c
|
||||||
|
index e04b374b82b04337..9c59c751c4eaf7a7 100644
|
||||||
|
--- a/dlfcn/dlopen.c
|
||||||
|
+++ b/dlfcn/dlopen.c
|
||||||
|
@@ -75,7 +75,7 @@ dlopen_implementation (const char *file, int mode, void *dl_caller)
|
||||||
|
void *
|
||||||
|
___dlopen (const char *file, int mode)
|
||||||
|
{
|
||||||
|
- if (!rtld_active ())
|
||||||
|
+ if (GLRO (dl_dlfcn_hook) != NULL)
|
||||||
|
return GLRO (dl_dlfcn_hook)->dlopen (file, mode, RETURN_ADDRESS (0));
|
||||||
|
else
|
||||||
|
return dlopen_implementation (file, mode, RETURN_ADDRESS (0));
|
||||||
|
diff --git a/dlfcn/dlopenold.c b/dlfcn/dlopenold.c
|
||||||
|
index 9115501ac121eeca..c2f2a42194d50953 100644
|
||||||
|
--- a/dlfcn/dlopenold.c
|
||||||
|
+++ b/dlfcn/dlopenold.c
|
||||||
|
@@ -70,7 +70,7 @@ __dlopen_nocheck (const char *file, int mode)
|
||||||
|
mode |= RTLD_LAZY;
|
||||||
|
args.mode = mode;
|
||||||
|
|
||||||
|
- if (!rtld_active ())
|
||||||
|
+ if (GLRO (dl_dlfcn_hook) != NULL)
|
||||||
|
return GLRO (dl_dlfcn_hook)->dlopen (file, mode, RETURN_ADDRESS (0));
|
||||||
|
|
||||||
|
return _dlerror_run (dlopen_doit, &args) ? NULL : args.new;
|
||||||
|
diff --git a/dlfcn/dlsym.c b/dlfcn/dlsym.c
|
||||||
|
index 43044cf7bb95801e..d3861170a7631d01 100644
|
||||||
|
--- a/dlfcn/dlsym.c
|
||||||
|
+++ b/dlfcn/dlsym.c
|
||||||
|
@@ -62,7 +62,7 @@ dlsym_implementation (void *handle, const char *name, void *dl_caller)
|
||||||
|
void *
|
||||||
|
___dlsym (void *handle, const char *name)
|
||||||
|
{
|
||||||
|
- if (!rtld_active ())
|
||||||
|
+ if (GLRO (dl_dlfcn_hook) != NULL)
|
||||||
|
return GLRO (dl_dlfcn_hook)->dlsym (handle, name, RETURN_ADDRESS (0));
|
||||||
|
else
|
||||||
|
return dlsym_implementation (handle, name, RETURN_ADDRESS (0));
|
||||||
|
diff --git a/dlfcn/dlvsym.c b/dlfcn/dlvsym.c
|
||||||
|
index 9b76f9afa513e11f..3af02109c306b800 100644
|
||||||
|
--- a/dlfcn/dlvsym.c
|
||||||
|
+++ b/dlfcn/dlvsym.c
|
||||||
|
@@ -65,7 +65,7 @@ dlvsym_implementation (void *handle, const char *name, const char *version,
|
||||||
|
void *
|
||||||
|
___dlvsym (void *handle, const char *name, const char *version)
|
||||||
|
{
|
||||||
|
- if (!rtld_active ())
|
||||||
|
+ if (GLRO (dl_dlfcn_hook) != NULL)
|
||||||
|
return GLRO (dl_dlfcn_hook)->dlvsym (handle, name, version,
|
||||||
|
RETURN_ADDRESS (0));
|
||||||
|
else
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index fec6e23b5b625e3b..c89a6a58690646ee 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -376,6 +376,7 @@ tests += \
|
||||||
|
tst-audit24d \
|
||||||
|
tst-audit25a \
|
||||||
|
tst-audit25b \
|
||||||
|
+ tst-audit26 \
|
||||||
|
tst-auditmany \
|
||||||
|
tst-auxobj \
|
||||||
|
tst-auxobj-dlopen \
|
||||||
|
@@ -721,6 +722,7 @@ modules-names = \
|
||||||
|
tst-auditmod24c \
|
||||||
|
tst-auditmod24d \
|
||||||
|
tst-auditmod25 \
|
||||||
|
+ tst-auditmod26 \
|
||||||
|
tst-auxvalmod \
|
||||||
|
tst-big-note-lib \
|
||||||
|
tst-deep1mod1 \
|
||||||
|
@@ -2194,6 +2196,10 @@ $(objpfx)tst-audit25b: $(objpfx)tst-audit25mod1.so \
|
||||||
|
LDFLAGS-tst-audit25b = -Wl,-z,now
|
||||||
|
tst-audit25b-ARGS = -- $(host-test-program-cmd)
|
||||||
|
|
||||||
|
+$(objpfx)tst-audit26.out: $(objpfx)tst-auditmod26.so
|
||||||
|
+$(objpfx)tst-auditmod26.so: $(libsupport)
|
||||||
|
+tst-audit26-ENV = LD_AUDIT=$(objpfx)tst-auditmod26.so
|
||||||
|
+
|
||||||
|
# tst-sonamemove links against an older implementation of the library.
|
||||||
|
LDFLAGS-tst-sonamemove-linkmod1.so = \
|
||||||
|
-Wl,--version-script=tst-sonamemove-linkmod1.map \
|
||||||
|
diff --git a/elf/dl-libc.c b/elf/dl-libc.c
|
||||||
|
index d5bc4a277f4c6ef3..db4342a3256921f0 100644
|
||||||
|
--- a/elf/dl-libc.c
|
||||||
|
+++ b/elf/dl-libc.c
|
||||||
|
@@ -157,7 +157,7 @@ __libc_dlopen_mode (const char *name, int mode)
|
||||||
|
args.caller_dlopen = RETURN_ADDRESS (0);
|
||||||
|
|
||||||
|
#ifdef SHARED
|
||||||
|
- if (!rtld_active ())
|
||||||
|
+ if (GLRO (dl_dlfcn_hook) != NULL)
|
||||||
|
return GLRO (dl_dlfcn_hook)->libc_dlopen_mode (name, mode);
|
||||||
|
#endif
|
||||||
|
return dlerror_run (do_dlopen, &args) ? NULL : (void *) args.map;
|
||||||
|
@@ -185,7 +185,7 @@ __libc_dlsym (void *map, const char *name)
|
||||||
|
args.name = name;
|
||||||
|
|
||||||
|
#ifdef SHARED
|
||||||
|
- if (!rtld_active ())
|
||||||
|
+ if (GLRO (dl_dlfcn_hook) != NULL)
|
||||||
|
return GLRO (dl_dlfcn_hook)->libc_dlsym (map, name);
|
||||||
|
#endif
|
||||||
|
return (dlerror_run (do_dlsym, &args) ? NULL
|
||||||
|
@@ -199,7 +199,7 @@ void *
|
||||||
|
__libc_dlvsym (void *map, const char *name, const char *version)
|
||||||
|
{
|
||||||
|
#ifdef SHARED
|
||||||
|
- if (!rtld_active ())
|
||||||
|
+ if (GLRO (dl_dlfcn_hook) != NULL)
|
||||||
|
return GLRO (dl_dlfcn_hook)->libc_dlvsym (map, name, version);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@@ -222,7 +222,7 @@ int
|
||||||
|
__libc_dlclose (void *map)
|
||||||
|
{
|
||||||
|
#ifdef SHARED
|
||||||
|
- if (!rtld_active ())
|
||||||
|
+ if (GLRO (dl_dlfcn_hook) != NULL)
|
||||||
|
return GLRO (dl_dlfcn_hook)->libc_dlclose (map);
|
||||||
|
#endif
|
||||||
|
return dlerror_run (do_dlclose, map);
|
||||||
|
diff --git a/elf/tst-audit26.c b/elf/tst-audit26.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..3f920e83bac247a5
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit26.c
|
||||||
|
@@ -0,0 +1,35 @@
|
||||||
|
+/* Check the usability of <dlfcn.h> functions in audit modules.
|
||||||
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <gnu/lib-names.h>
|
||||||
|
+
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/xdlfcn.h>
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ /* Check that the audit module has been loaded. */
|
||||||
|
+ void *handle = xdlopen ("mapped to libc", RTLD_LOCAL | RTLD_NOW);
|
||||||
|
+ TEST_VERIFY (handle
|
||||||
|
+ == xdlopen (LIBC_SO, RTLD_LOCAL | RTLD_NOW | RTLD_NOLOAD));
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/elf/tst-auditmod26.c b/elf/tst-auditmod26.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..db7ba95abec20f53
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-auditmod26.c
|
||||||
|
@@ -0,0 +1,104 @@
|
||||||
|
+/* Check the usability of <dlfcn.h> functions in audit modules. Audit module.
|
||||||
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <dlfcn.h>
|
||||||
|
+#include <first-versions.h>
|
||||||
|
+#include <gnu/lib-names.h>
|
||||||
|
+#include <link.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/xdlfcn.h>
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_version (unsigned int current)
|
||||||
|
+{
|
||||||
|
+ /* Exercise various <dlfcn.h> functions. */
|
||||||
|
+
|
||||||
|
+ /* Check dlopen, dlsym, dlclose. */
|
||||||
|
+ void *handle = xdlopen (LIBM_SO, RTLD_LOCAL | RTLD_NOW);
|
||||||
|
+ void *ptr = xdlsym (handle, "sincos");
|
||||||
|
+ TEST_VERIFY (ptr != NULL);
|
||||||
|
+ ptr = dlsym (handle, "SINCOS");
|
||||||
|
+ TEST_VERIFY (ptr == NULL);
|
||||||
|
+ const char *message = dlerror ();
|
||||||
|
+ TEST_VERIFY (strstr (message, ": undefined symbol: SINCOS") != NULL);
|
||||||
|
+ ptr = dlsym (handle, "SINCOS");
|
||||||
|
+ TEST_VERIFY (ptr == NULL);
|
||||||
|
+ xdlclose (handle);
|
||||||
|
+ TEST_COMPARE_STRING (dlerror (), NULL);
|
||||||
|
+
|
||||||
|
+ handle = xdlopen (LIBC_SO, RTLD_LOCAL | RTLD_NOW | RTLD_NOLOAD);
|
||||||
|
+
|
||||||
|
+ /* Check dlvsym. _exit is unlikely to gain another symbol
|
||||||
|
+ version. */
|
||||||
|
+ TEST_VERIFY (xdlsym (handle, "_exit")
|
||||||
|
+ == xdlvsym (handle, "_exit", FIRST_VERSION_libc__exit_STRING));
|
||||||
|
+
|
||||||
|
+ /* Check dlinfo. */
|
||||||
|
+ {
|
||||||
|
+ void *handle2 = NULL;
|
||||||
|
+ TEST_COMPARE (dlinfo (handle, RTLD_DI_LINKMAP, &handle2), 0);
|
||||||
|
+ TEST_VERIFY (handle2 == handle);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Check dladdr and dladdr1. */
|
||||||
|
+ Dl_info info = { };
|
||||||
|
+ TEST_VERIFY (dladdr (&_exit, &info) != 0);
|
||||||
|
+ if (strcmp (info.dli_sname, "_Exit") != 0) /* _Exit is an alias. */
|
||||||
|
+ TEST_COMPARE_STRING (info.dli_sname, "_exit");
|
||||||
|
+ TEST_VERIFY (info.dli_saddr == &_exit);
|
||||||
|
+ TEST_VERIFY (strstr (info.dli_fname, LIBC_SO));
|
||||||
|
+ void *extra_info;
|
||||||
|
+ memset (&info, 0, sizeof (info));
|
||||||
|
+ TEST_VERIFY (dladdr1 (&_exit, &info, &extra_info, RTLD_DL_LINKMAP) != 0);
|
||||||
|
+ TEST_VERIFY (extra_info == handle);
|
||||||
|
+
|
||||||
|
+ /* Verify that dlmopen creates a new namespace. */
|
||||||
|
+ void *dlmopen_handle = xdlmopen (LM_ID_NEWLM, LIBC_SO, RTLD_NOW);
|
||||||
|
+ TEST_VERIFY (dlmopen_handle != handle);
|
||||||
|
+ memset (&info, 0, sizeof (info));
|
||||||
|
+ extra_info = NULL;
|
||||||
|
+ ptr = xdlsym (dlmopen_handle, "_exit");
|
||||||
|
+ TEST_VERIFY (dladdr1 (ptr, &info, &extra_info, RTLD_DL_LINKMAP) != 0);
|
||||||
|
+ TEST_VERIFY (extra_info == dlmopen_handle);
|
||||||
|
+ xdlclose (dlmopen_handle);
|
||||||
|
+
|
||||||
|
+ /* Terminate the process with an error state. This does not happen
|
||||||
|
+ automatically because the audit module state is not shared with
|
||||||
|
+ the main program. */
|
||||||
|
+ if (support_record_failure_is_failed ())
|
||||||
|
+ {
|
||||||
|
+ fflush (stdout);
|
||||||
|
+ fflush (stderr);
|
||||||
|
+ _exit (1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return LAV_CURRENT;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+char *
|
||||||
|
+la_objsearch (const char *name, uintptr_t *cookie, unsigned int flag)
|
||||||
|
+{
|
||||||
|
+ if (strcmp (name, "mapped to libc") == 0)
|
||||||
|
+ return (char *) LIBC_SO;
|
||||||
|
+ else
|
||||||
|
+ return (char *) name;
|
||||||
|
+}
|
28
glibc-upstream-2.34-172.patch
Normal file
28
glibc-upstream-2.34-172.patch
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
commit 83cc145830bdbefdabe03787ed884d548bea9c99
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Fri Apr 22 19:34:52 2022 +0200
|
||||||
|
|
||||||
|
scripts/glibcelf.py: Mark as UNSUPPORTED on Python 3.5 and earlier
|
||||||
|
|
||||||
|
enum.IntFlag and enum.EnumMeta._missing_ support are not part of
|
||||||
|
earlier Python versions.
|
||||||
|
|
||||||
|
(cherry picked from commit b571f3adffdcbed23f35ea39b0ca43809dbb4f5b)
|
||||||
|
|
||||||
|
diff --git a/scripts/glibcelf.py b/scripts/glibcelf.py
|
||||||
|
index 8f7d0ca184845714..da0d5380f33a195e 100644
|
||||||
|
--- a/scripts/glibcelf.py
|
||||||
|
+++ b/scripts/glibcelf.py
|
||||||
|
@@ -28,6 +28,12 @@ import collections
|
||||||
|
import enum
|
||||||
|
import struct
|
||||||
|
|
||||||
|
+if not hasattr(enum, 'IntFlag'):
|
||||||
|
+ import sys
|
||||||
|
+ sys.stdout.write(
|
||||||
|
+ 'warning: glibcelf.py needs Python 3.6 for enum support\n')
|
||||||
|
+ sys.exit(77)
|
||||||
|
+
|
||||||
|
class _OpenIntEnum(enum.IntEnum):
|
||||||
|
"""Integer enumeration that supports arbitrary int values."""
|
||||||
|
@classmethod
|
254
glibc-upstream-2.34-173.patch
Normal file
254
glibc-upstream-2.34-173.patch
Normal file
@ -0,0 +1,254 @@
|
|||||||
|
commit 16245986fb9bfe396113fc7dfd1929f69a9e748e
|
||||||
|
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||||
|
Date: Fri Aug 20 06:42:24 2021 -0700
|
||||||
|
|
||||||
|
x86-64: Optimize load of all bits set into ZMM register [BZ #28252]
|
||||||
|
|
||||||
|
Optimize loads of all bits set into ZMM register in AVX512 SVML codes
|
||||||
|
by replacing
|
||||||
|
|
||||||
|
vpbroadcastq .L_2il0floatpacket.16(%rip), %zmmX
|
||||||
|
|
||||||
|
and
|
||||||
|
|
||||||
|
vmovups .L_2il0floatpacket.13(%rip), %zmmX
|
||||||
|
|
||||||
|
with
|
||||||
|
vpternlogd $0xff, %zmmX, %zmmX, %zmmX
|
||||||
|
|
||||||
|
This fixes BZ #28252.
|
||||||
|
|
||||||
|
(cherry picked from commit 78c9ec9000f873abe7a15a91b87080a2e4308260)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_cos8_core_avx512.S b/sysdeps/x86_64/fpu/multiarch/svml_d_cos8_core_avx512.S
|
||||||
|
index e68fcdbb16a79f36..58e588a3d42a8bc9 100644
|
||||||
|
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_cos8_core_avx512.S
|
||||||
|
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_cos8_core_avx512.S
|
||||||
|
@@ -265,7 +265,7 @@ WRAPPER_IMPL_AVX512 _ZGVdN4v_cos
|
||||||
|
vmovaps %zmm0, %zmm8
|
||||||
|
|
||||||
|
/* Check for large arguments path */
|
||||||
|
- vpbroadcastq .L_2il0floatpacket.16(%rip), %zmm2
|
||||||
|
+ vpternlogd $0xff, %zmm2, %zmm2, %zmm2
|
||||||
|
|
||||||
|
/*
|
||||||
|
ARGUMENT RANGE REDUCTION:
|
||||||
|
@@ -456,8 +456,3 @@ WRAPPER_IMPL_AVX512 _ZGVdN4v_cos
|
||||||
|
jmp .LBL_2_7
|
||||||
|
#endif
|
||||||
|
END (_ZGVeN8v_cos_skx)
|
||||||
|
-
|
||||||
|
- .section .rodata, "a"
|
||||||
|
-.L_2il0floatpacket.16:
|
||||||
|
- .long 0xffffffff,0xffffffff
|
||||||
|
- .type .L_2il0floatpacket.16,@object
|
||||||
|
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_log8_core_avx512.S b/sysdeps/x86_64/fpu/multiarch/svml_d_log8_core_avx512.S
|
||||||
|
index dfa2acafc486b56b..f5f117d474f66176 100644
|
||||||
|
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_log8_core_avx512.S
|
||||||
|
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_log8_core_avx512.S
|
||||||
|
@@ -274,7 +274,7 @@ WRAPPER_IMPL_AVX512 _ZGVdN4v_log
|
||||||
|
|
||||||
|
/* preserve mantissa, set input exponent to 2^(-10) */
|
||||||
|
vpternlogq $248, _ExpMask(%rax), %zmm3, %zmm2
|
||||||
|
- vpbroadcastq .L_2il0floatpacket.12(%rip), %zmm1
|
||||||
|
+ vpternlogd $0xff, %zmm1, %zmm1, %zmm1
|
||||||
|
vpsrlq $32, %zmm4, %zmm6
|
||||||
|
|
||||||
|
/* reciprocal approximation good to at least 11 bits */
|
||||||
|
@@ -461,8 +461,3 @@ WRAPPER_IMPL_AVX512 _ZGVdN4v_log
|
||||||
|
jmp .LBL_2_7
|
||||||
|
#endif
|
||||||
|
END (_ZGVeN8v_log_skx)
|
||||||
|
-
|
||||||
|
- .section .rodata, "a"
|
||||||
|
-.L_2il0floatpacket.12:
|
||||||
|
- .long 0xffffffff,0xffffffff
|
||||||
|
- .type .L_2il0floatpacket.12,@object
|
||||||
|
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_sin8_core_avx512.S b/sysdeps/x86_64/fpu/multiarch/svml_d_sin8_core_avx512.S
|
||||||
|
index be8ab7c6e0e33819..48d251db16ccab9d 100644
|
||||||
|
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_sin8_core_avx512.S
|
||||||
|
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_sin8_core_avx512.S
|
||||||
|
@@ -261,7 +261,7 @@ WRAPPER_IMPL_AVX512 _ZGVdN4v_sin
|
||||||
|
andq $-64, %rsp
|
||||||
|
subq $1280, %rsp
|
||||||
|
movq __svml_d_trig_data@GOTPCREL(%rip), %rax
|
||||||
|
- vpbroadcastq .L_2il0floatpacket.14(%rip), %zmm14
|
||||||
|
+ vpternlogd $0xff, %zmm1, %zmm1, %zmm14
|
||||||
|
vmovups __dAbsMask(%rax), %zmm7
|
||||||
|
vmovups __dInvPI(%rax), %zmm2
|
||||||
|
vmovups __dRShifter(%rax), %zmm1
|
||||||
|
@@ -458,8 +458,3 @@ WRAPPER_IMPL_AVX512 _ZGVdN4v_sin
|
||||||
|
jmp .LBL_2_7
|
||||||
|
#endif
|
||||||
|
END (_ZGVeN8v_sin_skx)
|
||||||
|
-
|
||||||
|
- .section .rodata, "a"
|
||||||
|
-.L_2il0floatpacket.14:
|
||||||
|
- .long 0xffffffff,0xffffffff
|
||||||
|
- .type .L_2il0floatpacket.14,@object
|
||||||
|
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_sincos8_core_avx512.S b/sysdeps/x86_64/fpu/multiarch/svml_d_sincos8_core_avx512.S
|
||||||
|
index 611887082a545854..a4944a4feef6aa98 100644
|
||||||
|
--- a/sysdeps/x86_64/fpu/multiarch/svml_d_sincos8_core_avx512.S
|
||||||
|
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_sincos8_core_avx512.S
|
||||||
|
@@ -430,7 +430,7 @@ WRAPPER_IMPL_AVX512_fFF _ZGVdN4vl8l8_sincos
|
||||||
|
|
||||||
|
/* SinPoly = SinR*SinPoly */
|
||||||
|
vfmadd213pd %zmm5, %zmm5, %zmm4
|
||||||
|
- vpbroadcastq .L_2il0floatpacket.15(%rip), %zmm3
|
||||||
|
+ vpternlogd $0xff, %zmm3, %zmm3, %zmm3
|
||||||
|
|
||||||
|
/* Update Cos result's sign */
|
||||||
|
vxorpd %zmm2, %zmm1, %zmm1
|
||||||
|
@@ -741,8 +741,3 @@ END (_ZGVeN8vvv_sincos_knl)
|
||||||
|
ENTRY (_ZGVeN8vvv_sincos_skx)
|
||||||
|
WRAPPER_AVX512_vvv_vl8l8 _ZGVeN8vl8l8_sincos_skx
|
||||||
|
END (_ZGVeN8vvv_sincos_skx)
|
||||||
|
-
|
||||||
|
- .section .rodata, "a"
|
||||||
|
-.L_2il0floatpacket.15:
|
||||||
|
- .long 0xffffffff,0xffffffff
|
||||||
|
- .type .L_2il0floatpacket.15,@object
|
||||||
|
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_cosf16_core_avx512.S b/sysdeps/x86_64/fpu/multiarch/svml_s_cosf16_core_avx512.S
|
||||||
|
index f671d60d5dab5a0e..fe8474fed943e8ad 100644
|
||||||
|
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_cosf16_core_avx512.S
|
||||||
|
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_cosf16_core_avx512.S
|
||||||
|
@@ -278,7 +278,7 @@ WRAPPER_IMPL_AVX512 _ZGVdN8v_cosf
|
||||||
|
X = X - Y*PI1 - Y*PI2 - Y*PI3
|
||||||
|
*/
|
||||||
|
vmovaps %zmm0, %zmm6
|
||||||
|
- vmovups .L_2il0floatpacket.13(%rip), %zmm12
|
||||||
|
+ vpternlogd $0xff, %zmm12, %zmm12, %zmm12
|
||||||
|
vmovups __sRShifter(%rax), %zmm3
|
||||||
|
vmovups __sPI1_FMA(%rax), %zmm5
|
||||||
|
vmovups __sA9_FMA(%rax), %zmm9
|
||||||
|
@@ -453,8 +453,3 @@ WRAPPER_IMPL_AVX512 _ZGVdN8v_cosf
|
||||||
|
jmp .LBL_2_7
|
||||||
|
#endif
|
||||||
|
END (_ZGVeN16v_cosf_skx)
|
||||||
|
-
|
||||||
|
- .section .rodata, "a"
|
||||||
|
-.L_2il0floatpacket.13:
|
||||||
|
- .long 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff
|
||||||
|
- .type .L_2il0floatpacket.13,@object
|
||||||
|
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_expf16_core_avx512.S b/sysdeps/x86_64/fpu/multiarch/svml_s_expf16_core_avx512.S
|
||||||
|
index 637bfe3c06ab9ad4..229b7828cde04db2 100644
|
||||||
|
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_expf16_core_avx512.S
|
||||||
|
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_expf16_core_avx512.S
|
||||||
|
@@ -264,7 +264,7 @@ WRAPPER_IMPL_AVX512 _ZGVdN8v_expf
|
||||||
|
vmovaps %zmm0, %zmm7
|
||||||
|
|
||||||
|
/* compare against threshold */
|
||||||
|
- vmovups .L_2il0floatpacket.13(%rip), %zmm3
|
||||||
|
+ vpternlogd $0xff, %zmm3, %zmm3, %zmm3
|
||||||
|
vmovups __sInvLn2(%rax), %zmm4
|
||||||
|
vmovups __sShifter(%rax), %zmm1
|
||||||
|
vmovups __sLn2hi(%rax), %zmm6
|
||||||
|
@@ -440,8 +440,3 @@ WRAPPER_IMPL_AVX512 _ZGVdN8v_expf
|
||||||
|
|
||||||
|
#endif
|
||||||
|
END (_ZGVeN16v_expf_skx)
|
||||||
|
-
|
||||||
|
- .section .rodata, "a"
|
||||||
|
-.L_2il0floatpacket.13:
|
||||||
|
- .long 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff
|
||||||
|
- .type .L_2il0floatpacket.13,@object
|
||||||
|
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_logf16_core_avx512.S b/sysdeps/x86_64/fpu/multiarch/svml_s_logf16_core_avx512.S
|
||||||
|
index 9d790fbf0ad6c8ec..fa2aae986f543582 100644
|
||||||
|
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_logf16_core_avx512.S
|
||||||
|
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_logf16_core_avx512.S
|
||||||
|
@@ -235,7 +235,7 @@ WRAPPER_IMPL_AVX512 _ZGVdN8v_logf
|
||||||
|
andq $-64, %rsp
|
||||||
|
subq $1280, %rsp
|
||||||
|
movq __svml_slog_data@GOTPCREL(%rip), %rax
|
||||||
|
- vmovups .L_2il0floatpacket.7(%rip), %zmm6
|
||||||
|
+ vpternlogd $0xff, %zmm6, %zmm6, %zmm6
|
||||||
|
vmovups _iBrkValue(%rax), %zmm4
|
||||||
|
vmovups _sPoly_7(%rax), %zmm8
|
||||||
|
|
||||||
|
@@ -409,8 +409,3 @@ WRAPPER_IMPL_AVX512 _ZGVdN8v_logf
|
||||||
|
|
||||||
|
#endif
|
||||||
|
END (_ZGVeN16v_logf_skx)
|
||||||
|
-
|
||||||
|
- .section .rodata, "a"
|
||||||
|
-.L_2il0floatpacket.7:
|
||||||
|
- .long 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff
|
||||||
|
- .type .L_2il0floatpacket.7,@object
|
||||||
|
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_powf16_core_avx512.S b/sysdeps/x86_64/fpu/multiarch/svml_s_powf16_core_avx512.S
|
||||||
|
index c5c43c46ff7af5a3..6aea2a4f11d1f85f 100644
|
||||||
|
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_powf16_core_avx512.S
|
||||||
|
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_powf16_core_avx512.S
|
||||||
|
@@ -385,7 +385,7 @@ WRAPPER_IMPL_AVX512_ff _ZGVdN8vv_powf
|
||||||
|
vpsrlq $32, %zmm3, %zmm2
|
||||||
|
vpmovqd %zmm2, %ymm11
|
||||||
|
vcvtps2pd %ymm14, %zmm13
|
||||||
|
- vmovups .L_2il0floatpacket.23(%rip), %zmm14
|
||||||
|
+ vpternlogd $0xff, %zmm14, %zmm14, %zmm14
|
||||||
|
vmovaps %zmm14, %zmm26
|
||||||
|
vpandd _ABSMASK(%rax), %zmm1, %zmm8
|
||||||
|
vpcmpd $1, _INF(%rax), %zmm8, %k2
|
||||||
|
@@ -427,7 +427,7 @@ WRAPPER_IMPL_AVX512_ff _ZGVdN8vv_powf
|
||||||
|
vpmovqd %zmm11, %ymm5
|
||||||
|
vpxord %zmm10, %zmm10, %zmm10
|
||||||
|
vgatherdpd _Log2Rcp_lookup(%rax,%ymm4), %zmm10{%k3}
|
||||||
|
- vpbroadcastq .L_2il0floatpacket.24(%rip), %zmm4
|
||||||
|
+ vpternlogd $0xff, %zmm4, %zmm4, %zmm4
|
||||||
|
vpxord %zmm11, %zmm11, %zmm11
|
||||||
|
vcvtdq2pd %ymm7, %zmm7
|
||||||
|
vgatherdpd _Log2Rcp_lookup(%rax,%ymm5), %zmm11{%k1}
|
||||||
|
@@ -643,11 +643,3 @@ WRAPPER_IMPL_AVX512_ff _ZGVdN8vv_powf
|
||||||
|
jmp .LBL_2_7
|
||||||
|
#endif
|
||||||
|
END (_ZGVeN16vv_powf_skx)
|
||||||
|
-
|
||||||
|
- .section .rodata, "a"
|
||||||
|
-.L_2il0floatpacket.23:
|
||||||
|
- .long 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff
|
||||||
|
- .type .L_2il0floatpacket.23,@object
|
||||||
|
-.L_2il0floatpacket.24:
|
||||||
|
- .long 0xffffffff,0xffffffff
|
||||||
|
- .type .L_2il0floatpacket.24,@object
|
||||||
|
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf16_core_avx512.S b/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf16_core_avx512.S
|
||||||
|
index 9cf359c86ff9bd70..a446c504f63c9399 100644
|
||||||
|
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf16_core_avx512.S
|
||||||
|
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_sincosf16_core_avx512.S
|
||||||
|
@@ -317,7 +317,7 @@ WRAPPER_IMPL_AVX512_fFF _ZGVdN8vvv_sincosf
|
||||||
|
|
||||||
|
/* Result sign calculations */
|
||||||
|
vpternlogd $150, %zmm0, %zmm14, %zmm1
|
||||||
|
- vmovups .L_2il0floatpacket.13(%rip), %zmm14
|
||||||
|
+ vpternlogd $0xff, %zmm14, %zmm14, %zmm14
|
||||||
|
|
||||||
|
/* Add correction term 0.5 for cos() part */
|
||||||
|
vaddps %zmm8, %zmm5, %zmm15
|
||||||
|
@@ -748,8 +748,3 @@ END (_ZGVeN16vvv_sincosf_knl)
|
||||||
|
ENTRY (_ZGVeN16vvv_sincosf_skx)
|
||||||
|
WRAPPER_AVX512_vvv_vl4l4 _ZGVeN16vl4l4_sincosf_skx
|
||||||
|
END (_ZGVeN16vvv_sincosf_skx)
|
||||||
|
-
|
||||||
|
- .section .rodata, "a"
|
||||||
|
-.L_2il0floatpacket.13:
|
||||||
|
- .long 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff
|
||||||
|
- .type .L_2il0floatpacket.13,@object
|
||||||
|
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_s_sinf16_core_avx512.S b/sysdeps/x86_64/fpu/multiarch/svml_s_sinf16_core_avx512.S
|
||||||
|
index bd05109a62181f22..c1b352d0ad1992cd 100644
|
||||||
|
--- a/sysdeps/x86_64/fpu/multiarch/svml_s_sinf16_core_avx512.S
|
||||||
|
+++ b/sysdeps/x86_64/fpu/multiarch/svml_s_sinf16_core_avx512.S
|
||||||
|
@@ -280,7 +280,7 @@ WRAPPER_IMPL_AVX512 _ZGVdN8v_sinf
|
||||||
|
movq __svml_s_trig_data@GOTPCREL(%rip), %rax
|
||||||
|
|
||||||
|
/* Check for large and special values */
|
||||||
|
- vmovups .L_2il0floatpacket.11(%rip), %zmm14
|
||||||
|
+ vpternlogd $0xff, %zmm14, %zmm14, %zmm14
|
||||||
|
vmovups __sAbsMask(%rax), %zmm5
|
||||||
|
vmovups __sInvPI(%rax), %zmm1
|
||||||
|
vmovups __sRShifter(%rax), %zmm2
|
||||||
|
@@ -472,8 +472,3 @@ WRAPPER_IMPL_AVX512 _ZGVdN8v_sinf
|
||||||
|
jmp .LBL_2_7
|
||||||
|
#endif
|
||||||
|
END (_ZGVeN16v_sinf_skx)
|
||||||
|
-
|
||||||
|
- .section .rodata, "a"
|
||||||
|
-.L_2il0floatpacket.11:
|
||||||
|
- .long 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff
|
||||||
|
- .type .L_2il0floatpacket.11,@object
|
42
glibc-upstream-2.34-174.patch
Normal file
42
glibc-upstream-2.34-174.patch
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
commit b5a44a6a471aafd3677659a610f32468c40a666b
|
||||||
|
Author: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||||
|
Date: Tue Sep 21 18:31:49 2021 -0500
|
||||||
|
|
||||||
|
x86: Modify ENTRY in sysdep.h so that p2align can be specified
|
||||||
|
|
||||||
|
No bug.
|
||||||
|
|
||||||
|
This change adds a new macro ENTRY_P2ALIGN which takes a second
|
||||||
|
argument, log2 of the desired function alignment.
|
||||||
|
|
||||||
|
The old ENTRY(name) macro is just ENTRY_P2ALIGN(name, 4) so this
|
||||||
|
doesn't affect any existing functionality.
|
||||||
|
|
||||||
|
Signed-off-by: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||||
|
(cherry picked from commit fc5bd179ef3a953dff8d1655bd530d0e230ffe71)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/x86/sysdep.h b/sysdeps/x86/sysdep.h
|
||||||
|
index cac1d762fb3f99d0..937180c1bd791570 100644
|
||||||
|
--- a/sysdeps/x86/sysdep.h
|
||||||
|
+++ b/sysdeps/x86/sysdep.h
|
||||||
|
@@ -78,15 +78,18 @@ enum cf_protection_level
|
||||||
|
#define ASM_SIZE_DIRECTIVE(name) .size name,.-name;
|
||||||
|
|
||||||
|
/* Define an entry point visible from C. */
|
||||||
|
-#define ENTRY(name) \
|
||||||
|
+#define ENTRY_P2ALIGN(name, alignment) \
|
||||||
|
.globl C_SYMBOL_NAME(name); \
|
||||||
|
.type C_SYMBOL_NAME(name),@function; \
|
||||||
|
- .align ALIGNARG(4); \
|
||||||
|
+ .align ALIGNARG(alignment); \
|
||||||
|
C_LABEL(name) \
|
||||||
|
cfi_startproc; \
|
||||||
|
_CET_ENDBR; \
|
||||||
|
CALL_MCOUNT
|
||||||
|
|
||||||
|
+/* Common entry 16 byte aligns. */
|
||||||
|
+#define ENTRY(name) ENTRY_P2ALIGN (name, 4)
|
||||||
|
+
|
||||||
|
#undef END
|
||||||
|
#define END(name) \
|
||||||
|
cfi_endproc; \
|
653
glibc-upstream-2.34-175.patch
Normal file
653
glibc-upstream-2.34-175.patch
Normal file
@ -0,0 +1,653 @@
|
|||||||
|
commit 5ec3416853c4150c4d13312e05f93a053586d528
|
||||||
|
Author: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||||
|
Date: Tue Sep 21 18:45:03 2021 -0500
|
||||||
|
|
||||||
|
x86: Optimize memcmp-evex-movbe.S for frontend behavior and size
|
||||||
|
|
||||||
|
No bug.
|
||||||
|
|
||||||
|
The frontend optimizations are to:
|
||||||
|
1. Reorganize logically connected basic blocks so they are either in
|
||||||
|
the same cache line or adjacent cache lines.
|
||||||
|
2. Avoid cases when basic blocks unnecissarily cross cache lines.
|
||||||
|
3. Try and 32 byte align any basic blocks possible without sacrificing
|
||||||
|
code size. Smaller / Less hot basic blocks are used for this.
|
||||||
|
|
||||||
|
Overall code size shrunk by 168 bytes. This should make up for any
|
||||||
|
extra costs due to aligning to 64 bytes.
|
||||||
|
|
||||||
|
In general performance before deviated a great deal dependending on
|
||||||
|
whether entry alignment % 64 was 0, 16, 32, or 48. These changes
|
||||||
|
essentially make it so that the current implementation is at least
|
||||||
|
equal to the best alignment of the original for any arguments.
|
||||||
|
|
||||||
|
The only additional optimization is in the page cross case. Branch on
|
||||||
|
equals case was removed from the size == [4, 7] case. As well the [4,
|
||||||
|
7] and [2, 3] case where swapped as [4, 7] is likely a more hot
|
||||||
|
argument size.
|
||||||
|
|
||||||
|
test-memcmp and test-wmemcmp are both passing.
|
||||||
|
|
||||||
|
(cherry picked from commit 1bd8b8d58fc9967cc073d2c13bfb6befefca2faa)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S b/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S
|
||||||
|
index 654dc7ac8ccb9445..2761b54f2e7dea9f 100644
|
||||||
|
--- a/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S
|
||||||
|
+++ b/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S
|
||||||
|
@@ -34,7 +34,24 @@
|
||||||
|
area.
|
||||||
|
7. Use 2 vector compares when size is 2 * CHAR_PER_VEC or less.
|
||||||
|
8. Use 4 vector compares when size is 4 * CHAR_PER_VEC or less.
|
||||||
|
- 9. Use 8 vector compares when size is 8 * CHAR_PER_VEC or less. */
|
||||||
|
+ 9. Use 8 vector compares when size is 8 * CHAR_PER_VEC or less.
|
||||||
|
+
|
||||||
|
+When possible the implementation tries to optimize for frontend in the
|
||||||
|
+following ways:
|
||||||
|
+Throughput:
|
||||||
|
+ 1. All code sections that fit are able to run optimally out of the
|
||||||
|
+ LSD.
|
||||||
|
+ 2. All code sections that fit are able to run optimally out of the
|
||||||
|
+ DSB
|
||||||
|
+ 3. Basic blocks are contained in minimum number of fetch blocks
|
||||||
|
+ necessary.
|
||||||
|
+
|
||||||
|
+Latency:
|
||||||
|
+ 1. Logically connected basic blocks are put in the same
|
||||||
|
+ cache-line.
|
||||||
|
+ 2. Logically connected basic blocks that do not fit in the same
|
||||||
|
+ cache-line are put in adjacent lines. This can get beneficial
|
||||||
|
+ L2 spatial prefetching and L1 next-line prefetching. */
|
||||||
|
|
||||||
|
# include <sysdep.h>
|
||||||
|
|
||||||
|
@@ -47,9 +64,11 @@
|
||||||
|
# ifdef USE_AS_WMEMCMP
|
||||||
|
# define CHAR_SIZE 4
|
||||||
|
# define VPCMP vpcmpd
|
||||||
|
+# define VPTEST vptestmd
|
||||||
|
# else
|
||||||
|
# define CHAR_SIZE 1
|
||||||
|
# define VPCMP vpcmpub
|
||||||
|
+# define VPTEST vptestmb
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# define VEC_SIZE 32
|
||||||
|
@@ -75,7 +94,9 @@
|
||||||
|
*/
|
||||||
|
|
||||||
|
.section .text.evex,"ax",@progbits
|
||||||
|
-ENTRY (MEMCMP)
|
||||||
|
+/* Cache align memcmp entry. This allows for much more thorough
|
||||||
|
+ frontend optimization. */
|
||||||
|
+ENTRY_P2ALIGN (MEMCMP, 6)
|
||||||
|
# ifdef __ILP32__
|
||||||
|
/* Clear the upper 32 bits. */
|
||||||
|
movl %edx, %edx
|
||||||
|
@@ -89,7 +110,7 @@ ENTRY (MEMCMP)
|
||||||
|
VPCMP $4, (%rdi), %YMM1, %k1
|
||||||
|
kmovd %k1, %eax
|
||||||
|
/* NB: eax must be destination register if going to
|
||||||
|
- L(return_vec_[0,2]). For L(return_vec_3 destination register
|
||||||
|
+ L(return_vec_[0,2]). For L(return_vec_3) destination register
|
||||||
|
must be ecx. */
|
||||||
|
testl %eax, %eax
|
||||||
|
jnz L(return_vec_0)
|
||||||
|
@@ -121,10 +142,6 @@ ENTRY (MEMCMP)
|
||||||
|
testl %ecx, %ecx
|
||||||
|
jnz L(return_vec_3)
|
||||||
|
|
||||||
|
- /* Zero YMM0. 4x VEC reduction is done with vpxor + vtern so
|
||||||
|
- compare with zero to get a mask is needed. */
|
||||||
|
- vpxorq %XMM0, %XMM0, %XMM0
|
||||||
|
-
|
||||||
|
/* Go to 4x VEC loop. */
|
||||||
|
cmpq $(CHAR_PER_VEC * 8), %rdx
|
||||||
|
ja L(more_8x_vec)
|
||||||
|
@@ -148,47 +165,61 @@ ENTRY (MEMCMP)
|
||||||
|
|
||||||
|
VMOVU (VEC_SIZE * 2)(%rsi), %YMM3
|
||||||
|
vpxorq (VEC_SIZE * 2)(%rdi), %YMM3, %YMM3
|
||||||
|
- /* Or together YMM1, YMM2, and YMM3 into YMM3. */
|
||||||
|
- vpternlogd $0xfe, %YMM1, %YMM2, %YMM3
|
||||||
|
|
||||||
|
VMOVU (VEC_SIZE * 3)(%rsi), %YMM4
|
||||||
|
/* Ternary logic to xor (VEC_SIZE * 3)(%rdi) with YMM4 while
|
||||||
|
- oring with YMM3. Result is stored in YMM4. */
|
||||||
|
- vpternlogd $0xde, (VEC_SIZE * 3)(%rdi), %YMM3, %YMM4
|
||||||
|
- /* Compare YMM4 with 0. If any 1s s1 and s2 don't match. */
|
||||||
|
- VPCMP $4, %YMM4, %YMM0, %k1
|
||||||
|
+ oring with YMM1. Result is stored in YMM4. */
|
||||||
|
+ vpternlogd $0xde, (VEC_SIZE * 3)(%rdi), %YMM1, %YMM4
|
||||||
|
+
|
||||||
|
+ /* Or together YMM2, YMM3, and YMM4 into YMM4. */
|
||||||
|
+ vpternlogd $0xfe, %YMM2, %YMM3, %YMM4
|
||||||
|
+
|
||||||
|
+ /* Test YMM4 against itself. Store any CHAR mismatches in k1.
|
||||||
|
+ */
|
||||||
|
+ VPTEST %YMM4, %YMM4, %k1
|
||||||
|
+ /* k1 must go to ecx for L(return_vec_0_1_2_3). */
|
||||||
|
kmovd %k1, %ecx
|
||||||
|
testl %ecx, %ecx
|
||||||
|
jnz L(return_vec_0_1_2_3)
|
||||||
|
/* NB: eax must be zero to reach here. */
|
||||||
|
ret
|
||||||
|
|
||||||
|
- /* NB: aligning 32 here allows for the rest of the jump targets
|
||||||
|
- to be tuned for 32 byte alignment. Most important this ensures
|
||||||
|
- the L(more_8x_vec) loop is 32 byte aligned. */
|
||||||
|
- .p2align 5
|
||||||
|
-L(less_vec):
|
||||||
|
- /* Check if one or less CHAR. This is necessary for size = 0 but
|
||||||
|
- is also faster for size = CHAR_SIZE. */
|
||||||
|
- cmpl $1, %edx
|
||||||
|
- jbe L(one_or_less)
|
||||||
|
+ .p2align 4
|
||||||
|
+L(8x_end_return_vec_0_1_2_3):
|
||||||
|
+ movq %rdx, %rdi
|
||||||
|
+L(8x_return_vec_0_1_2_3):
|
||||||
|
+ addq %rdi, %rsi
|
||||||
|
+L(return_vec_0_1_2_3):
|
||||||
|
+ VPTEST %YMM1, %YMM1, %k0
|
||||||
|
+ kmovd %k0, %eax
|
||||||
|
+ testl %eax, %eax
|
||||||
|
+ jnz L(return_vec_0)
|
||||||
|
|
||||||
|
- /* Check if loading one VEC from either s1 or s2 could cause a
|
||||||
|
- page cross. This can have false positives but is by far the
|
||||||
|
- fastest method. */
|
||||||
|
- movl %edi, %eax
|
||||||
|
- orl %esi, %eax
|
||||||
|
- andl $(PAGE_SIZE - 1), %eax
|
||||||
|
- cmpl $(PAGE_SIZE - VEC_SIZE), %eax
|
||||||
|
- jg L(page_cross_less_vec)
|
||||||
|
+ VPTEST %YMM2, %YMM2, %k0
|
||||||
|
+ kmovd %k0, %eax
|
||||||
|
+ testl %eax, %eax
|
||||||
|
+ jnz L(return_vec_1)
|
||||||
|
|
||||||
|
- /* No page cross possible. */
|
||||||
|
- VMOVU (%rsi), %YMM2
|
||||||
|
- VPCMP $4, (%rdi), %YMM2, %k1
|
||||||
|
- kmovd %k1, %eax
|
||||||
|
- /* Create mask in ecx for potentially in bound matches. */
|
||||||
|
- bzhil %edx, %eax, %eax
|
||||||
|
- jnz L(return_vec_0)
|
||||||
|
+ VPTEST %YMM3, %YMM3, %k0
|
||||||
|
+ kmovd %k0, %eax
|
||||||
|
+ testl %eax, %eax
|
||||||
|
+ jnz L(return_vec_2)
|
||||||
|
+L(return_vec_3):
|
||||||
|
+ /* bsf saves 1 byte from tzcnt. This keep L(return_vec_3) in one
|
||||||
|
+ fetch block and the entire L(*return_vec_0_1_2_3) in 1 cache
|
||||||
|
+ line. */
|
||||||
|
+ bsfl %ecx, %ecx
|
||||||
|
+# ifdef USE_AS_WMEMCMP
|
||||||
|
+ movl (VEC_SIZE * 3)(%rdi, %rcx, CHAR_SIZE), %eax
|
||||||
|
+ xorl %edx, %edx
|
||||||
|
+ cmpl (VEC_SIZE * 3)(%rsi, %rcx, CHAR_SIZE), %eax
|
||||||
|
+ setg %dl
|
||||||
|
+ leal -1(%rdx, %rdx), %eax
|
||||||
|
+# else
|
||||||
|
+ movzbl (VEC_SIZE * 3)(%rdi, %rcx), %eax
|
||||||
|
+ movzbl (VEC_SIZE * 3)(%rsi, %rcx), %ecx
|
||||||
|
+ subl %ecx, %eax
|
||||||
|
+# endif
|
||||||
|
ret
|
||||||
|
|
||||||
|
.p2align 4
|
||||||
|
@@ -209,10 +240,11 @@ L(return_vec_0):
|
||||||
|
# endif
|
||||||
|
ret
|
||||||
|
|
||||||
|
- /* NB: No p2align necessary. Alignment % 16 is naturally 1
|
||||||
|
- which is good enough for a target not in a loop. */
|
||||||
|
+ .p2align 4
|
||||||
|
L(return_vec_1):
|
||||||
|
- tzcntl %eax, %eax
|
||||||
|
+ /* bsf saves 1 byte over tzcnt and keeps L(return_vec_1) in one
|
||||||
|
+ fetch block. */
|
||||||
|
+ bsfl %eax, %eax
|
||||||
|
# ifdef USE_AS_WMEMCMP
|
||||||
|
movl VEC_SIZE(%rdi, %rax, CHAR_SIZE), %ecx
|
||||||
|
xorl %edx, %edx
|
||||||
|
@@ -226,10 +258,11 @@ L(return_vec_1):
|
||||||
|
# endif
|
||||||
|
ret
|
||||||
|
|
||||||
|
- /* NB: No p2align necessary. Alignment % 16 is naturally 2
|
||||||
|
- which is good enough for a target not in a loop. */
|
||||||
|
+ .p2align 4,, 10
|
||||||
|
L(return_vec_2):
|
||||||
|
- tzcntl %eax, %eax
|
||||||
|
+ /* bsf saves 1 byte over tzcnt and keeps L(return_vec_2) in one
|
||||||
|
+ fetch block. */
|
||||||
|
+ bsfl %eax, %eax
|
||||||
|
# ifdef USE_AS_WMEMCMP
|
||||||
|
movl (VEC_SIZE * 2)(%rdi, %rax, CHAR_SIZE), %ecx
|
||||||
|
xorl %edx, %edx
|
||||||
|
@@ -243,40 +276,6 @@ L(return_vec_2):
|
||||||
|
# endif
|
||||||
|
ret
|
||||||
|
|
||||||
|
- .p2align 4
|
||||||
|
-L(8x_return_vec_0_1_2_3):
|
||||||
|
- /* Returning from L(more_8x_vec) requires restoring rsi. */
|
||||||
|
- addq %rdi, %rsi
|
||||||
|
-L(return_vec_0_1_2_3):
|
||||||
|
- VPCMP $4, %YMM1, %YMM0, %k0
|
||||||
|
- kmovd %k0, %eax
|
||||||
|
- testl %eax, %eax
|
||||||
|
- jnz L(return_vec_0)
|
||||||
|
-
|
||||||
|
- VPCMP $4, %YMM2, %YMM0, %k0
|
||||||
|
- kmovd %k0, %eax
|
||||||
|
- testl %eax, %eax
|
||||||
|
- jnz L(return_vec_1)
|
||||||
|
-
|
||||||
|
- VPCMP $4, %YMM3, %YMM0, %k0
|
||||||
|
- kmovd %k0, %eax
|
||||||
|
- testl %eax, %eax
|
||||||
|
- jnz L(return_vec_2)
|
||||||
|
-L(return_vec_3):
|
||||||
|
- tzcntl %ecx, %ecx
|
||||||
|
-# ifdef USE_AS_WMEMCMP
|
||||||
|
- movl (VEC_SIZE * 3)(%rdi, %rcx, CHAR_SIZE), %eax
|
||||||
|
- xorl %edx, %edx
|
||||||
|
- cmpl (VEC_SIZE * 3)(%rsi, %rcx, CHAR_SIZE), %eax
|
||||||
|
- setg %dl
|
||||||
|
- leal -1(%rdx, %rdx), %eax
|
||||||
|
-# else
|
||||||
|
- movzbl (VEC_SIZE * 3)(%rdi, %rcx), %eax
|
||||||
|
- movzbl (VEC_SIZE * 3)(%rsi, %rcx), %ecx
|
||||||
|
- subl %ecx, %eax
|
||||||
|
-# endif
|
||||||
|
- ret
|
||||||
|
-
|
||||||
|
.p2align 4
|
||||||
|
L(more_8x_vec):
|
||||||
|
/* Set end of s1 in rdx. */
|
||||||
|
@@ -288,21 +287,19 @@ L(more_8x_vec):
|
||||||
|
andq $-VEC_SIZE, %rdi
|
||||||
|
/* Adjust because first 4x vec where check already. */
|
||||||
|
subq $-(VEC_SIZE * 4), %rdi
|
||||||
|
+
|
||||||
|
.p2align 4
|
||||||
|
L(loop_4x_vec):
|
||||||
|
VMOVU (%rsi, %rdi), %YMM1
|
||||||
|
vpxorq (%rdi), %YMM1, %YMM1
|
||||||
|
-
|
||||||
|
VMOVU VEC_SIZE(%rsi, %rdi), %YMM2
|
||||||
|
vpxorq VEC_SIZE(%rdi), %YMM2, %YMM2
|
||||||
|
-
|
||||||
|
VMOVU (VEC_SIZE * 2)(%rsi, %rdi), %YMM3
|
||||||
|
vpxorq (VEC_SIZE * 2)(%rdi), %YMM3, %YMM3
|
||||||
|
- vpternlogd $0xfe, %YMM1, %YMM2, %YMM3
|
||||||
|
-
|
||||||
|
VMOVU (VEC_SIZE * 3)(%rsi, %rdi), %YMM4
|
||||||
|
- vpternlogd $0xde, (VEC_SIZE * 3)(%rdi), %YMM3, %YMM4
|
||||||
|
- VPCMP $4, %YMM4, %YMM0, %k1
|
||||||
|
+ vpternlogd $0xde, (VEC_SIZE * 3)(%rdi), %YMM1, %YMM4
|
||||||
|
+ vpternlogd $0xfe, %YMM2, %YMM3, %YMM4
|
||||||
|
+ VPTEST %YMM4, %YMM4, %k1
|
||||||
|
kmovd %k1, %ecx
|
||||||
|
testl %ecx, %ecx
|
||||||
|
jnz L(8x_return_vec_0_1_2_3)
|
||||||
|
@@ -319,28 +316,25 @@ L(loop_4x_vec):
|
||||||
|
cmpl $(VEC_SIZE * 2), %edi
|
||||||
|
jae L(8x_last_2x_vec)
|
||||||
|
|
||||||
|
+ vpxorq (VEC_SIZE * 2)(%rdx), %YMM3, %YMM3
|
||||||
|
+
|
||||||
|
VMOVU (%rsi, %rdx), %YMM1
|
||||||
|
vpxorq (%rdx), %YMM1, %YMM1
|
||||||
|
|
||||||
|
VMOVU VEC_SIZE(%rsi, %rdx), %YMM2
|
||||||
|
vpxorq VEC_SIZE(%rdx), %YMM2, %YMM2
|
||||||
|
-
|
||||||
|
- vpxorq (VEC_SIZE * 2)(%rdx), %YMM3, %YMM3
|
||||||
|
- vpternlogd $0xfe, %YMM1, %YMM2, %YMM3
|
||||||
|
-
|
||||||
|
VMOVU (VEC_SIZE * 3)(%rsi, %rdx), %YMM4
|
||||||
|
- vpternlogd $0xde, (VEC_SIZE * 3)(%rdx), %YMM3, %YMM4
|
||||||
|
- VPCMP $4, %YMM4, %YMM0, %k1
|
||||||
|
+ vpternlogd $0xde, (VEC_SIZE * 3)(%rdx), %YMM1, %YMM4
|
||||||
|
+ vpternlogd $0xfe, %YMM2, %YMM3, %YMM4
|
||||||
|
+ VPTEST %YMM4, %YMM4, %k1
|
||||||
|
kmovd %k1, %ecx
|
||||||
|
- /* Restore s1 pointer to rdi. */
|
||||||
|
- movq %rdx, %rdi
|
||||||
|
testl %ecx, %ecx
|
||||||
|
- jnz L(8x_return_vec_0_1_2_3)
|
||||||
|
+ jnz L(8x_end_return_vec_0_1_2_3)
|
||||||
|
/* NB: eax must be zero to reach here. */
|
||||||
|
ret
|
||||||
|
|
||||||
|
/* Only entry is from L(more_8x_vec). */
|
||||||
|
- .p2align 4
|
||||||
|
+ .p2align 4,, 10
|
||||||
|
L(8x_last_2x_vec):
|
||||||
|
VPCMP $4, (VEC_SIZE * 2)(%rdx), %YMM3, %k1
|
||||||
|
kmovd %k1, %eax
|
||||||
|
@@ -355,7 +349,31 @@ L(8x_last_1x_vec):
|
||||||
|
jnz L(8x_return_vec_3)
|
||||||
|
ret
|
||||||
|
|
||||||
|
- .p2align 4
|
||||||
|
+ /* Not ideally aligned (at offset +9 bytes in fetch block) but
|
||||||
|
+ not aligning keeps it in the same cache line as
|
||||||
|
+ L(8x_last_1x/2x_vec) so likely worth it. As well, saves code
|
||||||
|
+ size. */
|
||||||
|
+ .p2align 4,, 4
|
||||||
|
+L(8x_return_vec_2):
|
||||||
|
+ subq $VEC_SIZE, %rdx
|
||||||
|
+L(8x_return_vec_3):
|
||||||
|
+ bsfl %eax, %eax
|
||||||
|
+# ifdef USE_AS_WMEMCMP
|
||||||
|
+ leaq (%rdx, %rax, CHAR_SIZE), %rax
|
||||||
|
+ movl (VEC_SIZE * 3)(%rax), %ecx
|
||||||
|
+ xorl %edx, %edx
|
||||||
|
+ cmpl (VEC_SIZE * 3)(%rsi, %rax), %ecx
|
||||||
|
+ setg %dl
|
||||||
|
+ leal -1(%rdx, %rdx), %eax
|
||||||
|
+# else
|
||||||
|
+ addq %rdx, %rax
|
||||||
|
+ movzbl (VEC_SIZE * 3)(%rsi, %rax), %ecx
|
||||||
|
+ movzbl (VEC_SIZE * 3)(%rax), %eax
|
||||||
|
+ subl %ecx, %eax
|
||||||
|
+# endif
|
||||||
|
+ ret
|
||||||
|
+
|
||||||
|
+ .p2align 4,, 10
|
||||||
|
L(last_2x_vec):
|
||||||
|
/* Check second to last VEC. */
|
||||||
|
VMOVU -(VEC_SIZE * 2)(%rsi, %rdx, CHAR_SIZE), %YMM1
|
||||||
|
@@ -374,26 +392,49 @@ L(last_1x_vec):
|
||||||
|
jnz L(return_vec_0_end)
|
||||||
|
ret
|
||||||
|
|
||||||
|
- .p2align 4
|
||||||
|
-L(8x_return_vec_2):
|
||||||
|
- subq $VEC_SIZE, %rdx
|
||||||
|
-L(8x_return_vec_3):
|
||||||
|
- tzcntl %eax, %eax
|
||||||
|
+ .p2align 4,, 10
|
||||||
|
+L(return_vec_1_end):
|
||||||
|
+ /* Use bsf to save code size. This is necessary to have
|
||||||
|
+ L(one_or_less) fit in aligning bytes between. */
|
||||||
|
+ bsfl %eax, %eax
|
||||||
|
+ addl %edx, %eax
|
||||||
|
# ifdef USE_AS_WMEMCMP
|
||||||
|
- leaq (%rdx, %rax, CHAR_SIZE), %rax
|
||||||
|
- movl (VEC_SIZE * 3)(%rax), %ecx
|
||||||
|
+ movl -(VEC_SIZE * 2)(%rdi, %rax, CHAR_SIZE), %ecx
|
||||||
|
xorl %edx, %edx
|
||||||
|
- cmpl (VEC_SIZE * 3)(%rsi, %rax), %ecx
|
||||||
|
+ cmpl -(VEC_SIZE * 2)(%rsi, %rax, CHAR_SIZE), %ecx
|
||||||
|
setg %dl
|
||||||
|
leal -1(%rdx, %rdx), %eax
|
||||||
|
# else
|
||||||
|
- addq %rdx, %rax
|
||||||
|
- movzbl (VEC_SIZE * 3)(%rsi, %rax), %ecx
|
||||||
|
- movzbl (VEC_SIZE * 3)(%rax), %eax
|
||||||
|
+ movzbl -(VEC_SIZE * 2)(%rsi, %rax), %ecx
|
||||||
|
+ movzbl -(VEC_SIZE * 2)(%rdi, %rax), %eax
|
||||||
|
subl %ecx, %eax
|
||||||
|
# endif
|
||||||
|
ret
|
||||||
|
|
||||||
|
+ /* NB: L(one_or_less) fits in alignment padding between
|
||||||
|
+ L(return_vec_1_end) and L(return_vec_0_end). */
|
||||||
|
+# ifdef USE_AS_WMEMCMP
|
||||||
|
+L(one_or_less):
|
||||||
|
+ jb L(zero)
|
||||||
|
+ movl (%rdi), %ecx
|
||||||
|
+ xorl %edx, %edx
|
||||||
|
+ cmpl (%rsi), %ecx
|
||||||
|
+ je L(zero)
|
||||||
|
+ setg %dl
|
||||||
|
+ leal -1(%rdx, %rdx), %eax
|
||||||
|
+ ret
|
||||||
|
+# else
|
||||||
|
+L(one_or_less):
|
||||||
|
+ jb L(zero)
|
||||||
|
+ movzbl (%rsi), %ecx
|
||||||
|
+ movzbl (%rdi), %eax
|
||||||
|
+ subl %ecx, %eax
|
||||||
|
+ ret
|
||||||
|
+# endif
|
||||||
|
+L(zero):
|
||||||
|
+ xorl %eax, %eax
|
||||||
|
+ ret
|
||||||
|
+
|
||||||
|
.p2align 4
|
||||||
|
L(return_vec_0_end):
|
||||||
|
tzcntl %eax, %eax
|
||||||
|
@@ -412,23 +453,56 @@ L(return_vec_0_end):
|
||||||
|
ret
|
||||||
|
|
||||||
|
.p2align 4
|
||||||
|
-L(return_vec_1_end):
|
||||||
|
+L(less_vec):
|
||||||
|
+ /* Check if one or less CHAR. This is necessary for size == 0
|
||||||
|
+ but is also faster for size == CHAR_SIZE. */
|
||||||
|
+ cmpl $1, %edx
|
||||||
|
+ jbe L(one_or_less)
|
||||||
|
+
|
||||||
|
+ /* Check if loading one VEC from either s1 or s2 could cause a
|
||||||
|
+ page cross. This can have false positives but is by far the
|
||||||
|
+ fastest method. */
|
||||||
|
+ movl %edi, %eax
|
||||||
|
+ orl %esi, %eax
|
||||||
|
+ andl $(PAGE_SIZE - 1), %eax
|
||||||
|
+ cmpl $(PAGE_SIZE - VEC_SIZE), %eax
|
||||||
|
+ jg L(page_cross_less_vec)
|
||||||
|
+
|
||||||
|
+ /* No page cross possible. */
|
||||||
|
+ VMOVU (%rsi), %YMM2
|
||||||
|
+ VPCMP $4, (%rdi), %YMM2, %k1
|
||||||
|
+ kmovd %k1, %eax
|
||||||
|
+ /* Check if any matches where in bounds. Intentionally not
|
||||||
|
+ storing result in eax to limit dependency chain if it goes to
|
||||||
|
+ L(return_vec_0_lv). */
|
||||||
|
+ bzhil %edx, %eax, %edx
|
||||||
|
+ jnz L(return_vec_0_lv)
|
||||||
|
+ xorl %eax, %eax
|
||||||
|
+ ret
|
||||||
|
+
|
||||||
|
+ /* Essentially duplicate of L(return_vec_0). Ends up not costing
|
||||||
|
+ any code as shrinks L(less_vec) by allowing 2-byte encoding of
|
||||||
|
+ the jump and ends up fitting in aligning bytes. As well fits on
|
||||||
|
+ same cache line as L(less_vec) so also saves a line from having
|
||||||
|
+ to be fetched on cold calls to memcmp. */
|
||||||
|
+ .p2align 4,, 4
|
||||||
|
+L(return_vec_0_lv):
|
||||||
|
tzcntl %eax, %eax
|
||||||
|
- addl %edx, %eax
|
||||||
|
# ifdef USE_AS_WMEMCMP
|
||||||
|
- movl -(VEC_SIZE * 2)(%rdi, %rax, CHAR_SIZE), %ecx
|
||||||
|
+ movl (%rdi, %rax, CHAR_SIZE), %ecx
|
||||||
|
xorl %edx, %edx
|
||||||
|
- cmpl -(VEC_SIZE * 2)(%rsi, %rax, CHAR_SIZE), %ecx
|
||||||
|
+ cmpl (%rsi, %rax, CHAR_SIZE), %ecx
|
||||||
|
+ /* NB: no partial register stall here because xorl zero idiom
|
||||||
|
+ above. */
|
||||||
|
setg %dl
|
||||||
|
leal -1(%rdx, %rdx), %eax
|
||||||
|
# else
|
||||||
|
- movzbl -(VEC_SIZE * 2)(%rsi, %rax), %ecx
|
||||||
|
- movzbl -(VEC_SIZE * 2)(%rdi, %rax), %eax
|
||||||
|
+ movzbl (%rsi, %rax), %ecx
|
||||||
|
+ movzbl (%rdi, %rax), %eax
|
||||||
|
subl %ecx, %eax
|
||||||
|
# endif
|
||||||
|
ret
|
||||||
|
|
||||||
|
-
|
||||||
|
.p2align 4
|
||||||
|
L(page_cross_less_vec):
|
||||||
|
/* if USE_AS_WMEMCMP it can only be 0, 4, 8, 12, 16, 20, 24, 28
|
||||||
|
@@ -439,108 +513,84 @@ L(page_cross_less_vec):
|
||||||
|
cmpl $8, %edx
|
||||||
|
jae L(between_8_15)
|
||||||
|
cmpl $4, %edx
|
||||||
|
- jae L(between_4_7)
|
||||||
|
-L(between_2_3):
|
||||||
|
- /* Load as big endian to avoid branches. */
|
||||||
|
- movzwl (%rdi), %eax
|
||||||
|
- movzwl (%rsi), %ecx
|
||||||
|
- shll $8, %eax
|
||||||
|
- shll $8, %ecx
|
||||||
|
- bswap %eax
|
||||||
|
- bswap %ecx
|
||||||
|
- movzbl -1(%rdi, %rdx), %edi
|
||||||
|
- movzbl -1(%rsi, %rdx), %esi
|
||||||
|
- orl %edi, %eax
|
||||||
|
- orl %esi, %ecx
|
||||||
|
- /* Subtraction is okay because the upper 8 bits are zero. */
|
||||||
|
- subl %ecx, %eax
|
||||||
|
- ret
|
||||||
|
- .p2align 4
|
||||||
|
-L(one_or_less):
|
||||||
|
- jb L(zero)
|
||||||
|
- movzbl (%rsi), %ecx
|
||||||
|
- movzbl (%rdi), %eax
|
||||||
|
- subl %ecx, %eax
|
||||||
|
+ jb L(between_2_3)
|
||||||
|
+
|
||||||
|
+ /* Load as big endian with overlapping movbe to avoid branches.
|
||||||
|
+ */
|
||||||
|
+ movbe (%rdi), %eax
|
||||||
|
+ movbe (%rsi), %ecx
|
||||||
|
+ shlq $32, %rax
|
||||||
|
+ shlq $32, %rcx
|
||||||
|
+ movbe -4(%rdi, %rdx), %edi
|
||||||
|
+ movbe -4(%rsi, %rdx), %esi
|
||||||
|
+ orq %rdi, %rax
|
||||||
|
+ orq %rsi, %rcx
|
||||||
|
+ subq %rcx, %rax
|
||||||
|
+ /* edx is guranteed to be positive int32 in range [4, 7]. */
|
||||||
|
+ cmovne %edx, %eax
|
||||||
|
+ /* ecx is -1 if rcx > rax. Otherwise 0. */
|
||||||
|
+ sbbl %ecx, %ecx
|
||||||
|
+ /* If rcx > rax, then ecx is 0 and eax is positive. If rcx ==
|
||||||
|
+ rax then eax and ecx are zero. If rax < rax then ecx is -1 so
|
||||||
|
+ eax doesn't matter. */
|
||||||
|
+ orl %ecx, %eax
|
||||||
|
ret
|
||||||
|
|
||||||
|
- .p2align 4
|
||||||
|
+ .p2align 4,, 8
|
||||||
|
L(between_8_15):
|
||||||
|
# endif
|
||||||
|
/* If USE_AS_WMEMCMP fall through into 8-15 byte case. */
|
||||||
|
- vmovq (%rdi), %XMM1
|
||||||
|
- vmovq (%rsi), %XMM2
|
||||||
|
- VPCMP $4, %XMM1, %XMM2, %k1
|
||||||
|
+ vmovq (%rdi), %xmm1
|
||||||
|
+ vmovq (%rsi), %xmm2
|
||||||
|
+ VPCMP $4, %xmm1, %xmm2, %k1
|
||||||
|
kmovd %k1, %eax
|
||||||
|
testl %eax, %eax
|
||||||
|
- jnz L(return_vec_0)
|
||||||
|
+ jnz L(return_vec_0_lv)
|
||||||
|
/* Use overlapping loads to avoid branches. */
|
||||||
|
- leaq -8(%rdi, %rdx, CHAR_SIZE), %rdi
|
||||||
|
- leaq -8(%rsi, %rdx, CHAR_SIZE), %rsi
|
||||||
|
- vmovq (%rdi), %XMM1
|
||||||
|
- vmovq (%rsi), %XMM2
|
||||||
|
- VPCMP $4, %XMM1, %XMM2, %k1
|
||||||
|
+ vmovq -8(%rdi, %rdx, CHAR_SIZE), %xmm1
|
||||||
|
+ vmovq -8(%rsi, %rdx, CHAR_SIZE), %xmm2
|
||||||
|
+ VPCMP $4, %xmm1, %xmm2, %k1
|
||||||
|
+ addl $(CHAR_PER_VEC - (8 / CHAR_SIZE)), %edx
|
||||||
|
kmovd %k1, %eax
|
||||||
|
testl %eax, %eax
|
||||||
|
- jnz L(return_vec_0)
|
||||||
|
- ret
|
||||||
|
-
|
||||||
|
- .p2align 4
|
||||||
|
-L(zero):
|
||||||
|
- xorl %eax, %eax
|
||||||
|
+ jnz L(return_vec_0_end)
|
||||||
|
ret
|
||||||
|
|
||||||
|
- .p2align 4
|
||||||
|
+ .p2align 4,, 8
|
||||||
|
L(between_16_31):
|
||||||
|
/* From 16 to 31 bytes. No branch when size == 16. */
|
||||||
|
- VMOVU (%rsi), %XMM2
|
||||||
|
- VPCMP $4, (%rdi), %XMM2, %k1
|
||||||
|
+
|
||||||
|
+ /* Use movups to save code size. */
|
||||||
|
+ movups (%rsi), %xmm2
|
||||||
|
+ VPCMP $4, (%rdi), %xmm2, %k1
|
||||||
|
kmovd %k1, %eax
|
||||||
|
testl %eax, %eax
|
||||||
|
- jnz L(return_vec_0)
|
||||||
|
-
|
||||||
|
+ jnz L(return_vec_0_lv)
|
||||||
|
/* Use overlapping loads to avoid branches. */
|
||||||
|
-
|
||||||
|
- VMOVU -16(%rsi, %rdx, CHAR_SIZE), %XMM2
|
||||||
|
- leaq -16(%rdi, %rdx, CHAR_SIZE), %rdi
|
||||||
|
- leaq -16(%rsi, %rdx, CHAR_SIZE), %rsi
|
||||||
|
- VPCMP $4, (%rdi), %XMM2, %k1
|
||||||
|
+ movups -16(%rsi, %rdx, CHAR_SIZE), %xmm2
|
||||||
|
+ VPCMP $4, -16(%rdi, %rdx, CHAR_SIZE), %xmm2, %k1
|
||||||
|
+ addl $(CHAR_PER_VEC - (16 / CHAR_SIZE)), %edx
|
||||||
|
kmovd %k1, %eax
|
||||||
|
testl %eax, %eax
|
||||||
|
- jnz L(return_vec_0)
|
||||||
|
- ret
|
||||||
|
-
|
||||||
|
-# ifdef USE_AS_WMEMCMP
|
||||||
|
- .p2align 4
|
||||||
|
-L(one_or_less):
|
||||||
|
- jb L(zero)
|
||||||
|
- movl (%rdi), %ecx
|
||||||
|
- xorl %edx, %edx
|
||||||
|
- cmpl (%rsi), %ecx
|
||||||
|
- je L(zero)
|
||||||
|
- setg %dl
|
||||||
|
- leal -1(%rdx, %rdx), %eax
|
||||||
|
+ jnz L(return_vec_0_end)
|
||||||
|
ret
|
||||||
|
-# else
|
||||||
|
|
||||||
|
- .p2align 4
|
||||||
|
-L(between_4_7):
|
||||||
|
- /* Load as big endian with overlapping movbe to avoid branches.
|
||||||
|
- */
|
||||||
|
- movbe (%rdi), %eax
|
||||||
|
- movbe (%rsi), %ecx
|
||||||
|
- shlq $32, %rax
|
||||||
|
- shlq $32, %rcx
|
||||||
|
- movbe -4(%rdi, %rdx), %edi
|
||||||
|
- movbe -4(%rsi, %rdx), %esi
|
||||||
|
- orq %rdi, %rax
|
||||||
|
- orq %rsi, %rcx
|
||||||
|
- subq %rcx, %rax
|
||||||
|
- jz L(zero_4_7)
|
||||||
|
- sbbl %eax, %eax
|
||||||
|
- orl $1, %eax
|
||||||
|
-L(zero_4_7):
|
||||||
|
+# ifndef USE_AS_WMEMCMP
|
||||||
|
+L(between_2_3):
|
||||||
|
+ /* Load as big endian to avoid branches. */
|
||||||
|
+ movzwl (%rdi), %eax
|
||||||
|
+ movzwl (%rsi), %ecx
|
||||||
|
+ shll $8, %eax
|
||||||
|
+ shll $8, %ecx
|
||||||
|
+ bswap %eax
|
||||||
|
+ bswap %ecx
|
||||||
|
+ movzbl -1(%rdi, %rdx), %edi
|
||||||
|
+ movzbl -1(%rsi, %rdx), %esi
|
||||||
|
+ orl %edi, %eax
|
||||||
|
+ orl %esi, %ecx
|
||||||
|
+ /* Subtraction is okay because the upper 8 bits are zero. */
|
||||||
|
+ subl %ecx, %eax
|
||||||
|
ret
|
||||||
|
# endif
|
||||||
|
-
|
||||||
|
END (MEMCMP)
|
||||||
|
#endif
|
497
glibc-upstream-2.34-176.patch
Normal file
497
glibc-upstream-2.34-176.patch
Normal file
@ -0,0 +1,497 @@
|
|||||||
|
commit 6d18a93dbbde2958001d65dff3080beed7ae675a
|
||||||
|
Author: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||||
|
Date: Mon Sep 20 16:20:15 2021 -0500
|
||||||
|
|
||||||
|
x86: Optimize memset-vec-unaligned-erms.S
|
||||||
|
|
||||||
|
No bug.
|
||||||
|
|
||||||
|
Optimization are
|
||||||
|
|
||||||
|
1. change control flow for L(more_2x_vec) to fall through to loop and
|
||||||
|
jump for L(less_4x_vec) and L(less_8x_vec). This uses less code
|
||||||
|
size and saves jumps for length > 4x VEC_SIZE.
|
||||||
|
|
||||||
|
2. For EVEX/AVX512 move L(less_vec) closer to entry.
|
||||||
|
|
||||||
|
3. Avoid complex address mode for length > 2x VEC_SIZE
|
||||||
|
|
||||||
|
4. Slightly better aligning code for the loop from the perspective of
|
||||||
|
code size and uops.
|
||||||
|
|
||||||
|
5. Align targets so they make full use of their fetch block and if
|
||||||
|
possible cache line.
|
||||||
|
|
||||||
|
6. Try and reduce total number of icache lines that will need to be
|
||||||
|
pulled in for a given length.
|
||||||
|
|
||||||
|
7. Include "local" version of stosb target. For AVX2/EVEX/AVX512
|
||||||
|
jumping to the stosb target in the sse2 code section will almost
|
||||||
|
certainly be to a new page. The new version does increase code size
|
||||||
|
marginally by duplicating the target but should get better iTLB
|
||||||
|
behavior as a result.
|
||||||
|
|
||||||
|
test-memset, test-wmemset, and test-bzero are all passing.
|
||||||
|
|
||||||
|
Signed-off-by: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||||
|
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
||||||
|
(cherry picked from commit e59ced238482fd71f3e493717f14f6507346741e)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/x86_64/memset.S b/sysdeps/x86_64/memset.S
|
||||||
|
index 7d4a327eba29ecb4..0137eba4cdd9f830 100644
|
||||||
|
--- a/sysdeps/x86_64/memset.S
|
||||||
|
+++ b/sysdeps/x86_64/memset.S
|
||||||
|
@@ -18,13 +18,15 @@
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <sysdep.h>
|
||||||
|
+#define USE_WITH_SSE2 1
|
||||||
|
|
||||||
|
#define VEC_SIZE 16
|
||||||
|
+#define MOV_SIZE 3
|
||||||
|
+#define RET_SIZE 1
|
||||||
|
+
|
||||||
|
#define VEC(i) xmm##i
|
||||||
|
-/* Don't use movups and movaps since it will get larger nop paddings for
|
||||||
|
- alignment. */
|
||||||
|
-#define VMOVU movdqu
|
||||||
|
-#define VMOVA movdqa
|
||||||
|
+#define VMOVU movups
|
||||||
|
+#define VMOVA movaps
|
||||||
|
|
||||||
|
#define MEMSET_VDUP_TO_VEC0_AND_SET_RETURN(d, r) \
|
||||||
|
movd d, %xmm0; \
|
||||||
|
diff --git a/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms.S
|
||||||
|
index ae0860f36a47d594..1af668af0aeda59e 100644
|
||||||
|
--- a/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms.S
|
||||||
|
+++ b/sysdeps/x86_64/multiarch/memset-avx2-unaligned-erms.S
|
||||||
|
@@ -1,8 +1,14 @@
|
||||||
|
#if IS_IN (libc)
|
||||||
|
+# define USE_WITH_AVX2 1
|
||||||
|
+
|
||||||
|
# define VEC_SIZE 32
|
||||||
|
+# define MOV_SIZE 4
|
||||||
|
+# define RET_SIZE 4
|
||||||
|
+
|
||||||
|
# define VEC(i) ymm##i
|
||||||
|
-# define VMOVU vmovdqu
|
||||||
|
-# define VMOVA vmovdqa
|
||||||
|
+
|
||||||
|
+# define VMOVU vmovdqu
|
||||||
|
+# define VMOVA vmovdqa
|
||||||
|
|
||||||
|
# define MEMSET_VDUP_TO_VEC0_AND_SET_RETURN(d, r) \
|
||||||
|
vmovd d, %xmm0; \
|
||||||
|
diff --git a/sysdeps/x86_64/multiarch/memset-avx512-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-avx512-unaligned-erms.S
|
||||||
|
index 8ad842fc2f140527..f14d6f8493c21a36 100644
|
||||||
|
--- a/sysdeps/x86_64/multiarch/memset-avx512-unaligned-erms.S
|
||||||
|
+++ b/sysdeps/x86_64/multiarch/memset-avx512-unaligned-erms.S
|
||||||
|
@@ -1,11 +1,18 @@
|
||||||
|
#if IS_IN (libc)
|
||||||
|
+# define USE_WITH_AVX512 1
|
||||||
|
+
|
||||||
|
# define VEC_SIZE 64
|
||||||
|
+# define MOV_SIZE 6
|
||||||
|
+# define RET_SIZE 1
|
||||||
|
+
|
||||||
|
# define XMM0 xmm16
|
||||||
|
# define YMM0 ymm16
|
||||||
|
# define VEC0 zmm16
|
||||||
|
# define VEC(i) VEC##i
|
||||||
|
-# define VMOVU vmovdqu64
|
||||||
|
-# define VMOVA vmovdqa64
|
||||||
|
+
|
||||||
|
+# define VMOVU vmovdqu64
|
||||||
|
+# define VMOVA vmovdqa64
|
||||||
|
+
|
||||||
|
# define VZEROUPPER
|
||||||
|
|
||||||
|
# define MEMSET_VDUP_TO_VEC0_AND_SET_RETURN(d, r) \
|
||||||
|
diff --git a/sysdeps/x86_64/multiarch/memset-evex-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-evex-unaligned-erms.S
|
||||||
|
index 640f092903302ad0..64b09e77cc20cc42 100644
|
||||||
|
--- a/sysdeps/x86_64/multiarch/memset-evex-unaligned-erms.S
|
||||||
|
+++ b/sysdeps/x86_64/multiarch/memset-evex-unaligned-erms.S
|
||||||
|
@@ -1,11 +1,18 @@
|
||||||
|
#if IS_IN (libc)
|
||||||
|
+# define USE_WITH_EVEX 1
|
||||||
|
+
|
||||||
|
# define VEC_SIZE 32
|
||||||
|
+# define MOV_SIZE 6
|
||||||
|
+# define RET_SIZE 1
|
||||||
|
+
|
||||||
|
# define XMM0 xmm16
|
||||||
|
# define YMM0 ymm16
|
||||||
|
# define VEC0 ymm16
|
||||||
|
# define VEC(i) VEC##i
|
||||||
|
-# define VMOVU vmovdqu64
|
||||||
|
-# define VMOVA vmovdqa64
|
||||||
|
+
|
||||||
|
+# define VMOVU vmovdqu64
|
||||||
|
+# define VMOVA vmovdqa64
|
||||||
|
+
|
||||||
|
# define VZEROUPPER
|
||||||
|
|
||||||
|
# define MEMSET_VDUP_TO_VEC0_AND_SET_RETURN(d, r) \
|
||||||
|
diff --git a/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S
|
||||||
|
index ff196844a093dc3b..e723413a664c088f 100644
|
||||||
|
--- a/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S
|
||||||
|
+++ b/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S
|
||||||
|
@@ -63,8 +63,27 @@
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#if VEC_SIZE == 64
|
||||||
|
+# define LOOP_4X_OFFSET (VEC_SIZE * 4)
|
||||||
|
+#else
|
||||||
|
+# define LOOP_4X_OFFSET (0)
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#if defined USE_WITH_EVEX || defined USE_WITH_AVX512
|
||||||
|
+# define END_REG rcx
|
||||||
|
+# define LOOP_REG rdi
|
||||||
|
+#else
|
||||||
|
+# define END_REG rdi
|
||||||
|
+# define LOOP_REG rdx
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#define PAGE_SIZE 4096
|
||||||
|
|
||||||
|
+/* Macro to calculate size of small memset block for aligning
|
||||||
|
+ purposes. */
|
||||||
|
+#define SMALL_MEMSET_ALIGN(mov_sz, ret_sz) (2 * (mov_sz) + (ret_sz) + 1)
|
||||||
|
+
|
||||||
|
+
|
||||||
|
#ifndef SECTION
|
||||||
|
# error SECTION is not defined!
|
||||||
|
#endif
|
||||||
|
@@ -74,6 +93,7 @@
|
||||||
|
ENTRY (__bzero)
|
||||||
|
mov %RDI_LP, %RAX_LP /* Set return value. */
|
||||||
|
mov %RSI_LP, %RDX_LP /* Set n. */
|
||||||
|
+ xorl %esi, %esi
|
||||||
|
pxor %XMM0, %XMM0
|
||||||
|
jmp L(entry_from_bzero)
|
||||||
|
END (__bzero)
|
||||||
|
@@ -158,7 +178,7 @@ ENTRY_CHK (MEMSET_CHK_SYMBOL (__memset_chk, unaligned_erms))
|
||||||
|
END_CHK (MEMSET_CHK_SYMBOL (__memset_chk, unaligned_erms))
|
||||||
|
# endif
|
||||||
|
|
||||||
|
-ENTRY (MEMSET_SYMBOL (__memset, unaligned_erms))
|
||||||
|
+ENTRY_P2ALIGN (MEMSET_SYMBOL (__memset, unaligned_erms), 6)
|
||||||
|
MEMSET_VDUP_TO_VEC0_AND_SET_RETURN (%esi, %rdi)
|
||||||
|
# ifdef __ILP32__
|
||||||
|
/* Clear the upper 32 bits. */
|
||||||
|
@@ -168,75 +188,43 @@ ENTRY (MEMSET_SYMBOL (__memset, unaligned_erms))
|
||||||
|
jb L(less_vec)
|
||||||
|
cmp $(VEC_SIZE * 2), %RDX_LP
|
||||||
|
ja L(stosb_more_2x_vec)
|
||||||
|
- /* From VEC and to 2 * VEC. No branch when size == VEC_SIZE. */
|
||||||
|
- VMOVU %VEC(0), -VEC_SIZE(%rdi,%rdx)
|
||||||
|
- VMOVU %VEC(0), (%rdi)
|
||||||
|
+ /* From VEC and to 2 * VEC. No branch when size == VEC_SIZE.
|
||||||
|
+ */
|
||||||
|
+ VMOVU %VEC(0), (%rax)
|
||||||
|
+ VMOVU %VEC(0), -VEC_SIZE(%rax, %rdx)
|
||||||
|
VZEROUPPER_RETURN
|
||||||
|
-
|
||||||
|
- .p2align 4
|
||||||
|
-L(stosb_more_2x_vec):
|
||||||
|
- cmp __x86_rep_stosb_threshold(%rip), %RDX_LP
|
||||||
|
- ja L(stosb)
|
||||||
|
-#else
|
||||||
|
- .p2align 4
|
||||||
|
#endif
|
||||||
|
-L(more_2x_vec):
|
||||||
|
- /* Stores to first 2x VEC before cmp as any path forward will
|
||||||
|
- require it. */
|
||||||
|
- VMOVU %VEC(0), (%rdi)
|
||||||
|
- VMOVU %VEC(0), VEC_SIZE(%rdi)
|
||||||
|
- cmpq $(VEC_SIZE * 4), %rdx
|
||||||
|
- ja L(loop_start)
|
||||||
|
- VMOVU %VEC(0), -(VEC_SIZE * 2)(%rdi,%rdx)
|
||||||
|
- VMOVU %VEC(0), -VEC_SIZE(%rdi,%rdx)
|
||||||
|
-L(return):
|
||||||
|
-#if VEC_SIZE > 16
|
||||||
|
- ZERO_UPPER_VEC_REGISTERS_RETURN
|
||||||
|
+
|
||||||
|
+ .p2align 4,, 10
|
||||||
|
+L(last_2x_vec):
|
||||||
|
+#ifdef USE_LESS_VEC_MASK_STORE
|
||||||
|
+ VMOVU %VEC(0), (VEC_SIZE * 2 + LOOP_4X_OFFSET)(%rcx)
|
||||||
|
+ VMOVU %VEC(0), (VEC_SIZE * 3 + LOOP_4X_OFFSET)(%rcx)
|
||||||
|
#else
|
||||||
|
- ret
|
||||||
|
+ VMOVU %VEC(0), (VEC_SIZE * -2)(%rdi)
|
||||||
|
+ VMOVU %VEC(0), (VEC_SIZE * -1)(%rdi)
|
||||||
|
#endif
|
||||||
|
+ VZEROUPPER_RETURN
|
||||||
|
|
||||||
|
-L(loop_start):
|
||||||
|
- VMOVU %VEC(0), (VEC_SIZE * 2)(%rdi)
|
||||||
|
- VMOVU %VEC(0), (VEC_SIZE * 3)(%rdi)
|
||||||
|
- cmpq $(VEC_SIZE * 8), %rdx
|
||||||
|
- jbe L(loop_end)
|
||||||
|
- andq $-(VEC_SIZE * 2), %rdi
|
||||||
|
- subq $-(VEC_SIZE * 4), %rdi
|
||||||
|
- leaq -(VEC_SIZE * 4)(%rax, %rdx), %rcx
|
||||||
|
- .p2align 4
|
||||||
|
-L(loop):
|
||||||
|
- VMOVA %VEC(0), (%rdi)
|
||||||
|
- VMOVA %VEC(0), VEC_SIZE(%rdi)
|
||||||
|
- VMOVA %VEC(0), (VEC_SIZE * 2)(%rdi)
|
||||||
|
- VMOVA %VEC(0), (VEC_SIZE * 3)(%rdi)
|
||||||
|
- subq $-(VEC_SIZE * 4), %rdi
|
||||||
|
- cmpq %rcx, %rdi
|
||||||
|
- jb L(loop)
|
||||||
|
-L(loop_end):
|
||||||
|
- /* NB: rax is set as ptr in MEMSET_VDUP_TO_VEC0_AND_SET_RETURN.
|
||||||
|
- rdx as length is also unchanged. */
|
||||||
|
- VMOVU %VEC(0), -(VEC_SIZE * 4)(%rax, %rdx)
|
||||||
|
- VMOVU %VEC(0), -(VEC_SIZE * 3)(%rax, %rdx)
|
||||||
|
- VMOVU %VEC(0), -(VEC_SIZE * 2)(%rax, %rdx)
|
||||||
|
- VMOVU %VEC(0), -VEC_SIZE(%rax, %rdx)
|
||||||
|
- VZEROUPPER_SHORT_RETURN
|
||||||
|
-
|
||||||
|
- .p2align 4
|
||||||
|
+ /* If have AVX512 mask instructions put L(less_vec) close to
|
||||||
|
+ entry as it doesn't take much space and is likely a hot target.
|
||||||
|
+ */
|
||||||
|
+#ifdef USE_LESS_VEC_MASK_STORE
|
||||||
|
+ .p2align 4,, 10
|
||||||
|
L(less_vec):
|
||||||
|
/* Less than 1 VEC. */
|
||||||
|
# if VEC_SIZE != 16 && VEC_SIZE != 32 && VEC_SIZE != 64
|
||||||
|
# error Unsupported VEC_SIZE!
|
||||||
|
# endif
|
||||||
|
-# ifdef USE_LESS_VEC_MASK_STORE
|
||||||
|
/* Clear high bits from edi. Only keeping bits relevant to page
|
||||||
|
cross check. Note that we are using rax which is set in
|
||||||
|
- MEMSET_VDUP_TO_VEC0_AND_SET_RETURN as ptr from here on out.
|
||||||
|
- */
|
||||||
|
+ MEMSET_VDUP_TO_VEC0_AND_SET_RETURN as ptr from here on out. */
|
||||||
|
andl $(PAGE_SIZE - 1), %edi
|
||||||
|
- /* Check if VEC_SIZE store cross page. Mask stores suffer serious
|
||||||
|
- performance degradation when it has to fault supress. */
|
||||||
|
+ /* Check if VEC_SIZE store cross page. Mask stores suffer
|
||||||
|
+ serious performance degradation when it has to fault supress.
|
||||||
|
+ */
|
||||||
|
cmpl $(PAGE_SIZE - VEC_SIZE), %edi
|
||||||
|
+ /* This is generally considered a cold target. */
|
||||||
|
ja L(cross_page)
|
||||||
|
# if VEC_SIZE > 32
|
||||||
|
movq $-1, %rcx
|
||||||
|
@@ -247,58 +235,185 @@ L(less_vec):
|
||||||
|
bzhil %edx, %ecx, %ecx
|
||||||
|
kmovd %ecx, %k1
|
||||||
|
# endif
|
||||||
|
- vmovdqu8 %VEC(0), (%rax) {%k1}
|
||||||
|
+ vmovdqu8 %VEC(0), (%rax){%k1}
|
||||||
|
VZEROUPPER_RETURN
|
||||||
|
|
||||||
|
+# if defined USE_MULTIARCH && IS_IN (libc)
|
||||||
|
+ /* Include L(stosb_local) here if including L(less_vec) between
|
||||||
|
+ L(stosb_more_2x_vec) and ENTRY. This is to cache align the
|
||||||
|
+ L(stosb_more_2x_vec) target. */
|
||||||
|
+ .p2align 4,, 10
|
||||||
|
+L(stosb_local):
|
||||||
|
+ movzbl %sil, %eax
|
||||||
|
+ mov %RDX_LP, %RCX_LP
|
||||||
|
+ mov %RDI_LP, %RDX_LP
|
||||||
|
+ rep stosb
|
||||||
|
+ mov %RDX_LP, %RAX_LP
|
||||||
|
+ VZEROUPPER_RETURN
|
||||||
|
+# endif
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#if defined USE_MULTIARCH && IS_IN (libc)
|
||||||
|
.p2align 4
|
||||||
|
-L(cross_page):
|
||||||
|
+L(stosb_more_2x_vec):
|
||||||
|
+ cmp __x86_rep_stosb_threshold(%rip), %RDX_LP
|
||||||
|
+ ja L(stosb_local)
|
||||||
|
+#endif
|
||||||
|
+ /* Fallthrough goes to L(loop_4x_vec). Tests for memset (2x, 4x]
|
||||||
|
+ and (4x, 8x] jump to target. */
|
||||||
|
+L(more_2x_vec):
|
||||||
|
+
|
||||||
|
+ /* Two different methods of setting up pointers / compare. The
|
||||||
|
+ two methods are based on the fact that EVEX/AVX512 mov
|
||||||
|
+ instructions take more bytes then AVX2/SSE2 mov instructions. As
|
||||||
|
+ well that EVEX/AVX512 machines also have fast LEA_BID. Both
|
||||||
|
+ setup and END_REG to avoid complex address mode. For EVEX/AVX512
|
||||||
|
+ this saves code size and keeps a few targets in one fetch block.
|
||||||
|
+ For AVX2/SSE2 this helps prevent AGU bottlenecks. */
|
||||||
|
+#if defined USE_WITH_EVEX || defined USE_WITH_AVX512
|
||||||
|
+ /* If EVEX/AVX512 compute END_REG - (VEC_SIZE * 4 +
|
||||||
|
+ LOOP_4X_OFFSET) with LEA_BID. */
|
||||||
|
+
|
||||||
|
+ /* END_REG is rcx for EVEX/AVX512. */
|
||||||
|
+ leaq -(VEC_SIZE * 4 + LOOP_4X_OFFSET)(%rdi, %rdx), %END_REG
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ /* Stores to first 2x VEC before cmp as any path forward will
|
||||||
|
+ require it. */
|
||||||
|
+ VMOVU %VEC(0), (%rax)
|
||||||
|
+ VMOVU %VEC(0), VEC_SIZE(%rax)
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+#if !(defined USE_WITH_EVEX || defined USE_WITH_AVX512)
|
||||||
|
+ /* If AVX2/SSE2 compute END_REG (rdi) with ALU. */
|
||||||
|
+ addq %rdx, %END_REG
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ cmpq $(VEC_SIZE * 4), %rdx
|
||||||
|
+ jbe L(last_2x_vec)
|
||||||
|
+
|
||||||
|
+ /* Store next 2x vec regardless. */
|
||||||
|
+ VMOVU %VEC(0), (VEC_SIZE * 2)(%rax)
|
||||||
|
+ VMOVU %VEC(0), (VEC_SIZE * 3)(%rax)
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+#if defined USE_WITH_EVEX || defined USE_WITH_AVX512
|
||||||
|
+ /* If LOOP_4X_OFFSET don't readjust LOOP_REG (rdi), just add
|
||||||
|
+ extra offset to addresses in loop. Used for AVX512 to save space
|
||||||
|
+ as no way to get (VEC_SIZE * 4) in imm8. */
|
||||||
|
+# if LOOP_4X_OFFSET == 0
|
||||||
|
+ subq $-(VEC_SIZE * 4), %LOOP_REG
|
||||||
|
# endif
|
||||||
|
-# if VEC_SIZE > 32
|
||||||
|
- cmpb $32, %dl
|
||||||
|
- jae L(between_32_63)
|
||||||
|
+ /* Avoid imm32 compare here to save code size. */
|
||||||
|
+ cmpq %rdi, %rcx
|
||||||
|
+#else
|
||||||
|
+ addq $-(VEC_SIZE * 4), %END_REG
|
||||||
|
+ cmpq $(VEC_SIZE * 8), %rdx
|
||||||
|
+#endif
|
||||||
|
+ jbe L(last_4x_vec)
|
||||||
|
+#if !(defined USE_WITH_EVEX || defined USE_WITH_AVX512)
|
||||||
|
+ /* Set LOOP_REG (rdx). */
|
||||||
|
+ leaq (VEC_SIZE * 4)(%rax), %LOOP_REG
|
||||||
|
+#endif
|
||||||
|
+ /* Align dst for loop. */
|
||||||
|
+ andq $(VEC_SIZE * -2), %LOOP_REG
|
||||||
|
+ .p2align 4
|
||||||
|
+L(loop):
|
||||||
|
+ VMOVA %VEC(0), LOOP_4X_OFFSET(%LOOP_REG)
|
||||||
|
+ VMOVA %VEC(0), (VEC_SIZE + LOOP_4X_OFFSET)(%LOOP_REG)
|
||||||
|
+ VMOVA %VEC(0), (VEC_SIZE * 2 + LOOP_4X_OFFSET)(%LOOP_REG)
|
||||||
|
+ VMOVA %VEC(0), (VEC_SIZE * 3 + LOOP_4X_OFFSET)(%LOOP_REG)
|
||||||
|
+ subq $-(VEC_SIZE * 4), %LOOP_REG
|
||||||
|
+ cmpq %END_REG, %LOOP_REG
|
||||||
|
+ jb L(loop)
|
||||||
|
+ .p2align 4,, MOV_SIZE
|
||||||
|
+L(last_4x_vec):
|
||||||
|
+ VMOVU %VEC(0), LOOP_4X_OFFSET(%END_REG)
|
||||||
|
+ VMOVU %VEC(0), (VEC_SIZE + LOOP_4X_OFFSET)(%END_REG)
|
||||||
|
+ VMOVU %VEC(0), (VEC_SIZE * 2 + LOOP_4X_OFFSET)(%END_REG)
|
||||||
|
+ VMOVU %VEC(0), (VEC_SIZE * 3 + LOOP_4X_OFFSET)(%END_REG)
|
||||||
|
+L(return):
|
||||||
|
+#if VEC_SIZE > 16
|
||||||
|
+ ZERO_UPPER_VEC_REGISTERS_RETURN
|
||||||
|
+#else
|
||||||
|
+ ret
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ .p2align 4,, 10
|
||||||
|
+#ifndef USE_LESS_VEC_MASK_STORE
|
||||||
|
+# if defined USE_MULTIARCH && IS_IN (libc)
|
||||||
|
+ /* If no USE_LESS_VEC_MASK put L(stosb_local) here. Will be in
|
||||||
|
+ range for 2-byte jump encoding. */
|
||||||
|
+L(stosb_local):
|
||||||
|
+ movzbl %sil, %eax
|
||||||
|
+ mov %RDX_LP, %RCX_LP
|
||||||
|
+ mov %RDI_LP, %RDX_LP
|
||||||
|
+ rep stosb
|
||||||
|
+ mov %RDX_LP, %RAX_LP
|
||||||
|
+ VZEROUPPER_RETURN
|
||||||
|
# endif
|
||||||
|
-# if VEC_SIZE > 16
|
||||||
|
- cmpb $16, %dl
|
||||||
|
+ /* Define L(less_vec) only if not otherwise defined. */
|
||||||
|
+ .p2align 4
|
||||||
|
+L(less_vec):
|
||||||
|
+#endif
|
||||||
|
+L(cross_page):
|
||||||
|
+#if VEC_SIZE > 32
|
||||||
|
+ cmpl $32, %edx
|
||||||
|
+ jae L(between_32_63)
|
||||||
|
+#endif
|
||||||
|
+#if VEC_SIZE > 16
|
||||||
|
+ cmpl $16, %edx
|
||||||
|
jae L(between_16_31)
|
||||||
|
-# endif
|
||||||
|
- MOVQ %XMM0, %rcx
|
||||||
|
- cmpb $8, %dl
|
||||||
|
+#endif
|
||||||
|
+ MOVQ %XMM0, %rdi
|
||||||
|
+ cmpl $8, %edx
|
||||||
|
jae L(between_8_15)
|
||||||
|
- cmpb $4, %dl
|
||||||
|
+ cmpl $4, %edx
|
||||||
|
jae L(between_4_7)
|
||||||
|
- cmpb $1, %dl
|
||||||
|
+ cmpl $1, %edx
|
||||||
|
ja L(between_2_3)
|
||||||
|
- jb 1f
|
||||||
|
- movb %cl, (%rax)
|
||||||
|
-1:
|
||||||
|
+ jb L(return)
|
||||||
|
+ movb %sil, (%rax)
|
||||||
|
VZEROUPPER_RETURN
|
||||||
|
-# if VEC_SIZE > 32
|
||||||
|
+
|
||||||
|
+ /* Align small targets only if not doing so would cross a fetch
|
||||||
|
+ line. */
|
||||||
|
+#if VEC_SIZE > 32
|
||||||
|
+ .p2align 4,, SMALL_MEMSET_ALIGN(MOV_SIZE, RET_SIZE)
|
||||||
|
/* From 32 to 63. No branch when size == 32. */
|
||||||
|
L(between_32_63):
|
||||||
|
- VMOVU %YMM0, -32(%rax,%rdx)
|
||||||
|
VMOVU %YMM0, (%rax)
|
||||||
|
+ VMOVU %YMM0, -32(%rax, %rdx)
|
||||||
|
VZEROUPPER_RETURN
|
||||||
|
-# endif
|
||||||
|
-# if VEC_SIZE > 16
|
||||||
|
- /* From 16 to 31. No branch when size == 16. */
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#if VEC_SIZE >= 32
|
||||||
|
+ .p2align 4,, SMALL_MEMSET_ALIGN(MOV_SIZE, RET_SIZE)
|
||||||
|
L(between_16_31):
|
||||||
|
- VMOVU %XMM0, -16(%rax,%rdx)
|
||||||
|
+ /* From 16 to 31. No branch when size == 16. */
|
||||||
|
VMOVU %XMM0, (%rax)
|
||||||
|
+ VMOVU %XMM0, -16(%rax, %rdx)
|
||||||
|
VZEROUPPER_RETURN
|
||||||
|
-# endif
|
||||||
|
- /* From 8 to 15. No branch when size == 8. */
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ .p2align 4,, SMALL_MEMSET_ALIGN(3, RET_SIZE)
|
||||||
|
L(between_8_15):
|
||||||
|
- movq %rcx, -8(%rax,%rdx)
|
||||||
|
- movq %rcx, (%rax)
|
||||||
|
+ /* From 8 to 15. No branch when size == 8. */
|
||||||
|
+ movq %rdi, (%rax)
|
||||||
|
+ movq %rdi, -8(%rax, %rdx)
|
||||||
|
VZEROUPPER_RETURN
|
||||||
|
+
|
||||||
|
+ .p2align 4,, SMALL_MEMSET_ALIGN(2, RET_SIZE)
|
||||||
|
L(between_4_7):
|
||||||
|
/* From 4 to 7. No branch when size == 4. */
|
||||||
|
- movl %ecx, -4(%rax,%rdx)
|
||||||
|
- movl %ecx, (%rax)
|
||||||
|
+ movl %edi, (%rax)
|
||||||
|
+ movl %edi, -4(%rax, %rdx)
|
||||||
|
VZEROUPPER_RETURN
|
||||||
|
+
|
||||||
|
+ .p2align 4,, SMALL_MEMSET_ALIGN(3, RET_SIZE)
|
||||||
|
L(between_2_3):
|
||||||
|
/* From 2 to 3. No branch when size == 2. */
|
||||||
|
- movw %cx, -2(%rax,%rdx)
|
||||||
|
- movw %cx, (%rax)
|
||||||
|
+ movw %di, (%rax)
|
||||||
|
+ movb %dil, -1(%rax, %rdx)
|
||||||
|
VZEROUPPER_RETURN
|
||||||
|
END (MEMSET_SYMBOL (__memset, unaligned_erms))
|
40
glibc-upstream-2.34-177.patch
Normal file
40
glibc-upstream-2.34-177.patch
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
commit baf3ece63453adac59c5688930324a78ced5b2e4
|
||||||
|
Author: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||||
|
Date: Sat Oct 23 01:26:47 2021 -0400
|
||||||
|
|
||||||
|
x86: Replace sse2 instructions with avx in memcmp-evex-movbe.S
|
||||||
|
|
||||||
|
This commit replaces two usages of SSE2 'movups' with AVX 'vmovdqu'.
|
||||||
|
|
||||||
|
it could potentially be dangerous to use SSE2 if this function is ever
|
||||||
|
called without using 'vzeroupper' beforehand. While compilers appear
|
||||||
|
to use 'vzeroupper' before function calls if AVX2 has been used, using
|
||||||
|
SSE2 here is more brittle. Since it is not absolutely necessary it
|
||||||
|
should be avoided.
|
||||||
|
|
||||||
|
It costs 2-extra bytes but the extra bytes should only eat into
|
||||||
|
alignment padding.
|
||||||
|
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
||||||
|
|
||||||
|
(cherry picked from commit bad852b61b79503fcb3c5fc379c70f768df3e1fb)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S b/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S
|
||||||
|
index 2761b54f2e7dea9f..640f6757fac8a356 100644
|
||||||
|
--- a/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S
|
||||||
|
+++ b/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S
|
||||||
|
@@ -561,13 +561,13 @@ L(between_16_31):
|
||||||
|
/* From 16 to 31 bytes. No branch when size == 16. */
|
||||||
|
|
||||||
|
/* Use movups to save code size. */
|
||||||
|
- movups (%rsi), %xmm2
|
||||||
|
+ vmovdqu (%rsi), %xmm2
|
||||||
|
VPCMP $4, (%rdi), %xmm2, %k1
|
||||||
|
kmovd %k1, %eax
|
||||||
|
testl %eax, %eax
|
||||||
|
jnz L(return_vec_0_lv)
|
||||||
|
/* Use overlapping loads to avoid branches. */
|
||||||
|
- movups -16(%rsi, %rdx, CHAR_SIZE), %xmm2
|
||||||
|
+ vmovdqu -16(%rsi, %rdx, CHAR_SIZE), %xmm2
|
||||||
|
VPCMP $4, -16(%rdi, %rdx, CHAR_SIZE), %xmm2, %k1
|
||||||
|
addl $(CHAR_PER_VEC - (16 / CHAR_SIZE)), %edx
|
||||||
|
kmovd %k1, %eax
|
690
glibc-upstream-2.34-178.patch
Normal file
690
glibc-upstream-2.34-178.patch
Normal file
@ -0,0 +1,690 @@
|
|||||||
|
commit f35ad30da4880a1574996df0674986ecf82fa7ae
|
||||||
|
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||||
|
Date: Fri Oct 29 12:40:20 2021 -0700
|
||||||
|
|
||||||
|
x86-64: Improve EVEX strcmp with masked load
|
||||||
|
|
||||||
|
In strcmp-evex.S, to compare 2 32-byte strings, replace
|
||||||
|
|
||||||
|
VMOVU (%rdi, %rdx), %YMM0
|
||||||
|
VMOVU (%rsi, %rdx), %YMM1
|
||||||
|
/* Each bit in K0 represents a mismatch in YMM0 and YMM1. */
|
||||||
|
VPCMP $4, %YMM0, %YMM1, %k0
|
||||||
|
VPCMP $0, %YMMZERO, %YMM0, %k1
|
||||||
|
VPCMP $0, %YMMZERO, %YMM1, %k2
|
||||||
|
/* Each bit in K1 represents a NULL in YMM0 or YMM1. */
|
||||||
|
kord %k1, %k2, %k1
|
||||||
|
/* Each bit in K1 represents a NULL or a mismatch. */
|
||||||
|
kord %k0, %k1, %k1
|
||||||
|
kmovd %k1, %ecx
|
||||||
|
testl %ecx, %ecx
|
||||||
|
jne L(last_vector)
|
||||||
|
|
||||||
|
with
|
||||||
|
|
||||||
|
VMOVU (%rdi, %rdx), %YMM0
|
||||||
|
VPTESTM %YMM0, %YMM0, %k2
|
||||||
|
/* Each bit cleared in K1 represents a mismatch or a null CHAR
|
||||||
|
in YMM0 and 32 bytes at (%rsi, %rdx). */
|
||||||
|
VPCMP $0, (%rsi, %rdx), %YMM0, %k1{%k2}
|
||||||
|
kmovd %k1, %ecx
|
||||||
|
incl %ecx
|
||||||
|
jne L(last_vector)
|
||||||
|
|
||||||
|
It makes EVEX strcmp faster than AVX2 strcmp by up to 40% on Tiger Lake
|
||||||
|
and Ice Lake.
|
||||||
|
|
||||||
|
Co-Authored-By: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||||
|
(cherry picked from commit c46e9afb2df5fc9e39ff4d13777e4b4c26e04e55)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/x86_64/multiarch/strcmp-evex.S b/sysdeps/x86_64/multiarch/strcmp-evex.S
|
||||||
|
index d5aa6daa46c7ed25..82f12ac89bcae20b 100644
|
||||||
|
--- a/sysdeps/x86_64/multiarch/strcmp-evex.S
|
||||||
|
+++ b/sysdeps/x86_64/multiarch/strcmp-evex.S
|
||||||
|
@@ -41,6 +41,8 @@
|
||||||
|
# ifdef USE_AS_WCSCMP
|
||||||
|
/* Compare packed dwords. */
|
||||||
|
# define VPCMP vpcmpd
|
||||||
|
+# define VPMINU vpminud
|
||||||
|
+# define VPTESTM vptestmd
|
||||||
|
# define SHIFT_REG32 r8d
|
||||||
|
# define SHIFT_REG64 r8
|
||||||
|
/* 1 dword char == 4 bytes. */
|
||||||
|
@@ -48,6 +50,8 @@
|
||||||
|
# else
|
||||||
|
/* Compare packed bytes. */
|
||||||
|
# define VPCMP vpcmpb
|
||||||
|
+# define VPMINU vpminub
|
||||||
|
+# define VPTESTM vptestmb
|
||||||
|
# define SHIFT_REG32 ecx
|
||||||
|
# define SHIFT_REG64 rcx
|
||||||
|
/* 1 byte char == 1 byte. */
|
||||||
|
@@ -67,6 +71,9 @@
|
||||||
|
# define YMM5 ymm22
|
||||||
|
# define YMM6 ymm23
|
||||||
|
# define YMM7 ymm24
|
||||||
|
+# define YMM8 ymm25
|
||||||
|
+# define YMM9 ymm26
|
||||||
|
+# define YMM10 ymm27
|
||||||
|
|
||||||
|
/* Warning!
|
||||||
|
wcscmp/wcsncmp have to use SIGNED comparison for elements.
|
||||||
|
@@ -76,7 +83,7 @@
|
||||||
|
/* The main idea of the string comparison (byte or dword) using 256-bit
|
||||||
|
EVEX instructions consists of comparing (VPCMP) two ymm vectors. The
|
||||||
|
latter can be on either packed bytes or dwords depending on
|
||||||
|
- USE_AS_WCSCMP. In order to check the null char, algorithm keeps the
|
||||||
|
+ USE_AS_WCSCMP. In order to check the null CHAR, algorithm keeps the
|
||||||
|
matched bytes/dwords, requiring 5 EVEX instructions (3 VPCMP and 2
|
||||||
|
KORD). In general, the costs of comparing VEC_SIZE bytes (32-bytes)
|
||||||
|
are 3 VPCMP and 2 KORD instructions, together with VMOVU and ktestd
|
||||||
|
@@ -123,27 +130,21 @@ ENTRY (STRCMP)
|
||||||
|
jg L(cross_page)
|
||||||
|
/* Start comparing 4 vectors. */
|
||||||
|
VMOVU (%rdi), %YMM0
|
||||||
|
- VMOVU (%rsi), %YMM1
|
||||||
|
|
||||||
|
- /* Each bit in K0 represents a mismatch in YMM0 and YMM1. */
|
||||||
|
- VPCMP $4, %YMM0, %YMM1, %k0
|
||||||
|
+ /* Each bit set in K2 represents a non-null CHAR in YMM0. */
|
||||||
|
+ VPTESTM %YMM0, %YMM0, %k2
|
||||||
|
|
||||||
|
- /* Check for NULL in YMM0. */
|
||||||
|
- VPCMP $0, %YMMZERO, %YMM0, %k1
|
||||||
|
- /* Check for NULL in YMM1. */
|
||||||
|
- VPCMP $0, %YMMZERO, %YMM1, %k2
|
||||||
|
- /* Each bit in K1 represents a NULL in YMM0 or YMM1. */
|
||||||
|
- kord %k1, %k2, %k1
|
||||||
|
+ /* Each bit cleared in K1 represents a mismatch or a null CHAR
|
||||||
|
+ in YMM0 and 32 bytes at (%rsi). */
|
||||||
|
+ VPCMP $0, (%rsi), %YMM0, %k1{%k2}
|
||||||
|
|
||||||
|
- /* Each bit in K1 represents:
|
||||||
|
- 1. A mismatch in YMM0 and YMM1. Or
|
||||||
|
- 2. A NULL in YMM0 or YMM1.
|
||||||
|
- */
|
||||||
|
- kord %k0, %k1, %k1
|
||||||
|
-
|
||||||
|
- ktestd %k1, %k1
|
||||||
|
- je L(next_3_vectors)
|
||||||
|
kmovd %k1, %ecx
|
||||||
|
+# ifdef USE_AS_WCSCMP
|
||||||
|
+ subl $0xff, %ecx
|
||||||
|
+# else
|
||||||
|
+ incl %ecx
|
||||||
|
+# endif
|
||||||
|
+ je L(next_3_vectors)
|
||||||
|
tzcntl %ecx, %edx
|
||||||
|
# ifdef USE_AS_WCSCMP
|
||||||
|
/* NB: Multiply wchar_t count by 4 to get the number of bytes. */
|
||||||
|
@@ -172,9 +173,7 @@ L(return):
|
||||||
|
# endif
|
||||||
|
ret
|
||||||
|
|
||||||
|
- .p2align 4
|
||||||
|
L(return_vec_size):
|
||||||
|
- kmovd %k1, %ecx
|
||||||
|
tzcntl %ecx, %edx
|
||||||
|
# ifdef USE_AS_WCSCMP
|
||||||
|
/* NB: Multiply wchar_t count by 4 to get the number of bytes. */
|
||||||
|
@@ -210,9 +209,7 @@ L(return_vec_size):
|
||||||
|
# endif
|
||||||
|
ret
|
||||||
|
|
||||||
|
- .p2align 4
|
||||||
|
L(return_2_vec_size):
|
||||||
|
- kmovd %k1, %ecx
|
||||||
|
tzcntl %ecx, %edx
|
||||||
|
# ifdef USE_AS_WCSCMP
|
||||||
|
/* NB: Multiply wchar_t count by 4 to get the number of bytes. */
|
||||||
|
@@ -248,9 +245,7 @@ L(return_2_vec_size):
|
||||||
|
# endif
|
||||||
|
ret
|
||||||
|
|
||||||
|
- .p2align 4
|
||||||
|
L(return_3_vec_size):
|
||||||
|
- kmovd %k1, %ecx
|
||||||
|
tzcntl %ecx, %edx
|
||||||
|
# ifdef USE_AS_WCSCMP
|
||||||
|
/* NB: Multiply wchar_t count by 4 to get the number of bytes. */
|
||||||
|
@@ -289,43 +284,45 @@ L(return_3_vec_size):
|
||||||
|
.p2align 4
|
||||||
|
L(next_3_vectors):
|
||||||
|
VMOVU VEC_SIZE(%rdi), %YMM0
|
||||||
|
- VMOVU VEC_SIZE(%rsi), %YMM1
|
||||||
|
- /* Each bit in K0 represents a mismatch in YMM0 and YMM1. */
|
||||||
|
- VPCMP $4, %YMM0, %YMM1, %k0
|
||||||
|
- VPCMP $0, %YMMZERO, %YMM0, %k1
|
||||||
|
- VPCMP $0, %YMMZERO, %YMM1, %k2
|
||||||
|
- /* Each bit in K1 represents a NULL in YMM0 or YMM1. */
|
||||||
|
- kord %k1, %k2, %k1
|
||||||
|
- /* Each bit in K1 represents a NULL or a mismatch. */
|
||||||
|
- kord %k0, %k1, %k1
|
||||||
|
- ktestd %k1, %k1
|
||||||
|
+ /* Each bit set in K2 represents a non-null CHAR in YMM0. */
|
||||||
|
+ VPTESTM %YMM0, %YMM0, %k2
|
||||||
|
+ /* Each bit cleared in K1 represents a mismatch or a null CHAR
|
||||||
|
+ in YMM0 and 32 bytes at VEC_SIZE(%rsi). */
|
||||||
|
+ VPCMP $0, VEC_SIZE(%rsi), %YMM0, %k1{%k2}
|
||||||
|
+ kmovd %k1, %ecx
|
||||||
|
+# ifdef USE_AS_WCSCMP
|
||||||
|
+ subl $0xff, %ecx
|
||||||
|
+# else
|
||||||
|
+ incl %ecx
|
||||||
|
+# endif
|
||||||
|
jne L(return_vec_size)
|
||||||
|
|
||||||
|
- VMOVU (VEC_SIZE * 2)(%rdi), %YMM2
|
||||||
|
- VMOVU (VEC_SIZE * 3)(%rdi), %YMM3
|
||||||
|
- VMOVU (VEC_SIZE * 2)(%rsi), %YMM4
|
||||||
|
- VMOVU (VEC_SIZE * 3)(%rsi), %YMM5
|
||||||
|
-
|
||||||
|
- /* Each bit in K0 represents a mismatch in YMM2 and YMM4. */
|
||||||
|
- VPCMP $4, %YMM2, %YMM4, %k0
|
||||||
|
- VPCMP $0, %YMMZERO, %YMM2, %k1
|
||||||
|
- VPCMP $0, %YMMZERO, %YMM4, %k2
|
||||||
|
- /* Each bit in K1 represents a NULL in YMM2 or YMM4. */
|
||||||
|
- kord %k1, %k2, %k1
|
||||||
|
- /* Each bit in K1 represents a NULL or a mismatch. */
|
||||||
|
- kord %k0, %k1, %k1
|
||||||
|
- ktestd %k1, %k1
|
||||||
|
+ VMOVU (VEC_SIZE * 2)(%rdi), %YMM0
|
||||||
|
+ /* Each bit set in K2 represents a non-null CHAR in YMM0. */
|
||||||
|
+ VPTESTM %YMM0, %YMM0, %k2
|
||||||
|
+ /* Each bit cleared in K1 represents a mismatch or a null CHAR
|
||||||
|
+ in YMM0 and 32 bytes at (VEC_SIZE * 2)(%rsi). */
|
||||||
|
+ VPCMP $0, (VEC_SIZE * 2)(%rsi), %YMM0, %k1{%k2}
|
||||||
|
+ kmovd %k1, %ecx
|
||||||
|
+# ifdef USE_AS_WCSCMP
|
||||||
|
+ subl $0xff, %ecx
|
||||||
|
+# else
|
||||||
|
+ incl %ecx
|
||||||
|
+# endif
|
||||||
|
jne L(return_2_vec_size)
|
||||||
|
|
||||||
|
- /* Each bit in K0 represents a mismatch in YMM3 and YMM5. */
|
||||||
|
- VPCMP $4, %YMM3, %YMM5, %k0
|
||||||
|
- VPCMP $0, %YMMZERO, %YMM3, %k1
|
||||||
|
- VPCMP $0, %YMMZERO, %YMM5, %k2
|
||||||
|
- /* Each bit in K1 represents a NULL in YMM3 or YMM5. */
|
||||||
|
- kord %k1, %k2, %k1
|
||||||
|
- /* Each bit in K1 represents a NULL or a mismatch. */
|
||||||
|
- kord %k0, %k1, %k1
|
||||||
|
- ktestd %k1, %k1
|
||||||
|
+ VMOVU (VEC_SIZE * 3)(%rdi), %YMM0
|
||||||
|
+ /* Each bit set in K2 represents a non-null CHAR in YMM0. */
|
||||||
|
+ VPTESTM %YMM0, %YMM0, %k2
|
||||||
|
+ /* Each bit cleared in K1 represents a mismatch or a null CHAR
|
||||||
|
+ in YMM0 and 32 bytes at (VEC_SIZE * 2)(%rsi). */
|
||||||
|
+ VPCMP $0, (VEC_SIZE * 3)(%rsi), %YMM0, %k1{%k2}
|
||||||
|
+ kmovd %k1, %ecx
|
||||||
|
+# ifdef USE_AS_WCSCMP
|
||||||
|
+ subl $0xff, %ecx
|
||||||
|
+# else
|
||||||
|
+ incl %ecx
|
||||||
|
+# endif
|
||||||
|
jne L(return_3_vec_size)
|
||||||
|
L(main_loop_header):
|
||||||
|
leaq (VEC_SIZE * 4)(%rdi), %rdx
|
||||||
|
@@ -375,56 +372,51 @@ L(back_to_loop):
|
||||||
|
VMOVA VEC_SIZE(%rax), %YMM2
|
||||||
|
VMOVA (VEC_SIZE * 2)(%rax), %YMM4
|
||||||
|
VMOVA (VEC_SIZE * 3)(%rax), %YMM6
|
||||||
|
- VMOVU (%rdx), %YMM1
|
||||||
|
- VMOVU VEC_SIZE(%rdx), %YMM3
|
||||||
|
- VMOVU (VEC_SIZE * 2)(%rdx), %YMM5
|
||||||
|
- VMOVU (VEC_SIZE * 3)(%rdx), %YMM7
|
||||||
|
-
|
||||||
|
- VPCMP $4, %YMM0, %YMM1, %k0
|
||||||
|
- VPCMP $0, %YMMZERO, %YMM0, %k1
|
||||||
|
- VPCMP $0, %YMMZERO, %YMM1, %k2
|
||||||
|
- kord %k1, %k2, %k1
|
||||||
|
- /* Each bit in K4 represents a NULL or a mismatch in YMM0 and
|
||||||
|
- YMM1. */
|
||||||
|
- kord %k0, %k1, %k4
|
||||||
|
-
|
||||||
|
- VPCMP $4, %YMM2, %YMM3, %k0
|
||||||
|
- VPCMP $0, %YMMZERO, %YMM2, %k1
|
||||||
|
- VPCMP $0, %YMMZERO, %YMM3, %k2
|
||||||
|
- kord %k1, %k2, %k1
|
||||||
|
- /* Each bit in K5 represents a NULL or a mismatch in YMM2 and
|
||||||
|
- YMM3. */
|
||||||
|
- kord %k0, %k1, %k5
|
||||||
|
-
|
||||||
|
- VPCMP $4, %YMM4, %YMM5, %k0
|
||||||
|
- VPCMP $0, %YMMZERO, %YMM4, %k1
|
||||||
|
- VPCMP $0, %YMMZERO, %YMM5, %k2
|
||||||
|
- kord %k1, %k2, %k1
|
||||||
|
- /* Each bit in K6 represents a NULL or a mismatch in YMM4 and
|
||||||
|
- YMM5. */
|
||||||
|
- kord %k0, %k1, %k6
|
||||||
|
-
|
||||||
|
- VPCMP $4, %YMM6, %YMM7, %k0
|
||||||
|
- VPCMP $0, %YMMZERO, %YMM6, %k1
|
||||||
|
- VPCMP $0, %YMMZERO, %YMM7, %k2
|
||||||
|
- kord %k1, %k2, %k1
|
||||||
|
- /* Each bit in K7 represents a NULL or a mismatch in YMM6 and
|
||||||
|
- YMM7. */
|
||||||
|
- kord %k0, %k1, %k7
|
||||||
|
-
|
||||||
|
- kord %k4, %k5, %k0
|
||||||
|
- kord %k6, %k7, %k1
|
||||||
|
-
|
||||||
|
- /* Test each mask (32 bits) individually because for VEC_SIZE
|
||||||
|
- == 32 is not possible to OR the four masks and keep all bits
|
||||||
|
- in a 64-bit integer register, differing from SSE2 strcmp
|
||||||
|
- where ORing is possible. */
|
||||||
|
- kortestd %k0, %k1
|
||||||
|
- je L(loop)
|
||||||
|
- ktestd %k4, %k4
|
||||||
|
+
|
||||||
|
+ VPMINU %YMM0, %YMM2, %YMM8
|
||||||
|
+ VPMINU %YMM4, %YMM6, %YMM9
|
||||||
|
+
|
||||||
|
+ /* A zero CHAR in YMM8 means that there is a null CHAR. */
|
||||||
|
+ VPMINU %YMM8, %YMM9, %YMM8
|
||||||
|
+
|
||||||
|
+ /* Each bit set in K1 represents a non-null CHAR in YMM8. */
|
||||||
|
+ VPTESTM %YMM8, %YMM8, %k1
|
||||||
|
+
|
||||||
|
+ /* (YMM ^ YMM): A non-zero CHAR represents a mismatch. */
|
||||||
|
+ vpxorq (%rdx), %YMM0, %YMM1
|
||||||
|
+ vpxorq VEC_SIZE(%rdx), %YMM2, %YMM3
|
||||||
|
+ vpxorq (VEC_SIZE * 2)(%rdx), %YMM4, %YMM5
|
||||||
|
+ vpxorq (VEC_SIZE * 3)(%rdx), %YMM6, %YMM7
|
||||||
|
+
|
||||||
|
+ vporq %YMM1, %YMM3, %YMM9
|
||||||
|
+ vporq %YMM5, %YMM7, %YMM10
|
||||||
|
+
|
||||||
|
+ /* A non-zero CHAR in YMM9 represents a mismatch. */
|
||||||
|
+ vporq %YMM9, %YMM10, %YMM9
|
||||||
|
+
|
||||||
|
+ /* Each bit cleared in K0 represents a mismatch or a null CHAR. */
|
||||||
|
+ VPCMP $0, %YMMZERO, %YMM9, %k0{%k1}
|
||||||
|
+ kmovd %k0, %ecx
|
||||||
|
+# ifdef USE_AS_WCSCMP
|
||||||
|
+ subl $0xff, %ecx
|
||||||
|
+# else
|
||||||
|
+ incl %ecx
|
||||||
|
+# endif
|
||||||
|
+ je L(loop)
|
||||||
|
+
|
||||||
|
+ /* Each bit set in K1 represents a non-null CHAR in YMM0. */
|
||||||
|
+ VPTESTM %YMM0, %YMM0, %k1
|
||||||
|
+ /* Each bit cleared in K0 represents a mismatch or a null CHAR
|
||||||
|
+ in YMM0 and (%rdx). */
|
||||||
|
+ VPCMP $0, %YMMZERO, %YMM1, %k0{%k1}
|
||||||
|
+ kmovd %k0, %ecx
|
||||||
|
+# ifdef USE_AS_WCSCMP
|
||||||
|
+ subl $0xff, %ecx
|
||||||
|
+# else
|
||||||
|
+ incl %ecx
|
||||||
|
+# endif
|
||||||
|
je L(test_vec)
|
||||||
|
- kmovd %k4, %edi
|
||||||
|
- tzcntl %edi, %ecx
|
||||||
|
+ tzcntl %ecx, %ecx
|
||||||
|
# ifdef USE_AS_WCSCMP
|
||||||
|
/* NB: Multiply wchar_t count by 4 to get the number of bytes. */
|
||||||
|
sall $2, %ecx
|
||||||
|
@@ -466,9 +458,18 @@ L(test_vec):
|
||||||
|
cmpq $VEC_SIZE, %r11
|
||||||
|
jbe L(zero)
|
||||||
|
# endif
|
||||||
|
- ktestd %k5, %k5
|
||||||
|
+ /* Each bit set in K1 represents a non-null CHAR in YMM2. */
|
||||||
|
+ VPTESTM %YMM2, %YMM2, %k1
|
||||||
|
+ /* Each bit cleared in K0 represents a mismatch or a null CHAR
|
||||||
|
+ in YMM2 and VEC_SIZE(%rdx). */
|
||||||
|
+ VPCMP $0, %YMMZERO, %YMM3, %k0{%k1}
|
||||||
|
+ kmovd %k0, %ecx
|
||||||
|
+# ifdef USE_AS_WCSCMP
|
||||||
|
+ subl $0xff, %ecx
|
||||||
|
+# else
|
||||||
|
+ incl %ecx
|
||||||
|
+# endif
|
||||||
|
je L(test_2_vec)
|
||||||
|
- kmovd %k5, %ecx
|
||||||
|
tzcntl %ecx, %edi
|
||||||
|
# ifdef USE_AS_WCSCMP
|
||||||
|
/* NB: Multiply wchar_t count by 4 to get the number of bytes. */
|
||||||
|
@@ -512,9 +513,18 @@ L(test_2_vec):
|
||||||
|
cmpq $(VEC_SIZE * 2), %r11
|
||||||
|
jbe L(zero)
|
||||||
|
# endif
|
||||||
|
- ktestd %k6, %k6
|
||||||
|
+ /* Each bit set in K1 represents a non-null CHAR in YMM4. */
|
||||||
|
+ VPTESTM %YMM4, %YMM4, %k1
|
||||||
|
+ /* Each bit cleared in K0 represents a mismatch or a null CHAR
|
||||||
|
+ in YMM4 and (VEC_SIZE * 2)(%rdx). */
|
||||||
|
+ VPCMP $0, %YMMZERO, %YMM5, %k0{%k1}
|
||||||
|
+ kmovd %k0, %ecx
|
||||||
|
+# ifdef USE_AS_WCSCMP
|
||||||
|
+ subl $0xff, %ecx
|
||||||
|
+# else
|
||||||
|
+ incl %ecx
|
||||||
|
+# endif
|
||||||
|
je L(test_3_vec)
|
||||||
|
- kmovd %k6, %ecx
|
||||||
|
tzcntl %ecx, %edi
|
||||||
|
# ifdef USE_AS_WCSCMP
|
||||||
|
/* NB: Multiply wchar_t count by 4 to get the number of bytes. */
|
||||||
|
@@ -558,8 +568,18 @@ L(test_3_vec):
|
||||||
|
cmpq $(VEC_SIZE * 3), %r11
|
||||||
|
jbe L(zero)
|
||||||
|
# endif
|
||||||
|
- kmovd %k7, %esi
|
||||||
|
- tzcntl %esi, %ecx
|
||||||
|
+ /* Each bit set in K1 represents a non-null CHAR in YMM6. */
|
||||||
|
+ VPTESTM %YMM6, %YMM6, %k1
|
||||||
|
+ /* Each bit cleared in K0 represents a mismatch or a null CHAR
|
||||||
|
+ in YMM6 and (VEC_SIZE * 3)(%rdx). */
|
||||||
|
+ VPCMP $0, %YMMZERO, %YMM7, %k0{%k1}
|
||||||
|
+ kmovd %k0, %ecx
|
||||||
|
+# ifdef USE_AS_WCSCMP
|
||||||
|
+ subl $0xff, %ecx
|
||||||
|
+# else
|
||||||
|
+ incl %ecx
|
||||||
|
+# endif
|
||||||
|
+ tzcntl %ecx, %ecx
|
||||||
|
# ifdef USE_AS_WCSCMP
|
||||||
|
/* NB: Multiply wchar_t count by 4 to get the number of bytes. */
|
||||||
|
sall $2, %ecx
|
||||||
|
@@ -615,39 +635,51 @@ L(loop_cross_page):
|
||||||
|
|
||||||
|
VMOVU (%rax, %r10), %YMM2
|
||||||
|
VMOVU VEC_SIZE(%rax, %r10), %YMM3
|
||||||
|
- VMOVU (%rdx, %r10), %YMM4
|
||||||
|
- VMOVU VEC_SIZE(%rdx, %r10), %YMM5
|
||||||
|
-
|
||||||
|
- VPCMP $4, %YMM4, %YMM2, %k0
|
||||||
|
- VPCMP $0, %YMMZERO, %YMM2, %k1
|
||||||
|
- VPCMP $0, %YMMZERO, %YMM4, %k2
|
||||||
|
- kord %k1, %k2, %k1
|
||||||
|
- /* Each bit in K1 represents a NULL or a mismatch in YMM2 and
|
||||||
|
- YMM4. */
|
||||||
|
- kord %k0, %k1, %k1
|
||||||
|
-
|
||||||
|
- VPCMP $4, %YMM5, %YMM3, %k3
|
||||||
|
- VPCMP $0, %YMMZERO, %YMM3, %k4
|
||||||
|
- VPCMP $0, %YMMZERO, %YMM5, %k5
|
||||||
|
- kord %k4, %k5, %k4
|
||||||
|
- /* Each bit in K3 represents a NULL or a mismatch in YMM3 and
|
||||||
|
- YMM5. */
|
||||||
|
- kord %k3, %k4, %k3
|
||||||
|
+
|
||||||
|
+ /* Each bit set in K2 represents a non-null CHAR in YMM2. */
|
||||||
|
+ VPTESTM %YMM2, %YMM2, %k2
|
||||||
|
+ /* Each bit cleared in K1 represents a mismatch or a null CHAR
|
||||||
|
+ in YMM2 and 32 bytes at (%rdx, %r10). */
|
||||||
|
+ VPCMP $0, (%rdx, %r10), %YMM2, %k1{%k2}
|
||||||
|
+ kmovd %k1, %r9d
|
||||||
|
+ /* Don't use subl since it is the lower 16/32 bits of RDI
|
||||||
|
+ below. */
|
||||||
|
+ notl %r9d
|
||||||
|
+# ifdef USE_AS_WCSCMP
|
||||||
|
+ /* Only last 8 bits are valid. */
|
||||||
|
+ andl $0xff, %r9d
|
||||||
|
+# endif
|
||||||
|
+
|
||||||
|
+ /* Each bit set in K4 represents a non-null CHAR in YMM3. */
|
||||||
|
+ VPTESTM %YMM3, %YMM3, %k4
|
||||||
|
+ /* Each bit cleared in K3 represents a mismatch or a null CHAR
|
||||||
|
+ in YMM3 and 32 bytes at VEC_SIZE(%rdx, %r10). */
|
||||||
|
+ VPCMP $0, VEC_SIZE(%rdx, %r10), %YMM3, %k3{%k4}
|
||||||
|
+ kmovd %k3, %edi
|
||||||
|
+# ifdef USE_AS_WCSCMP
|
||||||
|
+ /* Don't use subl since it is the upper 8 bits of EDI below. */
|
||||||
|
+ notl %edi
|
||||||
|
+ andl $0xff, %edi
|
||||||
|
+# else
|
||||||
|
+ incl %edi
|
||||||
|
+# endif
|
||||||
|
|
||||||
|
# ifdef USE_AS_WCSCMP
|
||||||
|
- /* NB: Each bit in K1/K3 represents 4-byte element. */
|
||||||
|
- kshiftlw $8, %k3, %k2
|
||||||
|
+ /* NB: Each bit in EDI/R9D represents 4-byte element. */
|
||||||
|
+ sall $8, %edi
|
||||||
|
/* NB: Divide shift count by 4 since each bit in K1 represent 4
|
||||||
|
bytes. */
|
||||||
|
movl %ecx, %SHIFT_REG32
|
||||||
|
sarl $2, %SHIFT_REG32
|
||||||
|
+
|
||||||
|
+ /* Each bit in EDI represents a null CHAR or a mismatch. */
|
||||||
|
+ orl %r9d, %edi
|
||||||
|
# else
|
||||||
|
- kshiftlq $32, %k3, %k2
|
||||||
|
-# endif
|
||||||
|
+ salq $32, %rdi
|
||||||
|
|
||||||
|
- /* Each bit in K1 represents a NULL or a mismatch. */
|
||||||
|
- korq %k1, %k2, %k1
|
||||||
|
- kmovq %k1, %rdi
|
||||||
|
+ /* Each bit in RDI represents a null CHAR or a mismatch. */
|
||||||
|
+ orq %r9, %rdi
|
||||||
|
+# endif
|
||||||
|
|
||||||
|
/* Since ECX < VEC_SIZE * 2, simply skip the first ECX bytes. */
|
||||||
|
shrxq %SHIFT_REG64, %rdi, %rdi
|
||||||
|
@@ -692,35 +724,45 @@ L(loop_cross_page_2_vec):
|
||||||
|
/* The first VEC_SIZE * 2 bytes match or are ignored. */
|
||||||
|
VMOVU (VEC_SIZE * 2)(%rax, %r10), %YMM0
|
||||||
|
VMOVU (VEC_SIZE * 3)(%rax, %r10), %YMM1
|
||||||
|
- VMOVU (VEC_SIZE * 2)(%rdx, %r10), %YMM2
|
||||||
|
- VMOVU (VEC_SIZE * 3)(%rdx, %r10), %YMM3
|
||||||
|
-
|
||||||
|
- VPCMP $4, %YMM0, %YMM2, %k0
|
||||||
|
- VPCMP $0, %YMMZERO, %YMM0, %k1
|
||||||
|
- VPCMP $0, %YMMZERO, %YMM2, %k2
|
||||||
|
- kord %k1, %k2, %k1
|
||||||
|
- /* Each bit in K1 represents a NULL or a mismatch in YMM0 and
|
||||||
|
- YMM2. */
|
||||||
|
- kord %k0, %k1, %k1
|
||||||
|
-
|
||||||
|
- VPCMP $4, %YMM1, %YMM3, %k3
|
||||||
|
- VPCMP $0, %YMMZERO, %YMM1, %k4
|
||||||
|
- VPCMP $0, %YMMZERO, %YMM3, %k5
|
||||||
|
- kord %k4, %k5, %k4
|
||||||
|
- /* Each bit in K3 represents a NULL or a mismatch in YMM1 and
|
||||||
|
- YMM3. */
|
||||||
|
- kord %k3, %k4, %k3
|
||||||
|
|
||||||
|
+ VPTESTM %YMM0, %YMM0, %k2
|
||||||
|
+ /* Each bit cleared in K1 represents a mismatch or a null CHAR
|
||||||
|
+ in YMM0 and 32 bytes at (VEC_SIZE * 2)(%rdx, %r10). */
|
||||||
|
+ VPCMP $0, (VEC_SIZE * 2)(%rdx, %r10), %YMM0, %k1{%k2}
|
||||||
|
+ kmovd %k1, %r9d
|
||||||
|
+ /* Don't use subl since it is the lower 16/32 bits of RDI
|
||||||
|
+ below. */
|
||||||
|
+ notl %r9d
|
||||||
|
# ifdef USE_AS_WCSCMP
|
||||||
|
- /* NB: Each bit in K1/K3 represents 4-byte element. */
|
||||||
|
- kshiftlw $8, %k3, %k2
|
||||||
|
+ /* Only last 8 bits are valid. */
|
||||||
|
+ andl $0xff, %r9d
|
||||||
|
+# endif
|
||||||
|
+
|
||||||
|
+ VPTESTM %YMM1, %YMM1, %k4
|
||||||
|
+ /* Each bit cleared in K3 represents a mismatch or a null CHAR
|
||||||
|
+ in YMM1 and 32 bytes at (VEC_SIZE * 3)(%rdx, %r10). */
|
||||||
|
+ VPCMP $0, (VEC_SIZE * 3)(%rdx, %r10), %YMM1, %k3{%k4}
|
||||||
|
+ kmovd %k3, %edi
|
||||||
|
+# ifdef USE_AS_WCSCMP
|
||||||
|
+ /* Don't use subl since it is the upper 8 bits of EDI below. */
|
||||||
|
+ notl %edi
|
||||||
|
+ andl $0xff, %edi
|
||||||
|
# else
|
||||||
|
- kshiftlq $32, %k3, %k2
|
||||||
|
+ incl %edi
|
||||||
|
# endif
|
||||||
|
|
||||||
|
- /* Each bit in K1 represents a NULL or a mismatch. */
|
||||||
|
- korq %k1, %k2, %k1
|
||||||
|
- kmovq %k1, %rdi
|
||||||
|
+# ifdef USE_AS_WCSCMP
|
||||||
|
+ /* NB: Each bit in EDI/R9D represents 4-byte element. */
|
||||||
|
+ sall $8, %edi
|
||||||
|
+
|
||||||
|
+ /* Each bit in EDI represents a null CHAR or a mismatch. */
|
||||||
|
+ orl %r9d, %edi
|
||||||
|
+# else
|
||||||
|
+ salq $32, %rdi
|
||||||
|
+
|
||||||
|
+ /* Each bit in RDI represents a null CHAR or a mismatch. */
|
||||||
|
+ orq %r9, %rdi
|
||||||
|
+# endif
|
||||||
|
|
||||||
|
xorl %r8d, %r8d
|
||||||
|
/* If ECX > VEC_SIZE * 2, skip ECX - (VEC_SIZE * 2) bytes. */
|
||||||
|
@@ -729,12 +771,15 @@ L(loop_cross_page_2_vec):
|
||||||
|
/* R8 has number of bytes skipped. */
|
||||||
|
movl %ecx, %r8d
|
||||||
|
# ifdef USE_AS_WCSCMP
|
||||||
|
- /* NB: Divide shift count by 4 since each bit in K1 represent 4
|
||||||
|
+ /* NB: Divide shift count by 4 since each bit in RDI represent 4
|
||||||
|
bytes. */
|
||||||
|
sarl $2, %ecx
|
||||||
|
-# endif
|
||||||
|
+ /* Skip ECX bytes. */
|
||||||
|
+ shrl %cl, %edi
|
||||||
|
+# else
|
||||||
|
/* Skip ECX bytes. */
|
||||||
|
shrq %cl, %rdi
|
||||||
|
+# endif
|
||||||
|
1:
|
||||||
|
/* Before jumping back to the loop, set ESI to the number of
|
||||||
|
VEC_SIZE * 4 blocks before page crossing. */
|
||||||
|
@@ -818,7 +863,7 @@ L(cross_page_loop):
|
||||||
|
movzbl (%rdi, %rdx), %eax
|
||||||
|
movzbl (%rsi, %rdx), %ecx
|
||||||
|
# endif
|
||||||
|
- /* Check null char. */
|
||||||
|
+ /* Check null CHAR. */
|
||||||
|
testl %eax, %eax
|
||||||
|
jne L(cross_page_loop)
|
||||||
|
/* Since %eax == 0, subtract is OK for both SIGNED and UNSIGNED
|
||||||
|
@@ -901,18 +946,17 @@ L(cross_page):
|
||||||
|
jg L(cross_page_1_vector)
|
||||||
|
L(loop_1_vector):
|
||||||
|
VMOVU (%rdi, %rdx), %YMM0
|
||||||
|
- VMOVU (%rsi, %rdx), %YMM1
|
||||||
|
-
|
||||||
|
- /* Each bit in K0 represents a mismatch in YMM0 and YMM1. */
|
||||||
|
- VPCMP $4, %YMM0, %YMM1, %k0
|
||||||
|
- VPCMP $0, %YMMZERO, %YMM0, %k1
|
||||||
|
- VPCMP $0, %YMMZERO, %YMM1, %k2
|
||||||
|
- /* Each bit in K1 represents a NULL in YMM0 or YMM1. */
|
||||||
|
- kord %k1, %k2, %k1
|
||||||
|
- /* Each bit in K1 represents a NULL or a mismatch. */
|
||||||
|
- kord %k0, %k1, %k1
|
||||||
|
+
|
||||||
|
+ VPTESTM %YMM0, %YMM0, %k2
|
||||||
|
+ /* Each bit cleared in K1 represents a mismatch or a null CHAR
|
||||||
|
+ in YMM0 and 32 bytes at (%rsi, %rdx). */
|
||||||
|
+ VPCMP $0, (%rsi, %rdx), %YMM0, %k1{%k2}
|
||||||
|
kmovd %k1, %ecx
|
||||||
|
- testl %ecx, %ecx
|
||||||
|
+# ifdef USE_AS_WCSCMP
|
||||||
|
+ subl $0xff, %ecx
|
||||||
|
+# else
|
||||||
|
+ incl %ecx
|
||||||
|
+# endif
|
||||||
|
jne L(last_vector)
|
||||||
|
|
||||||
|
addl $VEC_SIZE, %edx
|
||||||
|
@@ -931,18 +975,17 @@ L(cross_page_1_vector):
|
||||||
|
cmpl $(PAGE_SIZE - 16), %eax
|
||||||
|
jg L(cross_page_1_xmm)
|
||||||
|
VMOVU (%rdi, %rdx), %XMM0
|
||||||
|
- VMOVU (%rsi, %rdx), %XMM1
|
||||||
|
-
|
||||||
|
- /* Each bit in K0 represents a mismatch in XMM0 and XMM1. */
|
||||||
|
- VPCMP $4, %XMM0, %XMM1, %k0
|
||||||
|
- VPCMP $0, %XMMZERO, %XMM0, %k1
|
||||||
|
- VPCMP $0, %XMMZERO, %XMM1, %k2
|
||||||
|
- /* Each bit in K1 represents a NULL in XMM0 or XMM1. */
|
||||||
|
- korw %k1, %k2, %k1
|
||||||
|
- /* Each bit in K1 represents a NULL or a mismatch. */
|
||||||
|
- korw %k0, %k1, %k1
|
||||||
|
- kmovw %k1, %ecx
|
||||||
|
- testl %ecx, %ecx
|
||||||
|
+
|
||||||
|
+ VPTESTM %YMM0, %YMM0, %k2
|
||||||
|
+ /* Each bit cleared in K1 represents a mismatch or a null CHAR
|
||||||
|
+ in XMM0 and 16 bytes at (%rsi, %rdx). */
|
||||||
|
+ VPCMP $0, (%rsi, %rdx), %XMM0, %k1{%k2}
|
||||||
|
+ kmovd %k1, %ecx
|
||||||
|
+# ifdef USE_AS_WCSCMP
|
||||||
|
+ subl $0xf, %ecx
|
||||||
|
+# else
|
||||||
|
+ subl $0xffff, %ecx
|
||||||
|
+# endif
|
||||||
|
jne L(last_vector)
|
||||||
|
|
||||||
|
addl $16, %edx
|
||||||
|
@@ -965,25 +1008,16 @@ L(cross_page_1_xmm):
|
||||||
|
vmovq (%rdi, %rdx), %XMM0
|
||||||
|
vmovq (%rsi, %rdx), %XMM1
|
||||||
|
|
||||||
|
- /* Each bit in K0 represents a mismatch in XMM0 and XMM1. */
|
||||||
|
- VPCMP $4, %XMM0, %XMM1, %k0
|
||||||
|
- VPCMP $0, %XMMZERO, %XMM0, %k1
|
||||||
|
- VPCMP $0, %XMMZERO, %XMM1, %k2
|
||||||
|
- /* Each bit in K1 represents a NULL in XMM0 or XMM1. */
|
||||||
|
- kord %k1, %k2, %k1
|
||||||
|
- /* Each bit in K1 represents a NULL or a mismatch. */
|
||||||
|
- kord %k0, %k1, %k1
|
||||||
|
- kmovd %k1, %ecx
|
||||||
|
-
|
||||||
|
+ VPTESTM %YMM0, %YMM0, %k2
|
||||||
|
+ /* Each bit cleared in K1 represents a mismatch or a null CHAR
|
||||||
|
+ in XMM0 and XMM1. */
|
||||||
|
+ VPCMP $0, %XMM1, %XMM0, %k1{%k2}
|
||||||
|
+ kmovb %k1, %ecx
|
||||||
|
# ifdef USE_AS_WCSCMP
|
||||||
|
- /* Only last 2 bits are valid. */
|
||||||
|
- andl $0x3, %ecx
|
||||||
|
+ subl $0x3, %ecx
|
||||||
|
# else
|
||||||
|
- /* Only last 8 bits are valid. */
|
||||||
|
- andl $0xff, %ecx
|
||||||
|
+ subl $0xff, %ecx
|
||||||
|
# endif
|
||||||
|
-
|
||||||
|
- testl %ecx, %ecx
|
||||||
|
jne L(last_vector)
|
||||||
|
|
||||||
|
addl $8, %edx
|
||||||
|
@@ -1002,25 +1036,16 @@ L(cross_page_8bytes):
|
||||||
|
vmovd (%rdi, %rdx), %XMM0
|
||||||
|
vmovd (%rsi, %rdx), %XMM1
|
||||||
|
|
||||||
|
- /* Each bit in K0 represents a mismatch in XMM0 and XMM1. */
|
||||||
|
- VPCMP $4, %XMM0, %XMM1, %k0
|
||||||
|
- VPCMP $0, %XMMZERO, %XMM0, %k1
|
||||||
|
- VPCMP $0, %XMMZERO, %XMM1, %k2
|
||||||
|
- /* Each bit in K1 represents a NULL in XMM0 or XMM1. */
|
||||||
|
- kord %k1, %k2, %k1
|
||||||
|
- /* Each bit in K1 represents a NULL or a mismatch. */
|
||||||
|
- kord %k0, %k1, %k1
|
||||||
|
+ VPTESTM %YMM0, %YMM0, %k2
|
||||||
|
+ /* Each bit cleared in K1 represents a mismatch or a null CHAR
|
||||||
|
+ in XMM0 and XMM1. */
|
||||||
|
+ VPCMP $0, %XMM1, %XMM0, %k1{%k2}
|
||||||
|
kmovd %k1, %ecx
|
||||||
|
-
|
||||||
|
# ifdef USE_AS_WCSCMP
|
||||||
|
- /* Only the last bit is valid. */
|
||||||
|
- andl $0x1, %ecx
|
||||||
|
+ subl $0x1, %ecx
|
||||||
|
# else
|
||||||
|
- /* Only last 4 bits are valid. */
|
||||||
|
- andl $0xf, %ecx
|
||||||
|
+ subl $0xf, %ecx
|
||||||
|
# endif
|
||||||
|
-
|
||||||
|
- testl %ecx, %ecx
|
||||||
|
jne L(last_vector)
|
||||||
|
|
||||||
|
addl $4, %edx
|
85
glibc-upstream-2.34-179.patch
Normal file
85
glibc-upstream-2.34-179.patch
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
commit a182bb7a3922404f79def09d79ef89678b4049f0
|
||||||
|
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||||
|
Date: Fri Oct 29 12:56:53 2021 -0700
|
||||||
|
|
||||||
|
x86-64: Remove Prefer_AVX2_STRCMP
|
||||||
|
|
||||||
|
Remove Prefer_AVX2_STRCMP to enable EVEX strcmp. When comparing 2 32-byte
|
||||||
|
strings, EVEX strcmp has been improved to require 1 load, 1 VPTESTM, 1
|
||||||
|
VPCMP, 1 KMOVD and 1 INCL instead of 2 loads, 3 VPCMPs, 2 KORDs, 1 KMOVD
|
||||||
|
and 1 TESTL while AVX2 strcmp requires 1 load, 2 VPCMPEQs, 1 VPMINU, 1
|
||||||
|
VPMOVMSKB and 1 TESTL. EVEX strcmp is now faster than AVX2 strcmp by up
|
||||||
|
to 40% on Tiger Lake and Ice Lake.
|
||||||
|
|
||||||
|
(cherry picked from commit 14dbbf46a007ae5df36646b51ad0c9e5f5259f30)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
|
||||||
|
index de4e3c3b7258120d..f4d4049e391cbabd 100644
|
||||||
|
--- a/sysdeps/x86/cpu-features.c
|
||||||
|
+++ b/sysdeps/x86/cpu-features.c
|
||||||
|
@@ -574,14 +574,6 @@ disable_tsx:
|
||||||
|
if (CPU_FEATURE_USABLE_P (cpu_features, RTM))
|
||||||
|
cpu_features->preferred[index_arch_Prefer_No_VZEROUPPER]
|
||||||
|
|= bit_arch_Prefer_No_VZEROUPPER;
|
||||||
|
-
|
||||||
|
- /* Since to compare 2 32-byte strings, 256-bit EVEX strcmp
|
||||||
|
- requires 2 loads, 3 VPCMPs and 2 KORDs while AVX2 strcmp
|
||||||
|
- requires 1 load, 2 VPCMPEQs, 1 VPMINU and 1 VPMOVMSKB,
|
||||||
|
- AVX2 strcmp is faster than EVEX strcmp. */
|
||||||
|
- if (CPU_FEATURE_USABLE_P (cpu_features, AVX2))
|
||||||
|
- cpu_features->preferred[index_arch_Prefer_AVX2_STRCMP]
|
||||||
|
- |= bit_arch_Prefer_AVX2_STRCMP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Avoid avoid short distance REP MOVSB on processor with FSRM. */
|
||||||
|
diff --git a/sysdeps/x86/cpu-tunables.c b/sysdeps/x86/cpu-tunables.c
|
||||||
|
index 58f2fad4323d5d91..957db3ad229ba39f 100644
|
||||||
|
--- a/sysdeps/x86/cpu-tunables.c
|
||||||
|
+++ b/sysdeps/x86/cpu-tunables.c
|
||||||
|
@@ -239,8 +239,6 @@ TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp)
|
||||||
|
CHECK_GLIBC_IFUNC_PREFERRED_BOTH (n, cpu_features,
|
||||||
|
Fast_Copy_Backward,
|
||||||
|
disable, 18);
|
||||||
|
- CHECK_GLIBC_IFUNC_PREFERRED_NEED_BOTH
|
||||||
|
- (n, cpu_features, Prefer_AVX2_STRCMP, AVX2, disable, 18);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 19:
|
||||||
|
diff --git a/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def b/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def
|
||||||
|
index 3bdc76cf71007948..8250bfcbecd29a9f 100644
|
||||||
|
--- a/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def
|
||||||
|
+++ b/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def
|
||||||
|
@@ -31,5 +31,4 @@ BIT (Prefer_ERMS)
|
||||||
|
BIT (Prefer_No_AVX512)
|
||||||
|
BIT (MathVec_Prefer_No_AVX512)
|
||||||
|
BIT (Prefer_FSRM)
|
||||||
|
-BIT (Prefer_AVX2_STRCMP)
|
||||||
|
BIT (Avoid_Short_Distance_REP_MOVSB)
|
||||||
|
diff --git a/sysdeps/x86_64/multiarch/strcmp.c b/sysdeps/x86_64/multiarch/strcmp.c
|
||||||
|
index 62b7abeeee646ab4..7c2901bf44456259 100644
|
||||||
|
--- a/sysdeps/x86_64/multiarch/strcmp.c
|
||||||
|
+++ b/sysdeps/x86_64/multiarch/strcmp.c
|
||||||
|
@@ -43,8 +43,7 @@ IFUNC_SELECTOR (void)
|
||||||
|
{
|
||||||
|
if (CPU_FEATURE_USABLE_P (cpu_features, AVX512VL)
|
||||||
|
&& CPU_FEATURE_USABLE_P (cpu_features, AVX512BW)
|
||||||
|
- && CPU_FEATURE_USABLE_P (cpu_features, BMI2)
|
||||||
|
- && !CPU_FEATURES_ARCH_P (cpu_features, Prefer_AVX2_STRCMP))
|
||||||
|
+ && CPU_FEATURE_USABLE_P (cpu_features, BMI2))
|
||||||
|
return OPTIMIZE (evex);
|
||||||
|
|
||||||
|
if (CPU_FEATURE_USABLE_P (cpu_features, RTM))
|
||||||
|
diff --git a/sysdeps/x86_64/multiarch/strncmp.c b/sysdeps/x86_64/multiarch/strncmp.c
|
||||||
|
index 60ba0fe356b31779..f94a421784bfe923 100644
|
||||||
|
--- a/sysdeps/x86_64/multiarch/strncmp.c
|
||||||
|
+++ b/sysdeps/x86_64/multiarch/strncmp.c
|
||||||
|
@@ -43,8 +43,7 @@ IFUNC_SELECTOR (void)
|
||||||
|
{
|
||||||
|
if (CPU_FEATURE_USABLE_P (cpu_features, AVX512VL)
|
||||||
|
&& CPU_FEATURE_USABLE_P (cpu_features, AVX512BW)
|
||||||
|
- && CPU_FEATURE_USABLE_P (cpu_features, BMI2)
|
||||||
|
- && !CPU_FEATURES_ARCH_P (cpu_features, Prefer_AVX2_STRCMP))
|
||||||
|
+ && CPU_FEATURE_USABLE_P (cpu_features, BMI2))
|
||||||
|
return OPTIMIZE (evex);
|
||||||
|
|
||||||
|
if (CPU_FEATURE_USABLE_P (cpu_features, RTM))
|
48
glibc-upstream-2.34-180.patch
Normal file
48
glibc-upstream-2.34-180.patch
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
commit 2e64237a8744dd50f9222293275fa52e7248ff76
|
||||||
|
Author: Fangrui Song <maskray@google.com>
|
||||||
|
Date: Tue Nov 2 20:59:52 2021 -0700
|
||||||
|
|
||||||
|
x86-64: Replace movzx with movzbl
|
||||||
|
|
||||||
|
Clang cannot assemble movzx in the AT&T dialect mode.
|
||||||
|
|
||||||
|
../sysdeps/x86_64/strcmp.S:2232:16: error: invalid operand for instruction
|
||||||
|
movzx (%rsi), %ecx
|
||||||
|
^~~~
|
||||||
|
|
||||||
|
Change movzx to movzbl, which follows the AT&T dialect and is used
|
||||||
|
elsewhere in the file.
|
||||||
|
|
||||||
|
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
||||||
|
(cherry picked from commit 6720d36b6623c5e48c070d86acf61198b33e144e)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/x86_64/multiarch/strcmp-sse42.S b/sysdeps/x86_64/multiarch/strcmp-sse42.S
|
||||||
|
index bc19547b09639071..6197a723b9e0606e 100644
|
||||||
|
--- a/sysdeps/x86_64/multiarch/strcmp-sse42.S
|
||||||
|
+++ b/sysdeps/x86_64/multiarch/strcmp-sse42.S
|
||||||
|
@@ -1771,8 +1771,8 @@ LABEL(strcmp_exitz):
|
||||||
|
.p2align 4
|
||||||
|
// XXX Same as code above
|
||||||
|
LABEL(Byte0):
|
||||||
|
- movzx (%rsi), %ecx
|
||||||
|
- movzx (%rdi), %eax
|
||||||
|
+ movzbl (%rsi), %ecx
|
||||||
|
+ movzbl (%rdi), %eax
|
||||||
|
|
||||||
|
#if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
|
||||||
|
leaq _nl_C_LC_CTYPE_tolower+128*4(%rip), %rdx
|
||||||
|
diff --git a/sysdeps/x86_64/strcmp.S b/sysdeps/x86_64/strcmp.S
|
||||||
|
index 824e648230a15739..7f8a1bc756f86aee 100644
|
||||||
|
--- a/sysdeps/x86_64/strcmp.S
|
||||||
|
+++ b/sysdeps/x86_64/strcmp.S
|
||||||
|
@@ -2232,8 +2232,8 @@ LABEL(strcmp_exitz):
|
||||||
|
|
||||||
|
.p2align 4
|
||||||
|
LABEL(Byte0):
|
||||||
|
- movzx (%rsi), %ecx
|
||||||
|
- movzx (%rdi), %eax
|
||||||
|
+ movzbl (%rsi), %ecx
|
||||||
|
+ movzbl (%rdi), %eax
|
||||||
|
|
||||||
|
#if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
|
||||||
|
leaq _nl_C_LC_CTYPE_tolower+128*4(%rip), %rdx
|
843
glibc-upstream-2.34-181.patch
Normal file
843
glibc-upstream-2.34-181.patch
Normal file
@ -0,0 +1,843 @@
|
|||||||
|
commit a7392db2ff2b9dd906500941ac6361dbe2211b0d
|
||||||
|
Author: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||||
|
Date: Mon Nov 1 00:49:51 2021 -0500
|
||||||
|
|
||||||
|
x86: Optimize memmove-vec-unaligned-erms.S
|
||||||
|
|
||||||
|
No bug.
|
||||||
|
|
||||||
|
The optimizations are as follows:
|
||||||
|
|
||||||
|
1) Always align entry to 64 bytes. This makes behavior more
|
||||||
|
predictable and makes other frontend optimizations easier.
|
||||||
|
|
||||||
|
2) Make the L(more_8x_vec) cases 4k aliasing aware. This can have
|
||||||
|
significant benefits in the case that:
|
||||||
|
0 < (dst - src) < [256, 512]
|
||||||
|
|
||||||
|
3) Align before `rep movsb`. For ERMS this is roughly a [0, 30%]
|
||||||
|
improvement and for FSRM [-10%, 25%].
|
||||||
|
|
||||||
|
In addition to these primary changes there is general cleanup
|
||||||
|
throughout to optimize the aligning routines and control flow logic.
|
||||||
|
|
||||||
|
Signed-off-by: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||||
|
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
||||||
|
(cherry picked from commit a6b7502ec0c2da89a7437f43171f160d713e39c6)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/x86_64/memmove.S b/sysdeps/x86_64/memmove.S
|
||||||
|
index db106a7a1f23f268..b2b318084823dceb 100644
|
||||||
|
--- a/sysdeps/x86_64/memmove.S
|
||||||
|
+++ b/sysdeps/x86_64/memmove.S
|
||||||
|
@@ -25,7 +25,7 @@
|
||||||
|
/* Use movups and movaps for smaller code sizes. */
|
||||||
|
#define VMOVU movups
|
||||||
|
#define VMOVA movaps
|
||||||
|
-
|
||||||
|
+#define MOV_SIZE 3
|
||||||
|
#define SECTION(p) p
|
||||||
|
|
||||||
|
#ifdef USE_MULTIARCH
|
||||||
|
diff --git a/sysdeps/x86_64/multiarch/memmove-avx-unaligned-erms-rtm.S b/sysdeps/x86_64/multiarch/memmove-avx-unaligned-erms-rtm.S
|
||||||
|
index 1ec1962e861dbf63..67a55f0c85af841c 100644
|
||||||
|
--- a/sysdeps/x86_64/multiarch/memmove-avx-unaligned-erms-rtm.S
|
||||||
|
+++ b/sysdeps/x86_64/multiarch/memmove-avx-unaligned-erms-rtm.S
|
||||||
|
@@ -4,7 +4,7 @@
|
||||||
|
# define VMOVNT vmovntdq
|
||||||
|
# define VMOVU vmovdqu
|
||||||
|
# define VMOVA vmovdqa
|
||||||
|
-
|
||||||
|
+# define MOV_SIZE 4
|
||||||
|
# define ZERO_UPPER_VEC_REGISTERS_RETURN \
|
||||||
|
ZERO_UPPER_VEC_REGISTERS_RETURN_XTEST
|
||||||
|
|
||||||
|
diff --git a/sysdeps/x86_64/multiarch/memmove-avx-unaligned-erms.S b/sysdeps/x86_64/multiarch/memmove-avx-unaligned-erms.S
|
||||||
|
index e195e93f153c9512..975ae6c0515b83cb 100644
|
||||||
|
--- a/sysdeps/x86_64/multiarch/memmove-avx-unaligned-erms.S
|
||||||
|
+++ b/sysdeps/x86_64/multiarch/memmove-avx-unaligned-erms.S
|
||||||
|
@@ -4,7 +4,7 @@
|
||||||
|
# define VMOVNT vmovntdq
|
||||||
|
# define VMOVU vmovdqu
|
||||||
|
# define VMOVA vmovdqa
|
||||||
|
-
|
||||||
|
+# define MOV_SIZE 4
|
||||||
|
# define SECTION(p) p##.avx
|
||||||
|
# define MEMMOVE_SYMBOL(p,s) p##_avx_##s
|
||||||
|
|
||||||
|
diff --git a/sysdeps/x86_64/multiarch/memmove-avx512-unaligned-erms.S b/sysdeps/x86_64/multiarch/memmove-avx512-unaligned-erms.S
|
||||||
|
index 848848ab39ff9326..0fa7126830af7acb 100644
|
||||||
|
--- a/sysdeps/x86_64/multiarch/memmove-avx512-unaligned-erms.S
|
||||||
|
+++ b/sysdeps/x86_64/multiarch/memmove-avx512-unaligned-erms.S
|
||||||
|
@@ -25,7 +25,7 @@
|
||||||
|
# define VMOVU vmovdqu64
|
||||||
|
# define VMOVA vmovdqa64
|
||||||
|
# define VZEROUPPER
|
||||||
|
-
|
||||||
|
+# define MOV_SIZE 6
|
||||||
|
# define SECTION(p) p##.evex512
|
||||||
|
# define MEMMOVE_SYMBOL(p,s) p##_avx512_##s
|
||||||
|
|
||||||
|
diff --git a/sysdeps/x86_64/multiarch/memmove-evex-unaligned-erms.S b/sysdeps/x86_64/multiarch/memmove-evex-unaligned-erms.S
|
||||||
|
index 0cbce8f944da51a0..88715441feaaccf5 100644
|
||||||
|
--- a/sysdeps/x86_64/multiarch/memmove-evex-unaligned-erms.S
|
||||||
|
+++ b/sysdeps/x86_64/multiarch/memmove-evex-unaligned-erms.S
|
||||||
|
@@ -25,7 +25,7 @@
|
||||||
|
# define VMOVU vmovdqu64
|
||||||
|
# define VMOVA vmovdqa64
|
||||||
|
# define VZEROUPPER
|
||||||
|
-
|
||||||
|
+# define MOV_SIZE 6
|
||||||
|
# define SECTION(p) p##.evex
|
||||||
|
# define MEMMOVE_SYMBOL(p,s) p##_evex_##s
|
||||||
|
|
||||||
|
diff --git a/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S b/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S
|
||||||
|
index abde8438d41f2320..7b27cbdda5fb99f7 100644
|
||||||
|
--- a/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S
|
||||||
|
+++ b/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S
|
||||||
|
@@ -76,6 +76,25 @@
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+/* Whether to align before movsb. Ultimately we want 64 byte
|
||||||
|
+ align and not worth it to load 4x VEC for VEC_SIZE == 16. */
|
||||||
|
+#define ALIGN_MOVSB (VEC_SIZE > 16)
|
||||||
|
+/* Number of bytes to align movsb to. */
|
||||||
|
+#define MOVSB_ALIGN_TO 64
|
||||||
|
+
|
||||||
|
+#define SMALL_MOV_SIZE (MOV_SIZE <= 4)
|
||||||
|
+#define LARGE_MOV_SIZE (MOV_SIZE > 4)
|
||||||
|
+
|
||||||
|
+#if SMALL_MOV_SIZE + LARGE_MOV_SIZE != 1
|
||||||
|
+# error MOV_SIZE Unknown
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#if LARGE_MOV_SIZE
|
||||||
|
+# define SMALL_SIZE_OFFSET (4)
|
||||||
|
+#else
|
||||||
|
+# define SMALL_SIZE_OFFSET (0)
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#ifndef PAGE_SIZE
|
||||||
|
# define PAGE_SIZE 4096
|
||||||
|
#endif
|
||||||
|
@@ -199,25 +218,21 @@ L(start):
|
||||||
|
# endif
|
||||||
|
cmp $VEC_SIZE, %RDX_LP
|
||||||
|
jb L(less_vec)
|
||||||
|
+ /* Load regardless. */
|
||||||
|
+ VMOVU (%rsi), %VEC(0)
|
||||||
|
cmp $(VEC_SIZE * 2), %RDX_LP
|
||||||
|
ja L(more_2x_vec)
|
||||||
|
-#if !defined USE_MULTIARCH || !IS_IN (libc)
|
||||||
|
-L(last_2x_vec):
|
||||||
|
-#endif
|
||||||
|
/* From VEC and to 2 * VEC. No branch when size == VEC_SIZE. */
|
||||||
|
- VMOVU (%rsi), %VEC(0)
|
||||||
|
VMOVU -VEC_SIZE(%rsi,%rdx), %VEC(1)
|
||||||
|
VMOVU %VEC(0), (%rdi)
|
||||||
|
VMOVU %VEC(1), -VEC_SIZE(%rdi,%rdx)
|
||||||
|
-#if !defined USE_MULTIARCH || !IS_IN (libc)
|
||||||
|
-L(nop):
|
||||||
|
- ret
|
||||||
|
+#if !(defined USE_MULTIARCH && IS_IN (libc))
|
||||||
|
+ ZERO_UPPER_VEC_REGISTERS_RETURN
|
||||||
|
#else
|
||||||
|
VZEROUPPER_RETURN
|
||||||
|
#endif
|
||||||
|
#if defined USE_MULTIARCH && IS_IN (libc)
|
||||||
|
END (MEMMOVE_SYMBOL (__memmove, unaligned))
|
||||||
|
-
|
||||||
|
# if VEC_SIZE == 16
|
||||||
|
ENTRY (__mempcpy_chk_erms)
|
||||||
|
cmp %RDX_LP, %RCX_LP
|
||||||
|
@@ -289,7 +304,7 @@ ENTRY (MEMMOVE_CHK_SYMBOL (__memmove_chk, unaligned_erms))
|
||||||
|
END (MEMMOVE_CHK_SYMBOL (__memmove_chk, unaligned_erms))
|
||||||
|
# endif
|
||||||
|
|
||||||
|
-ENTRY (MEMMOVE_SYMBOL (__memmove, unaligned_erms))
|
||||||
|
+ENTRY_P2ALIGN (MEMMOVE_SYMBOL (__memmove, unaligned_erms), 6)
|
||||||
|
movq %rdi, %rax
|
||||||
|
L(start_erms):
|
||||||
|
# ifdef __ILP32__
|
||||||
|
@@ -298,310 +313,448 @@ L(start_erms):
|
||||||
|
# endif
|
||||||
|
cmp $VEC_SIZE, %RDX_LP
|
||||||
|
jb L(less_vec)
|
||||||
|
+ /* Load regardless. */
|
||||||
|
+ VMOVU (%rsi), %VEC(0)
|
||||||
|
cmp $(VEC_SIZE * 2), %RDX_LP
|
||||||
|
ja L(movsb_more_2x_vec)
|
||||||
|
-L(last_2x_vec):
|
||||||
|
- /* From VEC and to 2 * VEC. No branch when size == VEC_SIZE. */
|
||||||
|
- VMOVU (%rsi), %VEC(0)
|
||||||
|
- VMOVU -VEC_SIZE(%rsi,%rdx), %VEC(1)
|
||||||
|
+ /* From VEC and to 2 * VEC. No branch when size == VEC_SIZE.
|
||||||
|
+ */
|
||||||
|
+ VMOVU -VEC_SIZE(%rsi, %rdx), %VEC(1)
|
||||||
|
VMOVU %VEC(0), (%rdi)
|
||||||
|
- VMOVU %VEC(1), -VEC_SIZE(%rdi,%rdx)
|
||||||
|
+ VMOVU %VEC(1), -VEC_SIZE(%rdi, %rdx)
|
||||||
|
L(return):
|
||||||
|
-#if VEC_SIZE > 16
|
||||||
|
+# if VEC_SIZE > 16
|
||||||
|
ZERO_UPPER_VEC_REGISTERS_RETURN
|
||||||
|
-#else
|
||||||
|
+# else
|
||||||
|
ret
|
||||||
|
+# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-L(movsb):
|
||||||
|
- cmp __x86_rep_movsb_stop_threshold(%rip), %RDX_LP
|
||||||
|
- jae L(more_8x_vec)
|
||||||
|
- cmpq %rsi, %rdi
|
||||||
|
- jb 1f
|
||||||
|
- /* Source == destination is less common. */
|
||||||
|
- je L(nop)
|
||||||
|
- leaq (%rsi,%rdx), %r9
|
||||||
|
- cmpq %r9, %rdi
|
||||||
|
- /* Avoid slow backward REP MOVSB. */
|
||||||
|
- jb L(more_8x_vec_backward)
|
||||||
|
-# if AVOID_SHORT_DISTANCE_REP_MOVSB
|
||||||
|
- testl $X86_STRING_CONTROL_AVOID_SHORT_DISTANCE_REP_MOVSB, __x86_string_control(%rip)
|
||||||
|
- jz 3f
|
||||||
|
- movq %rdi, %rcx
|
||||||
|
- subq %rsi, %rcx
|
||||||
|
- jmp 2f
|
||||||
|
-# endif
|
||||||
|
-1:
|
||||||
|
-# if AVOID_SHORT_DISTANCE_REP_MOVSB
|
||||||
|
- testl $X86_STRING_CONTROL_AVOID_SHORT_DISTANCE_REP_MOVSB, __x86_string_control(%rip)
|
||||||
|
- jz 3f
|
||||||
|
- movq %rsi, %rcx
|
||||||
|
- subq %rdi, %rcx
|
||||||
|
-2:
|
||||||
|
-/* Avoid "rep movsb" if RCX, the distance between source and destination,
|
||||||
|
- is N*4GB + [1..63] with N >= 0. */
|
||||||
|
- cmpl $63, %ecx
|
||||||
|
- jbe L(more_2x_vec) /* Avoid "rep movsb" if ECX <= 63. */
|
||||||
|
-3:
|
||||||
|
-# endif
|
||||||
|
- mov %RDX_LP, %RCX_LP
|
||||||
|
- rep movsb
|
||||||
|
-L(nop):
|
||||||
|
+#if LARGE_MOV_SIZE
|
||||||
|
+ /* If LARGE_MOV_SIZE this fits in the aligning bytes between the
|
||||||
|
+ ENTRY block and L(less_vec). */
|
||||||
|
+ .p2align 4,, 8
|
||||||
|
+L(between_4_7):
|
||||||
|
+ /* From 4 to 7. No branch when size == 4. */
|
||||||
|
+ movl (%rsi), %ecx
|
||||||
|
+ movl (%rsi, %rdx), %esi
|
||||||
|
+ movl %ecx, (%rdi)
|
||||||
|
+ movl %esi, (%rdi, %rdx)
|
||||||
|
ret
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+ .p2align 4
|
||||||
|
L(less_vec):
|
||||||
|
/* Less than 1 VEC. */
|
||||||
|
#if VEC_SIZE != 16 && VEC_SIZE != 32 && VEC_SIZE != 64
|
||||||
|
# error Unsupported VEC_SIZE!
|
||||||
|
#endif
|
||||||
|
#if VEC_SIZE > 32
|
||||||
|
- cmpb $32, %dl
|
||||||
|
+ cmpl $32, %edx
|
||||||
|
jae L(between_32_63)
|
||||||
|
#endif
|
||||||
|
#if VEC_SIZE > 16
|
||||||
|
- cmpb $16, %dl
|
||||||
|
+ cmpl $16, %edx
|
||||||
|
jae L(between_16_31)
|
||||||
|
#endif
|
||||||
|
- cmpb $8, %dl
|
||||||
|
+ cmpl $8, %edx
|
||||||
|
jae L(between_8_15)
|
||||||
|
- cmpb $4, %dl
|
||||||
|
+#if SMALL_MOV_SIZE
|
||||||
|
+ cmpl $4, %edx
|
||||||
|
+#else
|
||||||
|
+ subq $4, %rdx
|
||||||
|
+#endif
|
||||||
|
jae L(between_4_7)
|
||||||
|
- cmpb $1, %dl
|
||||||
|
- ja L(between_2_3)
|
||||||
|
- jb 1f
|
||||||
|
- movzbl (%rsi), %ecx
|
||||||
|
+ cmpl $(1 - SMALL_SIZE_OFFSET), %edx
|
||||||
|
+ jl L(copy_0)
|
||||||
|
+ movb (%rsi), %cl
|
||||||
|
+ je L(copy_1)
|
||||||
|
+ movzwl (-2 + SMALL_SIZE_OFFSET)(%rsi, %rdx), %esi
|
||||||
|
+ movw %si, (-2 + SMALL_SIZE_OFFSET)(%rdi, %rdx)
|
||||||
|
+L(copy_1):
|
||||||
|
movb %cl, (%rdi)
|
||||||
|
-1:
|
||||||
|
+L(copy_0):
|
||||||
|
ret
|
||||||
|
+
|
||||||
|
+#if SMALL_MOV_SIZE
|
||||||
|
+ .p2align 4,, 8
|
||||||
|
+L(between_4_7):
|
||||||
|
+ /* From 4 to 7. No branch when size == 4. */
|
||||||
|
+ movl -4(%rsi, %rdx), %ecx
|
||||||
|
+ movl (%rsi), %esi
|
||||||
|
+ movl %ecx, -4(%rdi, %rdx)
|
||||||
|
+ movl %esi, (%rdi)
|
||||||
|
+ ret
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#if VEC_SIZE > 16
|
||||||
|
+ /* From 16 to 31. No branch when size == 16. */
|
||||||
|
+ .p2align 4,, 8
|
||||||
|
+L(between_16_31):
|
||||||
|
+ vmovdqu (%rsi), %xmm0
|
||||||
|
+ vmovdqu -16(%rsi, %rdx), %xmm1
|
||||||
|
+ vmovdqu %xmm0, (%rdi)
|
||||||
|
+ vmovdqu %xmm1, -16(%rdi, %rdx)
|
||||||
|
+ /* No ymm registers have been touched. */
|
||||||
|
+ ret
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#if VEC_SIZE > 32
|
||||||
|
+ .p2align 4,, 10
|
||||||
|
L(between_32_63):
|
||||||
|
/* From 32 to 63. No branch when size == 32. */
|
||||||
|
VMOVU (%rsi), %YMM0
|
||||||
|
- VMOVU -32(%rsi,%rdx), %YMM1
|
||||||
|
+ VMOVU -32(%rsi, %rdx), %YMM1
|
||||||
|
VMOVU %YMM0, (%rdi)
|
||||||
|
- VMOVU %YMM1, -32(%rdi,%rdx)
|
||||||
|
- VZEROUPPER_RETURN
|
||||||
|
-#endif
|
||||||
|
-#if VEC_SIZE > 16
|
||||||
|
- /* From 16 to 31. No branch when size == 16. */
|
||||||
|
-L(between_16_31):
|
||||||
|
- VMOVU (%rsi), %XMM0
|
||||||
|
- VMOVU -16(%rsi,%rdx), %XMM1
|
||||||
|
- VMOVU %XMM0, (%rdi)
|
||||||
|
- VMOVU %XMM1, -16(%rdi,%rdx)
|
||||||
|
+ VMOVU %YMM1, -32(%rdi, %rdx)
|
||||||
|
VZEROUPPER_RETURN
|
||||||
|
#endif
|
||||||
|
+
|
||||||
|
+ .p2align 4,, 10
|
||||||
|
L(between_8_15):
|
||||||
|
/* From 8 to 15. No branch when size == 8. */
|
||||||
|
- movq -8(%rsi,%rdx), %rcx
|
||||||
|
+ movq -8(%rsi, %rdx), %rcx
|
||||||
|
movq (%rsi), %rsi
|
||||||
|
- movq %rcx, -8(%rdi,%rdx)
|
||||||
|
movq %rsi, (%rdi)
|
||||||
|
+ movq %rcx, -8(%rdi, %rdx)
|
||||||
|
ret
|
||||||
|
-L(between_4_7):
|
||||||
|
- /* From 4 to 7. No branch when size == 4. */
|
||||||
|
- movl -4(%rsi,%rdx), %ecx
|
||||||
|
- movl (%rsi), %esi
|
||||||
|
- movl %ecx, -4(%rdi,%rdx)
|
||||||
|
- movl %esi, (%rdi)
|
||||||
|
- ret
|
||||||
|
-L(between_2_3):
|
||||||
|
- /* From 2 to 3. No branch when size == 2. */
|
||||||
|
- movzwl -2(%rsi,%rdx), %ecx
|
||||||
|
- movzwl (%rsi), %esi
|
||||||
|
- movw %cx, -2(%rdi,%rdx)
|
||||||
|
- movw %si, (%rdi)
|
||||||
|
- ret
|
||||||
|
|
||||||
|
+ .p2align 4,, 10
|
||||||
|
+L(last_4x_vec):
|
||||||
|
+ /* Copy from 2 * VEC + 1 to 4 * VEC, inclusively. */
|
||||||
|
+
|
||||||
|
+ /* VEC(0) and VEC(1) have already been loaded. */
|
||||||
|
+ VMOVU -VEC_SIZE(%rsi, %rdx), %VEC(2)
|
||||||
|
+ VMOVU -(VEC_SIZE * 2)(%rsi, %rdx), %VEC(3)
|
||||||
|
+ VMOVU %VEC(0), (%rdi)
|
||||||
|
+ VMOVU %VEC(1), VEC_SIZE(%rdi)
|
||||||
|
+ VMOVU %VEC(2), -VEC_SIZE(%rdi, %rdx)
|
||||||
|
+ VMOVU %VEC(3), -(VEC_SIZE * 2)(%rdi, %rdx)
|
||||||
|
+ VZEROUPPER_RETURN
|
||||||
|
+
|
||||||
|
+ .p2align 4
|
||||||
|
#if defined USE_MULTIARCH && IS_IN (libc)
|
||||||
|
L(movsb_more_2x_vec):
|
||||||
|
cmp __x86_rep_movsb_threshold(%rip), %RDX_LP
|
||||||
|
ja L(movsb)
|
||||||
|
#endif
|
||||||
|
L(more_2x_vec):
|
||||||
|
- /* More than 2 * VEC and there may be overlap between destination
|
||||||
|
- and source. */
|
||||||
|
+ /* More than 2 * VEC and there may be overlap between
|
||||||
|
+ destination and source. */
|
||||||
|
cmpq $(VEC_SIZE * 8), %rdx
|
||||||
|
ja L(more_8x_vec)
|
||||||
|
+ /* Load VEC(1) regardless. VEC(0) has already been loaded. */
|
||||||
|
+ VMOVU VEC_SIZE(%rsi), %VEC(1)
|
||||||
|
cmpq $(VEC_SIZE * 4), %rdx
|
||||||
|
jbe L(last_4x_vec)
|
||||||
|
- /* Copy from 4 * VEC + 1 to 8 * VEC, inclusively. */
|
||||||
|
- VMOVU (%rsi), %VEC(0)
|
||||||
|
- VMOVU VEC_SIZE(%rsi), %VEC(1)
|
||||||
|
+ /* Copy from 4 * VEC + 1 to 8 * VEC, inclusively. */
|
||||||
|
VMOVU (VEC_SIZE * 2)(%rsi), %VEC(2)
|
||||||
|
VMOVU (VEC_SIZE * 3)(%rsi), %VEC(3)
|
||||||
|
- VMOVU -VEC_SIZE(%rsi,%rdx), %VEC(4)
|
||||||
|
- VMOVU -(VEC_SIZE * 2)(%rsi,%rdx), %VEC(5)
|
||||||
|
- VMOVU -(VEC_SIZE * 3)(%rsi,%rdx), %VEC(6)
|
||||||
|
- VMOVU -(VEC_SIZE * 4)(%rsi,%rdx), %VEC(7)
|
||||||
|
+ VMOVU -VEC_SIZE(%rsi, %rdx), %VEC(4)
|
||||||
|
+ VMOVU -(VEC_SIZE * 2)(%rsi, %rdx), %VEC(5)
|
||||||
|
+ VMOVU -(VEC_SIZE * 3)(%rsi, %rdx), %VEC(6)
|
||||||
|
+ VMOVU -(VEC_SIZE * 4)(%rsi, %rdx), %VEC(7)
|
||||||
|
VMOVU %VEC(0), (%rdi)
|
||||||
|
VMOVU %VEC(1), VEC_SIZE(%rdi)
|
||||||
|
VMOVU %VEC(2), (VEC_SIZE * 2)(%rdi)
|
||||||
|
VMOVU %VEC(3), (VEC_SIZE * 3)(%rdi)
|
||||||
|
- VMOVU %VEC(4), -VEC_SIZE(%rdi,%rdx)
|
||||||
|
- VMOVU %VEC(5), -(VEC_SIZE * 2)(%rdi,%rdx)
|
||||||
|
- VMOVU %VEC(6), -(VEC_SIZE * 3)(%rdi,%rdx)
|
||||||
|
- VMOVU %VEC(7), -(VEC_SIZE * 4)(%rdi,%rdx)
|
||||||
|
- VZEROUPPER_RETURN
|
||||||
|
-L(last_4x_vec):
|
||||||
|
- /* Copy from 2 * VEC + 1 to 4 * VEC, inclusively. */
|
||||||
|
- VMOVU (%rsi), %VEC(0)
|
||||||
|
- VMOVU VEC_SIZE(%rsi), %VEC(1)
|
||||||
|
- VMOVU -VEC_SIZE(%rsi,%rdx), %VEC(2)
|
||||||
|
- VMOVU -(VEC_SIZE * 2)(%rsi,%rdx), %VEC(3)
|
||||||
|
- VMOVU %VEC(0), (%rdi)
|
||||||
|
- VMOVU %VEC(1), VEC_SIZE(%rdi)
|
||||||
|
- VMOVU %VEC(2), -VEC_SIZE(%rdi,%rdx)
|
||||||
|
- VMOVU %VEC(3), -(VEC_SIZE * 2)(%rdi,%rdx)
|
||||||
|
+ VMOVU %VEC(4), -VEC_SIZE(%rdi, %rdx)
|
||||||
|
+ VMOVU %VEC(5), -(VEC_SIZE * 2)(%rdi, %rdx)
|
||||||
|
+ VMOVU %VEC(6), -(VEC_SIZE * 3)(%rdi, %rdx)
|
||||||
|
+ VMOVU %VEC(7), -(VEC_SIZE * 4)(%rdi, %rdx)
|
||||||
|
VZEROUPPER_RETURN
|
||||||
|
|
||||||
|
+ .p2align 4,, 4
|
||||||
|
L(more_8x_vec):
|
||||||
|
+ movq %rdi, %rcx
|
||||||
|
+ subq %rsi, %rcx
|
||||||
|
+ /* Go to backwards temporal copy if overlap no matter what as
|
||||||
|
+ backward REP MOVSB is slow and we don't want to use NT stores if
|
||||||
|
+ there is overlap. */
|
||||||
|
+ cmpq %rdx, %rcx
|
||||||
|
+ /* L(more_8x_vec_backward_check_nop) checks for src == dst. */
|
||||||
|
+ jb L(more_8x_vec_backward_check_nop)
|
||||||
|
/* Check if non-temporal move candidate. */
|
||||||
|
#if (defined USE_MULTIARCH || VEC_SIZE == 16) && IS_IN (libc)
|
||||||
|
/* Check non-temporal store threshold. */
|
||||||
|
- cmp __x86_shared_non_temporal_threshold(%rip), %RDX_LP
|
||||||
|
+ cmp __x86_shared_non_temporal_threshold(%rip), %RDX_LP
|
||||||
|
ja L(large_memcpy_2x)
|
||||||
|
#endif
|
||||||
|
- /* Entry if rdx is greater than non-temporal threshold but there
|
||||||
|
- is overlap. */
|
||||||
|
+ /* To reach this point there cannot be overlap and dst > src. So
|
||||||
|
+ check for overlap and src > dst in which case correctness
|
||||||
|
+ requires forward copy. Otherwise decide between backward/forward
|
||||||
|
+ copy depending on address aliasing. */
|
||||||
|
+
|
||||||
|
+ /* Entry if rdx is greater than __x86_rep_movsb_stop_threshold
|
||||||
|
+ but less than __x86_shared_non_temporal_threshold. */
|
||||||
|
L(more_8x_vec_check):
|
||||||
|
- cmpq %rsi, %rdi
|
||||||
|
- ja L(more_8x_vec_backward)
|
||||||
|
- /* Source == destination is less common. */
|
||||||
|
- je L(nop)
|
||||||
|
- /* Load the first VEC and last 4 * VEC to support overlapping
|
||||||
|
- addresses. */
|
||||||
|
- VMOVU (%rsi), %VEC(4)
|
||||||
|
+ /* rcx contains dst - src. Add back length (rdx). */
|
||||||
|
+ leaq (%rcx, %rdx), %r8
|
||||||
|
+ /* If r8 has different sign than rcx then there is overlap so we
|
||||||
|
+ must do forward copy. */
|
||||||
|
+ xorq %rcx, %r8
|
||||||
|
+ /* Isolate just sign bit of r8. */
|
||||||
|
+ shrq $63, %r8
|
||||||
|
+ /* Get 4k difference dst - src. */
|
||||||
|
+ andl $(PAGE_SIZE - 256), %ecx
|
||||||
|
+ /* If r8 is non-zero must do foward for correctness. Otherwise
|
||||||
|
+ if ecx is non-zero there is 4k False Alaising so do backward
|
||||||
|
+ copy. */
|
||||||
|
+ addl %r8d, %ecx
|
||||||
|
+ jz L(more_8x_vec_backward)
|
||||||
|
+
|
||||||
|
+ /* if rdx is greater than __x86_shared_non_temporal_threshold
|
||||||
|
+ but there is overlap, or from short distance movsb. */
|
||||||
|
+L(more_8x_vec_forward):
|
||||||
|
+ /* Load first and last 4 * VEC to support overlapping addresses.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ /* First vec was already loaded into VEC(0). */
|
||||||
|
VMOVU -VEC_SIZE(%rsi, %rdx), %VEC(5)
|
||||||
|
VMOVU -(VEC_SIZE * 2)(%rsi, %rdx), %VEC(6)
|
||||||
|
+ /* Save begining of dst. */
|
||||||
|
+ movq %rdi, %rcx
|
||||||
|
+ /* Align dst to VEC_SIZE - 1. */
|
||||||
|
+ orq $(VEC_SIZE - 1), %rdi
|
||||||
|
VMOVU -(VEC_SIZE * 3)(%rsi, %rdx), %VEC(7)
|
||||||
|
VMOVU -(VEC_SIZE * 4)(%rsi, %rdx), %VEC(8)
|
||||||
|
- /* Save start and stop of the destination buffer. */
|
||||||
|
- movq %rdi, %r11
|
||||||
|
- leaq -VEC_SIZE(%rdi, %rdx), %rcx
|
||||||
|
- /* Align destination for aligned stores in the loop. Compute
|
||||||
|
- how much destination is misaligned. */
|
||||||
|
- movq %rdi, %r8
|
||||||
|
- andq $(VEC_SIZE - 1), %r8
|
||||||
|
- /* Get the negative of offset for alignment. */
|
||||||
|
- subq $VEC_SIZE, %r8
|
||||||
|
- /* Adjust source. */
|
||||||
|
- subq %r8, %rsi
|
||||||
|
- /* Adjust destination which should be aligned now. */
|
||||||
|
- subq %r8, %rdi
|
||||||
|
- /* Adjust length. */
|
||||||
|
- addq %r8, %rdx
|
||||||
|
|
||||||
|
- .p2align 4
|
||||||
|
+ /* Subtract dst from src. Add back after dst aligned. */
|
||||||
|
+ subq %rcx, %rsi
|
||||||
|
+ /* Finish aligning dst. */
|
||||||
|
+ incq %rdi
|
||||||
|
+ /* Restore src adjusted with new value for aligned dst. */
|
||||||
|
+ addq %rdi, %rsi
|
||||||
|
+ /* Store end of buffer minus tail in rdx. */
|
||||||
|
+ leaq (VEC_SIZE * -4)(%rcx, %rdx), %rdx
|
||||||
|
+
|
||||||
|
+ /* Dont use multi-byte nop to align. */
|
||||||
|
+ .p2align 4,, 11
|
||||||
|
L(loop_4x_vec_forward):
|
||||||
|
/* Copy 4 * VEC a time forward. */
|
||||||
|
- VMOVU (%rsi), %VEC(0)
|
||||||
|
- VMOVU VEC_SIZE(%rsi), %VEC(1)
|
||||||
|
- VMOVU (VEC_SIZE * 2)(%rsi), %VEC(2)
|
||||||
|
- VMOVU (VEC_SIZE * 3)(%rsi), %VEC(3)
|
||||||
|
+ VMOVU (%rsi), %VEC(1)
|
||||||
|
+ VMOVU VEC_SIZE(%rsi), %VEC(2)
|
||||||
|
+ VMOVU (VEC_SIZE * 2)(%rsi), %VEC(3)
|
||||||
|
+ VMOVU (VEC_SIZE * 3)(%rsi), %VEC(4)
|
||||||
|
subq $-(VEC_SIZE * 4), %rsi
|
||||||
|
- addq $-(VEC_SIZE * 4), %rdx
|
||||||
|
- VMOVA %VEC(0), (%rdi)
|
||||||
|
- VMOVA %VEC(1), VEC_SIZE(%rdi)
|
||||||
|
- VMOVA %VEC(2), (VEC_SIZE * 2)(%rdi)
|
||||||
|
- VMOVA %VEC(3), (VEC_SIZE * 3)(%rdi)
|
||||||
|
+ VMOVA %VEC(1), (%rdi)
|
||||||
|
+ VMOVA %VEC(2), VEC_SIZE(%rdi)
|
||||||
|
+ VMOVA %VEC(3), (VEC_SIZE * 2)(%rdi)
|
||||||
|
+ VMOVA %VEC(4), (VEC_SIZE * 3)(%rdi)
|
||||||
|
subq $-(VEC_SIZE * 4), %rdi
|
||||||
|
- cmpq $(VEC_SIZE * 4), %rdx
|
||||||
|
+ cmpq %rdi, %rdx
|
||||||
|
ja L(loop_4x_vec_forward)
|
||||||
|
/* Store the last 4 * VEC. */
|
||||||
|
- VMOVU %VEC(5), (%rcx)
|
||||||
|
- VMOVU %VEC(6), -VEC_SIZE(%rcx)
|
||||||
|
- VMOVU %VEC(7), -(VEC_SIZE * 2)(%rcx)
|
||||||
|
- VMOVU %VEC(8), -(VEC_SIZE * 3)(%rcx)
|
||||||
|
+ VMOVU %VEC(5), (VEC_SIZE * 3)(%rdx)
|
||||||
|
+ VMOVU %VEC(6), (VEC_SIZE * 2)(%rdx)
|
||||||
|
+ VMOVU %VEC(7), VEC_SIZE(%rdx)
|
||||||
|
+ VMOVU %VEC(8), (%rdx)
|
||||||
|
/* Store the first VEC. */
|
||||||
|
- VMOVU %VEC(4), (%r11)
|
||||||
|
+ VMOVU %VEC(0), (%rcx)
|
||||||
|
+ /* Keep L(nop_backward) target close to jmp for 2-byte encoding.
|
||||||
|
+ */
|
||||||
|
+L(nop_backward):
|
||||||
|
VZEROUPPER_RETURN
|
||||||
|
|
||||||
|
+ .p2align 4,, 8
|
||||||
|
+L(more_8x_vec_backward_check_nop):
|
||||||
|
+ /* rcx contains dst - src. Test for dst == src to skip all of
|
||||||
|
+ memmove. */
|
||||||
|
+ testq %rcx, %rcx
|
||||||
|
+ jz L(nop_backward)
|
||||||
|
L(more_8x_vec_backward):
|
||||||
|
/* Load the first 4 * VEC and last VEC to support overlapping
|
||||||
|
addresses. */
|
||||||
|
- VMOVU (%rsi), %VEC(4)
|
||||||
|
+
|
||||||
|
+ /* First vec was also loaded into VEC(0). */
|
||||||
|
VMOVU VEC_SIZE(%rsi), %VEC(5)
|
||||||
|
VMOVU (VEC_SIZE * 2)(%rsi), %VEC(6)
|
||||||
|
+ /* Begining of region for 4x backward copy stored in rcx. */
|
||||||
|
+ leaq (VEC_SIZE * -4 + -1)(%rdi, %rdx), %rcx
|
||||||
|
VMOVU (VEC_SIZE * 3)(%rsi), %VEC(7)
|
||||||
|
- VMOVU -VEC_SIZE(%rsi,%rdx), %VEC(8)
|
||||||
|
- /* Save stop of the destination buffer. */
|
||||||
|
- leaq -VEC_SIZE(%rdi, %rdx), %r11
|
||||||
|
- /* Align destination end for aligned stores in the loop. Compute
|
||||||
|
- how much destination end is misaligned. */
|
||||||
|
- leaq -VEC_SIZE(%rsi, %rdx), %rcx
|
||||||
|
- movq %r11, %r9
|
||||||
|
- movq %r11, %r8
|
||||||
|
- andq $(VEC_SIZE - 1), %r8
|
||||||
|
- /* Adjust source. */
|
||||||
|
- subq %r8, %rcx
|
||||||
|
- /* Adjust the end of destination which should be aligned now. */
|
||||||
|
- subq %r8, %r9
|
||||||
|
- /* Adjust length. */
|
||||||
|
- subq %r8, %rdx
|
||||||
|
-
|
||||||
|
- .p2align 4
|
||||||
|
+ VMOVU -VEC_SIZE(%rsi, %rdx), %VEC(8)
|
||||||
|
+ /* Subtract dst from src. Add back after dst aligned. */
|
||||||
|
+ subq %rdi, %rsi
|
||||||
|
+ /* Align dst. */
|
||||||
|
+ andq $-(VEC_SIZE), %rcx
|
||||||
|
+ /* Restore src. */
|
||||||
|
+ addq %rcx, %rsi
|
||||||
|
+
|
||||||
|
+ /* Don't use multi-byte nop to align. */
|
||||||
|
+ .p2align 4,, 11
|
||||||
|
L(loop_4x_vec_backward):
|
||||||
|
/* Copy 4 * VEC a time backward. */
|
||||||
|
- VMOVU (%rcx), %VEC(0)
|
||||||
|
- VMOVU -VEC_SIZE(%rcx), %VEC(1)
|
||||||
|
- VMOVU -(VEC_SIZE * 2)(%rcx), %VEC(2)
|
||||||
|
- VMOVU -(VEC_SIZE * 3)(%rcx), %VEC(3)
|
||||||
|
- addq $-(VEC_SIZE * 4), %rcx
|
||||||
|
- addq $-(VEC_SIZE * 4), %rdx
|
||||||
|
- VMOVA %VEC(0), (%r9)
|
||||||
|
- VMOVA %VEC(1), -VEC_SIZE(%r9)
|
||||||
|
- VMOVA %VEC(2), -(VEC_SIZE * 2)(%r9)
|
||||||
|
- VMOVA %VEC(3), -(VEC_SIZE * 3)(%r9)
|
||||||
|
- addq $-(VEC_SIZE * 4), %r9
|
||||||
|
- cmpq $(VEC_SIZE * 4), %rdx
|
||||||
|
- ja L(loop_4x_vec_backward)
|
||||||
|
+ VMOVU (VEC_SIZE * 3)(%rsi), %VEC(1)
|
||||||
|
+ VMOVU (VEC_SIZE * 2)(%rsi), %VEC(2)
|
||||||
|
+ VMOVU (VEC_SIZE * 1)(%rsi), %VEC(3)
|
||||||
|
+ VMOVU (VEC_SIZE * 0)(%rsi), %VEC(4)
|
||||||
|
+ addq $(VEC_SIZE * -4), %rsi
|
||||||
|
+ VMOVA %VEC(1), (VEC_SIZE * 3)(%rcx)
|
||||||
|
+ VMOVA %VEC(2), (VEC_SIZE * 2)(%rcx)
|
||||||
|
+ VMOVA %VEC(3), (VEC_SIZE * 1)(%rcx)
|
||||||
|
+ VMOVA %VEC(4), (VEC_SIZE * 0)(%rcx)
|
||||||
|
+ addq $(VEC_SIZE * -4), %rcx
|
||||||
|
+ cmpq %rcx, %rdi
|
||||||
|
+ jb L(loop_4x_vec_backward)
|
||||||
|
/* Store the first 4 * VEC. */
|
||||||
|
- VMOVU %VEC(4), (%rdi)
|
||||||
|
+ VMOVU %VEC(0), (%rdi)
|
||||||
|
VMOVU %VEC(5), VEC_SIZE(%rdi)
|
||||||
|
VMOVU %VEC(6), (VEC_SIZE * 2)(%rdi)
|
||||||
|
VMOVU %VEC(7), (VEC_SIZE * 3)(%rdi)
|
||||||
|
/* Store the last VEC. */
|
||||||
|
- VMOVU %VEC(8), (%r11)
|
||||||
|
+ VMOVU %VEC(8), -VEC_SIZE(%rdx, %rdi)
|
||||||
|
+ VZEROUPPER_RETURN
|
||||||
|
+
|
||||||
|
+#if defined USE_MULTIARCH && IS_IN (libc)
|
||||||
|
+ /* L(skip_short_movsb_check) is only used with ERMS. Not for
|
||||||
|
+ FSRM. */
|
||||||
|
+ .p2align 5,, 16
|
||||||
|
+# if ALIGN_MOVSB
|
||||||
|
+L(skip_short_movsb_check):
|
||||||
|
+# if MOVSB_ALIGN_TO > VEC_SIZE
|
||||||
|
+ VMOVU VEC_SIZE(%rsi), %VEC(1)
|
||||||
|
+# endif
|
||||||
|
+# if MOVSB_ALIGN_TO > (VEC_SIZE * 2)
|
||||||
|
+# error Unsupported MOVSB_ALIGN_TO
|
||||||
|
+# endif
|
||||||
|
+ /* If CPU does not have FSRM two options for aligning. Align src
|
||||||
|
+ if dst and src 4k alias. Otherwise align dst. */
|
||||||
|
+ testl $(PAGE_SIZE - 512), %ecx
|
||||||
|
+ jnz L(movsb_align_dst)
|
||||||
|
+ /* Fall through. dst and src 4k alias. It's better to align src
|
||||||
|
+ here because the bottleneck will be loads dues to the false
|
||||||
|
+ dependency on dst. */
|
||||||
|
+
|
||||||
|
+ /* rcx already has dst - src. */
|
||||||
|
+ movq %rcx, %r9
|
||||||
|
+ /* Add src to len. Subtract back after src aligned. -1 because
|
||||||
|
+ src is initially aligned to MOVSB_ALIGN_TO - 1. */
|
||||||
|
+ leaq -1(%rsi, %rdx), %rcx
|
||||||
|
+ /* Inclusively align src to MOVSB_ALIGN_TO - 1. */
|
||||||
|
+ orq $(MOVSB_ALIGN_TO - 1), %rsi
|
||||||
|
+ /* Restore dst and len adjusted with new values for aligned dst.
|
||||||
|
+ */
|
||||||
|
+ leaq 1(%rsi, %r9), %rdi
|
||||||
|
+ subq %rsi, %rcx
|
||||||
|
+ /* Finish aligning src. */
|
||||||
|
+ incq %rsi
|
||||||
|
+
|
||||||
|
+ rep movsb
|
||||||
|
+
|
||||||
|
+ VMOVU %VEC(0), (%r8)
|
||||||
|
+# if MOVSB_ALIGN_TO > VEC_SIZE
|
||||||
|
+ VMOVU %VEC(1), VEC_SIZE(%r8)
|
||||||
|
+# endif
|
||||||
|
VZEROUPPER_RETURN
|
||||||
|
+# endif
|
||||||
|
+
|
||||||
|
+ .p2align 4,, 12
|
||||||
|
+L(movsb):
|
||||||
|
+ movq %rdi, %rcx
|
||||||
|
+ subq %rsi, %rcx
|
||||||
|
+ /* Go to backwards temporal copy if overlap no matter what as
|
||||||
|
+ backward REP MOVSB is slow and we don't want to use NT stores if
|
||||||
|
+ there is overlap. */
|
||||||
|
+ cmpq %rdx, %rcx
|
||||||
|
+ /* L(more_8x_vec_backward_check_nop) checks for src == dst. */
|
||||||
|
+ jb L(more_8x_vec_backward_check_nop)
|
||||||
|
+# if ALIGN_MOVSB
|
||||||
|
+ /* Save dest for storing aligning VECs later. */
|
||||||
|
+ movq %rdi, %r8
|
||||||
|
+# endif
|
||||||
|
+ /* If above __x86_rep_movsb_stop_threshold most likely is
|
||||||
|
+ candidate for NT moves aswell. */
|
||||||
|
+ cmp __x86_rep_movsb_stop_threshold(%rip), %RDX_LP
|
||||||
|
+ jae L(large_memcpy_2x_check)
|
||||||
|
+# if AVOID_SHORT_DISTANCE_REP_MOVSB || ALIGN_MOVSB
|
||||||
|
+ /* Only avoid short movsb if CPU has FSRM. */
|
||||||
|
+ testl $X86_STRING_CONTROL_AVOID_SHORT_DISTANCE_REP_MOVSB, __x86_string_control(%rip)
|
||||||
|
+ jz L(skip_short_movsb_check)
|
||||||
|
+# if AVOID_SHORT_DISTANCE_REP_MOVSB
|
||||||
|
+ /* Avoid "rep movsb" if RCX, the distance between source and
|
||||||
|
+ destination, is N*4GB + [1..63] with N >= 0. */
|
||||||
|
+
|
||||||
|
+ /* ecx contains dst - src. Early check for backward copy
|
||||||
|
+ conditions means only case of slow movsb with src = dst + [0,
|
||||||
|
+ 63] is ecx in [-63, 0]. Use unsigned comparison with -64 check
|
||||||
|
+ for that case. */
|
||||||
|
+ cmpl $-64, %ecx
|
||||||
|
+ ja L(more_8x_vec_forward)
|
||||||
|
+# endif
|
||||||
|
+# endif
|
||||||
|
+# if ALIGN_MOVSB
|
||||||
|
+# if MOVSB_ALIGN_TO > VEC_SIZE
|
||||||
|
+ VMOVU VEC_SIZE(%rsi), %VEC(1)
|
||||||
|
+# endif
|
||||||
|
+# if MOVSB_ALIGN_TO > (VEC_SIZE * 2)
|
||||||
|
+# error Unsupported MOVSB_ALIGN_TO
|
||||||
|
+# endif
|
||||||
|
+ /* Fall through means cpu has FSRM. In that case exclusively
|
||||||
|
+ align destination. */
|
||||||
|
+L(movsb_align_dst):
|
||||||
|
+ /* Subtract dst from src. Add back after dst aligned. */
|
||||||
|
+ subq %rdi, %rsi
|
||||||
|
+ /* Exclusively align dst to MOVSB_ALIGN_TO (64). */
|
||||||
|
+ addq $(MOVSB_ALIGN_TO - 1), %rdi
|
||||||
|
+ /* Add dst to len. Subtract back after dst aligned. */
|
||||||
|
+ leaq (%r8, %rdx), %rcx
|
||||||
|
+ /* Finish aligning dst. */
|
||||||
|
+ andq $-(MOVSB_ALIGN_TO), %rdi
|
||||||
|
+ /* Restore src and len adjusted with new values for aligned dst.
|
||||||
|
+ */
|
||||||
|
+ addq %rdi, %rsi
|
||||||
|
+ subq %rdi, %rcx
|
||||||
|
+
|
||||||
|
+ rep movsb
|
||||||
|
+
|
||||||
|
+ /* Store VECs loaded for aligning. */
|
||||||
|
+ VMOVU %VEC(0), (%r8)
|
||||||
|
+# if MOVSB_ALIGN_TO > VEC_SIZE
|
||||||
|
+ VMOVU %VEC(1), VEC_SIZE(%r8)
|
||||||
|
+# endif
|
||||||
|
+ VZEROUPPER_RETURN
|
||||||
|
+# else /* !ALIGN_MOVSB. */
|
||||||
|
+L(skip_short_movsb_check):
|
||||||
|
+ mov %RDX_LP, %RCX_LP
|
||||||
|
+ rep movsb
|
||||||
|
+ ret
|
||||||
|
+# endif
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
+ .p2align 4,, 10
|
||||||
|
#if (defined USE_MULTIARCH || VEC_SIZE == 16) && IS_IN (libc)
|
||||||
|
- .p2align 4
|
||||||
|
+L(large_memcpy_2x_check):
|
||||||
|
+ cmp __x86_rep_movsb_threshold(%rip), %RDX_LP
|
||||||
|
+ jb L(more_8x_vec_check)
|
||||||
|
L(large_memcpy_2x):
|
||||||
|
- /* Compute absolute value of difference between source and
|
||||||
|
- destination. */
|
||||||
|
- movq %rdi, %r9
|
||||||
|
- subq %rsi, %r9
|
||||||
|
- movq %r9, %r8
|
||||||
|
- leaq -1(%r9), %rcx
|
||||||
|
- sarq $63, %r8
|
||||||
|
- xorq %r8, %r9
|
||||||
|
- subq %r8, %r9
|
||||||
|
- /* Don't use non-temporal store if there is overlap between
|
||||||
|
- destination and source since destination may be in cache when
|
||||||
|
- source is loaded. */
|
||||||
|
- cmpq %r9, %rdx
|
||||||
|
- ja L(more_8x_vec_check)
|
||||||
|
+ /* To reach this point it is impossible for dst > src and
|
||||||
|
+ overlap. Remaining to check is src > dst and overlap. rcx
|
||||||
|
+ already contains dst - src. Negate rcx to get src - dst. If
|
||||||
|
+ length > rcx then there is overlap and forward copy is best. */
|
||||||
|
+ negq %rcx
|
||||||
|
+ cmpq %rcx, %rdx
|
||||||
|
+ ja L(more_8x_vec_forward)
|
||||||
|
|
||||||
|
/* Cache align destination. First store the first 64 bytes then
|
||||||
|
adjust alignments. */
|
||||||
|
- VMOVU (%rsi), %VEC(8)
|
||||||
|
-#if VEC_SIZE < 64
|
||||||
|
- VMOVU VEC_SIZE(%rsi), %VEC(9)
|
||||||
|
-#if VEC_SIZE < 32
|
||||||
|
- VMOVU (VEC_SIZE * 2)(%rsi), %VEC(10)
|
||||||
|
- VMOVU (VEC_SIZE * 3)(%rsi), %VEC(11)
|
||||||
|
-#endif
|
||||||
|
-#endif
|
||||||
|
- VMOVU %VEC(8), (%rdi)
|
||||||
|
-#if VEC_SIZE < 64
|
||||||
|
- VMOVU %VEC(9), VEC_SIZE(%rdi)
|
||||||
|
-#if VEC_SIZE < 32
|
||||||
|
- VMOVU %VEC(10), (VEC_SIZE * 2)(%rdi)
|
||||||
|
- VMOVU %VEC(11), (VEC_SIZE * 3)(%rdi)
|
||||||
|
-#endif
|
||||||
|
-#endif
|
||||||
|
+
|
||||||
|
+ /* First vec was also loaded into VEC(0). */
|
||||||
|
+# if VEC_SIZE < 64
|
||||||
|
+ VMOVU VEC_SIZE(%rsi), %VEC(1)
|
||||||
|
+# if VEC_SIZE < 32
|
||||||
|
+ VMOVU (VEC_SIZE * 2)(%rsi), %VEC(2)
|
||||||
|
+ VMOVU (VEC_SIZE * 3)(%rsi), %VEC(3)
|
||||||
|
+# endif
|
||||||
|
+# endif
|
||||||
|
+ VMOVU %VEC(0), (%rdi)
|
||||||
|
+# if VEC_SIZE < 64
|
||||||
|
+ VMOVU %VEC(1), VEC_SIZE(%rdi)
|
||||||
|
+# if VEC_SIZE < 32
|
||||||
|
+ VMOVU %VEC(2), (VEC_SIZE * 2)(%rdi)
|
||||||
|
+ VMOVU %VEC(3), (VEC_SIZE * 3)(%rdi)
|
||||||
|
+# endif
|
||||||
|
+# endif
|
||||||
|
+
|
||||||
|
/* Adjust source, destination, and size. */
|
||||||
|
movq %rdi, %r8
|
||||||
|
andq $63, %r8
|
||||||
|
@@ -614,9 +767,13 @@ L(large_memcpy_2x):
|
||||||
|
/* Adjust length. */
|
||||||
|
addq %r8, %rdx
|
||||||
|
|
||||||
|
- /* Test if source and destination addresses will alias. If they do
|
||||||
|
- the larger pipeline in large_memcpy_4x alleviated the
|
||||||
|
+ /* Test if source and destination addresses will alias. If they
|
||||||
|
+ do the larger pipeline in large_memcpy_4x alleviated the
|
||||||
|
performance drop. */
|
||||||
|
+
|
||||||
|
+ /* ecx contains -(dst - src). not ecx will return dst - src - 1
|
||||||
|
+ which works for testing aliasing. */
|
||||||
|
+ notl %ecx
|
||||||
|
testl $(PAGE_SIZE - VEC_SIZE * 8), %ecx
|
||||||
|
jz L(large_memcpy_4x)
|
||||||
|
|
||||||
|
@@ -704,8 +861,8 @@ L(loop_large_memcpy_4x_outer):
|
||||||
|
/* ecx stores inner loop counter. */
|
||||||
|
movl $(PAGE_SIZE / LARGE_LOAD_SIZE), %ecx
|
||||||
|
L(loop_large_memcpy_4x_inner):
|
||||||
|
- /* Only one prefetch set per page as doing 4 pages give more time
|
||||||
|
- for prefetcher to keep up. */
|
||||||
|
+ /* Only one prefetch set per page as doing 4 pages give more
|
||||||
|
+ time for prefetcher to keep up. */
|
||||||
|
PREFETCH_ONE_SET(1, (%rsi), PREFETCHED_LOAD_SIZE)
|
||||||
|
PREFETCH_ONE_SET(1, (%rsi), PAGE_SIZE + PREFETCHED_LOAD_SIZE)
|
||||||
|
PREFETCH_ONE_SET(1, (%rsi), PAGE_SIZE * 2 + PREFETCHED_LOAD_SIZE)
|
131
glibc-upstream-2.34-182.patch
Normal file
131
glibc-upstream-2.34-182.patch
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
commit cecbac52123456e2fbcff062a4165bf7b9174797
|
||||||
|
Author: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||||
|
Date: Mon Nov 1 00:49:52 2021 -0500
|
||||||
|
|
||||||
|
x86: Double size of ERMS rep_movsb_threshold in dl-cacheinfo.h
|
||||||
|
|
||||||
|
No bug.
|
||||||
|
|
||||||
|
This patch doubles the rep_movsb_threshold when using ERMS. Based on
|
||||||
|
benchmarks the vector copy loop, especially now that it handles 4k
|
||||||
|
aliasing, is better for these medium ranged.
|
||||||
|
|
||||||
|
On Skylake with ERMS:
|
||||||
|
|
||||||
|
Size, Align1, Align2, dst>src,(rep movsb) / (vec copy)
|
||||||
|
4096, 0, 0, 0, 0.975
|
||||||
|
4096, 0, 0, 1, 0.953
|
||||||
|
4096, 12, 0, 0, 0.969
|
||||||
|
4096, 12, 0, 1, 0.872
|
||||||
|
4096, 44, 0, 0, 0.979
|
||||||
|
4096, 44, 0, 1, 0.83
|
||||||
|
4096, 0, 12, 0, 1.006
|
||||||
|
4096, 0, 12, 1, 0.989
|
||||||
|
4096, 0, 44, 0, 0.739
|
||||||
|
4096, 0, 44, 1, 0.942
|
||||||
|
4096, 12, 12, 0, 1.009
|
||||||
|
4096, 12, 12, 1, 0.973
|
||||||
|
4096, 44, 44, 0, 0.791
|
||||||
|
4096, 44, 44, 1, 0.961
|
||||||
|
4096, 2048, 0, 0, 0.978
|
||||||
|
4096, 2048, 0, 1, 0.951
|
||||||
|
4096, 2060, 0, 0, 0.986
|
||||||
|
4096, 2060, 0, 1, 0.963
|
||||||
|
4096, 2048, 12, 0, 0.971
|
||||||
|
4096, 2048, 12, 1, 0.941
|
||||||
|
4096, 2060, 12, 0, 0.977
|
||||||
|
4096, 2060, 12, 1, 0.949
|
||||||
|
8192, 0, 0, 0, 0.85
|
||||||
|
8192, 0, 0, 1, 0.845
|
||||||
|
8192, 13, 0, 0, 0.937
|
||||||
|
8192, 13, 0, 1, 0.939
|
||||||
|
8192, 45, 0, 0, 0.932
|
||||||
|
8192, 45, 0, 1, 0.927
|
||||||
|
8192, 0, 13, 0, 0.621
|
||||||
|
8192, 0, 13, 1, 0.62
|
||||||
|
8192, 0, 45, 0, 0.53
|
||||||
|
8192, 0, 45, 1, 0.516
|
||||||
|
8192, 13, 13, 0, 0.664
|
||||||
|
8192, 13, 13, 1, 0.659
|
||||||
|
8192, 45, 45, 0, 0.593
|
||||||
|
8192, 45, 45, 1, 0.575
|
||||||
|
8192, 2048, 0, 0, 0.854
|
||||||
|
8192, 2048, 0, 1, 0.834
|
||||||
|
8192, 2061, 0, 0, 0.863
|
||||||
|
8192, 2061, 0, 1, 0.857
|
||||||
|
8192, 2048, 13, 0, 0.63
|
||||||
|
8192, 2048, 13, 1, 0.629
|
||||||
|
8192, 2061, 13, 0, 0.627
|
||||||
|
8192, 2061, 13, 1, 0.62
|
||||||
|
|
||||||
|
Signed-off-by: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||||
|
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
||||||
|
(cherry picked from commit 475b63702ef38b69558fc3d31a0b66776a70f1d3)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/x86/dl-cacheinfo.h b/sysdeps/x86/dl-cacheinfo.h
|
||||||
|
index e6c94dfd023a25dc..2e43e67e4f4037d3 100644
|
||||||
|
--- a/sysdeps/x86/dl-cacheinfo.h
|
||||||
|
+++ b/sysdeps/x86/dl-cacheinfo.h
|
||||||
|
@@ -866,12 +866,14 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
|
||||||
|
/* NB: The REP MOVSB threshold must be greater than VEC_SIZE * 8. */
|
||||||
|
unsigned int minimum_rep_movsb_threshold;
|
||||||
|
#endif
|
||||||
|
- /* NB: The default REP MOVSB threshold is 2048 * (VEC_SIZE / 16). */
|
||||||
|
+ /* NB: The default REP MOVSB threshold is 4096 * (VEC_SIZE / 16) for
|
||||||
|
+ VEC_SIZE == 64 or 32. For VEC_SIZE == 16, the default REP MOVSB
|
||||||
|
+ threshold is 2048 * (VEC_SIZE / 16). */
|
||||||
|
unsigned int rep_movsb_threshold;
|
||||||
|
if (CPU_FEATURE_USABLE_P (cpu_features, AVX512F)
|
||||||
|
&& !CPU_FEATURE_PREFERRED_P (cpu_features, Prefer_No_AVX512))
|
||||||
|
{
|
||||||
|
- rep_movsb_threshold = 2048 * (64 / 16);
|
||||||
|
+ rep_movsb_threshold = 4096 * (64 / 16);
|
||||||
|
#if HAVE_TUNABLES
|
||||||
|
minimum_rep_movsb_threshold = 64 * 8;
|
||||||
|
#endif
|
||||||
|
@@ -879,7 +881,7 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
|
||||||
|
else if (CPU_FEATURE_PREFERRED_P (cpu_features,
|
||||||
|
AVX_Fast_Unaligned_Load))
|
||||||
|
{
|
||||||
|
- rep_movsb_threshold = 2048 * (32 / 16);
|
||||||
|
+ rep_movsb_threshold = 4096 * (32 / 16);
|
||||||
|
#if HAVE_TUNABLES
|
||||||
|
minimum_rep_movsb_threshold = 32 * 8;
|
||||||
|
#endif
|
||||||
|
diff --git a/sysdeps/x86/dl-tunables.list b/sysdeps/x86/dl-tunables.list
|
||||||
|
index dd6e1d65c9490d4f..419313804d49cf65 100644
|
||||||
|
--- a/sysdeps/x86/dl-tunables.list
|
||||||
|
+++ b/sysdeps/x86/dl-tunables.list
|
||||||
|
@@ -32,17 +32,21 @@ glibc {
|
||||||
|
}
|
||||||
|
x86_rep_movsb_threshold {
|
||||||
|
type: SIZE_T
|
||||||
|
- # Since there is overhead to set up REP MOVSB operation, REP MOVSB
|
||||||
|
- # isn't faster on short data. The memcpy micro benchmark in glibc
|
||||||
|
- # shows that 2KB is the approximate value above which REP MOVSB
|
||||||
|
- # becomes faster than SSE2 optimization on processors with Enhanced
|
||||||
|
- # REP MOVSB. Since larger register size can move more data with a
|
||||||
|
- # single load and store, the threshold is higher with larger register
|
||||||
|
- # size. Note: Since the REP MOVSB threshold must be greater than 8
|
||||||
|
- # times of vector size and the default value is 2048 * (vector size
|
||||||
|
- # / 16), the default value and the minimum value must be updated at
|
||||||
|
- # run-time. NB: Don't set the default value since we can't tell if
|
||||||
|
- # the tunable value is set by user or not [BZ #27069].
|
||||||
|
+ # Since there is overhead to set up REP MOVSB operation, REP
|
||||||
|
+ # MOVSB isn't faster on short data. The memcpy micro benchmark
|
||||||
|
+ # in glibc shows that 2KB is the approximate value above which
|
||||||
|
+ # REP MOVSB becomes faster than SSE2 optimization on processors
|
||||||
|
+ # with Enhanced REP MOVSB. Since larger register size can move
|
||||||
|
+ # more data with a single load and store, the threshold is
|
||||||
|
+ # higher with larger register size. Micro benchmarks show AVX
|
||||||
|
+ # REP MOVSB becomes faster apprximately at 8KB. The AVX512
|
||||||
|
+ # threshold is extrapolated to 16KB. For machines with FSRM the
|
||||||
|
+ # threshold is universally set at 2112 bytes. Note: Since the
|
||||||
|
+ # REP MOVSB threshold must be greater than 8 times of vector
|
||||||
|
+ # size and the default value is 4096 * (vector size / 16), the
|
||||||
|
+ # default value and the minimum value must be updated at
|
||||||
|
+ # run-time. NB: Don't set the default value since we can't tell
|
||||||
|
+ # if the tunable value is set by user or not [BZ #27069].
|
||||||
|
minval: 1
|
||||||
|
}
|
||||||
|
x86_rep_stosb_threshold {
|
2423
glibc-upstream-2.34-183.patch
Normal file
2423
glibc-upstream-2.34-183.patch
Normal file
File diff suppressed because it is too large
Load Diff
104
glibc-upstream-2.34-184.patch
Normal file
104
glibc-upstream-2.34-184.patch
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
commit 4bbd0f866ad0ff197f72346f776ebee9b7e1a706
|
||||||
|
Author: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||||
|
Date: Fri Dec 3 15:29:25 2021 -0800
|
||||||
|
|
||||||
|
x86-64: Use notl in EVEX strcmp [BZ #28646]
|
||||||
|
|
||||||
|
Must use notl %edi here as lower bits are for CHAR comparisons
|
||||||
|
potentially out of range thus can be 0 without indicating mismatch.
|
||||||
|
This fixes BZ #28646.
|
||||||
|
|
||||||
|
Co-Authored-By: H.J. Lu <hjl.tools@gmail.com>
|
||||||
|
(cherry picked from commit 4df1fa6ddc8925a75f3da644d5da3bb16eb33f02)
|
||||||
|
|
||||||
|
diff --git a/string/test-strcmp.c b/string/test-strcmp.c
|
||||||
|
index 7feababf4ddc5603..a0255b9625fbcedd 100644
|
||||||
|
--- a/string/test-strcmp.c
|
||||||
|
+++ b/string/test-strcmp.c
|
||||||
|
@@ -25,6 +25,7 @@
|
||||||
|
# define TEST_NAME "strcmp"
|
||||||
|
#endif
|
||||||
|
#include "test-string.h"
|
||||||
|
+#include <support/test-driver.h>
|
||||||
|
|
||||||
|
#ifdef WIDE
|
||||||
|
# include <wchar.h>
|
||||||
|
@@ -392,6 +393,32 @@ check2 (void)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void
|
||||||
|
+check3 (void)
|
||||||
|
+{
|
||||||
|
+ size_t size = 0xd000 + 0x4000;
|
||||||
|
+ CHAR *s1, *s2;
|
||||||
|
+ CHAR *buffer1 = mmap (NULL, size, PROT_READ | PROT_WRITE,
|
||||||
|
+ MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||||
|
+ CHAR *buffer2 = mmap (NULL, size, PROT_READ | PROT_WRITE,
|
||||||
|
+ MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||||
|
+ if (buffer1 == MAP_FAILED || buffer1 == MAP_FAILED)
|
||||||
|
+ error (EXIT_UNSUPPORTED, errno, "mmap failed");
|
||||||
|
+
|
||||||
|
+ s1 = (CHAR *) (buffer1 + 0x8f8 / sizeof (CHAR));
|
||||||
|
+ s2 = (CHAR *) (buffer2 + 0xcff3 / sizeof (CHAR));
|
||||||
|
+
|
||||||
|
+ STRCPY(s1, L("/export/redhat/rpms/BUILD/java-1.8.0-openjdk-1.8.0.312.b07-2.fc35.x86_64/openjdk/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/PathDocFileFactory.java"));
|
||||||
|
+ STRCPY(s2, L("/export/redhat/rpms/BUILD/java-1.8.0-openjdk-1.8.0.312.b07-2.fc35.x86_64/openjdk/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ThrowsTaglet.java"));
|
||||||
|
+
|
||||||
|
+ int exp_result = SIMPLE_STRCMP (s1, s2);
|
||||||
|
+ FOR_EACH_IMPL (impl, 0)
|
||||||
|
+ check_result (impl, s1, s2, exp_result);
|
||||||
|
+
|
||||||
|
+ munmap ((void *) buffer1, size);
|
||||||
|
+ munmap ((void *) buffer2, size);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int
|
||||||
|
test_main (void)
|
||||||
|
{
|
||||||
|
@@ -400,6 +427,7 @@ test_main (void)
|
||||||
|
test_init ();
|
||||||
|
check();
|
||||||
|
check2 ();
|
||||||
|
+ check3 ();
|
||||||
|
|
||||||
|
printf ("%23s", "");
|
||||||
|
FOR_EACH_IMPL (impl, 0)
|
||||||
|
diff --git a/sysdeps/x86_64/multiarch/strcmp-evex.S b/sysdeps/x86_64/multiarch/strcmp-evex.S
|
||||||
|
index 82f12ac89bcae20b..6f5c4bf984da2b80 100644
|
||||||
|
--- a/sysdeps/x86_64/multiarch/strcmp-evex.S
|
||||||
|
+++ b/sysdeps/x86_64/multiarch/strcmp-evex.S
|
||||||
|
@@ -656,12 +656,13 @@ L(loop_cross_page):
|
||||||
|
in YMM3 and 32 bytes at VEC_SIZE(%rdx, %r10). */
|
||||||
|
VPCMP $0, VEC_SIZE(%rdx, %r10), %YMM3, %k3{%k4}
|
||||||
|
kmovd %k3, %edi
|
||||||
|
+ /* Must use notl %edi here as lower bits are for CHAR
|
||||||
|
+ comparisons potentially out of range thus can be 0 without
|
||||||
|
+ indicating mismatch. */
|
||||||
|
+ notl %edi
|
||||||
|
# ifdef USE_AS_WCSCMP
|
||||||
|
/* Don't use subl since it is the upper 8 bits of EDI below. */
|
||||||
|
- notl %edi
|
||||||
|
andl $0xff, %edi
|
||||||
|
-# else
|
||||||
|
- incl %edi
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifdef USE_AS_WCSCMP
|
||||||
|
@@ -743,12 +744,13 @@ L(loop_cross_page_2_vec):
|
||||||
|
in YMM1 and 32 bytes at (VEC_SIZE * 3)(%rdx, %r10). */
|
||||||
|
VPCMP $0, (VEC_SIZE * 3)(%rdx, %r10), %YMM1, %k3{%k4}
|
||||||
|
kmovd %k3, %edi
|
||||||
|
+ /* Must use notl %edi here as lower bits are for CHAR
|
||||||
|
+ comparisons potentially out of range thus can be 0 without
|
||||||
|
+ indicating mismatch. */
|
||||||
|
+ notl %edi
|
||||||
|
# ifdef USE_AS_WCSCMP
|
||||||
|
/* Don't use subl since it is the upper 8 bits of EDI below. */
|
||||||
|
- notl %edi
|
||||||
|
andl $0xff, %edi
|
||||||
|
-# else
|
||||||
|
- incl %edi
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifdef USE_AS_WCSCMP
|
30
glibc-upstream-2.34-185.patch
Normal file
30
glibc-upstream-2.34-185.patch
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
commit f3a99b2216114f89b20329ae7664b764248b4bbd
|
||||||
|
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||||
|
Date: Mon Dec 6 07:14:12 2021 -0800
|
||||||
|
|
||||||
|
x86: Don't set Prefer_No_AVX512 for processors with AVX512 and AVX-VNNI
|
||||||
|
|
||||||
|
Don't set Prefer_No_AVX512 on processors with AVX512 and AVX-VNNI since
|
||||||
|
they won't lower CPU frequency when ZMM load and store instructions are
|
||||||
|
used.
|
||||||
|
|
||||||
|
(cherry picked from commit ceeffe968c01b1202e482f4855cb6baf5c6cb713)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
|
||||||
|
index f4d4049e391cbabd..09590d8794b1c6fb 100644
|
||||||
|
--- a/sysdeps/x86/cpu-features.c
|
||||||
|
+++ b/sysdeps/x86/cpu-features.c
|
||||||
|
@@ -566,8 +566,11 @@ disable_tsx:
|
||||||
|
|= bit_arch_Prefer_No_VZEROUPPER;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
- cpu_features->preferred[index_arch_Prefer_No_AVX512]
|
||||||
|
- |= bit_arch_Prefer_No_AVX512;
|
||||||
|
+ /* Processors with AVX512 and AVX-VNNI won't lower CPU frequency
|
||||||
|
+ when ZMM load and store instructions are used. */
|
||||||
|
+ if (!CPU_FEATURES_CPU_P (cpu_features, AVX_VNNI))
|
||||||
|
+ cpu_features->preferred[index_arch_Prefer_No_AVX512]
|
||||||
|
+ |= bit_arch_Prefer_No_AVX512;
|
||||||
|
|
||||||
|
/* Avoid RTM abort triggered by VZEROUPPER inside a
|
||||||
|
transactionally executing RTM region. */
|
384
glibc-upstream-2.34-186.patch
Normal file
384
glibc-upstream-2.34-186.patch
Normal file
@ -0,0 +1,384 @@
|
|||||||
|
commit c796418d00f65c8c5fbed477f3ba6da2bee64ece
|
||||||
|
Author: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||||
|
Date: Fri Dec 24 18:54:41 2021 -0600
|
||||||
|
|
||||||
|
x86: Optimize L(less_vec) case in memcmp-evex-movbe.S
|
||||||
|
|
||||||
|
No bug.
|
||||||
|
Optimizations are twofold.
|
||||||
|
|
||||||
|
1) Replace page cross and 0/1 checks with masked load instructions in
|
||||||
|
L(less_vec). In applications this reduces branch-misses in the
|
||||||
|
hot [0, 32] case.
|
||||||
|
2) Change controlflow so that L(less_vec) case gets the fall through.
|
||||||
|
|
||||||
|
Change 2) helps copies in the [0, 32] size range but comes at the cost
|
||||||
|
of copies in the [33, 64] size range. From profiles of GCC and
|
||||||
|
Python3, 94%+ and 99%+ of calls are in the [0, 32] range so this
|
||||||
|
appears to the the right tradeoff.
|
||||||
|
|
||||||
|
Signed-off-by: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||||
|
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
||||||
|
(cherry picked from commit abddd61de090ae84e380aff68a98bd94ef704667)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S b/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S
|
||||||
|
index 640f6757fac8a356..d2899e7c7078cd41 100644
|
||||||
|
--- a/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S
|
||||||
|
+++ b/sysdeps/x86_64/multiarch/memcmp-evex-movbe.S
|
||||||
|
@@ -62,15 +62,18 @@ Latency:
|
||||||
|
# define VMOVU vmovdqu64
|
||||||
|
|
||||||
|
# ifdef USE_AS_WMEMCMP
|
||||||
|
+# define VMOVU_MASK vmovdqu32
|
||||||
|
# define CHAR_SIZE 4
|
||||||
|
# define VPCMP vpcmpd
|
||||||
|
# define VPTEST vptestmd
|
||||||
|
# else
|
||||||
|
+# define VMOVU_MASK vmovdqu8
|
||||||
|
# define CHAR_SIZE 1
|
||||||
|
# define VPCMP vpcmpub
|
||||||
|
# define VPTEST vptestmb
|
||||||
|
# endif
|
||||||
|
|
||||||
|
+
|
||||||
|
# define VEC_SIZE 32
|
||||||
|
# define PAGE_SIZE 4096
|
||||||
|
# define CHAR_PER_VEC (VEC_SIZE / CHAR_SIZE)
|
||||||
|
@@ -102,12 +105,48 @@ ENTRY_P2ALIGN (MEMCMP, 6)
|
||||||
|
movl %edx, %edx
|
||||||
|
# endif
|
||||||
|
cmp $CHAR_PER_VEC, %RDX_LP
|
||||||
|
- jb L(less_vec)
|
||||||
|
+ /* Fall through for [0, VEC_SIZE] as its the hottest. */
|
||||||
|
+ ja L(more_1x_vec)
|
||||||
|
+
|
||||||
|
+ /* Create mask for CHAR's we want to compare. This allows us to
|
||||||
|
+ avoid having to include page cross logic. */
|
||||||
|
+ movl $-1, %ecx
|
||||||
|
+ bzhil %edx, %ecx, %ecx
|
||||||
|
+ kmovd %ecx, %k2
|
||||||
|
+
|
||||||
|
+ /* Safe to load full ymm with mask. */
|
||||||
|
+ VMOVU_MASK (%rsi), %YMM2{%k2}
|
||||||
|
+ VPCMP $4,(%rdi), %YMM2, %k1{%k2}
|
||||||
|
+ kmovd %k1, %eax
|
||||||
|
+ testl %eax, %eax
|
||||||
|
+ jnz L(return_vec_0)
|
||||||
|
+ ret
|
||||||
|
|
||||||
|
+ .p2align 4
|
||||||
|
+L(return_vec_0):
|
||||||
|
+ tzcntl %eax, %eax
|
||||||
|
+# ifdef USE_AS_WMEMCMP
|
||||||
|
+ movl (%rdi, %rax, CHAR_SIZE), %ecx
|
||||||
|
+ xorl %edx, %edx
|
||||||
|
+ cmpl (%rsi, %rax, CHAR_SIZE), %ecx
|
||||||
|
+ /* NB: no partial register stall here because xorl zero idiom
|
||||||
|
+ above. */
|
||||||
|
+ setg %dl
|
||||||
|
+ leal -1(%rdx, %rdx), %eax
|
||||||
|
+# else
|
||||||
|
+ movzbl (%rsi, %rax), %ecx
|
||||||
|
+ movzbl (%rdi, %rax), %eax
|
||||||
|
+ subl %ecx, %eax
|
||||||
|
+# endif
|
||||||
|
+ ret
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ .p2align 4
|
||||||
|
+L(more_1x_vec):
|
||||||
|
/* From VEC to 2 * VEC. No branch when size == VEC_SIZE. */
|
||||||
|
VMOVU (%rsi), %YMM1
|
||||||
|
/* Use compare not equals to directly check for mismatch. */
|
||||||
|
- VPCMP $4, (%rdi), %YMM1, %k1
|
||||||
|
+ VPCMP $4,(%rdi), %YMM1, %k1
|
||||||
|
kmovd %k1, %eax
|
||||||
|
/* NB: eax must be destination register if going to
|
||||||
|
L(return_vec_[0,2]). For L(return_vec_3) destination register
|
||||||
|
@@ -131,13 +170,13 @@ ENTRY_P2ALIGN (MEMCMP, 6)
|
||||||
|
|
||||||
|
/* Check third and fourth VEC no matter what. */
|
||||||
|
VMOVU (VEC_SIZE * 2)(%rsi), %YMM3
|
||||||
|
- VPCMP $4, (VEC_SIZE * 2)(%rdi), %YMM3, %k1
|
||||||
|
+ VPCMP $4,(VEC_SIZE * 2)(%rdi), %YMM3, %k1
|
||||||
|
kmovd %k1, %eax
|
||||||
|
testl %eax, %eax
|
||||||
|
jnz L(return_vec_2)
|
||||||
|
|
||||||
|
VMOVU (VEC_SIZE * 3)(%rsi), %YMM4
|
||||||
|
- VPCMP $4, (VEC_SIZE * 3)(%rdi), %YMM4, %k1
|
||||||
|
+ VPCMP $4,(VEC_SIZE * 3)(%rdi), %YMM4, %k1
|
||||||
|
kmovd %k1, %ecx
|
||||||
|
testl %ecx, %ecx
|
||||||
|
jnz L(return_vec_3)
|
||||||
|
@@ -169,7 +208,7 @@ ENTRY_P2ALIGN (MEMCMP, 6)
|
||||||
|
VMOVU (VEC_SIZE * 3)(%rsi), %YMM4
|
||||||
|
/* Ternary logic to xor (VEC_SIZE * 3)(%rdi) with YMM4 while
|
||||||
|
oring with YMM1. Result is stored in YMM4. */
|
||||||
|
- vpternlogd $0xde, (VEC_SIZE * 3)(%rdi), %YMM1, %YMM4
|
||||||
|
+ vpternlogd $0xde,(VEC_SIZE * 3)(%rdi), %YMM1, %YMM4
|
||||||
|
|
||||||
|
/* Or together YMM2, YMM3, and YMM4 into YMM4. */
|
||||||
|
vpternlogd $0xfe, %YMM2, %YMM3, %YMM4
|
||||||
|
@@ -184,7 +223,8 @@ ENTRY_P2ALIGN (MEMCMP, 6)
|
||||||
|
/* NB: eax must be zero to reach here. */
|
||||||
|
ret
|
||||||
|
|
||||||
|
- .p2align 4
|
||||||
|
+
|
||||||
|
+ .p2align 4,, 8
|
||||||
|
L(8x_end_return_vec_0_1_2_3):
|
||||||
|
movq %rdx, %rdi
|
||||||
|
L(8x_return_vec_0_1_2_3):
|
||||||
|
@@ -222,23 +262,6 @@ L(return_vec_3):
|
||||||
|
# endif
|
||||||
|
ret
|
||||||
|
|
||||||
|
- .p2align 4
|
||||||
|
-L(return_vec_0):
|
||||||
|
- tzcntl %eax, %eax
|
||||||
|
-# ifdef USE_AS_WMEMCMP
|
||||||
|
- movl (%rdi, %rax, CHAR_SIZE), %ecx
|
||||||
|
- xorl %edx, %edx
|
||||||
|
- cmpl (%rsi, %rax, CHAR_SIZE), %ecx
|
||||||
|
- /* NB: no partial register stall here because xorl zero idiom
|
||||||
|
- above. */
|
||||||
|
- setg %dl
|
||||||
|
- leal -1(%rdx, %rdx), %eax
|
||||||
|
-# else
|
||||||
|
- movzbl (%rsi, %rax), %ecx
|
||||||
|
- movzbl (%rdi, %rax), %eax
|
||||||
|
- subl %ecx, %eax
|
||||||
|
-# endif
|
||||||
|
- ret
|
||||||
|
|
||||||
|
.p2align 4
|
||||||
|
L(return_vec_1):
|
||||||
|
@@ -297,7 +320,7 @@ L(loop_4x_vec):
|
||||||
|
VMOVU (VEC_SIZE * 2)(%rsi, %rdi), %YMM3
|
||||||
|
vpxorq (VEC_SIZE * 2)(%rdi), %YMM3, %YMM3
|
||||||
|
VMOVU (VEC_SIZE * 3)(%rsi, %rdi), %YMM4
|
||||||
|
- vpternlogd $0xde, (VEC_SIZE * 3)(%rdi), %YMM1, %YMM4
|
||||||
|
+ vpternlogd $0xde,(VEC_SIZE * 3)(%rdi), %YMM1, %YMM4
|
||||||
|
vpternlogd $0xfe, %YMM2, %YMM3, %YMM4
|
||||||
|
VPTEST %YMM4, %YMM4, %k1
|
||||||
|
kmovd %k1, %ecx
|
||||||
|
@@ -324,7 +347,7 @@ L(loop_4x_vec):
|
||||||
|
VMOVU VEC_SIZE(%rsi, %rdx), %YMM2
|
||||||
|
vpxorq VEC_SIZE(%rdx), %YMM2, %YMM2
|
||||||
|
VMOVU (VEC_SIZE * 3)(%rsi, %rdx), %YMM4
|
||||||
|
- vpternlogd $0xde, (VEC_SIZE * 3)(%rdx), %YMM1, %YMM4
|
||||||
|
+ vpternlogd $0xde,(VEC_SIZE * 3)(%rdx), %YMM1, %YMM4
|
||||||
|
vpternlogd $0xfe, %YMM2, %YMM3, %YMM4
|
||||||
|
VPTEST %YMM4, %YMM4, %k1
|
||||||
|
kmovd %k1, %ecx
|
||||||
|
@@ -336,14 +359,14 @@ L(loop_4x_vec):
|
||||||
|
/* Only entry is from L(more_8x_vec). */
|
||||||
|
.p2align 4,, 10
|
||||||
|
L(8x_last_2x_vec):
|
||||||
|
- VPCMP $4, (VEC_SIZE * 2)(%rdx), %YMM3, %k1
|
||||||
|
+ VPCMP $4,(VEC_SIZE * 2)(%rdx), %YMM3, %k1
|
||||||
|
kmovd %k1, %eax
|
||||||
|
testl %eax, %eax
|
||||||
|
jnz L(8x_return_vec_2)
|
||||||
|
/* Naturally aligned to 16 bytes. */
|
||||||
|
L(8x_last_1x_vec):
|
||||||
|
VMOVU (VEC_SIZE * 3)(%rsi, %rdx), %YMM1
|
||||||
|
- VPCMP $4, (VEC_SIZE * 3)(%rdx), %YMM1, %k1
|
||||||
|
+ VPCMP $4,(VEC_SIZE * 3)(%rdx), %YMM1, %k1
|
||||||
|
kmovd %k1, %eax
|
||||||
|
testl %eax, %eax
|
||||||
|
jnz L(8x_return_vec_3)
|
||||||
|
@@ -392,7 +415,9 @@ L(last_1x_vec):
|
||||||
|
jnz L(return_vec_0_end)
|
||||||
|
ret
|
||||||
|
|
||||||
|
- .p2align 4,, 10
|
||||||
|
+
|
||||||
|
+ /* Don't align. Takes 2-fetch blocks either way and aligning
|
||||||
|
+ will cause code to spill into another cacheline. */
|
||||||
|
L(return_vec_1_end):
|
||||||
|
/* Use bsf to save code size. This is necessary to have
|
||||||
|
L(one_or_less) fit in aligning bytes between. */
|
||||||
|
@@ -411,31 +436,8 @@ L(return_vec_1_end):
|
||||||
|
# endif
|
||||||
|
ret
|
||||||
|
|
||||||
|
- /* NB: L(one_or_less) fits in alignment padding between
|
||||||
|
- L(return_vec_1_end) and L(return_vec_0_end). */
|
||||||
|
-# ifdef USE_AS_WMEMCMP
|
||||||
|
-L(one_or_less):
|
||||||
|
- jb L(zero)
|
||||||
|
- movl (%rdi), %ecx
|
||||||
|
- xorl %edx, %edx
|
||||||
|
- cmpl (%rsi), %ecx
|
||||||
|
- je L(zero)
|
||||||
|
- setg %dl
|
||||||
|
- leal -1(%rdx, %rdx), %eax
|
||||||
|
- ret
|
||||||
|
-# else
|
||||||
|
-L(one_or_less):
|
||||||
|
- jb L(zero)
|
||||||
|
- movzbl (%rsi), %ecx
|
||||||
|
- movzbl (%rdi), %eax
|
||||||
|
- subl %ecx, %eax
|
||||||
|
- ret
|
||||||
|
-# endif
|
||||||
|
-L(zero):
|
||||||
|
- xorl %eax, %eax
|
||||||
|
- ret
|
||||||
|
-
|
||||||
|
- .p2align 4
|
||||||
|
+ /* Don't align. Takes 2-fetch blocks either way and aligning
|
||||||
|
+ will cause code to spill into another cacheline. */
|
||||||
|
L(return_vec_0_end):
|
||||||
|
tzcntl %eax, %eax
|
||||||
|
addl %edx, %eax
|
||||||
|
@@ -451,146 +453,7 @@ L(return_vec_0_end):
|
||||||
|
subl %ecx, %eax
|
||||||
|
# endif
|
||||||
|
ret
|
||||||
|
+ /* 1-byte until next cache line. */
|
||||||
|
|
||||||
|
- .p2align 4
|
||||||
|
-L(less_vec):
|
||||||
|
- /* Check if one or less CHAR. This is necessary for size == 0
|
||||||
|
- but is also faster for size == CHAR_SIZE. */
|
||||||
|
- cmpl $1, %edx
|
||||||
|
- jbe L(one_or_less)
|
||||||
|
-
|
||||||
|
- /* Check if loading one VEC from either s1 or s2 could cause a
|
||||||
|
- page cross. This can have false positives but is by far the
|
||||||
|
- fastest method. */
|
||||||
|
- movl %edi, %eax
|
||||||
|
- orl %esi, %eax
|
||||||
|
- andl $(PAGE_SIZE - 1), %eax
|
||||||
|
- cmpl $(PAGE_SIZE - VEC_SIZE), %eax
|
||||||
|
- jg L(page_cross_less_vec)
|
||||||
|
-
|
||||||
|
- /* No page cross possible. */
|
||||||
|
- VMOVU (%rsi), %YMM2
|
||||||
|
- VPCMP $4, (%rdi), %YMM2, %k1
|
||||||
|
- kmovd %k1, %eax
|
||||||
|
- /* Check if any matches where in bounds. Intentionally not
|
||||||
|
- storing result in eax to limit dependency chain if it goes to
|
||||||
|
- L(return_vec_0_lv). */
|
||||||
|
- bzhil %edx, %eax, %edx
|
||||||
|
- jnz L(return_vec_0_lv)
|
||||||
|
- xorl %eax, %eax
|
||||||
|
- ret
|
||||||
|
-
|
||||||
|
- /* Essentially duplicate of L(return_vec_0). Ends up not costing
|
||||||
|
- any code as shrinks L(less_vec) by allowing 2-byte encoding of
|
||||||
|
- the jump and ends up fitting in aligning bytes. As well fits on
|
||||||
|
- same cache line as L(less_vec) so also saves a line from having
|
||||||
|
- to be fetched on cold calls to memcmp. */
|
||||||
|
- .p2align 4,, 4
|
||||||
|
-L(return_vec_0_lv):
|
||||||
|
- tzcntl %eax, %eax
|
||||||
|
-# ifdef USE_AS_WMEMCMP
|
||||||
|
- movl (%rdi, %rax, CHAR_SIZE), %ecx
|
||||||
|
- xorl %edx, %edx
|
||||||
|
- cmpl (%rsi, %rax, CHAR_SIZE), %ecx
|
||||||
|
- /* NB: no partial register stall here because xorl zero idiom
|
||||||
|
- above. */
|
||||||
|
- setg %dl
|
||||||
|
- leal -1(%rdx, %rdx), %eax
|
||||||
|
-# else
|
||||||
|
- movzbl (%rsi, %rax), %ecx
|
||||||
|
- movzbl (%rdi, %rax), %eax
|
||||||
|
- subl %ecx, %eax
|
||||||
|
-# endif
|
||||||
|
- ret
|
||||||
|
-
|
||||||
|
- .p2align 4
|
||||||
|
-L(page_cross_less_vec):
|
||||||
|
- /* if USE_AS_WMEMCMP it can only be 0, 4, 8, 12, 16, 20, 24, 28
|
||||||
|
- bytes. */
|
||||||
|
- cmpl $(16 / CHAR_SIZE), %edx
|
||||||
|
- jae L(between_16_31)
|
||||||
|
-# ifndef USE_AS_WMEMCMP
|
||||||
|
- cmpl $8, %edx
|
||||||
|
- jae L(between_8_15)
|
||||||
|
- cmpl $4, %edx
|
||||||
|
- jb L(between_2_3)
|
||||||
|
-
|
||||||
|
- /* Load as big endian with overlapping movbe to avoid branches.
|
||||||
|
- */
|
||||||
|
- movbe (%rdi), %eax
|
||||||
|
- movbe (%rsi), %ecx
|
||||||
|
- shlq $32, %rax
|
||||||
|
- shlq $32, %rcx
|
||||||
|
- movbe -4(%rdi, %rdx), %edi
|
||||||
|
- movbe -4(%rsi, %rdx), %esi
|
||||||
|
- orq %rdi, %rax
|
||||||
|
- orq %rsi, %rcx
|
||||||
|
- subq %rcx, %rax
|
||||||
|
- /* edx is guranteed to be positive int32 in range [4, 7]. */
|
||||||
|
- cmovne %edx, %eax
|
||||||
|
- /* ecx is -1 if rcx > rax. Otherwise 0. */
|
||||||
|
- sbbl %ecx, %ecx
|
||||||
|
- /* If rcx > rax, then ecx is 0 and eax is positive. If rcx ==
|
||||||
|
- rax then eax and ecx are zero. If rax < rax then ecx is -1 so
|
||||||
|
- eax doesn't matter. */
|
||||||
|
- orl %ecx, %eax
|
||||||
|
- ret
|
||||||
|
-
|
||||||
|
- .p2align 4,, 8
|
||||||
|
-L(between_8_15):
|
||||||
|
-# endif
|
||||||
|
- /* If USE_AS_WMEMCMP fall through into 8-15 byte case. */
|
||||||
|
- vmovq (%rdi), %xmm1
|
||||||
|
- vmovq (%rsi), %xmm2
|
||||||
|
- VPCMP $4, %xmm1, %xmm2, %k1
|
||||||
|
- kmovd %k1, %eax
|
||||||
|
- testl %eax, %eax
|
||||||
|
- jnz L(return_vec_0_lv)
|
||||||
|
- /* Use overlapping loads to avoid branches. */
|
||||||
|
- vmovq -8(%rdi, %rdx, CHAR_SIZE), %xmm1
|
||||||
|
- vmovq -8(%rsi, %rdx, CHAR_SIZE), %xmm2
|
||||||
|
- VPCMP $4, %xmm1, %xmm2, %k1
|
||||||
|
- addl $(CHAR_PER_VEC - (8 / CHAR_SIZE)), %edx
|
||||||
|
- kmovd %k1, %eax
|
||||||
|
- testl %eax, %eax
|
||||||
|
- jnz L(return_vec_0_end)
|
||||||
|
- ret
|
||||||
|
-
|
||||||
|
- .p2align 4,, 8
|
||||||
|
-L(between_16_31):
|
||||||
|
- /* From 16 to 31 bytes. No branch when size == 16. */
|
||||||
|
-
|
||||||
|
- /* Use movups to save code size. */
|
||||||
|
- vmovdqu (%rsi), %xmm2
|
||||||
|
- VPCMP $4, (%rdi), %xmm2, %k1
|
||||||
|
- kmovd %k1, %eax
|
||||||
|
- testl %eax, %eax
|
||||||
|
- jnz L(return_vec_0_lv)
|
||||||
|
- /* Use overlapping loads to avoid branches. */
|
||||||
|
- vmovdqu -16(%rsi, %rdx, CHAR_SIZE), %xmm2
|
||||||
|
- VPCMP $4, -16(%rdi, %rdx, CHAR_SIZE), %xmm2, %k1
|
||||||
|
- addl $(CHAR_PER_VEC - (16 / CHAR_SIZE)), %edx
|
||||||
|
- kmovd %k1, %eax
|
||||||
|
- testl %eax, %eax
|
||||||
|
- jnz L(return_vec_0_end)
|
||||||
|
- ret
|
||||||
|
-
|
||||||
|
-# ifndef USE_AS_WMEMCMP
|
||||||
|
-L(between_2_3):
|
||||||
|
- /* Load as big endian to avoid branches. */
|
||||||
|
- movzwl (%rdi), %eax
|
||||||
|
- movzwl (%rsi), %ecx
|
||||||
|
- shll $8, %eax
|
||||||
|
- shll $8, %ecx
|
||||||
|
- bswap %eax
|
||||||
|
- bswap %ecx
|
||||||
|
- movzbl -1(%rdi, %rdx), %edi
|
||||||
|
- movzbl -1(%rsi, %rdx), %esi
|
||||||
|
- orl %edi, %eax
|
||||||
|
- orl %esi, %ecx
|
||||||
|
- /* Subtraction is okay because the upper 8 bits are zero. */
|
||||||
|
- subl %ecx, %eax
|
||||||
|
- ret
|
||||||
|
-# endif
|
||||||
|
END (MEMCMP)
|
||||||
|
#endif
|
42
glibc-upstream-2.34-187.patch
Normal file
42
glibc-upstream-2.34-187.patch
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
commit 9681691402052b727e01ae3375c73e0f76566593
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Wed Apr 27 13:59:26 2022 -0300
|
||||||
|
|
||||||
|
linux: Fix missing internal 64 bit time_t stat usage
|
||||||
|
|
||||||
|
These are two missing spots initially done by 52a5fe70a2c77935.
|
||||||
|
|
||||||
|
Checked on i686-linux-gnu.
|
||||||
|
|
||||||
|
(cherry picked from commit 834ddd0432f68d6dc85b6aac95065721af0d86e9)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/faccessat.c b/sysdeps/unix/sysv/linux/faccessat.c
|
||||||
|
index 13160d32499c4e58..00e4ce7f80ee2dfe 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/faccessat.c
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/faccessat.c
|
||||||
|
@@ -39,8 +39,8 @@ __faccessat (int fd, const char *file, int mode, int flag)
|
||||||
|
if ((flag == 0 || ((flag & ~AT_EACCESS) == 0 && ! __libc_enable_secure)))
|
||||||
|
return INLINE_SYSCALL (faccessat, 3, fd, file, mode);
|
||||||
|
|
||||||
|
- struct stat64 stats;
|
||||||
|
- if (__fstatat64 (fd, file, &stats, flag & AT_SYMLINK_NOFOLLOW))
|
||||||
|
+ struct __stat64_t64 stats;
|
||||||
|
+ if (__fstatat64_time64 (fd, file, &stats, flag & AT_SYMLINK_NOFOLLOW))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
mode &= (X_OK | W_OK | R_OK); /* Clear any bogus bits. */
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/pathconf.c b/sysdeps/unix/sysv/linux/pathconf.c
|
||||||
|
index b599a66c930cad4d..f79930303118ebcd 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/pathconf.c
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/pathconf.c
|
||||||
|
@@ -110,8 +110,8 @@ distinguish_extX (const struct statfs *fsbuf, const char *file, int fd)
|
||||||
|
&& strcmp (mntbuf.mnt_type, "ext4") != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
- struct stat64 fsst;
|
||||||
|
- if (__stat64 (mntbuf.mnt_dir, &fsst) >= 0
|
||||||
|
+ struct __stat64_t64 fsst;
|
||||||
|
+ if (__stat64_time64 (mntbuf.mnt_dir, &fsst) >= 0
|
||||||
|
&& st.st_dev == fsst.st_dev)
|
||||||
|
{
|
||||||
|
if (strcmp (mntbuf.mnt_type, "ext4") == 0)
|
39
glibc-upstream-2.34-188.patch
Normal file
39
glibc-upstream-2.34-188.patch
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
commit 55640ed3fde48360a8e8083be4843bd2dc7cecfe
|
||||||
|
Author: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
Date: Tue Apr 26 10:52:41 2022 -0400
|
||||||
|
|
||||||
|
i386: Regenerate ulps
|
||||||
|
|
||||||
|
These failures were caught while building glibc master for Fedora
|
||||||
|
Rawhide which is built with '-mtune=generic -msse2 -mfpmath=sse'
|
||||||
|
using gcc 11.3 (gcc-11.3.1-2.fc35) on a Cascadelake Intel Xeon
|
||||||
|
processor.
|
||||||
|
|
||||||
|
(cherry picked from commit e465d97653311c3687aee49de782177353acfe86)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/i386/fpu/libm-test-ulps b/sysdeps/i386/fpu/libm-test-ulps
|
||||||
|
index 7601049110789201..84e6686eba5fe79a 100644
|
||||||
|
--- a/sysdeps/i386/fpu/libm-test-ulps
|
||||||
|
+++ b/sysdeps/i386/fpu/libm-test-ulps
|
||||||
|
@@ -668,7 +668,7 @@ ldouble: 4
|
||||||
|
|
||||||
|
Function: Imaginary part of "clog10":
|
||||||
|
double: 2
|
||||||
|
-float: 1
|
||||||
|
+float: 2
|
||||||
|
float128: 2
|
||||||
|
ldouble: 2
|
||||||
|
|
||||||
|
diff --git a/sysdeps/i386/i686/fpu/multiarch/libm-test-ulps b/sysdeps/i386/i686/fpu/multiarch/libm-test-ulps
|
||||||
|
index a39c89cec1141935..cc21e6907fe8b6a3 100644
|
||||||
|
--- a/sysdeps/i386/i686/fpu/multiarch/libm-test-ulps
|
||||||
|
+++ b/sysdeps/i386/i686/fpu/multiarch/libm-test-ulps
|
||||||
|
@@ -668,7 +668,7 @@ ldouble: 4
|
||||||
|
|
||||||
|
Function: Imaginary part of "clog10":
|
||||||
|
double: 2
|
||||||
|
-float: 1
|
||||||
|
+float: 2
|
||||||
|
float128: 2
|
||||||
|
ldouble: 2
|
||||||
|
|
116
glibc-upstream-2.34-189.patch
Normal file
116
glibc-upstream-2.34-189.patch
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
commit 88a8637cb4658cd91a002659db05867716b88b36
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Wed Apr 27 13:40:30 2022 -0300
|
||||||
|
|
||||||
|
linux: Fix fchmodat with AT_SYMLINK_NOFOLLOW for 64 bit time_t (BZ#29097)
|
||||||
|
|
||||||
|
The AT_SYMLINK_NOFOLLOW emulation ues the default 32 bit stat internal
|
||||||
|
calls, which fails with EOVERFLOW if the file constains timestamps
|
||||||
|
beyond 2038.
|
||||||
|
|
||||||
|
Checked on i686-linux-gnu.
|
||||||
|
|
||||||
|
(cherry picked from commit 118a2aee07f64d605b6668cbe195c1f44eac6be6)
|
||||||
|
|
||||||
|
diff --git a/io/Makefile b/io/Makefile
|
||||||
|
index 9871ecbc74020a6d..01968b81042e01e4 100644
|
||||||
|
--- a/io/Makefile
|
||||||
|
+++ b/io/Makefile
|
||||||
|
@@ -81,16 +81,17 @@ tests := test-utime test-stat test-stat2 test-lfs tst-getcwd \
|
||||||
|
tst-closefrom \
|
||||||
|
|
||||||
|
tests-time64 := \
|
||||||
|
+ tst-fcntl-time64 \
|
||||||
|
+ tst-fts-time64 \
|
||||||
|
tst-futimens-time64 \
|
||||||
|
tst-futimes-time64\
|
||||||
|
- tst-fts-time64 \
|
||||||
|
+ tst-futimesat-time64 \
|
||||||
|
+ tst-lchmod-time64 \
|
||||||
|
tst-lutimes-time64 \
|
||||||
|
tst-stat-time64 \
|
||||||
|
- tst-futimesat-time64 \
|
||||||
|
tst-utime-time64 \
|
||||||
|
tst-utimensat-time64 \
|
||||||
|
tst-utimes-time64 \
|
||||||
|
- tst-fcntl-time64 \
|
||||||
|
# tests-time64
|
||||||
|
|
||||||
|
# Likewise for statx, but we do not need static linking here.
|
||||||
|
@@ -134,6 +135,7 @@ CFLAGS-close.c += -fexceptions -fasynchronous-unwind-tables
|
||||||
|
|
||||||
|
CFLAGS-test-stat.c += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
|
||||||
|
CFLAGS-test-lfs.c += -D_LARGEFILE64_SOURCE
|
||||||
|
+CFLAGS-tst-lchmod.c += -D_FILE_OFFSET_BITS=64
|
||||||
|
|
||||||
|
test-stat2-ARGS = Makefile . $(objpfx)test-stat2
|
||||||
|
|
||||||
|
diff --git a/io/tst-lchmod-time64.c b/io/tst-lchmod-time64.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..f2b7cc9d358f2a77
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/io/tst-lchmod-time64.c
|
||||||
|
@@ -0,0 +1,2 @@
|
||||||
|
+#define CHECK_TIME64
|
||||||
|
+#include "tst-lchmod.c"
|
||||||
|
diff --git a/io/tst-lchmod.c b/io/tst-lchmod.c
|
||||||
|
index 0fe98e01b74b713d..472766b186975922 100644
|
||||||
|
--- a/io/tst-lchmod.c
|
||||||
|
+++ b/io/tst-lchmod.c
|
||||||
|
@@ -66,10 +66,27 @@ select_path (bool do_relative_path, const char *full_path, const char *relative_
|
||||||
|
return full_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void
|
||||||
|
+update_file_time_to_y2038 (const char *fname, int flags)
|
||||||
|
+{
|
||||||
|
+#ifdef CHECK_TIME64
|
||||||
|
+ /* Y2038 threshold plus 1 second. */
|
||||||
|
+ const struct timespec ts[] = { { 0x80000001LL, 0}, { 0x80000001LL } };
|
||||||
|
+ TEST_VERIFY_EXIT (utimensat (AT_FDCWD, fname, ts, flags) == 0);
|
||||||
|
+#endif
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void
|
||||||
|
test_1 (bool do_relative_path, int (*chmod_func) (int fd, const char *, mode_t, int))
|
||||||
|
{
|
||||||
|
char *tempdir = support_create_temp_directory ("tst-lchmod-");
|
||||||
|
+#ifdef CHECK_TIME64
|
||||||
|
+ if (!support_path_support_time64 (tempdir))
|
||||||
|
+ {
|
||||||
|
+ puts ("info: test skipped, filesystem does not support 64 bit time_t");
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
char *path_dangling = xasprintf ("%s/dangling", tempdir);
|
||||||
|
char *path_file = xasprintf ("%s/file", tempdir);
|
||||||
|
@@ -93,9 +110,12 @@ test_1 (bool do_relative_path, int (*chmod_func) (int fd, const char *, mode_t,
|
||||||
|
xsymlink ("loop", path_loop);
|
||||||
|
xsymlink ("target-does-not-exist", path_dangling);
|
||||||
|
|
||||||
|
+ update_file_time_to_y2038 (path_file, 0);
|
||||||
|
+ update_file_time_to_y2038 (path_to_file, AT_SYMLINK_NOFOLLOW);
|
||||||
|
+
|
||||||
|
/* Check that the modes do not collide with what we will use in the
|
||||||
|
test. */
|
||||||
|
- struct stat64 st;
|
||||||
|
+ struct stat st;
|
||||||
|
xstat (path_file, &st);
|
||||||
|
TEST_VERIFY ((st.st_mode & 0777) != 1);
|
||||||
|
xlstat (path_to_file, &st);
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/fchmodat.c b/sysdeps/unix/sysv/linux/fchmodat.c
|
||||||
|
index 5bd1eb96a5d78130..b0cf61949a9302d9 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/fchmodat.c
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/fchmodat.c
|
||||||
|
@@ -48,8 +48,8 @@ fchmodat (int fd, const char *file, mode_t mode, int flag)
|
||||||
|
|
||||||
|
/* Use fstatat because fstat does not work on O_PATH descriptors
|
||||||
|
before Linux 3.6. */
|
||||||
|
- struct stat64 st;
|
||||||
|
- if (__fstatat64 (pathfd, "", &st, AT_EMPTY_PATH) != 0)
|
||||||
|
+ struct __stat64_t64 st;
|
||||||
|
+ if (__fstatat64_time64 (pathfd, "", &st, AT_EMPTY_PATH) != 0)
|
||||||
|
{
|
||||||
|
__close_nocancel (pathfd);
|
||||||
|
return -1;
|
189
glibc-upstream-2.34-190.patch
Normal file
189
glibc-upstream-2.34-190.patch
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
commit c66c92181ddbd82306537a608e8c0282587131de
|
||||||
|
Author: DJ Delorie <dj@redhat.com>
|
||||||
|
Date: Wed Mar 30 17:44:02 2022 -0400
|
||||||
|
|
||||||
|
posix/glob.c: update from gnulib
|
||||||
|
|
||||||
|
Copied from gnulib/lib/glob.c in order to fix rhbz 1982608
|
||||||
|
Also fixes swbz 25659
|
||||||
|
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
Tested-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
(cherry picked from commit 7c477b57a31487eda516db02b9e04f22d1a6e6af)
|
||||||
|
|
||||||
|
diff --git a/posix/glob.c b/posix/glob.c
|
||||||
|
index 593a4c358f3d42e5..6af310a1aa31401a 100644
|
||||||
|
--- a/posix/glob.c
|
||||||
|
+++ b/posix/glob.c
|
||||||
|
@@ -21,13 +21,14 @@
|
||||||
|
optimizes away the pattern == NULL test below. */
|
||||||
|
# define _GL_ARG_NONNULL(params)
|
||||||
|
|
||||||
|
-# include <config.h>
|
||||||
|
+# include <libc-config.h>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <glob.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
+#include <fcntl.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
@@ -56,6 +57,8 @@
|
||||||
|
# define sysconf(id) __sysconf (id)
|
||||||
|
# define closedir(dir) __closedir (dir)
|
||||||
|
# define opendir(name) __opendir (name)
|
||||||
|
+# undef dirfd
|
||||||
|
+# define dirfd(str) __dirfd (str)
|
||||||
|
# define readdir(str) __readdir64 (str)
|
||||||
|
# define getpwnam_r(name, bufp, buf, len, res) \
|
||||||
|
__getpwnam_r (name, bufp, buf, len, res)
|
||||||
|
@@ -69,11 +72,8 @@
|
||||||
|
# ifndef GLOB_LSTAT
|
||||||
|
# define GLOB_LSTAT gl_lstat
|
||||||
|
# endif
|
||||||
|
-# ifndef GLOB_STAT64
|
||||||
|
-# define GLOB_STAT64 __stat64
|
||||||
|
-# endif
|
||||||
|
-# ifndef GLOB_LSTAT64
|
||||||
|
-# define GLOB_LSTAT64 __lstat64
|
||||||
|
+# ifndef GLOB_FSTATAT64
|
||||||
|
+# define GLOB_FSTATAT64 __fstatat64
|
||||||
|
# endif
|
||||||
|
# include <shlib-compat.h>
|
||||||
|
#else /* !_LIBC */
|
||||||
|
@@ -88,8 +88,7 @@
|
||||||
|
# define struct_stat struct stat
|
||||||
|
# define struct_stat64 struct stat
|
||||||
|
# define GLOB_LSTAT gl_lstat
|
||||||
|
-# define GLOB_STAT64 stat
|
||||||
|
-# define GLOB_LSTAT64 lstat
|
||||||
|
+# define GLOB_FSTATAT64 fstatat
|
||||||
|
#endif /* _LIBC */
|
||||||
|
|
||||||
|
#include <fnmatch.h>
|
||||||
|
@@ -215,7 +214,8 @@ glob_lstat (glob_t *pglob, int flags, const char *fullname)
|
||||||
|
} ust;
|
||||||
|
return (__glibc_unlikely (flags & GLOB_ALTDIRFUNC)
|
||||||
|
? pglob->GLOB_LSTAT (fullname, &ust.st)
|
||||||
|
- : GLOB_LSTAT64 (fullname, &ust.st64));
|
||||||
|
+ : GLOB_FSTATAT64 (AT_FDCWD, fullname, &ust.st64,
|
||||||
|
+ AT_SYMLINK_NOFOLLOW));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set *R = A + B. Return true if the answer is mathematically
|
||||||
|
@@ -257,7 +257,8 @@ is_dir (char const *filename, int flags, glob_t const *pglob)
|
||||||
|
struct_stat64 st64;
|
||||||
|
return (__glibc_unlikely (flags & GLOB_ALTDIRFUNC)
|
||||||
|
? pglob->gl_stat (filename, &st) == 0 && S_ISDIR (st.st_mode)
|
||||||
|
- : GLOB_STAT64 (filename, &st64) == 0 && S_ISDIR (st64.st_mode));
|
||||||
|
+ : (GLOB_FSTATAT64 (AT_FDCWD, filename, &st64, 0) == 0
|
||||||
|
+ && S_ISDIR (st64.st_mode)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find the end of the sub-pattern in a brace expression. */
|
||||||
|
@@ -747,6 +748,8 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifndef WINDOWS32
|
||||||
|
+ /* Recognize ~user as a shorthand for the specified user's home
|
||||||
|
+ directory. */
|
||||||
|
char *end_name = strchr (dirname, '/');
|
||||||
|
char *user_name;
|
||||||
|
int malloc_user_name = 0;
|
||||||
|
@@ -885,7 +888,22 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
|
||||||
|
}
|
||||||
|
scratch_buffer_free (&pwtmpbuf);
|
||||||
|
}
|
||||||
|
-#endif /* !WINDOWS32 */
|
||||||
|
+#else /* WINDOWS32 */
|
||||||
|
+ /* On native Windows, access to a user's home directory
|
||||||
|
+ (via GetUserProfileDirectory) or to a user's environment
|
||||||
|
+ variables (via ExpandEnvironmentStringsForUser) requires
|
||||||
|
+ the credentials of the user. Therefore we cannot support
|
||||||
|
+ the ~user syntax on this platform.
|
||||||
|
+ Handling ~user specially (and treat it like plain ~) if
|
||||||
|
+ user is getenv ("USERNAME") would not be a good idea,
|
||||||
|
+ since it would make people think that ~user is supported
|
||||||
|
+ in general. */
|
||||||
|
+ if (flags & GLOB_TILDE_CHECK)
|
||||||
|
+ {
|
||||||
|
+ retval = GLOB_NOMATCH;
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+#endif /* WINDOWS32 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1266,6 +1284,8 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
|
||||||
|
{
|
||||||
|
size_t dirlen = strlen (directory);
|
||||||
|
void *stream = NULL;
|
||||||
|
+ struct scratch_buffer s;
|
||||||
|
+ scratch_buffer_init (&s);
|
||||||
|
# define GLOBNAMES_MEMBERS(nnames) \
|
||||||
|
struct globnames *next; size_t count; char *name[nnames];
|
||||||
|
struct globnames { GLOBNAMES_MEMBERS (FLEXIBLE_ARRAY_MEMBER) };
|
||||||
|
@@ -1337,6 +1357,7 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
+ int dfd = dirfd (stream);
|
||||||
|
int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
|
||||||
|
| ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0));
|
||||||
|
flags |= GLOB_MAGCHAR;
|
||||||
|
@@ -1364,8 +1385,32 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
|
||||||
|
if (flags & GLOB_ONLYDIR)
|
||||||
|
switch (readdir_result_type (d))
|
||||||
|
{
|
||||||
|
- case DT_DIR: case DT_LNK: case DT_UNKNOWN: break;
|
||||||
|
default: continue;
|
||||||
|
+ case DT_DIR: break;
|
||||||
|
+ case DT_LNK: case DT_UNKNOWN:
|
||||||
|
+ /* The filesystem was too lazy to give us a hint,
|
||||||
|
+ so we have to do it the hard way. */
|
||||||
|
+ if (__glibc_unlikely (dfd < 0 || flags & GLOB_ALTDIRFUNC))
|
||||||
|
+ {
|
||||||
|
+ size_t namelen = strlen (d.name);
|
||||||
|
+ size_t need = dirlen + 1 + namelen + 1;
|
||||||
|
+ if (s.length < need
|
||||||
|
+ && !scratch_buffer_set_array_size (&s, need, 1))
|
||||||
|
+ goto memory_error;
|
||||||
|
+ char *p = mempcpy (s.data, directory, dirlen);
|
||||||
|
+ *p = '/';
|
||||||
|
+ p += p[-1] != '/';
|
||||||
|
+ memcpy (p, d.name, namelen + 1);
|
||||||
|
+ if (! is_dir (s.data, flags, pglob))
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ struct_stat64 st64;
|
||||||
|
+ if (! (GLOB_FSTATAT64 (dfd, d.name, &st64, 0) == 0
|
||||||
|
+ && S_ISDIR (st64.st_mode)))
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fnmatch (pattern, d.name, fnm_flags) == 0)
|
||||||
|
@@ -1497,5 +1542,6 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
|
||||||
|
__set_errno (save);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ scratch_buffer_free (&s);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/glob64-time64.c b/sysdeps/unix/sysv/linux/glob64-time64.c
|
||||||
|
index a465f70905e5a8a3..95efe4c4f4624967 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/glob64-time64.c
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/glob64-time64.c
|
||||||
|
@@ -37,6 +37,7 @@
|
||||||
|
# define GLOB_LSTAT gl_lstat
|
||||||
|
# define GLOB_STAT64 __stat64_time64
|
||||||
|
# define GLOB_LSTAT64 __lstat64_time64
|
||||||
|
+# define GLOB_FSTATAT64 __fstatat64_time64
|
||||||
|
|
||||||
|
# define COMPILE_GLOB64 1
|
||||||
|
|
136
glibc.spec
136
glibc.spec
@ -148,7 +148,7 @@ end \
|
|||||||
Summary: The GNU libc libraries
|
Summary: The GNU libc libraries
|
||||||
Name: glibc
|
Name: glibc
|
||||||
Version: %{glibcversion}
|
Version: %{glibcversion}
|
||||||
Release: 29%{?dist}
|
Release: 32%{?dist}
|
||||||
|
|
||||||
# In general, GPLv2+ is used by programs, LGPLv2+ is used for
|
# In general, GPLv2+ is used by programs, LGPLv2+ is used for
|
||||||
# libraries.
|
# libraries.
|
||||||
@ -379,17 +379,17 @@ Patch175: glibc-rh2058224-2.patch
|
|||||||
Patch176: glibc-rh2058230.patch
|
Patch176: glibc-rh2058230.patch
|
||||||
Patch177: glibc-rh2054789.patch
|
Patch177: glibc-rh2054789.patch
|
||||||
Patch178: glibc-upstream-2.34-108.patch
|
Patch178: glibc-upstream-2.34-108.patch
|
||||||
Patch179: glibc-upstream-2.34-110.patch
|
|
||||||
# glibc-2.34-109-gd64b08d5ba only changes NEWS.
|
# glibc-2.34-109-gd64b08d5ba only changes NEWS.
|
||||||
|
Patch179: glibc-upstream-2.34-110.patch
|
||||||
Patch180: glibc-upstream-2.34-111.patch
|
Patch180: glibc-upstream-2.34-111.patch
|
||||||
Patch181: glibc-upstream-2.34-112.patch
|
Patch181: glibc-upstream-2.34-112.patch
|
||||||
Patch182: glibc-upstream-2.34-113.patch
|
Patch182: glibc-upstream-2.34-113.patch
|
||||||
Patch183: glibc-upstream-2.34-114.patch
|
Patch183: glibc-upstream-2.34-114.patch
|
||||||
|
# glibc-2.34-115-gd5d1c95aaf only changes NEWS.
|
||||||
|
# glibc-2.34-116-g852361b5a3 is glibc-rh2054789.patch.
|
||||||
Patch184: glibc-upstream-2.34-117.patch
|
Patch184: glibc-upstream-2.34-117.patch
|
||||||
Patch185: glibc-upstream-2.34-118.patch
|
Patch185: glibc-upstream-2.34-118.patch
|
||||||
Patch186: glibc-upstream-2.34-119.patch
|
Patch186: glibc-upstream-2.34-119.patch
|
||||||
# glibc-2.34-115-gd5d1c95aaf only changes NEWS.
|
|
||||||
# glibc-2.34-116-g852361b5a3 is glibc-rh2054789.patch.
|
|
||||||
Patch187: glibc-upstream-2.34-120.patch
|
Patch187: glibc-upstream-2.34-120.patch
|
||||||
Patch188: glibc-upstream-2.34-121.patch
|
Patch188: glibc-upstream-2.34-121.patch
|
||||||
Patch189: glibc-upstream-2.34-122.patch
|
Patch189: glibc-upstream-2.34-122.patch
|
||||||
@ -403,6 +403,64 @@ Patch196: glibc-upstream-2.34-129.patch
|
|||||||
Patch197: glibc-upstream-2.34-130.patch
|
Patch197: glibc-upstream-2.34-130.patch
|
||||||
Patch198: glibc-upstream-2.34-131.patch
|
Patch198: glibc-upstream-2.34-131.patch
|
||||||
Patch199: glibc-upstream-2.34-132.patch
|
Patch199: glibc-upstream-2.34-132.patch
|
||||||
|
Patch200: glibc-upstream-2.34-133.patch
|
||||||
|
Patch201: glibc-upstream-2.34-134.patch
|
||||||
|
Patch202: glibc-upstream-2.34-135.patch
|
||||||
|
Patch203: glibc-upstream-2.34-136.patch
|
||||||
|
Patch204: glibc-upstream-2.34-137.patch
|
||||||
|
Patch205: glibc-upstream-2.34-138.patch
|
||||||
|
Patch206: glibc-upstream-2.34-139.patch
|
||||||
|
Patch207: glibc-upstream-2.34-140.patch
|
||||||
|
Patch208: glibc-upstream-2.34-141.patch
|
||||||
|
Patch209: glibc-upstream-2.34-142.patch
|
||||||
|
Patch210: glibc-upstream-2.34-143.patch
|
||||||
|
Patch211: glibc-upstream-2.34-144.patch
|
||||||
|
Patch212: glibc-upstream-2.34-145.patch
|
||||||
|
Patch213: glibc-upstream-2.34-146.patch
|
||||||
|
Patch214: glibc-upstream-2.34-147.patch
|
||||||
|
Patch215: glibc-upstream-2.34-148.patch
|
||||||
|
Patch216: glibc-upstream-2.34-149.patch
|
||||||
|
Patch217: glibc-upstream-2.34-150.patch
|
||||||
|
Patch218: glibc-upstream-2.34-151.patch
|
||||||
|
Patch219: glibc-upstream-2.34-152.patch
|
||||||
|
Patch220: glibc-upstream-2.34-153.patch
|
||||||
|
Patch221: glibc-upstream-2.34-154.patch
|
||||||
|
Patch222: glibc-upstream-2.34-155.patch
|
||||||
|
Patch223: glibc-upstream-2.34-156.patch
|
||||||
|
Patch224: glibc-upstream-2.34-157.patch
|
||||||
|
Patch225: glibc-upstream-2.34-158.patch
|
||||||
|
Patch226: glibc-upstream-2.34-159.patch
|
||||||
|
Patch227: glibc-upstream-2.34-160.patch
|
||||||
|
# glibc-2.34-161-gceed89d089 only changes NEWS.
|
||||||
|
Patch228: glibc-upstream-2.34-162.patch
|
||||||
|
Patch229: glibc-upstream-2.34-163.patch
|
||||||
|
Patch230: glibc-upstream-2.34-164.patch
|
||||||
|
Patch231: glibc-upstream-2.34-165.patch
|
||||||
|
Patch232: glibc-upstream-2.34-166.patch
|
||||||
|
Patch233: glibc-upstream-2.34-167.patch
|
||||||
|
Patch234: glibc-upstream-2.34-168.patch
|
||||||
|
Patch235: glibc-upstream-2.34-169.patch
|
||||||
|
Patch236: glibc-upstream-2.34-170.patch
|
||||||
|
Patch237: glibc-upstream-2.34-171.patch
|
||||||
|
Patch238: glibc-upstream-2.34-172.patch
|
||||||
|
Patch239: glibc-upstream-2.34-173.patch
|
||||||
|
Patch240: glibc-upstream-2.34-174.patch
|
||||||
|
Patch241: glibc-upstream-2.34-175.patch
|
||||||
|
Patch242: glibc-upstream-2.34-176.patch
|
||||||
|
Patch243: glibc-upstream-2.34-177.patch
|
||||||
|
Patch244: glibc-upstream-2.34-178.patch
|
||||||
|
Patch245: glibc-upstream-2.34-179.patch
|
||||||
|
Patch246: glibc-upstream-2.34-180.patch
|
||||||
|
Patch247: glibc-upstream-2.34-181.patch
|
||||||
|
Patch248: glibc-upstream-2.34-182.patch
|
||||||
|
Patch249: glibc-upstream-2.34-183.patch
|
||||||
|
Patch250: glibc-upstream-2.34-184.patch
|
||||||
|
Patch251: glibc-upstream-2.34-185.patch
|
||||||
|
Patch252: glibc-upstream-2.34-186.patch
|
||||||
|
Patch253: glibc-upstream-2.34-187.patch
|
||||||
|
Patch254: glibc-upstream-2.34-188.patch
|
||||||
|
Patch255: glibc-upstream-2.34-189.patch
|
||||||
|
Patch256: glibc-upstream-2.34-190.patch
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# Continued list of core "glibc" package information:
|
# Continued list of core "glibc" package information:
|
||||||
@ -2459,6 +2517,76 @@ fi
|
|||||||
%files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared
|
%files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu Apr 28 2022 Carlos O'Donell <carlos@redhat.com> - 2.34-32
|
||||||
|
- Sync with upstream branch release/2.34/master,
|
||||||
|
commit c66c92181ddbd82306537a608e8c0282587131de:
|
||||||
|
- posix/glob.c: update from gnulib (BZ#25659)
|
||||||
|
- linux: Fix fchmodat with AT_SYMLINK_NOFOLLOW for 64 bit time_t (BZ#29097)
|
||||||
|
|
||||||
|
* Wed Apr 27 2022 Carlos O'Donell <carlos@redhat.com> - 2.34-31
|
||||||
|
- Sync with upstream branch release/2.34/master,
|
||||||
|
commit 55640ed3fde48360a8e8083be4843bd2dc7cecfe:
|
||||||
|
- i386: Regenerate ulps
|
||||||
|
- linux: Fix missing internal 64 bit time_t stat usage
|
||||||
|
- x86: Optimize L(less_vec) case in memcmp-evex-movbe.S
|
||||||
|
- x86: Don't set Prefer_No_AVX512 for processors with AVX512 and AVX-VNNI
|
||||||
|
- x86-64: Use notl in EVEX strcmp [BZ #28646]
|
||||||
|
- x86: Shrink memcmp-sse4.S code size
|
||||||
|
- x86: Double size of ERMS rep_movsb_threshold in dl-cacheinfo.h
|
||||||
|
- x86: Optimize memmove-vec-unaligned-erms.S
|
||||||
|
- x86-64: Replace movzx with movzbl
|
||||||
|
- x86-64: Remove Prefer_AVX2_STRCMP
|
||||||
|
- x86-64: Improve EVEX strcmp with masked load
|
||||||
|
- x86: Replace sse2 instructions with avx in memcmp-evex-movbe.S
|
||||||
|
- x86: Optimize memset-vec-unaligned-erms.S
|
||||||
|
- x86: Optimize memcmp-evex-movbe.S for frontend behavior and size
|
||||||
|
- x86: Modify ENTRY in sysdep.h so that p2align can be specified
|
||||||
|
- x86-64: Optimize load of all bits set into ZMM register [BZ #28252]
|
||||||
|
- scripts/glibcelf.py: Mark as UNSUPPORTED on Python 3.5 and earlier
|
||||||
|
- dlfcn: Do not use rtld_active () to determine ld.so state (bug 29078)
|
||||||
|
- INSTALL: Rephrase -with-default-link documentation
|
||||||
|
- misc: Fix rare fortify crash on wchar funcs. [BZ 29030]
|
||||||
|
- Default to --with-default-link=no (bug 25812)
|
||||||
|
- scripts: Add glibcelf.py module
|
||||||
|
|
||||||
|
* Thu Apr 21 2022 Carlos O'Donell <carlos@redhat.com> - 2.34-30
|
||||||
|
- Sync with upstream branch release/2.34/master,
|
||||||
|
commit 71326f1f2fd09dafb9c34404765fb88129e94237:
|
||||||
|
- nptl: Fix pthread_cancel cancelhandling atomic operations
|
||||||
|
- mips: Fix mips64n32 64 bit time_t stat support (BZ#29069)
|
||||||
|
- hurd: Fix arbitrary error code
|
||||||
|
- nptl: Handle spurious EINTR when thread cancellation is disabled (BZ#29029)
|
||||||
|
- S390: Add new s390 platform z16.
|
||||||
|
- NEWS: Update fixed bug list for LD_AUDIT backports.
|
||||||
|
- hppa: Fix bind-now audit (BZ #28857)
|
||||||
|
- elf: Replace tst-audit24bmod2.so with tst-audit24bmod2
|
||||||
|
- Fix elf/tst-audit25a with default bind now toolchains
|
||||||
|
- elf: Fix runtime linker auditing on aarch64 (BZ #26643)
|
||||||
|
- elf: Issue la_symbind for bind-now (BZ #23734)
|
||||||
|
- elf: Fix initial-exec TLS access on audit modules (BZ #28096)
|
||||||
|
- elf: Add la_activity during application exit
|
||||||
|
- elf: Do not fail for failed dlmopen on audit modules (BZ #28061)
|
||||||
|
- elf: Issue audit la_objopen for vDSO
|
||||||
|
- elf: Add audit tests for modules with TLSDESC
|
||||||
|
- elf: Avoid unnecessary slowdown from profiling with audit (BZ#15533)
|
||||||
|
- elf: Add _dl_audit_pltexit
|
||||||
|
- elf: Add _dl_audit_pltenter
|
||||||
|
- elf: Add _dl_audit_preinit
|
||||||
|
- elf: Add _dl_audit_symbind_alt and _dl_audit_symbind
|
||||||
|
- elf: Add _dl_audit_objclose
|
||||||
|
- elf: Add _dl_audit_objsearch
|
||||||
|
- elf: Add _dl_audit_activity_map and _dl_audit_activity_nsid
|
||||||
|
- elf: Add _dl_audit_objopen
|
||||||
|
- elf: Move la_activity (LA_ACT_ADD) after _dl_add_to_namespace_list() (BZ #28062)
|
||||||
|
- elf: Move LAV_CURRENT to link_lavcurrent.h
|
||||||
|
- elf: Fix elf_get_dynamic_info() for bootstrap
|
||||||
|
- elf: Fix dynamic-link.h usage on rtld.c
|
||||||
|
- elf: Fix elf_get_dynamic_info definition
|
||||||
|
- elf: Avoid nested functions in the loader [BZ #27220]
|
||||||
|
- powerpc: Delete unneeded ELF_MACHINE_BEFORE_RTLD_RELOC
|
||||||
|
- hppa: Use END instead of PSEUDO_END in swapcontext.S
|
||||||
|
- hppa: Implement swapcontext in assembler (bug 28960)
|
||||||
|
|
||||||
* Tue Mar 15 2022 Florian Weimer <fweimer@redhat.com> - 2.34-29
|
* Tue Mar 15 2022 Florian Weimer <fweimer@redhat.com> - 2.34-29
|
||||||
- Sync with upstream branch release/2.34/master,
|
- Sync with upstream branch release/2.34/master,
|
||||||
commit 224d8c1890b6c57c7e4e8ddbb792dd9552086704:
|
commit 224d8c1890b6c57c7e4e8ddbb792dd9552086704:
|
||||||
|
Loading…
Reference in New Issue
Block a user