| #!/bin/bash |
| set -exuo pipefail |
| |
| function build { |
| CRATE=enclave |
| |
| mkdir -p "${WORK_DIR}" |
| pushd "${WORK_DIR}" |
| rm -rf "${CRATE}" |
| cp -a "${TEST_DIR}"/enclave . |
| pushd $CRATE |
| echo "${WORK_DIR}" |
| # HACK(eddyb) sets `RUSTC_BOOTSTRAP=1` so Cargo can accept nightly features. |
| # These come from the top-level Rust workspace, that this crate is not a |
| # member of, but Cargo tries to load the workspace `Cargo.toml` anyway. |
| env RUSTC_BOOTSTRAP=1 |
| cargo -v run --target "${TARGET}" |
| popd |
| popd |
| } |
| |
| function check { |
| local func_re="$1" |
| local checks="${TEST_DIR}/$2" |
| local asm="" |
| local objdump="${LLVM_BIN_DIR}/llvm-objdump" |
| local filecheck="${LLVM_BIN_DIR}/FileCheck" |
| local enclave=${WORK_DIR}/enclave/target/x86_64-fortanix-unknown-sgx/debug/enclave |
| |
| asm=$(mktemp) |
| func="$(${objdump} --syms --demangle "${enclave}" | \ |
| grep --only-matching -E "[[:blank:]]+${func_re}\$" | \ |
| sed -e 's/^[[:space:]]*//' )" |
| ${objdump} --disassemble-symbols="${func}" --demangle \ |
| "${enclave}" > "${asm}" |
| ${filecheck} --input-file "${asm}" "${checks}" |
| |
| if [ "${func_re}" != "rust_plus_one_global_asm" ] && |
| [ "${func_re}" != "cmake_plus_one_c_global_asm" ] && |
| [ "${func_re}" != "cmake_plus_one_cxx_global_asm" ]; then |
| # The assembler cannot avoid explicit `ret` instructions. Sequences |
| # of `shlq $0x0, (%rsp); lfence; retq` are used instead. |
| # https://www.intel.com/content/www/us/en/developer/articles/technical/ |
| # software-security-guidance/technical-documentation/load-value-injection.html |
| ${filecheck} --implicit-check-not ret --input-file "${asm}" "${checks}" |
| fi |
| } |
| |
| build |
| |
| check "unw_getcontext" unw_getcontext.checks |
| check "__libunwind_Registers_x86_64_jumpto" jumpto.checks |
| check 'std::io::stdio::_print::[[:alnum:]]+' print.with_frame_pointers.checks || |
| check 'std::io::stdio::_print::[[:alnum:]]+' print.without_frame_pointers.checks |
| check rust_plus_one_global_asm rust_plus_one_global_asm.checks |
| |
| check cc_plus_one_c cc_plus_one_c.checks |
| check cc_plus_one_c_asm cc_plus_one_c_asm.checks |
| check cc_plus_one_cxx cc_plus_one_cxx.checks |
| check cc_plus_one_cxx_asm cc_plus_one_cxx_asm.checks |
| check cc_plus_one_asm cc_plus_one_asm.checks |
| |
| check cmake_plus_one_c cmake_plus_one_c.checks |
| check cmake_plus_one_c_asm cmake_plus_one_c_asm.checks |
| check cmake_plus_one_c_global_asm cmake_plus_one_c_global_asm.checks |
| check cmake_plus_one_cxx cmake_plus_one_cxx.checks |
| check cmake_plus_one_cxx_asm cmake_plus_one_cxx_asm.checks |
| check cmake_plus_one_cxx_global_asm cmake_plus_one_cxx_global_asm.checks |
| check cmake_plus_one_asm cmake_plus_one_asm.checks |