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