aboutsummaryrefslogtreecommitdiff
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
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
-rw-r--r--sim/ppc/ChangeLog12
-rw-r--r--sim/ppc/configure.in8
-rw-r--r--sim/ppc/emul_unix.c265
3 files changed, 243 insertions, 42 deletions
diff --git a/sim/ppc/ChangeLog b/sim/ppc/ChangeLog
index 1786be3..83caaf8 100644
--- a/sim/ppc/ChangeLog
+++ b/sim/ppc/ChangeLog
@@ -1,3 +1,15 @@
+Mon Jun 3 15:02:04 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * emul_unix.c (do_unix_{time,gettimeofday,getrusage}): Add support
+ for time, gettimeofday, and getrusage system calls.
+ ({solaris,linux}_descriptors): Add new system calls.
+ (do_get{,e}{uid,gid}): Use gid_t/uid_t types.
+ (do_get{,p}pid): Use pic_t types.
+
+ * configure.in (AC_TYPE_{GETGROUPS,SIGNAL}): Define.
+ (AC_TYPE_{MODE,OFF,PID,SIZE,UID}_T): Define.
+ * config{.in,ure}: Regenerate.
+
Sun Jun 2 11:21:17 1996 Michael Meissner <meissner@tiktok.cygnus.com>
* emul_unix.{h,c}: New files to provide Solaris and Linux system
diff --git a/sim/ppc/configure.in b/sim/ppc/configure.in
index fb662a0..05d9d7f 100644
--- a/sim/ppc/configure.in
+++ b/sim/ppc/configure.in
@@ -444,6 +444,14 @@ AC_STRUCT_ST_BLOCKS
AC_STRUCT_ST_RDEV
AC_STRUCT_TIMEZONE
+AC_TYPE_GETGROUPS
+AC_TYPE_MODE_T
+AC_TYPE_OFF_T
+AC_TYPE_PID_T
+AC_TYPE_SIGNAL
+AC_TYPE_SIZE_T
+AC_TYPE_UID_T
+
AC_CHECK_FUNCS(cfgetispeed cfgetospeed cfsetispeed cfsetospeed chdir chmod chown dup dup2 fchmod fchown fcntl fstat fstatfs getdirentries getegid geteuid getgid getpid getppid getrusage gettimeofday getuid ioctl kill link lseek lstat mkdir pipe readlink rmdir setreuid setregid stat sigprocmask stat symlink tcgetattr tcsetattr tcsendbreak tcdrain tcflush tcflow tcgetpgrp tcsetpgrp time umask unlink)
AC_CHECK_HEADERS(fcntl.h stdlib.h string.h strings.h sys/ioctl.h sys/mount.h sys/param.h sys/resource.h sys/stat.h sys/termio.h sys/termios.h sys/time.h sys/times.h sys/types.h time.h unistd.h)
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" },