|
From: <sv...@va...> - 2006-10-17 02:16:53
|
Author: sewardj
Date: 2006-10-17 03:16:44 +0100 (Tue, 17 Oct 2006)
New Revision: 6295
Log:
Merge from branches/AIX5:
- AIX5 support
- get rid of VG_(nanosleep)
- track SysRes changes
Modified:
trunk/coregrind/m_libcproc.c
trunk/coregrind/pub_core_libcproc.h
Modified: trunk/coregrind/m_libcproc.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/m_libcproc.c 2006-10-17 02:15:17 UTC (rev 6294)
+++ trunk/coregrind/m_libcproc.c 2006-10-17 02:16:44 UTC (rev 6295)
@@ -30,14 +30,15 @@
=20
#include "pub_core_basics.h"
#include "pub_core_vki.h"
+#include "pub_core_vkiscnums.h"
#include "pub_core_libcbase.h"
#include "pub_core_libcassert.h"
#include "pub_core_libcprint.h"
#include "pub_core_libcproc.h"
+#include "pub_core_libcsignal.h"
#include "pub_core_mallocfree.h"
#include "pub_core_syscall.h"
#include "pub_core_clientstate.h"
-#include "pub_core_vkiscnums.h"
=20
/* ---------------------------------------------------------------------
Command line and environment stuff
@@ -222,8 +223,20 @@
=20
Int VG_(waitpid)(Int pid, Int *status, Int options)
{
+# if defined(VGO_linux)
SysRes res =3D VG_(do_syscall4)(__NR_wait4, pid, (UWord)status, optio=
ns, 0);
- return res.isError ? -1 : res.val;
+ return res.isError ? -1 : res.res;
+# elif defined(VGO_aix5)
+ /* magic number 4 obtained by truss-ing a C program doing
+ 'waitpid'. Note status and pid args opposite way round from
+ POSIX. */
+ SysRes res =3D VG_(do_syscall5)(__NR_AIX5_kwaitpid,=20
+ (UWord)status, pid, 4 | options,0,0);
+ if (0) VG_(printf)("waitpid: got 0x%x 0x%x\n", res.res, res.err);
+ return res.isError ? -1 : res.res;
+# else
+# error Unknown OS
+# endif
}
=20
/* clone the environment */
@@ -263,7 +276,7 @@
res =3D VG_(do_syscall0)(__NR_fork);
if (res.isError)
return -1;
- pid =3D res.val;
+ pid =3D res.res;
if (pid =3D=3D 0) {
/* child */
static Char** envp =3D NULL;
@@ -287,7 +300,32 @@
VG_(exit)(1);
} else {
/* parent */
- Int zzz =3D VG_(waitpid)(pid, NULL, 0);
+ Int ir, zzz;
+ /* We have to set SIGCHLD to its default behaviour in order that
+ VG_(waitpid) works (at least on AIX). According to the Linux
+ man page for waitpid:
+
+ POSIX.1-2001 specifies that if the disposition of SIGCHLD is
+ set to SIG_IGN or the SA_NOCLDWAIT flag is set for SIGCHLD
+ (see sigaction(2)), then children that terminate do not
+ become zombies and a call to wait() or waitpid() will block
+ until all children have terminated, and then fail with errno
+ set to ECHILD. (The original POSIX standard left the
+ behaviour of setting SIGCHLD to SIG_IGN unspecified.)
+ */
+ struct vki_sigaction sa, saved_sa;
+ VG_(memset)( &sa, 0, sizeof(struct vki_sigaction) );
+ VG_(sigemptyset)(&sa.sa_mask);
+ sa.ksa_handler =3D VKI_SIG_DFL;
+ sa.sa_flags =3D 0;
+ ir =3D VG_(sigaction)(VKI_SIGCHLD, &sa, &saved_sa);
+ vg_assert(ir =3D=3D 0);
+
+ zzz =3D VG_(waitpid)(pid, NULL, 0);
+
+ ir =3D VG_(sigaction)(VKI_SIGCHLD, &saved_sa, NULL);
+ vg_assert(ir =3D=3D 0);
+
return zzz =3D=3D -1 ? -1 : 0;
}
}
@@ -304,9 +342,9 @@
# ifdef __NR_ugetrlimit
res =3D VG_(do_syscall2)(__NR_ugetrlimit, resource, (UWord)rlim);
# endif
- if (res.isError && res.val =3D=3D VKI_ENOSYS)
+ if (res.isError && res.err =3D=3D VKI_ENOSYS)
res =3D VG_(do_syscall2)(__NR_getrlimit, resource, (UWord)rlim);
- return res.isError ? -1 : res.val;
+ return res.isError ? -1 : res.res;
}
=20
=20
@@ -316,7 +354,7 @@
SysRes res;
/* res =3D setrlimit( resource, rlim ); */
res =3D VG_(do_syscall2)(__NR_setrlimit, resource, (UWord)rlim);
- return res.isError ? -1 : res.val;
+ return res.isError ? -1 : res.res;
}
=20
/* ---------------------------------------------------------------------
@@ -325,9 +363,18 @@
=20
Int VG_(gettid)(void)
{
+# if defined(VGO_aix5)
+ SysRes res;
+ Int r;
+ vg_assert(__NR_AIX5__thread_self !=3D __NR_AIX5_UNKNOWN);
+ res =3D VG_(do_syscall0)(__NR_AIX5__thread_self);
+ r =3D res.res;
+ return r;
+
+# else
SysRes res =3D VG_(do_syscall0)(__NR_gettid);
=20
- if (res.isError && res.val =3D=3D VKI_ENOSYS) {
+ if (res.isError && res.res =3D=3D VKI_ENOSYS) {
Char pid[16]; =20
/*
* The gettid system call does not exist. The obvious assumption
@@ -345,44 +392,53 @@
=20
res =3D VG_(do_syscall3)(__NR_readlink, (UWord)"/proc/self",
(UWord)pid, sizeof(pid));
- if (!res.isError && res.val > 0) {
- pid[res.val] =3D '\0';
- res.val =3D VG_(atoll)(pid);
+ if (!res.isError && res.res > 0) {
+ pid[res.res] =3D '\0';
+ res.res =3D VG_(atoll)(pid);
}
}
=20
- return res.val;
+ return res.res;
+# endif
}
=20
/* You'd be amazed how many places need to know the current pid. */
Int VG_(getpid) ( void )
{
/* ASSUMES SYSCALL ALWAYS SUCCEEDS */
- return VG_(do_syscall0)(__NR_getpid) . val;
+ return VG_(do_syscall0)(__NR_getpid) . res;
}
=20
Int VG_(getpgrp) ( void )
{
/* ASSUMES SYSCALL ALWAYS SUCCEEDS */
- return VG_(do_syscall0)(__NR_getpgrp) . val;
+ return VG_(do_syscall0)(__NR_getpgrp) . res;
}
=20
Int VG_(getppid) ( void )
{
/* ASSUMES SYSCALL ALWAYS SUCCEEDS */
- return VG_(do_syscall0)(__NR_getppid) . val;
+ return VG_(do_syscall0)(__NR_getppid) . res;
}
=20
Int VG_(geteuid) ( void )
{
/* ASSUMES SYSCALL ALWAYS SUCCEEDS */
- return VG_(do_syscall0)(__NR_geteuid) . val;
+# if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+ return VG_(do_syscall1)(__NR_AIX5_getuidx, 1) . res;
+# else
+ return VG_(do_syscall0)(__NR_geteuid) . res;
+# endif
}
=20
Int VG_(getegid) ( void )
{
/* ASSUMES SYSCALL ALWAYS SUCCEEDS */
- return VG_(do_syscall0)(__NR_getegid) . val;
+# if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+ return VG_(do_syscall1)(__NR_AIX5_getgidx, 1) . res;
+# else
+ return VG_(do_syscall0)(__NR_getegid) . res;
+# endif
}
=20
/* Get supplementary groups into list[0 .. size-1]. Returns the
@@ -400,18 +456,19 @@
sres =3D VG_(do_syscall2)(__NR_getgroups, size, (Addr)list16);
if (sres.isError)
return -1;
- if (sres.val > size)
+ if (sres.res > size)
return -1;
- for (i =3D 0; i < sres.val; i++)
+ for (i =3D 0; i < sres.res; i++)
list[i] =3D (UInt)list16[i];
- return sres.val;
+ return sres.res;
=20
-# elif defined(VGP_amd64_linux) || defined(VGP_ppc64_linux)
+# elif defined(VGP_amd64_linux) || defined(VGP_ppc64_linux) \
+ || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
SysRes sres;
sres =3D VG_(do_syscall2)(__NR_getgroups, size, (Addr)list);
if (sres.isError)
return -1;
- return sres.val;
+ return sres.res;
=20
# else
# error "VG_(getgroups): needs implementation on this platform"
@@ -428,7 +485,7 @@
res =3D VG_(do_syscall4)(__NR_ptrace, request, pid, (UWord)addr, (UWo=
rd)data);
if (res.isError)
return -1;
- return res.val;
+ return res.res;
}
=20
/* ---------------------------------------------------------------------
@@ -441,7 +498,7 @@
res =3D VG_(do_syscall0)(__NR_fork);
if (res.isError)
return -1;
- return res.val;
+ return res.res;
}
=20
/* ---------------------------------------------------------------------
@@ -450,14 +507,35 @@
=20
UInt VG_(read_millisecond_timer) ( void )
{
+ /* 'now' and 'base' are in microseconds */
static ULong base =3D 0;
+ ULong now;
+
+# if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+ /* AIX requires a totally different implementation since
+ sys_gettimeofday doesn't exist. We use the POWER real-time
+ register facility. This will SIGILL on PowerPC 970 on AIX,
+ since PowerPC doesn't support these instructions. */
+ UWord nsec, sec1, sec2;
+ while (1) {
+ __asm__ __volatile__ ("\n"
+ "\tmfspr %0,4\n" /* 4=3D=3DRTCU */
+ "\tmfspr %1,5\n" /* 5=3D=3DRTCL */
+ "\tmfspr %2,4\n" /* 4=3D=3DRTCU */
+ : "=3Db" (sec1), "=3Db" (nsec), "=3Db" (sec2)
+ );
+ if (sec1 =3D=3D sec2) break;
+ }
+ vg_assert(nsec < 1000*1000*1000);
+ now =3D ((ULong)sec1) * 1000000ULL;
+ now +=3D (ULong)(nsec / 1000);
+# else
+
struct vki_timeval tv_now;
- ULong now;
SysRes res;
-
res =3D VG_(do_syscall2)(__NR_gettimeofday, (UWord)&tv_now, (UWord)NU=
LL);
- =20
now =3D tv_now.tv_sec * 1000000ULL + tv_now.tv_usec;
+# endif
=20
if (base =3D=3D 0)
base =3D now;
@@ -465,12 +543,6 @@
return (now - base) / 1000;
}
=20
-
-void VG_(nanosleep)(struct vki_timespec *ts)
-{
- (void)VG_(do_syscall2)(__NR_nanosleep, (UWord)ts, (UWord)NULL);
-}
-
/* ---------------------------------------------------------------------
A trivial atfork() facility for Valgrind's internal use
------------------------------------------------------------------ */
Modified: trunk/coregrind/pub_core_libcproc.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/pub_core_libcproc.h 2006-10-17 02:15:17 UTC (rev 6294=
)
+++ trunk/coregrind/pub_core_libcproc.h 2006-10-17 02:16:44 UTC (rev 6295=
)
@@ -76,7 +76,6 @@
extern Char **VG_(env_clone) ( Char **env_clone );
=20
// misc
-extern void VG_(nanosleep) ( struct vki_timespec * );
extern Int VG_(getgroups)( Int size, UInt* list );
extern Int VG_(ptrace)( Int request, Int pid, void *addr, void *data );
extern Int VG_(fork)( void );
|