int
hppa_require_attach (int pid)
{
  int pt_status;
  CORE_ADDR pc;
  CORE_ADDR pc_addr;
  unsigned int regs_offset;

  /* Are we already attached?  There appears to be no explicit way to
     answer this via ptrace, so we try something which should be
     innocuous if we are attached.  If that fails, then we assume
     we're not attached, and so attempt to make it so. */

  errno = 0;
  regs_offset = U_REGS_OFFSET;
  pc_addr = register_addr (PC_REGNUM, regs_offset);
  pc = call_ptrace (PT_READ_U, pid, (PTRACE_ARG3_TYPE) pc_addr, 0);

  if (errno)
    {
      errno = 0;
      pt_status = call_ptrace (PT_ATTACH, pid, (PTRACE_ARG3_TYPE) 0, 0);

      if (errno)
	return -1;

      /* Now we really are attached. */
      errno = 0;
    }
  attach_flag = 1;
  return pid;
}
inline intptr_t* frame::entry_frame_argument_at(int offset) const {
  // Since an entry frame always calls the interpreter first,
  // the parameters are on the stack and relative to known register in the
  // entry frame.
  intptr_t* tos = (intptr_t*) *register_addr(GR_entry_frame_TOS);
  return &tos[offset + 1]; // prepushed tos
}
Beispiel #3
0
static void
fetch_register (int regno)
{
  register unsigned int regaddr;
  char buf[MAX_REGISTER_RAW_SIZE];
  register int i;

  /* Offset of registers within the u area.  */
  unsigned int offset;

  offset = U_REGS_OFFSET;

  regaddr = register_addr (regno, offset);
  for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
    {
      errno = 0;
      *(int *) &buf[i] = ptrace (PT_RUREGS, PIDGET (inferior_ptid),
				 (PTRACE_ARG3_TYPE) regaddr, 0);
      regaddr += sizeof (int);
      if (errno != 0)
	{
	  /* Warning, not error, in case we are attached; sometimes the
	     kernel doesn't let us at the registers.  */
	  char *err = safe_strerror (errno);
	  char *msg = alloca (strlen (err) + 128);
	  sprintf (msg, "reading register %s: %s", REGISTER_NAME (regno), err);
	  warning (msg);
	  goto error_exit;
	}
    }
  supply_register (regno, buf);
error_exit:;
}
static void
fetch_register (int regno)
{
  int tid;
  int val;

  if (CANNOT_FETCH_REGISTER (regno))
    {
      regcache_raw_supply (current_regcache, regno, NULL);
      return;
    }

  /* GNU/Linux LWP ID's are process ID's.  */
  tid = TIDGET (inferior_ptid);
  if (tid == 0)
    tid = PIDGET (inferior_ptid); /* Not a threaded program.  */

  errno = 0;
  val = ptrace (PTRACE_PEEKUSER, tid, register_addr (regno, 0), 0);
  if (errno != 0)
    error (_("Couldn't read register %s (#%d): %s."), REGISTER_NAME (regno),
	   regno, safe_strerror (errno));

  regcache_raw_supply (current_regcache, regno, &val);
}
Beispiel #5
0
/* Store our register values back into the inferior.
   If REGNO is -1, do this for all registers.
   Otherwise, REGNO specifies which register (so we can save time).  */
