# Copyright 2025 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 EAPI=8 inherit cmake flag-o-matic toolchain-funcs DESCRIPTION="Memory debugging tool for Linux and Windows" HOMEPAGE="https://drmemory.org/ https://github.com/DynamoRIO/drmemory" # DynamoRIO submodule commit for release_2.6.0 DRIO_COMMIT="bbd4ffadd03a7630b6143035c369bf7714357eeb" # Googletest submodule commit GTEST_COMMIT="12ddfca458945b8fcffa7ed416076ed55bf669b1" # DynamoRIO's submodules (libipt and zlib) LIBIPT_COMMIT="c848a85c3104e2f5780741f85de5c9e65476ece2" ZLIB_COMMIT="21767c654d31d2dccdde4330529775c6c5fd5389" SRC_URI=" https://github.com/DynamoRIO/${PN}/archive/release_${PV}.tar.gz -> ${P}.tar.gz https://github.com/DynamoRIO/dynamorio/archive/${DRIO_COMMIT}.tar.gz -> dynamorio-${DRIO_COMMIT:0:7}.tar.gz https://github.com/DynamoRIO/googletest/archive/${GTEST_COMMIT}.tar.gz -> googletest-${GTEST_COMMIT:0:7}.tar.gz https://github.com/intel/libipt/archive/${LIBIPT_COMMIT}.tar.gz -> libipt-${LIBIPT_COMMIT:0:7}.tar.gz https://github.com/madler/zlib/archive/${ZLIB_COMMIT}.tar.gz -> zlib-${ZLIB_COMMIT:0:7}.tar.gz " S="${WORKDIR}/${PN}-release_${PV}" LICENSE="LGPL-2.1" SLOT="0" KEYWORDS="~amd64" IUSE="doc test" # DynamoRIO uses special ELF structures for dynamic binary instrumentation # Stripping corrupts these structures and causes SIGILL at runtime RESTRICT="strip !test? ( test )" RDEPEND=" sys-libs/libunwind:= dev-lang/perl " DEPEND="${RDEPEND}" BDEPEND=" doc? ( app-text/doxygen ) " PATCHES=( "${FILESDIR}/${PN}-2.6.0-cmake-cmp0043.patch" "${FILESDIR}/${PN}-2.6.0-gcc-asm-flags.patch" "${FILESDIR}/${PN}-2.6.0-gcc15.patch" "${FILESDIR}/${PN}-2.6.0-stdbool.patch" "${FILESDIR}/${PN}-2.6.0-cxx20-destructor.patch" "${FILESDIR}/${PN}-2.6.0-strcasestr.patch" "${FILESDIR}/${PN}-2.6.0-uninitialized.patch" "${FILESDIR}/${PN}-2.6.0-enum-mismatch.patch" "${FILESDIR}/${PN}-2.6.0-options-bool.patch" "${FILESDIR}/${PN}-2.6.0-memlayout-bool.patch" ) QA_FLAGS_IGNORED=" opt/drmemory/.* " src_prepare() { # Setup bundled DynamoRIO rmdir "${S}/dynamorio" || die mv "${WORKDIR}/dynamorio-${DRIO_COMMIT}" "${S}/dynamorio" || die # Setup DynamoRIO's bundled libipt rmdir "${S}/dynamorio/third_party/libipt" || die mv "${WORKDIR}/libipt-${LIBIPT_COMMIT}" "${S}/dynamorio/third_party/libipt" || die # Setup DynamoRIO's bundled zlib rmdir "${S}/dynamorio/third_party/zlib" || die mv "${WORKDIR}/zlib-${ZLIB_COMMIT}" "${S}/dynamorio/third_party/zlib" || die # Setup bundled googletest rmdir "${S}/third_party/googletest" || die mv "${WORKDIR}/googletest-${GTEST_COMMIT}" "${S}/third_party/googletest" || die # Fix cmake install commands to respect DESTDIR # The file(WRITE/MAKE_DIRECTORY/APPEND) and configure_file() commands # do not automatically respect the DESTDIR environment variable sed -i \ -e 's|"\\${CMAKE_INSTALL_PREFIX}/|"\\$ENV{DESTDIR}\\${CMAKE_INSTALL_PREFIX}/|g' \ "${S}/CMakeLists.txt" "${S}/docs/CMakeLists.txt" || die cmake_src_prepare } src_configure() { # DynamoRIO needs specific compiler flags filter-flags -fstack-protector-strong -fstack-clash-protection append-flags -fno-stack-protector # Avoid AVX-512 for portability append-flags -mno-avx512f # Static link libstdc++ and libgcc to avoid runtime library path issues # DynamoRIO uses a private loader that doesn't respect standard library paths # This is the recommended approach per DynamoRIO documentation append-ldflags -static-libgcc -static-libstdc++ local mycmakeargs=( -DCMAKE_INSTALL_PREFIX="${EPREFIX}/opt/${PN}" -DBUILD_TOOL_TESTS=$(usex test ON OFF) ) # Disable doxygen search when doc USE is disabled # drmemory unconditionally runs find_package(Doxygen) and builds docs if found if ! use doc; then mycmakeargs+=( -DCMAKE_DISABLE_FIND_PACKAGE_Doxygen=ON ) fi cmake_src_configure } src_install() { cmake_src_install # Remove incorrectly installed DynamoRIO build artifacts # These are cmake install targets that don't properly respect DESTDIR rm -rf "${ED}/var" || die # Install DynamoRIO extension libraries that DRMF depends on # These are built but not installed by DrMemory's cmake install local ext_src="${BUILD_DIR}/dynamorio/ext/lib64/release" local ext_dst="${ED}/opt/${PN}/dynamorio/ext/lib64/release" if [[ -d "${ext_src}" ]]; then einfo "Installing DynamoRIO extension libraries" dodir "/opt/${PN}/dynamorio/ext/lib64/release" local lib for lib in "${ext_src}"/*.so; do if [[ -f "${lib}" ]]; then cp -a "${lib}" "${ext_dst}/" || die "Failed to install ${lib##*/}" fi done else ewarn "DynamoRIO extension directory not found: ${ext_src}" fi # Create .drpath files for DynamoRIO's private loader to find GCC libraries # DynamoRIO uses its own loader that doesn't respect standard library paths # The .drpath file is DynamoRIO's cross-platform mechanism for library search paths # Note: patchelf is NOT used because it can break DynamoRIO's private loader local gcc_libdir gcc_libdir="$($(tc-getCC) -print-file-name=libstdc++.so.6)" gcc_libdir="${gcc_libdir%/*}" if [[ -d "${gcc_libdir}" ]]; then einfo "Creating .drpath files with GCC library path: ${gcc_libdir}" local f basename while IFS= read -r -d '' f; do if [[ -f "${f}" ]] && file "${f}" | grep -q "ELF.*shared object"; then basename="${f##*/}" basename="${basename%.so*}" echo "${gcc_libdir}" > "${f%/*}/${basename}.drpath" || \ ewarn "Failed to create .drpath for ${f}" fi done < <(find "${ED}/opt/${PN}" -name "*.so" -print0) fi # Create symlinks in /usr/bin for DrMemory tools dodir /usr/bin local tool for tool in drmemory drltrace drstrace symquery; do if [[ -x "${ED}/opt/${PN}/bin64/${tool}" ]]; then dosym "../../opt/${PN}/bin64/${tool}" "/usr/bin/${tool}" fi done # Create symlinks in /usr/bin for bundled DynamoRIO tools for tool in drrun drconfig drinject drdisas; do if [[ -x "${ED}/opt/${PN}/dynamorio/bin64/${tool}" ]]; then dosym "../../opt/${PN}/dynamorio/bin64/${tool}" "/usr/bin/${tool}" fi done dodoc README.md }