aboutsummaryrefslogtreecommitdiff
path: root/sim/ppc/emul_unix.c
diff options
context:
space:
mode:
authorMichael Meissner <gnu@the-meissners.org>1996-06-03 19:10:25 +0000
committerMichael Meissner <gnu@the-meissners.org>1996-06-03 19:10:25 +0000
commit5b18a1a0bf971923756de403a0ea34a78a0e06ec (patch)
tree79ff2cdf448d62b6d7dddd8daf6c3d0a4cee75c9 /sim/ppc/emul_unix.c
parentf4c952e475230babf7c1640f1de122c6fbfc36bb (diff)
downloadfsf-binutils-gdb-5b18a1a0bf971923756de403a0ea34a78a0e06ec.zip
fsf-binutils-gdb-5b18a1a0bf971923756de403a0ea34a78a0e06ec.tar.gz
fsf-binutils-gdb-5b18a1a0bf971923756de403a0ea34a78a0e06ec.tar.bz2
Add time, gettimeofday, and getrusage system call support
Diffstat (limited to 'sim/ppc/emul_unix.c')
-rw-r--r--sim/ppc/emul_unix.c265
1 files changed, 223 insertions, 42 deletions
diff --git a/sim/ppc/emul_unix.c b/sim/ppc/emul_unix.c
index 6003204..3a2c92d 100644
--- a/sim/ppc/emul_unix.c
+++ b/sim/ppc/emul_unix.c
@@ -141,8 +141,44 @@ struct _os_emul_data {
emul_syscall *syscalls;
};
-
+
/* Emulation of simple UNIX system calls that are common on all systems. */
+
+/* Structures that are common agmonst the UNIX varients */
+struct unix_timeval {
+ signed32 tv_sec; /* seconds */
+ signed32 tv_usec; /* microseconds */
+};
+
+struct unix_timezone {
+ signed32 tz_minuteswest; /* minutes west of Greenwich */
+ signed32 tz_dsttime; /* type of dst correction */
+};
+
+#define UNIX_RUSAGE_SELF 0
+#define UNIX_RUSAGE_CHILDREN (-1)
+#define UNIX_RUSAGE_BOTH (-2) /* sys_wait4() uses this */
+
+struct unix_rusage {
+ struct unix_timeval ru_utime; /* user time used */
+ struct unix_timeval ru_stime; /* system time used */
+ signed32 ru_maxrss; /* maximum resident set size */
+ signed32 ru_ixrss; /* integral shared memory size */
+ signed32 ru_idrss; /* integral unshared data size */
+ signed32 ru_isrss; /* integral unshared stack size */
+ signed32 ru_minflt; /* any page faults not requiring I/O */
+ signed32 ru_majflt; /* any page faults requiring I/O */
+ signed32 ru_nswap; /* swaps */
+ signed32 ru_inblock; /* block input operations */
+ signed32 ru_oublock; /* block output operations */
+ signed32 ru_msgsnd; /* messages sent */
+ signed32 ru_msgrcv; /* messages received */
+ signed32 ru_nsignals; /* signals received */
+ signed32 ru_nvcsw; /* voluntary context switches */
+ signed32 ru_nivcsw; /* involuntary " */
+};
+
+
static void
do_unix_exit(os_emul_data *emul,
unsigned call,
@@ -305,8 +341,8 @@ do_unix_getpid(os_emul_data *emul,
cpu *processor,
unsigned_word cia)
{
- int status = (int)getpid();
- emul_write_status(processor, status, errno);
+ pid_t status = getpid();
+ emul_write_status(processor, (int)status, errno);
}
#endif
@@ -320,8 +356,8 @@ do_unix_getppid(os_emul_data *emul,
cpu *processor,
unsigned_word cia)
{
- int status = (int)getppid();
- emul_write_status(processor, status, errno);
+ pid_t status = getppid();
+ emul_write_status(processor, (int)status, errno);
}
#endif
@@ -351,9 +387,9 @@ do_unix_getuid2(os_emul_data *emul,
cpu *processor,
unsigned_word cia)
{
- int uid = (int)getuid();
- int euid = (int)geteuid();
- emul_write2_status(processor, uid, euid, errno);
+ uid_t uid = getuid();
+ uid_t euid = geteuid();
+ emul_write2_status(processor, (int)uid, (int)euid, errno);
}
#endif
@@ -367,8 +403,8 @@ do_unix_getuid(os_emul_data *emul,
cpu *processor,
unsigned_word cia)
{
- int status = (int)getuid();
- emul_write_status(processor, status, errno);
+ uid_t status = getuid();
+ emul_write_status(processor, (int)status, errno);
}
#endif
@@ -382,8 +418,8 @@ do_unix_geteuid(os_emul_data *emul,
cpu *processor,
unsigned_word cia)
{
- int status = (int)geteuid();
- emul_write_status(processor, status, errno);
+ uid_t status = geteuid();
+ emul_write_status(processor, (int)status, errno);
}
#endif
@@ -465,21 +501,16 @@ do_unix_lseek(os_emul_data *emul,
cpu *processor,
unsigned_word cia)
{
- int fildes = cpu_registers(processor)->gpr[arg0];
- off_t offset = emul_read_gpr64(processor, arg0+2);
- int whence = cpu_registers(processor)->gpr[arg0+4];
+ int fildes = (int)cpu_registers(processor)->gpr[arg0];
+ off_t offset = (off_t)cpu_registers(processor)->gpr[arg0+1];
+ int whence = (int)cpu_registers(processor)->gpr[arg0+2];
off_t status;
if (WITH_TRACE && ppc_trace[trace_os_emul])
printf_filtered ("%d %ld %d", fildes, (long)offset, whence);
status = lseek(fildes, offset, whence);
- if (status == -1)
- emul_write_status(processor, -1, errno);
- else {
- emul_write_status(processor, 0, 0); /* success */
- emul_write_gpr64(processor, 3, status);
- }
+ emul_write_status(processor, (int)status, errno);
}
#endif
@@ -494,9 +525,9 @@ do_unix_getgid2(os_emul_data *emul,
cpu *processor,
unsigned_word cia)
{
- int gid = (int)getgid();
- int egid = (int)getegid();
- emul_write2_status(processor, gid, egid, errno);
+ gid_t gid = getgid();
+ gid_t egid = getegid();
+ emul_write2_status(processor, (int)gid, (int)egid, errno);
}
#endif
@@ -510,8 +541,8 @@ do_unix_getgid(os_emul_data *emul,
cpu *processor,
unsigned_word cia)
{
- int status = (int)getgid();
- emul_write_status(processor, status, 0);
+ gid_t status = getgid();
+ emul_write_status(processor, (int)status, errno);
}
#endif
@@ -525,8 +556,8 @@ do_unix_getegid(os_emul_data *emul,
cpu *processor,
unsigned_word cia)
{
- int status = (int)getegid();
- emul_write_status(processor, status, errno);
+ gid_t status = getegid();
+ emul_write_status(processor, (int)status, errno);
}
#endif
@@ -540,7 +571,7 @@ do_unix_umask(os_emul_data *emul,
cpu *processor,
unsigned_word cia)
{
- int mask = cpu_registers(processor)->gpr[arg0];
+ mode_t mask = (mode_t)cpu_registers(processor)->gpr[arg0];
int status = umask(mask);
if (WITH_TRACE && ppc_trace[trace_os_emul])
@@ -695,6 +726,161 @@ do_unix_rmdir(os_emul_data *emul,
}
#endif
+#ifndef HAVE_TIME
+#define do_unix_time 0
+#else
+static void
+do_unix_time(os_emul_data *emul,
+ unsigned call,
+ const int arg0,
+ cpu *processor,
+ unsigned_word cia)
+{
+ unsigned_word tp = cpu_registers(processor)->gpr[arg0];
+ time_t now = time ((time_t *)0);
+ unsigned_word status = H2T_4(now);
+
+ if (WITH_TRACE && ppc_trace[trace_os_emul])
+ printf_filtered ("0x%lx", (long)tp);
+
+ emul_write_status(processor, (int)status, errno);
+
+ if (tp)
+ emul_write_buffer(&status, tp, sizeof(status), processor, cia);
+}
+#endif
+
+#if !defined(HAVE_GETTIMEOFDAY) || !defined(HAVE_SYS_TIME_H)
+#define do_unix_gettimeofday 0
+#else
+static void
+do_unix_gettimeofday(os_emul_data *emul,
+ unsigned call,
+ const int arg0,
+ cpu *processor,
+ unsigned_word cia)
+{
+ unsigned_word tv = cpu_registers(processor)->gpr[arg0];
+ unsigned_word tz = cpu_registers(processor)->gpr[arg0+1];
+ struct unix_timeval target_timeval;
+ struct timeval host_timeval;
+ struct unix_timezone target_timezone;
+ struct timezone host_timezone;
+ int status;
+
+ if (WITH_TRACE && ppc_trace[trace_os_emul])
+ printf_filtered ("0x%lx, 0x%lx", (long)tv, (long)tz);
+
+ /* Just in case the system doesn't set the timezone structure */
+ host_timezone.tz_minuteswest = 0;
+ host_timezone.tz_dsttime = 0;
+
+ status = gettimeofday(&host_timeval, &host_timezone);
+ if (status >= 0) {
+ if (tv) {
+ target_timeval.tv_sec = H2T_4(host_timeval.tv_sec);
+ target_timeval.tv_usec = H2T_4(host_timeval.tv_usec);
+ emul_write_buffer((void *) &target_timeval, tv, sizeof(target_timeval), processor, cia);
+ }
+
+ if (tz) {
+ target_timezone.tz_minuteswest = H2T_4(host_timezone.tz_minuteswest);
+ target_timezone.tz_dsttime = H2T_4(host_timezone.tz_dsttime);
+ emul_write_buffer((void *) &target_timezone, tv, sizeof(target_timezone), processor, cia);
+ }
+ }
+
+ emul_write_status(processor, (int)status, errno);
+}
+#endif
+
+
+#ifndef HAVE_GETRUSAGE
+#define do_unix_getrusage 0
+#else
+static void
+do_unix_getrusage(os_emul_data *emul,
+ unsigned call,
+ const int arg0,
+ cpu *processor,
+ unsigned_word cia)
+{
+ signed_word who = (signed_word)cpu_registers(processor)->gpr[arg0];
+ unsigned_word usage = cpu_registers(processor)->gpr[arg0+1];
+ struct rusage host_rusage, host_rusage2;
+ struct unix_rusage target_rusage;
+ int status;
+
+ if (WITH_TRACE && ppc_trace[trace_os_emul])
+ printf_filtered ("%ld, 0x%lx", (long)who, (long)usage);
+
+ switch (who) {
+ default:
+ status = -1;
+ errno = EINVAL;
+ break;
+
+ case UNIX_RUSAGE_SELF:
+ status = getrusage(RUSAGE_SELF, &host_rusage);
+ break;
+
+ case UNIX_RUSAGE_CHILDREN:
+ status = getrusage(RUSAGE_CHILDREN, &host_rusage);
+ break;
+
+ case UNIX_RUSAGE_BOTH:
+ status = getrusage(RUSAGE_SELF, &host_rusage);
+ if (status >= 0) {
+ status = getrusage(RUSAGE_CHILDREN, &host_rusage2);
+ if (status >= 0) {
+ host_rusage.ru_utime.tv_sec += host_rusage2.ru_utime.tv_sec;
+ host_rusage.ru_utime.tv_usec += host_rusage2.ru_utime.tv_usec;
+ host_rusage.ru_stime.tv_sec += host_rusage2.ru_stime.tv_sec;
+ host_rusage.ru_stime.tv_usec += host_rusage2.ru_stime.tv_usec;
+ host_rusage.ru_maxrss += host_rusage2.ru_maxrss;
+ host_rusage.ru_ixrss += host_rusage2.ru_ixrss;
+ host_rusage.ru_idrss += host_rusage2.ru_idrss;
+ host_rusage.ru_isrss += host_rusage2.ru_isrss;
+ host_rusage.ru_minflt += host_rusage2.ru_minflt;
+ host_rusage.ru_majflt += host_rusage2.ru_majflt;
+ host_rusage.ru_nswap += host_rusage2.ru_nswap;
+ host_rusage.ru_inblock += host_rusage2.ru_inblock;
+ host_rusage.ru_oublock += host_rusage2.ru_oublock;
+ host_rusage.ru_msgsnd += host_rusage2.ru_msgsnd;
+ host_rusage.ru_msgrcv += host_rusage2.ru_msgrcv;
+ host_rusage.ru_nsignals += host_rusage2.ru_nsignals;
+ host_rusage.ru_nvcsw += host_rusage2.ru_nvcsw;
+ host_rusage.ru_nivcsw += host_rusage2.ru_nivcsw;
+ }
+ }
+ }
+
+ if (status >= 0) {
+ target_rusage.ru_utime.tv_sec = H2T_4(host_rusage2.ru_utime.tv_sec);
+ target_rusage.ru_utime.tv_usec = H2T_4(host_rusage2.ru_utime.tv_usec);
+ target_rusage.ru_stime.tv_sec = H2T_4(host_rusage2.ru_stime.tv_sec);
+ target_rusage.ru_stime.tv_usec = H2T_4(host_rusage2.ru_stime.tv_usec);
+ target_rusage.ru_maxrss = H2T_4(host_rusage2.ru_maxrss);
+ target_rusage.ru_ixrss = H2T_4(host_rusage2.ru_ixrss);
+ target_rusage.ru_idrss = H2T_4(host_rusage2.ru_idrss);
+ target_rusage.ru_isrss = H2T_4(host_rusage2.ru_isrss);
+ target_rusage.ru_minflt = H2T_4(host_rusage2.ru_minflt);
+ target_rusage.ru_majflt = H2T_4(host_rusage2.ru_majflt);
+ target_rusage.ru_nswap = H2T_4(host_rusage2.ru_nswap);
+ target_rusage.ru_inblock = H2T_4(host_rusage2.ru_inblock);
+ target_rusage.ru_oublock = H2T_4(host_rusage2.ru_oublock);
+ target_rusage.ru_msgsnd = H2T_4(host_rusage2.ru_msgsnd);
+ target_rusage.ru_msgrcv = H2T_4(host_rusage2.ru_msgrcv);
+ target_rusage.ru_nsignals = H2T_4(host_rusage2.ru_nsignals);
+ target_rusage.ru_nvcsw = H2T_4(host_rusage2.ru_nvcsw);
+ target_rusage.ru_nivcsw = H2T_4(host_rusage2.ru_nivcsw);
+ emul_write_buffer((void *) &target_rusage, usage, sizeof(target_rusage), processor, cia);
+ }
+
+ emul_write_status(processor, status, errno);
+}
+#endif
+
/* Common code for initializing the system call stuff */
@@ -772,11 +958,6 @@ typedef unsigned32 solaris_nlink_t;
#ifdef HAVE_SYS_STAT_H
#define SOLARIS_ST_FSTYPSZ 16 /* array size for file system type name */
-typedef struct {
- solaris_time_t tv_sec;
- signed32 tv_usec;
-} solaris_timestruc_t;
-
struct solaris_stat {
solaris_dev_t st_dev;
signed32 st_pad1[3]; /* reserved for network id */
@@ -789,9 +970,9 @@ struct solaris_stat {
signed32 st_pad2[2];
solaris_off_t st_size;
signed32 st_pad3; /* future off_t expansion */
- solaris_timestruc_t st_atim;
- solaris_timestruc_t st_mtim;
- solaris_timestruc_t st_ctim;
+ struct unix_timeval st_atim;
+ struct unix_timeval st_mtim;
+ struct unix_timeval st_ctim;
signed32 st_blksize;
signed32 st_blocks;
char st_fstype[SOLARIS_ST_FSTYPSZ];
@@ -1222,7 +1403,7 @@ static emul_syscall_descriptor solaris_descriptors[] = {
/* 10 */ { do_unix_unlink, "unlink" },
/* 11 */ { 0, "exec" },
/* 12 */ { do_unix_chdir, "chdir" },
- /* 13 */ { 0, "time" },
+ /* 13 */ { do_unix_time, "time" },
/* 14 */ { 0, "mknod" },
/* 15 */ { 0, "chmod" },
/* 16 */ { 0, "chown" },
@@ -1366,7 +1547,7 @@ static emul_syscall_descriptor solaris_descriptors[] = {
/* 153 */ { 0, "fchroot" },
/* 154 */ { 0, "utimes" },
/* 155 */ { 0, "vhangup" },
- /* 156 */ { 0, "gettimeofday" },
+ /* 156 */ { do_unix_gettimeofday, "gettimeofday" },
/* 157 */ { 0, "getitimer" },
/* 158 */ { 0, "setitimer" },
/* 159 */ { 0, "lwp_create" },
@@ -2152,7 +2333,7 @@ static emul_syscall_descriptor linux_descriptors[] = {
/* 10 */ { do_unix_unlink, "unlink" },
/* 11 */ { 0, "execve" },
/* 12 */ { do_unix_chdir, "chdir" },
- /* 13 */ { 0, "time" },
+ /* 13 */ { do_unix_time, "time" },
/* 14 */ { 0, "mknod" },
/* 15 */ { 0, "chmod" },
/* 16 */ { 0, "chown" },
@@ -2216,8 +2397,8 @@ static emul_syscall_descriptor linux_descriptors[] = {
/* 74 */ { 0, "sethostname" },
/* 75 */ { 0, "setrlimit" },
/* 76 */ { 0, "getrlimit" },
- /* 77 */ { 0, "getrusage" },
- /* 78 */ { 0, "gettimeofday" },
+ /* 77 */ { do_unix_getrusage, "getrusage" },
+ /* 78 */ { do_unix_gettimeofday, "gettimeofday" },
/* 79 */ { 0, "settimeofday" },
/* 80 */ { 0, "getgroups" },
/* 81 */ { 0, "setgroups" },