Esempio n. 1
0
/* places a single char in the input buffer.  */
static int 
sf_fill_input (SCM port)
{
  SCM p = SCM_PACK (SCM_STREAM (port));
  SCM ans;
  scm_t_port *pt;

  ans = scm_call_0 (SCM_SIMPLE_VECTOR_REF (p, 3)); /* get char.  */
  if (scm_is_false (ans) || SCM_EOF_OBJECT_P (ans))
    return EOF;
  SCM_ASSERT (SCM_CHARP (ans), ans, SCM_ARG1, "sf_fill_input");
  pt = SCM_PTAB_ENTRY (port);    

  if (pt->encoding == NULL)
    {
      scm_t_port *pt = SCM_PTAB_ENTRY (port);    
      
      *pt->read_buf = SCM_CHAR (ans);
      pt->read_pos = pt->read_buf;
      pt->read_end = pt->read_buf + 1;
      return *pt->read_buf;
    }
  else
    scm_ungetc_unlocked (SCM_CHAR (ans), port);
  return SCM_CHAR (ans);
}
static void
gdbscm_memory_port_end_input (SCM port, int offset)
{
  scm_t_port *pt = SCM_PTAB_ENTRY (port);
  ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
  size_t remaining = pt->read_end - pt->read_pos;

  /* Note: Use of "int offset" is specified by Guile ports API.  */
  if ((offset < 0 && remaining + offset > remaining)
      || (offset > 0 && remaining + offset < remaining))
    {
      gdbscm_out_of_range_error (FUNC_NAME, 0, scm_from_int (offset),
				 _("overflow in offset calculation"));
    }
  offset += remaining;

  if (offset > 0)
    {
      pt->read_pos = pt->read_end;
      /* Throw error if unread-char used at beginning of file
	 then attempting to write.  Seems correct.  */
      if (!ioscm_lseek_address (iomem, -offset, SEEK_CUR))
	{
	  gdbscm_out_of_range_error (FUNC_NAME, 0, scm_from_int (offset),
				     _("bad offset"));
	}
    }

  pt->rw_active = SCM_PORT_NEITHER;
}
static void
gdbscm_memory_port_flush (SCM port)
{
  scm_t_port *pt = SCM_PTAB_ENTRY (port);
  ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
  size_t to_write = pt->write_pos - pt->write_buf;

  if (to_write == 0)
    return;

  /* There's no way to indicate a short write, so if the request goes past
     the end of the port's memory range, flag an error.  */
  if (to_write > iomem->size - iomem->current)
    {
      gdbscm_out_of_range_error (FUNC_NAME, 0,
				 gdbscm_scm_from_ulongest (to_write),
				 _("writing beyond end of memory range"));
    }

  if (target_write_memory (iomem->start + iomem->current, pt->write_buf,
			   to_write) != 0)
    gdbscm_memory_error (FUNC_NAME, _("error writing memory"), SCM_EOL);

  iomem->current += to_write;
  pt->write_pos = pt->write_buf;
  pt->rw_active = SCM_PORT_NEITHER;
}
static int
gdbscm_memory_port_fill_input (SCM port)
{
  scm_t_port *pt = SCM_PTAB_ENTRY (port);
  ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
  size_t to_read;

  /* "current" is the offset of the first byte we want to read.  */
  gdb_assert (iomem->current <= iomem->size);
  if (iomem->current == iomem->size)
    return EOF;

  /* Don't read outside the allowed memory range.  */
  to_read = pt->read_buf_size;
  if (to_read > iomem->size - iomem->current)
    to_read = iomem->size - iomem->current;

  if (target_read_memory (iomem->start + iomem->current, pt->read_buf,
			  to_read) != 0)
    gdbscm_memory_error (FUNC_NAME, _("error reading memory"), SCM_EOL);

  iomem->current += to_read;
  pt->read_pos = pt->read_buf;
  pt->read_end = pt->read_buf + to_read;
  return *pt->read_buf;
}
static void
ioscm_reinit_memory_port (SCM port, size_t read_buf_size,
			  size_t write_buf_size, const char *func_name)
{
  scm_t_port *pt = SCM_PTAB_ENTRY (port);
  ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);

  gdb_assert (read_buf_size >= min_memory_port_buf_size
	      && read_buf_size <= max_memory_port_buf_size);
  gdb_assert (write_buf_size >= min_memory_port_buf_size
	      && write_buf_size <= max_memory_port_buf_size);

  /* First check if the port is unbuffered.  */

  if (pt->read_buf == &pt->shortbuf)
    {
      gdb_assert (pt->write_buf == &pt->shortbuf);
      scm_misc_error (func_name, _("port is unbuffered: ~a"),
		      scm_list_1 (port));
    }

  /* Next check if anything is buffered.  */

  if (read_buf_size != pt->read_buf_size
      && pt->read_end != pt->read_buf)
    {
      scm_misc_error (func_name, _("read buffer not empty: ~a"),
		      scm_list_1 (port));
    }

  if (write_buf_size != pt->write_buf_size
      && pt->write_pos != pt->write_buf)
    {
      scm_misc_error (func_name, _("write buffer not empty: ~a"),
		      scm_list_1 (port));
    }

  /* Now we can update the buffer sizes, but only if the size has changed.  */

  if (read_buf_size != pt->read_buf_size)
    {
      iomem->read_buf_size = read_buf_size;
      pt->read_buf_size = read_buf_size;
      xfree (pt->read_buf);
      pt->read_buf = (unsigned char *) xmalloc (pt->read_buf_size);
      pt->read_pos = pt->read_end = pt->read_buf;
    }

  if (write_buf_size != pt->write_buf_size)
    {
      iomem->write_buf_size = write_buf_size;
      pt->write_buf_size = write_buf_size;
      xfree (pt->write_buf);
      pt->write_buf = (unsigned char *) xmalloc (pt->write_buf_size);
      pt->write_pos = pt->write_buf;
      pt->write_end = pt->write_buf + pt->write_buf_size;
    }
}
Esempio n. 6
0
static int 
sf_close (SCM port)
{
  SCM p = SCM_PACK (SCM_STREAM (port));
  SCM f = SCM_SIMPLE_VECTOR_REF (p, 4);
  if (scm_is_false (f))
    return 0;
  f = scm_call_0 (f);
  errno = 0;
  return scm_is_false (f) ? EOF : 0;
}
static SCM
gdbscm_memory_port_write_buffer_size (SCM port)
{
  ioscm_memory_port *iomem;

  SCM_ASSERT_TYPE (gdbscm_is_memory_port (port), port, SCM_ARG1, FUNC_NAME,
		   memory_port_desc_name);

  iomem = (ioscm_memory_port *) SCM_STREAM (port);
  return scm_from_uint (iomem->write_buf_size);
}
Esempio n. 8
0
static void
sf_write (SCM port, const void *data, size_t size)
{
  SCM p = SCM_PACK (SCM_STREAM (port));

  /* DATA is assumed to be a locale-encoded C string, which makes it
     hard to reliably pass binary data to a soft port.  It can be
     achieved by choosing a Latin-1 locale, though, but the recommended
     approach is to use an R6RS "custom binary output port" instead.  */
  scm_call_1 (SCM_SIMPLE_VECTOR_REF (p, 1),
	      scm_from_locale_stringn ((char *) data, size));
}
static SCM
gdbscm_memory_port_range (SCM port)
{
  ioscm_memory_port *iomem;

  SCM_ASSERT_TYPE (gdbscm_is_memory_port (port), port, SCM_ARG1, FUNC_NAME,
		   memory_port_desc_name);

  iomem = (ioscm_memory_port *) SCM_STREAM (port);
  return scm_list_2 (gdbscm_scm_from_ulongest (iomem->start),
		     gdbscm_scm_from_ulongest (iomem->end));
}
Esempio n. 10
0
static int 
sf_input_waiting (SCM port)
{
  SCM p = SCM_PACK (SCM_STREAM (port));
  if (SCM_SIMPLE_VECTOR_LENGTH (p) >= 6)
    {
      SCM f = SCM_SIMPLE_VECTOR_REF (p, 5);
      if (scm_is_true (f))
	return scm_to_int (scm_call_0 (f));
    }
  /* Default is such that char-ready? for soft ports returns #t, as it
     did before this extension was implemented. */
  return 1;
}
Esempio n. 11
0
static int
gdbscm_memory_port_print (SCM exp, SCM port, scm_print_state *pstate)
{
  ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (exp);
  char *type = SCM_PTOBNAME (SCM_PTOBNUM (exp));

  scm_puts ("#<", port);
  scm_print_port_mode (exp, port);
  /* scm_print_port_mode includes a trailing space.  */
  gdbscm_printf (port, "%s %s-%s", type,
		 hex_string (iomem->start), hex_string (iomem->end));
  scm_putc ('>', port);
  return 1;
}
Esempio n. 12
0
static int
gdbscm_memory_port_close (SCM port)
{
  scm_t_port *pt = SCM_PTAB_ENTRY (port);
  ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);

  gdbscm_memory_port_flush (port);

  if (pt->read_buf == pt->putback_buf)
    pt->read_buf = pt->saved_read_buf;
  if (pt->read_buf != &pt->shortbuf)
    xfree (pt->read_buf);
  if (pt->write_buf != &pt->shortbuf)
    xfree (pt->write_buf);
  scm_gc_free (iomem, sizeof (*iomem), "memory port");

  return 0;
}
Esempio n. 13
0
/* Read one byte from PORT.  */
static int
fill_input (SCM port)
{
  int result;
  scm_t_port *c_port = SCM_PTAB_ENTRY (port);

  /* Make sure that C_PORT's internal buffer wasn't changed behind our back.
     See http://lists.gnu.org/archive/html/guile-devel/2008-11/msg00042.html
     for an example where this assumption matters.  */
  assert (c_port->read_buf == (unsigned char *) SCM_STREAM (port));
  assert (c_port->read_buf_size == PORT_BUFFER_SIZE);

  if (c_port->read_pos >= c_port->read_end)
    result = EOF;
  else
    result = (int) *c_port->read_pos++;

  return result;
}
Esempio n. 14
0
static SCM
gdbscm_set_memory_port_write_buffer_size_x (SCM port, SCM size)
{
  ioscm_memory_port *iomem;

  SCM_ASSERT_TYPE (gdbscm_is_memory_port (port), port, SCM_ARG1, FUNC_NAME,
		   memory_port_desc_name);
  SCM_ASSERT_TYPE (scm_is_integer (size), size, SCM_ARG2, FUNC_NAME,
		   _("integer"));

  if (!scm_is_unsigned_integer (size, min_memory_port_buf_size,
				max_memory_port_buf_size))
    {
      gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG2, size,
				 out_of_range_buf_size);
    }

  iomem = (ioscm_memory_port *) SCM_STREAM (port);
  ioscm_reinit_memory_port (port, iomem->read_buf_size, scm_to_uint (size),
			    FUNC_NAME);

  return SCM_UNSPECIFIED;
}
Esempio n. 15
0
static scm_t_off
gdbscm_memory_port_seek (SCM port, scm_t_off offset, int whence)
{
  scm_t_port *pt = SCM_PTAB_ENTRY (port);
  ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
  CORE_ADDR result;
  int rc;

  if (pt->rw_active == SCM_PORT_WRITE)
    {
      if (offset != 0 || whence != SEEK_CUR)
	{
	  gdbscm_memory_port_flush (port);
	  rc = ioscm_lseek_address (iomem, offset, whence);
	  result = iomem->current;
	}
      else
	{
	  /* Read current position without disturbing the buffer,
	     but flag an error if what's in the buffer goes outside the
	     allowed range.  */
	  CORE_ADDR current = iomem->current;
	  size_t delta = pt->write_pos - pt->write_buf;

	  if (current + delta < current
	      || current + delta > iomem->size)
	    rc = 0;
	  else
	    {
	      result = current + delta;
	      rc = 1;
	    }
	}
    }
  else if (pt->rw_active == SCM_PORT_READ)
    {
      if (offset != 0 || whence != SEEK_CUR)
	{
	  scm_end_input (port);
	  rc = ioscm_lseek_address (iomem, offset, whence);
	  result = iomem->current;
	}
      else
	{
	  /* Read current position without disturbing the buffer
	     (particularly the unread-char buffer).  */
	  CORE_ADDR current = iomem->current;
	  size_t remaining = pt->read_end - pt->read_pos;

	  if (current - remaining > current
	      || current - remaining < iomem->start)
	    rc = 0;
	  else
	    {
	      result = current - remaining;
	      rc = 1;
	    }

	  if (rc != 0 && pt->read_buf == pt->putback_buf)
	    {
	      size_t saved_remaining = pt->saved_read_end - pt->saved_read_pos;

	      if (result - saved_remaining > result
		  || result - saved_remaining < iomem->start)
		rc = 0;
	      else
		result -= saved_remaining;
	    }
	}
    }
  else /* SCM_PORT_NEITHER */
    {
      rc = ioscm_lseek_address (iomem, offset, whence);
      result = iomem->current;
    }

  if (rc == 0)
    {
      gdbscm_out_of_range_error (FUNC_NAME, 0,
				 gdbscm_scm_from_longest (offset),
				 _("bad seek"));
    }

  /* TODO: The Guile API doesn't support 32x64.  We can't fix that here,
     and there's no need to throw an error if the new address can't be
     represented in a scm_t_off.  But we could return something less
     clumsy.  */
  return result;
}
Esempio n. 16
0
static void
gdbscm_memory_port_write (SCM port, const void *void_data, size_t size)
{
  scm_t_port *pt = SCM_PTAB_ENTRY (port);
  ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
  const gdb_byte *data = (const gdb_byte *) void_data;

  /* There's no way to indicate a short write, so if the request goes past
     the end of the port's memory range, flag an error.  */
  if (size > iomem->size - iomem->current)
    {
      gdbscm_out_of_range_error (FUNC_NAME, 0, gdbscm_scm_from_ulongest (size),
				 _("writing beyond end of memory range"));
    }

  if (pt->write_buf == &pt->shortbuf)
    {
      /* Unbuffered port.  */
      if (target_write_memory (iomem->start + iomem->current, data, size) != 0)
	gdbscm_memory_error (FUNC_NAME, _("error writing memory"), SCM_EOL);
      iomem->current += size;
      return;
    }

  /* Note: The edge case of what to do when the buffer exactly fills is
     debatable.  Guile flushes when the buffer exactly fills up, so we
     do too.  It's counter-intuitive to my mind, but in case there's a
     subtlety somewhere that depends on this, we do the same.  */

  {
    size_t space = pt->write_end - pt->write_pos;

    if (size < space)
      {
	/* Data fits in buffer, and does not fill it.  */
	memcpy (pt->write_pos, data, size);
	pt->write_pos += size;
      }
    else
      {
	memcpy (pt->write_pos, data, space);
	pt->write_pos = pt->write_end;
	gdbscm_memory_port_flush (port);
	{
	  const gdb_byte *ptr = data + space;
	  size_t remaining = size - space;

	  if (remaining >= pt->write_buf_size)
	    {
	      if (target_write_memory (iomem->start + iomem->current, ptr,
				       remaining) != 0)
		gdbscm_memory_error (FUNC_NAME, _("error writing memory"),
				     SCM_EOL);
	      iomem->current += remaining;
	    }
	  else
	    {
	      memcpy (pt->write_pos, ptr, remaining);
	      pt->write_pos += remaining;
	    }
	}
      }
  }
}