예제 #1
0
void
_initialize_arm_linux_nat (void)
{
  struct target_ops *t;

  os_version = get_linux_version (&os_major, &os_minor, &os_release);

  /* Fill in the generic GNU/Linux methods.  */
  t = linux_target ();

  /* Add our register access methods.  */
  t->to_fetch_registers = arm_linux_fetch_inferior_registers;
  t->to_store_registers = arm_linux_store_inferior_registers;

  t->to_read_description = arm_linux_read_description;

  /* Register the target.  */
  linux_nat_add_target (t);

  /* Initialize the standard target descriptions.  */
  initialize_tdesc_arm_with_iwmmxt ();
}
static const struct target_desc *
arm_linux_read_description (struct target_ops *ops)
{
  CORE_ADDR arm_hwcap = 0;
  arm_linux_has_wmmx_registers = 0;
  arm_linux_vfp_register_count = 0;

  if (target_auxv_search (ops, AT_HWCAP, &arm_hwcap) != 1)
    {
      return NULL;
    }

  if (arm_hwcap & HWCAP_IWMMXT)
    {
      arm_linux_has_wmmx_registers = 1;
      if (tdesc_arm_with_iwmmxt == NULL)
	initialize_tdesc_arm_with_iwmmxt ();
      return tdesc_arm_with_iwmmxt;
    }

  if (arm_hwcap & HWCAP_VFP)
    {
      int pid;
      char *buf;
      const struct target_desc * result = NULL;

      /* NEON implies VFPv3-D32 or no-VFP unit.  Say that we only support
	 Neon with VFPv3-D32.  */
      if (arm_hwcap & HWCAP_NEON)
	{
	  arm_linux_vfp_register_count = 32;
	  if (tdesc_arm_with_neon == NULL)
	    initialize_tdesc_arm_with_neon ();
	  result = tdesc_arm_with_neon;
	}
      else if ((arm_hwcap & (HWCAP_VFPv3 | HWCAP_VFPv3D16)) == HWCAP_VFPv3)
	{
	  arm_linux_vfp_register_count = 32;
	  if (tdesc_arm_with_vfpv3 == NULL)
	    initialize_tdesc_arm_with_vfpv3 ();
	  result = tdesc_arm_with_vfpv3;
	}
      else
	{
	  arm_linux_vfp_register_count = 16;
	  if (tdesc_arm_with_vfpv2 == NULL)
	    initialize_tdesc_arm_with_vfpv2 ();
	  result = tdesc_arm_with_vfpv2;
	}

      /* Now make sure that the kernel supports reading these
	 registers.  Support was added in 2.6.30.  */
      pid = GET_LWP (inferior_ptid);
      errno = 0;
      buf = alloca (VFP_REGS_SIZE);
      if (ptrace (PTRACE_GETVFPREGS, pid, 0, buf) < 0
	  && errno == EIO)
	result = NULL;

      return result;
    }

  return NULL;
}