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