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