[RFC 3/5] configure: Add --enable-sframe option
claudiu.zissulescu-ianculescu@oracle.com
claudiu.zissulescu-ianculescu@oracle.com
Tue Mar 18 13:03:31 GMT 2025
From: Claudiu Zissulescu <claudiu.zissulescu-ianculescu@oracle.com>
Enable SFrame stack track information. The --enable-sframe option
allows the glibc build to compile with SFrame stack track
information. Thus, enabling glibc's backtrace to work within glibc.
Signed-off-by: Claudiu Zissulescu <claudiu.zissulescu-ianculescu@oracle.com>
---
Makeconfig | 8 +++-
config.make.in | 1 +
configure | 128 +++++++++++++++++++++++++++++++++++++++++++++++++
configure.ac | 43 +++++++++++++++++
4 files changed, 179 insertions(+), 1 deletion(-)
diff --git a/Makeconfig b/Makeconfig
index a87ff7b1d3..7d360f7daf 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -1011,6 +1011,12 @@ else
+cflags += $(no-fortify-source)
endif
+# Enable SFrame while compiling for stack backtracing.
+ifeq ($(enable-gsframe),yes)
+as-sframe = -Wa,--gsframe
+endif
++cflags += $(as-sframe)
+
# Each sysdeps directory can contain header files that both will be
# used to compile and will be installed. Each can also contain an
# include/ subdirectory, whose header files will be used to compile
@@ -1158,7 +1164,7 @@ endif
ifndef ASFLAGS
ASFLAGS := $(filter -g% -fdebug-prefix-map=%,$(CFLAGS))
endif
-override ASFLAGS += -Werror=undef $(ASFLAGS-config) $(asflags-cpu)
+override ASFLAGS += -Werror=undef $(ASFLAGS-config) $(asflags-cpu) $(as-sframe)
ifndef BUILD_CC
BUILD_CC = $(CC)
diff --git a/config.make.in b/config.make.in
index 36096881b7..db2367f007 100644
--- a/config.make.in
+++ b/config.make.in
@@ -51,6 +51,7 @@ c++-cstdlib-header = @CXX_CSTDLIB_HEADER@
c++-cmath-header = @CXX_CMATH_HEADER@
c++-bits-std_abs-h = @CXX_BITS_STD_ABS_H@
enable-werror = @enable_werror@
+enable-gsframe = @enable_gsframe@
have-z-execstack = @libc_cv_z_execstack@
have-protected-data = @libc_cv_protected_data@
diff --git a/configure b/configure
index ec0b62db36..7908121794 100755
--- a/configure
+++ b/configure
@@ -620,6 +620,8 @@ DEFINES
static_nss
profile
libc_cv_multidir
+enable_gsframe
+READELF_SFRAME
shared
static
ldd_rewrite_script
@@ -808,6 +810,7 @@ enable_mathvec
enable_cet
enable_scv
enable_fortify_source
+enable_sframe
with_cpu
'
ac_precious_vars='build_alias
@@ -1491,6 +1494,8 @@ Optional Features:
Use -D_FORTIFY_SOURCE=[1|2|3] to control code
hardening, defaults to highest possible value
supported by the build compiler.
+ --enable-sframe Enable SFrame stack trace information [default
+ depends on toolchain]
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@@ -4855,6 +4860,16 @@ case "$enable_fortify_source" in
*) as_fn_error $? "Not a valid argument for --enable-fortify-source: \"$enable_fortify_source\"" "$LINENO" 5;;
esac
+# Check whether --enable-sframe was given.
+if test ${enable_sframe+y}
+then :
+ enableval=$enable_sframe; use_sframe=$enableval
+else case e in #(
+ e) use_sframe=notset ;;
+esac
+fi
+
+
# We keep the original values in `$config_*' and never modify them, so we
# can write them unchanged into config.make. Everything else uses
# $machine, $vendor, and $os, and changes them whenever convenient.
@@ -8110,6 +8125,119 @@ fi
config_vars="$config_vars
enable-static-pie = $libc_cv_static_pie"
+# Glibc stacktracer supports SFrame v2 or newer
+libc_cv_readelf_version_ok=yes
+for ac_prog in $READELF
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_READELF_SFRAME+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) if test -n "$READELF_SFRAME"; then
+ ac_cv_prog_READELF_SFRAME="$READELF_SFRAME" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ case $as_dir in #(((
+ '') as_dir=./ ;;
+ */) ;;
+ *) as_dir=$as_dir/ ;;
+ esac
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+ ac_cv_prog_READELF_SFRAME="$ac_prog"
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi ;;
+esac
+fi
+READELF_SFRAME=$ac_cv_prog_READELF_SFRAME
+if test -n "$READELF_SFRAME"; then
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $READELF_SFRAME" >&5
+printf "%s\n" "$READELF_SFRAME" >&6; }
+else
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+ test -n "$READELF_SFRAME" && break
+done
+
+if test -z "$READELF_SFRAME"; then
+ ac_verc_fail=yes
+else
+ # Found it, now check the version.
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking version of $READELF_SFRAME" >&5
+printf %s "checking version of $READELF_SFRAME... " >&6; }
+ ac_prog_version=`$READELF_SFRAME --version 2>&1 | sed -n 's/^.*GNU readelf.* \([0-9][0-9]*\.[0-9.]*\).*$/\1/p'`
+ case $ac_prog_version in
+ '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
+ 2.4[1-9]*|2.[5-9][0-9]*|[3-9].*|[1-9][0-9]*)
+ ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;;
+ *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;;
+
+ esac
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_prog_version" >&5
+printf "%s\n" "$ac_prog_version" >&6; }
+fi
+if test $ac_verc_fail = yes; then
+ libc_cv_readelf_version_ok=no
+fi
+
+
+# Check the current toolchain for SFrame support
+if test $libc_cv_readelf_version_ok = yes; then
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for SFrame support" >&5
+printf %s "checking for SFrame support... " >&6; }
+if test ${libc_cv_default_sframe+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) cat > conftest.c <<EOF
+int test_function(void)
+{
+ return 42;
+}
+EOF
+ libc_cv_default_sframe=no
+ if ${CC} -c conftest.c -o conftest.o -Wa,--gsframe >/dev/null 2>&1 && \
+ # Check if .sframe section is present and if version > 1
+ $READELF --sframe conftest.o | grep "SFRAME_VER" | grep -qv "VERSION_1"; then
+ libc_cv_default_sframe=yes
+ fi
+ rm -f conftest.c conftest.o
+ ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_default_sframe" >&5
+printf "%s\n" "$libc_cv_default_sframe" >&6; }
+fi
+
+# Prevent enabling sframe on non-supporting toolchains
+enable_gsframe=no
+if test $use_sframe$libc_cv_default_sframe = yesyes || \
+ test $use_sframe$libc_cv_default_sframe = notsetyes; then
+ enable_gsframe=yes
+elif test $use_sframe = yes; then
+ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}
+as_fn_error $? "toolchain doesn't support SFrame V2 or higher
+See 'config.log' for more details" "$LINENO" 5; }
+fi
+
+
# Set the `multidir' variable by grabbing the variable from the compiler.
# We do it once and save the result in a generated makefile.
libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory`
diff --git a/configure.ac b/configure.ac
index 7c9b57789e..2d8c1be411 100644
--- a/configure.ac
+++ b/configure.ac
@@ -426,6 +426,12 @@ case "$enable_fortify_source" in
*) AC_MSG_ERROR([Not a valid argument for --enable-fortify-source: "$enable_fortify_source"]);;
esac
+AC_ARG_ENABLE([sframe],
+ [AS_HELP_STRING([--enable-sframe],
+ [Enable SFrame stack trace information @<:@default depends on toolchain@:>@])],
+ [use_sframe=$enableval],
+ [use_sframe=notset])
+
# We keep the original values in `$config_*' and never modify them, so we
# can write them unchanged into config.make. Everything else uses
# $machine, $vendor, and $os, and changes them whenever convenient.
@@ -1776,6 +1782,43 @@ if test "$libc_cv_static_pie" = "yes"; then
fi
LIBC_CONFIG_VAR([enable-static-pie], [$libc_cv_static_pie])
+# Glibc stacktracer supports SFrame v2 or newer
+libc_cv_readelf_version_ok=yes
+AC_CHECK_PROG_VER(READELF_SFRAME, $READELF, --version,
+ [GNU readelf.* \([0-9][0-9]*\.[0-9.]*\)],
+ [2.4[1-9]*|2.[5-9][0-9]*|[3-9].*|[1-9][0-9]*],
+ libc_cv_readelf_version_ok=no)
+
+# Check the current toolchain for SFrame support
+if test $libc_cv_readelf_version_ok = yes; then
+ AC_CACHE_CHECK([for SFrame support], libc_cv_default_sframe,
+ [dnl
+cat > conftest.c <<EOF
+int test_function(void)
+{
+ return 42;
+}
+EOF
+ libc_cv_default_sframe=no
+ if ${CC} -c conftest.c -o conftest.o -Wa,--gsframe >/dev/null 2>&1 && \
+ # Check if .sframe section is present and if version > 1
+ $READELF --sframe conftest.o | grep "SFRAME_VER" | grep -qv "VERSION_1"; then
+ libc_cv_default_sframe=yes
+ fi
+ rm -f conftest.c conftest.o
+ ])
+fi
+
+# Prevent enabling sframe on non-supporting toolchains
+enable_gsframe=no
+if test $use_sframe$libc_cv_default_sframe = yesyes || \
+ test $use_sframe$libc_cv_default_sframe = notsetyes; then
+ enable_gsframe=yes
+elif test $use_sframe = yes; then
+ AC_MSG_FAILURE([toolchain doesn't support SFrame V2 or higher])
+fi
+AC_SUBST(enable_gsframe)
+
# Set the `multidir' variable by grabbing the variable from the compiler.
# We do it once and save the result in a generated makefile.
libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory`
--
2.48.1
More information about the Libc-alpha
mailing list