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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [sim/] [ppc/] [emul_netbsd.c] - Blame information for rev 1774

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

Line No. Rev Author Line
1 578 markom
/*  This file is part of the program psim.
2
 
3
    Copyright (C) 1994-1998, Andrew Cagney <cagney@highland.com.au>
4
 
5
    This program is free software; you can redistribute it and/or modify
6
    it under the terms of the GNU General Public License as published by
7
    the Free Software Foundation; either version 2 of the License, or
8
    (at your option) any later version.
9
 
10
    This program is distributed in the hope that it will be useful,
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
    GNU General Public License for more details.
14
 
15
    You should have received a copy of the GNU General Public License
16
    along with this program; if not, write to the Free Software
17
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
 
19
    */
20
 
21
 
22
#ifndef _EMUL_NETBSD_C_
23
#define _EMUL_NETBSD_C_
24
 
25
 
26
/* Note: this module is called via a table.  There is no benefit in
27
   making it inline */
28
 
29
#include "emul_generic.h"
30
#include "emul_netbsd.h"
31
 
32
#ifdef HAVE_STRING_H
33
#include <string.h>
34
#else
35
#ifdef HAVE_STRINGS_H
36
#include <strings.h>
37
#endif
38
#endif
39
 
40
#include <sys/types.h>
41
#include <sys/stat.h>
42
#include <stdio.h>
43
#include <signal.h>
44
#include <fcntl.h>
45
#include <errno.h>
46
#include <sys/errno.h>
47
#include <sys/param.h>
48
#include <sys/time.h>
49
 
50
#ifdef HAVE_GETRUSAGE
51
#ifndef HAVE_SYS_RESOURCE_H
52
#undef HAVE_GETRUSAGE
53
#endif
54
#endif
55
 
56
#ifdef HAVE_GETRUSAGE
57
#include <sys/resource.h>
58
int getrusage();
59
#endif
60
 
61
#if HAVE_SYS_IOCTL_H
62
#include <sys/ioctl.h>
63
#endif
64
 
65
#if HAVE_DIRENT_H
66
# include <dirent.h>
67
# define NAMLEN(dirent) strlen((dirent)->d_name)
68
#else
69
# define dirent direct
70
# define NAMLEN(dirent) (dirent)->d_namlen
71
# if HAVE_SYS_NDIR_H
72
#  include <sys/ndir.h>
73
# endif
74
# if HAVE_SYS_DIR_H
75
#  include <sys/dir.h>
76
# endif
77
# if HAVE_NDIR_H
78
#  include <ndir.h>
79
# endif
80
#endif
81
 
82
#ifdef HAVE_UNISTD_H
83
#undef MAXPATHLEN               /* sys/param.h might define this also */
84
#include <unistd.h>
85
#endif
86
 
87
#ifdef HAVE_STDLIB_H
88
#include <stdlib.h>
89
#endif
90
 
91
#define WITH_NetBSD_HOST (NetBSD >= 199306)
92
#if WITH_NetBSD_HOST /* here NetBSD as that is what we're emulating */
93
#include <sys/syscall.h> /* FIXME - should not be including this one */
94
#include <sys/sysctl.h>
95
#include <sys/mount.h>
96
extern int getdirentries(int fd, char *buf, int nbytes, long *basep);
97
#else
98
 
99
/* If this is not netbsd, don't allow fstatfs or getdirentries at this time */
100
#undef HAVE_FSTATFS
101
#undef HAVE_GETDIRENTRIES
102
#endif
103
 
104
#if (BSD < 199306) /* here BSD as just a bug */
105
extern int errno;
106
#endif
107
 
108
#ifndef STATIC_INLINE_EMUL_NETBSD
109
#define STATIC_INLINE_EMUL_NETBSD STATIC_INLINE
110
#endif
111
 
112
 
113
#if WITH_NetBSD_HOST
114
#define SYS(X) ASSERT(call == (SYS_##X))
115
#else
116
#define SYS(X)
117
#endif
118
 
119
#if WITH_NetBSD_HOST && (PATH_MAX != 1024)
120
#error "PATH_MAX not 1024"
121
#elif !defined(PATH_MAX)
122
#define PATH_MAX 1024
123
#endif
124
 
125
 
126
/* EMULATION
127
 
128
   NetBSD - Emulation of user programs for NetBSD/PPC
129
 
130
   DESCRIPTION
131
 
132
   */
133
 
134
 
135
/* NetBSD's idea of what is needed to implement emulations */
136
 
137
struct _os_emul_data {
138
  device *vm;
139
  emul_syscall *syscalls;
140
};
141
 
142
 
143
 
144
STATIC_INLINE_EMUL_NETBSD void
145
write_stat(unsigned_word addr,
146
           struct stat buf,
147
           cpu *processor,
148
           unsigned_word cia)
149
{
150
  H2T(buf.st_dev);
151
  H2T(buf.st_ino);
152
  H2T(buf.st_mode);
153
  H2T(buf.st_nlink);
154
  H2T(buf.st_uid);
155
  H2T(buf.st_gid);
156
  H2T(buf.st_size);
157
  H2T(buf.st_atime);
158
  /* H2T(buf.st_spare1); */
159
  H2T(buf.st_mtime);
160
  /* H2T(buf.st_spare2); */
161
  H2T(buf.st_ctime);
162
  /* H2T(buf.st_spare3); */
163
#ifdef AC_STRUCT_ST_RDEV
164
  H2T(buf.st_rdev);
165
#endif
166
#ifdef AC_STRUCT_ST_BLKSIZE
167
  H2T(buf.st_blksize);
168
#endif
169
#ifdef AC_STRUCT_ST_BLOCKS
170
  H2T(buf.st_blocks);
171
#endif
172
#if WITH_NetBSD_HOST
173
  H2T(buf.st_flags);
174
  H2T(buf.st_gen);
175
#endif
176
  emul_write_buffer(&buf, addr, sizeof(buf), processor, cia);
177
}
178
 
179
 
180
#ifdef HAVE_FSTATFS
181
STATIC_INLINE_EMUL_NETBSD void
182
write_statfs(unsigned_word addr,
183
             struct statfs buf,
184
             cpu *processor,
185
             unsigned_word cia)
186
{
187
  H2T(buf.f_type);
188
  H2T(buf.f_flags);
189
  H2T(buf.f_bsize);
190
  H2T(buf.f_iosize);
191
  H2T(buf.f_blocks);
192
  H2T(buf.f_bfree);
193
  H2T(buf.f_bavail);
194
  H2T(buf.f_files);
195
  H2T(buf.f_ffree);
196
  H2T(buf.f_fsid.val[0]);
197
  H2T(buf.f_fsid.val[1]);
198
  H2T(buf.f_owner);
199
  /* f_spare[4]; */
200
  /* f_fstypename[MFSNAMELEN]; */
201
  /* f_mntonname[MNAMELEN]; */
202
  /* f_mntfromname[MNAMELEN]; */
203
  emul_write_buffer(&buf, addr, sizeof(buf), processor, cia);
204
}
205
#endif
206
 
207
 
208
STATIC_INLINE_EMUL_NETBSD void
209
write_timeval(unsigned_word addr,
210
              struct timeval t,
211
              cpu *processor,
212
              unsigned_word cia)