static void
usr_store_inferior_registers (int regno)
{
  CORE_ADDR regaddr;
  int i, size;
  char *buf;

  if (regno >= 0)
    {
      if (regno >= the_low_target.num_regs)
	return;

      if ((*the_low_target.cannot_store_register) (regno) == 1)
	return;

      regaddr = register_addr (regno);
      if (regaddr == -1)
	return;
      errno = 0;
      size = (register_size (regno) + sizeof (PTRACE_XFER_TYPE) - 1)
	     & - sizeof (PTRACE_XFER_TYPE);
      buf = alloca (size);
      memset (buf, 0, size);
      if (the_low_target.left_pad_xfer
	  && register_size (regno) < sizeof (PTRACE_XFER_TYPE))
	collect_register (regno, (buf + sizeof (PTRACE_XFER_TYPE)
				  - register_size (regno)));
      else
	collect_register (regno, buf);
      for (i = 0; i < size; i += sizeof (PTRACE_XFER_TYPE))
	{
	  errno = 0;
	  ptrace (PTRACE_POKEUSER, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
		  *(PTRACE_XFER_TYPE *) (buf + i));
	  if (errno != 0)
	    {
	      if ((*the_low_target.cannot_store_register) (regno) == 0)
		{
		  char *err = strerror (errno);
		  char *msg = alloca (strlen (err) + 128);
		  sprintf (msg, "writing register %d: %s",
			   regno, err);
		  error (msg);
		  return;
		}
	    }
	  regaddr += sizeof (PTRACE_XFER_TYPE);
	}
    }
  else
    for (regno = 0; regno < the_low_target.num_regs; regno++)
      usr_store_inferior_registers (regno);
}
Beispiel #6
0
void
store_inferior_registers (int regno)
{
  register unsigned int regaddr;
  char buf[80];
  register int i;
  unsigned int offset = U_REGS_OFFSET;
  int scratch;

  if (regno >= 0)
    {
      if (CANNOT_STORE_REGISTER (regno))
	return;
      regaddr = register_addr (regno, offset);
      errno = 0;
      if (regno == PCOQ_HEAD_REGNUM || regno == PCOQ_TAIL_REGNUM)
	{
	  scratch = *(int *) &registers[REGISTER_BYTE (regno)] | 0x3;
	  ptrace (PT_WUREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr,
		  scratch);
	  if (errno != 0)
	    {
	      /* Error, even if attached.  Failing to write these two
	         registers is pretty serious.  */
	      sprintf (buf, "writing register number %d", regno);
	      perror_with_name (buf);
	    }
	}
      else
	for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
	  {
	    errno = 0;
	    ptrace (PT_WUREGS, PIDGET (inferior_ptid),
	            (PTRACE_ARG3_TYPE) regaddr,
		    *(int *) &registers[REGISTER_BYTE (regno) + i]);
	    if (errno != 0)
	      {
		/* Warning, not error, in case we are attached; sometimes the
		   kernel doesn't let us at the registers.  */
		char *err = safe_strerror (errno);
		char *msg = alloca (strlen (err) + 128);
		sprintf (msg, "writing register %s: %s",
			 REGISTER_NAME (regno), err);
		warning (msg);
		return;
	      }
	    regaddr += sizeof (int);
	  }
    }
  else
    for (regno = 0; regno < NUM_REGS; regno++)
      store_inferior_registers (regno);
}
inline intptr_t*    frame::sender_sp() const  { 
  if (is_interpreted_frame()) {
    return (intptr_t*) (*register_addr(GR_Lsave_SP));
  } else {
#ifndef CORE
    CodeBlob* cb =  CodeCache::find_blob(pc());
    assert(cb != NULL, "Didn't find code");
    return compiled_sender_sp(cb);
#else
    ShouldNotReachHere();
    return NULL;
#endif
  }
}
Beispiel #8
0
static void
fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
		      CORE_ADDR reg_addr)
{
  int regno;
  unsigned int addr;
  int bad_reg = -1;
  reg_ptr = -reg_addr;	/* Original u.u_ar0 is -reg_addr. */

  char zerobuf[MAX_REGISTER_SIZE];
  memset (zerobuf, 0, MAX_REGISTER_SIZE);


  /* If u.u_ar0 was an absolute address in the core file, relativize it now,
     so we can use it as an offset into core_reg_sect.  When we're done,
     "register 0" will be at core_reg_sect+reg_ptr, and we can use
     register_addr to offset to the other registers.  If this is a modern
     core file without a upage, reg_ptr will be zero and this is all a big
     NOP.  */
  if (reg_ptr > core_reg_size)
#ifdef KERNEL_U_ADDR
    reg_ptr -= KERNEL_U_ADDR;
#else
    error ("Old mips core file can't be processed on this machine.");
#endif

  for (regno = 0; regno < NUM_REGS; regno++)
    {
      addr = register_addr (regno, reg_ptr);
      if (addr >= core_reg_size)
	{
	  if (bad_reg < 0)
	    bad_reg = regno;
	}
      else
	{
	  supply_register (regno, core_reg_sect + addr);
	}
    }
  if (bad_reg >= 0)
    {
      error ("Register %s not found in core file.", REGISTER_NAME (bad_reg));
    }
  supply_register (ZERO_REGNUM, zerobuf);
  /* Frame ptr reg must appear to be 0; it is faked by stack handling code. */
  supply_register (DEPRECATED_FP_REGNUM, zerobuf);
}
Beispiel #9
0
/* Fetch one register.  */
static void
fetch_register (int regno)
{
  CORE_ADDR regaddr;
  int i, size;
  char *buf;

  if (regno >= the_low_target.num_regs)
    return;
  if ((*the_low_target.cannot_fetch_register) (regno))
    return;

  regaddr = register_addr (regno);
  if (regaddr == -1)
    return;
  size = (register_size (regno) + sizeof (PTRACE_XFER_TYPE) - 1)
         & - sizeof (PTRACE_XFER_TYPE);
  buf = alloca (size);
  for (i = 0; i < size; i += sizeof (PTRACE_XFER_TYPE))
    {
      errno = 0;
      *(PTRACE_XFER_TYPE *) (buf + i) =
	ptrace (PTRACE_PEEKUSER, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, 0);
      regaddr += sizeof (PTRACE_XFER_TYPE);
      if (errno != 0)
	{
	  /* Warning, not error, in case we are attached; sometimes the
	     kernel doesn't let us at the registers.  */
	  char *err = strerror (errno);
	  char *msg = alloca (strlen (err) + 128);
	  sprintf (msg, "reading register %d: %s", regno, err);
	  error (msg);
	  goto error_exit;
	}
    }
  if (the_low_target.left_pad_xfer
      && register_size (regno) < sizeof (PTRACE_XFER_TYPE))
    supply_register (regno, (buf + sizeof (PTRACE_XFER_TYPE)
			     - register_size (regno)));
  else
    supply_register (regno, buf);

error_exit:;
}
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);
	}
    }
}
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);
}
static void
store_register (int regno)
{
  int tid;
  int val;

  if (CANNOT_STORE_REGISTER (regno))
    return;

  /* GNU/Linux LWP ID's are process ID's.  */
  tid = TIDGET (inferior_ptid);
  if (tid == 0)
    tid = PIDGET (inferior_ptid); /* Not a threaded program.  */

  errno = 0;
  regcache_raw_collect (current_regcache, regno, &val);
  ptrace (PTRACE_POKEUSER, tid, register_addr (regno, 0), val);
  if (errno != 0)
    error (_("Couldn't write register %s (#%d): %s."), REGISTER_NAME (regno),
	   regno, safe_strerror (errno));
}
static void
fetch_register (int regnum)
{
  CORE_ADDR addr;
  size_t size;
  PTRACE_TYPE_RET *buf;
  int tid, i;

  if (CANNOT_FETCH_REGISTER (regnum))
    {
      regcache_raw_supply (current_regcache, regnum, NULL);
      return;
    }

  /* GNU/Linux LWP ID's are process ID's.  */
  tid = TIDGET (inferior_ptid);
  if (tid == 0)
    tid = PIDGET (inferior_ptid); /* Not a threaded program.  */

  /* This isn't really an address.  But ptrace thinks of it as one.  */
  addr = register_addr (regnum, U_REGS_OFFSET);
  size = register_size (current_gdbarch, regnum);

  gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0);
  buf = alloca (size);

  /* Read the register contents from the inferior a chuck at the time.  */
  for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
    {
      errno = 0;
      buf[i] = ptrace (PT_READ_U, tid, (PTRACE_TYPE_ARG3) addr, 0);
      if (errno != 0)
	error (_("Couldn't read register %s (#%d): %s."), REGISTER_NAME (regnum),
	       regnum, safe_strerror (errno));

      addr += sizeof (PTRACE_TYPE_RET);
    }
  regcache_raw_supply (current_regcache, regnum, buf);
}
static void
store_register (int regnum)
{
  CORE_ADDR addr;
  size_t size;
  PTRACE_TYPE_RET *buf;
  int tid, i;

  if (CANNOT_STORE_REGISTER (regnum))
    return;

  /* GNU/Linux LWP ID's are process ID's.  */
  tid = TIDGET (inferior_ptid);
  if (tid == 0)
    tid = PIDGET (inferior_ptid); /* Not a threaded program.  */

  /* This isn't really an address.  But ptrace thinks of it as one.  */
  addr = register_addr (regnum, U_REGS_OFFSET);
  size = register_size (current_gdbarch, regnum);

  gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0);
  buf = alloca (size);

  /* Write the register contents into the inferior a chunk at the time.  */
  regcache_raw_collect (current_regcache, regnum, buf);
  for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
    {
      errno = 0;
      ptrace (PT_WRITE_U, tid, (PTRACE_TYPE_ARG3) addr, buf[i]);
      if (errno != 0)
	error (_("Couldn't write register %s (#%d): %s."),
	       REGISTER_NAME (regnum), regnum, safe_strerror (errno));

      addr += sizeof (PTRACE_TYPE_RET);
    }
}
inline JavaCallWrapper* frame::entry_frame_call_wrapper() const {
  // note: adjust this code if the link argument in StubGenerator::call_stub() changes!
  return (JavaCallWrapper*) *register_addr(GR_I0);
}
inline address*  frame::sender_pc_addr()   const    { 
  assert(is_interpreted_frame(), "must be interpreted");
  return (address*) (register_addr(GR_Lsave_RP));
}
// Only called for interpreted frames??
inline void     frame::set_sender_pc(address addr) { 
  assert(is_interpreted_frame(), "must be interpreted");
  *register_addr(GR_Lsave_RP) = (intptr_t) (addr - pc_return_offset);
}