xref: /netbsd-src/external/gpl3/gdb/dist/sim/common/sim-io.c (revision 88241920d21b339bf319c0e979ffda80c49a2936)
14e98e3e1Schristos /* The common simulator framework for GDB, the GNU Debugger.
24e98e3e1Schristos 
3*88241920Schristos    Copyright 2002-2024 Free Software Foundation, Inc.
44e98e3e1Schristos 
54e98e3e1Schristos    Contributed by Andrew Cagney and Red Hat.
64e98e3e1Schristos 
74e98e3e1Schristos    This file is part of GDB.
84e98e3e1Schristos 
94e98e3e1Schristos    This program is free software; you can redistribute it and/or modify
104e98e3e1Schristos    it under the terms of the GNU General Public License as published by
114e98e3e1Schristos    the Free Software Foundation; either version 3 of the License, or
124e98e3e1Schristos    (at your option) any later version.
134e98e3e1Schristos 
144e98e3e1Schristos    This program is distributed in the hope that it will be useful,
154e98e3e1Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
164e98e3e1Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
174e98e3e1Schristos    GNU General Public License for more details.
184e98e3e1Schristos 
194e98e3e1Schristos    You should have received a copy of the GNU General Public License
204e98e3e1Schristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
214e98e3e1Schristos 
224b169a6bSchristos /* This must come before any other includes.  */
234b169a6bSchristos #include "defs.h"
244e98e3e1Schristos 
254e98e3e1Schristos #include <errno.h>
264e98e3e1Schristos #if HAVE_FCNTL_H
274e98e3e1Schristos #include <fcntl.h>
284e98e3e1Schristos #endif
294b169a6bSchristos #include <stdarg.h>
304b169a6bSchristos #include <stdint.h>
314b169a6bSchristos #include <stdlib.h>
324e98e3e1Schristos #include <unistd.h>
334e98e3e1Schristos 
344b169a6bSchristos #undef open
354b169a6bSchristos 
364b169a6bSchristos #include "sim-main.h"
374b169a6bSchristos #include "sim-io.h"
384b169a6bSchristos #include "sim/callback.h"
398dffb485Schristos 
404e98e3e1Schristos /* Define the rate at which the simulator should poll the host
414e98e3e1Schristos    for a quit. */
424e98e3e1Schristos #ifndef POLL_QUIT_INTERVAL
434e98e3e1Schristos #define POLL_QUIT_INTERVAL 0x10
444e98e3e1Schristos #endif
454e98e3e1Schristos 
464e98e3e1Schristos static int poll_quit_count = POLL_QUIT_INTERVAL;
474e98e3e1Schristos 
484e98e3e1Schristos /* See the file include/callbacks.h for a description */
494e98e3e1Schristos 
504e98e3e1Schristos 
514e98e3e1Schristos int
524e98e3e1Schristos sim_io_init (SIM_DESC sd)
534e98e3e1Schristos {
544e98e3e1Schristos   return STATE_CALLBACK (sd)->init (STATE_CALLBACK (sd));
554e98e3e1Schristos }
564e98e3e1Schristos 
574e98e3e1Schristos 
584e98e3e1Schristos int
594e98e3e1Schristos sim_io_shutdown (SIM_DESC sd)
604e98e3e1Schristos {
614e98e3e1Schristos   return STATE_CALLBACK (sd)->shutdown (STATE_CALLBACK (sd));
624e98e3e1Schristos }
634e98e3e1Schristos 
644e98e3e1Schristos 
654e98e3e1Schristos int
664e98e3e1Schristos sim_io_unlink (SIM_DESC sd,
674e98e3e1Schristos 	       const char *f1)
684e98e3e1Schristos {
694e98e3e1Schristos   return STATE_CALLBACK (sd)->unlink (STATE_CALLBACK (sd), f1);
704e98e3e1Schristos }
714e98e3e1Schristos 
724e98e3e1Schristos 
734b169a6bSchristos int64_t
744b169a6bSchristos sim_io_time (SIM_DESC sd)
754e98e3e1Schristos {
764b169a6bSchristos   return STATE_CALLBACK (sd)->time (STATE_CALLBACK (sd));
774e98e3e1Schristos }
784e98e3e1Schristos 
794e98e3e1Schristos 
804e98e3e1Schristos int
814e98e3e1Schristos sim_io_system (SIM_DESC sd, const char *s)
824e98e3e1Schristos {
834e98e3e1Schristos   return STATE_CALLBACK (sd)->system (STATE_CALLBACK (sd), s);
844e98e3e1Schristos }
854e98e3e1Schristos 
864e98e3e1Schristos 
874e98e3e1Schristos int
884e98e3e1Schristos sim_io_rename (SIM_DESC sd,
894e98e3e1Schristos 	       const char *f1,
904e98e3e1Schristos 	       const char *f2)
914e98e3e1Schristos {
924e98e3e1Schristos   return STATE_CALLBACK (sd)->rename (STATE_CALLBACK (sd), f1, f2);
934e98e3e1Schristos }
944e98e3e1Schristos 
954e98e3e1Schristos 
964e98e3e1Schristos int
974e98e3e1Schristos sim_io_write_stdout (SIM_DESC sd,
984e98e3e1Schristos 		     const char *buf,
994e98e3e1Schristos 		     int len)
1004e98e3e1Schristos {
1014e98e3e1Schristos   switch (CURRENT_STDIO) {
1024e98e3e1Schristos   case DO_USE_STDIO:
1034e98e3e1Schristos     return STATE_CALLBACK (sd)->write_stdout (STATE_CALLBACK (sd), buf, len);
1044e98e3e1Schristos     break;
1054e98e3e1Schristos   case DONT_USE_STDIO:
1064e98e3e1Schristos     return STATE_CALLBACK (sd)->write (STATE_CALLBACK (sd), 1, buf, len);
1074e98e3e1Schristos     break;
1084e98e3e1Schristos   default:
1094e98e3e1Schristos     sim_io_error (sd, "sim_io_write_stdout: unaccounted switch\n");
1104e98e3e1Schristos     break;
1114e98e3e1Schristos   }
1124e98e3e1Schristos   return 0;
1134e98e3e1Schristos }
1144e98e3e1Schristos 
1154e98e3e1Schristos 
1164e98e3e1Schristos void
1174e98e3e1Schristos sim_io_flush_stdout (SIM_DESC sd)
1184e98e3e1Schristos {
1194e98e3e1Schristos   switch (CURRENT_STDIO) {
1204e98e3e1Schristos   case DO_USE_STDIO:
1214e98e3e1Schristos     STATE_CALLBACK (sd)->flush_stdout (STATE_CALLBACK (sd));
1224e98e3e1Schristos     break;
1234e98e3e1Schristos   case DONT_USE_STDIO:
1244e98e3e1Schristos     break;
1254e98e3e1Schristos   default:
1264e98e3e1Schristos     sim_io_error (sd, "sim_io_flush_stdout: unaccounted switch\n");
1274e98e3e1Schristos     break;
1284e98e3e1Schristos   }
1294e98e3e1Schristos }
1304e98e3e1Schristos 
1314e98e3e1Schristos 
1324e98e3e1Schristos int
1334e98e3e1Schristos sim_io_write_stderr (SIM_DESC sd,
1344e98e3e1Schristos 		     const char *buf,
1354e98e3e1Schristos 		     int len)
1364e98e3e1Schristos {
1374e98e3e1Schristos   switch (CURRENT_STDIO) {
1384e98e3e1Schristos   case DO_USE_STDIO:
1394e98e3e1Schristos     return STATE_CALLBACK (sd)->write_stderr (STATE_CALLBACK (sd), buf, len);
1404e98e3e1Schristos     break;
1414e98e3e1Schristos   case DONT_USE_STDIO:
1424e98e3e1Schristos     return STATE_CALLBACK (sd)->write (STATE_CALLBACK (sd), 2, buf, len);
1434e98e3e1Schristos     break;
1444e98e3e1Schristos   default:
1454e98e3e1Schristos     sim_io_error (sd, "sim_io_write_stderr: unaccounted switch\n");
1464e98e3e1Schristos     break;
1474e98e3e1Schristos   }
1484e98e3e1Schristos   return 0;
1494e98e3e1Schristos }
1504e98e3e1Schristos 
1514e98e3e1Schristos 
1524e98e3e1Schristos void
1534e98e3e1Schristos sim_io_flush_stderr (SIM_DESC sd)
1544e98e3e1Schristos {
1554e98e3e1Schristos   switch (CURRENT_STDIO) {
1564e98e3e1Schristos   case DO_USE_STDIO:
1574e98e3e1Schristos     STATE_CALLBACK (sd)->flush_stderr (STATE_CALLBACK (sd));
1584e98e3e1Schristos     break;
1594e98e3e1Schristos   case DONT_USE_STDIO:
1604e98e3e1Schristos     break;
1614e98e3e1Schristos   default:
1624e98e3e1Schristos     sim_io_error (sd, "sim_io_flush_stderr: unaccounted switch\n");
1634e98e3e1Schristos     break;
1644e98e3e1Schristos   }
1654e98e3e1Schristos }
1664e98e3e1Schristos 
1674e98e3e1Schristos 
1684e98e3e1Schristos int
1694e98e3e1Schristos sim_io_write (SIM_DESC sd,
1704e98e3e1Schristos 	      int fd,
1714e98e3e1Schristos 	      const char *buf,
1724e98e3e1Schristos 	      int len)
1734e98e3e1Schristos {
1744e98e3e1Schristos   return STATE_CALLBACK (sd)->write (STATE_CALLBACK (sd), fd, buf, len);
1754e98e3e1Schristos }
1764e98e3e1Schristos 
1774e98e3e1Schristos 
1784e98e3e1Schristos int
1794e98e3e1Schristos sim_io_read_stdin (SIM_DESC sd,
1804e98e3e1Schristos 		   char *buf,
1814e98e3e1Schristos 		   int len)
1824e98e3e1Schristos {
1834e98e3e1Schristos   switch (CURRENT_STDIO) {
1844e98e3e1Schristos   case DO_USE_STDIO:
1854e98e3e1Schristos     return STATE_CALLBACK (sd)->read_stdin (STATE_CALLBACK (sd), buf, len);
1864e98e3e1Schristos     break;
1874e98e3e1Schristos   case DONT_USE_STDIO:
1884e98e3e1Schristos     return STATE_CALLBACK (sd)->read (STATE_CALLBACK (sd), 0, buf, len);
1894e98e3e1Schristos     break;
1904e98e3e1Schristos   default:
1914e98e3e1Schristos     sim_io_error (sd, "sim_io_read_stdin: unaccounted switch\n");
1924e98e3e1Schristos     break;
1934e98e3e1Schristos   }
1944e98e3e1Schristos   return 0;
1954e98e3e1Schristos }
1964e98e3e1Schristos 
1974e98e3e1Schristos 
1984e98e3e1Schristos int
1994e98e3e1Schristos sim_io_read (SIM_DESC sd, int fd,
2004e98e3e1Schristos 	     char *buf,
2014e98e3e1Schristos 	     int len)
2024e98e3e1Schristos {
2034e98e3e1Schristos   return STATE_CALLBACK (sd)->read (STATE_CALLBACK (sd), fd, buf, len);
2044e98e3e1Schristos }
2054e98e3e1Schristos 
2064e98e3e1Schristos 
2074e98e3e1Schristos int
2084e98e3e1Schristos sim_io_open (SIM_DESC sd,
2094e98e3e1Schristos 	     const char *name,
2104e98e3e1Schristos 	     int flags)
2114e98e3e1Schristos {
2124e98e3e1Schristos   return STATE_CALLBACK (sd)->open (STATE_CALLBACK (sd), name, flags);
2134e98e3e1Schristos }
2144e98e3e1Schristos 
2154e98e3e1Schristos 
2164b169a6bSchristos int64_t
2174e98e3e1Schristos sim_io_lseek (SIM_DESC sd,
2184e98e3e1Schristos 	      int fd,
2194b169a6bSchristos 	      int64_t off,
2204e98e3e1Schristos 	      int way)
2214e98e3e1Schristos {
2224e98e3e1Schristos   return STATE_CALLBACK (sd)->lseek (STATE_CALLBACK (sd), fd, off, way);
2234e98e3e1Schristos }
2244e98e3e1Schristos 
2254e98e3e1Schristos 
2264e98e3e1Schristos int
2274e98e3e1Schristos sim_io_isatty (SIM_DESC sd,
2284e98e3e1Schristos 	       int fd)
2294e98e3e1Schristos {
2304e98e3e1Schristos   return STATE_CALLBACK (sd)->isatty (STATE_CALLBACK (sd), fd);
2314e98e3e1Schristos }
2324e98e3e1Schristos 
2334e98e3e1Schristos 
2344e98e3e1Schristos int
2354e98e3e1Schristos sim_io_get_errno (SIM_DESC sd)
2364e98e3e1Schristos {
2374e98e3e1Schristos   return STATE_CALLBACK (sd)->get_errno (STATE_CALLBACK (sd));
2384e98e3e1Schristos }
2394e98e3e1Schristos 
2404e98e3e1Schristos 
2414e98e3e1Schristos int
2424e98e3e1Schristos sim_io_close (SIM_DESC sd,
2434e98e3e1Schristos 	      int fd)
2444e98e3e1Schristos {
2454e98e3e1Schristos   return STATE_CALLBACK (sd)->close (STATE_CALLBACK (sd), fd);
2464e98e3e1Schristos }
2474e98e3e1Schristos 
2484e98e3e1Schristos 
2494e98e3e1Schristos void
2504e98e3e1Schristos sim_io_printf (SIM_DESC sd,
2514e98e3e1Schristos 	       const char *fmt,
2524e98e3e1Schristos 	       ...)
2534e98e3e1Schristos {
2544e98e3e1Schristos   va_list ap;
2554e98e3e1Schristos   va_start (ap, fmt);
2564e98e3e1Schristos   STATE_CALLBACK (sd)->vprintf_filtered (STATE_CALLBACK (sd), fmt, ap);
2574e98e3e1Schristos   va_end (ap);
2584e98e3e1Schristos }
2594e98e3e1Schristos 
2604e98e3e1Schristos 
2614e98e3e1Schristos void
2624e98e3e1Schristos sim_io_vprintf (SIM_DESC sd,
2634e98e3e1Schristos 		const char *fmt,
2644e98e3e1Schristos 		va_list ap)
2654e98e3e1Schristos {
2664e98e3e1Schristos   STATE_CALLBACK (sd)->vprintf_filtered (STATE_CALLBACK (sd), fmt, ap);
2674e98e3e1Schristos }
2684e98e3e1Schristos 
2694e98e3e1Schristos 
2704e98e3e1Schristos void
2714e98e3e1Schristos sim_io_eprintf (SIM_DESC sd,
2724e98e3e1Schristos 	       const char *fmt,
2734e98e3e1Schristos 	       ...)
2744e98e3e1Schristos {
2754e98e3e1Schristos   va_list ap;
2764e98e3e1Schristos   va_start (ap, fmt);
2774e98e3e1Schristos   STATE_CALLBACK (sd)->evprintf_filtered (STATE_CALLBACK (sd), fmt, ap);
2784e98e3e1Schristos   va_end (ap);
2794e98e3e1Schristos }
2804e98e3e1Schristos 
2814e98e3e1Schristos 
2824e98e3e1Schristos void
2834e98e3e1Schristos sim_io_evprintf (SIM_DESC sd,
2844e98e3e1Schristos 		 const char *fmt,
2854e98e3e1Schristos 		 va_list ap)
2864e98e3e1Schristos {
2874e98e3e1Schristos   STATE_CALLBACK (sd)->evprintf_filtered (STATE_CALLBACK (sd), fmt, ap);
2884e98e3e1Schristos }
2894e98e3e1Schristos 
2904e98e3e1Schristos 
2914e98e3e1Schristos void
2924e98e3e1Schristos sim_io_error (SIM_DESC sd,
2934e98e3e1Schristos 	      const char *fmt,
2944e98e3e1Schristos 	      ...)
2954e98e3e1Schristos {
2964e98e3e1Schristos   if (sd == NULL || STATE_CALLBACK (sd) == NULL) {
2974e98e3e1Schristos     va_list ap;
2984e98e3e1Schristos     va_start (ap, fmt);
2994e98e3e1Schristos     vfprintf (stderr, fmt, ap);
3004e98e3e1Schristos     va_end (ap);
3014e98e3e1Schristos     fprintf (stderr, "\n");
3024e98e3e1Schristos     abort ();
3034e98e3e1Schristos   }
3044e98e3e1Schristos   else {
3054e98e3e1Schristos     va_list ap;
3064e98e3e1Schristos     va_start (ap, fmt);
3074e98e3e1Schristos     STATE_CALLBACK (sd)->evprintf_filtered (STATE_CALLBACK (sd), fmt, ap);
3084e98e3e1Schristos     va_end (ap);
3094b169a6bSchristos     /* The %s avoids empty printf compiler warnings.  Not ideal, but we want
3104b169a6bSchristos        error's side-effect where it halts processing.  */
3114b169a6bSchristos     STATE_CALLBACK (sd)->error (STATE_CALLBACK (sd), "%s", "");
3124e98e3e1Schristos   }
3134e98e3e1Schristos }
3144e98e3e1Schristos 
3154e98e3e1Schristos 
3164e98e3e1Schristos void
3174e98e3e1Schristos sim_io_poll_quit (SIM_DESC sd)
3184e98e3e1Schristos {
3194e98e3e1Schristos   if (STATE_CALLBACK (sd)->poll_quit != NULL && poll_quit_count-- < 0)
3204e98e3e1Schristos     {
3214e98e3e1Schristos       poll_quit_count = POLL_QUIT_INTERVAL;
3224e98e3e1Schristos       if (STATE_CALLBACK (sd)->poll_quit (STATE_CALLBACK (sd)))
3234e98e3e1Schristos 	sim_stop (sd);
3244e98e3e1Schristos     }
3254e98e3e1Schristos }
3264e98e3e1Schristos 
3274e98e3e1Schristos 
3284e98e3e1Schristos /* Based on gdb-4.17/sim/ppc/main.c:sim_io_read_stdin().
3294e98e3e1Schristos 
3304e98e3e1Schristos    FIXME: Should not be calling fcntl() or grubbing around inside of
3314e98e3e1Schristos    ->fdmap and ->errno.
3324e98e3e1Schristos 
3334e98e3e1Schristos    FIXME: Some completly new mechanism for handling the general
3344e98e3e1Schristos    problem of asynchronous IO is needed.
3354e98e3e1Schristos 
3364e98e3e1Schristos    FIXME: This function does not supress the echoing (ECHO) of input.
3374e98e3e1Schristos    Consequently polled input is always displayed.
3384e98e3e1Schristos 
3394e98e3e1Schristos    FIXME: This function does not perform uncooked reads.
3404e98e3e1Schristos    Consequently, data will not be read until an EOLN character has
3414e98e3e1Schristos    been entered. A cntrl-d may force the early termination of a line */
3424e98e3e1Schristos 
3434e98e3e1Schristos 
3444e98e3e1Schristos int
3454e98e3e1Schristos sim_io_poll_read (SIM_DESC sd,
3464e98e3e1Schristos 		  int sim_io_fd,
3474e98e3e1Schristos 		  char *buf,
3484e98e3e1Schristos 		  int sizeof_buf)
3494e98e3e1Schristos {
3504b169a6bSchristos #if defined(O_NONBLOCK) && defined(F_GETFL) && defined(F_SETFL)
3514e98e3e1Schristos   int fd = STATE_CALLBACK (sd)->fdmap[sim_io_fd];
3524e98e3e1Schristos   int flags;
3534e98e3e1Schristos   int status;
3544e98e3e1Schristos   int nr_read;
3554e98e3e1Schristos   int result;
3564e98e3e1Schristos   STATE_CALLBACK (sd)->last_errno = 0;
3574e98e3e1Schristos   /* get the old status */
3584e98e3e1Schristos   flags = fcntl (fd, F_GETFL, 0);
3594e98e3e1Schristos   if (flags == -1)
3604e98e3e1Schristos     {
3614e98e3e1Schristos       perror ("sim_io_poll_read");
3624e98e3e1Schristos       return 0;
3634e98e3e1Schristos     }
3644e98e3e1Schristos   /* temp, disable blocking IO */
3654b169a6bSchristos   status = fcntl (fd, F_SETFL, flags | O_NONBLOCK);
3664e98e3e1Schristos   if (status == -1)
3674e98e3e1Schristos     {
3684e98e3e1Schristos       perror ("sim_io_read_stdin");
3694e98e3e1Schristos       return 0;
3704e98e3e1Schristos     }
3714e98e3e1Schristos   /* try for input */
3724e98e3e1Schristos   nr_read = read (fd, buf, sizeof_buf);
3734e98e3e1Schristos   if (nr_read >= 0)
3744e98e3e1Schristos     {
3754e98e3e1Schristos       /* printf ("<nr-read=%d>\n", nr_read); */
3764e98e3e1Schristos       result = nr_read;
3774e98e3e1Schristos     }
3784e98e3e1Schristos   else
3794e98e3e1Schristos     { /* nr_read < 0 */
3804e98e3e1Schristos       result = -1;
3814e98e3e1Schristos       STATE_CALLBACK (sd)->last_errno = errno;
3824e98e3e1Schristos     }
3834e98e3e1Schristos   /* return to regular vewing */
3844e98e3e1Schristos   status = fcntl (fd, F_SETFL, flags);
3854e98e3e1Schristos   if (status == -1)
3864e98e3e1Schristos     {
3874e98e3e1Schristos       perror ("sim_io_read_stdin");
3884e98e3e1Schristos       /* return 0; */
3894e98e3e1Schristos     }
3904e98e3e1Schristos   return result;
3914e98e3e1Schristos #else
3924e98e3e1Schristos   return sim_io_read (sd, sim_io_fd, buf, sizeof_buf);
3934e98e3e1Schristos #endif
3944e98e3e1Schristos }
3954e98e3e1Schristos 
3964e98e3e1Schristos int
3974e98e3e1Schristos sim_io_stat (SIM_DESC sd, const char *path, struct stat *buf)
3984e98e3e1Schristos {
399837edd6bSchristos   return STATE_CALLBACK (sd)->to_stat (STATE_CALLBACK (sd), path, buf);
4004e98e3e1Schristos }
4014e98e3e1Schristos 
4024e98e3e1Schristos int
4034e98e3e1Schristos sim_io_fstat (SIM_DESC sd, int fd, struct stat *buf)
4044e98e3e1Schristos {
405837edd6bSchristos   return STATE_CALLBACK (sd)->to_fstat (STATE_CALLBACK (sd), fd, buf);
4064e98e3e1Schristos }
407