tracexec 1.0.0

Tracer for execve{,at} and pre-exec behavior, launcher for debuggers.
# Credits: https://github.com/jordanisaacs/kernel-module-flake
# Original Copyright Notice:

# MIT License

# Copyright (c) 2022 Jordan Isaacs

# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:

# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

{
  stdenv,
  lib,
  callPackage,
  buildPackages,
  rustPlatform,
}:
{
  src,
  configfile,
  modDirVersion,
  version,
  # Install the GDB scripts
  kernelPatches ? [ ],
  extraMakeFlags,
  nixpkgs, # Nixpkgs source
}:
let
  kernel =
    ((callPackage "${nixpkgs}/pkgs/os-specific/linux/kernel/build.nix" { }) {
      inherit
        src
        modDirVersion
        version
        kernelPatches
        configfile
        extraMakeFlags
        ;
      inherit lib stdenv;

      # Because allowedImportFromDerivation is not enabled,
      # the function cannot set anything based on the configfile. These settings do not
      # actually change the .config but let the kernel derivation know what can be built.
      # See manual-config.nix for other options
      config = {
        # Enables the dev build
        CONFIG_MODULES = "y";
      };
    }).overrideAttrs
      (old: {
        inherit (old) nativeBuildInputs;

        dontStrip = true;

        postInstall = ''
          mkdir -p $dev
          cp vmlinux $dev/

          mkdir -p $dev/lib/modules/${modDirVersion}/{build,source}
          cp -rL $buildRoot/scripts $dev/lib/modules/${modDirVersion}/build/
          cp -L $buildRoot/vmlinux-gdb.py $dev/lib/modules/${modDirVersion}/build/scripts/gdb/
          ln -sfn $dev/lib/modules/${modDirVersion}/build/scripts/gdb/vmlinux-gdb.py $dev/lib/modules/${modDirVersion}/build/vmlinux-gdb.py

          if [ -z "''${dontStrip-}" ]; then
            installFlags+=("INSTALL_MOD_STRIP=1")
          fi
          make modules_install "''${makeFlags[@]}" "''${installFlags[@]}"
          unlink $modules/lib/modules/${modDirVersion}/build

          # To save space, exclude a bunch of unneeded stuff when copying.
          (cd .. && rsync --archive --prune-empty-dirs \
              --exclude='/build/' \
              * $dev/lib/modules/${modDirVersion}/source/)

          cd $dev/lib/modules/${modDirVersion}/source
          cp $buildRoot/{.config,Module.symvers} $dev/lib/modules/${modDirVersion}/build

          make modules_prepare "''${makeFlags[@]}" O=$dev/lib/modules/${modDirVersion}/build

          # For reproducibility, removes accidental leftovers from a `cc1` call
          # from a `try-run` call from the Makefile
          rm -f $dev/lib/modules/${modDirVersion}/build/.[0-9]*.d

          # Keep some extra files on some arches (powerpc, aarch64)
          for f in arch/powerpc/lib/crtsavres.o arch/arm64/kernel/ftrace-mod.o; do
            if [ -f "$buildRoot/$f" ]; then
              cp $buildRoot/$f $dev/lib/modules/${modDirVersion}/build/$f
            fi
          done

          # Not doing the nix default of removing files from the source tree.
          # This is because the source tree is necessary for debugging with GDB.
        '';
      });

  kernelPassthru = {
    inherit (configfile) structuredConfig;
    inherit modDirVersion configfile;
    passthru = kernel.passthru // (removeAttrs kernelPassthru [ "passthru" ]);
  };
in
lib.extendDerivation true kernelPassthru kernel