213
{
214
  H2T(t.tv_sec);
215
  H2T(t.tv_usec);
216
  emul_write_buffer(&t, addr, sizeof(t), processor, cia);
217
}
218
 
219
 
220
STATIC_INLINE_EMUL_NETBSD void
221
write_timezone(unsigned_word addr,
222
               struct timezone tz,
223
               cpu *processor,
224
               unsigned_word cia)
225
{
226
  H2T(tz.tz_minuteswest);
227
  H2T(tz.tz_dsttime);
228
  emul_write_buffer(&tz, addr, sizeof(tz), processor, cia);
229
}
230
 
231
 
232
#ifdef HAVE_GETDIRENTRIES
233
STATIC_INLINE_EMUL_NETBSD void
234
write_direntries(unsigned_word addr,
235
                 char *buf,
236
                 int nbytes,
237
                 cpu *processor,
238
                 unsigned_word cia)
239
{
240
  while (nbytes > 0) {
241
    struct dirent *out;
242
    struct dirent *in = (struct dirent*)buf;
243
    ASSERT(in->d_reclen <= nbytes);
244
    out = (struct dirent*)zalloc(in->d_reclen);
245
    memcpy(out/*dest*/, in/*src*/, in->d_reclen);
246
    H2T(out->d_fileno);
247
    H2T(out->d_reclen);
248
    H2T(out->d_type);
249
    H2T(out->d_namlen);
250
    emul_write_buffer(out, addr, in->d_reclen, processor, cia);
251
    nbytes -= in->d_reclen;
252
    addr += in->d_reclen;
253
    buf += in->d_reclen;
254
    zfree(out);
255
  }
256
}
257
#endif
258
 
259
 
260
#ifdef HAVE_GETRUSAGE
261
STATIC_INLINE_EMUL_NETBSD void
262
write_rusage(unsigned_word addr,
263
             struct rusage rusage,
264
             cpu *processor,
265
             unsigned_word cia)
266
{
267
  H2T(rusage.ru_utime.tv_sec); /* user time used */
268
  H2T(rusage.ru_utime.tv_usec);
269
  H2T(rusage.ru_stime.tv_sec); /* system time used */
270
  H2T(rusage.ru_stime.tv_usec);
271
  H2T(rusage.ru_maxrss);          /* integral max resident set size */
272
  H2T(rusage.ru_ixrss);           /* integral shared text memory size */
273
  H2T(rusage.ru_idrss);           /* integral unshared data size */
274
  H2T(rusage.ru_isrss);           /* integral unshared stack size */
275
  H2T(rusage.ru_minflt);          /* page reclaims */
276
  H2T(rusage.ru_majflt);          /* page faults */
277
  H2T(rusage.ru_nswap);           /* swaps */
278
  H2T(rusage.ru_inblock);         /* block input operations */
279
  H2T(rusage.ru_oublock);         /* block output operations */
280
  H2T(rusage.ru_msgsnd);          /* messages sent */
281
  H2T(rusage.ru_msgrcv);          /* messages received */
282
  H2T(rusage.ru_nsignals);        /* signals received */
283
  H2T(rusage.ru_nvcsw);           /* voluntary context switches */
284
  H2T(rusage.ru_nivcsw);          /* involuntary context switches */
285
  emul_write_buffer(&rusage, addr, sizeof(rusage), processor, cia);
286
}
287
#endif
288
 
289
static void
290
do_exit(os_emul_data *emul,
291
        unsigned call,
292
        const int arg0,
293
        cpu *processor,
294
        unsigned_word cia)
295
{
296
  int status = (int)cpu_registers(processor)->gpr[arg0];
297
  SYS(exit);
298
  if (WITH_TRACE && ppc_trace[trace_os_emul])
299
    printf_filtered ("%d)\n", status);
300
 
301
  cpu_halt(processor, cia, was_exited, status);
302
}
303
 
304
 
305
static void
306
do_read(os_emul_data *emul,
307
        unsigned call,
308
        const int arg0,
309
        cpu *processor,
310
        unsigned_word cia)
311
{
312
  void *scratch_buffer;
313
  int d = (int)cpu_registers(processor)->gpr[arg0];
314
  unsigned_word buf = cpu_registers(processor)->gpr[arg0+1];
315
  int nbytes = cpu_registers(processor)->gpr[arg0+2];
316
  int status;
317
  SYS(read);
318
 
319
  if (WITH_TRACE && ppc_trace[trace_os_emul])
320
    printf_filtered ("%d, 0x%lx, %d", d, (long)buf, nbytes);
321
 
322
  /* get a tempoary bufer */
323
  scratch_buffer = zalloc(nbytes);
324
 
325
  /* check if buffer exists by reading it */
326
  emul_read_buffer(scratch_buffer, buf, nbytes, processor, cia);
327
 
328
  /* read */
329
#if 0
330
  if (d == 0) {
331
    status = fread (scratch_buffer, 1, nbytes, stdin);
332
    if (status == 0 && ferror (stdin))
333
      status = -1;
334
  }
335
#endif
336
  status = read (d, scratch_buffer, nbytes);
337
 
338
  emul_write_status(processor, status, errno);
339
  if (status > 0)
340
    emul_write_buffer(scratch_buffer, buf, status, processor, cia);
341
 
342
  zfree(scratch_buffer);
343
}
344
 
345
 
346
static void
347
do_write(os_emul_data *emul,
348
         unsigned call,
349
         const int arg0,
350
         cpu *processor,
351
         unsigned_word cia)
352
{
353
  void *scratch_buffer = NULL;
354
  int d = (int)cpu_registers(processor)->gpr[arg0];
355
  unsigned_word buf = cpu_registers(processor)->gpr[arg0+1];
356
  int nbytes = cpu_registers(processor)->gpr[arg0+2];
357
  int status;
358
  SYS(write);
359
 
360
  if (WITH_TRACE && ppc_trace[trace_os_emul])
361
    printf_filtered ("%d, 0x%lx, %d", d, (long)buf, nbytes);
362
 
363
  /* get a tempoary bufer */
364
  scratch_buffer = zalloc(nbytes); /* FIXME - nbytes == 0 */
365
 
366
  /* copy in */
367
  emul_read_buffer(scratch_buffer, buf, nbytes,
368
                   processor, cia);
369
 
370
  /* write */
371
  status = write(d, scratch_buffer, nbytes);
372
  emul_write_status(processor, status, errno);
373
  zfree(scratch_buffer);
374
 
375
  flush_stdoutput();
376
}
377
 
378
 
379
static void
380
do_open(os_emul_data *emul,
381
        unsigned call,
382
        const int arg0,
383
        cpu *processor,
384
        unsigned_word cia)
385
{
386
  unsigned_word path_addr = cpu_registers(processor)->gpr[arg0];
387
  char path_buf[PATH_MAX];
388
  char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia);
389
  int flags = (int)cpu_registers(processor)->gpr[arg0+1];
390
  int mode = (int)cpu_registers(processor)->gpr[arg0+2];
391
  int hostflags;
392
  int status;
393
 
394
  if (WITH_TRACE && ppc_trace[trace_os_emul])
395
    printf_filtered ("0x%lx [%s], 0x%x, 0x%x", (long)path_addr, path, flags, mode);
396
 
397
  SYS(open);
398
 
399
  /* Do some translation on 'flags' to match it to the host's version.  */
