static LONGEST
ia64_hpux_xfer_memory_no_bs (struct target_ops *ops, const char *annex,
			     gdb_byte *readbuf, const gdb_byte *writebuf,
			     CORE_ADDR addr, LONGEST len)
{
  /* Memory writes need to be aligned on 16byte boundaries, at least
     when writing in the text section.  On the other hand, the size
     of the buffer does not need to be a multiple of 16bytes.

     No such restriction when performing memory reads.  */

  if (writebuf && addr & 0x0f)
    {
      const CORE_ADDR aligned_addr = addr & ~0x0f;
      const int aligned_len = len + (addr - aligned_addr);
      gdb_byte *aligned_buf = alloca (aligned_len * sizeof (gdb_byte));
      LONGEST status;

      /* Read the portion of memory between ALIGNED_ADDR and ADDR, so
         that we can write it back during our aligned memory write.  */
      status = super_xfer_partial (ops, TARGET_OBJECT_MEMORY, annex,
				   aligned_buf /* read */,
				   NULL /* write */,
				   aligned_addr, addr - aligned_addr);
      if (status <= 0)
	return 0;
      memcpy (aligned_buf + (addr - aligned_addr), writebuf, len);

      return super_xfer_partial (ops, TARGET_OBJECT_MEMORY, annex,
				 NULL /* read */, aligned_buf /* write */,
				 aligned_addr, aligned_len);
    }
  else
    /* Memory read or properly aligned memory write.  */
    return super_xfer_partial (ops, TARGET_OBJECT_MEMORY, annex, readbuf,
			       writebuf, addr, len);
}
static LONGEST
ia64_hpux_xfer_partial (struct target_ops *ops, enum target_object object,
			const char *annex, gdb_byte *readbuf,
			const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
{
  LONGEST val;

  if (object == TARGET_OBJECT_MEMORY)
    val = ia64_hpux_xfer_memory (ops, annex, readbuf, writebuf, offset, len);
  else if (object == TARGET_OBJECT_HPUX_UREGS)
    val = ia64_hpux_xfer_uregs (ops, annex, readbuf, writebuf, offset, len);
  else if (object == TARGET_OBJECT_HPUX_SOLIB_GOT)
    val = ia64_hpux_xfer_solib_got (ops, annex, readbuf, writebuf, offset,
				    len);
  else
    val = super_xfer_partial (ops, object, annex, readbuf, writebuf, offset,
			      len);

  return val;
}
Esempio n. 3
0
static enum target_xfer_status
ia64_linux_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)
{
  if (object == TARGET_OBJECT_UNWIND_TABLE && readbuf != NULL)
    {
      static long gate_table_size;
      gdb_byte *tmp_buf;
      long res;

      /* Probe for the table size once.  */
      if (gate_table_size == 0)
        gate_table_size = syscall (__NR_getunwind, NULL, 0);
      if (gate_table_size < 0)
	return TARGET_XFER_E_IO;

      if (offset >= gate_table_size)
	return TARGET_XFER_EOF;

      tmp_buf = alloca (gate_table_size);
      res = syscall (__NR_getunwind, tmp_buf, gate_table_size);
      if (res < 0)
	return TARGET_XFER_E_IO;
      gdb_assert (res == gate_table_size);

      if (offset + len > gate_table_size)
	len = gate_table_size - offset;

      memcpy (readbuf, tmp_buf + offset, len);
      *xfered_len = len;
      return TARGET_XFER_OK;
    }

  return super_xfer_partial (ops, object, annex, readbuf, writebuf,
			     offset, len, xfered_len);
}