diff options
author | Michael Meissner <gnu@the-meissners.org> | 1996-06-03 19:10:25 +0000 |
---|---|---|
committer | Michael Meissner <gnu@the-meissners.org> | 1996-06-03 19:10:25 +0000 |
commit | 5b18a1a0bf971923756de403a0ea34a78a0e06ec (patch) | |
tree | 79ff2cdf448d62b6d7dddd8daf6c3d0a4cee75c9 /sim/ppc/emul_unix.c | |
parent | f4c952e475230babf7c1640f1de122c6fbfc36bb (diff) | |
download | fsf-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.c | 265 |
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" }, |