/* This file is part of the program psim.
- Copyright (C) 1996, Andrew Cagney <cagney@highland.com.au>
+ Copyright (C) 1996-1998, Andrew Cagney <cagney@highland.com.au>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
#include <sys/time.h>
#endif
-#ifdef HAVE_SYS_TERMIOS_H
+#ifndef HAVE_TERMIOS_STRUCTURE
+#undef HAVE_SYS_TERMIOS_H
+#undef HAVE_TCGETATTR
+#else
+#ifndef HAVE_SYS_TERMIOS_H
+#undef HAVE_TERMIOS_STRUCTURE
+#endif
+#endif
+
+#ifdef HAVE_TERMIOS_STRUCTURE
#include <sys/termios.h>
+
+/* If we have TERMIOS, use that for the termio structure, since some systems
+ don't like including both sys/termios.h and sys/termio.h at the same
+ time. */
+#undef HAVE_TERMIO_STRUCTURE
+#undef TCGETA
+#undef termio
+#define termio termios
+#endif
+
+#ifndef HAVE_TERMIO_STRUCTURE
+#undef HAVE_SYS_TERMIO_H
+#else
+#ifndef HAVE_SYS_TERMIO_H
+#undef HAVE_TERMIO_STRUCTURE
+#endif
#endif
-#ifdef HAVE_SYS_TERMIO_H
+#ifdef HAVE_TERMIO_STRUCTURE
#include <sys/termio.h>
#endif
int getrusage();
#endif
-#if HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-
-#if HAVE_SYS_MOUNT_H
-#include <sys/mount.h>
-#endif
-
#if HAVE_DIRENT_H
# include <dirent.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
if (status > 0)
emul_write_buffer(scratch_buffer, buf, status, processor, cia);
- zfree(scratch_buffer);
+ free(scratch_buffer);
}
unsigned_word cia)
{
void *scratch_buffer = NULL;
- int nr_moved;
int d = (int)cpu_registers(processor)->gpr[arg0];
unsigned_word buf = cpu_registers(processor)->gpr[arg0+1];
int nbytes = cpu_registers(processor)->gpr[arg0+2];
scratch_buffer = zalloc(nbytes); /* FIXME - nbytes == 0 */
/* copy in */
- nr_moved = vm_data_map_read_buffer(cpu_data_map(processor),
- scratch_buffer,
- buf,
- nbytes);
- if (nr_moved != nbytes) {
- /* FIXME - should handle better */
- error("system_call()write copy failed (nr_moved=%d != nbytes=%d)\n",
- nr_moved, nbytes);
- }
+ emul_read_buffer(scratch_buffer, buf, nbytes,
+ processor, cia);
/* write */
status = write(d, scratch_buffer, nbytes);
emul_write_status(processor, status, errno);
- zfree(scratch_buffer);
+ free(scratch_buffer);
flush_stdoutput();
}
unsigned_word cia)
{
/* just pass this onto the `vm' device */
- psim *system = cpu_system(processor);
unsigned_word new_break = cpu_registers(processor)->gpr[arg0];
int status;
printf_filtered ("0x%lx", (long)cpu_registers(processor)->gpr[arg0]);
status = device_ioctl(emul->vm,
- system,
processor,
cia,
+ device_ioctl_break,
new_break); /*ioctl-data*/
emul_write_status(processor, 0, status);
}
+#ifndef HAVE_ACCESS
+#define do_unix_access 0
+#else
+static void
+do_unix_access(os_emul_data *emul,
+ unsigned call,
+ const int arg0,
+ cpu *processor,
+ unsigned_word cia)
+{
+ unsigned_word path_addr = cpu_registers(processor)->gpr[arg0];
+ char path_buf[PATH_MAX];
+ char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia);
+ int mode = (int)cpu_registers(processor)->gpr[arg0+1];
+ int status;
+
+ if (WITH_TRACE && ppc_trace[trace_os_emul])
+ printf_filtered ("0x%lx [%s], 0x%x [0%o]", (long)path_addr, path, mode, mode);
+
+ status = access(path, mode);
+ emul_write_status(processor, status, errno);
+}
+#endif
+
#ifndef HAVE_GETPID
#define do_unix_getpid 0
#else
int status = umask(mask);
if (WITH_TRACE && ppc_trace[trace_os_emul])
- printf_filtered ("0%o", mask);
+ printf_filtered ("0%o", (unsigned int)mask);
emul_write_status(processor, status, errno);
}
if (WITH_TRACE && ppc_trace[trace_os_emul])
printf_filtered ("0x%lx [%s], 0%3o", (long)path_addr, path, mode);
+#ifdef USE_WIN32API
+ status = mkdir(path);
+#else
status = mkdir(path, mode);
+#endif
emul_write_status(processor, status, errno);
}
#endif
}
#endif
+
+static void
+do_unix_nop(os_emul_data *emul,
+ unsigned call,
+ const int arg0,
+ cpu *processor,
+ unsigned_word cia)
+{
+ if (WITH_TRACE && ppc_trace[trace_os_emul])
+ printf_filtered ("0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx",
+ (long)cpu_registers(processor)->gpr[arg0],
+ (long)cpu_registers(processor)->gpr[arg0+1],
+ (long)cpu_registers(processor)->gpr[arg0+2],
+ (long)cpu_registers(processor)->gpr[arg0+3],
+ (long)cpu_registers(processor)->gpr[arg0+4],
+ (long)cpu_registers(processor)->gpr[arg0+5]);
+
+ emul_write_status(processor, 0, errno);
+}
+
\f
/* Common code for initializing the system call stuff */
int elf_binary;
os_emul_data *data;
device *vm;
+ char *filename;
/* merge any emulation specific entries into the device tree */
0 /*oea-interrupt-prefix*/);
/* virtual memory - handles growth of stack/heap */
- vm = device_tree_add_parsed(root, "/openprom/vm@0x%lx",
- (unsigned long)(top_of_stack - stack_size));
- device_tree_add_parsed(vm, "./stack-base 0x%lx",
- (unsigned long)(top_of_stack - stack_size));
- device_tree_add_parsed(vm, "./nr-bytes 0x%x", stack_size);
+ vm = tree_parse(root, "/openprom/vm@0x%lx",
+ (unsigned long)(top_of_stack - stack_size));
+ tree_parse(vm, "./stack-base 0x%lx",
+ (unsigned long)(top_of_stack - stack_size));
+ tree_parse(vm, "./nr-bytes 0x%x", stack_size);
- device_tree_add_parsed(root, "/openprom/vm/map-binary/file-name %s",
- bfd_get_filename(image));
+ filename = tree_quote_property (bfd_get_filename(image));
+ tree_parse(root, "/openprom/vm/map-binary/file-name %s",
+ filename);
+ free (filename);
/* finish the init */
- device_tree_add_parsed(root, "/openprom/init/register/pc 0x%lx",
- (unsigned long)bfd_get_start_address(image));
- device_tree_add_parsed(root, "/openprom/init/register/sp 0x%lx",
- (unsigned long)top_of_stack);
- device_tree_add_parsed(root, "/openprom/init/register/msr 0x%x", msr_little_endian_mode);
- device_tree_add_parsed(root, "/openprom/init/stack/stack-type %s",
- (elf_binary ? "elf" : "xcoff"));
+ tree_parse(root, "/openprom/init/register/pc 0x%lx",
+ (unsigned long)bfd_get_start_address(image));
+ tree_parse(root, "/openprom/init/register/sp 0x%lx",
+ (unsigned long)top_of_stack);
+ tree_parse(root, "/openprom/init/register/msr 0x%x",
+ ((tree_find_boolean_property(root, "/options/little-endian?")
+ ? msr_little_endian_mode
+ : 0)
+ | (tree_find_boolean_property(root, "/openprom/options/floating-point?")
+ ? (msr_floating_point_available
+ | msr_floating_point_exception_mode_0
+ | msr_floating_point_exception_mode_1)
+ : 0)));
+ tree_parse(root, "/openprom/init/stack/stack-type %s",
+ (elf_binary ? "ppc-elf" : "ppc-xcoff"));
/* finally our emulation data */
data = ZALLOC(os_emul_data);
}
\f
+/* EMULATION
+
+ Solaris - Emulation of user programs for Solaris/PPC
+
+ DESCRIPTION
+
+ */
+
+
/* Solaris specific implementation */
typedef signed32 solaris_uid_t;
#ifdef HAVE_SYS_STAT_H
#define SOLARIS_ST_FSTYPSZ 16 /* array size for file system type name */
+/* AIX 7.1 defines st_pad[123] to st_[amc]tim.tv_pad, respectively */
+#undef st_pad1
+#undef st_pad2
+#undef st_pad3
+
struct solaris_stat {
solaris_dev_t st_dev;
signed32 st_pad1[3]; /* reserved for network id */
}
#endif
-#if defined(HAVE_SYS_TERMIO_H) || defined(HAVE_SYS_TERMIOS_H)
+#if defined(HAVE_TERMIO_STRUCTURE) || defined(HAVE_TERMIOS_STRUCTURE)
#define SOLARIS_TIOC ('T'<<8)
#define SOLARIS_NCC 8
#define SOLARIS_NCCS 19
#define SOLARIS_VLNEXT 15
#endif
-#ifdef HAVE_SYS_TERMIO_H
+#if defined(HAVE_TERMIO_STRUCTURE) || defined(HAVE_TERMIOS_STRUCTURE)
/* Convert to/from host termio structure */
struct solaris_termio {
target.c_oflag = H2T_2 (host->c_oflag);
target.c_cflag = H2T_2 (host->c_cflag);
target.c_lflag = H2T_2 (host->c_lflag);
+
+#if defined(HAVE_TERMIO_CLINE) || defined(HAVE_TERMIOS_CLINE)
target.c_line = host->c_line;
+#else
+ target.c_line = 0;
+#endif
for (i = 0; i < SOLARIS_NCC; i++)
target.c_cc[i] = 0;
emul_write_buffer(&target, addr, sizeof(target), processor, cia);
}
-#endif /* HAVE_SYS_TERMIO_H */
+#endif /* HAVE_TERMIO_STRUCTURE || HAVE_TERMIOS_STRUCTURE */
-#ifdef HAVE_SYS_TERMIOS_H
+#ifdef HAVE_TERMIOS_STRUCTURE
/* Convert to/from host termios structure */
typedef unsigned32 solaris_tcflag_t;
emul_write_buffer(&target, addr, sizeof(target), processor, cia);
}
-#endif /* HAVE_SYS_TERMIOS_H */
+#endif /* HAVE_TERMIOS_STRUCTURE */
#ifndef HAVE_IOCTL
#define do_solaris_ioctl 0
int status = 0;
const char *name = "<unknown>";
-#ifdef HAVE_SYS_TERMIO_H
+#ifdef HAVE_TERMIOS_STRUCTURE
+ struct termios host_termio;
+
+#else
+#ifdef HAVE_TERMIO_STRUCTURE
struct termio host_termio;
#endif
-
-#ifdef HAVE_SYS_TERMIOS_H
- struct termios host_termios;
#endif
switch (request)
errno = EINVAL;
break;
-#ifdef HAVE_SYS_TERMIO_H
-#ifdef TCGETA
+#if defined(HAVE_TERMIO_STRUCTURE) || defined(HAVE_TERMIOS_STRUCTURE)
+#if defined(TCGETA) || defined(TCGETS) || defined(HAVE_TCGETATTR)
case SOLARIS_TIOC | 1: /* TCGETA */
name = "TCGETA";
+#ifdef HAVE_TCGETATTR
+ status = tcgetattr(fildes, &host_termio);
+#elif defined(TCGETS)
+ status = ioctl (fildes, TCGETS, &host_termio);
+#else
status = ioctl (fildes, TCGETA, &host_termio);
+#endif
if (status == 0)
convert_to_solaris_termio (argp_addr, &host_termio, processor, cia);
break;
#endif /* TCGETA */
-#endif /* HAVE_SYS_TERMIO_H */
+#endif /* HAVE_TERMIO_STRUCTURE */
-#ifdef HAVE_SYS_TERMIOS_H
+#ifdef HAVE_TERMIOS_STRUCTURE
#if defined(TCGETS) || defined(HAVE_TCGETATTR)
case SOLARIS_TIOC | 13: /* TCGETS */
name = "TCGETS";
#ifdef HAVE_TCGETATTR
- status = tcgetattr(fildes, &host_termios);
+ status = tcgetattr(fildes, &host_termio);
#else
- status = ioctl (fildes, TCGETS, &host_termios);
+ status = ioctl (fildes, TCGETS, &host_termio);
#endif
if (status == 0)
- convert_to_solaris_termios (argp_addr, &host_termios, processor, cia);
+ convert_to_solaris_termios (argp_addr, &host_termio, processor, cia);
break;
#endif /* TCGETS */
-#endif /* HAVE_SYS_TERMIOS_H */
+#endif /* HAVE_TERMIOS_STRUCTURE */
}
emul_write_status(processor, status, errno);
/* 30 */ { 0, "utime" },
/* 31 */ { 0, "stty" },
/* 32 */ { 0, "gtty" },
- /* 33 */ { 0, "access" },
+ /* 33 */ { do_unix_access, "access" },
/* 34 */ { 0, "nice" },
/* 35 */ { 0, "statfs" },
/* 36 */ { 0, "sync" },
/* 94 */ { 0, "fchown" },
/* 95 */ { 0, "sigprocmask" },
/* 96 */ { 0, "sigsuspend" },
- /* 97 */ { 0, "sigaltstack" },
- /* 98 */ { 0, "sigaction" },
+ /* 97 */ { do_unix_nop, "sigaltstack" },
+ /* 98 */ { do_unix_nop, "sigaction" },
/* 99 */ { 0, "sigpending" },
/* 100 */ { 0, "context" },
/* 101 */ { 0, "evsys" },
return emul_unix_create(root, image, "solaris", &emul_solaris_syscalls);
}
-
+
static void
emul_solaris_init(os_emul_data *emul_data,
int nr_cpus)
};
\f
+/* EMULATION
+
+ Linux - Emulation of user programs for Linux/PPC
+
+ DESCRIPTION
+
+ */
+
+
/* Linux specific implementation */
typedef unsigned32 linux_dev_t;
}
#endif
-#if defined(HAVE_SYS_TERMIO_H) || defined(HAVE_SYS_TERMIOS_H)
+#if defined(HAVE_TERMIO_STRUCTURE) || defined(HAVE_TERMIOS_STRUCTURE)
#define LINUX_NCC 10
#define LINUX_NCCS 19
#define LINUX_IOWR(type,nr,size) LINUX_IOC(LINUX_IOC_READ|LINUX_IOC_WRITE,(type),(nr),sizeof(size))
#endif
-#ifdef HAVE_SYS_TERMIO_H
+#if defined(HAVE_TERMIO_STRUCTURE) || defined(HAVE_TERMIOS_STRUCTURE)
/* Convert to/from host termio structure */
struct linux_termio {
target.c_oflag = H2T_2 (host->c_oflag);
target.c_cflag = H2T_2 (host->c_cflag);
target.c_lflag = H2T_2 (host->c_lflag);
+
+#if defined(HAVE_TERMIO_CLINE) || defined(HAVE_TERMIOS_CLINE)
target.c_line = host->c_line;
+#else
+ target.c_line = 0;
+#endif
for (i = 0; i < LINUX_NCC; i++)
target.c_cc[i] = 0;
emul_write_buffer(&target, addr, sizeof(target), processor, cia);
}
-#endif /* HAVE_SYS_TERMIO_H */
+#endif /* HAVE_TERMIO_STRUCTURE */
-#ifdef HAVE_SYS_TERMIOS_H
+#ifdef HAVE_TERMIOS_STRUCTURE
/* Convert to/from host termios structure */
typedef unsigned32 linux_tcflag_t;
#endif
#ifdef VSWTCH
- target.c_cc[LINUX_VSWTCH] = host->c_cc[VSWTCH];
+ target.c_cc[LINUX_VSWTC] = host->c_cc[VSWTCH];
#endif
+#ifdef HAVE_TERMIOS_CLINE
+ target.c_line = host->c_line;
+#else
target.c_line = 0;
+#endif
#ifdef HAVE_CFGETISPEED
target.c_ispeed = cfgetispeed (host);
emul_write_buffer(&target, addr, sizeof(target), processor, cia);
}
-#endif /* HAVE_SYS_TERMIOS_H */
+#endif /* HAVE_TERMIOS_STRUCTURE */
#ifndef HAVE_IOCTL
#define do_linux_ioctl 0
#else
static void
do_linux_ioctl(os_emul_data *emul,
- unsigned call,
- const int arg0,
- cpu *processor,
- unsigned_word cia)
+ unsigned call,
+ const int arg0,
+ cpu *processor,
+ unsigned_word cia)
{
int fildes = cpu_registers(processor)->gpr[arg0];
unsigned request = cpu_registers(processor)->gpr[arg0+1];
int status = 0;
const char *name = "<unknown>";
-#ifdef HAVE_SYS_TERMIO_H
+#ifdef HAVE_TERMIOS_STRUCTURE
+ struct termios host_termio;
+
+#else
+#ifdef HAVE_TERMIO_STRUCTURE
struct termio host_termio;
#endif
-
-#ifdef HAVE_SYS_TERMIOS_H
- struct termios host_termios;
#endif
switch (request)
errno = EINVAL;
break;
-#ifdef HAVE_SYS_TERMIO_H
-#ifdef TCGETA
+#if defined(HAVE_TERMIO_STRUCTURE) || defined(HAVE_TERMIOS_STRUCTURE)
+#if defined(TCGETA) || defined(TCGETS) || defined(HAVE_TCGETATTR)
case LINUX_IOR('t', 23, struct linux_termio): /* TCGETA */
name = "TCGETA";
+#ifdef HAVE_TCGETATTR
+ status = tcgetattr(fildes, &host_termio);
+#elif defined(TCGETS)
+ status = ioctl (fildes, TCGETS, &host_termio);
+#else
status = ioctl (fildes, TCGETA, &host_termio);
+#endif
if (status == 0)
convert_to_linux_termio (argp_addr, &host_termio, processor, cia);
break;
#endif /* TCGETA */
-#endif /* HAVE_SYS_TERMIO_H */
+#endif /* HAVE_TERMIO_STRUCTURE */
-#ifdef HAVE_SYS_TERMIOS_H
+#ifdef HAVE_TERMIOS_STRUCTURE
#if defined(TCGETS) || defined(HAVE_TCGETATTR)
case LINUX_IOR('t', 19, struct linux_termios): /* TCGETS */
name = "TCGETS";
#ifdef HAVE_TCGETATTR
- status = tcgetattr(fildes, &host_termios);
+ status = tcgetattr(fildes, &host_termio);
#else
- status = ioctl (fildes, TCGETS, &host_termios);
+ status = ioctl (fildes, TCGETS, &host_termio);
#endif
if (status == 0)
- convert_to_linux_termios (argp_addr, &host_termios, processor, cia);
+ convert_to_linux_termios (argp_addr, &host_termio, processor, cia);
break;
#endif /* TCGETS */
-#endif /* HAVE_SYS_TERMIOS_H */
+#endif /* HAVE_TERMIOS_STRUCTURE */
}
emul_write_status(processor, status, errno);
/* 30 */ { 0, "utime" },
/* 31 */ { 0, "stty" },
/* 32 */ { 0, "gtty" },
- /* 33 */ { 0, "access" },
+ /* 33 */ { do_unix_access, "access" },
/* 34 */ { 0, "nice" },
/* 35 */ { 0, "ftime" },
/* 36 */ { 0, "sync" },
static os_emul_data *
emul_linux_create(device *root,
- bfd *image,
- const char *name)
+ bfd *image,
+ const char *name)
{
/* check that this emulation is really for us */
if (name != NULL && strcmp(name, "linux") != 0)
static void
emul_linux_init(os_emul_data *emul_data,
- int nr_cpus)
+ int nr_cpus)
{
/* nothing yet */
}
static void
emul_linux_system_call(cpu *processor,
- unsigned_word cia,
- os_emul_data *emul_data)
+ unsigned_word cia,
+ os_emul_data *emul_data)
{
emul_do_system_call(emul_data,
emul_data->syscalls,