Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 0 additions & 25 deletions .github/actions/build-capstone/action.yml

This file was deleted.

4 changes: 0 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,13 @@ jobs:
build-essential \
automake \
autoconf \
cmake \
libc6-dev \
gdb \
docbook \
docbook-xsl \
docbook-xml \
xsltproc

- name: Build Capstone (cycle-estimation decoder)
uses: ./.github/actions/build-capstone

- name: Run autogen
run: ./autogen.sh

Expand Down
5 changes: 0 additions & 5 deletions .github/workflows/codspeed.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,17 +72,12 @@ jobs:
build-essential \
automake \
autoconf \
cmake \
gdb \
docbook \
docbook-xsl \
docbook-xml \
xsltproc

- name: Build Capstone (cycle-estimation decoder)
if: steps.valgrind-cache.outputs.cache-hit != 'true' && matrix.valgrind == 'local'
uses: ./.github/actions/build-capstone

- name: Build Valgrind (${{ matrix.valgrind }})
if: steps.valgrind-cache.outputs.cache-hit != 'true'
run: just build ${{ matrix.valgrind }}
Expand Down
8 changes: 2 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,16 @@ jobs:
- name: Install packaging deps
run: sudo apt-get install -y build-essential devscripts debhelper dh-make
- name: Install build deps
run: sudo apt-get install -y debhelper-compat gdb mpi-default-dev pkgconf cmake docbook docbook-xsl docbook-xml xsltproc
run: sudo apt-get install -y debhelper-compat gdb mpi-default-dev pkgconf docbook docbook-xsl docbook-xml xsltproc
- name: Configure GPG Key
run: echo -n "$GPG_SIGNING_KEY" | base64 --decode | gpg --import
env:
GPG_SIGNING_KEY: ${{ secrets.GPG_SIGNING_KEY }}

# debian/rules forwards $CAPSTONE_DIR to configure via --with-capstone.
- name: Build Capstone (cycle-estimation decoder)
uses: ./.github/actions/build-capstone

- name: Build the deb package
id: build_deb
run: |
debuild -e CAPSTONE_DIR --no-tgz-check -nc
debuild --no-tgz-check -nc
echo "asset-path=$(find .. -name 'valgrind_*.deb')" >> "$GITHUB_OUTPUT"
env:
DEBEMAIL: ${{ vars.MAINTAINER_EMAIL }}
Expand Down
9 changes: 8 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2566,7 +2566,14 @@ test-suite.log
# autoconf backup
/configure~

# Capstone build install prefix (built from the third_party/capstone submodule)
# /third_party/ (vendored Capstone, built by third_party/Makefile.am)
/third_party/Makefile
/third_party/Makefile.in
/third_party/libcapstone.a
/third_party/capstone-stubs/.deps
/third_party/capstone-stubs/.dirstamp

# install prefix of a Capstone built by hand for --with-capstone
/.capstone

# fake CodSpeed benchmark fixture binary (compiled from testdata/llsc_tzconvert_bench.c)
Expand Down
1 change: 1 addition & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ EXP_TOOLS = \
# Put docs last because building the HTML is slow and we want to get
# everything else working before we try it.
SUBDIRS = \
third_party \
include \
VEX \
coregrind \
Expand Down
10 changes: 10 additions & 0 deletions autogen.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ run autoconf
if git rev-parse --is-inside-work-tree > /dev/null 2>&1 ; then
echo "running: git configuration"
git config blame.ignoreRevsFile .git-blame-ignore-revs
# CodSpeed: the vendored Capstone decoder that Callgrind's cycle estimation
# links against. A clone without --recurse-submodules leaves it empty.
# Not fatal: a build using --with-capstone=PATH (or CAPSTONE_DIR) needs no
# submodule, and must still work in a sandbox with no network. configure
# reports the empty submodule if neither is available.
echo "running: git submodule update --init third_party/capstone"
if ! git submodule update --init third_party/capstone ; then
echo "warning: could not check out third_party/capstone."
echo "warning: pass --with-capstone=PATH to configure to use a prebuilt Capstone."
fi
else
echo "skipping: git configuration"
fi
2 changes: 1 addition & 1 deletion callgrind/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ callgrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_CFLAGS = $(LTO_CFLAGS) \
$(AM_CFLAGS_@VGCONF_PLATFORM_PRI_CAPS@) $(CALLGRIND_CFLAGS_COMMON) \
@CAPSTONE_CFLAGS@
callgrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_DEPENDENCIES = \
$(TOOL_DEPENDENCIES_@VGCONF_PLATFORM_PRI_CAPS@)
$(TOOL_DEPENDENCIES_@VGCONF_PLATFORM_PRI_CAPS@) @CAPSTONE_LIBS@
callgrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_LDADD = \
$(TOOL_LDADD_@VGCONF_PLATFORM_PRI_CAPS@) @CAPSTONE_LIBS@
callgrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_LDFLAGS = \
Expand Down
25 changes: 21 additions & 4 deletions callgrind/cycledecode_capstone.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ extern char* vgPlain_strncpy(char* d, const char* s, unsigned long n);
extern char* vgPlain_strchr(const char* s, char c);
extern char* vgPlain_strrchr(const char* s, char c);
extern char* vgPlain_strstr(const char* h, const char* n);
extern char* vgPlain_strcat(char* d, const char* s);

