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