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