@@ -486,6 +486,28 @@ assume that the CPU is @code{xxx} where xxx may have one of these values:
This tunable is specific to aarch64.
@end deftp
+@deftp Tunable glibc.cpu.riscv_cfi_lp
+The @code{glibc.cpu.riscv_cfi_lp=[on|off|permissive]} tunable allows the
+user to temporarily turn off the branch control flow protection (a.k.a.
+landing pad) or set to permissive mode. The default value is @code{on} for
+target compiled with Zicfilp extension. Permissive mode allows the protection
+to be turned off on program trying to dynamically load a legacy shared library
+without landing pad support.
+
+This tunable is specific to riscv.
+@end deftp
+
+@deftp Tunable glibc.cpu.riscv_cfi_ss
+The @code{glibc.cpu.riscv_cfi_ss=[on|off|permissive]} tunable allows the
+user to temporarily turn off the return control flow protection (a.k.a.
+shadow stack) or set to permissive mode. The default value is @code{on} for
+target compiled with Zicfiss extension. Permissive mode allows the protection
+to be turned off on program trying to dynamically load a legacy shared library
+without shadow stack support.
+
+This tunable is specific to riscv.
+@end deftp
+
@deftp Tunable glibc.cpu.x86_data_cache_size
The @code{glibc.cpu.x86_data_cache_size} tunable allows the user to set
data cache size in bytes for use in memory and string routines.
@@ -1,6 +1,7 @@
ifeq ($(subdir),misc)
sysdep_headers += sys/asm.h
endif
+sysdep-dl-routines += dl-get-cpu-features
ifeq ($(subdir),elf)
gen-as-const-headers += dl-link.sym features-offsets.sym
new file mode 100644
@@ -0,0 +1,46 @@
+/* Initialize CPU feature data.
+ This file is part of the GNU C Library.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _CPU_FEATURES_RISCV_H
+#define _CPU_FEATURES_RISCV_H
+
+# define TUNABLE_NAMESPACE cpu
+# include <cpu-tunables.c>
+
+# ifdef __riscv_landing_pad
+extern void TUNABLE_CALLBACK (set_riscv_cfi_lp) (tunable_val_t *)
+ attribute_hidden;
+# endif
+# ifdef __riscv_shadow_stack
+extern void TUNABLE_CALLBACK (set_riscv_cfi_ss) (tunable_val_t *)
+ attribute_hidden;
+# endif
+
+static inline void
+init_cpu_features (void)
+{
+# ifdef __riscv_landing_pad
+ TUNABLE_GET (riscv_cfi_lp, tunable_val_t *,
+ TUNABLE_CALLBACK (set_riscv_cfi_lp));
+# endif
+# ifdef __riscv_shadow_stack
+ TUNABLE_GET (riscv_cfi_ss, tunable_val_t *,
+ TUNABLE_CALLBACK (set_riscv_cfi_ss));
+# endif
+}
+#endif /* _CPU_FEATURES_RISCV_H */
new file mode 100644
@@ -0,0 +1,50 @@
+/* RISC-V CPU feature tuning.
+ This file is part of the GNU C Library.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#define TUNABLE_NAMESPACE cpu
+#include <elf/dl-tunables.h>
+#include <dl-tunables-parse.h>
+#include <ldsodefs.h>
+
+#ifdef __riscv_landing_pad
+attribute_hidden
+void
+TUNABLE_CALLBACK (set_riscv_cfi_lp) (tunable_val_t *valp)
+{
+ if (tunable_strcmp_cte (valp, "permissive"))
+ GL(dl_riscv_feature_control).lp = cfi_permissive;
+ else if (tunable_strcmp_cte (valp, "off"))
+ GL(dl_riscv_feature_control).lp = cfi_always_off;
+ else
+ GL(dl_riscv_feature_control).lp = cfi_always_on;
+}
+#endif
+
+#ifdef __riscv_shadow_stack
+attribute_hidden
+void
+TUNABLE_CALLBACK (set_riscv_cfi_ss) (tunable_val_t *valp)
+{
+ if (tunable_strcmp_cte (valp, "permissive"))
+ GL(dl_riscv_feature_control).ss = cfi_permissive;
+ else if (tunable_strcmp_cte (valp, "off"))
+ GL(dl_riscv_feature_control).ss = cfi_always_off;
+ else
+ GL(dl_riscv_feature_control).ss = cfi_always_on;
+}
+#endif
@@ -15,6 +15,7 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
+#include "feature-control.h"
#include <asm-generic/errno-base.h>
#include <unistd.h>
#include <libintl.h>
@@ -22,8 +23,39 @@
#include <dl-cfi.h>
#include <sys/mman.h>
+struct dl_cfi_info
+{
+ const char *program;
+
+ /* Check how lp and ss should be enabled. */
+#ifdef __riscv_landing_pad
+ enum dl_riscv_cfi_control enable_lp_type;
+#endif
+#ifdef __riscv_shadow_stack
+ enum dl_riscv_cfi_control enable_ss_type;
+#endif
+
+ /* Previously enabled features. */
+ unsigned int feature_1_enabled;
+
+ /* Features that should be enabled. */
+ unsigned int enable_feature_1;
+
+ /* If there are any legacy shared object. */
+ unsigned int feature_1_legacy;
+
+ /* Which shared object is the first legacy shared object. */
+#ifdef __riscv_landing_pad
+ unsigned int feature_1_legacy_lp;
+#endif
+#ifdef __riscv_shadow_stack
+ unsigned int feature_1_legacy_ss;
+#endif
+};
+
+
static void
-dl_check_legacy_object (struct link_map *m, unsigned int *feature_1)
+dl_check_legacy_object (struct link_map *m, struct dl_cfi_info *info)
{
/* Iterate through the dependencies and disable if needed here */
struct link_map *l = NULL;
@@ -42,32 +74,150 @@ dl_check_legacy_object (struct link_map *m, unsigned int *feature_1)
/* Skip check for ld.so since it has the features enabled. The
features will be disabled later if they are not enabled in
executable. */
- if (l == &GL(dl_rtld_map)
- || l->l_real == &GL(dl_rtld_map))
+ if (is_rtld_link_map (l)
+ || is_rtld_link_map (l->l_real)
+ || (info->program != NULL && l == m))
continue;
#endif /* SHARED */
- *feature_1 &= l->l_riscv_feature_1_and;
+ info->enable_feature_1 &= ((l->l_riscv_feature_1_and
+ & (GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED
+ | GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS))
+ | ~(GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED
+ | GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS));
+
+ /* Bookkeeping legacy objects */
+#ifdef __riscv_landing_pad
+ if ((info->feature_1_legacy & GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED) == 0
+ && ((info->enable_feature_1 & GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED)
+ != (info->feature_1_enabled & GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED))
+ )
+ {
+ info->feature_1_legacy_lp = i;
+ info->feature_1_legacy |= GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED;
+ }
+#endif
+#ifdef __riscv_shadow_stack
+ if ((info->feature_1_legacy & GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS) == 0
+ && ((info->enable_feature_1 & GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS)
+ != (info->feature_1_enabled & GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS))
+ )
+ {
+ info->feature_1_legacy_ss = i;
+ info->feature_1_legacy |= GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS;
+ }
+#endif
}
+
+ /* Keep bits set if cfi_always_on */
+#ifdef __riscv_landing_pad
+ if ((info->feature_1_enabled & GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED) != 0
+ && info->enable_lp_type == cfi_always_on)
+ {
+ info->enable_feature_1 |= GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED;
+ }
+#endif
+#ifdef __riscv_shadow_stack
+ if ((info->feature_1_enabled & GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS) != 0
+ && info->enable_ss_type == cfi_always_on)
+ {
+ info->enable_feature_1 |= GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS;
+ }
+#endif
}
#ifdef SHARED
static void
-dl_cfi_check_startup (struct link_map *m, unsigned int *feature_1)
+dl_cfi_check_startup (struct link_map *m, struct dl_cfi_info *info)
{
- /* FIXME: Add tunables here */
- if (!*feature_1)
- return;
- dl_check_legacy_object (m, feature_1);
+# ifdef __riscv_landing_pad
+ if (info->enable_lp_type == cfi_always_on)
+ info->enable_feature_1 |= GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED;
+ else if (info->enable_lp_type == cfi_always_off)
+ info->enable_feature_1 &= ~GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED;
+ else
+ info->enable_feature_1 &= ((m->l_riscv_feature_1_and
+ & GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED)
+ | ~GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED);
+# endif
+# ifdef __riscv_shadow_stack
+ if (info->enable_ss_type == cfi_always_on)
+ info->enable_feature_1 |= GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS;
+ else if (info->enable_ss_type == cfi_always_off)
+ info->enable_feature_1 &= ~GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS;
+ else
+ info->enable_feature_1 &= ((m->l_riscv_feature_1_and
+ & GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS)
+ | ~GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS);
+# endif
+
+ if (info->enable_feature_1 != 0)
+ dl_check_legacy_object (m, info);
/* Update GL(dl_riscv_feature_1) */
- GL(dl_riscv_feature_1) = *feature_1;
+ if (info->enable_feature_1 ^ info->feature_1_enabled) {
+ info->feature_1_enabled = info->enable_feature_1;
+ GL(dl_riscv_feature_1) = info->enable_feature_1;
+ }
}
#endif /* SHARED */
static void
-dl_cfi_check_dlopen (struct link_map *m)
+dl_cfi_check_dlopen (struct link_map *m, struct dl_cfi_info *info)
{
+ if (info->enable_feature_1 != 0) {
+ dl_check_legacy_object(m, info);
+
+ if (info->feature_1_legacy == 0)
+ return;
+ }
+
+ unsigned int disable_feature_1 = 0;
+ unsigned int legacy_obj = 0;
+ const char *msg = NULL;
+
+#ifdef __riscv_landing_pad
+ if ((info->feature_1_enabled & GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED) != 0
+ && (info->feature_1_legacy & GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED) != 0)
+ {
+ if (info->enable_lp_type != cfi_permissive || !SINGLE_THREAD_P)
+ {
+ legacy_obj = info->feature_1_legacy_lp;
+ msg = N_("rebuild shared object with landing pad support");
+ }
+ else
+ disable_feature_1 |= GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED;
+ }
+#endif
+
+#ifdef __riscv_shadow_stack
+ if ((info->feature_1_enabled & GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS) != 0
+ && (info->feature_1_legacy & GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS) != 0)
+ {
+ if (info->enable_ss_type != cfi_permissive || !SINGLE_THREAD_P)
+ {
+ legacy_obj = info->feature_1_legacy_ss;
+ msg = N_("rebuild shared object with shadow stack support");
+ }
+ else
+ disable_feature_1 |= GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS;
+ }
+#endif
+
+ if (msg != NULL)
+ _dl_signal_error (0, m->l_initfini[legacy_obj]->l_name, "dlopen", msg);
+
+ if (disable_feature_1 != 0)
+ // FIXME: Disable CFI here
+ int res = -1;
+ if (res)
+ {
+ msg = N_("can't disable CFI feature");
+ _dl_signal_error (-res, m->l_initfini[legacy_obj]->l_name,
+ "dlopen", msg);
+ }
+ GL(dl_riscv_feature_1) &= ~disable_feature_1;
+ }
}
attribute_hidden void
@@ -89,20 +239,61 @@ _dl_cfi_check (struct link_map *l, const char *program)
{
/* As this point we have parsed the gnu properties,
for dynamic binary we should verify the dependencies here. */
- /* FIXME: Implement different policy for supporting legacy binaries */
- unsigned int feature_1;
+ struct dl_cfi_info info;
#if defined SHARED && defined RTLD_START_ENABLE_RISCV_CFI
if (program)
{
GL(dl_riscv_feature_1) = l->l_riscv_feature_1_and;
- feature_1 = l->l_riscv_feature_1_and;
}
#endif /* SHARED */
+ unsigned int supported_exts = 0;
+ unsigned int always_on_exts = 0;
+
+#ifdef __riscv_landing_pad
+ info.enable_lp_type = GL(dl_riscv_feature_control).lp;
+ supported_exts += 1;
+ always_on_exts += (info.enable_lp_type == cfi_always_on);
+#endif
+#ifdef __riscv_shadow_stack
+ info.enable_ss_type = GL(dl_riscv_feature_control).ss;
+ supported_exts += 1;
+ always_on_exts += (info.enable_ss_type == cfi_always_on);
+#endif
+
+ info.feature_1_enabled = GL(dl_riscv_feature_1);
+
+ /* No legacy check needed if all cfi exts are always on in main */
+ if (program && (supported_exts == always_on_exts))
+ return;
+
+ /* No legacy check needed if all cfi exts are off */
+ if (info.feature_1_enabled == 0)
+ return;
+
+ info.program = program;
+
+ info.enable_feature_1 = 0;
+#ifdef __riscv_landing_pad
+ if (info.enable_lp_type != cfi_always_off)
+ info.enable_feature_1 |= (info.feature_1_enabled
+ & GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED);
+ info.feature_1_legacy_lp = 0;
+#endif
+#ifdef __riscv_shadow_stack
+ if (info.enable_ss_type != cfi_always_off)
+ info.enable_feature_1 |= (info.feature_1_enabled
+ & GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS);
+ info.feature_1_legacy_ss = 0;
+#endif
+
+ info.feature_1_enabled = GL(dl_riscv_feature_1);
+ info.feature_1_legacy = 0;
+
#ifdef SHARED
if (program)
- dl_cfi_check_startup (l, &feature_1);
+ dl_cfi_check_startup (l, &info);
else
#endif /* SHARED */
- dl_cfi_check_dlopen (l);
+ dl_cfi_check_dlopen (l, &info);
}
new file mode 100644
@@ -0,0 +1,27 @@
+/* Initialize CPU feature data.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <ldsodefs.h>
+
+#ifdef SHARED
+# include <cpu-features.c>
+void
+_dl_riscv_init_cpu_features (void)
+{
+ init_cpu_features ();
+}
+#endif
@@ -41,6 +41,7 @@ extern void _dl_cfi_setup_features (unsigned int features);
#else
# define SET_LPAD
#endif
+extern void _dl_riscv_init_cpu_features (void);
#ifndef _RTLD_PROLOGUE
# define _RTLD_PROLOGUE(entry) \
@@ -153,6 +154,24 @@ elf_machine_dynamic (void)
#define ARCH_LA_PLTENTER riscv_gnu_pltenter
#define ARCH_LA_PLTEXIT riscv_gnu_pltexit
+/* We define an initialization function. This is called very early in
+ _dl_sysdep_start. */
+#define DL_PLATFORM_INIT dl_platform_init ()
+
+static inline void __attribute__ ((unused))
+dl_platform_init (void)
+{
+ if (GLRO(dl_platform) != NULL && *GLRO(dl_platform) == '\0')
+ /* Avoid an empty string which would disturb us. */
+ GLRO(dl_platform) = NULL;
+
+#ifdef SHARED
+ /* init_cpu_features which has been called early from __libc_start_main in
+ static executable. */
+ _dl_riscv_init_cpu_features ();
+#endif
+}
+
/* Bias .got.plt entry by the offset requested by the PLT header. */
#define elf_machine_plt_value(map, reloc, value) (value)
@@ -57,4 +57,21 @@ PROCINFO_CLASS unsigned int _dl_riscv_feature_1
# else
,
# endif
+
+# if !defined PROCINFO_DECL && defined SHARED
+ ._dl_riscv_feature_control
+# else
+PROCINFO_CLASS struct dl_riscv_feature_control _dl_riscv_feature_control
+# endif
+# ifndef PROCINFO_DECL
+= {
+ .lp = cfi_always_on,
+ .ss = cfi_always_on,
+ }
+# endif
+# if !defined SHARED || defined PROCINFO_DECL
+;
+# else
+,
+# endif
#endif
new file mode 100644
@@ -0,0 +1,27 @@
+# RISC-V specific tunables.
+# Copyright (C) 2026 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/>.
+
+glibc {
+ cpu {
+ riscv_cfi_lp {
+ type: STRING
+ }
+ riscv_cfi_ss {
+ type: STRING
+ }
+}
new file mode 100644
@@ -0,0 +1,42 @@
+/* RISC-V feature tuning.
+ This file is part of the GNU C Library.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _RISCV_FEATURE_CONTROL_H
+#define _RISCV_FEATURE_CONTROL_H
+
+/* For each CFI feature, LP and SS, valid control values. */
+enum dl_riscv_cfi_control
+{
+ /* Enable CFI features based on ELF property note. */
+ cfi_elf_property = 0,
+ /* Always enable CFI features. */
+ cfi_always_on,
+ /* Always disable CFI features. */
+ cfi_always_off,
+ /* Enable CFI features permissively. */
+ cfi_permissive
+};
+
+struct dl_riscv_feature_control
+{
+ enum dl_riscv_cfi_control lp : 2;
+ enum dl_riscv_cfi_control ss : 2;
+};
+
+#endif /* feature-control.h */
+
@@ -20,6 +20,7 @@
#define _RISCV_LDSODEFS_H 1
#include <elf.h>
+#include <feature-control.h>
struct La_riscv_regs;
struct La_riscv_retval;
new file mode 100644
@@ -0,0 +1,31 @@
+/* Copyright (C) 2026 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 SHARED
+
+/* Mark symbols hidden in static PIE for early self relocation to work. */
+# if BUILD_PIE_DEFAULT
+# pragma GCC visibility push(hidden)
+# endif
+# include <ldsodefs.h>
+# include <cpu-features.c>
+
+# define ARCH_INIT_CPU_FEATURES() init_cpu_features ()
+
+#endif /* !SHARED */
+#include <csu/libc-start.c>
+
@@ -31,6 +31,15 @@ get_cfi_feature (void)
{
unsigned int cfi_feature = 0;
/* FIXME: check if cfi feature is supported by CPU */
+
+#ifdef __riscv_landing_pad
+ if (GL(dl_riscv_feature_control).lp != cfi_always_off)
+ cfi_feature |= GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED;
+#endif
+#ifdef __riscv_shadow_stack
+ if (GL(dl_riscv_feature_control).ss != cfi_always_off)
+ cfi_feature |= GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS;
+#endif
struct link_map *main_map = _dl_get_dl_main_map ();
/* Scan program headers backward to check PT_GNU_PROPERTY early for
@@ -43,9 +52,7 @@ get_cfi_feature (void)
_dl_process_pt_gnu_property (main_map, -1, &ph[-1]);
/* Enable landing pad and shstk only if they are enabled on a static
executable. */
- /* FIXME: change to &= to mask off other features after cpu_feature
- is implemented */
- cfi_feature = (main_map->l_riscv_feature_1_and
+ cfi_feature &= (main_map->l_riscv_feature_1_and
& (GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED
| GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS));