Projects
openEuler:24.03:SP1:Everything
glibc
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 6
View file
_service:tar_scm:glibc.spec
Changed
@@ -67,7 +67,7 @@ ############################################################################## Name: glibc Version: 2.38 -Release: 37 +Release: 41 Summary: The GNU libc libraries License: %{all_license} URL: http://www.gnu.org/software/glibc/ @@ -215,33 +215,47 @@ Patch126: Fix-name-space-violation-in-fortify-wrappers-bug-320.patch Patch127: x86-Fix-bug-in-strchrnul-evex512-BZ-32078.patch Patch128: 19614-locale-Handle-loading-a-missing-locale-twice-Bug-14.patch +Patch129: support-Add-FAIL-test-failure-helper.patch +Patch130: stdio-common-Add-test-for-vfscanf-with-matches-longe.patch +Patch131: Make-tst-ungetc-use-libsupport.patch +Patch132: ungetc-Fix-uninitialized-read-when-putting-into-unus.patch +Patch133: ungetc-Fix-backup-buffer-leak-on-program-exit-BZ-278.patch +Patch134: posix-Use-support-check.h-facilities-in-tst-truncate.patch +Patch135: nptl-Use-support-check.h-facilities-in-tst-setuid3.patch +Patch136: libio-Attempt-wide-backup-free-only-for-non-legacy-c.patch +Patch137: Add-crt1-2.0.o-for-glibc-2.0-compatibility-tests.patch +Patch138: elf-Change-ldconfig-auxcache-magic-number-bug-32231.patch +Patch139: 0001-LoongArch-Use-builtins-for-ffs-and-ffsll.patch +Patch140: 0002-elf-Add-new-LoongArch-reloc-types-110-to-126-into-el.patch +Patch141: 0003-LoongArch-Add-glibc.cpu.hwcap-support.patch +Patch142: 0004-LoongArch-Add-support-for-TLS-Descriptors.patch +Patch143: 0005-LoongArch-Fix-tst-gnu2-tls2-compiler-error.patch +Patch144: 0006-LoongArch-Use-fcsr0-instead-of-r0-in-_FPU_-GET-SET-C.patch +Patch145: 0007-LoongArch-Ensure-sp-16-byte-aligned-for-tlsdesc.patch +Patch146: 0008-LoongArch-Fix-_dl_tlsdesc_dynamic-in-LSX-case.patch +Patch147: 0009-LoongArch-Fix-tst-gnu2-tls2-test-case.patch +Patch148: 0010-LoongArch-Add-cfi-instructions-for-_dl_tlsdesc_dynam.patch +Patch149: 0011-LoongArch-Fix-macro-redefined-warning-in-tls-desc.S.patch +Patch150: 0012-LoongArch-Undef-__NR_fstat-and-__NR_newfstatat.patch +Patch151: 0013-From-Adhemerval-Zanella-adhemerval.zanella-linaro.or.patch +Patch152: 0014-loongarch-Remove-duplicate-strnlen-in-libc.a-BZ-3178.patch +Patch153: 0015-LoongArch-Change-tunable-for-2.38.patch #openEuler patch list Patch9000: turn-default-value-of-x86_rep_stosb_threshold_form_2K_to_1M.patch Patch9001: locale-delete-no-hard-link-to-avoid-all_language-pac.patch -#Patch9002: 0001-add-base-files-for-libphtread-condition-family.patch -#Patch9003: 0002-add-header-files-for-libphtread_2_17_so.patch -#Patch9004: 0003-add-build-script-and-files-of-libpthread_2_17_so.patch -#Patch9005: 0004-add-two-header-files-with-some-deleted-macros.patch -#Patch9006: 0005-add-pthread-functions_h.patch -#Patch9007: 0006-add-elsion-function-which-moved-to-libc-in-glibc-2.34.patch -#Patch9008: 0007-add-lowlevellock_2_17_c.patch -#Patch9009: 0008-add-pause_nocancel_2_17.patch -#Patch9010: 0009-add-unwind-with-longjmp.patch -Patch9011: use-region-to-instead-of-country-for-extract-timezon.patch -Patch9012: malloc-use-__get_nprocs-replace-__get_nprocs_sched.patch -Patch9013: x86-use-total-l3cache-for-non_temporal_threshold.patch -Patch9014: strcmp-delete-align-for-loop_aligned.patch -Patch9015: add-pthread_cond_clockwait-GLIBC_2_28.patch -Patch9016: add-GB18030-2022-charmap-BZ-30243.patch -Patch9017: fix-Segmentation-fault-in-nss-module.patch -Patch9018: fix_nss_database_check_reload_and_get_memleak.patch -Patch9019: 0001-fix-glibc-build-error-on-x86.patch +Patch9002: use-region-to-instead-of-country-for-extract-timezon.patch +Patch9003: strcmp-delete-align-for-loop_aligned.patch +Patch9004: add-pthread_cond_clockwait-GLIBC_2_28.patch +Patch9005: add-GB18030-2022-charmap-BZ-30243.patch +Patch9006: fix-Segmentation-fault-in-nss-module.patch +Patch9007: fix_nss_database_check_reload_and_get_memleak.patch +Patch9008: 0001-fix-glibc-build-error-on-x86.patch %if %{ENABLE_RELOC} -Patch9021: reserve-relocation-information-for-sysboost.patch +Patch9009: reserve-relocation-information-for-sysboost.patch %endif -Patch9022: add-Wl-z-noseparate-code-for-so.patch +Patch9010: add-Wl-z-noseparate-code-for-so.patch Provides: ldconfig rtld(GNU_HASH) bundled(gnulib) @@ -1447,6 +1461,26 @@ %endif %changelog +* Wed Nov 6 2024 lixing <lixing@loongson.cn> - 2.38-41 +- update LoongArch with tlsdec and tunable support + +* Tue Nov 5 2024 Qingqing Li <liqingqing3@huawei.com> - 2.38-40 +- elf: Change ldconfig auxcache magic number (bug 32231) +- Add crt1-2.0.o for glibc 2.0 compatibility tests +- libio: Attempt wide backup free only for non-legacy code + +* Fri Sep 20 2024 Qingqing Li <liqingqing3@huawei.com> - 2.38-39 +- clean code, remove some oe patches which already fixed in upstream + +* Mon Sep 9 2024 Qingqing Li <liqingqing3@huawei.com> - 2.38-38 +- nptl: Use <support/check.h> facilities in tst-setuid3 +- posix: Use <support/check.h> facilities in tst-truncate and tst-truncate64 +- ungetc: Fix backup buffer leak on program exit BZ #27821 +- ungetc: Fix uninitialized read when putting into unused streams BZ #27821 +- Make tst-ungetc use libsupport +- stdio-common: Add test for vfscanf with matches longer than INT_MAX BZ #27650 +- support: Add FAIL test failure helper + * Wed Sep 4 2024 Zhaoshuang <zhaoshuang@uniontech.com> - 2.38-37 - Fix issue that loading a missing locale twice BZ #14247
View file
_service:tar_scm:0001-LoongArch-Use-builtins-for-ffs-and-ffsll.patch
Added
@@ -0,0 +1,30 @@ +From 288d144301d20104e1b79fe5695f09af336574eb Mon Sep 17 00:00:00 2001 +From: Xi Ruoyao <xry111@xry111.site> +Date: Sun, 4 Feb 2024 08:27:50 +0800 +Subject: PATCH 01/15 LoongArch: Use builtins for ffs and ffsll + +On LoongArch GCC compiles __builtin_ffs{,ll} to basically +`(x ? __builtin_ctz (x) : -1) + 1`. Since a hardware ctz instruction is +available, this is much better than the table-driven generic +implementation. + +Tested on loongarch64. + +Signed-off-by: Xi Ruoyao <xry111@xry111.site> +Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org> +--- + sysdeps/loongarch/math-use-builtins-ffs.h | 2 ++ + 1 file changed, 2 insertions(+) + create mode 100644 sysdeps/loongarch/math-use-builtins-ffs.h + +diff --git a/sysdeps/loongarch/math-use-builtins-ffs.h b/sysdeps/loongarch/math-use-builtins-ffs.h +new file mode 100644 +index 00000000..a83bb154 +--- /dev/null ++++ b/sysdeps/loongarch/math-use-builtins-ffs.h +@@ -0,0 +1,2 @@ ++#define USE_FFS_BUILTIN 1 ++#define USE_FFSLL_BUILTIN 1 +-- +2.43.0 +
View file
_service:tar_scm:0002-elf-Add-new-LoongArch-reloc-types-110-to-126-into-el.patch
Added
@@ -0,0 +1,45 @@ +From ba560bc2785afa80bc1ad512dbab95936cddeea5 Mon Sep 17 00:00:00 2001 +From: Xi Ruoyao <xry111@xry111.site> +Date: Thu, 22 Feb 2024 18:57:43 +0800 +Subject: PATCH 02/15 elf: Add new LoongArch reloc types (110 to 126) into + elf.h + +These reloc types have been added in LoongArch psABI v2.30. + +Link: https://github.com/loongson/la-abi-specs/blob/v2.30/laelf.adoc#relocation-types +Signed-off-by: Xi Ruoyao <xry111@xry111.site> +--- + elf/elf.h | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/elf/elf.h b/elf/elf.h +index 51633079..3dbc7c0f 100644 +--- a/elf/elf.h ++++ b/elf/elf.h +@@ -4219,6 +4219,23 @@ enum + #define R_LARCH_ADD_ULEB128 107 + #define R_LARCH_SUB_ULEB128 108 + #define R_LARCH_64_PCREL 109 ++#define R_LARCH_CALL36 110 ++#define R_LARCH_TLS_DESC_PC_HI20 111 ++#define R_LARCH_TLS_DESC_PC_LO12 112 ++#define R_LARCH_TLS_DESC64_PC_LO20 113 ++#define R_LARCH_TLS_DESC64_PC_HI12 114 ++#define R_LARCH_TLS_DESC_HI20 115 ++#define R_LARCH_TLS_DESC_LO12 116 ++#define R_LARCH_TLS_DESC64_LO20 117 ++#define R_LARCH_TLS_DESC64_HI12 118 ++#define R_LARCH_TLS_DESC_LD 119 ++#define R_LARCH_TLS_DESC_CALL 120 ++#define R_LARCH_TLS_LE_HI20_R 121 ++#define R_LARCH_TLS_LE_ADD_R 122 ++#define R_LARCH_TLS_LE_LO12_R 123 ++#define R_LARCH_TLS_LD_PCREL20_S2 124 ++#define R_LARCH_TLS_GD_PCREL20_S2 125 ++#define R_LARCH_TLS_DESC_PCREL20_S2 126 + + /* ARC specific declarations. */ + +-- +2.43.0 +
View file
_service:tar_scm:0003-LoongArch-Add-glibc.cpu.hwcap-support.patch
Added
@@ -0,0 +1,663 @@ +From 3842a3428f45f00b989c6fa37dc1bb1c2e91335d Mon Sep 17 00:00:00 2001 +From: caiyinyu <caiyinyu@loongson.cn> +Date: Fri, 15 Sep 2023 17:35:19 +0800 +Subject: PATCH 03/15 LoongArch: Add glibc.cpu.hwcap support. + +The current IFUNC selection is always using the most recent +features which are available via AT_HWCAP. But in +some scenarios it is useful to adjust this selection. + +The environment variable: + +GLIBC_TUNABLES=glibc.cpu.hwcaps=-xxx,yyy,zzz,.... + +can be used to enable HWCAP feature yyy, disable HWCAP feature xxx, +where the feature name is case-sensitive and has to match the ones +used in sysdeps/loongarch/cpu-tunables.c. + +Signed-off-by: caiyinyu <caiyinyu@loongson.cn> +--- + manual/tunables.texi | 5 +- + sysdeps/loongarch/Makefile | 12 ++ + sysdeps/loongarch/cpu-tunables.c | 87 +++++++++++ + sysdeps/loongarch/dl-get-cpu-features.c | 25 ++++ + sysdeps/loongarch/dl-machine.h | 28 +++- + sysdeps/loongarch/dl-tunables.list | 25 ++++ + .../lp64/multiarch/dl-symbol-redir-ifunc.h | 5 +- + sysdeps/loongarch/tst-hwcap-tunables.c | 136 ++++++++++++++++++ + .../unix/sysv/linux/loongarch/cpu-features.c | 30 ++++ + .../unix/sysv/linux/loongarch/cpu-features.h | 17 ++- + .../unix/sysv/linux/loongarch/dl-procinfo.c | 60 ++++++++ + sysdeps/unix/sysv/linux/loongarch/dl-sysdep.c | 21 +++ + .../unix/sysv/linux/loongarch/libc-start.c | 34 +++++ + 13 files changed, 475 insertions(+), 10 deletions(-) + create mode 100644 sysdeps/loongarch/cpu-tunables.c + create mode 100644 sysdeps/loongarch/dl-get-cpu-features.c + create mode 100644 sysdeps/loongarch/dl-tunables.list + create mode 100644 sysdeps/loongarch/tst-hwcap-tunables.c + create mode 100644 sysdeps/unix/sysv/linux/loongarch/cpu-features.c + create mode 100644 sysdeps/unix/sysv/linux/loongarch/dl-procinfo.c + create mode 100644 sysdeps/unix/sysv/linux/loongarch/dl-sysdep.c + create mode 100644 sysdeps/unix/sysv/linux/loongarch/libc-start.c + +diff --git a/manual/tunables.texi b/manual/tunables.texi +index bb17fef5..6493904b 100644 +--- a/manual/tunables.texi ++++ b/manual/tunables.texi +@@ -513,7 +513,10 @@ On s390x, the supported HWCAP and STFLE features can be found in + @code{sysdeps/s390/cpu-features.c}. In addition the user can also set + a CPU arch-level like @code{z13} instead of single HWCAP and STFLE features. + +-This tunable is specific to i386, x86-64 and s390x. ++On loongarch, the supported HWCAP features can be found in ++@code{sysdeps/loongarch/cpu-tunables.c}. ++ ++This tunable is specific to i386, x86-64, s390x, powerpc and loongarch. + @end deftp + + @deftp Tunable glibc.cpu.cached_memopt +diff --git a/sysdeps/loongarch/Makefile b/sysdeps/loongarch/Makefile +index 43d2f583..446bda65 100644 +--- a/sysdeps/loongarch/Makefile ++++ b/sysdeps/loongarch/Makefile +@@ -1,11 +1,23 @@ + ifeq ($(subdir),misc) + sysdep_headers += sys/asm.h ++ ++tests += \ ++ tst-hwcap-tunables \ ++ # tests ++ ++tst-hwcap-tunables-ARGS = -- $(host-test-program-cmd) + endif + + ifeq ($(subdir),elf) + gen-as-const-headers += dl-link.sym + endif + ++ifeq ($(subdir),elf) ++sysdep-dl-routines += \ ++ dl-get-cpu-features \ ++ # sysdep-dl-routines ++endif ++ + # LoongArch's assembler also needs to know about PIC as it changes the + # definition of some assembler macros. + ASFLAGS-.os += $(pic-ccflag) +diff --git a/sysdeps/loongarch/cpu-tunables.c b/sysdeps/loongarch/cpu-tunables.c +new file mode 100644 +index 00000000..e274e993 +--- /dev/null ++++ b/sysdeps/loongarch/cpu-tunables.c +@@ -0,0 +1,87 @@ ++/* LoongArch CPU feature tuning. ++ This file is part of the GNU C Library. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++#include <stdbool.h> ++#include <stdint.h> ++#include <unistd.h> /* Get STDOUT_FILENO for _dl_printf. */ ++#include <elf/dl-tunables.h> ++#include <string.h> ++#include <cpu-features.h> ++#include <ldsodefs.h> ++#include <sys/auxv.h> ++#include <dl-tunables-parse.h> ++#include <dl-symbol-redir-ifunc.h> ++ ++#define CHECK_GLIBC_IFUNC_CPU(f, name, len) \ ++ _Static_assert (sizeof (#name) - 1 == len, #name " != " #len); \ ++ if (tunable_str_comma_strcmp_cte (&f, #name)) \ ++ { \ ++ if (f.disable) \ ++ GLRO(dl_larch_cpu_features).hwcap &= (~HWCAP_LOONGARCH_##name); \ ++ else \ ++ GLRO(dl_larch_cpu_features).hwcap |= HWCAP_LOONGARCH_##name; \ ++ break; \ ++ } ++ ++attribute_hidden void ++TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp) ++{ ++ /* The current IFUNC selection is based on microbenchmarks in glibc. ++ It should give the best performance for most workloads. But other ++ choices may have better performance for a particular workload or on ++ the hardware which wasn't available when the selection was made. ++ The environment variable: ++ ++ GLIBC_TUNABLES=glibc.cpu.hwcaps=-xxx,yyy,-zzz,.... ++ ++ can be used to enable CPU/ARCH feature yyy, disable CPU/ARCH feature ++ yyy and zzz, where the feature name is case-sensitive and has to ++ match the ones in cpu-features.h. It can be used by glibc developers ++ to tune for a new processor or override the IFUNC selection to ++ improve performance for a particular workload. ++ ++ NOTE: the IFUNC selection may change over time. Please check all ++ multiarch implementations when experimenting. */ ++ ++ struct tunable_str_comma_state_t ts; ++ tunable_str_comma_init (&ts, valp); ++ ++ struct tunable_str_comma_t n; ++ while (tunable_str_comma_next (&ts, &n)) ++ { ++ switch (n.len) ++ { ++ default: ++ break; ++ case 3: ++ { ++ CHECK_GLIBC_IFUNC_CPU (n, LSX, 3); ++ CHECK_GLIBC_IFUNC_CPU (n, UAL, 3); ++ } ++ break; ++ case 4: ++ { ++ CHECK_GLIBC_IFUNC_CPU (n, LASX, 4); ++ } ++ break; ++ } ++ } ++ ++ /* Ensure that the user has not enabled any unsupported features. */ ++ GLRO(dl_larch_cpu_features).hwcap &= GLRO(dl_hwcap); ++} +diff --git a/sysdeps/loongarch/dl-get-cpu-features.c b/sysdeps/loongarch/dl-get-cpu-features.c +new file mode 100644 +index 00000000..3dcecefb +--- /dev/null ++++ b/sysdeps/loongarch/dl-get-cpu-features.c +@@ -0,0 +1,25 @@ ++/* Define _dl_larch_get_cpu_features. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <https://www.gnu.org/licenses/>. */ ++ ++ ++#include <ldsodefs.h> ++ ++const struct cpu_features * ++_dl_larch_get_cpu_features (void) ++{ ++ return &GLRO(dl_larch_cpu_features); ++} +diff --git a/sysdeps/loongarch/dl-machine.h b/sysdeps/loongarch/dl-machine.h +index 57913cef..befb29a3 100644 +--- a/sysdeps/loongarch/dl-machine.h ++++ b/sysdeps/loongarch/dl-machine.h +@@ -29,6 +29,8 @@ + #include <dl-static-tls.h> + #include <dl-machine-rel.h> + ++#include <cpu-features.c> ++ + #ifndef _RTLD_PROLOGUE + # define _RTLD_PROLOGUE(entry) \ + ".globl\t" __STRING (entry) "\n\t" \ +@@ -53,7 +55,23 @@ + #define ELF_MACHINE_NO_REL 1 + #define ELF_MACHINE_NO_RELA 0 + +-/* Return nonzero iff ELF header is compatible with the running host. */ ++#define DL_PLATFORM_INIT dl_platform_init () ++ ++static inline void __attribute__ ((unused)) ++dl_platform_init (void) ++{ ++ if (GLRO(dl_platform) != NULL && *GLRO(dl_platform) == '\0') ++ /* Avoid an empty string which would disturb us. */ ++ GLRO(dl_platform) = NULL; ++ ++#ifdef SHARED ++ /* init_cpu_features has been called early from __libc_start_main in ++ static executable. */ ++ init_cpu_features (&GLRO(dl_larch_cpu_features)); ++#endif ++} ++ ++/* Return nonzero if ELF header is compatible with the running host. */ + static inline int + elf_machine_matches_host (const ElfW (Ehdr) *ehdr) + { +@@ -290,9 +308,9 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope, + if (profile != 0) + { + #if !defined __loongarch_soft_float +- if (SUPPORT_LASX) ++ if (RTLD_SUPPORT_LASX) + gotplt0 = (ElfW(Addr)) &_dl_runtime_profile_lasx; +- else if (SUPPORT_LSX) ++ else if (RTLD_SUPPORT_LSX) + gotplt0 = (ElfW(Addr)) &_dl_runtime_profile_lsx; + else + #endif +@@ -310,9 +328,9 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope, + indicated by the offset on the stack, and then jump to + the resolved address. */ + #if !defined __loongarch_soft_float +- if (SUPPORT_LASX) ++ if (RTLD_SUPPORT_LASX) + gotplt0 = (ElfW(Addr)) &_dl_runtime_resolve_lasx; +- else if (SUPPORT_LSX) ++ else if (RTLD_SUPPORT_LSX) + gotplt0 = (ElfW(Addr)) &_dl_runtime_resolve_lsx; + else + #endif +diff --git a/sysdeps/loongarch/dl-tunables.list b/sysdeps/loongarch/dl-tunables.list +new file mode 100644 +index 00000000..00869a9f +--- /dev/null ++++ b/sysdeps/loongarch/dl-tunables.list +@@ -0,0 +1,25 @@ ++# LoongArch specific tunables. ++# Copyright (C) 2024 Free Software Foundation, Inc. ++# This file is part of the GNU C Library. ++ ++# The GNU C Library is free software; you can redistribute it and/or ++# modify it under the terms of the GNU Lesser General Public ++# License as published by the Free Software Foundation; either ++# version 2.1 of the License, or (at your option) any later version. ++ ++# The GNU C Library is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# Lesser General Public License for more details. ++ ++# You should have received a copy of the GNU Lesser General Public ++# License along with the GNU C Library; if not, see ++# <http://www.gnu.org/licenses/>. ++ ++glibc { ++ cpu { ++ hwcaps { ++ type: STRING ++ } ++ } ++} +diff --git a/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h b/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h +index e2723873..603d9ec2 100644 +--- a/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h ++++ b/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h +@@ -19,6 +19,9 @@ + #ifndef _DL_IFUNC_GENERIC_H + #define _DL_IFUNC_GENERIC_H + +-asm ("memset = __memset_aligned"); ++#ifndef SHARED ++ asm ("memset = __memset_aligned"); ++ asm ("memcmp = __memcmp_aligned"); ++#endif + + #endif +diff --git a/sysdeps/loongarch/tst-hwcap-tunables.c b/sysdeps/loongarch/tst-hwcap-tunables.c +new file mode 100644 +index 00000000..fe1b95a8 +--- /dev/null ++++ b/sysdeps/loongarch/tst-hwcap-tunables.c +@@ -0,0 +1,136 @@ ++/* Tests for LoongArch GLIBC_TUNABLES=glibc.cpu.hwcaps filter. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++#include <array_length.h> ++#include <getopt.h> ++#include <ifunc-impl-list.h> ++#include <spawn.h> ++#include <stdio.h> ++#include <stdlib.h> ++#include <string.h> ++#include <support/check.h> ++#include <support/support.h> ++#include <support/xunistd.h> ++#include <sys/auxv.h> ++#include <sys/wait.h> ++ ++/* Nonzero if the program gets called via `exec'. */ ++#define CMDLINE_OPTIONS \ ++ { "restart", no_argument, &restart, 1 }, \ ++ { "enable", no_argument, &enable, 1 }, ++static int restart; ++static int enable; ++ ++/* Hold the four initial argument used to respawn the process, plus the extra ++ '--direct', '--restart', and the function to check. */ ++static char *spargs9; ++static int fc; ++ ++/* Called on process re-execution. */ ++_Noreturn static void ++handle_restart (int argc, char *argv) ++{ ++ TEST_VERIFY_EXIT (argc == 1); ++ const char *funcname = argv0; ++ ++ struct libc_ifunc_impl impls32; ++ int cnt = __libc_ifunc_impl_list ("memcpy", impls, array_length (impls)); ++ if (cnt == 0) ++ _exit (EXIT_SUCCESS); ++ TEST_VERIFY_EXIT (cnt >= 1); ++ for (int i = 0; i < cnt; i++) ++ { ++ if (strcmp (implsi.name, funcname) == 0) ++ { ++ if (enable && implsi.usable != true) ++ FAIL_EXIT1 ("FAIL: %s ifunc selection is not enabled.\n", funcname); ++ else if (!enable && implsi.usable != false) ++ FAIL_EXIT1 ("FAIL: %s ifunc selection is not disabled.\n", funcname); ++ break; ++ } ++ } ++ ++ _exit (EXIT_SUCCESS); ++} ++ ++static void ++run_test (const char *filter, const char *funcname, int disable) ++{ ++ if (disable) ++ printf ("info: checking filter %s (expect %s ifunc " ++ "selection to be disabled)\n", filter, funcname); ++ else ++ { ++ printf ("info: checking filter %s (expect %s ifunc " ++ "selection to be enabled)\n", filter, funcname); ++ spargsfc++ = (char *) "--enable"; ++ } ++ ++ char *tunable = xasprintf ("GLIBC_TUNABLES=glibc.cpu.hwcaps=%s", filter); ++ char *const newenvs = { (char*) tunable, NULL }; ++ spargsfc = (char *) funcname; ++ ++ pid_t pid; ++ TEST_COMPARE (posix_spawn (&pid, spargs0, NULL, NULL, spargs, newenvs), 0); ++ int status; ++ TEST_COMPARE (xwaitpid (pid, &status, 0), pid); ++ TEST_VERIFY (WIFEXITED (status)); ++ TEST_VERIFY (!WIFSIGNALED (status)); ++ TEST_COMPARE (WEXITSTATUS (status), 0); ++ ++ if (!disable) ++ fc--; ++ free (tunable); ++} ++ ++static int ++do_test (int argc, char *argv) ++{ ++ if (restart) ++ handle_restart (argc - 1, &argv1); ++ ++ TEST_VERIFY_EXIT (argc == 2 || argc == 5); ++ ++ int i; ++ for (i = 0; i < argc - 1; i++) ++ spargsi = argvi + 1; ++ spargsi++ = (char *) "--direct"; ++ spargsi++ = (char *) "--restart"; ++ fc = i++; ++ spargsi = NULL; ++ ++ unsigned long int hwcap = getauxval (AT_HWCAP); ++ ++ if (hwcap & HWCAP_LOONGARCH_LASX) ++ run_test ("-LASX", "__memcpy_lasx", 1); ++ if (hwcap & HWCAP_LOONGARCH_LSX) ++ run_test ("-LSX", "__memcpy_lsx", 1); ++ if (hwcap & HWCAP_LOONGARCH_UAL) ++ run_test ("-UAL", "__memcpy_unaligned", 1); ++ ++ /* __memcpy_aligned is the default ifunc selection and will be ++ * always enabled. */ ++ run_test ("-LASX,-LSX,-UAL", "__memcpy_aligned", 0); ++ run_test ("-LASX,-LSX", "__memcpy_aligned", 0); ++ run_test ("-LASX", "__memcpy_aligned", 0); ++ ++ return 0; ++} ++ ++#define TEST_FUNCTION_ARGV do_test ++#include <support/test-driver.c> +diff --git a/sysdeps/unix/sysv/linux/loongarch/cpu-features.c b/sysdeps/unix/sysv/linux/loongarch/cpu-features.c +new file mode 100644 +index 00000000..ba6201ad +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/cpu-features.c +@@ -0,0 +1,30 @@ ++/* Initialize CPU feature data. LoongArch64 version. ++ This file is part of the GNU C Library. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++#include <cpu-features.h> ++#include <elf/dl-hwcaps.h> ++#include <elf/dl-tunables.h> ++extern void TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *) attribute_hidden; ++ ++static inline void ++init_cpu_features (struct cpu_features *cpu_features) ++{ ++ GLRO(dl_larch_cpu_features).hwcap = GLRO(dl_hwcap); ++ TUNABLE_GET (glibc, cpu, hwcaps, tunable_val_t *, ++ TUNABLE_CALLBACK (set_hwcaps)); ++} +diff --git a/sysdeps/unix/sysv/linux/loongarch/cpu-features.h b/sysdeps/unix/sysv/linux/loongarch/cpu-features.h +index d1a280a5..b1fa4b7b 100644 +--- a/sysdeps/unix/sysv/linux/loongarch/cpu-features.h ++++ b/sysdeps/unix/sysv/linux/loongarch/cpu-features.h +@@ -19,12 +19,23 @@ + #ifndef _CPU_FEATURES_LOONGARCH64_H + #define _CPU_FEATURES_LOONGARCH64_H + ++#include <stdint.h> + #include <sys/auxv.h> + +-#define SUPPORT_UAL (GLRO (dl_hwcap) & HWCAP_LOONGARCH_UAL) +-#define SUPPORT_LSX (GLRO (dl_hwcap) & HWCAP_LOONGARCH_LSX) +-#define SUPPORT_LASX (GLRO (dl_hwcap) & HWCAP_LOONGARCH_LASX) ++struct cpu_features ++{ ++ uint64_t hwcap; ++}; + ++/* Get a pointer to the CPU features structure. */ ++extern const struct cpu_features * ++_dl_larch_get_cpu_features (void) __attribute__ ((pure)); ++ ++#define SUPPORT_UAL (GLRO (dl_larch_cpu_features).hwcap & HWCAP_LOONGARCH_UAL) ++#define SUPPORT_LSX (GLRO (dl_larch_cpu_features).hwcap & HWCAP_LOONGARCH_LSX) ++#define SUPPORT_LASX (GLRO (dl_larch_cpu_features).hwcap & HWCAP_LOONGARCH_LASX) ++#define RTLD_SUPPORT_LSX (GLRO (dl_hwcap) & HWCAP_LOONGARCH_LSX) ++#define RTLD_SUPPORT_LASX (GLRO (dl_hwcap) & HWCAP_LOONGARCH_LASX) + #define INIT_ARCH() + + #endif /* _CPU_FEATURES_LOONGARCH64_H */ +diff --git a/sysdeps/unix/sysv/linux/loongarch/dl-procinfo.c b/sysdeps/unix/sysv/linux/loongarch/dl-procinfo.c +new file mode 100644 +index 00000000..5e056a19 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/dl-procinfo.c +@@ -0,0 +1,60 @@ ++/* Data for LoongArch64 version of processor capability information. ++ Linux version. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++/* If anything should be added here check whether the size of each string ++ is still ok with the given array size. ++ ++ All the #ifdefs in the definitions are quite irritating but ++ necessary if we want to avoid duplicating the information. There ++ are three different modes: ++ ++ - PROCINFO_DECL is defined. This means we are only interested in ++ declarations. ++ ++ - PROCINFO_DECL is not defined: ++ ++ + if SHARED is defined the file is included in an array ++ initializer. The .element = { ... } syntax is needed. ++ ++ + if SHARED is not defined a normal array initialization is ++ needed. ++ */ ++ ++#ifndef PROCINFO_CLASS ++# define PROCINFO_CLASS ++#endif ++ ++#if !IS_IN (ldconfig) ++# if !defined PROCINFO_DECL && defined SHARED ++ ._dl_larch_cpu_features ++# else ++PROCINFO_CLASS struct cpu_features _dl_larch_cpu_features ++# endif ++# ifndef PROCINFO_DECL ++= { } ++# endif ++# if !defined SHARED || defined PROCINFO_DECL ++; ++# else ++, ++# endif ++#endif ++ ++#undef PROCINFO_DECL ++#undef PROCINFO_CLASS +diff --git a/sysdeps/unix/sysv/linux/loongarch/dl-sysdep.c b/sysdeps/unix/sysv/linux/loongarch/dl-sysdep.c +new file mode 100644 +index 00000000..30b84f19 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/dl-sysdep.c +@@ -0,0 +1,21 @@ ++/* Operating system support for run-time dynamic linker. LoongArch version. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++#include <config.h> ++#include <sysdeps/loongarch/cpu-tunables.c> ++#include <sysdeps/unix/sysv/linux/dl-sysdep.c> +diff --git a/sysdeps/unix/sysv/linux/loongarch/libc-start.c b/sysdeps/unix/sysv/linux/loongarch/libc-start.c +new file mode 100644 +index 00000000..e545f7f1 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/libc-start.c +@@ -0,0 +1,34 @@ ++/* Override csu/libc-start.c on LoongArch64. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++#ifndef SHARED ++ ++/* Mark symbols hidden in static PIE for early self relocation to work. */ ++#if BUILD_PIE_DEFAULT ++# pragma GCC visibility push (hidden) ++#endif ++ ++#include <ldsodefs.h> ++#include <cpu-features.c> ++ ++extern struct cpu_features _dl_larch_cpu_features; ++ ++#define ARCH_INIT_CPU_FEATURES() init_cpu_features (&_dl_larch_cpu_features) ++ ++#endif ++#include <csu/libc-start.c> +-- +2.43.0 +
View file
_service:tar_scm:0004-LoongArch-Add-support-for-TLS-Descriptors.patch
Added
@@ -0,0 +1,1312 @@ +From 9b2057696dae6abc6c69c124ff3325b0e1a48422 Mon Sep 17 00:00:00 2001 +From: mengqinggang <mengqinggang@loongson.cn> +Date: Wed, 8 May 2024 10:06:15 +0800 +Subject: PATCH 04/15 LoongArch: Add support for TLS Descriptors + +This is mostly based on AArch64 and RISC-V implementation. + +Add R_LARCH_TLS_DESC32 and R_LARCH_TLS_DESC64 relocations. + +For _dl_tlsdesc_dynamic function slow path, temporarily save and restore +all vector registers. +--- + config.h.in | 3 + + elf/elf.h | 2 + + sysdeps/loongarch/Makefile | 34 ++- + sysdeps/loongarch/configure | 33 +++ + sysdeps/loongarch/configure.ac | 16 ++ + sysdeps/loongarch/dl-machine.h | 52 +++- + sysdeps/loongarch/dl-tls.h | 9 +- + sysdeps/loongarch/dl-tlsdesc.S | 436 ++++++++++++++++++++++++++++++ + sysdeps/loongarch/dl-tlsdesc.h | 49 ++++ + sysdeps/loongarch/linkmap.h | 3 +- + sysdeps/loongarch/preconfigure | 1 + + sysdeps/loongarch/sys/asm.h | 1 + + sysdeps/loongarch/sys/regdef.h | 1 + + sysdeps/loongarch/tlsdesc.c | 39 +++ + sysdeps/loongarch/tlsdesc.sym | 28 ++ + sysdeps/loongarch/tst-gnu2-tls2.h | 377 ++++++++++++++++++++++++++ + 16 files changed, 1076 insertions(+), 8 deletions(-) + create mode 100644 sysdeps/loongarch/dl-tlsdesc.S + create mode 100644 sysdeps/loongarch/dl-tlsdesc.h + create mode 100644 sysdeps/loongarch/tlsdesc.c + create mode 100644 sysdeps/loongarch/tlsdesc.sym + create mode 100644 sysdeps/loongarch/tst-gnu2-tls2.h + +diff --git a/config.h.in b/config.h.in +index 44a34072..7b5283ba 100644 +--- a/config.h.in ++++ b/config.h.in +@@ -141,6 +141,9 @@ + /* LOONGARCH floating-point ABI for ld.so. */ + #undef LOONGARCH_ABI_FRLEN + ++/* Define whether compiler support vector. */ ++#undef HAVE_LOONGARCH_VEC_COM ++ + /* Linux specific: minimum supported kernel version. */ + #undef __LINUX_KERNEL_VERSION + +diff --git a/elf/elf.h b/elf/elf.h +index 3dbc7c0f..a4695042 100644 +--- a/elf/elf.h ++++ b/elf/elf.h +@@ -4125,6 +4125,8 @@ enum + #define R_LARCH_TLS_TPREL32 10 + #define R_LARCH_TLS_TPREL64 11 + #define R_LARCH_IRELATIVE 12 ++#define R_LARCH_TLS_DESC32 13 ++#define R_LARCH_TLS_DESC64 14 + + /* Reserved for future relocs that the dynamic linker must understand. */ + +diff --git a/sysdeps/loongarch/Makefile b/sysdeps/loongarch/Makefile +index 446bda65..a4ee915e 100644 +--- a/sysdeps/loongarch/Makefile ++++ b/sysdeps/loongarch/Makefile +@@ -1,5 +1,7 @@ + ifeq ($(subdir),misc) +-sysdep_headers += sys/asm.h ++sysdep_headers += \ ++ sys/asm.h \ ++ # sysdep_headers + + tests += \ + tst-hwcap-tunables \ +@@ -9,21 +11,45 @@ tst-hwcap-tunables-ARGS = -- $(host-test-program-cmd) + endif + + ifeq ($(subdir),elf) +-gen-as-const-headers += dl-link.sym ++sysdep-dl-routines += \ ++ dl-tlsdesc \ ++ tlsdesc \ ++ # sysdep-dl-routines ++ ++gen-as-const-headers += \ ++ dl-link.sym \ ++ # gen-as-const-headers ++endif ++ ++ifeq ($(subdir),csu) ++gen-as-const-headers += \ ++ tlsdesc.sym \ ++ # gen-as-const-headers + endif + + ifeq ($(subdir),elf) + sysdep-dl-routines += \ + dl-get-cpu-features \ + # sysdep-dl-routines ++ ++# Disable the compiler from using LSX for TLS descriptor tests, or storing into ++# 16B TLS variable may clobber FP/vector registers and prevent us from checking ++# their contents. ++CFLAGS-tst-gnu2-tls2mod0.c += -mno-lsx ++CFLAGS-tst-gnu2-tls2mod1.c += -mno-lsx ++CFLAGS-tst-gnu2-tls2mod2.c += -mno-lsx + endif + + # LoongArch's assembler also needs to know about PIC as it changes the + # definition of some assembler macros. +-ASFLAGS-.os += $(pic-ccflag) ++ASFLAGS-.os += \ ++ $(pic-ccflag) \ ++ # ASFLAGS-.os + + # All the objects in lib*_nonshared.a need to be compiled with medium code + # model or large applications may fail to link. + ifeq (yes,$(have-cmodel-medium)) +-CFLAGS-.oS += -mcmodel=medium ++CFLAGS-.oS += \ ++ -mcmodel=medium \ ++ # CFLAGS-.oS + endif +diff --git a/sysdeps/loongarch/configure b/sysdeps/loongarch/configure +index 4df1c12e..a133821f 100644 +--- a/sysdeps/loongarch/configure ++++ b/sysdeps/loongarch/configure +@@ -132,3 +132,36 @@ if test $libc_cv_loongarch_vec_asm = no; then + as_fn_error $? "binutils version is too old, use 2.41 or newer version" "$LINENO" 5 + fi + ++ ++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for vector support in compiler" >&5 ++printf %s "checking for vector support in compiler... " >&6; } ++if test ${libc_cv_loongarch_vec_com+y} ++then : ++ printf %s "(cached) " >&6 ++else $as_nop ++ ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++void foo (void) ++{ ++ asm volatile ("vldi \$vr0, 1" ::: "\$vr0"); ++ asm volatile ("xvldi \$xr0, 1" ::: "\$xr0"); ++} ++ ++_ACEOF ++if ac_fn_c_try_compile "$LINENO" ++then : ++ libc_cv_loongarch_vec_com=yes ++else $as_nop ++ libc_cv_loongarch_vec_com=no ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ++fi ++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_loongarch_vec_com" >&5 ++printf "%s\n" "$libc_cv_loongarch_vec_com" >&6; } ++if test "$libc_cv_loongarch_vec_com" = yes ; ++then ++ printf "%s\n" "#define HAVE_LOONGARCH_VEC_COM 1" >>confdefs.h ++ ++fi +diff --git a/sysdeps/loongarch/configure.ac b/sysdeps/loongarch/configure.ac +index 0219c66c..9b1cf26e 100644 +--- a/sysdeps/loongarch/configure.ac ++++ b/sysdeps/loongarch/configure.ac +@@ -77,3 +77,19 @@ rm -f conftest*) + if test $libc_cv_loongarch_vec_asm = no; then + AC_MSG_ERROR(binutils version is too old, use 2.41 or newer version) + fi ++ ++AC_CACHE_CHECK(for vector support in compiler, ++ libc_cv_loongarch_vec_com, ++AC_COMPILE_IFELSE(AC_LANG_SOURCE( ++void foo (void) ++{ ++ asm volatile ("vldi $vr0, 1" ::: "$vr0"); ++ asm volatile ("xvldi $xr0, 1" ::: "$xr0"); ++} ++), ++ libc_cv_loongarch_vec_com=yes, ++ libc_cv_loongarch_vec_com=no)) ++if test "$libc_cv_loongarch_vec_com" = yes ; ++then ++ AC_DEFINE(HAVE_LOONGARCH_VEC_COM) ++fi +diff --git a/sysdeps/loongarch/dl-machine.h b/sysdeps/loongarch/dl-machine.h +index befb29a3..222d51a8 100644 +--- a/sysdeps/loongarch/dl-machine.h ++++ b/sysdeps/loongarch/dl-machine.h +@@ -25,7 +25,7 @@ + #include <entry.h> + #include <elf/elf.h> + #include <sys/asm.h> +-#include <dl-tls.h> ++#include <dl-tlsdesc.h> + #include <dl-static-tls.h> + #include <dl-machine-rel.h> + +@@ -205,6 +205,36 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope, + *addr_field = TLS_TPREL_VALUE (sym_map, sym) + reloc->r_addend; + break; + ++ case __WORDSIZE == 64 ? R_LARCH_TLS_DESC64 : R_LARCH_TLS_DESC32: ++ { ++ struct tlsdesc volatile *td = (struct tlsdesc volatile *)addr_field; ++ if (sym == NULL) ++ { ++ td->arg = (void*)reloc->r_addend; ++ td->entry = _dl_tlsdesc_undefweak; ++ } ++ else ++ { ++# ifndef SHARED ++ CHECK_STATIC_TLS (map, sym_map); ++# else ++ if (!TRY_STATIC_TLS (map, sym_map)) ++ { ++ td->arg = _dl_make_tlsdesc_dynamic (sym_map, ++ sym->st_value + reloc->r_addend); ++ td->entry = _dl_tlsdesc_dynamic; ++ } ++ else ++# endif ++ { ++ td->arg = (void *)(TLS_TPREL_VALUE (sym_map, sym) ++ + reloc->r_addend); ++ td->entry = _dl_tlsdesc_return; ++ } ++ } ++ break; ++ } ++ + case R_LARCH_COPY: + { + if (sym == NULL) +@@ -273,6 +303,26 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope, + else + *reloc_addr = map->l_mach.plt; + } ++ else if (__glibc_likely (r_type == R_LARCH_TLS_DESC64) ++ || __glibc_likely (r_type == R_LARCH_TLS_DESC32)) ++ { ++ const Elf_Symndx symndx = ELFW (R_SYM) (reloc->r_info); ++ const ElfW (Sym) *symtab = (const void *)D_PTR (map, l_infoDT_SYMTAB); ++ const ElfW (Sym) *sym = &symtabsymndx; ++ const struct r_found_version *version = NULL; ++ ++ if (map->l_infoVERSYMIDX (DT_VERSYM) != NULL) ++ { ++ const ElfW (Half) *vernum = (const void *)D_PTR (map, ++ l_infoVERSYMIDX (DT_VERSYM)); ++ version = &map->l_versionsvernumsymndx & 0x7fff; ++ } ++ ++ /* Always initialize TLS descriptors completely, because lazy ++ initialization requires synchronization at every TLS access. */ ++ elf_machine_rela (map, scope, reloc, sym, version, reloc_addr, ++ skip_ifunc); ++ } + else + _dl_reloc_bad_type (map, r_type, 1); + } +diff --git a/sysdeps/loongarch/dl-tls.h b/sysdeps/loongarch/dl-tls.h +index a551594b..1ca37648 100644 +--- a/sysdeps/loongarch/dl-tls.h ++++ b/sysdeps/loongarch/dl-tls.h +@@ -16,6 +16,9 @@ + License along with the GNU C Library. If not, see + <https://www.gnu.org/licenses/>. */ + ++#ifndef _DL_TLS_H ++#define _DL_TLS_H ++ + /* Type used for the representation of TLS information in the GOT. */ + typedef struct + { +@@ -23,6 +26,8 @@ typedef struct + unsigned long int ti_offset; + } tls_index; + ++extern void *__tls_get_addr (tls_index *ti); ++ + /* The thread pointer points to the first static TLS block. */ + #define TLS_TP_OFFSET 0 + +@@ -37,10 +42,10 @@ typedef struct + /* Compute the value for a DTPREL reloc. */ + #define TLS_DTPREL_VALUE(sym) ((sym)->st_value - TLS_DTV_OFFSET) + +-extern void *__tls_get_addr (tls_index *ti); +- + #define GET_ADDR_OFFSET (ti->ti_offset + TLS_DTV_OFFSET) + #define __TLS_GET_ADDR(__ti) (__tls_get_addr (__ti) - TLS_DTV_OFFSET) + + /* Value used for dtv entries for which the allocation is delayed. */ + #define TLS_DTV_UNALLOCATED ((void *) -1l) ++ ++#endif +diff --git a/sysdeps/loongarch/dl-tlsdesc.S b/sysdeps/loongarch/dl-tlsdesc.S +new file mode 100644 +index 00000000..15d5fa1c +--- /dev/null ++++ b/sysdeps/loongarch/dl-tlsdesc.S +@@ -0,0 +1,436 @@ ++/* Thread-local storage handling in the ELF dynamic linker. ++ LoongArch version. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <https://www.gnu.org/licenses/>. */ ++ ++#include <sysdep.h> ++#include <tls.h> ++#include "tlsdesc.h" ++ ++ .text ++ ++ /* Compute the thread pointer offset for symbols in the static ++ TLS block. The offset is the same for all threads. ++ Prototype: ++ _dl_tlsdesc_return (tlsdesc *); */ ++ .hidden _dl_tlsdesc_return ++ .global _dl_tlsdesc_return ++ .type _dl_tlsdesc_return,%function ++ cfi_startproc ++ .align 2 ++_dl_tlsdesc_return: ++ REG_L a0, a0, 8 ++ RET ++ cfi_endproc ++ .size _dl_tlsdesc_return, .-_dl_tlsdesc_return ++ ++ /* Handler for undefined weak TLS symbols. ++ Prototype: ++ _dl_tlsdesc_undefweak (tlsdesc *); ++ ++ The second word of the descriptor contains the addend. ++ Return the addend minus the thread pointer. This ensures ++ that when the caller adds on the thread pointer it gets back ++ the addend. */ ++ .hidden _dl_tlsdesc_undefweak ++ .global _dl_tlsdesc_undefweak ++ .type _dl_tlsdesc_undefweak,%function ++ cfi_startproc ++ .align 2 ++_dl_tlsdesc_undefweak: ++ REG_L a0, a0, 8 ++ sub.d a0, a0, tp ++ RET ++ cfi_endproc ++ .size _dl_tlsdesc_undefweak, .-_dl_tlsdesc_undefweak ++ ++ ++#ifdef SHARED ++ ++#define FRAME_SIZE (-((-14 * SZREG) & ALMASK)) ++#define FRAME_SIZE_LSX (-((-32 * SZVREG) & ALMASK)) ++#define FRAME_SIZE_LASX (-((-32 * SZXREG) & ALMASK)) ++#define FRAME_SIZE_FLOAT (-((-24 * SZFREG) & ALMASK)) ++ ++ /* Handler for dynamic TLS symbols. ++ Prototype: ++ _dl_tlsdesc_dynamic (tlsdesc *) ; ++ ++ The second word of the descriptor points to a ++ tlsdesc_dynamic_arg structure. ++ ++ Returns the offset between the thread pointer and the ++ object referenced by the argument. ++ ++ ptrdiff_t ++ _dl_tlsdesc_dynamic (struct tlsdesc *tdp) ++ { ++ struct tlsdesc_dynamic_arg *td = tdp->arg; ++ dtv_t *dtv = *(dtv_t **)((char *)__thread_pointer - TCBHEAD_DTV); ++ if (__glibc_likely (td->gen_count <= dtv0.counter ++ && (dtvtd->tlsinfo.ti_module.pointer.val ++ != TLS_DTV_UNALLOCATED), ++ 1)) ++ return dtvtd->tlsinfo.ti_module.pointer.val ++ + td->tlsinfo.ti_offset ++ - __thread_pointer; ++ ++ return ___tls_get_addr (&td->tlsinfo) - __thread_pointer; ++ } */ ++ .hidden _dl_tlsdesc_dynamic ++ .global _dl_tlsdesc_dynamic ++ .type _dl_tlsdesc_dynamic,%function ++ cfi_startproc ++ .align 2 ++_dl_tlsdesc_dynamic: ++ /* Save just enough registers to support fast path, if we fall ++ into slow path we will save additional registers. */ ++ ADDI sp, sp, -24 ++ REG_S t0, sp, 0 ++ REG_S t1, sp, 8 ++ REG_S t2, sp, 16 ++ ++/* Runtime Storage Layout of Thread-Local Storage ++ TP point to the start of TLS block. ++ ++ dtv ++Low address TCB ----------------> dtv0(counter) ++ TP --> static_block0 <----- dtv1 ++ static_block1 <----- dtv2 ++ static_block2 <----- dtv3 ++ dynamic_block0 <----- dtv4 ++Hign address dynamic_block1 <----- dtv5 */ ++ ++ REG_L t0, tp, -SIZE_OF_TCB /* t0 = dtv */ ++ REG_L a0, a0, TLSDESC_ARG /* a0(td) = tdp->arg */ ++ REG_L t1, a0, TLSDESC_GEN_COUNT /* t1 = td->gen_count */ ++ REG_L t2, t0, DTV_COUNTER /* t2 = dtv0.counter */ ++ /* If dtv0.counter < td->gen_count, goto slow path. */ ++ bltu t2, t1, .Lslow ++ ++ REG_L t1, a0, TLSDESC_MODID /* t1 = td->tlsinfo.ti_module */ ++ /* t1 = t1 * sizeof(dtv_t) = t1 * (2 * sizeof(void*)) */ ++ slli.d t1, t1, 4 ++ add.d t1, t1, t0 /* t1 = dtvtd->tlsinfo.ti_module */ ++ REG_L t1, t1, 0 /* t1 = dtvtd->tlsinfo.ti_module.pointer.val */ ++ li.d t2, TLS_DTV_UNALLOCATED ++ /* If dtvtd->tlsinfo.ti_module.pointer.val is TLS_DTV_UNALLOCATED, ++ goto slow path. */ ++ beq t1, t2, .Lslow ++ ++ REG_L t2, a0, TLSDESC_MODOFF /* t2 = td->tlsinfo.ti_offset */ ++ /* dtvtd->tlsinfo.ti_module.pointer.val + td->tlsinfo.ti_offset */ ++ add.d a0, t1, t2 ++.Lret: ++ sub.d a0, a0, tp ++ REG_L t0, sp, 0 ++ REG_L t1, sp, 8 ++ REG_L t2, sp, 16 ++ ADDI sp, sp, 24 ++ RET ++ ++.Lslow: ++ /* This is the slow path. We need to call __tls_get_addr() which ++ means we need to save and restore all the register that the ++ callee will trash. */ ++ ++ /* Save the remaining registers that we must treat as caller save. */ ++ ADDI sp, sp, -FRAME_SIZE ++ REG_S ra, sp, 0 * SZREG ++ REG_S a1, sp, 1 * SZREG ++ REG_S a2, sp, 2 * SZREG ++ REG_S a3, sp, 3 * SZREG ++ REG_S a4, sp, 4 * SZREG ++ REG_S a5, sp, 5 * SZREG ++ REG_S a6, sp, 6 * SZREG ++ REG_S a7, sp, 7 * SZREG ++ REG_S t3, sp, 8 * SZREG ++ REG_S t4, sp, 9 * SZREG ++ REG_S t5, sp, 10 * SZREG ++ REG_S t6, sp, 11 * SZREG ++ REG_S t7, sp, 12 * SZREG ++ REG_S t8, sp, 13 * SZREG ++ ++#ifndef __loongarch_soft_float ++ ++ /* Save fcsr0 register. ++ Only one physical fcsr0 register, fcsr1-fcsr3 are aliases ++ of some fields in fcsr0. */ ++ ADDI sp, sp, -SZFCSREG ++ movfcsr2gr t0, fcsr0 ++ st.w t0, sp, 0 ++ ++ /* Whether support LASX. */ ++ la.global t0, _rtld_global_ro ++ REG_L t0, t0, GLRO_DL_HWCAP_OFFSET ++ andi t0, t0, HWCAP_LOONGARCH_LASX ++ beqz t0, .Llsx ++ ++ /* Save 256-bit vector registers. ++ FIXME: Without vector ABI, save all vector registers. */ ++ ADDI sp, sp, -FRAME_SIZE_LASX ++ xvst xr0, sp, 0*SZXREG ++ xvst xr1, sp, 1*SZXREG ++ xvst xr2, sp, 2*SZXREG ++ xvst xr3, sp, 3*SZXREG ++ xvst xr4, sp, 4*SZXREG ++ xvst xr5, sp, 5*SZXREG ++ xvst xr6, sp, 6*SZXREG ++ xvst xr7, sp, 7*SZXREG ++ xvst xr8, sp, 8*SZXREG ++ xvst xr9, sp, 9*SZXREG ++ xvst xr10, sp, 10*SZXREG ++ xvst xr11, sp, 11*SZXREG ++ xvst xr12, sp, 12*SZXREG ++ xvst xr13, sp, 13*SZXREG ++ xvst xr14, sp, 14*SZXREG ++ xvst xr15, sp, 15*SZXREG ++ xvst xr16, sp, 16*SZXREG ++ xvst xr17, sp, 17*SZXREG ++ xvst xr18, sp, 18*SZXREG ++ xvst xr19, sp, 19*SZXREG ++ xvst xr20, sp, 20*SZXREG ++ xvst xr21, sp, 21*SZXREG ++ xvst xr22, sp, 22*SZXREG ++ xvst xr23, sp, 23*SZXREG ++ xvst xr24, sp, 24*SZXREG ++ xvst xr25, sp, 25*SZXREG ++ xvst xr26, sp, 26*SZXREG ++ xvst xr27, sp, 27*SZXREG ++ xvst xr28, sp, 28*SZXREG ++ xvst xr29, sp, 29*SZXREG ++ xvst xr30, sp, 30*SZXREG ++ xvst xr31, sp, 31*SZXREG ++ b .Ltga ++ ++.Llsx: ++ /* Whether support LSX. */ ++ andi t0, t0, HWCAP_LOONGARCH_LSX ++ beqz t0, .Lfloat ++ ++ /* Save 128-bit vector registers. */ ++ ADDI sp, sp, -FRAME_SIZE_LSX ++ vst vr0, sp, 0*SZVREG ++ vst vr1, sp, 1*SZVREG ++ vst vr2, sp, 2*SZVREG ++ vst vr3, sp, 3*SZVREG ++ vst vr4, sp, 4*SZVREG ++ vst vr5, sp, 5*SZVREG ++ vst vr6, sp, 6*SZVREG ++ vst vr7, sp, 7*SZVREG ++ vst vr8, sp, 8*SZVREG ++ vst vr9, sp, 9*SZVREG ++ vst vr10, sp, 10*SZVREG ++ vst vr11, sp, 11*SZVREG ++ vst vr12, sp, 12*SZVREG ++ vst vr13, sp, 13*SZVREG ++ vst vr14, sp, 14*SZVREG ++ vst vr15, sp, 15*SZVREG ++ vst vr16, sp, 16*SZVREG ++ vst vr17, sp, 17*SZVREG ++ vst vr18, sp, 18*SZVREG ++ vst vr19, sp, 19*SZVREG ++ vst vr20, sp, 20*SZVREG ++ vst vr21, sp, 21*SZVREG ++ vst vr22, sp, 22*SZVREG ++ vst vr23, sp, 23*SZVREG ++ vst vr24, sp, 24*SZVREG ++ vst vr25, sp, 25*SZVREG ++ vst vr26, sp, 26*SZVREG ++ vst vr27, sp, 27*SZVREG ++ vst vr28, sp, 28*SZVREG ++ vst vr29, sp, 29*SZVREG ++ vst vr30, sp, 30*SZVREG ++ vst vr31, sp, 31*SZVREG ++ b .Ltga ++ ++.Lfloat: ++ /* Save float registers. */ ++ ADDI sp, sp, -FRAME_SIZE_FLOAT ++ FREG_S fa0, sp, 0*SZFREG ++ FREG_S fa1, sp, 1*SZFREG ++ FREG_S fa2, sp, 2*SZFREG ++ FREG_S fa3, sp, 3*SZFREG ++ FREG_S fa4, sp, 4*SZFREG ++ FREG_S fa5, sp, 5*SZFREG ++ FREG_S fa6, sp, 6*SZFREG ++ FREG_S fa7, sp, 7*SZFREG ++ FREG_S ft0, sp, 8*SZFREG ++ FREG_S ft1, sp, 9*SZFREG ++ FREG_S ft2, sp, 10*SZFREG ++ FREG_S ft3, sp, 11*SZFREG ++ FREG_S ft4, sp, 12*SZFREG ++ FREG_S ft5, sp, 13*SZFREG ++ FREG_S ft6, sp, 14*SZFREG ++ FREG_S ft7, sp, 15*SZFREG ++ FREG_S ft8, sp, 16*SZFREG ++ FREG_S ft9, sp, 17*SZFREG ++ FREG_S ft10, sp, 18*SZFREG ++ FREG_S ft11, sp, 19*SZFREG ++ FREG_S ft12, sp, 20*SZFREG ++ FREG_S ft13, sp, 21*SZFREG ++ FREG_S ft14, sp, 22*SZFREG ++ FREG_S ft15, sp, 23*SZFREG ++ ++#endif /* #ifndef __loongarch_soft_float */ ++ ++.Ltga: ++ bl HIDDEN_JUMPTARGET(__tls_get_addr) ++ ADDI a0, a0, -TLS_DTV_OFFSET ++ ++#ifndef __loongarch_soft_float ++ ++ la.global t0, _rtld_global_ro ++ REG_L t0, t0, GLRO_DL_HWCAP_OFFSET ++ andi t0, t0, HWCAP_LOONGARCH_LASX ++ beqz t0, .Llsx1 ++ ++ /* Restore 256-bit vector registers. */ ++ xvld xr0, sp, 0*SZXREG ++ xvld xr1, sp, 1*SZXREG ++ xvld xr2, sp, 2*SZXREG ++ xvld xr3, sp, 3*SZXREG ++ xvld xr4, sp, 4*SZXREG ++ xvld xr5, sp, 5*SZXREG ++ xvld xr6, sp, 6*SZXREG ++ xvld xr7, sp, 7*SZXREG ++ xvld xr8, sp, 8*SZXREG ++ xvld xr9, sp, 9*SZXREG ++ xvld xr10, sp, 10*SZXREG ++ xvld xr11, sp, 11*SZXREG ++ xvld xr12, sp, 12*SZXREG ++ xvld xr13, sp, 13*SZXREG ++ xvld xr14, sp, 14*SZXREG ++ xvld xr15, sp, 15*SZXREG ++ xvld xr16, sp, 16*SZXREG ++ xvld xr17, sp, 17*SZXREG ++ xvld xr18, sp, 18*SZXREG ++ xvld xr19, sp, 19*SZXREG ++ xvld xr20, sp, 20*SZXREG ++ xvld xr21, sp, 21*SZXREG ++ xvld xr22, sp, 22*SZXREG ++ xvld xr23, sp, 23*SZXREG ++ xvld xr24, sp, 24*SZXREG ++ xvld xr25, sp, 25*SZXREG ++ xvld xr26, sp, 26*SZXREG ++ xvld xr27, sp, 27*SZXREG ++ xvld xr28, sp, 28*SZXREG ++ xvld xr29, sp, 29*SZXREG ++ xvld xr30, sp, 30*SZXREG ++ xvld xr31, sp, 31*SZXREG ++ ADDI sp, sp, FRAME_SIZE_LASX ++ b .Lfcsr ++ ++.Llsx1: ++ andi t0, s0, HWCAP_LOONGARCH_LSX ++ beqz t0, .Lfloat1 ++ ++ /* Restore 128-bit vector registers. */ ++ vld vr0, sp, 0*SZVREG ++ vld vr1, sp, 1*SZVREG ++ vld vr2, sp, 2*SZVREG ++ vld vr3, sp, 3*SZVREG ++ vld vr4, sp, 4*SZVREG ++ vld vr5, sp, 5*SZVREG ++ vld vr6, sp, 6*SZVREG ++ vld vr7, sp, 7*SZVREG ++ vld vr8, sp, 8*SZVREG ++ vld vr9, sp, 9*SZVREG ++ vld vr10, sp, 10*SZVREG ++ vld vr11, sp, 11*SZVREG ++ vld vr12, sp, 12*SZVREG ++ vld vr13, sp, 13*SZVREG ++ vld vr14, sp, 14*SZVREG ++ vld vr15, sp, 15*SZVREG ++ vld vr16, sp, 16*SZVREG ++ vld vr17, sp, 17*SZVREG ++ vld vr18, sp, 18*SZVREG ++ vld vr19, sp, 19*SZVREG ++ vld vr20, sp, 20*SZVREG ++ vld vr21, sp, 21*SZVREG ++ vld vr22, sp, 22*SZVREG ++ vld vr23, sp, 23*SZVREG ++ vld vr24, sp, 24*SZVREG ++ vld vr25, sp, 25*SZVREG ++ vld vr26, sp, 26*SZVREG ++ vld vr27, sp, 27*SZVREG ++ vld vr28, sp, 28*SZVREG ++ vld vr29, sp, 29*SZVREG ++ vld vr30, sp, 30*SZVREG ++ vld vr31, sp, 31*SZVREG ++ ADDI sp, sp, FRAME_SIZE_LSX ++ b .Lfcsr ++ ++.Lfloat1: ++ /* Restore float registers. */ ++ FREG_L fa0, sp, 0*SZFREG ++ FREG_L fa1, sp, 1*SZFREG ++ FREG_L fa2, sp, 2*SZFREG ++ FREG_L fa3, sp, 3*SZFREG ++ FREG_L fa4, sp, 4*SZFREG ++ FREG_L fa5, sp, 5*SZFREG ++ FREG_L fa6, sp, 6*SZFREG ++ FREG_L fa7, sp, 7*SZFREG ++ FREG_L ft0, sp, 8*SZFREG ++ FREG_L ft1, sp, 9*SZFREG ++ FREG_L ft2, sp, 10*SZFREG ++ FREG_L ft3, sp, 11*SZFREG ++ FREG_L ft4, sp, 12*SZFREG ++ FREG_L ft5, sp, 13*SZFREG ++ FREG_L ft6, sp, 14*SZFREG ++ FREG_L ft7, sp, 15*SZFREG ++ FREG_L ft8, sp, 16*SZFREG ++ FREG_L ft9, sp, 17*SZFREG ++ FREG_L ft10, sp, 18*SZFREG ++ FREG_L ft11, sp, 19*SZFREG ++ FREG_L ft12, sp, 20*SZFREG ++ FREG_L ft13, sp, 21*SZFREG ++ FREG_L ft14, sp, 22*SZFREG ++ FREG_L ft15, sp, 23*SZFREG ++ ADDI sp, sp, FRAME_SIZE_FLOAT ++ ++.Lfcsr: ++ /* Restore fcsr0 register. */ ++ ld.w t0, sp, 0 ++ movgr2fcsr fcsr0, t0 ++ ADDI sp, sp, SZFCSREG ++ ++#endif /* #ifndef __loongarch_soft_float */ ++ ++ REG_L ra, sp, 0 * SZREG ++ REG_L a1, sp, 1 * SZREG ++ REG_L a2, sp, 2 * SZREG ++ REG_L a3, sp, 3 * SZREG ++ REG_L a4, sp, 4 * SZREG ++ REG_L a5, sp, 5 * SZREG ++ REG_L a6, sp, 6 * SZREG ++ REG_L a7, sp, 7 * SZREG ++ REG_L t3, sp, 8 * SZREG ++ REG_L t4, sp, 9 * SZREG ++ REG_L t5, sp, 10 * SZREG ++ REG_L t6, sp, 11 * SZREG ++ REG_L t7, sp, 12 * SZREG ++ REG_L t8, sp, 13 * SZREG ++ ADDI sp, sp, FRAME_SIZE ++ ++ b .Lret ++ cfi_endproc ++ .size _dl_tlsdesc_dynamic, .-_dl_tlsdesc_dynamic ++ .hidden HIDDEN_JUMPTARGET(__tls_get_addr) ++ ++#endif /* #ifdef SHARED */ +diff --git a/sysdeps/loongarch/dl-tlsdesc.h b/sysdeps/loongarch/dl-tlsdesc.h +new file mode 100644 +index 00000000..ff8c69cb +--- /dev/null ++++ b/sysdeps/loongarch/dl-tlsdesc.h +@@ -0,0 +1,49 @@ ++/* Thread-local storage descriptor handling in the ELF dynamic linker. ++ LoongArch version. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <https://www.gnu.org/licenses/>. */ ++ ++#ifndef _DL_TLSDESC_H ++#define _DL_TLSDESC_H ++ ++#include <dl-tls.h> ++ ++/* Type used to represent a TLS descriptor in the GOT. */ ++struct tlsdesc ++{ ++ ptrdiff_t (*entry) (struct tlsdesc *); ++ void *arg; ++}; ++ ++/* Type used as the argument in a TLS descriptor for a symbol that ++ needs dynamic TLS offsets. */ ++struct tlsdesc_dynamic_arg ++{ ++ tls_index tlsinfo; ++ size_t gen_count; ++}; ++ ++extern ptrdiff_t attribute_hidden _dl_tlsdesc_return (struct tlsdesc *); ++extern ptrdiff_t attribute_hidden _dl_tlsdesc_undefweak (struct tlsdesc *); ++ ++#ifdef SHARED ++extern void *_dl_make_tlsdesc_dynamic (struct link_map *, size_t); ++extern ptrdiff_t attribute_hidden _dl_tlsdesc_dynamic (struct tlsdesc *); ++#endif ++ ++#endif +diff --git a/sysdeps/loongarch/linkmap.h b/sysdeps/loongarch/linkmap.h +index 2f5bf534..4e637d49 100644 +--- a/sysdeps/loongarch/linkmap.h ++++ b/sysdeps/loongarch/linkmap.h +@@ -18,5 +18,6 @@ + + struct link_map_machine + { +- ElfW (Addr) plt; /* Address of .plt. */ ++ ElfW (Addr) plt; /* Address of .plt. */ ++ void *tlsdesc_table; /* Address of TLS descriptor hash table. */ + }; +diff --git a/sysdeps/loongarch/preconfigure b/sysdeps/loongarch/preconfigure +index dfc7ecfd..0d1e9ed8 100644 +--- a/sysdeps/loongarch/preconfigure ++++ b/sysdeps/loongarch/preconfigure +@@ -43,6 +43,7 @@ loongarch*) + + + base_machine=loongarch ++ mtls_descriptor=desc + ;; + esac + +diff --git a/sysdeps/loongarch/sys/asm.h b/sysdeps/loongarch/sys/asm.h +index c5eb8afa..dbee93ee 100644 +--- a/sysdeps/loongarch/sys/asm.h ++++ b/sysdeps/loongarch/sys/asm.h +@@ -25,6 +25,7 @@ + /* Macros to handle different pointer/register sizes for 32/64-bit code. */ + #define SZREG 8 + #define SZFREG 8 ++#define SZFCSREG 4 + #define SZVREG 16 + #define SZXREG 32 + #define REG_L ld.d +diff --git a/sysdeps/loongarch/sys/regdef.h b/sysdeps/loongarch/sys/regdef.h +index 524d2e32..c26b729e 100644 +--- a/sysdeps/loongarch/sys/regdef.h ++++ b/sysdeps/loongarch/sys/regdef.h +@@ -97,6 +97,7 @@ + #define fcc5 $fcc5 + #define fcc6 $fcc6 + #define fcc7 $fcc7 ++#define fcsr0 $fcsr0 + + #define vr0 $vr0 + #define vr1 $vr1 +diff --git a/sysdeps/loongarch/tlsdesc.c b/sysdeps/loongarch/tlsdesc.c +new file mode 100644 +index 00000000..76708f7e +--- /dev/null ++++ b/sysdeps/loongarch/tlsdesc.c +@@ -0,0 +1,39 @@ ++/* Manage TLS descriptors. LoongArch64 version. ++ ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <https://www.gnu.org/licenses/>. */ ++ ++#include <ldsodefs.h> ++#include <tls.h> ++#include <dl-tlsdesc.h> ++#include <dl-unmap-segments.h> ++#include <tlsdeschtab.h> ++ ++/* Unmap the dynamic object, but also release its TLS descriptor table ++ if there is one. */ ++ ++void ++_dl_unmap (struct link_map *map) ++{ ++ _dl_unmap_segments (map); ++ ++#ifdef SHARED ++ if (map->l_mach.tlsdesc_table) ++ htab_delete (map->l_mach.tlsdesc_table); ++#endif ++} +diff --git a/sysdeps/loongarch/tlsdesc.sym b/sysdeps/loongarch/tlsdesc.sym +new file mode 100644 +index 00000000..213d0b30 +--- /dev/null ++++ b/sysdeps/loongarch/tlsdesc.sym +@@ -0,0 +1,28 @@ ++#include <stddef.h> ++#include <sysdep.h> ++#include <tls.h> ++#include <link.h> ++#include <dl-tlsdesc.h> ++ ++#define SHARED 1 ++ ++#include <ldsodefs.h> ++ ++#define GLRO_offsetof(name) offsetof (struct rtld_global_ro, _##name) ++ ++-- ++ ++-- Abuse tls.h macros to derive offsets relative to the thread register. ++ ++TLSDESC_ARG offsetof(struct tlsdesc, arg) ++TLSDESC_GEN_COUNT offsetof(struct tlsdesc_dynamic_arg, gen_count) ++TLSDESC_MODID offsetof(struct tlsdesc_dynamic_arg, tlsinfo.ti_module) ++TLSDESC_MODOFF offsetof(struct tlsdesc_dynamic_arg, tlsinfo.ti_offset) ++TCBHEAD_DTV offsetof(tcbhead_t, dtv) ++DTV_COUNTER offsetof(dtv_t, counter) ++TLS_DTV_UNALLOCATED TLS_DTV_UNALLOCATED ++TLS_DTV_OFFSET TLS_DTV_OFFSET ++SIZE_OF_TCB sizeof(tcbhead_t) ++GLRO_DL_HWCAP_OFFSET GLRO_offsetof (dl_hwcap) ++HWCAP_LOONGARCH_LSX HWCAP_LOONGARCH_LSX ++HWCAP_LOONGARCH_LASX HWCAP_LOONGARCH_LASX +diff --git a/sysdeps/loongarch/tst-gnu2-tls2.h b/sysdeps/loongarch/tst-gnu2-tls2.h +new file mode 100644 +index 00000000..8e421678 +--- /dev/null ++++ b/sysdeps/loongarch/tst-gnu2-tls2.h +@@ -0,0 +1,377 @@ ++/* Test TLSDESC relocation. LoongArch64 version. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <https://www.gnu.org/licenses/>. */ ++ ++#include <config.h> ++#include <string.h> ++#include <stdlib.h> ++#include <sys/auxv.h> ++ ++/* The instruction between BEFORE_TLSDESC_CALL and _dl_tlsdesc_dynamic, ++ and the instruction between _dl_tlsdesc_dynamic and AFTER_TLSDESC_CALL, ++ may modified most of the general-purpose register. */ ++#define SAVE_REGISTER(src) \ ++ asm volatile ("st.d $r3, %0" :"=m"(src) :); ++ ++#ifdef __loongarch_soft_float ++ ++#define BEFORE_TLSDESC_CALL() \ ++ uint64_t src; \ ++ SAVE_REGISTER (src); ++ ++#define AFTER_TLSDESC_CALL() \ ++ uint64_t restore; \ ++ SAVE_REGISTER (restore); \ ++ if (src != restore) \ ++ abort (); ++ ++#else /* hard float */ ++ ++#define SAVE_REGISTER_FCC(src) \ ++ asm volatile ("movcf2gr $t0, $fcc0" ::: "$t0"); \ ++ asm volatile ("st.d $t0, %0" :"=m"(src0) :); \ ++ asm volatile ("movcf2gr $t0, $fcc1" ::: "$t0"); \ ++ asm volatile ("st.d $t0, %0" :"=m"(src1) :); \ ++ asm volatile ("movcf2gr $t0, $fcc2" ::: "$t0"); \ ++ asm volatile ("st.d $t0, %0" :"=m"(src2) :); \ ++ asm volatile ("movcf2gr $t0, $fcc3" ::: "$t0"); \ ++ asm volatile ("st.d $t0, %0" :"=m"(src3) :); \ ++ asm volatile ("movcf2gr $t0, $fcc4" ::: "$t0"); \ ++ asm volatile ("st.d $t0, %0" :"=m"(src4) :); \ ++ asm volatile ("movcf2gr $t0, $fcc5" ::: "$t0"); \ ++ asm volatile ("st.d $t0, %0" :"=m"(src5) :); \ ++ asm volatile ("movcf2gr $t0, $fcc6" ::: "$t0"); \ ++ asm volatile ("st.d $t0, %0" :"=m"(src6) :); \ ++ asm volatile ("movcf2gr $t0, $fcc7" ::: "$t0"); \ ++ asm volatile ("st.d $t0, %0" :"=m"(src7) :); ++ ++#define LOAD_REGISTER_FCSR() \ ++ asm volatile ("li.d $t0, 0x01010101" ::: "$t0"); \ ++ asm volatile ("movgr2fcsr $fcsr0, $t0" :::); ++ ++#define SAVE_REGISTER_FCSR() \ ++ asm volatile ("movfcsr2gr $t0, $fcsr0" ::: "$t0"); \ ++ asm volatile ("st.d $t0, %0" :"=m"(restore_fcsr) :); ++ ++# define INIT_TLSDESC_CALL() \ ++ unsigned long hwcap = getauxval (AT_HWCAP); ++ ++#define LOAD_REGISTER_FLOAT() \ ++ asm volatile ("fld.d $f0, %0" ::"m"(src_float0) :"$f0"); \ ++ asm volatile ("fld.d $f1, %0" ::"m"(src_float1) :"$f1"); \ ++ asm volatile ("fld.d $f2, %0" ::"m"(src_float2) :"$f2"); \ ++ asm volatile ("fld.d $f3, %0" ::"m"(src_float3) :"$f3"); \ ++ asm volatile ("fld.d $f4, %0" ::"m"(src_float4) :"$f4"); \ ++ asm volatile ("fld.d $f5, %0" ::"m"(src_float5) :"$f5"); \ ++ asm volatile ("fld.d $f6, %0" ::"m"(src_float6) :"$f6"); \ ++ asm volatile ("fld.d $f7, %0" ::"m"(src_float7) :"$f7"); \ ++ asm volatile ("fld.d $f8, %0" ::"m"(src_float8) :"$f8"); \ ++ asm volatile ("fld.d $f9, %0" ::"m"(src_float9) :"$f9"); \ ++ asm volatile ("fld.d $f10, %0" ::"m"(src_float10) :"$f10"); \ ++ asm volatile ("fld.d $f11, %0" ::"m"(src_float11) :"$f11"); \ ++ asm volatile ("fld.d $f12, %0" ::"m"(src_float12) :"$f12"); \ ++ asm volatile ("fld.d $f13, %0" ::"m"(src_float13) :"$f13"); \ ++ asm volatile ("fld.d $f14, %0" ::"m"(src_float14) :"$f14"); \ ++ asm volatile ("fld.d $f15, %0" ::"m"(src_float15) :"$f15"); \ ++ asm volatile ("fld.d $f16, %0" ::"m"(src_float16) :"$f16"); \ ++ asm volatile ("fld.d $f17, %0" ::"m"(src_float17) :"$f17"); \ ++ asm volatile ("fld.d $f18, %0" ::"m"(src_float18) :"$f18"); \ ++ asm volatile ("fld.d $f19, %0" ::"m"(src_float19) :"$f19"); \ ++ asm volatile ("fld.d $f20, %0" ::"m"(src_float20) :"$f20"); \ ++ asm volatile ("fld.d $f21, %0" ::"m"(src_float21) :"$f21"); \ ++ asm volatile ("fld.d $f22, %0" ::"m"(src_float22) :"$f22"); \ ++ asm volatile ("fld.d $f23, %0" ::"m"(src_float23) :"$f23"); \ ++ asm volatile ("fld.d $f24, %0" ::"m"(src_float24) :"$f24"); \ ++ asm volatile ("fld.d $f25, %0" ::"m"(src_float25) :"$f25"); \ ++ asm volatile ("fld.d $f26, %0" ::"m"(src_float26) :"$f26"); \ ++ asm volatile ("fld.d $f27, %0" ::"m"(src_float27) :"$f27"); \ ++ asm volatile ("fld.d $f28, %0" ::"m"(src_float28) :"$f28"); \ ++ asm volatile ("fld.d $f29, %0" ::"m"(src_float29) :"$f29"); \ ++ asm volatile ("fld.d $f30, %0" ::"m"(src_float30) :"$f30"); \ ++ asm volatile ("fld.d $f31, %0" ::"m"(src_float31) :"$f31"); ++ ++#define SAVE_REGISTER_FLOAT() \ ++ asm volatile ("fst.d $f0, %0" :"=m"(restore_float0) :); \ ++ asm volatile ("fst.d $f1, %0" :"=m"(restore_float1) :); \ ++ asm volatile ("fst.d $f2, %0" :"=m"(restore_float2) :); \ ++ asm volatile ("fst.d $f3, %0" :"=m"(restore_float3) :); \ ++ asm volatile ("fst.d $f4, %0" :"=m"(restore_float4) :); \ ++ asm volatile ("fst.d $f5, %0" :"=m"(restore_float5) :); \ ++ asm volatile ("fst.d $f6, %0" :"=m"(restore_float6) :); \ ++ asm volatile ("fst.d $f7, %0" :"=m"(restore_float7) :); \ ++ asm volatile ("fst.d $f8, %0" :"=m"(restore_float8) :); \ ++ asm volatile ("fst.d $f9, %0" :"=m"(restore_float9) :); \ ++ asm volatile ("fst.d $f10, %0" :"=m"(restore_float10) :); \ ++ asm volatile ("fst.d $f11, %0" :"=m"(restore_float11) :); \ ++ asm volatile ("fst.d $f12, %0" :"=m"(restore_float12) :); \ ++ asm volatile ("fst.d $f13, %0" :"=m"(restore_float13) :); \ ++ asm volatile ("fst.d $f14, %0" :"=m"(restore_float14) :); \ ++ asm volatile ("fst.d $f15, %0" :"=m"(restore_float15) :); \ ++ asm volatile ("fst.d $f16, %0" :"=m"(restore_float16) :); \ ++ asm volatile ("fst.d $f17, %0" :"=m"(restore_float17) :); \ ++ asm volatile ("fst.d $f18, %0" :"=m"(restore_float18) :); \ ++ asm volatile ("fst.d $f19, %0" :"=m"(restore_float19) :); \ ++ asm volatile ("fst.d $f20, %0" :"=m"(restore_float20) :); \ ++ asm volatile ("fst.d $f21, %0" :"=m"(restore_float21) :); \ ++ asm volatile ("fst.d $f22, %0" :"=m"(restore_float22) :); \ ++ asm volatile ("fst.d $f23, %0" :"=m"(restore_float23) :); \ ++ asm volatile ("fst.d $f24, %0" :"=m"(restore_float24) :); \ ++ asm volatile ("fst.d $f25, %0" :"=m"(restore_float25) :); \ ++ asm volatile ("fst.d $f26, %0" :"=m"(restore_float26) :); \ ++ asm volatile ("fst.d $f27, %0" :"=m"(restore_float27) :); \ ++ asm volatile ("fst.d $f28, %0" :"=m"(restore_float28) :); \ ++ asm volatile ("fst.d $f29, %0" :"=m"(restore_float29) :); \ ++ asm volatile ("fst.d $f30, %0" :"=m"(restore_float30) :); \ ++ asm volatile ("fst.d $f31, %0" :"=m"(restore_float31) :); ++ ++#ifdef HAVE_LOONGARCH_VEC_COM ++ #define LOAD_REGISTER_LSX() \ ++ /* Every byte in $vr0 is 1. */ \ ++ asm volatile ("vldi $vr0, 1" ::: "$vr0"); \ ++ asm volatile ("vldi $vr1, 2" ::: "$vr1"); \ ++ asm volatile ("vldi $vr2, 3" ::: "$vr2"); \ ++ asm volatile ("vldi $vr3, 4" ::: "$vr3"); \ ++ asm volatile ("vldi $vr4, 5" ::: "$vr4"); \ ++ asm volatile ("vldi $vr5, 6" ::: "$vr5"); \ ++ asm volatile ("vldi $vr6, 7" ::: "$vr6"); \ ++ asm volatile ("vldi $vr7, 8" ::: "$vr7"); \ ++ asm volatile ("vldi $vr8, 9" ::: "$vr8"); \ ++ asm volatile ("vldi $vr9, 10" ::: "$vr9"); \ ++ asm volatile ("vldi $vr10, 11" ::: "$vr10"); \ ++ asm volatile ("vldi $vr11, 12" ::: "$vr11"); \ ++ asm volatile ("vldi $vr12, 13" ::: "$vr12"); \ ++ asm volatile ("vldi $vr13, 14" ::: "$vr13"); \ ++ asm volatile ("vldi $vr14, 15" ::: "$vr14"); \ ++ asm volatile ("vldi $vr15, 16" ::: "$vr15"); \ ++ asm volatile ("vldi $vr16, 17" ::: "$vr16"); \ ++ asm volatile ("vldi $vr17, 18" ::: "$vr17"); \ ++ asm volatile ("vldi $vr18, 19" ::: "$vr18"); \ ++ asm volatile ("vldi $vr19, 20" ::: "$vr19"); \ ++ asm volatile ("vldi $vr20, 21" ::: "$vr20"); \ ++ asm volatile ("vldi $vr21, 22" ::: "$vr21"); \ ++ asm volatile ("vldi $vr22, 23" ::: "$vr22"); \ ++ asm volatile ("vldi $vr23, 24" ::: "$vr23"); \ ++ asm volatile ("vldi $vr24, 25" ::: "$vr24"); \ ++ asm volatile ("vldi $vr25, 26" ::: "$vr25"); \ ++ asm volatile ("vldi $vr26, 27" ::: "$vr26"); \ ++ asm volatile ("vldi $vr27, 28" ::: "$vr27"); \ ++ asm volatile ("vldi $vr28, 29" ::: "$vr28"); \ ++ asm volatile ("vldi $vr29, 30" ::: "$vr29"); \ ++ asm volatile ("vldi $vr30, 31" ::: "$vr30"); \ ++ asm volatile ("vldi $vr31, 32" ::: "$vr31"); ++#else ++ #define LOAD_REGISTER_LSX() ++#endif ++ ++#ifdef HAVE_LOONGARCH_VEC_COM ++ #define SAVE_REGISTER_LSX() \ ++ int src_lsx324; \ ++ int restore_lsx324; \ ++ asm volatile ("vst $vr0, %0" :"=m"(restore_lsx0) :); \ ++ asm volatile ("vst $vr1, %0" :"=m"(restore_lsx1) :); \ ++ asm volatile ("vst $vr2, %0" :"=m"(restore_lsx2) :); \ ++ asm volatile ("vst $vr3, %0" :"=m"(restore_lsx3) :); \ ++ asm volatile ("vst $vr4, %0" :"=m"(restore_lsx4) :); \ ++ asm volatile ("vst $vr5, %0" :"=m"(restore_lsx5) :); \ ++ asm volatile ("vst $vr6, %0" :"=m"(restore_lsx6) :); \ ++ asm volatile ("vst $vr7, %0" :"=m"(restore_lsx7) :); \ ++ asm volatile ("vst $vr8, %0" :"=m"(restore_lsx8) :); \ ++ asm volatile ("vst $vr9, %0" :"=m"(restore_lsx9) :); \ ++ asm volatile ("vst $vr10, %0" :"=m"(restore_lsx10) :); \ ++ asm volatile ("vst $vr11, %0" :"=m"(restore_lsx11) :); \ ++ asm volatile ("vst $vr12, %0" :"=m"(restore_lsx12) :); \ ++ asm volatile ("vst $vr13, %0" :"=m"(restore_lsx13) :); \ ++ asm volatile ("vst $vr14, %0" :"=m"(restore_lsx14) :); \ ++ asm volatile ("vst $vr15, %0" :"=m"(restore_lsx15) :); \ ++ asm volatile ("vst $vr16, %0" :"=m"(restore_lsx16) :); \ ++ asm volatile ("vst $vr17, %0" :"=m"(restore_lsx17) :); \ ++ asm volatile ("vst $vr18, %0" :"=m"(restore_lsx18) :); \ ++ asm volatile ("vst $vr19, %0" :"=m"(restore_lsx19) :); \ ++ asm volatile ("vst $vr20, %0" :"=m"(restore_lsx20) :); \ ++ asm volatile ("vst $vr21, %0" :"=m"(restore_lsx21) :); \ ++ asm volatile ("vst $vr22, %0" :"=m"(restore_lsx22) :); \ ++ asm volatile ("vst $vr23, %0" :"=m"(restore_lsx23) :); \ ++ asm volatile ("vst $vr24, %0" :"=m"(restore_lsx24) :); \ ++ asm volatile ("vst $vr25, %0" :"=m"(restore_lsx25) :); \ ++ asm volatile ("vst $vr26, %0" :"=m"(restore_lsx26) :); \ ++ asm volatile ("vst $vr27, %0" :"=m"(restore_lsx27) :); \ ++ asm volatile ("vst $vr28, %0" :"=m"(restore_lsx28) :); \ ++ asm volatile ("vst $vr29, %0" :"=m"(restore_lsx29) :); \ ++ asm volatile ("vst $vr30, %0" :"=m"(restore_lsx30) :); \ ++ asm volatile ("vst $vr31, %0" :"=m"(restore_lsx31) :); \ ++ for (int i = 0; i < 32; i++) \ ++ for (int j = 0; j < 4; j++) \ ++ { \ ++ src_lsxij = 0x01010101 * (i + 1); \ ++ if (src_lsxij != restore_lsxij) \ ++ abort (); \ ++ } ++#else ++ #define SAVE_REGISTER_LSX() ++#endif ++ ++#ifdef HAVE_LOONGARCH_VEC_COM ++ #define LOAD_REGISTER_LASX() \ ++ /* Every byte in $xr0 is 1. */ \ ++ asm volatile ("xvldi $xr0, 1" ::: "$xr0"); \ ++ asm volatile ("xvldi $xr1, 2" ::: "$xr1"); \ ++ asm volatile ("xvldi $xr2, 3" ::: "$xr2"); \ ++ asm volatile ("xvldi $xr3, 4" ::: "$xr3"); \ ++ asm volatile ("xvldi $xr4, 5" ::: "$xr4"); \ ++ asm volatile ("xvldi $xr5, 6" ::: "$xr5"); \ ++ asm volatile ("xvldi $xr6, 7" ::: "$xr6"); \ ++ asm volatile ("xvldi $xr7, 8" ::: "$xr7"); \ ++ asm volatile ("xvldi $xr8, 9" ::: "$xr8"); \ ++ asm volatile ("xvldi $xr9, 10" ::: "$xr9"); \ ++ asm volatile ("xvldi $xr10, 11" ::: "$xr10"); \ ++ asm volatile ("xvldi $xr11, 12" ::: "$xr11"); \ ++ asm volatile ("xvldi $xr12, 13" ::: "$xr12"); \ ++ asm volatile ("xvldi $xr13, 14" ::: "$xr13"); \ ++ asm volatile ("xvldi $xr14, 15" ::: "$xr14"); \ ++ asm volatile ("xvldi $xr15, 16" ::: "$xr15"); \ ++ asm volatile ("xvldi $xr16, 17" ::: "$xr16"); \ ++ asm volatile ("xvldi $xr17, 18" ::: "$xr17"); \ ++ asm volatile ("xvldi $xr18, 19" ::: "$xr18"); \ ++ asm volatile ("xvldi $xr19, 20" ::: "$xr19"); \ ++ asm volatile ("xvldi $xr20, 21" ::: "$xr20"); \ ++ asm volatile ("xvldi $xr21, 22" ::: "$xr21"); \ ++ asm volatile ("xvldi $xr22, 23" ::: "$xr22"); \ ++ asm volatile ("xvldi $xr23, 24" ::: "$xr23"); \ ++ asm volatile ("xvldi $xr24, 25" ::: "$xr24"); \ ++ asm volatile ("xvldi $xr25, 26" ::: "$xr25"); \ ++ asm volatile ("xvldi $xr26, 27" ::: "$xr26"); \ ++ asm volatile ("xvldi $xr27, 28" ::: "$xr27"); \ ++ asm volatile ("xvldi $xr28, 29" ::: "$xr28"); \ ++ asm volatile ("xvldi $xr29, 30" ::: "$xr29"); \ ++ asm volatile ("xvldi $xr30, 31" ::: "$xr30"); \ ++ asm volatile ("xvldi $xr31, 32" ::: "$xr31"); ++#else ++ #define LOAD_REGISTER_LASX() ++#endif ++ ++#ifdef HAVE_LOONGARCH_VEC_COM ++ #define SAVE_REGISTER_LASX() \ ++ int src_lasx328; \ ++ int restore_lasx328; \ ++ asm volatile ("xvst $xr0, %0" :"=m"(restore_lasx0) :); \ ++ asm volatile ("xvst $xr1, %0" :"=m"(restore_lasx1) :); \ ++ asm volatile ("xvst $xr2, %0" :"=m"(restore_lasx2) :); \ ++ asm volatile ("xvst $xr3, %0" :"=m"(restore_lasx3) :); \ ++ asm volatile ("xvst $xr4, %0" :"=m"(restore_lasx4) :); \ ++ asm volatile ("xvst $xr5, %0" :"=m"(restore_lasx5) :); \ ++ asm volatile ("xvst $xr6, %0" :"=m"(restore_lasx6) :); \ ++ asm volatile ("xvst $xr7, %0" :"=m"(restore_lasx7) :); \ ++ asm volatile ("xvst $xr8, %0" :"=m"(restore_lasx8) :); \ ++ asm volatile ("xvst $xr9, %0" :"=m"(restore_lasx9) :); \ ++ asm volatile ("xvst $xr10, %0" :"=m"(restore_lasx10) :); \ ++ asm volatile ("xvst $xr11, %0" :"=m"(restore_lasx11) :); \ ++ asm volatile ("xvst $xr12, %0" :"=m"(restore_lasx12) :); \ ++ asm volatile ("xvst $xr13, %0" :"=m"(restore_lasx13) :); \ ++ asm volatile ("xvst $xr14, %0" :"=m"(restore_lasx14) :); \ ++ asm volatile ("xvst $xr15, %0" :"=m"(restore_lasx15) :); \ ++ asm volatile ("xvst $xr16, %0" :"=m"(restore_lasx16) :); \ ++ asm volatile ("xvst $xr17, %0" :"=m"(restore_lasx17) :); \ ++ asm volatile ("xvst $xr18, %0" :"=m"(restore_lasx18) :); \ ++ asm volatile ("xvst $xr19, %0" :"=m"(restore_lasx19) :); \ ++ asm volatile ("xvst $xr20, %0" :"=m"(restore_lasx20) :); \ ++ asm volatile ("xvst $xr21, %0" :"=m"(restore_lasx21) :); \ ++ asm volatile ("xvst $xr22, %0" :"=m"(restore_lasx22) :); \ ++ asm volatile ("xvst $xr23, %0" :"=m"(restore_lasx23) :); \ ++ asm volatile ("xvst $xr24, %0" :"=m"(restore_lasx24) :); \ ++ asm volatile ("xvst $xr25, %0" :"=m"(restore_lasx25) :); \ ++ asm volatile ("xvst $xr26, %0" :"=m"(restore_lasx26) :); \ ++ asm volatile ("xvst $xr27, %0" :"=m"(restore_lasx27) :); \ ++ asm volatile ("xvst $xr28, %0" :"=m"(restore_lasx28) :); \ ++ asm volatile ("xvst $xr29, %0" :"=m"(restore_lasx29) :); \ ++ asm volatile ("xvst $xr30, %0" :"=m"(restore_lasx30) :); \ ++ asm volatile ("xvst $xr31, %0" :"=m"(restore_lasx31) :); \ ++ for (int i = 0; i < 32; i++) \ ++ for (int j = 0; j < 8; j++) \ ++ { \ ++ src_lasxij = 0x01010101 * (i + 1); \ ++ if (src_lasxij != restore_lasxij) \ ++ abort (); \ ++ } ++#else ++ #define SAVE_REGISTER_LASX() ++#endif ++ ++#define BEFORE_TLSDESC_CALL() \ ++ uint64_t src; \ ++ double src_float32; \ ++ uint64_t src_fcc8; \ ++ for (int i = 0; i < 32; i++) \ ++ src_floati = i + 1; \ ++ \ ++ SAVE_REGISTER (src); \ ++ LOAD_REGISTER_FCSR (); \ ++ SAVE_REGISTER_FCC(src_fcc) \ ++ \ ++ if (hwcap & HWCAP_LOONGARCH_LASX) \ ++ { \ ++ LOAD_REGISTER_LASX (); \ ++ } \ ++ else if (hwcap & HWCAP_LOONGARCH_LSX) \ ++ { \ ++ LOAD_REGISTER_LSX (); \ ++ } \ ++ else \ ++ { \ ++ LOAD_REGISTER_FLOAT (); \ ++ } ++ ++#define AFTER_TLSDESC_CALL() \ ++ uint64_t restore; \ ++ uint64_t src_fcsr = 0x01010101; \ ++ uint64_t restore_fcsr; \ ++ uint64_t restore_fcc8; \ ++ SAVE_REGISTER (restore); \ ++ SAVE_REGISTER_FCSR (); \ ++ SAVE_REGISTER_FCC(restore_fcc) \ ++ \ ++ /* memcmp_lasx/strlen_lasx corrupts LSX/LASX registers, */ \ ++ /* compare LSX/LASX registers first. */ \ ++ if (hwcap & HWCAP_LOONGARCH_LASX) \ ++ { \ ++ SAVE_REGISTER_LASX (); \ ++ } \ ++ else if (hwcap & HWCAP_LOONGARCH_LSX) \ ++ { \ ++ SAVE_REGISTER_LSX (); \ ++ } \ ++ else \ ++ { \ ++ double restore_float32; \ ++ SAVE_REGISTER_FLOAT (); \ ++ \ ++ for (int i = 0; i < 32; i++) \ ++ if (src_floati != restore_floati) \ ++ abort (); \ ++ } \ ++ \ ++ if (src_fcsr != restore_fcsr) \ ++ abort (); \ ++ \ ++ if (memcmp (src_fcc, restore_fcc, sizeof (src_fcc)) != 0) \ ++ abort (); \ ++ \ ++ if (src != restore) \ ++ abort (); ++ ++#endif /* #ifdef __loongarch_soft_float */ ++ ++#include_next <tst-gnu2-tls2.h> +-- +2.43.0 +
View file
_service:tar_scm:0005-LoongArch-Fix-tst-gnu2-tls2-compiler-error.patch
Added
@@ -0,0 +1,64 @@ +From 479cf47724e06c1020d5806c90abfdb353e832c8 Mon Sep 17 00:00:00 2001 +From: mengqinggang <mengqinggang@loongson.cn> +Date: Mon, 20 May 2024 17:05:12 +0800 +Subject: PATCH 05/15 LoongArch: Fix tst-gnu2-tls2 compiler error + +Add -mno-lsx to tst-gnu2-tlsmod*.c if gcc support -mno-lsx. +Add escape character '\' in vector support test function. +--- + sysdeps/loongarch/Makefile | 2 ++ + sysdeps/loongarch/configure | 3 +++ + sysdeps/loongarch/configure.ac | 5 +++-- + 3 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/sysdeps/loongarch/Makefile b/sysdeps/loongarch/Makefile +index a4ee915e..b00c090f 100644 +--- a/sysdeps/loongarch/Makefile ++++ b/sysdeps/loongarch/Makefile +@@ -35,10 +35,12 @@ sysdep-dl-routines += \ + # Disable the compiler from using LSX for TLS descriptor tests, or storing into + # 16B TLS variable may clobber FP/vector registers and prevent us from checking + # their contents. ++ifeq (yes,$(loongarch-vec-com)) + CFLAGS-tst-gnu2-tls2mod0.c += -mno-lsx + CFLAGS-tst-gnu2-tls2mod1.c += -mno-lsx + CFLAGS-tst-gnu2-tls2mod2.c += -mno-lsx + endif ++endif + + # LoongArch's assembler also needs to know about PIC as it changes the + # definition of some assembler macros. +diff --git a/sysdeps/loongarch/configure b/sysdeps/loongarch/configure +index a133821f..73cf3b95 100644 +--- a/sysdeps/loongarch/configure ++++ b/sysdeps/loongarch/configure +@@ -165,3 +165,6 @@ then + printf "%s\n" "#define HAVE_LOONGARCH_VEC_COM 1" >>confdefs.h + + fi ++config_vars="$config_vars ++loongarch-vec-com = $libc_cv_loongarch_vec_com" ++ +diff --git a/sysdeps/loongarch/configure.ac b/sysdeps/loongarch/configure.ac +index 9b1cf26e..878c5d64 100644 +--- a/sysdeps/loongarch/configure.ac ++++ b/sysdeps/loongarch/configure.ac +@@ -83,8 +83,8 @@ AC_CACHE_CHECK(for vector support in compiler, + AC_COMPILE_IFELSE(AC_LANG_SOURCE( + void foo (void) + { +- asm volatile ("vldi $vr0, 1" ::: "$vr0"); +- asm volatile ("xvldi $xr0, 1" ::: "$xr0"); ++ asm volatile ("vldi \$vr0, 1" ::: "\$vr0"); ++ asm volatile ("xvldi \$xr0, 1" ::: "\$xr0"); + } + ), + libc_cv_loongarch_vec_com=yes, +@@ -93,3 +93,4 @@ if test "$libc_cv_loongarch_vec_com" = yes ; + then + AC_DEFINE(HAVE_LOONGARCH_VEC_COM) + fi ++LIBC_CONFIG_VAR(loongarch-vec-com, $libc_cv_loongarch_vec_com) +-- +2.43.0 +
View file
_service:tar_scm:0006-LoongArch-Use-fcsr0-instead-of-r0-in-_FPU_-GET-SET-C.patch
Added
@@ -0,0 +1,37 @@ +From 3a6a1dc7b501846856faeed6b83af2f12bda782f Mon Sep 17 00:00:00 2001 +From: Xi Ruoyao <xry111@xry111.site> +Date: Mon, 29 Apr 2024 15:26:24 +0800 +Subject: PATCH 06/15 LoongArch: Use "$fcsr0" instead of "$r0" in + _FPU_{GET,SET}CW + +Clang inline-asm parser does not allow using "$r0" in +movfcsr2gr/movgr2fcsr, so everything using _FPU_{GET,SET}CW is now +failing to build with Clang on LoongArch. As we now requires Binutils +>= 2.41 which supports using "$fcsr0" here, use it instead of "$r0" to +fix the issue. + +Link: https://github.com/loongson-community/discussions/issues/53#issuecomment-2081507390 +Link: https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=4142b2368353 +Signed-off-by: Xi Ruoyao <xry111@xry111.site> +--- + sysdeps/loongarch/fpu_control.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/sysdeps/loongarch/fpu_control.h b/sysdeps/loongarch/fpu_control.h +index ffb01ca5..3c8ae8b5 100644 +--- a/sysdeps/loongarch/fpu_control.h ++++ b/sysdeps/loongarch/fpu_control.h +@@ -91,8 +91,8 @@ typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__))); + /* Macros for accessing the hardware control word. */ + extern fpu_control_t __loongarch_fpu_getcw (void) __THROW; + extern void __loongarch_fpu_setcw (fpu_control_t) __THROW; +-#define _FPU_GETCW(cw) __asm__ volatile ("movfcsr2gr %0,$r0" : "=r"(cw)) +-#define _FPU_SETCW(cw) __asm__ volatile ("movgr2fcsr $r0,%0" : : "r"(cw)) ++#define _FPU_GETCW(cw) __asm__ volatile ("movfcsr2gr %0,$fcsr0" : "=r"(cw)) ++#define _FPU_SETCW(cw) __asm__ volatile ("movgr2fcsr $fcsr0,%0" : : "r"(cw)) + + /* Default control word set at startup. */ + extern fpu_control_t __fpu_control; +-- +2.43.0 +
View file
_service:tar_scm:0007-LoongArch-Ensure-sp-16-byte-aligned-for-tlsdesc.patch
Added
@@ -0,0 +1,76 @@ +From 8fac691bbaaf60690902e585290bb88e060cc85a Mon Sep 17 00:00:00 2001 +From: Xi Ruoyao <xry111@xry111.site> +Date: Thu, 13 Jun 2024 19:04:05 +0800 +Subject: PATCH 07/15 LoongArch: Ensure sp 16-byte aligned for tlsdesc + +"ADDI sp, sp, 24" and "ADDI sp, sp, SZFCSREG" (SZFCSREG = 4) are +misaligning the stack: the ABI mandates a 16-byte alignment. Fix it +by changing the first one to "ADDI sp, sp, 32", and reuse the spare 4th +slot for saving fcsr. + +Reported-by: Jinyang He <hejinyang@loongson.cn> +Signed-off-by: Xi Ruoyao <xry111@xry111.site> +--- + sysdeps/loongarch/dl-tlsdesc.S | 10 ++++------ + sysdeps/loongarch/sys/asm.h | 1 - + 2 files changed, 4 insertions(+), 7 deletions(-) + +diff --git a/sysdeps/loongarch/dl-tlsdesc.S b/sysdeps/loongarch/dl-tlsdesc.S +index 15d5fa1c..346b80f2 100644 +--- a/sysdeps/loongarch/dl-tlsdesc.S ++++ b/sysdeps/loongarch/dl-tlsdesc.S +@@ -100,7 +100,7 @@ _dl_tlsdesc_undefweak: + _dl_tlsdesc_dynamic: + /* Save just enough registers to support fast path, if we fall + into slow path we will save additional registers. */ +- ADDI sp, sp, -24 ++ ADDI sp, sp, -32 + REG_S t0, sp, 0 + REG_S t1, sp, 8 + REG_S t2, sp, 16 +@@ -141,7 +141,7 @@ Hign address dynamic_block1 <----- dtv5 */ + REG_L t0, sp, 0 + REG_L t1, sp, 8 + REG_L t2, sp, 16 +- ADDI sp, sp, 24 ++ ADDI sp, sp, 32 + RET + + .Lslow: +@@ -171,9 +171,8 @@ Hign address dynamic_block1 <----- dtv5 */ + /* Save fcsr0 register. + Only one physical fcsr0 register, fcsr1-fcsr3 are aliases + of some fields in fcsr0. */ +- ADDI sp, sp, -SZFCSREG + movfcsr2gr t0, fcsr0 +- st.w t0, sp, 0 ++ st.w t0, sp, FRAME_SIZE + 24 /* Use the spare slot above t2 */ + + /* Whether support LASX. */ + la.global t0, _rtld_global_ro +@@ -406,9 +405,8 @@ Hign address dynamic_block1 <----- dtv5 */ + + .Lfcsr: + /* Restore fcsr0 register. */ +- ld.w t0, sp, 0 ++ ld.w t0, sp, FRAME_SIZE + 24 + movgr2fcsr fcsr0, t0 +- ADDI sp, sp, SZFCSREG + + #endif /* #ifndef __loongarch_soft_float */ + +diff --git a/sysdeps/loongarch/sys/asm.h b/sysdeps/loongarch/sys/asm.h +index dbee93ee..c5eb8afa 100644 +--- a/sysdeps/loongarch/sys/asm.h ++++ b/sysdeps/loongarch/sys/asm.h +@@ -25,7 +25,6 @@ + /* Macros to handle different pointer/register sizes for 32/64-bit code. */ + #define SZREG 8 + #define SZFREG 8 +-#define SZFCSREG 4 + #define SZVREG 16 + #define SZXREG 32 + #define REG_L ld.d +-- +2.43.0 +
View file
_service:tar_scm:0008-LoongArch-Fix-_dl_tlsdesc_dynamic-in-LSX-case.patch
Added
@@ -0,0 +1,73 @@ +From ff46cceb89bb4aab7e510c2d3dc02855500617a0 Mon Sep 17 00:00:00 2001 +From: mengqinggang <mengqinggang@loongson.cn> +Date: Fri, 14 Jun 2024 11:58:30 +0800 +Subject: PATCH 08/15 LoongArch: Fix _dl_tlsdesc_dynamic in LSX case + +HWCAP value is overwritten at the first comparison of the LASX case. +The second comparison at LSX get incorrect result. +Change to use t0 to save HWCAP value, and use t1 to save comparison +result. +--- + sysdeps/loongarch/dl-tlsdesc.S | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/sysdeps/loongarch/dl-tlsdesc.S b/sysdeps/loongarch/dl-tlsdesc.S +index 346b80f2..a6627cc7 100644 +--- a/sysdeps/loongarch/dl-tlsdesc.S ++++ b/sysdeps/loongarch/dl-tlsdesc.S +@@ -81,7 +81,7 @@ _dl_tlsdesc_undefweak: + _dl_tlsdesc_dynamic (struct tlsdesc *tdp) + { + struct tlsdesc_dynamic_arg *td = tdp->arg; +- dtv_t *dtv = *(dtv_t **)((char *)__thread_pointer - TCBHEAD_DTV); ++ dtv_t *dtv = *(dtv_t **)((char *)__thread_pointer - SIZE_OF_TCB); + if (__glibc_likely (td->gen_count <= dtv0.counter + && (dtvtd->tlsinfo.ti_module.pointer.val + != TLS_DTV_UNALLOCATED), +@@ -177,8 +177,8 @@ Hign address dynamic_block1 <----- dtv5 */ + /* Whether support LASX. */ + la.global t0, _rtld_global_ro + REG_L t0, t0, GLRO_DL_HWCAP_OFFSET +- andi t0, t0, HWCAP_LOONGARCH_LASX +- beqz t0, .Llsx ++ andi t1, t0, HWCAP_LOONGARCH_LASX ++ beqz t1, .Llsx + + /* Save 256-bit vector registers. + FIXME: Without vector ABI, save all vector registers. */ +@@ -219,8 +219,8 @@ Hign address dynamic_block1 <----- dtv5 */ + + .Llsx: + /* Whether support LSX. */ +- andi t0, t0, HWCAP_LOONGARCH_LSX +- beqz t0, .Lfloat ++ andi t1, t0, HWCAP_LOONGARCH_LSX ++ beqz t1, .Lfloat + + /* Save 128-bit vector registers. */ + ADDI sp, sp, -FRAME_SIZE_LSX +@@ -296,8 +296,8 @@ Hign address dynamic_block1 <----- dtv5 */ + + la.global t0, _rtld_global_ro + REG_L t0, t0, GLRO_DL_HWCAP_OFFSET +- andi t0, t0, HWCAP_LOONGARCH_LASX +- beqz t0, .Llsx1 ++ andi t1, t0, HWCAP_LOONGARCH_LASX ++ beqz t1, .Llsx1 + + /* Restore 256-bit vector registers. */ + xvld xr0, sp, 0*SZXREG +@@ -336,8 +336,8 @@ Hign address dynamic_block1 <----- dtv5 */ + b .Lfcsr + + .Llsx1: +- andi t0, s0, HWCAP_LOONGARCH_LSX +- beqz t0, .Lfloat1 ++ andi t1, t0, HWCAP_LOONGARCH_LSX ++ beqz t1, .Lfloat1 + + /* Restore 128-bit vector registers. */ + vld vr0, sp, 0*SZVREG +-- +2.43.0 +
View file
_service:tar_scm:0009-LoongArch-Fix-tst-gnu2-tls2-test-case.patch
Added
@@ -0,0 +1,420 @@ +From b230d00bc0f6ab5cd7b017b7d4307ea8e55c261a Mon Sep 17 00:00:00 2001 +From: mengqinggang <mengqinggang@loongson.cn> +Date: Fri, 21 Jun 2024 16:08:53 +0800 +Subject: PATCH 09/15 LoongArch: Fix tst-gnu2-tls2 test case + +asm volatile ("movfcsr2gr $t0, $fcsr0" ::: "$t0"); +asm volatile ("st.d $t0, %0" :"=m"(restore_fcsr)); + +generate to the following instructions with -Og flag: + +movfcsr2gr $t0, $zero +addi.d $t0, $sp, 2047(0x7ff) +addi.d $t0, $t0, 77(0x4d) +st.w $t0, $t0, 0 + +fcsr0 register and restore_fcsr variable are both stored in t0 register. + +Change to: + +asm volatile ("movfcsr2gr %0, $fcsr0" :"=r"(restore_fcsr)); + +to avoid restore_fcsr address in t0. + +Comparing float value using memcmp because float value cannot be +directly compared for equality. + +Put LOAD_REGISTER_FCSR and SAVE_REGISTER_FCC after LOAD_REGISTER_FLOAT. +Some float instructions may change fcsr register. +--- + sysdeps/loongarch/tst-gnu2-tls2.h | 296 +++++++++++++++--------------- + 1 file changed, 153 insertions(+), 143 deletions(-) + +diff --git a/sysdeps/loongarch/tst-gnu2-tls2.h b/sysdeps/loongarch/tst-gnu2-tls2.h +index 8e421678..863abe59 100644 +--- a/sysdeps/loongarch/tst-gnu2-tls2.h ++++ b/sysdeps/loongarch/tst-gnu2-tls2.h +@@ -16,6 +16,7 @@ + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + ++#include <stdio.h> + #include <config.h> + #include <string.h> + #include <stdlib.h> +@@ -42,35 +43,35 @@ + #else /* hard float */ + + #define SAVE_REGISTER_FCC(src) \ +- asm volatile ("movcf2gr $t0, $fcc0" ::: "$t0"); \ +- asm volatile ("st.d $t0, %0" :"=m"(src0) :); \ +- asm volatile ("movcf2gr $t0, $fcc1" ::: "$t0"); \ +- asm volatile ("st.d $t0, %0" :"=m"(src1) :); \ +- asm volatile ("movcf2gr $t0, $fcc2" ::: "$t0"); \ +- asm volatile ("st.d $t0, %0" :"=m"(src2) :); \ +- asm volatile ("movcf2gr $t0, $fcc3" ::: "$t0"); \ +- asm volatile ("st.d $t0, %0" :"=m"(src3) :); \ +- asm volatile ("movcf2gr $t0, $fcc4" ::: "$t0"); \ +- asm volatile ("st.d $t0, %0" :"=m"(src4) :); \ +- asm volatile ("movcf2gr $t0, $fcc5" ::: "$t0"); \ +- asm volatile ("st.d $t0, %0" :"=m"(src5) :); \ +- asm volatile ("movcf2gr $t0, $fcc6" ::: "$t0"); \ +- asm volatile ("st.d $t0, %0" :"=m"(src6) :); \ +- asm volatile ("movcf2gr $t0, $fcc7" ::: "$t0"); \ +- asm volatile ("st.d $t0, %0" :"=m"(src7) :); ++ asm volatile ("movcf2gr %0, $fcc0" :"=r"(src0)); \ ++ asm volatile ("movcf2gr %0, $fcc1" :"=r"(src1)); \ ++ asm volatile ("movcf2gr %0, $fcc2" :"=r"(src2)); \ ++ asm volatile ("movcf2gr %0, $fcc3" :"=r"(src3)); \ ++ asm volatile ("movcf2gr %0, $fcc4" :"=r"(src4)); \ ++ asm volatile ("movcf2gr %0, $fcc5" :"=r"(src5)); \ ++ asm volatile ("movcf2gr %0, $fcc6" :"=r"(src6)); \ ++ asm volatile ("movcf2gr %0, $fcc7" :"=r"(src7)); \ + + #define LOAD_REGISTER_FCSR() \ ++ uint64_t src_fcsr = 0x01010101; \ + asm volatile ("li.d $t0, 0x01010101" ::: "$t0"); \ + asm volatile ("movgr2fcsr $fcsr0, $t0" :::); + +-#define SAVE_REGISTER_FCSR() \ +- asm volatile ("movfcsr2gr $t0, $fcsr0" ::: "$t0"); \ +- asm volatile ("st.d $t0, %0" :"=m"(restore_fcsr) :); ++#define SAVE_REGISTER_FCSR() \ ++ uint64_t restore_fcsr; \ ++ asm volatile ("movfcsr2gr %0, $fcsr0" :"=r"(restore_fcsr)); \ ++ if (src_fcsr != restore_fcsr) \ ++ { \ ++ printf ("FCSR registers compare failed!\n"); \ ++ abort (); \ ++ } \ + +-# define INIT_TLSDESC_CALL() \ ++#define INIT_TLSDESC_CALL() \ + unsigned long hwcap = getauxval (AT_HWCAP); + + #define LOAD_REGISTER_FLOAT() \ ++ for (int i = 0; i < 32; i++) \ ++ src_floati = i + 1; \ + asm volatile ("fld.d $f0, %0" ::"m"(src_float0) :"$f0"); \ + asm volatile ("fld.d $f1, %0" ::"m"(src_float1) :"$f1"); \ + asm volatile ("fld.d $f2, %0" ::"m"(src_float2) :"$f2"); \ +@@ -105,38 +106,44 @@ + asm volatile ("fld.d $f31, %0" ::"m"(src_float31) :"$f31"); + + #define SAVE_REGISTER_FLOAT() \ +- asm volatile ("fst.d $f0, %0" :"=m"(restore_float0) :); \ +- asm volatile ("fst.d $f1, %0" :"=m"(restore_float1) :); \ +- asm volatile ("fst.d $f2, %0" :"=m"(restore_float2) :); \ +- asm volatile ("fst.d $f3, %0" :"=m"(restore_float3) :); \ +- asm volatile ("fst.d $f4, %0" :"=m"(restore_float4) :); \ +- asm volatile ("fst.d $f5, %0" :"=m"(restore_float5) :); \ +- asm volatile ("fst.d $f6, %0" :"=m"(restore_float6) :); \ +- asm volatile ("fst.d $f7, %0" :"=m"(restore_float7) :); \ +- asm volatile ("fst.d $f8, %0" :"=m"(restore_float8) :); \ +- asm volatile ("fst.d $f9, %0" :"=m"(restore_float9) :); \ +- asm volatile ("fst.d $f10, %0" :"=m"(restore_float10) :); \ +- asm volatile ("fst.d $f11, %0" :"=m"(restore_float11) :); \ +- asm volatile ("fst.d $f12, %0" :"=m"(restore_float12) :); \ +- asm volatile ("fst.d $f13, %0" :"=m"(restore_float13) :); \ +- asm volatile ("fst.d $f14, %0" :"=m"(restore_float14) :); \ +- asm volatile ("fst.d $f15, %0" :"=m"(restore_float15) :); \ +- asm volatile ("fst.d $f16, %0" :"=m"(restore_float16) :); \ +- asm volatile ("fst.d $f17, %0" :"=m"(restore_float17) :); \ +- asm volatile ("fst.d $f18, %0" :"=m"(restore_float18) :); \ +- asm volatile ("fst.d $f19, %0" :"=m"(restore_float19) :); \ +- asm volatile ("fst.d $f20, %0" :"=m"(restore_float20) :); \ +- asm volatile ("fst.d $f21, %0" :"=m"(restore_float21) :); \ +- asm volatile ("fst.d $f22, %0" :"=m"(restore_float22) :); \ +- asm volatile ("fst.d $f23, %0" :"=m"(restore_float23) :); \ +- asm volatile ("fst.d $f24, %0" :"=m"(restore_float24) :); \ +- asm volatile ("fst.d $f25, %0" :"=m"(restore_float25) :); \ +- asm volatile ("fst.d $f26, %0" :"=m"(restore_float26) :); \ +- asm volatile ("fst.d $f27, %0" :"=m"(restore_float27) :); \ +- asm volatile ("fst.d $f28, %0" :"=m"(restore_float28) :); \ +- asm volatile ("fst.d $f29, %0" :"=m"(restore_float29) :); \ +- asm volatile ("fst.d $f30, %0" :"=m"(restore_float30) :); \ +- asm volatile ("fst.d $f31, %0" :"=m"(restore_float31) :); ++ double restore_float32; \ ++ asm volatile ("fst.d $f0, %0" :"=m"(restore_float0)); \ ++ asm volatile ("fst.d $f1, %0" :"=m"(restore_float1)); \ ++ asm volatile ("fst.d $f2, %0" :"=m"(restore_float2)); \ ++ asm volatile ("fst.d $f3, %0" :"=m"(restore_float3)); \ ++ asm volatile ("fst.d $f4, %0" :"=m"(restore_float4)); \ ++ asm volatile ("fst.d $f5, %0" :"=m"(restore_float5)); \ ++ asm volatile ("fst.d $f6, %0" :"=m"(restore_float6)); \ ++ asm volatile ("fst.d $f7, %0" :"=m"(restore_float7)); \ ++ asm volatile ("fst.d $f8, %0" :"=m"(restore_float8)); \ ++ asm volatile ("fst.d $f9, %0" :"=m"(restore_float9)); \ ++ asm volatile ("fst.d $f10, %0" :"=m"(restore_float10)); \ ++ asm volatile ("fst.d $f11, %0" :"=m"(restore_float11)); \ ++ asm volatile ("fst.d $f12, %0" :"=m"(restore_float12)); \ ++ asm volatile ("fst.d $f13, %0" :"=m"(restore_float13)); \ ++ asm volatile ("fst.d $f14, %0" :"=m"(restore_float14)); \ ++ asm volatile ("fst.d $f15, %0" :"=m"(restore_float15)); \ ++ asm volatile ("fst.d $f16, %0" :"=m"(restore_float16)); \ ++ asm volatile ("fst.d $f17, %0" :"=m"(restore_float17)); \ ++ asm volatile ("fst.d $f18, %0" :"=m"(restore_float18)); \ ++ asm volatile ("fst.d $f19, %0" :"=m"(restore_float19)); \ ++ asm volatile ("fst.d $f20, %0" :"=m"(restore_float20)); \ ++ asm volatile ("fst.d $f21, %0" :"=m"(restore_float21)); \ ++ asm volatile ("fst.d $f22, %0" :"=m"(restore_float22)); \ ++ asm volatile ("fst.d $f23, %0" :"=m"(restore_float23)); \ ++ asm volatile ("fst.d $f24, %0" :"=m"(restore_float24)); \ ++ asm volatile ("fst.d $f25, %0" :"=m"(restore_float25)); \ ++ asm volatile ("fst.d $f26, %0" :"=m"(restore_float26)); \ ++ asm volatile ("fst.d $f27, %0" :"=m"(restore_float27)); \ ++ asm volatile ("fst.d $f28, %0" :"=m"(restore_float28)); \ ++ asm volatile ("fst.d $f29, %0" :"=m"(restore_float29)); \ ++ asm volatile ("fst.d $f30, %0" :"=m"(restore_float30)); \ ++ asm volatile ("fst.d $f31, %0" :"=m"(restore_float31)); \ ++ if (memcmp (src_float, restore_float, sizeof (src_float)) != 0) \ ++ { \ ++ printf ("Float registers compare failed!\n"); \ ++ abort (); \ ++ } + + #ifdef HAVE_LOONGARCH_VEC_COM + #define LOAD_REGISTER_LSX() \ +@@ -181,44 +188,47 @@ + #define SAVE_REGISTER_LSX() \ + int src_lsx324; \ + int restore_lsx324; \ +- asm volatile ("vst $vr0, %0" :"=m"(restore_lsx0) :); \ +- asm volatile ("vst $vr1, %0" :"=m"(restore_lsx1) :); \ +- asm volatile ("vst $vr2, %0" :"=m"(restore_lsx2) :); \ +- asm volatile ("vst $vr3, %0" :"=m"(restore_lsx3) :); \ +- asm volatile ("vst $vr4, %0" :"=m"(restore_lsx4) :); \ +- asm volatile ("vst $vr5, %0" :"=m"(restore_lsx5) :); \ +- asm volatile ("vst $vr6, %0" :"=m"(restore_lsx6) :); \ +- asm volatile ("vst $vr7, %0" :"=m"(restore_lsx7) :); \ +- asm volatile ("vst $vr8, %0" :"=m"(restore_lsx8) :); \ +- asm volatile ("vst $vr9, %0" :"=m"(restore_lsx9) :); \ +- asm volatile ("vst $vr10, %0" :"=m"(restore_lsx10) :); \ +- asm volatile ("vst $vr11, %0" :"=m"(restore_lsx11) :); \ +- asm volatile ("vst $vr12, %0" :"=m"(restore_lsx12) :); \ +- asm volatile ("vst $vr13, %0" :"=m"(restore_lsx13) :); \ +- asm volatile ("vst $vr14, %0" :"=m"(restore_lsx14) :); \ +- asm volatile ("vst $vr15, %0" :"=m"(restore_lsx15) :); \ +- asm volatile ("vst $vr16, %0" :"=m"(restore_lsx16) :); \ +- asm volatile ("vst $vr17, %0" :"=m"(restore_lsx17) :); \ +- asm volatile ("vst $vr18, %0" :"=m"(restore_lsx18) :); \ +- asm volatile ("vst $vr19, %0" :"=m"(restore_lsx19) :); \ +- asm volatile ("vst $vr20, %0" :"=m"(restore_lsx20) :); \ +- asm volatile ("vst $vr21, %0" :"=m"(restore_lsx21) :); \ +- asm volatile ("vst $vr22, %0" :"=m"(restore_lsx22) :); \ +- asm volatile ("vst $vr23, %0" :"=m"(restore_lsx23) :); \ +- asm volatile ("vst $vr24, %0" :"=m"(restore_lsx24) :); \ +- asm volatile ("vst $vr25, %0" :"=m"(restore_lsx25) :); \ +- asm volatile ("vst $vr26, %0" :"=m"(restore_lsx26) :); \ +- asm volatile ("vst $vr27, %0" :"=m"(restore_lsx27) :); \ +- asm volatile ("vst $vr28, %0" :"=m"(restore_lsx28) :); \ +- asm volatile ("vst $vr29, %0" :"=m"(restore_lsx29) :); \ +- asm volatile ("vst $vr30, %0" :"=m"(restore_lsx30) :); \ +- asm volatile ("vst $vr31, %0" :"=m"(restore_lsx31) :); \ ++ asm volatile ("vst $vr0, %0" :"=m"(restore_lsx0)); \ ++ asm volatile ("vst $vr1, %0" :"=m"(restore_lsx1)); \ ++ asm volatile ("vst $vr2, %0" :"=m"(restore_lsx2)); \ ++ asm volatile ("vst $vr3, %0" :"=m"(restore_lsx3)); \ ++ asm volatile ("vst $vr4, %0" :"=m"(restore_lsx4)); \ ++ asm volatile ("vst $vr5, %0" :"=m"(restore_lsx5)); \ ++ asm volatile ("vst $vr6, %0" :"=m"(restore_lsx6)); \ ++ asm volatile ("vst $vr7, %0" :"=m"(restore_lsx7)); \ ++ asm volatile ("vst $vr8, %0" :"=m"(restore_lsx8)); \ ++ asm volatile ("vst $vr9, %0" :"=m"(restore_lsx9)); \ ++ asm volatile ("vst $vr10, %0" :"=m"(restore_lsx10)); \ ++ asm volatile ("vst $vr11, %0" :"=m"(restore_lsx11)); \ ++ asm volatile ("vst $vr12, %0" :"=m"(restore_lsx12)); \ ++ asm volatile ("vst $vr13, %0" :"=m"(restore_lsx13)); \ ++ asm volatile ("vst $vr14, %0" :"=m"(restore_lsx14)); \ ++ asm volatile ("vst $vr15, %0" :"=m"(restore_lsx15)); \ ++ asm volatile ("vst $vr16, %0" :"=m"(restore_lsx16)); \ ++ asm volatile ("vst $vr17, %0" :"=m"(restore_lsx17)); \ ++ asm volatile ("vst $vr18, %0" :"=m"(restore_lsx18)); \ ++ asm volatile ("vst $vr19, %0" :"=m"(restore_lsx19)); \ ++ asm volatile ("vst $vr20, %0" :"=m"(restore_lsx20)); \ ++ asm volatile ("vst $vr21, %0" :"=m"(restore_lsx21)); \ ++ asm volatile ("vst $vr22, %0" :"=m"(restore_lsx22)); \ ++ asm volatile ("vst $vr23, %0" :"=m"(restore_lsx23)); \ ++ asm volatile ("vst $vr24, %0" :"=m"(restore_lsx24)); \ ++ asm volatile ("vst $vr25, %0" :"=m"(restore_lsx25)); \ ++ asm volatile ("vst $vr26, %0" :"=m"(restore_lsx26)); \ ++ asm volatile ("vst $vr27, %0" :"=m"(restore_lsx27)); \ ++ asm volatile ("vst $vr28, %0" :"=m"(restore_lsx28)); \ ++ asm volatile ("vst $vr29, %0" :"=m"(restore_lsx29)); \ ++ asm volatile ("vst $vr30, %0" :"=m"(restore_lsx30)); \ ++ asm volatile ("vst $vr31, %0" :"=m"(restore_lsx31)); \ + for (int i = 0; i < 32; i++) \ + for (int j = 0; j < 4; j++) \ + { \ + src_lsxij = 0x01010101 * (i + 1); \ + if (src_lsxij != restore_lsxij) \ +- abort (); \ ++ { \ ++ printf ("LSX registers compare failed!\n"); \ ++ abort (); \ ++ } \ + } + #else + #define SAVE_REGISTER_LSX() +@@ -267,44 +277,48 @@ + #define SAVE_REGISTER_LASX() \ + int src_lasx328; \ + int restore_lasx328; \ +- asm volatile ("xvst $xr0, %0" :"=m"(restore_lasx0) :); \ +- asm volatile ("xvst $xr1, %0" :"=m"(restore_lasx1) :); \ +- asm volatile ("xvst $xr2, %0" :"=m"(restore_lasx2) :); \ +- asm volatile ("xvst $xr3, %0" :"=m"(restore_lasx3) :); \ +- asm volatile ("xvst $xr4, %0" :"=m"(restore_lasx4) :); \ +- asm volatile ("xvst $xr5, %0" :"=m"(restore_lasx5) :); \ +- asm volatile ("xvst $xr6, %0" :"=m"(restore_lasx6) :); \ +- asm volatile ("xvst $xr7, %0" :"=m"(restore_lasx7) :); \ +- asm volatile ("xvst $xr8, %0" :"=m"(restore_lasx8) :); \ +- asm volatile ("xvst $xr9, %0" :"=m"(restore_lasx9) :); \ +- asm volatile ("xvst $xr10, %0" :"=m"(restore_lasx10) :); \ +- asm volatile ("xvst $xr11, %0" :"=m"(restore_lasx11) :); \ +- asm volatile ("xvst $xr12, %0" :"=m"(restore_lasx12) :); \ +- asm volatile ("xvst $xr13, %0" :"=m"(restore_lasx13) :); \ +- asm volatile ("xvst $xr14, %0" :"=m"(restore_lasx14) :); \ +- asm volatile ("xvst $xr15, %0" :"=m"(restore_lasx15) :); \ +- asm volatile ("xvst $xr16, %0" :"=m"(restore_lasx16) :); \ +- asm volatile ("xvst $xr17, %0" :"=m"(restore_lasx17) :); \ +- asm volatile ("xvst $xr18, %0" :"=m"(restore_lasx18) :); \ +- asm volatile ("xvst $xr19, %0" :"=m"(restore_lasx19) :); \ +- asm volatile ("xvst $xr20, %0" :"=m"(restore_lasx20) :); \ +- asm volatile ("xvst $xr21, %0" :"=m"(restore_lasx21) :); \ +- asm volatile ("xvst $xr22, %0" :"=m"(restore_lasx22) :); \ +- asm volatile ("xvst $xr23, %0" :"=m"(restore_lasx23) :); \ +- asm volatile ("xvst $xr24, %0" :"=m"(restore_lasx24) :); \ +- asm volatile ("xvst $xr25, %0" :"=m"(restore_lasx25) :); \ +- asm volatile ("xvst $xr26, %0" :"=m"(restore_lasx26) :); \ +- asm volatile ("xvst $xr27, %0" :"=m"(restore_lasx27) :); \ +- asm volatile ("xvst $xr28, %0" :"=m"(restore_lasx28) :); \ +- asm volatile ("xvst $xr29, %0" :"=m"(restore_lasx29) :); \ +- asm volatile ("xvst $xr30, %0" :"=m"(restore_lasx30) :); \ +- asm volatile ("xvst $xr31, %0" :"=m"(restore_lasx31) :); \ ++ asm volatile ("xvst $xr0, %0" :"=m"(restore_lasx0)); \ ++ asm volatile ("xvst $xr1, %0" :"=m"(restore_lasx1)); \ ++ asm volatile ("xvst $xr2, %0" :"=m"(restore_lasx2)); \ ++ asm volatile ("xvst $xr3, %0" :"=m"(restore_lasx3)); \ ++ asm volatile ("xvst $xr4, %0" :"=m"(restore_lasx4)); \ ++ asm volatile ("xvst $xr5, %0" :"=m"(restore_lasx5)); \ ++ asm volatile ("xvst $xr6, %0" :"=m"(restore_lasx6)); \ ++ asm volatile ("xvst $xr7, %0" :"=m"(restore_lasx7)); \ ++ asm volatile ("xvst $xr8, %0" :"=m"(restore_lasx8)); \ ++ asm volatile ("xvst $xr9, %0" :"=m"(restore_lasx9)); \ ++ asm volatile ("xvst $xr10, %0" :"=m"(restore_lasx10)); \ ++ asm volatile ("xvst $xr11, %0" :"=m"(restore_lasx11)); \ ++ asm volatile ("xvst $xr12, %0" :"=m"(restore_lasx12)); \ ++ asm volatile ("xvst $xr13, %0" :"=m"(restore_lasx13)); \ ++ asm volatile ("xvst $xr14, %0" :"=m"(restore_lasx14)); \ ++ asm volatile ("xvst $xr15, %0" :"=m"(restore_lasx15)); \ ++ asm volatile ("xvst $xr16, %0" :"=m"(restore_lasx16)); \ ++ asm volatile ("xvst $xr17, %0" :"=m"(restore_lasx17)); \ ++ asm volatile ("xvst $xr18, %0" :"=m"(restore_lasx18)); \ ++ asm volatile ("xvst $xr19, %0" :"=m"(restore_lasx19)); \ ++ asm volatile ("xvst $xr20, %0" :"=m"(restore_lasx20)); \ ++ asm volatile ("xvst $xr21, %0" :"=m"(restore_lasx21)); \ ++ asm volatile ("xvst $xr22, %0" :"=m"(restore_lasx22)); \ ++ asm volatile ("xvst $xr23, %0" :"=m"(restore_lasx23)); \ ++ asm volatile ("xvst $xr24, %0" :"=m"(restore_lasx24)); \ ++ asm volatile ("xvst $xr25, %0" :"=m"(restore_lasx25)); \ ++ asm volatile ("xvst $xr26, %0" :"=m"(restore_lasx26)); \ ++ asm volatile ("xvst $xr27, %0" :"=m"(restore_lasx27)); \ ++ asm volatile ("xvst $xr28, %0" :"=m"(restore_lasx28)); \ ++ asm volatile ("xvst $xr29, %0" :"=m"(restore_lasx29)); \ ++ asm volatile ("xvst $xr30, %0" :"=m"(restore_lasx30)); \ ++ asm volatile ("xvst $xr31, %0" :"=m"(restore_lasx31)); \ ++ /* memcmp_lasx/strlen_lasx corrupts LSX/LASX registers, */ \ + for (int i = 0; i < 32; i++) \ + for (int j = 0; j < 8; j++) \ + { \ + src_lasxij = 0x01010101 * (i + 1); \ + if (src_lasxij != restore_lasxij) \ +- abort (); \ ++ { \ ++ printf ("LASX registers compare failed!\n"); \ ++ abort (); \ ++ } \ + } + #else + #define SAVE_REGISTER_LASX() +@@ -314,12 +328,7 @@ + uint64_t src; \ + double src_float32; \ + uint64_t src_fcc8; \ +- for (int i = 0; i < 32; i++) \ +- src_floati = i + 1; \ +- \ + SAVE_REGISTER (src); \ +- LOAD_REGISTER_FCSR (); \ +- SAVE_REGISTER_FCC(src_fcc) \ + \ + if (hwcap & HWCAP_LOONGARCH_LASX) \ + { \ +@@ -332,19 +341,34 @@ + else \ + { \ + LOAD_REGISTER_FLOAT (); \ +- } ++ } \ ++ \ ++ /* LOAD_REGISTER_FLOAT convert int double may change fcsr. */ \ ++ LOAD_REGISTER_FCSR (); \ ++ SAVE_REGISTER_FCC (src_fcc) ++ + + #define AFTER_TLSDESC_CALL() \ + uint64_t restore; \ +- uint64_t src_fcsr = 0x01010101; \ +- uint64_t restore_fcsr; \ + uint64_t restore_fcc8; \ ++ \ + SAVE_REGISTER (restore); \ ++ if (src != restore) \ ++ { \ ++ printf ("General registers compare failed!\n"); \ ++ abort (); \ ++ } \ ++ \ + SAVE_REGISTER_FCSR (); \ +- SAVE_REGISTER_FCC(restore_fcc) \ + \ +- /* memcmp_lasx/strlen_lasx corrupts LSX/LASX registers, */ \ +- /* compare LSX/LASX registers first. */ \ ++ SAVE_REGISTER_FCC (restore_fcc) \ ++ for (int i = 0; i < 8; i++) \ ++ if (src_fcci != restore_fcci) \ ++ { \ ++ printf ("FCC registers compare failed!\n"); \ ++ abort (); \ ++ } \ ++ \ + if (hwcap & HWCAP_LOONGARCH_LASX) \ + { \ + SAVE_REGISTER_LASX (); \ +@@ -355,22 +379,8 @@ + } \ + else \ + { \ +- double restore_float32; \ + SAVE_REGISTER_FLOAT (); \ +- \ +- for (int i = 0; i < 32; i++) \ +- if (src_floati != restore_floati) \ +- abort (); \ + } \ +- \ +- if (src_fcsr != restore_fcsr) \ +- abort (); \ +- \ +- if (memcmp (src_fcc, restore_fcc, sizeof (src_fcc)) != 0) \ +- abort (); \ +- \ +- if (src != restore) \ +- abort (); + + #endif /* #ifdef __loongarch_soft_float */ + +-- +2.43.0 +
View file
_service:tar_scm:0010-LoongArch-Add-cfi-instructions-for-_dl_tlsdesc_dynam.patch
Added
@@ -0,0 +1,719 @@ +From 4c3e5be27dd56bb67f7e259f6f24dcb392b3aaa2 Mon Sep 17 00:00:00 2001 +From: mengqinggang <mengqinggang@loongson.cn> +Date: Fri, 5 Jul 2024 10:40:33 +0800 +Subject: PATCH 10/15 LoongArch: Add cfi instructions for _dl_tlsdesc_dynamic + +In _dl_tlsdesc_dynamic, there are three 'addi.d sp, sp, -size' +instructions to allocate stack size for Float/LSX/LASX registers. +Every 'addi.d sp, sp, -size' needs a cfi_adjust_cfa_offset because +of sp is used to compute CFA. But only one 'addi.d sp, sp, -size' +will be run according to HWCAP value. And all cfi_adjust_cfa_offset +will be executed in stack unwinding, it result in incorrect CFA. + +Change _dl_tlsdesc_dynamic to _dl_tlsdesc_dynamic, +_dl_tlsdesc_dynamic_lsx and _dl_tlsdesc_dynamic_lasx. +Conflicting cfi instructions can be distributed to the three functions. +And cfi instructions can correspond to stack down instructions. +--- + sysdeps/loongarch/dl-machine.h | 7 + + sysdeps/loongarch/dl-tlsdesc-dynamic.h | 225 ++++++++++++++ + sysdeps/loongarch/dl-tlsdesc.S | 386 ++----------------------- + sysdeps/loongarch/dl-tlsdesc.h | 4 + + sysdeps/loongarch/tlsdesc.sym | 9 - + 5 files changed, 258 insertions(+), 373 deletions(-) + create mode 100644 sysdeps/loongarch/dl-tlsdesc-dynamic.h + +diff --git a/sysdeps/loongarch/dl-machine.h b/sysdeps/loongarch/dl-machine.h +index 222d51a8..d934c77f 100644 +--- a/sysdeps/loongarch/dl-machine.h ++++ b/sysdeps/loongarch/dl-machine.h +@@ -222,6 +222,13 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope, + { + td->arg = _dl_make_tlsdesc_dynamic (sym_map, + sym->st_value + reloc->r_addend); ++# ifndef __loongarch_soft_float ++ if (RTLD_SUPPORT_LASX) ++ td->entry = _dl_tlsdesc_dynamic_lasx; ++ else if (RTLD_SUPPORT_LSX) ++ td->entry = _dl_tlsdesc_dynamic_lsx; ++ else ++# endif + td->entry = _dl_tlsdesc_dynamic; + } + else +diff --git a/sysdeps/loongarch/dl-tlsdesc-dynamic.h b/sysdeps/loongarch/dl-tlsdesc-dynamic.h +new file mode 100644 +index 00000000..d10f4a88 +--- /dev/null ++++ b/sysdeps/loongarch/dl-tlsdesc-dynamic.h +@@ -0,0 +1,225 @@ ++/* Thread-local storage handling in the ELF dynamic linker. ++ LoongArch version. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <https://www.gnu.org/licenses/>. */ ++ ++#define FRAME_SIZE (-((-14 * SZREG) & ALMASK)) ++#define FRAME_SIZE_LSX (-((-32 * SZVREG) & ALMASK)) ++#define FRAME_SIZE_LASX (-((-32 * SZXREG) & ALMASK)) ++#define FRAME_SIZE_FLOAT (-((-24 * SZFREG) & ALMASK)) ++ ++ /* Handler for dynamic TLS symbols. ++ Prototype: ++ _dl_tlsdesc_dynamic (tlsdesc *) ; ++ ++ The second word of the descriptor points to a ++ tlsdesc_dynamic_arg structure. ++ ++ Returns the offset between the thread pointer and the ++ object referenced by the argument. ++ ++ ptrdiff_t ++ _dl_tlsdesc_dynamic (struct tlsdesc *tdp) ++ { ++ struct tlsdesc_dynamic_arg *td = tdp->arg; ++ dtv_t *dtv = *(dtv_t **)((char *)__thread_pointer - SIZE_OF_TCB); ++ if (__glibc_likely (td->gen_count <= dtv0.counter ++ && (dtvtd->tlsinfo.ti_module.pointer.val ++ != TLS_DTV_UNALLOCATED), ++ 1)) ++ return dtvtd->tlsinfo.ti_module.pointer.val ++ + td->tlsinfo.ti_offset ++ - __thread_pointer; ++ ++ return ___tls_get_addr (&td->tlsinfo) - __thread_pointer; ++ } */ ++ .hidden _dl_tlsdesc_dynamic ++ .global _dl_tlsdesc_dynamic ++ .type _dl_tlsdesc_dynamic,%function ++ cfi_startproc ++ .align 2 ++_dl_tlsdesc_dynamic: ++ /* Save just enough registers to support fast path, if we fall ++ into slow path we will save additional registers. */ ++ ADDI sp, sp, -32 ++ cfi_adjust_cfa_offset (32) ++ REG_S t0, sp, 0 ++ REG_S t1, sp, 8 ++ REG_S t2, sp, 16 ++ cfi_rel_offset (12, 0) ++ cfi_rel_offset (13, 8) ++ cfi_rel_offset (14, 16) ++ ++/* Runtime Storage Layout of Thread-Local Storage ++ TP point to the start of TLS block. ++ ++ dtv ++Low address TCB ----------------> dtv0(counter) ++ TP --> static_block0 <----- dtv1 ++ static_block1 <----- dtv2 ++ static_block2 <----- dtv3 ++ dynamic_block0 <----- dtv4 ++Hign address dynamic_block1 <----- dtv5 */ ++ ++ REG_L t0, tp, -SIZE_OF_TCB /* t0 = dtv */ ++ REG_L a0, a0, TLSDESC_ARG /* a0(td) = tdp->arg */ ++ REG_L t1, a0, TLSDESC_GEN_COUNT /* t1 = td->gen_count */ ++ REG_L t2, t0, DTV_COUNTER /* t2 = dtv0.counter */ ++ /* If dtv0.counter < td->gen_count, goto slow path. */ ++ bltu t2, t1, .Lslow ++ ++ REG_L t1, a0, TLSDESC_MODID /* t1 = td->tlsinfo.ti_module */ ++ /* t1 = t1 * sizeof(dtv_t) = t1 * (2 * sizeof(void*)) */ ++ slli.d t1, t1, 4 ++ add.d t1, t1, t0 /* t1 = dtvtd->tlsinfo.ti_module */ ++ REG_L t1, t1, 0 /* t1 = dtvtd->tlsinfo.ti_module.pointer.val */ ++ li.d t2, TLS_DTV_UNALLOCATED ++ /* If dtvtd->tlsinfo.ti_module.pointer.val is TLS_DTV_UNALLOCATED, ++ goto slow path. */ ++ beq t1, t2, .Lslow ++ ++ cfi_remember_state ++ REG_L t2, a0, TLSDESC_MODOFF /* t2 = td->tlsinfo.ti_offset */ ++ /* dtvtd->tlsinfo.ti_module.pointer.val + td->tlsinfo.ti_offset */ ++ add.d a0, t1, t2 ++.Lret: ++ sub.d a0, a0, tp ++ REG_L t0, sp, 0 ++ REG_L t1, sp, 8 ++ REG_L t2, sp, 16 ++ ADDI sp, sp, 32 ++ cfi_adjust_cfa_offset (-32) ++ RET ++ ++.Lslow: ++ /* This is the slow path. We need to call __tls_get_addr() which ++ means we need to save and restore all the register that the ++ callee will trash. */ ++ ++ /* Save the remaining registers that we must treat as caller save. */ ++ cfi_restore_state ++ ADDI sp, sp, -FRAME_SIZE ++ cfi_adjust_cfa_offset (FRAME_SIZE) ++ REG_S ra, sp, 0 * SZREG ++ REG_S a1, sp, 1 * SZREG ++ REG_S a2, sp, 2 * SZREG ++ REG_S a3, sp, 3 * SZREG ++ REG_S a4, sp, 4 * SZREG ++ REG_S a5, sp, 5 * SZREG ++ REG_S a6, sp, 6 * SZREG ++ REG_S a7, sp, 7 * SZREG ++ REG_S t3, sp, 8 * SZREG ++ REG_S t4, sp, 9 * SZREG ++ REG_S t5, sp, 10 * SZREG ++ REG_S t6, sp, 11 * SZREG ++ REG_S t7, sp, 12 * SZREG ++ REG_S t8, sp, 13 * SZREG ++ cfi_rel_offset (1, 0 * SZREG) ++ cfi_rel_offset (5, 1 * SZREG) ++ cfi_rel_offset (6, 2 * SZREG) ++ cfi_rel_offset (7, 3 * SZREG) ++ cfi_rel_offset (8, 4 * SZREG) ++ cfi_rel_offset (9, 5 * SZREG) ++ cfi_rel_offset (10, 6 * SZREG) ++ cfi_rel_offset (11, 7 * SZREG) ++ cfi_rel_offset (15, 8 * SZREG) ++ cfi_rel_offset (16, 9 * SZREG) ++ cfi_rel_offset (17, 10 * SZREG) ++ cfi_rel_offset (18, 11 * SZREG) ++ cfi_rel_offset (19, 12 * SZREG) ++ cfi_rel_offset (20, 13 * SZREG) ++ ++#ifndef __loongarch_soft_float ++ ++ /* Save fcsr0 register. ++ Only one physical fcsr0 register, fcsr1-fcsr3 are aliases ++ of some fields in fcsr0. */ ++ movfcsr2gr t0, fcsr0 ++ st.w t0, sp, FRAME_SIZE + 24 /* Use the spare slot above t2. */ ++ ++#ifdef USE_LASX ++ #define V_REG_S xvst ++ #define V_REG_L xvld ++ #define V_SPACE FRAME_SIZE_LASX ++ #define V_REG(n) $xr##n ++ #define V_REGS 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, \ ++ 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 ++ #define V_REGSZ SZXREG ++#elif defined USE_LSX ++ #define V_REG_S vst ++ #define V_REG_L vld ++ #define V_SPACE FRAME_SIZE_LSX ++ #define V_REG(n) $vr##n ++ #define V_REGS 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, \ ++ 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 ++ #define V_REGSZ SZVREG ++#else ++ #define V_REG_S fst.d ++ #define V_REG_L fld.d ++ #define V_SPACE FRAME_SIZE_FLOAT ++ #define V_REG(n) $f##n ++ #define V_REGS 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23 ++ #define V_REGSZ SZFREG ++#endif ++ ++ ADDI sp, sp, -V_SPACE ++ cfi_adjust_cfa_offset (V_SPACE) ++ .irp i,V_REGS ++ V_REG_S V_REG(\i), sp, \i * V_REGSZ ++ .endr ++ ++#endif /* #ifndef __loongarch_soft_float */ ++ ++ bl HIDDEN_JUMPTARGET(__tls_get_addr) ++ ADDI a0, a0, -TLS_DTV_OFFSET ++ ++#ifndef __loongarch_soft_float ++ ++ .irp i,V_REGS ++ V_REG_L V_REG(\i), sp, \i * V_REGSZ ++ .endr ++ ADDI sp, sp, V_SPACE ++ cfi_adjust_cfa_offset (-V_SPACE) ++ ++ /* Restore fcsr0 register. */ ++ ld.w t0, sp, FRAME_SIZE + 24 ++ movgr2fcsr fcsr0, t0 ++ ++#endif /* #ifndef __loongarch_soft_float */ ++ ++ REG_L ra, sp, 0 * SZREG ++ REG_L a1, sp, 1 * SZREG ++ REG_L a2, sp, 2 * SZREG ++ REG_L a3, sp, 3 * SZREG ++ REG_L a4, sp, 4 * SZREG ++ REG_L a5, sp, 5 * SZREG ++ REG_L a6, sp, 6 * SZREG ++ REG_L a7, sp, 7 * SZREG ++ REG_L t3, sp, 8 * SZREG ++ REG_L t4, sp, 9 * SZREG ++ REG_L t5, sp, 10 * SZREG ++ REG_L t6, sp, 11 * SZREG ++ REG_L t7, sp, 12 * SZREG ++ REG_L t8, sp, 13 * SZREG ++ ADDI sp, sp, FRAME_SIZE ++ cfi_adjust_cfa_offset (-FRAME_SIZE) ++ ++ b .Lret ++ cfi_endproc ++ .size _dl_tlsdesc_dynamic, .-_dl_tlsdesc_dynamic ++ .hidden HIDDEN_JUMPTARGET(__tls_get_addr) +diff --git a/sysdeps/loongarch/dl-tlsdesc.S b/sysdeps/loongarch/dl-tlsdesc.S +index a6627cc7..b6cfd612 100644 +--- a/sysdeps/loongarch/dl-tlsdesc.S ++++ b/sysdeps/loongarch/dl-tlsdesc.S +@@ -59,376 +59,34 @@ _dl_tlsdesc_undefweak: + cfi_endproc + .size _dl_tlsdesc_undefweak, .-_dl_tlsdesc_undefweak + +- + #ifdef SHARED + +-#define FRAME_SIZE (-((-14 * SZREG) & ALMASK)) +-#define FRAME_SIZE_LSX (-((-32 * SZVREG) & ALMASK)) +-#define FRAME_SIZE_LASX (-((-32 * SZXREG) & ALMASK)) +-#define FRAME_SIZE_FLOAT (-((-24 * SZFREG) & ALMASK)) +- +- /* Handler for dynamic TLS symbols. +- Prototype: +- _dl_tlsdesc_dynamic (tlsdesc *) ; +- +- The second word of the descriptor points to a +- tlsdesc_dynamic_arg structure. +- +- Returns the offset between the thread pointer and the +- object referenced by the argument. +- +- ptrdiff_t +- _dl_tlsdesc_dynamic (struct tlsdesc *tdp) +- { +- struct tlsdesc_dynamic_arg *td = tdp->arg; +- dtv_t *dtv = *(dtv_t **)((char *)__thread_pointer - SIZE_OF_TCB); +- if (__glibc_likely (td->gen_count <= dtv0.counter +- && (dtvtd->tlsinfo.ti_module.pointer.val +- != TLS_DTV_UNALLOCATED), +- 1)) +- return dtvtd->tlsinfo.ti_module.pointer.val +- + td->tlsinfo.ti_offset +- - __thread_pointer; +- +- return ___tls_get_addr (&td->tlsinfo) - __thread_pointer; +- } */ +- .hidden _dl_tlsdesc_dynamic +- .global _dl_tlsdesc_dynamic +- .type _dl_tlsdesc_dynamic,%function +- cfi_startproc +- .align 2 +-_dl_tlsdesc_dynamic: +- /* Save just enough registers to support fast path, if we fall +- into slow path we will save additional registers. */ +- ADDI sp, sp, -32 +- REG_S t0, sp, 0 +- REG_S t1, sp, 8 +- REG_S t2, sp, 16 +- +-/* Runtime Storage Layout of Thread-Local Storage +- TP point to the start of TLS block. +- +- dtv +-Low address TCB ----------------> dtv0(counter) +- TP --> static_block0 <----- dtv1 +- static_block1 <----- dtv2 +- static_block2 <----- dtv3 +- dynamic_block0 <----- dtv4 +-Hign address dynamic_block1 <----- dtv5 */ +- +- REG_L t0, tp, -SIZE_OF_TCB /* t0 = dtv */ +- REG_L a0, a0, TLSDESC_ARG /* a0(td) = tdp->arg */ +- REG_L t1, a0, TLSDESC_GEN_COUNT /* t1 = td->gen_count */ +- REG_L t2, t0, DTV_COUNTER /* t2 = dtv0.counter */ +- /* If dtv0.counter < td->gen_count, goto slow path. */ +- bltu t2, t1, .Lslow +- +- REG_L t1, a0, TLSDESC_MODID /* t1 = td->tlsinfo.ti_module */ +- /* t1 = t1 * sizeof(dtv_t) = t1 * (2 * sizeof(void*)) */ +- slli.d t1, t1, 4 +- add.d t1, t1, t0 /* t1 = dtvtd->tlsinfo.ti_module */ +- REG_L t1, t1, 0 /* t1 = dtvtd->tlsinfo.ti_module.pointer.val */ +- li.d t2, TLS_DTV_UNALLOCATED +- /* If dtvtd->tlsinfo.ti_module.pointer.val is TLS_DTV_UNALLOCATED, +- goto slow path. */ +- beq t1, t2, .Lslow +- +- REG_L t2, a0, TLSDESC_MODOFF /* t2 = td->tlsinfo.ti_offset */ +- /* dtvtd->tlsinfo.ti_module.pointer.val + td->tlsinfo.ti_offset */ +- add.d a0, t1, t2 +-.Lret: +- sub.d a0, a0, tp +- REG_L t0, sp, 0 +- REG_L t1, sp, 8 +- REG_L t2, sp, 16 +- ADDI sp, sp, 32 +- RET +- +-.Lslow: +- /* This is the slow path. We need to call __tls_get_addr() which +- means we need to save and restore all the register that the +- callee will trash. */ +- +- /* Save the remaining registers that we must treat as caller save. */ +- ADDI sp, sp, -FRAME_SIZE +- REG_S ra, sp, 0 * SZREG +- REG_S a1, sp, 1 * SZREG +- REG_S a2, sp, 2 * SZREG +- REG_S a3, sp, 3 * SZREG +- REG_S a4, sp, 4 * SZREG +- REG_S a5, sp, 5 * SZREG +- REG_S a6, sp, 6 * SZREG +- REG_S a7, sp, 7 * SZREG +- REG_S t3, sp, 8 * SZREG +- REG_S t4, sp, 9 * SZREG +- REG_S t5, sp, 10 * SZREG +- REG_S t6, sp, 11 * SZREG +- REG_S t7, sp, 12 * SZREG +- REG_S t8, sp, 13 * SZREG +- + #ifndef __loongarch_soft_float + +- /* Save fcsr0 register. +- Only one physical fcsr0 register, fcsr1-fcsr3 are aliases +- of some fields in fcsr0. */ +- movfcsr2gr t0, fcsr0 +- st.w t0, sp, FRAME_SIZE + 24 /* Use the spare slot above t2 */ +- +- /* Whether support LASX. */ +- la.global t0, _rtld_global_ro +- REG_L t0, t0, GLRO_DL_HWCAP_OFFSET +- andi t1, t0, HWCAP_LOONGARCH_LASX +- beqz t1, .Llsx +- +- /* Save 256-bit vector registers. +- FIXME: Without vector ABI, save all vector registers. */ +- ADDI sp, sp, -FRAME_SIZE_LASX +- xvst xr0, sp, 0*SZXREG +- xvst xr1, sp, 1*SZXREG +- xvst xr2, sp, 2*SZXREG +- xvst xr3, sp, 3*SZXREG +- xvst xr4, sp, 4*SZXREG +- xvst xr5, sp, 5*SZXREG +- xvst xr6, sp, 6*SZXREG +- xvst xr7, sp, 7*SZXREG +- xvst xr8, sp, 8*SZXREG +- xvst xr9, sp, 9*SZXREG +- xvst xr10, sp, 10*SZXREG +- xvst xr11, sp, 11*SZXREG +- xvst xr12, sp, 12*SZXREG +- xvst xr13, sp, 13*SZXREG +- xvst xr14, sp, 14*SZXREG +- xvst xr15, sp, 15*SZXREG +- xvst xr16, sp, 16*SZXREG +- xvst xr17, sp, 17*SZXREG +- xvst xr18, sp, 18*SZXREG +- xvst xr19, sp, 19*SZXREG +- xvst xr20, sp, 20*SZXREG +- xvst xr21, sp, 21*SZXREG +- xvst xr22, sp, 22*SZXREG +- xvst xr23, sp, 23*SZXREG +- xvst xr24, sp, 24*SZXREG +- xvst xr25, sp, 25*SZXREG +- xvst xr26, sp, 26*SZXREG +- xvst xr27, sp, 27*SZXREG +- xvst xr28, sp, 28*SZXREG +- xvst xr29, sp, 29*SZXREG +- xvst xr30, sp, 30*SZXREG +- xvst xr31, sp, 31*SZXREG +- b .Ltga +- +-.Llsx: +- /* Whether support LSX. */ +- andi t1, t0, HWCAP_LOONGARCH_LSX +- beqz t1, .Lfloat +- +- /* Save 128-bit vector registers. */ +- ADDI sp, sp, -FRAME_SIZE_LSX +- vst vr0, sp, 0*SZVREG +- vst vr1, sp, 1*SZVREG +- vst vr2, sp, 2*SZVREG +- vst vr3, sp, 3*SZVREG +- vst vr4, sp, 4*SZVREG +- vst vr5, sp, 5*SZVREG +- vst vr6, sp, 6*SZVREG +- vst vr7, sp, 7*SZVREG +- vst vr8, sp, 8*SZVREG +- vst vr9, sp, 9*SZVREG +- vst vr10, sp, 10*SZVREG +- vst vr11, sp, 11*SZVREG +- vst vr12, sp, 12*SZVREG +- vst vr13, sp, 13*SZVREG +- vst vr14, sp, 14*SZVREG +- vst vr15, sp, 15*SZVREG +- vst vr16, sp, 16*SZVREG +- vst vr17, sp, 17*SZVREG +- vst vr18, sp, 18*SZVREG +- vst vr19, sp, 19*SZVREG +- vst vr20, sp, 20*SZVREG +- vst vr21, sp, 21*SZVREG +- vst vr22, sp, 22*SZVREG +- vst vr23, sp, 23*SZVREG +- vst vr24, sp, 24*SZVREG +- vst vr25, sp, 25*SZVREG +- vst vr26, sp, 26*SZVREG +- vst vr27, sp, 27*SZVREG +- vst vr28, sp, 28*SZVREG +- vst vr29, sp, 29*SZVREG +- vst vr30, sp, 30*SZVREG +- vst vr31, sp, 31*SZVREG +- b .Ltga +- +-.Lfloat: +- /* Save float registers. */ +- ADDI sp, sp, -FRAME_SIZE_FLOAT +- FREG_S fa0, sp, 0*SZFREG +- FREG_S fa1, sp, 1*SZFREG +- FREG_S fa2, sp, 2*SZFREG +- FREG_S fa3, sp, 3*SZFREG +- FREG_S fa4, sp, 4*SZFREG +- FREG_S fa5, sp, 5*SZFREG +- FREG_S fa6, sp, 6*SZFREG +- FREG_S fa7, sp, 7*SZFREG +- FREG_S ft0, sp, 8*SZFREG +- FREG_S ft1, sp, 9*SZFREG +- FREG_S ft2, sp, 10*SZFREG +- FREG_S ft3, sp, 11*SZFREG +- FREG_S ft4, sp, 12*SZFREG +- FREG_S ft5, sp, 13*SZFREG +- FREG_S ft6, sp, 14*SZFREG +- FREG_S ft7, sp, 15*SZFREG +- FREG_S ft8, sp, 16*SZFREG +- FREG_S ft9, sp, 17*SZFREG +- FREG_S ft10, sp, 18*SZFREG +- FREG_S ft11, sp, 19*SZFREG +- FREG_S ft12, sp, 20*SZFREG +- FREG_S ft13, sp, 21*SZFREG +- FREG_S ft14, sp, 22*SZFREG +- FREG_S ft15, sp, 23*SZFREG +- +-#endif /* #ifndef __loongarch_soft_float */ +- +-.Ltga: +- bl HIDDEN_JUMPTARGET(__tls_get_addr) +- ADDI a0, a0, -TLS_DTV_OFFSET +- +-#ifndef __loongarch_soft_float +- +- la.global t0, _rtld_global_ro +- REG_L t0, t0, GLRO_DL_HWCAP_OFFSET +- andi t1, t0, HWCAP_LOONGARCH_LASX +- beqz t1, .Llsx1 +- +- /* Restore 256-bit vector registers. */ +- xvld xr0, sp, 0*SZXREG +- xvld xr1, sp, 1*SZXREG +- xvld xr2, sp, 2*SZXREG +- xvld xr3, sp, 3*SZXREG +- xvld xr4, sp, 4*SZXREG +- xvld xr5, sp, 5*SZXREG +- xvld xr6, sp, 6*SZXREG +- xvld xr7, sp, 7*SZXREG +- xvld xr8, sp, 8*SZXREG +- xvld xr9, sp, 9*SZXREG +- xvld xr10, sp, 10*SZXREG +- xvld xr11, sp, 11*SZXREG +- xvld xr12, sp, 12*SZXREG +- xvld xr13, sp, 13*SZXREG +- xvld xr14, sp, 14*SZXREG +- xvld xr15, sp, 15*SZXREG +- xvld xr16, sp, 16*SZXREG +- xvld xr17, sp, 17*SZXREG +- xvld xr18, sp, 18*SZXREG +- xvld xr19, sp, 19*SZXREG +- xvld xr20, sp, 20*SZXREG +- xvld xr21, sp, 21*SZXREG +- xvld xr22, sp, 22*SZXREG +- xvld xr23, sp, 23*SZXREG +- xvld xr24, sp, 24*SZXREG +- xvld xr25, sp, 25*SZXREG +- xvld xr26, sp, 26*SZXREG +- xvld xr27, sp, 27*SZXREG +- xvld xr28, sp, 28*SZXREG +- xvld xr29, sp, 29*SZXREG +- xvld xr30, sp, 30*SZXREG +- xvld xr31, sp, 31*SZXREG +- ADDI sp, sp, FRAME_SIZE_LASX +- b .Lfcsr +- +-.Llsx1: +- andi t1, t0, HWCAP_LOONGARCH_LSX +- beqz t1, .Lfloat1 +- +- /* Restore 128-bit vector registers. */ +- vld vr0, sp, 0*SZVREG +- vld vr1, sp, 1*SZVREG +- vld vr2, sp, 2*SZVREG +- vld vr3, sp, 3*SZVREG +- vld vr4, sp, 4*SZVREG +- vld vr5, sp, 5*SZVREG +- vld vr6, sp, 6*SZVREG +- vld vr7, sp, 7*SZVREG +- vld vr8, sp, 8*SZVREG +- vld vr9, sp, 9*SZVREG +- vld vr10, sp, 10*SZVREG +- vld vr11, sp, 11*SZVREG +- vld vr12, sp, 12*SZVREG +- vld vr13, sp, 13*SZVREG +- vld vr14, sp, 14*SZVREG +- vld vr15, sp, 15*SZVREG +- vld vr16, sp, 16*SZVREG +- vld vr17, sp, 17*SZVREG +- vld vr18, sp, 18*SZVREG +- vld vr19, sp, 19*SZVREG +- vld vr20, sp, 20*SZVREG +- vld vr21, sp, 21*SZVREG +- vld vr22, sp, 22*SZVREG +- vld vr23, sp, 23*SZVREG +- vld vr24, sp, 24*SZVREG +- vld vr25, sp, 25*SZVREG +- vld vr26, sp, 26*SZVREG +- vld vr27, sp, 27*SZVREG +- vld vr28, sp, 28*SZVREG +- vld vr29, sp, 29*SZVREG +- vld vr30, sp, 30*SZVREG +- vld vr31, sp, 31*SZVREG +- ADDI sp, sp, FRAME_SIZE_LSX +- b .Lfcsr +- +-.Lfloat1: +- /* Restore float registers. */ +- FREG_L fa0, sp, 0*SZFREG +- FREG_L fa1, sp, 1*SZFREG +- FREG_L fa2, sp, 2*SZFREG +- FREG_L fa3, sp, 3*SZFREG +- FREG_L fa4, sp, 4*SZFREG +- FREG_L fa5, sp, 5*SZFREG +- FREG_L fa6, sp, 6*SZFREG +- FREG_L fa7, sp, 7*SZFREG +- FREG_L ft0, sp, 8*SZFREG +- FREG_L ft1, sp, 9*SZFREG +- FREG_L ft2, sp, 10*SZFREG +- FREG_L ft3, sp, 11*SZFREG +- FREG_L ft4, sp, 12*SZFREG +- FREG_L ft5, sp, 13*SZFREG +- FREG_L ft6, sp, 14*SZFREG +- FREG_L ft7, sp, 15*SZFREG +- FREG_L ft8, sp, 16*SZFREG +- FREG_L ft9, sp, 17*SZFREG +- FREG_L ft10, sp, 18*SZFREG +- FREG_L ft11, sp, 19*SZFREG +- FREG_L ft12, sp, 20*SZFREG +- FREG_L ft13, sp, 21*SZFREG +- FREG_L ft14, sp, 22*SZFREG +- FREG_L ft15, sp, 23*SZFREG +- ADDI sp, sp, FRAME_SIZE_FLOAT +- +-.Lfcsr: +- /* Restore fcsr0 register. */ +- ld.w t0, sp, FRAME_SIZE + 24 +- movgr2fcsr fcsr0, t0 ++#define USE_LASX ++#define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_lasx ++#define Lret Lret_lasx ++#define Lslow Lslow_lasx ++#include "dl-tlsdesc-dynamic.h" ++#undef FRAME_SIZE ++#undef USE_LASX ++#undef _dl_tlsdesc_dynamic ++#undef Lret ++#undef Lslow ++ ++#define USE_LSX ++#define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_lsx ++#define Lret Lret_lsx ++#define Lslow Lslow_lsx ++#include "dl-tlsdesc-dynamic.h" ++#undef FRAME_SIZE ++#undef USE_LSX ++#undef _dl_tlsdesc_dynamic ++#undef Lret ++#undef Lslow + + #endif /* #ifndef __loongarch_soft_float */ + +- REG_L ra, sp, 0 * SZREG +- REG_L a1, sp, 1 * SZREG +- REG_L a2, sp, 2 * SZREG +- REG_L a3, sp, 3 * SZREG +- REG_L a4, sp, 4 * SZREG +- REG_L a5, sp, 5 * SZREG +- REG_L a6, sp, 6 * SZREG +- REG_L a7, sp, 7 * SZREG +- REG_L t3, sp, 8 * SZREG +- REG_L t4, sp, 9 * SZREG +- REG_L t5, sp, 10 * SZREG +- REG_L t6, sp, 11 * SZREG +- REG_L t7, sp, 12 * SZREG +- REG_L t8, sp, 13 * SZREG +- ADDI sp, sp, FRAME_SIZE +- +- b .Lret +- cfi_endproc +- .size _dl_tlsdesc_dynamic, .-_dl_tlsdesc_dynamic +- .hidden HIDDEN_JUMPTARGET(__tls_get_addr) ++#include "dl-tlsdesc-dynamic.h" + + #endif /* #ifdef SHARED */ +diff --git a/sysdeps/loongarch/dl-tlsdesc.h b/sysdeps/loongarch/dl-tlsdesc.h +index ff8c69cb..45c43a5b 100644 +--- a/sysdeps/loongarch/dl-tlsdesc.h ++++ b/sysdeps/loongarch/dl-tlsdesc.h +@@ -43,6 +43,10 @@ extern ptrdiff_t attribute_hidden _dl_tlsdesc_undefweak (struct tlsdesc *); + + #ifdef SHARED + extern void *_dl_make_tlsdesc_dynamic (struct link_map *, size_t); ++#ifndef __loongarch_soft_float ++extern ptrdiff_t attribute_hidden _dl_tlsdesc_dynamic_lasx (struct tlsdesc *); ++extern ptrdiff_t attribute_hidden _dl_tlsdesc_dynamic_lsx (struct tlsdesc *); ++#endif + extern ptrdiff_t attribute_hidden _dl_tlsdesc_dynamic (struct tlsdesc *); + #endif + +diff --git a/sysdeps/loongarch/tlsdesc.sym b/sysdeps/loongarch/tlsdesc.sym +index 213d0b30..9f80fcec 100644 +--- a/sysdeps/loongarch/tlsdesc.sym ++++ b/sysdeps/loongarch/tlsdesc.sym +@@ -4,12 +4,6 @@ + #include <link.h> + #include <dl-tlsdesc.h> + +-#define SHARED 1 +- +-#include <ldsodefs.h> +- +-#define GLRO_offsetof(name) offsetof (struct rtld_global_ro, _##name) +- + -- + + -- Abuse tls.h macros to derive offsets relative to the thread register. +@@ -23,6 +17,3 @@ DTV_COUNTER offsetof(dtv_t, counter) + TLS_DTV_UNALLOCATED TLS_DTV_UNALLOCATED + TLS_DTV_OFFSET TLS_DTV_OFFSET + SIZE_OF_TCB sizeof(tcbhead_t) +-GLRO_DL_HWCAP_OFFSET GLRO_offsetof (dl_hwcap) +-HWCAP_LOONGARCH_LSX HWCAP_LOONGARCH_LSX +-HWCAP_LOONGARCH_LASX HWCAP_LOONGARCH_LASX +-- +2.43.0 +
View file
_service:tar_scm:0011-LoongArch-Fix-macro-redefined-warning-in-tls-desc.S.patch
Added
@@ -0,0 +1,85 @@ +From c07ae520f10f01218640ae2a1f74fd01a4136e1b Mon Sep 17 00:00:00 2001 +From: mengqinggang <mengqinggang@loongson.cn> +Date: Mon, 2 Sep 2024 09:51:04 +0800 +Subject: PATCH 11/15 LoongArch: Fix macro redefined warning in tls-desc.S + +Undef macro to avoid redefined warning. +--- + sysdeps/loongarch/dl-tlsdesc-dynamic.h | 9 +++------ + sysdeps/loongarch/dl-tlsdesc.S | 12 ++++++++++++ + 2 files changed, 15 insertions(+), 6 deletions(-) + +diff --git a/sysdeps/loongarch/dl-tlsdesc-dynamic.h b/sysdeps/loongarch/dl-tlsdesc-dynamic.h +index d10f4a88..3daf9910 100644 +--- a/sysdeps/loongarch/dl-tlsdesc-dynamic.h ++++ b/sysdeps/loongarch/dl-tlsdesc-dynamic.h +@@ -19,9 +19,6 @@ + <https://www.gnu.org/licenses/>. */ + + #define FRAME_SIZE (-((-14 * SZREG) & ALMASK)) +-#define FRAME_SIZE_LSX (-((-32 * SZVREG) & ALMASK)) +-#define FRAME_SIZE_LASX (-((-32 * SZXREG) & ALMASK)) +-#define FRAME_SIZE_FLOAT (-((-24 * SZFREG) & ALMASK)) + + /* Handler for dynamic TLS symbols. + Prototype: +@@ -155,7 +152,7 @@ Hign address dynamic_block1 <----- dtv5 */ + #ifdef USE_LASX + #define V_REG_S xvst + #define V_REG_L xvld +- #define V_SPACE FRAME_SIZE_LASX ++ #define V_SPACE (-((-32 * SZXREG) & ALMASK)) /* Space for LASX registers. */ + #define V_REG(n) $xr##n + #define V_REGS 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, \ + 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 +@@ -163,7 +160,7 @@ Hign address dynamic_block1 <----- dtv5 */ + #elif defined USE_LSX + #define V_REG_S vst + #define V_REG_L vld +- #define V_SPACE FRAME_SIZE_LSX ++ #define V_SPACE (-((-32 * SZVREG) & ALMASK)) /* Space for LSX registers. */ + #define V_REG(n) $vr##n + #define V_REGS 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, \ + 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 +@@ -171,7 +168,7 @@ Hign address dynamic_block1 <----- dtv5 */ + #else + #define V_REG_S fst.d + #define V_REG_L fld.d +- #define V_SPACE FRAME_SIZE_FLOAT ++ #define V_SPACE (-((-24 * SZFREG) & ALMASK)) /* Space for FLOAT registers. */ + #define V_REG(n) $f##n + #define V_REGS 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23 + #define V_REGSZ SZFREG +diff --git a/sysdeps/loongarch/dl-tlsdesc.S b/sysdeps/loongarch/dl-tlsdesc.S +index b6cfd612..be76c07c 100644 +--- a/sysdeps/loongarch/dl-tlsdesc.S ++++ b/sysdeps/loongarch/dl-tlsdesc.S +@@ -69,6 +69,12 @@ _dl_tlsdesc_undefweak: + #define Lslow Lslow_lasx + #include "dl-tlsdesc-dynamic.h" + #undef FRAME_SIZE ++#undef V_REG_S ++#undef V_REG_L ++#undef V_SPACE ++#undef V_REG ++#undef V_REGS ++#undef V_REGSZ + #undef USE_LASX + #undef _dl_tlsdesc_dynamic + #undef Lret +@@ -80,6 +86,12 @@ _dl_tlsdesc_undefweak: + #define Lslow Lslow_lsx + #include "dl-tlsdesc-dynamic.h" + #undef FRAME_SIZE ++#undef V_REG_S ++#undef V_REG_L ++#undef V_SPACE ++#undef V_REG ++#undef V_REGS ++#undef V_REGSZ + #undef USE_LSX + #undef _dl_tlsdesc_dynamic + #undef Lret +-- +2.43.0 +
View file
_service:tar_scm:0012-LoongArch-Undef-__NR_fstat-and-__NR_newfstatat.patch
Added
@@ -0,0 +1,48 @@ +From 035939a919540b7d4a3e388b47945da28b6900bd Mon Sep 17 00:00:00 2001 +From: caiyinyu <caiyinyu@loongson.cn> +Date: Tue, 24 Sep 2024 11:09:32 +0800 +Subject: PATCH 12/15 LoongArch: Undef __NR_fstat and __NR_newfstatat. + +In Linux 6.11, fstat and newfstatat are added back. To avoid the messy +usage of the fstat, newfstatat, and statx system calls, we will continue +using statx only in glibc, maintaining consistency with previous versions of +the LoongArch-specific glibc implementation. + +Signed-off-by: caiyinyu <caiyinyu@loongson.cn> +Reviewed-by: Xi Ruoyao <xry111@xry111.site> +Suggested-by: Florian Weimer <fweimer@redhat.com> +--- + .../sysv/linux/loongarch/fixup-asm-unistd.h | 21 +++++++++++++++++++ + 1 file changed, 21 insertions(+) + create mode 100644 sysdeps/unix/sysv/linux/loongarch/fixup-asm-unistd.h + +diff --git a/sysdeps/unix/sysv/linux/loongarch/fixup-asm-unistd.h b/sysdeps/unix/sysv/linux/loongarch/fixup-asm-unistd.h +new file mode 100644 +index 00000000..0062756b +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/loongarch/fixup-asm-unistd.h +@@ -0,0 +1,21 @@ ++/* Regularize <asm/unistd.h> definitions. LoongArch version. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++/* To avoid the messy usage of the fstat, newfstatat, and statx system calls, we ++only use statx. */ ++#undef __NR_fstat ++#undef __NR_newfstatat +-- +2.43.0 +
View file
_service:tar_scm:0013-From-Adhemerval-Zanella-adhemerval.zanella-linaro.or.patch
Added
@@ -0,0 +1,60 @@ +From 2353c043849ba92c1e1f42f442a6286cd6f60438 Mon Sep 17 00:00:00 2001 +From: Xing Li <lixing@loongson.cn> +Date: Thu, 24 Oct 2024 09:49:10 +0800 +Subject: PATCH 13/15 From: Adhemerval Zanella + <adhemerval.zanella@linaro.org> Date: Mon, 6 Nov 2023 17:25:46 -0300 Subject: + PATCH elf: Remove LD_PROFILE for static binaries + +The _dl_non_dynamic_init does not parse LD_PROFILE, which does not +enable profile for dlopen objects. Since dlopen is deprecated for +static objects, it is better to remove the support. + +It also allows to trim down libc.a of profile support. + +Checked on x86_64-linux-gnu. +Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org> +--- + sysdeps/loongarch/dl-machine.h | 2 ++ + sysdeps/loongarch/dl-trampoline.h | 2 ++ + 2 files changed, 4 insertions(+) + +diff --git a/sysdeps/loongarch/dl-machine.h b/sysdeps/loongarch/dl-machine.h +index d934c77f..7fa3b4e9 100644 +--- a/sysdeps/loongarch/dl-machine.h ++++ b/sysdeps/loongarch/dl-machine.h +@@ -362,6 +362,7 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope, + to intercept the calls to collect information. In this case we + don't store the address in the GOT so that all future calls also + end in this function. */ ++#ifdef SHARED + if (profile != 0) + { + #if !defined __loongarch_soft_float +@@ -380,6 +381,7 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope, + GL(dl_profile_map) = l; + } + else ++#endif + { + /* This function will get called to fix up the GOT entry + indicated by the offset on the stack, and then jump to +diff --git a/sysdeps/loongarch/dl-trampoline.h b/sysdeps/loongarch/dl-trampoline.h +index e298439d..1da70aeb 100644 +--- a/sysdeps/loongarch/dl-trampoline.h ++++ b/sysdeps/loongarch/dl-trampoline.h +@@ -126,6 +126,7 @@ ENTRY (_dl_runtime_resolve) + jirl zero, t1, 0 + END (_dl_runtime_resolve) + ++#ifdef SHARED + #include "dl-link.h" + + ENTRY (_dl_runtime_profile) +@@ -367,3 +368,4 @@ ENTRY (_dl_runtime_profile) + jirl zero, ra, 0 + + END (_dl_runtime_profile) ++#endif /* SHARED */ +-- +2.43.0 +
View file
_service:tar_scm:0014-loongarch-Remove-duplicate-strnlen-in-libc.a-BZ-3178.patch
Added
@@ -0,0 +1,28 @@ +From 7ec8b739ef6b859830a445f30689a024b18b5cc6 Mon Sep 17 00:00:00 2001 +From: Adhemerval Zanella <adhemerval.zanella@linaro.org> +Date: Wed, 22 May 2024 10:21:10 -0300 +Subject: PATCH 14/15 loongarch: Remove duplicate strnlen in libc.a (BZ + 31785) + +The generic version provides weak definitions of strnlen, +which are already provided by the ifunc resolver. +Reviewed-by: H.J. Lu <hjl.tools@gmail.com> +--- + sysdeps/loongarch/lp64/multiarch/strnlen-aligned.S | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sysdeps/loongarch/lp64/multiarch/strnlen-aligned.S b/sysdeps/loongarch/lp64/multiarch/strnlen-aligned.S +index a8296a1b..05837ce7 100644 +--- a/sysdeps/loongarch/lp64/multiarch/strnlen-aligned.S ++++ b/sysdeps/loongarch/lp64/multiarch/strnlen-aligned.S +@@ -98,5 +98,7 @@ L(out): + jr ra + END(STRNLEN) + ++#if !IS_IN (libc) + weak_alias (STRNLEN, strnlen) + libc_hidden_builtin_def (STRNLEN) ++#endif +-- +2.43.0 +
View file
_service:tar_scm:0015-LoongArch-Change-tunable-for-2.38.patch
Added
@@ -0,0 +1,98 @@ +From 1d87ab186cd328420e27fc231a25858fca5e546e Mon Sep 17 00:00:00 2001 +From: Xing Li <lixing@loongson.cn> +Date: Fri, 25 Oct 2024 07:31:30 +0000 +Subject: PATCH 15/15 LoongArch: Change tunable for 2.38 + +--- + sysdeps/loongarch/cpu-tunables.c | 54 ++++++++++++++++++++++---------- + 1 file changed, 37 insertions(+), 17 deletions(-) + +diff --git a/sysdeps/loongarch/cpu-tunables.c b/sysdeps/loongarch/cpu-tunables.c +index e274e993..3b341a0d 100644 +--- a/sysdeps/loongarch/cpu-tunables.c ++++ b/sysdeps/loongarch/cpu-tunables.c +@@ -24,14 +24,12 @@ + #include <cpu-features.h> + #include <ldsodefs.h> + #include <sys/auxv.h> +-#include <dl-tunables-parse.h> +-#include <dl-symbol-redir-ifunc.h> + +-#define CHECK_GLIBC_IFUNC_CPU(f, name, len) \ ++#define CHECK_GLIBC_IFUNC_CPU(f, name, disable, len) \ + _Static_assert (sizeof (#name) - 1 == len, #name " != " #len); \ +- if (tunable_str_comma_strcmp_cte (&f, #name)) \ ++ if (!memcmp(f, #name, len)) \ + { \ +- if (f.disable) \ ++ if (disable) \ + GLRO(dl_larch_cpu_features).hwcap &= (~HWCAP_LOONGARCH_##name); \ + else \ + GLRO(dl_larch_cpu_features).hwcap |= HWCAP_LOONGARCH_##name; \ +@@ -58,29 +56,51 @@ TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp) + NOTE: the IFUNC selection may change over time. Please check all + multiarch implementations when experimenting. */ + +- struct tunable_str_comma_state_t ts; +- tunable_str_comma_init (&ts, valp); ++ const char *p = valp->strval, *c; ++ size_t len; + +- struct tunable_str_comma_t n; +- while (tunable_str_comma_next (&ts, &n)) ++ do + { +- switch (n.len) ++ const char *n; ++ bool disable; ++ size_t nl; ++ ++ for (c = p; *c != ','; c++) ++ if (*c == '\0') ++ break; ++ ++ len = c - p; ++ disable = *p == '-'; ++ if (disable) ++ { ++ n = p + 1; ++ nl = len - 1; ++ } ++ else ++ { ++ n = p; ++ nl = len; ++ } ++ switch (nl) + { + default: + break; + case 3: +- { +- CHECK_GLIBC_IFUNC_CPU (n, LSX, 3); +- CHECK_GLIBC_IFUNC_CPU (n, UAL, 3); +- } ++ { ++ CHECK_GLIBC_IFUNC_CPU (n, LSX, disable, 3); ++ CHECK_GLIBC_IFUNC_CPU (n, UAL, disable, 3); ++ } + break; + case 4: +- { +- CHECK_GLIBC_IFUNC_CPU (n, LASX, 4); +- } ++ { ++ CHECK_GLIBC_IFUNC_CPU (n, LASX, disable, 4); ++ } + break; + } ++ p += len + 1; + } ++ while (*c != '\0'); ++ + + /* Ensure that the user has not enabled any unsupported features. */ + GLRO(dl_larch_cpu_features).hwcap &= GLRO(dl_hwcap); +-- +2.45.2 +
View file
_service:tar_scm:Add-crt1-2.0.o-for-glibc-2.0-compatibility-tests.patch
Added
@@ -0,0 +1,231 @@ +From 4dd8641461463b667b5503ab0ea4abcf261378a9 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" <hjl.tools@gmail.com> +Date: Tue, 30 Apr 2024 09:57:12 -0700 +Subject: PATCH Add crt1-2.0.o for glibc 2.0 compatibility tests + +Starting from glibc 2.1, crt1.o contains _IO_stdin_used which is checked +by _IO_check_libio to provide binary compatibility for glibc 2.0. Add +crt1-2.0.o for tests against glibc 2.0. Define tests-2.0 for glibc 2.0 +compatibility tests. Add and update glibc 2.0 compatibility tests for +stderr, matherr and pthread_kill. +Reviewed-by: Carlos O'Donell <carlos@redhat.com> + +(cherry picked from commit 5f245f3bfbe61b2182964dafb94907e38284b806) +--- + Makeconfig | 21 ++++++++++++++++ + Rules | 13 +++++++++- + csu/Makefile | 5 +++- + libio/Makefile | 6 +++++ + libio/tst-stderr-compat.c | 52 +++++++++++++++++++++++++++++++++++++++ + math/Makefile | 3 +++ + sysdeps/pthread/Makefile | 4 +++ + 7 files changed, 102 insertions(+), 2 deletions(-) + create mode 100644 libio/tst-stderr-compat.c + +diff --git a/Makeconfig b/Makeconfig +index 3f8acff459..3a2c864b04 100644 +--- a/Makeconfig ++++ b/Makeconfig +@@ -360,6 +360,8 @@ whole-archive = -Wl,--whole-archive + # Installed name of the startup code. + # The ELF convention is that the startfile is called crt1.o + start-installed-name = crt1.o ++# Similar to crt1.o, but without _IO_stdin_used. ++start-name-2.0 = crt1-2.0.o + # On systems that do not need a special startfile for statically linked + # binaries, simply set it to the normal name. + ifndef static-start-installed-name +@@ -537,6 +539,25 @@ else # build-static + endif # build-shared + endif # +link + ++# Command for linking test programs with crt1.o from glibc 2.0. +++link-2.0-before-inputs = -nostdlib -nostartfiles $(no-pie-ldflag) \ ++ $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \ ++ $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \ ++ $(firstword $(CRT-$(@F)) $(csu-objpfx)$(start-name-2.0)) \ ++ $(+preinit) $(+prector) +++link-2.0-before-libc = -o $@ $(+link-2.0-before-inputs) \ ++ $(filter-out $(addprefix $(csu-objpfx),start.o \ ++ $(start-name-2.0))\ ++ $(+preinit) $(link-extra-libs) \ ++ $(common-objpfx)libc% $(+postinit),$^) \ ++ $(link-extra-libs) +++link-after-libc = $(+postctor) $(+postinit) ++define +link-2.0-tests ++$(CC) $(+link-2.0-before-libc) $(rtld-tests-LDFLAGS) $(link-libc-tests) \ ++ $(+link-after-libc) ++$(call after-link,$@) ++endef ++ + # The pretty printer test programs need to be compiled without optimizations + # so they won't confuse gdb. We could use either the 'GCC optimize' pragma + # or the 'optimize' function attribute to achieve this; however, at least on +diff --git a/Rules b/Rules +index 279ae490ac..e8096cb285 100644 +--- a/Rules ++++ b/Rules +@@ -188,6 +188,7 @@ binaries-all = $(binaries-all-notests) $(binaries-all-tests) + binaries-static-notests = $(others-static) + binaries-static-tests = $(tests-static) $(xtests-static) + binaries-static = $(binaries-static-notests) $(binaries-static-tests) ++binaries-shared-2.0-tests = $(tests-2.0) + ifeq (yesyes,$(have-fpie)$(build-shared)) + binaries-pie-tests = $(tests-pie) $(xtests-pie) + binaries-pie-notests = $(others-pie) +@@ -215,7 +216,8 @@ binaries-malloc-hugetlb2-tests = + endif + + binaries-pie = $(binaries-pie-tests) $(binaries-pie-notests) +-binaries-shared-tests = $(filter-out $(binaries-pie) $(binaries-static), \ ++binaries-shared-tests = $(filter-out $(binaries-pie) $(binaries-static) \ ++ $(binaries-shared-2.0-tests), \ + $(binaries-all-tests)) + binaries-shared-notests = $(filter-out $(binaries-pie) $(binaries-static), \ + $(binaries-all-notests)) +@@ -235,6 +237,15 @@ $(addprefix $(objpfx),$(binaries-shared-tests)): %: %.o \ + $(+link-tests) + endif + ++# Linking test programs with crt1.o from glibc 2.0. ++ifneq "$(strip $(binaries-shared-2.0-tests))" "" ++$(addprefix $(objpfx),$(binaries-shared-2.0-tests)): %: %.o \ ++ $(link-extra-libs-tests) \ ++ $(sort $(filter $(common-objpfx)lib%,$(link-libc))) \ ++ $(addprefix $(csu-objpfx),start.o) $(+preinit) $(+postinit) ++ $(+link-2.0-tests) ++endif ++ + ifneq "$(strip $(binaries-mcheck-tests))" "" + $(addprefix $(objpfx),$(binaries-mcheck-tests)): %-mcheck: %.o \ + $(link-extra-libs-tests) \ +diff --git a/csu/Makefile b/csu/Makefile +index fcd277e6d3..c2b1c4013f 100644 +--- a/csu/Makefile ++++ b/csu/Makefile +@@ -33,7 +33,7 @@ elide-routines.os = libc-tls + csu-dummies = $(filter-out $(start-installed-name),crt1.o Mcrt1.o) + extra-objs = start.o \ + $(start-installed-name) g$(start-installed-name) $(csu-dummies) \ +- S$(start-installed-name) ++ S$(start-installed-name) $(start-name-2.0) + omit-deps = $(patsubst %.o,%,$(start-installed-name) g$(start-installed-name) \ + b$(start-installed-name) $(csu-dummies) \ + S$(start-installed-name) \ +@@ -138,6 +138,9 @@ ifndef start-installed-name-rule + $(objpfx)$(start-installed-name): $(objpfx)start.o $(objpfx)abi-note.o \ + $(objpfx)init.o $(objpfx)static-reloc.o + $(link-relocatable) ++$(objpfx)$(start-name-2.0): $(objpfx)start.o $(objpfx)abi-note.o \ ++ $(objpfx)static-reloc.o ++ $(link-relocatable) + $(objpfx)r$(start-installed-name): $(objpfx)start.o $(objpfx)abi-note.o \ + $(objpfx)init.o + $(link-relocatable) +diff --git a/libio/Makefile b/libio/Makefile +index 287ec11338..8f9f302807 100644 +--- a/libio/Makefile ++++ b/libio/Makefile +@@ -212,6 +212,12 @@ aux := fileops genops stdfiles stdio strops + ifeq ($(build-shared),yes) + generated += tst-bz24228.mtrace tst-bz24228.check + aux += oldfileops oldstdfiles ++tests += \ ++ tst-stderr-compat \ ++# tests ++tests-2.0 += \ ++ tst-stderr-compat \ ++# tests-2.0 + endif + + shared-only-routines = oldiofopen oldiofdopen oldiofclose oldfileops \ +diff --git a/libio/tst-stderr-compat.c b/libio/tst-stderr-compat.c +new file mode 100644 +index 0000000000..8221415cd4 +--- /dev/null ++++ b/libio/tst-stderr-compat.c +@@ -0,0 +1,52 @@ ++/* Test that fclose works on stderr from glibc 2.0. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <https://www.gnu.org/licenses/>. */ ++ ++#include <shlib-compat.h> ++ ++#if TEST_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) ++# define _LIBC ++# define _IO_USE_OLD_IO_FILE ++# include <stdio.h> ++# include <support/check.h> ++ ++extern FILE _IO_stderr_; ++compat_symbol_reference (libc, _IO_stderr_, _IO_stderr_, GLIBC_2_0); ++compat_symbol_reference (libc, fclose, fclose, GLIBC_2_0); ++ ++__attribute__ ((weak, noclone, noinline)) ++void ++do_fclose (FILE *fp) ++{ ++ TEST_VERIFY_EXIT (fclose (fp) == 0); ++} ++ ++static int ++do_test (void) ++{ ++ do_fclose (&_IO_stderr_); ++ return 0; ++} ++#else ++static int ++do_test (void) ++{ ++ return 0; ++} ++#endif ++ ++#include <support/test-driver.c> +diff --git a/math/Makefile b/math/Makefile +index a9daae09de..9730093630 100644 +--- a/math/Makefile ++++ b/math/Makefile +@@ -261,6 +261,9 @@ tests-static = test-fpucw-static test-fpucw-ieee-static \ + # The tested symbols matherr, _LIB_VERSION have been removed in glibc 2.27. + ifeq ($(have-GLIBC_2.26)$(build-shared),yesyes) + tests += test-matherr test-matherr-2 ++tests-2.0 += \ ++ test-matherr-2 \ ++ # tests-2.0 + endif + + # These tests use internal (unexported) GMP functions and are linked +diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile +index 31028406d5..67706433f0 100644 +--- a/sysdeps/pthread/Makefile ++++ b/sysdeps/pthread/Makefile +@@ -282,6 +282,10 @@ tests += \ + tst-vfork2x \ + # tests + ++tests-2.0 += \ ++ tst-pthread_kill-exited ++ # tests-2.0 ++ + tests-time64 += \ + tst-abstime-time64 \ + tst-cnd-timedwait-time64 \ +-- +2.27.0 +
View file
_service:tar_scm:Make-tst-ungetc-use-libsupport.patch
Added
@@ -0,0 +1,147 @@ +From 87a1968a72e4b4e5436f3e2be1ed8a8d5a5862c7 Mon Sep 17 00:00:00 2001 +From: Siddhesh Poyarekar <siddhesh@sourceware.org> +Date: Wed, 14 Aug 2024 19:20:04 -0400 +Subject: PATCH Make tst-ungetc use libsupport + +Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org> +Reviewed-by: Carlos O'Donell <carlos@redhat.com> +(cherry picked from commit 3f7df7e757f4efec38e45d4068e5492efcac4856) +--- + stdio-common/tst-ungetc.c | 112 +++++++++++++++++++------------------- + 1 file changed, 57 insertions(+), 55 deletions(-) + +diff --git a/stdio-common/tst-ungetc.c b/stdio-common/tst-ungetc.c +index 1344b2b591..5c808f0734 100644 +--- a/stdio-common/tst-ungetc.c ++++ b/stdio-common/tst-ungetc.c +@@ -1,70 +1,72 @@ +-/* Test for ungetc bugs. */ ++/* Test for ungetc bugs. ++ Copyright (C) 1996-2024 Free Software Foundation, Inc. ++ Copyright The GNU Toolchain Authors. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <https://www.gnu.org/licenses/>. */ + + #include <stdio.h> + #include <stdlib.h> +-#include <unistd.h> +- +-#undef assert +-#define assert(x) \ +- if (!(x)) \ +- { \ +- fputs ("test failed: " #x "\n", stderr); \ +- retval = 1; \ +- goto the_end; \ +- } ++#include <support/check.h> ++#include <support/support.h> ++#include <support/temp_file.h> ++#include <support/xstdio.h> ++#include <support/xunistd.h> + +-int +-main (int argc, char *argv) ++static int ++do_test (void) + { +- char name = "/tmp/tst-ungetc.XXXXXX"; ++ char *name = NULL; + FILE *fp = NULL; +- int retval = 0; + int c; + char buffer64; + +- int fd = mkstemp (name); ++ int fd = create_temp_file ("tst-ungetc.", &name); + if (fd == -1) +- { +- printf ("mkstemp failed: %m\n"); +- return 1; +- } +- close (fd); +- fp = fopen (name, "w"); +- assert (fp != NULL) +- fputs ("bla", fp); +- fclose (fp); +- fp = NULL; ++ FAIL_EXIT1 ("cannot create temporary file: %m"); ++ xclose (fd); + +- fp = fopen (name, "r"); +- assert (fp != NULL); +- assert (ungetc ('z', fp) == 'z'); +- assert (getc (fp) == 'z'); +- assert (getc (fp) == 'b'); +- assert (getc (fp) == 'l'); +- assert (ungetc ('m', fp) == 'm'); +- assert (getc (fp) == 'm'); +- assert ((c = getc (fp)) == 'a'); +- assert (getc (fp) == EOF); +- assert (ungetc (c, fp) == c); +- assert (feof (fp) == 0); +- assert (getc (fp) == c); +- assert (getc (fp) == EOF); +- fclose (fp); +- fp = NULL; ++ fp = xfopen (name, "w"); ++ fputs ("bla", fp); ++ xfclose (fp); + +- fp = fopen (name, "r"); +- assert (fp != NULL); +- assert (getc (fp) == 'b'); +- assert (getc (fp) == 'l'); +- assert (ungetc ('b', fp) == 'b'); +- assert (fread (buffer, 1, 64, fp) == 2); +- assert (buffer0 == 'b'); +- assert (buffer1 == 'a'); ++ fp = xfopen (name, "r"); ++ TEST_VERIFY_EXIT (ungetc ('z', fp) == 'z'); ++ TEST_VERIFY_EXIT (getc (fp) == 'z'); ++ TEST_VERIFY_EXIT (getc (fp) == 'b'); ++ TEST_VERIFY_EXIT (getc (fp) == 'l'); ++ TEST_VERIFY_EXIT (ungetc ('m', fp) == 'm'); ++ TEST_VERIFY_EXIT (getc (fp) == 'm'); ++ TEST_VERIFY_EXIT ((c = getc (fp)) == 'a'); ++ TEST_VERIFY_EXIT (getc (fp) == EOF); ++ TEST_VERIFY_EXIT (ungetc (c, fp) == c); ++ TEST_VERIFY_EXIT (feof (fp) == 0); ++ TEST_VERIFY_EXIT (getc (fp) == c); ++ TEST_VERIFY_EXIT (getc (fp) == EOF); ++ xfclose (fp); + +-the_end: +- if (fp != NULL) +- fclose (fp); +- unlink (name); ++ fp = xfopen (name, "r"); ++ TEST_VERIFY_EXIT (getc (fp) == 'b'); ++ TEST_VERIFY_EXIT (getc (fp) == 'l'); ++ TEST_VERIFY_EXIT (ungetc ('b', fp) == 'b'); ++ TEST_VERIFY_EXIT (fread (buffer, 1, 64, fp) == 2); ++ TEST_VERIFY_EXIT (buffer0 == 'b'); ++ TEST_VERIFY_EXIT (buffer1 == 'a'); ++ xfclose (fp); + +- return retval; ++ return 0; + } ++ ++#include <support/test-driver.c> +-- +2.33.0 +
View file
_service:tar_scm:elf-Change-ldconfig-auxcache-magic-number-bug-32231.patch
Added
@@ -0,0 +1,49 @@ +From fa4ad104063204add2144df8151aa1135fffdd2d Mon Sep 17 00:00:00 2001 +From: Florian Weimer <fweimer@redhat.com> +Date: Mon, 28 Oct 2024 14:45:30 +0100 +Subject: PATCH elf: Change ldconfig auxcache magic number (bug 32231) + +In commit c628c2296392ed3bf2cb8d8470668e64fe53389f (elf: Remove +ldconfig kernel version check), the layout of auxcache entries +changed because the osversion field was removed from +struct aux_cache_file_entry. However, AUX_CACHEMAGIC was not +changed, so existing files are still used, potentially leading +to unintended ldconfig behavior. This commit changes AUX_CACHEMAGIC, +so that the file is regenerated. + +Reported-by: DJ Delorie <dj@redhat.com> +Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org> +(cherry picked from commit 0a536f6e2f76e3ef581b3fd9af1e5cf4ddc7a5a2) +--- + NEWS | 1 + + elf/cache.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/NEWS b/NEWS +index a2adce11ff..8feb39f1ba 100644 +--- a/NEWS ++++ b/NEWS +@@ -59,6 +59,7 @@ The following bugs are resolved with this release: + 31968 mremap implementation in C does not handle arguments correctly + 32052 Name space violation in fortify wrappers + 32137 libio: Attempt wide backup free only for non-legacy code ++ 32231 elf: Change ldconfig auxcache magic number +  + Version 2.38 + +diff --git a/elf/cache.c b/elf/cache.c +index 8149f889ba..5de69ec4ca 100644 +--- a/elf/cache.c ++++ b/elf/cache.c +@@ -823,7 +823,7 @@ struct aux_cache_entry + struct aux_cache_entry *next; + }; + +-#define AUX_CACHEMAGIC "glibc-ld.so.auxcache-1.0" ++#define AUX_CACHEMAGIC "glibc-ld.so.auxcache-2.0" + + struct aux_cache_file_entry + { +-- +2.27.0 +
View file
_service:tar_scm:libio-Attempt-wide-backup-free-only-for-non-legacy-c.patch
Added
@@ -0,0 +1,54 @@ +From 370be858928c2c537c112859ccd54cd1b0d56715 Mon Sep 17 00:00:00 2001 +From: Siddhesh Poyarekar <siddhesh@sourceware.org> +Date: Tue, 3 Sep 2024 14:58:33 -0400 +Subject: PATCH libio: Attempt wide backup free only for non-legacy code + +_wide_data and _mode are not available in legacy code, so do not attempt +to free the wide backup buffer in legacy code. + +Resolves: BZ #32137 and BZ #27821 + +Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org> +Reviewed-by: Florian Weimer <fweimer@redhat.com> +(cherry picked from commit ae4d44b1d501421ad9a3af95279b8f4d1546f1ce) +--- + NEWS | 2 ++ + libio/genops.c | 2 +- + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/NEWS b/NEWS +index 7a9a4b7ea3..a2adce11ff 100644 +--- a/NEWS ++++ b/NEWS +@@ -36,6 +36,7 @@ Security related changes: + + The following bugs are resolved with this release: + ++ 27821 ungetc: Fix backup buffer leak on program exit + 29039 Corrupt DTV after reuse of a TLS module ID following dlclose with unused TLS + 30081 resolv: Do not wait for non-existing second DNS response after error + 30694 The iconv program no longer tells the user which given encoding name was wrong +@@ -57,6 +58,7 @@ The following bugs are resolved with this release: + 31965 rseq extension mechanism does not work as intended + 31968 mremap implementation in C does not handle arguments correctly + 32052 Name space violation in fortify wrappers ++ 32137 libio: Attempt wide backup free only for non-legacy code +  + Version 2.38 + +diff --git a/libio/genops.c b/libio/genops.c +index fb06245467..7b30aab095 100644 +--- a/libio/genops.c ++++ b/libio/genops.c +@@ -792,7 +792,7 @@ _IO_unbuffer_all (void) + /* Free up the backup area if it was ever allocated. */ + if (_IO_have_backup (fp)) + _IO_free_backup_area (fp); +- if (fp->_mode > 0 && _IO_have_wbackup (fp)) ++ if (!legacy && fp->_mode > 0 && _IO_have_wbackup (fp)) + _IO_free_wbackup_area (fp); + + if (! (fp->_flags & _IO_UNBUFFERED) +-- +2.27.0 +
View file
_service:tar_scm:malloc-Use-__get_nprocs-on-arena_get2-BZ-30945.patch
Changed
@@ -1,4 +1,4 @@ -From 0ba0f3c749211d2888ee310b2b58ff6401eae624 Mon Sep 17 00:00:00 2001 +From 506e47da1d66b33e24440a495eeef85daf7f2a78 Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella <adhemerval.zanella@linaro.org> Date: Wed, 11 Oct 2023 13:43:56 -0300 Subject: PATCH malloc: Use __get_nprocs on arena_get2 (BZ 30945) @@ -20,10 +20,11 @@ (cherry picked from commit 472894d2cfee5751b44c0aaa71ed87df81c8e62e) --- include/sys/sysinfo.h | 4 ---- + malloc/arena.c | 2 +- misc/getsysstats.c | 6 ------ sysdeps/mach/getsysstats.c | 6 ------ sysdeps/unix/sysv/linux/getsysstats.c | 2 +- - 4 files changed, 1 insertion(+), 17 deletions(-) + 5 files changed, 2 insertions(+), 18 deletions(-) diff --git a/include/sys/sysinfo.h b/include/sys/sysinfo.h index c490561581..65742b1036 100644 @@ -40,6 +41,19 @@ /* Return number of physical pages of memory in the system. */ extern long int __get_phys_pages (void); libc_hidden_proto (__get_phys_pages) +diff --git a/malloc/arena.c b/malloc/arena.c +index 6f03955ff2..82b09adb47 100644 +--- a/malloc/arena.c ++++ b/malloc/arena.c +@@ -820,7 +820,7 @@ arena_get2 (size_t size, mstate avoid_arena) + narenas_limit = mp_.arena_max; + else if (narenas > mp_.arena_test) + { +- int n = __get_nprocs_sched (); ++ int n = __get_nprocs (); + + if (n >= 1) + narenas_limit = NARENAS_FROM_NCORES (n); diff --git a/misc/getsysstats.c b/misc/getsysstats.c index 5f36adc0e8..23cc112074 100644 --- a/misc/getsysstats.c @@ -88,5 +102,5 @@ { enum -- -2.23.0 +2.33.0
View file
_service:tar_scm:malloc-use-__get_nprocs-replace-__get_nprocs_sched.patch
Deleted
@@ -1,25 +0,0 @@ -From f5545d74d6dc4d5036bee6a91cda14a51e2a0676 Mon Sep 17 00:00:00 2001 -From: Yang Yanchao <yangyanchao6@huawei.com> -Date: Sat, 12 Mar 2022 15:30:17 +0800 -Subject: PATCH malloc: use __get_nprocs replace __get_nprocs_sched. - ---- - malloc/arena.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/malloc/arena.c b/malloc/arena.c -index f1f0af86..66748463 100644 ---- a/malloc/arena.c -+++ b/malloc/arena.c -@@ -879,7 +879,7 @@ arena_get2 (size_t size, mstate avoid_arena) - narenas_limit = mp_.arena_max; - else if (narenas > mp_.arena_test) - { -- int n = __get_nprocs_sched (); -+ int n = __get_nprocs (); - - if (n >= 1) - narenas_limit = NARENAS_FROM_NCORES (n); --- -2.33.0 -
View file
_service:tar_scm:nptl-Use-support-check.h-facilities-in-tst-setuid3.patch
Added
@@ -0,0 +1,134 @@ +From f30501ca7557a194a53af22ff5b47b3189c48216 Mon Sep 17 00:00:00 2001 +From: "Maciej W. Rozycki" <macro@redhat.com> +Date: Fri, 26 Jul 2024 13:21:34 +0100 +Subject: PATCH nptl: Use <support/check.h> facilities in tst-setuid3 + +Remove local FAIL macro in favor to FAIL_EXIT1 from <support/check.h>, +which provides equivalent reporting, with the name of the file and the +line number within of the failure site additionally included. Remove +FAIL_ERR altogether and include ": %m" explicitly with the format string +supplied to FAIL_EXIT1 as there seems little value to have a separate +macro just for this. + +Reviewed-by: DJ Delorie <dj@redhat.com> +(cherry picked from commit 8c98195af6e6f1ce21743fc26c723e0f7e45bcf2) +--- + sysdeps/pthread/tst-setuid3.c | 37 +++++++++++++++-------------------- + 1 file changed, 16 insertions(+), 21 deletions(-) + +diff --git a/sysdeps/pthread/tst-setuid3.c b/sysdeps/pthread/tst-setuid3.c +index 58b78d3116..d13848a647 100644 +--- a/sysdeps/pthread/tst-setuid3.c ++++ b/sysdeps/pthread/tst-setuid3.c +@@ -15,24 +15,19 @@ + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +-#include <stdio.h> + #include <errno.h> + #include <pthread.h> + #include <stdbool.h> + #include <unistd.h> + ++#include <support/check.h> ++ + /* The test must run under a non-privileged user ID. */ + static const uid_t test_uid = 1; + + static pthread_barrier_t barrier1; + static pthread_barrier_t barrier2; + +-#define FAIL(fmt, ...) \ +- do { printf ("FAIL: " fmt "\n", __VA_ARGS__); _exit (1); } while (0) +- +-#define FAIL_ERR(fmt, ...) \ +- do { printf ("FAIL: " fmt ": %m\n", __VA_ARGS__); _exit (1); } while (0) +- + /* True if x is not a successful return code from pthread_barrier_wait. */ + static inline bool + is_invalid_barrier_ret (int x) +@@ -45,10 +40,10 @@ thread_func (void *ctx __attribute__ ((unused))) + { + int ret = pthread_barrier_wait (&barrier1); + if (is_invalid_barrier_ret (ret)) +- FAIL ("pthread_barrier_wait (barrier1) (on thread): %d", ret); ++ FAIL_EXIT1 ("pthread_barrier_wait (barrier1) (on thread): %d", ret); + ret = pthread_barrier_wait (&barrier2); + if (is_invalid_barrier_ret (ret)) +- FAIL ("pthread_barrier_wait (barrier2) (on thread): %d", ret); ++ FAIL_EXIT1 ("pthread_barrier_wait (barrier2) (on thread): %d", ret); + return NULL; + } + +@@ -59,13 +54,13 @@ setuid_failure (int phase) + switch (ret) + { + case 0: +- FAIL ("setuid succeeded unexpectedly in phase %d", phase); ++ FAIL_EXIT1 ("setuid succeeded unexpectedly in phase %d", phase); + case -1: + if (errno != EPERM) +- FAIL_ERR ("setuid phase %d", phase); ++ FAIL_EXIT1 ("setuid phase %d: %m", phase); + break; + default: +- FAIL ("invalid setuid return value in phase %d: %d", phase, ret); ++ FAIL_EXIT1 ("invalid setuid return value in phase %d: %d", phase, ret); + } + } + +@@ -74,42 +69,42 @@ do_test (void) + { + if (getuid () == 0) + if (setuid (test_uid) != 0) +- FAIL_ERR ("setuid (%u)", (unsigned) test_uid); ++ FAIL_EXIT1 ("setuid (%u): %m", (unsigned) test_uid); + if (setuid (getuid ())) +- FAIL_ERR ("setuid (%s)", "getuid ()"); ++ FAIL_EXIT1 ("setuid (%s): %m", "getuid ()"); + setuid_failure (1); + + int ret = pthread_barrier_init (&barrier1, NULL, 2); + if (ret != 0) +- FAIL ("pthread_barrier_init (barrier1): %d", ret); ++ FAIL_EXIT1 ("pthread_barrier_init (barrier1): %d", ret); + ret = pthread_barrier_init (&barrier2, NULL, 2); + if (ret != 0) +- FAIL ("pthread_barrier_init (barrier2): %d", ret); ++ FAIL_EXIT1 ("pthread_barrier_init (barrier2): %d", ret); + + pthread_t thread; + ret = pthread_create (&thread, NULL, thread_func, NULL); + if (ret != 0) +- FAIL ("pthread_create: %d", ret); ++ FAIL_EXIT1 ("pthread_create: %d", ret); + + /* Ensure that the thread is running properly. */ + ret = pthread_barrier_wait (&barrier1); + if (is_invalid_barrier_ret (ret)) +- FAIL ("pthread_barrier_wait (barrier1): %d", ret); ++ FAIL_EXIT1 ("pthread_barrier_wait (barrier1): %d", ret); + + setuid_failure (2); + + /* Check success case. */ + if (setuid (getuid ()) != 0) +- FAIL_ERR ("setuid (%s)", "getuid ()"); ++ FAIL_EXIT1 ("setuid (%s): %m", "getuid ()"); + + /* Shutdown. */ + ret = pthread_barrier_wait (&barrier2); + if (is_invalid_barrier_ret (ret)) +- FAIL ("pthread_barrier_wait (barrier2): %d", ret); ++ FAIL_EXIT1 ("pthread_barrier_wait (barrier2): %d", ret); + + ret = pthread_join (thread, NULL); + if (ret != 0) +- FAIL ("pthread_join: %d", ret); ++ FAIL_EXIT1 ("pthread_join: %d", ret); + + return 0; + } +-- +2.33.0 +
View file
_service:tar_scm:posix-Use-support-check.h-facilities-in-tst-truncate.patch
Added
@@ -0,0 +1,89 @@ +From 15ca66303f7a7ce463bb41a83d88474996e46efd Mon Sep 17 00:00:00 2001 +From: "Maciej W. Rozycki" <macro@redhat.com> +Date: Fri, 26 Jul 2024 13:21:34 +0100 +Subject: PATCH posix: Use <support/check.h> facilities in tst-truncate + and tst-truncate64 + +Remove local FAIL macro in favor to FAIL_RET from <support/check.h>, +which provides equivalent reporting, with the name of the file of the +failure site additionally included, for the tst-truncate-common core +shared between the tst-truncate and tst-truncate64 tests. + +Reviewed-by: DJ Delorie <dj@redhat.com> +(cherry picked from commit fe47595504a55e7bb992f8928533df154b510383) +--- + posix/tst-truncate-common.c | 25 ++++++++++++------------- + 1 file changed, 12 insertions(+), 13 deletions(-) + +diff --git a/posix/tst-truncate-common.c b/posix/tst-truncate-common.c +index 9a8163fdfe..fd32eb73c5 100644 +--- a/posix/tst-truncate-common.c ++++ b/posix/tst-truncate-common.c +@@ -21,6 +21,8 @@ + #include <sys/stat.h> + #include <unistd.h> + ++#include <support/check.h> ++ + static void do_prepare (void); + #define PREPARE(argc, argv) do_prepare () + static int do_test (void); +@@ -42,9 +44,6 @@ do_prepare (void) + } + } + +-#define FAIL(str) \ +- do { printf ("error: %s (line %d)\n", str, __LINE__); return 1; } while (0) +- + static int + do_test_with_offset (off_t offset) + { +@@ -54,35 +53,35 @@ do_test_with_offset (off_t offset) + memset (buf, 0xcf, sizeof (buf)); + + if (pwrite (temp_fd, buf, sizeof (buf), offset) != sizeof (buf)) +- FAIL ("write failed"); ++ FAIL_RET ("write failed"); + if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + sizeof (buf))) +- FAIL ("initial size wrong"); ++ FAIL_RET ("initial size wrong"); + + if (ftruncate (temp_fd, offset + 800) < 0) +- FAIL ("size reduction with ftruncate failed"); ++ FAIL_RET ("size reduction with ftruncate failed"); + if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + 800)) +- FAIL ("size after reduction with ftruncate is incorrect"); ++ FAIL_RET ("size after reduction with ftruncate is incorrect"); + + /* The following test covers more than POSIX. POSIX does not require + that ftruncate() can increase the file size. But we are testing + Unix systems. */ + if (ftruncate (temp_fd, offset + 1200) < 0) +- FAIL ("size increate with ftruncate failed"); ++ FAIL_RET ("size increate with ftruncate failed"); + if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + 1200)) +- FAIL ("size after increase is incorrect"); ++ FAIL_RET ("size after increase is incorrect"); + + if (truncate (temp_filename, offset + 800) < 0) +- FAIL ("size reduction with truncate failed"); ++ FAIL_RET ("size reduction with truncate failed"); + if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + 800)) +- FAIL ("size after reduction with truncate incorrect"); ++ FAIL_RET ("size after reduction with truncate incorrect"); + + /* The following test covers more than POSIX. POSIX does not require + that truncate() can increase the file size. But we are testing + Unix systems. */ + if (truncate (temp_filename, (offset + 1200)) < 0) +- FAIL ("size increase with truncate failed"); ++ FAIL_RET ("size increase with truncate failed"); + if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + 1200)) +- FAIL ("size increase with truncate is incorrect"); ++ FAIL_RET ("size increase with truncate is incorrect"); + + return 0; + } +-- +2.33.0 +
View file
_service:tar_scm:stdio-common-Add-test-for-vfscanf-with-matches-longe.patch
Added
@@ -0,0 +1,176 @@ +From 99ffa84bdcdc3d81e82f448279f0c8278dd30964 Mon Sep 17 00:00:00 2001 +From: "Maciej W. Rozycki" <macro@redhat.com> +Date: Fri, 26 Jul 2024 13:21:34 +0100 +Subject: PATCH stdio-common: Add test for vfscanf with matches longer + than INT_MAX BZ #27650 + +Complement commit b03e4d7bd25b ("stdio: fix vfscanf with matches longer +than INT_MAX (bug 27650)") and add a test case for the issue, inspired +by the reproducer provided with the bug report. + +This has been verified to succeed as from the commit referred and fail +beforehand. + +As the test requires 2GiB of data to be passed around its performance +has been evaluated using a choice of systems and the execution time +determined to be respectively in the range of 9s for POWER9@2.166GHz, +24s for FU740@1.2GHz, and 40s for 74Kf@950MHz. As this is on the verge +of and beyond the default timeout it has been increased by the factor of +8. Regardless, following recent practice the test has been added to the +standard rather than extended set. + +Reviewed-by: DJ Delorie <dj@redhat.com> +(cherry picked from commit 89cddc8a7096f3d9225868304d2bc0a1aaf07d63) +--- + stdio-common/Makefile | 5 ++ + stdio-common/tst-scanf-bz27650.c | 108 +++++++++++++++++++++++++++++++ + 2 files changed, 113 insertions(+) + create mode 100644 stdio-common/tst-scanf-bz27650.c + +diff --git a/stdio-common/Makefile b/stdio-common/Makefile +index 3866362bae..2bcbaf754a 100644 +--- a/stdio-common/Makefile ++++ b/stdio-common/Makefile +@@ -243,6 +243,7 @@ tests := \ + tst-scanf-binary-c2x \ + tst-scanf-binary-gnu11 \ + tst-scanf-binary-gnu89 \ ++ tst-scanf-bz27650 \ + tst-scanf-round \ + tst-scanf-to_inpunct \ + tst-setvbuf1 \ +@@ -312,6 +313,7 @@ generated += \ + tst-printf-fp-free.mtrace \ + tst-printf-fp-leak-mem.out \ + tst-printf-fp-leak.mtrace \ ++ tst-scanf-bz27650.mtrace \ + tst-vfprintf-width-prec-mem.out \ + tst-vfprintf-width-prec.mtrace \ + # generated +@@ -398,6 +400,9 @@ tst-printf-fp-free-ENV = \ + tst-printf-fp-leak-ENV = \ + MALLOC_TRACE=$(objpfx)tst-printf-fp-leak.mtrace \ + LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so ++tst-scanf-bz27650-ENV = \ ++ MALLOC_TRACE=$(objpfx)tst-scanf-bz27650.mtrace \ ++ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so + + $(objpfx)tst-unbputc.out: tst-unbputc.sh $(objpfx)tst-unbputc + $(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \ +diff --git a/stdio-common/tst-scanf-bz27650.c b/stdio-common/tst-scanf-bz27650.c +new file mode 100644 +index 0000000000..3a742bc865 +--- /dev/null ++++ b/stdio-common/tst-scanf-bz27650.c +@@ -0,0 +1,108 @@ ++/* Test for BZ #27650, formatted input matching beyond INT_MAX. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <https://www.gnu.org/licenses/>. */ ++ ++#include <error.h> ++#include <errno.h> ++#include <limits.h> ++#include <mcheck.h> ++#include <stddef.h> ++#include <stdio.h> ++#include <stdlib.h> ++#include <string.h> ++ ++#include <sys/types.h> ++ ++#include <support/check.h> ++#include <support/test-driver.h> ++ ++/* Produce a stream of more than INT_MAX characters via buffer BUF of ++ size SIZE according to bookkeeping in COOKIE and then return EOF. */ ++ ++static ssize_t ++io_read (void *cookie, char *buf, size_t size) ++{ ++ unsigned int *written = cookie; ++ unsigned int w = *written; ++ ++ if (w > INT_MAX) ++ return 0; ++ ++ memset (buf, 'a', size); ++ *written = w + size; ++ return size; ++} ++ ++/* Consume a stream of more than INT_MAX characters from an artificial ++ input stream of which none is the new line character. The call to ++ fscanf is supposed to complete upon the EOF condition of input, ++ however in the presence of BZ #27650 it will terminate prematurely ++ with characters still outstanding in input. Diagnose the condition ++ and return status accordingly. */ ++ ++int ++do_test (void) ++{ ++ static cookie_io_functions_t io_funcs = { .read = io_read }; ++ unsigned int written = 0; ++ FILE *in; ++ int v; ++ ++ mtrace (); ++ ++ in = fopencookie (&written, "r", io_funcs); ++ if (in == NULL) ++ { ++ FAIL ("fopencookie: %m"); ++ goto out; ++ } ++ ++ v = fscanf (in, "%*^\n"); ++ if (ferror (in)) ++ { ++ FAIL ("fscanf: input failure, at %u: %m", written); ++ goto out_close; ++ } ++ else if (v == EOF) ++ { ++ FAIL ("fscanf: unexpected end of file, at %u", written); ++ goto out_close; ++ } ++ ++ if (!feof (in)) ++ { ++ v = fgetc (in); ++ if (ferror (in)) ++ FAIL ("fgetc: input failure: %m"); ++ else if (v == EOF) ++ FAIL ("fgetc: unexpected end of file after missing end of file"); ++ else if (v == '\n') ++ FAIL ("unexpected new line character received"); ++ else ++ FAIL ("character received after end of file expected: \\x%02x", v); ++ } ++ ++out_close: ++ if (fclose (in) != 0) ++ FAIL ("fclose: %m"); ++ ++out: ++ return EXIT_SUCCESS; ++} ++ ++#define TIMEOUT (DEFAULT_TIMEOUT * 8) ++#include <support/test-driver.c> +-- +2.33.0 +
View file
_service:tar_scm:support-Add-FAIL-test-failure-helper.patch
Added
@@ -0,0 +1,201 @@ +From 28f358bc4209ab0425170cdccf65bb1fe861148f Mon Sep 17 00:00:00 2001 +From: "Maciej W. Rozycki" <macro@redhat.com> +Date: Fri, 26 Jul 2024 13:21:34 +0100 +Subject: PATCH support: Add FAIL test failure helper + +Add a FAIL test failure helper analogous to FAIL_RET, that does not +cause the current function to return, providing a standardized way to +report a test failure with a message supplied while permitting the +caller to continue executing, for further reporting, cleaning up, etc. + +Update existing test cases that provide a conflicting definition of FAIL +by removing the local FAIL definition and then as follows: + +- tst-fortify-syslog: provide a meaningful message in addition to the + file name already added by <support/check.h>; 'support_record_failure' + is already called by 'support_print_failure_impl' invoked by the new + FAIL test failure helper. + +- tst-ctype: no update to FAIL calls required, with the name of the file + and the line number within of the failure site additionally included + by the new FAIL test failure helper, and error counting plus count + reporting upon test program termination also already provided by + 'support_record_failure' and 'support_report_failure' respectively, + called by 'support_print_failure_impl' and 'adjust_exit_status' also + respectively. However in a number of places 'printf' is called and + the error count adjusted by hand, so update these places to make use + of FAIL instead. And last but not least adjust the final summary just + to report completion, with any error count following as reported by + the test driver. + +- test-tgmath2: no update to FAIL calls required, with the name of the + file of the failure site additionally included by the new FAIL test + failure helper. Also there is no need to track the return status by + hand as any call to FAIL will eventually cause the test case to return + an unsuccesful exit status regardless of the return status from the + test function, via a call to 'adjust_exit_status' made by the test + driver. + +Reviewed-by: DJ Delorie <dj@redhat.com> +(cherry picked from commit 1b97a9f23bf605ca608162089c94187573fb2a9e) +--- + localedata/tst-ctype.c | 40 +++++++++------------------------------- + math/test-tgmath2.c | 13 +++---------- + support/check.h | 5 +++++ + 3 files changed, 17 insertions(+), 41 deletions(-) + +diff --git a/localedata/tst-ctype.c b/localedata/tst-ctype.c +index 098bf51335..355b666866 100644 +--- a/localedata/tst-ctype.c ++++ b/localedata/tst-ctype.c +@@ -21,6 +21,8 @@ + #include <stdio.h> + #include <string.h> + ++#include <support/check.h> ++ + + static const char lower = "abcdefghijklmnopqrstuvwxyz"; + static const char upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; +@@ -53,19 +55,11 @@ static struct classes + #define nclasses (sizeof (classes) / sizeof (classes0)) + + +-#define FAIL(str, args...) \ +- { \ +- printf (" " str "\n", ##args); \ +- ++errors; \ +- } +- +- + static int + do_test (void) + { + const char *cp; + const char *cp2; +- int errors = 0; + char *inpline = NULL; + size_t inplinelen = 0; + char *resline = NULL; +@@ -394,11 +388,8 @@ punct = %04x alnum = %04x\n", + { + if (((__ctype_b(unsigned int) *inp & classesn.mask) != 0) + != (*resp != '0')) +- { +- printf (" is%s('%c' = '\\x%02x') %s true\n", inpline, +- *inp, *inp, *resp == '1' ? "not" : "is"); +- ++errors; +- } ++ FAIL (" is%s('%c' = '\\x%02x') %s true\n", inpline, ++ *inp, *inp, *resp == '1' ? "not" : "is"); + ++inp; + ++resp; + } +@@ -408,11 +399,8 @@ punct = %04x alnum = %04x\n", + while (*inp != '\0') + { + if (tolower (*inp) != *resp) +- { +- printf (" tolower('%c' = '\\x%02x') != '%c'\n", +- *inp, *inp, *resp); +- ++errors; +- } ++ FAIL (" tolower('%c' = '\\x%02x') != '%c'\n", ++ *inp, *inp, *resp); + ++inp; + ++resp; + } +@@ -422,11 +410,8 @@ punct = %04x alnum = %04x\n", + while (*inp != '\0') + { + if (toupper (*inp) != *resp) +- { +- printf (" toupper('%c' = '\\x%02x') != '%c'\n", +- *inp, *inp, *resp); +- ++errors; +- } ++ FAIL (" toupper('%c' = '\\x%02x') != '%c'\n", ++ *inp, *inp, *resp); + ++inp; + ++resp; + } +@@ -436,14 +421,7 @@ punct = %04x alnum = %04x\n", + } + + +- if (errors != 0) +- { +- printf (" %d error%s for `%s' locale\n\n\n", errors, +- errors == 1 ? "" : "s", setlocale (LC_ALL, NULL)); +- return 1; +- } +- +- printf (" No errors for `%s' locale\n\n\n", setlocale (LC_ALL, NULL)); ++ printf ("Completed testing for `%s' locale\n\n\n", setlocale (LC_ALL, NULL)); + return 0; + } + +diff --git a/math/test-tgmath2.c b/math/test-tgmath2.c +index 6dd0d64da5..deba439e0c 100644 +--- a/math/test-tgmath2.c ++++ b/math/test-tgmath2.c +@@ -24,6 +24,8 @@ + #include <string.h> + #include <tgmath.h> + ++#include <support/check.h> ++ + //#define DEBUG + + typedef complex float cfloat; +@@ -87,13 +89,6 @@ enum + int count; + int countsTlastC_last; + +-#define FAIL(str) \ +- do \ +- { \ +- printf ("%s failure on line %d\n", (str), __LINE__); \ +- result = 1; \ +- } \ +- while (0) + #define TEST_TYPE_ONLY(expr, rettype) \ + do \ + { \ +@@ -133,8 +128,6 @@ int countsTlastC_last; + int + test_cos (const int Vint4, const long long int Vllong4) + { +- int result = 0; +- + TEST (cos (vfloat1), float, cos); + TEST (cos (vdouble1), double, cos); + TEST (cos (vldouble1), ldouble, cos); +@@ -152,7 +145,7 @@ test_cos (const int Vint4, const long long int Vllong4) + TEST (cos (Vcdouble1), cdouble, cos); + TEST (cos (Vcldouble1), cldouble, cos); + +- return result; ++ return 0; + } + + int +diff --git a/support/check.h b/support/check.h +index e6ae39f1a1..0a9fff484f 100644 +--- a/support/check.h ++++ b/support/check.h +@@ -24,6 +24,11 @@ + + __BEGIN_DECLS + ++/* Record a test failure, print the failure message to standard output ++ and pass the result of 1 through. */ ++#define FAIL(...) \ ++ support_print_failure_impl (__FILE__, __LINE__, __VA_ARGS__) ++ + /* Record a test failure, print the failure message to standard output + and return 1. */ + #define FAIL_RET(...) \ +-- +2.33.0 +
View file
_service:tar_scm:ungetc-Fix-backup-buffer-leak-on-program-exit-BZ-278.patch
Added
@@ -0,0 +1,145 @@ +From b9f72bd5de931eac39219018c2fa319a449bb2cf Mon Sep 17 00:00:00 2001 +From: Siddhesh Poyarekar <siddhesh@sourceware.org> +Date: Tue, 13 Aug 2024 21:08:49 -0400 +Subject: PATCH ungetc: Fix backup buffer leak on program exit BZ + #27821 + +If a file descriptor is left unclosed and is cleaned up by _IO_cleanup +on exit, its backup buffer remains unfreed, registering as a leak in +valgrind. This is not strictly an issue since (1) the program should +ideally be closing the stream once it's not in use and (2) the program +is about to exit anyway, so keeping the backup buffer around a wee bit +longer isn't a real problem. Free it anyway to keep valgrind happy +when the streams in question are the standard ones, i.e. stdout, stdin +or stderr. + +Also, the _IO_have_backup macro checks for _IO_save_base, +which is a roundabout way to check for a backup buffer instead of +directly looking for _IO_backup_base. The roundabout check breaks when +the main get area has not been used and user pushes a char into the +backup buffer with ungetc. Fix this to use the _IO_backup_base +directly. + +Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org> +Reviewed-by: Carlos O'Donell <carlos@redhat.com> +(cherry picked from commit 3e1d8d1d1dca24ae90df2ea826a8916896fc7e77) +--- + libio/genops.c | 6 ++++++ + libio/libioP.h | 4 ++-- + stdio-common/Makefile | 7 +++++++ + stdio-common/tst-ungetc-leak.c | 32 ++++++++++++++++++++++++++++++++ + 4 files changed, 47 insertions(+), 2 deletions(-) + create mode 100644 stdio-common/tst-ungetc-leak.c + +diff --git a/libio/genops.c b/libio/genops.c +index c673c0acec..fb06245467 100644 +--- a/libio/genops.c ++++ b/libio/genops.c +@@ -789,6 +789,12 @@ _IO_unbuffer_all (void) + legacy = 1; + #endif + ++ /* Free up the backup area if it was ever allocated. */ ++ if (_IO_have_backup (fp)) ++ _IO_free_backup_area (fp); ++ if (fp->_mode > 0 && _IO_have_wbackup (fp)) ++ _IO_free_wbackup_area (fp); ++ + if (! (fp->_flags & _IO_UNBUFFERED) + /* Iff stream is un-orientated, it wasn't used. */ + && (legacy || fp->_mode != 0)) +diff --git a/libio/libioP.h b/libio/libioP.h +index 745278e076..e75ee770bc 100644 +--- a/libio/libioP.h ++++ b/libio/libioP.h +@@ -577,8 +577,8 @@ extern void _IO_old_init (FILE *fp, int flags) __THROW; + ((__fp)->_wide_data->_IO_write_base \ + = (__fp)->_wide_data->_IO_write_ptr = __p, \ + (__fp)->_wide_data->_IO_write_end = (__ep)) +-#define _IO_have_backup(fp) ((fp)->_IO_save_base != NULL) +-#define _IO_have_wbackup(fp) ((fp)->_wide_data->_IO_save_base != NULL) ++#define _IO_have_backup(fp) ((fp)->_IO_backup_base != NULL) ++#define _IO_have_wbackup(fp) ((fp)->_wide_data->_IO_backup_base != NULL) + #define _IO_in_backup(fp) ((fp)->_flags & _IO_IN_BACKUP) + #define _IO_have_markers(fp) ((fp)->_markers != NULL) + #define _IO_blen(fp) ((fp)->_IO_buf_end - (fp)->_IO_buf_base) +diff --git a/stdio-common/Makefile b/stdio-common/Makefile +index 2bcbaf754a..381040570b 100644 +--- a/stdio-common/Makefile ++++ b/stdio-common/Makefile +@@ -256,6 +256,7 @@ tests := \ + tst-swscanf \ + tst-tmpnam \ + tst-ungetc \ ++ tst-ungetc-leak \ + tst-unlockedio \ + tst-vfprintf-mbs-prec \ + tst-vfprintf-user-type \ +@@ -300,6 +301,7 @@ tests-special += \ + $(objpfx)tst-printfsz-islongdouble.out \ + $(objpfx)tst-setvbuf1-cmp.out \ + $(objpfx)tst-unbputc.out \ ++ $(objpfx)tst-ungetc-leak-mem.out \ + $(objpfx)tst-vfprintf-width-prec-mem.out \ + # tests-special + +@@ -314,6 +316,8 @@ generated += \ + tst-printf-fp-leak-mem.out \ + tst-printf-fp-leak.mtrace \ + tst-scanf-bz27650.mtrace \ ++ tst-ungetc-leak-mem.out \ ++ tst-ungetc-leak.mtrace \ + tst-vfprintf-width-prec-mem.out \ + tst-vfprintf-width-prec.mtrace \ + # generated +@@ -403,6 +407,9 @@ tst-printf-fp-leak-ENV = \ + tst-scanf-bz27650-ENV = \ + MALLOC_TRACE=$(objpfx)tst-scanf-bz27650.mtrace \ + LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so ++tst-ungetc-leak-ENV = \ ++ MALLOC_TRACE=$(objpfx)tst-ungetc-leak.mtrace \ ++ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so + + $(objpfx)tst-unbputc.out: tst-unbputc.sh $(objpfx)tst-unbputc + $(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \ +diff --git a/stdio-common/tst-ungetc-leak.c b/stdio-common/tst-ungetc-leak.c +new file mode 100644 +index 0000000000..6c5152b43f +--- /dev/null ++++ b/stdio-common/tst-ungetc-leak.c +@@ -0,0 +1,32 @@ ++/* Test for memory leak with ungetc when stream is unused. ++ Copyright The GNU Toolchain Authors. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <https://www.gnu.org/licenses/>. */ ++ ++#include <stdio.h> ++#include <mcheck.h> ++#include <support/check.h> ++#include <support/support.h> ++ ++static int ++do_test (void) ++{ ++ mtrace (); ++ TEST_COMPARE (ungetc('y', stdin), 'y'); ++ return 0; ++} ++ ++#include <support/test-driver.c> +-- +2.33.0 +
View file
_service:tar_scm:ungetc-Fix-uninitialized-read-when-putting-into-unus.patch
Added
@@ -0,0 +1,78 @@ +From 804d3c8db79db204154dcf5e11a76f14fdddc570 Mon Sep 17 00:00:00 2001 +From: Siddhesh Poyarekar <siddhesh@sourceware.org> +Date: Tue, 13 Aug 2024 21:00:06 -0400 +Subject: PATCH ungetc: Fix uninitialized read when putting into unused + streams BZ #27821 + +When ungetc is called on an unused stream, the backup buffer is +allocated without the main get area being present. This results in +every subsequent ungetc (as the stream remains in the backup area) +checking uninitialized memory in the backup buffer when trying to put a +character back into the stream. + +Avoid comparing the input character with buffer contents when in backup +to avoid this uninitialized read. The uninitialized read is harmless in +this context since the location is promptly overwritten with the input +character, thus fulfilling ungetc functionality. + +Also adjust wording in the manual to drop the paragraph that says glibc +cannot do multiple ungetc back to back since with this change, ungetc +can actually do this. + +Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org> +Reviewed-by: Carlos O'Donell <carlos@redhat.com> +(cherry picked from commit cdf0f88f97b0aaceb894cc02b21159d148d7065c) +--- + libio/genops.c | 2 +- + manual/stdio.texi | 8 +++----- + stdio-common/tst-ungetc.c | 2 ++ + 3 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/libio/genops.c b/libio/genops.c +index fbd8dd9e75..c673c0acec 100644 +--- a/libio/genops.c ++++ b/libio/genops.c +@@ -635,7 +635,7 @@ _IO_sputbackc (FILE *fp, int c) + { + int result; + +- if (fp->_IO_read_ptr > fp->_IO_read_base ++ if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp) + && (unsigned char)fp->_IO_read_ptr-1 == (unsigned char)c) + { + fp->_IO_read_ptr--; +diff --git a/manual/stdio.texi b/manual/stdio.texi +index 9cf622403f..a54cd369db 100644 +--- a/manual/stdio.texi ++++ b/manual/stdio.texi +@@ -1474,11 +1474,9 @@ program; usually @code{ungetc} is used only to unread a character that + was just read from the same stream. @Theglibc{} supports this + even on files opened in binary mode, but other systems might not. + +-@Theglibc{} only supports one character of pushback---in other +-words, it does not work to call @code{ungetc} twice without doing input +-in between. Other systems might let you push back multiple characters; +-then reading from the stream retrieves the characters in the reverse +-order that they were pushed. ++@Theglibc{} supports pushing back multiple characters; subsequently ++reading from the stream retrieves the characters in the reverse order ++that they were pushed. + + Pushing back characters doesn't alter the file; only the internal + buffering for the stream is affected. If a file positioning function +diff --git a/stdio-common/tst-ungetc.c b/stdio-common/tst-ungetc.c +index 5c808f0734..388b202493 100644 +--- a/stdio-common/tst-ungetc.c ++++ b/stdio-common/tst-ungetc.c +@@ -48,6 +48,8 @@ do_test (void) + TEST_VERIFY_EXIT (getc (fp) == 'b'); + TEST_VERIFY_EXIT (getc (fp) == 'l'); + TEST_VERIFY_EXIT (ungetc ('m', fp) == 'm'); ++ TEST_VERIFY_EXIT (ungetc ('n', fp) == 'n'); ++ TEST_VERIFY_EXIT (getc (fp) == 'n'); + TEST_VERIFY_EXIT (getc (fp) == 'm'); + TEST_VERIFY_EXIT ((c = getc (fp)) == 'a'); + TEST_VERIFY_EXIT (getc (fp) == EOF); +-- +2.33.0 +
View file
_service:tar_scm:x86-use-total-l3cache-for-non_temporal_threshold.patch
Deleted
@@ -1,74 +0,0 @@ -From af0606f5d626b92d6e59da3a797548e9daab5580 Mon Sep 17 00:00:00 2001 -From: Qingqing Li <liqingqing3@huawei.com> -Date: Sat, 25 Jun 2022 15:36:44 +0800 -Subject: PATCH x86: use total l3cache for non_temporal_threshold - -Below glibc upstream patch modified the default behavoir for large size of memcpy, -such as 1M~10M. revert it and use GLIBC_TUNABLES="glibc.cpu.x86_non_temporal_threshold=xxx" -to tune the application when needed. - -d3c57027470b78dba79c6d931e4e409b1fecfc80 -Author: Patrick McGehearty <patrick.mcgehearty@oracle.com> -Date: Mon Sep 28 20:11:28 2020 +0000 - - Reversing calculation of __x86_shared_non_temporal_threshold - - The __x86_shared_non_temporal_threshold determines when memcpy on x86 - uses non_temporal stores to avoid pushing other data out of the last - level cache. - uses non_temporal stores to avoid pushing other data out of the last - level cache. - - This patch proposes to revert the calculation change made by H.J. Lu's - patch of June 2, 2017. - - H.J. Lu's patch selected a threshold suitable for a single thread - getting maximum performance. It was tuned using the single threaded - large memcpy micro benchmark on an 8 core processor. The last change - changes the threshold from using 3/4 of one thread's share of the - cache to using 3/4 of the entire cache of a multi-threaded system - before switching to non-temporal stores. Multi-threaded systems with - more than a few threads are server-class and typically have many - active threads. If one thread consumes 3/4 of the available cache for - all threads, it will cause other active threads to have data removed - from the cache. Two examples show the range of the effect. John - McCalpin's widely parallel Stream benchmark, which runs in parallel - and fetches data sequentially, saw a 20% slowdown with this patch on - an internal system test of 128 threads. This regression was discovered - when comparing OL8 performance to OL7. An example that compares - normal stores to non-temporal stores may be found at - https://vgatherps.github.io/2018-09-02-nontemporal/. A simple test - shows performance loss of 400 to 500% due to a failure to use - nontemporal stores. These performance losses are most likely to occur - when the system load is heaviest and good performance is critical. - - The tunable x86_non_temporal_threshold can be used to override the - default for the knowledgable user who really wants maximum cache - allocation to a single thread in a multi-threaded system. - The manual entry for the tunable has been expanded to provide - more information about its purpose. - - modified: sysdeps/x86/cacheinfo.c - modified: manual/tunables.texi ---- - sysdeps/x86/dl-cacheinfo.h | 4 ++++++ - 1 file changed, 4 insertions(+) - -diff --git a/sysdeps/x86/dl-cacheinfo.h b/sysdeps/x86/dl-cacheinfo.h -index e6c94dfd..c5e8deb3 100644 ---- a/sysdeps/x86/dl-cacheinfo.h -+++ b/sysdeps/x86/dl-cacheinfo.h -@@ -926,6 +926,10 @@ dl_init_cacheinfo (struct cpu_features *cpu_features) - if (tunable_size != 0) - shared = tunable_size; - -+ /* keep x86 to use the same non_temporal_threshold like glibc2.28 */ -+ if (threads != 0) -+ non_temporal_threshold *= threads; -+ - tunable_size = TUNABLE_GET (x86_non_temporal_threshold, long int, NULL); - if (tunable_size > minimum_non_temporal_threshold - && tunable_size <= maximum_non_temporal_threshold) --- -2.30.0 -
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2