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