gdbserver: Add linux_get_hwcap
In gdbserver, Tidy up calls to read HWCAP (and HWCAP2) by adding common functions, removing the Arm, AArch64, PPC and S390 specific versions. No functionality differences. gdb/gdbserver/ChangeLog: * 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.
This commit is contained in:
parent
7ea79cb3af
commit
974c89e088
@ -1,3 +1,19 @@
|
||||
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>
|
||||
|
||||
|
@ -505,30 +505,6 @@ aarch64_linux_new_fork (struct process_info *parent,
|
||||
/* 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
|
||||
@ -545,8 +521,8 @@ aarch64_arch_setup (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);
|
||||
}
|
||||
|
@ -847,40 +847,15 @@ get_next_pcs_syscall_next_pc (struct arm_get_next_pcs *self)
|
||||
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;
|
||||
|
||||
|
@ -7423,6 +7423,53 @@ linux_get_pc_64bit (struct regcache *regcache)
|
||||
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,
|
||||
|
@ -435,4 +435,14 @@ bool thread_db_thread_handle (ptid_t ptid, gdb_byte **handle, int *handle_len);
|
||||
|
||||
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 */
|
||||
|
@ -323,43 +323,6 @@ ppc_set_pc (struct regcache *regcache, CORE_ADDR pc)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
@ -944,8 +907,8 @@ ppc_arch_setup (void)
|
||||
|
||||
/* 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);
|
||||
|
||||
|
@ -467,36 +467,6 @@ s390_set_pc (struct regcache *regcache, CORE_ADDR newpc)
|
||||
}
|
||||
}
|
||||
|
||||
/* 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__
|
||||
@ -548,7 +518,7 @@ s390_arch_setup (void)
|
||||
/* 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user