#include "observable.h"
#include "gdbthread.h"
+#include "aarch32-tdep.h"
#include "arm-tdep.h"
#include "arm-linux-tdep.h"
#include "aarch32-linux-nat.h"
#include <sys/procfs.h>
#include "nat/linux-ptrace.h"
+#include "linux-tdep.h"
/* Prototypes for supply_gregset etc. */
#include "gregset.h"
#define PTRACE_SETHBPREGS 30
#endif
-extern int arm_apcs_32;
-
class arm_linux_nat_target final : public linux_nat_target
{
public:
/* Fetch all WMMX registers of the process and store into
regcache. */
-#define IWMMXT_REGS_SIZE (16 * 8 + 6 * 4)
-
static void
fetch_wmmx_regs (struct regcache *regcache)
{
static void
fetch_vfp_regs (struct regcache *regcache)
{
- gdb_byte regbuf[VFP_REGS_SIZE];
+ gdb_byte regbuf[ARM_VFP3_REGS_SIZE];
int ret, tid;
struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
struct iovec iov;
iov.iov_base = regbuf;
- iov.iov_len = VFP_REGS_SIZE;
+ iov.iov_len = ARM_VFP3_REGS_SIZE;
ret = ptrace (PTRACE_GETREGSET, tid, NT_ARM_VFP, &iov);
}
else
static void
store_vfp_regs (const struct regcache *regcache)
{
- gdb_byte regbuf[VFP_REGS_SIZE];
+ gdb_byte regbuf[ARM_VFP3_REGS_SIZE];
int ret, tid;
struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
struct iovec iov;
iov.iov_base = regbuf;
- iov.iov_len = VFP_REGS_SIZE;
+ iov.iov_len = ARM_VFP3_REGS_SIZE;
ret = ptrace (PTRACE_GETREGSET, tid, NT_ARM_VFP, &iov);
}
else
struct iovec iov;
iov.iov_base = regbuf;
- iov.iov_len = VFP_REGS_SIZE;
+ iov.iov_len = ARM_VFP3_REGS_SIZE;
ret = ptrace (PTRACE_SETREGSET, tid, NT_ARM_VFP, &iov);
}
else
const struct target_desc *
arm_linux_nat_target::read_description ()
{
- CORE_ADDR arm_hwcap = 0;
+ CORE_ADDR arm_hwcap = linux_get_hwcap (this);
if (have_ptrace_getregset == TRIBOOL_UNKNOWN)
{
have_ptrace_getregset = TRIBOOL_TRUE;
}
- if (target_auxv_search (this, AT_HWCAP, &arm_hwcap) != 1)
- {
- return this->beneath ()->read_description ();
- }
-
if (arm_hwcap & HWCAP_IWMMXT)
- return tdesc_arm_with_iwmmxt;
+ return arm_read_description (ARM_FP_TYPE_IWMMXT);
if (arm_hwcap & HWCAP_VFP)
{
- int pid;
- char *buf;
- const struct target_desc * result = NULL;
+ /* Make sure that the kernel supports reading VFP registers. Support was
+ added in 2.6.30. */
+ int pid = inferior_ptid.lwp ();
+ errno = 0;
+ char *buf = (char *) alloca (ARM_VFP3_REGS_SIZE);
+ if (ptrace (PTRACE_GETVFPREGS, pid, 0, buf) < 0 && errno == EIO)
+ return nullptr;
/* NEON implies VFPv3-D32 or no-VFP unit. Say that we only support
Neon with VFPv3-D32. */
if (arm_hwcap & HWCAP_NEON)
- result = tdesc_arm_with_neon;
+ return aarch32_read_description ();
else if ((arm_hwcap & (HWCAP_VFPv3 | HWCAP_VFPv3D16)) == HWCAP_VFPv3)
- result = tdesc_arm_with_vfpv3;
- else
- result = tdesc_arm_with_vfpv2;
-
- /* Now make sure that the kernel supports reading these
- registers. Support was added in 2.6.30. */
- pid = inferior_ptid.lwp ();
- errno = 0;
- buf = (char *) alloca (VFP_REGS_SIZE);
- if (ptrace (PTRACE_GETVFPREGS, pid, 0, buf) < 0
- && errno == EIO)
- result = NULL;
+ return arm_read_description (ARM_FP_TYPE_VFPV3);
- return result;
+ return arm_read_description (ARM_FP_TYPE_VFPV2);
}
return this->beneath ()->read_description ();
return -1;
}
else
- gdb_assert (FALSE);
+ gdb_assert_not_reached ("unknown breakpoint type");
return 1;
}