Move gdb_select.h to gdbsupport/
[deliverable/binutils-gdb.git] / gdb / guile / scm-ports.c
index dcf7d2d44f503b8086a531bc3492d003b7f9b247..407d1d36f1f5bcbfedbb50554b4f951f84dc0cb2 100644 (file)
@@ -1,7 +1,7 @@
 /* Support for connecting Guile's stdio to GDB's.
    as well as r/w memory via ports.
 
-   Copyright (C) 2014-2015 Free Software Foundation, Inc.
+   Copyright (C) 2014-2020 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    conventions, et.al.  */
 
 #include "defs.h"
-#include "gdb_select.h"
-#include "interps.h"
+#include "gdbsupport/gdb_select.h"
+#include "top.h"
 #include "target.h"
 #include "guile-internal.h"
+#include "gdbsupport/gdb_optional.h"
 
 #ifdef HAVE_POLL
 #if defined (HAVE_POLL_H)
 
 /* A ui-file for sending output to Guile.  */
 
-typedef struct
+class ioscm_file_port : public ui_file
 {
-  int *magic;
-  SCM port;
-} ioscm_file_port;
+public:
+  /* Return a ui_file that writes to PORT.  */
+  explicit ioscm_file_port (SCM port);
+
+  void flush () override;
+  void write (const char *buf, long length_buf) override;
+
+private:
+  SCM m_port;
+};
 
 /* Data for a memory port.  */
 
 typedef struct
 {
-  /* Bounds of memory range this port is allowed to access, inclusive.
-     To simplify overflow handling, an END of 0xff..ff is not allowed.
-     This also means a start address of 0xff..ff is also not allowed.
-     I can live with that.  */
+  /* Bounds of memory range this port is allowed to access: [start, end).
+     This means that 0xff..ff is not accessible.  I can live with that.  */
   CORE_ADDR start, end;
 
-  /* (end - start + 1), recorded for convenience.  */
+  /* (end - start), recorded for convenience.  */
   ULONGEST size;
 
   /* Think of this as the lseek value maintained by the kernel.
@@ -92,10 +98,6 @@ static SCM input_port_scm;
 static SCM output_port_scm;
 static SCM error_port_scm;
 
-/* Magic number to identify port ui-files.
-   Actually, the address of this variable is the magic number.  */
-static int file_port_magic;
-
 /* Internal enum for specifying output port.  */
 enum oport { GDB_STDOUT, GDB_STDERR };
 
@@ -203,7 +205,9 @@ ioscm_input_waiting (SCM port)
     FD_ZERO (&input_fds);
     FD_SET (fdes, &input_fds);
 
-    num_found = gdb_select (num_fds, &input_fds, NULL, NULL, &timeout);
+    num_found = interruptible_select (num_fds,
+                                     &input_fds, NULL, NULL,
+                                     &timeout);
     if (num_found < 0)
       {
        /* Guile doesn't export SIGINT hooks like Python does.
@@ -230,7 +234,7 @@ ioscm_fill_input (SCM port)
   gdb_flush (gdb_stdout);
   gdb_flush (gdb_stderr);
 
-  count = ui_file_read (gdb_stdin, (char *) pt->read_buf, pt->read_buf_size);
+  count = gdb_stdin->read ((char *) pt->read_buf, pt->read_buf_size);
   if (count == -1)
     scm_syserror (FUNC_NAME);
   if (count == 0)
@@ -263,20 +267,24 @@ fputsn_filtered (const char *s, size_t size, struct ui_file *stream)
 static void
 ioscm_write (SCM port, const void *data, size_t size)
 {
-  volatile struct gdb_exception except;
 
   /* If we're called on stdin, punt.  */
   if (scm_is_eq (port, input_port_scm))
     return;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  gdbscm_gdb_exception exc {};
+  try
     {
       if (scm_is_eq (port, error_port_scm))
-       fputsn_filtered (data, size, gdb_stderr);
+       fputsn_filtered ((const char *) data, size, gdb_stderr);
       else
-       fputsn_filtered (data, size, gdb_stdout);
+       fputsn_filtered ((const char *) data, size, gdb_stdout);
     }
-  GDBSCM_HANDLE_GDB_EXCEPTION (except);
+  catch (const gdb_exception &except)
+    {
+      exc = unpack (except);
+    }
+  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
 }
 
 /* Flush gdb's stdout or stderr.  */
@@ -325,7 +333,8 @@ ioscm_init_stdio_buffers (SCM port, long mode_bits)
 
   if (!writing && size > 0)
     {
-      pt->read_buf = scm_gc_malloc_pointerless (size, "port buffer");
+      pt->read_buf
+       = (unsigned char *) scm_gc_malloc_pointerless (size, "port buffer");
       pt->read_pos = pt->read_end = pt->read_buf;
       pt->read_buf_size = size;
     }
@@ -337,7 +346,8 @@ ioscm_init_stdio_buffers (SCM port, long mode_bits)
 
   if (writing && size > 0)
     {
-      pt->write_buf = scm_gc_malloc_pointerless (size, "port buffer");
+      pt->write_buf
+       = (unsigned char *) scm_gc_malloc_pointerless (size, "port buffer");
       pt->write_pos = pt->write_buf;
       pt->write_buf_size = size;
     }
@@ -356,6 +366,7 @@ ioscm_make_gdb_stdio_port (int fd)
 {
   int is_a_tty = isatty (fd);
   const char *name;
+  const char *mode_str;
   long mode_bits;
   SCM port;
 
@@ -363,20 +374,21 @@ ioscm_make_gdb_stdio_port (int fd)
     {
     case 0:
       name = input_port_name;
-      mode_bits = scm_mode_bits (is_a_tty ? "r0" : "r");
+      mode_str = is_a_tty ? "r0" : "r";
       break;
     case 1:
       name = output_port_name;
-      mode_bits = scm_mode_bits (is_a_tty ? "w0" : "w");
+      mode_str = is_a_tty ? "w0" : "w";
       break;
     case 2:
       name = error_port_name;
-      mode_bits = scm_mode_bits (is_a_tty ? "w0" : "w");
+      mode_str = is_a_tty ? "w0" : "w";
       break;
     default:
       gdb_assert_not_reached ("bad stdio file descriptor");
     }
 
+  mode_bits = scm_mode_bits ((char *) mode_str);
   port = ioscm_open_port (stdio_port_desc, mode_bits);
 
   scm_set_port_filename_x (port, gdbscm_scm_from_c_string (name));
@@ -424,74 +436,21 @@ gdbscm_error_port (void)
 \f
 /* Support for sending GDB I/O to Guile ports.  */
 
-static void
-ioscm_file_port_delete (struct ui_file *file)
-{
-  ioscm_file_port *stream = ui_file_data (file);
-
-  if (stream->magic != &file_port_magic)
-    internal_error (__FILE__, __LINE__,
-                   _("ioscm_file_port_delete: bad magic number"));
-  xfree (stream);
-}
-
-static void
-ioscm_file_port_rewind (struct ui_file *file)
-{
-  ioscm_file_port *stream = ui_file_data (file);
-
-  if (stream->magic != &file_port_magic)
-    internal_error (__FILE__, __LINE__,
-                   _("ioscm_file_port_rewind: bad magic number"));
-
-  scm_truncate_file (stream->port, 0);
-}
+ioscm_file_port::ioscm_file_port (SCM port)
+  : m_port (port)
+{}
 
-static void
-ioscm_file_port_put (struct ui_file *file,
-                    ui_file_put_method_ftype *write,
-                    void *dest)
+void
+ioscm_file_port::flush ()
 {
-  ioscm_file_port *stream = ui_file_data (file);
-
-  if (stream->magic != &file_port_magic)
-    internal_error (__FILE__, __LINE__,
-                   _("ioscm_file_port_put: bad magic number"));
-
-  /* This function doesn't meld with ports very well.  */
 }
 
-static void
-ioscm_file_port_write (struct ui_file *file,
-                      const char *buffer,
-                      long length_buffer)
+void
+ioscm_file_port::write (const char *buffer, long length_buffer)
 {
-  ioscm_file_port *stream = ui_file_data (file);
-
-  if (stream->magic != &file_port_magic)
-    internal_error (__FILE__, __LINE__,
-                   _("ioscm_pot_file_write: bad magic number"));
-
-  scm_c_write (stream->port, buffer, length_buffer);
+  scm_c_write (m_port, buffer, length_buffer);
 }
 
-/* Return a ui_file that writes to PORT.  */
-
-static struct ui_file *
-ioscm_file_port_new (SCM port)
-{
-  ioscm_file_port *stream = XCNEW (ioscm_file_port);
-  struct ui_file *file = ui_file_new ();
-
-  set_ui_file_data (file, stream, ioscm_file_port_delete);
-  set_ui_file_rewind (file, ioscm_file_port_rewind);
-  set_ui_file_put (file, ioscm_file_port_put);
-  set_ui_file_write (file, ioscm_file_port_write);
-  stream->magic = &file_port_magic;
-  stream->port = port;
-
-  return file;
-}
 \f
 /* Helper routine for with-{output,error}-to-port.  */
 
@@ -499,8 +458,6 @@ static SCM
 ioscm_with_output_to_port_worker (SCM port, SCM thunk, enum oport oport,
                                  const char *func_name)
 {
-  struct ui_file *port_file;
-  struct cleanup *cleanups;
   SCM result;
 
   SCM_ASSERT_TYPE (gdbscm_is_true (scm_output_port_p (port)), port,
@@ -508,35 +465,29 @@ ioscm_with_output_to_port_worker (SCM port, SCM thunk, enum oport oport,
   SCM_ASSERT_TYPE (gdbscm_is_true (scm_thunk_p (thunk)), thunk,
                   SCM_ARG2, func_name, _("thunk"));
 
-  cleanups = set_batch_flag_and_make_cleanup_restore_page_info ();
-
-  make_cleanup_restore_integer (&interpreter_async);
-  interpreter_async = 0;
-
-  port_file = ioscm_file_port_new (port);
+  set_batch_flag_and_restore_page_info save_page_info;
 
-  make_cleanup_ui_file_delete (port_file);
+  scoped_restore restore_async = make_scoped_restore (&current_ui->async, 0);
 
-  if (oport == GDB_STDERR)
-    {
-      make_cleanup_restore_ui_file (&gdb_stderr);
-      gdb_stderr = port_file;
-    }
-  else
-    {
-      make_cleanup_restore_ui_file (&gdb_stdout);
+  ui_file_up port_file (new ioscm_file_port (port));
 
-      if (ui_out_redirect (current_uiout, port_file) < 0)
-       warning (_("Current output protocol does not support redirection"));
-      else
-       make_cleanup_ui_out_redirect_pop (current_uiout);
+  scoped_restore save_file = make_scoped_restore (oport == GDB_STDERR
+                                                 ? &gdb_stderr : &gdb_stdout);
 
-      gdb_stdout = port_file;
-    }
+  {
+    gdb::optional<ui_out_redirect_pop> redirect_popper;
+    if (oport == GDB_STDERR)
+      gdb_stderr = port_file.get ();
+    else
+      {
+       current_uiout->redirect (port_file.get ());
+       redirect_popper.emplace (current_uiout);
 
-  result = gdbscm_safe_call_0 (thunk, NULL);
+       gdb_stdout = port_file.get ();
+      }
 
-  do_cleanups (cleanups);
+    result = gdbscm_safe_call_0 (thunk, NULL);
+  }
 
   if (gdbscm_is_exception (result))
     gdbscm_throw (result);
@@ -592,7 +543,7 @@ ioscm_lseek_address (ioscm_memory_port *iomem, LONGEST offset, int whence)
     case SEEK_CUR:
       /* Catch over/underflow.  */
       if ((offset < 0 && iomem->current + offset > iomem->current)
-         || (offset >= 0 && iomem->current + offset < iomem->current))
+         || (offset > 0 && iomem->current + offset < iomem->current))
        return 0;
       new_current = iomem->current + offset;
       break;
@@ -627,7 +578,8 @@ gdbscm_memory_port_fill_input (SCM port)
   size_t to_read;
 
   /* "current" is the offset of the first byte we want to read.  */
-  if (iomem->current >= iomem->size)
+  gdb_assert (iomem->current <= iomem->size);
+  if (iomem->current == iomem->size)
     return EOF;
 
   /* Don't read outside the allowed memory range.  */
@@ -639,9 +591,9 @@ gdbscm_memory_port_fill_input (SCM port)
                          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;
-  iomem->current += to_read;
   return *pt->read_buf;
 }
 
@@ -712,17 +664,11 @@ gdbscm_memory_port_flush (SCM port)
 /* "write" method for memory ports.  */
 
 static void
-gdbscm_memory_port_write (SCM port, const void *data, size_t size)
+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 char *input = (char *) data;
-
-  /* We could get fancy here, and try to buffer the request since we're
-     buffering anyway.  But there's currently no need.  */
-
-  /* First flush what's currently buffered.  */
-  gdbscm_memory_port_flush (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.  */
@@ -732,10 +678,54 @@ gdbscm_memory_port_write (SCM port, const void *data, size_t size)
                                 _("writing beyond end of memory range"));
     }
 
-  if (target_write_memory (iomem->start + iomem->current, data, size) != 0)
-    gdbscm_memory_error (FUNC_NAME, _("error writing memory"), SCM_EOL);
+  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;
 
-  iomem->current += size;
+         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;
+           }
+       }
+      }
+  }
 }
 
 /* "seek" method for memory ports.  */
