Example #1
0
static void
fetch_inferior_registers (struct target_ops *ops,
			  struct regcache *regcache, int regnum)
{
  elf_gregset_t regs;
  int tid;

  tid = ptid_get_lwp (inferior_ptid);
  if (tid == 0)
    tid = ptid_get_pid (inferior_ptid);

  if (ptrace (PTRACE_GETREGS, tid, 0, (PTRACE_TYPE_ARG3) &regs) < 0)
    perror_with_name (_("Couldn't get registers"));

  supply_gregset (regcache, (const elf_gregset_t *)&regs);
}
static void
i386_linux_dr_set (int regnum, unsigned long value)
{
  int tid;

  /* FIXME: kettenis/2001-01-29: It's not clear what we should do with
     multi-threaded processes here.  For now, pretend there is just
     one thread.  */
  tid = PIDGET (inferior_ptid);

  errno = 0;
  ptrace (PTRACE_POKEUSER, tid,
	  offsetof (struct user, u_debugreg[regnum]), value);
  if (errno != 0)
    perror_with_name (_("Couldn't write debug register"));
}
Example #3
0
static void
delete_target (struct file *file, const char *on_behalf_of)
{
  struct stat st;
  int e;

	if (file->precious || file->phony) {
		return;
	}

#ifndef NO_ARCHIVES
  if (ar_name (file->name))
    {
      time_t file_date = (file->last_mtime == NONEXISTENT_MTIME
			  ? (time_t) -1
			  : (time_t) FILE_TIMESTAMP_S (file->last_mtime));
      if (ar_member_date (file->name) != file_date)
	{
		if (on_behalf_of) {
	    error (NILF, _("*** [%s] Archive member `%s' may be bogus; not deleted"),
		   on_behalf_of, file->name);
		} else {
	    error (NILF, _("*** Archive member `%s' may be bogus; not deleted"),
		   file->name);
		}
	}
      return;
    }
#endif	/* !NO_ARCHIVES.  */

  EINTRLOOP (e, stat (file->name, &st));
  if (e == 0
      && S_ISREG (st.st_mode)
#ifdef ST_MTIM_NSEC
      && FILE_TIMESTAMP_STAT_MODTIME (file->name, st) != file->last_mtime
#endif /* ST_MTIM_NSEC */
	  && e != 1)
    {
		if (on_behalf_of) {
	error (NILF, _("*** [%s] Deleting file `%s'"), on_behalf_of, file->name);
		} else
	error (NILF, _("*** Deleting file `%s'"), file->name);
      if (unlink (file->name) < 0
	  && errno != ENOENT)	/* It disappeared; so what.  */
	perror_with_name ("unlink: ", file->name);
    }
}
Example #4
0
void *
alloc_jump_pad_buffer (size_t size)
{
#if __ILP32__
  uintptr_t addr;
  int pagesize;

  pagesize = sysconf (_SC_PAGE_SIZE);
  if (pagesize == -1)
    perror_with_name ("sysconf");

  addr = 0x80000000 - size;

  /* size should already be page-aligned, but this can't hurt.  */
  addr &= ~(pagesize - 1);

  /* Search for a free area.  If we hit 0, we're out of luck.  */
  for (; addr; addr -= pagesize)
    {
      void *res;

      /* No MAP_FIXED - we don't want to zap someone's mapping.  */
      res = mmap ((void *) addr, size,
		  PROT_READ | PROT_WRITE | PROT_EXEC,
		  MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

      /* If we got what we wanted, return.  */
      if ((uintptr_t) res == addr)
	return res;

      /* If we got a mapping, but at a wrong address, undo it.  */
      if (res != MAP_FAILED)
	munmap (res, size);
    }

  return NULL;
#else
  void *res = mmap (NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC,
		    MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT, -1, 0);

  if (res == MAP_FAILED)
    return NULL;

  return res;
#endif
}
Example #5
0
int
inf_ptrace_target::follow_fork (int follow_child, int detach_fork)
{
  if (!follow_child)
    {
      struct thread_info *tp = inferior_thread ();
      pid_t child_pid = tp->pending_follow.value.related_pid.pid ();

      /* Breakpoints have already been detached from the child by
	 infrun.c.  */

      if (ptrace (PT_DETACH, child_pid, (PTRACE_TYPE_ARG3)1, 0) == -1)
	perror_with_name (("ptrace"));
    }

  return 0;
}
static int
inf_ptrace_follow_fork (struct target_ops *ops, int follow_child,
			int detach_fork)
{
  if (!follow_child)
    {
      pid_t child_pid = inferior_thread->pending_follow.value.related_pid;

      /* Breakpoints have already been detached from the child by
	 infrun.c.  */

      if (ptrace (PT_DETACH, child_pid, (PTRACE_TYPE_ARG3)1, 0) == -1)
	perror_with_name (("ptrace"));
    }

  return 0;
}
void
fetch_inferior_registers (int regno)
{
  if (regno == -1 || GETREGS_SUPPLIES (regno))
    {
      struct reg inferior_registers;

      if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
		  (PTRACE_TYPE_ARG3) &inferior_registers, 0) == -1)
	perror_with_name (_("Couldn't get registers"));

      shnbsd_supply_reg ((char *) &inferior_registers, regno);

      if (regno != -1)
	return;
    }
}
Example #8
0
static void
fbsd_wait_for_process (struct process_info **childp, int *wstatp)
{
  int ret;
  int to_wait_for = -1;

  if (*childp != NULL)
    to_wait_for = (*childp)->lwpid;

  while (1)
    {
      ret = waitpid (to_wait_for, wstatp, WNOHANG);

      if (ret == -1)
	{
	  if (errno != ECHILD)
	    perror_with_name ("waitpid");
	}
      else if (ret > 0)
	break;

      usleep (1000);
    }

  if (debug_threads
      && (!WIFSTOPPED (*wstatp)
	  || (WSTOPSIG (*wstatp) != 32
	      && WSTOPSIG (*wstatp) != 33)))
    fprintf (stderr, "Got an event from %d (%x)\n", ret, *wstatp);

  if (to_wait_for == -1)
    *childp = (struct process_info *) find_inferior_id (&all_processes, ret);

  (*childp)->stopped = 1;
  (*childp)->pending_is_breakpoint = 0;

  if (debug_threads
      && WIFSTOPPED (*wstatp))
    {
      current_inferior = (struct thread_info *)
	find_inferior_id (&all_threads, (*childp)->tid);
      /* For testing only; i386_stop_pc prints out a diagnostic.  */
      if (the_low_target.get_pc != NULL)
	get_stop_pc ();
    }
}
Example #9
0
static long
get_current_lwp (int pid)
{
  struct ptrace_lwpinfo pl;
  lwpid_t lwpid;

  if (!target_has_execution)
    {
      lwpid = 0;
      bfd_map_over_sections (core_bfd, fbsd_core_get_first_lwp, &lwpid);
      return lwpid;
    }
  if (ptrace (PT_LWPINFO, pid, (caddr_t)&pl, sizeof(pl)))
    perror_with_name("PT_LWPINFO");

  return (long)pl.pl_lwpid;
}
Example #10
0
static void
sh3_open (char *args, int from_tty)
{
  char *serial_port_name = args;
  char *parallel_port_name = 0;

  if (args)
    {
      char *cursor = serial_port_name = xstrdup (args);

      while (*cursor && *cursor != ' ')
	cursor++;

      if (*cursor)
	*cursor++ = 0;

      while (*cursor == ' ')
	cursor++;

      if (*cursor)
	parallel_port_name = cursor;
    }

  monitor_open (serial_port_name, &sh3_cmds, from_tty);

  if (parallel_port_name)
    {
      parallel = serial_open (parallel_port_name);

      if (!parallel)
	perror_with_name (_("Unable to open parallel port."));

      parallel_in_use = 1;
    }


  /* If we connected successfully, we know the processor is an SH3.  */
  {
    struct gdbarch_info info;
    gdbarch_info_init (&info);
    info.bfd_arch_info = bfd_lookup_arch (bfd_arch_sh, bfd_mach_sh3);
    if (!gdbarch_update_p (info))
      error (_("Target is not an SH3"));
  }
}
Example #11
0
static int
resume_one_thread_cb (struct thread_info *tp, void *data)
{
  ptid_t *ptid = data;
  int request;

  if (ptid_get_pid (tp->ptid) != ptid_get_pid (*ptid))
    return 0;

  if (ptid_get_lwp (tp->ptid) == ptid_get_lwp (*ptid))
    request = PT_RESUME;
  else
    request = PT_SUSPEND;

  if (ptrace (request, ptid_get_lwp (tp->ptid), NULL, 0) == -1)
    perror_with_name (("ptrace"));
  return 0;
}
Example #12
0
static void
fetch_vsx_registers (struct regcache *regcache, int tid)
{
  int ret;
  gdb_vsxregset_t regs;

  ret = ptrace (PTRACE_GETVSXREGS, tid, 0, &regs);
  if (ret < 0)
    {
      if (errno == EIO)
	{
	  have_ptrace_getsetvsxregs = 0;
	  return;
	}
      perror_with_name (_("Unable to fetch VSX registers"));
    }
  supply_vsxregset (regcache, &regs);
}
static void
fetch_altivec_registers (int tid)
{
  int ret;
  gdb_vrregset_t regs;
  
  ret = ptrace (PTRACE_GETVRREGS, tid, 0, &regs);
  if (ret < 0)
    {
      if (errno == EIO)
	{
          have_ptrace_getvrregs = 0;
	  return;
	}
      perror_with_name (_("Unable to fetch AltiVec registers"));
    }
  supply_vrregset (&regs);
}
Example #14
0
static unsigned long
amd64_linux_dr_get (ptid_t ptid, int regnum)
{
  int tid;
  unsigned long value;

  tid = ptid_get_lwp (ptid);
  if (tid == 0)
    tid = ptid_get_pid (ptid);

  errno = 0;
  value = ptrace (PTRACE_PEEKUSER, tid,
		  offsetof (struct user, u_debugreg[regnum]), 0);
  if (errno != 0)
    perror_with_name (_("Couldn't read debug register"));

  return value;
}
static int
fetch_xstateregs (struct regcache *regcache, int tid)
{
  char xstateregs[X86_XSTATE_MAX_SIZE];
  struct iovec iov;

  if (!have_ptrace_getregset)
    return 0;

  iov.iov_base = xstateregs;
  iov.iov_len = sizeof(xstateregs);
  if (ptrace (PTRACE_GETREGSET, tid, (unsigned int) NT_X86_XSTATE,
	      &iov) < 0)
    perror_with_name (_("Couldn't read extended state status"));

  i387_supply_xsave (regcache, -1, xstateregs);
  return 1;
}
Example #16
0
void
xcoff_relocate_symtab (unsigned int pid)
{
  int load_segs = 64; /* number of load segments */
  int rc;
  LdInfo *ldi = NULL;
  int arch64 = ARCH64 ();
  int ldisize = arch64 ? sizeof (ldi->l64) : sizeof (ldi->l32);
  int size;

  do
    {
      size = load_segs * ldisize;
      ldi = (void *) xrealloc (ldi, size);

#if 0
      /* According to my humble theory, AIX has some timing problems and
         when the user stack grows, kernel doesn't update stack info in time
         and ptrace calls step on user stack. That is why we sleep here a
         little, and give kernel to update its internals. */
      usleep (36000);
#endif

      if (arch64)
	rc = rs6000_ptrace64 (PT_LDINFO, pid, (unsigned long) ldi, size, NULL);
      else
	rc = rs6000_ptrace32 (PT_LDINFO, pid, (int *) ldi, size, NULL);

      if (rc == -1)
        {
          if (errno == ENOMEM)
            load_segs *= 2;
          else
            perror_with_name ("ptrace ldinfo");
        }
      else
	{
          vmap_ldinfo (ldi);
          vmap_exec (); /* relocate the exec and core sections as well. */
	}
    } while (rc == -1);
  if (ldi)
    xfree (ldi);
}
Example #17
0
static void
i386fbsd_resume (struct target_ops *ops,
		 ptid_t ptid, int step, enum gdb_signal signal)
{
  pid_t pid = ptid_get_pid (ptid);
  int request = PT_STEP;

  if (pid == -1)
    /* Resume all threads.  This only gets used in the non-threaded
       case, where "resume all threads" and "resume inferior_ptid" are
       the same.  */
    pid = ptid_get_pid (inferior_ptid);

  if (!step)
    {
      struct regcache *regcache = get_current_regcache ();
      ULONGEST eflags;

      /* Workaround for a bug in FreeBSD.  Make sure that the trace
 	 flag is off when doing a continue.  There is a code path
 	 through the kernel which leaves the flag set when it should
 	 have been cleared.  If a process has a signal pending (such
 	 as SIGALRM) and we do a PT_STEP, the process never really has
 	 a chance to run because the kernel needs to notify the
 	 debugger that a signal is being sent.  Therefore, the process
 	 never goes through the kernel's trap() function which would
 	 normally clear it.  */

      regcache_cooked_read_unsigned (regcache, I386_EFLAGS_REGNUM,
				     &eflags);
      if (eflags & 0x0100)
	regcache_cooked_write_unsigned (regcache, I386_EFLAGS_REGNUM,
					eflags & ~0x0100);

      request = PT_CONTINUE;
    }

  /* An addres of (caddr_t) 1 tells ptrace to continue from where it
     was.  (If GDB wanted it to start some other way, we have already
     written a new PC value to the child.)  */
  if (ptrace (request, pid, (caddr_t) 1,
	      gdb_signal_to_host (signal)) == -1)
    perror_with_name (("ptrace"));
}
static void
store_register (int regno)
{
  /* This isn't really an address.  But ptrace thinks of it as one.  */
  CORE_ADDR regaddr;
  char mess[128];		/* For messages */
  int i;
  unsigned int offset;		/* Offset of registers within the u area.  */
  int tid;
  char buf[MAX_REGISTER_SIZE];

  if (CANNOT_STORE_REGISTER (regno))
    {
      return;
    }

  /* Overload thread id onto process id */
  tid = TIDGET (inferior_ptid);
  if (tid == 0)
    tid = PIDGET (inferior_ptid);	/* no thread id, just use process id */

  offset = U_REGS_OFFSET;

  regaddr = register_addr (regno, offset);

  /* Put the contents of regno into a local buffer */
  regcache_raw_collect (current_regcache, regno, buf);

  /* Store the local buffer into the inferior a chunk at the time. */
  for (i = 0; i < register_size (current_gdbarch, regno);
       i += sizeof (PTRACE_XFER_TYPE))
    {
      errno = 0;
      ptrace (PT_WRITE_U, tid, (PTRACE_ARG3_TYPE) regaddr,
	      *(PTRACE_XFER_TYPE *) (buf + i));
      regaddr += sizeof (PTRACE_XFER_TYPE);
      if (errno != 0)
	{
	  sprintf (mess, "writing register %s (#%d)", 
		   REGISTER_NAME (regno), regno);
	  perror_with_name (mess);
	}
    }
}
Example #19
0
int
ar_touch (const char *name)
{
  char *arname, *memname;
  int val;

  ar_parse_name (name, &arname, &memname);

  /* Make sure we know the modtime of the archive itself before we
     touch the member, since this will change the archive modtime.  */
  {
    struct file *arfile;
    arfile = enter_file (strcache_add (arname));
    f_mtime (arfile, 0);
  }

  val = 1;
  switch (ar_member_touch (arname, memname))
    {
    case -1:
      error (NILF, _("touch: Archive `%s' does not exist"), arname);
      break;
    case -2:
      error (NILF, _("touch: `%s' is not a valid archive"), arname);
      break;
    case -3:
      perror_with_name ("touch: ", arname);
      break;
    case 1:
      error (NILF,
             _("touch: Member `%s' does not exist in `%s'"), memname, arname);
      break;
    case 0:
      val = 0;
      break;
    default:
      error (NILF,
             _("touch: Bad return code from ar_member_touch on `%s'"), name);
    }

  free (arname);

  return val;
}
void
fetch_inferior_registers (int regno)
{
  int reglo, reghi;
  int i;
  unsigned long ecp;

  if (regno == -1)
    {
      reglo = 0;
      reghi = NUM_REGS - 1;
    }
  else
    reglo = reghi = regno;

  ecp = registers_addr (PIDGET (inferior_ptid));

  {
    char buf[MAX_REGISTER_SIZE];
    for (regno = reglo; regno <= reghi; regno++)
      {
	int ptrace_fun = PTRACE_PEEKTHREAD;
	
#ifdef M68K
	ptrace_fun = regno == SP_REGNUM ? PTRACE_PEEKUSP : PTRACE_PEEKTHREAD;
#endif
	
	for (i = 0; i < DEPRECATED_REGISTER_RAW_SIZE (regno); i += sizeof (int))
	  {
	    unsigned int reg;
	    
	    errno = 0;
	    reg = ptrace (ptrace_fun, PIDGET (inferior_ptid),
			  (PTRACE_ARG3_TYPE) (ecp + regmap[regno] + i), 0);
	    if (errno)
	      perror_with_name ("ptrace(PTRACE_PEEKUSP)");
	    
	    *(int *) &buf[i] = reg;
	  }
	supply_register (regno, buf);
      }
  }
}
void
store_inferior_registers (int regno)
{
  int reglo, reghi;
  int i;
  unsigned long ecp;

  if (regno == -1)
    {
      reglo = 0;
      reghi = NUM_REGS - 1;
    }
  else
    reglo = reghi = regno;

  ecp = registers_addr (PIDGET (inferior_ptid));

  for (regno = reglo; regno <= reghi; regno++)
    {
      int ptrace_fun = PTRACE_POKEUSER;

      if (CANNOT_STORE_REGISTER (regno))
	continue;

#ifdef M68K
      ptrace_fun = regno == SP_REGNUM ? PTRACE_POKEUSP : PTRACE_POKEUSER;
#endif

      for (i = 0; i < DEPRECATED_REGISTER_RAW_SIZE (regno); i += sizeof (int))
	{
	  unsigned int reg;

	  reg = *(unsigned int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (regno) + i];

	  errno = 0;
	  ptrace (ptrace_fun, PIDGET (inferior_ptid),
		  (PTRACE_ARG3_TYPE) (ecp + regmap[regno] + i), reg);
	  if (errno)
	    perror_with_name ("ptrace(PTRACE_POKEUSP)");
	}
    }
}
static void
fetch_register (int regno)
{
  /* This isn't really an address.  But ptrace thinks of it as one.  */
  CORE_ADDR regaddr;
  char mess[128];		/* For messages */
  int i;
  unsigned int offset;		/* Offset of registers within the u area.  */
  char buf[MAX_REGISTER_SIZE];
  int tid;

  if (CANNOT_FETCH_REGISTER (regno))
    {
      memset (buf, '\0', register_size (current_gdbarch, regno));	/* Supply zeroes */
      regcache_raw_supply (current_regcache, regno, buf);
      return;
    }

  /* Overload thread id onto process id */
  tid = TIDGET (inferior_ptid);
  if (tid == 0)
    tid = PIDGET (inferior_ptid);	/* no thread id, just use process id */

  offset = U_REGS_OFFSET;

  regaddr = register_addr (regno, offset);
  for (i = 0; i < register_size (current_gdbarch, regno);
       i += sizeof (PTRACE_XFER_TYPE))
    {
      errno = 0;
      *(PTRACE_XFER_TYPE *) &buf[i] = ptrace (PT_READ_U, tid,
					      (PTRACE_ARG3_TYPE) regaddr, 0);
      regaddr += sizeof (PTRACE_XFER_TYPE);
      if (errno != 0)
	{
	  sprintf (mess, "reading register %s (#%d)", 
		   REGISTER_NAME (regno), regno);
	  perror_with_name (mess);
	}
    }
  regcache_raw_supply (current_regcache, regno, buf);
}
Example #23
0
void
fbsd_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
{
#if defined(TDP_RFPPWAIT) && !defined(PTRACE_VFORK)
  pid_t pid;

  /* Don't PT_CONTINUE a process which has a pending vfork done event.  */
  if (minus_one_ptid == ptid)
    pid = inferior_ptid.pid ();
  else
    pid = ptid.pid ();
  if (fbsd_is_vfork_done_pending (pid))
    return;
#endif

  if (debug_fbsd_lwp)
    fprintf_unfiltered (gdb_stdlog,
			"FLWP: fbsd_resume for ptid (%d, %ld, %ld)\n",
			ptid.pid (), ptid.lwp (),
			ptid.tid ());
  if (ptid.lwp_p ())
    {
      /* If ptid is a specific LWP, suspend all other LWPs in the process.  */
      struct thread_info *tp;
      int request;

      ALL_NON_EXITED_THREADS (tp)
        {
	  if (tp->ptid.pid () != ptid.pid ())
	    continue;

	  if (tp->ptid.lwp () == ptid.lwp ())
	    request = PT_RESUME;
	  else
	    request = PT_SUSPEND;

	  if (ptrace (request, tp->ptid.lwp (), NULL, 0) == -1)
	    perror_with_name (("ptrace"));
	}
    }
  else
    {
Example #24
0
static const char *
fbsd_thread_name (struct target_ops *self, struct thread_info *thr)
{
  struct ptrace_lwpinfo pl;
  struct kinfo_proc kp;
  int pid = ptid_get_pid (thr->ptid);
  long lwp = ptid_get_lwp (thr->ptid);
  static char buf[sizeof pl.pl_tdname + 1];

  /* Note that ptrace_lwpinfo returns the process command in pl_tdname
     if a name has not been set explicitly.  Return a NULL name in
     that case.  */
  fbsd_fetch_kinfo_proc (pid, &kp);
  if (ptrace (PT_LWPINFO, lwp, (caddr_t) &pl, sizeof pl) == -1)
    perror_with_name (("ptrace"));
  if (strcmp (kp.ki_comm, pl.pl_tdname) == 0)
    return NULL;
  xsnprintf (buf, sizeof buf, "%s", pl.pl_tdname);
  return buf;
}
Example #25
0
static void
shnbsd_fetch_inferior_registers (struct target_ops *ops,
                                 struct regcache *regcache, int regno)
{
    if (regno == -1 || GETREGS_SUPPLIES (get_regcache_arch (regcache), regno))
    {
        struct reg inferior_registers;

        if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
                    (PTRACE_TYPE_ARG3) &inferior_registers, 0) == -1)
            perror_with_name (_("Couldn't get registers"));

        sh_corefile_supply_regset (&sh_corefile_gregset, regcache, regno,
                                   (char *) &inferior_registers,
                                   SHNBSD_SIZEOF_GREGS);

        if (regno != -1)
            return;
    }
}
/* Assuming TID referrs to an SPE process, set the top halves of TID's
   general-purpose registers and its SPE-specific registers to the
   values in EVRREGSET.  If we don't support PTRACE_SETEVRREGS, do
   nothing.

   All the logic to deal with whether or not the PTRACE_GETEVRREGS and
   PTRACE_SETEVRREGS requests are supported is isolated here, and in
   get_spe_registers.  */
