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