]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/guile/scm-ports.c
68f2f8d0b928bdf6aa53321625c0ed59710afa60
[thirdparty/binutils-gdb.git] / gdb / guile / scm-ports.c
1 /* Support for connecting Guile's stdio to GDB's.
2 as well as r/w memory via ports.
3
4 Copyright (C) 2014-2016 Free Software Foundation, Inc.
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20
21 /* See README file in this directory for implementation notes, coding
22 conventions, et.al. */
23
24 #include "defs.h"
25 #include "gdb_select.h"
26 #include "top.h"
27 #include "target.h"
28 #include "guile-internal.h"
29
30 #ifdef HAVE_POLL
31 #if defined (HAVE_POLL_H)
32 #include <poll.h>
33 #elif defined (HAVE_SYS_POLL_H)
34 #include <sys/poll.h>
35 #endif
36 #endif
37
38 /* A ui-file for sending output to Guile. */
39
40 typedef struct
41 {
42 int *magic;
43 SCM port;
44 } ioscm_file_port;
45
46 /* Data for a memory port. */
47
48 typedef struct
49 {
50 /* Bounds of memory range this port is allowed to access: [start, end).
51 This means that 0xff..ff is not accessible. I can live with that. */
52 CORE_ADDR start, end;
53
54 /* (end - start), recorded for convenience. */
55 ULONGEST size;
56
57 /* Think of this as the lseek value maintained by the kernel.
58 This value is always in the range [0, size]. */
59 ULONGEST current;
60
61 /* The size of the internal r/w buffers.
62 Scheme ports aren't a straightforward mapping to memory r/w.
63 Generally the user specifies how much to r/w and all access is
64 unbuffered. We don't try to provide equivalent access, but we allow
65 the user to specify these values to help get something similar. */
66 unsigned read_buf_size, write_buf_size;
67 } ioscm_memory_port;
68
69 /* Copies of the original system input/output/error ports.
70 These are recorded for debugging purposes. */
71 static SCM orig_input_port_scm;
72 static SCM orig_output_port_scm;
73 static SCM orig_error_port_scm;
74
75 /* This is the stdio port descriptor, scm_ptob_descriptor. */
76 static scm_t_bits stdio_port_desc;
77
78 /* Note: scm_make_port_type takes a char * instead of a const char *. */
79 static /*const*/ char stdio_port_desc_name[] = "gdb:stdio-port";
80
81 /* Names of each gdb port. */
82 static const char input_port_name[] = "gdb:stdin";
83 static const char output_port_name[] = "gdb:stdout";
84 static const char error_port_name[] = "gdb:stderr";
85
86 /* This is the actual port used from Guile.
87 We don't expose these to the user though, to ensure they're not
88 overwritten. */
89 static SCM input_port_scm;
90 static SCM output_port_scm;
91 static SCM error_port_scm;
92
93 /* Magic number to identify port ui-files.
94 Actually, the address of this variable is the magic number. */
95 static int file_port_magic;
96
97 /* Internal enum for specifying output port. */
98 enum oport { GDB_STDOUT, GDB_STDERR };
99
100 /* This is the memory port descriptor, scm_ptob_descriptor. */
101 static scm_t_bits memory_port_desc;
102
103 /* Note: scm_make_port_type takes a char * instead of a const char *. */
104 static /*const*/ char memory_port_desc_name[] = "gdb:memory-port";
105
106 /* The default amount of memory to fetch for each read/write request.
107 Scheme ports don't provide a way to specify the size of a read,
108 which is important to us to minimize the number of inferior interactions,
109 which over a remote link can be important. To compensate we augment the
110 port API with a new function that let's the user specify how much the next
111 read request should fetch. This is the initial value for each new port. */
112 static const unsigned default_read_buf_size = 16;
113 static const unsigned default_write_buf_size = 16;
114
115 /* Arbitrarily limit memory port buffers to 1 byte to 4K. */
116 static const unsigned min_memory_port_buf_size = 1;
117 static const unsigned max_memory_port_buf_size = 4096;
118
119 /* "out of range" error message for buf sizes. */
120 static char *out_of_range_buf_size;
121
122 /* Keywords used by open-memory. */
123 static SCM mode_keyword;
124 static SCM start_keyword;
125 static SCM size_keyword;
126 \f
127 /* Helper to do the low level work of opening a port.
128 Newer versions of Guile (2.1.x) have scm_c_make_port. */
129
130 static SCM
131 ioscm_open_port (scm_t_bits port_type, long mode_bits)
132 {
133 SCM port;
134
135 #if 0 /* TODO: Guile doesn't export this. What to do? */
136 scm_i_scm_pthread_mutex_lock (&scm_i_port_table_mutex);
137 #endif
138
139 port = scm_new_port_table_entry (port_type);
140
141 SCM_SET_CELL_TYPE (port, port_type | mode_bits);
142
143 #if 0 /* TODO: Guile doesn't export this. What to do? */
144 scm_i_pthread_mutex_unlock (&scm_i_port_table_mutex);
145 #endif
146
147 return port;
148 }
149 \f
150 /* Support for connecting Guile's stdio ports to GDB's stdio ports. */
151
152 /* The scm_t_ptob_descriptor.input_waiting "method".
153 Return a lower bound on the number of bytes available for input. */
154
155 static int
156 ioscm_input_waiting (SCM port)
157 {
158 int fdes = 0;
159
160 if (! scm_is_eq (port, input_port_scm))
161 return 0;
162
163 #ifdef HAVE_POLL
164 {
165 /* This is copied from libguile/fports.c. */
166 struct pollfd pollfd = { fdes, POLLIN, 0 };
167 static int use_poll = -1;
168
169 if (use_poll < 0)
170 {
171 /* This is copied from event-loop.c: poll cannot be used for stdin on
172 m68k-motorola-sysv. */
173 struct pollfd test_pollfd = { fdes, POLLIN, 0 };
174
175 if (poll (&test_pollfd, 1, 0) == 1 && (test_pollfd.revents & POLLNVAL))
176 use_poll = 0;
177 else
178 use_poll = 1;
179 }
180
181 if (use_poll)
182 {
183 /* Guile doesn't export SIGINT hooks like Python does.
184 For now pass EINTR to scm_syserror, that's what fports.c does. */
185 if (poll (&pollfd, 1, 0) < 0)
186 scm_syserror (FUNC_NAME);
187
188 return pollfd.revents & POLLIN ? 1 : 0;
189 }
190 }
191 /* Fall through. */
192 #endif
193
194 {
195 struct timeval timeout;
196 fd_set input_fds;
197 int num_fds = fdes + 1;
198 int num_found;
199
200 memset (&timeout, 0, sizeof (timeout));
201 FD_ZERO (&input_fds);
202 FD_SET (fdes, &input_fds);
203
204 num_found = interruptible_select (num_fds,
205 &input_fds, NULL, NULL,
206 &timeout);
207 if (num_found < 0)
208 {
209 /* Guile doesn't export SIGINT hooks like Python does.
210 For now pass EINTR to scm_syserror, that's what fports.c does. */
211 scm_syserror (FUNC_NAME);
212 }
213 return num_found > 0 && FD_ISSET (fdes, &input_fds);
214 }
215 }
216
217 /* The scm_t_ptob_descriptor.fill_input "method". */
218
219 static int
220 ioscm_fill_input (SCM port)
221 {
222 /* Borrowed from libguile/fports.c. */
223 long count;
224 scm_t_port *pt = SCM_PTAB_ENTRY (port);
225
226 /* If we're called on stdout,stderr, punt. */
227 if (! scm_is_eq (port, input_port_scm))
228 return (scm_t_wchar) EOF; /* Set errno and return -1? */
229
230 gdb_flush (gdb_stdout);
231 gdb_flush (gdb_stderr);
232
233 count = ui_file_read (gdb_stdin, (char *) pt->read_buf, pt->read_buf_size);
234 if (count == -1)
235 scm_syserror (FUNC_NAME);
236 if (count == 0)
237 return (scm_t_wchar) EOF;
238
239 pt->read_pos = pt->read_buf;
240 pt->read_end = pt->read_buf + count;
241 return *pt->read_buf;
242 }
243
244 /* Like fputstrn_filtered, but don't escape characters, except nul.
245 Also like fputs_filtered, but a length is specified. */
246
247 static void
248 fputsn_filtered (const char *s, size_t size, struct ui_file *stream)
249 {
250 size_t i;
251
252 for (i = 0; i < size; ++i)
253 {
254 if (s[i] == '\0')
255 fputs_filtered ("\\000", stream);
256 else
257 fputc_filtered (s[i], stream);
258 }
259 }
260
261 /* Write to gdb's stdout or stderr. */
262
263 static void
264 ioscm_write (SCM port, const void *data, size_t size)
265 {
266
267 /* If we're called on stdin, punt. */
268 if (scm_is_eq (port, input_port_scm))
269 return;
270
271 TRY
272 {
273 if (scm_is_eq (port, error_port_scm))
274 fputsn_filtered ((const char *) data, size, gdb_stderr);
275 else
276 fputsn_filtered ((const char *) data, size, gdb_stdout);
277 }
278 CATCH (except, RETURN_MASK_ALL)
279 {
280 GDBSCM_HANDLE_GDB_EXCEPTION (except);
281 }
282 END_CATCH
283 }
284
285 /* Flush gdb's stdout or stderr. */
286
287 static void
288 ioscm_flush (SCM port)
289 {
290 /* If we're called on stdin, punt. */
291 if (scm_is_eq (port, input_port_scm))
292 return;
293
294 if (scm_is_eq (port, error_port_scm))
295 gdb_flush (gdb_stderr);
296 else
297 gdb_flush (gdb_stdout);
298 }
299
300 /* Initialize the gdb stdio port type.
301
302 N.B. isatty? will fail on these ports, it is only supported for file
303 ports. IWBN if we could "subclass" file ports. */
304
305 static void
306 ioscm_init_gdb_stdio_port (void)
307 {
308 stdio_port_desc = scm_make_port_type (stdio_port_desc_name,
309 ioscm_fill_input, ioscm_write);
310
311 scm_set_port_input_waiting (stdio_port_desc, ioscm_input_waiting);
312 scm_set_port_flush (stdio_port_desc, ioscm_flush);
313 }
314
315 /* Subroutine of ioscm_make_gdb_stdio_port to simplify it.
316 Set up the buffers of port PORT.
317 MODE_BITS are the mode bits of PORT. */
318
319 static void
320 ioscm_init_stdio_buffers (SCM port, long mode_bits)
321 {
322 scm_t_port *pt = SCM_PTAB_ENTRY (port);
323 #define GDB_STDIO_BUFFER_DEFAULT_SIZE 1024
324 int size = mode_bits & SCM_BUF0 ? 0 : GDB_STDIO_BUFFER_DEFAULT_SIZE;
325 int writing = (mode_bits & SCM_WRTNG) != 0;
326
327 /* This is heavily copied from scm_fport_buffer_add. */
328
329 if (!writing && size > 0)
330 {
331 pt->read_buf
332 = (unsigned char *) scm_gc_malloc_pointerless (size, "port buffer");
333 pt->read_pos = pt->read_end = pt->read_buf;
334 pt->read_buf_size = size;
335 }
336 else
337 {
338 pt->read_pos = pt->read_buf = pt->read_end = &pt->shortbuf;
339 pt->read_buf_size = 1;
340 }
341
342 if (writing && size > 0)
343 {
344 pt->write_buf
345 = (unsigned char *) scm_gc_malloc_pointerless (size, "port buffer");
346 pt->write_pos = pt->write_buf;
347 pt->write_buf_size = size;
348 }
349 else
350 {
351 pt->write_buf = pt->write_pos = &pt->shortbuf;
352 pt->write_buf_size = 1;
353 }
354 pt->write_end = pt->write_buf + pt->write_buf_size;
355 }
356
357 /* Create a gdb stdio port. */
358
359 static SCM
360 ioscm_make_gdb_stdio_port (int fd)
361 {
362 int is_a_tty = isatty (fd);
363 const char *name;
364 const char *mode_str;
365 long mode_bits;
366 SCM port;
367
368 switch (fd)
369 {
370 case 0:
371 name = input_port_name;
372 mode_str = is_a_tty ? "r0" : "r";
373 break;
374 case 1:
375 name = output_port_name;
376 mode_str = is_a_tty ? "w0" : "w";
377 break;
378 case 2:
379 name = error_port_name;
380 mode_str = is_a_tty ? "w0" : "w";
381 break;
382 default:
383 gdb_assert_not_reached ("bad stdio file descriptor");
384 }
385
386 mode_bits = scm_mode_bits ((char *) mode_str);
387 port = ioscm_open_port (stdio_port_desc, mode_bits);
388
389 scm_set_port_filename_x (port, gdbscm_scm_from_c_string (name));
390
391 ioscm_init_stdio_buffers (port, mode_bits);
392
393 return port;
394 }
395
396 /* (stdio-port? object) -> boolean */
397
398 static SCM
399 gdbscm_stdio_port_p (SCM scm)
400 {
401 /* This is copied from SCM_FPORTP. */
402 return scm_from_bool (!SCM_IMP (scm)
403 && (SCM_TYP16 (scm) == stdio_port_desc));
404 }
405 \f
406 /* GDB's ports are accessed via functions to keep them read-only. */
407
408 /* (input-port) -> port */
409
410 static SCM
411 gdbscm_input_port (void)
412 {
413 return input_port_scm;
414 }
415
416 /* (output-port) -> port */
417
418 static SCM
419 gdbscm_output_port (void)
420 {
421 return output_port_scm;
422 }
423
424 /* (error-port) -> port */
425
426 static SCM
427 gdbscm_error_port (void)
428 {
429 return error_port_scm;
430 }
431 \f
432 /* Support for sending GDB I/O to Guile ports. */
433
434 static void
435 ioscm_file_port_delete (struct ui_file *file)
436 {
437 ioscm_file_port *stream = (ioscm_file_port *) ui_file_data (file);
438
439 if (stream->magic != &file_port_magic)
440 internal_error (__FILE__, __LINE__,
441 _("ioscm_file_port_delete: bad magic number"));
442 xfree (stream);
443 }
444
445 static void
446 ioscm_file_port_rewind (struct ui_file *file)
447 {
448 ioscm_file_port *stream = (ioscm_file_port *) ui_file_data (file);
449
450 if (stream->magic != &file_port_magic)
451 internal_error (__FILE__, __LINE__,
452 _("ioscm_file_port_rewind: bad magic number"));
453
454 scm_truncate_file (stream->port, 0);
455 }
456
457 static void
458 ioscm_file_port_put (struct ui_file *file,
459 ui_file_put_method_ftype *write,
460 void *dest)
461 {
462 ioscm_file_port *stream = (ioscm_file_port *) ui_file_data (file);
463
464 if (stream->magic != &file_port_magic)
465 internal_error (__FILE__, __LINE__,
466 _("ioscm_file_port_put: bad magic number"));
467
468 /* This function doesn't meld with ports very well. */
469 }
470
471 static void
472 ioscm_file_port_write (struct ui_file *file,
473 const char *buffer,
474 long length_buffer)
475 {
476 ioscm_file_port *stream = (ioscm_file_port *) ui_file_data (file);
477
478 if (stream->magic != &file_port_magic)
479 internal_error (__FILE__, __LINE__,
480 _("ioscm_pot_file_write: bad magic number"));
481
482 scm_c_write (stream->port, buffer, length_buffer);
483 }
484
485 /* Return a ui_file that writes to PORT. */
486
487 static struct ui_file *
488 ioscm_file_port_new (SCM port)
489 {
490 ioscm_file_port *stream = XCNEW (ioscm_file_port);
491 struct ui_file *file = ui_file_new ();
492
493 set_ui_file_data (file, stream, ioscm_file_port_delete);
494 set_ui_file_rewind (file, ioscm_file_port_rewind);
495 set_ui_file_put (file, ioscm_file_port_put);
496 set_ui_file_write (file, ioscm_file_port_write);
497 stream->magic = &file_port_magic;
498 stream->port = port;
499
500 return file;
501 }
502 \f
503 /* Helper routine for with-{output,error}-to-port. */
504
505 static SCM
506 ioscm_with_output_to_port_worker (SCM port, SCM thunk, enum oport oport,
507 const char *func_name)
508 {
509 struct ui_file *port_file;
510 struct cleanup *cleanups;
511 SCM result;
512
513 SCM_ASSERT_TYPE (gdbscm_is_true (scm_output_port_p (port)), port,
514 SCM_ARG1, func_name, _("output port"));
515 SCM_ASSERT_TYPE (gdbscm_is_true (scm_thunk_p (thunk)), thunk,
516 SCM_ARG2, func_name, _("thunk"));
517
518 cleanups = set_batch_flag_and_make_cleanup_restore_page_info ();
519
520 make_cleanup_restore_integer (&current_ui->async);
521 current_ui->async = 0;
522
523 port_file = ioscm_file_port_new (port);
524
525 make_cleanup_ui_file_delete (port_file);
526
527 scoped_restore save_file = make_scoped_restore (oport == GDB_STDERR
528 ? &gdb_stderr : &gdb_stdout);
529
530 if (oport == GDB_STDERR)
531 gdb_stderr = port_file;
532 else
533 {
534 if (current_uiout->redirect (port_file) < 0)
535 warning (_("Current output protocol does not support redirection"));
536 else
537 make_cleanup_ui_out_redirect_pop (current_uiout);
538
539 gdb_stdout = port_file;
540 }
541
542 result = gdbscm_safe_call_0 (thunk, NULL);
543
544 do_cleanups (cleanups);
545
546 if (gdbscm_is_exception (result))
547 gdbscm_throw (result);
548
549 return result;
550 }
551
552 /* (%with-gdb-output-to-port port thunk) -> object
553 This function is experimental.
554 IWBN to not include "gdb" in the name, but it would collide with a standard
555 procedure, and it's common to import the gdb module without a prefix.
556 There are ways around this, but they're more cumbersome.
557
558 This has % in the name because it's experimental, and we want the
559 user-visible version to come from module (gdb experimental). */
560
561 static SCM
562 gdbscm_percent_with_gdb_output_to_port (SCM port, SCM thunk)
563 {
564 return ioscm_with_output_to_port_worker (port, thunk, GDB_STDOUT, FUNC_NAME);
565 }
566
567 /* (%with-gdb-error-to-port port thunk) -> object
568 This function is experimental.
569 IWBN to not include "gdb" in the name, but it would collide with a standard
570 procedure, and it's common to import the gdb module without a prefix.
571 There are ways around this, but they're more cumbersome.
572
573 This has % in the name because it's experimental, and we want the
574 user-visible version to come from module (gdb experimental). */
575
576 static SCM
577 gdbscm_percent_with_gdb_error_to_port (SCM port, SCM thunk)
578 {
579 return ioscm_with_output_to_port_worker (port, thunk, GDB_STDERR, FUNC_NAME);
580 }
581 \f
582 /* Support for r/w memory via ports. */
583
584 /* Perform an "lseek" to OFFSET,WHENCE on memory port IOMEM.
585 OFFSET must be in the range [0,size].
586 The result is non-zero for success, zero for failure. */
587
588 static int
589 ioscm_lseek_address (ioscm_memory_port *iomem, LONGEST offset, int whence)
590 {
591 CORE_ADDR new_current;
592
593 gdb_assert (iomem->current <= iomem->size);
594
595 switch (whence)
596 {
597 case SEEK_CUR:
598 /* Catch over/underflow. */
599 if ((offset < 0 && iomem->current + offset > iomem->current)
600 || (offset > 0 && iomem->current + offset < iomem->current))
601 return 0;
602 new_current = iomem->current + offset;
603 break;
604 case SEEK_SET:
605 new_current = offset;
606 break;
607 case SEEK_END:
608 if (offset == 0)
609 {
610 new_current = iomem->size;
611 break;
612 }
613 /* TODO: Not supported yet. */
614 return 0;
615 default:
616 return 0;
617 }
618
619 if (new_current > iomem->size)
620 return 0;
621 iomem->current = new_current;
622 return 1;
623 }
624
625 /* "fill_input" method for memory ports. */
626
627 static int
628 gdbscm_memory_port_fill_input (SCM port)
629 {
630 scm_t_port *pt = SCM_PTAB_ENTRY (port);
631 ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
632 size_t to_read;
633
634 /* "current" is the offset of the first byte we want to read. */
635 gdb_assert (iomem->current <= iomem->size);
636 if (iomem->current == iomem->size)
637 return EOF;
638
639 /* Don't read outside the allowed memory range. */
640 to_read = pt->read_buf_size;
641 if (to_read > iomem->size - iomem->current)
642 to_read = iomem->size - iomem->current;
643
644 if (target_read_memory (iomem->start + iomem->current, pt->read_buf,
645 to_read) != 0)
646 gdbscm_memory_error (FUNC_NAME, _("error reading memory"), SCM_EOL);
647
648 iomem->current += to_read;
649 pt->read_pos = pt->read_buf;
650 pt->read_end = pt->read_buf + to_read;
651 return *pt->read_buf;
652 }
653
654 /* "end_input" method for memory ports.
655 Clear the read buffer and adjust the file position for unread bytes. */
656
657 static void
658 gdbscm_memory_port_end_input (SCM port, int offset)
659 {
660 scm_t_port *pt = SCM_PTAB_ENTRY (port);
661 ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
662 size_t remaining = pt->read_end - pt->read_pos;
663
664 /* Note: Use of "int offset" is specified by Guile ports API. */
665 if ((offset < 0 && remaining + offset > remaining)
666 || (offset > 0 && remaining + offset < remaining))
667 {
668 gdbscm_out_of_range_error (FUNC_NAME, 0, scm_from_int (offset),
669 _("overflow in offset calculation"));
670 }
671 offset += remaining;
672
673 if (offset > 0)
674 {
675 pt->read_pos = pt->read_end;
676 /* Throw error if unread-char used at beginning of file
677 then attempting to write. Seems correct. */
678 if (!ioscm_lseek_address (iomem, -offset, SEEK_CUR))
679 {
680 gdbscm_out_of_range_error (FUNC_NAME, 0, scm_from_int (offset),
681 _("bad offset"));
682 }
683 }
684
685 pt->rw_active = SCM_PORT_NEITHER;
686 }
687
688 /* "flush" method for memory ports. */
689
690 static void
691 gdbscm_memory_port_flush (SCM port)
692 {
693 scm_t_port *pt = SCM_PTAB_ENTRY (port);
694 ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
695 size_t to_write = pt->write_pos - pt->write_buf;
696
697 if (to_write == 0)
698 return;
699
700 /* There's no way to indicate a short write, so if the request goes past
701 the end of the port's memory range, flag an error. */
702 if (to_write > iomem->size - iomem->current)
703 {
704 gdbscm_out_of_range_error (FUNC_NAME, 0,
705 gdbscm_scm_from_ulongest (to_write),
706 _("writing beyond end of memory range"));
707 }
708
709 if (target_write_memory (iomem->start + iomem->current, pt->write_buf,
710 to_write) != 0)
711 gdbscm_memory_error (FUNC_NAME, _("error writing memory"), SCM_EOL);
712
713 iomem->current += to_write;
714 pt->write_pos = pt->write_buf;
715 pt->rw_active = SCM_PORT_NEITHER;
716 }
717
718 /* "write" method for memory ports. */
719
720 static void
721 gdbscm_memory_port_write (SCM port, const void *void_data, size_t size)
722 {
723 scm_t_port *pt = SCM_PTAB_ENTRY (port);
724 ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
725 const gdb_byte *data = (const gdb_byte *) void_data;
726
727 /* There's no way to indicate a short write, so if the request goes past
728 the end of the port's memory range, flag an error. */
729 if (size > iomem->size - iomem->current)
730 {
731 gdbscm_out_of_range_error (FUNC_NAME, 0, gdbscm_scm_from_ulongest (size),
732 _("writing beyond end of memory range"));
733 }
734
735 if (pt->write_buf == &pt->shortbuf)
736 {
737 /* Unbuffered port. */
738 if (target_write_memory (iomem->start + iomem->current, data, size) != 0)
739 gdbscm_memory_error (FUNC_NAME, _("error writing memory"), SCM_EOL);
740 iomem->current += size;
741 return;
742 }
743
744 /* Note: The edge case of what to do when the buffer exactly fills is
745 debatable. Guile flushes when the buffer exactly fills up, so we
746 do too. It's counter-intuitive to my mind, but in case there's a
747 subtlety somewhere that depends on this, we do the same. */
748
749 {
750 size_t space = pt->write_end - pt->write_pos;
751
752 if (size < space)
753 {
754 /* Data fits in buffer, and does not fill it. */
755 memcpy (pt->write_pos, data, size);
756 pt->write_pos += size;
757 }
758 else
759 {
760 memcpy (pt->write_pos, data, space);
761 pt->write_pos = pt->write_end;
762 gdbscm_memory_port_flush (port);
763 {
764 const gdb_byte *ptr = data + space;
765 size_t remaining = size - space;
766
767 if (remaining >= pt->write_buf_size)
768 {
769 if (target_write_memory (iomem->start + iomem->current, ptr,
770 remaining) != 0)
771 gdbscm_memory_error (FUNC_NAME, _("error writing memory"),
772 SCM_EOL);
773 iomem->current += remaining;
774 }
775 else
776 {
777 memcpy (pt->write_pos, ptr, remaining);
778 pt->write_pos += remaining;
779 }
780 }
781 }
782 }
783 }
784
785 /* "seek" method for memory ports. */
786
787 static scm_t_off
788 gdbscm_memory_port_seek (SCM port, scm_t_off offset, int whence)
789 {
790 scm_t_port *pt = SCM_PTAB_ENTRY (port);
791 ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
792 CORE_ADDR result;
793 int rc;
794
795 if (pt->rw_active == SCM_PORT_WRITE)
796 {
797 if (offset != 0 || whence != SEEK_CUR)
798 {
799 gdbscm_memory_port_flush (port);
800 rc = ioscm_lseek_address (iomem, offset, whence);
801 result = iomem->current;
802 }
803 else
804 {
805 /* Read current position without disturbing the buffer,
806 but flag an error if what's in the buffer goes outside the
807 allowed range. */
808 CORE_ADDR current = iomem->current;
809 size_t delta = pt->write_pos - pt->write_buf;
810
811 if (current + delta < current
812 || current + delta > iomem->size)
813 rc = 0;
814 else
815 {
816 result = current + delta;
817 rc = 1;
818 }
819 }
820 }
821 else if (pt->rw_active == SCM_PORT_READ)
822 {
823 if (offset != 0 || whence != SEEK_CUR)
824 {
825 scm_end_input (port);
826 rc = ioscm_lseek_address (iomem, offset, whence);
827 result = iomem->current;
828 }
829 else
830 {
831 /* Read current position without disturbing the buffer
832 (particularly the unread-char buffer). */
833 CORE_ADDR current = iomem->current;
834 size_t remaining = pt->read_end - pt->read_pos;
835
836 if (current - remaining > current
837 || current - remaining < iomem->start)
838 rc = 0;
839 else
840 {
841 result = current - remaining;
842 rc = 1;
843 }
844
845 if (rc != 0 && pt->read_buf == pt->putback_buf)
846 {
847 size_t saved_remaining = pt->saved_read_end - pt->saved_read_pos;
848
849 if (result - saved_remaining > result
850 || result - saved_remaining < iomem->start)
851 rc = 0;
852 else
853 result -= saved_remaining;
854 }
855 }
856 }
857 else /* SCM_PORT_NEITHER */
858 {
859 rc = ioscm_lseek_address (iomem, offset, whence);
860 result = iomem->current;
861 }
862
863 if (rc == 0)
864 {
865 gdbscm_out_of_range_error (FUNC_NAME, 0,
866 gdbscm_scm_from_longest (offset),
867 _("bad seek"));
868 }
869
870 /* TODO: The Guile API doesn't support 32x64. We can't fix that here,
871 and there's no need to throw an error if the new address can't be
872 represented in a scm_t_off. But we could return something less
873 clumsy. */
874 return result;
875 }
876
877 /* "close" method for memory ports. */
878
879 static int
880 gdbscm_memory_port_close (SCM port)
881 {
882 scm_t_port *pt = SCM_PTAB_ENTRY (port);
883 ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
884
885 gdbscm_memory_port_flush (port);
886
887 if (pt->read_buf == pt->putback_buf)
888 pt->read_buf = pt->saved_read_buf;
889 if (pt->read_buf != &pt->shortbuf)
890 xfree (pt->read_buf);
891 if (pt->write_buf != &pt->shortbuf)
892 xfree (pt->write_buf);
893 scm_gc_free (iomem, sizeof (*iomem), "memory port");
894
895 return 0;
896 }
897
898 /* "free" method for memory ports. */
899
900 static size_t
901 gdbscm_memory_port_free (SCM port)
902 {
903 gdbscm_memory_port_close (port);
904
905 return 0;
906 }
907
908 /* "print" method for memory ports. */
909
910 static int
911 gdbscm_memory_port_print (SCM exp, SCM port, scm_print_state *pstate)
912 {
913 ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (exp);
914 char *type = SCM_PTOBNAME (SCM_PTOBNUM (exp));
915
916 scm_puts ("#<", port);
917 scm_print_port_mode (exp, port);
918 /* scm_print_port_mode includes a trailing space. */
919 gdbscm_printf (port, "%s %s-%s", type,
920 hex_string (iomem->start), hex_string (iomem->end));
921 scm_putc ('>', port);
922 return 1;
923 }
924
925 /* Create the port type used for memory. */
926
927 static void
928 ioscm_init_memory_port_type (void)
929 {
930 memory_port_desc = scm_make_port_type (memory_port_desc_name,
931 gdbscm_memory_port_fill_input,
932 gdbscm_memory_port_write);
933
934 scm_set_port_end_input (memory_port_desc, gdbscm_memory_port_end_input);
935 scm_set_port_flush (memory_port_desc, gdbscm_memory_port_flush);
936 scm_set_port_seek (memory_port_desc, gdbscm_memory_port_seek);
937 scm_set_port_close (memory_port_desc, gdbscm_memory_port_close);
938 scm_set_port_free (memory_port_desc, gdbscm_memory_port_free);
939 scm_set_port_print (memory_port_desc, gdbscm_memory_port_print);
940 }
941
942 /* Helper for gdbscm_open_memory to parse the mode bits.
943 An exception is thrown if MODE is invalid. */
944
945 static long
946 ioscm_parse_mode_bits (const char *func_name, const char *mode)
947 {
948 const char *p;
949 long mode_bits;
950
951 if (*mode != 'r' && *mode != 'w')
952 {
953 gdbscm_out_of_range_error (func_name, 0,
954 gdbscm_scm_from_c_string (mode),
955 _("bad mode string"));
956 }
957 for (p = mode + 1; *p != '\0'; ++p)
958 {
959 switch (*p)
960 {
961 case '0':
962 case 'b':
963 case '+':
964 break;
965 default:
966 gdbscm_out_of_range_error (func_name, 0,
967 gdbscm_scm_from_c_string (mode),
968 _("bad mode string"));
969 }
970 }
971
972 /* Kinda awkward to convert the mode from SCM -> string only to have Guile
973 convert it back to SCM, but that's the API we have to work with. */
974 mode_bits = scm_mode_bits ((char *) mode);
975
976 return mode_bits;
977 }
978
979 /* Helper for gdbscm_open_memory to finish initializing the port.
980 The port has address range [start,end).
981 This means that address of 0xff..ff is not accessible.
982 I can live with that. */
983
984 static void
985 ioscm_init_memory_port (SCM port, CORE_ADDR start, CORE_ADDR end)
986 {
987 scm_t_port *pt;
988 ioscm_memory_port *iomem;
989 int buffered = (SCM_CELL_WORD_0 (port) & SCM_BUF0) == 0;
990
991 gdb_assert (start <= end);
992
993 iomem = (ioscm_memory_port *) scm_gc_malloc_pointerless (sizeof (*iomem),
994 "memory port");
995
996 iomem->start = start;
997 iomem->end = end;
998 iomem->size = end - start;
999 iomem->current = 0;
1000 if (buffered)
1001 {
1002 iomem->read_buf_size = default_read_buf_size;
1003 iomem->write_buf_size = default_write_buf_size;
1004 }
1005 else
1006 {
1007 iomem->read_buf_size = 1;
1008 iomem->write_buf_size = 1;
1009 }
1010
1011 pt = SCM_PTAB_ENTRY (port);
1012 /* Match the expectation of `binary-port?'. */
1013 pt->encoding = NULL;
1014 pt->rw_random = 1;
1015 pt->read_buf_size = iomem->read_buf_size;
1016 pt->write_buf_size = iomem->write_buf_size;
1017 if (buffered)
1018 {
1019 pt->read_buf = (unsigned char *) xmalloc (pt->read_buf_size);
1020 pt->write_buf = (unsigned char *) xmalloc (pt->write_buf_size);
1021 }
1022 else
1023 {
1024 pt->read_buf = &pt->shortbuf;
1025 pt->write_buf = &pt->shortbuf;
1026 }
1027 pt->read_pos = pt->read_end = pt->read_buf;
1028 pt->write_pos = pt->write_buf;
1029 pt->write_end = pt->write_buf + pt->write_buf_size;
1030
1031 SCM_SETSTREAM (port, iomem);
1032 }
1033
1034 /* Re-initialize a memory port, updating its read/write buffer sizes.
1035 An exception is thrown if the port is unbuffered.
1036 TODO: Allow switching buffered/unbuffered.
1037 An exception is also thrown if data is still buffered, except in the case
1038 where the buffer size isn't changing (since that's just a nop). */
1039
1040 static void
1041 ioscm_reinit_memory_port (SCM port, size_t read_buf_size,
1042 size_t write_buf_size, const char *func_name)
1043 {
1044 scm_t_port *pt = SCM_PTAB_ENTRY (port);
1045 ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
1046
1047 gdb_assert (read_buf_size >= min_memory_port_buf_size
1048 && read_buf_size <= max_memory_port_buf_size);
1049 gdb_assert (write_buf_size >= min_memory_port_buf_size
1050 && write_buf_size <= max_memory_port_buf_size);
1051
1052 /* First check if the port is unbuffered. */
1053
1054 if (pt->read_buf == &pt->shortbuf)
1055 {
1056 gdb_assert (pt->write_buf == &pt->shortbuf);
1057 scm_misc_error (func_name, _("port is unbuffered: ~a"),
1058 scm_list_1 (port));
1059 }
1060
1061 /* Next check if anything is buffered. */
1062
1063 if (read_buf_size != pt->read_buf_size
1064 && pt->read_end != pt->read_buf)
1065 {
1066 scm_misc_error (func_name, _("read buffer not empty: ~a"),
1067 scm_list_1 (port));
1068 }
1069
1070 if (write_buf_size != pt->write_buf_size
1071 && pt->write_pos != pt->write_buf)
1072 {
1073 scm_misc_error (func_name, _("write buffer not empty: ~a"),
1074 scm_list_1 (port));
1075 }
1076
1077 /* Now we can update the buffer sizes, but only if the size has changed. */
1078
1079 if (read_buf_size != pt->read_buf_size)
1080 {
1081 iomem->read_buf_size = read_buf_size;
1082 pt->read_buf_size = read_buf_size;
1083 xfree (pt->read_buf);
1084 pt->read_buf = (unsigned char *) xmalloc (pt->read_buf_size);
1085 pt->read_pos = pt->read_end = pt->read_buf;
1086 }
1087
1088 if (write_buf_size != pt->write_buf_size)
1089 {
1090 iomem->write_buf_size = write_buf_size;
1091 pt->write_buf_size = write_buf_size;
1092 xfree (pt->write_buf);
1093 pt->write_buf = (unsigned char *) xmalloc (pt->write_buf_size);
1094 pt->write_pos = pt->write_buf;
1095 pt->write_end = pt->write_buf + pt->write_buf_size;
1096 }
1097 }
1098
1099 /* (open-memory [#:mode string] [#:start address] [#:size integer]) -> port
1100 Return a port that can be used for reading and writing memory.
1101 MODE is a string, and must be one of "r", "w", or "r+".
1102 "0" may be appended to MODE to mark the port as unbuffered.
1103 For compatibility "b" (binary) may also be appended, but we ignore it:
1104 memory ports are binary only.
1105
1106 The chunk of memory that can be accessed can be bounded.
1107 If both START,SIZE are unspecified, all of memory can be accessed
1108 (except 0xff..ff). If only START is specified, all of memory from that
1109 point on can be accessed (except 0xff..ff). If only SIZE if specified,
1110 all memory in [0,SIZE) can be accessed. If both are specified, all memory
1111 in [START,START+SIZE) can be accessed.
1112
1113 Note: If it becomes useful enough we can later add #:end as an alternative
1114 to #:size. For now it is left out.
1115
1116 The result is a Scheme port, and its semantics are a bit odd for accessing
1117 memory (e.g., unget), but we don't try to hide this. It's a port.
1118
1119 N.B. Seeks on the port must be in the range [0,size].
1120 This is for similarity with bytevector ports, and so that one can seek
1121 to the first byte. */
1122
1123 static SCM
1124 gdbscm_open_memory (SCM rest)
1125 {
1126 const SCM keywords[] = {
1127 mode_keyword, start_keyword, size_keyword, SCM_BOOL_F
1128 };
1129 char *mode = NULL;
1130 CORE_ADDR start = 0;
1131 CORE_ADDR end;
1132 int mode_arg_pos = -1, start_arg_pos = -1, size_arg_pos = -1;
1133 ULONGEST size;
1134 SCM port;
1135 long mode_bits;
1136
1137 gdbscm_parse_function_args (FUNC_NAME, SCM_ARG1, keywords, "#sUU", rest,
1138 &mode_arg_pos, &mode,
1139 &start_arg_pos, &start,
1140 &size_arg_pos, &size);
1141
1142 scm_dynwind_begin ((scm_t_dynwind_flags) 0);
1143
1144 if (mode == NULL)
1145 mode = xstrdup ("r");
1146 scm_dynwind_free (mode);
1147
1148 if (size_arg_pos > 0)
1149 {
1150 /* For now be strict about start+size overflowing. If it becomes
1151 a nuisance we can relax things later. */
1152 if (start + size < start)
1153 {
1154 gdbscm_out_of_range_error (FUNC_NAME, 0,
1155 scm_list_2 (gdbscm_scm_from_ulongest (start),
1156 gdbscm_scm_from_ulongest (size)),
1157 _("start+size overflows"));
1158 }
1159 end = start + size;
1160 }
1161 else
1162 end = ~(CORE_ADDR) 0;
1163
1164 mode_bits = ioscm_parse_mode_bits (FUNC_NAME, mode);
1165
1166 port = ioscm_open_port (memory_port_desc, mode_bits);
1167
1168 ioscm_init_memory_port (port, start, end);
1169
1170 scm_dynwind_end ();
1171
1172 /* TODO: Set the file name as "memory-start-end"? */
1173 return port;
1174 }
1175
1176 /* Return non-zero if OBJ is a memory port. */
1177
1178 static int
1179 gdbscm_is_memory_port (SCM obj)
1180 {
1181 return !SCM_IMP (obj) && (SCM_TYP16 (obj) == memory_port_desc);
1182 }
1183
1184 /* (memory-port? obj) -> boolean */
1185
1186 static SCM
1187 gdbscm_memory_port_p (SCM obj)
1188 {
1189 return scm_from_bool (gdbscm_is_memory_port (obj));
1190 }
1191
1192 /* (memory-port-range port) -> (start end) */
1193
1194 static SCM
1195 gdbscm_memory_port_range (SCM port)
1196 {
1197 ioscm_memory_port *iomem;
1198
1199 SCM_ASSERT_TYPE (gdbscm_is_memory_port (port), port, SCM_ARG1, FUNC_NAME,
1200 memory_port_desc_name);
1201
1202 iomem = (ioscm_memory_port *) SCM_STREAM (port);
1203 return scm_list_2 (gdbscm_scm_from_ulongest (iomem->start),
1204 gdbscm_scm_from_ulongest (iomem->end));
1205 }
1206
1207 /* (memory-port-read-buffer-size port) -> integer */
1208
1209 static SCM
1210 gdbscm_memory_port_read_buffer_size (SCM port)
1211 {
1212 ioscm_memory_port *iomem;
1213
1214 SCM_ASSERT_TYPE (gdbscm_is_memory_port (port), port, SCM_ARG1, FUNC_NAME,
1215 memory_port_desc_name);
1216
1217 iomem = (ioscm_memory_port *) SCM_STREAM (port);
1218 return scm_from_uint (iomem->read_buf_size);
1219 }
1220
1221 /* (set-memory-port-read-buffer-size! port size) -> unspecified
1222 An exception is thrown if read data is still buffered or if the port
1223 is unbuffered. */
1224
1225 static SCM
1226 gdbscm_set_memory_port_read_buffer_size_x (SCM port, SCM size)
1227 {
1228 ioscm_memory_port *iomem;
1229
1230 SCM_ASSERT_TYPE (gdbscm_is_memory_port (port), port, SCM_ARG1, FUNC_NAME,
1231 memory_port_desc_name);
1232 SCM_ASSERT_TYPE (scm_is_integer (size), size, SCM_ARG2, FUNC_NAME,
1233 _("integer"));
1234
1235 if (!scm_is_unsigned_integer (size, min_memory_port_buf_size,
1236 max_memory_port_buf_size))
1237 {
1238 gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG2, size,
1239 out_of_range_buf_size);
1240 }
1241
1242 iomem = (ioscm_memory_port *) SCM_STREAM (port);
1243 ioscm_reinit_memory_port (port, scm_to_uint (size), iomem->write_buf_size,
1244 FUNC_NAME);
1245
1246 return SCM_UNSPECIFIED;
1247 }
1248
1249 /* (memory-port-write-buffer-size port) -> integer */
1250
1251 static SCM
1252 gdbscm_memory_port_write_buffer_size (SCM port)
1253 {
1254 ioscm_memory_port *iomem;
1255
1256 SCM_ASSERT_TYPE (gdbscm_is_memory_port (port), port, SCM_ARG1, FUNC_NAME,
1257 memory_port_desc_name);
1258
1259 iomem = (ioscm_memory_port *) SCM_STREAM (port);
1260 return scm_from_uint (iomem->write_buf_size);
1261 }
1262
1263 /* (set-memory-port-write-buffer-size! port size) -> unspecified
1264 An exception is thrown if write data is still buffered or if the port
1265 is unbuffered. */
1266
1267 static SCM
1268 gdbscm_set_memory_port_write_buffer_size_x (SCM port, SCM size)
1269 {
1270 ioscm_memory_port *iomem;
1271
1272 SCM_ASSERT_TYPE (gdbscm_is_memory_port (port), port, SCM_ARG1, FUNC_NAME,
1273 memory_port_desc_name);
1274 SCM_ASSERT_TYPE (scm_is_integer (size), size, SCM_ARG2, FUNC_NAME,
1275 _("integer"));
1276
1277 if (!scm_is_unsigned_integer (size, min_memory_port_buf_size,
1278 max_memory_port_buf_size))
1279 {
1280 gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG2, size,
1281 out_of_range_buf_size);
1282 }
1283
1284 iomem = (ioscm_memory_port *) SCM_STREAM (port);
1285 ioscm_reinit_memory_port (port, iomem->read_buf_size, scm_to_uint (size),
1286 FUNC_NAME);
1287
1288 return SCM_UNSPECIFIED;
1289 }
1290 \f
1291 /* Initialize gdb ports. */
1292
1293 static const scheme_function port_functions[] =
1294 {
1295 { "input-port", 0, 0, 0, as_a_scm_t_subr (gdbscm_input_port),
1296 "\
1297 Return gdb's input port." },
1298
1299 { "output-port", 0, 0, 0, as_a_scm_t_subr (gdbscm_output_port),
1300 "\
1301 Return gdb's output port." },
1302
1303 { "error-port", 0, 0, 0, as_a_scm_t_subr (gdbscm_error_port),
1304 "\
1305 Return gdb's error port." },
1306
1307 { "stdio-port?", 1, 0, 0, as_a_scm_t_subr (gdbscm_stdio_port_p),
1308 "\
1309 Return #t if the object is a gdb:stdio-port." },
1310
1311 { "open-memory", 0, 0, 1, as_a_scm_t_subr (gdbscm_open_memory),
1312 "\
1313 Return a port that can be used for reading/writing inferior memory.\n\
1314 \n\
1315 Arguments: [#:mode string] [#:start address] [#:size integer]\n\
1316 Returns: A port object." },
1317
1318 { "memory-port?", 1, 0, 0, as_a_scm_t_subr (gdbscm_memory_port_p),
1319 "\
1320 Return #t if the object is a memory port." },
1321
1322 { "memory-port-range", 1, 0, 0, as_a_scm_t_subr (gdbscm_memory_port_range),
1323 "\
1324 Return the memory range of the port as (start end)." },
1325
1326 { "memory-port-read-buffer-size", 1, 0, 0,
1327 as_a_scm_t_subr (gdbscm_memory_port_read_buffer_size),
1328 "\
1329 Return the size of the read buffer for the memory port." },
1330
1331 { "set-memory-port-read-buffer-size!", 2, 0, 0,
1332 as_a_scm_t_subr (gdbscm_set_memory_port_read_buffer_size_x),
1333 "\
1334 Set the size of the read buffer for the memory port.\n\
1335 \n\
1336 Arguments: port integer\n\
1337 Returns: unspecified." },
1338
1339 { "memory-port-write-buffer-size", 1, 0, 0,
1340 as_a_scm_t_subr (gdbscm_memory_port_write_buffer_size),
1341 "\
1342 Return the size of the write buffer for the memory port." },
1343
1344 { "set-memory-port-write-buffer-size!", 2, 0, 0,
1345 as_a_scm_t_subr (gdbscm_set_memory_port_write_buffer_size_x),
1346 "\
1347 Set the size of the write buffer for the memory port.\n\
1348 \n\
1349 Arguments: port integer\n\
1350 Returns: unspecified." },
1351
1352 END_FUNCTIONS
1353 };
1354
1355 static const scheme_function private_port_functions[] =
1356 {
1357 #if 0 /* TODO */
1358 { "%with-gdb-input-from-port", 2, 0, 0,
1359 as_a_scm_t_subr (gdbscm_percent_with_gdb_input_from_port),
1360 "\
1361 Temporarily set GDB's input port to PORT and then invoke THUNK.\n\
1362 \n\
1363 Arguments: port thunk\n\
1364 Returns: The result of calling THUNK.\n\
1365 \n\
1366 This procedure is experimental." },
1367 #endif
1368
1369 { "%with-gdb-output-to-port", 2, 0, 0,
1370 as_a_scm_t_subr (gdbscm_percent_with_gdb_output_to_port),
1371 "\
1372 Temporarily set GDB's output port to PORT and then invoke THUNK.\n\
1373 \n\
1374 Arguments: port thunk\n\
1375 Returns: The result of calling THUNK.\n\
1376 \n\
1377 This procedure is experimental." },
1378
1379 { "%with-gdb-error-to-port", 2, 0, 0,
1380 as_a_scm_t_subr (gdbscm_percent_with_gdb_error_to_port),
1381 "\
1382 Temporarily set GDB's error port to PORT and then invoke THUNK.\n\
1383 \n\
1384 Arguments: port thunk\n\
1385 Returns: The result of calling THUNK.\n\
1386 \n\
1387 This procedure is experimental." },
1388
1389 END_FUNCTIONS
1390 };
1391
1392 void
1393 gdbscm_initialize_ports (void)
1394 {
1395 /* Save the original stdio ports for debugging purposes. */
1396
1397 orig_input_port_scm = scm_current_input_port ();
1398 orig_output_port_scm = scm_current_output_port ();
1399 orig_error_port_scm = scm_current_error_port ();
1400
1401 /* Set up the stdio ports. */
1402
1403 ioscm_init_gdb_stdio_port ();
1404 input_port_scm = ioscm_make_gdb_stdio_port (0);
1405 output_port_scm = ioscm_make_gdb_stdio_port (1);
1406 error_port_scm = ioscm_make_gdb_stdio_port (2);
1407
1408 /* Set up memory ports. */
1409
1410 ioscm_init_memory_port_type ();
1411
1412 /* Install the accessor functions. */
1413
1414 gdbscm_define_functions (port_functions, 1);
1415 gdbscm_define_functions (private_port_functions, 0);
1416
1417 /* Keyword args for open-memory. */
1418
1419 mode_keyword = scm_from_latin1_keyword ("mode");
1420 start_keyword = scm_from_latin1_keyword ("start");
1421 size_keyword = scm_from_latin1_keyword ("size");
1422
1423 /* Error message text for "out of range" memory port buffer sizes. */
1424
1425 out_of_range_buf_size = xstrprintf ("size not between %u - %u",
1426 min_memory_port_buf_size,
1427 max_memory_port_buf_size);
1428 }