static void
set_spe_registers (int tid, struct gdb_evrregset_t *evrregset)
{
  if (have_ptrace_getsetevrregs)
    {
      if (ptrace (PTRACE_SETEVRREGS, tid, 0, evrregset) >= 0)
        return;
      else
        {
          /* EIO means that the PTRACE_SETEVRREGS request isn't
             supported; we fail silently, and don't try the call
             again.  */
          if (errno == EIO)
            have_ptrace_getsetevrregs = 0;
          else
            /* Anything else needs to be reported.  */
            perror_with_name (_("Unable to set SPE registers"));
        }
    }
}
Example #27
0
static void
fetch_regs (struct regcache *regcache, int tid)
{
  elf_gregset_t regs;

  if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
    {
      if (errno == EIO)
	{
	  /* The kernel we're running on doesn't support the GETREGS
             request.  Reset `have_ptrace_getregs'.  */
	  have_ptrace_getregs = 0;
	  return;
	}

      perror_with_name (_("Couldn't get registers"));
    }

  supply_gregset (regcache, (const elf_gregset_t *) &regs);
}
unsigned long
i386bsd_dr_get_status (void)
{
  struct dbreg dbregs;

  /* FIXME: kettenis/2001-03-31: Calling perror_with_name if the
     ptrace call fails breaks debugging remote targets.  The correct
     way to fix this is to add the hardware breakpoint and watchpoint
     stuff to the target vector.  For now, just return zero if the
     ptrace call fails.  */
  if (ptrace (PT_GETDBREGS, PIDGET (inferior_ptid),
	      (PTRACE_ARG3_TYPE) & dbregs, 0) == -1)
#if 0
    perror_with_name ("Couldn't read debug registers");
#else
    return 0;
#endif

  return DBREG_DRX ((&dbregs), 6);
}
Example #29
0
static const struct target_desc *
amd64fbsd_read_description (struct target_ops *ops)
{
#ifdef PT_GETXSTATE_INFO
  static int xsave_probed;
  static uint64_t xcr0;
#endif
  struct reg regs;
  int is64;

  if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
	      (PTRACE_TYPE_ARG3) &regs, 0) == -1)
    perror_with_name (_("Couldn't get registers"));
  is64 = (regs.r_cs == GSEL (GUCODE_SEL, SEL_UPL));
