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