400
  /* These flag values were taken from the NetBSD 1.4 header files.  */
401
  if ((flags & 3) == 0)
402
    hostflags = O_RDONLY;
403
  else if ((flags & 3) == 1)
404
    hostflags = O_WRONLY;
405
  else
406
    hostflags = O_RDWR;
407
  if (flags & 0x00000008)
408
    hostflags |= O_APPEND;
409
  if (flags & 0x00000200)
410
    hostflags |= O_CREAT;
411
  if (flags & 0x00000400)
412
    hostflags |= O_TRUNC;
413
  if (flags & 0x00000800)
414
    hostflags |= O_EXCL;
415
 
416
  /* Can't combine these statements, cuz open sets errno. */
417
  status = open(path, hostflags, mode);
418
  emul_write_status(processor, status, errno);
419
}
420
 
421
 
422
static void
423
do_close(os_emul_data *emul,
424
         unsigned call,
425
         const int arg0,
426
         cpu *processor,
427
         unsigned_word cia)
428
{
429
  int d = (int)cpu_registers(processor)->gpr[arg0];
430
  int status;
431
 
432
  if (WITH_TRACE && ppc_trace[trace_os_emul])
433
    printf_filtered ("%d", d);
434
 
435
  SYS(close);
436
 
437
  /* Can't combine these statements, cuz close sets errno. */
438
  status = close(d);
439
  emul_write_status(processor, status, errno);
440
}
441
 
442
 
443
static void
444
do_break(os_emul_data *emul,
445
         unsigned call,
446
         const int arg0,
447
         cpu *processor,
448
         unsigned_word cia)
449
{
450
  /* just pass this onto the `vm' device */
451
  unsigned_word new_break = cpu_registers(processor)->gpr[arg0];
452
  int status;
453
 
454
  if (WITH_TRACE && ppc_trace[trace_os_emul])
455
    printf_filtered ("0x%lx", (long)cpu_registers(processor)->gpr[arg0]);
456
 
457
  SYS(break);
458
  status = device_ioctl(emul->vm,
459
                        processor,
460
                        cia,
461
                        device_ioctl_break,
462
                        new_break); /*ioctl-data*/
463
  emul_write_status(processor, 0, status);
464
}
465
 
466
 
467
#ifndef HAVE_GETPID
468
#define do_getpid 0
469
#else
470
static void
471
do_getpid(os_emul_data *emul,
472
          unsigned call,
473
          const int arg0,
474
          cpu *processor,
475
          unsigned_word cia)
476
{
477
  SYS(getpid);
478
  emul_write_status(processor, (int)getpid(), 0);
479
}
480
#endif
481
 
482
#ifndef HAVE_GETUID
483
#define do_getuid 0
484
#else
485
static void
486
do_getuid(os_emul_data *emul,
487
          unsigned call,
488
          const int arg0,
489
          cpu *processor,
490
          unsigned_word cia)
491
{
492
  SYS(getuid);
493
  emul_write_status(processor, (int)getuid(), 0);
494
}
495
#endif
496
 
497
#ifndef HAVE_GETEUID
498
#define do_geteuid 0
499
#else
500
static void
501
do_geteuid(os_emul_data *emul,
502
           unsigned call,
503
           const int arg0,
504
           cpu *processor,
505
           unsigned_word cia)
506
{
507
  SYS(geteuid);
508
  emul_write_status(processor, (int)geteuid(), 0);
509
}
510
#endif
511
 
512
#ifndef HAVE_KILL
513
#define do_kill 0
514
#else
515
static void
516
do_kill(os_emul_data *emul,
517
        unsigned call,
518
        const int arg0,
519
        cpu *processor,
520
        unsigned_word cia)
521
{
522
  pid_t pid = cpu_registers(processor)->gpr[arg0];
523
  int sig = cpu_registers(processor)->gpr[arg0+1];
524
 
525
  if (WITH_TRACE && ppc_trace[trace_os_emul])
526
    printf_filtered ("%d, %d", (int)pid, sig);
527
 
528
  SYS(kill);
529
  printf_filtered("SYS_kill at 0x%lx - more to this than just being killed\n",
530
                  (long)cia);
531
  cpu_halt(processor, cia, was_signalled, sig);
532
}
533
#endif
534
 
535
#ifndef HAVE_DUP
536
#define do_dup 0
537
#else
538
static void
539
do_dup(os_emul_data *emul,
540
       unsigned call,
541
       const int arg0,
542
       cpu *processor,
543
       unsigned_word cia)
544
{
545
  int oldd = cpu_registers(processor)->gpr[arg0];
546
  int status = dup(oldd);
547
  int err = errno;
548
 
549
  if (WITH_TRACE && ppc_trace[trace_os_emul])
550
    printf_filtered ("%d", oldd);
551
 
552
  SYS(dup);
553
  emul_write_status(processor, status, err);
554
}
555
#endif
556
 
557
#ifndef HAVE_GETEGID
558
#define do_getegid 0
559
#else
560
static void
561
do_getegid(os_emul_data *emul,
562
           unsigned call,
563
           const int arg0,
564
           cpu *processor,
565
           unsigned_word cia)
566
{
567
  SYS(getegid);
568
  emul_write_status(processor, (int)getegid(), 0);
569
}
570
#endif
571
 
572
#ifndef HAVE_GETGID
573
#define do_getgid 0
574
#else
575
static void
576
do_getgid(os_emul_data *emul,
577
          unsigned call,
578
          const int arg0,
579
          cpu *processor,
580
          unsigned_word cia)
581
{
582
  SYS(getgid);
583
  emul_write_status(processor, (int)getgid(), 0);
584
}
585
#endif
586
 
587
#ifndef HAVE_SIGPROCMASK
588
#define do_sigprocmask 0
589
#else
590
static void
591
do_sigprocmask(os_emul_data *emul,
592
               unsigned call,
593
               const int arg0,
594
               cpu *processor,
595
               unsigned_word cia)
596
{
597
  natural_word how = cpu_registers(processor)->gpr[arg0];
598
  unsigned_word set = cpu_registers(processor)->gpr[arg0+1];
599
  unsigned_word oset = cpu_registers(processor)->gpr[arg0+2];
600
#ifdef SYS_sigprocmask
601
  SYS(sigprocmask);
602
#endif
603
 
604
  if (WITH_TRACE && ppc_trace[trace_os_emul])
605
    printf_filtered ("%ld, 0x%ld, 0x%ld", (long)how, (long)set, (long)oset);
606
 
607
  emul_write_status(processor, 0, 0);
608
  cpu_registers(processor)->gpr[4] = set;
609
}
610
#endif
611
 
612
#ifndef HAVE_IOCTL
613
#define do_ioctl 0
614
#else
615
static void
616
do_ioctl(os_emul_data *emul,
617
         unsigned call,
618
         const int arg0,
619
         cpu *processor,
620
         unsigned_word cia)
