Beispiel #1
0
static enum target_xfer_status
record_btrace_xfer_partial (struct target_ops *ops, enum target_object object,
			    const char *annex, gdb_byte *readbuf,
			    const gdb_byte *writebuf, ULONGEST offset,
			    ULONGEST len, ULONGEST *xfered_len)
{
  struct target_ops *t;

  /* Filter out requests that don't make sense during replay.  */
  if (!record_btrace_allow_memory_access && record_btrace_is_replaying (ops))
    {
      switch (object)
	{
	case TARGET_OBJECT_MEMORY:
	  {
	    struct target_section *section;

	    /* We do not allow writing memory in general.  */
	    if (writebuf != NULL)
	      {
		*xfered_len = len;
		return TARGET_XFER_UNAVAILABLE;
	      }

	    /* We allow reading readonly memory.  */
	    section = target_section_by_addr (ops, offset);
	    if (section != NULL)
	      {
		/* Check if the section we found is readonly.  */
		if ((bfd_get_section_flags (section->the_bfd_section->owner,
					    section->the_bfd_section)
		     & SEC_READONLY) != 0)
		  {
		    /* Truncate the request to fit into this section.  */
		    len = min (len, section->endaddr - offset);
		    break;
		  }
	      }

	    *xfered_len = len;
	    return TARGET_XFER_UNAVAILABLE;
	  }
	}
    }

  /* Forward the request.  */
  for (ops = ops->beneath; ops != NULL; ops = ops->beneath)
    if (ops->to_xfer_partial != NULL)
      return ops->to_xfer_partial (ops, object, annex, readbuf, writebuf,
				   offset, len, xfered_len);

  *xfered_len = len;
  return TARGET_XFER_UNAVAILABLE;
}
Beispiel #2
0
static CORE_ADDR
ppc64_fbsd_convert_from_func_ptr_addr (struct gdbarch *gdbarch,
				       CORE_ADDR addr,
				       struct target_ops *targ)
{
  struct section_table *s = target_section_by_addr (targ, addr);
  
  /* Check if ADDR points to a function descriptor.  */
  if (s && strcmp (s->the_bfd_section->name, ".opd") == 0)
    return get_target_memory_unsigned (targ, addr, 8);

  return addr;
}
Beispiel #3
0
CORE_ADDR
ppc64_convert_from_func_ptr_addr (struct gdbarch *gdbarch,
					CORE_ADDR addr,
					struct target_ops *targ)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  struct target_section *s = target_section_by_addr (targ, addr);

  /* Check if ADDR points to a function descriptor.  */
  if (s && strcmp (s->the_bfd_section->name, ".opd") == 0)
    {
      /* There may be relocations that need to be applied to the .opd 
	 section.  Unfortunately, this function may be called at a time
	 where these relocations have not yet been performed -- this can
	 happen for example shortly after a library has been loaded with
	 dlopen, but ld.so has not yet applied the relocations.

	 To cope with both the case where the relocation has been applied,
	 and the case where it has not yet been applied, we do *not* read
	 the (maybe) relocated value from target memory, but we instead
	 read the non-relocated value from the BFD, and apply the relocation
	 offset manually.

	 This makes the assumption that all .opd entries are always relocated
	 by the same offset the section itself was relocated.  This should
	 always be the case for GNU/Linux executables and shared libraries.
	 Note that other kind of object files (e.g. those added via
	 add-symbol-files) will currently never end up here anyway, as this
	 function accesses *target* sections only; only the main exec and
	 shared libraries are ever added to the target.  */

      gdb_byte buf[8];
      int res;

      res = bfd_get_section_contents (s->the_bfd_section->owner,
				      s->the_bfd_section,
				      &buf, addr - s->addr, 8);
      if (res != 0)
	return extract_unsigned_integer (buf, 8, byte_order)
		- bfd_section_vma (s->bfd, s->the_bfd_section) + s->addr;
   }

  return addr;
}
LONGEST
target_bfd_xfer_partial (struct target_ops *ops,
			 enum target_object object,
			 const char *annex, gdb_byte *readbuf,
			 const gdb_byte *writebuf,
			 ULONGEST offset, LONGEST len)
{
  switch (object)
    {
    case TARGET_OBJECT_MEMORY:
      {
	struct section_table *s = target_section_by_addr (ops, offset);
	if (s == NULL)
	  return -1;
	/* If the length extends beyond the section, truncate it.  Be
           careful to not suffer from overflow (wish S contained a
           length).  */
	if ((offset - s->addr + len) > (s->endaddr - s->addr))
	  len = (s->endaddr - s->addr) - (offset - s->addr);
	if (readbuf != NULL
	    && !bfd_get_section_contents (s->bfd, s->the_bfd_section,
					  readbuf, offset - s->addr, len))
	  return -1;
#if 1
	if (writebuf != NULL)
	  return -1;
#else
	/* FIXME: cagney/2003-10-31: The BFD interface doesn't yet
           take a const buffer.  */
	if (writebuf != NULL
	    && !bfd_set_section_contents (s->bfd, s->the_bfd_section,
					  writebuf, offset - s->addr, len))
	  return -1;
#endif
	return len;
      }
    default:
      return -1;
    }
}
Beispiel #5
0
static CORE_ADDR
ppc_linux_convert_from_func_ptr_addr (struct gdbarch *gdbarch,
				      CORE_ADDR addr,
				      struct target_ops *targ)
{
  struct gdbarch_tdep *tdep;
  struct section_table *s = target_section_by_addr (targ, addr);
  char *sect_name = NULL;

  if (!s)
    return addr;

  tdep = gdbarch_tdep (gdbarch);

  switch (tdep->wordsize)
    {
      case 4:
	sect_name = ".plt";
	break;
      case 8:
	sect_name = ".opd";
	break;
      default:
	internal_error (__FILE__, __LINE__,
			_("failed internal consistency check"));
    }

  /* Check if ADDR points to a function descriptor.  */

  /* NOTE: this depends on the coincidence that the address of a functions
     entry point is contained in the first word of its function descriptor
     for both PPC-64 and for PPC-32 with secure PLTs.  */
  if ((strcmp (s->the_bfd_section->name, sect_name) == 0)
      && s->the_bfd_section->flags & SEC_DATA)
    return get_target_memory_unsigned (targ, addr, tdep->wordsize);

  return addr;
}