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