Accepting request 1286665 from Base:System

- ppc64le-revert-power10-strcmp.patch: Revert optimized POWER10 strcmp,
  strncmp implementations (CVE-2025-5745, CVE-2025-5702, bsc#1244184,
  bsc#1244182, BZ #33060, BZ #33056)
- ppc64le-revert-power10-memcmp.patch: Revert optimized POWER10 memcmp
  implementation (BZ #33059) (forwarded request 1286664 from Andreas_Schwab)

OBS-URL: https://build.opensuse.org/request/show/1286665
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/glibc?expand=0&rev=299
This commit is contained in:
2025-06-24 18:45:10 +00:00
committed by Git OBS Bridge
5 changed files with 1297 additions and 51 deletions

View File

@@ -1,3 +1,24 @@
-------------------------------------------------------------------
Tue Jun 17 09:11:26 UTC 2025 - Andreas Schwab <schwab@suse.de>
- ppc64le-revert-power10-strcmp.patch: Revert optimized POWER10 strcmp,
strncmp implementations (CVE-2025-5745, CVE-2025-5702, bsc#1244184,
bsc#1244182, BZ #33060, BZ #33056)
- ppc64le-revert-power10-memcmp.patch: Revert optimized POWER10 memcmp
implementation (BZ #33059)
-------------------------------------------------------------------
Mon Jun 2 10:54:37 UTC 2025 - Andreas Schwab <schwab@suse.de>
- Filter GLIBC_PRIVATE symbols again
- Drop ngpt provides
- Refine libc_nonshared.a workaround
-------------------------------------------------------------------
Fri Apr 18 19:50:23 UTC 2025 - Giuliano Belinassi <giuliano.belinassi@suse.com>
- Enable Userspace Livepatching on ppc64le (jsc#PED-7395)
-------------------------------------------------------------------
Wed Mar 12 10:28:15 UTC 2025 - Andreas Schwab <schwab@suse.de>
@@ -319,6 +340,7 @@ Thu Feb 1 09:25:37 UTC 2024 - Andreas Schwab <schwab@suse.de>
sem-open-o-creat.patch, setxid-propagate-glibc-tunables.patch,
syslog-buffer-overflow.patch, tls-modid-reuse.patch,
tunables-string-parsing.patch: Removed
- CVE-2025-4802
-------------------------------------------------------------------
Wed Jan 31 09:25:16 UTC 2024 - Andreas Schwab <schwab@suse.de>

View File

@@ -111,11 +111,11 @@ ExclusiveArch: do_not_build
# Enable support for livepatching.
%define have_livepatching_support 0
%if %{build_cross}
%if "%{cross_arch}" == "x86_64"
%if "%{cross_arch}" == "x86_64" || "%{cross_arch}" == "ppc64le"
%define have_livepatching_support 1
%endif
%else
%ifarch x86_64
%ifarch x86_64 ppc64le
%define have_livepatching_support 1
%endif
%endif
@@ -138,7 +138,9 @@ ExclusiveArch: do_not_build
%define name_suffix -%{flavor}-src
%endif
%define __filter_GLIBC_PRIVATE 1
# Nothing outside of glibc must use these symbols
%define __requires_exclude GLIBC_PRIVATE
%define __provides_exclude GLIBC_PRIVATE
%ifarch i686
# For i686 let's only build what's different from i586, so
# no need to build documentation
@@ -211,11 +213,6 @@ Source21: nscd.service
Source22: nscd.sysusers
%if %{build_main}
# ngpt was used in 8.1 and SLES8
Obsoletes: ngpt < 2.2.2
Obsoletes: ngpt-devel < 2.2.2
Provides: ngpt = 2.2.2
Provides: ngpt-devel = 2.2.2
%if %{without nscd}
Obsoletes: nscd <= %{version}
%endif
@@ -351,6 +348,10 @@ Patch1003: round-tanf.patch
Patch1004: tst-aarch64-pkey.patch
# PATCH-FIX-UPSTREAM x86 (__HAVE_FLOAT128): Defined to 0 for Intel SYCL compiler (BZ #32723)
Patch1005: float128-sycl.patch
# PATCH-FIX-UPSTREAM Revert optimized POWER10 strcmp, strncmp implementations (CVE-2025-5745, CVE-2025-5702, BZ #33060, BZ #33056)
Patch1006: ppc64le-revert-power10-strcmp.patch
# PATCH-FIX-UPSTREAM Revert optimized POWER10 memcmp (BZ #33059)
Patch1007: ppc64le-revert-power10-memcmp.patch
###
%endif
@@ -794,12 +795,13 @@ archsub=powerpc
%endif
xstatbuild ()
{
gcc -O2 -I ../sysdeps/unix/sysv/linux/$archsub -xc - -c -o $1stat$2.oS <<EOF
gcc -O2 -fpic -I ../sysdeps/unix/sysv/linux/$archsub -xc - -c -o $1stat$2.oS <<EOF
#include <bits/wordsize.h>
#include <xstatver.h>
int __$1xstat$2 (int, $3, void *);
int
__attribute__ ((visibility ("hidden")))
$1stat$2 ($3 file, void *buf)
{
return __$1xstat$2 (_STAT_VER, file, buf);

View File

@@ -0,0 +1,417 @@
Index: glibc-2.41/sysdeps/powerpc/powerpc64/le/power10/memchr.S
===================================================================
--- glibc-2.41.orig/sysdeps/powerpc/powerpc64/le/power10/memchr.S
+++ /dev/null
@@ -1,315 +0,0 @@
-/* Optimized memchr implementation for POWER10 LE.
- Copyright (C) 2021-2025 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <https://www.gnu.org/licenses/>. */
-
-#include <sysdep.h>
-
-# ifndef MEMCHR
-# define MEMCHR __memchr
-# endif
-# define M_VREG_ZERO v20
-# define M_OFF_START_LOOP 256
-# define MEMCHR_SUBTRACT_VECTORS \
- vsububm v4,v4,v18; \
- vsububm v5,v5,v18; \
- vsububm v6,v6,v18; \
- vsububm v7,v7,v18;
-# define M_TAIL(vreg,increment) \
- vctzlsbb r4,vreg; \
- cmpld r5,r4; \
- ble L(null); \
- addi r4,r4,increment; \
- add r3,r6,r4; \
- blr
-
-/* TODO: Replace macros by the actual instructions when minimum binutils becomes
- >= 2.35. This is used to keep compatibility with older versions. */
-#define M_VEXTRACTBM(rt,vrb) \
- .long(((4)<<(32-6)) \
- | ((rt)<<(32-11)) \
- | ((8)<<(32-16)) \
- | ((vrb)<<(32-21)) \
- | 1602)
-
-#define M_LXVP(xtp,dq,ra) \
- .long(((6)<<(32-6)) \
- | ((((xtp)-32)>>1)<<(32-10)) \
- | ((1)<<(32-11)) \
- | ((ra)<<(32-16)) \
- | dq)
-
-#define CHECK16B(vreg,offset,addr,label) \
- lxv vreg+32,offset(addr); \
- vcmpequb. vreg,vreg,v18; \
- bne cr6,L(label); \
- cmpldi r5,16; \
- ble L(null); \
- addi r5,r5,-16;
-
-/* Load 4 quadwords, merge into one VR for speed and check for NULLs. r6 has #
- of bytes already checked. */
-#define CHECK64B(offset,addr,label) \
- M_LXVP(v4+32,offset,addr); \
- M_LXVP(v6+32,offset+32,addr); \
- MEMCHR_SUBTRACT_VECTORS; \
- vminub v14,v4,v5; \
- vminub v15,v6,v7; \
- vminub v16,v14,v15; \
- vcmpequb. v0,v16,M_VREG_ZERO; \
- beq cr6,$+12; \
- li r7,offset; \
- b L(label); \
- cmpldi r5,64; \
- ble L(null); \
- addi r5,r5,-64
-
-/* Implements the function
- void *[r3] memchr (const void *s [r3], int c [r4], size_t n [r5]). */
-
- .machine power9
-
-ENTRY_TOCLESS (MEMCHR)
- CALL_MCOUNT 3
-
- cmpldi r5,0
- beq L(null)
- mr r0,r5
- xori r6,r4,0xff
-
- mtvsrd v18+32,r4 /* matching char in v18 */
- mtvsrd v19+32,r6 /* non matching char in v19 */
-
- vspltb v18,v18,7 /* replicate */
- vspltb v19,v19,7 /* replicate */
- vspltisb M_VREG_ZERO,0
-
- /* Next 16B-aligned address. Prepare address for L(aligned). */
- addi r6,r3,16
- clrrdi r6,r6,4
-
- /* Align data and fill bytes not loaded with non matching char. */
- lvx v0,0,r3
- lvsr v1,0,r3
- vperm v0,v19,v0,v1
-
- vcmpequb. v6,v0,v18
- bne cr6,L(found)
- sub r4,r6,r3
- cmpld r5,r4
- ble L(null)
- sub r5,r5,r4
-
- /* Test up to OFF_START_LOOP-16 bytes in 16B chunks. The main loop is
- optimized for longer strings, so checking the first bytes in 16B
- chunks benefits a lot small strings. */
- .p2align 5
-L(aligned):
- cmpldi r5,0
- beq L(null)
-
- CHECK16B(v0,0,r6,tail1)
- CHECK16B(v1,16,r6,tail2)
- CHECK16B(v2,32,r6,tail3)
- CHECK16B(v3,48,r6,tail4)
- CHECK16B(v4,64,r6,tail5)
- CHECK16B(v5,80,r6,tail6)
- CHECK16B(v6,96,r6,tail7)
- CHECK16B(v7,112,r6,tail8)
- CHECK16B(v8,128,r6,tail9)
- CHECK16B(v9,144,r6,tail10)
- CHECK16B(v10,160,r6,tail11)
- CHECK16B(v0,176,r6,tail12)
- CHECK16B(v1,192,r6,tail13)
- CHECK16B(v2,208,r6,tail14)
- CHECK16B(v3,224,r6,tail15)
-
- cmpdi cr5,r4,0 /* Check if c == 0. This will be useful to
- choose how we will perform the main loop. */
-
- /* Prepare address for the loop. */
- addi r4,r3,M_OFF_START_LOOP
- clrrdi r4,r4,6
- sub r6,r4,r3
- sub r5,r0,r6
- addi r6,r4,128
-
- /* If c == 0, use the loop without the vsububm. */
- beq cr5,L(loop)
-
- /* This is very similar to the block after L(loop), the difference is
- that here MEMCHR_SUBTRACT_VECTORS is not empty, and we subtract
- each byte loaded by the char we are looking for, this way we can keep
- using vminub to merge the results and checking for nulls. */
- .p2align 5
-L(memchr_loop):
- CHECK64B(0,r4,pre_tail_64b)
- CHECK64B(64,r4,pre_tail_64b)
- addi r4,r4,256
-
- CHECK64B(0,r6,tail_64b)
- CHECK64B(64,r6,tail_64b)
- addi r6,r6,256
-
- CHECK64B(0,r4,pre_tail_64b)
- CHECK64B(64,r4,pre_tail_64b)
- addi r4,r4,256
-
- CHECK64B(0,r6,tail_64b)
- CHECK64B(64,r6,tail_64b)
- addi r6,r6,256
-
- b L(memchr_loop)
- /* Switch to a more aggressive approach checking 64B each time. Use 2
- pointers 128B apart and unroll the loop once to make the pointer
- updates and usages separated enough to avoid stalls waiting for
- address calculation. */
- .p2align 5
-L(loop):
-#undef MEMCHR_SUBTRACT_VECTORS
-#define MEMCHR_SUBTRACT_VECTORS /* nothing */
- CHECK64B(0,r4,pre_tail_64b)
- CHECK64B(64,r4,pre_tail_64b)
- addi r4,r4,256
-
- CHECK64B(0,r6,tail_64b)
- CHECK64B(64,r6,tail_64b)
- addi r6,r6,256
-
- CHECK64B(0,r4,pre_tail_64b)
- CHECK64B(64,r4,pre_tail_64b)
- addi r4,r4,256
-
- CHECK64B(0,r6,tail_64b)
- CHECK64B(64,r6,tail_64b)
- addi r6,r6,256
-
- b L(loop)
-
- .p2align 5
-L(pre_tail_64b):
- mr r6,r4
-L(tail_64b):
- /* OK, we found a null byte. Let's look for it in the current 64-byte
- block and mark it in its corresponding VR. lxvp vx,0(ry) puts the
- low 16B bytes into vx+1, and the high into vx, so the order here is
- v5, v4, v7, v6. */
- vcmpequb v1,v5,M_VREG_ZERO
- vcmpequb v2,v4,M_VREG_ZERO
- vcmpequb v3,v7,M_VREG_ZERO
- vcmpequb v4,v6,M_VREG_ZERO
-
- /* Take into account the other 64B blocks we had already checked. */
- add r6,r6,r7
- /* Extract first bit of each byte. */
- M_VEXTRACTBM(r8,v1)
- M_VEXTRACTBM(r9,v2)
- M_VEXTRACTBM(r10,v3)
- M_VEXTRACTBM(r11,v4)
-
- /* Shift each value into their corresponding position. */
- sldi r9,r9,16
- sldi r10,r10,32
- sldi r11,r11,48
-
- /* Merge the results. */
- or r8,r8,r9
- or r9,r10,r11
- or r11,r9,r8
-
- cnttzd r0,r11 /* Count trailing zeros before the match. */
- cmpld r5,r0
- ble L(null)
- add r3,r6,r0 /* Compute final address. */
- blr
-
- .p2align 5
-L(tail1):
- M_TAIL(v0,0)
-
- .p2align 5
-L(tail2):
- M_TAIL(v1,16)
-
- .p2align 5
-L(tail3):
- M_TAIL(v2,32)
-
- .p2align 5
-L(tail4):
- M_TAIL(v3,48)
-
- .p2align 5
-L(tail5):
- M_TAIL(v4,64)
-
- .p2align 5
-L(tail6):
- M_TAIL(v5,80)
-
- .p2align 5
-L(tail7):
- M_TAIL(v6,96)
-
- .p2align 5
-L(tail8):
- M_TAIL(v7,112)
-
- .p2align 5
-L(tail9):
- M_TAIL(v8,128)
-
- .p2align 5
-L(tail10):
- M_TAIL(v9,144)
-
- .p2align 5
-L(tail11):
- M_TAIL(v10,160)
-
- .p2align 5
-L(tail12):
- M_TAIL(v0,176)
-
- .p2align 5
-L(tail13):
- M_TAIL(v1,192)
-
- .p2align 5
-L(tail14):
- M_TAIL(v2,208)
-
- .p2align 5
-L(tail15):
- M_TAIL(v3,224)
-
- .p2align 5
-L(found):
- vctzlsbb r7,v6
- cmpld r5,r7
- ble L(null)
- add r3,r3,r7
- blr
-
- .p2align 5
-L(null):
- li r3,0
- blr
-
-END (MEMCHR)
-
-weak_alias (__memchr, memchr)
-libc_hidden_builtin_def (memchr)
Index: glibc-2.41/sysdeps/powerpc/powerpc64/multiarch/Makefile
===================================================================
--- glibc-2.41.orig/sysdeps/powerpc/powerpc64/multiarch/Makefile
+++ glibc-2.41/sysdeps/powerpc/powerpc64/multiarch/Makefile
@@ -31,7 +31,7 @@ sysdep_routines += memcpy-power8-cached
strncase-power8
ifneq (,$(filter %le,$(config-machine)))
-sysdep_routines += memchr-power10 memcmp-power10 memcpy-power10 \
+sysdep_routines += memcmp-power10 memcpy-power10 \
memmove-power10 memset-power10 rawmemchr-power9 \
rawmemchr-power10 strcmp-power9 \
strncmp-power9 strcpy-power9 strcat-power10 \
Index: glibc-2.41/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
===================================================================
--- glibc-2.41.orig/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+++ glibc-2.41/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
@@ -226,12 +226,6 @@ __libc_ifunc_impl_list (const char *name
/* Support sysdeps/powerpc/powerpc64/multiarch/memchr.c. */
IFUNC_IMPL (i, name, memchr,
-#ifdef __LITTLE_ENDIAN__
- IFUNC_IMPL_ADD (array, i, memchr,
- hwcap2 & PPC_FEATURE2_ARCH_3_1
- && hwcap & PPC_FEATURE_HAS_VSX,
- __memchr_power10)
-#endif
IFUNC_IMPL_ADD (array, i, memchr,
hwcap2 & PPC_FEATURE2_ARCH_2_07
&& hwcap & PPC_FEATURE_HAS_ALTIVEC,
Index: glibc-2.41/sysdeps/powerpc/powerpc64/multiarch/memchr-power10.S
===================================================================
--- glibc-2.41.orig/sysdeps/powerpc/powerpc64/multiarch/memchr-power10.S
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Optimized memchr implementation for POWER10/PPC64.
- Copyright (C) 2016-2025 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <https://www.gnu.org/licenses/>. */
-
-#if defined __LITTLE_ENDIAN__ && IS_IN (libc)
-#define MEMCHR __memchr_power10
-
-#undef libc_hidden_builtin_def
-#define libc_hidden_builtin_def(name)
-#undef weak_alias
-#define weak_alias(name,alias)
-
-#include <sysdeps/powerpc/powerpc64/le/power10/memchr.S>
-#endif
Index: glibc-2.41/sysdeps/powerpc/powerpc64/multiarch/memchr.c
===================================================================
--- glibc-2.41.orig/sysdeps/powerpc/powerpc64/multiarch/memchr.c
+++ glibc-2.41/sysdeps/powerpc/powerpc64/multiarch/memchr.c
@@ -25,23 +25,15 @@ extern __typeof (__memchr) __memchr_ppc
extern __typeof (__memchr) __memchr_power7 attribute_hidden;
extern __typeof (__memchr) __memchr_power8 attribute_hidden;
-# ifdef __LITTLE_ENDIAN__
-extern __typeof (__memchr) __memchr_power10 attribute_hidden;
-# endif
/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
ifunc symbol properly. */
libc_ifunc (__memchr,
-# ifdef __LITTLE_ENDIAN__
- (hwcap2 & PPC_FEATURE2_ARCH_3_1
- && hwcap & PPC_FEATURE_HAS_VSX)
- ? __memchr_power10 :
-# endif
- (hwcap2 & PPC_FEATURE2_ARCH_2_07
- && hwcap & PPC_FEATURE_HAS_ALTIVEC)
- ? __memchr_power8 :
- (hwcap & PPC_FEATURE_ARCH_2_06)
- ? __memchr_power7
- : __memchr_ppc);
+ (hwcap2 & PPC_FEATURE2_ARCH_2_07
+ && hwcap & PPC_FEATURE_HAS_ALTIVEC)
+ ? __memchr_power8 :
+ (hwcap & PPC_FEATURE_ARCH_2_06)
+ ? __memchr_power7
+ : __memchr_ppc);
weak_alias (__memchr, memchr)
libc_hidden_builtin_def (memchr)

View File

@@ -0,0 +1,658 @@
Index: glibc-2.41/sysdeps/powerpc/powerpc64/le/power10/strcmp.S
===================================================================
--- glibc-2.41.orig/sysdeps/powerpc/powerpc64/le/power10/strcmp.S
+++ /dev/null
@@ -1,233 +0,0 @@
-/* Optimized strcmp implementation for PowerPC64/POWER10.
- Copyright (C) 2021-2025 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <https://www.gnu.org/licenses/>. */
-#include <sysdep.h>
-
-#ifndef STRCMP
-# define STRCMP strcmp
-#endif
-
-/* Implements the function
- int [r3] strcmp (const char *s1 [r3], const char *s2 [r4]). */
-
-/* TODO: Change this to actual instructions when minimum binutils is upgraded
- to 2.27. Macros are defined below for these newer instructions in order
- to maintain compatibility. */
-
-#define LXVP(xtp,dq,ra) \
- .long(((6)<<(32-6)) \
- | ((((xtp)-32)>>1)<<(32-10)) \
- | ((1)<<(32-11)) \
- | ((ra)<<(32-16)) \
- | dq)
-
-#define COMPARE_16(vreg1,vreg2,offset) \
- lxv vreg1+32,offset(r3); \
- lxv vreg2+32,offset(r4); \
- vcmpnezb. v7,vreg1,vreg2; \
- bne cr6,L(different); \
-
-#define COMPARE_32(vreg1,vreg2,offset,label1,label2) \
- LXVP(vreg1+32,offset,r3); \
- LXVP(vreg2+32,offset,r4); \
- vcmpnezb. v7,vreg1+1,vreg2+1; \
- bne cr6,L(label1); \
- vcmpnezb. v7,vreg1,vreg2; \
- bne cr6,L(label2); \
-
-#define TAIL(vreg1,vreg2) \
- vctzlsbb r6,v7; \
- vextubrx r5,r6,vreg1; \
- vextubrx r4,r6,vreg2; \
- subf r3,r4,r5; \
- blr; \
-
-#define CHECK_N_BYTES(reg1,reg2,len_reg) \
- sldi r0,len_reg,56; \
- lxvl 32+v4,reg1,r0; \
- lxvl 32+v5,reg2,r0; \
- add reg1,reg1,len_reg; \
- add reg2,reg2,len_reg; \
- vcmpnezb v7,v4,v5; \
- vctzlsbb r6,v7; \
- cmpld cr7,r6,len_reg; \
- blt cr7,L(different); \
-
- /* TODO: change this to .machine power10 when the minimum required
- binutils allows it. */
-
- .machine power9
-ENTRY_TOCLESS (STRCMP, 4)
- andi. r7,r3,4095
- andi. r8,r4,4095
- cmpldi cr0,r7,4096-16
- cmpldi cr1,r8,4096-16
- bgt cr0,L(crosses)
- bgt cr1,L(crosses)
- COMPARE_16(v4,v5,0)
-
-L(crosses):
- andi. r7,r3,15
- subfic r7,r7,16 /* r7(nalign1) = 16 - (str1 & 15). */
- andi. r9,r4,15
- subfic r5,r9,16 /* r5(nalign2) = 16 - (str2 & 15). */
- cmpld cr7,r7,r5
- beq cr7,L(same_aligned)
- blt cr7,L(nalign1_min)
-
- /* nalign2 is minimum and s2 pointer is aligned. */
- CHECK_N_BYTES(r3,r4,r5)
- /* Are we on the 64B hunk which crosses a page? */
- andi. r10,r3,63 /* Determine offset into 64B hunk. */
- andi. r8,r3,15 /* The offset into the 16B hunk. */
- neg r7,r3
- andi. r9,r7,15 /* Number of bytes after a 16B cross. */
- rlwinm. r7,r7,26,0x3F /* ((r3-4096))>>6&63. */
- beq L(compare_64_pagecross)
- mtctr r7
- b L(compare_64B_unaligned)
-
- /* nalign1 is minimum and s1 pointer is aligned. */
-L(nalign1_min):
- CHECK_N_BYTES(r3,r4,r7)
- /* Are we on the 64B hunk which crosses a page? */
- andi. r10,r4,63 /* Determine offset into 64B hunk. */
- andi. r8,r4,15 /* The offset into the 16B hunk. */
- neg r7,r4
- andi. r9,r7,15 /* Number of bytes after a 16B cross. */
- rlwinm. r7,r7,26,0x3F /* ((r4-4096))>>6&63. */
- beq L(compare_64_pagecross)
- mtctr r7
-
- .p2align 5
-L(compare_64B_unaligned):
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
- COMPARE_16(v4,v5,32)
- COMPARE_16(v4,v5,48)
- addi r3,r3,64
- addi r4,r4,64
- bdnz L(compare_64B_unaligned)
-
- /* Cross the page boundary of s2, carefully. Only for first
- iteration we have to get the count of 64B blocks to be checked.
- From second iteration and beyond, loop counter is always 63. */
-L(compare_64_pagecross):
- li r11, 63
- mtctr r11
- cmpldi r10,16
- ble L(cross_4)
- cmpldi r10,32
- ble L(cross_3)
- cmpldi r10,48
- ble L(cross_2)
-L(cross_1):
- CHECK_N_BYTES(r3,r4,r9)
- CHECK_N_BYTES(r3,r4,r8)
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
- COMPARE_16(v4,v5,32)
- addi r3,r3,48
- addi r4,r4,48
- b L(compare_64B_unaligned)
-L(cross_2):
- COMPARE_16(v4,v5,0)
- addi r3,r3,16
- addi r4,r4,16
- CHECK_N_BYTES(r3,r4,r9)
- CHECK_N_BYTES(r3,r4,r8)
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
- addi r3,r3,32
- addi r4,r4,32
- b L(compare_64B_unaligned)
-L(cross_3):
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
- addi r3,r3,32
- addi r4,r4,32
- CHECK_N_BYTES(r3,r4,r9)
- CHECK_N_BYTES(r3,r4,r8)
- COMPARE_16(v4,v5,0)
- addi r3,r3,16
- addi r4,r4,16
- b L(compare_64B_unaligned)
-L(cross_4):
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
- COMPARE_16(v4,v5,32)
- addi r3,r3,48
- addi r4,r4,48
- CHECK_N_BYTES(r3,r4,r9)
- CHECK_N_BYTES(r3,r4,r8)
- b L(compare_64B_unaligned)
-
-L(same_aligned):
- CHECK_N_BYTES(r3,r4,r7)
- /* Align s1 to 32B and adjust s2 address.
- Use lxvp only if both s1 and s2 are 32B aligned. */
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
- COMPARE_16(v4,v5,32)
- COMPARE_16(v4,v5,48)
- addi r3,r3,64
- addi r4,r4,64
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
-
- clrldi r6,r3,59
- subfic r5,r6,32
- add r3,r3,r5
- add r4,r4,r5
- andi. r5,r4,0x1F
- beq cr0,L(32B_aligned_loop)
-
- .p2align 5
-L(16B_aligned_loop):
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
- COMPARE_16(v4,v5,32)
- COMPARE_16(v4,v5,48)
- addi r3,r3,64
- addi r4,r4,64
- b L(16B_aligned_loop)
-
- /* Calculate and return the difference. */
-L(different):
- TAIL(v4,v5)
-
- .p2align 5
-L(32B_aligned_loop):
- COMPARE_32(v14,v16,0,tail1,tail2)
- COMPARE_32(v18,v20,32,tail3,tail4)
- COMPARE_32(v22,v24,64,tail5,tail6)
- COMPARE_32(v26,v28,96,tail7,tail8)
- addi r3,r3,128
- addi r4,r4,128
- b L(32B_aligned_loop)
-
-L(tail1): TAIL(v15,v17)
-L(tail2): TAIL(v14,v16)
-L(tail3): TAIL(v19,v21)
-L(tail4): TAIL(v18,v20)
-L(tail5): TAIL(v23,v25)
-L(tail6): TAIL(v22,v24)
-L(tail7): TAIL(v27,v29)
-L(tail8): TAIL(v26,v28)
-
-END (STRCMP)
-libc_hidden_builtin_def (strcmp)
Index: glibc-2.41/sysdeps/powerpc/powerpc64/le/power10/strncmp.S
===================================================================
--- glibc-2.41.orig/sysdeps/powerpc/powerpc64/le/power10/strncmp.S
+++ /dev/null
@@ -1,271 +0,0 @@
-/* Optimized strncmp implementation for PowerPC64/POWER10.
- Copyright (C) 2024-2025 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>
-
-/* Implements the function
-
- int [r3] strncmp (const char *s1 [r3], const char *s2 [r4], size_t [r5] n)
-
- The implementation uses unaligned doubleword access to avoid specialized
- code paths depending of data alignment for first 32 bytes and uses
- vectorised loops after that. */
-
-#ifndef STRNCMP
-# define STRNCMP strncmp
-#endif
-
-/* TODO: Change this to actual instructions when minimum binutils is upgraded
- to 2.27. Macros are defined below for these newer instructions in order
- to maintain compatibility. */
-
-#define LXVP(xtp,dq,ra) \
- .long(((6)<<(32-6)) \
- | ((((xtp)-32)>>1)<<(32-10)) \
- | ((1)<<(32-11)) \
- | ((ra)<<(32-16)) \
- | dq)
-
-#define COMPARE_16(vreg1,vreg2,offset) \
- lxv vreg1+32,offset(r3); \
- lxv vreg2+32,offset(r4); \
- vcmpnezb. v7,vreg1,vreg2; \
- bne cr6,L(different); \
- cmpldi cr7,r5,16; \
- ble cr7,L(ret0); \
- addi r5,r5,-16;
-
-#define COMPARE_32(vreg1,vreg2,offset,label1,label2) \
- LXVP(vreg1+32,offset,r3); \
- LXVP(vreg2+32,offset,r4); \
- vcmpnezb. v7,vreg1+1,vreg2+1; \
- bne cr6,L(label1); \
- vcmpnezb. v7,vreg1,vreg2; \
- bne cr6,L(label2); \
- cmpldi cr7,r5,32; \
- ble cr7,L(ret0); \
- addi r5,r5,-32;
-
-#define TAIL_FIRST_16B(vreg1,vreg2) \
- vctzlsbb r6,v7; \
- cmpld cr7,r5,r6; \
- ble cr7,L(ret0); \
- vextubrx r5,r6,vreg1; \
- vextubrx r4,r6,vreg2; \
- subf r3,r4,r5; \
- blr;
-
-#define TAIL_SECOND_16B(vreg1,vreg2) \
- vctzlsbb r6,v7; \
- addi r0,r6,16; \
- cmpld cr7,r5,r0; \
- ble cr7,L(ret0); \
- vextubrx r5,r6,vreg1; \
- vextubrx r4,r6,vreg2; \
- subf r3,r4,r5; \
- blr;
-
-#define CHECK_N_BYTES(reg1,reg2,len_reg) \
- sldi r6,len_reg,56; \
- lxvl 32+v4,reg1,r6; \
- lxvl 32+v5,reg2,r6; \
- add reg1,reg1,len_reg; \
- add reg2,reg2,len_reg; \
- vcmpnezb v7,v4,v5; \
- vctzlsbb r6,v7; \
- cmpld cr7,r6,len_reg; \
- blt cr7,L(different); \
- cmpld cr7,r5,len_reg; \
- ble cr7,L(ret0); \
- sub r5,r5,len_reg; \
-
- /* TODO: change this to .machine power10 when the minimum required
- binutils allows it. */
- .machine power9
-ENTRY_TOCLESS (STRNCMP, 4)
- /* Check if size is 0. */
- cmpdi cr0,r5,0
- beq cr0,L(ret0)
- andi. r7,r3,4095
- andi. r8,r4,4095
- cmpldi cr0,r7,4096-16
- cmpldi cr1,r8,4096-16
- bgt cr0,L(crosses)
- bgt cr1,L(crosses)
- COMPARE_16(v4,v5,0)
- addi r3,r3,16
- addi r4,r4,16
-
-L(crosses):
- andi. r7,r3,15
- subfic r7,r7,16 /* r7(nalign1) = 16 - (str1 & 15). */
- andi. r9,r4,15
- subfic r8,r9,16 /* r8(nalign2) = 16 - (str2 & 15). */
- cmpld cr7,r7,r8
- beq cr7,L(same_aligned)
- blt cr7,L(nalign1_min)
-
- /* nalign2 is minimum and s2 pointer is aligned. */
- CHECK_N_BYTES(r3,r4,r8)
- /* Are we on the 64B hunk which crosses a page? */
- andi. r10,r3,63 /* Determine offset into 64B hunk. */
- andi. r8,r3,15 /* The offset into the 16B hunk. */
- neg r7,r3
- andi. r9,r7,15 /* Number of bytes after a 16B cross. */
- rlwinm. r7,r7,26,0x3F /* ((r4-4096))>>6&63. */
- beq L(compare_64_pagecross)
- mtctr r7
- b L(compare_64B_unaligned)
-
- /* nalign1 is minimum and s1 pointer is aligned. */
-L(nalign1_min):
- CHECK_N_BYTES(r3,r4,r7)
- /* Are we on the 64B hunk which crosses a page? */
- andi. r10,r4,63 /* Determine offset into 64B hunk. */
- andi. r8,r4,15 /* The offset into the 16B hunk. */
- neg r7,r4
- andi. r9,r7,15 /* Number of bytes after a 16B cross. */
- rlwinm. r7,r7,26,0x3F /* ((r4-4096))>>6&63. */
- beq L(compare_64_pagecross)
- mtctr r7
-
- .p2align 5
-L(compare_64B_unaligned):
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
- COMPARE_16(v4,v5,32)
- COMPARE_16(v4,v5,48)
- addi r3,r3,64
- addi r4,r4,64
- bdnz L(compare_64B_unaligned)
-
- /* Cross the page boundary of s2, carefully. Only for first
- iteration we have to get the count of 64B blocks to be checked.
- From second iteration and beyond, loop counter is always 63. */
-L(compare_64_pagecross):
- li r11, 63
- mtctr r11
- cmpldi r10,16
- ble L(cross_4)
- cmpldi r10,32
- ble L(cross_3)
- cmpldi r10,48
- ble L(cross_2)
-L(cross_1):
- CHECK_N_BYTES(r3,r4,r9)
- CHECK_N_BYTES(r3,r4,r8)
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
- COMPARE_16(v4,v5,32)
- addi r3,r3,48
- addi r4,r4,48
- b L(compare_64B_unaligned)
-L(cross_2):
- COMPARE_16(v4,v5,0)
- addi r3,r3,16
- addi r4,r4,16
- CHECK_N_BYTES(r3,r4,r9)
- CHECK_N_BYTES(r3,r4,r8)
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
- addi r3,r3,32
- addi r4,r4,32
- b L(compare_64B_unaligned)
-L(cross_3):
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
- addi r3,r3,32
- addi r4,r4,32
- CHECK_N_BYTES(r3,r4,r9)
- CHECK_N_BYTES(r3,r4,r8)
- COMPARE_16(v4,v5,0)
- addi r3,r3,16
- addi r4,r4,16
- b L(compare_64B_unaligned)
-L(cross_4):
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
- COMPARE_16(v4,v5,32)
- addi r3,r3,48
- addi r4,r4,48
- CHECK_N_BYTES(r3,r4,r9)
- CHECK_N_BYTES(r3,r4,r8)
- b L(compare_64B_unaligned)
-
-L(same_aligned):
- CHECK_N_BYTES(r3,r4,r7)
- /* Align s1 to 32B and adjust s2 address.
- Use lxvp only if both s1 and s2 are 32B aligned. */
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
- COMPARE_16(v4,v5,32)
- COMPARE_16(v4,v5,48)
- addi r3,r3,64
- addi r4,r4,64
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
- addi r5,r5,32
-
- clrldi r6,r3,59
- subfic r7,r6,32
- add r3,r3,r7
- add r4,r4,r7
- subf r5,r7,r5
- andi. r7,r4,0x1F
- beq cr0,L(32B_aligned_loop)
-
- .p2align 5
-L(16B_aligned_loop):
- COMPARE_16(v4,v5,0)
- COMPARE_16(v4,v5,16)
- COMPARE_16(v4,v5,32)
- COMPARE_16(v4,v5,48)
- addi r3,r3,64
- addi r4,r4,64
- b L(16B_aligned_loop)
-
- /* Calculate and return the difference. */
-L(different):
- TAIL_FIRST_16B(v4,v5)
-
- .p2align 5
-L(32B_aligned_loop):
- COMPARE_32(v14,v16,0,tail1,tail2)
- COMPARE_32(v18,v20,32,tail3,tail4)
- COMPARE_32(v22,v24,64,tail5,tail6)
- COMPARE_32(v26,v28,96,tail7,tail8)
- addi r3,r3,128
- addi r4,r4,128
- b L(32B_aligned_loop)
-
-L(tail1): TAIL_FIRST_16B(v15,v17)
-L(tail2): TAIL_SECOND_16B(v14,v16)
-L(tail3): TAIL_FIRST_16B(v19,v21)
-L(tail4): TAIL_SECOND_16B(v18,v20)
-L(tail5): TAIL_FIRST_16B(v23,v25)
-L(tail6): TAIL_SECOND_16B(v22,v24)
-L(tail7): TAIL_FIRST_16B(v27,v29)
-L(tail8): TAIL_SECOND_16B(v26,v28)
-
- .p2align 5
-L(ret0):
- li r3,0
- blr
-
-END(STRNCMP)
-libc_hidden_builtin_def(strncmp)
Index: glibc-2.41/sysdeps/powerpc/powerpc64/multiarch/Makefile
===================================================================
--- glibc-2.41.orig/sysdeps/powerpc/powerpc64/multiarch/Makefile
+++ glibc-2.41/sysdeps/powerpc/powerpc64/multiarch/Makefile
@@ -33,8 +33,8 @@ sysdep_routines += memcpy-power8-cached
ifneq (,$(filter %le,$(config-machine)))
sysdep_routines += memchr-power10 memcmp-power10 memcpy-power10 \
memmove-power10 memset-power10 rawmemchr-power9 \
- rawmemchr-power10 strcmp-power9 strcmp-power10 \
- strncmp-power9 strncmp-power10 strcpy-power9 strcat-power10 \
+ rawmemchr-power10 strcmp-power9 \
+ strncmp-power9 strcpy-power9 strcat-power10 \
stpcpy-power9 strlen-power9 strncpy-power9 stpncpy-power9 \
strlen-power10
endif
Index: glibc-2.41/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
===================================================================
--- glibc-2.41.orig/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+++ glibc-2.41/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
@@ -164,9 +164,6 @@ __libc_ifunc_impl_list (const char *name
/* Support sysdeps/powerpc/powerpc64/multiarch/strncmp.c. */
IFUNC_IMPL (i, name, strncmp,
#ifdef __LITTLE_ENDIAN__
- IFUNC_IMPL_ADD (array, i, strncmp, hwcap2 & PPC_FEATURE2_ARCH_3_1
- && hwcap & PPC_FEATURE_HAS_VSX,
- __strncmp_power10)
IFUNC_IMPL_ADD (array, i, strncmp, hwcap2 & PPC_FEATURE2_ARCH_3_00
&& hwcap & PPC_FEATURE_HAS_ALTIVEC,
__strncmp_power9)
@@ -387,10 +384,6 @@ __libc_ifunc_impl_list (const char *name
IFUNC_IMPL (i, name, strcmp,
#ifdef __LITTLE_ENDIAN__
IFUNC_IMPL_ADD (array, i, strcmp,
- (hwcap2 & PPC_FEATURE2_ARCH_3_1)
- && (hwcap & PPC_FEATURE_HAS_VSX),
- __strcmp_power10)
- IFUNC_IMPL_ADD (array, i, strcmp,
hwcap2 & PPC_FEATURE2_ARCH_3_00
&& hwcap & PPC_FEATURE_HAS_ALTIVEC,
__strcmp_power9)
Index: glibc-2.41/sysdeps/powerpc/powerpc64/multiarch/strcmp-power10.S
===================================================================
--- glibc-2.41.orig/sysdeps/powerpc/powerpc64/multiarch/strcmp-power10.S
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Optimized strcmp implementation for POWER10/PPC64.
- Copyright (C) 2021-2025 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <https://www.gnu.org/licenses/>. */
-
-#if defined __LITTLE_ENDIAN__ && IS_IN (libc)
-#define STRCMP __strcmp_power10
-
-#undef libc_hidden_builtin_def
-#define libc_hidden_builtin_def(name)
-
-#include <sysdeps/powerpc/powerpc64/le/power10/strcmp.S>
-#endif /* __LITTLE_ENDIAN__ && IS_IN (libc) */
Index: glibc-2.41/sysdeps/powerpc/powerpc64/multiarch/strcmp.c
===================================================================
--- glibc-2.41.orig/sysdeps/powerpc/powerpc64/multiarch/strcmp.c
+++ glibc-2.41/sysdeps/powerpc/powerpc64/multiarch/strcmp.c
@@ -29,16 +29,12 @@ extern __typeof (strcmp) __strcmp_power7
extern __typeof (strcmp) __strcmp_power8 attribute_hidden;
# ifdef __LITTLE_ENDIAN__
extern __typeof (strcmp) __strcmp_power9 attribute_hidden;
-extern __typeof (strcmp) __strcmp_power10 attribute_hidden;
# endif
# undef strcmp
libc_ifunc_redirected (__redirect_strcmp, strcmp,
# ifdef __LITTLE_ENDIAN__
- (hwcap2 & PPC_FEATURE2_ARCH_3_1
- && hwcap & PPC_FEATURE_HAS_VSX)
- ? __strcmp_power10 :
(hwcap2 & PPC_FEATURE2_ARCH_3_00
&& hwcap & PPC_FEATURE_HAS_ALTIVEC)
? __strcmp_power9 :
Index: glibc-2.41/sysdeps/powerpc/powerpc64/multiarch/strncmp-power10.S
===================================================================
--- glibc-2.41.orig/sysdeps/powerpc/powerpc64/multiarch/strncmp-power10.S
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Copyright (C) 2024-2025 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <https://www.gnu.org/licenses/>. */
-
-#if defined __LITTLE_ENDIAN__ && IS_IN (libc)
-#define STRNCMP __strncmp_power10
-
-#undef libc_hidden_builtin_def
-#define libc_hidden_builtin_def(name)
-
-#include <sysdeps/powerpc/powerpc64/le/power10/strncmp.S>
-#endif
Index: glibc-2.41/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
===================================================================
--- glibc-2.41.orig/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
+++ glibc-2.41/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
@@ -29,7 +29,6 @@ extern __typeof (strncmp) __strncmp_ppc
extern __typeof (strncmp) __strncmp_power8 attribute_hidden;
# ifdef __LITTLE_ENDIAN__
extern __typeof (strncmp) __strncmp_power9 attribute_hidden;
-extern __typeof (strncmp) __strncmp_power10 attribute_hidden;
# endif
# undef strncmp
@@ -37,9 +36,6 @@ extern __typeof (strncmp) __strncmp_powe
ifunc symbol properly. */
libc_ifunc_redirected (__redirect_strncmp, strncmp,
# ifdef __LITTLE_ENDIAN__
- (hwcap2 & PPC_FEATURE2_ARCH_3_1
- && hwcap & PPC_FEATURE_HAS_VSX)
- ? __strncmp_power10 :
(hwcap2 & PPC_FEATURE2_ARCH_3_00
&& hwcap & PPC_FEATURE_HAS_ALTIVEC)
? __strncmp_power9 :

View File

@@ -1,6 +1,6 @@
From 322a7b6a9bad6ab6a985ea67f7bc65a434806061 Mon Sep 17 00:00:00 2001
From 43c311457caf71c02ea2857bcf4e1e0499dc221a Mon Sep 17 00:00:00 2001
From: Giuliano Belinassi <gbelinassi@suse.de>
Date: Mon, 6 May 2024 20:09:55 -0300
Date: Fri, 18 Apr 2025 14:22:49 -0300
Subject: [PATCH] Add Userspace Livepatch prologue into ASM functions
Userspace Live Patching (ULP) refers to the process of applying
@@ -12,38 +12,24 @@ this have to be included manually. This patch does this.
Signed-off-by: Giuliano Belinassi <gbelinassi@suse.de>
---
Makeconfig | 5 +++
config.h.in | 3 ++
config.make.in | 1 +
configure | 21 +++++++++
configure.ac | 13 ++++++
config.make.in | 2 +
configure | 54 +++++++++++++++++++++++
configure.ac | 29 +++++++++++++
sysdeps/powerpc/powerpc64/le/Makefile | 8 ++++
sysdeps/powerpc/powerpc64/sysdep.h | 55 ++++++++++++++++++++++--
sysdeps/x86_64/Makefile | 5 +++
sysdeps/x86_64/multiarch/strcmp-avx2.S | 5 +--
sysdeps/x86_64/multiarch/strcmp-evex.S | 5 +--
sysdeps/x86_64/multiarch/strcmp-sse4_2.S | 5 +--
sysdeps/x86_64/sysdep.h | 54 ++++++++++++++++++++++--
9 files changed, 96 insertions(+), 16 deletions(-)
sysdeps/x86_64/sysdep.h | 54 +++++++++++++++++++++--
11 files changed, 205 insertions(+), 20 deletions(-)
diff --git a/Makeconfig b/Makeconfig
index a0abc2239b..1eb730a2f7 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -1017,6 +1017,11 @@ endif
# Filter out 64 bit time_t flags if compiler defines it by default.
+cflags += $(no-time-bits-source)
+# Add flags for Userspace Livepatching support.
+ifeq (yes,$(enable-userspace-livepatch))
++cflags += -fpatchable-function-entry=16,14
+endif
+
# Each sysdeps directory can contain header files that both will be
# used to compile and will be installed. Each can also contain an
# include/ subdirectory, whose header files will be used to compile
diff --git a/config.h.in b/config.h.in
index 6c25c923fa..98e267d71c 100644
index cdbd555366..2cd9838361 100644
--- a/config.h.in
+++ b/config.h.in
@@ -211,6 +211,9 @@
@@ -221,6 +221,9 @@
/* Define to 1 if libpthread actually resides in libc. */
#define PTHREAD_IN_LIBC 0
@@ -54,30 +40,32 @@ index 6c25c923fa..98e267d71c 100644
#define TIMEOUTFACTOR 1
diff --git a/config.make.in b/config.make.in
index 36096881b7..04cf873fad 100644
index 59897eaec2..63f9b6ee58 100644
--- a/config.make.in
+++ b/config.make.in
@@ -81,6 +81,7 @@ mach-interface-list = @mach_interface_list@
@@ -82,6 +82,8 @@ mach-interface-list = @mach_interface_list@
memory-tagging = @memory_tagging@
# Configuration options.
+enable-userspace-livepatch = @enable_userspace_livepatch@
+supports-msplit-patch-nops = @supports_msplit_patch_nops@
build-shared = @shared@
build-profile = @profile@
build-static-nss = @static_nss@
diff --git a/configure b/configure
index 9c0c0dce03..4b18c93595 100755
index 674d1d7e4a..51dbce3b34 100755
--- a/configure
+++ b/configure
@@ -615,6 +615,7 @@ LIBOBJS
@@ -615,6 +615,8 @@ LIBOBJS
pthread_in_libc
RELEASE
VERSION
+supports_msplit_patch_nops
+enable_userspace_livepatch
mach_interface_list
DEFINES
static_nss
@@ -811,6 +812,7 @@ enable_cet
@@ -821,6 +823,7 @@ enable_cet
enable_scv
enable_fortify_source
with_cpu
@@ -85,7 +73,7 @@ index 9c0c0dce03..4b18c93595 100755
'
ac_precious_vars='build_alias
host_alias
@@ -1493,6 +1495,8 @@ Optional Features:
@@ -1505,6 +1508,8 @@ Optional Features:
Use -D_FORTIFY_SOURCE=[1|2|3] to control code
hardening, defaults to highest possible value
supported by the build compiler.
@@ -94,7 +82,7 @@ index 9c0c0dce03..4b18c93595 100755
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@@ -8184,6 +8188,23 @@ libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory`
@@ -9152,6 +9157,55 @@ libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory`
@@ -102,11 +90,42 @@ index 9c0c0dce03..4b18c93595 100755
+if test ${enable_userspace_livepatch+y}
+then :
+ enableval=$enable_userspace_livepatch; enable_userspace_livepatch=$enableval
+else $as_nop
+ enable_userspace_livepatch=no
+else case e in #(
+ e) enable_userspace_livepatch=no ;;
+esac
+fi
+
+
+# Check if compiler provides -msplit-patch-nops. It may be required on
+# some architectures for livepatching support.
+if test "x$enable_userspace_livepatch" = xyes; then
+ old_CFLAGS="$CFLAGS"
+ CFLAGS="-msplit-patch-nops $CFLAGS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+extern void g(void);
+ __attribute__((patchable_function_entry(14, 13)))
+ void f(void) { g(); }
+int
+main (void)
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+ supports_msplit_patch_nops=yes
+else case e in #(
+ e) supports_msplit_patch_nops=no ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+
+ CFLAGS="$old_CFLAGS"
+fi
+
+# Libpulp uses -fpatchable-function-entry to add padding NOPS to the
+# prologue of all functions.
+if test "x$enable_userspace_livepatch" = xyes; then
@@ -114,15 +133,16 @@ index 9c0c0dce03..4b18c93595 100755
+
+fi
+
+
+
VERSION=`sed -n -e 's/^#define VERSION "\([^"]*\)"/\1/p' < $srcdir/version.h`
RELEASE=`sed -n -e 's/^#define RELEASE "\([^"]*\)"/\1/p' < $srcdir/version.h`
diff --git a/configure.ac b/configure.ac
index d5a00461ff..80f183a7b5 100644
index 57cd24c87d..97c65dc6c5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1813,6 +1813,19 @@ AC_SUBST(DEFINES)
@@ -2079,6 +2079,35 @@ AC_SUBST(DEFINES)
dnl See sysdeps/mach/configure.ac for this variable.
AC_SUBST(mach_interface_list)
@@ -132,18 +152,145 @@ index d5a00461ff..80f183a7b5 100644
+ [enable_userspace_livepatch=$enableval],
+ [enable_userspace_livepatch=no])
+
+# Check if compiler provides -msplit-patch-nops. It may be required on
+# some architectures for livepatching support.
+if test "x$enable_userspace_livepatch" = xyes; then
+ old_CFLAGS="$CFLAGS"
+ CFLAGS="-msplit-patch-nops $CFLAGS"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
+ [[extern void g(void);
+ __attribute__((patchable_function_entry(14, 13)))
+ void f(void) { g(); }]])],
+ [supports_msplit_patch_nops=yes],
+ [supports_msplit_patch_nops=no])
+
+ CFLAGS="$old_CFLAGS"
+fi
+
+# Libpulp uses -fpatchable-function-entry to add padding NOPS to the
+# prologue of all functions.
+if test "x$enable_userspace_livepatch" = xyes; then
+ AC_DEFINE(ENABLE_USERSPACE_LIVEPATCH)
+fi
+AC_SUBST(enable_userspace_livepatch)
+AC_SUBST(supports_msplit_patch_nops)
+
VERSION=`sed -n -e 's/^#define VERSION "\([^"]*\)"/\1/p' < $srcdir/version.h`
RELEASE=`sed -n -e 's/^#define RELEASE "\([^"]*\)"/\1/p' < $srcdir/version.h`
AC_SUBST(VERSION)
diff --git a/sysdeps/powerpc/powerpc64/le/Makefile b/sysdeps/powerpc/powerpc64/le/Makefile
index b77775cf95..8340a8e02f 100644
--- a/sysdeps/powerpc/powerpc64/le/Makefile
+++ b/sysdeps/powerpc/powerpc64/le/Makefile
@@ -1,3 +1,11 @@
+# Add flags for Userspace Livepatching support.
+ifeq (yes,$(enable-userspace-livepatch))
++cflags += -fpatchable-function-entry=14,13
+ifeq (yes,$(supports-msplit-patch-nops))
++cflags += -msplit-patch-nops
+endif
+endif
+
# When building float128 we need to ensure -mfloat128 is
# passed to all such object files.
type-float128-CFLAGS := -mfloat128
diff --git a/sysdeps/powerpc/powerpc64/sysdep.h b/sysdeps/powerpc/powerpc64/sysdep.h
index f05dae71f6..55c6b9b45b 100644
--- a/sysdeps/powerpc/powerpc64/sysdep.h
+++ b/sysdeps/powerpc/powerpc64/sysdep.h
@@ -163,6 +163,46 @@
BODY_LABEL(\name):
.endm
+/* Libpulp uses -fpatchable-function-entry to add padding NOPS to the
+ prologue of all functions. This works for C functions. For functions
+ written in ASM, the way we do this is by adding this prologue manually. */
+
+#if ENABLE_USERSPACE_LIVEPATCH
+
+/* Instructions to be inserted before the function label. */
+# define ULP_NOPS_PRE_PROLOGUE .rept 13; nop; .endr
+
+/* Instruction to be inserted after the function label. */
+# define ULP_NOPS_POST_PROLOGUE .rept 1; nop; .endr
+
+
+/* this macro expands according to the following condition:
+ * if name = _start, then the prologue is not inserted.
+ * if name = _dl_relocate_static_pie, then the prologue is not inserted.
+ * if name = anything else, then the prologue is inserted.
+ **/
+# define __ULP_PRE_PROLOGUE_dl_relocate_static_pie ,
+# define __ULP_PRE_PROLOGUE_start ,
+# define __ULP_PRE_PROLOGUE(x, y,...) y
+# define _ULP_PRE_PROLOGUE(x, ...) __ULP_PRE_PROLOGUE(x, __VA_ARGS__)
+# define ULP_PRE_PROLOGUE(name) _ULP_PRE_PROLOGUE(__ULP_PRE_PROLOGUE##name, ULP_NOPS_PRE_PROLOGUE,)
+
+/* this macro expands according to the following condition:
+ * if name = _start, then the postlogue is not inserted.
+ * if name = _dl_relocate_static_pie, then the postlogue is not inserted.
+ * if name = anything else, then the postlogue is inserted.
+ **/
+# define __ULP_POST_PROLOGUE_dl_relocate_static_pie ,
+# define __ULP_POST_PROLOGUE_start ,
+# define __ULP_POST_PROLOGUE(x, y,...) y
+# define _ULP_POST_PROLOGUE(x, ...) __ULP_POST_PROLOGUE(x, __VA_ARGS__)
+# define ULP_POST_PROLOGUE(name) _ULP_POST_PROLOGUE(__ULP_POST_PROLOGUE##name, ULP_NOPS_POST_PROLOGUE,)
+
+#else
+# define ULP_PRE_PROLOGUE(name)
+# define ULP_POST_PROLOGUE(name)
+#endif
+
/* Use ENTRY_TOCLESS for functions that make no use of r2 and
guarantee r2 is unchanged on exit. Any function that has @toc or
@got relocs uses r2. Functions that call other functions via the
@@ -175,19 +215,26 @@ BODY_LABEL(\name):
before the start of the function's code. */
#ifndef PROF
#define ENTRY_TOCLESS(name, ...) \
+ ULP_PRE_PROLOGUE(name); \
ENTRY_3 name, ## __VA_ARGS__; \
- cfi_startproc
+ cfi_startproc; \
+ ULP_POST_PROLOGUE(name)
#define ENTRY(name, ...) \
- ENTRY_TOCLESS(name, ## __VA_ARGS__); \
- LOCALENTRY(name)
+ ULP_PRE_PROLOGUE(name); \
+ ENTRY_3 name, ## __VA_ARGS__; \
+ cfi_startproc; \
+ LOCALENTRY(name); \
+ ULP_POST_PROLOGUE(name)
#else
/* The call to _mcount is potentially via the plt, so profiling code
is never free of an r2 use. */
#define ENTRY_TOCLESS(name, ...) \
+ ULP_PRE_PROLOGUE(name); \
ENTRY_3 name, ## __VA_ARGS__; \
cfi_startproc; \
- LOCALENTRY(name)
+ LOCALENTRY(name); \
+ ULP_POST_PROLOGUE(name)
#define ENTRY(name, ...) \
ENTRY_TOCLESS(name, ## __VA_ARGS__)
diff --git a/sysdeps/x86_64/Makefile b/sysdeps/x86_64/Makefile
index 9d31685e02..d20287a050 100644
--- a/sysdeps/x86_64/Makefile
+++ b/sysdeps/x86_64/Makefile
@@ -1,3 +1,8 @@
+# Add flags for Userspace Livepatching support.
+ifeq (yes,$(enable-userspace-livepatch))
++cflags += -fpatchable-function-entry=16,14
+endif
+
# The i387 `long double' is a distinct type we support.
long-double-fcts = yes
diff --git a/sysdeps/x86_64/multiarch/strcmp-avx2.S b/sysdeps/x86_64/multiarch/strcmp-avx2.S
index 5bc1d90078..3ea96c0aa3 100644
index 4b46a8de17..8266f558d9 100644
--- a/sysdeps/x86_64/multiarch/strcmp-avx2.S
+++ b/sysdeps/x86_64/multiarch/strcmp-avx2.S
@@ -201,10 +201,7 @@ END (STRCASECMP)
@@ -159,7 +306,7 @@ index 5bc1d90078..3ea96c0aa3 100644
# if defined USE_AS_STRCASECMP_L
/* We have to fall back on the C implementation for locales with
diff --git a/sysdeps/x86_64/multiarch/strcmp-evex.S b/sysdeps/x86_64/multiarch/strcmp-evex.S
index cea034f394..3ed55b7d66 100644
index 6316bb940e..91192f2d2e 100644
--- a/sysdeps/x86_64/multiarch/strcmp-evex.S
+++ b/sysdeps/x86_64/multiarch/strcmp-evex.S
@@ -226,10 +226,7 @@ END (STRCASECMP)
@@ -175,7 +322,7 @@ index cea034f394..3ed55b7d66 100644
# if defined USE_AS_STRCASECMP_L
/* We have to fall back on the C implementation for locales with
diff --git a/sysdeps/x86_64/multiarch/strcmp-sse4_2.S b/sysdeps/x86_64/multiarch/strcmp-sse4_2.S
index 4e98da0246..2a2280c65f 100644
index 1b746c4b2f..01c8eb44e3 100644
--- a/sysdeps/x86_64/multiarch/strcmp-sse4_2.S
+++ b/sysdeps/x86_64/multiarch/strcmp-sse4_2.S
@@ -103,10 +103,7 @@ END (STRCASECMP)
@@ -191,7 +338,7 @@ index 4e98da0246..2a2280c65f 100644
/*
* This implementation uses SSE to compare up to 16 bytes at a time.
diff --git a/sysdeps/x86_64/sysdep.h b/sysdeps/x86_64/sysdep.h
index db6e36b2dd..86a5d1b2be 100644
index cb475bec98..2bb84c4c31 100644
--- a/sysdeps/x86_64/sysdep.h
+++ b/sysdeps/x86_64/sysdep.h
@@ -49,6 +49,46 @@ enum cf_protection_level
@@ -268,5 +415,5 @@ index db6e36b2dd..86a5d1b2be 100644
/* This macro is for setting proper CFI with DW_CFA_expression describing
the register as saved relative to %rsp instead of relative to the CFA.
--
2.46.2
2.49.0