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