aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps')
-rwxr-xr-xsysdeps/aarch64/configure2
-rw-r--r--sysdeps/aarch64/configure.ac2
-rw-r--r--sysdeps/generic/Makefile2
-rw-r--r--sysdeps/generic/sframe-read.c128
-rw-r--r--sysdeps/generic/sframe-read.h6
-rw-r--r--sysdeps/generic/sframe.h15
-rw-r--r--sysdeps/i386/Makefile27
-rw-r--r--sysdeps/pthread/Makefile1
-rw-r--r--sysdeps/pthread/tst-backtrace1.c84
-rw-r--r--sysdeps/pthread/tst-cond23.c2
-rw-r--r--sysdeps/unix/sysv/linux/Makefile2
-rw-r--r--sysdeps/unix/sysv/linux/aarch64/uw-sigframe.h2
-rw-r--r--sysdeps/unix/sysv/linux/alpha/bits/ioctls.h36
-rw-r--r--sysdeps/unix/sysv/linux/alpha/termios_arch.h26
-rw-r--r--sysdeps/unix/sysv/linux/bits/ioctls.h14
-rw-r--r--sysdeps/unix/sysv/linux/hppa/bits/ioctls.h36
-rw-r--r--sysdeps/unix/sysv/linux/isatty.c2
-rw-r--r--sysdeps/unix/sysv/linux/isatty_nostatus.c2
-rw-r--r--sysdeps/unix/sysv/linux/mips/termios_arch.h (renamed from sysdeps/unix/sysv/linux/mips/old_termios.h)23
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/internal-ioctl.h27
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/termios_arch.h33
-rw-r--r--sysdeps/unix/sysv/linux/sparc/bits/ioctls.h36
-rw-r--r--sysdeps/unix/sysv/linux/sparc/termios_arch.h (renamed from sysdeps/unix/sysv/linux/sparc/old_termios.h)23
-rw-r--r--sysdeps/unix/sysv/linux/tcgetattr.c2
-rw-r--r--sysdeps/unix/sysv/linux/tcsetattr.c18
-rw-r--r--sysdeps/unix/sysv/linux/termios-kernel-consts.sym26
-rw-r--r--sysdeps/unix/sysv/linux/termios_arch.h23
-rw-r--r--sysdeps/unix/sysv/linux/termios_internals.h42
-rw-r--r--sysdeps/x86/configure4
-rw-r--r--sysdeps/x86/configure.ac2
-rw-r--r--sysdeps/x86_64/Makefile25
-rw-r--r--sysdeps/x86_64/configure2
-rw-r--r--sysdeps/x86_64/configure.ac2
-rw-r--r--sysdeps/x86_64/fpu/multiarch/Makefile39
-rw-r--r--sysdeps/x86_64/fpu/multiarch/ifunc-sse4_1-avx.h41
-rw-r--r--sysdeps/x86_64/fpu/multiarch/s_modf-avx.c2
-rw-r--r--sysdeps/x86_64/fpu/multiarch/s_modf-c.c2
-rw-r--r--sysdeps/x86_64/fpu/multiarch/s_modf-sse4_1.c6
-rw-r--r--sysdeps/x86_64/fpu/multiarch/s_modf.c10
-rw-r--r--sysdeps/x86_64/fpu/multiarch/s_modff-avx.c2
-rw-r--r--sysdeps/x86_64/fpu/multiarch/s_modff-c.c2
-rw-r--r--sysdeps/x86_64/fpu/multiarch/s_modff-sse4_1.c6
-rw-r--r--sysdeps/x86_64/fpu/multiarch/s_modff.c10
43 files changed, 497 insertions, 300 deletions
diff --git a/sysdeps/aarch64/configure b/sysdeps/aarch64/configure
index 26a0989..f364e65 100755
--- a/sysdeps/aarch64/configure
+++ b/sysdeps/aarch64/configure
@@ -194,3 +194,5 @@ if test $build_mathvec = no; then
printf "%s\n" "$as_me: WARNING: mathvec is disabled, this results in incomplete ABI." >&2;}
fi
+libc_cv_support_sframe=yes
+
diff --git a/sysdeps/aarch64/configure.ac b/sysdeps/aarch64/configure.ac
index 22fca8b..a9a1b74 100644
--- a/sysdeps/aarch64/configure.ac
+++ b/sysdeps/aarch64/configure.ac
@@ -31,3 +31,5 @@ fi
if test $build_mathvec = no; then
AC_MSG_WARN([mathvec is disabled, this results in incomplete ABI.])
fi
+
+libc_cv_support_sframe=yes
diff --git a/sysdeps/generic/Makefile b/sysdeps/generic/Makefile
index c48e713..1be63b7 100644
--- a/sysdeps/generic/Makefile
+++ b/sysdeps/generic/Makefile
@@ -21,7 +21,9 @@ CFLAGS-wordcopy.c += -Wno-uninitialized
endif
ifeq ($(subdir),elf)
+ifeq ($(enable-gsframe),yes)
sysdep_routines += sframe-read sframe
+endif
ifeq (yes:yes,$(build-shared):$(unwind-find-fde))
# This is needed to support g++ v2 and v3.
sysdep_routines += framestate unwind-pe
diff --git a/sysdeps/generic/sframe-read.c b/sysdeps/generic/sframe-read.c
index d536575..a6ebc42 100644
--- a/sysdeps/generic/sframe-read.c
+++ b/sysdeps/generic/sframe-read.c
@@ -75,11 +75,10 @@ sframe_get_fde_type (sframe_func_desc_entry *fdep)
static bool
sframe_header_sanity_check_p (sframe_header *hp)
{
- uint8_t all_flags = SFRAME_F_FDE_SORTED | SFRAME_F_FRAME_POINTER;
/* Check preamble is valid. */
if ((hp->sfh_preamble.sfp_magic != SFRAME_MAGIC)
|| (hp->sfh_preamble.sfp_version != SFRAME_VERSION_2)
- || ((hp->sfh_preamble.sfp_flags | all_flags) != all_flags))
+ || (hp->sfh_preamble.sfp_flags & ~SFRAME_V2_F_ALL_FLAGS))
return false;
/* Check offsets are valid. */
@@ -171,25 +170,103 @@ sframe_fre_entry_size (sframe_frame_row_entry *frep, size_t addr_size)
+ sframe_fre_offset_bytes_size (fre_info));
}
-/* Check whether for the given FDEP, the SFrame Frame Row Entry identified via
- the START_IP_OFFSET and the END_IP_OFFSET, provides the stack trace
- information for the PC. */
+/* Get SFrame header from the given decoder context DCTX. */
+
+static inline sframe_header *
+sframe_decoder_get_header (sframe_decoder_ctx *dctx)
+{
+ sframe_header *hp = NULL;
+ if (dctx != NULL)
+ hp = &dctx->sfd_header;
+ return hp;
+}
+
+/* Get the offset of the sfde_func_start_address field (from the start of the
+ on-disk layout of the SFrame section) of the FDE at FUNC_IDX in the decoder
+ context DCTX. */
+
+static uint32_t
+sframe_decoder_get_offsetof_fde_start_addr (sframe_decoder_ctx *dctx,
+ uint32_t func_idx,
+ _Unwind_Reason_Code *errp)
+{
+ sframe_header *dhp;
+
+ dhp = sframe_decoder_get_header (dctx);
+ if (dhp == NULL)
+ {
+ if (errp != NULL)
+ *errp = _URC_END_OF_STACK;
+ return 0;
+ }
+
+ if (func_idx >= dhp->sfh_num_fdes)
+ {
+ if (errp != NULL)
+ *errp = _URC_END_OF_STACK;
+ return 0;
+ }
+ else if (errp != NULL)
+ *errp = _URC_NO_REASON;
+
+ return (sframe_get_hdr_size (dhp)
+ + func_idx * sizeof (sframe_func_desc_entry)
+ + offsetof (sframe_func_desc_entry, sfde_func_start_address));
+}
+
+
+/* Get the offset of the start PC of the SFrame FDE at FUNC_IDX from
+ the start of the SFrame section. If the flag
+ SFRAME_F_FDE_FUNC_START_PCREL is set, sfde_func_start_address is
+ the offset of the start PC of the function from the field itself.
+
+ If FUNC_IDX is not a valid index in the given decoder object, returns 0. */
+
+static int32_t
+sframe_decoder_get_secrel_func_start_addr (sframe_decoder_ctx *dctx,
+ uint32_t func_idx)
+{
+ int32_t func_start_addr;
+ _Unwind_Reason_Code err = 0;
+ int32_t offsetof_fde_in_sec = 0;
+
+ /* Check if we have SFRAME_F_FDE_FUNC_START_PCREL. */
+ sframe_header *sh = &dctx->sfd_header;
+ if ((sh->sfh_preamble.sfp_flags & SFRAME_F_FDE_FUNC_START_PCREL))
+ {
+ offsetof_fde_in_sec =
+ sframe_decoder_get_offsetof_fde_start_addr (dctx, func_idx, &err);
+ /* If func_idx is not a valid index, return 0. */
+ if (err == _URC_END_OF_STACK)
+ return 0;
+ }
+
+ func_start_addr = dctx->sfd_funcdesc[func_idx].sfde_func_start_address;
+
+ return func_start_addr + offsetof_fde_in_sec;
+}
+
+/* Check if the SFrame Frame Row Entry identified via the
+ START_IP_OFFSET and the END_IP_OFFSET (for SFrame FDE at
+ FUNC_IDX). */
static bool
-sframe_fre_check_range_p (sframe_func_desc_entry *fdep,
+sframe_fre_check_range_p (sframe_decoder_ctx *dctx, uint32_t func_idx,
uint32_t start_ip_offset, uint32_t end_ip_offset,
int32_t pc)
{
+ sframe_func_desc_entry *fdep;
int32_t func_start_addr;
uint8_t rep_block_size;
uint32_t fde_type;
uint32_t pc_offset;
bool mask_p;
+ fdep = &dctx->sfd_funcdesc[func_idx];
if (fdep == NULL)
return false;
- func_start_addr = fdep->sfde_func_start_address;
+ func_start_addr = sframe_decoder_get_secrel_func_start_addr (dctx, func_idx);
fde_type = sframe_get_fde_type (fdep);
mask_p = (fde_type == SFRAME_FDE_TYPE_PCMASK);
rep_block_size = fdep->sfde_func_rep_size;
@@ -207,19 +284,6 @@ sframe_fre_check_range_p (sframe_func_desc_entry *fdep,
return (start_ip_offset <= pc_offset) && (end_ip_offset >= pc_offset);
}
-/* The SFrame Decoder. */
-
-/* Get SFrame header from the given decoder context DCTX. */
-
-static inline sframe_header *
-sframe_decoder_get_header (sframe_decoder_ctx *dctx)
-{
- sframe_header *hp = NULL;
- if (dctx != NULL)
- hp = &dctx->sfd_header;
- return hp;
-}
-
/* Get IDX'th offset from FRE. Set ERRP as applicable. */
static int32_t
@@ -298,7 +362,7 @@ sframe_decode_fre_start_address (const char *fre_buf,
static sframe_func_desc_entry *
sframe_get_funcdesc_with_addr_internal (sframe_decoder_ctx *ctx, int32_t addr,
- int *errp)
+ int *errp, uint32_t *func_idx)
{
sframe_header *dhp;
sframe_func_desc_entry *fdp;
@@ -319,19 +383,23 @@ sframe_get_funcdesc_with_addr_internal (sframe_decoder_ctx *ctx, int32_t addr,
/* Do the binary search. */
fdp = (sframe_func_desc_entry *) ctx->sfd_funcdesc;
low = 0;
- high = dhp->sfh_num_fdes;
+ high = dhp->sfh_num_fdes - 1;
while (low <= high)
{
int mid = low + (high - low) / 2;
/* Given sfde_func_start_address <= addr,
addr - sfde_func_start_address must be positive. */
- if (fdp[mid].sfde_func_start_address <= addr
- && ((uint32_t)(addr - fdp[mid].sfde_func_start_address)
+ if (sframe_decoder_get_secrel_func_start_addr (ctx, mid) <= addr
+ && ((uint32_t)(addr - sframe_decoder_get_secrel_func_start_addr (ctx,
+ mid))
< fdp[mid].sfde_func_size))
- return fdp + mid;
+ {
+ *func_idx = mid;
+ return fdp + mid;
+ }
- if (fdp[mid].sfde_func_start_address < addr)
+ if (sframe_decoder_get_secrel_func_start_addr (ctx, mid) < addr)
low = mid + 1;
else
high = mid - 1;
@@ -510,6 +578,7 @@ __sframe_find_fre (sframe_decoder_ctx *ctx, int32_t pc,
sframe_frame_row_entry *frep)
{
sframe_func_desc_entry *fdep;
+ uint32_t func_idx;
uint32_t fre_type, i;
uint32_t start_ip_offset;
int32_t func_start_addr;
@@ -522,14 +591,14 @@ __sframe_find_fre (sframe_decoder_ctx *ctx, int32_t pc,
return _URC_END_OF_STACK;
/* Find the FDE which contains the PC, then scan its fre entries. */
- fdep = sframe_get_funcdesc_with_addr_internal (ctx, pc, &err);
+ fdep = sframe_get_funcdesc_with_addr_internal (ctx, pc, &err, &func_idx);
if (fdep == NULL || ctx->sfd_fres == NULL)
return _URC_END_OF_STACK;
fre_type = sframe_get_fre_type (fdep);
fres = ctx->sfd_fres + fdep->sfde_func_start_fre_off;
- func_start_addr = fdep->sfde_func_start_address;
+ func_start_addr = sframe_decoder_get_secrel_func_start_addr (ctx, func_idx);
for (i = 0; i < fdep->sfde_func_num_fres; i++)
{
@@ -553,7 +622,8 @@ __sframe_find_fre (sframe_decoder_ctx *ctx, int32_t pc,
if (start_ip_offset > (uint32_t) (pc - func_start_addr))
return _URC_END_OF_STACK;
- if (sframe_fre_check_range_p (fdep, start_ip_offset, end_ip_offset, pc))
+ if (sframe_fre_check_range_p (ctx, func_idx, start_ip_offset,
+ end_ip_offset, pc))
{
/* Decode last FRE bits: offsets size. */
frep->fre_offsets = fres + addr_size + sizeof (frep->fre_info);
diff --git a/sysdeps/generic/sframe-read.h b/sysdeps/generic/sframe-read.h
index 1db1886..1461421 100644
--- a/sysdeps/generic/sframe-read.h
+++ b/sysdeps/generic/sframe-read.h
@@ -99,6 +99,12 @@ __sframe_fre_get_ra_offset (sframe_decoder_ctx *dctx,
sframe_frame_row_entry *fre,
_Unwind_Reason_Code *errp);
+/* Get the offset of the sfde_func_start_address field. */
+
+extern uint32_t
+__sframe_decoder_get_offsetof_fde_start_addr (sframe_decoder_ctx *dctx,
+ uint32_t func_idx,
+ _Unwind_Reason_Code *errp);
#ifdef __cplusplus
}
#endif
diff --git a/sysdeps/generic/sframe.h b/sysdeps/generic/sframe.h
index 3f8ff1c..e38adcf 100644
--- a/sysdeps/generic/sframe.h
+++ b/sysdeps/generic/sframe.h
@@ -80,9 +80,20 @@ extern "C"
/* Various flags for SFrame. */
/* Function Descriptor Entries are sorted on PC. */
-#define SFRAME_F_FDE_SORTED 0x1
+#define SFRAME_F_FDE_SORTED 0x1
/* Functions preserve frame pointer. */
-#define SFRAME_F_FRAME_POINTER 0x2
+#define SFRAME_F_FRAME_POINTER 0x2
+/* Function start address in SFrame FDE is encoded as the distance from the
+ location of the sfde_func_start_address to the start PC of the function.
+ If absent, the function start address in SFrame FDE is encoded as the
+ distance from the start of the SFrame FDE section to the start PC of the
+ function. */
+#define SFRAME_F_FDE_FUNC_START_PCREL 0x4
+
+/* Set of all defined flags in SFrame V2. */
+#define SFRAME_V2_F_ALL_FLAGS \
+ (SFRAME_F_FDE_SORTED | SFRAME_F_FRAME_POINTER \
+ | SFRAME_F_FDE_FUNC_START_PCREL)
#define SFRAME_CFA_FIXED_FP_INVALID 0
#define SFRAME_CFA_FIXED_RA_INVALID 0
diff --git a/sysdeps/i386/Makefile b/sysdeps/i386/Makefile
index ee6470d..74068ea 100644
--- a/sysdeps/i386/Makefile
+++ b/sysdeps/i386/Makefile
@@ -17,19 +17,22 @@ ifeq ($(subdir),gmon)
sysdep_routines += i386-mcount
endif
-ifeq ($(subdir),elf)
-CFLAGS-rtld.c += -Wno-uninitialized -Wno-unused
-CFLAGS-dl-load.c += -Wno-unused
-CFLAGS-dl-reloc.c += -Wno-unused
-endif
-
ifeq ($(subdir),csu)
gen-as-const-headers += link-defines.sym
+gen-as-const-headers += tlsdesc.sym
else
stack-align-test-flags += -malign-double
endif
+# Make sure no code in ld.so uses mm/xmm/ymm/zmm registers on i386 since
+# the first 3 mm/xmm/ymm/zmm registers are used to pass vector parameters
+# which must be preserved.
+# With SSE disabled, ensure -fpmath is not set to use sse either.
+rtld-CFLAGS += -mno-sse -mno-mmx -mfpmath=387
ifeq ($(subdir),elf)
+CFLAGS-rtld.c += -Wno-uninitialized -Wno-unused
+CFLAGS-dl-load.c += -Wno-unused
+CFLAGS-dl-reloc.c += -Wno-unused
sysdep-dl-routines += \
dl-tls-get-addr \
# sysdep-dl-routines
@@ -40,18 +43,6 @@ modules-names += tst-auditmod3a tst-auditmod3b
$(objpfx)tst-audit3: $(objpfx)tst-auditmod3a.so
$(objpfx)tst-audit3.out: $(objpfx)tst-auditmod3b.so
tst-audit3-ENV = LD_AUDIT=$(objpfx)tst-auditmod3b.so
-endif
-
-ifeq ($(subdir),csu)
-gen-as-const-headers += tlsdesc.sym
-endif
-
-# Make sure no code in ld.so uses mm/xmm/ymm/zmm registers on i386 since
-# the first 3 mm/xmm/ymm/zmm registers are used to pass vector parameters
-# which must be preserved.
-# With SSE disabled, ensure -fpmath is not set to use sse either.
-rtld-CFLAGS += -mno-sse -mno-mmx -mfpmath=387
-ifeq ($(subdir),elf)
CFLAGS-.os += $(if $(filter $(@F),$(patsubst %,%.os,$(all-rtld-routines))),\
$(rtld-CFLAGS))
diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile
index de146dd..7572f62 100644
--- a/sysdeps/pthread/Makefile
+++ b/sysdeps/pthread/Makefile
@@ -62,7 +62,6 @@ tests += \
tst-abstime \
tst-atfork1 \
tst-attr1 \
- tst-backtrace1 \
tst-bad-schedattr \
tst-barrier1 \
tst-barrier2 \
diff --git a/sysdeps/pthread/tst-backtrace1.c b/sysdeps/pthread/tst-backtrace1.c
deleted file mode 100644
index 01b8a0c..0000000
--- a/sysdeps/pthread/tst-backtrace1.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/* Copyright (C) 2004-2025 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <https://www.gnu.org/licenses/>. */
-
-#include <execinfo.h>
-#include <pthread.h>
-#include <stdio.h>
-
-#define BT_SIZE 64
-void *bt_array[BT_SIZE];
-int bt_cnt;
-
-int
-do_bt (void)
-{
- bt_cnt = backtrace (bt_array, BT_SIZE);
- return 56;
-}
-
-int
-call_do_bt (void)
-{
- return do_bt () + 1;
-}
-
-void *
-tf (void *arg)
-{
- if (call_do_bt () != 57)
- return (void *) 1L;
- return NULL;
-}
-
-int
-do_test (void)
-{
- pthread_t th;
- if (pthread_create (&th, NULL, tf, NULL))
- {
- puts ("create failed");
- return 1;
- }
-
- void *res;
- if (pthread_join (th, &res))
- {
- puts ("join failed");
- return 1;
- }
-
- if (res != NULL)
- {
- puts ("thread failed");
- return 1;
- }
-
- char **text = backtrace_symbols (bt_array, bt_cnt);
- if (text == NULL)
- {
- puts ("backtrace_symbols failed");
- return 1;
- }
-
- for (int i = 0; i < bt_cnt; ++i)
- puts (text[i]);
-
- return 0;
-}
-
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
diff --git a/sysdeps/pthread/tst-cond23.c b/sysdeps/pthread/tst-cond23.c
index 0a68472..a338397 100644
--- a/sysdeps/pthread/tst-cond23.c
+++ b/sysdeps/pthread/tst-cond23.c
@@ -151,7 +151,7 @@ do_test (void)
#if !defined _POSIX_CLOCK_SELECTION || _POSIX_CLOCK_SELECTION == -1
puts ("_POSIX_CLOCK_SELECTION not supported, test skipped");
- return 0;
+ return EXIT_UNSUPPORTED;
#else
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 0aec783..c47cbdf 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -425,8 +425,6 @@ sysdep_headers += \
bits/termios-tcflow.h \
# sysdep_headers
-gen-as-const-headers += termios-kernel-consts.sym
-
tests += \
tst-termios-linux \
# tests
diff --git a/sysdeps/unix/sysv/linux/aarch64/uw-sigframe.h b/sysdeps/unix/sysv/linux/aarch64/uw-sigframe.h
index 3a77c23..9d5d345 100644
--- a/sysdeps/unix/sysv/linux/aarch64/uw-sigframe.h
+++ b/sysdeps/unix/sysv/linux/aarch64/uw-sigframe.h
@@ -24,7 +24,7 @@
#include <sys/ucontext.h>
#include <kernel_rt_sigframe.h>
-#if __AARCH64EL__
+#ifdef __AARCH64EL__
#define MOVZ_X8_8B 0xd2801168
#define SVC_0 0xd4000001
#else
diff --git a/sysdeps/unix/sysv/linux/alpha/bits/ioctls.h b/sysdeps/unix/sysv/linux/alpha/bits/ioctls.h
new file mode 100644
index 0000000..77dc0c1
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/bits/ioctls.h
@@ -0,0 +1,36 @@
+/* Copyright (C) 1996-2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_IOCTL_H
+# error "Never use <bits/ioctls.h> directly; include <sys/ioctl.h> instead."
+#endif
+
+/* Use the definitions from the kernel header files. */
+#include <asm/ioctls.h>
+
+/* Oh well, this is necessary since the kernel data structure is
+ different from the user-level version. */
+#undef TCGETS
+#undef TCSETS
+#undef TCSETSW
+#undef TCSETSF
+#define TCGETS _IOR ('t', 19, char[44])
+#define TCSETS _IOW ('t', 20, char[44])
+#define TCSETSW _IOW ('t', 21, char[44])
+#define TCSETSF _IOW ('t', 22, char[44])
+
+#include <linux/sockios.h>
diff --git a/sysdeps/unix/sysv/linux/alpha/termios_arch.h b/sysdeps/unix/sysv/linux/alpha/termios_arch.h
new file mode 100644
index 0000000..20025f2
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/termios_arch.h
@@ -0,0 +1,26 @@
+/* Architectural parameters for Linux termios - Alpha/PowerPC version
+
+ Copyright (C) 1997-2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef TERMIOS_INTERNALS_H
+# error "<termios_arch.h> should only be included from <termios_internals.h>"
+#endif
+
+#define _TERMIOS2_NCCS 19
+#define _HAVE_TERMIOS2_C_CC_BEFORE_C_LINE 1
+#define _HAVE_STRUCT_OLD_TERMIOS 0
diff --git a/sysdeps/unix/sysv/linux/bits/ioctls.h b/sysdeps/unix/sysv/linux/bits/ioctls.h
index f340a4f..1ddcd4f 100644
--- a/sysdeps/unix/sysv/linux/bits/ioctls.h
+++ b/sysdeps/unix/sysv/linux/bits/ioctls.h
@@ -22,18 +22,4 @@
/* Use the definitions from the kernel header files. */
#include <asm/ioctls.h>
-/* The GNU C library has a different definition of struct termios,
- incompatible with what the ioctl interface expects. The existence
- of the termios2 ioctls is considered an implementation detail.
- Undefine all related ioctl constants. */
-#undef TCGETS
-#undef TCSETS
-#undef TCSETSF
-#undef TCSETSW
-#undef TCGETS2
-#undef TCSETS2
-#undef TCSETSF2
-#undef TCSETSW2
-
-
#include <linux/sockios.h>
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/ioctls.h b/sysdeps/unix/sysv/linux/hppa/bits/ioctls.h
new file mode 100644
index 0000000..6563be8
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/bits/ioctls.h
@@ -0,0 +1,36 @@
+/* Copyright (C) 1996-2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_IOCTL_H
+# error "Never use <bits/ioctls.h> directly; include <sys/ioctl.h> instead."
+#endif
+
+/* Use the definitions from the kernel header files. */
+#include <asm/ioctls.h>
+
+/* Oh well, this is necessary since the kernel data structure is
+ different from the user-level version. */
+#undef TCGETS
+#undef TCSETS
+#undef TCSETSW
+#undef TCSETSF
+#define TCGETS _IOR ('T', 16, char[36])
+#define TCSETS _IOW ('T', 17, char[36])
+#define TCSETSW _IOW ('T', 18, char[36])
+#define TCSETSF _IOW ('T', 19, char[36])
+
+#include <linux/sockios.h>
diff --git a/sysdeps/unix/sysv/linux/isatty.c b/sysdeps/unix/sysv/linux/isatty.c
index e7e98f8..3faaec5 100644
--- a/sysdeps/unix/sysv/linux/isatty.c
+++ b/sysdeps/unix/sysv/linux/isatty.c
@@ -24,6 +24,6 @@ int
__isatty (int fd)
{
struct termios2 k_termios;
- return INLINE_SYSCALL_CALL (ioctl, fd, ARCH_TCGETS, &k_termios) == 0;
+ return INLINE_SYSCALL_CALL (ioctl, fd, TCGETS2, &k_termios) == 0;
}
weak_alias (__isatty, isatty)
diff --git a/sysdeps/unix/sysv/linux/isatty_nostatus.c b/sysdeps/unix/sysv/linux/isatty_nostatus.c
index 9970442..406decb 100644
--- a/sysdeps/unix/sysv/linux/isatty_nostatus.c
+++ b/sysdeps/unix/sysv/linux/isatty_nostatus.c
@@ -22,5 +22,5 @@ int
__isatty_nostatus (int fd)
{
struct termios2 k_termios;
- return INTERNAL_SYSCALL_CALL (ioctl, fd, ARCH_TCGETS, &k_termios) == 0;
+ return INTERNAL_SYSCALL_CALL (ioctl, fd, TCGETS2, &k_termios) == 0;
}
diff --git a/sysdeps/unix/sysv/linux/mips/old_termios.h b/sysdeps/unix/sysv/linux/mips/termios_arch.h
index 8164742..392d9aa 100644
--- a/sysdeps/unix/sysv/linux/mips/old_termios.h
+++ b/sysdeps/unix/sysv/linux/mips/termios_arch.h
@@ -1,6 +1,6 @@
-/* old_termios.h for MIPS.
+/* Architectural parameters for Linux termios - MIPS version
- Copyright (C) 2025 Free Software Foundation, Inc.
+ Copyright (C) 1991-2025 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,15 +17,18 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
+#define _TERMIOS2_NCCS 23
+#define _HAVE_TERMIOS2_C_CC_BEFORE_C_LINE 0
+
#define _HAVE_STRUCT_OLD_TERMIOS 1
#define OLD_NCCS 32
-typedef struct old_termios
+struct old_termios
{
- tcflag_t c_iflag; /* input mode flags */
- tcflag_t c_oflag; /* output mode flags */
- tcflag_t c_cflag; /* control mode flags */
- tcflag_t c_lflag; /* local mode flags */
- cc_t c_line; /* line discipline */
- cc_t c_cc[OLD_NCCS]; /* control characters */
-} old_termios_t;
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[OLD_NCCS]; /* control characters */
+};
diff --git a/sysdeps/unix/sysv/linux/powerpc/internal-ioctl.h b/sysdeps/unix/sysv/linux/powerpc/internal-ioctl.h
index 94cfd71..6c21357 100644
--- a/sysdeps/unix/sysv/linux/powerpc/internal-ioctl.h
+++ b/sysdeps/unix/sysv/linux/powerpc/internal-ioctl.h
@@ -1,4 +1,4 @@
-/* Linux internal definitions for ioctl. powerpc version.
+/* Linux internal definitions for ioctl.
Copyright (C) 2021-2025 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -17,40 +17,27 @@
<https://www.gnu.org/licenses/>. */
#include <termios.h>
-#include <termios_internals.h>
-#include <assert.h>
-
-/* PowerPC quirk: on PowerPC only, ioctl() emulates the TCGETS/TCSETS*
- ioctls with tcgetattr/tcsetattr using the glibc struct termios.
- As struct termios2 is the same as the kernel struct termios on PowerPC,
- simply consider the kernel ones as the termios2 interface, even
- though the kernel doesn't call it that. */
-
-#define GLIBC_TCGETS _IOR ('t', 19, struct termios)
-#define GLIBC_TCSETS _IOW ('t', 20, struct termios)
-#define GLIBC_TCSETSW _IOW ('t', 21, struct termios)
-#define GLIBC_TCSETSF _IOW ('t', 22, struct termios)
+/* The user-visible size of struct termios has changed. Catch ioctl calls
+ using the new-style struct termios, and translate them to old-style. */
static inline bool
__ioctl_arch (int *r, int fd, unsigned long request, void *arg)
{
- static_assert (GLIBC_TCGETS != KERNEL_TCGETS2,
- "emulation not possible due to matching ioctl constants");
switch (request)
{
- case GLIBC_TCGETS:
+ case TCGETS:
*r = __tcgetattr (fd, (struct termios *) arg);
break;
- case GLIBC_TCSETS:
+ case TCSETS:
*r = __tcsetattr (fd, TCSANOW, (struct termios *) arg);
break;
- case GLIBC_TCSETSW:
+ case TCSETSW:
*r = __tcsetattr (fd, TCSADRAIN, (struct termios *) arg);
break;
- case GLIBC_TCSETSF:
+ case TCSETSF:
*r = __tcsetattr (fd, TCSAFLUSH, (struct termios *) arg);
break;
diff --git a/sysdeps/unix/sysv/linux/powerpc/termios_arch.h b/sysdeps/unix/sysv/linux/powerpc/termios_arch.h
new file mode 100644
index 0000000..919b437
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/termios_arch.h
@@ -0,0 +1,33 @@
+/* Architectural parameters for Linux termios - PowerPC version
+
+ Copyright (C) 1997-2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#define _TERMIOS2_NCCS 19
+#define _HAVE_TERMIOS2_C_CC_BEFORE_C_LINE 1
+#define _HAVE_STRUCT_OLD_TERMIOS 0
+
+/* PowerPC quirk: on PowerPC only, ioctl() emulates the TCGETS/TCSETS*
+ ioctls with tcgetattr/tcsetattr using the glibc struct termios.
+ As struct termios2 is the same as the kernel struct termios on PowerPC,
+ simply consider the kernel ones as the termios2 interface, even
+ though the kernel doesn't call it that. */
+
+#define TCGETS2 _IOR ('t', 19, struct termios2)
+#define TCSETS2 _IOW ('t', 20, struct termios2)
+#define TCSETSW2 _IOW ('t', 21, struct termios2)
+#define TCSETSF2 _IOW ('t', 22, struct termios2)
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/ioctls.h b/sysdeps/unix/sysv/linux/sparc/bits/ioctls.h
new file mode 100644
index 0000000..1a95466
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/bits/ioctls.h
@@ -0,0 +1,36 @@
+/* Copyright (C) 1996-2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_IOCTL_H
+# error "Never use <bits/ioctls.h> directly; include <sys/ioctl.h> instead."
+#endif
+
+/* Use the definitions from the kernel header files. */
+#include <asm/ioctls.h>
+
+/* Oh well, this is necessary since the kernel data structure is
+ different from the user-level version. */
+#undef TCGETS
+#undef TCSETS
+#undef TCSETSW
+#undef TCSETSF
+#define TCGETS _IOR ('T', 8, char[36])
+#define TCSETS _IOW ('T', 9, char[36])
+#define TCSETSW _IOW ('T', 10, char[36])
+#define TCSETSF _IOW ('T', 11, char[36])
+
+#include <linux/sockios.h>
diff --git a/sysdeps/unix/sysv/linux/sparc/old_termios.h b/sysdeps/unix/sysv/linux/sparc/termios_arch.h
index d7af589..f3b3f65 100644
--- a/sysdeps/unix/sysv/linux/sparc/old_termios.h
+++ b/sysdeps/unix/sysv/linux/sparc/termios_arch.h
@@ -1,6 +1,6 @@
-/* old_termios.h for SPARC.
+/* Architectural parameters for Linux termios - SPARC version
- Copyright (C) 2025 Free Software Foundation, Inc.
+ Copyright (C) 1991-2025 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,15 +17,18 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
+#define _TERMIOS2_NCCS 19
+#define _HAVE_TERMIOS2_C_CC_BEFORE_C_LINE 0
+
#define _HAVE_STRUCT_OLD_TERMIOS 1
#define OLD_NCCS 17
-typedef struct old_termios
+struct old_termios
{
- tcflag_t c_iflag; /* input mode flags */
- tcflag_t c_oflag; /* output mode flags */
- tcflag_t c_cflag; /* control mode flags */
- tcflag_t c_lflag; /* local mode flags */
- cc_t c_line; /* line discipline */
- cc_t c_cc[OLD_NCCS]; /* control characters */
-} old_termios_t;
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[OLD_NCCS]; /* control characters */
+};
diff --git a/sysdeps/unix/sysv/linux/tcgetattr.c b/sysdeps/unix/sysv/linux/tcgetattr.c
index 36f68a7..ca17569 100644
--- a/sysdeps/unix/sysv/linux/tcgetattr.c
+++ b/sysdeps/unix/sysv/linux/tcgetattr.c
@@ -22,7 +22,7 @@ int
__tcgetattr (int fd, struct termios *termios_p)
{
struct termios2 k_termios;
- long int retval = INLINE_SYSCALL_CALL (ioctl, fd, ARCH_TCGETS, &k_termios);
+ long int retval = INLINE_SYSCALL_CALL (ioctl, fd, TCGETS2, &k_termios);
if (__glibc_likely (retval != -1))
{
diff --git a/sysdeps/unix/sysv/linux/tcsetattr.c b/sysdeps/unix/sysv/linux/tcsetattr.c
index ad8f2df..4f07a03 100644
--- a/sysdeps/unix/sysv/linux/tcsetattr.c
+++ b/sysdeps/unix/sysv/linux/tcsetattr.c
@@ -19,12 +19,6 @@
#define static_assert_equal(x,y) _Static_assert ((x) == (y), #x " != " #y)
-static_assert_equal (sizeof (struct termios2), KERNEL_TERMIOS2_SIZE);
-static_assert_equal (offsetof (struct termios2, c_cc),
- KERNEL_TERMIOS2_CC_OFFSET);
-static_assert_equal (offsetof (struct termios2, c_line),
- KERNEL_TERMIOS2_LINE_OFFSET);
-
/* Set the state of FD to *TERMIOS_P. */
int
__tcsetattr (int fd, int optional_actions, const struct termios *termios_p)
@@ -59,10 +53,10 @@ __tcsetattr (int fd, int optional_actions, const struct termios *termios_p)
*/
static_assert_equal(TCSADRAIN, TCSANOW + 1);
static_assert_equal(TCSAFLUSH, TCSANOW + 2);
- static_assert_equal(KERNEL_TCSETSW2, KERNEL_TCSETS2 + 1);
- static_assert_equal(KERNEL_TCSETSF2, KERNEL_TCSETS2 + 2);
- static_assert_equal(KERNEL_TCSETSW, KERNEL_TCSETS + 1);
- static_assert_equal(KERNEL_TCSETSF, KERNEL_TCSETS + 2);
+ static_assert_equal(TCSETSW2, TCSETS2 + 1);
+ static_assert_equal(TCSETSF2, TCSETS2 + 2);
+ static_assert_equal(TCSETSW, TCSETS + 1);
+ static_assert_equal(TCSETSF, TCSETS + 2);
cmd = (long)optional_actions - TCSANOW;
if (cmd > 2)
@@ -72,11 +66,11 @@ __tcsetattr (int fd, int optional_actions, const struct termios *termios_p)
k_termios.c_ospeed != k_termios.c_ispeed ||
cbaud (k_termios.c_cflag) == __BOTHER)
{
- cmd += KERNEL_TCSETS2;
+ cmd += TCSETS2;
}
else
{
- cmd += KERNEL_TCSETS;
+ cmd += TCSETS;
k_termios.c_cflag &= ~CIBAUD;
}
diff --git a/sysdeps/unix/sysv/linux/termios-kernel-consts.sym b/sysdeps/unix/sysv/linux/termios-kernel-consts.sym
deleted file mode 100644
index 3856a8c..0000000
--- a/sysdeps/unix/sysv/linux/termios-kernel-consts.sym
+++ /dev/null
@@ -1,26 +0,0 @@
-#include <linux/termios.h>
-#include <stddef.h>
-
-#ifdef TCGETS2
-# define STRUCT_TERMIOS struct termios2
-#else
-# define TCGETS2 TCGETS
-# define TCSETS2 TCSETS
-# define TCSETSW2 TCSETSW
-# define TCSETSF2 TCSETSF
-# define STRUCT_TERMIOS struct termios
-#endif
-
---
-KERNEL_TCGETS TCGETS
-KERNEL_TCSETS TCSETS
-KERNEL_TCSETSF TCSETSF
-KERNEL_TCSETSW TCSETSW
-KERNEL_TCGETS2 TCGETS2
-KERNEL_TCSETS2 TCSETS2
-KERNEL_TCSETSF2 TCSETSF2
-KERNEL_TCSETSW2 TCSETSW2
-KERNEL_TERMIOS2_SIZE sizeof (STRUCT_TERMIOS)
-KERNEL_TERMIOS2_CC_OFFSET offsetof (STRUCT_TERMIOS, c_cc)
-KERNEL_TERMIOS2_LINE_OFFSET offsetof (STRUCT_TERMIOS, c_line)
-_TERMIOS2_NCCS sizeof ((STRUCT_TERMIOS) { 0 }.c_cc) / sizeof (cc_t)
diff --git a/sysdeps/unix/sysv/linux/termios_arch.h b/sysdeps/unix/sysv/linux/termios_arch.h
new file mode 100644
index 0000000..8dbf420
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/termios_arch.h
@@ -0,0 +1,23 @@
+/* Architectural parameters for Linux termios - generic version
+
+ Copyright (C) 1997-2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#define _TERMIOS2_NCCS 19
+#define _HAVE_TERMIOS2_C_CC_BEFORE_C_LINE 0
+
+#define _HAVE_STRUCT_OLD_TERMIOS 0
diff --git a/sysdeps/unix/sysv/linux/termios_internals.h b/sysdeps/unix/sysv/linux/termios_internals.h
index b2f3f1b..e8dbfe7 100644
--- a/sysdeps/unix/sysv/linux/termios_internals.h
+++ b/sysdeps/unix/sysv/linux/termios_internals.h
@@ -30,18 +30,7 @@
#include <sysdep.h>
#include <shlib-compat.h>
-#include <termios-kernel-consts.h>
-
-/* Alpha got termios2 late, but TCGETS has exactly the same structure
- format and function as TCGETS2. On all other platforms, the termios2
- interface exists as far back as this version of glibc supports.
-
- For TCSETS* it is more complicated; this is handled in tcsetattr.c. */
-#ifdef __ASSUME_TERMIOS2
-# define ARCH_TCGETS KERNEL_TCGETS2
-#else
-# define ARCH_TCGETS KERNEL_TCGETS
-#endif
+#include <termios_arch.h>
/* ---- Kernel interface definitions ---- */
@@ -55,7 +44,7 @@ struct termios2
tcflag_t c_oflag; /* output mode flags */
tcflag_t c_cflag; /* control mode flags */
tcflag_t c_lflag; /* local mode flags */
-#if KERNEL_TERMIOS2_CC_OFFSET < KERNEL_TERMIOS2_LINE_OFFSET
+#if _HAVE_TERMIOS2_C_CC_BEFORE_C_LINE
cc_t c_cc[_TERMIOS2_NCCS]; /* control characters */
cc_t c_line; /* line discipline */
#else
@@ -66,6 +55,26 @@ struct termios2
speed_t c_ospeed; /* output speed */
};
+/* Alpha got termios2 late, but TCGETS has exactly the same structure
+ format and function as TCGETS2. On all other platforms, the termios2
+ interface exists as far back as this version of glibc supports.
+
+ For TCSETS* it is more complicated; this is handled in tcsetattr.c.
+
+ Some other architectures only have the equivalent of the termios2
+ interface, in which case the old ioctl names are the only ones
+ presented, but are equivalent to the new ones. */
+#ifndef TCGETS2
+# define TCGETS2 TCGETS
+# define TCSETS2 TCSETS
+# define TCSETSW2 TCSETSW
+# define TCSETSF2 TCSETSF
+#elif !__ASSUME_TERMIOS2
+/* Hack for Alpha */
+# undef TCGETS2
+# define TCGETS2 TCGETS
+#endif
+
/* ---- Application interface definitions ---- */
/*
@@ -82,7 +91,12 @@ struct termios2
* This only applies to SPARC and MIPS; for other architectures the
* new and old speed_t interfaces both use the same struct termios.
*/
-#include <old_termios.h>
+#if _HAVE_STRUCT_OLD_TERMIOS
+typedef struct old_termios old_termios_t;
+#else
+# define OLD_NCCS NCCS
+typedef struct termios old_termios_t;
+#endif
/* ---- Internal function definitions ---- */
diff --git a/sysdeps/x86/configure b/sysdeps/x86/configure
index c7ea9ac..dff26e9 100644
--- a/sysdeps/x86/configure
+++ b/sysdeps/x86/configure
@@ -171,8 +171,12 @@ fi
config_vars="$config_vars
have-x86-isa-level = $libc_cv_have_x86_isa_level"
config_vars="$config_vars
+x86-isa-level-2-or-above = 2 3 4"
+config_vars="$config_vars
x86-isa-level-3-or-above = 3 4"
config_vars="$config_vars
+x86-isa-level-4-or-above = 4"
+config_vars="$config_vars
enable-x86-isa-level = $libc_cv_include_x86_isa_level"
diff --git a/sysdeps/x86/configure.ac b/sysdeps/x86/configure.ac
index 031f917..54960a7 100644
--- a/sysdeps/x86/configure.ac
+++ b/sysdeps/x86/configure.ac
@@ -117,7 +117,9 @@ else
AC_DEFINE_UNQUOTED(MINIMUM_X86_ISA_LEVEL, $libc_cv_have_x86_isa_level)
fi
LIBC_CONFIG_VAR([have-x86-isa-level], [$libc_cv_have_x86_isa_level])
+LIBC_CONFIG_VAR([x86-isa-level-2-or-above], [2 3 4])
LIBC_CONFIG_VAR([x86-isa-level-3-or-above], [3 4])
+LIBC_CONFIG_VAR([x86-isa-level-4-or-above], [4])
LIBC_CONFIG_VAR([enable-x86-isa-level], [$libc_cv_include_x86_isa_level])
dnl Check if TEST_CC supports -mfpmath=387
diff --git a/sysdeps/x86_64/Makefile b/sysdeps/x86_64/Makefile
index c3e1065..8cace35 100644
--- a/sysdeps/x86_64/Makefile
+++ b/sysdeps/x86_64/Makefile
@@ -11,6 +11,7 @@ endif
ifeq ($(subdir),csu)
gen-as-const-headers += link-defines.sym
+gen-as-const-headers += tlsdesc.sym rtld-offsets.sym
endif
ifeq ($(subdir),gmon)
@@ -235,10 +236,6 @@ $(objpfx)check-rtld.out: $(objpfx)rtld.reloc
generated += check-rtld.out
endif # $(subdir) == elf
-ifeq ($(subdir),csu)
-gen-as-const-headers += tlsdesc.sym rtld-offsets.sym
-endif
-
ifeq ($(subdir),wcsmbs)
sysdep_routines += \
@@ -269,6 +266,15 @@ endif
ifneq ($(enable-cet),no)
+# Add -fcf-protection to CFLAGS when CET is enabled.
+CFLAGS-.o += -fcf-protection
+CFLAGS-.os += -fcf-protection
+CFLAGS-.op += -fcf-protection
+CFLAGS-.oS += -fcf-protection
+
+# Compile assembly codes with <cet.h> when CET is enabled.
+asm-CPPFLAGS += -fcf-protection -include cet.h
+
ifeq ($(subdir),elf)
sysdep-dl-routines += dl-cet
@@ -461,18 +467,7 @@ $(objpfx)tst-shstk-legacy-1g.out: \
$(..)/sysdeps/x86_64/tst-shstk-legacy-1g.sh $(objpfx)tst-shstk-legacy-1g
$(SHELL) $< $(common-objpfx) '$(test-program-prefix)' 2> $@; \
$(evaluate-test)
-endif
-
-# Add -fcf-protection to CFLAGS when CET is enabled.
-CFLAGS-.o += -fcf-protection
-CFLAGS-.os += -fcf-protection
-CFLAGS-.op += -fcf-protection
-CFLAGS-.oS += -fcf-protection
-
-# Compile assembly codes with <cet.h> when CET is enabled.
-asm-CPPFLAGS += -fcf-protection -include cet.h
-ifeq ($(subdir),elf)
ifeq (yes,$(build-shared))
tests-special += $(objpfx)check-cet.out
endif
diff --git a/sysdeps/x86_64/configure b/sysdeps/x86_64/configure
index bbf520b..32324f6 100644
--- a/sysdeps/x86_64/configure
+++ b/sysdeps/x86_64/configure
@@ -289,6 +289,8 @@ fi
config_vars="$config_vars
have-x86-apx = $libc_cv_x86_have_apx"
+libc_cv_support_sframe=yes
+
test -n "$critic_missing" && as_fn_error $? "
*** $critic_missing" "$LINENO" 5
diff --git a/sysdeps/x86_64/configure.ac b/sysdeps/x86_64/configure.ac
index 4a3f7f4..a00958e 100644
--- a/sysdeps/x86_64/configure.ac
+++ b/sysdeps/x86_64/configure.ac
@@ -104,5 +104,7 @@ if test $libc_cv_x86_have_apx = yes; then
fi
LIBC_CONFIG_VAR([have-x86-apx], [$libc_cv_x86_have_apx])
+libc_cv_support_sframe=yes
+
test -n "$critic_missing" && AC_MSG_ERROR([
*** $critic_missing])
diff --git a/sysdeps/x86_64/fpu/multiarch/Makefile b/sysdeps/x86_64/fpu/multiarch/Makefile
index 5fe872b..708b142 100644
--- a/sysdeps/x86_64/fpu/multiarch/Makefile
+++ b/sysdeps/x86_64/fpu/multiarch/Makefile
@@ -26,19 +26,21 @@ CFLAGS-s_sinf-fma.c = -mfma -mavx2
CFLAGS-s_cosf-fma.c = -mfma -mavx2
CFLAGS-s_sincosf-fma.c = -mfma -mavx2
+# Check if ISA level is 2 or above.
+ifeq (,$(filter $(have-x86-isa-level),$(x86-isa-level-2-or-above)))
+sysdep_calls += \
+ s_modf-sse4_1 \
+ s_modff-sse4_1 \
+# sysdep_calls
+endif
+
# Check if ISA level is 3 or above.
ifneq (,$(filter $(have-x86-isa-level),$(x86-isa-level-3-or-above)))
-sysdep_routines += \
- s_modf-avx \
- s_modff-avx \
-# sysdep_routines
libm-sysdep_routines += \
s_ceil-avx \
s_ceilf-avx \
s_floor-avx \
s_floorf-avx \
- s_modf-avx \
- s_modff-avx \
s_nearbyint-avx \
s_nearbyintf-avx \
s_rint-avx \
@@ -49,6 +51,10 @@ libm-sysdep_routines += \
s_truncf-avx \
# libm-sysdep_routines
else
+sysdep_calls += \
+ s_modf-avx \
+ s_modff-avx \
+# sysdep_calls
ifeq (no,$(have-x86-apx))
libm-sysdep_routines += \
e_asin-fma4 \
@@ -62,10 +68,6 @@ libm-sysdep_routines += \
s_tan-fma4 \
# libm-sysdep_routines
endif
-sysdep_routines += \
- s_modf-sse4_1 \
- s_modff-sse4_1 \
-# sysdep_routines
libm-sysdep_routines += \
e_asin-fma \
e_atan2-avx \
@@ -95,8 +97,6 @@ libm-sysdep_routines += \
s_floor-sse4_1 \
s_floorf-sse4_1 \
s_log1p-fma \
- s_modf-sse4_1 \
- s_modff-sse4_1 \
s_nearbyint-sse4_1 \
s_nearbyintf-sse4_1 \
s_rint-sse4_1 \
@@ -118,17 +118,11 @@ libm-sysdep_routines += \
s_truncf-sse4_1 \
# libm-sysdep_routines
ifeq ($(have-x86-isa-level),baseline)
-sysdep_routines += \
- s_modf-c \
- s_modff-c \
-# sysdep-routines
libm-sysdep_routines += \
s_ceil-c \
s_ceilf-c \
s_floor-c \
s_floorf-c \
- s_modf-c \
- s_modff-c \
s_nearbyint-c \
s_nearbyintf-c \
s_rint-c \
@@ -139,6 +133,11 @@ libm-sysdep_routines += \
s_truncf-c \
# libm-sysdep_routines
endif
+
+# $(sysdep_calls) functions are built both for libc and libm. While the
+# libc objects have the prefix s_, the libm ones are prefixed with m_.
+sysdep_routines += $(sysdep_calls)
+libm-sysdep_routines += $(sysdep_calls:s_%=m_%)
endif
CFLAGS-e_asin-fma4.c = -mfma4
@@ -162,8 +161,8 @@ CFLAGS-s_sincos-avx.c = -msse2avx -DSSE2AVX
CFLAGS-s_modf-sse4_1.c = -msse4.1 -fno-builtin-modff32x -fno-builtin-modff64
CFLAGS-s_modff-sse4_1.c = -msse4.1 -fno-builtin-modff32
-CFLAGS-s_modf-avx.c = -msse2avx -DSSE2AVX -fno-builtin-modff32x -fno-builtin-modff64
-CFLAGS-s_modff-avx.c = -msse2avx -DSSE2AVX -fno-builtin-modff32
+CFLAGS-s_modf-avx.c = -mavx -fno-builtin-modff32x -fno-builtin-modff64
+CFLAGS-s_modff-avx.c = -mavx -fno-builtin-modff32
endif
ifeq ($(subdir),mathvec)
diff --git a/sysdeps/x86_64/fpu/multiarch/ifunc-sse4_1-avx.h b/sysdeps/x86_64/fpu/multiarch/ifunc-sse4_1-avx.h
new file mode 100644
index 0000000..071595f
--- /dev/null
+++ b/sysdeps/x86_64/fpu/multiarch/ifunc-sse4_1-avx.h
@@ -0,0 +1,41 @@
+/* Common definition for ifunc selections optimized with SSE4.1 and AVX.
+ Copyright (C) 2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <init-arch.h>
+
+extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (sse41) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (avx) attribute_hidden;
+
+static inline void *
+IFUNC_SELECTOR (void)
+{
+ const struct cpu_features* cpu_features = __get_cpu_features ();
+
+ if (CPU_FEATURE_USABLE_P (cpu_features, AVX))
+ return OPTIMIZE (avx);
+
+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
+ return OPTIMIZE (sse41);
+#else
+ if (CPU_FEATURE_USABLE_P (cpu_features, SSE4_1))
+ return OPTIMIZE (sse41);
+
+ return OPTIMIZE (sse2);
+#endif
+}
diff --git a/sysdeps/x86_64/fpu/multiarch/s_modf-avx.c b/sysdeps/x86_64/fpu/multiarch/s_modf-avx.c
index db32398..ab4f03d 100644
--- a/sysdeps/x86_64/fpu/multiarch/s_modf-avx.c
+++ b/sysdeps/x86_64/fpu/multiarch/s_modf-avx.c
@@ -1 +1,3 @@
+#define __modf __modf_avx
+
#include <sysdeps/ieee754/dbl-64/s_modf.c>
diff --git a/sysdeps/x86_64/fpu/multiarch/s_modf-c.c b/sysdeps/x86_64/fpu/multiarch/s_modf-c.c
deleted file mode 100644
index 6679d32..0000000
--- a/sysdeps/x86_64/fpu/multiarch/s_modf-c.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define __modf __modf_c
-#include <sysdeps/ieee754/dbl-64/s_modf.c>
diff --git a/sysdeps/x86_64/fpu/multiarch/s_modf-sse4_1.c b/sysdeps/x86_64/fpu/multiarch/s_modf-sse4_1.c
index 6ef4c19..00aa8cd 100644
--- a/sysdeps/x86_64/fpu/multiarch/s_modf-sse4_1.c
+++ b/sysdeps/x86_64/fpu/multiarch/s_modf-sse4_1.c
@@ -1,7 +1,3 @@
-#include <sysdeps/x86/isa-level.h>
-
-#if MINIMUM_X86_ISA_LEVEL != SSE4_1_X86_ISA_LEVEL
-# define __modf __modf_sse41
-#endif
+#define __modf __modf_sse41
#include <sysdeps/ieee754/dbl-64/s_modf.c>
diff --git a/sysdeps/x86_64/fpu/multiarch/s_modf.c b/sysdeps/x86_64/fpu/multiarch/s_modf.c
index d65977d..e365bfc 100644
--- a/sysdeps/x86_64/fpu/multiarch/s_modf.c
+++ b/sysdeps/x86_64/fpu/multiarch/s_modf.c
@@ -17,7 +17,7 @@
<https://www.gnu.org/licenses/>. */
#include <sysdeps/x86/isa-level.h>
-#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL
+#if MINIMUM_X86_ISA_LEVEL < AVX_X86_ISA_LEVEL
# define NO_MATH_REDIRECT
# include <libm-alias-double.h>
@@ -28,8 +28,14 @@
# undef __modf
# define SYMBOL_NAME modf
-# include "ifunc-sse4_1.h"
+# include "ifunc-sse4_1-avx.h"
libc_ifunc_redirected (__redirect_modf, __modf, IFUNC_SELECTOR ());
libm_alias_double (__modf, modf)
+# if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
+# define __modf __modf_sse41
+# else
+# define __modf __modf_sse2
+# endif
#endif
+#include <sysdeps/ieee754/dbl-64/s_modf.c>
diff --git a/sysdeps/x86_64/fpu/multiarch/s_modff-avx.c b/sysdeps/x86_64/fpu/multiarch/s_modff-avx.c
index 804b042..07cb9c1 100644
--- a/sysdeps/x86_64/fpu/multiarch/s_modff-avx.c
+++ b/sysdeps/x86_64/fpu/multiarch/s_modff-avx.c
@@ -1 +1,3 @@
+#define __modff __modff_avx
+
#include <sysdeps/ieee754/flt-32/s_modff.c>
diff --git a/sysdeps/x86_64/fpu/multiarch/s_modff-c.c b/sysdeps/x86_64/fpu/multiarch/s_modff-c.c
deleted file mode 100644
index f54f8ea..0000000
--- a/sysdeps/x86_64/fpu/multiarch/s_modff-c.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define __modff __modff_c
-#include <sysdeps/ieee754/flt-32/s_modff.c>
diff --git a/sysdeps/x86_64/fpu/multiarch/s_modff-sse4_1.c b/sysdeps/x86_64/fpu/multiarch/s_modff-sse4_1.c
index 0437e04..060c5e3 100644
--- a/sysdeps/x86_64/fpu/multiarch/s_modff-sse4_1.c
+++ b/sysdeps/x86_64/fpu/multiarch/s_modff-sse4_1.c
@@ -1,7 +1,3 @@
-#include <sysdeps/x86/isa-level.h>
-
-#if MINIMUM_X86_ISA_LEVEL != SSE4_1_X86_ISA_LEVEL
-# define __modff __modff_sse41
-#endif
+#define __modff __modff_sse41
#include <sysdeps/ieee754/flt-32/s_modff.c>
diff --git a/sysdeps/x86_64/fpu/multiarch/s_modff.c b/sysdeps/x86_64/fpu/multiarch/s_modff.c
index 89d0a32..a4b5429 100644
--- a/sysdeps/x86_64/fpu/multiarch/s_modff.c
+++ b/sysdeps/x86_64/fpu/multiarch/s_modff.c
@@ -17,7 +17,7 @@
<https://www.gnu.org/licenses/>. */
#include <sysdeps/x86/isa-level.h>
-#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL
+#if MINIMUM_X86_ISA_LEVEL < AVX_X86_ISA_LEVEL
# define NO_MATH_REDIRECT
# include <libm-alias-float.h>
@@ -28,8 +28,14 @@
# undef __modff
# define SYMBOL_NAME modff
-# include "ifunc-sse4_1.h"
+# include "ifunc-sse4_1-avx.h"
libc_ifunc_redirected (__redirect_modff, __modff, IFUNC_SELECTOR ());
libm_alias_float (__modf, modf)
+# if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
+# define __modff __modff_sse41
+# else
+# define __modff __modff_sse2
+# endif
#endif
+#include <sysdeps/ieee754/flt-32/s_modff.c>