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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [sim/] [common/] [callback.c] - Blame information for rev 578

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

Line No. Rev Author Line
1 578 markom
/* Remote target callback routines.
2
   Copyright 1995, 1996, 1997 Free Software Foundation, Inc.
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
9
   the Free Software Foundation; either version 2 of the License, or
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
18
   along with GAS; see the file COPYING.  If not, write to the Free Software
19
   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
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 "config.h"
26
#endif
27
#include "ansidecl.h"
28
#ifdef ANSI_PROTOTYPES
29
#include <stdarg.h>
30
#else
31
#include <varargs.h>
32
#endif
33
#include <stdio.h>
34
#ifdef HAVE_STDLIB_H
35
#include <stdlib.h>
36
#endif
37
#ifdef HAVE_STRING_H
38
#include <string.h>
39
#else
40
#ifdef HAVE_STRINGS_H
41
#include <strings.h>
42
#endif
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 "callback.h"
50
#include "targ-vals.h"
51
 
52
#ifdef HAVE_UNISTD_H
53
#include <unistd.h>
54
#endif
55
 
56
/* ??? sim_cb_printf should be cb_printf, but until the callback support is
57
   broken out of the simulator directory, these are here to not require
58
   sim-utils.h.  */
59
void sim_cb_printf PARAMS ((host_callback *, const char *, ...));
60
void sim_cb_eprintf PARAMS ((host_callback *, const char *, ...));
61
 
62
extern CB_TARGET_DEFS_MAP cb_init_syscall_map[];
63
extern CB_TARGET_DEFS_MAP cb_init_errno_map[];
64
extern CB_TARGET_DEFS_MAP cb_init_open_map[];
65
 
66
extern int system PARAMS ((const char *));
67
 
68
static int os_init PARAMS ((host_callback *));
69
static int os_shutdown PARAMS ((host_callback *));
70
static int os_unlink PARAMS ((host_callback *, const char *));
71
static long os_time PARAMS ((host_callback *, long *));
72
static int os_system PARAMS ((host_callback *, const char *));
73
static int os_rename PARAMS ((host_callback *, const char *, const char *));
74
static int os_write_stdout PARAMS ((host_callback *, const char *, int));
75
static void os_flush_stdout PARAMS ((host_callback *));
76
static int os_write_stderr PARAMS ((host_callback *, const char *, int));
77
static void os_flush_stderr PARAMS ((host_callback *));
78
static int os_write PARAMS ((host_callback *, int, const char *, int));
79
static int os_read_stdin PARAMS ((host_callback *, char *, int));
80
static int os_read PARAMS ((host_callback *, int, char *, int));
81
static int os_open PARAMS ((host_callback *, const char *, int));
82
static int os_lseek PARAMS ((host_callback *, int, long, int));
83
static int os_isatty PARAMS ((host_callback *, int));
84
static int os_get_errno PARAMS ((host_callback *));
85
static int os_close PARAMS ((host_callback *, int));
86
static void os_vprintf_filtered PARAMS ((host_callback *, const char *, va_list));
87
static void os_evprintf_filtered PARAMS ((host_callback *, const char *, va_list));
88
static void os_error PARAMS ((host_callback *, const char *, ...));
89
static int fdmap PARAMS ((host_callback *, int));
90
static int fdbad PARAMS ((host_callback *, int));
91
static int wrap PARAMS ((host_callback *, int));
92
 
93
/* Set the callback copy of errno from what we see now.  */
94
 
95
static int
96
wrap (p, val)
97
     host_callback *p;
98
     int val;
99
{
100
  p->last_errno = errno;
101
  return val;
102
}
103
 
104
/* Make sure the FD provided is ok.  If not, return non-zero
105
   and set errno. */
106
 
107
static int
108
fdbad (p, fd)
109
     host_callback *p;
110
     int fd;
