diff --git a/.github/actions/build-capstone/action.yml b/.github/actions/build-capstone/action.yml deleted file mode 100644 index ef837a772..000000000 --- a/.github/actions/build-capstone/action.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: Build Capstone (cycle-estimation decoder) -description: >- - Build the static Capstone that Callgrind cycle estimation links against, and - export its install prefix as CAPSTONE_DIR for later steps. - -runs: - using: composite - steps: - - shell: bash - run: | - CS_SRC="$GITHUB_WORKSPACE/third_party/capstone" - CS_PREFIX="$GITHUB_WORKSPACE/.capstone" - cmake -S "$CS_SRC" -B "$CS_SRC/build" \ - -DCMAKE_BUILD_TYPE=Release \ - -DCAPSTONE_ARCHITECTURE_DEFAULT=OFF \ - -DCAPSTONE_X86_SUPPORT=ON \ - -DCAPSTONE_ARM64_SUPPORT=ON \ - -DCAPSTONE_BUILD_SHARED_LIBS=OFF \ - -DCAPSTONE_BUILD_CSTOOL=OFF \ - -DCMAKE_INSTALL_LIBDIR=lib \ - -DCMAKE_INSTALL_PREFIX="$CS_PREFIX" \ - -DCMAKE_C_FLAGS="-fno-stack-protector -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0 -fPIC" - cmake --build "$CS_SRC/build" -j"$(nproc)" - cmake --install "$CS_SRC/build" - echo "CAPSTONE_DIR=$CS_PREFIX" >> "$GITHUB_ENV" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 56254b955..a1ca43ae4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,6 +7,9 @@ on: branches: [ master ] workflow_dispatch: +permissions: + contents: read + jobs: test-callgrind: strategy: @@ -44,7 +47,6 @@ jobs: build-essential \ automake \ autoconf \ - cmake \ libc6-dev \ gdb \ docbook \ @@ -52,9 +54,6 @@ jobs: docbook-xml \ xsltproc - - name: Build Capstone (cycle-estimation decoder) - uses: ./.github/actions/build-capstone - - name: Run autogen run: ./autogen.sh @@ -67,6 +66,10 @@ jobs: - name: Build Valgrind run: make -j$(nproc) + # The vendored build must not write anything into the submodule checkout. + - name: Check the Capstone submodule is clean + run: test -z "$(git -C third_party/capstone status --porcelain --untracked-files=all)" + - name: Build test dependencies run: | make -C tests arch_test os_test true @@ -84,3 +87,59 @@ jobs: with: name: callgrind-test-logs-${{ matrix.runner.ubuntu-version }} path: callgrind/tests/*.log + + # `make` builds the vendored submodule; this guards the other supported path, + # --with-capstone=PATH, which debian/rules forwards CAPSTONE_DIR to. + build-with-prebuilt-capstone: + runs-on: ubuntu-24.04 + + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Update apt-get cache + run: sudo apt-get update + + - name: Install build dependencies + run: | + sudo apt-get install -y \ + build-essential \ + automake \ + autoconf \ + cmake \ + libc6-dev + + # Not the distribution's libcapstone-dev: a Valgrind tool links + # -nodefaultlibs and runs without glibc's %fs TLS, so the decoder has to + # be built without stack-protector and without fortify, which no distro + # package is. + - name: Build Capstone outside the source tree + run: | + cmake -S third_party/capstone -B "$RUNNER_TEMP/capstone-build" \ + -DCMAKE_BUILD_TYPE=Release \ + -DCAPSTONE_ARCHITECTURE_DEFAULT=OFF \ + -DCAPSTONE_X86_SUPPORT=ON \ + -DCAPSTONE_ARM64_SUPPORT=ON \ + -DCAPSTONE_BUILD_SHARED_LIBS=OFF \ + -DCAPSTONE_BUILD_CSTOOL=OFF \ + -DCMAKE_INSTALL_LIBDIR=lib \ + -DCMAKE_INSTALL_PREFIX="$RUNNER_TEMP/capstone" \ + -DCMAKE_C_FLAGS="-fno-stack-protector -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0 -fPIC" + cmake --build "$RUNNER_TEMP/capstone-build" -j"$(nproc)" + cmake --install "$RUNNER_TEMP/capstone-build" + + - name: Run autogen + run: ./autogen.sh + + - name: Configure + run: ./configure --enable-only64bit --with-capstone="$RUNNER_TEMP/capstone" + + - name: Build Valgrind + run: make -j$(nproc) + + - name: Check cycle estimation + run: | + ./vg-in-place --tool=callgrind --cycle-estimation=yes \ + --callgrind-out-file=/dev/null /bin/true 2>&1 | grep -q 'Events : Ir Ct Cl' + diff --git a/.github/workflows/codspeed.yml b/.github/workflows/codspeed.yml index fc41edf9d..4a0b5628a 100644 --- a/.github/workflows/codspeed.yml +++ b/.github/workflows/codspeed.yml @@ -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 }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b3850a7da..5f639d782 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -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 }} diff --git a/.gitignore b/.gitignore index 5c527eaee..4446456c3 100644 --- a/.gitignore +++ b/.gitignore @@ -2567,7 +2567,13 @@ 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-obj/ + +# install prefix of a Capstone built by hand for --with-capstone /.capstone # fake CodSpeed benchmark fixture binary (compiled from testdata/llsc_tzconvert_bench.c) diff --git a/Makefile.am b/Makefile.am index 6c5b9f5b6..176317a5d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 \ diff --git a/autogen.sh b/autogen.sh index 5de086b1a..b350bc9c9 100755 --- a/autogen.sh +++ b/autogen.sh @@ -20,6 +20,11 @@ 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: check out the Capstone decoder that Callgrind's cycle estimation + # links against, unless a prebuilt one was provided or it is already there. + if test -z "$CAPSTONE_DIR" && test ! -f third_party/capstone/cs.c ; then + run git submodule update --init third_party/capstone + fi else echo "skipping: git configuration" fi diff --git a/callgrind/Makefile.am b/callgrind/Makefile.am index 1e5bcb97d..de92e16b8 100644 --- a/callgrind/Makefile.am +++ b/callgrind/Makefile.am @@ -65,9 +65,9 @@ callgrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_CPPFLAGS = \ $(AM_CPPFLAGS_@VGCONF_PLATFORM_PRI_CAPS@) callgrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_CFLAGS = $(LTO_CFLAGS) \ $(AM_CFLAGS_@VGCONF_PLATFORM_PRI_CAPS@) $(CALLGRIND_CFLAGS_COMMON) \ - @CAPSTONE_CFLAGS@ + @CAPSTONE_CFLAGS@ @CODSPEED_C_STD@ 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 = \ diff --git a/callgrind/cycledecode_capstone.c b/callgrind/cycledecode_capstone.c index 31033bf73..6472cc485 100644 --- a/callgrind/cycledecode_capstone.c +++ b/callgrind/cycledecode_capstone.c @@ -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"; @@ -91,10 +92,11 @@ 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 buffer-overflow guard calls fprintf(stderr, ...), which + * GCC folds into fwrite only when builtins are enabled -- and Valgrind's tool + * CFLAGS pass -fno-builtin. Both are defined, so the tool links against a + * Capstone compiled either way. Valgrind has no FILE* layer, so stderr is a + * sentinel and the bytes are routed to the Valgrind log fd. */ 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) @@ -103,6 +105,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); } @@ -118,6 +129,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 -*/ diff --git a/configure.ac b/configure.ac index 4275bb3c5..cb61db938 100644 --- a/configure.ac +++ b/configure.ac @@ -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: C dialect for the Callgrind tool. See m4/codspeed_capstone.m4. +CODSPEED_C_STD_GNU17 + AC_PROG_CPP AC_PROG_CXX AC_PROG_RANLIB @@ -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 @@ -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 diff --git a/debian/rules b/debian/rules index c7caefdfe..07fc9a2c8 100644 --- a/debian/rules +++ b/debian/rules @@ -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 diff --git a/flake.nix b/flake.nix index 277c0c31d..553d4d345 100644 --- a/flake.nix +++ b/flake.nix @@ -12,39 +12,14 @@ system: let pkgs = import nixpkgs { inherit system; }; - - # Capstone for the Callgrind cycle-estimation decoder, built the same way - # as the CI workflows (see .github/workflows): x86 + arm64 only, static. - # - # Valgrind tools run without glibc's %fs TLS and link -nodefaultlibs, so - # Capstone must be built without stack-protector (its %fs:0x28 canary - # read faults at runtime) and without fortify (pulls __*_chk libc - # symbols); hardeningDisable drops both. Limiting the architectures also - # drops the non-x86/arm64 instruction printers that reference libc - # symbols (e.g. XCore's strtol) the tool does not shim. - capstone = pkgs.capstone.overrideAttrs (old: { - cmakeFlags = (old.cmakeFlags or [ ]) ++ [ - "-DCAPSTONE_ARCHITECTURE_DEFAULT=OFF" - "-DCAPSTONE_X86_SUPPORT=ON" - "-DCAPSTONE_ARM64_SUPPORT=ON" - ]; - hardeningDisable = (old.hardeningDisable or [ ]) ++ [ - "stackprotector" - "fortify" - "fortify3" - ]; - }); 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. - packages.capstone = capstone; - devShells.default = pkgs.mkShell { # Valgrind tool objects link -nodefaultlibs and run without glibc's %fs # TLS, so the toolchain must not inject stack-protector or fortify # (__*_chk) into them. The compiler wrapper otherwise re-adds these - # over our -fno-stack-protector / -D_FORTIFY_SOURCE=0 flags. + # over our -fno-stack-protector / -D_FORTIFY_SOURCE=0 flags. This + # covers the vendored Capstone too, which is compiled into the tool. hardeningDisable = [ "stackprotector" "fortify" @@ -52,7 +27,6 @@ ]; packages = [ - capstone pkgs.python3 pkgs.uv pkgs.autoconf @@ -62,10 +36,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}"; }; } ); diff --git a/m4/codspeed_capstone.m4 b/m4/codspeed_capstone.m4 new file mode 100644 index 000000000..398ed85aa --- /dev/null +++ b/m4/codspeed_capstone.m4 @@ -0,0 +1,72 @@ +# codspeed_capstone.m4 -- CodSpeed additions to Valgrind's configure. + +# CODSPEED_CAPSTONE +# ----------------- +# Export CAPSTONE_CFLAGS / CAPSTONE_LIBS for callgrind/Makefile.am. The vendored +# third_party/capstone submodule is compiled by third_party/Makefile.am; +# --with-capstone=PATH (or CAPSTONE_DIR) selects a prebuilt 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 + # libcapstone.a is not tested for: 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 + capstone_lib= + for d in lib lib64 "lib/$host_cpu-linux-gnu"; do + if test -f "$capstone_dir/$d/libcapstone.a"; then + capstone_lib="$capstone_dir/$d/libcapstone.a" + break + fi + done + if test -z "$capstone_lib" -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_lib" + AC_MSG_NOTICE([Callgrind cycle estimation enabled with Capstone at $capstone_dir]) +fi + +# Fortify off: the tool links -nodefaultlibs, so glibc's __*_chk wrappers are +# unavailable and our libc shims must be definitions, not 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 +# -------------------- +# Export CODSPEED_C_STD, the dialect the Callgrind tool is compiled with. Under +# C23 -- what AC_PROG_CC picks on GCC 15+ -- glibc 2.42+ defines strchr/strrchr/ +# strstr as _Generic macros, which clash with the definitions in +# cycledecode_capstone.c. It stays out of CFLAGS so the rest of the tree, the +# test programs included, keeps the compiler's own default. +# +# 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]) + CODSPEED_C_STD="-std=gnu17"], + [AC_MSG_RESULT([no]) + CODSPEED_C_STD=]) +CFLAGS="$codspeed_save_CFLAGS" +AC_SUBST([CODSPEED_C_STD]) +]) diff --git a/third_party/Makefile.am b/third_party/Makefile.am new file mode 100644 index 000000000..4c75e5511 --- /dev/null +++ b/third_party/Makefile.am @@ -0,0 +1,99 @@ +include $(top_srcdir)/Makefile.all.am + +# CodSpeed: the vendored Capstone decoder for Callgrind cycle estimation. +# Skipped when configure was given a prebuilt one (--with-capstone=PATH). +if BUILD_VENDORED_CAPSTONE + +noinst_LIBRARIES = libcapstone.a + +# Only x86 and arm64: the other targets' instruction printers reference libc +# symbols a Valgrind tool does not shim, so linking them breaks the tool. +capstone_sources = \ + cs.c \ + MCInst.c \ + MCInstrDesc.c \ + MCRegisterInfo.c \ + Mapping.c \ + SStream.c \ + utils.c \ + arch/X86/X86ATTInstPrinter.c \ + arch/X86/X86Disassembler.c \ + arch/X86/X86DisassemblerDecoder.c \ + arch/X86/X86InstPrinterCommon.c \ + arch/X86/X86IntelInstPrinter.c \ + arch/X86/X86Mapping.c \ + arch/X86/X86Module.c \ + arch/AArch64/AArch64BaseInfo.c \ + arch/AArch64/AArch64Disassembler.c \ + arch/AArch64/AArch64InstPrinter.c \ + arch/AArch64/AArch64Mapping.c \ + arch/AArch64/AArch64Module.c + +# Compiled by the rules below rather than through _SOURCES: automake writes +# every object, .deps and .dirstamp next to its source, i.e. into the submodule +# checkout. These mirror the source tree under capstone-obj/ in the build dir. +capstone_objects = $(capstone_sources:%.c=capstone-obj/%.$(OBJEXT)) + +libcapstone_a_SOURCES = +libcapstone_a_LIBADD = $(capstone_objects) + +# The preprocessor state of a CMake build with -DCAPSTONE_ARCHITECTURE_DEFAULT=OFF +# -DCAPSTONE_X86_SUPPORT=ON -DCAPSTONE_ARM64_SUPPORT=ON. +capstone_cppflags = \ + -I$(srcdir)/capstone/include \ + -DCAPSTONE_X86_SUPPORT \ + -DCAPSTONE_HAS_X86 \ + -DCAPSTONE_ARM64_SUPPORT \ + -DCAPSTONE_HAS_ARM64 \ + -DCAPSTONE_USE_SYS_DYN_MEM + +# Capstone goes into the primary Callgrind tool, so it gets that platform's +# flags: AM_CFLAGS_BASE carries -fno-stack-protector (a canary read faults in a +# tool, which runs without glibc's TLS) and the right word size. -DNDEBUG is +# load bearing: assert() would pull in __assert_fail. +capstone_cflags = \ + $(AM_CFLAGS_@VGCONF_PLATFORM_PRI_CAPS@) \ + -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0 \ + -DNDEBUG \ + -w + +capstone-obj/%.$(OBJEXT): $(srcdir)/capstone/%.c + $(AM_V_at)$(MKDIR_P) $(@D) + $(AM_V_CC)$(CC) $(capstone_cppflags) $(capstone_cflags) \ + -MMD -MP -MF $(@:.$(OBJEXT)=.d) -c -o $@ $< + +-include $(capstone_objects:.$(OBJEXT)=.d) + +clean-local: + -rm -rf capstone-obj + +endif + +# `make dist` tarballs are unpacked outside a git checkout, so the sources above +# and everything they include are shipped explicitly. Only the compiled-in +# architectures, which keeps this at ~18M of the submodule's 76M. +EXTRA_DIST = \ + capstone/cs.c \ + capstone/MCInst.c \ + capstone/MCInstrDesc.c \ + capstone/MCRegisterInfo.c \ + capstone/Mapping.c \ + capstone/SStream.c \ + capstone/utils.c \ + capstone/include \ + capstone/arch/X86 \ + capstone/arch/AArch64 \ + capstone/LEB128.h \ + capstone/MCDisassembler.h \ + capstone/MCFixedLenDisassembler.h \ + capstone/MCInst.h \ + capstone/MCInstrDesc.h \ + capstone/MCRegisterInfo.h \ + capstone/Mapping.h \ + capstone/MathExtras.h \ + capstone/SStream.h \ + capstone/cs_priv.h \ + capstone/cs_simple_types.h \ + capstone/utils.h \ + capstone/LICENSE.TXT \ + capstone/LICENSE_LLVM.TXT