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