621
{
622
  int d = cpu_registers(processor)->gpr[arg0];
623
  unsigned request = cpu_registers(processor)->gpr[arg0+1];
624
  unsigned_word argp_addr = cpu_registers(processor)->gpr[arg0+2];
625
 
626
#if !WITH_NetBSD_HOST
627
  cpu_registers(processor)->gpr[arg0] = 0; /* just succeed */
628
#else
629
  unsigned dir = request & IOC_DIRMASK;
630
  int status;
631
  SYS(ioctl);
632
  /* what we haven't done */
633
  if (dir & IOC_IN /* write into the io device */
634
      || dir & IOC_OUT
635
      || !(dir & IOC_VOID))
636
    error("do_ioctl() read or write of parameter not implemented\n");
637
  status = ioctl(d, request, NULL);
638
  emul_write_status(processor, status, errno);
639
#endif
640
 
641
  if (WITH_TRACE && ppc_trace[trace_os_emul])
642
    printf_filtered ("%d, 0x%x, 0x%lx", d, request, (long)argp_addr);
643
}
644
#endif
645
 
646
#ifndef HAVE_UMASK
647
#define do_umask 0
648
#else
649
static void
650
do_umask(os_emul_data *emul,
651
         unsigned call,
652
         const int arg0,
653
         cpu *processor,
654
         unsigned_word cia)
655
{
656
  int mask = cpu_registers(processor)->gpr[arg0];
657
 
658
  if (WITH_TRACE && ppc_trace[trace_os_emul])
659
    printf_filtered ("0%o", mask);
660
 
661
  SYS(umask);
662
  emul_write_status(processor, umask(mask), 0);
663
}
664
#endif
665
 
666
#ifndef HAVE_DUP2
667
#define do_dup2 0
668
#else
669
static void
670
do_dup2(os_emul_data *emul,
671
        unsigned call,
672
        const int arg0,
673
        cpu *processor,
674
        unsigned_word cia)
675
{
676
  int oldd = cpu_registers(processor)->gpr[arg0];
677
  int newd = cpu_registers(processor)->gpr[arg0+1];
678
  int status = dup2(oldd, newd);
679
  int err = errno;
680
 
681
  if (WITH_TRACE && ppc_trace[trace_os_emul])
682
    printf_filtered ("%d, %d", oldd, newd);
683
 
684
  SYS(dup2);
685
  emul_write_status(processor, status, err);
686
}
687
#endif
688
 
689
#ifndef HAVE_FCNTL
690
#define do_fcntl 0
691
#else
692
static void
693
do_fcntl(os_emul_data *emul,
694
         unsigned call,
695
         const int arg0,
696
         cpu *processor,
697
         unsigned_word cia)
698
{
699
  int fd = cpu_registers(processor)->gpr[arg0];
700
  int cmd = cpu_registers(processor)->gpr[arg0+1];
701
  int arg = cpu_registers(processor)->gpr[arg0+2];
702
  int status;
703
 
704
  if (WITH_TRACE && ppc_trace[trace_os_emul])
705
    printf_filtered ("%d, %d, %d", fd, cmd, arg);
706
 
707
  SYS(fcntl);
708
  status = fcntl(fd, cmd, arg);
709
  emul_write_status(processor, status, errno);
710
}
711
#endif
712
 
713
#ifndef HAVE_GETTIMEOFDAY
714
#define do_gettimeofday 0
715
#else
716
static void
717
do_gettimeofday(os_emul_data *emul,
718
                unsigned call,
719
                const int arg0,
720
                cpu *processor,
721
                unsigned_word cia)
722
{
723
  unsigned_word t_addr = cpu_registers(processor)->gpr[arg0];
724
  unsigned_word tz_addr = cpu_registers(processor)->gpr[arg0+1];
725
  struct timeval t;
726
  struct timezone tz;
727
  int status = gettimeofday((t_addr != 0 ? &t : NULL),
728
                            (tz_addr != 0 ? &tz : NULL));
729
  int err = errno;
730
 
731
  if (WITH_TRACE && ppc_trace[trace_os_emul])
732
    printf_filtered ("0x%lx, 0x%lx", (long)t_addr, (long)tz_addr);
733
 
734
  SYS(gettimeofday);
735
  emul_write_status(processor, status, err);
736
  if (status == 0) {
737
    if (t_addr != 0)
738
      write_timeval(t_addr, t, processor, cia);
739
    if (tz_addr != 0)
740
      write_timezone(tz_addr, tz, processor, cia);
741
  }
742
}
743
#endif
744
 
745
#ifndef HAVE_GETRUSAGE
746
#define do_getrusage 0
747
#else
748
static void
749
do_getrusage(os_emul_data *emul,
750
             unsigned call,
751
             const int arg0,
752
             cpu *processor,
753
             unsigned_word cia)
754
{
755
  int who = cpu_registers(processor)->gpr[arg0];
756
  unsigned_word rusage_addr = cpu_registers(processor)->gpr[arg0+1];
757
  struct rusage rusage;
758
  int status = getrusage(who, (rusage_addr != 0 ? &rusage : NULL));
759
  int err = errno;
760
 
761
  if (WITH_TRACE && ppc_trace[trace_os_emul])
762
    printf_filtered ("%d, 0x%lx", who, (long)rusage_addr);
763
 
764
  SYS(getrusage);
765
  emul_write_status(processor, status, err);
766
  if (status == 0) {
767
    if (rusage_addr != 0)
768
      write_rusage(rusage_addr, rusage, processor, cia);
769
  }
770
}
771
#endif
772
 
773
 
774
#ifndef HAVE_FSTATFS
775
#define do_fstatfs 0
776
#else
777
static void
778
do_fstatfs(os_emul_data *emul,
779
           unsigned call,
780
           const int arg0,
781
           cpu *processor,
782
           unsigned_word cia)
783
{
784
  int fd = cpu_registers(processor)->gpr[arg0];
785
  unsigned_word buf_addr = cpu_registers(processor)->gpr[arg0+1];
786
  struct statfs buf;
787
  int status;
788
 
789
  if (WITH_TRACE && ppc_trace[trace_os_emul])
790
    printf_filtered ("%d, 0x%lx", fd, (long)buf_addr);
791
 
792
  SYS(fstatfs);
793
  status = fstatfs(fd, (buf_addr == 0 ? NULL : &buf));
794
  emul_write_status(processor, status, errno);
795
  if (status == 0) {
796
    if (buf_addr != 0)
797
      write_statfs(buf_addr, buf, processor, cia);
798
  }
799
}
800
#endif
801
 
802
#ifndef HAVE_STAT
803
#define do_stat 0
804
#else
805
static void
806
do_stat(os_emul_data *emul,
807
        unsigned call,
808
        const int arg0,
809
        cpu *processor,
810
        unsigned_word cia)
811
{
812
  char path_buf[PATH_MAX];
813
  unsigned_word path_addr = cpu_registers(processor)->gpr[arg0];
814
  unsigned_word stat_buf_addr = cpu_registers(processor)->gpr[arg0+1];
815
  char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia);
816
  struct stat buf;
817
  int status;
818
#ifdef SYS_stat
819
  SYS(stat);
820
#endif
821
  status = stat(path, &buf);
822
  emul_write_status(processor, status, errno);
823
  if (status == 0)
824
    write_stat(stat_buf_addr, buf, processor, cia);
825
}
826
#endif
827
 
828
#ifndef HAVE_FSTAT
829
#define do_fstat 0
830
#else
831
static void
832
do_fstat(os_emul_data *emul,
833
         unsigned call,
834
         const int arg0,
835
         cpu *processor,
836
         unsigned_word cia)
