Index: head/devel/gdb/Makefile =================================================================== --- head/devel/gdb/Makefile (revision 528337) +++ head/devel/gdb/Makefile (revision 528338) @@ -1,182 +1,181 @@ # Created by: Steven Kreuzer # $FreeBSD$ PORTNAME= gdb PORTVERSION= 9.1 CATEGORIES= devel MASTER_SITES= GNU MAINTAINER= pizzamig@FreeBSD.org COMMENT= GNU GDB of newer version than comes with the system LICENSE= GPLv3 LICENSE_FILE= ${WRKSRC}/COPYING3 # untested on sparc64, might work NOT_FOR_ARCHS= sparc64 LIB_DEPENDS= libmpfr.so:math/mpfr TEST_DEPENDS= runtest:misc/dejagnu USES= compiler:c++11-lang cpe gmake libtool makeinfo pkgconfig tar:xz USE_PYTHON= flavors py3kplist TEST_TARGET= check USE_CSTD= gnu89 CPE_VENDOR= gnu GNU_CONFIGURE= yes CONFIGURE_ENV= CONFIGURED_M4=m4 CONFIGURED_BISON=byacc CONFIGURE_ARGS= --program-suffix=${PORTVERSION:S/.//g} \ --enable-targets=all --enable-64-bit-bfd \ --with-separate-debug-dir=/usr/lib/debug \ ${ICONV_CONFIGURE_ARG} \ --with-expat=yes --with-libexpat-prefix=${LOCALBASE} \ --without-libunwind-ia64 --with-system-zlib CONFIGURE_OUTSOURCE= yes CFLAGS:= ${CFLAGS:C/ +$//} # blanks at EOL creep in sometimes CFLAGS+= -DRL_NO_COMPAT -Wno-unused-function -Wno-unused-variable CFLAGS+= -Wno-unknown-warning-option EXCLUDE= dejagnu expect sim texinfo intl EXTRACT_AFTER_ARGS= ${EXCLUDE:S/^/--exclude /} LIB_DEPENDS+= libexpat.so:textproc/expat2 VER= ${PORTVERSION:S/.//g} PLIST_SUB= VER=${VER} OPTIONS_DEFINE= DEBUG GDB_LINK GUILE KGDB NLS PYTHON SOURCE_HIGHLIGHT TUI OPTIONS_DEFAULT= GDB_LINK KGDB NLS PYTHON SOURCE_HIGHLIGHT TUI OPTIONS_DEFAULT+= PORT_READLINE PORT_ICONV SYSTEM_ZLIB OPTIONS_SINGLE= READLINE ICONV ZLIB OPTIONS_SINGLE_READLINE= BUNDLED_READLINE PORT_READLINE OPTIONS_SINGLE_ICONV= PORT_ICONV SYSTEM_ICONV OPTIONS_SINGLE_ZLIB= BUNDLED_ZLIB SYSTEM_ZLIB GDB_LINK_DESC= Create ${PREFIX}/bin/gdb symlink KGDB_DESC= Kernel Debugging Support BUNDLED_READLINE_DESC= from gdb distfile BUNDLED_ZLIB_DESC= from gdb distfile PORT_READLINE_DESC= from devel/readline port PORT_ICONV_DESC= use libiconv, with wider charset support SOURCE_HIGHLIGHT_DESC= Source Code Styling SYSTEM_ICONV_DESC= use libc iconv, with no wchar support SYSTEM_ZLIB_DESC= use system zlib TUI_DESC= Text User Interface enabled OPTIONS_SUB= yes BUNDLED_READLINE_CONFIGURE_OFF= --with-system-readline DEBUG_CFLAGS= -g GUILE_CONFIGURE_WITH= guile -GUILE_USES= pkgconfig GUILE_LIB_DEPENDS= libguile-2.2.so:lang/guile2 GUILE_EXTRA_PATCHES= ${FILESDIR}/extrapatch-guile22 NLS_USES= gettext-runtime PORT_READLINE_USES= readline:port PORT_ICONV_USES= iconv:wchar_t PYTHON_CONFIGURE_ON= --with-python=${PYTHON_CMD} PYTHON_CONFIGURE_OFF= --without-python PYTHON_USES= python SOURCE_HIGHLIGHT_WITH= source-highlight SOURCE_HIGHLIGHT_LIB_DEPENDS= \ libsource-highlight.so:textproc/source-highlight SYSTEM_ICONV_USES= iconv SYSTEM_ZLIB_WITH= system-zlib TUI_CONFIGURE_ENABLE= tui .include .if ${PORT_OPTIONS:MPYTHON} .if ${PYTHON_VER} != ${PYTHON_DEFAULT} PKGNAMESUFFIX= ${PYTHON_PKGNAMESUFFIX} .endif .endif .if ${PORT_OPTIONS:MPYTHON} && exists(/usr/lib/libc++.so.1) USE_GITHUB= nodefault GH_ACCOUNT= bsdjhb:libcxx GH_PROJECT= libcxx-gdbpy:libcxx GH_TAGNAME= 229610a:libcxx # Workaround USE_GITHUB preventing the default DISTFILES DISTFILES= ${DISTNAME}${EXTRACT_SUFX} PLIST_SUB+= LIBCXX="" .else PLIST_SUB+= LIBCXX="@comment " .endif .if ! ${PORT_OPTIONS:MBUNDLED_ZLIB} EXCLUDE+= zlib .endif .if ${ARCH} == amd64 CONFIGURE_TARGET= x86_64-portbld-freebsd${OSREL} .endif .if ${CHOSEN_COMPILER_TYPE} == clang CFLAGS+= -Wno-extended-offsetof .endif post-patch: @${REINPLACE_CMD} -e 's|$$| [GDB v${PORTVERSION} for FreeBSD]|' \ ${WRKSRC}/gdb/version.in post-patch-KGDB-on: @${CP} -r ${FILESDIR}/kgdb/*.[ch] ${WRKSRC}/gdb/ @${PATCH} -d ${PATCH_WRKSRC} ${PATCH_ARGS} < ${FILESDIR}/extrapatch-kgdb do-install: ${INSTALL_PROGRAM} ${INSTALL_WRKSRC}/gdb/gdb \ ${STAGEDIR}${PREFIX}/bin/gdb${VER} ${INSTALL_MAN} ${WRKSRC}/gdb/doc/gdb.1 \ ${STAGEDIR}${MAN1PREFIX}/man/man1/gdb${VER}.1 (cd ${INSTALL_WRKSRC}/gdb/data-directory ; \ ${SETENV} ${MAKE_ENV} ${MAKE_CMD} ${MAKE_ARGS} install-syscalls ) do-install-KGDB-on: ${INSTALL_PROGRAM} ${INSTALL_WRKSRC}/gdb/kgdb \ ${STAGEDIR}${PREFIX}/bin/kgdb${VER} ${INSTALL_MAN} ${FILESDIR}/kgdb/kgdb.1 \ ${STAGEDIR}${MAN1PREFIX}/man/man1/kgdb${VER}.1 do-install-TUI-on: ${LN} -sf gdb${VER} ${STAGEDIR}${PREFIX}/bin/gdbtui${VER} do-install-GDB_LINK-on: ${LN} -sf gdb${VER} ${STAGEDIR}${PREFIX}/bin/gdb ${LN} -sf gdb${VER}.1 ${STAGEDIR}${MAN1PREFIX}/man/man1/gdb.1 .if ${PORT_OPTIONS:MKGDB} ${LN} -sf kgdb${VER} ${STAGEDIR}${PREFIX}/bin/kgdb ${LN} -sf kgdb${VER}.1 ${STAGEDIR}${MAN1PREFIX}/man/man1/kgdb.1 .endif do-install-PYTHON-on: (cd ${INSTALL_WRKSRC}/gdb ; \ ${SETENV} ${MAKE_ENV} ${MAKE_CMD} ${MAKE_ARGS} install-python ) (cd ${INSTALL_WRKSRC}/gdb/data-directory ; \ ${SETENV} ${MAKE_ENV} ${MAKE_CMD} ${MAKE_ARGS} install-python ) @(cd ${STAGEDIR}${PREFIX}/share/gdb/python && \ ${PYTHON_CMD} -m compileall .) . for f in gdb gdb/command gdb/function gdb/printer @(cd ${STAGEDIR}${PREFIX}/share/gdb/python/${f} ; ${CHMOD} 644 *.py* ) . endfor .if exists(/usr/lib/libc++.so.1) @(cd ${WRKSRC_libcxx} ; \ ${SETENV} ${MAKE_ENV} ${MAKE} ${MAKE_ARGS} install ) @(cd ${STAGEDIR}${PREFIX}/share/gdb/auto-load/usr/lib && \ ${PYTHON_CMD} -m compileall .) @(cd ${STAGEDIR}${PREFIX}/share/libcxx-gdbpy/libcxx && \ ${PYTHON_CMD} -m compileall .) .endif do-install-GUILE-on: (cd ${INSTALL_WRKSRC}/gdb ; \ ${SETENV} ${MAKE_ENV} ${MAKE_CMD} ${MAKE_ARGS} install-guile ) (cd ${INSTALL_WRKSRC}/gdb/data-directory ; \ ${SETENV} ${MAKE_ENV} ${MAKE_CMD} ${MAKE_ARGS} install-guile ) .include Index: head/devel/gdb/files/extrapatch-guile22 =================================================================== --- head/devel/gdb/files/extrapatch-guile22 (revision 528337) +++ head/devel/gdb/files/extrapatch-guile22 (revision 528338) @@ -1,717 +1,716 @@ 2018-01-21 Doug Evans PR guile/21104 * 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. --- gdb/configure.orig 2019-06-26 13:50:46 UTC +++ gdb/configure @@ -10985,7 +10985,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) --- gdb/guile/scm-ports.c.orig 2019-05-11 18:19:03 UTC +++ 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,12 +116,19 @@ 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, which is important to us to minimize the number of inferior interactions, @@ -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,12 @@ 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); +#endif #if 0 /* TODO: Guile doesn't export this. What to do? */ scm_i_pthread_mutex_unlock (&scm_i_port_table_mutex); @@ -150,6 +177,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. */ -@@ -218,6 +262,73 @@ ioscm_input_waiting (SCM port) +@@ -218,6 +262,72 @@ ioscm_input_waiting (SCM port) } } +#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 ++ 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) ++ catch (gdbscm_gdb_exception &except) + { + GDBSCM_HANDLE_GDB_EXCEPTION (except); + } -+ END_CATCH + + return count; +} + +#else /* !PORTS_V22 */ + /* The scm_t_ptob_descriptor.fill_input "method". */ static int @@ -245,23 +356,6 @@ 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 @@ -301,6 +395,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 +405,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_desc, ioscm_input_waiting); - scm_set_port_flush (stdio_port_desc, ioscm_flush); + scm_set_port_input_waiting (stdio_port_type, ioscm_input_waiting); + +#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 +464,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 +496,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 +688,94 @@ ioscm_lseek_address (ioscm_memory_port *iomem, LONGEST 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 +1059,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 +1082,25 @@ gdbscm_memory_port_print (SCM exp, SCM port, scm_print 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 +1140,20 @@ ioscm_parse_mode_bits (const char *func_name, const ch 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,7 +1164,25 @@ ioscm_init_memory_port (SCM port, CORE_ADDR start, COR 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?'. */ pt->encoding = NULL; @@ -972,8 +1202,6 @@ ioscm_init_memory_port (SCM port, CORE_ADDR start, COR 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 +1269,8 @@ ioscm_reinit_memory_port (SCM port, size_t read_buf_si } } +#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 +1337,19 @@ gdbscm_open_memory (SCM rest) end = ~(CORE_ADDR) 0; mode_bits = ioscm_parse_mode_bits (FUNC_NAME, mode); + /* 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; - port = ioscm_open_port (memory_port_desc, mode_bits); + 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); - ioscm_init_memory_port (port, start, end); +#if !PORTS_V22 + ioscm_init_memory_port_buffers (port); +#endif scm_dynwind_end (); @@ -1123,7 +1362,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 +1386,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 +1403,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 +1419,7 @@ gdbscm_set_memory_port_read_buffer_size_x (SCM port, S 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 +1445,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 +1461,7 @@ gdbscm_set_memory_port_write_buffer_size_x (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); SCM_ASSERT_TYPE (scm_is_integer (size), size, SCM_ARG2, FUNC_NAME, _("integer")); @@ -1232,6 +1478,8 @@ gdbscm_set_memory_port_write_buffer_size_x (SCM port, return SCM_UNSPECIFIED; } + +#endif /* !PORTS_V22 */ /* Initialize gdb ports. */ @@ -1268,6 +1516,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 +1542,7 @@ Set the size of the write buffer for the memory port.\ \n\ Arguments: port integer\n\ Returns: unspecified." }, +#endif END_FUNCTIONS }; @@ -1365,9 +1615,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 }