]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/ppc/emul_netbsd.c
sim: ppc: drop natural types
[thirdparty/binutils-gdb.git] / sim / ppc / emul_netbsd.c
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
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, see <http://www.gnu.org/licenses/>.
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 "defs.h"
29
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>
39
40 #include "emul_generic.h"
41 #include "emul_netbsd.h"
42
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>
51 int 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
80 #include <stdlib.h>
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>
86 #include <sys/mount.h>
87 extern int getdirentries(int fd, char *buf, int nbytes, long *basep);
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
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
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
132 struct _os_emul_data {
133 device *vm;
134 emul_syscall *syscalls;
135 };
136
137
138
139 STATIC_INLINE_EMUL_NETBSD void
140 write_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
176 STATIC_INLINE_EMUL_NETBSD void
177 write_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
203 STATIC_INLINE_EMUL_NETBSD void
204 write_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
214 #ifdef HAVE_GETTIMEOFDAY
215 STATIC_INLINE_EMUL_NETBSD void
216 write_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 }
225 #endif
226
227 #ifdef HAVE_GETDIRENTRIES
228 STATIC_INLINE_EMUL_NETBSD void
229 write_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;
249 free(out);
250 }
251 }
252 #endif
253
254
255 #ifdef HAVE_GETRUSAGE
256 STATIC_INLINE_EMUL_NETBSD void
257 write_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
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
289 static 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
298 static int
299 fdbad (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
309 static void
310 do_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
325 static void
326 do_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
356 status = fdbad (d);
357 if (status == 0)
358 status = read (d, scratch_buffer, nbytes);
359
360 emul_write_status(processor, status, errno);
361 if (status > 0)
362 emul_write_buffer(scratch_buffer, buf, status, processor, cia);
363
364 free(scratch_buffer);
365 }
366
367
368 static void
369 do_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 */
393 status = fdbad (d);
394 if (status == 0)
395 status = write(d, scratch_buffer, nbytes);
396
397 emul_write_status(processor, status, errno);
398 free(scratch_buffer);
399
400 flush_stdoutput();
401 }
402
403
404 static void
405 do_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];
416 int hostflags;
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
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
441 /* Can't combine these statements, cuz open sets errno. */
442 status = open(path, hostflags, mode);
443 emul_write_status(processor, status, errno);
444 }
445
446
447 static void
448 do_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
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
476 emul_write_status(processor, status, errno);
477 }
478
479
480 static void
481 do_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
507 static void
508 do_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
522 static void
523 do_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
537 static void
538 do_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
552 static void
553 do_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
575 static void
576 do_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];
583 int status = (fdbad (oldd) < 0) ? -1 : dup(oldd);
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
597 static void
598 do_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
612 static void
613 do_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
627 static void
628 do_sigprocmask(os_emul_data *emul,
629 unsigned call,
630 const int arg0,
631 cpu *processor,
632 unsigned_word cia)
633 {
634 signed_word how = cpu_registers(processor)->gpr[arg0];
635 unsigned_word set = cpu_registers(processor)->gpr[arg0+1];
636 unsigned_word oset = cpu_registers(processor)->gpr[arg0+2];
637 #ifdef SYS_sigprocmask
638 SYS(sigprocmask);
639 #endif
640
641 if (WITH_TRACE && ppc_trace[trace_os_emul])
642 printf_filtered ("%ld, 0x%lx, 0x%lx", (long)how, (long)set, (long)oset);
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
652 static void
653 do_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");
674 status = fdbad (d);
675 if (status == 0)
676 status = ioctl(d, request, NULL);
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
688 static void
689 do_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
708 static void
709 do_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];
717 int status = (fdbad (oldd) < 0) ? -1 : dup2(oldd, newd);
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
731 static void
732 do_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);
747 status = fdbad (fd);
748 if (status == 0)
749 status = fcntl(fd, cmd, arg);
750 emul_write_status(processor, status, errno);
751 }
752 #endif
753
754 #ifndef HAVE_GETTIMEOFDAY
755 #define do_gettimeofday 0
756 #else
757 static void
758 do_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;
768 int status = gettimeofday(&t, (tz_addr != 0 ? &tz : NULL));
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
788 static void
789 do_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
817 static void
818 do_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);
833 status = fdbad (fd);
834 if (status == 0)
835 status = fstatfs(fd, (buf_addr == 0 ? NULL : &buf));
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
847 static void
848 do_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;
860 #ifdef SYS_stat
861 SYS(stat);
862 #endif
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
873 static void
874 do_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];
882 struct stat buf;
883 int status;
884 #ifdef SYS_fstat
885 SYS(fstat);
886 #endif
887 /* Can't combine these statements, cuz fstat sets errno. */
888 status = fdbad (fd);
889 if (status == 0)
890 status = fstat(fd, &buf);
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
899 static void
900 do_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;
912 #ifdef SYS_lstat
913 SYS(lstat);
914 #endif
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
925 static void
926 do_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;
939 #ifdef SYS_getdirentries
940 SYS(getdirentries);
941 #endif
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)
956 free(buf);
957 }
958 #endif
959
960
961 static void
962 do___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
980 static void
981 do_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);
992 status = fdbad (fildes);
993 if (status == 0)
994 status = lseek(fildes, offset, whence);
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
1004 static void
1005 do___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];
1013 signed_word namelen = cpu_registers(processor)->gpr[arg0+1];
1014 unsigned_word oldp = cpu_registers(processor)->gpr[arg0+2];
1015 unsigned_word oldlenp = cpu_registers(processor)->gpr[arg0+3];
1016 signed_word oldlen;
1017 signed_word mib;
1018 signed_word int_val;
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);
1052 if (sizeof(signed_word) > oldlen)
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
1073 static 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
1281 static 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",
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",
1382 };
1383
1384 static 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",
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",
1449 };
1450
1451 static emul_syscall emul_netbsd_syscalls = {
1452 netbsd_descriptors,
1453 ARRAY_SIZE (netbsd_descriptors),
1454 netbsd_error_names,
1455 ARRAY_SIZE (netbsd_error_names),
1456 netbsd_signal_names,
1457 ARRAY_SIZE (netbsd_signal_names),
1458 };
1459
1460
1461 /* NetBSD's os_emul interface, most are just passed on to the generic
1462 syscall stuff */
1463
1464 static os_emul_data *
1465 emul_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;
1474 char *filename;
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
1509 filename = tree_quote_property (bfd_get_filename(image));
1510 tree_parse(root, "/openprom/vm/map-binary/file-name %s",
1511 filename);
1512 free (filename);
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
1538 static void
1539 emul_netbsd_init(os_emul_data *emul_data,
1540 int nr_cpus)
1541 {
1542 fd_closed[0] = 0;
1543 fd_closed[1] = 0;
1544 fd_closed[2] = 0;
1545 }
1546
1547 static void
1548 emul_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
1560 const 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
1569 #endif /* _EMUL_NETBSD_C_ */