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