+2019-03-26 Alan Hayward <alan.hayward@arm.com>
+
+ * linux-aarch64-low.c (aarch64_get_hwcap): Remove function.
+ (aarch64_arch_setup): Call linux_get_hwcap.
+ * linux-arm-low.c (arm_get_hwcap): Remove function.
+ (arm_read_description): Call linux_get_hwcap.
+ * linux-low.c (linux_get_auxv): New function.
+ (linux_get_hwcap): Likewise.
+ (linux_get_hwcap2): Likewise.
+ * linux-low.h (linux_get_hwcap): New declaration.
+ (linux_get_hwcap2): Likewise.
+ * linux-ppc-low.c (ppc_get_auxv): Remove function.
+ (ppc_arch_setup): Call linux_get_hwcap.
+ * linux-s390-low.c (s390_get_hwcap): Remove function.
+ (s390_arch_setup): Call linux_get_hwcap.
+
2019-03-22 Alan Hayward <alan.hayward@arm.com>
Jiong Wang <jiong.wang@arm.com>
/* Matches HWCAP_PACA in kernel header arch/arm64/include/uapi/asm/hwcap.h. */
#define AARCH64_HWCAP_PACA (1 << 30)
-/* Fetch the AT_HWCAP entry from the auxv vector. */
-
-static bool
-aarch64_get_hwcap (unsigned long *valp)
-{
- unsigned char *data = (unsigned char *) alloca (16);
- int offset = 0;
-
- while ((*the_target->read_auxv) (offset, data, 16) == 16)
- {
- unsigned long *data_p = (unsigned long *)data;
- if (data_p[0] == AT_HWCAP)
- {
- *valp = data_p[1];
- return true;
- }
-
- offset += 16;
- }
-
- *valp = 0;
- return false;
-}
-
/* Implementation of linux_target_ops method "arch_setup". */
static void
if (is_elf64)
{
uint64_t vq = aarch64_sve_get_vq (tid);
- unsigned long hwcap = 0;
- bool pauth_p = aarch64_get_hwcap (&hwcap) && (hwcap & AARCH64_HWCAP_PACA);
+ unsigned long hwcap = linux_get_hwcap (8);
+ bool pauth_p = hwcap & AARCH64_HWCAP_PACA;
current_process ()->tdesc = aarch64_linux_read_description (vq, pauth_p);
}
return next_pc;
}
-static int
-arm_get_hwcap (unsigned long *valp)
-{
- unsigned char *data = (unsigned char *) alloca (8);
- int offset = 0;
-
- while ((*the_target->read_auxv) (offset, data, 8) == 8)
- {
- unsigned int *data_p = (unsigned int *)data;
- if (data_p[0] == AT_HWCAP)
- {
- *valp = data_p[1];
- return 1;
- }
-
- offset += 8;
- }
-
- *valp = 0;
- return 0;
-}
-
static const struct target_desc *
arm_read_description (void)
{
int pid = lwpid_of (current_thread);
- unsigned long arm_hwcap = 0;
+ unsigned long arm_hwcap = linux_get_hwcap (4);
/* Query hardware watchpoint/breakpoint capabilities. */
arm_linux_init_hwbp_cap (pid);
- if (arm_get_hwcap (&arm_hwcap) == 0)
- return tdesc_arm;
-
if (arm_hwcap & HWCAP_IWMMXT)
return tdesc_arm_with_iwmmxt;
return pc;
}
+/* Fetch the entry MATCH from the auxv vector, where entries are length
+ WORDSIZE. If no entry was found, return zero. */
+
+static CORE_ADDR
+linux_get_auxv (int wordsize, CORE_ADDR match)
+{
+ gdb_byte *data = (gdb_byte *) alloca (2 * wordsize);
+ int offset = 0;
+
+ gdb_assert (wordsize == 4 || wordsize == 8);
+
+ while ((*the_target->read_auxv) (offset, data, 2 * wordsize) == 2 * wordsize)
+ {
+ if (wordsize == 4)
+ {
+ uint32_t *data_p = (uint32_t *)data;
+ if (data_p[0] == match)
+ return data_p[1];
+ }
+ else
+ {
+ uint64_t *data_p = (uint64_t *)data;
+ if (data_p[0] == match)
+ return data_p[1];
+ }
+
+ offset += 2 * wordsize;
+ }
+
+ return 0;
+}
+
+/* See linux-low.h. */
+
+CORE_ADDR
+linux_get_hwcap (int wordsize)
+{
+ return linux_get_auxv (wordsize, AT_HWCAP);
+}
+
+/* See linux-low.h. */
+
+CORE_ADDR
+linux_get_hwcap2 (int wordsize)
+{
+ return linux_get_auxv (wordsize, AT_HWCAP2);
+}
static struct target_ops linux_target_ops = {
linux_create_inferior,
extern int have_ptrace_getregset;
+/* Fetch the AT_HWCAP entry from the auxv vector, where entries are length
+ WORDSIZE. If no entry was found, return zero. */
+
+CORE_ADDR linux_get_hwcap (int wordsize);
+
+/* Fetch the AT_HWCAP2 entry from the auxv vector, where entries are length
+ WORDSIZE. If no entry was found, return zero. */
+
+CORE_ADDR linux_get_hwcap2 (int wordsize);
+
#endif /* GDBSERVER_LINUX_LOW_H */
}
}
-
-static int
-ppc_get_auxv (unsigned long type, unsigned long *valp)
-{
- const struct target_desc *tdesc = current_process ()->tdesc;
- int wordsize = register_size (tdesc, 0);
- unsigned char *data = (unsigned char *) alloca (2 * wordsize);
- int offset = 0;
-
- while ((*the_target->read_auxv) (offset, data, 2 * wordsize) == 2 * wordsize)
- {
- if (wordsize == 4)
- {
- unsigned int *data_p = (unsigned int *)data;
- if (data_p[0] == type)
- {
- *valp = data_p[1];
- return 1;
- }
- }
- else
- {
- unsigned long *data_p = (unsigned long *)data;
- if (data_p[0] == type)
- {
- *valp = data_p[1];
- return 1;
- }
- }
-
- offset += 2 * wordsize;
- }
-
- *valp = 0;
- return 0;
-}
-
#ifndef __powerpc64__
static int ppc_regmap_adjusted;
#endif
/* The value of current_process ()->tdesc needs to be set for this
call. */
- ppc_get_auxv (AT_HWCAP, &ppc_hwcap);
- ppc_get_auxv (AT_HWCAP2, &ppc_hwcap2);
+ ppc_hwcap = linux_get_hwcap (features.wordsize);
+ ppc_hwcap2 = linux_get_hwcap2 (features.wordsize);
features.isa205 = ppc_linux_has_isa205 (ppc_hwcap);
}
}
-/* Get HWCAP from AUXV, using the given WORDSIZE. Return the HWCAP, or
- zero if not found. */
-
-static unsigned long
-s390_get_hwcap (int wordsize)
-{
- gdb_byte *data = (gdb_byte *) alloca (2 * wordsize);
- int offset = 0;
-
- while ((*the_target->read_auxv) (offset, data, 2 * wordsize) == 2 * wordsize)
- {
- if (wordsize == 4)
- {
- unsigned int *data_p = (unsigned int *)data;
- if (data_p[0] == AT_HWCAP)
- return data_p[1];
- }
- else
- {
- unsigned long *data_p = (unsigned long *)data;
- if (data_p[0] == AT_HWCAP)
- return data_p[1];
- }
-
- offset += 2 * wordsize;
- }
-
- return 0;
-}
-
/* Determine the word size for the given PID, in bytes. */
#ifdef __s390x__
/* Determine word size and HWCAP. */
int pid = pid_of (current_thread);
int wordsize = s390_get_wordsize (pid);
- unsigned long hwcap = s390_get_hwcap (wordsize);
+ unsigned long hwcap = linux_get_hwcap (wordsize);
/* Check whether the kernel supports extra register sets. */
int have_regset_last_break