PR 14072
[deliverable/binutils-gdb.git] / sim / common / callback.c
CommitLineData
c906108c 1/* Remote target callback routines.
c5a57081
JB
2 Copyright 1995-1997, 2000, 2002-2004, 2007-2012 Free Software
3 Foundation, Inc.
c906108c
SS
4 Contributed by Cygnus Solutions.
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
4744ac1b 10 the Free Software Foundation; either version 3 of the License, or
c906108c
SS
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
4744ac1b 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
20
21/* This file provides a standard way for targets to talk to the host OS
22 level. */
23
24#ifdef HAVE_CONFIG_H
41ee5402 25#include "cconfig.h"
c906108c 26#endif
a6ff997c 27#include "config.h"
c906108c 28#include "ansidecl.h"
c906108c 29#include <stdarg.h>
c906108c
SS
30#include <stdio.h>
31#ifdef HAVE_STDLIB_H
32#include <stdlib.h>
33#endif
34#ifdef HAVE_STRING_H
35#include <string.h>
36#else
37#ifdef HAVE_STRINGS_H
38#include <strings.h>
39#endif
40#endif
97f669ed
HPN
41#ifdef HAVE_LIMITS_H
42/* For PIPE_BUF. */
43#include <limits.h>
44#endif
c906108c
SS
45#include <errno.h>
46#include <fcntl.h>
47#include <time.h>
48#include <sys/types.h>
49#include <sys/stat.h>
3c25f8c7 50#include "gdb/callback.h"
c906108c 51#include "targ-vals.h"
97f669ed
HPN
52/* For xmalloc. */
53#include "libiberty.h"
c906108c
SS
54
55#ifdef HAVE_UNISTD_H
56#include <unistd.h>
57#endif
58
33aa0cbb
PB
59#ifndef PIPE_BUF
60#define PIPE_BUF 512
61#endif
62
c906108c
SS
63/* ??? sim_cb_printf should be cb_printf, but until the callback support is
64 broken out of the simulator directory, these are here to not require
65 sim-utils.h. */
66void sim_cb_printf PARAMS ((host_callback *, const char *, ...));
67void sim_cb_eprintf PARAMS ((host_callback *, const char *, ...));
68
69extern CB_TARGET_DEFS_MAP cb_init_syscall_map[];
70extern CB_TARGET_DEFS_MAP cb_init_errno_map[];
71extern CB_TARGET_DEFS_MAP cb_init_open_map[];
72
73extern int system PARAMS ((const char *));
74
75static int os_init PARAMS ((host_callback *));
76static int os_shutdown PARAMS ((host_callback *));
77static int os_unlink PARAMS ((host_callback *, const char *));
78static long os_time PARAMS ((host_callback *, long *));
79static int os_system PARAMS ((host_callback *, const char *));
80static int os_rename PARAMS ((host_callback *, const char *, const char *));
81static int os_write_stdout PARAMS ((host_callback *, const char *, int));
82static void os_flush_stdout PARAMS ((host_callback *));
83static int os_write_stderr PARAMS ((host_callback *, const char *, int));
84static void os_flush_stderr PARAMS ((host_callback *));
85static int os_write PARAMS ((host_callback *, int, const char *, int));
86static int os_read_stdin PARAMS ((host_callback *, char *, int));
87static int os_read PARAMS ((host_callback *, int, char *, int));
88static int os_open PARAMS ((host_callback *, const char *, int));
89static int os_lseek PARAMS ((host_callback *, int, long, int));
90static int os_isatty PARAMS ((host_callback *, int));
91static int os_get_errno PARAMS ((host_callback *));
92static int os_close PARAMS ((host_callback *, int));
93static void os_vprintf_filtered PARAMS ((host_callback *, const char *, va_list));
94static void os_evprintf_filtered PARAMS ((host_callback *, const char *, va_list));
2a8922a9
HPN
95static void os_error PARAMS ((host_callback *, const char *, ...))
96#ifdef __GNUC__
97 __attribute__ ((__noreturn__))
98#endif
99 ;
c906108c
SS
100static int fdmap PARAMS ((host_callback *, int));
101static int fdbad PARAMS ((host_callback *, int));
102static int wrap PARAMS ((host_callback *, int));
103
104/* Set the callback copy of errno from what we see now. */
105
028f6515 106static int
c906108c
SS
107wrap (p, val)
108 host_callback *p;
109 int val;
110{
111 p->last_errno = errno;
112 return val;
113}
114
115/* Make sure the FD provided is ok. If not, return non-zero
116 and set errno. */
117
028f6515 118static int
c906108c
SS
119fdbad (p, fd)
120 host_callback *p;
121 int fd;
122{
594ee3a7 123 if (fd < 0 || fd > MAX_CALLBACK_FDS || p->fd_buddy[fd] < 0)
c906108c 124 {
fee17b35 125 p->last_errno = EBADF;
c906108c
SS
126 return -1;
127 }
128 return 0;
129}
130
028f6515 131static int
c906108c
SS
132fdmap (p, fd)
133 host_callback *p;
134 int fd;
135{
136 return p->fdmap[fd];
137}
138
028f6515 139static int
c906108c
SS
140os_close (p, fd)
141 host_callback *p;
142 int fd;
143{
144 int result;
594ee3a7 145 int i, next;
c906108c
SS
146
147 result = fdbad (p, fd);
148 if (result)
149 return result;
594ee3a7
JR
150 /* If this file descripter has one or more buddies (originals /
151 duplicates from a dup), just remove it from the circular list. */
152 for (i = fd; (next = p->fd_buddy[i]) != fd; )
153 i = next;
154 if (fd != i)
155 p->fd_buddy[i] = p->fd_buddy[fd];
156 else
97f669ed
HPN
157 {
158 if (p->ispipe[fd])
159 {
160 int other = p->ispipe[fd];
161 int reader, writer;
162
163 if (other > 0)
164 {
165 /* Closing the read side. */
166 reader = fd;
167 writer = other;
168 }
169 else
170 {
171 /* Closing the write side. */
172 writer = fd;
173 reader = -other;
174 }
175
176 /* If there was data in the buffer, make a last "now empty"
177 call, then deallocate data. */
178 if (p->pipe_buffer[writer].buffer != NULL)
179 {
180 (*p->pipe_empty) (p, reader, writer);
181 free (p->pipe_buffer[writer].buffer);
182 p->pipe_buffer[writer].buffer = NULL;
183 }
184
185 /* Clear pipe data for this side. */
186 p->pipe_buffer[fd].size = 0;
187 p->ispipe[fd] = 0;
188
189 /* If this was the first close, mark the other side as the
190 only remaining side. */
191 if (fd != abs (other))
192 p->ispipe[abs (other)] = -other;
193 p->fd_buddy[fd] = -1;
194 return 0;
195 }
196
197 result = wrap (p, close (fdmap (p, fd)));
198 }
594ee3a7 199 p->fd_buddy[fd] = -1;
c906108c
SS
200
201 return result;
202}
203
204
205/* taken from gdb/util.c:notice_quit() - should be in a library */
206
207
208#if defined(__GO32__) || defined (_MSC_VER)
209static int
210os_poll_quit (p)
211 host_callback *p;
212{
213#if defined(__GO32__)
214 int kbhit ();
215 int getkey ();
216 if (kbhit ())
217 {
218 int k = getkey ();
219 if (k == 1)
220 {
221 return 1;
222 }
223 else if (k == 2)
224 {
225 return 1;
226 }
028f6515 227 else
c906108c
SS
228 {
229 sim_cb_eprintf (p, "CTRL-A to quit, CTRL-B to quit harder\n");
230 }
231 }
232#endif
233#if defined (_MSC_VER)
234 /* NB - this will not compile! */
34b47c38 235 int k = win32pollquit ();
c906108c
SS
236 if (k == 1)
237 return 1;
238 else if (k == 2)
239 return 1;
240#endif
241 return 0;
242}
243#else
244#define os_poll_quit 0
245#endif /* defined(__GO32__) || defined(_MSC_VER) */
246
028f6515 247static int
c906108c
SS
248os_get_errno (p)
249 host_callback *p;
250{
251 return cb_host_to_target_errno (p, p->last_errno);
252}
253
254
028f6515 255static int
c906108c
SS
256os_isatty (p, fd)
257 host_callback *p;
258 int fd;
259{
260 int result;
261
262 result = fdbad (p, fd);
263 if (result)
264 return result;
265 result = wrap (p, isatty (fdmap (p, fd)));
266
267 return result;
268}
269
028f6515 270static int
c906108c
SS
271os_lseek (p, fd, off, way)
272 host_callback *p;
273 int fd;
274 long off;
275 int way;
276{
277 int result;
278
279 result = fdbad (p, fd);
280 if (result)
281 return result;
0bd15c7f 282 result = wrap (p, lseek (fdmap (p, fd), off, way));
c906108c
SS
283 return result;
284}
285
028f6515 286static int
c906108c
SS
287os_open (p, name, flags)
288 host_callback *p;
289 const char *name;
290 int flags;
291{
292 int i;
293 for (i = 0; i < MAX_CALLBACK_FDS; i++)
294 {
594ee3a7 295 if (p->fd_buddy[i] < 0)
c906108c
SS
296 {
297 int f = open (name, cb_target_to_host_open (p, flags), 0644);
298 if (f < 0)
299 {
300 p->last_errno = errno;
301 return f;
302 }
594ee3a7 303 p->fd_buddy[i] = i;
c906108c
SS
304 p->fdmap[i] = f;
305 return i;
306 }
307 }
308 p->last_errno = EMFILE;
309 return -1;
310}
311
028f6515 312static int
c906108c
SS
313os_read (p, fd, buf, len)
314 host_callback *p;
315 int fd;
316 char *buf;
317 int len;
318{
319 int result;
320
321 result = fdbad (p, fd);
322 if (result)
323 return result;
97f669ed
HPN
324 if (p->ispipe[fd])
325 {
326 int writer = p->ispipe[fd];
327
328 /* Can't read from the write-end. */
329 if (writer < 0)
330 {
331 p->last_errno = EBADF;
332 return -1;
333 }
334
335 /* Nothing to read if nothing is written. */
336 if (p->pipe_buffer[writer].size == 0)
337 return 0;
338
339 /* Truncate read request size to buffer size minus what's already
340 read. */
341 if (len > p->pipe_buffer[writer].size - p->pipe_buffer[fd].size)
342 len = p->pipe_buffer[writer].size - p->pipe_buffer[fd].size;
343
344 memcpy (buf, p->pipe_buffer[writer].buffer + p->pipe_buffer[fd].size,
345 len);
346
347 /* Account for what we just read. */
348 p->pipe_buffer[fd].size += len;
349
350 /* If we've read everything, empty and deallocate the buffer and
351 signal buffer-empty to client. (This isn't expected to be a
352 hot path in the simulator, so we don't hold on to the buffer.) */
353 if (p->pipe_buffer[fd].size == p->pipe_buffer[writer].size)
354 {
355 free (p->pipe_buffer[writer].buffer);
356 p->pipe_buffer[writer].buffer = NULL;
357 p->pipe_buffer[fd].size = 0;
358 p->pipe_buffer[writer].size = 0;
359 (*p->pipe_empty) (p, fd, writer);
360 }
361
362 return len;
363 }
364
c906108c
SS
365 result = wrap (p, read (fdmap (p, fd), buf, len));
366 return result;
367}
368
028f6515 369static int
c906108c
SS
370os_read_stdin (p, buf, len)
371 host_callback *p;
372 char *buf;
373 int len;
374{
375 return wrap (p, read (0, buf, len));
376}
377
028f6515 378static int
c906108c
SS
379os_write (p, fd, buf, len)
380 host_callback *p;
381 int fd;
382 const char *buf;
383 int len;
384{
385 int result;
386 int real_fd;
387
388 result = fdbad (p, fd);
389 if (result)
390 return result;
97f669ed
HPN
391
392 if (p->ispipe[fd])
393 {
394 int reader = -p->ispipe[fd];
395
396 /* Can't write to the read-end. */
397 if (reader < 0)
398 {
399 p->last_errno = EBADF;
400 return -1;
401 }
402
403 /* Can't write to pipe with closed read end.
404 FIXME: We should send a SIGPIPE. */
405 if (reader == fd)
406 {
407 p->last_errno = EPIPE;
408 return -1;
409 }
410
411 /* As a sanity-check, we bail out it the buffered contents is much
412 larger than the size of the buffer on the host. We don't want
413 to run out of memory in the simulator due to a target program
414 bug if we can help it. Unfortunately, regarding the value that
415 reaches the simulated program, it's no use returning *less*
416 than the requested amount, because cb_syscall loops calling
417 this function until the whole amount is done. */
418 if (p->pipe_buffer[fd].size + len > 10 * PIPE_BUF)
419 {
420 p->last_errno = EFBIG;
421 return -1;
422 }
423
424 p->pipe_buffer[fd].buffer
425 = xrealloc (p->pipe_buffer[fd].buffer, p->pipe_buffer[fd].size + len);
426 memcpy (p->pipe_buffer[fd].buffer + p->pipe_buffer[fd].size,
427 buf, len);
428 p->pipe_buffer[fd].size += len;
429
430 (*p->pipe_nonempty) (p, reader, fd);
431 return len;
432 }
433
c906108c
SS
434 real_fd = fdmap (p, fd);
435 switch (real_fd)
436 {
437 default:
438 result = wrap (p, write (real_fd, buf, len));
439 break;
440 case 1:
441 result = p->write_stdout (p, buf, len);
442 break;
443 case 2:
444 result = p->write_stderr (p, buf, len);
445 break;
446 }
447 return result;
448}
449
028f6515 450static int
c906108c 451os_write_stdout (p, buf, len)
6d358e86 452 host_callback *p ATTRIBUTE_UNUSED;
c906108c
SS
453 const char *buf;
454 int len;
455{
456 return fwrite (buf, 1, len, stdout);
457}
458
459static void
460os_flush_stdout (p)
6d358e86 461 host_callback *p ATTRIBUTE_UNUSED;
c906108c
SS
462{
463 fflush (stdout);
464}
465
028f6515 466static int
c906108c 467os_write_stderr (p, buf, len)
6d358e86 468 host_callback *p ATTRIBUTE_UNUSED;
c906108c
SS
469 const char *buf;
470 int len;
471{
472 return fwrite (buf, 1, len, stderr);
473}
474
475static void
476os_flush_stderr (p)
6d358e86 477 host_callback *p ATTRIBUTE_UNUSED;
c906108c
SS
478{
479 fflush (stderr);
480}
481
028f6515 482static int
c906108c
SS
483os_rename (p, f1, f2)
484 host_callback *p;
485 const char *f1;
486 const char *f2;
487{
488 return wrap (p, rename (f1, f2));
489}
490
491
492static int
493os_system (p, s)
494 host_callback *p;
495 const char *s;
496{
497 return wrap (p, system (s));
498}
499
028f6515 500static long
c906108c
SS
501os_time (p, t)
502 host_callback *p;
503 long *t;
504{
505 return wrap (p, time (t));
506}
507
508
028f6515 509static int
c906108c
SS
510os_unlink (p, f1)
511 host_callback *p;
512 const char *f1;
513{
514 return wrap (p, unlink (f1));
515}
516
517static int
518os_stat (p, file, buf)
519 host_callback *p;
520 const char *file;
521 struct stat *buf;
522{
523 /* ??? There is an issue of when to translate to the target layout.
524 One could do that inside this function, or one could have the
525 caller do it. It's more flexible to let the caller do it, though
526 I'm not sure the flexibility will ever be useful. */
527 return wrap (p, stat (file, buf));
528}
529
530static int
531os_fstat (p, fd, buf)
532 host_callback *p;
533 int fd;
534 struct stat *buf;
535{
536 if (fdbad (p, fd))
537 return -1;
97f669ed
HPN
538
539 if (p->ispipe[fd])
540 {
0c4507fd 541#if defined (HAVE_STRUCT_STAT_ST_ATIME) || defined (HAVE_STRUCT_STAT_ST_CTIME) || defined (HAVE_STRUCT_STAT_ST_MTIME)
97f669ed 542 time_t t = (*p->time) (p, NULL);
0c4507fd 543#endif
97f669ed
HPN
544
545 /* We have to fake the struct stat contents, since the pipe is
546 made up in the simulator. */
547 memset (buf, 0, sizeof (*buf));
548
549#ifdef HAVE_STRUCT_STAT_ST_MODE
550 buf->st_mode = S_IFIFO;
551#endif
552
553 /* If more accurate tracking than current-time is needed (for
554 example, on GNU/Linux we get accurate numbers), the p->time
555 callback (which may be something other than os_time) should
556 happen for each read and write, and we'd need to keep track of
557 atime, ctime and mtime. */
558#ifdef HAVE_STRUCT_STAT_ST_ATIME
559 buf->st_atime = t;
560#endif
561#ifdef HAVE_STRUCT_STAT_ST_CTIME
562 buf->st_ctime = t;
563#endif
564#ifdef HAVE_STRUCT_STAT_ST_MTIME
565 buf->st_mtime = t;
566#endif
567 return 0;
568 }
569
c906108c
SS
570 /* ??? There is an issue of when to translate to the target layout.
571 One could do that inside this function, or one could have the
572 caller do it. It's more flexible to let the caller do it, though
573 I'm not sure the flexibility will ever be useful. */
574 return wrap (p, fstat (fdmap (p, fd), buf));
575}
576
0d3cd463
HPN
577static int
578os_lstat (p, file, buf)
579 host_callback *p;
580 const char *file;
581 struct stat *buf;
582{
583 /* NOTE: hpn/2004-12-12: Same issue here as with os_fstat. */
33aa0cbb 584#ifdef HAVE_LSTAT
0d3cd463 585 return wrap (p, lstat (file, buf));
33aa0cbb
PB
586#else
587 return wrap (p, stat (file, buf));
588#endif
0d3cd463
HPN
589}
590
028f6515 591static int
8822d001
JR
592os_ftruncate (p, fd, len)
593 host_callback *p;
594 int fd;
595 long len;
596{
597 int result;
598
599 result = fdbad (p, fd);
97f669ed
HPN
600 if (p->ispipe[fd])
601 {
602 p->last_errno = EINVAL;
603 return -1;
604 }
8822d001
JR
605 if (result)
606 return result;
33aa0cbb 607#ifdef HAVE_FTRUNCATE
8822d001 608 result = wrap (p, ftruncate (fdmap (p, fd), len));
33aa0cbb
PB
609#else
610 p->last_errno = EINVAL;
611 result = -1;
612#endif
8822d001
JR
613 return result;
614}
615
616static int
617os_truncate (p, file, len)
618 host_callback *p;
619 const char *file;
620 long len;
621{
33aa0cbb 622#ifdef HAVE_TRUNCATE
ee3073b5 623 return wrap (p, truncate (file, len));
33aa0cbb
PB
624#else
625 p->last_errno = EINVAL;
626 return -1;
627#endif
8822d001
JR
628}
629
97f669ed
HPN
630static int
631os_pipe (p, filedes)
632 host_callback *p;
633 int *filedes;
634{
635 int i;
636
637 /* We deliberately don't use fd 0. It's probably stdin anyway. */
638 for (i = 1; i < MAX_CALLBACK_FDS; i++)
639 {
640 int j;
641
642 if (p->fd_buddy[i] < 0)
643 for (j = i + 1; j < MAX_CALLBACK_FDS; j++)
644 if (p->fd_buddy[j] < 0)
645 {
646 /* Found two free fd:s. Set stat to allocated and mark
647 pipeness. */
648 p->fd_buddy[i] = i;
649 p->fd_buddy[j] = j;
650 p->ispipe[i] = j;
651 p->ispipe[j] = -i;
652 filedes[0] = i;
653 filedes[1] = j;
654
655 /* Poison the FD map to make bugs apparent. */
656 p->fdmap[i] = -1;
657 p->fdmap[j] = -1;
658 return 0;
659 }
660 }
661
662 p->last_errno = EMFILE;
663 return -1;
664}
665
666/* Stub functions for pipe support. They should always be overridden in
667 targets using the pipe support, but that's up to the target. */
668
669/* Called when the simulator says that the pipe at (reader, writer) is
670 now empty (so the writer should leave its waiting state). */
671
672static void
673os_pipe_empty (p, reader, writer)
674 host_callback *p;
675 int reader;
676 int writer;
677{
678}
679
680/* Called when the simulator says the pipe at (reader, writer) is now
681 non-empty (so the writer should wait). */
682
683static void
684os_pipe_nonempty (p, reader, writer)
685 host_callback *p;
686 int reader;
687 int writer;
688{
689}
690
c906108c
SS
691static int
692os_shutdown (p)
693 host_callback *p;
694{
594ee3a7 695 int i, next, j;
c906108c
SS
696 for (i = 0; i < MAX_CALLBACK_FDS; i++)
697 {
594ee3a7
JR
698 int do_close = 1;
699
97f669ed
HPN
700 /* Zero out all pipe state. Don't call callbacks for non-empty
701 pipes; the target program has likely terminated at this point
702 or we're called at initialization time. */
703 p->ispipe[i] = 0;
704 p->pipe_buffer[i].size = 0;
705 p->pipe_buffer[i].buffer = NULL;
706
594ee3a7
JR
707 next = p->fd_buddy[i];
708 if (next < 0)
709 continue;
710 do
711 {
712 j = next;
713 if (j == MAX_CALLBACK_FDS)
714 do_close = 0;
715 next = p->fd_buddy[j];
716 p->fd_buddy[j] = -1;
717 /* At the initial call of os_init, we got -1, 0, 0, 0, ... */
718 if (next < 0)
719 {
0242f9ea 720 p->fd_buddy[i] = -1;
594ee3a7
JR
721 do_close = 0;
722 break;
723 }
724 }
725 while (j != i);
726 if (do_close)
c906108c 727 close (p->fdmap[i]);
c906108c
SS
728 }
729 return 1;
730}
731
732static int
733os_init (p)
734 host_callback *p;
735{
736 int i;
737
738 os_shutdown (p);
739 for (i = 0; i < 3; i++)
740 {
741 p->fdmap[i] = i;
594ee3a7 742 p->fd_buddy[i] = i - 1;
c906108c 743 }
594ee3a7
JR
744 p->fd_buddy[0] = MAX_CALLBACK_FDS;
745 p->fd_buddy[MAX_CALLBACK_FDS] = 2;
c906108c
SS
746
747 p->syscall_map = cb_init_syscall_map;
748 p->errno_map = cb_init_errno_map;
749 p->open_map = cb_init_open_map;
750
751 return 1;
752}
753
5accf1ff 754/* DEPRECATED */
c906108c
SS
755
756/* VARARGS */
757static void
6d358e86 758os_printf_filtered (host_callback *p ATTRIBUTE_UNUSED, const char *format, ...)
c906108c
SS
759{
760 va_list args;
c906108c 761 va_start (args, format);
c906108c
SS
762
763 vfprintf (stdout, format, args);
764 va_end (args);
765}
766
767/* VARARGS */
768static void
6d358e86 769os_vprintf_filtered (host_callback *p ATTRIBUTE_UNUSED, const char *format, va_list args)
c906108c
SS
770{
771 vprintf (format, args);
772}
773
774/* VARARGS */
775static void
6d358e86 776os_evprintf_filtered (host_callback *p ATTRIBUTE_UNUSED, const char *format, va_list args)
c906108c
SS
777{
778 vfprintf (stderr, format, args);
779}
780
781/* VARARGS */
782static void
6d358e86 783os_error (host_callback *p ATTRIBUTE_UNUSED, const char *format, ...)
c906108c
SS
784{
785 va_list args;
c906108c 786 va_start (args, format);
c906108c
SS
787
788 vfprintf (stderr, format, args);
789 fprintf (stderr, "\n");
790
791 va_end (args);
792 exit (1);
793}
794
795host_callback default_callback =
796{
797 os_close,
798 os_get_errno,
799 os_isatty,
800 os_lseek,
801 os_open,
802 os_read,
803 os_read_stdin,
804 os_rename,
805 os_system,
806 os_time,
807 os_unlink,
808 os_write,
809 os_write_stdout,
810 os_flush_stdout,
811 os_write_stderr,
812 os_flush_stderr,
813
814 os_stat,
815 os_fstat,
0d3cd463 816 os_lstat,
c906108c 817
8822d001
JR
818 os_ftruncate,
819 os_truncate,
820
97f669ed
HPN
821 os_pipe,
822 os_pipe_empty,
823 os_pipe_nonempty,
824
c906108c
SS
825 os_poll_quit,
826
827 os_shutdown,
828 os_init,
829
830 os_printf_filtered, /* deprecated */
831
832 os_vprintf_filtered,
833 os_evprintf_filtered,
834 os_error,
835
836 0, /* last errno */
837
838 { 0, }, /* fdmap */
594ee3a7 839 { -1, }, /* fd_buddy */
97f669ed
HPN
840 { 0, }, /* ispipe */
841 { { 0, 0 }, }, /* pipe_buffer */
c906108c
SS
842
843 0, /* syscall_map */
844 0, /* errno_map */
845 0, /* open_map */
846 0, /* signal_map */
847 0, /* stat_map */
028f6515 848
f4f8cce4
HPN
849 /* Defaults expected to be overridden at initialization, where needed. */
850 BFD_ENDIAN_UNKNOWN, /* target_endian */
97f669ed 851 4, /* target_sizeof_int */
f4f8cce4 852
c906108c
SS
853 HOST_CALLBACK_MAGIC,
854};
855\f
856/* Read in a file describing the target's system call values.
857 E.g. maybe someone will want to use something other than newlib.
858 This assumes that the basic system call recognition and value passing/
859 returning is supported. So maybe some coding/recompilation will be
860 necessary, but not as much.
861
862 If an error occurs, the existing mapping is not changed. */
863
864CB_RC
865cb_read_target_syscall_maps (cb, file)
866 host_callback *cb;
867 const char *file;
868{
869 CB_TARGET_DEFS_MAP *syscall_map, *errno_map, *open_map, *signal_map;
870 const char *stat_map;
871 FILE *f;
872
873 if ((f = fopen (file, "r")) == NULL)
874 return CB_RC_ACCESS;
875
876 /* ... read in and parse file ... */
877
878 fclose (f);
879 return CB_RC_NO_MEM; /* FIXME:wip */
880
881 /* Free storage allocated for any existing maps. */
882 if (cb->syscall_map)
883 free (cb->syscall_map);
884 if (cb->errno_map)
885 free (cb->errno_map);
886 if (cb->open_map)
887 free (cb->open_map);
888 if (cb->signal_map)
889 free (cb->signal_map);
890 if (cb->stat_map)
891 free ((PTR) cb->stat_map);
892
893 cb->syscall_map = syscall_map;
894 cb->errno_map = errno_map;
895 cb->open_map = open_map;
896 cb->signal_map = signal_map;
897 cb->stat_map = stat_map;
898
899 return CB_RC_OK;
900}
901
902/* Translate the target's version of a syscall number to the host's.
903 This isn't actually the host's version, rather a canonical form.
904 ??? Perhaps this should be renamed to ..._canon_syscall. */
905
906int
907cb_target_to_host_syscall (cb, target_val)
908 host_callback *cb;
909 int target_val;
910{
911 CB_TARGET_DEFS_MAP *m;
912
913 for (m = &cb->syscall_map[0]; m->target_val != -1; ++m)
914 if (m->target_val == target_val)
915 return m->host_val;
916
917 return -1;
918}
919
920/* FIXME: sort tables if large.
921 Alternatively, an obvious improvement for errno conversion is
922 to machine generate a function with a large switch(). */
923
924/* Translate the host's version of errno to the target's. */
925
926int
927cb_host_to_target_errno (cb, host_val)
928 host_callback *cb;
929 int host_val;
930{
931 CB_TARGET_DEFS_MAP *m;
932
933 for (m = &cb->errno_map[0]; m->host_val; ++m)
934 if (m->host_val == host_val)
935 return m->target_val;
936
937 /* ??? Which error to return in this case is up for grabs.
938 Note that some missing values may have standard alternatives.
939 For now return 0 and require caller to deal with it. */
940 return 0;
941}
942
943/* Given a set of target bitmasks for the open system call,
944 return the host equivalent.
945 Mapping open flag values is best done by looping so there's no need
946 to machine generate this function. */
947
948int
949cb_target_to_host_open (cb, target_val)
950 host_callback *cb;
951 int target_val;
952{
953 int host_val = 0;
954 CB_TARGET_DEFS_MAP *m;
955
956 for (m = &cb->open_map[0]; m->host_val != -1; ++m)
957 {
958 switch (m->target_val)
959 {
960 /* O_RDONLY can be (and usually is) 0 which needs to be treated
961 specially. */
962 case TARGET_O_RDONLY :
963 case TARGET_O_WRONLY :
964 case TARGET_O_RDWR :
965 if ((target_val & (TARGET_O_RDONLY | TARGET_O_WRONLY | TARGET_O_RDWR))
966 == m->target_val)
967 host_val |= m->host_val;
968 /* Handle the host/target differentiating between binary and
969 text mode. Only one case is of importance */
970#if ! defined (TARGET_O_BINARY) && defined (O_BINARY)
971 host_val |= O_BINARY;
972#endif
973 break;
974 default :
975 if ((m->target_val & target_val) == m->target_val)
976 host_val |= m->host_val;
977 break;
978 }
979 }
980
981 return host_val;
982}
983
f4f8cce4 984/* Utility for e.g. cb_host_to_target_stat to store values in the target's
c906108c
SS
985 stat struct. */
986
f4f8cce4
HPN
987void
988cb_store_target_endian (cb, p, size, val)
989 host_callback *cb;
c906108c
SS
990 char *p;
991 int size;
992 long val; /* ??? must be as big as target word size */
c906108c 993{
f4f8cce4 994 if (cb->target_endian == BFD_ENDIAN_BIG)
c906108c
SS
995 {
996 p += size;
997 while (size-- > 0)
998 {
999 *--p = val;
1000 val >>= 8;
1001 }
1002 }
1003 else
1004 {
1005 while (size-- > 0)
1006 {
1007 *p++ = val;
1008 val >>= 8;
1009 }
1010 }
1011}
1012
1013/* Translate a host's stat struct into a target's.
1014 If HS is NULL, just compute the length of the buffer required,
1015 TS is ignored.
1016
1017 The result is the size of the target's stat struct,
6439295f 1018 or zero if an error occurred during the translation. */
c906108c
SS
1019
1020int
1021cb_host_to_target_stat (cb, hs, ts)
1022 host_callback *cb;
1023 const struct stat *hs;
1024 PTR ts;
1025{
1026 const char *m = cb->stat_map;
1027 char *p;
c906108c
SS
1028
1029 if (hs == NULL)
1030 ts = NULL;
1031 p = ts;
1032
1033 while (m)
1034 {
1035 char *q = strchr (m, ',');
1036 int size;
1037
1038 /* FIXME: Use sscanf? */
1039 if (q == NULL)
1040 {
1041 /* FIXME: print error message */
1042 return 0;
1043 }
1044 size = atoi (q + 1);
1045 if (size == 0)
1046 {
1047 /* FIXME: print error message */
1048 return 0;
1049 }
1050
1051 if (hs != NULL)
1052 {
e1591da4 1053 if (0)
697afb65
HPN
1054 ;
1055 /* Defined here to avoid emacs indigestion on a lone "else". */
1056#undef ST_x
1057#define ST_x(FLD) \
1058 else if (strncmp (m, #FLD, q - m) == 0) \
f4f8cce4 1059 cb_store_target_endian (cb, p, size, hs->FLD)
697afb65
HPN
1060
1061#ifdef HAVE_STRUCT_STAT_ST_DEV
1062 ST_x (st_dev);
1063#endif
1064#ifdef HAVE_STRUCT_STAT_ST_INO
1065 ST_x (st_ino);
1066#endif
1067#ifdef HAVE_STRUCT_STAT_ST_MODE
1068 ST_x (st_mode);
1069#endif
1070#ifdef HAVE_STRUCT_STAT_ST_NLINK
1071 ST_x (st_nlink);
1072#endif
1073#ifdef HAVE_STRUCT_STAT_ST_UID
1074 ST_x (st_uid);
1075#endif
1076#ifdef HAVE_STRUCT_STAT_ST_GID
1077 ST_x (st_gid);
1078#endif
1079#ifdef HAVE_STRUCT_STAT_ST_RDEV
1080 ST_x (st_rdev);
1081#endif
1082#ifdef HAVE_STRUCT_STAT_ST_SIZE
1083 ST_x (st_size);
1084#endif
1085#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1086 ST_x (st_blksize);
1087#endif
1088#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1089 ST_x (st_blocks);
1090#endif
1091#ifdef HAVE_STRUCT_STAT_ST_ATIME
1092 ST_x (st_atime);
1093#endif
1094#ifdef HAVE_STRUCT_STAT_ST_MTIME
1095 ST_x (st_mtime);
1096#endif
1097#ifdef HAVE_STRUCT_STAT_ST_CTIME
1098 ST_x (st_ctime);
1099#endif
1100#undef ST_x
c906108c
SS
1101 /* FIXME:wip */
1102 else
f4f8cce4
HPN
1103 /* Unsupported field, store 0. */
1104 cb_store_target_endian (cb, p, size, 0);
c906108c
SS
1105 }
1106
1107 p += size;
1108 m = strchr (q, ':');
1109 if (m)
1110 ++m;
1111 }
1112
1113 return p - (char *) ts;
1114}
1115\f
1116/* Cover functions to the vfprintf callbacks.
1117
1118 ??? If one thinks of the callbacks as a subsystem onto itself [or part of
1119 a larger "remote target subsystem"] with a well defined interface, then
1120 one would think that the subsystem would provide these. However, until
1121 one is allowed to create such a subsystem (with its own source tree
1122 independent of any particular user), such a critter can't exist. Thus
1123 these functions are here for the time being. */
1124
1125void
1126sim_cb_printf (host_callback *p, const char *fmt, ...)
1127{
1128 va_list ap;
1129
1130 va_start (ap, fmt);
1131 p->vprintf_filtered (p, fmt, ap);
1132 va_end (ap);
1133}
1134
1135void
1136sim_cb_eprintf (host_callback *p, const char *fmt, ...)
1137{
1138 va_list ap;
1139
1140 va_start (ap, fmt);
1141 p->evprintf_filtered (p, fmt, ap);
1142 va_end (ap);
1143}
b981d709
DJ
1144
1145int
1146cb_is_stdin (host_callback *cb, int fd)
1147{
1148 return fdbad (cb, fd) ? 0 : fdmap (cb, fd) == 0;
1149}
1150
eb639c50
DJ
1151int
1152cb_is_stdout (host_callback *cb, int fd)
1153{
1154 return fdbad (cb, fd) ? 0 : fdmap (cb, fd) == 1;
1155}
1156
1157int
1158cb_is_stderr (host_callback *cb, int fd)
1159{
1160 return fdbad (cb, fd) ? 0 : fdmap (cb, fd) == 2;
1161}
This page took 0.571953 seconds and 4 git commands to generate.