diff --git a/.github/actions/prepare-llvm-cache/action.yml b/.github/actions/prepare-llvm-cache/action.yml new file mode 100644 index 0000000..180667b --- /dev/null +++ b/.github/actions/prepare-llvm-cache/action.yml @@ -0,0 +1,65 @@ +name: Prepare LLVM Cache +description: Restore or build the cached LLVM toolchain. + +inputs: + llvm-commit: + description: LLVM commit to build. + required: true + +runs: + using: composite + steps: + + - name: Restore LLVM Repository Cache + id: restore-llvm-project-cache + uses: actions/cache/restore@v4 + with: + path: ${{ github.workspace }}/llvm-project/ + key: llvm-project-${{ runner.os }}-${{ inputs.llvm-commit }} + + - name: Clone LLVM + if: steps.restore-llvm-project-cache.outputs.cache-hit != 'true' + shell: bash + run: | + git clone --filter=blob:none --no-checkout https://github.com/llvm/llvm-project.git llvm-project + cd llvm-project + git fetch --depth 1 origin ${{ inputs.llvm-commit }} + git checkout FETCH_HEAD + + - name: Save LLVM Project Cache + if: steps.restore-llvm-project-cache.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 + with: + path: ${{ github.workspace }}/llvm-project/ + key: llvm-project-${{ runner.os }}-${{ inputs.llvm-commit }} + + + - name: Restore LLVM Build Cache + id: restore-llvm-cache + uses: actions/cache/restore@v4 + with: + path: ${{ github.workspace }}/llvm-build/ + key: llvm-${{ runner.os }}-${{ inputs.llvm-commit }} + + - name: Build LLVM + if: steps.restore-llvm-cache.outputs.cache-hit != 'true' + shell: bash + working-directory: ${{ github.workspace }}/llvm-project + run: | + builddir="${{ github.workspace }}/llvm-build/" + cmake -G Ninja \ + -B "$builddir" \ + -S llvm \ + -DLLVM_ENABLE_PROJECTS="clang" \ + -DCMAKE_BUILD_TYPE=Release \ + -DLLVM_ENABLE_ASSERTIONS=OFF \ + -DLLDB_INCLUDE_TESTS=OFF \ + -DLIBCLC_TARGETS_TO_BUILD="RISCV;X86" + cmake --build "$builddir" + + - name: Save LLVM Build Cache + if: steps.restore-llvm-cache.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 + with: + path: ${{ github.workspace }}/llvm-build/ + key: llvm-${{ runner.os }}-${{ inputs.llvm-commit }} \ No newline at end of file diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7f2129c..53482fc 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,4 +1,13 @@ name: ASPIS main CI +env: + LLVM_COMMIT: 2078da43e25a4623cab2d0d60decddf709aaea28 # llvmorg-21.1.8 + CMAKE_VERSION: 4.3.0 + MOLD_LINKER_FLAGS: -fuse-ld=mold + CCACHE_DIR: ${{ github.workspace }}/.ccache + CCACHE_MAXSIZE: 10G + CCACHE_BASEDIR: ${{ github.workspace }} + CCACHE_COMPILERCHECK: content + CCACHE_NOHASHDIR: "true" on: [push] jobs: compile-ASPIS: @@ -8,64 +17,64 @@ jobs: uses: actions/checkout@v4 with: path: ASPIS - - name: Cache LLVM build - uses: actions/cache@v4 - id: llvm-cache + + - name: Install system dependencies + run: | + sudo apt update + sudo apt install -y cmake ninja-build build-essential mold curl ca-certificates ccache + + - name: Prepare LLVM Cache + uses: ./ASPIS/.github/actions/prepare-llvm-cache with: - path: /mnt/build/ - key: llvm-build-${{ hashFiles('llvm-project/**', 'ASPIS/CMakeLists.txt') }} - restore-keys: | - llvm-build- - - name: Checking out LLVM project - uses: actions/checkout@master - if: steps.llvm-cache.outputs.cache-hit != 'true' + llvm-commit: ${{ env.LLVM_COMMIT }} + + - name: Restore ccache + id: restore-ccache + uses: actions/cache/restore@v4 with: - repository: llvm/llvm-project - ref: llvmorg-21.1.8 - path: llvm-project - - name: Compiling LLVM - if: steps.llvm-cache.outputs.cache-hit != 'true' - shell: bash - working-directory: ./llvm-project - run: | - builddir="/mnt/build/" - sudo mkdir -p $builddir - sudo chmod 777 $builddir - cmake -G Ninja \ - -B "$builddir" \ - -S llvm \ - -DLLVM_ENABLE_PROJECTS="clang" \ - -DCMAKE_BUILD_TYPE=Release \ - -DLLVM_ENABLE_ASSERTIONS=OFF \ - -DLLDB_INCLUDE_TESTS=OFF \ - -DLIBCLC_TARGETS_TO_BUILD="RISCV;X86" - cmake --build "$builddir" + path: ${{ env.CCACHE_DIR }} + key: ccache-${{ runner.os }}-${{ github.ref_name }}-${{ env.LLVM_COMMIT }}-${{ env.CMAKE_VERSION }}-${{ github.sha }} + restore-keys: | + ccache-${{ runner.os }}-${{ github.ref_name }}-${{ env.LLVM_COMMIT }}-${{ env.CMAKE_VERSION }}- + ccache-${{ runner.os }}-${{ env.LLVM_COMMIT }}-${{ env.CMAKE_VERSION }}- + - name: Compiling ASPIS shell: bash - working-directory: ./ASPIS + working-directory: ${{ github.workspace }}/ASPIS run: | - mkdir build - cmake -B build -DLLVM_DIR=/mnt/build/lib/cmake/llvm/ - cmake --build build + ccache --set-config=max_size=${CCACHE_MAXSIZE} + ccache --zero-stats + ccache --show-config + ccache --show-stats + + mkdir build + cmake -B build -DLLVM_DIR=${{ github.workspace }}/llvm-build/lib/cmake/llvm/ + cmake --build build + + - name: Save ccache + if: steps.build-llvm.outcome == 'success' && steps.restore-ccache.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 + with: + path: ${{ env.CCACHE_DIR }} + key: ccache-${{ runner.os }}-${{ github.ref_name }}-${{ env.LLVM_COMMIT }}-${{ env.CMAKE_VERSION }}-${{ github.sha }} + - name: Cache pip uses: actions/cache@v4 id: pip-cache with: path: ~/.cache/pip - key: pip-${{ hashFiles('ASPIS/testing/requirements.txt') }} + key: pip-${{ hashFiles('${{ github.workspace }}/ASPIS/testing/requirements.txt') }} restore-keys: | pip- - name: Install Python requirements shell: bash - if: steps.llvm-cache.outputs.cache-hit != 'true' - working-directory: ./ASPIS/testing + if: steps.restore-ccache.outputs.cache-hit != 'true' + working-directory: ${{ github.workspace }}/ASPIS/testing run: | pip install -r requirements.txt - name: Testing ASPIS shell: bash - working-directory: ./ASPIS/testing + working-directory: ${{ github.workspace }}/ASPIS/testing run: | - pytest test.py --tests-file config/tests.toml - pytest test.py --tests-file config/racfed+eddi.toml - pytest test.py --tests-file config/racfed.toml + pytest test.py diff --git a/testing/README.md b/testing/README.md index 7033b79..2b23956 100644 --- a/testing/README.md +++ b/testing/README.md @@ -4,10 +4,10 @@ This directory contains utilities and scripts for testing ASPIS. ## Local Testing -For local testing, use the `test.py` script. Configure your tests using `tests.toml`. Configure the llvm_bin flag in `llvm_bin.toml`. +For local testing, use the `test.py` script. Configure your tests using `complete_testing.toml`. Configure the llvm_bin flag in `llvm_bin.toml`. Then run: ```bash -pytest test.py +pytest test.py --no-header -v ``` > To run pytest the modules listed in requirements.txt must be installed. @@ -26,12 +26,12 @@ Test config files must be `.toml` files with the following structure for each te [[tests]] test_name = source_file = -expected_output = -aspis_options = ``` > `` is a relative path from `./tests/` folder +All the combinations of ASPIS protection mechanisms will be used for each different test. + ### Flags It is possible to write different configuration test files. diff --git a/testing/config/llvm.toml b/testing/config/llvm.toml index 0a61754..8b36024 100644 --- a/testing/config/llvm.toml +++ b/testing/config/llvm.toml @@ -1,2 +1,2 @@ #llvm_bin = "" -llvm_bin = "/mnt/build/bin/" \ No newline at end of file +llvm_bin = "/home/runner/work/ASPIS/ASPIS/llvm-build/bin" \ No newline at end of file diff --git a/testing/config/racfed+eddi.toml b/testing/config/racfed+eddi.toml deleted file mode 100644 index ce3d34e..0000000 --- a/testing/config/racfed+eddi.toml +++ /dev/null @@ -1,108 +0,0 @@ -[[tests]] -test_name = "racfed_eddi_ml_add" -source_file = "c/multi_instruction/add.c" -expected_output = "30" -aspis_options = "--eddi --racfed" - -[[tests]] -test_name = "racfed_eddi_ml_function_call" -source_file = "c/multi_instruction/function.c" -expected_output = "foo() 25" -aspis_options = "--eddi --racfed" - -[[tests]] -test_name = "racfed_eddi_preserve_runtime_sig" -source_file = "c/multi_instruction/call_less_two.c" -expected_output = "0" -aspis_options = "--eddi --racfed" - -[[tests]] -test_name = "racfed_eddi_ml_if_then_else" -source_file = "c/multi_instruction/if_then_else.c" -expected_output = "1001" -aspis_options = "--eddi --racfed" - -[[tests]] -test_name = "racfed_eddi_ml_phi_instruction" -source_file = "c/multi_instruction/phi.c" -expected_output = "SUCCESS" -aspis_options = "--eddi --racfed" - -[[tests]] -test_name = "racfed_eddi_function_pointer" -source_file = "c/control_flow/function_pointer.c" -expected_output = "42" -aspis_options = "--eddi --racfed" - -[[tests]] -test_name = "racfed_eddi_loop_exit" -source_file = "c/control_flow/loop_exit.c" -expected_output = "2" -aspis_options = "--eddi --racfed" - -[[tests]] -test_name = "racfed_eddi_n-branch_eddi" -source_file = "c/control_flow/nested-branch.c" -expected_output = "6" -aspis_options = "--eddi --racfed" - -[[tests]] -test_name = "racfed_eddi_s-branch_eddi" -source_file = "c/control_flow/simple-branch.c" -expected_output = "OK" -aspis_options = "--eddi --racfed" - -[[tests]] -test_name = "racfed_eddi_s-case_eddi" -source_file = "c/control_flow/switch-case.c" -expected_output = "300" -aspis_options = "--eddi --racfed" - -[[tests]] -test_name = "racfed_eddi_data_dep_branches" -source_file = "c/data_duplication_integrity/data_dep_branches.c" -expected_output = "7" -aspis_options = "--eddi --racfed" - -[[tests]] -test_name = "racfed_eddi_global_var_across_functions" -source_file = "c/data_duplication_integrity/global_var_across_functions.c" -expected_output = "2" -aspis_options = "--eddi --racfed" - -[[tests]] -test_name = "racfed_eddi_misc_data_dup" -source_file = "c/data_duplication_integrity/misc_data_dup.c" -expected_output = "OK" -aspis_options = "--eddi --racfed" - -[[tests]] -test_name = "racfed_eddi_volatile_io" -source_file = "c/data_duplication_integrity/volatile_io.c" -expected_output = "42" -aspis_options = "--eddi --racfed" - -[[tests]] -test_name = "racfed_eddi_arit_pipeline" -source_file = "c/misc_math/arit_pipeline.c" -expected_output = "3" -aspis_options = "--eddi --racfed" - -[[tests]] -test_name = "racfed_eddi_mixed_ops" -source_file = "c/misc_math/mixed_ops.c" -expected_output = "14.5" -aspis_options = "--eddi --racfed" - -[[tests]] -test_name = "racfed_eddi_xor_cypher" -source_file = "c/misc_math/xor_cypher.c" -expected_output = "SUCCESS" -aspis_options = "--eddi --racfed" - -[[tests]] -test_name = "racfed_ml_multi_if_else" -source_file = "c/multi_instruction/multi_if_then_else.c" -expected_output = "r > 200" -aspis_options = "--eddi --racfed" - diff --git a/testing/config/racfed.toml b/testing/config/racfed.toml deleted file mode 100644 index 5129d1f..0000000 --- a/testing/config/racfed.toml +++ /dev/null @@ -1,108 +0,0 @@ -[[tests]] -test_name = "racfed_ml_add" -source_file = "c/multi_instruction/add.c" -expected_output = "30" -aspis_options = "--no-dup --racfed" - -[[tests]] -test_name = "racfed_ml_function_call" -source_file = "c/multi_instruction/function.c" -expected_output = "foo() 25" -aspis_options = "--no-dup --racfed" - -[[tests]] -test_name = "racfed_preserve_runtime_sig" -source_file = "c/multi_instruction/call_less_two.c" -expected_output = "0" -aspis_options = "--no-dup --racfed" - -[[tests]] -test_name = "racfed_ml_if_then_else" -source_file = "c/multi_instruction/if_then_else.c" -expected_output = "1001" -aspis_options = "--no-dup --racfed" - -[[tests]] -test_name = "racfed_ml_phi_instruction" -source_file = "c/multi_instruction/phi.c" -expected_output = "SUCCESS" -aspis_options = "--no-dup --racfed" - -[[tests]] -test_name = "racfed_function_pointer" -source_file = "c/control_flow/function_pointer.c" -expected_output = "42" -aspis_options = "--no-dup --racfed" - -[[tests]] -test_name = "racfed_loop_exit" -source_file = "c/control_flow/loop_exit.c" -expected_output = "2" -aspis_options = "--no-dup --racfed" - -[[tests]] -test_name = "racfed_nested-branch" -source_file = "c/control_flow/nested-branch.c" -expected_output = "6" -aspis_options = "--no-dup --racfed" - -[[tests]] -test_name = "racfed_simple-branch" -source_file = "c/control_flow/simple-branch.c" -expected_output = "OK" -aspis_options = "--no-dup --racfed" - -[[tests]] -test_name = "racfed_switch-case" -source_file = "c/control_flow/switch-case.c" -expected_output = "300" -aspis_options = "--no-dup --racfed" - -[[tests]] -test_name = "racfed_data_dep_branches" -source_file = "c/data_duplication_integrity/data_dep_branches.c" -expected_output = "7" -aspis_options = "--no-dup --racfed" - -[[tests]] -test_name = "racfed_global_var_across_functions" -source_file = "c/data_duplication_integrity/global_var_across_functions.c" -expected_output = "2" -aspis_options = "--no-dup --racfed" - -[[tests]] -test_name = "racfed_misc_data_dup" -source_file = "c/data_duplication_integrity/misc_data_dup.c" -expected_output = "OK" -aspis_options = "--no-dup --racfed" - -[[tests]] -test_name = "racfed_volatile_io" -source_file = "c/data_duplication_integrity/volatile_io.c" -expected_output = "42" -aspis_options = "--no-dup --racfed" - -[[tests]] -test_name = "racfed_arit_pipeline" -source_file = "c/misc_math/arit_pipeline.c" -expected_output = "3" -aspis_options = "--no-dup --racfed" - -[[tests]] -test_name = "racfed_mixed_ops" -source_file = "c/misc_math/mixed_ops.c" -expected_output = "14.5" -aspis_options = "--no-dup --racfed" - -[[tests]] -test_name = "racfed_xor_cypher" -source_file = "c/misc_math/xor_cypher.c" -expected_output = "SUCCESS" -aspis_options = "--no-dup --racfed" - -[[tests]] -test_name = "racfed_ml_multi_if_else" -source_file = "c/multi_instruction/multi_if_then_else.c" -expected_output = "r > 200" -aspis_options = "--no-dup --racfed" - diff --git a/testing/config/tests.toml b/testing/config/tests.toml index f7eed84..61d0239 100644 --- a/testing/config/tests.toml +++ b/testing/config/tests.toml @@ -1,750 +1,135 @@ - -[[tests]] -test_name = "add1" -source_file = "cpp/simple/add.cpp" -expected_output = "7" -aspis_options = "--eddi --cfcss" - -[[tests]] -test_name = "add2" -source_file = "cpp/simple/add.cpp" -expected_output = "7" -aspis_options = "--seddi --rasm" - -[[tests]] -test_name = "add3" -source_file = "cpp/simple/add.cpp" -expected_output = "7" -aspis_options = "--fdsc --rasm" - -[[tests]] -test_name = "add4" -source_file = "cpp/simple/add.cpp" -expected_output = "7" -aspis_options = "--eddi --no-cfc" - -[[tests]] -test_name = "class_polymorphism1" -source_file = "cpp/simple/class.cpp" -expected_output = """ -12 -5, 7 -3, 6, 9""" -aspis_options = "--eddi --cfcss" - -[[tests]] -test_name = "class_polymorphism2" -source_file = "cpp/simple/class.cpp" -expected_output = """ -12 -5, 7 -3, 6, 9""" -aspis_options = "--seddi --rasm" - -[[tests]] -test_name = "class_polymorphism3" -source_file = "cpp/simple/class.cpp" -expected_output = """ -12 -5, 7 -3, 6, 9""" -aspis_options = "--fdsc --rasm" - -[[tests]] -test_name = "class_polymorphism4" -source_file = "cpp/simple/class.cpp" -expected_output = """ -12 -5, 7 -3, 6, 9""" -aspis_options = "--eddi --no-cfc" - -[[tests]] -test_name = "exception_handling1" -source_file = "cpp/simple/exceptions.cpp" -expected_output = """ -Exception caught: Test exception -Exception caught: Test exception""" -aspis_options = "--eddi --cfcss" - -[[tests]] -test_name = "exception_handling2" -source_file = "cpp/simple/exceptions.cpp" -expected_output = """ -Exception caught: Test exception -Exception caught: Test exception""" -aspis_options = "--seddi --rasm" - -[[tests]] -test_name = "exception_handling3" -source_file = "cpp/simple/exceptions.cpp" -expected_output = """ -Exception caught: Test exception -Exception caught: Test exception""" -aspis_options = "--fdsc --rasm" - -[[tests]] -test_name = "exception_handling4" -source_file = "cpp/simple/exceptions.cpp" -expected_output = """ -Exception caught: Test exception -Exception caught: Test exception""" -aspis_options = "--eddi --no-cfc" - -[[tests]] -test_name = "fact1" -source_file = "cpp/simple/fact.cpp" -expected_output = """ -3628800""" -aspis_options = "--eddi --cfcss" - -[[tests]] -test_name = "fact2" -source_file = "cpp/simple/fact.cpp" -expected_output = """ -3628800""" -aspis_options = "--seddi --rasm" - -[[tests]] -test_name = "fact3" -source_file = "cpp/simple/fact.cpp" -expected_output = """ -3628800""" -aspis_options = "--fdsc --rasm" - -[[tests]] -test_name = "fact4" -source_file = "cpp/simple/fact.cpp" -expected_output = """ -3628800""" -aspis_options = "--eddi --no-cfc" - -[[tests]] -test_name = "func1" -source_file = "cpp/simple/func.cpp" -expected_output = """ -Function f called (g incremented to 1) -Final value of g: 1""" -aspis_options = "--eddi --cfcss" - -[[tests]] -test_name = "func2" -source_file = "cpp/simple/func.cpp" -expected_output = """ -Function f called (g incremented to 1) -Final value of g: 1""" -aspis_options = "--seddi --rasm" - -[[tests]] -test_name = "func3" -source_file = "cpp/simple/func.cpp" -expected_output = """ -Function f called (g incremented to 1) -Final value of g: 1""" -aspis_options = "--fdsc --rasm" - -[[tests]] -test_name = "func4" -source_file = "cpp/simple/func.cpp" -expected_output = """ -Function f called (g incremented to 1) -Final value of g: 1""" -aspis_options = "--eddi --no-cfc" - -[[tests]] -test_name = "mul1" -source_file = "cpp/simple/mul.cpp" -expected_output = """ -42""" -aspis_options = "--eddi --cfcss" - -[[tests]] -test_name = "mul2" -source_file = "cpp/simple/mul.cpp" -expected_output = """ -42""" -aspis_options = "--seddi --rasm" - -[[tests]] -test_name = "mul3" -source_file = "cpp/simple/mul.cpp" -expected_output = """ -42""" -aspis_options = "--fdsc --rasm" - -[[tests]] -test_name = "mul4" -source_file = "cpp/simple/mul.cpp" -expected_output = """ -42""" -aspis_options = "--eddi --no-cfc" - -[[tests]] -test_name = "template1" -source_file = "cpp/simple/template.cpp" -expected_output = """ -Result: 42 -Result: 15""" -aspis_options = "--eddi --cfcss" - -[[tests]] -test_name = "template2" -source_file = "cpp/simple/template.cpp" -expected_output = """ -Result: 42 -Result: 15""" -aspis_options = "--seddi --rasm" - -[[tests]] -test_name = "template3" -source_file = "cpp/simple/template.cpp" -expected_output = """ -Result: 42 -Result: 15""" -aspis_options = "--fdsc --rasm" - -[[tests]] -test_name = "template4" -source_file = "cpp/simple/template.cpp" -expected_output = """ -Result: 42 -Result: 15""" -aspis_options = "--eddi --no-cfc" - -[[tests]] -test_name = "ptrsSharedUnique1" -source_file = "cpp/simple/ptr.cpp" -expected_output = """ -Value pointed by p1: 42, Value pointed by p2: 42""" -aspis_options = "--eddi --cfcss" - -[[tests]] -test_name = "ptrsSharedUnique2" -source_file = "cpp/simple/ptr.cpp" -expected_output = """ -Value pointed by p1: 42, Value pointed by p2: 42""" -aspis_options = "--seddi --rasm" - -[[tests]] -test_name = "ptrsSharedUnique3" -source_file = "cpp/simple/ptr.cpp" -expected_output = """ -Value pointed by p1: 42, Value pointed by p2: 42""" -aspis_options = "--fdsc --rasm" - -[[tests]] -test_name = "ptrsSharedUnique4" -source_file = "cpp/simple/ptr.cpp" -expected_output = """ -Value pointed by p1: 42, Value pointed by p2: 42""" -aspis_options = "--eddi --no-cfc" - -[[tests]] -test_name = "heap1" -source_file = "cpp/simple/heap.cpp" -expected_output = """ -Value: 10""" -aspis_options = "--eddi --cfcss" - -[[tests]] -test_name = "heap2" -source_file = "cpp/simple/heap.cpp" -expected_output = """ -Value: 10""" -aspis_options = "--seddi --rasm" - -[[tests]] -test_name = "heap3" -source_file = "cpp/simple/heap.cpp" -expected_output = """ -Value: 10""" -aspis_options = "--fdsc --rasm" - -[[tests]] -test_name = "heap4" -source_file = "cpp/simple/heap.cpp" -expected_output = """ -Value: 10""" -aspis_options = "--eddi --no-cfc" - -[[tests]] -test_name = "raii_filehandler1" -source_file = "cpp/simple/file_handler.cpp" -expected_output = """ -Handler created -File closed""" -aspis_options = "--eddi --cfcss" - -[[tests]] -test_name = "raii_filehandler2" -source_file = "cpp/simple/file_handler.cpp" -expected_output = """ -Handler created -File closed""" -aspis_options = "--seddi --rasm" - -[[tests]] -test_name = "raii_filehandler3" -source_file = "cpp/simple/file_handler.cpp" -expected_output = """ -Handler created -File closed""" -aspis_options = "--fdsc --rasm" - -[[tests]] -test_name = "raii_filehandler4" -source_file = "cpp/simple/file_handler.cpp" -expected_output = """ -Handler created -File closed""" -aspis_options = "--eddi --no-cfc" - -[[tests]] -test_name = "inline_constexpr1" -source_file = "cpp/simple/inline_constexpr.cpp" -aspis_options = "--eddi --cfcss" -expected_output = """ -9 -16 -5""" - -[[tests]] -test_name = "inline_constexpr2" -source_file = "cpp/simple/inline_constexpr.cpp" -aspis_options = "--seddi --rasm" -expected_output = """ -9 -16 -5""" - -[[tests]] -test_name = "inline_constexpr3" -source_file = "cpp/simple/inline_constexpr.cpp" -aspis_options = "--fdsc --rasm" -expected_output = """ -9 -16 -5""" - -[[tests]] -test_name = "inline_constexpr4" -source_file = "cpp/simple/inline_constexpr.cpp" -aspis_options = "--eddi --no-cfc" -expected_output = """ -9 -16 -5""" - -[[tests]] -test_name = "lambda_captures1" -source_file = "cpp/simple/lambda_captures.cpp" -aspis_options = "--eddi --cfcss" -expected_output = """ -x incremented by 5 -Value pointed by p: 11""" - [[tests]] -test_name = "lambda_captures2" -source_file = "cpp/simple/lambda_captures.cpp" -aspis_options = "--seddi --rasm" -expected_output = """ -x incremented by 5 -Value pointed by p: 11""" - -[[tests]] -test_name = "lambda_captures3" -source_file = "cpp/simple/lambda_captures.cpp" -aspis_options = "--fdsc --rasm" -expected_output = """ -x incremented by 5 -Value pointed by p: 11""" - -[[tests]] -test_name = "lambda_captures4" -source_file = "cpp/simple/lambda_captures.cpp" -aspis_options = "--eddi --no-cfc" -expected_output = """ -x incremented by 5 -Value pointed by p: 11""" - -[[tests]] -test_name = "volatile_memory_order1" -source_file = "cpp/simple/volatile_memory_order.cpp" -aspis_options = "--eddi --cfcss" -expected_output = """ -42""" - -[[tests]] -test_name = "volatile_memory_order2" -source_file = "cpp/simple/volatile_memory_order.cpp" -aspis_options = "--seddi --rasm" -expected_output = """ -42""" - -[[tests]] -test_name = "volatile_memory_order3" -source_file = "cpp/simple/volatile_memory_order.cpp" -aspis_options = "--fdsc --rasm" -expected_output = """ -42""" - -[[tests]] -test_name = "volatile_memory_order4" -source_file = "cpp/simple/volatile_memory_order.cpp" -aspis_options = "--eddi --no-cfc" -expected_output = """ -42""" - -[[tests]] -test_name = "stl_containers_advanced1" -source_file = "cpp/simple/stl_containers_advanced.cpp" -aspis_options = "--eddi --cfcss" -expected_output = """ -0 1 2 3 4""" - -[[tests]] -test_name = "stl_containers_advanced2" -source_file = "cpp/simple/stl_containers_advanced.cpp" -aspis_options = "--seddi --rasm" -expected_output = """ -0 1 2 3 4""" - -[[tests]] -test_name = "stl_containers_advanced3" -source_file = "cpp/simple/stl_containers_advanced.cpp" -aspis_options = "--fdsc --rasm" -expected_output = """ -0 1 2 3 4""" - -[[tests]] -test_name = "stl_containers_advanced4" -source_file = "cpp/simple/stl_containers_advanced.cpp" -aspis_options = "--eddi --no-cfc" -expected_output = """ -0 1 2 3 4""" - -# [[tests]] -# test_name = "threads1" -# source_file = "cpp/simple/threads.cpp" -# aspis_options = "--eddi --cfcss" -# expected_output = """ -# 4000 -# """ -# -# [[tests]] -# test_name = "threads2" -# source_file = "cpp/simple/threads.cpp" -# aspis_options = "--seddi --rasm" -# expected_output = """ -# 4000 -# """ -# -# [[tests]] -# test_name = "threads3" -# source_file = "cpp/simple/threads.cpp" -# aspis_options = "--fdsc --rasm" -# expected_output = """ -# 4000 -# """ -# -# [[tests]] -# test_name = "threads4" -# source_file = "cpp/simple/threads.cpp" -# aspis_options = "--eddi --no-cfc" -# expected_output = """ -# 4000 -# """ - -[[tests]] -test_name = "function_pointer_v0" -source_file = "c/control_flow/function_pointer.c" -expected_output = "42" -aspis_options = "--eddi --cfcss" - -[[tests]] -test_name = "function_pointer_v1" -source_file = "c/control_flow/function_pointer.c" -expected_output = "42" -aspis_options = "--seddi --rasm" - -[[tests]] -test_name = "function_pointer_v2" -source_file = "c/control_flow/function_pointer.c" -expected_output = "42" -aspis_options = "--fdsc --rasm" - -[[tests]] -test_name = "function_pointer_v3" +test_name = "c_function_pointer" source_file = "c/control_flow/function_pointer.c" -expected_output = "42" -aspis_options = "--eddi --no-cfc" [[tests]] -test_name = "loop_exit_v0" +test_name = "c_loop_exit" source_file = "c/control_flow/loop_exit.c" -expected_output = "2" -aspis_options = "--eddi --cfcss" - -[[tests]] -test_name = "loop_exit_v1" -source_file = "c/control_flow/loop_exit.c" -expected_output = "2" -aspis_options = "--seddi --rasm" - -[[tests]] -test_name = "loop_exit_v2" -source_file = "c/control_flow/loop_exit.c" -expected_output = "2" -aspis_options = "--fdsc --rasm" - -[[tests]] -test_name = "loop_exit_v3" -source_file = "c/control_flow/loop_exit.c" -expected_output = "2" -aspis_options = "--eddi --no-cfc" - -[[tests]] -test_name = "nested-branch_v0" -source_file = "c/control_flow/nested-branch.c" -expected_output = "6" -aspis_options = "--eddi --cfcss" - -[[tests]] -test_name = "nested-branch_v1" -source_file = "c/control_flow/nested-branch.c" -expected_output = "6" -aspis_options = "--seddi --rasm" - -[[tests]] -test_name = "nested-branch_v2" -source_file = "c/control_flow/nested-branch.c" -expected_output = "6" -aspis_options = "--fdsc --rasm" [[tests]] -test_name = "nested-branch_v3" +test_name = "c_nested-branch" source_file = "c/control_flow/nested-branch.c" -expected_output = "6" -aspis_options = "--eddi --no-cfc" [[tests]] -test_name = "simple-branch_v0" +test_name = "c_simple-branch" source_file = "c/control_flow/simple-branch.c" -expected_output = "OK" -aspis_options = "--eddi --cfcss" - -[[tests]] -test_name = "simple-branch_v1" -source_file = "c/control_flow/simple-branch.c" -expected_output = "OK" -aspis_options = "--seddi --rasm" - -[[tests]] -test_name = "simple-branch_v2" -source_file = "c/control_flow/simple-branch.c" -expected_output = "OK" -aspis_options = "--fdsc --rasm" - -[[tests]] -test_name = "simple-branch_v3" -source_file = "c/control_flow/simple-branch.c" -expected_output = "OK" -aspis_options = "--eddi --no-cfc" - -[[tests]] -test_name = "switch-case_v0" -source_file = "c/control_flow/switch-case.c" -expected_output = "300" -aspis_options = "--eddi --cfcss" - -[[tests]] -test_name = "switch-case_v1" -source_file = "c/control_flow/switch-case.c" -expected_output = "300" -aspis_options = "--seddi --rasm" - -[[tests]] -test_name = "switch-case_v2" -source_file = "c/control_flow/switch-case.c" -expected_output = "300" -aspis_options = "--fdsc --rasm" [[tests]] -test_name = "switch-case_v3" +test_name = "c_switch-case" source_file = "c/control_flow/switch-case.c" -expected_output = "300" -aspis_options = "--eddi --no-cfc" [[tests]] -test_name = "data_dep_branches_v0" +test_name = "c_data_dep_branches" source_file = "c/data_duplication_integrity/data_dep_branches.c" -expected_output = "7" -aspis_options = "--eddi --cfcss" [[tests]] -test_name = "data_dep_branches_v1" -source_file = "c/data_duplication_integrity/data_dep_branches.c" -expected_output = "7" -aspis_options = "--seddi --rasm" +test_name = "c_global_var_across_functions" +source_file = "c/data_duplication_integrity/global_var_across_functions.c" [[tests]] -test_name = "data_dep_branches_v2" -source_file = "c/data_duplication_integrity/data_dep_branches.c" -expected_output = "7" -aspis_options = "--fdsc --rasm" +test_name = "c_misc_data_dup" +source_file = "c/data_duplication_integrity/misc_data_dup.c" -[[tests]] -test_name = "data_dep_branches_v3" -source_file = "c/data_duplication_integrity/data_dep_branches.c" -expected_output = "7" -aspis_options = "--eddi --no-cfc" +# [[tests]] +# test_name = "c_printf_to_duplicate" +# source_file = "c/data_duplication_integrity/printf_to_duplicate.c" [[tests]] -test_name = "global_var_across_functions_v0" -source_file = "c/data_duplication_integrity/global_var_across_functions.c" -expected_output = "2" -aspis_options = "--eddi --cfcss" +test_name = "c_volatile_io" +source_file = "c/data_duplication_integrity/volatile_io.c" [[tests]] -test_name = "global_var_across_functions_v1" -source_file = "c/data_duplication_integrity/global_var_across_functions.c" -expected_output = "2" -aspis_options = "--seddi --rasm" +test_name = "c_arit_pipeline" +source_file = "c/misc_math/arit_pipeline.c" [[tests]] -test_name = "global_var_across_functions_v2" -source_file = "c/data_duplication_integrity/global_var_across_functions.c" -expected_output = "2" -aspis_options = "--fdsc --rasm" +test_name = "c_mixed_ops" +source_file = "c/misc_math/mixed_ops.c" -[[tests]] -test_name = "global_var_across_functions_v3" -source_file = "c/data_duplication_integrity/global_var_across_functions.c" -expected_output = "2" -aspis_options = "--eddi --no-cfc" +# [[tests]] +# test_name = "c_xor_cypher" +# source_file = "c/misc_math/xor_cypher.c" [[tests]] -test_name = "misc_data_dup_v0" -source_file = "c/data_duplication_integrity/misc_data_dup.c" -expected_output = "OK" -aspis_options = "--eddi --cfcss" +test_name = "c_add" +source_file = "c/multi_instruction/add.c" [[tests]] -test_name = "misc_data_dup_v1" -source_file = "c/data_duplication_integrity/misc_data_dup.c" -expected_output = "OK" -aspis_options = "--seddi --rasm" +test_name = "c_call_less_two" +source_file = "c/multi_instruction/call_less_two.c" [[tests]] -test_name = "misc_data_dup_v2" -source_file = "c/data_duplication_integrity/misc_data_dup.c" -expected_output = "OK" -aspis_options = "--fdsc --rasm" +test_name = "c_function" +source_file = "c/multi_instruction/function.c" [[tests]] -test_name = "misc_data_dup_v3" -source_file = "c/data_duplication_integrity/misc_data_dup.c" -expected_output = "OK" -aspis_options = "--eddi --no-cfc" +test_name = "c_if_then_else" +source_file = "c/multi_instruction/if_then_else.c" [[tests]] -test_name = "volatile_io_v0" -source_file = "c/data_duplication_integrity/volatile_io.c" -expected_output = "42" -aspis_options = "--eddi --cfcss" +test_name = "c_multi_if_then_else" +source_file = "c/multi_instruction/multi_if_then_else.c" [[tests]] -test_name = "volatile_io_v1" -source_file = "c/data_duplication_integrity/volatile_io.c" -expected_output = "42" -aspis_options = "--seddi --rasm" +test_name = "c_phi" +source_file = "c/multi_instruction/phi.c" [[tests]] -test_name = "volatile_io_v2" -source_file = "c/data_duplication_integrity/volatile_io.c" -expected_output = "42" -aspis_options = "--fdsc --rasm" +test_name = "cpp_add" +source_file = "cpp/simple/add.cpp" [[tests]] -test_name = "volatile_io_v3" -source_file = "c/data_duplication_integrity/volatile_io.c" -expected_output = "42" -aspis_options = "--eddi --no-cfc" +test_name = "cpp_class" +source_file = "cpp/simple/class.cpp" [[tests]] -test_name = "arit_pipeline_v0" -source_file = "c/misc_math/arit_pipeline.c" -expected_output = "3" -aspis_options = "--eddi --cfcss" +test_name = "cpp_exceptions" +source_file = "cpp/simple/exceptions.cpp" [[tests]] -test_name = "arit_pipeline_v1" -source_file = "c/misc_math/arit_pipeline.c" -expected_output = "3" -aspis_options = "--seddi --rasm" +test_name = "cpp_fact" +source_file = "cpp/simple/fact.cpp" [[tests]] -test_name = "arit_pipeline_v2" -source_file = "c/misc_math/arit_pipeline.c" -expected_output = "3" -aspis_options = "--fdsc --rasm" +test_name = "cpp_file_handler" +source_file = "cpp/simple/file_handler.cpp" [[tests]] -test_name = "arit_pipeline_v3" -source_file = "c/misc_math/arit_pipeline.c" -expected_output = "3" -aspis_options = "--eddi --no-cfc" +test_name = "cpp_func" +source_file = "cpp/simple/func.cpp" [[tests]] -test_name = "mixed_ops_v0" -source_file = "c/misc_math/mixed_ops.c" -expected_output = "14.5" -aspis_options = "--eddi --cfcss" +test_name = "cpp_heap" +source_file = "cpp/simple/heap.cpp" [[tests]] -test_name = "mixed_ops_v1" -source_file = "c/misc_math/mixed_ops.c" -expected_output = "14.5" -aspis_options = "--seddi --rasm" +test_name = "cpp_inline_constexpr" +source_file = "cpp/simple/inline_constexpr.cpp" [[tests]] -test_name = "mixed_ops_v2" -source_file = "c/misc_math/mixed_ops.c" -expected_output = "14.5" -aspis_options = "--fdsc --rasm" +test_name = "cpp_lambda_captures" +source_file = "cpp/simple/lambda_captures.cpp" [[tests]] -test_name = "mixed_ops_v3" -source_file = "c/misc_math/mixed_ops.c" -expected_output = "14.5" -aspis_options = "--eddi --no-cfc" +test_name = "cpp_mul" +source_file = "cpp/simple/mul.cpp" [[tests]] -test_name = "xor_cypher_v0" -source_file = "c/misc_math/xor_cypher.c" -expected_output = "SUCCESS" -aspis_options = "--eddi --cfcss" +test_name = "cpp_ptr" +source_file = "cpp/simple/ptr.cpp" [[tests]] -test_name = "xor_cypher_v1" -source_file = "c/misc_math/xor_cypher.c" -expected_output = "SUCCESS" -aspis_options = "--seddi --rasm" +test_name = "cpp_stl_containers_advanced" +source_file = "cpp/simple/stl_containers_advanced.cpp" [[tests]] -test_name = "xor_cypher_v2" -source_file = "c/misc_math/xor_cypher.c" -expected_output = "SUCCESS" -aspis_options = "--fdsc --rasm" +test_name = "cpp_template" +source_file = "cpp/simple/template.cpp" -[[tests]] -test_name = "xor_cypher_v3" -source_file = "c/misc_math/xor_cypher.c" -expected_output = "SUCCESS" -aspis_options = "--eddi --no-cfc" +# [[tests]] +# test_name = "cpp_threads" +# source_file = "cpp/simple/threads.cpp" [[tests]] -test_name = "printf_to_duplicate" -source_file = "c/data_duplication_integrity/printf_to_duplicate.c" -expected_output = "The string is: Hello WorldThe string is: Hello World" -aspis_options = "--eddi --no-cfc" \ No newline at end of file +test_name = "cpp_volatile_memory_order" +source_file = "cpp/simple/volatile_memory_order.cpp" diff --git a/testing/requirements.txt b/testing/requirements.txt index 48ea52e..db2b2c7 100644 --- a/testing/requirements.txt +++ b/testing/requirements.txt @@ -3,3 +3,4 @@ packaging==25.0 pluggy==1.6.0 Pygments==2.19.2 pytest==8.4.1 +pytest-timeout==2.4.0 diff --git a/testing/test.py b/testing/test.py index 6c1f571..77e1d6c 100644 --- a/testing/test.py +++ b/testing/test.py @@ -1,6 +1,8 @@ import os import subprocess import pytest + +import pytest_timeout import tomllib # Default configurations @@ -11,6 +13,9 @@ LOCAL_SHARED_VOLUME = "./tests/" DOCKER_COMPOSE_FILE = "../docker/docker-compose.yml" +data_techniques = ["--no-dup", "--eddi", "--seddi", "--fdsc"] # "--reddi" +cfc_techniques = ["--no-cfc", "--cfcss", "--rasm"] #, "--racfed", "--inter-rasm"] + # Load the test configuration def load_config(): assert os.path.exists("../aspis.sh") and "Cannot find aspis.sh, please run the tests from the ASPIS testing directory as `pytest test.py`" @@ -35,6 +40,16 @@ def compile_with_aspis(source_file, output_file, options, llvm_bin, build_dir): raise RuntimeError(f"[{output_file}] Compilation failed: {stderr}") return stdout +# Compile without ASPIS to get expected output +def compile_without_aspis(source_file, output_file, llvm_bin, build_dir): + """Compile a file without ASPIS.""" + command = f"{llvm_bin}/clang++ {source_file} -o {build_dir}/{output_file}.out --verbose" + print(command) + stdout, stderr, exit_code = run_command(command) + if exit_code != 0: + raise RuntimeError(f"[{output_file}] Compilation failed: {stderr}") + return stdout + def execute_binary(local_build_dir, test_name): """Execute the compiled binary and return its output.""" binary_file = f"./{local_build_dir}/{test_name}.out"; @@ -59,15 +74,18 @@ def pytest_generate_tests(metafunc): ids = [t.get("test_name", str(i)) for i, t in enumerate(test_list)] metafunc.parametrize("test_data", test_list, ids=ids) + # Tests -def test_aspis(test_data, use_container, aspis_addopt): +@pytest.mark.timeout(60) # Set a timeout of 60 seconds for each test +@pytest.mark.parametrize("data_technique", data_techniques) +@pytest.mark.parametrize("cfc_technique", cfc_techniques) +def test_aspis(test_data, use_container, aspis_addopt, data_technique, cfc_technique): """Run a single ASPIS test.""" config = load_config() llvm_bin = config["llvm_bin"] test_name = test_data["test_name"] source_file = test_data["source_file"] - aspis_options = aspis_addopt + " " + test_data["aspis_options"] - expected_output = test_data["expected_output"] + # use docker compose rather than ASPIS if --use-container is set if use_container: ASPIS_SCRIPT = f"docker compose -f {DOCKER_COMPOSE_FILE} run --rm aspis_runner" @@ -78,14 +96,28 @@ def test_aspis(test_data, use_container, aspis_addopt): docker_build_dir = "./build/test/"+test_name local_build_dir = "./build/test/"+test_name + # Create build directory if it doesn't exist + os.makedirs(local_build_dir, exist_ok=True) + source_path = os.path.join(TEST_DIR, source_file) + if not os.path.exists(docker_build_dir + "/" + test_name + ".out"): + print("Compiling without ASPIS to get expected output...") + compile_without_aspis(source_path, test_name, llvm_bin, docker_build_dir) + + print("Executing binary compiled without ASPIS...") + expected_output = execute_binary(local_build_dir, test_name) + print(f"Expected output: {expected_output}") + + aspis_options = aspis_addopt + " " + data_technique + " " + cfc_technique + + test_name_complete = f"{test_name}_{data_technique}_{cfc_technique}" # Compile the source file - compile_with_aspis(source_path, test_name, aspis_options, llvm_bin, docker_build_dir) + compile_with_aspis(source_path, test_name_complete, aspis_options, llvm_bin, docker_build_dir) # Execute the binary and check output - result = execute_binary(local_build_dir, test_name) - assert result == expected_output, f"Test {test_name} failed: {result}" + result = execute_binary(local_build_dir, test_name_complete) + assert result == expected_output, f"Test {test_name_complete} failed: {result}" if __name__ == "__main__": pytest.main() diff --git a/testing/tests/c/control_flow/function_pointer.c b/testing/tests/c/control_flow/function_pointer.c index 7a3d13c..f7e8302 100644 --- a/testing/tests/c/control_flow/function_pointer.c +++ b/testing/tests/c/control_flow/function_pointer.c @@ -9,10 +9,20 @@ int foo() { return 42; } +int add(int a, int b) { + return a + b; +} + int main() { + // Simple function pointer call int (*fptr)() = foo; int result = fptr(); - printf("%d", result); + printf("%d\n", result); + + // Function pointer call with parameters + int (*addptr)(int, int) = add; + int sum = addptr(27, result); + printf("%d\n", sum); return 0; } diff --git a/testing/tests/c/data_duplication_integrity/global_var_across_functions.c b/testing/tests/c/data_duplication_integrity/global_var_across_functions.c index 40c3d2b..a02356a 100644 --- a/testing/tests/c/data_duplication_integrity/global_var_across_functions.c +++ b/testing/tests/c/data_duplication_integrity/global_var_across_functions.c @@ -4,7 +4,8 @@ #include -int __attribute__((annotate("to_duplicate"))) g = 0; +__attribute__((annotate("to_harden"))) +int g = 0; void increment() { g += 1; diff --git a/testing/tests/c/data_duplication_integrity/misc_data_dup.c b/testing/tests/c/data_duplication_integrity/misc_data_dup.c index 0619c3c..3a31410 100644 --- a/testing/tests/c/data_duplication_integrity/misc_data_dup.c +++ b/testing/tests/c/data_duplication_integrity/misc_data_dup.c @@ -7,7 +7,7 @@ void DataCorruption_Handler(void) {} void SigMismatch_Handler(void) {} -__attribute__((annotate("to_duplicate"))) +__attribute__((annotate("to_harden"))) int duplicated_global = 100; __attribute__((annotate("exclude"))) @@ -17,7 +17,7 @@ int increment(int x) { return x + 1; } -__attribute__((annotate("to_duplicate"))) +__attribute__((annotate("to_harden"))) int multiply_by_two(int x) { return x * 2; } diff --git a/testing/tests/c/data_duplication_integrity/printf_to_duplicate.c b/testing/tests/c/data_duplication_integrity/printf_to_duplicate.c index 5d83fac..4b6950d 100644 --- a/testing/tests/c/data_duplication_integrity/printf_to_duplicate.c +++ b/testing/tests/c/data_duplication_integrity/printf_to_duplicate.c @@ -1,6 +1,6 @@ #include -__attribute__((annotate("to_duplicate"))) +__attribute__((annotate("to_harden"))) void print_string(char *s) { printf("The string is: %s", s); } diff --git a/testing/tests/c/misc_math/xor_cypher.c b/testing/tests/c/misc_math/xor_cypher.c index 59aff92..1d219ef 100644 --- a/testing/tests/c/misc_math/xor_cypher.c +++ b/testing/tests/c/misc_math/xor_cypher.c @@ -12,7 +12,7 @@ void DataCorruption_Handler(void) {} void SigMismatch_Handler(void) {} // Global key -__attribute__((annotate("to_duplicate"))) +__attribute__((annotate("to_harden"))) unsigned char key = 0x5A; // Encrypt/decrypt function @@ -21,7 +21,7 @@ unsigned char xor_crypt(unsigned char data, unsigned char k) { } // Process buffer function -__attribute__((annotate("to_duplicate"))) +__attribute__((annotate("to_harden"))) void process_buffer(unsigned char *buf, size_t len, unsigned char k) { for (size_t i = 0; i < len; i++) { buf[i] = xor_crypt(buf[i], k); diff --git a/testing/tests/cpp/simple/add.cpp b/testing/tests/cpp/simple/add.cpp index c7d653a..9512744 100644 --- a/testing/tests/cpp/simple/add.cpp +++ b/testing/tests/cpp/simple/add.cpp @@ -1,5 +1,18 @@ #include +extern "C" { + // ASPIS error handling functions + void DataCorruption_Handler() { + std::cerr << "Errore ASPIS: Data corruption detected\n"; + std::exit(EXIT_FAILURE); + } + + void SigMismatch_Handler() { + std::cerr << "Errore ASPIS: Signature mismatch detected\n"; + std::exit(EXIT_FAILURE); + } +} + int add(int a, int b) { return a + b; } diff --git a/testing/tests/cpp/simple/class.cpp b/testing/tests/cpp/simple/class.cpp index 2d86302..6352bde 100644 --- a/testing/tests/cpp/simple/class.cpp +++ b/testing/tests/cpp/simple/class.cpp @@ -2,12 +2,13 @@ #include // Gestori di errore ASPIS +extern "C" void DataCorruption_Handler() { - std::cerr << "Errore ASPIS: Data corruption rilevata\n"; + std::cerr << "Errore ASPIS: Data corruption detected\n"; std::exit(1); } void SigMismatch_Handler() { - std::cerr << "Errore ASPIS: Signature mismatch rilevata\n"; + std::cerr << "Errore ASPIS: Signature mismatch detected\n"; std::exit(1); } diff --git a/testing/tests/cpp/simple/exceptions.cpp b/testing/tests/cpp/simple/exceptions.cpp index 7a43fad..d773435 100644 --- a/testing/tests/cpp/simple/exceptions.cpp +++ b/testing/tests/cpp/simple/exceptions.cpp @@ -3,16 +3,17 @@ #include // ASPIS error handlers (non-duplicated) -__attribute__((no_duplicate)) -void DataCorruption_Handler() { - std::cerr << "ASPIS error: Data corruption detected\n"; - std::exit(1); -} +extern "C" { + // ASPIS error handling functions + void DataCorruption_Handler() { + std::cerr << "Errore ASPIS: Data corruption detected\n"; + std::exit(EXIT_FAILURE); + } -__attribute__((no_duplicate)) -void SigMismatch_Handler() { - std::cerr << "ASPIS error: Signature mismatch detected\n"; - std::exit(1); + void SigMismatch_Handler() { + std::cerr << "Errore ASPIS: Signature mismatch detected\n"; + std::exit(EXIT_FAILURE); + } } // A leaf that always throws diff --git a/testing/tests/cpp/simple/fact.cpp b/testing/tests/cpp/simple/fact.cpp index a7382ba..bb46800 100644 --- a/testing/tests/cpp/simple/fact.cpp +++ b/testing/tests/cpp/simple/fact.cpp @@ -1,12 +1,12 @@ #include -extern "C" __attribute__((no_duplicate)) +extern "C" void DataCorruption_Handler() { std::cerr << "ASPIS error: Data corruption detected\n"; std::exit(EXIT_FAILURE); } -extern "C" __attribute__((no_duplicate)) +extern "C" void SigMismatch_Handler() { std::cerr << "ASPIS error: Signature mismatch detected\n"; std::exit(EXIT_FAILURE); diff --git a/testing/tests/cpp/simple/file_handler.cpp b/testing/tests/cpp/simple/file_handler.cpp index fa5d8a9..1332647 100644 --- a/testing/tests/cpp/simple/file_handler.cpp +++ b/testing/tests/cpp/simple/file_handler.cpp @@ -2,13 +2,13 @@ #include // ASPIS handlers -extern "C" __attribute__((no_duplicate)) +extern "C" void DataCorruption_Handler() { std::cerr << "Data corruption detected" << std::endl; std::exit(EXIT_FAILURE); } -extern "C" __attribute__((no_duplicate)) +extern "C" void SigMismatch_Handler() { std::cerr << "Signature mismatch detected" << std::endl; std::exit(EXIT_FAILURE); diff --git a/testing/tests/cpp/simple/func.cpp b/testing/tests/cpp/simple/func.cpp index 9598821..a61b2c2 100644 --- a/testing/tests/cpp/simple/func.cpp +++ b/testing/tests/cpp/simple/func.cpp @@ -1,21 +1,29 @@ #include // ASPIS error handlers (non-duplicated) -__attribute__((no_duplicate)) -void DataCorruption_Handler() { - std::cerr << "ASPIS error: Data corruption detected\n"; -} +extern "C" { + // ASPIS error handling functions + void DataCorruption_Handler() { + std::cerr << "Errore ASPIS: Data corruption detected\n"; + std::exit(EXIT_FAILURE); + } -__attribute__((no_duplicate)) -void SigMismatch_Handler() { - std::cerr << "ASPIS error: Signature mismatch detected\n"; + void SigMismatch_Handler() { + std::cerr << "Errore ASPIS: Signature mismatch detected\n"; + std::exit(EXIT_FAILURE); + } } // Global variable used in the test int g = 0; // A function with a side effect on a global variable (non-duplicated) -__attribute__((no_duplicate)) +__attribute__((annotate("exclude"))) // Marked as non-duplicable +void fNonDup() { + g++; + std::cout << "Function fNonDup called (g incremented to " << g << ")" << std::endl; +} + void f() { g++; std::cout << "Function f called (g incremented to " << g << ")" << std::endl; @@ -23,6 +31,7 @@ void f() { int main() { f(); // Called once + fNonDup(); std::cout << "Final value of g: " << g << std::endl; return 0; } diff --git a/testing/tests/cpp/simple/heap.cpp b/testing/tests/cpp/simple/heap.cpp index 3d2a500..2786d73 100644 --- a/testing/tests/cpp/simple/heap.cpp +++ b/testing/tests/cpp/simple/heap.cpp @@ -1,14 +1,17 @@ #include // ASPIS error handlers (non-duplicated) -__attribute__((no_duplicate)) -void DataCorruption_Handler() { - std::cerr << "ASPIS error: Data corruption detected\n"; -} +extern "C" { + // ASPIS error handling functions + void DataCorruption_Handler() { + std::cerr << "Errore ASPIS: Data corruption detected\n"; + std::exit(EXIT_FAILURE); + } -__attribute__((no_duplicate)) -void SigMismatch_Handler() { - std::cerr << "ASPIS error: Signature mismatch detected\n"; + void SigMismatch_Handler() { + std::cerr << "Errore ASPIS: Signature mismatch detected\n"; + std::exit(EXIT_FAILURE); + } } // A function that allocates memory, uses it, and then deletes it diff --git a/testing/tests/cpp/simple/inline_constexpr.cpp b/testing/tests/cpp/simple/inline_constexpr.cpp index f74c5f3..900fb3f 100644 --- a/testing/tests/cpp/simple/inline_constexpr.cpp +++ b/testing/tests/cpp/simple/inline_constexpr.cpp @@ -1,18 +1,19 @@ #include // ASPIS error handlers (non-duplicated) -__attribute__((no_duplicate)) -void DataCorruption_Handler() { - std::cerr << "ASPIS error: Data corruption detected\n"; +extern "C" { + // ASPIS error handling functions + void DataCorruption_Handler() { + std::cerr << "Errore ASPIS: Data corruption detected\n"; + std::exit(EXIT_FAILURE); + } + + void SigMismatch_Handler() { + std::cerr << "Errore ASPIS: Signature mismatch detected\n"; + std::exit(EXIT_FAILURE); + } } -__attribute__((no_duplicate)) -void SigMismatch_Handler() { - std::cerr << "ASPIS error: Signature mismatch detected\n"; -} - -// Print function (non-duplicated) -__attribute__((no_duplicate)) void printResult(int value) { std::cout << value << std::endl; } diff --git a/testing/tests/cpp/simple/lambda_captures.cpp b/testing/tests/cpp/simple/lambda_captures.cpp index af08e3a..6c13f07 100644 --- a/testing/tests/cpp/simple/lambda_captures.cpp +++ b/testing/tests/cpp/simple/lambda_captures.cpp @@ -1,23 +1,31 @@ #include // ASPIS error handlers (non-duplicated) -__attribute__((no_duplicate)) -void DataCorruption_Handler() { - std::cerr << "ASPIS error: Data corruption detected\n"; -} +extern "C" { + // ASPIS error handling functions + void DataCorruption_Handler() { + std::cerr << "Errore ASPIS: Data corruption detected\n"; + std::exit(EXIT_FAILURE); + } -__attribute__((no_duplicate)) -void SigMismatch_Handler() { - std::cerr << "ASPIS error: Signature mismatch detected\n"; + void SigMismatch_Handler() { + std::cerr << "Errore ASPIS: Signature mismatch detected\n"; + std::exit(EXIT_FAILURE); + } } // Executes a function/lambda in a non-duplicated context template -__attribute__((no_duplicate)) +__attribute__((annotate("exclude"))) // Marked as non-duplicable void runNoDup(F func) { func(); } +template +void run(F func) { + func(); +} + int main() { // Example 1: lambda capturing a local variable by reference int x = 0; @@ -34,6 +42,8 @@ int main() { }; runNoDup(incPtr); // non-duplicated increment of shared memory + run(incPtr); // duplicated increment of shared memory + std::cout << "Value pointed by p: " << *p << std::endl; delete p; return 0; diff --git a/testing/tests/cpp/simple/mul.cpp b/testing/tests/cpp/simple/mul.cpp index ee681a9..85c8cb5 100644 --- a/testing/tests/cpp/simple/mul.cpp +++ b/testing/tests/cpp/simple/mul.cpp @@ -1,13 +1,17 @@ #include #include -void DataCorruption_Handler() { - std::cerr << "Errore ASPIS: Data corruption rilevata\n"; - std::exit(1); -} -void SigMismatch_Handler() { - std::cerr << "Errore ASPIS: Signature mismatch rilevata\n"; - std::exit(1); +extern "C" { + // ASPIS error handling functions + void DataCorruption_Handler() { + std::cerr << "Errore ASPIS: Data corruption detected\n"; + std::exit(EXIT_FAILURE); + } + + void SigMismatch_Handler() { + std::cerr << "Errore ASPIS: Signature mismatch detected\n"; + std::exit(EXIT_FAILURE); + } } int multiply(int a, int b) diff --git a/testing/tests/cpp/simple/ptr.cpp b/testing/tests/cpp/simple/ptr.cpp index 23bab0d..08436a0 100644 --- a/testing/tests/cpp/simple/ptr.cpp +++ b/testing/tests/cpp/simple/ptr.cpp @@ -2,18 +2,20 @@ #include // ASPIS error handlers (non-duplicated) -__attribute__((no_duplicate)) -void DataCorruption_Handler() { - std::cerr << "ASPIS error: Data corruption detected\n"; -} +extern "C" { + // ASPIS error handling functions + void DataCorruption_Handler() { + std::cerr << "Errore ASPIS: Data corruption detected\n"; + std::exit(EXIT_FAILURE); + } -__attribute__((no_duplicate)) -void SigMismatch_Handler() { - std::cerr << "ASPIS error: Signature mismatch detected\n"; + void SigMismatch_Handler() { + std::cerr << "Errore ASPIS: Signature mismatch detected\n"; + std::exit(EXIT_FAILURE); + } } // Helper to print two pointer values (non-duplicated) -__attribute__((no_duplicate)) void printPointers(int *p1, int *p2) { std::cout << "Value pointed by p1: " << *p1; if (p2) { diff --git a/testing/tests/cpp/simple/stl_containers_advanced.cpp b/testing/tests/cpp/simple/stl_containers_advanced.cpp index 96804b1..b19903d 100644 --- a/testing/tests/cpp/simple/stl_containers_advanced.cpp +++ b/testing/tests/cpp/simple/stl_containers_advanced.cpp @@ -2,15 +2,17 @@ #include #include -// ASPIS error handling functions -void DataCorruption_Handler() { - std::cerr << "Errore ASPIS: Data corruption rilevata\n"; - std::exit(EXIT_FAILURE); -} +extern "C" { + // ASPIS error handling functions + void DataCorruption_Handler() { + std::cerr << "Errore ASPIS: Data corruption detected\n"; + std::exit(EXIT_FAILURE); + } -void SigMismatch_Handler() { - std::cerr << "Errore ASPIS: Signature mismatch rilevata\n"; - std::exit(EXIT_FAILURE); + void SigMismatch_Handler() { + std::cerr << "Errore ASPIS: Signature mismatch detected\n"; + std::exit(EXIT_FAILURE); + } } int main() { diff --git a/testing/tests/cpp/simple/template.cpp b/testing/tests/cpp/simple/template.cpp index efadd67..1b060b9 100644 --- a/testing/tests/cpp/simple/template.cpp +++ b/testing/tests/cpp/simple/template.cpp @@ -1,18 +1,21 @@ #include // ASPIS error handlers (non-duplicated) -__attribute__((no_duplicate)) -void DataCorruption_Handler() { - std::cerr << "ASPIS error: Data corruption detected\n"; -} +extern "C" { + // ASPIS error handling functions + void DataCorruption_Handler() { + std::cerr << "Errore ASPIS: Data corruption detected\n"; + std::exit(EXIT_FAILURE); + } -__attribute__((no_duplicate)) -void SigMismatch_Handler() { - std::cerr << "ASPIS error: Signature mismatch detected\n"; + void SigMismatch_Handler() { + std::cerr << "Errore ASPIS: Signature mismatch detected\n"; + std::exit(EXIT_FAILURE); + } } // Print function (non-duplicated) -__attribute__((no_duplicate)) +__attribute__((annotate("exclude"))) void printResult(int value) { std::cout << "Result: " << value << std::endl; } diff --git a/testing/tests/cpp/simple/threads.cpp b/testing/tests/cpp/simple/threads.cpp index 28eaf55..5bc27ae 100644 --- a/testing/tests/cpp/simple/threads.cpp +++ b/testing/tests/cpp/simple/threads.cpp @@ -13,13 +13,13 @@ __attribute__((annotate("run_adj_sig"))) thread_local int run_adj_sig = -0xDEAD; // ASPIS error handlers -extern "C" __attribute__((no_duplicate)) +extern "C" void DataCorruption_Handler() { std::cerr << "ASPIS error: Data corruption detected\n"; std::exit(EXIT_FAILURE); } -extern "C" __attribute__((no_duplicate)) +extern "C" void SigMismatch_Handler() { std::cerr << "ASPIS error: Signature mismatch detected\n"; std::exit(EXIT_FAILURE); @@ -27,8 +27,6 @@ void SigMismatch_Handler() { std::atomic counter{0}; -// Worker function marked as non-duplicable due to atomic update -__attribute__((no_duplicate)) void worker(int times) { int local_count = 0; for (int i = 0; i < times; ++i) { @@ -37,8 +35,6 @@ void worker(int times) { counter.fetch_add(local_count, std::memory_order_relaxed); } -// Thread launching logic is marked non-duplicable -__attribute__((no_duplicate)) void run_all_threads(int num_threads, int work_per_thread) { for (int i = 0; i < num_threads; ++i) { std::thread t(worker, work_per_thread); diff --git a/testing/tests/cpp/simple/volatile_memory_order.cpp b/testing/tests/cpp/simple/volatile_memory_order.cpp index 2a4455c..de9a851 100644 --- a/testing/tests/cpp/simple/volatile_memory_order.cpp +++ b/testing/tests/cpp/simple/volatile_memory_order.cpp @@ -1,14 +1,17 @@ #include // ASPIS error handlers (never duplicated) -void DataCorruption_Handler() { - std::cerr << "Data corruption detected\n"; - std::exit(1); -} +extern "C" { + // ASPIS error handling functions + void DataCorruption_Handler() { + std::cerr << "Errore ASPIS: Data corruption detected\n"; + std::exit(EXIT_FAILURE); + } -void SigMismatch_Handler() { - std::cerr << "Signature mismatch detected\n"; - std::exit(1); + void SigMismatch_Handler() { + std::cerr << "Errore ASPIS: Signature mismatch detected\n"; + std::exit(EXIT_FAILURE); + } }