about summary refs log tree commit diff
path: root/sysdeps/x86_64
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2024-01-05 09:32:37 -0300
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2024-01-09 13:55:51 -0300
commitb7fc4a07f206a640e6d807d72f5c1ee3ea7a25b6 (patch)
tree51669d2e37be82d006f4f665f47274ed78273cbb /sysdeps/x86_64
parent46e713be5770b19568fab074afbc7d992b0c3624 (diff)
downloadglibc-b7fc4a07f206a640e6d807d72f5c1ee3ea7a25b6.tar.gz
glibc-b7fc4a07f206a640e6d807d72f5c1ee3ea7a25b6.tar.xz
glibc-b7fc4a07f206a640e6d807d72f5c1ee3ea7a25b6.zip
x86: Move CET infrastructure to x86_64
The CET is only supported for x86_64 and there is no plan to add
kernel support for i386.  Move the Makefile rules and files from the
generic x86 folder to x86_64 one.

Checked on x86_64-linux-gnu and i686-linux-gnu.
Diffstat (limited to 'sysdeps/x86_64')
-rw-r--r--sysdeps/x86_64/Makefile243
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-1.c44
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-10-static.c1
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-10.c43
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-10a-static.c2
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-10a.c2
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-1a.c81
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-2.c64
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-2a.c1
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-3.c37
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-4.c60
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-4a.c1
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-4b.c1
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-4c.c1
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-5.c89
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-5a.c1
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-5b.c1
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-6.c89
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-6a.c1
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-6b.c1
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-7.c38
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-8.c49
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-9-static.c1
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-9.c41
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-mod-1.c24
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-mod-2.c24
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-mod-4.c2
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-mod-5.c31
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-mod-5a.c1
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-mod-5b.c1
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-mod-5c.c36
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-mod-6.c31
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-mod-6a.c1
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-mod-6b.c1
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-mod-6c.c36
-rw-r--r--sysdeps/x86_64/tst-cet-legacy-mod-6d.c1
-rw-r--r--sysdeps/x86_64/tst-shstk-legacy-1-extra.S35
-rw-r--r--sysdeps/x86_64/tst-shstk-legacy-1a-static.c1
-rw-r--r--sysdeps/x86_64/tst-shstk-legacy-1a.c32
-rw-r--r--sysdeps/x86_64/tst-shstk-legacy-1b-static.c1
-rw-r--r--sysdeps/x86_64/tst-shstk-legacy-1b.c38
-rw-r--r--sysdeps/x86_64/tst-shstk-legacy-1c-static.c1
-rw-r--r--sysdeps/x86_64/tst-shstk-legacy-1c.c20
-rw-r--r--sysdeps/x86_64/tst-shstk-legacy-1d-static.c1
-rw-r--r--sysdeps/x86_64/tst-shstk-legacy-1d.c47
-rw-r--r--sysdeps/x86_64/tst-shstk-legacy-1e-static.c1
-rwxr-xr-xsysdeps/x86_64/tst-shstk-legacy-1e-static.sh33
-rw-r--r--sysdeps/x86_64/tst-shstk-legacy-1e.c53
-rwxr-xr-xsysdeps/x86_64/tst-shstk-legacy-1e.sh35
-rw-r--r--sysdeps/x86_64/tst-shstk-legacy-1f.c29
-rw-r--r--sysdeps/x86_64/tst-shstk-legacy-1g.c35
-rwxr-xr-xsysdeps/x86_64/tst-shstk-legacy-1g.sh35
-rw-r--r--sysdeps/x86_64/tst-shstk-legacy-mod-1.c28
53 files changed, 1506 insertions, 0 deletions
diff --git a/sysdeps/x86_64/Makefile b/sysdeps/x86_64/Makefile
index 836e03a224..98f0e04f90 100644
--- a/sysdeps/x86_64/Makefile
+++ b/sysdeps/x86_64/Makefile
@@ -233,6 +233,249 @@ tests += \
   tst-rsi-wcslen
 endif
 
