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