mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-08 13:01:17 +00:00
Merge from branches/AIX5:
- AIX5 support - get rid of VG_(nanosleep) - track SysRes changes git-svn-id: svn://svn.valgrind.org/valgrind/trunk@6295
This commit is contained in:
parent
12ef34f623
commit
c09f0d7bdb
@ -30,14 +30,15 @@
|
||||
|
||||
#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"
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
Command line and environment stuff
|
||||
@ -222,8 +223,20 @@ void VG_(env_remove_valgrind_env_stuff)(Char** envp)
|
||||
|
||||
Int VG_(waitpid)(Int pid, Int *status, Int options)
|
||||
{
|
||||
# if defined(VGO_linux)
|
||||
SysRes res = VG_(do_syscall4)(__NR_wait4, pid, (UWord)status, options, 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 = VG_(do_syscall5)(__NR_AIX5_kwaitpid,
|
||||
(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
|
||||
}
|
||||
|
||||
/* clone the environment */
|
||||
@ -263,7 +276,7 @@ Int VG_(system) ( Char* cmd )
|
||||
res = VG_(do_syscall0)(__NR_fork);
|
||||
if (res.isError)
|
||||
return -1;
|
||||
pid = res.val;
|
||||
pid = res.res;
|
||||
if (pid == 0) {
|
||||
/* child */
|
||||
static Char** envp = NULL;
|
||||
@ -287,7 +300,32 @@ Int VG_(system) ( Char* cmd )
|
||||
VG_(exit)(1);
|
||||
} else {
|
||||
/* parent */
|
||||
Int zzz = 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 = VKI_SIG_DFL;
|
||||
sa.sa_flags = 0;
|
||||
ir = VG_(sigaction)(VKI_SIGCHLD, &sa, &saved_sa);
|
||||
vg_assert(ir == 0);
|
||||
|
||||
zzz = VG_(waitpid)(pid, NULL, 0);
|
||||
|
||||
ir = VG_(sigaction)(VKI_SIGCHLD, &saved_sa, NULL);
|
||||
vg_assert(ir == 0);
|
||||
|
||||
return zzz == -1 ? -1 : 0;
|
||||
}
|
||||
}
|
||||
@ -304,9 +342,9 @@ Int VG_(getrlimit) (Int resource, struct vki_rlimit *rlim)
|
||||
# ifdef __NR_ugetrlimit
|
||||
res = VG_(do_syscall2)(__NR_ugetrlimit, resource, (UWord)rlim);
|
||||
# endif
|
||||
if (res.isError && res.val == VKI_ENOSYS)
|
||||
if (res.isError && res.err == VKI_ENOSYS)
|
||||
res = VG_(do_syscall2)(__NR_getrlimit, resource, (UWord)rlim);
|
||||
return res.isError ? -1 : res.val;
|
||||
return res.isError ? -1 : res.res;
|
||||
}
|
||||
|
||||
|
||||
@ -316,7 +354,7 @@ Int VG_(setrlimit) (Int resource, const struct vki_rlimit *rlim)
|
||||
SysRes res;
|
||||
/* res = setrlimit( resource, rlim ); */
|
||||
res = VG_(do_syscall2)(__NR_setrlimit, resource, (UWord)rlim);
|
||||
return res.isError ? -1 : res.val;
|
||||
return res.isError ? -1 : res.res;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
@ -325,9 +363,18 @@ Int VG_(setrlimit) (Int resource, const struct vki_rlimit *rlim)
|
||||
|
||||
Int VG_(gettid)(void)
|
||||
{
|
||||
# if defined(VGO_aix5)
|
||||
SysRes res;
|
||||
Int r;
|
||||
vg_assert(__NR_AIX5__thread_self != __NR_AIX5_UNKNOWN);
|
||||
res = VG_(do_syscall0)(__NR_AIX5__thread_self);
|
||||
r = res.res;
|
||||
return r;
|
||||
|
||||
# else
|
||||
SysRes res = VG_(do_syscall0)(__NR_gettid);
|
||||
|
||||
if (res.isError && res.val == VKI_ENOSYS) {
|
||||
if (res.isError && res.res == VKI_ENOSYS) {
|
||||
Char pid[16];
|
||||
/*
|
||||
* The gettid system call does not exist. The obvious assumption
|
||||
@ -345,44 +392,53 @@ Int VG_(gettid)(void)
|
||||
|
||||
res = VG_(do_syscall3)(__NR_readlink, (UWord)"/proc/self",
|
||||
(UWord)pid, sizeof(pid));
|
||||
if (!res.isError && res.val > 0) {
|
||||
pid[res.val] = '\0';
|
||||
res.val = VG_(atoll)(pid);
|
||||
if (!res.isError && res.res > 0) {
|
||||
pid[res.res] = '\0';
|
||||
res.res = VG_(atoll)(pid);
|
||||
}
|
||||
}
|
||||
|
||||
return res.val;
|
||||
return res.res;
|
||||
# endif
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
Int VG_(getpgrp) ( void )
|
||||
{
|
||||
/* ASSUMES SYSCALL ALWAYS SUCCEEDS */
|
||||
return VG_(do_syscall0)(__NR_getpgrp) . val;
|
||||
return VG_(do_syscall0)(__NR_getpgrp) . res;
|
||||
}
|
||||
|
||||
Int VG_(getppid) ( void )
|
||||
{
|
||||
/* ASSUMES SYSCALL ALWAYS SUCCEEDS */
|
||||
return VG_(do_syscall0)(__NR_getppid) . val;
|
||||
return VG_(do_syscall0)(__NR_getppid) . res;
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
/* Get supplementary groups into list[0 .. size-1]. Returns the
|
||||
@ -400,18 +456,19 @@ Int VG_(getgroups)( Int size, UInt* list )
|
||||
sres = 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 = 0; i < sres.val; i++)
|
||||
for (i = 0; i < sres.res; i++)
|
||||
list[i] = (UInt)list16[i];
|
||||
return sres.val;
|
||||
return sres.res;
|
||||
|
||||
# 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 = VG_(do_syscall2)(__NR_getgroups, size, (Addr)list);
|
||||
if (sres.isError)
|
||||
return -1;
|
||||
return sres.val;
|
||||
return sres.res;
|
||||
|
||||
# else
|
||||
# error "VG_(getgroups): needs implementation on this platform"
|
||||
@ -428,7 +485,7 @@ Int VG_(ptrace) ( Int request, Int pid, void *addr, void *data )
|
||||
res = VG_(do_syscall4)(__NR_ptrace, request, pid, (UWord)addr, (UWord)data);
|
||||
if (res.isError)
|
||||
return -1;
|
||||
return res.val;
|
||||
return res.res;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
@ -441,7 +498,7 @@ Int VG_(fork) ( void )
|
||||
res = VG_(do_syscall0)(__NR_fork);
|
||||
if (res.isError)
|
||||
return -1;
|
||||
return res.val;
|
||||
return res.res;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
@ -450,14 +507,35 @@ Int VG_(fork) ( void )
|
||||
|
||||
UInt VG_(read_millisecond_timer) ( void )
|
||||
{
|
||||
/* 'now' and 'base' are in microseconds */
|
||||
static ULong base = 0;
|
||||
struct vki_timeval tv_now;
|
||||
ULong now;
|
||||
SysRes res;
|
||||
|
||||
# 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==RTCU */
|
||||
"\tmfspr %1,5\n" /* 5==RTCL */
|
||||
"\tmfspr %2,4\n" /* 4==RTCU */
|
||||
: "=b" (sec1), "=b" (nsec), "=b" (sec2)
|
||||
);
|
||||
if (sec1 == sec2) break;
|
||||
}
|
||||
vg_assert(nsec < 1000*1000*1000);
|
||||
now = ((ULong)sec1) * 1000000ULL;
|
||||
now += (ULong)(nsec / 1000);
|
||||
# else
|
||||
|
||||
struct vki_timeval tv_now;
|
||||
SysRes res;
|
||||
res = VG_(do_syscall2)(__NR_gettimeofday, (UWord)&tv_now, (UWord)NULL);
|
||||
|
||||
now = tv_now.tv_sec * 1000000ULL + tv_now.tv_usec;
|
||||
# endif
|
||||
|
||||
if (base == 0)
|
||||
base = now;
|
||||
@ -465,12 +543,6 @@ UInt VG_(read_millisecond_timer) ( void )
|
||||
return (now - base) / 1000;
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
@ -76,7 +76,6 @@ extern void VG_(env_remove_valgrind_env_stuff) ( Char** env );
|
||||
extern Char **VG_(env_clone) ( Char **env_clone );
|
||||
|
||||
// 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 );
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user