OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [sim/] [common/] [callback.c] - Blame information for rev 227

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.