From: Michael Meissner Date: Mon, 3 Jun 1996 19:10:25 +0000 (+0000) Subject: Add time, gettimeofday, and getrusage system call support X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=5b18a1a0bf971923756de403a0ea34a78a0e06ec;p=binutils-gdb.git Add time, gettimeofday, and getrusage system call support --- diff --git a/sim/ppc/ChangeLog b/sim/ppc/ChangeLog index 1786be3af7b..83caaf8faaa 100644 --- a/sim/ppc/ChangeLog +++ b/sim/ppc/ChangeLog @@ -1,3 +1,15 @@ +Mon Jun 3 15:02:04 1996 Michael Meissner + + * 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 * 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 fb662a0f322..05d9d7f3d34 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 6003204abfe..3a2c92d613e 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" },