@@ -765,7 +755,7 @@ gdbscm_memory_port_seek (SCM port, scm_t_off offset, int whence)
          size_t delta = pt->write_pos - pt->write_buf;
 
          if (current + delta < current
-             || current + delta > iomem->size + 1)
+             || current + delta > iomem->size)
            rc = 0;
          else
            {
@@ -842,8 +832,10 @@ gdbscm_memory_port_close (SCM port)
 
   if (pt->read_buf == pt->putback_buf)
     pt->read_buf = pt->saved_read_buf;
-  xfree (pt->read_buf);
-  xfree (pt->write_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;
@@ -912,6 +904,7 @@ ioscm_parse_mode_bits (const char *func_name, const char *mode)
     {
       switch (*p)
        {
+       case '0':
        case 'b':
        case '+':
          break;
@@ -930,9 +923,8 @@ ioscm_parse_mode_bits (const char *func_name, const char *mode)
 }
 
 /* Helper for gdbscm_open_memory to finish initializing the port.
-   The port has address range [start,end].
-   To simplify overflow handling, an END of 0xff..ff is not allowed.
-   This also means a start address of 0xff..f is also not allowed.
+   The port has address range [start,end).
+   This means that address of 0xff..ff is not accessible.
    I can live with that.  */
 
 static void
@@ -940,29 +932,45 @@ ioscm_init_memory_port (SCM port, CORE_ADDR start, CORE_ADDR end)
 {
   scm_t_port *pt;
   ioscm_memory_port *iomem;
+  int buffered = (SCM_CELL_WORD_0 (port) & SCM_BUF0) == 0;
 
   gdb_assert (start <= end);
-  gdb_assert (end < ~(CORE_ADDR) 0);
 
   iomem = (ioscm_memory_port *) scm_gc_malloc_pointerless (sizeof (*iomem),
                                                           "memory port");
 
   iomem->start = start;
   iomem->end = end;
-  iomem->size = end - start + 1;
+  iomem->size = end - start;
   iomem->current = 0;
-  iomem->read_buf_size = default_read_buf_size;
-  iomem->write_buf_size = default_write_buf_size;
+  if (buffered)
+    {
+      iomem->read_buf_size = default_read_buf_size;
+      iomem->write_buf_size = default_write_buf_size;
+    }
+  else
+    {
+      iomem->read_buf_size = 1;
+      iomem->write_buf_size = 1;
+    }
 
   pt = SCM_PTAB_ENTRY (port);
   /* Match the expectation of `binary-port?'.  */
   pt->encoding = NULL;
   pt->rw_random = 1;
   pt->read_buf_size = iomem->read_buf_size;
-  pt->read_buf = xmalloc (pt->read_buf_size);
-  pt->read_pos = pt->read_end = pt->read_buf;
   pt->write_buf_size = iomem->write_buf_size;
-  pt->write_buf = xmalloc (pt->write_buf_size);
+  if (buffered)
+    {
+      pt->read_buf = (unsigned char *) xmalloc (pt->read_buf_size);
+      pt->write_buf = (unsigned char *) xmalloc (pt->write_buf_size);
+    }
+  else
+    {
+      pt->read_buf = &pt->shortbuf;
+      pt->write_buf = &pt->shortbuf;
+    }
+  pt->read_pos = pt->read_end = pt->read_buf;
   pt->write_pos = pt->write_buf;
   pt->write_end = pt->write_buf + pt->write_buf_size;
 
@@ -970,7 +978,9 @@ ioscm_init_memory_port (SCM port, CORE_ADDR start, CORE_ADDR end)
 }
 
 /* Re-initialize a memory port, updating its read/write buffer sizes.
-   An exception is thrown if data is still buffered, except in the case
+   An exception is thrown if the port is unbuffered.
+   TODO: Allow switching buffered/unbuffered.
+   An exception is also thrown if data is still buffered, except in the case
    where the buffer size isn't changing (since that's just a nop).  */
 
 static void
@@ -985,7 +995,16 @@ ioscm_reinit_memory_port (SCM port, size_t read_buf_size,
   gdb_assert (write_buf_size >= min_memory_port_buf_size
              && write_buf_size <= max_memory_port_buf_size);
 
-  /* First check if anything is buffered.  */
+  /* 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)
@@ -1008,7 +1027,7 @@ ioscm_reinit_memory_port (SCM port, size_t read_buf_size,
       iomem->read_buf_size = read_buf_size;
       pt->read_buf_size = read_buf_size;
       xfree (pt->read_buf);
-      pt->read_buf = xmalloc (pt->read_buf_size);
+      pt->read_buf = (unsigned char *) xmalloc (pt->read_buf_size);
       pt->read_pos = pt->read_end = pt->read_buf;
     }
 
@@ -1017,7 +1036,7 @@ ioscm_reinit_memory_port (SCM port, size_t read_buf_size,
       iomem->write_buf_size = write_buf_size;
       pt->write_buf_size = write_buf_size;
       xfree (pt->write_buf);
-      pt->write_buf = xmalloc (pt->write_buf_size);
+      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;
     }
@@ -1026,17 +1045,16 @@ ioscm_reinit_memory_port (SCM port, size_t read_buf_size,
 /* (open-memory [#:mode string] [#:start address] [#:size integer]) -> port
    Return a port that can be used for reading and writing memory.
    MODE is a string, and must be one of "r", "w", or "r+".
-   For compatibility "b" (binary) may also be present, but we ignore it:
+   "0" may be appended to MODE to mark the port as unbuffered.
+   For compatibility "b" (binary) may also be appended, but we ignore it:
    memory ports are binary only.
 
-   TODO: Support "0" (unbuffered)?  Only support "0" (always unbuffered)?
-
    The chunk of memory that can be accessed can be bounded.
-   If both START,SIZE are unspecified, all of memory can be accessed.
-   If only START is specified, all of memory from that point on can be
-   accessed.  If only SIZE if specified, all memory in [0,SIZE) can be
-   accessed.  If both are specified, all memory in [START,START+SIZE) can be
-   accessed.
+   If both START,SIZE are unspecified, all of memory can be accessed
+   (except 0xff..ff).  If only START is specified, all of memory from that
+   point on can be accessed (except 0xff..ff).  If only SIZE if specified,
+   all memory in [0,SIZE) can be accessed.  If both are specified, all memory
+   in [START,START+SIZE) can be accessed.
 
    Note: If it becomes useful enough we can later add #:end as an alternative
    to #:size.  For now it is left out.
@@ -1044,7 +1062,7 @@ ioscm_reinit_memory_port (SCM port, size_t read_buf_size,
    The result is a Scheme port, and its semantics are a bit odd for accessing
    memory (e.g., unget), but we don't try to hide this.  It's a port.
 
-   N.B. Seeks on the port must be in the range [0,size).
+   N.B. Seeks on the port must be in the range [0,size].
    This is for similarity with bytevector ports, and so that one can seek
    to the first byte.  */
 
@@ -1067,25 +1085,14 @@ gdbscm_open_memory (SCM rest)
                              &start_arg_pos, &start,
                              &size_arg_pos, &size);
 
-  scm_dynwind_begin (0);
+  scm_dynwind_begin ((scm_t_dynwind_flags) 0);
 
   if (mode == NULL)
     mode = xstrdup ("r");
   scm_dynwind_free (mode);
 
-  if (start == ~(CORE_ADDR) 0)
-    {
-      gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, scm_from_int (-1),
-                                _("start address of 0xff..ff not allowed"));
-    }
-
   if (size_arg_pos > 0)
     {
-      if (size == 0)
-       {
-         gdbscm_out_of_range_error (FUNC_NAME, 0, scm_from_int (0),
-                                    "zero size");
-       }
       /* For now be strict about start+size overflowing.  If it becomes
         a nuisance we can relax things later.  */
       if (start + size < start)
@@ -1095,17 +1102,10 @@ gdbscm_open_memory (SCM rest)
                                            gdbscm_scm_from_ulongest (size)),
                                     _("start+size overflows"));
        }
