Update copyright year range in header of all files managed by GDB
[binutils-gdb.git] / sim / ppc / emul_unix.c
blob1d8b7814ffc62d0cdada4e316cacb57872fd4282
1 /* This file is part of the program psim.
3 Copyright (C) 1996-1998, Andrew Cagney <cagney@highland.com.au>
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.
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.
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/>.
21 #ifndef _EMUL_UNIX_C_
22 #define _EMUL_UNIX_C_
25 /* Note: this module is called via a table. There is no benefit in
26 making it inline */
28 #include "defs.h"
30 #include <string.h>
31 #ifdef HAVE_SYS_TYPES_H
32 #include <sys/types.h>
33 #endif
35 #ifdef HAVE_SYS_TYPES_H
36 #include <sys/stat.h>
37 #else
38 #undef HAVE_STAT
39 #undef HAVE_LSTAT
40 #undef HAVE_FSTAT
41 #endif
43 #include <stdio.h>
44 #include <signal.h>
45 #include <errno.h>
47 #ifdef HAVE_FCNTL_H
48 #include <fcntl.h>
49 #endif
51 #ifdef HAVE_SYS_PARAM_H
52 #include <sys/param.h>
53 #endif
55 #include <sys/time.h>
57 #ifndef HAVE_TERMIOS_STRUCTURE
58 #undef HAVE_SYS_TERMIOS_H
59 #undef HAVE_TCGETATTR
60 #else
61 #ifndef HAVE_SYS_TERMIOS_H
62 #undef HAVE_TERMIOS_STRUCTURE
63 #endif
64 #endif
66 #ifdef HAVE_TERMIOS_STRUCTURE
67 #include <sys/termios.h>
69 /* If we have TERMIOS, use that for the termio structure, since some systems
70 don't like including both sys/termios.h and sys/termio.h at the same
71 time. */
72 #undef HAVE_TERMIO_STRUCTURE
73 #undef TCGETA
74 #undef termio
75 #define termio termios
76 #endif
78 #ifndef HAVE_TERMIO_STRUCTURE
79 #undef HAVE_SYS_TERMIO_H
80 #else
81 #ifndef HAVE_SYS_TERMIO_H
82 #undef HAVE_TERMIO_STRUCTURE
83 #endif
84 #endif
86 #ifdef HAVE_TERMIO_STRUCTURE
87 #include <sys/termio.h>
88 #endif
90 #ifdef HAVE_GETRUSAGE
91 #ifndef HAVE_SYS_RESOURCE_H
92 #undef HAVE_GETRUSAGE
93 #endif
94 #endif
96 #ifdef HAVE_GETRUSAGE
97 #include <sys/resource.h>
98 int getrusage();
99 #endif
101 #if HAVE_DIRENT_H
102 # include <dirent.h>
103 # define NAMLEN(dirent) strlen((dirent)->d_name)
104 #else
105 # define dirent direct
106 # define NAMLEN(dirent) (dirent)->d_namlen
107 # if HAVE_SYS_NDIR_H
108 # include <sys/ndir.h>
109 # endif
110 # if HAVE_SYS_DIR_H
111 # include <sys/dir.h>
112 # endif
113 # if HAVE_NDIR_H
114 # include <ndir.h>
115 # endif
116 #endif
118 #ifdef HAVE_UNISTD_H
119 #undef MAXPATHLEN /* sys/param.h might define this also */
120 #include <unistd.h>
121 #endif
123 #include <stdlib.h>
124 #include <time.h>
126 #include "emul_generic.h"
127 #include "emul_unix.h"
129 #ifndef STATIC_INLINE_EMUL_UNIX
130 #define STATIC_INLINE_EMUL_UNIX STATIC_INLINE
131 #endif
133 #ifndef PATH_MAX
134 #define PATH_MAX 1024
135 #endif
137 #ifndef EINVAL
138 #define EINVAL -1
139 #endif
141 /* UNIX's idea of what is needed to implement emulations */
143 struct _os_emul_data {
144 device *vm;
145 emul_syscall *syscalls;
149 /* Emulation of simple UNIX system calls that are common on all systems. */
151 /* Structures that are common agmonst the UNIX varients */
152 struct unix_timeval {
153 int32_t tv_sec; /* seconds */
154 int32_t tv_usec; /* microseconds */
157 struct unix_timezone {
158 int32_t tz_minuteswest; /* minutes west of Greenwich */
159 int32_t tz_dsttime; /* type of dst correction */
162 #define UNIX_RUSAGE_SELF 0
163 #define UNIX_RUSAGE_CHILDREN (-1)
164 #define UNIX_RUSAGE_BOTH (-2) /* sys_wait4() uses this */
166 struct unix_rusage {
167 struct unix_timeval ru_utime; /* user time used */
168 struct unix_timeval ru_stime; /* system time used */
169 int32_t ru_maxrss; /* maximum resident set size */
170 int32_t ru_ixrss; /* integral shared memory size */
171 int32_t ru_idrss; /* integral unshared data size */
172 int32_t ru_isrss; /* integral unshared stack size */
173 int32_t ru_minflt; /* any page faults not requiring I/O */
174 int32_t ru_majflt; /* any page faults requiring I/O */
175 int32_t ru_nswap; /* swaps */
176 int32_t ru_inblock; /* block input operations */
177 int32_t ru_oublock; /* block output operations */
178 int32_t ru_msgsnd; /* messages sent */
179 int32_t ru_msgrcv; /* messages received */
180 int32_t ru_nsignals; /* signals received */
181 int32_t ru_nvcsw; /* voluntary context switches */
182 int32_t ru_nivcsw; /* involuntary " */
186 /* File descriptors 0, 1, and 2 should not be closed. fd_closed[]
187 tracks whether these descriptors have been closed in do_close()
188 below. */
190 static int fd_closed[3];
192 /* Check for some occurrences of bad file descriptors. We only check
193 whether fd 0, 1, or 2 are "closed". By "closed" we mean that these
194 descriptors aren't actually closed, but are considered to be closed
195 by this layer.
197 Other checks are performed by the underlying OS call. */
199 static int
200 fdbad (int fd)
202 if (fd >=0 && fd <= 2 && fd_closed[fd])
204 errno = EBADF;
205 return -1;
207 return 0;
210 static void
211 do_unix_exit(os_emul_data *emul,
212 unsigned call,
213 const int arg0,
214 cpu *processor,
215 unsigned_word cia)
217 int status = (int)cpu_registers(processor)->gpr[arg0];
218 if (WITH_TRACE && ppc_trace[trace_os_emul])
219 printf_filtered ("%d)\n", status);
221 cpu_halt(processor, cia, was_exited, status);
225 static void
226 do_unix_read(os_emul_data *emul,
227 unsigned call,
228 const int arg0,
229 cpu *processor,
230 unsigned_word cia)
232 void *scratch_buffer;
233 int d = (int)cpu_registers(processor)->gpr[arg0];
234 unsigned_word buf = cpu_registers(processor)->gpr[arg0+1];
235 int nbytes = cpu_registers(processor)->gpr[arg0+2];
236 int status;
238 if (WITH_TRACE && ppc_trace[trace_os_emul])
239 printf_filtered ("%d, 0x%lx, %d", d, (long)buf, nbytes);
241 /* get a tempoary bufer */
242 scratch_buffer = zalloc(nbytes);
244 /* check if buffer exists by reading it */
245 emul_read_buffer(scratch_buffer, buf, nbytes, processor, cia);
247 status = fdbad (d);
248 /* read */
249 if (status == 0)
250 status = read (d, scratch_buffer, nbytes);
252 emul_write_status(processor, status, errno);
253 if (status > 0)
254 emul_write_buffer(scratch_buffer, buf, status, processor, cia);
256 free(scratch_buffer);
260 static void
261 do_unix_write(os_emul_data *emul,
262 unsigned call,
263 const int arg0,
264 cpu *processor,
265 unsigned_word cia)
267 void *scratch_buffer = NULL;
268 int d = (int)cpu_registers(processor)->gpr[arg0];
269 unsigned_word buf = cpu_registers(processor)->gpr[arg0+1];
270 int nbytes = cpu_registers(processor)->gpr[arg0+2];
271 int status;
273 if (WITH_TRACE && ppc_trace[trace_os_emul])
274 printf_filtered ("%d, 0x%lx, %d", d, (long)buf, nbytes);
276 /* get a tempoary bufer */
277 scratch_buffer = zalloc(nbytes); /* FIXME - nbytes == 0 */
279 /* copy in */
280 emul_read_buffer(scratch_buffer, buf, nbytes,
281 processor, cia);
283 status = fdbad (d);
284 /* write */
285 if (status == 0)
286 status = write(d, scratch_buffer, nbytes);
287 emul_write_status(processor, status, errno);
288 free(scratch_buffer);
290 flush_stdoutput();
294 static void
295 do_unix_open(os_emul_data *emul,
296 unsigned call,
297 const int arg0,
298 cpu *processor,
299 unsigned_word cia)
301 unsigned_word path_addr = cpu_registers(processor)->gpr[arg0];
302 char path_buf[PATH_MAX];
303 char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia);
304 int flags = (int)cpu_registers(processor)->gpr[arg0+1];
305 int mode = (int)cpu_registers(processor)->gpr[arg0+2];
306 int status;
308 if (WITH_TRACE && ppc_trace[trace_os_emul])
309 printf_filtered ("0x%lx [%s], 0x%x, 0x%x", (long)path_addr, path, flags, mode);
311 status = open(path, flags, mode);
312 emul_write_status(processor, status, errno);
316 static void
317 do_unix_close(os_emul_data *emul,
318 unsigned call,
319 const int arg0,
320 cpu *processor,
321 unsigned_word cia)
323 int d = (int)cpu_registers(processor)->gpr[arg0];
324 int status;
326 if (WITH_TRACE && ppc_trace[trace_os_emul])
327 printf_filtered ("%d", d);
329 status = fdbad (d);
330 if (status == 0)
332 /* Do not close stdin, stdout, or stderr. GDB may still need access to
333 these descriptors. */
334 if (d == 0 || d == 1 || d == 2)
336 fd_closed[d] = 1;
337 status = 0;
339 else
340 status = close(d);
343 emul_write_status(processor, status, errno);
347 static void
348 do_unix_break(os_emul_data *emul,
349 unsigned call,
350 const int arg0,
351 cpu *processor,
352 unsigned_word cia)
354 /* just pass this onto the `vm' device */
355 unsigned_word new_break = cpu_registers(processor)->gpr[arg0];
356 int status;
358 if (WITH_TRACE && ppc_trace[trace_os_emul])
359 printf_filtered ("0x%lx", (long)cpu_registers(processor)->gpr[arg0]);
361 status = device_ioctl(emul->vm,
362 processor,
363 cia,
364 device_ioctl_break,
365 new_break); /*ioctl-data*/
367 emul_write_status(processor, 0, status);
370 #ifndef HAVE_ACCESS
371 #define do_unix_access 0
372 #else
373 static void
374 do_unix_access(os_emul_data *emul,
375 unsigned call,
376 const int arg0,
377 cpu *processor,
378 unsigned_word cia)
380 unsigned_word path_addr = cpu_registers(processor)->gpr[arg0];
381 char path_buf[PATH_MAX];
382 char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia);
383 int mode = (int)cpu_registers(processor)->gpr[arg0+1];
384 int status;
386 if (WITH_TRACE && ppc_trace[trace_os_emul])
387 printf_filtered ("0x%lx [%s], 0x%x [0%o]", (long)path_addr, path, mode, mode);
389 status = access(path, mode);
390 emul_write_status(processor, status, errno);
392 #endif
394 #ifndef HAVE_GETPID
395 #define do_unix_getpid 0
396 #else
397 static void
398 do_unix_getpid(os_emul_data *emul,
399 unsigned call,
400 const int arg0,
401 cpu *processor,
402 unsigned_word cia)
404 pid_t status = getpid();
405 emul_write_status(processor, (int)status, errno);
407 #endif
409 #ifndef HAVE_GETPPID
410 #define do_unix_getppid 0
411 #else
412 static void
413 do_unix_getppid(os_emul_data *emul,
414 unsigned call,
415 const int arg0,
416 cpu *processor,
417 unsigned_word cia)
419 pid_t status = getppid();
420 emul_write_status(processor, (int)status, errno);
422 #endif
424 #if !defined(HAVE_GETPID) || !defined(HAVE_GETPPID)
425 #define do_unix_getpid2 0
426 #else
427 static void
428 do_unix_getpid2(os_emul_data *emul,
429 unsigned call,
430 const int arg0,
431 cpu *processor,
432 unsigned_word cia)
434 int pid = (int)getpid();
435 int ppid = (int)getppid();
436 emul_write2_status(processor, pid, ppid, errno);
438 #endif
440 #if !defined(HAVE_GETUID) || !defined(HAVE_GETEUID)
441 #define do_unix_getuid2 0
442 #else
443 static void
444 do_unix_getuid2(os_emul_data *emul,
445 unsigned call,
446 const int arg0,
447 cpu *processor,
448 unsigned_word cia)
450 uid_t uid = getuid();
451 uid_t euid = geteuid();
452 emul_write2_status(processor, (int)uid, (int)euid, errno);
454 #endif
456 #ifndef HAVE_GETUID
457 #define do_unix_getuid 0
458 #else
459 static void
460 do_unix_getuid(os_emul_data *emul,
461 unsigned call,
462 const int arg0,
463 cpu *processor,
464 unsigned_word cia)
466 uid_t status = getuid();
467 emul_write_status(processor, (int)status, errno);
469 #endif
471 #ifndef HAVE_GETEUID
472 #define do_unix_geteuid 0
473 #else
474 static void
475 do_unix_geteuid(os_emul_data *emul,
476 unsigned call,
477 const int arg0,
478 cpu *processor,
479 unsigned_word cia)
481 uid_t status = geteuid();
482 emul_write_status(processor, (int)status, errno);
484 #endif
486 #if 0
487 #ifndef HAVE_KILL
488 #define do_unix_kill 0
489 #else
490 static void
491 do_unix_kill(os_emul_data *emul,
492 unsigned call,
493 const int arg0,
494 cpu *processor,
495 unsigned_word cia)
497 pid_t pid = cpu_registers(processor)->gpr[arg0];
498 int sig = cpu_registers(processor)->gpr[arg0+1];
500 if (WITH_TRACE && ppc_trace[trace_os_emul])
501 printf_filtered ("%d, %d", (int)pid, sig);
503 printf_filtered("SYS_kill at 0x%lx - more to this than just being killed\n",
504 (long)cia);
506 cpu_halt(processor, cia, was_signalled, sig);
508 #endif
509 #endif
511 #ifndef HAVE_DUP
512 #define do_unix_dup 0
513 #else
514 static void
515 do_unix_dup(os_emul_data *emul,
516 unsigned call,
517 const int arg0,
518 cpu *processor,
519 unsigned_word cia)
521 int oldd = cpu_registers(processor)->gpr[arg0];
522 int status = (fdbad (oldd) < 0) ? -1 : dup(oldd);
523 int err = errno;
525 if (WITH_TRACE && ppc_trace[trace_os_emul])
526 printf_filtered ("%d", oldd);
528 emul_write_status(processor, status, err);
530 #endif
532 #ifndef HAVE_DUP2
533 #define do_unix_dup2 0
534 #else
535 static void
536 do_unix_dup2(os_emul_data *emul,
537 unsigned call,
538 const int arg0,
539 cpu *processor,
540 unsigned_word cia)
542 int oldd = cpu_registers(processor)->gpr[arg0];
543 int newd = cpu_registers(processor)->gpr[arg0+1];
544 int status = (fdbad (oldd) < 0) ? -1 : dup2(oldd, newd);
545 int err = errno;
547 if (WITH_TRACE && ppc_trace[trace_os_emul])
548 printf_filtered ("%d, %d", oldd, newd);
550 emul_write_status(processor, status, err);
552 #endif
554 #ifndef HAVE_LSEEK
555 #define do_unix_lseek 0
556 #else
557 static void
558 do_unix_lseek(os_emul_data *emul,
559 unsigned call,
560 const int arg0,
561 cpu *processor,
562 unsigned_word cia)
564 int fildes = (int)cpu_registers(processor)->gpr[arg0];
565 off_t offset = (off_t)cpu_registers(processor)->gpr[arg0+1];
566 int whence = (int)cpu_registers(processor)->gpr[arg0+2];
567 off_t status;
569 if (WITH_TRACE && ppc_trace[trace_os_emul])
570 printf_filtered ("%d %ld %d", fildes, (long)offset, whence);
572 status = fdbad (fildes);
573 if (status == 0)
574 status = lseek(fildes, offset, whence);
575 emul_write_status(processor, (int)status, errno);
577 #endif
580 #if !defined(HAVE_GETGID) || !defined(HAVE_GETEGID)
581 #define do_unix_getgid2 0
582 #else
583 static void
584 do_unix_getgid2(os_emul_data *emul,
585 unsigned call,
586 const int arg0,
587 cpu *processor,
588 unsigned_word cia)
590 gid_t gid = getgid();
591 gid_t egid = getegid();
592 emul_write2_status(processor, (int)gid, (int)egid, errno);
594 #endif
596 #ifndef HAVE_GETGID
597 #define do_unix_getgid 0
598 #else
599 static void
600 do_unix_getgid(os_emul_data *emul,
601 unsigned call,
602 const int arg0,
603 cpu *processor,
604 unsigned_word cia)
606 gid_t status = getgid();
607 emul_write_status(processor, (int)status, errno);
609 #endif
611 #ifndef HAVE_GETEGID
612 #define do_unix_getegid 0
613 #else
614 static void
615 do_unix_getegid(os_emul_data *emul,
616 unsigned call,
617 const int arg0,
618 cpu *processor,
619 unsigned_word cia)
621 gid_t status = getegid();
622 emul_write_status(processor, (int)status, errno);
624 #endif
626 #ifndef HAVE_UMASK
627 #define do_unix_umask 0
628 #else
629 static void
630 do_unix_umask(os_emul_data *emul,
631 unsigned call,
632 const int arg0,
633 cpu *processor,
634 unsigned_word cia)
636 mode_t mask = (mode_t)cpu_registers(processor)->gpr[arg0];
637 int status = umask(mask);
639 if (WITH_TRACE && ppc_trace[trace_os_emul])
640 printf_filtered ("0%o", (unsigned int)mask);
642 emul_write_status(processor, status, errno);
644 #endif
646 #ifndef HAVE_CHDIR
647 #define do_unix_chdir 0
648 #else
649 static void
650 do_unix_chdir(os_emul_data *emul,
651 unsigned call,
652 const int arg0,
653 cpu *processor,
654 unsigned_word cia)
656 unsigned_word path_addr = cpu_registers(processor)->gpr[arg0];
657 char path_buf[PATH_MAX];
658 char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia);
659 int status;
661 if (WITH_TRACE && ppc_trace[trace_os_emul])
662 printf_filtered ("0x%lx [%s]", (long)path_addr, path);
664 status = chdir(path);
665 emul_write_status(processor, status, errno);
667 #endif
669 #ifndef HAVE_LINK
670 #define do_unix_link 0
671 #else
672 static void
673 do_unix_link(os_emul_data *emul,
674 unsigned call,
675 const int arg0,
676 cpu *processor,
677 unsigned_word cia)
679 unsigned_word path1_addr = cpu_registers(processor)->gpr[arg0];
680 char path1_buf[PATH_MAX];
681 char *path1 = emul_read_string(path1_buf, path1_addr, PATH_MAX, processor, cia);
682 unsigned_word path2_addr = cpu_registers(processor)->gpr[arg0+1];
683 char path2_buf[PATH_MAX];
684 char *path2 = emul_read_string(path2_buf, path2_addr, PATH_MAX, processor, cia);
685 int status;
687 if (WITH_TRACE && ppc_trace[trace_os_emul])
688 printf_filtered ("0x%lx [%s], 0x%lx [%s]", (long)path1_addr, path1, (long)path2_addr, path2);
690 status = link(path1, path2);
691 emul_write_status(processor, status, errno);
693 #endif
695 #ifndef HAVE_SYMLINK
696 #define do_unix_symlink 0
697 #else
698 static void
699 do_unix_symlink(os_emul_data *emul,
700 unsigned call,
701 const int arg0,
702 cpu *processor,
703 unsigned_word cia)
705 unsigned_word path1_addr = cpu_registers(processor)->gpr[arg0];
706 char path1_buf[PATH_MAX];
707 char *path1 = emul_read_string(path1_buf, path1_addr, PATH_MAX, processor, cia);
708 unsigned_word path2_addr = cpu_registers(processor)->gpr[arg0+1];
709 char path2_buf[PATH_MAX];
710 char *path2 = emul_read_string(path2_buf, path2_addr, PATH_MAX, processor, cia);
711 int status;
713 if (WITH_TRACE && ppc_trace[trace_os_emul])
714 printf_filtered ("0x%lx [%s], 0x%lx [%s]", (long)path1_addr, path1, (long)path2_addr, path2);
716 status = symlink(path1, path2);
717 emul_write_status(processor, status, errno);
719 #endif
721 #ifndef HAVE_UNLINK
722 #define do_unix_unlink 0
723 #else
724 static void
725 do_unix_unlink(os_emul_data *emul,
726 unsigned call,
727 const int arg0,
728 cpu *processor,
729 unsigned_word cia)
731 unsigned_word path_addr = cpu_registers(processor)->gpr[arg0];
732 char path_buf[PATH_MAX];
733 char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia);
734 int status;
736 if (WITH_TRACE && ppc_trace[trace_os_emul])
737 printf_filtered ("0x%lx [%s]", (long)path_addr, path);
739 status = unlink(path);
740 emul_write_status(processor, status, errno);
742 #endif
744 #ifndef HAVE_MKDIR
745 #define do_unix_mkdir 0
746 #else
747 static void
748 do_unix_mkdir(os_emul_data *emul,
749 unsigned call,
750 const int arg0,
751 cpu *processor,
752 unsigned_word cia)
754 unsigned_word path_addr = cpu_registers(processor)->gpr[arg0];
755 char path_buf[PATH_MAX];
756 char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia);
757 int mode = (int)cpu_registers(processor)->gpr[arg0+1];
758 int status;
760 if (WITH_TRACE && ppc_trace[trace_os_emul])
761 printf_filtered ("0x%lx [%s], 0%3o", (long)path_addr, path, mode);
763 status = mkdir(path, mode);
764 emul_write_status(processor, status, errno);
766 #endif
768 #ifndef HAVE_RMDIR
769 #define do_unix_rmdir 0
770 #else
771 static void
772 do_unix_rmdir(os_emul_data *emul,
773 unsigned call,
774 const int arg0,
775 cpu *processor,
776 unsigned_word cia)
778 unsigned_word path_addr = cpu_registers(processor)->gpr[arg0];
779 char path_buf[PATH_MAX];
780 char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia);
781 int status;
783 if (WITH_TRACE && ppc_trace[trace_os_emul])
784 printf_filtered ("0x%lx [%s]", (long)path_addr, path);
786 status = rmdir(path);
787 emul_write_status(processor, status, errno);
789 #endif
791 #ifndef HAVE_TIME
792 #define do_unix_time 0
793 #else
794 static void
795 do_unix_time(os_emul_data *emul,
796 unsigned call,
797 const int arg0,
798 cpu *processor,
799 unsigned_word cia)
801 unsigned_word tp = cpu_registers(processor)->gpr[arg0];
802 time_t now = time ((time_t *)0);
803 unsigned_word status = H2T_4(now);
805 if (WITH_TRACE && ppc_trace[trace_os_emul])
806 printf_filtered ("0x%lx", (long)tp);
808 emul_write_status(processor, (int)status, errno);
810 if (tp)
811 emul_write_buffer(&status, tp, sizeof(status), processor, cia);
813 #endif
815 #if !defined(HAVE_GETTIMEOFDAY)
816 #define do_unix_gettimeofday 0
817 #else
818 static void
819 do_unix_gettimeofday(os_emul_data *emul,
820 unsigned call,
821 const int arg0,
822 cpu *processor,
823 unsigned_word cia)
825 unsigned_word tv = cpu_registers(processor)->gpr[arg0];
826 unsigned_word tz = cpu_registers(processor)->gpr[arg0+1];
827 struct unix_timeval target_timeval;
828 struct timeval host_timeval;
829 struct unix_timezone target_timezone;
830 struct timezone host_timezone;
831 int status;
833 if (WITH_TRACE && ppc_trace[trace_os_emul])
834 printf_filtered ("0x%lx, 0x%lx", (long)tv, (long)tz);
836 /* Just in case the system doesn't set the timezone structure */
837 host_timezone.tz_minuteswest = 0;
838 host_timezone.tz_dsttime = 0;
840 status = gettimeofday(&host_timeval, &host_timezone);
841 if (status >= 0) {
842 if (tv) {
843 target_timeval.tv_sec = H2T_4(host_timeval.tv_sec);
844 target_timeval.tv_usec = H2T_4(host_timeval.tv_usec);
845 emul_write_buffer((void *) &target_timeval, tv, sizeof(target_timeval), processor, cia);
848 if (tz) {
849 target_timezone.tz_minuteswest = H2T_4(host_timezone.tz_minuteswest);
850 target_timezone.tz_dsttime = H2T_4(host_timezone.tz_dsttime);
851 emul_write_buffer((void *) &target_timezone, tv, sizeof(target_timezone), processor, cia);
855 emul_write_status(processor, (int)status, errno);
857 #endif
860 #ifndef HAVE_GETRUSAGE
861 #define do_unix_getrusage 0
862 #else
863 static void
864 do_unix_getrusage(os_emul_data *emul,
865 unsigned call,
866 const int arg0,
867 cpu *processor,
868 unsigned_word cia)
870 signed_word who = (signed_word)cpu_registers(processor)->gpr[arg0];
871 unsigned_word usage = cpu_registers(processor)->gpr[arg0+1];
872 struct rusage host_rusage, host_rusage2;
873 struct unix_rusage target_rusage;
874 int status;
876 if (WITH_TRACE && ppc_trace[trace_os_emul])
877 printf_filtered ("%ld, 0x%lx", (long)who, (long)usage);
879 switch (who) {
880 default:
881 status = -1;
882 errno = EINVAL;
883 break;
885 case UNIX_RUSAGE_SELF:
886 status = getrusage(RUSAGE_SELF, &host_rusage);
887 break;
889 case UNIX_RUSAGE_CHILDREN:
890 status = getrusage(RUSAGE_CHILDREN, &host_rusage);
891 break;
893 case UNIX_RUSAGE_BOTH:
894 status = getrusage(RUSAGE_SELF, &host_rusage);
895 if (status >= 0) {
896 status = getrusage(RUSAGE_CHILDREN, &host_rusage2);
897 if (status >= 0) {
898 host_rusage.ru_utime.tv_sec += host_rusage2.ru_utime.tv_sec;
899 host_rusage.ru_utime.tv_usec += host_rusage2.ru_utime.tv_usec;
900 host_rusage.ru_stime.tv_sec += host_rusage2.ru_stime.tv_sec;
901 host_rusage.ru_stime.tv_usec += host_rusage2.ru_stime.tv_usec;
902 host_rusage.ru_maxrss += host_rusage2.ru_maxrss;
903 host_rusage.ru_ixrss += host_rusage2.ru_ixrss;
904 host_rusage.ru_idrss += host_rusage2.ru_idrss;
905 host_rusage.ru_isrss += host_rusage2.ru_isrss;
906 host_rusage.ru_minflt += host_rusage2.ru_minflt;
907 host_rusage.ru_majflt += host_rusage2.ru_majflt;
908 host_rusage.ru_nswap += host_rusage2.ru_nswap;
909 host_rusage.ru_inblock += host_rusage2.ru_inblock;
910 host_rusage.ru_oublock += host_rusage2.ru_oublock;
911 host_rusage.ru_msgsnd += host_rusage2.ru_msgsnd;
912 host_rusage.ru_msgrcv += host_rusage2.ru_msgrcv;
913 host_rusage.ru_nsignals += host_rusage2.ru_nsignals;
914 host_rusage.ru_nvcsw += host_rusage2.ru_nvcsw;
915 host_rusage.ru_nivcsw += host_rusage2.ru_nivcsw;
920 if (status >= 0) {
921 target_rusage.ru_utime.tv_sec = H2T_4(host_rusage2.ru_utime.tv_sec);
922 target_rusage.ru_utime.tv_usec = H2T_4(host_rusage2.ru_utime.tv_usec);
923 target_rusage.ru_stime.tv_sec = H2T_4(host_rusage2.ru_stime.tv_sec);
924 target_rusage.ru_stime.tv_usec = H2T_4(host_rusage2.ru_stime.tv_usec);
925 target_rusage.ru_maxrss = H2T_4(host_rusage2.ru_maxrss);
926 target_rusage.ru_ixrss = H2T_4(host_rusage2.ru_ixrss);
927 target_rusage.ru_idrss = H2T_4(host_rusage2.ru_idrss);
928 target_rusage.ru_isrss = H2T_4(host_rusage2.ru_isrss);
929 target_rusage.ru_minflt = H2T_4(host_rusage2.ru_minflt);
930 target_rusage.ru_majflt = H2T_4(host_rusage2.ru_majflt);
931 target_rusage.ru_nswap = H2T_4(host_rusage2.ru_nswap);
932 target_rusage.ru_inblock = H2T_4(host_rusage2.ru_inblock);
933 target_rusage.ru_oublock = H2T_4(host_rusage2.ru_oublock);
934 target_rusage.ru_msgsnd = H2T_4(host_rusage2.ru_msgsnd);
935 target_rusage.ru_msgrcv = H2T_4(host_rusage2.ru_msgrcv);
936 target_rusage.ru_nsignals = H2T_4(host_rusage2.ru_nsignals);
937 target_rusage.ru_nvcsw = H2T_4(host_rusage2.ru_nvcsw);
938 target_rusage.ru_nivcsw = H2T_4(host_rusage2.ru_nivcsw);
939 emul_write_buffer((void *) &target_rusage, usage, sizeof(target_rusage), processor, cia);
942 emul_write_status(processor, status, errno);
944 #endif
947 static void
948 do_unix_nop(os_emul_data *emul,
949 unsigned call,
950 const int arg0,
951 cpu *processor,
952 unsigned_word cia)
954 if (WITH_TRACE && ppc_trace[trace_os_emul])
955 printf_filtered ("0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx",
956 (long)cpu_registers(processor)->gpr[arg0],
957 (long)cpu_registers(processor)->gpr[arg0+1],
958 (long)cpu_registers(processor)->gpr[arg0+2],
959 (long)cpu_registers(processor)->gpr[arg0+3],
960 (long)cpu_registers(processor)->gpr[arg0+4],
961 (long)cpu_registers(processor)->gpr[arg0+5]);
963 emul_write_status(processor, 0, errno);
967 /* Common code for initializing the system call stuff */
969 static os_emul_data *
970 emul_unix_create(device *root,
971 bfd *image,
972 const char *name,
973 emul_syscall *syscall)
975 unsigned_word top_of_stack;
976 unsigned stack_size;
977 int elf_binary;
978 os_emul_data *data;
979 device *vm;
980 char *filename;
982 /* merge any emulation specific entries into the device tree */
984 /* establish a few defaults */
985 if (image->xvec->flavour == bfd_target_elf_flavour) {
986 elf_binary = 1;
987 top_of_stack = 0xe0000000;
988 stack_size = 0x00100000;
990 else {
991 elf_binary = 0;
992 top_of_stack = 0x20000000;
993 stack_size = 0x00100000;
996 /* options */
997 emul_add_tree_options(root, image, name,
998 (WITH_ENVIRONMENT == USER_ENVIRONMENT
999 ? "user" : "virtual"),
1000 0 /*oea-interrupt-prefix*/);
1002 /* virtual memory - handles growth of stack/heap */
1003 vm = tree_parse(root, "/openprom/vm@0x%lx",
1004 (unsigned long)(top_of_stack - stack_size));
1005 tree_parse(vm, "./stack-base 0x%lx",
1006 (unsigned long)(top_of_stack - stack_size));
1007 tree_parse(vm, "./nr-bytes 0x%x", stack_size);
1009 filename = tree_quote_property (bfd_get_filename(image));
1010 tree_parse(root, "/openprom/vm/map-binary/file-name %s",
1011 filename);
1012 free (filename);
1014 /* finish the init */
1015 tree_parse(root, "/openprom/init/register/pc 0x%lx",
1016 (unsigned long)bfd_get_start_address(image));
1017 tree_parse(root, "/openprom/init/register/sp 0x%lx",
1018 (unsigned long)top_of_stack);
1019 tree_parse(root, "/openprom/init/register/msr 0x%x",
1020 ((tree_find_boolean_property(root, "/options/little-endian?")
1021 ? msr_little_endian_mode
1022 : 0)
1023 | (tree_find_boolean_property(root, "/openprom/options/floating-point?")
1024 ? (msr_floating_point_available
1025 | msr_floating_point_exception_mode_0
1026 | msr_floating_point_exception_mode_1)
1027 : 0)));
1028 tree_parse(root, "/openprom/init/stack/stack-type %s",
1029 (elf_binary ? "ppc-elf" : "ppc-xcoff"));
1031 /* finally our emulation data */
1032 data = ZALLOC(os_emul_data);
1033 data->vm = vm;
1034 data->syscalls = syscall;
1035 return data;
1039 /* EMULATION
1041 Solaris - Emulation of user programs for Solaris/PPC
1043 DESCRIPTION
1048 /* Solaris specific implementation */
1050 typedef int32_t solaris_uid_t;
1051 typedef int32_t solaris_gid_t;
1052 typedef int32_t solaris_off_t;
1053 typedef int32_t solaris_pid_t;
1054 typedef int32_t solaris_time_t;
1055 typedef uint32_t solaris_dev_t;
1056 typedef uint32_t solaris_ino_t;
1057 typedef uint32_t solaris_mode_t;
1058 typedef uint32_t solaris_nlink_t;
1060 #ifdef HAVE_SYS_STAT_H
1061 #define SOLARIS_ST_FSTYPSZ 16 /* array size for file system type name */
1063 /* AIX 7.1 defines st_pad[123] to st_[amc]tim.tv_pad, respectively */
1064 #undef st_pad1
1065 #undef st_pad2
1066 #undef st_pad3
1068 struct solaris_stat {
1069 solaris_dev_t st_dev;
1070 int32_t st_pad1[3]; /* reserved for network id */
1071 solaris_ino_t st_ino;
1072 solaris_mode_t st_mode;
1073 solaris_nlink_t st_nlink;
1074 solaris_uid_t st_uid;
1075 solaris_gid_t st_gid;
1076 solaris_dev_t st_rdev;
1077 int32_t st_pad2[2];
1078 solaris_off_t st_size;
1079 int32_t st_pad3; /* future off_t expansion */
1080 struct unix_timeval st_atim;
1081 struct unix_timeval st_mtim;
1082 struct unix_timeval st_ctim;
1083 int32_t st_blksize;
1084 int32_t st_blocks;
1085 char st_fstype[SOLARIS_ST_FSTYPSZ];
1086 int32_t st_pad4[8]; /* expansion area */
1089 /* Convert from host stat structure to solaris stat structure */
1090 STATIC_INLINE_EMUL_UNIX void
1091 convert_to_solaris_stat(unsigned_word addr,
1092 struct stat *host,
1093 cpu *processor,
1094 unsigned_word cia)
1096 struct solaris_stat target;
1097 int i;
1099 target.st_dev = H2T_4(host->st_dev);
1100 target.st_ino = H2T_4(host->st_ino);
1101 target.st_mode = H2T_4(host->st_mode);
1102 target.st_nlink = H2T_4(host->st_nlink);
1103 target.st_uid = H2T_4(host->st_uid);
1104 target.st_gid = H2T_4(host->st_gid);
1105 target.st_size = H2T_4(host->st_size);
1107 #ifdef HAVE_ST_RDEV
1108 target.st_rdev = H2T_4(host->st_rdev);
1109 #else
1110 target.st_rdev = 0;
1111 #endif
1113 #ifdef HAVE_ST_BLKSIZE
1114 target.st_blksize = H2T_4(host->st_blksize);
1115 #else
1116 target.st_blksize = 0;
1117 #endif
1119 #ifdef HAVE_ST_BLOCKS
1120 target.st_blocks = H2T_4(host->st_blocks);
1121 #else
1122 target.st_blocks = 0;
1123 #endif
1125 target.st_atim.tv_sec = H2T_4(host->st_atime);
1126 target.st_atim.tv_usec = 0;
1128 target.st_ctim.tv_sec = H2T_4(host->st_ctime);
1129 target.st_ctim.tv_usec = 0;
1131 target.st_mtim.tv_sec = H2T_4(host->st_mtime);
1132 target.st_mtim.tv_usec = 0;
1134 for (i = 0; i < ARRAY_SIZE (target.st_pad1); i++)
1135 target.st_pad1[i] = 0;
1137 for (i = 0; i < ARRAY_SIZE (target.st_pad2); i++)
1138 target.st_pad2[i] = 0;
1140 target.st_pad3 = 0;
1142 for (i = 0; i < ARRAY_SIZE (target.st_pad4); i++)
1143 target.st_pad4[i] = 0;
1145 /* For now, just punt and always say it is a ufs file */
1146 strcpy (target.st_fstype, "ufs");
1148 emul_write_buffer(&target, addr, sizeof(target), processor, cia);
1150 #endif /* HAVE_SYS_STAT_H */
1152 #ifndef HAVE_STAT
1153 #define do_solaris_stat 0
1154 #else
1155 static void
1156 do_solaris_stat(os_emul_data *emul,
1157 unsigned call,
1158 const int arg0,
1159 cpu *processor,
1160 unsigned_word cia)
1162 unsigned_word path_addr = cpu_registers(processor)->gpr[arg0];
1163 unsigned_word stat_pkt = cpu_registers(processor)->gpr[arg0+1];
1164 char path_buf[PATH_MAX];
1165 struct stat buf;
1166 char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia);
1167 int status;
1169 if (WITH_TRACE && ppc_trace[trace_os_emul])
1170 printf_filtered ("0x%lx [%s], 0x%lx", (long)path_addr, path, (long)stat_pkt);
1172 status = stat (path, &buf);
1173 if (status == 0)
1174 convert_to_solaris_stat (stat_pkt, &buf, processor, cia);
1176 emul_write_status(processor, status, errno);
1178 #endif
1180 #ifndef HAVE_LSTAT
1181 #define do_solaris_lstat 0
1182 #else
1183 static void
1184 do_solaris_lstat(os_emul_data *emul,
1185 unsigned call,
1186 const int arg0,
1187 cpu *processor,
1188 unsigned_word cia)
1190 unsigned_word path_addr = cpu_registers(processor)->gpr[arg0];
1191 unsigned_word stat_pkt = cpu_registers(processor)->gpr[arg0+1];
1192 char path_buf[PATH_MAX];
1193 struct stat buf;
1194 char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia);
1195 int status;
1197 if (WITH_TRACE && ppc_trace[trace_os_emul])
1198 printf_filtered ("0x%lx [%s], 0x%lx", (long)path_addr, path, (long)stat_pkt);
1200 status = lstat (path, &buf);
1201 if (status == 0)
1202 convert_to_solaris_stat (stat_pkt, &buf, processor, cia);
1204 emul_write_status(processor, status, errno);
1206 #endif
1208 #ifndef HAVE_FSTAT
1209 #define do_solaris_fstat 0
1210 #else
1211 static void
1212 do_solaris_fstat(os_emul_data *emul,
1213 unsigned call,
1214 const int arg0,
1215 cpu *processor,
1216 unsigned_word cia)
1218 int fildes = (int)cpu_registers(processor)->gpr[arg0];
1219 unsigned_word stat_pkt = cpu_registers(processor)->gpr[arg0+1];
1220 struct stat buf;
1221 int status;
1223 if (WITH_TRACE && ppc_trace[trace_os_emul])
1224 printf_filtered ("%d, 0x%lx", fildes, (long)stat_pkt);
1226 status = fdbad (fildes);
1227 if (status == 0)
1228 status = fstat (fildes, &buf);
1229 if (status == 0)
1230 convert_to_solaris_stat (stat_pkt, &buf, processor, cia);
1232 emul_write_status(processor, status, errno);
1234 #endif
1236 #if defined(HAVE_TERMIO_STRUCTURE) || defined(HAVE_TERMIOS_STRUCTURE)
1237 #define SOLARIS_TIOC ('T'<<8)
1238 #define SOLARIS_NCC 8
1239 #define SOLARIS_NCCS 19
1241 #define SOLARIS_VINTR 0
1242 #define SOLARIS_VQUIT 1
1243 #define SOLARIS_VERASE 2
1244 #define SOLARIS_VKILL 3
1245 #define SOLARIS_VEOF 4
1246 #define SOLARIS_VEOL 5
1247 #define SOLARIS_VEOL2 6
1248 #define SOLARIS_VSWTCH 7
1249 #define SOLARIS_VSTART 8
1250 #define SOLARIS_VSTOP 9
1251 #define SOLARIS_VSUSP 10
1252 #define SOLARIS_VDSUSP 11
1253 #define SOLARIS_VREPRINT 12
1254 #define SOLARIS_VDISCARD 13
1255 #define SOLARIS_VWERASE 14
1256 #define SOLARIS_VLNEXT 15
1257 #endif
1259 #if defined(HAVE_TERMIO_STRUCTURE) || defined(HAVE_TERMIOS_STRUCTURE)
1260 /* Convert to/from host termio structure */
1262 struct solaris_termio {
1263 uint16_t c_iflag; /* input modes */
1264 uint16_t c_oflag; /* output modes */
1265 uint16_t c_cflag; /* control modes */
1266 uint16_t c_lflag; /* line discipline modes */
1267 uint8_t c_line; /* line discipline */
1268 uint8_t c_cc[SOLARIS_NCC]; /* control chars */
1271 STATIC_INLINE_EMUL_UNIX void
1272 convert_to_solaris_termio(unsigned_word addr,
1273 struct termio *host,
1274 cpu *processor,
1275 unsigned_word cia)
1277 struct solaris_termio target;
1278 int i;
1280 target.c_iflag = H2T_2 (host->c_iflag);
1281 target.c_oflag = H2T_2 (host->c_oflag);
1282 target.c_cflag = H2T_2 (host->c_cflag);
1283 target.c_lflag = H2T_2 (host->c_lflag);
1285 #if defined(HAVE_TERMIO_CLINE) || defined(HAVE_TERMIOS_CLINE)
1286 target.c_line = host->c_line;
1287 #else
1288 target.c_line = 0;
1289 #endif
1291 for (i = 0; i < SOLARIS_NCC; i++)
1292 target.c_cc[i] = 0;
1294 #ifdef VINTR
1295 target.c_cc[SOLARIS_VINTR] = host->c_cc[VINTR];
1296 #endif
1298 #ifdef VQUIT
1299 target.c_cc[SOLARIS_VQUIT] = host->c_cc[VQUIT];
1300 #endif
1302 #ifdef VERASE
1303 target.c_cc[SOLARIS_VERASE] = host->c_cc[VERASE];
1304 #endif
1306 #ifdef VKILL
1307 target.c_cc[SOLARIS_VKILL] = host->c_cc[VKILL];
1308 #endif
1310 #ifdef VEOF
1311 target.c_cc[SOLARIS_VEOF] = host->c_cc[VEOF];
1312 #endif
1314 #ifdef VEOL
1315 target.c_cc[SOLARIS_VEOL] = host->c_cc[VEOL];
1316 #endif
1318 #ifdef VEOL2
1319 target.c_cc[SOLARIS_VEOL2] = host->c_cc[VEOL2];
1320 #endif
1322 #ifdef VSWTCH
1323 target.c_cc[SOLARIS_VSWTCH] = host->c_cc[VSWTCH];
1325 #else
1326 #ifdef VSWTC
1327 target.c_cc[SOLARIS_VSWTCH] = host->c_cc[VSWTC];
1328 #endif
1329 #endif
1331 emul_write_buffer(&target, addr, sizeof(target), processor, cia);
1333 #endif /* HAVE_TERMIO_STRUCTURE || HAVE_TERMIOS_STRUCTURE */
1335 #ifdef HAVE_TERMIOS_STRUCTURE
1336 /* Convert to/from host termios structure */
1338 typedef uint32_t solaris_tcflag_t;
1339 typedef uint8_t solaris_cc_t;
1340 typedef uint32_t solaris_speed_t;
1342 struct solaris_termios {
1343 solaris_tcflag_t c_iflag;
1344 solaris_tcflag_t c_oflag;
1345 solaris_tcflag_t c_cflag;
1346 solaris_tcflag_t c_lflag;
1347 solaris_cc_t c_cc[SOLARIS_NCCS];
1350 STATIC_INLINE_EMUL_UNIX void
1351 convert_to_solaris_termios(unsigned_word addr,
1352 struct termios *host,
1353 cpu *processor,
1354 unsigned_word cia)
1356 struct solaris_termios target;
1357 int i;
1359 target.c_iflag = H2T_4 (host->c_iflag);
1360 target.c_oflag = H2T_4 (host->c_oflag);
1361 target.c_cflag = H2T_4 (host->c_cflag);
1362 target.c_lflag = H2T_4 (host->c_lflag);
1364 for (i = 0; i < SOLARIS_NCCS; i++)
1365 target.c_cc[i] = 0;
1367 #ifdef VINTR
1368 target.c_cc[SOLARIS_VINTR] = host->c_cc[VINTR];
1369 #endif
1371 #ifdef VQUIT
1372 target.c_cc[SOLARIS_VQUIT] = host->c_cc[VQUIT];
1373 #endif
1375 #ifdef VERASE
1376 target.c_cc[SOLARIS_VERASE] = host->c_cc[VERASE];
1377 #endif
1379 #ifdef VKILL
1380 target.c_cc[SOLARIS_VKILL] = host->c_cc[VKILL];
1381 #endif
1383 #ifdef VEOF
1384 target.c_cc[SOLARIS_VEOF] = host->c_cc[VEOF];
1385 #endif
1387 #ifdef VEOL
1388 target.c_cc[SOLARIS_VEOL] = host->c_cc[VEOL];
1389 #endif
1391 #ifdef VEOL2
1392 target.c_cc[SOLARIS_VEOL2] = host->c_cc[VEOL2];
1393 #endif
1395 #ifdef VSWTCH
1396 target.c_cc[SOLARIS_VSWTCH] = host->c_cc[VSWTCH];
1398 #else
1399 #ifdef VSWTC
1400 target.c_cc[SOLARIS_VSWTCH] = host->c_cc[VSWTC];
1401 #endif
1402 #endif
1404 #ifdef VSTART
1405 target.c_cc[SOLARIS_VSTART] = host->c_cc[VSTART];
1406 #endif
1408 #ifdef VSTOP
1409 target.c_cc[SOLARIS_VSTOP] = host->c_cc[VSTOP];
1410 #endif
1412 #ifdef VSUSP
1413 target.c_cc[SOLARIS_VSUSP] = host->c_cc[VSUSP];
1414 #endif
1416 #ifdef VDSUSP
1417 target.c_cc[SOLARIS_VDSUSP] = host->c_cc[VDSUSP];
1418 #endif
1420 #ifdef VREPRINT
1421 target.c_cc[SOLARIS_VREPRINT] = host->c_cc[VREPRINT];
1422 #endif
1424 #ifdef VDISCARD
1425 target.c_cc[SOLARIS_VDISCARD] = host->c_cc[VDISCARD];
1426 #endif
1428 #ifdef VWERASE
1429 target.c_cc[SOLARIS_VWERASE] = host->c_cc[VWERASE];
1430 #endif
1432 #ifdef VLNEXT
1433 target.c_cc[SOLARIS_VLNEXT] = host->c_cc[VLNEXT];
1434 #endif
1436 emul_write_buffer(&target, addr, sizeof(target), processor, cia);
1438 #endif /* HAVE_TERMIOS_STRUCTURE */
1440 #ifndef HAVE_IOCTL
1441 #define do_solaris_ioctl 0
1442 #else
1443 static void
1444 do_solaris_ioctl(os_emul_data *emul,
1445 unsigned call,
1446 const int arg0,
1447 cpu *processor,
1448 unsigned_word cia)
1450 int fildes = cpu_registers(processor)->gpr[arg0];
1451 unsigned request = cpu_registers(processor)->gpr[arg0+1];
1452 unsigned_word argp_addr = cpu_registers(processor)->gpr[arg0+2];
1453 int status = 0;
1454 const char *name = "<unknown>";
1456 #ifdef HAVE_TERMIOS_STRUCTURE
1457 struct termios host_termio;
1459 #else
1460 #ifdef HAVE_TERMIO_STRUCTURE
1461 struct termio host_termio;
1462 #endif
1463 #endif
1465 status = fdbad (fildes);
1466 if (status != 0)
1467 goto done;
1469 switch (request)
1471 case 0: /* make sure we have at least one case */
1472 default:
1473 status = -1;
1474 errno = EINVAL;
1475 break;
1477 #if defined(HAVE_TERMIO_STRUCTURE) || defined(HAVE_TERMIOS_STRUCTURE)
1478 #if defined(TCGETA) || defined(TCGETS) || defined(HAVE_TCGETATTR)
1479 case SOLARIS_TIOC | 1: /* TCGETA */
1480 name = "TCGETA";
1481 #ifdef HAVE_TCGETATTR
1482 status = tcgetattr(fildes, &host_termio);
1483 #elif defined(TCGETS)
1484 status = ioctl (fildes, TCGETS, &host_termio);
1485 #else
1486 status = ioctl (fildes, TCGETA, &host_termio);
1487 #endif
1488 if (status == 0)
1489 convert_to_solaris_termio (argp_addr, &host_termio, processor, cia);
1490 break;
1491 #endif /* TCGETA */
1492 #endif /* HAVE_TERMIO_STRUCTURE */
1494 #ifdef HAVE_TERMIOS_STRUCTURE
1495 #if defined(TCGETS) || defined(HAVE_TCGETATTR)
1496 case SOLARIS_TIOC | 13: /* TCGETS */
1497 name = "TCGETS";
1498 #ifdef HAVE_TCGETATTR
1499 status = tcgetattr(fildes, &host_termio);
1500 #else
1501 status = ioctl (fildes, TCGETS, &host_termio);
1502 #endif
1503 if (status == 0)
1504 convert_to_solaris_termios (argp_addr, &host_termio, processor, cia);
1505 break;
1506 #endif /* TCGETS */
1507 #endif /* HAVE_TERMIOS_STRUCTURE */
1510 done:
1511 emul_write_status(processor, status, errno);
1513 if (WITH_TRACE && ppc_trace[trace_os_emul])
1514 printf_filtered ("%d, 0x%x [%s], 0x%lx", fildes, request, name, (long)argp_addr);
1516 #endif /* HAVE_IOCTL */
1518 static emul_syscall_descriptor solaris_descriptors[] = {
1519 /* 0 */ { 0, "syscall" },
1520 /* 1 */ { do_unix_exit, "exit" },
1521 /* 2 */ { 0, "fork" },
1522 /* 3 */ { do_unix_read, "read" },
1523 /* 4 */ { do_unix_write, "write" },
1524 /* 5 */ { do_unix_open, "open" },
1525 /* 6 */ { do_unix_close, "close" },
1526 /* 7 */ { 0, "wait" },
1527 /* 8 */ { 0, "creat" },
1528 /* 9 */ { do_unix_link, "link" },
1529 /* 10 */ { do_unix_unlink, "unlink" },
1530 /* 11 */ { 0, "exec" },
1531 /* 12 */ { do_unix_chdir, "chdir" },
1532 /* 13 */ { do_unix_time, "time" },
1533 /* 14 */ { 0, "mknod" },
1534 /* 15 */ { 0, "chmod" },
1535 /* 16 */ { 0, "chown" },
1536 /* 17 */ { do_unix_break, "brk" },
1537 /* 18 */ { do_solaris_stat, "stat" },
1538 /* 19 */ { do_unix_lseek, "lseek" },
1539 /* 20 */ { do_unix_getpid2, "getpid" },
1540 /* 21 */ { 0, "mount" },
1541 /* 22 */ { 0, "umount" },
1542 /* 23 */ { 0, "setuid" },
1543 /* 24 */ { do_unix_getuid2, "getuid" },
1544 /* 25 */ { 0, "stime" },
1545 /* 26 */ { 0, "ptrace" },
1546 /* 27 */ { 0, "alarm" },
1547 /* 28 */ { do_solaris_fstat, "fstat" },
1548 /* 29 */ { 0, "pause" },
1549 /* 30 */ { 0, "utime" },
1550 /* 31 */ { 0, "stty" },
1551 /* 32 */ { 0, "gtty" },
1552 /* 33 */ { do_unix_access, "access" },
1553 /* 34 */ { 0, "nice" },
1554 /* 35 */ { 0, "statfs" },
1555 /* 36 */ { 0, "sync" },
1556 /* 37 */ { 0, "kill" },
1557 /* 38 */ { 0, "fstatfs" },
1558 /* 39 */ { 0, "pgrpsys" },
1559 /* 40 */ { 0, "xenix" },
1560 /* 41 */ { do_unix_dup, "dup" },
1561 /* 42 */ { 0, "pipe" },
1562 /* 43 */ { 0, "times" },
1563 /* 44 */ { 0, "profil" },
1564 /* 45 */ { 0, "plock" },
1565 /* 46 */ { 0, "setgid" },
1566 /* 47 */ { do_unix_getgid2, "getgid" },
1567 /* 48 */ { 0, "signal" },
1568 /* 49 */ { 0, "msgsys" },
1569 /* 50 */ { 0, "syssun" },
1570 /* 51 */ { 0, "acct" },
1571 /* 52 */ { 0, "shmsys" },
1572 /* 53 */ { 0, "semsys" },
1573 /* 54 */ { do_solaris_ioctl, "ioctl" },
1574 /* 55 */ { 0, "uadmin" },
1575 /* 56 */ { 0, 0 /* reserved for exch */ },
1576 /* 57 */ { 0, "utssys" },
1577 /* 58 */ { 0, "fdsync" },
1578 /* 59 */ { 0, "execve" },
1579 /* 60 */ { do_unix_umask, "umask" },
1580 /* 61 */ { 0, "chroot" },
1581 /* 62 */ { 0, "fcntl" },
1582 /* 63 */ { 0, "ulimit" },
1583 /* 64 */ { 0, 0 /* reserved for UNIX PC */ },
1584 /* 64 */ { 0, 0 /* reserved for UNIX PC */ },
1585 /* 65 */ { 0, 0 /* reserved for UNIX PC */ },
1586 /* 66 */ { 0, 0 /* reserved for UNIX PC */ },
1587 /* 67 */ { 0, 0 /* reserved for UNIX PC */ },
1588 /* 68 */ { 0, 0 /* reserved for UNIX PC */ },
1589 /* 69 */ { 0, 0 /* reserved for UNIX PC */ },
1590 /* 70 */ { 0, 0 /* was advfs */ },
1591 /* 71 */ { 0, 0 /* was unadvfs */ },
1592 /* 72 */ { 0, 0 /* was rmount */ },
1593 /* 73 */ { 0, 0 /* was rumount */ },
1594 /* 74 */ { 0, 0 /* was rfstart */ },
1595 /* 75 */ { 0, 0 /* was sigret */ },
1596 /* 76 */ { 0, 0 /* was rdebug */ },
1597 /* 77 */ { 0, 0 /* was rfstop */ },
1598 /* 78 */ { 0, 0 /* was rfsys */ },
1599 /* 79 */ { do_unix_rmdir, "rmdir" },
1600 /* 80 */ { do_unix_mkdir, "mkdir" },
1601 /* 81 */ { 0, "getdents" },
1602 /* 82 */ { 0, 0 /* was libattach */ },
1603 /* 83 */ { 0, 0 /* was libdetach */ },
1604 /* 84 */ { 0, "sysfs" },
1605 /* 85 */ { 0, "getmsg" },
1606 /* 86 */ { 0, "putmsg" },
1607 /* 87 */ { 0, "poll" },
1608 /* 88 */ { do_solaris_lstat, "lstat" },
1609 /* 89 */ { do_unix_symlink, "symlink" },
1610 /* 90 */ { 0, "readlink" },
1611 /* 91 */ { 0, "setgroups" },
1612 /* 92 */ { 0, "getgroups" },
1613 /* 93 */ { 0, "fchmod" },
1614 /* 94 */ { 0, "fchown" },
1615 /* 95 */ { 0, "sigprocmask" },
1616 /* 96 */ { 0, "sigsuspend" },
1617 /* 97 */ { do_unix_nop, "sigaltstack" },
1618 /* 98 */ { do_unix_nop, "sigaction" },
1619 /* 99 */ { 0, "sigpending" },
1620 /* 100 */ { 0, "context" },
1621 /* 101 */ { 0, "evsys" },
1622 /* 102 */ { 0, "evtrapret" },
1623 /* 103 */ { 0, "statvfs" },
1624 /* 104 */ { 0, "fstatvfs" },
1625 /* 105 */ { 0, 0 /* reserved */ },
1626 /* 106 */ { 0, "nfssys" },
1627 /* 107 */ { 0, "waitsys" },
1628 /* 108 */ { 0, "sigsendsys" },
1629 /* 109 */ { 0, "hrtsys" },
1630 /* 110 */ { 0, "acancel" },
1631 /* 111 */ { 0, "async" },
1632 /* 112 */ { 0, "priocntlsys" },
1633 /* 113 */ { 0, "pathconf" },
1634 /* 114 */ { 0, "mincore" },
1635 /* 115 */ { 0, "mmap" },
1636 /* 116 */ { 0, "mprotect" },
1637 /* 117 */ { 0, "munmap" },
1638 /* 118 */ { 0, "fpathconf" },
1639 /* 119 */ { 0, "vfork" },
1640 /* 120 */ { 0, "fchdir" },
1641 /* 121 */ { 0, "readv" },
1642 /* 122 */ { 0, "writev" },
1643 /* 123 */ { 0, "xstat" },
1644 /* 124 */ { 0, "lxstat" },
1645 /* 125 */ { 0, "fxstat" },
1646 /* 126 */ { 0, "xmknod" },
1647 /* 127 */ { 0, "clocal" },
1648 /* 128 */ { 0, "setrlimit" },
1649 /* 129 */ { 0, "getrlimit" },
1650 /* 130 */ { 0, "lchown" },
1651 /* 131 */ { 0, "memcntl" },
1652 /* 132 */ { 0, "getpmsg" },
1653 /* 133 */ { 0, "putpmsg" },
1654 /* 134 */ { 0, "rename" },
1655 /* 135 */ { 0, "uname" },
1656 /* 136 */ { 0, "setegid" },
1657 /* 137 */ { 0, "sysconfig" },
1658 /* 138 */ { 0, "adjtime" },
1659 /* 139 */ { 0, "systeminfo" },
1660 /* 140 */ { 0, 0 /* reserved */ },
1661 /* 141 */ { 0, "seteuid" },
1662 /* 142 */ { 0, "vtrace" },
1663 /* 143 */ { 0, "fork1" },
1664 /* 144 */ { 0, "sigtimedwait" },
1665 /* 145 */ { 0, "lwp_info" },
1666 /* 146 */ { 0, "yield" },
1667 /* 147 */ { 0, "lwp_sema_wait" },
1668 /* 148 */ { 0, "lwp_sema_post" },
1669 /* 149 */ { 0, 0 /* reserved */ },
1670 /* 150 */ { 0, 0 /* reserved */ },
1671 /* 151 */ { 0, 0 /* reserved */ },
1672 /* 152 */ { 0, "modctl" },
1673 /* 153 */ { 0, "fchroot" },
1674 /* 154 */ { 0, "utimes" },
1675 /* 155 */ { 0, "vhangup" },
1676 /* 156 */ { do_unix_gettimeofday, "gettimeofday" },
1677 /* 157 */ { 0, "getitimer" },
1678 /* 158 */ { 0, "setitimer" },
1679 /* 159 */ { 0, "lwp_create" },
1680 /* 160 */ { 0, "lwp_exit" },
1681 /* 161 */ { 0, "lwp_suspend" },
1682 /* 162 */ { 0, "lwp_continue" },
1683 /* 163 */ { 0, "lwp_kill" },
1684 /* 164 */ { 0, "lwp_self" },
1685 /* 165 */ { 0, "lwp_setprivate" },
1686 /* 166 */ { 0, "lwp_getprivate" },
1687 /* 167 */ { 0, "lwp_wait" },
1688 /* 168 */ { 0, "lwp_mutex_unlock" },
1689 /* 169 */ { 0, "lwp_mutex_lock" },
1690 /* 170 */ { 0, "lwp_cond_wait" },
1691 /* 171 */ { 0, "lwp_cond_signal" },
1692 /* 172 */ { 0, "lwp_cond_broadcast" },
1693 /* 173 */ { 0, "pread" },
1694 /* 174 */ { 0, "pwrite" },
1695 /* 175 */ { 0, "llseek" },
1696 /* 176 */ { 0, "inst_sync" },
1697 /* 177 */ { 0, 0 /* reserved */ },
1698 /* 178 */ { 0, "kaio" },
1699 /* 179 */ { 0, 0 /* reserved */ },
1700 /* 180 */ { 0, 0 /* reserved */ },
1701 /* 181 */ { 0, 0 /* reserved */ },
1702 /* 182 */ { 0, 0 /* reserved */ },
1703 /* 183 */ { 0, 0 /* reserved */ },
1704 /* 184 */ { 0, "tsolsys" },
1705 /* 185 */ { 0, "acl" },
1706 /* 186 */ { 0, "auditsys" },
1707 /* 187 */ { 0, "processor_bind" },
1708 /* 188 */ { 0, "processor_info" },
1709 /* 189 */ { 0, "p_online" },
1710 /* 190 */ { 0, "sigqueue" },
1711 /* 191 */ { 0, "clock_gettime" },
1712 /* 192 */ { 0, "clock_settime" },
1713 /* 193 */ { 0, "clock_getres" },
1714 /* 194 */ { 0, "timer_create" },
1715 /* 195 */ { 0, "timer_delete" },
1716 /* 196 */ { 0, "timer_settime" },
1717 /* 197 */ { 0, "timer_gettime" },
1718 /* 198 */ { 0, "timer_getoverrun" },
1719 /* 199 */ { 0, "nanosleep" },
1720 /* 200 */ { 0, "facl" },
1721 /* 201 */ { 0, "door" },
1722 /* 202 */ { 0, "setreuid" },
1723 /* 203 */ { 0, "setregid" },
1724 /* 204 */ { 0, "install_utrap" },
1725 /* 205 */ { 0, 0 /* reserved */ },
1726 /* 206 */ { 0, 0 /* reserved */ },
1727 /* 207 */ { 0, 0 /* reserved */ },
1728 /* 208 */ { 0, 0 /* reserved */ },
1729 /* 209 */ { 0, 0 /* reserved */ },
1730 /* 210 */ { 0, "signotifywait" },
1731 /* 211 */ { 0, "lwp_sigredirect" },
1732 /* 212 */ { 0, "lwp_alarm" },
1735 static char *(solaris_error_names[]) = {
1736 /* 0 */ "ESUCCESS",
1737 /* 1 */ "EPERM",
1738 /* 2 */ "ENOENT",
1739 /* 3 */ "ESRCH",
1740 /* 4 */ "EINTR",
1741 /* 5 */ "EIO",
1742 /* 6 */ "ENXIO",
1743 /* 7 */ "E2BIG",
1744 /* 8 */ "ENOEXEC",
1745 /* 9 */ "EBADF",
1746 /* 10 */ "ECHILD",
1747 /* 11 */ "EAGAIN",
1748 /* 12 */ "ENOMEM",
1749 /* 13 */ "EACCES",
1750 /* 14 */ "EFAULT",
1751 /* 15 */ "ENOTBLK",
1752 /* 16 */ "EBUSY",
1753 /* 17 */ "EEXIST",
1754 /* 18 */ "EXDEV",
1755 /* 19 */ "ENODEV",
1756 /* 20 */ "ENOTDIR",
1757 /* 21 */ "EISDIR",
1758 /* 22 */ "EINVAL",
1759 /* 23 */ "ENFILE",
1760 /* 24 */ "EMFILE",
1761 /* 25 */ "ENOTTY",
1762 /* 26 */ "ETXTBSY",
1763 /* 27 */ "EFBIG",
1764 /* 28 */ "ENOSPC",
1765 /* 29 */ "ESPIPE",
1766 /* 30 */ "EROFS",
1767 /* 31 */ "EMLINK",
1768 /* 32 */ "EPIPE",
1769 /* 33 */ "EDOM",
1770 /* 34 */ "ERANGE",
1771 /* 35 */ "ENOMSG",
1772 /* 36 */ "EIDRM",
1773 /* 37 */ "ECHRNG",
1774 /* 38 */ "EL2NSYNC",
1775 /* 39 */ "EL3HLT",
1776 /* 40 */ "EL3RST",
1777 /* 41 */ "ELNRNG",
1778 /* 42 */ "EUNATCH",
1779 /* 43 */ "ENOCSI",
1780 /* 44 */ "EL2HLT",
1781 /* 45 */ "EDEADLK",
1782 /* 46 */ "ENOLCK",
1783 /* 47 */ "ECANCELED",
1784 /* 48 */ "ENOTSUP",
1785 /* 49 */ "EDQUOT",
1786 /* 50 */ "EBADE",
1787 /* 51 */ "EBADR",
1788 /* 52 */ "EXFULL",
1789 /* 53 */ "ENOANO",
1790 /* 54 */ "EBADRQC",
1791 /* 55 */ "EBADSLT",
1792 /* 56 */ "EDEADLOCK",
1793 /* 57 */ "EBFONT",
1794 /* 58 */ "Error code 58",
1795 /* 59 */ "Error code 59",
1796 /* 60 */ "ENOSTR",
1797 /* 61 */ "ENODATA",
1798 /* 62 */ "ETIME",
1799 /* 63 */ "ENOSR",
1800 /* 64 */ "ENONET",
1801 /* 65 */ "ENOPKG",
1802 /* 66 */ "EREMOTE",
1803 /* 67 */ "ENOLINK",
1804 /* 68 */ "EADV",
1805 /* 69 */ "ESRMNT",
1806 /* 70 */ "ECOMM",
1807 /* 71 */ "EPROTO",
1808 /* 72 */ "Error code 72",
1809 /* 73 */ "Error code 73",
1810 /* 74 */ "EMULTIHOP",
1811 /* 75 */ "Error code 75",
1812 /* 76 */ "Error code 76",
1813 /* 77 */ "EBADMSG",
1814 /* 78 */ "ENAMETOOLONG",
1815 /* 79 */ "EOVERFLOW",
1816 /* 80 */ "ENOTUNIQ",
1817 /* 81 */ "EBADFD",
1818 /* 82 */ "EREMCHG",
1819 /* 83 */ "ELIBACC",
1820 /* 84 */ "ELIBBAD",
1821 /* 85 */ "ELIBSCN",
1822 /* 86 */ "ELIBMAX",
1823 /* 87 */ "ELIBEXEC",
1824 /* 88 */ "EILSEQ",
1825 /* 89 */ "ENOSYS",
1826 /* 90 */ "ELOOP",
1827 /* 91 */ "ERESTART",
1828 /* 92 */ "ESTRPIPE",
1829 /* 93 */ "ENOTEMPTY",
1830 /* 94 */ "EUSERS",
1831 /* 95 */ "ENOTSOCK",
1832 /* 96 */ "EDESTADDRREQ",
1833 /* 97 */ "EMSGSIZE",
1834 /* 98 */ "EPROTOTYPE",
1835 /* 99 */ "ENOPROTOOPT",
1836 /* 100 */ "Error code 100",
1837 /* 101 */ "Error code 101",
1838 /* 102 */ "Error code 102",
1839 /* 103 */ "Error code 103",
1840 /* 104 */ "Error code 104",
1841 /* 105 */ "Error code 105",
1842 /* 106 */ "Error code 106",
1843 /* 107 */ "Error code 107",
1844 /* 108 */ "Error code 108",
1845 /* 109 */ "Error code 109",
1846 /* 110 */ "Error code 110",
1847 /* 111 */ "Error code 111",
1848 /* 112 */ "Error code 112",
1849 /* 113 */ "Error code 113",
1850 /* 114 */ "Error code 114",
1851 /* 115 */ "Error code 115",
1852 /* 116 */ "Error code 116",
1853 /* 117 */ "Error code 117",
1854 /* 118 */ "Error code 118",
1855 /* 119 */ "Error code 119",
1856 /* 120 */ "EPROTONOSUPPORT",
1857 /* 121 */ "ESOCKTNOSUPPORT",
1858 /* 122 */ "EOPNOTSUPP",
1859 /* 123 */ "EPFNOSUPPORT",
1860 /* 124 */ "EAFNOSUPPORT",
1861 /* 125 */ "EADDRINUSE",
1862 /* 126 */ "EADDRNOTAVAIL",
1863 /* 127 */ "ENETDOWN",
1864 /* 128 */ "ENETUNREACH",
1865 /* 129 */ "ENETRESET",
1866 /* 130 */ "ECONNABORTED",
1867 /* 131 */ "ECONNRESET",
1868 /* 132 */ "ENOBUFS",
1869 /* 133 */ "EISCONN",
1870 /* 134 */ "ENOTCONN",
1871 /* 135 */ "Error code 135", /* XENIX has 135 - 142 */
1872 /* 136 */ "Error code 136",
1873 /* 137 */ "Error code 137",
1874 /* 138 */ "Error code 138",
1875 /* 139 */ "Error code 139",
1876 /* 140 */ "Error code 140",
1877 /* 141 */ "Error code 141",
1878 /* 142 */ "Error code 142",
1879 /* 143 */ "ESHUTDOWN",
1880 /* 144 */ "ETOOMANYREFS",
1881 /* 145 */ "ETIMEDOUT",
1882 /* 146 */ "ECONNREFUSED",
1883 /* 147 */ "EHOSTDOWN",
1884 /* 148 */ "EHOSTUNREACH",
1885 /* 149 */ "EALREADY",
1886 /* 150 */ "EINPROGRESS",
1887 /* 151 */ "ESTALE",
1890 static char *(solaris_signal_names[]) = {
1891 /* 0 */ 0,
1892 /* 1 */ "SIGHUP",
1893 /* 2 */ "SIGINT",
1894 /* 3 */ "SIGQUIT",
1895 /* 4 */ "SIGILL",
1896 /* 5 */ "SIGTRAP",
1897 /* 6 */ "SIGABRT",
1898 /* 7 */ "SIGEMT",
1899 /* 8 */ "SIGFPE",
1900 /* 9 */ "SIGKILL",
1901 /* 10 */ "SIGBUS",
1902 /* 11 */ "SIGSEGV",
1903 /* 12 */ "SIGSYS",
1904 /* 13 */ "SIGPIPE",
1905 /* 14 */ "SIGALRM",
1906 /* 15 */ "SIGTERM",
1907 /* 16 */ "SIGUSR1",
1908 /* 17 */ "SIGUSR2",
1909 /* 18 */ "SIGCHLD",
1910 /* 19 */ "SIGPWR",
1911 /* 20 */ "SIGWINCH",
1912 /* 21 */ "SIGURG",
1913 /* 22 */ "SIGPOLL",
1914 /* 23 */ "SIGSTOP",
1915 /* 24 */ "SIGTSTP",
1916 /* 25 */ "SIGCONT",
1917 /* 26 */ "SIGTTIN",
1918 /* 27 */ "SIGTTOU",
1919 /* 28 */ "SIGVTALRM",
1920 /* 29 */ "SIGPROF",
1921 /* 30 */ "SIGXCPU",
1922 /* 31 */ "SIGXFSZ",
1923 /* 32 */ "SIGWAITING",
1924 /* 33 */ "SIGLWP",
1925 /* 34 */ "SIGFREEZE",
1926 /* 35 */ "SIGTHAW",
1927 /* 36 */ "SIGCANCEL",
1930 static emul_syscall emul_solaris_syscalls = {
1931 solaris_descriptors,
1932 ARRAY_SIZE (solaris_descriptors),
1933 solaris_error_names,
1934 ARRAY_SIZE (solaris_error_names),
1935 solaris_signal_names,
1936 ARRAY_SIZE (solaris_signal_names),
1940 /* Solaris's os_emul interface, most are just passed on to the generic
1941 syscall stuff */
1943 static os_emul_data *
1944 emul_solaris_create(device *root,
1945 bfd *image,
1946 const char *name)
1948 /* check that this emulation is really for us */
1949 if (name != NULL && strcmp(name, "solaris") != 0)
1950 return NULL;
1952 if (image == NULL)
1953 return NULL;
1955 return emul_unix_create(root, image, "solaris", &emul_solaris_syscalls);
1958 static void
1959 emul_solaris_init(os_emul_data *emul_data,
1960 int nr_cpus)
1962 fd_closed[0] = 0;
1963 fd_closed[1] = 0;
1964 fd_closed[2] = 0;
1967 static void
1968 emul_solaris_system_call(cpu *processor,
1969 unsigned_word cia,
1970 os_emul_data *emul_data)
1972 emul_do_system_call(emul_data,
1973 emul_data->syscalls,
1974 cpu_registers(processor)->gpr[0],
1975 3, /*r3 contains arg0*/
1976 processor,
1977 cia);
1980 const os_emul emul_solaris = {
1981 "solaris",
1982 emul_solaris_create,
1983 emul_solaris_init,
1984 emul_solaris_system_call,
1985 0, /*instruction_call*/
1986 0 /*data*/
1990 /* EMULATION
1992 Linux - Emulation of user programs for Linux/PPC
1994 DESCRIPTION
1999 /* Linux specific implementation */
2001 typedef uint32_t linux_dev_t;
2002 typedef uint32_t linux_ino_t;
2003 typedef uint32_t linux_mode_t;
2004 typedef uint16_t linux_nlink_t;
2005 typedef int32_t linux_off_t;
2006 typedef int32_t linux_pid_t;
2007 typedef uint32_t linux_uid_t;
2008 typedef uint32_t linux_gid_t;
2009 typedef uint32_t linux_size_t;
2010 typedef int32_t linux_ssize_t;
2011 typedef int32_t linux_ptrdiff_t;
2012 typedef int32_t linux_time_t;
2013 typedef int32_t linux_clock_t;
2014 typedef int32_t linux_daddr_t;
2016 #ifdef HAVE_SYS_STAT_H
2017 /* For the PowerPC, don't both with the 'old' stat structure, since there
2018 should be no extant binaries with that structure. */
2020 struct linux_stat {
2021 linux_dev_t st_dev;
2022 linux_ino_t st_ino;
2023 linux_mode_t st_mode;
2024 linux_nlink_t st_nlink;
2025 linux_uid_t st_uid;
2026 linux_gid_t st_gid;
2027 linux_dev_t st_rdev;
2028 linux_off_t st_size;
2029 uint32_t st_blksize;
2030 uint32_t st_blocks;
2031 uint32_t st_atimx; /* don't use st_{a,c,m}time, that might a macro */
2032 uint32_t __unused1; /* defined by the host's stat.h */
2033 uint32_t st_mtimx;
2034 uint32_t __unused2;
2035 uint32_t st_ctimx;
2036 uint32_t __unused3;
2037 uint32_t __unused4;
2038 uint32_t __unused5;
2041 /* Convert from host stat structure to solaris stat structure */
2042 STATIC_INLINE_EMUL_UNIX void
2043 convert_to_linux_stat(unsigned_word addr,
2044 struct stat *host,
2045 cpu *processor,
2046 unsigned_word cia)
2048 struct linux_stat target;
2050 target.st_dev = H2T_4(host->st_dev);
2051 target.st_ino = H2T_4(host->st_ino);
2052 target.st_mode = H2T_4(host->st_mode);
2053 target.st_nlink = H2T_2(host->st_nlink);
2054 target.st_uid = H2T_4(host->st_uid);
2055 target.st_gid = H2T_4(host->st_gid);
2056 target.st_size = H2T_4(host->st_size);
2058 #ifdef HAVE_ST_RDEV
2059 target.st_rdev = H2T_4(host->st_rdev);
2060 #else
2061 target.st_rdev = 0;
2062 #endif
2064 #ifdef HAVE_ST_BLKSIZE
2065 target.st_blksize = H2T_4(host->st_blksize);
2066 #else
2067 target.st_blksize = 0;
2068 #endif
2070 #ifdef HAVE_ST_BLOCKS
2071 target.st_blocks = H2T_4(host->st_blocks);
2072 #else
2073 target.st_blocks = 0;
2074 #endif
2076 target.st_atimx = H2T_4(host->st_atime);
2077 target.st_ctimx = H2T_4(host->st_ctime);
2078 target.st_mtimx = H2T_4(host->st_mtime);
2079 target.__unused1 = 0;
2080 target.__unused2 = 0;
2081 target.__unused3 = 0;
2082 target.__unused4 = 0;
2083 target.__unused5 = 0;
2085 emul_write_buffer(&target, addr, sizeof(target), processor, cia);
2087 #endif /* HAVE_SYS_STAT_H */
2089 #ifndef HAVE_STAT
2090 #define do_linux_stat 0
2091 #else
2092 static void
2093 do_linux_stat(os_emul_data *emul,
2094 unsigned call,
2095 const int arg0,
2096 cpu *processor,
2097 unsigned_word cia)
2099 unsigned_word path_addr = cpu_registers(processor)->gpr[arg0];
2100 unsigned_word stat_pkt = cpu_registers(processor)->gpr[arg0+1];
2101 char path_buf[PATH_MAX];
2102 struct stat buf;
2103 char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia);
2104 int status;
2106 if (WITH_TRACE && ppc_trace[trace_os_emul])
2107 printf_filtered ("0x%lx [%s], 0x%lx", (long)path_addr, path, (long)stat_pkt);
2109 status = stat (path, &buf);
2110 if (status == 0)
2111 convert_to_linux_stat (stat_pkt, &buf, processor, cia);
2113 emul_write_status(processor, status, errno);
2115 #endif
2117 #ifndef HAVE_LSTAT
2118 #define do_linux_lstat 0
2119 #else
2120 static void
2121 do_linux_lstat(os_emul_data *emul,
2122 unsigned call,
2123 const int arg0,
2124 cpu *processor,
2125 unsigned_word cia)
2127 unsigned_word path_addr = cpu_registers(processor)->gpr[arg0];
2128 unsigned_word stat_pkt = cpu_registers(processor)->gpr[arg0+1];
2129 char path_buf[PATH_MAX];
2130 struct stat buf;
2131 char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia);
2132 int status;
2134 if (WITH_TRACE && ppc_trace[trace_os_emul])
2135 printf_filtered ("0x%lx [%s], 0x%lx", (long)path_addr, path, (long)stat_pkt);
2137 status = lstat (path, &buf);
2138 if (status == 0)
2139 convert_to_linux_stat (stat_pkt, &buf, processor, cia);
2141 emul_write_status(processor, status, errno);
2143 #endif
2145 #ifndef HAVE_FSTAT
2146 #define do_linux_fstat 0
2147 #else
2148 static void
2149 do_linux_fstat(os_emul_data *emul,
2150 unsigned call,
2151 const int arg0,
2152 cpu *processor,
2153 unsigned_word cia)
2155 int fildes = (int)cpu_registers(processor)->gpr[arg0];
2156 unsigned_word stat_pkt = cpu_registers(processor)->gpr[arg0+1];
2157 struct stat buf;
2158 int status;
2160 if (WITH_TRACE && ppc_trace[trace_os_emul])
2161 printf_filtered ("%d, 0x%lx", fildes, (long)stat_pkt);
2163 status = fdbad (fildes);
2164 if (status == 0)
2165 status = fstat (fildes, &buf);
2166 if (status == 0)
2167 convert_to_linux_stat (stat_pkt, &buf, processor, cia);
2169 emul_write_status(processor, status, errno);
2171 #endif
2173 #if defined(HAVE_TERMIO_STRUCTURE) || defined(HAVE_TERMIOS_STRUCTURE)
2174 #define LINUX_NCC 10
2175 #define LINUX_NCCS 19
2177 #define LINUX_VINTR 0
2178 #define LINUX_VQUIT 1
2179 #define LINUX_VERASE 2
2180 #define LINUX_VKILL 3
2181 #define LINUX_VEOF 4
2182 #define LINUX_VMIN 5
2183 #define LINUX_VEOL 6
2184 #define LINUX_VTIME 7
2185 #define LINUX_VEOL2 8
2186 #define LINUX_VSWTC 9
2187 #define LINUX_VWERASE 10
2188 #define LINUX_VREPRINT 11
2189 #define LINUX_VSUSP 12
2190 #define LINUX_VSTART 13
2191 #define LINUX_VSTOP 14
2192 #define LINUX_VLNEXT 15
2193 #define LINUX_VDISCARD 16
2195 #define LINUX_IOC_NRBITS 8
2196 #define LINUX_IOC_TYPEBITS 8
2197 #define LINUX_IOC_SIZEBITS 13
2198 #define LINUX_IOC_DIRBITS 3
2200 #define LINUX_IOC_NRMASK ((1 << LINUX_IOC_NRBITS)-1)
2201 #define LINUX_IOC_TYPEMASK ((1 << LINUX_IOC_TYPEBITS)-1)
2202 #define LINUX_IOC_SIZEMASK ((1 << LINUX_IOC_SIZEBITS)-1)
2203 #define LINUX_IOC_DIRMASK ((1 << LINUX_IOC_DIRBITS)-1)
2205 #define LINUX_IOC_NRSHIFT 0
2206 #define LINUX_IOC_TYPESHIFT (LINUX_IOC_NRSHIFT+LINUX_IOC_NRBITS)
2207 #define LINUX_IOC_SIZESHIFT (LINUX_IOC_TYPESHIFT+LINUX_IOC_TYPEBITS)
2208 #define LINUX_IOC_DIRSHIFT (LINUX_IOC_SIZESHIFT+LINUX_IOC_SIZEBITS)
2211 * Direction bits _IOC_NONE could be 0, but OSF/1 gives it a bit.
2212 * And this turns out useful to catch old ioctl numbers in header
2213 * files for us.
2215 #define LINUX_IOC_NONE 1U
2216 #define LINUX_IOC_READ 2U
2217 #define LINUX_IOC_WRITE 4U
2219 #define LINUX_IOC(dir,type,nr,size) \
2220 (((dir) << LINUX_IOC_DIRSHIFT) | \
2221 ((type) << LINUX_IOC_TYPESHIFT) | \
2222 ((nr) << LINUX_IOC_NRSHIFT) | \
2223 ((size) << LINUX_IOC_SIZESHIFT))
2225 /* used to create numbers */
2226 #define LINUX_IO(type,nr) LINUX_IOC(LINUX_IOC_NONE,(type),(nr),0)
2227 #define LINUX_IOR(type,nr,size) LINUX_IOC(LINUX_IOC_READ,(type),(nr),sizeof(size))
2228 #define LINUX_IOW(type,nr,size) LINUX_IOC(LINUX_IOC_WRITE,(type),(nr),sizeof(size))
2229 #define LINUX_IOWR(type,nr,size) LINUX_IOC(LINUX_IOC_READ|LINUX_IOC_WRITE,(type),(nr),sizeof(size))
2230 #endif
2232 #if defined(HAVE_TERMIO_STRUCTURE) || defined(HAVE_TERMIOS_STRUCTURE)
2233 /* Convert to/from host termio structure */
2235 struct linux_termio {
2236 uint16_t c_iflag; /* input modes */
2237 uint16_t c_oflag; /* output modes */
2238 uint16_t c_cflag; /* control modes */
2239 uint16_t c_lflag; /* line discipline modes */
2240 uint8_t c_line; /* line discipline */
2241 uint8_t c_cc[LINUX_NCC]; /* control chars */
2244 STATIC_INLINE_EMUL_UNIX void
2245 convert_to_linux_termio(unsigned_word addr,
2246 struct termio *host,
2247 cpu *processor,
2248 unsigned_word cia)
2250 struct linux_termio target;
2251 int i;
2253 target.c_iflag = H2T_2 (host->c_iflag);
2254 target.c_oflag = H2T_2 (host->c_oflag);
2255 target.c_cflag = H2T_2 (host->c_cflag);
2256 target.c_lflag = H2T_2 (host->c_lflag);
2258 #if defined(HAVE_TERMIO_CLINE) || defined(HAVE_TERMIOS_CLINE)
2259 target.c_line = host->c_line;
2260 #else
2261 target.c_line = 0;
2262 #endif
2264 for (i = 0; i < LINUX_NCC; i++)
2265 target.c_cc[i] = 0;
2267 #ifdef VINTR
2268 target.c_cc[LINUX_VINTR] = host->c_cc[VINTR];
2269 #endif
2271 #ifdef VQUIT
2272 target.c_cc[LINUX_VQUIT] = host->c_cc[VQUIT];
2273 #endif
2275 #ifdef VERASE
2276 target.c_cc[LINUX_VERASE] = host->c_cc[VERASE];
2277 #endif
2279 #ifdef VKILL
2280 target.c_cc[LINUX_VKILL] = host->c_cc[VKILL];
2281 #endif
2283 #ifdef VEOF
2284 target.c_cc[LINUX_VEOF] = host->c_cc[VEOF];
2285 #endif
2287 #ifdef VMIN
2288 target.c_cc[LINUX_VMIN] = host->c_cc[VMIN];
2289 #endif
2291 #ifdef VEOL
2292 target.c_cc[LINUX_VEOL] = host->c_cc[VEOL];
2293 #endif
2295 #ifdef VTIME
2296 target.c_cc[LINUX_VTIME] = host->c_cc[VTIME];
2297 #endif
2299 #ifdef VEOL2
2300 target.c_cc[LINUX_VEOL2] = host->c_cc[VEOL2];
2301 #endif
2303 #ifdef VSWTC
2304 target.c_cc[LINUX_VSWTC] = host->c_cc[VSWTC];
2305 #endif
2307 #ifdef VSWTCH
2308 target.c_cc[LINUX_VSWTC] = host->c_cc[VSWTCH];
2309 #endif
2311 emul_write_buffer(&target, addr, sizeof(target), processor, cia);
2313 #endif /* HAVE_TERMIO_STRUCTURE */
2315 #ifdef HAVE_TERMIOS_STRUCTURE
2316 /* Convert to/from host termios structure */
2318 typedef uint32_t linux_tcflag_t;
2319 typedef uint8_t linux_cc_t;
2320 typedef uint32_t linux_speed_t;
2322 struct linux_termios {
2323 linux_tcflag_t c_iflag;
2324 linux_tcflag_t c_oflag;
2325 linux_tcflag_t c_cflag;
2326 linux_tcflag_t c_lflag;
2327 linux_cc_t c_cc[LINUX_NCCS];
2328 linux_cc_t c_line;
2329 int32_t c_ispeed;
2330 int32_t c_ospeed;
2333 STATIC_INLINE_EMUL_UNIX void
2334 convert_to_linux_termios(unsigned_word addr,
2335 struct termios *host,
2336 cpu *processor,
2337 unsigned_word cia)
2339 struct linux_termios target;
2340 int i;
2342 target.c_iflag = H2T_4 (host->c_iflag);
2343 target.c_oflag = H2T_4 (host->c_oflag);
2344 target.c_cflag = H2T_4 (host->c_cflag);
2345 target.c_lflag = H2T_4 (host->c_lflag);
2347 for (i = 0; i < LINUX_NCCS; i++)
2348 target.c_cc[i] = 0;
2350 #ifdef VINTR
2351 target.c_cc[LINUX_VINTR] = host->c_cc[VINTR];
2352 #endif
2354 #ifdef VQUIT
2355 target.c_cc[LINUX_VQUIT] = host->c_cc[VQUIT];
2356 #endif
2358 #ifdef VERASE
2359 target.c_cc[LINUX_VERASE] = host->c_cc[VERASE];
2360 #endif
2362 #ifdef VKILL
2363 target.c_cc[LINUX_VKILL] = host->c_cc[VKILL];
2364 #endif
2366 #ifdef VEOF
2367 target.c_cc[LINUX_VEOF] = host->c_cc[VEOF];
2368 #endif
2370 #ifdef VEOL
2371 target.c_cc[LINUX_VEOL] = host->c_cc[VEOL];
2372 #endif
2374 #ifdef VEOL2
2375 target.c_cc[LINUX_VEOL2] = host->c_cc[VEOL2];
2376 #endif
2378 #ifdef VSWTCH
2379 target.c_cc[LINUX_VSWTC] = host->c_cc[VSWTCH];
2380 #endif
2382 #ifdef HAVE_TERMIOS_CLINE
2383 target.c_line = host->c_line;
2384 #else
2385 target.c_line = 0;
2386 #endif
2388 #ifdef HAVE_CFGETISPEED
2389 target.c_ispeed = cfgetispeed (host);
2390 #else
2391 target.c_ispeed = 0;
2392 #endif
2394 #ifdef HAVE_CFGETOSPEED
2395 target.c_ospeed = cfgetospeed (host);
2396 #else
2397 target.c_ospeed = 0;
2398 #endif
2400 emul_write_buffer(&target, addr, sizeof(target), processor, cia);
2402 #endif /* HAVE_TERMIOS_STRUCTURE */
2404 #ifndef HAVE_IOCTL
2405 #define do_linux_ioctl 0
2406 #else
2407 static void
2408 do_linux_ioctl(os_emul_data *emul,
2409 unsigned call,
2410 const int arg0,
2411 cpu *processor,
2412 unsigned_word cia)
2414 int fildes = cpu_registers(processor)->gpr[arg0];
2415 unsigned request = cpu_registers(processor)->gpr[arg0+1];
2416 unsigned_word argp_addr = cpu_registers(processor)->gpr[arg0+2];
2417 int status = 0;
2418 const char *name = "<unknown>";
2420 #ifdef HAVE_TERMIOS_STRUCTURE
2421 struct termios host_termio;
2423 #else
2424 #ifdef HAVE_TERMIO_STRUCTURE
2425 struct termio host_termio;
2426 #endif
2427 #endif
2429 status = fdbad (fildes);
2430 if (status != 0)
2431 goto done;
2433 switch (request)
2435 case 0: /* make sure we have at least one case */
2436 default:
2437 status = -1;
2438 errno = EINVAL;
2439 break;
2441 #if defined(HAVE_TERMIO_STRUCTURE) || defined(HAVE_TERMIOS_STRUCTURE)
2442 #if defined(TCGETA) || defined(TCGETS) || defined(HAVE_TCGETATTR)
2443 case LINUX_IOR('t', 23, struct linux_termio): /* TCGETA */
2444 name = "TCGETA";
2445 #ifdef HAVE_TCGETATTR
2446 status = tcgetattr(fildes, &host_termio);
2447 #elif defined(TCGETS)
2448 status = ioctl (fildes, TCGETS, &host_termio);
2449 #else
2450 status = ioctl (fildes, TCGETA, &host_termio);
2451 #endif
2452 if (status == 0)
2453 convert_to_linux_termio (argp_addr, &host_termio, processor, cia);
2454 break;
2455 #endif /* TCGETA */
2456 #endif /* HAVE_TERMIO_STRUCTURE */
2458 #ifdef HAVE_TERMIOS_STRUCTURE
2459 #if defined(TCGETS) || defined(HAVE_TCGETATTR)
2460 case LINUX_IOR('t', 19, struct linux_termios): /* TCGETS */
2461 name = "TCGETS";
2462 #ifdef HAVE_TCGETATTR
2463 status = tcgetattr(fildes, &host_termio);
2464 #else
2465 status = ioctl (fildes, TCGETS, &host_termio);
2466 #endif
2467 if (status == 0)
2468 convert_to_linux_termios (argp_addr, &host_termio, processor, cia);
2469 break;
2470 #endif /* TCGETS */
2471 #endif /* HAVE_TERMIOS_STRUCTURE */
2474 done:
2475 emul_write_status(processor, status, errno);
2477 if (WITH_TRACE && ppc_trace[trace_os_emul])
2478 printf_filtered ("%d, 0x%x [%s], 0x%lx", fildes, request, name, (long)argp_addr);
2480 #endif /* HAVE_IOCTL */
2482 static emul_syscall_descriptor linux_descriptors[] = {
2483 /* 0 */ { 0, "setup" },
2484 /* 1 */ { do_unix_exit, "exit" },
2485 /* 2 */ { 0, "fork" },
2486 /* 3 */ { do_unix_read, "read" },
2487 /* 4 */ { do_unix_write, "write" },
2488 /* 5 */ { do_unix_open, "open" },
2489 /* 6 */ { do_unix_close, "close" },
2490 /* 7 */ { 0, "waitpid" },
2491 /* 8 */ { 0, "creat" },
2492 /* 9 */ { do_unix_link, "link" },
2493 /* 10 */ { do_unix_unlink, "unlink" },
2494 /* 11 */ { 0, "execve" },
2495 /* 12 */ { do_unix_chdir, "chdir" },
2496 /* 13 */ { do_unix_time, "time" },
2497 /* 14 */ { 0, "mknod" },
2498 /* 15 */ { 0, "chmod" },
2499 /* 16 */ { 0, "chown" },
2500 /* 17 */ { 0, "break" },
2501 /* 18 */ { 0, "stat" },
2502 /* 19 */ { do_unix_lseek, "lseek" },
2503 /* 20 */ { do_unix_getpid, "getpid" },
2504 /* 21 */ { 0, "mount" },
2505 /* 22 */ { 0, "umount" },
2506 /* 23 */ { 0, "setuid" },
2507 /* 24 */ { do_unix_getuid, "getuid" },
2508 /* 25 */ { 0, "stime" },
2509 /* 26 */ { 0, "ptrace" },
2510 /* 27 */ { 0, "alarm" },
2511 /* 28 */ { 0, "fstat" },
2512 /* 29 */ { 0, "pause" },
2513 /* 30 */ { 0, "utime" },
2514 /* 31 */ { 0, "stty" },
2515 /* 32 */ { 0, "gtty" },
2516 /* 33 */ { do_unix_access, "access" },
2517 /* 34 */ { 0, "nice" },
2518 /* 35 */ { 0, "ftime" },
2519 /* 36 */ { 0, "sync" },
2520 /* 37 */ { 0, "kill" },
2521 /* 38 */ { 0, "rename" },
2522 /* 39 */ { do_unix_mkdir, "mkdir" },
2523 /* 40 */ { do_unix_rmdir, "rmdir" },
2524 /* 41 */ { do_unix_dup, "dup" },
2525 /* 42 */ { 0, "pipe" },
2526 /* 43 */ { 0, "times" },
2527 /* 44 */ { 0, "prof" },
2528 /* 45 */ { do_unix_break, "brk" },
2529 /* 46 */ { 0, "setgid" },
2530 /* 47 */ { do_unix_getgid, "getgid" },
2531 /* 48 */ { 0, "signal" },
2532 /* 49 */ { do_unix_geteuid, "geteuid" },
2533 /* 50 */ { do_unix_getegid, "getegid" },
2534 /* 51 */ { 0, "acct" },
2535 /* 52 */ { 0, "phys" },
2536 /* 53 */ { 0, "lock" },
2537 /* 54 */ { do_linux_ioctl, "ioctl" },
2538 /* 55 */ { 0, "fcntl" },
2539 /* 56 */ { 0, "mpx" },
2540 /* 57 */ { 0, "setpgid" },
2541 /* 58 */ { 0, "ulimit" },
2542 /* 59 */ { 0, "olduname" },
2543 /* 60 */ { do_unix_umask, "umask" },
2544 /* 61 */ { 0, "chroot" },
2545 /* 62 */ { 0, "ustat" },
2546 /* 63 */ { do_unix_dup2, "dup2" },
2547 /* 64 */ { do_unix_getppid, "getppid" },
2548 /* 65 */ { 0, "getpgrp" },
2549 /* 66 */ { 0, "setsid" },
2550 /* 67 */ { 0, "sigaction" },
2551 /* 68 */ { 0, "sgetmask" },
2552 /* 69 */ { 0, "ssetmask" },
2553 /* 70 */ { 0, "setreuid" },
2554 /* 71 */ { 0, "setregid" },
2555 /* 72 */ { 0, "sigsuspend" },
2556 /* 73 */ { 0, "sigpending" },
2557 /* 74 */ { 0, "sethostname" },
2558 /* 75 */ { 0, "setrlimit" },
2559 /* 76 */ { 0, "getrlimit" },
2560 /* 77 */ { do_unix_getrusage, "getrusage" },
2561 /* 78 */ { do_unix_gettimeofday, "gettimeofday" },
2562 /* 79 */ { 0, "settimeofday" },
2563 /* 80 */ { 0, "getgroups" },
2564 /* 81 */ { 0, "setgroups" },
2565 /* 82 */ { 0, "select" },
2566 /* 83 */ { do_unix_symlink, "symlink" },
2567 /* 84 */ { 0, "lstat" },
2568 /* 85 */ { 0, "readlink" },
2569 /* 86 */ { 0, "uselib" },
2570 /* 87 */ { 0, "swapon" },
2571 /* 88 */ { 0, "reboot" },
2572 /* 89 */ { 0, "readdir" },
2573 /* 90 */ { 0, "mmap" },
2574 /* 91 */ { 0, "munmap" },
2575 /* 92 */ { 0, "truncate" },
2576 /* 93 */ { 0, "ftruncate" },
2577 /* 94 */ { 0, "fchmod" },
2578 /* 95 */ { 0, "fchown" },
2579 /* 96 */ { 0, "getpriority" },
2580 /* 97 */ { 0, "setpriority" },
2581 /* 98 */ { 0, "profil" },
2582 /* 99 */ { 0, "statfs" },
2583 /* 100 */ { 0, "fstatfs" },
2584 /* 101 */ { 0, "ioperm" },
2585 /* 102 */ { 0, "socketcall" },
2586 /* 103 */ { 0, "syslog" },
2587 /* 104 */ { 0, "setitimer" },
2588 /* 105 */ { 0, "getitimer" },
2589 /* 106 */ { do_linux_stat, "newstat" },
2590 /* 107 */ { do_linux_lstat, "newlstat" },
2591 /* 108 */ { do_linux_fstat, "newfstat" },
2592 /* 109 */ { 0, "uname" },
2593 /* 110 */ { 0, "iopl" },
2594 /* 111 */ { 0, "vhangup" },
2595 /* 112 */ { 0, "idle" },
2596 /* 113 */ { 0, "vm86" },
2597 /* 114 */ { 0, "wait4" },
2598 /* 115 */ { 0, "swapoff" },
2599 /* 116 */ { 0, "sysinfo" },
2600 /* 117 */ { 0, "ipc" },
2601 /* 118 */ { 0, "fsync" },
2602 /* 119 */ { 0, "sigreturn" },
2603 /* 120 */ { 0, "clone" },
2604 /* 121 */ { 0, "setdomainname" },
2605 /* 122 */ { 0, "newuname" },
2606 /* 123 */ { 0, "modify_ldt" },
2607 /* 124 */ { 0, "adjtimex" },
2608 /* 125 */ { 0, "mprotect" },
2609 /* 126 */ { 0, "sigprocmask" },
2610 /* 127 */ { 0, "create_module" },
2611 /* 128 */ { 0, "init_module" },
2612 /* 129 */ { 0, "delete_module" },
2613 /* 130 */ { 0, "get_kernel_syms" },
2614 /* 131 */ { 0, "quotactl" },
2615 /* 132 */ { 0, "getpgid" },
2616 /* 133 */ { 0, "fchdir" },
2617 /* 134 */ { 0, "bdflush" },
2618 /* 135 */ { 0, "sysfs" },
2619 /* 136 */ { 0, "personality" },
2620 /* 137 */ { 0, "afs_syscall" },
2621 /* 138 */ { 0, "setfsuid" },
2622 /* 139 */ { 0, "setfsgid" },
2623 /* 140 */ { 0, "llseek" },
2624 /* 141 */ { 0, "getdents" },
2625 /* 142 */ { 0, "newselect" },
2626 /* 143 */ { 0, "flock" },
2627 /* 144 */ { 0, "msync" },
2628 /* 145 */ { 0, "readv" },
2629 /* 146 */ { 0, "writev" },
2630 /* 147 */ { 0, "getsid" },
2631 /* 148 */ { 0, "fdatasync" },
2632 /* 149 */ { 0, "sysctl" },
2633 /* 150 */ { 0, "mlock" },
2634 /* 151 */ { 0, "munlock" },
2635 /* 152 */ { 0, "mlockall" },
2636 /* 153 */ { 0, "munlockall" },
2637 /* 154 */ { 0, "sched_setparam" },
2638 /* 155 */ { 0, "sched_getparam" },
2639 /* 156 */ { 0, "sched_setscheduler" },
2640 /* 157 */ { 0, "sched_getscheduler" },
2641 /* 158 */ { 0, "sched_yield" },
2642 /* 159 */ { 0, "sched_get_priority_max" },
2643 /* 160 */ { 0, "sched_get_priority_min" },
2644 /* 161 */ { 0, "sched_rr_get_interval" },
2647 static char *(linux_error_names[]) = {
2648 /* 0 */ "ESUCCESS",
2649 /* 1 */ "EPERM",
2650 /* 2 */ "ENOENT",
2651 /* 3 */ "ESRCH",
2652 /* 4 */ "EINTR",
2653 /* 5 */ "EIO",
2654 /* 6 */ "ENXIO",
2655 /* 7 */ "E2BIG",
2656 /* 8 */ "ENOEXEC",
2657 /* 9 */ "EBADF",
2658 /* 10 */ "ECHILD",
2659 /* 11 */ "EAGAIN",
2660 /* 12 */ "ENOMEM",
2661 /* 13 */ "EACCES",
2662 /* 14 */ "EFAULT",
2663 /* 15 */ "ENOTBLK",
2664 /* 16 */ "EBUSY",
2665 /* 17 */ "EEXIST",
2666 /* 18 */ "EXDEV",
2667 /* 19 */ "ENODEV",
2668 /* 20 */ "ENOTDIR",
2669 /* 21 */ "EISDIR",
2670 /* 22 */ "EINVAL",
2671 /* 23 */ "ENFILE",
2672 /* 24 */ "EMFILE",
2673 /* 25 */ "ENOTTY",
2674 /* 26 */ "ETXTBSY",
2675 /* 27 */ "EFBIG",
2676 /* 28 */ "ENOSPC",
2677 /* 29 */ "ESPIPE",
2678 /* 30 */ "EROFS",
2679 /* 31 */ "EMLINK",
2680 /* 32 */ "EPIPE",
2681 /* 33 */ "EDOM",
2682 /* 34 */ "ERANGE",
2683 /* 35 */ "EDEADLK",
2684 /* 36 */ "ENAMETOOLONG",
2685 /* 37 */ "ENOLCK",
2686 /* 38 */ "ENOSYS",
2687 /* 39 */ "ENOTEMPTY",
2688 /* 40 */ "ELOOP",
2689 /* 41 */ 0,
2690 /* 42 */ "ENOMSG",
2691 /* 43 */ "EIDRM",
2692 /* 44 */ "ECHRNG",
2693 /* 45 */ "EL2NSYNC",
2694 /* 46 */ "EL3HLT",
2695 /* 47 */ "EL3RST",
2696 /* 48 */ "ELNRNG",
2697 /* 49 */ "EUNATCH",
2698 /* 50 */ "ENOCSI",
2699 /* 51 */ "EL2HLT",
2700 /* 52 */ "EBADE",
2701 /* 53 */ "EBADR",
2702 /* 54 */ "EXFULL",
2703 /* 55 */ "ENOANO",
2704 /* 56 */ "EBADRQC",
2705 /* 57 */ "EBADSLT",
2706 /* 58 */ "EDEADLOCK",
2707 /* 59 */ "EBFONT",
2708 /* 60 */ "ENOSTR",
2709 /* 61 */ "ENODATA",
2710 /* 62 */ "ETIME",
2711 /* 63 */ "ENOSR",
2712 /* 64 */ "ENONET",
2713 /* 65 */ "ENOPKG",
2714 /* 66 */ "EREMOTE",
2715 /* 67 */ "ENOLINK",
2716 /* 68 */ "EADV",
2717 /* 69 */ "ESRMNT",
2718 /* 70 */ "ECOMM",
2719 /* 71 */ "EPROTO",
2720 /* 72 */ "EMULTIHOP",
2721 /* 73 */ "EDOTDOT",
2722 /* 74 */ "EBADMSG",
2723 /* 75 */ "EOVERFLOW",
2724 /* 76 */ "ENOTUNIQ",
2725 /* 77 */ "EBADFD",
2726 /* 78 */ "EREMCHG",
2727 /* 79 */ "ELIBACC",
2728 /* 80 */ "ELIBBAD",
2729 /* 81 */ "ELIBSCN",
2730 /* 82 */ "ELIBMAX",
2731 /* 83 */ "ELIBEXEC",
2732 /* 84 */ "EILSEQ",
2733 /* 85 */ "ERESTART",
2734 /* 86 */ "ESTRPIPE",
2735 /* 87 */ "EUSERS",
2736 /* 88 */ "ENOTSOCK",
2737 /* 89 */ "EDESTADDRREQ",
2738 /* 90 */ "EMSGSIZE",
2739 /* 91 */ "EPROTOTYPE",
2740 /* 92 */ "ENOPROTOOPT",
2741 /* 93 */ "EPROTONOSUPPORT",
2742 /* 94 */ "ESOCKTNOSUPPORT",
2743 /* 95 */ "EOPNOTSUPP",
2744 /* 96 */ "EPFNOSUPPORT",
2745 /* 97 */ "EAFNOSUPPORT",
2746 /* 98 */ "EADDRINUSE",
2747 /* 99 */ "EADDRNOTAVAIL",
2748 /* 100 */ "ENETDOWN",
2749 /* 101 */ "ENETUNREACH",
2750 /* 102 */ "ENETRESET",
2751 /* 103 */ "ECONNABORTED",
2752 /* 104 */ "ECONNRESET",
2753 /* 105 */ "ENOBUFS",
2754 /* 106 */ "EISCONN",
2755 /* 107 */ "ENOTCONN",
2756 /* 108 */ "ESHUTDOWN",
2757 /* 109 */ "ETOOMANYREFS",
2758 /* 110 */ "ETIMEDOUT",
2759 /* 111 */ "ECONNREFUSED",
2760 /* 112 */ "EHOSTDOWN",
2761 /* 113 */ "EHOSTUNREACH",
2762 /* 114 */ "EALREADY",
2763 /* 115 */ "EINPROGRESS",
2764 /* 116 */ "ESTALE",
2765 /* 117 */ "EUCLEAN",
2766 /* 118 */ "ENOTNAM",
2767 /* 119 */ "ENAVAIL",
2768 /* 120 */ "EISNAM",
2769 /* 121 */ "EREMOTEIO",
2770 /* 122 */ "EDQUOT",
2773 static char *(linux_signal_names[]) = {
2774 /* 0 */ 0,
2775 /* 1 */ "SIGHUP",
2776 /* 2 */ "SIGINT",
2777 /* 3 */ "SIGQUIT",
2778 /* 4 */ "SIGILL",
2779 /* 5 */ "SIGTRAP",
2780 /* 6 */ "SIGABRT",
2781 /* 6 */ "SIGIOT",
2782 /* 7 */ "SIGBUS",
2783 /* 8 */ "SIGFPE",
2784 /* 9 */ "SIGKILL",
2785 /* 10 */ "SIGUSR1",
2786 /* 11 */ "SIGSEGV",
2787 /* 12 */ "SIGUSR2",
2788 /* 13 */ "SIGPIPE",
2789 /* 14 */ "SIGALRM",
2790 /* 15 */ "SIGTERM",
2791 /* 16 */ "SIGSTKFLT",
2792 /* 17 */ "SIGCHLD",
2793 /* 18 */ "SIGCONT",
2794 /* 19 */ "SIGSTOP",
2795 /* 20 */ "SIGTSTP",
2796 /* 21 */ "SIGTTIN",
2797 /* 22 */ "SIGTTOU",
2798 /* 23 */ "SIGURG",
2799 /* 24 */ "SIGXCPU",
2800 /* 25 */ "SIGXFSZ",
2801 /* 26 */ "SIGVTALRM",
2802 /* 27 */ "SIGPROF",
2803 /* 28 */ "SIGWINCH",
2804 /* 29 */ "SIGIO",
2805 /* 30 */ "SIGPWR",
2806 /* 31 */ "SIGUNUSED",
2809 static emul_syscall emul_linux_syscalls = {
2810 linux_descriptors,
2811 ARRAY_SIZE (linux_descriptors),
2812 linux_error_names,
2813 ARRAY_SIZE (linux_error_names),
2814 linux_signal_names,
2815 ARRAY_SIZE (linux_signal_names),
2819 /* Linux's os_emul interface, most are just passed on to the generic
2820 syscall stuff */
2822 static os_emul_data *
2823 emul_linux_create(device *root,
2824 bfd *image,
2825 const char *name)
2827 /* check that this emulation is really for us */
2828 if (name != NULL && strcmp(name, "linux") != 0)
2829 return NULL;
2831 if (image == NULL)
2832 return NULL;
2834 return emul_unix_create(root, image, "linux", &emul_linux_syscalls);
2837 static void
2838 emul_linux_init(os_emul_data *emul_data,
2839 int nr_cpus)
2841 fd_closed[0] = 0;
2842 fd_closed[1] = 0;
2843 fd_closed[2] = 0;
2846 static void
2847 emul_linux_system_call(cpu *processor,
2848 unsigned_word cia,
2849 os_emul_data *emul_data)
2851 emul_do_system_call(emul_data,
2852 emul_data->syscalls,
2853 cpu_registers(processor)->gpr[0],
2854 3, /*r3 contains arg0*/
2855 processor,
2856 cia);
2859 const os_emul emul_linux = {
2860 "linux",
2861 emul_linux_create,
2862 emul_linux_init,
2863 emul_linux_system_call,
2864 0, /*instruction_call*/
2865 0 /*data*/
2868 #endif /* _EMUL_UNIX_C_ */