Ejemplo n.º 1
0
static const struct target_desc *
arm_linux_read_description (struct target_ops *ops)
{
  CORE_ADDR arm_hwcap = 0;

  if (have_ptrace_getregset == TRIBOOL_UNKNOWN)
    {
      elf_gregset_t gpregs;
      struct iovec iov;
      int tid = ptid_get_lwp (inferior_ptid);

      iov.iov_base = &gpregs;
      iov.iov_len = sizeof (gpregs);

      /* Check if PTRACE_GETREGSET works.  */
      if (ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, &iov) < 0)
	have_ptrace_getregset = TRIBOOL_FALSE;
      else
	have_ptrace_getregset = TRIBOOL_TRUE;
    }

  if (target_auxv_search (ops, AT_HWCAP, &arm_hwcap) != 1)
    {
      return ops->beneath->to_read_description (ops->beneath);
    }

  if (arm_hwcap & HWCAP_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)
	result = tdesc_arm_with_neon;
      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 = ptid_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 ops->beneath->to_read_description (ops->beneath);
}
Ejemplo n.º 2
0
/* Fetch the AT_HWCAP entry from the aux vector.  */
unsigned long ppc_linux_get_hwcap (void)
{
  CORE_ADDR field;

  if (target_auxv_search (&current_target, AT_HWCAP, &field))
    return (unsigned long) field;

  return 0;
}
Ejemplo n.º 3
0
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;
      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;
	  result = tdesc_arm_with_neon;
	}
      else if ((arm_hwcap & (HWCAP_VFPv3 | HWCAP_VFPv3D16)) == HWCAP_VFPv3)
	{
	  arm_linux_vfp_register_count = 32;
	  result = tdesc_arm_with_vfpv3;
	}
      else
	{
	  arm_linux_vfp_register_count = 16;
	  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;
}
Ejemplo n.º 4
0
static void
add_vsyscall_page (struct target_ops *target, int from_tty)
{
  CORE_ADDR sysinfo_ehdr;

  if (target_auxv_search (target, AT_SYSINFO_EHDR, &sysinfo_ehdr) > 0
      && sysinfo_ehdr != (CORE_ADDR) 0)
    {
      struct bfd *bfd;
      struct symbol_file_add_from_memory_args args;

      if (core_bfd != NULL)
	bfd = core_bfd;
      else if (exec_bfd != NULL)
	bfd = exec_bfd;
      else
       /* FIXME: cagney/2004-05-06: Should not require an existing
	  BFD when trying to create a run-time BFD of the VSYSCALL
	  page in the inferior.  Unfortunately that's the current
	  interface so for the moment bail.  Introducing a
	  ``bfd_runtime'' (a BFD created using the loaded image) file
	  format should fix this.  */
	{
	  warning (_("Could not load vsyscall page "
		     "because no executable was specified\n"
		     "try using the \"file\" command first."));
	  return;
	}
      args.bfd = bfd;
      args.sysinfo_ehdr = sysinfo_ehdr;
      args.name = xstrprintf ("system-supplied DSO at %s",
			      paddress (target_gdbarch (), sysinfo_ehdr));
      /* Pass zero for FROM_TTY, because the action of loading the
	 vsyscall DSO was not triggered by the user, even if the user
	 typed "run" at the TTY.  */
      args.from_tty = 0;
      catch_exceptions (current_uiout, symbol_file_add_from_memory_wrapper,
			&args, RETURN_MASK_ALL);
    }
}
Ejemplo n.º 5
0
static const struct target_desc *
arm_linux_core_read_description (struct gdbarch *gdbarch,
                                 struct target_ops *target,
                                 bfd *abfd)
{
  CORE_ADDR arm_hwcap = 0;

  if (target_auxv_search (target, AT_HWCAP, &arm_hwcap) != 1)
    return NULL;

  if (arm_hwcap & HWCAP_VFP)
    {
      /* NEON implies VFPv3-D32 or no-VFP unit.  Say that we only support
         Neon with VFPv3-D32.  */
      if (arm_hwcap & HWCAP_NEON)
	return tdesc_arm_with_neon;
      else if ((arm_hwcap & (HWCAP_VFPv3 | HWCAP_VFPv3D16)) == HWCAP_VFPv3)
	return tdesc_arm_with_vfpv3;
      else
	return tdesc_arm_with_vfpv2;
    }

  return NULL;
}
Ejemplo n.º 6
0
static CORE_ADDR
ppc_linux_displaced_step_location (struct gdbarch *gdbarch)
{
  if (ppc_linux_entry_point_addr == 0)
    {
      CORE_ADDR addr;

      /* Determine entry point from target auxiliary vector.  */
      if (target_auxv_search (&current_target, AT_ENTRY, &addr) <= 0)
	error (_("Cannot find AT_ENTRY auxiliary vector entry."));

      /* Make certain that the address points at real code, and not a
	 function descriptor.  */
      addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr,
						 &current_target);

      /* Inferior calls also use the entry point as a breakpoint location.
	 We don't want displaced stepping to interfere with those
	 breakpoints, so leave space.  */
      ppc_linux_entry_point_addr = addr + 2 * PPC_INSN_SIZE;
    }

  return ppc_linux_entry_point_addr;
}