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