static const char* const CLG_CD_CC = "clg.cycledecode";

Expand Down Expand Up @@ -91,10 +92,16 @@ int printf(const char* fmt, ...)
}
int puts(const char* s) { return printf("%s\n", s); }

/* Capstone's SStream references stderr/fwrite on a buffer-overflow guard in the
* op_str text path (which this code never reads). Valgrind has no FILE* layer,
* so stderr is a sentinel and fwrite routes the bytes to the Valgrind log fd,
* making such an overflow visible rather than swallowed. */
/* Capstone's SStream references stderr/fprintf on a buffer-overflow guard in
* the op_str text path (which this code never reads). Valgrind has no FILE*
* layer, so stderr is a sentinel and these route the bytes to the Valgrind log
* fd, making such an overflow visible rather than swallowed.
*
* Both fprintf and fwrite are needed: the guard calls fprintf, which GCC folds
* into fwrite for a format string with no conversions, but only when builtins
* are enabled. Valgrind's tool CFLAGS pass -fno-builtin, so whether the object
* ends up referencing fprintf or fwrite depends on how Capstone was compiled.
* Defining both keeps the tool linkable either way. */
extern int vgPlain_write(int fd, const void* buf, int count);
FILE* stderr = 0;
size_t fwrite(const void* p, size_t size, size_t nmemb, FILE* f)
Expand All @@ -103,6 +110,15 @@ size_t fwrite(const void* p, size_t size, size_t nmemb, FILE* f)
vgPlain_write(2, p, (int)(size * nmemb));
return nmemb;
}
int fprintf(FILE* f, const char* fmt, ...)
{
(void)f;
va_list ap;
va_start(ap, fmt);
unsigned int r = vgPlain_vprintf(fmt, ap);
va_end(ap);
return (int)r;
}

size_t strlen(const char* s) { return vgPlain_strlen(s); }
int strcmp(const char* a, const char* b) { return vgPlain_strcmp(a, b); }
Expand All @@ -118,6 +134,7 @@ char* strncpy(char* d, const char* s, size_t n)
char* strchr(const char* s, int c) { return vgPlain_strchr(s, (char)c); }
char* strrchr(const char* s, int c) { return vgPlain_strrchr(s, (char)c); }
char* strstr(const char* h, const char* n) { return vgPlain_strstr(h, n); }
char* strcat(char* d, const char* s) { return vgPlain_strcat(d, s); }

/*------------------------------------------------------------*/
/*--- Capstone handle: open / decode -*/
Expand Down
36 changes: 6 additions & 30 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ AC_PROG_CC
AS_IF([test "x$ac_cv_prog_cc_c11" = "xno"],
[AC_MSG_ERROR([Valgrind relies on a C compiler supporting C11])])

# CodSpeed: pin the C dialect. See m4/codspeed_capstone.m4.
CODSPEED_C_STD_GNU17

