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