111
{
112
  if (fd < 0 || fd > MAX_CALLBACK_FDS || !p->fdopen[fd])
113
    {
114
      p->last_errno = EINVAL;
115
      return -1;
116
    }
117
  return 0;
118
}
119
 
120
static int
121
fdmap (p, fd)
122
     host_callback *p;
123
     int fd;
124
{
125
  return p->fdmap[fd];
126
}
127
 
128
static int
129
os_close (p, fd)
130
     host_callback *p;
131
     int fd;
132
{
133
  int result;
134
 
135
  result = fdbad (p, fd);
136
  if (result)
137
    return result;
138
  result = wrap (p, close (fdmap (p, fd)));
139
  if (result == 0 && !p->alwaysopen[fd])
140
    p->fdopen[fd] = 0;
141
 
142
  return result;
143
}
144
 
145
 
146
/* taken from gdb/util.c:notice_quit() - should be in a library */
147
 
148
 
149
#if defined(__GO32__) || defined (_MSC_VER)
150
static int
151
os_poll_quit (p)
152
     host_callback *p;
153
{
154
#if defined(__GO32__)
155
  int kbhit ();
156
  int getkey ();
157
  if (kbhit ())
158
    {
159
      int k = getkey ();
160
      if (k == 1)
161
        {
162
          return 1;
163
        }
164
      else if (k == 2)
165
        {
166
          return 1;
167
        }
168
      else
169
        {
170
          sim_cb_eprintf (p, "CTRL-A to quit, CTRL-B to quit harder\n");
171
        }
172
    }
173
#endif
174
#if defined (_MSC_VER)
175
  /* NB - this will not compile! */
176
  int k = win32pollquit();
177
  if (k == 1)
178
    return 1;
179
  else if (k == 2)
180
    return 1;
181
#endif
182
  return 0;
183
}
184
#else
185
#define os_poll_quit 0
186
#endif /* defined(__GO32__) || defined(_MSC_VER) */
187
 
188
static int
189
os_get_errno (p)
190
     host_callback *p;
191
{
192
  return cb_host_to_target_errno (p, p->last_errno);
193
}
194
 
195
 
196
static int
197
os_isatty (p, fd)
198
     host_callback *p;
199
     int fd;
200
{
201
  int result;
202
 
203
  result = fdbad (p, fd);
204
  if (result)
205
    return result;
206
  result = wrap (p, isatty (fdmap (p, fd)));
207
 
208
  return result;
209
}
210
 
211
static int
212
os_lseek (p, fd, off, way)
213
     host_callback *p;
214
     int fd;
215
     long off;
216
     int way;
217
{
218
  int result;
219
 
220
  result = fdbad (p, fd);
221
  if (result)
222
    return result;
223
  result = lseek (fdmap (p, fd), off, way);
224
  return result;
225
}
226
 
227
static int
228
os_open (p, name, flags)
229
     host_callback *p;
230
     const char *name;
231
     int flags;
232
{
233
  int i;
234
  for (i = 0; i < MAX_CALLBACK_FDS; i++)
235
    {
236
      if (!p->fdopen[i])
237
        {
238
          int f = open (name, cb_target_to_host_open (p, flags), 0644);
239
          if (f < 0)
240
            {
241
              p->last_errno = errno;
242
              return f;
243
            }
244
          p->fdopen[i] = 1;
245
          p->fdmap[i] = f;
246
          return i;
247
        }
248
    }
249
  p->last_errno = EMFILE;
250
  return -1;
251
}
252
 
253
static int
254
os_read (p, fd, buf, len)
255
     host_callback *p;
256
     int fd;
257
     char *buf;
258
     int len;
259
{
260
  int result;
261
 
262
  result = fdbad (p, fd);
263
  if (result)
264
    return result;
265
  result = wrap (p, read (fdmap (p, fd), buf, len));
266
  return result;
267
}
268
 
269
static int
270
os_read_stdin (p, buf, len)
271
     host_callback *p;
272
     char *buf;
