return aarch32_read_description ();
CORE_ADDR hwcap = linux_get_hwcap (this);
- CORE_ADDR hwcap2 = linux_get_hwcap2 (this);
bool pauth_p = hwcap & AARCH64_HWCAP_PACA;
- bool capability_p = hwcap2 & HWCAP2_MORELLO;
+ /* We cannot use HWCAP2_MORELLO to check for Morello support. */
+ bool capability_p = aarch64_supports_morello (tid);
return aarch64_read_description (aarch64_sve_get_vq (tid),
pauth_p, capability_p);
struct target_ops *target, bfd *abfd)
{
CORE_ADDR hwcap = linux_get_hwcap (target);
- CORE_ADDR hwcap2 = linux_get_hwcap2 (target);
bool pauth_p = hwcap & AARCH64_HWCAP_PACA;
- bool capability_p = hwcap2 & HWCAP2_MORELLO;
+ /* We cannot use HWCAP2_MORELLO to check for Morello support. Check if
+ we have a NT_ARM_MORELLO register set dump instead. */
+ bool capability_p =
+ (bfd_get_section_by_name (abfd, ".reg-aarch-morello") != nullptr);
return aarch64_read_description (aarch64_linux_core_read_vq (gdbarch, abfd),
pauth_p, capability_p);
#ifndef ARCH_AARCH64_CAP_LINUX_H
#define ARCH_AARCH64_CAP_LINUX_H
-/* Morello HWCAP bit. */
-#define HWCAP2_MORELLO (1 << 19)
+#include "gdbsupport/common-defs.h"
+#include "gdbsupport/byte-vector.h"
+
+/* The HWCAP values are not being used to identify Morello anymore, but are
+ kept here for reference in case someone has a need for them. */
+/* Morello HWCAP bit V1, before Linux Kernel 5.18. */
+#define HWCAP2_MORELLO_V1 (1 << 19)
+/* Morello HWCAP bit V2, after Linux Kernel 5.18. */
+#define HWCAP2_MORELLO_V2 (1UL << 31)
/* Size of the Capability register set. */
#define AARCH64_LINUX_CREGS_SIZE ((39 * 16) + (2 * 8))
#include "gdbsupport/common-defs.h"
#include "gdb_ptrace.h"
#include "aarch64-cap-linux.h"
+#include <sys/uio.h>
+#include "elf/common.h"
/* Helper function to display various possible errors when reading
Morello capabilities from memory. */
return true;
}
+
+/* See aach64-cap-linux.h */
+
+bool
+aarch64_supports_morello (int tid)
+{
+ struct user_morello_state cregset;
+ struct iovec iovec;
+ iovec.iov_base = &cregset;
+ iovec.iov_len = sizeof (cregset);
+
+ /* Attempt to fetch NT_ARM_MORELLO. If it is supported, that means Morello
+ features are supported and that PTRACE_PEEKCAP and PTRACE_POKECAP are
+ also supported. */
+ if (ptrace (PTRACE_GETREGSET, tid, NT_ARM_MORELLO, &iovec) < 0)
+ return false;
+
+ return true;
+}
extern bool aarch64_linux_write_capability (int tid, CORE_ADDR address,
const user_cap &cap);
+
+/* Return true if the target supports Morello features (NT_ARM_MORELLO register
+ set, PTRACE_PEEKCAP and PTRACE_POKECAP). If it does, it means we are
+ dealing with a Morello Linux Kernel. This is needed because we can't
+ rely on the HWCAP2_MORELLO value anymore, given it has changed.
+
+ Return false otherwise. */
+
+extern bool aarch64_supports_morello (int tid);
+
#endif /* NAT_AARCH64_CAP_LINUX_H */
/* Kill CHILD. WHO is used to report warnings. */
-static void
-kill_child (pid_t child, const char *who)
+void
+linux_kill_child (pid_t child, const char *who)
{
pid_t got_pid;
int kill_status;
{
warning (_("linux_ptrace_test_ret_to_nx: status %d is not WIFSTOPPED!"),
status);
- kill_child (child, "linux_ptrace_test_ret_to_nx");
+ linux_kill_child (child, "linux_ptrace_test_ret_to_nx");
return;
}
warning (_("linux_ptrace_test_ret_to_nx: "
"WSTOPSIG %d is neither SIGTRAP nor SIGSEGV!"),
(int) WSTOPSIG (status));
- kill_child (child, "linux_ptrace_test_ret_to_nx");
+ linux_kill_child (child, "linux_ptrace_test_ret_to_nx");
return;
}
# error "!__i386__ && !__x86_64__"
#endif
- kill_child (child, "linux_ptrace_test_ret_to_nx");
+ linux_kill_child (child, "linux_ptrace_test_ret_to_nx");
/* + 1 is there as x86* stops after the 'int3' instruction. */
if (WSTOPSIG (status) == SIGTRAP && pc == return_address + 1)
static void linux_test_for_tracefork (int child_pid);
static void linux_test_for_exitkill (int child_pid);
-/* Determine ptrace features available on this target. */
+/* Create a child for testing ptrace features and return its pid. */
-void
-linux_check_ptrace_features (void)
+int
+linux_create_child_for_ptrace_testing ()
{
int child_pid, ret, status;
error (_("linux_check_ptrace_features: waitpid: unexpected status %d."),
status);
+ return child_pid;
+}
+
+
+/* Determine ptrace features available on this target. */
+
+void
+linux_check_ptrace_features (void)
+{
+ int child_pid = linux_create_child_for_ptrace_testing ();
+
linux_test_for_tracesysgood (child_pid);
linux_test_for_tracefork (child_pid);
linux_test_for_exitkill (child_pid);
/* Kill child_pid. */
- kill_child (child_pid, "linux_check_ptrace_features");
+ linux_kill_child (child_pid, "linux_check_ptrace_features");
}
/* Determine if PTRACE_O_TRACESYSGOOD can be used to catch
/* Do some cleanup and kill the grandchild. */
my_waitpid (second_pid, &second_status, 0);
- kill_child (second_pid, "linux_test_for_tracefork");
+ linux_kill_child (second_pid, "linux_test_for_tracefork");
}
}
else
extern int linux_ptrace_get_extended_event (int wstat);
extern int linux_is_extended_waitstatus (int wstat);
extern int linux_wstatus_maybe_breakpoint (int wstat);
-
+extern void linux_kill_child (pid_t child, const char *who);
+extern int linux_create_child_for_ptrace_testing ();
#endif /* NAT_LINUX_PTRACE_H */
{
uint64_t vq = aarch64_sve_get_vq (tid);
unsigned long hwcap = linux_get_hwcap ();
- unsigned long hwcap2 = linux_get_hwcap2 ();
bool pauth_p = hwcap & AARCH64_HWCAP_PACA;
- bool capability_p = hwcap2 & HWCAP2_MORELLO;
+ /* We cannot use HWCAP2_MORELLO to check for Morello support. */
+ bool capability_p = aarch64_supports_morello (tid);
current_process ()->tdesc = aarch64_linux_read_description (vq, pauth_p,
capability_p);
return arm_breakpoint_kind_from_current_state (pcptr);
}
+static bool
+aarch64_supports_morello_features ()
+{
+ /* Spawn a child for testing. */
+ int child_pid = linux_create_child_for_ptrace_testing ();
+ bool ret = aarch64_supports_morello (child_pid);
+ /* Kill child_pid. */
+ linux_kill_child (child_pid, "aarch64_check_ptrace_features");
+ return ret;
+}
+
/* Implementation of targets ops method "supports_qxfer_capability. */
bool
aarch64_target::supports_qxfer_capability ()
{
- unsigned long hwcap2 = linux_get_hwcap2 ();
-
- return (hwcap2 & HWCAP2_MORELLO) != 0;
+ /* Do a live ptrace feature check instead of using HWCAP bits. */
+ return aarch64_supports_morello_features ();
}
/* Implementation of targets ops method "qxfer_capability. */