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