273
     int len;
274
{
275
  return wrap (p, read (0, buf, len));
276
}
277
 
278
static int
279
os_write (p, fd, buf, len)
280
     host_callback *p;
281
     int fd;
282
     const char *buf;
283
     int len;
284
{
285
  int result;
286
  int real_fd;
287
 
288
  result = fdbad (p, fd);
289
  if (result)
290
    return result;
291
  real_fd = fdmap (p, fd);
292
  switch (real_fd)
293
    {
294
    default:
295
      result = wrap (p, write (real_fd, buf, len));
296
      break;
297
    case 1:
298
      result = p->write_stdout (p, buf, len);
299
      break;
300
    case 2:
301
      result = p->write_stderr (p, buf, len);
302
      break;
303
    }
304
  return result;
305
}
306
 
307
static int
308
os_write_stdout (p, buf, len)
309
     host_callback *p ATTRIBUTE_UNUSED;
310
     const char *buf;
311
     int len;
312
{
313
  return fwrite (buf, 1, len, stdout);
314
}
315
 
316
static void
317
os_flush_stdout (p)
318
     host_callback *p ATTRIBUTE_UNUSED;
319
{
320
  fflush (stdout);
321
}
322
 
323
static int
324
os_write_stderr (p, buf, len)
325
     host_callback *p ATTRIBUTE_UNUSED;
326
     const char *buf;
327
     int len;
328
{
329
  return fwrite (buf, 1, len, stderr);
330
}
331
 
332
static void
333
os_flush_stderr (p)
334
     host_callback *p ATTRIBUTE_UNUSED;
335
{
336
  fflush (stderr);
337
}
338
 
339
static int
340
os_rename (p, f1, f2)
341
     host_callback *p;
342
     const char *f1;
343
     const char *f2;
344
{
345
  return wrap (p, rename (f1, f2));
346
}
347
 
348
 
349
static int
350
os_system (p, s)
351
     host_callback *p;
352
     const char *s;
353
{
354
  return wrap (p, system (s));
355
}
356
 
357
static long
358
os_time (p, t)
359
     host_callback *p;
360
     long *t;
361
{
362
  return wrap (p, time (t));
363
}
364
 
365
 
366
static int
367
os_unlink (p, f1)
368
     host_callback *p;
369
     const char *f1;
370
{
371
  return wrap (p, unlink (f1));
372
}
373
 
374
static int
375
os_stat (p, file, buf)
376
     host_callback *p;
377
     const char *file;
378
     struct stat *buf;
379
{
380
  /* ??? There is an issue of when to translate to the target layout.
381
     One could do that inside this function, or one could have the
382
     caller do it.  It's more flexible to let the caller do it, though
383
     I'm not sure the flexibility will ever be useful.  */
384
  return wrap (p, stat (file, buf));
385
}
386
 
387
static int
388
os_fstat (p, fd, buf)
389
     host_callback *p;
390
     int fd;
391
     struct stat *buf;
392
{
393
  if (fdbad (p, fd))
394
    return -1;
395
  /* ??? There is an issue of when to translate to the target layout.
396
     One could do that inside this function, or one could have the
397
     caller do it.  It's more flexible to let the caller do it, though
398
     I'm not sure the flexibility will ever be useful.  */
399
  return wrap (p, fstat (fdmap (p, fd), buf));
400
}
401
 
402
static int
403
os_shutdown (p)
404
     host_callback *p;
405
{
406
  int i;
407
  for (i = 0; i < MAX_CALLBACK_FDS; i++)
408
    {
409
      if (p->fdopen[i] && !p->alwaysopen[i]) {
410
        close (p->fdmap[i]);
411
        p->fdopen[i] = 0;
412
      }
413
    }
414
  return 1;
415
}
416
 
417
static int
418
os_init (p)
419
     host_callback *p;