+
+ifeq ($(subdir),setjmp)
+ifneq ($(enable-cet),no)
+tests += \
+  tst-setjmp-cet \
+# tests
+tst-setjmp-cet-ENV = GLIBC_TUNABLES=glibc.cpu.x86_ibt=on:glibc.cpu.x86_shstk=on
+endif
+endif
+
+
+ifneq ($(enable-cet),no)
+ifeq ($(subdir),elf)
+sysdep-dl-routines += dl-cet
+
+tests += \
+  tst-cet-legacy-1 \
+  tst-cet-legacy-1a \
+  tst-cet-legacy-2 \
+  tst-cet-legacy-2a \
+  tst-cet-legacy-3 \
+  tst-cet-legacy-4 \
+  tst-cet-legacy-5a \
+  tst-cet-legacy-6a \
+  tst-cet-legacy-7 \
+  tst-cet-legacy-8 \
+  tst-cet-legacy-9 \
+  tst-cet-legacy-9-static \
+  tst-cet-legacy-10 \
+  tst-cet-legacy-10-static \
+  tst-cet-legacy-10a \
+  tst-cet-legacy-10a-static \
+# tests
+tests-static += \
+  tst-cet-legacy-9-static \
+  tst-cet-legacy-10-static \
+  tst-cet-legacy-10a-static \
+# tests-static
+tst-cet-legacy-1a-ARGS = -- $(host-test-program-cmd)
+
+tests += \
+  tst-shstk-legacy-1a \
+  tst-shstk-legacy-1a-static \
+  tst-shstk-legacy-1b \
+  tst-shstk-legacy-1b-static \
+  tst-shstk-legacy-1c \
+  tst-shstk-legacy-1c-static \
+  tst-shstk-legacy-1d \
+  tst-shstk-legacy-1d-static \
+  tst-shstk-legacy-1e \
+  tst-shstk-legacy-1e-static \
+  tst-shstk-legacy-1f \
+  tst-shstk-legacy-1g \
+# tests
+modules-names += \
+  tst-shstk-legacy-mod-1 \
+# modules-names
+tests-static += \
+  tst-shstk-legacy-1a-static \
+  tst-shstk-legacy-1b-static \
+  tst-shstk-legacy-1c-static \
+  tst-shstk-legacy-1d-static \
+  tst-shstk-legacy-1e-static \
+# tests-static
+extra-objs += \
+  tst-shstk-legacy-1-extra.o \
+# extra-objs
+
+tests += \
+  tst-cet-legacy-4a \
+  tst-cet-legacy-4b \
+  tst-cet-legacy-4c \
+  tst-cet-legacy-5b \
+  tst-cet-legacy-6b \
+# tests
+modules-names += \
+  tst-cet-legacy-mod-1 \
+  tst-cet-legacy-mod-2 \
+  tst-cet-legacy-mod-4 \
+  tst-cet-legacy-mod-5a \
+  tst-cet-legacy-mod-5b \
+  tst-cet-legacy-mod-5c \
+  tst-cet-legacy-mod-6a \
+  tst-cet-legacy-mod-6b \
+  tst-cet-legacy-mod-6c \
+# modules-names
+
+CFLAGS-tst-cet-legacy-2.c += -fcf-protection=none -fcf-protection=branch
+CFLAGS-tst-cet-legacy-2a.c += -fcf-protection
+CFLAGS-tst-cet-legacy-mod-1.c += -fcf-protection=none
+CFLAGS-tst-cet-legacy-mod-2.c += -fcf-protection=none
+CFLAGS-tst-cet-legacy-3.c += -fcf-protection=none
+CFLAGS-tst-cet-legacy-4.c += -fcf-protection=none -fcf-protection=branch
+CPPFLAGS-tst-cet-legacy-4a.c += -DCET_IS_PERMISSIVE=1
+CFLAGS-tst-cet-legacy-4a.c += -fcf-protection
+CFLAGS-tst-cet-legacy-4b.c += -fcf-protection
+CFLAGS-tst-cet-legacy-mod-4.c += -fcf-protection=none
+CFLAGS-tst-cet-legacy-5a.c += -fcf-protection -mshstk
+ifeq ($(enable-cet),permissive)
+CPPFLAGS-tst-cet-legacy-5a.c += -DCET_IS_PERMISSIVE=1
+endif
+CFLAGS-tst-cet-legacy-5b.c += -fcf-protection -mshstk
+CPPFLAGS-tst-cet-legacy-5b.c += -DCET_DISABLED_BY_ENV=1
+CFLAGS-tst-cet-legacy-mod-5a.c += -fcf-protection=none -fcf-protection=branch
+CFLAGS-tst-cet-legacy-mod-5b.c += -fcf-protection
+CFLAGS-tst-cet-legacy-mod-5c.c += -fcf-protection
+CFLAGS-tst-cet-legacy-6a.c += -fcf-protection -mshstk
+ifeq ($(enable-cet),permissive)
+CPPFLAGS-tst-cet-legacy-6a.c += -DCET_IS_PERMISSIVE=1
+endif
+CFLAGS-tst-cet-legacy-6b.c += -fcf-protection -mshstk
+CPPFLAGS-tst-cet-legacy-6b.c += -DCET_DISABLED_BY_ENV=1
+CFLAGS-tst-cet-legacy-mod-6a.c += -fcf-protection=none -fcf-protection=branch
+CFLAGS-tst-cet-legacy-mod-6b.c += -fcf-protection
+CFLAGS-tst-cet-legacy-mod-6c.c += -fcf-protection
+CFLAGS-tst-cet-legacy-7.c += -fcf-protection=none
+CFLAGS-tst-cet-legacy-10.c += -mshstk
+CFLAGS-tst-cet-legacy-10-static.c += -mshstk
+CFLAGS-tst-cet-legacy-10a.c += -fcf-protection=none
+CFLAGS-tst-cet-legacy-10a-static.c += -fcf-protection=none
+
+tst-cet-legacy-4-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK
+tst-cet-legacy-6-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK
+tst-cet-legacy-10-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK
+tst-cet-legacy-10-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK
+tst-cet-legacy-10a-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK
+tst-cet-legacy-10a-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK
+
+CFLAGS-tst-shstk-legacy-1a.c += -fcf-protection=none
+CFLAGS-tst-shstk-legacy-1a-static.c += -fcf-protection=none
+CFLAGS-tst-shstk-legacy-1d.c += -fcf-protection=none
+CFLAGS-tst-shstk-legacy-1d-static.c += -fcf-protection=none
+CFLAGS-tst-shstk-legacy-1f.c += -fcf-protection=none
+
+$(objpfx)tst-cet-legacy-1: $(objpfx)tst-cet-legacy-mod-1.so \
+		       $(objpfx)tst-cet-legacy-mod-2.so
+$(objpfx)tst-cet-legacy-1a: $(objpfx)tst-cet-legacy-mod-1.so \
+		       $(objpfx)tst-cet-legacy-mod-2.so
+$(objpfx)tst-cet-legacy-2: $(objpfx)tst-cet-legacy-mod-2.so
+$(objpfx)tst-cet-legacy-2.out: $(objpfx)tst-cet-legacy-mod-1.so
+$(objpfx)tst-cet-legacy-2a: $(objpfx)tst-cet-legacy-mod-2.so
+$(objpfx)tst-cet-legacy-2a.out: $(objpfx)tst-cet-legacy-mod-1.so
+$(objpfx)tst-cet-legacy-4.out: $(objpfx)tst-cet-legacy-mod-4.so
+$(objpfx)tst-cet-legacy-5a.out: $(objpfx)tst-cet-legacy-mod-5a.so \
+				$(objpfx)tst-cet-legacy-mod-5b.so
+$(objpfx)tst-cet-legacy-mod-5a.so: $(objpfx)tst-cet-legacy-mod-5c.so
+$(objpfx)tst-cet-legacy-mod-5b.so: $(objpfx)tst-cet-legacy-mod-5c.so
+$(objpfx)tst-cet-legacy-6a.out: $(objpfx)tst-cet-legacy-mod-6a.so \
+				$(objpfx)tst-cet-legacy-mod-6b.so
+$(objpfx)tst-cet-legacy-mod-6a.so: $(objpfx)tst-cet-legacy-mod-6c.so
+$(objpfx)tst-cet-legacy-mod-6b.so: $(objpfx)tst-cet-legacy-mod-6c.so
+LDFLAGS-tst-cet-legacy-mod-6c.so = -Wl,--enable-new-dtags,-z,nodelete
+$(objpfx)tst-cet-legacy-4a.out: $(objpfx)tst-cet-legacy-mod-4.so
+tst-cet-legacy-4a-ENV = GLIBC_TUNABLES=glibc.cpu.x86_shstk=permissive
+$(objpfx)tst-cet-legacy-4b.out: $(objpfx)tst-cet-legacy-mod-4.so
+tst-cet-legacy-4b-ENV = GLIBC_TUNABLES=glibc.cpu.x86_shstk=on
+$(objpfx)tst-cet-legacy-4c.out: $(objpfx)tst-cet-legacy-mod-4.so
+tst-cet-legacy-4c-ENV = GLIBC_TUNABLES=glibc.cpu.x86_shstk=off
+$(objpfx)tst-cet-legacy-5b.out: $(objpfx)tst-cet-legacy-mod-5a.so \
+				$(objpfx)tst-cet-legacy-mod-5b.so
+tst-cet-legacy-5b-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-IBT,-SHSTK
+$(objpfx)tst-cet-legacy-6b.out: $(objpfx)tst-cet-legacy-mod-6a.so \
+				$(objpfx)tst-cet-legacy-mod-6b.so
+tst-cet-legacy-6b-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-IBT,-SHSTK
+tst-cet-legacy-9-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-IBT,-SHSTK
+tst-cet-legacy-9-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-IBT,-SHSTK
+
+tst-shstk-legacy-1a-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK
+tst-shstk-legacy-1a-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK
+$(objpfx)tst-shstk-legacy-1a: $(objpfx)tst-shstk-legacy-1-extra.o
+$(objpfx)tst-shstk-legacy-1a-static: $(objpfx)tst-shstk-legacy-1-extra.o
+tst-shstk-legacy-1b-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK
+tst-shstk-legacy-1b-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK
+$(objpfx)tst-shstk-legacy-1b: $(objpfx)tst-shstk-legacy-1-extra.o
+$(objpfx)tst-shstk-legacy-1b-static: $(objpfx)tst-shstk-legacy-1-extra.o
+tst-shstk-legacy-1c-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-SHSTK
+tst-shstk-legacy-1c-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-SHSTK
+$(objpfx)tst-shstk-legacy-1c: $(objpfx)tst-shstk-legacy-1-extra.o
+$(objpfx)tst-shstk-legacy-1c-static: $(objpfx)tst-shstk-legacy-1-extra.o
+tst-shstk-legacy-1d-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK
+tst-shstk-legacy-1d-static-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK
+$(objpfx)tst-shstk-legacy-1d: $(objpfx)tst-shstk-legacy-1-extra.o
+$(objpfx)tst-shstk-legacy-1d-static: $(objpfx)tst-shstk-legacy-1-extra.o
+$(objpfx)tst-shstk-legacy-1e: $(objpfx)tst-shstk-legacy-1-extra.o
+$(objpfx)tst-shstk-legacy-1e-static: $(objpfx)tst-shstk-legacy-1-extra.o
+$(objpfx)tst-shstk-legacy-1e.out: \
+  $(..)/sysdeps/x86_64/tst-shstk-legacy-1e.sh $(objpfx)tst-shstk-legacy-1e
+	$(SHELL) $< $(common-objpfx) '$(test-program-prefix)' 2> $@; \
+	$(evaluate-test)
+$(objpfx)tst-shstk-legacy-1e-static.out: \
+  $(..)/sysdeps/x86_64/tst-shstk-legacy-1e-static.sh \
+  $(objpfx)tst-shstk-legacy-1e-static
+	$(SHELL) $< $(common-objpfx) 2> $@; \
+	$(evaluate-test)
+tst-shstk-legacy-1f-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK
+$(objpfx)tst-shstk-legacy-1f: $(objpfx)tst-shstk-legacy-mod-1.so
+$(objpfx)tst-shstk-legacy-mod-1.so: \
+  $(objpfx)tst-shstk-legacy-mod-1.os \
+  $(objpfx)tst-shstk-legacy-1-extra.os
+$(objpfx)tst-shstk-legacy-1g: $(objpfx)tst-shstk-legacy-mod-1.so
+$(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
+
+# FIXME: Can't use all-built-dso in elf/Makefile since this file is
+# processed before elf/Makefile.  Duplicate it here.
+cet-built-dso := $(common-objpfx)elf/ld.so $(common-objpfx)libc.so \
+		 $(filter-out $(common-objpfx)linkobj/libc.so, \
+			      $(sort $(wildcard $(addprefix $(common-objpfx), \
+							    */lib*.so \
+							    iconvdata/*.so))))
+
+$(cet-built-dso:=.note): %.note: %
+	@rm -f $@T
+	LC_ALL=C $(READELF) -n $< > $@T
+	test -s $@T
+	mv -f $@T $@
+common-generated += $(cet-built-dso:$(common-objpfx)%=%.note)
+
+$(objpfx)check-cet.out: $(..)sysdeps/x86/check-cet.awk \
+			$(cet-built-dso:=.note)
+	LC_ALL=C $(AWK) -f $^ > $@; \
+	$(evaluate-test)
+generated += check-cet.out
+endif # $(subdir) == elf
+endif # $(enable) != no
+
 do-tests-clean common-mostlyclean: tst-x86_64-1-clean
 
 .PHONY: tst-x86_64-1-clean
diff --git a/sysdeps/x86_64/tst-cet-legacy-1.c b/sysdeps/x86_64/tst-cet-legacy-1.c
new file mode 100644
index 0000000000..e2d8d55687
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-1.c
@@ -0,0 +1,44 @@
+/* Check compatibility of CET-enabled executable linked with legacy
+   shared object.
+   Copyright (C) 2018-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 <stdio.h>
+#include <stdlib.h>
+
+extern int in_dso_1 (void);
+extern int in_dso_2 (void);
+
+static int
+do_test (void)
+{
+  if (in_dso_1 () != 0x1234678)
+    {
+      puts ("in_dso_1 () != 0x1234678");
+      exit (1);
+    }
+
+  if (in_dso_2 () != 0xbadbeef)
+    {
+      puts ("in_dso_2 () != 0xbadbeef");
+      exit (1);
+    }
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/x86_64/tst-cet-legacy-10-static.c b/sysdeps/x86_64/tst-cet-legacy-10-static.c
new file mode 100644
index 0000000000..ecc1208e35
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-10-static.c
@@ -0,0 +1 @@
+#include "tst-cet-legacy-10.c"
diff --git a/sysdeps/x86_64/tst-cet-legacy-10.c b/sysdeps/x86_64/tst-cet-legacy-10.c
new file mode 100644
index 0000000000..02fe9e935c
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-10.c
@@ -0,0 +1,43 @@
+/* Check CPU_FEATURE_ACTIVE on IBT and SHSTK.
+   Copyright (C) 2021-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 <x86intrin.h>
+#include <sys/platform/x86.h>
+#include <support/test-driver.h>
+#include <support/xunistd.h>
+
+/* Check that CPU_FEATURE_ACTIVE on SHSTK matches _get_ssp.  */
+
+static int
+do_test (void)
+{
+  if (_get_ssp () != 0)
+    {
+      if (CPU_FEATURE_ACTIVE (SHSTK))
+	return EXIT_SUCCESS;
+    }
+  else
+    {
+      if (!CPU_FEATURE_ACTIVE (SHSTK))
+	return EXIT_SUCCESS;
+    }
+
+  return EXIT_FAILURE;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/x86_64/tst-cet-legacy-10a-static.c b/sysdeps/x86_64/tst-cet-legacy-10a-static.c
new file mode 100644
index 0000000000..05073a5d1e
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-10a-static.c
@@ -0,0 +1,2 @@
+#pragma GCC target ("shstk")
+#include "tst-cet-legacy-10.c"
diff --git a/sysdeps/x86_64/tst-cet-legacy-10a.c b/sysdeps/x86_64/tst-cet-legacy-10a.c
new file mode 100644
index 0000000000..05073a5d1e
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-10a.c
@@ -0,0 +1,2 @@
+#pragma GCC target ("shstk")
+#include "tst-cet-legacy-10.c"
diff --git a/sysdeps/x86_64/tst-cet-legacy-1a.c b/sysdeps/x86_64/tst-cet-legacy-1a.c
new file mode 100644
index 0000000000..205e0892b3
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-1a.c
@@ -0,0 +1,81 @@
+/* Test for re-exec with legacy bitmap.
+   Copyright (C) 2018-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 <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <support/check.h>
+
+/* Nonzero if the program gets called via `exec'.  */
+static int restart;
+
+#define CMDLINE_OPTIONS \
+  { "restart", no_argument, &restart, 1 },
+
+extern int do_test (int argc, char *argv[]);
+
+extern int in_dso_1 (void);
+extern int in_dso_2 (void);
+
+static int
+check (void)
+{
+  if (in_dso_1 () != 0x1234678)
+    {
+      puts ("in_dso_1 () != 0x1234678");
+      exit (1);
+    }
+
+  if (in_dso_2 () != 0xbadbeef)
+    {
+      puts ("in_dso_2 () != 0xbadbeef");
+      exit (1);
+    }
+
+  return 0;
+}
+
+int
+do_test (int argc, char *argv[])
+{
+  /* We must have
+     - one or four parameters left if called initially
+       + path for ld.so		optional
+       + "--library-path"	optional
+       + the library path	optional
+       + the application name
+  */
+
+  if (restart)
+    return check ();
+
+  if (argc != 2 && argc != 5)
+    FAIL_EXIT1 ("wrong number of arguments (%d)", argc);
+
+  if (argc == 5)
+    execl (argv[1], argv[1], argv[2], argv[3], argv[4], "--direct",
+	   "--restart",  NULL);
+  else
+    execl (argv[1], argv[1], "--direct", "--restart",  NULL);
+
+  return -1;
+}
+
+#define TEST_FUNCTION_ARGV do_test
+#include <support/test-driver.c>
diff --git a/sysdeps/x86_64/tst-cet-legacy-2.c b/sysdeps/x86_64/tst-cet-legacy-2.c
new file mode 100644
index 0000000000..887a98e348
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-2.c
@@ -0,0 +1,64 @@
+/* Check compatibility of CET-enabled executable with dlopened legacy
+   shared object.
+   Copyright (C) 2018-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 <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+extern int in_dso_2 (void);
+
+static int
+do_test (void)
+{
+  static const char modname[] = "tst-cet-legacy-mod-1.so";
+  int (*fp) (void);
+  void *h;
+
+  h = dlopen (modname, RTLD_LAZY);
+  if (h == NULL)
+    {
+      printf ("cannot open '%s': %s\n", modname, dlerror ());
+      exit (1);
+    }
+
+  fp = dlsym (h, "in_dso_1");
+  if (fp == NULL)
+    {
+      printf ("cannot get symbol 'in_dso': %s\n", dlerror ());
+      exit (1);
+    }
+
+  if (fp () != 0x1234678)
+    {
+      puts ("in_dso_1 () != 0x1234678");
+      exit (1);
+    }
+
+  if (in_dso_2 () != 0xbadbeef)
+    {
+      puts ("in_dso_2 () != 0xbadbeef");
+      exit (1);
+    }
+
+  dlclose (h);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/x86_64/tst-cet-legacy-2a.c b/sysdeps/x86_64/tst-cet-legacy-2a.c
new file mode 100644
index 0000000000..d5aead4303
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-2a.c
@@ -0,0 +1 @@
+#include "tst-cet-legacy-2.c"
diff --git a/sysdeps/x86_64/tst-cet-legacy-3.c b/sysdeps/x86_64/tst-cet-legacy-3.c
new file mode 100644
index 0000000000..39b0264848
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-3.c
@@ -0,0 +1,37 @@
+/* Check compatibility of CET-enabled executable with dlopened legacy
+   shared object.
+   Copyright (C) 2018-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 <stdio.h>
+
+int
+test (void)
+{
+  printf ("PASS\n");
+  return 0;
+}
+
+#ifndef TEST_MODULE
+static int
+do_test (void)
+{
+  return test ();
+}
+
+#include <support/test-driver.c>
+#endif
diff --git a/sysdeps/x86_64/tst-cet-legacy-4.c b/sysdeps/x86_64/tst-cet-legacy-4.c
new file mode 100644
index 0000000000..3d6e2ca15c
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-4.c
@@ -0,0 +1,60 @@
+/* Check compatibility of CET-enabled executable with dlopened legacy
+   shared object.
+   Copyright (C) 2018-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 <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/platform/x86.h>
+
+#include <support/check.h>
+
+static int
+do_test (void)
+{
+  static const char modname[] = "tst-cet-legacy-mod-4.so";
+  int (*fp) (void);
+  void *h;
+
+  h = dlopen (modname, RTLD_LAZY);
+  if (h == NULL)
+    {
+      const char *err = dlerror ();
+      if (!strstr (err, "rebuild shared object with IBT support enabled"))
+	FAIL_EXIT1 ("incorrect dlopen '%s' error: %s\n", modname, err);
+      return 0;
+    }
+
+#ifdef CET_IS_PERMISSIVE
+  TEST_VERIFY (!CPU_FEATURE_ACTIVE (IBT) && !CPU_FEATURE_ACTIVE (SHSTK));
+#endif
+
+  fp = dlsym (h, "test");
+  if (fp == NULL)
+    FAIL_EXIT1 ("cannot get symbol 'test': %s\n", dlerror ());
+
+  if (fp () != 0)
+    FAIL_EXIT1 ("test () != 0");
+
+  dlclose (h);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/x86_64/tst-cet-legacy-4a.c b/sysdeps/x86_64/tst-cet-legacy-4a.c
new file mode 100644
index 0000000000..b9bb18c36b
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-4a.c
@@ -0,0 +1 @@
+#include "tst-cet-legacy-4.c"
diff --git a/sysdeps/x86_64/tst-cet-legacy-4b.c b/sysdeps/x86_64/tst-cet-legacy-4b.c
new file mode 100644
index 0000000000..b9bb18c36b
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-4b.c
@@ -0,0 +1 @@
+#include "tst-cet-legacy-4.c"
diff --git a/sysdeps/x86_64/tst-cet-legacy-4c.c b/sysdeps/x86_64/tst-cet-legacy-4c.c
new file mode 100644
index 0000000000..b9bb18c36b
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-4c.c
@@ -0,0 +1 @@
+#include "tst-cet-legacy-4.c"
diff --git a/sysdeps/x86_64/tst-cet-legacy-5.c b/sysdeps/x86_64/tst-cet-legacy-5.c
new file mode 100644
index 0000000000..c546eb86e5
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-5.c
@@ -0,0 +1,89 @@
+/* Check compatibility of CET-enabled executable with dlopened legacy
+   shared object.
+   Copyright (C) 2019-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 <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <x86intrin.h>
+#include <support/check.h>
+
+#if defined CET_IS_PERMISSIVE || defined CET_DISABLED_BY_ENV
+# define CET_MAYBE_DISABLED 1
+#else
+# define CET_MAYBE_DISABLED 0
+#endif
+
+static void
+do_test_1 (const char *modname, bool fail)
+{
+  int (*fp) (void);
+  void *h;
+
+  /* NB: dlopen should never fail on non-CET platforms.  If SHSTK is
+     disabled, assuming IBT is also disabled.  */
+  bool cet_enabled = _get_ssp () != 0 && !CET_MAYBE_DISABLED;
+  if (!cet_enabled)
+    fail = false;
+
+  h = dlopen (modname, RTLD_LAZY);
+  if (h == NULL)
+    {
+      const char *err = dlerror ();
+      if (fail)
+	{
+	  if (strstr (err, "rebuild shared object with SHSTK support enabled")
+	      == NULL)
+	    FAIL_EXIT1 ("incorrect dlopen '%s' error: %s\n", modname, err);
+
+	  return;
+	}
+
+      FAIL_EXIT1 ("cannot open '%s': %s\n", modname, err);
+    }
+
+  if (fail)
+    FAIL_EXIT1 ("dlopen should have failed\n");
+
+  fp = dlsym (h, "test");
+  if (fp == NULL)
+    {
+      printf ("cannot get symbol 'test': %s\n", dlerror ());
+      exit (1);
+    }
+
+  if (fp () != 0)
+    {
+      puts ("test () != 0");
+      exit (1);
+    }
+
+  dlclose (h);
+}
+
+static int
+do_test (void)
+{
+  do_test_1 ("tst-cet-legacy-mod-5a.so", true);
+  do_test_1 ("tst-cet-legacy-mod-5b.so", false);
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/x86_64/tst-cet-legacy-5a.c b/sysdeps/x86_64/tst-cet-legacy-5a.c
new file mode 100644
index 0000000000..fc5a609dff
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-5a.c
@@ -0,0 +1 @@
+#include "tst-cet-legacy-5.c"
diff --git a/sysdeps/x86_64/tst-cet-legacy-5b.c b/sysdeps/x86_64/tst-cet-legacy-5b.c
new file mode 100644
index 0000000000..fc5a609dff
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-5b.c
@@ -0,0 +1 @@
+#include "tst-cet-legacy-5.c"
diff --git a/sysdeps/x86_64/tst-cet-legacy-6.c b/sysdeps/x86_64/tst-cet-legacy-6.c
new file mode 100644
index 0000000000..1cfe8e8bd8
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-6.c
@@ -0,0 +1,89 @@
+/* Check compatibility of CET-enabled executable with dlopened legacy
+   shared object.
+   Copyright (C) 2019-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 <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <x86intrin.h>
+#include <support/check.h>
+
+#if defined CET_IS_PERMISSIVE || defined CET_DISABLED_BY_ENV
+# define CET_MAYBE_DISABLED 1
+#else
+# define CET_MAYBE_DISABLED 0
+#endif
+
+static void
+do_test_1 (const char *modname, bool fail)
+{
+  int (*fp) (void);
+  void *h;
+
+  /* NB: dlopen should never fail on non-CET platforms.  If SHSTK is
+     disabled, assuming IBT is also disabled.  */
+  bool cet_enabled = _get_ssp () != 0 && !CET_MAYBE_DISABLED;
+  if (!cet_enabled)
+    fail = false;
+
+  h = dlopen (modname, RTLD_LAZY);
+  if (h == NULL)
+    {
+      const char *err = dlerror ();
+      if (fail)
+	{
+	  if (strstr (err, "rebuild shared object with SHSTK support enabled")
+	      == NULL)
+	    FAIL_EXIT1 ("incorrect dlopen '%s' error: %s\n", modname, err);
+
+	  return;
+	}
+
+      FAIL_EXIT1 ("cannot open '%s': %s\n", modname, err);
+    }
+
+  if (fail)
+    FAIL_EXIT1 ("dlopen should have failed\n");
+
+  fp = dlsym (h, "test");
+  if (fp == NULL)
+    {
+      printf ("cannot get symbol 'test': %s\n", dlerror ());
+      exit (1);
+    }
+
+  if (fp () != 0)
+    {
+      puts ("test () != 0");
+      exit (1);
+    }
+
+  dlclose (h);
+}
+
+static int
+do_test (void)
+{
+  do_test_1 ("tst-cet-legacy-mod-6a.so", true);
+  do_test_1 ("tst-cet-legacy-mod-6b.so", false);
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/x86_64/tst-cet-legacy-6a.c b/sysdeps/x86_64/tst-cet-legacy-6a.c
new file mode 100644
index 0000000000..2d1546d36b
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-6a.c
@@ -0,0 +1 @@
+#include "tst-cet-legacy-6.c"
diff --git a/sysdeps/x86_64/tst-cet-legacy-6b.c b/sysdeps/x86_64/tst-cet-legacy-6b.c
new file mode 100644
index 0000000000..2d1546d36b
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-6b.c
@@ -0,0 +1 @@
+#include "tst-cet-legacy-6.c"
diff --git a/sysdeps/x86_64/tst-cet-legacy-7.c b/sysdeps/x86_64/tst-cet-legacy-7.c
new file mode 100644
index 0000000000..0d72de7ee5
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-7.c
@@ -0,0 +1,38 @@
+/* Check compatibility of legacy executable with a JIT engine.
+   Copyright (C) 2020-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 <stdio.h>
+#include <sys/mman.h>
+#include <support/xunistd.h>
+
+/* Check that mmapped legacy code works with -fcf-protection=none.  */
+
+static int
+do_test (void)
+{
+  void (*funcp) (void);
+  funcp = xmmap (NULL, 0x1000, PROT_EXEC | PROT_READ | PROT_WRITE,
+		 MAP_ANONYMOUS | MAP_PRIVATE, -1);
+  printf ("mmap = %p\n", funcp);
+  /* Write RET instruction.  */
+  *(char *) funcp = 0xc3;
+  funcp ();
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/x86_64/tst-cet-legacy-8.c b/sysdeps/x86_64/tst-cet-legacy-8.c
new file mode 100644
index 0000000000..303c658068
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-8.c
@@ -0,0 +1,49 @@
+/* Check incompatibility with legacy JIT engine.
+   Copyright (C) 2020-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 <stdio.h>
+#include <stdlib.h>
+#include <sys/platform/x86.h>
+#include <sys/mman.h>
+#include <support/test-driver.h>
+#include <support/xsignal.h>
+#include <support/xunistd.h>
+
+/* Check that mmapped legacy code trigges segfault with -fcf-protection.  */
+
+static int
+do_test (void)
+{
+  void (*funcp) (void);
+  funcp = xmmap (NULL, 0x1000, PROT_EXEC | PROT_READ | PROT_WRITE,
+		 MAP_ANONYMOUS | MAP_PRIVATE, -1);
+  printf ("mmap = %p\n", funcp);
+  /* Write RET instruction.  */
+  *(char *) funcp = 0xc3;
+  funcp ();
+
+  /* NB: This test should trigger SIGSEGV when IBT is active.  We should
+     reach here if IBT isn't active.  */
+  if (!CPU_FEATURE_ACTIVE (IBT))
+    return EXIT_UNSUPPORTED;
+
+  return EXIT_FAILURE;
+}
+
+#define EXPECTED_SIGNAL (CPU_FEATURE_ACTIVE (IBT) ? SIGSEGV : 0)
+#include <support/test-driver.c>
diff --git a/sysdeps/x86_64/tst-cet-legacy-9-static.c b/sysdeps/x86_64/tst-cet-legacy-9-static.c
new file mode 100644
index 0000000000..f9a8518b99
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-9-static.c
@@ -0,0 +1 @@
+#include "tst-cet-legacy-9.c"
diff --git a/sysdeps/x86_64/tst-cet-legacy-9.c b/sysdeps/x86_64/tst-cet-legacy-9.c
new file mode 100644
index 0000000000..7f2f1a2bba
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-9.c
@@ -0,0 +1,41 @@
+/* Check CET compatibility with legacy JIT engine via GLIBC_TUNABLES.
+   Copyright (C) 2021-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 <stdio.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <support/test-driver.h>
+#include <support/xunistd.h>
+
+/* Check that mmapped legacy code won't trigger segfault with
+   -fcf-protection and GLIBC_TUNABLES=glibc.cpu.hwcaps=-IBT,-SHSTK.  */
+
+static int
+do_test (void)
+{
+  void (*funcp) (void);
+  funcp = xmmap (NULL, 0x1000, PROT_EXEC | PROT_READ | PROT_WRITE,
+		 MAP_ANONYMOUS | MAP_PRIVATE, -1);
+  printf ("mmap = %p\n", funcp);
+  /* Write RET instruction.  */
+  *(char *) funcp = 0xc3;
+  funcp ();
+  return EXIT_SUCCESS;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/x86_64/tst-cet-legacy-mod-1.c b/sysdeps/x86_64/tst-cet-legacy-mod-1.c
new file mode 100644
index 0000000000..da06bced94
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-mod-1.c
@@ -0,0 +1,24 @@
+/* Check compatibility of CET-enabled executable with legacy shared
+   object.
+   Copyright (C) 2018-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/>.  */
+
+int
+in_dso_1 (void)
+{
+  return 0x1234678;
+}
diff --git a/sysdeps/x86_64/tst-cet-legacy-mod-2.c b/sysdeps/x86_64/tst-cet-legacy-mod-2.c
new file mode 100644
index 0000000000..c3f77c8edb
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-mod-2.c
@@ -0,0 +1,24 @@
+/* Check compatibility of CET-enabled executable with legacy shared
+   object.
+   Copyright (C) 2018-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/>.  */
+
+int
+in_dso_2 (void)
+{
+  return 0xbadbeef;
+}
diff --git a/sysdeps/x86_64/tst-cet-legacy-mod-4.c b/sysdeps/x86_64/tst-cet-legacy-mod-4.c
new file mode 100644
index 0000000000..a93c2fe4a7
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-mod-4.c
@@ -0,0 +1,2 @@
+#define TEST_MODULE
+#include "tst-cet-legacy-3.c"
diff --git a/sysdeps/x86_64/tst-cet-legacy-mod-5.c b/sysdeps/x86_64/tst-cet-legacy-mod-5.c
new file mode 100644
index 0000000000..3eacd58f20
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-mod-5.c
@@ -0,0 +1,31 @@
+/* Check compatibility of CET-enabled executable with dlopened legacy
+   shared object.
+   Copyright (C) 2019-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 <stdio.h>
+#include <stdlib.h>
+
+extern void foo (void);
+
+int
+test (void)
+{
+  foo ();
+  return 0;
+}
diff --git a/sysdeps/x86_64/tst-cet-legacy-mod-5a.c b/sysdeps/x86_64/tst-cet-legacy-mod-5a.c
new file mode 100644
index 0000000000..daa43e4e8d
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-mod-5a.c
@@ -0,0 +1 @@
+#include "tst-cet-legacy-mod-5.c"
diff --git a/sysdeps/x86_64/tst-cet-legacy-mod-5b.c b/sysdeps/x86_64/tst-cet-legacy-mod-5b.c
new file mode 100644
index 0000000000..daa43e4e8d
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-mod-5b.c
@@ -0,0 +1 @@
+#include "tst-cet-legacy-mod-5.c"
diff --git a/sysdeps/x86_64/tst-cet-legacy-mod-5c.c b/sysdeps/x86_64/tst-cet-legacy-mod-5c.c
new file mode 100644
index 0000000000..6acb36ba8d
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-mod-5c.c
@@ -0,0 +1,36 @@
+/* Check compatibility of CET-enabled executable with dlopened legacy
+   shared object.
+   Copyright (C) 2019-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 <stdlib.h>
+
+static int called = 0;
+
+static void
+__attribute__ ((constructor))
+init (void)
+{
+  called = 1;
+}
+
+void
+foo (void)
+{
+  if (!called)
+    abort ();
+}
diff --git a/sysdeps/x86_64/tst-cet-legacy-mod-6.c b/sysdeps/x86_64/tst-cet-legacy-mod-6.c
new file mode 100644
index 0000000000..3eacd58f20
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-mod-6.c
@@ -0,0 +1,31 @@
+/* Check compatibility of CET-enabled executable with dlopened legacy
+   shared object.
+   Copyright (C) 2019-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 <stdio.h>
+#include <stdlib.h>
+
+extern void foo (void);
+
+int
+test (void)
+{
+  foo ();
+  return 0;
+}
diff --git a/sysdeps/x86_64/tst-cet-legacy-mod-6a.c b/sysdeps/x86_64/tst-cet-legacy-mod-6a.c
new file mode 100644
index 0000000000..c89b8fe8ff
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-mod-6a.c
@@ -0,0 +1 @@
+#include "tst-cet-legacy-mod-6.c"
diff --git a/sysdeps/x86_64/tst-cet-legacy-mod-6b.c b/sysdeps/x86_64/tst-cet-legacy-mod-6b.c
new file mode 100644
index 0000000000..c89b8fe8ff
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-mod-6b.c
@@ -0,0 +1 @@
+#include "tst-cet-legacy-mod-6.c"
diff --git a/sysdeps/x86_64/tst-cet-legacy-mod-6c.c b/sysdeps/x86_64/tst-cet-legacy-mod-6c.c
new file mode 100644
index 0000000000..6acb36ba8d
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-mod-6c.c
@@ -0,0 +1,36 @@
+/* Check compatibility of CET-enabled executable with dlopened legacy
+   shared object.
+   Copyright (C) 2019-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 <stdlib.h>
+
+static int called = 0;
+
+static void
+__attribute__ ((constructor))
+init (void)
+{
+  called = 1;
+}
+
+void
+foo (void)
+{
+  if (!called)
+    abort ();
+}
diff --git a/sysdeps/x86_64/tst-cet-legacy-mod-6d.c b/sysdeps/x86_64/tst-cet-legacy-mod-6d.c
new file mode 100644
index 0000000000..eb233a1d10
--- /dev/null
+++ b/sysdeps/x86_64/tst-cet-legacy-mod-6d.c
@@ -0,0 +1 @@
+#include "tst-cet-legacy-mod-6c.c"
diff --git a/sysdeps/x86_64/tst-shstk-legacy-1-extra.S b/sysdeps/x86_64/tst-shstk-legacy-1-extra.S
new file mode 100644
index 0000000000..e2e27c5d65
--- /dev/null
+++ b/sysdeps/x86_64/tst-shstk-legacy-1-extra.S
@@ -0,0 +1,35 @@
+/* Legacy shadow stack code.
+   Copyright (C) 2023-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/>.  */
+
+	.text
+	.globl	legacy
+	.type	legacy, @function
+legacy:
+	.cfi_startproc
+#ifdef __x86_64__
+	movq	(%rsp), %rax
+	addq	$8, %rsp
+	jmp	*%rax
+#else
+	movl	(%esp), %eax
+	addl	$4, %esp
+	jmp	*%eax
+#endif
+	.cfi_endproc
+	.size	legacy, .-legacy
+	.section	.note.GNU-stack,"",@progbits
diff --git a/sysdeps/x86_64/tst-shstk-legacy-1a-static.c b/sysdeps/x86_64/tst-shstk-legacy-1a-static.c
new file mode 100644
index 0000000000..dd549890a0
--- /dev/null
+++ b/sysdeps/x86_64/tst-shstk-legacy-1a-static.c
@@ -0,0 +1 @@
+#include "tst-shstk-legacy-1a.c"
diff --git a/sysdeps/x86_64/tst-shstk-legacy-1a.c b/sysdeps/x86_64/tst-shstk-legacy-1a.c
new file mode 100644
index 0000000000..edfd72c459
--- /dev/null
+++ b/sysdeps/x86_64/tst-shstk-legacy-1a.c
@@ -0,0 +1,32 @@
+/* Check that legacy shadow stack code won't trigger segfault.
+   Copyright (C) 2023-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 <stdlib.h>
+#include <support/test-driver.h>
+
+/* Check that legacy shadow stack code won't trigger segfault.  */
+extern void legacy (void);
+
+static int
+do_test (void)
+{
+  legacy ();
+  return EXIT_SUCCESS;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/x86_64/tst-shstk-legacy-1b-static.c b/sysdeps/x86_64/tst-shstk-legacy-1b-static.c
new file mode 100644
index 0000000000..4945344675
--- /dev/null
+++ b/sysdeps/x86_64/tst-shstk-legacy-1b-static.c
@@ -0,0 +1 @@
+#include "tst-shstk-legacy-1b.c"
diff --git a/sysdeps/x86_64/tst-shstk-legacy-1b.c b/sysdeps/x86_64/tst-shstk-legacy-1b.c
new file mode 100644
index 0000000000..62943d724d
--- /dev/null
+++ b/sysdeps/x86_64/tst-shstk-legacy-1b.c
@@ -0,0 +1,38 @@
+/* Check that legacy shadow stack code will trigger segfault.
+   Copyright (C) 2023-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 <stdlib.h>
+#include <sys/platform/x86.h>
+#include <support/test-driver.h>
+#include <support/xsignal.h>
+
+/* Check that legacy shadow stack code will trigger segfault.  */
+extern void legacy (void);
+
+static int
+do_test (void)
+{
+  if (!CPU_FEATURE_ACTIVE (SHSTK))
+    return EXIT_UNSUPPORTED;
+
+  legacy ();
+  return EXIT_FAILURE;
+}
+
+#define EXPECTED_SIGNAL (CPU_FEATURE_ACTIVE (SHSTK) ? SIGSEGV : 0)
+#include <support/test-driver.c>
diff --git a/sysdeps/x86_64/tst-shstk-legacy-1c-static.c b/sysdeps/x86_64/tst-shstk-legacy-1c-static.c
new file mode 100644
index 0000000000..91ea346aaf
--- /dev/null
+++ b/sysdeps/x86_64/tst-shstk-legacy-1c-static.c
@@ -0,0 +1 @@
+#include "tst-shstk-legacy-1c.c"
diff --git a/sysdeps/x86_64/tst-shstk-legacy-1c.c b/sysdeps/x86_64/tst-shstk-legacy-1c.c
new file mode 100644
index 0000000000..da01fdfe0d
--- /dev/null
+++ b/sysdeps/x86_64/tst-shstk-legacy-1c.c
@@ -0,0 +1,20 @@
+/* Check that legacy shadow stack code won't trigger segfault with
+   GLIBC_TUNABLES=glibc.cpu.hwcaps=-SHSTK
+   Copyright (C) 2023-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 "tst-shstk-legacy-1a.c"
diff --git a/sysdeps/x86_64/tst-shstk-legacy-1d-static.c b/sysdeps/x86_64/tst-shstk-legacy-1d-static.c
new file mode 100644
index 0000000000..dca27a5482
--- /dev/null
+++ b/sysdeps/x86_64/tst-shstk-legacy-1d-static.c
@@ -0,0 +1 @@
+#include "tst-shstk-legacy-1d.c"
diff --git a/sysdeps/x86_64/tst-shstk-legacy-1d.c b/sysdeps/x86_64/tst-shstk-legacy-1d.c
new file mode 100644
index 0000000000..e9783b1c83
--- /dev/null
+++ b/sysdeps/x86_64/tst-shstk-legacy-1d.c
@@ -0,0 +1,47 @@
+/* Check that legacy shadow stack code in init_array won't trigger
+   segfault.
+   Copyright (C) 2023-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 <stdlib.h>
+#include <support/test-driver.h>
+
+/* Check that legacy shadow stack code in init_array won't trigger
+   segfault.  */
+extern void legacy (void);
+int done;
+
+void
+legacy_1 (void)
+{
+  legacy ();
+  done = 1;
+}
+
+void (*init_array []) (void)
+     __attribute__ ((section (".init_array"), aligned (sizeof (void *)))) =
+{
+  &legacy_1
+};
+
+static int
+do_test (void)
+{
+  return EXIT_SUCCESS;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/x86_64/tst-shstk-legacy-1e-static.c b/sysdeps/x86_64/tst-shstk-legacy-1e-static.c
new file mode 100644
index 0000000000..cb6ce0de00
--- /dev/null
+++ b/sysdeps/x86_64/tst-shstk-legacy-1e-static.c
@@ -0,0 +1 @@
+#include "tst-shstk-legacy-1e.c"
diff --git a/sysdeps/x86_64/tst-shstk-legacy-1e-static.sh b/sysdeps/x86_64/tst-shstk-legacy-1e-static.sh
new file mode 100755
index 0000000000..46f1233757
--- /dev/null
+++ b/sysdeps/x86_64/tst-shstk-legacy-1e-static.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+# Check that legacy shadow stack code in init_array will trigger
+# segfault.
+# Copyright (C) 2023-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/>.
+
+common_objpfx=$1; shift
+
+GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK \
+${common_objpfx}elf/tst-shstk-legacy-1e-static
+# The exit status should only be unsupported (77) or segfault (139).
+status=$?
+if test $status -eq 77; then
+  exit 77
+elif test $status == 139; then
+  exit 0
+else
+  exit 1
+fi
diff --git a/sysdeps/x86_64/tst-shstk-legacy-1e.c b/sysdeps/x86_64/tst-shstk-legacy-1e.c
new file mode 100644
index 0000000000..4c7706d398
--- /dev/null
+++ b/sysdeps/x86_64/tst-shstk-legacy-1e.c
@@ -0,0 +1,53 @@
+/* Check that legacy shadow stack code in init_array will trigger
+   segfault.
+   Copyright (C) 2023-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 <stdlib.h>
+#include <sys/platform/x86.h>
+#include <support/test-driver.h>
+#include <support/xsignal.h>
+
+/* Check that legacy shadow stack code in init_array will trigger
+   segfault.  */
+extern void legacy (void);
+int done;
+
+void
+legacy_1 (void)
+{
+  legacy ();
+  done = 1;
+}
+
+void (*init_array []) (void)
+     __attribute__ ((section (".init_array"), aligned (sizeof (void *)))) =
+{
+  &legacy_1
+};
+
+static int
+do_test (void)
+{
+  if (!CPU_FEATURE_ACTIVE (SHSTK))
+    return EXIT_UNSUPPORTED;
+
+  return EXIT_FAILURE;
+}
+
+#define EXPECTED_SIGNAL (CPU_FEATURE_ACTIVE (SHSTK) ? SIGSEGV : 0)
+#include <support/test-driver.c>
diff --git a/sysdeps/x86_64/tst-shstk-legacy-1e.sh b/sysdeps/x86_64/tst-shstk-legacy-1e.sh
new file mode 100755
index 0000000000..31212453d9
--- /dev/null
+++ b/sysdeps/x86_64/tst-shstk-legacy-1e.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+# Check that legacy shadow stack code in init_array will trigger
+# segfault.
+# Copyright (C) 2023-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/>.
+
+common_objpfx=$1; shift
+test_program_prefix=$1; shift
+
+GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK \
+${test_program_prefix} \
+  ${common_objpfx}elf/tst-shstk-legacy-1e
+# The exit status should only be unsupported (77) or segfault (139).
+status=$?
+if test $status -eq 77; then
+  exit 77
+elif test $status == 139; then
+  exit 0
+else
+  exit 1
+fi
diff --git a/sysdeps/x86_64/tst-shstk-legacy-1f.c b/sysdeps/x86_64/tst-shstk-legacy-1f.c
new file mode 100644
index 0000000000..098520db56
--- /dev/null
+++ b/sysdeps/x86_64/tst-shstk-legacy-1f.c
@@ -0,0 +1,29 @@
+/* Check that legacy shadow stack code in init_array won't trigger
+   segfault.
+   Copyright (C) 2023-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 <stdlib.h>
+#include <support/test-driver.h>
+
+static int
+do_test (void)
+{
+  return EXIT_SUCCESS;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/x86_64/tst-shstk-legacy-1g.c b/sysdeps/x86_64/tst-shstk-legacy-1g.c
new file mode 100644
index 0000000000..0faa052702
--- /dev/null
+++ b/sysdeps/x86_64/tst-shstk-legacy-1g.c
@@ -0,0 +1,35 @@
+/* Check that legacy shadow stack code in init_array will trigger
+   segfault.
+   Copyright (C) 2023-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 <stdlib.h>
+#include <sys/platform/x86.h>
+#include <support/test-driver.h>
+#include <support/xsignal.h>
+
+static int
+do_test (void)
+{
+  if (!CPU_FEATURE_ACTIVE (SHSTK))
+    return EXIT_UNSUPPORTED;
+
+  return EXIT_FAILURE;
+}
+
+#define EXPECTED_SIGNAL (CPU_FEATURE_ACTIVE (SHSTK) ? SIGSEGV : 0)
+#include <support/test-driver.c>
diff --git a/sysdeps/x86_64/tst-shstk-legacy-1g.sh b/sysdeps/x86_64/tst-shstk-legacy-1g.sh
new file mode 100755
index 0000000000..e84087068e
--- /dev/null
+++ b/sysdeps/x86_64/tst-shstk-legacy-1g.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+# Check that legacy shadow stack code in init_array will trigger
+# segfault.
+# Copyright (C) 2023-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/>.
+
+common_objpfx=$1; shift
+test_program_prefix=$1; shift
+
+GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK \
+${test_program_prefix} \
+  ${common_objpfx}elf/tst-shstk-legacy-1g
+# The exit status should only be unsupported (77) or segfault (139).
+status=$?
+if test $status -eq 77; then
+  exit 77
+elif test $status == 139; then
+  exit 0
+else
+  exit 1
+fi
diff --git a/sysdeps/x86_64/tst-shstk-legacy-mod-1.c b/sysdeps/x86_64/tst-shstk-legacy-mod-1.c
new file mode 100644
index 0000000000..c3e9055cd3
--- /dev/null
+++ b/sysdeps/x86_64/tst-shstk-legacy-mod-1.c
@@ -0,0 +1,28 @@
+/* Check legacy shadow stack code in init_array.
+   Copyright (C) 2023-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 <stdlib.h>
+
+/* Check legacy shadow stack code in init_array.  */
+extern void legacy (void) __attribute__ ((visibility ("hidden")));
+
+void (*init_array []) (void)
+     __attribute__ ((section (".init_array"), aligned (sizeof (void *)))) =
+{
+  &legacy
+};