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