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