@@ -342,6 +342,34 @@ store_fpregs_to_thread (const struct regcache *regcache)
}
}
+/* Fill GDB's register array with the pointer authentication mask values from
+ the current thread. */
+
+static void
+fetch_pauth_masks_from_thread (struct regcache *regcache)
+{
+ int ret, tid;
+ struct iovec iovec;
+ uint64_t pauth_regset[2] = {0, 0};
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ int dmask, cmask;
+
+ tid = ptid_get_lwp (inferior_ptid);
+
+ iovec.iov_base = &pauth_regset;
+ iovec.iov_len = sizeof (pauth_regset);
+
+ ret = ptrace (PTRACE_GETREGSET, tid, NT_ARM_PAC_MASK, &iovec);
+ if (ret != 0)
+ perror_with_name (_("unable to fetch pauth registers."));
+
+ dmask = tdep->regnum.pauth_reg_base;
+ cmask = tdep->regnum.pauth_reg_base + 1;
+ regcache_raw_supply (regcache, dmask, &pauth_regset[0]);
+ regcache_raw_supply (regcache, cmask, &pauth_regset[1]);
+}
+
/* Implement the "to_fetch_register" target_ops method. */
static void
@@ -349,15 +377,30 @@ aarch64_linux_fetch_inferior_registers (struct target_ops *ops,
struct regcache *regcache,
int regno)
{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ bool has_pauth_p = aarch64_tdep_has_pauth_p (tdep);
+
if (regno == -1)
{
fetch_gregs_from_thread (regcache);
fetch_fpregs_from_thread (regcache);
+
+ if (has_pauth_p)
+ fetch_pauth_masks_from_thread (regcache);
}
else if (regno < AARCH64_V0_REGNUM)
fetch_gregs_from_thread (regcache);
- else
+ else if (regno <= AARCH64_FPCR_REGNUM)
fetch_fpregs_from_thread (regcache);
+ else if (has_pauth_p)
+ {
+ int dmask = tdep->regnum.pauth_reg_base;
+ int cmask = tdep->regnum.pauth_reg_base + 1;
+
+ if (regno == cmask || regno == dmask)
+ fetch_pauth_masks_from_thread (regcache);
+ }
}
/* Implement the "to_store_register" target_ops method. */
@@ -501,7 +544,13 @@ aarch64_linux_read_description (struct target_ops *ops)
if (ret == 0)
return tdesc_arm_with_neon;
else
- return tdesc_aarch64;
+ {
+ CORE_ADDR hwcap = 0;
+
+ aarch64_host_hwcap (&hwcap);
+
+ return hwcap & HWCAP_APIA ? tdesc_aarch64_pauth : tdesc_aarch64;
+ }
}
/* Convert a native/host siginfo object, into/from the siginfo in the
@@ -57,6 +57,7 @@
#include "record-full.h"
#include "features/aarch64.c"
+#include "features/aarch64-pauth.c"
#include "arch/aarch64-insn.h"
@@ -157,6 +158,14 @@ static const char *const aarch64_v_register_names[] =
"fpcr"
};
+static const char *const aarch64_pauth_register_names[] =
+{
+ /* Authentication mask for data pointer. */
+ "pauth_dmask",
+ /* Authentication mask for code pointer. */
+ "pauth_cmask"
+};
+
/* AArch64 prologue cache structure. */
struct aarch64_prologue_cache
{
@@ -196,6 +205,16 @@ show_aarch64_debug (struct ui_file *file, int from_tty,
fprintf_filtered (file, _("AArch64 debugging is %s.\n"), value);
}
+/* Return TRUE if pointer authentication feature is available from those cached
+ information in TDEP in which case pauth_reg_base inside optional regnum
+ structure is not -1. Return FALSE otherwise. */
+
+bool
+aarch64_tdep_has_pauth_p (struct gdbarch_tdep *tdep)
+{
+ return tdep->regnum.pauth_reg_base != -1;
+}
+
namespace {
/* Abstract instruction reader. */
@@ -2403,6 +2422,19 @@ aarch64_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache,
gdb_assert_not_reached ("regnum out of bound");
}
+/* Implement the "cannot_store_register" gdbarch method. */
+
+static int
+aarch64_cannot_store_register (struct gdbarch *gdbarch, int regnum)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ int dmask = tdep->regnum.pauth_reg_base;
+ int cmask = tdep->regnum.pauth_reg_base + 1;
+
+ /* Pointer authentication registers are read-only. */
+ return (regnum == cmask || regnum == dmask);
+}
+
/* Callback function for user_reg_add. */
static struct value *
@@ -2854,9 +2886,11 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
const struct target_desc *tdesc = info.target_desc;
int i;
int valid_p = 1;
- const struct tdesc_feature *feature;
+ const struct tdesc_feature *feature, *feature_pauth;
int num_regs = 0;
int num_pseudo_regs = 0;
+ struct aarch64_optional_regnum *regnum;
+ int first_pauth_regnum = -1;
/* Ensure we always have a target descriptor. */
if (!tdesc_has_registers (tdesc))
@@ -2885,7 +2919,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
if (feature)
{
/* Validate the descriptor provides the mandatory V registers
- and allocate their numbers. */
+ and allocate their numbers. */
for (i = 0; i < ARRAY_SIZE (aarch64_v_register_names); i++)
valid_p &=
tdesc_numbered_register (feature, tdesc_data, AARCH64_V0_REGNUM + i,
@@ -2900,6 +2934,22 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
num_pseudo_regs += 32; /* add the Bn scalar register pseudos */
}
+ /* Look for the PAUTH registers. */
+ feature_pauth = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.pauth");
+ if (feature_pauth)
+ {
+ first_pauth_regnum = num_regs;
+ /* Validate the descriptor provides the mandatory PAUTH registers
+ and allocate their numbers. */
+ for (i = 0; i < ARRAY_SIZE (aarch64_pauth_register_names); i++)
+ valid_p &=
+ tdesc_numbered_register (feature_pauth, tdesc_data,
+ first_pauth_regnum + i,
+ aarch64_pauth_register_names[i]);
+
+ num_regs += i;
+ }
+
if (!valid_p)
{
tdesc_data_cleanup (tdesc_data);
@@ -2914,6 +2964,11 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
best_arch != NULL;
best_arch = gdbarch_list_lookup_by_info (best_arch->next, &info))
{
+ /* pauth status needs to be identical to match. */
+ if (aarch64_tdep_has_pauth_p (gdbarch_tdep (best_arch->gdbarch))
+ != (feature_pauth != NULL))
+ continue;
+
/* Found a match. */
break;
}
@@ -2932,6 +2987,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
tdep->lowest_pc = 0x20;
tdep->jb_pc = -1; /* Longjump support not enabled by default. */
tdep->jb_elt_size = 8;
+ tdep->regnum.pauth_reg_base = first_pauth_regnum;
set_gdbarch_push_dummy_call (gdbarch, aarch64_push_dummy_call);
set_gdbarch_frame_align (gdbarch, aarch64_frame_align);
@@ -2967,6 +3023,8 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_tdesc_pseudo_register_type (gdbarch, aarch64_pseudo_register_type);
set_tdesc_pseudo_register_reggroup_p (gdbarch,
aarch64_pseudo_register_reggroup_p);
+ if (aarch64_tdep_has_pauth_p (tdep))
+ set_gdbarch_cannot_store_register (gdbarch, aarch64_cannot_store_register);
/* ABI */
set_gdbarch_short_bit (gdbarch, 16);
@@ -3057,6 +3115,7 @@ _initialize_aarch64_tdep (void)
aarch64_dump_tdep);
initialize_tdesc_aarch64 ();
+ initialize_tdesc_aarch64_pauth ();
/* Debug this file's internals. */
add_setshow_boolean_cmd ("aarch64", class_maintenance, &aarch64_debug, _("\
@@ -75,6 +75,13 @@ enum aarch64_regnum
single-stepped instruction. */
#define DISPLACED_MODIFIED_INSNS 1
+/* Indexes for various registers in optional features. */
+struct aarch64_optional_regnum
+{
+ /* First pauth register number. */
+ int pauth_reg_base;
+};
+
/* Target-dependent structure in gdbarch. */
struct gdbarch_tdep
{
@@ -97,9 +104,12 @@ struct gdbarch_tdep
/* syscall record. */
int (*aarch64_syscall_record) (struct regcache *regcache, unsigned long svc_number);
+
+ struct aarch64_optional_regnum regnum;
};
extern struct target_desc *tdesc_aarch64;
+extern struct target_desc *tdesc_aarch64_pauth;
extern int aarch64_process_record (struct gdbarch *gdbarch,
struct regcache *regcache, CORE_ADDR addr);
@@ -117,4 +127,6 @@ void aarch64_displaced_step_fixup (struct gdbarch *gdbarch,
int aarch64_displaced_step_hw_singlestep (struct gdbarch *gdbarch,
struct displaced_step_closure *closure);
+bool aarch64_tdep_has_pauth_p (struct gdbarch_tdep *tdep);
+
#endif /* aarch64-tdep.h */
@@ -41175,6 +41175,9 @@ The @samp{org.gnu.gdb.aarch64.fpu} feature is optional. If present,
it should contain registers @samp{v0} through @samp{v31}, @samp{fpsr},
and @samp{fpcr}.
+The @samp{org.gnu.gdb.aarch64.pauth} feature is optional. If present,
+it should contain registers @samp{pauth_dmask} and @samp{pauth_cmask}.
+
@node ARC Features
@subsection ARC Features
@cindex target descriptions, ARC Features
@@ -44,6 +44,7 @@
# make GDB=/path/to/gdb XMLTOC="xml files" cfiles
WHICH = aarch64 \
+ aarch64-pauth \
arm/arm-with-iwmmxt arm/arm-with-vfpv2 arm/arm-with-vfpv3 \
arm/arm-with-neon \
i386/i386 i386/i386-linux \
@@ -129,6 +130,7 @@ OUTPUTS = $(patsubst %,$(outdir)/%.dat,$(WHICH))
# to make on the command line.
XMLTOC = \
aarch64.xml \
+ aarch64-pauth.xml \
arc-v2.xml \
arc-arcompact.xml \
arm/arm-with-iwmmxt.xml \
new file mode 100644
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2017 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.aarch64.pauth">
+ <reg name="pauth_dmask" bitsize="64"/>
+ <reg name="pauth_cmask" bitsize="64"/>
+</feature>
+
new file mode 100644
@@ -0,0 +1,195 @@
+/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro:
+ Original: aarch64-pauth.xml */
+
+#include "defs.h"
+#include "osabi.h"
+#include "target-descriptions.h"
+
+struct target_desc *tdesc_aarch64_pauth;
+static void
+initialize_tdesc_aarch64_pauth (void)
+{
+ struct target_desc *result = allocate_target_description ();
+ struct tdesc_feature *feature;
+ struct tdesc_type *field_type;
+ struct tdesc_type *type;
+
+ set_tdesc_architecture (result, bfd_scan_arch ("aarch64"));
+
+ feature = tdesc_create_feature (result, "org.gnu.gdb.aarch64.core");
+ type = tdesc_create_flags (feature, "cpsr_flags", 4);
+ tdesc_add_flag (type, 0, "SP");
+ tdesc_add_flag (type, 1, "");
+ tdesc_add_bitfield (type, "EL", 2, 3);
+ tdesc_add_flag (type, 4, "nRW");
+ tdesc_add_flag (type, 5, "");
+ tdesc_add_flag (type, 6, "F");
+ tdesc_add_flag (type, 7, "I");
+ tdesc_add_flag (type, 8, "A");
+ tdesc_add_flag (type, 9, "D");
+ tdesc_add_flag (type, 20, "IL");
+ tdesc_add_flag (type, 21, "SS");
+ tdesc_add_flag (type, 28, "V");
+ tdesc_add_flag (type, 29, "C");
+ tdesc_add_flag (type, 30, "Z");
+ tdesc_add_flag (type, 31, "N");
+
+ tdesc_create_reg (feature, "x0", 0, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "x1", 1, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "x2", 2, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "x3", 3, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "x4", 4, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "x5", 5, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "x6", 6, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "x7", 7, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "x8", 8, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "x9", 9, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "x10", 10, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "x11", 11, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "x12", 12, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "x13", 13, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "x14", 14, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "x15", 15, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "x16", 16, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "x17", 17, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "x18", 18, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "x19", 19, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "x20", 20, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "x21", 21, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "x22", 22, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "x23", 23, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "x24", 24, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "x25", 25, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "x26", 26, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "x27", 27, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "x28", 28, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "x29", 29, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "x30", 30, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "sp", 31, 1, NULL, 64, "data_ptr");
+ tdesc_create_reg (feature, "pc", 32, 1, NULL, 64, "code_ptr");
+ tdesc_create_reg (feature, "cpsr", 33, 1, NULL, 32, "cpsr_flags");
+
+ feature = tdesc_create_feature (result, "org.gnu.gdb.aarch64.fpu");
+ field_type = tdesc_named_type (feature, "ieee_double");
+ tdesc_create_vector (feature, "v2d", field_type, 2);
+
+ field_type = tdesc_named_type (feature, "uint64");
+ tdesc_create_vector (feature, "v2u", field_type, 2);
+
+ field_type = tdesc_named_type (feature, "int64");
+ tdesc_create_vector (feature, "v2i", field_type, 2);
+
+ field_type = tdesc_named_type (feature, "ieee_single");
+ tdesc_create_vector (feature, "v4f", field_type, 4);
+
+ field_type = tdesc_named_type (feature, "uint32");
+ tdesc_create_vector (feature, "v4u", field_type, 4);
+
+ field_type = tdesc_named_type (feature, "int32");
+ tdesc_create_vector (feature, "v4i", field_type, 4);
+
+ field_type = tdesc_named_type (feature, "uint16");
+ tdesc_create_vector (feature, "v8u", field_type, 8);
+
+ field_type = tdesc_named_type (feature, "int16");
+ tdesc_create_vector (feature, "v8i", field_type, 8);
+
+ field_type = tdesc_named_type (feature, "uint8");
+ tdesc_create_vector (feature, "v16u", field_type, 16);
+
+ field_type = tdesc_named_type (feature, "int8");
+ tdesc_create_vector (feature, "v16i", field_type, 16);
+
+ field_type = tdesc_named_type (feature, "uint128");
+ tdesc_create_vector (feature, "v1u", field_type, 1);
+
+ field_type = tdesc_named_type (feature, "int128");
+ tdesc_create_vector (feature, "v1i", field_type, 1);
+
+ type = tdesc_create_union (feature, "vnd");
+ field_type = tdesc_named_type (feature, "v2d");
+ tdesc_add_field (type, "f", field_type);
+ field_type = tdesc_named_type (feature, "v2u");
+ tdesc_add_field (type, "u", field_type);
+ field_type = tdesc_named_type (feature, "v2i");
+ tdesc_add_field (type, "s", field_type);
+
+ type = tdesc_create_union (feature, "vns");
+ field_type = tdesc_named_type (feature, "v4f");
+ tdesc_add_field (type, "f", field_type);
+ field_type = tdesc_named_type (feature, "v4u");
+ tdesc_add_field (type, "u", field_type);
+ field_type = tdesc_named_type (feature, "v4i");
+ tdesc_add_field (type, "s", field_type);
+
+ type = tdesc_create_union (feature, "vnh");
+ field_type = tdesc_named_type (feature, "v8u");
+ tdesc_add_field (type, "u", field_type);
+ field_type = tdesc_named_type (feature, "v8i");
+ tdesc_add_field (type, "s", field_type);
+
+ type = tdesc_create_union (feature, "vnb");
+ field_type = tdesc_named_type (feature, "v16u");
+ tdesc_add_field (type, "u", field_type);
+ field_type = tdesc_named_type (feature, "v16i");
+ tdesc_add_field (type, "s", field_type);
+
+ type = tdesc_create_union (feature, "vnq");
+ field_type = tdesc_named_type (feature, "v1u");
+ tdesc_add_field (type, "u", field_type);
+ field_type = tdesc_named_type (feature, "v1i");
+ tdesc_add_field (type, "s", field_type);
+
+ type = tdesc_create_union (feature, "aarch64v");
+ field_type = tdesc_named_type (feature, "vnd");
+ tdesc_add_field (type, "d", field_type);
+ field_type = tdesc_named_type (feature, "vns");
+ tdesc_add_field (type, "s", field_type);
+ field_type = tdesc_named_type (feature, "vnh");
+ tdesc_add_field (type, "h", field_type);
+ field_type = tdesc_named_type (feature, "vnb");
+ tdesc_add_field (type, "b", field_type);
+ field_type = tdesc_named_type (feature, "vnq");
+ tdesc_add_field (type, "q", field_type);
+
+ tdesc_create_reg (feature, "v0", 34, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v1", 35, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v2", 36, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v3", 37, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v4", 38, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v5", 39, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v6", 40, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v7", 41, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v8", 42, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v9", 43, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v10", 44, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v11", 45, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v12", 46, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v13", 47, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v14", 48, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v15", 49, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v16", 50, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v17", 51, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v18", 52, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v19", 53, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v20", 54, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v21", 55, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v22", 56, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v23", 57, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v24", 58, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v25", 59, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v26", 60, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v27", 61, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v28", 62, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v29", 63, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v30", 64, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "v31", 65, 1, NULL, 128, "aarch64v");
+ tdesc_create_reg (feature, "fpsr", 66, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "fpcr", 67, 1, NULL, 32, "int");
+
+ feature = tdesc_create_feature (result, "org.gnu.gdb.aarch64.pauth");
+ tdesc_create_reg (feature, "pauth_dmask", 68, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "pauth_cmask", 69, 1, NULL, 64, "int");
+
+ tdesc_aarch64_pauth = result;
+}
new file mode 100644
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2017 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+ <architecture>aarch64</architecture>
+ <xi:include href="aarch64-core.xml"/>
+ <xi:include href="aarch64-fpu.xml"/>
+ <xi:include href="aarch64-pauth-core.xml"/>
+</target>
+
@@ -237,3 +237,35 @@ aarch64_ps_get_thread_area (struct ps_prochandle *ph,
return PS_OK;
}
+
+#ifdef HAVE_GETAUXVAL
+#include <sys/auxv.h>
+#endif
+
+/* Get the HWCAP from the process of GDB or GDBserver. If success,
+ save it in *VALP. */
+
+void
+aarch64_host_hwcap (CORE_ADDR *valp)
+{
+#ifdef HAVE_GETAUXVAL
+ *valp = getauxval (AT_HWCAP);
+#else
+ CORE_ADDR data[2];
+ FILE *f = fopen ("/proc/self/auxv", "r");
+
+ if (f == NULL)
+ return;
+
+ while (fread (data, sizeof (data), 1, f) > 0)
+ {
+ if (data[0] == AT_HWCAP)
+ {
+ *valp = data[1];
+ break;
+ }
+ }
+
+ fclose (f);
+#endif /* HAVE_GETAUXVAL */
+}
@@ -126,4 +126,12 @@ ps_err_e aarch64_ps_get_thread_area (struct ps_prochandle *ph,
lwpid_t lwpid, int idx, void **base,
int is_64bit_p);
+#ifndef HWCAP_APIA
+/* AArch64 GNU/Linux HWCAP values. These should be synced with kernel
+ definitions. */
+#define HWCAP_APIA (1 << 16)
+#endif
+
+void aarch64_host_hwcap (CORE_ADDR *valp);
+
#endif /* AARCH64_LINUX_H */
new file mode 100644
@@ -0,0 +1,75 @@
+# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro:
+# Generated from: aarch64-pauth.xml
+name:aarch64_pauth
+xmltarget:aarch64-pauth.xml
+expedite:x29,sp,pc
+64:x0
+64:x1
+64:x2
+64:x3
+64:x4
+64:x5
+64:x6
+64:x7
+64:x8
+64:x9
+64:x10
+64:x11
+64:x12
+64:x13
+64:x14
+64:x15
+64:x16
+64:x17
+64:x18
+64:x19
+64:x20
+64:x21
+64:x22
+64:x23
+64:x24
+64:x25
+64:x26
+64:x27
+64:x28
+64:x29
+64:x30
+64:sp
+64:pc
+32:cpsr
+128:v0
+128:v1
+128:v2
+128:v3
+128:v4
+128:v5
+128:v6
+128:v7
+128:v8
+128:v9
+128:v10
+128:v11
+128:v12
+128:v13
+128:v14
+128:v15
+128:v16
+128:v17
+128:v18
+128:v19
+128:v20
+128:v21
+128:v22
+128:v23
+128:v24
+128:v25
+128:v26
+128:v27
+128:v28
+128:v29
+128:v30
+128:v31
+32:fpsr
+32:fpcr
+64:pauth_dmask
+64:pauth_cmask
@@ -613,6 +613,8 @@
/* note name must be "LINUX". */
#define NT_ARM_SVE 0x405 /* AArch SVE registers. */
/* note name must be "LINUX". */
+#define NT_ARM_PAC_MASK 0x406 /* AArch PAC mask registers. */
+ /* note name must be "LINUX". */
#define NT_SIGINFO 0x53494749 /* Fields of siginfo_t. */
#define NT_FILE 0x46494c45 /* Description of mapped files. */