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