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