837
{
838
  int fd = cpu_registers(processor)->gpr[arg0];
839
  unsigned_word stat_buf_addr = cpu_registers(processor)->gpr[arg0+1];
840
  struct stat buf;
841
  int status;
842
#ifdef SYS_fstat
843
  SYS(fstat);
844
#endif
845
  /* Can't combine these statements, cuz fstat sets errno. */
846
  status = fstat(fd, &buf);
847
  emul_write_status(processor, status, errno);
848
  write_stat(stat_buf_addr, buf, processor, cia);
849
}
850
#endif
851
 
852
#ifndef HAVE_LSTAT
853
#define do_lstat 0
854
#else
855
static void
856
do_lstat(os_emul_data *emul,
857
         unsigned call,
858
         const int arg0,
859
         cpu *processor,
860
         unsigned_word cia)
861
{
862
  char path_buf[PATH_MAX];
863
  unsigned_word path_addr = cpu_registers(processor)->gpr[arg0];
864
  char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia);
865
  unsigned_word stat_buf_addr = cpu_registers(processor)->gpr[arg0+1];
866
  struct stat buf;
867
  int status;
868
#ifdef SYS_lstat
869
  SYS(lstat);
870
#endif
871
  /* Can't combine these statements, cuz lstat sets errno. */
872
  status = lstat(path, &buf);
873
  emul_write_status(processor, status, errno);
874
  write_stat(stat_buf_addr, buf, processor, cia);
875
}
876
#endif
877
 
878
#ifndef HAVE_GETDIRENTRIES
879
#define do_getdirentries 0
880
#else
881
static void
882
do_getdirentries(os_emul_data *emul,
883
                 unsigned call,
884
                 const int arg0,
885
                 cpu *processor,
886
                 unsigned_word cia)
887
{
888
  int fd = cpu_registers(processor)->gpr[arg0];
889
  unsigned_word buf_addr = cpu_registers(processor)->gpr[arg0+1];
890
  char *buf;
891
  int nbytes = cpu_registers(processor)->gpr[arg0+2];
892
  unsigned_word basep_addr = cpu_registers(processor)->gpr[arg0+3];
893
  long basep;
894
  int status;
895
#ifdef SYS_getdirentries
896
  SYS(getdirentries);
897
#endif
898
  if (buf_addr != 0 && nbytes >= 0)
899
    buf = zalloc(nbytes);
900
  else
901
    buf = NULL;
902
  status = getdirentries(fd,
903
                         (buf_addr == 0 ? NULL : buf),
904
                         nbytes,
905
                         (basep_addr == 0 ? NULL : &basep));
906
  emul_write_status(processor, status, errno);
907
  if (basep_addr != 0)
908
    emul_write_word(basep_addr, basep, processor, cia);
909
  if (status > 0)
910
    write_direntries(buf_addr, buf, status, processor, cia);
911
  if (buf != NULL)
912
    zfree(buf);
913
}
914
#endif
915
 
916
 
917
static void
918
do___syscall(os_emul_data *emul,
919
             unsigned call,
920
             const int arg0,
921
             cpu *processor,
922
             unsigned_word cia)
923
{
924
  SYS(__syscall);
925
  emul_do_system_call(emul,
926
                      emul->syscalls,
927
                      cpu_registers(processor)->gpr[arg0],
928
                      arg0 + 1,
929
                      processor,
930
                      cia);
931
}
932
 
933
#ifndef HAVE_LSEEK
934
#define do_lseek 0
935
#else
936
static void
937
do_lseek(os_emul_data *emul,
938
         unsigned call,
939
         const int arg0,
940
         cpu *processor,
941
         unsigned_word cia)
942
{
943
  int fildes = cpu_registers(processor)->gpr[arg0];
944
  off_t offset = emul_read_gpr64(processor, arg0+2);
945
  int whence = cpu_registers(processor)->gpr[arg0+4];
946
  off_t status;
947
  SYS(lseek);
948
  status = lseek(fildes, offset, whence);
949
  if (status == -1)
950
    emul_write_status(processor, -1, errno);
951
  else {
952
    emul_write_status(processor, 0, 0); /* success */
953
    emul_write_gpr64(processor, 3, status);
954
  }
955
}
956
#endif
957
 
958
static void
959
do___sysctl(os_emul_data *emul,
960
            unsigned call,
961
            const int arg0,
962
            cpu *processor,
963
            unsigned_word cia)
964
{
965
  /* call the arguments by their real name */
966
  unsigned_word name = cpu_registers(processor)->gpr[arg0];
967
  natural_word namelen = cpu_registers(processor)->gpr[arg0+1];
968
  unsigned_word oldp = cpu_registers(processor)->gpr[arg0+2];
969
  unsigned_word oldlenp = cpu_registers(processor)->gpr[arg0+3];
970
  natural_word oldlen;
971
  natural_word mib;
972
  natural_word int_val;
973
  SYS(__sysctl);
974
 
975
  /* pluck out the management information base id */
976
  if (namelen < 1)
977
    error("system_call()SYS___sysctl bad name[0]\n");
978
  mib = vm_data_map_read_word(cpu_data_map(processor),
979
                              name,
980
                              processor,
981
                              cia);
982
  name += sizeof(mib);
983
 
984
  /* see what to do with it ... */
985
  switch ((int)mib) {
986
  case 6/*CTL_HW*/:
987
#if WITH_NetBSD_HOST && (CTL_HW != 6)
988
#  error "CTL_HW"
989
#endif
990
    if (namelen < 2)
991
      error("system_call()SYS___sysctl - CTL_HW - bad name[1]\n");
992
    mib = vm_data_map_read_word(cpu_data_map(processor),
993
                                name,
994
                                processor,
995
                                cia);
996
    name += sizeof(mib);
997
    switch ((int)mib) {
998
    case 7/*HW_PAGESIZE*/:
999
#if WITH_NetBSD_HOST && (HW_PAGESIZE != 7)
1000
#  error "HW_PAGESIZE"
1001
#endif
1002
      oldlen = vm_data_map_read_word(cpu_data_map(processor),
1003
                                     oldlenp,
1004
                                     processor,
1005
                                     cia);
1006
      if (sizeof(natural_word) > oldlen)
1007
        error("system_call()sysctl - CTL_HW.HW_PAGESIZE - to small\n");
1008
      int_val = 8192;
1009
      oldlen = sizeof(int_val);
1010
      emul_write_word(oldp, int_val, processor, cia);
1011
      emul_write_word(oldlenp, oldlen, processor, cia);
1012
      break;
1013
    default:
1014
      error("sysctl() CTL_HW.%d unknown\n", mib);
1015
      break;
1016
    }
1017
    break;
1018
  default:
1019
    error("sysctl() name[0]=%d unknown\n", (int)mib);
1020
    break;
1021
  }
1022
  emul_write_status(processor, 0, 0); /* always succeed */
1023
}
1024
 
1025
 
1026
 
