From: Abhay Kandpal via Valgrind-developers Date: Thu, 18 Jun 2026 18:08:26 +0000 (-0500) Subject: tests/check_ppc64_auxv_cap: replace LD_SHOW_AUXV-grep shell script with C program... X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e9bc25843afb7dd2a332d3a7cb5eba7ed82532f2;p=thirdparty%2Fvalgrind.git tests/check_ppc64_auxv_cap: replace LD_SHOW_AUXV-grep shell script with C program using getauxval() glibc 2.42 removed sysdeps/powerpc/dl-procinfo.h, which contained the PowerPC-specific _dl_procinfo() hook that printed human-readable capability strings in LD_SHOW_AUXV output. After the change, LD_SHOW_AUXV emits raw hex for AT_HWCAP / AT_HWCAP2 instead of capability names like 'altivec' or 'vsx'. tests/check_ppc64_auxv_cap was a shell script that grep'd LD_SHOW_AUXV output for capability words, used as a .vgtest 'prereq:' across many PowerPC tests under none/tests/ppc{32,64}/ and memcheck/tests/ppc{32,64}/. On glibc 2.42 it always returns non-zero, so vg_regtest.in silently skips every test that depends on it (rc 256, "skipping, prereq failed"). Effectively the entire PowerPC instruction-level regression suite was disabled. Replace the shell script with a small C program using getauxval(), which reads AT_HWCAP / AT_HWCAP2 directly and is unaffected by the glibc change. Calling convention and exit codes match the original script exactly, so none of the .vgtest files need modification: check_ppc64_auxv_cap exit 0 - capability is present exit 1 - capability is absent, unknown, or usage error tests/Makefile.am: move check_ppc64_auxv_cap from dist_noinst_SCRIPTS to check_PROGRAMS so automake builds the binary from the C source. For portability, configure.ac is extended with AC_CHECK_FUNCS([getauxval]) to detect whether the platform provides getauxval(). On glibc Linux it is always present (since 2.16, 2012). On other platforms (FreeBSD, Solaris, macOS) the function may be absent; on those, the program is compiled with a stub main() that returns 1 for every query. None of those platforms currently use Valgrind's PowerPC port, but the build must still succeed there. Signed-off-by: Abhay Kandpal --- diff --git a/configure.ac b/configure.ac index f8e7fb89f9..0737441441 100644 --- a/configure.ac +++ b/configure.ac @@ -5372,7 +5372,8 @@ AC_CHECK_FUNCS([ \ timer_delete \ fchroot \ setcred \ - exterrctl + exterrctl \ + getauxval ]) if test "$VGCONF_OS" = "solaris" ; then diff --git a/tests/Makefile.am b/tests/Makefile.am index efe3546ac7..7063bd82fb 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -24,7 +24,6 @@ min_power_isa_FLAGS = $(ISA_2_05_FLAG) $(ISA_2_06_FLAG) $(ISA_2_07_FLAG) dist_noinst_SCRIPTS = \ check_headers_and_includes \ check_makefile_consistency \ - check_ppc64_auxv_cap \ filter_addresses \ filter_libc \ filter_numbers \ @@ -52,6 +51,7 @@ check_PROGRAMS = \ x86_amd64_features \ s390x_features \ mips_features \ + check_ppc64_auxv_cap \ power_insn_available \ is_ppc64_BE \ min_power_isa \ diff --git a/tests/check_ppc64_auxv_cap b/tests/check_ppc64_auxv_cap deleted file mode 100755 index caceef53d3..0000000000 --- a/tests/check_ppc64_auxv_cap +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/sh - -# Check if the passed in (CAPABILITY_WORD) matches a value found in the -# current hwcap aux vector. - -# return '0' to indicate the capability was found. -# return '1' for not found, or any other error condition. - -CAPABILITY_WORD=$1 - -# SANITY CHECK Begin: -# These are potential hwcap values as found in the glibc dl-procinfo.c -# sources as of July 2015. -P_HWCAP_1=" vsx arch_2_06 power6x dfp pa6t arch_2_05 ic_snoop smt booke" -P_HWCAP_2=" cellbe power5+ power5 power4 notb efpdouble efpsingle spe" -P_HWCAP_3=" ucache 4xxmac mmu fpu altivec ppc601 ppc64 ppc32 " -P_HWCAP2_1=" tar isel ebb dscr htm arch_2_07 arch_3_00 " -# Additional entries as of ... future -P_HWCAP2_2=" arch_3_1 mma " -CAPABILITY_FOUND="no" -for POTENTIAL_CAP in $P_HWCAP_1 $P_HWCAP_2 $P_HWCAP_3 $P_HWCAP2_1 $P_HWCAP2_2 ; do - if [ "x$CAPABILITY_WORD" = "x$POTENTIAL_CAP" ]; then - CAPABILITY_FOUND="yes" - break - fi -done -if [ x$CAPABILITY_FOUND = "xno" ]; then - echo "Warning: did not find $CAPABILITY_WORD in the potential capabilities list." - echo " LD_SHOW_AUXV=1 /bin/true | grep ^AT_HWCAP " - echo " Double-check that the input value [$CAPABILITY_WORD] is valid." -fi -# SANITY CHECK End - -# Capability Check Begin: -LD_SHOW_AUXV=1 /bin/true | grep ^AT_HWCAP | grep -w $CAPABILITY_WORD 2>&1 > /dev/null -if [ "$?" -eq "0" ]; then - #echo "found the capability" - exit 0 -elif [ "$?" -eq "2" ]; then - # echo "grep failure" - exit 1 -else - #echo "did not find the capability" - exit 1 -fi - diff --git a/tests/check_ppc64_auxv_cap.c b/tests/check_ppc64_auxv_cap.c new file mode 100644 index 0000000000..43e5657098 --- /dev/null +++ b/tests/check_ppc64_auxv_cap.c @@ -0,0 +1,136 @@ +/* --------------------------------------------------------------------- + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (C) 2026 Abhay Kandpal + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 3 of the + License, or (at your option) any later version. + + This program 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . + + The GNU General Public License is contained in the file COPYING. + ------------------------------------------------------------------ */ + +/* check_ppc64_auxv_cap.c + + Replacement for the historical 'tests/check_ppc64_auxv_cap' shell + script. Used as a .vgtest 'prereq:' helper by ~51 tests under + none/tests/ppc{32,64}/ and memcheck/tests/ppc{32,64}/ to decide, + at test-run time, whether the host machine supports a given + PowerPC capability (altivec, vsx, dfp, arch_2_05, arch_2_06, + arch_2_07, arch_3_00, arch_3_1, htm, mma). + + The original shell script parsed the textual output of + LD_SHOW_AUXV=1 /bin/true | grep ^AT_HWCAP + for human-readable capability words such as 'altivec'. glibc 2.42 + removed the PowerPC-specific _dl_procinfo() hook (formerly in + sysdeps/powerpc/dl-procinfo.h, commits 6cb703b / 1d60b9d), so + LD_SHOW_AUXV now prints raw hex for AT_HWCAP / AT_HWCAP2 and the + 'grep -w altivec' pattern in the script never matches. The + resulting non-zero exit caused vg_regtest.in to skip every test + that depends on this prereq, silently disabling essentially the + whole PowerPC instruction-level regression suite. + + This C version uses getauxval() to read AT_HWCAP / AT_HWCAP2 + directly. That is the documented, stable interface to the auxv, + and it is unaffected by the glibc change. + + Calling convention (preserved from the old script so the existing + .vgtest files need no modification): + check_ppc64_auxv_cap + exit code 0 - capability is present + exit code 1 - capability is absent, unknown, or usage error +*/ + +#include "config.h" +#include +#include + +#ifdef HAVE_GETAUXVAL + +#include + +/* Capability bit table. Values are taken from + /usr/include/bits/hwcap.h on a glibc-2.41-or-earlier system, and + cross-checked against arch/powerpc/include/uapi/asm/cputable.h in + the Linux kernel. AT_HWCAP / AT_HWCAP2 bit assignments are part of + the kernel ABI and are stable, so it is safe to hardcode them here + rather than depend on the PowerPC-specific bits/hwcap.h header + being installed at build time. */ + +typedef + struct { + const char* name; + unsigned long type; /* AT_HWCAP or AT_HWCAP2 */ + unsigned long bit; + } + CapEntry; + +static const CapEntry cap_table[] = { + /* AT_HWCAP */ + { "altivec", AT_HWCAP, 0x10000000UL }, + { "vsx", AT_HWCAP, 0x00000080UL }, + { "dfp", AT_HWCAP, 0x00000400UL }, + { "arch_2_05", AT_HWCAP, 0x00001000UL }, + { "arch_2_06", AT_HWCAP, 0x00000100UL }, + /* AT_HWCAP2 */ + { "arch_2_07", AT_HWCAP2, 0x80000000UL }, + { "arch_3_00", AT_HWCAP2, 0x00800000UL }, + { "arch_3_1", AT_HWCAP2, 0x00040000UL }, + { "htm", AT_HWCAP2, 0x40000000UL }, + { "mma", AT_HWCAP2, 0x00020000UL }, +}; + +#define N_CAP_TABLE (sizeof cap_table / sizeof cap_table[0]) + +int main(int argc, char** argv) +{ + unsigned int i; + unsigned long hwcap; + const char* progname + = (argc > 0 && argv[0] != NULL) ? argv[0] : "check_ppc64_auxv_cap"; + + if (argc != 2) { + fprintf(stderr, "usage: %s \n", progname); + return 1; + } + + for (i = 0; i < N_CAP_TABLE; i++) { + if (strcmp(argv[1], cap_table[i].name) == 0) { + hwcap = getauxval(cap_table[i].type); + return (hwcap & cap_table[i].bit) ? 0 : 1; + } + } + + /* Unknown capability name. Report 'not found', matching the + behaviour of the original grep-based script when the requested + capability word did not appear in the LD_SHOW_AUXV output. */ + fprintf(stderr, "%s: unknown capability '%s'\n", progname, argv[1]); + return 1; +} + +#else /* !HAVE_GETAUXVAL */ + +/* getauxval() is not available on this platform (e.g. FreeBSD, Solaris, + macOS). None of those platforms currently use Valgrind's PowerPC + port, but the program must still build and link there. Return 1 for + every query - equivalent to "capability not detected" - which causes + the .vgtest harness to skip any test using this as a prereq. */ + +int main(int argc, char** argv) +{ + (void)argc; + (void)argv; + return 1; +} + +#endif /* HAVE_GETAUXVAL */