-      end = start + size - 1;
-      if (end == ~(CORE_ADDR) 0)
-       {
-         gdbscm_out_of_range_error (FUNC_NAME, 0,
-                               scm_list_2 (gdbscm_scm_from_ulongest (start),
-                                           gdbscm_scm_from_ulongest (size)),
-                                    _("end address of 0xff..ff not allowed"));
-       }
+      end = start + size;
     }
   else
-    end = (~(CORE_ADDR) 0) - 1;
+    end = ~(CORE_ADDR) 0;
 
   mode_bits = ioscm_parse_mode_bits (FUNC_NAME, mode);
 
@@ -1165,7 +1165,8 @@ gdbscm_memory_port_read_buffer_size (SCM port)
 }
 
 /* (set-memory-port-read-buffer-size! port size) -> unspecified
-   An exception is thrown if read data is still buffered.  */
+   An exception is thrown if read data is still buffered or if the port
+   is unbuffered.  */
 
 static SCM
 gdbscm_set_memory_port_read_buffer_size_x (SCM port, SCM size)
@@ -1206,7 +1207,8 @@ gdbscm_memory_port_write_buffer_size (SCM port)
 }
 
 /* (set-memory-port-write-buffer-size! port size) -> unspecified
-   An exception is thrown if write data is still buffered.  */
+   An exception is thrown if write data is still buffered or if the port
+   is unbuffered.  */
 
 static SCM
 gdbscm_set_memory_port_write_buffer_size_x (SCM port, SCM size)