1027
static emul_syscall_descriptor netbsd_descriptors[] = {
1028
  /* 0 */ { 0, "syscall" },
1029
  /* 1 */ { do_exit, "exit" },
1030
  /* 2 */ { 0, "fork" },
1031
  /* 3 */ { do_read, "read" },
1032
  /* 4 */ { do_write, "write" },
1033
  /* 5 */ { do_open, "open" },
1034
  /* 6 */ { do_close, "close" },
1035
  /* 7 */ { 0, "wait4" },
1036
  { 0, }, /* 8 is old creat */
1037
  /* 9 */ { 0, "link" },
1038
  /* 10 */ { 0, "unlink" },
1039
  { 0, }, /* 11 is obsolete execv */
1040
  /* 12 */ { 0, "chdir" },
1041
  /* 13 */ { 0, "fchdir" },
1042
  /* 14 */ { 0, "mknod" },
1043
  /* 15 */ { 0, "chmod" },
1044
  /* 16 */ { 0, "chown" },
1045
  /* 17 */ { do_break, "break" },
1046
  /* 18 */ { 0, "getfsstat" },
1047
  { 0, }, /* 19 is old lseek */
1048
  /* 20 */ { do_getpid, "getpid" },
1049
  /* 21 */ { 0, "mount" },
1050
  /* 22 */ { 0, "unmount" },
1051
  /* 23 */ { 0, "setuid" },
1052
  /* 24 */ { do_getuid, "getuid" },
1053
  /* 25 */ { do_geteuid, "geteuid" },
1054
  /* 26 */ { 0, "ptrace" },
1055
  /* 27 */ { 0, "recvmsg" },
1056
  /* 28 */ { 0, "sendmsg" },
1057
  /* 29 */ { 0, "recvfrom" },
1058
  /* 30 */ { 0, "accept" },
1059
  /* 31 */ { 0, "getpeername" },
1060
  /* 32 */ { 0, "getsockname" },
1061
  /* 33 */ { 0, "access" },
1062
  /* 34 */ { 0, "chflags" },
1063
  /* 35 */ { 0, "fchflags" },
1064
  /* 36 */ { 0, "sync" },
1065
  /* 37 */ { do_kill, "kill" },
1066
  { 0, }, /* 38 is old stat */
1067
  /* 39 */ { 0, "getppid" },
1068
  { 0, }, /* 40 is old lstat */
1069
  /* 41 */ { do_dup, "dup" },
1070
  /* 42 */ { 0, "pipe" },
1071
  /* 43 */ { do_getegid, "getegid" },
1072
  /* 44 */ { 0, "profil" },
1073
  /* 45 */ { 0, "ktrace" },
1074
  /* 46 */ { 0, "sigaction" },
1075
  /* 47 */ { do_getgid, "getgid" },
1076
  /* 48 */ { do_sigprocmask, "sigprocmask" },
1077
  /* 49 */ { 0, "getlogin" },
1078
  /* 50 */ { 0, "setlogin" },
1079
  /* 51 */ { 0, "acct" },
1080
  /* 52 */ { 0, "sigpending" },
1081
  /* 53 */ { 0, "sigaltstack" },
1082
  /* 54 */ { do_ioctl, "ioctl" },
1083
  /* 55 */ { 0, "reboot" },
1084
  /* 56 */ { 0, "revoke" },
1085
  /* 57 */ { 0, "symlink" },
1086
  /* 58 */ { 0, "readlink" },
1087
  /* 59 */ { 0, "execve" },
1088
  /* 60 */ { do_umask, "umask" },
1089
  /* 61 */ { 0, "chroot" },
1090
  { 0, }, /* 62 is old fstat */
1091
  { 0, }, /* 63 is old getkerninfo */
1092
  { 0, }, /* 64 is old getpagesize */
1093
  /* 65 */ { 0, "msync" },
1094
  /* 66 */ { 0, "vfork" },
1095
  { 0, }, /* 67 is obsolete vread */
1096
  { 0, }, /* 68 is obsolete vwrite */
1097
  /* 69 */ { 0, "sbrk" },
1098
  /* 70 */ { 0, "sstk" },
1099
  { 0, }, /* 71 is old mmap */
1100
  /* 72 */ { 0, "vadvise" },
1101
  /* 73 */ { 0, "munmap" },
1102
  /* 74 */ { 0, "mprotect" },
1103
  /* 75 */ { 0, "madvise" },
1104
  { 0, }, /* 76 is obsolete vhangup */
1105
  { 0, }, /* 77 is obsolete vlimit */
1106
  /* 78 */ { 0, "mincore" },
1107
  /* 79 */ { 0, "getgroups" },
1108
  /* 80 */ { 0, "setgroups" },
1109
  /* 81 */ { 0, "getpgrp" },
1110
  /* 82 */ { 0, "setpgid" },
1111
  /* 83 */ { 0, "setitimer" },
1112
  { 0, }, /* 84 is old wait */
1113
  /* 85 */ { 0, "swapon" },
1114
  /* 86 */ { 0, "getitimer" },
1115
  { 0, }, /* 87 is old gethostname */
1116
  { 0, }, /* 88 is old sethostname */
1117
  { 0, }, /* 89 is old getdtablesize */
1118
  { do_dup2, "dup2" },
1119
  { 0, }, /* 91 */
1120
  /* 92 */ { do_fcntl, "fcntl" },
1121
  /* 93 */ { 0, "select" },
1122
  { 0, }, /* 94 */
1123
  /* 95 */ { 0, "fsync" },
1124
  /* 96 */ { 0, "setpriority" },
1125
  /* 97 */ { 0, "socket" },
1126
  /* 98 */ { 0, "connect" },
1127
  { 0, }, /* 99 is old accept */
1128
  /* 100 */ { 0, "getpriority" },
1129
  { 0, }, /* 101 is old send */
1130
  { 0, }, /* 102 is old recv */
1131
  /* 103 */ { 0, "sigreturn" },
1132
  /* 104 */ { 0, "bind" },
1133
  /* 105 */ { 0, "setsockopt" },
1134
  /* 106 */ { 0, "listen" },
1135
  { 0, }, /* 107 is obsolete vtimes */
1136
  { 0, }, /* 108 is old sigvec */
1137
  { 0, }, /* 109 is old sigblock */
1138
  { 0, }, /* 110 is old sigsetmask */
1139
  /* 111 */ { 0, "sigsuspend" },
1140
  { 0, }, /* 112 is old sigstack */
1141
  { 0, }, /* 113 is old recvmsg */
1142
  { 0, }, /* 114 is old sendmsg */
1143
  /* - is obsolete vtrace */ { 0, "vtrace        115" },
1144
  /* 116 */ { do_gettimeofday, "gettimeofday" },
1145
  /* 117 */ { do_getrusage, "getrusage" },
1146
  /* 118 */ { 0, "getsockopt" },
1147
  /* 119 */ { 0, "resuba" },
1148
  /* 120 */ { 0, "readv" },
1149
  /* 121 */ { 0, "writev" },
1150
  /* 122 */ { 0, "settimeofday" },
1151
  /* 123 */ { 0, "fchown" },
1152
  /* 124 */ { 0, "fchmod" },
1153
  { 0, }, /* 125 is old recvfrom */
1154
  { 0, }, /* 126 is old setreuid */
1155
  { 0, }, /* 127 is old setregid */
1156
  /* 128 */ { 0, "rename" },
1157
  { 0, }, /* 129 is old truncate */
1158
  { 0, }, /* 130 is old ftruncate */
1159
  /* 131 */ { 0, "flock" },
1160
  /* 132 */ { 0, "mkfifo" },
1161
  /* 133 */ { 0, "sendto" },
1162
  /* 134 */ { 0, "shutdown" },
1163
  /* 135 */ { 0, "socketpair" },
1164
  /* 136 */ { 0, "mkdir" },
1165
  /* 137 */ { 0, "rmdir" },
1166
  /* 138 */ { 0, "utimes" },
1167
  { 0, }, /* 139 is obsolete 4.2 sigreturn */
1168
  /* 140 */ { 0, "adjtime" },
1169
  { 0, }, /* 141 is old getpeername */
1170
  { 0, }, /* 142 is old gethostid */
1171
  { 0, }, /* 143 is old sethostid */
1172
  { 0, }, /* 144 is old getrlimit */
1173
  { 0, }, /* 145 is old setrlimit */
1174
  { 0, }, /* 146 is old killpg */
1175
  /* 147 */ { 0, "setsid" },
1176
  /* 148 */ { 0, "quotactl" },
1177
  { 0, }, /* 149 is old quota */
1178
  { 0, }, /* 150 is old getsockname */
1179
  { 0, }, /* 151 */
1180
  { 0, }, /* 152 */
1181
  { 0, }, /* 153 */
1182
  { 0, }, /* 154 */
1183
  /* 155 */ { 0, "nfssvc" },
1184
  { 0, }, /* 156 is old getdirentries */
1185
  /* 157 */ { 0, "statfs" },
1186
  /* 158 */ { do_fstatfs, "fstatfs" },
1187
  { 0, }, /* 159 */
1188
  { 0, }, /* 160 */
1189
  /* 161 */ { 0, "getfh" },
1190
  { 0, }, /* 162 is old getdomainname */
1191
  { 0, }, /* 163 is old setdomainname */
1192
  { 0, }, /* 164 is old uname */
1193
  /* 165 */ { 0, "sysarch" },
1194
  { 0, }, /* 166 */
1195
  { 0, }, /* 167 */
1196
  { 0, }, /* 168 */
1197
  /* 169 */ { 0, "semsys" },
1198
  /* 170 */ { 0, "msgsys" },
1199
  /* 171 */ { 0, "shmsys" },
1200
  { 0, }, /* 172 */
1201
  { 0, }, /* 173 */
1202
  { 0, }, /* 174 */
1203
  { 0, }, /* 175 */
1204
  { 0, }, /* 176 */
1205
  { 0, }, /* 177 */
1206
  { 0, }, /* 178 */
1207
  { 0, }, /* 179 */
1208
  { 0, }, /* 180 */
1209
  /* 181 */ { 0, "setgid" },
1210
  /* 182 */ { 0, "setegid" },
1211
  /* 183 */ { 0, "seteuid" },
1212
  /* 184 */ { 0, "lfs_bmapv" },
1213
  /* 185 */ { 0, "lfs_markv" },
1214
  /* 186 */ { 0, "lfs_segclean" },
1215
  /* 187 */ { 0, "lfs_segwait" },
1216
  /* 188 */ { do_stat, "stat" },
1217
  /* 189 */ { do_fstat, "fstat" },
1218
  /* 190 */ { do_lstat, "lstat" },
1219
  /* 191 */ { 0, "pathconf" },
1220
  /* 192 */ { 0, "fpathconf" },
1221
  { 0, }, /* 193 */
1222
  /* 194 */ { 0, "getrlimit" },
1223
  /* 195 */ { 0, "setrlimit" },
1224
  /* 196 */ { do_getdirentries, "getdirentries" },
1225
  /* 197 */ { 0, "mmap" },
1226
  /* 198 */ { do___syscall, "__syscall" },
1227
  /* 199 */ { do_lseek, "lseek" },
1228
  /* 200 */ { 0, "truncate" },
1229
  /* 201 */ { 0, "ftruncate" },
1230
  /* 202 */ { do___sysctl, "__sysctl" },
1231
  /* 203 */ { 0, "mlock" },
1232
  /* 204 */ { 0, "munlock" },
1233
};
1234
 
