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