420
{
421
  int i;
422
 
423
  os_shutdown (p);
424
  for (i = 0; i < 3; i++)
425
    {
426
      p->fdmap[i] = i;
427
      p->fdopen[i] = 1;
428
      p->alwaysopen[i] = 1;
429
    }
430
 
431
  p->syscall_map = cb_init_syscall_map;
432
  p->errno_map = cb_init_errno_map;
433
  p->open_map = cb_init_open_map;
434
 
435
  return 1;
436
}
437
 
438
/* DEPRECIATED */
439
 
440
/* VARARGS */
441
static void
442
#ifdef ANSI_PROTOTYPES
443
os_printf_filtered (host_callback *p ATTRIBUTE_UNUSED, const char *format, ...)
444
#else
445
os_printf_filtered (p, va_alist)
446
     host_callback *p;
447
     va_dcl
448
#endif
449
{
450
  va_list args;
451
#ifdef ANSI_PROTOTYPES
452
  va_start (args, format);
453
#else
454
  char *format;
455
 
456
  va_start (args);
457
  format = va_arg (args, char *);
458
#endif
459
 
460
  vfprintf (stdout, format, args);
461
  va_end (args);
462
}
463
 
464
/* VARARGS */
465
static void
466
#ifdef ANSI_PROTOTYPES
467
os_vprintf_filtered (host_callback *p ATTRIBUTE_UNUSED, const char *format, va_list args)
468
#else
469
os_vprintf_filtered (p, format, args)
470
     host_callback *p;
471
     const char *format;
472
     va_list args;
473
#endif
474
{
475
  vprintf (format, args);
476
}
477
 
478
/* VARARGS */
479
static void
480
#ifdef ANSI_PROTOTYPES
481
os_evprintf_filtered (host_callback *p ATTRIBUTE_UNUSED, const char *format, va_list args)
482
#else
483
os_evprintf_filtered (p, format, args)
484
     host_callback *p;
485
     const char *format;
486
     va_list args;
487
#endif
488
{
489
  vfprintf (stderr, format, args);
490
}
491
 
492
/* VARARGS */
493
static void
494
#ifdef ANSI_PROTOTYPES
495
os_error (host_callback *p ATTRIBUTE_UNUSED, const char *format, ...)
496
#else
497
os_error (p, va_alist)
498
     host_callback *p;
499
     va_dcl
500
#endif
501
{
502
  va_list args;
503
#ifdef ANSI_PROTOTYPES
504
  va_start (args, format);
505
#else
506
  char *format;
507
 
508
  va_start (args);
509
  format = va_arg (args, char *);
510
#endif
511
 
512
  vfprintf (stderr, format, args);
513
  fprintf (stderr, "\n");
514
 
515
  va_end (args);
516
  exit (1);
517
}
518
 
519
host_callback default_callback =
520
{
521
  os_close,
522
  os_get_errno,
523
  os_isatty,
524
  os_lseek,
525
  os_open,
526
  os_read,
527
  os_read_stdin,
528
  os_rename,
529
  os_system,
530
  os_time,
531
  os_unlink,
532
  os_write,
533
  os_write_stdout,
534
  os_flush_stdout,
535
  os_write_stderr,
536
  os_flush_stderr,
537
 
538
  os_stat,
539
  os_fstat,
540
 
541
  os_poll_quit,
542
 
543
  os_shutdown,
544
  os_init,
545
 
546
  os_printf_filtered,  /* deprecated */
547
 
548
  os_vprintf_filtered,
549
  os_evprintf_filtered,
550
  os_error,
551
 
552
  0,             /* last errno */
553
 
554
  { 0, },        /* fdmap */
555
  { 0, },        /* fdopen */
556
  { 0, },        /* alwaysopen */
557
 
558
  0, /* syscall_map */
559
  0, /* errno_map */
560
  0, /* open_map */
561
  0, /* signal_map */
562
  0, /* stat_map */
563
 
564
  HOST_CALLBACK_MAGIC,
565
};
566
 