1235
static char *(netbsd_error_names[]) = {
1236
  /* 0 */ "ESUCCESS",
1237
  /* 1 */ "EPERM",
1238
  /* 2 */ "ENOENT",
1239
  /* 3 */ "ESRCH",
1240
  /* 4 */ "EINTR",
1241
  /* 5 */ "EIO",
1242
  /* 6 */ "ENXIO",
1243
  /* 7 */ "E2BIG",
1244
  /* 8 */ "ENOEXEC",
1245
  /* 9 */ "EBADF",
1246
  /* 10 */ "ECHILD",
1247
  /* 11 */ "EDEADLK",
1248
  /* 12 */ "ENOMEM",
1249
  /* 13 */ "EACCES",
1250
  /* 14 */ "EFAULT",
1251
  /* 15 */ "ENOTBLK",
1252
  /* 16 */ "EBUSY",
1253
  /* 17 */ "EEXIST",
1254
  /* 18 */ "EXDEV",
1255
  /* 19 */ "ENODEV",
1256
  /* 20 */ "ENOTDIR",
1257
  /* 21 */ "EISDIR",
1258
  /* 22 */ "EINVAL",
1259
  /* 23 */ "ENFILE",
1260
  /* 24 */ "EMFILE",
1261
  /* 25 */ "ENOTTY",
1262
  /* 26 */ "ETXTBSY",
1263
  /* 27 */ "EFBIG",
1264
  /* 28 */ "ENOSPC",
1265
  /* 29 */ "ESPIPE",
1266
  /* 30 */ "EROFS",
1267
  /* 31 */ "EMLINK",
1268
  /* 32 */ "EPIPE",
1269
  /* 33 */ "EDOM",
1270
  /* 34 */ "ERANGE",
1271
  /* 35 */ "EAGAIN",
1272
  /* 36 */ "EINPROGRESS",
1273
  /* 37 */ "EALREADY",
1274
  /* 38 */ "ENOTSOCK",
1275
  /* 39 */ "EDESTADDRREQ",
1276
  /* 40 */ "EMSGSIZE",
1277
  /* 41 */ "EPROTOTYPE",
1278
  /* 42 */ "ENOPROTOOPT",
1279
  /* 43 */ "EPROTONOSUPPORT",
1280
  /* 44 */ "ESOCKTNOSUPPORT",
1281
  /* 45 */ "EOPNOTSUPP",
1282
  /* 46 */ "EPFNOSUPPORT",
1283
  /* 47 */ "EAFNOSUPPORT",
1284
  /* 48 */ "EADDRINUSE",
1285
  /* 49 */ "EADDRNOTAVAIL",
1286
  /* 50 */ "ENETDOWN",
1287
  /* 51 */ "ENETUNREACH",
1288
  /* 52 */ "ENETRESET",
1289
  /* 53 */ "ECONNABORTED",
1290
  /* 54 */ "ECONNRESET",
1291
  /* 55 */ "ENOBUFS",
1292
  /* 56 */ "EISCONN",
1293
  /* 57 */ "ENOTCONN",
1294
  /* 58 */ "ESHUTDOWN",
1295
  /* 59 */ "ETOOMANYREFS",
1296
  /* 60 */ "ETIMEDOUT",
1297
  /* 61 */ "ECONNREFUSED",
1298
  /* 62 */ "ELOOP",
1299
  /* 63 */ "ENAMETOOLONG",
1300
  /* 64 */ "EHOSTDOWN",
1301
  /* 65 */ "EHOSTUNREACH",
1302
  /* 66 */ "ENOTEMPTY",
1303
  /* 67 */ "EPROCLIM",
1304
  /* 68 */ "EUSERS",
1305
  /* 69 */ "EDQUOT",
1306
  /* 70 */ "ESTALE",
1307
  /* 71 */ "EREMOTE",
1308
  /* 72 */ "EBADRPC",
1309
  /* 73 */ "ERPCMISMATCH",
1310
  /* 74 */ "EPROGUNAVAIL",
1311
  /* 75 */ "EPROGMISMATCH",
1312
  /* 76 */ "EPROCUNAVAIL",
1313
  /* 77 */ "ENOLCK",
1314
  /* 78 */ "ENOSYS",
1315
  /* 79 */ "EFTYPE",
1316
  /* 80 */ "EAUTH",
1317
  /* 81 */ "ENEEDAUTH",
1318
  /* 81 */ "ELAST",
1319
};
1320
 
