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