567
/* Read in a file describing the target's system call values.
568
   E.g. maybe someone will want to use something other than newlib.
569
   This assumes that the basic system call recognition and value passing/
570
   returning is supported.  So maybe some coding/recompilation will be
571
   necessary, but not as much.
572
 
573
   If an error occurs, the existing mapping is not changed.  */
574
 
575
CB_RC
576
cb_read_target_syscall_maps (cb, file)
577
     host_callback *cb;
578
     const char *file;
579
{
580
  CB_TARGET_DEFS_MAP *syscall_map, *errno_map, *open_map, *signal_map;
581
  const char *stat_map;
582
  FILE *f;
583
 
584
  if ((f = fopen (file, "r")) == NULL)
585
    return CB_RC_ACCESS;
586
 
587
  /* ... read in and parse file ... */
588
 
589
  fclose (f);
590
  return CB_RC_NO_MEM; /* FIXME:wip */
591
 
592
  /* Free storage allocated for any existing maps.  */
593
  if (cb->syscall_map)
594
    free (cb->syscall_map);
595
  if (cb->errno_map)
596
    free (cb->errno_map);
597
  if (cb->open_map)
598
    free (cb->open_map);
599
  if (cb->signal_map)
600
    free (cb->signal_map);
601
  if (cb->stat_map)
602
    free ((PTR) cb->stat_map);
603
 
604
  cb->syscall_map = syscall_map;
605
  cb->errno_map = errno_map;
606
  cb->open_map = open_map;
607
  cb->signal_map = signal_map;
608
  cb->stat_map = stat_map;
609
 
610
  return CB_RC_OK;
611
}
612
 
613
/* Translate the target's version of a syscall number to the host's.
614
   This isn't actually the host's version, rather a canonical form.
615
   ??? Perhaps this should be renamed to ..._canon_syscall.  */
616
 
617
int
618
cb_target_to_host_syscall (cb, target_val)
619
     host_callback *cb;
620
     int target_val;
621
{
622
  CB_TARGET_DEFS_MAP *m;
623
 
624
  for (m = &cb->syscall_map[0]; m->target_val != -1; ++m)
625
    if (m->target_val == target_val)
626
      return m->host_val;
627
 
628
  return -1;
629
}
630
 
631
/* FIXME: sort tables if large.
632
   Alternatively, an obvious improvement for errno conversion is
633
   to machine generate a function with a large switch().  */
634
 
635
/* Translate the host's version of errno to the target's.  */
636
 
637
int
638
cb_host_to_target_errno (cb, host_val)
639
     host_callback *cb;
640
     int host_val;
641
{
642
  CB_TARGET_DEFS_MAP *m;
643
 
644
  for (m = &cb->errno_map[0]; m->host_val; ++m)
645
    if (m->host_val == host_val)
646
      return m->target_val;
647
 
648
  /* ??? Which error to return in this case is up for grabs.
649
     Note that some missing values may have standard alternatives.
650
     For now return 0 and require caller to deal with it.  */
651
  return 0;
652
}
653
 
654
/* Given a set of target bitmasks for the open system call,
655
   return the host equivalent.
656
   Mapping open flag values is best done by looping so there's no need
657
   to machine generate this function.  */
658
 
659
int
660
cb_target_to_host_open (cb, target_val)
661
     host_callback *cb;
662
     int target_val;
