From patchwork Tue Feb 6 18:58:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Terekhov, Mikhail via Gdb-patches" X-Patchwork-Id: 25839 Received: (qmail 4239 invoked by alias); 6 Feb 2018 18:58:54 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 4171 invoked by uid 89); 6 Feb 2018 18:58:54 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-22.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_NUMSUBJECT, RCVD_IN_DNSWL_NONE, SPF_PASS, T_RP_MATCHES_RCVD, UNSUBSCRIBE_BODY autolearn=ham version=3.3.2 spammy=redo, inclusive, rush, expectation X-HELO: mail-it0-f68.google.com Received: from mail-it0-f68.google.com (HELO mail-it0-f68.google.com) (209.85.214.68) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 06 Feb 2018 18:58:50 +0000 Received: by mail-it0-f68.google.com with SMTP id p139so3809685itb.1 for ; Tue, 06 Feb 2018 10:58:50 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to:cc; bh=hFvoKR+GRhHLaSHerSSPyet4sQ/PAYe+YPw5xOyqhdU=; b=M0lJaNFeql35K1hjuoUkPmpduod5o5WAF7nv6nALx2kusrbYWm/UYsQNmdhdjvRNmP xM/0Gb30GQDh6Q05El1MrAfcu9ieVM3QUYOpUIRP0iZsVatDZ/SQKfP+HXcQ9U+P80Xd SMrnbM2iFlbAcJ3T1IvDwEtk7/0wu9QEqU4q7ZsaY4CL2px/U0iIi4bG58WJoyD1dsLn 7rQU/+ejRVsKJH+265eUSZhhHsfOU9HtwtAW4BviYAvBlLRq5KRjMPFf+NqhrSDYAUe4 3JGdt6VT4w2uEnXC3G8KfVkvpzRLQt8PDRcjaFOd2ZFkk/mf7nizdAPlgUEb0ESImi03 N+4w== X-Gm-Message-State: APf1xPDjb3w/EYcQ57uuzYb2BckN3rQXDmJMixR/6cx5GHKLJn8j/zJ7 gGSva+SvqUgUmTSTlKTYNerpOoYILMlYqts7RIuzIpsMNMg= X-Google-Smtp-Source: AH8x2252eie5GcLTwm+2HNTVcTuior+Tk0+mNFQ3HHNrDE8wEVWHBjNtGEobtowmhDdra9wKo/0k7wZKBQ6B0vUBU/0= X-Received: by 10.36.224.141 with SMTP id c135mr4589776ith.144.1517943528193; Tue, 06 Feb 2018 10:58:48 -0800 (PST) MIME-Version: 1.0 Received: by 10.107.140.204 with HTTP; Tue, 6 Feb 2018 10:58:07 -0800 (PST) X-Patchwork-Original-From: "Doug Evans via gdb-patches" From: "Terekhov, Mikhail via Gdb-patches" Reply-To: Doug Evans Date: Tue, 6 Feb 2018 10:58:07 -0800 Message-ID: Subject: [PATCH PR guile/21104] Fix GDB build failure with Guile 2.2 To: gdb-patches Cc: guile-devel@gnu.org X-IsSubscribed: yes Guile folk. Any comments? This patch gets gdb building again with guile 2.2. Regression tested with guile 2.0.{13,14} and 2.2.3 on amd64-linux. In time I think we could delete Guile 2.0 support and that would simplify the code, but no rush. [And if someone wants to redo the 2.0 support to further reduced diffs that may be a possibility.] 2018-02-06 Doug Evans PR guile/21104 * NEWS: Mention guile 2.2 is supported again. * configure.ac: Add guile-2.2 back. * configure: Regenerate. * guile/scm-ports.c (PORTS_V22): New macro. (ioscm_memory_port) [!PORTS_V22]: Make read_buf_size,write_buf_size !PORTS_V22 only. (port_type_t): New type. (stdio_port_type): Renamed from stdio_port_desc. (stdio_port_type_name): Renamed from stdio_port_desc_name. (memory_port_type): Renamed from memory_port_desc. (memmory_port_type_name): Renamed from memory_port_desc_name. (natural_buf_size) [PORTS_V22]: New variable. (ioscm_open_port): New argument stream. All callers updated. (ioscm_read, ioscm_write) [PORTS_V22]: New functions. (ioscm_init_gdb_stdio_port) [PORTS_V22]: Adapt for use in Guile >= 2.2. (gdbscm_is_stdio_port): New function. (gdbscm_stdio_port_p): Call it. (gdbscm_get_natural_buffer_sizes, gdbscm_memory_port_seek) (gdbscm_memory_port_read, gdbscm_memory_port_write) [PORTS_V22]: New functions. (gdbscm_memory_port_print): Adapt for use in Guile >= 2.2. (ioscm_init_memory_port_type): Ditto. (ioscm_init_memory_stream): Replaces ioscm_init_memory_port. (ioscm_init_memory_port_buffers): New function. (gdbscm_open_memory): Update. (gdbscm_is_memory_port): Adapt for use in Guile >= 2.2. (port_functions) [!PORTS_V22]: Only define Guile functions memory-port-read-buffer-size, set-memory-port-read-buffer-size!, memory-port-write-buffer-size, set-memory-port-write-buffer-size! for Guile < 2.2. (gdbscm_initialize_ports): Only initialize out_of_range_buf_size if !PORTS_V22. doc/ * guile.texi (Memory Ports in Guile): Mention that these functions are only supported in Guile 2.0: memory-port-read-buffer-size, set-memory-port-read-buffer-size!, memory-port-write-buffer-size, set-memory-port-read-buffer-size!. 2018-01-21 Doug Evans PR guile/21104 * NEWS: Mention guile 2.2 is supported again. * configure.ac: Add guile-2.2 back. * configure: Regenerate. * guile/scm-ports.c (PORTS_V22): New macro. (ioscm_memory_port) [!PORTS_V22]: Make read_buf_size,write_buf_size !PORTS_V22 only. (port_type_t): New type. (stdio_port_type): Renamed from stdio_port_desc. (stdio_port_type_name): Renamed from stdio_port_desc_name. (memory_port_type): Renamed from memory_port_desc. (memmory_port_type_name): Renamed from memory_port_desc_name. (natural_buf_size) [PORTS_V22]: New variable. (ioscm_open_port): New argument stream. All callers updated. (ioscm_read, ioscm_write) [PORTS_V22]: New functions. (ioscm_init_gdb_stdio_port) [PORTS_V22]: Adapt for use in Guile >= 2.2. (gdbscm_is_stdio_port): New function. (gdbscm_stdio_port_p): Call it. (gdbscm_get_natural_buffer_sizes, gdbscm_memory_port_seek) (gdbscm_memory_port_read, gdbscm_memory_port_write) [PORTS_V22]: New functions. (gdbscm_memory_port_print): Adapt for use in Guile >= 2.2. (ioscm_init_memory_port_type): Ditto. (ioscm_init_memory_stream): Replaces ioscm_init_memory_port. (ioscm_init_memory_port_buffers): New function. (gdbscm_open_memory): Update. (gdbscm_is_memory_port): Adapt for use in Guile >= 2.2. (port_functions) [!PORTS_V22]: Only define Guile functions memory-port-read-buffer-size, set-memory-port-read-buffer-size!, memory-port-write-buffer-size, set-memory-port-write-buffer-size! for Guile < 2.2. (gdbscm_initialize_ports): Only initialize out_of_range_buf_size if !PORTS_V22. doc/ * guile.texi (Memory Ports in Guile): Mention that these functions are only supported in Guile 2.0: memory-port-read-buffer-size, set-memory-port-read-buffer-size!, memory-port-write-buffer-size, set-memory-port-read-buffer-size!. diff --git a/gdb/NEWS b/gdb/NEWS index f69173a245..324f98b217 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -3,6 +3,8 @@ *** Changes since GDB 8.1 +* Guile 2.2 support has been restored. + * 'info proc' now works on running processes on FreeBSD systems and core files created on FreeBSD systems. diff --git a/gdb/configure b/gdb/configure index a61a73f6e2..8657055ee5 100755 --- a/gdb/configure +++ b/gdb/configure @@ -10864,7 +10864,7 @@ fi -try_guile_versions="guile-2.0" +try_guile_versions="guile-2.0 guile-2.2" have_libguile=no case "${with_guile}" in no) diff --git a/gdb/configure.ac b/gdb/configure.ac index e53dda00d2..a454202146 100644 --- a/gdb/configure.ac +++ b/gdb/configure.ac @@ -1154,7 +1154,7 @@ AC_MSG_RESULT([$with_guile]) dnl We check guile with pkg-config. AC_PATH_PROG(pkg_config_prog_path, pkg-config, missing) -try_guile_versions="guile-2.0" +try_guile_versions="guile-2.0 guile-2.2" have_libguile=no case "${with_guile}" in no) diff --git a/gdb/doc/guile.texi b/gdb/doc/guile.texi index a5cfe9c435..d71fb85f31 100644 --- a/gdb/doc/guile.texi +++ b/gdb/doc/guile.texi @@ -3556,21 +3556,29 @@ inclusive. @deffn {Scheme Procedure} memory-port-read-buffer-size memory-port Return the size of the read buffer of @code{} @var{memory-port}. +This function is only available with Guile 2.0. Support for later versions +of Guile use Guile's builtin buffering and do not need this. @end deffn @deffn {Scheme Procedure} set-memory-port-read-buffer-size! memory-port size Set the size of the read buffer of @code{} @var{memory-port} to @var{size}. The result is unspecified. +This function is only available with Guile 2.0. Support for later versions +of Guile use Guile's builtin buffering and do not need this. @end deffn @deffn {Scheme Procedure} memory-port-write-buffer-size memory-port Return the size of the write buffer of @code{} @var{memory-port}. +This function is only available with Guile 2.0. Support for later versions +of Guile use Guile's builtin buffering and do not need this. @end deffn @deffn {Scheme Procedure} set-memory-port-write-buffer-size! memory-port size Set the size of the write buffer of @code{} @var{memory-port} to @var{size}. The result is unspecified. +This function is only available with Guile 2.0. Support for later versions +of Guile use Guile's builtin buffering and do not need this. @end deffn A memory port is closed like any other port, with @code{close-port}. diff --git a/gdb/guile/scm-ports.c b/gdb/guile/scm-ports.c index 26361e4a0c..01fe617641 100644 --- a/gdb/guile/scm-ports.c +++ b/gdb/guile/scm-ports.c @@ -36,6 +36,13 @@ #endif #endif +/* Guile ports radically changed in Guile 2.2. + Note: We don't support Guile < 2.0. + TODO(dje): Suggest deprecating and then removing Guile 2.0 support + at some point in the future. */ +#define PORTS_V22 (SCM_MAJOR_VERSION > 2 \ + || SCM_MAJOR_VERSION == 2 && SCM_MINOR_VERSION >= 2) + /* A ui-file for sending output to Guile. */ class ioscm_file_port : public ui_file @@ -66,12 +73,14 @@ typedef struct This value is always in the range [0, size]. */ ULONGEST current; +#if !PORTS_V22 /* The size of the internal r/w buffers. Scheme ports aren't a straightforward mapping to memory r/w. Generally the user specifies how much to r/w and all access is unbuffered. We don't try to provide equivalent access, but we allow the user to specify these values to help get something similar. */ unsigned read_buf_size, write_buf_size; +#endif } ioscm_memory_port; /* Copies of the original system input/output/error ports. @@ -80,11 +89,17 @@ static SCM orig_input_port_scm; static SCM orig_output_port_scm; static SCM orig_error_port_scm; -/* This is the stdio port descriptor, scm_ptob_descriptor. */ -static scm_t_bits stdio_port_desc; +#if PORTS_V22 +typedef scm_t_port_type *port_type_t; +#else +typedef scm_t_bits port_type_t; +#endif + +/* This is the stdio port type. */ +static port_type_t stdio_port_type; /* Note: scm_make_port_type takes a char * instead of a const char *. */ -static /*const*/ char stdio_port_desc_name[] = "gdb:stdio-port"; +static /*const*/ char stdio_port_type_name[] = "gdb:stdio-port"; /* Names of each gdb port. */ static const char input_port_name[] = "gdb:stdin"; @@ -101,11 +116,18 @@ static SCM error_port_scm; /* Internal enum for specifying output port. */ enum oport { GDB_STDOUT, GDB_STDERR }; -/* This is the memory port descriptor, scm_ptob_descriptor. */ -static scm_t_bits memory_port_desc; +/* This is the memory port type. */ +static port_type_t memory_port_type; /* Note: scm_make_port_type takes a char * instead of a const char *. */ -static /*const*/ char memory_port_desc_name[] = "gdb:memory-port"; +static /*const*/ char memory_port_type_name[] = "gdb:memory-port"; + +#if PORTS_V22 + +/* The maximum values to use for get_natural_buffer_sizes. */ +static const unsigned natural_buf_size = 16; + +#else /* The default amount of memory to fetch for each read/write request. Scheme ports don't provide a way to specify the size of a read, @@ -120,6 +142,8 @@ static const unsigned default_write_buf_size = 16; static const unsigned min_memory_port_buf_size = 1; static const unsigned max_memory_port_buf_size = 4096; +#endif + /* "out of range" error message for buf sizes. */ static char *out_of_range_buf_size; @@ -132,7 +156,7 @@ static SCM size_keyword; Newer versions of Guile (2.1.x) have scm_c_make_port. */ static SCM -ioscm_open_port (scm_t_bits port_type, long mode_bits) +ioscm_open_port (port_type_t port_type, long mode_bits, scm_t_bits stream) { SCM port; @@ -140,9 +164,13 @@ ioscm_open_port (scm_t_bits port_type, long mode_bits) scm_i_scm_pthread_mutex_lock (&scm_i_port_table_mutex); #endif +#if PORTS_V22 + port = scm_c_make_port (port_type, mode_bits, stream); +#else port = scm_new_port_table_entry (port_type); - SCM_SET_CELL_TYPE (port, port_type | mode_bits); + SCM_SETSTREAM(port, stream); +#endif #if 0 /* TODO: Guile doesn't export this. What to do? */ scm_i_pthread_mutex_unlock (&scm_i_port_table_mutex); @@ -150,6 +178,23 @@ ioscm_open_port (scm_t_bits port_type, long mode_bits) return port; } + +/* Like fputstrn_filtered, but don't escape characters, except nul. + Also like fputs_filtered, but a length is specified. */ + +static void +fputsn_filtered (const char *s, size_t size, struct ui_file *stream) +{ + size_t i; + + for (i = 0; i < size; ++i) + { + if (s[i] == '\0') + fputs_filtered ("\\000", stream); + else + fputc_filtered (s[i], stream); + } +} /* Support for connecting Guile's stdio ports to GDB's stdio ports. */ @@ -184,11 +229,10 @@ ioscm_input_waiting (SCM port) if (use_poll) { - /* Guile doesn't export SIGINT hooks like Python does. - For now pass EINTR to scm_syserror, that's what fports.c does. */ if (poll (&pollfd, 1, 0) < 0) - scm_syserror (FUNC_NAME); - + { + scm_syserror (FUNC_NAME); + } return pollfd.revents & POLLIN ? 1 : 0; } } @@ -210,14 +254,79 @@ ioscm_input_waiting (SCM port) &timeout); if (num_found < 0) { - /* Guile doesn't export SIGINT hooks like Python does. - For now pass EINTR to scm_syserror, that's what fports.c does. */ scm_syserror (FUNC_NAME); } return num_found > 0 && FD_ISSET (fdes, &input_fds); } } +#if PORTS_V22 + +static size_t +ioscm_read (SCM port, SCM dst, size_t start, size_t count) +{ + /* Borrowed from libguile/fports.c. */ + auto ptr = reinterpret_cast(SCM_BYTEVECTOR_CONTENTS (dst) + start); + ssize_t ret; + + /* If we're called on stdout,stderr, punt. */ + if (! scm_is_eq (port, input_port_scm)) + return 0; /* EOF */ + + gdb_flush (gdb_stdout); + gdb_flush (gdb_stderr); + + retry: + ret = ui_file_read (gdb_stdin, ptr, count); + if (ret < 0) + { + if (errno == EINTR) + { + scm_async_tick (); + goto retry; + } + if (errno == EWOULDBLOCK || errno == EAGAIN) + { + /* See the discussion of non-blocking I/O in the Guile manual. */ + return -1; + } + scm_syserror ("ioscm_read"); + } + return ret; +} + +static size_t +ioscm_write (SCM port, SCM src, size_t start, size_t count) +{ + /* Borrowed from libguile/fports.c. */ + auto ptr = reinterpret_cast(SCM_BYTEVECTOR_CONTENTS (src) + start); + ssize_t ret; + + /* If we're called on stdin, punt. */ + if (scm_is_eq (port, input_port_scm)) + { + errno = EIO; + scm_syserror("ioscm_write"); + } + + TRY + { + if (scm_is_eq (port, error_port_scm)) + fputsn_filtered (ptr, count, gdb_stderr); + else + fputsn_filtered (ptr, count, gdb_stdout); + } + CATCH (except, RETURN_MASK_ALL) + { + GDBSCM_HANDLE_GDB_EXCEPTION (except); + } + END_CATCH + + return count; +} + +#else /* !PORTS_V22 */ + /* The scm_t_ptob_descriptor.fill_input "method". */ static int @@ -245,29 +354,11 @@ ioscm_fill_input (SCM port) return *pt->read_buf; } -/* Like fputstrn_filtered, but don't escape characters, except nul. - Also like fputs_filtered, but a length is specified. */ - -static void -fputsn_filtered (const char *s, size_t size, struct ui_file *stream) -{ - size_t i; - - for (i = 0; i < size; ++i) - { - if (s[i] == '\0') - fputs_filtered ("\\000", stream); - else - fputc_filtered (s[i], stream); - } -} - /* Write to gdb's stdout or stderr. */ static void ioscm_write (SCM port, const void *data, size_t size) { - /* If we're called on stdin, punt. */ if (scm_is_eq (port, input_port_scm)) return; @@ -301,6 +392,8 @@ ioscm_flush (SCM port) gdb_flush (gdb_stdout); } +#endif + /* Initialize the gdb stdio port type. N.B. isatty? will fail on these ports, it is only supported for file @@ -309,13 +402,23 @@ ioscm_flush (SCM port) static void ioscm_init_gdb_stdio_port (void) { - stdio_port_desc = scm_make_port_type (stdio_port_desc_name, - ioscm_fill_input, ioscm_write); + stdio_port_type = scm_make_port_type (stdio_port_type_name, +#if PORTS_V22 + ioscm_read, +#else + ioscm_fill_input, +#endif + ioscm_write); + + scm_set_port_input_waiting (stdio_port_type, ioscm_input_waiting); - scm_set_port_input_waiting (stdio_port_desc, ioscm_input_waiting); - scm_set_port_flush (stdio_port_desc, ioscm_flush); +#if !PORTS_V22 + scm_set_port_flush (stdio_port_type, ioscm_flush); +#endif } +#if !PORTS_V22 + /* Subroutine of ioscm_make_gdb_stdio_port to simplify it. Set up the buffers of port PORT. MODE_BITS are the mode bits of PORT. */ @@ -358,6 +461,8 @@ ioscm_init_stdio_buffers (SCM port, long mode_bits) pt->write_end = pt->write_buf + pt->write_buf_size; } +#endif + /* Create a gdb stdio port. */ static SCM @@ -388,23 +493,36 @@ ioscm_make_gdb_stdio_port (int fd) } mode_bits = scm_mode_bits ((char *) mode_str); - port = ioscm_open_port (stdio_port_desc, mode_bits); + port = ioscm_open_port (stdio_port_type, mode_bits, 0); scm_set_port_filename_x (port, gdbscm_scm_from_c_string (name)); +#if !PORTS_V22 ioscm_init_stdio_buffers (port, mode_bits); +#endif return port; } +/* Return non-zero if OBJ is a stdio port. */ + +static int +gdbscm_is_stdio_port (SCM obj) +{ + /* This is copied from SCM_FPORTP. */ +#if PORTS_V22 + return SCM_PORTP (obj) && SCM_PORT_TYPE (obj) == stdio_port_type; +#else + return !SCM_IMP (obj) && SCM_TYP16 (obj) == stdio_port_type; +#endif +} + /* (stdio-port? object) -> boolean */ static SCM -gdbscm_stdio_port_p (SCM scm) +gdbscm_stdio_port_p (SCM obj) { - /* This is copied from SCM_FPORTP. */ - return scm_from_bool (!SCM_IMP (scm) - && (SCM_TYP16 (scm) == stdio_port_desc)); + return scm_from_bool (gdbscm_is_stdio_port (obj)); } /* GDB's ports are accessed via functions to keep them read-only. */ @@ -567,6 +685,94 @@ ioscm_lseek_address (ioscm_memory_port *iomem, LONGEST offset, int whence) return 1; } +#if PORTS_V22 + +/* The semantics get weird if the buffer size is larger than the port range, + so provide a better default buffer size. */ + +static void +gdbscm_get_natural_buffer_sizes (SCM port, size_t *read_size, + size_t *write_size) +{ + ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port); + + size_t size = natural_buf_size; + if (iomem->size < size) + size = iomem->size; + *read_size = *write_size = size; +} + +static scm_t_off +gdbscm_memory_port_seek (SCM port, scm_t_off offset, int whence) +{ + ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port); + scm_t_off result; + int rc; + + if (ioscm_lseek_address (iomem, offset, whence) == 0) + { + gdbscm_out_of_range_error (FUNC_NAME, 0, + gdbscm_scm_from_longest (offset), + _("bad seek")); + } + + return iomem->current; +} + +static size_t +gdbscm_memory_port_read (SCM port, SCM dst, size_t start, size_t count) +{ + /* Borrowed from libguile/fports.c. */ + auto ptr = reinterpret_cast(SCM_BYTEVECTOR_CONTENTS (dst) + start); + 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 0; /* EOF */ + + /* Don't read outside the allowed memory range. */ + to_read = count; + if (to_read > iomem->size - iomem->current) + to_read = iomem->size - iomem->current; + + if (target_read_memory (iomem->start + iomem->current, ptr, to_read) != 0) + gdbscm_memory_error (FUNC_NAME, _("error reading memory"), SCM_EOL); + + iomem->current += to_read; + return to_read; +} + +static size_t +gdbscm_memory_port_write (SCM port, SCM src, size_t start, size_t count) +{ + /* Borrowed from libguile/fports.c. */ + auto ptr = reinterpret_cast(SCM_BYTEVECTOR_CONTENTS (src) + + start); + ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port); + ssize_t ret; + + /* "current" is the offset of the first byte we want to read. */ + gdb_assert (iomem->current <= iomem->size); + + /* 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 (count > iomem->size - iomem->current) + { + gdbscm_out_of_range_error (FUNC_NAME, 0, gdbscm_scm_from_ulongest (count), + _("writing beyond end of memory range")); + } + + if (target_write_memory (iomem->start + iomem->current, ptr, count) != 0) + gdbscm_memory_error (FUNC_NAME, _("error writing memory"), SCM_EOL); + iomem->current += count; + + return count; +} + +#else /* !PORTS_V22 */ + /* "fill_input" method for memory ports. */ static int @@ -850,18 +1056,19 @@ gdbscm_memory_port_free (SCM port) return 0; } +#endif + /* "print" method for memory ports. */ 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, + gdbscm_printf (port, "%s %s-%s", memory_port_type_name, hex_string (iomem->start), hex_string (iomem->end)); scm_putc ('>', port); return 1; @@ -872,16 +1079,25 @@ gdbscm_memory_port_print (SCM exp, SCM port, scm_print_state *pstate) static void ioscm_init_memory_port_type (void) { - memory_port_desc = scm_make_port_type (memory_port_desc_name, + memory_port_type = scm_make_port_type (memory_port_type_name, +#if PORTS_V22 + gdbscm_memory_port_read, +#else gdbscm_memory_port_fill_input, +#endif gdbscm_memory_port_write); - scm_set_port_end_input (memory_port_desc, gdbscm_memory_port_end_input); - scm_set_port_flush (memory_port_desc, gdbscm_memory_port_flush); - scm_set_port_seek (memory_port_desc, gdbscm_memory_port_seek); - scm_set_port_close (memory_port_desc, gdbscm_memory_port_close); - scm_set_port_free (memory_port_desc, gdbscm_memory_port_free); - scm_set_port_print (memory_port_desc, gdbscm_memory_port_print); +#if PORTS_V22 + scm_set_port_get_natural_buffer_sizes (memory_port_type, + gdbscm_get_natural_buffer_sizes); +#else + scm_set_port_end_input (memory_port_type, gdbscm_memory_port_end_input); + scm_set_port_flush (memory_port_type, gdbscm_memory_port_flush); + scm_set_port_free (memory_port_type, gdbscm_memory_port_free); + scm_set_port_close (memory_port_type, gdbscm_memory_port_close); +#endif + scm_set_port_seek (memory_port_type, gdbscm_memory_port_seek); + scm_set_port_print (memory_port_type, gdbscm_memory_port_print); } /* Helper for gdbscm_open_memory to parse the mode bits. @@ -921,27 +1137,20 @@ ioscm_parse_mode_bits (const char *func_name, const char *mode) return mode_bits; } -/* Helper for gdbscm_open_memory to finish initializing the port. - The port has address range [start,end). - This means that address of 0xff..ff is not accessible. - I can live with that. */ - -static void -ioscm_init_memory_port (SCM port, CORE_ADDR start, CORE_ADDR end) +static scm_t_bits +ioscm_init_memory_stream (bool buffered, CORE_ADDR start, CORE_ADDR end) { - scm_t_port *pt; - ioscm_memory_port *iomem; - int buffered = (SCM_CELL_WORD_0 (port) & SCM_BUF0) == 0; + auto iomem = reinterpret_cast( + scm_gc_malloc_pointerless (sizeof (ioscm_memory_port), "memory port")); gdb_assert (start <= end); - iomem = (ioscm_memory_port *) scm_gc_malloc_pointerless (sizeof (*iomem), - "memory port"); - iomem->start = start; iomem->end = end; iomem->size = end - start; iomem->current = 0; + +#if !PORTS_V22 if (buffered) { iomem->read_buf_size = default_read_buf_size; @@ -952,6 +1161,24 @@ ioscm_init_memory_port (SCM port, CORE_ADDR start, CORE_ADDR end) iomem->read_buf_size = 1; iomem->write_buf_size = 1; } +#endif + + return reinterpret_cast(iomem); +} + +#if !PORTS_V22 + +/* Helper for gdbscm_open_memory to finish initializing the port. + The port has address range [start,end). + This means that address of 0xff..ff is not accessible. + I can live with that. */ + +static void +ioscm_init_memory_port_buffers (SCM port) +{ + scm_t_port *pt; + auto iomem = reinterpret_cast(SCM_STREAM (port)); + bool buffered = (SCM_CELL_WORD_0 (port) & SCM_BUF0) == 0; pt = SCM_PTAB_ENTRY (port); /* Match the expectation of `binary-port?'. */ @@ -972,8 +1199,6 @@ ioscm_init_memory_port (SCM port, CORE_ADDR start, CORE_ADDR end) 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; - - SCM_SETSTREAM (port, iomem); } /* Re-initialize a memory port, updating its read/write buffer sizes. @@ -1041,6 +1266,8 @@ ioscm_reinit_memory_port (SCM port, size_t read_buf_size, } } +#endif /* !PORTS_V22 */ + /* (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+". @@ -1107,10 +1334,19 @@ gdbscm_open_memory (SCM rest) end = ~(CORE_ADDR) 0; mode_bits = ioscm_parse_mode_bits (FUNC_NAME, mode); - - port = ioscm_open_port (memory_port_desc, mode_bits); - - ioscm_init_memory_port (port, start, end); + /* Edge case: empty range -> unbuffered. + There's no need to disallow empty ranges, but we need an unbuffered port + to get the semantics right. */ + if (size == 0) + mode_bits |= SCM_BUF0; + + bool buffered = (mode_bits & SCM_BUF0) == 0; + auto stream = ioscm_init_memory_stream(buffered, start, end); + port = ioscm_open_port (memory_port_type, mode_bits, stream); + +#if !PORTS_V22 + ioscm_init_memory_port_buffers (port); +#endif scm_dynwind_end (); @@ -1123,7 +1359,12 @@ gdbscm_open_memory (SCM rest) static int gdbscm_is_memory_port (SCM obj) { - return !SCM_IMP (obj) && (SCM_TYP16 (obj) == memory_port_desc); + /* This is copied from SCM_FPORTP. */ +#if PORTS_V22 + return SCM_PORTP (obj) && SCM_PORT_TYPE (obj) == memory_port_type; +#else + return !SCM_IMP (obj) && SCM_TYP16 (obj) == memory_port_type; +#endif } /* (memory-port? obj) -> boolean */ @@ -1142,13 +1383,15 @@ 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); + memory_port_type_name); iomem = (ioscm_memory_port *) SCM_STREAM (port); return scm_list_2 (gdbscm_scm_from_ulongest (iomem->start), gdbscm_scm_from_ulongest (iomem->end)); } +#if !PORTS_V22 + /* (memory-port-read-buffer-size port) -> integer */ static SCM @@ -1157,7 +1400,7 @@ gdbscm_memory_port_read_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); + memory_port_type_name); iomem = (ioscm_memory_port *) SCM_STREAM (port); return scm_from_uint (iomem->read_buf_size); @@ -1173,7 +1416,7 @@ gdbscm_set_memory_port_read_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); + memory_port_type_name); SCM_ASSERT_TYPE (scm_is_integer (size), size, SCM_ARG2, FUNC_NAME, _("integer")); @@ -1199,7 +1442,7 @@ 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); + memory_port_type_name); iomem = (ioscm_memory_port *) SCM_STREAM (port); return scm_from_uint (iomem->write_buf_size); @@ -1215,7 +1458,7 @@ 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); + memory_port_type_name); SCM_ASSERT_TYPE (scm_is_integer (size), size, SCM_ARG2, FUNC_NAME, _("integer")); @@ -1232,6 +1475,8 @@ gdbscm_set_memory_port_write_buffer_size_x (SCM port, SCM size) return SCM_UNSPECIFIED; } + +#endif /* !PORTS_V22 */ /* Initialize gdb ports. */ @@ -1268,6 +1513,7 @@ Return #t if the object is a memory port." }, "\ Return the memory range of the port as (start end)." }, +#if !PORTS_V22 { "memory-port-read-buffer-size", 1, 0, 0, as_a_scm_t_subr (gdbscm_memory_port_read_buffer_size), "\ @@ -1293,6 +1539,7 @@ Set the size of the write buffer for the memory port.\n\ \n\ Arguments: port integer\n\ Returns: unspecified." }, +#endif END_FUNCTIONS }; @@ -1365,9 +1612,11 @@ gdbscm_initialize_ports (void) start_keyword = scm_from_latin1_keyword ("start"); size_keyword = scm_from_latin1_keyword ("size"); +#if !PORTS_V22 /* Error message text for "out of range" memory port buffer sizes. */ out_of_range_buf_size = xstrprintf ("size not between %u - %u", min_memory_port_buf_size, max_memory_port_buf_size); +#endif }