#ifdef PT_GETXSTATE_INFO
  if (!xsave_probed)
    {
      struct ptrace_xstate_info info;

      if (ptrace (PT_GETXSTATE_INFO, ptid_get_pid (inferior_ptid),
		  (PTRACE_TYPE_ARG3) &info, sizeof (info)) == 0)
	{
	  amd64bsd_xsave_len = info.xsave_len;
	  xcr0 = info.xsave_mask;
	}
      xsave_probed = 1;
    }

  if (amd64bsd_xsave_len != 0)
    {
      if (is64)
	return amd64_target_description (xcr0);
      else
	return i386_target_description (xcr0);
    }
#endif
  if (is64)
    return tdesc_amd64;
  else
    return tdesc_i386;
}
/* Fetch the top 32 bits of TID's general-purpose registers and the
   SPE-specific registers, and place the results in EVRREGSET.  If we
   don't support PTRACE_GETEVRREGS, then just fill EVRREGSET with
   zeros.

   All the logic to deal with whether or not the PTRACE_GETEVRREGS and
   PTRACE_SETEVRREGS requests are supported is isolated here, and in
   set_spe_registers.  */
static void
get_spe_registers (int tid, struct gdb_evrregset_t *evrregset)
{
  if (have_ptrace_getsetevrregs)
    {
      if (ptrace (PTRACE_GETEVRREGS, tid, 0, evrregset) >= 0)
        return;
      else
        {
          /* EIO means that the PTRACE_GETEVRREGS request isn't supported;
             we just return zeros.  */
          if (errno == EIO)
            have_ptrace_getsetevrregs = 0;
          else
            /* Anything else needs to be reported.  */
            perror_with_name (_("Unable to fetch SPE registers"));
        }
    }

  memset (evrregset, 0, sizeof (*evrregset));
}