1321
static char *(netbsd_signal_names[]) = {
1322
  /* 0 */ 0,
1323
  /* 1 */ "SIGHUP",
1324
  /* 2 */ "SIGINT",
1325
  /* 3 */ "SIGQUIT",
1326
  /* 4 */ "SIGILL",
1327
  /* 5 */ "SIGTRAP",
1328
  /* 6 */ "SIGABRT",
1329
  /* 7 */ "SIGEMT",
1330
  /* 8 */ "SIGFPE",
1331
  /* 9 */ "SIGKILL",
1332
  /* 10 */ "SIGBUS",
1333
  /* 11 */ "SIGSEGV",
1334
  /* 12 */ "SIGSYS",
1335
  /* 13 */ "SIGPIPE",
1336
  /* 14 */ "SIGALRM",
1337
  /* 15 */ "SIGTERM",
1338
  /* 16 */ "SIGURG",
1339
  /* 17 */ "SIGSTOP",
1340
  /* 18 */ "SIGTSTP",
1341
  /* 19 */ "SIGCONT",
1342
  /* 20 */ "SIGCHLD",
1343
  /* 21 */ "SIGTTIN",
1344
  /* 22 */ "SIGTTOU",
1345
  /* 23 */ "SIGIO",
1346
  /* 24 */ "SIGXCPU",
1347
  /* 25 */ "SIGXFSZ",
1348
  /* 26 */ "SIGVTALRM",
1349
  /* 27 */ "SIGPROF",
1350
  /* 28 */ "SIGWINCH",
1351
  /* 29 */ "SIGINFO",
1352
  /* 30 */ "SIGUSR1",
1353
  /* 31 */ "SIGUSR2",
1354
};
1355
 
1356
static emul_syscall emul_netbsd_syscalls = {
1357
  netbsd_descriptors,
1358
  sizeof(netbsd_descriptors) / sizeof(netbsd_descriptors[0]),
1359
  netbsd_error_names,
1360
  sizeof(netbsd_error_names) / sizeof(netbsd_error_names[0]),
1361
  netbsd_signal_names,
1362
  sizeof(netbsd_signal_names) / sizeof(netbsd_signal_names[0]),
1363
};
1364
 
1365
 
1366
/* NetBSD's os_emul interface, most are just passed on to the generic
1367
   syscall stuff */
1368
 
1369
static os_emul_data *
1370
emul_netbsd_create(device *root,
1371
                   bfd *image,
1372
                   const char *name)
1373
{
1374
  unsigned_word top_of_stack;
1375
  unsigned stack_size;
1376
  int elf_binary;
1377
  os_emul_data *bsd_data;
1378
  device *vm;
1379
 
1380
  /* check that this emulation is really for us */
1381
  if (name != NULL && strcmp(name, "netbsd") != 0)
1382
    return NULL;
1383
  if (image == NULL)
1384
    return NULL;
1385
 
1386
 
1387
  /* merge any emulation specific entries into the device tree */
1388
 
1389
  /* establish a few defaults */
1390
  if (image->xvec->flavour == bfd_target_elf_flavour) {
1391
    elf_binary = 1;
1392
    top_of_stack = 0xe0000000;
1393
    stack_size =   0x00100000;
1394
  }
1395
  else {
1396
    elf_binary = 0;
1397
    top_of_stack = 0x20000000;
1398
    stack_size =   0x00100000;
1399
  }
1400
 
1401
  /* options */
1402
  emul_add_tree_options(root, image, "netbsd",
1403
                        (WITH_ENVIRONMENT == USER_ENVIRONMENT
1404
                         ? "user" : "virtual"),
1405
 
1406
 
1407
  /* virtual memory - handles growth of stack/heap */
1408
  vm = tree_parse(root, "/openprom/vm");
1409
  tree_parse(vm, "./stack-base 0x%lx",
1410
             (unsigned long)(top_of_stack - stack_size));
1411
  tree_parse(vm, "./nr-bytes 0x%x", stack_size);
1412
 
1413
  tree_parse(root, "/openprom/vm/map-binary/file-name %s",
1414
             bfd_get_filename(image));
1415
 
1416
  /* finish the init */
1417
  tree_parse(root, "/openprom/init/register/pc 0x%lx",
1418
             (unsigned long)bfd_get_start_address(image));
1419
  tree_parse(root, "/openprom/init/register/sp 0x%lx",
1420
             (unsigned long)top_of_stack);
1421
  tree_parse(root, "/openprom/init/register/msr 0x%x",
1422
             ((tree_find_boolean_property(root, "/options/little-endian?")
1423
               ? msr_little_endian_mode
1424
               : 0)
1425
              | (tree_find_boolean_property(root, "/openprom/options/floating-point?")
1426
                 ? (msr_floating_point_available
1427
                    | msr_floating_point_exception_mode_0
1428
                    | msr_floating_point_exception_mode_1)
1429
                 : 0)));
1430
  tree_parse(root, "/openprom/init/stack/stack-type %s",
1431
             (elf_binary ? "ppc-elf" : "ppc-xcoff"));
1432
 
1433
  /* finally our emulation data */
1434
  bsd_data = ZALLOC(os_emul_data);
1435
  bsd_data->vm = vm;
1436
  bsd_data->syscalls = &emul_netbsd_syscalls;
1437
  return bsd_data;
1438
}
1439
 
1440
static void
1441
emul_netbsd_init(os_emul_data *emul_data,
1442
                 int nr_cpus)
1443
{
1444
  /* nothing yet */
1445
}
1446
 
1447
static void
1448
emul_netbsd_system_call(cpu *processor,
1449
                        unsigned_word cia,
1450
                        os_emul_data *emul_data)
1451
{
1452
  emul_do_system_call(emul_data,
1453
                      emul_data->syscalls,
1454
                      cpu_registers(processor)->gpr[0],
1455
                      3, /*r3 contains arg0*/
1456
                      processor,
1457
                      cia);
1458
}
1459
 
1460
const os_emul emul_netbsd = {
1461
  "netbsd",
1462
  emul_netbsd_create,
1463
  emul_netbsd_init,
1464
  emul_netbsd_system_call,
1465
  0, /*instruction_call*/
1466
 
1467
};
1468
 
1469
#endif _EMUL_NETBSD_C_

powered by: WebSVN 2.1.0

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