AC_PROG_CPP
AC_PROG_CXX
AC_PROG_RANLIB
Expand Down Expand Up @@ -1122,36 +1125,8 @@ AC_ARG_WITH(tmpdir,
AC_DEFINE_UNQUOTED(VG_TMPDIR, "$tmpdir", [Temporary files directory])
AC_SUBST(VG_TMPDIR, [$tmpdir])

#----------------------------------------------------------------------------
# CodSpeed: mandatory Capstone for Callgrind per-instruction cycle estimation
#----------------------------------------------------------------------------
# Callgrind's primary (native) tool is always built with the Capstone decoder
# and a generated cost table (x86 or arm64, selected at compile time), enabling
# --cycle-estimation=yes. The decoder location comes from --with-capstone=PATH
# or, when omitted, the CAPSTONE_DIR environment variable (`nix develop` sets
# it). A build without Capstone is not supported and fails here.
AC_ARG_WITH(capstone,
[ --with-capstone=PATH Path to the Capstone decoder install used for
Callgrind cycle estimation (Cy/Cl). Defaults to the
CAPSTONE_DIR environment variable (amd64/arm64)],
[capstone_dir="$withval"],
[capstone_dir="$CAPSTONE_DIR"])

if test -z "$capstone_dir"; then
AC_MSG_ERROR([Capstone is required for Callgrind cycle estimation. Pass --with-capstone=PATH or set CAPSTONE_DIR (`nix develop` provides it).])
fi
if test ! -f "$capstone_dir/lib/libcapstone.a" \
-o ! -f "$capstone_dir/include/capstone/capstone.h"; then
AC_MSG_ERROR([--with-capstone=$capstone_dir: libcapstone.a or capstone.h not found])
fi
# Fortify off: the tool links -nodefaultlibs, so glibc's __*_chk fortify
# wrappers are unavailable, and our libc shims (sprintf/snprintf/...) must
# be real definitions, not fortify macro-expansions.
CAPSTONE_CFLAGS="-DCLG_WITH_CAPSTONE -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0 -I$capstone_dir/include"
CAPSTONE_LIBS="$capstone_dir/lib/libcapstone.a"
AC_MSG_NOTICE([Callgrind cycle estimation enabled with Capstone at $capstone_dir])
AC_SUBST(CAPSTONE_CFLAGS)
AC_SUBST(CAPSTONE_LIBS)
# CodSpeed: Capstone decoder for Callgrind cycle estimation. See m4/codspeed_capstone.m4.
CODSPEED_CAPSTONE

#----------------------------------------------------------------------------
# Detect xcode path
Expand Down Expand Up @@ -5790,6 +5765,7 @@ CFLAGS=$safe_CFLAGS
AC_CONFIG_FILES([
Makefile
VEX/Makefile:Makefile.vex.in
third_party/Makefile
valgrind.spec
valgrind.pc
glibc-2.X.supp
Expand Down
5 changes: 3 additions & 2 deletions debian/rules
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ CONFARGS = \
--enable-only64bit \
--with-gdbscripts-dir=/usr/share/gdb/auto-load

# Callgrind cycle estimation requires Capstone; the release workflow builds a
# static decoder and exports its prefix as CAPSTONE_DIR.
# Callgrind cycle estimation needs Capstone. The build compiles the vendored
# third_party/capstone submodule by default; CAPSTONE_DIR, when set, points at a
# prebuilt decoder to use instead.
ifneq ($(CAPSTONE_DIR),)
CONFARGS += --with-capstone=$(CAPSTONE_DIR)
endif
Expand Down
9 changes: 3 additions & 6 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@
});
in
{
# Expose the pinned Capstone so the autotools build and scripts can find
# it via `nix build .#capstone` or the CAPSTONE_DIR env var below.
# Expose the pinned Capstone for the builds that want a prebuilt decoder
# rather than the vendored submodule: `nix build .#capstone`, then pass it
# to configure as --with-capstone=PATH (or CAPSTONE_DIR).
packages.capstone = capstone;

devShells.default = pkgs.mkShell {
Expand All @@ -62,10 +63,6 @@
pkgs.gcc
pkgs.pkg-config
];

# Consumed by configure (--with-capstone), the LUT generator, and the
# standalone cycledecode test. Point them at the hardening-free build.
CAPSTONE_DIR = "${capstone}";
};
}
);
Expand Down
73 changes: 73 additions & 0 deletions m4/codspeed_capstone.m4
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# codspeed_capstone.m4 -- CodSpeed additions to Valgrind's configure.

