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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gdb/] [gdb-6.8/] [sim/] [ppc/] [emul_netbsd.c] - Blame information for rev 26

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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