@@ -1236,44 +1238,44 @@ gdbscm_set_memory_port_write_buffer_size_x (SCM port, SCM size)
 
 static const scheme_function port_functions[] =
 {
-  { "input-port", 0, 0, 0, gdbscm_input_port,
+  { "input-port", 0, 0, 0, as_a_scm_t_subr (gdbscm_input_port),
     "\
 Return gdb's input port." },
 
-  { "output-port", 0, 0, 0, gdbscm_output_port,
+  { "output-port", 0, 0, 0, as_a_scm_t_subr (gdbscm_output_port),
     "\
 Return gdb's output port." },
 
-  { "error-port", 0, 0, 0, gdbscm_error_port,
+  { "error-port", 0, 0, 0, as_a_scm_t_subr (gdbscm_error_port),
     "\
 Return gdb's error port." },
 
-  { "stdio-port?", 1, 0, 0, gdbscm_stdio_port_p,
+  { "stdio-port?", 1, 0, 0, as_a_scm_t_subr (gdbscm_stdio_port_p),
     "\
 Return #t if the object is a gdb:stdio-port." },
 
-  { "open-memory", 0, 0, 1, gdbscm_open_memory,
+  { "open-memory", 0, 0, 1, as_a_scm_t_subr (gdbscm_open_memory),
     "\
 Return a port that can be used for reading/writing inferior memory.\n\
 \n\
   Arguments: [#:mode string] [#:start address] [#:size integer]\n\
   Returns: A port object." },
 
-  { "memory-port?", 1, 0, 0, gdbscm_memory_port_p,
+  { "memory-port?", 1, 0, 0, as_a_scm_t_subr (gdbscm_memory_port_p),
     "\
 Return #t if the object is a memory port." },
 
-  { "memory-port-range", 1, 0, 0, gdbscm_memory_port_range,
+  { "memory-port-range", 1, 0, 0, as_a_scm_t_subr (gdbscm_memory_port_range),
     "\
 Return the memory range of the port as (start end)." },
 
   { "memory-port-read-buffer-size", 1, 0, 0,
-    gdbscm_memory_port_read_buffer_size,
+    as_a_scm_t_subr (gdbscm_memory_port_read_buffer_size),
     "\
 Return the size of the read buffer for the memory port." },
 
   { "set-memory-port-read-buffer-size!", 2, 0, 0,
-    gdbscm_set_memory_port_read_buffer_size_x,
+    as_a_scm_t_subr (gdbscm_set_memory_port_read_buffer_size_x),
     "\
 Set the size of the read buffer for the memory port.\n\
 \n\
@@ -1281,12 +1283,12 @@ Set the size of the read buffer for the memory port.\n\
   Returns: unspecified." },
 
   { "memory-port-write-buffer-size", 1, 0, 0,
-    gdbscm_memory_port_write_buffer_size,
+    as_a_scm_t_subr (gdbscm_memory_port_write_buffer_size),
     "\
 Return the size of the write buffer for the memory port." },
 
   { "set-memory-port-write-buffer-size!", 2, 0, 0,
-    gdbscm_set_memory_port_write_buffer_size_x,
+    as_a_scm_t_subr (gdbscm_set_memory_port_write_buffer_size_x),
     "\
 Set the size of the write buffer for the memory port.\n\
 \n\
@@ -1300,7 +1302,7 @@ static const scheme_function private_port_functions[] =
 {
 #if 0 /* TODO */
   { "%with-gdb-input-from-port", 2, 0, 0,
-    gdbscm_percent_with_gdb_input_from_port,
+    as_a_scm_t_subr (gdbscm_percent_with_gdb_input_from_port),
     "\
 Temporarily set GDB's input port to PORT and then invoke THUNK.\n\
 \n\
@@ -1311,7 +1313,7 @@ This procedure is experimental." },
 #endif
 
   { "%with-gdb-output-to-port", 2, 0, 0,
-    gdbscm_percent_with_gdb_output_to_port,
+    as_a_scm_t_subr (gdbscm_percent_with_gdb_output_to_port),
     "\
 Temporarily set GDB's output port to PORT and then invoke THUNK.\n\
 \n\
@@ -1321,7 +1323,7 @@ Temporarily set GDB's output port to PORT and then invoke THUNK.\n\
 This procedure is experimental." },
 
   { "%with-gdb-error-to-port", 2, 0, 0,
-    gdbscm_percent_with_gdb_error_to_port,
+    as_a_scm_t_subr (gdbscm_percent_with_gdb_error_to_port),
     "\
 Temporarily set GDB's error port to PORT and then invoke THUNK.\n\
 \n\
This page took 0.032709 seconds and 4 git commands to generate.