Add unaligned_data.c to exercise unaligned memh/memw/memd accesses and verify SIGBUS is raised and caught.
Signed-off-by: Brian Cain <[email protected]> --- tests/tcg/hexagon/Makefile.target | 2 + tests/tcg/hexagon/unaligned_data.c | 118 +++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 tests/tcg/hexagon/unaligned_data.c diff --git a/tests/tcg/hexagon/Makefile.target b/tests/tcg/hexagon/Makefile.target index 70a8ec2e7fb..a2a0ffc69b2 100644 --- a/tests/tcg/hexagon/Makefile.target +++ b/tests/tcg/hexagon/Makefile.target @@ -54,6 +54,7 @@ HEX_TESTS += invalid-slots HEX_TESTS += invalid-encoding HEX_TESTS += multiple-writes HEX_TESTS += unaligned_pc +HEX_TESTS += unaligned_data HEX_TESTS += test_abs HEX_TESTS += test_bitcnt @@ -108,6 +109,7 @@ preg_alias: preg_alias.c hex_test.h read_write_overlap: read_write_overlap.c hex_test.h reg_mut: reg_mut.c hex_test.h test_pnew_jump_loads: test_pnew_jump_loads.c hex_test.h +unaligned_data: unaligned_data.c hex_test.h unaligned_pc: unaligned_pc.c # Compile for v66 so that the ELF selects a v66 CPU; the test then diff --git a/tests/tcg/hexagon/unaligned_data.c b/tests/tcg/hexagon/unaligned_data.c new file mode 100644 index 00000000000..e0375faafbe --- /dev/null +++ b/tests/tcg/hexagon/unaligned_data.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +/* + * Test that unaligned scalar loads raise SIGBUS. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <stdint.h> +#include <stdbool.h> +#include <setjmp.h> +#include <signal.h> + +int err; + +#include "hex_test.h" + +static bool sigbus_caught; +static sigjmp_buf jmp_env; +static uint64_t buf[2] = { 0, 0 }; + +static void sigbus_handler(int sig, siginfo_t *info, void *puc) +{ + check32(sig, SIGBUS); + sigbus_caught = true; + siglongjmp(jmp_env, 1); +} + +static void test_unaligned_load(int size, int offset) +{ + char *p = (char *)buf + offset; + uint32_t dummy32; + uint64_t dummy64; + + sigbus_caught = false; + if (sigsetjmp(jmp_env, 1) == 0) { + switch (size) { + case 2: + asm volatile("%[dst] = memh(%[src])\n\t" + : [dst] "=r"(dummy32) : [src] "r"(p) : "memory"); + break; + case 4: + asm volatile("%[dst] = memw(%[src])\n\t" + : [dst] "=r"(dummy32) : [src] "r"(p) : "memory"); + break; + case 8: + asm volatile("%[dst] = memd(%[src])\n\t" + : [dst] "=r"(dummy64) : [src] "r"(p) : "memory"); + break; + default: + abort(); + } + } + check32(sigbus_caught, true); +} + +static void test_unaligned_store(int size, int offset) +{ + char *p = (char *)buf + offset; + uint32_t val32 = 0x11223344; + uint64_t val64 = 0x1122334455667788ULL; + + sigbus_caught = false; + if (sigsetjmp(jmp_env, 1) == 0) { + switch (size) { + case 2: + asm volatile("memh(%[addr]) = %[val]\n\t" + : : [addr] "r"(p), [val] "r"(val32) : "memory"); + break; + case 4: + asm volatile("memw(%[addr]) = %[val]\n\t" + : : [addr] "r"(p), [val] "r"(val32) : "memory"); + break; + case 8: + asm volatile("memd(%[addr]) = %[val]\n\t" + : : [addr] "r"(p), [val] "r"(val64) : "memory"); + break; + default: + abort(); + } + } + check32(sigbus_caught, true); +} + +int main() +{ + struct sigaction act; + + act.sa_sigaction = sigbus_handler; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_SIGINFO; + chk_error(sigaction(SIGBUS, &act, NULL)); + + test_unaligned_load(2, 1); + test_unaligned_load(4, 1); + test_unaligned_load(4, 2); + test_unaligned_load(4, 3); + test_unaligned_load(8, 1); + test_unaligned_load(8, 4); + + test_unaligned_store(2, 1); + test_unaligned_store(4, 1); + test_unaligned_store(4, 2); + test_unaligned_store(4, 3); + test_unaligned_store(8, 1); + test_unaligned_store(8, 4); + + act.sa_handler = SIG_DFL; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + chk_error(sigaction(SIGBUS, &act, NULL)); + + puts(err ? "FAIL" : "PASS"); + return err ? EXIT_FAILURE : EXIT_SUCCESS; +} -- 2.34.1
