OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

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

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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