From d3072c1322d069df507c8247ac0e67c99694e9ce Mon Sep 17 00:00:00 2001 From: Rowan Hart Date: Thu, 11 Apr 2024 12:42:59 -0700 Subject: [PATCH] Fixup versioning for simics APIs and add versioned tests (#75) --- .dockerignore | 20 +- .github/builder/.dockerignore | 1 - .github/builder/Dockerfile | 28 +- .github/builder/build.sh | 17 +- .github/workflows/ci.yml | 19 +- scripts/build.sh | 26 +- simics-rs/cargo-simics-build/src/lib.rs | 48 +-- simics-rs/docs/src/SUMMARY.md | 2 +- simics-rs/docs/src/chapter_1.md | 1 - simics-rs/simics-build-utils/src/lib.rs | 166 +++------- simics-rs/simics-macro/src/interface/mod.rs | 20 +- simics-rs/simics-sign/Cargo.toml | 2 +- simics-rs/simics-test/src/lib.rs | 80 ++++- simics-rs/simics/src/api/base/version.rs | 18 -- simics-rs/simics/src/api/internal/core.rs | 3 + simics-rs/simics/src/api/internal/mod.rs | 1 + simics-rs/simics/src/api/logging/mod.rs | 144 --------- simics-rs/simics/src/api/simulator/embed.rs | 20 +- simics-rs/simics/src/api/simulator/mod.rs | 38 ++- .../simics/src/api/simulator/snapshots.rs | 283 ++++++++++++------ src/lib.rs | 191 +++++------- src/util/mod.rs | 3 +- ..._64_kernel_from_userspace_magic_6_0_185.rs | 145 +++++++++ ..._64_kernel_from_userspace_magic_latest.rs} | 5 +- tests/riscv_64_kernel_magic_6_0_185.rs | 76 +++++ ...gic.rs => riscv_64_kernel_magic_latest.rs} | 5 +- tests/riscv_64_userspace_magic_6_0_185.rs | 74 +++++ ....rs => riscv_64_userspace_magic_latest.rs} | 5 +- tests/x86_64_edk2_magic_6_0_185.rs | 76 +++++ ...2_magic.rs => x86_64_edk2_magic_latest.rs} | 5 +- tests/x86_64_edk2_timeout_6_0_185.rs | 76 +++++ ...meout.rs => x86_64_edk2_timeout_latest.rs} | 5 +- tests/x86_64_magic_6_0_185.rs | 76 +++++ tests/x86_64_magic_apitest_6_0_185.rs | 92 ++++++ ...test.rs => x86_64_magic_apitest_latest.rs} | 5 +- tests/x86_64_magic_crash_6_0_185.rs | 76 +++++ ..._crash.rs => x86_64_magic_crash_latest.rs} | 5 +- ...x86_64_magic.rs => x86_64_magic_latest.rs} | 5 +- tests/x86_64_magic_reporting_6_0_185.rs | 78 +++++ ...ng.rs => x86_64_magic_reporting_latest.rs} | 5 +- tests/x86_64_magic_speedtest_6_0_185.rs | 76 +++++ ...st.rs => x86_64_magic_speedtest_latest.rs} | 5 +- ...x86_64_magic_speedtest_tokenize_6_0_185.rs | 77 +++++ ...x86_64_magic_speedtest_tokenize_latest.rs} | 5 +- tests/x86_64_manual_6_0_185.rs | 154 ++++++++++ ...6_64_manual.rs => x86_64_manual_latest.rs} | 5 +- tests/x86_64_manual_max_6_0_185.rs | 151 ++++++++++ ...ual_max.rs => x86_64_manual_max_latest.rs} | 5 +- tests/x86_userspace_magic_6_0_185.rs | 112 +++++++ ...magic.rs => x86_userspace_magic_latest.rs} | 5 +- 50 files changed, 1874 insertions(+), 666 deletions(-) delete mode 100644 .github/builder/.dockerignore delete mode 100644 simics-rs/docs/src/chapter_1.md create mode 100644 tests/riscv_64_kernel_from_userspace_magic_6_0_185.rs rename tests/{riscv_64_kernel_from_userspace_magic.rs => riscv_64_kernel_from_userspace_magic_latest.rs} (93%) create mode 100644 tests/riscv_64_kernel_magic_6_0_185.rs rename tests/{riscv_64_kernel_magic.rs => riscv_64_kernel_magic_latest.rs} (94%) create mode 100644 tests/riscv_64_userspace_magic_6_0_185.rs rename tests/{riscv_64_userspace_magic.rs => riscv_64_userspace_magic_latest.rs} (94%) create mode 100644 tests/x86_64_edk2_magic_6_0_185.rs rename tests/{x86_64_edk2_magic.rs => x86_64_edk2_magic_latest.rs} (94%) create mode 100644 tests/x86_64_edk2_timeout_6_0_185.rs rename tests/{x86_64_edk2_timeout.rs => x86_64_edk2_timeout_latest.rs} (94%) create mode 100644 tests/x86_64_magic_6_0_185.rs create mode 100644 tests/x86_64_magic_apitest_6_0_185.rs rename tests/{x86_64_magic_apitest.rs => x86_64_magic_apitest_latest.rs} (96%) create mode 100644 tests/x86_64_magic_crash_6_0_185.rs rename tests/{x86_64_magic_crash.rs => x86_64_magic_crash_latest.rs} (94%) rename tests/{x86_64_magic.rs => x86_64_magic_latest.rs} (95%) create mode 100644 tests/x86_64_magic_reporting_6_0_185.rs rename tests/{x86_64_magic_reporting.rs => x86_64_magic_reporting_latest.rs} (94%) create mode 100644 tests/x86_64_magic_speedtest_6_0_185.rs rename tests/{x86_64_magic_speedtest.rs => x86_64_magic_speedtest_latest.rs} (94%) create mode 100644 tests/x86_64_magic_speedtest_tokenize_6_0_185.rs rename tests/{x86_64_magic_speedtest_tokenize.rs => x86_64_magic_speedtest_tokenize_latest.rs} (94%) create mode 100644 tests/x86_64_manual_6_0_185.rs rename tests/{x86_64_manual.rs => x86_64_manual_latest.rs} (97%) create mode 100644 tests/x86_64_manual_max_6_0_185.rs rename tests/{x86_64_manual_max.rs => x86_64_manual_max_latest.rs} (97%) create mode 100644 tests/x86_userspace_magic_6_0_185.rs rename tests/{x86_userspace_magic.rs => x86_userspace_magic_latest.rs} (97%) diff --git a/.dockerignore b/.dockerignore index 890d8768..b4175f15 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,15 +1,5 @@ -config.mk -.package-list -.modcache -Dockerfile -.project-properties/ -bin/ -linux64/ -win64/ -packageinfo/ -target/ -documentation -simics -simics-eclipse -simics-gui -compiler.mk +# Ignore dockerfile so re-runs with dockerfile-only fixes don't rebuild +**/Dockerfile +**/target/ +**/*.img +**/*.diff.craff \ No newline at end of file diff --git a/.github/builder/.dockerignore b/.github/builder/.dockerignore deleted file mode 100644 index 1d1fe94d..00000000 --- a/.github/builder/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -Dockerfile \ No newline at end of file diff --git a/.github/builder/Dockerfile b/.github/builder/Dockerfile index bbdef3cd..e0115173 100644 --- a/.github/builder/Dockerfile +++ b/.github/builder/Dockerfile @@ -3,20 +3,15 @@ FROM fedora:20 ENV PATH="${PATH}:/root/.cargo/bin/" -RUN yum -y update && \ - yum -y install \ - coreutils \ - gcc \ - gcc-c++ \ - make && \ - yum clean all - COPY .github/builder/rsrc/rustup-init /install/rustup-init COPY .github/builder/rsrc/make-4.4.1.tar.gz /install/make-4.4.1.tar.gz COPY .github/builder/rsrc/cmake-3.28.0-rc5-linux-x86_64.tar.gz /install/cmake-3.28.0-rc5-linux-x86_64.tar.gz -COPY .github/builder/rsrc/llvm-5.0.2.src.tar.xz /install/llvm-5.0.2.src.tar.xz +COPY .github/builder/rsrc/lld-5.0.2.src.tar.xz /install/lld-5.0.2.src.tar.xz COPY .github/builder/rsrc/cfe-5.0.2.src.tar.xz /install/cfe-5.0.2.src.tar.xz -COPY .github/builder/rsrc/patchelf-0.18.0-x86_64.tar.gz /install/patchelf-0.18.0-x86_64.tar.gz +COPY .github/builder/rsrc/llvm-5.0.2.src.tar.xz /install/llvm-5.0.2.src.tar.xz +COPY .github/builder/rsrc/rpms /install/rpms + +RUN yum -y install /install/rpms/*.rpm && yum clean all RUN chmod +x /install/rustup-init && \ /install/rustup-init -y --default-toolchain nightly && \ @@ -30,8 +25,10 @@ RUN chmod +x /install/rustup-init && \ popd && \ tar -C /usr/local/ --strip-components=1 -xf /install/cmake-3.28.0-rc5-linux-x86_64.tar.gz && \ mkdir -p /llvm/tools/clang && \ + mkdir -p /llvm/tools/lld && \ tar -C /llvm --strip-components=1 -xf /install/llvm-5.0.2.src.tar.xz && \ tar -C /llvm/tools/clang --strip-components=1 -xf /install/cfe-5.0.2.src.tar.xz && \ + tar -C /llvm/tools/lld --strip-components=1 -xf /install/lld-5.0.2.src.tar.xz && \ mkdir -p /llvm/build && \ pushd /llvm/build && \ cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE="MinSizeRel" -DLLVM_TARGETS_TO_BUILD="X86" .. && \ @@ -40,8 +37,7 @@ RUN chmod +x /install/rustup-init && \ make clean && \ rm -rf /llvm/build/ && \ popd && \ - rm -rf /make /llvm && \ - tar -C /usr/local/ --strip-components=1 -xf /install/patchelf-0.18.0-x86_64.tar.gz + rm -rf /make /llvm WORKDIR / @@ -56,9 +52,11 @@ WORKDIR /tsffs/ RUN mkdir -p /simics/ispm && \ tar -C /simics/ispm --strip-components=1 -xf .github/builder/rsrc/ispm.tar.gz && \ ispm settings install-dir /simics && \ - ispm packages --install-bundle .github/builder/rsrc/simics.ispm --non-interactive --trust-insecure-packages && \ - ls -lah /simics/ && \ + ispm packages --install-bundle .github/builder/rsrc/simics.ispm --non-interactive --trust-insecure-packages + +RUN RUSTFLAGS="-C linker=clang -C link-arg=-fuse-ld=$(which ld.lld)" && \ + export RUSTFLAGS && \ cargo install --path simics-rs/cargo-simics-build && \ - cargo simics-build --with-patchelf -r && \ + cargo simics-build -r && \ mkdir -p /packages && \ cp target/release/*.ispm /packages diff --git a/.github/builder/build.sh b/.github/builder/build.sh index f98fd63a..a0b962b5 100755 --- a/.github/builder/build.sh +++ b/.github/builder/build.sh @@ -2,12 +2,12 @@ # NOTE: Do not just copy-paste scripts/build.sh! +LLD_URL="https://releases.llvm.org/5.0.2/lld-5.0.2.src.tar.xz" CFE_URL="https://releases.llvm.org/5.0.2/cfe-5.0.2.src.tar.xz" LLVM_SRC_URL="https://releases.llvm.org/5.0.2/llvm-5.0.2.src.tar.xz" MAKE_SRC_URL="https://ftp.gnu.org/gnu/make/make-4.4.1.tar.gz" RUSTUP_INIT_URL="https://static.rust-lang.org/rustup/dist/x86_64-unknown-linux-gnu/rustup-init" CMAKE_URL="https://github.com/Kitware/CMake/releases/download/v3.28.0-rc5/cmake-3.28.0-rc5-linux-x86_64.tar.gz" -PATCHELF_URL="https://github.com/NixOS/patchelf/releases/download/0.18.0/patchelf-0.18.0-x86_64.tar.gz" PUBLIC_SIMICS_PKGS_URL="https://registrationcenter-download.intel.com/akdlm/IRC_NAS/ead79ef5-28b5-48c7-8d1f-3cde7760798f/simics-6-packages-2024-05-linux64.ispm" PUBLIC_SIMICS_ISPM_URL="https://registrationcenter-download.intel.com/akdlm/IRC_NAS/ead79ef5-28b5-48c7-8d1f-3cde7760798f/intel-simics-package-manager-1.8.3-linux64.tar.gz" PUBLIC_SIMICS_PACKAGE_VERSION_1000="6.0.185" @@ -31,6 +31,11 @@ if [ ! -f "${BUILDER_DIR}/rsrc/simics.ispm" ]; then "${PUBLIC_SIMICS_PKGS_URL}" fi +if [ ! -f "${BUILDER_DIR}/rsrc/lld-5.0.2.src.tar.xz" ]; then + curl --noproxy '*.intel.com' -L -o "${BUILDER_DIR}/rsrc/lld-5.0.2.src.tar.xz" \ + "${LLD_URL}" +fi + if [ ! -f "${BUILDER_DIR}/rsrc/cfe-5.0.2.src.tar.xz" ]; then curl --noproxy '*.intel.com' -L -o "${BUILDER_DIR}/rsrc/cfe-5.0.2.src.tar.xz" \ "${CFE_URL}" @@ -57,9 +62,13 @@ if [ ! -f "${BUILDER_DIR}/rsrc/cmake-3.28.0-rc5-linux-x86_64.tar.gz" ]; then "${CMAKE_URL}" fi -if [ ! -f "${BUILDER_DIR}/rsrc/patchelf-0.18.0-x86_64.tar.gz" ]; then - curl --noproxy '*.intel.com' -L -o "${BUILDER_DIR}/rsrc/patchelf-0.18.0-x86_64.tar.gz" \ - "${PATCHELF_URL}" +if [ ! -d "${BUILDER_DIR}/rsrc/rpms" ]; then + echo "RPM dependencies not found. Downloading..." + # NOTE: This may stop working at some point, as Fedora 20 is EOL. Therefore, we download the + # packages with the expectation that we will provide them separately if they are no longer + # available. + docker run -v "${BUILDER_DIR}/rsrc/rpms:/rpms" fedora:20 bash -c \ + 'yum -y update && yum install --downloadonly --downloaddir=/rpms coreutils gcc gcc-c++ make which && chmod -R 755 /rpms/' fi unset SIMICS_BASE diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bb983519..43e2a801 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,11 +10,11 @@ on: env: CARGO_TERM_COLOR: always CFE_URL: "https://releases.llvm.org/5.0.2/cfe-5.0.2.src.tar.xz" + LLD_URL: "https://releases.llvm.org/5.0.2/lld-5.0.2.src.tar.xz" LLVM_SRC_URL: "https://releases.llvm.org/5.0.2/llvm-5.0.2.src.tar.xz" MAKE_SRC_URL: "https://ftp.gnu.org/gnu/make/make-4.4.1.tar.gz" RUSTUP_INIT_URL: "https://static.rust-lang.org/rustup/dist/x86_64-unknown-linux-gnu/rustup-init" CMAKE_URL: "https://github.com/Kitware/CMake/releases/download/v3.28.0-rc5/cmake-3.28.0-rc5-linux-x86_64.tar.gz" - PATCHELF_URL: "https://github.com/NixOS/patchelf/releases/download/0.18.0/patchelf-0.18.0-x86_64.tar.gz" PUBLIC_SIMICS_PKGS_URL_WINDOWS: "https://registrationcenter-download.intel.com/akdlm/IRC_NAS/ead79ef5-28b5-48c7-8d1f-3cde7760798f/simics-6-packages-2024-05-win64.ispm" # NOTE: We use the old ISPM because there is something wrong with 1.8.3 with unattended installation # PUBLIC_SIMICS_ISPM_URL_WINDOWS: "https://registrationcenter-download.intel.com/akdlm/IRC_NAS/881ee76a-c24d-41c0-af13-5d89b2a857ff/intel-simics-package-manager-1.7.5-win64.exe" @@ -23,11 +23,11 @@ env: PUBLIC_SIMICS_ISPM_URL: "https://registrationcenter-download.intel.com/akdlm/IRC_NAS/ead79ef5-28b5-48c7-8d1f-3cde7760798f/intel-simics-package-manager-1.8.3-linux64.tar.gz" PUBLIC_SIMICS_PACKAGE_VERSION_1000: "6.0.185" PUBLIC_SIMICS_ISPM_VERSION: "1.8.3" + BUILDER_LLD_VERSION: "5.0.2" BUILDER_CFE_VERSION: "5.0.2" BUILDER_LLVM_VERSION: "5.0.2" BUILDER_MAKE_VERSION: "4.4.1" BUILDER_CMAKE_VERSION: "3.28.0-rc5" - BUILDER_PATCHELF_VERSION: "0.18.0" MINGW_URL: "https://github.com/brechtsanders/winlibs_mingw/releases/download/13.2.0-16.0.6-11.0.0-ucrt-r1/winlibs-x86_64-posix-seh-gcc-13.2.0-llvm-16.0.6-mingw-w64ucrt-11.0.0-r1.7z" MINGW_VERSION: "13.2.0-16.0.6-11.0.0-ucrt-r1" @@ -50,7 +50,7 @@ jobs: id: cache-simics-packages uses: actions/cache@v4 with: - path: ~/simics + path: "${HOME}/simics" key: simics-linux-${{ env.PUBLIC_SIMICS_PACKAGE_VERSION_1000 }}-${{ env.PUBLIC_SIMICS_ISPM_VERSION }} - name: Install SIMICS (External) @@ -78,8 +78,7 @@ jobs: run: | mkdir bin && \ cp "${HOME}/simics/simics-${{ env.PUBLIC_SIMICS_PACKAGE_VERSION_1000 }}/linux64/bin/craff" bin/craff && \ - cp "${HOME}/simics/simics-${{ env.PUBLIC_SIMICS_PACKAGE_VERSION_1000 }}/linux64/bin/craff-fs" bin/craff-fs && \ - rm -rf "${HOME}/simics/" + cp "${HOME}/simics/simics-${{ env.PUBLIC_SIMICS_PACKAGE_VERSION_1000 }}/linux64/bin/craff-fs" bin/craff-fs - name: Upload Test Artifacts uses: actions/upload-artifact@v4 @@ -483,7 +482,7 @@ jobs: - name: Test Project run: | - SIMICS_TEST_CLEANUP_EACH=1 SIMICS_TEST_LOCAL_PACKAGES_ONLY=1 cargo test --no-fail-fast -r || ( echo "❗ Tests failed" && exit 1 ) + SIMICS_TEST_CLEANUP_EACH=1 SIMICS_TEST_LOCAL_PACKAGES_ONLY=1 cargo test --no-fail-fast -r _latest || ( echo "❗ Tests failed" && exit 1 ) echo "✅ Tests passed" - name: Build Docs @@ -593,7 +592,7 @@ jobs: uses: actions/cache@v4 with: path: .github/builder/rsrc - key: "cache-builder-dependencies-${{ env.PUBLIC_SIMICS_ISPM_VERSION }}-${{ env.BUILDER_CFE_VERSION }}-${{ env.BUILDER_LLVM_VERSION }}-${{ env.BUILDER_MAKE_VERSION }}-${{ env.BUILDER_CMAKE_VERSION }}" + key: "cache-builder-dependencies-${{ env.PUBLIC_SIMICS_ISPM_VERSION }}-${{ env.BUILDER_LLD_VERSION }}-${{ env.BUILDER_CFE_VERSION }}-${{ env.BUILDER_LLVM_VERSION }}-${{ env.BUILDER_MAKE_VERSION }}-${{ env.BUILDER_CMAKE_VERSION }}" - name: Download Builder Dependencies if: ${{ steps.cache-builder-dependencies.outputs.cache-hit != 'true' }} @@ -605,6 +604,8 @@ jobs: "${{ env.PUBLIC_SIMICS_PKGS_URL }}" curl -L -o .github/builder/rsrc/cfe-5.0.2.src.tar.xz \ "${{ env.CFE_URL }}" + curl -L -o .github/builder/rsrc/lld-5.0.2.src.tar.xz \ + "${{ env.LLD_URL }}" curl -L -o .github/builder/rsrc/llvm-5.0.2.src.tar.xz \ "${{ env.LLVM_SRC_URL }}" curl -L -o .github/builder/rsrc/make-4.4.1.tar.gz \ @@ -614,8 +615,8 @@ jobs: chmod +x .github/builder/rsrc/rustup-init curl -L -o .github/builder/rsrc/cmake-3.28.0-rc5-linux-x86_64.tar.gz \ "${{ env.CMAKE_URL }}" - curl -L -o .github/builder/rsrc/patchelf-0.18.0-x86_64.tar.gz \ - "${{ env.PATCHELF_URL}}" + docker run -v "$(pwd)/.github/builder/rsrc/rpms:/rpms" fedora:20 bash -c \ + 'yum -y update && yum install --downloadonly --downloaddir=/rpms coreutils gcc gcc-c++ make which && chmod -R 755 /rpms/' - name: Build Distribution Package run: | diff --git a/scripts/build.sh b/scripts/build.sh index d0be942d..53f98f2a 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -3,12 +3,13 @@ # Copyright (C) 2024 Intel Corporation # SPDX-License-Identifier: Apache-2.0 + +LLD_URL="https://releases.llvm.org/5.0.2/lld-5.0.2.src.tar.xz" CFE_URL="https://releases.llvm.org/5.0.2/cfe-5.0.2.src.tar.xz" LLVM_SRC_URL="https://releases.llvm.org/5.0.2/llvm-5.0.2.src.tar.xz" MAKE_SRC_URL="https://ftp.gnu.org/gnu/make/make-4.4.1.tar.gz" RUSTUP_INIT_URL="https://static.rust-lang.org/rustup/dist/x86_64-unknown-linux-gnu/rustup-init" CMAKE_URL="https://github.com/Kitware/CMake/releases/download/v3.28.0-rc5/cmake-3.28.0-rc5-linux-x86_64.tar.gz" -PATCHELF_URL="https://github.com/NixOS/patchelf/releases/download/0.18.0/patchelf-0.18.0-x86_64.tar.gz" PUBLIC_SIMICS_PKGS_URL="https://registrationcenter-download.intel.com/akdlm/IRC_NAS/ead79ef5-28b5-48c7-8d1f-3cde7760798f/simics-6-packages-2024-05-linux64.ispm" PUBLIC_SIMICS_ISPM_URL="https://registrationcenter-download.intel.com/akdlm/IRC_NAS/ead79ef5-28b5-48c7-8d1f-3cde7760798f/intel-simics-package-manager-1.8.3-linux64.tar.gz" PUBLIC_SIMICS_PACKAGE_VERSION_1000="6.0.185" @@ -22,44 +23,61 @@ CONTAINER_NAME="${IMAGE_NAME}-tmp-${CONTAINER_UID}" mkdir -p "${BUILDER_DIR}/rsrc" if [ ! -f "${BUILDER_DIR}/rsrc/ispm.tar.gz" ]; then + echo "ISPM not found. Downloading..." curl --noproxy '*.intel.com' -L -o "${BUILDER_DIR}/rsrc/ispm.tar.gz" \ "${PUBLIC_SIMICS_ISPM_URL}" fi if [ ! -f "${BUILDER_DIR}/rsrc/simics.ispm" ]; then + echo "Simics not found. Downloading..." curl --noproxy '*.intel.com' -L -o "${BUILDER_DIR}/rsrc/simics.ispm" \ "${PUBLIC_SIMICS_PKGS_URL}" fi +if [ ! -f "${BUILDER_DIR}/rsrc/lld-5.0.2.src.tar.xz" ]; then + echo "LLD not found. Downloading..." + curl --noproxy '*.intel.com' -L -o "${BUILDER_DIR}/rsrc/lld-5.0.2.src.tar.xz" \ + "${LLD_URL}" +fi + if [ ! -f "${BUILDER_DIR}/rsrc/cfe-5.0.2.src.tar.xz" ]; then + echo "CFE not found. Downloading..." curl --noproxy '*.intel.com' -L -o "${BUILDER_DIR}/rsrc/cfe-5.0.2.src.tar.xz" \ "${CFE_URL}" fi if [ ! -f "${BUILDER_DIR}/rsrc/llvm-5.0.2.src.tar.xz" ]; then + echo "LLVM not found. Downloading..." curl --noproxy '*.intel.com' -L -o "${BUILDER_DIR}/rsrc/llvm-5.0.2.src.tar.xz" \ "${LLVM_SRC_URL}" fi if [ ! -f "${BUILDER_DIR}/rsrc/make-4.4.1.tar.gz" ]; then + echo "Make not found. Downloading..." curl --noproxy '*.intel.com' -L -o "${BUILDER_DIR}/rsrc/make-4.4.1.tar.gz" \ "${MAKE_SRC_URL}" fi if [ ! -f "${BUILDER_DIR}/rsrc/rustup-init" ]; then + echo "rustup not found. Downloading..." curl --noproxy '*.intel.com' -L -o "${BUILDER_DIR}/rsrc/rustup-init" \ "${RUSTUP_INIT_URL}" chmod +x "${BUILDER_DIR}/rsrc/rustup-init" fi if [ ! -f "${BUILDER_DIR}/rsrc/cmake-3.28.0-rc5-linux-x86_64.tar.gz" ]; then + echo "CMake not found. Downloading..." curl --noproxy '*.intel.com' -L -o "${BUILDER_DIR}/rsrc/cmake-3.28.0-rc5-linux-x86_64.tar.gz" \ "${CMAKE_URL}" fi -if [ ! -f "${BUILDER_DIR}/rsrc/patchelf-0.18.0-x86_64.tar.gz" ]; then - curl --noproxy '*.intel.com' -L -o "${BUILDER_DIR}/rsrc/patchelf-0.18.0-x86_64.tar.gz" \ - "${PATCHELF_URL}" +if [ ! -d "${BUILDER_DIR}/rsrc/rpms" ]; then + echo "RPM dependencies not found. Downloading..." + # NOTE: This may stop working at some point, as Fedora 20 is EOL. Therefore, we download the + # packages with the expectation that we will provide them separately if they are no longer + # available. + docker run -v "${BUILDER_DIR}/rsrc/rpms:/rpms" fedora:20 bash -c \ + 'yum -y update && yum install --downloadonly --downloaddir=/rpms coreutils gcc gcc-c++ make which && chmod -R 755 /rpms/' fi unset SIMICS_BASE diff --git a/simics-rs/cargo-simics-build/src/lib.rs b/simics-rs/cargo-simics-build/src/lib.rs index bb670651..234a0c4f 100644 --- a/simics-rs/cargo-simics-build/src/lib.rs +++ b/simics-rs/cargo-simics-build/src/lib.rs @@ -105,8 +105,6 @@ pub enum SimicsBuildCmd { args: Args, #[clap(long)] simics_base: Option, - #[clap(long)] - with_patchelf: bool, }, } @@ -116,11 +114,7 @@ type Result = std::result::Result; impl App { pub fn run(cmd: Cmd) -> Result { - let SimicsBuildCmd::SimicsBuild { - args, - simics_base, - with_patchelf, - } = cmd.simics_build; + let SimicsBuildCmd::SimicsBuild { args, simics_base } = cmd.simics_build; let subcommand = Subcommand::new(args)?; let cargo = var("CARGO")?; @@ -235,46 +229,6 @@ impl App { signed.write(&signed_module_cdylib)?; - signed_module_cdylib = signed_module_cdylib.canonicalize()?; - - if with_patchelf { - // We need to use patchelf to replace absolute paths to shared objects with - // just names - String::from_utf8( - Command::new("patchelf") - .arg("--print-needed") - .arg(&signed_module_cdylib) - .check()? - .stdout, - )? - .lines() - .filter(|l| l.starts_with('/')) - .try_for_each(|l| { - let path = PathBuf::from(l); - let file_name = path - .file_name() - .ok_or_else(|| Error::NoFilename { - path: PathBuf::from(l), - })? - .to_str() - .ok_or_else(|| Error::NoFilename { - path: PathBuf::from(l), - })?; - println!("Replacing needed library {} with {}", l, file_name); - Command::new("patchelf") - .arg("--remove-needed") - .arg(&l) - .arg(&signed_module_cdylib) - .check()?; - Command::new("patchelf") - .arg("--add-needed") - .arg(file_name) - .arg(&signed_module_cdylib) - .check()?; - Ok::<(), Error>(()) - })?; - } - let target_profile_build_dir = subcommand.build_dir(subcommand.target()).join("build"); // Find interfaces diff --git a/simics-rs/docs/src/SUMMARY.md b/simics-rs/docs/src/SUMMARY.md index 7390c828..06ffc046 100644 --- a/simics-rs/docs/src/SUMMARY.md +++ b/simics-rs/docs/src/SUMMARY.md @@ -1,3 +1,3 @@ # Summary -- [Chapter 1](./chapter_1.md) +- [Build Directives](./build-directives.md) diff --git a/simics-rs/docs/src/chapter_1.md b/simics-rs/docs/src/chapter_1.md deleted file mode 100644 index b743fda3..00000000 --- a/simics-rs/docs/src/chapter_1.md +++ /dev/null @@ -1 +0,0 @@ -# Chapter 1 diff --git a/simics-rs/simics-build-utils/src/lib.rs b/simics-rs/simics-build-utils/src/lib.rs index 3abc1523..f8e62aaa 100644 --- a/simics-rs/simics-build-utils/src/lib.rs +++ b/simics-rs/simics-build-utils/src/lib.rs @@ -1,7 +1,7 @@ // Copyright (C) 2024 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -use anyhow::{anyhow, ensure}; +use anyhow::{anyhow, ensure, Result}; use ispm_wrapper::ispm::{self, GlobalOptions}; use std::{ env::var, @@ -9,32 +9,9 @@ use std::{ path::{Path, PathBuf}, }; -/// Configuration indicating that the experimental snapshots API is available (as of -/// 6.0.173) -pub const CFG_SIMICS_EXPERIMENTAL_API_SNAPSHOTS: &str = "simics_experimental_api_snapshots"; -/// Configuration indicating that the experimental snapshots API is available under the -/// new `VT_take_snapshot` API name instead of the original `VT_save_snapshot` API name -/// (as of 6.0.180)) -pub const CFG_SIMICS_EXPERIMENTAL_API_SNAPSHOTS_V2: &str = "simics_experimental_api_snapshots_v2"; -/// Configuration indicating that SIM_log_info is deprecated and should be replaced with -/// VT_log_info until an API update -pub const CFG_SIMICS_DEPRECATED_API_SIM_LOG: &str = "simics_deprecated_api_sim_log"; -/// Configuration indicating that `SIM_register_copyright` is deprecated (as of 7.0.0) -pub const CFG_SIMICS_DEPRECATED_API_SIM_REGISTER_COPYRIGHT: &str = - "simics_deprecated_api_sim_register_copyright"; -/// Configuration indicating that all rev-exec features are deprecated (as of 7.0.0) -pub const CFG_SIMICS_DEPRECATED_API_REV_EXEC: &str = "simics_deprecated_api_rev_exec"; -/// Configuration indicating that the snapshots API has been stabilized and is available under -/// the name `SIM_` instead of `VT_` (as of 7.0.0) -pub const CFG_SIMICS_STABLE_API_SNAPSHOTS: &str = "simics_stable_api_snapshots"; -/// Configuration indicating that the `cpu_variant_t` and `gui_mode_t` command-line options are -/// deprecated (as of 7.0.0) -pub const CFG_SIMICS_DEPRECATED_API_CPU_VARIANT_GUI_MODE: &str = - "simics_deprecated_api_cpu_variant_gui_mode"; - /// Get the only subdirectory of a directory, if only one exists. If zero or more than one subdirectories /// exist, returns an error -pub fn subdir

(dir: P) -> anyhow::Result +pub fn subdir

(dir: P) -> Result where P: AsRef, { @@ -55,73 +32,41 @@ where .ok_or_else(|| anyhow!("No sub-directories found")) } -/// Emit configuration directives used in the build process to conditionally enable -/// features that aren't compatible with all supported SIMICS versions, based on the -/// SIMICS version of the low level bindings. This is not needed for all consumers of the -/// API, but is useful for consumers which need to remain compatible with a wide range of -/// SIMICS base versions. -pub fn emit_cfg_directives() -> anyhow::Result<()> { +/// Emit CFG directives for the version of the Simics API being compiled against. For example, +/// simics_version_6_0_185 and simics_version_6. Both a full triple version and a major version +/// directive is emitted. +/// +/// This function can be used in the `build.rs` script of a crate that depends on the `simics` +/// crate to conditionally enable experimental features in its own code. +pub fn emit_cfg_directives() -> Result<()> { // Set configurations to conditionally enable experimental features that aren't // compatible with all supported SIMICS versions, based on the SIMICS version of the // low level bindings. let simics_api_version = versions::Versioning::new(simics_api_sys::SIMICS_VERSION) - .ok_or_else(|| anyhow::anyhow!("Invalid version {}", simics_api_sys::SIMICS_VERSION))?; - - // Conditional configurations for API versions - - if ::from_str("<6.0.163")? - .matches(&simics_api_version) - { - // Bail out if we are targeting a version before 6.0.163. We don't test any earlier than - // this. - panic!("Target SIMICS API version is too old. The minimum version supported is 6.0.163."); - } - - if ::from_str(">=6.0.177")? - .matches(&simics_api_version) - { - // Deprecate (temporarily) the SIM_log APIs for versions over 6.0.177 (where the API - // was first deprecated) - // NOTE: This will be un-deprecated at an unspecified time in the future - println!("cargo:rustc-cfg={CFG_SIMICS_DEPRECATED_API_SIM_LOG}"); - } - - if ::from_str(">=6.0.173")? - .matches(&simics_api_version) - && ::from_str("<6.0.180")? - .matches(&simics_api_version) - { - // Enable the experimental snapshots api for versions over 6.0.173 (where the API first - // appears) - println!("cargo:rustc-cfg={CFG_SIMICS_EXPERIMENTAL_API_SNAPSHOTS}"); - } + .ok_or_else(|| anyhow!("Invalid version {}", simics_api_sys::SIMICS_VERSION))?; - if ::from_str(">=6.0.180")? - .matches(&simics_api_version) - && ::from_str("<7.0.0")? - .matches(&simics_api_version) - { - // Enable the changed snapshot API (VT_save_snapshot has been renamed to - // VT_take_snapshot) as of 6.0.180 - println!("cargo:rustc-cfg={CFG_SIMICS_EXPERIMENTAL_API_SNAPSHOTS_V2}"); - } + // Exports a configuration directive indicating which Simics version is *compiled* against. + println!( + "cargo:rustc-cfg=simics_version_{}", + simics_api_version.to_string().replace('.', "_") + ); - if ::from_str(">=7.0.0")? - .matches(&simics_api_version) - { - println!("cargo:rustc-cfg={CFG_SIMICS_DEPRECATED_API_SIM_REGISTER_COPYRIGHT}"); - println!("cargo:rustc-cfg={CFG_SIMICS_DEPRECATED_API_REV_EXEC}"); - println!("cargo:rustc-cfg={CFG_SIMICS_STABLE_API_SNAPSHOTS}"); - println!("cargo:rustc-cfg={CFG_SIMICS_DEPRECATED_API_CPU_VARIANT_GUI_MODE}"); - } + println!( + "cargo:rustc-cfg=simics_version_{}", + simics_api_version + .to_string() + .split('.') + .next() + .ok_or_else(|| anyhow!("No major version found"))? + ); Ok(()) } -pub fn emit_link_info() -> anyhow::Result<()> { +pub fn emit_link_info() -> Result<()> { #[cfg(unix)] - const HOST_DIRNAME: &'static str = "linux64"; + const HOST_DIRNAME: &str = "linux64"; #[cfg(not(unix))] const HOST_DIRNAME: &'static str = "win64"; @@ -133,11 +78,6 @@ pub fn emit_link_info() -> anyhow::Result<()> { let mut packages = ispm::packages::list(&GlobalOptions::default())?; - println!( - "cargo:warning=Found {:?} installed packages", - packages.installed_packages - ); - packages.sort(); let Some(installed) = packages.installed_packages.as_ref() else { @@ -151,7 +91,7 @@ pub fn emit_link_info() -> anyhow::Result<()> { println!("cargo:warning=Using Simics base version {}", base.version); base.paths .first() - .ok_or_else(|| anyhow::anyhow!("No paths found for package with package number 1000"))? + .ok_or_else(|| anyhow!("No paths found for package with package number 1000"))? .clone() }; @@ -194,7 +134,7 @@ pub fn emit_link_info() -> anyhow::Result<()> { .map(|p| p.path()) .next() .ok_or_else(|| { - anyhow::anyhow!("No libpythonX.XX.so.X.X found in {}", sys_lib_dir.display()) + anyhow!("No libpythonX.XX.so.X.X found in {}", sys_lib_dir.display()) })?, ); @@ -202,48 +142,45 @@ pub fn emit_link_info() -> anyhow::Result<()> { "cargo:rustc-link-lib=dylib:+verbatim={}", libsimics_common .file_name() - .ok_or_else(|| anyhow::anyhow!( - "No file name found for {}", - libsimics_common.display() - ))? + .ok_or_else(|| anyhow!("No file name found for {}", libsimics_common.display()))? .to_str() - .ok_or_else(|| anyhow::anyhow!("Could not convert path to string"))? + .ok_or_else(|| anyhow!("Could not convert path to string"))? ); println!( "cargo:rustc-link-lib=dylib:+verbatim={}", libvtutils .file_name() - .ok_or_else(|| anyhow::anyhow!("No file name found for {}", libvtutils.display()))? + .ok_or_else(|| anyhow!("No file name found for {}", libvtutils.display()))? .to_str() - .ok_or_else(|| anyhow::anyhow!("Could not convert path to string"))? + .ok_or_else(|| anyhow!("Could not convert path to string"))? ); println!( "cargo:rustc-link-lib=dylib:+verbatim={}", libpython .file_name() - .ok_or_else(|| anyhow::anyhow!("No file name found for {}", libpython.display()))? + .ok_or_else(|| anyhow!("No file name found for {}", libpython.display()))? .to_str() - .ok_or_else(|| anyhow::anyhow!("Could not convert path to string"))? + .ok_or_else(|| anyhow!("Could not convert path to string"))? ); println!( "cargo:rustc-link-search=native={}", bin_dir .to_str() - .ok_or_else(|| anyhow::anyhow!("Could not convert path to string"))? + .ok_or_else(|| anyhow!("Could not convert path to string"))? ); println!( "cargo:rustc-link-search=native={}", sys_lib_dir .to_str() - .ok_or_else(|| anyhow::anyhow!("Could not convert path to string"))? + .ok_or_else(|| anyhow!("Could not convert path to string"))? ); - let ld_library_path = vec![ + let ld_library_path = [ bin_dir .to_str() - .ok_or_else(|| anyhow::anyhow!("Could not convert path to string"))?, + .ok_or_else(|| anyhow!("Could not convert path to string"))?, sys_lib_dir .to_str() - .ok_or_else(|| anyhow::anyhow!("Could not convert path to string"))?, + .ok_or_else(|| anyhow!("Could not convert path to string"))?, ] .join(":"); @@ -335,57 +272,52 @@ pub fn emit_link_info() -> anyhow::Result<()> { }) .map(|p| p.path()) .next() - .ok_or_else(|| { - anyhow::anyhow!("No pythonX.XX.dll found in {}", sys_lib_dir.display()) - })?, + .ok_or_else(|| anyhow!("No pythonX.XX.dll found in {}", sys_lib_dir.display()))?, ); println!( "cargo:rustc-link-lib=dylib:+verbatim={}", libsimics_common .file_name() - .ok_or_else(|| anyhow::anyhow!( - "No file name found for {}", - libsimics_common.display() - ))? + .ok_or_else(|| anyhow!("No file name found for {}", libsimics_common.display()))? .to_str() - .ok_or_else(|| anyhow::anyhow!("Could not convert path to string"))? + .ok_or_else(|| anyhow!("Could not convert path to string"))? ); println!( "cargo:rustc-link-lib=dylib:+verbatim={}", libvtutils .file_name() - .ok_or_else(|| anyhow::anyhow!("No file name found for {}", libvtutils.display()))? + .ok_or_else(|| anyhow!("No file name found for {}", libvtutils.display()))? .to_str() - .ok_or_else(|| anyhow::anyhow!("Could not convert path to string"))? + .ok_or_else(|| anyhow!("Could not convert path to string"))? ); println!( "cargo:rustc-link-lib=dylib:+verbatim={}", libpython .file_name() - .ok_or_else(|| anyhow::anyhow!("No file name found for {}", libpython.display()))? + .ok_or_else(|| anyhow!("No file name found for {}", libpython.display()))? .to_str() - .ok_or_else(|| anyhow::anyhow!("Could not convert path to string"))? + .ok_or_else(|| anyhow!("Could not convert path to string"))? ); println!( "cargo:rustc-link-search=native={}", bin_dir .to_str() - .ok_or_else(|| anyhow::anyhow!("Could not convert path to string"))? + .ok_or_else(|| anyhow!("Could not convert path to string"))? ); println!( "cargo:rustc-link-search=native={}", sys_lib_dir .to_str() - .ok_or_else(|| anyhow::anyhow!("Could not convert path to string"))? + .ok_or_else(|| anyhow!("Could not convert path to string"))? ); let ld_library_path = vec![ bin_dir .to_str() - .ok_or_else(|| anyhow::anyhow!("Could not convert path to string"))?, + .ok_or_else(|| anyhow!("Could not convert path to string"))?, sys_lib_dir .to_str() - .ok_or_else(|| anyhow::anyhow!("Could not convert path to string"))?, + .ok_or_else(|| anyhow!("Could not convert path to string"))?, ] .join(":"); } diff --git a/simics-rs/simics-macro/src/interface/mod.rs b/simics-rs/simics-macro/src/interface/mod.rs index 75e4511b..9776d0e6 100644 --- a/simics-rs/simics-macro/src/interface/mod.rs +++ b/simics-rs/simics-macro/src/interface/mod.rs @@ -1,5 +1,5 @@ use crate::exception::IsResultType; -use command_ext::{CommandExtCheck, CommandExtPrint}; +use command_ext::CommandExtCheck; use darling::{ast::NestedMeta, Error, FromMeta, Result}; use ispm_wrapper::ispm::{self, GlobalOptions}; use proc_macro::TokenStream; @@ -754,7 +754,6 @@ impl CInterface { .join("py-typemaps.c"), ) .arg(interface_subdir.join(&header_name)) - .print_args() .check() .map_err(|e| { Error::custom(format!( @@ -946,7 +945,7 @@ impl CInterface { .arg(interface_subdir.join(&pyifaces_interface_i)) .arg("-o") .arg(interface_subdir.join(pyiface_interface)) - .print_args() + // .print_args() .check() .map_err(|e| Error::custom(format!("Failed to generate pyiface: {e}")))?; @@ -1418,8 +1417,19 @@ pub fn interface_impl(args: TokenStream, input: TokenStream) -> TokenStream { // Get the `name = ""` attribute let input = parse_macro_input!(input as syn::ItemImpl); - if let Err(e) = CInterface::generate(&input, &name) { - return TokenStream::from(e.write_errors()); + // Try three times to generate the interface, with a short delay between each + // attempt. For an unknown reason, disassembly/emission of the pyiface trampolines can fail. + // + // TODO: Disassemble these trampolines and emit the data in a more reliable way. + for i in 0..3 { + if let Err(e) = CInterface::generate(&input, &name) { + if i == 2 { + return TokenStream::from(e.write_errors()); + } + std::thread::sleep(std::time::Duration::from_secs(1)); + } else { + break; + } } let interface = Interface { input, name }; diff --git a/simics-rs/simics-sign/Cargo.toml b/simics-rs/simics-sign/Cargo.toml index 96cabefc..7a7e4d9e 100644 --- a/simics-rs/simics-sign/Cargo.toml +++ b/simics-rs/simics-sign/Cargo.toml @@ -22,6 +22,6 @@ categories = [ ] [dependencies] -object = "0.34.0" +object = "0.35.0" chrono = "0.4.34" thiserror = "1.0.57" diff --git a/simics-rs/simics-test/src/lib.rs b/simics-rs/simics-test/src/lib.rs index b7f8e59a..e43157ad 100644 --- a/simics-rs/simics-test/src/lib.rs +++ b/simics-rs/simics-test/src/lib.rs @@ -103,9 +103,20 @@ pub fn local_or_remote_pkg_install(mut options: InstallOptions) -> Result<()> { let Some(available) = installed.iter().find(|p| { p.package_number == package.package_number - && (Requirement::new(&package.version.to_string()).is_some_and(|r| { - Versioning::new(&p.version).is_some_and(|pv| r.matches(&pv)) - }) || package.version == "latest") + && (Requirement::new(&format!("={}", package.version)) + .or_else(|| { + eprintln!("Failed to parse requirement {}", package.version); + None + }) + .is_some_and(|r| { + Versioning::new(&p.version) + .or_else(|| { + eprintln!("Failed to parse version{}", p.version); + None + }) + .is_some_and(|pv| r.matches(&pv)) + }) + || package.version == "latest") }) else { bail!("Did not find package {package:?} in {installed:?}"); }; @@ -179,6 +190,10 @@ pub struct TestEnvSpec { install_all: bool, #[builder(default, setter(into))] package_crates: Vec, + #[builder(default, setter(into, strip_option))] + build_simics_version: Option, + #[builder(default, setter(into))] + run_simics_version: Option, } impl TestEnvSpec { @@ -205,7 +220,7 @@ pub struct TestEnv { impl TestEnv { /// Return a reference to the test base directory - pub fn simics_base_dir

(simics_home_dir: P) -> Result + pub fn default_simics_base_dir

(simics_home_dir: P) -> Result where P: AsRef, { @@ -226,6 +241,28 @@ impl TestEnv { ) }) } + + /// Return a reference to the base directory specified by a version + pub fn simics_base_dir(version: S, simics_home_dir: P) -> Result + where + P: AsRef, + S: AsRef, + { + read_dir(simics_home_dir.as_ref())? + .filter_map(|d| d.ok()) + .filter(|d| d.path().is_dir()) + .map(|d| d.path()) + .find(|d| { + d.file_name() + .is_some_and(|n| n.to_string_lossy() == format!("simics-{}", version.as_ref())) + }) + .ok_or_else(|| { + anyhow!( + "No simics base in home directory {:?}", + simics_home_dir.as_ref() + ) + }) + } } impl TestEnv { @@ -365,12 +402,27 @@ impl TestEnv { )?; if let Some(installed) = installed.installed_packages { - installed_packages.extend(installed.iter().map(|ip| { - ProjectPackage::builder() - .package_number(ip.package_number) - .version(ip.version.clone()) - .build() - })); + installed_packages.extend( + installed + .iter() + .filter(|ip| { + if ip.package_number == 1000 { + if let Some(run_version) = spec.run_simics_version.as_ref() { + *run_version == ip.version + } else { + true + } + } else { + true + } + }) + .map(|ip| { + ProjectPackage::builder() + .package_number(ip.package_number) + .version(ip.version.clone()) + .build() + }), + ); } } } @@ -410,8 +462,12 @@ impl TestEnv { let cmd = Cmd { simics_build: SimicsBuildCmd::SimicsBuild { args: install_args, - simics_base: Some(Self::simics_base_dir(&simics_home_dir)?), - with_patchelf: false, + simics_base: Some( + spec.build_simics_version + .as_ref() + .map(|v| Self::simics_base_dir(&v, &simics_home_dir)) + .unwrap_or_else(|| Self::default_simics_base_dir(&simics_home_dir))?, + ), }, }; diff --git a/simics-rs/simics/src/api/base/version.rs b/simics-rs/simics/src/api/base/version.rs index dc5e405c..28605ab9 100644 --- a/simics-rs/simics/src/api/base/version.rs +++ b/simics-rs/simics/src/api/base/version.rs @@ -3,14 +3,10 @@ //! SIMICS version access and management APIs -#[cfg(not(simics_deprecated_api_sim_register_copyright))] -use crate::sys::SIM_register_copyright; use crate::{ sys::{SIM_copyright, SIM_version, SIM_version_base, SIM_version_major, SIM_vmxmon_version}, Result, }; -#[cfg(not(simics_deprecated_api_sim_register_copyright))] -use raw_cstr::raw_cstr; use std::ffi::CStr; /// Get the current SIMICS version @@ -67,17 +63,3 @@ pub fn copyright() -> Result { .to_str()? .to_string()) } - -#[cfg(not(simics_deprecated_api_sim_register_copyright))] -/// Set the current copyright string -/// -/// # Contex -/// -/// Global Context -pub fn register_copyright(str: S) -> Result<()> -where - S: AsRef, -{ - unsafe { SIM_register_copyright(raw_cstr(str)?) }; - Ok(()) -} diff --git a/simics-rs/simics/src/api/internal/core.rs b/simics-rs/simics/src/api/internal/core.rs index 5810ee2a..28449211 100644 --- a/simics-rs/simics/src/api/internal/core.rs +++ b/simics-rs/simics/src/api/internal/core.rs @@ -3,13 +3,16 @@ //! Not officially exported CORE APIs +#[cfg(simics_version_6)] use crate::simics_exception; +#[cfg(simics_version_6)] extern "C" { /// Discard recorded future events and forget them pub fn CORE_discard_future(); } +#[cfg(simics_version_6)] #[simics_exception] /// Discard future events that are scheduled /// diff --git a/simics-rs/simics/src/api/internal/mod.rs b/simics-rs/simics/src/api/internal/mod.rs index 269e6fda..9ca8a17d 100644 --- a/simics-rs/simics/src/api/internal/mod.rs +++ b/simics-rs/simics/src/api/internal/mod.rs @@ -4,4 +4,5 @@ //! Internal non-exported APIs pub mod core; +#[allow(unused)] pub use self::core::*; diff --git a/simics-rs/simics/src/api/logging/mod.rs b/simics-rs/simics/src/api/logging/mod.rs index a987b6a3..df0eaee9 100644 --- a/simics-rs/simics/src/api/logging/mod.rs +++ b/simics-rs/simics/src/api/logging/mod.rs @@ -5,11 +5,6 @@ #![allow(clippy::not_unsafe_ptr_arg_deref)] -#[cfg(not(simics_deprecated_api_sim_log))] -use crate::sys::{ - SIM_log_critical, SIM_log_error, SIM_log_info, SIM_log_spec_violation, SIM_log_unimplemented, -}; -#[cfg(simics_deprecated_api_sim_log)] use crate::sys::{ VT_log_critical, VT_log_error, VT_log_info, VT_log_spec_violation, VT_log_unimplemented, }; @@ -46,38 +41,6 @@ where s.as_ref().replace('%', "%%") } -#[cfg(not(simics_deprecated_api_sim_log))] -#[simics_exception] -/// Log an info-level message through the SIMICS logging functions -/// -/// # Arguments -/// -/// * `level` - The level to emit this log message at -/// * `device` - The device to emit this log message through -/// * `msg` - The message to log -/// -/// # Notes -/// -/// The macros [`simics::error`], [`simics::warn`], [`simics::info`], [`simics::debug`], -/// and [`simics::trace`] are more flexible and user friendly. They should be used instead. -/// -/// # Context -/// -/// All Contexts -pub fn log_info(level: LogLevel, device: *mut ConfObject, msg: S) -> Result<()> -where - S: AsRef, -{ - let msg_cstring = CString::new(msg.as_ref())?; - - unsafe { - SIM_log_info(level as i32, device, LOG_GROUP, msg_cstring.as_ptr()); - }; - - Ok(()) -} - -#[cfg(simics_deprecated_api_sim_log)] #[simics_exception] /// Log an info-level message through the SIMICS logging functions /// @@ -108,37 +71,6 @@ where Ok(()) } -#[cfg(not(simics_deprecated_api_sim_log))] -#[simics_exception] -/// Log an info-level message through the SIMICS logging functions -/// -/// # Arguments -/// -/// * `device` - The device to emit this log message through -/// * `msg` - The message to log -/// -/// # Notes -/// -/// The macros [`simics::error`], [`simics::warn`], [`simics::info`], [`simics::debug`], -/// and [`simics::trace`] are more flexible and user friendly. They should be used instead. -/// -/// # Context -/// -/// All Contexts -pub fn log_error(device: *mut ConfObject, msg: S) -> Result<()> -where - S: AsRef, -{ - let msg_cstring = CString::new(sanitize(msg.as_ref()))?; - - unsafe { - SIM_log_error(device, LOG_GROUP, msg_cstring.as_ptr()); - }; - - Ok(()) -} - -#[cfg(simics_deprecated_api_sim_log)] #[simics_exception] /// Log an info-level message through the SIMICS logging functions /// @@ -168,41 +100,6 @@ where Ok(()) } -#[cfg(not(simics_deprecated_api_sim_log))] -#[simics_exception] -/// Log an info-level message through the SIMICS logging functions -/// -/// # Arguments -/// -/// * `device` - The device to emit this log message through -/// * `msg` - The message to log -/// -/// # Notes -/// -/// This function causes a frontend exception. Only use it if the error is truly critical. -/// -/// # Context -/// -/// All Contexts -pub fn log_critical(device: *mut ConfObject, msg: S) -> Result<()> -where - S: AsRef, -{ - let msg_cstring = CString::new(sanitize(msg.as_ref()))?; - - unsafe { - SIM_log_critical(device, LOG_GROUP, msg_cstring.as_ptr()); - }; - - #[cfg(simics_deprecated_api_sim_log)] - unsafe { - VT_log_critical(device, LOG_GROUP as u64, msg_cstring.as_ptr()); - }; - - Ok(()) -} - -#[cfg(simics_deprecated_api_sim_log)] #[simics_exception] /// Log an info-level message through the SIMICS logging functions /// @@ -231,29 +128,6 @@ where Ok(()) } -#[cfg(not(simics_deprecated_api_sim_log))] -#[simics_exception] -/// Log an error-level message through the SIMICS logging functions -/// -/// # Context -/// -/// All Contexts -pub fn log_spec_violation(level: LogLevel, device: *mut ConfObject, msg: String) -> Result<()> { - let msg_cstring = CString::new(sanitize(msg))?; - - unsafe { - SIM_log_spec_violation(level as i32, device, LOG_GROUP, msg_cstring.as_ptr()); - }; - - #[cfg(simics_deprecated_api_sim_log)] - unsafe { - VT_log_spec_violation(level as i32, device, LOG_GROUP as u64, msg_cstring.as_ptr()); - }; - - Ok(()) -} - -#[cfg(simics_deprecated_api_sim_log)] #[simics_exception] /// Log an error-level message through the SIMICS logging functions /// @@ -270,24 +144,6 @@ pub fn log_spec_violation(level: LogLevel, device: *mut ConfObject, msg: String) Ok(()) } -#[cfg(not(simics_deprecated_api_sim_log))] -#[simics_exception] -/// Log an error-level message through the SIMICS logging functions -/// -/// # Context -/// -/// All Contexts -pub fn log_unimplemented(level: LogLevel, device: *mut ConfObject, msg: String) -> Result<()> { - let msg_cstring = CString::new(sanitize(msg))?; - - unsafe { - SIM_log_unimplemented(level as i32, device, LOG_GROUP, msg_cstring.as_ptr()); - }; - - Ok(()) -} - -#[cfg(simics_deprecated_api_sim_log)] #[simics_exception] /// Log an error-level message through the SIMICS logging functions /// diff --git a/simics-rs/simics/src/api/simulator/embed.rs b/simics-rs/simics/src/api/simulator/embed.rs index 22129fc5..05799fa9 100644 --- a/simics-rs/simics/src/api/simulator/embed.rs +++ b/simics-rs/simics/src/api/simulator/embed.rs @@ -4,8 +4,6 @@ //! Functionality for embedding SIMICS into a program or library. These functions are useful for //! creating alternate SIMICS frontends -#[cfg(not(simics_deprecated_api_cpu_variant_gui_mode))] -use crate::sys::{cpu_variant_t, gui_mode_t}; use crate::{ simics_exception, sys::{ @@ -18,23 +16,23 @@ use paste::paste; use raw_cstr::raw_cstr; use std::{mem::forget, ptr::null}; -#[cfg(not(simics_deprecated_api_cpu_variant_gui_mode))] +#[cfg(simics_version_6)] /// Alias for `cpu_variant_t` -pub type CpuVariant = cpu_variant_t; +pub type CpuVariant = crate::sys::cpu_variant_t; -#[cfg(not(simics_deprecated_api_cpu_variant_gui_mode))] +#[cfg(simics_version_6)] #[derive(Debug, Clone)] /// Wrapper for `gui_mode_t` which can be converted to a string -pub struct GuiMode(gui_mode_t); +pub struct GuiMode(crate::sys::gui_mode_t); -#[cfg(not(simics_deprecated_api_cpu_variant_gui_mode))] +#[cfg(simics_version_6)] impl ToString for GuiMode { fn to_string(&self) -> String { match self.0 { - gui_mode_t::GUI_Mode_None => "no-gui", - gui_mode_t::GUI_Mode_Mixed => "mixed", - gui_mode_t::GUI_Mode_Only => "gui", - gui_mode_t::GUI_Mode_Default => "default", + crate::sys::gui_mode_t::GUI_Mode_None => "no-gui", + crate::sys::gui_mode_t::GUI_Mode_Mixed => "mixed", + crate::sys::gui_mode_t::GUI_Mode_Only => "gui", + crate::sys::gui_mode_t::GUI_Mode_Default => "default", } .to_string() } diff --git a/simics-rs/simics/src/api/simulator/mod.rs b/simics-rs/simics/src/api/simulator/mod.rs index 03251bb4..600feab6 100644 --- a/simics-rs/simics/src/api/simulator/mod.rs +++ b/simics-rs/simics/src/api/simulator/mod.rs @@ -16,17 +16,24 @@ pub mod modules; pub mod paths; pub mod processor; pub mod python; -#[cfg(not(simics_deprecated_api_rev_exec))] +#[cfg(simics_version_6)] pub mod rev_exec; pub mod script; pub mod sim_caches; pub mod sim_conf_object; pub mod sim_get_class; -#[cfg(any( - simics_experimental_api_snapshots, - simics_experimental_api_snapshots_v2, - simics_stable_api_snapshots -))] +#[cfg(not(any( + simics_version_6_0_163, + simics_version_6_0_164, + simics_version_6_0_165, + simics_version_6_0_166, + simics_version_6_0_167, + simics_version_6_0_168, + simics_version_6_0_169, + simics_version_6_0_170, + simics_version_6_0_171, + simics_version_6_0_172, +)))] pub mod snapshots; pub use breakpoints::*; @@ -42,15 +49,22 @@ pub use modules::*; pub use paths::*; pub use processor::*; pub use python::*; -#[cfg(not(simics_deprecated_api_rev_exec))] +#[cfg(simics_version_6)] pub use rev_exec::*; pub use script::*; pub use sim_caches::*; pub use sim_conf_object::*; pub use sim_get_class::*; -#[cfg(any( - simics_experimental_api_snapshots, - simics_experimental_api_snapshots_v2, - simics_stable_api_snapshots -))] +#[cfg(not(any( + simics_version_6_0_163, + simics_version_6_0_164, + simics_version_6_0_165, + simics_version_6_0_166, + simics_version_6_0_167, + simics_version_6_0_168, + simics_version_6_0_169, + simics_version_6_0_170, + simics_version_6_0_171, + simics_version_6_0_172, +)))] pub use snapshots::*; diff --git a/simics-rs/simics/src/api/simulator/snapshots.rs b/simics-rs/simics/src/api/simulator/snapshots.rs index eb685d03..9473efa6 100644 --- a/simics-rs/simics/src/api/simulator/snapshots.rs +++ b/simics-rs/simics/src/api/simulator/snapshots.rs @@ -3,206 +3,307 @@ //! Experimental snapshot APIs -#[cfg(all( - simics_experimental_api_snapshots, - not(simics_experimental_api_snapshots_v2), - not(simics_stable_api_snapshots) -))] -// NOTE: This API changes to VT_take_snapshot in simics 6.0.180 -use crate::sys::VT_save_snapshot; - -#[cfg(all(simics_experimental_api_snapshots_v2, not(simics_stable_api_snapshots)))] -// NOTE: This API changed to VT_take_snapshot in simics 6.0.180 and to SIM_take_snapshot in simics 6.0.180 -use crate::sys::{snapshot_error_t, VT_take_snapshot}; - -#[cfg(simics_stable_api_snapshots)] -use crate::sys::{ - SIM_delete_snapshot, SIM_list_snapshots, SIM_restore_snapshot, SIM_take_snapshot, -}; - -#[cfg(any( - simics_experimental_api_snapshots, - simics_experimental_api_snapshots_v2 -))] -use crate::sys::{VT_delete_snapshot, VT_list_snapshots, VT_restore_snapshot}; - -#[cfg(any( - simics_experimental_api_snapshots, - simics_experimental_api_snapshots_v2, - simics_stable_api_snapshots, -))] -use crate::sys::{VT_snapshot_size_used, VT_snapshots_ignore_class}; - -#[cfg(simics_stable_api_snapshots)] -use crate::sys::snapshot_error_t; use crate::{simics_exception, AttrValue, Result}; use raw_cstr::raw_cstr; -#[cfg(any(simics_experimental_api_snapshots_v2, simics_stable_api_snapshots))] -type SnapshotError = snapshot_error_t; +#[cfg(not(any( + simics_version_6_0_163, + simics_version_6_0_164, + simics_version_6_0_165, + simics_version_6_0_166, + simics_version_6_0_167, + simics_version_6_0_168, + simics_version_6_0_169, + simics_version_6_0_170, + simics_version_6_0_171, + simics_version_6_0_172, + simics_version_6_0_173, + simics_version_6_0_174, + simics_version_6_0_175, + simics_version_6_0_176, + simics_version_6_0_177, + simics_version_6_0_178, + simics_version_6_0_179, +)))] +type SnapshotError = crate::sys::snapshot_error_t; -#[cfg(all( - simics_experimental_api_snapshots, - not(simics_experimental_api_snapshots_v2) +#[cfg(simics_version_6_0_173)] +#[simics_exception] +/// Save a snapshot with a name. This function was renamed to +/// `VT_take_snapshot` in version 6.0.180 +pub fn save_snapshot(name: S) -> Result<()> +where + S: AsRef, +{ + Ok(unsafe { crate::sys::VT_save_snapshot(raw_cstr(name)?) }) +} + +#[cfg(any( + simics_version_6_0_174, + simics_version_6_0_175, + simics_version_6_0_176, + simics_version_6_0_177, + simics_version_6_0_178, + simics_version_6_0_179, ))] #[simics_exception] -/// Save a snapshot with a name +/// Save a snapshot with a name. This function was renamed to +/// `VT_take_snapshot` in version 6.0.180 pub fn save_snapshot(name: S) -> Result where S: AsRef, { - Ok(unsafe { VT_save_snapshot(raw_cstr(name)?) }) + Ok(unsafe { crate::sys::VT_save_snapshot(raw_cstr(name)?) }) } -#[cfg(simics_experimental_api_snapshots_v2)] -#[cfg_attr( - any(simics_experimental_api_snapshots, simics_stable_api_snapshots), - deprecated = "Use `take_snapshot` instead" -)] +#[cfg(all( + not(any( + simics_version_6_0_163, + simics_version_6_0_164, + simics_version_6_0_165, + simics_version_6_0_166, + simics_version_6_0_167, + simics_version_6_0_168, + simics_version_6_0_169, + simics_version_6_0_170, + simics_version_6_0_171, + simics_version_6_0_172, + simics_version_6_0_173, + simics_version_6_0_174, + simics_version_6_0_175, + simics_version_6_0_176, + simics_version_6_0_177, + simics_version_6_0_178, + simics_version_6_0_179, + )), + simics_version_6 +))] /// Save a snapshot with a name. API deprecated as of SIMICS 6.0.180 pub fn save_snapshot(name: S) -> Result where S: AsRef, { - Ok(unsafe { VT_take_snapshot(raw_cstr(name)?) }) + Ok(unsafe { crate::sys::VT_take_snapshot(raw_cstr(name)?) }) } -#[cfg(simics_experimental_api_snapshots_v2)] +#[cfg(all( + not(any( + simics_version_6_0_163, + simics_version_6_0_164, + simics_version_6_0_165, + simics_version_6_0_166, + simics_version_6_0_167, + simics_version_6_0_168, + simics_version_6_0_169, + simics_version_6_0_170, + simics_version_6_0_171, + simics_version_6_0_172, + simics_version_6_0_173, + simics_version_6_0_174, + simics_version_6_0_175, + simics_version_6_0_176, + simics_version_6_0_177, + simics_version_6_0_178, + simics_version_6_0_179, + )), + simics_version_6 +))] #[simics_exception] /// Take a snapshot with a name pub fn take_snapshot(name: S) -> Result where S: AsRef, { - Ok(unsafe { VT_take_snapshot(raw_cstr(name)?) }) + Ok(unsafe { crate::sys::VT_take_snapshot(raw_cstr(name)?) }) } -#[cfg(all( - simics_experimental_api_snapshots, - not(simics_experimental_api_snapshots_v2) -))] +#[cfg(simics_version_6_0_173)] #[simics_exception] /// Restore a snapshot with a name -pub fn restore_snapshot(name: S) -> Result +pub fn restore_snapshot(index: i32) -> Result where S: AsRef, { - Ok(unsafe { VT_restore_snapshot(raw_cstr(name)?) }) + Ok(unsafe { crate::sys::VT_restore_snapshot(index) }) } -#[cfg(simics_experimental_api_snapshots_v2)] +#[cfg(all( + not(any( + simics_version_6_0_163, + simics_version_6_0_164, + simics_version_6_0_165, + simics_version_6_0_166, + simics_version_6_0_167, + simics_version_6_0_168, + simics_version_6_0_169, + simics_version_6_0_170, + simics_version_6_0_171, + simics_version_6_0_172, + simics_version_6_0_173, + simics_version_6_0_174, + simics_version_6_0_175, + simics_version_6_0_176, + simics_version_6_0_177, + simics_version_6_0_178, + simics_version_6_0_179, + )), + simics_version_6 +))] #[simics_exception] /// Restore a snapshot with a name pub fn restore_snapshot(name: S) -> Result where S: AsRef, { - Ok(unsafe { VT_restore_snapshot(raw_cstr(name)?) }) + Ok(unsafe { crate::sys::VT_restore_snapshot(raw_cstr(name)?) }) } -#[cfg(all( - simics_experimental_api_snapshots, - not(simics_experimental_api_snapshots_v2) -))] +#[cfg(simics_version_6_0_173)] #[simics_exception] /// Delete a snapshot with a name -pub fn delete_snapshot(name: S) -> Result -where - S: AsRef, -{ - Ok(unsafe { VT_delete_snapshot(raw_cstr(name)?) }) +pub fn delete_snapshot(index: i32) -> Result { + Ok(unsafe { crate::sys::VT_delete_snapshot(index) }) } -#[cfg(simics_experimental_api_snapshots_v2)] +#[cfg(all( + not(any( + simics_version_6_0_163, + simics_version_6_0_164, + simics_version_6_0_165, + simics_version_6_0_166, + simics_version_6_0_167, + simics_version_6_0_168, + simics_version_6_0_169, + simics_version_6_0_170, + simics_version_6_0_171, + simics_version_6_0_172, + simics_version_6_0_173, + simics_version_6_0_174, + simics_version_6_0_175, + simics_version_6_0_176, + simics_version_6_0_177, + simics_version_6_0_178, + simics_version_6_0_179, + )), + simics_version_6 +))] #[simics_exception] /// Delete a snapshot with a name pub fn delete_snapshot(name: S) -> Result where S: AsRef, { - Ok(unsafe { VT_delete_snapshot(raw_cstr(name)?) }) + Ok(unsafe { crate::sys::VT_delete_snapshot(raw_cstr(name)?) }) } -#[cfg(any( - simics_experimental_api_snapshots, - simics_experimental_api_snapshots_v2, - simics_stable_api_snapshots +#[cfg(all( + not(any( + simics_version_6_0_163, + simics_version_6_0_164, + simics_version_6_0_165, + simics_version_6_0_166, + simics_version_6_0_167, + simics_version_6_0_168, + simics_version_6_0_169, + simics_version_6_0_170, + simics_version_6_0_171, + simics_version_6_0_172, + )), + simics_version_6, ))] #[simics_exception] /// Get the total size used by all snapshots pub fn snapshot_size_used() -> AttrValue { - unsafe { VT_snapshot_size_used() }.into() + unsafe { crate::sys::VT_snapshot_size_used() }.into() } -#[cfg(any( - simics_experimental_api_snapshots, - simics_experimental_api_snapshots_v2 +#[cfg(all( + not(any( + simics_version_6_0_163, + simics_version_6_0_164, + simics_version_6_0_165, + simics_version_6_0_166, + simics_version_6_0_167, + simics_version_6_0_168, + simics_version_6_0_169, + simics_version_6_0_170, + simics_version_6_0_171, + simics_version_6_0_172, + )), + simics_version_6, ))] #[simics_exception] /// Get the list of all snapshots pub fn list_snapshots() -> AttrValue { - unsafe { VT_list_snapshots() }.into() + unsafe { crate::sys::VT_list_snapshots() }.into() } -#[cfg(any( - simics_experimental_api_snapshots, - simics_experimental_api_snapshots_v2, - simics_stable_api_snapshots -))] +#[cfg(not(any( + simics_version_6_0_163, + simics_version_6_0_164, + simics_version_6_0_165, + simics_version_6_0_166, + simics_version_6_0_167, + simics_version_6_0_168, + simics_version_6_0_169, + simics_version_6_0_170, + simics_version_6_0_171, + simics_version_6_0_172, +)))] #[simics_exception] /// Set snapshots to ignore a given class by name pub fn snapshots_ignore_class(class_name: S) -> Result<()> where S: AsRef, { - unsafe { VT_snapshots_ignore_class(raw_cstr(class_name)?) }; + unsafe { crate::sys::VT_snapshots_ignore_class(raw_cstr(class_name)?) }; Ok(()) } #[deprecated = "Use `take_snapshot` instead`"] -#[cfg(simics_stable_api_snapshots)] +#[cfg(simics_version_7)] #[simics_exception] /// Take a snapshot with a name pub fn save_snapshot(name: S) -> Result where S: AsRef, { - Ok(unsafe { SIM_take_snapshot(raw_cstr(name)?) }) + Ok(unsafe { crate::sys::SIM_take_snapshot(raw_cstr(name)?) }) } -#[cfg(simics_stable_api_snapshots)] +#[cfg(simics_version_7)] #[simics_exception] /// Take a snapshot with a name pub fn take_snapshot(name: S) -> Result where S: AsRef, { - Ok(unsafe { SIM_take_snapshot(raw_cstr(name)?) }) + Ok(unsafe { crate::sys::SIM_take_snapshot(raw_cstr(name)?) }) } -#[cfg(simics_stable_api_snapshots)] +#[cfg(simics_version_7)] #[simics_exception] /// Restore a snapshot with a name pub fn restore_snapshot(name: S) -> Result where S: AsRef, { - Ok(unsafe { SIM_restore_snapshot(raw_cstr(name)?) }) + Ok(unsafe { crate::sys::SIM_restore_snapshot(raw_cstr(name)?) }) } -#[cfg(simics_stable_api_snapshots)] +#[cfg(simics_version_7)] #[simics_exception] /// Delete a snapshot with a name pub fn delete_snapshot(name: S) -> Result where S: AsRef, { - Ok(unsafe { SIM_delete_snapshot(raw_cstr(name)?) }) + Ok(unsafe { crate::sys::SIM_delete_snapshot(raw_cstr(name)?) }) } -#[cfg(simics_stable_api_snapshots)] +#[cfg(simics_version_7)] #[simics_exception] /// Get the list of all snapshots pub fn list_snapshots() -> AttrValue { - unsafe { SIM_list_snapshots() }.into() + unsafe { crate::sys::SIM_list_snapshots() }.into() } diff --git a/src/lib.rs b/src/lib.rs index 83973db8..e921d32f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -30,7 +30,7 @@ use crate::interfaces::{config::config, fuzz::fuzz}; use crate::state::SolutionKind; -#[cfg(not(simics_deprecated_api_rev_exec))] +#[cfg(simics_version_6)] use crate::util::Utils; use anyhow::{anyhow, Result}; use arch::{Architecture, ArchitectureHint, ArchitectureOperations}; @@ -43,34 +43,24 @@ use magic::MagicNumber; use num_traits::FromPrimitive as _; use serde::{Deserialize, Serialize}; use simics::{ - break_simulation, class, error, free_attribute, get_class, get_interface, get_processor_number, - info, lookup_file, object_clock, run_command, run_python, simics_init, trace, AsConfObject, - BreakpointId, ClassCreate, ClassObjectsFinalize, ConfObject, CoreBreakpointMemopHap, - CoreExceptionHap, CoreMagicInstructionHap, CoreSimulationStoppedHap, + break_simulation, class, debug, error, free_attribute, get_class, get_interface, + get_processor_number, info, lookup_file, object_clock, run_command, run_python, simics_init, + trace, AsConfObject, BreakpointId, ClassCreate, ClassObjectsFinalize, ConfObject, + CoreBreakpointMemopHap, CoreExceptionHap, CoreMagicInstructionHap, CoreSimulationStoppedHap, CpuInstrumentationSubscribeInterface, Event, EventClassFlag, FromConfObject, HapHandle, Interface, IntoAttrValueDict, }; -#[cfg(any( - simics_experimental_api_snapshots, - simics_experimental_api_snapshots_v2, - simics_stable_api_snapshots -))] -// NOTE: save_snapshot used because it is a stable alias for both save_snapshot and take_snapshot -// which is necessary because this module is compatible with base versions which cross the -// deprecation boundary -use simics::{ - debug, restore_snapshot, save_snapshot, sys::save_flags_t, write_configuration_to_file, -}; -#[cfg(not(simics_deprecated_api_rev_exec))] +#[cfg(simics_version_6)] use simics::{ discard_future, restore_micro_checkpoint, save_micro_checkpoint, MicroCheckpointFlags, }; +#[cfg(simics_version_7)] +// NOTE: save_snapshot used because it is a stable alias for both save_snapshot and take_snapshot +// which is necessary because this module is compatible with base versions which cross the +// deprecation boundary +use simics::{restore_snapshot, save_snapshot, sys::save_flags_t, write_configuration_to_file}; use state::StopReason; -#[cfg(any( - simics_experimental_api_snapshots, - simics_experimental_api_snapshots_v2, - simics_stable_api_snapshots -))] +#[cfg(simics_version_7)] use std::fs::remove_dir_all; use std::{ alloc::{alloc_zeroed, Layout}, @@ -265,16 +255,6 @@ pub(crate) struct Tsffs { /// Whether the fuzzer should stop on compiled-in harnesses. If set to `True`, the fuzzer /// will start fuzzing when a harness macro is executed. pub stop_on_harness: bool, - #[class(attribute(optional, default = true))] - /// Whether snapshots should be used. Snapshots are introduced as of Simics 6.0.173 and - /// replace rev-exec micro checkpoints as the only method of taking full simulation - /// snapshots as of Simics 7.0.0. If set to `True`, the fuzzer will use snapshots to - /// restore the state of the simulation to a known state before each iteration. If set to - /// `False` the fuzzer will use rev-exec micro checkpoints to restore the state of the - /// simulation to a known state before each iteration. If snapshots are not supported by - /// the version of SIMICS being used, the fuzzer will quit with an error message when this - /// option is set. - pub use_snapshots: bool, #[class(attribute(optional, default = 0))] /// The index number which is passed to the platform-specific magic instruction HAP /// by a compiled-in harness to signal that the fuzzer should start the fuzzing loop. @@ -670,67 +650,58 @@ impl Tsffs { /// Save the initial snapshot using the configured method (either rev-exec micro checkpoints /// or snapshots) pub fn save_initial_snapshot(&mut self) -> Result<()> { - if self.use_snapshots && self.snapshot_name.get().is_none() { - #[cfg(any( - simics_experimental_api_snapshots, - simics_experimental_api_snapshots_v2, - simics_stable_api_snapshots - ))] - { - if self.checkpoint_path.exists() { - remove_dir_all(&self.checkpoint_path)?; - } + if self.have_initial_snapshot() { + return Ok(()); + } - debug!( - self.as_conf_object(), - "Saving checkpoint to {}", - self.checkpoint_path.display() - ); + #[cfg(simics_version_7)] + { + if self.checkpoint_path.exists() { + remove_dir_all(&self.checkpoint_path)?; + } - if self.pre_snapshot_checkpoint { - write_configuration_to_file(&self.checkpoint_path, save_flags_t(0))?; - } + debug!( + self.as_conf_object(), + "Saving checkpoint to {}", + self.checkpoint_path.display() + ); - save_snapshot(Self::SNAPSHOT_NAME)?; - self.snapshot_name - .set(Self::SNAPSHOT_NAME.to_string()) - .map_err(|_| anyhow!("Snapshot name already set"))?; + if self.pre_snapshot_checkpoint { + write_configuration_to_file(&self.checkpoint_path, save_flags_t(0))?; } - #[cfg(not(any( - simics_experimental_api_snapshots, - simics_experimental_api_snapshots_v2, - simics_stable_api_snapshots - )))] - panic!("Snapshots cannot be used without SIMICS support from recent SIMICS versions."); - } else if !self.use_snapshots - && self.snapshot_name.get().is_none() - && self.micro_checkpoint_index.get().is_none() + + debug!(self.as_conf_object(), "Saving initial snapshot"); + + save_snapshot(Self::SNAPSHOT_NAME)?; + self.snapshot_name + .set(Self::SNAPSHOT_NAME.to_string()) + .map_err(|_| anyhow!("Snapshot name already set"))?; + } + + #[cfg(simics_version_6)] { - #[cfg(not(simics_deprecated_api_rev_exec))] - { - save_micro_checkpoint( - Self::SNAPSHOT_NAME, - MicroCheckpointFlags::Sim_MC_ID_User | MicroCheckpointFlags::Sim_MC_Persistent, - )?; - - self.snapshot_name - .set(Self::SNAPSHOT_NAME.to_string()) - .map_err(|_| anyhow!("Snapshot name already set"))?; - - self.micro_checkpoint_index - .set( - Utils::get_micro_checkpoints()? - .iter() - .enumerate() - .find_map(|(i, c)| (c.name == Self::SNAPSHOT_NAME).then_some(i as i32)) - .ok_or_else(|| { - anyhow!("No micro checkpoint with just-registered name found") - })?, - ) - .map_err(|_| anyhow!("Micro checkpoint index already set"))?; - } - #[cfg(simics_deprecated_api_rev_exec)] - panic!("Micro checkpoints are deprecated in SIMICS >=7.0.0 and cannot be used. Set `use_snapshots` to `true` to use snapshots instead."); + debug!(self.as_conf_object(), "Saving initial micro checkpoint"); + + save_micro_checkpoint( + Self::SNAPSHOT_NAME, + MicroCheckpointFlags::Sim_MC_ID_User | MicroCheckpointFlags::Sim_MC_Persistent, + )?; + + self.snapshot_name + .set(Self::SNAPSHOT_NAME.to_string()) + .map_err(|_| anyhow!("Snapshot name already set"))?; + + self.micro_checkpoint_index + .set( + Utils::get_micro_checkpoints()? + .iter() + .enumerate() + .find_map(|(i, c)| (c.name == Self::SNAPSHOT_NAME).then_some(i as i32)) + .ok_or_else(|| { + anyhow!("No micro checkpoint with just-registered name found") + })?, + ) + .map_err(|_| anyhow!("Micro checkpoint index already set"))?; } Ok(()) @@ -739,30 +710,15 @@ impl Tsffs { /// Restore the initial snapshot using the configured method (either rev-exec micro checkpoints /// or snapshots) pub fn restore_initial_snapshot(&mut self) -> Result<()> { - if self.use_snapshots { - #[cfg(any( - simics_experimental_api_snapshots, - simics_experimental_api_snapshots_v2, - simics_stable_api_snapshots - ))] - restore_snapshot(Self::SNAPSHOT_NAME)?; - #[cfg(not(any( - simics_experimental_api_snapshots, - simics_experimental_api_snapshots_v2, - simics_stable_api_snapshots - )))] - panic!("Snapshots cannot be used without SIMICS support from recent SIMICS versions."); - } else { - #[cfg(not(simics_deprecated_api_rev_exec))] - { - restore_micro_checkpoint(*self.micro_checkpoint_index.get().ok_or_else(|| { - anyhow!("Not using snapshots and no micro checkpoint index present") - })?)?; - discard_future()?; - } + #[cfg(simics_version_7)] + restore_snapshot(Self::SNAPSHOT_NAME)?; + #[cfg(simics_version_6)] + { + restore_micro_checkpoint(*self.micro_checkpoint_index.get().ok_or_else(|| { + anyhow!("Not using snapshots and no micro checkpoint index present") + })?)?; - #[cfg(simics_deprecated_api_rev_exec)] - panic!("Micro checkpoints are deprecated in SIMICS >=7.0.0 and cannot be used. Set `use_snapshots` to `true` to use snapshots instead."); + discard_future()?; } Ok(()) @@ -770,10 +726,15 @@ impl Tsffs { /// Whether an initial snapshot has been saved pub fn have_initial_snapshot(&self) -> bool { - (self.snapshot_name.get().is_some() && self.use_snapshots) - || (self.snapshot_name.get().is_some() - && self.micro_checkpoint_index.get().is_some() - && !self.use_snapshots) + let have = if cfg!(simics_version_7) { + self.snapshot_name.get().is_some() + } else if cfg!(simics_version_6) { + self.snapshot_name.get().is_some() && self.micro_checkpoint_index.get().is_some() + } else { + error!(self.as_conf_object(), "Unsupported SIMICS version"); + false + }; + have } /// Save a repro bookmark if one is needed diff --git a/src/util/mod.rs b/src/util/mod.rs index 8a00be9c..e9d7e94f 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -25,9 +25,10 @@ impl Utils { run_python( r#"print(simics.SIM_get_attribute(simics.SIM_get_object("sim.rexec"), "state_info"))"#, )?; + let checkpoints: Vec = get_attribute(get_object("sim.rexec")?, "state_info")?.try_into()?; - println!("{:?}", checkpoints); + Ok(checkpoints) } } diff --git a/tests/riscv_64_kernel_from_userspace_magic_6_0_185.rs b/tests/riscv_64_kernel_from_userspace_magic_6_0_185.rs new file mode 100644 index 00000000..d53ef132 --- /dev/null +++ b/tests/riscv_64_kernel_from_userspace_magic_6_0_185.rs @@ -0,0 +1,145 @@ +// Copyright (C) 2024 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +use anyhow::Result; +use indoc::indoc; +use ispm_wrapper::data::ProjectPackage; +use simics_test::TestEnvSpec; +use std::path::PathBuf; + +#[test] +#[cfg_attr(miri, ignore)] +fn test_riscv_64_kernel_from_userspace_magic_6_0_185() -> Result<()> { + let output = TestEnvSpec::builder() + .name("test_riscv_64_kernel_from_userspace_magic_6_0_185") + .package_crates([PathBuf::from(env!("CARGO_MANIFEST_DIR"))]) + .packages([ + ProjectPackage::builder() + .package_number(1000) + .version("6.0.185") + .build(), + ProjectPackage::builder() + .package_number(2050) + .version("6.0.60") + .build(), + ProjectPackage::builder() + .package_number(2053) + .version("6.0.4") + .build(), + ]) + .cargo_target_tmpdir(env!("CARGO_TARGET_TMPDIR")) + .directories([PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("tests") + .join("rsrc") + .join("riscv-64")]) + .build() + .to_env()? + .test(indoc! {r#" + load-module tsffs + init-tsffs + + @tsffs.log_level = 4 + @tsffs.start_on_harness = True + @tsffs.stop_on_harness = True + @tsffs.magic_start_index = 1 + @tsffs.magic_stop_indices = [1] + @tsffs.timeout = 3.0 + @tsffs.exceptions = [14] + @tsffs.generate_random_corpus = True + @tsffs.iteration_limit = 1000 + + load-target "risc-v-simple/linux" namespace = riscv machine:hardware:storage:disk1:image = "test.fs.craff" + + script-branch { + bp.time.wait-for seconds = 15 + board.console.con.input "mkdir /mnt/disk0\r\n" + bp.time.wait-for seconds = 1.0 + board.console.con.input "mount /dev/vdb /mnt/disk0\r\n" + bp.time.wait-for seconds = 1.0 + board.console.con.input "insmod /mnt/disk0/test-mod.ko\r\n" + bp.time.wait-for seconds = 1.0 + board.console.con.input "/mnt/disk0/test-mod-userspace\r\n" + } + + script-branch { + bp.time.wait-for seconds = 240 + quit 1 + } + + run + "#})?; + + let output_str = String::from_utf8_lossy(&output.stdout); + + println!("{output_str}"); + + Ok(()) +} + +#[test] +#[cfg_attr(miri, ignore)] +fn test_riscv_64_kernel_magic_6_0_185() -> Result<()> { + let output = TestEnvSpec::builder() + .name("test_riscv_64_kernel_magic_6_0_185") + .package_crates([PathBuf::from(env!("CARGO_MANIFEST_DIR"))]) + .packages([ + ProjectPackage::builder() + .package_number(1000) + .version("6.0.185") + .build(), + ProjectPackage::builder() + .package_number(2050) + .version("6.0.60") + .build(), + ProjectPackage::builder() + .package_number(2053) + .version("6.0.4") + .build(), + ]) + .cargo_target_tmpdir(env!("CARGO_TARGET_TMPDIR")) + .directories([PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("tests") + .join("rsrc") + .join("riscv-64")]) + .build() + .to_env()? + .test(indoc! {r#" + load-module tsffs + init-tsffs + + @tsffs.log_level = 2 + @tsffs.start_on_harness = True + @tsffs.stop_on_harness = True + @tsffs.timeout = 3.0 + @tsffs.exceptions = [14] + @tsffs.generate_random_corpus = True + @tsffs.iteration_limit = 1000 + @tsffs.debug_log_libafl = True + + load-target "risc-v-simple/linux" namespace = riscv machine:hardware:storage:disk1:image = "test.fs.craff" + + script-branch { + bp.time.wait-for seconds = 15 + board.console.con.input "mkdir /mnt/disk0\r\n" + bp.time.wait-for seconds = 1.0 + board.console.con.input "mount /dev/vdb /mnt/disk0\r\n" + bp.time.wait-for seconds = 1.0 + board.console.con.input "insmod /mnt/disk0/test-mod.ko\r\n" + bp.time.wait-for seconds = 1.0 + board.console.con.input "/mnt/disk0/test-mod-userspace\r\n" + } + + script-branch { + bp.time.wait-for seconds = 240 + quit 1 + } + + run + "#})?; + + let output_str = String::from_utf8_lossy(&output.stdout); + + println!("{output_str}"); + + Ok(()) +} diff --git a/tests/riscv_64_kernel_from_userspace_magic.rs b/tests/riscv_64_kernel_from_userspace_magic_latest.rs similarity index 93% rename from tests/riscv_64_kernel_from_userspace_magic.rs rename to tests/riscv_64_kernel_from_userspace_magic_latest.rs index f115f9a3..1c76c6d8 100644 --- a/tests/riscv_64_kernel_from_userspace_magic.rs +++ b/tests/riscv_64_kernel_from_userspace_magic_latest.rs @@ -9,9 +9,9 @@ use std::path::PathBuf; #[test] #[cfg_attr(miri, ignore)] -fn test_riscv_64_kernel_from_userspace_magic() -> Result<()> { +fn test_riscv_64_kernel_from_userspace_magic_latest() -> Result<()> { let output = TestEnvSpec::builder() - .name("test_riscv_64_kernel_from_userspace_magic") + .name("test_riscv_64_kernel_from_userspace_magic_latest") .package_crates([PathBuf::from(env!("CARGO_MANIFEST_DIR"))]) .packages([ ProjectPackage::builder() @@ -47,7 +47,6 @@ fn test_riscv_64_kernel_from_userspace_magic() -> Result<()> { @tsffs.exceptions = [14] @tsffs.generate_random_corpus = True @tsffs.iteration_limit = 1000 - @tsffs.use_snapshots = True load-target "risc-v-simple/linux" namespace = riscv machine:hardware:storage:disk1:image = "test.fs.craff" diff --git a/tests/riscv_64_kernel_magic_6_0_185.rs b/tests/riscv_64_kernel_magic_6_0_185.rs new file mode 100644 index 00000000..435b5fef --- /dev/null +++ b/tests/riscv_64_kernel_magic_6_0_185.rs @@ -0,0 +1,76 @@ +// Copyright (C) 2024 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +use anyhow::Result; +use indoc::indoc; +use ispm_wrapper::data::ProjectPackage; +use simics_test::TestEnvSpec; +use std::path::PathBuf; + +#[test] +#[cfg_attr(miri, ignore)] +fn test_riscv_64_kernel_magic_6_0_185() -> Result<()> { + let output = TestEnvSpec::builder() + .name("test_riscv_64_kernel_magic_6_0_185") + .package_crates([PathBuf::from(env!("CARGO_MANIFEST_DIR"))]) + .packages([ + ProjectPackage::builder() + .package_number(1000) + .version("6.0.185") + .build(), + ProjectPackage::builder() + .package_number(2050) + .version("6.0.60") + .build(), + ProjectPackage::builder() + .package_number(2053) + .version("6.0.4") + .build(), + ]) + .cargo_target_tmpdir(env!("CARGO_TARGET_TMPDIR")) + .directories([PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("tests") + .join("rsrc") + .join("riscv-64")]) + .build() + .to_env()? + .test(indoc! {r#" + load-module tsffs + init-tsffs + + @tsffs.log_level = 2 + @tsffs.start_on_harness = True + @tsffs.stop_on_harness = True + @tsffs.timeout = 3.0 + @tsffs.exceptions = [14] + @tsffs.generate_random_corpus = True + @tsffs.iteration_limit = 1000 + @tsffs.debug_log_libafl = True + + load-target "risc-v-simple/linux" namespace = riscv machine:hardware:storage:disk1:image = "test.fs.craff" + + script-branch { + bp.time.wait-for seconds = 15 + board.console.con.input "mkdir /mnt/disk0\r\n" + bp.time.wait-for seconds = 1.0 + board.console.con.input "mount /dev/vdb /mnt/disk0\r\n" + bp.time.wait-for seconds = 1.0 + board.console.con.input "insmod /mnt/disk0/test-mod.ko\r\n" + bp.time.wait-for seconds = 1.0 + board.console.con.input "/mnt/disk0/test-mod-userspace\r\n" + } + + script-branch { + bp.time.wait-for seconds = 240 + quit 1 + } + + run + "#})?; + + let output_str = String::from_utf8_lossy(&output.stdout); + + println!("{output_str}"); + + Ok(()) +} diff --git a/tests/riscv_64_kernel_magic.rs b/tests/riscv_64_kernel_magic_latest.rs similarity index 94% rename from tests/riscv_64_kernel_magic.rs rename to tests/riscv_64_kernel_magic_latest.rs index 8e94bf1f..225a49c4 100644 --- a/tests/riscv_64_kernel_magic.rs +++ b/tests/riscv_64_kernel_magic_latest.rs @@ -9,9 +9,9 @@ use std::path::PathBuf; #[test] #[cfg_attr(miri, ignore)] -fn test_riscv_64_kernel_magic() -> Result<()> { +fn test_riscv_64_kernel_magic_latest() -> Result<()> { let output = TestEnvSpec::builder() - .name("test_riscv_64_kernel_magic") + .name("test_riscv_64_kernel_magic_latest") .package_crates([PathBuf::from(env!("CARGO_MANIFEST_DIR"))]) .packages([ ProjectPackage::builder() @@ -45,7 +45,6 @@ fn test_riscv_64_kernel_magic() -> Result<()> { @tsffs.exceptions = [14] @tsffs.generate_random_corpus = True @tsffs.iteration_limit = 1000 - @tsffs.use_snapshots = True @tsffs.debug_log_libafl = True load-target "risc-v-simple/linux" namespace = riscv machine:hardware:storage:disk1:image = "test.fs.craff" diff --git a/tests/riscv_64_userspace_magic_6_0_185.rs b/tests/riscv_64_userspace_magic_6_0_185.rs new file mode 100644 index 00000000..df4dabf4 --- /dev/null +++ b/tests/riscv_64_userspace_magic_6_0_185.rs @@ -0,0 +1,74 @@ +// Copyright (C) 2024 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +use anyhow::Result; +use indoc::indoc; +use ispm_wrapper::data::ProjectPackage; +use simics_test::TestEnvSpec; +use std::path::PathBuf; + +#[test] +#[cfg_attr(miri, ignore)] +fn test_riscv_64_userspace_magic_6_0_185() -> Result<()> { + let output = TestEnvSpec::builder() + .name("test_riscv_64_userspace_magic_6_0_185") + .package_crates([PathBuf::from(env!("CARGO_MANIFEST_DIR"))]) + .packages([ + ProjectPackage::builder() + .package_number(1000) + .version("6.0.185") + .build(), + ProjectPackage::builder() + .package_number(2050) + .version("6.0.60") + .build(), + ProjectPackage::builder() + .package_number(2053) + .version("6.0.4") + .build(), + ]) + .cargo_target_tmpdir(env!("CARGO_TARGET_TMPDIR")) + .directories([PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("tests") + .join("rsrc") + .join("riscv-64")]) + .build() + .to_env()? + .test(indoc! {r#" + load-module tsffs + init-tsffs + + @tsffs.log_level = 2 + @tsffs.start_on_harness = True + @tsffs.stop_on_harness = True + @tsffs.timeout = 3.0 + @tsffs.exceptions = [14] + @tsffs.generate_random_corpus = True + @tsffs.iteration_limit = 1000 + + load-target "risc-v-simple/linux" namespace = riscv machine:hardware:storage:disk1:image = "test.fs.craff" + + script-branch { + bp.time.wait-for seconds = 15 + board.console.con.input "mkdir /mnt/disk0\r\n" + bp.time.wait-for seconds = 1.0 + board.console.con.input "mount /dev/vdb /mnt/disk0\r\n" + bp.time.wait-for seconds = 1.0 + board.console.con.capture-start out.txt + board.console.con.input "/mnt/disk0/test\r\n" + } + + script-branch { + bp.time.wait-for seconds = 240 + quit 1 + } + + run + "#})?; + + let output_str = String::from_utf8_lossy(&output.stdout); + + println!("{output_str}"); + + Ok(()) +} diff --git a/tests/riscv_64_userspace_magic.rs b/tests/riscv_64_userspace_magic_latest.rs similarity index 94% rename from tests/riscv_64_userspace_magic.rs rename to tests/riscv_64_userspace_magic_latest.rs index 8436e1b0..9058c137 100644 --- a/tests/riscv_64_userspace_magic.rs +++ b/tests/riscv_64_userspace_magic_latest.rs @@ -9,9 +9,9 @@ use std::path::PathBuf; #[test] #[cfg_attr(miri, ignore)] -fn test_riscv_64_userspace_magic() -> Result<()> { +fn test_riscv_64_userspace_magic_latest() -> Result<()> { let output = TestEnvSpec::builder() - .name("test_riscv_64_userspace_magic") + .name("test_riscv_64_userspace_magic_latest") .package_crates([PathBuf::from(env!("CARGO_MANIFEST_DIR"))]) .packages([ ProjectPackage::builder() @@ -45,7 +45,6 @@ fn test_riscv_64_userspace_magic() -> Result<()> { @tsffs.exceptions = [14] @tsffs.generate_random_corpus = True @tsffs.iteration_limit = 1000 - @tsffs.use_snapshots = True load-target "risc-v-simple/linux" namespace = riscv machine:hardware:storage:disk1:image = "test.fs.craff" diff --git a/tests/x86_64_edk2_magic_6_0_185.rs b/tests/x86_64_edk2_magic_6_0_185.rs new file mode 100644 index 00000000..9ffedf73 --- /dev/null +++ b/tests/x86_64_edk2_magic_6_0_185.rs @@ -0,0 +1,76 @@ +// Copyright (C) 2024 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +use anyhow::Result; +use indoc::indoc; +use ispm_wrapper::data::ProjectPackage; +use simics_test::TestEnvSpec; +use std::path::PathBuf; + +#[test] +#[cfg_attr(miri, ignore)] +fn test_x86_64_edk2_magic_6_0_185() -> Result<()> { + let output = TestEnvSpec::builder() + .name("test_x86_64_edk2_magic_6_0_185") + .package_crates([PathBuf::from(env!("CARGO_MANIFEST_DIR"))]) + .packages([ + ProjectPackage::builder() + .package_number(1000) + .version("6.0.185") + .build(), + ProjectPackage::builder() + .package_number(2096) + .version("6.0.73") + .build(), + ProjectPackage::builder() + .package_number(8112) + .version("6.0.21") + .build(), + ]) + .cargo_target_tmpdir(env!("CARGO_TARGET_TMPDIR")) + .directories([PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("tests") + .join("rsrc") + .join("x86_64-uefi-edk2")]) + .build() + .to_env()? + .test(indoc! {r#" + load-module tsffs + init-tsffs + + @tsffs.log_level = 2 + @tsffs.start_on_harness = True + @tsffs.stop_on_harness = True + @tsffs.timeout = 3.0 + @tsffs.exceptions = [14, 6] + @tsffs.generate_random_corpus = True + @tsffs.iteration_limit = 1000 + + load-target "qsp-x86/uefi-shell" namespace = qsp machine:hardware:storage:disk0:image = "minimal_boot_disk.craff" + + script-branch { + bp.time.wait-for seconds = 15 + qsp.serconsole.con.input "\n" + bp.time.wait-for seconds = .5 + qsp.serconsole.con.input "FS0:\n" + bp.time.wait-for seconds = .5 + local $manager = (start-agent-manager) + qsp.serconsole.con.input ("SimicsAgent.efi --download " + (lookup-file "%simics%/test.efi") + "\n") + bp.time.wait-for seconds = .5 + qsp.serconsole.con.input "test.efi\n" + } + + script-branch { + bp.time.wait-for seconds = 240 + quit 1 + } + + run + "#})?; + + let output_str = String::from_utf8_lossy(&output.stdout); + + println!("{output_str}"); + + Ok(()) +} diff --git a/tests/x86_64_edk2_magic.rs b/tests/x86_64_edk2_magic_latest.rs similarity index 94% rename from tests/x86_64_edk2_magic.rs rename to tests/x86_64_edk2_magic_latest.rs index 25fd0131..9ec3053f 100644 --- a/tests/x86_64_edk2_magic.rs +++ b/tests/x86_64_edk2_magic_latest.rs @@ -9,9 +9,9 @@ use std::path::PathBuf; #[test] #[cfg_attr(miri, ignore)] -fn test_x86_64_edk2_magic() -> Result<()> { +fn test_x86_64_edk2_magic_latest() -> Result<()> { let output = TestEnvSpec::builder() - .name("test_x86_64_edk2_magic") + .name("test_x86_64_edk2_magic_latest") .package_crates([PathBuf::from(env!("CARGO_MANIFEST_DIR"))]) .packages([ ProjectPackage::builder() @@ -45,7 +45,6 @@ fn test_x86_64_edk2_magic() -> Result<()> { @tsffs.exceptions = [14, 6] @tsffs.generate_random_corpus = True @tsffs.iteration_limit = 1000 - @tsffs.use_snapshots = True load-target "qsp-x86/uefi-shell" namespace = qsp machine:hardware:storage:disk0:image = "minimal_boot_disk.craff" diff --git a/tests/x86_64_edk2_timeout_6_0_185.rs b/tests/x86_64_edk2_timeout_6_0_185.rs new file mode 100644 index 00000000..ac44a39d --- /dev/null +++ b/tests/x86_64_edk2_timeout_6_0_185.rs @@ -0,0 +1,76 @@ +// Copyright (C) 2024 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +use anyhow::Result; +use indoc::indoc; +use ispm_wrapper::data::ProjectPackage; +use simics_test::TestEnvSpec; +use std::path::PathBuf; + +#[test] +#[cfg_attr(miri, ignore)] +fn test_x86_64_edk2_timeout_6_0_185() -> Result<()> { + let output = TestEnvSpec::builder() + .name("test_x86_64_edk2_timeout_6_0_185") + .package_crates([PathBuf::from(env!("CARGO_MANIFEST_DIR"))]) + .packages([ + ProjectPackage::builder() + .package_number(1000) + .version("6.0.185") + .build(), + ProjectPackage::builder() + .package_number(2096) + .version("6.0.73") + .build(), + ProjectPackage::builder() + .package_number(8112) + .version("6.0.21") + .build(), + ]) + .cargo_target_tmpdir(env!("CARGO_TARGET_TMPDIR")) + .directories([PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("tests") + .join("rsrc") + .join("x86_64-timeout-uefi-edk2")]) + .build() + .to_env()? + .test(indoc! {r#" + load-module tsffs + init-tsffs + + @tsffs.log_level = 2 + @tsffs.start_on_harness = True + @tsffs.stop_on_harness = True + @tsffs.timeout = 3.0 + @tsffs.exceptions = [14] + @tsffs.generate_random_corpus = True + @tsffs.iteration_limit = 30 + + load-target "qsp-x86/uefi-shell" namespace = qsp machine:hardware:storage:disk0:image = "minimal_boot_disk.craff" + + script-branch { + bp.time.wait-for seconds = 15 + qsp.serconsole.con.input "\n" + bp.time.wait-for seconds = .5 + qsp.serconsole.con.input "FS0:\n" + bp.time.wait-for seconds = .5 + local $manager = (start-agent-manager) + qsp.serconsole.con.input ("SimicsAgent.efi --download " + (lookup-file "%simics%/test.efi") + "\n") + bp.time.wait-for seconds = .5 + qsp.serconsole.con.input "test.efi\n" + } + + script-branch { + bp.time.wait-for seconds = 240 + quit 1 + } + + run + "#})?; + + let output_str = String::from_utf8_lossy(&output.stdout); + + println!("{output_str}"); + + Ok(()) +} diff --git a/tests/x86_64_edk2_timeout.rs b/tests/x86_64_edk2_timeout_latest.rs similarity index 94% rename from tests/x86_64_edk2_timeout.rs rename to tests/x86_64_edk2_timeout_latest.rs index b2306d26..0609a006 100644 --- a/tests/x86_64_edk2_timeout.rs +++ b/tests/x86_64_edk2_timeout_latest.rs @@ -9,9 +9,9 @@ use std::path::PathBuf; #[test] #[cfg_attr(miri, ignore)] -fn test_x86_64_edk2_timeout() -> Result<()> { +fn test_x86_64_edk2_timeout_latest() -> Result<()> { let output = TestEnvSpec::builder() - .name("test_x86_64_edk2_timeout") + .name("test_x86_64_edk2_timeout_latest") .package_crates([PathBuf::from(env!("CARGO_MANIFEST_DIR"))]) .packages([ ProjectPackage::builder() @@ -45,7 +45,6 @@ fn test_x86_64_edk2_timeout() -> Result<()> { @tsffs.exceptions = [14] @tsffs.generate_random_corpus = True @tsffs.iteration_limit = 30 - @tsffs.use_snapshots = True load-target "qsp-x86/uefi-shell" namespace = qsp machine:hardware:storage:disk0:image = "minimal_boot_disk.craff" diff --git a/tests/x86_64_magic_6_0_185.rs b/tests/x86_64_magic_6_0_185.rs new file mode 100644 index 00000000..0743e66a --- /dev/null +++ b/tests/x86_64_magic_6_0_185.rs @@ -0,0 +1,76 @@ +// Copyright (C) 2024 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +use anyhow::Result; +use indoc::indoc; +use ispm_wrapper::data::ProjectPackage; +use simics_test::TestEnvSpec; +use std::path::PathBuf; + +#[test] +#[cfg_attr(miri, ignore)] +fn test_x86_64_magic_6_0_185() -> Result<()> { + let output = TestEnvSpec::builder() + .name("test_x86_64_magic_6_0_185") + .package_crates([PathBuf::from(env!("CARGO_MANIFEST_DIR"))]) + .packages([ + ProjectPackage::builder() + .package_number(1000) + .version("6.0.185") + .build(), + ProjectPackage::builder() + .package_number(2096) + .version("6.0.73") + .build(), + ProjectPackage::builder() + .package_number(8112) + .version("6.0.21") + .build(), + ]) + .cargo_target_tmpdir(env!("CARGO_TARGET_TMPDIR")) + .directories([PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("tests") + .join("rsrc") + .join("x86_64-uefi")]) + .build() + .to_env()? + .test(indoc! {r#" + load-module tsffs + init-tsffs + + @tsffs.log_level = 2 + @tsffs.start_on_harness = True + @tsffs.stop_on_harness = True + @tsffs.timeout = 3.0 + @tsffs.exceptions = [14] + @tsffs.generate_random_corpus = True + @tsffs.iteration_limit = 1000 + + load-target "qsp-x86/uefi-shell" namespace = qsp machine:hardware:storage:disk0:image = "minimal_boot_disk.craff" + + script-branch { + bp.time.wait-for seconds = 15 + qsp.serconsole.con.input "\n" + bp.time.wait-for seconds = .5 + qsp.serconsole.con.input "FS0:\n" + bp.time.wait-for seconds = .5 + local $manager = (start-agent-manager) + qsp.serconsole.con.input ("SimicsAgent.efi --download " + (lookup-file "%simics%/test.efi") + "\n") + bp.time.wait-for seconds = .5 + qsp.serconsole.con.input "test.efi\n" + } + + script-branch { + bp.time.wait-for seconds = 240 + quit 1 + } + + run + "#})?; + + let output_str = String::from_utf8_lossy(&output.stdout); + + println!("{output_str}"); + + Ok(()) +} diff --git a/tests/x86_64_magic_apitest_6_0_185.rs b/tests/x86_64_magic_apitest_6_0_185.rs new file mode 100644 index 00000000..b5fa88d9 --- /dev/null +++ b/tests/x86_64_magic_apitest_6_0_185.rs @@ -0,0 +1,92 @@ +// Copyright (C) 2024 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +use anyhow::Result; +use indoc::indoc; +use ispm_wrapper::data::ProjectPackage; +use simics_test::TestEnvSpec; +use std::path::PathBuf; + +#[test] +#[cfg_attr(miri, ignore)] +fn test_x86_64_magic_apitest_6_0_185() -> Result<()> { + let output = TestEnvSpec::builder() + .name("test_x86_64_magic_apitest_6_0_185") + .package_crates([PathBuf::from(env!("CARGO_MANIFEST_DIR"))]) + .packages([ + ProjectPackage::builder() + .package_number(1000) + .version("6.0.185") + .build(), + ProjectPackage::builder() + .package_number(2096) + .version("6.0.73") + .build(), + ProjectPackage::builder() + .package_number(8112) + .version("6.0.21") + .build(), + ]) + .cargo_target_tmpdir(env!("CARGO_TARGET_TMPDIR")) + .directories([PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("tests") + .join("rsrc") + .join("x86_64-uefi")]) + .build() + .to_env()? + .test(indoc! {r#" + load-module tsffs + init-tsffs + + @tsffs.log_level = 2 + + @tsffs.all_breakpoints_are_solutions = True + @tsffs.all_breakpoints_are_solutions = False + @tsffs.all_exceptions_are_solutions = True + @tsffs.all_exceptions_are_solutions = False + @tsffs.exceptions = [14] + @tsffs.exceptions.remove(14) + @tsffs.exceptions = [14] + @tsffs.breakpoints = [1] + @tsffs.breakpoints.remove(1) + @tsffs.timeout = 3.0 + @tsffs.start_on_harness = True + @tsffs.stop_on_harness = True + @tsffs.iteration_limit = 100 + @tsffs.initial_random_corpus_size = 32 + @tsffs.corpus_directory = SIM_lookup_file("%simics%") + "/corpus" + @tsffs.solutions_directory = SIM_lookup_file("%simics%") + "/solutions" + @tsffs.generate_random_corpus = True + @tsffs.cmplog = True + @tsffs.coverage_reporting = True + @tsffs.token_executables += [SIM_lookup_file("%simics%/test.efi")] + @tsffs.pre_snapshot_checkpoint = False + + load-target "qsp-x86/uefi-shell" namespace = qsp machine:hardware:storage:disk0:image = "minimal_boot_disk.craff" + + script-branch { + bp.time.wait-for seconds = 15 + qsp.serconsole.con.input "\n" + bp.time.wait-for seconds = .5 + qsp.serconsole.con.input "FS0:\n" + bp.time.wait-for seconds = .5 + local $manager = (start-agent-manager) + qsp.serconsole.con.input ("SimicsAgent.efi --download " + (lookup-file "%simics%/test.efi") + "\n") + bp.time.wait-for seconds = .5 + qsp.serconsole.con.input "test.efi\n" + } + + script-branch { + bp.time.wait-for seconds = 240 + quit 1 + } + + run + "#})?; + + let output_str = String::from_utf8_lossy(&output.stdout); + + println!("{output_str}"); + + Ok(()) +} diff --git a/tests/x86_64_magic_apitest.rs b/tests/x86_64_magic_apitest_latest.rs similarity index 96% rename from tests/x86_64_magic_apitest.rs rename to tests/x86_64_magic_apitest_latest.rs index 75534d0a..9ca112a0 100644 --- a/tests/x86_64_magic_apitest.rs +++ b/tests/x86_64_magic_apitest_latest.rs @@ -9,9 +9,9 @@ use std::path::PathBuf; #[test] #[cfg_attr(miri, ignore)] -fn test_x86_64_magic_apitest() -> Result<()> { +fn test_x86_64_magic_apitest_latest() -> Result<()> { let output = TestEnvSpec::builder() - .name("test_x86_64_magic_apitest") + .name("test_x86_64_magic_apitest_latest") .package_crates([PathBuf::from(env!("CARGO_MANIFEST_DIR"))]) .packages([ ProjectPackage::builder() @@ -52,7 +52,6 @@ fn test_x86_64_magic_apitest() -> Result<()> { @tsffs.timeout = 3.0 @tsffs.start_on_harness = True @tsffs.stop_on_harness = True - @tsffs.use_snapshots = True @tsffs.iteration_limit = 100 @tsffs.initial_random_corpus_size = 32 @tsffs.corpus_directory = SIM_lookup_file("%simics%") + "/corpus" diff --git a/tests/x86_64_magic_crash_6_0_185.rs b/tests/x86_64_magic_crash_6_0_185.rs new file mode 100644 index 00000000..f6e2f4db --- /dev/null +++ b/tests/x86_64_magic_crash_6_0_185.rs @@ -0,0 +1,76 @@ +// Copyright (C) 2024 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +use anyhow::Result; +use indoc::indoc; +use ispm_wrapper::data::ProjectPackage; +use simics_test::TestEnvSpec; +use std::path::PathBuf; + +#[test] +#[cfg_attr(miri, ignore)] +fn test_x86_64_magic_crash_6_0_185() -> Result<()> { + let output = TestEnvSpec::builder() + .name("test_x86_64_magic_crash_6_0_185") + .package_crates([PathBuf::from(env!("CARGO_MANIFEST_DIR"))]) + .packages([ + ProjectPackage::builder() + .package_number(1000) + .version("6.0.185") + .build(), + ProjectPackage::builder() + .package_number(2096) + .version("6.0.73") + .build(), + ProjectPackage::builder() + .package_number(8112) + .version("6.0.21") + .build(), + ]) + .cargo_target_tmpdir(env!("CARGO_TARGET_TMPDIR")) + .directories([PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("tests") + .join("rsrc") + .join("x86_64-crash-uefi")]) + .build() + .to_env()? + .test(indoc! {r#" + load-module tsffs + init-tsffs + + @tsffs.log_level = 2 + @tsffs.start_on_harness = True + @tsffs.stop_on_harness = True + @tsffs.timeout = 3.0 + @tsffs.exceptions = [14] + @tsffs.generate_random_corpus = True + @tsffs.iteration_limit = 100 + + load-target "qsp-x86/uefi-shell" namespace = qsp machine:hardware:storage:disk0:image = "minimal_boot_disk.craff" + + script-branch { + bp.time.wait-for seconds = 15 + qsp.serconsole.con.input "\n" + bp.time.wait-for seconds = .5 + qsp.serconsole.con.input "FS0:\n" + bp.time.wait-for seconds = .5 + local $manager = (start-agent-manager) + qsp.serconsole.con.input ("SimicsAgent.efi --download " + (lookup-file "%simics%/test.efi") + "\n") + bp.time.wait-for seconds = .5 + qsp.serconsole.con.input "test.efi\n" + } + + script-branch { + bp.time.wait-for seconds = 240 + quit 1 + } + + run + "#})?; + + let output_str = String::from_utf8_lossy(&output.stdout); + + println!("{output_str}"); + + Ok(()) +} diff --git a/tests/x86_64_magic_crash.rs b/tests/x86_64_magic_crash_latest.rs similarity index 94% rename from tests/x86_64_magic_crash.rs rename to tests/x86_64_magic_crash_latest.rs index 800111a0..fc631923 100644 --- a/tests/x86_64_magic_crash.rs +++ b/tests/x86_64_magic_crash_latest.rs @@ -9,9 +9,9 @@ use std::path::PathBuf; #[test] #[cfg_attr(miri, ignore)] -fn test_x86_64_magic_crash() -> Result<()> { +fn test_x86_64_magic_crash_latest() -> Result<()> { let output = TestEnvSpec::builder() - .name("test_x86_64_magic_crash") + .name("test_x86_64_magic_crash_latest") .package_crates([PathBuf::from(env!("CARGO_MANIFEST_DIR"))]) .packages([ ProjectPackage::builder() @@ -45,7 +45,6 @@ fn test_x86_64_magic_crash() -> Result<()> { @tsffs.exceptions = [14] @tsffs.generate_random_corpus = True @tsffs.iteration_limit = 100 - @tsffs.use_snapshots = True load-target "qsp-x86/uefi-shell" namespace = qsp machine:hardware:storage:disk0:image = "minimal_boot_disk.craff" diff --git a/tests/x86_64_magic.rs b/tests/x86_64_magic_latest.rs similarity index 95% rename from tests/x86_64_magic.rs rename to tests/x86_64_magic_latest.rs index 48726ec3..c61e69f5 100644 --- a/tests/x86_64_magic.rs +++ b/tests/x86_64_magic_latest.rs @@ -9,9 +9,9 @@ use std::path::PathBuf; #[test] #[cfg_attr(miri, ignore)] -fn test_x86_64_magic() -> Result<()> { +fn test_x86_64_magic_latest() -> Result<()> { let output = TestEnvSpec::builder() - .name("test_x86_64_magic") + .name("test_x86_64_magic_latest") .package_crates([PathBuf::from(env!("CARGO_MANIFEST_DIR"))]) .packages([ ProjectPackage::builder() @@ -45,7 +45,6 @@ fn test_x86_64_magic() -> Result<()> { @tsffs.exceptions = [14] @tsffs.generate_random_corpus = True @tsffs.iteration_limit = 1000 - @tsffs.use_snapshots = True load-target "qsp-x86/uefi-shell" namespace = qsp machine:hardware:storage:disk0:image = "minimal_boot_disk.craff" diff --git a/tests/x86_64_magic_reporting_6_0_185.rs b/tests/x86_64_magic_reporting_6_0_185.rs new file mode 100644 index 00000000..13d5bc5f --- /dev/null +++ b/tests/x86_64_magic_reporting_6_0_185.rs @@ -0,0 +1,78 @@ +// Copyright (C) 2024 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +use anyhow::Result; +use indoc::indoc; +use ispm_wrapper::data::ProjectPackage; +use simics_test::TestEnvSpec; +use std::path::PathBuf; + +#[test] +#[cfg_attr(miri, ignore)] +fn test_x86_64_magic_reporting_6_0_185() -> Result<()> { + let output = TestEnvSpec::builder() + .name("test_x86_64_magic_reporting_6_0_185") + .package_crates([PathBuf::from(env!("CARGO_MANIFEST_DIR"))]) + .packages([ + ProjectPackage::builder() + .package_number(1000) + .version("6.0.185") + .build(), + ProjectPackage::builder() + .package_number(2096) + .version("6.0.73") + .build(), + ProjectPackage::builder() + .package_number(8112) + .version("6.0.21") + .build(), + ]) + .cargo_target_tmpdir(env!("CARGO_TARGET_TMPDIR")) + .directories([PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("tests") + .join("rsrc") + .join("x86_64-uefi")]) + .build() + .to_env()? + .test(indoc! {r#" + load-module tsffs + init-tsffs + + @tsffs.log_level = 2 + @tsffs.start_on_harness = True + @tsffs.stop_on_harness = True + @tsffs.timeout = 3.0 + @tsffs.exceptions = [14] + @tsffs.generate_random_corpus = True + @tsffs.iteration_limit = 100 + @tsffs.coverage_reporting = True + @tsffs.corpus_directory = "%simics%/corpus2" + + load-target "qsp-x86/uefi-shell" namespace = qsp machine:hardware:storage:disk0:image = "minimal_boot_disk.craff" + + script-branch { + bp.time.wait-for seconds = 15 + qsp.serconsole.con.input "\n" + bp.time.wait-for seconds = .5 + qsp.serconsole.con.input "FS0:\n" + bp.time.wait-for seconds = .5 + local $manager = (start-agent-manager) + qsp.serconsole.con.input ("SimicsAgent.efi --download " + (lookup-file "%simics%/test-cov.efi") + "\n") + bp.time.wait-for seconds = .5 + qsp.serconsole.con.input "test-cov.efi\n" + } + + script-branch { + bp.time.wait-for seconds = 240 + quit 1 + } + + run + "#})?; + + let output_str = String::from_utf8_lossy(&output.stdout); + + println!("{output_str}"); + + Ok(()) +} diff --git a/tests/x86_64_magic_reporting.rs b/tests/x86_64_magic_reporting_latest.rs similarity index 94% rename from tests/x86_64_magic_reporting.rs rename to tests/x86_64_magic_reporting_latest.rs index f6fb4e70..6086531e 100644 --- a/tests/x86_64_magic_reporting.rs +++ b/tests/x86_64_magic_reporting_latest.rs @@ -9,9 +9,9 @@ use std::path::PathBuf; #[test] #[cfg_attr(miri, ignore)] -fn test_x86_64_magic_reporting() -> Result<()> { +fn test_x86_64_magic_reporting_latest() -> Result<()> { let output = TestEnvSpec::builder() - .name("test_x86_64_magic_reporting") + .name("test_x86_64_magic_reporting_latest") .package_crates([PathBuf::from(env!("CARGO_MANIFEST_DIR"))]) .packages([ ProjectPackage::builder() @@ -45,7 +45,6 @@ fn test_x86_64_magic_reporting() -> Result<()> { @tsffs.exceptions = [14] @tsffs.generate_random_corpus = True @tsffs.iteration_limit = 100 - @tsffs.use_snapshots = True @tsffs.coverage_reporting = True @tsffs.corpus_directory = "%simics%/corpus2" diff --git a/tests/x86_64_magic_speedtest_6_0_185.rs b/tests/x86_64_magic_speedtest_6_0_185.rs new file mode 100644 index 00000000..c8db9065 --- /dev/null +++ b/tests/x86_64_magic_speedtest_6_0_185.rs @@ -0,0 +1,76 @@ +// Copyright (C) 2024 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +use anyhow::Result; +use indoc::indoc; +use ispm_wrapper::data::ProjectPackage; +use simics_test::TestEnvSpec; +use std::path::PathBuf; + +#[test] +#[cfg_attr(miri, ignore)] +fn test_x86_64_magic_speedtest_6_0_185() -> Result<()> { + let output = TestEnvSpec::builder() + .name("test_x86_64_magic_speedtest_6_0_185") + .package_crates([PathBuf::from(env!("CARGO_MANIFEST_DIR"))]) + .packages([ + ProjectPackage::builder() + .package_number(1000) + .version("6.0.185") + .build(), + ProjectPackage::builder() + .package_number(2096) + .version("6.0.73") + .build(), + ProjectPackage::builder() + .package_number(8112) + .version("6.0.21") + .build(), + ]) + .cargo_target_tmpdir(env!("CARGO_TARGET_TMPDIR")) + .directories([PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("tests") + .join("rsrc") + .join("x86_64-uefi")]) + .build() + .to_env()? + .test(indoc! {r#" + load-module tsffs + init-tsffs + + @tsffs.log_level = 2 + @tsffs.start_on_harness = True + @tsffs.stop_on_harness = True + @tsffs.timeout = 3.0 + @tsffs.exceptions = [14] + @tsffs.generate_random_corpus = True + @tsffs.iteration_limit = 1000 + + load-target "qsp-x86/uefi-shell" namespace = qsp machine:hardware:storage:disk0:image = "minimal_boot_disk.craff" + + script-branch { + bp.time.wait-for seconds = 15 + qsp.serconsole.con.input "\n" + bp.time.wait-for seconds = .5 + qsp.serconsole.con.input "FS0:\n" + bp.time.wait-for seconds = .5 + local $manager = (start-agent-manager) + qsp.serconsole.con.input ("SimicsAgent.efi --download " + (lookup-file "%simics%/test-fast.efi") + "\n") + bp.time.wait-for seconds = .5 + qsp.serconsole.con.input "test-fast.efi\n" + } + + script-branch { + bp.time.wait-for seconds = 240 + quit 1 + } + + run + "#})?; + + let output_str = String::from_utf8_lossy(&output.stdout); + + println!("{output_str}"); + + Ok(()) +} diff --git a/tests/x86_64_magic_speedtest.rs b/tests/x86_64_magic_speedtest_latest.rs similarity index 94% rename from tests/x86_64_magic_speedtest.rs rename to tests/x86_64_magic_speedtest_latest.rs index 6cc175ee..abc20772 100644 --- a/tests/x86_64_magic_speedtest.rs +++ b/tests/x86_64_magic_speedtest_latest.rs @@ -9,9 +9,9 @@ use std::path::PathBuf; #[test] #[cfg_attr(miri, ignore)] -fn test_x86_64_magic_speedtest() -> Result<()> { +fn test_x86_64_magic_speedtest_latest() -> Result<()> { let output = TestEnvSpec::builder() - .name("test_x86_64_magic_speedtest") + .name("test_x86_64_magic_speedtest_latest") .package_crates([PathBuf::from(env!("CARGO_MANIFEST_DIR"))]) .packages([ ProjectPackage::builder() @@ -45,7 +45,6 @@ fn test_x86_64_magic_speedtest() -> Result<()> { @tsffs.exceptions = [14] @tsffs.generate_random_corpus = True @tsffs.iteration_limit = 1000 - @tsffs.use_snapshots = True load-target "qsp-x86/uefi-shell" namespace = qsp machine:hardware:storage:disk0:image = "minimal_boot_disk.craff" diff --git a/tests/x86_64_magic_speedtest_tokenize_6_0_185.rs b/tests/x86_64_magic_speedtest_tokenize_6_0_185.rs new file mode 100644 index 00000000..2f1f65d6 --- /dev/null +++ b/tests/x86_64_magic_speedtest_tokenize_6_0_185.rs @@ -0,0 +1,77 @@ +// Copyright (C) 2024 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +use anyhow::Result; +use indoc::indoc; +use ispm_wrapper::data::ProjectPackage; +use simics_test::TestEnvSpec; +use std::path::PathBuf; + +#[test] +#[cfg_attr(miri, ignore)] +fn test_x86_64_magic_speedtest_tokenize_6_0_185() -> Result<()> { + let output = TestEnvSpec::builder() + .name("test_x86_64_magic_speedtest_tokenize_6_0_185") + .package_crates([PathBuf::from(env!("CARGO_MANIFEST_DIR"))]) + .packages([ + ProjectPackage::builder() + .package_number(1000) + .version("6.0.185") + .build(), + ProjectPackage::builder() + .package_number(2096) + .version("6.0.73") + .build(), + ProjectPackage::builder() + .package_number(8112) + .version("6.0.21") + .build(), + ]) + .cargo_target_tmpdir(env!("CARGO_TARGET_TMPDIR")) + .directories([PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("tests") + .join("rsrc") + .join("x86_64-uefi")]) + .build() + .to_env()? + .test(indoc! {r#" + load-module tsffs + init-tsffs + + @tsffs.log_level = 2 + @tsffs.start_on_harness = True + @tsffs.stop_on_harness = True + @tsffs.timeout = 3.0 + @tsffs.exceptions = [14] + @tsffs.generate_random_corpus = True + @tsffs.iteration_limit = 1000 + @tsffs.token_executables += [SIM_lookup_file("%simics%/test-fast.efi")] + + load-target "qsp-x86/uefi-shell" namespace = qsp machine:hardware:storage:disk0:image = "minimal_boot_disk.craff" + + script-branch { + bp.time.wait-for seconds = 15 + qsp.serconsole.con.input "\n" + bp.time.wait-for seconds = .5 + qsp.serconsole.con.input "FS0:\n" + bp.time.wait-for seconds = .5 + local $manager = (start-agent-manager) + qsp.serconsole.con.input ("SimicsAgent.efi --download " + (lookup-file "%simics%/test-fast.efi") + "\n") + bp.time.wait-for seconds = .5 + qsp.serconsole.con.input "test-fast.efi\n" + } + + script-branch { + bp.time.wait-for seconds = 240 + quit 1 + } + + run + "#})?; + + let output_str = String::from_utf8_lossy(&output.stdout); + + println!("{output_str}"); + + Ok(()) +} diff --git a/tests/x86_64_magic_speedtest_tokenize.rs b/tests/x86_64_magic_speedtest_tokenize_latest.rs similarity index 94% rename from tests/x86_64_magic_speedtest_tokenize.rs rename to tests/x86_64_magic_speedtest_tokenize_latest.rs index 714bf429..a1fef52c 100644 --- a/tests/x86_64_magic_speedtest_tokenize.rs +++ b/tests/x86_64_magic_speedtest_tokenize_latest.rs @@ -9,9 +9,9 @@ use std::path::PathBuf; #[test] #[cfg_attr(miri, ignore)] -fn test_x86_64_magic_speedtest_tokenize() -> Result<()> { +fn test_x86_64_magic_speedtest_tokenize_latest() -> Result<()> { let output = TestEnvSpec::builder() - .name("test_x86_64_magic_speedtest_tokenize") + .name("test_x86_64_magic_speedtest_tokenize_latest") .package_crates([PathBuf::from(env!("CARGO_MANIFEST_DIR"))]) .packages([ ProjectPackage::builder() @@ -45,7 +45,6 @@ fn test_x86_64_magic_speedtest_tokenize() -> Result<()> { @tsffs.exceptions = [14] @tsffs.generate_random_corpus = True @tsffs.iteration_limit = 1000 - @tsffs.use_snapshots = True @tsffs.token_executables += [SIM_lookup_file("%simics%/test-fast.efi")] load-target "qsp-x86/uefi-shell" namespace = qsp machine:hardware:storage:disk0:image = "minimal_boot_disk.craff" diff --git a/tests/x86_64_manual_6_0_185.rs b/tests/x86_64_manual_6_0_185.rs new file mode 100644 index 00000000..076edc7c --- /dev/null +++ b/tests/x86_64_manual_6_0_185.rs @@ -0,0 +1,154 @@ +// Copyright (C) 2024 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +use anyhow::Result; +use indoc::indoc; +use ispm_wrapper::data::ProjectPackage; +use simics_test::TestEnvSpec; +use std::path::PathBuf; + +#[test] +#[cfg_attr(miri, ignore)] +fn test_x86_64_manual_6_0_185() -> Result<()> { + let output = TestEnvSpec::builder() + .name("test_x86_64_manual_6_0_185") + .package_crates([PathBuf::from(env!("CARGO_MANIFEST_DIR"))]) + .packages([ + ProjectPackage::builder() + .package_number(1000) + .version("6.0.185") + .build(), + ProjectPackage::builder() + .package_number(1030) + .version("6.0.8") + .build(), + ProjectPackage::builder() + .package_number(2096) + .version("6.0.73") + .build(), + ProjectPackage::builder() + .package_number(8112) + .version("6.0.21") + .build(), + ]) + .cargo_target_tmpdir(env!("CARGO_TARGET_TMPDIR")) + .directories([PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("tests") + .join("rsrc") + .join("x86_64-uefi")]) + .build() + .to_env()? + .test_python(indoc! {r#" + import cli + import simics + + simics.SIM_load_module("tsffs") + + tsffs = simics.SIM_create_object(simics.SIM_get_class("tsffs"), "tsffs", []) + simics.SIM_set_log_level(tsffs, 4) + tsffs.start_on_harness = False + tsffs.stop_on_harness = False + tsffs.timeout = 3.0 + tsffs.exceptions = [14] + tsffs.generate_random_corpus = True + tsffs.iteration_limit = 100 + + simics.SIM_load_target( + "qsp-x86/uefi-shell", # Target + "qsp", # Namespace + [], # Presets + [ # Cmdline args + ["machine:hardware:storage:disk0:image", "minimal_boot_disk.craff"], + ["machine:hardware:processor:class", "x86-goldencove-server"], + ], + ) + + qsp = simics.SIM_get_object("qsp") + + + def on_magic(o, e, r): + if r == 2: + print("Got magic stop...") + tsffs.iface.fuzz.stop() + + + def start_script_branch(): + # Wait for magic start -- in reality this could wait for any + # start condition, but we make it easy on ourselves for testing purposes + print("Waiting for magic start...") + conf.bp.magic.cli_cmds.wait_for(number=1) + print("Got magic start...") + + # In reality, you probably have a known buffer in mind to fuzz + testcase_address_regno = conf.qsp.mb.cpu0.core[0][0].iface.int_register.get_number( + "rsi" + ) + print("testcase address regno: ", testcase_address_regno) + testcase_address = conf.qsp.mb.cpu0.core[0][0].iface.int_register.read( + testcase_address_regno + ) + print("testcase address: ", testcase_address) + size_regno = conf.qsp.mb.cpu0.core[0][0].iface.int_register.get_number("rdx") + print("size regno: ", size_regno) + size_address = conf.qsp.mb.cpu0.core[0][0].iface.int_register.read(size_regno) + print("size address: ", size_address) + virt = False + + print( + "Starting with testcase address", + hex(testcase_address), + "size address", + hex(size_address), + "virt", + virt, + ) + + tsffs.iface.fuzz.start_with_buffer_ptr_size_ptr( + conf.qsp.mb.cpu0.core[0][0], + testcase_address, + size_address, + True, + ) + + + def startup_script_branch(): + cli.global_cmds.wait_for_global_time(seconds=15.0, _relative=True) + qsp.serconsole.con.iface.con_input.input_str("\n") + cli.global_cmds.wait_for_global_time(seconds=1.0, _relative=True) + qsp.serconsole.con.iface.con_input.input_str("FS0:\n") + cli.global_cmds.wait_for_global_time(seconds=1.0, _relative=True) + cli.global_cmds.start_agent_manager() + qsp.serconsole.con.iface.con_input.input_str( + "SimicsAgent.efi --download " + + simics.SIM_lookup_file("%simics%/test.efi") + + "\n" + ) + cli.global_cmds.wait_for_global_time(seconds=3.0, _relative=True) + qsp.serconsole.con.iface.con_input.input_str("test.efi\n") + + + def exit_script_branch(): + cli.global_cmds.wait_for_global_time(seconds=240.0, _relative=True) + simics.SIM_quit(1) + + def on_magic(o, e, r): + if r == 2: + print("Got magic stop...") + tsffs.iface.fuzz.stop() + + simics.SIM_hap_add_callback("Core_Magic_Instruction", on_magic, None) + cli.sb_create(start_script_branch) + cli.sb_create(startup_script_branch) + cli.sb_create(exit_script_branch) + + simics.SIM_continue(0) + # NOTE: If running from CLI, omit this! + simics.SIM_main_loop() + "#})?; + + let output_str = String::from_utf8_lossy(&output.stdout); + + println!("{output_str}"); + + Ok(()) +} diff --git a/tests/x86_64_manual.rs b/tests/x86_64_manual_latest.rs similarity index 97% rename from tests/x86_64_manual.rs rename to tests/x86_64_manual_latest.rs index d6b7d687..4faac108 100644 --- a/tests/x86_64_manual.rs +++ b/tests/x86_64_manual_latest.rs @@ -9,9 +9,9 @@ use std::path::PathBuf; #[test] #[cfg_attr(miri, ignore)] -fn test_x86_64_manual() -> Result<()> { +fn test_x86_64_manual_latest() -> Result<()> { let output = TestEnvSpec::builder() - .name("test_x86_64_manual") + .name("test_x86_64_manual_latest") .package_crates([PathBuf::from(env!("CARGO_MANIFEST_DIR"))]) .packages([ ProjectPackage::builder() @@ -52,7 +52,6 @@ fn test_x86_64_manual() -> Result<()> { tsffs.exceptions = [14] tsffs.generate_random_corpus = True tsffs.iteration_limit = 100 - tsffs.use_snapshots = True simics.SIM_load_target( "qsp-x86/uefi-shell", # Target diff --git a/tests/x86_64_manual_max_6_0_185.rs b/tests/x86_64_manual_max_6_0_185.rs new file mode 100644 index 00000000..8b781d26 --- /dev/null +++ b/tests/x86_64_manual_max_6_0_185.rs @@ -0,0 +1,151 @@ +// Copyright (C) 2024 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +use anyhow::Result; +use indoc::indoc; +use ispm_wrapper::data::ProjectPackage; +use simics_test::TestEnvSpec; +use std::path::PathBuf; + +#[test] +#[cfg_attr(miri, ignore)] +fn test_x86_64_manual_max_6_0_185() -> Result<()> { + let output = TestEnvSpec::builder() + .name("test_x86_64_manual_max_6_0_185") + .package_crates([PathBuf::from(env!("CARGO_MANIFEST_DIR"))]) + .packages([ + ProjectPackage::builder() + .package_number(1000) + .version("6.0.185") + .build(), + ProjectPackage::builder() + .package_number(1030) + .version("6.0.8") + .build(), + ProjectPackage::builder() + .package_number(2096) + .version("6.0.73") + .build(), + ProjectPackage::builder() + .package_number(8112) + .version("6.0.21") + .build(), + ]) + .cargo_target_tmpdir(env!("CARGO_TARGET_TMPDIR")) + .directories([PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("tests") + .join("rsrc") + .join("x86_64-uefi")]) + .build() + .to_env()? + .test_python(indoc! {r#" + import cli + import simics + + simics.SIM_load_module("tsffs") + + tsffs = simics.SIM_create_object(simics.SIM_get_class("tsffs"), "tsffs", []) + simics.SIM_set_log_level(tsffs, 2) + tsffs.start_on_harness = False + tsffs.stop_on_harness = False + tsffs.timeout = 3.0 + tsffs.exceptions = [14] + tsffs.generate_random_corpus = True + tsffs.iteration_limit = 100 + + simics.SIM_load_target( + "qsp-x86/uefi-shell", # Target + "qsp", # Namespace + [], # Presets + [ # Cmdline args + ["machine:hardware:storage:disk0:image", "minimal_boot_disk.craff"], + ["machine:hardware:processor:class", "x86-goldencove-server"], + ], + ) + + qsp = simics.SIM_get_object("qsp") + + + def on_magic(o, e, r): + if r == 2: + print("Got magic stop...") + tsffs.iface.fuzz.stop() + + + def start_script_branch(): + # Wait for magic start -- in reality this could wait for any + # start condition, but we make it easy on ourselves for testing purposes + print("Waiting for magic start...") + conf.bp.magic.cli_cmds.wait_for(number=1) + print("Got magic start...") + + # In reality, you probably have a known buffer in mind to fuzz + testcase_address_regno = conf.qsp.mb.cpu0.core[0][0].iface.int_register.get_number( + "rsi" + ) + print("testcase address regno: ", testcase_address_regno) + testcase_address = conf.qsp.mb.cpu0.core[0][0].iface.int_register.read( + testcase_address_regno + ) + print("testcase address: ", testcase_address) + maximum_size = 8 + virt = True + + print( + "Starting with testcase address", + hex(testcase_address), + "maximum_size", + hex(maximum_size), + "virt", + virt, + ) + + tsffs.iface.fuzz.start_with_buffer_ptr_size_value( + conf.qsp.mb.cpu0.core[0][0], + testcase_address, + maximum_size, + virt, + ) + + + def startup_script_branch(): + cli.global_cmds.wait_for_global_time(seconds=15.0, _relative=True) + qsp.serconsole.con.iface.con_input.input_str("\n") + cli.global_cmds.wait_for_global_time(seconds=1.0, _relative=True) + qsp.serconsole.con.iface.con_input.input_str("FS0:\n") + cli.global_cmds.wait_for_global_time(seconds=1.0, _relative=True) + cli.global_cmds.start_agent_manager() + qsp.serconsole.con.iface.con_input.input_str( + "SimicsAgent.efi --download " + + simics.SIM_lookup_file("%simics%/test.efi") + + "\n" + ) + cli.global_cmds.wait_for_global_time(seconds=3.0, _relative=True) + qsp.serconsole.con.iface.con_input.input_str("test.efi\n") + + + def exit_script_branch(): + cli.global_cmds.wait_for_global_time(seconds=240.0, _relative=True) + simics.SIM_quit(1) + + def on_magic(o, e, r): + if r == 2: + print("Got magic stop...") + tsffs.iface.fuzz.stop() + + simics.SIM_hap_add_callback("Core_Magic_Instruction", on_magic, None) + cli.sb_create(start_script_branch) + cli.sb_create(startup_script_branch) + cli.sb_create(exit_script_branch) + + simics.SIM_continue(0) + # NOTE: If running from CLI, omit this! + simics.SIM_main_loop() + "#})?; + + let output_str = String::from_utf8_lossy(&output.stdout); + + println!("{output_str}"); + + Ok(()) +} diff --git a/tests/x86_64_manual_max.rs b/tests/x86_64_manual_max_latest.rs similarity index 97% rename from tests/x86_64_manual_max.rs rename to tests/x86_64_manual_max_latest.rs index bb3f307e..061e387c 100644 --- a/tests/x86_64_manual_max.rs +++ b/tests/x86_64_manual_max_latest.rs @@ -9,9 +9,9 @@ use std::path::PathBuf; #[test] #[cfg_attr(miri, ignore)] -fn test_x86_64_manual_max() -> Result<()> { +fn test_x86_64_manual_max_latest() -> Result<()> { let output = TestEnvSpec::builder() - .name("test_x86_64_manual_max") + .name("test_x86_64_manual_max_latest") .package_crates([PathBuf::from(env!("CARGO_MANIFEST_DIR"))]) .packages([ ProjectPackage::builder() @@ -52,7 +52,6 @@ fn test_x86_64_manual_max() -> Result<()> { tsffs.exceptions = [14] tsffs.generate_random_corpus = True tsffs.iteration_limit = 100 - tsffs.use_snapshots = True simics.SIM_load_target( "qsp-x86/uefi-shell", # Target diff --git a/tests/x86_userspace_magic_6_0_185.rs b/tests/x86_userspace_magic_6_0_185.rs new file mode 100644 index 00000000..a5ff030a --- /dev/null +++ b/tests/x86_userspace_magic_6_0_185.rs @@ -0,0 +1,112 @@ +// Copyright (C) 2024 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +use anyhow::Result; +use indoc::indoc; +use ispm_wrapper::data::ProjectPackage; +use simics_test::TestEnvSpec; +use std::path::PathBuf; + +#[test] +#[cfg_attr(miri, ignore)] +fn test_x86_userspace_6_0_185() -> Result<()> { + let output = TestEnvSpec::builder() + .name("test_x86_userspace_6_0_185") + .package_crates([PathBuf::from(env!("CARGO_MANIFEST_DIR"))]) + .packages([ + ProjectPackage::builder() + .package_number(1000) + .version("6.0.185") + .build(), + ProjectPackage::builder() + .package_number(2096) + .version("6.0.73") + .build(), + ProjectPackage::builder() + .package_number(8112) + .version("6.0.21") + .build(), + ProjectPackage::builder() + .package_number(1030) + .version("6.0.8") + .build(), + ProjectPackage::builder() + .package_number(4094) + .version("6.0.15") + .build(), + ]) + .cargo_target_tmpdir(env!("CARGO_TARGET_TMPDIR")) + .directories([PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("tests") + .join("rsrc") + .join("x86-user")]) + .build() + .to_env()? + .test_python(indoc! {r#" + import cli + import simics + + simics.SIM_load_module("tsffs") + + tsffs = simics.SIM_create_object(simics.SIM_get_class("tsffs"), "tsffs", []) + simics.SIM_set_log_level(tsffs, 2) + tsffs.start_on_harness = True + tsffs.stop_on_harness = True + tsffs.timeout = 3.0 + tsffs.generate_random_corpus = True + tsffs.iteration_limit = 100 + + simics.SIM_load_target( + "qsp-x86/clear-linux", # target + "qsp", # namespace + [], # presets + [["machine:hardware:storage:disk1:image", "test.fs.craff"]], + ) + + qsp = simics.SIM_get_object("qsp") + + tsffs.iface.config.add_architecture_hint(qsp.mb.cpu0.core[0][0], "i386") + + + # when we're running userspace code, we don't want to catch exeptions until + # we actually start fuzzing, including gpfs on other code. we can wait to + # enable the exception until later (we could even toggle it on and off per + # iteration) + def on_magic(o, e, r): + # wait for magic stop -- in reality this could wait for any stop + # condition, but we make it easy on ourselves for testing purposes + if r == 1: + tsffs.exceptions = [13] + + + def startup_script_branch(): + cli.global_cmds.wait_for_global_time(seconds=20.0, _relative=True) + qsp.serconsole.con.iface.con_input.input_str("sudo mkdir /disk0/\n") + cli.global_cmds.wait_for_global_time(seconds=1.0, _relative=True) + qsp.serconsole.con.iface.con_input.input_str("sudo mount /dev/sdb /disk0/\n") + cli.global_cmds.wait_for_global_time(seconds=1.0, _relative=True) + qsp.serconsole.con.iface.con_input.input_str("ls /disk0\n") + cli.global_cmds.wait_for_global_time(seconds=1.0, _relative=True) + qsp.serconsole.con.iface.con_input.input_str("/disk0/test\n") + + + def exit_script_branch(): + cli.global_cmds.wait_for_global_time(seconds=240.0, _relative=True) + simics.SIM_quit(1) + + + simics.SIM_hap_add_callback("Core_Magic_Instruction", on_magic, None) + cli.sb_create(startup_script_branch) + cli.sb_create(exit_script_branch) + + simics.SIM_continue(0) + # note: if running from cli, omit this! + simics.SIM_main_loop() + "#})?; + + let output_str = String::from_utf8_lossy(&output.stdout); + + println!("{output_str}"); + + Ok(()) +} diff --git a/tests/x86_userspace_magic.rs b/tests/x86_userspace_magic_latest.rs similarity index 97% rename from tests/x86_userspace_magic.rs rename to tests/x86_userspace_magic_latest.rs index 41f37864..0de060a1 100644 --- a/tests/x86_userspace_magic.rs +++ b/tests/x86_userspace_magic_latest.rs @@ -9,9 +9,9 @@ use std::path::PathBuf; #[test] #[cfg_attr(miri, ignore)] -fn test_x86_userspace() -> Result<()> { +fn test_x86_userspace_latest() -> Result<()> { let output = TestEnvSpec::builder() - .name("test_x86_userspace") + .name("test_x86_userspace_latest") .package_crates([PathBuf::from(env!("CARGO_MANIFEST_DIR"))]) .packages([ ProjectPackage::builder() @@ -55,7 +55,6 @@ fn test_x86_userspace() -> Result<()> { tsffs.timeout = 3.0 tsffs.generate_random_corpus = True tsffs.iteration_limit = 100 - tsffs.use_snapshots = True simics.SIM_load_target( "qsp-x86/clear-linux", # target