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