For a 64-bit parent debugging a 32-bit child, add tests for reading the
TLS registers, and mangling with the mode bits in CPSR.

Signed-off-by: Dev Jain <dev.j...@arm.com>
---
 tools/testing/selftests/arm/abi/ptrace_64.c   | 91 +++++++++++++++++++
 .../selftests/arm/abi/trivial_32bit_program.c | 14 +++
 2 files changed, 105 insertions(+)
 create mode 100644 tools/testing/selftests/arm/abi/ptrace_64.c
 create mode 100644 tools/testing/selftests/arm/abi/trivial_32bit_program.c

diff --git a/tools/testing/selftests/arm/abi/ptrace_64.c 
b/tools/testing/selftests/arm/abi/ptrace_64.c
new file mode 100644
index 000000000000..97398cf59052
--- /dev/null
+++ b/tools/testing/selftests/arm/abi/ptrace_64.c
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 ARM Limited.
+ *
+ * Inspired from selftests/arm64/abi/ptrace.c
+ *
+ * Author: Dev Jain <dev.j...@arm.com>
+ *
+ */
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/auxv.h>
+#include <sys/prctl.h>
+#include <sys/ptrace.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/wait.h>
+#include <asm/sigcontext.h>
+#include <asm/ptrace.h>
+
+#include "ptrace.h"
+#include "../../kselftest.h"
+
+#define EXPECTED_TESTS 12
+#define NUM_TLS_REGS   2
+
+static void test_tpidr(pid_t child)
+{
+       unsigned int read_val[NUM_TLS_REGS];
+       struct iovec read_iov;
+       int ret;
+
+       memset(read_val, 0, sizeof(read_val));
+
+       read_iov.iov_base = read_val;
+
+       /* Should be able to read a single TLS register... */
+       read_iov.iov_len = 2 * sizeof(unsigned int);
+       ret = ptrace(PTRACE_GETREGSET, child, NT_ARM_TLS, &read_iov);
+       ksft_test_result(ret == 0, "read_tls\n");
+
+       ksft_test_result(read_val[0], "read_tls_1\n");
+       ksft_test_result(!read_val[1], "cannot read_tls_2\n");
+}
+
+static void run_tests(pid_t child)
+{
+       test_tpidr(child);
+       test_user_regs(child);
+       test_hw_debug(child, NT_ARM_HW_WATCH, "NT_ARM_HW_WATCH");
+       test_hw_debug(child, NT_ARM_HW_BREAK, "NT_ARM_HW_BREAK");
+}
+
+static int do_child(void)
+{
+       if (ptrace(PTRACE_TRACEME, -1, NULL, NULL))
+               ksft_exit_fail_perror("PTRACE_TRACEME");
+
+       /* SIGTRAP makes the child stop after exec; do_parent() resumes it */
+       execv("trivial_32bit_program", NULL);
+       return EXIT_SUCCESS;
+}
+
+int main(void)
+{
+       int ret = EXIT_SUCCESS;
+       pid_t child;
+
+       srandom(getpid());
+
+       ksft_print_header();
+
+       ksft_set_plan(EXPECTED_TESTS);
+
+       child = fork();
+       if (!child)
+               return do_child();
+
+       if (do_parent(child))
+               ret = EXIT_FAILURE;
+
+       ksft_print_cnts();
+
+       return ret;
+}
diff --git a/tools/testing/selftests/arm/abi/trivial_32bit_program.c 
b/tools/testing/selftests/arm/abi/trivial_32bit_program.c
new file mode 100644
index 000000000000..c5ad7abb23ed
--- /dev/null
+++ b/tools/testing/selftests/arm/abi/trivial_32bit_program.c
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 ARM Limited.
+ */
+
+#include <stdio.h>
+#include <signal.h>
+
+int main(void)
+{
+       raise(SIGSTOP);
+       raise(SIGSTOP);
+       return 0;
+}
-- 
2.39.2


Reply via email to