# CODSPEED_CAPSTONE
# -----------------
# Locate the Capstone decoder that Callgrind's per-instruction cycle
# estimation (--cycle-estimation=yes) links against, and export
# CAPSTONE_CFLAGS / CAPSTONE_LIBS for callgrind/Makefile.am.
#
# By default the vendored submodule in third_party/capstone is compiled by
# third_party/Makefile.am as part of `make`, so a plain
# `./autogen.sh && ./configure && make && make install` is all that is needed.
# --with-capstone=PATH (or the CAPSTONE_DIR environment variable, which `nix
# develop` sets) selects a prebuilt Capstone install instead.
AC_DEFUN([CODSPEED_CAPSTONE], [
AC_ARG_WITH([capstone],
[AS_HELP_STRING([--with-capstone=PATH],
[use a prebuilt Capstone install for Callgrind cycle estimation instead
of the vendored third_party/capstone submodule. Defaults to the
CAPSTONE_DIR environment variable])],
[capstone_dir="$withval"],
[capstone_dir="$CAPSTONE_DIR"])

AM_CONDITIONAL([BUILD_VENDORED_CAPSTONE], [test -z "$capstone_dir"])

if test -z "$capstone_dir"; then
# Built by third_party/Makefile.am. Note there is deliberately no check
# for libcapstone.a here: it does not exist yet at configure time.
if test ! -f "$srcdir/third_party/capstone/cs.c"; then
AC_MSG_ERROR([third_party/capstone is empty. Run:
git submodule update --init third_party/capstone
or pass --with-capstone=PATH to use a prebuilt Capstone.])
fi
CAPSTONE_INCLUDES='-I$(top_srcdir)/third_party/capstone/include'
CAPSTONE_LIBS='$(top_builddir)/third_party/libcapstone.a'
AC_MSG_NOTICE([Callgrind cycle estimation enabled with the vendored Capstone])
else
if test ! -f "$capstone_dir/lib/libcapstone.a" \
-o ! -f "$capstone_dir/include/capstone/capstone.h"; then
AC_MSG_ERROR([--with-capstone=$capstone_dir: libcapstone.a or capstone.h not found])
fi
CAPSTONE_INCLUDES="-I$capstone_dir/include"
CAPSTONE_LIBS="$capstone_dir/lib/libcapstone.a"
AC_MSG_NOTICE([Callgrind cycle estimation enabled with Capstone at $capstone_dir])
fi

# Fortify off: the tool links -nodefaultlibs, so glibc's __*_chk fortify
# wrappers are unavailable, and our libc shims (sprintf/snprintf/...) must
# be real definitions, not fortify macro-expansions.
CAPSTONE_CFLAGS="-DCLG_WITH_CAPSTONE -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0 $CAPSTONE_INCLUDES"
AC_SUBST([CAPSTONE_CFLAGS])
AC_SUBST([CAPSTONE_LIBS])
])

# CODSPEED_C_STD_GNU17
# --------------------
# Pin the C dialect to gnu17.
#
# AC_PROG_CC under Autoconf 2.70+ selects the newest dialect the compiler
# supports, which is -std=gnu23 on GCC 15+. Under C23, glibc 2.42+ defines
# strchr/strrchr/strstr as _Generic macros, which clash with Callgrind's own
# definitions of those symbols. Appending to CFLAGS is enough to win: Autoconf
# puts its own -std= into $CC, and CFLAGS comes later on the command line.
#
# Must be called after AC_PROG_CC.
AC_DEFUN([CODSPEED_C_STD_GNU17], [
AC_MSG_CHECKING([whether $CC accepts -std=gnu17])
codspeed_save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -std=gnu17"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
CFLAGS="$codspeed_save_CFLAGS"])
])
Loading
Loading