663
{
664
  int host_val = 0;
665
  CB_TARGET_DEFS_MAP *m;
666
 
667
  for (m = &cb->open_map[0]; m->host_val != -1; ++m)
668
    {
669
      switch (m->target_val)
670
        {
671
          /* O_RDONLY can be (and usually is) 0 which needs to be treated
672
             specially.  */
673
        case TARGET_O_RDONLY :
674
        case TARGET_O_WRONLY :
675
        case TARGET_O_RDWR :
676
          if ((target_val & (TARGET_O_RDONLY | TARGET_O_WRONLY | TARGET_O_RDWR))
677
              == m->target_val)
678
            host_val |= m->host_val;
679
          /* Handle the host/target differentiating between binary and
680
             text mode.  Only one case is of importance */
681
#if ! defined (TARGET_O_BINARY) && defined (O_BINARY)
682
          host_val |= O_BINARY;
683
#endif
684
          break;
685
        default :
686
          if ((m->target_val & target_val) == m->target_val)
687
            host_val |= m->host_val;
688
          break;
689
        }
690
    }
691
 
692
  return host_val;
693
}
694
 
695
/* Utility for cb_host_to_target_stat to store values in the target's
696
   stat struct.  */
697
 
698
static void
699
store (p, size, val, big_p)
700
     char *p;
701
     int size;
702
     long val; /* ??? must be as big as target word size */
703
     int big_p;
704
{
705
  if (big_p)
706
    {
707
      p += size;
708
      while (size-- > 0)
709
        {
710
          *--p = val;
711
          val >>= 8;
712
        }
713
    }
714
  else
715
    {
716
      while (size-- > 0)
717
        {
718
          *p++ = val;
719
          val >>= 8;
720
        }
721
    }
722
}
723
 
724
/* Translate a host's stat struct into a target's.
725
   If HS is NULL, just compute the length of the buffer required,
726
   TS is ignored.
727
 
728
   The result is the size of the target's stat struct,
729
   or zero if an error occured during the translation.  */
730
 
731
int
732
cb_host_to_target_stat (cb, hs, ts)
733
     host_callback *cb;
734
     const struct stat *hs;
735
     PTR ts;
736
{
737
  const char *m = cb->stat_map;
738
  char *p;
739
  int big_p = 0;
740
 
741
  if (hs == NULL)
742
    ts = NULL;
743
  p = ts;
744
 
745
  while (m)
746
    {
747
      char *q = strchr (m, ',');
748
      int size;
749
 
750
      /* FIXME: Use sscanf? */
751
      if (q == NULL)
752
        {
753
          /* FIXME: print error message */
754
          return 0;
755
        }
756
      size = atoi (q + 1);
757
      if (size == 0)
758
        {
759
          /* FIXME: print error message */
760
          return 0;
761
        }
762
 
763
      if (hs != NULL)
764
        {
765
          if (strncmp (m, "st_dev", q - m) == 0)
766
            store (p, size, hs->st_dev, big_p);
767
          else if (strncmp (m, "st_ino", q - m) == 0)
768
            store (p, size, hs->st_ino, big_p);
769
          /* FIXME:wip */
770
          else
771
            store (p, size, 0, big_p); /* unsupported field, store 0 */
772
        }
773
 
774
      p += size;
775
      m = strchr (q, ':');
776
      if (m)
777
        ++m;
778
    }
779
 
780
  return p - (char *) ts;
781
}
782
 
783
/* Cover functions to the vfprintf callbacks.
784
 
785
   ??? If one thinks of the callbacks as a subsystem onto itself [or part of
786
   a larger "remote target subsystem"] with a well defined interface, then
787
   one would think that the subsystem would provide these.  However, until
788
   one is allowed to create such a subsystem (with its own source tree
789
   independent of any particular user), such a critter can't exist.  Thus
790
   these functions are here for the time being.  */
791
 
792
void
793
sim_cb_printf (host_callback *p, const char *fmt, ...)
794
{
795
  va_list ap;
796
 
797
  va_start (ap, fmt);
798
  p->vprintf_filtered (p, fmt, ap);
799
  va_end (ap);
800
}
801
 
802
void
803
sim_cb_eprintf (host_callback *p, const char *fmt, ...)
804
{
805
  va_list ap;
806
 
807
  va_start (ap, fmt);
808
  p->evprintf_filtered (p, fmt, ap);
809
  va_end (ap);
810
}

powered by: WebSVN 2.1.0

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